kalpak-js 1.0.0 → 1.1.0

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.
package/README.md CHANGED
@@ -1,50 +1,46 @@
1
1
  # Kalpak.js 🧢
2
2
 
3
- A lightweight, accurate JavaScript library for transliterating **Karakalpak** text between Latin and Cyrillic scripts.
4
- Built by [**Ishipiskenler**](https://github.com/ishipiskenler) (The Doers).
3
+ Karakalpak language tools for JavaScript.
5
4
 
6
- > **Note:** This library follows the official Karakalpak alphabet tables (Yellow Table standards).
5
+ ## Install
7
6
 
8
- ## ✨ Features
7
+ ```bash
8
+ npm install kalpak-js
9
+ ```
9
10
 
10
- - **Latin ➡️ Cyrillic**: Handles complex digraphs (Sh, Ch, etc.) correctly.
11
- - **Cyrillic ➡️ Latin**: Supports official mappings (e.g., И→I, Ы→Í).
12
- - **Zero Dependencies**: Pure JavaScript. Fast and simple.
11
+ ## Features
13
12
 
14
- ## 📦 Installation
13
+ ### 1. Transliteration
15
14
 
16
- ```bash
17
- # Clone the repository
18
- git clone https://github.com/ishipiskenler/karakalpak-translit-js.git
15
+ Convert text between Latin and Cyrillic scripts.
16
+
17
+ ```javascript
18
+ const { latinToCyrillic, cyrillicToLatin } = require("kalpak-js");
19
+
20
+ latinToCyrillic("Sálem"); // "Сәлем"
21
+ cyrillicToLatin("Сәлем"); // "Sálem"
19
22
  ```
20
23
 
21
- _(NPM package coming soon!)_
24
+ ### 2. Number to Text
22
25
 
23
- ## 🚀 Usage
26
+ Convert numbers to Karakalpak words (0 to 1 trillion).
24
27
 
25
28
  ```javascript
26
- const { latinToCyrillic, cyrillicToLatin } = require("./index");
29
+ const { numberToText } = require("kalpak-js");
27
30
 
28
- // 1. Latin to Cyrillic
29
- const cyrillic = latinToCyrillic("Sálem, Qaraqalpaqstan!");
30
- console.log(cyrillic);
31
- // Output: "Сәлем, Қарақалпақстан!"
32
-
33
- // 2. Cyrillic to Latin
34
- const latin = cyrillicToLatin("Мен сeни жақсы көремен ❤️");
35
- console.log(latin);
36
- // Output: "Men seni jaqsı kóremen"
31
+ numberToText(42); // "qırıq eki"
32
+ numberToText(2026); // "eki miń jigirma altı"
33
+ numberToText(1000000); // "bir million"
37
34
  ```
38
35
 
39
- ## 🤝 Contributing
40
-
41
- We welcome contributions!
36
+ ## API
42
37
 
43
- 1. Fork the repo
44
- 2. Create your feature branch
45
- 3. Commit your changes
46
- 4. Open a Pull Request
38
+ | Function | Input | Output |
39
+ | ----------------------- | ----------------------- | ---------------- |
40
+ | `latinToCyrillic(text)` | Latin string | Cyrillic string |
41
+ | `cyrillicToLatin(text)` | Cyrillic string | Latin string |
42
+ | `numberToText(num)` | Number (0 - 1 trillion) | Karakalpak words |
47
43
 
48
- ---
44
+ ## License
49
45
 
50
- © 2026 **Ishipiskenler**. Open Source.
46
+ MIT © [Ishipiskenler](https://github.com/ishipiskenler)
package/index.js CHANGED
@@ -1,218 +1,8 @@
1
- const latinToCyrillicMap = {
2
- // Basic letters
3
- A: "А",
4
- a: "а",
5
- B: "Б",
6
- b: "б",
7
- D: "Д",
8
- d: "д",
9
- E: "Е",
10
- e: "е",
11
- F: "Ф",
12
- f: "ф",
13
- G: "Г",
14
- g: "г",
15
- H: "Ҳ",
16
- h: "ҳ",
17
- X: "Х",
18
- x: "х",
19
- J: "Ж",
20
- j: "ж",
21
- K: "К",
22
- k: "к",
23
- Q: "Қ",
24
- q: "қ",
25
- L: "Л",
26
- l: "л",
27
- M: "М",
28
- m: "м",
29
- N: "Н",
30
- n: "н",
31
- O: "О",
32
- o: "о",
33
- P: "П",
34
- p: "п",
35
- R: "Р",
36
- r: "р",
37
- S: "С",
38
- s: "с",
39
- T: "Т",
40
- t: "т",
41
- U: "У",
42
- u: "у",
43
- V: "В",
44
- v: "в",
45
- Z: "З",
46
- z: "з",
47
-
48
- // Special Karakalpak letters
49
- Á: "Ә",
50
- á: "ә",
51
- Ó: "Ө",
52
- ó: "ө",
53
- Ú: "Ү",
54
- ú: "ү",
55
- I: "И",
56
- i: "и",
57
- Í: "Ы",
58
- ı: "ы",
59
- Ǵ: "Ғ",
60
- ǵ: "ғ",
61
- Ń: "Ң",
62
- ń: "ң",
63
-
64
- // Extra letters
65
- Y: "Й",
66
- y: "й",
67
- W: "Ў",
68
- w: "ў",
69
-
70
- // Digraphs
71
- Sh: "Ш",
72
- sh: "ш",
73
- SH: "Ш",
74
- Yu: "Ю",
75
- yu: "ю",
76
- Ya: "Я",
77
- ya: "я",
78
- Yo: "Ё",
79
- yo: "ё",
80
-
81
- Ch: "Ч",
82
- ch: "ч",
83
- CH: "Ч",
84
-
85
- // Optional / borrowed letters
86
- C: "Ц",
87
- c: "ц",
88
- };
89
-
90
- const cyrillicToLatinMap = {
91
- А: "A",
92
- а: "a",
93
- Ә: "Á",
94
- ә: "á",
95
- Б: "B",
96
- б: "b",
97
- В: "V",
98
- в: "v",
99
- Г: "G",
100
- г: "g",
101
- Ғ: "Ǵ",
102
- ғ: "ǵ",
103
- Д: "D",
104
- д: "d",
105
- Е: "E",
106
- е: "e",
107
- Ё: "Yo",
108
- ё: "yo",
109
- Ж: "J",
110
- ж: "j",
111
- З: "Z",
112
- з: "z",
113
- И: "I",
114
- и: "i",
115
- Й: "Y",
116
- й: "y",
117
- К: "K",
118
- к: "k",
119
- Қ: "Q",
120
- қ: "q",
121
- Л: "L",
122
- л: "l",
123
- М: "M",
124
- м: "m",
125
- Н: "N",
126
- н: "n",
127
- Ң: "Ń",
128
- ң: "ń",
129
- О: "O",
130
- о: "o",
131
- Ө: "Ó",
132
- ө: "ó",
133
- П: "P",
134
- п: "p",
135
- Р: "R",
136
- р: "r",
137
- С: "S",
138
- с: "s",
139
- Т: "T",
140
- т: "t",
141
- У: "U",
142
- у: "u",
143
- Ү: "Ú",
144
- ү: "ú",
145
- Ў: "W",
146
- ў: "w",
147
- Ф: "F",
148
- ф: "f",
149
- Х: "X",
150
- х: "x",
151
- Ҳ: "H",
152
- ҳ: "h",
153
- Ш: "Sh",
154
- ш: "sh",
155
- Ч: "Ch",
156
- ч: "ch",
157
- Щ: "Sh",
158
- щ: "sh", // optional
159
- Ы: "Í",
160
- ы: "ı",
161
-
162
- // Borrowed/Russian letters
163
- Ц: "C",
164
- ц: "c",
165
- Э: "E",
166
- э: "e",
167
- Ю: "Yu",
168
- ю: "yu",
169
- Я: "Ya",
170
- я: "ya",
171
- Ъ: "",
172
- ъ: "",
173
- Ь: "",
174
- ь: "",
175
- };
176
-
177
- function latinToCyrillic(text) {
178
- let result = "";
179
-
180
- for (let i = 0; i < text.length; i++) {
181
- let twoChars = text[i] + (text[i + 1] || "");
182
- if (latinToCyrillicMap[twoChars]) {
183
- result += latinToCyrillicMap[twoChars];
184
- i++;
185
- continue;
186
- }
187
-
188
- let oneChar = text[i];
189
- if (latinToCyrillicMap[oneChar]) {
190
- result += latinToCyrillicMap[oneChar];
191
- } else {
192
- result += oneChar;
193
- }
194
- }
195
-
196
- return result;
197
- }
198
-
199
- function cyrillicToLatin(text) {
200
- let result = "";
201
-
202
- for (let i = 0; i < text.length; i++) {
203
- const char = text[i];
204
-
205
- if (cyrillicToLatinMap[char] !== undefined) {
206
- result += cyrillicToLatinMap[char];
207
- } else {
208
- result += char;
209
- }
210
- }
211
-
212
- return result;
213
- }
1
+ const { latinToCyrillic, cyrillicToLatin } = require("./src/transliterate");
2
+ const { numberToText } = require("./src/numbers");
214
3
 
215
4
  module.exports = {
216
5
  latinToCyrillic,
217
6
  cyrillicToLatin,
7
+ numberToText,
218
8
  };
package/package.json CHANGED
@@ -1,18 +1,21 @@
1
1
  {
2
2
  "name": "kalpak-js",
3
- "version": "1.0.0",
3
+ "version": "1.1.0",
4
4
  "main": "index.js",
5
5
  "scripts": {
6
6
  "test": "echo \"Error: no test specified\" && exit 1"
7
7
  },
8
- "description": "A lightweight JavaScript library for Karakalpak Cyrillic-Latin transliteration.",
8
+ "description": "Karakalpak language tools: transliteration (Latin/Cyrillic) and number-to-text conversion.",
9
9
  "keywords": [
10
10
  "karakalpak",
11
11
  "transliteration",
12
12
  "cyrillic",
13
13
  "latin",
14
14
  "qaraqalpaq",
15
- "language"
15
+ "language",
16
+ "numbers",
17
+ "karakalpakstan",
18
+ "uzbekistan"
16
19
  ],
17
20
  "author": "Ishipiskenler",
18
21
  "license": "MIT",
package/src/numbers.js ADDED
@@ -0,0 +1,145 @@
1
+ // 1. Define the building blocks
2
+ const digits = [
3
+ "nól",
4
+ "bir",
5
+ "eki",
6
+ "úsh",
7
+ "tórt",
8
+ "bes",
9
+ "altı",
10
+ "jeti",
11
+ "segiz",
12
+ "toǵız",
13
+ ];
14
+
15
+ const tens = {
16
+ 10: "on",
17
+ 20: "jigirma",
18
+ 30: "otız",
19
+ 40: "qırıq",
20
+ 50: "eliw",
21
+ 60: "alpıs",
22
+ 70: "jetpis",
23
+ 80: "seksen",
24
+ 90: "toqsan",
25
+ };
26
+
27
+ const hundreds = {
28
+ 100: "bir júz",
29
+ 200: "eki júz",
30
+ 300: "úsh júz",
31
+ 400: "tórt júz",
32
+ 500: "bes júz",
33
+ 600: "altı júz",
34
+ 700: "jeti júz",
35
+ 800: "segiz júz",
36
+ 900: "toǵız júz",
37
+ };
38
+
39
+ function numberToText(num) {
40
+ // 0. Safety check (Validation)
41
+ if (typeof num !== "number") return "Error: Not a number";
42
+ if (num < 0 || num > 1000000000000)
43
+ return "Error: Only 0-1000000000000 (up to one trillion) supported for now";
44
+
45
+ // 1. Handle exact whole numbers
46
+ if (num === 100) return "júz";
47
+ if (num === 1000) return "miń";
48
+ if (num === 10000) return "on miń";
49
+ if (num === 100000) return "júz miń";
50
+ if (num === 1000000) return "bir million";
51
+ if (num === 10000000) return "on million";
52
+ if (num === 100000000) return "júz million";
53
+ if (num === 1000000000) return "bir milliard";
54
+ if (num === 10000000000) return "on milliard";
55
+ if (num === 100000000000) return "júz milliard";
56
+ if (num === 1000000000000) return "bir trillion";
57
+
58
+ // 2. Handle 0-9
59
+ if (num < 10) {
60
+ return digits[num];
61
+ }
62
+
63
+ // 3. Handle 10-99
64
+ if (num > 9 && num < 100) {
65
+ const tenPart = Math.floor(num / 10) * 10; // e.g. 42 -> 40
66
+ const onePart = num % 10; // e.g. 42 -> 2
67
+
68
+ const tenText = tens[tenPart];
69
+
70
+ // If perfectly 20, 30, 40... (onePart is 0), just return the tenText
71
+ if (onePart === 0) {
72
+ return tenText;
73
+ }
74
+
75
+ // Otherwise combine them: "qırıq" + " " + "eki"
76
+ const oneText = digits[onePart];
77
+ return `${tenText} ${oneText}`;
78
+ }
79
+
80
+ // Handle 100-999
81
+ if (num >= 100 && num < 1000) {
82
+ const hundredsPart = Math.floor(num / 100) * 100;
83
+ const tenPart = Math.floor((num % 100) / 10) * 10;
84
+ const onePart = (num % 100) % 10;
85
+
86
+ const hundredsText = hundreds[hundredsPart];
87
+ const tenText = tens[tenPart];
88
+ const oneText = digits[onePart];
89
+
90
+ if (tenPart === 0 && onePart === 0) {
91
+ return `${hundreds[num]}`;
92
+ }
93
+
94
+ // If the ten-part is zero, return hundreds and one-part only (101,102, ...)
95
+ if (tenPart === 0) {
96
+ return `${hundredsText} ${oneText}`;
97
+ }
98
+
99
+ // If the one-part is zero, return hundreds-part and tens-part only (110,120, ...)
100
+ if (onePart === 0) {
101
+ return `${hundredsText} ${tenText}`;
102
+ }
103
+
104
+ // You know this broo :)
105
+ return `${hundredsText} ${tenText} ${oneText}`;
106
+ }
107
+
108
+ // Handle (1000 - 999999) (thousands)
109
+ if (num >= 1000 && num < 1000000) {
110
+ const thousandsPart = Math.floor(num / 1000);
111
+ const remainder = num % 1000;
112
+
113
+ if (remainder === 0) {
114
+ return `${numberToText(thousandsPart)} miń`;
115
+ }
116
+
117
+ return `${numberToText(thousandsPart)} miń ${numberToText(remainder)}`;
118
+ }
119
+
120
+ // Handle (million - billion) (millions)
121
+ if (num >= 1000000 && num < 1000000000) {
122
+ const millionsPart = Math.floor(num / 1000000);
123
+ const remainder = num % 1000000;
124
+
125
+ if (remainder === 0) {
126
+ return `${numberToText(millionsPart)} million`;
127
+ }
128
+
129
+ return `${numberToText(millionsPart)} million ${numberToText(remainder)}`;
130
+ }
131
+
132
+ // Handle (billion - trillion) (billions)
133
+ if (num >= 1000000000 && num < 1000000000000) {
134
+ const billionsPart = Math.floor(num / 1000000000);
135
+ const remainder = num % 1000000000;
136
+
137
+ if (remainder === 0) {
138
+ return `${numberToText(billionsPart)} milliard`;
139
+ }
140
+
141
+ return `${numberToText(billionsPart)} milliard ${numberToText(remainder)}`;
142
+ }
143
+ }
144
+
145
+ module.exports = { numberToText };
@@ -0,0 +1,215 @@
1
+ const latinToCyrillicMap = {
2
+ // Basic letters
3
+ A: "А",
4
+ a: "а",
5
+ B: "Б",
6
+ b: "б",
7
+ D: "Д",
8
+ d: "д",
9
+ E: "Е",
10
+ e: "е",
11
+ F: "Ф",
12
+ f: "ф",
13
+ G: "Г",
14
+ g: "г",
15
+ H: "Ҳ",
16
+ h: "ҳ",
17
+ X: "Х",
18
+ x: "х",
19
+ J: "Ж",
20
+ j: "ж",
21
+ K: "К",
22
+ k: "к",
23
+ Q: "Қ",
24
+ q: "қ",
25
+ L: "Л",
26
+ l: "л",
27
+ M: "М",
28
+ m: "м",
29
+ N: "Н",
30
+ n: "н",
31
+ O: "О",
32
+ o: "о",
33
+ P: "П",
34
+ p: "п",
35
+ R: "Р",
36
+ r: "р",
37
+ S: "С",
38
+ s: "с",
39
+ T: "Т",
40
+ t: "т",
41
+ U: "У",
42
+ u: "у",
43
+ V: "В",
44
+ v: "в",
45
+ Z: "З",
46
+ z: "з",
47
+
48
+ // Special letters
49
+ Á: "Ә",
50
+ á: "ә",
51
+ Ó: "Ө",
52
+ ó: "ө",
53
+ Ú: "Ү",
54
+ ú: "ү",
55
+ I: "И",
56
+ i: "и",
57
+ Í: "Ы",
58
+ ı: "ы",
59
+ Ǵ: "Ғ",
60
+ ǵ: "ғ",
61
+ Ń: "Ң",
62
+ ń: "ң",
63
+
64
+ // Extra letters
65
+ Y: "Й",
66
+ y: "й",
67
+ W: "Ў",
68
+ w: "ў",
69
+
70
+ // Digraphs
71
+ Sh: "Ш",
72
+ sh: "ш",
73
+ SH: "Ш",
74
+ Yu: "Ю",
75
+ yu: "ю",
76
+ Ya: "Я",
77
+ ya: "я",
78
+ Yo: "Ё",
79
+ yo: "ё",
80
+
81
+ Ch: "Ч",
82
+ ch: "ч",
83
+ CH: "Ч",
84
+
85
+ // Optional / borrowed letters
86
+ C: "Ц",
87
+ c: "ц",
88
+ };
89
+
90
+ const cyrillicToLatinMap = {
91
+ А: "A",
92
+ а: "a",
93
+ Ә: "Á",
94
+ ә: "á",
95
+ Б: "B",
96
+ б: "b",
97
+ В: "V",
98
+ в: "v",
99
+ Г: "G",
100
+ г: "g",
101
+ Ғ: "Ǵ",
102
+ ғ: "ǵ",
103
+ Д: "D",
104
+ д: "d",
105
+ Е: "E",
106
+ е: "e",
107
+ Ё: "Yo",
108
+ ё: "yo",
109
+ Ж: "J",
110
+ ж: "j",
111
+ З: "Z",
112
+ з: "z",
113
+ И: "I",
114
+ и: "i",
115
+ Й: "Y",
116
+ й: "y",
117
+ К: "K",
118
+ к: "k",
119
+ Қ: "Q",
120
+ қ: "q",
121
+ Л: "L",
122
+ л: "l",
123
+ М: "M",
124
+ м: "m",
125
+ Н: "N",
126
+ н: "n",
127
+ Ң: "Ń",
128
+ ң: "ń",
129
+ О: "O",
130
+ о: "o",
131
+ Ө: "Ó",
132
+ ө: "ó",
133
+ П: "P",
134
+ п: "p",
135
+ Р: "R",
136
+ р: "r",
137
+ С: "S",
138
+ с: "s",
139
+ Т: "T",
140
+ т: "t",
141
+ У: "U",
142
+ у: "u",
143
+ Ү: "Ú",
144
+ ү: "ú",
145
+ Ў: "W",
146
+ ў: "w",
147
+ Ф: "F",
148
+ ф: "f",
149
+ Х: "X",
150
+ х: "x",
151
+ Ҳ: "H",
152
+ ҳ: "h",
153
+ Ш: "Sh",
154
+ ш: "sh",
155
+ Ч: "Ch",
156
+ ч: "ch",
157
+ Щ: "Sh",
158
+ щ: "sh", // optional
159
+ Ы: "Í",
160
+ ы: "ı",
161
+
162
+ // Borrowed/Russian letters
163
+ Ц: "C",
164
+ ц: "c",
165
+ Э: "E",
166
+ э: "e",
167
+ Ю: "Yu",
168
+ ю: "yu",
169
+ Я: "Ya",
170
+ я: "ya",
171
+ Ъ: "",
172
+ ъ: "",
173
+ Ь: "",
174
+ ь: "",
175
+ };
176
+
177
+ function latinToCyrillic(text) {
178
+ let result = "";
179
+
180
+ for (let i = 0; i < text.length; i++) {
181
+ let twoChars = text[i] + (text[i + 1] || "");
182
+ if (latinToCyrillicMap[twoChars]) {
183
+ result += latinToCyrillicMap[twoChars];
184
+ i++;
185
+ continue;
186
+ }
187
+
188
+ let oneChar = text[i];
189
+ if (latinToCyrillicMap[oneChar]) {
190
+ result += latinToCyrillicMap[oneChar];
191
+ } else {
192
+ result += oneChar;
193
+ }
194
+ }
195
+
196
+ return result;
197
+ }
198
+
199
+ function cyrillicToLatin(text) {
200
+ let result = "";
201
+
202
+ for (let i = 0; i < text.length; i++) {
203
+ const char = text[i];
204
+
205
+ if (cyrillicToLatinMap[char] !== undefined) {
206
+ result += cyrillicToLatinMap[char];
207
+ } else {
208
+ result += char;
209
+ }
210
+ }
211
+
212
+ return result;
213
+ }
214
+
215
+ module.exports = { latinToCyrillic, cyrillicToLatin };