{ "version": 3, "sources": ["../../node_modules/src/utils/typeOf.js", "../../node_modules/src/utils/isEmpty.js", "../../node_modules/src/utils/isCharInRange.js", "../../node_modules/src/constants.ts", "../../node_modules/src/utils/isCharJapanese.js", "../../node_modules/src/isJapanese.js", "../../node_modules/node_modules/memoize-one/dist/memoize-one.esm.js", "../../node_modules/node_modules/dequal/dist/index.mjs", "../../node_modules/src/utils/mergeWithDefaultOptions.js", "../../node_modules/src/utils/kanaMapping.js", "../../node_modules/src/utils/romajiToKanaMap.js", "../../node_modules/src/utils/isCharUpperCase.js", "../../node_modules/src/utils/isCharLongDash.js", "../../node_modules/src/utils/isCharSlashDot.js", "../../node_modules/src/utils/isCharHiragana.js", "../../node_modules/src/utils/hiraganaToKatakana.js", "../../node_modules/src/toKana.js", "../../node_modules/src/utils/dom.js", "../../node_modules/src/utils/logInputEvents.js", "../../node_modules/src/bind.js", "../../node_modules/src/unbind.js", "../../node_modules/src/utils/isCharRomaji.js", "../../node_modules/src/isRomaji.js", "../../node_modules/src/utils/isCharKatakana.js", "../../node_modules/src/utils/isCharKana.js", "../../node_modules/src/isKana.js", "../../node_modules/src/isHiragana.js", "../../node_modules/src/isKatakana.js", "../../node_modules/src/utils/isCharIterationMark.js", "../../node_modules/src/utils/isCharKanji.js", "../../node_modules/src/isKanji.js", "../../node_modules/src/isMixed.js", "../../node_modules/src/utils/katakanaToHiragana.js", "../../node_modules/src/utils/kanaToRomajiMap.js", "../../node_modules/src/toRomaji.js", "../../node_modules/src/utils/isCharEnglishPunctuation.js", "../../node_modules/src/toHiragana.js", "../../node_modules/src/toKatakana.js", "../../node_modules/src/utils/isCharJapanesePunctuation.js", "../../node_modules/src/tokenize.js", "../../node_modules/src/stripOkurigana.js"], "sourcesContent": ["/**\n * Returns detailed type as string (instead of just 'object' for arrays etc)\n * @private\n * @param {any} value js value\n * @returns {String} type of value\n * @example\n * typeOf({}); // 'object'\n * typeOf([]); // 'array'\n * typeOf(function() {}); // 'function'\n * typeOf(/a/); // 'regexp'\n * typeOf(new Date()); // 'date'\n * typeOf(null); // 'null'\n * typeOf(undefined); // 'undefined'\n * typeOf('a'); // 'string'\n * typeOf(1); // 'number'\n * typeOf(true); // 'boolean'\n * typeOf(new Map()); // 'map'\n * typeOf(new Set()); // 'map'\n */\nfunction typeOf(value) {\n if (value === null) {\n return 'null';\n }\n if (value !== Object(value)) {\n return typeof value;\n }\n return {}.toString\n .call(value)\n .slice(8, -1)\n .toLowerCase();\n}\n\nexport default typeOf;\n", "import typeOf from './typeOf';\n/**\n * Checks if input string is empty\n * @param {String} input text input\n * @return {Boolean} true if no input\n */\nfunction isEmpty(input) {\n if (typeOf(input) !== 'string') {\n return true;\n }\n return !input.length;\n}\n\nexport default isEmpty;\n", "import isEmpty from './isEmpty';\n\n/**\n * Takes a character and a unicode range. Returns true if the char is in the range.\n * @param {String} char unicode character\n * @param {Number} start unicode start range\n * @param {Number} end unicode end range\n * @return {Boolean}\n */\nfunction isCharInRange(char = '', start, end) {\n if (isEmpty(char)) return false;\n const code = char.charCodeAt(0);\n return start <= code && code <= end;\n}\n\nexport default isCharInRange;\n", "export const VERSION = '5.3.1';\n\nexport const TO_KANA_METHODS: {\n HIRAGANA: 'toHiragana',\n KATAKANA: 'toKatakana',\n} = {\n HIRAGANA: 'toHiragana',\n KATAKANA: 'toKatakana',\n};\n\nexport const ROMANIZATIONS: { HEPBURN: 'hepburn' } = {\n HEPBURN: 'hepburn',\n};\n\nexport type DefaultOptions = {\n useObsoleteKana?: boolean,\n passRomaji?: boolean,\n convertLongVowelMark?: boolean,\n upcaseKatakana?: boolean,\n IMEMode?: boolean | 'toHiragana' | 'toKatakana',\n romanization?: 'hepburn',\n customKanaMapping?: { [index: string]: string }\n customRomajiMapping?: { [index: string]: string }\n};\n\n/**\n * Default config for WanaKana, user passed options will be merged with these\n * @type {DefaultOptions}\n * @name DefaultOptions\n * @property {Boolean} [useObsoleteKana=false] - Set to true to use obsolete characters, such as ゐ and ゑ.\n * @example\n * toHiragana('we', { useObsoleteKana: true })\n * // => 'ゑ'\n * @property {Boolean} [passRomaji=false] - Set to true to pass romaji when using mixed syllabaries with toKatakana() or toHiragana()\n * @example\n * toHiragana('only convert the katakana: ヒラガナ', { passRomaji: true })\n * // => \"only convert the katakana: ひらがな\"\n * @property {Boolean} [convertLongVowelMark=true] - Set to false to prevent conversions of 'ー' to extended vowels with toHiragana()\n * @example\n * toHiragana('ラーメン', { convertLongVowelMark: false });\n * // => 'らーめん\n * @property {Boolean} [upcaseKatakana=false] - Set to true to convert katakana to uppercase using toRomaji()\n * @example\n * toRomaji('ひらがな カタカナ', { upcaseKatakana: true })\n * // => \"hiragana KATAKANA\"\n * @property {Boolean | 'toHiragana' | 'toKatakana'} [IMEMode=false] - Set to true, 'toHiragana', or 'toKatakana' to handle conversion while it is being typed.\n * @property {'hepburn'} [romanization='hepburn'] - choose toRomaji() romanization map (currently only 'hepburn')\n * @property {Object.} [customKanaMapping] - custom map will be merged with default conversion\n * @example\n * toKana('wanakana', { customKanaMapping: { na: 'に', ka: 'Bana' }) };\n * // => 'わにBanaに'\n * @property {Object.} [customRomajiMapping] - custom map will be merged with default conversion\n * @example\n * toRomaji('つじぎり', { customRomajiMapping: { じ: 'zi', つ: 'tu', り: 'li' }) };\n * // => 'tuzigili'\n */\nexport const DEFAULT_OPTIONS: DefaultOptions = {\n useObsoleteKana: false,\n passRomaji: false,\n convertLongVowelMark: true,\n upcaseKatakana: false,\n IMEMode: false,\n romanization: ROMANIZATIONS.HEPBURN,\n};\n\n// CharCode References\n// http://www.rikai.com/library/kanjitables/kanji_codes.unicode.shtml\n// http://unicode-table.com\n\nexport const LATIN_LOWERCASE_START = 0x61;\nexport const LATIN_LOWERCASE_END = 0x7a;\nexport const LATIN_UPPERCASE_START = 0x41;\nexport const LATIN_UPPERCASE_END = 0x5a;\nexport const LOWERCASE_ZENKAKU_START = 0xff41;\nexport const LOWERCASE_ZENKAKU_END = 0xff5a;\nexport const UPPERCASE_ZENKAKU_START = 0xff21;\nexport const UPPERCASE_ZENKAKU_END = 0xff3a;\nexport const HIRAGANA_START = 0x3041;\nexport const HIRAGANA_END = 0x3096;\nexport const KATAKANA_START = 0x30a1;\nexport const KATAKANA_END = 0x30fc;\nexport const KANJI_START = 0x4e00;\nexport const KANJI_END = 0x9faf;\n\nexport const KANJI_ITERATION_MARK = 0x3005; // 々\nexport const PROLONGED_SOUND_MARK = 0x30fc; // ー\nexport const KANA_SLASH_DOT = 0x30fb; // ・\n\nconst ZENKAKU_NUMBERS = [0xff10, 0xff19];\nconst ZENKAKU_UPPERCASE = [UPPERCASE_ZENKAKU_START, UPPERCASE_ZENKAKU_END];\nconst ZENKAKU_LOWERCASE = [LOWERCASE_ZENKAKU_START, LOWERCASE_ZENKAKU_END];\nconst ZENKAKU_PUNCTUATION_1 = [0xff01, 0xff0f];\nconst ZENKAKU_PUNCTUATION_2 = [0xff1a, 0xff1f];\nconst ZENKAKU_PUNCTUATION_3 = [0xff3b, 0xff3f];\nconst ZENKAKU_PUNCTUATION_4 = [0xff5b, 0xff60];\nconst ZENKAKU_SYMBOLS_CURRENCY = [0xffe0, 0xffee];\n\nconst HIRAGANA_CHARS = [0x3040, 0x309f];\nconst KATAKANA_CHARS = [0x30a0, 0x30ff];\nconst HANKAKU_KATAKANA = [0xff66, 0xff9f];\nconst KATAKANA_PUNCTUATION = [0x30fb, 0x30fc];\nconst KANA_PUNCTUATION = [0xff61, 0xff65];\nconst CJK_SYMBOLS_PUNCTUATION = [0x3000, 0x303f];\nconst COMMON_CJK = [0x4e00, 0x9fff];\nconst RARE_CJK = [0x3400, 0x4dbf];\n\nexport const KANA_RANGES = [\n HIRAGANA_CHARS,\n KATAKANA_CHARS,\n KANA_PUNCTUATION,\n HANKAKU_KATAKANA,\n];\n\nexport const JA_PUNCTUATION_RANGES = [\n CJK_SYMBOLS_PUNCTUATION,\n KANA_PUNCTUATION,\n KATAKANA_PUNCTUATION,\n ZENKAKU_PUNCTUATION_1,\n ZENKAKU_PUNCTUATION_2,\n ZENKAKU_PUNCTUATION_3,\n ZENKAKU_PUNCTUATION_4,\n ZENKAKU_SYMBOLS_CURRENCY,\n];\n\n// All Japanese unicode start and end ranges\n// Includes kanji, kana, zenkaku latin chars, punctuation, and number ranges.\nexport const JAPANESE_RANGES = [\n ...KANA_RANGES,\n ...JA_PUNCTUATION_RANGES,\n ZENKAKU_UPPERCASE,\n ZENKAKU_LOWERCASE,\n ZENKAKU_NUMBERS,\n COMMON_CJK,\n RARE_CJK,\n];\n\nconst MODERN_ENGLISH = [0x0000, 0x007f];\nconst HEPBURN_MACRON_RANGES = [\n [0x0100, 0x0101], // Ā ā\n [0x0112, 0x0113], // Ē ē\n [0x012a, 0x012b], // Ī ī\n [0x014c, 0x014d], // Ō ō\n [0x016a, 0x016b], // Ū ū\n];\nconst SMART_QUOTE_RANGES = [\n [0x2018, 0x2019], // ‘ ’\n [0x201c, 0x201d], // “ ”\n];\n\nexport const ROMAJI_RANGES = [MODERN_ENGLISH, ...HEPBURN_MACRON_RANGES];\n\nexport const EN_PUNCTUATION_RANGES = [\n [0x20, 0x2f],\n [0x3a, 0x3f],\n [0x5b, 0x60],\n [0x7b, 0x7e],\n ...SMART_QUOTE_RANGES,\n];\n", "import isCharInRange from './isCharInRange';\nimport { JAPANESE_RANGES } from '../constants.ts';\n\n/**\n * Tests a character. Returns true if the character is [Katakana](https://en.wikipedia.org/wiki/Katakana).\n * @param {String} char character string to test\n * @return {Boolean}\n */\nfunction isCharJapanese(char = '') {\n return JAPANESE_RANGES.some(([start, end]) => isCharInRange(char, start, end));\n}\n\nexport default isCharJapanese;\n", "import typeOf from './utils/typeOf';\nimport isEmpty from './utils/isEmpty';\nimport isCharJapanese from './utils/isCharJapanese';\n\n/**\n * Test if `input` only includes [Kanji](https://en.wikipedia.org/wiki/Kanji), [Kana](https://en.wikipedia.org/wiki/Kana), zenkaku numbers, and JA punctuation/symbols.”\n * @param {String} [input=''] text\n * @param {RegExp} [allowed] additional test allowed to pass for each char\n * @return {Boolean} true if passes checks\n * @example\n * isJapanese('泣き虫')\n * // => true\n * isJapanese('あア')\n * // => true\n * isJapanese('2月') // Zenkaku numbers allowed\n * // => true\n * isJapanese('泣き虫。!〜$') // Zenkaku/JA punctuation\n * // => true\n * isJapanese('泣き虫.!~$') // Latin punctuation fails\n * // => false\n * isJapanese('A泣き虫')\n * // => false\n * isJapanese('≪偽括弧≫', /[≪≫]/);\n * // => true\n */\nfunction isJapanese(input = '', allowed) {\n const augmented = typeOf(allowed) === 'regexp';\n return isEmpty(input)\n ? false\n : [...input].every((char) => {\n const isJa = isCharJapanese(char);\n return !augmented ? isJa : isJa || allowed.test(char);\n });\n}\n\nexport default isJapanese;\n", "var safeIsNaN = Number.isNaN ||\n function ponyfill(value) {\n return typeof value === 'number' && value !== value;\n };\nfunction isEqual(first, second) {\n if (first === second) {\n return true;\n }\n if (safeIsNaN(first) && safeIsNaN(second)) {\n return true;\n }\n return false;\n}\nfunction areInputsEqual(newInputs, lastInputs) {\n if (newInputs.length !== lastInputs.length) {\n return false;\n }\n for (var i = 0; i < newInputs.length; i++) {\n if (!isEqual(newInputs[i], lastInputs[i])) {\n return false;\n }\n }\n return true;\n}\n\nfunction memoizeOne(resultFn, isEqual) {\n if (isEqual === void 0) { isEqual = areInputsEqual; }\n var cache = null;\n function memoized() {\n var newArgs = [];\n for (var _i = 0; _i < arguments.length; _i++) {\n newArgs[_i] = arguments[_i];\n }\n if (cache && cache.lastThis === this && isEqual(newArgs, cache.lastArgs)) {\n return cache.lastResult;\n }\n var lastResult = resultFn.apply(this, newArgs);\n cache = {\n lastResult: lastResult,\n lastArgs: newArgs,\n lastThis: this,\n };\n return lastResult;\n }\n memoized.clear = function clear() {\n cache = null;\n };\n return memoized;\n}\n\nexport { memoizeOne as default };\n", "var has = Object.prototype.hasOwnProperty;\n\nfunction find(iter, tar, key) {\n\tfor (key of iter.keys()) {\n\t\tif (dequal(key, tar)) return key;\n\t}\n}\n\nexport function dequal(foo, bar) {\n\tvar ctor, len, tmp;\n\tif (foo === bar) return true;\n\n\tif (foo && bar && (ctor=foo.constructor) === bar.constructor) {\n\t\tif (ctor === Date) return foo.getTime() === bar.getTime();\n\t\tif (ctor === RegExp) return foo.toString() === bar.toString();\n\n\t\tif (ctor === Array) {\n\t\t\tif ((len=foo.length) === bar.length) {\n\t\t\t\twhile (len-- && dequal(foo[len], bar[len]));\n\t\t\t}\n\t\t\treturn len === -1;\n\t\t}\n\n\t\tif (ctor === Set) {\n\t\t\tif (foo.size !== bar.size) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tfor (len of foo) {\n\t\t\t\ttmp = len;\n\t\t\t\tif (tmp && typeof tmp === 'object') {\n\t\t\t\t\ttmp = find(bar, tmp);\n\t\t\t\t\tif (!tmp) return false;\n\t\t\t\t}\n\t\t\t\tif (!bar.has(tmp)) return false;\n\t\t\t}\n\t\t\treturn true;\n\t\t}\n\n\t\tif (ctor === Map) {\n\t\t\tif (foo.size !== bar.size) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tfor (len of foo) {\n\t\t\t\ttmp = len[0];\n\t\t\t\tif (tmp && typeof tmp === 'object') {\n\t\t\t\t\ttmp = find(bar, tmp);\n\t\t\t\t\tif (!tmp) return false;\n\t\t\t\t}\n\t\t\t\tif (!dequal(len[1], bar.get(tmp))) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn true;\n\t\t}\n\n\t\tif (ctor === ArrayBuffer) {\n\t\t\tfoo = new Uint8Array(foo);\n\t\t\tbar = new Uint8Array(bar);\n\t\t} else if (ctor === DataView) {\n\t\t\tif ((len=foo.byteLength) === bar.byteLength) {\n\t\t\t\twhile (len-- && foo.getInt8(len) === bar.getInt8(len));\n\t\t\t}\n\t\t\treturn len === -1;\n\t\t}\n\n\t\tif (ArrayBuffer.isView(foo)) {\n\t\t\tif ((len=foo.byteLength) === bar.byteLength) {\n\t\t\t\twhile (len-- && foo[len] === bar[len]);\n\t\t\t}\n\t\t\treturn len === -1;\n\t\t}\n\n\t\tif (!ctor || typeof foo === 'object') {\n\t\t\tlen = 0;\n\t\t\tfor (ctor in foo) {\n\t\t\t\tif (has.call(foo, ctor) && ++len && !has.call(bar, ctor)) return false;\n\t\t\t\tif (!(ctor in bar) || !dequal(foo[ctor], bar[ctor])) return false;\n\t\t\t}\n\t\t\treturn Object.keys(bar).length === len;\n\t\t}\n\t}\n\n\treturn foo !== foo && bar !== bar;\n}\n", "import { DEFAULT_OPTIONS } from '../constants.ts';\n/**\n * Easy re-use of merging with default options\n * @param {Object} opts user options\n * @returns user options merged over default options\n */\nconst mergeWithDefaultOptions = (opts = {}) => Object.assign({}, DEFAULT_OPTIONS, opts);\n\nexport default mergeWithDefaultOptions;\n", "import typeOf from './typeOf';\n\nexport function applyMapping(string, mapping, convertEnding) {\n const root = mapping;\n\n function nextSubtree(tree, nextChar) {\n const subtree = tree[nextChar];\n if (subtree === undefined) {\n return undefined;\n }\n // if the next child node does not have a node value, set its node value to the input\n return Object.assign({ '': tree[''] + nextChar }, tree[nextChar]);\n }\n\n function newChunk(remaining, currentCursor) {\n // start parsing a new chunk\n const firstChar = remaining.charAt(0);\n\n return parse(\n Object.assign({ '': firstChar }, root[firstChar]),\n remaining.slice(1),\n currentCursor,\n currentCursor + 1\n );\n }\n\n function parse(tree, remaining, lastCursor, currentCursor) {\n if (!remaining) {\n if (convertEnding || Object.keys(tree).length === 1) {\n // nothing more to consume, just commit the last chunk and return it\n // so as to not have an empty element at the end of the result\n return tree[''] ? [[lastCursor, currentCursor, tree['']]] : [];\n }\n // if we don't want to convert the ending, because there are still possible continuations\n // return null as the final node value\n return [[lastCursor, currentCursor, null]];\n }\n\n if (Object.keys(tree).length === 1) {\n return [[lastCursor, currentCursor, tree['']]].concat(\n newChunk(remaining, currentCursor)\n );\n }\n\n const subtree = nextSubtree(tree, remaining.charAt(0));\n\n if (subtree === undefined) {\n return [[lastCursor, currentCursor, tree['']]].concat(\n newChunk(remaining, currentCursor)\n );\n }\n // continue current branch\n return parse(subtree, remaining.slice(1), lastCursor, currentCursor + 1);\n }\n\n return newChunk(string, 0);\n}\n\n// transform the tree, so that for example hepburnTree['ゔ']['ぁ'][''] === 'va'\n// or kanaTree['k']['y']['a'][''] === 'きゃ'\nexport function transform(tree) {\n return Object.entries(tree).reduce((map, [char, subtree]) => {\n const endOfBranch = typeOf(subtree) === 'string';\n // eslint-disable-next-line no-param-reassign\n map[char] = endOfBranch ? { '': subtree } : transform(subtree);\n return map;\n }, {});\n}\n\nexport function getSubTreeOf(tree, string) {\n return string.split('').reduce((correctSubTree, char) => {\n if (correctSubTree[char] === undefined) {\n // eslint-disable-next-line no-param-reassign\n correctSubTree[char] = {};\n }\n return correctSubTree[char];\n }, tree);\n}\n\n/**\n * Creates a custom mapping tree, returns a function that accepts a defaultMap which the newly created customMapping will be merged with and returned\n * (customMap) => (defaultMap) => mergedMap\n * @param {Object} customMap { 'ka' : 'な' }\n * @return {Function} (defaultMap) => defaultMergedWithCustomMap\n * @example\n * const sillyMap = createCustomMapping({ 'ちゃ': 'time', '茎': 'cookie' });\n * // sillyMap is passed defaultMapping to merge with when called in toRomaji()\n * toRomaji(\"It's 茎 ちゃ よ\", { customRomajiMapping: sillyMap });\n * // => 'It's cookie time yo';\n */\nexport function createCustomMapping(customMap = {}) {\n const customTree = {};\n\n if (typeOf(customMap) === 'object') {\n Object.entries(customMap).forEach(([roma, kana]) => {\n let subTree = customTree;\n roma.split('').forEach((char) => {\n if (subTree[char] === undefined) {\n subTree[char] = {};\n }\n subTree = subTree[char];\n });\n subTree[''] = kana;\n });\n }\n\n return function makeMap(map) {\n const mapCopy = JSON.parse(JSON.stringify(map));\n\n function transformMap(mapSubtree, customSubtree) {\n if (mapSubtree === undefined || typeOf(mapSubtree) === 'string') {\n return customSubtree;\n }\n return Object.entries(customSubtree).reduce(\n (newSubtree, [char, subtree]) => {\n // eslint-disable-next-line no-param-reassign\n newSubtree[char] = transformMap(mapSubtree[char], subtree);\n return newSubtree;\n },\n mapSubtree\n );\n }\n\n return transformMap(mapCopy, customTree);\n };\n}\n\n// allow consumer to pass either function or object as customMapping\nexport function mergeCustomMapping(map, customMapping) {\n if (!customMapping) {\n return map;\n }\n return typeOf(customMapping) === 'function'\n ? customMapping(map)\n : createCustomMapping(customMapping)(map);\n}\n", "import { transform, getSubTreeOf, createCustomMapping } from './kanaMapping';\n\n// NOTE: not exactly kunrei shiki, for example ぢゃ -> dya instead of zya, to avoid name clashing\n/* eslint-disable */\n// prettier-ignore\nconst BASIC_KUNREI = {\n a: 'あ', i: 'い', u: 'う', e: 'え', o: 'お',\n k: { a: 'か', i: 'き', u: 'く', e: 'け', o: 'こ', },\n s: { a: 'さ', i: 'し', u: 'す', e: 'せ', o: 'そ', },\n t: { a: 'た', i: 'ち', u: 'つ', e: 'て', o: 'と', },\n n: { a: 'な', i: 'に', u: 'ぬ', e: 'ね', o: 'の', },\n h: { a: 'は', i: 'ひ', u: 'ふ', e: 'へ', o: 'ほ', },\n m: { a: 'ま', i: 'み', u: 'む', e: 'め', o: 'も', },\n y: { a: 'や', u: 'ゆ', o: 'よ' },\n r: { a: 'ら', i: 'り', u: 'る', e: 'れ', o: 'ろ', },\n w: { a: 'わ', i: 'ゐ', e: 'ゑ', o: 'を', },\n g: { a: 'が', i: 'ぎ', u: 'ぐ', e: 'げ', o: 'ご', },\n z: { a: 'ざ', i: 'じ', u: 'ず', e: 'ぜ', o: 'ぞ', },\n d: { a: 'だ', i: 'ぢ', u: 'づ', e: 'で', o: 'ど', },\n b: { a: 'ば', i: 'び', u: 'ぶ', e: 'べ', o: 'ぼ', },\n p: { a: 'ぱ', i: 'ぴ', u: 'ぷ', e: 'ぺ', o: 'ぽ', },\n v: { a: 'ゔぁ', i: 'ゔぃ', u: 'ゔ', e: 'ゔぇ', o: 'ゔぉ', },\n};\n\nconst SPECIAL_SYMBOLS = {\n '.': '。',\n ',': '、',\n ':': ':',\n '/': '・',\n '!': '!',\n '?': '?',\n '~': '〜',\n '-': 'ー',\n '‘': '「',\n '’': '」',\n '“': '『',\n '”': '』',\n '[': '[',\n ']': ']',\n '(': '(',\n ')': ')',\n '{': '{',\n '}': '}',\n};\n\nconst CONSONANTS = {\n k: 'き',\n s: 'し',\n t: 'ち',\n n: 'に',\n h: 'ひ',\n m: 'み',\n r: 'り',\n g: 'ぎ',\n z: 'じ',\n d: 'ぢ',\n b: 'び',\n p: 'ぴ',\n v: 'ゔ',\n q: 'く',\n f: 'ふ',\n};\nconst SMALL_Y = { ya: 'ゃ', yi: 'ぃ', yu: 'ゅ', ye: 'ぇ', yo: 'ょ' };\nconst SMALL_VOWELS = { a: 'ぁ', i: 'ぃ', u: 'ぅ', e: 'ぇ', o: 'ぉ' };\n\n// typing one should be the same as having typed the other instead\nconst ALIASES = {\n sh: 'sy', // sha -> sya\n ch: 'ty', // cho -> tyo\n cy: 'ty', // cyo -> tyo\n chy: 'ty', // chyu -> tyu\n shy: 'sy', // shya -> sya\n j: 'zy', // ja -> zya\n jy: 'zy', // jye -> zye\n\n // exceptions to above rules\n shi: 'si',\n chi: 'ti',\n tsu: 'tu',\n ji: 'zi',\n fu: 'hu',\n};\n\n// xtu -> っ\nconst SMALL_LETTERS = Object.assign(\n {\n tu: 'っ',\n wa: 'ゎ',\n ka: 'ヵ',\n ke: 'ヶ',\n },\n SMALL_VOWELS,\n SMALL_Y\n);\n\n// don't follow any notable patterns\nconst SPECIAL_CASES = {\n yi: 'い',\n wu: 'う',\n ye: 'いぇ',\n wi: 'うぃ',\n we: 'うぇ',\n kwa: 'くぁ',\n whu: 'う',\n // because it's not thya for てゃ but tha\n // and tha is not てぁ, but てゃ\n tha: 'てゃ',\n thu: 'てゅ',\n tho: 'てょ',\n dha: 'でゃ',\n dhu: 'でゅ',\n dho: 'でょ',\n};\n\nconst AIUEO_CONSTRUCTIONS = {\n wh: 'う',\n kw: 'く',\n qw: 'く',\n q: 'く',\n gw: 'ぐ',\n sw: 'す',\n ts: 'つ',\n th: 'て',\n tw: 'と',\n dh: 'で',\n dw: 'ど',\n fw: 'ふ',\n f: 'ふ',\n};\n\n/* eslint-enable */\nfunction createRomajiToKanaMap() {\n const kanaTree = transform(BASIC_KUNREI);\n // pseudo partial application\n const subtreeOf = (string) => getSubTreeOf(kanaTree, string);\n\n // add tya, sya, etc.\n Object.entries(CONSONANTS).forEach(([consonant, yKana]) => {\n Object.entries(SMALL_Y).forEach(([roma, kana]) => {\n // for example kyo -> き + ょ\n subtreeOf(consonant + roma)[''] = yKana + kana;\n });\n });\n\n Object.entries(SPECIAL_SYMBOLS).forEach(([symbol, jsymbol]) => {\n subtreeOf(symbol)[''] = jsymbol;\n });\n\n // things like うぃ, くぃ, etc.\n Object.entries(AIUEO_CONSTRUCTIONS).forEach(([consonant, aiueoKana]) => {\n Object.entries(SMALL_VOWELS).forEach(([vowel, kana]) => {\n const subtree = subtreeOf(consonant + vowel);\n subtree[''] = aiueoKana + kana;\n });\n });\n\n // different ways to write ん\n ['n', \"n'\", 'xn'].forEach((nChar) => {\n subtreeOf(nChar)[''] = 'ん';\n });\n\n // c is equivalent to k, but not for chi, cha, etc. that's why we have to make a copy of k\n kanaTree.c = JSON.parse(JSON.stringify(kanaTree.k));\n\n Object.entries(ALIASES).forEach(([string, alternative]) => {\n const allExceptLast = string.slice(0, string.length - 1);\n const last = string.charAt(string.length - 1);\n const parentTree = subtreeOf(allExceptLast);\n // copy to avoid recursive containment\n parentTree[last] = JSON.parse(JSON.stringify(subtreeOf(alternative)));\n });\n\n function getAlternatives(string) {\n return [...Object.entries(ALIASES), ...[['c', 'k']]].reduce(\n (list, [alt, roma]) => (string.startsWith(roma) ? list.concat(string.replace(roma, alt)) : list),\n []\n );\n }\n\n Object.entries(SMALL_LETTERS).forEach(([kunreiRoma, kana]) => {\n const last = (char) => char.charAt(char.length - 1);\n const allExceptLast = (chars) => chars.slice(0, chars.length - 1);\n const xRoma = `x${kunreiRoma}`;\n const xSubtree = subtreeOf(xRoma);\n xSubtree[''] = kana;\n\n // ltu -> xtu -> っ\n const parentTree = subtreeOf(`l${allExceptLast(kunreiRoma)}`);\n parentTree[last(kunreiRoma)] = xSubtree;\n\n // ltsu -> ltu -> っ\n getAlternatives(kunreiRoma).forEach((altRoma) => {\n ['l', 'x'].forEach((prefix) => {\n const altParentTree = subtreeOf(prefix + allExceptLast(altRoma));\n altParentTree[last(altRoma)] = subtreeOf(prefix + kunreiRoma);\n });\n });\n });\n\n Object.entries(SPECIAL_CASES).forEach(([string, kana]) => {\n subtreeOf(string)[''] = kana;\n });\n\n // add kka, tta, etc.\n function addTsu(tree) {\n return Object.entries(tree).reduce((tsuTree, [key, value]) => {\n if (!key) {\n // we have reached the bottom of this branch\n // eslint-disable-next-line no-param-reassign\n tsuTree[key] = `っ${value}`;\n } else {\n // more subtrees\n // eslint-disable-next-line no-param-reassign\n tsuTree[key] = addTsu(value);\n }\n return tsuTree;\n }, {});\n }\n // have to explicitly name c here, because we made it a copy of k, not a reference\n [...Object.keys(CONSONANTS), 'c', 'y', 'w', 'j'].forEach((consonant) => {\n const subtree = kanaTree[consonant];\n subtree[consonant] = addTsu(subtree);\n });\n // nn should not be っん\n delete kanaTree.n.n;\n // solidify the results, so that there there is referential transparency within the tree\n return Object.freeze(JSON.parse(JSON.stringify(kanaTree)));\n}\n\nlet romajiToKanaMap = null;\n\nexport function getRomajiToKanaTree() {\n if (romajiToKanaMap == null) {\n romajiToKanaMap = createRomajiToKanaMap();\n }\n return romajiToKanaMap;\n}\n\nexport const USE_OBSOLETE_KANA_MAP = createCustomMapping({\n wi: 'ゐ',\n we: 'ゑ',\n});\n\nexport function IME_MODE_MAP(map) {\n // in IME mode, we do not want to convert single ns\n const mapCopy = JSON.parse(JSON.stringify(map));\n mapCopy.n.n = { '': 'ん' };\n mapCopy.n[' '] = { '': 'ん' };\n return mapCopy;\n}\n", "import isEmpty from './isEmpty';\nimport isCharInRange from './isCharInRange';\nimport { LATIN_UPPERCASE_START, LATIN_UPPERCASE_END } from '../constants.ts';\n\n/**\n * Tests if char is in English unicode uppercase range\n * @param {String} char\n * @return {Boolean}\n */\nfunction isCharUpperCase(char = '') {\n if (isEmpty(char)) return false;\n return isCharInRange(char, LATIN_UPPERCASE_START, LATIN_UPPERCASE_END);\n}\n\nexport default isCharUpperCase;\n", "import isEmpty from './isEmpty';\nimport { PROLONGED_SOUND_MARK } from '../constants.ts';\n\n/**\n * Returns true if char is 'ー'\n * @param {String} char to test\n * @return {Boolean}\n */\nfunction isCharLongDash(char = '') {\n if (isEmpty(char)) return false;\n return char.charCodeAt(0) === PROLONGED_SOUND_MARK;\n}\n\nexport default isCharLongDash;\n", "import isEmpty from './isEmpty';\nimport { KANA_SLASH_DOT } from '../constants.ts';\n\n/**\n * Tests if char is '・'\n * @param {String} char\n * @return {Boolean} true if '・'\n */\nfunction isCharSlashDot(char = '') {\n if (isEmpty(char)) return false;\n return char.charCodeAt(0) === KANA_SLASH_DOT;\n}\n\nexport default isCharSlashDot;\n", "import isEmpty from './isEmpty';\nimport isCharLongDash from './isCharLongDash';\nimport isCharInRange from './isCharInRange';\nimport {\n HIRAGANA_START,\n HIRAGANA_END,\n} from '../constants.ts';\n\n/**\n * Tests a character. Returns true if the character is [Hiragana](https://en.wikipedia.org/wiki/Hiragana).\n * @param {String} char character string to test\n * @return {Boolean}\n */\nfunction isCharHiragana(char = '') {\n if (isEmpty(char)) return false;\n if (isCharLongDash(char)) return true;\n return isCharInRange(char, HIRAGANA_START, HIRAGANA_END);\n}\n\nexport default isCharHiragana;\n", "import { KATAKANA_START, HIRAGANA_START } from '../constants.ts';\n\nimport isCharLongDash from './isCharLongDash';\nimport isCharSlashDot from './isCharSlashDot';\nimport isCharHiragana from './isCharHiragana';\n\n/**\n * Convert [Hiragana](https://en.wikipedia.org/wiki/Hiragana) to [Katakana](https://en.wikipedia.org/wiki/Katakana)\n * Passes through any non-hiragana chars\n * @private\n * @param {String} [input=''] text input\n * @return {String} converted text\n * @example\n * hiraganaToKatakana('ひらがな')\n * // => \"ヒラガナ\"\n * hiraganaToKatakana('ひらがな is a type of kana')\n * // => \"ヒラガナ is a type of kana\"\n */\nfunction hiraganaToKatakana(input = '') {\n const kata = [];\n input.split('').forEach((char) => {\n // Short circuit to avoid incorrect codeshift for 'ー' and '・'\n if (isCharLongDash(char) || isCharSlashDot(char)) {\n kata.push(char);\n } else if (isCharHiragana(char)) {\n // Shift charcode.\n const code = char.charCodeAt(0) + (KATAKANA_START - HIRAGANA_START);\n const kataChar = String.fromCharCode(code);\n kata.push(kataChar);\n } else {\n // Pass non-hiragana chars through\n kata.push(char);\n }\n });\n return kata.join('');\n}\n\nexport default hiraganaToKatakana;\n", "import memoizeOne from 'memoize-one';\nimport { dequal } from 'dequal';\n\nimport { TO_KANA_METHODS } from './constants';\nimport mergeWithDefaultOptions from './utils/mergeWithDefaultOptions';\nimport {\n getRomajiToKanaTree,\n IME_MODE_MAP,\n USE_OBSOLETE_KANA_MAP,\n} from './utils/romajiToKanaMap';\nimport { applyMapping, mergeCustomMapping } from './utils/kanaMapping';\nimport isCharUpperCase from './utils/isCharUpperCase';\nimport hiraganaToKatakana from './utils/hiraganaToKatakana';\n\n// memoize and deeply compare args so we only recreate when necessary\nexport const createRomajiToKanaMap = memoizeOne(\n (IMEMode, useObsoleteKana, customKanaMapping) => {\n let map = getRomajiToKanaTree();\n\n map = IMEMode ? IME_MODE_MAP(map) : map;\n map = useObsoleteKana ? USE_OBSOLETE_KANA_MAP(map) : map;\n\n if (customKanaMapping) {\n map = mergeCustomMapping(map, customKanaMapping);\n }\n\n return map;\n },\n dequal\n);\n\n/**\n * Convert [Romaji](https://en.wikipedia.org/wiki/Romaji) to [Kana](https://en.wikipedia.org/wiki/Kana), lowercase text will result in [Hiragana](https://en.wikipedia.org/wiki/Hiragana) and uppercase text will result in [Katakana](https://en.wikipedia.org/wiki/Katakana).\n * @param {String} [input=''] text\n * @param {DefaultOptions} [options=defaultOptions]\n * @param {Object.} [map] custom mapping\n * @return {String} converted text\n * @example\n * toKana('onaji BUTTSUUJI')\n * // => 'おなじ ブッツウジ'\n * toKana('ONAJI buttsuuji')\n * // => 'オナジ ぶっつうじ'\n * toKana('座禅‘zazen’スタイル')\n * // => '座禅「ざぜん」スタイル'\n * toKana('batsuge-mu')\n * // => 'ばつげーむ'\n * toKana('!?.:/,~-‘’“”[](){}') // Punctuation conversion\n * // => '!?。:・、〜ー「」『』[](){}'\n * toKana('we', { useObsoleteKana: true })\n * // => 'ゑ'\n * toKana('wanakana', { customKanaMapping: { na: 'に', ka: 'bana' } });\n * // => 'わにbanaに'\n */\nexport function toKana(input = '', options = {}, map) {\n let config;\n if (!map) {\n config = mergeWithDefaultOptions(options);\n map = createRomajiToKanaMap(\n config.IMEMode,\n config.useObsoleteKana,\n config.customKanaMapping\n );\n } else {\n config = options;\n }\n\n // throw away the substring index information and just concatenate all the kana\n return splitIntoConvertedKana(input, config, map)\n .map((kanaToken) => {\n const [start, end, kana] = kanaToken;\n if (kana === null) {\n // haven't converted the end of the string, since we are in IME mode\n return input.slice(start);\n }\n const enforceHiragana = config.IMEMode === TO_KANA_METHODS.HIRAGANA;\n const enforceKatakana = config.IMEMode === TO_KANA_METHODS.KATAKANA\n || [...input.slice(start, end)].every(isCharUpperCase);\n\n return enforceHiragana || !enforceKatakana\n ? kana\n : hiraganaToKatakana(kana);\n })\n .join('');\n}\n\n/**\n *\n * @private\n * @param {String} [input=''] input text\n * @param {DefaultOptions} [options=defaultOptions] toKana options\n * @param {Object} [map] custom mapping\n * @returns {Array[]} [[start, end, token]]\n * @example\n * splitIntoConvertedKana('buttsuuji')\n * // => [[0, 2, 'ぶ'], [2, 6, 'っつ'], [6, 7, 'う'], [7, 9, 'じ']]\n */\nexport function splitIntoConvertedKana(input = '', options = {}, map) {\n const { IMEMode, useObsoleteKana, customKanaMapping } = options;\n\n if (!map) {\n map = createRomajiToKanaMap(IMEMode, useObsoleteKana, customKanaMapping);\n }\n\n return applyMapping(input.toLowerCase(), map, !IMEMode);\n}\n\nexport default toKana;\n", "import isJapanese from '../isJapanese';\nimport toKana, { createRomajiToKanaMap } from '../toKana';\nimport mergeWithDefaultOptions from './mergeWithDefaultOptions';\n\nlet LISTENERS = [];\n/**\n * Automagically replaces input values with converted text to kana\n * @param {defaultOptions} [options] user config overrides, default conversion is toKana()\n * @return {Function} event handler with bound options\n * @private\n */\nexport function makeOnInput(options) {\n let prevInput;\n\n // Enforce IMEMode if not already specified\n const mergedConfig = Object.assign({}, mergeWithDefaultOptions(options), {\n IMEMode: options.IMEMode || true,\n });\n\n const preConfiguredMap = createRomajiToKanaMap(\n mergedConfig.IMEMode,\n mergedConfig.useObsoleteKana,\n mergedConfig.customKanaMapping\n );\n\n const triggers = [\n ...Object.keys(preConfiguredMap),\n ...Object.keys(preConfiguredMap).map((char) => char.toUpperCase()),\n ];\n\n return function onInput({ target }) {\n if (\n target.value !== prevInput\n && target.dataset.ignoreComposition !== 'true'\n ) {\n convertInput(target, mergedConfig, preConfiguredMap, triggers, prevInput);\n }\n };\n}\n\nexport function convertInput(target, options, map, triggers, prevInput) {\n const [head, textToConvert, tail] = splitInput(\n target.value,\n target.selectionEnd,\n triggers\n );\n const convertedText = toKana(textToConvert, options, map);\n const changed = textToConvert !== convertedText;\n\n if (changed) {\n const newCursor = head.length + convertedText.length;\n const newValue = head + convertedText + tail;\n // eslint-disable-next-line no-param-reassign\n target.value = newValue;\n // eslint-disable-next-line no-param-reassign\n prevInput = newValue;\n\n if (tail.length) {\n // push later on event loop (otherwise mid-text insertion can be 1 char too far to the right)\n setTimeout(() => target.setSelectionRange(newCursor, newCursor), 1);\n } else {\n target.setSelectionRange(newCursor, newCursor);\n }\n } else {\n // eslint-disable-next-line no-param-reassign\n prevInput = target.value;\n }\n}\n\nexport function onComposition({ type, target, data }) {\n // navigator.platform is not 100% reliable for singling out all OS,\n // but for determining desktop \"Mac OS\" it is effective enough.\n const isMacOS = /Mac/.test(window.navigator && window.navigator.platform);\n // We don't want to ignore on Android:\n // https://github.com/WaniKani/WanaKana/issues/82\n // But MacOS IME auto-closes if we don't ignore:\n // https://github.com/WaniKani/WanaKana/issues/71\n // Other platform Japanese IMEs pass through happily\n if (isMacOS) {\n if (type === 'compositionupdate' && isJapanese(data)) {\n // eslint-disable-next-line no-param-reassign\n target.dataset.ignoreComposition = 'true';\n }\n\n if (type === 'compositionend') {\n // eslint-disable-next-line no-param-reassign\n target.dataset.ignoreComposition = 'false';\n }\n }\n}\n\nexport function trackListeners(id, inputHandler, compositionHandler) {\n LISTENERS = LISTENERS.concat({\n id,\n inputHandler,\n compositionHandler,\n });\n}\n\nexport function untrackListeners({ id: targetId }) {\n LISTENERS = LISTENERS.filter(({ id }) => id !== targetId);\n}\n\nexport function findListeners(el) {\n return (\n el && LISTENERS.find(({ id }) => id === el.getAttribute('data-wanakana-id'))\n );\n}\n\n// Handle non-terminal inserted input conversion:\n// | -> わ| -> わび| -> わ|び -> わs|び -> わsh|び -> わshi|び -> わし|び\n// or multiple ambiguous positioning (to select which \"s\" to work from)\n// こsこs|こsこ -> こsこso|こsこ -> こsこそ|こsこ\nexport function splitInput(text = '', cursor = 0, triggers = []) {\n let head;\n let toConvert;\n let tail;\n\n if (cursor === 0 && triggers.includes(text[0])) {\n [head, toConvert, tail] = workFromStart(text, triggers);\n } else if (cursor > 0) {\n [head, toConvert, tail] = workBackwards(text, cursor);\n } else {\n [head, toConvert] = takeWhileAndSlice(\n text,\n (char) => !triggers.includes(char)\n );\n [toConvert, tail] = takeWhileAndSlice(\n toConvert,\n (char) => !isJapanese(char)\n );\n }\n\n return [head, toConvert, tail];\n}\n\nfunction workFromStart(text, catalystChars) {\n return [\n '',\n ...takeWhileAndSlice(\n text,\n (char) => catalystChars.includes(char) || !isJapanese(char, /[0-9]/)\n ),\n ];\n}\n\nfunction workBackwards(text = '', startIndex = 0) {\n const [toConvert, head] = takeWhileAndSlice(\n [...text.slice(0, startIndex)].reverse(),\n (char) => !isJapanese(char)\n );\n return [\n head.reverse().join(''),\n toConvert\n .split('')\n .reverse()\n .join(''),\n text.slice(startIndex),\n ];\n}\n\nfunction takeWhileAndSlice(source = {}, predicate = (x) => !!x) {\n const result = [];\n const { length } = source;\n let i = 0;\n while (i < length && predicate(source[i], i)) {\n result.push(source[i]);\n i += 1;\n }\n return [result.join(''), source.slice(i)];\n}\n", "/* eslint-disable no-console */\nconst onInput = ({ target: { value, selectionStart, selectionEnd } }) => console.log('input:', { value, selectionStart, selectionEnd });\nconst onCompositionStart = () => console.log('compositionstart');\nconst onCompositionUpdate = ({\n target: { value, selectionStart, selectionEnd },\n data,\n}) => console.log('compositionupdate', {\n data,\n value,\n selectionStart,\n selectionEnd,\n});\nconst onCompositionEnd = () => console.log('compositionend');\n\nconst events = {\n input: onInput,\n compositionstart: onCompositionStart,\n compositionupdate: onCompositionUpdate,\n compositionend: onCompositionEnd,\n};\n\nexport const addDebugListeners = (input) => {\n Object.entries(events).forEach(([event, handler]) => input.addEventListener(event, handler)\n );\n};\n\nexport const removeDebugListeners = (input) => {\n Object.entries(events).forEach(([event, handler]) => input.removeEventListener(event, handler)\n );\n};\n", "import { makeOnInput, onComposition, trackListeners } from './utils/dom';\nimport { addDebugListeners } from './utils/logInputEvents';\n\nconst ELEMENTS = ['TEXTAREA', 'INPUT'];\n\nlet idCounter = 0;\nconst newId = () => {\n idCounter += 1;\n return `${Date.now()}${idCounter}`;\n};\n\n/**\n * Binds eventListener for 'input' events to an input field to automagically replace values with kana\n * Can pass `{ IMEMode: 'toHiragana' || 'toKatakana' }` to enforce kana conversion type\n * @param {HTMLInputElement | HTMLTextAreaElement} element textarea, input[type=\"text\"] etc\n * @param {DefaultOptions} [options=defaultOptions] defaults to { IMEMode: true } using `toKana`\n * @example\n * bind(document.querySelector('#myInput'));\n */\nfunction bind(element = {}, options = {}, debug = false) {\n if (!ELEMENTS.includes(element.nodeName)) {\n throw new Error(\n `Element provided to Wanakana bind() was not a valid input or textarea element.\\n Received: (${JSON.stringify(\n element\n )})`\n );\n }\n if (element.hasAttribute('data-wanakana-id')) {\n return;\n }\n const onInput = makeOnInput(options);\n const id = newId();\n const attributes = [\n { name: 'data-wanakana-id', value: id },\n { name: 'lang', value: 'ja' },\n { name: 'autoCapitalize', value: 'none' },\n { name: 'autoCorrect', value: 'off' },\n { name: 'autoComplete', value: 'off' },\n { name: 'spellCheck', value: 'false' },\n ];\n const previousAttributes = {};\n attributes.forEach((attribute) => {\n previousAttributes[attribute.name] = element.getAttribute(attribute.name);\n element.setAttribute(attribute.name, attribute.value);\n });\n element.dataset.previousAttributes = JSON.stringify(previousAttributes);\n element.addEventListener('input', onInput);\n element.addEventListener('compositionupdate', onComposition);\n element.addEventListener('compositionend', onComposition);\n trackListeners(id, onInput, onComposition);\n if (debug === true) {\n addDebugListeners(element);\n }\n}\n\nexport default bind;\n", "import { findListeners, untrackListeners } from './utils/dom';\nimport { removeDebugListeners } from './utils/logInputEvents';\n\n/**\n * Unbinds eventListener from input field\n * @param {HTMLInputElement | HTMLTextAreaElement} element textarea, input\n */\nexport function unbind(element, debug = false) {\n const listeners = findListeners(element);\n if (listeners == null) {\n throw new Error(\n `Element provided to Wanakana unbind() had no listener registered.\\n Received: ${JSON.stringify(\n element\n )}`\n );\n }\n const { inputHandler, compositionHandler } = listeners;\n const attributes = JSON.parse(element.dataset.previousAttributes);\n Object.keys(attributes).forEach((key) => {\n if (attributes[key]) {\n element.setAttribute(key, attributes[key]);\n } else {\n element.removeAttribute(key);\n }\n });\n element.removeAttribute('data-previous-attributes');\n element.removeAttribute('data-ignore-composition');\n element.removeEventListener('input', inputHandler);\n element.removeEventListener('compositionstart', compositionHandler);\n element.removeEventListener('compositionupdate', compositionHandler);\n element.removeEventListener('compositionend', compositionHandler);\n untrackListeners(listeners);\n if (debug === true) {\n removeDebugListeners(element);\n }\n}\n\nexport default unbind;\n", "import isEmpty from './isEmpty';\nimport isCharInRange from './isCharInRange';\nimport { ROMAJI_RANGES } from '../constants.ts';\n\n/**\n * Tests a character. Returns true if the character is [Romaji](https://en.wikipedia.org/wiki/Romaji) (allowing [Hepburn romanisation](https://en.wikipedia.org/wiki/Hepburn_romanization))\n * @param {String} char character string to test\n * @return {Boolean}\n */\nfunction isCharRomaji(char = '') {\n if (isEmpty(char)) return false;\n return ROMAJI_RANGES.some(([start, end]) => isCharInRange(char, start, end));\n}\n\nexport default isCharRomaji;\n", "import typeOf from './utils/typeOf';\nimport isEmpty from './utils/isEmpty';\nimport isCharRomaji from './utils/isCharRomaji';\n\n/**\n * Test if `input` is [Romaji](https://en.wikipedia.org/wiki/Romaji) (allowing [Hepburn romanisation](https://en.wikipedia.org/wiki/Hepburn_romanization))\n * @param {String} [input=''] text\n * @param {RegExp} [allowed] additional test allowed to pass for each char\n * @return {Boolean} true if [Romaji](https://en.wikipedia.org/wiki/Romaji)\n * @example\n * isRomaji('Tōkyō and Ōsaka')\n * // => true\n * isRomaji('12a*b&c-d')\n * // => true\n * isRomaji('あアA')\n * // => false\n * isRomaji('お願い')\n * // => false\n * isRomaji('a!b&cーd') // Zenkaku punctuation fails\n * // => false\n * isRomaji('a!b&cーd', /[!ー]/)\n * // => true\n */\nfunction isRomaji(input = '', allowed) {\n const augmented = typeOf(allowed) === 'regexp';\n return isEmpty(input)\n ? false\n : [...input].every((char) => {\n const isRoma = isCharRomaji(char);\n return !augmented ? isRoma : isRoma || allowed.test(char);\n });\n}\n\nexport default isRomaji;\n", "import {\n KATAKANA_START,\n KATAKANA_END,\n} from '../constants.ts';\n\nimport isCharInRange from './isCharInRange';\n\n/**\n * Tests a character. Returns true if the character is [Katakana](https://en.wikipedia.org/wiki/Katakana).\n * @param {String} char character string to test\n * @return {Boolean}\n */\nfunction isCharKatakana(char = '') {\n return isCharInRange(char, KATAKANA_START, KATAKANA_END);\n}\n\nexport default isCharKatakana;\n", "import isEmpty from './isEmpty';\nimport isCharHiragana from './isCharHiragana';\nimport isCharKatakana from './isCharKatakana';\n\n/**\n * Tests a character. Returns true if the character is [Hiragana](https://en.wikipedia.org/wiki/Hiragana) or [Katakana](https://en.wikipedia.org/wiki/Katakana).\n * @param {String} char character string to test\n * @return {Boolean}\n */\nfunction isCharKana(char = '') {\n if (isEmpty(char)) return false;\n return isCharHiragana(char) || isCharKatakana(char);\n}\n\nexport default isCharKana;\n", "import isEmpty from './utils/isEmpty';\nimport isCharKana from './utils/isCharKana';\n\n/**\n * Test if `input` is [Kana](https://en.wikipedia.org/wiki/Kana) ([Katakana](https://en.wikipedia.org/wiki/Katakana) and/or [Hiragana](https://en.wikipedia.org/wiki/Hiragana))\n * @param {String} [input=''] text\n * @return {Boolean} true if all [Kana](https://en.wikipedia.org/wiki/Kana)\n * @example\n * isKana('あ')\n * // => true\n * isKana('ア')\n * // => true\n * isKana('あーア')\n * // => true\n * isKana('A')\n * // => false\n * isKana('あAア')\n * // => false\n */\nfunction isKana(input = '') {\n if (isEmpty(input)) return false;\n return [...input].every(isCharKana);\n}\n\nexport default isKana;\n", "import isEmpty from './utils/isEmpty';\nimport isCharHiragana from './utils/isCharHiragana';\n\n/**\n * Test if `input` is [Hiragana](https://en.wikipedia.org/wiki/Hiragana)\n * @param {String} [input=''] text\n * @return {Boolean} true if all [Hiragana](https://en.wikipedia.org/wiki/Hiragana)\n * @example\n * isHiragana('げーむ')\n * // => true\n * isHiragana('A')\n * // => false\n * isHiragana('あア')\n * // => false\n */\nfunction isHiragana(input = '') {\n if (isEmpty(input)) return false;\n return [...input].every(isCharHiragana);\n}\n\nexport default isHiragana;\n", "import isEmpty from './utils/isEmpty';\nimport isCharKatakana from './utils/isCharKatakana';\n\n/**\n * Test if `input` is [Katakana](https://en.wikipedia.org/wiki/Katakana)\n * @param {String} [input=''] text\n * @return {Boolean} true if all [Katakana](https://en.wikipedia.org/wiki/Katakana)\n * @example\n * isKatakana('ゲーム')\n * // => true\n * isKatakana('あ')\n * // => false\n * isKatakana('A')\n * // => false\n * isKatakana('あア')\n * // => false\n */\nfunction isKatakana(input = '') {\n if (isEmpty(input)) return false;\n return [...input].every(isCharKatakana);\n}\n\nexport default isKatakana;\n", "import isEmpty from './isEmpty';\nimport { KANJI_ITERATION_MARK } from '../constants.ts';\n\n/**\n * Returns true if char is '々'\n * @param {String} char to test\n * @return {Boolean}\n */\nfunction isCharIterationMark(char = '') {\n if (isEmpty(char)) return false;\n return char.charCodeAt(0) === KANJI_ITERATION_MARK;\n}\n\nexport default isCharIterationMark;\n", "import { KANJI_START, KANJI_END } from '../constants.ts';\n\nimport isCharInRange from './isCharInRange';\nimport isCharIterationMark from './isCharIterationMark';\n/**\n * Tests a character. Returns true if the character is a CJK ideograph (kanji).\n * @param {String} char character string to test\n * @return {Boolean}\n */\nfunction isCharKanji(char = '') {\n return isCharInRange(char, KANJI_START, KANJI_END) || isCharIterationMark(char);\n}\n\nexport default isCharKanji;\n", "import isEmpty from './utils/isEmpty';\nimport isCharKanji from './utils/isCharKanji';\n\n/**\n * Tests if `input` is [Kanji](https://en.wikipedia.org/wiki/Kanji) ([Japanese CJK ideographs](https://en.wikipedia.org/wiki/CJK_Unified_Ideographs))\n * @param {String} [input=''] text\n * @return {Boolean} true if all [Kanji](https://en.wikipedia.org/wiki/Kanji)\n * @example\n * isKanji('刀')\n * // => true\n * isKanji('切腹')\n * // => true\n * isKanji('勢い')\n * // => false\n * isKanji('あAア')\n * // => false\n * isKanji('🐸')\n * // => false\n */\nfunction isKanji(input = '') {\n if (isEmpty(input)) return false;\n return [...input].every(isCharKanji);\n}\n\nexport default isKanji;\n", "import isKanji from './isKanji';\nimport isHiragana from './isHiragana';\nimport isKatakana from './isKatakana';\nimport isRomaji from './isRomaji';\n\n/**\n * Test if `input` contains a mix of [Romaji](https://en.wikipedia.org/wiki/Romaji) *and* [Kana](https://en.wikipedia.org/wiki/Kana), defaults to pass through [Kanji](https://en.wikipedia.org/wiki/Kanji)\n * @param {String} input text\n * @param {{ passKanji: Boolean}} [options={ passKanji: true }] optional config to pass through kanji\n * @return {Boolean} true if mixed\n * @example\n * isMixed('Abあア'))\n * // => true\n * isMixed('お腹A')) // ignores kanji by default\n * // => true\n * isMixed('お腹A', { passKanji: false }))\n * // => false\n * isMixed('ab'))\n * // => false\n * isMixed('あア'))\n * // => false\n */\nfunction isMixed(input = '', options = { passKanji: true }) {\n const chars = [...input];\n let hasKanji = false;\n if (!options.passKanji) {\n hasKanji = chars.some(isKanji);\n }\n return (chars.some(isHiragana) || chars.some(isKatakana)) && chars.some(isRomaji) && !hasKanji;\n}\n\nexport default isMixed;\n", "import { KATAKANA_START, HIRAGANA_START } from '../constants.ts';\n\nimport isCharLongDash from './isCharLongDash';\nimport isCharSlashDot from './isCharSlashDot';\nimport isCharKatakana from './isCharKatakana';\nconst isCharInitialLongDash = (char, index) => isCharLongDash(char) && index < 1;\nconst isCharInnerLongDash = (char, index) => isCharLongDash(char) && index > 0;\nconst isKanaAsSymbol = (char) => ['ヶ', 'ヵ'].includes(char);\nconst LONG_VOWELS = {\n a: 'あ',\n i: 'い',\n u: 'う',\n e: 'え',\n o: 'う',\n};\n\n// inject toRomaji to avoid circular dependency between toRomaji <-> katakanaToHiragana\nfunction katakanaToHiragana(\n input = '',\n toRomaji,\n { isDestinationRomaji, convertLongVowelMark } = {}\n) {\n let previousKana = '';\n\n return input\n .split('')\n .reduce((hira, char, index) => {\n // Short circuit to avoid incorrect codeshift for 'ー' and '・'\n if (\n isCharSlashDot(char)\n || isCharInitialLongDash(char, index)\n || isKanaAsSymbol(char)\n ) {\n return hira.concat(char);\n }\n\n // Transform long vowels: 'オー' to 'おう'\n if (\n convertLongVowelMark\n && previousKana\n && isCharInnerLongDash(char, index)\n ) {\n // Transform previousKana back to romaji, and slice off the vowel\n const romaji = toRomaji(previousKana).slice(-1);\n // However, ensure 'オー' => 'おお' => 'oo' if this is a transform on the way to romaji\n if (\n isCharKatakana(input[index - 1])\n && romaji === 'o'\n && isDestinationRomaji\n ) {\n return hira.concat('お');\n }\n return hira.concat(LONG_VOWELS[romaji]);\n // Transform all other chars\n }\n\n if (!isCharLongDash(char) && isCharKatakana(char)) {\n const code = char.charCodeAt(0) + (HIRAGANA_START - KATAKANA_START);\n const hiraChar = String.fromCharCode(code);\n previousKana = hiraChar;\n return hira.concat(hiraChar);\n }\n\n // Pass non katakana chars through\n previousKana = '';\n return hira.concat(char);\n }, [])\n .join('');\n}\n\nexport default katakanaToHiragana;\n", "import { transform, getSubTreeOf } from './kanaMapping';\nimport { ROMANIZATIONS } from '../constants.ts';\n\nlet kanaToHepburnMap = null;\n\n/* eslint-disable */\n// prettier-ignore\nconst BASIC_ROMAJI = {\n あ:'a', い:'i', う:'u', え:'e', お:'o',\n か:'ka', き:'ki', く:'ku', け:'ke', こ:'ko',\n さ:'sa', し:'shi', す:'su', せ:'se', そ:'so',\n た:'ta', ち:'chi', つ:'tsu', て:'te', と:'to',\n な:'na', に:'ni', ぬ:'nu', ね:'ne', の:'no',\n は:'ha', ひ:'hi', ふ:'fu', へ:'he', ほ:'ho',\n ま:'ma', み:'mi', む:'mu', め:'me', も:'mo',\n ら:'ra', り:'ri', る:'ru', れ:'re', ろ:'ro',\n や:'ya', ゆ:'yu', よ:'yo',\n わ:'wa', ゐ:'wi', ゑ:'we', を:'wo',\n ん: 'n',\n が:'ga', ぎ:'gi', ぐ:'gu', げ:'ge', ご:'go',\n ざ:'za', じ:'ji', ず:'zu', ぜ:'ze', ぞ:'zo',\n だ:'da', ぢ:'ji', づ:'zu', で:'de', ど:'do',\n ば:'ba', び:'bi', ぶ:'bu', べ:'be', ぼ:'bo',\n ぱ:'pa', ぴ:'pi', ぷ:'pu', ぺ:'pe', ぽ:'po',\n ゔぁ:'va', ゔぃ:'vi', ゔ:'vu', ゔぇ:'ve', ゔぉ:'vo',\n};\n/* eslint-enable */\n\nconst SPECIAL_SYMBOLS = {\n '。': '.',\n '、': ',',\n ':': ':',\n '・': '/',\n '!': '!',\n '?': '?',\n '〜': '~',\n 'ー': '-',\n '「': '‘',\n '」': '’',\n '『': '“',\n '』': '”',\n '[': '[',\n ']': ']',\n '(': '(',\n ')': ')',\n '{': '{',\n '}': '}',\n ' ': ' ',\n};\n\n// んい -> n'i\nconst AMBIGUOUS_VOWELS = ['あ', 'い', 'う', 'え', 'お', 'や', 'ゆ', 'よ'];\nconst SMALL_Y = { ゃ: 'ya', ゅ: 'yu', ょ: 'yo' };\nconst SMALL_Y_EXTRA = { ぃ: 'yi', ぇ: 'ye' };\nconst SMALL_AIUEO = {\n ぁ: 'a',\n ぃ: 'i',\n ぅ: 'u',\n ぇ: 'e',\n ぉ: 'o',\n};\nconst YOON_KANA = [\n 'き',\n 'に',\n 'ひ',\n 'み',\n 'り',\n 'ぎ',\n 'び',\n 'ぴ',\n 'ゔ',\n 'く',\n 'ふ',\n];\nconst YOON_EXCEPTIONS = {\n し: 'sh',\n ち: 'ch',\n じ: 'j',\n ぢ: 'j',\n};\nconst SMALL_KANA = {\n っ: '',\n ゃ: 'ya',\n ゅ: 'yu',\n ょ: 'yo',\n ぁ: 'a',\n ぃ: 'i',\n ぅ: 'u',\n ぇ: 'e',\n ぉ: 'o',\n};\n\n// going with the intuitive (yet incorrect) solution where っや -> yya and っぃ -> ii\n// in other words, just assume the sokuon could have been applied to anything\nconst SOKUON_WHITELIST = {\n b: 'b',\n c: 't',\n d: 'd',\n f: 'f',\n g: 'g',\n h: 'h',\n j: 'j',\n k: 'k',\n m: 'm',\n p: 'p',\n q: 'q',\n r: 'r',\n s: 's',\n t: 't',\n v: 'v',\n w: 'w',\n x: 'x',\n z: 'z',\n};\n\nfunction getKanaToHepburnTree() {\n if (kanaToHepburnMap == null) {\n kanaToHepburnMap = createKanaToHepburnMap();\n }\n return kanaToHepburnMap;\n}\n\nexport function getKanaToRomajiTree(romanization) {\n switch (romanization) {\n case ROMANIZATIONS.HEPBURN:\n return getKanaToHepburnTree();\n default:\n return {};\n }\n}\n\nfunction createKanaToHepburnMap() {\n const romajiTree = transform(BASIC_ROMAJI);\n\n const subtreeOf = (string) => getSubTreeOf(romajiTree, string);\n const setTrans = (string, transliteration) => {\n subtreeOf(string)[''] = transliteration;\n };\n\n Object.entries(SPECIAL_SYMBOLS).forEach(([jsymbol, symbol]) => {\n subtreeOf(jsymbol)[''] = symbol;\n });\n\n [...Object.entries(SMALL_Y), ...Object.entries(SMALL_AIUEO)].forEach(\n ([roma, kana]) => {\n setTrans(roma, kana);\n }\n );\n\n // きゃ -> kya\n YOON_KANA.forEach((kana) => {\n const firstRomajiChar = subtreeOf(kana)[''][0];\n Object.entries(SMALL_Y).forEach(([yKana, yRoma]) => {\n setTrans(kana + yKana, firstRomajiChar + yRoma);\n });\n // きぃ -> kyi\n Object.entries(SMALL_Y_EXTRA).forEach(([yKana, yRoma]) => {\n setTrans(kana + yKana, firstRomajiChar + yRoma);\n });\n });\n\n Object.entries(YOON_EXCEPTIONS).forEach(([kana, roma]) => {\n // じゃ -> ja\n Object.entries(SMALL_Y).forEach(([yKana, yRoma]) => {\n setTrans(kana + yKana, roma + yRoma[1]);\n });\n // じぃ -> jyi, じぇ -> je\n setTrans(`${kana}ぃ`, `${roma}yi`);\n setTrans(`${kana}ぇ`, `${roma}e`);\n });\n\n romajiTree['っ'] = resolveTsu(romajiTree);\n\n Object.entries(SMALL_KANA).forEach(([kana, roma]) => {\n setTrans(kana, roma);\n });\n\n AMBIGUOUS_VOWELS.forEach((kana) => {\n setTrans(`ん${kana}`, `n'${subtreeOf(kana)['']}`);\n });\n\n // NOTE: could be re-enabled with an option?\n // // んば -> mbo\n // const LABIAL = [\n // 'ば', 'び', 'ぶ', 'べ', 'ぼ',\n // 'ぱ', 'ぴ', 'ぷ', 'ぺ', 'ぽ',\n // 'ま', 'み', 'む', 'め', 'も',\n // ];\n // LABIAL.forEach((kana) => {\n // setTrans(`ん${kana}`, `m${subtreeOf(kana)['']}`);\n // });\n\n return Object.freeze(JSON.parse(JSON.stringify(romajiTree)));\n}\n\nfunction resolveTsu(tree) {\n return Object.entries(tree).reduce((tsuTree, [key, value]) => {\n if (!key) {\n // we have reached the bottom of this branch\n const consonant = value.charAt(0);\n // eslint-disable-next-line no-param-reassign\n tsuTree[key] = Object.keys(SOKUON_WHITELIST).includes(consonant)\n ? SOKUON_WHITELIST[consonant] + value\n : value;\n } else {\n // more subtrees\n // eslint-disable-next-line no-param-reassign\n tsuTree[key] = resolveTsu(value);\n }\n return tsuTree;\n }, {});\n}\n", "import memoizeOne from 'memoize-one';\nimport { dequal } from 'dequal';\n\nimport mergeWithDefaultOptions from './utils/mergeWithDefaultOptions';\nimport katakanaToHiragana from './utils/katakanaToHiragana';\nimport isKatakana from './isKatakana';\nimport { getKanaToRomajiTree } from './utils/kanaToRomajiMap';\nimport { applyMapping, mergeCustomMapping } from './utils/kanaMapping';\n\n// memoize and deeply compare args so we only recreate when necessary\nexport const createKanaToRomajiMap = memoizeOne(\n (romanization, customRomajiMapping) => {\n let map = getKanaToRomajiTree(romanization);\n\n if (customRomajiMapping) {\n map = mergeCustomMapping(map, customRomajiMapping);\n }\n\n return map;\n },\n dequal\n);\n\n/**\n * Convert kana to romaji\n * @param {String} kana text input\n * @param {DefaultOptions} [options=defaultOptions]\n * @param {Object.} [map] custom mapping\n * @return {String} converted text\n * @example\n * toRomaji('ひらがな カタカナ')\n * // => 'hiragana katakana'\n * toRomaji('げーむ ゲーム')\n * // => 'ge-mu geemu'\n * toRomaji('ひらがな カタカナ', { upcaseKatakana: true })\n * // => 'hiragana KATAKANA'\n * toRomaji('つじぎり', { customRomajiMapping: { じ: 'zi', つ: 'tu', り: 'li' } });\n * // => 'tuzigili'\n */\nexport function toRomaji(input = '', options = {}, map) {\n const config = mergeWithDefaultOptions(options);\n\n if (!map) {\n map = createKanaToRomajiMap(\n config.romanization,\n config.customRomajiMapping\n );\n }\n\n // just throw away the substring index information and simply concatenate all the kana\n return splitIntoRomaji(input, config, map)\n .map((romajiToken) => {\n const [start, end, romaji] = romajiToken;\n const makeUpperCase = config.upcaseKatakana && isKatakana(input.slice(start, end));\n return makeUpperCase ? romaji.toUpperCase() : romaji;\n })\n .join('');\n}\n\nfunction splitIntoRomaji(input, options, map) {\n if (!map) {\n map = createKanaToRomajiMap(\n options.romanization,\n options.customRomajiMapping\n );\n }\n\n const config = Object.assign({}, { isDestinationRomaji: true }, options);\n\n return applyMapping(\n katakanaToHiragana(input, toRomaji, config),\n map,\n !options.IMEMode\n );\n}\n\nexport default toRomaji;\n", "import isEmpty from './isEmpty';\nimport { EN_PUNCTUATION_RANGES } from '../constants.ts';\nimport isCharInRange from './isCharInRange';\n\n/**\n * Tests a character. Returns true if the character is considered English punctuation.\n * @param {String} char character string to test\n * @return {Boolean}\n */\nfunction isCharEnglishPunctuation(char = '') {\n if (isEmpty(char)) return false;\n return EN_PUNCTUATION_RANGES.some(([start, end]) => isCharInRange(char, start, end));\n}\n\nexport default isCharEnglishPunctuation;\n", "import mergeWithDefaultOptions from './utils/mergeWithDefaultOptions';\nimport katakanaToHiragana from './utils/katakanaToHiragana';\nimport isCharEnglishPunctuation from './utils/isCharEnglishPunctuation';\nimport isRomaji from './isRomaji';\nimport isMixed from './isMixed';\nimport toKana from './toKana';\nimport toRomaji from './toRomaji';\n\n/**\n * Convert input to [Hiragana](https://en.wikipedia.org/wiki/Hiragana)\n * @param {String} [input=''] text\n * @param {DefaultOptions} [options=defaultOptions]\n * @return {String} converted text\n * @example\n * toHiragana('toukyou, オオサカ')\n * // => 'とうきょう、 おおさか'\n * toHiragana('only カナ', { passRomaji: true })\n * // => 'only かな'\n * toHiragana('wi')\n * // => 'うぃ'\n * toHiragana('wi', { useObsoleteKana: true })\n * // => 'ゐ'\n */\nfunction toHiragana(input = '', options = {}) {\n const config = mergeWithDefaultOptions(options);\n if (config.passRomaji) {\n return katakanaToHiragana(input, toRomaji, config);\n }\n\n if (isMixed(input, { passKanji: true })) {\n const convertedKatakana = katakanaToHiragana(input, toRomaji, config);\n return toKana(convertedKatakana.toLowerCase(), config);\n }\n\n if (isRomaji(input) || isCharEnglishPunctuation(input)) {\n return toKana(input.toLowerCase(), config);\n }\n\n return katakanaToHiragana(input, toRomaji, config);\n}\n\nexport default toHiragana;\n", "import mergeWithDefaultOptions from './utils/mergeWithDefaultOptions';\nimport hiraganaToKatakana from './utils/hiraganaToKatakana';\nimport isCharEnglishPunctuation from './utils/isCharEnglishPunctuation';\nimport toKana from './toKana';\nimport isRomaji from './isRomaji';\nimport isMixed from './isMixed';\n\n/**\n * Convert input to [Katakana](https://en.wikipedia.org/wiki/Katakana)\n * @param {String} [input=''] text\n * @param {DefaultOptions} [options=defaultOptions]\n * @return {String} converted text\n * @example\n * toKatakana('toukyou, おおさか')\n * // => 'トウキョウ、 オオサカ'\n * toKatakana('only かな', { passRomaji: true })\n * // => 'only カナ'\n * toKatakana('wi')\n * // => 'ウィ'\n * toKatakana('wi', { useObsoleteKana: true })\n * // => 'ヰ'\n */\nfunction toKatakana(input = '', options = {}) {\n const mergedOptions = mergeWithDefaultOptions(options);\n if (mergedOptions.passRomaji) {\n return hiraganaToKatakana(input);\n }\n\n if (isMixed(input) || isRomaji(input) || isCharEnglishPunctuation(input)) {\n const hiragana = toKana(input.toLowerCase(), mergedOptions);\n return hiraganaToKatakana(hiragana);\n }\n\n return hiraganaToKatakana(input);\n}\n\nexport default toKatakana;\n", "import isEmpty from './isEmpty';\nimport { JA_PUNCTUATION_RANGES } from '../constants.ts';\nimport isCharInRange from './isCharInRange';\nimport isCharIterationMark from './isCharIterationMark';\n\n/**\n * Tests a character. Returns true if the character is considered Japanese punctuation.\n * @param {String} char character string to test\n * @return {Boolean}\n */\nfunction isCharJapanesePunctuation(char = '') {\n if (isEmpty(char) || isCharIterationMark(char)) return false;\n return JA_PUNCTUATION_RANGES.some(([start, end]) => isCharInRange(char, start, end));\n}\n\nexport default isCharJapanesePunctuation;\n", "import isEmpty from './utils/isEmpty';\nimport isCharEnglishPunctuation from './utils/isCharEnglishPunctuation';\nimport isCharJapanesePunctuation from './utils/isCharJapanesePunctuation';\nimport isCharRomaji from './utils/isCharRomaji';\nimport isCharKanji from './utils/isCharKanji';\nimport isCharHiragana from './utils/isCharHiragana';\nimport isCharKatakana from './utils/isCharKatakana';\nimport isCharJapanese from './utils/isCharJapanese';\n\nconst isCharEnSpace = (x) => x === ' ';\nconst isCharJaSpace = (x) => x === ' ';\nconst isCharJaNum = (x) => /[0-9]/.test(x);\nconst isCharEnNum = (x) => /[0-9]/.test(x);\n\nconst TOKEN_TYPES = {\n EN: 'en',\n JA: 'ja',\n EN_NUM: 'englishNumeral',\n JA_NUM: 'japaneseNumeral',\n EN_PUNC: 'englishPunctuation',\n JA_PUNC: 'japanesePunctuation',\n KANJI: 'kanji',\n HIRAGANA: 'hiragana',\n KATAKANA: 'katakana',\n SPACE: 'space',\n OTHER: 'other',\n};\n\n// prettier-ignore\nexport function getType(input, compact = false) {\n const {\n EN, JA, EN_NUM, JA_NUM, EN_PUNC, JA_PUNC, KANJI, HIRAGANA, KATAKANA, SPACE, OTHER,\n } = TOKEN_TYPES;\n\n if (compact) {\n switch (true) {\n case isCharJaNum(input): return OTHER;\n case isCharEnNum(input): return OTHER;\n case isCharEnSpace(input): return EN;\n case isCharEnglishPunctuation(input): return OTHER;\n case isCharJaSpace(input): return JA;\n case isCharJapanesePunctuation(input): return OTHER;\n case isCharJapanese(input): return JA;\n case isCharRomaji(input): return EN;\n default: return OTHER;\n }\n } else {\n switch (true) {\n case isCharJaSpace(input): return SPACE;\n case isCharEnSpace(input): return SPACE;\n case isCharJaNum(input): return JA_NUM;\n case isCharEnNum(input): return EN_NUM;\n case isCharEnglishPunctuation(input): return EN_PUNC;\n case isCharJapanesePunctuation(input): return JA_PUNC;\n case isCharKanji(input): return KANJI;\n case isCharHiragana(input): return HIRAGANA;\n case isCharKatakana(input): return KATAKANA;\n case isCharJapanese(input): return JA;\n case isCharRomaji(input): return EN;\n default: return OTHER;\n }\n }\n}\n\n/**\n * Splits input into array of strings separated by opinionated token types\n * `'en', 'ja', 'englishNumeral', 'japaneseNumeral','englishPunctuation', 'japanesePunctuation','kanji', 'hiragana', 'katakana', 'space', 'other'`.\n * If `{ compact: true }` then many same-language tokens are combined (spaces + text, kanji + kana, numeral + punctuation).\n * If `{ detailed: true }` then return array will contain `{ type, value }` instead of `'value'`\n * @param {String} input text\n * @param {{compact: Boolean | undefined, detailed: Boolean | undefined}} [options={ compact: false, detailed: false}] options to modify output style\n * @return {(String[]|Array.<{type: String, value: String}>)} text split into tokens containing values, or detailed object\n * @example\n * tokenize('ふふフフ')\n * // ['ふふ', 'フフ']\n *\n * tokenize('感じ')\n * // ['感', 'じ']\n *\n * tokenize('人々')\n * // ['人々']\n *\n * tokenize('truly 私は悲しい')\n * // ['truly', ' ', '私', 'は', '悲', 'しい']\n *\n * tokenize('truly 私は悲しい', { compact: true })\n * // ['truly ', '私は悲しい']\n *\n * tokenize('5romaji here...!?人々漢字ひらがなカタ カナ4「SHIO」。!')\n * // [ '5', 'romaji', ' ', 'here', '...!?', '人々漢字', 'ひらがな', 'カタ', ' ', 'カナ', '4', '「', 'SHIO', '」。!']\n *\n * tokenize('5romaji here...!?人々漢字ひらがなカタ カナ4「SHIO」。!', { compact: true })\n * // [ '5', 'romaji here', '...!?', '人々漢字ひらがなカタ カナ', '4「', 'SHIO', '」。!']\n *\n * tokenize('5romaji here...!?人々漢字ひらがなカタ カナ4「SHIO」。! لنذهب', { detailed: true })\n * // [\n * { type: 'englishNumeral', value: '5' },\n * { type: 'en', value: 'romaji' },\n * { type: 'space', value: ' ' },\n * { type: 'en', value: 'here' },\n * { type: 'englishPunctuation', value: '...!?' },\n * { type: 'kanji', value: '人々漢字' },\n * { type: 'hiragana', value: 'ひらがな' },\n * { type: 'katakana', value: 'カタ' },\n * { type: 'space', value: ' ' },\n * { type: 'katakana', value: 'カナ' },\n * { type: 'japaneseNumeral', value: '4' },\n * { type: 'japanesePunctuation', value: '「' },\n * { type: 'ja', value: 'SHIO' },\n * { type: 'japanesePunctuation', value: '」。!' },\n * { type: 'space', value: ' ' },\n * { type: 'other', value: 'لنذهب' },\n * ]\n *\n * tokenize('5romaji here...!?人々漢字ひらがなカタ カナ4「SHIO」。! لنذهب', { compact: true, detailed: true})\n * // [\n * { type: 'other', value: '5' },\n * { type: 'en', value: 'romaji here' },\n * { type: 'other', value: '...!?' },\n * { type: 'ja', value: '人々漢字ひらがなカタ カナ' },\n * { type: 'other', value: '4「' },\n * { type: 'ja', value: 'SHIO' },\n * { type: 'other', value: '」。!' },\n * { type: 'en', value: ' ' },\n * { type: 'other', value: 'لنذهب' },\n *]\n */\nfunction tokenize(input, { compact = false, detailed = false } = {}) {\n if (input == null || isEmpty(input)) {\n return [];\n }\n const chars = [...input];\n let initial = chars.shift();\n let prevType = getType(initial, compact);\n initial = detailed ? { type: prevType, value: initial } : initial;\n\n const result = chars.reduce(\n (tokens, char) => {\n const currType = getType(char, compact);\n const sameType = currType === prevType;\n prevType = currType;\n let newValue = char;\n\n if (sameType) {\n newValue = (detailed ? tokens.pop().value : tokens.pop()) + newValue;\n }\n\n return detailed\n ? tokens.concat({ type: currType, value: newValue })\n : tokens.concat(newValue);\n },\n [initial]\n );\n return result;\n}\n\nexport default tokenize;\n", "import isJapanese from './isJapanese';\nimport isKana from './isKana';\nimport isKanji from './isKanji';\nimport tokenize from './tokenize';\n\nconst isLeadingWithoutInitialKana = (input, leading) => leading && !isKana(input[0]);\nconst isTrailingWithoutFinalKana = (input, leading) => !leading && !isKana(input[input.length - 1]);\nconst isInvalidMatcher = (input, matchKanji) =>\n (matchKanji && ![...matchKanji].some(isKanji)) || (!matchKanji && isKana(input));\n\n/**\n * Strips [Okurigana](https://en.wikipedia.org/wiki/Okurigana)\n * @param {String} input text\n * @param {{ leading: Boolean | undefined, matchKanji: string | undefined }} [options={ leading: false, matchKanji: '' }] optional config\n * @return {String} text with okurigana removed\n * @example\n * stripOkurigana('踏み込む')\n * // => '踏み込'\n * stripOkurigana('お祝い')\n * // => 'お祝'\n * stripOkurigana('お腹', { leading: true });\n * // => '腹'\n * stripOkurigana('ふみこむ', { matchKanji: '踏み込む' });\n * // => 'ふみこ'\n * stripOkurigana('おみまい', { matchKanji: 'お祝い', leading: true });\n * // => 'みまい'\n */\nfunction stripOkurigana(input = '', { leading = false, matchKanji = '' } = {}) {\n if (\n !isJapanese(input) ||\n isLeadingWithoutInitialKana(input, leading) ||\n isTrailingWithoutFinalKana(input, leading) ||\n isInvalidMatcher(input, matchKanji)\n ) {\n return input;\n }\n\n const chars = matchKanji || input;\n const okuriganaRegex = new RegExp(\n leading ? `^${tokenize(chars).shift()}` : `${tokenize(chars).pop()}$`\n );\n return input.replace(okuriganaRegex, '');\n}\n\nexport default stripOkurigana;\n"], "mappings": "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", "names": ["isEqual", "SPECIAL_SYMBOLS", "SMALL_Y", "createRomajiToKanaMap", "onInput", "toRomaji"] }