miki-template 2.3.1 → 2.3.3

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.
Files changed (167) hide show
  1. package/README.md +1 -1
  2. package/package.json +24 -2
  3. package/src/codegen.js +140 -9
  4. package/src/parser.js +69 -1
  5. package/src/tags/control.js +112 -51
  6. package/src/tags/extra.js +4 -17
  7. package/src/tags/i18n.js +6 -17
  8. package/src/tags/inheritance.js +6 -20
  9. package/src/tags/util.js +5 -20
  10. package/.eslintrc.json +0 -16
  11. package/.github/release-notes/v1.3.1.md +0 -55
  12. package/.github/release-notes/v1.3.3.md +0 -77
  13. package/.github/release-notes/v1.3.7.md +0 -20
  14. package/.github/workflows/ci.yml +0 -42
  15. package/.github/workflows/docs.yml +0 -107
  16. package/.github/workflows/release.yml +0 -107
  17. package/AGENT.md +0 -71
  18. package/API_REFERENCE.md +0 -341
  19. package/CHANGELOG.md +0 -173
  20. package/CODE_OF_CONDUCT.md +0 -14
  21. package/CONTRIBUTING.md +0 -27
  22. package/ROADMAP.md +0 -40
  23. package/assets/banner.png +0 -0
  24. package/assets/logo.png +0 -0
  25. package/benchmarks/ejs-results.json +0 -17
  26. package/benchmarks/ejs.js +0 -38
  27. package/benchmarks/handlebars-results.json +0 -17
  28. package/benchmarks/handlebars.js +0 -45
  29. package/benchmarks/miki-results.json +0 -17
  30. package/benchmarks/miki.js +0 -39
  31. package/benchmarks/pug-results.json +0 -17
  32. package/benchmarks/pug.js +0 -38
  33. package/benchmarks/report.json +0 -17
  34. package/benchmarks/run.js +0 -81
  35. package/benchmarks/stress.mjs +0 -647
  36. package/benchmarks/templates/large.dtpl +0 -7
  37. package/benchmarks/templates/medium.dtpl +0 -3
  38. package/benchmarks/templates/small.dtpl +0 -7
  39. package/context/component.md +0 -109
  40. package/context/prd.md +0 -131
  41. package/context/project-structure.md +0 -33
  42. package/dir/base.html +0 -23
  43. package/dir/cmpnt.html +0 -11
  44. package/dir/footer.html +0 -3
  45. package/dir/home.html +0 -80
  46. package/dir/index.html +0 -80
  47. package/dir/navbar.html +0 -9
  48. package/docs/api/async-render.md +0 -170
  49. package/docs/api/cache.md +0 -174
  50. package/docs/api/compile.md +0 -256
  51. package/docs/api/context-processors.md +0 -154
  52. package/docs/api/filters.md +0 -437
  53. package/docs/api/finder.md +0 -188
  54. package/docs/api/helpers.md +0 -106
  55. package/docs/api/i18n.md +0 -314
  56. package/docs/api/index.md +0 -108
  57. package/docs/api/libraries.md +0 -414
  58. package/docs/api/render-partial.md +0 -162
  59. package/docs/api/render.md +0 -184
  60. package/docs/api/security.md +0 -290
  61. package/docs/api/setup-express.md +0 -152
  62. package/docs/api/tags.md +0 -268
  63. package/docs/assets/banner.png +0 -0
  64. package/docs/assets/logo.png +0 -0
  65. package/docs/filter.md +0 -0
  66. package/docs/guide/advanced-usage.md +0 -794
  67. package/docs/guide/async-rendering.md +0 -616
  68. package/docs/guide/context-processors.md +0 -514
  69. package/docs/guide/custom-filters.md +0 -622
  70. package/docs/guide/custom-tags.md +0 -542
  71. package/docs/guide/filters.md +0 -1314
  72. package/docs/guide/getting-started.md +0 -204
  73. package/docs/guide/installation.md +0 -190
  74. package/docs/guide/partial-templates.md +0 -734
  75. package/docs/guide/quick-start.md +0 -444
  76. package/docs/guide/security.md +0 -690
  77. package/docs/guide/tags.md +0 -1566
  78. package/docs/guide/template-discovery.md +0 -340
  79. package/docs/guide/template-inheritance.md +0 -546
  80. package/docs/guide/what-is-miki-template.md +0 -28
  81. package/docs/guide/why-miki-template.md +0 -75
  82. package/docs/index.md +0 -86
  83. package/docs/integrations/elysia.md +0 -80
  84. package/docs/integrations/express.md +0 -219
  85. package/docs/integrations/fastify.md +0 -79
  86. package/docs/integrations/hono.md +0 -80
  87. package/docs/integrations/index.md +0 -68
  88. package/docs/integrations/koa.md +0 -90
  89. package/docs/integrations/nestjs.md +0 -80
  90. package/docs/integrations/tsed.md +0 -83
  91. package/docs/performance.md +0 -74
  92. package/eslint.config.mjs +0 -42
  93. package/ex.mjs +0 -36
  94. package/live-test/integrations/elysia-example.js +0 -16
  95. package/live-test/integrations/express-example.js +0 -24
  96. package/live-test/integrations/fastify-example.js +0 -20
  97. package/live-test/integrations/hono-example.js +0 -16
  98. package/live-test/integrations/koa-example.js +0 -30
  99. package/live-test/integrations/nestjs-example.js +0 -25
  100. package/live-test/integrations/smoke-test.js +0 -166
  101. package/live-test/integrations/tsed-example.js +0 -23
  102. package/live-test/package-lock.json +0 -1150
  103. package/live-test/package.json +0 -13
  104. package/live-test/packages/product/templates/product/detail.html +0 -7
  105. package/live-test/server.js +0 -38
  106. package/live-test/templates/app_templates/detail.html +0 -6
  107. package/live-test/views/base.html +0 -8
  108. package/live-test/views/child.html +0 -7
  109. package/live-test/views/home.html +0 -17
  110. package/live-test/views/index.html +0 -1
  111. package/miki-template-extension/.github/workflows/ci.yml +0 -116
  112. package/miki-template-extension/.vscodeignore +0 -7
  113. package/miki-template-extension/CHANGELOG.md +0 -99
  114. package/miki-template-extension/LICENSE +0 -21
  115. package/miki-template-extension/README.md +0 -273
  116. package/miki-template-extension/extension.js +0 -1013
  117. package/miki-template-extension/icon.png +0 -0
  118. package/miki-template-extension/icon.svg +0 -10
  119. package/miki-template-extension/miki-template-1.7.1.vsix +0 -0
  120. package/miki-template-extension/package.json +0 -280
  121. package/miki-template-extension/snippets/miki-template.json +0 -717
  122. package/miki-template-extension/syntaxes/language-configuration.json +0 -114
  123. package/miki-template-extension/syntaxes/miki-template.tmLanguage.json +0 -355
  124. package/miki-template-extension/tests/grammar-tests.json +0 -162
  125. package/miki-template-extension/tests/run-grammar-tests.js +0 -82
  126. package/mkdocs.yml +0 -195
  127. package/overrides/main.html +0 -26
  128. package/requirements-docs.txt +0 -2
  129. package/sample-app/package-lock.json +0 -901
  130. package/sample-app/package.json +0 -9
  131. package/sample-app/server.js +0 -14
  132. package/sample-app/views/index.html +0 -1
  133. package/scripts/build-vsix.js +0 -129
  134. package/scripts/build-vsix.ps1 +0 -15
  135. package/snippets/miki-template.json +0 -177
  136. package/src/asyncRender.js +0 -21
  137. package/src/types.d.ts +0 -107
  138. package/syntaxes/language-configuration.json +0 -26
  139. package/syntaxes/miki-template.tmLanguage.json +0 -146
  140. package/tests/asyncRender.test.js +0 -17
  141. package/tests/base.html +0 -6
  142. package/tests/child.html +0 -3
  143. package/tests/context_processors.test.js +0 -13
  144. package/tests/esm.test.mjs +0 -61
  145. package/tests/filters.test.js +0 -263
  146. package/tests/finder-appdirs.test.js +0 -19
  147. package/tests/finder.test.js +0 -17
  148. package/tests/fixtures/views/nested/index.html +0 -1
  149. package/tests/fixtures/views/partial.html +0 -1
  150. package/tests/fixtures/views/sub/deepfile.html +0 -1
  151. package/tests/fixtures/views-appdirs/product/site/detail.html +0 -1
  152. package/tests/include_security.test.js +0 -9
  153. package/tests/integration/README.md +0 -32
  154. package/tests/integration/features.test.cjs +0 -1681
  155. package/tests/integration/features.test.mjs +0 -1697
  156. package/tests/integration/finder.esm.test.mjs +0 -13
  157. package/tests/integration/partial-render.test.cjs +0 -13
  158. package/tests/integration/templates/base.miki +0 -6
  159. package/tests/integration/templates/child.miki +0 -6
  160. package/tests/integration/templates/index.html +0 -17
  161. package/tests/lexer.test.js +0 -45
  162. package/tests/parser.test.js +0 -57
  163. package/tests/partial.html +0 -1
  164. package/tests/partialdef.test.js +0 -79
  165. package/tests/production_checks.js +0 -57
  166. package/tests/security.test.js +0 -28
  167. package/tests/tags.test.js +0 -233
@@ -1,437 +0,0 @@
1
- # Filters API
2
-
3
-
4
-
5
- ## registerFilter
6
-
7
-
8
-
9
- Register a custom filter callable from templates as `{{ value|filter_name:arg }}`.
10
-
11
-
12
-
13
- === "CommonJS"
14
-
15
-
16
-
17
- ```javascript
18
-
19
- const { registerFilter } = require('miki-template');
20
-
21
-
22
-
23
- registerFilter('reverse', (val) => {
24
-
25
- return String(val).split('').reverse().join('');
26
-
27
- });
28
-
29
- ```
30
-
31
-
32
-
33
- === "ES Modules"
34
-
35
-
36
-
37
- ```javascript
38
-
39
- import { registerFilter } from 'miki-template';
40
-
41
-
42
-
43
- registerFilter('reverse', (val) => {
44
-
45
- return String(val).split('').reverse().join('');
46
-
47
- });
48
-
49
- ```
50
-
51
-
52
-
53
- ### Filter Signature
54
-
55
-
56
-
57
- Filters receive `(value, argument, context)` and must return a string (or `SafeString`):
58
-
59
-
60
-
61
- ```javascript
62
-
63
- registerFilter('greet', (val, greeting, context) => {
64
-
65
- return `${greeting}, ${val}!`;
66
-
67
- });
68
-
69
- ```
70
-
71
-
72
-
73
- ### Async Filters
74
-
75
-
76
-
77
- Filters that return a Promise are awaited automatically when using `asyncRender()`:
78
-
79
-
80
-
81
- === "CommonJS"
82
-
83
-
84
-
85
- ```javascript
86
-
87
- const { registerFilter, asyncRender } = require('miki-template');
88
-
89
-
90
-
91
- registerFilter('fetch_data', async (url) => {
92
-
93
- const res = await fetch(url);
94
-
95
- return res.text();
96
-
97
- });
98
-
99
-
100
-
101
- const html = await asyncRender('{{ endpoint|fetch_data }}', {
102
-
103
- endpoint: 'https://api.example.com/data'
104
-
105
- });
106
-
107
- ```
108
-
109
-
110
-
111
- === "ES Modules"
112
-
113
-
114
-
115
- ```javascript
116
-
117
- import { registerFilter, asyncRender } from 'miki-template';
118
-
119
-
120
-
121
- registerFilter('fetch_data', async (url) => {
122
-
123
- const res = await fetch(url);
124
-
125
- return res.text();
126
-
127
- });
128
-
129
-
130
-
131
- const html = await asyncRender('{{ endpoint|fetch_data }}', {
132
-
133
- endpoint: 'https://api.example.com/data'
134
-
135
- });
136
-
137
- ```
138
-
139
-
140
-
141
- ## getFilter
142
-
143
-
144
-
145
- Retrieve a registered filter by name.
146
-
147
-
148
-
149
- === "CommonJS"
150
-
151
-
152
-
153
- ```javascript
154
-
155
- const { getFilter } = require('miki-template);
156
-
157
-
158
-
159
- const reverseFilter = getFilter('reverse');
160
-
161
- console.log(reverseFilter('hello')); // 'olleh'
162
-
163
- ```
164
-
165
-
166
-
167
- === "ES Modules"
168
-
169
-
170
-
171
- ```javascript
172
-
173
- import { getFilter } from 'miki-template';
174
-
175
-
176
-
177
- const reverseFilter = getFilter('reverse');
178
-
179
- ```
180
-
181
-
182
-
183
- ## Built-in Filters
184
-
185
-
186
-
187
- ### Text Filters
188
-
189
-
190
-
191
- | Filter | Description |
192
-
193
- |--------|-------------|
194
-
195
- | `upper` | Uppercase |
196
-
197
- | `lower` | Lowercase |
198
-
199
- | `title` | Title case |
200
-
201
- | `capfirst` | Capitalize first character |
202
-
203
- | `truncatewords:N` | Truncate to N words |
204
-
205
- | `truncatechars:N` | Truncate to N characters (ellipsis) |
206
-
207
- | `truncatechars_html:N` | Truncate to N chars, preserving HTML |
208
-
209
- | `wordcount` | Count words |
210
-
211
- | `repeat` | Repeat a string N times |
212
- | `range` | Generate a range of integers |
213
- | `striptags` | Remove HTML tags |
214
-
215
-
216
- | `slugify` | Convert to URL-friendly slug |
217
-
218
- | `linebreaks` | Convert newlines to `<br>` and `<p>` |
219
-
220
- | `linebreaksbr` | Convert newlines to `<br>` |
221
-
222
- | `length_is:N` | Return length if equals N, else empty |
223
-
224
-
225
-
226
- ### HTML Filters
227
-
228
-
229
-
230
- | Filter | Description |
231
-
232
- |--------|-------------|
233
-
234
- | `safe` | Mark as safe (no escaping) |
235
-
236
- | `escape` | Force HTML escaping |
237
-
238
-
239
-
240
- ### List Filters
241
-
242
-
243
-
244
- | Filter | Description |
245
-
246
- |--------|-------------|
247
-
248
- | `length` | Number of items |
249
-
250
- | `join:sep` | Join items with separator |
251
-
252
- | `slice:"start:end"` | Slice a list/string |
253
-
254
- | `dictsort:"key"` | Sort by key (ascending) |
255
-
256
- | `dictsortreversed:"key"` | Sort by key (descending) |
257
-
258
- | `sort` | Sort items |
259
-
260
- | `unique` | Remove duplicates |
261
-
262
- | `random` | Random item |
263
-
264
- | `reverse` | Reverse order |
265
-
266
- | `split:sep` | Split string into list |
267
-
268
- | `replace:"old,new"` | Replace occurrences |
269
-
270
-
271
-
272
- ### Default Filters
273
-
274
-
275
-
276
- | Filter | Description |
277
-
278
- |--------|-------------|
279
-
280
- | `default:"fallback"` | Show fallback if value is falsy |
281
-
282
- | `default_if_none:"fallback"` | Show fallback if value is `null`/`undefined` |
283
-
284
- | `firstof:v1 v2 v3` | First non-empty value |
285
-
286
-
287
-
288
- ### Date/Time Filters
289
-
290
-
291
-
292
- | Filter | Description |
293
-
294
- |--------|-------------|
295
-
296
- | `date:"Y-m-d"` | Django-style date format |
297
-
298
- | `time:"H:i"` | Django-style time format |
299
-
300
- | `date_format:"yyyy-MM-dd"` | Intl-style date format |
301
-
302
- | `strftime:"PPPP"` | Intl-style time format |
303
-
304
- | `timesince` | Time since date ("2 hours ago") |
305
-
306
- | `timeuntil` | Time until date |
307
-
308
- | `ago` | Short time-ago ("2m", "3h") |
309
-
310
- | `until` | Short time-until |
311
-
312
- | `time_diff:other_date` | Difference between two dates |
313
-
314
-
315
-
316
- ### Numeric Filters
317
-
318
-
319
-
320
- | Filter | Description |
321
-
322
- |--------|-------------|
323
-
324
- | `add:N` | Add N |
325
-
326
- | `sub:N` | Subtract N |
327
-
328
- | `mult:N` | Multiply by N |
329
-
330
- | `divisibleby:N` | Check divisibility |
331
-
332
- | `mod:N` | Modulo |
333
-
334
- | `floatformat:N` | Format float with N decimals |
335
-
336
- | `square` | Square a number |
337
-
338
- | `sqrt` | Square root |
339
-
340
- | `abs` | Absolute value |
341
-
342
- | `round:N` | Round to N decimals |
343
-
344
- | `floor` | Floor |
345
-
346
- | `ceil` | Ceiling |
347
-
348
- | `min:N` | Minimum of value and N |
349
-
350
- | `max:N` | Maximum of value and N |
351
-
352
- | `sum` | Sum of list |
353
-
354
- | `average` | Average of list |
355
-
356
-
357
-
358
- ### Currency and Data Formatting
359
-
360
-
361
-
362
- | Filter | Description |
363
-
364
- |--------|-------------|
365
-
366
- | `currency:"$"` | Format as currency |
367
-
368
- | `phone_number` | Format phone number |
369
-
370
- | `email` | Format as email link |
371
-
372
- | `url` | Format as URL link |
373
-
374
- | `mask:"*"` | Mask sensitive data |
375
-
376
- | `whatsapp_link:"msg"` | Generate WhatsApp link |
377
-
378
- | `credit_card` | Format credit card number |
379
-
380
- | `ssn` | Format SSN |
381
-
382
- | `ip_address` | Format IP address |
383
-
384
- | `uuid` | Format UUID |
385
-
386
- | `filesizeformat` | Human-readable file size |
387
-
388
- | `yesno:"yes,no,maybe"` | Yes/no based on boolean |
389
-
390
- | `pluralize:"s"` | Add plural suffix if needed |
391
-
392
- | `urlencode` | URL-encode |
393
-
394
- | `escapeuri` | Escape URI component |
395
-
396
- | `stringformat:"%s"` | String format |
397
-
398
- | `cut:"text"` | Remove occurrences |
399
-
400
- | `addslashes` | Add slashes |
401
-
402
- | `removetags:"p,div"` | Remove specified tags |
403
-
404
- | `trans:"key"` | Translate key |
405
-
406
- | `regroup:"attr"` | Regroup list by attribute |
407
-
408
- | `json` | Serialize to JSON |
409
-
410
- | `urlize` | Auto-link URLs in text |
411
-
412
-
413
-
414
- ### Encoding Filters
415
-
416
-
417
-
418
- | Filter | Description |
419
-
420
- |--------|-------------|
421
-
422
- | `base64_encode` | Base64 encode |
423
-
424
- | `base64_decode` | Base64 decode |
425
-
426
-
427
-
428
- ## Next Steps
429
-
430
-
431
-
432
- - [Filters Guide](../guide/filters.md)
433
-
434
- - [Custom Filters](../guide/custom-filters.md)
435
-
436
- - [API Reference](../index.md)
437
-
@@ -1,188 +0,0 @@
1
- # Finder API
2
-
3
-
4
-
5
- ## findTemplateInViews
6
-
7
-
8
-
9
- Find a template file by name in the provided views directories.
10
-
11
-
12
-
13
- === "CommonJS"
14
-
15
-
16
-
17
- ```javascript
18
-
19
- const { findTemplateInViews } = require('miki-template');
20
-
21
-
22
-
23
- const found = findTemplateInViews('home', ['./views', './app/templates']);
24
-
25
- console.log(found);
26
-
27
- // Output: /absolute/path/to/home.html
28
-
29
- ```
30
-
31
-
32
-
33
- === "ES Modules"
34
-
35
-
36
-
37
- ```javascript
38
-
39
- import { findTemplateInViews } from 'miki-template';
40
-
41
-
42
-
43
- const found = findTemplateInViews('home', ['./views', './app/templates']);
44
-
45
- console.log(found);
46
-
47
- ```
48
-
49
-
50
-
51
- ### Parameters
52
-
53
-
54
-
55
- | Parameter | Type | Description |
56
-
57
- |-----------|------|-------------|
58
-
59
- | `templateName` | `string` | Template name to search for (with or without extension) |
60
-
61
- | `viewsDirs` | `string[]` | Array of views directories to search |
62
-
63
-
64
-
65
- ### Returns
66
-
67
-
68
-
69
- `string | null` — Absolute path to the template file, or `null` if not found.
70
-
71
-
72
-
73
- ### Behavior
74
-
75
-
76
-
77
- - Searches recursively through subdirectories for bare template names (no `/` in name).
78
-
79
- - Tries `.html` and `.miki` extensions when no extension is provided.
80
-
81
- - Also searches app-style `templates/` directories nested inside the views root.
82
-
83
- - Returns the **first match found**.
84
-
85
-
86
-
87
- ## setAppTemplateDirNames
88
-
89
-
90
-
91
- Configure which directory names are treated as app-style template directories.
92
-
93
-
94
-
95
- === "CommonJS"
96
-
97
-
98
-
99
- ```javascript
100
-
101
- const { setAppTemplateDirNames } = require('miki-template');
102
-
103
-
104
-
105
- setAppTemplateDirNames(['templates', 'views', 'pages']);
106
-
107
- ```
108
-
109
-
110
-
111
- === "ES Modules"
112
-
113
-
114
-
115
- ```javascript
116
-
117
- import { setAppTemplateDirNames } from 'miki-template';
118
-
119
-
120
-
121
- setAppTemplateDirNames(['templates', 'views', 'pages']);
122
-
123
- ```
124
-
125
-
126
-
127
- ### Parameters
128
-
129
-
130
-
131
- | Parameter | Type | Description |
132
-
133
- |-----------|------|-------------|
134
-
135
- | `names` | `string \| string[]` | Directory name(s) to recognize |
136
-
137
-
138
-
139
- ## getAppTemplateDirNames
140
-
141
-
142
-
143
- Get the current app template directory names.
144
-
145
-
146
-
147
- === "CommonJS"
148
-
149
-
150
-
151
- ```javascript
152
-
153
- const { getAppTemplateDirNames } = require('miki-template');
154
-
155
-
156
-
157
- console.log(getAppTemplateDirNames());
158
-
159
- // ['templates']
160
-
161
- ```
162
-
163
-
164
-
165
- === "ES Modules"
166
-
167
-
168
-
169
- ```javascript
170
-
171
- import { getAppTemplateDirNames } from 'miki-template';
172
-
173
-
174
-
175
- console.log(getAppTemplateDirNames());
176
-
177
- ```
178
-
179
-
180
-
181
- ## Next Steps
182
-
183
-
184
-
185
- - [Guide: Smart Template Discovery](../guide/template-discovery.md)
186
-
187
- - [API Reference](../index.md)
188
-
@@ -1,106 +0,0 @@
1
- # Helpers API
2
-
3
-
4
-
5
- ## registerHelper
6
-
7
-
8
-
9
- Register a helper function that can be called from templates.
10
-
11
-
12
-
13
- === "CommonJS"
14
-
15
-
16
-
17
- ```javascript
18
-
19
- const { registerHelper } = require('miki-template');
20
-
21
-
22
-
23
- registerHelper('bold', (inner, context) => `<b>${inner}</b>`);
24
-
25
- ```
26
-
27
-
28
-
29
- === "ES Modules"
30
-
31
-
32
-
33
- ```javascript
34
-
35
- import { registerHelper } from 'miki-template';
36
-
37
-
38
-
39
- registerHelper('bold', (inner, context) => `<b>${inner}</b>`);
40
-
41
- ```
42
-
43
-
44
-
45
- ### Helper Signature
46
-
47
-
48
-
49
- Helpers receive `(content, context)` where `content` is the rendered inner content of the tag:
50
-
51
-
52
-
53
- ```javascript
54
-
55
- registerHelper('panel', (content, context) => {
56
-
57
- return `<div class="panel">${content}</div>`;
58
-
59
- });
60
-
61
- ```
62
-
63
-
64
-
65
- Usage in templates:
66
-
67
-
68
-
69
- ```html
70
-
71
- {% panel %}
72
-
73
- <h2>{{ title }}</h2>
74
-
75
- <p>{{ description }}</p>
76
-
77
- {% endpanel %}
78
-
79
- ```
80
-
81
-
82
-
83
- ## Built-in Helpers
84
-
85
-
86
-
87
- miki-template includes built-in helpers for common formatting tasks:
88
-
89
-
90
-
91
- - `bold` — Wrap content in `<b>` tags
92
-
93
- - `italic` — Wrap content in `<i>` tags
94
-
95
- - `underline` — Wrap content in `<u>` tags
96
-
97
-
98
-
99
- ## Next Steps
100
-
101
-
102
-
103
- - [Custom Tags](../guide/custom-tags.md)
104
-
105
- - [API Reference](../index.md)
106
-