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

    /**
     * Register plugin
     *
     * This plugin handles validation and addition logic for the registration form and its fields.
     */
    $.plugin('swRegister', {

        /**
         * Plugin default options.
         * Get merged automatically with the user configuration.
         */
        defaults: {

            /**
             * Class to indicate an element to be hidden.
             *
             * @property hiddenClass
             * @type {String}
             */
            hiddenClass: 'is--hidden',

            /**
             * Class to indicate that an element has an error.
             *
             * @property errorClass
             * @type {String}
             */
            errorClass: 'has--error',

            /**
             * Selector for the forms submit button.
             *
             * @property submitBtnSelector
             * @type {String}
             */
            submitBtnSelector: '.register--submit',

            /**
             * Selector for the type selection field.
             *
             * @property typeFieldSelector
             * @type {String}
             */
            typeFieldSelector: '.register--customertype select',

            /**
             * Type name for a company selection.
             * Used for comparison on the type selection field.
             *
             * @property companyType
             * @type {String}
             */
            companyType: 'business',

            /**
             * Selector for the skip account creation checkbox.
             * Toggles specific field sets when checked.
             *
             * @property skipAccountSelector
             * @type {String}
             */
            skipAccountSelector: '.register--check input',

            /**
             * Selector for the alternative shipping checkbox.
             * Toggles specific field sets when checked.
             *
             * @property altShippingSelector
             * @type {String}
             */
            altShippingSelector: '.register--alt-shipping input',

            /**
             * Selector for the company field set.
             *
             * @property companyFieldSelector
             * @type {String}
             */
            companyFieldSelector: '.register--company',

            /**
             * Selector for the account field set.
             *
             * @property accountFieldSelector
             * @type {String}
             */
            accountFieldSelector: '.register--account-information',

            /**
             * Selector for the shipping field set.
             *
             * @property shippingFieldSelector
             * @type {String}
             */
            shippingFieldSelector: '.register--shipping',

            /**
             * Selector for the payment field set.
             *
             * @property paymentFieldSelector
             * @type {String}
             */
            paymentFieldSelector: '.payment--content',

            /**
             * Selector for the payment selection radio button.
             *
             * @property paymentInputSelector
             * @type {String}
             */
            paymentInputSelector: '.payment--selection-input input',

            /**
             * Selector for the country select field.
             *
             * @property countryFieldSelector
             * @type {String}
             */
            countryFieldSelector: '.select--country',

            /**
             * Selector for the state field set.
             * This corresponding field set will be toggled
             * when a country was selected.
             *
             * @property stateContainerSelector
             * @type {String}
             */
            stateContainerSelector: '.register--state-selection',

            /**
             * Selector for the payment method select fields.
             *
             * @property paymentMethodSelector
             * @type {String}
             */
            paymentMethodSelector: '.payment--method',

            /**
             * Selector for a input field.
             *
             * @property inputSelector
             * @type {String}
             */
            inputSelector: '.is--required',

            /**
             * Class that will be added to a error message.
             *
             * @property errorMessageClass
             * @type {String}
             */
            errorMessageClass: 'register--error-msg'
        },

        /**
         * Initializes the plugin, sets up event listeners and adds the necessary
         * classes to get the plugin up and running.
         *
         * @public
         * @method init
         */
        init: function () {
            var me = this,
                opts = me.opts,
                $el = me.$el;

            me.$submitBtn = $el.find(opts.submitBtnSelector);

            me.$typeSelection = $el.find(opts.typeFieldSelector);
            me.$skipAccount = $el.find(opts.skipAccountSelector);
            me.$alternativeShipping = $el.find(opts.altShippingSelector);

            me.$companyFieldset = $el.find(opts.companyFieldSelector);
            me.$accountFieldset = $el.find(opts.accountFieldSelector);
            me.$shippingFieldset = $el.find(opts.shippingFieldSelector);

            me.$countySelectFields = $el.find(opts.countryFieldSelector);

            me.$paymentMethods = $el.find(opts.paymentMethodSelector);

            me.$inputs = $el.find(opts.inputSelector);

            me.checkType();
            me.checkSkipAccount();
            me.checkChangeShipping();

            me.registerEvents();
        },

        /**
         * Registers all necessary event listeners for the plugin to proper operate.
         *
         * @public
         * @method registerEvents
         */
        registerEvents: function () {
            var me = this;

            me._on(me.$typeSelection, 'change', $.proxy(me.checkType, me));
            me._on(me.$skipAccount, 'change', $.proxy(me.checkSkipAccount, me));
            me._on(me.$alternativeShipping, 'change', $.proxy(me.checkChangeShipping, me));
            me._on(me.$countySelectFields, 'change', $.proxy(me.onCountryChanged, me));
            me._on(me.$paymentMethods, 'change', $.proxy(me.onPaymentChanged, me));
            me._on(me.$inputs, 'blur', $.proxy(me.onValidateInput, me));
            me._on(me.$submitBtn, 'click', $.proxy(me.onSubmitBtn, me));

            $.publish('plugin/swRegister/onRegisterEvents', [ me ]);
        },

        /**
         * Checks the type selection field.
         * If the value is equal to the configured companyType,
         * the company field set will be shown.
         *
         * @public
         * @method checkType
         */
        checkType: function () {
            var me = this,
                opts = me.opts,
                $fieldSet = me.$companyFieldset,
                hideCompanyFields = (me.$typeSelection.length && me.$typeSelection.val() !== opts.companyType),
                requiredFields = $fieldSet.find(opts.inputSelector),
                requiredMethod = (!hideCompanyFields) ? me.setHtmlRequired : me.removeHtmlRequired,
                classMethod = (!hideCompanyFields) ? 'removeClass' : 'addClass';

            requiredMethod(requiredFields);

            $fieldSet[classMethod](opts.hiddenClass);

            $.publish('plugin/swRegister/onCheckType', [ me, hideCompanyFields ]);
        },

        /**
         * Checks the skip account checkbox.
         * The account field set will be shown/hidden depending
         * on the check state of the checkbox.
         *
         * @public
         * @method checkSkipAccount
         */
        checkSkipAccount: function () {
            var me = this,
                opts = me.opts,
                $fieldSet = me.$accountFieldset,
                isChecked = me.$skipAccount.is(':checked'),
                requiredFields = $fieldSet.find(opts.inputSelector),
                requiredMethod = (!isChecked) ? me.setHtmlRequired : me.removeHtmlRequired,
                classMethod = (isChecked) ? 'addClass' : 'removeClass';

            requiredMethod(requiredFields);

            $fieldSet[classMethod](opts.hiddenClass);

            $.publish('plugin/swRegister/onCheckSkipAccount', [ me, isChecked ]);
        },

        /**
         * Checks the alternative shipping checkbox.
         * The shipping field set will be shown/hidden depending
         * on the check state of the checkbox.
         *
         * @public
         * @method checkChangeShipping
         */
        checkChangeShipping: function () {
            var me = this,
                opts = me.opts,
                $fieldSet = me.$shippingFieldset,
                isChecked = me.$alternativeShipping.is(':checked'),
                requiredFields = $fieldSet.find(opts.inputSelector),
                requiredMethod = (isChecked) ? me.setHtmlRequired : me.removeHtmlRequired,
                classMethod = (isChecked) ? 'removeClass' : 'addClass';

            requiredMethod(requiredFields);

            $fieldSet[classMethod](opts.hiddenClass);

            $.publish('plugin/swRegister/onCheckChangeShipping', [ me, isChecked ]);
        },

        /**
         * Called when another country was selected in the country selection.
         * Triggers additional classes depending on the selection.
         *
         * @public
         * @method onCountryChanged
         * @param {jQuery.Event} event
         */
        onCountryChanged: function (event) {
            var me = this,
                opts = me.opts,
                hiddenClass = opts.hiddenClass,
                $select = $(event.currentTarget),
                selectId = $select.attr('id'),
                val = $select.val(),
                $parent = $select.parents('.panel--body'),
                areaSelection = $parent.find('#' + selectId + '_' + val + '_states'),
                select,
                plugin;

            $.publish('plugin/swRegister/onCountryChangedBefore', [ me, event ]);

            $parent.find(opts.stateContainerSelector).addClass(hiddenClass);
            select = areaSelection.find('select');
            areaSelection.addClass(hiddenClass);

            if (!(plugin = select.data('plugin_swSelectboxReplacement'))) {
                return;
            }

            if (!areaSelection.length) {
                plugin.$el.addClass(hiddenClass);
                plugin.$wrapEl.addClass(hiddenClass);
                plugin.setDisabled();
            } else {
                plugin.$el.removeClass(hiddenClass);
                plugin.$wrapEl.removeClass(hiddenClass);
                areaSelection.removeClass(hiddenClass);
                plugin.setEnabled();
            }

            $.publish('plugin/swRegister/onCountryChanged', [ me, event ]);
        },

        /**
         * Called when another payment method was selected.
         * Depending on the selection, the payment field set will be toggled.
         *
         * @public
         * @method onPaymentChanged
         */
        onPaymentChanged: function () {
            var me = this,
                opts = me.opts,
                inputClass = opts.inputSelector,
                hiddenClass = opts.hiddenClass,
                inputSelector = opts.paymentInputSelector,
                paymentSelector = opts.paymentFieldSelector,
                requiredMethod,
                $fieldSet,
                isChecked,
                radio,
                $el;

            $.each(me.$paymentMethods, function (index, el) {
                $el = $(el);

                radio = $el.find(inputSelector);
                isChecked = radio[0].checked;

                requiredMethod = (isChecked) ? me.setHtmlRequired : me.removeHtmlRequired;

                requiredMethod($el.find(inputClass));

                $fieldSet = $el.find(paymentSelector);
                $fieldSet[((isChecked) ? 'removeClass' : 'addClass')](hiddenClass);
            });

            $.publish('plugin/swRegister/onPaymentChanged', [ me ]);
        },

        /**
         * Will be called when the submit button was clicked.
         * Loops through all input fields and checks if they have a value.
         * When no value is available, the field will be marked with an error.
         *
         * @public
         * @method onSubmitBtn
         */
        onSubmitBtn: function () {
            var me = this,
                $input;

            me.$inputs.each(function () {
                $input = $(this);

                if (!$input.val()) {
                    me.setFieldAsError($input);
                }
            });

            $.publish('plugin/swRegister/onSubmitButton', [ me ]);
        },

        /**
         * Called when a input field lost its focus.
         * Depending on the elements id, the corresponding method will be called.
         * billing ust id, emails and passwords will be validated via AJAX.
         *
         * @public
         * @method onValidateInput
         * @param {jQuery.Event} event
         */
        onValidateInput: function (event) {
            var me = this,
                $el = $(event.currentTarget),
                id = $el.attr('id'),
                action;

            switch (id) {
                case 'register_personal_skipLogin':
                case 'register_personal_email':
                case 'register_personal_emailConfirmation':
                    action = 'ajax_validate_email';
                    break;
                case 'register_billing_ustid':
                    action = 'ajax_validate_billing';
                    break;
                case 'register_personal_password':
                case 'register_personal_passwordConfirmation':
                    action = 'ajax_validate_password';
                    break;
                default:
                    break;
            }

            if (!$el.val()) {
                me.setFieldAsError($el);
            } else if ($el.attr('type') === 'checkbox' && !$el.is(':checked')) {
                me.setFieldAsError($el);
            } else if (action) {
                me.validateUsingAjax($el, action);
            } else {
                me.setFieldAsSuccess($el);
            }

            $.publish('plugin/swRegister/onValidateInput', [ me, event, action ]);
        },

        /**
         * Adds additional attributes to the given elements to indicate
         * the elements to be required.
         *
         * @private
         * @method setHtmlRequired
         * @param {jQuery} $elements
         */
        setHtmlRequired: function ($elements) {
            $elements.attr({
                'required': 'required',
                'aria-required': 'true'
            });

            $.publish('plugin/swRegister/onSetHtmlRequired', [ this, $elements ]);
        },

        /**
         * Removes addition attributes that indicate the input as required.
         *
         * @public
         * @method removeHtmlRequired
         * @param {jQuery} $inputs
         */
        removeHtmlRequired: function ($inputs) {
            $inputs.removeAttr('required aria-required');

            $.publish('plugin/swRegister/onRemoveHtmlRequired', [ this, $inputs ]);
        },

        /**
         * Adds the defined error class to the given field or calls the
         * setError() method of the selectboxReplacement plugin if its
         * registered on the element.
         *
         * @public
         * @method setFieldAsError
         * @param {jQuery} $el
         */
        setFieldAsError: function ($el) {
            var me = this,
                plugin;

            if ((plugin = $el.data('plugin_swSelectboxReplacement'))) {
                plugin.setError();
            } else {
                $el.addClass(me.opts.errorClass);
            }

            $.publish('plugin/swRegister/onSetFieldAsError', [ me, $el ]);
        },

        /**
         * Removes the defined error class to the given field or calls the
         * removeError() method of the selectboxReplacement plugin if its
         * registered on the element.
         *
         * @public
         * @method setFieldAsSuccess
         * @param {jQuery} $el
         */
        setFieldAsSuccess: function ($el) {
            var me = this,
                plugin;

            if ((plugin = $el.data('plugin_swSelectboxReplacement'))) {
                plugin.removeError();
            } else {
                $el.removeClass(me.opts.errorClass);
            }

            $.publish('plugin/swRegister/onSetFieldAsSuccess', [ me, $el ]);
        },

        /**
         * Sends an ajax request to validate a given field server side.
         *
         * @public
         * @method validateUsingAjax
         * @param {jQuery} $input
         * @param {String} action
         */
        validateUsingAjax: function ($input, action) {
            var me = this,
                data = 'action=' + action + '&' + me.$el.find('form').serialize(),
                URL = window.controller.ajax_validate;

            if (!URL) {
                return;
            }

            $.publish('plugin/swRegister/onValidateBefore', [ me, data, URL ]);

            $.ajax({
                'data': data,
                'type': 'post',
                'dataType': 'json',
                'url': URL,
                'success': $.proxy(me.onValidateSuccess, me, action, $input)
            });
        },

        /**
         * This method gets called when the server side validation request
         * was successfully called. Updates the corresponding fields
         * and adds/removes error messages.
         *
         * @public
         * @method onValidateSuccess
         * @param {String} action
         * @param {jQuery} $input
         * @param {Object} result
         */
        onValidateSuccess: function (action, $input, result) {
            var me = this,
                errorFlags,
                errorMessages;

            $('#' + action + '--message').remove();

            if (!result) {
                return;
            }

            errorFlags = result.error_flags;
            errorMessages = result.error_messages;

            if (errorFlags) {
                me.updateFieldFlags(errorFlags);
            }

            if (errorMessages && errorMessages.length) {
                $('
', {
                    'html': '
' + errorMessages.join('
') + '
',
                    'id': action + '--message',
                    'class': me.opts.errorMessageClass
                }).insertAfter($input);

                me.setFieldAsError($input);
            }

            $.publish('plugin/swRegister/onValidateSuccess', [ me, $input ]);
        },

        /**
         * Loops through all flags and updates the error/success status
         * of the corresponding elements.
         *
         * @public
         * @method updateFieldFlags
         * @param {Object} flags
         */
        updateFieldFlags: function (flags) {
            var me = this,
                $el = me.$el,
                keys = Object.keys(flags),
                len = keys.length,
                i = 0,
                flag,
                $input;

            for (; i < len; i++) {
                flag = keys[i];
                $input = $el.find('.' + flag);

                if (flags[flag]) {
                    me.setFieldAsError($input);
                    continue;
                }

                me.setFieldAsSuccess($input);
            }

            $.publish('plugin/swRegister/onUpdateFields', [ me, flags ]);
        },

        /**
         * Destroys the initialized plugin completely, so all event listeners will
         * be removed and the plugin data, which is stored in-memory referenced to
         * the DOM node.
         *
         * @public
         * @method destroy
         */
        destroy: function () {
            this._destroy();
        }
    });
})(jQuery);
<commit_msg>fix jquery.register.js to perform the ajax validations<commit_after>;(function ($) {
    'use strict';

    /**
     * Register plugin
     *
     * This plugin handles validation and addition logic for the registration form and its fields.
     */
    $.plugin('swRegister', {

        /**
         * Plugin default options.
         * Get merged automatically with the user configuration.
         */
        defaults: {

            /**
             * Class to indicate an element to be hidden.
             *
             * @property hiddenClass
             * @type {String}
             */
            hiddenClass: 'is--hidden',

            /**
             * Class to indicate that an element has an error.
             *
             * @property errorClass
             * @type {String}
             */
            errorClass: 'has--error',

            /**
             * Selector for the forms submit button.
             *
             * @property submitBtnSelector
             * @type {String}
             */
            submitBtnSelector: '.register--submit',

            /**
             * Selector for the type selection field.
             *
             * @property typeFieldSelector
             * @type {String}
             */
            typeFieldSelector: '.register--customertype select',

            /**
             * Type name for a company selection.
             * Used for comparison on the type selection field.
             *
             * @property companyType
             * @type {String}
             */
            companyType: 'business',

            /**
             * Selector for the skip account creation checkbox.
             * Toggles specific field sets when checked.
             *
             * @property skipAccountSelector
             * @type {String}
             */
            skipAccountSelector: '.register--check input',

            /**
             * Selector for the alternative shipping checkbox.
             * Toggles specific field sets when checked.
             *
             * @property altShippingSelector
             * @type {String}
             */
            altShippingSelector: '.register--alt-shipping input',

            /**
             * Selector for the company field set.
             *
             * @property companyFieldSelector
             * @type {String}
             */
            companyFieldSelector: '.register--company',

            /**
             * Selector for the account field set.
             *
             * @property accountFieldSelector
             * @type {String}
             */
            accountFieldSelector: '.register--account-information',

            /**
             * Selector for the shipping field set.
             *
             * @property shippingFieldSelector
             * @type {String}
             */
            shippingFieldSelector: '.register--shipping',

            /**
             * Selector for the payment field set.
             *
             * @property paymentFieldSelector
             * @type {String}
             */
            paymentFieldSelector: '.payment--content',

            /**
             * Selector for the payment selection radio button.
             *
             * @property paymentInputSelector
             * @type {String}
             */
            paymentInputSelector: '.payment--selection-input input',

            /**
             * Selector for the country select field.
             *
             * @property countryFieldSelector
             * @type {String}
             */
            countryFieldSelector: '.select--country',

            /**
             * Selector for the state field set.
             * This corresponding field set will be toggled
             * when a country was selected.
             *
             * @property stateContainerSelector
             * @type {String}
             */
            stateContainerSelector: '.register--state-selection',

            /**
             * Selector for the payment method select fields.
             *
             * @property paymentMethodSelector
             * @type {String}
             */
            paymentMethodSelector: '.payment--method',

            /**
             * Selector for a input field.
             *
             * @property inputSelector
             * @type {String}
             */
            inputSelector: '.is--required',

            /**
             * Class that will be added to a error message.
             *
             * @property errorMessageClass
             * @type {String}
             */
            errorMessageClass: 'register--error-msg'
        },

        /**
         * Initializes the plugin, sets up event listeners and adds the necessary
         * classes to get the plugin up and running.
         *
         * @public
         * @method init
         */
        init: function () {
            var me = this,
                opts = me.opts,
                $el = me.$el;

            me.$submitBtn = $el.find(opts.submitBtnSelector);

            me.$typeSelection = $el.find(opts.typeFieldSelector);
            me.$skipAccount = $el.find(opts.skipAccountSelector);
            me.$alternativeShipping = $el.find(opts.altShippingSelector);

            me.$companyFieldset = $el.find(opts.companyFieldSelector);
            me.$accountFieldset = $el.find(opts.accountFieldSelector);
            me.$shippingFieldset = $el.find(opts.shippingFieldSelector);

            me.$countySelectFields = $el.find(opts.countryFieldSelector);

            me.$paymentMethods = $el.find(opts.paymentMethodSelector);

            me.$inputs = $el.find(opts.inputSelector);

            me.checkType();
            me.checkSkipAccount();
            me.checkChangeShipping();

            me.registerEvents();
        },

        /**
         * Registers all necessary event listeners for the plugin to proper operate.
         *
         * @public
         * @method registerEvents
         */
        registerEvents: function () {
            var me = this;

            me._on(me.$typeSelection, 'change', $.proxy(me.checkType, me));
            me._on(me.$skipAccount, 'change', $.proxy(me.checkSkipAccount, me));
            me._on(me.$alternativeShipping, 'change', $.proxy(me.checkChangeShipping, me));
            me._on(me.$countySelectFields, 'change', $.proxy(me.onCountryChanged, me));
            me._on(me.$paymentMethods, 'change', $.proxy(me.onPaymentChanged, me));
            me._on(me.$inputs, 'blur', $.proxy(me.onValidateInput, me));
            me._on(me.$submitBtn, 'click', $.proxy(me.onSubmitBtn, me));

            $.publish('plugin/swRegister/onRegisterEvents', [ me ]);
        },

        /**
         * Checks the type selection field.
         * If the value is equal to the configured companyType,
         * the company field set will be shown.
         *
         * @public
         * @method checkType
         */
        checkType: function () {
            var me = this,
                opts = me.opts,
                $fieldSet = me.$companyFieldset,
                hideCompanyFields = (me.$typeSelection.length && me.$typeSelection.val() !== opts.companyType),
                requiredFields = $fieldSet.find(opts.inputSelector),
                requiredMethod = (!hideCompanyFields) ? me.setHtmlRequired : me.removeHtmlRequired,
                classMethod = (!hideCompanyFields) ? 'removeClass' : 'addClass';

            requiredMethod(requiredFields);

            $fieldSet[classMethod](opts.hiddenClass);

            $.publish('plugin/swRegister/onCheckType', [ me, hideCompanyFields ]);
        },

        /**
         * Checks the skip account checkbox.
         * The account field set will be shown/hidden depending
         * on the check state of the checkbox.
         *
         * @public
         * @method checkSkipAccount
         */
        checkSkipAccount: function () {
            var me = this,
                opts = me.opts,
                $fieldSet = me.$accountFieldset,
                isChecked = me.$skipAccount.is(':checked'),
                requiredFields = $fieldSet.find(opts.inputSelector),
                requiredMethod = (!isChecked) ? me.setHtmlRequired : me.removeHtmlRequired,
                classMethod = (isChecked) ? 'addClass' : 'removeClass';

            requiredMethod(requiredFields);

            $fieldSet[classMethod](opts.hiddenClass);

            $.publish('plugin/swRegister/onCheckSkipAccount', [ me, isChecked ]);
        },

        /**
         * Checks the alternative shipping checkbox.
         * The shipping field set will be shown/hidden depending
         * on the check state of the checkbox.
         *
         * @public
         * @method checkChangeShipping
         */
        checkChangeShipping: function () {
            var me = this,
                opts = me.opts,
                $fieldSet = me.$shippingFieldset,
                isChecked = me.$alternativeShipping.is(':checked'),
                requiredFields = $fieldSet.find(opts.inputSelector),
                requiredMethod = (isChecked) ? me.setHtmlRequired : me.removeHtmlRequired,
                classMethod = (isChecked) ? 'removeClass' : 'addClass';

            requiredMethod(requiredFields);

            $fieldSet[classMethod](opts.hiddenClass);

            $.publish('plugin/swRegister/onCheckChangeShipping', [ me, isChecked ]);
        },

        /**
         * Called when another country was selected in the country selection.
         * Triggers additional classes depending on the selection.
         *
         * @public
         * @method onCountryChanged
         * @param {jQuery.Event} event
         */
        onCountryChanged: function (event) {
            var me = this,
                opts = me.opts,
                hiddenClass = opts.hiddenClass,
                $select = $(event.currentTarget),
                selectId = $select.attr('id'),
                val = $select.val(),
                $parent = $select.parents('.panel--body'),
                areaSelection = $parent.find('#' + selectId + '_' + val + '_states'),
                select,
                plugin;

            $.publish('plugin/swRegister/onCountryChangedBefore', [ me, event ]);

            $parent.find(opts.stateContainerSelector).addClass(hiddenClass);
            select = areaSelection.find('select');
            areaSelection.addClass(hiddenClass);

            if (!(plugin = select.data('plugin_swSelectboxReplacement'))) {
                return;
            }

            if (!areaSelection.length) {
                plugin.$el.addClass(hiddenClass);
                plugin.$wrapEl.addClass(hiddenClass);
                plugin.setDisabled();
            } else {
                plugin.$el.removeClass(hiddenClass);
                plugin.$wrapEl.removeClass(hiddenClass);
                areaSelection.removeClass(hiddenClass);
                plugin.setEnabled();
            }

            $.publish('plugin/swRegister/onCountryChanged', [ me, event ]);
        },

        /**
         * Called when another payment method was selected.
         * Depending on the selection, the payment field set will be toggled.
         *
         * @public
         * @method onPaymentChanged
         */
        onPaymentChanged: function () {
            var me = this,
                opts = me.opts,
                inputClass = opts.inputSelector,
                hiddenClass = opts.hiddenClass,
                inputSelector = opts.paymentInputSelector,
                paymentSelector = opts.paymentFieldSelector,
                requiredMethod,
                $fieldSet,
                isChecked,
                radio,
                $el;

            $.each(me.$paymentMethods, function (index, el) {
                $el = $(el);

                radio = $el.find(inputSelector);
                isChecked = radio[0].checked;

                requiredMethod = (isChecked) ? me.setHtmlRequired : me.removeHtmlRequired;

                requiredMethod($el.find(inputClass));

                $fieldSet = $el.find(paymentSelector);
                $fieldSet[((isChecked) ? 'removeClass' : 'addClass')](hiddenClass);
            });

            $.publish('plugin/swRegister/onPaymentChanged', [ me ]);
        },

        /**
         * Will be called when the submit button was clicked.
         * Loops through all input fields and checks if they have a value.
         * When no value is available, the field will be marked with an error.
         *
         * @public
         * @method onSubmitBtn
         */
        onSubmitBtn: function () {
            var me = this,
                $input;

            me.$inputs.each(function () {
                $input = $(this);

                if (!$input.val()) {
                    me.setFieldAsError($input);
                }
            });

            $.publish('plugin/swRegister/onSubmitButton', [ me ]);
        },

        /**
         * Called when a input field lost its focus.
         * Depending on the elements id, the corresponding method will be called.
         * billing ust id, emails and passwords will be validated via AJAX.
         *
         * @public
         * @method onValidateInput
         * @param {jQuery.Event} event
         */
        onValidateInput: function (event) {
            var me = this,
                $el = $(event.currentTarget),
                id = $el.attr('id'),
                action;

            switch (id) {
                case 'register_personal_skipLogin':
                case 'register_personal_email':
                case 'register_personal_emailConfirmation':
                    action = 'ajax_validate_email';
                    break;
                case 'register_billing_ustid':
                    action = 'ajax_validate_billing';
                    break;
                case 'register_personal_password':
                case 'register_personal_passwordConfirmation':
                    action = 'ajax_validate_password';
                    break;
                default:
                    break;
            }

            if (!$el.val()) {
                me.setFieldAsError($el);
            } else if ($el.attr('type') === 'checkbox' && !$el.is(':checked')) {
                me.setFieldAsError($el);
            } else if (action) {
                me.validateUsingAjax($el, action);
            } else {
                me.setFieldAsSuccess($el);
            }

            $.publish('plugin/swRegister/onValidateInput', [ me, event, action ]);
        },

        /**
         * Adds additional attributes to the given elements to indicate
         * the elements to be required.
         *
         * @private
         * @method setHtmlRequired
         * @param {jQuery} $elements
         */
        setHtmlRequired: function ($elements) {
            $elements.attr({
                'required': 'required',
                'aria-required': 'true'
            });

            $.publish('plugin/swRegister/onSetHtmlRequired', [ this, $elements ]);
        },

        /**
         * Removes addition attributes that indicate the input as required.
         *
         * @public
         * @method removeHtmlRequired
         * @param {jQuery} $inputs
         */
        removeHtmlRequired: function ($inputs) {
            $inputs.removeAttr('required aria-required');

            $.publish('plugin/swRegister/onRemoveHtmlRequired', [ this, $inputs ]);
        },

        /**
         * Adds the defined error class to the given field or calls the
         * setError() method of the selectboxReplacement plugin if its
         * registered on the element.
         *
         * @public
         * @method setFieldAsError
         * @param {jQuery} $el
         */
        setFieldAsError: function ($el) {
            var me = this,
                plugin;

            if ((plugin = $el.data('plugin_swSelectboxReplacement'))) {
                plugin.setError();
            } else {
                $el.addClass(me.opts.errorClass);
            }

            $.publish('plugin/swRegister/onSetFieldAsError', [ me, $el ]);
        },

        /**
         * Removes the defined error class to the given field or calls the
         * removeError() method of the selectboxReplacement plugin if its
         * registered on the element.
         *
         * @public
         * @method setFieldAsSuccess
         * @param {jQuery} $el
         */
        setFieldAsSuccess: function ($el) {
            var me = this,
                plugin;

            if ((plugin = $el.data('plugin_swSelectboxReplacement'))) {
                plugin.removeError();
            } else {
                $el.removeClass(me.opts.errorClass);
            }

            $.publish('plugin/swRegister/onSetFieldAsSuccess', [ me, $el ]);
        },

        /**
         * Sends an ajax request to validate a given field server side.
         *
         * @public
         * @method validateUsingAjax
         * @param {jQuery} $input
         * @param {String} action
         */
        validateUsingAjax: function ($input, action) {
            var me = this,
                data = 'action=' + action + '&' + me.$el.find('form').serialize(),
                URL = window.controller.ajax_validate + '/' + action;

            if (!URL) {
                return;
            }

            $.publish('plugin/swRegister/onValidateBefore', [ me, data, URL ]);

            $.ajax({
                'data': data,
                'type': 'post',
                'dataType': 'json',
                'url': URL,
                'success': $.proxy(me.onValidateSuccess, me, action, $input)
            });
        },

        /**
         * This method gets called when the server side validation request
         * was successfully called. Updates the corresponding fields
         * and adds/removes error messages.
         *
         * @public
         * @method onValidateSuccess
         * @param {String} action
         * @param {jQuery} $input
         * @param {Object} result
         */
        onValidateSuccess: function (action, $input, result) {
            var me = this,
                errorFlags,
                errorMessages;

            $('#' + action + '--message').remove();

            if (!result) {
                return;
            }

            errorFlags = result.error_flags;
            errorMessages = result.error_messages;

            if (errorFlags) {
                me.updateFieldFlags(errorFlags);
            }

            if (errorMessages && errorMessages.length) {
                $('
', {
                    'html': '
' + errorMessages.join('
') + '
',
                    'id': action + '--message',
                    'class': me.opts.errorMessageClass
                }).insertAfter($input);

                me.setFieldAsError($input);
            }

            $.publish('plugin/swRegister/onValidateSuccess', [ me, $input ]);
        },

        /**
         * Loops through all flags and updates the error/success status
         * of the corresponding elements.
         *
         * @public
         * @method updateFieldFlags
         * @param {Object} flags
         */
        updateFieldFlags: function (flags) {
            var me = this,
                $el = me.$el,
                keys = Object.keys(flags),
                len = keys.length,
                i = 0,
                flag,
                $input;

            for (; i < len; i++) {
                flag = keys[i];
                $input = $el.find('.' + flag);

                if (flags[flag]) {
                    me.setFieldAsError($input);
                    continue;
                }

                me.setFieldAsSuccess($input);
            }

            $.publish('plugin/swRegister/onUpdateFields', [ me, flags ]);
        },

        /**
         * Destroys the initialized plugin completely, so all event listeners will
         * be removed and the plugin data, which is stored in-memory referenced to
         * the DOM node.
         *
         * @public
         * @method destroy
         */
        destroy: function () {
            this._destroy();
        }
    });
})(jQuery);
<|endoftext|>


<commit_before>// read stream to get events
// for each item, check to see if already rendered root
// accept prioritized list (render these first)

var pull = require('pull-stream')
var nest = require('depnest')
var extend = require('xtend')

exports.needs = nest({
  'sbot.pull.backlinks': 'first',
  'sbot.async.get': 'first',
  'message.sync.root': 'first',
  'message.sync.unbox': 'first'
})

exports.gives = nest('feed.pull.rollup', true)

exports.create = function (api) {
  return nest('feed.pull.rollup', function (rootFilter) {
    return pull(
      Roots(),
      Lookup(),
      pull.filter(msg => msg && msg.value && !api.message.sync.root(msg)),
      pull.filter(rootFilter || (() => true)),
      AddReplies()
    )
  })

  // scoped

  function Roots () {
    var alreadyEmitted = new Set()
    return pull(
      pull.map((msg) => {
        var root = api.message.sync.root(msg) || msg.key
        if (!alreadyEmitted.has(root)) {
          alreadyEmitted.add(root)
          return root
        }
      }),
      pull.filter()
    )
  }

  function Lookup () {
    return pull.asyncMap((key, cb) => {
      api.sbot.async.get(key, (_, value) => {
        if (typeof value.content === 'string') {
          value = api.message.sync.unbox(value)
        }
        cb(null, {key, value})
      })
    })
  }

  function AddReplies () {
    return pull.asyncMap((rootMessage, cb) => {
      pull(
        api.sbot.pull.backlinks({
          query: [{$filter: { dest: rootMessage.key }}]
        }),
        pull.filter(msg => api.message.sync.root(msg) || rootMessage.key === rootMessage.key),
        pull.collect((err, replies) => {
          if (err) return cb(err)
          cb(null, extend(rootMessage, { replies }))
        })
      )
    })
  }
}
<commit_msg>feed.pull.rollup: use pull.unique instead of custom code<commit_after>// read stream to get events
// for each item, check to see if already rendered root
// accept prioritized list (render these first)

var pull = require('pull-stream')
var nest = require('depnest')
var extend = require('xtend')

exports.needs = nest({
  'sbot.pull.backlinks': 'first',
  'sbot.async.get': 'first',
  'message.sync.root': 'first',
  'message.sync.unbox': 'first'
})

exports.gives = nest('feed.pull.rollup', true)

exports.create = function (api) {
  return nest('feed.pull.rollup', function (rootFilter) {
    return pull(
      pull.map(msg => api.message.sync.root(msg) || msg.key),
      pull.unique(),
      Lookup(),
      pull.filter(msg => msg && msg.value && !api.message.sync.root(msg)),
      pull.filter(rootFilter || (() => true)),
      AddReplies()
    )
  })

  // scoped
  function Lookup () {
    return pull.asyncMap((key, cb) => {
      api.sbot.async.get(key, (_, value) => {
        if (typeof value.content === 'string') {
          value = api.message.sync.unbox(value)
        }
        cb(null, {key, value})
      })
    })
  }

  function AddReplies () {
    return pull.asyncMap((rootMessage, cb) => {
      pull(
        api.sbot.pull.backlinks({
          query: [{$filter: { dest: rootMessage.key }}]
        }),
        pull.filter(msg => api.message.sync.root(msg) || rootMessage.key === rootMessage.key),
        pull.collect((err, replies) => {
          if (err) return cb(err)
          cb(null, extend(rootMessage, { replies }))
        })
      )
    })
  }
}
<|endoftext|>


<commit_before>// HyperHTML Renderer ported to SkateJS
import { withComponent, shadow, props } from 'skatejs';
import { hasNativeShadowDomSupport } from '../utils/environment';
import { findParentTag } from '../utils/find-parent-tag';

export function BoltBase(Base = HTMLElement) {
  return class extends Base {
    constructor(...args) {
      super(...args);
      this._wasInitiallyRendered = false;
    }

    connectedCallback() {
      // NOTE: it's SUPER important that setupSlots is run during the component's connectedCallback lifecycle event
      // Without this, browsers like IE 11 won't re-render as expected when props change!
      this.setupSlots();

      // Automatically force a component to render if no props exist BUT props are defined.
      if (
        Object.keys(this.props).length !== 0 &&
        Object.keys(this._props).length === 0
      ) {
        this.updated();
      }
    }

    setupSlots() {
      // Automatically adjust which inner element inside the custom element gets used as the base when evaluating slotted children. Necessary when including deeply nested slots in the initial HTML being rendered, which might include a few wrapping containers that get removed when the JavaScript kicks in. <-- this is how we get slotted buttons to work!
      const isShadowRootSelector = this.querySelector('[is="shadow-root"]');
      if (isShadowRootSelector && isShadowRootSelector.childNodes) {
        if (isShadowRootSelector.childNodes) {
          this.slots = this._checkSlots(isShadowRootSelector.childNodes);
        } else {
          this.slots = this._checkSlots();
        }
      } else {
        this.slots = this._checkSlots();
      }
    }

    setupShadow() {
      if (
        this.useShadow === false ||
        findParentTag(this, 'FORM') ||
        this.getAttribute('no-shadow') !== null
      ) {
        this.useShadow = false;
      } else {
        this.useShadow = hasNativeShadowDomSupport;
      }
    }

    get renderRoot() {
      // ensure every component instance renders to the light DOM when needed (ex. if nested inside of a form, render to the light DOM)
      // this ensures that things work as expected, even when a component gets removed / re-added to the page
      this.setupShadow();

      if (hasNativeShadowDomSupport && this.useShadow === true) {
        return super.renderRoot || shadow(this);
      } else {
        return this;
      }
    }

    addStyles(stylesheet) {
      let styles = Array.from(stylesheet);
      styles = styles.join(' ');

      if (this.useShadow && this.renderStyles) {
        return this.renderStyles(styles);
      }
    }

    // Inspired by https://codepen.io/jovdb/pen/ddRZKo
    _checkSlots(selector = this.childNodes) {
      const slots = { default: [] };

      // Loop through nodelist
      selector.forEach(function(child, index, nodelist) {
        const slotName = child.getAttribute ? child.getAttribute('slot') : null;

        if (!slotName) {
          slots.default.push(child);
        } else if (slots[slotName]) {
          slots[slotName].push(child);
        } else {
          slots[slotName] = [];
          slots[slotName].push(child);
        }
      });

      return slots;
    }

    disconnectedCallback() {
      this.disconnecting && this.disconnecting();
      this.disconnected && this.disconnected();
    }

    rendered() {
      if (!this._wasInitiallyRendered) {
        this._wasInitiallyRendered = true;

        // Fired only once, when the component has finished rendering for the first time.
        this.dispatchEvent(
          new CustomEvent('ready', {
            detail: {
              name: this.tagName.toLowerCase(),
              shadowDom: this.useShadow ? true : false,
            },
            bubbles: true,
          }),
        );
      }

      // Fired every time an element has rendered
      this.dispatchEvent(
        new CustomEvent('rendered', {
          detail: {
            name: this.tagName.toLowerCase(),
            shadowDom: this.useShadow ? true : false,
          },
          bubbles: true,
        }),
      );
    }
  };
}
<commit_msg>hotfix: update bolt-base to re-check slotted content during the component's renderRoot method — workaround to address occasional rendering issues with dynamically injected content<commit_after>// HyperHTML Renderer ported to SkateJS
import { withComponent, shadow, props } from 'skatejs';
import { hasNativeShadowDomSupport } from '../utils/environment';
import { findParentTag } from '../utils/find-parent-tag';

export function BoltBase(Base = HTMLElement) {
  return class extends Base {
    constructor(...args) {
      super(...args);
      this._wasInitiallyRendered = false;
    }

    connectedCallback() {
      // NOTE: it's SUPER important that setupSlots is run during the component's connectedCallback lifecycle event
      // Without this, browsers like IE 11 won't re-render as expected when props change!
      this.setupSlots();

      // Automatically force a component to render if no props exist BUT props are defined.
      if (
        Object.keys(this.props).length !== 0 &&
        Object.keys(this._props).length === 0
      ) {
        this.updated();
      }
    }

    setupSlots() {
      // Automatically adjust which inner element inside the custom element gets used as the base when evaluating slotted children. Necessary when including deeply nested slots in the initial HTML being rendered, which might include a few wrapping containers that get removed when the JavaScript kicks in. <-- this is how we get slotted buttons to work!
      const isShadowRootSelector = this.querySelector('[is="shadow-root"]');
      if (isShadowRootSelector && isShadowRootSelector.childNodes) {
        if (isShadowRootSelector.childNodes) {
          this.slots = this._checkSlots(isShadowRootSelector.childNodes);
        } else {
          this.slots = this._checkSlots();
        }
      } else {
        this.slots = this._checkSlots();
      }
    }

    setupShadow() {
      if (
        this.useShadow === false ||
        findParentTag(this, 'FORM') ||
        this.getAttribute('no-shadow') !== null
      ) {
        this.useShadow = false;
      } else {
        this.useShadow = hasNativeShadowDomSupport;
      }
    }

    get renderRoot() {
      // ensure every component instance renders to the light DOM when needed (ex. if nested inside of a form, render to the light DOM)
      // this ensures that things work as expected, even when a component gets removed / re-added to the page
      this.setupShadow();

      // @todo: rework to disable this extra check here (used for demoing before/after behavior), unless a specific feature flag is used (debug mode?)
      if (!this.closest('.js-disable-extra-slot-check')) {
        this.setupSlots(); // hotfix to ensure heavily nested elements containing text-nodes like <replace-with-children> re-render consistently in browsers that don't natively support custom elements Fixes wwwd8-2678
      }

      if (hasNativeShadowDomSupport && this.useShadow === true) {
        return super.renderRoot || shadow(this);
      } else {
        return this;
      }
    }

    addStyles(stylesheet) {
      let styles = Array.from(stylesheet);
      styles = styles.join(' ');

      if (this.useShadow && this.renderStyles) {
        return this.renderStyles(styles);
      }
    }

    // Inspired by https://codepen.io/jovdb/pen/ddRZKo
    _checkSlots(selector = this.childNodes) {
      const slots = { default: [] };

      // Loop through nodelist
      selector.forEach(function(child, index, nodelist) {
        const slotName = child.getAttribute ? child.getAttribute('slot') : null;

        if (!slotName) {
          slots.default.push(child);
        } else if (slots[slotName]) {
          slots[slotName].push(child);
        } else {
          slots[slotName] = [];
          slots[slotName].push(child);
        }
      });

      return slots;
    }

    disconnectedCallback() {
      this.disconnecting && this.disconnecting();
      this.disconnected && this.disconnected();
    }

    rendered() {
      if (!this._wasInitiallyRendered) {
        this._wasInitiallyRendered = true;

        // Fired only once, when the component has finished rendering for the first time.
        this.dispatchEvent(
          new CustomEvent('ready', {
            detail: {
              name: this.tagName.toLowerCase(),
              shadowDom: this.useShadow ? true : false,
            },
            bubbles: true,
          }),
        );
      }

      // Fired every time an element has rendered
      this.dispatchEvent(
        new CustomEvent('rendered', {
          detail: {
            name: this.tagName.toLowerCase(),
            shadowDom: this.useShadow ? true : false,
          },
          bubbles: true,
        }),
      );
    }
  };
}
<|endoftext|>


<commit_before>import {Game, ItemList, Item} from './game.js'

export default new Game({
  id: 'shiren',
  title: '不思議のダンジョン2 風来のシレン',
  shortTitle: '風来のシレン',
  lists: [
    new ItemList({
      type: 'udewa',
      name: '腕輪',
      items: [
        new Item({name: '遠投の腕輪',       buy: 1200,  sell: 600}),
        new Item({name: '混乱よけの腕輪',   buy: 2400,  sell: 1200}),
        new Item({name: '錆よけの腕輪',     buy: 2400,  sell: 1200}),
        new Item({name: '垂れ流しの腕輪',   buy: 2400,  sell: 1200}),
        new Item({name: '通過の腕輪',       buy: 2400,  sell: 1200}),
        new Item({name: '呪いよけの腕輪',   buy: 2400,  sell: 1200}),
        new Item({name: 'レベル固定の腕輪', buy: 2400,  sell: 1200}),
        new Item({name: '透視の腕輪',       buy: 3600,  sell: 1800}),
        new Item({name: '回復の腕輪',       buy: 5000,  sell: 2500}),
        new Item({name: 'ワナ師の腕輪',     buy: 5000,  sell: 2500}),
        new Item({name: '会心の腕輪',       buy: 10000, sell: 5000}),
        new Item({name: 'しあわせの腕輪',   buy: 10000, sell: 5000}),
        new Item({name: '痛恨の腕輪',       buy: 10000, sell: 5000}),
        new Item({name: '値切の腕輪',       buy: 10000, sell: 5000}),
        new Item({name: '識別の腕輪',       buy: 30000, sell: 15000}),
      ]
    }),
    new ItemList({
      type: 'kusa',
      name: '草',
      items: [
        new Item({name: '雑草',         buy: 50,    sell: 25}),
        new Item({name: 'どく草',       buy: 50,    sell: 25}),
        new Item({name: 'めぐすり草',   buy: 50,    sell: 25}),
        new Item({name: '薬草',         buy: 50,    sell: 25}),
        new Item({name: '弟切草',       buy: 100,   sell: 50}),
        new Item({name: '超不幸の種',   buy: 200,   sell: 30}),
        new Item({name: '不幸の種',     buy: 200,   sell: 40}),
        new Item({name: 'くねくね草',   buy: 200,   sell: 50}),
        new Item({name: '胃縮小の種',   buy: 200,   sell: 60}),
        new Item({name: 'キグニ族の種', buy: 200,   sell: 100}),
        new Item({name: '命の草',       buy: 500,   sell: 200}),
        new Item({name: 'ドラゴン草',   buy: 500,   sell: 200}),
        new Item({name: 'ちからの草',   buy: 500,   sell: 250}),
        new Item({name: 'どく消し草',   buy: 650,   sell: 250}),
        new Item({name: '胃拡張の種',   buy: 1000,  sell: 500}),
        new Item({name: 'しあわせ草',   buy: 1000,  sell: 500}),
        new Item({name: '無敵草',       buy: 3000,  sell: 100}),
        new Item({name: '混乱草',       buy: 3000,  sell: 1500}),
        new Item({name: '睡眠草',       buy: 5000,  sell: 2500}),
        new Item({name: '復活の草',     buy: 5000,  sell: 2500}),
        new Item({name: '天使の種',     buy: 10000, sell: 1500}),
      ]
    }),
    new ItemList({
      type: 'makimono',
      name: '巻物',
      items: [
          new Item({name: 'モンスターハウスの巻物', buy: 80,    sell: 40}),
          new Item({name: '混乱の巻物',             buy: 100,   sell: 50}),
          new Item({name: '敵倍速の巻物',           buy: 100,   sell: 50}),
          new Item({name: 'バクスイの巻物',         buy: 200,   sell: 100}),
          new Item({name: '迷子の巻物',             buy: 200,   sell: 100}),
          new Item({name: '識別の巻物',             buy: 300,   sell: 150}),
          new Item({name: 'あかりの巻物',           buy: 300,   sell: 250}),
          new Item({name: '拾えずの巻物',           buy: 300,   sell: 300}),
          new Item({name: '大部屋の巻物',           buy: 400,   sell: 200}),
          new Item({name: '自爆の巻物',             buy: 500,   sell: 100}),
          new Item({name: 'おはらいの巻物',         buy: 500,   sell: 250}),
          new Item({name: 'くちなしの巻物',         buy: 500,   sell: 250}),
          new Item({name: '地の恵みの巻物',         buy: 800,   sell: 400}),
          new Item({name: '天の恵みの巻物',         buy: 800,   sell: 400}),
          new Item({name: 'パワーアップの巻物',     buy: 1000,  sell: 100}),
          new Item({name: '困った時の巻物',         buy: 1000,  sell: 250}),
          new Item({name: '真空斬りの巻物',         buy: 1000,  sell: 500}),
          new Item({name: '壺増大の巻物',           buy: 1000,  sell: 500}),
          new Item({name: 'ワナの巻物',             buy: 1000,  sell: 500}),
          new Item({name: 'メッキの巻物',           buy: 1500,  sell: 500}),
          new Item({name: '吸い出しの巻物',         buy: 1500,  sell: 750}),
          new Item({name: '白紙の巻物',             buy: 3000,  sell: 1000}),
          new Item({name: 'ジェノサイドの巻物',     buy: 50000, sell: 750}),
          new Item({name: '聖域の巻物',             buy: -1,     sell: -1}),
          new Item({name: '全滅の巻物',             buy: -1,     sell: -1}),
      ]
    }),
    new ItemList({
      type: 'tsubo',
      name: '壺',
      items: [
        new Item({name: '弱化の壺',           buy: 1000,  sell: 200}),
        new Item({name: 'やりすごしの壺',     buy: 1000,  sell: 400}),
        new Item({name: '識別の壺',           buy: 1000,  sell: 500}),
        new Item({name: '変化の壺',           buy: 1000,  sell: 500}),
        new Item({name: '背中の壺',           buy: 1500,  sell: 700}),
        new Item({name: 'トドの壺',           buy: 1600,  sell: 600}),
        new Item({name: '保存の壺',           buy: 1600,  sell: 600}),
        new Item({name: '魔物のるつぼ',       buy: 2000,  sell: 300}),
        new Item({name: '底抜けの壺',         buy: 2500,  sell: 400}),
        new Item({name: '倉庫の壺',           buy: 2500,  sell: 1200}),
        new Item({name: '分裂の壺',           buy: 3000,  sell: 1500}),
        new Item({name: '合成の壺',           buy: 3500,  sell: 1500}),
        new Item({name: 'アホくさい壺',       buy: 7500,  sell: 1500}),
        new Item({name: 'うっぷんばらしの壺', buy: 7500,  sell: 1500}),
        new Item({name: '割れない壺',         buy: 10000, sell: 1500}),
        new Item({name: '強化の壺',           buy: 10000, sell: 5000}),
        new Item({name: 'ガイバラの壺',       buy: 15000, sell: 1500}),
      ]
    }),
    new ItemList({
      type: 'tsue',
      name: '杖',
      items: [
        new Item({name: 'ガイコツまどうの杖', buy: 300,  sell: 150}),
        new Item({name: '一時しのぎの杖',     buy: 500,  sell: 250}),
        new Item({name: 'しあわせの杖',       buy: 500,  sell: 250}),
        new Item({name: 'ふきとばしの杖',     buy: 500,  sell: 250}),
        new Item({name: '不幸の杖',           buy: 500,  sell: 250}),
        new Item({name: '場所替えの杖',       buy: 700,  sell: 350}),
        new Item({name: '痛み分けの杖',       buy: 1000, sell: 500}),
        new Item({name: 'かなしばりの杖',     buy: 1000, sell: 500}),
        new Item({name: '封印の杖    ',       buy: 1000, sell: 500}),
        new Item({name: '身がわりの杖',       buy: 1000, sell: 500}),
        new Item({name: 'ブフーの杖',         buy: 2000, sell: 500}),
      ]
    }),
  ]
});

<commit_msg>model/shiren.js: Add properties to show about page<commit_after>import {Game, ItemList, Item} from './game.js'

export default new Game({
  id: 'shiren',
  title: '不思議のダンジョン2 風来のシレン',
  shortTitle: '風来のシレン',
  gameUrl: 'https://www.nintendo.co.jp/wii/vc/vc_sr/',
  developerName: 'スパイク・チュンソフト',
  developerUrl: 'http://www.spike-chunsoft.co.jp/',
  referenceName: 'SFCシレンwiki',
  referenceUrl: 'http://twist.jpn.org/sfcsiren/',
  lists: [
    new ItemList({
      type: 'udewa',
      name: '腕輪',
      items: [
        new Item({name: '遠投の腕輪',       buy: 1200,  sell: 600}),
        new Item({name: '混乱よけの腕輪',   buy: 2400,  sell: 1200}),
        new Item({name: '錆よけの腕輪',     buy: 2400,  sell: 1200}),
        new Item({name: '垂れ流しの腕輪',   buy: 2400,  sell: 1200}),
        new Item({name: '通過の腕輪',       buy: 2400,  sell: 1200}),
        new Item({name: '呪いよけの腕輪',   buy: 2400,  sell: 1200}),
        new Item({name: 'レベル固定の腕輪', buy: 2400,  sell: 1200}),
        new Item({name: '透視の腕輪',       buy: 3600,  sell: 1800}),
        new Item({name: '回復の腕輪',       buy: 5000,  sell: 2500}),
        new Item({name: 'ワナ師の腕輪',     buy: 5000,  sell: 2500}),
        new Item({name: '会心の腕輪',       buy: 10000, sell: 5000}),
        new Item({name: 'しあわせの腕輪',   buy: 10000, sell: 5000}),
        new Item({name: '痛恨の腕輪',       buy: 10000, sell: 5000}),
        new Item({name: '値切の腕輪',       buy: 10000, sell: 5000}),
        new Item({name: '識別の腕輪',       buy: 30000, sell: 15000}),
      ]
    }),
    new ItemList({
      type: 'kusa',
      name: '草',
      items: [
        new Item({name: '雑草',         buy: 50,    sell: 25}),
        new Item({name: 'どく草',       buy: 50,    sell: 25}),
        new Item({name: 'めぐすり草',   buy: 50,    sell: 25}),
        new Item({name: '薬草',         buy: 50,    sell: 25}),
        new Item({name: '弟切草',       buy: 100,   sell: 50}),
        new Item({name: '超不幸の種',   buy: 200,   sell: 30}),
        new Item({name: '不幸の種',     buy: 200,   sell: 40}),
        new Item({name: 'くねくね草',   buy: 200,   sell: 50}),
        new Item({name: '胃縮小の種',   buy: 200,   sell: 60}),
        new Item({name: 'キグニ族の種', buy: 200,   sell: 100}),
        new Item({name: '命の草',       buy: 500,   sell: 200}),
        new Item({name: 'ドラゴン草',   buy: 500,   sell: 200}),
        new Item({name: 'ちからの草',   buy: 500,   sell: 250}),
        new Item({name: 'どく消し草',   buy: 650,   sell: 250}),
        new Item({name: '胃拡張の種',   buy: 1000,  sell: 500}),
        new Item({name: 'しあわせ草',   buy: 1000,  sell: 500}),
        new Item({name: '無敵草',       buy: 3000,  sell: 100}),
        new Item({name: '混乱草',       buy: 3000,  sell: 1500}),
        new Item({name: '睡眠草',       buy: 5000,  sell: 2500}),
        new Item({name: '復活の草',     buy: 5000,  sell: 2500}),
        new Item({name: '天使の種',     buy: 10000, sell: 1500}),
      ]
    }),
    new ItemList({
      type: 'makimono',
      name: '巻物',
      items: [
          new Item({name: 'モンスターハウスの巻物', buy: 80,    sell: 40}),
          new Item({name: '混乱の巻物',             buy: 100,   sell: 50}),
          new Item({name: '敵倍速の巻物',           buy: 100,   sell: 50}),
          new Item({name: 'バクスイの巻物',         buy: 200,   sell: 100}),
          new Item({name: '迷子の巻物',             buy: 200,   sell: 100}),
          new Item({name: '識別の巻物',             buy: 300,   sell: 150}),
          new Item({name: 'あかりの巻物',           buy: 300,   sell: 250}),
          new Item({name: '拾えずの巻物',           buy: 300,   sell: 300}),
          new Item({name: '大部屋の巻物',           buy: 400,   sell: 200}),
          new Item({name: '自爆の巻物',             buy: 500,   sell: 100}),
          new Item({name: 'おはらいの巻物',         buy: 500,   sell: 250}),
          new Item({name: 'くちなしの巻物',         buy: 500,   sell: 250}),
          new Item({name: '地の恵みの巻物',         buy: 800,   sell: 400}),
          new Item({name: '天の恵みの巻物',         buy: 800,   sell: 400}),
          new Item({name: 'パワーアップの巻物',     buy: 1000,  sell: 100}),
          new Item({name: '困った時の巻物',         buy: 1000,  sell: 250}),
          new Item({name: '真空斬りの巻物',         buy: 1000,  sell: 500}),
          new Item({name: '壺増大の巻物',           buy: 1000,  sell: 500}),
          new Item({name: 'ワナの巻物',             buy: 1000,  sell: 500}),
          new Item({name: 'メッキの巻物',           buy: 1500,  sell: 500}),
          new Item({name: '吸い出しの巻物',         buy: 1500,  sell: 750}),
          new Item({name: '白紙の巻物',             buy: 3000,  sell: 1000}),
          new Item({name: 'ジェノサイドの巻物',     buy: 50000, sell: 750}),
          new Item({name: '聖域の巻物',             buy: -1,     sell: -1}),
          new Item({name: '全滅の巻物',             buy: -1,     sell: -1}),
      ]
    }),
    new ItemList({
      type: 'tsubo',
      name: '壺',
      items: [
        new Item({name: '弱化の壺',           buy: 1000,  sell: 200}),
        new Item({name: 'やりすごしの壺',     buy: 1000,  sell: 400}),
        new Item({name: '識別の壺',           buy: 1000,  sell: 500}),
        new Item({name: '変化の壺',           buy: 1000,  sell: 500}),
        new Item({name: '背中の壺',           buy: 1500,  sell: 700}),
        new Item({name: 'トドの壺',           buy: 1600,  sell: 600}),
        new Item({name: '保存の壺',           buy: 1600,  sell: 600}),
        new Item({name: '魔物のるつぼ',       buy: 2000,  sell: 300}),
        new Item({name: '底抜けの壺',         buy: 2500,  sell: 400}),
        new Item({name: '倉庫の壺',           buy: 2500,  sell: 1200}),
        new Item({name: '分裂の壺',           buy: 3000,  sell: 1500}),
        new Item({name: '合成の壺',           buy: 3500,  sell: 1500}),
        new Item({name: 'アホくさい壺',       buy: 7500,  sell: 1500}),
        new Item({name: 'うっぷんばらしの壺', buy: 7500,  sell: 1500}),
        new Item({name: '割れない壺',         buy: 10000, sell: 1500}),
        new Item({name: '強化の壺',           buy: 10000, sell: 5000}),
        new Item({name: 'ガイバラの壺',       buy: 15000, sell: 1500}),
      ]
    }),
    new ItemList({
      type: 'tsue',
      name: '杖',
      items: [
        new Item({name: 'ガイコツまどうの杖', buy: 300,  sell: 150}),
        new Item({name: '一時しのぎの杖',     buy: 500,  sell: 250}),
        new Item({name: 'しあわせの杖',       buy: 500,  sell: 250}),
        new Item({name: 'ふきとばしの杖',     buy: 500,  sell: 250}),
        new Item({name: '不幸の杖',           buy: 500,  sell: 250}),
        new Item({name: '場所替えの杖',       buy: 700,  sell: 350}),
        new Item({name: '痛み分けの杖',       buy: 1000, sell: 500}),
        new Item({name: 'かなしばりの杖',     buy: 1000, sell: 500}),
        new Item({name: '封印の杖    ',       buy: 1000, sell: 500}),
        new Item({name: '身がわりの杖',       buy: 1000, sell: 500}),
        new Item({name: 'ブフーの杖',         buy: 2000, sell: 500}),
      ]
    }),
  ]
});

<|endoftext|>


<commit_before>Facebook = {};

// Request Facebook credentials for the user
//
// @param options {optional}
// @param credentialRequestCompleteCallback {Function} Callback function to call on
//   completion. Takes one argument, credentialToken on success, or Error on
//   error.
Facebook.requestCredential = function (options, credentialRequestCompleteCallback) {
  // support both (options, callback) and (callback).
  if (!credentialRequestCompleteCallback && typeof options === 'function') {
    credentialRequestCompleteCallback = options;
    options = {};
  }

  var config = ServiceConfiguration.configurations.findOne({service: 'facebook'});
  if (!config) {
    credentialRequestCompleteCallback && credentialRequestCompleteCallback(new ServiceConfiguration.ConfigError("Service not configured"));
    return;
  }

  var credentialToken = Random.id();
  var mobile = /Android|webOS|iPhone|iPad|iPod|BlackBerry/i.test(navigator.userAgent);
  var display = mobile ? 'touch' : 'popup';

  var scope = "email";
  if (options && options.requestPermissions)
    scope = options.requestPermissions.join(',');

  var loginUrl =
        'https://www.facebook.com/dialog/oauth?client_id=' + config.appId +
        '&redirect_uri=' + Meteor.absoluteUrl('_oauth/facebook?close') +
        '&display=' + display + '&scope=' + scope + '&state=' + credentialToken;

  Oauth.showPopup(
    loginUrl,
    _.bind(credentialRequestCompleteCallback, null, credentialToken)
  );
};
<commit_msg>Add Windows Phone to mobile<commit_after>Facebook = {};

// Request Facebook credentials for the user
//
// @param options {optional}
// @param credentialRequestCompleteCallback {Function} Callback function to call on
//   completion. Takes one argument, credentialToken on success, or Error on
//   error.
Facebook.requestCredential = function (options, credentialRequestCompleteCallback) {
  // support both (options, callback) and (callback).
  if (!credentialRequestCompleteCallback && typeof options === 'function') {
    credentialRequestCompleteCallback = options;
    options = {};
  }

  var config = ServiceConfiguration.configurations.findOne({service: 'facebook'});
  if (!config) {
    credentialRequestCompleteCallback && credentialRequestCompleteCallback(new ServiceConfiguration.ConfigError("Service not configured"));
    return;
  }

  var credentialToken = Random.id();
  var mobile = /Android|webOS|iPhone|iPad|iPod|BlackBerry|Windows Phone/i.test(navigator.userAgent);
  var display = mobile ? 'touch' : 'popup';

  var scope = "email";
  if (options && options.requestPermissions)
    scope = options.requestPermissions.join(',');

  var loginUrl =
        'https://www.facebook.com/dialog/oauth?client_id=' + config.appId +
        '&redirect_uri=' + Meteor.absoluteUrl('_oauth/facebook?close') +
        '&display=' + display + '&scope=' + scope + '&state=' + credentialToken;

  Oauth.showPopup(
    loginUrl,
    _.bind(credentialRequestCompleteCallback, null, credentialToken)
  );
};
<|endoftext|>


<commit_before>const Discord = require("discord.js");
const client = new Discord.Client();

const owner_id = "" //put your ID here. HOW TO GET AN ID : http://i.imgur.com/GhKpBMQ.gif
client.login("") //put your bot token here, Not "secret".  The secret is not the token.

var prefix = "px;"
var version = "v0.2 Beta 1"

client.on("ready", () => {
	console.log("\n===============================\n")
	console.log(`PIXABOT`)
	console.log(`Logged in as ${client.user.username}`);
	console.log("The bot is ready! Currently on:");
	console.log(client.guilds.size + " servers");
	console.log(client.channels.size + " channels")
	console.log("\n===============================\n")
});

client.on("guildCreate", guild => {
	console.log(`New guild joined ${guild.name}`);
});

client.on("guildDelete", guild => {
	  console.log(`I have been removed from ${guild.name}`);
});

client.on("disconnected", function () {
	  console.log("The bot is now shut down.");
	  process.exit(1);
});

client.on("message", function(message) {

    if (message.author.equals(client.user)) return;

    if (!message.content.startsWith(prefix)) return;

    var args = message.content.substring(prefix.length).split(" ");
    var haveMatched=true;

    switch (args[0]) {
        //ping command

        case "ping":
            var m = message.channel.send("Ping...").then(m => {
            var embed = new Discord.RichEmbed()
           	.setColor("#940000")
           	.setAuthor("Pong!", "https://image.noelshack.com/fichiers/2017/33/6/1503111758-371886a66446c46e66e9435158468720.png")
	     	.setDescription(`Response time: ${m.createdTimestamp - message.createdTimestamp}ms`)
           	.setFooter("Requested by " + message.author.tag, message.author.displayAvatarURL)
           	.setTimestamp()
            m.delete()
            message.channel.send({embed})
            });
            break;
        // about command
        case "about":
            var embed = new Discord.RichEmbed()
	        .setColor("#940000")
            	.setTitle("About PixaBot")
		.setDescription("PixaBot is a Discord bot that features games, image manipulation, moderation and music commands written in JavaScript.")
           	.setFooter("Requested by " + message.author.tag, message.author.displayAvatarURL)
           	.setTimestamp()
            message.channel.send({embed});
            break;
        // version command
        case "version":
            var embed = new Discord.RichEmbed()
	        .setColor("#940000")
            	.setTitle("Version", "The current version is **v0.2 beta 1**.")
           	.setFooter("Requested by " + message.author.tag, message.author.displayAvatarURL)
           	.setTimestamp()
            message.channel.send({embed});
            break;
        // kick command
        case "kick":
		    message.channel.send("Coming Soon!")
		break;
        // ban command
        case "ban":
            message.channel.send("Coming Soon!")
            break;
        case "shutdown":
            if (message.author.id != owner_id) {
                return;
            } else {
                var embed = new Discord.RichEmbed()
                .setColor("#940000")
                    .setTitle("Shuting down...", "Please wait.")
                    .setFooter("Requested by " + message.author.tag, message.author.displayAvatarURL)
                    .setTimestamp()
                message.channel.send({embed});
                client.destroy((err) => {
                        console.log(err);
                    });
                console.log("The bot is now shut down.");
                setTimeout(function(){
                    process.exit(0);
                }, 2000)
            }
            break;
                //exit node.js without an error
        case "help":
                var embed = new Discord.RichEmbed()
                .setColor("#940000")
                .setTitle("PixaBot Help Guide")
		.setDescription("Here are my available commands. To execute one of my commands, my prefix is `px;`.")
                .addField("General Commands", "ping\nabout\nversion", true)
		.addField("Coming Soon", "px;kick\npx;ban", true)
		.addField("Owner", "shutdown", true)
                .setFooter("Requested by " + message.author.tag, message.author.displayAvatarURL)
                .setTimestamp()
                message.channel.send({embed});
            break;
        case "CanIbeMod?":
            message.channel.send("No, but you can be jailed if you want.")
            break;
        default:
            haveMatched = false
	    message.channel.send("Unknown command.")
}
if (haveMatched){
    console.log(`[Command] ${message.author.id}/${message.author.username} (${message.content})`)
}
})
<commit_msg>Improved help and some descriptive commands.<commit_after>const Discord = require("discord.js");
const client = new Discord.Client();

const owner_id = "" //put your ID here. HOW TO GET AN ID : http://i.imgur.com/GhKpBMQ.gif
client.login("") //put your bot token here, Not "secret".  The secret is not the token.

var prefix = "px;"
var version = "v0.2 Beta 1"

client.on("ready", () => {
	console.log("\n===============================\n")
	console.log(`PIXABOT`)
	console.log(`Logged in as ${client.user.username}`);
	console.log("The bot is ready! Currently on:");
	console.log(client.guilds.size + " servers");
	console.log(client.channels.size + " channels")
	console.log("\n===============================\n")
});

client.on("guildCreate", guild => {
	console.log(`New guild joined ${guild.name}`);
});

client.on("guildDelete", guild => {
	  console.log(`I have been removed from ${guild.name}`);
});

client.on("disconnected", function () {
	  console.log("The bot is now shut down.");
	  process.exit(1);
});

client.on("message", function(message) {

    if (message.author.equals(client.user)) return;

    if (!message.content.startsWith(prefix)) return;

    var args = message.content.substring(prefix.length).split(" ");
    var haveMatched=true;

    switch (args[0]) {
        //ping command
        case "ping":
            var m = message.channel.send("Ping...").then(m => {
            var embed = new Discord.RichEmbed()
           	.setColor("#940000")
           	.setAuthor("Pong!", "https://image.noelshack.com/fichiers/2017/33/6/1503111758-371886a66446c46e66e9435158468720.png")
	     	.setDescription(`Response time: ${m.createdTimestamp - message.createdTimestamp}ms`)
           	.setFooter("Requested by " + message.author.tag, message.author.displayAvatarURL)
           	.setTimestamp()
            m.delete()
            message.channel.send({embed})
            });
            break;
        // about command
        case "about":
            var embed = new Discord.RichEmbed()
	        .setColor("#940000")
            .setTitle("About PixaBot")
			.setDescription("PixaBot is a Discord bot that features games, image manipulation, moderation and music commands written in JavaScript.")
           	.setFooter("Requested by " + message.author.tag, message.author.displayAvatarURL)
           	.setTimestamp()
            message.channel.send({embed});
            break;
        // version command
        case "version":
            var embed = new Discord.RichEmbed()
	        .setColor("#940000")
            .setAuthor("Version"
			.setDescription("The current version is " + ver + ".")
           	.setFooter("Requested by " + message.author.tag, message.author.displayAvatarURL)
           	.setTimestamp()
            message.channel.send({embed});
            break;
        // kick command
        case "kick":
		    message.channel.send("Coming Soon!")
		break;
        // ban command
        case "ban":
            message.channel.send("Coming Soon!")
            break;
        case "shutdown":
            if (message.author.id != owner_id) {
                return;
            } else {
                var embed = new Discord.RichEmbed()
                .setColor("#940000")
                    .setTitle("Shuting down...", "Please wait.")
                    .setFooter("Requested by " + message.author.tag, message.author.displayAvatarURL)
                    .setTimestamp()
                message.channel.send({embed});
                client.destroy((err) => {
                        console.log(err);
                    });
                console.log("The bot is now shut down.");
                setTimeout(function(){
                    process.exit(0);
                }, 2000)
            }
            break;
                //exit node.js without an error
        case "help":
                var embed = new Discord.RichEmbed()
                .setColor("#940000")
                .setTitle("PixaBot Help Guide")
		.setDescription("Here are my available commands. To execute one of my commands, my prefix is `px;`.")
                .addField("General Commands", "`ping` - Test a connection to PixaBot.\n`about` - Information about PixaBot.\n`version` - Displays the PixaBot's current version.", true)
		.addField("Coming Soon", "`kick` - Kicks a member.\n`ban` - Bans the user out of this server.", true)
		.addField("Owner", "`shutdown` - De-initialize the bot.", true)
                .setFooter("Requested by " + message.author.tag, message.author.displayAvatarURL)
                .setTimestamp()
                message.channel.send({embed});
            break;
        case "CanIbeMod?":
            message.channel.send("No, but you can be jailed if you want.")
            break;
        default:
            haveMatched = false
	    message.channel.send("Unknown command.")
}
if (haveMatched){
    console.log(`[Command] ${message.author.id}/${message.author.username} (${message.content})`)
}
})
<|endoftext|>


<commit_before>if (!process.env.token) {
    console.log('Error: Specify token in environment');
    process.exit(1);
}

var Botkit = require('botkit');
var os = require('os');

var controller = Botkit.slackbot({
    debug: true,
});

var bot = controller.spawn({
    token: process.env.token
}).startRTM();

controller.hears(['hello', 'hi'], 'direct_message,direct_mention,mention', function(bot, message) {

    bot.api.reactions.add({
        timestamp: message.ts,
        channel: message.channel,
        name: 'robot_face',
    }, function(err, res) {
        if (err) {
            bot.botkit.log('Failed to add emoji reaction :(', err);
        }
    });

    controller.storage.users.get(message.user, function(err, user) {
        if (user && user.name) {
            bot.reply(message, 'Hello ' + user.name + '!!');
        } else {
            bot.reply(message, 'Hello.');
        }
    });
});
<commit_msg>implements main logic<commit_after>if (!process.env.token) {
    console.log('Error: Specify token in environment');
    process.exit(1);
}

var Botkit = require('botkit');
let capture = require('./lib/NightmareCapture')
let fs = require('fs')

var controller = Botkit.slackbot({
    debug: false,
});

var bot = controller.spawn({
    token: process.env.token
}).startRTM();

controller.hears(['capture <(https?://.*)>'], 'direct_message,direct_mention,mention', function(bot, message) {

    // reaction robot face
    bot.api.reactions.add({
        timestamp: message.ts,
        channel: message.channel,
        name: 'robot_face',
    }, function(err, res) {
        if (err) {
            bot.botkit.log('Failed to add emoji reaction :(', err);
        }
    });

    // url extract
    let url = message.match[1] + ''

    let callback = () => {
      const messageObj = {
        file: fs.createReadStream('./screenshot.png'),
        filename: 'screenshot.png',
        title: 'screenshot.png',
        channels: message.channel
      };

      // post screenshot.png to slack
      bot.api.files.upload(messageObj, function(err, res){
        if(err){
            console.log(err);
        }
      });

      // remove screenshot.png
      fs.unlink('./screenshot.png', function (err) {
        if (err) throw err;
        console.log('successfully deleted');
      });

      // reaction check mark
      bot.api.reactions.add({
          timestamp: message.ts,
          channel: message.channel,
          name: 'heavy_check_mark',
      }, function(err, res) {
          if (err) {
              bot.botkit.log('Failed to add emoji reaction :(', err);
          }
      });
    }
    capture(url, callback)

});
<|endoftext|>