diff --git a/documents/how_to_add_new_language.md b/documents/how_to_add_new_language.md
index b0ff36d3..5813dfb7 100644
--- a/documents/how_to_add_new_language.md
+++ b/documents/how_to_add_new_language.md
@@ -10,6 +10,9 @@ The following steps with help you identify files that need to be added or change
NOTE: Take a look at [PR #40](https://github.com/unicode-org/inflection/pull/40) and [PR #111](https://github.com/unicode-org/inflection/pull/111) for example on how to add initial language support based on dictionary lookup only.
In general, to bootstrap your progress look for grammatically similar language that's already supported, e.g. if you are adding Serbian look for existing Russian implementation.
This will help you find most of the files you need to add/change and will speed up implementation of the rules and lexicons.
+We recommend you spend around a week researching the language and all the different components of the language before even beginning to modify and add the files below. Look at all the files in the project such as tokenizers, configuration files, grammar files, and different lookup functions to see what you need. This will save you a lot of time in the end. We highly suggest you stray away from hardcoded logic and rely on the Dictionary Lookup. Look at all the grammemes, tokenizer logic, and multi-word phrase handling.
+
+Before you add new language support, go to the README.md in the inflection subfolder (inflection/inflection/README.md), build the project, and make sure all the tests run on your computer.
## Mark your language as supported
* UPDATE: inflection/src/inflection/util/LocaleUtils.hpp
@@ -29,13 +32,13 @@ TODO: We need to expand what each of these do.
* ADD: inflection/src/inflection/grammar/synthesis/*Xx*GrammarSynthesizer.hpp
* ADD: inflection/src/inflection/grammar/synthesis/*Xx*GrammarSynthesizer.cpp
* ADD: inflection/src/inflection/grammar/synthesis/*Xx*GrammarSynthesizer_*Xx*DisplayFunction.hpp
-* ADD: inflection/src/inflection/grammar/synthesis/*Xx*GrammarSynthesizer_*Xx*DisplayFunction.hpp
+* ADD: inflection/src/inflection/grammar/synthesis/*Xx*GrammarSynthesizer_*Xx*DisplayFunction.cpp
* UPDATE: inflection/src/inflection/grammar/synthesis/GrammarSynthesizerFactory.cpp
* UPDATE: inflection/src/inflection/grammar/synthesis/fwd.hpp
## Add language specific properties for lists, quantities and related topics
* ADD: inflection/src/inflection/dialog/language/*Xx*CommonConceptFactory.hpp
-* ADD: inflection/src/inflection/dialog/language/*Xx*CommonConceptFactory.hpp
+* ADD: inflection/src/inflection/dialog/language/*Xx*CommonConceptFactory.cpp
* UPDATE: inflection/src/inflection/dialog/language/fwd.hpp
## Define and create lexion
diff --git a/inflection/resources/org/unicode/inflection/dictionary/.gitattributes b/inflection/resources/org/unicode/inflection/dictionary/.gitattributes
index fe535cd8..9dc3b5af 100644
--- a/inflection/resources/org/unicode/inflection/dictionary/.gitattributes
+++ b/inflection/resources/org/unicode/inflection/dictionary/.gitattributes
@@ -8,6 +8,7 @@ dictionary_he.lst filter=lfs diff=lfs merge=lfs -text
dictionary_hi.lst filter=lfs diff=lfs merge=lfs -text
dictionary_it.lst filter=lfs diff=lfs merge=lfs -text
dictionary_ko.lst filter=lfs diff=lfs merge=lfs -text
+dictionary_ml.lst filter=lfs diff=lfs merge=lfs -text
dictionary_nb.lst filter=lfs diff=lfs merge=lfs -text
dictionary_nl.lst filter=lfs diff=lfs merge=lfs -text
dictionary_pt.lst filter=lfs diff=lfs merge=lfs -text
@@ -23,6 +24,7 @@ inflectional_fr.xml filter=lfs diff=lfs merge=lfs -text
inflectional_he.xml filter=lfs diff=lfs merge=lfs -text
inflectional_hi.xml filter=lfs diff=lfs merge=lfs -text
inflectional_it.xml filter=lfs diff=lfs merge=lfs -text
+inflectional_ml.xml filter=lfs diff=lfs merge=lfs -text
inflectional_nb.xml filter=lfs diff=lfs merge=lfs -text
inflectional_nl.xml filter=lfs diff=lfs merge=lfs -text
inflectional_pt.xml filter=lfs diff=lfs merge=lfs -text
diff --git a/inflection/resources/org/unicode/inflection/dictionary/dictionary_ml.lst b/inflection/resources/org/unicode/inflection/dictionary/dictionary_ml.lst
new file mode 100644
index 00000000..16334d78
--- /dev/null
+++ b/inflection/resources/org/unicode/inflection/dictionary/dictionary_ml.lst
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:bf0c250408b3b33d34c649abdc9fb38f4038eb8c79376457927d6875c6b2d2b1
+size 53959671
diff --git a/inflection/resources/org/unicode/inflection/dictionary/inflectional_ml.xml b/inflection/resources/org/unicode/inflection/dictionary/inflectional_ml.xml
new file mode 100644
index 00000000..07c896d8
--- /dev/null
+++ b/inflection/resources/org/unicode/inflection/dictionary/inflectional_ml.xml
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:5d37a014f1784bde85ab6d5e2c274a9509a535a1a4d070d86cc506c09bcd4813
+size 617609
diff --git a/inflection/resources/org/unicode/inflection/features/grammar.xml b/inflection/resources/org/unicode/inflection/features/grammar.xml
index 6a620220..ba7ddccd 100644
--- a/inflection/resources/org/unicode/inflection/features/grammar.xml
+++ b/inflection/resources/org/unicode/inflection/features/grammar.xml
@@ -1624,6 +1624,106 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/inflection/resources/org/unicode/inflection/inflection/pronoun_ml.csv b/inflection/resources/org/unicode/inflection/inflection/pronoun_ml.csv
new file mode 100644
index 00000000..d4150315
--- /dev/null
+++ b/inflection/resources/org/unicode/inflection/inflection/pronoun_ml.csv
@@ -0,0 +1,83 @@
+അവൻ,third,singular,nominative,masculine,personal,distal
+എനിക്ക്,first,singular,dative,personal
+ഞാൻ,first,singular,nominative,exclusive,personal
+എന്നെ,first,singular,accusative,exclusive,personal
+എന്റെ,first,singular,genitive,determination=dependent,exclusive,personal
+എന്റേത്,first,singular,genitive,determination=independent,exclusive,personal
+നമ്മെ,first,plural,accusative,inclusive,personal
+നമുക്ക്,first,plural,dative,inclusive,personal
+ഞങ്ങൾ,first,plural,nominative,exclusive,personal
+ഞങ്ങളെ,first,plural,accusative,exclusive,personal
+ഞങ്ങൾക്ക്,first,plural,dative,exclusive,personal
+ഞങ്ങളുടെ,first,plural,genitive,exclusive,determination=dependent,personal
+ഞങ്ങളുടേത്,first,plural,genitive,exclusive,determination=independent,personal
+നമ്മുടെ,first,plural,genitive,inclusive,determination=dependent,personal
+നമ്മുടേതു്,first,plural,genitive,inclusive,determination=independent,personal
+നിനക്ക്,second,singular,dative,informal,personal
+നീ,second,singular,nominative,informal,personal
+നിനെ,second,singular,accusative,informal,personal
+നിന്റെ,second,singular,genitive,informal,determination=dependent,personal
+നിന്റേതു്,second,singular,genitive,informal,determination=independent,personal
+താങ്കൾ,second,singular,nominative,formal,personal
+താങ്കളെ,second,singular,accusative,formal,personal
+താങ്കൾക്ക്,second,singular,dative,formal,personal
+താങ്കളുടെ,second,singular,genitive,formal,determination=dependent,personal
+താങ്കളുടേതു്,second,singular,genitive,formal,determination=independent,personal
+നിങ്ങൾ,second,plural,nominative,formal,personal
+നിങ്ങളെ,second,plural,accusative,formal,personal
+നിങ്ങൾക്ക്,second,plural,dative,formal,personal
+നിങ്ങളുടെ,second,plural,genitive,formal,determination=dependent,personal
+നിങ്ങളുടേതു്,second,plural,genitive,formal,determination=independent,personal
+അവനെ,third,singular,accusative,masculine,personal,distal
+അവന്റെ,third,singular,genitive,masculine,determination=dependent,personal,distal
+അവന്റെത്,third,singular,genitive,masculine,determination=independent,personal,distal
+അവൾ,third,singular,nominative,feminine,personal,distal
+അവളെ,third,singular,accusative,feminine,personal,distal
+അവളുടെ,third,singular,genitive,feminine,determination=dependent,personal,distal
+അവളുടേതു്,third,singular,genitive,feminine,determination=independent,personal,distal
+അത്,third,singular,nominative,neuter,personal,distal
+അതിനെ,third,singular,accusative,neuter,personal,distal
+അതിന്റെ,third,singular,genitive,neuter,determination=dependent,personal,distal
+അതിന്റേതു്,third,singular,genitive,neuter,determination=independent,personal,distal
+അവർ,third,plural,nominative,personal,distal
+അവരെ,third,plural,accusative,personal,distal
+അവരുടെ,third,plural,genitive,determination=dependent,personal,distal
+അവരുടേതു്,third,plural,genitive,determination=independent,personal,distal
+എന്നിൽ,first,singular,locative,personal
+എന്നാൽ,first,singular,instrumental,personal
+എന്നോടു്,first,singular,sociative,personal
+ഞങ്ങളിലു്,first,plural,locative,exclusive,personal
+ഞങ്ങളാൽ,first,plural,instrumental,exclusive,personal
+ഞങ്ങളോടു്,first,plural,sociative,exclusive,personal
+നിനിൽ,second,singular,locative,informal,personal
+നിനാൽ,second,singular,instrumental,informal,personal
+നിനോടു്,second,singular,sociative,informal,personal
+താങ്കളിൽ,second,singular,locative,formal,personal
+താങ്കളാൽ,second,singular,instrumental,formal,personal
+താങ്കളോടു്,second,singular,sociative,formal,personal
+നിങ്ങളിൽ,second,plural,locative,formal,personal
+നിങ്ങളാൽ,second,plural,instrumental,formal,personal
+നിങ്ങളോടു്,second,plural,sociative,formal,personal
+അവനിൽ,third,singular,locative,masculine,personal,distal
+അവനാൽ,third,singular,instrumental,masculine,personal,distal
+അവനോടു്,third,singular,sociative,masculine,personal,distal
+അവളിൽ,third,singular,locative,feminine,personal,distal
+അവളാൽ,third,singular,instrumental,feminine,personal,distal
+അവളോടു്,third,singular,sociative,feminine,personal,distal
+അതിൽ,third,singular,locative,neuter,personal,distal
+അതാൽ,third,singular,instrumental,neuter,personal,distal
+അതോടു്,third,singular,sociative,neuter,personal,distal
+അവരിൽ,third,plural,locative,personal,distal
+അവരാൽ,third,plural,instrumental,personal,distal
+അവരോടു്,third,plural,sociative,personal,distal
+താൻ,third,singular,nominative,reflexive,personal
+തങ്ങൾ,third,plural,nominative,formal,reflexive,personal
+ഇവൻ,third,singular,nominative,masculine,proximal,personal
+ഇവൾ,third,singular,nominative,feminine,proximal,personal
+ഇത്,third,singular,nominative,neuter,proximal,personal
+ഇവർ,third,plural,nominative,proximal,personal
+എവൻ,third,singular,nominative,masculine,interrogative
+എവൾ,third,singular,nominative,feminine,interrogative
+എവർ,third,plural,nominative,interrogative
+ഏത്,third,singular,nominative,neuter,interrogative
+നാം,first,plural,nominative,inclusive,personal
diff --git a/inflection/resources/org/unicode/inflection/locale/supported-locales.properties b/inflection/resources/org/unicode/inflection/locale/supported-locales.properties
index 6815591d..43741bca 100644
--- a/inflection/resources/org/unicode/inflection/locale/supported-locales.properties
+++ b/inflection/resources/org/unicode/inflection/locale/supported-locales.properties
@@ -15,6 +15,7 @@ locale.group.it=it_IT,it_CH
locale.group.ja=ja_JP
locale.group.ko=ko_KR
locale.group.ms=ms_MY
+locale.group.ml=ml_IN
locale.group.nb=nb_NO
locale.group.nl=nl_NL,nl_BE
locale.group.pt=pt_BR,pt_PT
diff --git a/inflection/resources/org/unicode/inflection/tokenizer/config_ml.properties b/inflection/resources/org/unicode/inflection/tokenizer/config_ml.properties
new file mode 100644
index 00000000..03f49492
--- /dev/null
+++ b/inflection/resources/org/unicode/inflection/tokenizer/config_ml.properties
@@ -0,0 +1,7 @@
+#
+# Copyright 2025 Unicode Incorporated and others. All rights reserved.
+#
+tokenizer.implementation.class=DefaultTokenizer
+tokenizer.nonDecompound.file=/org/unicode/inflection/tokenizer/ml/nondecompound.tok
+tokenizer.decompound=(ശ്രീ)(.+?)(ഗുരു|സര്ക്കാര്)$|^(.+?)(ഗുരു|സര്ക്കാര്)$|^(.+?)(ഉണ്ട്|ആണ്|ഇല്ല)$|^(.+?)(ഒടൊപ്പം|ഉടൻ|ഓടെ|ഓട്|ഒപ്പം|തന്നെ|പോലും|പോലെ|ഉം|യ്)$|^(.+?)(കളുടെ|ങ്ങളുടെ|ത്തിന്റെ|ൻ്റെ|ന്റെ|യുടേ|യുടെ|യാൽ|യിൽ|ഇൽ|ല്|ൽ|ക്ക്|മാർ|ങ്ങൾ|കൾ|നെ|യെ)
+
diff --git a/inflection/resources/org/unicode/inflection/tokenizer/ml/nondecompound.tok b/inflection/resources/org/unicode/inflection/tokenizer/ml/nondecompound.tok
new file mode 100644
index 00000000..c62b299c
--- /dev/null
+++ b/inflection/resources/org/unicode/inflection/tokenizer/ml/nondecompound.tok
@@ -0,0 +1,35 @@
+അമ്മ
+അച്ഛൻ
+അച്ഛി
+അമ്മൻ
+മകൻ
+മകൾ
+കുട്ടി
+കുട്ടികൾ
+ആൺകുട്ടി
+ആൺകുട്ടികൾ
+പെൺകുട്ടി
+പെൺകുട്ടികൾ
+കഥ
+ചിത്രം
+ചിത്രങ്ങൾ
+ഗ്രന്ഥം
+ഗ്രന്ഥങ്ങൾ
+മക്കൾ
+ഞാൻ
+നീ
+നിങ്ങൾ
+അവൻ
+അവൾ
+അവ
+അവർ
+ഇത്
+അത്
+ഇവ
+അവ
+ശ്രീ
+നാരായണ
+ഗുരു
+കേരളം
+സര്ക്കാര്
+കേരളസര്ക്കാര്
diff --git a/inflection/src/inflection/dialog/language/MlCommonConceptFactory.cpp b/inflection/src/inflection/dialog/language/MlCommonConceptFactory.cpp
new file mode 100644
index 00000000..0626c420
--- /dev/null
+++ b/inflection/src/inflection/dialog/language/MlCommonConceptFactory.cpp
@@ -0,0 +1,60 @@
+/*
+ * Copyright 2025 Unicode Incorporated and others. All rights reserved.
+ */
+
+#include
+#include
+#include
+#include
+#include
+
+namespace inflection::dialog::language {
+
+// Malayalam-specific conjunction for OR
+::inflection::dialog::SemanticConceptList* MlCommonConceptFactory::createOrList(
+ const ::std::vector& concepts) const
+{
+ auto list = super::createOrList(concepts);
+ if (list) {
+ list->setBeforeLast(::inflection::dialog::SpeakableString(u" അല്ലെങ്കിൽ "));
+ }
+ return list;
+}
+
+// Malayalam-specific conjunction for AND
+::inflection::dialog::SemanticConceptList* MlCommonConceptFactory::createAndList(
+ const ::std::vector& concepts) const
+{
+ auto list = super::createAndList(concepts);
+ if (list) {
+ list->setBeforeLast(::inflection::dialog::SpeakableString(u"യും "));
+ list->setItemDelimiter(::inflection::dialog::SpeakableString(u", "));
+ }
+ return list;
+}
+
+// In Malayalam, numbers generally follow the noun
+::inflection::dialog::SpeakableString
+MlCommonConceptFactory::quantifiedJoin(const ::inflection::dialog::SpeakableString& formattedNumber,
+ const ::inflection::dialog::SpeakableString& nounPhrase,
+ const ::std::u16string& /*measureWord*/,
+ Plurality::Rule countType) const
+{
+ ::inflection::dialog::SpeakableString space(u" ");
+ if (countType == Plurality::Rule::ONE) {
+ return nounPhrase + space + formattedNumber;
+ }
+ return formattedNumber + space + nounPhrase;
+}
+
+// Fallback to base implementation for now
+::inflection::dialog::SpeakableString
+MlCommonConceptFactory::quantifyType(const ::inflection::dialog::SpeakableString& formattedNumber,
+ const ::inflection::dialog::SemanticFeatureConceptBase& semanticConcept,
+ bool useDefault,
+ ::inflection::dialog::Plurality::Rule countType) const
+{
+ return super::quantifyType(formattedNumber, semanticConcept, useDefault, countType);
+}
+
+} // namespace inflection::dialog::language
diff --git a/inflection/src/inflection/dialog/language/MlCommonConceptFactory.hpp b/inflection/src/inflection/dialog/language/MlCommonConceptFactory.hpp
new file mode 100644
index 00000000..ee9e9f42
--- /dev/null
+++ b/inflection/src/inflection/dialog/language/MlCommonConceptFactory.hpp
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2025 Unicode Incorporated and others. All rights reserved.
+ */
+#pragma once
+
+#include
+#include
+#include
+#include
+
+namespace inflection::dialog::language {
+
+class MlCommonConceptFactory : public CommonConceptFactoryImpl {
+ using super = CommonConceptFactoryImpl;
+
+public:
+ explicit MlCommonConceptFactory(const ::inflection::util::ULocale& language);
+ ~MlCommonConceptFactory() override;
+
+ // Malayalam-specific conjunction handling
+ ::inflection::dialog::SemanticConceptList* createOrList(
+ const ::std::vector& concepts) const override;
+
+ ::inflection::dialog::SemanticConceptList* createAndList(
+ const ::std::vector& concepts) const override;
+
+protected:
+ ::inflection::dialog::SpeakableString quantifiedJoin(
+ const ::inflection::dialog::SpeakableString& formattedNumber,
+ const ::inflection::dialog::SpeakableString& nounPhrase,
+ const ::std::u16string& measureWord,
+ ::inflection::dialog::Plurality::Rule countType) const override;
+
+ ::inflection::dialog::SpeakableString quantifyType(
+ const ::inflection::dialog::SpeakableString& formattedNumber,
+ const ::inflection::dialog::SemanticFeatureConceptBase& semanticConcept,
+ bool useDefault,
+ ::inflection::dialog::Plurality::Rule countType) const override;
+};
+
+} // namespace inflection::dialog::language
diff --git a/inflection/src/inflection/dialog/language/fwd.hpp b/inflection/src/inflection/dialog/language/fwd.hpp
index 6429ca3a..8dbefaee 100644
--- a/inflection/src/inflection/dialog/language/fwd.hpp
+++ b/inflection/src/inflection/dialog/language/fwd.hpp
@@ -1,5 +1,5 @@
/*
- * Copyright 2017-2024 Apple Inc. All rights reserved.
+ * Copyright 2017-2025 Apple Inc. All rights reserved.
*/
// Forward declarations for inflection.dialog.language
#pragma once
@@ -28,6 +28,7 @@ namespace inflection
class JaCommonConceptFactory;
class KoCommonConceptFactory;
class KoCommonConceptFactory_KoAndList;
+ class MlCommonConceptFactory;
class MsCommonConceptFactory;
class NbCommonConceptFactory;
class NlCommonConceptFactory;
diff --git a/inflection/src/inflection/grammar/synthesis/GrammarSynthesizerFactory.cpp b/inflection/src/inflection/grammar/synthesis/GrammarSynthesizerFactory.cpp
index ecb31303..faff5658 100644
--- a/inflection/src/inflection/grammar/synthesis/GrammarSynthesizerFactory.cpp
+++ b/inflection/src/inflection/grammar/synthesis/GrammarSynthesizerFactory.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright 2017-2024 Apple Inc. All rights reserved.
+ * Copyright 2017-2025 Apple Inc. All rights reserved.
*/
#include
@@ -13,6 +13,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -41,6 +42,7 @@ static const ::std::map<::inflection::util::ULocale, addSemanticFeatures>& GRAMM
{::inflection::util::LocaleUtils::HINDI(), &HiGrammarSynthesizer::addSemanticFeatures},
{::inflection::util::LocaleUtils::ITALIAN(), &ItGrammarSynthesizer::addSemanticFeatures},
{::inflection::util::LocaleUtils::KOREAN(), &KoGrammarSynthesizer::addSemanticFeatures},
+ {::inflection::util::LocaleUtils::MALAYALAM(), &MlGrammarSynthesizer::addSemanticFeatures},
{::inflection::util::LocaleUtils::NORWEGIAN(), &NbGrammarSynthesizer::addSemanticFeatures},
{::inflection::util::LocaleUtils::DUTCH(), &NlGrammarSynthesizer::addSemanticFeatures},
{::inflection::util::LocaleUtils::PORTUGUESE(), &PtGrammarSynthesizer::addSemanticFeatures},
diff --git a/inflection/src/inflection/grammar/synthesis/GrammemeConstants.cpp b/inflection/src/inflection/grammar/synthesis/GrammemeConstants.cpp
index 52d1f31f..68ef6b23 100644
--- a/inflection/src/inflection/grammar/synthesis/GrammemeConstants.cpp
+++ b/inflection/src/inflection/grammar/synthesis/GrammemeConstants.cpp
@@ -159,6 +159,12 @@ const ::std::u16string& GrammemeConstants::CASE_PREPOSITIONAL()
return *npc(CASE_PREPOSITIONAL_);
}
+const ::std::u16string& GrammemeConstants::CASE_SOCIATIVE()
+{
+ static auto CASE_SOCIATIVE_ = new ::std::u16string(u"sociative");
+ return *npc(CASE_SOCIATIVE_);
+}
+
const ::std::u16string& GrammemeConstants::CASE_TRANSLATIVE()
{
static auto CASE_TRANSLATIVE_ = new ::std::u16string(u"translative");
diff --git a/inflection/src/inflection/grammar/synthesis/GrammemeConstants.hpp b/inflection/src/inflection/grammar/synthesis/GrammemeConstants.hpp
index 4010c1ba..dcd61fc7 100644
--- a/inflection/src/inflection/grammar/synthesis/GrammemeConstants.hpp
+++ b/inflection/src/inflection/grammar/synthesis/GrammemeConstants.hpp
@@ -42,6 +42,7 @@ class inflection::grammar::synthesis::GrammemeConstants final
static const ::std::u16string& CASE_OBLIQUE();
static const ::std::u16string& CASE_PARTITIVE();
static const ::std::u16string& CASE_PREPOSITIONAL();
+ static const ::std::u16string& CASE_SOCIATIVE();
static const ::std::u16string& CASE_TRANSLATIVE();
static const ::std::u16string& CASE_VOCATIVE();
diff --git a/inflection/src/inflection/grammar/synthesis/MlGrammarSynthesizer.cpp b/inflection/src/inflection/grammar/synthesis/MlGrammarSynthesizer.cpp
new file mode 100644
index 00000000..759d4cb2
--- /dev/null
+++ b/inflection/src/inflection/grammar/synthesis/MlGrammarSynthesizer.cpp
@@ -0,0 +1,157 @@
+/*
+ * Copyright 2025 Unicode Incorporated and others. All rights reserved.
+ */
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include