<commit_before>function Styler() {
    var maxColumns = 3
    var buildStatusPadding = 10

    var widthOfSingleLetter = 6
    var widthOfSingleLetterAtFontSize = 10
    var fontPaddingInCharacters = 2

    function buildStatusCount() {
        return $('li').size()
    }

    function numberOfColumns() {
        return Math.min(maxColumns, buildStatusCount())
    }

    function numberOfRows() {
        return Math.ceil(buildStatusCount() / maxColumns)
    }

    function buildStatusWidth() {
        return window.innerWidth / numberOfColumns() - (buildStatusPadding * 2)
    }

    function buildStatusHeight() {
        return window.innerHeight / numberOfRows() - buildStatusPadding
    }

    function findLongestWord() {
        var words = $.makeArray($('li div div').map(function(index, item) { return $(item).text().split(" ")}))
        return words.reduce(function(largestFound, candidate) { return Math.max(candidate.length, largestFound)  }, 0)
    }

    function idealFontSizeForBoxBasedOffTheLongestWord() {
        var longestWord = findLongestWord() + fontPaddingInCharacters
        var longestWordSize = (widthOfSingleLetter * longestWord)
        return (buildStatusWidth() / longestWordSize) * widthOfSingleLetterAtFontSize
    }

    function scaleFontToContainerSize() {
        $(".outerContainer").css("font-size", Math.floor(idealFontSizeForBoxBasedOffTheLongestWord()))
    }

    function correctBoxHeightForOverlappingText() {
        var heights = $.makeArray($('li div div').map(function(index, item) { return $(item).height()}))
        var largest = Math.max.apply(Math, heights)
        $('li div').height(largest)
    }

    this.styleProjects = function () {
        $('.outerContainer').height(buildStatusHeight()).width(buildStatusWidth())
        scaleFontToContainerSize()
        correctBoxHeightForOverlappingText()
    }
}

function StatusAppender(projects) {
    function addBuildStatusToScreen(project) {
        $('#projects')
         .append("

" +
          project.name + "

")
    }

    this.addProjects = function() {
        $('#projects').empty()
        projects.forEach(addBuildStatusToScreen)

        if(projects.length === 0) {
            $('#projects')
                .append("

=(^.^)=

")
        }
    }
}

function Updater(frequency) {
    function updateBuildMonitor() {
        $.getJSON("/interesting").then(function(data){
            new StatusAppender(data).addProjects()
            new Styler().styleProjects()
        })
    }

    this.start = function() {
        updateBuildMonitor() // run immediately
        setInterval(updateBuildMonitor, frequency)
    }
}

var fiveSeconds = 5000
new Updater(fiveSeconds).start()
<commit_msg>Joe - Balancing text with extra padding<commit_after>function Styler() {
    var maxColumns = 3
    var buildStatusPadding = 10

    var widthOfSingleLetter = 6
    var widthOfSingleLetterAtFontSize = 10
    var fontPaddingInCharacters = 3

    function buildStatusCount() {
        return $('li').size()
    }

    function numberOfColumns() {
        return Math.min(maxColumns, buildStatusCount())
    }

    function numberOfRows() {
        return Math.ceil(buildStatusCount() / maxColumns)
    }

    function buildStatusWidth() {
        return window.innerWidth / numberOfColumns() - (buildStatusPadding * 2)
    }

    function buildStatusHeight() {
        return window.innerHeight / numberOfRows() - buildStatusPadding
    }

    function findLongestWord() {
        var words = $.makeArray($('li div div').map(function(index, item) { return $(item).text().split(" ")}))
        return words.reduce(function(largestFound, candidate) { return Math.max(candidate.length, largestFound)  }, 0)
    }

    function idealFontSizeForBoxBasedOffTheLongestWord() {
        var longestWord = findLongestWord() + fontPaddingInCharacters
        var longestWordSize = (widthOfSingleLetter * longestWord)
        return (buildStatusWidth() / longestWordSize) * widthOfSingleLetterAtFontSize
    }

    function scaleFontToContainerSize() {
        $(".outerContainer").css("font-size", Math.floor(idealFontSizeForBoxBasedOffTheLongestWord()))
    }

    function correctBoxHeightForOverlappingText() {
        var heights = $.makeArray($('li div div').map(function(index, item) { return $(item).height()}))
        var largest = Math.max.apply(Math, heights)
        $('li div').height(largest)
    }

    this.styleProjects = function () {
        $('.outerContainer').height(buildStatusHeight()).width(buildStatusWidth())
        scaleFontToContainerSize()
        correctBoxHeightForOverlappingText()
    }
}

function StatusAppender(projects) {
    function addBuildStatusToScreen(project) {
        $('#projects')
         .append("

" +
          project.name + "

")
    }

    this.addProjects = function() {
        $('#projects').empty()
        projects.forEach(addBuildStatusToScreen)

        if(projects.length === 0) {
            $('#projects')
                .append("

=(^.^)=

")
        }
    }
}

function Updater(frequency) {
    function updateBuildMonitor() {
        $.getJSON("/interesting").then(function(data){
            new StatusAppender(data).addProjects()
            new Styler().styleProjects()
        })
    }

    this.start = function() {
        updateBuildMonitor() // run immediately
        setInterval(updateBuildMonitor, frequency)
    }
}

var fiveSeconds = 5000
new Updater(fiveSeconds).start()
<|endoftext|>


<commit_before>/**
 * Talisman tokenizers/fingerprint/name
 * =====================================
 *
 * Variant of the fingerprint tokenizer but with opinionated options and
 * transformations known to work better with occidental names.
 */
import {createTokenizer} from './';
import {squeeze} from '../../helpers';

const RULES = [

  // McCallister / MacCallister
  [/\bmc(?=\w)/g, 'mac'],
  [/\b(ma?c\s+)(?=\w)/g, 'mac'],

  // Lee / Li
  [/\blee\b/g, 'li'],

  // Moussorgski / Moussorgsky
  [/ski\b/g, 'sky'],

  // Van Hoff / Von Hoff
  [/\bvan\b/g, 'von'],

  // Doerk / Dörk
  [/ö/g, 'oe'],

  // Düring / Duering
  [/ü/g, 'ue']
];

const OPTIONS = {
  digits: false,
  split: ['-'],
  stopwords: [

    // Articles
    'the',
    'le',
    'la',

    // Title
    'dr',
    'mgr',
    'prof',
    'md',
    'phd',
    'sir',
    'lord',

    // Civility
    'mr',
    'mrs',
    'ms',
    'mme',
    'mlle',
    'jr',
    'junior',
    'sr',
    'senior'
  ]
};

const tokenizer = createTokenizer(OPTIONS);

/**
 * Function returning the fingerprint of the given name.
 *
 * @param  {string} name - Target name.
 * @param  {array}
 */
export default function nameFingerprint(name) {
  name = name.toLowerCase();

  // Applying rules
  for (let i = 0, l = RULES.length; i < l; i++)
    name = name.replace(RULES[i][0], RULES[i][1]);

  name = squeeze(name);

  return tokenizer(name);
}
<commit_msg>Improving performance<commit_after>/**
 * Talisman tokenizers/fingerprint/name
 * =====================================
 *
 * Variant of the fingerprint tokenizer but with opinionated options and
 * transformations known to work better with occidental names.
 */
import {createTokenizer} from './';
import {squeeze} from '../../helpers';

const RULES = [

  // McCallister / MacCallister
  [/\bmc(?=\w)/g, 'mac'],
  [/\b(ma?c\s+)(?=\w)/g, 'mac'],

  // Lee / Li
  [/\blee\b/g, 'li'],

  // Moussorgski / Moussorgsky
  [/ski\b/g, 'sky'],

  // Van Hoff / Von Hoff
  [/\bvan\b/g, 'von'],

  // Doerk / Dörk
  [/ö/g, 'oe'],

  // Düring / Duering
  [/ü/g, 'ue']
];

const OPTIONS = {
  digits: false,
  split: ['-'],
  stopwords: [

    // Articles
    'the',
    'le',
    'la',

    // Title
    'dr',
    'mgr',
    'prof',
    'md',
    'phd',
    'sir',
    'lord',

    // Civility
    'mr',
    'mrs',
    'ms',
    'mme',
    'mlle',
    'jr',
    'junior',
    'sr',
    'senior'
  ]
};

const tokenizer = createTokenizer(OPTIONS);

/**
 * Function returning the fingerprint of the given name.
 *
 * @param  {string} name - Target name.
 * @param  {array}
 */
export default function nameFingerprint(name) {
  name = name.toLowerCase();

  // Applying rules
  for (let i = 0, l = RULES.length; i < l; i++)
    name = name.replace(RULES[i][0], RULES[i][1]);

  return tokenizer(name).map(squeeze);
}
<|endoftext|>


<commit_before>'use strict';

angular.module('arachne.visualizations.directives')
    .directive('con10tVega', function () { // con10t-vega
        return {
            restrict: 'E',
            scope: {
                spec: '@',
                name: '@'
            },
            link: function(scope, element, attrs) {

                scope.renderVega = function (spec) {
                    scope.vegaView = new vega.View(vega.parse(spec))
                        .renderer('canvas')
                        .initialize('[name="' + scope.name + '"]')
                        .hover()
                        .run();
                };

                vega.loader()
                    .load(scope.spec)
                    .then(function(data){
                        scope.renderVega(JSON.parse(data));
                    });
            }
        }
    });<commit_msg>Add notes for debugging Vega<commit_after>'use strict';

// In order to debug your Vega spec, run the following command in your browser's console:
// view = angular.element(document.getElementsByName('<name attribute>')).scope().$$childHead.vegaView
// You can then use the variable view as described in https://vega.github.io/vega/docs/api/debugging/

angular.module('arachne.visualizations.directives')
    .directive('con10tVega', function () { // con10t-vega
        return {
            restrict: 'E',
            scope: {
                spec: '@',
                name: '@'
            },
            link: function(scope, element, attrs) {

                scope.renderVega = function (spec) {
                    scope.vegaView = new vega.View(vega.parse(spec))
                        .renderer('canvas')
                        .initialize('[name="' + scope.name + '"]')
                        //.logLevel(vega.Debug)
                        .hover()
                        .run();
                };

                vega.loader()
                    .load(scope.spec)
                    .then(function(data){
                        scope.renderVega(JSON.parse(data));
                    });
            }
        }
    });<|endoftext|>


<commit_before>/**
 * This class contains position information.
 * @param {Object} lat
 * @param {Object} lng
 * @param {Object} acc
 * @param {Object} alt
 * @param {Object} altacc
 * @param {Object} head
 * @param {Object} vel
 * @constructor
 */
function Position(coords, timestamp) {
	this.coords = coords;
        this.timestamp = new Date().getTime();
}

function Coordinates(lat, lng, alt, acc, head, vel, altAcc) {
	/**
	 * The latitude of the position.
	 */
	this.latitude = lat;
	/**
	 * The longitude of the position,
	 */
	this.longitude = lng;
	/**
	 * The accuracy of the position.
	 */
	this.accuracy = acc;
	/**
	 * The altitude of the position.
	 */
	this.altitude = alt;
	/**
	 * The direction the device is moving at the position.
	 */
	this.heading = head;
	/**
	 * The velocity with which the device is moving at the position.
	 */
	this.speed = vel;
	/**
	 * The altitude accuracy of the position.
	 */
	this.altitudeAccuracy = (altacc != 'undefined') ? altacc : null;
}

/**
 * This class specifies the options for requesting position data.
 * @constructor
 */
function PositionOptions() {
	/**
	 * Specifies the desired position accuracy.
	 */
	this.enableHighAccuracy = true;
	/**
	 * The timeout after which if position data cannot be obtained the errorCallback
	 * is called.
	 */
	this.timeout = 10000;
}

/**
 * This class contains information about any GSP errors.
 * @constructor
 */
function PositionError() {
	this.code = null;
	this.message = "";
}

PositionError.UNKNOWN_ERROR = 0;
PositionError.PERMISSION_DENIED = 1;
PositionError.POSITION_UNAVAILABLE = 2;
PositionError.TIMEOUT = 3;
<commit_msg>Variable case issue fixed altAcc NOT altacc, tests were failing<commit_after>/**
 * This class contains position information.
 * @param {Object} lat
 * @param {Object} lng
 * @param {Object} acc
 * @param {Object} alt
 * @param {Object} altAcc
 * @param {Object} head
 * @param {Object} vel
 * @constructor
 */
function Position(coords, timestamp) {
	this.coords = coords;
        this.timestamp = new Date().getTime();
}

function Coordinates(lat, lng, alt, acc, head, vel, altAcc) {
	/**
	 * The latitude of the position.
	 */
	this.latitude = lat;
	/**
	 * The longitude of the position,
	 */
	this.longitude = lng;
	/**
	 * The accuracy of the position.
	 */
	this.accuracy = acc;
	/**
	 * The altitude of the position.
	 */
	this.altitude = alt;
	/**
	 * The direction the device is moving at the position.
	 */
	this.heading = head;
	/**
	 * The velocity with which the device is moving at the position.
	 */
	this.speed = vel;
	/**
	 * The altitude accuracy of the position.
	 */
	this.altitudeAccuracy = (altAcc != 'undefined') ? altAcc : null;
}

/**
 * This class specifies the options for requesting position data.
 * @constructor
 */
function PositionOptions() {
	/**
	 * Specifies the desired position accuracy.
	 */
	this.enableHighAccuracy = true;
	/**
	 * The timeout after which if position data cannot be obtained the errorCallback
	 * is called.
	 */
	this.timeout = 10000;
}

/**
 * This class contains information about any GSP errors.
 * @constructor
 */
function PositionError() {
	this.code = null;
	this.message = "";
}

PositionError.UNKNOWN_ERROR = 0;
PositionError.PERMISSION_DENIED = 1;
PositionError.POSITION_UNAVAILABLE = 2;
PositionError.TIMEOUT = 3;
<|endoftext|>


<commit_before>(function (Q, $) {

/**
 * Streams Tools
 * @module Streams-tools
 * @main
 */

/**
 * Interface for selecting an app user
 * @class Streams userChooser
 * @constructor
 * @param {Object} [options] this object contains function parameters
 *   @param {Q.Event} [options.onChoose] is triggered with (userId, avatar)
 *       parameters when a user is chosen
 *   @param {Number} [options.delay=500] how long to delay before sending a request
 *    to allow more characters to be entered
 *   @param {bool} [options.communitiesOnly=false] If true, search communities instead regular users
 *   @param {Object} [options.exclude] hash of {userId: true},
 *    where userId are the ids of the users to exclude from the results.
 *    Defaults to id of logged-in user, if logged in.
 *   @param {string} [options.position=bottom] Vertical position of results related to input. Can be 'top', 'bottom'
 */
Q.Tool.define("Streams/userChooser", function(o) {
    Q.Streams.cache.userChooser = Q.Streams.cache.userChooser || {};

	var tool = this;

	tool.onChoose = o.onChoose;
	tool.delay = o.delay;
	tool.exclude = o.exclude;

	var element = $(this.element);
	var offset = this.$input.offset();
	this.$input = $('input', element);
	if (!this.$input || !offset) {
		return; // some error
	}
	var cached = {};
	var focusedResults = false;
	tool.$results = $('
')
		.css({
			display: 'none',
			position: 'absolute',
			left: offset.left + 'px',
			top: offset.top + tool.$input.outerHeight() + 'px',
			width: tool.$input.outerWidth(),
			'z-index': 80000,
			background: 'white',
			border: 'solid 1px #99a',
			'tab-index': 9000
		}).on(Q.Pointer.start.eventName + ' focusin', function () {
			focusedResults = true;
		}).appendTo('body');

	var t = null;
	tool.$input.on('blur', function (event) {
		setTimeout(function () {
			if (!focusedResults) {
				tool.$results.remove();
			} else {
				function _handlePointerEnd() {
					tool.$results.remove();
					$(document).off(Q.Pointer.end, _handlePointerEnd);
				}
				$(document).on(Q.Pointer.end, tool, function () {
					setTimeout(_handlePointerEnd, 0);
				});
			}
			focusedResults = false;
		}, 10);
	}).on('focus change', doQuery);
	element.on('keyup keydown', doQuery);

	var lastQuery = null;

	function doQuery(event) {

		var cur = $('.Q_selected', tool.$results);
		var query = tool.$input.val();

		switch (event.keyCode) {
			case 38: // up arrow
				if (event.type === 'keyup') {
					return;
				}
				var prev = cur.prev();
				if (!prev.length) {
					prev = tool.$results.children().last();
				}
				tool.$results.children().removeClass('Q_selected');
				prev.addClass('Q_selected');
				return false;
			case 40: // down arrow
				if (event.type === 'keyup') {
					return;
				}
				var next = cur.next();
				if (!next.length) {
					next = tool.$results.children().first();
				}
				tool.$results.children().removeClass('Q_selected');
				next.addClass('Q_selected');
				return false;
			case 13: // enter
				if (event.type === 'keyup') {
					return;
				}
				if (cur) {
					onChoose(cur);
				}
				return false;
			default:
				if (query === lastQuery) {
					return;
				}
				lastQuery = query;
				if (event.type === 'keydown') {
					return;
				}
				if (!query) {
					tool.$results.remove();
					return;
				}
				tool.$input.css({
					'background-image': 'url(' +Q.url('/{{Q}}/img/throbbers/loading.gif') + ')',
					'background-repeat': 'no-repeat'
				});
				Q.Streams.Avatar.byPrefix(tool.$input.val().toLowerCase(), onResponse, {'public': true});
		}

		function onChoose (cur) {
			var userId = cur.data('userId');
			var avatar = cur.data('avatar');
			tool.$input.blur().val('');
			Q.handle(tool.onChoose, this, [userId, avatar]);
			tool.end();
		}

		function onResponse (err, avatars) {
			tool.$input.css('background-image', 'none');
			if (err) {
				return; // silently return
			}
			if (Q.isEmpty(avatars)) {
				return tool.$results.remove();
			}
			tool.$results.empty();
			var show = 0;
			for (var k in avatars) {
				if (k in tool.exclude && tool.exclude[k]) {
					continue;
				}

				if ((tool.state.communitiesOnly && !Q.Users.isCommunityId(k)) || (!tool.state.communitiesOnly && Q.Users.isCommunityId(k))) {
					continue;
				}

				var result = $('').append(
					$('')
					.attr('src', Q.plugins.Users.iconUrl(avatars[k].icon, 40))
				).append(
					$('').html(avatars[k].displayName())
				).on(Q.Pointer.enter, function () {
					$('*', tool.$results).removeClass('Q_selected');
					$(this).addClass('Q_selected');
				}).on(Q.Pointer.leave, function () {
					$('*', tool.$results).removeClass('Q_selected');
					$(this).addClass('Q_selected');
				}).on(Q.Pointer.fastclick, function () {
					onChoose($(this));
				}).data('userId', k)
				.data('avatar', avatars[k])
				.on(Q.Pointer.start.eventName + ' focusin', function () {
					focusedResults = true;
				}).appendTo(tool.$results);
				if (!show) {
					result.addClass('Q_selected');
				}
				++show;
			}
			if (show) {
				tool.$results.css({
					left: tool.$input.offset().left + 'px',
					width: tool.$input.outerWidth()
				}).appendTo('body').show();

				var position = tool.$input.offset().top + tool.$input.outerHeight();
				var height = 300 - tool.$input.outerHeight();
				if (tool.state.position === 'top') {
					tool.$results.css({
						'max-height': height,
						'overflow-y': 'auto',
						'overflow-x': 'hidden',
					});
					tool.$results.css({
						top: tool.$input.offset().top - tool.$results.outerHeight() + 'px',
					});
				} else {
					tool.$results.css({
						top: position + 'px',
					});
				}
			} else {
				tool.$results.remove();
			}
		}
	}

},

{
	onChoose: new Q.Event(),
	delay: 500,
	communitiesOnly: false,
	exclude: {}
},

{
	end: function () {
		if (this.$input) {
			this.$input.blur().trigger('Q_refresh');
		}
		if (this.$results) {
			this.$results.remove();
		}
	},
	Q: {
		beforeRemove: function () {
			this.end();
		}
	}
}

);

})(Q, jQuery);<commit_msg>Fixed userChooser edge case<commit_after>(function (Q, $) {

/**
 * Streams Tools
 * @module Streams-tools
 * @main
 */

/**
 * Interface for selecting an app user
 * @class Streams userChooser
 * @constructor
 * @param {Object} [options] this object contains function parameters
 *   @param {Q.Event} [options.onChoose] is triggered with (userId, avatar)
 *       parameters when a user is chosen
 *   @param {Number} [options.delay=500] how long to delay before sending a request
 *    to allow more characters to be entered
 *   @param {bool} [options.communitiesOnly=false] If true, search communities instead regular users
 *   @param {Object} [options.exclude] hash of {userId: true},
 *    where userId are the ids of the users to exclude from the results.
 *    Defaults to id of logged-in user, if logged in.
 *   @param {string} [options.position=bottom] Vertical position of results related to input. Can be 'top', 'bottom'
 */
Q.Tool.define("Streams/userChooser", function(o) {
    Q.Streams.cache.userChooser = Q.Streams.cache.userChooser || {};

	var tool = this;

	tool.onChoose = o.onChoose;
	tool.delay = o.delay;
	tool.exclude = o.exclude;

	var element = $(this.element);
	this.$input = $('input', element);
	var offset = this.$input && $this.offset();
	if (!offset) {
		return; // some error
	}
	var cached = {};
	var focusedResults = false;
	tool.$results = $('
')
		.css({
			display: 'none',
			position: 'absolute',
			left: offset.left + 'px',
			top: offset.top + tool.$input.outerHeight() + 'px',
			width: tool.$input.outerWidth(),
			'z-index': 80000,
			background: 'white',
			border: 'solid 1px #99a',
			'tab-index': 9000
		}).on(Q.Pointer.start.eventName + ' focusin', function () {
			focusedResults = true;
		}).appendTo('body');

	var t = null;
	tool.$input.on('blur', function (event) {
		setTimeout(function () {
			if (!focusedResults) {
				tool.$results.remove();
			} else {
				function _handlePointerEnd() {
					tool.$results.remove();
					$(document).off(Q.Pointer.end, _handlePointerEnd);
				}
				$(document).on(Q.Pointer.end, tool, function () {
					setTimeout(_handlePointerEnd, 0);
				});
			}
			focusedResults = false;
		}, 10);
	}).on('focus change', doQuery);
	element.on('keyup keydown', doQuery);

	var lastQuery = null;

	function doQuery(event) {

		var cur = $('.Q_selected', tool.$results);
		var query = tool.$input.val();

		switch (event.keyCode) {
			case 38: // up arrow
				if (event.type === 'keyup') {
					return;
				}
				var prev = cur.prev();
				if (!prev.length) {
					prev = tool.$results.children().last();
				}
				tool.$results.children().removeClass('Q_selected');
				prev.addClass('Q_selected');
				return false;
			case 40: // down arrow
				if (event.type === 'keyup') {
					return;
				}
				var next = cur.next();
				if (!next.length) {
					next = tool.$results.children().first();
				}
				tool.$results.children().removeClass('Q_selected');
				next.addClass('Q_selected');
				return false;
			case 13: // enter
				if (event.type === 'keyup') {
					return;
				}
				if (cur) {
					onChoose(cur);
				}
				return false;
			default:
				if (query === lastQuery) {
					return;
				}
				lastQuery = query;
				if (event.type === 'keydown') {
					return;
				}
				if (!query) {
					tool.$results.remove();
					return;
				}
				tool.$input.css({
					'background-image': 'url(' +Q.url('/{{Q}}/img/throbbers/loading.gif') + ')',
					'background-repeat': 'no-repeat'
				});
				Q.Streams.Avatar.byPrefix(tool.$input.val().toLowerCase(), onResponse, {'public': true});
		}

		function onChoose (cur) {
			var userId = cur.data('userId');
			var avatar = cur.data('avatar');
			tool.$input.blur().val('');
			Q.handle(tool.onChoose, this, [userId, avatar]);
			tool.end();
		}

		function onResponse (err, avatars) {
			tool.$input.css('background-image', 'none');
			if (err) {
				return; // silently return
			}
			if (Q.isEmpty(avatars)) {
				return tool.$results.remove();
			}
			tool.$results.empty();
			var show = 0;
			for (var k in avatars) {
				if (k in tool.exclude && tool.exclude[k]) {
					continue;
				}

				if ((tool.state.communitiesOnly && !Q.Users.isCommunityId(k)) || (!tool.state.communitiesOnly && Q.Users.isCommunityId(k))) {
					continue;
				}

				var result = $('').append(
					$('')
					.attr('src', Q.plugins.Users.iconUrl(avatars[k].icon, 40))
				).append(
					$('').html(avatars[k].displayName())
				).on(Q.Pointer.enter, function () {
					$('*', tool.$results).removeClass('Q_selected');
					$(this).addClass('Q_selected');
				}).on(Q.Pointer.leave, function () {
					$('*', tool.$results).removeClass('Q_selected');
					$(this).addClass('Q_selected');
				}).on(Q.Pointer.fastclick, function () {
					onChoose($(this));
				}).data('userId', k)
				.data('avatar', avatars[k])
				.on(Q.Pointer.start.eventName + ' focusin', function () {
					focusedResults = true;
				}).appendTo(tool.$results);
				if (!show) {
					result.addClass('Q_selected');
				}
				++show;
			}
			if (show) {
				tool.$results.css({
					left: tool.$input.offset().left + 'px',
					width: tool.$input.outerWidth()
				}).appendTo('body').show();

				var position = tool.$input.offset().top + tool.$input.outerHeight();
				var height = 300 - tool.$input.outerHeight();
				if (tool.state.position === 'top') {
					tool.$results.css({
						'max-height': height,
						'overflow-y': 'auto',
						'overflow-x': 'hidden',
					});
					tool.$results.css({
						top: tool.$input.offset().top - tool.$results.outerHeight() + 'px',
					});
				} else {
					tool.$results.css({
						top: position + 'px',
					});
				}
			} else {
				tool.$results.remove();
			}
		}
	}

},

{
	onChoose: new Q.Event(),
	delay: 500,
	communitiesOnly: false,
	exclude: {}
},

{
	end: function () {
		if (this.$input) {
			this.$input.blur().trigger('Q_refresh');
		}
		if (this.$results) {
			this.$results.remove();
		}
	},
	Q: {
		beforeRemove: function () {
			this.end();
		}
	}
}

);

})(Q, jQuery);<|endoftext|>


<commit_before>import React, { Component } from 'react';
import PikadayWrapper from '../../lib-components/PikadayWrapper/PikadayWrapper';

export default class PantryItem extends Component {
    constructor(props) {
        super(props);

        this.state = {
            expiration: this.props.item.expiration,
            name: this.props.item.name
        };
    }

    onSelectDate(newDate) {
        this.setState({ expiration: newDate });

        this.props.onItemChange(this.getItem());
    }

    onNameChange(newName) {
        this.setState({ name: newName });

        this.props.onItemChange(this.getItem());
    }

    getItem() {
        return {
            name: this.state.name,
            expiration: this.state.expiration
        };
    }

    render() {
        return (

                        Product name

                        <input type="text" className="pantry-item__form-input" defaultValue={this.state.name} onChange={evt => this.onNameChange(evt.target.value) } />

                        Expiry date

                        <PikadayWrapper onSelect={(date) => this.onSelectDate(date)}
                                defaultValue={this.state.expiration}
                                className="pantry-item__form-input pantry-item__form-input--datepicker" />

        );
    }
}<commit_msg>Fix issue with state being saved with last value<commit_after>import React, { Component } from 'react';
import PikadayWrapper from '../../lib-components/PikadayWrapper/PikadayWrapper';

export default class PantryItem extends Component {
    constructor(props) {
        super(props);

        this.state = {
            expiration: this.props.item.expiration,
            name: this.props.item.name
        };
    }

    onSelectDate(newDate) {
        this.setState({ expiration: newDate }, () => {
            this.props.onItemChange(this.getItem());
        });
    }

    onNameChange(newName) {
        this.setState({ name: newName }, () => {
            this.props.onItemChange(this.getItem());
        });
    }

    getItem() {
        return {
            name: this.state.name,
            expiration: this.state.expiration
        };
    }

    render() {
        return (

                        Product name

                        <input type="text" className="pantry-item__form-input" defaultValue={this.state.name} onChange={evt => this.onNameChange(evt.target.value)} />

                        Expiry date

                        <PikadayWrapper onSelect={(date) => this.onSelectDate(date)}
                            defaultValue={this.state.expiration}
                            className="pantry-item__form-input pantry-item__form-input--datepicker" />

        );
    }
}<|endoftext|>


<commit_before>/* global window */
/* eslint no-console: 0 */

import anime from 'animejs';

/**
 * this file contains _functions_ that do RAW DOM manipulations.
 * keeping our React Components _free_ of DOM hassle
 */

/**
 * shows or hides .close-button
 *
 * @param  {Boolean} show
 */
function showCloseButton(show = true) {
  const closeButton = window.document.querySelector('.close-button');

  switch (show) {
    case true:
      closeButton.style.transform = 'translateY(0em)';
      closeButton.style.opacity = '1';
      return;

    case false:
      closeButton.style.opacity = '0';
      setTimeout(() => {
        closeButton.style.transform = 'translateY(-2em)';
      }, 350);
      return;

    default:
      console.warn(`Expected bool, instead got '${typeof show}'`);
  }
}

/**
 * shows or hides .view-movie-background
 * @param  {Boolean} show [description]
 */
function showMovieBackground(show = true) {
  const viewMovieBackground = window.document.querySelector('.view-movie-background');

  switch (show) {
    case true:
      viewMovieBackground.style.transform = 'translateY(0vh)';
      viewMovieBackground.style.opacity = '1';
      return;

    case false:
      viewMovieBackground.style.opacity = '0';
      setTimeout(() => {
        viewMovieBackground.style.transform = 'translateY(100vh)';
      }, 350);
      return;

    default:
      console.warn(`Expected bool, instead got '${typeof show}'`);
  }
}

/**
 * shows or hides .movie-poster
 * @param  {Boolean} show
 * @param  {String} src
 * @return {Promise | undefined}
 */
function showPoster(show = true, src = '') {
  const moviePoster = window.document.querySelector('.movie-poster');

  switch (show) {
    case true: {
      // getting location and dimension of the active poster
      const activePoster = window.document.querySelector('.movie-container.active .poster-container .img-poster');
      const rect = activePoster.getBoundingClientRect();
      const { top, left } = rect; // number
      let width = window.getComputedStyle(activePoster).width; // string
      width = Number(width.substring(0, width.length - 2)); // number
      // Not using window.screen.width because on Safari it returns the Mac's screen width, not
      // the phone width (even in responsive mode)
      let screenWidth = window.getComputedStyle(window.document.body).width;
      screenWidth = Number(screenWidth.substring(0, screenWidth.length - 2));

      // overlaying image on the active poster...
      moviePoster.src = src;
      moviePoster.style.top = `${top}px`;
      moviePoster.style.left = `${left}px`;
      moviePoster.style.width = width;
      moviePoster.style.opacity = '1';

      // setting dataset...
      moviePoster.dataset.top = top;
      moviePoster.dataset.left = left;
      moviePoster.dataset.width = width;
      moviePoster.dataset.screenWidth = screenWidth;

      return new Promise((resolve) => {
        // scaling up the movie poster to fill the screen
        anime({
          targets: moviePoster,
          translateY: ['0px', `${top > 0 ? `-${top}` : '0'}px`],
          translateX: ['0px', `-${left}px`],
          width: [`${width}px`, `${screenWidth}px`],
          easing: 'easeOutExpo',
          duration: 500,
          elasticity: 100,
          complete() {
            resolve();
          },
        });
      });
    }

    case false: {
      const { top, left, width, screenWidth } = moviePoster.dataset;

      // setting border radius in the middle of scale-down animation
      setTimeout(() => {
        moviePoster.style.borderRadius = '.25em';
      }, 250);

      return new Promise((resolve) => {
        // scaling-down...
        anime({
          targets: moviePoster,
          translateY: [`-${top}px`, '0px'],
          translateX: [`-${left}px`, '0px'],
          width: [`${screenWidth}px`, `${width}px`],
          easing: 'easeOutExpo',
          duration: 500,
          opacity: {
            value: 0,
            delay: 200,
            easing: 'easeOutExpo',
          },
          elasticity: 100,
          complete() {
            // resetting style...
            moviePoster.style.top = '0px';
            moviePoster.style.left = '0px';
            moviePoster.style.width = 'auto';
            moviePoster.style.borderRadius = '0em';
            moviePoster.style.transform = 'translateY(100vh)';
            resolve();
          },
        });
      });
    }

    default:
      console.warn(`Expected bool, instead got '${typeof show}'`);
      return typeof show;
  }
}

/**
 * sets .movie-poster src
 *
 * @param {String} src
 */
function setPosterSrc(src = '') {
  window.document.querySelector('.movie-poster').src = src;
}

module.exports = {
  showCloseButton,
  showMovieBackground,
  showPoster,
  setPosterSrc,
};
<commit_msg>easy does it<commit_after>/* global window */
/* eslint no-console: 0 */

import anime from 'animejs';

/**
 * this file contains _functions_ that do RAW DOM manipulations.
 * keeping our React Components _free_ of DOM hassle
 */

/**
 * shows or hides .close-button
 *
 * @param  {Boolean} show
 */
function showCloseButton(show = true) {
  const closeButton = window.document.querySelector('.close-button');

  switch (show) {
    case true:
      closeButton.style.transform = 'translateY(0em)';
      closeButton.style.opacity = '1';
      return;

    case false:
      closeButton.style.opacity = '0';
      setTimeout(() => {
        closeButton.style.transform = 'translateY(-2em)';
      }, 350);
      return;

    default:
      console.warn(`Expected bool, instead got '${typeof show}'`);
  }
}

/**
 * shows or hides .view-movie-background
 * @param  {Boolean} show [description]
 */
function showMovieBackground(show = true) {
  const viewMovieBackground = window.document.querySelector('.view-movie-background');

  switch (show) {
    case true:
      viewMovieBackground.style.transform = 'translateY(0vh)';
      viewMovieBackground.style.opacity = '1';
      return;

    case false:
      viewMovieBackground.style.opacity = '0';
      setTimeout(() => {
        viewMovieBackground.style.transform = 'translateY(100vh)';
      }, 350);
      return;

    default:
      console.warn(`Expected bool, instead got '${typeof show}'`);
  }
}

/**
 * shows or hides .movie-poster
 * @param  {Boolean} show
 * @param  {String} src
 * @return {Promise | undefined}
 */
function showPoster(show = true, src = '') {
  const moviePoster = window.document.querySelector('.movie-poster');

  switch (show) {
    case true: {
      // getting location and dimension of the active poster
      const activePoster = window.document.querySelector('.movie-container.active .poster-container .img-poster');
      const rect = activePoster.getBoundingClientRect();
      const { top, left } = rect; // number
      let width = window.getComputedStyle(activePoster).width; // string
      width = Number(width.substring(0, width.length - 2)); // number
      // Not using window.screen.width because on Safari it returns the Mac's screen width, not
      // the phone width (even in responsive mode)
      let screenWidth = window.getComputedStyle(window.document.body).width;
      screenWidth = Number(screenWidth.substring(0, screenWidth.length - 2));

      // overlaying image on the active poster...
      moviePoster.src = src;
      moviePoster.style.top = `${top}px`;
      moviePoster.style.left = `${left}px`;
      moviePoster.style.width = width;
      moviePoster.style.opacity = '1';

      // setting dataset...
      moviePoster.dataset.top = top;
      moviePoster.dataset.left = left;
      moviePoster.dataset.width = width;
      moviePoster.dataset.screenWidth = screenWidth;

      return new Promise((resolve) => {
        // scaling up the movie poster to fill the screen
        anime({
          targets: moviePoster,
          translateY: ['0px', `${top > 0 ? `-${top}` : '0'}px`],
          translateX: ['0px', `-${left}px`],
          width: [`${width}px`, `${screenWidth}px`],
          easing: 'easeOutExpo',
          duration: 500,
          elasticity: 100,
          complete() {
            resolve();
          },
        });
      });
    }

    case false: {
      const { top, left, width, screenWidth } = moviePoster.dataset;

      // setting border radius in the middle of scale-down animation
      setTimeout(() => {
        moviePoster.style.borderRadius = '.25em';
      }, 250);

      return new Promise((resolve) => {
        // scaling-down...
        anime({
          targets: moviePoster,
          translateY: [`-${top}px`, '0px'],
          translateX: [`-${left}px`, '0px'],
          width: [`${screenWidth}px`, `${width}px`],
          easing: 'easeOutExpo',
          duration: 500,
          opacity: {
            value: 0,
            delay: 300,
            easing: 'easeOutExpo',
          },
          elasticity: 100,
          complete() {
            // resetting style...
            moviePoster.style.top = '0px';
            moviePoster.style.left = '0px';
            moviePoster.style.width = 'auto';
            moviePoster.style.borderRadius = '0em';
            moviePoster.style.transform = 'translateY(100vh)';
            resolve();
          },
        });
      });
    }

    default:
      console.warn(`Expected bool, instead got '${typeof show}'`);
      return typeof show;
  }
}

/**
 * sets .movie-poster src
 *
 * @param {String} src
 */
function setPosterSrc(src = '') {
  window.document.querySelector('.movie-poster').src = src;
}

module.exports = {
  showCloseButton,
  showMovieBackground,
  showPoster,
  setPosterSrc,
};
<|endoftext|>


<commit_before>'use strict';

const co = require('../common');

module.exports = {
    'file': {
        uri: (!co.isEmpty(process.env.SERVICE_URL_FILE)) ? process.env.SERVICE_URL_FILE : 'http://fileservice'
    },
    'tag': {
        uri: (!co.isEmpty(process.env.SERVICE_URL_TAG)) ? process.env.SERVICE_URL_TAG : 'http://localhost:5000'
    }
};
<commit_msg>fix tag microservice config<commit_after>'use strict';

const co = require('../common');

module.exports = {
    'file': {
        uri: (!co.isEmpty(process.env.SERVICE_URL_FILE)) ? process.env.SERVICE_URL_FILE : 'http://fileservice'
    },
    'tag': {
        uri: (!co.isEmpty(process.env.SERVICE_URL_TAG)) ? process.env.SERVICE_URL_TAG : 'http://tagservice'
    }
};
<|endoftext|>


<commit_before>/* eslint-disable import/prefer-default-export */

// Credit David Walsh (https://davidwalsh.name/javascript-debounce-function)
// Slightly editted for linter to accept.
// Returns a function, that, as long as it continues to be invoked, will not
// be triggered. The function will be called after it stops being called for
// N milliseconds. If `immediate` is passed, trigger the function on the
// leading edge, instead of the trailing.
export function debounce(func, wait, immediate) {
  let timeout;

  return function executedFunction(...args) {
    const context = this;

    const later = () => {
      timeout = null;
      if (!immediate) func.apply(context, args);
    };

    const callNow = immediate && !timeout;

    clearTimeout(timeout);

    timeout = setTimeout(later, wait);

    if (callNow) func.apply(context, args);
  };
}
<commit_msg>Add hardware back button debounce return value update<commit_after>/* eslint-disable import/prefer-default-export */

// Credit David Walsh (https://davidwalsh.name/javascript-debounce-function)
// Slightly editted for linter to accept.
// Returns a function, that, as long as it continues to be invoked, will not
// be triggered. The function will be called after it stops being called for
// N milliseconds. If `immediate` is passed, trigger the function on the
// leading edge, instead of the trailing.
export function debounce(func, wait, immediate) {
  let timeout;

  return function executedFunction(...args) {
    const context = this;

    const later = () => {
      timeout = null;
      if (!immediate) return func.apply(context, args);
      return null;
    };

    const callNow = immediate && !timeout;

    clearTimeout(timeout);

    timeout = setTimeout(later, wait);

    if (callNow) return func.apply(context, args);

    return timeout;
  };
}
<|endoftext|>


<commit_before>'use strict';

const co = require('../common');

module.exports = {
  'deck': {
    uri: (!co.isEmpty(process.env.SERVICE_URL_DECK)) ? process.env.SERVICE_URL_DECK : 'https://deckservice.experimental.slidewiki.org'
  },
  'pdf': {
    uri: (!co.isEmpty(process.env.SERVICE_URL_PDF)) ? process.env.SERVICE_URL_PDF : 'https://pdfservice.experimental.slidewiki.org'
  },
  'user':{
    uri: (!co.isEmpty(process.env.SERVICE_URL_USER)) ? process.env.SERVICE_URL_USER : 'https://userservice.experimental.slidewiki.org'
  },
  'platform':{
    uri: (!co.isEmpty(process.env.SERVICE_URL_PLATFORM)) ? process.env.SERVICE_URL_PLATFORM : 'https://platform.experimental.slidewiki.org'
  }
};
<commit_msg>package.json updated<commit_after>'use strict';

const co = require('../common');

module.exports = {
  'deck': {
    uri: (!co.isEmpty(process.env.SERVICE_URL_DECK)) ? process.env.SERVICE_URL_DECK : 'http://deckservice'
  },
  'pdf': {
    uri: (!co.isEmpty(process.env.SERVICE_URL_PDF)) ? process.env.SERVICE_URL_PDF : 'http://pdfservice'
  },
  'user':{
    uri: (!co.isEmpty(process.env.SERVICE_URL_USER)) ? process.env.SERVICE_URL_USER : 'http://userservice'
  },
  'platform':{
    uri: (!co.isEmpty(process.env.SERVICE_URL_PLATFORM)) ? process.env.SERVICE_URL_PLATFORM : 'http://platform'
  }
};
<|endoftext|>


<commit_before>/**
 * This file contains all necessary Angular controller definitions for 'frontend.admin.login-history' module.
 *
 * Note that this file should only contain controllers and nothing else.
 */
(function () {
  'use strict';

  angular.module('frontend.plugins')
    .controller('EditPluginController', [
      '_', '$scope', '$rootScope', '$log', 'ListConfig',
      'MessageService', 'ConsumerModel', 'SocketHelperService', 'PluginHelperService',
      'KongPluginsService', '$uibModalInstance', 'PluginsService', '_plugin', '_schema',
      function controller(_, $scope, $rootScope, $log, ListConfig,
                          MessageService, ConsumerModel, SocketHelperService, PluginHelperService,
                          KongPluginsService, $uibModalInstance, PluginsService, _plugin, _schema) {

        $scope.plugin = _plugin;

        var sch = _schema.data;
        $scope.schema = {
          fields: {}
        };

        if(_.isArray(sch.fields)) {
          sch.fields.forEach(item => {
            $scope.schema.fields[Object.keys(item)[0]] = item[Object.keys(item)[0]];
          })
        }

        // $scope.schema = _schema.data;
        $scope.context = 'update';
        console.log("Plugin", $scope.plugin);
        $log.debug("Schema", $scope.schema);

        //var pluginOptions = new KongPluginsService().pluginOptions()
        var options = new KongPluginsService().pluginOptions(_plugin.name);

        // Define the plugins that will have their own custom form
        // so that it can be included via ng-include in the .html files
        $scope.customPluginForms = ['statsd'];

        //$log.debug("Options", options)
        $scope.close = close;

        $scope.humanizeLabel = function (key) {
          return key.split("_").join(" ");
        };

        $scope.addFlexField = function (fields, v) {
          if (!v.flex_field) return;

          fields[v.flex_field] = {
            "schema": {
              "fields": {
                "day": {
                  "type": "number",
                },
                "minute": {
                  "type": "number",
                },
                "second": {
                  "type": "number",
                },
                "year": {
                  "type": "number",
                },
                "month": {
                  "type": "number",
                },
                "hour": {
                  "type": "number",
                }
              }
            }
          };

          v.flex_field = ""
        };

        $scope.removeField = function (object, key) {
          delete object[key];
        };

        function initialize() {
          // Initialize plugin fields data
          $scope.data = _.merge(options.fields, $scope.schema, {
            consumer: {
              id: _.get($scope, 'plugin.consumer.id')
            }
          });

          // Define general modal window content
          $scope.description = $scope.data.meta ? $scope.data.meta.description
            : 'Configure the Plugin.';

          // Remove unwanted data fields that start with "_"
          Object.keys($scope.data.fields).forEach(function (key) {
            if (key.startsWith("_")) delete $scope.data.fields[key];
          });

          // Monkey patch for response-ratelimiting plugin
          if (_plugin.name === 'response-ratelimiting') {
            console.log("response-ratelimiting:limits =>", _plugin.config.limits);

            // Delete initial schema fields
            delete $scope.data.fields.limits.schema.fields.day;
            delete $scope.data.fields.limits.schema.fields.hour;
            delete $scope.data.fields.limits.schema.fields.minute;
            delete $scope.data.fields.limits.schema.fields.month;
            delete $scope.data.fields.limits.schema.fields.second;
            delete $scope.data.fields.limits.schema.fields.year;

            if (_plugin.config.limits) {
              Object.keys(_plugin.config.limits).forEach(function (key) {

                //console.log("_plugin.config.limits[key]",_plugin.config.limits[key])

                var inner_fields = {};
                Object.keys(_plugin.config.limits[key]).forEach(function (k) {
                  inner_fields[k] = {
                    type: 'number',
                    default: _plugin.config.limits[key][k]
                  }
                });

                $scope.data.fields.limits.schema.fields[key] = {

                  schema: {
                    fields: inner_fields
                  }
                }
              })
            }
          }

          // Customize data fields according to plugin
          PluginHelperService.customizeDataFieldsForPlugin(_plugin.name, $scope.data.fields);

          assignValues($scope.data.fields);
        }

        function assignValues(fields, prefix) {

          Object.keys(fields).forEach(function (item) {
            if (fields[item].schema) {
              assignValues(fields[item].schema.fields, prefix ? prefix + "." + item : item)
            } else {

              var path = prefix ? prefix + "." + item : item;
              var value = _.get(_plugin.config, path);

              if (fields[item].type === 'record' && fields[item].fields) {
                fields[item].fields.forEach(field => {
                  const prop = Object.keys(field)[0];
                  field[prop].value = _.get(_plugin.config, `${path}.${prop}`);
                })
              }

              if (fields[item].type === 'array'
                && value !== null && typeof value === 'object' && !Object.keys(value).length) {
                value = []
              }
              fields[item].value = value;
              fields[item].help = _.get(options, path) ? _.get(options, path).help : ''
            }
          });
        }

        $scope.updatePlugin = function () {

          $scope.busy = true;

          var data = {
            enabled: $scope.plugin.enabled
          };

          //if($scope.data.consumer_id instanceof Object) {
          //    data.consumer_id = $scope.data.consumer_id.id
          //}

          const consumerId = _.get($scope, 'data.consumer.id');
          if (consumerId) {
            data.consumer = {
              id: consumerId
            };
          }

          // Create request data "config." properties
          const config = PluginHelperService.createConfigProperties(_plugin.name,$scope.data.fields)

          const finalData = _.merge(data, config)

          console.log("REQUEST DATA =>", finalData);

          PluginsService.update(_plugin.id, finalData)
            .then(function (res) {
              $log.debug("updatePlugin", res);
              $scope.busy = false;
              $rootScope.$broadcast('plugin.updated', res.data);
              MessageService.success('"' + _plugin.name + '" plugin updated successfully!');
              $uibModalInstance.close({
                data: res.data
              });
            }).catch(function (err) {
            $scope.busy = false;
            $log.error("update plugin", err);
            var errors = {};

            if (err.data.customMessage) {
              Object.keys(err.data.customMessage).forEach(function (key) {
                errors[key.replace('config.', '')] = err.data.customMessage[key];
                MessageService.error(key + " : " + err.data.customMessage[key])
              })
            } else if (err.data.body && err.data.body.message) {
              MessageService.error(err.data.body.message)
            }

            $scope.errors = errors
          })
        };

        // Initialize used title items
        $scope.titleItems = ListConfig.getTitleItems(ConsumerModel.endpoint);

        // Add the consumers to the plugin options
        $scope.getConsumer = function (val) {

          if (!val) return;

          var commonParameters = {
            where: SocketHelperService.getWhere({
              searchWord: val,
              columns: $scope.titleItems
            })
          };

          return ConsumerModel
            .load(_.merge({}, commonParameters, {
              limit: 5
            }))
            .then(function (response) {
              return response.map(function (item) {
                return item;
              });
            });
        };

        function close() {
          $uibModalInstance.dismiss()
        }

        initialize();

        /**
         * STATSD
         */

        $scope.statsd = {
          metricNames : [
            'request_count',
            'request_size',
            'response_size',
            'latency',
            'status_count',
            'unique_users',
            'request_per_user',
            'upstream_latency',
            'kong_latency',
            'status_count_per_user'
          ],
          statTypes : [
            'gauge',
            'timer',
            'counter',
            'histogram',
            'meter',
            'set'
          ],
          consumerIndentifiers : [
            'consumer_id',
            'custom_id',
            'username'
          ],
          addMetric : function (metrics) {

            var template = {
              name : 'upstream_latency',
              stat_type: 'gauge',
              custom_identifier: 'consumer_id'
            };

            metrics.push(template);

          },
          removeMetric: function (metrics, index) {
            metrics.splice(index,1);
          }
        };

        $scope.getFieldProp = (field) => {
          return Object.keys(field)[0];
        }
      }
    ])
  ;
}());
<commit_msg>Use original plugin object as base when updating. Ref issue #288<commit_after>/**
 * This file contains all necessary Angular controller definitions for 'frontend.admin.login-history' module.
 *
 * Note that this file should only contain controllers and nothing else.
 */
(function () {
  'use strict';

  angular.module('frontend.plugins')
    .controller('EditPluginController', [
      '_', '$scope', '$rootScope', '$log', 'ListConfig',
      'MessageService', 'ConsumerModel', 'SocketHelperService', 'PluginHelperService',
      'KongPluginsService', '$uibModalInstance', 'PluginsService', '_plugin', '_schema',
      function controller(_, $scope, $rootScope, $log, ListConfig,
                          MessageService, ConsumerModel, SocketHelperService, PluginHelperService,
                          KongPluginsService, $uibModalInstance, PluginsService, _plugin, _schema) {

        $scope.plugin = _plugin;

        var sch = _schema.data;
        $scope.schema = {
          fields: {}
        };

        if(_.isArray(sch.fields)) {
          sch.fields.forEach(item => {
            $scope.schema.fields[Object.keys(item)[0]] = item[Object.keys(item)[0]];
          })
        }

        // $scope.schema = _schema.data;
        $scope.context = 'update';
        console.log("Plugin", $scope.plugin);
        console.log("Schema", $scope.schema);

        //var pluginOptions = new KongPluginsService().pluginOptions()
        var options = new KongPluginsService().pluginOptions(_plugin.name);

        // Define the plugins that will have their own custom form
        // so that it can be included via ng-include in the .html files
        $scope.customPluginForms = ['statsd'];

        //$log.debug("Options", options)
        $scope.close = close;

        $scope.humanizeLabel = function (key) {
          return key.split("_").join(" ");
        };

        $scope.addFlexField = function (fields, v) {
          if (!v.flex_field) return;

          fields[v.flex_field] = {
            "schema": {
              "fields": {
                "day": {
                  "type": "number",
                },
                "minute": {
                  "type": "number",
                },
                "second": {
                  "type": "number",
                },
                "year": {
                  "type": "number",
                },
                "month": {
                  "type": "number",
                },
                "hour": {
                  "type": "number",
                }
              }
            }
          };

          v.flex_field = ""
        };

        $scope.removeField = function (object, key) {
          delete object[key];
        };

        function initialize() {
          // Initialize plugin fields data
          $scope.data = _.merge(options.fields, $scope.schema, {
            consumer: {
              id: _.get($scope, 'plugin.consumer.id')
            }
          });

          // Define general modal window content
          $scope.description = $scope.data.meta ? $scope.data.meta.description
            : 'Configure the Plugin.';

          // Remove unwanted data fields that start with "_"
          Object.keys($scope.data.fields).forEach(function (key) {
            if (key.startsWith("_")) delete $scope.data.fields[key];
          });

          // Monkey patch for response-ratelimiting plugin
          if (_plugin.name === 'response-ratelimiting') {
            console.log("response-ratelimiting:limits =>", _plugin.config.limits);

            // Delete initial schema fields
            delete $scope.data.fields.limits.schema.fields.day;
            delete $scope.data.fields.limits.schema.fields.hour;
            delete $scope.data.fields.limits.schema.fields.minute;
            delete $scope.data.fields.limits.schema.fields.month;
            delete $scope.data.fields.limits.schema.fields.second;
            delete $scope.data.fields.limits.schema.fields.year;

            if (_plugin.config.limits) {
              Object.keys(_plugin.config.limits).forEach(function (key) {

                //console.log("_plugin.config.limits[key]",_plugin.config.limits[key])

                var inner_fields = {};
                Object.keys(_plugin.config.limits[key]).forEach(function (k) {
                  inner_fields[k] = {
                    type: 'number',
                    default: _plugin.config.limits[key][k]
                  }
                });

                $scope.data.fields.limits.schema.fields[key] = {

                  schema: {
                    fields: inner_fields
                  }
                }
              })
            }
          }

          // Customize data fields according to plugin
          PluginHelperService.customizeDataFieldsForPlugin(_plugin.name, $scope.data.fields);

          assignValues($scope.data.fields);
        }

        function assignValues(fields, prefix) {

          Object.keys(fields).forEach(function (item) {
            if (fields[item].schema) {
              assignValues(fields[item].schema.fields, prefix ? prefix + "." + item : item)
            } else {

              var path = prefix ? prefix + "." + item : item;
              var value = _.get(_plugin.config, path);

              if (fields[item].type === 'record' && fields[item].fields) {
                fields[item].fields.forEach(field => {
                  const prop = Object.keys(field)[0];
                  field[prop].value = _.get(_plugin.config, `${path}.${prop}`);
                })
              }

              if (fields[item].type === 'array'
                && value !== null && typeof value === 'object' && !Object.keys(value).length) {
                value = []
              }
              fields[item].value = value;
              fields[item].help = _.get(options, path) ? _.get(options, path).help : ''
            }
          });
        }

        $scope.updatePlugin = function () {

          $scope.busy = true;

          var data = _.omit($scope.plugin, ['config']);

          //if($scope.data.consumer_id instanceof Object) {
          //    data.consumer_id = $scope.data.consumer_id.id
          //}

          const consumerId = _.get($scope, 'data.consumer.id');
          if (consumerId) {
            data.consumer = {
              id: consumerId
            };
          }

          // Create request data "config." properties
          const config = PluginHelperService.createConfigProperties(_plugin.name,$scope.data.fields)

          const finalData = _.merge(data, config)

          console.log("REQUEST DATA =>", finalData);

          PluginsService.update(_plugin.id, finalData)
            .then(function (res) {
              $log.debug("updatePlugin", res);
              $scope.busy = false;
              $rootScope.$broadcast('plugin.updated', res.data);
              MessageService.success('"' + _plugin.name + '" plugin updated successfully!');
              $uibModalInstance.close({
                data: res.data
              });
            }).catch(function (err) {
            $scope.busy = false;
            $log.error("update plugin", err);
            var errors = {};

            if (err.data.customMessage) {
              Object.keys(err.data.customMessage).forEach(function (key) {
                errors[key.replace('config.', '')] = err.data.customMessage[key];
                MessageService.error(key + " : " + err.data.customMessage[key])
              })
            } else if (err.data.body && err.data.body.message) {
              MessageService.error(err.data.body.message)
            }

            $scope.errors = errors
          })
        };

        // Initialize used title items
        $scope.titleItems = ListConfig.getTitleItems(ConsumerModel.endpoint);

        // Add the consumers to the plugin options
        $scope.getConsumer = function (val) {

          if (!val) return;

          var commonParameters = {
            where: SocketHelperService.getWhere({
              searchWord: val,
              columns: $scope.titleItems
            })
          };

          return ConsumerModel
            .load(_.merge({}, commonParameters, {
              limit: 5
            }))
            .then(function (response) {
              return response.map(function (item) {
                return item;
              });
            });
        };

        function close() {
          $uibModalInstance.dismiss()
        }

        initialize();

        /**
         * STATSD
         */

        $scope.statsd = {
          metricNames : [
            'request_count',
            'request_size',
            'response_size',
            'latency',
            'status_count',
            'unique_users',
            'request_per_user',
            'upstream_latency',
            'kong_latency',
            'status_count_per_user'
          ],
          statTypes : [
            'gauge',
            'timer',
            'counter',
            'histogram',
            'meter',
            'set'
          ],
          consumerIndentifiers : [
            'consumer_id',
            'custom_id',
            'username'
          ],
          addMetric : function (metrics) {

            var template = {
              name : 'upstream_latency',
              stat_type: 'gauge',
              custom_identifier: 'consumer_id'
            };

            metrics.push(template);

          },
          removeMetric: function (metrics, index) {
            metrics.splice(index,1);
          }
        };

        $scope.getFieldProp = (field) => {
          return Object.keys(field)[0];
        }
      }
    ])
  ;
}());
<|endoftext|>


<commit_before>/**
 * core/user data store
 *
 * Site Kit by Google, Copyright 2020 Google LLC
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * Internal dependencies
 */
import Data from 'googlesitekit-data';
import authentication from './authentication';
import disconnect from './disconnect';
import userInfo from './user-info';
import notifications from './notifications';
import error from './error';
import { STORE_NAME } from './constants';

const store = Data.combineStores(
	Data.commonStore,
	authentication,
	disconnect,
	error,
  notifications,
	userInfo,
);

export const INITIAL_STATE = store.INITIAL_STATE;
export const actions = store.actions;
export const controls = store.controls;
export const reducer = store.reducer;
export const resolvers = store.resolvers;
export const selectors = store.selectors;

// Register this store on the global registry.
Data.registerStore( STORE_NAME, store );

export default store;
<commit_msg>Fix spacing and restore STORE_NAME export to user store.<commit_after>/**
 * core/user data store
 *
 * Site Kit by Google, Copyright 2020 Google LLC
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * Internal dependencies
 */
import Data from 'googlesitekit-data';
import authentication from './authentication';
import disconnect from './disconnect';
import userInfo from './user-info';
import notifications from './notifications';
import error from './error';
import { STORE_NAME } from './constants';

export { STORE_NAME };

const store = Data.combineStores(
	Data.commonStore,
	authentication,
	disconnect,
	error,
	notifications,
	userInfo,
);

export const INITIAL_STATE = store.INITIAL_STATE;
export const actions = store.actions;
export const controls = store.controls;
export const reducer = store.reducer;
export const resolvers = store.resolvers;
export const selectors = store.selectors;

// Register this store on the global registry.
Data.registerStore( STORE_NAME, store );

export default store;
<|endoftext|>


<commit_before>/**
 * modules/analytics data store: report.
 *
 * Site Kit by Google, Copyright 2020 Google LLC
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * External dependencies
 */
import invariant from 'invariant';
import isPlainObject from 'lodash/isPlainObject';

/**
 * Internal dependencies
 */
import API from 'googlesitekit-api';
import Data from 'googlesitekit-data';
import { STORE_NAME } from './constants';
import { stringifyObject } from '../../../util';
import { createFetchStore } from '../../../googlesitekit/data/create-fetch-store';
import {
	isValidMetrics,
	isValidDimensions,
	isValidDateRange,
	isValidOrders,
} from '../../../util/report-validation';

const fetchGetReportStore = createFetchStore( {
	baseName: 'getReport',
	controlCallback: ( { options } ) => {
		return API.get( 'modules', 'analytics', 'report', options );
	},
	reducerCallback: ( state, report, { options } ) => {
		return {
			...state,
			reports: {
				...state.reports,
				[ stringifyObject( options ) ]: report,
			},
		};
	},
	argsToParams: ( options ) => {
		const {
			metrics,
			dimensions,
			orderby,
		} = options;

		invariant( isPlainObject( options ), 'Options for Analytics report must be an object.' );
		invariant( isValidDateRange( options ), 'Either date range or start/end dates must be provided for Analytics report.' );

		if ( metrics ) {
			invariant(
				isValidMetrics( metrics ),
				'Metrics for an Analytics report must be either a string, an array of strings, an object, an array of objects or a mix of strings and objects. If an object is used, it must have "expression" and "alias" properties.',
			);
		}

		if ( dimensions ) {
			invariant(
				isValidDimensions( dimensions ),
				'Dimensions for an Analytics report must be either a string, an array of strings, an object, an array of objects or a mix of strings and objects. If an object is used, it must have "name" property.',
			);
		}

		if ( orderby ) {
			invariant(
				isValidOrders( orderby ),
				'Orders for an Analytics report must be either an object or an array of objects where each object should have "fieldName" and "sortOrder" properties.',
			);
		}

		return { options };
	},
} );

const BASE_INITIAL_STATE = {
	reports: {},
};

const baseResolvers = {
	*getReport( options = {} ) {
		const registry = yield Data.commonActions.getRegistry();
		const existingReport = registry.select( STORE_NAME ).getReport( options );

		// If there are already alerts loaded in state, consider it fulfilled
		// and don't make an API request.
		if ( existingReport ) {
			return;
		}

		yield fetchGetReportStore.actions.fetchGetReport( options );
	},
};

const baseSelectors = {
	/**
	 * Gets a Search Console report for the given options.
	 *
	 * @since n.e.x.t
	 *
	 * @param {Object}         state                     Data store's state.
	 * @param {Object}         options                   Optional. Options for generating the report.
	 * @param {string}         options.startDate         Required, unless dateRange is provided. Start date to query report data for as YYYY-mm-dd.
	 * @param {string}         options.endDate           Required, unless dateRange is provided. End date to query report data for as YYYY-mm-dd.
	 * @param {string}         options.dateRange         Required, alternative to startDate and endDate. A date range string such as 'last-28-days'.
	 * @param {boolean}        options.compareDateRanges Optional. Only relevant with dateRange. Default false.
	 * @param {boolean}        options.multiDateRange    Optional. Only relevant with dateRange. Default false.
	 * @param {Array.<string>} options.metrics           Required. List of metrics to query.
	 * @param {Array.<string>} options.dimensions        Optional. List of dimensions to group results by. Default an empty array.
	 * @param {Array.<Object>} options.orderby           Optional. An order definition object, or a list of order definition objects, each one containing 'fieldName' and 'sortOrder'. 'sortOrder' must be either 'ASCENDING' or 'DESCENDING'. Default empty array.
	 * @param {string}         options.url               Optional. URL to get a report for only this URL. Default an empty string.
	 * @param {number}         options.limit             Optional. Maximum number of entries to return. Default 1000.
	 * @return {(Array.<Object>|undefined)} A Search Console report; `undefined` if not loaded.
	 */
	getReport( state, options = {} ) {
		const { reports } = state;

		return reports[ stringifyObject( options ) ];
	},
};

const store = Data.combineStores(
	fetchGetReportStore,
	{
		INITIAL_STATE: BASE_INITIAL_STATE,
		resolvers: baseResolvers,
		selectors: baseSelectors,
	}
);

export const INITIAL_STATE = store.INITIAL_STATE;
export const actions = store.actions;
export const controls = store.controls;
export const reducer = store.reducer;
export const resolvers = store.resolvers;
export const selectors = store.selectors;

export default store;
<commit_msg>Update assets/js/modules/analytics/datastore/report.js<commit_after>/**
 * modules/analytics data store: report.
 *
 * Site Kit by Google, Copyright 2020 Google LLC
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * External dependencies
 */
import invariant from 'invariant';
import isPlainObject from 'lodash/isPlainObject';

/**
 * Internal dependencies
 */
import API from 'googlesitekit-api';
import Data from 'googlesitekit-data';
import { STORE_NAME } from './constants';
import { stringifyObject } from '../../../util';
import { createFetchStore } from '../../../googlesitekit/data/create-fetch-store';
import {
	isValidMetrics,
	isValidDimensions,
	isValidDateRange,
	isValidOrders,
} from '../../../util/report-validation';

const fetchGetReportStore = createFetchStore( {
	baseName: 'getReport',
	controlCallback: ( { options } ) => {
		return API.get( 'modules', 'analytics', 'report', options );
	},
	reducerCallback: ( state, report, { options } ) => {
		return {
			...state,
			reports: {
				...state.reports,
				[ stringifyObject( options ) ]: report,
			},
		};
	},
	argsToParams: ( options ) => {
		const {
			metrics,
			dimensions,
			orderby,
		} = options;

		invariant( isPlainObject( options ), 'Options for Analytics report must be an object.' );
		invariant( isValidDateRange( options ), 'Either date range or start/end dates must be provided for Analytics report.' );

		if ( metrics ) {
			invariant(
				isValidMetrics( metrics ),
				'Metrics for an Analytics report must be either a string, an array of strings, an object, an array of objects or a mix of strings and objects. If an object is used, it must have "expression" and "alias" properties.',
			);
		}

		if ( dimensions ) {
			invariant(
				isValidDimensions( dimensions ),
				'Dimensions for an Analytics report must be either a string, an array of strings, an object, an array of objects or a mix of strings and objects. If an object is used, it must have "name" property.',
			);
		}

		if ( orderby ) {
			invariant(
				isValidOrders( orderby ),
				'Orders for an Analytics report must be either an object or an array of objects where each object should have "fieldName" and "sortOrder" properties.',
			);
		}

		return { options };
	},
} );

const BASE_INITIAL_STATE = {
	reports: {},
};

const baseResolvers = {
	*getReport( options = {} ) {
		const registry = yield Data.commonActions.getRegistry();
		const existingReport = registry.select( STORE_NAME ).getReport( options );

		// If there are already alerts loaded in state, consider it fulfilled
		// and don't make an API request.
		if ( existingReport ) {
			return;
		}

		yield fetchGetReportStore.actions.fetchGetReport( options );
	},
};

const baseSelectors = {
	/**
	 * Gets an Analytics report for the given options.
	 *
	 * @since n.e.x.t
	 *
	 * @param {Object}         state                     Data store's state.
	 * @param {Object}         options                   Optional. Options for generating the report.
	 * @param {string}         options.startDate         Required, unless dateRange is provided. Start date to query report data for as YYYY-mm-dd.
	 * @param {string}         options.endDate           Required, unless dateRange is provided. End date to query report data for as YYYY-mm-dd.
	 * @param {string}         options.dateRange         Required, alternative to startDate and endDate. A date range string such as 'last-28-days'.
	 * @param {boolean}        options.compareDateRanges Optional. Only relevant with dateRange. Default false.
	 * @param {boolean}        options.multiDateRange    Optional. Only relevant with dateRange. Default false.
	 * @param {Array.<string>} options.metrics           Required. List of metrics to query.
	 * @param {Array.<string>} options.dimensions        Optional. List of dimensions to group results by. Default an empty array.
	 * @param {Array.<Object>} options.orderby           Optional. An order definition object, or a list of order definition objects, each one containing 'fieldName' and 'sortOrder'. 'sortOrder' must be either 'ASCENDING' or 'DESCENDING'. Default empty array.
	 * @param {string}         options.url               Optional. URL to get a report for only this URL. Default an empty string.
	 * @param {number}         options.limit             Optional. Maximum number of entries to return. Default 1000.
	 * @return {(Array.<Object>|undefined)} A Search Console report; `undefined` if not loaded.
	 */
	getReport( state, options = {} ) {
		const { reports } = state;

		return reports[ stringifyObject( options ) ];
	},
};

const store = Data.combineStores(
	fetchGetReportStore,
	{
		INITIAL_STATE: BASE_INITIAL_STATE,
		resolvers: baseResolvers,
		selectors: baseSelectors,
	}
);

export const INITIAL_STATE = store.INITIAL_STATE;
export const actions = store.actions;
export const controls = store.controls;
export const reducer = store.reducer;
export const resolvers = store.resolvers;
export const selectors = store.selectors;

export default store;
<|endoftext|>


<commit_before>// script.js

    // create the module
     // also include ngRoute for all our routing needs
    var atibApp = angular.module('atibApp', ['ngRoute']);

    // configure our routes
    atibApp.config(function($routeProvider) {
        $routeProvider

            // route for the home page
            .when('/', {
                templateUrl : 'pages/home.html',
                controller  : 'mainController'
            })

            // route for the about page
            .when('/about', {
                templateUrl : 'pages/about.html',
                controller  : 'aboutController'
            })

            // route for the contact page
            .when('/contact', {
                templateUrl : 'pages/contact.html',
                controller  : 'contactController'
            })

            .when('/contribute', {
            	templateUrl : 'pages/contribute.html',
            	controller  : 'contributeController'
            });
    });

    // create the controller and inject Angular's $scope
    atibApp.controller('mainController', function($scope) {
        // create a message to display in our view
        $scope.image = [{
        	src: 'img/trump-pepe-frog2.png',
        }];
    });

    atibApp.controller('aboutController', function($scope) {
        $scope.message = 'The purpose of this project is to build a web application that gathers information and data relating to the United States 46th President Donald Trump. This is a strictly data oriented project and is not a political statement. This project is to remain as un-biased as possible in its purpose of displaying data. The referenced data can include, but is not limited to, news articles, Twitter statistics and tweets, Facebook posts, and any other information that could be relevant. This project will attempt to accumulate all this data in an automated fashion with limited input from the creators.';
    });

    atibApp.controller('contactController', function($scope) {
        $scope.message = 'Contact us.';
    });

    atibApp.controller('contributeController', function($scope) {
        $scope.message = 'Feel like contributing to A.T.I.B ?';
    });
<commit_msg>updated about<commit_after>// script.js

    // create the module
     // also include ngRoute for all our routing needs
    var atibApp = angular.module('atibApp', ['ngRoute']);

    // configure our routes
    atibApp.config(function($routeProvider) {
        $routeProvider

            // route for the home page
            .when('/', {
                templateUrl : 'pages/home.html',
                controller  : 'mainController'
            })

            // route for the about page
            .when('/about', {
                templateUrl : 'pages/about.html',
                controller  : 'aboutController'
            })

            // route for the contact page
            .when('/contact', {
                templateUrl : 'pages/contact.html',
                controller  : 'contactController'
            })

            .when('/contribute', {
            	templateUrl : 'pages/contribute.html',
            	controller  : 'contributeController'
            });
    });

    // create the controller and inject Angular's $scope
    atibApp.controller('mainController', function($scope) {
        // create a message to display in our view
        $scope.image = [{
        	src: 'img/trump-pepe-frog2.png',
        }];
    });

    atibApp.controller('aboutController', function($scope) {
        $scope.message = 'The purpose of this project is to build a web application that gathers information and data relating to the United States 45th President Donald Trump. This is a strictly data oriented project and is not a political statement. This project is to remain as un-biased as possible in its purpose of displaying data. The referenced data can include, but is not limited to, news articles, Twitter statistics and tweets, Facebook posts, and any other information that could be relevant. This project will attempt to accumulate all this data in an automated fashion with limited input from the creators.';
    });

    atibApp.controller('contactController', function($scope) {
        $scope.message = 'Contact us.';
    });

    atibApp.controller('contributeController', function($scope) {
        $scope.message = 'Feel like contributing to A.T.I.B ?';
    });
<|endoftext|>


<commit_before>var nqp = require('nqp-runtime');
var CodeRef = require('nqp-runtime/code-ref');
var NQPArray = require('nqp-runtime/array');
var op = {};

var Scalar, True, False, Int, Num, Str, Code;

op.p6settypes = function(types) {
  Scalar = types.content.get('Scalar');
  True = types.content.get('True');
  False = types.content.get('False');
  Int = types.content.get('Int');
  Num = types.content.get('Num');
  Str = types.content.get('Str');
  Code = types.content.get('Code');
  Mu = types.content.get('Mu');
  return types;
};

op.p6bool = function(value) {
  return value ? True : False;
};

op.p6definite = function(obj) {
  return obj.typeObject_ ? False : True;
};

op.p6typecheckrv = function(rv, routine, bypassType) {
  // STUB
  return rv;
};

op.p6decontrv = function(rountine, cont) {
  // STUB
  return cont;
};

op.p6box_i = function(int) {
  var repr = Int._STable.REPR;
  var boxed = repr.allocate(Int._STable);
  boxed.$$setInt(int);
  return boxed;
};

op.p6box_n = function(num) {
  var repr = Num._STable.REPR;
  var boxed = repr.allocate(Num._STable);
  boxed.$$setNum(num);
  return boxed;
};

op.p6box_s = function(str) {
  var repr = Str._STable.REPR;
  var boxed = repr.allocate(Str._STable);
  boxed.$$setStr(str);
  return boxed;
};

op.p6captureouters2 = function(ctx, capList, target) {
  var cf = (target.outerCtx || closure.forcedOuter);

  if (cf === null) {
    return capList;
  }

  var elems = capList.$$elems();

  for (var i = 0; i < elems; i++) {
      var codeObj = capList.$$atpos(i);

      var closure = codeObj.$$getattr(Code, "$!do");

      var ctxToDiddle = (closure.outerCtx || closure.forcedOuter);
      ctxToDiddle.$$outer = cf;
  }

  return capList;
};

op.p6captureouters = function(ctx, capList) {

  var elems = capList.$$elems();

  for (var i = 0; i < elems; i++) {
      var codeObj = capList.$$atpos(i);
      var closure = codeObj.$$getattr(Code, "$!do");
      var ctxToDiddle = (closure.outerCtx || closure.forcedOuter);
      ctxToDiddle.$$outer = ctx;
  }

  return capList;
};

op.p6capturelex = function(ctx, codeObj) {

  var closure = codeObj.$$getattr(Code, "$!do");
  var wantedStaticInfo = closure.staticCode.outerCodeRef;

  if (ctx.codeRef().staticCode === wantedStaticInfo) {
    closure.forcedOuter = ctx;
  } else if (ctx.$$outer.codeRef().staticCode === wantedStaticInfo) {
    closure.forcedOuter = ctx.$$outer;
  }

  return codeObj;
};

op.p6var = function(cont) {
  if (cont != null && cont.$$iscont && cont.$$iscont()) {
    var wrapper = Scalar._STable.REPR.allocate(Scalar._STable);
    wrapper.$$bindattr(Scalar, '$!value', cont);
    return wrapper;
  } else {
    return cont;
  }
}

op.p6bindassert = function(ctx, value, type) {
  if (type !== Mu) {
    var decont = nqp.op.decont(ctx, value);
    if (nqp.op.istype(decont, type) == 0) {
      ctx.die("Type check failed in binding");
    }
  }
  return value;
};

op.p6store = function(ctx, cont, value) {
  if (cont) {
    cont.$$assign(ctx, nqp.op.decont(ctx, value));
  } else {
    if (!cont.STORE) {
      // TODO throw typed exception X::Assignment::RO
      ctx.die("Cannot assign to a non-container");
    } else {
      cont.STORE(ctx, null, cont, value);
    }
  }
  return cont;
};

op.p6argvmarray = function(ctx, args) {
  var array = [];
  console.log("in p6argvmarray");
  for (var i=2; i < args.length; i++) {
    array[i-2] = nqp.op.hllizefor(ctx, args[i], 'perl6');
  }
  return new NQPArray(array);
};

var containerSpecs = require('nqp-runtime/container-specs.js');

function RakudoScalar(STable) {
  this.STable = STable;
}

RakudoScalar.prototype.configure = function(conf) {
  this.setupSTable();
};

RakudoScalar.prototype.setupSTable = function() {
  this.STable.addInternalMethod('$$assignunchecked', function(ctx, value) {
    console.log('storing into rakudo_scalar unchecked');
    return this.$$bindattr(Scalar, '$!value', value);
  });

  this.STable.addInternalMethod('$$assign', function(ctx, value) {
    /* TODO - checking and WHENCE */
    return this.$$bindattr(Scalar, '$!value', value);
  });

  this.STable.addInternalMethod('$$decont', function(ctx) {
    return this.$$getattr(Scalar, '$!value');
  });

  this.STable.addInternalMethod('$$getInt', function(ctx) {
    return this.$$decont().$$getInt();
  });

  this.STable.addInternalMethod('$$iscont', function() {
    return 1;
  });
};

RakudoScalar.prototype.serialize = function(cursor) {
  console.log('// serializing rakudo_scalar');
};

RakudoScalar.prototype.deserialize = function(cursor) {
  console.log('// deserializing rakudo_scalar');
};

RakudoScalar.prototype.name = 'rakudo_scalar';

containerSpecs.rakudo_scalar = RakudoScalar;

nqp.loadOps({op: op});
module.exports = null;

<commit_msg>[js] Fix coercing a rakudo_scalar to num or str.<commit_after>var nqp = require('nqp-runtime');
var CodeRef = require('nqp-runtime/code-ref');
var NQPArray = require('nqp-runtime/array');
var op = {};

var Scalar, True, False, Int, Num, Str, Code;

op.p6settypes = function(types) {
  Scalar = types.content.get('Scalar');
  True = types.content.get('True');
  False = types.content.get('False');
  Int = types.content.get('Int');
  Num = types.content.get('Num');
  Str = types.content.get('Str');
  Code = types.content.get('Code');
  Mu = types.content.get('Mu');
  return types;
};

op.p6bool = function(value) {
  return value ? True : False;
};

op.p6definite = function(obj) {
  return obj.typeObject_ ? False : True;
};

op.p6typecheckrv = function(rv, routine, bypassType) {
  // STUB
  return rv;
};

op.p6decontrv = function(rountine, cont) {
  // STUB
  return cont;
};

op.p6box_i = function(int) {
  var repr = Int._STable.REPR;
  var boxed = repr.allocate(Int._STable);
  boxed.$$setInt(int);
  return boxed;
};

op.p6box_n = function(num) {
  var repr = Num._STable.REPR;
  var boxed = repr.allocate(Num._STable);
  boxed.$$setNum(num);
  return boxed;
};

op.p6box_s = function(str) {
  var repr = Str._STable.REPR;
  var boxed = repr.allocate(Str._STable);
  boxed.$$setStr(str);
  return boxed;
};

op.p6captureouters2 = function(ctx, capList, target) {
  var cf = (target.outerCtx || closure.forcedOuter);

  if (cf === null) {
    return capList;
  }

  var elems = capList.$$elems();

  for (var i = 0; i < elems; i++) {
      var codeObj = capList.$$atpos(i);

      var closure = codeObj.$$getattr(Code, "$!do");

      var ctxToDiddle = (closure.outerCtx || closure.forcedOuter);
      ctxToDiddle.$$outer = cf;
  }

  return capList;
};

op.p6captureouters = function(ctx, capList) {

  var elems = capList.$$elems();

  for (var i = 0; i < elems; i++) {
      var codeObj = capList.$$atpos(i);
      var closure = codeObj.$$getattr(Code, "$!do");
      var ctxToDiddle = (closure.outerCtx || closure.forcedOuter);
      ctxToDiddle.$$outer = ctx;
  }

  return capList;
};

op.p6capturelex = function(ctx, codeObj) {

  var closure = codeObj.$$getattr(Code, "$!do");
  var wantedStaticInfo = closure.staticCode.outerCodeRef;

  if (ctx.codeRef().staticCode === wantedStaticInfo) {
    closure.forcedOuter = ctx;
  } else if (ctx.$$outer.codeRef().staticCode === wantedStaticInfo) {
    closure.forcedOuter = ctx.$$outer;
  }

  return codeObj;
};

op.p6var = function(cont) {
  if (cont != null && cont.$$iscont && cont.$$iscont()) {
    var wrapper = Scalar._STable.REPR.allocate(Scalar._STable);
    wrapper.$$bindattr(Scalar, '$!value', cont);
    return wrapper;
  } else {
    return cont;
  }
}

op.p6bindassert = function(ctx, value, type) {
  if (type !== Mu) {
    var decont = nqp.op.decont(ctx, value);
    if (nqp.op.istype(decont, type) == 0) {
      ctx.die("Type check failed in binding");
    }
  }
  return value;
};

op.p6store = function(ctx, cont, value) {
  if (cont) {
    cont.$$assign(ctx, nqp.op.decont(ctx, value));
  } else {
    if (!cont.STORE) {
      // TODO throw typed exception X::Assignment::RO
      ctx.die("Cannot assign to a non-container");
    } else {
      cont.STORE(ctx, null, cont, value);
    }
  }
  return cont;
};

op.p6argvmarray = function(ctx, args) {
  var array = [];
  console.log("in p6argvmarray");
  for (var i=2; i < args.length; i++) {
    array[i-2] = nqp.op.hllizefor(ctx, args[i], 'perl6');
  }
  return new NQPArray(array);
};

var containerSpecs = require('nqp-runtime/container-specs.js');

function RakudoScalar(STable) {
  this.STable = STable;
}

RakudoScalar.prototype.configure = function(conf) {
  this.setupSTable();
};

RakudoScalar.prototype.setupSTable = function() {
  this.STable.addInternalMethod('$$assignunchecked', function(ctx, value) {
    console.log('storing into rakudo_scalar unchecked');
    return this.$$bindattr(Scalar, '$!value', value);
  });

  this.STable.addInternalMethod('$$assign', function(ctx, value) {
    /* TODO - checking and WHENCE */
    return this.$$bindattr(Scalar, '$!value', value);
  });

  this.STable.addInternalMethod('$$decont', function(ctx) {
    return this.$$getattr(Scalar, '$!value');
  });

  this.STable.addInternalMethod('$$getInt', function(ctx) {
    return this.$$decont().$$getInt();
  });

  this.STable.addInternalMethod('$$getNum', function(ctx) {
    return this.$$decont().$$getNum();
  });

  this.STable.addInternalMethod('$$getStr', function(ctx) {
    return this.$$decont().$$getStr();
  });

  this.STable.addInternalMethod('$$iscont', function() {
    return 1;
  });
};

RakudoScalar.prototype.serialize = function(cursor) {
  console.log('// serializing rakudo_scalar');
};

RakudoScalar.prototype.deserialize = function(cursor) {
  console.log('// deserializing rakudo_scalar');
};

RakudoScalar.prototype.name = 'rakudo_scalar';

containerSpecs.rakudo_scalar = RakudoScalar;

nqp.loadOps({op: op});
module.exports = null;

<|endoftext|>