@keenmate/svelte-spa-router 2.0.1 → 5.0.0-rc04
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/CHANGELOG.md +317 -0
- package/LICENSE.md +21 -21
- package/README.md +1363 -507
- package/package.json +117 -72
- package/src/lib/Router.svelte +436 -0
- package/src/lib/active.d.ts +47 -0
- package/src/lib/active.svelte.js +157 -0
- package/src/lib/constants.d.ts +12 -0
- package/src/lib/constants.js +6 -0
- package/src/lib/helpers/filters.d.ts +158 -0
- package/src/lib/helpers/filters.svelte.js +291 -0
- package/src/lib/helpers/navigation-guard.d.ts +129 -0
- package/src/lib/helpers/navigation-guard.svelte.js +177 -0
- package/src/lib/helpers/permissions.d.ts +176 -0
- package/src/lib/helpers/permissions.svelte.js +255 -0
- package/src/lib/helpers/querystring-helpers.d.ts +92 -0
- package/src/lib/helpers/querystring-helpers.svelte.js +316 -0
- package/src/lib/helpers/querystring.d.ts +59 -0
- package/src/lib/helpers/querystring.svelte.js +74 -0
- package/src/lib/helpers/route-metadata.d.ts +190 -0
- package/src/lib/helpers/route-metadata.svelte.js +257 -0
- package/src/lib/helpers/url-helpers.d.ts +24 -0
- package/src/lib/helpers/url-helpers.svelte.js +48 -0
- package/src/lib/index.d.ts +19 -0
- package/src/lib/index.js +27 -0
- package/src/lib/parse-route.js +58 -0
- package/src/lib/routes.d.ts +76 -0
- package/src/lib/routes.svelte.js +115 -0
- package/src/lib/utils.d.ts +288 -0
- package/src/lib/utils.svelte.js +489 -0
- package/src/lib/wrap.d.ts +162 -0
- package/src/lib/wrap.js +232 -0
- package/.editorconfig +0 -21
- package/Router.d.ts +0 -225
- package/Router.svelte +0 -689
- package/active.d.ts +0 -23
- package/active.js +0 -121
- package/constants.js +0 -1
- package/helpers/url-helpers.js +0 -29
- package/nightwatch.conf.cjs +0 -52
- package/wrap.d.ts +0 -41
- package/wrap.js +0 -93
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,317 @@
|
|
|
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
|
+
## [Unreleased]
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
#### Convenient Route Creation API
|
|
13
|
+
- **New `createRoute()` and `createRouteDefinition()` functions** for easier route configuration
|
|
14
|
+
- `createRoute()` - Returns already wrapped component (most convenient, no `wrap()` needed)
|
|
15
|
+
- `createRouteDefinition()` - Returns route definition for use with `wrap()` (advanced use)
|
|
16
|
+
- Consistent API pattern matching `createProtectedRoute()` / `createProtectedRouteDefinition()`
|
|
17
|
+
- Support for `title` and `breadcrumbs` metadata directly in route options
|
|
18
|
+
- Automatic detection of sync vs async components
|
|
19
|
+
|
|
20
|
+
- **Enhanced Permission System**
|
|
21
|
+
- `createProtectedRoute()` - Now returns already wrapped component (breaking change from definition-only)
|
|
22
|
+
- `createProtectedRouteDefinition()` - New function that returns definition (replaces old `createProtectedRoute()` behavior)
|
|
23
|
+
- Maintains backward compatibility for existing `wrap(createProtectedRoute(...))` usage
|
|
24
|
+
|
|
25
|
+
- **Route Metadata Support**
|
|
26
|
+
- `title` - Set page title for routes
|
|
27
|
+
- `breadcrumbs` - Define breadcrumb trail with `{ label, path? }` structure
|
|
28
|
+
- Metadata stored in `userData` object, accessible in route events and components
|
|
29
|
+
|
|
30
|
+
#### Dynamic Metadata & Loading Control
|
|
31
|
+
- **Reactive Metadata Helpers**: `helpers/route-metadata.svelte.js`
|
|
32
|
+
- `routeTitle()` - Get current route title reactively
|
|
33
|
+
- `routeBreadcrumbs()` - Get current breadcrumb trail reactively
|
|
34
|
+
- `routeUserData()` - Get full route userData reactively
|
|
35
|
+
- `updateRouteMetadata(userData)` - Update metadata after data loads (e.g., change title from "Document" to "Invoice.pdf")
|
|
36
|
+
- **`updateTitle(title)` - Update just the title** (simpler than updateRouteMetadata)
|
|
37
|
+
- **`updateBreadcrumb(id, updates)` - Partial breadcrumb updates** (update specific segments by ID)
|
|
38
|
+
- Automatically updated by Router on route changes
|
|
39
|
+
|
|
40
|
+
- **Partial Breadcrumb Updates** (NEW!)
|
|
41
|
+
- Add `id` property to breadcrumb items in route config: `{ id: 'docDetail', label: 'Loading...', path: '/doc/:id' }`
|
|
42
|
+
- Update specific breadcrumbs after data loads: `updateBreadcrumb('docDetail', { label: 'Invoice.pdf', path: '/doc/123' })`
|
|
43
|
+
- **No need to replace the entire breadcrumbs array** - only update what changes!
|
|
44
|
+
- Perfect for nested paths: `/documents/:id/logs/:logId` where each segment needs dynamic data
|
|
45
|
+
- Static segments (Home, Documents, etc.) stay unchanged
|
|
46
|
+
|
|
47
|
+
- **Flexible Loading Control** with `shouldDisplayLoadingOnRouteLoad` flag
|
|
48
|
+
- **Pattern 1 (Router-managed with loadingComponent)**: Set `shouldDisplayLoadingOnRouteLoad: true` - Router keeps loading component visible until component calls `hideLoading()`
|
|
49
|
+
- **Pattern 2 (Component-managed)**: Default behavior - component handles its own loading state
|
|
50
|
+
- **Pattern 3 (Global overlay)**: User-defined global loading UI in App.svelte that reacts to `routeIsLoading()`
|
|
51
|
+
- `showLoading()` - Manually show loading state (triggers global overlay if defined)
|
|
52
|
+
- `hideLoading()` - Component signals data is loaded (hides loading component/overlay)
|
|
53
|
+
- `routeIsLoading()` - Check if route is currently loading (reactive state)
|
|
54
|
+
- Perfect for routes that fetch data and need dynamic titles/breadcrumbs
|
|
55
|
+
- Supports multi-zone layouts (toolpanel + content) with different loading UIs per zone
|
|
56
|
+
|
|
57
|
+
**Use cases**:
|
|
58
|
+
- Document detail page: Show "Document" while loading, then "Invoice template.pdf" after data loads
|
|
59
|
+
- User profile: Show "User Profile" while loading, then "John Doe" after data loads
|
|
60
|
+
- Product page: Show "Product" while loading, then "iPhone 15 Pro" after data loads
|
|
61
|
+
- Nested paths: `/documents/:id/logs` where both document name and "Logs" need to be in breadcrumbs
|
|
62
|
+
|
|
63
|
+
#### Named Routes Enhancement
|
|
64
|
+
- **Array/Object Syntax for Navigation**: `push()` and `replace()` functions now support the same convenient array/object syntax as the `link` action
|
|
65
|
+
- Array format: `push(['userProfile', { userId: 123 }, { tab: 'settings' }])`
|
|
66
|
+
- Object format: `push({ route: 'userProfile', params: { userId: 123 }, query: { tab: 'settings' } })`
|
|
67
|
+
- String format (legacy): `push('/about')` - still fully supported for backward compatibility
|
|
68
|
+
- Eliminates the need to manually call `buildUrl()` for programmatic navigation
|
|
69
|
+
- See `example-history/src/routes/LinksDemo.svelte` for interactive demos
|
|
70
|
+
|
|
71
|
+
### Added - Querystring & Filter System
|
|
72
|
+
|
|
73
|
+
#### Querystring Helpers
|
|
74
|
+
- **Shared Reactive State**: `helpers/querystring.svelte.js`
|
|
75
|
+
- `configureQuerystring(options)` - Configure querystring parsing for entire app
|
|
76
|
+
- `query<T>()` - Get reactive parsed querystring with TypeScript generics
|
|
77
|
+
- Auto-detection of array formats (repeat vs comma-separated)
|
|
78
|
+
- Configure once, use everywhere pattern
|
|
79
|
+
|
|
80
|
+
- **Querystring Utilities**: `helpers/querystring-helpers.svelte.js`
|
|
81
|
+
- `parseQuerystring(qs, options)` - Parse querystring with array format support
|
|
82
|
+
- `stringifyQuerystring(obj, options)` - Convert object to querystring
|
|
83
|
+
- `getParsedQuerystring(options)` - Get parsed querystring (non-reactive)
|
|
84
|
+
- `updateQuerystring(updates, options)` - Update URL querystring (partial or full)
|
|
85
|
+
- `createQuerystringHelpers(parser, stringifier)` - Custom parser support
|
|
86
|
+
|
|
87
|
+
- **Array Format Support**:
|
|
88
|
+
- `'auto'` (default) - Auto-detects both repeat and comma formats
|
|
89
|
+
- `'repeat'` - `?tags=foo&tags=bar` (multiple parameters with same key)
|
|
90
|
+
- `'comma'` - `?tags=foo,bar,baz` (comma-separated values)
|
|
91
|
+
|
|
92
|
+
#### Filter System
|
|
93
|
+
- **Flexible Filters**: `helpers/filters.svelte.js`
|
|
94
|
+
- `configureFilters(options)` - Configure filter mode and parsing
|
|
95
|
+
- `filters<T>()` - Get reactive parsed filters with TypeScript generics
|
|
96
|
+
- `updateFilters<T>(updates, options)` - Update filters with type safety
|
|
97
|
+
- `getFiltersConfig()` - Get current filter configuration
|
|
98
|
+
|
|
99
|
+
- **Dual Mode Support**:
|
|
100
|
+
- **Flat Mode** (default): Each filter as separate query parameter
|
|
101
|
+
- Example: `?search=java&category=books&status=active`
|
|
102
|
+
- **Structured Mode**: Single parameter with custom syntax
|
|
103
|
+
- Example: `?$filter=search eq 'java' AND category eq 'books'`
|
|
104
|
+
- Supports custom parse/stringify functions for OData, Microsoft Graph API, etc.
|
|
105
|
+
|
|
106
|
+
#### TypeScript Support
|
|
107
|
+
- Full generic support for type-safe parameter access:
|
|
108
|
+
- `params<T>()` - Route parameters with intellisense
|
|
109
|
+
- `query<T>()` - Query parameters with intellisense
|
|
110
|
+
- `filters<T>()` - Filter parameters with intellisense
|
|
111
|
+
- `updateFilters<T>(updates, options)` - Type-safe filter updates
|
|
112
|
+
|
|
113
|
+
#### Value Handling
|
|
114
|
+
- **Filters**:
|
|
115
|
+
- `undefined` - Always removes the parameter
|
|
116
|
+
- `null` - Keeps parameter with empty value
|
|
117
|
+
- **Querystring**:
|
|
118
|
+
- `undefined` - Always removes the parameter
|
|
119
|
+
- `null` - Controlled by `dropNull` option (default: true removes it)
|
|
120
|
+
- Empty string - Controlled by `dropEmpty` option (default: false keeps it)
|
|
121
|
+
|
|
122
|
+
#### Example Applications
|
|
123
|
+
- `example-history/src/routes/QuerystringDemo.svelte` - Interactive querystring demo
|
|
124
|
+
- `example-history/src/routes/FiltersDemo.svelte` - Filter system with products demo
|
|
125
|
+
- `example-history/src/routes/RouteDataDemo.svelte` - Route data extraction examples
|
|
126
|
+
|
|
127
|
+
### Fixed
|
|
128
|
+
- **Router Initialization**: Fixed location state initialization to be reactive to config changes
|
|
129
|
+
- Issue: Direct URL access (e.g., `http://localhost:5050/querystring-demo`) showed homepage
|
|
130
|
+
- Solution: Changed from `$state(getLocation())` to `$derived.by()` to react to config changes
|
|
131
|
+
- Now correctly reads `setHashRoutingEnabled()` before initializing location state
|
|
132
|
+
|
|
133
|
+
### Documentation
|
|
134
|
+
- Updated `README.md` with comprehensive querystring and filter system documentation
|
|
135
|
+
- Added TypeScript generic examples throughout
|
|
136
|
+
- Added Quick Reference section with all available imports
|
|
137
|
+
- Updated main features list to highlight TypeScript and URL helpers
|
|
138
|
+
|
|
139
|
+
## [1.0.0] - 2024
|
|
140
|
+
|
|
141
|
+
### Package Information
|
|
142
|
+
|
|
143
|
+
- **Package Name:** @keenmate/svelte-spa-router
|
|
144
|
+
- **Publisher:** KeenMate (https://keenmate.com)
|
|
145
|
+
- **Repository:** https://github.com/keenmate/svelte-spa-router
|
|
146
|
+
|
|
147
|
+
### Added - Svelte 5 Conversion
|
|
148
|
+
|
|
149
|
+
#### Core Router
|
|
150
|
+
- Complete rewrite using Svelte 5 runes (`$state`, `$props`, `$effect`)
|
|
151
|
+
- Reactive location tracking with rune-based state management
|
|
152
|
+
- Event handlers converted from `on:` directives to callback props
|
|
153
|
+
- Maintained full backward compatibility in route definition syntax
|
|
154
|
+
|
|
155
|
+
#### Dual-Mode Routing System
|
|
156
|
+
- **Hash Mode (Default)**: Traditional hash-based routing (`#/path`)
|
|
157
|
+
- No configuration required
|
|
158
|
+
- Works everywhere, including `file://` protocol
|
|
159
|
+
- Perfect for static hosting
|
|
160
|
+
|
|
161
|
+
- **History Mode (New)**: Clean URL routing (`/path`)
|
|
162
|
+
- Uses History API for clean URLs without hash
|
|
163
|
+
- Supports modifier keys (Ctrl+Click to open in new tab)
|
|
164
|
+
- Respects `target` attribute on links
|
|
165
|
+
- Requires server configuration to serve index.html for all routes
|
|
166
|
+
|
|
167
|
+
#### Configuration Functions
|
|
168
|
+
- `setHashRoutingEnabled(boolean)` - Toggle between hash and history mode
|
|
169
|
+
- `setBasePath(string)` - Set base path for history mode
|
|
170
|
+
- `getHashRoutingEnabled()` - Get current routing mode
|
|
171
|
+
- `getBasePath()` - Get current base path
|
|
172
|
+
|
|
173
|
+
#### Permission System (New)
|
|
174
|
+
- `helpers/permissions.svelte.js` - Comprehensive RBAC system
|
|
175
|
+
- `configurePermissions(config)` - Setup permission checking logic
|
|
176
|
+
- `createPermissionCondition(requirements)` - Create route guards
|
|
177
|
+
- `createProtectedRoute(options)` - Helper for protected routes
|
|
178
|
+
- `hasPermission(requirements)` - UI-level permission checking
|
|
179
|
+
- Support for `any` (OR) and `all` (AND) permission logic
|
|
180
|
+
- Flexible integration with existing route guards
|
|
181
|
+
|
|
182
|
+
#### URL Helpers
|
|
183
|
+
- `helpers/url-helpers.svelte.js` - Path manipulation utilities
|
|
184
|
+
- `joinPaths(...paths)` - Intelligent path joining with slash handling
|
|
185
|
+
|
|
186
|
+
#### Enhanced Active Link Detection
|
|
187
|
+
- Updated to work with both hash and history modes
|
|
188
|
+
- Automatic CSS class application on matching routes
|
|
189
|
+
- Pattern matching support
|
|
190
|
+
|
|
191
|
+
### Changed
|
|
192
|
+
|
|
193
|
+
#### API Changes (Breaking)
|
|
194
|
+
- **Stores → Functions**:
|
|
195
|
+
- `$location` → `location()`
|
|
196
|
+
- `$querystring` → `querystring()`
|
|
197
|
+
- `$params` → `params()`
|
|
198
|
+
- `$loc` → `loc()`
|
|
199
|
+
|
|
200
|
+
- **Events → Props**:
|
|
201
|
+
- `on:routeLoading` → `onrouteLoading`
|
|
202
|
+
- `on:routeLoaded` → `onrouteLoaded`
|
|
203
|
+
- `on:conditionsFailed` → `onconditionsFailed`
|
|
204
|
+
- `on:routeEvent` → `onrouteEvent`
|
|
205
|
+
|
|
206
|
+
- **Component Props**:
|
|
207
|
+
- `export let params` → `let { params } = $props()`
|
|
208
|
+
|
|
209
|
+
- **Reactive Subscriptions**:
|
|
210
|
+
- `.subscribe()` → `$effect(() => { ... })`
|
|
211
|
+
|
|
212
|
+
### Unchanged (Backward Compatible)
|
|
213
|
+
|
|
214
|
+
- ✅ Route definition syntax (same object/Map structure)
|
|
215
|
+
- ✅ `push()`, `pop()`, `replace()` navigation functions
|
|
216
|
+
- ✅ `link` action for anchor tags
|
|
217
|
+
- ✅ `active` action for link highlighting
|
|
218
|
+
- ✅ `wrap()` utility for async components and conditions
|
|
219
|
+
- ✅ Route guards/pre-conditions
|
|
220
|
+
- ✅ Dynamic imports and code-splitting
|
|
221
|
+
- ✅ Nested routers with prefix
|
|
222
|
+
- ✅ Scroll restoration
|
|
223
|
+
- ✅ Loading components
|
|
224
|
+
|
|
225
|
+
### Documentation
|
|
226
|
+
|
|
227
|
+
#### New Files
|
|
228
|
+
- `CONTEXT.md` - Comprehensive project overview
|
|
229
|
+
- `CHANGELOG.md` - This file
|
|
230
|
+
- `DEVELOPMENT.md` - Development workflow guide
|
|
231
|
+
- `MIGRATION.md` - Detailed v4 → v5 migration guide
|
|
232
|
+
- `HASHLESS_MERGE_PLAN.md` - Technical implementation notes
|
|
233
|
+
|
|
234
|
+
#### Updated Files
|
|
235
|
+
- `README.md` - Added routing modes and permission system documentation
|
|
236
|
+
- `package.json` - Updated exports for new modules
|
|
237
|
+
|
|
238
|
+
### Examples
|
|
239
|
+
|
|
240
|
+
- `example/` - Hash mode example (updated for Svelte 5)
|
|
241
|
+
- `example-history/` - History mode example (new)
|
|
242
|
+
|
|
243
|
+
### Infrastructure
|
|
244
|
+
|
|
245
|
+
- ESLint configuration for Svelte 5
|
|
246
|
+
- Makefile for cross-platform development commands
|
|
247
|
+
- Package exports for all modules
|
|
248
|
+
|
|
249
|
+
## Migration Guide
|
|
250
|
+
|
|
251
|
+
See [MIGRATION.md](./MIGRATION.md) for detailed instructions on upgrading from v4 to v5.
|
|
252
|
+
|
|
253
|
+
### Quick Migration Checklist
|
|
254
|
+
|
|
255
|
+
1. ✅ Update imports: `svelte-spa-router` → `@keenmate/svelte-spa-router`
|
|
256
|
+
2. ✅ Change stores to functions: `$location` → `location()`
|
|
257
|
+
3. ✅ Update event handlers: `on:routeLoaded` → `onrouteLoaded`
|
|
258
|
+
4. ✅ Convert component props: `export let params` → `let { params } = $props()`
|
|
259
|
+
5. ✅ Replace subscriptions with `$effect`
|
|
260
|
+
6. ✅ Test all routes and navigation
|
|
261
|
+
|
|
262
|
+
### Optional: Enable History Mode
|
|
263
|
+
|
|
264
|
+
```javascript
|
|
265
|
+
// main.js
|
|
266
|
+
import { setHashRoutingEnabled, setBasePath } from '@keenmate/svelte-spa-router/utils'
|
|
267
|
+
|
|
268
|
+
setHashRoutingEnabled(false)
|
|
269
|
+
setBasePath('/')
|
|
270
|
+
|
|
271
|
+
mount(App, { target: document.body })
|
|
272
|
+
```
|
|
273
|
+
|
|
274
|
+
### Optional: Add Permission System
|
|
275
|
+
|
|
276
|
+
```javascript
|
|
277
|
+
// main.js
|
|
278
|
+
import { configurePermissions } from '@keenmate/svelte-spa-router/helpers/permissions'
|
|
279
|
+
|
|
280
|
+
configurePermissions({
|
|
281
|
+
checkPermissions: (user, requirements) => {
|
|
282
|
+
// Your permission logic
|
|
283
|
+
},
|
|
284
|
+
getCurrentUser: () => getCurrentUser(),
|
|
285
|
+
onUnauthorized: (detail) => push('/unauthorized')
|
|
286
|
+
})
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
## Browser Compatibility
|
|
290
|
+
|
|
291
|
+
- **Svelte 5**: All modern browsers (Chrome, Firefox, Safari, Edge)
|
|
292
|
+
- **Hash Mode**: All browsers including IE10+
|
|
293
|
+
- **History Mode**: All browsers with History API support (IE10+)
|
|
294
|
+
- **Permissions**: All modern browsers
|
|
295
|
+
|
|
296
|
+
## Dependencies
|
|
297
|
+
|
|
298
|
+
### Runtime
|
|
299
|
+
- `regexparam@2.0.2` - Route pattern matching
|
|
300
|
+
|
|
301
|
+
### Peer Dependencies
|
|
302
|
+
- `svelte@^5.0.0` - Required
|
|
303
|
+
|
|
304
|
+
### Dev Dependencies
|
|
305
|
+
- `eslint@^9.0.0` - Code linting
|
|
306
|
+
|
|
307
|
+
## Credits
|
|
308
|
+
|
|
309
|
+
- **Publisher:** KeenMate (https://keenmate.com)
|
|
310
|
+
- **Original svelte-spa-router:** Alessandro Segala (@ItalyPaleAle)
|
|
311
|
+
- **Svelte 5 Conversion:** KeenMate team
|
|
312
|
+
- **History Mode:** Adapted from svelte-spa-router-hashless
|
|
313
|
+
- **Permission System:** KeenMate team
|
|
314
|
+
|
|
315
|
+
## License
|
|
316
|
+
|
|
317
|
+
MIT License - See [LICENSE.md](./LICENSE.md)
|
package/LICENSE.md
CHANGED
|
@@ -1,21 +1,21 @@
|
|
|
1
|
-
# The MIT License
|
|
2
|
-
|
|
3
|
-
Copyright (c) 2019, Alessandro Segala
|
|
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
|
|
13
|
-
all 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
|
|
21
|
-
THE SOFTWARE.
|
|
1
|
+
# The MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2019, Alessandro Segala
|
|
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
|
|
13
|
+
all 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
|
|
21
|
+
THE SOFTWARE.
|