1 |
|
2 | !function(exports, Object, Function) {
|
3 |
|
4 | "use strict";
|
5 | var currentLang, currentMap
|
6 | , isArray = Array.isArray
|
7 | , create = Object.create
|
8 | , cache = {}
|
9 | , formatRe = /{(?!;)({[\s\S]*}|\[[\s\S]*]|(?:("|')(?:\\\2|.)*?\2|[^;{}])+?)(?:;((?:(['"\/])(?:\\\4|.)*?\4[gim]*|[^}])*))?}/g
|
10 | , exprRe = /(['"\/])(?:\\\1|.)*?\1[gim]*|\b(?:[$_]|false|in|null|true|typeof|void)\b|\.\w+|\w+\s*:|\s+/g
|
11 | , wordRe = /(\$?)([a-z_][\w$]*)/ig
|
12 | , pattRe = /(\w+)(?::((?:(['"\/])(?:\\\3|.)*?\3[gim]*|[^;])*))?/g
|
13 | , pointerRe = /^([\w ]+)\.([\w ]+)$/
|
14 | , globalTexts = {}
|
15 | , globalVals = i18n.vals = {}
|
16 |
|
17 |
|
18 | , list = i18n.list = []
|
19 | , ext = i18n.ext = {}
|
20 | , fnScope = {}
|
21 |
|
22 | exports.i18n = i18n
|
23 | i18n.add = add
|
24 | i18n.get = get
|
25 | i18n.use = use
|
26 |
|
27 | function i18n(str, data) {
|
28 | if (typeof str === "number") return "" + str
|
29 | str = cache[str] || (
|
30 | cache[str] = makeFn(get(str) || str)
|
31 | )
|
32 | return isString(str) ? str : str(data || {}, i18n, globalVals)
|
33 | }
|
34 |
|
35 | function get(str, fallback) {
|
36 | var tmp
|
37 | return isString(str) ? (
|
38 | isString(currentMap[str]) ? currentMap[str] :
|
39 | typeof currentMap[str] === "object" ? currentMap[str][""] :
|
40 | (tmp = pointerRe.exec(str)) && (
|
41 | typeof currentMap[tmp[1]] === "object" &&
|
42 | currentMap[tmp[1]][tmp[2]] ||
|
43 | currentMap[tmp[2]] ||
|
44 | fallback ||
|
45 | tmp[2]
|
46 | ) || fallback
|
47 | ) :
|
48 | isArray(str) ?
|
49 | get(str[0], get(str[1], get(str[2], fallback))) :
|
50 | fallback
|
51 | }
|
52 |
|
53 |
|
54 | function makeFn(str) {
|
55 | var tmp, m, expr, pattern
|
56 | , args = ""
|
57 | , fn = ""
|
58 | , lastIndex = 0
|
59 | for (; m = formatRe.exec(str); ) {
|
60 | for (expr = m[1].replace(exprRe, ""); tmp = wordRe.exec(expr); ) {
|
61 | args += (args ? "," : "var ") + tmp[0] + (
|
62 | tmp[1] ? "=" : "=$['" + tmp[0] + "']!=null?$['" + tmp[0] + "']:"
|
63 | ) + "$g['" + tmp[2] + "']!=null?$g['" + tmp[2] + "']:''"
|
64 | }
|
65 | expr = m[1]
|
66 | if (pattern = get(m[3], m[3])) {
|
67 | if (ext[tmp = pattern.charAt(0)]) {
|
68 | expr = "_." + ext[tmp] + "(" + expr + "," + quote(pattern.slice(tmp == "#" ? 0 : 1)) + ")"
|
69 | } else {
|
70 | for (; tmp = pattRe.exec(pattern); ) {
|
71 | expr = "_." + tmp[1] + ".call($," + expr + (tmp[2] ? "," + tmp[2] : "") + ")"
|
72 | }
|
73 | }
|
74 | }
|
75 | fn += (fn ? "+" : "") + (
|
76 | lastIndex < m.index ?
|
77 | quote(str.slice(lastIndex, m.index)) + "+(" : "("
|
78 | ) + expr + ")"
|
79 | lastIndex = m.index + m[0].length
|
80 | }
|
81 |
|
82 | if (fn) try {
|
83 | return Function("$,_,$g", args + ";return(" + fn + (
|
84 | lastIndex < str.length ? ")+" + quote(str.slice(lastIndex)) : ")"
|
85 | ))
|
86 | } catch (e) {
|
87 | |
88 |
|
89 |
|
90 |
|
91 | }
|
92 | return str.replace(/{;/g, "{")
|
93 | }
|
94 |
|
95 | function add(lang, texts) {
|
96 | if (list.indexOf(lang) < 0) {
|
97 | i18n[lang] = create(globalTexts)
|
98 | list.push(lang)
|
99 | if (!currentLang) use(lang)
|
100 | }
|
101 | merge(i18n[lang], texts)
|
102 | }
|
103 |
|
104 | function merge(target, map) {
|
105 | for (var k in map) {
|
106 | target[k] = map[k] && map[k].constructor === Object ? merge(create(target), map[k]) : map[k]
|
107 | }
|
108 | return target
|
109 | }
|
110 |
|
111 | i18n.def = function(map) {
|
112 | for (var k in map) {
|
113 | add(k, map)
|
114 | }
|
115 | }
|
116 |
|
117 | function getLang(lang) {
|
118 | return lang && (
|
119 | i18n[lang = ("" + lang).toLowerCase()] ||
|
120 | i18n[lang = lang.split("-")[0]]
|
121 | ) && lang
|
122 | }
|
123 |
|
124 | function use(lang) {
|
125 | lang = getLang(lang)
|
126 | if (lang && currentLang != lang) {
|
127 | cache = {}
|
128 | currentMap = i18n[currentLang = i18n.current = lang] = i18n[currentLang]
|
129 | }
|
130 | return currentLang
|
131 | }
|
132 |
|
133 | function isString(str) {
|
134 | return typeof str === "string"
|
135 | }
|
136 | function isObject(obj) {
|
137 | return obj && obj.constructor === Object
|
138 | }
|
139 | function getStr(sub, word, fallback) {
|
140 | return currentMap && (
|
141 | isObject(currentMap[word]) && currentMap[word][sub] ||
|
142 | isObject(currentMap[sub]) && currentMap[sub][word] ||
|
143 | isString(currentMap[sub + word]) && currentMap[sub + word] ||
|
144 | isString(currentMap[word]) && currentMap[word]
|
145 | ) || isString(fallback) && fallback || ""
|
146 | }
|
147 | function quote(str) {
|
148 | return "'" + (str || "").replace(/'/g, "\\'").replace(/\n/g, "\\n") + "'"
|
149 | }
|
150 |
|
151 |
|
152 |
|
153 |
|
154 |
|
155 | var dateRe = /([Md])\1\1\1?|([yMdHhmswSZ])(\2?)|[uUaSeoQ]|'((?:''|[^'])*)'|(["\\\n\r\u2028\u2029])/g
|
156 | , fns = create(null)
|
157 | , tmp1 = new Date()
|
158 | , tmp2 = new Date()
|
159 | , map = {
|
160 | e: "Day()||7",
|
161 | M: "Month()+1",
|
162 | d: "Date()",
|
163 | H: "Hours()",
|
164 | h: "Hours()%12||12",
|
165 | m: "Minutes()",
|
166 | s: "Seconds()",
|
167 | S: "Milliseconds()"
|
168 | }
|
169 |
|
170 |
|
171 | i18n[ext["@"] = "date"] = date
|
172 | function date(input, _mask, _zone) {
|
173 | var offset, undef
|
174 | , d = typeof input === "number" ? input : isNaN(input) ? Date.parse(input) : +input
|
175 | , locale = currentMap["@"]
|
176 | , mask = locale[_mask] || _mask || locale.iso
|
177 | , zone = _zone != undef ? _zone : Date._tz != undef ? Date._tz : undef
|
178 | , utc = mask.slice(0, 4) == "UTC:"
|
179 | if (zone != undef && !utc) {
|
180 | offset = 60 * zone
|
181 | tmp1.setTime(d + offset * 6e4)
|
182 | utc = mask = "UTC:" + mask
|
183 | } else {
|
184 | tmp1.setTime(d)
|
185 | offset = utc ? 0 : -tmp1.getTimezoneOffset()
|
186 | }
|
187 | return isNaN(d) ? "" + d : (
|
188 | fns[mask] || (fns[mask] = Function("d,a,o,l", "var t;return \"" + dateStr(mask, utc) + "\"")))(
|
189 | tmp1,
|
190 | tmp2,
|
191 | offset,
|
192 | locale
|
193 | )
|
194 | }
|
195 |
|
196 | date.dateStr = dateStr
|
197 | function dateStr(mask, utc) {
|
198 | var get = "d.get" + (utc ? "UTC" : "")
|
199 | , setA = "a.setTime(+d+((4-(" + get + map.e + "))*864e5))"
|
200 | return (utc ? mask.slice(4) : mask).replace(dateRe, function(match, MD, single, pad, text, esc) {
|
201 | mask = (
|
202 | esc ? escape(esc).replace(/%u/g, "\\u").replace(/%/g, "\\x") :
|
203 | text !== void 0 ? text.replace(/''/g, "'") :
|
204 | MD ? "l.names[" + get + (MD == "M" ? "Month" : "Day" ) + "()+" + (match == "ddd" ? 24 : MD == "d" ? 31 : match == "MMM" ? 0 : 12) + "]" :
|
205 | match == "u" ? "(d/1000)>>>0" :
|
206 | match == "U" ? "+d" :
|
207 | match == "Q" ? "((" + get + "Month()/3)|0)+1" :
|
208 | match == "a" ? "l[" + get + map.H + ">11?'pm':'am']" :
|
209 | match == "o" ? setA + ",a" + get.slice(1) + "FullYear()" :
|
210 | single == "y" ? get + "FullYear()" + (pad == "y" ? "%100" : "") :
|
211 | single == "Z" ? "(t=o)?(t<0?((t=-t),'-'):'+')+(t<600?'0':'')+(0|(t/60))" + (pad ? "" : "+':'") + "+((t%=60)>9?t:'0'+t):'Z'" :
|
212 | single == "w" ? "Math.ceil(((" + setA + "-a.s" + get.slice(3) + "Month(0,1))/864e5+1)/7)" :
|
213 | get + map[single || match]
|
214 | )
|
215 | return text !== void 0 || esc ? mask : "\"+(" + (
|
216 | match == "SS" ? "(t=" + mask + ")>9?t>99?t:'0'+t:'00'+t" :
|
217 | pad && single != "Z" ? "(t=" + mask + ")>9?t:'0'+t" :
|
218 | mask
|
219 | ) + ")+\""
|
220 | })
|
221 | }
|
222 |
|
223 | /**/
|
224 |
|
225 | /*** i18n.detect ***/
|
226 | i18n.detect = function(fallback) {
|
227 | var navigator = exports.navigator || exports
|
228 |
|
229 |
|
230 | return use([navigator.language, navigator.userLanguage].concat(
|
231 | navigator.languages, fallback, list[0]
|
232 | ).filter(getLang)[0])
|
233 | }
|
234 |
|
235 |
|
236 |
|
237 | var numRe1 = /([^\d#]*)([\d# .,_·']*\/?\d+)(?:(\s*)([a-z%]+)(\d*))?(.*)/
|
238 | , numRe2 = /([.,\/])(\d*)$/
|
239 |
|
240 | i18n[ext["#"] = ext["+"] = "number"] = number
|
241 | function number(input, format) {
|
242 | format = getStr("#", format.slice(1), format)
|
243 | return (cache[format] || (cache[format] = Function(
|
244 | "d,g",
|
245 | "var N=d<0&&(d=-d),n,r,o;return " + numStr(format)
|
246 | )))(input, fnScope)
|
247 | }
|
248 | number.pre = {
|
249 | a: "(o+=d<1e3?'':d<1e6?(d/=1e3,'k'):d<1e9?(d/=1e6,'M'):d<1e12?(d/=1e9,'G'):d<1e15?(d/=1e12,'T'):d<1e18?(d/=1e15,'P'):(d/=1e18,'E')),"
|
250 | }
|
251 | number.post = {
|
252 | }
|
253 |
|
254 | function numStr(format) {
|
255 |
|
256 | var conf = format.split(";")
|
257 | , nan_value = conf[1] || "-"
|
258 | , m2 = numRe1.exec(conf[0])
|
259 | , m3 = numRe2.exec(m2[2])
|
260 | , decimals = m3 && m3[2].length || 0
|
261 | , full = m3 ? m2[2].slice(0, m3.index) : m2[2]
|
262 | , num = full.replace(/\D+/g, "")
|
263 | , sLen = num.length
|
264 | , step = decimals ? +(m3[1] === "/" ? 1 / m3[2] : num + "." + m3[2]) : num
|
265 | , decSep = m3 && m3[1]
|
266 | , fn = "d===Infinity?(N?" + quote(conf[5]||nan_value) + ":" + quote(conf[4]||nan_value) + "):d>0||d===0?(o=" + quote(m2[3]) + "," + (number.pre[m2[4]] || "") + "n=" + (
|
267 |
|
268 |
|
269 | decimals ?
|
270 | "d>1e-" + (decimals + 1) + "?(n=(d+'e" + decimals + "')/" + (step + "e" + decimals) + "":
|
271 | "d>"+num+"e-1?(n=d/" + num
|
272 | ) + ",Math.floor(n" + (
|
273 | conf[6] == 1 ? "%1?n+1:n" : "+" + (conf[6] || 0.5)
|
274 | ) + ")*" + step + "):0,r=" + (
|
275 | m2[5] ? "(''+(+n.toPrecision(" + (m2[5]) + ")))" :
|
276 | decimals ? "n.toFixed(" + decimals + ")" :
|
277 | "n+''"
|
278 | )
|
279 |
|
280 | if (decimals) {
|
281 | if (decSep == "/") {
|
282 | fn += ".replace(/\\.\\d+/,'" + (
|
283 | m3[2] == 5 ?
|
284 | "⅕⅖⅗⅘'.charAt(5" :
|
285 | "⅛¼⅜½⅝¾⅞'.charAt(8"
|
286 | ) + "*(n%1)-1))"
|
287 | } else if (decSep != ".") {
|
288 | fn += ".replace('.','" + decSep + "')"
|
289 | }
|
290 | if (sLen === 0) {
|
291 | fn += ",n<1&&(r=r.slice(1)||'0')"
|
292 | }
|
293 | }
|
294 | if (sLen > 1) {
|
295 | if (decimals) sLen += decimals + 1
|
296 | fn += ",r=(r.length<" + sLen + "?(1e15+r).slice(-" + sLen + "):r)"
|
297 | }
|
298 |
|
299 | if (num = full.match(/[^\d#][\d#]+/g)) {
|
300 | fn += ",r=" + numJunk(num, num.length - 1, 0, decimals ? decimals + 1 : 0)
|
301 | }
|
302 |
|
303 | if (m2[4] == "o") {
|
304 | number.post.o = "r+(o=g.o," + (
|
305 | fnScope.o = get("ordinal").split(";")
|
306 | ).pop() + ")"
|
307 | }
|
308 |
|
309 | fn += (
|
310 | (m2[4] ? ",r=" + (number.post[m2[4]] || "r+o") : "") +
|
311 | // negative format
|
312 | ",N&&n>0?" + quote(conf[2] || "-#").replace("#", "'+r+'") + ":" +
|
313 | (conf[3] ? "n===0?" + quote(conf[3]) + ":" : "") +
|
314 | (m2[1] ? quote(m2[1]) + "+r" : "r") +
|
315 | (m2[6] ? "+" + quote(m2[6]) : "")
|
316 | )
|
317 |
|
318 | return fn + "):" + quote(nan_value)
|
319 | }
|
320 |
|
321 | function numJunk(arr, i, lastLen, dec) {
|
322 | var len = lastLen + arr[i].length - 1
|
323 |
|
324 | return "(n<1e" + len + (
|
325 | lastLen ? "?r.slice(0,-" + (lastLen + dec) + "):" : "?r:"
|
326 | ) + (
|
327 | len < 16 ? numJunk(arr, i?i-1:i, len, dec) : "r.slice(0,-" + (lastLen + dec) + ")"
|
328 | ) + "+" + quote(arr[i].charAt(0)) + "+r.slice(-" + (len + dec) + (
|
329 | lastLen ? ",-" + (lastLen + dec) : ""
|
330 | ) + "))"
|
331 | }
|
332 |
|
333 |
|
334 |
|
335 | var pickRe1 = /([^;=,]+?)\?/g
|
336 | , pickRe2 = /[;=,]/
|
337 | i18n[ext["?"] = "pick"] = pick
|
338 | function pick(val, word) {
|
339 | for (var arr = getStr("?", word, word).replace(pickRe1, "$1=$1;").split(pickRe2), i = 1|arr.length; i > 0; ) {
|
340 | if ((i-=2) < 0 || arr[i] && (arr[i] == "" + val || +arr[i] <= val)) {
|
341 | return arr[i + 1] ? arr[i + 1].replace("#", val) : ""
|
342 | }
|
343 | }
|
344 | }
|
345 |
|
346 |
|
347 |
|
348 | i18n[ext["*"] = "plural"] = plural
|
349 | function plural(n, word) {
|
350 | var expr = getStr("*", "", "n!=1")
|
351 | return (cache[expr] || (cache[expr] = Function(
|
352 | "a,n",
|
353 | "return (a[+(" + expr + ")]||a[0]).replace('#',n)"
|
354 | )))((getStr("*", word, "# " + word)).split(";"), n)
|
355 | }
|
356 |
|
357 |
|
358 | i18n.map = function(input, str, sep, lastSep) {
|
359 | if (isObject(input)) input = Object.values(input)
|
360 | else if (!isArray(input)) return input
|
361 | input = input.map(function(data) {
|
362 | return i18n(str, data)
|
363 | })
|
364 | lastSep = lastSep && input.length > 1 ? lastSep + input.pop() : ""
|
365 | return input.join(sep || ", ") + lastSep
|
366 | }
|
367 | i18n.upcase = function(str) {
|
368 | return isString(str) ? str.toUpperCase() : "" + str
|
369 | }
|
370 | i18n.locase = function(str) {
|
371 | return isString(str) ? str.toLowerCase() : "" + str
|
372 | }
|
373 | i18n.json = JSON.stringify
|
374 |
|
375 |
|
376 | }(this, Object, Function)
|
377 |
|
378 |
|