[6a3a178] | 1 | # upath v1.2.0
|
---|
| 2 |
|
---|
| 3 | [![Build Status](https://travis-ci.org/anodynos/upath.svg?branch=master)](https://travis-ci.org/anodynos/upath)
|
---|
| 4 | [![Up to date Status](https://david-dm.org/anodynos/upath.png)](https://david-dm.org/anodynos/upath)
|
---|
| 5 |
|
---|
| 6 | A drop-in replacement / proxy to nodejs's `path` that:
|
---|
| 7 |
|
---|
| 8 | * Replaces the windows `\` with the unix `/` in all string params & results. This has significant positives - see below.
|
---|
| 9 |
|
---|
| 10 | * Adds **filename extensions** functions `addExt`, `trimExt`, `removeExt`, `changeExt`, and `defaultExt`.
|
---|
| 11 |
|
---|
| 12 | * Add a `normalizeSafe` function to preserve any meaningful leading `./` & a `normalizeTrim` which additionally trims any useless ending `/`.
|
---|
| 13 |
|
---|
| 14 | * Plus a helper `toUnix` that simply converts `\` to `/` and consolidates duplicates.
|
---|
| 15 |
|
---|
| 16 | **Useful note: these docs are actually auto generated from [specs](https://github.com/anodynos/upath/blob/master/source/spec/upath-spec.coffee), running on Linux.**
|
---|
| 17 |
|
---|
| 18 | Notes:
|
---|
| 19 |
|
---|
| 20 | * `upath.sep` is set to `'/'` for seamless replacement (as of 1.0.3).
|
---|
| 21 |
|
---|
| 22 | * upath has no runtime dependencies, except built-in `path` (as of 1.0.4)
|
---|
| 23 |
|
---|
| 24 | * travis-ci tested in node versions 4 to 12
|
---|
| 25 |
|
---|
| 26 |
|
---|
| 27 | ## Why ?
|
---|
| 28 |
|
---|
| 29 | Normal `path` doesn't convert paths to a unified format (ie `/`) before calculating paths (`normalize`, `join`), which can lead to numerous problems.
|
---|
| 30 | Also path joining, normalization etc on the two formats is not consistent, depending on where it runs. Running `path` on Windows yields different results than when it runs on Linux / Mac.
|
---|
| 31 |
|
---|
| 32 | In general, if you code your paths logic while developing on Unix/Mac and it runs on Windows, you may run into problems when using `path`.
|
---|
| 33 |
|
---|
| 34 | Note that using **Unix `/` on Windows** works perfectly inside nodejs (and other languages), so there's no reason to stick to the Windows legacy at all.
|
---|
| 35 |
|
---|
| 36 | ##### Examples / specs
|
---|
| 37 |
|
---|
| 38 |
|
---|
| 39 | Check out the different (improved) behavior to vanilla `path`:
|
---|
| 40 |
|
---|
| 41 | `upath.normalize(path)` --returns-->
|
---|
| 42 |
|
---|
| 43 | ✓ `'c:/windows/nodejs/path'` ---> `'c:/windows/nodejs/path'` // equal to `path.normalize()`
|
---|
| 44 | ✓ `'c:/windows/../nodejs/path'` ---> `'c:/nodejs/path'` // equal to `path.normalize()`
|
---|
| 45 | ✓ `'c:\\windows\\nodejs\\path'` ---> `'c:/windows/nodejs/path'` // `path.normalize()` gives `'c:\windows\nodejs\path'`
|
---|
| 46 | ✓ `'c:\\windows\\..\\nodejs\\path'` ---> `'c:/nodejs/path'` // `path.normalize()` gives `'c:\windows\..\nodejs\path'`
|
---|
| 47 | ✓ `'//windows\\unix/mixed'` ---> `'/windows/unix/mixed'` // `path.normalize()` gives `'/windows\unix/mixed'`
|
---|
| 48 | ✓ `'\\windows//unix/mixed'` ---> `'/windows/unix/mixed'` // `path.normalize()` gives `'\windows/unix/mixed'`
|
---|
| 49 | ✓ `'////\\windows\\..\\unix/mixed/'` ---> `'/unix/mixed/'` // `path.normalize()` gives `'/\windows\..\unix/mixed/'`
|
---|
| 50 |
|
---|
| 51 |
|
---|
| 52 | Joining paths can also be a problem:
|
---|
| 53 |
|
---|
| 54 | `upath.join(paths...)` --returns-->
|
---|
| 55 |
|
---|
| 56 | ✓ `'some/nodejs/deep', '../path'` ---> `'some/nodejs/path'` // equal to `path.join()`
|
---|
| 57 | ✓ `'some/nodejs\\windows', '../path'` ---> `'some/nodejs/path'` // `path.join()` gives `'some/path'`
|
---|
| 58 | ✓ `'some\\windows\\only', '..\\path'` ---> `'some/windows/path'` // `path.join()` gives `'some\windows\only/..\path'`
|
---|
| 59 |
|
---|
| 60 |
|
---|
| 61 | Parsing with `path.parse()` should also be consistent across OSes:
|
---|
| 62 |
|
---|
| 63 | `upath.parse(path)` --returns-->
|
---|
| 64 |
|
---|
| 65 | ✓ `'c:\Windows\Directory\somefile.ext'` ---> `{ root: '', dir: 'c:/Windows/Directory', base: 'somefile.ext', ext: '.ext', name: 'somefile' }`
|
---|
| 66 | // `path.parse()` gives `'{ root: '', dir: '', base: 'c:\\Windows\\Directory\\somefile.ext', ext: '.ext', name: 'c:\\Windows\\Directory\\somefile' }'`
|
---|
| 67 | ✓ `'/root/of/unix/somefile.ext'` ---> `{ root: '/', dir: '/root/of/unix', base: 'somefile.ext', ext: '.ext', name: 'somefile' }` // equal to `path.parse()`
|
---|
| 68 |
|
---|
| 69 |
|
---|
| 70 | ## Added functions
|
---|
| 71 |
|
---|
| 72 |
|
---|
| 73 | #### `upath.toUnix(path)`
|
---|
| 74 |
|
---|
| 75 | Just converts all `` to `/` and consolidates duplicates, without performing any normalization.
|
---|
| 76 |
|
---|
| 77 | ##### Examples / specs
|
---|
| 78 |
|
---|
| 79 | `upath.toUnix(path)` --returns-->
|
---|
| 80 |
|
---|
| 81 | ✓ `'.//windows\//unix//mixed////'` ---> `'./windows/unix/mixed/'`
|
---|
| 82 | ✓ `'..///windows\..\\unix/mixed'` ---> `'../windows/../unix/mixed'`
|
---|
| 83 |
|
---|
| 84 |
|
---|
| 85 | #### `upath.normalizeSafe(path)`
|
---|
| 86 |
|
---|
| 87 | Exactly like `path.normalize(path)`, but it keeps the first meaningful `./`.
|
---|
| 88 |
|
---|
| 89 | Note that the unix `/` is returned everywhere, so windows `\` is always converted to unix `/`.
|
---|
| 90 |
|
---|
| 91 | ##### Examples / specs & how it differs from vanilla `path`
|
---|
| 92 |
|
---|
| 93 | `upath.normalizeSafe(path)` --returns-->
|
---|
| 94 |
|
---|
| 95 | ✓ `''` ---> `'.'` // equal to `path.normalize()`
|
---|
| 96 | ✓ `'.'` ---> `'.'` // equal to `path.normalize()`
|
---|
| 97 | ✓ `'./'` ---> `'./'` // equal to `path.normalize()`
|
---|
| 98 | ✓ `'.//'` ---> `'./'` // equal to `path.normalize()`
|
---|
| 99 | ✓ `'.\\'` ---> `'./'` // `path.normalize()` gives `'.\'`
|
---|
| 100 | ✓ `'.\\//'` ---> `'./'` // `path.normalize()` gives `'.\/'`
|
---|
| 101 | ✓ `'./..'` ---> `'..'` // equal to `path.normalize()`
|
---|
| 102 | ✓ `'.//..'` ---> `'..'` // equal to `path.normalize()`
|
---|
| 103 | ✓ `'./../'` ---> `'../'` // equal to `path.normalize()`
|
---|
| 104 | ✓ `'.\\..\\'` ---> `'../'` // `path.normalize()` gives `'.\..\'`
|
---|
| 105 | ✓ `'./../dep'` ---> `'../dep'` // equal to `path.normalize()`
|
---|
| 106 | ✓ `'../dep'` ---> `'../dep'` // equal to `path.normalize()`
|
---|
| 107 | ✓ `'../path/dep'` ---> `'../path/dep'` // equal to `path.normalize()`
|
---|
| 108 | ✓ `'../path/../dep'` ---> `'../dep'` // equal to `path.normalize()`
|
---|
| 109 | ✓ `'dep'` ---> `'dep'` // equal to `path.normalize()`
|
---|
| 110 | ✓ `'path//dep'` ---> `'path/dep'` // equal to `path.normalize()`
|
---|
| 111 | ✓ `'./dep'` ---> `'./dep'` // `path.normalize()` gives `'dep'`
|
---|
| 112 | ✓ `'./path/dep'` ---> `'./path/dep'` // `path.normalize()` gives `'path/dep'`
|
---|
| 113 | ✓ `'./path/../dep'` ---> `'./dep'` // `path.normalize()` gives `'dep'`
|
---|
| 114 | ✓ `'.//windows\\unix/mixed/'` ---> `'./windows/unix/mixed/'` // `path.normalize()` gives `'windows\unix/mixed/'`
|
---|
| 115 | ✓ `'..//windows\\unix/mixed'` ---> `'../windows/unix/mixed'` // `path.normalize()` gives `'../windows\unix/mixed'`
|
---|
| 116 | ✓ `'windows\\unix/mixed/'` ---> `'windows/unix/mixed/'` // `path.normalize()` gives `'windows\unix/mixed/'`
|
---|
| 117 | ✓ `'..//windows\\..\\unix/mixed'` ---> `'../unix/mixed'` // `path.normalize()` gives `'../windows\..\unix/mixed'`
|
---|
| 118 |
|
---|
| 119 |
|
---|
| 120 | #### `upath.normalizeTrim(path)`
|
---|
| 121 |
|
---|
| 122 | Exactly like `path.normalizeSafe(path)`, but it trims any useless ending `/`.
|
---|
| 123 |
|
---|
| 124 | ##### Examples / specs
|
---|
| 125 |
|
---|
| 126 | `upath.normalizeTrim(path)` --returns-->
|
---|
| 127 |
|
---|
| 128 | ✓ `'./'` ---> `'.'` // `upath.normalizeSafe()` gives `'./'`
|
---|
| 129 | ✓ `'./../'` ---> `'..'` // `upath.normalizeSafe()` gives `'../'`
|
---|
| 130 | ✓ `'./../dep/'` ---> `'../dep'` // `upath.normalizeSafe()` gives `'../dep/'`
|
---|
| 131 | ✓ `'path//dep\\'` ---> `'path/dep'` // `upath.normalizeSafe()` gives `'path/dep/'`
|
---|
| 132 | ✓ `'.//windows\\unix/mixed/'` ---> `'./windows/unix/mixed'` // `upath.normalizeSafe()` gives `'./windows/unix/mixed/'`
|
---|
| 133 |
|
---|
| 134 |
|
---|
| 135 | #### `upath.joinSafe([path1][, path2][, ...])`
|
---|
| 136 |
|
---|
| 137 | Exactly like `path.join()`, but it keeps the first meaningful `./`.
|
---|
| 138 |
|
---|
| 139 | Note that the unix `/` is returned everywhere, so windows `\` is always converted to unix `/`.
|
---|
| 140 |
|
---|
| 141 | ##### Examples / specs & how it differs from vanilla `path`
|
---|
| 142 |
|
---|
| 143 | `upath.joinSafe(path)` --returns-->
|
---|
| 144 |
|
---|
| 145 | ✓ `'some/nodejs/deep', '../path'` ---> `'some/nodejs/path'` // equal to `path.join()`
|
---|
| 146 | ✓ `'./some/local/unix/', '../path'` ---> `'./some/local/path'` // `path.join()` gives `'some/local/path'`
|
---|
| 147 | ✓ `'./some\\current\\mixed', '..\\path'` ---> `'./some/current/path'` // `path.join()` gives `'some\current\mixed/..\path'`
|
---|
| 148 | ✓ `'../some/relative/destination', '..\\path'` ---> `'../some/relative/path'` // `path.join()` gives `'../some/relative/destination/..\path'`
|
---|
| 149 |
|
---|
| 150 |
|
---|
| 151 | ## Added functions for *filename extension* manipulation.
|
---|
| 152 |
|
---|
| 153 | **Happy notes:**
|
---|
| 154 |
|
---|
| 155 | In all functions you can:
|
---|
| 156 |
|
---|
| 157 | * use both `.ext` & `ext` - the dot `.` on the extension is always adjusted correctly.
|
---|
| 158 |
|
---|
| 159 | * omit the `ext` param (pass null/undefined/empty string) and the common sense thing will happen.
|
---|
| 160 |
|
---|
| 161 | * ignore specific extensions from being considered as valid ones (eg `.min`, `.dev` `.aLongExtIsNotAnExt` etc), hence no trimming or replacement takes place on them.
|
---|
| 162 |
|
---|
| 163 |
|
---|
| 164 |
|
---|
| 165 | #### `upath.addExt(filename, [ext])`
|
---|
| 166 |
|
---|
| 167 | Adds `.ext` to `filename`, but only if it doesn't already have the exact extension.
|
---|
| 168 |
|
---|
| 169 | ##### Examples / specs
|
---|
| 170 |
|
---|
| 171 | `upath.addExt(filename, 'js')` --returns-->
|
---|
| 172 |
|
---|
| 173 | ✓ `'myfile/addExt'` ---> `'myfile/addExt.js'`
|
---|
| 174 | ✓ `'myfile/addExt.txt'` ---> `'myfile/addExt.txt.js'`
|
---|
| 175 | ✓ `'myfile/addExt.js'` ---> `'myfile/addExt.js'`
|
---|
| 176 | ✓ `'myfile/addExt.min.'` ---> `'myfile/addExt.min..js'`
|
---|
| 177 |
|
---|
| 178 |
|
---|
| 179 | It adds nothing if no `ext` param is passed.
|
---|
| 180 |
|
---|
| 181 | `upath.addExt(filename)` --returns-->
|
---|
| 182 |
|
---|
| 183 | ✓ `'myfile/addExt'` ---> `'myfile/addExt'`
|
---|
| 184 | ✓ `'myfile/addExt.txt'` ---> `'myfile/addExt.txt'`
|
---|
| 185 | ✓ `'myfile/addExt.js'` ---> `'myfile/addExt.js'`
|
---|
| 186 | ✓ `'myfile/addExt.min.'` ---> `'myfile/addExt.min.'`
|
---|
| 187 |
|
---|
| 188 |
|
---|
| 189 | #### `upath.trimExt(filename, [ignoreExts], [maxSize=7])`
|
---|
| 190 |
|
---|
| 191 | Trims a filename's extension.
|
---|
| 192 |
|
---|
| 193 | * Extensions are considered to be up to `maxSize` chars long, counting the dot (defaults to 7).
|
---|
| 194 |
|
---|
| 195 | * An `Array` of `ignoreExts` (eg `['.min']`) prevents these from being considered as extension, thus are not trimmed.
|
---|
| 196 |
|
---|
| 197 | ##### Examples / specs
|
---|
| 198 |
|
---|
| 199 | `upath.trimExt(filename)` --returns-->
|
---|
| 200 |
|
---|
| 201 | ✓ `'my/trimedExt.txt'` ---> `'my/trimedExt'`
|
---|
| 202 | ✓ `'my/trimedExt'` ---> `'my/trimedExt'`
|
---|
| 203 | ✓ `'my/trimedExt.min'` ---> `'my/trimedExt'`
|
---|
| 204 | ✓ `'my/trimedExt.min.js'` ---> `'my/trimedExt.min'`
|
---|
| 205 | ✓ `'../my/trimedExt.longExt'` ---> `'../my/trimedExt.longExt'`
|
---|
| 206 |
|
---|
| 207 |
|
---|
| 208 | It is ignoring `.min` & `.dev` as extensions, and considers exts with up to 8 chars.
|
---|
| 209 |
|
---|
| 210 | `upath.trimExt(filename, ['min', '.dev'], 8)` --returns-->
|
---|
| 211 |
|
---|
| 212 | ✓ `'my/trimedExt.txt'` ---> `'my/trimedExt'`
|
---|
| 213 | ✓ `'my/trimedExt.min'` ---> `'my/trimedExt.min'`
|
---|
| 214 | ✓ `'my/trimedExt.dev'` ---> `'my/trimedExt.dev'`
|
---|
| 215 | ✓ `'../my/trimedExt.longExt'` ---> `'../my/trimedExt'`
|
---|
| 216 | ✓ `'../my/trimedExt.longRExt'` ---> `'../my/trimedExt.longRExt'`
|
---|
| 217 |
|
---|
| 218 |
|
---|
| 219 | #### `upath.removeExt(filename, ext)`
|
---|
| 220 |
|
---|
| 221 | Removes the specific `ext` extension from filename, if it has it. Otherwise it leaves it as is.
|
---|
| 222 | As in all upath functions, it be `.ext` or `ext`.
|
---|
| 223 |
|
---|
| 224 | ##### Examples / specs
|
---|
| 225 |
|
---|
| 226 | `upath.removeExt(filename, '.js')` --returns-->
|
---|
| 227 |
|
---|
| 228 | ✓ `'removedExt.js'` ---> `'removedExt'`
|
---|
| 229 | ✓ `'removedExt.txt.js'` ---> `'removedExt.txt'`
|
---|
| 230 | ✓ `'notRemoved.txt'` ---> `'notRemoved.txt'`
|
---|
| 231 |
|
---|
| 232 | It does not care about the length of exts.
|
---|
| 233 |
|
---|
| 234 | `upath.removeExt(filename, '.longExt')` --returns-->
|
---|
| 235 |
|
---|
| 236 | ✓ `'removedExt.longExt'` ---> `'removedExt'`
|
---|
| 237 | ✓ `'removedExt.txt.longExt'` ---> `'removedExt.txt'`
|
---|
| 238 | ✓ `'notRemoved.txt'` ---> `'notRemoved.txt'`
|
---|
| 239 |
|
---|
| 240 |
|
---|
| 241 | #### `upath.changeExt(filename, [ext], [ignoreExts], [maxSize=7])`
|
---|
| 242 |
|
---|
| 243 | Changes a filename's extension to `ext`. If it has no (valid) extension, it adds it.
|
---|
| 244 |
|
---|
| 245 | * Valid extensions are considered to be up to `maxSize` chars long, counting the dot (defaults to 7).
|
---|
| 246 |
|
---|
| 247 | * An `Array` of `ignoreExts` (eg `['.min']`) prevents these from being considered as extension, thus are not changed - the new extension is added instead.
|
---|
| 248 |
|
---|
| 249 | ##### Examples / specs
|
---|
| 250 |
|
---|
| 251 | `upath.changeExt(filename, '.js')` --returns-->
|
---|
| 252 |
|
---|
| 253 | ✓ `'my/module.min'` ---> `'my/module.js'`
|
---|
| 254 | ✓ `'my/module.coffee'` ---> `'my/module.js'`
|
---|
| 255 | ✓ `'my/module'` ---> `'my/module.js'`
|
---|
| 256 | ✓ `'file/withDot.'` ---> `'file/withDot.js'`
|
---|
| 257 | ✓ `'file/change.longExt'` ---> `'file/change.longExt.js'`
|
---|
| 258 |
|
---|
| 259 |
|
---|
| 260 | If no `ext` param is given, it trims the current extension (if any).
|
---|
| 261 |
|
---|
| 262 | `upath.changeExt(filename)` --returns-->
|
---|
| 263 |
|
---|
| 264 | ✓ `'my/module.min'` ---> `'my/module'`
|
---|
| 265 | ✓ `'my/module.coffee'` ---> `'my/module'`
|
---|
| 266 | ✓ `'my/module'` ---> `'my/module'`
|
---|
| 267 | ✓ `'file/withDot.'` ---> `'file/withDot'`
|
---|
| 268 | ✓ `'file/change.longExt'` ---> `'file/change.longExt'`
|
---|
| 269 |
|
---|
| 270 |
|
---|
| 271 | It is ignoring `.min` & `.dev` as extensions, and considers exts with up to 8 chars.
|
---|
| 272 |
|
---|
| 273 | `upath.changeExt(filename, 'js', ['min', '.dev'], 8)` --returns-->
|
---|
| 274 |
|
---|
| 275 | ✓ `'my/module.coffee'` ---> `'my/module.js'`
|
---|
| 276 | ✓ `'file/notValidExt.min'` ---> `'file/notValidExt.min.js'`
|
---|
| 277 | ✓ `'file/notValidExt.dev'` ---> `'file/notValidExt.dev.js'`
|
---|
| 278 | ✓ `'file/change.longExt'` ---> `'file/change.js'`
|
---|
| 279 | ✓ `'file/change.longRExt'` ---> `'file/change.longRExt.js'`
|
---|
| 280 |
|
---|
| 281 |
|
---|
| 282 | #### `upath.defaultExt(filename, [ext], [ignoreExts], [maxSize=7])`
|
---|
| 283 |
|
---|
| 284 | Adds `.ext` to `filename`, only if it doesn't already have _any_ *old* extension.
|
---|
| 285 |
|
---|
| 286 | * (Old) extensions are considered to be up to `maxSize` chars long, counting the dot (defaults to 7).
|
---|
| 287 |
|
---|
| 288 | * An `Array` of `ignoreExts` (eg `['.min']`) will force adding default `.ext` even if one of these is present.
|
---|
| 289 |
|
---|
| 290 | ##### Examples / specs
|
---|
| 291 |
|
---|
| 292 | `upath.defaultExt(filename, 'js')` --returns-->
|
---|
| 293 |
|
---|
| 294 | ✓ `'fileWith/defaultExt'` ---> `'fileWith/defaultExt.js'`
|
---|
| 295 | ✓ `'fileWith/defaultExt.js'` ---> `'fileWith/defaultExt.js'`
|
---|
| 296 | ✓ `'fileWith/defaultExt.min'` ---> `'fileWith/defaultExt.min'`
|
---|
| 297 | ✓ `'fileWith/defaultExt.longExt'` ---> `'fileWith/defaultExt.longExt.js'`
|
---|
| 298 |
|
---|
| 299 |
|
---|
| 300 | If no `ext` param is passed, it leaves filename intact.
|
---|
| 301 |
|
---|
| 302 | `upath.defaultExt(filename)` --returns-->
|
---|
| 303 |
|
---|
| 304 | ✓ `'fileWith/defaultExt'` ---> `'fileWith/defaultExt'`
|
---|
| 305 | ✓ `'fileWith/defaultExt.js'` ---> `'fileWith/defaultExt.js'`
|
---|
| 306 | ✓ `'fileWith/defaultExt.min'` ---> `'fileWith/defaultExt.min'`
|
---|
| 307 | ✓ `'fileWith/defaultExt.longExt'` ---> `'fileWith/defaultExt.longExt'`
|
---|
| 308 |
|
---|
| 309 |
|
---|
| 310 | It is ignoring `.min` & `.dev` as extensions, and considers exts with up to 8 chars.
|
---|
| 311 |
|
---|
| 312 | `upath.defaultExt(filename, 'js', ['min', '.dev'], 8)` --returns-->
|
---|
| 313 |
|
---|
| 314 | ✓ `'fileWith/defaultExt'` ---> `'fileWith/defaultExt.js'`
|
---|
| 315 | ✓ `'fileWith/defaultExt.min'` ---> `'fileWith/defaultExt.min.js'`
|
---|
| 316 | ✓ `'fileWith/defaultExt.dev'` ---> `'fileWith/defaultExt.dev.js'`
|
---|
| 317 | ✓ `'fileWith/defaultExt.longExt'` ---> `'fileWith/defaultExt.longExt'`
|
---|
| 318 | ✓ `'fileWith/defaultExt.longRext'` ---> `'fileWith/defaultExt.longRext.js'`
|
---|
| 319 |
|
---|
| 320 |
|
---|
| 321 | Copyright(c) 2014-2019 Angelos Pikoulas (agelos.pikoulas@gmail.com)
|
---|
| 322 |
|
---|
| 323 | Permission is hereby granted, free of charge, to any person
|
---|
| 324 | obtaining a copy of this software and associated documentation
|
---|
| 325 | files (the "Software"), to deal in the Software without
|
---|
| 326 | restriction, including without limitation the rights to use,
|
---|
| 327 | copy, modify, merge, publish, distribute, sublicense, and/or sell
|
---|
| 328 | copies of the Software, and to permit persons to whom the
|
---|
| 329 | Software is furnished to do so, subject to the following
|
---|
| 330 | conditions:
|
---|
| 331 |
|
---|
| 332 | The above copyright notice and this permission notice shall be
|
---|
| 333 | included in all copies or substantial portions of the Software.
|
---|
| 334 |
|
---|
| 335 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
---|
| 336 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
---|
| 337 | OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
---|
| 338 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
---|
| 339 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
---|
| 340 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
---|
| 341 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
---|
| 342 | OTHER DEALINGS IN THE SOFTWARE.
|
---|