1package ki
2
3import (
4	"math"
5	"strconv"
6	"time"
7
8	"github.com/go-playground/locales"
9	"github.com/go-playground/locales/currency"
10)
11
12type ki struct {
13	locale                 string
14	pluralsCardinal        []locales.PluralRule
15	pluralsOrdinal         []locales.PluralRule
16	pluralsRange           []locales.PluralRule
17	decimal                string
18	group                  string
19	minus                  string
20	percent                string
21	perMille               string
22	timeSeparator          string
23	inifinity              string
24	currencies             []string // idx = enum of currency code
25	currencyNegativePrefix string
26	currencyNegativeSuffix string
27	monthsAbbreviated      []string
28	monthsNarrow           []string
29	monthsWide             []string
30	daysAbbreviated        []string
31	daysNarrow             []string
32	daysShort              []string
33	daysWide               []string
34	periodsAbbreviated     []string
35	periodsNarrow          []string
36	periodsShort           []string
37	periodsWide            []string
38	erasAbbreviated        []string
39	erasNarrow             []string
40	erasWide               []string
41	timezones              map[string]string
42}
43
44// New returns a new instance of translator for the 'ki' locale
45func New() locales.Translator {
46	return &ki{
47		locale:                 "ki",
48		pluralsCardinal:        nil,
49		pluralsOrdinal:         nil,
50		pluralsRange:           nil,
51		timeSeparator:          ":",
52		currencies:             []string{"ADP", "AED", "AFA", "AFN", "ALK", "ALL", "AMD", "ANG", "AOA", "AOK", "AON", "AOR", "ARA", "ARL", "ARM", "ARP", "ARS", "ATS", "AUD", "AWG", "AZM", "AZN", "BAD", "BAM", "BAN", "BBD", "BDT", "BEC", "BEF", "BEL", "BGL", "BGM", "BGN", "BGO", "BHD", "BIF", "BMD", "BND", "BOB", "BOL", "BOP", "BOV", "BRB", "BRC", "BRE", "BRL", "BRN", "BRR", "BRZ", "BSD", "BTN", "BUK", "BWP", "BYB", "BYN", "BYR", "BZD", "CAD", "CDF", "CHE", "CHF", "CHW", "CLE", "CLF", "CLP", "CNH", "CNX", "CNY", "COP", "COU", "CRC", "CSD", "CSK", "CUC", "CUP", "CVE", "CYP", "CZK", "DDM", "DEM", "DJF", "DKK", "DOP", "DZD", "ECS", "ECV", "EEK", "EGP", "ERN", "ESA", "ESB", "ESP", "ETB", "EUR", "FIM", "FJD", "FKP", "FRF", "GBP", "GEK", "GEL", "GHC", "GHS", "GIP", "GMD", "GNF", "GNS", "GQE", "GRD", "GTQ", "GWE", "GWP", "GYD", "HKD", "HNL", "HRD", "HRK", "HTG", "HUF", "IDR", "IEP", "ILP", "ILR", "ILS", "INR", "IQD", "IRR", "ISJ", "ISK", "ITL", "JMD", "JOD", "JPY", "Ksh", "KGS", "KHR", "KMF", "KPW", "KRH", "KRO", "KRW", "KWD", "KYD", "KZT", "LAK", "LBP", "LKR", "LRD", "LSL", "LTL", "LTT", "LUC", "LUF", "LUL", "LVL", "LVR", "LYD", "MAD", "MAF", "MCF", "MDC", "MDL", "MGA", "MGF", "MKD", "MKN", "MLF", "MMK", "MNT", "MOP", "MRO", "MTL", "MTP", "MUR", "MVP", "MVR", "MWK", "MXN", "MXP", "MXV", "MYR", "MZE", "MZM", "MZN", "NAD", "NGN", "NIC", "NIO", "NLG", "NOK", "NPR", "NZD", "OMR", "PAB", "PEI", "PEN", "PES", "PGK", "PHP", "PKR", "PLN", "PLZ", "PTE", "PYG", "QAR", "RHD", "ROL", "RON", "RSD", "RUB", "RUR", "RWF", "SAR", "SBD", "SCR", "SDD", "SDG", "SDP", "SEK", "SGD", "SHP", "SIT", "SKK", "SLL", "SOS", "SRD", "SRG", "SSP", "STD", "STN", "SUR", "SVC", "SYP", "SZL", "THB", "TJR", "TJS", "TMM", "TMT", "TND", "TOP", "TPE", "TRL", "TRY", "TTD", "TWD", "TZS", "UAH", "UAK", "UGS", "UGX", "USD", "USN", "USS", "UYI", "UYP", "UYU", "UZS", "VEB", "VEF", "VND", "VNN", "VUV", "WST", "XAF", "XAG", "XAU", "XBA", "XBB", "XBC", "XBD", "XCD", "XDR", "XEU", "XFO", "XFU", "XOF", "XPD", "XPF", "XPT", "XRE", "XSU", "XTS", "XUA", "XXX", "YDD", "YER", "YUD", "YUM", "YUN", "YUR", "ZAL", "ZAR", "ZMK", "ZMW", "ZRN", "ZRZ", "ZWD", "ZWL", "ZWR"},
53		currencyNegativePrefix: "(",
54		currencyNegativeSuffix: ")",
55		monthsAbbreviated:      []string{"", "JEN", "WKR", "WGT", "WKN", "WTN", "WTD", "WMJ", "WNN", "WKD", "WIK", "WMW", "DIT"},
56		monthsNarrow:           []string{"", "J", "K", "G", "K", "G", "G", "M", "K", "K", "I", "I", "D"},
57		monthsWide:             []string{"", "Njenuarĩ", "Mwere wa kerĩ", "Mwere wa gatatũ", "Mwere wa kana", "Mwere wa gatano", "Mwere wa gatandatũ", "Mwere wa mũgwanja", "Mwere wa kanana", "Mwere wa kenda", "Mwere wa ikũmi", "Mwere wa ikũmi na ũmwe", "Ndithemba"},
58		daysAbbreviated:        []string{"KMA", "NTT", "NMN", "NMT", "ART", "NMA", "NMM"},
59		daysNarrow:             []string{"K", "N", "N", "N", "A", "N", "N"},
60		daysWide:               []string{"Kiumia", "Njumatatũ", "Njumaine", "Njumatana", "Aramithi", "Njumaa", "Njumamothi"},
61		periodsAbbreviated:     []string{"Kiroko", "Hwaĩ-inĩ"},
62		periodsWide:            []string{"Kiroko", "Hwaĩ-inĩ"},
63		erasAbbreviated:        []string{"MK", "TK"},
64		erasNarrow:             []string{"", ""},
65		erasWide:               []string{"Mbere ya Kristo", "Thutha wa Kristo"},
66		timezones:              map[string]string{"HKST": "HKST", "ChST": "ChST", "PST": "PST", "AEST": "AEST", "SGT": "SGT", "HEEG": "HEEG", "HEPM": "HEPM", "CAT": "CAT", "CHADT": "CHADT", "BOT": "BOT", "HNEG": "HNEG", "ACST": "ACST", "GFT": "GFT", "WIT": "WIT", "OESZ": "OESZ", "ARST": "ARST", "GMT": "GMT", "CST": "CST", "LHST": "LHST", "WART": "WART", "WESZ": "WESZ", "NZST": "NZST", "NZDT": "NZDT", "JST": "JST", "AKST": "AKST", "CDT": "CDT", "AWST": "AWST", "MDT": "MDT", "WITA": "WITA", "JDT": "JDT", "HADT": "HADT", "COT": "COT", "HNPMX": "HNPMX", "SAST": "SAST", "MYT": "MYT", "EST": "EST", "MEZ": "MEZ", "HNT": "HNT", "OEZ": "OEZ", "UYST": "UYST", "CHAST": "CHAST", "PDT": "PDT", "WIB": "WIB", "HEOG": "HEOG", "HKT": "HKT", "HENOMX": "HENOMX", "TMT": "TMT", "∅∅∅": "∅∅∅", "AKDT": "AKDT", "HNOG": "HNOG", "AWDT": "AWDT", "HEPMX": "HEPMX", "MST": "MST", "LHDT": "LHDT", "WARST": "WARST", "HAT": "HAT", "SRT": "SRT", "AEDT": "AEDT", "WEZ": "WEZ", "ACWST": "ACWST", "IST": "IST", "HAST": "HAST", "ART": "ART", "UYT": "UYT", "HECU": "HECU", "ACDT": "ACDT", "MESZ": "MESZ", "ACWDT": "ACWDT", "HNPM": "HNPM", "TMST": "TMST", "COST": "COST", "HNCU": "HNCU", "BT": "BT", "ECT": "ECT", "CLT": "CLT", "ADT": "ADT", "WAT": "WAT", "HNNOMX": "HNNOMX", "VET": "VET", "EAT": "EAT", "CLST": "CLST", "GYT": "GYT", "AST": "AST", "WAST": "WAST", "EDT": "EDT"},
67	}
68}
69
70// Locale returns the current translators string locale
71func (ki *ki) Locale() string {
72	return ki.locale
73}
74
75// PluralsCardinal returns the list of cardinal plural rules associated with 'ki'
76func (ki *ki) PluralsCardinal() []locales.PluralRule {
77	return ki.pluralsCardinal
78}
79
80// PluralsOrdinal returns the list of ordinal plural rules associated with 'ki'
81func (ki *ki) PluralsOrdinal() []locales.PluralRule {
82	return ki.pluralsOrdinal
83}
84
85// PluralsRange returns the list of range plural rules associated with 'ki'
86func (ki *ki) PluralsRange() []locales.PluralRule {
87	return ki.pluralsRange
88}
89
90// CardinalPluralRule returns the cardinal PluralRule given 'num' and digits/precision of 'v' for 'ki'
91func (ki *ki) CardinalPluralRule(num float64, v uint64) locales.PluralRule {
92	return locales.PluralRuleUnknown
93}
94
95// OrdinalPluralRule returns the ordinal PluralRule given 'num' and digits/precision of 'v' for 'ki'
96func (ki *ki) OrdinalPluralRule(num float64, v uint64) locales.PluralRule {
97	return locales.PluralRuleUnknown
98}
99
100// RangePluralRule returns the ordinal PluralRule given 'num1', 'num2' and digits/precision of 'v1' and 'v2' for 'ki'
101func (ki *ki) RangePluralRule(num1 float64, v1 uint64, num2 float64, v2 uint64) locales.PluralRule {
102	return locales.PluralRuleUnknown
103}
104
105// MonthAbbreviated returns the locales abbreviated month given the 'month' provided
106func (ki *ki) MonthAbbreviated(month time.Month) string {
107	return ki.monthsAbbreviated[month]
108}
109
110// MonthsAbbreviated returns the locales abbreviated months
111func (ki *ki) MonthsAbbreviated() []string {
112	return ki.monthsAbbreviated[1:]
113}
114
115// MonthNarrow returns the locales narrow month given the 'month' provided
116func (ki *ki) MonthNarrow(month time.Month) string {
117	return ki.monthsNarrow[month]
118}
119
120// MonthsNarrow returns the locales narrow months
121func (ki *ki) MonthsNarrow() []string {
122	return ki.monthsNarrow[1:]
123}
124
125// MonthWide returns the locales wide month given the 'month' provided
126func (ki *ki) MonthWide(month time.Month) string {
127	return ki.monthsWide[month]
128}
129
130// MonthsWide returns the locales wide months
131func (ki *ki) MonthsWide() []string {
132	return ki.monthsWide[1:]
133}
134
135// WeekdayAbbreviated returns the locales abbreviated weekday given the 'weekday' provided
136func (ki *ki) WeekdayAbbreviated(weekday time.Weekday) string {
137	return ki.daysAbbreviated[weekday]
138}
139
140// WeekdaysAbbreviated returns the locales abbreviated weekdays
141func (ki *ki) WeekdaysAbbreviated() []string {
142	return ki.daysAbbreviated
143}
144
145// WeekdayNarrow returns the locales narrow weekday given the 'weekday' provided
146func (ki *ki) WeekdayNarrow(weekday time.Weekday) string {
147	return ki.daysNarrow[weekday]
148}
149
150// WeekdaysNarrow returns the locales narrow weekdays
151func (ki *ki) WeekdaysNarrow() []string {
152	return ki.daysNarrow
153}
154
155// WeekdayShort returns the locales short weekday given the 'weekday' provided
156func (ki *ki) WeekdayShort(weekday time.Weekday) string {
157	return ki.daysShort[weekday]
158}
159
160// WeekdaysShort returns the locales short weekdays
161func (ki *ki) WeekdaysShort() []string {
162	return ki.daysShort
163}
164
165// WeekdayWide returns the locales wide weekday given the 'weekday' provided
166func (ki *ki) WeekdayWide(weekday time.Weekday) string {
167	return ki.daysWide[weekday]
168}
169
170// WeekdaysWide returns the locales wide weekdays
171func (ki *ki) WeekdaysWide() []string {
172	return ki.daysWide
173}
174
175// Decimal returns the decimal point of number
176func (ki *ki) Decimal() string {
177	return ki.decimal
178}
179
180// Group returns the group of number
181func (ki *ki) Group() string {
182	return ki.group
183}
184
185// Group returns the minus sign of number
186func (ki *ki) Minus() string {
187	return ki.minus
188}
189
190// FmtNumber returns 'num' with digits/precision of 'v' for 'ki' and handles both Whole and Real numbers based on 'v'
191func (ki *ki) FmtNumber(num float64, v uint64) string {
192
193	return strconv.FormatFloat(math.Abs(num), 'f', int(v), 64)
194}
195
196// FmtPercent returns 'num' with digits/precision of 'v' for 'ki' and handles both Whole and Real numbers based on 'v'
197// NOTE: 'num' passed into FmtPercent is assumed to be in percent already
198func (ki *ki) FmtPercent(num float64, v uint64) string {
199	return strconv.FormatFloat(math.Abs(num), 'f', int(v), 64)
200}
201
202// FmtCurrency returns the currency representation of 'num' with digits/precision of 'v' for 'ki'
203func (ki *ki) FmtCurrency(num float64, v uint64, currency currency.Type) string {
204
205	s := strconv.FormatFloat(math.Abs(num), 'f', int(v), 64)
206	symbol := ki.currencies[currency]
207	l := len(s) + len(symbol) + 0
208	count := 0
209	inWhole := v == 0
210	b := make([]byte, 0, l)
211
212	for i := len(s) - 1; i >= 0; i-- {
213
214		if s[i] == '.' {
215			b = append(b, ki.decimal[0])
216			inWhole = true
217			continue
218		}
219
220		if inWhole {
221			if count == 3 {
222				b = append(b, ki.group[0])
223				count = 1
224			} else {
225				count++
226			}
227		}
228
229		b = append(b, s[i])
230	}
231
232	for j := len(symbol) - 1; j >= 0; j-- {
233		b = append(b, symbol[j])
234	}
235
236	if num < 0 {
237		b = append(b, ki.minus[0])
238	}
239
240	// reverse
241	for i, j := 0, len(b)-1; i < j; i, j = i+1, j-1 {
242		b[i], b[j] = b[j], b[i]
243	}
244
245	if int(v) < 2 {
246
247		if v == 0 {
248			b = append(b, ki.decimal...)
249		}
250
251		for i := 0; i < 2-int(v); i++ {
252			b = append(b, '0')
253		}
254	}
255
256	return string(b)
257}
258
259// FmtAccounting returns the currency representation of 'num' with digits/precision of 'v' for 'ki'
260// in accounting notation.
261func (ki *ki) FmtAccounting(num float64, v uint64, currency currency.Type) string {
262
263	s := strconv.FormatFloat(math.Abs(num), 'f', int(v), 64)
264	symbol := ki.currencies[currency]
265	l := len(s) + len(symbol) + 2
266	count := 0
267	inWhole := v == 0
268	b := make([]byte, 0, l)
269
270	for i := len(s) - 1; i >= 0; i-- {
271
272		if s[i] == '.' {
273			b = append(b, ki.decimal[0])
274			inWhole = true
275			continue
276		}
277
278		if inWhole {
279			if count == 3 {
280				b = append(b, ki.group[0])
281				count = 1
282			} else {
283				count++
284			}
285		}
286
287		b = append(b, s[i])
288	}
289
290	if num < 0 {
291
292		for j := len(symbol) - 1; j >= 0; j-- {
293			b = append(b, symbol[j])
294		}
295
296		b = append(b, ki.currencyNegativePrefix[0])
297
298	} else {
299
300		for j := len(symbol) - 1; j >= 0; j-- {
301			b = append(b, symbol[j])
302		}
303
304	}
305
306	// reverse
307	for i, j := 0, len(b)-1; i < j; i, j = i+1, j-1 {
308		b[i], b[j] = b[j], b[i]
309	}
310
311	if int(v) < 2 {
312
313		if v == 0 {
314			b = append(b, ki.decimal...)
315		}
316
317		for i := 0; i < 2-int(v); i++ {
318			b = append(b, '0')
319		}
320	}
321
322	if num < 0 {
323		b = append(b, ki.currencyNegativeSuffix...)
324	}
325
326	return string(b)
327}
328
329// FmtDateShort returns the short date representation of 't' for 'ki'
330func (ki *ki) FmtDateShort(t time.Time) string {
331
332	b := make([]byte, 0, 32)
333
334	if t.Day() < 10 {
335		b = append(b, '0')
336	}
337
338	b = strconv.AppendInt(b, int64(t.Day()), 10)
339	b = append(b, []byte{0x2f}...)
340
341	if t.Month() < 10 {
342		b = append(b, '0')
343	}
344
345	b = strconv.AppendInt(b, int64(t.Month()), 10)
346
347	b = append(b, []byte{0x2f}...)
348
349	if t.Year() > 0 {
350		b = strconv.AppendInt(b, int64(t.Year()), 10)
351	} else {
352		b = strconv.AppendInt(b, int64(-t.Year()), 10)
353	}
354
355	return string(b)
356}
357
358// FmtDateMedium returns the medium date representation of 't' for 'ki'
359func (ki *ki) FmtDateMedium(t time.Time) string {
360
361	b := make([]byte, 0, 32)
362
363	b = strconv.AppendInt(b, int64(t.Day()), 10)
364	b = append(b, []byte{0x20}...)
365	b = append(b, ki.monthsAbbreviated[t.Month()]...)
366	b = append(b, []byte{0x20}...)
367
368	if t.Year() > 0 {
369		b = strconv.AppendInt(b, int64(t.Year()), 10)
370	} else {
371		b = strconv.AppendInt(b, int64(-t.Year()), 10)
372	}
373
374	return string(b)
375}
376
377// FmtDateLong returns the long date representation of 't' for 'ki'
378func (ki *ki) FmtDateLong(t time.Time) string {
379
380	b := make([]byte, 0, 32)
381
382	b = strconv.AppendInt(b, int64(t.Day()), 10)
383	b = append(b, []byte{0x20}...)
384	b = append(b, ki.monthsWide[t.Month()]...)
385	b = append(b, []byte{0x20}...)
386
387	if t.Year() > 0 {
388		b = strconv.AppendInt(b, int64(t.Year()), 10)
389	} else {
390		b = strconv.AppendInt(b, int64(-t.Year()), 10)
391	}
392
393	return string(b)
394}
395
396// FmtDateFull returns the full date representation of 't' for 'ki'
397func (ki *ki) FmtDateFull(t time.Time) string {
398
399	b := make([]byte, 0, 32)
400
401	b = append(b, ki.daysWide[t.Weekday()]...)
402	b = append(b, []byte{0x2c, 0x20}...)
403	b = strconv.AppendInt(b, int64(t.Day()), 10)
404	b = append(b, []byte{0x20}...)
405	b = append(b, ki.monthsWide[t.Month()]...)
406	b = append(b, []byte{0x20}...)
407
408	if t.Year() > 0 {
409		b = strconv.AppendInt(b, int64(t.Year()), 10)
410	} else {
411		b = strconv.AppendInt(b, int64(-t.Year()), 10)
412	}
413
414	return string(b)
415}
416
417// FmtTimeShort returns the short time representation of 't' for 'ki'
418func (ki *ki) FmtTimeShort(t time.Time) string {
419
420	b := make([]byte, 0, 32)
421
422	if t.Hour() < 10 {
423		b = append(b, '0')
424	}
425
426	b = strconv.AppendInt(b, int64(t.Hour()), 10)
427	b = append(b, ki.timeSeparator...)
428
429	if t.Minute() < 10 {
430		b = append(b, '0')
431	}
432
433	b = strconv.AppendInt(b, int64(t.Minute()), 10)
434
435	return string(b)
436}
437
438// FmtTimeMedium returns the medium time representation of 't' for 'ki'
439func (ki *ki) FmtTimeMedium(t time.Time) string {
440
441	b := make([]byte, 0, 32)
442
443	if t.Hour() < 10 {
444		b = append(b, '0')
445	}
446
447	b = strconv.AppendInt(b, int64(t.Hour()), 10)
448	b = append(b, ki.timeSeparator...)
449
450	if t.Minute() < 10 {
451		b = append(b, '0')
452	}
453
454	b = strconv.AppendInt(b, int64(t.Minute()), 10)
455	b = append(b, ki.timeSeparator...)
456
457	if t.Second() < 10 {
458		b = append(b, '0')
459	}
460
461	b = strconv.AppendInt(b, int64(t.Second()), 10)
462
463	return string(b)
464}
465
466// FmtTimeLong returns the long time representation of 't' for 'ki'
467func (ki *ki) FmtTimeLong(t time.Time) string {
468
469	b := make([]byte, 0, 32)
470
471	if t.Hour() < 10 {
472		b = append(b, '0')
473	}
474
475	b = strconv.AppendInt(b, int64(t.Hour()), 10)
476	b = append(b, ki.timeSeparator...)
477
478	if t.Minute() < 10 {
479		b = append(b, '0')
480	}
481
482	b = strconv.AppendInt(b, int64(t.Minute()), 10)
483	b = append(b, ki.timeSeparator...)
484
485	if t.Second() < 10 {
486		b = append(b, '0')
487	}
488
489	b = strconv.AppendInt(b, int64(t.Second()), 10)
490	b = append(b, []byte{0x20}...)
491
492	tz, _ := t.Zone()
493	b = append(b, tz...)
494
495	return string(b)
496}
497
498// FmtTimeFull returns the full time representation of 't' for 'ki'
499func (ki *ki) FmtTimeFull(t time.Time) string {
500
501	b := make([]byte, 0, 32)
502
503	if t.Hour() < 10 {
504		b = append(b, '0')
505	}
506
507	b = strconv.AppendInt(b, int64(t.Hour()), 10)
508	b = append(b, ki.timeSeparator...)
509
510	if t.Minute() < 10 {
511		b = append(b, '0')
512	}
513
514	b = strconv.AppendInt(b, int64(t.Minute()), 10)
515	b = append(b, ki.timeSeparator...)
516
517	if t.Second() < 10 {
518		b = append(b, '0')
519	}
520
521	b = strconv.AppendInt(b, int64(t.Second()), 10)
522	b = append(b, []byte{0x20}...)
523
524	tz, _ := t.Zone()
525
526	if btz, ok := ki.timezones[tz]; ok {
527		b = append(b, btz...)
528	} else {
529		b = append(b, tz...)
530	}
531
532	return string(b)
533}
534