translations-api 1.0.0__tar.gz

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.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 CEDAR FORGE CONSULTANTS LLC
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,318 @@
1
+ Metadata-Version: 2.4
2
+ Name: translations-api
3
+ Version: 1.0.0
4
+ Summary: Python client for Translations API - Multi-language translation management with DeepL integration
5
+ Author-email: Translations API <support@translationsapi.com>
6
+ License: MIT
7
+ Project-URL: Homepage, https://translationsapi.com
8
+ Project-URL: Documentation, https://translationsapi.com/documentation.html
9
+ Project-URL: Repository, https://github.com/stephenhodgkiss/translations-api-python
10
+ Project-URL: Issues, https://github.com/stephenhodgkiss/translations-api-python/issues
11
+ Keywords: translation,i18n,localization,deepl,api,multi-language
12
+ Classifier: Development Status :: 4 - Beta
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: License :: OSI Approved :: MIT License
15
+ Classifier: Programming Language :: Python :: 3
16
+ Classifier: Programming Language :: Python :: 3.8
17
+ Classifier: Programming Language :: Python :: 3.9
18
+ Classifier: Programming Language :: Python :: 3.10
19
+ Classifier: Programming Language :: Python :: 3.11
20
+ Classifier: Programming Language :: Python :: 3.12
21
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
22
+ Classifier: Topic :: Software Development :: Internationalization
23
+ Requires-Python: >=3.8
24
+ Description-Content-Type: text/markdown
25
+ License-File: LICENSE
26
+ Requires-Dist: httpx>=0.24.0
27
+ Dynamic: license-file
28
+
29
+ # Translations API Python SDK
30
+
31
+ Python client for the Translations API - Multi-language translation management with DeepL integration.
32
+
33
+ ## Features
34
+
35
+ - **3-tier translation lookup**: User Custom Pool → Common Library → DeepL auto-translation
36
+ - **SHA256 hash-based O(1) string lookup** for efficient translation retrieval
37
+ - **Batch translation** for multiple texts and languages
38
+ - **Dictionary lookups** for complete language modules
39
+ - **User string management** with pagination support
40
+ - **Usage statistics** and quota monitoring
41
+ - **File upload** for bulk translation imports
42
+ - **Type-safe** with full type hints
43
+ - **Context manager support** for automatic resource cleanup
44
+
45
+ ## Installation
46
+
47
+ ```bash
48
+ pip install translations-api
49
+ ```
50
+
51
+ > Not yet on PyPI? Install straight from GitHub until it is listed:
52
+ >
53
+ > ```bash
54
+ > pip install git+https://github.com/stephenhodgkiss/translations-api-python.git
55
+ > ```
56
+
57
+ Or install from source:
58
+
59
+ ```bash
60
+ git clone https://github.com/stephenhodgkiss/translations-api-python.git
61
+ cd translations-api-python
62
+ pip install -e .
63
+ ```
64
+
65
+ ## Quick Start
66
+
67
+ ```python
68
+ from translations_api import TranslationClient
69
+
70
+ # Initialize the client
71
+ client = TranslationClient(api_key="your-api-key-here")
72
+
73
+ # Using context manager for automatic cleanup
74
+ with client:
75
+ # Translate a single text
76
+ translation = client.translate("Hello, world!", "de")
77
+ print(translation) # "Hallo, Welt!"
78
+
79
+ # Check if a string exists
80
+ exists = client.exists("Hello, world!")
81
+ print(exists) # True or False
82
+
83
+ # Translate or add if it doesn't exist
84
+ translation = client.translate_or_add("Welcome", "fr", use_deepl=True)
85
+ print(translation)
86
+ ```
87
+
88
+ ## Usage
89
+
90
+ ### Basic Translation
91
+
92
+ ```python
93
+ from translations_api import TranslationClient, ClientException
94
+
95
+ client = TranslationClient(api_key="your-api-key-here")
96
+
97
+ try:
98
+ # Translate to German
99
+ translation = client.translate("Hello, world!", "de")
100
+ print(translation)
101
+ except ClientException as e:
102
+ print(f"Error: {e}")
103
+ ```
104
+
105
+ ### Batch Translation
106
+
107
+ ```python
108
+ # Translate multiple texts to multiple languages
109
+ batch_result = client.batch(
110
+ texts=["Hello", "Goodbye", "Thank you"],
111
+ languages=["de", "fr", "es"],
112
+ use_deepl=False
113
+ )
114
+
115
+ for result in batch_result.results:
116
+ print(f"{result.source} -> {result.language}: {result.translation}")
117
+ ```
118
+
119
+ ### Dictionary Lookup
120
+
121
+ ```python
122
+ # Get complete dictionary for a language
123
+ dictionary = client.dictionary("de", module="yemchain")
124
+ print(f"Total translations: {dictionary.total}")
125
+
126
+ # Access translations
127
+ for source, translation in dictionary.translations.items():
128
+ print(f"{source} -> {translation}")
129
+ ```
130
+
131
+ ### User String Management
132
+
133
+ ```python
134
+ # Get user's stored strings with pagination
135
+ strings = client.get_my_strings(page=1, per_page=10)
136
+ print(f"Total strings: {strings.total}")
137
+
138
+ for user_string in strings.data:
139
+ print(f"ID: {user_string.id}, Text: {user_string.text}")
140
+ ```
141
+
142
+ ### Upload Strings
143
+
144
+ ```python
145
+ # Upload text strings
146
+ upload_result = client.upload_strings(
147
+ strings=["New string 1", "New string 2"],
148
+ auto_translate=False
149
+ )
150
+
151
+ print(f"Added: {upload_result.strings_added}")
152
+ print(f"Updated: {upload_result.strings_updated}")
153
+ print(f"Skipped: {upload_result.strings_skipped}")
154
+ ```
155
+
156
+ ### Upload Files
157
+
158
+ ```python
159
+ # Upload a translation file
160
+ upload_result = client.upload_file("translations.txt", format="txt")
161
+ print(f"Upload: {upload_result.message}")
162
+ ```
163
+
164
+ ### Usage Statistics
165
+
166
+ ```python
167
+ # Get usage statistics
168
+ usage = client.usage()
169
+ print(f"API calls: {usage.usage['api_calls']}")
170
+ print(f"Remaining: {usage.limits['api_calls_remaining']}")
171
+ print(f"Plan: {usage.plan['display_name']}")
172
+ ```
173
+
174
+ ### Error Handling
175
+
176
+ ```python
177
+ from translations_api import (
178
+ TranslationClient,
179
+ ClientException,
180
+ RateLimitException,
181
+ AuthenticationException,
182
+ QuotaExceededException,
183
+ )
184
+
185
+ client = TranslationClient(api_key="your-api-key-here")
186
+
187
+ try:
188
+ translation = client.translate("Hello", "de")
189
+ except RateLimitException as e:
190
+ print(f"Rate limit exceeded. Remaining: {e.get_remaining()}")
191
+ except AuthenticationException:
192
+ print("Invalid API key")
193
+ except QuotaExceededException:
194
+ print("Quota exceeded. Please upgrade your plan")
195
+ except ClientException as e:
196
+ print(f"Error: {e}")
197
+ ```
198
+
199
+ ### Configuration
200
+
201
+ ```python
202
+ client = TranslationClient(
203
+ api_key="your-api-key-here",
204
+ api_base_url="https://translationsapi.com/api/v1",
205
+ timeout=30
206
+ )
207
+
208
+ # Or configure after initialization
209
+ client.set_api_base_url("https://custom-api.com/api/v1")
210
+ client.set_timeout(60)
211
+ ```
212
+
213
+ ### Context Manager
214
+
215
+ ```python
216
+ # Using context manager for automatic cleanup
217
+ with TranslationClient(api_key="your-api-key-here") as client:
218
+ translation = client.translate("Hello", "de")
219
+ print(translation)
220
+
221
+ # Client is automatically closed
222
+ ```
223
+
224
+ ## API Reference
225
+
226
+ ### TranslationClient
227
+
228
+ #### Constructor
229
+
230
+ ```python
231
+ TranslationClient(
232
+ api_key: str,
233
+ api_base_url: str = "https://translationsapi.com/api/v1",
234
+ timeout: int = 30
235
+ )
236
+ ```
237
+
238
+ #### Methods
239
+
240
+ - `translate(text: str, language: str, use_deepl: bool = False) -> str`
241
+ - Translate a single text
242
+
243
+ - `exists(text: str) -> bool`
244
+ - Check if string exists in user's translation pool
245
+
246
+ - `translate_or_add(text: str, language: str, use_deepl: bool = True) -> str`
247
+ - Translate text or add it if it doesn't exist
248
+
249
+ - `batch(texts: List[str], languages: List[str], use_deepl: bool = False) -> BatchResult`
250
+ - Batch translate multiple texts
251
+
252
+ - `dictionary(language: str, module: Optional[str] = None) -> DictionaryResult`
253
+ - Get dictionary of translations for a language
254
+
255
+ - `upload_file(file_path: str, format: str = "txt") -> UploadResult`
256
+ - Upload a translation file
257
+
258
+ - `upload_strings(strings: List[str], auto_translate: bool = False) -> UploadTextResult`
259
+ - Upload text strings
260
+
261
+ - `get_my_strings(page: int = 1, per_page: int = 100) -> PaginatedStrings`
262
+ - Get user's stored strings
263
+
264
+ - `usage() -> UsageStats`
265
+ - Get usage statistics
266
+
267
+ - `get_last_response() -> Optional[Dict[str, Any]]`
268
+ - Get the last API response
269
+
270
+ - `get_last_status_code() -> Optional[int]`
271
+ - Get the last HTTP status code
272
+
273
+ - `set_api_base_url(api_base_url: str) -> TranslationClient`
274
+ - Set the API base URL
275
+
276
+ - `set_timeout(timeout: int) -> TranslationClient`
277
+ - Set the request timeout
278
+
279
+ - `close()`
280
+ - Close the HTTP client
281
+
282
+ ### Exceptions
283
+
284
+ - `ClientException` - Base exception for client errors
285
+ - `RateLimitException` - Raised when rate limit is exceeded
286
+ - `NetworkException` - Raised for network-related errors
287
+ - `ValidationException` - Raised for validation errors
288
+ - `AuthenticationException` - Raised for authentication errors
289
+ - `QuotaExceededException` - Raised when quota is exceeded
290
+
291
+ ### Types
292
+
293
+ - `TranslationResult` - Translation result from translate endpoint
294
+ - `BatchResult` - Batch translation result
295
+ - `ExistsResult` - Result from exists endpoint
296
+ - `UsageStats` - Usage statistics from usage endpoint
297
+ - `DictionaryResult` - Dictionary lookup result
298
+ - `UploadResult` - File upload result
299
+ - `UserString` - User's stored string
300
+ - `PaginatedStrings` - Paginated list of user strings
301
+ - `UserStats` - User statistics
302
+ - `UploadTextResult` - Text strings upload result
303
+ - `UploadTextRequest` - Request for uploading text strings
304
+
305
+ ## Requirements
306
+
307
+ - Python 3.8+
308
+ - httpx 0.24.0+
309
+
310
+ ## License
311
+
312
+ MIT License - see LICENSE file for details.
313
+
314
+ ## Support
315
+
316
+ - Documentation: https://translationsapi.com/documentation.html
317
+ - GitHub Issues: https://github.com/stephenhodgkiss/translations-api-python/issues
318
+ - Email: support@translationsapi.com
@@ -0,0 +1,290 @@
1
+ # Translations API Python SDK
2
+
3
+ Python client for the Translations API - Multi-language translation management with DeepL integration.
4
+
5
+ ## Features
6
+
7
+ - **3-tier translation lookup**: User Custom Pool → Common Library → DeepL auto-translation
8
+ - **SHA256 hash-based O(1) string lookup** for efficient translation retrieval
9
+ - **Batch translation** for multiple texts and languages
10
+ - **Dictionary lookups** for complete language modules
11
+ - **User string management** with pagination support
12
+ - **Usage statistics** and quota monitoring
13
+ - **File upload** for bulk translation imports
14
+ - **Type-safe** with full type hints
15
+ - **Context manager support** for automatic resource cleanup
16
+
17
+ ## Installation
18
+
19
+ ```bash
20
+ pip install translations-api
21
+ ```
22
+
23
+ > Not yet on PyPI? Install straight from GitHub until it is listed:
24
+ >
25
+ > ```bash
26
+ > pip install git+https://github.com/stephenhodgkiss/translations-api-python.git
27
+ > ```
28
+
29
+ Or install from source:
30
+
31
+ ```bash
32
+ git clone https://github.com/stephenhodgkiss/translations-api-python.git
33
+ cd translations-api-python
34
+ pip install -e .
35
+ ```
36
+
37
+ ## Quick Start
38
+
39
+ ```python
40
+ from translations_api import TranslationClient
41
+
42
+ # Initialize the client
43
+ client = TranslationClient(api_key="your-api-key-here")
44
+
45
+ # Using context manager for automatic cleanup
46
+ with client:
47
+ # Translate a single text
48
+ translation = client.translate("Hello, world!", "de")
49
+ print(translation) # "Hallo, Welt!"
50
+
51
+ # Check if a string exists
52
+ exists = client.exists("Hello, world!")
53
+ print(exists) # True or False
54
+
55
+ # Translate or add if it doesn't exist
56
+ translation = client.translate_or_add("Welcome", "fr", use_deepl=True)
57
+ print(translation)
58
+ ```
59
+
60
+ ## Usage
61
+
62
+ ### Basic Translation
63
+
64
+ ```python
65
+ from translations_api import TranslationClient, ClientException
66
+
67
+ client = TranslationClient(api_key="your-api-key-here")
68
+
69
+ try:
70
+ # Translate to German
71
+ translation = client.translate("Hello, world!", "de")
72
+ print(translation)
73
+ except ClientException as e:
74
+ print(f"Error: {e}")
75
+ ```
76
+
77
+ ### Batch Translation
78
+
79
+ ```python
80
+ # Translate multiple texts to multiple languages
81
+ batch_result = client.batch(
82
+ texts=["Hello", "Goodbye", "Thank you"],
83
+ languages=["de", "fr", "es"],
84
+ use_deepl=False
85
+ )
86
+
87
+ for result in batch_result.results:
88
+ print(f"{result.source} -> {result.language}: {result.translation}")
89
+ ```
90
+
91
+ ### Dictionary Lookup
92
+
93
+ ```python
94
+ # Get complete dictionary for a language
95
+ dictionary = client.dictionary("de", module="yemchain")
96
+ print(f"Total translations: {dictionary.total}")
97
+
98
+ # Access translations
99
+ for source, translation in dictionary.translations.items():
100
+ print(f"{source} -> {translation}")
101
+ ```
102
+
103
+ ### User String Management
104
+
105
+ ```python
106
+ # Get user's stored strings with pagination
107
+ strings = client.get_my_strings(page=1, per_page=10)
108
+ print(f"Total strings: {strings.total}")
109
+
110
+ for user_string in strings.data:
111
+ print(f"ID: {user_string.id}, Text: {user_string.text}")
112
+ ```
113
+
114
+ ### Upload Strings
115
+
116
+ ```python
117
+ # Upload text strings
118
+ upload_result = client.upload_strings(
119
+ strings=["New string 1", "New string 2"],
120
+ auto_translate=False
121
+ )
122
+
123
+ print(f"Added: {upload_result.strings_added}")
124
+ print(f"Updated: {upload_result.strings_updated}")
125
+ print(f"Skipped: {upload_result.strings_skipped}")
126
+ ```
127
+
128
+ ### Upload Files
129
+
130
+ ```python
131
+ # Upload a translation file
132
+ upload_result = client.upload_file("translations.txt", format="txt")
133
+ print(f"Upload: {upload_result.message}")
134
+ ```
135
+
136
+ ### Usage Statistics
137
+
138
+ ```python
139
+ # Get usage statistics
140
+ usage = client.usage()
141
+ print(f"API calls: {usage.usage['api_calls']}")
142
+ print(f"Remaining: {usage.limits['api_calls_remaining']}")
143
+ print(f"Plan: {usage.plan['display_name']}")
144
+ ```
145
+
146
+ ### Error Handling
147
+
148
+ ```python
149
+ from translations_api import (
150
+ TranslationClient,
151
+ ClientException,
152
+ RateLimitException,
153
+ AuthenticationException,
154
+ QuotaExceededException,
155
+ )
156
+
157
+ client = TranslationClient(api_key="your-api-key-here")
158
+
159
+ try:
160
+ translation = client.translate("Hello", "de")
161
+ except RateLimitException as e:
162
+ print(f"Rate limit exceeded. Remaining: {e.get_remaining()}")
163
+ except AuthenticationException:
164
+ print("Invalid API key")
165
+ except QuotaExceededException:
166
+ print("Quota exceeded. Please upgrade your plan")
167
+ except ClientException as e:
168
+ print(f"Error: {e}")
169
+ ```
170
+
171
+ ### Configuration
172
+
173
+ ```python
174
+ client = TranslationClient(
175
+ api_key="your-api-key-here",
176
+ api_base_url="https://translationsapi.com/api/v1",
177
+ timeout=30
178
+ )
179
+
180
+ # Or configure after initialization
181
+ client.set_api_base_url("https://custom-api.com/api/v1")
182
+ client.set_timeout(60)
183
+ ```
184
+
185
+ ### Context Manager
186
+
187
+ ```python
188
+ # Using context manager for automatic cleanup
189
+ with TranslationClient(api_key="your-api-key-here") as client:
190
+ translation = client.translate("Hello", "de")
191
+ print(translation)
192
+
193
+ # Client is automatically closed
194
+ ```
195
+
196
+ ## API Reference
197
+
198
+ ### TranslationClient
199
+
200
+ #### Constructor
201
+
202
+ ```python
203
+ TranslationClient(
204
+ api_key: str,
205
+ api_base_url: str = "https://translationsapi.com/api/v1",
206
+ timeout: int = 30
207
+ )
208
+ ```
209
+
210
+ #### Methods
211
+
212
+ - `translate(text: str, language: str, use_deepl: bool = False) -> str`
213
+ - Translate a single text
214
+
215
+ - `exists(text: str) -> bool`
216
+ - Check if string exists in user's translation pool
217
+
218
+ - `translate_or_add(text: str, language: str, use_deepl: bool = True) -> str`
219
+ - Translate text or add it if it doesn't exist
220
+
221
+ - `batch(texts: List[str], languages: List[str], use_deepl: bool = False) -> BatchResult`
222
+ - Batch translate multiple texts
223
+
224
+ - `dictionary(language: str, module: Optional[str] = None) -> DictionaryResult`
225
+ - Get dictionary of translations for a language
226
+
227
+ - `upload_file(file_path: str, format: str = "txt") -> UploadResult`
228
+ - Upload a translation file
229
+
230
+ - `upload_strings(strings: List[str], auto_translate: bool = False) -> UploadTextResult`
231
+ - Upload text strings
232
+
233
+ - `get_my_strings(page: int = 1, per_page: int = 100) -> PaginatedStrings`
234
+ - Get user's stored strings
235
+
236
+ - `usage() -> UsageStats`
237
+ - Get usage statistics
238
+
239
+ - `get_last_response() -> Optional[Dict[str, Any]]`
240
+ - Get the last API response
241
+
242
+ - `get_last_status_code() -> Optional[int]`
243
+ - Get the last HTTP status code
244
+
245
+ - `set_api_base_url(api_base_url: str) -> TranslationClient`
246
+ - Set the API base URL
247
+
248
+ - `set_timeout(timeout: int) -> TranslationClient`
249
+ - Set the request timeout
250
+
251
+ - `close()`
252
+ - Close the HTTP client
253
+
254
+ ### Exceptions
255
+
256
+ - `ClientException` - Base exception for client errors
257
+ - `RateLimitException` - Raised when rate limit is exceeded
258
+ - `NetworkException` - Raised for network-related errors
259
+ - `ValidationException` - Raised for validation errors
260
+ - `AuthenticationException` - Raised for authentication errors
261
+ - `QuotaExceededException` - Raised when quota is exceeded
262
+
263
+ ### Types
264
+
265
+ - `TranslationResult` - Translation result from translate endpoint
266
+ - `BatchResult` - Batch translation result
267
+ - `ExistsResult` - Result from exists endpoint
268
+ - `UsageStats` - Usage statistics from usage endpoint
269
+ - `DictionaryResult` - Dictionary lookup result
270
+ - `UploadResult` - File upload result
271
+ - `UserString` - User's stored string
272
+ - `PaginatedStrings` - Paginated list of user strings
273
+ - `UserStats` - User statistics
274
+ - `UploadTextResult` - Text strings upload result
275
+ - `UploadTextRequest` - Request for uploading text strings
276
+
277
+ ## Requirements
278
+
279
+ - Python 3.8+
280
+ - httpx 0.24.0+
281
+
282
+ ## License
283
+
284
+ MIT License - see LICENSE file for details.
285
+
286
+ ## Support
287
+
288
+ - Documentation: https://translationsapi.com/documentation.html
289
+ - GitHub Issues: https://github.com/stephenhodgkiss/translations-api-python/issues
290
+ - Email: support@translationsapi.com
@@ -0,0 +1,50 @@
1
+ [build-system]
2
+ requires = ["setuptools>=61.0", "wheel"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "translations-api"
7
+ version = "1.0.0"
8
+ description = "Python client for Translations API - Multi-language translation management with DeepL integration"
9
+ readme = "README.md"
10
+ requires-python = ">=3.8"
11
+ license = {text = "MIT"}
12
+ authors = [
13
+ {name = "Translations API", email = "support@translationsapi.com"}
14
+ ]
15
+ keywords = [
16
+ "translation",
17
+ "i18n",
18
+ "localization",
19
+ "deepl",
20
+ "api",
21
+ "multi-language"
22
+ ]
23
+ classifiers = [
24
+ "Development Status :: 4 - Beta",
25
+ "Intended Audience :: Developers",
26
+ "License :: OSI Approved :: MIT License",
27
+ "Programming Language :: Python :: 3",
28
+ "Programming Language :: Python :: 3.8",
29
+ "Programming Language :: Python :: 3.9",
30
+ "Programming Language :: Python :: 3.10",
31
+ "Programming Language :: Python :: 3.11",
32
+ "Programming Language :: Python :: 3.12",
33
+ "Topic :: Software Development :: Libraries :: Python Modules",
34
+ "Topic :: Software Development :: Internationalization",
35
+ ]
36
+ dependencies = [
37
+ "httpx>=0.24.0",
38
+ ]
39
+
40
+ [project.urls]
41
+ Homepage = "https://translationsapi.com"
42
+ Documentation = "https://translationsapi.com/documentation.html"
43
+ Repository = "https://github.com/stephenhodgkiss/translations-api-python"
44
+ Issues = "https://github.com/stephenhodgkiss/translations-api-python/issues"
45
+
46
+ [tool.setuptools.packages.find]
47
+ where = ["src"]
48
+
49
+ [tool.setuptools.package-data]
50
+ "*" = ["py.typed"]
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+