+16
| var LanguageTag = require('./src/main') | ||
| var tag = new LanguageTag('en-Latn-US') | ||
| console.log(tag.language) | ||
| console.log(tag.script) | ||
| console.log(tag.region) | ||
| console.log(tag.variant) | ||
| console.log(tag.minimal.toString()) | ||
| console.log(tag == 'en-Latn-US') // eslint-disable-line eqeqeq | ||
| console.log(tag.matches('en-*')) | ||
| console.log(tag.minimal.suitableFor('en-US')) | ||
| console.log(tag.truncate().toString()) | ||
| console.log(tag.truncate({script: false}).toString()) | ||
| tag.forEach((subtag) => console.log(subtag.toString())) |
+376
| /** | ||
| * @overview | ||
| * RFC 5646 Language Tags Implementation | ||
| * @author James M Snell (jasnell@gmail.com) | ||
| * @license Public Domain | ||
| * @description An implementation of the RFC 5646 Language Tag | ||
| * syntax that works in browser and server environments | ||
| * and does not require Language Tag registry knowledge. | ||
| * @example | ||
| * var tag = new LanguageTag('en-Latn-US'); | ||
| * console.log(tag.language); // en | ||
| * console.log(tag.script); // Latn | ||
| * console.log(tag.region); // US | ||
| * console.log(tag.variant); // undefined | ||
| * console.log(tag.minimal; // en-US; | ||
| * console.log(tag == 'en-US'); // true | ||
| * console.log(tag.matches('en-*')); // true | ||
| * console.log(tag.minimal.suitableFor('en-US')); // true | ||
| * console.log(tag.truncate().toString()); //en-Latn-US | ||
| * console.log(tag.truncate({script:false}).toString()); // en-US | ||
| * var i = tag.iterator; | ||
| * var n | ||
| * while(!(n=i.next()).done) { | ||
| * console.log(n.value.toString()); | ||
| * } | ||
| **/ | ||
| 'use strict' | ||
| const kInspect = typeof require === 'function' | ||
| ? require('util').inspect.custom : 'inspect' | ||
| const Types = {} | ||
| Object.defineProperties(Types, { | ||
| Wildcard: { configurable: false, enumerable: true, value: undefined }, | ||
| Other: { configurable: false, enumerable: true, value: 0x0 }, | ||
| Language: { configurable: false, enumerable: true, value: 0x1 }, | ||
| ExtLang: { configurable: false, enumerable: true, value: 0x2 }, | ||
| Script: { configurable: false, enumerable: true, value: 0x4 }, | ||
| Region: { configurable: false, enumerable: true, value: 0x8 }, | ||
| Variant: { configurable: false, enumerable: true, value: 0x10 }, | ||
| Singleton: { configurable: false, enumerable: true, value: 0x20 }, | ||
| Extension: { configurable: false, enumerable: true, value: 0x40 }, | ||
| PrivateUse: { configurable: false, enumerable: true, value: 0x80 }, | ||
| Invalid: { configurable: false, enumerable: true, value: 0xFF } | ||
| }) | ||
| const _wild = { r: /^\*$/i, v: Types.Wildcard } | ||
| const _pvt = { r: /^x$/i, v: Types.PrivateUse | Types.Singleton } | ||
| const _ext = { r: /^[a-wy-z]$/i, v: Types.Extension | Types.Singleton } | ||
| const _lang = { r: /^[a-z]{2,3}$/i, v: Types.Language } | ||
| const _extlang = { r: /^[a-z]{3}$/i, v: Types.ExtLang } | ||
| const _script = { r: /^[a-z]{4}$/i, v: Types.Script } | ||
| const _region = { r: /^[a-z]{2}|[0-9]{3}$/i, v: Types.Region } | ||
| const _variant = { r: /^[a-z0-9]{5,8}|[0-9][a-z0-9]{3}$/i, v: Types.Variant } | ||
| const _other = { r: /^[a-z0-9]{2,8}$/i, v: Types.Other } | ||
| const kInner = Symbol('inner') | ||
| function flag (a, b) { | ||
| return (a & b) === b | ||
| } | ||
| function countext (previous) { | ||
| let c = 1 | ||
| let p = previous | ||
| while (p) { | ||
| if (p.type === Types.ExtLang) c++ | ||
| else break | ||
| p = p.previous | ||
| } | ||
| return c | ||
| } | ||
| function extpvtchk (v, previous) { | ||
| if (previous) { | ||
| if (!flag(v, Types.Singleton) && flag(previous.type, Types.Extension)) { v |= Types.Extension } else if (!flag(v, Types.Singleton) && flag(previous.type, Types.PrivateUse)) { v |= Types.PrivateUse } | ||
| } | ||
| return v | ||
| } | ||
| function classify (token, previous) { | ||
| var ret | ||
| function _test (t) { | ||
| return t.r.test(token) | ||
| }; | ||
| if (token.length === 0) { return Types.Invalid } | ||
| if (previous === undefined) { | ||
| ret = [_wild, _pvt, _lang].find(_test) | ||
| return ret ? ret.v : Types.Invalid | ||
| } else { | ||
| switch (previous.type) { | ||
| case Types.Language: | ||
| case Types.ExtLang: | ||
| ret = [_wild, _pvt, _ext, _extlang, _script, _region, _variant, _other] | ||
| .find(_test) | ||
| if (!ret) return Types.Invalid | ||
| return ret.v === Types.ExtLang | ||
| ? (countext(previous) <= 3 ? ret.v : Types.Invalid) | ||
| : extpvtchk(ret.v, previous) | ||
| case Types.Script: | ||
| ret = [_wild, _pvt, _ext, _region, _variant, _other].find(_test) | ||
| return ret ? extpvtchk(ret.v, previous) : Types.Invalid | ||
| case Types.Region: | ||
| ret = [_wild, _pvt, _ext, _variant, _other].find(_test) | ||
| return ret ? extpvtchk(ret.v, previous) : Types.Invalid | ||
| default: | ||
| ret = [_wild, _pvt, _ext, _other].find(_test) | ||
| return ret ? extpvtchk(ret.v, previous) : Types.Invalid | ||
| } | ||
| } | ||
| } | ||
| class Subtag { | ||
| constructor (token, previous) { | ||
| token = token.toLowerCase() | ||
| if (previous !== undefined) { | ||
| if (previous[kInner] === undefined) { throw new TypeError('The "previous" argument must be a Subtag') } | ||
| previous[kInner].next = this | ||
| } | ||
| const type = classify(token, previous) | ||
| this[kInner] = { | ||
| token, | ||
| previous, | ||
| type, | ||
| wild: type === undefined, | ||
| singleton: (type & Types.Singleton) === Types.Singleton, | ||
| extension: (type & Types.Extension) === Types.Extension, | ||
| privateuse: (type & Types.PrivateUse) === Types.PrivateUse | ||
| } | ||
| } | ||
| get token () { | ||
| return this[kInner].token | ||
| } | ||
| get next () { | ||
| return this[kInner].next | ||
| } | ||
| get previous () { | ||
| return this[kInner].previous | ||
| } | ||
| get type () { | ||
| return this[kInner].type | ||
| } | ||
| get wild () { | ||
| return this[kInner].wild | ||
| } | ||
| get singleton () { | ||
| return this[kInner].singleton | ||
| } | ||
| get extension () { | ||
| return this[kInner].extension | ||
| } | ||
| get privateuse () { | ||
| return this[kInner].privateuse | ||
| } | ||
| [kInspect] () { | ||
| return this[kInner] | ||
| } | ||
| toString () { | ||
| const token = this[kInner].token | ||
| switch (this[kInner].type) { | ||
| case Types.Script: | ||
| return token[0].toUpperCase() + token.slice(1) | ||
| case Types.Region: | ||
| return token.toUpperCase() | ||
| default: | ||
| if (this[kInner].singleton) { | ||
| let ret = token | ||
| let next = this.next | ||
| while (next && !next[kInner].singleton) { | ||
| ret += `-${next[kInner].token}` | ||
| next = next[kInner].next | ||
| } | ||
| return ret | ||
| } else { | ||
| return token | ||
| } | ||
| } | ||
| } | ||
| valueOf () { | ||
| return this.toString() | ||
| } | ||
| } | ||
| class LanguageTag { | ||
| constructor (tag) { | ||
| let language | ||
| let region | ||
| let script | ||
| let variant | ||
| let invalid | ||
| let privateuse | ||
| let extensions | ||
| let first | ||
| let p | ||
| let wild = false | ||
| let length = 0 | ||
| const tokens = String(tag).split(/[-_]/) | ||
| for (; length < tokens.length; length++) { | ||
| p = new Subtag(tokens[length], p) | ||
| switch (p.type) { | ||
| case Types.Language: | ||
| language = p.toString() | ||
| break | ||
| case Types.Region: | ||
| region = p.toString() | ||
| break | ||
| case Types.Script: | ||
| script = p.toString() | ||
| break | ||
| case Types.Variant: | ||
| variant = p.toString() | ||
| break | ||
| case Types.Invalid: | ||
| invalid = true | ||
| break | ||
| default: | ||
| if (p.singleton) { | ||
| if (p.privateuse && !privateuse) { | ||
| privateuse = p | ||
| } else if (p.extension) { | ||
| extensions = extensions || {} | ||
| extensions[p.token] = p | ||
| } | ||
| } else if (p.wild) { | ||
| wild = true | ||
| } | ||
| } | ||
| first = first || p | ||
| } | ||
| this[kInner] = { | ||
| language, | ||
| region, | ||
| script, | ||
| variant, | ||
| invalid, | ||
| privateuse, | ||
| extensions, | ||
| wild, | ||
| length, | ||
| first | ||
| } | ||
| } | ||
| get language () { | ||
| return this[kInner].language | ||
| } | ||
| get region () { | ||
| return this[kInner].region | ||
| } | ||
| get script () { | ||
| return this[kInner].script | ||
| } | ||
| get variant () { | ||
| return this[kInner].variant | ||
| } | ||
| get invalid () { | ||
| return this[kInner].invalid | ||
| } | ||
| get privateuse () { | ||
| return this[kInner].privateuse | ||
| } | ||
| get extensions () { | ||
| return this[kInner].extensions | ||
| } | ||
| get wild () { | ||
| return this[kInner].wild | ||
| } | ||
| get length () { | ||
| return this[kInner].length | ||
| } | ||
| get first () { | ||
| return this[kInner].first | ||
| } | ||
| [kInspect] () { | ||
| return this[kInner] | ||
| } | ||
| suitableFor (other) { | ||
| const inner = this[kInner] | ||
| if (inner.wild) return true | ||
| const _other = new LanguageTag(other) | ||
| const otherInner = _other[kInner] | ||
| if (inner.language !== otherInner.language) return false | ||
| if (inner.region && inner.region !== otherInner.region) return false | ||
| if (inner.script && inner.script !== otherInner.script) return false | ||
| if (inner.variant && inner.variant !== otherInner.variant) return false | ||
| return true | ||
| } | ||
| matches (other) { | ||
| const inner = this[kInner] | ||
| const wild = inner.wild | ||
| let a = wild ? this : other | ||
| const b = wild ? other : this | ||
| if (a === '*') a = '(?:[a-z0-9]{1,8})(?:-[a-z0-9]{1,8})*' | ||
| const pattern = a.toString().replace(/-\*/g, '(?:-[a-z0-9]{1,8})*') | ||
| const reg = new RegExp(`^${pattern}$`, 'i') | ||
| return reg.test(b.toString()) | ||
| } | ||
| truncate (options) { | ||
| const tags = [] | ||
| const inner = this[kInner] | ||
| let n = inner.first | ||
| if (n[kInner].privateuse) { return this } // don't truncate if tag is a privateuse | ||
| while (n !== undefined) { | ||
| let t = n | ||
| n = n.next | ||
| if (t.type < 0x10) { | ||
| if (options) { | ||
| if ((options.extlang === false && t.type === Types.ExtLang) || | ||
| (options.script === false && t.type === Types.Script) || | ||
| (options.variant === false && t.type === Types.Variant)) { | ||
| continue | ||
| } | ||
| } | ||
| tags.push(t.toString()) | ||
| } | ||
| } | ||
| return new LanguageTag(tags.join('-')) | ||
| } | ||
| get minimal () { | ||
| return this.truncate({ extlang: false, script: false, variant: false }) | ||
| } | ||
| valueOf () { | ||
| return this.toString() | ||
| } | ||
| toString () { | ||
| return Array.from(this).join('-') | ||
| } | ||
| * [Symbol.iterator] () { | ||
| let n = this.first | ||
| while (n !== undefined) { | ||
| yield n | ||
| n = n.next | ||
| } | ||
| } | ||
| forEach (callback) { | ||
| if (typeof callback !== 'function') { throw new TypeError('A callback function must be provided') } | ||
| for (const tag of this) { callback.call(this, tag) } | ||
| } | ||
| } | ||
| LanguageTag.Types = Types | ||
| module.exports = LanguageTag |
+8
-12
| { | ||
| "name": "rfc5646", | ||
| "version": "2.0.0", | ||
| "version": "3.0.0", | ||
| "description": "RFC 5646 Language Tags Implementation", | ||
| "license": "Public Domain", | ||
| "keywords": [ | ||
| "rfc5646", | ||
| "languagetag" | ||
| ], | ||
| "maintainers": [ | ||
| "James M Snell <jasnell@us.ibm.com> (http://www.chmod777self.com)" | ||
| ], | ||
| "keywords": [ "rfc5646", "languagetag" ], | ||
| "author": "James M Snell <jasnell@gmail.com>", | ||
| "scripts": { | ||
| "test": "mocha" | ||
| "test": "standard && mocha test -R tap" | ||
| }, | ||
| "devDependencies": { | ||
| "async": "^1.4.0", | ||
| "mocha": "^2.2.5" | ||
| "async": "^2.5.0", | ||
| "mocha": "^4.0.1", | ||
| "standard": "^10.0.3" | ||
| }, | ||
| "main": "./src/main.js", | ||
| "main": "main.js", | ||
| "repository": { | ||
@@ -22,0 +18,0 @@ "type": "git", |
+15
-10
| # RFC 5646 Language Tag Implementation | ||
| Basic Language Tag handling. Does not attempt to do validation against | ||
| the registry. If you need a more complete implementation, look at | ||
| https://www.npmjs.com/package/language-tags by https://www.npmjs.com/~mcg | ||
| the registry. | ||
@@ -12,2 +11,6 @@ License: Public Domain | ||
| ```bash | ||
| yarn add rfc5646 | ||
| ``` | ||
| ```bash | ||
| npm install rfc5646 | ||
@@ -18,7 +21,9 @@ ``` | ||
| ```javascript | ||
| var LanguageTag = require('rfc5646'); | ||
| ```js | ||
| const LanguageTag = require('rfc5646'); | ||
| var tag = LanguageTag('en-Latn-US'); | ||
| // (The new keyword is required) | ||
| const tag = new LanguageTag('en-Latn-US'); | ||
| // Immutable properties | ||
| console.log(tag.language); // en | ||
@@ -31,2 +36,3 @@ console.log(tag.script); // Latn | ||
| console.log(tag.matches('en-*')); // true | ||
| console.log(tag.suitableFor('en-US')); // true | ||
| console.log(tag.minimal.suitableFor('en-US')); // true | ||
@@ -36,7 +42,7 @@ console.log(tag.truncate().toString()); // en-Latn-US | ||
| tag.forEach(function(subtag) { | ||
| console.log(subtag.toString()); | ||
| }); | ||
| // ES6 Iteration... | ||
| tag.forEach((subtag) => console.log(subtag.toString())); | ||
| tag = LanguageTag('en-US-a-abc-b-xyz-x-123'); | ||
| // Extensions and Private Use Tags | ||
| tag = new LanguageTag('en-US-a-abc-b-xyz-x-123'); | ||
@@ -46,3 +52,2 @@ console.log(tag.extensions.a.toString()); // a-abc | ||
| console.log(tag.privateuse.toString()); // x-123 | ||
| ``` |
Sorry, the diff of this file is not supported yet
-75
| ##### Signed by https://keybase.io/jasnell | ||
| ``` | ||
| -----BEGIN PGP SIGNATURE----- | ||
| Comment: GPGTools - https://gpgtools.org | ||
| iQEcBAABCgAGBQJWJnVhAAoJEHNBsVwHCHesPmMIALeKhpZRjzrXUoFQlKw5n7Sy | ||
| k92HtUJzp+ZQuP+HiVhLsUzUbhk0O/vtAA7V3e4HJ9dU4Psea+9CKXh47p650mQF | ||
| 1qOQ5Pid39UZ/zsit6fc4vYNM3vWwEbjHuGOUD5PVAfttPLhBH9w6G2s2zxwGXcx | ||
| hEOheYmNxpIYYHoXb2e4jx+i6YtW8U28J2yDB9lruowIooDYknQxCcIGRg4pJrEa | ||
| etYqtc3MD1N5xKxK1T7gh4jK0s5Rv0wc+6eX09wLwA4ooAbULxOOMCoCyQyN+q4S | ||
| uWH28hNeUAvI9aGau4Am04bcJzNvOdtuBB0QbHu3xPLIhPS0xXS4zZLctYz2rK8= | ||
| =55si | ||
| -----END PGP SIGNATURE----- | ||
| ``` | ||
| <!-- END SIGNATURES --> | ||
| ### Begin signed statement | ||
| #### Expect | ||
| ``` | ||
| size exec file contents | ||
| ./ | ||
| 15 .gitignore 44d20a8fa365553cb3fc77c3b81d228a44fe28b980b4a3907a6120d58af3253b | ||
| 93 .jshintrc ac72baaccc327aca1aa7b22eb98d0eec7b15a69cfc2fe5a568c6f086ba8e2197 | ||
| 32 .npmignore 97df9979b36f6537fbdd6bacf86a9c534a0548be28fd3c038be3e33502b76d9a | ||
| 620 example.js b1e1f7469e1fb5e8bb38d88a0c95ad89c4d02074dd5a0af8830e337dacb1f17f | ||
| 513 package.json 7899444e5b69cb85941ecee2a1dc3afd52349def778c220cba428c9cc9e74f7a | ||
| 1330 README.md 10addbae27687d65f7c6db6896875030ccb3397cc183359e459de1b9d4fb1638 | ||
| src/ | ||
| 8772 main.js 0ae9ad6ef850da8296b8214fe0790ab99defbec73dd90bf8ef517b89c90b61ba | ||
| test/ | ||
| 10636 test.js 8a149f597584cdde54120f63dd3f8c5a32d0ee25d1c929acb2cd7e57327c15d8 | ||
| ``` | ||
| #### Ignore | ||
| ``` | ||
| /SIGNED.md | ||
| ``` | ||
| #### Presets | ||
| ``` | ||
| git # ignore .git and anything as described by .gitignore files | ||
| dropbox # ignore .dropbox-cache and other Dropbox-related files | ||
| kb # ignore anything as described by .kbignore files | ||
| ``` | ||
| <!-- summarize version = 0.0.9 --> | ||
| ### End signed statement | ||
| <hr> | ||
| #### Notes | ||
| With keybase you can sign any directory's contents, whether it's a git repo, | ||
| source code distribution, or a personal documents folder. It aims to replace the drudgery of: | ||
| 1. comparing a zipped file to a detached statement | ||
| 2. downloading a public key | ||
| 3. confirming it is in fact the author's by reviewing public statements they've made, using it | ||
| All in one simple command: | ||
| ```bash | ||
| keybase dir verify | ||
| ``` | ||
| There are lots of options, including assertions for automating your checks. | ||
| For more info, check out https://keybase.io/docs/command_line/code_signing |
-306
| /** | ||
| * @overview | ||
| * RFC 5646 Language Tags Implementation | ||
| * @author James M Snell (jasnell@gmail.com) | ||
| * @license Public Domain | ||
| * @description An implementation of the RFC 5646 Language Tag | ||
| * syntax that works in browser and server environments | ||
| * and does not require Language Tag registry knowledge. | ||
| * @example | ||
| * var tag = new LanguageTag('en-Latn-US'); | ||
| * console.log(tag.language); // en | ||
| * console.log(tag.script); // Latn | ||
| * console.log(tag.region); // US | ||
| * console.log(tag.variant); // undefined | ||
| * console.log(tag.minimal; // en-US; | ||
| * console.log(tag == 'en-US'); // true | ||
| * console.log(tag.matches('en-*')); // true | ||
| * console.log(tag.minimal.suitableFor('en-US')); // true | ||
| * console.log(tag.truncate().toString()); //en-Latn-US | ||
| * console.log(tag.truncate({script:false}).toString()); // en-US | ||
| * var i = tag.iterator; | ||
| * var n | ||
| * while(!(n=i.next()).done) { | ||
| * console.log(n.value.toString()); | ||
| * } | ||
| **/ | ||
| 'use strict'; | ||
| function def(obj, prop,value) { | ||
| Object.defineProperty( | ||
| obj, prop,{ | ||
| enumerable: true, | ||
| value: value | ||
| }); | ||
| } | ||
| /** | ||
| * @enum {number} | ||
| * @memberOf LanguageTag | ||
| * @description The Subtag Type | ||
| **/ | ||
| const Types = { | ||
| /** Subtag is equal to '*' (value 0x0) **/ | ||
| Wildcard: undefined, | ||
| Other : 0x0, | ||
| /** Language Subtag (value 0x1) **/ | ||
| Language : 0x1, | ||
| /** Ext-Lang Subtag (value 0x2) **/ | ||
| ExtLang : 0x2, | ||
| /** Script Subtag (value 0x4) **/ | ||
| Script : 0x4, | ||
| /** Region Subtag (value 0x8) **/ | ||
| Region : 0x8, | ||
| /** Variant Subtag (value 0x10) **/ | ||
| Variant : 0x10, | ||
| /** Singleton Subtag (value 0x20) **/ | ||
| Singleton: 0x20, | ||
| /** Extension Subtag (value 0x40) **/ | ||
| Extension: 0x40, | ||
| /** Private Use Subtag (value 0x80) **/ | ||
| PrivateUse: 0x80, | ||
| /** Invalid Subtag (value 0xFF) **/ | ||
| Invalid: 0xFF | ||
| }; | ||
| const _wild = {r:/^\*$/i,v:Types.Wildcard}, | ||
| _pvt = {r:/^x$/i,v:Types.PrivateUse|Types.Singleton}, | ||
| _ext = {r:/^[a-wy-z]$/i,v:Types.Extension|Types.Singleton}, | ||
| _lang = {r:/^[a-z]{2,3}$/i,v:Types.Language}, | ||
| _extlang = {r:/^[a-z]{3}$/i,v:Types.ExtLang}, | ||
| _script = {r:/^[a-z]{4}$/i,v:Types.Script}, | ||
| _region = {r:/^[a-z]{2}|[0-9]{3}$/i,v:Types.Region}, | ||
| _variant = {r:/^[a-z0-9]{5,8}|[0-9][a-z0-9]{3}$/i,v:Types.Variant}, | ||
| _other = {r:/^[a-z0-9]{2,8}$/i,v:Types.Other} | ||
| ; | ||
| function flag(a,b) { | ||
| return (a&b)==b; | ||
| } | ||
| function countext(previous) { | ||
| var c = 1, p = previous; | ||
| while(p) { | ||
| if (p.type == Types.ExtLang) c++; | ||
| else break; | ||
| p = p.previous; | ||
| } | ||
| return c; | ||
| } | ||
| function extpvtchk(v,previous) { | ||
| if (previous) { | ||
| if (!flag(v,Types.Singleton) && flag(previous.type,Types.Extension)) | ||
| v |= Types.Extension; | ||
| else if (!flag(v,Types.Singleton) && flag(previous.type,Types.PrivateUse)) | ||
| v |= Types.PrivateUse; | ||
| } | ||
| return v; | ||
| } | ||
| function classify(token, previous) { | ||
| var ret; | ||
| var _test = function(t) { | ||
| return t.r.test(token); | ||
| }; | ||
| if (token.length === 0) | ||
| return Types.Invalid; | ||
| if (!previous) { | ||
| ret = [_wild, _pvt, _lang].find(_test); | ||
| return ret ? ret.v : Types.Invalid; | ||
| } else { | ||
| switch(previous.type) { | ||
| case Types.Language: | ||
| case Types.ExtLang: | ||
| ret = [_wild,_pvt,_ext,_extlang,_script,_region,_variant,_other] | ||
| .find(_test); | ||
| if (!ret) return Types.Invalid; | ||
| return ret.v == Types.ExtLang ? | ||
| (countext(previous) <= 3 ? ret.v : Types.Invalid) : | ||
| extpvtchk(ret.v,previous); | ||
| case Types.Script: | ||
| ret = [_wild,_pvt,_ext,_region,_variant,_other].find(_test); | ||
| return ret ? extpvtchk(ret.v,previous): Types.Invalid; | ||
| case Types.Region: | ||
| ret = [_wild,_pvt,_ext,_variant,_other].find(_test); | ||
| return ret ? extpvtchk(ret.v,previous) : Types.Invalid; | ||
| default: | ||
| ret = [_wild,_pvt,_ext,_other].find(_test); | ||
| return ret ? extpvtchk(ret.v,previous) : Types.Invalid; | ||
| } | ||
| } | ||
| } | ||
| function Subtag(token, previous) { | ||
| if (!(this instanceof Subtag)) | ||
| return new Subtag(token, previous); | ||
| def(this,'token',token.toLowerCase()); | ||
| if (previous) { | ||
| def(previous,'next',this); | ||
| def(this,'previous',previous); | ||
| } | ||
| def(this,'type',classify(token,previous)); | ||
| def(this,'wild',this.type === undefined); | ||
| def(this,'singleton',flag(this.type,Types.Singleton)); | ||
| def(this,'extension',flag(this.type,Types.Extension)); | ||
| def(this,'privateUse',flag(this.type,Types.PrivateUse)); | ||
| } | ||
| Subtag.prototype = { | ||
| toString: function() { | ||
| switch(this.type) { | ||
| case Types.Script: | ||
| return this.token[0].toUpperCase() + this.token.substr(1); | ||
| case Types.Region: | ||
| return this.token.toUpperCase(); | ||
| default: | ||
| if (this.singleton) { | ||
| var ret = this.token; | ||
| var next = this.next; | ||
| while(next && !next.singleton) { | ||
| ret += '-' + next.token; | ||
| next = next.next; | ||
| } | ||
| return ret; | ||
| } else { | ||
| return this.token; | ||
| } | ||
| } | ||
| }, | ||
| valueOf: function() { | ||
| return this.toString(); | ||
| } | ||
| }; | ||
| function LanguageTag(_tag) { | ||
| if (!(this instanceof LanguageTag)) | ||
| return new LanguageTag(_tag.toString()); | ||
| else if (_tag instanceof LanguageTag) | ||
| return _tag; | ||
| // check for grandfathered here... | ||
| var f, p; | ||
| var splits = _tag.split(/[-_]/); | ||
| var exts; | ||
| var wild = false; | ||
| for (var n = 0, l = splits.length; n < l; n++) { | ||
| p = new Subtag(splits[n], p); | ||
| switch(p.type) { | ||
| case Types.Language: | ||
| def(this,'language',p.toString()); | ||
| break; | ||
| case Types.Region: | ||
| def(this,'region',p.toString()); | ||
| break; | ||
| case Types.Script: | ||
| def(this,'script',p.toString()); | ||
| break; | ||
| case Types.Variant: | ||
| def(this,'variant',p.toString()); | ||
| break; | ||
| case Types.Invalid: | ||
| def(this,'invalid',true); | ||
| break; | ||
| default: | ||
| if (p.singleton) { | ||
| if (p.privateUse) { | ||
| if (!this.privateuse) | ||
| def(this,'privateuse',p); | ||
| } else if (p.extension) { | ||
| if (!exts) exts = {}; | ||
| exts[p.token] = p; | ||
| } | ||
| } else if (p.wild) { | ||
| this.wild = true; | ||
| } | ||
| } | ||
| f = f||p; | ||
| } | ||
| if (exts) def(this,'extensions',exts); | ||
| def(this,'wild', wild); | ||
| def(this,'length',splits.length); | ||
| def(this,'first',f); | ||
| } | ||
| LanguageTag.prototype = { | ||
| suitableFor : function(other) { | ||
| if (this.wild) return true; | ||
| var _othertag = new LanguageTag(other); | ||
| if (this.language !== _othertag.language) return false; | ||
| if (this.region && this.region !== _othertag.region) return false; | ||
| if (this.script && this.script !== _othertag.script) return false; | ||
| if (this.variant && this.variant !== _othertag.variant) return false; | ||
| return true; | ||
| }, | ||
| valueOf : function() { | ||
| return this.toString(); | ||
| }, | ||
| toString : function() { | ||
| var tags = [], n = this.first; | ||
| this.forEach(function(tag) { | ||
| tags.push(tag.toString()); | ||
| }); | ||
| return tags.join('-'); | ||
| }, | ||
| matches : function(other) { | ||
| var wild = this.wild; | ||
| var a = wild?this:other; | ||
| var b = wild?other:this; | ||
| if (a === '*') a = '(?:[a-z0-9]{1,8})(?:-[a-z0-9]{1,8})*'; | ||
| var pattern = a.toString().replace(/-\*/g,'(?:-[a-z0-9]{1,8})*'); | ||
| var reg = new RegExp('^'+pattern+'$', 'i'); | ||
| return reg.test(b.toString()); | ||
| }, | ||
| truncate : function(options) { | ||
| var tags = [], n = this.first; | ||
| if (n.privateUse) return this; // don't truncate if tag is a private use | ||
| while(n) { | ||
| var t = n; | ||
| n = n.next; | ||
| if (t.type < 0x10) { | ||
| if (options) { | ||
| if ((options.extlang === false && t.type === Types.ExtLang) || | ||
| (options.script === false && t.type === Types.Script) || | ||
| (options.variant === false && t.type === Types.Variant)) { | ||
| continue; | ||
| } | ||
| } | ||
| tags.push(t.toString()); | ||
| } | ||
| } | ||
| return new LanguageTag(tags.join('-')); | ||
| }, | ||
| get minimal() { | ||
| return this.truncate({extlang:false,script:false,variant:false}); | ||
| }, | ||
| get iterator() { | ||
| var current = this.first; | ||
| var ret = { | ||
| next: function() { | ||
| if (this.done) return {done:true}; | ||
| var ret = current; | ||
| if (current.singleton) { | ||
| do { | ||
| current = current.next; | ||
| } while(current && !current.singleton); | ||
| } else { | ||
| current = current.next; | ||
| } | ||
| return {done:false,value:ret}; | ||
| }, | ||
| get done() { | ||
| return current === undefined; | ||
| } | ||
| }; | ||
| return ret; | ||
| }, | ||
| forEach : function(callback) { | ||
| if (typeof callback !== 'function') | ||
| throw new Error('A callback function must be provided'); | ||
| var i = this.iterator; | ||
| while(!i.done) { | ||
| callback(i.next().value); | ||
| } | ||
| } | ||
| }; | ||
| LanguageTag.Types = Types; | ||
| module.exports = LanguageTag; |
-557
| 'use strict'; | ||
| // source: http://www.langtag.net/test-suites.html | ||
| const valid = ['fr', | ||
| 'fr-Latn', | ||
| 'fr-fra', | ||
| 'fr-Latn-FR', | ||
| 'fr-Latn-419', | ||
| 'fr-FR', | ||
| 'ax-TZ', | ||
| 'fr-shadok', | ||
| 'fr-y-myext-myext2', | ||
| 'fra-Latn', | ||
| 'fra', | ||
| 'fra-FX', | ||
| 'i-klingon', | ||
| 'I-kLINgon', | ||
| 'no-bok', | ||
| 'fr-Lat', | ||
| 'mn-Cyrl-MN', | ||
| 'mN-cYrL-Mn', | ||
| 'fr-Latn-CA', | ||
| 'en-US', | ||
| 'fr-Latn-CA', | ||
| 'i-enochian', | ||
| 'x-fr-CH', | ||
| 'sr-Latn-CS', | ||
| 'es-419', | ||
| 'sl-nedis', | ||
| 'de-CH-1996', | ||
| 'de-Latg-1996', | ||
| 'sl-IT-nedis', | ||
| 'en-a-bbb-x-a-ccc', | ||
| 'de-a-value', | ||
| 'en-Latn-GB-boont-r-extended-sequence-x-private', | ||
| 'en-x-US', | ||
| 'az-Arab-x-AZE-derbend', | ||
| 'es-Latn-CO-x-private', | ||
| 'en-US-boont', | ||
| 'ab-x-abc-x-abc', | ||
| 'ab-x-abc-a-a', | ||
| 'i-default', | ||
| 'i-klingon', | ||
| 'abcd-Latn', | ||
| 'AaBbCcDd-x-y-any-x', | ||
| 'en', | ||
| 'de-AT', | ||
| 'es-419', | ||
| 'de-CH-1901', | ||
| 'sr-Cyrl', | ||
| 'sr-Cyrl-CS', | ||
| 'sl-Latn-IT-rozaj', | ||
| 'en-US-x-twain', | ||
| 'zh-cmn', | ||
| 'zh-cmn-Hant', | ||
| 'zh-cmn-Hant-HK', | ||
| 'zh-gan', | ||
| 'zh-yue-Hant-HK', | ||
| 'xr-lxs-qut', | ||
| 'xr-lqt-qu', | ||
| 'xr-p-lze', | ||
| 'fr', | ||
| 'fr-Latn', | ||
| 'fr-fra', | ||
| 'fr-Latn-FR', | ||
| 'fr-Latn-419', | ||
| 'fr-FR', | ||
| 'fr-y-myext-myext2', | ||
| 'apa-Latn', | ||
| 'apa', | ||
| 'apa-CA', | ||
| 'i-klingon', | ||
| 'no-bok', | ||
| 'fr-Lat', | ||
| 'mn-Cyrl-MN', | ||
| 'mN-cYrL-Mn', | ||
| 'fr-Latn-CA', | ||
| 'en-US', | ||
| 'fr-Latn-CA', | ||
| 'i-enochian', | ||
| 'x-fr-CH', | ||
| 'sr-Latn-CS', | ||
| 'es-419', | ||
| 'sl-nedis', | ||
| 'de-CH-1996', | ||
| 'de-Latg-1996', | ||
| 'sl-IT-nedis', | ||
| 'en-a-bbb-x-a-ccc', | ||
| 'de-a-value', | ||
| 'en-x-US', | ||
| 'az-Arab-x-AZE-derbend', | ||
| 'es-Latn-CO-x-private', | ||
| 'ab-x-abc-x-abc', | ||
| 'ab-x-abc-a-a', | ||
| 'i-default', | ||
| 'i-klingon', | ||
| 'en', | ||
| 'de-AT', | ||
| 'es-419', | ||
| 'de-CH-1901', | ||
| 'sr-Cyrl', | ||
| 'sr-Cyrl-CS', | ||
| 'sl-Latn-IT-rozaj', | ||
| 'en-US-x-twain', | ||
| 'zh-cmn', | ||
| 'zh-cmn-Hant', | ||
| 'zh-cmn-Hant-HK', | ||
| 'zh-gan', | ||
| 'zh-yue-Hant-HK', | ||
| 'en-Latn-GB-boont-r-extended-sequence-x-private', | ||
| 'en-US-boont' | ||
| ]; | ||
| const invalid = [ | ||
| 'f', | ||
| 'f-Latn', | ||
| 'fr-Latn-F', | ||
| 'a-value', | ||
| 'en-a-bbb-a-ccc', | ||
| 'tlh-a-b-foo', | ||
| 'i-notexist', | ||
| 'abcdefghi-012345678', | ||
| 'ab-abc-abc-abc-abc', | ||
| 'ab-abcd-abc', | ||
| 'ab-ab-abc', | ||
| 'ab-123-abc', | ||
| 'a-Hant-ZH', | ||
| 'a1-Hant-ZH', | ||
| 'ab-abcde-abc', | ||
| 'ab-1abc-abc', | ||
| 'ab-ab-abcd', | ||
| 'ab-123-abcd', | ||
| 'ab-abcde-abcd', | ||
| 'ab-1abc-abcd', | ||
| 'ab-a-b', | ||
| 'ab-a-x', | ||
| 'ab--ab', | ||
| 'ab-abc-', | ||
| '-ab-abc', | ||
| 'ab-c-abc-r-toto-c-abc', | ||
| 'abcd-efg', | ||
| 'aabbccddE', | ||
| 'ax-TZ', | ||
| 'fra-Latn', | ||
| 'fra', | ||
| 'fra-FX', | ||
| 'abcd-Latn', | ||
| 'AaBbCcDd-x-y-any-x', | ||
| 'zh-Latm-CN', | ||
| 'de-DE-1902', | ||
| 'fr-shadok' | ||
| ]; | ||
| const wellformed = [ | ||
| 'en-GB-oed', | ||
| 'zh-cmn-Hans', | ||
| 'no-bok', | ||
| '#zh-Hans-HK-SCOUSE-a-foobar-b-x-a-en@collation=phonebook;calendar=islamic', | ||
| '#i-default@abc=def', | ||
| '#x-foobar@abc=def', | ||
| '#zh-Hans-HK-SCOUSE-a-foobar-x-a-en@collation=phonebook;calendar=islamic', | ||
| '#zh@collation=phonebook', | ||
| '#zh@collation=phonebook;calendar=islamic', | ||
| '#zh-Hans-HK-SCOUSE-a-foobar-b-en-x-a-en@collation=phonebook;calendar=islamic', | ||
| 'AaBbCcDd', | ||
| 'AaBbCcDd-x-y-any-x', | ||
| 'abcd-Latn', | ||
| 'ab-x-abc-a-a', | ||
| 'ab-x-abc-a-a', | ||
| 'ab-x-abc-x-abc', | ||
| 'ax-TZ', | ||
| 'az-Arab-x-AZE-derbend', | ||
| 'de-a-value', | ||
| 'de-CH-1996', | ||
| 'de-Latg-1996', | ||
| 'en', | ||
| 'en-a-bbb-x-a-ccc', | ||
| 'en-gb-oed', | ||
| 'en-Latn', | ||
| 'en-Latn-001', | ||
| 'en-Latn-GB-boont-r-extended-sequence-x-private', | ||
| 'en-Latn-US', | ||
| 'en-Latn-US-lojban-gaulish', | ||
| 'en-Latn-US-lojban-gaulish-a-12345678-ABCD-b-ABCDEFGH', | ||
| 'en-Latn-US-lojban-gaulish-a-12345678-ABCD-b-ABCDEFGH-x-a-b-c-12345678', | ||
| 'en-US', | ||
| 'en-US', | ||
| 'en-US-boont', | ||
| 'en-x-US', | ||
| 'es-419', | ||
| 'es-Latn-CO-x-private', | ||
| 'fr ', | ||
| 'fra', | ||
| 'fra-FX', | ||
| 'fra-Latn', | ||
| 'fr-FR', | ||
| 'fr-Latn', | ||
| 'fr-Latn-419', | ||
| 'fr-Latn-CA', | ||
| 'fr-Latn-CA', | ||
| 'fr-Latn-FR', | ||
| 'fr-shadok', | ||
| 'fr-y-myext-myext2', | ||
| 'i-default', | ||
| 'i-default', | ||
| 'i-enochian', | ||
| 'i-klingon', | ||
| 'i-klingon', | ||
| 'mn-Cyrl-MN', | ||
| 'mN-cYrL-Mn', | ||
| 'no-bok', | ||
| 'sl-IT-nedis', | ||
| 'sl-nedis', | ||
| 'sr-Latn-CS', | ||
| 'x-12345678-a', | ||
| 'x-fr-CH', | ||
| 'i-notexist', | ||
| 'En-Gb-Oed', | ||
| 'I-Ami', | ||
| 'I-Bnn', | ||
| 'I-Default', | ||
| 'I-Enochian', | ||
| 'I-Hak', | ||
| 'I-Klingon', | ||
| 'I-Lux', | ||
| 'I-Mingo', | ||
| 'I-Navajo', | ||
| 'I-Pwn', | ||
| 'I-Tao', | ||
| 'I-Tay', | ||
| 'I-Tsu', | ||
| 'Sgn-Be-Fr', | ||
| 'Sgn-Be-Nl', | ||
| 'Sgn-Ch-De', | ||
| 'art-lojban', | ||
| 'cel-gaulish', | ||
| 'en-boont', | ||
| 'en-scouse', | ||
| 'no-bok', | ||
| 'no-nyn', | ||
| 'zh-cmn', | ||
| 'zh-cmn-Hans', | ||
| 'zh-cmn-Hant', | ||
| 'zh-gan', | ||
| 'zh-guoyu', | ||
| 'zh-hakka', | ||
| 'zh-min', | ||
| 'zh-min-nan', | ||
| 'zh-wuu', | ||
| 'zh-xiang', | ||
| 'zh-yue', | ||
| 'ab-a-abc-a-abc', | ||
| 'en-a-bbb-a-ccc', | ||
| 'ab-c-abc-r-toto-c-abc', | ||
| 'zszLDm-sCVS-es-x-gn762vG-83-S-mlL', | ||
| 'IIJdFI-cfZv', | ||
| 'kbAxSgJ-685', | ||
| 'tbutP', | ||
| 'hDL-595', | ||
| 'dUf-iUjq-0hJ4P-5YkF-WD8fk', | ||
| 'FZAABA-FH', | ||
| 'xZ-lh-4QfM5z9J-1eG4-x-K-R6VPr2z', | ||
| 'Fyi', | ||
| 'SeI-DbaG', | ||
| 'ch-xwFn', | ||
| 'OeC-GPVI', | ||
| 'JLzvUSi', | ||
| 'Fxh-hLAs', | ||
| 'pKHzCP-sgaO-554', | ||
| 'eytqeW-hfgH-uQ', | ||
| 'ydn-zeOP-PR', | ||
| 'uoWmBM-yHCf-JE', | ||
| 'xwYem', | ||
| 'zie', | ||
| 'Re-wjSv-Ey-i-XE-E-JjWTEB8-f-DLSH-NVzLH-AtnFGWoH-SIDE', | ||
| 'Ri-063-c-u6v-ZfhkToTB-C-IFfmv-XT-j-rdyYFMhK-h-pY-D5-Oh6FqBhL-hcXt-v-WdpNx71-K-c74m4-eBTT7-JdH7Q1Z', | ||
| 'ji', | ||
| 'IM-487', | ||
| 'EPZ-zwcB', | ||
| 'GauwEcwo', | ||
| 'kDEP', | ||
| 'FwDYt-TNvo', | ||
| 'ottqP-KLES-x-9-i9', | ||
| 'fcflR-grQQ', | ||
| 'TvFwdu-kYhs', | ||
| 'WE-336', | ||
| 'MgxQa-ywEp-8lcW-7bvT-h-dP1Md-0h7-0Z3ir-K-Srkm-kA-7LXM-Z-whb2MiO-2mNsvbLm-W3O-4r-U-KceIxHdI-gvMVgUBV-2uRUni-J0-7C8yTK2', | ||
| 'Hyr-B-evMtVoB1-mtsVZf-vQMV-gM-I-rr-kvLzg-f-lAUK-Qb36Ne-Z-7eFzOD-mv6kKf-l-miZ7U3-k-XDGtNQG', | ||
| 'ybrlCpzy', | ||
| 'PTow-w-cAQ51-8Xd6E-cumicgt-WpkZv3NY-q-ORYPRy-v-A4jL4A-iNEqQZZ-sjKn-W-N1F-pzyc-xP5eWz-LmsCiCcZ', | ||
| 'ih-DlPR-PE', | ||
| 'Krf-362', | ||
| 'WzaD', | ||
| 'EPaOnB-gHHn', | ||
| 'XYta', | ||
| 'NZ-RgOO-tR', | ||
| 'at-FE', | ||
| 'Tpc-693', | ||
| 'YFp', | ||
| 'gRQrQULo', | ||
| 'pVomZ-585', | ||
| 'laSu-ZcAq-338', | ||
| 'gCW', | ||
| 'PydSwHRI-TYfF', | ||
| 'zKmWDD', | ||
| 'X-bCrL5RL', | ||
| 'HK', | ||
| 'YMKGcLY', | ||
| 'GDJ-nHYa-bw-X-ke-rohH5GfS-LdJKsGVe', | ||
| 'tfOxdau-yjge-489-a-oB-I8Csb-1ESaK1v-VFNz-N-FT-ZQyn-On2-I-hu-vaW3-jIQb-vg0U-hUl-h-dO6KuJqB-U-tde2L-P3gHUY-vnl5c-RyO-H-gK1-zDPu-VF1oeh8W-kGzzvBbW-yuAJZ', | ||
| 'LwDux', | ||
| 'Zl-072', | ||
| 'Ri-Ar', | ||
| 'vocMSwo-cJnr-288', | ||
| 'kUWq-gWfQ-794', | ||
| 'YyzqKL-273', | ||
| 'Xrw-ZHwH-841-9foT-ESSZF-6OqO-0knk-991U-9p3m-b-JhiV-0Kq7Y-h-cxphLb-cDlXUBOQ-X-4Ti-jty94yPp', | ||
| 'en-GB-oed', | ||
| 'LEuZl-so', | ||
| 'HyvBvFi-cCAl-X-irMQA-Pzt-H', | ||
| 'uDbsrAA-304', | ||
| 'wTS', | ||
| 'IWXS', | ||
| 'XvDqNkSn-jRDR', | ||
| 'gX-Ycbb-iLphEks-AQ1aJ5', | ||
| 'FbSBz-VLcR-VL', | ||
| 'JYoVQOP-Iytp', | ||
| 'gDSoDGD-lq-v-7aFec-ag-k-Z4-0kgNxXC-7h', | ||
| 'Bjvoayy-029', | ||
| 'qSDJd', | ||
| 'qpbQov', | ||
| 'fYIll-516', | ||
| 'GfgLyfWE-EHtB', | ||
| 'Wc-ZMtk', | ||
| 'cgh-VEYK', | ||
| 'WRZs-AaFd-yQ', | ||
| 'eSb-CpsZ-788', | ||
| 'YVwFU', | ||
| 'JSsHiQhr-MpjT-381', | ||
| 'LuhtJIQi-JKYt', | ||
| 'vVTvS-RHcP', | ||
| 'SY', | ||
| 'fSf-EgvQfI-ktWoG-8X5z-63PW', | ||
| 'NOKcy', | ||
| 'OjJb-550', | ||
| 'KB', | ||
| 'qzKBv-zDKk-589', | ||
| 'Jr', | ||
| 'Acw-GPXf-088', | ||
| 'WAFSbos', | ||
| 'HkgnmerM-x-e5-zf-VdDjcpz-1V6', | ||
| 'UAfYflJU-uXDc-YV', | ||
| 'x-CHsHx-VDcOUAur-FqagDTx-H-V0e74R', | ||
| 'uZIAZ-Xmbh-pd', | ||
| 'en-enx', | ||
| 'en-enx-eny-enz-latn-us', | ||
| 'fr-fra', | ||
| 'fr-Lat', | ||
| //ILL-FORMED | ||
| '-a', | ||
| 'a-', | ||
| 'a1-Hant-ZH', | ||
| 'aabbccddE', | ||
| 'a--b', | ||
| 'ab-123-abc', | ||
| 'ab-123-abc', | ||
| 'ab-123-abcd', | ||
| 'ab-123-abcd', | ||
| 'ab-1abc-abc', | ||
| 'ab-1abc-abc', | ||
| 'ab-1abc-abcd', | ||
| 'ab-1abc-abcd', | ||
| 'ab--ab', | ||
| 'ab--ab', | ||
| 'ab-a-b', | ||
| 'ab-a-b', | ||
| 'ab-ab-abc', | ||
| 'ab-ab-abc', | ||
| 'ab-ab-abcd', | ||
| 'ab-ab-abcd', | ||
| '-ab-abc', | ||
| '-ab-abc', | ||
| 'ab-abc-', | ||
| 'ab-abc-', | ||
| 'ab-abc-abc-abc-abc', | ||
| 'ab-abc-abc-abc-abc', | ||
| 'ab-abcd-abc', | ||
| 'ab-abcd-abc', | ||
| 'ab-abcde-abc', | ||
| 'ab-abcde-abc', | ||
| 'ab-abcde-abcd', | ||
| 'ab-abcde-abcd', | ||
| 'ab-a-x', | ||
| 'ab-a-x', | ||
| 'abcd-efg', | ||
| 'abcdefghi-012345678', | ||
| 'abcdefghi-012345678', | ||
| 'a-foo', | ||
| 'a-Hant-ZH', | ||
| 'a-value', | ||
| 'a-x', | ||
| 'b-fish', | ||
| 'en-enx-eny-enz-enw', | ||
| 'en-UK-oed', | ||
| 'en-US-Latn', | ||
| 'f', | ||
| 'f-Latn', | ||
| 'fr-Latn-F', | ||
| 'overlongone', | ||
| 'tlh-a-b-foo', | ||
| 'EdY-z_H791Xx6_m_kj', | ||
| 'qWt85_8S0-L_rbBDq0gl_m_O_zsAx_nRS', | ||
| 'VzyL2', | ||
| 'T_VFJq-L-0JWuH_u2_VW-hK-kbE', | ||
| 'u-t', | ||
| 'Q-f_ZVJXyc-doj_k-i', | ||
| 'JWB7gNa_K-5GB-25t_W-s-ZbGVwDu1-H3E', | ||
| 'b-2T-Qob_L-C9v_2CZxK86', | ||
| 'fQTpX_0_4Vg_L3L_g7VtALh2', | ||
| 'S-Z-E_J', | ||
| 'f6wsq-02_i-F', | ||
| '9_GcUPq_G', | ||
| 'QjsIy_9-0-7_Dv2yPV09_D-JXWXM', | ||
| 'D_se-f-k', | ||
| 'ON47Wv1_2_W', | ||
| 'f-z-R_s-ha', | ||
| 'N3APeiw_195_Bx2-mM-pf-Z-Ip5lXWa-5r', | ||
| 'IRjxU-E_6kS_D_b1b_H', | ||
| 'NB-3-5-AyW_FQ-9hB-TrRJg3JV_3C', | ||
| 'yF-3a_V_FoJQAHeL_Z-Mc-u', | ||
| 'n_w_bbunOG_1-s-tJMT5je', | ||
| 'Q-AEWE_X', | ||
| '57b1O_k_R6MU_sb', | ||
| 'hK_65J_i-o_SI-Y', | ||
| 'wB4B7u_5I2_I_NZPI', | ||
| 'J24Nb_q_d-zE', | ||
| 'v6-dHjJmvPS_IEb-x_A-O-i', | ||
| '8_8_dl-ZgBr84u-P-E', | ||
| 'nIn-xD7EVhe_C', | ||
| '5_N-6P_x7Of_Lo_6_YX_R', | ||
| '0_46Oo0sZ-YNwiU8Wr_d-M-pg1OriV', | ||
| 'laiY-5', | ||
| 'K-8Mdd-j_ila0sSpo_aO8_J', | ||
| 'wNATtSL-Cp4_gPa_fD41_9z', | ||
| 'H_FGz5V8_n6rrcoz0_1O6d-kH-7-N', | ||
| 'wDOrnHU-odqJ_vWl', | ||
| 'gP_qO-I-jH', | ||
| 'h', | ||
| 'dJ0hX-o_csBykEhU-F', | ||
| 'L-Vf7_BV_eRJ5goSF_Kp', | ||
| 'y-oF-chnavU-H', | ||
| '9FkG-8Q-8_v', | ||
| 'W_l_NDQqI-O_SFSAOVq', | ||
| 'kDG3fzXw', | ||
| 't-nsSp-7-t-mUK2', | ||
| 'Yw-F', | ||
| '1-S_3_l', | ||
| 'u-v_brn-Y', | ||
| '4_ft_3ZPZC5lA_D', | ||
| 'n_dR-QodsqJnh_e', | ||
| 'Hwvt-bSwZwj_KL-hxg0m-3_hUG', | ||
| 'mQHzvcV-UL-o2O_1KhUJQo_G2_uryk3-a', | ||
| 'b-UTn33HF', | ||
| 'r-Ep-jY-aFM_N_H', | ||
| 'K-k-krEZ0gwD_k_ua-9dm3Oy-s_v', | ||
| 'XS_oS-p', | ||
| 'EIx_h-zf5', | ||
| 'p_z-0_i-omQCo3B', | ||
| '1_q0N_jo_9', | ||
| '0Ai-6-S', | ||
| 'L-LZEp_HtW', | ||
| 'Zj-A4JD_2A5Aj7_b-m3', | ||
| 'x', | ||
| 'p-qPuXQpp_d-jeKifB-c-7_G-X', | ||
| 'X94cvJ_A', | ||
| 'F2D25R_qk_W-w_Okf_kx', | ||
| 'rc-f', | ||
| 'D', | ||
| 'gD_WrDfxmF-wu-E-U4t', | ||
| 'Z_BN9O4_D9-D_0E_KnCwZF-84b-19', | ||
| 'T-8_g-u-0_E', | ||
| 'lXTtys9j_X_A_m-vtNiNMw_X_b-C6Nr', | ||
| 'V_Ps-4Y-S', | ||
| 'X5wGEA', | ||
| 'mIbHFf_ALu4_Jo1Z1', | ||
| 'ET-TacYx_c', | ||
| 'Z-Lm5cAP_ri88-d_q_fi8-x', | ||
| 'rTi2ah-4j_j_4AlxTs6m_8-g9zqncIf-N5', | ||
| 'FBaLB85_u-0NxhAy-ZU_9c', | ||
| 'x_j_l-5_aV95_s_tY_jp4', | ||
| 'PL768_D-m7jNWjfD-Nl_7qvb_bs_8_Vg', | ||
| '9-yOc-gbh', | ||
| '6DYxZ_SL-S_Ye', | ||
| 'ZCa-U-muib-6-d-f_oEh_O', | ||
| 'Qt-S-o8340F_f_aGax-c-jbV0gfK_p', | ||
| 'WE_SzOI_OGuoBDk-gDp', | ||
| 'cs-Y_9', | ||
| 'm1_uj', | ||
| 'Y-ob_PT', | ||
| 'li-B', | ||
| 'f-2-7-9m_f8den_J_T_d', | ||
| 'p-Os0dua-H_o-u', | ||
| 'L', | ||
| 'rby-w' | ||
| ]; | ||
| const LanguageTag = require('../'); | ||
| const async = require('async'); | ||
| const assert = require('assert'); | ||
| function testParse(tag) { | ||
| return function() { | ||
| it(tag, function(done) { | ||
| try { | ||
| var t = new LanguageTag(tag); | ||
| if (!t.invalid) { | ||
| // if it's valid, it has to at least have a language or privateuse | ||
| assert(t.language || t.privateuse); | ||
| } | ||
| done(); | ||
| } catch (err) { | ||
| done(err); | ||
| } | ||
| }); | ||
| }; | ||
| } | ||
| describe('Liberal Parsing Tests', function() { | ||
| // everything should parse, even invalid tags, | ||
| // that doesn't make the tags valid tho | ||
| async.parallel( | ||
| valid.map(testParse), | ||
| function() {}); | ||
| async.parallel( | ||
| invalid.map(testParse), | ||
| function() {}); | ||
| async.parallel( | ||
| wellformed.map(testParse), | ||
| function() {}); | ||
| }); | ||
| describe('Minimal Valid Example', function() { | ||
| it('All asserts should pass', function() { | ||
| var tag = new LanguageTag('en-Latn-US'); | ||
| assert.equal(tag.language,'en'); | ||
| assert.equal(tag.script,'Latn'); | ||
| assert.equal(tag.region,'US'); | ||
| assert.equal(tag.variant,undefined); | ||
| assert.equal(tag.minimal,'en-US'); | ||
| assert(tag.matches('en-*')); | ||
| assert(tag.minimal.suitableFor('en-US')); | ||
| assert.equal(tag.truncate().toString(),'en-Latn-US'); | ||
| assert.equal(tag.truncate({script:false}).toString(), 'en-US'); | ||
| }); | ||
| }); |
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
Unidentified License
LicenseSomething that seems like a license was found, but its contents could not be matched with a known license.
Found 1 instance in 1 package
No contributors or author data
MaintenancePackage does not specify a list of contributors or an author in package.json.
Found 1 instance in 1 package
Unidentified License
LicenseSomething that seems like a license was found, but its contents could not be matched with a known license.
Found 1 instance in 1 package
2
-33.33%49
11.36%12130
-49.34%3
50%4
-33.33%343
-59.31%1
Infinity%