Socket
Socket
Sign inDemoInstall

globalize

Package Overview
Dependencies
Maintainers
4
Versions
68
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

globalize - npm Package Compare versions

Comparing version 1.0.0-alpha.6 to 1.0.0-alpha.7

doc/api/date/date-formatter.md

8

bower.json
{
"name": "globalize",
"version": "1.0.0-alpha.6",
"version": "1.0.0-alpha.7",
"license": "MIT",
"ignore": [

@@ -11,6 +12,7 @@ "**/.*",

"dependencies": {
"cldrjs": "0.3.8"
"cldrjs": "0.3.8",
"cldr-data": ">=25"
},
"devDependencies": {
"CLDRPluralRuleParser": "santhoshtr/CLDRPluralRuleParser#v1.1.3",
"CLDRPluralRuleParser": "santhoshtr/CLDRPluralRuleParser#6b17882b834b1ab8bb3a593fd66529c9822dd6d7",
"es5-shim": "3.4.0",

@@ -17,0 +19,0 @@ "qunit": "1.12.0",

/*!
* Globalize v1.0.0-alpha.6
* Globalize v1.0.0-alpha.7
*

@@ -10,3 +10,3 @@ * http://github.com/jquery/globalize

*
* Date: 2014-09-01T21:32Z
* Date: 2014-09-30T12:31Z
*/

@@ -13,0 +13,0 @@

/*!
* Globalize v1.0.0-alpha.6
* Globalize v1.0.0-alpha.7
*

@@ -10,3 +10,3 @@ * http://github.com/jquery/globalize

*
* Date: 2014-09-01T21:32Z
* Date: 2014-09-30T12:31Z
*/

@@ -13,0 +13,0 @@ (function( root, factory ) {

/*!
* Globalize v1.0.0-alpha.6 2014-09-01T21:32Z Released under the MIT license
* Globalize v1.0.0-alpha.7 2014-09-30T12:31Z Released under the MIT license
* http://git.io/TrdQbw
*/
!function(a,b){"function"==typeof define&&define.amd?define(["cldr","cldr/event"],b):"object"==typeof exports?module.exports=b(require("cldrjs")):a.Globalize=b(a.Cldr)}(this,function(a){function b(a){a.once("get",i),a.get("supplemental/likelySubtags")}function c(a){return this instanceof c?(k(a,"locale"),n(a,"locale"),this.cldr=q(a),void b(this.cldr)):new c(a)}var d=function(a){return"string"==typeof a?a:"number"==typeof a?""+a:JSON.stringify(a)},e=function(a,b){return a=a.replace(/{[0-9a-zA-Z-_. ]+}/g,function(a){return a=a.replace(/^{([^}]*)}$/,"$1"),d(b[a])})},f=function(a,b,c){var d;return b=a+(b?": "+e(b,c):""),d=new Error(b),d.code=a,Object.keys(c).forEach(function(a){d[a]=c[a]}),d},g=function(a,b,c,d){if(!c)throw f(a,b,d)},h=function(a){return Array.isArray(a)?a:a?[a]:[]},i=function(a,b,c){var d;c=c||{},d=h(c.skip).some(function(b){return b.test(a)}),g("E_MISSING_CLDR","Missing required CLDR content `{path}`.",b||d,{path:a})},j=function(a){g("E_DEFAULT_LOCALE_NOT_DEFINED","Default locale has not been defined.",void 0!==a,{})},k=function(a,b){g("E_MISSING_PARAMETER","Missing required parameter `{name}`.",void 0!==a,{name:b})},l=function(a,b,c,d){g("E_PAR_OUT_OF_RANGE","Parameter `{name}` has value `{value}` out of range [{minimum}, {maximum}].",void 0===a||a>=c&&d>=a,{maximum:d,minimum:c,name:b,value:a})},m=function(a,b,c,d){g("E_INVALID_PAR_TYPE","Invalid `{name}` parameter ({value}). {expected} expected.",c,{expected:d,name:b,value:a})},n=function(b,c){m(b,c,void 0===b||"string"==typeof b||b instanceof a,"String or Cldr instance")},o=function(a){return null!==a&&""+a=="[object Object]"},p=function(a,b){m(a,b,void 0===a||o(a),"Plain Object")},q=function(b){return b instanceof a?b:new a(b)};return c.load=function(b){k(b,"json"),p(b,"json"),a.load(b)},c.locale=function(a){return n(a,"locale"),arguments.length&&(this.cldr=q(a),b(this.cldr)),this.cldr},c._alwaysArray=h,c._createError=f,c._formatMessage=e,c._isPlainObject=o,c._validate=g,c._validateCldr=i,c._validateDefaultLocale=j,c._validateParameterPresence=k,c._validateParameterRange=l,c._validateParameterTypePlainObject=p,c._validateParameterType=m,c});
/*!
* Globalize v1.0.0-alpha.6
* Globalize v1.0.0-alpha.7
*

@@ -10,3 +10,3 @@ * http://github.com/jquery/globalize

*
* Date: 2014-09-01T21:32Z
* Date: 2014-09-30T12:31Z
*/

@@ -36,4 +36,3 @@ (function( root, factory ) {

var alwaysArray = Globalize._alwaysArray,
createError = Globalize._createError,
var createError = Globalize._createError,
formatMessage = Globalize._formatMessage,

@@ -78,65 +77,2 @@ isPlainObject = Globalize._isPlainObject,

var objectValues = function( object ) {
var i,
result = [];
for ( i in object ) {
result.push( object[ i ] );
}
return result;
};
/**
* allPreset()
*
* @cldr [Cldr instance].
*
* Return an Array with all (skeleton, date, time, datetime) presets.
*/
var dateAllPresets = function( cldr ) {
var result = [];
// Skeleton
result = objectValues( cldr.main(
"dates/calendars/gregorian/dateTimeFormats/availableFormats") );
// Time
result = result.concat( objectValues( cldr.main( "dates/calendars/gregorian/timeFormats" ) ) );
// Date
result = result.concat( objectValues( cldr.main( "dates/calendars/gregorian/dateFormats" ) ) );
// Datetime
result = result.concat(
objectValues( cldr.main(
"dates/calendars/gregorian/dateTimeFormats"
)).map(function( datetimeFormat, key ) {
if ( typeof datetimeFormat !== "string" ) {
return datetimeFormat;
}
return formatMessage( datetimeFormat, [
cldr.main([
"dates/calendars/gregorian/timeFormats",
key
]),
cldr.main([
"dates/calendars/gregorian/dateFormats",
key
])
]);
})
);
return result.map(function( pattern ) {
return { pattern: pattern };
});
};
var createErrorInvalidParameterValue = function( name, value ) {

@@ -233,20 +169,9 @@ return createError( "E_INVALID_PAR_VALUE", "Invalid `{name}` value ({value}).", {

var dateWeekDays = [ "sun", "mon", "tue", "wed", "thu", "fri", "sat" ];
/**
* firstDayOfWeek
*/
var dateFirstDayOfWeek = function( cldr ) {
return dateWeekDays.indexOf( cldr.supplemental.weekData.firstDay() );
};
/**
* dayOfWeek
* dayOfWeek( date, firstDay )
*
* @date
*
* @firstDay the result of `dateFirstDayOfWeek( cldr )`
*
* Return the day of the week normalized by the territory's firstDay [0-6].

@@ -258,4 +183,4 @@ * Eg for "mon":

*/
var dateDayOfWeek = function( date, cldr ) {
return ( date.getDay() - dateFirstDayOfWeek( cldr ) + 7 ) % 7;
var dateDayOfWeek = function( date, firstDay ) {
return ( date.getDay() - firstDay + 7 ) % 7;
};

@@ -327,3 +252,18 @@

var dateWeekDays = [ "sun", "mon", "tue", "wed", "thu", "fri", "sat" ];
/**
* firstDayOfWeek
*/
var dateFirstDayOfWeek = function( cldr ) {
return dateWeekDays.indexOf( cldr.supplemental.weekData.firstDay() );
};
/**
* millisecondsInDay

@@ -359,11 +299,8 @@ */

/**
* format( date, pattern, cldr )
* format( date, properties )
*
* @date [Date instance].
*
* @pattern [String] raw pattern.
* ref: http://www.unicode.org/reports/tr35/tr35-dates.html#Date_Format_Patterns
* @properties
*
* @cldr [Cldr instance].
*
* TODO Support other calendar types.

@@ -373,5 +310,4 @@ *

*/
var dateFormat = function( date, pattern, cldr ) {
var widths = [ "abbreviated", "wide", "narrow" ];
return pattern.replace( datePatternRe, function( current ) {
var dateFormat = function( date, properties ) {
return properties.pattern.replace( datePatternRe, function( current ) {
var pad, ret,

@@ -384,3 +320,3 @@ chr = current.charAt( 0 ),

// http://www.unicode.org/reports/tr35/tr35-dates.html#Time_Data
chr = cldr.supplemental.timeData.preferred();
chr = properties.preferredTime;
}

@@ -392,7 +328,3 @@

case "G":
ret = cldr.main([
"dates/calendars/gregorian/eras",
length <= 3 ? "eraAbbr" : ( length === 4 ? "eraNames" : "eraNarrow" ),
date.getFullYear() < 0 ? 0 : 1
]);
ret = properties.eras[ date.getFullYear() < 0 ? 0 : 1 ];
break;

@@ -420,5 +352,5 @@

ret.getDate() + 7 -
dateDayOfWeek( date, cldr ) -
dateFirstDayOfWeek( cldr ) -
cldr.supplemental.weekData.minDays()
dateDayOfWeek( date, properties.firstDay ) -
properties.firstDay -
properties.minDays
);

@@ -443,9 +375,3 @@ ret = String( ret.getFullYear() );

} else {
// http://unicode.org/cldr/trac/ticket/6788
ret = cldr.main([
"dates/calendars/gregorian/quarters",
chr === "Q" ? "format" : "stand-alone",
widths[ length - 3 ],
ret
]);
ret = properties.quarters[ chr ][ length ][ ret ];
}

@@ -461,8 +387,3 @@ break;

} else {
ret = cldr.main([
"dates/calendars/gregorian/months",
chr === "M" ? "format" : "stand-alone",
widths[ length - 3 ],
ret
]);
ret = properties.months[ chr ][ length ][ ret ];
}

@@ -476,5 +397,5 @@ break;

// TODO should pad on ww? Not documented, but I guess so.
ret = dateDayOfWeek( dateStartOf( date, "year" ), cldr );
ret = dateDayOfWeek( dateStartOf( date, "year" ), properties.firstDay );
ret = Math.ceil( ( dateDayOfYear( date ) + ret ) / 7 ) -
( 7 - ret >= cldr.supplemental.weekData.minDays() ? 0 : 1 );
( 7 - ret >= properties.minDays ? 0 : 1 );
pad = true;

@@ -486,5 +407,5 @@ break;

// wom = ceil( ( dom + dow of `1/month` ) / 7 ) - minDaysStuff ? 1 : 0.
ret = dateDayOfWeek( dateStartOf( date, "month" ), cldr );
ret = dateDayOfWeek( dateStartOf( date, "month" ), properties.firstDay );
ret = Math.ceil( ( date.getDate() + ret ) / 7 ) -
( 7 - ret >= cldr.supplemental.weekData.minDays() ? 0 : 1 );
( 7 - ret >= properties.minDays ? 0 : 1 );
break;

@@ -518,3 +439,3 @@

// TODO Should pad with zeros (not specified in the docs)?
ret = dateDayOfWeek( date, cldr ) + 1;
ret = dateDayOfWeek( date, properties.firstDay ) + 1;
pad = true;

@@ -527,26 +448,3 @@ break;

ret = dateWeekDays[ date.getDay() ];
if ( length === 6 ) {
// If short day names are not explicitly specified, abbreviated day names are
// used instead.
// http://www.unicode.org/reports/tr35/tr35-dates.html#months_days_quarters_eras
// http://unicode.org/cldr/trac/ticket/6790
ret = cldr.main([
"dates/calendars/gregorian/days",
chr === "c" ? "stand-alone" : "format",
"short",
ret
]) || cldr.main([
"dates/calendars/gregorian/days",
chr === "c" ? "stand-alone" : "format",
"abbreviated",
ret
]);
} else {
ret = cldr.main([
"dates/calendars/gregorian/days",
chr === "c" ? "stand-alone" : "format",
widths[ length < 3 ? 0 : length - 3 ],
ret
]);
}
ret = properties.days[ chr ][ length ][ ret ];
break;

@@ -556,6 +454,3 @@

case "a":
ret = cldr.main([
"dates/calendars/gregorian/dayPeriods/format/wide",
date.getHours() < 12 ? "am" : "pm"
]);
ret = properties.dayPeriods[ date.getHours() < 12 ? "am" : "pm" ];
break;

@@ -634,74 +529,28 @@

/**
* tokenizer( value, pattern )
* properties( pattern, cldr )
*
* Returns an Array of tokens, eg. value "5 o'clock PM", pattern "h 'o''clock' a":
* [{
* type: "h",
* lexeme: "5"
* }, {
* type: "literal",
* lexeme: " "
* }, {
* type: "literal",
* lexeme: "o'clock"
* }, {
* type: "literal",
* lexeme: " "
* }, {
* type: "a",
* lexeme: "PM",
* value: "pm"
* }]
* @pattern [String] raw pattern.
* ref: http://www.unicode.org/reports/tr35/tr35-dates.html#Date_Format_Patterns
*
* OBS: lexeme's are always String and may return invalid ranges depending of the token type.
* Eg. "99" for month number.
* @cldr [Cldr instance].
*
* Return an empty Array when not successfully parsed.
* Return the properties given the pattern and cldr.
*
* TODO Support other calendar types.
*/
var dateTokenizer = function( value, pattern, cldr ) {
var valid,
tokens = [],
var dateFormatProperties = function( pattern, cldr ) {
var properties = {},
widths = [ "abbreviated", "wide", "narrow" ];
valid = pattern.match( datePatternRe ).every(function( current ) {
var chr, length, tokenRe,
token = {};
properties.pattern = pattern;
pattern.replace( datePatternRe, function( current ) {
var chr = current.charAt( 0 ),
length = current.length;
function oneDigitIfLengthOne() {
if ( length === 1 ) {
return tokenRe = /\d/;
}
if ( chr === "j" ) {
// Locale preferred hHKk.
// http://www.unicode.org/reports/tr35/tr35-dates.html#Time_Data
properties.preferredTime = chr = cldr.supplemental.timeData.preferred();
}
function oneOrTwoDigitsIfLengthOne() {
if ( length === 1 ) {
return tokenRe = /\d\d?/;
}
}
function twoDigitsIfLengthTwo() {
if ( length === 2 ) {
return tokenRe = /\d\d/;
}
}
// Brute-force test every locale entry in an attempt to match the given value.
// Return the first found one (and set token accordingly), or null.
function lookup( path ) {
var i, re,
data = cldr.main( path );
for ( i in data ) {
re = new RegExp( "^" + data[ i ] );
if ( re.test( value ) ) {
token.value = i;
return tokenRe = new RegExp( data[ i ] );
}
}
return null;
}
token.type = current;
chr = current.charAt( 0 ),
length = current.length;
switch ( chr ) {

@@ -711,3 +560,3 @@

case "G":
lookup([
properties.eras = cldr.main([
"dates/calendars/gregorian/eras",

@@ -718,13 +567,6 @@ length <= 3 ? "eraAbbr" : ( length === 4 ? "eraNames" : "eraNarrow" )

// Year
case "y":
case "Y":
// number l=1:+, l=2:{2}, l=3:{3,}, l=4:{4,}, ...
if ( length === 1 ) {
tokenRe = /\d+/;
} else if ( length === 2 ) {
tokenRe = /\d\d/;
} else {
tokenRe = new RegExp( "\\d{" + length + ",}" );
}
// Year in "Week of Year"
properties.firstDay = dateFirstDayOfWeek( cldr );
properties.minDays = cldr.supplemental.weekData.minDays();
break;

@@ -739,9 +581,15 @@

case "q":
// number l=1:{1}, l=2:{2}.
// lookup l=3...
oneDigitIfLengthOne() || twoDigitsIfLengthTwo() || lookup([
"dates/calendars/gregorian/quarters",
chr === "Q" ? "format" : "stand-alone",
widths[ length - 3 ]
]);
if ( length > 2 ) {
if ( !properties.quarters ) {
properties.quarters = {};
}
if ( !properties.quarters[ chr ] ) {
properties.quarters[ chr ] = {};
}
properties.quarters[ chr ][ length ] = cldr.main([
"dates/calendars/gregorian/quarters",
chr === "Q" ? "format" : "stand-alone",
widths[ length - 3 ]
]);
}
break;

@@ -752,36 +600,29 @@

case "L":
// number l=1:{1,2}, l=2:{2}.
// lookup l=3...
oneOrTwoDigitsIfLengthOne() || twoDigitsIfLengthTwo() || lookup([
"dates/calendars/gregorian/months",
chr === "M" ? "format" : "stand-alone",
widths[ length - 3 ]
]);
break;
// Day (see d below)
case "D":
// number {l,3}.
if ( length <= 3 ) {
tokenRe = new RegExp( "\\d{" + length + ",3}" );
if ( length > 2 ) {
if ( !properties.months ) {
properties.months = {};
}
if ( !properties.months[ chr ] ) {
properties.months[ chr ] = {};
}
properties.months[ chr ][ length ] = cldr.main([
"dates/calendars/gregorian/months",
chr === "M" ? "format" : "stand-alone",
widths[ length - 3 ]
]);
}
break;
// Week - Week of Year (w) or Week of Month (W).
case "w":
case "W":
case "F":
// number l=1:{1}.
oneDigitIfLengthOne();
properties.firstDay = dateFirstDayOfWeek( cldr );
properties.minDays = cldr.supplemental.weekData.minDays();
break;
case "g+":
// Modified Julian day. Need to be implemented.
throw new Error( "Not implemented" );
// Week day
case "e":
case "c":
// number l=1:{1}, l=2:{2}.
// lookup for length >=3.
if ( length <= 2 ) {
oneDigitIfLengthOne() || twoDigitsIfLengthTwo();
properties.firstDay = dateFirstDayOfWeek( cldr );
break;

@@ -792,18 +633,27 @@ }

case "E":
if ( !properties.days ) {
properties.days = {};
}
if ( !properties.days[ chr ] ) {
properties.days[ chr ] = {};
}
if ( length === 6 ) {
// Note: if short day names are not explicitly specified, abbreviated day
// names are used instead http://www.unicode.org/reports/tr35/tr35-dates.html#months_days_quarters_eras
lookup([
"dates/calendars/gregorian/days",
[ chr === "c" ? "stand-alone" : "format" ],
"short"
]) || lookup([
"dates/calendars/gregorian/days",
[ chr === "c" ? "stand-alone" : "format" ],
"abbreviated"
]);
// If short day names are not explicitly specified, abbreviated day names are
// used instead.
// http://www.unicode.org/reports/tr35/tr35-dates.html#months_days_quarters_eras
// http://unicode.org/cldr/trac/ticket/6790
properties.days[ chr ][ length ] = cldr.main([
"dates/calendars/gregorian/days",
chr === "c" ? "stand-alone" : "format",
"short"
]) || cldr.main([
"dates/calendars/gregorian/days",
chr === "c" ? "stand-alone" : "format",
"abbreviated"
]);
} else {
lookup([
properties.days[ chr ][ length ] = cldr.main([
"dates/calendars/gregorian/days",
[ chr === "c" ? "stand-alone" : "format" ],
chr === "c" ? "stand-alone" : "format",
widths[ length < 3 ? 0 : length - 3 ]

@@ -816,31 +666,7 @@ ]);

case "a":
lookup([
properties.dayPeriods = cldr.main(
"dates/calendars/gregorian/dayPeriods/format/wide"
]);
);
break;
// Week, Day, Hour, Minute, or Second
case "w":
case "d":
case "h":
case "H":
case "K":
case "k":
case "j":
case "m":
case "s":
// number l1:{1,2}, l2:{2}.
oneOrTwoDigitsIfLengthOne() || twoDigitsIfLengthTwo();
break;
case "S":
// number {l}.
tokenRe = new RegExp( "\\d{" + length + "}" );
break;
case "A":
// number {l+5}.
tokenRe = new RegExp( "\\d{" + ( length + 5 ) + "}" );
break;
// Zone

@@ -857,36 +683,6 @@ // see http://www.unicode.org/reports/tr35/tr35-dates.html#Using_Time_Zone_Names ?

throw new Error( "Not implemented" );
case "'":
token.type = "literal";
if ( current.charAt( 1 ) === "'" ) {
tokenRe = /'/;
} else {
tokenRe = /'[^']+'/;
}
break;
default:
token.type = "literal";
tokenRe = /./;
}
if ( !tokenRe ) {
return false;
}
// Get lexeme and consume it.
value = value.replace( new RegExp( "^" + tokenRe.source ), function( lexeme ) {
token.lexeme = lexeme;
return "";
});
if ( !token.lexeme ) {
return false;
}
tokens.push( token );
return true;
});
return valid ? tokens : [];
return properties;
};

@@ -936,7 +732,13 @@

/**
* parse
* parse( value, tokens, properties )
*
* @value [String] string date.
*
* @tokens [Object] tokens returned by date/tokenizer.
*
* @properties [Object] output returned by date/tokenizer-properties.
*
* ref: http://www.unicode.org/reports/tr35/tr35-dates.html#Date_Format_Patterns
*/
return function( value, pattern, cldr ) {
return function( value, tokens, properties ) {
var amPm, era, hour, hour12, valid,

@@ -951,3 +753,2 @@ YEAR = 0,

date = new Date(),
tokens = dateTokenizer( value, pattern, cldr ),
truncateAt = [],

@@ -974,3 +775,3 @@ units = [ "year", "month", "day", "hour", "minute", "second", "milliseconds" ];

// http://www.unicode.org/reports/tr35/tr35-dates.html#Time_Data
chr = cldr.supplemental.timeData.preferred();
chr = properties.preferredTimeData;
}

@@ -1197,2 +998,390 @@

/**
* parseProperties( cldr )
*
* @cldr [Cldr instance].
*
* Return parser properties.
*/
var dateParseProperties = function( cldr ) {
return {
preferredTimeData: cldr.supplemental.timeData.preferred()
};
};
/**
* tokenizer( value, pattern, properties )
*
* @value [String] string date.
*
* @properties [Object] output returned by date/tokenizer-properties.
*
* Returns an Array of tokens, eg. value "5 o'clock PM", pattern "h 'o''clock' a":
* [{
* type: "h",
* lexeme: "5"
* }, {
* type: "literal",
* lexeme: " "
* }, {
* type: "literal",
* lexeme: "o'clock"
* }, {
* type: "literal",
* lexeme: " "
* }, {
* type: "a",
* lexeme: "PM",
* value: "pm"
* }]
*
* OBS: lexeme's are always String and may return invalid ranges depending of the token type.
* Eg. "99" for month number.
*
* Return an empty Array when not successfully parsed.
*/
var dateTokenizer = function( value, properties ) {
var valid,
tokens = [],
widths = [ "abbreviated", "wide", "narrow" ];
valid = properties.pattern.match( datePatternRe ).every(function( current ) {
var chr, length, tokenRe,
token = {};
function oneDigitIfLengthOne() {
if ( length === 1 ) {
return tokenRe = /\d/;
}
}
function oneOrTwoDigitsIfLengthOne() {
if ( length === 1 ) {
return tokenRe = /\d\d?/;
}
}
function twoDigitsIfLengthTwo() {
if ( length === 2 ) {
return tokenRe = /\d\d/;
}
}
// Brute-force test every locale entry in an attempt to match the given value.
// Return the first found one (and set token accordingly), or null.
function lookup( path ) {
var i, re,
data = properties[ path.join( "/" ).replace( /^.*calendars\//, "" ) ];
for ( i in data ) {
re = new RegExp( "^" + data[ i ] );
if ( re.test( value ) ) {
token.value = i;
return tokenRe = new RegExp( data[ i ] );
}
}
return null;
}
token.type = current;
chr = current.charAt( 0 ),
length = current.length;
switch ( chr ) {
// Era
case "G":
lookup([
"dates/calendars/gregorian/eras",
length <= 3 ? "eraAbbr" : ( length === 4 ? "eraNames" : "eraNarrow" )
]);
break;
// Year
case "y":
case "Y":
// number l=1:+, l=2:{2}, l=3:{3,}, l=4:{4,}, ...
if ( length === 1 ) {
tokenRe = /\d+/;
} else if ( length === 2 ) {
tokenRe = /\d\d/;
} else {
tokenRe = new RegExp( "\\d{" + length + ",}" );
}
break;
case "u": // Extended year. Need to be implemented.
case "U": // Cyclic year name. Need to be implemented.
throw new Error( "Not implemented" );
// Quarter
case "Q":
case "q":
// number l=1:{1}, l=2:{2}.
// lookup l=3...
oneDigitIfLengthOne() || twoDigitsIfLengthTwo() || lookup([
"dates/calendars/gregorian/quarters",
chr === "Q" ? "format" : "stand-alone",
widths[ length - 3 ]
]);
break;
// Month
case "M":
case "L":
// number l=1:{1,2}, l=2:{2}.
// lookup l=3...
oneOrTwoDigitsIfLengthOne() || twoDigitsIfLengthTwo() || lookup([
"dates/calendars/gregorian/months",
chr === "M" ? "format" : "stand-alone",
widths[ length - 3 ]
]);
break;
// Day (see d below)
case "D":
// number {l,3}.
if ( length <= 3 ) {
tokenRe = new RegExp( "\\d{" + length + ",3}" );
}
break;
case "W":
case "F":
// number l=1:{1}.
oneDigitIfLengthOne();
break;
case "g+":
// Modified Julian day. Need to be implemented.
throw new Error( "Not implemented" );
// Week day
case "e":
case "c":
// number l=1:{1}, l=2:{2}.
// lookup for length >=3.
if ( length <= 2 ) {
oneDigitIfLengthOne() || twoDigitsIfLengthTwo();
break;
}
/* falls through */
case "E":
if ( length === 6 ) {
// Note: if short day names are not explicitly specified, abbreviated day
// names are used instead http://www.unicode.org/reports/tr35/tr35-dates.html#months_days_quarters_eras
lookup([
"dates/calendars/gregorian/days",
[ chr === "c" ? "stand-alone" : "format" ],
"short"
]) || lookup([
"dates/calendars/gregorian/days",
[ chr === "c" ? "stand-alone" : "format" ],
"abbreviated"
]);
} else {
lookup([
"dates/calendars/gregorian/days",
[ chr === "c" ? "stand-alone" : "format" ],
widths[ length < 3 ? 0 : length - 3 ]
]);
}
break;
// Period (AM or PM)
case "a":
lookup([
"dates/calendars/gregorian/dayPeriods/format/wide"
]);
break;
// Week, Day, Hour, Minute, or Second
case "w":
case "d":
case "h":
case "H":
case "K":
case "k":
case "j":
case "m":
case "s":
// number l1:{1,2}, l2:{2}.
oneOrTwoDigitsIfLengthOne() || twoDigitsIfLengthTwo();
break;
case "S":
// number {l}.
tokenRe = new RegExp( "\\d{" + length + "}" );
break;
case "A":
// number {l+5}.
tokenRe = new RegExp( "\\d{" + ( length + 5 ) + "}" );
break;
// Zone
// see http://www.unicode.org/reports/tr35/tr35-dates.html#Using_Time_Zone_Names ?
// Need to be implemented.
case "z":
case "Z":
case "O":
case "v":
case "V":
case "X":
case "x":
throw new Error( "Not implemented" );
case "'":
token.type = "literal";
if ( current.charAt( 1 ) === "'" ) {
tokenRe = /'/;
} else {
tokenRe = /'[^']+'/;
}
break;
default:
token.type = "literal";
tokenRe = /./;
}
if ( !tokenRe ) {
return false;
}
// Get lexeme and consume it.
value = value.replace( new RegExp( "^" + tokenRe.source ), function( lexeme ) {
token.lexeme = lexeme;
return "";
});
if ( !token.lexeme ) {
return false;
}
tokens.push( token );
return true;
});
return valid ? tokens : [];
};
/**
* tokenizerProperties( pattern, cldr )
*
* @pattern [String] raw pattern.
*
* @cldr [Cldr instance].
*
* Return Object with data that will be used by tokenizer.
*/
var dateTokenizerProperties = function( pattern, cldr ) {
var properties = {
pattern: pattern
},
widths = [ "abbreviated", "wide", "narrow" ];
function populateProperties( path, value ) {
properties[ path.replace( /^.*calendars\//, "" ) ] = value;
}
cldr.on( "get", populateProperties );
pattern.match( datePatternRe ).forEach(function( current ) {
var chr, length;
chr = current.charAt( 0 ),
length = current.length;
switch ( chr ) {
// Era
case "G":
cldr.main([
"dates/calendars/gregorian/eras",
length <= 3 ? "eraAbbr" : ( length === 4 ? "eraNames" : "eraNarrow" )
]);
break;
// Quarter
case "Q":
case "q":
if ( length > 2 ) {
cldr.main([
"dates/calendars/gregorian/quarters",
chr === "Q" ? "format" : "stand-alone",
widths[ length - 3 ]
]);
}
break;
// Month
case "M":
case "L":
// number l=1:{1,2}, l=2:{2}.
// lookup l=3...
if ( length > 2 ) {
cldr.main([
"dates/calendars/gregorian/months",
chr === "M" ? "format" : "stand-alone",
widths[ length - 3 ]
]);
}
break;
// Week day
case "e":
case "c":
// lookup for length >=3.
if ( length <= 2 ) {
break;
}
/* falls through */
case "E":
if ( length === 6 ) {
// Note: if short day names are not explicitly specified, abbreviated day
// names are used instead http://www.unicode.org/reports/tr35/tr35-dates.html#months_days_quarters_eras
cldr.main([
"dates/calendars/gregorian/days",
[ chr === "c" ? "stand-alone" : "format" ],
"short"
]) || cldr.main([
"dates/calendars/gregorian/days",
[ chr === "c" ? "stand-alone" : "format" ],
"abbreviated"
]);
} else {
cldr.main([
"dates/calendars/gregorian/days",
[ chr === "c" ? "stand-alone" : "format" ],
widths[ length < 3 ? 0 : length - 3 ]
]);
}
break;
// Period (AM or PM)
case "a":
cldr.main([
"dates/calendars/gregorian/dayPeriods/format/wide"
]);
break;
}
});
cldr.off( "get", populateProperties );
return properties;
};
function validateRequiredCldr( path, value ) {

@@ -1209,17 +1398,21 @@ validateCldr( path, value, {

/**
* .formatDate( value, pattern )
* .dateFormatter( pattern )
*
* @pattern [String or Object] see date/expand_pattern for more info.
*
* Return a date formatter function (of the form below) according to the given pattern and the
* default/instance locale.
*
* fn( value )
*
* @value [Date]
*
* @pattern [String or Object] see date/expand_pattern for more info.
*
* Formats a date or number according to the given pattern string and the default/instance locale.
* Return a function that formats a date according to the given `format` and the default/instance
* locale.
*/
Globalize.formatDate =
Globalize.prototype.formatDate = function( value, pattern ) {
var cldr, ret;
Globalize.dateFormatter =
Globalize.prototype.dateFormatter = function( pattern ) {
var cldr, properties;
validateParameterPresence( value, "value" );
validateParameterPresence( pattern, "pattern" );
validateParameterTypeDate( value, "value" );
validateParameterTypeDatePattern( pattern, "pattern" );

@@ -1233,24 +1426,26 @@

pattern = dateExpandPattern( pattern, cldr );
ret = dateFormat( value, pattern, cldr );
properties = dateFormatProperties( pattern, cldr );
cldr.off( "get", validateRequiredCldr );
return ret;
return function( value ) {
validateParameterPresence( value, "value" );
validateParameterTypeDate( value, "value" );
return dateFormat( value, properties );
};
};
/**
* .parseDate( value, patterns )
* .dateParser( pattern )
*
* @value [String]
* @pattern [String or Object] see date/expand_pattern for more info.
*
* @patterns [Array] Optional. See date/expand_pattern for more info about each pattern. Defaults
* to the list of all presets defined in the locale (see date/all_presets for more info).
*
* Return a Date instance or null.
* Return a function that parses a string date according to the given `formats` and the
* default/instance locale.
*/
Globalize.parseDate =
Globalize.prototype.parseDate = function( value, patterns ) {
var cldr, date;
Globalize.dateParser =
Globalize.prototype.dateParser = function( pattern ) {
var cldr, parseProperties, tokenizerProperties;
validateParameterPresence( value, "value" );
validateParameterTypeString( value, "value" );
validateParameterPresence( pattern, "pattern" );
validateParameterTypeDatePattern( pattern, "pattern" );

@@ -1262,21 +1457,52 @@ cldr = this.cldr;

cldr.on( "get", validateRequiredCldr );
pattern = dateExpandPattern( pattern, cldr );
tokenizerProperties = dateTokenizerProperties( pattern, cldr );
parseProperties = dateParseProperties( cldr );
cldr.off( "get", validateRequiredCldr );
if ( !patterns ) {
patterns = dateAllPresets( cldr );
} else {
patterns = alwaysArray( patterns );
}
return function( value ) {
var tokens;
patterns.some(function( pattern ) {
validateParameterTypeDatePattern( pattern, "patterns" );
pattern = dateExpandPattern( pattern, cldr );
date = dateParse( value, pattern, cldr );
return !!date;
});
validateParameterPresence( value, "value" );
validateParameterTypeString( value, "value" );
cldr.off( "get", validateRequiredCldr );
tokens = dateTokenizer( value, tokenizerProperties );
return dateParse( value, tokens, parseProperties ) || null;
};
};
return date || null;
/**
* .formatDate( value, pattern )
*
* @value [Date]
*
* @pattern [String or Object] see date/expand_pattern for more info.
*
* Formats a date or number according to the given pattern string and the default/instance locale.
*/
Globalize.formatDate =
Globalize.prototype.formatDate = function( value, pattern ) {
validateParameterPresence( value, "value" );
validateParameterTypeDate( value, "value" );
return this.dateFormatter( pattern )( value );
};
/**
* .parseDate( value, pattern )
*
* @value [String]
*
* @pattern [String or Object] see date/expand_pattern for more info.
*
* Return a Date instance or null.
*/
Globalize.parseDate =
Globalize.prototype.parseDate = function( value, pattern ) {
validateParameterPresence( value, "value" );
validateParameterTypeString( value, "value" );
return this.dateParser( pattern )( value );
};
return Globalize;

@@ -1283,0 +1509,0 @@

/*!
* Globalize v1.0.0-alpha.6 2014-09-01T21:32Z Released under the MIT license
* Globalize v1.0.0-alpha.7 2014-09-30T12:31Z Released under the MIT license
* http://git.io/TrdQbw
*/
!function(a,b){"function"==typeof define&&define.amd?define(["cldr","../globalize","cldr/event","cldr/supplemental"],b):"object"==typeof exports?module.exports=b(require("cldrjs"),require("globalize")):b(a.Cldr,a.Globalize)}(this,function(a,b){function c(a,b){h(a,b,{skip:[/dates\/calendars\/gregorian\/days\/.*\/short/,/supplemental\/timeData\/(?!001)/,/supplemental\/weekData\/(?!001)/]})}var d=b._alwaysArray,e=b._createError,f=b._formatMessage,g=b._isPlainObject,h=b._validateCldr,i=b._validateDefaultLocale,j=b._validateParameterPresence,k=b._validateParameterType,l=function(a,b){k(a,b,void 0===a||a instanceof Date,"Date")},m=function(a,b){k(a,b,void 0===a||"string"==typeof a||g(a),"String or plain Object")},n=function(a,b){k(a,b,void 0===a||"string"==typeof a,"a string")},o=function(a){var b,c=[];for(b in a)c.push(a[b]);return c},p=function(a){var b=[];return b=o(a.main("dates/calendars/gregorian/dateTimeFormats/availableFormats")),b=b.concat(o(a.main("dates/calendars/gregorian/timeFormats"))),b=b.concat(o(a.main("dates/calendars/gregorian/dateFormats"))),b=b.concat(o(a.main("dates/calendars/gregorian/dateTimeFormats")).map(function(b,c){return"string"!=typeof b?b:f(b,[a.main(["dates/calendars/gregorian/timeFormats",c]),a.main(["dates/calendars/gregorian/dateFormats",c])])})),b.map(function(a){return{pattern:a}})},q=function(a,b){return e("E_INVALID_PAR_VALUE","Invalid `{name}` value ({value}).",{name:a,value:b})},r=function(a,b){var c;switch("string"==typeof a&&(a={skeleton:a}),!0){case"skeleton"in a:c=b.main(["dates/calendars/gregorian/dateTimeFormats/availableFormats",a.skeleton]);break;case"date"in a:case"time"in a:c=b.main(["dates/calendars/gregorian","date"in a?"dateFormats":"timeFormats",a.date||a.time]);break;case"datetime"in a:c=b.main(["dates/calendars/gregorian/dateTimeFormats",a.datetime]),c&&(c=f(c,[b.main(["dates/calendars/gregorian/timeFormats",a.datetime]),b.main(["dates/calendars/gregorian/dateFormats",a.datetime])]));break;case"pattern"in a:c=a.pattern;break;default:throw q({name:"pattern",value:a})}return c},s=["sun","mon","tue","wed","thu","fri","sat"],t=function(a){return s.indexOf(a.supplemental.weekData.firstDay())},u=function(a,b){return(a.getDay()-t(b)+7)%7},v=function(a,b){var c=864e5;return(b.getTime()-a.getTime())/c},w=function(a,b){switch(a=new Date(a.getTime()),b){case"year":a.setMonth(0);case"month":a.setDate(1);case"day":a.setHours(0);case"hour":a.setMinutes(0);case"minute":a.setSeconds(0);case"second":a.setMilliseconds(0)}return a},x=function(a){return Math.floor(v(w(a,"year"),a))},y=function(a){return a-w(a,"day")},z=/([a-z])\1*|'[^']+'|''|./gi,A=function(a,b,c){var d;for("string"!=typeof a&&(a=String(a)),d=a.length;b>d;d+=1)a=c?a+"0":"0"+a;return a},B=function(a,b,c){var d=["abbreviated","wide","narrow"];return b.replace(z,function(b){var e,f,g=b.charAt(0),h=b.length;switch("j"===g&&(g=c.supplemental.timeData.preferred()),g){case"G":f=c.main(["dates/calendars/gregorian/eras",3>=h?"eraAbbr":4===h?"eraNames":"eraNarrow",a.getFullYear()<0?0:1]);break;case"y":f=String(a.getFullYear()),e=!0,2===h&&(f=f.substr(f.length-2));break;case"Y":f=new Date(a.getTime()),f.setDate(f.getDate()+7-u(a,c)-t(c)-c.supplemental.weekData.minDays()),f=String(f.getFullYear()),e=!0,2===h&&(f=f.substr(f.length-2));break;case"u":case"U":throw new Error("Not implemented");case"Q":case"q":f=Math.ceil((a.getMonth()+1)/3),2>=h?e=!0:f=c.main(["dates/calendars/gregorian/quarters","Q"===g?"format":"stand-alone",d[h-3],f]);break;case"M":case"L":f=a.getMonth()+1,2>=h?e=!0:f=c.main(["dates/calendars/gregorian/months","M"===g?"format":"stand-alone",d[h-3],f]);break;case"w":f=u(w(a,"year"),c),f=Math.ceil((x(a)+f)/7)-(7-f>=c.supplemental.weekData.minDays()?0:1),e=!0;break;case"W":f=u(w(a,"month"),c),f=Math.ceil((a.getDate()+f)/7)-(7-f>=c.supplemental.weekData.minDays()?0:1);break;case"d":f=a.getDate(),e=!0;break;case"D":f=x(a)+1,e=!0;break;case"F":f=Math.floor(a.getDate()/7)+1;break;case"g+":throw new Error("Not implemented");case"e":case"c":if(2>=h){f=u(a,c)+1,e=!0;break}case"E":f=s[a.getDay()],f=6===h?c.main(["dates/calendars/gregorian/days","c"===g?"stand-alone":"format","short",f])||c.main(["dates/calendars/gregorian/days","c"===g?"stand-alone":"format","abbreviated",f]):c.main(["dates/calendars/gregorian/days","c"===g?"stand-alone":"format",d[3>h?0:h-3],f]);break;case"a":f=c.main(["dates/calendars/gregorian/dayPeriods/format/wide",a.getHours()<12?"am":"pm"]);break;case"h":f=a.getHours()%12||12,e=!0;break;case"H":f=a.getHours(),e=!0;break;case"K":f=a.getHours()%12,e=!0;break;case"k":f=a.getHours()||24,e=!0;break;case"m":f=a.getMinutes(),e=!0;break;case"s":f=a.getSeconds(),e=!0;break;case"S":f=Math.round(a.getMilliseconds()*Math.pow(10,h-3)),e=!0;break;case"A":f=Math.round(y(a)*Math.pow(10,h-3)),e=!0;break;case"z":case"Z":case"O":case"v":case"V":case"X":case"x":throw new Error("Not implemented");default:return b}return e&&(f=A(f,h)),f})},C=function(a,b,c){var d,e=[],f=["abbreviated","wide","narrow"];return d=b.match(z).every(function(b){function d(){return 1===k?l=/\d/:void 0}function g(){return 1===k?l=/\d\d?/:void 0}function h(){return 2===k?l=/\d\d/:void 0}function i(b){var d,e,f=c.main(b);for(d in f)if(e=new RegExp("^"+f[d]),e.test(a))return m.value=d,l=new RegExp(f[d]);return null}var j,k,l,m={};switch(m.type=b,j=b.charAt(0),k=b.length,j){case"G":i(["dates/calendars/gregorian/eras",3>=k?"eraAbbr":4===k?"eraNames":"eraNarrow"]);break;case"y":case"Y":l=1===k?/\d+/:2===k?/\d\d/:new RegExp("\\d{"+k+",}");break;case"u":case"U":throw new Error("Not implemented");case"Q":case"q":d()||h()||i(["dates/calendars/gregorian/quarters","Q"===j?"format":"stand-alone",f[k-3]]);break;case"M":case"L":g()||h()||i(["dates/calendars/gregorian/months","M"===j?"format":"stand-alone",f[k-3]]);break;case"D":3>=k&&(l=new RegExp("\\d{"+k+",3}"));break;case"W":case"F":d();break;case"g+":throw new Error("Not implemented");case"e":case"c":if(2>=k){d()||h();break}case"E":6===k?i(["dates/calendars/gregorian/days",["c"===j?"stand-alone":"format"],"short"])||i(["dates/calendars/gregorian/days",["c"===j?"stand-alone":"format"],"abbreviated"]):i(["dates/calendars/gregorian/days",["c"===j?"stand-alone":"format"],f[3>k?0:k-3]]);break;case"a":i(["dates/calendars/gregorian/dayPeriods/format/wide"]);break;case"w":case"d":case"h":case"H":case"K":case"k":case"j":case"m":case"s":g()||h();break;case"S":l=new RegExp("\\d{"+k+"}");break;case"A":l=new RegExp("\\d{"+(k+5)+"}");break;case"z":case"Z":case"O":case"v":case"V":case"X":case"x":throw new Error("Not implemented");case"'":m.type="literal",l="'"===b.charAt(1)?/'/:/'[^']+'/;break;default:m.type="literal",l=/./}return l?(a=a.replace(new RegExp("^"+l.source),function(a){return m.lexeme=a,""}),m.lexeme?(e.push(m),!0):!1):!1}),d?e:[]},D=function(a,b){var c=new Date(a.getFullYear(),a.getMonth()+1,0).getDate();a.setDate(1>b?1:c>b?b:c)},E=function(a,b){var c=a.getDate();a.setDate(1),a.setMonth(b),D(a,c)},F=function(){function a(a,b,c){return b>a||a>c}return function(b,c,d){var e,f,g,h,i,j=0,k=1,l=2,m=3,n=4,o=5,p=6,q=new Date,r=C(b,c,d),s=[],t=["year","month","day","hour","minute","second","milliseconds"];return r.length&&(i=r.every(function(b){var c,i,r,t;if("literal"===b.type)return!0;switch(i=b.type.charAt(0),t=b.type.length,"j"===i&&(i=d.supplemental.timeData.preferred()),i){case"G":s.push(j),f=+b.value;break;case"y":if(r=+b.lexeme,2===t){if(a(r,0,99))return!1;c=100*Math.floor(q.getFullYear()/100),r+=c,r>q.getFullYear()+20&&(r-=100)}q.setFullYear(r),s.push(j);break;case"Y":case"u":case"U":throw new Error("Not implemented");case"Q":case"q":break;case"M":case"L":if(r=2>=t?+b.lexeme:+b.value,a(r,1,12))return!1;E(q,r-1),s.push(k);break;case"w":case"W":break;case"d":if(r=+b.lexeme,a(r,1,31))return!1;D(q,r),s.push(l);break;case"D":if(r=+b.lexeme,a(r,1,366))return!1;q.setMonth(0),q.setDate(r),s.push(l);break;case"F":break;case"g+":throw new Error("Not implemented");case"e":case"c":case"E":break;case"a":e=b.value;break;case"h":if(r=+b.lexeme,a(r,1,12))return!1;g=h=!0,q.setHours(12===r?0:r),s.push(m);break;case"K":if(r=+b.lexeme,a(r,0,11))return!1;g=h=!0,q.setHours(r),s.push(m);break;case"k":if(r=+b.lexeme,a(r,1,24))return!1;g=!0,q.setHours(24===r?0:r),s.push(m);break;case"H":if(r=+b.lexeme,a(r,0,23))return!1;g=!0,q.setHours(r),s.push(m);break;case"m":if(r=+b.lexeme,a(r,0,59))return!1;q.setMinutes(r),s.push(n);break;case"s":if(r=+b.lexeme,a(r,0,59))return!1;q.setSeconds(r),s.push(o);break;case"A":q.setHours(0),q.setMinutes(0),q.setSeconds(0);case"S":r=Math.round(+b.lexeme*Math.pow(10,3-t)),q.setMilliseconds(r),s.push(p);break;case"z":case"Z":case"O":case"v":case"V":case"X":case"x":throw new Error("Not implemented")}return!0}))&&(!g||!e^h)?(0===f&&q.setFullYear(-1*q.getFullYear()+1),h&&"pm"===e&&q.setHours(q.getHours()+12),s=Math.max.apply(null,s),q=w(q,t[s])):null}}();return b.formatDate=b.prototype.formatDate=function(a,b){var d,e;return j(a,"value"),j(b,"pattern"),l(a,"value"),m(b,"pattern"),d=this.cldr,i(d),d.on("get",c),b=r(b,d),e=B(a,b,d),d.off("get",c),e},b.parseDate=b.prototype.parseDate=function(a,b){var e,f;return j(a,"value"),n(a,"value"),e=this.cldr,i(e),e.on("get",c),b=b?d(b):p(e),b.some(function(b){return m(b,"patterns"),b=r(b,e),f=F(a,b,e),!!f}),e.off("get",c),f||null},b});
!function(a,b){"function"==typeof define&&define.amd?define(["cldr","../globalize","cldr/event","cldr/supplemental"],b):"object"==typeof exports?module.exports=b(require("cldrjs"),require("globalize")):b(a.Cldr,a.Globalize)}(this,function(a,b){function c(a,b){g(a,b,{skip:[/dates\/calendars\/gregorian\/days\/.*\/short/,/supplemental\/timeData\/(?!001)/,/supplemental\/weekData\/(?!001)/]})}var d=b._createError,e=b._formatMessage,f=b._isPlainObject,g=b._validateCldr,h=b._validateDefaultLocale,i=b._validateParameterPresence,j=b._validateParameterType,k=function(a,b){j(a,b,void 0===a||a instanceof Date,"Date")},l=function(a,b){j(a,b,void 0===a||"string"==typeof a||f(a),"String or plain Object")},m=function(a,b){j(a,b,void 0===a||"string"==typeof a,"a string")},n=function(a,b){return d("E_INVALID_PAR_VALUE","Invalid `{name}` value ({value}).",{name:a,value:b})},o=function(a,b){var c;switch("string"==typeof a&&(a={skeleton:a}),!0){case"skeleton"in a:c=b.main(["dates/calendars/gregorian/dateTimeFormats/availableFormats",a.skeleton]);break;case"date"in a:case"time"in a:c=b.main(["dates/calendars/gregorian","date"in a?"dateFormats":"timeFormats",a.date||a.time]);break;case"datetime"in a:c=b.main(["dates/calendars/gregorian/dateTimeFormats",a.datetime]),c&&(c=e(c,[b.main(["dates/calendars/gregorian/timeFormats",a.datetime]),b.main(["dates/calendars/gregorian/dateFormats",a.datetime])]));break;case"pattern"in a:c=a.pattern;break;default:throw n({name:"pattern",value:a})}return c},p=function(a,b){return(a.getDay()-b+7)%7},q=function(a,b){var c=864e5;return(b.getTime()-a.getTime())/c},r=function(a,b){switch(a=new Date(a.getTime()),b){case"year":a.setMonth(0);case"month":a.setDate(1);case"day":a.setHours(0);case"hour":a.setMinutes(0);case"minute":a.setSeconds(0);case"second":a.setMilliseconds(0)}return a},s=function(a){return Math.floor(q(r(a,"year"),a))},t=["sun","mon","tue","wed","thu","fri","sat"],u=function(a){return t.indexOf(a.supplemental.weekData.firstDay())},v=function(a){return a-r(a,"day")},w=/([a-z])\1*|'[^']+'|''|./gi,x=function(a,b,c){var d;for("string"!=typeof a&&(a=String(a)),d=a.length;b>d;d+=1)a=c?a+"0":"0"+a;return a},y=function(a,b){return b.pattern.replace(w,function(c){var d,e,f=c.charAt(0),g=c.length;switch("j"===f&&(f=b.preferredTime),f){case"G":e=b.eras[a.getFullYear()<0?0:1];break;case"y":e=String(a.getFullYear()),d=!0,2===g&&(e=e.substr(e.length-2));break;case"Y":e=new Date(a.getTime()),e.setDate(e.getDate()+7-p(a,b.firstDay)-b.firstDay-b.minDays),e=String(e.getFullYear()),d=!0,2===g&&(e=e.substr(e.length-2));break;case"u":case"U":throw new Error("Not implemented");case"Q":case"q":e=Math.ceil((a.getMonth()+1)/3),2>=g?d=!0:e=b.quarters[f][g][e];break;case"M":case"L":e=a.getMonth()+1,2>=g?d=!0:e=b.months[f][g][e];break;case"w":e=p(r(a,"year"),b.firstDay),e=Math.ceil((s(a)+e)/7)-(7-e>=b.minDays?0:1),d=!0;break;case"W":e=p(r(a,"month"),b.firstDay),e=Math.ceil((a.getDate()+e)/7)-(7-e>=b.minDays?0:1);break;case"d":e=a.getDate(),d=!0;break;case"D":e=s(a)+1,d=!0;break;case"F":e=Math.floor(a.getDate()/7)+1;break;case"g+":throw new Error("Not implemented");case"e":case"c":if(2>=g){e=p(a,b.firstDay)+1,d=!0;break}case"E":e=t[a.getDay()],e=b.days[f][g][e];break;case"a":e=b.dayPeriods[a.getHours()<12?"am":"pm"];break;case"h":e=a.getHours()%12||12,d=!0;break;case"H":e=a.getHours(),d=!0;break;case"K":e=a.getHours()%12,d=!0;break;case"k":e=a.getHours()||24,d=!0;break;case"m":e=a.getMinutes(),d=!0;break;case"s":e=a.getSeconds(),d=!0;break;case"S":e=Math.round(a.getMilliseconds()*Math.pow(10,g-3)),d=!0;break;case"A":e=Math.round(v(a)*Math.pow(10,g-3)),d=!0;break;case"z":case"Z":case"O":case"v":case"V":case"X":case"x":throw new Error("Not implemented");default:return c}return d&&(e=x(e,g)),e})},z=function(a,b){var c={},d=["abbreviated","wide","narrow"];return c.pattern=a,a.replace(w,function(a){var e=a.charAt(0),f=a.length;switch("j"===e&&(c.preferredTime=e=b.supplemental.timeData.preferred()),e){case"G":c.eras=b.main(["dates/calendars/gregorian/eras",3>=f?"eraAbbr":4===f?"eraNames":"eraNarrow"]);break;case"Y":c.firstDay=u(b),c.minDays=b.supplemental.weekData.minDays();break;case"u":case"U":throw new Error("Not implemented");case"Q":case"q":f>2&&(c.quarters||(c.quarters={}),c.quarters[e]||(c.quarters[e]={}),c.quarters[e][f]=b.main(["dates/calendars/gregorian/quarters","Q"===e?"format":"stand-alone",d[f-3]]));break;case"M":case"L":f>2&&(c.months||(c.months={}),c.months[e]||(c.months[e]={}),c.months[e][f]=b.main(["dates/calendars/gregorian/months","M"===e?"format":"stand-alone",d[f-3]]));break;case"w":case"W":c.firstDay=u(b),c.minDays=b.supplemental.weekData.minDays();break;case"e":case"c":if(2>=f){c.firstDay=u(b);break}case"E":c.days||(c.days={}),c.days[e]||(c.days[e]={}),c.days[e][f]=6===f?b.main(["dates/calendars/gregorian/days","c"===e?"stand-alone":"format","short"])||b.main(["dates/calendars/gregorian/days","c"===e?"stand-alone":"format","abbreviated"]):b.main(["dates/calendars/gregorian/days","c"===e?"stand-alone":"format",d[3>f?0:f-3]]);break;case"a":c.dayPeriods=b.main("dates/calendars/gregorian/dayPeriods/format/wide");break;case"z":case"Z":case"O":case"v":case"V":case"X":case"x":throw new Error("Not implemented")}}),c},A=function(a,b){var c=new Date(a.getFullYear(),a.getMonth()+1,0).getDate();a.setDate(1>b?1:c>b?b:c)},B=function(a,b){var c=a.getDate();a.setDate(1),a.setMonth(b),A(a,c)},C=function(){function a(a,b,c){return b>a||a>c}return function(b,c,d){var e,f,g,h,i,j=0,k=1,l=2,m=3,n=4,o=5,p=6,q=new Date,s=[],t=["year","month","day","hour","minute","second","milliseconds"];return c.length&&(i=c.every(function(b){var c,i,r,t;if("literal"===b.type)return!0;switch(i=b.type.charAt(0),t=b.type.length,"j"===i&&(i=d.preferredTimeData),i){case"G":s.push(j),f=+b.value;break;case"y":if(r=+b.lexeme,2===t){if(a(r,0,99))return!1;c=100*Math.floor(q.getFullYear()/100),r+=c,r>q.getFullYear()+20&&(r-=100)}q.setFullYear(r),s.push(j);break;case"Y":case"u":case"U":throw new Error("Not implemented");case"Q":case"q":break;case"M":case"L":if(r=2>=t?+b.lexeme:+b.value,a(r,1,12))return!1;B(q,r-1),s.push(k);break;case"w":case"W":break;case"d":if(r=+b.lexeme,a(r,1,31))return!1;A(q,r),s.push(l);break;case"D":if(r=+b.lexeme,a(r,1,366))return!1;q.setMonth(0),q.setDate(r),s.push(l);break;case"F":break;case"g+":throw new Error("Not implemented");case"e":case"c":case"E":break;case"a":e=b.value;break;case"h":if(r=+b.lexeme,a(r,1,12))return!1;g=h=!0,q.setHours(12===r?0:r),s.push(m);break;case"K":if(r=+b.lexeme,a(r,0,11))return!1;g=h=!0,q.setHours(r),s.push(m);break;case"k":if(r=+b.lexeme,a(r,1,24))return!1;g=!0,q.setHours(24===r?0:r),s.push(m);break;case"H":if(r=+b.lexeme,a(r,0,23))return!1;g=!0,q.setHours(r),s.push(m);break;case"m":if(r=+b.lexeme,a(r,0,59))return!1;q.setMinutes(r),s.push(n);break;case"s":if(r=+b.lexeme,a(r,0,59))return!1;q.setSeconds(r),s.push(o);break;case"A":q.setHours(0),q.setMinutes(0),q.setSeconds(0);case"S":r=Math.round(+b.lexeme*Math.pow(10,3-t)),q.setMilliseconds(r),s.push(p);break;case"z":case"Z":case"O":case"v":case"V":case"X":case"x":throw new Error("Not implemented")}return!0}))&&(!g||!e^h)?(0===f&&q.setFullYear(-1*q.getFullYear()+1),h&&"pm"===e&&q.setHours(q.getHours()+12),s=Math.max.apply(null,s),q=r(q,t[s])):null}}(),D=function(a){return{preferredTimeData:a.supplemental.timeData.preferred()}},E=function(a,b){var c,d=[],e=["abbreviated","wide","narrow"];return c=b.pattern.match(w).every(function(c){function f(){return 1===k?l=/\d/:void 0}function g(){return 1===k?l=/\d\d?/:void 0}function h(){return 2===k?l=/\d\d/:void 0}function i(c){var d,e,f=b[c.join("/").replace(/^.*calendars\//,"")];for(d in f)if(e=new RegExp("^"+f[d]),e.test(a))return m.value=d,l=new RegExp(f[d]);return null}var j,k,l,m={};switch(m.type=c,j=c.charAt(0),k=c.length,j){case"G":i(["dates/calendars/gregorian/eras",3>=k?"eraAbbr":4===k?"eraNames":"eraNarrow"]);break;case"y":case"Y":l=1===k?/\d+/:2===k?/\d\d/:new RegExp("\\d{"+k+",}");break;case"u":case"U":throw new Error("Not implemented");case"Q":case"q":f()||h()||i(["dates/calendars/gregorian/quarters","Q"===j?"format":"stand-alone",e[k-3]]);break;case"M":case"L":g()||h()||i(["dates/calendars/gregorian/months","M"===j?"format":"stand-alone",e[k-3]]);break;case"D":3>=k&&(l=new RegExp("\\d{"+k+",3}"));break;case"W":case"F":f();break;case"g+":throw new Error("Not implemented");case"e":case"c":if(2>=k){f()||h();break}case"E":6===k?i(["dates/calendars/gregorian/days",["c"===j?"stand-alone":"format"],"short"])||i(["dates/calendars/gregorian/days",["c"===j?"stand-alone":"format"],"abbreviated"]):i(["dates/calendars/gregorian/days",["c"===j?"stand-alone":"format"],e[3>k?0:k-3]]);break;case"a":i(["dates/calendars/gregorian/dayPeriods/format/wide"]);break;case"w":case"d":case"h":case"H":case"K":case"k":case"j":case"m":case"s":g()||h();break;case"S":l=new RegExp("\\d{"+k+"}");break;case"A":l=new RegExp("\\d{"+(k+5)+"}");break;case"z":case"Z":case"O":case"v":case"V":case"X":case"x":throw new Error("Not implemented");case"'":m.type="literal",l="'"===c.charAt(1)?/'/:/'[^']+'/;break;default:m.type="literal",l=/./}return l?(a=a.replace(new RegExp("^"+l.source),function(a){return m.lexeme=a,""}),m.lexeme?(d.push(m),!0):!1):!1}),c?d:[]},F=function(a,b){function c(a,b){d[a.replace(/^.*calendars\//,"")]=b}var d={pattern:a},e=["abbreviated","wide","narrow"];return b.on("get",c),a.match(w).forEach(function(a){var c,d;switch(c=a.charAt(0),d=a.length,c){case"G":b.main(["dates/calendars/gregorian/eras",3>=d?"eraAbbr":4===d?"eraNames":"eraNarrow"]);break;case"Q":case"q":d>2&&b.main(["dates/calendars/gregorian/quarters","Q"===c?"format":"stand-alone",e[d-3]]);break;case"M":case"L":d>2&&b.main(["dates/calendars/gregorian/months","M"===c?"format":"stand-alone",e[d-3]]);break;case"e":case"c":if(2>=d)break;case"E":6===d?b.main(["dates/calendars/gregorian/days",["c"===c?"stand-alone":"format"],"short"])||b.main(["dates/calendars/gregorian/days",["c"===c?"stand-alone":"format"],"abbreviated"]):b.main(["dates/calendars/gregorian/days",["c"===c?"stand-alone":"format"],e[3>d?0:d-3]]);break;case"a":b.main(["dates/calendars/gregorian/dayPeriods/format/wide"])}}),b.off("get",c),d};return b.dateFormatter=b.prototype.dateFormatter=function(a){var b,d;return i(a,"pattern"),l(a,"pattern"),b=this.cldr,h(b),b.on("get",c),a=o(a,b),d=z(a,b),b.off("get",c),function(a){return i(a,"value"),k(a,"value"),y(a,d)}},b.dateParser=b.prototype.dateParser=function(a){var b,d,e;return i(a,"pattern"),l(a,"pattern"),b=this.cldr,h(b),b.on("get",c),a=o(a,b),e=F(a,b),d=D(b),b.off("get",c),function(a){var b;return i(a,"value"),m(a,"value"),b=E(a,e),C(a,b,d)||null}},b.formatDate=b.prototype.formatDate=function(a,b){return i(a,"value"),k(a,"value"),this.dateFormatter(b)(a)},b.parseDate=b.prototype.parseDate=function(a,b){return i(a,"value"),m(a,"value"),this.dateParser(b)(a)},b});
/*!
* Globalize v1.0.0-alpha.6
* Globalize v1.0.0-alpha.7
*

@@ -10,3 +10,3 @@ * http://github.com/jquery/globalize

*
* Date: 2014-09-01T21:32Z
* Date: 2014-09-30T12:31Z
*/

@@ -13,0 +13,0 @@ (function( root, factory ) {

/*!
* Globalize v1.0.0-alpha.6 2014-09-01T21:32Z Released under the MIT license
* Globalize v1.0.0-alpha.7 2014-09-30T12:31Z Released under the MIT license
* http://git.io/TrdQbw
*/
!function(a,b){"function"==typeof define&&define.amd?define(["cldr","../globalize"],b):"object"==typeof exports?module.exports=b(require("cldrjs"),require("globalize")):b(a.Cldr,a.Globalize)}(this,function(a,b){var c=b._alwaysArray,d=b._validateDefaultLocale,e=b._validateParameterPresence,f=b._validateParameterType,g=b._validateParameterTypePlainObject;return b.loadTranslations=function(b){var c={"globalize-translations":b};e(b,"json"),g(b,"json"),a.load(c)},b.translate=b.prototype.translate=function(a){var b;return e(a,"path"),f(a,"path","string"==typeof a||Array.isArray(a),"a String nor an Array"),a=c(a),b=this.cldr,d(b),b.get(["globalize-translations/{languageId}"].concat(a))},b});
/*!
* Globalize v1.0.0-alpha.6
* Globalize v1.0.0-alpha.7
*

@@ -10,3 +10,3 @@ * http://github.com/jquery/globalize

*
* Date: 2014-09-01T21:32Z
* Date: 2014-09-30T12:31Z
*/

@@ -273,2 +273,109 @@ (function( root, factory ) {

/**
* format( number, properties )
*
* @number [Number].
*
* @properties [Object] Output of number/format-properties.
*
* Return the formatted number.
* ref: http://www.unicode.org/reports/tr35/tr35-numbers.html
*/
var numberFormat = function( number, properties ) {
var infinitySymbol, maximumFractionDigits, maximumSignificantDigits, minimumFractionDigits,
minimumIntegerDigits, minimumSignificantDigits, nanSymbol, padding, prefix,
primaryGroupingSize, pattern, ret, round, roundIncrement, secondaryGroupingSize, suffix,
symbolMap;
padding = properties[ 1 ];
minimumIntegerDigits = properties[ 2 ];
minimumFractionDigits = properties[ 3 ];
maximumFractionDigits = properties[ 4 ];
minimumSignificantDigits = properties[ 5 ];
maximumSignificantDigits = properties[ 6 ];
roundIncrement = properties[ 7 ];
primaryGroupingSize = properties[ 8 ];
secondaryGroupingSize = properties[ 9 ];
round = properties[ 15 ];
infinitySymbol = properties[ 16 ];
nanSymbol = properties[ 17 ];
symbolMap = properties[ 18 ];
// NaN
if ( isNaN( number ) ) {
return nanSymbol;
}
if ( number < 0 ) {
pattern = properties[ 12 ];
prefix = properties[ 13 ];
suffix = properties[ 14 ];
} else {
pattern = properties[ 11 ];
prefix = properties[ 0 ];
suffix = properties[ 10 ];
}
// Infinity
if ( !isFinite( number ) ) {
return prefix + infinitySymbol + suffix;
}
ret = prefix;
// Percent
if ( pattern.indexOf( "%" ) !== -1 ) {
number *= 100;
// Per mille
} else if ( pattern.indexOf( "\u2030" ) !== -1 ) {
number *= 1000;
}
// Significant digit format
if ( !isNaN( minimumSignificantDigits * maximumSignificantDigits ) ) {
number = numberFormatSignificantDigits( number, minimumSignificantDigits,
maximumSignificantDigits, round );
// Integer and fractional format
} else {
number = numberFormatIntegerFractionDigits( number, minimumIntegerDigits,
minimumFractionDigits, maximumFractionDigits, round, roundIncrement );
}
// Remove the possible number minus sign
number = number.replace( /^-/, "" );
// Grouping separators
if ( primaryGroupingSize ) {
number = numberFormatGroupingSeparator( number, primaryGroupingSize,
secondaryGroupingSize );
}
ret += number;
// Scientific notation
if ( false ) {
throw new Error( "Scientific notation not implemented" );
}
// Padding
if ( false ) {
throw new Error( "Padding not implemented" );
}
ret += suffix;
// Symbols
return ret.replace( /'[^']+'|[.,\-+E%\u2030]/g, function( symbol ) {
if ( symbol.charAt( 0 ) === "'" ) {
return symbol;
}
return symbolMap[ symbol ];
});
};
/**
* EBNF representation:

@@ -493,2 +600,28 @@ *

/**
* symbolMap( cldr )
*
* @cldr [Cldr instance].
*
* Return the (localized symbol, pattern symbol) key value pair, eg. {
* ".": "٫",
* ",": "٬",
* "%": "٪",
* ...
* };
*/
var numberSymbolMap = function( cldr ) {
var symbol,
symbolMap = {};
for ( symbol in numberSymbolName ) {
symbolMap[ symbol ] = numberSymbol( numberSymbolName[ symbol ], cldr );
}
return symbolMap;
};
/**
* round( method )

@@ -525,6 +658,4 @@ *

/**
* format( number, pattern, cldr [, options] )
* formatProperties( pattern, cldr [, options] )
*
* @number [Number].
*
* @pattern [String] raw pattern for numbers.

@@ -541,129 +672,69 @@ *

*
* Return the formatted number.
* Return the processed properties that will be used in number/format.
* ref: http://www.unicode.org/reports/tr35/tr35-numbers.html
*/
var numberFormat = function( number, pattern, cldr, options ) {
var maximumFractionDigits, maximumSignificantDigits, minimumFractionDigits,
minimumIntegerDigits, minimumSignificantDigits, padding, prefix, primaryGroupingSize,
properties, ret, round, roundIncrement, secondaryGroupingSize, suffix;
var numberFormatProperties = function( pattern, cldr, options ) {
var negativePattern, negativePrefix, negativeProperties, negativeSuffix, positivePattern,
properties;
// NaN
if ( isNaN( number ) ) {
return numberSymbol( "nan", cldr );
function getOptions( attribute, propertyIndex ) {
if ( attribute in options ) {
properties[ propertyIndex ] = options[ attribute ];
}
}
options = options || {};
pattern = pattern.split( ";" );
function getOptions( property, defaultValue ) {
return property in options ? options[ property ] : defaultValue;
}
positivePattern = pattern[ 0 ];
options = options || {};
round = numberRound( options.round );
properties = numberPatternProperties( pattern[ 0 ] );
padding = properties[ 1 ];
minimumIntegerDigits = getOptions( "minimumIntegerDigits", properties[ 2 ] );
minimumIntegerDigits = getOptions( "minimumIntegerDigits", properties[ 2 ] );
minimumFractionDigits = getOptions( "minimumFractionDigits", properties[ 3 ] );
maximumFractionDigits = getOptions( "maximumFractionDigits", properties[ 4 ] );
minimumSignificantDigits = getOptions( "minimumSignificantDigits", properties[ 5 ] );
maximumSignificantDigits = getOptions( "maximumSignificantDigits", properties[ 6 ] );
roundIncrement = properties[ 7 ];
primaryGroupingSize = properties[ 8 ];
secondaryGroupingSize = properties[ 9 ];
negativePattern = pattern[ 1 ] || "-" + positivePattern;
negativeProperties = numberPatternProperties( negativePattern );
negativePrefix = negativeProperties[ 0 ];
negativeSuffix = negativeProperties[ 10 ];
// Negative pattern
// "If there is an explicit negative subpattern, it serves only to specify the negative prefix
// and suffix" UTS#35
if ( number < 0 ) {
properties = numberPatternProperties( positivePattern ).concat([
positivePattern,
negativePrefix + positivePattern + negativeSuffix,
negativePrefix,
negativeSuffix,
numberRound( options.round ),
numberSymbol( "infinity", cldr ),
numberSymbol( "nan", cldr ),
numberSymbolMap( cldr )
]);
// "If there is no explicit negative subpattern, the negative subpattern is the localized
// minus sign prefixed to the positive subpattern" UTS#35
pattern = pattern[ 1 ] || "-" + pattern[ 0 ];
properties = numberPatternProperties( pattern );
} else {
pattern = pattern[ 0 ];
}
getOptions( "minimumIntegerDigits", 2 );
getOptions( "minimumFractionDigits", 3 );
getOptions( "maximumFractionDigits", 4 );
getOptions( "minimumSignificantDigits", 5 );
getOptions( "maximumSignificantDigits", 6 );
prefix = properties[ 0 ];
suffix = properties[ 10 ];
// Infinity (observe that isNaN() has been checked above)
if ( !isFinite( number ) ) {
return prefix + numberSymbol( "infinity", cldr ) + suffix;
}
ret = prefix;
// Percent
if ( pattern.indexOf( "%" ) !== -1 ) {
number *= 100;
// Per mille
} else if ( pattern.indexOf( "\u2030" ) !== -1 ) {
number *= 1000;
}
// Significant digit format
if ( !isNaN( minimumSignificantDigits * maximumSignificantDigits ) ) {
validateParameterRange( minimumSignificantDigits, "minimumSignificantDigits", 1, 21 );
validateParameterRange( maximumSignificantDigits, "maximumSignificantDigits",
minimumSignificantDigits, 21 );
number = numberFormatSignificantDigits( number, minimumSignificantDigits,
maximumSignificantDigits, round );
} else if ( !isNaN( minimumSignificantDigits ) || !isNaN( maximumSignificantDigits ) ) {
throw new Error( "Neither or both the minimum and maximum significant digits must be " +
"present" );
// Integer and fractional format
} else {
// Normalize number of digits if only one of either minimumFractionDigits or
// maximumFractionDigits is passed in as an option
if ( "minimumFractionDigits" in options && !( "maximumFractionDigits" in options ) ) {
maximumFractionDigits = Math.max( minimumFractionDigits, maximumFractionDigits );
} else if ( !( "minimumFractionDigits" in options ) &&
"maximumFractionDigits" in options ) {
minimumFractionDigits = Math.min( minimumFractionDigits, maximumFractionDigits );
}
validateParameterRange( minimumIntegerDigits, "minimumIntegerDigits", 1, 21 );
validateParameterRange( minimumFractionDigits, "minimumFractionDigits", 0, 20 );
validateParameterRange( maximumFractionDigits, "maximumFractionDigits",
minimumFractionDigits, 20 );
number = numberFormatIntegerFractionDigits( number, minimumIntegerDigits,
minimumFractionDigits, maximumFractionDigits, round, roundIncrement );
}
// Remove the possible number minus sign
number = number.replace( /^-/, "" );
// Grouping separators
if ( primaryGroupingSize && !( "useGrouping" in options && !options.useGrouping ) ) {
number = numberFormatGroupingSeparator( number, primaryGroupingSize,
secondaryGroupingSize );
if ( options.useGrouping === false ) {
properties[ 8 ] = null;
}
ret += number;
// Scientific notation
if ( false ) {
throw new Error( "Scientific notation not implemented" );
// Normalize number of digits if only one of either minimumFractionDigits or
// maximumFractionDigits is passed in as an option
if ( "minimumFractionDigits" in options && !( "maximumFractionDigits" in options ) ) {
// maximumFractionDigits = Math.max( minimumFractionDigits, maximumFractionDigits );
properties[ 4 ] = Math.max( properties[ 3 ], properties[ 4 ] );
} else if ( !( "minimumFractionDigits" in options ) &&
"maximumFractionDigits" in options ) {
// minimumFractionDigits = Math.min( minimumFractionDigits, maximumFractionDigits );
properties[ 3 ] = Math.min( properties[ 3 ], properties[ 4 ] );
}
// Padding
if ( false ) {
throw new Error( "Padding not implemented" );
}
ret += suffix;
// Symbols
return ret.replace( /'[^']+'|[.,\-+E%\u2030]/g, function( symbol ) {
if ( symbol.charAt( 0 ) === "'" ) {
return symbol;
}
return numberSymbol( numberSymbolName[ symbol ], cldr );
});
// Return:
// 0-10: see number/pattern-properties.
// 11: @positivePattern [String] Positive pattern.
// 12: @negativePattern [String] Negative pattern.
// 13: @negativePrefix [String] Negative prefix.
// 14: @negativeSuffix [String] Negative suffix.
// 15: @round [Function] Round function.
// 16: @infinitySymbol [String] Infinity symbol.
// 17: @nanSymbol [String] NaN symbol.
// 18: @symbolMap [Object] A bunch of other symbols.
return properties;
};

@@ -714,28 +785,2 @@

/**
* symbolMap( cldr )
*
* @cldr [Cldr instance].
*
* Return the (localized symbol, pattern symbol) key value pair, eg. {
* "٫": ".",
* "٬": ",",
* "٪": "%",
* ...
* };
*/
var numberSymbolMap = function( cldr ) {
var symbol,
symbolMap = {};
for ( symbol in numberSymbolName ) {
symbolMap[ numberSymbol( numberSymbolName[ symbol ], cldr ) ] = symbol;
}
return symbolMap;
};
// ref: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions?redirectlocale=en-US&redirectslug=JavaScript%2FGuide%2FRegular_Expressions

@@ -750,7 +795,8 @@ var regexpEscape = function( string ) {

/**
* parse( value, cldr )
* parse( value, properties )
*
* @value [String].
*
* @cldr [Cldr instance].
* @properties [Object] Parser properties is a reduced pre-processed cldr
* data set returned by numberParserProperties().
*

@@ -760,7 +806,13 @@ * Return the parsed Number (including Infinity) or NaN when value is invalid.

*/
var numberParse = function( value, pattern, cldr ) {
var aux, localizedSymbolsRe, number, prefix, properties, suffix, symbolMap;
var numberParse = function( value, properties ) {
var aux, infinitySymbol, invertedSymbolMap, localizedSymbolsRe, negativePrefix, negativeSuffix,
number, prefix, suffix;
infinitySymbol = properties[ 0 ];
invertedSymbolMap = properties[ 1 ];
negativePrefix = properties[ 2 ];
negativeSuffix = properties[ 3 ];
// Infinite number.
if ( aux = value.match( numberSymbol( "infinity", cldr ) ) ) {
if ( aux = value.match( infinitySymbol ) ) {

@@ -774,10 +826,12 @@ number = Infinity;

symbolMap = numberSymbolMap( cldr );
localizedSymbolsRe = new RegExp( Object.keys( symbolMap ).map(function( localizedSymbol ) {
return regexpEscape( localizedSymbol );
}).join( "|" ), "g" );
localizedSymbolsRe = new RegExp(
Object.keys( invertedSymbolMap ).map(function( localizedSymbol ) {
return regexpEscape( localizedSymbol );
}).join( "|" ),
"g"
);
// Reverse localized symbols.
value = value.replace( localizedSymbolsRe, function( localizedSymbol ) {
return symbolMap[ localizedSymbol ];
return invertedSymbolMap[ localizedSymbol ];
});

@@ -816,2 +870,3 @@

number /= 100;
suffix = suffix.replace( "%", "" );

@@ -821,2 +876,3 @@ // Per mille

number /= 1000;
suffix = suffix.replace( "\u2030", "" );
}

@@ -829,5 +885,3 @@ }

// localized minus sign prefixed to the positive subpattern" UTS#35
pattern = pattern.split( ";" );
properties = numberPatternProperties( pattern[ 1 ] || pattern[ 0 ] );
if ( prefix === ( pattern[ 1 ] ? "" : "-" ) + properties[ 0 ] && suffix === properties[ 10 ] ) {
if ( prefix === negativePrefix && suffix === negativeSuffix ) {
number *= -1;

@@ -843,2 +897,59 @@ }

/**
* symbolMap( cldr )
*
* @cldr [Cldr instance].
*
* Return the (localized symbol, pattern symbol) key value pair, eg. {
* "٫": ".",
* "٬": ",",
* "٪": "%",
* ...
* };
*/
var numberSymbolInvertedMap = function( cldr ) {
var symbol,
symbolMap = {};
for ( symbol in numberSymbolName ) {
symbolMap[ numberSymbol( numberSymbolName[ symbol ], cldr ) ] = symbol;
}
return symbolMap;
};
/**
* parseProperties( pattern, cldr )
*
* @pattern [String] raw pattern for numbers.
*
* @cldr [Cldr instance].
*
* Return parser properties, used to feed parser function.
*/
var numberParseProperties = function( pattern, cldr ) {
var negativePattern, negativeProperties;
pattern = pattern.split( ";" );
negativePattern = pattern[ 1 ] || "-" + pattern[ 0 ];
negativeProperties = numberPatternProperties( negativePattern );
// 0: @infinitySymbol [String] Infinity symbol.
// 1: @invertedSymbolMap [Object] Inverted symbol map.
// 2: @negativePrefix [String] Negative prefix.
// 3: @negativeSuffix [String] Negative suffix with percent or per mille stripped out.
return [
numberSymbol( "infinity", cldr ),
numberSymbolInvertedMap( cldr ),
negativeProperties[ 0 ],
negativeProperties[ 10 ].replace( "%", "" ).replace( "\u2030", "" )
];
};
/**
* Pattern( style )

@@ -866,21 +977,19 @@ *

/**
* .formatNumber( value, pattern )
* .numberFormatter( [options] )
*
* @value [Number]
*
* @attributes [Object]:
* @options [Object]:
* - style: [String] "decimal" (default) or "percent".
* - see also number/format options.
*
* Format a number according to the given attributes and default/instance locale.
* Return a function that formats a number according to the given options and default/instance
* locale.
*/
Globalize.formatNumber =
Globalize.prototype.formatNumber = function( value, attributes ) {
var cldr, pattern, ret;
Globalize.numberFormatter =
Globalize.prototype.numberFormatter = function( options ) {
var cldr, maximumFractionDigits, maximumSignificantDigits, minimumFractionDigits,
minimumIntegerDigits, minimumSignificantDigits, pattern, properties;
validateParameterPresence( value, "value" );
validateParameterTypeNumber( value, "value" );
validateParameterTypePlainObject( attributes, "attributes" );
validateParameterTypePlainObject( options, "options" );
attributes = attributes || {};
options = options || {};
cldr = this.cldr;

@@ -892,27 +1001,57 @@

if ( !attributes.pattern ) {
pattern = numberPattern( attributes.style || "decimal", cldr );
if ( !options.pattern ) {
pattern = numberPattern( options.style || "decimal", cldr );
}
ret = numberFormat( value, pattern, cldr, attributes );
properties = numberFormatProperties( pattern, cldr, options );
cldr.off( "get", validateCldr );
return ret;
minimumIntegerDigits = properties[ 2 ];
minimumFractionDigits = properties[ 3 ];
maximumFractionDigits = properties[ 4 ];
minimumSignificantDigits = properties[ 5 ];
maximumSignificantDigits = properties[ 6 ];
// Validate significant digit format properties
if ( !isNaN( minimumSignificantDigits * maximumSignificantDigits ) ) {
validateParameterRange( minimumSignificantDigits, "minimumSignificantDigits", 1, 21 );
validateParameterRange( maximumSignificantDigits, "maximumSignificantDigits",
minimumSignificantDigits, 21 );
} else if ( !isNaN( minimumSignificantDigits ) || !isNaN( maximumSignificantDigits ) ) {
throw new Error( "Neither or both the minimum and maximum significant digits must be " +
"present" );
// Validate integer and fractional format
} else {
validateParameterRange( minimumIntegerDigits, "minimumIntegerDigits", 1, 21 );
validateParameterRange( minimumFractionDigits, "minimumFractionDigits", 0, 20 );
validateParameterRange( maximumFractionDigits, "maximumFractionDigits",
minimumFractionDigits, 20 );
}
return function( value ) {
validateParameterPresence( value, "value" );
validateParameterTypeNumber( value, "value" );
return numberFormat( value, properties );
};
};
/**
* .parseNumber( value )
* .numberParser( [options] )
*
* @value [String]
* @options [Object]:
* - style: [String] "decimal" (default) or "percent".
*
* Return the parsed Number (including Infinity) or NaN when value is invalid.
* Return the number parser according to the default/instance locale.
*/
Globalize.parseNumber =
Globalize.prototype.parseNumber = function( value ) {
var cldr, pattern, ret;
Globalize.numberParser =
Globalize.prototype.numberParser = function( options ) {
var cldr, pattern, properties;
validateParameterPresence( value, "value" );
validateParameterTypeString( value, "value" );
validateParameterTypePlainObject( options, "options" );
options = options || {};
cldr = this.cldr;

@@ -924,12 +1063,51 @@

// TODO: What about per mille? Which "style" does it belong to?
pattern = numberPattern( value.indexOf( "%" ) !== -1 ? "percent" : "decimal", cldr );
if ( !options.pattern ) {
pattern = numberPattern( options.style || "decimal", cldr );
}
ret = numberParse( value, pattern, cldr );
properties = numberParseProperties( pattern, cldr );
cldr.off( "get", validateCldr );
return ret;
return function( value ) {
validateParameterPresence( value, "value" );
validateParameterTypeString( value, "value" );
return numberParse( value, properties );
};
};
/**
* .formatNumber( value [, options] )
*
* @value [Number] number to be formatted.
*
* @options [Object]: see number/format-properties.
*
* Format a number according to the given options and default/instance locale.
*/
Globalize.formatNumber =
Globalize.prototype.formatNumber = function( value, options ) {
validateParameterPresence( value, "value" );
validateParameterTypeNumber( value, "value" );
return this.numberFormatter( options )( value );
};
/**
* .parseNumber( value [, options] )
*
* @value [String]
*
* @options [Object]: See numberParser().
*
* Return the parsed Number (including Infinity) or NaN when value is invalid.
*/
Globalize.parseNumber =
Globalize.prototype.parseNumber = function( value, options ) {
validateParameterPresence( value, "value" );
validateParameterTypeString( value, "value" );
return this.numberParser( options )( value );
};
return Globalize;

@@ -936,0 +1114,0 @@

/*!
* Globalize v1.0.0-alpha.6 2014-09-01T21:32Z Released under the MIT license
* Globalize v1.0.0-alpha.7 2014-09-30T12:31Z Released under the MIT license
* http://git.io/TrdQbw
*/
!function(a,b){"function"==typeof define&&define.amd?define(["cldr","../globalize","cldr/event"],b):"object"==typeof exports?module.exports=b(require("cldrjs"),require("globalize")):b(a.Cldr,a.Globalize)}(this,function(a,b){var c=b._validateCldr,d=b._validateDefaultLocale,e=b._validateParameterPresence,f=b._validateParameterRange,g=b._validateParameterType,h=b._validateParameterTypePlainObject,i=function(a,b){g(a,b,void 0===a||"number"==typeof a,"Number")},j=function(a,b){g(a,b,void 0===a||"string"==typeof a,"a string")},k=function(a,b,c){var d,e=b,f="",g=",",h=c?!0:!1;for(a=String(a).split("."),d=a[0].length;d>e;)f=a[0].slice(d-e,d)+(f.length?g:"")+f,d-=e,h&&(e=c,h=!1);return a[0]=a[0].slice(0,d)+(f.length?g:"")+f,a.join(".")},l=function(a){return isNaN(a)?0/0:Math[0>a?"ceil":"floor"](a)},m=function(a,b,c){var d;for("string"!=typeof a&&(a=String(a)),d=a.length;b>d;d+=1)a=c?a+"0":"0"+a;return a},n=function(a,b,c,d,e,f){return d?(a=f?e(a,f):e(a,Math.pow(10,-d)),a=+a.toFixed(d),c&&(a=String(a).split("."),a[1]=m(a[1]||"",c,!0),a=a.join("."))):a=l(a),a=String(a),b&&(a=a.split("."),a[0]=m(a[0],b),a=a.join(".")),a},o=function(a,b,c){var d,e;return a=a.toPrecision(b+2),d=Math.ceil(Math.log(Math.abs(a))/Math.log(10)),d-=b,e=Math.pow(10,d),a=c(a,e),0>d&&(a=+a.toFixed(-d)),a},p=function(a,b,c,d){var e,f;if(b>c&&(c=b),e=o(a,b,d),f=o(a,c,d),a=+e===+f?e:f,a=(+a).toString(10),/e/.test(a))throw new Error("Ops! Integers out of (1e21, 1e-7) not supported");return b-a.replace(/^0+|\./g,"").length>0&&(a=a.split("."),a[1]=m(a[1]||"",b-a[0].replace(/^0+/,"").length,!0),a=a.join(".")),a},q=/^(('[^']+'|''|[^*#@0,.E])*)(\*.)?((([#,]*[0,]*0+)(\.0*[0-9]*#*)?)|([#,]*@+#*))(E\+?0+)?(('[^']+'|''|[^*#@0,.E])*)$/,r=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,r,s,t;if(a=a.match(q),!a)throw new Error("Invalid pattern: "+a);if(m=a[1],l=a[3],e=a[4],s=a[8],p=a[9],t=a[10],s?s.replace(/(@+)(#*)/,function(a,b,c){k=b.length,h=k+c.length}):(d=a[7],f=a[6],d&&(d.replace(/[0-9]+/,function(a){i=a}),i?(o=+("0."+i),i=i.length):i=0,g=d.length-1),f.replace(/0+$/,function(a){j=a.length})),p)throw new Error("Scientific notation not implemented");if(l)throw new Error("Padding not implemented");return-1!==(b=e.lastIndexOf(","))&&(c=e.split(".")[0],n=c.length-b-1,-1!==(c=e.lastIndexOf(",",b-1))&&(r=b-1-c)),[m,l,j,i,g,k,h,o,n,r,t]},s=function(a){return a.main("numbers/defaultNumberingSystem")},t=function(a,b){return b.main(["numbers/symbols-numberSystem-"+s(b),a])},u={".":"decimal",",":"group","%":"percentSign","+":"plusSign","-":"minusSign",E:"exponential","‰":"perMille"},v=function(a){return a=a||"round",a="truncate"===a?l:Math[a],function(b,c){return c=c||1,a(b/c)*c}},w=function(a,b,c,d){function e(a,b){return a in d?d[a]:b}var g,h,i,j,l,m,o,q,s,w,x,y,z,A;if(isNaN(a))return t("nan",c);if(b=b.split(";"),d=d||{},x=v(d.round),s=r(b[0]),m=s[1],j=e("minimumIntegerDigits",s[2]),j=e("minimumIntegerDigits",s[2]),i=e("minimumFractionDigits",s[3]),g=e("maximumFractionDigits",s[4]),l=e("minimumSignificantDigits",s[5]),h=e("maximumSignificantDigits",s[6]),y=s[7],q=s[8],z=s[9],0>a?(b=b[1]||"-"+b[0],s=r(b)):b=b[0],o=s[0],A=s[10],!isFinite(a))return o+t("infinity",c)+A;if(w=o,-1!==b.indexOf("%")?a*=100:-1!==b.indexOf("‰")&&(a*=1e3),isNaN(l*h)){if(!isNaN(l)||!isNaN(h))throw new Error("Neither or both the minimum and maximum significant digits must be present");"minimumFractionDigits"in d&&!("maximumFractionDigits"in d)?g=Math.max(i,g):!("minimumFractionDigits"in d)&&"maximumFractionDigits"in d&&(i=Math.min(i,g)),f(j,"minimumIntegerDigits",1,21),f(i,"minimumFractionDigits",0,20),f(g,"maximumFractionDigits",i,20),a=n(a,j,i,g,x,y)}else f(l,"minimumSignificantDigits",1,21),f(h,"maximumSignificantDigits",l,21),a=p(a,l,h,x);return a=a.replace(/^-/,""),!q||"useGrouping"in d&&!d.useGrouping||(a=k(a,q,z)),w+=a,w+=A,w.replace(/'[^']+'|[.,\-+E%\u2030]/g,function(a){return"'"===a.charAt(0)?a:t(u[a],c)})},x=/^([^0-9]*)(([0-9,]*[0-9]+)(\.[0-9]+)?)(E[+-]?[0-9]+)?([^0-9]*)$/,y=function(a){var b,c={};for(b in u)c[t(u[b],a)]=b;return c},z=function(a){return a.replace(/([.*+?^=!:${}()|\[\]\/\\])/g,"\\$1")},A=function(a,b,c){var d,e,f,g,h,i,j;if(d=a.match(t("infinity",c)))f=1/0,g=a.slice(0,d.length),i=a.slice(d.length+1);else{if(j=y(c),e=new RegExp(Object.keys(j).map(function(a){return z(a)}).join("|"),"g"),a=a.replace(e,function(a){return j[a]}),a=a.match(x),!a)return 0/0;if(g=a[1],i=a[6],f=a[2].replace(/,/g,""),a[5]&&(f+=a[5]),f=+f,isNaN(f))return 0/0;-1!==a[0].indexOf("%")?f/=100:-1!==a[0].indexOf("‰")&&(f/=1e3)}return b=b.split(";"),h=r(b[1]||b[0]),g===(b[1]?"":"-")+h[0]&&i===h[10]&&(f*=-1),f},B=function(a,b){if("decimal"!==a&&"percent"!==a)throw new Error("Invalid style");return b.main(["numbers",a+"Formats-numberSystem-"+s(b),"standard"])};return b.formatNumber=b.prototype.formatNumber=function(a,b){var f,g,j;return e(a,"value"),i(a,"value"),h(b,"attributes"),b=b||{},f=this.cldr,d(f),f.on("get",c),b.pattern||(g=B(b.style||"decimal",f)),j=w(a,g,f,b),f.off("get",c),j},b.parseNumber=b.prototype.parseNumber=function(a){var b,f,g;return e(a,"value"),j(a,"value"),b=this.cldr,d(b),b.on("get",c),f=B(-1!==a.indexOf("%")?"percent":"decimal",b),g=A(a,f,b),b.off("get",c),g},b});
!function(a,b){"function"==typeof define&&define.amd?define(["cldr","../globalize","cldr/event"],b):"object"==typeof exports?module.exports=b(require("cldrjs"),require("globalize")):b(a.Cldr,a.Globalize)}(this,function(a,b){var c=b._validateCldr,d=b._validateDefaultLocale,e=b._validateParameterPresence,f=b._validateParameterRange,g=b._validateParameterType,h=b._validateParameterTypePlainObject,i=function(a,b){g(a,b,void 0===a||"number"==typeof a,"Number")},j=function(a,b){g(a,b,void 0===a||"string"==typeof a,"a string")},k=function(a,b,c){var d,e=b,f="",g=",",h=c?!0:!1;for(a=String(a).split("."),d=a[0].length;d>e;)f=a[0].slice(d-e,d)+(f.length?g:"")+f,d-=e,h&&(e=c,h=!1);return a[0]=a[0].slice(0,d)+(f.length?g:"")+f,a.join(".")},l=function(a){return isNaN(a)?0/0:Math[0>a?"ceil":"floor"](a)},m=function(a,b,c){var d;for("string"!=typeof a&&(a=String(a)),d=a.length;b>d;d+=1)a=c?a+"0":"0"+a;return a},n=function(a,b,c,d,e,f){return d?(a=f?e(a,f):e(a,Math.pow(10,-d)),a=+a.toFixed(d),c&&(a=String(a).split("."),a[1]=m(a[1]||"",c,!0),a=a.join("."))):a=l(a),a=String(a),b&&(a=a.split("."),a[0]=m(a[0],b),a=a.join(".")),a},o=function(a,b,c){var d,e;return a=a.toPrecision(b+2),d=Math.ceil(Math.log(Math.abs(a))/Math.log(10)),d-=b,e=Math.pow(10,d),a=c(a,e),0>d&&(a=+a.toFixed(-d)),a},p=function(a,b,c,d){var e,f;if(b>c&&(c=b),e=o(a,b,d),f=o(a,c,d),a=+e===+f?e:f,a=(+a).toString(10),/e/.test(a))throw new Error("Ops! Integers out of (1e21, 1e-7) not supported");return b-a.replace(/^0+|\./g,"").length>0&&(a=a.split("."),a[1]=m(a[1]||"",b-a[0].replace(/^0+/,"").length,!0),a=a.join(".")),a},q=function(a,b){var c,d,e,f,g,h,i,j,l,m,o,q,r,s,t,u,v;return j=b[1],g=b[2],f=b[3],d=b[4],h=b[5],e=b[6],s=b[7],m=b[8],t=b[9],r=b[15],c=b[16],i=b[17],v=b[18],isNaN(a)?i:(0>a?(o=b[12],l=b[13],u=b[14]):(o=b[11],l=b[0],u=b[10]),isFinite(a)?(q=l,-1!==o.indexOf("%")?a*=100:-1!==o.indexOf("‰")&&(a*=1e3),a=isNaN(h*e)?n(a,g,f,d,r,s):p(a,h,e,r),a=a.replace(/^-/,""),m&&(a=k(a,m,t)),q+=a,q+=u,q.replace(/'[^']+'|[.,\-+E%\u2030]/g,function(a){return"'"===a.charAt(0)?a:v[a]})):l+c+u)},r=/^(('[^']+'|''|[^*#@0,.E])*)(\*.)?((([#,]*[0,]*0+)(\.0*[0-9]*#*)?)|([#,]*@+#*))(E\+?0+)?(('[^']+'|''|[^*#@0,.E])*)$/,s=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,s,t;if(a=a.match(r),!a)throw new Error("Invalid pattern: "+a);if(m=a[1],l=a[3],e=a[4],s=a[8],p=a[9],t=a[10],s?s.replace(/(@+)(#*)/,function(a,b,c){k=b.length,h=k+c.length}):(d=a[7],f=a[6],d&&(d.replace(/[0-9]+/,function(a){i=a}),i?(o=+("0."+i),i=i.length):i=0,g=d.length-1),f.replace(/0+$/,function(a){j=a.length})),p)throw new Error("Scientific notation not implemented");if(l)throw new Error("Padding not implemented");return-1!==(b=e.lastIndexOf(","))&&(c=e.split(".")[0],n=c.length-b-1,-1!==(c=e.lastIndexOf(",",b-1))&&(q=b-1-c)),[m,l,j,i,g,k,h,o,n,q,t]},t=function(a){return a.main("numbers/defaultNumberingSystem")},u=function(a,b){return b.main(["numbers/symbols-numberSystem-"+t(b),a])},v={".":"decimal",",":"group","%":"percentSign","+":"plusSign","-":"minusSign",E:"exponential","‰":"perMille"},w=function(a){var b,c={};for(b in v)c[b]=u(v[b],a);return c},x=function(a){return a=a||"round",a="truncate"===a?l:Math[a],function(b,c){return c=c||1,a(b/c)*c}},y=function(a,b,c){function d(a,b){a in c&&(j[b]=c[a])}var e,f,g,h,i,j;return c=c||{},a=a.split(";"),i=a[0],e=a[1]||"-"+i,g=s(e),f=g[0],h=g[10],j=s(i).concat([i,f+i+h,f,h,x(c.round),u("infinity",b),u("nan",b),w(b)]),d("minimumIntegerDigits",2),d("minimumFractionDigits",3),d("maximumFractionDigits",4),d("minimumSignificantDigits",5),d("maximumSignificantDigits",6),c.useGrouping===!1&&(j[8]=null),"minimumFractionDigits"in c&&!("maximumFractionDigits"in c)?j[4]=Math.max(j[3],j[4]):!("minimumFractionDigits"in c)&&"maximumFractionDigits"in c&&(j[3]=Math.min(j[3],j[4])),j},z=/^([^0-9]*)(([0-9,]*[0-9]+)(\.[0-9]+)?)(E[+-]?[0-9]+)?([^0-9]*)$/,A=function(a){return a.replace(/([.*+?^=!:${}()|\[\]\/\\])/g,"\\$1")},B=function(a,b){var c,d,e,f,g,h,i,j,k;if(d=b[0],e=b[1],g=b[2],h=b[3],c=a.match(d))i=1/0,j=a.slice(0,c.length),k=a.slice(c.length+1);else{if(f=new RegExp(Object.keys(e).map(function(a){return A(a)}).join("|"),"g"),a=a.replace(f,function(a){return e[a]}),a=a.match(z),!a)return 0/0;if(j=a[1],k=a[6],i=a[2].replace(/,/g,""),a[5]&&(i+=a[5]),i=+i,isNaN(i))return 0/0;-1!==a[0].indexOf("%")?(i/=100,k=k.replace("%","")):-1!==a[0].indexOf("‰")&&(i/=1e3,k=k.replace("‰",""))}return j===g&&k===h&&(i*=-1),i},C=function(a){var b,c={};for(b in v)c[u(v[b],a)]=b;return c},D=function(a,b){var c,d;return a=a.split(";"),c=a[1]||"-"+a[0],d=s(c),[u("infinity",b),C(b),d[0],d[10].replace("%","").replace("‰","")]},E=function(a,b){if("decimal"!==a&&"percent"!==a)throw new Error("Invalid style");return b.main(["numbers",a+"Formats-numberSystem-"+t(b),"standard"])};return b.numberFormatter=b.prototype.numberFormatter=function(a){var b,g,j,k,l,m,n,o;if(h(a,"options"),a=a||{},b=this.cldr,d(b),b.on("get",c),a.pattern||(n=E(a.style||"decimal",b)),o=y(n,b,a),b.off("get",c),l=o[2],k=o[3],g=o[4],m=o[5],j=o[6],isNaN(m*j)){if(!isNaN(m)||!isNaN(j))throw new Error("Neither or both the minimum and maximum significant digits must be present");f(l,"minimumIntegerDigits",1,21),f(k,"minimumFractionDigits",0,20),f(g,"maximumFractionDigits",k,20)}else f(m,"minimumSignificantDigits",1,21),f(j,"maximumSignificantDigits",m,21);return function(a){return e(a,"value"),i(a,"value"),q(a,o)}},b.numberParser=b.prototype.numberParser=function(a){var b,f,g;return h(a,"options"),a=a||{},b=this.cldr,d(b),b.on("get",c),a.pattern||(f=E(a.style||"decimal",b)),g=D(f,b),b.off("get",c),function(a){return e(a,"value"),j(a,"value"),B(a,g)}},b.formatNumber=b.prototype.formatNumber=function(a,b){return e(a,"value"),i(a,"value"),this.numberFormatter(b)(a)},b.parseNumber=b.prototype.parseNumber=function(a,b){return e(a,"value"),j(a,"value"),this.numberParser(b)(a)},b});
/*!
* Globalize v1.0.0-alpha.6
* Globalize v1.0.0-alpha.7
*

@@ -10,3 +10,3 @@ * http://github.com/jquery/globalize

*
* Date: 2014-09-01T21:32Z
* Date: 2014-09-30T12:31Z
*/

@@ -86,3 +86,2 @@ (function( root, factory ) {

*
* @version 0.1.0
* @source https://github.com/santhoshtr/CLDRPluralRuleParser

@@ -392,3 +391,3 @@ * @author Santhosh Thottingal <santhosh.thottingal@gmail.com>

return parseInt(result[0], 10) % parseInt(result[4], 10);
return parseFloat(result[0]) % parseInt(result[4], 10);
}

@@ -533,3 +532,3 @@

for (i = 0; i < range_list.length; i++) {
if (parseInt(range_list[i], 10) === parseInt(result[0], 10)) {
if (parseInt(range_list[i], 10) === parseFloat(result[0])) {
return (result[1][0] !== 'not');

@@ -536,0 +535,0 @@ }

/*!
* Globalize v1.0.0-alpha.6 2014-09-01T21:32Z Released under the MIT license
* Globalize v1.0.0-alpha.7 2014-09-30T12:31Z Released under the MIT license
* http://git.io/TrdQbw
*/
!function(a,b){"function"==typeof define&&define.amd?define(["cldr","../globalize","cldr/event"],b):"object"==typeof exports?module.exports=b(require("cldrjs"),require("globalize")):b(a.Cldr,a.Globalize)}(this,function(a,b){var c=b._formatMessage,d=b._validate,e=b._validateCldr,f=b._validateDefaultLocale,g=b._validateParameterPresence,h=b._validateParameterType,i=b._validateParameterTypePlainObject,j=function(a,b,c){d("E_PAR_MISSING_KEY","Parameter `{name}` misses key `{key}`",void 0===a||c in a,{key:c,name:"messageData"})},k=function(a,b){h(a,b,void 0===a||"number"==typeof a,"Number")},l=function(){function a(a,b){function c(){}function d(a){return function(){var b,c;for(b=0;b<a.length;b++)if(c=a[b](),null!==c)return c;return null}}function e(a){var b,c,d=G,e=[];for(b=0;b<a.length;b++){if(c=a[b](),null===c)return G=d,null;e.push(c)}return e}function f(a,b){return function(){for(var c=G,d=[],e=b();null!==e;)d.push(e),e=b();return d.length<a?(G=c,null):d}}function g(b){var c=b.length;return function(){var d=null;return a.substr(G,c)===b&&(d=b,G+=c),d}}function h(b){return function(){var c=a.substr(G).match(b);return null===c?null:(G+=c[0].length,c[0])}}function i(){var a=K();return null===a?(c(" -- failed i",parseInt(b,10)),a):(a=parseInt(b,10),c(" -- passed i ",a),a)}function j(){var a=J();return null===a?(c(" -- failed n ",b),a):(a=parseFloat(b,10),c(" -- passed n ",a),a)}function k(){var a=L();return null===a?(c(" -- failed f ",b),a):(a=(b+".").split(".")[1]||0,c(" -- passed f ",a),a)}function l(){var a=M();return null===a?(c(" -- failed t ",b),a):(a=(b+".").split(".")[1].replace(/0$/,"")||0,c(" -- passed t ",a),a)}function m(){var a=N();return null===a?(c(" -- failed v ",b),a):(a=(b+".").split(".")[1].length||0,c(" -- passed v ",a),a)}function n(){var a=O();return null===a?(c(" -- failed w ",b),a):(a=(b+".").split(".")[1].replace(/0$/,"").length||0,c(" -- passed w ",a),a)}function o(){var a=e([C,H,d([T,U]),H,I]);return null===a?(c(" -- failed mod"),null):(c(" -- passed "+parseInt(a[0],10)+" "+a[2]+" "+parseInt(a[4],10)),parseInt(a[0],10)%parseInt(a[4],10))}function p(){var a=e([H,V]);return null===a?(c(" -- failed not"),null):a[1]}function q(){var a=e([D,H,d([P]),H,I]);return null!==a?(c(" -- passed is : "+a[0]+" == "+parseInt(a[4],10)),a[0]===parseInt(a[4],10)):(c(" -- failed is"),null)}function r(){var a=e([D,H,d([Q,R]),H,I]);return null!==a?(c(" -- passed isnot: "+a[0]+" != "+parseInt(a[4],10)),a[0]!==parseInt(a[4],10)):(c(" -- failed isnot"),null)}function s(){var a,b,d=e([D,H,R,H,t]);if(null!==d){for(c(" -- passed not_in: "+d[0]+" != "+d[4]),b=d[4],a=0;a<b.length;a++)if(parseInt(b[a],10)===parseInt(d[0],10))return!1;return!0}return c(" -- failed not_in"),null}function t(){var a=e([d([v,I]),f(0,u)]),b=[];return null!==a?(b=b.concat(a[0]),a[1][0]&&(b=b.concat(a[1][0])),b):(c(" -- failed rangeList"),null)}function u(){var a=e([Z,t]);return null!==a?a[1]:(c(" -- failed rangeTail"),null)}function v(){var a,b,d,f,g=e([I,Y,I]);if(null!==g){for(c(" -- passed range"),b=[],d=parseInt(g[0],10),f=parseInt(g[2],10),a=d;f>=a;a++)b.push(a);return b}return c(" -- failed range"),null}function w(){var a,b,g;if(a=e([D,f(0,p),H,d([W,S]),H,t]),null!==a){for(c(" -- passed _in:"+a),b=a[5],g=0;g<b.length;g++)if(parseInt(b[g],10)===parseInt(a[0],10))return"not"!==a[1][0];return"not"===a[1][0]}return c(" -- failed _in "),null}function x(){var a,b;return b=e([D,f(0,p),H,X,H,t]),null!==b?(c(" -- passed within"),a=b[5],b[0]>=parseInt(a[0],10)&&b[0]<parseInt(a[a.length-1],10)?"not"!==b[1][0]:"not"===b[1][0]):(c(" -- failed within "),null)}function y(){var a,b=e([E,f(0,z)]);if(b){if(!b[0])return!1;for(a=0;a<b[1].length;a++)if(!b[1][a])return!1;return!0}return c(" -- failed and"),null}function z(){var a=e([H,_,H,E]);return null!==a?(c(" -- passed andTail"+a),a[3]):(c(" -- failed andTail"),null)}function A(){var a=e([H,$,H,y]);return null!==a?(c(" -- passed orTail: "+a[3]),a[3]):(c(" -- failed orTail"),null)}function B(){var a,b=e([y,f(0,A)]);if(b){for(a=0;a<b[1].length;a++)if(b[1][a])return!0;return b[0]}return!1}if(a=a.split("@")[0].replace(/^\s*/,"").replace(/\s*$/,""),!a.length)return!0;var C,D,E,F,G=0,H=h(/^\s+/),I=h(/^\d+/),J=g("n"),K=g("i"),L=g("f"),M=g("t"),N=g("v"),O=g("w"),P=g("is"),Q=g("is not"),R=g("!="),S=g("="),T=g("mod"),U=g("%"),V=g("not"),W=g("in"),X=g("within"),Y=g(".."),Z=g(","),$=g("or"),_=g("and");if(c("pluralRuleParser",a,b),C=d([j,i,k,l,m,n]),D=d([o,C]),E=d([q,s,r,w,x]),F=B(),null===F)throw new Error("Parse error at position "+G.toString()+" for rule: "+a);return G!==a.length&&c("Warning: Rule not parsed completely. Parser stopped at "+a.substr(0,G)+" for rule: "+a),F}return a}(),m=function(a,b){var c,d=b.supplemental("plurals-type-cardinal/{language}");for(c in d)if(l(d[c],a))return c.replace(/pluralRule-count-/,"");return null};return b.formatPlural=b.prototype.formatPlural=function(a,b,d){var e;return g(a,"value"),g(b,"messageData"),i(b,"messageData"),h(d,"formatValue",void 0===d||"string"==typeof d||"number"==typeof d,"String or Number"),e=this.plural(a),d=void 0===d?a:d,j(b,"messageData",e),c(b[e],[d])},b.plural=b.prototype.plural=function(a){var b,c;return g(a,"value"),k(a,"value"),b=this.cldr,f(b),b.on("get",e),c=m(a,b),b.off("get",e),d("E_INVALID_CLDR","{description}","string"==typeof c,{description:"Missing rules to deduce plural form of `"+a+"`"}),c},b});
!function(a,b){"function"==typeof define&&define.amd?define(["cldr","../globalize","cldr/event"],b):"object"==typeof exports?module.exports=b(require("cldrjs"),require("globalize")):b(a.Cldr,a.Globalize)}(this,function(a,b){var c=b._formatMessage,d=b._validate,e=b._validateCldr,f=b._validateDefaultLocale,g=b._validateParameterPresence,h=b._validateParameterType,i=b._validateParameterTypePlainObject,j=function(a,b,c){d("E_PAR_MISSING_KEY","Parameter `{name}` misses key `{key}`",void 0===a||c in a,{key:c,name:"messageData"})},k=function(a,b){h(a,b,void 0===a||"number"==typeof a,"Number")},l=function(){function a(a,b){function c(){}function d(a){return function(){var b,c;for(b=0;b<a.length;b++)if(c=a[b](),null!==c)return c;return null}}function e(a){var b,c,d=G,e=[];for(b=0;b<a.length;b++){if(c=a[b](),null===c)return G=d,null;e.push(c)}return e}function f(a,b){return function(){for(var c=G,d=[],e=b();null!==e;)d.push(e),e=b();return d.length<a?(G=c,null):d}}function g(b){var c=b.length;return function(){var d=null;return a.substr(G,c)===b&&(d=b,G+=c),d}}function h(b){return function(){var c=a.substr(G).match(b);return null===c?null:(G+=c[0].length,c[0])}}function i(){var a=K();return null===a?(c(" -- failed i",parseInt(b,10)),a):(a=parseInt(b,10),c(" -- passed i ",a),a)}function j(){var a=J();return null===a?(c(" -- failed n ",b),a):(a=parseFloat(b,10),c(" -- passed n ",a),a)}function k(){var a=L();return null===a?(c(" -- failed f ",b),a):(a=(b+".").split(".")[1]||0,c(" -- passed f ",a),a)}function l(){var a=M();return null===a?(c(" -- failed t ",b),a):(a=(b+".").split(".")[1].replace(/0$/,"")||0,c(" -- passed t ",a),a)}function m(){var a=N();return null===a?(c(" -- failed v ",b),a):(a=(b+".").split(".")[1].length||0,c(" -- passed v ",a),a)}function n(){var a=O();return null===a?(c(" -- failed w ",b),a):(a=(b+".").split(".")[1].replace(/0$/,"").length||0,c(" -- passed w ",a),a)}function o(){var a=e([C,H,d([T,U]),H,I]);return null===a?(c(" -- failed mod"),null):(c(" -- passed "+parseInt(a[0],10)+" "+a[2]+" "+parseInt(a[4],10)),parseFloat(a[0])%parseInt(a[4],10))}function p(){var a=e([H,V]);return null===a?(c(" -- failed not"),null):a[1]}function q(){var a=e([D,H,d([P]),H,I]);return null!==a?(c(" -- passed is : "+a[0]+" == "+parseInt(a[4],10)),a[0]===parseInt(a[4],10)):(c(" -- failed is"),null)}function r(){var a=e([D,H,d([Q,R]),H,I]);return null!==a?(c(" -- passed isnot: "+a[0]+" != "+parseInt(a[4],10)),a[0]!==parseInt(a[4],10)):(c(" -- failed isnot"),null)}function s(){var a,b,d=e([D,H,R,H,t]);if(null!==d){for(c(" -- passed not_in: "+d[0]+" != "+d[4]),b=d[4],a=0;a<b.length;a++)if(parseInt(b[a],10)===parseInt(d[0],10))return!1;return!0}return c(" -- failed not_in"),null}function t(){var a=e([d([v,I]),f(0,u)]),b=[];return null!==a?(b=b.concat(a[0]),a[1][0]&&(b=b.concat(a[1][0])),b):(c(" -- failed rangeList"),null)}function u(){var a=e([Z,t]);return null!==a?a[1]:(c(" -- failed rangeTail"),null)}function v(){var a,b,d,f,g=e([I,Y,I]);if(null!==g){for(c(" -- passed range"),b=[],d=parseInt(g[0],10),f=parseInt(g[2],10),a=d;f>=a;a++)b.push(a);return b}return c(" -- failed range"),null}function w(){var a,b,g;if(a=e([D,f(0,p),H,d([W,S]),H,t]),null!==a){for(c(" -- passed _in:"+a),b=a[5],g=0;g<b.length;g++)if(parseInt(b[g],10)===parseFloat(a[0]))return"not"!==a[1][0];return"not"===a[1][0]}return c(" -- failed _in "),null}function x(){var a,b;return b=e([D,f(0,p),H,X,H,t]),null!==b?(c(" -- passed within"),a=b[5],b[0]>=parseInt(a[0],10)&&b[0]<parseInt(a[a.length-1],10)?"not"!==b[1][0]:"not"===b[1][0]):(c(" -- failed within "),null)}function y(){var a,b=e([E,f(0,z)]);if(b){if(!b[0])return!1;for(a=0;a<b[1].length;a++)if(!b[1][a])return!1;return!0}return c(" -- failed and"),null}function z(){var a=e([H,_,H,E]);return null!==a?(c(" -- passed andTail"+a),a[3]):(c(" -- failed andTail"),null)}function A(){var a=e([H,$,H,y]);return null!==a?(c(" -- passed orTail: "+a[3]),a[3]):(c(" -- failed orTail"),null)}function B(){var a,b=e([y,f(0,A)]);if(b){for(a=0;a<b[1].length;a++)if(b[1][a])return!0;return b[0]}return!1}if(a=a.split("@")[0].replace(/^\s*/,"").replace(/\s*$/,""),!a.length)return!0;var C,D,E,F,G=0,H=h(/^\s+/),I=h(/^\d+/),J=g("n"),K=g("i"),L=g("f"),M=g("t"),N=g("v"),O=g("w"),P=g("is"),Q=g("is not"),R=g("!="),S=g("="),T=g("mod"),U=g("%"),V=g("not"),W=g("in"),X=g("within"),Y=g(".."),Z=g(","),$=g("or"),_=g("and");if(c("pluralRuleParser",a,b),C=d([j,i,k,l,m,n]),D=d([o,C]),E=d([q,s,r,w,x]),F=B(),null===F)throw new Error("Parse error at position "+G.toString()+" for rule: "+a);return G!==a.length&&c("Warning: Rule not parsed completely. Parser stopped at "+a.substr(0,G)+" for rule: "+a),F}return a}(),m=function(a,b){var c,d=b.supplemental("plurals-type-cardinal/{language}");for(c in d)if(l(d[c],a))return c.replace(/pluralRule-count-/,"");return null};return b.formatPlural=b.prototype.formatPlural=function(a,b,d){var e;return g(a,"value"),g(b,"messageData"),i(b,"messageData"),h(d,"formatValue",void 0===d||"string"==typeof d||"number"==typeof d,"String or Number"),e=this.plural(a),d=void 0===d?a:d,j(b,"messageData",e),c(b[e],[d])},b.plural=b.prototype.plural=function(a){var b,c;return g(a,"value"),k(a,"value"),b=this.cldr,f(b),b.on("get",e),c=m(a,b),b.off("get",e),d("E_INVALID_CLDR","{description}","string"==typeof c,{description:"Missing rules to deduce plural form of `"+a+"`"}),c},b});

@@ -1,5 +0,8 @@

## .formatDate( value, format )
## .formatDate( value, pattern )
Format a date `value` according to the given `format`.
Format a date `value` according to the given `pattern`.
*Important:* Use [`.dateFormatter( pattern )`](./date-formatter.md) instead when
formatting more then one date, for improved performance.
### Parameters

@@ -11,53 +14,6 @@

**format**
**pattern**
String value indicating a skeleton, eg. `"GyMMMd"`.
See [.dateFormatter( pattern )](./date-formatter.md).
> Skeleton provides a more flexible formatting mechanism than the predefined
> list `full`, `long`, `medium`, or `short` represented by date, time, or
> datetime. Instead, they are an open-ended list of patterns containing
> only [date
> field](http://www.unicode.org/reports/tr35/tr35-dates.html#Date_Field_Symbol_Table)
> information, and in a canonical order. For example:
>
> | locale | `"GyMMMd"` skeleton |
> | --- | --- |
> | *en* | `"Apr 9, 2014 AD"` |
> | *zh* | `"公元2014年4月9日"` |
> | *es* | `"9 abr. de 2014 d. C."` |
> | *ar* | `"9 أبريل، 2014 م"` |
> | *pt* | `"9 de abr de 2014 d.C."` |
Or, a JSON object including one of the following.
> **skeleton**
>
> String value indicating a skeleton (see description above), eg.
> `{ skeleton: "GyMMMd" }`.
>
> **date**
> One of the following String values: `full`, `long`, `medium`, or `short`, eg.
> `{ date: "full" }`.
>
> **time**
>
> One of the following String values: `full`, `long`, `medium`, or `short`, eg.
> `{ time: "full" }`.
>
> **datetime**
>
> One of the following String values: `full`, `long`, `medium`, or `short`, eg.
> `{ datetime: "full" }`
>
> **pattern**
>
> String value indicating a
> [raw pattern](http://www.unicode.org/reports/tr35/tr35-dates.html#Date_Field_Symbol_Table)
> eg. `{ pattern: "dd/mm" }`.
>
> Raw patterns are NOT recommended for i18n in general. Few specific cases may
> suite the need of using it, eg. locale-independent format for machine parsing.
>
> Use skeletons for i18n purposes.
### Example

@@ -93,3 +49,1 @@

| *es* | `"1/11/10 17:55"` |

@@ -1,7 +0,9 @@

## Globalize.parseDate( value [, formats] )
## .parseDate( value, pattern )
Parse a string representing a date into a JavaScript Date object, taking into
account the given possible formats (or the given locale's set of preset formats
if not provided).
Parse a string representing a date into a JavaScript Date object according to
the given pattern.
*Important:* Use [`.dateParser( pattern )`](./date-parser.md) instead when
parsing more then one date, for improved performance.
### Parameters

@@ -13,5 +15,5 @@

**formats** Optional
**pattern**
Array of formats.
See [.dateFormatter( pattern )](./date-formatter.md).

@@ -25,7 +27,7 @@ ### Example

Globalize.locale( "en" );
Globalize.parseDate( "1/2/13" );
Globalize.parseDate( "1/2/13", { date: "short" } );
// Wed Jan 02 2013 00:00:00
Globalize.locale( "es" );
Globalize.parseDate( "1/2/13" );
Globalize.parseDate( "1/2/13", { date: "short" } );
// Fri Feb 01 2013 00:00:00

@@ -38,4 +40,4 @@ ```

var es = new Globalize( "es" );
es.parseDate( "1/2/13" );
es.parseDate( "1/2/13", { date: "short" } );
// Fri Feb 01 2013 00:00:00
```

@@ -1,5 +0,8 @@

## .formatNumber( value [, attributes] )
## .formatNumber( value [, options] )
Format a number `value` according to the given `attributes`.
Format a number `value` according to the given `options`.
*Important*: Use [`.numberFormatter( [options] )`](./number-formatter.md)
instead when formatting more then one number, for improved performance.
### Parameters

@@ -11,40 +14,6 @@

**attributes** Optional
**options** Optional
A JSON object including none or any of the following attributes.
See [`.numberFormatter( [options] )`](./number-formatter.md).
> **style** Optional
>
> String `decimal` (default), or `percent`.
>
> **minimumIntegerDigits** Optional
>
> Non-negative integer Number value indicating the minimum integer digits to be
> used. Numbers will be padded with leading zeroes if necessary.
>
> **minimumFractionDigits** and **maximumFractionDigits** Optional
>
> Non-negative integer Number values indicating the minimum and maximum fraction
> digits to be used. Numbers will be rounded or padded with trailing zeroes if
> necessary. Either one or both of these properties must be present. If they
> are, they will override minimum and maximum fraction digits derived from the
> CLDR patterns.
>
> **minimumSignificantDigits** and **maximumSignificantDigits** Optional
>
> Positive integer Number values indicating the minimum and maximum fraction
> digits to be shown. Either none or both of these properties are present. If
> they are, they override minimum and maximum integer and fraction digits. The
> formatter uses however many integer and fraction digits are required to
> display the specified number of significant digits.
>
> **round** Optional
>
> String with rounding method `ceil`, `floor`, `round` (default), or `truncate`.
>
> **useGrouping** Optional
>
> Boolean (default is true) value indicating whether a grouping separator should
> be used.
### Example

@@ -51,0 +20,0 @@

@@ -1,2 +0,2 @@

## Globalize.parseNumber( value )
## Globalize.parseNumber( value [, options] )

@@ -6,2 +6,5 @@ Parse a string representing a number taking into account the localized symbols.

*Important*: Use [`.numberParser( [options] )`](./number-parser.md) instead when
parsing more then one number, for improved performance.
### Parameters

@@ -13,2 +16,6 @@

**options** Optional
See [`.numberParser( [options] )`](./number-parser.md).
### Example

@@ -15,0 +22,0 @@

{
"name": "globalize",
"version": "1.0.0-alpha.6",
"description": "New age globalization and localization. Formats and parses strings, dates and numbers in over 350 cultures.",
"version": "1.0.0-alpha.7",
"description": "A JavaScript library for internationalization and localization that leverage the official Unicode CLDR JSON data.",
"keywords": [

@@ -24,5 +24,11 @@ "utility",

"calendars",
"plural",
"plurals",
"pluralize",
"cultures",
"languages",
"locales"
"locales",
"Unicode",
"CLDR",
"JSON"
],

@@ -64,2 +70,5 @@ "homepage": "https://github.com/jquery/globalize",

},
"peerDependencies": {
"cldr-data": ">=25"
},
"devDependencies": {

@@ -66,0 +75,0 @@ "grunt": "0.4.5",

# Globalize
[![Build Status](https://secure.travis-ci.org/jquery/globalize.svg)](http://travis-ci.org/jquery/globalize)
[![Build Status](https://secure.travis-ci.org/jquery/globalize.svg?branch=master)](http://travis-ci.org/jquery/globalize)
[![devDependency Status](https://david-dm.org/jquery/globalize/status.svg)](https://david-dm.org/jquery/globalize#info=dependencies)

@@ -213,5 +213,5 @@ [![devDependency Status](https://david-dm.org/jquery/globalize/dev-status.svg)](https://david-dm.org/jquery/globalize#info=devDependencies)

to you in different flavors):
- [Hello World (AMD + bower)](doc/hello-world/amd-bower/).
- [Hello World (Node.js + npm)](doc/hello-world/node-npm/).
- [Hello World (plain JavaScript)](doc/hello-world/plain-javascript/).
- [Hello World (AMD + bower)](examples/amd-bower/).
- [Hello World (Node.js + npm)](examples/node-npm/).
- [Hello World (plain JavaScript)](examples/plain-javascript/).

@@ -247,13 +247,24 @@

- **`.formatDate( value, format )`**
- **`.dateFormatter( pattern )`**
Format a date `value` according to the given `format`.
Return a function that formats a date according to the given `pattern`.
[Read more...](doc/api/date/date-formatter.md)
- **`.dateParser( pattern )`**
Return a function that parses a string date according to the given `pattern`.
[Read more...](doc/api/date/date-parser.md)
- **`.formatDate( value, pattern )`**
Format a date `value` according to the given `pattern`.
[Read more...](doc/api/date/format-date.md)
- **`.parseDate( value [, formats] )`**
- **`.parseDate( value, pattern )`**
Parse a string representing a date into a JavaScript Date object, taking into
account the given possible formats (or the given locale's set of preset
formats if not provided).
Parse a string representing a date into a JavaScript Date object according to
the given pattern.

@@ -280,12 +291,24 @@ [Read more...](doc/api/date/parse-date.md)

- **`.formatNumber( value [, attributes] )`**
- **`.numberFormatter( [options] )`**
Format a number according to the given attributes.
Return a function that formats a number according to the given options or locale's defaults.
[Read more...](doc/api/number/number-formatter.md)
- **`.numberParser( [options] )`**
Return a function that parses a string representing a number according to the given options or
locale's defaults.
[Read more...](doc/api/number/number-parser.md)
- **`.formatNumber( value [, options] )`**
Format a number according to the given options or locale's defaults.
[Read more...](doc/api/number/format-number.md)
- **`.parseNumber( value )`**
- **`.parseNumber( value [, options] )`**
Parse a string representing a number taking into account the localized
symbols. If value is invalid, `NaN` is returned.
Parse a string representing a number according to the given options or locale's defaults. If value is invalid, `NaN` is returned.

@@ -292,0 +315,0 @@ [Read more...](doc/api/number/parse-number.md)

@@ -35,4 +35,3 @@ /*!

var alwaysArray = Globalize._alwaysArray,
createError = Globalize._createError,
var createError = Globalize._createError,
formatMessage = Globalize._formatMessage,

@@ -39,0 +38,0 @@ isPlainObject = Globalize._isPlainObject,

@@ -11,7 +11,9 @@ define([

"./core",
"./date/all-presets",
"./date/expand-pattern",
"./date/format",
"./date/format-properties",
"./date/parse",
"./util/always-array",
"./date/parse-properties",
"./date/tokenizer",
"./date/tokenizer-properties",
"cldr/event",

@@ -21,4 +23,4 @@ "cldr/supplemental"

validateParameterTypeDataType, validateParameterTypeDate, validateParameterTypeDatePattern,
validateParameterTypeString, Globalize, dateAllPresets, dateExpandPattern, dateFormat,
dateParse, alwaysArray ) {
validateParameterTypeString, Globalize, dateExpandPattern, dateFormat, dateFormatProperties,
dateParse, dateParseProperties, dateTokenizer, dateTokenizerProperties ) {

@@ -36,17 +38,21 @@ function validateRequiredCldr( path, value ) {

/**
* .formatDate( value, pattern )
* .dateFormatter( pattern )
*
* @pattern [String or Object] see date/expand_pattern for more info.
*
* Return a date formatter function (of the form below) according to the given pattern and the
* default/instance locale.
*
* fn( value )
*
* @value [Date]
*
* @pattern [String or Object] see date/expand_pattern for more info.
*
* Formats a date or number according to the given pattern string and the default/instance locale.
* Return a function that formats a date according to the given `format` and the default/instance
* locale.
*/
Globalize.formatDate =
Globalize.prototype.formatDate = function( value, pattern ) {
var cldr, ret;
Globalize.dateFormatter =
Globalize.prototype.dateFormatter = function( pattern ) {
var cldr, properties;
validateParameterPresence( value, "value" );
validateParameterPresence( pattern, "pattern" );
validateParameterTypeDate( value, "value" );
validateParameterTypeDatePattern( pattern, "pattern" );

@@ -60,24 +66,26 @@

pattern = dateExpandPattern( pattern, cldr );
ret = dateFormat( value, pattern, cldr );
properties = dateFormatProperties( pattern, cldr );
cldr.off( "get", validateRequiredCldr );
return ret;
return function( value ) {
validateParameterPresence( value, "value" );
validateParameterTypeDate( value, "value" );
return dateFormat( value, properties );
};
};
/**
* .parseDate( value, patterns )
* .dateParser( pattern )
*
* @value [String]
* @pattern [String or Object] see date/expand_pattern for more info.
*
* @patterns [Array] Optional. See date/expand_pattern for more info about each pattern. Defaults
* to the list of all presets defined in the locale (see date/all_presets for more info).
*
* Return a Date instance or null.
* Return a function that parses a string date according to the given `formats` and the
* default/instance locale.
*/
Globalize.parseDate =
Globalize.prototype.parseDate = function( value, patterns ) {
var cldr, date;
Globalize.dateParser =
Globalize.prototype.dateParser = function( pattern ) {
var cldr, parseProperties, tokenizerProperties;
validateParameterPresence( value, "value" );
validateParameterTypeString( value, "value" );
validateParameterPresence( pattern, "pattern" );
validateParameterTypeDatePattern( pattern, "pattern" );

@@ -89,23 +97,54 @@ cldr = this.cldr;

cldr.on( "get", validateRequiredCldr );
pattern = dateExpandPattern( pattern, cldr );
tokenizerProperties = dateTokenizerProperties( pattern, cldr );
parseProperties = dateParseProperties( cldr );
cldr.off( "get", validateRequiredCldr );
if ( !patterns ) {
patterns = dateAllPresets( cldr );
} else {
patterns = alwaysArray( patterns );
}
return function( value ) {
var tokens;
patterns.some(function( pattern ) {
validateParameterTypeDatePattern( pattern, "patterns" );
pattern = dateExpandPattern( pattern, cldr );
date = dateParse( value, pattern, cldr );
return !!date;
});
validateParameterPresence( value, "value" );
validateParameterTypeString( value, "value" );
cldr.off( "get", validateRequiredCldr );
tokens = dateTokenizer( value, tokenizerProperties );
return dateParse( value, tokens, parseProperties ) || null;
};
};
return date || null;
/**
* .formatDate( value, pattern )
*
* @value [Date]
*
* @pattern [String or Object] see date/expand_pattern for more info.
*
* Formats a date or number according to the given pattern string and the default/instance locale.
*/
Globalize.formatDate =
Globalize.prototype.formatDate = function( value, pattern ) {
validateParameterPresence( value, "value" );
validateParameterTypeDate( value, "value" );
return this.dateFormatter( pattern )( value );
};
/**
* .parseDate( value, pattern )
*
* @value [String]
*
* @pattern [String or Object] see date/expand_pattern for more info.
*
* Return a Date instance or null.
*/
Globalize.parseDate =
Globalize.prototype.parseDate = function( value, pattern ) {
validateParameterPresence( value, "value" );
validateParameterTypeString( value, "value" );
return this.dateParser( pattern )( value );
};
return Globalize;
});

@@ -1,8 +0,10 @@

define([
"./first-day-of-week"
], function( dateFirstDayOfWeek ) {
define(function() {
/**
* dayOfWeek
* dayOfWeek( date, firstDay )
*
* @date
*
* @firstDay the result of `dateFirstDayOfWeek( cldr )`
*
* Return the day of the week normalized by the territory's firstDay [0-6].

@@ -14,6 +16,6 @@ * Eg for "mon":

*/
return function( date, cldr ) {
return ( date.getDay() - dateFirstDayOfWeek( cldr ) + 7 ) % 7;
return function( date, firstDay ) {
return ( date.getDay() - firstDay + 7 ) % 7;
};
});

@@ -14,11 +14,8 @@ define([

/**
* format( date, pattern, cldr )
* format( date, properties )
*
* @date [Date instance].
*
* @pattern [String] raw pattern.
* ref: http://www.unicode.org/reports/tr35/tr35-dates.html#Date_Format_Patterns
* @properties
*
* @cldr [Cldr instance].
*
* TODO Support other calendar types.

@@ -28,5 +25,4 @@ *

*/
return function( date, pattern, cldr ) {
var widths = [ "abbreviated", "wide", "narrow" ];
return pattern.replace( datePatternRe, function( current ) {
return function( date, properties ) {
return properties.pattern.replace( datePatternRe, function( current ) {
var pad, ret,

@@ -39,3 +35,3 @@ chr = current.charAt( 0 ),

// http://www.unicode.org/reports/tr35/tr35-dates.html#Time_Data
chr = cldr.supplemental.timeData.preferred();
chr = properties.preferredTime;
}

@@ -47,7 +43,3 @@

case "G":
ret = cldr.main([
"dates/calendars/gregorian/eras",
length <= 3 ? "eraAbbr" : ( length === 4 ? "eraNames" : "eraNarrow" ),
date.getFullYear() < 0 ? 0 : 1
]);
ret = properties.eras[ date.getFullYear() < 0 ? 0 : 1 ];
break;

@@ -75,5 +67,5 @@

ret.getDate() + 7 -
dateDayOfWeek( date, cldr ) -
dateFirstDayOfWeek( cldr ) -
cldr.supplemental.weekData.minDays()
dateDayOfWeek( date, properties.firstDay ) -
properties.firstDay -
properties.minDays
);

@@ -98,9 +90,3 @@ ret = String( ret.getFullYear() );

} else {
// http://unicode.org/cldr/trac/ticket/6788
ret = cldr.main([
"dates/calendars/gregorian/quarters",
chr === "Q" ? "format" : "stand-alone",
widths[ length - 3 ],
ret
]);
ret = properties.quarters[ chr ][ length ][ ret ];
}

@@ -116,8 +102,3 @@ break;

} else {
ret = cldr.main([
"dates/calendars/gregorian/months",
chr === "M" ? "format" : "stand-alone",
widths[ length - 3 ],
ret
]);
ret = properties.months[ chr ][ length ][ ret ];
}

@@ -131,5 +112,5 @@ break;

// TODO should pad on ww? Not documented, but I guess so.
ret = dateDayOfWeek( dateStartOf( date, "year" ), cldr );
ret = dateDayOfWeek( dateStartOf( date, "year" ), properties.firstDay );
ret = Math.ceil( ( dateDayOfYear( date ) + ret ) / 7 ) -
( 7 - ret >= cldr.supplemental.weekData.minDays() ? 0 : 1 );
( 7 - ret >= properties.minDays ? 0 : 1 );
pad = true;

@@ -141,5 +122,5 @@ break;

// wom = ceil( ( dom + dow of `1/month` ) / 7 ) - minDaysStuff ? 1 : 0.
ret = dateDayOfWeek( dateStartOf( date, "month" ), cldr );
ret = dateDayOfWeek( dateStartOf( date, "month" ), properties.firstDay );
ret = Math.ceil( ( date.getDate() + ret ) / 7 ) -
( 7 - ret >= cldr.supplemental.weekData.minDays() ? 0 : 1 );
( 7 - ret >= properties.minDays ? 0 : 1 );
break;

@@ -173,3 +154,3 @@

// TODO Should pad with zeros (not specified in the docs)?
ret = dateDayOfWeek( date, cldr ) + 1;
ret = dateDayOfWeek( date, properties.firstDay ) + 1;
pad = true;

@@ -182,26 +163,3 @@ break;

ret = dateWeekDays[ date.getDay() ];
if ( length === 6 ) {
// If short day names are not explicitly specified, abbreviated day names are
// used instead.
// http://www.unicode.org/reports/tr35/tr35-dates.html#months_days_quarters_eras
// http://unicode.org/cldr/trac/ticket/6790
ret = cldr.main([
"dates/calendars/gregorian/days",
chr === "c" ? "stand-alone" : "format",
"short",
ret
]) || cldr.main([
"dates/calendars/gregorian/days",
chr === "c" ? "stand-alone" : "format",
"abbreviated",
ret
]);
} else {
ret = cldr.main([
"dates/calendars/gregorian/days",
chr === "c" ? "stand-alone" : "format",
widths[ length < 3 ? 0 : length - 3 ],
ret
]);
}
ret = properties.days[ chr ][ length ][ ret ];
break;

@@ -211,6 +169,3 @@

case "a":
ret = cldr.main([
"dates/calendars/gregorian/dayPeriods/format/wide",
date.getHours() < 12 ? "am" : "pm"
]);
ret = properties.dayPeriods[ date.getHours() < 12 ? "am" : "pm" ];
break;

@@ -217,0 +172,0 @@

define([
"./pattern-re",
"./start-of",
"./tokenizer",
"../util/date/set-date",
"../util/date/set-month"
], function( datePatternRe, dateStartOf, dateTokenizer, dateSetDate, dateSetMonth ) {
], function( datePatternRe, dateStartOf, dateSetDate, dateSetMonth ) {

@@ -14,7 +13,13 @@ function outOfRange( value, low, high ) {

/**
* parse
* parse( value, tokens, properties )
*
* @value [String] string date.
*
* @tokens [Object] tokens returned by date/tokenizer.
*
* @properties [Object] output returned by date/tokenizer-properties.
*
* ref: http://www.unicode.org/reports/tr35/tr35-dates.html#Date_Format_Patterns
*/
return function( value, pattern, cldr ) {
return function( value, tokens, properties ) {
var amPm, era, hour, hour12, valid,

@@ -29,3 +34,2 @@ YEAR = 0,

date = new Date(),
tokens = dateTokenizer( value, pattern, cldr ),
truncateAt = [],

@@ -52,3 +56,3 @@ units = [ "year", "month", "day", "hour", "minute", "second", "milliseconds" ];

// http://www.unicode.org/reports/tr35/tr35-dates.html#Time_Data
chr = cldr.supplemental.timeData.preferred();
chr = properties.preferredTimeData;
}

@@ -55,0 +59,0 @@

@@ -6,4 +6,8 @@ define([

/**
* tokenizer( value, pattern )
* tokenizer( value, pattern, properties )
*
* @value [String] string date.
*
* @properties [Object] output returned by date/tokenizer-properties.
*
* Returns an Array of tokens, eg. value "5 o'clock PM", pattern "h 'o''clock' a":

@@ -33,3 +37,3 @@ * [{

*/
return function( value, pattern, cldr ) {
return function( value, properties ) {
var valid,

@@ -39,3 +43,3 @@ tokens = [],

valid = pattern.match( datePatternRe ).every(function( current ) {
valid = properties.pattern.match( datePatternRe ).every(function( current ) {
var chr, length, tokenRe,

@@ -66,3 +70,4 @@ token = {};

var i, re,
data = cldr.main( path );
data = properties[ path.join( "/" ).replace( /^.*calendars\//, "" ) ];
for ( i in data ) {

@@ -69,0 +74,0 @@ re = new RegExp( "^" + data[ i ] );

@@ -6,2 +6,3 @@ define([

"./common/validate/parameter-presence",
"./common/validate/parameter-range",
"./common/validate/parameter-type/number",

@@ -11,29 +12,30 @@ "./common/validate/parameter-type/plain-object",

"./number/format",
"./number/format-properties",
"./number/parse",
"./number/parse-properties",
"./number/pattern",
"cldr/event"
], function( Globalize, validateCldr, validateDefaultLocale, validateParameterPresence,
validateParameterTypeNumber, validateParameterTypePlainObject, validateParameterTypeString,
numberFormat, numberParse, numberPattern ) {
validateParameterRange, validateParameterTypeNumber, validateParameterTypePlainObject,
validateParameterTypeString, numberFormat, numberFormatProperties, numberParse,
numberParseProperties, numberPattern ) {
/**
* .formatNumber( value, pattern )
* .numberFormatter( [options] )
*
* @value [Number]
*
* @attributes [Object]:
* @options [Object]:
* - style: [String] "decimal" (default) or "percent".
* - see also number/format options.
*
* Format a number according to the given attributes and default/instance locale.
* Return a function that formats a number according to the given options and default/instance
* locale.
*/
Globalize.formatNumber =
Globalize.prototype.formatNumber = function( value, attributes ) {
var cldr, pattern, ret;
Globalize.numberFormatter =
Globalize.prototype.numberFormatter = function( options ) {
var cldr, maximumFractionDigits, maximumSignificantDigits, minimumFractionDigits,
minimumIntegerDigits, minimumSignificantDigits, pattern, properties;
validateParameterPresence( value, "value" );
validateParameterTypeNumber( value, "value" );
validateParameterTypePlainObject( attributes, "attributes" );
validateParameterTypePlainObject( options, "options" );
attributes = attributes || {};
options = options || {};
cldr = this.cldr;

@@ -45,27 +47,57 @@

if ( !attributes.pattern ) {
pattern = numberPattern( attributes.style || "decimal", cldr );
if ( !options.pattern ) {
pattern = numberPattern( options.style || "decimal", cldr );
}
ret = numberFormat( value, pattern, cldr, attributes );
properties = numberFormatProperties( pattern, cldr, options );
cldr.off( "get", validateCldr );
return ret;
minimumIntegerDigits = properties[ 2 ];
minimumFractionDigits = properties[ 3 ];
maximumFractionDigits = properties[ 4 ];
minimumSignificantDigits = properties[ 5 ];
maximumSignificantDigits = properties[ 6 ];
// Validate significant digit format properties
if ( !isNaN( minimumSignificantDigits * maximumSignificantDigits ) ) {
validateParameterRange( minimumSignificantDigits, "minimumSignificantDigits", 1, 21 );
validateParameterRange( maximumSignificantDigits, "maximumSignificantDigits",
minimumSignificantDigits, 21 );
} else if ( !isNaN( minimumSignificantDigits ) || !isNaN( maximumSignificantDigits ) ) {
throw new Error( "Neither or both the minimum and maximum significant digits must be " +
"present" );
// Validate integer and fractional format
} else {
validateParameterRange( minimumIntegerDigits, "minimumIntegerDigits", 1, 21 );
validateParameterRange( minimumFractionDigits, "minimumFractionDigits", 0, 20 );
validateParameterRange( maximumFractionDigits, "maximumFractionDigits",
minimumFractionDigits, 20 );
}
return function( value ) {
validateParameterPresence( value, "value" );
validateParameterTypeNumber( value, "value" );
return numberFormat( value, properties );
};
};
/**
* .parseNumber( value )
* .numberParser( [options] )
*
* @value [String]
* @options [Object]:
* - style: [String] "decimal" (default) or "percent".
*
* Return the parsed Number (including Infinity) or NaN when value is invalid.
* Return the number parser according to the default/instance locale.
*/
Globalize.parseNumber =
Globalize.prototype.parseNumber = function( value ) {
var cldr, pattern, ret;
Globalize.numberParser =
Globalize.prototype.numberParser = function( options ) {
var cldr, pattern, properties;
validateParameterPresence( value, "value" );
validateParameterTypeString( value, "value" );
validateParameterTypePlainObject( options, "options" );
options = options || {};
cldr = this.cldr;

@@ -77,14 +109,53 @@

// TODO: What about per mille? Which "style" does it belong to?
pattern = numberPattern( value.indexOf( "%" ) !== -1 ? "percent" : "decimal", cldr );
if ( !options.pattern ) {
pattern = numberPattern( options.style || "decimal", cldr );
}
ret = numberParse( value, pattern, cldr );
properties = numberParseProperties( pattern, cldr );
cldr.off( "get", validateCldr );
return ret;
return function( value ) {
validateParameterPresence( value, "value" );
validateParameterTypeString( value, "value" );
return numberParse( value, properties );
};
};
/**
* .formatNumber( value [, options] )
*
* @value [Number] number to be formatted.
*
* @options [Object]: see number/format-properties.
*
* Format a number according to the given options and default/instance locale.
*/
Globalize.formatNumber =
Globalize.prototype.formatNumber = function( value, options ) {
validateParameterPresence( value, "value" );
validateParameterTypeNumber( value, "value" );
return this.numberFormatter( options )( value );
};
/**
* .parseNumber( value [, options] )
*
* @value [String]
*
* @options [Object]: See numberParser().
*
* Return the parsed Number (including Infinity) or NaN when value is invalid.
*/
Globalize.parseNumber =
Globalize.prototype.parseNumber = function( value, options ) {
validateParameterPresence( value, "value" );
validateParameterTypeString( value, "value" );
return this.numberParser( options )( value );
};
return Globalize;
});
define([
"./format/grouping-separator",
"./format/integer-fraction-digits",
"./format/significant-digits",
"./pattern-properties",
"./symbol",
"./symbol/name",
"../common/validate/parameter-range",
"../util/number/round"
"./format/significant-digits"
], function( numberFormatGroupingSeparator, numberFormatIntegerFractionDigits,
numberFormatSignificantDigits, numberPatternProperties, numberSymbol, numberSymbolName,
validateParameterRange, numberRound ) {
numberFormatSignificantDigits ) {
/**
* format( number, pattern, cldr [, options] )
* format( number, properties )
*
* @number [Number].
*
* @pattern [String] raw pattern for numbers.
* @properties [Object] Output of number/format-properties.
*
* @cldr [Cldr instance].
*
* @options [Object]:
* - minimumIntegerDigits [Number]
* - minimumFractionDigits, maximumFractionDigits [Number]
* - minimumSignificantDigits, maximumSignificantDigits [Number]
* - round [String] "ceil", "floor", "round" (default), or "truncate".
* - useGrouping [Boolean] default true.
*
* Return the formatted number.
* ref: http://www.unicode.org/reports/tr35/tr35-numbers.html
*/
return function( number, pattern, cldr, options ) {
var maximumFractionDigits, maximumSignificantDigits, minimumFractionDigits,
minimumIntegerDigits, minimumSignificantDigits, padding, prefix, primaryGroupingSize,
properties, ret, round, roundIncrement, secondaryGroupingSize, suffix;
return function( number, properties ) {
var infinitySymbol, maximumFractionDigits, maximumSignificantDigits, minimumFractionDigits,
minimumIntegerDigits, minimumSignificantDigits, nanSymbol, padding, prefix,
primaryGroupingSize, pattern, ret, round, roundIncrement, secondaryGroupingSize, suffix,
symbolMap;
// NaN
if ( isNaN( number ) ) {
return numberSymbol( "nan", cldr );
}
pattern = pattern.split( ";" );
function getOptions( property, defaultValue ) {
return property in options ? options[ property ] : defaultValue;
}
options = options || {};
round = numberRound( options.round );
properties = numberPatternProperties( pattern[ 0 ] );
padding = properties[ 1 ];
minimumIntegerDigits = getOptions( "minimumIntegerDigits", properties[ 2 ] );
minimumIntegerDigits = getOptions( "minimumIntegerDigits", properties[ 2 ] );
minimumFractionDigits = getOptions( "minimumFractionDigits", properties[ 3 ] );
maximumFractionDigits = getOptions( "maximumFractionDigits", properties[ 4 ] );
minimumSignificantDigits = getOptions( "minimumSignificantDigits", properties[ 5 ] );
maximumSignificantDigits = getOptions( "maximumSignificantDigits", properties[ 6 ] );
minimumIntegerDigits = properties[ 2 ];
minimumFractionDigits = properties[ 3 ];
maximumFractionDigits = properties[ 4 ];
minimumSignificantDigits = properties[ 5 ];
maximumSignificantDigits = properties[ 6 ];
roundIncrement = properties[ 7 ];
primaryGroupingSize = properties[ 8 ];
secondaryGroupingSize = properties[ 9 ];
round = properties[ 15 ];
infinitySymbol = properties[ 16 ];
nanSymbol = properties[ 17 ];
symbolMap = properties[ 18 ];
// Negative pattern
// "If there is an explicit negative subpattern, it serves only to specify the negative prefix
// and suffix" UTS#35
// NaN
if ( isNaN( number ) ) {
return nanSymbol;
}
if ( number < 0 ) {
// "If there is no explicit negative subpattern, the negative subpattern is the localized
// minus sign prefixed to the positive subpattern" UTS#35
pattern = pattern[ 1 ] || "-" + pattern[ 0 ];
properties = numberPatternProperties( pattern );
pattern = properties[ 12 ];
prefix = properties[ 13 ];
suffix = properties[ 14 ];
} else {
pattern = pattern[ 0 ];
pattern = properties[ 11 ];
prefix = properties[ 0 ];
suffix = properties[ 10 ];
}
prefix = properties[ 0 ];
suffix = properties[ 10 ];
// Infinity (observe that isNaN() has been checked above)
// Infinity
if ( !isFinite( number ) ) {
return prefix + numberSymbol( "infinity", cldr ) + suffix;
return prefix + infinitySymbol + suffix;
}

@@ -97,28 +71,7 @@

if ( !isNaN( minimumSignificantDigits * maximumSignificantDigits ) ) {
validateParameterRange( minimumSignificantDigits, "minimumSignificantDigits", 1, 21 );
validateParameterRange( maximumSignificantDigits, "maximumSignificantDigits",
minimumSignificantDigits, 21 );
number = numberFormatSignificantDigits( number, minimumSignificantDigits,
maximumSignificantDigits, round );
} else if ( !isNaN( minimumSignificantDigits ) || !isNaN( maximumSignificantDigits ) ) {
throw new Error( "Neither or both the minimum and maximum significant digits must be " +
"present" );
// Integer and fractional format
} else {
// Normalize number of digits if only one of either minimumFractionDigits or
// maximumFractionDigits is passed in as an option
if ( "minimumFractionDigits" in options && !( "maximumFractionDigits" in options ) ) {
maximumFractionDigits = Math.max( minimumFractionDigits, maximumFractionDigits );
} else if ( !( "minimumFractionDigits" in options ) &&
"maximumFractionDigits" in options ) {
minimumFractionDigits = Math.min( minimumFractionDigits, maximumFractionDigits );
}
validateParameterRange( minimumIntegerDigits, "minimumIntegerDigits", 1, 21 );
validateParameterRange( minimumFractionDigits, "minimumFractionDigits", 0, 20 );
validateParameterRange( maximumFractionDigits, "maximumFractionDigits",
minimumFractionDigits, 20 );
number = numberFormatIntegerFractionDigits( number, minimumIntegerDigits,

@@ -132,3 +85,3 @@ minimumFractionDigits, maximumFractionDigits, round, roundIncrement );

// Grouping separators
if ( primaryGroupingSize && !( "useGrouping" in options && !options.useGrouping ) ) {
if ( primaryGroupingSize ) {
number = numberFormatGroupingSeparator( number, primaryGroupingSize,

@@ -157,3 +110,3 @@ secondaryGroupingSize );

}
return numberSymbol( numberSymbolName[ symbol ], cldr );
return symbolMap[ symbol ];
});

@@ -160,0 +113,0 @@ };

define([
"./number-re",
"./pattern-properties",
"./symbol",
"./symbol/map",
"../util/regexp/escape"
], function( numberNumberRe, numberPatternProperties, numberSymbol, numberSymbolMap,
regexpEscape ) {
], function( numberNumberRe, regexpEscape ) {
/**
* parse( value, cldr )
* parse( value, properties )
*
* @value [String].
*
* @cldr [Cldr instance].
* @properties [Object] Parser properties is a reduced pre-processed cldr
* data set returned by numberParserProperties().
*

@@ -20,7 +17,13 @@ * Return the parsed Number (including Infinity) or NaN when value is invalid.

*/
return function( value, pattern, cldr ) {
var aux, localizedSymbolsRe, number, prefix, properties, suffix, symbolMap;
return function( value, properties ) {
var aux, infinitySymbol, invertedSymbolMap, localizedSymbolsRe, negativePrefix, negativeSuffix,
number, prefix, suffix;
infinitySymbol = properties[ 0 ];
invertedSymbolMap = properties[ 1 ];
negativePrefix = properties[ 2 ];
negativeSuffix = properties[ 3 ];
// Infinite number.
if ( aux = value.match( numberSymbol( "infinity", cldr ) ) ) {
if ( aux = value.match( infinitySymbol ) ) {

@@ -34,10 +37,12 @@ number = Infinity;

symbolMap = numberSymbolMap( cldr );
localizedSymbolsRe = new RegExp( Object.keys( symbolMap ).map(function( localizedSymbol ) {
return regexpEscape( localizedSymbol );
}).join( "|" ), "g" );
localizedSymbolsRe = new RegExp(
Object.keys( invertedSymbolMap ).map(function( localizedSymbol ) {
return regexpEscape( localizedSymbol );
}).join( "|" ),
"g"
);
// Reverse localized symbols.
value = value.replace( localizedSymbolsRe, function( localizedSymbol ) {
return symbolMap[ localizedSymbol ];
return invertedSymbolMap[ localizedSymbol ];
});

@@ -76,2 +81,3 @@

number /= 100;
suffix = suffix.replace( "%", "" );

@@ -81,2 +87,3 @@ // Per mille

number /= 1000;
suffix = suffix.replace( "\u2030", "" );
}

@@ -89,5 +96,3 @@ }

// localized minus sign prefixed to the positive subpattern" UTS#35
pattern = pattern.split( ";" );
properties = numberPatternProperties( pattern[ 1 ] || pattern[ 0 ] );
if ( prefix === ( pattern[ 1 ] ? "" : "-" ) + properties[ 0 ] && suffix === properties[ 10 ] ) {
if ( prefix === negativePrefix && suffix === negativeSuffix ) {
number *= -1;

@@ -94,0 +99,0 @@ }

@@ -12,5 +12,5 @@ define([

* Return the (localized symbol, pattern symbol) key value pair, eg. {
* "٫": ".",
* "٬": ",",
* "٪": "%",
* ".": "٫",
* ",": "٬",
* "%": "٪",
* ...

@@ -24,3 +24,3 @@ * };

for ( symbol in numberSymbolName ) {
symbolMap[ numberSymbol( numberSymbolName[ symbol ], cldr ) ] = symbol;
symbolMap[ symbol ] = numberSymbol( numberSymbolName[ symbol ], cldr );
}

@@ -27,0 +27,0 @@

@@ -18,2 +18,4 @@ require.config({

// date
"./functional/date/date-formatter",
"./functional/date/date-parser",
"./functional/date/format-date",

@@ -26,2 +28,4 @@ "./functional/date/parse-date",

// number
"./functional/number/number-formatter",
"./functional/number/number-parser",
"./functional/number/format-number",

@@ -28,0 +32,0 @@ "./functional/number/parse-number",

@@ -6,3 +6,3 @@ define([

QUnit.module( "Globalize.load()" );
QUnit.module( "Globalize.load( cldrJSONData )" );

@@ -9,0 +9,0 @@ QUnit.test( "should validate parameters", function( assert ) {

@@ -9,3 +9,3 @@ define([

QUnit.module( "Globalize.locale()" );
QUnit.module( "Globalize.locale( [locale|cldr] )" );

@@ -12,0 +12,0 @@ QUnit.test( "should validate parameters", function( assert ) {

@@ -21,3 +21,3 @@ define([

QUnit.module( "Datetime Format", {
QUnit.module( ".formatDate( value, pattern )", {
setup: function() {

@@ -24,0 +24,0 @@ Globalize.load( likelySubtags );

@@ -22,3 +22,3 @@ define([

QUnit.module( "Datetime Parse", {
QUnit.module( ".parseDate( value, pattern )", {
setup: function() {

@@ -46,5 +46,5 @@ Globalize.load( likelySubtags );

util.assertDatePatternParameter( assert, "patterns", function( invalidValue ) {
util.assertDatePatternParameter( assert, "pattern", function( invalidValue ) {
return function() {
Globalize.parseDate( "15 Wed", [ invalidValue ] );
Globalize.parseDate( "15 Wed", invalidValue );
};

@@ -125,3 +125,3 @@ });

QUnit.test( "should parse raw patterns", function( assert ) {
QUnit.test( "should parse raw pattern", function( assert ) {
extraSetup();

@@ -128,0 +128,0 @@

@@ -9,3 +9,3 @@ define([

QUnit.module( "Translate", {
QUnit.module( ".translate( path )", {
setup: function() {

@@ -12,0 +12,0 @@ Globalize.load( likelySubtags );

@@ -19,3 +19,3 @@ define([

QUnit.module( "Number Format", {
QUnit.module( ".formatNumber( value [, options] )", {
setup: function() {

@@ -39,3 +39,3 @@ Globalize.load( likelySubtags );

util.assertPlainObjectParameter( assert, "attributes", function( invalidValue ) {
util.assertPlainObjectParameter( assert, "options", function( invalidValue ) {
return function() {

@@ -53,28 +53,2 @@ Globalize.formatNumber( 7, invalidValue );

QUnit.test( "should validate options", function( assert ) {
extraSetup();
util.assertParameterRange( assert, 1, 21, function( num ) {
Globalize.formatNumber( pi, {
maximumSignificantDigits: 1,
minimumSignificantDigits: num
});
});
util.assertParameterRange( assert, 1, 21, function( num ) {
Globalize.formatNumber( pi, {
maximumSignificantDigits: num,
minimumSignificantDigits: 1
});
});
util.assertParameterRange( assert, 1, 21, function( num ) {
Globalize.formatNumber( pi, { minimumIntegerDigits: num } );
});
util.assertParameterRange( assert, 0, 20, function( num ) {
Globalize.formatNumber( pi, { minimumFractionDigits: num } );
});
util.assertParameterRange( assert, 0, 20, function( num ) {
Globalize.formatNumber( pi, { maximumFractionDigits: num } );
});
});
QUnit.test( "should format decimal style", function( assert ) {

@@ -81,0 +55,0 @@ extraSetup();

@@ -23,3 +23,3 @@ define([

QUnit.module( "Number Parse", {
QUnit.module( ".parseNumber( value [, options] )", {
setup: function() {

@@ -46,2 +46,8 @@ Globalize.load( likelySubtags );

});
util.assertPlainObjectParameter( assert, "options", function( invalidValue ) {
return function() {
Globalize.parseNumber( "3", invalidValue );
};
});
});

@@ -48,0 +54,0 @@

@@ -13,3 +13,3 @@ define([

QUnit.module( ".formatPlural()", {
QUnit.module( ".formatPlural( value, messageData [, formatValue ] )", {
setup: function() {

@@ -16,0 +16,0 @@ Globalize.load( likelySubtags );

@@ -13,3 +13,3 @@ define([

QUnit.module( ".plural()", {
QUnit.module( ".plural( value )", {
setup: function() {

@@ -16,0 +16,0 @@ Globalize.load( likelySubtags );

@@ -19,4 +19,7 @@ require.config({

"./unit/date/expand-pattern",
"./unit/date/format-properties",
"./unit/date/format",
"./unit/date/tokenizer-properties",
"./unit/date/tokenizer",
"./unit/date/parse-properties",
"./unit/date/parse",

@@ -28,6 +31,9 @@

// number
"./unit/number/pattern-properties",
"./unit/number/format/integer-fraction-digits",
"./unit/number/format/significant-digits",
"./unit/number/format/grouping-separator",
"./unit/number/format-properties",
"./unit/number/format",
"./unit/number/parse-properties",
"./unit/number/parse",

@@ -34,0 +40,0 @@

@@ -15,3 +15,3 @@ define([

QUnit.module( "Datetime Expand Pattern" );
QUnit.module( "Date Expand Pattern" );

@@ -18,0 +18,0 @@ QUnit.test( "should expand skeleton \"<skeleton>\" (as a String)", function( assert ) {

define([
"cldr",
"src/date/format",
"src/date/format-properties",
"json!fixtures/cldr/main/en/ca-gregorian.json",

@@ -9,3 +10,3 @@ "json!fixtures/cldr/supplemental/likelySubtags.json",

"cldr/supplemental"
], function( Cldr, format, enCaGregorian, likelySubtags, timeData, weekData ) {
], function( Cldr, format, properties, enCaGregorian, likelySubtags, timeData, weekData ) {

@@ -27,3 +28,3 @@ var cldr,

QUnit.module( "Datetime Format" );
QUnit.module( "Date Format" );

@@ -35,23 +36,23 @@ /**

QUnit.test( "should format era (G|GG|GGG)", function( assert ) {
assert.equal( format( date1, "G", cldr ), "AD" );
assert.equal( format( year0, "G", cldr ), "AD" );
assert.equal( format( yearBc, "G", cldr ), "BC" );
assert.equal( format( date1, "GG", cldr ), "AD" );
assert.equal( format( year0, "GG", cldr ), "AD" );
assert.equal( format( yearBc, "GG", cldr ), "BC" );
assert.equal( format( date1, "GGG", cldr ), "AD" );
assert.equal( format( year0, "GGG", cldr ), "AD" );
assert.equal( format( yearBc, "GGG", cldr ), "BC" );
assert.equal( format( date1, properties( "G", cldr ) ), "AD" );
assert.equal( format( year0, properties( "G", cldr ) ), "AD" );
assert.equal( format( yearBc, properties( "G", cldr ) ), "BC" );
assert.equal( format( date1, properties( "GG", cldr ) ), "AD" );
assert.equal( format( year0, properties( "GG", cldr ) ), "AD" );
assert.equal( format( yearBc, properties( "GG", cldr ) ), "BC" );
assert.equal( format( date1, properties( "GGG", cldr ) ), "AD" );
assert.equal( format( year0, properties( "GGG", cldr ) ), "AD" );
assert.equal( format( yearBc, properties( "GGG", cldr ) ), "BC" );
});
QUnit.test( "should format era (GGGG)", function( assert ) {
assert.equal( format( date1, "GGGG", cldr ), "Anno Domini" );
assert.equal( format( year0, "GGGG", cldr ), "Anno Domini" );
assert.equal( format( yearBc, "GGGG", cldr ), "Before Christ" );
assert.equal( format( date1, properties( "GGGG", cldr ) ), "Anno Domini" );
assert.equal( format( year0, properties( "GGGG", cldr ) ), "Anno Domini" );
assert.equal( format( yearBc, properties( "GGGG", cldr ) ), "Before Christ" );
});
QUnit.test( "should format era (GGGGG)", function( assert ) {
assert.equal( format( date1, "GGGGG", cldr ), "A" );
assert.equal( format( year0, "GGGGG", cldr ), "A" );
assert.equal( format( yearBc, "GGGGG", cldr ), "B" );
assert.equal( format( date1, properties( "GGGGG", cldr ) ), "A" );
assert.equal( format( year0, properties( "GGGGG", cldr ) ), "A" );
assert.equal( format( yearBc, properties( "GGGGG", cldr ) ), "B" );
});

@@ -64,36 +65,36 @@

QUnit.test( "should format year (y) with no padding", function( assert ) {
assert.equal( format( date2, "y", cldr ), "2010" );
assert.equal( format( date1, "y", cldr ), "1982" );
assert.equal( format( year0, "y", cldr ), "0" );
assert.equal( format( date2, properties( "y", cldr ) ), "2010" );
assert.equal( format( date1, properties( "y", cldr ) ), "1982" );
assert.equal( format( year0, properties( "y", cldr ) ), "0" );
});
QUnit.test( "should format year (yy) with padding, and limit 2 digits", function( assert ) {
assert.equal( format( date2, "yy", cldr ), "10" );
assert.equal( format( date1, "yy", cldr ), "82" );
assert.equal( format( year0, "yy", cldr ), "00" );
assert.equal( format( date2, properties( "yy", cldr ) ), "10" );
assert.equal( format( date1, properties( "yy", cldr ) ), "82" );
assert.equal( format( year0, properties( "yy", cldr ) ), "00" );
});
QUnit.test( "should format year (yyy+) with padding", function( assert ) {
assert.equal( format( date1, "yyy", cldr ), "1982" );
assert.equal( format( date2, "yyy", cldr ), "2010" );
assert.equal( format( year0, "yyyy", cldr ), "0000" );
assert.equal( format( date1, "yyyyy", cldr ), "01982" );
assert.equal( format( date2, "yyyyy", cldr ), "02010" );
assert.equal( format( date1, properties( "yyy", cldr ) ), "1982" );
assert.equal( format( date2, properties( "yyy", cldr ) ), "2010" );
assert.equal( format( year0, properties( "yyyy", cldr ) ), "0000" );
assert.equal( format( date1, properties( "yyyyy", cldr ) ), "01982" );
assert.equal( format( date2, properties( "yyyyy", cldr ) ), "02010" );
});
QUnit.test( "should format year in \"week of year\" (Y) with no padding", function( assert ) {
assert.equal( format( date3, "Y", cldr ), "1982" );
assert.equal( format( date4, "Y", cldr ), "1994" );
assert.equal( format( date3, properties( "Y", cldr ) ), "1982" );
assert.equal( format( date4, properties( "Y", cldr ) ), "1994" );
});
QUnit.test( "should format year in \"week of year\" (YY) with padding, and limit 2 digits", function( assert ) {
assert.equal( format( date3, "YY", cldr ), "82" );
assert.equal( format( date4, "YY", cldr ), "94" );
assert.equal( format( date3, properties( "YY", cldr ) ), "82" );
assert.equal( format( date4, properties( "YY", cldr ) ), "94" );
});
QUnit.test( "should format year in \"week of year\" (YYY+) with padding", function( assert ) {
assert.equal( format( date3, "YYY", cldr ), "1982" );
assert.equal( format( date4, "YYY", cldr ), "1994" );
assert.equal( format( date3, "YYYYY", cldr ), "01982" );
assert.equal( format( date4, "YYYYY", cldr ), "01994" );
assert.equal( format( date3, properties( "YYY", cldr ) ), "1982" );
assert.equal( format( date4, properties( "YYY", cldr ) ), "1994" );
assert.equal( format( date3, properties( "YYYYY", cldr ) ), "01982" );
assert.equal( format( date4, properties( "YYYYY", cldr ) ), "01994" );
});

@@ -106,27 +107,27 @@

QUnit.test( "should format quarter (Q|q) with no padding", function( assert ) {
assert.equal( format( date1, "Q", cldr ), "1" );
assert.equal( format( date2, "Q", cldr ), "3" );
assert.equal( format( date1, "q", cldr ), "1" );
assert.equal( format( date2, "q", cldr ), "3" );
assert.equal( format( date1, properties( "Q", cldr ) ), "1" );
assert.equal( format( date2, properties( "Q", cldr ) ), "3" );
assert.equal( format( date1, properties( "q", cldr ) ), "1" );
assert.equal( format( date2, properties( "q", cldr ) ), "3" );
});
QUnit.test( "should format quarter (QQ|qq) with padding", function( assert ) {
assert.equal( format( date1, "QQ", cldr ), "01" );
assert.equal( format( date2, "QQ", cldr ), "03" );
assert.equal( format( date1, "qq", cldr ), "01" );
assert.equal( format( date2, "qq", cldr ), "03" );
assert.equal( format( date1, properties( "QQ", cldr ) ), "01" );
assert.equal( format( date2, properties( "QQ", cldr ) ), "03" );
assert.equal( format( date1, properties( "qq", cldr ) ), "01" );
assert.equal( format( date2, properties( "qq", cldr ) ), "03" );
});
QUnit.test( "should format quarter (QQQ|qqq)", function( assert ) {
assert.equal( format( date1, "QQQ", cldr ), "Q1" );
assert.equal( format( date2, "QQQ", cldr ), "Q3" );
assert.equal( format( date1, "qqq", cldr ), "Q1" );
assert.equal( format( date2, "qqq", cldr ), "Q3" );
assert.equal( format( date1, properties( "QQQ", cldr ) ), "Q1" );
assert.equal( format( date2, properties( "QQQ", cldr ) ), "Q3" );
assert.equal( format( date1, properties( "qqq", cldr ) ), "Q1" );
assert.equal( format( date2, properties( "qqq", cldr ) ), "Q3" );
});
QUnit.test( "should format quarter (QQQQ|qqqq) with padding", function( assert ) {
assert.equal( format( date1, "QQQQ", cldr ), "1st quarter" );
assert.equal( format( date2, "QQQQ", cldr ), "3rd quarter" );
assert.equal( format( date1, "qqqq", cldr ), "1st quarter" );
assert.equal( format( date2, "qqqq", cldr ), "3rd quarter" );
assert.equal( format( date1, properties( "QQQQ", cldr ) ), "1st quarter" );
assert.equal( format( date2, properties( "QQQQ", cldr ) ), "3rd quarter" );
assert.equal( format( date1, properties( "qqqq", cldr ) ), "1st quarter" );
assert.equal( format( date2, properties( "qqqq", cldr ) ), "3rd quarter" );
});

@@ -139,34 +140,34 @@

QUnit.test( "should format month (M|L) with no padding", function( assert ) {
assert.equal( format( date1, "M", cldr ), "1" );
assert.equal( format( date2, "M", cldr ), "9" );
assert.equal( format( date1, "L", cldr ), "1" );
assert.equal( format( date2, "L", cldr ), "9" );
assert.equal( format( date1, properties( "M", cldr ) ), "1" );
assert.equal( format( date2, properties( "M", cldr ) ), "9" );
assert.equal( format( date1, properties( "L", cldr ) ), "1" );
assert.equal( format( date2, properties( "L", cldr ) ), "9" );
});
QUnit.test( "should format month (MM|LL) with padding", function( assert ) {
assert.equal( format( date1, "MM", cldr ), "01" );
assert.equal( format( date2, "MM", cldr ), "09" );
assert.equal( format( date1, "LL", cldr ), "01" );
assert.equal( format( date2, "LL", cldr ), "09" );
assert.equal( format( date1, properties( "MM", cldr ) ), "01" );
assert.equal( format( date2, properties( "MM", cldr ) ), "09" );
assert.equal( format( date1, properties( "LL", cldr ) ), "01" );
assert.equal( format( date2, properties( "LL", cldr ) ), "09" );
});
QUnit.test( "should format month (MMM|LLL)", function( assert ) {
assert.equal( format( date1, "MMM", cldr ), "Jan" );
assert.equal( format( date2, "MMM", cldr ), "Sep" );
assert.equal( format( date1, "LLL", cldr ), "Jan" );
assert.equal( format( date2, "LLL", cldr ), "Sep" );
assert.equal( format( date1, properties( "MMM", cldr ) ), "Jan" );
assert.equal( format( date2, properties( "MMM", cldr ) ), "Sep" );
assert.equal( format( date1, properties( "LLL", cldr ) ), "Jan" );
assert.equal( format( date2, properties( "LLL", cldr ) ), "Sep" );
});
QUnit.test( "should format month (MMMM|LLLL)", function( assert ) {
assert.equal( format( date1, "MMMM", cldr ), "January" );
assert.equal( format( date2, "MMMM", cldr ), "September" );
assert.equal( format( date1, "LLLL", cldr ), "January" );
assert.equal( format( date2, "LLLL", cldr ), "September" );
assert.equal( format( date1, properties( "MMMM", cldr ) ), "January" );
assert.equal( format( date2, properties( "MMMM", cldr ) ), "September" );
assert.equal( format( date1, properties( "LLLL", cldr ) ), "January" );
assert.equal( format( date2, properties( "LLLL", cldr ) ), "September" );
});
QUnit.test( "should format month (MMMMM|LLLLL)", function( assert ) {
assert.equal( format( date1, "MMMMM", cldr ), "J" );
assert.equal( format( date2, "MMMMM", cldr ), "S" );
assert.equal( format( date1, "LLLLL", cldr ), "J" );
assert.equal( format( date2, "LLLLL", cldr ), "S" );
assert.equal( format( date1, properties( "MMMMM", cldr ) ), "J" );
assert.equal( format( date2, properties( "MMMMM", cldr ) ), "S" );
assert.equal( format( date1, properties( "LLLLL", cldr ) ), "J" );
assert.equal( format( date2, properties( "LLLLL", cldr ) ), "S" );
});

@@ -179,15 +180,15 @@

QUnit.test( "should format week of year (w) with no padding", function( assert ) {
assert.equal( format( date1, "w", cldr ), "1" );
assert.equal( format( date2, "w", cldr ), "38" );
assert.equal( format( date1, properties( "w", cldr ) ), "1" );
assert.equal( format( date2, properties( "w", cldr ) ), "38" );
});
QUnit.test( "should format week of year (ww) with padding", function( assert ) {
assert.equal( format( date1, "ww", cldr ), "01" );
assert.equal( format( date2, "ww", cldr ), "38" );
assert.equal( format( date1, properties( "ww", cldr ) ), "01" );
assert.equal( format( date2, properties( "ww", cldr ) ), "38" );
});
QUnit.test( "should format week of month (W)", function( assert ) {
assert.equal( format( date1, "W", cldr ), "1" );
assert.equal( format( date2, "W", cldr ), "3" );
assert.equal( format( date3, "W", cldr ), "5" );
assert.equal( format( date1, properties( "W", cldr ) ), "1" );
assert.equal( format( date2, properties( "W", cldr ) ), "3" );
assert.equal( format( date3, properties( "W", cldr ) ), "5" );
});

@@ -200,25 +201,25 @@

QUnit.test( "should format day (d) with no padding", function( assert ) {
assert.equal( format( date1, "d", cldr ), "2" );
assert.equal( format( date2, "d", cldr ), "15" );
assert.equal( format( date1, properties( "d", cldr ) ), "2" );
assert.equal( format( date2, properties( "d", cldr ) ), "15" );
});
QUnit.test( "should format day (dd) with padding", function( assert ) {
assert.equal( format( date1, "dd", cldr ), "02" );
assert.equal( format( date2, "dd", cldr ), "15" );
assert.equal( format( date1, properties( "dd", cldr ) ), "02" );
assert.equal( format( date2, properties( "dd", cldr ) ), "15" );
});
QUnit.test( "should format day of year (D) with no padding", function( assert ) {
assert.equal( format( date1, "D", cldr ), "2" );
assert.equal( format( date2, "D", cldr ), "258" );
assert.equal( format( date1, properties( "D", cldr ) ), "2" );
assert.equal( format( date2, properties( "D", cldr ) ), "258" );
});
QUnit.test( "should format day of year (DD|DDD) with padding", function( assert ) {
assert.equal( format( date1, "DD", cldr ), "02" );
assert.equal( format( date1, "DDD", cldr ), "002" );
assert.equal( format( date2, "DD", cldr ), "258" );
assert.equal( format( date1, properties( "DD", cldr ) ), "02" );
assert.equal( format( date1, properties( "DDD", cldr ) ), "002" );
assert.equal( format( date2, properties( "DD", cldr ) ), "258" );
});
QUnit.test( "should format day of week in month (F)", function( assert ) {
assert.equal( format( date1, "F", cldr ), "1" );
assert.equal( format( date2, "F", cldr ), "3" );
assert.equal( format( date1, properties( "F", cldr ) ), "1" );
assert.equal( format( date2, properties( "F", cldr ) ), "3" );
});

@@ -231,53 +232,53 @@

QUnit.test( "should format local day of week (e|c) with no padding", function( assert ) {
assert.equal( format( date1, "e", cldr ), "7" );
assert.equal( format( date2, "e", cldr ), "4" );
assert.equal( format( date1, "c", cldr ), "7" );
assert.equal( format( date2, "c", cldr ), "4" );
assert.equal( format( date1, properties( "e", cldr ) ), "7" );
assert.equal( format( date2, properties( "e", cldr ) ), "4" );
assert.equal( format( date1, properties( "c", cldr ) ), "7" );
assert.equal( format( date2, properties( "c", cldr ) ), "4" );
});
QUnit.test( "should format local day of week (ee|cc) with padding", function( assert ) {
assert.equal( format( date1, "ee", cldr ), "07" );
assert.equal( format( date2, "ee", cldr ), "04" );
assert.equal( format( date1, "cc", cldr ), "07" );
assert.equal( format( date2, "cc", cldr ), "04" );
assert.equal( format( date1, properties( "ee", cldr ) ), "07" );
assert.equal( format( date2, properties( "ee", cldr ) ), "04" );
assert.equal( format( date1, properties( "cc", cldr ) ), "07" );
assert.equal( format( date2, properties( "cc", cldr ) ), "04" );
});
QUnit.test( "should format local day of week (E|EE|EEE|eee|ccc)", function( assert ) {
assert.equal( format( date1, "E", cldr ), "Sat" );
assert.equal( format( date2, "E", cldr ), "Wed" );
assert.equal( format( date1, "EE", cldr ), "Sat" );
assert.equal( format( date2, "EE", cldr ), "Wed" );
assert.equal( format( date1, "EEE", cldr ), "Sat" );
assert.equal( format( date2, "EEE", cldr ), "Wed" );
assert.equal( format( date1, "eee", cldr ), "Sat" );
assert.equal( format( date2, "eee", cldr ), "Wed" );
assert.equal( format( date1, "ccc", cldr ), "Sat" );
assert.equal( format( date2, "ccc", cldr ), "Wed" );
assert.equal( format( date1, properties( "E", cldr ) ), "Sat" );
assert.equal( format( date2, properties( "E", cldr ) ), "Wed" );
assert.equal( format( date1, properties( "EE", cldr ) ), "Sat" );
assert.equal( format( date2, properties( "EE", cldr ) ), "Wed" );
assert.equal( format( date1, properties( "EEE", cldr ) ), "Sat" );
assert.equal( format( date2, properties( "EEE", cldr ) ), "Wed" );
assert.equal( format( date1, properties( "eee", cldr ) ), "Sat" );
assert.equal( format( date2, properties( "eee", cldr ) ), "Wed" );
assert.equal( format( date1, properties( "ccc", cldr ) ), "Sat" );
assert.equal( format( date2, properties( "ccc", cldr ) ), "Wed" );
});
QUnit.test( "should format local day of week (EEEE|eeee|cccc)", function( assert ) {
assert.equal( format( date1, "EEEE", cldr ), "Saturday" );
assert.equal( format( date2, "EEEE", cldr ), "Wednesday" );
assert.equal( format( date1, "eeee", cldr ), "Saturday" );
assert.equal( format( date2, "eeee", cldr ), "Wednesday" );
assert.equal( format( date1, "cccc", cldr ), "Saturday" );
assert.equal( format( date2, "cccc", cldr ), "Wednesday" );
assert.equal( format( date1, properties( "EEEE", cldr ) ), "Saturday" );
assert.equal( format( date2, properties( "EEEE", cldr ) ), "Wednesday" );
assert.equal( format( date1, properties( "eeee", cldr ) ), "Saturday" );
assert.equal( format( date2, properties( "eeee", cldr ) ), "Wednesday" );
assert.equal( format( date1, properties( "cccc", cldr ) ), "Saturday" );
assert.equal( format( date2, properties( "cccc", cldr ) ), "Wednesday" );
});
QUnit.test( "should format local day of week (EEEEE|eeeee|ccccc)", function( assert ) {
assert.equal( format( date1, "EEEEE", cldr ), "S" );
assert.equal( format( date2, "EEEEE", cldr ), "W" );
assert.equal( format( date1, "eeeee", cldr ), "S" );
assert.equal( format( date2, "eeeee", cldr ), "W" );
assert.equal( format( date1, "ccccc", cldr ), "S" );
assert.equal( format( date2, "ccccc", cldr ), "W" );
assert.equal( format( date1, properties( "EEEEE", cldr ) ), "S" );
assert.equal( format( date2, properties( "EEEEE", cldr ) ), "W" );
assert.equal( format( date1, properties( "eeeee", cldr ) ), "S" );
assert.equal( format( date2, properties( "eeeee", cldr ) ), "W" );
assert.equal( format( date1, properties( "ccccc", cldr ) ), "S" );
assert.equal( format( date2, properties( "ccccc", cldr ) ), "W" );
});
QUnit.test( "should format local day of week (EEEEEE|eeeeee|cccccc)", function( assert ) {
assert.equal( format( date1, "EEEEEE", cldr ), "Sa" );
assert.equal( format( date2, "EEEEEE", cldr ), "We" );
assert.equal( format( date1, "eeeeee", cldr ), "Sa" );
assert.equal( format( date2, "eeeeee", cldr ), "We" );
assert.equal( format( date1, "cccccc", cldr ), "Sa" );
assert.equal( format( date2, "cccccc", cldr ), "We" );
assert.equal( format( date1, properties( "EEEEEE", cldr ) ), "Sa" );
assert.equal( format( date2, properties( "EEEEEE", cldr ) ), "We" );
assert.equal( format( date1, properties( "eeeeee", cldr ) ), "Sa" );
assert.equal( format( date2, properties( "eeeeee", cldr ) ), "We" );
assert.equal( format( date1, properties( "cccccc", cldr ) ), "Sa" );
assert.equal( format( date2, properties( "cccccc", cldr ) ), "We" );
});

@@ -290,4 +291,4 @@

QUnit.test( "should format period (a)", function( assert ) {
assert.equal( format( date1, "a", cldr ), "AM" );
assert.equal( format( date2, "a", cldr ), "PM" );
assert.equal( format( date1, properties( "a", cldr ) ), "AM" );
assert.equal( format( date2, properties( "a", cldr ) ), "PM" );
});

@@ -300,62 +301,62 @@

QUnit.test( "should format hour (h) using 12-hour-cycle [1-12] with no padding", function( assert ) {
assert.equal( format( date1, "h", cldr ), "9" );
assert.equal( format( date2, "h", cldr ), "5" );
assert.equal( format( new Date( 0, 0, 0, 0 ), "h", cldr ), "12" );
assert.equal( format( date1, properties( "h", cldr ) ), "9" );
assert.equal( format( date2, properties( "h", cldr ) ), "5" );
assert.equal( format( new Date( 0, 0, 0, 0 ), properties( "h", cldr ) ), "12" );
});
QUnit.test( "should format hour (hh) using 12-hour-cycle [1-12] with padding", function( assert ) {
assert.equal( format( date1, "hh", cldr ), "09" );
assert.equal( format( date2, "hh", cldr ), "05" );
assert.equal( format( new Date( 0, 0, 0, 0 ), "hh", cldr ), "12" );
assert.equal( format( date1, properties( "hh", cldr ) ), "09" );
assert.equal( format( date2, properties( "hh", cldr ) ), "05" );
assert.equal( format( new Date( 0, 0, 0, 0 ), properties( "hh", cldr ) ), "12" );
});
QUnit.test( "should format hour (H) using 24-hour-cycle [0-23] with no padding", function( assert ) {
assert.equal( format( date1, "H", cldr ), "9" );
assert.equal( format( date2, "H", cldr ), "17" );
assert.equal( format( new Date( 0, 0, 0, 0 ), "H", cldr ), "0" );
assert.equal( format( date1, properties( "H", cldr ) ), "9" );
assert.equal( format( date2, properties( "H", cldr ) ), "17" );
assert.equal( format( new Date( 0, 0, 0, 0 ), properties( "H", cldr ) ), "0" );
});
QUnit.test( "should format hour (HH) using 24-hour-cycle [0-23] with padding", function( assert ) {
assert.equal( format( date1, "HH", cldr ), "09" );
assert.equal( format( date2, "HH", cldr ), "17" );
assert.equal( format( new Date( 0, 0, 0, 0 ), "HH", cldr ), "00" );
assert.equal( format( date1, properties( "HH", cldr ) ), "09" );
assert.equal( format( date2, properties( "HH", cldr ) ), "17" );
assert.equal( format( new Date( 0, 0, 0, 0 ), properties( "HH", cldr ) ), "00" );
});
QUnit.test( "should format hour (K) using 12-hour-cycle [0-11] with no padding", function( assert ) {
assert.equal( format( date1, "K", cldr ), "9" );
assert.equal( format( date2, "K", cldr ), "5" );
assert.equal( format( new Date( 0, 0, 0, 0 ), "K", cldr ), "0" );
assert.equal( format( date1, properties( "K", cldr ) ), "9" );
assert.equal( format( date2, properties( "K", cldr ) ), "5" );
assert.equal( format( new Date( 0, 0, 0, 0 ), properties( "K", cldr ) ), "0" );
});
QUnit.test( "should format hour (KK) using 12-hour-cycle [0-11] with padding", function( assert ) {
assert.equal( format( date1, "KK", cldr ), "09" );
assert.equal( format( date2, "KK", cldr ), "05" );
assert.equal( format( new Date( 0, 0, 0, 0 ), "KK", cldr ), "00" );
assert.equal( format( date1, properties( "KK", cldr ) ), "09" );
assert.equal( format( date2, properties( "KK", cldr ) ), "05" );
assert.equal( format( new Date( 0, 0, 0, 0 ), properties( "KK", cldr ) ), "00" );
});
QUnit.test( "should format hour (k) using 24-hour-cycle [1-24] with no padding", function( assert ) {
assert.equal( format( date1, "k", cldr ), "9" );
assert.equal( format( date2, "k", cldr ), "17" );
assert.equal( format( new Date( 0, 0, 0, 0 ), "k", cldr ), "24" );
assert.equal( format( date1, properties( "k", cldr ) ), "9" );
assert.equal( format( date2, properties( "k", cldr ) ), "17" );
assert.equal( format( new Date( 0, 0, 0, 0 ), properties( "k", cldr ) ), "24" );
});
QUnit.test( "should format hour (kk) using 24-hour-cycle [1-24] with padding", function( assert ) {
assert.equal( format( date1, "kk", cldr ), "09" );
assert.equal( format( date2, "kk", cldr ), "17" );
assert.equal( format( new Date( 0, 0, 0, 0 ), "kk", cldr ), "24" );
assert.equal( format( date1, properties( "kk", cldr ) ), "09" );
assert.equal( format( date2, properties( "kk", cldr ) ), "17" );
assert.equal( format( new Date( 0, 0, 0, 0 ), properties( "kk", cldr ) ), "24" );
});
QUnit.test( "should format hour (j) using preferred hour format for the locale (h, H, K, or k) with no padding", function( assert ) {
assert.equal( format( date2, "j", cldr ), "5" );
assert.equal( format( date2, "j", new Cldr( "pt-BR" ) ), "17" );
assert.equal( format( date2, "j", new Cldr( "de" ) ), "17" );
assert.equal( format( date2, "j", new Cldr( "en-IN" ) ), "5" );
assert.equal( format( date2, "j", new Cldr( "en-GB" ) ), "17" );
assert.equal( format( date2, "j", new Cldr( "ru" ) ), "17" );
assert.equal( format( date2, properties( "j", cldr ) ), "5" );
assert.equal( format( date2, properties( "j", new Cldr( "pt-BR" ) ) ), "17" );
assert.equal( format( date2, properties( "j", new Cldr( "de" ) ) ), "17" );
assert.equal( format( date2, properties( "j", new Cldr( "en-IN" ) ) ), "5" );
assert.equal( format( date2, properties( "j", new Cldr( "en-GB" ) ) ), "17" );
assert.equal( format( date2, properties( "j", new Cldr( "ru" ) ) ), "17" );
});
QUnit.test( "should format hour (jj) using preferred hour format for the locale (h, H, K, or k) with padding", function( assert ) {
assert.equal( format( date1, "jj", cldr ), "09" );
assert.equal( format( date2, "jj", cldr ), "05" );
assert.equal( format( new Date( 0, 0, 0, 0 ), "jj", cldr ), "12" );
assert.equal( format( date1, properties( "jj", cldr ) ), "09" );
assert.equal( format( date2, properties( "jj", cldr ) ), "05" );
assert.equal( format( new Date( 0, 0, 0, 0 ), properties( "jj", cldr ) ), "12" );
});

@@ -368,9 +369,9 @@

QUnit.test( "should format minute (m) with no padding", function( assert ) {
assert.equal( format( date1, "m", cldr ), "5" );
assert.equal( format( date2, "m", cldr ), "35" );
assert.equal( format( date1, properties( "m", cldr ) ), "5" );
assert.equal( format( date2, properties( "m", cldr ) ), "35" );
});
QUnit.test( "should format minute (mm) with padding", function( assert ) {
assert.equal( format( date1, "mm", cldr ), "05" );
assert.equal( format( date2, "mm", cldr ), "35" );
assert.equal( format( date1, properties( "mm", cldr ) ), "05" );
assert.equal( format( date2, properties( "mm", cldr ) ), "35" );
});

@@ -383,25 +384,25 @@

QUnit.test( "should format second (s) with no padding", function( assert ) {
assert.equal( format( date1, "s", cldr ), "59" );
assert.equal( format( date2, "s", cldr ), "7" );
assert.equal( format( date1, properties( "s", cldr ) ), "59" );
assert.equal( format( date2, properties( "s", cldr ) ), "7" );
});
QUnit.test( "should format second (ss) with padding", function( assert ) {
assert.equal( format( date1, "ss", cldr ), "59" );
assert.equal( format( date2, "ss", cldr ), "07" );
assert.equal( format( date1, properties( "ss", cldr ) ), "59" );
assert.equal( format( date2, properties( "ss", cldr ) ), "07" );
});
QUnit.test( "should format various milliseconds (S+)", function( assert ) {
assert.equal( format( date2, "S", cldr ), "4" );
assert.equal( format( date2, "SS", cldr ), "37" );
assert.equal( format( date2, "SSS", cldr ), "369" );
assert.equal( format( date2, "SSSS", cldr ), "3690" );
assert.equal( format( date2, "SSSSS", cldr ), "36900" );
assert.equal( format( date2, properties( "S", cldr ) ), "4" );
assert.equal( format( date2, properties( "SS", cldr ) ), "37" );
assert.equal( format( date2, properties( "SSS", cldr ) ), "369" );
assert.equal( format( date2, properties( "SSSS", cldr ) ), "3690" );
assert.equal( format( date2, properties( "SSSSS", cldr ) ), "36900" );
});
QUnit.test( "should format various milliseconds (A+)", function( assert ) {
assert.equal( format( date2, "A", cldr ), "633074" );
assert.equal( format( date2, "AA", cldr ), "6330737" );
assert.equal( format( date2, "AAA", cldr ), "63307369" );
assert.equal( format( date2, "AAAA", cldr ), "633073690" );
assert.equal( format( date2, "AAAAA", cldr ), "6330736900" );
assert.equal( format( date2, properties( "A", cldr ) ), "633074" );
assert.equal( format( date2, properties( "AA", cldr ) ), "6330737" );
assert.equal( format( date2, properties( "AAA", cldr ) ), "63307369" );
assert.equal( format( date2, properties( "AAAA", cldr ) ), "633073690" );
assert.equal( format( date2, properties( "AAAAA", cldr ) ), "6330736900" );
});

@@ -408,0 +409,0 @@

define([
"cldr",
"src/date/parse",
"src/date/parse-properties",
"src/date/start-of",
"src/date/tokenizer",
"src/date/tokenizer-properties",
"json!fixtures/cldr/main/en/ca-gregorian.json",

@@ -10,6 +13,12 @@ "json!fixtures/cldr/supplemental/likelySubtags.json",

"cldr/supplemental"
], function( Cldr, parse, startOf, enCaGregorian, likelySubtags, timeData, weekData ) {
], function( Cldr, parse, parseProperties, startOf, tokenizer, tokenizerProperties, enCaGregorian,
likelySubtags, timeData, weekData ) {
var cldr, date1, date2;
function assertParse( assert, stringDate, pattern, cldr, date ) {
var tokens = tokenizer( stringDate, tokenizerProperties( pattern, cldr ) );
assert.deepEqual( parse( stringDate, tokens, parseProperties( cldr ) ), date );
}
Cldr.load( enCaGregorian );

@@ -22,3 +31,3 @@ Cldr.load( likelySubtags );

QUnit.module( "Datetime Parse" );
QUnit.module( "Date Parse" );

@@ -34,8 +43,8 @@ /**

date2.setFullYear( -4 );
assert.deepEqual( parse( "AD 4", "G y", cldr ), date1 );
assert.deepEqual( parse( "BC 5", "G y", cldr ), date2 );
assert.deepEqual( parse( "AD 4", "GG y", cldr ), date1 );
assert.deepEqual( parse( "BC 5", "GG y", cldr ), date2 );
assert.deepEqual( parse( "AD 4", "GGG y", cldr ), date1 );
assert.deepEqual( parse( "BC 5", "GGG y", cldr ), date2 );
assertParse( assert, "AD 4", "G y", cldr, date1 );
assertParse( assert, "BC 5", "G y", cldr, date2 );
assertParse( assert, "AD 4", "GG y", cldr, date1 );
assertParse( assert, "BC 5", "GG y", cldr, date2 );
assertParse( assert, "AD 4", "GGG y", cldr, date1 );
assertParse( assert, "BC 5", "GGG y", cldr, date2 );
});

@@ -48,4 +57,4 @@

date2.setFullYear( -4 );
assert.deepEqual( parse( "Anno Domini 4", "GGGG y", cldr ), date1 );
assert.deepEqual( parse( "Before Christ 5", "GGGG y", cldr ), date2 );
assertParse( assert, "Anno Domini 4", "GGGG y", cldr, date1 );
assertParse( assert, "Before Christ 5", "GGGG y", cldr, date2 );
});

@@ -58,4 +67,4 @@

date2.setFullYear( -4 );
assert.deepEqual( parse( "A 4", "GGGGG y", cldr ), date1 );
assert.deepEqual( parse( "B 5", "GGGGG y", cldr ), date2 );
assertParse( assert, "A 4", "GGGGG y", cldr, date1 );
assertParse( assert, "B 5", "GGGGG y", cldr, date2 );
});

@@ -68,3 +77,3 @@

QUnit.test( "should parse year (y) with no padding", function( assert ) {
assert.deepEqual( parse( "1982", "y", cldr ), new Date( 1982, 0 ) );
assertParse( assert, "1982", "y", cldr, new Date( 1982, 0 ) );
});

@@ -74,8 +83,8 @@

// This may change in the future, eg. 82 could eventually be 2082.
assert.deepEqual( parse( "82", "yy", cldr ), new Date( 1982, 0 ) );
assertParse( assert, "82", "yy", cldr, new Date( 1982, 0 ) );
});
QUnit.test( "should parse year (yyy+) with padding", function( assert ) {
assert.deepEqual( parse( "1982", "yyy", cldr ), new Date( 1982, 0 ) );
assert.deepEqual( parse( "01982", "yyyyy", cldr ), new Date( 1982, 0 ) );
assertParse( assert, "1982", "yyy", cldr, new Date( 1982, 0 ) );
assertParse( assert, "01982", "yyyyy", cldr, new Date( 1982, 0 ) );
});

@@ -91,4 +100,4 @@

date1 = startOf( date1, "month" );
assert.deepEqual( parse( "1", "M", cldr ), date1 );
assert.deepEqual( parse( "1", "L", cldr ), date1 );
assertParse( assert, "1", "M", cldr, date1 );
assertParse( assert, "1", "L", cldr, date1 );
});

@@ -100,4 +109,4 @@

date1 = startOf( date1, "month" );
assert.deepEqual( parse( "01", "MM", cldr ), date1 );
assert.deepEqual( parse( "01", "LL", cldr ), date1 );
assertParse( assert, "01", "MM", cldr, date1 );
assertParse( assert, "01", "LL", cldr, date1 );
});

@@ -109,4 +118,4 @@

date1 = startOf( date1, "month" );
assert.deepEqual( parse( "Jan", "MMM", cldr ), date1 );
assert.deepEqual( parse( "Jan", "LLL", cldr ), date1 );
assertParse( assert, "Jan", "MMM", cldr, date1 );
assertParse( assert, "Jan", "LLL", cldr, date1 );
});

@@ -118,4 +127,4 @@

date1 = startOf( date1, "month" );
assert.deepEqual( parse( "January", "MMMM", cldr ), date1 );
assert.deepEqual( parse( "January", "LLLL", cldr ), date1 );
assertParse( assert, "January", "MMMM", cldr, date1 );
assertParse( assert, "January", "LLLL", cldr, date1 );
});

@@ -127,4 +136,4 @@

date1 = startOf( date1, "month" );
assert.deepEqual( parse( "J", "MMMMM", cldr ), date1 );
assert.deepEqual( parse( "J", "LLLLL", cldr ), date1 );
assertParse( assert, "J", "MMMMM", cldr, date1 );
assertParse( assert, "J", "LLLLL", cldr, date1 );
});

@@ -140,3 +149,3 @@

date1 = startOf( date1, "day" );
assert.deepEqual( parse( "2", "d", cldr ), date1 );
assertParse( assert, "2", "d", cldr, date1 );
});

@@ -148,3 +157,3 @@

date1 = startOf( date1, "day" );
assert.deepEqual( parse( "02", "dd", cldr ), date1 );
assertParse( assert, "02", "dd", cldr, date1 );
});

@@ -157,3 +166,3 @@

date1 = startOf( date1, "day" );
assert.deepEqual( parse( "2", "D", cldr ), date1 );
assertParse( assert, "2", "D", cldr, date1 );
});

@@ -166,4 +175,4 @@

date1 = startOf( date1, "day" );
assert.deepEqual( parse( "02", "DD", cldr ), date1 );
assert.deepEqual( parse( "002", "DDD", cldr ), date1 );
assertParse( assert, "02", "DD", cldr, date1 );
assertParse( assert, "002", "DDD", cldr, date1 );
});

@@ -182,4 +191,4 @@

date2 = startOf( date2, "hour" );
assert.deepEqual( parse( "5 AM", "h a", cldr ), date1 );
assert.deepEqual( parse( "5 PM", "h a", cldr ), date2 );
assertParse( assert, "5 AM", "h a", cldr, date1 );
assertParse( assert, "5 PM", "h a", cldr, date2 );
});

@@ -192,5 +201,5 @@

QUnit.test( "should parse hour (h) using 12-hour-cycle [1-12] with no padding", function( assert ) {
assert.equal( parse( "1", "h", cldr ), null, "12-hour time without period should return null" );
assert.equal( parse( "0 AM", "h a", cldr ), null, "Out of range should return null" );
assert.equal( parse( "13 AM", "h a", cldr ), null, "Out of range should return null" );
assertParse( assert, "1", "h", cldr, null, "12-hour time without period should return null" );
assertParse( assert, "0 AM", "h a", cldr, null, "Out of range should return null" );
assertParse( assert, "13 AM", "h a", cldr, null, "Out of range should return null" );

@@ -200,15 +209,15 @@ date1 = new Date();

date1 = startOf( date1, "hour" );
assert.deepEqual( parse( "9 AM", "h a", cldr ), date1 );
assertParse( assert, "9 AM", "h a", cldr, date1 );
date1.setHours( 0 );
assert.deepEqual( parse( "12 AM", "h a", cldr ), date1 );
assertParse( assert, "12 AM", "h a", cldr, date1 );
date1.setHours( 1 );
assert.deepEqual( parse( "1 AM", "h a", cldr ), date1 );
assertParse( assert, "1 AM", "h a", cldr, date1 );
date1.setHours( 12 );
assert.deepEqual( parse( "12 PM", "h a", cldr ), date1 );
assertParse( assert, "12 PM", "h a", cldr, date1 );
date1.setHours( 13 );
assert.deepEqual( parse( "1 PM", "h a", cldr ), date1 );
assertParse( assert, "1 PM", "h a", cldr, date1 );
});

@@ -220,7 +229,7 @@

date1 = startOf( date1, "hour" );
assert.deepEqual( parse( "09 AM", "hh a", cldr ), date1 );
assertParse( assert, "09 AM", "hh a", cldr, date1 );
});
QUnit.test( "should parse hour (H) using 24-hour-cycle [0-23] with no padding", function( assert ) {
assert.equal( parse( "24", "H", cldr ), null, "Out of range should return null" );
assertParse( assert, "24", "H", cldr, null, "Out of range should return null" );

@@ -230,12 +239,12 @@ date1 = new Date();

date1 = startOf( date1, "hour" );
assert.deepEqual( parse( "0", "H", cldr ), date1 );
assertParse( assert, "0", "H", cldr, date1 );
date1.setHours( 1 );
assert.deepEqual( parse( "1", "H", cldr ), date1 );
assertParse( assert, "1", "H", cldr, date1 );
date1.setHours( 12 );
assert.deepEqual( parse( "12", "H", cldr ), date1 );
assertParse( assert, "12", "H", cldr, date1 );
date1.setHours( 16 );
assert.deepEqual( parse( "16", "H", cldr ), date1 );
assertParse( assert, "16", "H", cldr, date1 );
});

@@ -247,12 +256,12 @@

date1 = startOf( date1, "hour" );
assert.deepEqual( parse( "09", "HH", cldr ), date1 );
assertParse( assert, "09", "HH", cldr, date1 );
date1.setHours( 16 );
assert.deepEqual( parse( "16", "HH", cldr ), date1 );
assertParse( assert, "16", "HH", cldr, date1 );
});
QUnit.test( "should parse hour (K) using 12-hour-cycle [0-11] with no padding", function( assert ) {
assert.equal( parse( "1", "K", cldr ), null, "12-hour time without period should return null" );
assert.equal( parse( "12 AM", "K a", cldr ), null, "Out of range should return null" );
assert.equal( parse( "13 AM", "K a", cldr ), null, "Out of range should return null" );
assertParse( assert, "1", "K", cldr, null, "12-hour time without period should return null" );
assertParse( assert, "12 AM", "K a", cldr, null, "Out of range should return null" );
assertParse( assert, "13 AM", "K a", cldr, null, "Out of range should return null" );

@@ -262,12 +271,12 @@ date1 = new Date();

date1 = startOf( date1, "hour" );
assert.deepEqual( parse( "0 AM", "K a", cldr ), date1 );
assertParse( assert, "0 AM", "K a", cldr, date1 );
date1.setHours( 8 );
assert.deepEqual( parse( "8 AM", "K a", cldr ), date1 );
assertParse( assert, "8 AM", "K a", cldr, date1 );
date1.setHours( 12 );
assert.deepEqual( parse( "0 PM", "K a", cldr ), date1 );
assertParse( assert, "0 PM", "K a", cldr, date1 );
date1.setHours( 20 );
assert.deepEqual( parse( "8 PM", "K a", cldr ), date1 );
assertParse( assert, "8 PM", "K a", cldr, date1 );
});

@@ -279,7 +288,7 @@

date1 = startOf( date1, "hour" );
assert.deepEqual( parse( "08 AM", "KK a", cldr ), date1 );
assertParse( assert, "08 AM", "KK a", cldr, date1 );
});
QUnit.test( "should parse hour (k) using 24-hour-cycle [1-24] with no padding", function( assert ) {
assert.equal( parse( "0", "k", cldr ), null, "Out of range should return null" );
assertParse( assert, "0", "k", cldr, null, "Out of range should return null" );

@@ -289,12 +298,12 @@ date1 = new Date();

date1 = startOf( date1, "hour" );
assert.deepEqual( parse( "24", "k", cldr ), date1 );
assertParse( assert, "24", "k", cldr, date1 );
date1.setHours( 8 );
assert.deepEqual( parse( "8", "k", cldr ), date1 );
assertParse( assert, "8", "k", cldr, date1 );
date1.setHours( 12 );
assert.deepEqual( parse( "12", "k", cldr ), date1 );
assertParse( assert, "12", "k", cldr, date1 );
date1.setHours( 20 );
assert.deepEqual( parse( "20", "k", cldr ), date1 );
assertParse( assert, "20", "k", cldr, date1 );
});

@@ -306,6 +315,6 @@

date1 = startOf( date1, "hour" );
assert.deepEqual( parse( "05", "kk", cldr ), date1 );
assertParse( assert, "05", "kk", cldr, date1 );
date1.setHours( 17 );
assert.deepEqual( parse( "17", "kk", cldr ), date1 );
assertParse( assert, "17", "kk", cldr, date1 );
});

@@ -317,3 +326,3 @@

date1 = startOf( date1, "hour" );
assert.deepEqual( parse( "9 AM", "j a", cldr ), date1 );
assertParse( assert, "9 AM", "j a", cldr, date1 );
});

@@ -325,3 +334,3 @@

date1 = startOf( date1, "hour" );
assert.deepEqual( parse( "09 AM", "jj a", cldr ), date1 );
assertParse( assert, "09 AM", "jj a", cldr, date1 );
});

@@ -337,3 +346,3 @@

date1 = startOf( date1, "minute" );
assert.deepEqual( parse( "5", "m", cldr ), date1 );
assertParse( assert, "5", "m", cldr, date1 );
});

@@ -345,3 +354,3 @@

date1 = startOf( date1, "minute" );
assert.deepEqual( parse( "05", "mm", cldr ), date1 );
assertParse( assert, "05", "mm", cldr, date1 );
});

@@ -357,3 +366,3 @@

date1 = startOf( date1, "second" );
assert.deepEqual( parse( "59", "s", cldr ), date1 );
assertParse( assert, "59", "s", cldr, date1 );
});

@@ -365,3 +374,3 @@

date1 = startOf( date1, "second" );
assert.deepEqual( parse( "59", "ss", cldr ), date1 );
assertParse( assert, "59", "ss", cldr, date1 );
});

@@ -373,9 +382,9 @@

date1.setMilliseconds( 400 );
assert.deepEqual( parse( "0 4", "s S", cldr ), date1 );
assertParse( assert, "0 4", "s S", cldr, date1 );
date1.setMilliseconds( 370 );
assert.deepEqual( parse( "0 37", "s SS", cldr ), date1 );
assertParse( assert, "0 37", "s SS", cldr, date1 );
date1.setMilliseconds( 369 );
assert.deepEqual( parse( "0 369", "s SSS", cldr ), date1 );
assert.deepEqual( parse( "0 3690", "s SSSS", cldr ), date1 );
assert.deepEqual( parse( "0 36900", "s SSSSS", cldr ), date1 );
assertParse( assert, "0 369", "s SSS", cldr, date1 );
assertParse( assert, "0 3690", "s SSSS", cldr, date1 );
assertParse( assert, "0 36900", "s SSSSS", cldr, date1 );
});

@@ -387,11 +396,11 @@

date1.setMilliseconds( 63307400 );
assert.deepEqual( parse( "633074", "A", cldr ), date1 );
assertParse( assert, "633074", "A", cldr, date1 );
date1 = startOf( date1, "day" );
date1.setMilliseconds( 63307370 );
assert.deepEqual( parse( "6330737", "AA", cldr ), date1 );
assertParse( assert, "6330737", "AA", cldr, date1 );
date1 = startOf( date1, "day" );
date1.setMilliseconds( 63307369 );
assert.deepEqual( parse( "63307369", "AAA", cldr ), date1 );
assert.deepEqual( parse( "633073690", "AAAA", cldr ), date1 );
assert.deepEqual( parse( "6330736900", "AAAAA", cldr ), date1 );
assertParse( assert, "63307369", "AAA", cldr, date1 );
assertParse( assert, "633073690", "AAAA", cldr, date1 );
assertParse( assert, "6330736900", "AAAAA", cldr, date1 );
});

@@ -398,0 +407,0 @@

define([
"cldr",
"src/date/tokenizer",
"src/date/tokenizer-properties",
"json!fixtures/cldr/main/en/ca-gregorian.json",

@@ -8,3 +9,3 @@ "json!fixtures/cldr/supplemental/likelySubtags.json",

"json!fixtures/cldr/supplemental/weekData.json"
], function( Cldr, tokenizer, enCaGregorian, likelySubtags, timeData, weekData ) {
], function( Cldr, tokenizer, properties, enCaGregorian, likelySubtags, timeData, weekData ) {

@@ -20,3 +21,3 @@ var cldr;

QUnit.module( "Datetime Tokenizer" );
QUnit.module( "Date Tokenizer" );

@@ -28,3 +29,3 @@ /**

QUnit.test( "should tokenize era (G|GG|GGG)", function( assert ) {
assert.deepEqual( tokenizer( "AD", "G", cldr ), [{
assert.deepEqual( tokenizer( "AD", properties( "G", cldr ) ), [{
type: "G",

@@ -34,3 +35,3 @@ lexeme: "AD",

}] );
assert.deepEqual( tokenizer( "AD", "GG", cldr ), [{
assert.deepEqual( tokenizer( "AD", properties( "GG", cldr ) ), [{
type: "GG",

@@ -40,3 +41,3 @@ lexeme: "AD",

}] );
assert.deepEqual( tokenizer( "AD", "GGG", cldr ), [{
assert.deepEqual( tokenizer( "AD", properties( "GGG", cldr ) ), [{
type: "GGG",

@@ -49,3 +50,3 @@ lexeme: "AD",

QUnit.test( "should tokenize era (GGGG)", function( assert ) {
assert.deepEqual( tokenizer( "Anno Domini", "GGGG", cldr ), [{
assert.deepEqual( tokenizer( "Anno Domini", properties( "GGGG", cldr ) ), [{
type: "GGGG",

@@ -58,3 +59,3 @@ lexeme: "Anno Domini",

QUnit.test( "should tokenize era (GGGGG)", function( assert ) {
assert.deepEqual( tokenizer( "A", "GGGGG", cldr ), [{
assert.deepEqual( tokenizer( "A", properties( "GGGGG", cldr ) ), [{
type: "GGGGG",

@@ -71,3 +72,3 @@ lexeme: "A",

QUnit.test( "should tokenize year (y) with no padding", function( assert ) {
assert.deepEqual( tokenizer( "1982", "y", cldr ), [{
assert.deepEqual( tokenizer( "1982", properties( "y", cldr ) ), [{
type: "y",

@@ -79,3 +80,3 @@ lexeme: "1982"

QUnit.test( "should tokenize year (yy) with padding, and limit 2 digits", function( assert ) {
assert.deepEqual( tokenizer( "82", "yy", cldr ), [{
assert.deepEqual( tokenizer( "82", properties( "yy", cldr ) ), [{
type: "yy",

@@ -87,7 +88,7 @@ lexeme: "82"

QUnit.test( "should tokenize year (yyy+) with padding", function( assert ) {
assert.deepEqual( tokenizer( "1982", "yyy", cldr ), [{
assert.deepEqual( tokenizer( "1982", properties( "yyy", cldr ) ), [{
type: "yyy",
lexeme: "1982"
}] );
assert.deepEqual( tokenizer( "01982", "yyyyy", cldr ), [{
assert.deepEqual( tokenizer( "01982", properties( "yyyyy", cldr ) ), [{
type: "yyyyy",

@@ -99,3 +100,3 @@ lexeme: "01982"

QUnit.test( "should tokenize year in \"week of year\" (Y) with no padding", function( assert ) {
assert.deepEqual( tokenizer( "1982", "Y", cldr ), [{
assert.deepEqual( tokenizer( "1982", properties( "Y", cldr ) ), [{
type: "Y",

@@ -107,3 +108,3 @@ lexeme: "1982"

QUnit.test( "should tokenize year in \"week of year\" (YY) with padding, and limit 2 digits", function( assert ) {
assert.deepEqual( tokenizer( "82", "YY", cldr ), [{
assert.deepEqual( tokenizer( "82", properties( "YY", cldr ) ), [{
type: "YY",

@@ -115,7 +116,7 @@ lexeme: "82"

QUnit.test( "should tokenize year in \"week of year\" (YYY+) with padding", function( assert ) {
assert.deepEqual( tokenizer( "1982", "YYY", cldr ), [{
assert.deepEqual( tokenizer( "1982", properties( "YYY", cldr ) ), [{
type: "YYY",
lexeme: "1982"
}] );
assert.deepEqual( tokenizer( "01982", "YYYYY", cldr ), [{
assert.deepEqual( tokenizer( "01982", properties( "YYYYY", cldr ) ), [{
type: "YYYYY",

@@ -131,7 +132,7 @@ lexeme: "01982"

QUnit.test( "should tokenize quarter (Q|q) with no padding", function( assert ) {
assert.deepEqual( tokenizer( "1", "Q", cldr ), [{
assert.deepEqual( tokenizer( "1", properties( "Q", cldr ) ), [{
type: "Q",
lexeme: "1"
}] );
assert.deepEqual( tokenizer( "1", "q", cldr ), [{
assert.deepEqual( tokenizer( "1", properties( "q", cldr ) ), [{
type: "q",

@@ -143,7 +144,7 @@ lexeme: "1"

QUnit.test( "should tokenize quarter (QQ|qq) with padding", function( assert ) {
assert.deepEqual( tokenizer( "01", "QQ", cldr ), [{
assert.deepEqual( tokenizer( "01", properties( "QQ", cldr ) ), [{
type: "QQ",
lexeme: "01"
}] );
assert.deepEqual( tokenizer( "01", "qq", cldr ), [{
assert.deepEqual( tokenizer( "01", properties( "qq", cldr ) ), [{
type: "qq",

@@ -155,3 +156,3 @@ lexeme: "01"

QUnit.test( "should tokenize quarter (QQQ|qqq)", function( assert ) {
assert.deepEqual( tokenizer( "Q1", "QQQ", cldr ), [{
assert.deepEqual( tokenizer( "Q1", properties( "QQQ", cldr ) ), [{
type: "QQQ",

@@ -161,3 +162,3 @@ lexeme: "Q1",

}] );
assert.deepEqual( tokenizer( "Q1", "qqq", cldr ), [{
assert.deepEqual( tokenizer( "Q1", properties( "qqq", cldr ) ), [{
type: "qqq",

@@ -170,3 +171,3 @@ lexeme: "Q1",

QUnit.test( "should tokenize quarter (QQQQ|qqqq) with padding", function( assert ) {
assert.deepEqual( tokenizer( "1st quarter", "QQQQ", cldr ), [{
assert.deepEqual( tokenizer( "1st quarter", properties( "QQQQ", cldr ) ), [{
type: "QQQQ",

@@ -176,3 +177,3 @@ lexeme: "1st quarter",

}] );
assert.deepEqual( tokenizer( "1st quarter", "qqqq", cldr ), [{
assert.deepEqual( tokenizer( "1st quarter", properties( "qqqq", cldr ) ), [{
type: "qqqq",

@@ -189,7 +190,7 @@ lexeme: "1st quarter",

QUnit.test( "should tokenize month (M|L) with no padding", function( assert ) {
assert.deepEqual( tokenizer( "1", "M", cldr ), [{
assert.deepEqual( tokenizer( "1", properties( "M", cldr ) ), [{
type: "M",
lexeme: "1"
}] );
assert.deepEqual( tokenizer( "1", "L", cldr ), [{
assert.deepEqual( tokenizer( "1", properties( "L", cldr ) ), [{
type: "L",

@@ -201,7 +202,7 @@ lexeme: "1"

QUnit.test( "should tokenize month (MM|LL) with padding", function( assert ) {
assert.deepEqual( tokenizer( "01", "MM", cldr ), [{
assert.deepEqual( tokenizer( "01", properties( "MM", cldr ) ), [{
type: "MM",
lexeme: "01"
}] );
assert.deepEqual( tokenizer( "01", "LL", cldr ), [{
assert.deepEqual( tokenizer( "01", properties( "LL", cldr ) ), [{
type: "LL",

@@ -213,3 +214,3 @@ lexeme: "01"

QUnit.test( "should tokenize month (MMM|LLL)", function( assert ) {
assert.deepEqual( tokenizer( "Jan", "MMM", cldr ), [{
assert.deepEqual( tokenizer( "Jan", properties( "MMM", cldr ) ), [{
type: "MMM",

@@ -219,3 +220,3 @@ lexeme: "Jan",

}] );
assert.deepEqual( tokenizer( "Jan", "LLL", cldr ), [{
assert.deepEqual( tokenizer( "Jan", properties( "LLL", cldr ) ), [{
type: "LLL",

@@ -228,3 +229,3 @@ lexeme: "Jan",

QUnit.test( "should tokenize month (MMMM|LLLL)", function( assert ) {
assert.deepEqual( tokenizer( "January", "MMMM", cldr ), [{
assert.deepEqual( tokenizer( "January", properties( "MMMM", cldr ) ), [{
type: "MMMM",

@@ -234,3 +235,3 @@ lexeme: "January",

}] );
assert.deepEqual( tokenizer( "January", "LLLL", cldr ), [{
assert.deepEqual( tokenizer( "January", properties( "LLLL", cldr ) ), [{
type: "LLLL",

@@ -243,3 +244,3 @@ lexeme: "January",

QUnit.test( "should tokenize month (MMMMM|LLLLL)", function( assert ) {
assert.deepEqual( tokenizer( "J", "MMMMM", cldr ), [{
assert.deepEqual( tokenizer( "J", properties( "MMMMM", cldr ) ), [{
type: "MMMMM",

@@ -249,3 +250,3 @@ lexeme: "J",

}] );
assert.deepEqual( tokenizer( "J", "LLLLL", cldr ), [{
assert.deepEqual( tokenizer( "J", properties( "LLLLL", cldr ) ), [{
type: "LLLLL",

@@ -262,3 +263,3 @@ lexeme: "J",

QUnit.test( "should tokenize week of year (w) with no padding", function( assert ) {
assert.deepEqual( tokenizer( "1", "w", cldr ), [{
assert.deepEqual( tokenizer( "1", properties( "w", cldr ) ), [{
type: "w",

@@ -270,3 +271,3 @@ lexeme: "1"

QUnit.test( "should tokenize week of year (ww) with padding", function( assert ) {
assert.deepEqual( tokenizer( "01", "ww", cldr ), [{
assert.deepEqual( tokenizer( "01", properties( "ww", cldr ) ), [{
type: "ww",

@@ -278,3 +279,3 @@ lexeme: "01"

QUnit.test( "should tokenize week of month (W)", function( assert ) {
assert.deepEqual( tokenizer( "1", "W", cldr ), [{
assert.deepEqual( tokenizer( "1", properties( "W", cldr ) ), [{
type: "W",

@@ -290,3 +291,3 @@ lexeme: "1"

QUnit.test( "should tokenize day (d) with no padding", function( assert ) {
assert.deepEqual( tokenizer( "2", "d", cldr ), [{
assert.deepEqual( tokenizer( "2", properties( "d", cldr ) ), [{
type: "d",

@@ -298,3 +299,3 @@ lexeme: "2"

QUnit.test( "should tokenize day (dd) with padding", function( assert ) {
assert.deepEqual( tokenizer( "02", "dd", cldr ), [{
assert.deepEqual( tokenizer( "02", properties( "dd", cldr ) ), [{
type: "dd",

@@ -306,3 +307,3 @@ lexeme: "02"

QUnit.test( "should tokenize day of year (D) with no padding", function( assert ) {
assert.deepEqual( tokenizer( "2", "D", cldr ), [{
assert.deepEqual( tokenizer( "2", properties( "D", cldr ) ), [{
type: "D",

@@ -314,7 +315,7 @@ lexeme: "2"

QUnit.test( "should tokenize day of year (DD|DDD) with padding", function( assert ) {
assert.deepEqual( tokenizer( "02", "DD", cldr ), [{
assert.deepEqual( tokenizer( "02", properties( "DD", cldr ) ), [{
type: "DD",
lexeme: "02"
}] );
assert.deepEqual( tokenizer( "002", "DDD", cldr ), [{
assert.deepEqual( tokenizer( "002", properties( "DDD", cldr ) ), [{
type: "DDD",

@@ -326,3 +327,3 @@ lexeme: "002"

QUnit.test( "should tokenize day of week in month (F)", function( assert ) {
assert.deepEqual( tokenizer( "1", "F", cldr ), [{
assert.deepEqual( tokenizer( "1", properties( "F", cldr ) ), [{
type: "F",

@@ -338,7 +339,7 @@ lexeme: "1"

QUnit.test( "should tokenize local day of week (e|c) with no padding", function( assert ) {
assert.deepEqual( tokenizer( "7", "e", cldr ), [{
assert.deepEqual( tokenizer( "7", properties( "e", cldr ) ), [{
type: "e",
lexeme: "7"
}] );
assert.deepEqual( tokenizer( "7", "c", cldr ), [{
assert.deepEqual( tokenizer( "7", properties( "c", cldr ) ), [{
type: "c",

@@ -350,7 +351,7 @@ lexeme: "7"

QUnit.test( "should tokenize local day of week (ee|cc) with padding", function( assert ) {
assert.deepEqual( tokenizer( "07", "ee", cldr ), [{
assert.deepEqual( tokenizer( "07", properties( "ee", cldr ) ), [{
type: "ee",
lexeme: "07"
}] );
assert.deepEqual( tokenizer( "07", "cc", cldr ), [{
assert.deepEqual( tokenizer( "07", properties( "cc", cldr ) ), [{
type: "cc",

@@ -362,3 +363,3 @@ lexeme: "07"

QUnit.test( "should tokenize local day of week (E|EE|EEE|eee|ccc)", function( assert ) {
assert.deepEqual( tokenizer( "Sat", "E", cldr ), [{
assert.deepEqual( tokenizer( "Sat", properties( "E", cldr ) ), [{
type: "E",

@@ -368,3 +369,3 @@ lexeme: "Sat",

}] );
assert.deepEqual( tokenizer( "Sat", "EE", cldr ), [{
assert.deepEqual( tokenizer( "Sat", properties( "EE", cldr ) ), [{
type: "EE",

@@ -374,3 +375,3 @@ lexeme: "Sat",

}] );
assert.deepEqual( tokenizer( "Sat", "EEE", cldr ), [{
assert.deepEqual( tokenizer( "Sat", properties( "EEE", cldr ) ), [{
type: "EEE",

@@ -380,3 +381,3 @@ lexeme: "Sat",

}] );
assert.deepEqual( tokenizer( "Sat", "eee", cldr ), [{
assert.deepEqual( tokenizer( "Sat", properties( "eee", cldr ) ), [{
type: "eee",

@@ -386,3 +387,3 @@ lexeme: "Sat",

}] );
assert.deepEqual( tokenizer( "Sat", "ccc", cldr ), [{
assert.deepEqual( tokenizer( "Sat", properties( "ccc", cldr ) ), [{
type: "ccc",

@@ -395,3 +396,3 @@ lexeme: "Sat",

QUnit.test( "should tokenize local day of week (EEEE|eeee|cccc)", function( assert ) {
assert.deepEqual( tokenizer( "Saturday", "EEEE", cldr ), [{
assert.deepEqual( tokenizer( "Saturday", properties( "EEEE", cldr ) ), [{
type: "EEEE",

@@ -401,3 +402,3 @@ lexeme: "Saturday",

}] );
assert.deepEqual( tokenizer( "Saturday", "eeee", cldr ), [{
assert.deepEqual( tokenizer( "Saturday", properties( "eeee", cldr ) ), [{
type: "eeee",

@@ -407,3 +408,3 @@ lexeme: "Saturday",

}] );
assert.deepEqual( tokenizer( "Saturday", "cccc", cldr ), [{
assert.deepEqual( tokenizer( "Saturday", properties( "cccc", cldr ) ), [{
type: "cccc",

@@ -417,3 +418,3 @@ lexeme: "Saturday",

// OBS: note the abbreviated S would matche sun or sat. But, only the first is returned.
assert.deepEqual( tokenizer( "S", "EEEEE", cldr ), [{
assert.deepEqual( tokenizer( "S", properties( "EEEEE", cldr ) ), [{
type: "EEEEE",

@@ -423,3 +424,3 @@ lexeme: "S",

}] );
assert.deepEqual( tokenizer( "S", "eeeee", cldr ), [{
assert.deepEqual( tokenizer( "S", properties( "eeeee", cldr ) ), [{
type: "eeeee",

@@ -429,3 +430,3 @@ lexeme: "S",

}] );
assert.deepEqual( tokenizer( "S", "ccccc", cldr ), [{
assert.deepEqual( tokenizer( "S", properties( "ccccc", cldr ) ), [{
type: "ccccc",

@@ -438,3 +439,3 @@ lexeme: "S",

QUnit.test( "should tokenize local day of week (EEEEEE|eeeeee|cccccc)", function( assert ) {
assert.deepEqual( tokenizer( "Sa", "EEEEEE", cldr ), [{
assert.deepEqual( tokenizer( "Sa", properties( "EEEEEE", cldr ) ), [{
type: "EEEEEE",

@@ -444,3 +445,3 @@ lexeme: "Sa",

}] );
assert.deepEqual( tokenizer( "Sa", "eeeeee", cldr ), [{
assert.deepEqual( tokenizer( "Sa", properties( "eeeeee", cldr ) ), [{
type: "eeeeee",

@@ -450,3 +451,3 @@ lexeme: "Sa",

}] );
assert.deepEqual( tokenizer( "Sa", "cccccc", cldr ), [{
assert.deepEqual( tokenizer( "Sa", properties( "cccccc", cldr ) ), [{
type: "cccccc",

@@ -463,3 +464,3 @@ lexeme: "Sa",

QUnit.test( "should tokenize period (a)", function( assert ) {
assert.deepEqual( tokenizer( "AM", "a", cldr ), [{
assert.deepEqual( tokenizer( "AM", properties( "a", cldr ) ), [{
type: "a",

@@ -476,3 +477,3 @@ lexeme: "AM",

QUnit.test( "should tokenize hour (h) using 12-hour-cycle [1-12] with no padding", function( assert ) {
assert.deepEqual( tokenizer( "9", "h", cldr ), [{
assert.deepEqual( tokenizer( "9", properties( "h", cldr ) ), [{
type: "h",

@@ -484,3 +485,3 @@ lexeme: "9"

QUnit.test( "should tokenize hour (hh) using 12-hour-cycle [1-12] with padding", function( assert ) {
assert.deepEqual( tokenizer( "09", "hh", cldr ), [{
assert.deepEqual( tokenizer( "09", properties( "hh", cldr ) ), [{
type: "hh",

@@ -492,3 +493,3 @@ lexeme: "09"

QUnit.test( "should tokenize hour (H) using 24-hour-cycle [0-23] with no padding", function( assert ) {
assert.deepEqual( tokenizer( "9", "H", cldr ), [{
assert.deepEqual( tokenizer( "9", properties( "H", cldr ) ), [{
type: "H",

@@ -500,3 +501,3 @@ lexeme: "9"

QUnit.test( "should tokenize hour (HH) using 24-hour-cycle [0-23] with padding", function( assert ) {
assert.deepEqual( tokenizer( "09", "HH", cldr ), [{
assert.deepEqual( tokenizer( "09", properties( "HH", cldr ) ), [{
type: "HH",

@@ -508,3 +509,3 @@ lexeme: "09"

QUnit.test( "should tokenize hour (K) using 12-hour-cycle [0-11] with no padding", function( assert ) {
assert.deepEqual( tokenizer( "9", "K", cldr ), [{
assert.deepEqual( tokenizer( "9", properties( "K", cldr ) ), [{
type: "K",

@@ -516,3 +517,3 @@ lexeme: "9"

QUnit.test( "should tokenize hour (KK) using 12-hour-cycle [0-11] with padding", function( assert ) {
assert.deepEqual( tokenizer( "09", "KK", cldr ), [{
assert.deepEqual( tokenizer( "09", properties( "KK", cldr ) ), [{
type: "KK",

@@ -524,3 +525,3 @@ lexeme: "09"

QUnit.test( "should tokenize hour (k) using 24-hour-cycle [1-24] with no padding", function( assert ) {
assert.deepEqual( tokenizer( "9", "k", cldr ), [{
assert.deepEqual( tokenizer( "9", properties( "k", cldr ) ), [{
type: "k",

@@ -532,3 +533,3 @@ lexeme: "9"

QUnit.test( "should tokenize hour (kk) using 24-hour-cycle [1-24] with padding", function( assert ) {
assert.deepEqual( tokenizer( "09", "kk", cldr ), [{
assert.deepEqual( tokenizer( "09", properties( "kk", cldr ) ), [{
type: "kk",

@@ -540,3 +541,3 @@ lexeme: "09"

QUnit.test( "should tokenize hour (j) using preferred hour format for the locale (h, H, K, or k) with no padding", function( assert ) {
assert.deepEqual( tokenizer( "9", "j", cldr ), [{
assert.deepEqual( tokenizer( "9", properties( "j", cldr ) ), [{
type: "j",

@@ -548,3 +549,3 @@ lexeme: "9"

QUnit.test( "should tokenize hour (jj) using preferred hour format for the locale (h, H, K, or k) with padding", function( assert ) {
assert.deepEqual( tokenizer( "09", "jj", cldr ), [{
assert.deepEqual( tokenizer( "09", properties( "jj", cldr ) ), [{
type: "jj",

@@ -560,3 +561,3 @@ lexeme: "09"

QUnit.test( "should tokenize minute (m) with no padding", function( assert ) {
assert.deepEqual( tokenizer( "5", "m", cldr ), [{
assert.deepEqual( tokenizer( "5", properties( "m", cldr ) ), [{
type: "m",

@@ -568,3 +569,3 @@ lexeme: "5"

QUnit.test( "should tokenize minute (mm) with padding", function( assert ) {
assert.deepEqual( tokenizer( "05", "mm", cldr ), [{
assert.deepEqual( tokenizer( "05", properties( "mm", cldr ) ), [{
type: "mm",

@@ -580,3 +581,3 @@ lexeme: "05"

QUnit.test( "should tokenize second (s) with no padding", function( assert ) {
assert.deepEqual( tokenizer( "59", "s", cldr ), [{
assert.deepEqual( tokenizer( "59", properties( "s", cldr ) ), [{
type: "s",

@@ -588,3 +589,3 @@ lexeme: "59"

QUnit.test( "should tokenize second (ss) with padding", function( assert ) {
assert.deepEqual( tokenizer( "59", "ss", cldr ), [{
assert.deepEqual( tokenizer( "59", properties( "ss", cldr ) ), [{
type: "ss",

@@ -596,19 +597,19 @@ lexeme: "59"

QUnit.test( "should tokenize milliseconds (S+)", function( assert ) {
assert.deepEqual( tokenizer( "4", "S", cldr ), [{
assert.deepEqual( tokenizer( "4", properties( "S", cldr ) ), [{
type: "S",
lexeme: "4"
}] );
assert.deepEqual( tokenizer( "37", "SS", cldr ), [{
assert.deepEqual( tokenizer( "37", properties( "SS", cldr ) ), [{
type: "SS",
lexeme: "37"
}] );
assert.deepEqual( tokenizer( "369", "SSS", cldr ), [{
assert.deepEqual( tokenizer( "369", properties( "SSS", cldr ) ), [{
type: "SSS",
lexeme: "369"
}] );
assert.deepEqual( tokenizer( "3690", "SSSS", cldr ), [{
assert.deepEqual( tokenizer( "3690", properties( "SSSS", cldr ) ), [{
type: "SSSS",
lexeme: "3690"
}] );
assert.deepEqual( tokenizer( "36900", "SSSSS", cldr ), [{
assert.deepEqual( tokenizer( "36900", properties( "SSSSS", cldr ) ), [{
type: "SSSSS",

@@ -620,19 +621,19 @@ lexeme: "36900"

QUnit.test( "should tokenize milliseconds in a day (A+)", function( assert ) {
assert.deepEqual( tokenizer( "633074", "A", cldr ), [{
assert.deepEqual( tokenizer( "633074", properties( "A", cldr ) ), [{
type: "A",
lexeme: "633074"
}] );
assert.deepEqual( tokenizer( "6330737", "AA", cldr ), [{
assert.deepEqual( tokenizer( "6330737", properties( "AA", cldr ) ), [{
type: "AA",
lexeme: "6330737"
}] );
assert.deepEqual( tokenizer( "63307369", "AAA", cldr ), [{
assert.deepEqual( tokenizer( "63307369", properties( "AAA", cldr ) ), [{
type: "AAA",
lexeme: "63307369"
}] );
assert.deepEqual( tokenizer( "633073690", "AAAA", cldr ), [{
assert.deepEqual( tokenizer( "633073690", properties( "AAAA", cldr ) ), [{
type: "AAAA",
lexeme: "633073690"
}] );
assert.deepEqual( tokenizer( "6330736900", "AAAAA", cldr ), [{
assert.deepEqual( tokenizer( "6330736900", properties( "AAAAA", cldr ) ), [{
type: "AAAAA",

@@ -639,0 +640,0 @@ lexeme: "6330736900"

define([
"cldr",
"src/number/format",
"src/number/format-properties",
"json!fixtures/cldr/main/ar/numbers.json",

@@ -8,3 +9,4 @@ "json!fixtures/cldr/main/en/numbers.json",

"json!fixtures/cldr/supplemental/likelySubtags.json"
], function( Cldr, format, arNumbers, enNumbers, esNumbers, likelySubtags ) {
], function( Cldr, format, properties, arNumbers, enNumbers, esNumbers,
likelySubtags ) {

@@ -34,24 +36,24 @@ // 1: Earth average diameter according to:

QUnit.test( "should format integers", function( assert ) {
assert.equal( format( pi, "#0", en ), "3" );
assert.equal( format( pi, "###0", en ), "3" );
assert.equal( format( pi, properties( "#0", en ) ), "3" );
assert.equal( format( pi, properties( "###0", en ) ), "3" );
});
QUnit.test( "should zero-pad minimum integer digits", function( assert ) {
assert.equal( format( pi, "0", en ), "3" );
assert.equal( format( pi, "00", en ), "03" );
assert.equal( format( pi, "000", en ), "003" );
assert.equal( format( pi, properties( "0", en ) ), "3" );
assert.equal( format( pi, properties( "00", en ) ), "03" );
assert.equal( format( pi, properties( "000", en ) ), "003" );
});
QUnit.test( "should not limit the maximum number of digits of integers", function( assert ) {
assert.equal( format( earthDiameter, "0", en ), "12735" );
assert.equal( format( earthDiameter, "00", en ), "12735" );
assert.equal( format( earthDiameter, "#0", en ), "12735" );
assert.equal( format( earthDiameter, properties( "0", en ) ), "12735" );
assert.equal( format( earthDiameter, properties( "00", en ) ), "12735" );
assert.equal( format( earthDiameter, properties( "#0", en ) ), "12735" );
});
QUnit.test( "should format negative integer", function( assert ) {
assert.equal( format( -earthDiameter, "0", en ), "-12735" );
assert.equal( format( -earthDiameter, "0;(0)", en ), "(12735)" );
assert.equal( format( -earthDiameter, properties( "0", en ) ), "-12735" );
assert.equal( format( -earthDiameter, properties( "0;(0)", en ) ), "(12735)" );
// The number of digits, minimal digits, and other characteristics shall be ignored in the negative subpattern.
assert.equal( format( -earthDiameter, "0;(0.0##)", en ), "(12735)" );
assert.equal( format( -earthDiameter, properties( "0;(0.0##)", en ) ), "(12735)" );
});

@@ -64,20 +66,20 @@

QUnit.test( "should format decimals", function( assert ) {
assert.equal( format( pi, "0.##", en ), "3.14" );
assert.equal( format( pi, properties( "0.##", en ) ), "3.14" );
});
QUnit.test( "should limit maximum fraction digits", function( assert ) {
assert.equal( format( pi, "0.##", en ), "3.14" );
assert.equal( format( pi, "0.0#", en ), "3.14" );
assert.equal( format( pi, "0.####", en ), "3.1416" );
assert.equal( format( 0.10004, "0.##", en ), "0.1" );
assert.equal( format( pi, properties( "0.##", en ) ), "3.14" );
assert.equal( format( pi, properties( "0.0#", en ) ), "3.14" );
assert.equal( format( pi, properties( "0.####", en ) ), "3.1416" );
assert.equal( format( 0.10004, properties( "0.##", en ) ), "0.1" );
});
QUnit.test( "should zero-pad minimum fraction digits", function( assert ) {
assert.equal( format( earthDiameter, "0.0", en ), "12735.0" );
assert.equal( format( deci, "0.00", en ), "0.10" );
assert.equal( format( earthDiameter, properties( "0.0", en ) ), "12735.0" );
assert.equal( format( deci, properties( "0.00", en ) ), "0.10" );
});
QUnit.test( "should localize decimal separator symbol (.)", function( assert ) {
assert.equal( format( pi, "0.##", es ), "3,14" );
assert.equal( format( pi, "0.##", ar ), "3٫14" );
assert.equal( format( pi, properties( "0.##", es ) ), "3,14" );
assert.equal( format( pi, properties( "0.##", ar ) ), "3٫14" );
});

@@ -87,104 +89,104 @@

// Overriding minimum integer digits only.
assert.equal( format( pi, "0", en, { minimumIntegerDigits: 2 } ), "03" );
assert.equal( format( pi, properties( "0", en, { minimumIntegerDigits: 2 } ) ), "03" );
// Overriding both fraction options.
assert.equal( format( pi, "0.##", en, {
assert.equal( format( pi, properties( "0.##", en, {
maximumFractionDigits: 5,
minimumFractionDigits: 3
} ), "3.14159" );
assert.equal( format( 0.1, "0.##", en, {
} ) ), "3.14159" );
assert.equal( format( 0.1, properties( "0.##", en, {
maximumFractionDigits: 5,
minimumFractionDigits: 3
} ), "0.100" );
} ) ), "0.100" );
// Overriding maximum fraction digits only.
assert.equal( format( pi, "0.##", en, { maximumFractionDigits: 0 } ), "3" );
assert.equal( format( pi, "0.##", en, { maximumFractionDigits: 1 } ), "3.1" );
assert.equal( format( pi, "0.##", en, { maximumFractionDigits: 3 } ), "3.142" );
assert.equal( format( 0.01, "0.##", en, { maximumFractionDigits: 1 } ), "0" );
assert.equal( format( 0.01, "0.0#", en, { maximumFractionDigits: 1 } ), "0.0" );
assert.equal( format( pi, properties( "0.##", en, { maximumFractionDigits: 0 } ) ), "3" );
assert.equal( format( pi, properties( "0.##", en, { maximumFractionDigits: 1 } ) ), "3.1" );
assert.equal( format( pi, properties( "0.##", en, { maximumFractionDigits: 3 } ) ), "3.142" );
assert.equal( format( 0.01, properties( "0.##", en, { maximumFractionDigits: 1 } ) ), "0" );
assert.equal( format( 0.01, properties( "0.0#", en, { maximumFractionDigits: 1 } ) ), "0.0" );
// Sanity normalization: minimumFractionDigits = min( minimumFractionDigits, maximumFractionDigits )
assert.equal( format( 0.1, "0.0000", en, { maximumFractionDigits: 2 } ), "0.10" );
assert.equal( format( 0.1, properties( "0.0000", en, { maximumFractionDigits: 2 } ) ), "0.10" );
// Overriding minimum fraction digits only.
assert.equal( format( 1, "0.00", en, { minimumFractionDigits: 0 } ), "1" );
assert.equal( format( 0.1, "0.00", en, { minimumFractionDigits: 0 } ), "0.1" );
assert.equal( format( 0.001, "0.00", en, { minimumFractionDigits: 0 } ), "0" );
assert.equal( format( 0.1, "0.##", en, { minimumFractionDigits: 2 } ), "0.10" );
assert.equal( format( 1, properties( "0.00", en, { minimumFractionDigits: 0 } ) ), "1" );
assert.equal( format( 0.1, properties( "0.00", en, { minimumFractionDigits: 0 } ) ), "0.1" );
assert.equal( format( 0.001, properties( "0.00", en, { minimumFractionDigits: 0 } ) ), "0" );
assert.equal( format( 0.1, properties( "0.##", en, { minimumFractionDigits: 2 } ) ), "0.10" );
// Sanity normalization: maximumFractionDigits = max( minimumFractionDigits, maximumFractionDigits ).
assert.equal( format( pi, "0.##", en, { minimumFractionDigits: 5 } ), "3.14159" );
assert.equal( format( pi, properties( "0.##", en, { minimumFractionDigits: 5 } ) ), "3.14159" );
// Overriding both minimum and maximum fraction digits.
assert.equal( format( pi, "0.##", en, {
assert.equal( format( pi, properties( "0.##", en, {
minimumFractionDigits: 1,
maximumFractionDigits: 4
}), "3.1416" );
assert.equal( format( pi, "0.##", en, {
}) ), "3.1416" );
assert.equal( format( pi, properties( "0.##", en, {
minimumIntegerDigits: 2,
maximumFractionDigits: 3
}), "03.142" );
}) ), "03.142" );
// Overriding both integer and fraction options.
assert.equal( format( 1.1, "0.##", en, {
assert.equal( format( 1.1, properties( "0.##", en, {
minimumIntegerDigits: 2,
minimumFractionDigits: 3
}), "01.100" );
assert.equal( format( 1.1, "0.##", en, {
}) ), "01.100" );
assert.equal( format( 1.1, properties( "0.##", en, {
minimumIntegerDigits: 2,
maximumFractionDigits: 3
}), "01.1" );
}) ), "01.1" );
});
QUnit.test( "should allow rounding", function( assert ) {
assert.equal( format( pi, "0.10", en ), "3.10" );
assert.equal( format( pi, "0.20", en ), "3.20" );
assert.equal( format( pi, "0.5", en ), "3.0" );
assert.equal( format( pi, "0.1", en ), "3.1" );
assert.equal( format( pi, properties( "0.10", en ) ), "3.10" );
assert.equal( format( pi, properties( "0.20", en ) ), "3.20" );
assert.equal( format( pi, properties( "0.5", en ) ), "3.0" );
assert.equal( format( pi, properties( "0.1", en ) ), "3.1" );
});
QUnit.test( "should allow different rounding options", function( assert ) {
assert.equal( format( pi, "0.##", en, { round: "ceil" } ), "3.15" );
assert.equal( format( pi, "0.##", en, { round: "floor"} ), "3.14" );
assert.equal( format( pi, "0.##", en, { round: "round" } ), "3.14" );
assert.equal( format( pi, "0.##", en, { round: "truncate"} ), "3.14" );
assert.equal( format( pi, "0.####", en, { round: "ceil" } ), "3.1416" );
assert.equal( format( pi, "0.####", en, { round: "floor"} ), "3.1415" );
assert.equal( format( pi, "0.####", en, { round: "round" } ), "3.1416" );
assert.equal( format( pi, "0.####", en, { round: "truncate"} ), "3.1415" );
assert.equal( format( -pi, "0.##", en, { round: "ceil" } ), "-3.14" );
assert.equal( format( -pi, "0.##", en, { round: "floor"} ), "-3.15" );
assert.equal( format( -pi, "0.##", en, { round: "round" } ), "-3.14" );
assert.equal( format( -pi, "0.##", en, { round: "truncate"} ), "-3.14" );
assert.equal( format( -pi, "0.####", en, { round: "ceil" } ), "-3.1415" );
assert.equal( format( -pi, "0.####", en, { round: "floor"} ), "-3.1416" );
assert.equal( format( -pi, "0.####", en, { round: "round" } ), "-3.1416" );
assert.equal( format( -pi, "0.####", en, { round: "truncate"} ), "-3.1415" );
assert.equal( format( pi, properties( "0.##", en, { round: "ceil" } ) ), "3.15" );
assert.equal( format( pi, properties( "0.##", en, { round: "floor"} ) ), "3.14" );
assert.equal( format( pi, properties( "0.##", en, { round: "round" } ) ), "3.14" );
assert.equal( format( pi, properties( "0.##", en, { round: "truncate"} ) ), "3.14" );
assert.equal( format( pi, properties( "0.####", en, { round: "ceil" } ) ), "3.1416" );
assert.equal( format( pi, properties( "0.####", en, { round: "floor"} ) ), "3.1415" );
assert.equal( format( pi, properties( "0.####", en, { round: "round" } ) ), "3.1416" );
assert.equal( format( pi, properties( "0.####", en, { round: "truncate"} ) ), "3.1415" );
assert.equal( format( -pi, properties( "0.##", en, { round: "ceil" } ) ), "-3.14" );
assert.equal( format( -pi, properties( "0.##", en, { round: "floor"} ) ), "-3.15" );
assert.equal( format( -pi, properties( "0.##", en, { round: "round" } ) ), "-3.14" );
assert.equal( format( -pi, properties( "0.##", en, { round: "truncate"} ) ), "-3.14" );
assert.equal( format( -pi, properties( "0.####", en, { round: "ceil" } ) ), "-3.1415" );
assert.equal( format( -pi, properties( "0.####", en, { round: "floor"} ) ), "-3.1416" );
assert.equal( format( -pi, properties( "0.####", en, { round: "round" } ) ), "-3.1416" );
assert.equal( format( -pi, properties( "0.####", en, { round: "truncate"} ) ), "-3.1415" );
});
QUnit.test( "should format significant digits", function( assert ) {
assert.equal( format( 123, "@@@", en ), "123" );
assert.equal( format( 12345, "@@@", en ), "12300" );
assert.equal( format( 12345, "@@#", en ), "12300" );
assert.equal( format( 12345, "@##", en ), "12300" );
assert.equal( format( pi, "@@", en ), "3.1" );
assert.equal( format( pi, "@@#", en ), "3.14" );
assert.equal( format( pi, "@@##", en ), "3.142" );
assert.equal( format( pi, "@####", en ), "3.1416" );
assert.equal( format( 0.10004, "@@", en ), "0.10" );
assert.equal( format( 0.10004, "@##", en ), "0.1" );
assert.equal( format( 0.12345, "@@@", en ), "0.123" );
assert.equal( format( 1.23004, "@@##", en ), "1.23" );
assert.equal( format( 123, properties( "@@@", en ) ), "123" );
assert.equal( format( 12345, properties( "@@@", en ) ), "12300" );
assert.equal( format( 12345, properties( "@@#", en ) ), "12300" );
assert.equal( format( 12345, properties( "@##", en ) ), "12300" );
assert.equal( format( pi, properties( "@@", en ) ), "3.1" );
assert.equal( format( pi, properties( "@@#", en ) ), "3.14" );
assert.equal( format( pi, properties( "@@##", en ) ), "3.142" );
assert.equal( format( pi, properties( "@####", en ) ), "3.1416" );
assert.equal( format( 0.10004, properties( "@@", en ) ), "0.10" );
assert.equal( format( 0.10004, properties( "@##", en ) ), "0.1" );
assert.equal( format( 0.12345, properties( "@@@", en ) ), "0.123" );
assert.equal( format( 1.23004, properties( "@@##", en ) ), "1.23" );
});
QUnit.test( "should format negative decimal", function( assert ) {
assert.equal( format( -pi, "0.##", en ), "-3.14" );
assert.equal( format( -pi, "0.##;(0.##)", en ), "(3.14)" );
assert.equal( format( -pi, "@@#", en ), "-3.14" );
assert.equal( format( -pi, "@@#;(@@#)", en ), "(3.14)" );
assert.equal( format( -pi, properties( "0.##", en ) ), "-3.14" );
assert.equal( format( -pi, properties( "0.##;(0.##)", en ) ), "(3.14)" );
assert.equal( format( -pi, properties( "@@#", en ) ), "-3.14" );
assert.equal( format( -pi, properties( "@@#;(@@#)", en ) ), "(3.14)" );
// The number of digits, minimal digits, and other characteristics shall be ignored in the negative subpattern.
assert.equal( format( -pi, "0.##;(0)", en ), "(3.14)" );
assert.equal( format( -pi, "@@#;(0)", en ), "(3.14)" );
assert.equal( format( -pi, properties( "0.##;(0)", en ) ), "(3.14)" );
assert.equal( format( -pi, properties( "@@#;(0)", en ) ), "(3.14)" );
});

@@ -197,7 +199,7 @@

QUnit.test( "should format grouping separators", function( assert ) {
assert.equal( format( earthDiameter, "#,##0.#", en ), "12,735" );
assert.equal( format( earthDiameter, "#,#,#0.#", en ), "1,2,7,35" );
assert.equal( format( 123456789, "#,##,###,###0", en ), "12,345,6789" );
assert.equal( format( 123456789, "###,###,###0", en ), "12,345,6789" );
assert.equal( format( 123456789, "##,#,###,###0", en ), "12,345,6789" );
assert.equal( format( earthDiameter, properties( "#,##0.#", en ) ), "12,735" );
assert.equal( format( earthDiameter, properties( "#,#,#0.#", en ) ), "1,2,7,35" );
assert.equal( format( 123456789, properties( "#,##,###,###0", en ) ), "12,345,6789" );
assert.equal( format( 123456789, properties( "###,###,###0", en ) ), "12,345,6789" );
assert.equal( format( 123456789, properties( "##,#,###,###0", en ) ), "12,345,6789" );
});

@@ -210,19 +212,19 @@

QUnit.test( "should format percent", function( assert ) {
assert.equal( format( 0.01, "0%", en ), "1%" );
assert.equal( format( 0.01, "00%", en ), "01%" );
assert.equal( format( 0.1, "0%", en ), "10%" );
assert.equal( format( 0.5, "#0%", en ), "50%" );
assert.equal( format( 1, "0%", en ), "100%" );
assert.equal( format( 0.005, "##0.#%", en ), "0.5%" );
assert.equal( format( 0.005, "##0.#%", en ), "0.5%" );
assert.equal( format( 0.01, properties( "0%", en ) ), "1%" );
assert.equal( format( 0.01, properties( "00%", en ) ), "01%" );
assert.equal( format( 0.1, properties( "0%", en ) ), "10%" );
assert.equal( format( 0.5, properties( "#0%", en ) ), "50%" );
assert.equal( format( 1, properties( "0%", en ) ), "100%" );
assert.equal( format( 0.005, properties( "##0.#%", en ) ), "0.5%" );
assert.equal( format( 0.005, properties( "##0.#%", en ) ), "0.5%" );
});
QUnit.test( "should localize percent symbol (%)", function( assert ) {
assert.equal( format( 0.5, "#0%", ar ), "50٪" );
assert.equal( format( 0.5, properties( "#0%", ar ) ), "50٪" );
});
QUnit.test( "should format negative percentage", function( assert ) {
assert.equal( format( -0.1, "0%", en ), "-10%" );
assert.equal( format( -0.1, "0%;(0%)", en ), "(10%)" );
assert.equal( format( -0.1, "0%;(0)%", en ), "(10)%" );
assert.equal( format( -0.1, properties( "0%", en ) ), "-10%" );
assert.equal( format( -0.1, properties( "0%;(0%)", en ) ), "(10%)" );
assert.equal( format( -0.1, properties( "0%;(0)%", en ) ), "(10)%" );
});

@@ -235,22 +237,22 @@

QUnit.test( "should format per mille", function( assert ) {
assert.equal( format( 0.001, "0\u2030", en ), "1\u2030" );
assert.equal( format( 0.001, "00\u2030", en ), "01\u2030" );
assert.equal( format( 0.01, "0\u2030", en ), "10\u2030" );
assert.equal( format( 0.1, "0\u2030", en ), "100\u2030" );
assert.equal( format( 0.5, "#0\u2030", en ), "500\u2030" );
assert.equal( format( 1, "0\u2030", en ), "1000\u2030" );
assert.equal( format( 0.0005, "##0.#\u2030", en ), "0.5\u2030" );
assert.equal( format( 0.0005, "##0.#\u2030", en ), "0.5\u2030" );
assert.equal( format( 0.5, "#0‰", en ), "500\u2030" );
assert.equal( format( 0.5, "#0‰", en ), "500‰" );
assert.equal( format( 0.001, properties( "0\u2030", en ) ), "1\u2030" );
assert.equal( format( 0.001, properties( "00\u2030", en ) ), "01\u2030" );
assert.equal( format( 0.01, properties( "0\u2030", en ) ), "10\u2030" );
assert.equal( format( 0.1, properties( "0\u2030", en ) ), "100\u2030" );
assert.equal( format( 0.5, properties( "#0\u2030", en ) ), "500\u2030" );
assert.equal( format( 1, properties( "0\u2030", en ) ), "1000\u2030" );
assert.equal( format( 0.0005, properties( "##0.#\u2030", en ) ), "0.5\u2030" );
assert.equal( format( 0.0005, properties( "##0.#\u2030", en ) ), "0.5\u2030" );
assert.equal( format( 0.5, properties( "#0‰", en ) ), "500\u2030" );
assert.equal( format( 0.5, properties( "#0‰", en ) ), "500‰" );
});
QUnit.test( "should localize per mille symbol (\u2030)", function( assert ) {
assert.equal( format( 0.5, "#0\u2030", ar ), "500؉" );
assert.equal( format( 0.5, properties( "#0\u2030", ar ) ), "500؉" );
});
QUnit.test( "should format negative mille", function( assert ) {
assert.equal( format( -0.001, "0\u2030", en ), "-1\u2030" );
assert.equal( format( -0.001, "0\u2030;(0\u2030)", en ), "(1\u2030)" );
assert.equal( format( -0.001, "0\u2030;(0)\u2030", en ), "(1)\u2030" );
assert.equal( format( -0.001, properties( "0\u2030", en ) ), "-1\u2030" );
assert.equal( format( -0.001, properties( "0\u2030;(0\u2030)", en ) ), "(1\u2030)" );
assert.equal( format( -0.001, properties( "0\u2030;(0)\u2030", en ) ), "(1)\u2030" );
});

@@ -263,4 +265,4 @@

QUnit.test( "should format infinite numbers", function( assert ) {
assert.equal( format( Math.pow(2, 2000), "0", en ), "∞" );
assert.equal( format( Math.pow(-2, 2001), "0", en ), "-∞" );
assert.equal( format( Math.pow(2, 2000 ), properties( "0", en ) ), "∞" );
assert.equal( format( Math.pow(-2, 2001 ), properties( "0", en ) ), "-∞" );
});

@@ -273,5 +275,5 @@

QUnit.test( "should format infinite numbers", function( assert ) {
assert.equal( format( NaN, "0", en ), "NaN" );
assert.equal( format( NaN, properties( "0", en ) ), "NaN" );
});
});
define([
"cldr",
"src/number/parse",
"src/number/parse-properties",
"json!fixtures/cldr/main/ar/numbers.json",

@@ -10,3 +11,4 @@ "json!fixtures/cldr/main/dz/numbers.json",

"json!fixtures/cldr/supplemental/likelySubtags.json"
], function( Cldr, parse, arNumbers, dzNumbers, enNumbers, esNumbers, svNumbers, likelySubtags ) {
], function( Cldr, parse, properties, arNumbers, dzNumbers, enNumbers, esNumbers, svNumbers,
likelySubtags ) {

@@ -35,18 +37,18 @@ var ar, dz, en, es, sv;

QUnit.test( "should parse integers", function( assert ) {
assert.equal( parse( "3", "0", en ), 3 );
assert.equal( parse( "3", properties( "0", en ) ), 3 );
});
QUnit.test( "should parse zero-padded integers", function( assert ) {
assert.equal( parse( "003", "000", en ), 3 );
assert.equal( parse( "003", properties( "000", en ) ), 3 );
});
QUnit.test( "should parse grouping separators", function( assert ) {
assert.equal( parse( "12,735", "#,##0.#", en ), 12735 );
assert.equal( parse( "1,2,7,35", "#,#,#0.#", en ), 12735 );
assert.equal( parse( "12.735", "#,##0", es ), 12735 );
assert.equal( parse( "12,735", properties( "#,##0.#", en ) ), 12735 );
assert.equal( parse( "1,2,7,35", properties( "#,#,#0.#", en ) ), 12735 );
assert.equal( parse( "12.735", properties( "#,##0", es ) ), 12735 );
});
QUnit.test( "should parse negative integers", function( assert ) {
assert.equal( parse( "-3", "0", en ), -3 );
assert.equal( parse( "(3)", "0;(0)", en ), -3 );
assert.equal( parse( "-3", properties( "0", en ) ), -3 );
assert.equal( parse( "(3)", properties( "0;(0)", en ) ), -3 );
});

@@ -59,16 +61,16 @@

QUnit.test( "should parse decimals", function( assert ) {
assert.equal( parse( "3.14", "0.##", en ), 3.14 );
assert.equal( parse( "3,14", "0.##", es ), 3.14 );
assert.equal( parse( "3٫14", "0.##", ar ), 3.14 );
assert.equal( parse( "3.00", "0.##", en ), 3 );
assert.equal( parse( "3.14", properties( "0.##", en ) ), 3.14 );
assert.equal( parse( "3,14", properties( "0.##", es ) ), 3.14 );
assert.equal( parse( "3٫14", properties( "0.##", ar ) ), 3.14 );
assert.equal( parse( "3.00", properties( "0.##", en ) ), 3 );
});
QUnit.test( "should parse zero-padded decimals", function( assert ) {
assert.equal( parse( "12735.0", "0.0", en ), 12735 );
assert.equal( parse( "0.10", "0.00", en ), 0.1 );
assert.equal( parse( "12735.0", properties( "0.0", en ) ), 12735 );
assert.equal( parse( "0.10", properties( "0.00", en ) ), 0.1 );
});
QUnit.test( "should parse negative decimal", function( assert ) {
assert.equal( parse( "-3.14", "0.##", en ), -3.14 );
assert.equal( parse( "(3.14)", "0.##;(0.##)", en ), -3.14 );
assert.equal( parse( "-3.14", properties( "0.##", en ) ), -3.14 );
assert.equal( parse( "(3.14)", properties( "0.##;(0.##)", en ) ), -3.14 );
});

@@ -81,19 +83,19 @@

QUnit.test( "should parse percent", function( assert ) {
assert.equal( parse( "1%", "0%", en ), 0.01 );
assert.equal( parse( "01%", "00%", en ), 0.01 );
assert.equal( parse( "10%", "0%", en ), 0.1 );
assert.equal( parse( "50%", "#0%", en ), 0.5 );
assert.equal( parse( "100%", "0%", en ), 1 );
assert.equal( parse( "0.5%", "##0.#%", en ), 0.005 );
assert.equal( parse( "0.5%", "##0.#%", en ), 0.005 );
assert.equal( parse( "1%", properties( "0%", en ) ), 0.01 );
assert.equal( parse( "01%", properties( "00%", en ) ), 0.01 );
assert.equal( parse( "10%", properties( "0%", en ) ), 0.1 );
assert.equal( parse( "50%", properties( "#0%", en ) ), 0.5 );
assert.equal( parse( "100%", properties( "0%", en ) ), 1 );
assert.equal( parse( "0.5%", properties( "##0.#%", en ) ), 0.005 );
assert.equal( parse( "0.5%", properties( "##0.#%", en ) ), 0.005 );
});
QUnit.test( "should localize percent symbol (%)", function( assert ) {
assert.equal( parse( "50٪", "#0%", ar ), 0.5 );
assert.equal( parse( "50٪", properties( "#0%", ar ) ), 0.5 );
});
QUnit.test( "should parse negative percentage", function( assert ) {
assert.equal( parse( "-10%", "0%", en ), -0.1 );
assert.equal( parse( "(10%)", "0%;(0%)", en ), -0.1 );
assert.equal( parse( "(10)%", "0%;(0)%", en ), -0.1 );
assert.equal( parse( "-10%", properties( "0%", en ) ), -0.1 );
assert.equal( parse( "(10%)", properties( "0%;(0%)", en ) ), -0.1 );
assert.equal( parse( "(10)%", properties( "0%;(0)%", en ) ), -0.1 );
});

@@ -106,19 +108,19 @@

QUnit.test( "should parse per mille", function( assert ) {
assert.equal( parse( "1\u2030", "0\u2030", en ), 0.001 );
assert.equal( parse( "01\u2030", "00\u2030", en ), 0.001 );
assert.equal( parse( "10\u2030", "0\u2030", en ), 0.01 );
assert.equal( parse( "100\u2030", "0\u2030", en ), 0.1 );
assert.equal( parse( "500\u2030", "#0\u2030", en ), 0.5 );
assert.equal( parse( "1000\u2030", "0\u2030", en ), 1 );
assert.equal( parse( "0.5\u2030", "##0.#\u2030", en ), 0.0005 );
assert.equal( parse( "0.5\u2030", "##0.#\u2030", en ), 0.0005 );
assert.equal( parse( "500\u2030", "#0‰", en ), 0.5 );
assert.equal( parse( "500‰", "#0‰", en ), 0.5 );
assert.equal( parse( "500؉", "#0\u2030", ar ), 0.5 );
assert.equal( parse( "1\u2030", properties( "0\u2030", en ) ), 0.001 );
assert.equal( parse( "01\u2030", properties( "00\u2030", en ) ), 0.001 );
assert.equal( parse( "10\u2030", properties( "0\u2030", en ) ), 0.01 );
assert.equal( parse( "100\u2030", properties( "0\u2030", en ) ), 0.1 );
assert.equal( parse( "500\u2030", properties( "#0\u2030", en ) ), 0.5 );
assert.equal( parse( "1000\u2030", properties( "0\u2030", en ) ), 1 );
assert.equal( parse( "0.5\u2030", properties( "##0.#\u2030", en ) ), 0.0005 );
assert.equal( parse( "0.5\u2030", properties( "##0.#\u2030", en ) ), 0.0005 );
assert.equal( parse( "500\u2030", properties( "#0‰", en ) ), 0.5 );
assert.equal( parse( "500‰", properties( "#0‰", en ) ), 0.5 );
assert.equal( parse( "500؉", properties( "#0\u2030", ar ) ), 0.5 );
});
QUnit.test( "should parse negative mille", function( assert ) {
assert.equal( parse( "-1\u2030", "0\u2030", en ), -0.001 );
assert.equal( parse( "(1\u2030)", "0\u2030;(0\u2030)", en ), -0.001 );
assert.equal( parse( "(1)\u2030", "0\u2030;(0)\u2030", en ), -0.001 );
assert.equal( parse( "-1\u2030", properties( "0\u2030", en ) ), -0.001 );
assert.equal( parse( "(1\u2030)", properties( "0\u2030;(0\u2030)", en ) ), -0.001 );
assert.equal( parse( "(1)\u2030", properties( "0\u2030;(0)\u2030", en ) ), -0.001 );
});

@@ -130,4 +132,4 @@

QUnit.test( "should parse scientific notation numbers", function( assert ) {
assert.equal( parse( "3E-3", "0", en ), 0.003 );
assert.equal( parse( "3×10^-3", "0", sv ), 0.003 );
assert.equal( parse( "3E-3", properties( "0", en ) ), 0.003 );
assert.equal( parse( "3×10^-3", properties( "0", sv ) ), 0.003 );
});

@@ -139,6 +141,6 @@

QUnit.test( "should parse infinite numbers", function( assert ) {
assert.equal( parse( "∞", "0", en ), Infinity );
assert.equal( parse( "-∞", "0", en ), -Infinity );
assert.equal( parse( "(∞)", "0;(0)", en ), -Infinity );
assert.equal( parse( "གྲངས་མེད", "0", dz ), Infinity );
assert.equal( parse( "∞", properties( "0", en ) ), Infinity );
assert.equal( parse( "-∞", properties( "0", en ) ), -Infinity );
assert.equal( parse( "(∞)", properties( "0;(0)", en ) ), -Infinity );
assert.equal( parse( "གྲངས་མེད", properties( "0", dz ) ), Infinity );
});

@@ -151,4 +153,4 @@

QUnit.test( "should parse invalid numbers as NaN", function( assert ) {
assert.deepEqual( parse( "invalid", "0", en ), NaN );
assert.deepEqual( parse( "NaN", "0", en ), NaN );
assert.deepEqual( parse( "invalid", properties( "0", en ) ), NaN );
assert.deepEqual( parse( "NaN", properties( "0", en ) ), NaN );
});

@@ -155,0 +157,0 @@

@@ -48,3 +48,3 @@ define([

assert.equal( pluralForm( 199, ar ), "many" );
assert.equal( pluralForm( 3.14, ar ), "few" );
assert.equal( pluralForm( 3.14, ar ), "other" );

@@ -51,0 +51,0 @@ assert.equal( pluralForm( 0, ja ), "other" );

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc