chore: import upstream snapshot with attribution

This commit is contained in:
wehub-resource-sync
2026-07-13 13:25:10 +08:00
commit c397331b1e
3684 changed files with 990993 additions and 0 deletions
@@ -0,0 +1 @@
@@ -0,0 +1,50 @@
# Copyright 2017 Google Inc.
# Adapted from https://github.com/google/TextNormalizationCoveringGrammars
# Russian minimally supervised number grammar.
import pynini
from fun_text_processing.text_normalization.en.graph_utils import (
DAMO_NON_BREAKING_SPACE,
DAMO_SPACE,
)
from fun_text_processing.text_normalization.ru.utils import get_abs_path
RU_LOWER_ALPHA = "абвгдеёжзийклмнопрстуфхцчшщъыьэюя"
RU_UPPER_ALPHA = RU_LOWER_ALPHA.upper()
RU_LOWER_ALPHA = pynini.union(*RU_LOWER_ALPHA).optimize()
RU_UPPER_ALPHA = pynini.union(*RU_UPPER_ALPHA).optimize()
RU_ALPHA = (RU_LOWER_ALPHA | RU_UPPER_ALPHA).optimize()
RU_STRESSED_MAP = [
("А́", "А'"),
("Е́", "Е'"),
("Ё́", "Е'"),
("И́", "И'"),
("О́", "О'"),
("У́", "У'"),
("Ы́", "Ы'"),
("Э́", "Э'"),
("Ю́", "Ю'"),
("Я́", "Я'"),
("а́", "а'"),
("е́", "е'"),
("ё́", "е'"),
("и́", "и'"),
("о́", "о'"),
("у́", "у'"),
("ы́", "ы'"),
("э́", "э'"),
("ю́", "ю'"),
("я́", "я'"),
("ё", "е"),
("Ё", "Е"),
]
REWRITE_STRESSED = pynini.closure(
pynini.string_map(RU_STRESSED_MAP).optimize() | RU_ALPHA
).optimize()
TO_CYRILLIC = pynini.string_file(get_abs_path("data/latin_to_cyrillic.tsv")).optimize()
TO_LATIN = pynini.invert(TO_CYRILLIC).optimize()
RU_ALPHA_OR_SPACE = pynini.union(RU_ALPHA, DAMO_SPACE, DAMO_NON_BREAKING_SPACE).optimize()
@@ -0,0 +1 @@
@@ -0,0 +1,53 @@
р. рубли 0.1
р. рубля 0.1
р. рублей 0.1
р. рублям 0.1
р. рублями 0.1
р. рублях 0.1
руб. рубли -0.1
руб. рубля -0.1
руб. рублей -0.1
руб. рублям -0.1
руб. рублями -0.1
руб. рублях -0.1
₽ рубли 0.1
₽ рубля 0.1
₽ рублей 0.1
₽ рублям 0.1
₽ рублями 0.1
₽ рублях 0.1
RUB рубли 0.1
RUB рублей 0.1
RUB рубля 0.1
RUB рублям 0.1
RUB рублями 0.1
RUB рублях 0.1
$ доллары 0.1
$ долларов 0.1
$ доллара 0.1
$ долларам 0.1
$ доллары 0.1
$ долларами 0.1
USD доллары -0.1
USD долларов -0.1
USD долларам -0.1
USD долларах -0.1
USD долларами -0.1
USD американские доллары 0.1
USD американских долларов 0.1
USD американским долларам 0.1
USD американскими долларами 0.1
USD американских долларах 0.1
долл. США долларов сэ ш а 0.1
долл. США долларов с ш а 0.1
долл. США долларов сша -0.1
долл. США доллара сша -0.1
£ фунта 0.1
£ фунтов 0.1
€ евро 0.1
€ евро 0.1
коп. копейки
коп. копеек
коп. копейкам
коп. копейками
коп. копейках
1 р. рубли 0.1
2 р. рубля 0.1
3 р. рублей 0.1
4 р. рублям 0.1
5 р. рублями 0.1
6 р. рублях 0.1
7 руб. рубли -0.1
8 руб. рубля -0.1
9 руб. рублей -0.1
10 руб. рублям -0.1
11 руб. рублями -0.1
12 руб. рублях -0.1
13 рубли 0.1
14 рубля 0.1
15 рублей 0.1
16 рублям 0.1
17 рублями 0.1
18 рублях 0.1
19 RUB рубли 0.1
20 RUB рублей 0.1
21 RUB рубля 0.1
22 RUB рублям 0.1
23 RUB рублями 0.1
24 RUB рублях 0.1
25 $ доллары 0.1
26 $ долларов 0.1
27 $ доллара 0.1
28 $ долларам 0.1
29 $ доллары 0.1
30 $ долларами 0.1
31 USD доллары -0.1
32 USD долларов -0.1
33 USD долларам -0.1
34 USD долларах -0.1
35 USD долларами -0.1
36 USD американские доллары 0.1
37 USD американских долларов 0.1
38 USD американским долларам 0.1
39 USD американскими долларами 0.1
40 USD американских долларах 0.1
41 долл. США долларов сэ ш а 0.1
42 долл. США долларов с ш а 0.1
43 долл. США долларов сша -0.1
44 долл. США доллара сша -0.1
45 £ фунта 0.1
46 £ фунтов 0.1
47 евро 0.1
48 евро 0.1
49 коп. копейки
50 коп. копеек
51 коп. копейкам
52 коп. копейками
53 коп. копейках
@@ -0,0 +1,48 @@
р. рубль 1
р. рубля 1
р. рублю 1
р. рублем 1
р. рубле 1
руб. рубль -1
руб. рубля -1
руб. рублю -1
руб. рублем -1
руб. рубле -1
₽ рубль 1
₽ рубля 1
₽ рублю 1
₽ рублем 1
₽ рубле 1
RUB рубль 1
RUB рубль 1
RUB рубля 1
RUB рублю 1
RUB рублем 1
RUB рубле 1
USD доллар -1
USD доллара -1
USD доллару -1
USD долларом -1
USD долларе -1
USD американский доллар 1
USD американского доллара 1
USD американскому доллару 1
USD американским долларом 1
USD американском долларе 1
$ доллар 1
$ доллар сэ ш а
$ доллар с ш а
$ доллар 1
$ доллара 1
$ доллару 1
$ долларом 1
$ долларе 1
£ фунт
€ евро
коп. копейка
коп. копейки
коп. копейке
коп. копейку
коп. копейкой
коп. копейкою
коп. копейке
1 р. рубль 1
2 р. рубля 1
3 р. рублю 1
4 р. рублем 1
5 р. рубле 1
6 руб. рубль -1
7 руб. рубля -1
8 руб. рублю -1
9 руб. рублем -1
10 руб. рубле -1
11 рубль 1
12 рубля 1
13 рублю 1
14 рублем 1
15 рубле 1
16 RUB рубль 1
17 RUB рубль 1
18 RUB рубля 1
19 RUB рублю 1
20 RUB рублем 1
21 RUB рубле 1
22 USD доллар -1
23 USD доллара -1
24 USD доллару -1
25 USD долларом -1
26 USD долларе -1
27 USD американский доллар 1
28 USD американского доллара 1
29 USD американскому доллару 1
30 USD американским долларом 1
31 USD американском долларе 1
32 $ доллар 1
33 $ доллар сэ ш а
34 $ доллар с ш а
35 $ доллар 1
36 $ доллара 1
37 $ доллару 1
38 $ долларом 1
39 $ долларе 1
40 £ фунт
41 евро
42 коп. копейка
43 коп. копейки
44 коп. копейке
45 коп. копейку
46 коп. копейкой
47 коп. копейкою
48 коп. копейке
@@ -0,0 +1,9 @@
com ком
uk
fr
net нет
br
in
ru ру
de
it
1 com ком
2 uk
3 fr
4 net нет
5 br
6 in
7 ru ру
8 de
9 it
@@ -0,0 +1,17 @@
gmail джи мейл
n vidia н видия
n vidia эн видия
n vidia энвидия
n vidia нвидия
outlook аутлук
hotmail хот мейл
yahoo яху
aol
gmx
msn
live лайв
yandex яндекс
orange орандж
wanadoo ванаду
web веб
comcast комкаст
1 gmail джи мейл
2 n vidia н видия
3 n vidia эн видия
4 n vidia энвидия
5 n vidia нвидия
6 outlook аутлук
7 hotmail хот мейл
8 yahoo яху
9 aol
10 gmx
11 msn
12 live лайв
13 yandex яндекс
14 orange орандж
15 wanadoo ванаду
16 web веб
17 comcast комкаст
@@ -0,0 +1,28 @@
. точка
- тире
- дефис
- минус
_ нижнее подчеркивание
_ знак подчеркивания
! восклицательный знак
# решетка
$ доллар
% процент
& энд
& амперсанд
' кавычка
* звездочка
* знак умножения
+ плюс
/ слэш
/ косая черта
\ бэк слэш
\ обратная косая черта
= равно
? вопросительный знак
^ знак вставки
` кавычка
{ открытая фигурная скобка
| вертикальный слэш
} закрытая фигурная скобка
~ тильда
1 . точка
2 - тире
3 - дефис
4 - минус
5 _ нижнее подчеркивание
6 _ знак подчеркивания
7 ! восклицательный знак
8 # решетка
9 $ доллар
10 % процент
11 & энд
12 & амперсанд
13 ' кавычка
14 * звездочка
15 * знак умножения
16 + плюс
17 / слэш
18 / косая черта
19 \ бэк слэш
20 \ обратная косая черта
21 = равно
22 ? вопросительный знак
23 ^ знак вставки
24 ` кавычка
25 { открытая фигурная скобка
26 | вертикальный слэш
27 } закрытая фигурная скобка
28 ~ тильда
@@ -0,0 +1,38 @@
a эй
b би
b бэ
c си
d ди
e и
f эф
f ф
h эйч
h х
i ай
g джи
j джей
k кей
k к
l л
l эл
m эм
n н
n эн
o оу
o о
p пи
q кью
r а
r ар
r р
s эс
t ти
u ю
v ви
w дабл ю
w дабл в
x экс
y уай
z з
z зед
z зи
1 a эй
2 b би
3 b бэ
4 c си
5 d ди
6 e и
7 f эф
8 f ф
9 h эйч
10 h х
11 i ай
12 g джи
13 j джей
14 k кей
15 k к
16 l л
17 l эл
18 m эм
19 n н
20 n эн
21 o оу
22 o о
23 p пи
24 q кью
25 r а
26 r ар
27 r р
28 s эс
29 t ти
30 u ю
31 v ви
32 w дабл ю
33 w дабл в
34 x экс
35 y уай
36 z з
37 z зед
38 z зи
@@ -0,0 +1,321 @@
°F Фаренгейт
°F градусов Фаренгейта
°F градусов по Фаренгейту
°F фаренгейт
°F градусов фаренгейта
°F градусов по фаренгейту
°C цельсия
°C градусов цельсия
°C градусов по цельсию
°C Цельсия
°C градусов цельсия
°C градусов по цельсию
° градус
° градуса
° градусу
° градусом
° градусе
° градусы
° градусов
° градусам
° градусы
° градусами
° градусах
рад радиан
рад радиана
рад радиану
рад радианом
рад радиане
рад радианы
рад радианов
рад радианам
рад радианами
рад радианах
км километр
км километры
км километра
км километров
км километру
км километрам
км километром
км километрами
км километре
км километрах
м метр
м метра
м метру
м метра
м метром
м метре
м метры
м метров
м метрам
м метров
м метрами
м метрах
см сантиметр
см сантиметры
см сантиметра
см сантиметров
см сантиметру
см сантиметрам
см сантиметром
см сантиметрами
см сантиметре
см сантиметрах
мм миллиметр
мм миллиметры
мм миллиметра
мм миллиметров
мм миллиметру
мм миллиметрам
мм миллиметр
мм миллиметром
мм миллиметрами
мм миллиметре
мм миллиметрах
га гектар
га гектары
га гектара
га гектаров
га гектару
га гектарам
га гектаром
га гектарами
га гектаре
га гектарах
м² квадратный метр -0.11
м² квадратные метры -0.11
м² квадратного метра -0.11
м² квадратных метров -0.11
м² квадратному метру -0.11
м² квадратным метрам -0.11
м² квадратные метры -0.11
м² квадратным метром -0.11
м² квадратными метрами -0.11
м² квадратном метре -0.11
м² квадратных метрах -0.11
кв. м. квадратный метр -0.1
кв. м. квадратные метры -0.1
кв. м. квадратного метра -0.1
кв. м. квадратных метров -0.1
кв. м. квадратному метру -0.1
кв. м. квадратным метрам -0.1
кв. м. квадратные метры -0.1
кв. м. квадратным метром -0.1
кв. м. квадратными метрами -0.1
кв. м. квадратном метре -0.1
кв.м. квадратных метрах -0.1
кв.м. квадратный метр -0.1
кв.м. квадратные метры -0.1
кв.м. квадратного метра -0.1
кв.м. квадратных метров -0.1
кв.м. квадратному метру -0.1
кв.м. квадратным метрам -0.1
кв.м. квадратные метры -0.1
кв.м. квадратным метром -0.1
кв.м. квадратными метрами -0.1
кв.м. квадратном метре -0.1
кв.м. квадратных метрах -0.1
м2 квадратный метр 0.1
м2 квадратные метры 0.1
м2 квадратного метра 0.1
м2 квадратных метров 0.1
м2 квадратному метру 0.1
м2 квадратным метрам 0.1
м2 квадратные метры 0.1
м2 квадратным метром 0.1
м2 квадратными метрами 0.1
м2 квадратном метре 0.1
м2 квадратных метрах 0.1
₽ рублей 0.1
₽ рубля 0.1
₽ рубль 0.1
RUB рублей 0.1
RUB рубля 0.1
RUB рубль 0.1
pуб. рублей -0.1
pуб. рубля -0.1
pуб. рубль -0.1
pуб рублей 0.1
pуб рубля 0.1
pуб рубль 0.1
км² квадратный километр -0.1
км2 квадратный километр 0.1
% процент
% проценты
% процента
% процентов
% проценту
% процентам
% процентом
% процентами
% проценте
% процентах
кВт киловатт
л. с. лошадиная сила
л. с. лошадиные силы
л. с. лошадиной силы
л. с. лошадиных сил
л. с. лошадиной силе
л. с. лошадиным силам
л. с. лошадиную силу
л. с. лошадиные силы
л. с. лошадиной силой
л. с. лошадиной силою
л. с. лошадиными силами
л. с. лошадиных силах
мг миллиграм
кг килограм
кг килограма
кг килограму
кг килограм
кг килограмом
кг килограме
кг килограмы
кг килограмов
кг килограмам
кг килограмы
кг килограмами
кг килограмах
л литр
л литры
л литра
л литров
л литру
л литрам
л литры
л литром
л литрами
л литре
л литрах
л литре
кл килолитр
гл гектолитр
Мл мегалитр
Гл гигалитр
мл миллиитр
ч час
сек. секунд -0.1
сек. секунда -0.1
сек. секунды -0.1
сек. секунды -0.1
сек. секунд -0.1
сек. секунде -0.1
сек. секундам -0.1
сек. секунду -0.1
сек. секунды -0.1
сек. секундой -0.1
сек. секундами -0.1
сек. секунде -0.1
сек. секундах -0.1
сек секунд 0.1
сек секунда 0.1
сек секунды 0.1
сек секунды 0.1
сек секунд 0.1
сек секунде 0.1
сек секундам 0.1
сек секунду 0.1
сек секунды 0.1
сек секундой 0.1
сек секундами 0.1
сек секунде 0.1
сек секундах 0.1
с секунд 0.1
с секунда 0.1
с секунды 0.1
с секунды 0.1
с секунд 0.1
с секунде 0.1
с секундам 0.1
с секунду 0.1
с секунды 0.1
с секундой 0.1
с секундами 0.1
с секунде 0.1
с секундах 0.1
дас декасекунда
кс килосекунда
Мс мегасекунда
мс миллисекунда
нм нанометр
нм нанометра
нм нанометров
нм нанометры
А ампер
К кельвин
кд кандела
мА миллиампер
кВт⋅ч киловатт час
м³ кубический метр -0.1
м³ кубический метров -0.1
м3 кубический метр 0.1
м3 кубический метров 0.1
м³ кубометр -0.1
м³ кубометров -0.1
км/ч километров в час
км/ч километра в час
В вольт
гВ гектовольт
кВ киловольт
МВ мегавольт
мВ милливольт
мВт мегаватт
ТВт тераватт
мкм микрометр
г грамм
г граммов
дБ децибел
Б байт
Кбайт килобайт
Мбайт мегабайт
Пбайт петабайт
Тбайт терабайт 0.1
ТБ терабайт -0.1
Гбайт гигабайт 0.1
Гб гигабайт -0.1
Гц герц
даГц декагерц
дГц децигерц
гГц гектогерц
сГц сантигерц
кГц килогерц
мГц миллигерц
МГц мегагерц
мкГц микрогерц
ГГц гигагерц
нГц наногерц
ТГц терагерц
пГц пикогерц
ПГц петагерц
фГц фемтогерц
ЭГц эксагерц
аГц аттогерц
ЗГц зеттагерц
зГц зептогерц
ИГц иоттагерц
иГц иоктогерц
кбит килобит
Мбит мегабит
Гбит гигабит
Тбит терабит
бит/с бит в секунду
кбит/с килобит в секунду
Мбит/с мегабит в секунду
Гбит/с гигабит в секунду
нс наносекунда
нс наносекунды
нс наносекунд
мм² квадратный миллиметр -0.1
мм² квадратных миллиметров -0.1
мм² квадратных миллиметра -0.1
мм2 квадратный миллиметр 0.1
мм2 квадратных миллимета 0.1
мм2 квадратных миллиметров 0.1
см² квадратный сантиметр -0.1
см² квадратных сантимета -0.1
см² квадратных сантиметров -0.1
см2 квадратный сантиметр 0.1
см2 квадратных сантиметра 0.1
см2 квадратных сантиметров 0.1
1 °F Фаренгейт
2 °F градусов Фаренгейта
3 °F градусов по Фаренгейту
4 °F фаренгейт
5 °F градусов фаренгейта
6 °F градусов по фаренгейту
7 °C цельсия
8 °C градусов цельсия
9 °C градусов по цельсию
10 °C Цельсия
11 °C градусов цельсия
12 °C градусов по цельсию
13 ° градус
14 ° градуса
15 ° градусу
16 ° градусом
17 ° градусе
18 ° градусы
19 ° градусов
20 ° градусам
21 ° градусы
22 ° градусами
23 ° градусах
24 рад радиан
25 рад радиана
26 рад радиану
27 рад радианом
28 рад радиане
29 рад радианы
30 рад радианов
31 рад радианам
32 рад радианами
33 рад радианах
34 км километр
35 км километры
36 км километра
37 км километров
38 км километру
39 км километрам
40 км километром
41 км километрами
42 км километре
43 км километрах
44 м метр
45 м метра
46 м метру
47 м метра
48 м метром
49 м метре
50 м метры
51 м метров
52 м метрам
53 м метров
54 м метрами
55 м метрах
56 см сантиметр
57 см сантиметры
58 см сантиметра
59 см сантиметров
60 см сантиметру
61 см сантиметрам
62 см сантиметром
63 см сантиметрами
64 см сантиметре
65 см сантиметрах
66 мм миллиметр
67 мм миллиметры
68 мм миллиметра
69 мм миллиметров
70 мм миллиметру
71 мм миллиметрам
72 мм миллиметр
73 мм миллиметром
74 мм миллиметрами
75 мм миллиметре
76 мм миллиметрах
77 га гектар
78 га гектары
79 га гектара
80 га гектаров
81 га гектару
82 га гектарам
83 га гектаром
84 га гектарами
85 га гектаре
86 га гектарах
87 м² квадратный метр -0.11
88 м² квадратные метры -0.11
89 м² квадратного метра -0.11
90 м² квадратных метров -0.11
91 м² квадратному метру -0.11
92 м² квадратным метрам -0.11
93 м² квадратные метры -0.11
94 м² квадратным метром -0.11
95 м² квадратными метрами -0.11
96 м² квадратном метре -0.11
97 м² квадратных метрах -0.11
98 кв. м. квадратный метр -0.1
99 кв. м. квадратные метры -0.1
100 кв. м. квадратного метра -0.1
101 кв. м. квадратных метров -0.1
102 кв. м. квадратному метру -0.1
103 кв. м. квадратным метрам -0.1
104 кв. м. квадратные метры -0.1
105 кв. м. квадратным метром -0.1
106 кв. м. квадратными метрами -0.1
107 кв. м. квадратном метре -0.1
108 кв.м. квадратных метрах -0.1
109 кв.м. квадратный метр -0.1
110 кв.м. квадратные метры -0.1
111 кв.м. квадратного метра -0.1
112 кв.м. квадратных метров -0.1
113 кв.м. квадратному метру -0.1
114 кв.м. квадратным метрам -0.1
115 кв.м. квадратные метры -0.1
116 кв.м. квадратным метром -0.1
117 кв.м. квадратными метрами -0.1
118 кв.м. квадратном метре -0.1
119 кв.м. квадратных метрах -0.1
120 м2 квадратный метр 0.1
121 м2 квадратные метры 0.1
122 м2 квадратного метра 0.1
123 м2 квадратных метров 0.1
124 м2 квадратному метру 0.1
125 м2 квадратным метрам 0.1
126 м2 квадратные метры 0.1
127 м2 квадратным метром 0.1
128 м2 квадратными метрами 0.1
129 м2 квадратном метре 0.1
130 м2 квадратных метрах 0.1
131 рублей 0.1
132 рубля 0.1
133 рубль 0.1
134 RUB рублей 0.1
135 RUB рубля 0.1
136 RUB рубль 0.1
137 pуб. рублей -0.1
138 pуб. рубля -0.1
139 pуб. рубль -0.1
140 pуб рублей 0.1
141 pуб рубля 0.1
142 pуб рубль 0.1
143 км² квадратный километр -0.1
144 км2 квадратный километр 0.1
145 % процент
146 % проценты
147 % процента
148 % процентов
149 % проценту
150 % процентам
151 % процентом
152 % процентами
153 % проценте
154 % процентах
155 кВт киловатт
156 л. с. лошадиная сила
157 л. с. лошадиные силы
158 л. с. лошадиной силы
159 л. с. лошадиных сил
160 л. с. лошадиной силе
161 л. с. лошадиным силам
162 л. с. лошадиную силу
163 л. с. лошадиные силы
164 л. с. лошадиной силой
165 л. с. лошадиной силою
166 л. с. лошадиными силами
167 л. с. лошадиных силах
168 мг миллиграм
169 кг килограм
170 кг килограма
171 кг килограму
172 кг килограм
173 кг килограмом
174 кг килограме
175 кг килограмы
176 кг килограмов
177 кг килограмам
178 кг килограмы
179 кг килограмами
180 кг килограмах
181 л литр
182 л литры
183 л литра
184 л литров
185 л литру
186 л литрам
187 л литры
188 л литром
189 л литрами
190 л литре
191 л литрах
192 л литре
193 кл килолитр
194 гл гектолитр
195 Мл мегалитр
196 Гл гигалитр
197 мл миллиитр
198 ч час
199 сек. секунд -0.1
200 сек. секунда -0.1
201 сек. секунды -0.1
202 сек. секунды -0.1
203 сек. секунд -0.1
204 сек. секунде -0.1
205 сек. секундам -0.1
206 сек. секунду -0.1
207 сек. секунды -0.1
208 сек. секундой -0.1
209 сек. секундами -0.1
210 сек. секунде -0.1
211 сек. секундах -0.1
212 сек секунд 0.1
213 сек секунда 0.1
214 сек секунды 0.1
215 сек секунды 0.1
216 сек секунд 0.1
217 сек секунде 0.1
218 сек секундам 0.1
219 сек секунду 0.1
220 сек секунды 0.1
221 сек секундой 0.1
222 сек секундами 0.1
223 сек секунде 0.1
224 сек секундах 0.1
225 с секунд 0.1
226 с секунда 0.1
227 с секунды 0.1
228 с секунды 0.1
229 с секунд 0.1
230 с секунде 0.1
231 с секундам 0.1
232 с секунду 0.1
233 с секунды 0.1
234 с секундой 0.1
235 с секундами 0.1
236 с секунде 0.1
237 с секундах 0.1
238 дас декасекунда
239 кс килосекунда
240 Мс мегасекунда
241 мс миллисекунда
242 нм нанометр
243 нм нанометра
244 нм нанометров
245 нм нанометры
246 А ампер
247 К кельвин
248 кд кандела
249 мА миллиампер
250 кВт⋅ч киловатт час
251 м³ кубический метр -0.1
252 м³ кубический метров -0.1
253 м3 кубический метр 0.1
254 м3 кубический метров 0.1
255 м³ кубометр -0.1
256 м³ кубометров -0.1
257 км/ч километров в час
258 км/ч километра в час
259 В вольт
260 гВ гектовольт
261 кВ киловольт
262 МВ мегавольт
263 мВ милливольт
264 мВт мегаватт
265 ТВт тераватт
266 мкм микрометр
267 г грамм
268 г граммов
269 дБ децибел
270 Б байт
271 Кбайт килобайт
272 Мбайт мегабайт
273 Пбайт петабайт
274 Тбайт терабайт 0.1
275 ТБ терабайт -0.1
276 Гбайт гигабайт 0.1
277 Гб гигабайт -0.1
278 Гц герц
279 даГц декагерц
280 дГц децигерц
281 гГц гектогерц
282 сГц сантигерц
283 кГц килогерц
284 мГц миллигерц
285 МГц мегагерц
286 мкГц микрогерц
287 ГГц гигагерц
288 нГц наногерц
289 ТГц терагерц
290 пГц пикогерц
291 ПГц петагерц
292 фГц фемтогерц
293 ЭГц эксагерц
294 аГц аттогерц
295 ЗГц зеттагерц
296 зГц зептогерц
297 ИГц иоттагерц
298 иГц иоктогерц
299 кбит килобит
300 Мбит мегабит
301 Гбит гигабит
302 Тбит терабит
303 бит/с бит в секунду
304 кбит/с килобит в секунду
305 Мбит/с мегабит в секунду
306 Гбит/с гигабит в секунду
307 нс наносекунда
308 нс наносекунды
309 нс наносекунд
310 мм² квадратный миллиметр -0.1
311 мм² квадратных миллиметров -0.1
312 мм² квадратных миллиметра -0.1
313 мм2 квадратный миллиметр 0.1
314 мм2 квадратных миллимета 0.1
315 мм2 квадратных миллиметров 0.1
316 см² квадратный сантиметр -0.1
317 см² квадратных сантимета -0.1
318 см² квадратных сантиметров -0.1
319 см2 квадратный сантиметр 0.1
320 см2 квадратных сантиметра 0.1
321 см2 квадратных сантиметров 0.1
@@ -0,0 +1,12 @@
янв январь
фев февраль
мар март
апр апрель
май май
июнь июнь
июль июль
авг август
сент сентябрь
окт октябрь
нояб ноябрь
дек декабрь
1 янв январь
2 фев февраль
3 мар март
4 апр апрель
5 май май
6 июнь июнь
7 июль июль
8 авг август
9 сент сентябрь
10 окт октябрь
11 нояб ноябрь
12 дек декабрь
@@ -0,0 +1,62 @@
янв январь 0.1
янв января -0.1
янв январю 0.1
янв январем 0.1
янв январе 0.1
фев февраль 0.1
фев февраль 0.1
фев февраля -0.1
фев февралю 0.1
фев февралем 0.1
фев феврале 0.1
мар март 0.1
мар марта -0.1
мар марту 0.1
мар мартом 0.1
мар марте 0.1
апр апрель 0.1
апр апреля -0.1
апр апрелю 0.1
апр апрелем 0.1
апр апреле 0.1
май май 0.1
май мая -0.1
май маю 0.1
май маем 0.1
май мае 0.1
июнь июнь 0.1
июнь июня -0.1
июнь июню 0.1
июнь июнем 0.1
июнь июне 0.1
июль июль 0.1
июль июля -0.1
июль июлю 0.1
июль июлем 0.1
июль июле 0.1
авг август 0.1
авг августа -0.1
авг августу 0.1
авг август 0.1
авг августом 0.1
авг августе 0.1
сент сентябрь 0.1
сент сентября -0.1
сент сентябрю 0.1
сент сентябрем 0.1
сент сентябре 0.1
окт октябрь 0.1
окт октября -0.1
окт октябрю 0.1
окт октябрем 0.1
окт октябре 0.1
нояб ноябрь 0.1
нояб ноября -0.1
нояб ноябрю 0.1
нояб ноябрем 0.1
нояб ноябре 0.1
дек декабрь 0.1
дек декабря -0.1
дек декабрю 0.1
дек декабрем 0.1
дек декабре 0.1
1 янв январь 0.1
2 янв января -0.1
3 янв январю 0.1
4 янв январем 0.1
5 янв январе 0.1
6 фев февраль 0.1
7 фев февраль 0.1
8 фев февраля -0.1
9 фев февралю 0.1
10 фев февралем 0.1
11 фев феврале 0.1
12 мар март 0.1
13 мар марта -0.1
14 мар марту 0.1
15 мар мартом 0.1
16 мар марте 0.1
17 апр апрель 0.1
18 апр апреля -0.1
19 апр апрелю 0.1
20 апр апрелем 0.1
21 апр апреле 0.1
22 май май 0.1
23 май мая -0.1
24 май маю 0.1
25 май маем 0.1
26 май мае 0.1
27 июнь июнь 0.1
28 июнь июня -0.1
29 июнь июню 0.1
30 июнь июнем 0.1
31 июнь июне 0.1
32 июль июль 0.1
33 июль июля -0.1
34 июль июлю 0.1
35 июль июлем 0.1
36 июль июле 0.1
37 авг август 0.1
38 авг августа -0.1
39 авг августу 0.1
40 авг август 0.1
41 авг августом 0.1
42 авг августе 0.1
43 сент сентябрь 0.1
44 сент сентября -0.1
45 сент сентябрю 0.1
46 сент сентябрем 0.1
47 сент сентябре 0.1
48 окт октябрь 0.1
49 окт октября -0.1
50 окт октябрю 0.1
51 окт октябрем 0.1
52 окт октябре 0.1
53 нояб ноябрь 0.1
54 нояб ноября -0.1
55 нояб ноябрю 0.1
56 нояб ноябрем 0.1
57 нояб ноябре 0.1
58 дек декабрь 0.1
59 дек декабря -0.1
60 дек декабрю 0.1
61 дек декабрем 0.1
62 дек декабре 0.1
@@ -0,0 +1,21 @@
1 янв
2 фев
3 мар
4 апр
5 май
6 июнь
7 июль
8 авг
9 сент
10 окт
11 нояб
12 дек
01 янв
02 фев
03 мар
04 апр
05 май
06 июнь
07 июль
08 авг
09 сент
1 1 янв
2 2 фев
3 3 мар
4 4 апр
5 5 май
6 6 июнь
7 7 июль
8 8 авг
9 9 сент
10 10 окт
11 11 нояб
12 12 дек
13 01 янв
14 02 фев
15 03 мар
16 04 апр
17 05 май
18 06 июнь
19 07 июль
20 08 авг
21 09 сент
@@ -0,0 +1,50 @@
0 ноль
1 один
1 одна
1 одно
1 одни
2 два
2 две
3 три
4 четыре
5 пять
6 шесть
7 семь
8 восемь
9 девять
10 десять
11 одиннадцать
12 двенадцать
13 тринадцать
14 четырнадцать
15 пятнадцать
16 шестнадцать
17 семнадцать
18 восемнадцать
19 девятнадцать
20 двадцать
30 тридцать
40 сорок
50 пятьдесят
60 шестьдесят
70 семьдесят
80 восемьдесят
90 девяносто
100 сто
200 двести
300 триста
400 четыреста
500 пятьсот
600 шестьсот
700 семьсот
800 восемьсот
900 девятьсот
1000 тысяч
1000 тысяча
1000 тысячи
1000000 миллион
1000000 миллиона
1000000 миллионов
1000000000 миллиард
1000000000 миллиарда
1000000000 миллиардов
1 0 ноль
2 1 один
3 1 одна
4 1 одно
5 1 одни
6 2 два
7 2 две
8 3 три
9 4 четыре
10 5 пять
11 6 шесть
12 7 семь
13 8 восемь
14 9 девять
15 10 десять
16 11 одиннадцать
17 12 двенадцать
18 13 тринадцать
19 14 четырнадцать
20 15 пятнадцать
21 16 шестнадцать
22 17 семнадцать
23 18 восемнадцать
24 19 девятнадцать
25 20 двадцать
26 30 тридцать
27 40 сорок
28 50 пятьдесят
29 60 шестьдесят
30 70 семьдесят
31 80 восемьдесят
32 90 девяносто
33 100 сто
34 200 двести
35 300 триста
36 400 четыреста
37 500 пятьсот
38 600 шестьсот
39 700 семьсот
40 800 восемьсот
41 900 девятьсот
42 1000 тысяч
43 1000 тысяча
44 1000 тысячи
45 1000000 миллион
46 1000000 миллиона
47 1000000 миллионов
48 1000000000 миллиард
49 1000000000 миллиарда
50 1000000000 миллиардов
@@ -0,0 +1,45 @@
0 ноля
1 одного
1 одной
1 одних
2 двух
3 трех
4 четырех
5 пяти
6 шести
7 семи
8 восьми
9 девяти
10 десяти
11 одиннадцати
12 двенадцати
13 тринадцати
14 четырнадцати
15 пятнадцати
16 шестнадцати
17 семнадцати
18 восемнадцати
19 девятнадцати
20 двадцати
30 тридцати
40 сорока
50 пятидесяти
60 шестидесяти
70 семидесяти
80 восьмидесяти
90 девяноста
100 ста
200 двухсот
300 трехсот
400 четырехсот
500 пятисот
600 шестисот
700 семисот
800 восьмисот
900 девятисот
1000 тысячи
1000 тысяч
1000000 миллиона
1000000 миллионов
1000000000 миллиарда
1000000000 миллиардов
1 0 ноля
2 1 одного
3 1 одной
4 1 одних
5 2 двух
6 3 трех
7 4 четырех
8 5 пяти
9 6 шести
10 7 семи
11 8 восьми
12 9 девяти
13 10 десяти
14 11 одиннадцати
15 12 двенадцати
16 13 тринадцати
17 14 четырнадцати
18 15 пятнадцати
19 16 шестнадцати
20 17 семнадцати
21 18 восемнадцати
22 19 девятнадцати
23 20 двадцати
24 30 тридцати
25 40 сорока
26 50 пятидесяти
27 60 шестидесяти
28 70 семидесяти
29 80 восьмидесяти
30 90 девяноста
31 100 ста
32 200 двухсот
33 300 трехсот
34 400 четырехсот
35 500 пятисот
36 600 шестисот
37 700 семисот
38 800 восьмисот
39 900 девятисот
40 1000 тысячи
41 1000 тысяч
42 1000000 миллиона
43 1000000 миллионов
44 1000000000 миллиарда
45 1000000000 миллиардов
@@ -0,0 +1,45 @@
0 нолем
1 одним
1 одному
1 одной
2 двум
3 трем
4 четырем
5 пяти
6 шести
7 семи
8 восьми
9 девяти
10 десяти
11 одиннадцати
12 двенадцати
13 тринадцати
14 четырнадцати
15 пятнадцати
16 шестнадцати
17 семнадцати
18 восемнадцати
19 девятнадцати
20 двадцати
30 тридцати
40 сорока
50 пятидесяти
60 шестидесяти
70 семидесяти
80 восьмидесяти
90 девяноста
100 ста
200 двумстам
300 тремстам
400 четыремстам
500 пятистам
600 шестистам
700 семистам
800 восьмистам
900 девятистам
1000 тысяче
1000 тысячам
1000000 миллиону
1000000 миллионам
1000000000 миллиарду
1000000000 миллиардам
1 0 нолем
2 1 одним
3 1 одному
4 1 одной
5 2 двум
6 3 трем
7 4 четырем
8 5 пяти
9 6 шести
10 7 семи
11 8 восьми
12 9 девяти
13 10 десяти
14 11 одиннадцати
15 12 двенадцати
16 13 тринадцати
17 14 четырнадцати
18 15 пятнадцати
19 16 шестнадцати
20 17 семнадцати
21 18 восемнадцати
22 19 девятнадцати
23 20 двадцати
24 30 тридцати
25 40 сорока
26 50 пятидесяти
27 60 шестидесяти
28 70 семидесяти
29 80 восьмидесяти
30 90 девяноста
31 100 ста
32 200 двумстам
33 300 тремстам
34 400 четыремстам
35 500 пятистам
36 600 шестистам
37 700 семистам
38 800 восьмистам
39 900 девятистам
40 1000 тысяче
41 1000 тысячам
42 1000000 миллиону
43 1000000 миллионам
44 1000000000 миллиарду
45 1000000000 миллиардам
@@ -0,0 +1,48 @@
0 ноль
1 один
1 одного
1 одни
1 одно
1 одну
2 два
2 две
3 трех
4 четырех
5 пять
6 шесть
7 семь
8 восемь
9 девять
10 десять
11 одиннадцать
12 двенадцать
13 тринадцать
14 четырнадцать
15 пятнадцать
16 шестнадцать
17 семнадцать
18 восемнадцать
19 девятнадцать
20 двадцать
30 тридцать
40 сорок
50 пятьдесят
60 шестьдесят
70 семьдесят
80 восемьдесят
90 девяносто
100 сто
200 двести
300 триста
400 четыреста
500 пятьсот
600 шестьсот
700 семьсот
800 восемьсот
900 девятьсот
1000 тысячи
1000 тысячу
1000000 миллион
1000000 миллионы
1000000000 миллиард
1000000000 миллиарды
1 0 ноль
2 1 один
3 1 одного
4 1 одни
5 1 одно
6 1 одну
7 2 два
8 2 две
9 3 трех
10 4 четырех
11 5 пять
12 6 шесть
13 7 семь
14 8 восемь
15 9 девять
16 10 десять
17 11 одиннадцать
18 12 двенадцать
19 13 тринадцать
20 14 четырнадцать
21 15 пятнадцать
22 16 шестнадцать
23 17 семнадцать
24 18 восемнадцать
25 19 девятнадцать
26 20 двадцать
27 30 тридцать
28 40 сорок
29 50 пятьдесят
30 60 шестьдесят
31 70 семьдесят
32 80 восемьдесят
33 90 девяносто
34 100 сто
35 200 двести
36 300 триста
37 400 четыреста
38 500 пятьсот
39 600 шестьсот
40 700 семьсот
41 800 восемьсот
42 900 девятьсот
43 1000 тысячи
44 1000 тысячу
45 1000000 миллион
46 1000000 миллионы
47 1000000000 миллиард
48 1000000000 миллиарды
@@ -0,0 +1,47 @@
0 нолем
1 одним
1 одними
1 одной
1 одною
1 одну
2 двумя
3 тремя
4 четырьмя
5 пятью
6 шестью
7 семью
8 восемью
8 восьмью
9 девятью
10 десятью
11 одиннадцатью
12 двенадцатью
13 тринадцатью
14 четырнадцатью
15 пятнадцатью
16 шестнадцатью
17 семнадцатью
18 восемнадцатью
19 девятнадцатью
20 двадцатью
30 тридцатью
40 сорока
50 пятьюдесятью
60 шестьюдесятью
70 семьюдесятью
80 восьмьюдесятью
90 девяноста
100 ста
200 двумястами
300 тремястами
400 четырьмястами
500 пятьюстами
600 шестьюстами
700 семьюстами
800 восемьюстами
900 девятьюстами
1000000 миллионами
1000000 миллионом
1000000 миллиону
1000000 миллионы
1000000000 миллиардом
1 0 нолем
2 1 одним
3 1 одними
4 1 одной
5 1 одною
6 1 одну
7 2 двумя
8 3 тремя
9 4 четырьмя
10 5 пятью
11 6 шестью
12 7 семью
13 8 восемью
14 8 восьмью
15 9 девятью
16 10 десятью
17 11 одиннадцатью
18 12 двенадцатью
19 13 тринадцатью
20 14 четырнадцатью
21 15 пятнадцатью
22 16 шестнадцатью
23 17 семнадцатью
24 18 восемнадцатью
25 19 девятнадцатью
26 20 двадцатью
27 30 тридцатью
28 40 сорока
29 50 пятьюдесятью
30 60 шестьюдесятью
31 70 семьюдесятью
32 80 восьмьюдесятью
33 90 девяноста
34 100 ста
35 200 двумястами
36 300 тремястами
37 400 четырьмястами
38 500 пятьюстами
39 600 шестьюстами
40 700 семьюстами
41 800 восемьюстами
42 900 девятьюстами
43 1000000 миллионами
44 1000000 миллионом
45 1000000 миллиону
46 1000000 миллионы
47 1000000000 миллиардом
@@ -0,0 +1,46 @@
0 ноле
0 нуле
1 одной
1 одном
2 двух
3 трех
4 четырех
5 пяти
6 шести
7 семи
8 восьми
9 девяти
10 десяти
11 одиннадцати
12 двенадцати
13 тринадцати
14 четырнадцати
15 пятнадцати
16 шестнадцати
17 семнадцати
18 восемнадцати
19 девятнадцати
20 двадцати
30 тридцати
40 сорока
50 пятидесяти
60 шестидесяти
70 семидесяти
90 девяноста
100 ста
200 двухстах
300 трехстах
400 четырехстах
500 пятистах
600 шестистах
700 семистах
800 восьмистах
900 девятистах
900 девятьсот
900 девятьюстами
1000 тысячах
1000 тысяче
1000000 миллионах
1000000 миллионе
1000000000 миллиардах
1000000000 миллиарде
1 0 ноле
2 0 нуле
3 1 одной
4 1 одном
5 2 двух
6 3 трех
7 4 четырех
8 5 пяти
9 6 шести
10 7 семи
11 8 восьми
12 9 девяти
13 10 десяти
14 11 одиннадцати
15 12 двенадцати
16 13 тринадцати
17 14 четырнадцати
18 15 пятнадцати
19 16 шестнадцати
20 17 семнадцати
21 18 восемнадцати
22 19 девятнадцати
23 20 двадцати
24 30 тридцати
25 40 сорока
26 50 пятидесяти
27 60 шестидесяти
28 70 семидесяти
29 90 девяноста
30 100 ста
31 200 двухстах
32 300 трехстах
33 400 четырехстах
34 500 пятистах
35 600 шестистах
36 700 семистах
37 800 восьмистах
38 900 девятистах
39 900 девятьсот
40 900 девятьюстами
41 1000 тысячах
42 1000 тысяче
43 1000000 миллионах
44 1000000 миллионе
45 1000000000 миллиардах
46 1000000000 миллиарде
@@ -0,0 +1,16 @@
1т одна тысяча
1т одной тысячи
1т одной тысяче
1т одну тысячу
1т одной тысячей
1т одной тысяче
1млн один миллион
1млн одного миллиона
1млн одному миллиону
1млн одним миллионом
1млн одном миллионе
1млрд один миллиард
1млрд одного миллиарда
1млрд одному миллиарду
1млрд одним миллиардом
1млрд одном миллиарде
1 одна тысяча
2 одной тысячи
3 одной тысяче
4 одну тысячу
5 одной тысячей
6 одной тысяче
7 1млн один миллион
8 1млн одного миллиона
9 1млн одному миллиону
10 1млн одним миллионом
11 1млн одном миллионе
12 1млрд один миллиард
13 1млрд одного миллиарда
14 1млрд одному миллиарду
15 1млрд одним миллиардом
16 1млрд одном миллиарде
@@ -0,0 +1,37 @@
0 ноль
1 один
2 два
3 три
4 четыре
5 пять
6 шесть
7 семь
8 восемь
9 девять
10 десять
11 одиннадцать
12 двенадцать
13 тринадцать
14 четырнадцать
15 пятнадцать
16 шестнадцать
17 семнадцать
18 восемнадцать
19 девятнадцать
20 двадцать
30 тридцать
40 сорок
50 пятьдесят
60 шестьдесят
70 семьдесят
80 восемьдесят
90 девяносто
100 сто
200 двести
300 триста
400 четыреста
500 пятьсот
600 шестьсот
700 семьсот
800 восемьсот
900 девятьсот
1 0 ноль
2 1 один
3 2 два
4 3 три
5 4 четыре
6 5 пять
7 6 шесть
8 7 семь
9 8 восемь
10 9 девять
11 10 десять
12 11 одиннадцать
13 12 двенадцать
14 13 тринадцать
15 14 четырнадцать
16 15 пятнадцать
17 16 шестнадцать
18 17 семнадцать
19 18 восемнадцать
20 19 девятнадцать
21 20 двадцать
22 30 тридцать
23 40 сорок
24 50 пятьдесят
25 60 шестьдесят
26 70 семьдесят
27 80 восемьдесят
28 90 девяносто
29 100 сто
30 200 двести
31 300 триста
32 400 четыреста
33 500 пятьсот
34 600 шестьсот
35 700 семьсот
36 800 восемьсот
37 900 девятьсот
@@ -0,0 +1,15 @@
@@decimal_delimiter@@ целого 0.1
@@decimal_delimiter@@ целому 0.1
@@decimal_delimiter@@ целый 0.1
@@decimal_delimiter@@ целого 0.1
@@decimal_delimiter@@ целым 0.1
@@decimal_delimiter@@ целом 0.1
@@decimal_delimiter@@ целая -0.1
@@decimal_delimiter@@ целой 0.1
@@decimal_delimiter@@ целую 0.1
@@decimal_delimiter@@ целою 0.1
@@decimal_delimiter@@ целые -0.1
@@decimal_delimiter@@ целых -0.1
@@decimal_delimiter@@ целым 0.1
@@decimal_delimiter@@ целые 0.1
@@decimal_delimiter@@ целыми 0.1
1 @@decimal_delimiter@@ целого 0.1
2 @@decimal_delimiter@@ целому 0.1
3 @@decimal_delimiter@@ целый 0.1
4 @@decimal_delimiter@@ целого 0.1
5 @@decimal_delimiter@@ целым 0.1
6 @@decimal_delimiter@@ целом 0.1
7 @@decimal_delimiter@@ целая -0.1
8 @@decimal_delimiter@@ целой 0.1
9 @@decimal_delimiter@@ целую 0.1
10 @@decimal_delimiter@@ целою 0.1
11 @@decimal_delimiter@@ целые -0.1
12 @@decimal_delimiter@@ целых -0.1
13 @@decimal_delimiter@@ целым 0.1
14 @@decimal_delimiter@@ целые 0.1
15 @@decimal_delimiter@@ целыми 0.1
@@ -0,0 +1,37 @@
10 десятая -0.1
10 десятой 0.1
10 десятой 0.1
10 десятую 0.1
10 десятою 0.1
10 десятой 0.1
10 десятые 0.1
10 десятых -0.1
10 десятым 0.1
10 десятыми 0.1
100 сотые -0.1
100 сотых -0.1
100 сотым 0.1
100 сотыми 0.1
100 сотая -0.1
100 сотой 0.1
100 сотую 0.1
100 сотою 0.1
1000 тысячные -0.1
1000 тысячных -0.1
1000 тысячным 0.1
1000 тысячными 0.1
1000 тысячная -0.1
1000 тысячной 0.1
1000 тысячную 0.1
1000 тысячною 0.1
10000 десятитысячная -0.1
10000 десятитысячной 0.1
10000 десятитысячной 0.1
10000 десятитысячную 0.1
10000 десятитысячною 0.1
10000 десятитысячной 0.1
10000 десятитысячные 0.1
10000 десятитысячных -0.1
10000 десятитысячным 0.1
10000 десятитысячные 0.1
10000 десятитысячными 0.1
1 10 десятая -0.1
2 10 десятой 0.1
3 10 десятой 0.1
4 10 десятую 0.1
5 10 десятою 0.1
6 10 десятой 0.1
7 10 десятые 0.1
8 10 десятых -0.1
9 10 десятым 0.1
10 10 десятыми 0.1
11 100 сотые -0.1
12 100 сотых -0.1
13 100 сотым 0.1
14 100 сотыми 0.1
15 100 сотая -0.1
16 100 сотой 0.1
17 100 сотую 0.1
18 100 сотою 0.1
19 1000 тысячные -0.1
20 1000 тысячных -0.1
21 1000 тысячным 0.1
22 1000 тысячными 0.1
23 1000 тысячная -0.1
24 1000 тысячной 0.1
25 1000 тысячную 0.1
26 1000 тысячною 0.1
27 10000 десятитысячная -0.1
28 10000 десятитысячной 0.1
29 10000 десятитысячной 0.1
30 10000 десятитысячную 0.1
31 10000 десятитысячною 0.1
32 10000 десятитысячной 0.1
33 10000 десятитысячные 0.1
34 10000 десятитысячных -0.1
35 10000 десятитысячным 0.1
36 10000 десятитысячные 0.1
37 10000 десятитысячными 0.1
@@ -0,0 +1,10 @@
0 ноль
1 один
2 два
3 три
4 четыре
5 пять
6 шесть
7 семь
8 восемь
9 девять
1 0 ноль
2 1 один
3 2 два
4 3 три
5 4 четыре
6 5 пять
7 6 шесть
8 7 семь
9 8 восемь
10 9 девять
@@ -0,0 +1,40 @@
ая-ая
ого-го
ьего-го
ьего-его
ьей-ей
ьему-ему
ьем-ем
ое-е
ые-е
ье-е
ий-ий
ьими-ими
ьим-им
ьих-их
ьи-и
ий-й
ой-й
ый-й
ыми-ми
ьими-ми
ому-му
ьему-му
ого-ого
ое-ое
ой-ой
ом-ом
ому-ому
ую-ую
ых-х
ьих-х
ые-ые
ый-ый
ыми-ыми
ым-ым
ых-ых
ую-ю
ью-ю
ая-я
ья-я
ом-м
1 ая-ая
2 ого-го
3 ьего-го
4 ьего-его
5 ьей-ей
6 ьему-ему
7 ьем-ем
8 ое-е
9 ые-е
10 ье-е
11 ий-ий
12 ьими-ими
13 ьим-им
14 ьих-их
15 ьи-и
16 ий-й
17 ой-й
18 ый-й
19 ыми-ми
20 ьими-ми
21 ому-му
22 ьему-му
23 ого-ого
24 ое-ое
25 ой-ой
26 ом-ом
27 ому-ому
28 ую-ую
29 ых-х
30 ьих-х
31 ые-ые
32 ый-ый
33 ыми-ыми
34 ым-ым
35 ых-ых
36 ую-ю
37 ью-ю
38 ая-я
39 ья-я
40 ом-м
@@ -0,0 +1,752 @@
0 нулевая 0.1
0 нулевого 0.1
0 нулевое 0.1
0 нулевой 0.1
0 нулевом 0.1
0 нулевому 0.1
0 нулевую 0.1
0 нулевые -0.01
0 нулевым 0.1
0 нулевыми 0.1
0 нулевых 0.1
1 первая -0.01
1 первого -0.01
1 первое -0.01
1 первой 0.1
1 первом 0.1
1 первому 0.1
1 первую 0.1
1 первые 0.1
1 первый -0.01
1 первым 0.1
1 первыми 0.1
1 первых 0.1
2 вторая -0.01
2 второго 0.1
2 второе -0.01
2 второй -0.01
2 втором 0.1
2 второму 0.1
2 вторую 0.1
2 вторые 0.1
2 вторым 0.1
2 вторыми 0.1
2 вторых 0.1
3 третий
3 третье
3 третьего
3 третьей
3 третьем
3 третьему
3 третьи
3 третьим
3 третьим
3 третьими
3 третьих
3 третью
3 третья
4 четвертая
4 четвертого
4 четвертое
4 четвертой
4 четвертом
4 четвертому
4 четвертую
4 четвертые
4 четвертый
4 четвертым
4 четвертым
4 четвертыми
4 четвертых
4 четвертая
4 четвертого
4 четвертое
4 четвертой
4 четвертом
4 четвертому
4 четвертую
4 четвертые
4 четвертый
4 четвертым
4 четвертым
4 четвертыми
4 четвертых
5 пятая
5 пятого
5 пятое
5 пятой
5 пятом
5 пятому
5 пятую
5 пятые
5 пятый
5 пятым
5 пятым
5 пятыми
5 пятых
6 шестая
6 шестого
6 шестое
6 шестой
6 шестом
6 шестому
6 шестую
6 шестые
6 шестым
6 шестым
6 шестыми
6 шестых
7 седьмая
7 седьмого
7 седьмое
7 седьмой
7 седьмом
7 седьмому
7 седьмую
7 седьмые
7 седьмым
7 седьмым
7 седьмыми
7 седьмых
8 восьмая
8 восьмого
8 восьмое
8 восьмой
8 восьмом
8 восьмому
8 восьмую
8 восьмые
8 восьмым
8 восьмым
8 восьмыми
8 восьмых
9 девятая
9 девятого
9 девятое
9 девятой
9 девятом
9 девятому
9 девятую
9 девятые
9 девятый
9 девятым
9 девятым
9 девятыми
9 девятых
10 десятая
10 десятого
10 десятое
10 десятой
10 десятом
10 десятому
10 десятую
10 десятые
10 десятый
10 десятым
10 десятым
10 десятыми
10 десятых
11 одиннадцатая
11 одиннадцатого
11 одиннадцатое
11 одиннадцатой
11 одиннадцатом
11 одиннадцатому
11 одиннадцатую
11 одиннадцатые
11 одиннадцатый
11 одиннадцатым
11 одиннадцатым
11 одиннадцатыми
11 одиннадцатых
12 двенадцатая
12 двенадцатого
12 двенадцатое
12 двенадцатой
12 двенадцатом
12 двенадцатому
12 двенадцатую
12 двенадцатые
12 двенадцатый
12 двенадцатым
12 двенадцатым
12 двенадцатыми
12 двенадцатых
13 тринадцатая
13 тринадцатого
13 тринадцатое
13 тринадцатой
13 тринадцатом
13 тринадцатому
13 тринадцатую
13 тринадцатые
13 тринадцатый
13 тринадцатым
13 тринадцатым
13 тринадцатыми
13 тринадцатых
14 четырнадцатая
14 четырнадцатого
14 четырнадцатое
14 четырнадцатой
14 четырнадцатом
14 четырнадцатому
14 четырнадцатую
14 четырнадцатые
14 четырнадцатый
14 четырнадцатым
14 четырнадцатым
14 четырнадцатыми
14 четырнадцатых
15 пятнадцатая
15 пятнадцатого
15 пятнадцатое
15 пятнадцатой
15 пятнадцатом
15 пятнадцатому
15 пятнадцатую
15 пятнадцатые
15 пятнадцатый
15 пятнадцатым
15 пятнадцатым
15 пятнадцатыми
15 пятнадцатых
16 шестнадцатая
16 шестнадцатого
16 шестнадцатое
16 шестнадцатой
16 шестнадцатом
16 шестнадцатому
16 шестнадцатую
16 шестнадцатые
16 шестнадцатый
16 шестнадцатым
16 шестнадцатым
16 шестнадцатыми
16 шестнадцатых
17 семнадцатая
17 семнадцатого
17 семнадцатое
17 семнадцатой
17 семнадцатом
17 семнадцатому
17 семнадцатую
17 семнадцатые
17 семнадцатый
17 семнадцатым
17 семнадцатым
17 семнадцатыми
17 семнадцатых
18 восемнадцатая
18 восемнадцатого
18 восемнадцатое
18 восемнадцатой
18 восемнадцатом
18 восемнадцатому
18 восемнадцатую
18 восемнадцатые
18 восемнадцатый
18 восемнадцатым
18 восемнадцатым
18 восемнадцатыми
18 восемнадцатых
19 девятнадцатая
19 девятнадцатого
19 девятнадцатое
19 девятнадцатой
19 девятнадцатом
19 девятнадцатому
19 девятнадцатую
19 девятнадцатые
19 девятнадцатый
19 девятнадцатым
19 девятнадцатым
19 девятнадцатыми
19 девятнадцатых
20 двадцатая
20 двадцатого
20 двадцатое
20 двадцатой
20 двадцатом
20 двадцатому
20 двадцатую
20 двадцатые
20 двадцатый
20 двадцатым
20 двадцатым
20 двадцатыми
20 двадцатых
30 тридцатая
30 тридцатого
30 тридцатое
30 тридцатой
30 тридцатом
30 тридцатому
30 тридцатую
30 тридцатые
30 тридцатый
30 тридцатым
30 тридцатым
30 тридцатыми
30 тридцатых
40 сороковая
40 сорокового
40 сороковое
40 сороковой
40 сороковом
40 сороковому
40 сороковую
40 сороковые
40 сороковым
40 сороковым
40 сороковыми
40 сороковых
50 пятидесятая
50 пятидесятого
50 пятидесятое
50 пятидесятой
50 пятидесятом
50 пятидесятому
50 пятидесятую
50 пятидесятые
50 пятидесятый
50 пятидесятым
50 пятидесятым
50 пятидесятыми
50 пятидесятых
60 шестидесятая
60 шестидесятого
60 шестидесятое
60 шестидесятой
60 шестидесятом
60 шестидесятому
60 шестидесятую
60 шестидесятые
60 шестидесятый
60 шестидесятым
60 шестидесятым
60 шестидесятыми
60 шестидесятых
70 семидесятая
70 семидесятого
70 семидесятое
70 семидесятой
70 семидесятом
70 семидесятому
70 семидесятую
70 семидесятые
70 семидесятый
70 семидесятым
70 семидесятым
70 семидесятыми
70 семидесятых
80 восьмидесятая
80 восьмидесятого
80 восьмидесятое
80 восьмидесятой
80 восьмидесятом
80 восьмидесятому
80 восьмидесятую
80 восьмидесятые
80 восьмидесятый
80 восьмидесятым
80 восьмидесятым
80 восьмидесятыми
80 восьмидесятых
90 девяностая
90 девяностого
90 девяностое
90 девяностой
90 девяностом
90 девяностому
90 девяностую
90 девяностые
90 девяностый
90 девяностым
90 девяностым
90 девяностыми
90 девяностых
100 сотая
100 сотого
100 сотое
100 сотой
100 сотом
100 сотому
100 сотую
100 сотые
100 сотый
100 сотым
100 сотым
100 сотыми
100 сотых
200 двухсотая
200 двухсотого
200 двухсотое
200 двухсотой
200 двухсотом
200 двухсотому
200 двухсотую
200 двухсотые
200 двухсотый
200 двухсотым
200 двухсотым
200 двухсотыми
200 двухсотых
300 трехсотая
300 трехсотого
300 трехсотое
300 трехсотой
300 трехсотом
300 трехсотому
300 трехсотую
300 трехсотые
300 трехсотый
300 трехсотым
300 трехсотым
300 трехсотыми
300 трехсотых
400 четырехсотая
400 четырехсотого
400 четырехсотое
400 четырехсотой
400 четырехсотом
400 четырехсотому
400 четырехсотую
400 четырехсотые
400 четырехсотый
400 четырехсотым
400 четырехсотым
400 четырехсотыми
400 четырехсотых
500 пятисотая
500 пятисотого
500 пятисотое
500 пятисотой
500 пятисотом
500 пятисотому
500 пятисотую
500 пятисотые
500 пятисотый
500 пятисотым
500 пятисотым
500 пятисотыми
500 пятисотых
600 шестисотая
600 шестисотого
600 шестисотое
600 шестисотой
600 шестисотом
600 шестисотому
600 шестисотую
600 шестисотые
600 шестисотый
600 шестисотым
600 шестисотым
600 шестисотыми
600 шестисотых
700 семисотая
700 семисотого
700 семисотое
700 семисотой
700 семисотом
700 семисотому
700 семисотую
700 семисотые
700 семисотый
700 семисотым
700 семисотым
700 семисотыми
700 семисотых
800 восьмисотая
800 восьмисотого
800 восьмисотое
800 восьмисотой
800 восьмисотом
800 восьмисотому
800 восьмисотую
800 восьмисотые
800 восьмисотый
800 восьмисотым
800 восьмисотым
800 восьмисотыми
800 восьмисотых
900 девятисотая
900 девятисотого
900 девятисотое
900 девятисотой
900 девятисотом
900 девятисотому
900 девятисотую
900 девятисотые
900 девятисотый
900 девятисотым
900 девятисотым
900 девятисотыми
900 девятисотых
1000 тысячная
1000 тысячного
1000 тысячное
1000 тысячной
1000 тысячном
1000 тысячному
1000 тысячную
1000 тысячные
1000 тысячный
1000 тысячным
1000 тысячным
1000 тысячными
1000 тысячных
1000000 миллионная
1000000 миллионного
1000000 миллионное
1000000 миллионной
1000000 миллионном
1000000 миллионному
1000000 миллионную
1000000 миллионные
1000000 миллионный
1000000 миллионным
1000000 миллионным
1000000 миллионными
1000000 миллионных
1000000000 миллиардная
1000000000 миллиардного
1000000000 миллиардное
1000000000 миллиардной
1000000000 миллиардном
1000000000 миллиардному
1000000000 миллиардную
1000000000 миллиардные
1000000000 миллиардный
1000000000 миллиардным
1000000000 миллиардным
1000000000 миллиардными
1000000000 миллиардных
2000 двухтысячная
2000 двухтысячных
2000 двухтысячные
2000 двухтысячный
2000 двухтысячными
2000 двухтысячному
2000 двухтысячным
2000 двухтысячном
2000 двухтысячной
2000 двухтысячного
2000 двухтысячную
2000 двухтысячное
3000 трехтысячное
3000 трехтысячных
3000 трехтысячного
3000 трехтысячные
3000 трехтысячную
3000 трехтысячная
3000 трехтысячному
3000 трехтысячной
3000 трехтысячном
3000 трехтысячный
3000 трехтысячным
3000 трехтысячными
4000 четырехтысячных
4000 четырехтысячный
4000 четырехтысячное
4000 четырехтысячным
4000 четырехтысячными
4000 четырехтысячные
4000 четырехтысячному
4000 четырехтысячного
4000 четырехтысячной
4000 четырехтысячная
4000 четырехтысячную
4000 четырехтысячном
5000 пятитысячными
5000 пятитысячные
5000 пятитысячному
5000 пятитысячную
5000 пятитысячного
5000 пятитысячной
5000 пятитысячным
5000 пятитысячная
5000 пятитысячное
5000 пятитысячных
5000 пятитысячном
5000 пятитысячный
6000 шеститысячных
6000 шеститысячным
6000 шеститысячная
6000 шеститысячной
6000 шеститысячными
6000 шеститысячные
6000 шеститысячное
6000 шеститысячную
6000 шеститысячный
6000 шеститысячному
6000 шеститысячного
6000 шеститысячном
7000 семитысячную
7000 семитысячная
7000 семитысячном
7000 семитысячным
7000 семитысячного
7000 семитысячной
7000 семитысячный
7000 семитысячное
7000 семитысячных
7000 семитысячными
7000 семитысячные
7000 семитысячному
8000 восьмитысячному
8000 восьмитысячном
8000 восьмитысячную
8000 восьмитысячная
8000 восьмитысячными
8000 восьмитысячный
8000 восьмитысячной
8000 восьмитысячного
8000 восьмитысячное
8000 восьмитысячных
8000 восьмитысячным
8000 восьмитысячные
9000 девятитысячных
9000 девятитысячная
9000 девятитысячное
9000 девятитысячному
9000 девятитысячными
9000 девятитысячного
9000 девятитысячной
9000 девятитысячном
9000 девятитысячный
9000 девятитысячные
9000 девятитысячную
9000 девятитысячным
10000 десятитысячным
10000 десятитысячное
10000 десятитысячных
10000 десятитысячными
10000 десятитысячный
10000 десятитысячная
10000 десятитысячные
10000 десятитысячном
10000 десятитысячного
10000 десятитысячному
10000 десятитысячной
10000 десятитысячную
11000 одиннадцатитысячном
11000 одиннадцатитысячное
11000 одиннадцатитысячными
11000 одиннадцатитысячная
11000 одиннадцатитысячных
11000 одиннадцатитысячной
11000 одиннадцатитысячного
11000 одиннадцатитысячную
11000 одиннадцатитысячные
11000 одиннадцатитысячный
11000 одиннадцатитысячным
11000 одиннадцатитысячному
12000 двенадцатитысячного
12000 двенадцатитысячным
12000 двенадцатитысячной
12000 двенадцатитысячную
12000 двенадцатитысячный
12000 двенадцатитысячном
12000 двенадцатитысячными
12000 двенадцатитысячная
12000 двенадцатитысячному
12000 двенадцатитысячные
12000 двенадцатитысячное
12000 двенадцатитысячных
13000 тринадцатитысячных
13000 тринадцатитысячные
13000 тринадцатитысячной
13000 тринадцатитысячным
13000 тринадцатитысячное
13000 тринадцатитысячного
13000 тринадцатитысячная
13000 тринадцатитысячном
13000 тринадцатитысячными
13000 тринадцатитысячный
13000 тринадцатитысячную
13000 тринадцатитысячному
14000 четырнадцатитысячных
14000 четырнадцатитысячном
14000 четырнадцатитысячным
14000 четырнадцатитысячной
14000 четырнадцатитысячному
14000 четырнадцатитысячная
14000 четырнадцатитысячными
14000 четырнадцатитысячный
14000 четырнадцатитысячные
14000 четырнадцатитысячную
14000 четырнадцатитысячного
14000 четырнадцатитысячное
15000 пятнадцатитысячное
15000 пятнадцатитысячных
15000 пятнадцатитысячный
15000 пятнадцатитысячной
15000 пятнадцатитысячную
15000 пятнадцатитысячном
15000 пятнадцатитысячным
15000 пятнадцатитысячными
15000 пятнадцатитысячные
15000 пятнадцатитысячному
15000 пятнадцатитысячная
15000 пятнадцатитысячного
16000 шестнадцатитысячному
16000 шестнадцатитысячным
16000 шестнадцатитысячные
16000 шестнадцатитысячное
16000 шестнадцатитысячный
16000 шестнадцатитысячными
16000 шестнадцатитысячном
16000 шестнадцатитысячного
16000 шестнадцатитысячной
16000 шестнадцатитысячных
16000 шестнадцатитысячная
16000 шестнадцатитысячную
17000 семнадцатитысячного
17000 семнадцатитысячный
17000 семнадцатитысячное
17000 семнадцатитысячному
17000 семнадцатитысячную
17000 семнадцатитысячная
17000 семнадцатитысячной
17000 семнадцатитысячными
17000 семнадцатитысячным
17000 семнадцатитысячном
17000 семнадцатитысячные
17000 семнадцатитысячных
18000 восемнадцатитысячные
18000 восемнадцатитысячным
18000 восемнадцатитысячный
18000 восемнадцатитысячного
18000 восемнадцатитысячному
18000 восемнадцатитысячными
18000 восемнадцатитысячное
18000 восемнадцатитысячном
18000 восемнадцатитысячных
18000 восемнадцатитысячной
18000 восемнадцатитысячную
18000 восемнадцатитысячная
19000 девятнадцатитысячных
19000 девятнадцатитысячного
19000 девятнадцатитысячному
19000 девятнадцатитысячный
19000 девятнадцатитысячным
19000 девятнадцатитысячные
19000 девятнадцатитысячной
19000 девятнадцатитысячными
19000 девятнадцатитысячном
19000 девятнадцатитысячную
19000 девятнадцатитысячная
19000 девятнадцатитысячное
20000 двадцатитысячном
20000 двадцатитысячной
20000 двадцатитысячная
20000 двадцатитысячным
20000 двадцатитысячными
20000 двадцатитысячный
20000 двадцатитысячного
20000 двадцатитысячному
20000 двадцатитысячное
20000 двадцатитысячные
20000 двадцатитысячных
20000 двадцатитысячную
1 0 нулевая 0.1
2 0 нулевого 0.1
3 0 нулевое 0.1
4 0 нулевой 0.1
5 0 нулевом 0.1
6 0 нулевому 0.1
7 0 нулевую 0.1
8 0 нулевые -0.01
9 0 нулевым 0.1
10 0 нулевыми 0.1
11 0 нулевых 0.1
12 1 первая -0.01
13 1 первого -0.01
14 1 первое -0.01
15 1 первой 0.1
16 1 первом 0.1
17 1 первому 0.1
18 1 первую 0.1
19 1 первые 0.1
20 1 первый -0.01
21 1 первым 0.1
22 1 первыми 0.1
23 1 первых 0.1
24 2 вторая -0.01
25 2 второго 0.1
26 2 второе -0.01
27 2 второй -0.01
28 2 втором 0.1
29 2 второму 0.1
30 2 вторую 0.1
31 2 вторые 0.1
32 2 вторым 0.1
33 2 вторыми 0.1
34 2 вторых 0.1
35 3 третий
36 3 третье
37 3 третьего
38 3 третьей
39 3 третьем
40 3 третьему
41 3 третьи
42 3 третьим
43 3 третьим
44 3 третьими
45 3 третьих
46 3 третью
47 3 третья
48 4 четвертая
49 4 четвертого
50 4 четвертое
51 4 четвертой
52 4 четвертом
53 4 четвертому
54 4 четвертую
55 4 четвертые
56 4 четвертый
57 4 четвертым
58 4 четвертым
59 4 четвертыми
60 4 четвертых
61 4 четвертая
62 4 четвертого
63 4 четвертое
64 4 четвертой
65 4 четвертом
66 4 четвертому
67 4 четвертую
68 4 четвертые
69 4 четвертый
70 4 четвертым
71 4 четвертым
72 4 четвертыми
73 4 четвертых
74 5 пятая
75 5 пятого
76 5 пятое
77 5 пятой
78 5 пятом
79 5 пятому
80 5 пятую
81 5 пятые
82 5 пятый
83 5 пятым
84 5 пятым
85 5 пятыми
86 5 пятых
87 6 шестая
88 6 шестого
89 6 шестое
90 6 шестой
91 6 шестом
92 6 шестому
93 6 шестую
94 6 шестые
95 6 шестым
96 6 шестым
97 6 шестыми
98 6 шестых
99 7 седьмая
100 7 седьмого
101 7 седьмое
102 7 седьмой
103 7 седьмом
104 7 седьмому
105 7 седьмую
106 7 седьмые
107 7 седьмым
108 7 седьмым
109 7 седьмыми
110 7 седьмых
111 8 восьмая
112 8 восьмого
113 8 восьмое
114 8 восьмой
115 8 восьмом
116 8 восьмому
117 8 восьмую
118 8 восьмые
119 8 восьмым
120 8 восьмым
121 8 восьмыми
122 8 восьмых
123 9 девятая
124 9 девятого
125 9 девятое
126 9 девятой
127 9 девятом
128 9 девятому
129 9 девятую
130 9 девятые
131 9 девятый
132 9 девятым
133 9 девятым
134 9 девятыми
135 9 девятых
136 10 десятая
137 10 десятого
138 10 десятое
139 10 десятой
140 10 десятом
141 10 десятому
142 10 десятую
143 10 десятые
144 10 десятый
145 10 десятым
146 10 десятым
147 10 десятыми
148 10 десятых
149 11 одиннадцатая
150 11 одиннадцатого
151 11 одиннадцатое
152 11 одиннадцатой
153 11 одиннадцатом
154 11 одиннадцатому
155 11 одиннадцатую
156 11 одиннадцатые
157 11 одиннадцатый
158 11 одиннадцатым
159 11 одиннадцатым
160 11 одиннадцатыми
161 11 одиннадцатых
162 12 двенадцатая
163 12 двенадцатого
164 12 двенадцатое
165 12 двенадцатой
166 12 двенадцатом
167 12 двенадцатому
168 12 двенадцатую
169 12 двенадцатые
170 12 двенадцатый
171 12 двенадцатым
172 12 двенадцатым
173 12 двенадцатыми
174 12 двенадцатых
175 13 тринадцатая
176 13 тринадцатого
177 13 тринадцатое
178 13 тринадцатой
179 13 тринадцатом
180 13 тринадцатому
181 13 тринадцатую
182 13 тринадцатые
183 13 тринадцатый
184 13 тринадцатым
185 13 тринадцатым
186 13 тринадцатыми
187 13 тринадцатых
188 14 четырнадцатая
189 14 четырнадцатого
190 14 четырнадцатое
191 14 четырнадцатой
192 14 четырнадцатом
193 14 четырнадцатому
194 14 четырнадцатую
195 14 четырнадцатые
196 14 четырнадцатый
197 14 четырнадцатым
198 14 четырнадцатым
199 14 четырнадцатыми
200 14 четырнадцатых
201 15 пятнадцатая
202 15 пятнадцатого
203 15 пятнадцатое
204 15 пятнадцатой
205 15 пятнадцатом
206 15 пятнадцатому
207 15 пятнадцатую
208 15 пятнадцатые
209 15 пятнадцатый
210 15 пятнадцатым
211 15 пятнадцатым
212 15 пятнадцатыми
213 15 пятнадцатых
214 16 шестнадцатая
215 16 шестнадцатого
216 16 шестнадцатое
217 16 шестнадцатой
218 16 шестнадцатом
219 16 шестнадцатому
220 16 шестнадцатую
221 16 шестнадцатые
222 16 шестнадцатый
223 16 шестнадцатым
224 16 шестнадцатым
225 16 шестнадцатыми
226 16 шестнадцатых
227 17 семнадцатая
228 17 семнадцатого
229 17 семнадцатое
230 17 семнадцатой
231 17 семнадцатом
232 17 семнадцатому
233 17 семнадцатую
234 17 семнадцатые
235 17 семнадцатый
236 17 семнадцатым
237 17 семнадцатым
238 17 семнадцатыми
239 17 семнадцатых
240 18 восемнадцатая
241 18 восемнадцатого
242 18 восемнадцатое
243 18 восемнадцатой
244 18 восемнадцатом
245 18 восемнадцатому
246 18 восемнадцатую
247 18 восемнадцатые
248 18 восемнадцатый
249 18 восемнадцатым
250 18 восемнадцатым
251 18 восемнадцатыми
252 18 восемнадцатых
253 19 девятнадцатая
254 19 девятнадцатого
255 19 девятнадцатое
256 19 девятнадцатой
257 19 девятнадцатом
258 19 девятнадцатому
259 19 девятнадцатую
260 19 девятнадцатые
261 19 девятнадцатый
262 19 девятнадцатым
263 19 девятнадцатым
264 19 девятнадцатыми
265 19 девятнадцатых
266 20 двадцатая
267 20 двадцатого
268 20 двадцатое
269 20 двадцатой
270 20 двадцатом
271 20 двадцатому
272 20 двадцатую
273 20 двадцатые
274 20 двадцатый
275 20 двадцатым
276 20 двадцатым
277 20 двадцатыми
278 20 двадцатых
279 30 тридцатая
280 30 тридцатого
281 30 тридцатое
282 30 тридцатой
283 30 тридцатом
284 30 тридцатому
285 30 тридцатую
286 30 тридцатые
287 30 тридцатый
288 30 тридцатым
289 30 тридцатым
290 30 тридцатыми
291 30 тридцатых
292 40 сороковая
293 40 сорокового
294 40 сороковое
295 40 сороковой
296 40 сороковом
297 40 сороковому
298 40 сороковую
299 40 сороковые
300 40 сороковым
301 40 сороковым
302 40 сороковыми
303 40 сороковых
304 50 пятидесятая
305 50 пятидесятого
306 50 пятидесятое
307 50 пятидесятой
308 50 пятидесятом
309 50 пятидесятому
310 50 пятидесятую
311 50 пятидесятые
312 50 пятидесятый
313 50 пятидесятым
314 50 пятидесятым
315 50 пятидесятыми
316 50 пятидесятых
317 60 шестидесятая
318 60 шестидесятого
319 60 шестидесятое
320 60 шестидесятой
321 60 шестидесятом
322 60 шестидесятому
323 60 шестидесятую
324 60 шестидесятые
325 60 шестидесятый
326 60 шестидесятым
327 60 шестидесятым
328 60 шестидесятыми
329 60 шестидесятых
330 70 семидесятая
331 70 семидесятого
332 70 семидесятое
333 70 семидесятой
334 70 семидесятом
335 70 семидесятому
336 70 семидесятую
337 70 семидесятые
338 70 семидесятый
339 70 семидесятым
340 70 семидесятым
341 70 семидесятыми
342 70 семидесятых
343 80 восьмидесятая
344 80 восьмидесятого
345 80 восьмидесятое
346 80 восьмидесятой
347 80 восьмидесятом
348 80 восьмидесятому
349 80 восьмидесятую
350 80 восьмидесятые
351 80 восьмидесятый
352 80 восьмидесятым
353 80 восьмидесятым
354 80 восьмидесятыми
355 80 восьмидесятых
356 90 девяностая
357 90 девяностого
358 90 девяностое
359 90 девяностой
360 90 девяностом
361 90 девяностому
362 90 девяностую
363 90 девяностые
364 90 девяностый
365 90 девяностым
366 90 девяностым
367 90 девяностыми
368 90 девяностых
369 100 сотая
370 100 сотого
371 100 сотое
372 100 сотой
373 100 сотом
374 100 сотому
375 100 сотую
376 100 сотые
377 100 сотый
378 100 сотым
379 100 сотым
380 100 сотыми
381 100 сотых
382 200 двухсотая
383 200 двухсотого
384 200 двухсотое
385 200 двухсотой
386 200 двухсотом
387 200 двухсотому
388 200 двухсотую
389 200 двухсотые
390 200 двухсотый
391 200 двухсотым
392 200 двухсотым
393 200 двухсотыми
394 200 двухсотых
395 300 трехсотая
396 300 трехсотого
397 300 трехсотое
398 300 трехсотой
399 300 трехсотом
400 300 трехсотому
401 300 трехсотую
402 300 трехсотые
403 300 трехсотый
404 300 трехсотым
405 300 трехсотым
406 300 трехсотыми
407 300 трехсотых
408 400 четырехсотая
409 400 четырехсотого
410 400 четырехсотое
411 400 четырехсотой
412 400 четырехсотом
413 400 четырехсотому
414 400 четырехсотую
415 400 четырехсотые
416 400 четырехсотый
417 400 четырехсотым
418 400 четырехсотым
419 400 четырехсотыми
420 400 четырехсотых
421 500 пятисотая
422 500 пятисотого
423 500 пятисотое
424 500 пятисотой
425 500 пятисотом
426 500 пятисотому
427 500 пятисотую
428 500 пятисотые
429 500 пятисотый
430 500 пятисотым
431 500 пятисотым
432 500 пятисотыми
433 500 пятисотых
434 600 шестисотая
435 600 шестисотого
436 600 шестисотое
437 600 шестисотой
438 600 шестисотом
439 600 шестисотому
440 600 шестисотую
441 600 шестисотые
442 600 шестисотый
443 600 шестисотым
444 600 шестисотым
445 600 шестисотыми
446 600 шестисотых
447 700 семисотая
448 700 семисотого
449 700 семисотое
450 700 семисотой
451 700 семисотом
452 700 семисотому
453 700 семисотую
454 700 семисотые
455 700 семисотый
456 700 семисотым
457 700 семисотым
458 700 семисотыми
459 700 семисотых
460 800 восьмисотая
461 800 восьмисотого
462 800 восьмисотое
463 800 восьмисотой
464 800 восьмисотом
465 800 восьмисотому
466 800 восьмисотую
467 800 восьмисотые
468 800 восьмисотый
469 800 восьмисотым
470 800 восьмисотым
471 800 восьмисотыми
472 800 восьмисотых
473 900 девятисотая
474 900 девятисотого
475 900 девятисотое
476 900 девятисотой
477 900 девятисотом
478 900 девятисотому
479 900 девятисотую
480 900 девятисотые
481 900 девятисотый
482 900 девятисотым
483 900 девятисотым
484 900 девятисотыми
485 900 девятисотых
486 1000 тысячная
487 1000 тысячного
488 1000 тысячное
489 1000 тысячной
490 1000 тысячном
491 1000 тысячному
492 1000 тысячную
493 1000 тысячные
494 1000 тысячный
495 1000 тысячным
496 1000 тысячным
497 1000 тысячными
498 1000 тысячных
499 1000000 миллионная
500 1000000 миллионного
501 1000000 миллионное
502 1000000 миллионной
503 1000000 миллионном
504 1000000 миллионному
505 1000000 миллионную
506 1000000 миллионные
507 1000000 миллионный
508 1000000 миллионным
509 1000000 миллионным
510 1000000 миллионными
511 1000000 миллионных
512 1000000000 миллиардная
513 1000000000 миллиардного
514 1000000000 миллиардное
515 1000000000 миллиардной
516 1000000000 миллиардном
517 1000000000 миллиардному
518 1000000000 миллиардную
519 1000000000 миллиардные
520 1000000000 миллиардный
521 1000000000 миллиардным
522 1000000000 миллиардным
523 1000000000 миллиардными
524 1000000000 миллиардных
525 2000 двухтысячная
526 2000 двухтысячных
527 2000 двухтысячные
528 2000 двухтысячный
529 2000 двухтысячными
530 2000 двухтысячному
531 2000 двухтысячным
532 2000 двухтысячном
533 2000 двухтысячной
534 2000 двухтысячного
535 2000 двухтысячную
536 2000 двухтысячное
537 3000 трехтысячное
538 3000 трехтысячных
539 3000 трехтысячного
540 3000 трехтысячные
541 3000 трехтысячную
542 3000 трехтысячная
543 3000 трехтысячному
544 3000 трехтысячной
545 3000 трехтысячном
546 3000 трехтысячный
547 3000 трехтысячным
548 3000 трехтысячными
549 4000 четырехтысячных
550 4000 четырехтысячный
551 4000 четырехтысячное
552 4000 четырехтысячным
553 4000 четырехтысячными
554 4000 четырехтысячные
555 4000 четырехтысячному
556 4000 четырехтысячного
557 4000 четырехтысячной
558 4000 четырехтысячная
559 4000 четырехтысячную
560 4000 четырехтысячном
561 5000 пятитысячными
562 5000 пятитысячные
563 5000 пятитысячному
564 5000 пятитысячную
565 5000 пятитысячного
566 5000 пятитысячной
567 5000 пятитысячным
568 5000 пятитысячная
569 5000 пятитысячное
570 5000 пятитысячных
571 5000 пятитысячном
572 5000 пятитысячный
573 6000 шеститысячных
574 6000 шеститысячным
575 6000 шеститысячная
576 6000 шеститысячной
577 6000 шеститысячными
578 6000 шеститысячные
579 6000 шеститысячное
580 6000 шеститысячную
581 6000 шеститысячный
582 6000 шеститысячному
583 6000 шеститысячного
584 6000 шеститысячном
585 7000 семитысячную
586 7000 семитысячная
587 7000 семитысячном
588 7000 семитысячным
589 7000 семитысячного
590 7000 семитысячной
591 7000 семитысячный
592 7000 семитысячное
593 7000 семитысячных
594 7000 семитысячными
595 7000 семитысячные
596 7000 семитысячному
597 8000 восьмитысячному
598 8000 восьмитысячном
599 8000 восьмитысячную
600 8000 восьмитысячная
601 8000 восьмитысячными
602 8000 восьмитысячный
603 8000 восьмитысячной
604 8000 восьмитысячного
605 8000 восьмитысячное
606 8000 восьмитысячных
607 8000 восьмитысячным
608 8000 восьмитысячные
609 9000 девятитысячных
610 9000 девятитысячная
611 9000 девятитысячное
612 9000 девятитысячному
613 9000 девятитысячными
614 9000 девятитысячного
615 9000 девятитысячной
616 9000 девятитысячном
617 9000 девятитысячный
618 9000 девятитысячные
619 9000 девятитысячную
620 9000 девятитысячным
621 10000 десятитысячным
622 10000 десятитысячное
623 10000 десятитысячных
624 10000 десятитысячными
625 10000 десятитысячный
626 10000 десятитысячная
627 10000 десятитысячные
628 10000 десятитысячном
629 10000 десятитысячного
630 10000 десятитысячному
631 10000 десятитысячной
632 10000 десятитысячную
633 11000 одиннадцатитысячном
634 11000 одиннадцатитысячное
635 11000 одиннадцатитысячными
636 11000 одиннадцатитысячная
637 11000 одиннадцатитысячных
638 11000 одиннадцатитысячной
639 11000 одиннадцатитысячного
640 11000 одиннадцатитысячную
641 11000 одиннадцатитысячные
642 11000 одиннадцатитысячный
643 11000 одиннадцатитысячным
644 11000 одиннадцатитысячному
645 12000 двенадцатитысячного
646 12000 двенадцатитысячным
647 12000 двенадцатитысячной
648 12000 двенадцатитысячную
649 12000 двенадцатитысячный
650 12000 двенадцатитысячном
651 12000 двенадцатитысячными
652 12000 двенадцатитысячная
653 12000 двенадцатитысячному
654 12000 двенадцатитысячные
655 12000 двенадцатитысячное
656 12000 двенадцатитысячных
657 13000 тринадцатитысячных
658 13000 тринадцатитысячные
659 13000 тринадцатитысячной
660 13000 тринадцатитысячным
661 13000 тринадцатитысячное
662 13000 тринадцатитысячного
663 13000 тринадцатитысячная
664 13000 тринадцатитысячном
665 13000 тринадцатитысячными
666 13000 тринадцатитысячный
667 13000 тринадцатитысячную
668 13000 тринадцатитысячному
669 14000 четырнадцатитысячных
670 14000 четырнадцатитысячном
671 14000 четырнадцатитысячным
672 14000 четырнадцатитысячной
673 14000 четырнадцатитысячному
674 14000 четырнадцатитысячная
675 14000 четырнадцатитысячными
676 14000 четырнадцатитысячный
677 14000 четырнадцатитысячные
678 14000 четырнадцатитысячную
679 14000 четырнадцатитысячного
680 14000 четырнадцатитысячное
681 15000 пятнадцатитысячное
682 15000 пятнадцатитысячных
683 15000 пятнадцатитысячный
684 15000 пятнадцатитысячной
685 15000 пятнадцатитысячную
686 15000 пятнадцатитысячном
687 15000 пятнадцатитысячным
688 15000 пятнадцатитысячными
689 15000 пятнадцатитысячные
690 15000 пятнадцатитысячному
691 15000 пятнадцатитысячная
692 15000 пятнадцатитысячного
693 16000 шестнадцатитысячному
694 16000 шестнадцатитысячным
695 16000 шестнадцатитысячные
696 16000 шестнадцатитысячное
697 16000 шестнадцатитысячный
698 16000 шестнадцатитысячными
699 16000 шестнадцатитысячном
700 16000 шестнадцатитысячного
701 16000 шестнадцатитысячной
702 16000 шестнадцатитысячных
703 16000 шестнадцатитысячная
704 16000 шестнадцатитысячную
705 17000 семнадцатитысячного
706 17000 семнадцатитысячный
707 17000 семнадцатитысячное
708 17000 семнадцатитысячному
709 17000 семнадцатитысячную
710 17000 семнадцатитысячная
711 17000 семнадцатитысячной
712 17000 семнадцатитысячными
713 17000 семнадцатитысячным
714 17000 семнадцатитысячном
715 17000 семнадцатитысячные
716 17000 семнадцатитысячных
717 18000 восемнадцатитысячные
718 18000 восемнадцатитысячным
719 18000 восемнадцатитысячный
720 18000 восемнадцатитысячного
721 18000 восемнадцатитысячному
722 18000 восемнадцатитысячными
723 18000 восемнадцатитысячное
724 18000 восемнадцатитысячном
725 18000 восемнадцатитысячных
726 18000 восемнадцатитысячной
727 18000 восемнадцатитысячную
728 18000 восемнадцатитысячная
729 19000 девятнадцатитысячных
730 19000 девятнадцатитысячного
731 19000 девятнадцатитысячному
732 19000 девятнадцатитысячный
733 19000 девятнадцатитысячным
734 19000 девятнадцатитысячные
735 19000 девятнадцатитысячной
736 19000 девятнадцатитысячными
737 19000 девятнадцатитысячном
738 19000 девятнадцатитысячную
739 19000 девятнадцатитысячная
740 19000 девятнадцатитысячное
741 20000 двадцатитысячном
742 20000 двадцатитысячной
743 20000 двадцатитысячная
744 20000 двадцатитысячным
745 20000 двадцатитысячными
746 20000 двадцатитысячный
747 20000 двадцатитысячного
748 20000 двадцатитысячному
749 20000 двадцатитысячное
750 20000 двадцатитысячные
751 20000 двадцатитысячных
752 20000 двадцатитысячную
@@ -0,0 +1,16 @@
тысяч тысяч 0.1
тысяча тысяча 0.1
тысячи тысячи 0.1
тыс. тысячи 0.1
тыс тысячи -0.1
миллион миллион 0.1
миллионов миллионов 0.1
миллиона миллиона 0.1
миллиона миллиона 0.1
млн. миллиона 0.1
млн миллиона -0.1
миллиарда миллиарда 0.1
миллиард миллиард 0.1
миллиардов миллиардов 0.1
млрд. миллиарда 0.1
млрд миллиарда -0.1
1 тысяч тысяч 0.1
2 тысяча тысяча 0.1
3 тысячи тысячи 0.1
4 тыс. тысячи 0.1
5 тыс тысячи -0.1
6 миллион миллион 0.1
7 миллионов миллионов 0.1
8 миллиона миллиона 0.1
9 миллиона миллиона 0.1
10 млн. миллиона 0.1
11 млн миллиона -0.1
12 миллиарда миллиарда 0.1
13 миллиард миллиард 0.1
14 миллиардов миллиардов 0.1
15 млрд. миллиарда 0.1
16 млрд миллиарда -0.1
@@ -0,0 +1,24 @@
00 час -0.1
01 два -0.1
02 три -0.1
03 четыре -0.1
04 пять -0.1
05 шесть -0.1
06 семь -0.1
07 восемь -0.1
08 девять -0.1
09 десять -0.1
10 одиннадцать 0.1
11 двенадцать 0.1
12 час 0.1
13 два 0.1
14 три 0.1
15 четыре 0.1
16 пять 0.1
17 шесть 0.1
18 семь 0.1
19 восемь 0.1
20 девять 0.1
21 десять 0.1
22 одиннадцать 0.1
23 двенадцать 0.1
1 00 час -0.1
2 01 два -0.1
3 02 три -0.1
4 03 четыре -0.1
5 04 пять -0.1
6 05 шесть -0.1
7 06 семь -0.1
8 07 восемь -0.1
9 08 девять -0.1
10 09 десять -0.1
11 10 одиннадцать 0.1
12 11 двенадцать 0.1
13 12 час 0.1
14 13 два 0.1
15 14 три 0.1
16 15 четыре 0.1
17 16 пять 0.1
18 17 шесть 0.1
19 18 семь 0.1
20 19 восемь 0.1
21 20 девять 0.1
22 21 десять 0.1
23 22 одиннадцать 0.1
24 23 двенадцать 0.1
@@ -0,0 +1,24 @@
00 первого 0.1
01 второго -0.1
02 третьего -0.1
03 четвертого -0.1
04 пятого -0.1
05 шестого -0.1
06 седьмого -0.1
07 восьмого -0.1
08 девятого -0.1
09 десятого -0.1
10 одиннадцатого -0.1
11 двенадцатого -0.1
12 первого -0.1
13 второго 0.1
14 третьего 0.1
15 четвертого 0.1
16 пятого 0.1
17 шестого 0.1
18 седьмого 0.1
19 восьмого 0.1
20 девятого 0.1
21 десятого 0.1
22 одиннадцатого 0.1
23 двенадцатого 0.1
1 00 первого 0.1
2 01 второго -0.1
3 02 третьего -0.1
4 03 четвертого -0.1
5 04 пятого -0.1
6 05 шестого -0.1
7 06 седьмого -0.1
8 07 восьмого -0.1
9 08 девятого -0.1
10 09 десятого -0.1
11 10 одиннадцатого -0.1
12 11 двенадцатого -0.1
13 12 первого -0.1
14 13 второго 0.1
15 14 третьего 0.1
16 15 четвертого 0.1
17 16 пятого 0.1
18 17 шестого 0.1
19 18 седьмого 0.1
20 19 восьмого 0.1
21 20 девятого 0.1
22 21 десятого 0.1
23 22 одиннадцатого 0.1
24 23 двенадцатого 0.1
@@ -0,0 +1,25 @@
59 одной минуты
58 двух минут
57 трех минут
56 четырех минут
55 пяти минут
54 шести минут
53 семи минут
52 восеми минут
51 девяти минут
50 десяти минут
49 одиннадцати минут
48 двенадцати минут
47 тринадцати минут
46 четырнадцати минут
45 пятнадцати минут
44 шестнадцати минут
43 семнадцати минут
42 восемьнадцати минут
41 девятнадцати минут
40 двадцати минут
39 двадцати одной минуты
38 двадцати двух минут
37 двадцати трех минут
36 двадцати четырех минут
35 двадцать пяти минут
1 59 одной минуты
2 58 двух минут
3 57 трех минут
4 56 четырех минут
5 55 пяти минут
6 54 шести минут
7 53 семи минут
8 52 восеми минут
9 51 девяти минут
10 50 десяти минут
11 49 одиннадцати минут
12 48 двенадцати минут
13 47 тринадцати минут
14 46 четырнадцати минут
15 45 пятнадцати минут
16 44 шестнадцати минут
17 43 семнадцати минут
18 42 восемьнадцати минут
19 41 девятнадцати минут
20 40 двадцати минут
21 39 двадцати одной минуты
22 38 двадцати двух минут
23 37 двадцати трех минут
24 36 двадцати четырех минут
25 35 двадцать пяти минут
@@ -0,0 +1,12 @@
13 1
14 2
15 3
16 4
17 5
18 6
19 7
20 8
21 9
22 10
23 11
24 12
1 13 1
2 14 2
3 15 3
4 16 4
5 17 5
6 18 6
7 19 7
8 20 8
9 21 9
10 22 10
11 23 11
12 24 12
@@ -0,0 +1,37 @@
гг. годы
г. год
г. году
г. год
г. года
г. годом
г. годе
§ параграф
комн. комнатная
эт. этажный
кв. квартира
кв. квартал
кв. квартала
кв. кварталу
кв. кварталом
кв. квартале
ЖК женская консультация
ЖК жидкие кристаллы
ЖК жилой комплекс
ЖК жилищный кооператив
ЖК жилищный кодекс
р-н район
до н. э. до нашей эры
н. э. нашей эры
см. также смотри также
с.ш. северной широты
ю.ш. южной широты
в.д. восточной долготы
з.д. западной долготы
и т. д. и так далее
и т. п. и тому подобное
б/у бывший в употреблении
экз. экземпляр
экз. экземпляры
и др. и другие
и пр. и прочие
т.е. то есть
1 гг. годы
2 г. год
3 г. году
4 г. год
5 г. года
6 г. годом
7 г. годе
8 § параграф
9 комн. комнатная
10 эт. этажный
11 кв. квартира
12 кв. квартал
13 кв. квартала
14 кв. кварталу
15 кв. кварталом
16 кв. квартале
17 ЖК женская консультация
18 ЖК жидкие кристаллы
19 ЖК жилой комплекс
20 ЖК жилищный кооператив
21 ЖК жилищный кодекс
22 р-н район
23 до н. э. до нашей эры
24 н. э. нашей эры
25 см. также смотри также
26 с.ш. северной широты
27 ю.ш. южной широты
28 в.д. восточной долготы
29 з.д. западной долготы
30 и т. д. и так далее
31 и т. п. и тому подобное
32 б/у бывший в употреблении
33 экз. экземпляр
34 экз. экземпляры
35 и др. и другие
36 и пр. и прочие
37 т.е. то есть
@@ -0,0 +1 @@
@@ -0,0 +1,165 @@
# Copyright 2017 Google Inc.
# Adapted from https://github.com/google/TextNormalizationCoveringGrammars
# Russian minimally supervised number grammar.
import pynini
from fun_text_processing.text_normalization.en.graph_utils import (
DAMO_DIGIT,
DAMO_SIGMA,
DAMO_SPACE,
GraphFst,
insert_space,
)
from fun_text_processing.text_normalization.ru.alphabet import RU_ALPHA, TO_CYRILLIC
from fun_text_processing.text_normalization.ru.utils import get_abs_path
from pynini.lib import pynutil
class CardinalFst(GraphFst):
"""
Finite state transducer for classifying cardinals, e.g.
"1 001" -> cardinal { integer: "тысяча один" }
Args:
number_names: number_names for cardinal and ordinal numbers
alternative_formats: alternative number formats
deterministic: if True will provide a single transduction option,
for False multiple transduction are generated (used for audio-based normalization)
"""
def __init__(self, number_names: dict, alternative_formats: dict, deterministic: bool = False):
super().__init__(name="cardinal", kind="classify", deterministic=deterministic)
self.cardinal_numbers_default = self.get_cardinal_numbers(
number_names, alternative_formats, mode="all"
)
self.cardinal_numbers_nominative = self.get_cardinal_numbers(
number_names, alternative_formats, mode="nominative"
)
self.optional_graph_negative = pynini.closure(
pynutil.insert("negative: ") + pynini.cross("-", '"true"') + insert_space, 0, 1
)
self.cardinal_numbers_with_optional_negative = (
self.optional_graph_negative
+ pynutil.insert('integer: "')
+ self.cardinal_numbers_default
+ pynutil.insert('"')
)
# "03" -> remove leading zeros and verbalize
leading_zeros = pynini.closure(pynini.cross("0", ""))
self.cardinal_numbers_with_leading_zeros = (
leading_zeros + self.cardinal_numbers_default
).optimize()
# "123" -> "один два три"
single_digits_graph = pynini.string_file(
get_abs_path("data/numbers/cardinals_nominative_case.tsv")
).optimize()
single_digits_graph = pynini.compose(DAMO_DIGIT, single_digits_graph)
self.single_digits_graph = single_digits_graph + pynini.closure(
insert_space + single_digits_graph
)
optional_quantity = pynini.string_file(get_abs_path("data/numbers/quantity.tsv")).optimize()
optional_quantity = pynutil.insert('quantity: "') + optional_quantity + pynutil.insert('"')
optional_quantity = pynini.closure(
(pynutil.add_weight(pynini.accep(DAMO_SPACE), -0.1) | insert_space) + optional_quantity,
0,
1,
)
serial_graph = self.get_serial_graph()
final_graph = (
self.optional_graph_negative
+ pynutil.insert('integer: "')
+ self.cardinal_numbers_with_leading_zeros
+ pynutil.insert('"')
+ optional_quantity
).optimize()
final_graph = pynutil.add_weight(final_graph, -0.1)
final_graph |= (
pynutil.insert('integer: "')
+ pynutil.add_weight(serial_graph, 10)
+ pynutil.insert('"')
)
self.final_graph = final_graph
# to cover cases "2-х" -> "двух" (this is not covered by ordinal endings)
final_graph |= pynini.compose(
pynini.compose(DAMO_DIGIT ** (1, ...) + pynini.cross("-х", ""), final_graph),
DAMO_SIGMA + pynini.accep('х"') + DAMO_SIGMA,
)
final_graph = self.add_tokens(final_graph)
self.fst = final_graph.optimize()
def get_cardinal_numbers(
self, number_names: dict, alternative_formats: dict, mode: str = "all"
):
"""Returns cardinal numbers names graph.
Args:
number_names: number_names for cardinal and ordinal numbers
alternative_formats: alternative number formats
mode: "all" - to return graph that includes all Ru cases, "nominative" to return only the nominative form
"""
if mode == "all":
cardinal_names = number_names["cardinal_number_names"]
elif mode == "nominative":
cardinal_names = number_names["cardinal_names_nominative"]
else:
raise ValueError(f"{mode} is not supported.")
one_thousand_alternative = alternative_formats["one_thousand_alternative"]
separators = alternative_formats["separators"]
cardinal_numbers = cardinal_names | pynini.compose(cardinal_names, one_thousand_alternative)
cardinal_numbers = pynini.compose(separators, cardinal_numbers)
return cardinal_numbers
def get_serial_graph(self):
"""
Finite state transducer for classifying serial.
The serial is a combination of digits, letters and dashes, e.g.:
c325-b -> tokens { cardinal { integer: "си три два пять би" } }
"""
num_graph = self.single_digits_graph
alpha = TO_CYRILLIC | RU_ALPHA
delimiter = insert_space | pynini.cross("-", " ") | pynini.cross("/", " ")
letter_num = pynini.closure(alpha + delimiter, 1) + num_graph
num_letter = pynini.closure(num_graph + delimiter, 1) + alpha
num_delimiter_num = pynini.closure(num_graph + delimiter, 1) + num_graph
next_alpha_or_num = pynini.closure(delimiter + (alpha | num_graph))
serial_graph = (letter_num | num_letter | num_delimiter_num) + next_alpha_or_num
# at least 1 alpha and 1 digit is present
at_least_one_alpha_num = (
DAMO_SIGMA
+ (RU_ALPHA | pynini.project(TO_CYRILLIC, "input"))
+ DAMO_SIGMA
+ DAMO_DIGIT
+ DAMO_SIGMA
) | (
DAMO_SIGMA
+ DAMO_DIGIT
+ DAMO_SIGMA
+ (RU_ALPHA | pynini.project(TO_CYRILLIC, "input"))
+ DAMO_SIGMA
)
serial_graph = pynini.compose(at_least_one_alpha_num, serial_graph.optimize()).optimize()
# numbers only with 2+ delimiters
serial_graph |= (
num_graph
+ delimiter
+ num_graph
+ delimiter
+ num_graph
+ pynini.closure(delimiter + num_graph)
).optimize()
return serial_graph.optimize()
@@ -0,0 +1,139 @@
import pynini
from fun_text_processing.text_normalization.en.graph_utils import (
DAMO_DIGIT,
DAMO_NOT_QUOTE,
DAMO_SIGMA,
GraphFst,
delete_extra_space,
delete_space,
insert_space,
)
from fun_text_processing.text_normalization.ru.utils import get_abs_path
from pynini.lib import pynutil
class DateFst(GraphFst):
"""
Finite state transducer for classifying date, e.g.
"01.05" -> tokens { date { day: "первое мая" } }
Args:
number_names: number_names for cardinal and ordinal numbers
deterministic: if True will provide a single transduction option,
for False multiple transduction are generated (used for audio-based normalization)
"""
def __init__(self, number_names: dict, deterministic: bool):
super().__init__(name="date", kind="classify", deterministic=deterministic)
# Ru format: DD-MM-YYYY or DD-MM-YY
month_abbr_to_names = pynini.string_file(
get_abs_path("data/months/abbr_to_name.tsv")
).optimize()
delete_sep = pynutil.add_weight(pynini.cross(".", " "), 1.09) | pynutil.add_weight(
pynini.cross(pynini.union("/", "-"), " "), 1.1
)
numbers = number_names["ordinal_number_names"]
zero = (pynutil.add_weight(pynini.cross("0", ""), -0.1)) | (
pynutil.add_weight(pynini.cross("0", "ноль "), 0.1)
)
zero_digit = zero + pynini.compose(DAMO_DIGIT, numbers)
digit_day = (pynini.union("1", "2", "3") + DAMO_DIGIT) | DAMO_DIGIT
digit_day = pynini.compose(digit_day, numbers)
day = zero_digit | digit_day
day = pynini.compose(
day,
pynini.difference(DAMO_SIGMA, DAMO_SIGMA + pynini.union("ой", "ая", "ых", "ые", "ыми")),
)
day = (pynutil.insert('day: "') + day + pynutil.insert('"')).optimize()
digit_month = zero_digit | pynini.compose(pynini.accep("1") + DAMO_DIGIT, numbers)
month_number_to_abbr = pynini.string_file(
get_abs_path("data/months/numbers.tsv")
).optimize()
month_number_to_abbr = (
(
((pynutil.add_weight(pynini.cross("0", ""), -0.1) | pynini.accep("1")) + DAMO_DIGIT)
| DAMO_DIGIT
).optimize()
@ month_number_to_abbr
).optimize()
month_name = (
(month_number_to_abbr @ month_abbr_to_names)
| pynutil.add_weight(month_abbr_to_names, 0.1)
).optimize()
month = (
pynutil.insert('month: "')
+ (month_name | pynutil.add_weight(digit_month, 0.1))
+ pynutil.insert('"')
).optimize()
year = pynini.compose(((DAMO_DIGIT**4) | (DAMO_DIGIT**2)), numbers).optimize()
year |= zero_digit
# reduce year options
year_wrong_endings = ["ую", "ая"]
year_wrong_beginning = ["две тысяча", "два тысяч", "два тысячи", "две тысяч "]
year = pynini.compose(
year, pynini.difference(DAMO_SIGMA, DAMO_SIGMA + pynini.union("ой", "ого"))
) | pynutil.add_weight(pynini.compose(year, DAMO_SIGMA + pynini.union("ой", "ого")), -0.1)
year_restrict1 = pynini.difference(
DAMO_SIGMA, pynini.union(*year_wrong_beginning) + DAMO_SIGMA
)
year_restrict2 = pynini.difference(
DAMO_SIGMA, DAMO_SIGMA + pynini.union(*year_wrong_endings)
)
year = pynini.compose(pynini.compose(year, year_restrict1), year_restrict2)
year_word_singular = ["год", "года", "году", "годом", "годе"]
year_word_plural = ["годы", "годов", "годам", "годами", "годам", "годах"]
year_word = pynini.cross("г.", pynini.union(*year_word_singular))
year_word |= pynini.cross("гг.", pynini.union(*year_word_plural))
year_word = (
pynutil.add_weight(insert_space, -0.1) | pynutil.add_weight(pynini.accep(" "), 0.1)
) + year_word
year_optional = (
pynutil.insert('year: "') + year + pynini.closure(year_word, 0, 1) + pynutil.insert('"')
)
year_optional = pynini.closure(delete_sep + year_optional, 0, 1).optimize()
year_only = pynutil.insert('year: "') + year + year_word + pynutil.insert('"')
tagger_graph = (day + delete_sep + month + year_optional) | year_only
# Verbalizer
day = (
pynutil.delete("day:")
+ delete_space
+ pynutil.delete('"')
+ pynini.closure(DAMO_NOT_QUOTE, 1)
+ pynutil.delete('"')
)
month = (
pynutil.delete("month:")
+ delete_space
+ pynutil.delete('"')
+ pynini.closure(DAMO_NOT_QUOTE, 1)
+ pynutil.delete('"')
)
year = (
pynutil.delete("year:")
+ delete_space
+ pynutil.delete('"')
+ pynini.closure(DAMO_NOT_QUOTE, 1)
+ delete_space
+ pynutil.delete('"')
)
year_optional = pynini.closure(delete_extra_space + year, 0, 1)
graph_dmy = day + delete_extra_space + month + year_optional
verbalizer_graph = (graph_dmy | year) + delete_space
self.final_graph = pynini.compose(tagger_graph, verbalizer_graph).optimize()
self.fst = pynutil.insert('day: "') + self.final_graph + pynutil.insert('"')
self.fst = self.add_tokens(self.fst).optimize()
@@ -0,0 +1,114 @@
from collections import defaultdict
import pynini
from fun_text_processing.text_normalization.en.graph_utils import (
DAMO_DIGIT,
DAMO_SPACE,
GraphFst,
insert_space,
)
from fun_text_processing.text_normalization.en.utils import load_labels
from fun_text_processing.text_normalization.ru.utils import get_abs_path
from pynini.lib import pynutil
delete_space = pynutil.delete(" ")
def prepare_labels_for_insertion(file_path: str):
"""
Read the file and creates a union insertion graph
Args:
file_path: path to a file (3 columns: a label type e.g.
"@@decimal_delimiter@@", a label e.g. "целого", and a weight e.g. "0.1").
Returns dictionary mapping from label type to an fst that inserts the labels with the specified weights.
"""
labels = load_labels(file_path)
mapping = defaultdict(list)
for k, v, w in labels:
mapping[k].append((v, w))
for k in mapping:
mapping[k] = (
insert_space
+ pynini.union(
*[pynutil.add_weight(pynutil.insert(end), weight) for end, weight in mapping[k]]
)
).optimize()
return mapping
class DecimalFst(GraphFst):
"""
Finite state transducer for classifying decimal, e.g.
"1,08" -> tokens { decimal { integer_part: "одно целая" fractional_part: "восемь сотых} }
Args:
cardinal: CardinalFst
deterministic: if True will provide a single transduction option,
for False multiple transduction are generated (used for audio-based normalization)
"""
def __init__(self, cardinal: GraphFst, deterministic: bool = False):
super().__init__(name="decimal", kind="classify", deterministic=deterministic)
integer_part = cardinal.cardinal_numbers_default
cardinal_numbers_with_leading_zeros = cardinal.cardinal_numbers_with_leading_zeros
delimiter_map = prepare_labels_for_insertion(
get_abs_path("data/numbers/decimal_delimiter.tsv")
)
delimiter = (
pynini.cross(",", "")
+ delimiter_map["@@decimal_delimiter@@"]
+ pynini.closure(pynutil.add_weight(pynutil.insert(" и"), 0.5), 0, 1)
).optimize()
decimal_endings_map = prepare_labels_for_insertion(
get_abs_path("data/numbers/decimal_endings.tsv")
)
self.integer_part = integer_part + delimiter
graph_integer = pynutil.insert('integer_part: "') + self.integer_part + pynutil.insert('"')
graph_fractional = (
DAMO_DIGIT @ cardinal_numbers_with_leading_zeros + decimal_endings_map["10"]
)
graph_fractional |= (
DAMO_DIGIT + DAMO_DIGIT
) @ cardinal_numbers_with_leading_zeros + decimal_endings_map["100"]
graph_fractional |= (
DAMO_DIGIT + DAMO_DIGIT + DAMO_DIGIT
) @ cardinal_numbers_with_leading_zeros + decimal_endings_map["1000"]
graph_fractional |= (
DAMO_DIGIT + DAMO_DIGIT + DAMO_DIGIT + DAMO_DIGIT
) @ cardinal_numbers_with_leading_zeros + decimal_endings_map["10000"]
self.optional_quantity = pynini.string_file(
get_abs_path("data/numbers/quantity.tsv")
).optimize()
self.graph_fractional = graph_fractional
graph_fractional = (
pynutil.insert('fractional_part: "') + graph_fractional + pynutil.insert('"')
)
optional_quantity = pynini.closure(
(pynutil.add_weight(pynini.accep(DAMO_SPACE), -0.1) | insert_space)
+ pynutil.insert('quantity: "')
+ self.optional_quantity
+ pynutil.insert('"'),
0,
1,
)
self.final_graph = (
cardinal.optional_graph_negative
+ graph_integer
+ insert_space
+ graph_fractional
+ optional_quantity
)
self.final_graph = self.add_tokens(self.final_graph)
self.fst = self.final_graph.optimize()
@@ -0,0 +1,113 @@
import pynini
from fun_text_processing.text_normalization.en.graph_utils import (
DAMO_ALPHA,
DAMO_DIGIT,
DAMO_NOT_QUOTE,
GraphFst,
delete_space,
insert_space,
)
from fun_text_processing.text_normalization.ru.alphabet import RU_ALPHA, TO_CYRILLIC
from fun_text_processing.text_normalization.ru.utils import get_abs_path
from pynini.lib import pynutil
class ElectronicFst(GraphFst):
"""
Finite state transducer for classifying electronic: email addresses
e.g. "ab@nd.ru" -> electronic { username: "эй би собака эн ди точка ру" }
Args:
deterministic: if True will provide a single transduction option,
for False multiple transduction are generated (used for audio-based normalization)
"""
def __init__(self, deterministic: bool = True):
super().__init__(name="electronic", kind="classify", deterministic=deterministic)
# tagger
accepted_symbols = []
with open(get_abs_path("data/electronic/symbols.tsv"), "r", encoding="utf-8") as f:
for line in f:
symbol, _ = line.split("\t")
accepted_symbols.append(pynini.accep(symbol))
username = (
pynutil.insert('username: "')
+ DAMO_ALPHA
+ pynini.closure(DAMO_ALPHA | DAMO_DIGIT | pynini.union(*accepted_symbols))
+ pynutil.insert('"')
+ pynini.cross("@", " ")
)
domain_graph = (
DAMO_ALPHA
+ (pynini.closure(DAMO_ALPHA | DAMO_DIGIT | pynini.accep("-") | pynini.accep(".")))
+ (DAMO_ALPHA | DAMO_DIGIT)
)
domain_graph = pynutil.insert('domain: "') + domain_graph + pynutil.insert('"')
tagger_graph = (username + domain_graph).optimize()
# verbalizer
graph_digit = pynini.string_file(
get_abs_path("data/numbers/digits_nominative_case.tsv")
).optimize()
graph_symbols = pynini.string_file(get_abs_path("data/electronic/symbols.tsv")).optimize()
user_name = (
pynutil.delete("username:")
+ delete_space
+ pynutil.delete('"')
+ (
pynini.closure(
pynutil.add_weight(graph_digit + insert_space, 1.09)
| pynutil.add_weight(pynini.closure(graph_symbols + pynutil.insert(" ")), 1.09)
| pynutil.add_weight(DAMO_NOT_QUOTE + insert_space, 1.1)
)
)
+ pynutil.delete('"')
)
domain_default = (
pynini.closure(DAMO_NOT_QUOTE + insert_space)
+ pynini.cross(".", "точка ")
+ DAMO_NOT_QUOTE
+ pynini.closure(insert_space + DAMO_NOT_QUOTE)
)
server_default = (
pynini.closure((graph_digit | DAMO_ALPHA) + insert_space, 1)
+ pynini.closure(graph_symbols + insert_space)
+ pynini.closure((graph_digit | DAMO_ALPHA) + insert_space, 1)
)
server_common = (
pynini.string_file(get_abs_path("data/electronic/server_name.tsv")) + insert_space
)
domain_common = pynini.cross(".", "точка ") + pynini.string_file(
get_abs_path("data/electronic/domain.tsv")
)
domain = (
pynutil.delete("domain:")
+ delete_space
+ pynutil.delete('"')
+ (pynutil.add_weight(server_common, 1.09) | pynutil.add_weight(server_default, 1.1))
+ (pynutil.add_weight(domain_common, 1.09) | pynutil.add_weight(domain_default, 1.1))
+ delete_space
+ pynutil.delete('"')
)
graph = (
user_name
+ delete_space
+ pynutil.insert("собака ")
+ delete_space
+ domain
+ delete_space
)
# replace all latin letters with their Ru verbalization
verbalizer_graph = (
graph.optimize() @ (pynini.closure(TO_CYRILLIC | RU_ALPHA | pynini.accep(" ")))
).optimize()
verbalizer_graph = verbalizer_graph.optimize()
self.final_graph = (tagger_graph @ verbalizer_graph).optimize()
self.fst = self.add_tokens(
pynutil.insert('username: "') + self.final_graph + pynutil.insert('"')
).optimize()
@@ -0,0 +1,183 @@
import pynini
from fun_text_processing.text_normalization.en.graph_utils import (
DAMO_NON_BREAKING_SPACE,
DAMO_NOT_QUOTE,
DAMO_SPACE,
GraphFst,
insert_space,
)
from fun_text_processing.text_normalization.ru.alphabet import RU_ALPHA
from fun_text_processing.text_normalization.ru.utils import get_abs_path
from pynini.lib import pynutil
class MeasureFst(GraphFst):
"""
Finite state transducer for classifying measure, e.g.
"2 кг" -> measure { cardinal { integer: "два килограма" } }
This class also converts words containing numbers and letters
e.g. "тест-8" —> "тест восемь"
e.g. "тест-1,02" —> "тест одна целая две сотых"
Args:
cardinal: CardinalFst
decimal: DecimalFst
deterministic: if True will provide a single transduction option,
for False multiple transduction are generated (used for audio-based normalization)
"""
def __init__(self, cardinal: GraphFst, decimal: GraphFst, deterministic: bool = True):
super().__init__(name="measure", kind="classify", deterministic=deterministic)
# adding weight to make sure the space is preserved for ITN
delete_space = pynini.closure(
pynutil.add_weight(
pynutil.delete(pynini.union(DAMO_SPACE, DAMO_NON_BREAKING_SPACE)), -1
),
0,
1,
)
cardinal_graph = cardinal.cardinal_numbers_default
cardinal_graph_nominative = cardinal.cardinal_numbers_nominative
graph_unit = pynini.string_file(get_abs_path("data/measurements.tsv"))
optional_graph_negative = cardinal.optional_graph_negative
space_for_units = (
pynutil.add_weight(pynutil.insert(DAMO_NON_BREAKING_SPACE), -0.1)
| pynutil.add_weight(pynutil.insert(DAMO_SPACE), 0.1)
).optimize()
slash_unit = (
(pynini.cross("/", "в") | pynini.cross("/", "за")) + space_for_units + graph_unit
)
unit_slash_unit = pynutil.add_weight(graph_unit + space_for_units + slash_unit, -0.1)
default_units = (
pynutil.insert('units: "') + (graph_unit | unit_slash_unit) + pynutil.insert('"')
)
slash_units = pynutil.insert('units: "') + slash_unit + pynutil.insert('"')
subgraph_decimal = decimal.final_graph + ((delete_space + default_units) | slash_units)
cardinal_space = (
pynutil.insert("cardinal { ")
+ optional_graph_negative
+ pynutil.insert('integer: "')
+ cardinal_graph
+ (
(delete_space + pynutil.insert('"') + pynutil.insert(" } ") + default_units)
| (pynutil.insert('"') + pynutil.insert(" } ") + slash_units)
)
)
cardinal_optional_dash_alpha = (
pynutil.insert('cardinal { integer: "')
+ cardinal_graph
+ pynini.closure(pynini.cross("-", ""), 0, 1)
+ pynutil.insert('" } units: "')
+ pynini.closure(RU_ALPHA, 1)
+ pynutil.insert('"')
)
alpha_optional_dash_cardinal = (
pynutil.insert('units: "')
+ pynini.closure(RU_ALPHA, 1)
+ pynini.closure(pynini.cross("-", ""), 0, 1)
+ pynutil.insert('"')
+ pynutil.insert(' cardinal { integer: "')
+ cardinal_graph_nominative
+ pynutil.insert('" } preserve_order: true')
)
decimal_dash_alpha = (
decimal.final_graph
+ pynini.cross("-", "")
+ pynutil.insert(' units: "')
+ pynini.closure(RU_ALPHA, 1)
+ pynutil.insert('"')
)
alpha_dash_decimal = (
pynutil.insert('units: "')
+ pynini.closure(RU_ALPHA, 1)
+ pynini.cross("-", "")
+ pynutil.insert('" ')
+ decimal.final_graph
+ pynutil.insert(" preserve_order: true")
)
self.tagger_graph_default = (subgraph_decimal | cardinal_space).optimize()
tagger_graph = (
self.tagger_graph_default
| cardinal_optional_dash_alpha
| alpha_optional_dash_cardinal
| decimal_dash_alpha
| alpha_dash_decimal
).optimize()
# verbalizer
unit = (
pynutil.delete('units: "')
+ pynini.closure(DAMO_NOT_QUOTE, 1)
+ pynutil.delete('"')
+ delete_space
)
optional_sign = pynini.closure(pynini.cross('negative: "true" ', "минус "), 0, 1)
integer = pynutil.delete(' "') + pynini.closure(DAMO_NOT_QUOTE, 1) + pynutil.delete('"')
integer_part = pynutil.delete("integer_part:") + integer
fractional_part = pynutil.delete("fractional_part:") + integer
optional_quantity_part = pynini.closure(
pynini.accep(" ")
+ pynutil.delete('quantity: "')
+ pynini.closure(DAMO_NOT_QUOTE, 1)
+ pynutil.delete('"'),
0,
1,
)
graph_decimal = (
optional_sign
+ integer_part
+ pynini.accep(" ")
+ fractional_part
+ optional_quantity_part
)
graph_decimal = (
pynutil.delete("decimal {")
+ delete_space
+ graph_decimal
+ delete_space
+ pynutil.delete("}")
)
graph_cardinal = (
pynutil.delete("cardinal {")
+ delete_space
+ optional_sign
+ pynutil.delete('integer: "')
+ pynini.closure(DAMO_NOT_QUOTE, 1)
+ pynutil.delete('"')
+ delete_space
+ pynutil.delete("}")
)
verbalizer_graph = (graph_cardinal | graph_decimal) + delete_space + insert_space + unit
# SH adds "preserve_order: true" by default
preserve_order = (
pynutil.delete("preserve_order:") + delete_space + pynutil.delete("true") + delete_space
)
verbalizer_graph |= (
unit
+ insert_space
+ (graph_cardinal | graph_decimal)
+ delete_space
+ pynini.closure(preserve_order, 0, 1)
)
self.verbalizer_graph = verbalizer_graph.optimize()
final_graph = (tagger_graph @ verbalizer_graph).optimize()
self.fst = self.add_tokens(
pynutil.insert('cardinal { integer: "') + final_graph + pynutil.insert('" }')
).optimize()
@@ -0,0 +1,97 @@
import pynini
from fun_text_processing.text_normalization.en.graph_utils import (
DAMO_NOT_QUOTE,
DAMO_SIGMA,
DAMO_SPACE,
GraphFst,
)
from fun_text_processing.text_normalization.ru.utils import get_abs_path
from pynini.lib import pynutil
class MoneyFst(GraphFst):
"""
Finite state transducer for classifying money, e.g.
"5руб." -> money { "пять рублей" }
Args:
cardinal: CardinalFst
decimal: DecimalFst
deterministic: if True will provide a single transduction option,
for False multiple transduction are generated (used for audio-based normalization)
"""
def __init__(self, cardinal: GraphFst, decimal: GraphFst, deterministic: bool = True):
super().__init__(name="money", kind="classify", deterministic=deterministic)
cardinal_graph = cardinal.cardinal_numbers_default
decimal_graph = decimal.final_graph
unit_singular = pynini.string_file(get_abs_path("data/currency/currency_singular.tsv"))
unit_plural = pynini.string_file(get_abs_path("data/currency/currency_plural.tsv"))
# adding weight to make sure the space is preserved for ITN
optional_delimiter = pynini.closure(
pynutil.add_weight(pynini.cross(DAMO_SPACE, ""), -100), 0, 1
)
graph_unit_singular = (
optional_delimiter
+ pynutil.insert(' currency: "')
+ unit_singular
+ pynutil.insert('"')
)
graph_unit_plural = (
optional_delimiter + pynutil.insert(' currency: "') + unit_plural + pynutil.insert('"')
)
one = pynini.compose(pynini.accep("1"), cardinal_graph).optimize()
singular_graph = (
pynutil.insert('integer_part: "') + one + pynutil.insert('"') + graph_unit_singular
)
graph_decimal = decimal_graph + graph_unit_plural
graph_integer = (
pynutil.insert('integer_part: "')
+ ((DAMO_SIGMA - "1") @ cardinal_graph)
+ pynutil.insert('"')
+ (graph_unit_plural)
)
graph_integer |= singular_graph
tagger_graph = (graph_integer.optimize() | graph_decimal.optimize()).optimize()
# verbalizer
integer = pynutil.delete('"') + pynini.closure(DAMO_NOT_QUOTE, 1) + pynutil.delete('"')
integer_part = pynutil.delete("integer_part: ") + integer
unit = (
pynutil.delete("currency: ")
+ pynutil.delete('"')
+ pynini.closure(DAMO_NOT_QUOTE, 1)
+ pynutil.delete('"')
)
unit = pynini.accep(DAMO_SPACE) + unit
verbalizer_graph_cardinal = (integer_part + unit).optimize()
fractional_part = pynutil.delete("fractional_part: ") + integer
optional_quantity = pynini.closure(
pynini.accep(DAMO_SPACE) + pynutil.delete("quantity: ") + integer, 0, 1
)
verbalizer_graph_decimal = (
pynutil.delete("decimal { ")
+ integer_part
+ pynini.accep(" ")
+ fractional_part
+ optional_quantity
+ pynutil.delete(" }")
+ unit
)
verbalizer_graph = (verbalizer_graph_cardinal | verbalizer_graph_decimal).optimize()
self.final_graph = (tagger_graph @ verbalizer_graph).optimize()
self.fst = self.add_tokens(
pynutil.insert('integer_part: "') + self.final_graph + pynutil.insert('"')
).optimize()
@@ -0,0 +1,138 @@
# Copyright 2017 Google Inc.
# Adapted from https://github.com/google/TextNormalizationCoveringGrammars
# Russian minimally supervised number grammar.
#
# Supports cardinals and ordinals in all inflected forms.
#
# The language-specific acceptor G was compiled with digit, teen, decade,
# century, and big power-of-ten preterminals. The lexicon transducer is
# highly ambiguous, but no LM is used.
# Intersects the universal factorization transducer (F) with language-specific
# acceptor (G).
import pynini
from fun_text_processing.text_normalization.en.graph_utils import DAMO_SIGMA
from fun_text_processing.text_normalization.ru.utils import get_abs_path, load_labels
from pynini.lib import pynutil, rewrite
def get_number_names():
"""
Creates numbers names.
Based on: 1) Gorman, K., and Sproat, R. 2016. Minimally supervised number normalization.
Transactions of the Association for Computational Linguistics 4: 507-519.
and 2) Ng, A. H., Gorman, K., and Sproat, R. 2017.
Minimally supervised written-to-spoken text normalization. In ASRU, pages 665-670.
"""
a = pynini.Far(get_abs_path("data/utils/util_arithmetic.far"), mode="r")
d = a["DELTA_STAR"]
f = a["IARITHMETIC_RESTRICTED"]
g = pynini.Fst.read(get_abs_path("data/utils/g.fst"))
fg = (d @ (f @ (f @ (f @ g).optimize()).optimize()).optimize()).optimize()
assert rewrite.top_rewrite("230", fg) == "(+ 200 30 +)"
# Compiles lexicon transducers (L).
cardinal_name_nominative = pynini.string_file(
get_abs_path("data/numbers/1_cardinals_nominative.tsv")
).optimize()
cardinal_name_genitive = pynini.string_file(
get_abs_path("data/numbers/2_cardinals_genitive.tsv")
).optimize()
cardinal_name_dative = pynini.string_file(
get_abs_path("data/numbers/3_cardinals_dative.tsv")
).optimize()
cardinal_name_accusative = pynini.string_file(
get_abs_path("data/numbers/4_cardinals_accusative.tsv")
).optimize()
cardinal_name_instrumental = pynini.string_file(
get_abs_path("data/numbers/5_cardinals_instrumental.tsv")
).optimize()
cardinal_name_prepositional = pynini.string_file(
get_abs_path("data/numbers/6_cardinals_prepositional.tsv")
).optimize()
cardinal_name_nominative = (
pynini.closure(cardinal_name_nominative + pynini.accep(" ")) + cardinal_name_nominative
).optimize()
cardinal_l = pynutil.add_weight(cardinal_name_nominative, -0.1)
for case in [
pynutil.add_weight(cardinal_name_genitive, 0.1).optimize(),
pynutil.add_weight(cardinal_name_dative, 0.1).optimize(),
pynutil.add_weight(cardinal_name_accusative, 0.1).optimize(),
pynutil.add_weight(cardinal_name_instrumental, 0.1).optimize(),
pynutil.add_weight(cardinal_name_prepositional, 0.1).optimize(),
]:
cardinal_l |= (pynini.closure(case + pynini.accep(" ")) + case).optimize()
# Numbers in nominative case (to use, for example, with telephone or serial_graph (in cardinals))
cardinal_names_nominative_l = (
pynini.closure(cardinal_name_nominative + pynini.accep(" ")) + cardinal_name_nominative
).optimize()
# Convert e.g. "(* 5 1000 *)" back to "5000" so complex ordinals will be formed correctly,
# e.g. "пятитысячный" will eventually be formed. (If we didn't do this, the incorrect phrase
# "пять тысячный" would be formed).
# We do this for all thousands from "(*2 1000 *)" —> "2000" to "(*20 1000 *)" —> "20000".
# We do not go higher, in order to prevent the WFST graph becoming even larger.
complex_numbers = pynini.cross("(* 2 1000 *)", "2000")
for number in range(3, 21):
complex_numbers |= pynini.cross(f"(* {number} 1000 *)", f"{number}000")
complex_numbers = (
DAMO_SIGMA
+ pynutil.add_weight(complex_numbers, -1)
+ pynini.closure(pynini.union(" ", ")", "(", "+", "*"))
).optimize()
fg_ordinal = pynutil.add_weight(pynini.compose(fg, complex_numbers), -1) | fg
ordinal_name = pynini.string_file(get_abs_path("data/numbers/ordinals.tsv"))
ordinal_l = (
pynini.closure(cardinal_name_nominative + pynini.accep(" ")) + ordinal_name
).optimize()
# Composes L with the leaf transducer (P), then composes that with FG.
p = a["LEAVES"]
number_names = {}
number_names["ordinal_number_names"] = (fg_ordinal @ (p @ ordinal_l)).optimize()
number_names["cardinal_number_names"] = (fg @ (p @ cardinal_l)).optimize()
number_names["cardinal_names_nominative"] = (fg @ (p @ cardinal_names_nominative_l)).optimize()
return number_names
def get_alternative_formats():
"""
Utils to get alternative formats for numbers.
"""
one_alternatives = load_labels(get_abs_path("data/numbers/cardinals_alternatives.tsv"))
one_thousand_map = []
for k in one_alternatives:
default, alternative = k
one_thousand_map.append((alternative.split()[1], alternative))
one_thousand_map = pynini.string_map(one_thousand_map)
one_thousand_alternative = pynini.cdrewrite(one_thousand_map, "[BOS]", "", DAMO_SIGMA)
# Adapted from
# https://github.com/google/TextNormalizationCoveringGrammars/blob/master/src/universal/thousands_punct.grm
# Specifies common ways of delimiting thousands in digit strings.
t = pynini.Far(get_abs_path("data/utils/universal_thousands_punct.far"))
separators = (
pynutil.add_weight(t["dot_thousands"], 0.1)
| pynutil.add_weight(t["no_delimiter"], -0.1)
| pynutil.add_weight(t["space_thousands"], 0.1)
)
alternative_formats = {}
alternative_formats["one_thousand_alternative"] = one_thousand_alternative.optimize()
alternative_formats["separators"] = separators.optimize()
return alternative_formats
if __name__ == "__main__":
from fun_text_processing.text_normalization.en.graph_utils import generator_main
numbers = get_number_names()
for k, v in numbers.items():
generator_main(f"{k}.far", {k: v})
@@ -0,0 +1,52 @@
# Adapted from https://github.com/google/TextNormalizationCoveringGrammars
# Russian minimally supervised number grammar.
import pynini
from fun_text_processing.text_normalization.en.graph_utils import DAMO_SIGMA, GraphFst
from fun_text_processing.text_normalization.ru.utils import get_abs_path
from pynini.lib import pynutil
class OrdinalFst(GraphFst):
"""
Finite state transducer for classifying cardinals, e.g.
"2" -> ordinal { integer: "второе" } }
Args:
number_names: number_names for cardinal and ordinal numbers
alternative_formats: alternative format for cardinal and ordinal numbers
deterministic: if True will provide a single transduction option,
for False multiple transduction are generated (used for audio-based normalization)
"""
def __init__(self, number_names: dict, alternative_formats: dict, deterministic=False):
super().__init__(name="ordinal", kind="classify", deterministic=deterministic)
one_thousand_alternative = alternative_formats["one_thousand_alternative"]
separators = alternative_formats["separators"]
ordinal = number_names["ordinal_number_names"]
ordinal |= ordinal @ one_thousand_alternative
ordinal_numbers = separators @ ordinal
# to handle cases like 2-ая
endings = pynini.string_file(get_abs_path("data/numbers/ordinal_endings.tsv"))
not_dash = pynini.closure(pynini.difference(DAMO_SIGMA, "-"))
del_ending = pynini.cdrewrite(pynini.cross("-" + not_dash, ""), "", "[EOS]", DAMO_SIGMA)
ordinal_numbers_marked = (
((separators @ ordinal).optimize() + pynini.accep("-") + not_dash).optimize()
@ (DAMO_SIGMA + endings).optimize()
@ del_ending
).optimize()
self.ordinal_numbers = ordinal_numbers
# "03" -> remove leading zeros and verbalize
leading_zeros = pynini.closure(pynini.cross("0", ""))
self.ordinal_numbers_with_leading_zeros = (leading_zeros + ordinal_numbers).optimize()
final_graph = (ordinal_numbers | ordinal_numbers_marked).optimize()
final_graph = pynutil.insert('integer: "') + final_graph + pynutil.insert('"')
final_graph = self.add_tokens(final_graph)
self.fst = final_graph.optimize()
@@ -0,0 +1,71 @@
import pynini
from fun_text_processing.text_normalization.en.graph_utils import (
DAMO_DIGIT,
GraphFst,
delete_space,
insert_space,
)
from fun_text_processing.text_normalization.ru.alphabet import RU_ALPHA_OR_SPACE
from pynini.lib import pynutil
class TelephoneFst(GraphFst):
"""
Finite state transducer for classifying telephone, which includes country code, number part and extension
E.g
"8-913-983-56-01" -> telephone { number_part: "восемь девятьсот тринадцать девятьсот восемьдесят три пятьдесят шесть ноль один" }
Args:
number_names: number_names for cardinal and ordinal numbers
deterministic: if True will provide a single transduction option,
for False multiple transduction are generated (used for audio-based normalization)
"""
def __init__(self, number_names: dict, deterministic: bool = True):
super().__init__(name="telephone", kind="classify", deterministic=deterministic)
separator = pynini.cross("-", " ") # between components
number = number_names["cardinal_names_nominative"]
country_code = (
pynutil.insert('country_code: "')
+ pynini.closure(pynutil.add_weight(pynutil.delete("+"), 0.1), 0, 1)
+ number
+ separator
+ pynutil.insert('"')
)
optional_country_code = pynini.closure(country_code + insert_space, 0, 1)
number_part = (
DAMO_DIGIT**3 @ number
+ separator
+ DAMO_DIGIT**3 @ number
+ separator
+ DAMO_DIGIT**2 @ number
+ separator
+ DAMO_DIGIT**2 @ (pynini.closure(pynini.cross("0", "ноль ")) + number)
)
number_part = pynutil.insert('number_part: "') + number_part + pynutil.insert('"')
tagger_graph = (optional_country_code + number_part).optimize()
# verbalizer
verbalizer_graph = pynini.closure(
pynutil.delete('country_code: "')
+ pynini.closure(RU_ALPHA_OR_SPACE, 1)
+ pynutil.delete('"')
+ delete_space,
0,
1,
)
verbalizer_graph += (
pynutil.delete('number_part: "')
+ pynini.closure(RU_ALPHA_OR_SPACE, 1)
+ pynutil.delete('"')
)
verbalizer_graph = verbalizer_graph.optimize()
self.final_graph = (tagger_graph @ verbalizer_graph).optimize()
self.fst = self.add_tokens(
pynutil.insert('number_part: "') + self.final_graph + pynutil.insert('"')
).optimize()
@@ -0,0 +1,115 @@
import pynini
from fun_text_processing.text_normalization.en.graph_utils import GraphFst
from fun_text_processing.text_normalization.ru.utils import get_abs_path
from pynini.lib import pynutil
class TimeFst(GraphFst):
"""
Finite state transducer for classifying time, e.g.
"02:15" -> time { hours: "два часа пятнадцать минут" }
Args:
number_names: number_names for cardinal and ordinal numbers
deterministic: if True will provide a single transduction option,
for False multiple transduction are generated (used for audio-based normalization)
"""
def __init__(self, number_names: dict, deterministic: bool = True):
super().__init__(name="time", kind="classify", deterministic=deterministic)
increment_hour_ordinal = pynini.string_file(
get_abs_path("data/time/increment_hour_ordinal.tsv")
)
increment_hour_cardinal = pynini.string_file(
get_abs_path("data/time/increment_hour_cardinal.tsv")
)
convert_hour = pynini.string_file(get_abs_path("data/time/time_convert.tsv"))
number = (
pynini.closure(pynini.cross("0", ""), 0, 1) + number_names["cardinal_names_nominative"]
)
hour_options = pynini.project(increment_hour_ordinal, "input")
hour_options = hour_options | pynini.project(convert_hour, "output")
hour_exeption_ends_with_one = pynini.union(*["01", "21"])
hour_exeption_ends_rest = pynini.union(*["02", "03", "04", "22", "23"])
hour_other = (
pynini.difference(
hour_options, pynini.union(hour_exeption_ends_with_one, hour_exeption_ends_rest)
)
).optimize()
hour = hour_exeption_ends_with_one @ number + pynutil.insert(" час")
hour |= hour_exeption_ends_rest @ number + pynutil.insert(" часа")
hour |= hour_other @ number + pynutil.insert(" часов")
optional_and = pynini.closure(pynutil.insert("и "), 0, 1)
digits = pynini.union(*[str(x) for x in range(10)])
mins_start = pynini.union(*"012345")
mins_options = mins_start + digits
mins_exception_ends_with_one = mins_start + pynini.accep("1")
mins_exception_ends_rest = pynini.difference(
mins_start + pynini.union(*"234"), pynini.union(*["12", "13", "14"])
)
mins_other = pynini.difference(
mins_options, pynini.union(mins_exception_ends_with_one, mins_exception_ends_rest)
)
minutes = mins_exception_ends_with_one @ number + pynutil.insert(" минута")
minutes |= mins_exception_ends_rest @ number + pynutil.insert(" минуты")
minutes |= mins_other @ number + pynutil.insert(" минут")
self.minutes = minutes.optimize()
# 17:15 -> "семнадцать часов и пятнадцать минут"
hm = (
pynutil.insert('hours: "')
+ hour.optimize()
+ pynutil.insert('"')
+ (
pynini.cross(":", " ")
+ pynutil.insert('minutes: "')
+ optional_and
+ minutes.optimize()
)
+ pynutil.insert('"')
+ pynutil.insert(" preserve_order: true")
)
h = pynutil.insert('hours: "') + hour + pynutil.insert('"') + pynutil.delete(":00")
self.graph_preserve_order = (hm | h).optimize()
# 17:15 -> "пятнадцать минут шестого"
# Requires permutations for the correct verbalization
self.increment_hour_ordinal = pynini.compose(
hour_options, increment_hour_ordinal
).optimize()
m_next_h = (
pynutil.insert('hours: "')
+ self.increment_hour_ordinal
+ pynutil.insert('"')
+ pynini.cross(":", " ")
+ pynutil.insert('minutes: "')
+ minutes
+ pynutil.insert('"')
)
# 17:45 -> "без пятнадцати минут шесть"
# Requires permutations for the correct verbalization
self.mins_to_h = pynini.string_file(
get_abs_path("data/time/minutes_to_hour.tsv")
).optimize()
self.increment_hour_cardinal = pynini.compose(
hour_options, increment_hour_cardinal
).optimize()
m_to_h = (
pynutil.insert('hours: "')
+ self.increment_hour_cardinal
+ pynutil.insert('"')
+ pynini.cross(":", " ")
+ pynutil.insert('minutes: "без ')
+ self.mins_to_h
+ pynutil.insert('"')
)
self.final_graph = m_next_h | self.graph_preserve_order | m_to_h
self.fst = self.add_tokens(self.final_graph)
self.fst = self.fst.optimize()
@@ -0,0 +1,149 @@
import os
import pynini
from fun_text_processing.text_normalization.en.graph_utils import (
GraphFst,
delete_extra_space,
delete_space,
generator_main,
)
from fun_text_processing.text_normalization.en.taggers.punctuation import PunctuationFst
from fun_text_processing.text_normalization.ru.taggers.cardinal import CardinalFst
from fun_text_processing.text_normalization.ru.taggers.date import DateFst
from fun_text_processing.text_normalization.ru.taggers.decimals import DecimalFst
from fun_text_processing.text_normalization.ru.taggers.electronic import ElectronicFst
from fun_text_processing.text_normalization.ru.taggers.measure import MeasureFst
from fun_text_processing.text_normalization.ru.taggers.money import MoneyFst
from fun_text_processing.text_normalization.ru.taggers.number_names import (
get_alternative_formats,
get_number_names,
)
from fun_text_processing.text_normalization.ru.taggers.ordinal import OrdinalFst
from fun_text_processing.text_normalization.ru.taggers.telephone import TelephoneFst
from fun_text_processing.text_normalization.ru.taggers.time import TimeFst
from fun_text_processing.text_normalization.ru.taggers.whitelist import WhiteListFst
from fun_text_processing.text_normalization.ru.taggers.word import WordFst
from pynini.lib import pynutil
import logging
class ClassifyFst(GraphFst):
"""
Final class that composes all other classification grammars. This class can process an entire sentence, that is lower cased.
For deployment, this grammar will be compiled and exported to OpenFst Finite State Archive (FAR) File.
More details to deployment at NeMo/tools/text_processing_deployment.
Args:
input_case: accepting either "lower_cased" or "cased" input.
deterministic: if True will provide a single transduction option,
for False multiple options (used for audio-based normalization)
cache_dir: path to a dir with .far grammar file. Set to None to avoid using cache.
overwrite_cache: set to True to overwrite .far files
whitelist: path to a file with whitelist replacements
"""
def __init__(
self,
input_case: str,
deterministic: bool = False,
cache_dir: str = None,
overwrite_cache: bool = False,
whitelist: str = None,
):
super().__init__(name="tokenize_and_classify", kind="classify", deterministic=deterministic)
if deterministic:
raise ValueError(
"Ru TN only supports non-deterministic cases and produces multiple normalization options."
)
far_file = None
if cache_dir is not None and cache_dir != "None":
os.makedirs(cache_dir, exist_ok=True)
whitelist_file = os.path.basename(whitelist) if whitelist else ""
far_file = os.path.join(
cache_dir, f"_{input_case}_ru_tn_{deterministic}_deterministic{whitelist_file}.far"
)
if not overwrite_cache and far_file and os.path.exists(far_file):
self.fst = pynini.Far(far_file, mode="r")["tokenize_and_classify"]
logging.info(f"ClassifyFst.fst was restored from {far_file}.")
else:
logging.info(f"Creating ClassifyFst grammars. This might take some time...")
number_names = get_number_names()
alternative_formats = get_alternative_formats()
self.cardinal = CardinalFst(
number_names=number_names,
alternative_formats=alternative_formats,
deterministic=deterministic,
)
cardinal_graph = self.cardinal.fst
self.ordinal = OrdinalFst(
number_names=number_names,
alternative_formats=alternative_formats,
deterministic=deterministic,
)
ordinal_graph = self.ordinal.fst
self.decimal = DecimalFst(cardinal=self.cardinal, deterministic=deterministic)
decimal_graph = self.decimal.fst
self.measure = MeasureFst(
cardinal=self.cardinal, decimal=self.decimal, deterministic=deterministic
)
measure_graph = self.measure.fst
self.date = DateFst(number_names=number_names, deterministic=deterministic)
date_graph = self.date.fst
word_graph = WordFst(deterministic=deterministic).fst
self.time = TimeFst(number_names=number_names, deterministic=deterministic)
time_graph = self.time.fst
self.telephone = TelephoneFst(number_names=number_names, deterministic=deterministic)
telephone_graph = self.telephone.fst
self.electronic = ElectronicFst(deterministic=deterministic)
electronic_graph = self.electronic.fst
self.money = MoneyFst(
cardinal=self.cardinal, decimal=self.decimal, deterministic=deterministic
)
money_graph = self.money.fst
self.whitelist = WhiteListFst(
input_case=input_case, deterministic=deterministic, input_file=whitelist
)
whitelist_graph = self.whitelist.fst
punct_graph = PunctuationFst(deterministic=deterministic).fst
classify = (
pynutil.add_weight(whitelist_graph, 1.01)
| pynutil.add_weight(time_graph, 1.1)
| pynutil.add_weight(date_graph, 1.09)
| pynutil.add_weight(decimal_graph, 1.1)
| pynutil.add_weight(measure_graph, 0.9)
| pynutil.add_weight(cardinal_graph, 1.1)
| pynutil.add_weight(ordinal_graph, 1.1)
| pynutil.add_weight(money_graph, 1.1)
| pynutil.add_weight(telephone_graph, 1.1)
| pynutil.add_weight(electronic_graph, 1.1)
| pynutil.add_weight(word_graph, 100)
)
punct = (
pynutil.insert("tokens { ")
+ pynutil.add_weight(punct_graph, weight=1.1)
+ pynutil.insert(" }")
)
token = pynutil.insert("tokens { ") + classify + pynutil.insert(" }")
token_plus_punct = (
pynini.closure(punct + pynutil.insert(" "))
+ token
+ pynini.closure(pynutil.insert(" ") + punct)
)
graph = token_plus_punct + pynini.closure(
pynutil.add_weight(delete_extra_space, 1.1) + token_plus_punct
)
graph = delete_space + graph + delete_space
self.fst = graph.optimize()
if far_file:
generator_main(far_file, {"tokenize_and_classify": self.fst})
logging.info(f"ClassifyFst grammars are saved to {far_file}.")
@@ -0,0 +1,51 @@
import pynini
from fun_text_processing.text_normalization.en.graph_utils import DAMO_CHAR, GraphFst, convert_space
from fun_text_processing.text_normalization.ru.alphabet import RU_ALPHA, TO_CYRILLIC
from fun_text_processing.text_normalization.ru.utils import get_abs_path, load_labels
from pynini.lib import pynutil
class WhiteListFst(GraphFst):
"""
Finite state transducer for classifying whitelist, e.g.
misses -> tokens { name: "mrs" }
for non-deterministic case: "Dr. Abc" ->
tokens { name: "drive" } tokens { name: "Abc" }
tokens { name: "doctor" } tokens { name: "Abc" }
tokens { name: "Dr." } tokens { name: "Abc" }
This class has highest priority among all classifier grammars. Whitelisted tokens are defined and loaded from "data/whitelist.tsv".
Args:
input_case: accepting either "lower_cased" or "cased" input.
deterministic: if True will provide a single transduction option,
for False multiple options (used for audio-based normalization)
input_file: path to a file with whitelist replacements
"""
def __init__(self, input_case: str, deterministic: bool = True, input_file: str = None):
super().__init__(name="whitelist", kind="classify", deterministic=deterministic)
def _get_whitelist_graph(input_case, file):
whitelist = load_labels(file)
if input_case == "lower_cased":
whitelist = [[x[0].lower()] + x[1:] for x in whitelist]
else:
whitelist = [[x[0].lower()] + x[1:] for x in whitelist]
graph = pynini.string_map(whitelist)
return graph
graph = _get_whitelist_graph(input_case, get_abs_path("data/whitelist.tsv"))
if input_file:
graph = _get_whitelist_graph(input_case, input_file)
units_graph = _get_whitelist_graph(input_case, file=get_abs_path("data/measurements.tsv"))
# do not replace single letter units, like `м`, `°` and `%` will be replaced
units_graph = pynini.compose(
(DAMO_CHAR ** (2, ...) | pynini.difference(DAMO_CHAR, RU_ALPHA)), units_graph
)
graph |= units_graph.optimize()
graph |= TO_CYRILLIC + pynini.closure(pynutil.insert(" ") + TO_CYRILLIC)
self.final_graph = convert_space(graph)
self.fst = (pynutil.insert('name: "') + self.final_graph + pynutil.insert('"')).optimize()
@@ -0,0 +1,19 @@
import pynini
from fun_text_processing.text_normalization.en.graph_utils import DAMO_NOT_SPACE, GraphFst
from pynini.lib import pynutil
class WordFst(GraphFst):
"""
Finite state transducer for classifying word.
e.g. sleep -> tokens { name: "sleep" }
Args:
deterministic: if True will provide a single transduction option,
for False multiple transduction are generated (used for audio-based normalization)
"""
def __init__(self, deterministic: bool = True):
super().__init__(name="word", kind="classify")
word = pynutil.insert('name: "') + pynini.closure(DAMO_NOT_SPACE, 1) + pynutil.insert('"')
self.fst = word.optimize()
@@ -0,0 +1,34 @@
import csv
import os
import logging
def get_abs_path(rel_path):
"""
Get absolute path
Args:
rel_path: relative path to this file
Returns absolute path
"""
abs_path = os.path.dirname(os.path.abspath(__file__)) + os.sep + rel_path
if not os.path.exists(abs_path):
logging.warning(f"{abs_path} does not exist")
return abs_path
def load_labels(abs_path):
"""
loads relative path file as dictionary
Args:
abs_path: absolute path
Returns dictionary of mappings
"""
label_tsv = open(abs_path, encoding="utf-8")
labels = list(csv.reader(label_tsv, delimiter="\t"))
return labels
@@ -0,0 +1,32 @@
import pynini
from fun_text_processing.text_normalization.en.graph_utils import DAMO_NOT_QUOTE, GraphFst
from pynini.lib import pynutil
class CardinalFst(GraphFst):
"""
Finite state transducer for verbalizing cardinals
e.g. cardinal { integer: "тысяча один" } -> "тысяча один"
Args:
deterministic: if True will provide a single transduction option,
for False multiple transduction are generated (used for audio-based normalization)
"""
def __init__(self, deterministic: bool = True):
super().__init__(name="cardinal", kind="verbalize", deterministic=deterministic)
optional_sign = pynini.closure(pynini.cross('negative: "true" ', "минус "), 0, 1)
optional_quantity_part = pynini.closure(
pynini.accep(" ")
+ pynutil.delete('quantity: "')
+ pynini.closure(DAMO_NOT_QUOTE, 1)
+ pynutil.delete('"'),
0,
1,
)
integer = (
pynutil.delete('integer: "') + pynini.closure(DAMO_NOT_QUOTE, 1) + pynutil.delete('"')
)
self.graph = optional_sign + integer + optional_quantity_part
delete_tokens = self.delete_tokens(self.graph)
self.fst = delete_tokens.optimize()
@@ -0,0 +1,22 @@
import pynini
from fun_text_processing.text_normalization.en.graph_utils import GraphFst
from fun_text_processing.text_normalization.ru.alphabet import RU_ALPHA
from pynini.lib import pynutil
class DateFst(GraphFst):
"""
Finite state transducer for verbalizing date, e.g.
tokens { date { day: "первое мая" } } -> "первое мая"
Args:
deterministic: if True will provide a single transduction option,
for False multiple transduction are generated (used for audio-based normalization)
"""
def __init__(self, deterministic: bool = True):
super().__init__(name="date", kind="verbalize", deterministic=deterministic)
graph = pynutil.delete('day: "') + pynini.closure(RU_ALPHA | " ", 1) + pynutil.delete('"')
delete_tokens = self.delete_tokens(graph)
self.fst = delete_tokens.optimize()
@@ -0,0 +1,46 @@
import pynini
from fun_text_processing.text_normalization.en.graph_utils import (
DAMO_NOT_QUOTE,
GraphFst,
delete_space,
)
from pynini.lib import pynutil
class DecimalFst(GraphFst):
"""
Finite state transducer for verbalizing decimal, e.g.
tokens { decimal { integer_part: "одно целая" fractional_part: "восемь сотых} } ->
"одно целая восемь сотых"
Args:
deterministic: if True will provide a single transduction option,
for False multiple transduction are generated (used for audio-based normalization)
"""
def __init__(self, deterministic: bool = True):
super().__init__(name="decimal", kind="verbalize", deterministic=deterministic)
optional_sign = pynini.closure(pynini.cross('negative: "true" ', "минус "), 0, 1)
integer = pynutil.delete(' "') + pynini.closure(DAMO_NOT_QUOTE, 1) + pynutil.delete('"')
integer_part = pynutil.delete("integer_part:") + integer
fractional_part = pynutil.delete("fractional_part:") + integer
optional_quantity_part = pynini.closure(
pynini.accep(" ")
+ pynutil.delete('quantity: "')
+ pynini.closure(DAMO_NOT_QUOTE, 1)
+ pynutil.delete('"'),
0,
1,
)
self.graph = (
optional_sign
+ integer_part
+ pynini.accep(" ")
+ fractional_part
+ optional_quantity_part
+ delete_space
)
delete_tokens = self.delete_tokens(self.graph)
self.fst = delete_tokens.optimize()
@@ -0,0 +1,22 @@
import pynini
from fun_text_processing.text_normalization.en.graph_utils import GraphFst
from fun_text_processing.text_normalization.ru.alphabet import RU_ALPHA
from pynini.lib import pynutil
class ElectronicFst(GraphFst):
"""
Finite state transducer for verbalizing electronic
e.g. electronic { username: "эй би собака эн ди точка ру" } -> "эй би собака эн ди точка ру"
Args:
deterministic: if True will provide a single transduction option,
for False multiple transduction are generated (used for audio-based normalization)
"""
def __init__(self, deterministic: bool = True):
super().__init__(name="electronic", kind="verbalize", deterministic=deterministic)
graph = pynutil.delete('username: "') + pynini.closure(RU_ALPHA | " ") + pynutil.delete('"')
delete_tokens = self.delete_tokens(graph)
self.fst = delete_tokens.optimize()
@@ -0,0 +1,34 @@
import pynini
from fun_text_processing.text_normalization.en.graph_utils import (
DAMO_NON_BREAKING_SPACE,
DAMO_SPACE,
GraphFst,
delete_space,
)
from fun_text_processing.text_normalization.ru.alphabet import RU_ALPHA
from pynini.lib import pynutil
class MeasureFst(GraphFst):
"""
Finite state transducer for verbalizing measure, e.g.
measure { cardinal { integer: "два килограма" } } -> "два килограма"
Args:
deterministic: if True will provide a single transduction option,
for False multiple transduction are generated (used for audio-based normalization)
"""
def __init__(self, deterministic: bool = True):
super().__init__(name="measure", kind="verbalize", deterministic=deterministic)
graph = (
pynutil.delete(' cardinal { integer: "')
+ pynini.closure(RU_ALPHA | DAMO_SPACE | DAMO_NON_BREAKING_SPACE)
+ pynutil.delete('"')
+ delete_space
+ pynutil.delete("}")
)
delete_tokens = self.delete_tokens(graph)
self.fst = delete_tokens.optimize()
@@ -0,0 +1,24 @@
import pynini
from fun_text_processing.text_normalization.en.graph_utils import GraphFst
from fun_text_processing.text_normalization.ru.alphabet import RU_ALPHA
from pynini.lib import pynutil
class MoneyFst(GraphFst):
"""
Finite state transducer for verbalizing money, e.g.
money { "пять рублей" } -> пять рублей
Args:
deterministic: if True will provide a single transduction option,
for False multiple transduction are generated (used for audio-based normalization)
"""
def __init__(self, deterministic: bool = True):
super().__init__(name="money", kind="verbalize", deterministic=deterministic)
graph = pynini.closure(RU_ALPHA | " ")
delete_tokens = self.delete_tokens(
pynutil.delete('integer_part: "') + graph + pynutil.delete('"')
)
self.fst = delete_tokens.optimize()
@@ -0,0 +1,22 @@
import pynini
from fun_text_processing.text_normalization.en.graph_utils import DAMO_NOT_QUOTE, GraphFst
from pynini.lib import pynutil
class OrdinalFst(GraphFst):
"""
Finite state transducer for verbalizing roman numerals
e.g. ordinal { integer: "второе" } } -> "второе"
Args:
deterministic: if True will provide a single transduction option,
for False multiple transduction are generated (used for audio-based normalization)
"""
def __init__(self, deterministic: bool = True):
super().__init__(name="ordinal", kind="verbalize", deterministic=deterministic)
value = pynini.closure(DAMO_NOT_QUOTE)
graph = pynutil.delete('integer: "') + value + pynutil.delete('"')
delete_tokens = self.delete_tokens(graph)
self.fst = delete_tokens.optimize()
@@ -0,0 +1,26 @@
import pynini
from fun_text_processing.text_normalization.en.graph_utils import GraphFst
from fun_text_processing.text_normalization.ru.alphabet import RU_ALPHA
from pynini.lib import pynutil
class TelephoneFst(GraphFst):
"""
Finite state transducer for verbalizing telephone, e.g.
telephone { number_part: "восемь девятьсот тринадцать девятьсот восемьдесят три пятьдесят шесть ноль один" } -> "восемь девятьсот тринадцать девятьсот восемьдесят три пятьдесят шесть ноль один"
Args:
deterministic: if True will provide a single transduction option,
for False multiple transduction are generated (used for audio-based normalization)
"""
def __init__(self, deterministic: bool = True):
super().__init__(name="telephone", kind="verbalize", deterministic=deterministic)
graph = (
pynutil.delete('number_part: "')
+ pynini.closure(RU_ALPHA | " ", 1)
+ pynutil.delete('"')
)
delete_tokens = self.delete_tokens(graph)
self.fst = delete_tokens.optimize()
@@ -0,0 +1,51 @@
import pynini
from fun_text_processing.text_normalization.en.graph_utils import (
DAMO_NOT_QUOTE,
GraphFst,
delete_space,
insert_space,
)
from pynini.lib import pynutil
class TimeFst(GraphFst):
"""
Finite state transducer for verbalizing electronic
e.g. time { hours: "два часа пятнадцать минут" } -> "два часа пятнадцать минут"
Args:
deterministic: if True will provide a single transduction option,
for False multiple transduction are generated (used for audio-based normalization)
"""
def __init__(self, deterministic: bool = True):
super().__init__(name="time", kind="verbalize", deterministic=deterministic)
hour = (
pynutil.delete("hours:")
+ delete_space
+ pynutil.delete('"')
+ pynini.closure(DAMO_NOT_QUOTE, 1)
+ pynutil.delete('"')
)
minutes = (
pynutil.delete("minutes:")
+ delete_space
+ pynutil.delete('"')
+ pynini.closure(DAMO_NOT_QUOTE, 1)
+ pynutil.delete('"')
)
self.graph = (
hour
+ delete_space
+ insert_space
+ minutes
+ delete_space
+ pynutil.delete("preserve_order: true")
)
self.graph |= hour + delete_space
self.graph |= minutes + delete_space + insert_space + hour + delete_space
delete_tokens = self.delete_tokens(self.graph)
self.fst = delete_tokens.optimize()
@@ -0,0 +1,55 @@
from fun_text_processing.text_normalization.en.graph_utils import GraphFst
from fun_text_processing.text_normalization.en.verbalizers.whitelist import WhiteListFst
from fun_text_processing.text_normalization.ru.verbalizers.cardinal import CardinalFst
from fun_text_processing.text_normalization.ru.verbalizers.date import DateFst
from fun_text_processing.text_normalization.ru.verbalizers.decimal import DecimalFst
from fun_text_processing.text_normalization.ru.verbalizers.electronic import ElectronicFst
from fun_text_processing.text_normalization.ru.verbalizers.measure import MeasureFst
from fun_text_processing.text_normalization.ru.verbalizers.money import MoneyFst
from fun_text_processing.text_normalization.ru.verbalizers.ordinal import OrdinalFst
from fun_text_processing.text_normalization.ru.verbalizers.telephone import TelephoneFst
from fun_text_processing.text_normalization.ru.verbalizers.time import TimeFst
class VerbalizeFst(GraphFst):
"""
Composes other verbalizer grammars.
For deployment, this grammar will be compiled and exported to OpenFst Finate State Archiv (FAR) File.
More details to deployment at NeMo/tools/text_processing_deployment.
Args:
deterministic: if True will provide a single transduction option,
for False multiple options (used for audio-based normalization)
"""
def __init__(self, deterministic: bool = True):
super().__init__(name="verbalize", kind="verbalize", deterministic=deterministic)
cardinal = CardinalFst()
cardinal_graph = cardinal.fst
ordinal_graph = OrdinalFst().fst
decimal = DecimalFst()
decimal_graph = decimal.fst
date = DateFst()
date_graph = date.fst
measure = MeasureFst()
measure_graph = measure.fst
electronic = ElectronicFst()
electronic_graph = electronic.fst
whitelist_graph = WhiteListFst().fst
money_graph = MoneyFst().fst
telephone_graph = TelephoneFst().fst
time_graph = TimeFst().fst
graph = (
measure_graph
| cardinal_graph
| decimal_graph
| ordinal_graph
| date_graph
| electronic_graph
| money_graph
| whitelist_graph
| telephone_graph
| time_graph
)
self.fst = graph
@@ -0,0 +1,62 @@
import os
import pynini
from fun_text_processing.text_normalization.en.graph_utils import (
GraphFst,
delete_extra_space,
delete_space,
generator_main,
)
from fun_text_processing.text_normalization.en.verbalizers.word import WordFst
from fun_text_processing.text_normalization.ru.verbalizers.verbalize import VerbalizeFst
from pynini.lib import pynutil
import logging
class VerbalizeFinalFst(GraphFst):
"""
Finite state transducer that verbalizes an entire sentence, e.g.
tokens { name: "its" } tokens { time { hours: "12" minutes: "30" } } tokens { name: "now" } -> its 12:30 now
Args:
deterministic: if True will provide a single transduction option,
for False multiple options (used for audio-based normalization)
cache_dir: path to a dir with .far grammar file. Set to None to avoid using cache.
overwrite_cache: set to True to overwrite .far files
"""
def __init__(
self, deterministic: bool = True, cache_dir: str = None, overwrite_cache: bool = False
):
super().__init__(name="verbalize_final", kind="verbalize", deterministic=deterministic)
far_file = None
if cache_dir is not None and cache_dir != "None":
os.makedirs(cache_dir, exist_ok=True)
far_file = os.path.join(
cache_dir, f"ru_tn_{deterministic}_deterministic_verbalizer.far"
)
if not overwrite_cache and far_file and os.path.exists(far_file):
self.fst = pynini.Far(far_file, mode="r")["verbalize"]
logging.info(f"VerbalizeFinalFst graph was restored from {far_file}.")
else:
verbalize = VerbalizeFst().fst
word = WordFst().fst
types = verbalize | word
graph = (
pynutil.delete("tokens")
+ delete_space
+ pynutil.delete("{")
+ delete_space
+ types
+ delete_space
+ pynutil.delete("}")
)
graph = delete_space + pynini.closure(graph + delete_extra_space) + graph + delete_space
self.fst = graph.optimize()
if far_file:
generator_main(far_file, {"verbalize": self.fst})
logging.info(f"VerbalizeFinalFst grammars are saved to {far_file}.")