twitter_cldr_js 3.2.0 → 3.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile +1 -1
- data/README.md +12 -3
- data/lib/assets/javascripts/twitter_cldr/core.js +307 -9
- data/lib/twitter_cldr/js/compiler.rb +12 -1
- data/lib/twitter_cldr/js/mustache/bundle.coffee +2 -0
- data/lib/twitter_cldr/js/mustache/implementation/clone/clone.coffee +58 -0
- data/lib/twitter_cldr/js/mustache/implementation/numbers/numbers.coffee +27 -10
- data/lib/twitter_cldr/js/renderers/implementation/clone.rb +20 -0
- data/lib/twitter_cldr/js/renderers.rb +1 -0
- data/lib/twitter_cldr/js/version.rb +1 -1
- data/spec/js/clone/clone.spec.js +234 -0
- data/spec/js/numbers/long_short_decimal.spec.js +77 -0
- data/twitter_cldr_js.gemspec +1 -2
- metadata +7 -23
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c7fa717f3763a3f4ca2593e5ff7104fea5f2cb56959bc89fc93f93219f34b82a
|
4
|
+
data.tar.gz: 2a1a5fe1a2f32f4eaf80f78b5aefe081b6fc85cce453940dfbe254a11d86becf
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 77e9dd6b9439d03d11c26de9027dc7080a5dcbd46519f58623931a864c2f09c11654ff8cc79855eb8e175b329613ea744aa24db235748fa03aff40f610b20040
|
7
|
+
data.tar.gz: 30a80da24b9d490da60530f0d0470264f766748d4fc2756235f2ee6edce5bf070831a5ed5c61b08b06bad732aca44f34b34499168fc1ab5a5d8f5f2a912a893f
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -297,7 +297,7 @@ formatter.format(123, 'OrdinalRules', 'digits-ordinal')
|
|
297
297
|
// '123rd'
|
298
298
|
```
|
299
299
|
|
300
|
-
In
|
300
|
+
In comparison, here is what the Spanish formatting looks like
|
301
301
|
```javascript
|
302
302
|
// include the es data bundle for the Spanish RBNF Formatter
|
303
303
|
var formatter = new TwitterCldr.RBNF()
|
@@ -397,7 +397,7 @@ TwitterCldr.TerritoriesContainment.contains('419', 'FR') // false
|
|
397
397
|
|
398
398
|
### Unicode Regular Expressions
|
399
399
|
|
400
|
-
Unicode regular expressions are an
|
400
|
+
Unicode regular expressions are an implementaion of regular expressions that support all Unicode characters in the [BMP](http://en.wikipedia.org/wiki/Plane_(Unicode)#Basic_Multilingual_Plane). They provide support for multi-character strings, Unicode character escapes, set operations (unions, intersections, and differences), and character sets.
|
401
401
|
|
402
402
|
#### Changes to Character Classes
|
403
403
|
|
@@ -429,7 +429,7 @@ regex3 = TwitterCldr.UnicodeRegex.compile("[[a-z]-[d-g]]+", "g");
|
|
429
429
|
//supports the JavaScript RegExp modifiers
|
430
430
|
```
|
431
431
|
|
432
|
-
Once compiled, instances of `UnicodeRegex`
|
432
|
+
Once compiled, instances of `UnicodeRegex` can be directly used to match against a string:
|
433
433
|
|
434
434
|
```javascript
|
435
435
|
|
@@ -438,6 +438,15 @@ regex2.match("ABCDfooABC"); // ["ABCD", "ABC"]
|
|
438
438
|
regex3.match("dog"); // ["o"]
|
439
439
|
```
|
440
440
|
|
441
|
+
Alternatively, you can convert a `UnicodeRegex` into a native JavaScript regex by calling its `to_regexp` method:
|
442
|
+
|
443
|
+
```javascript
|
444
|
+
|
445
|
+
regex3.to_regexp(); // /(?:[\u0061-\u0063]|[\u0068-\u007a])+/g
|
446
|
+
regex3.to_regexp().test("a"); // true
|
447
|
+
regex3.to_regexp().test("d"); // false
|
448
|
+
```
|
449
|
+
|
441
450
|
Protip: Try to avoid negation in character classes (eg. [^abc] and \P{Lu}) as it tends to negatively affect both performance when constructing regexes as well as matching.
|
442
451
|
|
443
452
|
### Text Segmentation
|
@@ -16,10 +16,11 @@
|
|
16
16
|
/*_lib/twitter_cldr_*/
|
17
17
|
|
18
18
|
(function() {
|
19
|
-
var TwitterCldr, key, obj, root,
|
19
|
+
var TwitterCldr, get_with_data_isolation, key, obj, proxy_or_primitive, root, with_data_isolation,
|
20
20
|
__hasProp = {}.hasOwnProperty,
|
21
21
|
__extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
|
22
|
-
__indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }
|
22
|
+
__indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; },
|
23
|
+
__slice = [].slice;
|
23
24
|
|
24
25
|
TwitterCldr = {};
|
25
26
|
|
@@ -3607,7 +3608,7 @@
|
|
3607
3608
|
};
|
3608
3609
|
|
3609
3610
|
NumberFormatter.prototype.format = function(number, options) {
|
3610
|
-
var fraction, fraction_format, integer_format, intg, key, opts, prefix, result, sign, suffix, tokens, tokens_sample, truncated_number, val, _ref, _ref1;
|
3611
|
+
var fraction, fraction_format, integer_format, intg, key, number_part, opts, prefix, result, rounded_num, sign, suffix, tokens, tokens_sample, truncated_number, val, _ref, _ref1;
|
3611
3612
|
if (options == null) {
|
3612
3613
|
options = {};
|
3613
3614
|
}
|
@@ -3616,27 +3617,38 @@
|
|
3616
3617
|
val = options[key];
|
3617
3618
|
opts[key] = options[key] != null ? options[key] : opts[key];
|
3618
3619
|
}
|
3620
|
+
number = this.round_to(number, opts.precision || 0);
|
3619
3621
|
tokens = this.get_tokens(number, opts);
|
3620
3622
|
if (tokens != null) {
|
3621
3623
|
if (!(tokens instanceof Array)) {
|
3622
3624
|
tokens_sample = tokens[Object.keys(tokens)[0]];
|
3623
3625
|
truncated_number = this.truncate_number(number, tokens_sample[1].length);
|
3626
|
+
rounded_num = Number(this.parse_number(truncated_number, opts)[0]) * Number(this.get_key(number)) / (Math.pow(10, tokens_sample[1].length - 1));
|
3627
|
+
if (!opts._stack_depth && this.get_key(rounded_num) !== this.get_key(number)) {
|
3628
|
+
return this.format(rounded_num, Object.assign(opts, {
|
3629
|
+
_stack_depth: 1
|
3630
|
+
}));
|
3631
|
+
}
|
3624
3632
|
if (opts.precision === 0) {
|
3625
3633
|
truncated_number = Math.floor(truncated_number);
|
3626
3634
|
}
|
3627
3635
|
tokens = tokens[TwitterCldr.PluralRules.rule_for(truncated_number)];
|
3628
3636
|
}
|
3629
3637
|
_ref = this.partition_tokens(tokens), prefix = _ref[0], suffix = _ref[1], integer_format = _ref[2], fraction_format = _ref[3];
|
3630
|
-
|
3631
|
-
_ref1 = this.parse_number(
|
3638
|
+
number_part = this.truncate_number(number, integer_format.format.length);
|
3639
|
+
_ref1 = this.parse_number(number_part, opts), intg = _ref1[0], fraction = _ref1[1];
|
3632
3640
|
result = integer_format.apply(parseFloat(intg), opts);
|
3633
3641
|
if (fraction) {
|
3634
3642
|
result += fraction_format.apply(fraction, opts);
|
3635
3643
|
}
|
3636
|
-
sign =
|
3644
|
+
sign = number_part < 0 && prefix !== "-" ? this.symbols().minus_sign || this.default_symbols.minus_sign : "";
|
3637
3645
|
return "" + prefix + result + suffix;
|
3638
3646
|
} else {
|
3639
|
-
|
3647
|
+
if (!(this instanceof TwitterCldr.DecimalFormatter)) {
|
3648
|
+
return new TwitterCldr.DecimalFormatter().format(number, opts);
|
3649
|
+
} else {
|
3650
|
+
return number.toString();
|
3651
|
+
}
|
3640
3652
|
}
|
3641
3653
|
};
|
3642
3654
|
|
@@ -3679,7 +3691,7 @@
|
|
3679
3691
|
};
|
3680
3692
|
|
3681
3693
|
NumberFormatter.prototype.get_tokens = function() {
|
3682
|
-
throw "get_tokens() not implemented - use a derived class like PercentFormatter.";
|
3694
|
+
throw new Error("get_tokens() not implemented - use a derived class like PercentFormatter.");
|
3683
3695
|
};
|
3684
3696
|
|
3685
3697
|
return NumberFormatter;
|
@@ -3746,7 +3758,7 @@
|
|
3746
3758
|
return result;
|
3747
3759
|
} catch (_error) {
|
3748
3760
|
error = _error;
|
3749
|
-
return number;
|
3761
|
+
return number.toString();
|
3750
3762
|
}
|
3751
3763
|
};
|
3752
3764
|
|
@@ -5447,6 +5459,292 @@
|
|
5447
5459
|
|
5448
5460
|
})();
|
5449
5461
|
|
5462
|
+
with_data_isolation = function(data) {
|
5463
|
+
return function(fn) {
|
5464
|
+
var original, result;
|
5465
|
+
original = TwitterCldr.data;
|
5466
|
+
TwitterCldr.data = data;
|
5467
|
+
result = fn();
|
5468
|
+
TwitterCldr.data = original;
|
5469
|
+
return result;
|
5470
|
+
};
|
5471
|
+
};
|
5472
|
+
|
5473
|
+
get_with_data_isolation = function(data) {
|
5474
|
+
return function(target, property_key, receiver) {
|
5475
|
+
var isolate_data;
|
5476
|
+
isolate_data = with_data_isolation(data);
|
5477
|
+
return isolate_data(function() {
|
5478
|
+
var fn, result;
|
5479
|
+
result = Reflect.get(target, property_key, receiver);
|
5480
|
+
if (typeof result === 'function') {
|
5481
|
+
fn = result;
|
5482
|
+
result = function() {
|
5483
|
+
var args;
|
5484
|
+
args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
|
5485
|
+
return isolate_data(function() {
|
5486
|
+
return Reflect.apply(fn, target, args);
|
5487
|
+
});
|
5488
|
+
};
|
5489
|
+
}
|
5490
|
+
return result;
|
5491
|
+
});
|
5492
|
+
};
|
5493
|
+
};
|
5494
|
+
|
5495
|
+
proxy_or_primitive = function(value, handlers) {
|
5496
|
+
if (value instanceof Object) {
|
5497
|
+
return new Proxy(value, handlers);
|
5498
|
+
} else {
|
5499
|
+
return value;
|
5500
|
+
}
|
5501
|
+
};
|
5502
|
+
|
5503
|
+
TwitterCldr.clone = function(data) {
|
5504
|
+
var get, isolate_data;
|
5505
|
+
if (!data) {
|
5506
|
+
throw new Error('Cannot create a clone with no data');
|
5507
|
+
}
|
5508
|
+
get = get_with_data_isolation(data);
|
5509
|
+
isolate_data = with_data_isolation(data);
|
5510
|
+
return proxy_or_primitive(root, {
|
5511
|
+
get: function(target, property_key, receiver) {
|
5512
|
+
switch (property_key) {
|
5513
|
+
case 'set_data':
|
5514
|
+
return function() {
|
5515
|
+
throw new Error('Cannot set data on a TwitterCldr clone');
|
5516
|
+
};
|
5517
|
+
default:
|
5518
|
+
return isolate_data(function() {
|
5519
|
+
return proxy_or_primitive(Reflect.get(target, property_key, receiver), {
|
5520
|
+
get: get,
|
5521
|
+
apply: function() {
|
5522
|
+
var args;
|
5523
|
+
args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
|
5524
|
+
return isolate_data(function() {
|
5525
|
+
return Reflect.apply.apply(Reflect, args);
|
5526
|
+
});
|
5527
|
+
},
|
5528
|
+
construct: function() {
|
5529
|
+
var args;
|
5530
|
+
args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
|
5531
|
+
return isolate_data(function() {
|
5532
|
+
return proxy_or_primitive(Reflect.construct.apply(Reflect, args), {
|
5533
|
+
get: get
|
5534
|
+
});
|
5535
|
+
});
|
5536
|
+
}
|
5537
|
+
});
|
5538
|
+
});
|
5539
|
+
}
|
5540
|
+
},
|
5541
|
+
set: function() {
|
5542
|
+
throw new Error('Cannot set properties on a TwitterCldr clone');
|
5543
|
+
}
|
5544
|
+
});
|
5545
|
+
};
|
5546
|
+
|
5547
|
+
TwitterCldr.get_available_locales = function() {
|
5548
|
+
return [
|
5549
|
+
{
|
5550
|
+
"locale": "af",
|
5551
|
+
"file_name": "af"
|
5552
|
+
}, {
|
5553
|
+
"locale": "ar",
|
5554
|
+
"file_name": "ar"
|
5555
|
+
}, {
|
5556
|
+
"locale": "be",
|
5557
|
+
"file_name": "be"
|
5558
|
+
}, {
|
5559
|
+
"locale": "bg",
|
5560
|
+
"file_name": "bg"
|
5561
|
+
}, {
|
5562
|
+
"locale": "bn",
|
5563
|
+
"file_name": "bn"
|
5564
|
+
}, {
|
5565
|
+
"locale": "ca",
|
5566
|
+
"file_name": "ca"
|
5567
|
+
}, {
|
5568
|
+
"locale": "cs",
|
5569
|
+
"file_name": "cs"
|
5570
|
+
}, {
|
5571
|
+
"locale": "cy",
|
5572
|
+
"file_name": "cy"
|
5573
|
+
}, {
|
5574
|
+
"locale": "da",
|
5575
|
+
"file_name": "da"
|
5576
|
+
}, {
|
5577
|
+
"locale": "de",
|
5578
|
+
"file_name": "de"
|
5579
|
+
}, {
|
5580
|
+
"locale": "de-CH",
|
5581
|
+
"file_name": "de-CH"
|
5582
|
+
}, {
|
5583
|
+
"locale": "el",
|
5584
|
+
"file_name": "el"
|
5585
|
+
}, {
|
5586
|
+
"locale": "en",
|
5587
|
+
"file_name": "en"
|
5588
|
+
}, {
|
5589
|
+
"locale": "en-150",
|
5590
|
+
"file_name": "en-150"
|
5591
|
+
}, {
|
5592
|
+
"locale": "en-AU",
|
5593
|
+
"file_name": "en-AU"
|
5594
|
+
}, {
|
5595
|
+
"locale": "en-CA",
|
5596
|
+
"file_name": "en-CA"
|
5597
|
+
}, {
|
5598
|
+
"locale": "en-GB",
|
5599
|
+
"file_name": "en-GB"
|
5600
|
+
}, {
|
5601
|
+
"locale": "en-IE",
|
5602
|
+
"file_name": "en-IE"
|
5603
|
+
}, {
|
5604
|
+
"locale": "en-SG",
|
5605
|
+
"file_name": "en-SG"
|
5606
|
+
}, {
|
5607
|
+
"locale": "en-ZA",
|
5608
|
+
"file_name": "en-ZA"
|
5609
|
+
}, {
|
5610
|
+
"locale": "es",
|
5611
|
+
"file_name": "es"
|
5612
|
+
}, {
|
5613
|
+
"locale": "es-419",
|
5614
|
+
"file_name": "es-419"
|
5615
|
+
}, {
|
5616
|
+
"locale": "es-CO",
|
5617
|
+
"file_name": "es-CO"
|
5618
|
+
}, {
|
5619
|
+
"locale": "es-MX",
|
5620
|
+
"file_name": "es-MX"
|
5621
|
+
}, {
|
5622
|
+
"locale": "es-US",
|
5623
|
+
"file_name": "es-US"
|
5624
|
+
}, {
|
5625
|
+
"locale": "eu",
|
5626
|
+
"file_name": "eu"
|
5627
|
+
}, {
|
5628
|
+
"locale": "fa",
|
5629
|
+
"file_name": "fa"
|
5630
|
+
}, {
|
5631
|
+
"locale": "fi",
|
5632
|
+
"file_name": "fi"
|
5633
|
+
}, {
|
5634
|
+
"locale": "fil",
|
5635
|
+
"file_name": "fil"
|
5636
|
+
}, {
|
5637
|
+
"locale": "fr",
|
5638
|
+
"file_name": "fr"
|
5639
|
+
}, {
|
5640
|
+
"locale": "fr-BE",
|
5641
|
+
"file_name": "fr-BE"
|
5642
|
+
}, {
|
5643
|
+
"locale": "fr-CA",
|
5644
|
+
"file_name": "fr-CA"
|
5645
|
+
}, {
|
5646
|
+
"locale": "fr-CH",
|
5647
|
+
"file_name": "fr-CH"
|
5648
|
+
}, {
|
5649
|
+
"locale": "ga",
|
5650
|
+
"file_name": "ga"
|
5651
|
+
}, {
|
5652
|
+
"locale": "gl",
|
5653
|
+
"file_name": "gl"
|
5654
|
+
}, {
|
5655
|
+
"locale": "he",
|
5656
|
+
"file_name": "he"
|
5657
|
+
}, {
|
5658
|
+
"locale": "hi",
|
5659
|
+
"file_name": "hi"
|
5660
|
+
}, {
|
5661
|
+
"locale": "hr",
|
5662
|
+
"file_name": "hr"
|
5663
|
+
}, {
|
5664
|
+
"locale": "hu",
|
5665
|
+
"file_name": "hu"
|
5666
|
+
}, {
|
5667
|
+
"locale": "id",
|
5668
|
+
"file_name": "id"
|
5669
|
+
}, {
|
5670
|
+
"locale": "is",
|
5671
|
+
"file_name": "is"
|
5672
|
+
}, {
|
5673
|
+
"locale": "it",
|
5674
|
+
"file_name": "it"
|
5675
|
+
}, {
|
5676
|
+
"locale": "it-CH",
|
5677
|
+
"file_name": "it-CH"
|
5678
|
+
}, {
|
5679
|
+
"locale": "ja",
|
5680
|
+
"file_name": "ja"
|
5681
|
+
}, {
|
5682
|
+
"locale": "ko",
|
5683
|
+
"file_name": "ko"
|
5684
|
+
}, {
|
5685
|
+
"locale": "lv",
|
5686
|
+
"file_name": "lv"
|
5687
|
+
}, {
|
5688
|
+
"locale": "ms",
|
5689
|
+
"file_name": "msa"
|
5690
|
+
}, {
|
5691
|
+
"locale": "nb",
|
5692
|
+
"file_name": "no"
|
5693
|
+
}, {
|
5694
|
+
"locale": "nl",
|
5695
|
+
"file_name": "nl"
|
5696
|
+
}, {
|
5697
|
+
"locale": "pl",
|
5698
|
+
"file_name": "pl"
|
5699
|
+
}, {
|
5700
|
+
"locale": "pt",
|
5701
|
+
"file_name": "pt"
|
5702
|
+
}, {
|
5703
|
+
"locale": "ro",
|
5704
|
+
"file_name": "ro"
|
5705
|
+
}, {
|
5706
|
+
"locale": "ru",
|
5707
|
+
"file_name": "ru"
|
5708
|
+
}, {
|
5709
|
+
"locale": "sk",
|
5710
|
+
"file_name": "sk"
|
5711
|
+
}, {
|
5712
|
+
"locale": "sq",
|
5713
|
+
"file_name": "sq"
|
5714
|
+
}, {
|
5715
|
+
"locale": "sr",
|
5716
|
+
"file_name": "sr"
|
5717
|
+
}, {
|
5718
|
+
"locale": "sv",
|
5719
|
+
"file_name": "sv"
|
5720
|
+
}, {
|
5721
|
+
"locale": "ta",
|
5722
|
+
"file_name": "ta"
|
5723
|
+
}, {
|
5724
|
+
"locale": "th",
|
5725
|
+
"file_name": "th"
|
5726
|
+
}, {
|
5727
|
+
"locale": "tr",
|
5728
|
+
"file_name": "tr"
|
5729
|
+
}, {
|
5730
|
+
"locale": "uk",
|
5731
|
+
"file_name": "uk"
|
5732
|
+
}, {
|
5733
|
+
"locale": "ur",
|
5734
|
+
"file_name": "ur"
|
5735
|
+
}, {
|
5736
|
+
"locale": "vi",
|
5737
|
+
"file_name": "vi"
|
5738
|
+
}, {
|
5739
|
+
"locale": "zh",
|
5740
|
+
"file_name": "zh-cn"
|
5741
|
+
}, {
|
5742
|
+
"locale": "zh-Hant",
|
5743
|
+
"file_name": "zh-tw"
|
5744
|
+
}
|
5745
|
+
];
|
5746
|
+
};
|
5747
|
+
|
5450
5748
|
TwitterCldr.set_data = function(bundle) {
|
5451
5749
|
TwitterCldr.data = bundle;
|
5452
5750
|
return null;
|
@@ -89,6 +89,16 @@ module TwitterCldr
|
|
89
89
|
def compile_implementation(options = {})
|
90
90
|
bundle = TwitterCldr::Js::Renderers::Bundle.new
|
91
91
|
bundle[:locale] = TwitterCldr::DEFAULT_LOCALE
|
92
|
+
|
93
|
+
available_locales = @locales.map do |locale|
|
94
|
+
{
|
95
|
+
locale: locale,
|
96
|
+
file_name: TwitterCldr.twitter_locale(locale),
|
97
|
+
}
|
98
|
+
end
|
99
|
+
|
100
|
+
bundle[:available_locales] = available_locales.sort_by { |x| x[:locale] }.to_json
|
101
|
+
|
92
102
|
file = compile_bundle(bundle, @features, implementation_renderers, options)
|
93
103
|
|
94
104
|
file.source
|
@@ -152,7 +162,8 @@ module TwitterCldr
|
|
152
162
|
:plural => TwitterCldr::Js::Renderers::Implementation::Numbers::RBNF::PluralRenderer,
|
153
163
|
:range => TwitterCldr::Js::Renderers::Implementation::Utils::RangeRenderer,
|
154
164
|
:range_set => TwitterCldr::Js::Renderers::Implementation::Utils::RangeSetRenderer,
|
155
|
-
:code_points => TwitterCldr::Js::Renderers::Implementation::Utils::CodePointsRenderer
|
165
|
+
:code_points => TwitterCldr::Js::Renderers::Implementation::Utils::CodePointsRenderer,
|
166
|
+
:clone => TwitterCldr::Js::Renderers::Implementation::Clone::CloneRenderer,
|
156
167
|
}
|
157
168
|
end
|
158
169
|
|
@@ -0,0 +1,58 @@
|
|
1
|
+
with_data_isolation = (data) -> (fn) ->
|
2
|
+
original = TwitterCldr.data
|
3
|
+
TwitterCldr.data = data
|
4
|
+
result = fn()
|
5
|
+
TwitterCldr.data = original
|
6
|
+
result
|
7
|
+
|
8
|
+
get_with_data_isolation = (data) -> (target, property_key, receiver) ->
|
9
|
+
isolate_data = with_data_isolation(data)
|
10
|
+
|
11
|
+
isolate_data(->
|
12
|
+
result = Reflect.get(target, property_key, receiver)
|
13
|
+
|
14
|
+
if typeof result == 'function'
|
15
|
+
fn = result
|
16
|
+
|
17
|
+
result = (args...) -> isolate_data(-> Reflect.apply(fn, target, args))
|
18
|
+
|
19
|
+
result
|
20
|
+
)
|
21
|
+
|
22
|
+
proxy_or_primitive = (value, handlers) ->
|
23
|
+
if value instanceof Object
|
24
|
+
new Proxy(value, handlers)
|
25
|
+
else
|
26
|
+
value
|
27
|
+
|
28
|
+
TwitterCldr.clone = (data) ->
|
29
|
+
if !data
|
30
|
+
throw new Error('Cannot create a clone with no data')
|
31
|
+
|
32
|
+
get = get_with_data_isolation(data)
|
33
|
+
isolate_data = with_data_isolation(data)
|
34
|
+
|
35
|
+
proxy_or_primitive(
|
36
|
+
root,
|
37
|
+
get: (target, property_key, receiver) ->
|
38
|
+
switch property_key
|
39
|
+
when 'set_data'
|
40
|
+
return -> throw new Error('Cannot set data on a TwitterCldr clone')
|
41
|
+
else
|
42
|
+
isolate_data(
|
43
|
+
-> proxy_or_primitive(
|
44
|
+
Reflect.get(target, property_key, receiver), {
|
45
|
+
get,
|
46
|
+
apply: (args...) ->
|
47
|
+
isolate_data(
|
48
|
+
-> Reflect.apply(args...)
|
49
|
+
)
|
50
|
+
construct: (args...) ->
|
51
|
+
isolate_data(
|
52
|
+
-> proxy_or_primitive(Reflect.construct(args...), { get })
|
53
|
+
)
|
54
|
+
}
|
55
|
+
)
|
56
|
+
)
|
57
|
+
set: () -> throw new Error('Cannot set properties on a TwitterCldr clone')
|
58
|
+
)
|
@@ -21,30 +21,47 @@ class TwitterCldr.NumberFormatter
|
|
21
21
|
@constructor.data().symbols
|
22
22
|
|
23
23
|
format: (number, options = {}) ->
|
24
|
-
opts =
|
24
|
+
opts = @default_format_options_for(number)
|
25
25
|
|
26
26
|
for key, val of options
|
27
27
|
opts[key] = if options[key]? then options[key] else opts[key]
|
28
28
|
|
29
|
-
|
29
|
+
number = @round_to(number, opts.precision || 0)
|
30
|
+
|
31
|
+
tokens = @get_tokens(number, opts)
|
30
32
|
|
31
33
|
if tokens?
|
32
34
|
if tokens not instanceof Array
|
33
35
|
tokens_sample = tokens[Object.keys(tokens)[0]]
|
34
36
|
truncated_number = @truncate_number(number, tokens_sample[1].length)
|
37
|
+
|
38
|
+
rounded_num = Number(@parse_number(truncated_number, opts)[0]) * Number(@get_key(number)) / (10 ** (tokens_sample[1].length - 1))
|
39
|
+
|
40
|
+
# Checking _stack_depth should be a redundant condition, as
|
41
|
+
# @get_key(rounded_num) should always equal @get_key(number) the second
|
42
|
+
# time around. We only check it to prevent infinite loops in case of
|
43
|
+
# bugs
|
44
|
+
if !opts._stack_depth && @get_key(rounded_num) != @get_key(number)
|
45
|
+
return @format(rounded_num, Object.assign(opts, { _stack_depth: 1 }))
|
46
|
+
|
35
47
|
truncated_number = Math.floor(truncated_number) if opts.precision == 0
|
36
48
|
tokens = tokens[TwitterCldr.PluralRules.rule_for(truncated_number)]
|
37
49
|
|
38
|
-
[prefix, suffix, integer_format, fraction_format] =
|
39
|
-
|
40
|
-
[intg, fraction] =
|
50
|
+
[prefix, suffix, integer_format, fraction_format] = @partition_tokens(tokens)
|
51
|
+
number_part = @truncate_number(number, integer_format.format.length)
|
52
|
+
[intg, fraction] = @parse_number(number_part, opts)
|
41
53
|
result = integer_format.apply(parseFloat(intg), opts)
|
42
54
|
result += fraction_format.apply(fraction, opts) if fraction
|
43
|
-
sign = if
|
55
|
+
sign = if number_part < 0 && prefix != "-" then @symbols().minus_sign || @default_symbols.minus_sign else ""
|
44
56
|
"#{prefix}#{result}#{suffix}"
|
45
57
|
else
|
46
|
-
|
47
|
-
|
58
|
+
unless @ instanceof TwitterCldr.DecimalFormatter
|
59
|
+
# No specific formatting pattern for this number in current locale, so
|
60
|
+
# we fall back to DecimalFormatter
|
61
|
+
new TwitterCldr.DecimalFormatter().format(number, opts)
|
62
|
+
else
|
63
|
+
# Use default toString if current instance is already a DecimalFormatter
|
64
|
+
number.toString()
|
48
65
|
|
49
66
|
truncate_number: (number, decimal_digits) ->
|
50
67
|
number # noop for base class
|
@@ -75,7 +92,7 @@ class TwitterCldr.NumberFormatter
|
|
75
92
|
Math.round(number * factor) / factor
|
76
93
|
|
77
94
|
get_tokens: ->
|
78
|
-
throw "get_tokens() not implemented - use a derived class like PercentFormatter."
|
95
|
+
throw new Error("get_tokens() not implemented - use a derived class like PercentFormatter.")
|
79
96
|
|
80
97
|
class TwitterCldr.PercentFormatter extends TwitterCldr.NumberFormatter
|
81
98
|
constructor: (options = {}) ->
|
@@ -106,7 +123,7 @@ class TwitterCldr.DecimalFormatter extends TwitterCldr.NumberFormatter
|
|
106
123
|
result = transliterator.transliterate(result)
|
107
124
|
result
|
108
125
|
catch error
|
109
|
-
number
|
126
|
+
number.toString()
|
110
127
|
|
111
128
|
default_format_options_for: (number) ->
|
112
129
|
precision: this.precision_from(number)
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
# Copyright 2012 Twitter, Inc
|
4
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
5
|
+
|
6
|
+
module TwitterCldr
|
7
|
+
module Js
|
8
|
+
module Renderers
|
9
|
+
module Implementation
|
10
|
+
module Clone
|
11
|
+
|
12
|
+
class CloneRenderer < TwitterCldr::Js::Renderers::Base
|
13
|
+
set_template "mustache/implementation/clone/clone.coffee"
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -19,6 +19,7 @@ module TwitterCldr
|
|
19
19
|
autoload :Numbers, 'twitter_cldr/js/renderers/implementation/numbers'
|
20
20
|
autoload :Parsers, 'twitter_cldr/js/renderers/implementation/parsers'
|
21
21
|
autoload :Tokenizers, 'twitter_cldr/js/renderers/implementation/tokenizers'
|
22
|
+
autoload :Clone, 'twitter_cldr/js/renderers/implementation/clone'
|
22
23
|
|
23
24
|
module Shared
|
24
25
|
autoload :BidiRenderer, 'twitter_cldr/js/renderers/implementation/shared/bidi_renderer'
|
@@ -0,0 +1,234 @@
|
|
1
|
+
const locales = "en,ar,ko,ru,hi".split(",");
|
2
|
+
const date = new Date(2000, 1, 1);
|
3
|
+
|
4
|
+
// Updated version of
|
5
|
+
// https://github.com/twitter/twitter-cldr-npm/blob/master/twitter_cldr.js
|
6
|
+
// that clones by default
|
7
|
+
const load = function (locale, options) {
|
8
|
+
var defaultOptions = { clone: true };
|
9
|
+
options = options || {};
|
10
|
+
|
11
|
+
for (var k in defaultOptions) {
|
12
|
+
if (!(k in options)) {
|
13
|
+
options[k] = defaultOptions[k];
|
14
|
+
}
|
15
|
+
}
|
16
|
+
|
17
|
+
var TwitterCldr = require("../../../lib/assets/javascripts/twitter_cldr/core");
|
18
|
+
var data = require("../../../lib/assets/javascripts/twitter_cldr/" + locale);
|
19
|
+
|
20
|
+
if (options.clone) {
|
21
|
+
return TwitterCldr.clone(data);
|
22
|
+
} else {
|
23
|
+
TwitterCldr.set_data(data);
|
24
|
+
return TwitterCldr;
|
25
|
+
}
|
26
|
+
};
|
27
|
+
|
28
|
+
const checkDataIsolation = ({ class: klass, ctorParams, methods, staticMethods, loadOptions }) => {
|
29
|
+
methods = methods || {}
|
30
|
+
staticMethods = staticMethods || {}
|
31
|
+
ctorParams = ctorParams || []
|
32
|
+
|
33
|
+
describe(klass, () => {
|
34
|
+
const allMethods = [
|
35
|
+
...(Object.entries(methods)).map(x => [false, ...x]),
|
36
|
+
...(Object.entries(staticMethods)).map(x => [true, ...x]),
|
37
|
+
]
|
38
|
+
|
39
|
+
for (let [static, name, { params, compare }] of allMethods) {
|
40
|
+
params = params || []
|
41
|
+
compare = compare || ((x) => x)
|
42
|
+
|
43
|
+
describe(`${static ? "." : "#"}${name}`, () => {
|
44
|
+
const twitterCldrs = locales.map((locale) => {
|
45
|
+
const params = [locale, loadOptions].filter((x) => x != null);
|
46
|
+
const TwitterCldr = load(...params);
|
47
|
+
|
48
|
+
return { locale, TwitterCldr };
|
49
|
+
});
|
50
|
+
|
51
|
+
const formatters = twitterCldrs.map(({ locale, TwitterCldr }) => {
|
52
|
+
const formatter = static ? TwitterCldr[klass] : new TwitterCldr[klass](...ctorParams)
|
53
|
+
|
54
|
+
return { locale, formatter };
|
55
|
+
});
|
56
|
+
|
57
|
+
const formatFns = formatters.map(({ locale, formatter }) => ({
|
58
|
+
locale,
|
59
|
+
format: formatter[name].bind(formatter),
|
60
|
+
}));
|
61
|
+
|
62
|
+
const results = formatFns.map(({ locale, format }) => ({
|
63
|
+
locale,
|
64
|
+
result: compare(format(...params)),
|
65
|
+
}));
|
66
|
+
|
67
|
+
it(`sanity check - result for same locale is equal`, () => {
|
68
|
+
const { formatter } = formatters[0];
|
69
|
+
const format = formatter[name].bind(formatter);
|
70
|
+
|
71
|
+
expect(compare(format(...params))).toBe(compare(format(...params)));
|
72
|
+
});
|
73
|
+
|
74
|
+
for (const [idx, { locale, result }] of results.entries()) {
|
75
|
+
const prevs = results.slice(0, idx);
|
76
|
+
|
77
|
+
if (!prevs.length) continue;
|
78
|
+
|
79
|
+
for (const prev of prevs) {
|
80
|
+
it(`result for "${locale}" differs from result for "${prev.locale}"`, () => {
|
81
|
+
expect(result).not.toBe(prev.result);
|
82
|
+
});
|
83
|
+
}
|
84
|
+
}
|
85
|
+
});
|
86
|
+
}
|
87
|
+
});
|
88
|
+
};
|
89
|
+
|
90
|
+
const tests = [
|
91
|
+
{
|
92
|
+
class: "DateTimeFormatter",
|
93
|
+
methods: {
|
94
|
+
format: { params: [date, { type: "full" }] },
|
95
|
+
weekday_local_stand_alone: { params: [date, "cc", 2] },
|
96
|
+
},
|
97
|
+
},
|
98
|
+
{
|
99
|
+
class: "Languages",
|
100
|
+
staticMethods: {
|
101
|
+
from_code: { params: ["en"] },
|
102
|
+
all: { params: [], compare: (x) => x.ja },
|
103
|
+
},
|
104
|
+
},
|
105
|
+
{
|
106
|
+
class: "RBNF",
|
107
|
+
methods: {
|
108
|
+
format: { params: [1, "SpelloutRules", "spellout-numbering"] },
|
109
|
+
},
|
110
|
+
}
|
111
|
+
];
|
112
|
+
|
113
|
+
describe("data isolation", () => {
|
114
|
+
for (const loadOptions of [
|
115
|
+
undefined, // no options param supplied
|
116
|
+
{}, // empty options - defaults to clone=true
|
117
|
+
{ clone: true }, // explicitly specify clone=true
|
118
|
+
]) {
|
119
|
+
tests.map((x) => ({ ...x, loadOptions })).forEach(checkDataIsolation);
|
120
|
+
}
|
121
|
+
});
|
122
|
+
|
123
|
+
describe("clone behavior", () => {
|
124
|
+
const TwitterCldr = require("../../../lib/assets/javascripts/twitter_cldr/core");
|
125
|
+
const en = require("../../../lib/assets/javascripts/twitter_cldr/en");
|
126
|
+
const ja = require("../../../lib/assets/javascripts/twitter_cldr/ja");
|
127
|
+
|
128
|
+
beforeEach(() => {
|
129
|
+
TwitterCldr.set_data(undefined);
|
130
|
+
})
|
131
|
+
|
132
|
+
afterEach(() => {
|
133
|
+
TwitterCldr.set_data(undefined);
|
134
|
+
});
|
135
|
+
|
136
|
+
const locale = (clone) => clone.get_data().Settings.locale;
|
137
|
+
|
138
|
+
it("can be cloned from base that has no data", () => {
|
139
|
+
const clone = TwitterCldr.clone(en);
|
140
|
+
|
141
|
+
expect(locale(clone)).toBe("en");
|
142
|
+
expect(TwitterCldr.is_data_set()).toBe(false);
|
143
|
+
expect(clone.is_data_set()).toBe(true);
|
144
|
+
});
|
145
|
+
|
146
|
+
it("returns undefined for properties not present on `root`", () => {
|
147
|
+
TwitterCldr.set_data(en);
|
148
|
+
const clone = TwitterCldr.clone(en);
|
149
|
+
|
150
|
+
expect(TwitterCldr.data).toBe(undefined);
|
151
|
+
expect(clone.data).toBe(undefined);
|
152
|
+
});
|
153
|
+
|
154
|
+
it("doesn't affect data of the base TwitterCldr", () => {
|
155
|
+
TwitterCldr.set_data(ja);
|
156
|
+
TwitterCldr.clone(en);
|
157
|
+
|
158
|
+
expect(locale(TwitterCldr)).toBe("ja");
|
159
|
+
});
|
160
|
+
|
161
|
+
|
162
|
+
it("isn't affected by data of the base TwitterCldr", () => {
|
163
|
+
const clone = TwitterCldr.clone(en);
|
164
|
+
TwitterCldr.set_data(ja);
|
165
|
+
|
166
|
+
expect(locale(clone)).toBe("en");
|
167
|
+
});
|
168
|
+
|
169
|
+
it("can be cloned indefinitely", () => {
|
170
|
+
const cloneEn1 = TwitterCldr.clone(en);
|
171
|
+
const cloneEn2 = cloneEn1.clone(en);
|
172
|
+
const cloneJa = cloneEn2.clone(ja);
|
173
|
+
|
174
|
+
expect(locale(cloneEn1)).toBe("en");
|
175
|
+
expect(locale(cloneEn2)).toBe(locale(cloneEn1));
|
176
|
+
expect(locale(cloneJa)).toBe("ja");
|
177
|
+
});
|
178
|
+
|
179
|
+
it("throws if attempting to create a clone with no data", () => {
|
180
|
+
expect(() => TwitterCldr.clone()).toThrow();
|
181
|
+
expect(() => TwitterCldr.clone(undefined)).toThrow();
|
182
|
+
expect(() => TwitterCldr.clone(null)).toThrow();
|
183
|
+
|
184
|
+
expect(() => TwitterCldr.clone({})).not.toThrow();
|
185
|
+
});
|
186
|
+
|
187
|
+
describe("cloned version throws if attempting to set data", () => {
|
188
|
+
const clone = TwitterCldr.clone(en);
|
189
|
+
|
190
|
+
it("using `set_data`", () => {
|
191
|
+
expect(() => clone.set_data({})).toThrow();
|
192
|
+
});
|
193
|
+
|
194
|
+
it("using `data = `", () => {
|
195
|
+
expect(() => clone.data = {}).toThrow();
|
196
|
+
});
|
197
|
+
});
|
198
|
+
});
|
199
|
+
|
200
|
+
describe("load(..., false)", () => {
|
201
|
+
describe("continues to use global state", () => {
|
202
|
+
const results = locales.map((locale) => {
|
203
|
+
const TwitterCldr = load(locale, { clone: false });
|
204
|
+
return new TwitterCldr.DateTimeFormatter();
|
205
|
+
}).map((formatter) => formatter.format(date, { type: "full" }));
|
206
|
+
|
207
|
+
describe("DateTimeFormatter", () => {
|
208
|
+
it("#format", () => {
|
209
|
+
expect(new Set(results).size).toEqual(1);
|
210
|
+
});
|
211
|
+
});
|
212
|
+
});
|
213
|
+
|
214
|
+
describe("works in environments without `Proxy` support", () => {
|
215
|
+
const originalProxy = globalThis.Proxy;
|
216
|
+
|
217
|
+
beforeEach(() => {
|
218
|
+
globalThis.Proxy = undefined;
|
219
|
+
});
|
220
|
+
|
221
|
+
afterEach(() => {
|
222
|
+
globalThis.Proxy = originalProxy;
|
223
|
+
});
|
224
|
+
|
225
|
+
describe("DateTimeFormatter", () => {
|
226
|
+
it("#weekday_local_stand_alone", () => {
|
227
|
+
const TwitterCldr = load("en", { clone: false });
|
228
|
+
const formatter = new TwitterCldr.DateTimeFormatter();
|
229
|
+
|
230
|
+
expect(formatter.weekday_local_stand_alone(date, "cc", 2)).toEqual("Tue");
|
231
|
+
});
|
232
|
+
});
|
233
|
+
});
|
234
|
+
});
|
@@ -0,0 +1,77 @@
|
|
1
|
+
const TwitterCldr = require("../../../lib/assets/javascripts/twitter_cldr/core.js");
|
2
|
+
|
3
|
+
const testData = {
|
4
|
+
Long: {
|
5
|
+
"en": [
|
6
|
+
// edge cases
|
7
|
+
{ raw: 999_499, precisions: ["999 thousand", "999.5 thousand"] },
|
8
|
+
{ raw: 999_500, precisions: ["1 million", "999.5 thousand"] },
|
9
|
+
{ raw: 1_000_000, precisions: ["1 million", "1.0 million"] },
|
10
|
+
|
11
|
+
// fractional
|
12
|
+
{ raw: 999.49, precisions: ["999", "999.5"], default: "999.49" },
|
13
|
+
{ raw: 999.5, precisions: ["1 thousand", "999.5"], default: "999.5" },
|
14
|
+
|
15
|
+
// negative
|
16
|
+
{ raw: -1_000_000, precisions: ["-1,000,000"] },
|
17
|
+
{ raw: -999_500, precisions: ["-999,500"] },
|
18
|
+
],
|
19
|
+
"zh-cn": [
|
20
|
+
// edge cases
|
21
|
+
{ raw: 9499, precisions: ["9千", "9.5千"] },
|
22
|
+
{ raw: 9500, precisions: ["1万", "9.5千"] },
|
23
|
+
{ raw: 10_000, precisions: ["1万", "1.0万"] },
|
24
|
+
],
|
25
|
+
"es": [
|
26
|
+
// pluralization
|
27
|
+
{ raw: 1e3, precisions: ["1 mil", "1,0 mil"] },
|
28
|
+
{ raw: 2e3, precisions: ["2 mil", "2,0 mil"] },
|
29
|
+
{ raw: 1e6, precisions: ["1 millón", "1,0 millón"] },
|
30
|
+
{ raw: 2e6, precisions: ["2 millones", "2,0 millones"] },
|
31
|
+
{ raw: 1e9, precisions: ["1 mil millones", "1,0 mil millones"] },
|
32
|
+
|
33
|
+
// fractional
|
34
|
+
{ raw: 999.49, precisions: ["999", "999,5"], default: "999,49" },
|
35
|
+
{ raw: 999.5, precisions: ["1 mil", "999,5"], default: "999,5" },
|
36
|
+
|
37
|
+
// negative
|
38
|
+
{ raw: -1_000_000, precisions: ["-1.000.000"] },
|
39
|
+
{ raw: -999_500, precisions: ["-999.500"] },
|
40
|
+
],
|
41
|
+
},
|
42
|
+
Short: {
|
43
|
+
"en": [
|
44
|
+
// edge cases
|
45
|
+
{ raw: 999_499, precisions: ["999K", "999.5K"] },
|
46
|
+
{ raw: 999_500, precisions: ["1M", "999.5K"] },
|
47
|
+
{ raw: 1_000_000, precisions: ["1M", "1.0M"] },
|
48
|
+
],
|
49
|
+
},
|
50
|
+
};
|
51
|
+
|
52
|
+
for (const [kind, locales] of Object.entries(testData)) {
|
53
|
+
for (const [localeFileName, tests] of Object.entries(locales)) {
|
54
|
+
describe(`${kind}DecimalFormatter (${localeFileName})`, () => {
|
55
|
+
let formatter;
|
56
|
+
|
57
|
+
beforeEach(() => {
|
58
|
+
TwitterCldr.set_data(require(`../../../lib/assets/javascripts/twitter_cldr/${localeFileName}`));
|
59
|
+
formatter = new TwitterCldr[`${kind}DecimalFormatter`]();
|
60
|
+
});
|
61
|
+
|
62
|
+
describe("#format", () => {
|
63
|
+
for (const { raw, precisions, default: _default } of tests) {
|
64
|
+
it(`formats ${raw} with no options supplied`, () => {
|
65
|
+
expect(formatter.format(raw)).toEqual(_default ?? precisions[0]);
|
66
|
+
});
|
67
|
+
|
68
|
+
for (const [precision, expected] of precisions.entries()) {
|
69
|
+
it(`formats ${raw} to precision ${precision}`, () => {
|
70
|
+
expect(formatter.format(raw, { precision })).toEqual(expected);
|
71
|
+
});
|
72
|
+
}
|
73
|
+
}
|
74
|
+
});
|
75
|
+
});
|
76
|
+
}
|
77
|
+
}
|
data/twitter_cldr_js.gemspec
CHANGED
@@ -14,12 +14,11 @@ Gem::Specification.new do |s|
|
|
14
14
|
s.summary = "Text formatting using data from Unicode's Common Locale Data Repository (CLDR)."
|
15
15
|
|
16
16
|
s.add_dependency 'json'
|
17
|
-
s.add_dependency 'railties', '>= 3.0'
|
17
|
+
s.add_dependency 'railties', '>= 3.0'
|
18
18
|
|
19
19
|
s.add_development_dependency 'rake'
|
20
20
|
s.add_development_dependency 'mustache', '~> 0.99.4'
|
21
21
|
s.add_development_dependency 'ruby_parser', '~> 2.3.1'
|
22
|
-
s.add_development_dependency 'therubyracer', '~> 0.12.0'
|
23
22
|
s.add_development_dependency 'uglifier', '~> 1.2.4'
|
24
23
|
s.add_development_dependency 'coffee-script', '~> 2.2.0'
|
25
24
|
s.add_development_dependency 'coffee-script-source', '~> 1.8.0'
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: twitter_cldr_js
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.
|
4
|
+
version: 3.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Cameron Dutro
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2023-03-20 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: json
|
@@ -31,9 +31,6 @@ dependencies:
|
|
31
31
|
- - ">="
|
32
32
|
- !ruby/object:Gem::Version
|
33
33
|
version: '3.0'
|
34
|
-
- - "<"
|
35
|
-
- !ruby/object:Gem::Version
|
36
|
-
version: '5.0'
|
37
34
|
type: :runtime
|
38
35
|
prerelease: false
|
39
36
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -41,9 +38,6 @@ dependencies:
|
|
41
38
|
- - ">="
|
42
39
|
- !ruby/object:Gem::Version
|
43
40
|
version: '3.0'
|
44
|
-
- - "<"
|
45
|
-
- !ruby/object:Gem::Version
|
46
|
-
version: '5.0'
|
47
41
|
- !ruby/object:Gem::Dependency
|
48
42
|
name: rake
|
49
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -86,20 +80,6 @@ dependencies:
|
|
86
80
|
- - "~>"
|
87
81
|
- !ruby/object:Gem::Version
|
88
82
|
version: 2.3.1
|
89
|
-
- !ruby/object:Gem::Dependency
|
90
|
-
name: therubyracer
|
91
|
-
requirement: !ruby/object:Gem::Requirement
|
92
|
-
requirements:
|
93
|
-
- - "~>"
|
94
|
-
- !ruby/object:Gem::Version
|
95
|
-
version: 0.12.0
|
96
|
-
type: :development
|
97
|
-
prerelease: false
|
98
|
-
version_requirements: !ruby/object:Gem::Requirement
|
99
|
-
requirements:
|
100
|
-
- - "~>"
|
101
|
-
- !ruby/object:Gem::Version
|
102
|
-
version: 0.12.0
|
103
83
|
- !ruby/object:Gem::Dependency
|
104
84
|
name: uglifier
|
105
85
|
requirement: !ruby/object:Gem::Requirement
|
@@ -257,6 +237,7 @@ files:
|
|
257
237
|
- lib/twitter_cldr/js/mustache/implementation/calendars/additional_date_format_selector.coffee
|
258
238
|
- lib/twitter_cldr/js/mustache/implementation/calendars/datetime.coffee
|
259
239
|
- lib/twitter_cldr/js/mustache/implementation/calendars/timespan.coffee
|
240
|
+
- lib/twitter_cldr/js/mustache/implementation/clone/clone.coffee
|
260
241
|
- lib/twitter_cldr/js/mustache/implementation/numbers/numbers.coffee
|
261
242
|
- lib/twitter_cldr/js/mustache/implementation/numbers/rbnf/formatters.coffee
|
262
243
|
- lib/twitter_cldr/js/mustache/implementation/numbers/rbnf/number_data_reader.coffee
|
@@ -327,6 +308,7 @@ files:
|
|
327
308
|
- lib/twitter_cldr/js/renderers/data/shared/list_renderer.rb
|
328
309
|
- lib/twitter_cldr/js/renderers/data_bundle.rb
|
329
310
|
- lib/twitter_cldr/js/renderers/implementation/calendars.rb
|
311
|
+
- lib/twitter_cldr/js/renderers/implementation/clone.rb
|
330
312
|
- lib/twitter_cldr/js/renderers/implementation/numbers.rb
|
331
313
|
- lib/twitter_cldr/js/renderers/implementation/parsers.rb
|
332
314
|
- lib/twitter_cldr/js/renderers/implementation/plurals.rb
|
@@ -352,6 +334,7 @@ files:
|
|
352
334
|
- spec/js/calendars/datetime.spec.js
|
353
335
|
- spec/js/calendars/timespan.ru.spec.js
|
354
336
|
- spec/js/calendars/timespan.spec.js
|
337
|
+
- spec/js/clone/clone.spec.js
|
355
338
|
- spec/js/numbers/abbreviated/abbreviated_number.spec.js
|
356
339
|
- spec/js/numbers/abbreviated/long_decimal.ko.spec.js
|
357
340
|
- spec/js/numbers/abbreviated/long_decimal.ru.spec.js
|
@@ -364,6 +347,7 @@ files:
|
|
364
347
|
- spec/js/numbers/decimal.spec.js
|
365
348
|
- spec/js/numbers/helpers/fraction.spec.js
|
366
349
|
- spec/js/numbers/helpers/integer.spec.js
|
350
|
+
- spec/js/numbers/long_short_decimal.spec.js
|
367
351
|
- spec/js/numbers/number.spec.js
|
368
352
|
- spec/js/numbers/percent.spec.js
|
369
353
|
- spec/js/numbers/rbnf.spec.js
|
@@ -416,7 +400,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
416
400
|
- !ruby/object:Gem::Version
|
417
401
|
version: '0'
|
418
402
|
requirements: []
|
419
|
-
rubygems_version: 3.
|
403
|
+
rubygems_version: 3.1.6
|
420
404
|
signing_key:
|
421
405
|
specification_version: 4
|
422
406
|
summary: Text formatting using data from Unicode's Common Locale Data Repository (CLDR).
|