afro-locale 0.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/API.md +390 -0
- package/CHANGELOG.md +73 -0
- package/CODE_OF_CONDUCT.md +96 -0
- package/CONTRIBUTING.md +351 -0
- package/EXAMPLES.md +327 -0
- package/LICENSE +21 -0
- package/README.md +431 -0
- package/SECURITY.md +84 -0
- package/SUPPORT.md +264 -0
- package/dist/index.d.ts +49 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +167 -0
- package/dist/index.js.map +1 -0
- package/package.json +61 -0
package/API.md
ADDED
|
@@ -0,0 +1,390 @@
|
|
|
1
|
+
# API Reference
|
|
2
|
+
|
|
3
|
+
Complete API reference for `@koadit/afro-locale`.
|
|
4
|
+
|
|
5
|
+
## Table of Contents
|
|
6
|
+
|
|
7
|
+
- [Classes](#classes)
|
|
8
|
+
- [Interfaces](#interfaces)
|
|
9
|
+
- [Enums & Constants](#enums--constants)
|
|
10
|
+
- [Singleton Instance](#singleton-instance)
|
|
11
|
+
- [Usage Patterns](#usage-patterns)
|
|
12
|
+
|
|
13
|
+
## Classes
|
|
14
|
+
|
|
15
|
+
### AfroLocale
|
|
16
|
+
|
|
17
|
+
Main class for handling localization.
|
|
18
|
+
|
|
19
|
+
```typescript
|
|
20
|
+
export class AfroLocale {
|
|
21
|
+
constructor();
|
|
22
|
+
|
|
23
|
+
// Locale Management
|
|
24
|
+
set(locale: string): void;
|
|
25
|
+
get(): string;
|
|
26
|
+
detectLocale(): string;
|
|
27
|
+
isLocaleSupported(locale: string): boolean;
|
|
28
|
+
|
|
29
|
+
// Formatting
|
|
30
|
+
formatCurrency(amount: number, currency: string): string;
|
|
31
|
+
formatNumber(value: number, options?: Intl.NumberFormatOptions): string;
|
|
32
|
+
formatDate(date: Date, style?: 'short' | 'long'): string;
|
|
33
|
+
formatTime(date: Date, style?: 'short' | 'long'): string;
|
|
34
|
+
formatDateTime(date: Date, style?: 'short' | 'long'): string;
|
|
35
|
+
|
|
36
|
+
// Language Information
|
|
37
|
+
getLanguageName(code: string): string;
|
|
38
|
+
getLanguageNativeName(code: string): string;
|
|
39
|
+
getSupportedLanguages(): LocaleConfig[];
|
|
40
|
+
getSupportedCurrencies(): string[];
|
|
41
|
+
}
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## Interfaces
|
|
45
|
+
|
|
46
|
+
### LocaleConfig
|
|
47
|
+
|
|
48
|
+
Configuration object for a supported locale.
|
|
49
|
+
|
|
50
|
+
```typescript
|
|
51
|
+
export interface LocaleConfig {
|
|
52
|
+
code: string; // Language code (e.g., 'yo', 'sw')
|
|
53
|
+
name: string; // English language name
|
|
54
|
+
nativeName: string; // Language name in native script
|
|
55
|
+
country?: string; // ISO 3166-1 alpha-2 country code
|
|
56
|
+
}
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
**Example:**
|
|
60
|
+
```typescript
|
|
61
|
+
{
|
|
62
|
+
code: 'yo',
|
|
63
|
+
name: 'Yoruba',
|
|
64
|
+
nativeName: 'Yorùbá',
|
|
65
|
+
country: 'NG'
|
|
66
|
+
}
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
### CurrencyFormat
|
|
70
|
+
|
|
71
|
+
Configuration for currency formatting.
|
|
72
|
+
|
|
73
|
+
```typescript
|
|
74
|
+
export interface CurrencyFormat {
|
|
75
|
+
symbol: string; // Currency symbol
|
|
76
|
+
position: 'left' | 'right'; // Symbol position relative to amount
|
|
77
|
+
decimals: number; // Number of decimal places
|
|
78
|
+
}
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
**Example:**
|
|
82
|
+
```typescript
|
|
83
|
+
{
|
|
84
|
+
symbol: '₦',
|
|
85
|
+
position: 'left',
|
|
86
|
+
decimals: 2
|
|
87
|
+
}
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
## Enums & Constants
|
|
91
|
+
|
|
92
|
+
### Supported Languages
|
|
93
|
+
|
|
94
|
+
```typescript
|
|
95
|
+
'am' | 'bn' | 'en' | 'ff' | 'ha' | 'ig' | 'ki' | 'ln' | 'lu' |
|
|
96
|
+
'mg' | 'ny' | 'om' | 'rw' | 'sn' | 'so' | 'st' | 'sw' | 'ti' |
|
|
97
|
+
'tn' | 'xh' | 'yo' | 'zu'
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
### Supported Currencies
|
|
101
|
+
|
|
102
|
+
```typescript
|
|
103
|
+
'ETB' | 'EUR' | 'GHS' | 'KES' | 'MWK' | 'NGN' | 'RWF' |
|
|
104
|
+
'TZS' | 'UGX' | 'USD' | 'XAF' | 'XOF' | 'ZAR' | 'ZMW'
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
### Format Styles
|
|
108
|
+
|
|
109
|
+
```typescript
|
|
110
|
+
type FormatStyle = 'short' | 'long';
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
## Singleton Instance
|
|
114
|
+
|
|
115
|
+
### locale
|
|
116
|
+
|
|
117
|
+
Pre-created singleton instance ready to use.
|
|
118
|
+
|
|
119
|
+
```typescript
|
|
120
|
+
export const locale: AfroLocale;
|
|
121
|
+
|
|
122
|
+
// Usage
|
|
123
|
+
import { locale } from '@koadit/afro-locale';
|
|
124
|
+
locale.set('yo');
|
|
125
|
+
locale.formatCurrency(5000, 'NGN');
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
### Creating Custom Instances
|
|
129
|
+
|
|
130
|
+
```typescript
|
|
131
|
+
import AfroLocale from '@koadit/afro-locale';
|
|
132
|
+
|
|
133
|
+
const locale1 = new AfroLocale();
|
|
134
|
+
const locale2 = new AfroLocale();
|
|
135
|
+
|
|
136
|
+
locale1.set('yo');
|
|
137
|
+
locale2.set('sw');
|
|
138
|
+
|
|
139
|
+
// Each instance maintains its own state
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
## Usage Patterns
|
|
143
|
+
|
|
144
|
+
### Pattern 1: Singleton Pattern
|
|
145
|
+
|
|
146
|
+
Best for most applications.
|
|
147
|
+
|
|
148
|
+
```typescript
|
|
149
|
+
import { locale } from '@koadit/afro-locale';
|
|
150
|
+
|
|
151
|
+
locale.set('yo');
|
|
152
|
+
const formatted = locale.formatCurrency(5000, 'NGN');
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
### Pattern 2: Instance Pattern
|
|
156
|
+
|
|
157
|
+
Use when you need to manage multiple independent locales.
|
|
158
|
+
|
|
159
|
+
```typescript
|
|
160
|
+
import AfroLocale from '@koadit/afro-locale';
|
|
161
|
+
|
|
162
|
+
const yoruba = new AfroLocale();
|
|
163
|
+
const swahili = new AfroLocale();
|
|
164
|
+
|
|
165
|
+
yoruba.set('yo');
|
|
166
|
+
swahili.set('sw');
|
|
167
|
+
|
|
168
|
+
console.log(yoruba.formatCurrency(5000, 'NGN'));
|
|
169
|
+
console.log(swahili.formatCurrency(5000, 'KES'));
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
### Pattern 3: Factory Pattern
|
|
173
|
+
|
|
174
|
+
Create a factory for managing locale instances.
|
|
175
|
+
|
|
176
|
+
```typescript
|
|
177
|
+
import AfroLocale from '@koadit/afro-locale';
|
|
178
|
+
|
|
179
|
+
class LocaleFactory {
|
|
180
|
+
private instances: Map<string, AfroLocale> = new Map();
|
|
181
|
+
|
|
182
|
+
getLocale(lang: string): AfroLocale {
|
|
183
|
+
if (!this.instances.has(lang)) {
|
|
184
|
+
const instance = new AfroLocale();
|
|
185
|
+
instance.set(lang);
|
|
186
|
+
this.instances.set(lang, instance);
|
|
187
|
+
}
|
|
188
|
+
return this.instances.get(lang)!;
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
const factory = new LocaleFactory();
|
|
193
|
+
const yoruba = factory.getLocale('yo');
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
### Pattern 4: Functional Wrapper
|
|
197
|
+
|
|
198
|
+
Create helper functions for common operations.
|
|
199
|
+
|
|
200
|
+
```typescript
|
|
201
|
+
import { locale } from '@koadit/afro-locale';
|
|
202
|
+
|
|
203
|
+
function formatPrice(price: number, lang: string, currency: string): string {
|
|
204
|
+
locale.set(lang);
|
|
205
|
+
return locale.formatCurrency(price, currency);
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
// Usage
|
|
209
|
+
formatPrice(5000, 'yo', 'NGN'); // ₦5,000.00
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
### Pattern 5: Locale Provider (React)
|
|
213
|
+
|
|
214
|
+
Managing locale in React applications.
|
|
215
|
+
|
|
216
|
+
```typescript
|
|
217
|
+
import React, { createContext, useContext, useState } from 'react';
|
|
218
|
+
import { locale } from '@koadit/afro-locale';
|
|
219
|
+
|
|
220
|
+
const LocaleContext = createContext<string>('en');
|
|
221
|
+
|
|
222
|
+
export function LocaleProvider({ children }) {
|
|
223
|
+
const [currentLocale, setCurrentLocale] = useState('en');
|
|
224
|
+
|
|
225
|
+
const handleSetLocale = (newLocale: string) => {
|
|
226
|
+
locale.set(newLocale);
|
|
227
|
+
setCurrentLocale(newLocale);
|
|
228
|
+
};
|
|
229
|
+
|
|
230
|
+
return (
|
|
231
|
+
<LocaleContext.Provider value={currentLocale}>
|
|
232
|
+
{children}
|
|
233
|
+
</LocaleContext.Provider>
|
|
234
|
+
);
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
export function useLocale() {
|
|
238
|
+
return useContext(LocaleContext);
|
|
239
|
+
}
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
### Pattern 6: Vue Composition API
|
|
243
|
+
|
|
244
|
+
Managing locale in Vue applications.
|
|
245
|
+
|
|
246
|
+
```typescript
|
|
247
|
+
import { ref, provide, inject } from 'vue';
|
|
248
|
+
import { locale } from '@koadit/afro-locale';
|
|
249
|
+
|
|
250
|
+
export function useLocale() {
|
|
251
|
+
const currentLocale = ref('en');
|
|
252
|
+
|
|
253
|
+
const setLocale = (newLocale: string) => {
|
|
254
|
+
locale.set(newLocale);
|
|
255
|
+
currentLocale.value = newLocale;
|
|
256
|
+
};
|
|
257
|
+
|
|
258
|
+
provide('locale', { currentLocale, setLocale });
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
export function useCurrentLocale() {
|
|
262
|
+
return inject('locale');
|
|
263
|
+
}
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
## Error Handling
|
|
267
|
+
|
|
268
|
+
### Handling Invalid Locale
|
|
269
|
+
|
|
270
|
+
```typescript
|
|
271
|
+
const locale = new AfroLocale();
|
|
272
|
+
|
|
273
|
+
if (locale.isLocaleSupported('xx')) {
|
|
274
|
+
locale.set('xx');
|
|
275
|
+
} else {
|
|
276
|
+
console.warn('Locale not supported, using English');
|
|
277
|
+
locale.set('en');
|
|
278
|
+
}
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
### Handling Invalid Currency
|
|
282
|
+
|
|
283
|
+
```typescript
|
|
284
|
+
try {
|
|
285
|
+
const formatted = locale.formatCurrency(5000, 'INVALID');
|
|
286
|
+
console.log(formatted); // "INVALID 5000.00"
|
|
287
|
+
} catch (error) {
|
|
288
|
+
console.error('Currency error:', error);
|
|
289
|
+
}
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
## Type Safety
|
|
293
|
+
|
|
294
|
+
### TypeScript
|
|
295
|
+
|
|
296
|
+
```typescript
|
|
297
|
+
import AfroLocale, { locale, LocaleConfig } from '@koadit/afro-locale';
|
|
298
|
+
|
|
299
|
+
// Type-safe locale setting
|
|
300
|
+
const supportedLocales: LocaleConfig[] = locale.getSupportedLanguages();
|
|
301
|
+
|
|
302
|
+
for (const config of supportedLocales) {
|
|
303
|
+
locale.set(config.code);
|
|
304
|
+
console.log(`${config.name}: ${config.nativeName}`);
|
|
305
|
+
}
|
|
306
|
+
```
|
|
307
|
+
|
|
308
|
+
## Performance Considerations
|
|
309
|
+
|
|
310
|
+
### Caching Formatted Values
|
|
311
|
+
|
|
312
|
+
```typescript
|
|
313
|
+
const cache = new Map<string, string>();
|
|
314
|
+
|
|
315
|
+
function getCachedFormatted(
|
|
316
|
+
amount: number,
|
|
317
|
+
currency: string,
|
|
318
|
+
lang: string
|
|
319
|
+
): string {
|
|
320
|
+
const key = `${amount}-${currency}-${lang}`;
|
|
321
|
+
|
|
322
|
+
if (cache.has(key)) {
|
|
323
|
+
return cache.get(key)!;
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
locale.set(lang);
|
|
327
|
+
const formatted = locale.formatCurrency(amount, currency);
|
|
328
|
+
cache.set(key, formatted);
|
|
329
|
+
|
|
330
|
+
return formatted;
|
|
331
|
+
}
|
|
332
|
+
```
|
|
333
|
+
|
|
334
|
+
### Lazy Locale Detection
|
|
335
|
+
|
|
336
|
+
```typescript
|
|
337
|
+
let detectedLocale: string | null = null;
|
|
338
|
+
|
|
339
|
+
function getDetectedLocale(): string {
|
|
340
|
+
if (detectedLocale === null) {
|
|
341
|
+
detectedLocale = locale.detectLocale();
|
|
342
|
+
}
|
|
343
|
+
return detectedLocale;
|
|
344
|
+
}
|
|
345
|
+
```
|
|
346
|
+
|
|
347
|
+
## Advanced Usage
|
|
348
|
+
|
|
349
|
+
### Internationalize Custom Objects
|
|
350
|
+
|
|
351
|
+
```typescript
|
|
352
|
+
interface Product {
|
|
353
|
+
name: string;
|
|
354
|
+
price: number;
|
|
355
|
+
currency: string;
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
function formatProduct(product: Product, lang: string): string {
|
|
359
|
+
locale.set(lang);
|
|
360
|
+
const formatted = locale.formatCurrency(product.price, product.currency);
|
|
361
|
+
return `${product.name}: ${formatted}`;
|
|
362
|
+
}
|
|
363
|
+
```
|
|
364
|
+
|
|
365
|
+
### Create Custom Formatter
|
|
366
|
+
|
|
367
|
+
```typescript
|
|
368
|
+
class CustomFormatter {
|
|
369
|
+
private locale: AfroLocale;
|
|
370
|
+
|
|
371
|
+
constructor(locale: AfroLocale) {
|
|
372
|
+
this.locale = locale;
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
formatPrice(amount: number, currency: string): string {
|
|
376
|
+
return `Price: ${this.locale.formatCurrency(amount, currency)}`;
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
formatEvent(date: Date): string {
|
|
380
|
+
return `Date: ${this.locale.formatDateTime(date)}`;
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
const formatter = new CustomFormatter(locale);
|
|
385
|
+
console.log(formatter.formatPrice(5000, 'NGN'));
|
|
386
|
+
```
|
|
387
|
+
|
|
388
|
+
---
|
|
389
|
+
|
|
390
|
+
For more examples, see [README.md](README.md) and check the test suite in `src/index.test.ts`.
|
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
## [0.1.0] - 2026-04-09
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
- Initial release of `@koadit/afro-locale`
|
|
13
|
+
- Support for 21+ African languages with native names and country codes
|
|
14
|
+
- West African: Yoruba, Hausa, Igbo, Bambara, Fulfulde
|
|
15
|
+
- East African: Swahili, Kikuyu, Oromo, Somali, Tigrinya
|
|
16
|
+
- Southern African: Zulu, Xhosa, Sotho, Tswana, Shona
|
|
17
|
+
- Central African: Lingala, Luba-Katanga
|
|
18
|
+
- Other: Amharic, Kinyarwanda, Chichewa, Malagasy, English
|
|
19
|
+
- Support for 14+ African currencies (NGN, KES, ZAR, ETB, UGX, XOF, XAF, etc.)
|
|
20
|
+
- Currency formatting with proper symbols and decimal places
|
|
21
|
+
- Number formatting with locale-specific separators
|
|
22
|
+
- Date and time localization
|
|
23
|
+
- Datetime formatting
|
|
24
|
+
- Automatic locale detection from browser navigator
|
|
25
|
+
- Language information methods (name, native name)
|
|
26
|
+
- Locale validation and normalization
|
|
27
|
+
- Full TypeScript support with interfaces and types
|
|
28
|
+
- ESM and CommonJS module support
|
|
29
|
+
- Comprehensive test suite (28+ test cases)
|
|
30
|
+
- ESLint configuration for code quality
|
|
31
|
+
- Jest configuration for testing
|
|
32
|
+
- Full API documentation in README
|
|
33
|
+
- Contributing guidelines
|
|
34
|
+
- Changelog
|
|
35
|
+
|
|
36
|
+
### Features
|
|
37
|
+
|
|
38
|
+
- **Multi-language Support**: 21+ African languages
|
|
39
|
+
- **Currency Formatting**: 14+ African currencies
|
|
40
|
+
- **Date/Time Localization**: Format dates, times, and datetimes
|
|
41
|
+
- **Locale Detection**: Automatic detection from browser
|
|
42
|
+
- **Zero Dependencies**: Built on native Web APIs
|
|
43
|
+
- **Type Safe**: Full TypeScript support
|
|
44
|
+
- **Well Tested**: 28+ unit tests with comprehensive coverage
|
|
45
|
+
- **ESM & CommonJS**: Works with both module systems
|
|
46
|
+
|
|
47
|
+
### Technical Details
|
|
48
|
+
|
|
49
|
+
- Built with TypeScript 5.4
|
|
50
|
+
- Jest for unit testing
|
|
51
|
+
- ESLint for code quality
|
|
52
|
+
- Automatic builds for both CJS and ESM
|
|
53
|
+
- Type definitions included
|
|
54
|
+
- Source maps for debugging
|
|
55
|
+
|
|
56
|
+
## Roadmap
|
|
57
|
+
|
|
58
|
+
### Planned for Future Releases
|
|
59
|
+
|
|
60
|
+
- [ ] Additional African languages
|
|
61
|
+
- [ ] Plural form handling
|
|
62
|
+
- [ ] Message translation support (i18n framework)
|
|
63
|
+
- [ ] Relative time formatting (e.g., "2 days ago")
|
|
64
|
+
- [ ] More currency support
|
|
65
|
+
- [ ] React hooks for locale management
|
|
66
|
+
- [ ] Vue composables for locale management
|
|
67
|
+
- [ ] CLI tools for batch translations
|
|
68
|
+
- [ ] Web component for language selector
|
|
69
|
+
- [ ] Locale persistence (localStorage/sessionStorage)
|
|
70
|
+
|
|
71
|
+
---
|
|
72
|
+
|
|
73
|
+
For migration information and breaking changes, please refer to the main README.
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
# Code of Conduct
|
|
2
|
+
|
|
3
|
+
## Our Commitment
|
|
4
|
+
|
|
5
|
+
We are committed to providing a welcoming and inspiring community for all. We expect all members of the community to adhere to this code of conduct in all spaces managed by the afro-locale project, including but not limited to:
|
|
6
|
+
|
|
7
|
+
- GitHub repositories
|
|
8
|
+
- Issue trackers
|
|
9
|
+
- Pull request discussions
|
|
10
|
+
- Community forums and discussions
|
|
11
|
+
- Social media channels
|
|
12
|
+
- Conferences and meetups
|
|
13
|
+
|
|
14
|
+
## Our Standards
|
|
15
|
+
|
|
16
|
+
Examples of behavior that contributes to creating a positive environment include:
|
|
17
|
+
|
|
18
|
+
- Using welcoming and inclusive language
|
|
19
|
+
- Being respectful of differing opinions, viewpoints, and experiences
|
|
20
|
+
- Gracefully accepting constructive criticism
|
|
21
|
+
- Focusing on what is best for the community
|
|
22
|
+
- Showing empathy towards other community members
|
|
23
|
+
- Encouraging and supporting new contributors
|
|
24
|
+
|
|
25
|
+
Examples of unacceptable behavior include:
|
|
26
|
+
|
|
27
|
+
- Harassment, bullying, or threatening language or gestures
|
|
28
|
+
- Discriminatory jokes and language
|
|
29
|
+
- Posting sexually explicit or violent material
|
|
30
|
+
- Posting (or threatening to post) others' personally identifying information ("doxing")
|
|
31
|
+
- Personal attacks or insults
|
|
32
|
+
- Unwelcome sexual attention
|
|
33
|
+
- Advocating for, or encouraging, any of the above behavior
|
|
34
|
+
- Sustained disruption of community spaces
|
|
35
|
+
|
|
36
|
+
## Scope
|
|
37
|
+
|
|
38
|
+
This Code of Conduct applies to all community spaces and extends to:
|
|
39
|
+
- Public repositories
|
|
40
|
+
- Private repositories
|
|
41
|
+
- Issues and pull requests
|
|
42
|
+
- Comments and discussions
|
|
43
|
+
- External channels and mailing lists
|
|
44
|
+
- Organizational events and gatherings
|
|
45
|
+
|
|
46
|
+
## Enforcement
|
|
47
|
+
|
|
48
|
+
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the community team at **conduct@koadit.com**. All complaints will be reviewed and investigated promptly and fairly.
|
|
49
|
+
|
|
50
|
+
### Reporting
|
|
51
|
+
|
|
52
|
+
If you are subject to or witness unacceptable behavior, or have any other concerns, please notify us by emailing **conduct@koadit.com** with:
|
|
53
|
+
|
|
54
|
+
- Your contact information
|
|
55
|
+
- Names (real or usernames) of any individuals involved
|
|
56
|
+
- Description of the incident
|
|
57
|
+
- Context and additional details
|
|
58
|
+
- Any evidence or screenshots
|
|
59
|
+
|
|
60
|
+
All report contents will be kept confidential and only shared with people who need to know to address the issue.
|
|
61
|
+
|
|
62
|
+
### Response
|
|
63
|
+
|
|
64
|
+
Community moderators are obligated to:
|
|
65
|
+
- Maintain confidentiality with respect to the reporter
|
|
66
|
+
- Review and investigate all complaints fairly
|
|
67
|
+
- Take appropriate action in response
|
|
68
|
+
|
|
69
|
+
### Consequences
|
|
70
|
+
|
|
71
|
+
Community members who violate this Code of Conduct may face:
|
|
72
|
+
- Warning and removal from community spaces
|
|
73
|
+
- Temporary or permanent ban from community spaces
|
|
74
|
+
- Removal of contributed content
|
|
75
|
+
- Action as determined by community moderators
|
|
76
|
+
|
|
77
|
+
## Appeals
|
|
78
|
+
|
|
79
|
+
If you feel a decision was made in error, you may appeal by emailing **conduct-appeal@koadit.com** with:
|
|
80
|
+
- Your appeal details
|
|
81
|
+
- Any additional context
|
|
82
|
+
- Reason why you believe the decision should be reconsidered
|
|
83
|
+
|
|
84
|
+
## Attribution
|
|
85
|
+
|
|
86
|
+
This Code of Conduct is adapted from:
|
|
87
|
+
- [Contributor Covenant](https://www.contributor-covenant.org/)
|
|
88
|
+
- [Fedora Community Code of Conduct](https://docs.fedoraproject.org/en-US/fedora/latest/code-of-conduct/)
|
|
89
|
+
|
|
90
|
+
## Questions?
|
|
91
|
+
|
|
92
|
+
If you have any questions about this Code of Conduct, please reach out to **conduct@koadit.com**.
|
|
93
|
+
|
|
94
|
+
---
|
|
95
|
+
|
|
96
|
+
Thank you for helping create a positive and inclusive community!
|