@kendawson-online/vantl 2.0.0 → 2.0.5

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,468 +1,262 @@
1
- # Vanilla JS Timeline
2
-
3
- A vanilla JavaScript app to create responsive horizontal and vertical timelines.
4
-
5
- Supports jQuery, external JSON configuration, color theming, HTML support, node images, and deep-linking via URL. Inspired by [timeline](https://github.com/squarechip/timeline) originally created by [Mike Collins](https://github.com/squarechip) in 2018.
6
-
7
- [Link to Screenshot]
8
-
9
- <br/>
10
-
11
- ## Features
12
-
13
- #### 🔘&nbsp; Create / load data via three methods (see Examples)
14
- - Directly via API using Javascript (e.g. jQuery)
15
- - Inline in HTML page using data-attributes
16
- - Externally via JSON configuration file
17
-
18
- #### 🔘&nbsp; Library agnostic. If jQuery is present it will register itself as a plugin.
19
-
20
- #### 🔘&nbsp; Color customization for nodes, timeline, and navigation buttons
21
-
22
- #### 🔘&nbsp; Image support (per-node) with fluid sizing
23
-
24
- #### 🔘&nbsp; Deep link to specific nodes via URL parameters
25
-
26
- #### 🔘&nbsp; Allows multiple independent timelines on a single page
27
-
28
- #### 🔘&nbsp; Auto-initialization when using JSON config
29
-
30
- #### 🔘&nbsp; Caches JSON data to local storage for faster loading
31
-
32
- #### 🔘&nbsp; Responsive layout switches based on screen size
33
-
34
- #### 🔘&nbsp; Small file size
35
-
36
- <br/>
37
-
38
- ### Examples:
39
-
40
- - Using Javascript (jQuery):
41
- &nbsp;&nbsp;[Horizontal](#) &nbsp;|&nbsp; [Vertical](#)
42
- - Using Inline HTML:
43
- &nbsp;&nbsp;[Horizontal Layout](#) &nbsp;|&nbsp; [Vertical Layout](#)
44
- - Using External JSON data:
45
- &nbsp;&nbsp;[Horizontal Layout](#) &nbsp;|&nbsp; [Vertical Layout](#)
46
- - Deep Linking to Nodes:
47
- &nbsp;&nbsp;[Horizontal Layout](#) &nbsp;|&nbsp; [Vertical Layout](#)
48
- - Using Multiple Timelines On A Page:
49
- &nbsp;&nbsp;[Horizontal Layout](#) &nbsp;|&nbsp; [Vertical Layout](#)
50
-
51
- <br/>
52
-
53
- ## Quick Start
54
-
55
- ### 1. Include required files in your page
56
- - Download code and load files locally:
57
- ```html
58
- <html>
59
- <head>
60
- <link href="src/css/timeline.css" rel="stylesheet" />
61
- </head>
62
- <body>
63
- <!-- [ timeline code goes here ] -->
64
- <script src="src/js/timeline.js"></script>
65
- </body>
66
- </html>
67
- ```
68
- - Load files via CDN links:
69
- ````html
70
- <html>
71
- <head>
72
- <link href="https://cdn.jsdelivr.net/gh/kendawson-online/vanillajs-timeline/src/css/timeline.css" rel="stylesheet">
73
- </head>
74
- <body>
75
- <!-- [ timeline code goes here ] -->
76
- <script src="https://cdn.jsdelivr.net/gh/kendawson-online/vanillajs-timeline/src/js/timeline.js"></script>
77
- </body>
78
- </html>
79
- ````
80
-
81
- ### 2. Choose a creation method
82
- - Javascript API (e.g. jQuery)
83
- - Inline HTML data-attributes
84
- - External JSON configuration file
85
-
86
- ### 3. Add timeline data
87
- - If you are using the vanilla JS/Jquery or data-attributes method, you need to add your timeline node data via regular HTML. If you are using the JSON method you can skip this step.
88
-
89
- ````html
90
- <div class="timeline">
91
- <div class="timeline__wrap">
92
- <div class="timeline__items">
93
- <div class="timeline__item">
94
- <div class="timeline__content">
95
- Content / markup here
96
- </div>
97
- </div>
98
- <div class="timeline__item">
99
- <div class="timeline__content">
100
- Content / markup here
101
- </div>
102
- </div>
103
- <div class="timeline__item">
104
- <div class="timeline__content">
105
- Content / markup here
106
- </div>
107
- </div>
108
- <div class="timeline__item">
109
- <div class="timeline__content">
110
- Content / markup here
111
- </div>
112
- </div>
113
- <div class="timeline__item">
114
- <div class="timeline__content">
115
- Content / markup here
116
- </div>
117
- </div>
118
- </div>
119
- </div>
120
- </div>
121
- ````
122
-
123
- - Add timeline nodes via [JSON config](demo/assets/data/sample1.json) file
124
-
125
- [Add More Explaination Text Here]
126
-
127
- - [Convert CSV or Spreadsheet](#) file to JSON [Link to server tool]
128
-
129
- [Add More Explaination Text Here]
130
-
131
- ### 4. Initialize the app
132
- - Using vanilla Javascript
133
- ````javascript
134
- timeline(document.querySelectorAll('.timeline'));
135
- ````
136
- - Using jQuery
137
- ````javascript
138
- jQuery('.timeline').timeline();
139
- ````
140
-
141
- <br/><br/>
142
-
143
- **NOTE: if you're using an external JSON file, you can skip step four. You don't have to manually initialize the app. Loading the JSON file automatically initializes the app for you.**
144
-
145
- <br/>
146
-
147
- ### Javascript API and data-attributes:
148
-
149
- 1. Using data-attributes will take priority over settings via the API.
150
-
151
- 2. Using an external JSON file will take priority over data-attributes and/or API settings.
152
-
153
- <br/><br/>
154
-
155
- # API Options:
156
-
157
- <br/>
158
-
159
- `mode`
160
-
161
- **Choose whether the timeline should be vertical or horizontal**
162
-
163
- JavaScript/jQuery
164
- ````js
165
- default: 'vertical'
166
- options: 'vertical', 'horizontal'
167
- ````
168
-
169
- Data attribute
170
- ````html
171
- <div class="timeline" data-mode="horizontal">
172
- ...
173
- </div>
174
- ````
175
-
176
- <br />
177
-
178
- ------
179
-
180
- <br />
181
-
182
- `minWidth`
183
-
184
- **When using the timeline in horizontal mode, define the minimum viewport width (px) to stay horizontal; below this it becomes vertical/mobile**
185
-
186
- JavaScript/jQuery
187
- ````javascript
188
- default: 600
189
- options: integer
190
- ````
191
-
192
- Data attribute
193
- ````html
194
- <div class="timeline" data-minwidth="600">
195
- ...
196
- </div>
197
- ````
198
-
199
- Notes:
200
- - Backwards compatibility: legacy `forceVerticalMode` (JS) and `data-force-vertical-mode` (HTML) are still accepted.
201
-
202
- <br />
203
-
204
- ------
205
-
206
- <br />
207
-
208
- `horizontalStartPosition`
209
-
210
- **When using the timeline in horizontal mode, define the vertical alignment of the first item**
211
-
212
- JavaScript/jQuery
213
- ````javascript
214
- default: 'top'
215
- options: 'bottom', 'top'
216
- ````
217
-
218
- Data attribute
219
- ````html
220
- <div class="timeline" data-horizontal-start-position="top">
221
- ...
222
- </div>
223
- ````
224
-
225
- <br />
226
-
227
- ------
228
-
229
- <br />
230
-
231
- `moveItems`
232
-
233
- **When using the timeline in horizontal mode, define how many items to move when clicking a navigation button**
234
-
235
- JavaScript/jQuery
236
- ````javascript
237
- default: 1
238
- options: integer
239
- ````
240
-
241
- Data attribute
242
- ````html
243
- <div class="timeline" data-move-items="1">
244
- ...
245
- </div>
246
- ````
247
-
248
- <br />
249
-
250
- ------
251
-
252
- <br />
253
-
254
-
255
- `rtlMode`
256
-
257
- **When using the timeline in horizontal mode, this defines whether the timeline should start from the right. This overrides the startIndex setting.**
258
-
259
- JavaScript/jQuery
260
- ````javascript
261
- default: false
262
- options: true / false
263
- ````
264
-
265
- Data attribute
266
- ````html
267
- <div class="timeline" data-rtl-mode="true">
268
- ...
269
- </div>
270
- ````
271
- <br />
272
-
273
- ------
274
-
275
- <br />
276
-
277
- `startIndex`
278
-
279
- **When using the timeline in horizontal mode, define which item the timeline should start at**
280
-
281
- JavaScript/jQuery
282
- ````javascript
283
- default: 0
284
- options: integer
285
- ````
286
-
287
- Data attribute
288
- ````html
289
- <div class="timeline" data-start-index="0">
290
- ...
291
- </div>
292
- ````
293
-
294
- <br />
295
-
296
- ------
297
-
298
- <br />
299
-
300
- `verticalStartPosition`
301
-
302
- **When using the timeline in vertical mode, define the alignment of the first item**
303
-
304
- JavaScript/jQuery
305
-
306
- ```javascript
307
- default: 'left'
308
- options: 'left', 'right'
309
- ```
310
-
311
- Data attribute
312
-
313
- ```html
314
- <div class="timeline" data-vertical-start-position="right">
315
- ...
316
- </div>
317
- ```
318
-
319
- <br />
320
-
321
- ------
322
-
323
- <br />
324
-
325
- `verticalTrigger`
326
-
327
- **When using the timeline in vertical mode, define the distance from the bottom of the screen, in percent or pixels, that the items slide into view**
328
-
329
- JavaScript/jQuery
330
-
331
- ```javascript
332
- default: '15%'
333
- options: percentage or pixel value e.g. '20%' or '150px'
334
- ```
335
-
336
- Data attribute
337
-
338
- ```html
339
- <div class="timeline" data-vertical-trigger="150px">
340
- ...
341
- </div>
342
- ```
343
-
344
- <br />
345
-
346
- ------
347
-
348
- <br />
349
-
350
- `visibleItems`
351
-
352
- **For horizontal mode: Controls the scrolling range and when navigation arrows appear. Note: With fixed-width timeline items, the actual number of visible items is determined by the container width**
353
-
354
- JavaScript/jQuery
355
-
356
- ```javascript
357
- default: 3
358
- options: integer
359
- ```
360
-
361
- Data attribute
362
-
363
- ```html
364
- <div class="timeline" data-visible-items="3">
365
- ...
366
- </div>
367
- ```
368
- <br />
369
-
370
- ------
371
-
372
- <br />
373
-
374
- `nodeColor`, `lineColor`, `navColor`
375
-
376
- **Set theme colors for nodes, center line, and navigation buttons (horizontal)**
377
-
378
- JavaScript/jQuery
379
-
380
- ```javascript
381
- // any subset can be provided
382
- jQuery('.timeline').timeline({
383
- nodeColor: '#2d6cdf',
384
- lineColor: '#2d6cdf',
385
- navColor: '#f2f2f2'
386
- });
387
- ```
388
-
389
- Data attributes (container)
390
-
391
- ```html
392
- <div class="timeline"
393
- data-node-color="#2d6cdf"
394
- data-line-color="#2d6cdf"
395
- data-nav-color="#f2f2f2">
396
- ...
397
- </div>
398
- ```
399
-
400
- JSON (top-level)
401
-
402
- ```json
403
- {
404
- "nodeColor": "#2d6cdf",
405
- "lineColor": "#2d6cdf",
406
- "navColor": "#f2f2f2"
407
- }
408
- ```
409
-
410
- Notes:
411
- - If only one of `nodeColor` or `lineColor` is set, it is used for both.
412
- - `navColor` automatically sets a contrasting border and arrow color.
413
-
414
- ------
415
-
416
- <br />
417
-
418
- Deep Linking and Node IDs
419
-
420
- **Link to a specific node by ID using `?timeline=<containerId>&id=<nodeId>`**
421
-
422
- - JSON nodes: set `id` on each node; the renderer adds `data-node-id` to items.
423
- - Inline markup: add `data-node-id` to each `.timeline__item` you want addressable.
424
- - On click modals: inline items can optionally declare `data-modal-title`, `data-modal-content`, `data-modal-image`, or `data-modal-html`. If absent, the library derives reasonable defaults from the markup (first heading, first paragraph, first image).
425
-
426
-
427
- ## Server Upload Workflow
428
-
429
- This repository includes a small PHP utility under the `server-tools/` folder that converts CSV / Excel / Google Sheets into the timeline JSON format used by the demo. The basic flow is:
430
-
431
- 1. Open `server-tools/upload.html` in a browser (or host the `server-tools/` folder on a PHP-capable host).
432
- 2. Upload a CSV or `.xls/.xlsx` file, or provide a public Google Sheets URL. The server runs `convert.php` to parse the sheet and produce JSON.
433
- 3. If conversion succeeds the JSON is saved to `server-tools/tmp/` with a unique filename and you are redirected to `server-tools/done.php` which shows a preview and a download link.
434
- 4. Temporary files are cleaned up automatically by `server-tools/cleanup_tmp.php` (24-hour TTL). Run that as a cron job on the server.
435
-
436
- Quick local test (from project root):
437
-
438
- ```bash
439
- php -S localhost:8000 -t .
440
- # then visit http://localhost:8000/server/upload.html
441
- ```
442
-
443
- Notes:
444
- - The converter will set a `lastupdated` timestamp in the JSON if none is provided — this integrates with the client's caching behavior.
445
- - Excel parsing requires `phpoffice/phpspreadsheet` (installed via Composer). `convert.php` auto-loads `vendor/autoload.php` if available in `server/` or project root.
446
-
447
- ## Security Notes (important)
448
-
449
- This upload utility is a convenience tool and not hardened for untrusted public hosting. If you plan to run it on a public server, consider the following safeguards:
450
-
451
- - Validate uploads: restrict accepted MIME types / extensions (`.csv`, `.xls`, `.xlsx`) and enforce a reasonable maximum file size.
452
- - Run file parsing in a controlled environment; avoid executing any uploaded content.
453
- - Store temporary files outside the web root or restrict direct listing/access; `server/done.php` only exposes the saved JSON filename.
454
- - Sanitize all filenames and never use user-supplied filenames for server paths without cleaning.
455
- - Limit rate and require authentication if the endpoint will be public to avoid abuse.
456
- - Use HTTPS to protect uploads in transit.
457
- - Keep Composer dependencies up-to-date and audit for security issues.
458
- - Consider additional input validation on fields extracted from the spreadsheet (e.g., URLs, image paths) before including them in output JSON.
459
-
460
-
461
- ## License & Credits
462
-
463
- This app is released under the [MIT License](LICENSE)
464
-
465
- The original `timeline` project was created by Mike Collins and was also released under the MIT License. His project can be found on GitHub here: [https://github.com/squarechip/timeline](https://github.com/squarechip/timeline)
466
-
467
-
468
- Last updated: Jan. 5, 2026
1
+ # Vantl - Vanilla (JS) Timeline
2
+
3
+ A lightweight, responsive timeline library created with vanilla Javascript for creating beautiful horizontal and vertical timelines with zero dependencies. Inspired by [timeline](https://github.com/squarechip/timeline) originally created by [squarechip](https://github.com/squarechip) in 2018.
4
+
5
+ <table align="center">
6
+ <tr>
7
+ <td><img src="demo/assets/img/horizontal-screenshot.png" width="650"></td>
8
+ </tr>
9
+ </table>
10
+
11
+
12
+ ## Features
13
+
14
+ - **Zero dependencies** - Pure vanilla JavaScript (jQuery optional)
15
+ - 📱 **Fully responsive** - Auto-switches between horizontal/vertical layouts
16
+ - 🎨 **Customizable colors** - Theme nodes, lines, and navigation
17
+ - 🖼️ **Rich content** - Support for images, HTML, and modal popups
18
+ - 🔗 **Deep linking** - Link directly to specific timeline nodes via URL
19
+ - 📦 **Multiple layouts** - Vertical scroll or horizontal carousel modes
20
+ - 💾 **Smart caching** - LocalStorage caching for JSON data
21
+ - 🚀 **Auto-init** - Just add a data attribute to load from JSON
22
+ - 📏 **Small footprint** - Minified and tree-shakeable
23
+
24
+ ## Quick Start
25
+
26
+ ### Via CDN
27
+
28
+ ```html
29
+ <!DOCTYPE html>
30
+ <html>
31
+ <head>
32
+ <!-- timeline stylesheet -->
33
+ <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@kendawson-online/vantl@2/dist/timeline.min.css">
34
+ </head>
35
+ <body>
36
+
37
+ <!-- your timeline code here -->
38
+ <div id="timeline" class="timeline" data-json-config="/path/to/your/data.json"></div>
39
+
40
+ <!-- timeline Javascript -->
41
+ <script src="https://cdn.jsdelivr.net/npm/@kendawson-online/vantl@2/dist/timeline.min.js"></script>
42
+ </body>
43
+ </html>
44
+ ```
45
+
46
+ ### Via npm
47
+
48
+ ```bash
49
+ npm install @kendawson-online/vantl
50
+ ```
51
+
52
+ ```javascript
53
+ import { timeline } from '@kendawson-online/vantl';
54
+ import '@kendawson-online/vantl/src/css/timeline.css';
55
+
56
+ timeline(document.querySelectorAll('.timeline'), {
57
+ mode: 'vertical',
58
+ nodeColor: '#2d6cdf'
59
+ });
60
+ ```
61
+
62
+ ## Usage Examples
63
+
64
+ ### 1. Auto-Init with JSON (Easiest)
65
+
66
+ The timeline auto-initializes when you add a `data-json-config` attribute:
67
+
68
+ ```html
69
+ <div class="timeline" data-json-config="/path/to/timeline.json"></div>
70
+ ```
71
+
72
+ **JSON Format:**
73
+ ```json
74
+ {
75
+ "timelineName": "My Timeline",
76
+ "layoutMode": "vertical",
77
+ "lastupdated": "2026-01-08T20:15:34.873Z",
78
+ "nodes": [
79
+ {
80
+ "id": 1,
81
+ "title": "Event Title",
82
+ "content": "Event description...",
83
+ "image": "/path/to/image.jpg"
84
+ }
85
+ ]
86
+ }
87
+ ```
88
+
89
+ ### 2. Inline HTML with Data Attributes
90
+
91
+ ```html
92
+ <div class="timeline" data-mode="horizontal">
93
+ <div class="timeline__wrap">
94
+ <div class="timeline__items">
95
+ <div class="timeline__item">
96
+ <div class="timeline__content">
97
+ <h5>2001</h5>
98
+ <p>Lorem ipsum dolor sit amet, qui <a href="#">minim</a> labore adipisicing minim sint cillum sint consectetur cupidatat.</p>
99
+ </div>
100
+ </div>
101
+ <div class="timeline__item">
102
+ <div class="timeline__content">
103
+ <h5>2002</h5>
104
+ <p>Lorem ipsum <a href="#">dolor sit amet</a>, qui minim labore adipisicing minim sint cillum sint consectetur cupidatat.</p>
105
+ </div>
106
+ </div>
107
+ <div class="timeline__item">
108
+ <div class="timeline__content">
109
+ <h5>2003</h5>
110
+ <p>Lorem ipsum dolor sit amet, qui minim labore adipisicing minim sint cillum sint consectetur cupidatat.</p>
111
+ </div>
112
+ </div>
113
+ </div>
114
+ </div>
115
+ </div>
116
+
117
+ <script>
118
+ timeline(document.querySelectorAll('.timeline'));
119
+ </script>
120
+ ```
121
+
122
+ ### 3. JavaScript API
123
+
124
+ ```javascript
125
+ // Vanilla JS
126
+ timeline(document.querySelectorAll('.timeline'), {
127
+ mode: 'horizontal',
128
+ visibleItems: 3,
129
+ });
130
+
131
+ // jQuery (if available)
132
+ $('.timeline').timeline({
133
+ mode: 'vertical',
134
+ verticalTrigger: '20%'
135
+ });
136
+ ```
137
+
138
+ ## API Options
139
+
140
+ All options can be set via JavaScript API, data attributes, or JSON config.
141
+
142
+ | Option | Type | Default | Description |
143
+ |--------|------|---------|-------------|
144
+ | `mode` | string | `'vertical'` | Layout mode: `'vertical'` or `'horizontal'` |
145
+ | `minWidth` | number | `600` | Min viewport width (px) to maintain horizontal mode |
146
+ | `visibleItems` | number | `3` | Number of items in horizontal viewport |
147
+ | `moveItems` | number | `1` | Items to scroll per navigation click (horizontal) |
148
+ | `startIndex` | number | `0` | Initial item index (horizontal mode) |
149
+ | `horizontalStartPosition` | string | `'top'` | First item alignment: `'top'` or `'bottom'` |
150
+ | `verticalStartPosition` | string | `'left'` | First item alignment: `'left'` or `'right'` |
151
+ | `verticalTrigger` | string | `'15%'` | Scroll trigger distance: percentage or px (e.g., `'20%'` or `'150px'`) |
152
+ | `rtlMode` | boolean | `false` | Right-to-left mode (horizontal) |
153
+ | `nodeColor` | string | — | Node circle color (hex/rgb/hsl) |
154
+ | `lineColor` | string | — | Center line color (hex/rgb/hsl) |
155
+ | `navColor` | string | — | Navigation button color (hex/rgb/hsl) |
156
+
157
+ **Setting Options:**
158
+
159
+ ```javascript
160
+ // JavaScript
161
+ timeline(el, { mode: 'horizontal', nodeColor: '#2d6cdf' });
162
+ ```
163
+
164
+ ```html
165
+ <!-- Data attributes -->
166
+ <div class="timeline" data-mode="horizontal" data-node-color="#2d6cdf">
167
+ ```
168
+
169
+ ```json
170
+ // JSON
171
+ { "layoutMode": "horizontal", "nodeColor": "#2d6cdf" }
172
+ ```
173
+
174
+ ## Deep Linking
175
+
176
+ Link to a specific timeline node using URL parameters:
177
+
178
+ ```
179
+ https://example.com/page.html?timeline=myTimelineId&id=3
180
+ ```
181
+
182
+ - Add `id` attribute to timeline container
183
+ - Add `data-node-id` to each item you want to link to
184
+ - Works automatically with JSON-loaded timelines
185
+
186
+ ## Advanced Features
187
+
188
+ ### Custom Image Path
189
+
190
+ Override the auto-detected image path:
191
+
192
+ ```html
193
+ <script>
194
+ window.TimelineConfig = {
195
+ basePath: '/custom/path/to/images'
196
+ };
197
+ </script>
198
+ <script src="dist/timeline.min.js"></script>
199
+ ```
200
+
201
+ ### Modal Content
202
+
203
+ Each timeline item can display a modal popup on click:
204
+
205
+ ```html
206
+ <div class="timeline__item"
207
+ data-modal-title="Full Title"
208
+ data-modal-content="Extended description..."
209
+ data-modal-image="/img/large.jpg"
210
+ data-modal-html="<p>Custom HTML content</p>">
211
+ ...
212
+ </div>
213
+ ```
214
+
215
+ JSON items automatically support modals with the `title`, `content`, `image`, and `html` fields.
216
+
217
+ ### Programmatic Control
218
+
219
+ ```javascript
220
+ // Load from JSON programmatically
221
+ loadDataFromJson('/data/timeline.json', '#myTimeline');
222
+
223
+ // Clear cache
224
+ clearTimelineCache(); // Clear all
225
+ clearTimelineCache('timelineId'); // Clear specific
226
+
227
+ // Navigate to node (horizontal mode)
228
+ navigateTimelineToNodeIndex(containerElement, 5);
229
+
230
+ // Open modal
231
+ openTimelineModal(itemElement);
232
+
233
+ // Close modal
234
+ closeTimelineModal();
235
+ ```
236
+
237
+ ## Browser Support
238
+
239
+ - Chrome/Edge (2018+)
240
+ - Firefox (2018+)
241
+ - Safari (2018+)
242
+ - Requires: ES6, IntersectionObserver, CSS Custom Properties
243
+
244
+ ## Contributing
245
+
246
+ See [DEVELOPMENT.md](DEVELOPMENT.md) for build instructions and architecture overview.
247
+
248
+ ## License
249
+
250
+ MIT License - see [LICENSE](LICENSE) file for details.
251
+
252
+ ## Credits
253
+
254
+ Originally inspired by [timeline](https://github.com/squarechip/timeline) by [Mike Collins](https://github.com/squarechip) (2018).
255
+
256
+ Refactored and maintained by [Ken Dawson](https://github.com/kendawson-online) (2026).
257
+
258
+ ---
259
+
260
+ **Package:** [@kendawson-online/vantl](https://www.npmjs.com/package/@kendawson-online/vantl)
261
+ **Repository:** [github.com/kendawson-online/vantl](https://github.com/kendawson-online/vantl)
262
+ **CDN:** [cdn.jsdelivr.net/npm/@kendawson-online/vantl](https://cdn.jsdelivr.net/npm/@kendawson-online/vantl)