···11-/**
22- * cldrpluralparser.js
33- * A parser engine for CLDR plural rules.
44- *
55- * Copyright 2012-2014 Santhosh Thottingal and other contributors
66- * Released under the MIT license
77- * http://opensource.org/licenses/MIT
88- *
99- * @source https://github.com/santhoshtr/CLDRPluralRuleParser
1010- * @author Santhosh Thottingal <santhosh.thottingal@gmail.com>
1111- * @author Timo Tijhof
1212- * @author Amir Aharoni
1313- */
1414-1515-/**
1616- * Evaluates a plural rule in CLDR syntax for a number
1717- * @param {string} rule
1818- * @param {integer} number
1919- * @return {boolean} true if evaluation passed, false if evaluation failed.
2020- */
2121-2222-// UMD returnExports https://github.com/umdjs/umd/blob/master/returnExports.js
2323-(function(root, factory) {
2424- if (typeof define === 'function' && define.amd) {
2525- // AMD. Register as an anonymous module.
2626- define(factory);
2727- } else if (typeof exports === 'object') {
2828- // Node. Does not work with strict CommonJS, but
2929- // only CommonJS-like environments that support module.exports,
3030- // like Node.
3131- module.exports = factory();
3232- } else {
3333- // Browser globals (root is window)
3434- root.pluralRuleParser = factory();
3535- }
3636-}(this, function() {
3737-3838-function pluralRuleParser(rule, number) {
3939- 'use strict';
4040-4141- /*
4242- Syntax: see http://unicode.org/reports/tr35/#Language_Plural_Rules
4343- -----------------------------------------------------------------
4444- condition = and_condition ('or' and_condition)*
4545- ('@integer' samples)?
4646- ('@decimal' samples)?
4747- and_condition = relation ('and' relation)*
4848- relation = is_relation | in_relation | within_relation
4949- is_relation = expr 'is' ('not')? value
5050- in_relation = expr (('not')? 'in' | '=' | '!=') range_list
5151- within_relation = expr ('not')? 'within' range_list
5252- expr = operand (('mod' | '%') value)?
5353- operand = 'n' | 'i' | 'f' | 't' | 'v' | 'w'
5454- range_list = (range | value) (',' range_list)*
5555- value = digit+
5656- digit = 0|1|2|3|4|5|6|7|8|9
5757- range = value'..'value
5858- samples = sampleRange (',' sampleRange)* (',' ('…'|'...'))?
5959- sampleRange = decimalValue '~' decimalValue
6060- decimalValue = value ('.' value)?
6161- */
6262-6363- // We don't evaluate the samples section of the rule. Ignore it.
6464- rule = rule.split('@')[0].replace(/^\s*/, '').replace(/\s*$/, '');
6565-6666- if (!rule.length) {
6767- // Empty rule or 'other' rule.
6868- return true;
6969- }
7070-7171- // Indicates the current position in the rule as we parse through it.
7272- // Shared among all parsing functions below.
7373- var pos = 0,
7474- operand,
7575- expression,
7676- relation,
7777- result,
7878- whitespace = makeRegexParser(/^\s+/),
7979- value = makeRegexParser(/^\d+/),
8080- _n_ = makeStringParser('n'),
8181- _i_ = makeStringParser('i'),
8282- _f_ = makeStringParser('f'),
8383- _t_ = makeStringParser('t'),
8484- _v_ = makeStringParser('v'),
8585- _w_ = makeStringParser('w'),
8686- _is_ = makeStringParser('is'),
8787- _isnot_ = makeStringParser('is not'),
8888- _isnot_sign_ = makeStringParser('!='),
8989- _equal_ = makeStringParser('='),
9090- _mod_ = makeStringParser('mod'),
9191- _percent_ = makeStringParser('%'),
9292- _not_ = makeStringParser('not'),
9393- _in_ = makeStringParser('in'),
9494- _within_ = makeStringParser('within'),
9595- _range_ = makeStringParser('..'),
9696- _comma_ = makeStringParser(','),
9797- _or_ = makeStringParser('or'),
9898- _and_ = makeStringParser('and');
9999-100100- function debug() {
101101- // console.log.apply(console, arguments);
102102- }
103103-104104- debug('pluralRuleParser', rule, number);
105105-106106- // Try parsers until one works, if none work return null
107107- function choice(parserSyntax) {
108108- return function() {
109109- var i, result;
110110-111111- for (i = 0; i < parserSyntax.length; i++) {
112112- result = parserSyntax[i]();
113113-114114- if (result !== null) {
115115- return result;
116116- }
117117- }
118118-119119- return null;
120120- };
121121- }
122122-123123- // Try several parserSyntax-es in a row.
124124- // All must succeed; otherwise, return null.
125125- // This is the only eager one.
126126- function sequence(parserSyntax) {
127127- var i, parserRes,
128128- originalPos = pos,
129129- result = [];
130130-131131- for (i = 0; i < parserSyntax.length; i++) {
132132- parserRes = parserSyntax[i]();
133133-134134- if (parserRes === null) {
135135- pos = originalPos;
136136-137137- return null;
138138- }
139139-140140- result.push(parserRes);
141141- }
142142-143143- return result;
144144- }
145145-146146- // Run the same parser over and over until it fails.
147147- // Must succeed a minimum of n times; otherwise, return null.
148148- function nOrMore(n, p) {
149149- return function() {
150150- var originalPos = pos,
151151- result = [],
152152- parsed = p();
153153-154154- while (parsed !== null) {
155155- result.push(parsed);
156156- parsed = p();
157157- }
158158-159159- if (result.length < n) {
160160- pos = originalPos;
161161-162162- return null;
163163- }
164164-165165- return result;
166166- };
167167- }
168168-169169- // Helpers - just make parserSyntax out of simpler JS builtin types
170170- function makeStringParser(s) {
171171- var len = s.length;
172172-173173- return function() {
174174- var result = null;
175175-176176- if (rule.substr(pos, len) === s) {
177177- result = s;
178178- pos += len;
179179- }
180180-181181- return result;
182182- };
183183- }
184184-185185- function makeRegexParser(regex) {
186186- return function() {
187187- var matches = rule.substr(pos).match(regex);
188188-189189- if (matches === null) {
190190- return null;
191191- }
192192-193193- pos += matches[0].length;
194194-195195- return matches[0];
196196- };
197197- }
198198-199199- /**
200200- * Integer digits of n.
201201- */
202202- function i() {
203203- var result = _i_();
204204-205205- if (result === null) {
206206- debug(' -- failed i', parseInt(number, 10));
207207-208208- return result;
209209- }
210210-211211- result = parseInt(number, 10);
212212- debug(' -- passed i ', result);
213213-214214- return result;
215215- }
216216-217217- /**
218218- * Absolute value of the source number (integer and decimals).
219219- */
220220- function n() {
221221- var result = _n_();
222222-223223- if (result === null) {
224224- debug(' -- failed n ', number);
225225-226226- return result;
227227- }
228228-229229- result = parseFloat(number, 10);
230230- debug(' -- passed n ', result);
231231-232232- return result;
233233- }
234234-235235- /**
236236- * Visible fractional digits in n, with trailing zeros.
237237- */
238238- function f() {
239239- var result = _f_();
240240-241241- if (result === null) {
242242- debug(' -- failed f ', number);
243243-244244- return result;
245245- }
246246-247247- result = (number + '.').split('.')[1] || 0;
248248- debug(' -- passed f ', result);
249249-250250- return result;
251251- }
252252-253253- /**
254254- * Visible fractional digits in n, without trailing zeros.
255255- */
256256- function t() {
257257- var result = _t_();
258258-259259- if (result === null) {
260260- debug(' -- failed t ', number);
261261-262262- return result;
263263- }
264264-265265- result = (number + '.').split('.')[1].replace(/0$/, '') || 0;
266266- debug(' -- passed t ', result);
267267-268268- return result;
269269- }
270270-271271- /**
272272- * Number of visible fraction digits in n, with trailing zeros.
273273- */
274274- function v() {
275275- var result = _v_();
276276-277277- if (result === null) {
278278- debug(' -- failed v ', number);
279279-280280- return result;
281281- }
282282-283283- result = (number + '.').split('.')[1].length || 0;
284284- debug(' -- passed v ', result);
285285-286286- return result;
287287- }
288288-289289- /**
290290- * Number of visible fraction digits in n, without trailing zeros.
291291- */
292292- function w() {
293293- var result = _w_();
294294-295295- if (result === null) {
296296- debug(' -- failed w ', number);
297297-298298- return result;
299299- }
300300-301301- result = (number + '.').split('.')[1].replace(/0$/, '').length || 0;
302302- debug(' -- passed w ', result);
303303-304304- return result;
305305- }
306306-307307- // operand = 'n' | 'i' | 'f' | 't' | 'v' | 'w'
308308- operand = choice([n, i, f, t, v, w]);
309309-310310- // expr = operand (('mod' | '%') value)?
311311- expression = choice([mod, operand]);
312312-313313- function mod() {
314314- var result = sequence(
315315- [operand, whitespace, choice([_mod_, _percent_]), whitespace, value]
316316- );
317317-318318- if (result === null) {
319319- debug(' -- failed mod');
320320-321321- return null;
322322- }
323323-324324- debug(' -- passed ' + parseInt(result[0], 10) + ' ' + result[2] + ' ' + parseInt(result[4], 10));
325325-326326- return parseFloat(result[0]) % parseInt(result[4], 10);
327327- }
328328-329329- function not() {
330330- var result = sequence([whitespace, _not_]);
331331-332332- if (result === null) {
333333- debug(' -- failed not');
334334-335335- return null;
336336- }
337337-338338- return result[1];
339339- }
340340-341341- // is_relation = expr 'is' ('not')? value
342342- function is() {
343343- var result = sequence([expression, whitespace, choice([_is_]), whitespace, value]);
344344-345345- if (result !== null) {
346346- debug(' -- passed is : ' + result[0] + ' == ' + parseInt(result[4], 10));
347347-348348- return result[0] === parseInt(result[4], 10);
349349- }
350350-351351- debug(' -- failed is');
352352-353353- return null;
354354- }
355355-356356- // is_relation = expr 'is' ('not')? value
357357- function isnot() {
358358- var result = sequence(
359359- [expression, whitespace, choice([_isnot_, _isnot_sign_]), whitespace, value]
360360- );
361361-362362- if (result !== null) {
363363- debug(' -- passed isnot: ' + result[0] + ' != ' + parseInt(result[4], 10));
364364-365365- return result[0] !== parseInt(result[4], 10);
366366- }
367367-368368- debug(' -- failed isnot');
369369-370370- return null;
371371- }
372372-373373- function not_in() {
374374- var i, range_list,
375375- result = sequence([expression, whitespace, _isnot_sign_, whitespace, rangeList]);
376376-377377- if (result !== null) {
378378- debug(' -- passed not_in: ' + result[0] + ' != ' + result[4]);
379379- range_list = result[4];
380380-381381- for (i = 0; i < range_list.length; i++) {
382382- if (parseInt(range_list[i], 10) === parseInt(result[0], 10)) {
383383- return false;
384384- }
385385- }
386386-387387- return true;
388388- }
389389-390390- debug(' -- failed not_in');
391391-392392- return null;
393393- }
394394-395395- // range_list = (range | value) (',' range_list)*
396396- function rangeList() {
397397- var result = sequence([choice([range, value]), nOrMore(0, rangeTail)]),
398398- resultList = [];
399399-400400- if (result !== null) {
401401- resultList = resultList.concat(result[0]);
402402-403403- if (result[1][0]) {
404404- resultList = resultList.concat(result[1][0]);
405405- }
406406-407407- return resultList;
408408- }
409409-410410- debug(' -- failed rangeList');
411411-412412- return null;
413413- }
414414-415415- function rangeTail() {
416416- // ',' range_list
417417- var result = sequence([_comma_, rangeList]);
418418-419419- if (result !== null) {
420420- return result[1];
421421- }
422422-423423- debug(' -- failed rangeTail');
424424-425425- return null;
426426- }
427427-428428- // range = value'..'value
429429- function range() {
430430- var i, array, left, right,
431431- result = sequence([value, _range_, value]);
432432-433433- if (result !== null) {
434434- debug(' -- passed range');
435435-436436- array = [];
437437- left = parseInt(result[0], 10);
438438- right = parseInt(result[2], 10);
439439-440440- for (i = left; i <= right; i++) {
441441- array.push(i);
442442- }
443443-444444- return array;
445445- }
446446-447447- debug(' -- failed range');
448448-449449- return null;
450450- }
451451-452452- function _in() {
453453- var result, range_list, i;
454454-455455- // in_relation = expr ('not')? 'in' range_list
456456- result = sequence(
457457- [expression, nOrMore(0, not), whitespace, choice([_in_, _equal_]), whitespace, rangeList]
458458- );
459459-460460- if (result !== null) {
461461- debug(' -- passed _in:' + result);
462462-463463- range_list = result[5];
464464-465465- for (i = 0; i < range_list.length; i++) {
466466- if (parseInt(range_list[i], 10) === parseFloat(result[0])) {
467467- return (result[1][0] !== 'not');
468468- }
469469- }
470470-471471- return (result[1][0] === 'not');
472472- }
473473-474474- debug(' -- failed _in ');
475475-476476- return null;
477477- }
478478-479479- /**
480480- * The difference between "in" and "within" is that
481481- * "in" only includes integers in the specified range,
482482- * while "within" includes all values.
483483- */
484484- function within() {
485485- var range_list, result;
486486-487487- // within_relation = expr ('not')? 'within' range_list
488488- result = sequence(
489489- [expression, nOrMore(0, not), whitespace, _within_, whitespace, rangeList]
490490- );
491491-492492- if (result !== null) {
493493- debug(' -- passed within');
494494-495495- range_list = result[5];
496496-497497- if ((result[0] >= parseInt(range_list[0], 10)) &&
498498- (result[0] < parseInt(range_list[range_list.length - 1], 10))) {
499499-500500- return (result[1][0] !== 'not');
501501- }
502502-503503- return (result[1][0] === 'not');
504504- }
505505-506506- debug(' -- failed within ');
507507-508508- return null;
509509- }
510510-511511- // relation = is_relation | in_relation | within_relation
512512- relation = choice([is, not_in, isnot, _in, within]);
513513-514514- // and_condition = relation ('and' relation)*
515515- function and() {
516516- var i,
517517- result = sequence([relation, nOrMore(0, andTail)]);
518518-519519- if (result) {
520520- if (!result[0]) {
521521- return false;
522522- }
523523-524524- for (i = 0; i < result[1].length; i++) {
525525- if (!result[1][i]) {
526526- return false;
527527- }
528528- }
529529-530530- return true;
531531- }
532532-533533- debug(' -- failed and');
534534-535535- return null;
536536- }
537537-538538- // ('and' relation)*
539539- function andTail() {
540540- var result = sequence([whitespace, _and_, whitespace, relation]);
541541-542542- if (result !== null) {
543543- debug(' -- passed andTail' + result);
544544-545545- return result[3];
546546- }
547547-548548- debug(' -- failed andTail');
549549-550550- return null;
551551-552552- }
553553- // ('or' and_condition)*
554554- function orTail() {
555555- var result = sequence([whitespace, _or_, whitespace, and]);
556556-557557- if (result !== null) {
558558- debug(' -- passed orTail: ' + result[3]);
559559-560560- return result[3];
561561- }
562562-563563- debug(' -- failed orTail');
564564-565565- return null;
566566- }
567567-568568- // condition = and_condition ('or' and_condition)*
569569- function condition() {
570570- var i,
571571- result = sequence([and, nOrMore(0, orTail)]);
572572-573573- if (result) {
574574- for (i = 0; i < result[1].length; i++) {
575575- if (result[1][i]) {
576576- return true;
577577- }
578578- }
579579-580580- return result[0];
581581- }
582582-583583- return false;
584584- }
585585-586586- result = condition();
587587-588588- /**
589589- * For success, the pos must have gotten to the end of the rule
590590- * and returned a non-null.
591591- * n.b. This is part of language infrastructure,
592592- * so we do not throw an internationalizable message.
593593- */
594594- if (result === null) {
595595- throw new Error('Parse error at position ' + pos.toString() + ' for rule: ' + rule);
596596- }
597597-598598- if (pos !== rule.length) {
599599- debug('Warning: Rule not parsed completely. Parser stopped at ' + rule.substr(0, pos) + ' for rule: ' + rule);
600600- }
601601-602602- return result;
603603-}
604604-605605-return pluralRuleParser;
606606-607607-}));
-95
scripts/jquery_i18n/jquery.i18n.emitter.bidi.js
···11-/*!
22- * BIDI embedding support for jQuery.i18n
33- *
44- * Copyright (C) 2015, David Chan
55- *
66- * This code is dual licensed GPLv2 or later and MIT. You don't have to do
77- * anything special to choose one license or the other and you don't have to
88- * notify anyone which license you are using. You are free to use this code
99- * in commercial projects as long as the copyright header is left intact.
1010- * See files GPL-LICENSE and MIT-LICENSE for details.
1111- *
1212- * @licence GNU General Public Licence 2.0 or later
1313- * @licence MIT License
1414- */
1515-1616-( function ( $ ) {
1717- 'use strict';
1818- var strongDirRegExp;
1919-2020- /**
2121- * Matches the first strong directionality codepoint:
2222- * - in group 1 if it is LTR
2323- * - in group 2 if it is RTL
2424- * Does not match if there is no strong directionality codepoint.
2525- *
2626- * Generated by UnicodeJS (see tools/strongDir) from the UCD; see
2727- * https://phabricator.wikimedia.org/diffusion/GUJS/ .
2828- */
2929- // eslint-disable-next-line no-misleading-character-class
3030- strongDirRegExp = new RegExp(
3131- '(?:' +
3232- '(' +
3333- '[\u0041-\u005a\u0061-\u007a\u00aa\u00b5\u00ba\u00c0-\u00d6\u00d8-\u00f6\u00f8-\u02b8\u02bb-\u02c1\u02d0\u02d1\u02e0-\u02e4\u02ee\u0370-\u0373\u0376\u0377\u037a-\u037d\u037f\u0386\u0388-\u038a\u038c\u038e-\u03a1\u03a3-\u03f5\u03f7-\u0482\u048a-\u052f\u0531-\u0556\u0559-\u055f\u0561-\u0587\u0589\u0903-\u0939\u093b\u093d-\u0940\u0949-\u094c\u094e-\u0950\u0958-\u0961\u0964-\u0980\u0982\u0983\u0985-\u098c\u098f\u0990\u0993-\u09a8\u09aa-\u09b0\u09b2\u09b6-\u09b9\u09bd-\u09c0\u09c7\u09c8\u09cb\u09cc\u09ce\u09d7\u09dc\u09dd\u09df-\u09e1\u09e6-\u09f1\u09f4-\u09fa\u0a03\u0a05-\u0a0a\u0a0f\u0a10\u0a13-\u0a28\u0a2a-\u0a30\u0a32\u0a33\u0a35\u0a36\u0a38\u0a39\u0a3e-\u0a40\u0a59-\u0a5c\u0a5e\u0a66-\u0a6f\u0a72-\u0a74\u0a83\u0a85-\u0a8d\u0a8f-\u0a91\u0a93-\u0aa8\u0aaa-\u0ab0\u0ab2\u0ab3\u0ab5-\u0ab9\u0abd-\u0ac0\u0ac9\u0acb\u0acc\u0ad0\u0ae0\u0ae1\u0ae6-\u0af0\u0af9\u0b02\u0b03\u0b05-\u0b0c\u0b0f\u0b10\u0b13-\u0b28\u0b2a-\u0b30\u0b32\u0b33\u0b35-\u0b39\u0b3d\u0b3e\u0b40\u0b47\u0b48\u0b4b\u0b4c\u0b57\u0b5c\u0b5d\u0b5f-\u0b61\u0b66-\u0b77\u0b83\u0b85-\u0b8a\u0b8e-\u0b90\u0b92-\u0b95\u0b99\u0b9a\u0b9c\u0b9e\u0b9f\u0ba3\u0ba4\u0ba8-\u0baa\u0bae-\u0bb9\u0bbe\u0bbf\u0bc1\u0bc2\u0bc6-\u0bc8\u0bca-\u0bcc\u0bd0\u0bd7\u0be6-\u0bf2\u0c01-\u0c03\u0c05-\u0c0c\u0c0e-\u0c10\u0c12-\u0c28\u0c2a-\u0c39\u0c3d\u0c41-\u0c44\u0c58-\u0c5a\u0c60\u0c61\u0c66-\u0c6f\u0c7f\u0c82\u0c83\u0c85-\u0c8c\u0c8e-\u0c90\u0c92-\u0ca8\u0caa-\u0cb3\u0cb5-\u0cb9\u0cbd-\u0cc4\u0cc6-\u0cc8\u0cca\u0ccb\u0cd5\u0cd6\u0cde\u0ce0\u0ce1\u0ce6-\u0cef\u0cf1\u0cf2\u0d02\u0d03\u0d05-\u0d0c\u0d0e-\u0d10\u0d12-\u0d3a\u0d3d-\u0d40\u0d46-\u0d48\u0d4a-\u0d4c\u0d4e\u0d57\u0d5f-\u0d61\u0d66-\u0d75\u0d79-\u0d7f\u0d82\u0d83\u0d85-\u0d96\u0d9a-\u0db1\u0db3-\u0dbb\u0dbd\u0dc0-\u0dc6\u0dcf-\u0dd1\u0dd8-\u0ddf\u0de6-\u0def\u0df2-\u0df4\u0e01-\u0e30\u0e32\u0e33\u0e40-\u0e46\u0e4f-\u0e5b\u0e81\u0e82\u0e84\u0e87\u0e88\u0e8a\u0e8d\u0e94-\u0e97\u0e99-\u0e9f\u0ea1-\u0ea3\u0ea5\u0ea7\u0eaa\u0eab\u0ead-\u0eb0\u0eb2\u0eb3\u0ebd\u0ec0-\u0ec4\u0ec6\u0ed0-\u0ed9\u0edc-\u0edf\u0f00-\u0f17\u0f1a-\u0f34\u0f36\u0f38\u0f3e-\u0f47\u0f49-\u0f6c\u0f7f\u0f85\u0f88-\u0f8c\u0fbe-\u0fc5\u0fc7-\u0fcc\u0fce-\u0fda\u1000-\u102c\u1031\u1038\u103b\u103c\u103f-\u1057\u105a-\u105d\u1061-\u1070\u1075-\u1081\u1083\u1084\u1087-\u108c\u108e-\u109c\u109e-\u10c5\u10c7\u10cd\u10d0-\u1248\u124a-\u124d\u1250-\u1256\u1258\u125a-\u125d\u1260-\u1288\u128a-\u128d\u1290-\u12b0\u12b2-\u12b5\u12b8-\u12be\u12c0\u12c2-\u12c5\u12c8-\u12d6\u12d8-\u1310\u1312-\u1315\u1318-\u135a\u1360-\u137c\u1380-\u138f\u13a0-\u13f5\u13f8-\u13fd\u1401-\u167f\u1681-\u169a\u16a0-\u16f8\u1700-\u170c\u170e-\u1711\u1720-\u1731\u1735\u1736\u1740-\u1751\u1760-\u176c\u176e-\u1770\u1780-\u17b3\u17b6\u17be-\u17c5\u17c7\u17c8\u17d4-\u17da\u17dc\u17e0-\u17e9\u1810-\u1819\u1820-\u1877\u1880-\u18a8\u18aa\u18b0-\u18f5\u1900-\u191e\u1923-\u1926\u1929-\u192b\u1930\u1931\u1933-\u1938\u1946-\u196d\u1970-\u1974\u1980-\u19ab\u19b0-\u19c9\u19d0-\u19da\u1a00-\u1a16\u1a19\u1a1a\u1a1e-\u1a55\u1a57\u1a61\u1a63\u1a64\u1a6d-\u1a72\u1a80-\u1a89\u1a90-\u1a99\u1aa0-\u1aad\u1b04-\u1b33\u1b35\u1b3b\u1b3d-\u1b41\u1b43-\u1b4b\u1b50-\u1b6a\u1b74-\u1b7c\u1b82-\u1ba1\u1ba6\u1ba7\u1baa\u1bae-\u1be5\u1be7\u1bea-\u1bec\u1bee\u1bf2\u1bf3\u1bfc-\u1c2b\u1c34\u1c35\u1c3b-\u1c49\u1c4d-\u1c7f\u1cc0-\u1cc7\u1cd3\u1ce1\u1ce9-\u1cec\u1cee-\u1cf3\u1cf5\u1cf6\u1d00-\u1dbf\u1e00-\u1f15\u1f18-\u1f1d\u1f20-\u1f45\u1f48-\u1f4d\u1f50-\u1f57\u1f59\u1f5b\u1f5d\u1f5f-\u1f7d\u1f80-\u1fb4\u1fb6-\u1fbc\u1fbe\u1fc2-\u1fc4\u1fc6-\u1fcc\u1fd0-\u1fd3\u1fd6-\u1fdb\u1fe0-\u1fec\u1ff2-\u1ff4\u1ff6-\u1ffc\u200e\u2071\u207f\u2090-\u209c\u2102\u2107\u210a-\u2113\u2115\u2119-\u211d\u2124\u2126\u2128\u212a-\u212d\u212f-\u2139\u213c-\u213f\u2145-\u2149\u214e\u214f\u2160-\u2188\u2336-\u237a\u2395\u249c-\u24e9\u26ac\u2800-\u28ff\u2c00-\u2c2e\u2c30-\u2c5e\u2c60-\u2ce4\u2ceb-\u2cee\u2cf2\u2cf3\u2d00-\u2d25\u2d27\u2d2d\u2d30-\u2d67\u2d6f\u2d70\u2d80-\u2d96\u2da0-\u2da6\u2da8-\u2dae\u2db0-\u2db6\u2db8-\u2dbe\u2dc0-\u2dc6\u2dc8-\u2dce\u2dd0-\u2dd6\u2dd8-\u2dde\u3005-\u3007\u3021-\u3029\u302e\u302f\u3031-\u3035\u3038-\u303c\u3041-\u3096\u309d-\u309f\u30a1-\u30fa\u30fc-\u30ff\u3105-\u312d\u3131-\u318e\u3190-\u31ba\u31f0-\u321c\u3220-\u324f\u3260-\u327b\u327f-\u32b0\u32c0-\u32cb\u32d0-\u32fe\u3300-\u3376\u337b-\u33dd\u33e0-\u33fe\u3400-\u4db5\u4e00-\u9fd5\ua000-\ua48c\ua4d0-\ua60c\ua610-\ua62b\ua640-\ua66e\ua680-\ua69d\ua6a0-\ua6ef\ua6f2-\ua6f7\ua722-\ua787\ua789-\ua7ad\ua7b0-\ua7b7\ua7f7-\ua801\ua803-\ua805\ua807-\ua80a\ua80c-\ua824\ua827\ua830-\ua837\ua840-\ua873\ua880-\ua8c3\ua8ce-\ua8d9\ua8f2-\ua8fd\ua900-\ua925\ua92e-\ua946\ua952\ua953\ua95f-\ua97c\ua983-\ua9b2\ua9b4\ua9b5\ua9ba\ua9bb\ua9bd-\ua9cd\ua9cf-\ua9d9\ua9de-\ua9e4\ua9e6-\ua9fe\uaa00-\uaa28\uaa2f\uaa30\uaa33\uaa34\uaa40-\uaa42\uaa44-\uaa4b\uaa4d\uaa50-\uaa59\uaa5c-\uaa7b\uaa7d-\uaaaf\uaab1\uaab5\uaab6\uaab9-\uaabd\uaac0\uaac2\uaadb-\uaaeb\uaaee-\uaaf5\uab01-\uab06\uab09-\uab0e\uab11-\uab16\uab20-\uab26\uab28-\uab2e\uab30-\uab65\uab70-\uabe4\uabe6\uabe7\uabe9-\uabec\uabf0-\uabf9\uac00-\ud7a3\ud7b0-\ud7c6\ud7cb-\ud7fb\ue000-\ufa6d\ufa70-\ufad9\ufb00-\ufb06\ufb13-\ufb17\uff21-\uff3a\uff41-\uff5a\uff66-\uffbe\uffc2-\uffc7\uffca-\uffcf\uffd2-\uffd7\uffda-\uffdc]|\ud800[\udc00-\udc0b]|\ud800[\udc0d-\udc26]|\ud800[\udc28-\udc3a]|\ud800\udc3c|\ud800\udc3d|\ud800[\udc3f-\udc4d]|\ud800[\udc50-\udc5d]|\ud800[\udc80-\udcfa]|\ud800\udd00|\ud800\udd02|\ud800[\udd07-\udd33]|\ud800[\udd37-\udd3f]|\ud800[\uddd0-\uddfc]|\ud800[\ude80-\ude9c]|\ud800[\udea0-\uded0]|\ud800[\udf00-\udf23]|\ud800[\udf30-\udf4a]|\ud800[\udf50-\udf75]|\ud800[\udf80-\udf9d]|\ud800[\udf9f-\udfc3]|\ud800[\udfc8-\udfd5]|\ud801[\udc00-\udc9d]|\ud801[\udca0-\udca9]|\ud801[\udd00-\udd27]|\ud801[\udd30-\udd63]|\ud801\udd6f|\ud801[\ude00-\udf36]|\ud801[\udf40-\udf55]|\ud801[\udf60-\udf67]|\ud804\udc00|\ud804[\udc02-\udc37]|\ud804[\udc47-\udc4d]|\ud804[\udc66-\udc6f]|\ud804[\udc82-\udcb2]|\ud804\udcb7|\ud804\udcb8|\ud804[\udcbb-\udcc1]|\ud804[\udcd0-\udce8]|\ud804[\udcf0-\udcf9]|\ud804[\udd03-\udd26]|\ud804\udd2c|\ud804[\udd36-\udd43]|\ud804[\udd50-\udd72]|\ud804[\udd74-\udd76]|\ud804[\udd82-\uddb5]|\ud804[\uddbf-\uddc9]|\ud804\uddcd|\ud804[\uddd0-\udddf]|\ud804[\udde1-\uddf4]|\ud804[\ude00-\ude11]|\ud804[\ude13-\ude2e]|\ud804\ude32|\ud804\ude33|\ud804\ude35|\ud804[\ude38-\ude3d]|\ud804[\ude80-\ude86]|\ud804\ude88|\ud804[\ude8a-\ude8d]|\ud804[\ude8f-\ude9d]|\ud804[\ude9f-\udea9]|\ud804[\udeb0-\udede]|\ud804[\udee0-\udee2]|\ud804[\udef0-\udef9]|\ud804\udf02|\ud804\udf03|\ud804[\udf05-\udf0c]|\ud804\udf0f|\ud804\udf10|\ud804[\udf13-\udf28]|\ud804[\udf2a-\udf30]|\ud804\udf32|\ud804\udf33|\ud804[\udf35-\udf39]|\ud804[\udf3d-\udf3f]|\ud804[\udf41-\udf44]|\ud804\udf47|\ud804\udf48|\ud804[\udf4b-\udf4d]|\ud804\udf50|\ud804\udf57|\ud804[\udf5d-\udf63]|\ud805[\udc80-\udcb2]|\ud805\udcb9|\ud805[\udcbb-\udcbe]|\ud805\udcc1|\ud805[\udcc4-\udcc7]|\ud805[\udcd0-\udcd9]|\ud805[\udd80-\uddb1]|\ud805[\uddb8-\uddbb]|\ud805\uddbe|\ud805[\uddc1-\udddb]|\ud805[\ude00-\ude32]|\ud805\ude3b|\ud805\ude3c|\ud805\ude3e|\ud805[\ude41-\ude44]|\ud805[\ude50-\ude59]|\ud805[\ude80-\udeaa]|\ud805\udeac|\ud805\udeae|\ud805\udeaf|\ud805\udeb6|\ud805[\udec0-\udec9]|\ud805[\udf00-\udf19]|\ud805\udf20|\ud805\udf21|\ud805\udf26|\ud805[\udf30-\udf3f]|\ud806[\udca0-\udcf2]|\ud806\udcff|\ud806[\udec0-\udef8]|\ud808[\udc00-\udf99]|\ud809[\udc00-\udc6e]|\ud809[\udc70-\udc74]|\ud809[\udc80-\udd43]|\ud80c[\udc00-\udfff]|\ud80d[\udc00-\udc2e]|\ud811[\udc00-\ude46]|\ud81a[\udc00-\ude38]|\ud81a[\ude40-\ude5e]|\ud81a[\ude60-\ude69]|\ud81a\ude6e|\ud81a\ude6f|\ud81a[\uded0-\udeed]|\ud81a\udef5|\ud81a[\udf00-\udf2f]|\ud81a[\udf37-\udf45]|\ud81a[\udf50-\udf59]|\ud81a[\udf5b-\udf61]|\ud81a[\udf63-\udf77]|\ud81a[\udf7d-\udf8f]|\ud81b[\udf00-\udf44]|\ud81b[\udf50-\udf7e]|\ud81b[\udf93-\udf9f]|\ud82c\udc00|\ud82c\udc01|\ud82f[\udc00-\udc6a]|\ud82f[\udc70-\udc7c]|\ud82f[\udc80-\udc88]|\ud82f[\udc90-\udc99]|\ud82f\udc9c|\ud82f\udc9f|\ud834[\udc00-\udcf5]|\ud834[\udd00-\udd26]|\ud834[\udd29-\udd66]|\ud834[\udd6a-\udd72]|\ud834\udd83|\ud834\udd84|\ud834[\udd8c-\udda9]|\ud834[\uddae-\udde8]|\ud834[\udf60-\udf71]|\ud835[\udc00-\udc54]|\ud835[\udc56-\udc9c]|\ud835\udc9e|\ud835\udc9f|\ud835\udca2|\ud835\udca5|\ud835\udca6|\ud835[\udca9-\udcac]|\ud835[\udcae-\udcb9]|\ud835\udcbb|\ud835[\udcbd-\udcc3]|\ud835[\udcc5-\udd05]|\ud835[\udd07-\udd0a]|\ud835[\udd0d-\udd14]|\ud835[\udd16-\udd1c]|\ud835[\udd1e-\udd39]|\ud835[\udd3b-\udd3e]|\ud835[\udd40-\udd44]|\ud835\udd46|\ud835[\udd4a-\udd50]|\ud835[\udd52-\udea5]|\ud835[\udea8-\udeda]|\ud835[\udedc-\udf14]|\ud835[\udf16-\udf4e]|\ud835[\udf50-\udf88]|\ud835[\udf8a-\udfc2]|\ud835[\udfc4-\udfcb]|\ud836[\udc00-\uddff]|\ud836[\ude37-\ude3a]|\ud836[\ude6d-\ude74]|\ud836[\ude76-\ude83]|\ud836[\ude85-\ude8b]|\ud83c[\udd10-\udd2e]|\ud83c[\udd30-\udd69]|\ud83c[\udd70-\udd9a]|\ud83c[\udde6-\ude02]|\ud83c[\ude10-\ude3a]|\ud83c[\ude40-\ude48]|\ud83c\ude50|\ud83c\ude51|[\ud840-\ud868][\udc00-\udfff]|\ud869[\udc00-\uded6]|\ud869[\udf00-\udfff]|[\ud86a-\ud86c][\udc00-\udfff]|\ud86d[\udc00-\udf34]|\ud86d[\udf40-\udfff]|\ud86e[\udc00-\udc1d]|\ud86e[\udc20-\udfff]|[\ud86f-\ud872][\udc00-\udfff]|\ud873[\udc00-\udea1]|\ud87e[\udc00-\ude1d]|[\udb80-\udbbe][\udc00-\udfff]|\udbbf[\udc00-\udffd]|[\udbc0-\udbfe][\udc00-\udfff]|\udbff[\udc00-\udffd]' +
3434- ')|(' +
3535- '[\u0590\u05be\u05c0\u05c3\u05c6\u05c8-\u05ff\u07c0-\u07ea\u07f4\u07f5\u07fa-\u0815\u081a\u0824\u0828\u082e-\u0858\u085c-\u089f\u200f\ufb1d\ufb1f-\ufb28\ufb2a-\ufb4f\u0608\u060b\u060d\u061b-\u064a\u066d-\u066f\u0671-\u06d5\u06e5\u06e6\u06ee\u06ef\u06fa-\u0710\u0712-\u072f\u074b-\u07a5\u07b1-\u07bf\u08a0-\u08e2\ufb50-\ufd3d\ufd40-\ufdcf\ufdf0-\ufdfc\ufdfe\ufdff\ufe70-\ufefe]|\ud802[\udc00-\udd1e]|\ud802[\udd20-\ude00]|\ud802\ude04|\ud802[\ude07-\ude0b]|\ud802[\ude10-\ude37]|\ud802[\ude3b-\ude3e]|\ud802[\ude40-\udee4]|\ud802[\udee7-\udf38]|\ud802[\udf40-\udfff]|\ud803[\udc00-\ude5f]|\ud803[\ude7f-\udfff]|\ud83a[\udc00-\udccf]|\ud83a[\udcd7-\udfff]|\ud83b[\udc00-\uddff]|\ud83b[\udf00-\udfff]|\ud83b[\udf00-\udfff]|\ud83b[\udf00-\udfff]|\ud83b[\udf00-\udfff]|\ud83b[\udf00-\udfff]|\ud83b[\udf00-\udfff]|\ud83b[\udf00-\udfff]|\ud83b[\udf00-\udfff]|\ud83b[\udf00-\udfff]|\ud83b[\udf00-\udfff]|\ud83b[\udf00-\udfff]|\ud83b[\udf00-\udfff]|\ud83b[\udf00-\udfff]|\ud83b[\ude00-\udeef]|\ud83b[\udef2-\udeff]' +
3636- ')' +
3737- ')'
3838- );
3939-4040- /**
4141- * Gets directionality of the first strongly directional codepoint
4242- *
4343- * This is the rule the BIDI algorithm uses to determine the directionality of
4444- * paragraphs ( http://unicode.org/reports/tr9/#The_Paragraph_Level ) and
4545- * FSI isolates ( http://unicode.org/reports/tr9/#Explicit_Directional_Isolates ).
4646- *
4747- * TODO: Does not handle BIDI control characters inside the text.
4848- * TODO: Does not handle unallocated characters.
4949- *
5050- * @param {string} text The text from which to extract initial directionality.
5151- * @return {string} Directionality (either 'ltr' or 'rtl')
5252- */
5353- function strongDirFromContent( text ) {
5454- var m = text.match( strongDirRegExp );
5555- if ( !m ) {
5656- return null;
5757- }
5858- if ( m[ 2 ] === undefined ) {
5959- return 'ltr';
6060- }
6161- return 'rtl';
6262- }
6363-6464- $.extend( $.i18n.parser.emitter, {
6565- /**
6666- * Wraps argument with unicode control characters for directionality safety
6767- *
6868- * This solves the problem where directionality-neutral characters at the edge of
6969- * the argument string get interpreted with the wrong directionality from the
7070- * enclosing context, giving renderings that look corrupted like "(Ben_(WMF".
7171- *
7272- * The wrapping is LRE...PDF or RLE...PDF, depending on the detected
7373- * directionality of the argument string, using the BIDI algorithm's own "First
7474- * strong directional codepoint" rule. Essentially, this works round the fact that
7575- * there is no embedding equivalent of U+2068 FSI (isolation with heuristic
7676- * direction inference). The latter is cleaner but still not widely supported.
7777- *
7878- * @param {string[]} nodes The text nodes from which to take the first item.
7979- * @return {string} Wrapped String of content as needed.
8080- */
8181- bidi: function ( nodes ) {
8282- var dir = strongDirFromContent( nodes[ 0 ] );
8383- if ( dir === 'ltr' ) {
8484- // Wrap in LEFT-TO-RIGHT EMBEDDING ... POP DIRECTIONAL FORMATTING
8585- return '\u202A' + nodes[ 0 ] + '\u202C';
8686- }
8787- if ( dir === 'rtl' ) {
8888- // Wrap in RIGHT-TO-LEFT EMBEDDING ... POP DIRECTIONAL FORMATTING
8989- return '\u202B' + nodes[ 0 ] + '\u202C';
9090- }
9191- // No strong directionality: do not wrap
9292- return nodes[ 0 ];
9393- }
9494- } );
9595-}( jQuery ) );
-168
scripts/jquery_i18n/jquery.i18n.emitter.js
···11-/*!
22- * jQuery Internationalization library
33- *
44- * Copyright (C) 2011-2013 Santhosh Thottingal, Neil Kandalgaonkar
55- *
66- * jquery.i18n is dual licensed GPLv2 or later and MIT. You don't have to do
77- * anything special to choose one license or the other and you don't have to
88- * notify anyone which license you are using. You are free to use
99- * UniversalLanguageSelector in commercial projects as long as the copyright
1010- * header is left intact. See files GPL-LICENSE and MIT-LICENSE for details.
1111- *
1212- * @licence GNU General Public Licence 2.0 or later
1313- * @licence MIT License
1414- */
1515-1616-( function ( $ ) {
1717- 'use strict';
1818-1919- var MessageParserEmitter = function () {
2020- this.language = $.i18n.languages[ String.locale ] || $.i18n.languages[ 'default' ];
2121- };
2222-2323- MessageParserEmitter.prototype = {
2424- constructor: MessageParserEmitter,
2525-2626- /**
2727- * (We put this method definition here, and not in prototype, to make
2828- * sure it's not overwritten by any magic.) Walk entire node structure,
2929- * applying replacements and template functions when appropriate
3030- *
3131- * @param {Mixed} node abstract syntax tree (top node or subnode)
3232- * @param {Array} replacements for $1, $2, ... $n
3333- * @return {Mixed} single-string node or array of nodes suitable for
3434- * jQuery appending.
3535- */
3636- emit: function ( node, replacements ) {
3737- var ret, subnodes, operation,
3838- messageParserEmitter = this;
3939-4040- switch ( typeof node ) {
4141- case 'string':
4242- case 'number':
4343- ret = node;
4444- break;
4545- case 'object':
4646- // node is an array of nodes
4747- subnodes = $.map( node.slice( 1 ), function ( n ) {
4848- return messageParserEmitter.emit( n, replacements );
4949- } );
5050-5151- operation = node[ 0 ].toLowerCase();
5252-5353- if ( typeof messageParserEmitter[ operation ] === 'function' ) {
5454- ret = messageParserEmitter[ operation ]( subnodes, replacements );
5555- } else {
5656- throw new Error( 'unknown operation "' + operation + '"' );
5757- }
5858-5959- break;
6060- case 'undefined':
6161- // Parsing the empty string (as an entire expression, or as a
6262- // paramExpression in a template) results in undefined
6363- // Perhaps a more clever parser can detect this, and return the
6464- // empty string? Or is that useful information?
6565- // The logical thing is probably to return the empty string here
6666- // when we encounter undefined.
6767- ret = '';
6868- break;
6969- default:
7070- throw new Error( 'unexpected type in AST: ' + typeof node );
7171- }
7272-7373- return ret;
7474- },
7575-7676- /**
7777- * Parsing has been applied depth-first we can assume that all nodes
7878- * here are single nodes Must return a single node to parents -- a
7979- * jQuery with synthetic span However, unwrap any other synthetic spans
8080- * in our children and pass them upwards
8181- *
8282- * @param {Array} nodes Mixed, some single nodes, some arrays of nodes.
8383- * @return {string}
8484- */
8585- concat: function ( nodes ) {
8686- var result = '';
8787-8888- $.each( nodes, function ( i, node ) {
8989- // strings, integers, anything else
9090- result += node;
9191- } );
9292-9393- return result;
9494- },
9595-9696- /**
9797- * Return escaped replacement of correct index, or string if
9898- * unavailable. Note that we expect the parsed parameter to be
9999- * zero-based. i.e. $1 should have become [ 0 ]. if the specified
100100- * parameter is not found return the same string (e.g. "$99" ->
101101- * parameter 98 -> not found -> return "$99" ) TODO throw error if
102102- * nodes.length > 1 ?
103103- *
104104- * @param {Array} nodes One element, integer, n >= 0
105105- * @param {Array} replacements for $1, $2, ... $n
106106- * @return {string} replacement
107107- */
108108- replace: function ( nodes, replacements ) {
109109- var index = parseInt( nodes[ 0 ], 10 );
110110-111111- if ( index < replacements.length ) {
112112- // replacement is not a string, don't touch!
113113- return replacements[ index ];
114114- } else {
115115- // index not found, fallback to displaying variable
116116- return '$' + ( index + 1 );
117117- }
118118- },
119119-120120- /**
121121- * Transform parsed structure into pluralization n.b. The first node may
122122- * be a non-integer (for instance, a string representing an Arabic
123123- * number). So convert it back with the current language's
124124- * convertNumber.
125125- *
126126- * @param {Array} nodes List [ {String|Number}, {String}, {String} ... ]
127127- * @return {string} selected pluralized form according to current
128128- * language.
129129- */
130130- plural: function ( nodes ) {
131131- var count = parseFloat( this.language.convertNumber( nodes[ 0 ], 10 ) ),
132132- forms = nodes.slice( 1 );
133133-134134- return forms.length ? this.language.convertPlural( count, forms ) : '';
135135- },
136136-137137- /**
138138- * Transform parsed structure into gender Usage
139139- * {{gender:gender|masculine|feminine|neutral}}.
140140- *
141141- * @param {Array} nodes List [ {String}, {String}, {String} , {String} ]
142142- * @return {string} selected gender form according to current language
143143- */
144144- gender: function ( nodes ) {
145145- var gender = nodes[ 0 ],
146146- forms = nodes.slice( 1 );
147147-148148- return this.language.gender( gender, forms );
149149- },
150150-151151- /**
152152- * Transform parsed structure into grammar conversion. Invoked by
153153- * putting {{grammar:form|word}} in a message
154154- *
155155- * @param {Array} nodes List [{Grammar case eg: genitive}, {String word}]
156156- * @return {string} selected grammatical form according to current
157157- * language.
158158- */
159159- grammar: function ( nodes ) {
160160- var form = nodes[ 0 ],
161161- word = nodes[ 1 ];
162162-163163- return word && form && this.language.convertGrammar( word, form );
164164- }
165165- };
166166-167167- $.extend( $.i18n.parser.emitter, new MessageParserEmitter() );
168168-}( jQuery ) );
···11-/*!
22- * jQuery Internationalization library
33- *
44- * Copyright (C) 2012 Santhosh Thottingal
55- *
66- * jquery.i18n is dual licensed GPLv2 or later and MIT. You don't have to do
77- * anything special to choose one license or the other and you don't have to
88- * notify anyone which license you are using. You are free to use
99- * UniversalLanguageSelector in commercial projects as long as the copyright
1010- * header is left intact. See files GPL-LICENSE and MIT-LICENSE for details.
1111- *
1212- * @licence GNU General Public Licence 2.0 or later
1313- * @licence MIT License
1414- */
1515-1616-( function ( $ ) {
1717- 'use strict';
1818-1919- var I18N,
2020- slice = Array.prototype.slice;
2121- /**
2222- * @constructor
2323- * @param {Object} options
2424- */
2525- I18N = function ( options ) {
2626- // Load defaults
2727- this.options = $.extend( {}, I18N.defaults, options );
2828-2929- this.parser = this.options.parser;
3030- this.locale = this.options.locale;
3131- this.messageStore = this.options.messageStore;
3232- this.languages = {};
3333- };
3434-3535- I18N.prototype = {
3636- /**
3737- * Localize a given messageKey to a locale.
3838- * @param {string} messageKey
3939- * @return {string} Localized message
4040- */
4141- localize: function ( messageKey ) {
4242- var localeParts, localePartIndex, locale, fallbackIndex,
4343- tryingLocale, message;
4444-4545- locale = this.locale;
4646- fallbackIndex = 0;
4747-4848- while ( locale ) {
4949- // Iterate through locales starting at most-specific until
5050- // localization is found. As in fi-Latn-FI, fi-Latn and fi.
5151- localeParts = locale.split( '-' );
5252- localePartIndex = localeParts.length;
5353-5454- do {
5555- tryingLocale = localeParts.slice( 0, localePartIndex ).join( '-' );
5656- message = this.messageStore.get( tryingLocale, messageKey );
5757-5858- if ( message ) {
5959- return message;
6060- }
6161-6262- localePartIndex--;
6363- } while ( localePartIndex );
6464-6565- if ( locale === this.options.fallbackLocale ) {
6666- break;
6767- }
6868-6969- locale = ( $.i18n.fallbacks[ this.locale ] &&
7070- $.i18n.fallbacks[ this.locale ][ fallbackIndex ] ) ||
7171- this.options.fallbackLocale;
7272- $.i18n.log( 'Trying fallback locale for ' + this.locale + ': ' + locale + ' (' + messageKey + ')' );
7373-7474- fallbackIndex++;
7575- }
7676-7777- // key not found
7878- return '';
7979- },
8080-8181- /*
8282- * Destroy the i18n instance.
8383- */
8484- destroy: function () {
8585- $.removeData( document, 'i18n' );
8686- },
8787-8888- /**
8989- * General message loading API This can take a URL string for
9090- * the json formatted messages. Example:
9191- * <code>load('path/to/all_localizations.json');</code>
9292- *
9393- * To load a localization file for a locale:
9494- * <code>
9595- * load('path/to/de-messages.json', 'de' );
9696- * </code>
9797- *
9898- * To load a localization file from a directory:
9999- * <code>
100100- * load('path/to/i18n/directory', 'de' );
101101- * </code>
102102- * The above method has the advantage of fallback resolution.
103103- * ie, it will automatically load the fallback locales for de.
104104- * For most usecases, this is the recommended method.
105105- * It is optional to have trailing slash at end.
106106- *
107107- * A data object containing message key- message translation mappings
108108- * can also be passed. Example:
109109- * <code>
110110- * load( { 'hello' : 'Hello' }, optionalLocale );
111111- * </code>
112112- *
113113- * A source map containing key-value pair of languagename and locations
114114- * can also be passed. Example:
115115- * <code>
116116- * load( {
117117- * bn: 'i18n/bn.json',
118118- * he: 'i18n/he.json',
119119- * en: 'i18n/en.json'
120120- * } )
121121- * </code>
122122- *
123123- * If the data argument is null/undefined/false,
124124- * all cached messages for the i18n instance will get reset.
125125- *
126126- * @param {string|Object} source
127127- * @param {string} locale Language tag
128128- * @return {jQuery.Promise}
129129- */
130130- load: function ( source, locale ) {
131131- var fallbackLocales, locIndex, fallbackLocale, sourceMap = {};
132132- if ( !source && !locale ) {
133133- source = 'i18n/' + $.i18n().locale + '.json';
134134- locale = $.i18n().locale;
135135- }
136136- if ( typeof source === 'string' &&
137137- // source extension should be json, but can have query params after that.
138138- source.split( '?' )[ 0 ].split( '.' ).pop() !== 'json'
139139- ) {
140140- // Load specified locale then check for fallbacks when directory is
141141- // specified in load()
142142- sourceMap[ locale ] = source + '/' + locale + '.json';
143143- fallbackLocales = ( $.i18n.fallbacks[ locale ] || [] )
144144- .concat( this.options.fallbackLocale );
145145- for ( locIndex = 0; locIndex < fallbackLocales.length; locIndex++ ) {
146146- fallbackLocale = fallbackLocales[ locIndex ];
147147- sourceMap[ fallbackLocale ] = source + '/' + fallbackLocale + '.json';
148148- }
149149- return this.load( sourceMap );
150150- } else {
151151- return this.messageStore.load( source, locale );
152152- }
153153-154154- },
155155-156156- /**
157157- * Does parameter and magic word substitution.
158158- *
159159- * @param {string} key Message key
160160- * @param {Array} parameters Message parameters
161161- * @return {string}
162162- */
163163- parse: function ( key, parameters ) {
164164- var message = this.localize( key );
165165- // FIXME: This changes the state of the I18N object,
166166- // should probably not change the 'this.parser' but just
167167- // pass it to the parser.
168168- this.parser.language = $.i18n.languages[ $.i18n().locale ] || $.i18n.languages[ 'default' ];
169169- if ( message === '' ) {
170170- message = key;
171171- }
172172- return this.parser.parse( message, parameters );
173173- }
174174- };
175175-176176- /**
177177- * Process a message from the $.I18N instance
178178- * for the current document, stored in jQuery.data(document).
179179- *
180180- * @param {string} key Key of the message.
181181- * @param {string} param1 [param...] Variadic list of parameters for {key}.
182182- * @return {string|$.I18N} Parsed message, or if no key was given
183183- * the instance of $.I18N is returned.
184184- */
185185- $.i18n = function ( key, param1 ) {
186186- var parameters,
187187- i18n = $.data( document, 'i18n' ),
188188- options = typeof key === 'object' && key;
189189-190190- // If the locale option for this call is different then the setup so far,
191191- // update it automatically. This doesn't just change the context for this
192192- // call but for all future call as well.
193193- // If there is no i18n setup yet, don't do this. It will be taken care of
194194- // by the `new I18N` construction below.
195195- // NOTE: It should only change language for this one call.
196196- // Then cache instances of I18N somewhere.
197197- if ( options && options.locale && i18n && i18n.locale !== options.locale ) {
198198- i18n.locale = options.locale;
199199- }
200200-201201- if ( !i18n ) {
202202- i18n = new I18N( options );
203203- $.data( document, 'i18n', i18n );
204204- }
205205-206206- if ( typeof key === 'string' ) {
207207- if ( param1 !== undefined ) {
208208- parameters = slice.call( arguments, 1 );
209209- } else {
210210- parameters = [];
211211- }
212212-213213- return i18n.parse( key, parameters );
214214- } else {
215215- // FIXME: remove this feature/bug.
216216- return i18n;
217217- }
218218- };
219219-220220- $.fn.i18n = function () {
221221- var i18n = $.data( document, 'i18n' );
222222-223223- if ( !i18n ) {
224224- i18n = new I18N();
225225- $.data( document, 'i18n', i18n );
226226- }
227227-228228- return this.each( function () {
229229- var $this = $( this ),
230230- messageKey = $this.data( 'i18n' ),
231231- lBracket, rBracket, type, key;
232232-233233- if ( messageKey ) {
234234- lBracket = messageKey.indexOf( '[' );
235235- rBracket = messageKey.indexOf( ']' );
236236- if ( lBracket !== -1 && rBracket !== -1 && lBracket < rBracket ) {
237237- type = messageKey.slice( lBracket + 1, rBracket );
238238- key = messageKey.slice( rBracket + 1 );
239239- if ( type === 'html' ) {
240240- $this.html( i18n.parse( key ) );
241241- } else {
242242- $this.attr( type, i18n.parse( key ) );
243243- }
244244- } else {
245245- $this.text( i18n.parse( messageKey ) );
246246- }
247247- } else {
248248- $this.find( '[data-i18n]' ).i18n();
249249- }
250250- } );
251251- };
252252-253253- function getDefaultLocale() {
254254- var locale = $( 'html' ).attr( 'lang' );
255255- if ( !locale ) {
256256- locale = navigator.language || navigator.userLanguage || '';
257257- }
258258- return locale;
259259- }
260260-261261- $.i18n.languages = {};
262262- $.i18n.messageStore = $.i18n.messageStore || {};
263263- $.i18n.parser = {
264264- // The default parser only handles variable substitution
265265- parse: function ( message, parameters ) {
266266- return message.replace( /\$(\d+)/g, function ( str, match ) {
267267- var index = parseInt( match, 10 ) - 1;
268268- return parameters[ index ] !== undefined ? parameters[ index ] : '$' + match;
269269- } );
270270- },
271271- emitter: {}
272272- };
273273- $.i18n.fallbacks = {};
274274- $.i18n.debug = false;
275275- $.i18n.log = function ( /* arguments */ ) {
276276- if ( window.console && $.i18n.debug ) {
277277- window.console.log.apply( window.console, arguments );
278278- }
279279- };
280280- /* Static members */
281281- I18N.defaults = {
282282- locale: getDefaultLocale(),
283283- fallbackLocale: 'en',
284284- parser: $.i18n.parser,
285285- messageStore: $.i18n.messageStore
286286- };
287287-288288- // Expose constructor
289289- $.i18n.constructor = I18N;
290290-}( jQuery ) );
-499
scripts/jquery_i18n/jquery.i18n.language.js
···11-/* global pluralRuleParser */
22-( function ( $ ) {
33- 'use strict';
44-55- // jscs:disable
66- var language = {
77- // CLDR plural rules generated using
88- // libs/CLDRPluralRuleParser/tools/PluralXML2JSON.html
99- pluralRules: {
1010- ak: {
1111- one: 'n = 0..1'
1212- },
1313- am: {
1414- one: 'i = 0 or n = 1'
1515- },
1616- ar: {
1717- zero: 'n = 0',
1818- one: 'n = 1',
1919- two: 'n = 2',
2020- few: 'n % 100 = 3..10',
2121- many: 'n % 100 = 11..99'
2222- },
2323- ars: {
2424- zero: 'n = 0',
2525- one: 'n = 1',
2626- two: 'n = 2',
2727- few: 'n % 100 = 3..10',
2828- many: 'n % 100 = 11..99'
2929- },
3030- as: {
3131- one: 'i = 0 or n = 1'
3232- },
3333- be: {
3434- one: 'n % 10 = 1 and n % 100 != 11',
3535- few: 'n % 10 = 2..4 and n % 100 != 12..14',
3636- many: 'n % 10 = 0 or n % 10 = 5..9 or n % 100 = 11..14'
3737- },
3838- bh: {
3939- one: 'n = 0..1'
4040- },
4141- bn: {
4242- one: 'i = 0 or n = 1'
4343- },
4444- br: {
4545- one: 'n % 10 = 1 and n % 100 != 11,71,91',
4646- two: 'n % 10 = 2 and n % 100 != 12,72,92',
4747- few: 'n % 10 = 3..4,9 and n % 100 != 10..19,70..79,90..99',
4848- many: 'n != 0 and n % 1000000 = 0'
4949- },
5050- bs: {
5151- one: 'v = 0 and i % 10 = 1 and i % 100 != 11 or f % 10 = 1 and f % 100 != 11',
5252- few: 'v = 0 and i % 10 = 2..4 and i % 100 != 12..14 or f % 10 = 2..4 and f % 100 != 12..14'
5353- },
5454- cs: {
5555- one: 'i = 1 and v = 0',
5656- few: 'i = 2..4 and v = 0',
5757- many: 'v != 0'
5858- },
5959- cy: {
6060- zero: 'n = 0',
6161- one: 'n = 1',
6262- two: 'n = 2',
6363- few: 'n = 3',
6464- many: 'n = 6'
6565- },
6666- da: {
6767- one: 'n = 1 or t != 0 and i = 0,1'
6868- },
6969- dsb: {
7070- one: 'v = 0 and i % 100 = 1 or f % 100 = 1',
7171- two: 'v = 0 and i % 100 = 2 or f % 100 = 2',
7272- few: 'v = 0 and i % 100 = 3..4 or f % 100 = 3..4'
7373- },
7474- fa: {
7575- one: 'i = 0 or n = 1'
7676- },
7777- ff: {
7878- one: 'i = 0,1'
7979- },
8080- fil: {
8181- one: 'v = 0 and i = 1,2,3 or v = 0 and i % 10 != 4,6,9 or v != 0 and f % 10 != 4,6,9'
8282- },
8383- fr: {
8484- one: 'i = 0,1'
8585- },
8686- ga: {
8787- one: 'n = 1',
8888- two: 'n = 2',
8989- few: 'n = 3..6',
9090- many: 'n = 7..10'
9191- },
9292- gd: {
9393- one: 'n = 1,11',
9494- two: 'n = 2,12',
9595- few: 'n = 3..10,13..19'
9696- },
9797- gu: {
9898- one: 'i = 0 or n = 1'
9999- },
100100- guw: {
101101- one: 'n = 0..1'
102102- },
103103- gv: {
104104- one: 'v = 0 and i % 10 = 1',
105105- two: 'v = 0 and i % 10 = 2',
106106- few: 'v = 0 and i % 100 = 0,20,40,60,80',
107107- many: 'v != 0'
108108- },
109109- he: {
110110- one: 'i = 1 and v = 0',
111111- two: 'i = 2 and v = 0',
112112- many: 'v = 0 and n != 0..10 and n % 10 = 0'
113113- },
114114- hi: {
115115- one: 'i = 0 or n = 1'
116116- },
117117- hr: {
118118- one: 'v = 0 and i % 10 = 1 and i % 100 != 11 or f % 10 = 1 and f % 100 != 11',
119119- few: 'v = 0 and i % 10 = 2..4 and i % 100 != 12..14 or f % 10 = 2..4 and f % 100 != 12..14'
120120- },
121121- hsb: {
122122- one: 'v = 0 and i % 100 = 1 or f % 100 = 1',
123123- two: 'v = 0 and i % 100 = 2 or f % 100 = 2',
124124- few: 'v = 0 and i % 100 = 3..4 or f % 100 = 3..4'
125125- },
126126- hy: {
127127- one: 'i = 0,1'
128128- },
129129- is: {
130130- one: 't = 0 and i % 10 = 1 and i % 100 != 11 or t != 0'
131131- },
132132- iu: {
133133- one: 'n = 1',
134134- two: 'n = 2'
135135- },
136136- iw: {
137137- one: 'i = 1 and v = 0',
138138- two: 'i = 2 and v = 0',
139139- many: 'v = 0 and n != 0..10 and n % 10 = 0'
140140- },
141141- kab: {
142142- one: 'i = 0,1'
143143- },
144144- kn: {
145145- one: 'i = 0 or n = 1'
146146- },
147147- kw: {
148148- one: 'n = 1',
149149- two: 'n = 2'
150150- },
151151- lag: {
152152- zero: 'n = 0',
153153- one: 'i = 0,1 and n != 0'
154154- },
155155- ln: {
156156- one: 'n = 0..1'
157157- },
158158- lt: {
159159- one: 'n % 10 = 1 and n % 100 != 11..19',
160160- few: 'n % 10 = 2..9 and n % 100 != 11..19',
161161- many: 'f != 0'
162162- },
163163- lv: {
164164- zero: 'n % 10 = 0 or n % 100 = 11..19 or v = 2 and f % 100 = 11..19',
165165- one: 'n % 10 = 1 and n % 100 != 11 or v = 2 and f % 10 = 1 and f % 100 != 11 or v != 2 and f % 10 = 1'
166166- },
167167- mg: {
168168- one: 'n = 0..1'
169169- },
170170- mk: {
171171- one: 'v = 0 and i % 10 = 1 or f % 10 = 1'
172172- },
173173- mo: {
174174- one: 'i = 1 and v = 0',
175175- few: 'v != 0 or n = 0 or n != 1 and n % 100 = 1..19'
176176- },
177177- mr: {
178178- one: 'i = 0 or n = 1'
179179- },
180180- mt: {
181181- one: 'n = 1',
182182- few: 'n = 0 or n % 100 = 2..10',
183183- many: 'n % 100 = 11..19'
184184- },
185185- naq: {
186186- one: 'n = 1',
187187- two: 'n = 2'
188188- },
189189- nso: {
190190- one: 'n = 0..1'
191191- },
192192- pa: {
193193- one: 'n = 0..1'
194194- },
195195- pl: {
196196- one: 'i = 1 and v = 0',
197197- few: 'v = 0 and i % 10 = 2..4 and i % 100 != 12..14',
198198- many: 'v = 0 and i != 1 and i % 10 = 0..1 or v = 0 and i % 10 = 5..9 or v = 0 and i % 100 = 12..14'
199199- },
200200- prg: {
201201- zero: 'n % 10 = 0 or n % 100 = 11..19 or v = 2 and f % 100 = 11..19',
202202- one: 'n % 10 = 1 and n % 100 != 11 or v = 2 and f % 10 = 1 and f % 100 != 11 or v != 2 and f % 10 = 1'
203203- },
204204- pt: {
205205- one: 'i = 0..1'
206206- },
207207- ro: {
208208- one: 'i = 1 and v = 0',
209209- few: 'v != 0 or n = 0 or n != 1 and n % 100 = 1..19'
210210- },
211211- ru: {
212212- one: 'v = 0 and i % 10 = 1 and i % 100 != 11',
213213- few: 'v = 0 and i % 10 = 2..4 and i % 100 != 12..14',
214214- many: 'v = 0 and i % 10 = 0 or v = 0 and i % 10 = 5..9 or v = 0 and i % 100 = 11..14'
215215- },
216216- se: {
217217- one: 'n = 1',
218218- two: 'n = 2'
219219- },
220220- sh: {
221221- one: 'v = 0 and i % 10 = 1 and i % 100 != 11 or f % 10 = 1 and f % 100 != 11',
222222- few: 'v = 0 and i % 10 = 2..4 and i % 100 != 12..14 or f % 10 = 2..4 and f % 100 != 12..14'
223223- },
224224- shi: {
225225- one: 'i = 0 or n = 1',
226226- few: 'n = 2..10'
227227- },
228228- si: {
229229- one: 'n = 0,1 or i = 0 and f = 1'
230230- },
231231- sk: {
232232- one: 'i = 1 and v = 0',
233233- few: 'i = 2..4 and v = 0',
234234- many: 'v != 0'
235235- },
236236- sl: {
237237- one: 'v = 0 and i % 100 = 1',
238238- two: 'v = 0 and i % 100 = 2',
239239- few: 'v = 0 and i % 100 = 3..4 or v != 0'
240240- },
241241- sma: {
242242- one: 'n = 1',
243243- two: 'n = 2'
244244- },
245245- smi: {
246246- one: 'n = 1',
247247- two: 'n = 2'
248248- },
249249- smj: {
250250- one: 'n = 1',
251251- two: 'n = 2'
252252- },
253253- smn: {
254254- one: 'n = 1',
255255- two: 'n = 2'
256256- },
257257- sms: {
258258- one: 'n = 1',
259259- two: 'n = 2'
260260- },
261261- sr: {
262262- one: 'v = 0 and i % 10 = 1 and i % 100 != 11 or f % 10 = 1 and f % 100 != 11',
263263- few: 'v = 0 and i % 10 = 2..4 and i % 100 != 12..14 or f % 10 = 2..4 and f % 100 != 12..14'
264264- },
265265- ti: {
266266- one: 'n = 0..1'
267267- },
268268- tl: {
269269- one: 'v = 0 and i = 1,2,3 or v = 0 and i % 10 != 4,6,9 or v != 0 and f % 10 != 4,6,9'
270270- },
271271- tzm: {
272272- one: 'n = 0..1 or n = 11..99'
273273- },
274274- uk: {
275275- one: 'v = 0 and i % 10 = 1 and i % 100 != 11',
276276- few: 'v = 0 and i % 10 = 2..4 and i % 100 != 12..14',
277277- many: 'v = 0 and i % 10 = 0 or v = 0 and i % 10 = 5..9 or v = 0 and i % 100 = 11..14'
278278- },
279279- wa: {
280280- one: 'n = 0..1'
281281- },
282282- zu: {
283283- one: 'i = 0 or n = 1'
284284- }
285285- },
286286- // jscs:enable
287287-288288- /**
289289- * Plural form transformations, needed for some languages.
290290- *
291291- * @param {integer} count
292292- * Non-localized quantifier
293293- * @param {Array} forms
294294- * List of plural forms
295295- * @return {string} Correct form for quantifier in this language
296296- */
297297- convertPlural: function ( count, forms ) {
298298- var pluralRules,
299299- pluralFormIndex,
300300- index,
301301- explicitPluralPattern = /\d+=/i,
302302- formCount,
303303- form;
304304-305305- if ( !forms || forms.length === 0 ) {
306306- return '';
307307- }
308308-309309- // Handle for Explicit 0= & 1= values
310310- for ( index = 0; index < forms.length; index++ ) {
311311- form = forms[ index ];
312312- if ( explicitPluralPattern.test( form ) ) {
313313- formCount = parseInt( form.slice( 0, form.indexOf( '=' ) ), 10 );
314314- if ( formCount === count ) {
315315- return ( form.slice( form.indexOf( '=' ) + 1 ) );
316316- }
317317- forms[ index ] = undefined;
318318- }
319319- }
320320-321321- forms = $.map( forms, function ( form ) {
322322- if ( form !== undefined ) {
323323- return form;
324324- }
325325- } );
326326-327327- pluralRules = this.pluralRules[ $.i18n().locale ];
328328-329329- if ( !pluralRules ) {
330330- // default fallback.
331331- return ( count === 1 ) ? forms[ 0 ] : forms[ 1 ];
332332- }
333333-334334- pluralFormIndex = this.getPluralForm( count, pluralRules );
335335- pluralFormIndex = Math.min( pluralFormIndex, forms.length - 1 );
336336-337337- return forms[ pluralFormIndex ];
338338- },
339339-340340- /**
341341- * For the number, get the plural for index
342342- *
343343- * @param {integer} number
344344- * @param {Object} pluralRules
345345- * @return {integer} plural form index
346346- */
347347- getPluralForm: function ( number, pluralRules ) {
348348- var i,
349349- pluralForms = [ 'zero', 'one', 'two', 'few', 'many', 'other' ],
350350- pluralFormIndex = 0;
351351-352352- for ( i = 0; i < pluralForms.length; i++ ) {
353353- if ( pluralRules[ pluralForms[ i ] ] ) {
354354- if ( pluralRuleParser( pluralRules[ pluralForms[ i ] ], number ) ) {
355355- return pluralFormIndex;
356356- }
357357-358358- pluralFormIndex++;
359359- }
360360- }
361361-362362- return pluralFormIndex;
363363- },
364364-365365- /**
366366- * Converts a number using digitTransformTable.
367367- *
368368- * @param {number} num Value to be converted
369369- * @param {boolean} integer Convert the return value to an integer
370370- * @return {string} The number converted into a String.
371371- */
372372- convertNumber: function ( num, integer ) {
373373- var tmp, item, i,
374374- transformTable, numberString, convertedNumber;
375375-376376- // Set the target Transform table:
377377- transformTable = this.digitTransformTable( $.i18n().locale );
378378- numberString = String( num );
379379- convertedNumber = '';
380380-381381- if ( !transformTable ) {
382382- return num;
383383- }
384384-385385- // Check if the restore to Latin number flag is set:
386386- if ( integer ) {
387387- if ( parseFloat( num, 10 ) === num ) {
388388- return num;
389389- }
390390-391391- tmp = [];
392392-393393- for ( item in transformTable ) {
394394- tmp[ transformTable[ item ] ] = item;
395395- }
396396-397397- transformTable = tmp;
398398- }
399399-400400- for ( i = 0; i < numberString.length; i++ ) {
401401- if ( transformTable[ numberString[ i ] ] ) {
402402- convertedNumber += transformTable[ numberString[ i ] ];
403403- } else {
404404- convertedNumber += numberString[ i ];
405405- }
406406- }
407407-408408- return integer ? parseFloat( convertedNumber, 10 ) : convertedNumber;
409409- },
410410-411411- /**
412412- * Grammatical transformations, needed for inflected languages.
413413- * Invoked by putting {{grammar:form|word}} in a message.
414414- * Override this method for languages that need special grammar rules
415415- * applied dynamically.
416416- *
417417- * @param {string} word
418418- * @param {string} form
419419- * @return {string}
420420- */
421421- // eslint-disable-next-line no-unused-vars
422422- convertGrammar: function ( word, form ) {
423423- return word;
424424- },
425425-426426- /**
427427- * Provides an alternative text depending on specified gender. Usage
428428- * {{gender:[gender|user object]|masculine|feminine|neutral}}. If second
429429- * or third parameter are not specified, masculine is used.
430430- *
431431- * These details may be overriden per language.
432432- *
433433- * @param {string} gender
434434- * male, female, or anything else for neutral.
435435- * @param {Array} forms
436436- * List of gender forms
437437- *
438438- * @return {string}
439439- */
440440- gender: function ( gender, forms ) {
441441- if ( !forms || forms.length === 0 ) {
442442- return '';
443443- }
444444-445445- while ( forms.length < 2 ) {
446446- forms.push( forms[ forms.length - 1 ] );
447447- }
448448-449449- if ( gender === 'male' ) {
450450- return forms[ 0 ];
451451- }
452452-453453- if ( gender === 'female' ) {
454454- return forms[ 1 ];
455455- }
456456-457457- return ( forms.length === 3 ) ? forms[ 2 ] : forms[ 0 ];
458458- },
459459-460460- /**
461461- * Get the digit transform table for the given language
462462- * See http://cldr.unicode.org/translation/numbering-systems
463463- *
464464- * @param {string} language
465465- * @return {Array|boolean} List of digits in the passed language or false
466466- * representation, or boolean false if there is no information.
467467- */
468468- digitTransformTable: function ( language ) {
469469- var tables = {
470470- ar: '٠١٢٣٤٥٦٧٨٩',
471471- fa: '۰۱۲۳۴۵۶۷۸۹',
472472- ml: '൦൧൨൩൪൫൬൭൮൯',
473473- kn: '೦೧೨೩೪೫೬೭೮೯',
474474- lo: '໐໑໒໓໔໕໖໗໘໙',
475475- or: '୦୧୨୩୪୫୬୭୮୯',
476476- kh: '០១២៣៤៥៦៧៨៩',
477477- nqo: '߀߁߂߃߄߅߆߇߈߉', // Note that the digits go right to left
478478- pa: '੦੧੨੩੪੫੬੭੮੯',
479479- gu: '૦૧૨૩૪૫૬૭૮૯',
480480- hi: '०१२३४५६७८९',
481481- my: '၀၁၂၃၄၅၆၇၈၉',
482482- ta: '௦௧௨௩௪௫௬௭௮௯',
483483- te: '౦౧౨౩౪౫౬౭౮౯',
484484- th: '๐๑๒๓๔๕๖๗๘๙', // FIXME use iso 639 codes
485485- bo: '༠༡༢༣༤༥༦༧༨༩' // FIXME use iso 639 codes
486486- };
487487-488488- if ( !tables[ language ] ) {
489489- return false;
490490- }
491491-492492- return tables[ language ].split( '' );
493493- }
494494- };
495495-496496- $.extend( $.i18n.languages, {
497497- default: language
498498- } );
499499-}( jQuery ) );
-123
scripts/jquery_i18n/jquery.i18n.messagestore.js
···11-/*!
22- * jQuery Internationalization library - Message Store
33- *
44- * Copyright (C) 2012 Santhosh Thottingal
55- *
66- * jquery.i18n is dual licensed GPLv2 or later and MIT. You don't have to do anything special to
77- * choose one license or the other and you don't have to notify anyone which license you are using.
88- * You are free to use UniversalLanguageSelector in commercial projects as long as the copyright
99- * header is left intact. See files GPL-LICENSE and MIT-LICENSE for details.
1010- *
1111- * @licence GNU General Public Licence 2.0 or later
1212- * @licence MIT License
1313- */
1414-1515-( function ( $ ) {
1616- 'use strict';
1717-1818- var MessageStore = function () {
1919- this.messages = {};
2020- this.sources = {};
2121- };
2222-2323- function jsonMessageLoader( url ) {
2424- var deferred = $.Deferred();
2525-2626- $.getJSON( url )
2727- .done( deferred.resolve )
2828- .fail( function ( jqxhr, settings, exception ) {
2929- $.i18n.log( 'Error in loading messages from ' + url + ' Exception: ' + exception );
3030- // Ignore 404 exception, because we are handling fallabacks explicitly
3131- deferred.resolve();
3232- } );
3333-3434- return deferred.promise();
3535- }
3636-3737- /**
3838- * See https://github.com/wikimedia/jquery.i18n/wiki/Specification#wiki-Message_File_Loading
3939- */
4040- MessageStore.prototype = {
4141-4242- /**
4343- * General message loading API This can take a URL string for
4444- * the json formatted messages.
4545- * <code>load('path/to/all_localizations.json');</code>
4646- *
4747- * This can also load a localization file for a locale <code>
4848- * load( 'path/to/de-messages.json', 'de' );
4949- * </code>
5050- * A data object containing message key- message translation mappings
5151- * can also be passed Eg:
5252- * <code>
5353- * load( { 'hello' : 'Hello' }, optionalLocale );
5454- * </code> If the data argument is
5555- * null/undefined/false,
5656- * all cached messages for the i18n instance will get reset.
5757- *
5858- * @param {string|Object} source
5959- * @param {string} locale Language tag
6060- * @return {jQuery.Promise}
6161- */
6262- load: function ( source, locale ) {
6363- var key = null,
6464- deferreds = [],
6565- messageStore = this;
6666-6767- if ( typeof source === 'string' ) {
6868- // This is a URL to the messages file.
6969- $.i18n.log( 'Loading messages from: ' + source );
7070- return jsonMessageLoader( source )
7171- .then( function ( localization ) {
7272- return messageStore.load( localization, locale );
7373- } );
7474- }
7575-7676- if ( locale ) {
7777- // source is an key-value pair of messages for given locale
7878- messageStore.set( locale, source );
7979-8080- return $.Deferred().resolve();
8181- } else {
8282- // source is a key-value pair of locales and their source
8383- for ( key in source ) {
8484- if ( Object.prototype.hasOwnProperty.call( source, key ) ) {
8585- locale = key;
8686- // No {locale} given, assume data is a group of languages,
8787- // call this function again for each language.
8888- deferreds.push( messageStore.load( source[ key ], locale ) );
8989- }
9090- }
9191- return $.when.apply( $, deferreds );
9292- }
9393-9494- },
9595-9696- /**
9797- * Set messages to the given locale.
9898- * If locale exists, add messages to the locale.
9999- *
100100- * @param {string} locale
101101- * @param {Object} messages
102102- */
103103- set: function ( locale, messages ) {
104104- if ( !this.messages[ locale ] ) {
105105- this.messages[ locale ] = messages;
106106- } else {
107107- this.messages[ locale ] = $.extend( this.messages[ locale ], messages );
108108- }
109109- },
110110-111111- /**
112112- *
113113- * @param {string} locale
114114- * @param {string} messageKey
115115- * @return {boolean}
116116- */
117117- get: function ( locale, messageKey ) {
118118- return this.messages[ locale ] && this.messages[ locale ][ messageKey ];
119119- }
120120- };
121121-122122- $.extend( $.i18n.messageStore, new MessageStore() );
123123-}( jQuery ) );
-310
scripts/jquery_i18n/jquery.i18n.parser.js
···11-/*!
22- * jQuery Internationalization library
33- *
44- * Copyright (C) 2011-2013 Santhosh Thottingal, Neil Kandalgaonkar
55- *
66- * jquery.i18n is dual licensed GPLv2 or later and MIT. You don't have to do
77- * anything special to choose one license or the other and you don't have to
88- * notify anyone which license you are using. You are free to use
99- * UniversalLanguageSelector in commercial projects as long as the copyright
1010- * header is left intact. See files GPL-LICENSE and MIT-LICENSE for details.
1111- *
1212- * @licence GNU General Public Licence 2.0 or later
1313- * @licence MIT License
1414- */
1515-1616-( function ( $ ) {
1717- 'use strict';
1818-1919- var MessageParser = function ( options ) {
2020- this.options = $.extend( {}, $.i18n.parser.defaults, options );
2121- this.language = $.i18n.languages[ String.locale ] || $.i18n.languages[ 'default' ];
2222- this.emitter = $.i18n.parser.emitter;
2323- };
2424-2525- MessageParser.prototype = {
2626-2727- constructor: MessageParser,
2828-2929- simpleParse: function ( message, parameters ) {
3030- return message.replace( /\$(\d+)/g, function ( str, match ) {
3131- var index = parseInt( match, 10 ) - 1;
3232-3333- return parameters[ index ] !== undefined ? parameters[ index ] : '$' + match;
3434- } );
3535- },
3636-3737- parse: function ( message, replacements ) {
3838- if ( message.indexOf( '{{' ) < 0 ) {
3939- return this.simpleParse( message, replacements );
4040- }
4141-4242- this.emitter.language = $.i18n.languages[ $.i18n().locale ] ||
4343- $.i18n.languages[ 'default' ];
4444-4545- return this.emitter.emit( this.ast( message ), replacements );
4646- },
4747-4848- ast: function ( message ) {
4949- var pipe, colon, backslash, anyCharacter, dollar, digits, regularLiteral,
5050- regularLiteralWithoutBar, regularLiteralWithoutSpace, escapedOrLiteralWithoutBar,
5151- escapedOrRegularLiteral, templateContents, templateName, openTemplate,
5252- closeTemplate, expression, paramExpression, result,
5353- pos = 0;
5454-5555- // Try parsers until one works, if none work return null
5656- function choice( parserSyntax ) {
5757- return function () {
5858- var i, result;
5959-6060- for ( i = 0; i < parserSyntax.length; i++ ) {
6161- result = parserSyntax[ i ]();
6262-6363- if ( result !== null ) {
6464- return result;
6565- }
6666- }
6767-6868- return null;
6969- };
7070- }
7171-7272- // Try several parserSyntax-es in a row.
7373- // All must succeed; otherwise, return null.
7474- // This is the only eager one.
7575- function sequence( parserSyntax ) {
7676- var i, res,
7777- originalPos = pos,
7878- result = [];
7979-8080- for ( i = 0; i < parserSyntax.length; i++ ) {
8181- res = parserSyntax[ i ]();
8282-8383- if ( res === null ) {
8484- pos = originalPos;
8585-8686- return null;
8787- }
8888-8989- result.push( res );
9090- }
9191-9292- return result;
9393- }
9494-9595- // Run the same parser over and over until it fails.
9696- // Must succeed a minimum of n times; otherwise, return null.
9797- function nOrMore( n, p ) {
9898- return function () {
9999- var originalPos = pos,
100100- result = [],
101101- parsed = p();
102102-103103- while ( parsed !== null ) {
104104- result.push( parsed );
105105- parsed = p();
106106- }
107107-108108- if ( result.length < n ) {
109109- pos = originalPos;
110110-111111- return null;
112112- }
113113-114114- return result;
115115- };
116116- }
117117-118118- // Helpers -- just make parserSyntax out of simpler JS builtin types
119119-120120- function makeStringParser( s ) {
121121- var len = s.length;
122122-123123- return function () {
124124- var result = null;
125125-126126- if ( message.slice( pos, pos + len ) === s ) {
127127- result = s;
128128- pos += len;
129129- }
130130-131131- return result;
132132- };
133133- }
134134-135135- function makeRegexParser( regex ) {
136136- return function () {
137137- var matches = message.slice( pos ).match( regex );
138138-139139- if ( matches === null ) {
140140- return null;
141141- }
142142-143143- pos += matches[ 0 ].length;
144144-145145- return matches[ 0 ];
146146- };
147147- }
148148-149149- pipe = makeStringParser( '|' );
150150- colon = makeStringParser( ':' );
151151- backslash = makeStringParser( '\\' );
152152- anyCharacter = makeRegexParser( /^./ );
153153- dollar = makeStringParser( '$' );
154154- digits = makeRegexParser( /^\d+/ );
155155- regularLiteral = makeRegexParser( /^[^{}[\]$\\]/ );
156156- regularLiteralWithoutBar = makeRegexParser( /^[^{}[\]$\\|]/ );
157157- regularLiteralWithoutSpace = makeRegexParser( /^[^{}[\]$\s]/ );
158158-159159- // There is a general pattern:
160160- // parse a thing;
161161- // if it worked, apply transform,
162162- // otherwise return null.
163163- // But using this as a combinator seems to cause problems
164164- // when combined with nOrMore().
165165- // May be some scoping issue.
166166- function transform( p, fn ) {
167167- return function () {
168168- var result = p();
169169-170170- return result === null ? null : fn( result );
171171- };
172172- }
173173-174174- // Used to define "literals" within template parameters. The pipe
175175- // character is the parameter delimeter, so by default
176176- // it is not a literal in the parameter
177177- function literalWithoutBar() {
178178- var result = nOrMore( 1, escapedOrLiteralWithoutBar )();
179179-180180- return result === null ? null : result.join( '' );
181181- }
182182-183183- function literal() {
184184- var result = nOrMore( 1, escapedOrRegularLiteral )();
185185-186186- return result === null ? null : result.join( '' );
187187- }
188188-189189- function escapedLiteral() {
190190- var result = sequence( [ backslash, anyCharacter ] );
191191-192192- return result === null ? null : result[ 1 ];
193193- }
194194-195195- choice( [ escapedLiteral, regularLiteralWithoutSpace ] );
196196- escapedOrLiteralWithoutBar = choice( [ escapedLiteral, regularLiteralWithoutBar ] );
197197- escapedOrRegularLiteral = choice( [ escapedLiteral, regularLiteral ] );
198198-199199- function replacement() {
200200- var result = sequence( [ dollar, digits ] );
201201-202202- if ( result === null ) {
203203- return null;
204204- }
205205-206206- return [ 'REPLACE', parseInt( result[ 1 ], 10 ) - 1 ];
207207- }
208208-209209- templateName = transform(
210210- // see $wgLegalTitleChars
211211- // not allowing : due to the need to catch "PLURAL:$1"
212212- makeRegexParser( /^[ !"$&'()*,./0-9;=?@A-Z^_`a-z~\x80-\xFF+-]+/ ),
213213-214214- function ( result ) {
215215- return result.toString();
216216- }
217217- );
218218-219219- function templateParam() {
220220- var expr,
221221- result = sequence( [ pipe, nOrMore( 0, paramExpression ) ] );
222222-223223- if ( result === null ) {
224224- return null;
225225- }
226226-227227- expr = result[ 1 ];
228228-229229- // use a "CONCAT" operator if there are multiple nodes,
230230- // otherwise return the first node, raw.
231231- return expr.length > 1 ? [ 'CONCAT' ].concat( expr ) : expr[ 0 ];
232232- }
233233-234234- function templateWithReplacement() {
235235- var result = sequence( [ templateName, colon, replacement ] );
236236-237237- return result === null ? null : [ result[ 0 ], result[ 2 ] ];
238238- }
239239-240240- function templateWithOutReplacement() {
241241- var result = sequence( [ templateName, colon, paramExpression ] );
242242-243243- return result === null ? null : [ result[ 0 ], result[ 2 ] ];
244244- }
245245-246246- templateContents = choice( [
247247- function () {
248248- var res = sequence( [
249249- // templates can have placeholders for dynamic
250250- // replacement eg: {{PLURAL:$1|one car|$1 cars}}
251251- // or no placeholders eg:
252252- // {{GRAMMAR:genitive|{{SITENAME}}}
253253- choice( [ templateWithReplacement, templateWithOutReplacement ] ),
254254- nOrMore( 0, templateParam )
255255- ] );
256256-257257- return res === null ? null : res[ 0 ].concat( res[ 1 ] );
258258- },
259259- function () {
260260- var res = sequence( [ templateName, nOrMore( 0, templateParam ) ] );
261261-262262- if ( res === null ) {
263263- return null;
264264- }
265265-266266- return [ res[ 0 ] ].concat( res[ 1 ] );
267267- }
268268- ] );
269269-270270- openTemplate = makeStringParser( '{{' );
271271- closeTemplate = makeStringParser( '}}' );
272272-273273- function template() {
274274- var result = sequence( [ openTemplate, templateContents, closeTemplate ] );
275275-276276- return result === null ? null : result[ 1 ];
277277- }
278278-279279- expression = choice( [ template, replacement, literal ] );
280280- paramExpression = choice( [ template, replacement, literalWithoutBar ] );
281281-282282- function start() {
283283- var result = nOrMore( 0, expression )();
284284-285285- if ( result === null ) {
286286- return null;
287287- }
288288-289289- return [ 'CONCAT' ].concat( result );
290290- }
291291-292292- result = start();
293293-294294- /*
295295- * For success, the pos must have gotten to the end of the input
296296- * and returned a non-null.
297297- * n.b. This is part of language infrastructure, so we do not throw an
298298- * internationalizable message.
299299- */
300300- if ( result === null || pos !== message.length ) {
301301- throw new Error( 'Parse error at position ' + pos.toString() + ' in input: ' + message );
302302- }
303303-304304- return result;
305305- }
306306-307307- };
308308-309309- $.extend( $.i18n.parser, new MessageParser() );
310310-}( jQuery ) );