<commit_before>/**
 * @param {Object} $    - Global jQuery object
 * @param {Object} bolt - The Bolt module
 */
(function ($, bolt) {
    'use strict';

    /**
     * Mode identifiers.
     *
     * @memberOf jQuery.widget.bolt.fieldSlug
     * @static
     * @type {Object.<string, number>}
     */
    var mode = {
        lock: 1,
        link: 2,
        edit: 3
    };

    /**
     * Slug field widget.
     *
     * @license http://opensource.org/licenses/mit-license.php MIT License
     * @author rarila
     *
     * @class fieldSlug
     * @memberOf jQuery.widget.bolt
     */
    $.widget('bolt.fieldSlug', /** @lends jQuery.widget.bolt.fieldSlug.prototype */ {
        /**
         * Default options.
         *
         * @property {string|null} contentId - Content Id
         * @property {string}      key       - The field key
         * @property {string}      slug      - Content slug
         * @property {Array}       uses      - Fields used to automatically generate a slug
         */
        options: {
            contentId: null,
            key:       '',
            slug:      '',
            uses:      []
        },

        /**
         * The constructor of the slug field widget.
         *
         * @private
         */
        _create: function () {
            var self = this,
                fieldset = this.element;

            /**
             * Refs to UI elements of this widget.
             *
             * @type {Object}
             * @name _ui
             * @memberOf jQuery.widget.bolt.fieldSlug.prototype
             * @private
             *
             * @property {Object} form  - The form this input is part of
             * @property {Object} group - Group container
             * @property {Object} data  - Data field
             * @property {Object} info  - Linkinfo block
             * @property {Object} uses  - Collection of uses fields
             */
            this._ui = {
                form:   this.element.closest('form'),
                group:  fieldset.find('.input-group'),
                data:   fieldset.find('input'),
                info:  fieldset.find('.linkinfo'),
                uses:   $()
            };

            $('[name]', self._ui.form).each(function () {
                if (self.options.uses.indexOf(this.name.replace(/\[\]$/, '')) >= 0) {
                    self._ui.uses = self._ui.uses.add($(this));
                }
            });

            /**
             * A timeout.
             *
             * @type {number}
             * @name _timeout
             * @memberOf jQuery.widget.bolt.fieldSlug.prototype
             * @private
             */
            this._timeout = 0;

            /**
             * Slug is generated, if true.
             *
             * @type {number}
             * @name _mode
             * @memberOf jQuery.widget.bolt.fieldSlug.prototype
             * @private
             */
            this._mode =
                (this._ui.group.hasClass('locked') ? mode.lock : 0) +
                (this._ui.group.hasClass('linked') ? mode.link : 0) +
                (this._ui.group.hasClass('editable') ? mode.edit : 0);

            if (this._mode === mode.linked) {
                this._startGeneration();
            }

            // Bind events.
            this._on({
                'click li.lock': function (event) {
                    event.preventDefault();
                    this._setMode(mode.lock);
                },
                'click li.link': function (event) {
                    event.preventDefault();
                    this._setMode(mode.link);
                },
                'click li.edit': function (event) {
                    event.preventDefault();
                    this._setMode(mode.edit);
                    this.element.find('input').focus();
                },
                'focusout input': function () {
                    if (this._mode === mode.edit) {
                        this._setMode(mode.lock);
                    }
                }
            });
        },

        /**
         * Cleanup.
         *
         * @private
         */
        _destroy: function () {
            clearTimeout(this._timeout);
        },

        /**
         * Update widgets visual and functional state.
         *
         * @private
         * @param {number} setMode - Mode to set
         */
        _setMode: function (setMode) {
            var modeIsLocked = setMode === mode.lock,
                modeIsLinked = setMode === mode.link,
                modeIsEditable = setMode === mode.edit;

            // Set dropdown button states.
            $('li.lock', this.element).toggleClass('disabled', modeIsLocked);
            $('li.link', this.element).toggleClass('disabled', modeIsLinked);
            $('li.edit', this.element).toggleClass('disabled', modeIsEditable);

            // Set container class.
            this._ui.group
                .toggleClass('locked', modeIsLocked)
                .toggleClass('linked', modeIsLinked)
                .toggleClass('edititable', modeIsEditable);

            // Show/hide edit warning.
            $('.warning', this.element).toggleClass('hidden', !modeIsEditable);

            // Toggle the input readonly.
            this._ui.data.prop('readonly', !modeIsEditable);

            if (modeIsLinked) {
                this._startGeneration();
            } else if (this._mode === mode.link) {
                this._stopGeneration();
            }

            this._mode = setMode;
        },

        /**
         * Get URI for slug from remote.
         *
         * @private
         * @param {string} text - New slug text
         */
        _getUri: function (text) {
            var self = this,
                data = {
                    title:           text,
                    contenttypeslug: self.options.slug,
                    id:              self.options.contentId,
                    slugfield:       self.options.key,
                    fulluri:         false
                };

            $.get(bolt.conf('paths.async') + 'makeuri', data)
                .done(function (uri) {
                    self._ui.data.val(uri);
                })
                .fail(function () {
                    console.log('failed to get an URI');
                });
        },

        /**
         * Start generating slugs from uses fields.
         *
         * @private
         */
        _startGeneration: function () {
            var self = this;

            self._buildSlug();

            self._on(self._ui.uses, {
                'change': function () {
                    self._buildSlug();
                },
                'input': function () {
                    self._buildSlug();
                }
            });
        },

        /**
         * Build the slug using the fields described in the uses parameter.
         *
         * @private
         */
        _buildSlug: function () {
            var self = this,
                term = '',
                value;

            $.each(self._ui.uses, function (i, field) {
                value = $(field).val();

                if (value) {
                    term += (typeof value === 'object' ? value.join(' ') : value) + ' ';
                }
            });

            clearTimeout(self._timeout);
            self._timeout = setTimeout(
                function () {
                    self._getUri(term.trim());
                },
                200
            );
        },

        /**
         * Stop generating slugs from uses fields.
         *
         * @private
         */
        _stopGeneration: function () {
            var self = this;

            clearTimeout(this._timeout);

            $(self.options.uses).each(function () {
                self._off($(this), 'change');
                self._off($(this), 'input');
            });
        }
    });
})(jQuery, Bolt);
<commit_msg>Fix not starting generation on empty entry<commit_after>/**
 * @param {Object} $    - Global jQuery object
 * @param {Object} bolt - The Bolt module
 */
(function ($, bolt) {
    'use strict';

    /**
     * Mode identifiers.
     *
     * @memberOf jQuery.widget.bolt.fieldSlug
     * @static
     * @type {Object.<string, number>}
     */
    var mode = {
        lock: 1,
        link: 2,
        edit: 3
    };

    /**
     * Slug field widget.
     *
     * @license http://opensource.org/licenses/mit-license.php MIT License
     * @author rarila
     *
     * @class fieldSlug
     * @memberOf jQuery.widget.bolt
     */
    $.widget('bolt.fieldSlug', /** @lends jQuery.widget.bolt.fieldSlug.prototype */ {
        /**
         * Default options.
         *
         * @property {string|null} contentId - Content Id
         * @property {string}      key       - The field key
         * @property {string}      slug      - Content slug
         * @property {Array}       uses      - Fields used to automatically generate a slug
         */
        options: {
            contentId: null,
            key:       '',
            slug:      '',
            uses:      []
        },

        /**
         * The constructor of the slug field widget.
         *
         * @private
         */
        _create: function () {
            var self = this,
                fieldset = this.element;

            /**
             * Refs to UI elements of this widget.
             *
             * @type {Object}
             * @name _ui
             * @memberOf jQuery.widget.bolt.fieldSlug.prototype
             * @private
             *
             * @property {Object} form  - The form this input is part of
             * @property {Object} group - Group container
             * @property {Object} data  - Data field
             * @property {Object} info  - Linkinfo block
             * @property {Object} uses  - Collection of uses fields
             */
            this._ui = {
                form:   this.element.closest('form'),
                group:  fieldset.find('.input-group'),
                data:   fieldset.find('input'),
                info:  fieldset.find('.linkinfo'),
                uses:   $()
            };

            $('[name]', self._ui.form).each(function () {
                if (self.options.uses.indexOf(this.name.replace(/\[\]$/, '')) >= 0) {
                    self._ui.uses = self._ui.uses.add($(this));
                }
            });

            /**
             * A timeout.
             *
             * @type {number}
             * @name _timeout
             * @memberOf jQuery.widget.bolt.fieldSlug.prototype
             * @private
             */
            this._timeout = 0;

            /**
             * Slug is generated, if true.
             *
             * @type {number}
             * @name _mode
             * @memberOf jQuery.widget.bolt.fieldSlug.prototype
             * @private
             */
            this._mode =
                (this._ui.group.hasClass('locked') ? mode.lock : 0) +
                (this._ui.group.hasClass('linked') ? mode.link : 0) +
                (this._ui.group.hasClass('editable') ? mode.edit : 0);

            if (this._mode === mode.link) {
                this._startGeneration();
            }

            // Bind events.
            this._on({
                'click li.lock': function (event) {
                    event.preventDefault();
                    this._setMode(mode.lock);
                },
                'click li.link': function (event) {
                    event.preventDefault();
                    this._setMode(mode.link);
                },
                'click li.edit': function (event) {
                    event.preventDefault();
                    this._setMode(mode.edit);
                    this.element.find('input').focus();
                },
                'focusout input': function () {
                    if (this._mode === mode.edit) {
                        this._setMode(mode.lock);
                    }
                }
            });
        },

        /**
         * Cleanup.
         *
         * @private
         */
        _destroy: function () {
            clearTimeout(this._timeout);
        },

        /**
         * Update widgets visual and functional state.
         *
         * @private
         * @param {number} setMode - Mode to set
         */
        _setMode: function (setMode) {
            var modeIsLocked = setMode === mode.lock,
                modeIsLinked = setMode === mode.link,
                modeIsEditable = setMode === mode.edit;

            // Set dropdown button states.
            $('li.lock', this.element).toggleClass('disabled', modeIsLocked);
            $('li.link', this.element).toggleClass('disabled', modeIsLinked);
            $('li.edit', this.element).toggleClass('disabled', modeIsEditable);

            // Set container class.
            this._ui.group
                .toggleClass('locked', modeIsLocked)
                .toggleClass('linked', modeIsLinked)
                .toggleClass('edititable', modeIsEditable);

            // Show/hide edit warning.
            $('.warning', this.element).toggleClass('hidden', !modeIsEditable);

            // Toggle the input readonly.
            this._ui.data.prop('readonly', !modeIsEditable);

            if (modeIsLinked) {
                this._startGeneration();
            } else if (this._mode === mode.link) {
                this._stopGeneration();
            }

            this._mode = setMode;
        },

        /**
         * Get URI for slug from remote.
         *
         * @private
         * @param {string} text - New slug text
         */
        _getUri: function (text) {
            var self = this,
                data = {
                    title:           text,
                    contenttypeslug: self.options.slug,
                    id:              self.options.contentId,
                    slugfield:       self.options.key,
                    fulluri:         false
                };

            $.get(bolt.conf('paths.async') + 'makeuri', data)
                .done(function (uri) {
                    self._ui.data.val(uri);
                })
                .fail(function () {
                    console.log('failed to get an URI');
                });
        },

        /**
         * Start generating slugs from uses fields.
         *
         * @private
         */
        _startGeneration: function () {
            var self = this;

            self._buildSlug();

            self._on(self._ui.uses, {
                'change': function () {
                    self._buildSlug();
                },
                'input': function () {
                    self._buildSlug();
                }
            });
        },

        /**
         * Build the slug using the fields described in the uses parameter.
         *
         * @private
         */
        _buildSlug: function () {
            var self = this,
                term = '',
                value;

            $.each(self._ui.uses, function (i, field) {
                value = $(field).val();

                if (value) {
                    term += (typeof value === 'object' ? value.join(' ') : value) + ' ';
                }
            });

            clearTimeout(self._timeout);
            self._timeout = setTimeout(
                function () {
                    self._getUri(term.trim());
                },
                200
            );
        },

        /**
         * Stop generating slugs from uses fields.
         *
         * @private
         */
        _stopGeneration: function () {
            var self = this;

            clearTimeout(this._timeout);

            $(self.options.uses).each(function () {
                self._off($(this), 'change');
                self._off($(this), 'input');
            });
        }
    });
})(jQuery, Bolt);
<|endoftext|>


<commit_before>var pingTime = 10000;
var notificationIcon = '/favicon.ico';

$(function ()
{
	if ($('meta[property="og:image"]').length != 0)
		notificationIcon = $('meta[property="og:image"]').attr('content');

	$.get(notificationIcon).fail(function() {
		notificationIcon = smf_images_url + '/blank.png';
	})
});

var updateAlerts = function ()
{
	var unreadAlerts;

	// Prevent multiple notifications across browsers
	if (typeof localStorage != 'undefined')
	{
		unreadAlerts = localStorage.getItem('alertsCounter');

		if (unreadAlerts != parseInt(unreadAlerts))
			return true;

		if ($('#alerts_menu_top > .amt:first').is(':visible'))
			$('#alerts_menu_top > .amt:first').text(unreadAlerts);
		else if (!$('#alerts_menu_top > .amt:first').is(':visible') && unreadAlerts != 0)
			$('#alerts_menu_top').append(' ' + unreadAlerts + '');

		if (localStorage.getItem('alertsPoll') != null && (+(new Date()) - localStorage.getItem('alertsPoll')) < pingTime)
		{
			setTimeout(updateAlerts, 1000);
			return true;
		}
		localStorage.setItem('alertsPoll', +(new Date()));
	}
	else
		unreadAlerts = $('#alerts_menu_top > .amt:first').text() ? $('#alerts_menu_top > .amt:first').text() : 0;

	unreadAlerts = parseInt(unreadAlerts);

	$.get(smf_scripturl + '?action=profile;area=alerts_popup;counter=' + unreadAlerts + ';u=' + smf_member_id, function (data)
	{
		var alerts = $(data).find('.unread_notify');
		if (alerts.length == 0)
			return true;

		unreadAlerts += alerts.length;

		if (unreadAlerts != parseInt(unreadAlerts))
			return true;

		if (typeof localStorage != 'undefined')
			localStorage.setItem('alertsCounter', unreadAlerts);

		if ($('#alerts_menu_top > .amt:first').is(':visible'))
			$('#alerts_menu_top > .amt:first').text(unreadAlerts);
		else if (!$('#alerts_menu_top > .amt:first').is(':visible') && unreadAlerts != 0)
			$('#alerts_menu_top').append('' + unreadAlerts + '');

		$.each(alerts, function(index, item)
		{
			var notification = notify.createNotification(new_alert_title, {
				body: $(item).find('div.details:first span.alert_text').text(),
				icon: notificationIcon
			});

			notification.click(function()
			{
				window.focus();
				if (!$('#alerts_menu').is(':visible'))
					$('#alerts_menu_top').click();

				this.close();
			});

			if (alert_timeout > 0)
				setTimeout(function()
				{
					notification.close();
				}, alert_timeout);
		});

		var user_menus = new smc_PopupMenu();
		user_menus.add("alerts", smf_scripturl + "?action=profile;area=alerts_popup;u=" + smf_member_id);
	});

	setTimeout(updateAlerts, pingTime);
}

$(function ()
{
	var permission = notify.permissionLevel();
	if (permission == notify.PERMISSION_DEFAULT)
	{
		$('#alerts_menu_top').click(function()
		{
			window.notify.requestPermission(function()
			{
				if (notify.permissionLevel() == notify.PERMISSION_GRANTED)
					updateAlerts();
			});
		});
	}
	else if (permission == notify.PERMISSION_GRANTED)
	{
		setTimeout(updateAlerts, pingTime);
		if (typeof localStorage != 'undefined')
			localStorage.setItem('alertsCounter', parseInt($('#alerts_menu_top > .amt:first').text() ? $('#alerts_menu_top > .amt:first').text() : 0));
	}
});

/**
* Copyright 2012 Tsvetan Tsvetkov
*
* 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.
*
* Author: Tsvetan Tsvetkov (tsekach@gmail.com)
*/
(function (win) {
	/*
	 Safari native methods required for Notifications do NOT run in strict mode.
	 */
	//"use strict";
	var PERMISSION_DEFAULT = "default",
		PERMISSION_GRANTED = "granted",
		PERMISSION_DENIED = "denied",
		PERMISSION = [PERMISSION_GRANTED, PERMISSION_DEFAULT, PERMISSION_DENIED],
		defaultSetting = {
			pageVisibility: false,
			autoClose: 0
		},
		empty = {},
		emptyString = "",
		isSupported = (function () {
			var isSupported = false;
			/*
			 * Use try {} catch() {} because the check for IE may throws an exception
			 * if the code is run on browser that is not Safar/Chrome/IE or
			 * Firefox with html5notifications plugin.
			 *
			 * Also, we canNOT detect if msIsSiteMode method exists, as it is
			 * a method of host object. In IE check for existing method of host
			 * object returns undefined. So, we try to run it - if it runs
			 * successfully - then it is IE9+, if not - an exceptions is thrown.
			 */
			try {
				isSupported = !!(/* Safari, Chrome */win.Notification || /* Chrome & ff-html5notifications plugin */win.webkitNotifications || /* Firefox Mobile */navigator.mozNotification || /* IE9+ */(win.external && win.external.msIsSiteMode() !== undefined));
			} catch (e) {
			}
			return isSupported;
		}()),
		ieVerification = Math.floor((Math.random() * 10) + 1),
		isFunction = function (value) {
			return (value && (value).constructor === Function);
		},
		isString = function (value) {
			return (value && (value).constructor === String);
		},
		isObject = function (value) {
			return (value && (value).constructor === Object);
		},
		/**
		 * Dojo Mixin
		 */
			mixin = function (target, source) {
			var name, s;
			for (name in source) {
				s = source[name];
				if (!(name in target) || (target[name] !== s && (!(name in empty) || empty[name] !== s))) {
					target[name] = s;
				}
			}
			return target; // Object
		},
		noop = function () {
		},
		settings = defaultSetting;

	function getNotification(title, options) {
		var notification;
		if (win.Notification) { /* Safari 6, Chrome (23+) */
			notification = new win.Notification(title, {
				/* The notification's icon - For Chrome in Windows, Linux & Chrome OS */
				icon: isString(options.icon) ? options.icon : options.icon.x32,
				/* The notification’s subtitle. */
				body: options.body || emptyString,
				/*
				 The notification’s unique identifier.
				 This prevents duplicate entries from appearing if the user has multiple instances of your website open at once.
				 */
				tag: options.tag || emptyString
			});
		} else if (win.webkitNotifications) { /* FF with html5Notifications plugin installed */
			notification = win.webkitNotifications.createNotification(options.icon, title, options.body);
			notification.show();
		} else if (navigator.mozNotification) { /* Firefox Mobile */
			notification = navigator.mozNotification.createNotification(title, options.body, options.icon);
			notification.show();
		} else if (win.external && win.external.msIsSiteMode()) { /* IE9+ */
			//Clear any previous notifications
			win.external.msSiteModeClearIconOverlay();
			win.external.msSiteModeSetIconOverlay((isString(options.icon) ? options.icon : options.icon.x16), title);
			win.external.msSiteModeActivate();
			notification = {
				"ieVerification": ieVerification + 1
			};
		}
		return notification;
	}

	function getWrapper(notification) {
		return {
			close: function () {
				if (notification) {
					if (notification.close) {
						//https://code.google.com/p/ff-html5notifications/issues/detail?id=58
						notification.close();
					} else if (win.external && win.external.msIsSiteMode()) {
						if (notification.ieVerification === ieVerification) {
							win.external.msSiteModeClearIconOverlay();
						}
					}
				}
			},
			click: function(callback) {
				notification.addEventListener('click', callback);
			}
		};
	}

	function requestPermission(callback) {
		if (!isSupported) {
			return;
		}
		var callbackFunction = isFunction(callback) ? callback : noop;
		if (win.webkitNotifications && win.webkitNotifications.checkPermission) {
			/*
			 * Chrome 23 supports win.Notification.requestPermission, but it
			 * breaks the browsers, so use the old-webkit-prefixed
			 * win.webkitNotifications.checkPermission instead.
			 *
			 * Firefox with html5notifications plugin supports this method
			 * for requesting permissions.
			 */
			win.webkitNotifications.requestPermission(callbackFunction);
		} else if (win.Notification && win.Notification.requestPermission) {
			win.Notification.requestPermission(callbackFunction);
		}
	}

	function permissionLevel() {
		var permission;
		if (!isSupported) {
			return;
		}
		if (win.Notification && win.Notification.permissionLevel) {
			//Safari 6
			permission = win.Notification.permissionLevel();
		} else if (win.webkitNotifications && win.webkitNotifications.checkPermission) {
			//Chrome & Firefox with html5-notifications plugin installed
			permission = PERMISSION[win.webkitNotifications.checkPermission()];
		} else if (navigator.mozNotification) {
			//Firefox Mobile
			permission = PERMISSION_GRANTED;
		} else if (win.Notification && win.Notification.permission) {
			// Firefox 23+
			permission = win.Notification.permission;
		} else if (win.external && (win.external.msIsSiteMode() !== undefined)) { /* keep last */
			//IE9+
			permission = win.external.msIsSiteMode() ? PERMISSION_GRANTED : PERMISSION_DEFAULT;
		}
		return permission;
	}

	/**
	 *
	 */
	function config(params) {
		if (params && isObject(params)) {
			mixin(settings, params);
		}
		return settings;
	}

	function isDocumentHidden() {
		return settings.pageVisibility ? (document.hidden || document.msHidden || document.mozHidden || document.webkitHidden) : true;
	}

	function createNotification(title, options) {
		var notification,
			notificationWrapper;
		/*
		 Return undefined if notifications are not supported.

		 Return undefined if no permissions for displaying notifications.

		 Title and icons are required. Return undefined if not set.
		 */
		if (isSupported && isDocumentHidden() && isString(title) && (options && (isString(options.icon) || isObject(options.icon))) && (permissionLevel() === PERMISSION_GRANTED)) {
			notification = getNotification(title, options);
		}
		notificationWrapper = getWrapper(notification);
		//Auto-close notification
		if (settings.autoClose && notification && !notification.ieVerification && notification.addEventListener) {
			notification.addEventListener("show", function () {
				var notification = notificationWrapper;
				win.setTimeout(function () {
					notification.close();
				}, settings.autoClose);
			});
		}
		return notificationWrapper;
	}

	win.notify = {
		PERMISSION_DEFAULT: PERMISSION_DEFAULT,
		PERMISSION_GRANTED: PERMISSION_GRANTED,
		PERMISSION_DENIED: PERMISSION_DENIED,
		isSupported: isSupported,
		config: config,
		createNotification: createNotification,
		permissionLevel: permissionLevel,
		requestPermission: requestPermission
	};
	if (isFunction(Object.seal)) {
		Object.seal(win.notify);
	}
}(window));<commit_msg>Prevents generating duplicate alert counter spans in top menu Fixes #5788<commit_after>var pingTime = 10000;
var notificationIcon = '/favicon.ico';

$(function ()
{
	if ($('meta[property="og:image"]').length != 0)
		notificationIcon = $('meta[property="og:image"]').attr('content');

	$.get(notificationIcon).fail(function() {
		notificationIcon = smf_images_url + '/blank.png';
	})
});

var updateAlerts = function ()
{
	var unreadAlerts;

	// Prevent multiple notifications across browsers
	if (typeof localStorage != 'undefined')
	{
		unreadAlerts = localStorage.getItem('alertsCounter');

		if (unreadAlerts != parseInt(unreadAlerts))
			return true;

		if ($('#alerts_menu_top > .amt:first').length)
			$('#alerts_menu_top > .amt:first').text(unreadAlerts);
		else if (!$('#alerts_menu_top > .amt:first').length && unreadAlerts != 0)
			$('#alerts_menu_top').append(' ' + unreadAlerts + '');

		if (localStorage.getItem('alertsPoll') != null && (+(new Date()) - localStorage.getItem('alertsPoll')) < pingTime)
		{
			setTimeout(updateAlerts, 1000);
			return true;
		}
		localStorage.setItem('alertsPoll', +(new Date()));
	}
	else
		unreadAlerts = $('#alerts_menu_top > .amt:first').text() ? $('#alerts_menu_top > .amt:first').text() : 0;

	unreadAlerts = parseInt(unreadAlerts);

	$.get(smf_scripturl + '?action=profile;area=alerts_popup;counter=' + unreadAlerts + ';u=' + smf_member_id, function (data)
	{
		var alerts = $(data).find('.unread_notify');
		if (alerts.length == 0)
			return true;

		unreadAlerts += alerts.length;

		if (unreadAlerts != parseInt(unreadAlerts))
			return true;

		if (typeof localStorage != 'undefined')
			localStorage.setItem('alertsCounter', unreadAlerts);

		if ($('#alerts_menu_top > .amt:first').length)
			$('#alerts_menu_top > .amt:first').text(unreadAlerts);
		else if (!$('#alerts_menu_top > .amt:first').length && unreadAlerts != 0)
			$('#alerts_menu_top').append('' + unreadAlerts + '');

		$.each(alerts, function(index, item)
		{
			var notification = notify.createNotification(new_alert_title, {
				body: $(item).find('div.details:first span.alert_text').text(),
				icon: notificationIcon
			});

			notification.click(function()
			{
				window.focus();
				if (!$('#alerts_menu').is(':visible'))
					$('#alerts_menu_top').click();

				this.close();
			});

			if (alert_timeout > 0)
				setTimeout(function()
				{
					notification.close();
				}, alert_timeout);
		});

		var user_menus = new smc_PopupMenu();
		user_menus.add("alerts", smf_scripturl + "?action=profile;area=alerts_popup;u=" + smf_member_id);
	});

	setTimeout(updateAlerts, pingTime);
}

$(function ()
{
	var permission = notify.permissionLevel();
	if (permission == notify.PERMISSION_DEFAULT)
	{
		$('#alerts_menu_top').click(function()
		{
			window.notify.requestPermission(function()
			{
				if (notify.permissionLevel() == notify.PERMISSION_GRANTED)
					updateAlerts();
			});
		});
	}
	else if (permission == notify.PERMISSION_GRANTED)
	{
		setTimeout(updateAlerts, pingTime);
		if (typeof localStorage != 'undefined')
			localStorage.setItem('alertsCounter', parseInt($('#alerts_menu_top > .amt:first').text() ? $('#alerts_menu_top > .amt:first').text() : 0));
	}
});

/**
* Copyright 2012 Tsvetan Tsvetkov
*
* 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.
*
* Author: Tsvetan Tsvetkov (tsekach@gmail.com)
*/
(function (win) {
	/*
	 Safari native methods required for Notifications do NOT run in strict mode.
	 */
	//"use strict";
	var PERMISSION_DEFAULT = "default",
		PERMISSION_GRANTED = "granted",
		PERMISSION_DENIED = "denied",
		PERMISSION = [PERMISSION_GRANTED, PERMISSION_DEFAULT, PERMISSION_DENIED],
		defaultSetting = {
			pageVisibility: false,
			autoClose: 0
		},
		empty = {},
		emptyString = "",
		isSupported = (function () {
			var isSupported = false;
			/*
			 * Use try {} catch() {} because the check for IE may throws an exception
			 * if the code is run on browser that is not Safar/Chrome/IE or
			 * Firefox with html5notifications plugin.
			 *
			 * Also, we canNOT detect if msIsSiteMode method exists, as it is
			 * a method of host object. In IE check for existing method of host
			 * object returns undefined. So, we try to run it - if it runs
			 * successfully - then it is IE9+, if not - an exceptions is thrown.
			 */
			try {
				isSupported = !!(/* Safari, Chrome */win.Notification || /* Chrome & ff-html5notifications plugin */win.webkitNotifications || /* Firefox Mobile */navigator.mozNotification || /* IE9+ */(win.external && win.external.msIsSiteMode() !== undefined));
			} catch (e) {
			}
			return isSupported;
		}()),
		ieVerification = Math.floor((Math.random() * 10) + 1),
		isFunction = function (value) {
			return (value && (value).constructor === Function);
		},
		isString = function (value) {
			return (value && (value).constructor === String);
		},
		isObject = function (value) {
			return (value && (value).constructor === Object);
		},
		/**
		 * Dojo Mixin
		 */
			mixin = function (target, source) {
			var name, s;
			for (name in source) {
				s = source[name];
				if (!(name in target) || (target[name] !== s && (!(name in empty) || empty[name] !== s))) {
					target[name] = s;
				}
			}
			return target; // Object
		},
		noop = function () {
		},
		settings = defaultSetting;

	function getNotification(title, options) {
		var notification;
		if (win.Notification) { /* Safari 6, Chrome (23+) */
			notification = new win.Notification(title, {
				/* The notification's icon - For Chrome in Windows, Linux & Chrome OS */
				icon: isString(options.icon) ? options.icon : options.icon.x32,
				/* The notification’s subtitle. */
				body: options.body || emptyString,
				/*
				 The notification’s unique identifier.
				 This prevents duplicate entries from appearing if the user has multiple instances of your website open at once.
				 */
				tag: options.tag || emptyString
			});
		} else if (win.webkitNotifications) { /* FF with html5Notifications plugin installed */
			notification = win.webkitNotifications.createNotification(options.icon, title, options.body);
			notification.show();
		} else if (navigator.mozNotification) { /* Firefox Mobile */
			notification = navigator.mozNotification.createNotification(title, options.body, options.icon);
			notification.show();
		} else if (win.external && win.external.msIsSiteMode()) { /* IE9+ */
			//Clear any previous notifications
			win.external.msSiteModeClearIconOverlay();
			win.external.msSiteModeSetIconOverlay((isString(options.icon) ? options.icon : options.icon.x16), title);
			win.external.msSiteModeActivate();
			notification = {
				"ieVerification": ieVerification + 1
			};
		}
		return notification;
	}

	function getWrapper(notification) {
		return {
			close: function () {
				if (notification) {
					if (notification.close) {
						//https://code.google.com/p/ff-html5notifications/issues/detail?id=58
						notification.close();
					} else if (win.external && win.external.msIsSiteMode()) {
						if (notification.ieVerification === ieVerification) {
							win.external.msSiteModeClearIconOverlay();
						}
					}
				}
			},
			click: function(callback) {
				notification.addEventListener('click', callback);
			}
		};
	}

	function requestPermission(callback) {
		if (!isSupported) {
			return;
		}
		var callbackFunction = isFunction(callback) ? callback : noop;
		if (win.webkitNotifications && win.webkitNotifications.checkPermission) {
			/*
			 * Chrome 23 supports win.Notification.requestPermission, but it
			 * breaks the browsers, so use the old-webkit-prefixed
			 * win.webkitNotifications.checkPermission instead.
			 *
			 * Firefox with html5notifications plugin supports this method
			 * for requesting permissions.
			 */
			win.webkitNotifications.requestPermission(callbackFunction);
		} else if (win.Notification && win.Notification.requestPermission) {
			win.Notification.requestPermission(callbackFunction);
		}
	}

	function permissionLevel() {
		var permission;
		if (!isSupported) {
			return;
		}
		if (win.Notification && win.Notification.permissionLevel) {
			//Safari 6
			permission = win.Notification.permissionLevel();
		} else if (win.webkitNotifications && win.webkitNotifications.checkPermission) {
			//Chrome & Firefox with html5-notifications plugin installed
			permission = PERMISSION[win.webkitNotifications.checkPermission()];
		} else if (navigator.mozNotification) {
			//Firefox Mobile
			permission = PERMISSION_GRANTED;
		} else if (win.Notification && win.Notification.permission) {
			// Firefox 23+
			permission = win.Notification.permission;
		} else if (win.external && (win.external.msIsSiteMode() !== undefined)) { /* keep last */
			//IE9+
			permission = win.external.msIsSiteMode() ? PERMISSION_GRANTED : PERMISSION_DEFAULT;
		}
		return permission;
	}

	/**
	 *
	 */
	function config(params) {
		if (params && isObject(params)) {
			mixin(settings, params);
		}
		return settings;
	}

	function isDocumentHidden() {
		return settings.pageVisibility ? (document.hidden || document.msHidden || document.mozHidden || document.webkitHidden) : true;
	}

	function createNotification(title, options) {
		var notification,
			notificationWrapper;
		/*
		 Return undefined if notifications are not supported.

		 Return undefined if no permissions for displaying notifications.

		 Title and icons are required. Return undefined if not set.
		 */
		if (isSupported && isDocumentHidden() && isString(title) && (options && (isString(options.icon) || isObject(options.icon))) && (permissionLevel() === PERMISSION_GRANTED)) {
			notification = getNotification(title, options);
		}
		notificationWrapper = getWrapper(notification);
		//Auto-close notification
		if (settings.autoClose && notification && !notification.ieVerification && notification.addEventListener) {
			notification.addEventListener("show", function () {
				var notification = notificationWrapper;
				win.setTimeout(function () {
					notification.close();
				}, settings.autoClose);
			});
		}
		return notificationWrapper;
	}

	win.notify = {
		PERMISSION_DEFAULT: PERMISSION_DEFAULT,
		PERMISSION_GRANTED: PERMISSION_GRANTED,
		PERMISSION_DENIED: PERMISSION_DENIED,
		isSupported: isSupported,
		config: config,
		createNotification: createNotification,
		permissionLevel: permissionLevel,
		requestPermission: requestPermission
	};
	if (isFunction(Object.seal)) {
		Object.seal(win.notify);
	}
}(window));<|endoftext|>


<commit_before>/*global table */

/**
 * Determine if a `HTMLTableCellElement` is a data cell
 * @param  {HTMLTableCellElement}  node The table cell to test
 * @return {Boolean}
 */
table.isDataCell = function (cell) {
	// @see http://www.whatwg.org/specs/web-apps/current-work/multipage/tables.html#empty-cell
	if (!cell.children.length && !cell.innerText.trim()) {
		return false;
	}
	return cell.nodeName === 'TD';
};<commit_msg>innerText doesnt work in Firefox<commit_after>/*global table */

/**
 * Determine if a `HTMLTableCellElement` is a data cell
 * @param  {HTMLTableCellElement}  node The table cell to test
 * @return {Boolean}
 */
table.isDataCell = function (cell) {
	// @see http://www.whatwg.org/specs/web-apps/current-work/multipage/tables.html#empty-cell
	if (!cell.children.length && !cell.textContent.trim()) {
		return false;
	}
	return cell.nodeName === 'TD';
};<|endoftext|>


<commit_before>/**
 * Created by Dean on 6/21/2015.
 */

var char = USERTEST.createNPCBase(),
	npc1 = USERTEST.createNPCBase(),
	npc2 = USERTEST.createNPCBase(),
	npc3 = USERTEST.createNPCBase(),
	enemy1 = USERTEST.createNPCBase(),
	enemy2 = USERTEST.createNPCBase(),
	enemy3 = USERTEST.createNPCBase(),
	loc1 = USERTEST.createLocationBase("1:1"),
	loc2 = USERTEST.createLocationBase("2:2"),
	loc3 = USERTEST.createLocationBase("3:3"),
	questGen = QUESTIFY.createQuestGenerator();

(function createConditionFunctions(){
	questGen.conditionFunctions.checkIfCharIsAtLocation = function(somebody, location) {
		return somebody.location === location;
	};
	questGen.conditionFunctions.checkIfCharIsAtLocationAndWantsItem = function(somebody, location, item) {
		if (somebody.hasOwnProperty("desires")) {
			return somebody.location === location && somebody.desires.indexOf(item) !== -1;
		}
		return false;
	};
	questGen.conditionFunctions.checkIfCharIsAlive = function(somebody) {
		return somebody.isAlive;
	};
	questGen.conditionFunctions.checkIfCharIsDead = function(somebody) {
		return !somebody.isAlive;
	};
	questGen.conditionFunctions.checkIfCharKnowsInformation = function(somebody, info) {
		return somebody.knownInformation.indexOf(info) !== -1;
	};
	questGen.conditionFunctions.checkIfCharHasItem = function(somebody, item) {
		return somebody.inventory.indexOf(item) !== -1;
	};
	questGen.conditionFunctions.checkIfCharHasPrisoner = function(somebody, other) {
		if (somebody.hasOwnProperty("prisoners")) {
			return somebody.prisoners.indexOf(other) !== -1;
		}
		return false;
	};
	questGen.conditionFunctions.checkIfCharHasItemAndOtherDoesNot = function(somebody, other, item) {
		return somebody.inventory.indexOf(item) !== -1 && somebody.inventory.indexOf(item) === -1;
	};
	questGen.conditionFunctions.checkIfCharIsAtLocationAndHasItem = function(somebody, location, item) {
		return somebody.location === location && somebody.inventory.indexOf(item) !== -1;
	};
	questGen.conditionFunctions.checkIfItemIsAtLocation = function(item, location) {
		return item.location === location;
	};
	questGen.conditionFunctions.checkIfCharIsAtLocationAndKnowsInformation = function(somebody, location, info) {
		return questGen.conditionFunctions.checkIfCharIsAtLocation(somebody, location) && questGen.conditionFunctions.checkIfCharIsAtLocationAndKnowsInformation(somebody, info);
	};
}());

(function createAtomicActions(){
	questGen.atomicActions.goto = QUESTIFY.createAtomicAction([questGen.conditionFunctions.checkIfCharIsAtLocation]);

	questGen.atomicActions.kill = QUESTIFY.createAtomicAction([questGen.conditionFunctions.checkIfCharIsAtLocation,
															  questGen.conditionFunctions.checkIfCharIsDead]);

	questGen.atomicActions.report = QUESTIFY.createAtomicAction([questGen.conditionFunctions.checkIfCharIsAtLocation,
														        questGen.conditionFunctions.checkIfCharKnowsInformation]);

	questGen.atomicActions.capture = QUESTIFY.createAtomicAction([questGen.conditionFunctions.checkIfCharHasPrisoner]);

	questGen.atomicActions.give = QUESTIFY.createAtomicAction([questGen.conditionFunctions.checkIfCharHasItem]);

	questGen.atomicActions.take = QUESTIFY.createAtomicAction([questGen.conditionFunctions.checkIfCharHasItemAndOtherDoesNot]);

	questGen.atomicActions.gather = QUESTIFY.createAtomicAction([questGen.conditionFunctions.checkIfCharIsAtLocation,
							                                    questGen.conditionFunctions.checkIfCharHasItem]);

	questGen.atomicActions.listen = QUESTIFY.createAtomicAction([questGen.conditionFunctions.checkIfCharKnowsInformation]);
}());

(function createStrategies(){
	questGen.strategies.killEnemy =
		QUESTIFY.createStrategy([
			{atomicAction: 'goto',   actionArgs: [["DEF:pc", "ENEMY:enemy:location"]]},
			{atomicAction: 'kill',   actionArgs: [["DEF:pc", "ENEMY:enemy:location"], ["ENEMY:enemy"]]},
			{atomicAction: 'goto',   actionArgs: [["DEF:pc", "DEF:start"]]},
			{atomicAction: 'report', actionArgs: [["DEF:giver", "DEF:pc:location"], ["DEF:giver", "ENEMY:enemy"]]}]);

	questGen.strategies.explore =
		QUESTIFY.createStrategy([
			{atomicAction: 'goto',   actionArgs: [["DEF:pc", "LOC:poi"], ["DEF:pc", "LOC:poi"]]},
			{atomicAction: 'goto',   actionArgs: [["DEF:pc", "DEF:start"], ["DEF:pc", "DEF:start"]]}]);

	questGen.strategies.goAndLearn =
		QUESTIFY.createStrategy([
			{atomicAction: 'goto',   actionArgs: [["DEF:pc", "NPC:otherNPC:location"], ["DEF:pc:location", "NPC:otherNPC:location"]]},
			{atomicAction: 'listen', actionArgs: [["DEF:pc", "LOC:locInfo"]]}]);
}());

(function createMotivations(){
	questGen.motivations.reputation = QUESTIFY.createMotivation([questGen.strategies.killEnemy]);
	questGen.motivations.knowledge = QUESTIFY.createMotivation([questGen.strategies.explore, questGen.strategies.goAndLearn]);
}());

function noSharedStateTest() {
	/*In this test, we create two very similar quests and make sure that the progress in one is not reflected in the other*/
	npc1 = USERTEST.createNPCBase("Quest Giver");
	char = USERTEST.createNPCBase("Player Character");
	enemy1 = USERTEST.createNPCBase("Enemy #1");
	enemy2 = USERTEST.createNPCBase("Enemy #2");
	loc1 = USERTEST.createLocationBase("1:1", "Quest Start Location");
	loc2 = USERTEST.createLocationBase("2:2", "Enemy Location");

	npc1.motivations.push(questGen.motivations.reputation);

	npc1.location = loc1;
	char.location = loc1;
	enemy1.location = loc2;

	char.knownInformation.push(loc1);
	char.knownInformation.push(loc2);

	var quest = questGen.generateQuest(char, npc1, [], [enemy1], [loc2], []),
		quest2 = questGen.generateQuest(char, npc1, [], [enemy2], [loc2], []);

	quest.updateState();
	console.log("Quest1: " + quest.isFinished());
	quest2.updateState();
	console.log("Quest2: " + quest2.isFinished());

	char.location = loc2; //Move to location of the enemy
	quest.updateState();
	quest2.updateState();
	console.log("Quest1: " + quest.isFinished() + " upon moving to enemy");
	console.log("Quest2: " + quest2.isFinished());

	enemy1.isAlive = false; //Kill the enemy
	quest.updateState();
	quest2.updateState();
	console.log("Quest1: " + quest.isFinished() + " upon killing enemy1");
	console.log("Quest2: " + quest2.isFinished());

	char.location = loc1; //Move to start location
	quest.updateState();
	quest2.updateState();
	console.log("Quest1: " + quest.isFinished() + " upon returning to start");
	console.log("Quest2: " + quest2.isFinished());

	npc1.knownInformation.push(enemy1);
	quest.updateState();
	quest2.updateState();
	console.log("Quest1: " + quest.isFinished() + " upon reporting back");
	console.log("Quest2: " + quest2.isFinished());

	console.log("No Shared State Test: Overall Test Result: ");
	console.log(quest.isFinished() && !quest2.isFinished() && !enemy1.isAlive && enemy2.isAlive);
}
noSharedStateTest();

function killEnemyTest() {
	char = USERTEST.createNPCBase("Player Character");
	npc1 = USERTEST.createNPCBase("Quest Giver");
	enemy1 = USERTEST.createNPCBase("Enemy To Kill");
	loc1 = USERTEST.createLocationBase("1:1", "Quest Start Location");
	loc2 = USERTEST.createLocationBase("2:2", "Enemy Location");

	npc1.motivations.push(questGen.motivations.reputation);

	char.location = loc1;
	npc1.location = loc1;
	char.knownInformation.push(loc1);
	npc1.knownInformation.push(loc1);
	enemy1.location = loc2;
	char.knownInformation.push(loc2);

	var quest = questGen.generateQuest(char, npc1, [], [enemy1], [loc2], [], questGen.strategies.killEnemy);

	quest.updateState();
	console.log("KillEnemy Quest: " + quest.isFinished() + " upon generation");

	char.location = enemy1.location;
	enemy1.isAlive = false;
	char.knownInformation.push(enemy1);
	quest.updateState();
	console.log("KillEnemy Quest: " + quest.isFinished() + " upon char moving to enemy and killing him");

	char.location = npc1.location;
	quest.updateState();
	console.log("KillEnemy Quest: " + quest.isFinished() + " upon returning to start");

	npc1.knownInformation.push(enemy1);
	quest.updateState();
	console.log("KillEnemy Quest: " + quest.isFinished() + " upon reporting back to quest giver");

	console.log("KillEnemy Quest: Overall Test Results: ");
	console.log(quest.isFinished());
}
killEnemyTest();<commit_msg>Added Explore and GoAndLearn Tests<commit_after>/**
 * Created by Dean on 6/21/2015.
 */

var char = USERTEST.createNPCBase(),
	npc1 = USERTEST.createNPCBase(),
	npc2 = USERTEST.createNPCBase(),
	npc3 = USERTEST.createNPCBase(),
	enemy1 = USERTEST.createNPCBase(),
	enemy2 = USERTEST.createNPCBase(),
	enemy3 = USERTEST.createNPCBase(),
	loc1 = USERTEST.createLocationBase("1:1"),
	loc2 = USERTEST.createLocationBase("2:2"),
	loc3 = USERTEST.createLocationBase("3:3"),
	questGen = QUESTIFY.createQuestGenerator();

(function createConditionFunctions(){
	questGen.conditionFunctions.checkIfCharIsAtLocation = function(somebody, location) {
		return somebody.location === location;
	};
	questGen.conditionFunctions.checkIfCharIsAtLocationAndWantsItem = function(somebody, location, item) {
		if (somebody.hasOwnProperty("desires")) {
			return somebody.location === location && somebody.desires.indexOf(item) !== -1;
		}
		return false;
	};
	questGen.conditionFunctions.checkIfCharIsAlive = function(somebody) {
		return somebody.isAlive;
	};
	questGen.conditionFunctions.checkIfCharIsDead = function(somebody) {
		return !somebody.isAlive;
	};
	questGen.conditionFunctions.checkIfCharKnowsInformation = function(somebody, info) {
		return somebody.knownInformation.indexOf(info) !== -1;
	};
	questGen.conditionFunctions.checkIfCharHasItem = function(somebody, item) {
		return somebody.inventory.indexOf(item) !== -1;
	};
	questGen.conditionFunctions.checkIfCharHasPrisoner = function(somebody, other) {
		if (somebody.hasOwnProperty("prisoners")) {
			return somebody.prisoners.indexOf(other) !== -1;
		}
		return false;
	};
	questGen.conditionFunctions.checkIfCharHasItemAndOtherDoesNot = function(somebody, other, item) {
		return somebody.inventory.indexOf(item) !== -1 && somebody.inventory.indexOf(item) === -1;
	};
	questGen.conditionFunctions.checkIfCharIsAtLocationAndHasItem = function(somebody, location, item) {
		return somebody.location === location && somebody.inventory.indexOf(item) !== -1;
	};
	questGen.conditionFunctions.checkIfItemIsAtLocation = function(item, location) {
		return item.location === location;
	};
	questGen.conditionFunctions.checkIfCharIsAtLocationAndKnowsInformation = function(somebody, location, info) {
		return questGen.conditionFunctions.checkIfCharIsAtLocation(somebody, location) && questGen.conditionFunctions.checkIfCharIsAtLocationAndKnowsInformation(somebody, info);
	};
}());

(function createAtomicActions(){
	questGen.atomicActions.goto = QUESTIFY.createAtomicAction([questGen.conditionFunctions.checkIfCharIsAtLocation]);

	questGen.atomicActions.kill = QUESTIFY.createAtomicAction([questGen.conditionFunctions.checkIfCharIsAtLocation,
															  questGen.conditionFunctions.checkIfCharIsDead]);

	questGen.atomicActions.report = QUESTIFY.createAtomicAction([questGen.conditionFunctions.checkIfCharIsAtLocation,
														        questGen.conditionFunctions.checkIfCharKnowsInformation]);

	questGen.atomicActions.capture = QUESTIFY.createAtomicAction([questGen.conditionFunctions.checkIfCharHasPrisoner]);

	questGen.atomicActions.give = QUESTIFY.createAtomicAction([questGen.conditionFunctions.checkIfCharHasItem]);

	questGen.atomicActions.take = QUESTIFY.createAtomicAction([questGen.conditionFunctions.checkIfCharHasItemAndOtherDoesNot]);

	questGen.atomicActions.gather = QUESTIFY.createAtomicAction([questGen.conditionFunctions.checkIfCharIsAtLocation,
							                                    questGen.conditionFunctions.checkIfCharHasItem]);

	questGen.atomicActions.learn = QUESTIFY.createAtomicAction([questGen.conditionFunctions.checkIfCharKnowsInformation]);
}());

(function createStrategies(){
	questGen.strategies.killEnemy =
		QUESTIFY.createStrategy([
			{atomicAction: 'goto',   actionArgs: [["DEF:pc", "ENEMY:enemy:location"]]},
			{atomicAction: 'kill',   actionArgs: [["DEF:pc", "ENEMY:enemy:location"], ["ENEMY:enemy"]]},
			{atomicAction: 'goto',   actionArgs: [["DEF:pc", "DEF:start"]]},
			{atomicAction: 'report', actionArgs: [["DEF:giver", "DEF:pc:location"], ["DEF:giver", "ENEMY:enemy"]]}]);

	questGen.strategies.explore =
		QUESTIFY.createStrategy([
			{atomicAction: 'goto',   actionArgs: [["DEF:pc", "LOC:poi"]]},
			{atomicAction: 'goto',   actionArgs: [["DEF:pc", "DEF:giver:location"]]},
			{atomicAction: 'report',   actionArgs: [["DEF:pc", "DEF:giver:location"], ["DEF:giver", "LOC:poi"]]}]);

	questGen.strategies.goAndLearn =
		QUESTIFY.createStrategy([
			{atomicAction: 'goto',   actionArgs: [["DEF:pc", "NPC:otherNPC:location"]]},
			{atomicAction: 'learn', actionArgs: [["DEF:pc", "LOC:locInfo"]]}]);
}());

(function createMotivations(){
	questGen.motivations.reputation = QUESTIFY.createMotivation([questGen.strategies.killEnemy]);
	questGen.motivations.knowledge = QUESTIFY.createMotivation([questGen.strategies.explore, questGen.strategies.goAndLearn]);
}());

function noSharedStateTest() {
	/*In this test, we create two very similar quests and make sure that the progress in one is not reflected in the other*/
	npc1 = USERTEST.createNPCBase("Quest Giver");
	char = USERTEST.createNPCBase("Player Character");
	enemy1 = USERTEST.createNPCBase("Enemy #1");
	enemy2 = USERTEST.createNPCBase("Enemy #2");
	loc1 = USERTEST.createLocationBase("1:1", "Quest Start Location");
	loc2 = USERTEST.createLocationBase("2:2", "Enemy Location");

	npc1.motivations.push(questGen.motivations.reputation);

	npc1.location = loc1;
	char.location = loc1;
	enemy1.location = loc2;

	char.knownInformation.push(loc1);
	char.knownInformation.push(loc2);

	var quest = questGen.generateQuest(char, npc1, [], [enemy1], [loc2], []),
		quest2 = questGen.generateQuest(char, npc1, [], [enemy2], [loc2], []);

	quest.updateState();
	console.log("Quest1: " + quest.isFinished());
	quest2.updateState();
	console.log("Quest2: " + quest2.isFinished());

	char.location = loc2; //Move to location of the enemy
	quest.updateState();
	quest2.updateState();
	console.log("Quest1: " + quest.isFinished() + " upon moving to enemy");
	console.log("Quest2: " + quest2.isFinished());

	enemy1.isAlive = false; //Kill the enemy
	quest.updateState();
	quest2.updateState();
	console.log("Quest1: " + quest.isFinished() + " upon killing enemy1");
	console.log("Quest2: " + quest2.isFinished());

	char.location = loc1; //Move to start location
	quest.updateState();
	quest2.updateState();
	console.log("Quest1: " + quest.isFinished() + " upon returning to start");
	console.log("Quest2: " + quest2.isFinished());

	npc1.knownInformation.push(enemy1);
	quest.updateState();
	quest2.updateState();
	console.log("Quest1: " + quest.isFinished() + " upon reporting back");
	console.log("Quest2: " + quest2.isFinished());

	console.log("No Shared State Test: Overall Test Result: ");
	console.log(quest.isFinished() && !quest2.isFinished() && !enemy1.isAlive && enemy2.isAlive);
}
noSharedStateTest();

function killEnemyTest() {
	char = USERTEST.createNPCBase("Player Character");
	npc1 = USERTEST.createNPCBase("Quest Giver");
	enemy1 = USERTEST.createNPCBase("Enemy To Kill");
	loc1 = USERTEST.createLocationBase("1:1", "Quest Start Location");
	loc2 = USERTEST.createLocationBase("2:2", "Enemy Location");

	npc1.motivations.push(questGen.motivations.reputation);

	char.location = loc1;
	npc1.location = loc1;
	enemy1.location = loc2;

	var quest = questGen.generateQuest(char, npc1, [], [enemy1], [loc2], [], questGen.strategies.killEnemy);

	quest.updateState();
	console.log("KillEnemy Quest: " + quest.isFinished() + " upon generation");

	char.location = enemy1.location;
	enemy1.isAlive = false;
	quest.updateState();
	console.log("KillEnemy Quest: " + quest.isFinished() + " upon char moving to enemy and killing him");

	char.location = npc1.location;
	quest.updateState();
	console.log("KillEnemy Quest: " + quest.isFinished() + " upon returning to start");

	npc1.knownInformation.push(enemy1);
	quest.updateState();
	console.log("KillEnemy Quest: " + quest.isFinished() + " upon reporting back to quest giver");

	console.log("KillEnemy Quest: Overall Test Results: ");
	console.log(quest.isFinished());
}
killEnemyTest();

function exploreTest() {
	char = USERTEST.createNPCBase("Player Character");
	npc1 = USERTEST.createNPCBase("Quest Giver");
	loc1 = USERTEST.createLocationBase("1:1", "Quest Start Location");

	char.location = loc1;
	npc1.location = loc1;

	var quest = questGen.generateQuest(char, npc1, [], [enemy1], [loc2], [], questGen.strategies.explore);

	quest.updateState();
	console.log("Explore Quest: " + quest.isFinished() + " upon generation");

	char.location = loc2;
	quest.updateState();
	console.log("Explore Quest: " + quest.isFinished() + " upon char moving to point of interest");

	char.location = npc1.location;
	quest.updateState();
	console.log("Explore Quest: " + quest.isFinished() + " upon returning to quest givers location");

	npc1.knownInformation.push(loc2);
	quest.updateState();
	console.log("Explore Quest: " + quest.isFinished() + " upon reporting back to quest giver");

	console.log("Explore Quest: Overall Test Results: ");
	console.log(quest.isFinished());
}
exploreTest();

function goAndLearnTest() {
	char = USERTEST.createNPCBase("Player Character");
	npc1 = USERTEST.createNPCBase("Quest Giver");
	npc2 = USERTEST.createNPCBase("NPC To Learn From");
	loc1 = USERTEST.createLocationBase("1:1", "Quest Start Location");
	loc1 = USERTEST.createLocationBase("2:2", "Info to Learn");

	var quest = questGen.generateQuest(char, npc1, [npc2], [], [loc2], [], questGen.strategies.goAndLearn);

	quest.updateState();
	console.log("GoAndLearn Quest: " + quest.isFinished() + " upon generation");

	char.location = npc2.location;
	quest.updateState();
	console.log("GoAndLearn Quest: " + quest.isFinished() + " upon char moving to the location of the other NPC");

	char.knownInformation.push(loc2);
	quest.updateState();
	console.log("GoAndLearn Quest: " + quest.isFinished() + " upon char learning required information");

	console.log("GoAndLearn Quest: Overall Test Results: ");
	console.log(quest.isFinished());
}
goAndLearnTest();<|endoftext|>


<commit_before>var apd = require("atom-package-dependencies"),
  _ = require("underscore"),
  ioslib = require("ioslib"),
  BufferedProcess = require("atom").BufferedProcess;

// install missing packages
apd.install();

module.exports = {
  activate: function() {
    atom.commands.add('atom-workspace', 'titanium-atom-menu:run-iphone', this.runIPhone);
    atom.commands.add('atom-workspace', 'titanium-atom-menu:run-android', this.runAndroid);
  },
  runIPhone: function() {
    atom.myConfig = [];
    ioslib.simulator.detect(function(err, result) {
      if (err) {
        atom.notifications.addError("Can't detect iOS simulators", {
          "details": err
        });
        return;
      }
      _.each(result.simulators.ios, function(simulators, os) {

        _.each(simulators, function(simulator) {
          atom.myConfig.push({
            "exec": "titanium",
            "name": simulator.name + " (" + simulator.version + ")",
            "args": ["build", "--target", "simulator", "-p", "ios", "-C", simulator.udid]
          });
          if (_.last(simulators) === simulator) {
            atom.commands.dispatch(atom.views.getView(atom.workspace), 'build:select-active-target');
          }
        });

      });
    });

  },
  runAndroid: function() {

    // Exec. titanium command to
    var process = new BufferedProcess({
      command: "titanium",
      args: ["info", "-t", "android", "--output", "json"],
      stdout: function(e) {
        var result = JSON.parse(e);

        atom.myConfig = [];
        _.each(result.android.emulators, function(emulator) {
          atom.myConfig.push({
            "exec": "titanium",
            "name": emulator.name,
            "args": ["build", "--target", "emulator", "--platform", "android", "-C", '"' + emulator.id + '"']
          });
        });
        _.each(result.android.devices, function(device) {
          atom.myConfig.push({
            "exec": "titanium",
            "name": device.name,
            "args": ["build", "--target", "device", "--platform", "android", "-C", device.id]
          });
        });
      },
      stderr: function(error) {
        // fix notice
        if (error.indexOf("NOTICE:") === 0) {
          return;
        }
        atom.notifications.addError("Can't detect iOS emulators & devices", {
          "details": error
        });
        console.log('[stderr] ', error);
      }
    });
    process.process.on('exit', function() {
      atom.commands.dispatch(atom.views.getView(atom.workspace), "build:select-active-target");
    });
    process.onWillThrowError(function() {
      atom.notifications.addError("Please install titanium cli or add it to your PATH variable");
      return;
    });
  },
  provideBuilder: function(service) {

    return {
      niceName: 'Titanium builder',
      isEligable: function(path) {
        if (!atom.project.contains(path + '/tiapp.xml')) {
          return false;
        }

        return true;
      },
      settings: function(path) {
        return atom.myConfig;
      }
    };
  }
};
<commit_msg>Add some comments<commit_after>var apd = require("atom-package-dependencies"),
  _ = require("underscore"),
  ioslib = require("ioslib"),
  BufferedProcess = require("atom").BufferedProcess;

// install missing packages
apd.install();

module.exports = {
  activate: function() {
    atom.commands.add('atom-workspace', 'titanium-atom-menu:run-iphone', this.runIPhone);
    atom.commands.add('atom-workspace', 'titanium-atom-menu:run-android', this.runAndroid);
  },
  runIPhone: function() {
    atom.myConfig = [];
    ioslib.simulator.detect(function(err, result) {
      if (err) {
        atom.notifications.addError("Can't detect iOS simulators", {
          "details": err
        });
        return;
      }
      _.each(result.simulators.ios, function(simulators, os) {

        _.each(simulators, function(simulator) {
          atom.myConfig.push({
            "exec": "titanium",
            "name": simulator.name + " (" + simulator.version + ")",
            "args": ["build", "--target", "simulator", "-p", "ios", "-C", simulator.udid]
          });
          if (_.last(simulators) === simulator) {
            atom.commands.dispatch(atom.views.getView(atom.workspace), 'build:select-active-target');
          }
        });

      });
    });

  },
  runAndroid: function() {

    // Exec. titanium command to list Android devices and emulators
    var process = new BufferedProcess({
      command: "titanium",
      args: ["info", "-t", "android", "--output", "json"],
      stdout: function(e) {

        // parse result and update the global variable used by build service
        var result = JSON.parse(e);

        // Emulators
        atom.myConfig = [];
        _.each(result.android.emulators, function(emulator) {
          atom.myConfig.push({
            "exec": "titanium",
            "name": emulator.name,
            "args": ["build", "--target", "emulator", "--platform", "android", "-C", '"' + emulator.id + '"']
          });
        });

        // Devices
        _.each(result.android.devices, function(device) {
          atom.myConfig.push({
            "exec": "titanium",
            "name": device.name,
            "args": ["build", "--target", "device", "--platform", "android", "-C", device.id]
          });
        });
      },
      stderr: function(error) {
        // No need to show notices, notice come by Longjohn
        if (error.indexOf("NOTICE:") === 0) {
          return;
        }
        atom.notifications.addError("Can't detect Android emulators & devices", {
          "details": error
        });
      }
    });

    // Select build after get all devices and emulators
    process.process.on('exit', function() {
      atom.commands.dispatch(atom.views.getView(atom.workspace), "build:select-active-target");
    });

    // Check if the Titanium npm package installed or not
    process.onWillThrowError(function() {
      atom.notifications.addError("Please install titanium cli or add it to your PATH variable");
      return;
    });
  },
  provideBuilder: function(service) {

    return {
      niceName: 'Titanium builder',
      isEligable: function(path) {
        if (!atom.project.contains(path + '/tiapp.xml')) {
          return false;
        }

        return true;
      },
      settings: function(path) {
        return atom.myConfig;
      }
    };
  }
};
<|endoftext|>


<commit_before>/**
 * Copyright (c) 2011, Lasse Fister lasse@graphicore.de, http://graphicore.de
 *
 * You should have received a copy of the MIT License along with this program.
 * If not, see http://www.opensource.org/licenses/mit-license.php
 *
 * This is a translation of BasePen defined in fontTools/pens/basePen.py
 * The svn revision of the source file in trunk/Lib/ was 498 from 2005-04-10 15:18:42  +0200
 *
 * I even copied the docstrings and comments! (These may still refer to the Python code)
 */
define(
    [
        'ufojs',
        'ufojs/errors',
        './main',
        './AbstractPen',
        './TransformPen'
    ],
    function(
        mainmain,
        errors,
        main,
        AbstractPen,
        TransformPen
) {
    "use strict";
    var enhance = mainmain.enhance,
        NotImplementedError = errors.NotImplemented,
        AssertionError = errors.Assertion,
        decomposeSuperBezierSegment = main.decomposeSuperBezierSegment,
        decomposeQuadraticSegment = main.decomposeQuadraticSegment,
        assert = errors.assert;
    /**
     * Base class for drawing pens. You must override _moveTo, _lineTo and
     * _curveToOne. You may additionally override _closePath, _endPath,
     * addComponent and/or _qCurveToOne. You should not override any other
     * methods.
     */
    /*constructor*/
    function BasePen (glyphSet) {
        this.glyphSet = glyphSet;
        this.__currentPoint = null;
    };

    /*inheritance*/
    BasePen.prototype = Object.create(AbstractPen.prototype);

    /*definition*/
    enhance(BasePen, {

        // must override

        _moveTo: function(pt)
        {
            throw new NotImplementedError('implement _moveTo');
        },
        _lineTo: function(pt)
        {
            throw new NotImplementedError('implement _lineTo');
        },
        _curveToOne: function(pt1, pt2, pt3)
        {
            throw new NotImplementedError('implement _curveToOne');
        },

        // may override

        _closePath: function()
        {
            //pass
        },
        _endPath: function()
        {
            //pass
        },
        /**
         * This method implements the basic quadratic curve type. The
         * default implementation delegates the work to the cubic curve
         * function. Optionally override with a native implementation.
         */
        _qCurveToOne: function(pt1, pt2)
        {
            var pt0x = this.__currentPoint[0],
                pt0y = this.__currentPoint[1],
                pt1x = pt1[0],
                pt1y = pt1[1],
                pt2x = pt2[0],
                pt2y = pt2[1],
                mid1x = pt0x + 0.66666666666666667 * (pt1x - pt0x),
                mid1y = pt0y + 0.66666666666666667 * (pt1y - pt0y),
                mid2x = pt2x + 0.66666666666666667 * (pt1x - pt2x),
                mid2y = pt2y + 0.66666666666666667 * (pt1y - pt2y);
            this._curveToOne([mid1x, mid1y], [mid2x, mid2y], pt2)
        },
        /**
         * This default implementation simply transforms the points
         * of the base glyph and draws it onto self.
         */
        addComponent: function(glyphName, transformation)
        {
            var glyph = this.glyphSet[glyphName];
            if(glyph !== undefined) {
                var tPen = new TransformPen(this, transformation);
                glyph.draw(tPen);
            }
        },

        // don't override

        /**
         * Return the current point. This is not part of the public
         * interface, yet is useful for subclasses.
         */
        _getCurrentPoint: function()
        {
            return this.__currentPoint;
        },
        closePath: function()
        {
            this._closePath();
            this.__currentPoint = null;
        },
        endPath: function()
        {
            this._endPath();
            this.__currentPoint = null;
        },
        moveTo: function(pt)
        {
            this._moveTo(pt);
            this.__currentPoint = pt;
        },
        lineTo: function(pt)
        {
            this._lineTo(pt);
            this.__currentPoint = pt;
        },
        curveTo: function(/* *points */)
        {
            var points = [].slice.call(arguments),//transform arguments to an array
                n = points.length - 1;// 'n' is the number of control points
            assert(n >= 0, 'curveTo needs at least one point');
            if (n == 2) {
                // The common case, we have exactly two BCP's, so this is a standard
                // cubic bezier. Even though decomposeSuperBezierSegment() handles
                // this case just fine, we special-case it anyway since it's so
                // common.
                this._curveToOne.apply(this, points);
                this.__currentPoint = points[points.length - 1];
            } else if (n > 2) {
                // n is the number of control points; split curve into n-1 cubic
                // bezier segments. The algorithm used here is inspired by NURB
                // splines and the TrueType "implied point" principle, and ensures
                // the smoothest possible connection between two curve segments,
                // with no disruption in the curvature. It is practical since it
                // allows one to construct multiple bezier segments with a much
                // smaller amount of points.
                var _curveToOne = this._curveToOne,
                    segments = decomposeSuperBezierSegment(points),
                    segment, i;
                for (i in segments) {
                    segment = segments[i];
                    //var pt1 = segment[0];
                    //var pt2 = segment[1];
                    //var pt3 = segment[2];
                    _curveToOne.apply(this ,segment);
                    this.__currentPoint = segment[2];//pt3
                }
            } else if (n == 1) {
                this.qCurveTo.apply(this, points);
            } else if (n == 0) {
                this.lineTo(points[0]);
            } else {
                throw new AssertionError("curveTo() can't get there from here");
            }
        },
        qCurveTo: function(/* *points */)
        {
            var points = [].slice.call(arguments),//transform arguments to an array
                n = points.length - 1; //'n' is the number of control points
            assert(n >= 0, 'qCurveTo needs at least one point');
            if (points[points.length -1] === null) {
                // Special case for TrueType quadratics: it is possible to
                // define a contour with NO on-curve points. BasePen supports
                // this by allowing the final argument (the expected on-curve
                // point) to be null. We simulate the feature by making the implied
                // on-curve point between the last and the first off-curve points
                // explicit.
                var x = points[points.length -2][0], // last off-curve point x
                    y = points[points.length -2][1], // last off-curve point y
                    nx = points[0][0], // first off-curve point x
                    ny = points[0][1], // first off-curve point y
                    impliedStartPoint = [ 0.5 * (x + nx), 0.5 * (y + ny) ];
                this.__currentPoint = impliedStartPoint;
                this._moveTo(impliedStartPoint);
                points.splice(-1, 1, impliedStartPoint);//splice syntax is: index, howMany, *elements to insert
            }
            if (n > 0) {
                // Split the string of points into discrete quadratic curve
                // segments. Between any two consecutive off-curve points
                // there's an implied on-curve point exactly in the middle.
                // This is where the segment splits.
                var _qCurveToOne = this._qCurveToOne,
                    segments = decomposeQuadraticSegment(points),
                    segment, i;
                for (i in segments) {
                    segment = segments[i];
                    //var pt1 = segment[0];
                    //var pt2 = segment[1];
                    _qCurveToOne.apply(this, segment);
                    this.__currentPoint = segment[1]; //pt2
                }
            } else {
                this.lineTo(points[0]);
            }
        }
    });

    return BasePen;
});
<commit_msg>adjust usage of glyphset and glyph.draw to current API<commit_after>/**
 * Copyright (c) 2011, Lasse Fister lasse@graphicore.de, http://graphicore.de
 *
 * You should have received a copy of the MIT License along with this program.
 * If not, see http://www.opensource.org/licenses/mit-license.php
 *
 * This is a translation of BasePen defined in fontTools/pens/basePen.py
 * The svn revision of the source file in trunk/Lib/ was 498 from 2005-04-10 15:18:42  +0200
 *
 * I even copied the docstrings and comments! (These may still refer to the Python code)
 */
define(
    [
        'ufojs',
        'ufojs/errors',
        './main',
        './AbstractPen',
        './TransformPen'
    ],
    function(
        mainmain,
        errors,
        main,
        AbstractPen,
        TransformPen
) {
    "use strict";
    var enhance = mainmain.enhance,
        NotImplementedError = errors.NotImplemented,
        AssertionError = errors.Assertion,
        decomposeSuperBezierSegment = main.decomposeSuperBezierSegment,
        decomposeQuadraticSegment = main.decomposeQuadraticSegment,
        assert = errors.assert;
    /**
     * Base class for drawing pens. You must override _moveTo, _lineTo and
     * _curveToOne. You may additionally override _closePath, _endPath,
     * addComponent and/or _qCurveToOne. You should not override any other
     * methods.
     */
    /*constructor*/
    function BasePen (glyphSet) {
        this.glyphSet = glyphSet;
        this.__currentPoint = null;
    };

    /*inheritance*/
    BasePen.prototype = Object.create(AbstractPen.prototype);

    /*definition*/
    enhance(BasePen, {

        // must override

        _moveTo: function(pt)
        {
            throw new NotImplementedError('implement _moveTo');
        },
        _lineTo: function(pt)
        {
            throw new NotImplementedError('implement _lineTo');
        },
        _curveToOne: function(pt1, pt2, pt3)
        {
            throw new NotImplementedError('implement _curveToOne');
        },

        // may override

        _closePath: function()
        {
            //pass
        },
        _endPath: function()
        {
            //pass
        },
        /**
         * This method implements the basic quadratic curve type. The
         * default implementation delegates the work to the cubic curve
         * function. Optionally override with a native implementation.
         */
        _qCurveToOne: function(pt1, pt2)
        {
            var pt0x = this.__currentPoint[0],
                pt0y = this.__currentPoint[1],
                pt1x = pt1[0],
                pt1y = pt1[1],
                pt2x = pt2[0],
                pt2y = pt2[1],
                mid1x = pt0x + 0.66666666666666667 * (pt1x - pt0x),
                mid1y = pt0y + 0.66666666666666667 * (pt1y - pt0y),
                mid2x = pt2x + 0.66666666666666667 * (pt1x - pt2x),
                mid2y = pt2y + 0.66666666666666667 * (pt1y - pt2y);
            this._curveToOne([mid1x, mid1y], [mid2x, mid2y], pt2)
        },
        /**
         * This default implementation simply transforms the points
         * of the base glyph and draws it onto self.
         */
        addComponent: function(glyphName, transformation)
        {
            var glyph = (typeof this.glyphSet.get === 'function')
                ? this.glyphSet.get(glyphName)
                : this.glyphSet[glyphName];
            if(glyph !== undefined) {
                var tPen = new TransformPen(this, transformation);
                // using the synchronous call!
                // load components before drawing the glyph if this is
                // not good for your case!
                // addComponent can't get a asynchronous api because
                // we would break the pen protocol then
                glyph.draw(false, tPen);
            }
        },

        // don't override

        /**
         * Return the current point. This is not part of the public
         * interface, yet is useful for subclasses.
         */
        _getCurrentPoint: function()
        {
            return this.__currentPoint;
        },
        closePath: function()
        {
            this._closePath();
            this.__currentPoint = null;
        },
        endPath: function()
        {
            this._endPath();
            this.__currentPoint = null;
        },
        moveTo: function(pt)
        {
            this._moveTo(pt);
            this.__currentPoint = pt;
        },
        lineTo: function(pt)
        {
            this._lineTo(pt);
            this.__currentPoint = pt;
        },
        curveTo: function(/* *points */)
        {
            var points = [].slice.call(arguments),//transform arguments to an array
                n = points.length - 1;// 'n' is the number of control points
            assert(n >= 0, 'curveTo needs at least one point');
            if (n == 2) {
                // The common case, we have exactly two BCP's, so this is a standard
                // cubic bezier. Even though decomposeSuperBezierSegment() handles
                // this case just fine, we special-case it anyway since it's so
                // common.
                this._curveToOne.apply(this, points);
                this.__currentPoint = points[points.length - 1];
            } else if (n > 2) {
                // n is the number of control points; split curve into n-1 cubic
                // bezier segments. The algorithm used here is inspired by NURB
                // splines and the TrueType "implied point" principle, and ensures
                // the smoothest possible connection between two curve segments,
                // with no disruption in the curvature. It is practical since it
                // allows one to construct multiple bezier segments with a much
                // smaller amount of points.
                var _curveToOne = this._curveToOne,
                    segments = decomposeSuperBezierSegment(points),
                    segment, i;
                for (i in segments) {
                    segment = segments[i];
                    //var pt1 = segment[0];
                    //var pt2 = segment[1];
                    //var pt3 = segment[2];
                    _curveToOne.apply(this ,segment);
                    this.__currentPoint = segment[2];//pt3
                }
            } else if (n == 1) {
                this.qCurveTo.apply(this, points);
            } else if (n == 0) {
                this.lineTo(points[0]);
            } else {
                throw new AssertionError("curveTo() can't get there from here");
            }
        },
        qCurveTo: function(/* *points */)
        {
            var points = [].slice.call(arguments),//transform arguments to an array
                n = points.length - 1; //'n' is the number of control points
            assert(n >= 0, 'qCurveTo needs at least one point');
            if (points[points.length -1] === null) {
                // Special case for TrueType quadratics: it is possible to
                // define a contour with NO on-curve points. BasePen supports
                // this by allowing the final argument (the expected on-curve
                // point) to be null. We simulate the feature by making the implied
                // on-curve point between the last and the first off-curve points
                // explicit.
                var x = points[points.length -2][0], // last off-curve point x
                    y = points[points.length -2][1], // last off-curve point y
                    nx = points[0][0], // first off-curve point x
                    ny = points[0][1], // first off-curve point y
                    impliedStartPoint = [ 0.5 * (x + nx), 0.5 * (y + ny) ];
                this.__currentPoint = impliedStartPoint;
                this._moveTo(impliedStartPoint);
                points.splice(-1, 1, impliedStartPoint);//splice syntax is: index, howMany, *elements to insert
            }
            if (n > 0) {
                // Split the string of points into discrete quadratic curve
                // segments. Between any two consecutive off-curve points
                // there's an implied on-curve point exactly in the middle.
                // This is where the segment splits.
                var _qCurveToOne = this._qCurveToOne,
                    segments = decomposeQuadraticSegment(points),
                    segment, i;
                for (i in segments) {
                    segment = segments[i];
                    //var pt1 = segment[0];
                    //var pt2 = segment[1];
                    _qCurveToOne.apply(this, segment);
                    this.__currentPoint = segment[1]; //pt2
                }
            } else {
                this.lineTo(points[0]);
            }
        }
    });

    return BasePen;
});
<|endoftext|>


<commit_before>var merge = require('mout/object/merge')
var deepFillIn = require('mout/object/deepFillIn')
var config = require('lib/config')
var log = require('debug')('democracyos:translations')
var missing = require('./missing')
var translations = require('./all')
var baseLocale = require('./base-locale')

var available = config.availableLocales

// Throw a Warning if there are missing translations
Object.keys(missing).forEach(function (locale) {
  log("Warning: Missing translation keys on '" + locale + "':")
  missing[locale].forEach(function (key) {
    log('  - %s', key)
  })
})

var configTranslation = baseLocale !== config.locale ? translations[config.locale] : {}
var baseTranslation = merge(translations[baseLocale], configTranslation)

available.forEach(function (locale) {
  var translation = merge(baseTranslation, translations[locale])
  module.exports[locale] = translation
})

module.exports.help = function (t) {
  deepFillIn(t, translations)
}
<commit_msg>remove missing translations warning<commit_after>const merge = require('mout/object/merge')
const deepFillIn = require('mout/object/deepFillIn')
const config = require('lib/config')
const translations = require('./all')
const baseLocale = require('./base-locale')

const available = config.availableLocales

const configTranslation = baseLocale !== config.locale
  ? translations[config.locale] : {}
const baseTranslation = merge(translations[baseLocale], configTranslation)

available.forEach(function (locale) {
  module.exports[locale] = merge(baseTranslation, translations[locale])
})

module.exports.help = function (t) {
  deepFillIn(t, translations)
}
<|endoftext|>


<commit_before>// Portuguese

$.extend( $.fn.pickadate.defaults, {
    monthsFull: [ 'janeiro', 'fevereiro', 'março', 'abril', 'maio', 'junho', 'julho', 'agosto', 'setembro', 'outubro', 'novembro', 'dezembro' ],
    monthsShort: [ 'jan', 'fev', 'mar', 'abr', 'mai', 'jun', 'jul', 'ago', 'set', 'out', 'nov', 'dez' ],
    weekdaysFull: [ 'domingo', 'segunda', 'terça', 'quarta', 'quinta', 'sexta', 'sábado' ],
    weekdaysShort: [ 'dom', 'seg', 'ter', 'qua', 'qui', 'sex', 'sab' ],
    today: 'hoje',
    clear: 'excluir',
    format: 'd de mmmm de yyyy',
    formatSubmit: 'yyyy/mm/dd'
});<commit_msg>Translation Fix: Scaping 'd'<commit_after>// Portuguese

$.extend( $.fn.pickadate.defaults, {
    monthsFull: [ 'janeiro', 'fevereiro', 'março', 'abril', 'maio', 'junho', 'julho', 'agosto', 'setembro', 'outubro', 'novembro', 'dezembro' ],
    monthsShort: [ 'jan', 'fev', 'mar', 'abr', 'mai', 'jun', 'jul', 'ago', 'set', 'out', 'nov', 'dez' ],
    weekdaysFull: [ 'domingo', 'segunda', 'terça', 'quarta', 'quinta', 'sexta', 'sábado' ],
    weekdaysShort: [ 'dom', 'seg', 'ter', 'qua', 'qui', 'sex', 'sab' ],
    today: 'hoje',
    clear: 'excluir',
    format: 'd !de mmmm !de yyyy',
    formatSubmit: 'yyyy/mm/dd'
});
<|endoftext|>


<commit_before>var hookTypes;

var callStyles = {
  sync: 'applyPlugins',
  syncWaterfall: 'applyPluginsWaterfall',
};

var camelToDash = function(camel) {
  return camel.replace(/_/g, '--').replace(/[A-Z]/g, function(c) {
    return '-' + c.toLowerCase();
  });
};

var knownPluginRegistrations = {
  Compilation: {
    needAdditionalPass: ['sync', []],
  },
  Compiler: {
    afterPlugins: ['sync', []],
    compilation: ['sync', ['compilation', 'params']]
  },
};

exports.register = function(tapable, name, style, args) {
  if (tapable.hooks) {
    if (!hookTypes) {
      var Tapable = require('tapable');
      hookTypes = {
        sync: Tapable.SyncHook,
        syncWaterfall: Tapable.SyncWaterfallHook,
      };
    }
    if (!tapable.hooks[name]) {
      tapable.hooks[name] = new (hookTypes[style])(args);
    }
  }
  else {
    if (!tapable.__hardSource_hooks) {
      tapable.__hardSource_hooks = {};
    }
    if (!tapable.__hardSource_hooks[name]) {
      tapable.__hardSource_hooks[name] = {
        name: name,
        dashName: camelToDash(name),
        style: style,
        args: args,
      };
    }
  }
};

exports.tap = function(tapable, name, reason, callback) {
  if (tapable.hooks) {
    tapable.hooks[name].tap(reason, callback);
  }
  else {
    if (!tapable.__hardSource_hooks || !tapable.__hardSource_hooks[name]) {
      var registration = knownPluginRegistrations[tapable.constructor.name][name];
      exports.register(tapable, name, registration[0], registration[1]);
    }
    var dashName = tapable.__hardSource_hooks[name].dashName;
    tapable.plugin(dashName, callback);
  }
};

exports.call = function(tapable, name, args) {
  if (tapable.hooks) {
    var hook = tapable.hooks[name];
    return hook.call.apply(hook, args);
  }
  else {
    var dashName = tapable.__hardSource_hooks[name].dashName;
    var style = tapable.__hardSource_hooks[name].style;
    return tapable[callStyles[style]].apply(tapable, [dashName].concat(args));
  }
};
<commit_msg>Add plugin registries for used module factories calls<commit_after>var hookTypes;

var callStyles = {
  sync: 'applyPlugins',
  syncWaterfall: 'applyPluginsWaterfall',
  syncBail: 'applyPluginsBailResult',
  asyncWaterfall: 'applyPluginsAsyncWaterfall',
};

var camelToDash = function(camel) {
  return camel.replace(/_/g, '--').replace(/[A-Z]/g, function(c) {
    return '-' + c.toLowerCase();
  });
};

var knownPluginRegistrations = {
  Compilation: {
    needAdditionalPass: ['sync', []],
    succeedModule: ['sync', ['module']]
  },
  Compiler: {
    afterPlugins: ['sync', []],
    compilation: ['sync', ['compilation', 'params']]
  },
  NormalModuleFactory: {
    createModule: ['syncBail', ['data']]
  },
  ContextModuleFactory: {
    afterResolve: ['asyncWaterfall', ['data']]
  },
};

exports.register = function(tapable, name, style, args) {
  if (tapable.hooks) {
    if (!hookTypes) {
      var Tapable = require('tapable');
      hookTypes = {
        sync: Tapable.SyncHook,
        syncWaterfall: Tapable.SyncWaterfallHook,
        syncBail: Tapable.SyncBailHook,
        asyncWaterfall: Tapable.AsyncWaterfallHook,
      };
    }
    if (!tapable.hooks[name]) {
      tapable.hooks[name] = new (hookTypes[style])(args);
    }
  }
  else {
    if (!tapable.__hardSource_hooks) {
      tapable.__hardSource_hooks = {};
    }
    if (!tapable.__hardSource_hooks[name]) {
      tapable.__hardSource_hooks[name] = {
        name: name,
        dashName: camelToDash(name),
        style: style,
        args: args,
      };
    }
  }
};

exports.tap = function(tapable, name, reason, callback) {
  if (tapable.hooks) {
    tapable.hooks[name].tap(reason, callback);
  }
  else {
    if (!tapable.__hardSource_hooks || !tapable.__hardSource_hooks[name]) {
      var registration = knownPluginRegistrations[tapable.constructor.name][name];
      exports.register(tapable, name, registration[0], registration[1]);
    }
    var dashName = tapable.__hardSource_hooks[name].dashName;
    tapable.plugin(dashName, callback);
  }
};

exports.call = function(tapable, name, args) {
  if (tapable.hooks) {
    var hook = tapable.hooks[name];
    return hook.call.apply(hook, args);
  }
  else {
    var dashName = tapable.__hardSource_hooks[name].dashName;
    var style = tapable.__hardSource_hooks[name].style;
    return tapable[callStyles[style]].apply(tapable, [dashName].concat(args));
  }
};
<|endoftext|>


<commit_before>'use strict';

// Detect if the string refers to a remote git repo.
// Proably a bit janky, but borrowed from Bower,
// so it's at least a Known Trick.
module.exports = function(str){
  return (/^git(\+(ssh|https?))?:\/\//i).test(str) || (/\.git\/?$/i).test(str) || (/^git@/i).test(str);
};
<commit_msg>Fix url format of isGitRepo, fixes #3777<commit_after>'use strict';

// Detect if the string refers to a remote git repo.
// Only handles git://, ssh://, and https://
module.exports = function(str){
  return (/^((git|ssh|https?))?:\/\//i).test(str) || (/\.git\/?$/i).test(str) || (/^git@/i).test(str);
};
<|endoftext|>


<commit_before>
var util = require('util');
var crypto = require('crypto');
var child_process = require('child_process');

// add startsWith/endsWith functions to string
if (typeof String.prototype.startsWith != 'function') {
	String.prototype.startsWith = function(str) {
		return this.slice(0, str.length) == str;
	};
}

if (typeof String.prototype.endsWith != 'function') {
	String.prototype.endsWith = function(str) {
		return this.slice(-str.length) == str;
	};
}

if (typeof String.prototype.md5 != 'function') {
	String.prototype.md5 = function() {
		return crypto.createHash('md5').update(new Buffer(this)).digest('hex');
	};
}

if (typeof String.prototype.exec != 'function') {
	String.prototype.exec = function(callback, errorCallback) {
		var cmd = this;
		var childProcess = child_process.exec(cmd, function (error, stdout, stderr) {
			KalturaLogger.log('Command: ' + cmd);
			KalturaLogger.log('Standard output: ' + stdout);

			if(stderr.length){
				KalturaLogger.error('Command: ' + cmd);
				KalturaLogger.error('Standard error: ' + stderr);
			}

		    if (error) {
		    	if(errorCallback){
		    		errorCallback(error);
		    	}
		    	else{
		    		KalturaLogger.error('Exec: ' + error);
		    	}
		    }
		    else if(callback){
		    	callback(stdout);
		    }
		});

		KalturaLogger.log('Started cli process [' + childProcess.pid + ']: ' + cmd);
	};
}

if (typeof Array.prototype.unique != 'function') {
	Array.prototype.unique = function() {
	    return this.reduce(function(p, c) {
	        if (p.indexOf(c) < 0)
	        	p.push(c);
	        return p;
	    }, []);
	};
}

if (typeof Array.prototype.diff != 'function') {
	Array.prototype.diff = function(arr) {
		var retArr = [];

		thisLoop: for (var k = 0; k < this.length; k++) {
		    for (var i = 0; i < arr.length; i++) {
		    	if(this[k] == arr[i]){
		    		continue thisLoop;
		    	}
		    }
		    retArr.push(this[k]);
		}
		return retArr;
	};
}

KalturaUtils = {
	getUniqueId : function(){
		return Math.floor(Math.random() * 10000000000000001).toString(36);
	}
};

<commit_msg>Change debug level<commit_after>
var util = require('util');
var crypto = require('crypto');
var child_process = require('child_process');

// add startsWith/endsWith functions to string
if (typeof String.prototype.startsWith != 'function') {
	String.prototype.startsWith = function(str) {
		return this.slice(0, str.length) == str;
	};
}

if (typeof String.prototype.endsWith != 'function') {
	String.prototype.endsWith = function(str) {
		return this.slice(-str.length) == str;
	};
}

if (typeof String.prototype.md5 != 'function') {
	String.prototype.md5 = function() {
		return crypto.createHash('md5').update(new Buffer(this)).digest('hex');
	};
}

if (typeof String.prototype.exec != 'function') {
	String.prototype.exec = function(callback, errorCallback) {
		var cmd = this;
		var childProcess = child_process.exec(cmd, function (error, stdout, stderr) {
			KalturaLogger.log('Command: ' + cmd);
			KalturaLogger.debug('Standard output: ' + stdout);

			if(stderr.length){
				KalturaLogger.error('Command: ' + cmd);
				KalturaLogger.error('Standard error: ' + stderr);
			}

		    if (error) {
		    	if(errorCallback){
		    		errorCallback(error);
		    	}
		    	else{
		    		KalturaLogger.error('Exec: ' + error);
		    	}
		    }
		    else if(callback){
		    	callback(stdout);
		    }
		});

		KalturaLogger.log('Started cli process [' + childProcess.pid + ']: ' + cmd);
	};
}

if (typeof Array.prototype.unique != 'function') {
	Array.prototype.unique = function() {
	    return this.reduce(function(p, c) {
	        if (p.indexOf(c) < 0)
	        	p.push(c);
	        return p;
	    }, []);
	};
}

if (typeof Array.prototype.diff != 'function') {
	Array.prototype.diff = function(arr) {
		var retArr = [];

		thisLoop: for (var k = 0; k < this.length; k++) {
		    for (var i = 0; i < arr.length; i++) {
		    	if(this[k] == arr[i]){
		    		continue thisLoop;
		    	}
		    }
		    retArr.push(this[k]);
		}
		return retArr;
	};
}

KalturaUtils = {
	getUniqueId : function(){
		return Math.floor(Math.random() * 10000000000000001).toString(36);
	}
};

<|endoftext|>


<commit_before>// Dependencies
var allowUnsafeNewFunction = require('loophole').allowUnsafeNewFunction
var standard = allowUnsafeNewFunction(function () {
  return require('standard')
})
var semistandard = allowUnsafeNewFunction(function () {
  return require('semistandard')
})
var happiness = allowUnsafeNewFunction(function () {
  return require('happiness')
})
var fs = require('fs')
var pkgConfig = require('pkg-config')

function getStyleThroughDevDeps (filePath) {
  // This will get the devDependencies
  // from the nearest package.json
  var options = { cwd: filePath, root: 'devDependencies', cache: false }
  var devDeps = pkgConfig(null, options)

  // Check if there are linters defined in
  // package.json devDependencies
  if (devDeps && (devDeps.standard || devDeps.semistandard || devDeps.happiness)) {
    // standard style
    if (devDeps.standard) {
      return standard
    }

    // happiness style
    if (devDeps.happiness) {
      return happiness
    }

    // semistandard style
    return semistandard
  }

  // no style
  return {
    cmd: 'no-style'
  }
}

module.exports = function selectStyle (config, filePath) {
  // see if setting 'checkStyleDevDependencies' is true
  // if true get style from the package.json
  if (config.checkStyleDevDependencies) {
    return getStyleThroughDevDeps(filePath)
  }

  // fallback to style select value to decide which style
  // we should use
  var linter
  if (config.style === 'standard') {
    linter = standard
  } else if (config.style === 'happiness') {
    linter = happiness
  } else {
    linter = semistandard
  }

  return linter
}
<commit_msg>fix semistandard issue<commit_after>// Dependencies
var allowUnsafeNewFunction = require('loophole').allowUnsafeNewFunction
var pickStandard = function (style) {
  return allowUnsafeNewFunction(function () {
    switch (style) {
      case 'standard':
        return require('standard')
      case 'happiness':
        return require('happiness')
      default:
        return require('semistandard')
    }
  })
}

var pkgConfig = require('pkg-config')

function getStyleThroughDevDeps (filePath) {
  // This will get the devDependencies
  // from the nearest package.json
  var options = { cwd: filePath, root: 'devDependencies', cache: false }
  var devDeps = pkgConfig(null, options)

  // Check if there are linters defined in
  // package.json devDependencies
  if (devDeps && (devDeps.standard || devDeps.semistandard || devDeps.happiness)) {
    // standard style
    if (devDeps.standard) {
      return pickStandard('standard')
    }

    // happiness style
    if (devDeps.happiness) {
      return pickStandard('happiness')
    }

    // semistandard style
    return pickStandard('semistandard')
  }

  // no style
  return {
    cmd: 'no-style'
  }
}

module.exports = function selectStyle (config, filePath) {
  // see if setting 'checkStyleDevDependencies' is true
  // if true get style from the package.json
  if (config.checkStyleDevDependencies) {
    return getStyleThroughDevDeps(filePath)
  }

  // fallback to style select value to decide which style
  // we should use
  var linter
  if (config.style === 'standard') {
    linter = pickStandard('standard')
  } else if (config.style === 'happiness') {
    linter = pickStandard('happiness')
  } else {
    linter = pickStandard('semistandard')
  }

  return linter
}
<|endoftext|>