<commit_before>/* eslint-disable no-restricted-syntax, no-invalid-this */
'use strict';

// MODULES //

var setReadOnly = require( '@stdlib/utils/define-read-only-property' );
var isPositive = require( '@stdlib/assert/is-positive-number').isPrimitive;
var entropy = require( '@stdlib/math/base/dist/chi/entropy' );
var kurtosis = require( '@stdlib/math/base/dist/chi/kurtosis' );
var mean = require( '@stdlib/math/base/dist/chi/mean' );
var mode = require( '@stdlib/math/base/dist/chi/mode' );
var skewness = require( '@stdlib/math/base/dist/chi/skewness' );
var variance = require( '@stdlib/math/base/dist/chi/variance' );
var cdf = require( '@stdlib/math/base/dist/chi/cdf' );
var pdf = require( '@stdlib/math/base/dist/chi/pdf' );
var quantile = require( '@stdlib/math/base/dist/chi/quantile' );

// FUNCTIONS //

/**
* Evaluates the cumulative distribution function (CDF).
*
* @private
* @param {number} x - input value
* @returns {number} evaluated CDF
*/
function chiCDF( x ) {
	return cdf( x, this.k );
} // end FUNCTION chiCDF()

/**
* Evaluates the probability density function (PDF).
*
* @private
* @param {number} x - input value
* @returns {number} evaluated PDF
*/
function chiPDF( x ) {
	return pdf( x, this.k );
} // end FUNCTION chiPDF()

/**
* Evaluates the quantile function.
*
* @private
* @param {Probability} p - input probability
* @returns {number} evaluated quantile function
*/
function chiQuantile( p ) {
	return quantile( p, this.k );
} // end FUNCTION chiQuantile()

// MAIN //

/**
* Chi distribution constructor.
*
* @constructor
* @param {PositiveNumber} [k=1.0] - degrees of freedom
* @throws {TypeError} `k` must be a positive number
* @returns {Chi} distribution instance
*
* @example
* var chi = new Chi( 1.0 );
*
* var y = chi.cdf( 0.8 );
* // returns ~0.576
*
* var mode = chi.mode;
* // returns 0.0
*/
function Chi() {
	var k;
	if ( !(this instanceof Chi) ) {
		if ( arguments.length === 0 ) {
			return new Chi();
		}
		return new Chi( arguments[ 0 ] );
	}
	if ( arguments.length ) {
		k = arguments[ 0 ];
		if ( !isPositive( k ) ) {
			throw new TypeError( 'invalid input argument. Rate parameter `k` must be a positive number. Value: `' + k + '`' );
		}
	} else {
		k = 1.0;
	}
	Object.defineProperty( this, 'k', {
		'configurable': false,
		'enumerable': true,
		'get': function get() {
			return k;
		},
		'set': function set( value ) {
			if ( !isPositive( value ) ) {
				throw new TypeError( 'invalid value. Must be a positive number. Value: `' + value + '`' );
			}
			k = value;
		}
	});
	return this;
} // end FUNCTION Chi()

/**
* Chi distribution differential entropy.
*
* @memberof Chi.prototype
* @name entropy
* @type {number}
* @see [differential entropy]{@link https://en.wikipedia.org/wiki/Entropy_%28information_theory%29}
*
* @example
* var chi = new Chi( 4.0 );
*
* var v = chi.entropy;
* // returns ~1.019
*/
Object.defineProperty( Chi.prototype, 'entropy', {
	'configurable': false,
	'enumerable': true,
	'get': function get() {
		return entropy( this.k );
	}
});

/**
* Chi distribution excess kurtosis.
*
* @memberof Chi.prototype
* @name kurtosis
* @type {number}
* @see [kurtosis]{@link https://en.wikipedia.org/wiki/Kurtosis}
*
* @example
* var chi = new Chi( 4.0 );
*
* var v = chi.kurtosis;
* // returns ~0.059
*/
Object.defineProperty( Chi.prototype, 'kurtosis', {
	'configurable': false,
	'enumerable': true,
	'get': function get() {
		return kurtosis( this.k );
	}
});

/**
* Chi distribution expected value.
*
* @memberof Chi.prototype
* @name mean
* @type {number}
* @see [expected value]{@link https://en.wikipedia.org/wiki/Expected_value}
*
* @example
* var chi = new Chi( 4.0 );
*
* var v = chi.mean;
* // returns ~1.88
*/
Object.defineProperty( Chi.prototype, 'mean', {
	'configurable': false,
	'enumerable': true,
	'get': function get() {
		return mean( this.k );
	}
});

/**
* Chi distribution mode.
*
* @memberof Chi.prototype
* @name mode
* @type {number}
* @see [mode]{@link https://en.wikipedia.org/wiki/Mode_%28statistics%29}
*
* @example
* var chi = new Chi( 4.0 );
*
* var v = chi.mode;
* // returns ~1.732
*/
Object.defineProperty( Chi.prototype, 'mode', {
	'configurable': false,
	'enumerable': true,
	'get': function get() {
		return mode( this.k );
	}
});

/**
* Chi distribution skewness.
*
* @memberof Chi.prototype
* @name skewness
* @type {number}
* @see [skewness]{@link https://en.wikipedia.org/wiki/Skewness}
*
* @example
* var chi = new Chi( 4.0 );
*
* var v = chi.skewness;
* // returns ~0.406
*/
Object.defineProperty( Chi.prototype, 'skewness', {
	'configurable': false,
	'enumerable': true,
	'get': function get() {
		return skewness( this.k );
	}
});

/**
* Chi distribution variance.
*
* @memberof Chi.prototype
* @name variance
* @type {number}
* @see [variance]{@link https://en.wikipedia.org/wiki/Variance}
*
* @example
* var chi = new Chi( 4.0 );
*
* var v = chi.variance;
* // returns ~0.466
*/
Object.defineProperty( Chi.prototype, 'variance', {
	'configurable': false,
	'enumerable': true,
	'get': function get() {
		return variance( this.k );
	}
});

/**
* Evaluates the cumulative distribution function (CDF).
*
* @memberof Chi.prototype
* @name cdf
* @type {Function}
* @param {number} x - input value
* @returns {number} evaluated CDF
* @see [cdf]{@link https://en.wikipedia.org/wiki/Cumulative_distribution_function}
*
* @example
* var chi = new Chi( 2.0 );
*
* var v = chi.cdf( 0.5 );
* // returns ~0.118
*/
setReadOnly( Chi.prototype, 'cdf', chiCDF );

/**
* Evaluates the probability density function (PDF).
*
* @memberof Chi.prototype
* @name pdf
* @type {Function}
* @param {number} x - input value
* @returns {number} evaluated PDF
* @see [pdf]{@link https://en.wikipedia.org/wiki/Probability_density_function}
*
* @example
* var chi = new Ch	i( 2.0 );
*
* var v = chi.pdf( 0.8 );
* // returns ~0.441
*/
setReadOnly( Chi.prototype, 'pdf', chiPDF );

/**
* Evaluates the quantile function.
*
* @memberof Chi.prototype
* @name quantile
* @type {Function}
* @param {Probability} p - input probability
* @returns {number} evaluated quantile function
* @see [quantile function]{@link https://en.wikipedia.org/wiki/Quantile_function}
*
* @example
* var chi = new Chi( 2.0 );
*
* var v = chi.quantile( 0.5 );
* // returns ~1.177
*/
setReadOnly( Chi.prototype, 'quantile', chiQuantile );

// EXPORTS //

module.exports = Chi;
<commit_msg>Remove wrongly places tab<commit_after>/* eslint-disable no-restricted-syntax, no-invalid-this */
'use strict';

// MODULES //

var setReadOnly = require( '@stdlib/utils/define-read-only-property' );
var isPositive = require( '@stdlib/assert/is-positive-number').isPrimitive;
var entropy = require( '@stdlib/math/base/dist/chi/entropy' );
var kurtosis = require( '@stdlib/math/base/dist/chi/kurtosis' );
var mean = require( '@stdlib/math/base/dist/chi/mean' );
var mode = require( '@stdlib/math/base/dist/chi/mode' );
var skewness = require( '@stdlib/math/base/dist/chi/skewness' );
var variance = require( '@stdlib/math/base/dist/chi/variance' );
var cdf = require( '@stdlib/math/base/dist/chi/cdf' );
var pdf = require( '@stdlib/math/base/dist/chi/pdf' );
var quantile = require( '@stdlib/math/base/dist/chi/quantile' );

// FUNCTIONS //

/**
* Evaluates the cumulative distribution function (CDF).
*
* @private
* @param {number} x - input value
* @returns {number} evaluated CDF
*/
function chiCDF( x ) {
	return cdf( x, this.k );
} // end FUNCTION chiCDF()

/**
* Evaluates the probability density function (PDF).
*
* @private
* @param {number} x - input value
* @returns {number} evaluated PDF
*/
function chiPDF( x ) {
	return pdf( x, this.k );
} // end FUNCTION chiPDF()

/**
* Evaluates the quantile function.
*
* @private
* @param {Probability} p - input probability
* @returns {number} evaluated quantile function
*/
function chiQuantile( p ) {
	return quantile( p, this.k );
} // end FUNCTION chiQuantile()

// MAIN //

/**
* Chi distribution constructor.
*
* @constructor
* @param {PositiveNumber} [k=1.0] - degrees of freedom
* @throws {TypeError} `k` must be a positive number
* @returns {Chi} distribution instance
*
* @example
* var chi = new Chi( 1.0 );
*
* var y = chi.cdf( 0.8 );
* // returns ~0.576
*
* var mode = chi.mode;
* // returns 0.0
*/
function Chi() {
	var k;
	if ( !(this instanceof Chi) ) {
		if ( arguments.length === 0 ) {
			return new Chi();
		}
		return new Chi( arguments[ 0 ] );
	}
	if ( arguments.length ) {
		k = arguments[ 0 ];
		if ( !isPositive( k ) ) {
			throw new TypeError( 'invalid input argument. Rate parameter `k` must be a positive number. Value: `' + k + '`' );
		}
	} else {
		k = 1.0;
	}
	Object.defineProperty( this, 'k', {
		'configurable': false,
		'enumerable': true,
		'get': function get() {
			return k;
		},
		'set': function set( value ) {
			if ( !isPositive( value ) ) {
				throw new TypeError( 'invalid value. Must be a positive number. Value: `' + value + '`' );
			}
			k = value;
		}
	});
	return this;
} // end FUNCTION Chi()

/**
* Chi distribution differential entropy.
*
* @memberof Chi.prototype
* @name entropy
* @type {number}
* @see [differential entropy]{@link https://en.wikipedia.org/wiki/Entropy_%28information_theory%29}
*
* @example
* var chi = new Chi( 4.0 );
*
* var v = chi.entropy;
* // returns ~1.019
*/
Object.defineProperty( Chi.prototype, 'entropy', {
	'configurable': false,
	'enumerable': true,
	'get': function get() {
		return entropy( this.k );
	}
});

/**
* Chi distribution excess kurtosis.
*
* @memberof Chi.prototype
* @name kurtosis
* @type {number}
* @see [kurtosis]{@link https://en.wikipedia.org/wiki/Kurtosis}
*
* @example
* var chi = new Chi( 4.0 );
*
* var v = chi.kurtosis;
* // returns ~0.059
*/
Object.defineProperty( Chi.prototype, 'kurtosis', {
	'configurable': false,
	'enumerable': true,
	'get': function get() {
		return kurtosis( this.k );
	}
});

/**
* Chi distribution expected value.
*
* @memberof Chi.prototype
* @name mean
* @type {number}
* @see [expected value]{@link https://en.wikipedia.org/wiki/Expected_value}
*
* @example
* var chi = new Chi( 4.0 );
*
* var v = chi.mean;
* // returns ~1.88
*/
Object.defineProperty( Chi.prototype, 'mean', {
	'configurable': false,
	'enumerable': true,
	'get': function get() {
		return mean( this.k );
	}
});

/**
* Chi distribution mode.
*
* @memberof Chi.prototype
* @name mode
* @type {number}
* @see [mode]{@link https://en.wikipedia.org/wiki/Mode_%28statistics%29}
*
* @example
* var chi = new Chi( 4.0 );
*
* var v = chi.mode;
* // returns ~1.732
*/
Object.defineProperty( Chi.prototype, 'mode', {
	'configurable': false,
	'enumerable': true,
	'get': function get() {
		return mode( this.k );
	}
});

/**
* Chi distribution skewness.
*
* @memberof Chi.prototype
* @name skewness
* @type {number}
* @see [skewness]{@link https://en.wikipedia.org/wiki/Skewness}
*
* @example
* var chi = new Chi( 4.0 );
*
* var v = chi.skewness;
* // returns ~0.406
*/
Object.defineProperty( Chi.prototype, 'skewness', {
	'configurable': false,
	'enumerable': true,
	'get': function get() {
		return skewness( this.k );
	}
});

/**
* Chi distribution variance.
*
* @memberof Chi.prototype
* @name variance
* @type {number}
* @see [variance]{@link https://en.wikipedia.org/wiki/Variance}
*
* @example
* var chi = new Chi( 4.0 );
*
* var v = chi.variance;
* // returns ~0.466
*/
Object.defineProperty( Chi.prototype, 'variance', {
	'configurable': false,
	'enumerable': true,
	'get': function get() {
		return variance( this.k );
	}
});

/**
* Evaluates the cumulative distribution function (CDF).
*
* @memberof Chi.prototype
* @name cdf
* @type {Function}
* @param {number} x - input value
* @returns {number} evaluated CDF
* @see [cdf]{@link https://en.wikipedia.org/wiki/Cumulative_distribution_function}
*
* @example
* var chi = new Chi( 2.0 );
*
* var v = chi.cdf( 0.5 );
* // returns ~0.118
*/
setReadOnly( Chi.prototype, 'cdf', chiCDF );

/**
* Evaluates the probability density function (PDF).
*
* @memberof Chi.prototype
* @name pdf
* @type {Function}
* @param {number} x - input value
* @returns {number} evaluated PDF
* @see [pdf]{@link https://en.wikipedia.org/wiki/Probability_density_function}
*
* @example
* var chi = new Chi( 2.0 );
*
* var v = chi.pdf( 0.8 );
* // returns ~0.441
*/
setReadOnly( Chi.prototype, 'pdf', chiPDF );

/**
* Evaluates the quantile function.
*
* @memberof Chi.prototype
* @name quantile
* @type {Function}
* @param {Probability} p - input probability
* @returns {number} evaluated quantile function
* @see [quantile function]{@link https://en.wikipedia.org/wiki/Quantile_function}
*
* @example
* var chi = new Chi( 2.0 );
*
* var v = chi.quantile( 0.5 );
* // returns ~1.177
*/
setReadOnly( Chi.prototype, 'quantile', chiQuantile );

// EXPORTS //

module.exports = Chi;
<|endoftext|>


<commit_before>var XWiki = (function (XWiki) {
// Start XWiki augmentation.
var widgets = XWiki.widgets = XWiki.widgets || {};
/**
 * A general purpose notification class, displaying a simple message for the user, at the bottom of the screen.
 * Features:
 *

 *
Several default aspects: <tt>plain</tt>, <tt>info</tt>, <tt>warning</tt>, <tt>error</tt>, <tt>inprogress</tt>,
 *  <tt>done</tt>.

 *
Stacking of multiple notifications on the screen.

 *
Possibility to replace a notification with another one, preserving the position.

 *
Automatic hide after a configurable period of time.

 *
Configurable icon, background and text color.

 *

 * To display a notification, it suffices to create a new XWiki.widgets.Notification object. Constructor parameters:
 *

 *
text

 *
The notification text

 *
type (optional)

 *
The notification type, one of <tt>plain</tt>, <tt>info</tt>, <tt>warning</tt>, <tt>error</tt>, <tt>inprogress</tt>,
 *    <tt>done</tt>. If an unknown or no type is passed, <tt>plain</tt> is used by default.

 *
options (optional)

 *
Additional configuration; supported options:
 *

 *
<tt>timeout</tt>: number of seconds to keep the notification on the screen. Use 0 or false to keep it until manually removed.

 *
<tt>inactive</tt>: don't show the notification when the object is created, manually call {@link #show} later

 *
<tt>icon</tt>: a custom image to use

 *
<tt>color</tt>: a custom color for the text

 *
<tt>backgroundColor</tt>: a custom color for the background

 *

 *

 *

 * Default parameters for the predefined notification types:
 *

 *
plain

 *
timeout: 5

 *
icon: none

 *
color: black

 *
background: #EEE

 *
info

 *
timeout: 5

 *
icon: (i)

 *
color: #28C

 *
background: #DDF

 *
warning

 *
timeout: 5

 *
icon: /!\

 *
color: 000

 *
background: #FFD

 *
error

 *
timeout: 10

 *
icon: (!)

 *
color: #900

 *
background: #EDD

 *
inprogress

 *
timeout: false

 *
icon: spinning

 *
color: #268

 *
background: #EEE

 *
done

 *
timeout: 2

 *
icon: (v)

 *
color: #090

 *
background: #EFD

 *

 */
widgets.Notification = Class.create({
  text : "Hello world!",
  defaultOptions : {
    /** supported types: plain, info, warning, error, inprogress, done */
    "plain"      : {timeout : 5},
    "info"       : {timeout : 5},
    "warning"    : {timeout : 5},
    "error"      : {timeout : 10},
    "inprogress" : {timeout : false},
    "done"       : {timeout : 2}
  },
  initialize : function(text, type, options) {
    this.text = text || this.text;
    this.type = (typeof this.defaultOptions[type] != "undefined") ? type : "plain";
    this.options = Object.extend(Object.clone(this.defaultOptions[this.type]), options || { });
    this.createElement();
    if (!this.options.inactive) {
      this.show();
    }
  },
  /** Creates the HTML structure for the notification. */
  createElement : function() {
    if (!this.element) {
      this.element = new Element("div", {"class" : "xnotification xnotification-" + this.type}).update(this.text);
      if (this.options.icon) {
        this.element.setStyle({backgroundImage : this.options.icon, paddingLeft : "22px"});
      }
      if (this.options.backgroundColor) {
        this.element.setStyle({backgroundColor : this.options.backgroundColor});
      }
      if (this.options.color) {
        this.element.setStyle({color : this.options.color});
      }
      this.element = this.element.wrap(new Element("div", {"class" : "xnotification-wrapper"}));
      Event.observe(this.element, "click", this.hide.bindAsEventListener(this));
    }
  },
  /** Display the notification and schedule an automatic hide after the configured period of time, if any. */
  show : function() {
    if (!this.element.descendantOf(widgets.Notification.getContainer())) {
      widgets.Notification.getContainer().insert({top: this.element});
    }
    this.element.show();
    if (this.options.timeout) {
      this.timer = window.setTimeout(this.hide.bind(this), this.options.timeout * 1000);
    }
  },
  /** Hide the notification. */
  hide : function() {
    this.element.hide();
    if (this.element.parentNode) {
      this.element.remove();
    }
    if (this.timer) {
      window.clearTimeout(this.timer);
      this.timer = null;
    }
  },
  /** Silently replace this notification with another one, keeping the same place. */
  replace : function(notification) {
    if (this.element.parentNode) {
      this.element.replace(notification.element);
    }
    if (this.timer) {
      window.clearTimeout(this.timer);
      this.timer = null;
    }
    notification.show();
  }
});

/** The container for all the notifications. */
widgets.Notification.container = null;

/** Returns the container for all the notifications. The container is created the first time this function is called. */
widgets.Notification.getContainer = function() {
  if (!widgets.Notification.container) {
    widgets.Notification.container = new Element('div', {"class" : "xnotification-container"});
    // Insert the container in the document body.
    $('body').insert(widgets.Notification.container);
  }
  return widgets.Notification.container;
};

// End XWiki augmentation.
return XWiki;
}(XWiki || {}));
<commit_msg>XWIKI-8697: Notification widget should have a callback function that gets called when the notification hides Done.<commit_after>var XWiki = (function (XWiki) {
// Start XWiki augmentation.
var widgets = XWiki.widgets = XWiki.widgets || {};
/**
 * A general purpose notification class, displaying a simple message for the user, at the bottom of the screen.
 * Features:
 *

 *
Several default aspects: <tt>plain</tt>, <tt>info</tt>, <tt>warning</tt>, <tt>error</tt>, <tt>inprogress</tt>,
 *  <tt>done</tt>.

 *
Stacking of multiple notifications on the screen.

 *
Possibility to replace a notification with another one, preserving the position.

 *
Automatic hide after a configurable period of time.

 *
 After hiding, call the function specified in the options.

 *
Configurable icon, background and text color.

 *

 * To display a notification, it suffices to create a new XWiki.widgets.Notification object. Constructor parameters:
 *

 *
text

 *
The notification text

 *
type (optional)

 *
The notification type, one of <tt>plain</tt>, <tt>info</tt>, <tt>warning</tt>, <tt>error</tt>, <tt>inprogress</tt>,
 *    <tt>done</tt>. If an unknown or no type is passed, <tt>plain</tt> is used by default.

 *
options (optional)

 *
Additional configuration; supported options:
 *

 *
<tt>timeout</tt>: number of seconds to keep the notification on the screen. Use 0 or false to keep it until manually removed.

 *
<tt>inactive</tt>: don't show the notification when the object is created, manually call {@link #show} later

 *
<tt>icon</tt>: a custom image to use

 *
<tt>color</tt>: a custom color for the text

 *
<tt>backgroundColor</tt>: a custom color for the background

 *

 *

 *

 * Default parameters for the predefined notification types:
 *

 *
plain

 *
timeout: 5

 *
icon: none

 *
color: black

 *
background: #EEE

 *
info

 *
timeout: 5

 *
icon: (i)

 *
color: #28C

 *
background: #DDF

 *
warning

 *
timeout: 5

 *
icon: /!\

 *
color: 000

 *
background: #FFD

 *
error

 *
timeout: 10

 *
icon: (!)

 *
color: #900

 *
background: #EDD

 *
inprogress

 *
timeout: false

 *
icon: spinning

 *
color: #268

 *
background: #EEE

 *
done

 *
timeout: 2

 *
icon: (v)

 *
color: #090

 *
background: #EFD

 *

 */
widgets.Notification = Class.create({
  text : "Hello world!",
  defaultOptions : {
    /** supported types: plain, info, warning, error, inprogress, done */
    "plain"      : {timeout : 5},
    "info"       : {timeout : 5},
    "warning"    : {timeout : 5},
    "error"      : {timeout : 10},
    "inprogress" : {timeout : false},
    "done"       : {timeout : 2}
  },
  initialize : function(text, type, options) {
    this.text = text || this.text;
    this.type = (typeof this.defaultOptions[type] != "undefined") ? type : "plain";
    this.options = Object.extend(Object.clone(this.defaultOptions[this.type]), options || { });
    this.createElement();
    if (!this.options.inactive) {
      this.show();
    }
  },
  /** Creates the HTML structure for the notification. */
  createElement : function() {
    if (!this.element) {
      this.element = new Element("div", {"class" : "xnotification xnotification-" + this.type}).update(this.text);
      if (this.options.icon) {
        this.element.setStyle({backgroundImage : this.options.icon, paddingLeft : "22px"});
      }
      if (this.options.backgroundColor) {
        this.element.setStyle({backgroundColor : this.options.backgroundColor});
      }
      if (this.options.color) {
        this.element.setStyle({color : this.options.color});
      }
      this.element = this.element.wrap(new Element("div", {"class" : "xnotification-wrapper"}));
      Event.observe(this.element, "click", this.hide.bindAsEventListener(this));
    }
  },
  /** Display the notification and schedule an automatic hide after the configured period of time, if any. */
  show : function() {
    if (!this.element.descendantOf(widgets.Notification.getContainer())) {
      widgets.Notification.getContainer().insert({top: this.element});
    }
    this.element.show();
    if (this.options.timeout) {
      this.timer = window.setTimeout(this.hide.bind(this), this.options.timeout * 1000);
    }
  },
  /** Hide the notification. */
  hide : function() {
    this.element.hide();
    if (this.element.parentNode) {
      this.element.remove();
    }
    if (this.timer) {
      window.clearTimeout(this.timer);
      this.timer = null;
    }
    (typeof this.options.onHide == 'function') && this.options.onHide();
  },
  /** Silently replace this notification with another one, keeping the same place. */
  replace : function(notification) {
    if (this.element.parentNode) {
      this.element.replace(notification.element);
    }
    if (this.timer) {
      window.clearTimeout(this.timer);
      this.timer = null;
    }
    notification.show();
  }
});

/** The container for all the notifications. */
widgets.Notification.container = null;

/** Returns the container for all the notifications. The container is created the first time this function is called. */
widgets.Notification.getContainer = function() {
  if (!widgets.Notification.container) {
    widgets.Notification.container = new Element('div', {"class" : "xnotification-container"});
    // Insert the container in the document body.
    $('body').insert(widgets.Notification.container);
  }
  return widgets.Notification.container;
};

// End XWiki augmentation.
return XWiki;
}(XWiki || {}));
<|endoftext|>


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

    function EditorContentHeader(serverValidationManager) {

        function link(scope, el, attr, ctrl) {

            var unsubscribe = [];

            if (!scope.serverValidationNameField) {
                scope.serverValidationNameField = "Name";
            }
            if (!scope.serverValidationAliasField) {
                scope.serverValidationAliasField = "Alias";
            }

            scope.vm = {};
            scope.vm.dropdownOpen = false;
            scope.vm.currentVariant = "";
            scope.vm.variantsWithError = [];
            scope.vm.defaultVariant = null;

            scope.vm.errorsOnOtherVariants = false;// maintained variable, indicating wether to show that other variants than the current has errors.

            function checkErrorsOnOtherVariants() {
                var check = false;
                angular.forEach(scope.content.variants, function (variant) {
                    if (scope.openVariants.indexOf(variant.language.culture) === -1 && scope.variantHasError(variant.language.culture)) {
                        check = true;
                    }
                });
                scope.vm.errorsOnOtherVariants = check;
            }

            function onCultureValidation(valid, errors, allErrors, culture) {
                var index = scope.vm.variantsWithError.indexOf(culture);
                if(valid === true) {
                    if (index !== -1) {
                        scope.vm.variantsWithError.splice(index, 1);
                    }
                } else {
                    if (index === -1) {
                        scope.vm.variantsWithError.push(culture);
                    }
                }
                checkErrorsOnOtherVariants();
            }

            function onInit() {

                // find default.
                angular.forEach(scope.content.variants, function (variant) {
                    if (variant.language.isDefault) {
                        scope.vm.defaultVariant = variant;
                    }
                });

                setCurrentVariant();

                angular.forEach(scope.content.apps, (app) => {
                    if (app.alias === "umbContent") {
                        app.anchors = scope.content.tabs;
                    }
                });

                angular.forEach(scope.content.variants, function (variant) {
                    unsubscribe.push(serverValidationManager.subscribe(null, variant.language.culture, null, onCultureValidation));
                });

                unsubscribe.push(serverValidationManager.subscribe(null, null, null, onCultureValidation));

            }

            function setCurrentVariant() {
                angular.forEach(scope.content.variants, function (variant) {
                    if (variant.active) {
                        scope.vm.currentVariant = variant;
                        checkErrorsOnOtherVariants();
                    }
                });
            }

            scope.goBack = function () {
                if (scope.onBack) {
                    scope.onBack();
                }
            };

            scope.selectVariant = function (event, variant) {

                if (scope.onSelectVariant) {
                    scope.vm.dropdownOpen = false;
                    scope.onSelectVariant({ "variant": variant });
                }
            };

            scope.selectNavigationItem = function(item) {
                if(scope.onSelectNavigationItem) {
                    scope.onSelectNavigationItem({"item": item});
                }
            }

            scope.selectAnchorItem = function(item, anchor) {
                if(scope.onSelectAnchorItem) {
                    scope.onSelectAnchorItem({"item": item, "anchor": anchor});
                }
            }

            scope.closeSplitView = function () {
                if (scope.onCloseSplitView) {
                    scope.onCloseSplitView();
                }
            };

            scope.openInSplitView = function (event, variant) {
                if (scope.onOpenInSplitView) {
                    scope.vm.dropdownOpen = false;
                    scope.onOpenInSplitView({ "variant": variant });
                }
            };

            /**
             * keep track of open variants - this is used to prevent the same variant to be open in more than one split view
             * @param {any} culture
             */
            scope.variantIsOpen = function(culture) {
                return (scope.openVariants.indexOf(culture) !== -1);
            }

            /**
             * Check whether a variant has a error, used to display errors in variant switcher.
             * @param {any} culture
             */
            scope.variantHasError = function(culture) {
                // if we are looking for the default language we also want to check for invariant (null)
                if (culture === scope.vm.defaultVariant.language.culture) {
                    if(scope.vm.variantsWithError.indexOf(null) !== -1) {
                        return true;
                    }
                }
                if(scope.vm.variantsWithError.indexOf(culture) !== -1) {
                    return true;
                }
                return false;
            }

            onInit();

            //watch for the active culture changing, if it changes, update the current variant
            if (scope.content.variants) {
                scope.$watch(function () {
                    for (var i = 0; i < scope.content.variants.length; i++) {
                        var v = scope.content.variants[i];
                        if (v.active) {
                            return v.language.culture;
                        }
                    }
                    return scope.vm.currentVariant.language.culture; //should never get here
                }, function (newValue, oldValue) {
                    if (newValue !== scope.vm.currentVariant.language.culture) {
                        setCurrentVariant();
                    }
                });
            }

            scope.$on('$destroy', function () {
                for (var u in unsubscribe) {
                    unsubscribe[u]();
                }
            });
        }

        var directive = {
            transclude: true,
            restrict: 'E',
            replace: true,
            templateUrl: 'views/components/editor/umb-editor-content-header.html',
            scope: {
                name: "=",
                nameDisabled: "<?",
                menu: "=",
                hideActionsMenu: "<?",
                content: "=",
                openVariants: "<",
                hideChangeVariant: "<?",
                onSelectNavigationItem: "&?",
                onSelectAnchorItem: "&?",
                showBackButton: "<?",
                onBack: "&?",
                splitViewOpen: "=?",
                onOpenInSplitView: "&?",
                onCloseSplitView: "&?",
                onSelectVariant: "&?",
                serverValidationNameField: "@?",
                serverValidationAliasField: "@?"
            },
            link: link
        };

        return directive;
    }

    angular.module('umbraco.directives').directive('umbEditorContentHeader', EditorContentHeader);

})();
<commit_msg>fix comment<commit_after>(function () {
    'use strict';

    function EditorContentHeader(serverValidationManager) {

        function link(scope, el, attr, ctrl) {

            var unsubscribe = [];

            if (!scope.serverValidationNameField) {
                scope.serverValidationNameField = "Name";
            }
            if (!scope.serverValidationAliasField) {
                scope.serverValidationAliasField = "Alias";
            }

            scope.vm = {};
            scope.vm.dropdownOpen = false;
            scope.vm.currentVariant = "";
            scope.vm.variantsWithError = [];
            scope.vm.defaultVariant = null;

            scope.vm.errorsOnOtherVariants = false;// indicating wether to show that other variants, than the current, have errors.

            function checkErrorsOnOtherVariants() {
                var check = false;
                angular.forEach(scope.content.variants, function (variant) {
                    if (scope.openVariants.indexOf(variant.language.culture) === -1 && scope.variantHasError(variant.language.culture)) {
                        check = true;
                    }
                });
                scope.vm.errorsOnOtherVariants = check;
            }

            function onCultureValidation(valid, errors, allErrors, culture) {
                var index = scope.vm.variantsWithError.indexOf(culture);
                if(valid === true) {
                    if (index !== -1) {
                        scope.vm.variantsWithError.splice(index, 1);
                    }
                } else {
                    if (index === -1) {
                        scope.vm.variantsWithError.push(culture);
                    }
                }
                checkErrorsOnOtherVariants();
            }

            function onInit() {

                // find default.
                angular.forEach(scope.content.variants, function (variant) {
                    if (variant.language.isDefault) {
                        scope.vm.defaultVariant = variant;
                    }
                });

                setCurrentVariant();

                angular.forEach(scope.content.apps, (app) => {
                    if (app.alias === "umbContent") {
                        app.anchors = scope.content.tabs;
                    }
                });

                angular.forEach(scope.content.variants, function (variant) {
                    unsubscribe.push(serverValidationManager.subscribe(null, variant.language.culture, null, onCultureValidation));
                });

                unsubscribe.push(serverValidationManager.subscribe(null, null, null, onCultureValidation));

            }

            function setCurrentVariant() {
                angular.forEach(scope.content.variants, function (variant) {
                    if (variant.active) {
                        scope.vm.currentVariant = variant;
                        checkErrorsOnOtherVariants();
                    }
                });
            }

            scope.goBack = function () {
                if (scope.onBack) {
                    scope.onBack();
                }
            };

            scope.selectVariant = function (event, variant) {

                if (scope.onSelectVariant) {
                    scope.vm.dropdownOpen = false;
                    scope.onSelectVariant({ "variant": variant });
                }
            };

            scope.selectNavigationItem = function(item) {
                if(scope.onSelectNavigationItem) {
                    scope.onSelectNavigationItem({"item": item});
                }
            }

            scope.selectAnchorItem = function(item, anchor) {
                if(scope.onSelectAnchorItem) {
                    scope.onSelectAnchorItem({"item": item, "anchor": anchor});
                }
            }

            scope.closeSplitView = function () {
                if (scope.onCloseSplitView) {
                    scope.onCloseSplitView();
                }
            };

            scope.openInSplitView = function (event, variant) {
                if (scope.onOpenInSplitView) {
                    scope.vm.dropdownOpen = false;
                    scope.onOpenInSplitView({ "variant": variant });
                }
            };

            /**
             * keep track of open variants - this is used to prevent the same variant to be open in more than one split view
             * @param {any} culture
             */
            scope.variantIsOpen = function(culture) {
                return (scope.openVariants.indexOf(culture) !== -1);
            }

            /**
             * Check whether a variant has a error, used to display errors in variant switcher.
             * @param {any} culture
             */
            scope.variantHasError = function(culture) {
                // if we are looking for the default language we also want to check for invariant (null)
                if (culture === scope.vm.defaultVariant.language.culture) {
                    if(scope.vm.variantsWithError.indexOf(null) !== -1) {
                        return true;
                    }
                }
                if(scope.vm.variantsWithError.indexOf(culture) !== -1) {
                    return true;
                }
                return false;
            }

            onInit();

            //watch for the active culture changing, if it changes, update the current variant
            if (scope.content.variants) {
                scope.$watch(function () {
                    for (var i = 0; i < scope.content.variants.length; i++) {
                        var v = scope.content.variants[i];
                        if (v.active) {
                            return v.language.culture;
                        }
                    }
                    return scope.vm.currentVariant.language.culture; //should never get here
                }, function (newValue, oldValue) {
                    if (newValue !== scope.vm.currentVariant.language.culture) {
                        setCurrentVariant();
                    }
                });
            }

            scope.$on('$destroy', function () {
                for (var u in unsubscribe) {
                    unsubscribe[u]();
                }
            });
        }

        var directive = {
            transclude: true,
            restrict: 'E',
            replace: true,
            templateUrl: 'views/components/editor/umb-editor-content-header.html',
            scope: {
                name: "=",
                nameDisabled: "<?",
                menu: "=",
                hideActionsMenu: "<?",
                content: "=",
                openVariants: "<",
                hideChangeVariant: "<?",
                onSelectNavigationItem: "&?",
                onSelectAnchorItem: "&?",
                showBackButton: "<?",
                onBack: "&?",
                splitViewOpen: "=?",
                onOpenInSplitView: "&?",
                onCloseSplitView: "&?",
                onSelectVariant: "&?",
                serverValidationNameField: "@?",
                serverValidationAliasField: "@?"
            },
            link: link
        };

        return directive;
    }

    angular.module('umbraco.directives').directive('umbEditorContentHeader', EditorContentHeader);

})();
<|endoftext|>


<commit_before>'use strict';

// MODULES //

var isnan = require( '@stdlib/math/base/assert/is-nan' );
var cospi = require( '@stdlib/math/base/special/cospi' );
var pow = require( '@stdlib/math/base/special/pow' );
var PHI = require( '@stdlib/constants/math/float64-phi' );
var PINF = require( '@stdlib/constants/math/float64-pinf' );
var NINF = require( '@stdlib/constants/math/float64-ninf' );

// VARIABLES //

var SQRT_5 = 2.23606797749979;

// MAIN //

/**
* Evaluates Binet's formula extended to real numbers.
*
* ## Notes
*
* * [Non integer Fibonacci numbers]{@link https://math.stackexchange.com/questions/798190/non-integer-fibonacci-numbers}
* * [Interpolated Fibonacci numbers - real or complex]{@link https://math.stackexchange.com/questions/589841/interpolated-fibonacci-numbers-real-or-complex}
*
*
* @param {number} x - input value
* @returns {number} real-valued result
*
* @example
* var y = binet( 0.0 );
* // returns 0.0
*
* @example
* var y = binet( 1.0 );
* // returns 1.0
*
* @example
* var y = binet( 2.0 );
* // returns 1.0
*
* @example
* var y = binet( 3.0 );
* // returns 2.0
*
* @example
* var y = binet( 4.0 );
* // returns 3.0
*
* @example
* var y = binet( 5.0 );
* // returns ~5.0
*
* @example
* var y = binet( 6.0 );
* // returns ~8.0
*
* @example
* var y = binet( NaN );
* // returns NaN
*
* @example
* var y = binet( 3.14 );
* // returns ~2.12
*
* @example
* var y = binet( -1.0 );
* // returns 1.0
*/
function binet( x ) {
	var a;
	var b;
	if (
		isnan( x ) ||
		x === PINF ||
		x === NINF
	) {
		return NaN;
	}
	a = pow( PHI, x );
	b = cospi( x ) / a;
	return ( a - b ) / SQRT_5;
} // end FUNCTION binet()

// EXPORTS //

module.exports = binet;
<commit_msg>Update formatting<commit_after>'use strict';

// MODULES //

var isnan = require( '@stdlib/math/base/assert/is-nan' );
var cospi = require( '@stdlib/math/base/special/cospi' );
var pow = require( '@stdlib/math/base/special/pow' );
var PHI = require( '@stdlib/constants/math/float64-phi' );
var PINF = require( '@stdlib/constants/math/float64-pinf' );
var NINF = require( '@stdlib/constants/math/float64-ninf' );

// VARIABLES //

var SQRT_5 = 2.23606797749979;

// MAIN //

/**
* Evaluates Binet's formula extended to real numbers.
*
* ## Notes
*
* -   [Non integer Fibonacci numbers]{@link https://math.stackexchange.com/questions/798190/non-integer-fibonacci-numbers}
* -   [Interpolated Fibonacci numbers - real or complex]{@link https://math.stackexchange.com/questions/589841/interpolated-fibonacci-numbers-real-or-complex}
*
*
* @param {number} x - input value
* @returns {number} real-valued result
*
* @example
* var y = binet( 0.0 );
* // returns 0.0
*
* @example
* var y = binet( 1.0 );
* // returns 1.0
*
* @example
* var y = binet( 2.0 );
* // returns 1.0
*
* @example
* var y = binet( 3.0 );
* // returns 2.0
*
* @example
* var y = binet( 4.0 );
* // returns 3.0
*
* @example
* var y = binet( 5.0 );
* // returns ~5.0
*
* @example
* var y = binet( 6.0 );
* // returns ~8.0
*
* @example
* var y = binet( NaN );
* // returns NaN
*
* @example
* var y = binet( 3.14 );
* // returns ~2.12
*
* @example
* var y = binet( -1.0 );
* // returns 1.0
*/
function binet( x ) {
	var a;
	var b;
	if (
		isnan( x ) ||
		x === PINF ||
		x === NINF
	) {
		return NaN;
	}
	a = pow( PHI, x );
	b = cospi( x ) / a;
	return ( a - b ) / SQRT_5;
} // end FUNCTION binet()

// EXPORTS //

module.exports = binet;
<|endoftext|>


<commit_before>/**
 * Period overview (overview of an period).
 */
Ext.define('devilry_subjectadmin.view.period.Overview' ,{
    extend: 'Ext.panel.Panel',
    alias: 'widget.periodoverview',
    cls: 'devilry_subjectadmin_periodoverview',
    requires: [
        'Ext.layout.container.Column',
        'devilry_extjsextras.EditableSidebarBox',
        'devilry_extjsextras.AlertMessage',
        'devilry_extjsextras.AlertMessageList',
        'devilry_subjectadmin.view.ActionList',
        'devilry_subjectadmin.view.AdminsBox',
        'devilry_subjectadmin.utils.UrlLookup',
        'devilry_subjectadmin.view.BaseNodeHierLocation'
    ],

    /**
     * @cfg {String} period_id (required)
     */

    initComponent: function() {
        Ext.apply(this, {
            frame: false,
            border: 0,
            bodyPadding: 40,
            autoScroll: true,

            items: [{
                xtype: 'alertmessagelist'
            }, {
                xtype: 'panel',
                ui: 'transparentpanel-overflowvisible',
                layout: 'column',
                items: [{
                    xtype: 'container',
                    columnWidth: 1.0,
                    items: [{
                        xtype: 'box',
                        cls: 'bootstrap',
                        margin: '0 0 20 0',
                        itemId: 'header',
                        tpl: '
{heading}
',
                        data: {
                            heading: gettext('Loading') + ' ...'
                        }
                    }, {
                        xtype: 'box',
                        cls: 'bootstrap devilry_subjectadmin_navigation',
                        itemId: 'createNewAssignmentBox',
                        tpl: [
                            '
{text}
'
                        ],
                        data: {
                            url: devilry_subjectadmin.utils.UrlLookup.createNewAssignment(this.period_id),
                            text: gettext('Create new assignment')
                        }
                    }, {
                        xtype: 'alertmessage',
                        itemId: 'noRelatedStudentsMessage',
                        hidden: true,
                        type: 'error',
                        title: gettext('No students'),
                        message: interpolate(gettext('This %(period_term)s has no students. Please go to the manage students page and add some students. You will not be able to add any assignments until you have at least one student.'), {
                            period_term: gettext('period'),
                            relatedstudents_url: devilry_subjectadmin.utils.UrlLookup.manageRelatedStudents(this.period_id)
                        }, true)
                    }, {
                        xtype: 'alertmessage',
                        itemId: 'noRelatedExaminersMessage',
                        hidden: true,
                        type: 'warning',
                        title: gettext('No examiners'),
                        message: interpolate(gettext('This %(period_term)s has no examiners. Please go to the manage examiners page and add some examiners.'), {
                            period_term: gettext('period'),
                            relatedexaminers_url: devilry_subjectadmin.utils.UrlLookup.manageRelatedExaminers(this.period_id)
                        }, true)
                    }, {
                        xtype: 'listofassignments'
                    }, {
                        xtype: 'box',
                        cls: 'bootstrap',
                        margin: '30 0 0 0',
                        tpl: [
                            '
', gettext('Students and examiners'), '
',
                            '
',
                                gettext('Students and examiners registered on a period are the only users available when you add students and examiners to assignments.'),
                            '
',
                            '
',
                                '

',
                                    '',
                                        gettext('Manage students'),
                                    '',
                                '

',
                                '

',
                                    '',
                                        gettext('Manage examiners'),
                                    '',
                                '

',
                            '
'
                        ],
                        data: {}
                    }, {
                        xtype: 'dangerousactions',
                        margin: '20 0 0 0',
                        items: [{
                            xtype: 'singleactionbox',
                            margin: '0 0 0 0',
                            itemId: 'renameButton',
                            id: 'periodRenameButton',
                            titleText: gettext('Loading ...'),
                            bodyHtml: gettext('Renaming a period should not done without a certain amount of consideration. The name of an period, especially the short name, is often used as an identifier when integrating other systems with Devilry.'),
                            buttonText: gettext('Rename') + ' ...'
                        }, {
                            xtype: 'singleactionbox',
                            itemId: 'deleteButton',
                            id: 'periodDeleteButton',
                            titleText: gettext('Loading ...'),
                            bodyHtml: gettext('Once you delete a period, there is no going back. Only superusers can delete a non-empty period.'),
                            buttonText: gettext('Delete') + ' ...'
                        }]
                    }]
                }, {
                    xtype: 'container',
                    border: false,
                    width: 250,
                    margin: '0 0 0 40',
                    defaults: {
                        margin: '20 0 0 0'
                    },
                    items: [{
                        xtype: 'adminsbox',
                        margin: '0 0 0 0'
                    }, {
                        xtype: 'basenodehierlocation'
                    }]
                }]
            }]
        });
        this.callParent(arguments);
    }
});
<commit_msg>devilry_subjectadmin...period.Overview: User the related terminology everywhere.<commit_after>/**
 * Period overview (overview of an period).
 */
Ext.define('devilry_subjectadmin.view.period.Overview' ,{
    extend: 'Ext.panel.Panel',
    alias: 'widget.periodoverview',
    cls: 'devilry_subjectadmin_periodoverview',
    requires: [
        'Ext.layout.container.Column',
        'devilry_extjsextras.EditableSidebarBox',
        'devilry_extjsextras.AlertMessage',
        'devilry_extjsextras.AlertMessageList',
        'devilry_subjectadmin.view.ActionList',
        'devilry_subjectadmin.view.AdminsBox',
        'devilry_subjectadmin.utils.UrlLookup',
        'devilry_subjectadmin.view.BaseNodeHierLocation'
    ],

    /**
     * @cfg {String} period_id (required)
     */

    initComponent: function() {
        Ext.apply(this, {
            frame: false,
            border: 0,
            bodyPadding: 40,
            autoScroll: true,

            items: [{
                xtype: 'alertmessagelist'
            }, {
                xtype: 'panel',
                ui: 'transparentpanel-overflowvisible',
                layout: 'column',
                items: [{
                    xtype: 'container',
                    columnWidth: 1.0,
                    items: [{
                        xtype: 'box',
                        cls: 'bootstrap',
                        margin: '0 0 20 0',
                        itemId: 'header',
                        tpl: '
{heading}
',
                        data: {
                            heading: gettext('Loading') + ' ...'
                        }
                    }, {
                        xtype: 'box',
                        cls: 'bootstrap devilry_subjectadmin_navigation',
                        itemId: 'createNewAssignmentBox',
                        tpl: [
                            '
{text}
'
                        ],
                        data: {
                            url: devilry_subjectadmin.utils.UrlLookup.createNewAssignment(this.period_id),
                            text: gettext('Create new assignment')
                        }
                    }, {
                        xtype: 'alertmessage',
                        itemId: 'noRelatedStudentsMessage',
                        hidden: true,
                        type: 'error',
                        title: gettext('No students'),
                        message: interpolate(gettext('This %(period_term)s has no students. Go to the manage related students page and add some students. You will not be able to add any assignments until you have at least one student.'), {
                            period_term: gettext('period'),
                            relatedstudents_url: devilry_subjectadmin.utils.UrlLookup.manageRelatedStudents(this.period_id)
                        }, true)
                    }, {
                        xtype: 'alertmessage',
                        itemId: 'noRelatedExaminersMessage',
                        hidden: true,
                        type: 'warning',
                        title: gettext('No examiners'),
                        message: interpolate(gettext('This %(period_term)s has no examiners. Go to the manage related examiners page and add some examiners.'), {
                            period_term: gettext('period'),
                            relatedexaminers_url: devilry_subjectadmin.utils.UrlLookup.manageRelatedExaminers(this.period_id)
                        }, true)
                    }, {
                        xtype: 'listofassignments'
                    }, {
                        xtype: 'box',
                        cls: 'bootstrap',
                        margin: '30 0 0 0',
                        tpl: [
                            '
', gettext('Related students and examiners'), '
',
                            '
',
                                gettext('Related students and examiners on a period are the only users available when you add students and examiners to assignments.'),
                            '
',
                            '
',
                                '

',
                                    '',
                                        gettext('Manage related students'),
                                    '',
                                '

',
                                '

',
                                    '',
                                        gettext('Manage related examiners'),
                                    '',
                                '

',
                            '
'
                        ],
                        data: {}
                    }, {
                        xtype: 'dangerousactions',
                        margin: '20 0 0 0',
                        items: [{
                            xtype: 'singleactionbox',
                            margin: '0 0 0 0',
                            itemId: 'renameButton',
                            id: 'periodRenameButton',
                            titleText: gettext('Loading ...'),
                            bodyHtml: gettext('Renaming a period should not done without a certain amount of consideration. The name of an period, especially the short name, is often used as an identifier when integrating other systems with Devilry.'),
                            buttonText: gettext('Rename') + ' ...'
                        }, {
                            xtype: 'singleactionbox',
                            itemId: 'deleteButton',
                            id: 'periodDeleteButton',
                            titleText: gettext('Loading ...'),
                            bodyHtml: gettext('Once you delete a period, there is no going back. Only superusers can delete a non-empty period.'),
                            buttonText: gettext('Delete') + ' ...'
                        }]
                    }]
                }, {
                    xtype: 'container',
                    border: false,
                    width: 250,
                    margin: '0 0 0 40',
                    defaults: {
                        margin: '20 0 0 0'
                    },
                    items: [{
                        xtype: 'adminsbox',
                        margin: '0 0 0 0'
                    }, {
                        xtype: 'basenodehierlocation'
                    }]
                }]
            }]
        });
        this.callParent(arguments);
    }
});
<|endoftext|>


<commit_before>/**
 * Switcher.js allows native-like page switching with ajax.
 *
 * Server identifies Switcher.js requests by "X-Requested-With: SwitchPage" HTTP header.
 * When this header is detected, you can return only updated elements. Usually there is no point
 * to track which elements was updated, but you can return very simplified page with container elements only,
 * with all layout missing. To identify which elements to replace, this script uses id attribute. All container
 * elements you want to update on page switch should contain .switcher class.
 *
 * If script fails to switch link, it uses http redirect to change page.
 *
 * This script adds following events:
 * construct        fires after page change
 * destruct        fires before page change
 * switch        fires after destruct when script understands that page switch will be successful
 */

var switcher = {};

switcher.noPush = false;
switcher.url = false;
switcher.referrer = false;

switcher.ajaxConfig = {
    async: true, cache: false, headers: {'X-Requested-With': 'SwitchPage'}, type: 'GET', beforeSend: function () {
        loading.show();
    }, success: function (data, status, xhr) {
        try {
            var newdata = $(data);
        } catch (ignore) {
            switcher.fallback();
            return;
        }
        var a = newdata.filter('.switcher').add(newdata.find('.switcher'));
        if (!a.length) {
            switcher.fallback();
            return;
        }
        $(document).triggerHandler('destruct');
        if (!switcher.noPush) {
            history.pushState({url: switcher.url}, '', switcher.url);
        }
        $(document).triggerHandler('switch');

        a.each(function (k, v) {
            try {
                $('#' + $(v).attr('id')).replaceWith(v).remove();
            } catch (ignore) {
            }
        });
        $(window).scrollTop(0);

        var title = newdata.filter('title').text();
        if (title.length) {
            document.title = title;
        } else {
            title = newdata.find('title').text();
            if (title.length) {
                document.title = title;
            }
        }
        $(document).triggerHandler('construct');
        loading.hide();
    }, error: function (xhr) {
        switcher.fallback();
    }
};

/**
 * Page switch fall back
 */
switcher.fallback = function () {
    $(document).triggerHandler('destruct');
    loading.hide();
    document.location = switcher.url;
};

/**
 * Switch page
 * @param url
 * @param noPush
 * @param data
 */
switcher.page = function (url, noPush, data) {
    // cut protocol://host part if it matches current host
    var host = window.location.protocol + "//" + window.location.host + "/";
    if (host == url.substring(0, host.length)) {
        switcher.page(url.substring(host.length - 1), noPush, data);
        return;
    }
    if (typeof debug != 'undefined') {
        debug.addReq('Switching page: ' + url);
    }
    switcher.noPush = !!noPush;
    switcher.referrer = switcher.url;
    switcher.url = url;
    if (typeof data == 'undefined') {
        if ($('.switcher:not(#debug)').length) {
            $.ajax(url, switcher.ajaxConfig);
        } else {
            $(document).triggerHandler('destruct');
            loading.hide();
            window.location = switcher.url;
        }
    } else {
        var conf = switcher.ajaxConfig;
        conf.type = 'POST';
        conf.data = data;
        $.ajax(url, conf);
    }
};

switcher.bind = function () {
    $(document).on('click dblclick touchend', 'a', function (event) {
        if (event.isDefaultPrevented()) {
            return;
        }

        // skip .ajaxer and .no-switcher links
        // warning: .noAjaxer is deprecated
        if ($(this).hasClass('ajaxer') || $(this).hasClass('noAjaxer') || $(this).hasClass('no-switcher')) {
            return;
        }

        if (!this.hasAttribute('href')) {
            return;
        }

        var href = $(this).attr('href');

        // skip empty links, anchors and javascript
        if (href == '' || href == '#') {
            event.preventDefault();
            return;
        }
        if (href.substr(0, 11) == 'javascript:' || href.substr(0, 1) == '#') {
            return;
        }

        event.preventDefault();
        switcher.page(href);
    });
    $(window).on('popstate', switcher.onpopstate);
};

/**
 * Support "Back" and "Forward" browser buttons
 */
switcher.onpopstate = function () {
    if (switcher.url && switcher.url != decodeURI(document.location.pathname)) {
        switcher.page(document.location.href, true);
    }
};

switcher.init = function () {
    // if there are no switcher elements, don't init
    if (!$('.switcher:not(#debug)').length) {
        return;
    }
    // remember current URL on first page load
    if (!switcher.url) {
        switcher.url = decodeURI(document.location.pathname);
    }
    // binds
    switcher.bind();
};

$(document).ready(switcher.init);
<commit_msg>Removed touchend from switcher binds<commit_after>/**
 * Switcher.js allows native-like page switching with ajax.
 *
 * Server identifies Switcher.js requests by "X-Requested-With: SwitchPage" HTTP header.
 * When this header is detected, you can return only updated elements. Usually there is no point
 * to track which elements was updated, but you can return very simplified page with container elements only,
 * with all layout missing. To identify which elements to replace, this script uses id attribute. All container
 * elements you want to update on page switch should contain .switcher class.
 *
 * If script fails to switch link, it uses http redirect to change page.
 *
 * This script adds following events:
 * construct        fires after page change
 * destruct        fires before page change
 * switch        fires after destruct when script understands that page switch will be successful
 */

var switcher = {};

switcher.noPush = false;
switcher.url = false;
switcher.referrer = false;

switcher.ajaxConfig = {
    async: true, cache: false, headers: {'X-Requested-With': 'SwitchPage'}, type: 'GET', beforeSend: function () {
        loading.show();
    }, success: function (data, status, xhr) {
        try {
            var newdata = $(data);
        } catch (ignore) {
            switcher.fallback();
            return;
        }
        var a = newdata.filter('.switcher').add(newdata.find('.switcher'));
        if (!a.length) {
            switcher.fallback();
            return;
        }
        $(document).triggerHandler('destruct');
        if (!switcher.noPush) {
            history.pushState({url: switcher.url}, '', switcher.url);
        }
        $(document).triggerHandler('switch');

        a.each(function (k, v) {
            try {
                $('#' + $(v).attr('id')).replaceWith(v).remove();
            } catch (ignore) {
            }
        });
        $(window).scrollTop(0);

        var title = newdata.filter('title').text();
        if (title.length) {
            document.title = title;
        } else {
            title = newdata.find('title').text();
            if (title.length) {
                document.title = title;
            }
        }
        $(document).triggerHandler('construct');
        loading.hide();
    }, error: function (xhr) {
        switcher.fallback();
    }
};

/**
 * Page switch fall back
 */
switcher.fallback = function () {
    $(document).triggerHandler('destruct');
    loading.hide();
    document.location = switcher.url;
};

/**
 * Switch page
 * @param url
 * @param noPush
 * @param data
 */
switcher.page = function (url, noPush, data) {
    // cut protocol://host part if it matches current host
    var host = window.location.protocol + "//" + window.location.host + "/";
    if (host == url.substring(0, host.length)) {
        switcher.page(url.substring(host.length - 1), noPush, data);
        return;
    }
    if (typeof debug != 'undefined') {
        debug.addReq('Switching page: ' + url);
    }
    switcher.noPush = !!noPush;
    switcher.referrer = switcher.url;
    switcher.url = url;
    if (typeof data == 'undefined') {
        if ($('.switcher:not(#debug)').length) {
            $.ajax(url, switcher.ajaxConfig);
        } else {
            $(document).triggerHandler('destruct');
            loading.hide();
            window.location = switcher.url;
        }
    } else {
        var conf = switcher.ajaxConfig;
        conf.type = 'POST';
        conf.data = data;
        $.ajax(url, conf);
    }
};

switcher.bind = function () {
    $(document).on('click dblclick', 'a', function (event) {
        if (event.isDefaultPrevented()) {
            return;
        }

        // skip .ajaxer and .no-switcher links
        // warning: .noAjaxer is deprecated
        if ($(this).hasClass('ajaxer') || $(this).hasClass('noAjaxer') || $(this).hasClass('no-switcher')) {
            return;
        }

        if (!this.hasAttribute('href')) {
            return;
        }

        var href = $(this).attr('href');

        // skip empty links, anchors and javascript
        if (href == '' || href == '#') {
            event.preventDefault();
            return;
        }
        if (href.substr(0, 11) == 'javascript:' || href.substr(0, 1) == '#') {
            return;
        }

        event.preventDefault();
        switcher.page(href);
    });
    $(window).on('popstate', switcher.onpopstate);
};

/**
 * Support "Back" and "Forward" browser buttons
 */
switcher.onpopstate = function () {
    if (switcher.url && switcher.url != decodeURI(document.location.pathname)) {
        switcher.page(document.location.href, true);
    }
};

switcher.init = function () {
    // if there are no switcher elements, don't init
    if (!$('.switcher:not(#debug)').length) {
        return;
    }
    // remember current URL on first page load
    if (!switcher.url) {
        switcher.url = decodeURI(document.location.pathname);
    }
    // binds
    switcher.bind();
};

$(document).ready(switcher.init);
<|endoftext|>


<commit_before>function Entities(myda) {
  this.myda = myda;
}

Entities.prototype.request = function(eventName, data) {
  return new Promise(function(resolve, reject) {
    myda.request(eventName, data, resolve, reject);
  });
};

Entities.prototype.create = function(entity, fields) {
  return this.request('entities.create', {
    root: this.myda.root,
    path: path,
    fields: fields
  });
};

Entities.prototype.get = function(path, options) {
  var data = {
    root: this.myda.root,
    path: path
  };
  return this.request('entities.data', data);
};

Entities.prototype.delete = function(path) {
  return this.request('entities.delete', {
    root: this.myda.root,
    path: path
  });
};

Entities.prototype.change = function(path, fields) {
  return this.request('entities.change', {
    root: this.myda.root,
    path: path,
    fields: fields
  });
};

Entities.prototype.subscribe = function(filter, events) {
  return this.request('entities.unsubscribe', {
    root: this.myda.root,
    path: filter,
    events: events
  });
};

Entities.prototype.unsubscribe = function(filter) {
  return this.request('entities.unsubscribe', {
    root: this.myda.root,
    path: filter
  });
};

Entities.prototype.on = function(eventName, callback) {
  this.myda.on('entities.' + eventName + '.res', callback);
};
<commit_msg>fix: Entities.get<commit_after>function Entities(myda) {
  this.myda = myda;
}

Entities.prototype.request = function(eventName, data) {
  return new Promise(function(resolve, reject) {
    myda.request(eventName, data, resolve, reject);
  });
};

Entities.prototype.create = function(entity, fields) {
  return this.request('entities.create', {
    root: this.myda.root,
    path: path,
    fields: fields
  });
};

Entities.prototype.get = function(path, options) {
  var data = {
    root: this.myda.root,
    path: path
  };
  return this.request('entities.get', data);
};

Entities.prototype.delete = function(path) {
  return this.request('entities.delete', {
    root: this.myda.root,
    path: path
  });
};

Entities.prototype.change = function(path, fields) {
  return this.request('entities.change', {
    root: this.myda.root,
    path: path,
    fields: fields
  });
};

Entities.prototype.subscribe = function(filter, events) {
  return this.request('entities.unsubscribe', {
    root: this.myda.root,
    path: filter,
    events: events
  });
};

Entities.prototype.unsubscribe = function(filter) {
  return this.request('entities.unsubscribe', {
    root: this.myda.root,
    path: filter
  });
};

Entities.prototype.on = function(eventName, callback) {
  this.myda.on('entities.' + eventName + '.res', callback);
};
<|endoftext|>


<commit_before>/**
 * Created by nagamai on 9/9/2016.
 */
import {cardFromNumber,schemeFromNumber,getAppData,addListener} from "./../utils";
import {getConfigValue} from '../ui-config';
import {validateExpiryDate, validateCreditCard} from './../validation/custom-validations';

let paymentField;
let field;
let cvvLen = 4;
let parentUrl = getAppData('parentUrl');
//todo:change its name later
let digit;
let parentUrl = getAppData('parentUrl');
const cardFieldHandler = () => {
    let fieldType = document.location.href.split("#");
    field = fieldType[1].split("-");
    paymentField = document.createElement("input");
    paymentField.setAttribute("id", field[0] + "citrusInput");
    document.body.appendChild(paymentField);
    var placeHolder = "";
    switch (field[0]) {
        case "cvv":
            placeHolder = "cvv";
            break;
        case "number":
            placeHolder = "card number";
            break;
        case "expiry":
            placeHolder = "expiry(mm/yy)";
            break;
    }
    var defaultStyle = {
        background: 0,
        display: 'inline-block',
        width: '78%',
        padding: "10px 0",
        fontSize: '13px',
        border:0
    };
    paymentField.setAttribute('placeholder', placeHolder);
    Object.assign(paymentField.style, defaultStyle);
    addEventListenersForHostedFields();
};

const postPaymentData = () => {
    //Send value of the field to the cardnumber iframe
    let cardData = {};
    cardData[field[0]] = paymentField.value;
    cardData.cardType = field[1];
    //todo:IMPORTANT, change * to citrus server url,
    //also if possible use name instead of index as index will be unreliable
    //if there are other iframes on merchant's page
    for(var i=0;i<parent.window.frames.length;i++)
    {parent.window.frames[i].postMessage(cardData, getConfigValue('hostedFieldDomain'));}
};

const addEventListenersForHostedFields = () => {
        //add the event listeners for ui validations of those fields.
        addListener(paymentField,"blur", postPaymentData, false);
        addListener(paymentField,"focus", addFocusAttributes, false);
        addListener(paymentField,"blur", removeFocusAttributes, false);
        switch (field[0]) {
            case "number" :
                addListener(paymentField,"blur", validateCard, false);
                addListener(paymentField,'keypress', restrictNumeric, false);
                addListener(paymentField,'keypress', restrictCardNumber, false);
                addListener(paymentField,'keypress', formatCardNumber, false);
                addListener(paymentField,'input', reFormatCardNumber, false);
                break;
            case "expiry" :
                addListener(paymentField,"blur", validateExpiry, false);
                addListener(paymentField,'keypress', restrictNumeric, false);
                addListener(paymentField,'keypress', formatExpiry, false);
                addListener(paymentField,'input', reformatExpiry, false);
                break;
            case "cvv"    :
                addListener(paymentField,'blur', validateCvv, false);
                paymentField.setAttribute("type", "password");
                addListener(paymentField,'keypress', restrictNumeric, false);
                addListener(paymentField,'keypress', restrictCVC, false);
                break;
        }
};

const addFocusAttributes=()=>{
    var hostedField = getAppData('hostedField');
    let focusReceivedMessage = {messageType:'focusReceived',fieldType:field[0],hostedField};
    parent.postMessage(focusReceivedMessage,getParentUrl());
}

const removeFocusAttributes =()=>{
     var hostedField = getAppData('hostedField');
    let focusLostMessage = {messageType:'focusLost',fieldType:field[0],hostedField};
    parent.postMessage(focusLostMessage,getParentUrl());
}

const formatCardNumber = () => {
    let num = paymentField.value;

    var card, groups, upperLength, _ref;
    card = cardFromNumber(num);
    if (!card) {
        return num;
    }
    upperLength = card.length[card.length.length - 1];
    num = num.replace(/\D/g, '');
    num = num.slice(0, upperLength);
    if (card.groupingFormat.global) {
        paymentField.value = (_ref = num.match(card.groupingFormat)) != null ? _ref.join(' ') : void 0;
    } else {
        groups = card.groupingFormat.exec(num);
        if (groups == null) {
            return;
        }
        groups.shift();
        groups = groups.filter(function (n) {
            return n;
        });
        paymentField.value = groups.join(' ');
    }
};

const hasTextSelected = (target) => {
    var _ref;
    if ((target.selectionStart != null) && target.selectionStart !== target.selectionEnd) {
        return true;
    }
    return !!(typeof document !== "undefined" && document !== null ? ( _ref = document.selection) != null ? typeof _ref.createRange === "function" ? _ref.createRange().text :
        void 0 :
        void 0 :
        void 0);

};

const formatExpiry = (e) => {
    let expiry = paymentField.value;
    var mon,
        parts,
        sep,
        year;
    parts = expiry.match(/^\D*(\d{1,2})(\D+)?(\d{1,4})?/);
    if (!parts) {
        paymentField.value = '';
        return;
    }
    mon = parts[1] || '';
    sep = parts[2] || '';
    year = parts[3] || '';
    if (year.length > 0 || (sep.length > 0 && !(/\ \/?\ ?/.test(sep)))) {
        sep = ' / ';
    }
    if (mon.length === 1 && (mon !== '0' && mon !== '1')) {
        mon = "0" + mon;
        sep = ' / ';
    }
    //check added for backspace key
    if(e.which<57) digit = e.which;
    if (digit< 57 && mon.length === 2)
    {
         sep = ' / ';
        digit = 60;
    }
    paymentField.value = mon + sep + year;
};

const restrictNumeric = (e) => {
    var input;
    if (e.metaKey || e.ctrlKey) {
        return true;
    }
    if (e.which === 32) {
        return false;
    }
    if (e.which === 0) {
        return true;
    }
    if (e.which < 33) {
        return true;
    }
    input = String.fromCharCode(e.which);
    //e.preventDefault ? e.preventDefault() : (e.returnValue = false);
    if(!/[\d\s]/.test(input)) e.preventDefault();
    //return !!/[\d\s]/.test(input);
};

//to avoid the acceptance of one extra digit in the field,
//and also formats the card number while pasting the number directly inside the field
const reFormatCardNumber = () => {
    return setTimeout(function () {
        formatCardNumber(paymentField.value);
    });
};
//to avoid the acceptance of one extra digit in the field
//and also formats the card number while pasting the number directly inside the field
const reformatExpiry = () => {
    return setTimeout(function () {
        formatExpiry(paymentField.value);
    });
};

// const restrictCVC = (e) => {
//     var digit,
//         keyCode;
//     //$target = $(e.currentTarget);
//     keyCode = e.which || e.keyCode;
//     digit = String.fromCharCode(keyCode);
//     if (!/^\d+$/.test(digit)) {
//         e.preventDefault ? e.preventDefault() : (e.returnValue = false);
//         return;
//     }
//     if (hasTextSelected(paymentField)) {
//         return;
//     }
//     e.preventDefault ? e.preventDefault() : (e.returnValue = false);
//     paymentField.value.length < cvvLen ? paymentField.value = paymentField.value + digit : (e.returnValue = false);
// };

const restrictCardNumber = function(e) {
    let card,
        digit,
        value;
    digit = String.fromCharCode(e.which);
    if (!/^\d+$/.test(digit)) {
        return;
    }
    if (hasTextSelected(paymentField)) {
        return;
    }
    value = (paymentField.value + digit).replace(/\D/g, '');
    card = cardFromNumber(value);
    if (card) {
        if(value.length > card.length[card.length.length - 1]) e.preventDefault();
    } else {
        if(value.length > 16) e.preventDefault();
    }
};

// const formatForwardExpiry = (e) => {
//     var $target,
//         digit,
//         val;
//     digit = String.fromCharCode(e.which);
//     if (!/^\d+$/.test(digit)) {
//         return;
//     }
//     $target = $(e.currentTarget);
//     val = $target.val();
//     if (/^\d\d$/.test(val)) {
//         return $target.val("" + val + " / ");
//     }
// };
//todo: change the value of these two fields
//if the card number does not require cvv or field;
let isExpiryRequired = true;
let isCvvRequired = true;
const validateCard = () => {
    const num = paymentField.value.replace(/\s+/g, '');
    var cardType = getAppData('cardType');
    var hostedField = getAppData('hostedField');
    let validationResult = {fieldType:'number',messageType:'validation',hostedField,cardType};
    if(!num){
        validationResult.cardValidationResult = {"isValidCard": false, "txMsg": 'Card nubmer can not be empty.',isValid:false};
        toggleValidity(false);
        parent.postMessage(validationResult,getParentUrl());
        return;
    }
    const scheme = schemeFromNumber(num);
    //todo : add check for maestro and rupay
    const isValidCard = validateCreditCard(num, scheme);
    let txMsg = "";
    if(!isValidCard) txMsg = "Invalid card number";
    validationResult.cardValidationResult = {"isValidCard": isValidCard, "txMsg": txMsg,isValid:isValidCard};
    parentUrl = getAppData('parentUrl');
    toggleValidity(isValidCard);
    parent.postMessage(validationResult, parentUrl);
};
const validateExpiry = () => {
    var hostedField = getAppData('hostedField');
    var cardType = getAppData('cardType');
    const exp = paymentField.value.replace(/\s+/g, '');
    let validationResult = {fieldType:'expiry',messageType:'validation',hostedField,cardType};
    if(!exp)
    {
        validationResult.cardValidationResult = {"isValidExpiry": false, "txMsg": 'Expiry date can not be empty.',isValid:false};
        toggleValidity(false);
        parent.postMessage(validationResult,getParentUrl());
        return;
    }
    const isValidExpiryDate = validateExpiryDate(exp);
    let txMsg = "";
    if(!isValidExpiryDate) {
        txMsg = "Invalid expiry date";
    }
    validationResult.cardValidationResult={"isValidExpiry" : isValidExpiryDate, "txMsg": txMsg,isValid:isValidExpiryDate};
    parentUrl = getAppData('parentUrl');
    toggleValidity(isValidExpiryDate);
    parent.postMessage(validationResult, parentUrl);
};

const toggleValidity = (isValid)=>{
    let classNameToAdd = ' invalid',classNameToRemove = ' valid';
    if(isValid)
    {
        classNameToAdd=' valid';
        classNameToRemove = ' invalid';
    }
    paymentField.className = paymentField.className.replace(classNameToRemove,'');
    if(paymentField.className.indexOf(classNameToAdd)===-1)
        paymentField.className += classNameToAdd;
}

const validateCvv = () =>{
    var hostedField = getAppData('hostedField');
    var cardType = getAppData('cardType');
    const cvv = paymentField.value.replace(/\s+/g, '');
     let validationResult = {fieldType:'cvv',messageType:'validation',hostedField,cardType};
    if(!cvv)
    {
        validationResult.cardValidationResult = {"isValidCvv": false, "txMsg": 'Cvv can not be empty.',isValid:false};
        toggleValidity(false);
        parent.postMessage(validationResult,getParentUrl());
        return;
    }
    else
    {
        validationResult.cardValidationResult = {"isValidCvv": true, "txMsg": '',isValid:true};
        toggleValidity(true);
        parent.postMessage(validationResult,getParentUrl());
        return;
    }
}

const restrictCVC = (e) => {
    var digit, val;
    digit = String.fromCharCode(e.which);
    if (!/^\d+$/.test(digit)) {
        return;
    }
    if (hasTextSelected(paymentField)) {
        return;
    }
    val = paymentField.value + digit;
    if(val.length > 4)  e.preventDefault();
};

const getParentUrl = ()=>{
  let url =  (window.location != window.parent.location)
            ? document.referrer
            : document.location.protocol+'//'+document.location.host;//getAppData('parentUrl');
  return url;
}

export {cardFieldHandler, formatExpiry}<commit_msg>removed duplicate declaration of parentUrl variable.<commit_after>/**
 * Created by nagamai on 9/9/2016.
 */
import {cardFromNumber,schemeFromNumber,getAppData,addListener} from "./../utils";
import {getConfigValue} from '../ui-config';
import {validateExpiryDate, validateCreditCard} from './../validation/custom-validations';

let paymentField;
let field;
let cvvLen = 4;
//todo:change its name later
let digit;
let parentUrl = getAppData('parentUrl');
const cardFieldHandler = () => {
    let fieldType = document.location.href.split("#");
    field = fieldType[1].split("-");
    paymentField = document.createElement("input");
    paymentField.setAttribute("id", field[0] + "citrusInput");
    document.body.appendChild(paymentField);
    var placeHolder = "";
    switch (field[0]) {
        case "cvv":
            placeHolder = "cvv";
            break;
        case "number":
            placeHolder = "card number";
            break;
        case "expiry":
            placeHolder = "expiry(mm/yy)";
            break;
    }
    var defaultStyle = {
        background: 0,
        display: 'inline-block',
        width: '78%',
        padding: "10px 0",
        fontSize: '13px',
        border:0
    };
    paymentField.setAttribute('placeholder', placeHolder);
    Object.assign(paymentField.style, defaultStyle);
    addEventListenersForHostedFields();
};

const postPaymentData = () => {
    //Send value of the field to the cardnumber iframe
    let cardData = {};
    cardData[field[0]] = paymentField.value;
    cardData.cardType = field[1];
    //todo:IMPORTANT, change * to citrus server url,
    //also if possible use name instead of index as index will be unreliable
    //if there are other iframes on merchant's page
    for(var i=0;i<parent.window.frames.length;i++)
    {parent.window.frames[i].postMessage(cardData, getConfigValue('hostedFieldDomain'));}
};

const addEventListenersForHostedFields = () => {
        //add the event listeners for ui validations of those fields.
        addListener(paymentField,"blur", postPaymentData, false);
        addListener(paymentField,"focus", addFocusAttributes, false);
        addListener(paymentField,"blur", removeFocusAttributes, false);
        switch (field[0]) {
            case "number" :
                addListener(paymentField,"blur", validateCard, false);
                addListener(paymentField,'keypress', restrictNumeric, false);
                addListener(paymentField,'keypress', restrictCardNumber, false);
                addListener(paymentField,'keypress', formatCardNumber, false);
                addListener(paymentField,'input', reFormatCardNumber, false);
                break;
            case "expiry" :
                addListener(paymentField,"blur", validateExpiry, false);
                addListener(paymentField,'keypress', restrictNumeric, false);
                addListener(paymentField,'keypress', formatExpiry, false);
                addListener(paymentField,'input', reformatExpiry, false);
                break;
            case "cvv"    :
                addListener(paymentField,'blur', validateCvv, false);
                paymentField.setAttribute("type", "password");
                addListener(paymentField,'keypress', restrictNumeric, false);
                addListener(paymentField,'keypress', restrictCVC, false);
                break;
        }
};

const addFocusAttributes=()=>{
    var hostedField = getAppData('hostedField');
    let focusReceivedMessage = {messageType:'focusReceived',fieldType:field[0],hostedField};
    parent.postMessage(focusReceivedMessage,getParentUrl());
}

const removeFocusAttributes =()=>{
     var hostedField = getAppData('hostedField');
    let focusLostMessage = {messageType:'focusLost',fieldType:field[0],hostedField};
    parent.postMessage(focusLostMessage,getParentUrl());
}

const formatCardNumber = () => {
    let num = paymentField.value;

    var card, groups, upperLength, _ref;
    card = cardFromNumber(num);
    if (!card) {
        return num;
    }
    upperLength = card.length[card.length.length - 1];
    num = num.replace(/\D/g, '');
    num = num.slice(0, upperLength);
    if (card.groupingFormat.global) {
        paymentField.value = (_ref = num.match(card.groupingFormat)) != null ? _ref.join(' ') : void 0;
    } else {
        groups = card.groupingFormat.exec(num);
        if (groups == null) {
            return;
        }
        groups.shift();
        groups = groups.filter(function (n) {
            return n;
        });
        paymentField.value = groups.join(' ');
    }
};

const hasTextSelected = (target) => {
    var _ref;
    if ((target.selectionStart != null) && target.selectionStart !== target.selectionEnd) {
        return true;
    }
    return !!(typeof document !== "undefined" && document !== null ? ( _ref = document.selection) != null ? typeof _ref.createRange === "function" ? _ref.createRange().text :
        void 0 :
        void 0 :
        void 0);

};

const formatExpiry = (e) => {
    let expiry = paymentField.value;
    var mon,
        parts,
        sep,
        year;
    parts = expiry.match(/^\D*(\d{1,2})(\D+)?(\d{1,4})?/);
    if (!parts) {
        paymentField.value = '';
        return;
    }
    mon = parts[1] || '';
    sep = parts[2] || '';
    year = parts[3] || '';
    if (year.length > 0 || (sep.length > 0 && !(/\ \/?\ ?/.test(sep)))) {
        sep = ' / ';
    }
    if (mon.length === 1 && (mon !== '0' && mon !== '1')) {
        mon = "0" + mon;
        sep = ' / ';
    }
    //check added for backspace key
    if(e.which<57) digit = e.which;
    if (digit< 57 && mon.length === 2)
    {
         sep = ' / ';
        digit = 60;
    }
    paymentField.value = mon + sep + year;
};

const restrictNumeric = (e) => {
    var input;
    if (e.metaKey || e.ctrlKey) {
        return true;
    }
    if (e.which === 32) {
        return false;
    }
    if (e.which === 0) {
        return true;
    }
    if (e.which < 33) {
        return true;
    }
    input = String.fromCharCode(e.which);
    //e.preventDefault ? e.preventDefault() : (e.returnValue = false);
    if(!/[\d\s]/.test(input)) e.preventDefault();
    //return !!/[\d\s]/.test(input);
};

//to avoid the acceptance of one extra digit in the field,
//and also formats the card number while pasting the number directly inside the field
const reFormatCardNumber = () => {
    return setTimeout(function () {
        formatCardNumber(paymentField.value);
    });
};
//to avoid the acceptance of one extra digit in the field
//and also formats the card number while pasting the number directly inside the field
const reformatExpiry = () => {
    return setTimeout(function () {
        formatExpiry(paymentField.value);
    });
};

// const restrictCVC = (e) => {
//     var digit,
//         keyCode;
//     //$target = $(e.currentTarget);
//     keyCode = e.which || e.keyCode;
//     digit = String.fromCharCode(keyCode);
//     if (!/^\d+$/.test(digit)) {
//         e.preventDefault ? e.preventDefault() : (e.returnValue = false);
//         return;
//     }
//     if (hasTextSelected(paymentField)) {
//         return;
//     }
//     e.preventDefault ? e.preventDefault() : (e.returnValue = false);
//     paymentField.value.length < cvvLen ? paymentField.value = paymentField.value + digit : (e.returnValue = false);
// };

const restrictCardNumber = function(e) {
    let card,
        digit,
        value;
    digit = String.fromCharCode(e.which);
    if (!/^\d+$/.test(digit)) {
        return;
    }
    if (hasTextSelected(paymentField)) {
        return;
    }
    value = (paymentField.value + digit).replace(/\D/g, '');
    card = cardFromNumber(value);
    if (card) {
        if(value.length > card.length[card.length.length - 1]) e.preventDefault();
    } else {
        if(value.length > 16) e.preventDefault();
    }
};

// const formatForwardExpiry = (e) => {
//     var $target,
//         digit,
//         val;
//     digit = String.fromCharCode(e.which);
//     if (!/^\d+$/.test(digit)) {
//         return;
//     }
//     $target = $(e.currentTarget);
//     val = $target.val();
//     if (/^\d\d$/.test(val)) {
//         return $target.val("" + val + " / ");
//     }
// };
//todo: change the value of these two fields
//if the card number does not require cvv or field;
let isExpiryRequired = true;
let isCvvRequired = true;
const validateCard = () => {
    const num = paymentField.value.replace(/\s+/g, '');
    var cardType = getAppData('cardType');
    var hostedField = getAppData('hostedField');
    let validationResult = {fieldType:'number',messageType:'validation',hostedField,cardType};
    if(!num){
        validationResult.cardValidationResult = {"isValidCard": false, "txMsg": 'Card nubmer can not be empty.',isValid:false};
        toggleValidity(false);
        parent.postMessage(validationResult,getParentUrl());
        return;
    }
    const scheme = schemeFromNumber(num);
    //todo : add check for maestro and rupay
    const isValidCard = validateCreditCard(num, scheme);
    let txMsg = "";
    if(!isValidCard) txMsg = "Invalid card number";
    validationResult.cardValidationResult = {"isValidCard": isValidCard, "txMsg": txMsg,isValid:isValidCard};
    parentUrl = getAppData('parentUrl');
    toggleValidity(isValidCard);
    parent.postMessage(validationResult, parentUrl);
};
const validateExpiry = () => {
    var hostedField = getAppData('hostedField');
    var cardType = getAppData('cardType');
    const exp = paymentField.value.replace(/\s+/g, '');
    let validationResult = {fieldType:'expiry',messageType:'validation',hostedField,cardType};
    if(!exp)
    {
        validationResult.cardValidationResult = {"isValidExpiry": false, "txMsg": 'Expiry date can not be empty.',isValid:false};
        toggleValidity(false);
        parent.postMessage(validationResult,getParentUrl());
        return;
    }
    const isValidExpiryDate = validateExpiryDate(exp);
    let txMsg = "";
    if(!isValidExpiryDate) {
        txMsg = "Invalid expiry date";
    }
    validationResult.cardValidationResult={"isValidExpiry" : isValidExpiryDate, "txMsg": txMsg,isValid:isValidExpiryDate};
    parentUrl = getAppData('parentUrl');
    toggleValidity(isValidExpiryDate);
    parent.postMessage(validationResult, parentUrl);
};

const toggleValidity = (isValid)=>{
    let classNameToAdd = ' invalid',classNameToRemove = ' valid';
    if(isValid)
    {
        classNameToAdd=' valid';
        classNameToRemove = ' invalid';
    }
    paymentField.className = paymentField.className.replace(classNameToRemove,'');
    if(paymentField.className.indexOf(classNameToAdd)===-1)
        paymentField.className += classNameToAdd;
}

const validateCvv = () =>{
    var hostedField = getAppData('hostedField');
    var cardType = getAppData('cardType');
    const cvv = paymentField.value.replace(/\s+/g, '');
     let validationResult = {fieldType:'cvv',messageType:'validation',hostedField,cardType};
    if(!cvv)
    {
        validationResult.cardValidationResult = {"isValidCvv": false, "txMsg": 'Cvv can not be empty.',isValid:false};
        toggleValidity(false);
        parent.postMessage(validationResult,getParentUrl());
        return;
    }
    else
    {
        validationResult.cardValidationResult = {"isValidCvv": true, "txMsg": '',isValid:true};
        toggleValidity(true);
        parent.postMessage(validationResult,getParentUrl());
        return;
    }
}

const restrictCVC = (e) => {
    var digit, val;
    digit = String.fromCharCode(e.which);
    if (!/^\d+$/.test(digit)) {
        return;
    }
    if (hasTextSelected(paymentField)) {
        return;
    }
    val = paymentField.value + digit;
    if(val.length > 4)  e.preventDefault();
};

const getParentUrl = ()=>{
  let url =  (window.location != window.parent.location)
            ? document.referrer
            : document.location.protocol+'//'+document.location.host;//getAppData('parentUrl');
  return url;
}

export {cardFieldHandler, formatExpiry}<|endoftext|>


<commit_before>/**
 * @file
 * Waypoint file parser module for the task creator.
 */
define(['jquery', 'waypoints/waypoints', 'task/task', 'tracks/tracks', 'formats/oziOld', 'formats/ozi', 'formats/cup', 'formats/igc', 'formats/tsk', 'formats/gpx', 'jgrowl'],
function($, waypoints, task, tracks, oziOld, ozi, cup, igc, tsk, gpx) {

  var formats = [oziOld, ozi, cup, igc, tsk, gpx];
  var parse = function(text, filename) {
    var result = formatCheck(text, filename);
    var format = result.format;

    if (!format) {
      $.jGrowl(result.message, {
        header : result.state,
        theme : result.state,
        sticky : true,
        position : 'top-left',
      });
      return;
    }

    var fileInfo = format.parse(text, filename);
    var parseInfo = {};

    if (fileInfo.waypoints) {
      var waypointsInfos = fileInfo.waypoints;
      var l = waypointsInfos.length;
      var waypointsArray = Array();
      for (var i = 0; i < l; i++) {
        if (!waypoints.alreadyHave(waypointsInfos[i])) {
          var waypoint = waypoints.addWaypoint(waypointsInfos[i]);
          waypointsArray.push(waypoint);
        }
      }

      if (l > 0) {
        waypoints.clearPastFile();
        waypoints.addFilename(filename);
        $.jGrowl(l + ' waypoints succesfully imported from file : ' + filename + ' !!', {
          header : 'success',
          theme : 'success',
          sticky : true,
          position : 'top-left',
        });
      } else {
        $.jGrowl('No waypoint were found from file  : ' + filename + ' !!', {
          header : 'warning',
          theme : 'warning',
          sticky : true,
          position : 'top-left',
        });
      }
      parseInfo.waypoints = waypointsArray;
    }

    if (fileInfo.tracks) {
      var tracksInfos = fileInfo.tracks;
      var l = tracksInfos.length;
      var tracksArray = Array();
      for (var i = 0; i < l; i++) {
        var track = tracks.addTrack(tracksInfos[i]);
        tracksArray.push(track);
      }
      parseInfo.tracks = tracksArray;
    }

    if (fileInfo.task) {
      parseInfo.task = fileInfo.task;
      if (parseInfo.task.turnpoints.length > 0) {
        for (var i = 0; i < parseInfo.task.turnpoints.length; i++ ) {
          var tp = parseInfo.task.turnpoints[i];
          var waypoint = waypoints.getWaypointByFileAndId(tp.wp.filename , tp.wp.id);
          tp.waypoint = waypoint;
        }
        return parseInfo;
      }
    }
  }

  var formatCheck = function(text, filename) {
    var formatsName = [];
    for (var i = 0; i < formats.length; i++) {
      formatsName.push(formats[i].name);
    }

    var result = {
      format : false,
      state : 'error',
      message : 'Waypoints file format unknown. We only support : ' + formatsName.join(" , ") + ' files',
    }

    if (waypoints.checkFilename(filename) == false) {
      result.message = 'This file : ' + filename + " is alredy used.";
      result.state = 'warning';
      return result;
    }

    for (var i = 0; i < formats.length; i++) {
      if (formats[i].check(text, filename) == true) {
        result.format = formats[i];
        return result;
      }
    }
    return result;
  }

  return {
    'parse' : parse,
  }
});
<commit_msg>Bug Fixes : Trying to import any set of existing waypoint (file) was impossible since last commit. Credits to James Bradley via PM on Paragliding Forum.<commit_after>/**
 * @file
 * Waypoint file parser module for the task creator.
 */
define(['jquery', 'waypoints/waypoints', 'task/task', 'tracks/tracks', 'formats/oziOld', 'formats/ozi', 'formats/cup', 'formats/igc', 'formats/tsk', 'formats/gpx', 'jgrowl'],
function($, waypoints, task, tracks, oziOld, ozi, cup, igc, tsk, gpx) {

  var formats = [oziOld, ozi, cup, igc, tsk, gpx];
  var parse = function(text, filename) {
    var result = formatCheck(text, filename);
    var format = result.format;

    if (!format) {
      $.jGrowl(result.message, {
        header : result.state,
        theme : result.state,
        sticky : true,
        position : 'top-left',
      });
      return;
    }

    var fileInfo = format.parse(text, filename);
    var parseInfo = {};

    if (fileInfo.waypoints) {
      var waypointsInfos = fileInfo.waypoints;
      var l = waypointsInfos.length;
      var waypointsArray = Array();
      for (var i = 0; i < l; i++) {
        if (!waypoints.alreadyHave(waypointsInfos[i])) {
          var waypoint = waypoints.addWaypoint(waypointsInfos[i]);
          waypointsArray.push(waypoint);
        }
      }

      if (l > 0) {
        waypoints.clearPastFile();
        waypoints.addFilename(filename);
        $.jGrowl(l + ' waypoints succesfully imported from file : ' + filename + ' !!', {
          header : 'success',
          theme : 'success',
          sticky : true,
          position : 'top-left',
        });
      } else {
        $.jGrowl('No waypoint were found from file  : ' + filename + ' !!', {
          header : 'warning',
          theme : 'warning',
          sticky : true,
          position : 'top-left',
        });
      }
      parseInfo.waypoints = waypointsArray;
    }

    if (fileInfo.tracks) {
      var tracksInfos = fileInfo.tracks;
      var l = tracksInfos.length;
      var tracksArray = Array();
      for (var i = 0; i < l; i++) {
        var track = tracks.addTrack(tracksInfos[i]);
        tracksArray.push(track);
      }
      parseInfo.tracks = tracksArray;
    }

    if (fileInfo.task) {
      parseInfo.task = fileInfo.task;
      if (parseInfo.task.turnpoints.length > 0) {
        for (var i = 0; i < parseInfo.task.turnpoints.length; i++ ) {
          var tp = parseInfo.task.turnpoints[i];
          var waypoint = waypoints.getWaypointByFileAndId(tp.wp.filename , tp.wp.id);
          tp.waypoint = waypoint;
        }
      }
    }
    return parseInfo;
  }

  var formatCheck = function(text, filename) {
    var formatsName = [];
    for (var i = 0; i < formats.length; i++) {
      formatsName.push(formats[i].name);
    }

    var result = {
      format : false,
      state : 'error',
      message : 'Waypoints file format unknown. We only support : ' + formatsName.join(" , ") + ' files',
    }

    if (waypoints.checkFilename(filename) == false) {
      result.message = 'This file : ' + filename + " is alredy used.";
      result.state = 'warning';
      return result;
    }

    for (var i = 0; i < formats.length; i++) {
      if (formats[i].check(text, filename) == true) {
        result.format = formats[i];
        return result;
      }
    }
    return result;
  }

  return {
    'parse' : parse,
  }
});
<|endoftext|>