New Research: Supply Chain Attack on Axios Pulls Malicious Dependency from npm.Details →
Socket
Book a DemoSign in
Socket

node-phony

Package Overview
Dependencies
Maintainers
1
Versions
4
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

node-phony - npm Package Compare versions

Comparing version
1.2.0
to
1.2.1
+487
lib/phony.js
/**
* Library for translating to/from the phonetic alphabet.
*
* @module phony
* @version 1.2.1
* @copyright Alasdair Mercer 2015
* @license MIT
*/
(function(factory) {
'use strict';
/**
* The root object that has been determined for the current environment (browser, server, <code>WebWorker</code>).
*
* @access private
* @type {*}
*/
var root = (typeof self === 'object' && self.self === self && self) ||
(typeof global === 'object' && global.global === global && global);
if (typeof define === 'function' && define.amd) {
// Defines for AMD but also exports to root for those expecting global phony
define(function() {
root.phony = factory(root);
return root.phony;
});
} else if (typeof module !== 'undefined' && module.exports) {
// Supports Node.js and the CommonJS patterns
exports = module.exports = factory(root);
} else {
// Falls back on browser support
root.phony = factory(root);
}
}(function(root) {
'use strict';
/**
* A phonetic alphabet configuration.
*
* @typedef {Object} PhoneticAlphabet
* @property {Object.<String, String>} characters - The map of characters and their phonetic counterparts.
* @property {String} [fallback] - The name of the fallback alphabet.
*/
/**
* Options to be passed to the primary {@linkcode phony} methods.
*
* @typedef {Object} PhonyOptions
* @property {String} [alphabet="itu"] - The default name of the alphabet to be used for the translation.
* @property {Boolean} [cache=true] - Whether a cache should be used for built alphabets to to improve performance.
* This cache can be disabled and/or cleared to avoid when modifying alphabets.
* @property {String} [letterSplitter=" "] - The default string to be used to split alphabetic letters (may be passed
* to <code>RegExp</code> constructor).
* @property {String} [wordSplitter="space"] - The default string to be used to split words (may be passed to
* <code>RegExp</code> constructor).
*/
/**
* The main <code>phony</code> object to be exported.
*
* @access public
* @type {Object}
* @alias module:phony
*/
var phony = {};
/**
* The previous value of the <code>phony</code> variable.
*
* @access private
* @type {*}
*/
var previousPhony = root.phony;
/**
* A cache of built alphabets that can be used to improve performance and avoid unnecessary rebuilds of the same
* alphabets.
* <p/>
* This cache can be cleared at any time by using {@linkcode phony.clearCache} or bypassed on a case-by-case basis
* via the <code>cache</code> option.
*
* @access private
* @type {Object.<String, Object<String, String>>}
*/
var alphabetCache = {};
/**
* Populates the specified <code>target</code> mapping with key/value pairs extracted from the character mapping from
* the named alphabet those from the fallback chain, where applicable.
* <p/>
* The key/value pairs are determined by the return value of the <code>iterator</code> provided, which should provide
* a simple two-element array where the first element will be used as the key and the second as the value. However,
* that key/value pair will only be set on <code>target</code> if a previous alphabet hasn't already set the same
* key.
*
* @param {Object.<String, String>} target - the mapping to be populated
* @param {String} name - the name of the alphabet to be built
* @param {String} method - the name of the method responsible for building this alphabet (used for caching purposes)
* @param {Boolean} cache - <code>true</code> to check and use a previously built and cached alphabet or caching this
* one after building it if not previously cached; otherwise <code>false</code>
* @param {Function} iterator - iterator which will be passed a character and phonetic mapping and needs to return a
* two-element array for the key/value mapping to be set on <code>target</code>
* @returns {Object.<String, String>} The populated <code>target</code>.
* @access private
*/
function buildAlphabet(target, name, method, cache, iterator) {
var alphabet = phony.alphabets[name];
if (!alphabet) {
return target;
}
var cacheHash = name + ':' + method;
if (cache && alphabetCache[cacheHash]) {
return alphabetCache[cacheHash];
}
each(alphabet.characters, function(character, phonetic) {
var keyValue = iterator(character, phonetic);
var key = keyValue[0];
var value = keyValue[1];
if (!target.hasOwnProperty(key)) {
target[key] = value;
}
});
buildAlphabet(target, alphabet.fallback, method, false, iterator);
if (cache) {
alphabetCache[cacheHash] = target;
}
return target;
}
/**
* Iterates over a given <code>object</code>.
* <p/>
* If <code>object</code> is an array, each element is yielded in turn to the specified <code>iterator</code>
* function; otherwise this is done for the key/value mapping of the hash.
*
* @param {Array|Object} [object] - the object or array to be iterated over
* @param {Function} iterator - the iterator function to be passed index/element if <code>object</code> is an array
* or key/value if it is a hash
* @returns {Array|Object} The specified <code>object</code>.
* @access private
*/
function each(object, iterator) {
if (!object) {
return object;
}
var key;
var index;
var length = object.length;
if (length === +length) {
for (index = 0; index < length; index++) {
iterator(object[index], index, object);
}
} else {
for (key in object) {
if (object.hasOwnProperty(key)) {
iterator(key, object[key], object);
}
}
}
return object;
}
/**
* Returns the given <code>options</code> with all of the <code>defaults</code> applied.
* <p/>
* This function <i>will change</i> the specified <code>options</code>.
*
* @param {PhonyOptions} [options={}] - the options to be extended
* @param {PhonyOptions} defaults - the default options
* @returns {PhonyOptions} The specified <code>options</code> with modifications.
* @access private
*/
function getOptions(options, defaults) {
options = options || {};
for (var key in defaults) {
if (typeof options[key] === 'undefined') {
options[key] = defaults[key];
}
}
options.alphabet = options.alphabet.toLocaleLowerCase();
options.wordSplitter = options.wordSplitter.toLocaleLowerCase();
return options;
}
/**
* Prepares a given string to simplify translation.
*
* @param {String} str - the string to prepare
* @param {String} [transformer] - the name of a <code>String.prototype</code> method to be used to transform
* <code>str</code> prior to preparation
* @param {String} wordSplitter - the string used to split words (will be passed to <code>RegExp</code> constructor)
* @param {String} letterSplitter - the string used to split alphabetic letters
* @returns {Array.<Array.<String>>} A multi-dimensional array of words and their alphabetic letters contained
* within.
* @access private
*/
function prepare(str, transformer, wordSplitter, letterSplitter) {
if (typeof str !== 'string') {
throw new TypeError('Invalid value type: ' + typeof str);
}
if (transformer && typeof str[transformer] === 'function') {
str = str[transformer]();
}
var rWordSplitter = new RegExp(wordSplitter + '|[\\n\\r]+', 'gi');
var result = str.trim().split(rWordSplitter);
each(result, function(word, i) {
result[i] = word.split(letterSplitter);
});
return result;
}
/**
* Transforms a given string in to title case.
*
* @param {String} str - the string to be transformed
* @returns {String} <code>str</code> in title case form.
* @access private
*/
function toTitleCase(str) {
return str[0].toLocaleUpperCase() + str.substring(1).toLocaleLowerCase();
}
/**
* The current version of {@linkcode phony}.
*
* @access public
* @static
* @constant
* @type {String}
*/
phony.VERSION = '1.2.1';
/**
* The configurations for the initially supported phonetic alphabets.
*
* @access public
* @static
* @type {Object.<String, PhoneticAlphabet>}
* @property {PhoneticAlphabet} ansi - The American National Standards Institute (ANSI) phonetic alphabet
* configuration.
* @property {PhoneticAlphabet} faa - The Federal Aviation Administration (FAA) phonetic alphabet configuration.
* @property {PhoneticAlphabet} icao - The International Civil Aviation Organization (ICAO) phonetic alphabet
* configuration.
* @property {PhoneticAlphabet} itu - The International Telecommunication Union (ITU) phonetic alphabet
* configuration.
*/
phony.alphabets = {
ansi: {
fallback: 'itu',
characters: {
'A': 'alpha',
'J': 'juliet'
}
},
faa: {
fallback: 'itu',
characters: {
'0': 'zero',
'1': 'one',
'2': 'two',
'3': 'three',
'4': 'four',
'5': 'five',
'6': 'six',
'7': 'seven',
'8': 'eight',
'9': 'nine'
}
},
icao: {
fallback: 'faa',
characters: {
'9': 'niner'
}
},
itu: {
characters: {
'A': 'alfa',
'B': 'bravo',
'C': 'charlie',
'D': 'delta',
'E': 'echo',
'F': 'foxtrot',
'G': 'golf',
'H': 'hotel',
'I': 'india',
'J': 'juliett',
'K': 'kilo',
'L': 'lima',
'M': 'mike',
'N': 'november',
'O': 'oscar',
'P': 'papa',
'Q': 'quebec',
'R': 'romeo',
'S': 'sierra',
'T': 'tango',
'U': 'uniform',
'V': 'victor',
'W': 'whiskey',
'X': 'x-ray',
'Y': 'yankee',
'Z': 'zulu',
'0': 'nadazero',
'1': 'unaone',
'2': 'bissotwo',
'3': 'terrathree',
'4': 'kartefour',
'5': 'pantafive',
'6': 'soxisix',
'7': 'setteseven',
'8': 'oktoeight',
'9': 'novenine',
'.': 'stop',
'-': 'dash'
}
}
};
/**
* The default values to be used when options are not specified or incomplete.
*
* @access public
* @static
* @type {PhonyOptions}
*/
phony.defaults = {
alphabet: 'itu',
cache: true,
letterSplitter: ' ',
wordSplitter: 'space'
};
/**
* Clears any previously cached built alphabets.
* <p/>
* This can be useful for when modifications have been made to the alphabet mapping.
*
* @returns {Object} A reference to this {@linkcode phony} for chaining.
* @access public
* @static
*/
phony.clearCache = function() {
alphabetCache = {};
return this;
};
/**
* Translates the <code>message</code> provided <i>from</i> the phonetic alphabet.
* <p/>
* The message may not be translated correctly if the some of the options used to translate the message originally
* are not the same as those in <code>options</code>.
*
* @param {String} [message=""] - the string to be translated from the phonetic alphabet
* @param {PhonyOptions} [options={}] - the options to be used
* @returns {String} The translation from the specified phonetic alphabet <code>message</code>.
* @access public
* @static
*/
phony.from = function(message, options) {
message = message || '';
options = getOptions(options, phony.defaults);
var result = '';
var value = prepare(message, 'toLocaleLowerCase', options.wordSplitter, options.letterSplitter);
// Ensures message was prepared successfully and that a valid alphabet was specified
if (!value || !phony.alphabets[options.alphabet]) {
return result;
}
var alphabet = buildAlphabet({}, options.alphabet, 'from', options.cache, function(character, phonetic) {
return [phonetic, character];
});
// Iterates over each word
each(value, function(word, i) {
// Inserts space between each word
if (i > 0) {
result += ' ';
}
// Iterates over each phonetic representation in the word
each(word, function(phonetic) {
// Reverse engineers character from phonetic representation
var character = alphabet[phonetic];
// Checks if character is supported
if (typeof character === 'string') {
result += character;
}
});
});
return result;
};
/**
* Translates the <code>message</code> provided <i>to</i> the phonetic alphabet.
*
* @param {String} [message=""] - the string to be translated to the phonetic alphabet
* @param {PhonyOptions} [options={}] - the options to be used
* @returns {String} The phonetic alphabet translation of the specified <code>message</code>.
* @access public
* @static
*/
phony.to = function(message, options) {
message = message || '';
options = getOptions(options, phony.defaults);
var letterSplitter = options.letterSplitter;
var result = '';
var value = prepare(message, 'toLocaleUpperCase', '\\s+', '');
var wordSplitter = letterSplitter + toTitleCase(options.wordSplitter) + letterSplitter;
// Ensures message was prepared successfully and that a valid alphabet was specified
if (!value || !phony.alphabets[options.alphabet]) {
return result;
}
var alphabet = buildAlphabet({}, options.alphabet, 'to', options.cache, function(character, phonetic) {
return [character, phonetic];
});
// Iterates over each word
each(value, function(word, i) {
// Inserts wordSplitter option between each word
if (i > 0) {
result += wordSplitter;
}
// Iterates over each character in the word
each(word, function(character, j) {
// Reverse engineers character from phonetic representation
var phonetic = alphabet[character];
// Checks if phonetic representation is supported
if (typeof phonetic === 'string') {
// Inserts letterSplitter option between each character
if (j > 0) {
result += letterSplitter;
}
result += toTitleCase(phonetic);
}
});
});
return result;
};
/**
* Runs phony in <i>no conflict</i> mode, returning the <code>phony</code> global variable to it's previous owner, if
* any.
*
* @returns {Object} A reference to this {@linkcode phony}.
* @access public
* @static
*/
phony.noConflict = function() {
root.phony = previousPhony;
return this;
};
return phony;
}));
+13
-0

@@ -0,1 +1,11 @@

## Version 1.2.1, 2015.06.14
* [#9](https://github.com/neocotic/phony.js/issues/9): Improve performance of core functions
* [#9](https://github.com/neocotic/phony.js/issues/9): Add new `cache` option (enabled by default) to core functions to bypass alphabet caching
* [#9](https://github.com/neocotic/phony.js/issues/9): Add new `phony.clearCache` function to purge alphabet cache at any time
* [#15](https://github.com/neocotic/phony.js/issues/15): Remove copy of source file from `dist` directory
* [#16](https://github.com/neocotic/phony.js/issues/16): Switch badges in `README.md` to use [Shields.io][10]
* [#17](https://github.com/neocotic/phony.js/issues/17): Switch from [Code Climate][11] to [Coveralls][12] for code coverage
* Rename `src` directory to `lib`
## Version 1.2.0, 2015.06.06

@@ -35,1 +45,4 @@

[9]: http://editorconfig.org
[10]: http://shields.io
[11]: https://codeclimate.com
[12]: https://coveralls.io
+5
-5
{
"name": "node-phony",
"version": "1.2.0",
"version": "1.2.1",
"description": "Library for translating to/from the phonetic alphabet",

@@ -34,3 +34,2 @@ "homepage": "http://neocotic.com/phony.js",

"devDependencies": {
"codeclimate-test-reporter": "^0.0.4",
"expect.js": "^0.3.1",

@@ -44,3 +43,4 @@ "grunt": "^0.4.5",

"grunt-contrib-watch": "^0.6.1",
"grunt-eslint": "^13.0.0",
"grunt-coveralls": "^1.0.0",
"grunt-eslint": "^14.0.0",
"grunt-jsdoc": "^0.6.7",

@@ -52,5 +52,5 @@ "grunt-mocha-test": "^0.12.7",

},
"main": "src/phony.js",
"main": "lib/phony.js",
"scripts": {
"codeclimate": "codeclimate < coverage/lcov.info",
"coveralls": "grunt coveralls",
"test": "grunt test"

@@ -57,0 +57,0 @@ },

+35
-15

@@ -16,7 +16,7 @@ ```

[![Build Status](https://travis-ci.org/neocotic/phony.js.svg?branch=develop)][1]
[![Code Climate](https://codeclimate.com/github/neocotic/phony.js/badges/gpa.svg)][10]
[![Test Coverage](https://codeclimate.com/github/neocotic/phony.js/badges/coverage.svg)][11]
[![Dependency Status](https://gemnasium.com/neocotic/phony.js.svg)][4]
[![Built with Grunt](https://cdn.gruntjs.com/builtwith.png)][5]
[![Build Status](https://img.shields.io/travis/neocotic/phony.js/develop.svg?style=flat-square)][1]
[![Test Coverage](https://img.shields.io/coveralls/neocotic/phony.js/develop.svg?style=flat-square)][10]
[![Dependency Status](https://img.shields.io/david/dev/neocotic/phony.js.svg?style=flat-square)][4]
[![License](https://img.shields.io/github/license/neocotic/phony.js.svg?style=flat-square)][9]
[![Release](https://img.shields.io/github/tag/neocotic/phony.js.svg?style=flat-square)][5]

@@ -44,7 +44,8 @@ ## Install

| Option | Description | Default |
| -------------- | -------------------------------------------------------- | --------- |
| alphabet | Name of the alphabet to be used to translate the message | `"itu"` |
| letterSplitter | Sequence of characters to split letters | `" "` |
| wordSplitter | Sequence of characters to split words | `"space"` |
| Option | Description | Default |
| -------------- | ------------------------------------------------------------ | --------- |
| alphabet | Name of the alphabet to be used to translate the message | `"itu"` |
| cache | Whether to cache built alphabets when calling `from` or `to` | `true` |
| letterSplitter | Sequence of characters to split letters | `" "` |
| wordSplitter | Sequence of characters to split words | `"space"` |

@@ -110,2 +111,20 @@ It's important to note that the same options should be used in order for bidirectional translations to work. Some of

#### `clearCache()`
Clears any previously built alphabets that may have been cached by `phony.from` and/or `phony.to`. This can be useful
when making modifications to alphabets and having them picked up.
``` javascript
phony.to('SOS');
//=> "Sierra Oscar Sierra"
phony.alphabets.itu.characters['O'] = 'Oompa';
phony.clearCache();
phony.to('SOS');
//=> "Sierra Oompa Sierra"
```
The cache can also be bypassed by using the `cache` option.
#### `defaults`

@@ -126,2 +145,3 @@

#### `noConflict()`
Returns `phony` in a no-conflict state, reallocating the `phony` global variable name to its previous owner, where

@@ -142,2 +162,3 @@ possible.

#### `VERSION`
The current version of `phony`.

@@ -147,3 +168,3 @@

phony.VERSION;
//=> "1.2.0"
//=> "1.2.1"
```

@@ -173,4 +194,4 @@

[3]: https://en.wikipedia.org/wiki/NATO_phonetic_alphabet
[4]: https://gemnasium.com/neocotic/phony.js
[5]: http://gruntjs.com
[4]: https://david-dm.org/neocotic/phony.js
[5]: https://github.com/neocotic/phony.js
[6]: https://github.com/neocotic/phony.js/issues

@@ -180,3 +201,2 @@ [7]: https://github.com/neocotic/phony.js/blob/master/AUTHORS.md

[9]: https://github.com/neocotic/phony.js/blob/master/LICENSE.md
[10]: https://codeclimate.com/github/neocotic/phony.js
[11]: https://codeclimate.com/github/neocotic/phony.js/coverage
[10]: https://coveralls.io/r/neocotic/phony.js
languages:
JavaScript: true
/**
* Library for translating to/from the phonetic alphabet.
*
* @module phony
* @version 1.2.0
* @copyright Alasdair Mercer 2015
* @license MIT
*/
(function(factory) {
'use strict';
/**
* The root object that has been determined for the current environment (browser, server, <code>WebWorker</code>).
*
* @access private
* @type {*}
*/
var root = (typeof self === 'object' && self.self === self && self) ||
(typeof global === 'object' && global.global === global && global);
if (typeof define === 'function' && define.amd) {
// Defines for AMD but also exports to root for those expecting global phony
define(function() {
root.phony = factory(root);
return root.phony;
});
} else if (typeof module !== 'undefined' && module.exports) {
// Supports Node.js and the CommonJS patterns
exports = module.exports = factory(root);
} else {
// Falls back on browser support
root.phony = factory(root);
}
}(function(root) {
'use strict';
/**
* A phonetic alphabet configuration.
*
* @typedef {Object} PhoneticAlphabet
* @property {Object.<String, String>} characters - The map of characters and their phonetic counterparts.
* @property {String} [fallback] - The name of the fallback alphabet.
*/
/**
* Options to be passed to the primary {@linkcode phony} methods.
*
* @typedef {Object} PhonyOptions
* @property {String} [alphabet="itu"] - The default name of the alphabet to be used for the translation.
* @property {String} [letterSplitter=" "] - The default string to be used to split alphabetic letters (may be passed
* to <code>RegExp</code> constructor).
* @property {String} [wordSplitter="space"] - The default string to be used to split words (may be passed to
* <code>RegExp</code> constructor).
*/
/**
* The main <code>phony</code> object to be exported.
*
* @access public
* @type {Object}
* @alias module:phony
*/
var phony = {};
/**
* The previous value of the <code>phony</code> variable.
*
* @access private
* @type {*}
*/
var previousPhony = root.phony;
/**
* Iterates over a given <code>object</code>.
* <p/>
* If <code>object</code> is an array, each element is yielded in turn to the specified <code>iterator</code>
* function; otherwise this is done for the key/value mapping of the hash.
*
* @param {Array|Object} [object] - the object or array to be iterated over
* @param {Function} iterator - the iterator function to be passed index/element if <code>object</code> is an array
* or key/value if it is a hash
* @returns {Array|Object} The specified <code>object</code>.
* @access private
*/
function each(object, iterator) {
if (!object) {
return object;
}
var key;
var index;
var length = object.length;
if (length === +length) {
for (index = 0; index < length; index++) {
iterator(object[index], index, object);
}
} else {
for (key in object) {
if (object.hasOwnProperty(key)) {
iterator(key, object[key], object);
}
}
}
return object;
}
/**
* Returns the character mapped to the specified <code>phonetic</code> from the alphabet with the given
* <code>name</code>, where possible.
* <p/>
* If the named alphabet does not contain a mapping for <code>phonetic</code> but has a fallback alphabet configured,
* then that alphabet will be checked.
*
* @param {String} name - the name of the alphabet
* @param {String} phonetic - the phonetic string whose alphabet character mapping is to be returned
* @returns {String} The character mapped to <code>phonetic</code> for the named alphabet or it's configured
* fallback.
* @access private
*/
function getAlphabetCharacter(name, phonetic) {
var alphabet = phony.alphabets[name];
var character;
if (alphabet) {
each(alphabet.characters, function(ch, ph) {
if (ph === phonetic) {
character = ch;
}
});
if (typeof character === 'undefined' && typeof alphabet.fallback !== 'undefined') {
character = getAlphabetCharacter(alphabet.fallback, phonetic);
}
}
return character;
}
/**
* Returns the phonetic mapped to the specified <code>character</code> from the alphabet with the given
* <code>name</code>, where possible.
* <p/>
* If the named alphabet does not contain a mapping for <code>character</code> but has a fallback alphabet
* configured, then that alphabet will be checked.
*
* @param {String} name - the name of the alphabet
* @param {String} character - the character whose alphabet phonetic mapping is to be returned
* @returns {String} The phonetic mapped to <code>character</code> for the named alphabet or it's configured
* fallback.
* @access private
*/
function getAlphabetPhonetic(name, character) {
var alphabet = phony.alphabets[name];
var phonetic = alphabet.characters && alphabet.characters[character];
if (typeof phonetic === 'undefined' && alphabet && typeof alphabet.fallback !== 'undefined') {
phonetic = getAlphabetPhonetic(alphabet.fallback, character);
}
return phonetic;
}
/**
* Returns the given <code>options</code> with all of the <code>defaults</code> applied.
* <p/>
* This function <i>will change</i> the specified <code>options</code>.
*
* @param {PhonyOptions} [options={}] - the options to be extended
* @param {PhonyOptions} defaults - the default options
* @returns {PhonyOptions} The specified <code>options</code> with modifications.
* @access private
*/
function getOptions(options, defaults) {
options = options || {};
for (var key in defaults) {
if (typeof options[key] === 'undefined') {
options[key] = defaults[key];
}
}
options.alphabet = options.alphabet.toLocaleLowerCase();
options.wordSplitter = options.wordSplitter.toLocaleLowerCase();
return options;
}
/**
* Prepares a given string to simplify translation.
*
* @param {String} str - the string to prepare
* @param {String} [transformer] - the name of a <code>String.prototype</code> method to be used to transform
* <code>str</code> prior to preparation
* @param {String} wordSplitter - the string used to split words (will be passed to <code>RegExp</code> constructor)
* @param {String} letterSplitter - the string used to split alphabetic letters
* @returns {Array.<Array.<String>>} A multi-dimensional array of words and their alphabetic letters contained
* within.
* @access private
*/
function prepare(str, transformer, wordSplitter, letterSplitter) {
if (typeof str !== 'string') {
throw new TypeError('Invalid value type: ' + typeof str);
}
if (transformer && typeof str[transformer] === 'function') {
str = str[transformer]();
}
var rWordSplitter = new RegExp(wordSplitter + '|[\\n\\r]+', 'gi');
var result = str.trim().split(rWordSplitter);
each(result, function(word, i) {
result[i] = word.split(letterSplitter);
});
return result;
}
/**
* Transforms a given string in to title case.
*
* @param {String} str - the string to be transformed
* @returns {String} <code>str</code> in title case form.
* @access private
*/
function toTitleCase(str) {
return str[0].toLocaleUpperCase() + str.substring(1).toLocaleLowerCase();
}
/**
* The current version of {@linkcode phony}.
*
* @access public
* @static
* @constant
* @type {String}
*/
phony.VERSION = '1.2.0';
/**
* The configurations for the initially supported phonetic alphabets.
*
* @access public
* @static
* @type {Object.<String, PhoneticAlphabet>}
* @property {PhoneticAlphabet} ansi - The American National Standards Institute (ANSI) phonetic alphabet
* configuration.
* @property {PhoneticAlphabet} faa - The Federal Aviation Administration (FAA) phonetic alphabet configuration.
* @property {PhoneticAlphabet} icao - The International Civil Aviation Organization (ICAO) phonetic alphabet
* configuration.
* @property {PhoneticAlphabet} itu - The International Telecommunication Union (ITU) phonetic alphabet
* configuration.
*/
phony.alphabets = {
ansi: {
fallback: 'itu',
characters: {
'A': 'alpha',
'J': 'juliet'
}
},
faa: {
fallback: 'itu',
characters: {
'0': 'zero',
'1': 'one',
'2': 'two',
'3': 'three',
'4': 'four',
'5': 'five',
'6': 'six',
'7': 'seven',
'8': 'eight',
'9': 'nine'
}
},
icao: {
fallback: 'faa',
characters: {
'9': 'niner'
}
},
itu: {
characters: {
'A': 'alfa',
'B': 'bravo',
'C': 'charlie',
'D': 'delta',
'E': 'echo',
'F': 'foxtrot',
'G': 'golf',
'H': 'hotel',
'I': 'india',
'J': 'juliett',
'K': 'kilo',
'L': 'lima',
'M': 'mike',
'N': 'november',
'O': 'oscar',
'P': 'papa',
'Q': 'quebec',
'R': 'romeo',
'S': 'sierra',
'T': 'tango',
'U': 'uniform',
'V': 'victor',
'W': 'whiskey',
'X': 'x-ray',
'Y': 'yankee',
'Z': 'zulu',
'0': 'nadazero',
'1': 'unaone',
'2': 'bissotwo',
'3': 'terrathree',
'4': 'kartefour',
'5': 'pantafive',
'6': 'soxisix',
'7': 'setteseven',
'8': 'oktoeight',
'9': 'novenine',
'.': 'stop',
'-': 'dash'
}
}
};
/**
* The default values to be used when options are not specified or incomplete.
*
* @access public
* @static
* @type {PhonyOptions}
*/
phony.defaults = {
alphabet: 'itu',
letterSplitter: ' ',
wordSplitter: 'space'
};
/**
* Translates the <code>message</code> provided <i>from</i> the phonetic alphabet.
* <p/>
* The message may not be translated correctly if the some of the options used to translate the message originally
* are not the same as those in <code>options</code>.
*
* @param {String} [message=""] - the string to be translated from the phonetic alphabet
* @param {PhonyOptions} [options={}] - the options to be used
* @returns {String} The translation from the specified phonetic alphabet <code>message</code>.
* @access public
* @static
*/
phony.from = function(message, options) {
message = message || '';
options = getOptions(options, phony.defaults);
var result = '';
var value = prepare(message, 'toLocaleLowerCase', options.wordSplitter, options.letterSplitter);
// Ensures message was prepared successfully and that a valid alphabet was specified
if (!value || !phony.alphabets[options.alphabet]) {
return result;
}
// Iterates over each word
each(value, function(word, i) {
// Inserts space between each word
if (i > 0) {
result += ' ';
}
// Iterates over each phonetic representation in the word
each(word, function(phonetic) {
// Reverse engineers character from phonetic representation
var character = getAlphabetCharacter(options.alphabet, phonetic);
// Checks if character is supported
if (typeof character === 'string') {
result += character;
}
});
});
return result;
};
/**
* Translates the <code>message</code> provided <i>to</i> the phonetic alphabet.
*
* @param {String} [message=""] - the string to be translated to the phonetic alphabet
* @param {PhonyOptions} [options={}] - the options to be used
* @returns {String} The phonetic alphabet translation of the specified <code>message</code>.
* @access public
* @static
*/
phony.to = function(message, options) {
message = message || '';
options = getOptions(options, phony.defaults);
var letterSplitter = options.letterSplitter;
var result = '';
var value = prepare(message, 'toLocaleUpperCase', '\\s+', '');
var wordSplitter = letterSplitter + toTitleCase(options.wordSplitter) + letterSplitter;
// Ensures message was prepared successfully and that a valid alphabet was specified
if (!value || !phony.alphabets[options.alphabet]) {
return result;
}
// Iterates over each word
each(value, function(word, i) {
// Inserts wordSplitter option between each word
if (i > 0) {
result += wordSplitter;
}
// Iterates over each character in the word
each(word, function(character, j) {
// Reverse engineers character from phonetic representation
var phonetic = getAlphabetPhonetic(options.alphabet, character);
// Checks if phonetic representation is supported
if (typeof phonetic === 'string') {
// Inserts letterSplitter option between each character
if (j > 0) {
result += letterSplitter;
}
result += toTitleCase(phonetic);
}
});
});
return result;
};
/**
* Runs phony in <i>no conflict</i> mode, returning the <code>phony</code> global variable to it's previous owner, if
* any.
*
* @returns {Object} A reference to this {@linkcode phony}.
* @access public
* @static
*/
phony.noConflict = function() {
root.phony = previousPhony;
return this;
};
return phony;
}));