kumaoni 1.0.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
kumaoni/__init__.py ADDED
@@ -0,0 +1,329 @@
1
+ """
2
+ Kumaoni (कुमाऊँनी) Language Library for Python
3
+ =============================================
4
+
5
+ A standard-library-style Python package for the Kumaoni language, providing
6
+ linguistic primitives, phonetics, grammar, verb conjugation, dictionary lookups,
7
+ and universal translation from any language of the world into Kumaoni.
8
+
9
+ Quick Start:
10
+ ------------
11
+ >>> import kumaoni
12
+ >>> kumaoni.translate("How are you?")
13
+ <TranslationResult text='कस छू तुम?' romanized='kas chhoo tum?'>
14
+ >>> kumaoni.conjugate("जाण", tense="past", person=1)
15
+ 'ग्यूँ'
16
+ >>> kumaoni.num_to_words(42)
17
+ 'बयालीस'
18
+ >>> kumaoni.lookup("ईजा")
19
+ Word(kumaoni='ईजा', roman='ija', english='mother', hindi='माँ', pos='noun', category='kinship')
20
+ """
21
+
22
+ __version__ = "1.0.0"
23
+ __author__ = "Akshat Singh Bisht"
24
+ __email__ = "infoakshatsinghbisht@gmail.com"
25
+ __maintainer__ = "Akshat Singh Bisht"
26
+ __website__ = "https://akshatsinghbisht.com/"
27
+ __copyright__ = "Copyright (c) 2026 Akshat Singh Bisht"
28
+ __license__ = "MIT"
29
+
30
+ # Constants
31
+ from kumaoni.constants import (
32
+ ISO_639_3,
33
+ ISO_639_NAME,
34
+ NATIVE_NAME,
35
+ Dialect,
36
+ Script,
37
+ PartOfSpeech,
38
+ Tense,
39
+ Gender,
40
+ GrammaticalNumber,
41
+ SEASONS,
42
+ KUMAONI_MONTHS,
43
+ DAYS_OF_WEEK,
44
+ KINSHIP,
45
+ )
46
+
47
+ # Phonetics & Script Conversion
48
+ from kumaoni.phonetics import (
49
+ normalize_devanagari as normalize,
50
+ detect_script,
51
+ devanagari_to_latin,
52
+ latin_to_devanagari,
53
+ tokenize,
54
+ syllables,
55
+ )
56
+
57
+ # Numbers & Numerals
58
+ from kumaoni.numbers import (
59
+ num_to_words,
60
+ words_to_num,
61
+ to_devanagari_numerals,
62
+ from_devanagari_numerals,
63
+ ordinal,
64
+ fraction,
65
+ )
66
+
67
+ # Grammar & Morphology
68
+ from kumaoni.grammar import (
69
+ extract_root,
70
+ conjugate,
71
+ conjugate_to_be,
72
+ conjunctive_participle,
73
+ agent_noun,
74
+ imperative,
75
+ pluralize,
76
+ decline_noun,
77
+ make_diminutive,
78
+ make_augmentative,
79
+ to_feminine,
80
+ to_masculine,
81
+ to_oblique,
82
+ attach_case,
83
+ get_marker,
84
+ get_pronoun,
85
+ CASE_MARKERS,
86
+ PRONOUN_TABLE,
87
+ SyntaxEngine,
88
+ causative,
89
+ passive,
90
+ medio_passive_inability,
91
+ compound_verb,
92
+ echo_word,
93
+ build_sentence,
94
+ conditional,
95
+ relative_correlative,
96
+ prohibitive,
97
+ modal_ability,
98
+ modal_obligation,
99
+ modal_desiderative,
100
+ interrogative_sentence,
101
+ )
102
+
103
+ # Lexicon & Dictionary & 100k+ Morphological Engine
104
+ from kumaoni.lexicon import (
105
+ Word,
106
+ Lexicon,
107
+ get_lexicon,
108
+ lookup,
109
+ search,
110
+ lemmatize,
111
+ analyze,
112
+ total_word_forms,
113
+ MorphAnalysis,
114
+ KumaoniMorphology,
115
+ FullFormCorpus,
116
+ )
117
+
118
+ # Translation Engine
119
+ from kumaoni.translator import (
120
+ Translator,
121
+ TranslationResult,
122
+ translate,
123
+ RuleBasedTranslator,
124
+ PivotTranslator,
125
+ LLMTranslator,
126
+ )
127
+
128
+ # Culture & Heritage
129
+ from kumaoni.culture import (
130
+ Festival,
131
+ get_festival,
132
+ list_festivals,
133
+ get_months,
134
+ get_seasons,
135
+ get_days_of_week,
136
+ get_current_season,
137
+ )
138
+
139
+
140
+ # Voice & Speech Synthesis
141
+ from kumaoni.voice import (
142
+ KumaoniVoiceSynthesizer,
143
+ VoiceTranslator,
144
+ VoiceTranslationResult,
145
+ voice_translate,
146
+ )
147
+
148
+
149
+ def transliterate(text: str, to_script: str = "devanagari") -> str:
150
+ """
151
+ Universal transliterator between Latin and Devanagari scripts for Kumaoni.
152
+ """
153
+ to_s = to_script.lower()
154
+ if to_s in ("devanagari", "dev"):
155
+ return latin_to_devanagari(text)
156
+ elif to_s in ("latin", "roman", "eng"):
157
+ return devanagari_to_latin(text)
158
+ return text
159
+
160
+
161
+ # Cultural convenience facades
162
+ class _ProverbsFacade:
163
+ def list(self):
164
+ return get_lexicon().get_proverbs()
165
+
166
+ def all(self):
167
+ return self.list()
168
+
169
+ def random(self):
170
+ return get_lexicon().random_proverb()
171
+
172
+
173
+ class _RiddlesFacade:
174
+ def list(self):
175
+ return get_lexicon().get_riddles()
176
+
177
+ def all(self):
178
+ return self.list()
179
+
180
+ def random(self):
181
+ return get_lexicon().random_riddle()
182
+
183
+
184
+ class _PhrasesFacade:
185
+ def list(self, category=None):
186
+ return get_lexicon().get_phrases(category=category)
187
+
188
+ def all(self, category=None):
189
+ return self.list(category=category)
190
+
191
+ def random(self):
192
+ return get_lexicon().random_phrase()
193
+
194
+
195
+ class _FestivalsFacade:
196
+ def list(self):
197
+ return list_festivals()
198
+
199
+ def all(self):
200
+ return self.list()
201
+
202
+ def get(self, name):
203
+ return get_festival(name)
204
+
205
+
206
+ class _LiteratureFacade:
207
+ def epics(self):
208
+ from kumaoni.culture.literature import LiteratureTreasury
209
+ return LiteratureTreasury.list_epics()
210
+
211
+ def get_epic(self, epic_id):
212
+ from kumaoni.culture.literature import LiteratureTreasury
213
+ return LiteratureTreasury.get_epic(epic_id)
214
+
215
+ def poems(self, form=None):
216
+ from kumaoni.culture.literature import LiteratureTreasury
217
+ return LiteratureTreasury.list_poems(form=form)
218
+
219
+ def authors(self):
220
+ from kumaoni.culture.literature import LiteratureTreasury
221
+ return LiteratureTreasury.list_authors()
222
+
223
+ def get_author(self, author_id):
224
+ from kumaoni.culture.literature import LiteratureTreasury
225
+ return LiteratureTreasury.get_author(author_id)
226
+
227
+
228
+ class _VoiceFacade:
229
+ def translate(self, text: str, source_lang: str = "auto", method: str = "auto", generate_audio: bool = False):
230
+ return voice_translate(text, source_lang=source_lang, method=method, generate_audio=generate_audio)
231
+
232
+ def synthesize_wav(self, duration_seconds: float = 1.0, freq: float = 440.0):
233
+ return KumaoniVoiceSynthesizer.generate_pcm_wav(duration_seconds=duration_seconds, freq=freq)
234
+
235
+ def phrases(self, category=None):
236
+ from kumaoni.voice.engine import _voice_translator
237
+ return _voice_translator.get_voice_phrases(category=category)
238
+
239
+
240
+ proverbs = _ProverbsFacade()
241
+ riddles = _RiddlesFacade()
242
+ phrases = _PhrasesFacade()
243
+ festivals = _FestivalsFacade()
244
+ literature = _LiteratureFacade()
245
+ voice = _VoiceFacade()
246
+
247
+ __all__ = [
248
+ # Top-level functions
249
+ "translate",
250
+ "voice_translate",
251
+ "lookup",
252
+ "search",
253
+ "lemmatize",
254
+ "analyze",
255
+ "total_word_forms",
256
+ "MorphAnalysis",
257
+ "KumaoniMorphology",
258
+ "FullFormCorpus",
259
+ "conjugate",
260
+ "conjugate_to_be",
261
+ "conjunctive_participle",
262
+ "agent_noun",
263
+ "imperative",
264
+ "causative",
265
+ "passive",
266
+ "medio_passive_inability",
267
+ "compound_verb",
268
+ "echo_word",
269
+ "build_sentence",
270
+ "conditional",
271
+ "relative_correlative",
272
+ "prohibitive",
273
+ "modal_ability",
274
+ "modal_obligation",
275
+ "modal_desiderative",
276
+ "interrogative_sentence",
277
+ "num_to_words",
278
+ "words_to_num",
279
+ "to_devanagari_numerals",
280
+ "from_devanagari_numerals",
281
+ "ordinal",
282
+ "fraction",
283
+ "normalize",
284
+ "transliterate",
285
+ "devanagari_to_latin",
286
+ "latin_to_devanagari",
287
+ "tokenize",
288
+ "syllables",
289
+ "pluralize",
290
+ "decline_noun",
291
+ "make_diminutive",
292
+ "make_augmentative",
293
+ "to_feminine",
294
+ "to_masculine",
295
+ "to_oblique",
296
+ "attach_case",
297
+ "get_marker",
298
+ "get_pronoun",
299
+ # Voice classes
300
+ "KumaoniVoiceSynthesizer",
301
+ "VoiceTranslator",
302
+ "VoiceTranslationResult",
303
+ # Constants
304
+ "ISO_639_3",
305
+ "ISO_639_NAME",
306
+ "NATIVE_NAME",
307
+ "Dialect",
308
+ "Script",
309
+ "PartOfSpeech",
310
+ "Tense",
311
+ "Gender",
312
+ "GrammaticalNumber",
313
+ "SEASONS",
314
+ "KUMAONI_MONTHS",
315
+ "DAYS_OF_WEEK",
316
+ "KINSHIP",
317
+ "CASE_MARKERS",
318
+ "PRONOUN_TABLE",
319
+ # Facades
320
+ "proverbs",
321
+ "riddles",
322
+ "phrases",
323
+ "festivals",
324
+ "literature",
325
+ "voice",
326
+ ]
327
+
328
+
329
+
kumaoni/cli.py ADDED
@@ -0,0 +1,148 @@
1
+ """
2
+ Command-line interface (CLI) for the Kumaoni language library.
3
+ Usage:
4
+ python -m kumaoni.cli translate "Hello, how are you?"
5
+ python -m kumaoni.cli lookup "ईजा"
6
+ python -m kumaoni.cli number 42
7
+ python -m kumaoni.cli conjugate "जाण" --tense past
8
+ python -m kumaoni.cli proverb
9
+ python -m kumaoni.cli riddle
10
+ """
11
+
12
+ import sys
13
+ import argparse
14
+ import json
15
+
16
+ # Ensure UTF-8 output on Windows consoles
17
+ if hasattr(sys.stdout, "reconfigure"):
18
+ try:
19
+ sys.stdout.reconfigure(encoding="utf-8")
20
+ sys.stderr.reconfigure(encoding="utf-8")
21
+ except Exception:
22
+ pass
23
+
24
+ import kumaoni
25
+ from kumaoni.constants import Tense, Gender, GrammaticalNumber
26
+
27
+
28
+ def main():
29
+ parser = argparse.ArgumentParser(
30
+ prog="kumaoni",
31
+ description="Kumaoni Language Standard Library CLI"
32
+ )
33
+ subparsers = parser.add_subparsers(dest="command", help="Available commands")
34
+
35
+ # translate
36
+ trans_parser = subparsers.add_parser("translate", help="Translate text to Kumaoni")
37
+ trans_parser.add_argument("text", type=str, help="Text to translate")
38
+ trans_parser.add_argument("--source", "-s", default="auto", help="Source language (default: auto)")
39
+ trans_parser.add_argument("--method", "-m", default="auto", choices=["auto", "rule_based", "pivot", "llm"])
40
+ trans_parser.add_argument("--api-key", "-k", default=None, help="Optional Gemini/OpenAI API key")
41
+
42
+ # lookup
43
+ lookup_parser = subparsers.add_parser("lookup", help="Dictionary search")
44
+ lookup_parser.add_argument("word", type=str, help="Word to look up")
45
+
46
+ # number
47
+ num_parser = subparsers.add_parser("number", help="Convert numbers to Kumaoni words")
48
+ num_parser.add_argument("num", type=int, help="Integer to convert")
49
+ num_parser.add_argument("--script", default="devanagari", choices=["devanagari", "latin"])
50
+
51
+ # conjugate
52
+ conj_parser = subparsers.add_parser("conjugate", help="Conjugate Kumaoni verbs")
53
+ conj_parser.add_argument("verb", type=str, help="Infinitive verb (e.g., खाण, जाण)")
54
+ conj_parser.add_argument("--tense", "-t", default="present", choices=["present", "past", "future", "present_continuous"])
55
+ conj_parser.add_argument("--person", "-p", type=int, default=3, choices=[1, 2, 3])
56
+ conj_parser.add_argument("--gender", "-g", default="m", choices=["m", "f"])
57
+
58
+ # proverb
59
+ subparsers.add_parser("proverb", help="Display a traditional Kumaoni proverb (Akhaan)")
60
+
61
+ # riddle
62
+ subparsers.add_parser("riddle", help="Display a traditional Kumaoni riddle (Aana)")
63
+
64
+ # voice
65
+ voice_parser = subparsers.add_parser("voice", help="Voice translation with phonetics, syllables, and SSML")
66
+ voice_parser.add_argument("text", type=str, help="Text or transcript to translate for voice")
67
+ voice_parser.add_argument("--source", "-s", default="auto", help="Source language (default: auto)")
68
+
69
+ # transliterate
70
+ translit_parser = subparsers.add_parser("transliterate", help="Transliterate between Devanagari and Latin")
71
+ translit_parser.add_argument("text", type=str, help="Text to transliterate")
72
+ translit_parser.add_argument("--to", default="devanagari", choices=["devanagari", "latin"])
73
+
74
+ args = parser.parse_args()
75
+
76
+ if not args.command:
77
+ parser.print_help()
78
+ sys.exit(0)
79
+
80
+ if args.command == "voice":
81
+ res = kumaoni.voice.translate(args.text, source_lang=args.source, generate_audio=False)
82
+ print(f"\n[Voice Input ({res.source_lang})]: {res.source_text}")
83
+ print(f"[Kumaoni Spoken]: {res.translated_text}")
84
+ print(f"[Phonetic Cadence]: {res.romanized}")
85
+ print(f"[Syllable Stress]: {' · '.join(res.syllables)}")
86
+ print(f"[SSML Markup]: {res.ssml}")
87
+ print(f"[Intent Category]: {res.category}\n")
88
+
89
+ if args.command == "translate":
90
+ res = kumaoni.translate(args.text, source=args.source, method=args.method, api_key=args.api_key)
91
+ print(f"\n[Source ({res.source_lang})]: {res.source}")
92
+ print(f"[Kumaoni]: {res.text}")
93
+ print(f"[Phonetic]: {res.romanized}")
94
+ print(f"[Method]: {res.method} (confidence: {res.confidence:.2f})\n")
95
+
96
+ elif args.command == "lookup":
97
+ w = kumaoni.lookup(args.word)
98
+ if w:
99
+ print(f"\nKumaoni: {w.kumaoni} ({w.roman})")
100
+ print(f"English: {w.english}")
101
+ print(f"Hindi: {w.hindi}")
102
+ print(f"Part of Sp.: {w.pos} [{w.category}]\n")
103
+ else:
104
+ results = kumaoni.search(args.word)
105
+ if results:
106
+ print(f"\nFound {len(results)} matches:")
107
+ for r in results:
108
+ print(f"- {r.kumaoni} ({r.roman}): {r.english} | {r.hindi}")
109
+ print()
110
+ else:
111
+ print(f"\nNo dictionary match found for '{args.word}'.\n")
112
+
113
+ elif args.command == "number":
114
+ w = kumaoni.num_to_words(args.num, script=args.script)
115
+ dev_num = kumaoni.to_devanagari_numerals(args.num)
116
+ print(f"\nNumber: {args.num} ({dev_num})")
117
+ print(f"In words: {w}\n")
118
+
119
+ elif args.command == "conjugate":
120
+ t = Tense(args.tense)
121
+ g = Gender.MASCULINE if args.gender == "m" else Gender.FEMININE
122
+ res = kumaoni.conjugate(args.verb, tense=t, person=args.person, gender=g)
123
+ print(f"\nVerb: {args.verb}")
124
+ print(f"Tense: {args.tense}")
125
+ print(f"Conjugated: {res}\n")
126
+
127
+ elif args.command == "proverb":
128
+ p = kumaoni.proverbs.random()
129
+ print(f"\nअखाण (Akhaan): {p.get('kumaoni')}")
130
+ print(f"Phonetic: {p.get('roman')}")
131
+ print(f"Meaning: {p.get('figurative_meaning')}")
132
+ print(f"Hindi: {p.get('hindi_equivalent')}")
133
+ print(f"English: {p.get('english_equivalent')}\n")
134
+
135
+ elif args.command == "riddle":
136
+ r = kumaoni.riddles.random()
137
+ print(f"\nआणा (Aana): {r.get('riddle')}")
138
+ print(f"English: {r.get('english_translation')}")
139
+ print(f"Answer: {r.get('answer_kumaoni')} ({r.get('answer_english')})\n")
140
+
141
+ elif args.command == "transliterate":
142
+ out = kumaoni.transliterate(args.text, to_script=args.to)
143
+ print(f"\nInput: {args.text}")
144
+ print(f"Output: {out}\n")
145
+
146
+
147
+ if __name__ == "__main__":
148
+ main()
kumaoni/constants.py ADDED
@@ -0,0 +1,123 @@
1
+ """
2
+ Linguistic and cultural constants for the Kumaoni language library.
3
+ """
4
+
5
+ from enum import Enum
6
+
7
+
8
+ class Dialect(str, Enum):
9
+ """Major regional dialects of the Kumaoni language."""
10
+ STANDARD = "standard" # Central / Almora / Majh-Kumaiya standard
11
+ KHASPARJIYA = "khasparjiya" # Almora and surrounding hilly heartland
12
+ SORYALI = "soryali" # Pithoragarh / Soar valley
13
+ GANGOLI = "gangoli" # Gangolihat region
14
+ ASKOTI = "askoti" # Askot / Didihat region
15
+ DANPURIYA = "danpuriya" # Danpur / Bageshwar region
16
+ SIRWALI = "sirwali" # Siragadh region
17
+ CHAUGAARKHIYA = "chaugaarkhiya" # Champawat / Kali Kumaon
18
+ JOHARI = "johari" # Johar valley / Munsiyari (northern borderland)
19
+
20
+
21
+ class Script(str, Enum):
22
+ """Scripts supported for Kumaoni."""
23
+ DEVANAGARI = "devanagari"
24
+ LATIN = "latin" # Romanized / English phonetic
25
+ IAST = "iast" # International Alphabet of Sanskrit Transliteration
26
+
27
+
28
+ class PartOfSpeech(str, Enum):
29
+ """Linguistic parts of speech."""
30
+ NOUN = "noun"
31
+ PRONOUN = "pronoun"
32
+ VERB = "verb"
33
+ ADJECTIVE = "adjective"
34
+ ADVERB = "adverb"
35
+ POSTPOSITION = "postposition"
36
+ CONJUNCTION = "conjunction"
37
+ INTERJECTION = "interjection"
38
+ PARTICLE = "particle"
39
+ NUMBER = "number"
40
+
41
+
42
+ class Tense(str, Enum):
43
+ """Grammatical tenses."""
44
+ PRESENT = "present"
45
+ PAST = "past"
46
+ FUTURE = "future"
47
+ PRESENT_CONTINUOUS = "present_continuous"
48
+ PAST_CONTINUOUS = "past_continuous"
49
+ FUTURE_CONTINUOUS = "future_continuous"
50
+ IMPERATIVE = "imperative"
51
+
52
+
53
+ class Gender(str, Enum):
54
+ """Grammatical genders."""
55
+ MASCULINE = "masculine"
56
+ FEMININE = "feminine"
57
+ NEUTER = "neuter"
58
+
59
+
60
+ class GrammaticalNumber(str, Enum):
61
+ """Grammatical numbers."""
62
+ SINGULAR = "singular"
63
+ PLURAL = "plural"
64
+
65
+
66
+ # ISO language code for Kumaoni
67
+ ISO_639_3 = "kfy"
68
+ ISO_639_NAME = "Kumaoni"
69
+ NATIVE_NAME = "कुमाऊँनी"
70
+
71
+ # Traditional Kumaoni Seasons (ऋतु / Ritu)
72
+ SEASONS = {
73
+ "basant": {"name_kmy": "बसंत", "english": "Spring", "months": ["फागुन", "चैत"]},
74
+ "grishma": {"name_kmy": "रूड़ि", "english": "Summer", "months": ["बैसाख", "जेठ"]},
75
+ "varsha": {"name_kmy": "चौमास", "english": "Monsoon / Rainy", "months": ["असाड़", "साउन", "भादौ"]},
76
+ "sharad": {"name_kmy": "सरद", "english": "Autumn", "months": ["आसोज", "कातिक"]},
77
+ "hemant": {"name_kmy": "स्यूँद", "english": "Early Winter", "months": ["मंगसिर", "पूस"]},
78
+ "shishir": {"name_kmy": "जाड़", "english": "Late Winter", "months": ["माघ", "फागुन"]},
79
+ }
80
+
81
+ # Kumaoni Solar Calendar Months (सौर मास)
82
+ KUMAONI_MONTHS = [
83
+ {"index": 1, "kumaoni": "चैत", "roman": "Chait", "gregorian": "March-April"},
84
+ {"index": 2, "kumaoni": "बैसाख", "roman": "Baisakh", "gregorian": "April-May"},
85
+ {"index": 3, "kumaoni": "जेठ", "roman": "Jeth", "gregorian": "May-June"},
86
+ {"index": 4, "kumaoni": "असाड़", "roman": "Asadh", "gregorian": "June-July"},
87
+ {"index": 5, "kumaoni": "साउन", "roman": "Saun", "gregorian": "July-August"},
88
+ {"index": 6, "kumaoni": "भादौ", "roman": "Bhado", "gregorian": "August-September"},
89
+ {"index": 7, "kumaoni": "आसोज", "roman": "Aasoj", "gregorian": "September-October"},
90
+ {"index": 8, "kumaoni": "कातिक", "roman": "Kaatik", "gregorian": "October-November"},
91
+ {"index": 9, "kumaoni": "मंगसिर", "roman": "Mangasir", "gregorian": "November-December"},
92
+ {"index": 10, "kumaoni": "पूस", "roman": "Poos", "gregorian": "December-January"},
93
+ {"index": 11, "kumaoni": "माघ", "roman": "Maagh", "gregorian": "January-February"},
94
+ {"index": 12, "kumaoni": "फागुन", "roman": "Faagun", "gregorian": "February-March"},
95
+ ]
96
+
97
+ # Days of the Week
98
+ DAYS_OF_WEEK = [
99
+ {"day": 0, "kumaoni": "इतवार", "roman": "Itwaar", "english": "Sunday"},
100
+ {"day": 1, "kumaoni": "सोमवार", "roman": "Somwaar", "english": "Monday"},
101
+ {"day": 2, "kumaoni": "मंगलवार", "roman": "Mangalwaar", "english": "Tuesday"},
102
+ {"day": 3, "kumaoni": "बुधवार", "roman": "Budhwaar", "english": "Wednesday"},
103
+ {"day": 4, "kumaoni": "बिसवार", "roman": "Biswaar", "english": "Thursday"},
104
+ {"day": 5, "kumaoni": "सुकरवार", "roman": "Sukarwaar", "english": "Friday"},
105
+ {"day": 6, "kumaoni": "सनिच्चर", "roman": "Sanicchar", "english": "Saturday"},
106
+ ]
107
+
108
+ # Common Kinship Terms
109
+ KINSHIP = {
110
+ "father": {"kumaoni": "बाबु", "variants": ["बौजी", "बुबा"], "roman": "Babu / Bauji"},
111
+ "mother": {"kumaoni": "ईजा", "variants": ["म्यात"], "roman": "Ija"},
112
+ "elder_brother": {"kumaoni": "दाज्यू", "variants": ["दाजू"], "roman": "Dajyu"},
113
+ "younger_brother": {"kumaoni": "भै", "variants": ["भैया"], "roman": "Bhai"},
114
+ "elder_sister": {"kumaoni": "दीदी", "variants": ["दिदी"], "roman": "Didi"},
115
+ "younger_sister": {"kumaoni": "भुली", "variants": ["बैणी"], "roman": "Bhuli / Baini"},
116
+ "grandfather": {"kumaoni": "बूबू", "variants": ["बारबाबू"], "roman": "Bubu"},
117
+ "grandmother": {"kumaoni": "आमा", "variants": ["अम्मा"], "roman": "Aama"},
118
+ "son": {"kumaoni": "च्याल", "variants": ["च्यल"], "roman": "Chyal"},
119
+ "daughter": {"kumaoni": "चेलि", "variants": ["चेली"], "roman": "Cheli"},
120
+ "uncle_paternal": {"kumaoni": "काका", "variants": ["काकू"], "roman": "Kaka"},
121
+ "aunt_paternal": {"kumaoni": "काकी", "variants": [], "roman": "Kaki"},
122
+ "children": {"kumaoni": "नान्तिन", "variants": ["नतुवे"], "roman": "Naantin"},
123
+ }
@@ -0,0 +1,33 @@
1
+ """
2
+ Cultural heritage and calendar module for Kumaon.
3
+ """
4
+
5
+ from kumaoni.culture.festivals import Festival, get_festival, list_festivals
6
+ from kumaoni.culture.calendar import get_months, get_seasons, get_days_of_week, get_current_season
7
+ from kumaoni.culture.literature import (
8
+ FolkEpic,
9
+ FolkPoem,
10
+ KumaoniAuthor,
11
+ LiteratureTreasury,
12
+ EPICS,
13
+ POEMS,
14
+ AUTHORS,
15
+ )
16
+
17
+ __all__ = [
18
+ "Festival",
19
+ "get_festival",
20
+ "list_festivals",
21
+ "get_months",
22
+ "get_seasons",
23
+ "get_days_of_week",
24
+ "get_current_season",
25
+ "FolkEpic",
26
+ "FolkPoem",
27
+ "KumaoniAuthor",
28
+ "LiteratureTreasury",
29
+ "EPICS",
30
+ "POEMS",
31
+ "AUTHORS",
32
+ ]
33
+
@@ -0,0 +1,29 @@
1
+ """
2
+ Kumaoni solar calendar and seasonal calculations.
3
+ """
4
+
5
+ from typing import Dict, List, Optional
6
+ from kumaoni.constants import KUMAONI_MONTHS, SEASONS, DAYS_OF_WEEK
7
+
8
+
9
+ def get_months() -> List[Dict]:
10
+ """Returns the twelve months of the Kumaoni solar calendar."""
11
+ return list(KUMAONI_MONTHS)
12
+
13
+
14
+ def get_seasons() -> Dict[str, Dict]:
15
+ """Returns the traditional Himalayan seasonal divisions."""
16
+ return dict(SEASONS)
17
+
18
+
19
+ def get_days_of_week() -> List[Dict]:
20
+ """Returns days of the week in Kumaoni."""
21
+ return list(DAYS_OF_WEEK)
22
+
23
+
24
+ def get_current_season(month_name: str) -> Optional[Dict]:
25
+ """Find the traditional season associated with a Kumaoni month."""
26
+ for s_key, s_info in SEASONS.items():
27
+ if month_name in s_info["months"]:
28
+ return s_info
29
+ return None