From 62b95a656f5e55395893982822b0388a425f5a29 Mon Sep 17 00:00:00 2001
From: odehjoseph
Search your installed dictionaries by entering a Japanese expression into the field below.
+Search your installed dictionaries by entering a Japanese expression into the field below.
-
- ++
-
Copyright (C) 2016-2017 Alex Yatskov diff --git a/ext/bg/search.html b/ext/bg/search.html index 121b477c..668b2436 100644 --- a/ext/bg/search.html +++ b/ext/bg/search.html @@ -9,7 +9,7 @@ -+Yomichan Search
diff --git a/ext/bg/settings.html b/ext/bg/settings.html index 02780f38..4db0a9b0 100644 --- a/ext/bg/settings.html +++ b/ext/bg/settings.html @@ -9,7 +9,7 @@ -+Profiles
-- cgit v1.2.3 From 9b929ffcd4bf34b784b94137f636a8a483b1f18e Mon Sep 17 00:00:00 2001 From: toasted-nutbreadDate: Sat, 28 Sep 2019 13:30:41 -0400 Subject: Add wrapping for usage conditions on small screens --- ext/bg/css/settings.css | 30 ++++++++++++++++++++++++++++++ ext/bg/settings.html | 3 ++- 2 files changed, 32 insertions(+), 1 deletion(-) (limited to 'ext/bg') diff --git a/ext/bg/css/settings.css b/ext/bg/css/settings.css index 150209e3..12bbe8a8 100644 --- a/ext/bg/css/settings.css +++ b/ext/bg/css/settings.css @@ -48,6 +48,20 @@ border-color: #f00000; } +.condition { + display: flex; + -flex-wrap: wrap; +} +.condition-input { + flex: 1 1 auto; +} +.condition-line-break { + flex: 1 0 100%; + display: none; +} +.condition>.input-group-btn { + width: auto; +} .condition>.condition-prefix:after { content: "IF"; } @@ -55,6 +69,9 @@ content: "AND"; } +.input-group .condition-prefix { + flex: 0 0 auto; +} .input-group .condition-prefix, .input-group .condition-group-separator-label { width: 60px; @@ -122,3 +139,16 @@ margin-top: 15px; } } + +@media screen and (max-width: 600px) { + .condition { + flex-wrap: wrap; + } + .condition-input { + order: 2; + } + .condition-line-break { + display: block; + order: 1; + } +} diff --git a/ext/bg/settings.html b/ext/bg/settings.html index 4db0a9b0..1406826b 100644 --- a/ext/bg/settings.html +++ b/ext/bg/settings.html @@ -105,7 +105,8 @@ - + + -- cgit v1.2.3 From b42fa9581fc6c6ca27a0cf3759f6f029b18f1ab2 Mon Sep 17 00:00:00 2001 From: toasted-nutbread-- cgit v1.2.3 From 8b7558a757447b931ee0dd1b5d724673e98bc13d Mon Sep 17 00:00:00 2001 From: toasted-nutbreadDate: Sat, 28 Sep 2019 13:32:51 -0400 Subject: Fix some incorrect labels --- ext/bg/settings.html | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'ext/bg') diff --git a/ext/bg/settings.html b/ext/bg/settings.html index 1406826b..5a368e91 100644 --- a/ext/bg/settings.html +++ b/ext/bg/settings.html @@ -188,14 +188,14 @@ - +- +@@ -402,7 +403,7 @@- +Date: Sun, 29 Sep 2019 15:26:46 -0400 Subject: Use toIterable for cross-window origin objects --- ext/bg/js/conditions-ui.js | 4 ++-- ext/bg/js/settings.js | 4 ++-- ext/mixed/js/extension.js | 15 +++++++++++++-- 3 files changed, 17 insertions(+), 6 deletions(-) (limited to 'ext/bg') diff --git a/ext/bg/js/conditions-ui.js b/ext/bg/js/conditions-ui.js index a6f54a1c..43c6dc08 100644 --- a/ext/bg/js/conditions-ui.js +++ b/ext/bg/js/conditions-ui.js @@ -36,7 +36,7 @@ ConditionsUI.Container = class Container { this.container.empty(); - for (const conditionGroup of conditionGroups) { + for (const conditionGroup of toIterable(conditionGroups)) { this.children.push(new ConditionsUI.ConditionGroup(this, conditionGroup)); } @@ -122,7 +122,7 @@ ConditionsUI.ConditionGroup = class ConditionGroup { this.separator = ConditionsUI.instantiateTemplate('#condition-group-separator-template').appendTo(parent.container); this.addButton = this.options.find('.condition-add'); - for (const condition of conditionGroup.conditions) { + for (const condition of toIterable(conditionGroup.conditions)) { this.children.push(new ConditionsUI.Condition(this, condition)); } diff --git a/ext/bg/js/settings.js b/ext/bg/js/settings.js index a0fe7c70..a100550c 100644 --- a/ext/bg/js/settings.js +++ b/ext/bg/js/settings.js @@ -422,7 +422,7 @@ async function onDictionaryPurge(e) { dictionarySpinnerShow(true); await utilDatabasePurge(); - for (const options of await getOptionsArray()) { + for (const options of toIterable(await getOptionsArray())) { options.dictionaries = utilBackgroundIsolate({}); options.general.mainDictionary = ''; } @@ -466,7 +466,7 @@ async function onDictionaryImport(e) { const exceptions = []; const summary = await utilDatabaseImport(e.target.files[0], updateProgress, exceptions); - for (const options of await getOptionsArray()) { + for (const options of toIterable(await getOptionsArray())) { options.dictionaries[summary.title] = utilBackgroundIsolate({ enabled: true, priority: 0, diff --git a/ext/mixed/js/extension.js b/ext/mixed/js/extension.js index d7085e5b..5c803132 100644 --- a/ext/mixed/js/extension.js +++ b/ext/mixed/js/extension.js @@ -17,13 +17,24 @@ */ +// toIterable is required on Edge for cross-window origin objects. function toIterable(value) { if (typeof Symbol !== 'undefined' && typeof value[Symbol.iterator] !== 'undefined') { return value; } - const array = JSON.parse(JSON.stringify(value)); - return Array.isArray(array) ? array : []; + if (value !== null && typeof value === 'object') { + const length = value.length; + if (typeof length === 'number' && Number.isFinite(length)) { + const array = []; + for (let i = 0; i < length; ++i) { + array.push(value[i]); + } + return array; + } + } + + throw 'Could not convert to iterable'; } function extensionHasChrome() { -- cgit v1.2.3 From 44119eea2c8ad4c8eed38070ef1a3ce27fa9359e Mon Sep 17 00:00:00 2001 From: toasted-nutbread Date: Mon, 30 Sep 2019 22:09:16 -0400 Subject: Fix deinflections not being handled correctly --- ext/bg/js/translator.js | 58 ++++++++++++++++++++++++++++++++++--------------- 1 file changed, 40 insertions(+), 18 deletions(-) (limited to 'ext/bg') diff --git a/ext/bg/js/translator.js b/ext/bg/js/translator.js index 4eb4b03a..65d746ea 100644 --- a/ext/bg/js/translator.js +++ b/ext/bg/js/translator.js @@ -218,22 +218,55 @@ class Translator { return []; } - const definitions = await this.database.findTermsBulk(deinflections.map(e => e.term), titles); + const uniqueDeinflectionTerms = []; + const uniqueDeinflectionArrays = []; + const uniqueDeinflectionsMap = {}; + for (const deinflection of deinflections) { + const term = deinflection.term; + let deinflectionArray; + if (uniqueDeinflectionsMap.hasOwnProperty(term)) { + deinflectionArray = uniqueDeinflectionsMap[term]; + } else { + deinflectionArray = []; + uniqueDeinflectionTerms.push(term); + uniqueDeinflectionArrays.push(deinflectionArray); + uniqueDeinflectionsMap[term] = deinflectionArray; + } + deinflectionArray.push(deinflection); + } + + const definitions = await this.database.findTermsBulk(uniqueDeinflectionTerms, titles); - for (const d of definitions) { - deinflections[d.index].definitions.push(d); + for (const definition of definitions) { + for (const deinflection of uniqueDeinflectionArrays[definition.index]) { + if (Translator.definitionContainsAnyRule(definition, deinflection.rules)) { + deinflection.definitions.push(definition); + } + } } return deinflections.filter(e => e.definitions.length > 0); } + static definitionContainsAnyRule(definition, rules) { + if (rules.length === 0) { + return true; + } + const definitionRules = definition.rules; + for (const rule of rules) { + if (definitionRules.includes(rule)) { + return true; + } + } + return false; + } + getDeinflections(text) { const deinflections = []; - const deinflectionsKeys = {}; for (let i = text.length; i > 0; --i) { const textSlice = text.slice(0, i); - Translator.addUniqueDeinflections(this.deinflector.deinflect(textSlice), deinflections, deinflectionsKeys); + deinflections.push(...this.deinflector.deinflect(textSlice)); } return deinflections; @@ -241,30 +274,19 @@ class Translator { getDeinflections2(text, text2) { const deinflections = []; - const deinflectionsKeys = {}; for (let i = text.length; i > 0; --i) { const textSlice = text.slice(0, i); const text2Slice = text2.slice(0, i); - Translator.addUniqueDeinflections(this.deinflector.deinflect(textSlice), deinflections, deinflectionsKeys); + deinflections.push(...this.deinflector.deinflect(textSlice)); if (textSlice !== text2Slice) { - Translator.addUniqueDeinflections(this.deinflector.deinflect(text2Slice), deinflections, deinflectionsKeys); + deinflections.push(...this.deinflector.deinflect(text2Slice)); } } return deinflections; } - static addUniqueDeinflections(newValues, deinflections, deinflectionsKeys) { - for (const value of newValues) { - const key = value.term; - if (!deinflectionsKeys.hasOwnProperty(key)) { - deinflections.push(value); - deinflectionsKeys[key] = true; - } - } - } - async findKanji(text, dictionaries) { let definitions = []; const processed = {}; -- cgit v1.2.3 From 10458c63e71303f27888c3dfca7b3f59d5a0702b Mon Sep 17 00:00:00 2001 From: toasted-nutbread Date: Wed, 2 Oct 2019 20:46:48 -0400 Subject: Use static object for backend message handlers --- ext/bg/js/backend.js | 84 ++++++++++++++-------------------------------------- 1 file changed, 22 insertions(+), 62 deletions(-) (limited to 'ext/bg') diff --git a/ext/bg/js/backend.js b/ext/bg/js/backend.js index 4068b760..3c5ad885 100644 --- a/ext/bg/js/backend.js +++ b/ext/bg/js/backend.js @@ -69,68 +69,13 @@ class Backend { } onMessage({action, params}, sender, callback) { - const forward = (promise, callback) => { - return promise.then(result => { - callback({result}); - }).catch(error => { - callback({error: error.toString ? error.toString() : error}); - }); - }; - - const handlers = { - optionsGet: ({optionsContext, callback}) => { - forward(apiOptionsGet(optionsContext), callback); - }, - - kanjiFind: ({text, optionsContext, callback}) => { - forward(apiKanjiFind(text, optionsContext), callback); - }, - - termsFind: ({text, optionsContext, callback}) => { - forward(apiTermsFind(text, optionsContext), callback); - }, - - definitionAdd: ({definition, mode, context, optionsContext, callback}) => { - forward(apiDefinitionAdd(definition, mode, context, optionsContext), callback); - }, - - definitionsAddable: ({definitions, modes, optionsContext, callback}) => { - forward(apiDefinitionsAddable(definitions, modes, optionsContext), callback); - }, - - noteView: ({noteId}) => { - forward(apiNoteView(noteId), callback); - }, - - templateRender: ({template, data, dynamic, callback}) => { - forward(apiTemplateRender(template, data, dynamic), callback); - }, - - commandExec: ({command, callback}) => { - forward(apiCommandExec(command), callback); - }, - - audioGetUrl: ({definition, source, callback}) => { - forward(apiAudioGetUrl(definition, source), callback); - }, - - screenshotGet: ({options}) => { - forward(apiScreenshotGet(options, sender), callback); - }, - - forward: ({action, params}) => { - forward(apiForward(action, params, sender), callback); - }, - - frameInformationGet: () => { - forward(apiFrameInformationGet(sender), callback); - } - }; - - const handler = handlers[action]; - if (handler) { - params.callback = callback; - handler(params); + const handlers = Backend.messageHandlers; + if (handlers.hasOwnProperty(action)) { + const handler = handlers[action]; + const promise = handler(params, sender); + promise + .then(result => callback({result})) + .catch(error => callback({error: typeof error.toString === 'function' ? error.toString() : error})); } return true; @@ -227,5 +172,20 @@ class Backend { } } +Backend.messageHandlers = { + optionsGet: ({optionsContext}) => apiOptionsGet(optionsContext), + kanjiFind: ({text, optionsContext}) => apiKanjiFind(text, optionsContext), + termsFind: ({text, optionsContext}) => apiTermsFind(text, optionsContext), + definitionAdd: ({definition, mode, context, optionsContext}) => apiDefinitionAdd(definition, mode, context, optionsContext), + definitionsAddable: ({definitions, modes, optionsContext}) => apiDefinitionsAddable(definitions, modes, optionsContext), + noteView: ({noteId}) => apiNoteView(noteId), + templateRender: ({template, data, dynamic}) => apiTemplateRender(template, data, dynamic), + commandExec: ({command}) => apiCommandExec(command), + audioGetUrl: ({definition, source}) => apiAudioGetUrl(definition, source), + screenshotGet: ({options}, sender) => apiScreenshotGet(options, sender), + forward: ({action, params}, sender) => apiForward(action, params, sender), + frameInformationGet: (params, sender) => apiFrameInformationGet(sender), +}; + window.yomichan_backend = new Backend(); window.yomichan_backend.prepare(); -- cgit v1.2.3 From 0d6177398d0a738430a555ce307ba0a61c15bf9a Mon Sep 17 00:00:00 2001 From: toasted-nutbread Date: Wed, 2 Oct 2019 20:47:03 -0400 Subject: Use static object for api command handlers --- ext/bg/js/api.js | 52 ++++++++++++++++++++++++++-------------------------- 1 file changed, 26 insertions(+), 26 deletions(-) (limited to 'ext/bg') diff --git a/ext/bg/js/api.js b/ext/bg/js/api.js index 474fe604..222e7ffe 100644 --- a/ext/bg/js/api.js +++ b/ext/bg/js/api.js @@ -126,35 +126,35 @@ async function apiTemplateRender(template, data, dynamic) { } async function apiCommandExec(command) { - const handlers = { - search: () => { - chrome.tabs.create({url: chrome.extension.getURL('/bg/search.html')}); - }, - - help: () => { - chrome.tabs.create({url: 'https://foosoft.net/projects/yomichan/'}); - }, - - options: () => { - chrome.runtime.openOptionsPage(); - }, - - toggle: async () => { - const optionsContext = { - depth: 0, - url: window.location.href - }; - const options = await apiOptionsGet(optionsContext); - options.general.enable = !options.general.enable; - await apiOptionsSave('popup'); - } - }; - - const handler = handlers[command]; - if (handler) { + const handlers = apiCommandExec.handlers; + if (handlers.hasOwnProperty(command)) { + const handler = handlers[command]; handler(); } } +apiCommandExec.handlers = { + search: () => { + chrome.tabs.create({url: chrome.extension.getURL('/bg/search.html')}); + }, + + help: () => { + chrome.tabs.create({url: 'https://foosoft.net/projects/yomichan/'}); + }, + + options: () => { + chrome.runtime.openOptionsPage(); + }, + + toggle: async () => { + const optionsContext = { + depth: 0, + url: window.location.href + }; + const options = await apiOptionsGet(optionsContext); + options.general.enable = !options.general.enable; + await apiOptionsSave('popup'); + } +}; async function apiAudioGetUrl(definition, source) { return audioBuildUrl(definition, source); -- cgit v1.2.3 From 457caf2221dad6fb67e0e3b8500984ef5a65e826 Mon Sep 17 00:00:00 2001 From: toasted-nutbread Date: Fri, 4 Oct 2019 22:11:45 -0400 Subject: Add support for progressive/perfect inflections --- ext/bg/lang/deinflect.json | 205 +++++++++++++++++++++++++++++++++++---------- 1 file changed, 161 insertions(+), 44 deletions(-) (limited to 'ext/bg') diff --git a/ext/bg/lang/deinflect.json b/ext/bg/lang/deinflect.json index 7a68ea71..c7977c88 100644 --- a/ext/bg/lang/deinflect.json +++ b/ext/bg/lang/deinflect.json @@ -1185,7 +1185,9 @@ { "kanaIn": "て", "kanaOut": "る", - "rulesIn": [], + "rulesIn": [ + "iru" + ], "rulesOut": [ "v1", "vk" @@ -1194,7 +1196,9 @@ { "kanaIn": "いて", "kanaOut": "く", - "rulesIn": [], + "rulesIn": [ + "iru" + ], "rulesOut": [ "v5" ] @@ -1202,7 +1206,9 @@ { "kanaIn": "いで", "kanaOut": "ぐ", - "rulesIn": [], + "rulesIn": [ + "iru" + ], "rulesOut": [ "v5" ] @@ -1210,7 +1216,9 @@ { "kanaIn": "きて", "kanaOut": "くる", - "rulesIn": [], + "rulesIn": [ + "iru" + ], "rulesOut": [ "vk" ] @@ -1218,7 +1226,9 @@ { "kanaIn": "くて", "kanaOut": "い", - "rulesIn": [], + "rulesIn": [ + "iru" + ], "rulesOut": [ "adj-i" ] @@ -1226,7 +1236,9 @@ { "kanaIn": "して", "kanaOut": "す", - "rulesIn": [], + "rulesIn": [ + "iru" + ], "rulesOut": [ "v5" ] @@ -1234,7 +1246,9 @@ { "kanaIn": "して", "kanaOut": "する", - "rulesIn": [], + "rulesIn": [ + "iru" + ], "rulesOut": [ "vs" ] @@ -1242,7 +1256,9 @@ { "kanaIn": "って", "kanaOut": "う", - "rulesIn": [], + "rulesIn": [ + "iru" + ], "rulesOut": [ "v5" ] @@ -1250,7 +1266,9 @@ { "kanaIn": "って", "kanaOut": "つ", - "rulesIn": [], + "rulesIn": [ + "iru" + ], "rulesOut": [ "v5" ] @@ -1258,7 +1276,9 @@ { "kanaIn": "って", "kanaOut": "る", - "rulesIn": [], + "rulesIn": [ + "iru" + ], "rulesOut": [ "v5" ] @@ -1266,7 +1286,9 @@ { "kanaIn": "んで", "kanaOut": "ぬ", - "rulesIn": [], + "rulesIn": [ + "iru" + ], "rulesOut": [ "v5" ] @@ -1274,7 +1296,9 @@ { "kanaIn": "んで", "kanaOut": "ぶ", - "rulesIn": [], + "rulesIn": [ + "iru" + ], "rulesOut": [ "v5" ] @@ -1282,7 +1306,9 @@ { "kanaIn": "んで", "kanaOut": "む", - "rulesIn": [], + "rulesIn": [ + "iru" + ], "rulesOut": [ "v5" ] @@ -1290,7 +1316,9 @@ { "kanaIn": "のたもうて", "kanaOut": "のたまう", - "rulesIn": [], + "rulesIn": [ + "iru" + ], "rulesOut": [ "v5" ] @@ -1298,7 +1326,9 @@ { "kanaIn": "いって", "kanaOut": "いく", - "rulesIn": [], + "rulesIn": [ + "iru" + ], "rulesOut": [ "v5" ] @@ -1306,7 +1336,9 @@ { "kanaIn": "おうて", "kanaOut": "おう", - "rulesIn": [], + "rulesIn": [ + "iru" + ], "rulesOut": [ "v5" ] @@ -1314,7 +1346,9 @@ { "kanaIn": "こうて", "kanaOut": "こう", - "rulesIn": [], + "rulesIn": [ + "iru" + ], "rulesOut": [ "v5" ] @@ -1322,7 +1356,9 @@ { "kanaIn": "そうて", "kanaOut": "そう", - "rulesIn": [], + "rulesIn": [ + "iru" + ], "rulesOut": [ "v5" ] @@ -1330,7 +1366,9 @@ { "kanaIn": "とうて", "kanaOut": "とう", - "rulesIn": [], + "rulesIn": [ + "iru" + ], "rulesOut": [ "v5" ] @@ -1338,7 +1376,9 @@ { "kanaIn": "行って", "kanaOut": "行く", - "rulesIn": [], + "rulesIn": [ + "iru" + ], "rulesOut": [ "v5" ] @@ -1346,7 +1386,9 @@ { "kanaIn": "逝って", "kanaOut": "逝く", - "rulesIn": [], + "rulesIn": [ + "iru" + ], "rulesOut": [ "v5" ] @@ -1354,7 +1396,9 @@ { "kanaIn": "往って", "kanaOut": "往く", - "rulesIn": [], + "rulesIn": [ + "iru" + ], "rulesOut": [ "v5" ] @@ -1362,7 +1406,9 @@ { "kanaIn": "請うて", "kanaOut": "請う", - "rulesIn": [], + "rulesIn": [ + "iru" + ], "rulesOut": [ "v5" ] @@ -1370,7 +1416,9 @@ { "kanaIn": "乞うて", "kanaOut": "乞う", - "rulesIn": [], + "rulesIn": [ + "iru" + ], "rulesOut": [ "v5" ] @@ -1378,7 +1426,9 @@ { "kanaIn": "恋うて", "kanaOut": "恋う", - "rulesIn": [], + "rulesIn": [ + "iru" + ], "rulesOut": [ "v5" ] @@ -1386,7 +1436,9 @@ { "kanaIn": "問うて", "kanaOut": "問う", - "rulesIn": [], + "rulesIn": [ + "iru" + ], "rulesOut": [ "v5" ] @@ -1394,7 +1446,9 @@ { "kanaIn": "負うて", "kanaOut": "負う", - "rulesIn": [], + "rulesIn": [ + "iru" + ], "rulesOut": [ "v5" ] @@ -1402,7 +1456,9 @@ { "kanaIn": "沿うて", "kanaOut": "沿う", - "rulesIn": [], + "rulesIn": [ + "iru" + ], "rulesOut": [ "v5" ] @@ -1410,7 +1466,9 @@ { "kanaIn": "添うて", "kanaOut": "添う", - "rulesIn": [], + "rulesIn": [ + "iru" + ], "rulesOut": [ "v5" ] @@ -1418,7 +1476,9 @@ { "kanaIn": "副うて", "kanaOut": "副う", - "rulesIn": [], + "rulesIn": [ + "iru" + ], "rulesOut": [ "v5" ] @@ -1426,10 +1486,22 @@ { "kanaIn": "厭うて", "kanaOut": "厭う", - "rulesIn": [], + "rulesIn": [ + "iru" + ], "rulesOut": [ "v5" ] + }, + { + "kanaIn": "で", + "kanaOut": "", + "rulesIn": [ + "iru" + ], + "rulesOut": [ + "neg-de" + ] } ], "-zu": [ @@ -2161,7 +2233,8 @@ "kanaIn": "ない", "kanaOut": "る", "rulesIn": [ - "adj-i" + "adj-i", + "neg-de" ], "rulesOut": [ "v1", @@ -2172,7 +2245,8 @@ "kanaIn": "かない", "kanaOut": "く", "rulesIn": [ - "adj-i" + "adj-i", + "neg-de" ], "rulesOut": [ "v5" @@ -2182,7 +2256,8 @@ "kanaIn": "がない", "kanaOut": "ぐ", "rulesIn": [ - "adj-i" + "adj-i", + "neg-de" ], "rulesOut": [ "v5" @@ -2192,7 +2267,8 @@ "kanaIn": "くない", "kanaOut": "い", "rulesIn": [ - "adj-i" + "adj-i", + "neg-de" ], "rulesOut": [ "adj-i" @@ -2202,7 +2278,8 @@ "kanaIn": "こない", "kanaOut": "くる", "rulesIn": [ - "adj-i" + "adj-i", + "neg-de" ], "rulesOut": [ "vk" @@ -2212,7 +2289,8 @@ "kanaIn": "さない", "kanaOut": "す", "rulesIn": [ - "adj-i" + "adj-i", + "neg-de" ], "rulesOut": [ "v5" @@ -2222,7 +2300,8 @@ "kanaIn": "しない", "kanaOut": "する", "rulesIn": [ - "adj-i" + "adj-i", + "neg-de" ], "rulesOut": [ "vs" @@ -2232,7 +2311,8 @@ "kanaIn": "たない", "kanaOut": "つ", "rulesIn": [ - "adj-i" + "adj-i", + "neg-de" ], "rulesOut": [ "v5" @@ -2242,7 +2322,8 @@ "kanaIn": "なない", "kanaOut": "ぬ", "rulesIn": [ - "adj-i" + "adj-i", + "neg-de" ], "rulesOut": [ "v5" @@ -2252,7 +2333,8 @@ "kanaIn": "ばない", "kanaOut": "ぶ", "rulesIn": [ - "adj-i" + "adj-i", + "neg-de" ], "rulesOut": [ "v5" @@ -2262,7 +2344,8 @@ "kanaIn": "まない", "kanaOut": "む", "rulesIn": [ - "adj-i" + "adj-i", + "neg-de" ], "rulesOut": [ "v5" @@ -2272,7 +2355,8 @@ "kanaIn": "らない", "kanaOut": "る", "rulesIn": [ - "adj-i" + "adj-i", + "neg-de" ], "rulesOut": [ "v5" @@ -2282,7 +2366,8 @@ "kanaIn": "わない", "kanaOut": "う", "rulesIn": [ - "adj-i" + "adj-i", + "neg-de" ], "rulesOut": [ "v5" @@ -3593,5 +3678,37 @@ "vk" ] } + ], + "progressive or perfect": [ + { + "kanaIn": "いる", + "kanaOut": "", + "rulesIn": [ + "v1" + ], + "rulesOut": [ + "iru" + ] + }, + { + "kanaIn": "る", + "kanaOut": "", + "rulesIn": [ + "v1" + ], + "rulesOut": [ + "iru" + ] + }, + { + "kanaIn": "おる", + "kanaOut": "", + "rulesIn": [ + "v1" + ], + "rulesOut": [ + "iru" + ] + } ] } -- cgit v1.2.3