@dp-bohrium/widget-cli 0.5.0 → 0.6.0

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.
@@ -0,0 +1,500 @@
1
+ //#region ../widget-sdk/src/protocol/generated-runtime-contracts.d.ts
2
+ /**
3
+ * 完整渲染请求联合:tool-result(内部)/ file-preview / panel。
4
+ */
5
+ type RenderRequest = (ToolResultRenderRequest | FilePreviewRenderRequest | PanelRenderRequest);
6
+ /**
7
+ * 历史 Host 投影类型;仅供受信任的内部 Host 与协议验证。Forge 新插件不得声明或挂载 tool-result,工具结果应由 Runtime 逻辑映射到自定义 Panel。
8
+ */
9
+ type ToolResultRenderRequest = (RenderRequestBase & {
10
+ contribution: "tool-result";
11
+ content: ToolResultContent;
12
+ });
13
+ /**
14
+ * 渲染状态:loading / partial / complete / error。
15
+ */
16
+ type RenderState = ("loading" | "partial" | "complete" | "error");
17
+ /**
18
+ * 主题模式:light 或 dark。
19
+ */
20
+ type ThemeMode = ("light" | "dark");
21
+ /**
22
+ * Host 已授予的能力;多数分支附带调用与预算限制(ui.presentation / ui.region 除外)。
23
+ */
24
+ type GrantedCapability = ({
25
+ name: "service.invoke";
26
+ services: WidgetServicePermissions;
27
+ limits: {
28
+ callsPerMinute: number;
29
+ requestBytes: number;
30
+ responseBytes: number;
31
+ };
32
+ } | {
33
+ name: "files.list";
34
+ limits: {
35
+ pageSize: number;
36
+ callsPerMinute: number;
37
+ };
38
+ } | {
39
+ name: "files.download";
40
+ limits: {
41
+ bytesPerRun: number;
42
+ callsPerMinute: number;
43
+ };
44
+ } | {
45
+ name: "files.metadata";
46
+ limits: {
47
+ callsPerMinute: number;
48
+ };
49
+ } | {
50
+ name: "files.read";
51
+ limits: {
52
+ bytesPerRequest: number;
53
+ /**
54
+ * @deprecated
55
+ * 历史读取累计额度字段,仅为兼容旧配置保留;当前 files.read 不累计或执行此额度,新宿主不再下发。
56
+ */
57
+ bytesPerRun?: number;
58
+ callsPerMinute: number;
59
+ };
60
+ } | {
61
+ name: "files.write";
62
+ limits: {
63
+ bytesPerRequest: number;
64
+ bytesPerRun: number;
65
+ callsPerMinute: number;
66
+ };
67
+ } | {
68
+ name: "events.read";
69
+ /**
70
+ * @minItems 1
71
+ * @maxItems 32
72
+ */
73
+ topics: [string, ...(string)[]];
74
+ limits: {
75
+ callsPerMinute: number;
76
+ pageSize: number;
77
+ minPollMs: number;
78
+ };
79
+ } | {
80
+ name: "tasks.list";
81
+ limits: {
82
+ callsPerMinute: number;
83
+ pageSize: number;
84
+ minPollMs: number;
85
+ };
86
+ } | {
87
+ name: "tasks.watch";
88
+ limits: {
89
+ callsPerMinute: number;
90
+ pageSize: number;
91
+ minPollMs: number;
92
+ };
93
+ } | {
94
+ name: "ui.state";
95
+ limits: {
96
+ callsPerMinute: number;
97
+ bytesPerRun: number;
98
+ maxValueBytes: number;
99
+ };
100
+ } | {
101
+ name: "actions.invoke";
102
+ /**
103
+ * @minItems 1
104
+ * @maxItems 32
105
+ */
106
+ actions: [string, ...(string)[]];
107
+ limits: {
108
+ callsPerMinute: number;
109
+ };
110
+ } | {
111
+ name: "network.fetch";
112
+ limits: WidgetNetworkLimits;
113
+ } | GrantedPresentationCapability | GrantedRegionCapability);
114
+ /**
115
+ * 服务权限列表。
116
+ *
117
+ * @minItems 1
118
+ * @maxItems 32
119
+ */
120
+ type WidgetServicePermissions = [WidgetServicePermission, ...(WidgetServicePermission)[]];
121
+ /**
122
+ * 正整数。
123
+ */
124
+ type PositiveInteger = number;
125
+ /**
126
+ * 可序列化为 JSON 的任意值;null / boolean / number / string / 数组 / 对象的递归联合。
127
+ */
128
+ type JsonValue = (null | boolean | number | string | JsonValue[] | {
129
+ [k: string]: JsonValue;
130
+ });
131
+ /**
132
+ * 文件预览渲染请求:公共字段 + contribution=file-preview + content。
133
+ */
134
+ type FilePreviewRenderRequest = (RenderRequestBase & {
135
+ contribution: "file-preview";
136
+ content: FilePreviewContent;
137
+ });
138
+ /**
139
+ * 由存储执行端签发的文件内容版本,用于条件读取和保存;不是 RenderRequest.revision。
140
+ */
141
+ type FileRevision = string;
142
+ /**
143
+ * 面板渲染请求:公共字段 + contribution=panel + content。
144
+ */
145
+ type PanelRenderRequest = (RenderRequestBase & {
146
+ contribution: "panel";
147
+ content: PanelContent;
148
+ });
149
+ /**
150
+ * 受控字段诊断或工程相对源码位置;不携带原始对象。
151
+ */
152
+ type WidgetDiagnosticDetail = ({
153
+ field: string;
154
+ expected?: string;
155
+ observed?: string;
156
+ } | {
157
+ file: string;
158
+ line: number;
159
+ column: number;
160
+ excerpt?: string;
161
+ });
162
+ /**
163
+ * 保留 transport、HTTP 与非法响应事实;不包含 URL 或原始响应。
164
+ */
165
+ type WidgetDiagnosticIO = ({
166
+ kind: ("transport" | "invalid-response");
167
+ sourceCode?: string;
168
+ } | {
169
+ kind: "http";
170
+ status: number;
171
+ sourceCode?: string;
172
+ });
173
+ /**
174
+ * 恢复动作的语义及类型化参数;可信宿主绑定已有工具,不包含任意命令。
175
+ */
176
+ type WidgetRecoveryAction = ({
177
+ id: "inspect";
178
+ params: {
179
+ area: ("toolchain" | "host-bridge" | "configuration" | "bundle" | "handshake" | "render" | "capability" | "lease" | "operation-outcome" | "runtime");
180
+ };
181
+ } | {
182
+ id: "wait";
183
+ params: {
184
+ milestone: ("budget-reset" | "connection-restored");
185
+ retryAfterMs?: number;
186
+ };
187
+ } | {
188
+ id: "edit-project";
189
+ params: {
190
+ evidence: "diagnostics";
191
+ };
192
+ } | {
193
+ id: "build-project";
194
+ params: {
195
+ target: "current-project";
196
+ };
197
+ } | {
198
+ id: "refresh-preview";
199
+ params: {
200
+ target: "current-project";
201
+ };
202
+ } | {
203
+ id: "verify-scenario";
204
+ params: {
205
+ target: ("current-attempt" | "next-built-generation");
206
+ scenarioId?: string;
207
+ };
208
+ } | {
209
+ id: "request-external-action";
210
+ params: {
211
+ reason: ("authorization" | "host-support" | "host-start" | "credentials");
212
+ };
213
+ } | {
214
+ id: "stop-preview";
215
+ params: {
216
+ target: "current-preview";
217
+ };
218
+ });
219
+ /**
220
+ * 仅表示受管渲染处理器的处理结果,不代表视觉或业务验收。
221
+ */
222
+ type WidgetRenderResult = ({
223
+ requestId: string;
224
+ revision: number;
225
+ outcome: ("handled" | "superseded");
226
+ } | {
227
+ requestId: string;
228
+ revision: number;
229
+ outcome: "failed";
230
+ diagnostic: WidgetRenderFailureDiagnostic;
231
+ });
232
+ /**
233
+ * 失败处理回执的 SDK 请求诊断;接收方还须匹配当前 requestId。
234
+ */
235
+ type WidgetRenderFailureDiagnostic = (WidgetGuestDiagnostic & {
236
+ correlationId: string;
237
+ phase?: ("render" | "update");
238
+ });
239
+ /**
240
+ * Guest 仅声明 SDK 诊断事实,不得冒充 Host 或工具链。
241
+ */
242
+ type WidgetGuestDiagnostic = (WidgetDevelopmentDiagnostic & {
243
+ source: "sdk";
244
+ });
245
+ /**
246
+ * 渲染请求公共字段:schemaVersion、requestId、instanceId、revision、state、context。
247
+ */
248
+ interface RenderRequestBase {
249
+ schemaVersion: 1;
250
+ requestId: string;
251
+ instanceId: string;
252
+ revision: number;
253
+ state: RenderState;
254
+ context: WidgetRenderContext;
255
+ }
256
+ /**
257
+ * 渲染上下文:locale、theme、viewport、能力与关联 id。
258
+ */
259
+ interface WidgetRenderContext {
260
+ locale: string;
261
+ theme: Theme;
262
+ viewport: {
263
+ width: number;
264
+ height: number;
265
+ };
266
+ capabilities: GrantedCapability[];
267
+ correlationId: string;
268
+ }
269
+ /**
270
+ * 渲染上下文中的主题:mode 与设计令牌表。
271
+ */
272
+ interface Theme {
273
+ mode: ThemeMode;
274
+ tokens: {
275
+ background: string;
276
+ foreground: string;
277
+ muted: string;
278
+ mutedForeground: string;
279
+ border: string;
280
+ primary: string;
281
+ danger: string;
282
+ };
283
+ }
284
+ /**
285
+ * 单条服务权限:服务名 + 允许的动作列表。
286
+ */
287
+ interface WidgetServicePermission {
288
+ service: string;
289
+ /**
290
+ * @minItems 1
291
+ * @maxItems 32
292
+ */
293
+ actions: [string, ...(string)[]];
294
+ }
295
+ /**
296
+ * Host 托管网络的限制项:超时、并发、频率与字节数。
297
+ */
298
+ interface WidgetNetworkLimits {
299
+ timeoutMs: PositiveInteger;
300
+ maxRedirects: PositiveInteger;
301
+ maxConcurrentRequests: PositiveInteger;
302
+ callsPerMinute: PositiveInteger;
303
+ requestHeaderBytes: PositiveInteger;
304
+ responseHeaderBytes: PositiveInteger;
305
+ requestBodyBytes: PositiveInteger;
306
+ responseBodyBytes: PositiveInteger;
307
+ }
308
+ /**
309
+ * 已授予的呈现能力;含 surfaces,requiresHostConfirmation 恒为 true。
310
+ */
311
+ interface GrantedPresentationCapability {
312
+ name: "ui.presentation";
313
+ /**
314
+ * @minItems 1
315
+ * @maxItems 2
316
+ */
317
+ surfaces: [("floating" | "overlay")] | [("floating" | "overlay"), ("floating" | "overlay")];
318
+ requiresHostConfirmation: true;
319
+ }
320
+ /**
321
+ * 已授予的会话右侧区域替换能力。
322
+ */
323
+ interface GrantedRegionCapability {
324
+ name: "ui.region";
325
+ /**
326
+ * @minItems 1
327
+ * @maxItems 1
328
+ */
329
+ regions: ["session.rightRail"];
330
+ mode: "replace";
331
+ requiresHostConfirmation: true;
332
+ }
333
+ /**
334
+ * tool-result 渲染内容;仅内部通道使用,外部作者不挂载。
335
+ */
336
+ interface ToolResultContent {
337
+ contribution: "tool-result";
338
+ tool: {
339
+ name: string;
340
+ callId: string;
341
+ status: ("running" | "succeeded" | "failed" | "cancelled");
342
+ };
343
+ input: JsonValue;
344
+ result?: JsonValue;
345
+ envelope?: ToolResultEnvelope;
346
+ error?: {
347
+ code: string;
348
+ message: string;
349
+ };
350
+ }
351
+ /**
352
+ * 工具执行结果信封;仅供受信任的内部 Host 与 Agent 事件,不进入作者 Contribution。
353
+ */
354
+ interface ToolResultEnvelope {
355
+ schemaVersion: 1;
356
+ status: ("running" | "succeeded" | "failed" | "cancelled");
357
+ summary?: string;
358
+ data?: JsonValue;
359
+ /**
360
+ * @maxItems 64
361
+ */
362
+ metrics?: ToolResultMetric[];
363
+ /**
364
+ * @maxItems 64
365
+ */
366
+ artifacts?: ToolResultArtifact[];
367
+ /**
368
+ * @maxItems 32
369
+ */
370
+ provenance?: ToolResultProvenance[];
371
+ /**
372
+ * @maxItems 32
373
+ */
374
+ warnings?: ToolResultNotice[];
375
+ /**
376
+ * @maxItems 32
377
+ */
378
+ missing?: ToolResultNotice[];
379
+ }
380
+ /**
381
+ * 工具结果中的单个指标。
382
+ */
383
+ interface ToolResultMetric {
384
+ name: string;
385
+ value: number;
386
+ unit?: string;
387
+ label?: string;
388
+ }
389
+ /**
390
+ * 工具结果中的产物元数据,不含内容本身。
391
+ */
392
+ interface ToolResultArtifact {
393
+ id: string;
394
+ name: string;
395
+ kind?: ("file" | "directory");
396
+ mimeType?: string;
397
+ size?: number;
398
+ downloadable?: boolean;
399
+ }
400
+ /**
401
+ * 工具结果的来源信息。
402
+ */
403
+ interface ToolResultProvenance {
404
+ source: string;
405
+ kind?: string;
406
+ label?: string;
407
+ }
408
+ /**
409
+ * 工具结果中的提示或警告。
410
+ */
411
+ interface ToolResultNotice {
412
+ code: string;
413
+ message: string;
414
+ }
415
+ /**
416
+ * 文件预览内容;contribution 必须为 file-preview。
417
+ */
418
+ interface FilePreviewContent {
419
+ contribution: "file-preview";
420
+ file: FileReference;
421
+ preview?: JsonValue;
422
+ }
423
+ /**
424
+ * Host 签发的文件引用;仅含不透明 id、可选内容版本和展示元数据。引用本身不授予写权限,不含路径或 URL。
425
+ */
426
+ interface FileReference {
427
+ id: string;
428
+ kind: ("file" | "directory");
429
+ name: string;
430
+ extension?: string;
431
+ mimeType?: string;
432
+ size?: number;
433
+ revision?: FileRevision;
434
+ }
435
+ /**
436
+ * 面板内容;contribution 必须为 panel。
437
+ */
438
+ interface PanelContent {
439
+ contribution: "panel";
440
+ id: string;
441
+ title?: string;
442
+ data: JsonValue;
443
+ }
444
+ /**
445
+ * 可信出口的标准诊断;恢复指令和 scope 由宿主另行生成。
446
+ */
447
+ interface WidgetDevelopmentDiagnostic {
448
+ schemaVersion: 1;
449
+ source: ("sdk" | "host" | "toolchain");
450
+ code: string;
451
+ sourceCode?: string;
452
+ phase: ("discovery" | "build" | "config" | "load" | "handshake" | "render" | "update" | "capability" | "dispose");
453
+ sourcePhase?: string;
454
+ operation: string;
455
+ severity: ("warning" | "request-error" | "instance-failure");
456
+ message: string;
457
+ retryable?: boolean;
458
+ correlationId?: string;
459
+ /**
460
+ * @maxItems 8
461
+ */
462
+ diagnostics?: [] | [WidgetDiagnosticDetail] | [WidgetDiagnosticDetail, WidgetDiagnosticDetail] | [WidgetDiagnosticDetail, WidgetDiagnosticDetail, WidgetDiagnosticDetail] | [WidgetDiagnosticDetail, WidgetDiagnosticDetail, WidgetDiagnosticDetail, WidgetDiagnosticDetail] | [WidgetDiagnosticDetail, WidgetDiagnosticDetail, WidgetDiagnosticDetail, WidgetDiagnosticDetail, WidgetDiagnosticDetail] | [WidgetDiagnosticDetail, WidgetDiagnosticDetail, WidgetDiagnosticDetail, WidgetDiagnosticDetail, WidgetDiagnosticDetail, WidgetDiagnosticDetail] | [WidgetDiagnosticDetail, WidgetDiagnosticDetail, WidgetDiagnosticDetail, WidgetDiagnosticDetail, WidgetDiagnosticDetail, WidgetDiagnosticDetail, WidgetDiagnosticDetail] | [WidgetDiagnosticDetail, WidgetDiagnosticDetail, WidgetDiagnosticDetail, WidgetDiagnosticDetail, WidgetDiagnosticDetail, WidgetDiagnosticDetail, WidgetDiagnosticDetail, WidgetDiagnosticDetail];
463
+ io?: WidgetDiagnosticIO;
464
+ }
465
+ /**
466
+ * 可信宿主观察到的恢复进展;重复故障无新证据时不能重复同一修复。
467
+ */
468
+ interface WidgetRecoveryProgress {
469
+ repeated: boolean;
470
+ hasNewEvidence: boolean;
471
+ }
472
+ /**
473
+ * 可信宿主选择的恢复计划;不能由 Guest 的诊断 payload 指定。
474
+ */
475
+ interface WidgetRecoveryPlan {
476
+ progress?: WidgetRecoveryProgress;
477
+ schemaVersion: 1;
478
+ ruleId: string;
479
+ ruleVersion: number;
480
+ disposition: ("retry" | "repair" | "inspect" | "external-action" | "stop");
481
+ nextAction: WidgetRecoveryAction;
482
+ verification: WidgetRecoveryVerification;
483
+ guidance: string;
484
+ /**
485
+ * 首项动作完成后的有限恢复步骤;宿主逐步验证前置条件,不原样盲目重放。
486
+ *
487
+ * @maxItems 8
488
+ */
489
+ followUpActions: [] | [WidgetRecoveryAction] | [WidgetRecoveryAction, WidgetRecoveryAction] | [WidgetRecoveryAction, WidgetRecoveryAction, WidgetRecoveryAction] | [WidgetRecoveryAction, WidgetRecoveryAction, WidgetRecoveryAction, WidgetRecoveryAction] | [WidgetRecoveryAction, WidgetRecoveryAction, WidgetRecoveryAction, WidgetRecoveryAction, WidgetRecoveryAction] | [WidgetRecoveryAction, WidgetRecoveryAction, WidgetRecoveryAction, WidgetRecoveryAction, WidgetRecoveryAction, WidgetRecoveryAction] | [WidgetRecoveryAction, WidgetRecoveryAction, WidgetRecoveryAction, WidgetRecoveryAction, WidgetRecoveryAction, WidgetRecoveryAction, WidgetRecoveryAction] | [WidgetRecoveryAction, WidgetRecoveryAction, WidgetRecoveryAction, WidgetRecoveryAction, WidgetRecoveryAction, WidgetRecoveryAction, WidgetRecoveryAction, WidgetRecoveryAction];
490
+ }
491
+ /**
492
+ * 恢复复验目标;下一成功构建须在取得回执后绑定实际产物。
493
+ */
494
+ interface WidgetRecoveryVerification {
495
+ target: ("current-attempt" | "next-built-generation" | "original-operation");
496
+ milestone: ("diagnostics-updated" | "render-handled" | "scenario-passed" | "operation-confirmed");
497
+ scenarioId?: string;
498
+ }
499
+ //#endregion
500
+ export { WidgetRenderResult as i, WidgetDevelopmentDiagnostic as n, WidgetRecoveryPlan as r, RenderRequest as t };
package/llms.txt CHANGED
@@ -41,8 +41,8 @@ pnpm exec bohr-widget --version --json
41
41
  - `integration --json`: `interfaceVersion=3`,返回固定 profile、执行器位置、
42
42
  `toolchain.formatVersion=3` 和 `documentation { url, quickStart, cli, llms, llmsFull }`,
43
43
  不返回 `skills`。已有工程加 `--project <目录>` 核对锁定,再读取对应参考。
44
- - `create`: 创建 vanilla 或 React 工程并写 `widget-toolchain.json`;工作区文件面板使用
45
- `--panel-id workspace-files`。
44
+ - `create`: 创建 vanilla 或 React 工程并写 `widget-toolchain.json`;Panel ID 可自定义,
45
+ `--panel-id workspace-files` 是可选的文件浏览面板预设。
46
46
  - `adopt`: 为旧工程显式写入工具链锁,先核对精确依赖、实际 SDK 与内置协议摘要、Manifest 和 samples。
47
47
  - SDK 0.5.0 的任务 Panel 在 Manifest 声明 `capabilities.tasks.list`;需要观察单个任务时再声明
48
48
  `tasks.watch`。列表刷新遵守 grant 的 `minPollMs`,面板不可见后停止轮询;CLI 校验通过不代表
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dp-bohrium/widget-cli",
3
- "version": "0.5.0",
3
+ "version": "0.6.0",
4
4
  "description": "Bohrium Widget 插件工程的创建、校验、开发和打包工具。",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -46,24 +46,21 @@
46
46
  "@types/node": "^22.15.0",
47
47
  "tsdown": "0.22.14",
48
48
  "typescript": "5.9.3",
49
- "@dp-bohrium/widget-contracts": "0.7.0",
50
- "@dp-bohrium/widget-contract-testing": "0.1.0-alpha.0",
51
- "@dp-bohrium/widget-sdk": "0.7.0"
49
+ "@dp-bohrium/widget-sdk": "0.9.0"
52
50
  },
53
51
  "sideEffects": false,
54
52
  "publishConfig": {
55
53
  "access": "public"
56
54
  },
57
55
  "scripts": {
58
- "build:assets": "node scripts/build-assets.mjs",
59
- "build:types": "tsdown --config types.tsdown.config.ts",
60
56
  "package:contents": "node ../../scripts/quality/check-widget-cli-package-contents.mjs ../../.artifacts/dp-bohrium-widget-cli-*.tgz",
61
- "build:inputs": "pnpm --filter @dp-bohrium/widget-sdk... run build && pnpm --filter @dp-bohrium/widget-contract-testing run build",
62
- "build": "pnpm build:inputs && pnpm build:assets && tsdown && pnpm build:types && node --check dist/cli.mjs",
63
- "typecheck": "node --check src/cli.mjs && node --check src/help.mjs && node --check src/core.mjs && node --check src/templates.mjs && node --check src/toolchain.mjs && node --check src/project-executor.mjs && node --check scripts/build-assets.mjs",
64
- "test": "pnpm build:inputs && pnpm build:assets && pnpm build:types && node --test test/*.test.mjs",
57
+ "build": "node ../../scripts/build/widget-build.mjs cli",
58
+ "typecheck": "node --check src/cli.mjs && node --check src/help.mjs && node --check src/core.mjs && node --check src/templates.mjs && node --check src/toolchain.mjs && node --check src/project-executor.mjs && node --check scripts/build-assets.mjs && tsc --project tsconfig.project.json",
59
+ "test": "node ../../scripts/build/with-build.mjs all -- node --test test/*.test.mjs test/project/*.test.mjs",
65
60
  "lint": "biome check src test scripts",
66
61
  "format:check": "biome check --linter-enabled=false src test scripts",
67
- "check": "pnpm --filter @dp-bohrium/widget-contracts build && pnpm --filter @dp-bohrium/widget-contract-testing build && pnpm --filter widget-project build && pnpm typecheck && pnpm test && pnpm lint && pnpm format:check && pnpm build"
62
+ "check": "pnpm typecheck && pnpm test && pnpm lint && pnpm format:check && pnpm build",
63
+ "test:coverage": "node ../../scripts/build/with-build.mjs all -- node --experimental-test-coverage --test-coverage-include=src/project/*.mjs --test-coverage-lines=80 --test-coverage-functions=80 --test-coverage-branches=70 --test test/project/*.test.mjs",
64
+ "build:tools": "node ../../scripts/build/widget-build.mjs tools"
68
65
  }
69
66
  }
@@ -1,21 +0,0 @@
1
- MIT License
2
-
3
- Copyright (c) 2026 DP Technology
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.