// @ts-nocheck // node_modules/wanakana/esm/index.js function typeOf(value) { if (value === null) { return "null"; } if (value !== Object(value)) { return typeof value; } return {}.toString.call(value).slice(8, -1).toLowerCase(); } function isEmpty(input) { if (typeOf(input) !== "string") { return true; } return !input.length; } function isCharInRange(char = "", start, end) { if (isEmpty(char)) return false; const code = char.charCodeAt(0); return start <= code && code <= end; } var VERSION = "5.3.1"; var TO_KANA_METHODS = { HIRAGANA: "toHiragana", KATAKANA: "toKatakana" }; var ROMANIZATIONS = { HEPBURN: "hepburn" }; var DEFAULT_OPTIONS = { useObsoleteKana: false, passRomaji: false, convertLongVowelMark: true, upcaseKatakana: false, IMEMode: false, romanization: ROMANIZATIONS.HEPBURN }; var LATIN_UPPERCASE_START = 65; var LATIN_UPPERCASE_END = 90; var LOWERCASE_ZENKAKU_START = 65345; var LOWERCASE_ZENKAKU_END = 65370; var UPPERCASE_ZENKAKU_START = 65313; var UPPERCASE_ZENKAKU_END = 65338; var HIRAGANA_START = 12353; var HIRAGANA_END = 12438; var KATAKANA_START = 12449; var KATAKANA_END = 12540; var KANJI_START = 19968; var KANJI_END = 40879; var KANJI_ITERATION_MARK = 12293; var PROLONGED_SOUND_MARK = 12540; var KANA_SLASH_DOT = 12539; var ZENKAKU_NUMBERS = [65296, 65305]; var ZENKAKU_UPPERCASE = [UPPERCASE_ZENKAKU_START, UPPERCASE_ZENKAKU_END]; var ZENKAKU_LOWERCASE = [LOWERCASE_ZENKAKU_START, LOWERCASE_ZENKAKU_END]; var ZENKAKU_PUNCTUATION_1 = [65281, 65295]; var ZENKAKU_PUNCTUATION_2 = [65306, 65311]; var ZENKAKU_PUNCTUATION_3 = [65339, 65343]; var ZENKAKU_PUNCTUATION_4 = [65371, 65376]; var ZENKAKU_SYMBOLS_CURRENCY = [65504, 65518]; var HIRAGANA_CHARS = [12352, 12447]; var KATAKANA_CHARS = [12448, 12543]; var HANKAKU_KATAKANA = [65382, 65439]; var KATAKANA_PUNCTUATION = [12539, 12540]; var KANA_PUNCTUATION = [65377, 65381]; var CJK_SYMBOLS_PUNCTUATION = [12288, 12351]; var COMMON_CJK = [19968, 40959]; var RARE_CJK = [13312, 19903]; var KANA_RANGES = [ HIRAGANA_CHARS, KATAKANA_CHARS, KANA_PUNCTUATION, HANKAKU_KATAKANA ]; var JA_PUNCTUATION_RANGES = [ CJK_SYMBOLS_PUNCTUATION, KANA_PUNCTUATION, KATAKANA_PUNCTUATION, ZENKAKU_PUNCTUATION_1, ZENKAKU_PUNCTUATION_2, ZENKAKU_PUNCTUATION_3, ZENKAKU_PUNCTUATION_4, ZENKAKU_SYMBOLS_CURRENCY ]; var JAPANESE_RANGES = [ ...KANA_RANGES, ...JA_PUNCTUATION_RANGES, ZENKAKU_UPPERCASE, ZENKAKU_LOWERCASE, ZENKAKU_NUMBERS, COMMON_CJK, RARE_CJK ]; var MODERN_ENGLISH = [0, 127]; var HEPBURN_MACRON_RANGES = [ [256, 257], [274, 275], [298, 299], [332, 333], [362, 363] // Ū ū ]; var SMART_QUOTE_RANGES = [ [8216, 8217], [8220, 8221] // “ ” ]; var ROMAJI_RANGES = [MODERN_ENGLISH, ...HEPBURN_MACRON_RANGES]; var EN_PUNCTUATION_RANGES = [ [32, 47], [58, 63], [91, 96], [123, 126], ...SMART_QUOTE_RANGES ]; function isCharJapanese(char = "") { return JAPANESE_RANGES.some(([start, end]) => isCharInRange(char, start, end)); } function isJapanese(input = "", allowed) { const augmented = typeOf(allowed) === "regexp"; return isEmpty(input) ? false : [...input].every((char) => { const isJa = isCharJapanese(char); return !augmented ? isJa : isJa || allowed.test(char); }); } var safeIsNaN = Number.isNaN || function ponyfill(value) { return typeof value === "number" && value !== value; }; function isEqual(first, second) { if (first === second) { return true; } if (safeIsNaN(first) && safeIsNaN(second)) { return true; } return false; } function areInputsEqual(newInputs, lastInputs) { if (newInputs.length !== lastInputs.length) { return false; } for (var i = 0; i < newInputs.length; i++) { if (!isEqual(newInputs[i], lastInputs[i])) { return false; } } return true; } function memoizeOne(resultFn, isEqual2) { if (isEqual2 === void 0) { isEqual2 = areInputsEqual; } var cache = null; function memoized() { var newArgs = []; for (var _i = 0; _i < arguments.length; _i++) { newArgs[_i] = arguments[_i]; } if (cache && cache.lastThis === this && isEqual2(newArgs, cache.lastArgs)) { return cache.lastResult; } var lastResult = resultFn.apply(this, newArgs); cache = { lastResult, lastArgs: newArgs, lastThis: this }; return lastResult; } memoized.clear = function clear() { cache = null; }; return memoized; } var has = Object.prototype.hasOwnProperty; function find(iter, tar, key) { for (key of iter.keys()) { if (dequal(key, tar)) return key; } } function dequal(foo, bar) { var ctor, len, tmp; if (foo === bar) return true; if (foo && bar && (ctor = foo.constructor) === bar.constructor) { if (ctor === Date) return foo.getTime() === bar.getTime(); if (ctor === RegExp) return foo.toString() === bar.toString(); if (ctor === Array) { if ((len = foo.length) === bar.length) { while (len-- && dequal(foo[len], bar[len])) ; } return len === -1; } if (ctor === Set) { if (foo.size !== bar.size) { return false; } for (len of foo) { tmp = len; if (tmp && typeof tmp === "object") { tmp = find(bar, tmp); if (!tmp) return false; } if (!bar.has(tmp)) return false; } return true; } if (ctor === Map) { if (foo.size !== bar.size) { return false; } for (len of foo) { tmp = len[0]; if (tmp && typeof tmp === "object") { tmp = find(bar, tmp); if (!tmp) return false; } if (!dequal(len[1], bar.get(tmp))) { return false; } } return true; } if (ctor === ArrayBuffer) { foo = new Uint8Array(foo); bar = new Uint8Array(bar); } else if (ctor === DataView) { if ((len = foo.byteLength) === bar.byteLength) { while (len-- && foo.getInt8(len) === bar.getInt8(len)) ; } return len === -1; } if (ArrayBuffer.isView(foo)) { if ((len = foo.byteLength) === bar.byteLength) { while (len-- && foo[len] === bar[len]) ; } return len === -1; } if (!ctor || typeof foo === "object") { len = 0; for (ctor in foo) { if (has.call(foo, ctor) && ++len && !has.call(bar, ctor)) return false; if (!(ctor in bar) || !dequal(foo[ctor], bar[ctor])) return false; } return Object.keys(bar).length === len; } } return foo !== foo && bar !== bar; } var mergeWithDefaultOptions = (opts = {}) => Object.assign({}, DEFAULT_OPTIONS, opts); function applyMapping(string, mapping, convertEnding) { const root = mapping; function nextSubtree(tree, nextChar) { const subtree = tree[nextChar]; if (subtree === void 0) { return void 0; } return Object.assign({ "": tree[""] + nextChar }, tree[nextChar]); } function newChunk(remaining, currentCursor) { const firstChar = remaining.charAt(0); return parse(Object.assign({ "": firstChar }, root[firstChar]), remaining.slice(1), currentCursor, currentCursor + 1); } function parse(tree, remaining, lastCursor, currentCursor) { if (!remaining) { if (convertEnding || Object.keys(tree).length === 1) { return tree[""] ? [[lastCursor, currentCursor, tree[""]]] : []; } return [[lastCursor, currentCursor, null]]; } if (Object.keys(tree).length === 1) { return [[lastCursor, currentCursor, tree[""]]].concat(newChunk(remaining, currentCursor)); } const subtree = nextSubtree(tree, remaining.charAt(0)); if (subtree === void 0) { return [[lastCursor, currentCursor, tree[""]]].concat(newChunk(remaining, currentCursor)); } return parse(subtree, remaining.slice(1), lastCursor, currentCursor + 1); } return newChunk(string, 0); } function transform(tree) { return Object.entries(tree).reduce((map, [char, subtree]) => { const endOfBranch = typeOf(subtree) === "string"; map[char] = endOfBranch ? { "": subtree } : transform(subtree); return map; }, {}); } function getSubTreeOf(tree, string) { return string.split("").reduce((correctSubTree, char) => { if (correctSubTree[char] === void 0) { correctSubTree[char] = {}; } return correctSubTree[char]; }, tree); } function createCustomMapping(customMap = {}) { const customTree = {}; if (typeOf(customMap) === "object") { Object.entries(customMap).forEach(([roma, kana]) => { let subTree = customTree; roma.split("").forEach((char) => { if (subTree[char] === void 0) { subTree[char] = {}; } subTree = subTree[char]; }); subTree[""] = kana; }); } return function makeMap(map) { const mapCopy = JSON.parse(JSON.stringify(map)); function transformMap(mapSubtree, customSubtree) { if (mapSubtree === void 0 || typeOf(mapSubtree) === "string") { return customSubtree; } return Object.entries(customSubtree).reduce((newSubtree, [char, subtree]) => { newSubtree[char] = transformMap(mapSubtree[char], subtree); return newSubtree; }, mapSubtree); } return transformMap(mapCopy, customTree); }; } function mergeCustomMapping(map, customMapping) { if (!customMapping) { return map; } return typeOf(customMapping) === "function" ? customMapping(map) : createCustomMapping(customMapping)(map); } var BASIC_KUNREI = { a: "\u3042", i: "\u3044", u: "\u3046", e: "\u3048", o: "\u304A", k: { a: "\u304B", i: "\u304D", u: "\u304F", e: "\u3051", o: "\u3053" }, s: { a: "\u3055", i: "\u3057", u: "\u3059", e: "\u305B", o: "\u305D" }, t: { a: "\u305F", i: "\u3061", u: "\u3064", e: "\u3066", o: "\u3068" }, n: { a: "\u306A", i: "\u306B", u: "\u306C", e: "\u306D", o: "\u306E" }, h: { a: "\u306F", i: "\u3072", u: "\u3075", e: "\u3078", o: "\u307B" }, m: { a: "\u307E", i: "\u307F", u: "\u3080", e: "\u3081", o: "\u3082" }, y: { a: "\u3084", u: "\u3086", o: "\u3088" }, r: { a: "\u3089", i: "\u308A", u: "\u308B", e: "\u308C", o: "\u308D" }, w: { a: "\u308F", i: "\u3090", e: "\u3091", o: "\u3092" }, g: { a: "\u304C", i: "\u304E", u: "\u3050", e: "\u3052", o: "\u3054" }, z: { a: "\u3056", i: "\u3058", u: "\u305A", e: "\u305C", o: "\u305E" }, d: { a: "\u3060", i: "\u3062", u: "\u3065", e: "\u3067", o: "\u3069" }, b: { a: "\u3070", i: "\u3073", u: "\u3076", e: "\u3079", o: "\u307C" }, p: { a: "\u3071", i: "\u3074", u: "\u3077", e: "\u307A", o: "\u307D" }, v: { a: "\u3094\u3041", i: "\u3094\u3043", u: "\u3094", e: "\u3094\u3047", o: "\u3094\u3049" } }; var SPECIAL_SYMBOLS$1 = { ".": "\u3002", ",": "\u3001", ":": "\uFF1A", "/": "\u30FB", "!": "\uFF01", "?": "\uFF1F", "~": "\u301C", "-": "\u30FC", "\u2018": "\u300C", "\u2019": "\u300D", "\u201C": "\u300E", "\u201D": "\u300F", "[": "\uFF3B", "]": "\uFF3D", "(": "\uFF08", ")": "\uFF09", "{": "\uFF5B", "}": "\uFF5D" }; var CONSONANTS = { k: "\u304D", s: "\u3057", t: "\u3061", n: "\u306B", h: "\u3072", m: "\u307F", r: "\u308A", g: "\u304E", z: "\u3058", d: "\u3062", b: "\u3073", p: "\u3074", v: "\u3094", q: "\u304F", f: "\u3075" }; var SMALL_Y$1 = { ya: "\u3083", yi: "\u3043", yu: "\u3085", ye: "\u3047", yo: "\u3087" }; var SMALL_VOWELS = { a: "\u3041", i: "\u3043", u: "\u3045", e: "\u3047", o: "\u3049" }; var ALIASES = { sh: "sy", ch: "ty", cy: "ty", chy: "ty", shy: "sy", j: "zy", jy: "zy", // exceptions to above rules shi: "si", chi: "ti", tsu: "tu", ji: "zi", fu: "hu" }; var SMALL_LETTERS = Object.assign({ tu: "\u3063", wa: "\u308E", ka: "\u30F5", ke: "\u30F6" }, SMALL_VOWELS, SMALL_Y$1); var SPECIAL_CASES = { yi: "\u3044", wu: "\u3046", ye: "\u3044\u3047", wi: "\u3046\u3043", we: "\u3046\u3047", kwa: "\u304F\u3041", whu: "\u3046", // because it's not thya for てゃ but tha // and tha is not てぁ, but てゃ tha: "\u3066\u3083", thu: "\u3066\u3085", tho: "\u3066\u3087", dha: "\u3067\u3083", dhu: "\u3067\u3085", dho: "\u3067\u3087" }; var AIUEO_CONSTRUCTIONS = { wh: "\u3046", kw: "\u304F", qw: "\u304F", q: "\u304F", gw: "\u3050", sw: "\u3059", ts: "\u3064", th: "\u3066", tw: "\u3068", dh: "\u3067", dw: "\u3069", fw: "\u3075", f: "\u3075" }; function createRomajiToKanaMap$1() { const kanaTree = transform(BASIC_KUNREI); const subtreeOf = (string) => getSubTreeOf(kanaTree, string); Object.entries(CONSONANTS).forEach(([consonant, yKana]) => { Object.entries(SMALL_Y$1).forEach(([roma, kana]) => { subtreeOf(consonant + roma)[""] = yKana + kana; }); }); Object.entries(SPECIAL_SYMBOLS$1).forEach(([symbol, jsymbol]) => { subtreeOf(symbol)[""] = jsymbol; }); Object.entries(AIUEO_CONSTRUCTIONS).forEach(([consonant, aiueoKana]) => { Object.entries(SMALL_VOWELS).forEach(([vowel, kana]) => { const subtree = subtreeOf(consonant + vowel); subtree[""] = aiueoKana + kana; }); }); ["n", "n'", "xn"].forEach((nChar) => { subtreeOf(nChar)[""] = "\u3093"; }); kanaTree.c = JSON.parse(JSON.stringify(kanaTree.k)); Object.entries(ALIASES).forEach(([string, alternative]) => { const allExceptLast = string.slice(0, string.length - 1); const last = string.charAt(string.length - 1); const parentTree = subtreeOf(allExceptLast); parentTree[last] = JSON.parse(JSON.stringify(subtreeOf(alternative))); }); function getAlternatives(string) { return [...Object.entries(ALIASES), ...[["c", "k"]]].reduce((list, [alt, roma]) => string.startsWith(roma) ? list.concat(string.replace(roma, alt)) : list, []); } Object.entries(SMALL_LETTERS).forEach(([kunreiRoma, kana]) => { const last = (char) => char.charAt(char.length - 1); const allExceptLast = (chars) => chars.slice(0, chars.length - 1); const xRoma = `x${kunreiRoma}`; const xSubtree = subtreeOf(xRoma); xSubtree[""] = kana; const parentTree = subtreeOf(`l${allExceptLast(kunreiRoma)}`); parentTree[last(kunreiRoma)] = xSubtree; getAlternatives(kunreiRoma).forEach((altRoma) => { ["l", "x"].forEach((prefix) => { const altParentTree = subtreeOf(prefix + allExceptLast(altRoma)); altParentTree[last(altRoma)] = subtreeOf(prefix + kunreiRoma); }); }); }); Object.entries(SPECIAL_CASES).forEach(([string, kana]) => { subtreeOf(string)[""] = kana; }); function addTsu(tree) { return Object.entries(tree).reduce((tsuTree, [key, value]) => { if (!key) { tsuTree[key] = `\u3063${value}`; } else { tsuTree[key] = addTsu(value); } return tsuTree; }, {}); } [...Object.keys(CONSONANTS), "c", "y", "w", "j"].forEach((consonant) => { const subtree = kanaTree[consonant]; subtree[consonant] = addTsu(subtree); }); delete kanaTree.n.n; return Object.freeze(JSON.parse(JSON.stringify(kanaTree))); } var romajiToKanaMap = null; function getRomajiToKanaTree() { if (romajiToKanaMap == null) { romajiToKanaMap = createRomajiToKanaMap$1(); } return romajiToKanaMap; } var USE_OBSOLETE_KANA_MAP = createCustomMapping({ wi: "\u3090", we: "\u3091" }); function IME_MODE_MAP(map) { const mapCopy = JSON.parse(JSON.stringify(map)); mapCopy.n.n = { "": "\u3093" }; mapCopy.n[" "] = { "": "\u3093" }; return mapCopy; } function isCharUpperCase(char = "") { if (isEmpty(char)) return false; return isCharInRange(char, LATIN_UPPERCASE_START, LATIN_UPPERCASE_END); } function isCharLongDash(char = "") { if (isEmpty(char)) return false; return char.charCodeAt(0) === PROLONGED_SOUND_MARK; } function isCharSlashDot(char = "") { if (isEmpty(char)) return false; return char.charCodeAt(0) === KANA_SLASH_DOT; } function isCharHiragana(char = "") { if (isEmpty(char)) return false; if (isCharLongDash(char)) return true; return isCharInRange(char, HIRAGANA_START, HIRAGANA_END); } function hiraganaToKatakana(input = "") { const kata = []; input.split("").forEach((char) => { if (isCharLongDash(char) || isCharSlashDot(char)) { kata.push(char); } else if (isCharHiragana(char)) { const code = char.charCodeAt(0) + (KATAKANA_START - HIRAGANA_START); const kataChar = String.fromCharCode(code); kata.push(kataChar); } else { kata.push(char); } }); return kata.join(""); } var createRomajiToKanaMap = memoizeOne((IMEMode, useObsoleteKana, customKanaMapping) => { let map = getRomajiToKanaTree(); map = IMEMode ? IME_MODE_MAP(map) : map; map = useObsoleteKana ? USE_OBSOLETE_KANA_MAP(map) : map; if (customKanaMapping) { map = mergeCustomMapping(map, customKanaMapping); } return map; }, dequal); function toKana(input = "", options = {}, map) { let config; if (!map) { config = mergeWithDefaultOptions(options); map = createRomajiToKanaMap(config.IMEMode, config.useObsoleteKana, config.customKanaMapping); } else { config = options; } return splitIntoConvertedKana(input, config, map).map((kanaToken) => { const [start, end, kana] = kanaToken; if (kana === null) { return input.slice(start); } const enforceHiragana = config.IMEMode === TO_KANA_METHODS.HIRAGANA; const enforceKatakana = config.IMEMode === TO_KANA_METHODS.KATAKANA || [...input.slice(start, end)].every(isCharUpperCase); return enforceHiragana || !enforceKatakana ? kana : hiraganaToKatakana(kana); }).join(""); } function splitIntoConvertedKana(input = "", options = {}, map) { const { IMEMode, useObsoleteKana, customKanaMapping } = options; if (!map) { map = createRomajiToKanaMap(IMEMode, useObsoleteKana, customKanaMapping); } return applyMapping(input.toLowerCase(), map, !IMEMode); } var LISTENERS = []; function makeOnInput(options) { let prevInput; const mergedConfig = Object.assign({}, mergeWithDefaultOptions(options), { IMEMode: options.IMEMode || true }); const preConfiguredMap = createRomajiToKanaMap(mergedConfig.IMEMode, mergedConfig.useObsoleteKana, mergedConfig.customKanaMapping); const triggers = [ ...Object.keys(preConfiguredMap), ...Object.keys(preConfiguredMap).map((char) => char.toUpperCase()) ]; return function onInput2({ target }) { if (target.value !== prevInput && target.dataset.ignoreComposition !== "true") { convertInput(target, mergedConfig, preConfiguredMap, triggers); } }; } function convertInput(target, options, map, triggers, prevInput) { const [head, textToConvert, tail] = splitInput(target.value, target.selectionEnd, triggers); const convertedText = toKana(textToConvert, options, map); const changed = textToConvert !== convertedText; if (changed) { const newCursor = head.length + convertedText.length; const newValue = head + convertedText + tail; target.value = newValue; if (tail.length) { setTimeout(() => target.setSelectionRange(newCursor, newCursor), 1); } else { target.setSelectionRange(newCursor, newCursor); } } else { target.value; } } function onComposition({ type, target, data }) { const isMacOS = /Mac/.test(window.navigator && window.navigator.platform); if (isMacOS) { if (type === "compositionupdate" && isJapanese(data)) { target.dataset.ignoreComposition = "true"; } if (type === "compositionend") { target.dataset.ignoreComposition = "false"; } } } function trackListeners(id, inputHandler, compositionHandler) { LISTENERS = LISTENERS.concat({ id, inputHandler, compositionHandler }); } function untrackListeners({ id: targetId }) { LISTENERS = LISTENERS.filter(({ id }) => id !== targetId); } function findListeners(el) { return el && LISTENERS.find(({ id }) => id === el.getAttribute("data-wanakana-id")); } function splitInput(text = "", cursor = 0, triggers = []) { let head; let toConvert; let tail; if (cursor === 0 && triggers.includes(text[0])) { [head, toConvert, tail] = workFromStart(text, triggers); } else if (cursor > 0) { [head, toConvert, tail] = workBackwards(text, cursor); } else { [head, toConvert] = takeWhileAndSlice(text, (char) => !triggers.includes(char)); [toConvert, tail] = takeWhileAndSlice(toConvert, (char) => !isJapanese(char)); } return [head, toConvert, tail]; } function workFromStart(text, catalystChars) { return [ "", ...takeWhileAndSlice(text, (char) => catalystChars.includes(char) || !isJapanese(char, /[0-9]/)) ]; } function workBackwards(text = "", startIndex = 0) { const [toConvert, head] = takeWhileAndSlice([...text.slice(0, startIndex)].reverse(), (char) => !isJapanese(char)); return [ head.reverse().join(""), toConvert.split("").reverse().join(""), text.slice(startIndex) ]; } function takeWhileAndSlice(source = {}, predicate = (x) => !!x) { const result = []; const { length } = source; let i = 0; while (i < length && predicate(source[i], i)) { result.push(source[i]); i += 1; } return [result.join(""), source.slice(i)]; } var onInput = ({ target: { value, selectionStart, selectionEnd } }) => console.log("input:", { value, selectionStart, selectionEnd }); var onCompositionStart = () => console.log("compositionstart"); var onCompositionUpdate = ({ target: { value, selectionStart, selectionEnd }, data }) => console.log("compositionupdate", { data, value, selectionStart, selectionEnd }); var onCompositionEnd = () => console.log("compositionend"); var events = { input: onInput, compositionstart: onCompositionStart, compositionupdate: onCompositionUpdate, compositionend: onCompositionEnd }; var addDebugListeners = (input) => { Object.entries(events).forEach(([event, handler]) => input.addEventListener(event, handler)); }; var removeDebugListeners = (input) => { Object.entries(events).forEach(([event, handler]) => input.removeEventListener(event, handler)); }; var ELEMENTS = ["TEXTAREA", "INPUT"]; var idCounter = 0; var newId = () => { idCounter += 1; return `${Date.now()}${idCounter}`; }; function bind(element = {}, options = {}, debug = false) { if (!ELEMENTS.includes(element.nodeName)) { throw new Error(`Element provided to Wanakana bind() was not a valid input or textarea element. Received: (${JSON.stringify(element)})`); } if (element.hasAttribute("data-wanakana-id")) { return; } const onInput2 = makeOnInput(options); const id = newId(); const attributes = [ { name: "data-wanakana-id", value: id }, { name: "lang", value: "ja" }, { name: "autoCapitalize", value: "none" }, { name: "autoCorrect", value: "off" }, { name: "autoComplete", value: "off" }, { name: "spellCheck", value: "false" } ]; const previousAttributes = {}; attributes.forEach((attribute) => { previousAttributes[attribute.name] = element.getAttribute(attribute.name); element.setAttribute(attribute.name, attribute.value); }); element.dataset.previousAttributes = JSON.stringify(previousAttributes); element.addEventListener("input", onInput2); element.addEventListener("compositionupdate", onComposition); element.addEventListener("compositionend", onComposition); trackListeners(id, onInput2, onComposition); if (debug === true) { addDebugListeners(element); } } function unbind(element, debug = false) { const listeners = findListeners(element); if (listeners == null) { throw new Error(`Element provided to Wanakana unbind() had no listener registered. Received: ${JSON.stringify(element)}`); } const { inputHandler, compositionHandler } = listeners; const attributes = JSON.parse(element.dataset.previousAttributes); Object.keys(attributes).forEach((key) => { if (attributes[key]) { element.setAttribute(key, attributes[key]); } else { element.removeAttribute(key); } }); element.removeAttribute("data-previous-attributes"); element.removeAttribute("data-ignore-composition"); element.removeEventListener("input", inputHandler); element.removeEventListener("compositionstart", compositionHandler); element.removeEventListener("compositionupdate", compositionHandler); element.removeEventListener("compositionend", compositionHandler); untrackListeners(listeners); if (debug === true) { removeDebugListeners(element); } } function isCharRomaji(char = "") { if (isEmpty(char)) return false; return ROMAJI_RANGES.some(([start, end]) => isCharInRange(char, start, end)); } function isRomaji(input = "", allowed) { const augmented = typeOf(allowed) === "regexp"; return isEmpty(input) ? false : [...input].every((char) => { const isRoma = isCharRomaji(char); return !augmented ? isRoma : isRoma || allowed.test(char); }); } function isCharKatakana(char = "") { return isCharInRange(char, KATAKANA_START, KATAKANA_END); } function isCharKana(char = "") { if (isEmpty(char)) return false; return isCharHiragana(char) || isCharKatakana(char); } function isKana(input = "") { if (isEmpty(input)) return false; return [...input].every(isCharKana); } function isHiragana(input = "") { if (isEmpty(input)) return false; return [...input].every(isCharHiragana); } function isKatakana(input = "") { if (isEmpty(input)) return false; return [...input].every(isCharKatakana); } function isCharIterationMark(char = "") { if (isEmpty(char)) return false; return char.charCodeAt(0) === KANJI_ITERATION_MARK; } function isCharKanji(char = "") { return isCharInRange(char, KANJI_START, KANJI_END) || isCharIterationMark(char); } function isKanji(input = "") { if (isEmpty(input)) return false; return [...input].every(isCharKanji); } function isMixed(input = "", options = { passKanji: true }) { const chars = [...input]; let hasKanji = false; if (!options.passKanji) { hasKanji = chars.some(isKanji); } return (chars.some(isHiragana) || chars.some(isKatakana)) && chars.some(isRomaji) && !hasKanji; } var isCharInitialLongDash = (char, index) => isCharLongDash(char) && index < 1; var isCharInnerLongDash = (char, index) => isCharLongDash(char) && index > 0; var isKanaAsSymbol = (char) => ["\u30F6", "\u30F5"].includes(char); var LONG_VOWELS = { a: "\u3042", i: "\u3044", u: "\u3046", e: "\u3048", o: "\u3046" }; function katakanaToHiragana(input = "", toRomaji2, { isDestinationRomaji, convertLongVowelMark } = {}) { let previousKana = ""; return input.split("").reduce((hira, char, index) => { if (isCharSlashDot(char) || isCharInitialLongDash(char, index) || isKanaAsSymbol(char)) { return hira.concat(char); } if (convertLongVowelMark && previousKana && isCharInnerLongDash(char, index)) { const romaji = toRomaji2(previousKana).slice(-1); if (isCharKatakana(input[index - 1]) && romaji === "o" && isDestinationRomaji) { return hira.concat("\u304A"); } return hira.concat(LONG_VOWELS[romaji]); } if (!isCharLongDash(char) && isCharKatakana(char)) { const code = char.charCodeAt(0) + (HIRAGANA_START - KATAKANA_START); const hiraChar = String.fromCharCode(code); previousKana = hiraChar; return hira.concat(hiraChar); } previousKana = ""; return hira.concat(char); }, []).join(""); } var kanaToHepburnMap = null; var BASIC_ROMAJI = { \u3042: "a", \u3044: "i", \u3046: "u", \u3048: "e", \u304A: "o", \u304B: "ka", \u304D: "ki", \u304F: "ku", \u3051: "ke", \u3053: "ko", \u3055: "sa", \u3057: "shi", \u3059: "su", \u305B: "se", \u305D: "so", \u305F: "ta", \u3061: "chi", \u3064: "tsu", \u3066: "te", \u3068: "to", \u306A: "na", \u306B: "ni", \u306C: "nu", \u306D: "ne", \u306E: "no", \u306F: "ha", \u3072: "hi", \u3075: "fu", \u3078: "he", \u307B: "ho", \u307E: "ma", \u307F: "mi", \u3080: "mu", \u3081: "me", \u3082: "mo", \u3089: "ra", \u308A: "ri", \u308B: "ru", \u308C: "re", \u308D: "ro", \u3084: "ya", \u3086: "yu", \u3088: "yo", \u308F: "wa", \u3090: "wi", \u3091: "we", \u3092: "wo", \u3093: "n", \u304C: "ga", \u304E: "gi", \u3050: "gu", \u3052: "ge", \u3054: "go", \u3056: "za", \u3058: "ji", \u305A: "zu", \u305C: "ze", \u305E: "zo", \u3060: "da", \u3062: "ji", \u3065: "zu", \u3067: "de", \u3069: "do", \u3070: "ba", \u3073: "bi", \u3076: "bu", \u3079: "be", \u307C: "bo", \u3071: "pa", \u3074: "pi", \u3077: "pu", \u307A: "pe", \u307D: "po", \u3094\u3041: "va", \u3094\u3043: "vi", \u3094: "vu", \u3094\u3047: "ve", \u3094\u3049: "vo" }; var SPECIAL_SYMBOLS = { "\u3002": ".", "\u3001": ",", "\uFF1A": ":", "\u30FB": "/", "\uFF01": "!", "\uFF1F": "?", "\u301C": "~", "\u30FC": "-", "\u300C": "\u2018", "\u300D": "\u2019", "\u300E": "\u201C", "\u300F": "\u201D", "\uFF3B": "[", "\uFF3D": "]", "\uFF08": "(", "\uFF09": ")", "\uFF5B": "{", "\uFF5D": "}", "\u3000": " " }; var AMBIGUOUS_VOWELS = ["\u3042", "\u3044", "\u3046", "\u3048", "\u304A", "\u3084", "\u3086", "\u3088"]; var SMALL_Y = { \u3083: "ya", \u3085: "yu", \u3087: "yo" }; var SMALL_Y_EXTRA = { \u3043: "yi", \u3047: "ye" }; var SMALL_AIUEO = { \u3041: "a", \u3043: "i", \u3045: "u", \u3047: "e", \u3049: "o" }; var YOON_KANA = [ "\u304D", "\u306B", "\u3072", "\u307F", "\u308A", "\u304E", "\u3073", "\u3074", "\u3094", "\u304F", "\u3075" ]; var YOON_EXCEPTIONS = { \u3057: "sh", \u3061: "ch", \u3058: "j", \u3062: "j" }; var SMALL_KANA = { \u3063: "", \u3083: "ya", \u3085: "yu", \u3087: "yo", \u3041: "a", \u3043: "i", \u3045: "u", \u3047: "e", \u3049: "o" }; var SOKUON_WHITELIST = { b: "b", c: "t", d: "d", f: "f", g: "g", h: "h", j: "j", k: "k", m: "m", p: "p", q: "q", r: "r", s: "s", t: "t", v: "v", w: "w", x: "x", z: "z" }; function getKanaToHepburnTree() { if (kanaToHepburnMap == null) { kanaToHepburnMap = createKanaToHepburnMap(); } return kanaToHepburnMap; } function getKanaToRomajiTree(romanization) { switch (romanization) { case ROMANIZATIONS.HEPBURN: return getKanaToHepburnTree(); default: return {}; } } function createKanaToHepburnMap() { const romajiTree = transform(BASIC_ROMAJI); const subtreeOf = (string) => getSubTreeOf(romajiTree, string); const setTrans = (string, transliteration) => { subtreeOf(string)[""] = transliteration; }; Object.entries(SPECIAL_SYMBOLS).forEach(([jsymbol, symbol]) => { subtreeOf(jsymbol)[""] = symbol; }); [...Object.entries(SMALL_Y), ...Object.entries(SMALL_AIUEO)].forEach(([roma, kana]) => { setTrans(roma, kana); }); YOON_KANA.forEach((kana) => { const firstRomajiChar = subtreeOf(kana)[""][0]; Object.entries(SMALL_Y).forEach(([yKana, yRoma]) => { setTrans(kana + yKana, firstRomajiChar + yRoma); }); Object.entries(SMALL_Y_EXTRA).forEach(([yKana, yRoma]) => { setTrans(kana + yKana, firstRomajiChar + yRoma); }); }); Object.entries(YOON_EXCEPTIONS).forEach(([kana, roma]) => { Object.entries(SMALL_Y).forEach(([yKana, yRoma]) => { setTrans(kana + yKana, roma + yRoma[1]); }); setTrans(`${kana}\u3043`, `${roma}yi`); setTrans(`${kana}\u3047`, `${roma}e`); }); romajiTree["\u3063"] = resolveTsu(romajiTree); Object.entries(SMALL_KANA).forEach(([kana, roma]) => { setTrans(kana, roma); }); AMBIGUOUS_VOWELS.forEach((kana) => { setTrans(`\u3093${kana}`, `n'${subtreeOf(kana)[""]}`); }); return Object.freeze(JSON.parse(JSON.stringify(romajiTree))); } function resolveTsu(tree) { return Object.entries(tree).reduce((tsuTree, [key, value]) => { if (!key) { const consonant = value.charAt(0); tsuTree[key] = Object.keys(SOKUON_WHITELIST).includes(consonant) ? SOKUON_WHITELIST[consonant] + value : value; } else { tsuTree[key] = resolveTsu(value); } return tsuTree; }, {}); } var createKanaToRomajiMap = memoizeOne((romanization, customRomajiMapping) => { let map = getKanaToRomajiTree(romanization); if (customRomajiMapping) { map = mergeCustomMapping(map, customRomajiMapping); } return map; }, dequal); function toRomaji(input = "", options = {}, map) { const config = mergeWithDefaultOptions(options); if (!map) { map = createKanaToRomajiMap(config.romanization, config.customRomajiMapping); } return splitIntoRomaji(input, config, map).map((romajiToken) => { const [start, end, romaji] = romajiToken; const makeUpperCase = config.upcaseKatakana && isKatakana(input.slice(start, end)); return makeUpperCase ? romaji.toUpperCase() : romaji; }).join(""); } function splitIntoRomaji(input, options, map) { if (!map) { map = createKanaToRomajiMap(options.romanization, options.customRomajiMapping); } const config = Object.assign({}, { isDestinationRomaji: true }, options); return applyMapping(katakanaToHiragana(input, toRomaji, config), map, !options.IMEMode); } function isCharEnglishPunctuation(char = "") { if (isEmpty(char)) return false; return EN_PUNCTUATION_RANGES.some(([start, end]) => isCharInRange(char, start, end)); } function toHiragana(input = "", options = {}) { const config = mergeWithDefaultOptions(options); if (config.passRomaji) { return katakanaToHiragana(input, toRomaji, config); } if (isMixed(input, { passKanji: true })) { const convertedKatakana = katakanaToHiragana(input, toRomaji, config); return toKana(convertedKatakana.toLowerCase(), config); } if (isRomaji(input) || isCharEnglishPunctuation(input)) { return toKana(input.toLowerCase(), config); } return katakanaToHiragana(input, toRomaji, config); } function toKatakana(input = "", options = {}) { const mergedOptions = mergeWithDefaultOptions(options); if (mergedOptions.passRomaji) { return hiraganaToKatakana(input); } if (isMixed(input) || isRomaji(input) || isCharEnglishPunctuation(input)) { const hiragana = toKana(input.toLowerCase(), mergedOptions); return hiraganaToKatakana(hiragana); } return hiraganaToKatakana(input); } function isCharJapanesePunctuation(char = "") { if (isEmpty(char) || isCharIterationMark(char)) return false; return JA_PUNCTUATION_RANGES.some(([start, end]) => isCharInRange(char, start, end)); } var isCharEnSpace = (x) => x === " "; var isCharJaSpace = (x) => x === "\u3000"; var isCharJaNum = (x) => /[0-9]/.test(x); var isCharEnNum = (x) => /[0-9]/.test(x); var TOKEN_TYPES = { EN: "en", JA: "ja", EN_NUM: "englishNumeral", JA_NUM: "japaneseNumeral", EN_PUNC: "englishPunctuation", JA_PUNC: "japanesePunctuation", KANJI: "kanji", HIRAGANA: "hiragana", KATAKANA: "katakana", SPACE: "space", OTHER: "other" }; function getType(input, compact = false) { const { EN, JA, EN_NUM, JA_NUM, EN_PUNC, JA_PUNC, KANJI, HIRAGANA, KATAKANA, SPACE, OTHER } = TOKEN_TYPES; if (compact) { switch (true) { case isCharJaNum(input): return OTHER; case isCharEnNum(input): return OTHER; case isCharEnSpace(input): return EN; case isCharEnglishPunctuation(input): return OTHER; case isCharJaSpace(input): return JA; case isCharJapanesePunctuation(input): return OTHER; case isCharJapanese(input): return JA; case isCharRomaji(input): return EN; default: return OTHER; } } else { switch (true) { case isCharJaSpace(input): return SPACE; case isCharEnSpace(input): return SPACE; case isCharJaNum(input): return JA_NUM; case isCharEnNum(input): return EN_NUM; case isCharEnglishPunctuation(input): return EN_PUNC; case isCharJapanesePunctuation(input): return JA_PUNC; case isCharKanji(input): return KANJI; case isCharHiragana(input): return HIRAGANA; case isCharKatakana(input): return KATAKANA; case isCharJapanese(input): return JA; case isCharRomaji(input): return EN; default: return OTHER; } } } function tokenize(input, { compact = false, detailed = false } = {}) { if (input == null || isEmpty(input)) { return []; } const chars = [...input]; let initial = chars.shift(); let prevType = getType(initial, compact); initial = detailed ? { type: prevType, value: initial } : initial; const result = chars.reduce((tokens, char) => { const currType = getType(char, compact); const sameType = currType === prevType; prevType = currType; let newValue = char; if (sameType) { newValue = (detailed ? tokens.pop().value : tokens.pop()) + newValue; } return detailed ? tokens.concat({ type: currType, value: newValue }) : tokens.concat(newValue); }, [initial]); return result; } var isLeadingWithoutInitialKana = (input, leading) => leading && !isKana(input[0]); var isTrailingWithoutFinalKana = (input, leading) => !leading && !isKana(input[input.length - 1]); var isInvalidMatcher = (input, matchKanji) => matchKanji && ![...matchKanji].some(isKanji) || !matchKanji && isKana(input); function stripOkurigana(input = "", { leading = false, matchKanji = "" } = {}) { if (!isJapanese(input) || isLeadingWithoutInitialKana(input, leading) || isTrailingWithoutFinalKana(input, leading) || isInvalidMatcher(input, matchKanji)) { return input; } const chars = matchKanji || input; const okuriganaRegex = new RegExp(leading ? `^${tokenize(chars).shift()}` : `${tokenize(chars).pop()}$`); return input.replace(okuriganaRegex, ""); } export { ROMANIZATIONS, TO_KANA_METHODS, VERSION, bind, isHiragana, isJapanese, isKana, isKanji, isKatakana, isMixed, isRomaji, stripOkurigana, toHiragana, toKana, toKatakana, toRomaji, tokenize, unbind }; //# sourceMappingURL=wanakana.js.map