uview-plus 3.8.129 → 3.8.135
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 +65 -0
- package/components/u-cropper/u-cropper.vue +41 -12
- package/components/u-goods-sku/u-goods-sku.vue +18 -2
- package/components/u-lottie/libs/LICENSE-lottie-miniprogram +21 -0
- package/components/u-lottie/libs/LICENSE-lottie-web +21 -0
- package/components/u-lottie/libs/harmony-canvas-adapter.js +394 -0
- package/components/u-lottie/libs/lottie-miniprogram.min.js +14 -0
- package/components/u-lottie/libs/lottie_svg.min.js +6 -0
- package/components/u-lottie/libs/wx-env.js +15 -0
- package/components/u-lottie/lottie.js +9 -0
- package/components/u-lottie/props.js +35 -0
- package/components/u-lottie/u-lottie.vue +635 -0
- package/components/u-number-keyboard/u-number-keyboard.vue +10 -2
- package/components/u-text/u-text.vue +0 -2
- package/components/u-toast/u-toast.vue +32 -5
- package/components/u-upload/props.js +4 -0
- package/components/u-upload/u-upload.vue +3 -1
- package/components/u-upload/upload.js +2 -1
- package/components/u-upload/utils.js +21 -12
- package/libs/function/calc.js +3 -10
- package/package.json +1 -1
- package/types/comps/toast.d.ts +5 -0
- package/types/comps/upload.d.ts +2 -0
package/changelog.md
CHANGED
|
@@ -1,3 +1,68 @@
|
|
|
1
|
+
## 3.8.135
|
|
2
|
+
feat: 新增 u-lottie 动画组件,u-upload 新增 mediaType 并修复 chooseMedia 平台判断
|
|
3
|
+
|
|
4
|
+
本次更新新增 Lottie 动画组件 u-lottie,覆盖 H5/App-Vue、微信小程序与鸿蒙多端渲染;同时为 u-upload 补上 mediaType 属性,并修复 chooseMedia 按平台硬编码导致的兼容性问题。
|
|
5
|
+
|
|
6
|
+
- 新增 u-lottie 组件:支持 filePath 传入动画 JSON 地址(http(s),H5 / App-Vue 额外支持本地静态路径),或 animationData 直接传入 Lottie JSON 对象(优先级高于 filePath);可配置 contentModel 内容填充模式(ScaleToFill / AspectFill / Center)、loop 循环播放、autoplay 数据与引擎就绪后自动播放
|
|
7
|
+
- u-lottie 跨端渲染:H5 / App-Vue 基于 lottie-web SVG 渲染器,H5 端引擎按需加载、加载失败自动清理;微信小程序基于 lottie-miniprogram 画布渲染;鸿蒙通过 harmony-canvas-adapter 画布适配,并修复同步渲染未提交绘制的问题
|
|
8
|
+
- u-lottie 实例方法:reload / playAnimation / pauseAnimation / resumeAnimation / cancelAnimation;statechange 事件统一回报 ready / play / pause / resume / stop / complete / error 状态(微信小程序从 event.detail 读取)
|
|
9
|
+
- u-upload:新增 mediaType 属性(默认 ['image', 'video']),accept 为 media 时透传给 chooseMedia 控制可选文件类型(image / video / mix)
|
|
10
|
+
- u-upload:chooseMedia 不再做平台编译判断,改为运行时检测接口是否存在,不存在时自动回退到 chooseImage,修复部分平台 accept="media" 直接报错的问题
|
|
11
|
+
- 新增 componentsD/lottie 示例页
|
|
12
|
+
|
|
13
|
+
## 3.8.134
|
|
14
|
+
fix: 修复 up-cropper 小程序端底部操作栏透出页面与导出参数失效
|
|
15
|
+
|
|
16
|
+
本次更新修复 u-cropper 的三个问题:iOS 上底部操作栏与页面浮动元素重叠、quality 参数完全失效,以及小数质量被悄悄改回 0.9。
|
|
17
|
+
|
|
18
|
+
- u-cropper:修复 iOS 上底部操作栏与页面浮动按钮/标签重叠的问题。画布高度减掉了底部安全区,而操作栏仍是 50px 贴在屏幕最底,两者之间露出一条约安全区高度的页面背景,页面上浮动的元素会从这条缝里透出来;安卓 safeAreaInsets.bottom 为 0,所以只有苹果机能看到。现在操作栏高度改为 50px + 安全区并用 padding-bottom 让出,与画布严丝合缝,按钮也完整位于 home 指示条上方
|
|
19
|
+
- u-cropper:新增 fileType 属性(默认 png,可选 png/jpg)。原先 5 处导出都把 fileType 硬编码为 png,PNG 是无损格式、没有质量档位,quality 形同虚设;只有 jpg 才会按 quality 压缩,chooseImage 的 params 也可覆盖
|
|
20
|
+
- u-cropper:修复 quality 归一化使用 parseInt 导致 parseInt(0.5) 为 0、被 `|| 0.9` 改回 0.9 的问题,改用 parseFloat 并夹取到 0-1,number 与数字字符串都认
|
|
21
|
+
- u-cropper:safeAreaInsets 取值增加兜底,个别端取不到时不再算出 NaN 把布局顶飞
|
|
22
|
+
- 升级说明:fileType 默认仍为 png,输出格式与升级前一致,不需要改代码;需要压缩体积时显式传 fileType="jpg" 并配合 quality
|
|
23
|
+
- 回归验证:新增 scripts/verify-cropper-export-and-safe-area.mjs,直接加载组件脚本真实调用 computed 与方法,锁住操作栏安全区样式、fileType 透传与 quality 归一化
|
|
24
|
+
|
|
25
|
+
## 3.8.133
|
|
26
|
+
fix: 修复微信小程序数字键盘退格键短按无效,toast 新增 overlay 属性支持提示期间穿透页面
|
|
27
|
+
|
|
28
|
+
本次更新修复 3.8.x 近期引入的两个小程序体验问题,并补上 toast 提示期间页面可操作的能力。
|
|
29
|
+
|
|
30
|
+
- u-number-keyboard:去掉退格键 @touchstart 上残留的 .stop,修复微信小程序 catchtouchstart 吞掉同一节点 tap,导致短按退格不删除内容、只剩长按连删有效的问题
|
|
31
|
+
- u-number-keyboard:补充 @touchcancel 清理定时器,避免触摸被系统手势或滚动打断后长按连删定时器空转
|
|
32
|
+
- u-toast:新增 overlay 属性(默认 true),设置 :overlay="false" 后遮罩由铺满全屏收缩为跟随内容大小并居中的浮动层,提示期间点击与滚动可穿透页面;show() 未显式传值时回落到该 prop,show({ overlay }) 仍然优先
|
|
33
|
+
- types/comps/toast.d.ts 的 ToastProps 补上 overlay,IDE 可提示
|
|
34
|
+
- 回归验证:新增键盘退格点击行为与 toast overlay 穿透两个验证脚本,改动前均失败
|
|
35
|
+
|
|
36
|
+
## 3.8.132
|
|
37
|
+
feat: 新增 u-goods-sku 默认选中与安全区配置,并修复 calc.div 精度崩溃
|
|
38
|
+
|
|
39
|
+
本次更新包含商品 SKU 组件的默认选中能力、底部安全区开关,以及修复浮点除法在无 xyutil 环境下崩溃的问题。
|
|
40
|
+
|
|
41
|
+
- u-goods-sku:新增 defaultSku 属性,支持设置默认选中的 SKU,并支持响应式更新与重置恢复(#1070)
|
|
42
|
+
- u-goods-sku:新增 safeAreaInsetBottom 属性(默认 true),可关闭底部安全距离,并透传给 u-popup
|
|
43
|
+
- calc.div:改用 digit.divide 实现,避免依赖未定义的 xyutil,修复运行环境为空时的崩溃
|
|
44
|
+
- 回归验证:新增 u-goods-sku 默认选中与 calc.div 精度验证脚本
|
|
45
|
+
|
|
46
|
+
## 3.8.131
|
|
47
|
+
fix: 修复微信小程序 u-text 的 v-bind 编译报错
|
|
48
|
+
|
|
49
|
+
修复 3.8.128 引入的 u-text 小程序编译兼容性回归,恢复组件原有的属性继承行为。
|
|
50
|
+
|
|
51
|
+
- u-text:移除原生 button 上不受小程序编译器支持的 v-bind="$attrs",修复 v-bind="" is not supported. 报错。
|
|
52
|
+
- u-text:恢复根节点属性继承,避免普通文本的 id、data-* 等属性丢失;保留原有 data-index、open-type 属性与事件绑定。
|
|
53
|
+
- 回归验证:新增真实微信小程序模板编译和 H5 属性继承测试,并通过微信小程序全量构建。
|
|
54
|
+
- 升级说明:撤回 3.8.128 中任意 data-* 属性向内部分享按钮的自动透传尝试;需要自定义分享数据时,请使用原生 button 显式绑定 data-* 并设置 open-type="share"。
|
|
55
|
+
|
|
56
|
+
## 3.8.130
|
|
57
|
+
fix: 修复微信小程序 u-text 的 v-bind 编译报错
|
|
58
|
+
|
|
59
|
+
修复 3.8.128 引入的 u-text 小程序编译兼容性回归,恢复组件原有的属性继承行为。
|
|
60
|
+
|
|
61
|
+
- u-text:移除原生 button 上不受小程序编译器支持的 v-bind="$attrs",修复 v-bind="" is not supported. 报错。
|
|
62
|
+
- u-text:恢复根节点属性继承,避免普通文本的 id、data-* 等属性丢失;保留原有 data-index、open-type 属性与事件绑定。
|
|
63
|
+
- 回归验证:新增真实微信小程序模板编译和 H5 属性继承测试,并通过微信小程序全量构建。
|
|
64
|
+
- 升级说明:撤回 3.8.128 中任意 data-* 属性向内部分享按钮的自动透传尝试;需要自定义分享数据时,请使用原生 button 显式绑定 data-* 并设置 open-type="share"。
|
|
65
|
+
|
|
1
66
|
## 3.8.129
|
|
2
67
|
fix: 修复条码画布引用时序与微信小程序导航栏胶囊遮挡
|
|
3
68
|
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
<up-canvas ref="avatarCanvas" :canvas-id="'avatar-canvas-' + instanceId" class="my-canvas" :width="windowWidth || 0" :height="windowHeight || 0" :style="{ top: styleTop, height: cvsStyleHeight }" bg-color="transparent"></up-canvas>
|
|
5
5
|
<up-canvas ref="operCanvas" :canvas-id="'oper-canvas-' + instanceId" class="oper-canvas" :width="windowWidth || 0" :height="windowHeight || 0" :style="{ top: styleTop, height: cvsStyleHeight }" bg-color="transparent" @touchstart="start" @touchmove="move" @touchend="end"></up-canvas>
|
|
6
6
|
<up-canvas ref="prvCanvas" :canvas-id="'prv-canvas-' + instanceId" class="prv-canvas" :width="windowWidth || 0" :height="windowHeight || 0" bg-color="transparent" @touchstart="hideImg" :style="{ height: cvsStyleHeight, top: prvTop }"></up-canvas>
|
|
7
|
-
<view class="oper-wrapper" :style="
|
|
7
|
+
<view class="oper-wrapper" :style="operStyle">
|
|
8
8
|
<view class="oper">
|
|
9
9
|
<view class="btn-wrapper" v-if="showOper">
|
|
10
10
|
<view class="u-cropper__action" @click="select" hover-class="hover" :style="{ width: btnWidth }">
|
|
@@ -91,7 +91,9 @@
|
|
|
91
91
|
lock: '',
|
|
92
92
|
noTab: true,
|
|
93
93
|
inner: false,
|
|
94
|
-
quality: '',
|
|
94
|
+
quality: '',
|
|
95
|
+
// 导出图片格式:png 为无损压缩(quality 不生效),jpg 才会按 quality 压缩
|
|
96
|
+
fileType: 'png',
|
|
95
97
|
index: '',
|
|
96
98
|
canChangeSize: false,
|
|
97
99
|
areaWidth: '300rpx',
|
|
@@ -107,11 +109,29 @@
|
|
|
107
109
|
default: 'transparent'
|
|
108
110
|
},
|
|
109
111
|
},
|
|
112
|
+
computed: {
|
|
113
|
+
// 导出图片格式:png 无损,quality 不生效;只有 jpg 才会按 quality 压缩
|
|
114
|
+
expFileType() {
|
|
115
|
+
const type = String(this.fileType || '').toLowerCase();
|
|
116
|
+
return type === 'jpg' || type === 'jpeg' ? 'jpg' : 'png';
|
|
117
|
+
},
|
|
118
|
+
// 底部操作栏样式:把底部安全区算进高度并用 padding-bottom 留出。
|
|
119
|
+
// 画布高度减掉了安全区,而操作栏仍是 50px 贴屏幕最底,两者之间会露出一
|
|
120
|
+
// 条页面背景,页面上浮动的按钮/标签会从这条缝里透出来,和裁剪底部按钮重叠。
|
|
121
|
+
operStyle() {
|
|
122
|
+
const safe = Math.max(0, parseInt(this.safeAreaInsetsBottom) || 0);
|
|
123
|
+
return {
|
|
124
|
+
display: this.styleDisplay,
|
|
125
|
+
height: (tabHeight + safe) + 'px',
|
|
126
|
+
paddingBottom: safe + 'px'
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
},
|
|
110
130
|
created() {
|
|
111
131
|
this.ctxCanvas = null;
|
|
112
132
|
this.ctxCanvasOper = null;
|
|
113
133
|
this.ctxCanvasPrv = null;
|
|
114
|
-
this.qlty =
|
|
134
|
+
this.qlty = this.parseQuality(this.quality);
|
|
115
135
|
this.imgSrc.imgSrc = this.imageSrc;
|
|
116
136
|
this.letRotate = (this.canRotate === false || this.inner === true) ? 0 : 1;
|
|
117
137
|
this.letScale = this.canScale === false ? 0 : 1;
|
|
@@ -147,7 +167,14 @@
|
|
|
147
167
|
mounted() {
|
|
148
168
|
this.initCanvasRefs(true);
|
|
149
169
|
},
|
|
150
|
-
methods: {
|
|
170
|
+
methods: {
|
|
171
|
+
// 图片质量归一化:接受 number 与数字字符串,越界夹到 0-1,无效值回落 0.9
|
|
172
|
+
// 原来用 parseInt,parseInt(0.5) 是 0,`|| 0.9` 会把所有小数质量悄悄改回 0.9
|
|
173
|
+
parseQuality(value) {
|
|
174
|
+
const num = parseFloat(value);
|
|
175
|
+
if (isNaN(num)) return 0.9;
|
|
176
|
+
return Math.min(1, Math.max(0, num));
|
|
177
|
+
},
|
|
151
178
|
t,
|
|
152
179
|
async initCanvasRefs(force = false) {
|
|
153
180
|
await this.$nextTick();
|
|
@@ -170,7 +197,7 @@
|
|
|
170
197
|
this.platform = sysInfo.platform;
|
|
171
198
|
this.pixelRatio = sysInfo.pixelRatio;
|
|
172
199
|
this.windowWidth = sysInfo.windowWidth;
|
|
173
|
-
this.safeAreaInsetsBottom = sysInfo.safeAreaInsets.bottom;
|
|
200
|
+
this.safeAreaInsetsBottom = (sysInfo.safeAreaInsets && sysInfo.safeAreaInsets.bottom) || 0;
|
|
174
201
|
// #ifdef H5
|
|
175
202
|
this.drawTop = sysInfo.windowTop;
|
|
176
203
|
this.windowHeight = sysInfo.windowHeight + sysInfo.windowBottom;
|
|
@@ -319,7 +346,7 @@
|
|
|
319
346
|
height: height,
|
|
320
347
|
destWidth: expWidth,
|
|
321
348
|
destHeight: expHeight,
|
|
322
|
-
fileType:
|
|
349
|
+
fileType: this.expFileType,
|
|
323
350
|
quality: this.qlty,
|
|
324
351
|
success: (r) => {
|
|
325
352
|
r = r.tempFilePath;
|
|
@@ -339,7 +366,7 @@
|
|
|
339
366
|
height: expHeight,
|
|
340
367
|
destWidth: expWidth,
|
|
341
368
|
destHeight: expHeight,
|
|
342
|
-
fileType:
|
|
369
|
+
fileType: this.expFileType,
|
|
343
370
|
quality: this.qlty,
|
|
344
371
|
success: (r) => {
|
|
345
372
|
r = r.tempFilePath;
|
|
@@ -413,7 +440,7 @@
|
|
|
413
440
|
height: prvHeight,
|
|
414
441
|
destWidth: expWidth,
|
|
415
442
|
destHeight: expHeight,
|
|
416
|
-
fileType:
|
|
443
|
+
fileType: this.expFileType,
|
|
417
444
|
quality: this.qlty,
|
|
418
445
|
success: (r) => {
|
|
419
446
|
r = r.tempFilePath;
|
|
@@ -433,7 +460,7 @@
|
|
|
433
460
|
height: expHeight,
|
|
434
461
|
destWidth: expWidth,
|
|
435
462
|
destHeight: expHeight,
|
|
436
|
-
fileType:
|
|
463
|
+
fileType: this.expFileType,
|
|
437
464
|
quality: this.qlty,
|
|
438
465
|
success: (r) => {
|
|
439
466
|
r = r.tempFilePath;
|
|
@@ -670,7 +697,7 @@
|
|
|
670
697
|
y: y,
|
|
671
698
|
width: width,
|
|
672
699
|
height: height,
|
|
673
|
-
fileType:
|
|
700
|
+
fileType: this.expFileType,
|
|
674
701
|
quality: this.qlty,
|
|
675
702
|
success: async (r) => {
|
|
676
703
|
// console.log(r)
|
|
@@ -737,7 +764,8 @@
|
|
|
737
764
|
areaHeight = params.areaHeight || this.areaHeight,
|
|
738
765
|
expWidth = params.exportWidth || this.exportWidth,
|
|
739
766
|
expHeight = params.exportHeight || this.exportHeight,
|
|
740
|
-
quality = params.quality,
|
|
767
|
+
quality = params.quality,
|
|
768
|
+
fileType = params.fileType,
|
|
741
769
|
canRotate = params.canRotate,
|
|
742
770
|
canScale = params.canScale,
|
|
743
771
|
canChangeSize = params.canChangeSize,
|
|
@@ -755,7 +783,8 @@
|
|
|
755
783
|
this.letScale = canScale === false ? 0 : 1;
|
|
756
784
|
// 设置是否允许调整裁剪框大小
|
|
757
785
|
this.letChangeSize = canChangeSize || false;
|
|
758
|
-
this.qlty =
|
|
786
|
+
this.qlty = this.parseQuality(quality);
|
|
787
|
+
if (fileType) this.fileType = fileType;
|
|
759
788
|
this.mnScale = minScale || 0.3;
|
|
760
789
|
this.mxScale = maxScale || 4;
|
|
761
790
|
this.stc = stretch;
|
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
mode="bottom"
|
|
9
9
|
:closeable="pageInline ? false : closeable"
|
|
10
10
|
:pageInline="pageInline"
|
|
11
|
+
:safeAreaInsetBottom="safeAreaInsetBottom"
|
|
11
12
|
:border-radius="20"
|
|
12
13
|
@close="close"
|
|
13
14
|
@closed="$emit('closed')"
|
|
@@ -96,6 +97,11 @@
|
|
|
96
97
|
type: Array,
|
|
97
98
|
default: () => []
|
|
98
99
|
},
|
|
100
|
+
// 默认选中的SKU
|
|
101
|
+
defaultSku: {
|
|
102
|
+
type: Object,
|
|
103
|
+
default: () => ({})
|
|
104
|
+
},
|
|
99
105
|
// 最大购买数量
|
|
100
106
|
maxBuy: {
|
|
101
107
|
type: Number,
|
|
@@ -115,13 +121,18 @@
|
|
|
115
121
|
pageInline: {
|
|
116
122
|
type: Boolean,
|
|
117
123
|
default: false
|
|
124
|
+
},
|
|
125
|
+
// 是否留出底部安全距离
|
|
126
|
+
safeAreaInsetBottom: {
|
|
127
|
+
type: Boolean,
|
|
128
|
+
default: true
|
|
118
129
|
}
|
|
119
130
|
},
|
|
120
131
|
data() {
|
|
121
132
|
return {
|
|
122
133
|
show: false,
|
|
123
134
|
// 已选择的SKU
|
|
124
|
-
selectedSku: {},
|
|
135
|
+
selectedSku: { ...this.defaultSku },
|
|
125
136
|
// 购买数量
|
|
126
137
|
buyNum: 1
|
|
127
138
|
}
|
|
@@ -175,6 +186,11 @@
|
|
|
175
186
|
}
|
|
176
187
|
},
|
|
177
188
|
watch: {
|
|
189
|
+
defaultSku: {
|
|
190
|
+
handler(sku) {
|
|
191
|
+
this.selectedSku = { ...(sku || {}) }
|
|
192
|
+
}
|
|
193
|
+
}
|
|
178
194
|
},
|
|
179
195
|
emits: ['open', 'confirm', 'close', 'closed'],
|
|
180
196
|
created() {
|
|
@@ -281,7 +297,7 @@
|
|
|
281
297
|
},
|
|
282
298
|
// 重置选择
|
|
283
299
|
reset() {
|
|
284
|
-
this.selectedSku = {}
|
|
300
|
+
this.selectedSku = { ...this.defaultSku }
|
|
285
301
|
this.buyNum = 1
|
|
286
302
|
},
|
|
287
303
|
open() {
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2019 wechat-miniprogram
|
|
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,21 @@
|
|
|
1
|
+
The MIT License (MIT)
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2015 Bodymovin
|
|
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.
|