cerber-core 1.0.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.
- package/.cerber-example/BIBLE.md +132 -0
- package/.cerber-example/CERBER_LAW.md +200 -0
- package/.cerber-example/connections/contracts/booking-to-pricing.json +44 -0
- package/.cerber-example/connections/contracts/pricing-to-booking.json +37 -0
- package/.cerber-example/modules/booking-calendar/MODULE.md +225 -0
- package/.cerber-example/modules/booking-calendar/contract.json +106 -0
- package/.cerber-example/modules/booking-calendar/dependencies.json +8 -0
- package/.cerber-example/modules/pricing-engine/MODULE.md +160 -0
- package/.cerber-example/modules/pricing-engine/contract.json +64 -0
- package/.cerber-example/modules/pricing-engine/dependencies.json +8 -0
- package/CHANGELOG.md +68 -0
- package/LICENSE +21 -0
- package/README.md +1379 -0
- package/bin/cerber +105 -0
- package/bin/cerber-focus +31 -0
- package/bin/cerber-guardian +90 -0
- package/bin/cerber-health +113 -0
- package/bin/cerber-morning +19 -0
- package/bin/cerber-repair +21 -0
- package/dist/cerber/index.d.ts +47 -0
- package/dist/cerber/index.d.ts.map +1 -0
- package/dist/cerber/index.js +154 -0
- package/dist/cerber/index.js.map +1 -0
- package/dist/guardian/index.d.ts +70 -0
- package/dist/guardian/index.d.ts.map +1 -0
- package/dist/guardian/index.js +271 -0
- package/dist/guardian/index.js.map +1 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +9 -0
- package/dist/index.js.map +1 -0
- package/dist/types.d.ts +76 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +5 -0
- package/dist/types.js.map +1 -0
- package/examples/backend-schema.ts +72 -0
- package/examples/frontend-schema.ts +67 -0
- package/examples/health-checks.ts +196 -0
- package/examples/solo-integration/README.md +457 -0
- package/examples/solo-integration/package.json +47 -0
- package/examples/team-integration/README.md +347 -0
- package/examples/team-integration/package.json +23 -0
- package/package.json +104 -0
- package/solo/README.md +258 -0
- package/solo/config/performance-budget.json +53 -0
- package/solo/config/solo-contract.json +71 -0
- package/solo/lib/feature-flags.ts +177 -0
- package/solo/scripts/cerber-auto-repair.js +260 -0
- package/solo/scripts/cerber-daily-check.js +282 -0
- package/solo/scripts/cerber-dashboard.js +191 -0
- package/solo/scripts/cerber-deps-health.js +247 -0
- package/solo/scripts/cerber-docs-sync.js +304 -0
- package/solo/scripts/cerber-flags-check.js +229 -0
- package/solo/scripts/cerber-performance-budget.js +271 -0
- package/solo/scripts/cerber-rollback.js +229 -0
- package/solo/scripts/cerber-snapshot.js +319 -0
- package/team/README.md +327 -0
- package/team/config/team-contract.json +27 -0
- package/team/lib/module-system.ts +157 -0
- package/team/scripts/cerber-add-module.sh +195 -0
- package/team/scripts/cerber-connections-check.sh +186 -0
- package/team/scripts/cerber-focus.sh +170 -0
- package/team/scripts/cerber-module-check.sh +165 -0
- package/team/scripts/cerber-team-morning.sh +210 -0
- package/team/templates/BIBLE_TEMPLATE.md +52 -0
- package/team/templates/CONNECTION_TEMPLATE.json +20 -0
- package/team/templates/MODULE_TEMPLATE.md +60 -0
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": "2.0.0",
|
|
3
|
+
"publicInterface": {
|
|
4
|
+
"checkAvailability": {
|
|
5
|
+
"name": "checkAvailability",
|
|
6
|
+
"params": {
|
|
7
|
+
"roomType": "string",
|
|
8
|
+
"checkIn": "Date",
|
|
9
|
+
"checkOut": "Date",
|
|
10
|
+
"quantity": "number"
|
|
11
|
+
},
|
|
12
|
+
"returns": "AvailabilityResult",
|
|
13
|
+
"description": "Checks if rooms are available for the specified dates"
|
|
14
|
+
},
|
|
15
|
+
"createBooking": {
|
|
16
|
+
"name": "createBooking",
|
|
17
|
+
"params": {
|
|
18
|
+
"roomId": "string",
|
|
19
|
+
"checkIn": "Date",
|
|
20
|
+
"checkOut": "Date",
|
|
21
|
+
"guestInfo": "GuestInfo",
|
|
22
|
+
"totalPrice": "number"
|
|
23
|
+
},
|
|
24
|
+
"returns": "BookingResult",
|
|
25
|
+
"description": "Creates a new booking reservation"
|
|
26
|
+
},
|
|
27
|
+
"cancelBooking": {
|
|
28
|
+
"name": "cancelBooking",
|
|
29
|
+
"params": {
|
|
30
|
+
"bookingId": "string"
|
|
31
|
+
},
|
|
32
|
+
"returns": "CancellationResult",
|
|
33
|
+
"description": "Cancels an existing booking"
|
|
34
|
+
},
|
|
35
|
+
"getBooking": {
|
|
36
|
+
"name": "getBooking",
|
|
37
|
+
"params": {
|
|
38
|
+
"bookingId": "string"
|
|
39
|
+
},
|
|
40
|
+
"returns": "Booking",
|
|
41
|
+
"description": "Retrieves booking details by ID or confirmation code"
|
|
42
|
+
},
|
|
43
|
+
"modifyBooking": {
|
|
44
|
+
"name": "modifyBooking",
|
|
45
|
+
"params": {
|
|
46
|
+
"bookingId": "string",
|
|
47
|
+
"changes": "BookingChanges"
|
|
48
|
+
},
|
|
49
|
+
"returns": "BookingResult",
|
|
50
|
+
"description": "Modifies an existing booking"
|
|
51
|
+
}
|
|
52
|
+
},
|
|
53
|
+
"types": {
|
|
54
|
+
"AvailabilityParams": {
|
|
55
|
+
"roomType": "string",
|
|
56
|
+
"checkIn": "Date",
|
|
57
|
+
"checkOut": "Date",
|
|
58
|
+
"quantity": "number"
|
|
59
|
+
},
|
|
60
|
+
"AvailabilityResult": {
|
|
61
|
+
"available": "boolean",
|
|
62
|
+
"availableCount": "number",
|
|
63
|
+
"conflictingBookings": "string[]"
|
|
64
|
+
},
|
|
65
|
+
"BookingParams": {
|
|
66
|
+
"roomId": "string",
|
|
67
|
+
"checkIn": "Date",
|
|
68
|
+
"checkOut": "Date",
|
|
69
|
+
"guestInfo": "GuestInfo",
|
|
70
|
+
"totalPrice": "number"
|
|
71
|
+
},
|
|
72
|
+
"BookingResult": {
|
|
73
|
+
"bookingId": "string",
|
|
74
|
+
"confirmationCode": "string",
|
|
75
|
+
"status": "string"
|
|
76
|
+
},
|
|
77
|
+
"GuestInfo": {
|
|
78
|
+
"name": "string",
|
|
79
|
+
"email": "string",
|
|
80
|
+
"phone": "string"
|
|
81
|
+
},
|
|
82
|
+
"Booking": {
|
|
83
|
+
"id": "string",
|
|
84
|
+
"roomId": "string",
|
|
85
|
+
"checkIn": "Date",
|
|
86
|
+
"checkOut": "Date",
|
|
87
|
+
"guestInfo": "GuestInfo",
|
|
88
|
+
"totalPrice": "number",
|
|
89
|
+
"status": "string",
|
|
90
|
+
"confirmationCode": "string"
|
|
91
|
+
},
|
|
92
|
+
"CancellationResult": {
|
|
93
|
+
"success": "boolean",
|
|
94
|
+
"refundAmount": "number",
|
|
95
|
+
"cancellationFee": "number"
|
|
96
|
+
},
|
|
97
|
+
"BookingChanges": {
|
|
98
|
+
"checkIn": "Date | undefined",
|
|
99
|
+
"checkOut": "Date | undefined",
|
|
100
|
+
"roomId": "string | undefined"
|
|
101
|
+
}
|
|
102
|
+
},
|
|
103
|
+
"dependencies": [
|
|
104
|
+
"pricing-engine"
|
|
105
|
+
]
|
|
106
|
+
}
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
# Module: pricing-engine
|
|
2
|
+
|
|
3
|
+
**Owner:** Stefan Pitek
|
|
4
|
+
**Status:** Active
|
|
5
|
+
**Last Updated:** 2026-01-02
|
|
6
|
+
|
|
7
|
+
## Purpose
|
|
8
|
+
|
|
9
|
+
Calculates dynamic room pricing based on date, occupancy, season, and other factors. Provides pricing intelligence for the booking system.
|
|
10
|
+
|
|
11
|
+
## Responsibilities
|
|
12
|
+
|
|
13
|
+
- Calculate base room price
|
|
14
|
+
- Apply seasonal multipliers (high/low season)
|
|
15
|
+
- Apply day-of-week adjustments (weekend premiums)
|
|
16
|
+
- Calculate advance booking discounts
|
|
17
|
+
- Apply length-of-stay discounts
|
|
18
|
+
- Provide price breakdowns and explanations
|
|
19
|
+
|
|
20
|
+
## Public Interface
|
|
21
|
+
|
|
22
|
+
Functions/classes that other modules can use:
|
|
23
|
+
|
|
24
|
+
### `calculatePrice(params: PriceParams): PriceResult`
|
|
25
|
+
|
|
26
|
+
Calculates the total price for a room booking.
|
|
27
|
+
|
|
28
|
+
**Parameters:**
|
|
29
|
+
- `roomType` (string) - Type of room (e.g., 'standard', 'deluxe', 'suite')
|
|
30
|
+
- `checkIn` (Date) - Check-in date
|
|
31
|
+
- `checkOut` (Date) - Check-out date
|
|
32
|
+
- `guests` (number) - Number of guests
|
|
33
|
+
- `promoCode` (string, optional) - Promotional code for discounts
|
|
34
|
+
|
|
35
|
+
**Returns:**
|
|
36
|
+
- `totalPrice` (number) - Final calculated price
|
|
37
|
+
- `basePrice` (number) - Base room price
|
|
38
|
+
- `breakdown` (object) - Detailed price breakdown
|
|
39
|
+
- `nightlyRates` (number[]) - Price per night
|
|
40
|
+
- `seasonalAdjustment` (number) - Seasonal multiplier applied
|
|
41
|
+
- `weekendPremium` (number) - Weekend surcharge
|
|
42
|
+
- `advanceBookingDiscount` (number) - Discount for booking in advance
|
|
43
|
+
- `lengthOfStayDiscount` (number) - Discount for extended stays
|
|
44
|
+
- `promoDiscount` (number) - Promotional code discount
|
|
45
|
+
|
|
46
|
+
**Example:**
|
|
47
|
+
```typescript
|
|
48
|
+
import { calculatePrice } from './modules/pricing-engine';
|
|
49
|
+
|
|
50
|
+
const result = calculatePrice({
|
|
51
|
+
roomType: 'deluxe',
|
|
52
|
+
checkIn: new Date('2026-07-15'),
|
|
53
|
+
checkOut: new Date('2026-07-20'),
|
|
54
|
+
guests: 2,
|
|
55
|
+
promoCode: 'SUMMER20'
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
console.log(result.totalPrice); // 850.00
|
|
59
|
+
console.log(result.breakdown); // { nightlyRates: [180, 180, ...], ... }
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
### `getSeasonalMultiplier(date: Date): number`
|
|
63
|
+
|
|
64
|
+
Returns the seasonal pricing multiplier for a given date.
|
|
65
|
+
|
|
66
|
+
**Parameters:**
|
|
67
|
+
- `date` (Date) - Date to check
|
|
68
|
+
|
|
69
|
+
**Returns:**
|
|
70
|
+
- Multiplier (number) - 1.0 = normal, 1.5 = high season, 0.8 = low season
|
|
71
|
+
|
|
72
|
+
**Example:**
|
|
73
|
+
```typescript
|
|
74
|
+
const multiplier = getSeasonalMultiplier(new Date('2026-12-25'));
|
|
75
|
+
console.log(multiplier); // 1.5 (Christmas is high season)
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
### `validatePromoCode(code: string): PromoCodeResult`
|
|
79
|
+
|
|
80
|
+
Validates a promotional code and returns discount information.
|
|
81
|
+
|
|
82
|
+
**Parameters:**
|
|
83
|
+
- `code` (string) - Promo code to validate
|
|
84
|
+
|
|
85
|
+
**Returns:**
|
|
86
|
+
- `valid` (boolean) - Whether code is valid
|
|
87
|
+
- `discount` (number) - Discount percentage (0-100)
|
|
88
|
+
- `minNights` (number) - Minimum nights required
|
|
89
|
+
- `expiryDate` (Date) - When code expires
|
|
90
|
+
|
|
91
|
+
## Dependencies
|
|
92
|
+
|
|
93
|
+
Modules this module uses:
|
|
94
|
+
- `booking-calendar` - To check availability during pricing calculation
|
|
95
|
+
- `database` - To fetch base room prices and seasonal rules
|
|
96
|
+
|
|
97
|
+
## File Structure
|
|
98
|
+
|
|
99
|
+
```
|
|
100
|
+
src/modules/pricing-engine/
|
|
101
|
+
├── index.ts - Public interface (exports calculatePrice, etc.)
|
|
102
|
+
├── calculator.ts - Core pricing logic
|
|
103
|
+
├── seasonal.ts - Seasonal multiplier logic
|
|
104
|
+
├── discounts.ts - Discount calculations
|
|
105
|
+
├── types.ts - TypeScript type definitions
|
|
106
|
+
└── constants.ts - Pricing constants and rules
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
## Testing
|
|
110
|
+
|
|
111
|
+
How to test this module:
|
|
112
|
+
|
|
113
|
+
```bash
|
|
114
|
+
npm test -- pricing-engine
|
|
115
|
+
|
|
116
|
+
# Or specific test suites
|
|
117
|
+
npm test -- pricing-engine.calculator
|
|
118
|
+
npm test -- pricing-engine.seasonal
|
|
119
|
+
npm test -- pricing-engine.discounts
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
Test coverage: 95%
|
|
123
|
+
|
|
124
|
+
## Performance
|
|
125
|
+
|
|
126
|
+
- Average calculation time: 5-10ms
|
|
127
|
+
- Caching: Seasonal multipliers cached for 24h
|
|
128
|
+
- Database queries: 1-2 per calculation (base price + seasonal rules)
|
|
129
|
+
|
|
130
|
+
## Configuration
|
|
131
|
+
|
|
132
|
+
Pricing rules configured in:
|
|
133
|
+
- `config/pricing-rules.json` - Seasonal dates and multipliers
|
|
134
|
+
- Database table `pricing_rules` - Dynamic rules
|
|
135
|
+
- Environment variable `WEEKEND_PREMIUM` - Default 1.2 (20% premium)
|
|
136
|
+
|
|
137
|
+
## Breaking Changes
|
|
138
|
+
|
|
139
|
+
### v2.0.0 (2026-01-02)
|
|
140
|
+
- Changed `calculatePrice` return type to include `breakdown`
|
|
141
|
+
- Removed deprecated `getPrice()` function
|
|
142
|
+
- `promoCode` parameter now optional (was required)
|
|
143
|
+
|
|
144
|
+
### v1.5.0 (2025-12-01)
|
|
145
|
+
- Added `lengthOfStayDiscount` to breakdown
|
|
146
|
+
|
|
147
|
+
## Notes
|
|
148
|
+
|
|
149
|
+
- Pricing engine does NOT handle payment processing (see payment-gateway module)
|
|
150
|
+
- All prices in USD, conversion happens at payment layer
|
|
151
|
+
- Seasonal rules can be overridden by database entries
|
|
152
|
+
- Price calculations are deterministic - same inputs = same output
|
|
153
|
+
- Consider caching results for identical requests within 1 hour
|
|
154
|
+
|
|
155
|
+
## Future Plans
|
|
156
|
+
|
|
157
|
+
- [ ] Add AI-powered dynamic pricing based on demand
|
|
158
|
+
- [ ] Implement competitor price monitoring
|
|
159
|
+
- [ ] Add group booking discounts
|
|
160
|
+
- [ ] Support multiple currencies natively
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": "2.0.0",
|
|
3
|
+
"publicInterface": {
|
|
4
|
+
"calculatePrice": {
|
|
5
|
+
"name": "calculatePrice",
|
|
6
|
+
"params": {
|
|
7
|
+
"roomType": "string",
|
|
8
|
+
"checkIn": "Date",
|
|
9
|
+
"checkOut": "Date",
|
|
10
|
+
"guests": "number",
|
|
11
|
+
"promoCode": "string | undefined"
|
|
12
|
+
},
|
|
13
|
+
"returns": "PriceResult",
|
|
14
|
+
"description": "Calculates the total price for a room booking with detailed breakdown"
|
|
15
|
+
},
|
|
16
|
+
"getSeasonalMultiplier": {
|
|
17
|
+
"name": "getSeasonalMultiplier",
|
|
18
|
+
"params": {
|
|
19
|
+
"date": "Date"
|
|
20
|
+
},
|
|
21
|
+
"returns": "number",
|
|
22
|
+
"description": "Returns the seasonal pricing multiplier for a given date"
|
|
23
|
+
},
|
|
24
|
+
"validatePromoCode": {
|
|
25
|
+
"name": "validatePromoCode",
|
|
26
|
+
"params": {
|
|
27
|
+
"code": "string"
|
|
28
|
+
},
|
|
29
|
+
"returns": "PromoCodeResult",
|
|
30
|
+
"description": "Validates a promotional code and returns discount information"
|
|
31
|
+
}
|
|
32
|
+
},
|
|
33
|
+
"types": {
|
|
34
|
+
"PriceParams": {
|
|
35
|
+
"roomType": "string",
|
|
36
|
+
"checkIn": "Date",
|
|
37
|
+
"checkOut": "Date",
|
|
38
|
+
"guests": "number",
|
|
39
|
+
"promoCode": "string | undefined"
|
|
40
|
+
},
|
|
41
|
+
"PriceResult": {
|
|
42
|
+
"totalPrice": "number",
|
|
43
|
+
"basePrice": "number",
|
|
44
|
+
"breakdown": "PriceBreakdown"
|
|
45
|
+
},
|
|
46
|
+
"PriceBreakdown": {
|
|
47
|
+
"nightlyRates": "number[]",
|
|
48
|
+
"seasonalAdjustment": "number",
|
|
49
|
+
"weekendPremium": "number",
|
|
50
|
+
"advanceBookingDiscount": "number",
|
|
51
|
+
"lengthOfStayDiscount": "number",
|
|
52
|
+
"promoDiscount": "number"
|
|
53
|
+
},
|
|
54
|
+
"PromoCodeResult": {
|
|
55
|
+
"valid": "boolean",
|
|
56
|
+
"discount": "number",
|
|
57
|
+
"minNights": "number",
|
|
58
|
+
"expiryDate": "Date"
|
|
59
|
+
}
|
|
60
|
+
},
|
|
61
|
+
"dependencies": [
|
|
62
|
+
"booking-calendar"
|
|
63
|
+
]
|
|
64
|
+
}
|
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
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
|
+
## [1.0.0] - 2026-01-03
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
- **Guardian 1.0**: Pre-commit architecture validator
|
|
12
|
+
- Forbidden pattern detection with architect approval system
|
|
13
|
+
- Required file validation
|
|
14
|
+
- Required import checking
|
|
15
|
+
- package.json rules validation
|
|
16
|
+
- Recursive directory scanning
|
|
17
|
+
- Detailed error/warning reporting
|
|
18
|
+
- CLI with `--schema`, `--verbose`, `--fail-on-warning` options
|
|
19
|
+
|
|
20
|
+
- **Cerber 2.1**: Runtime health monitoring
|
|
21
|
+
- Flexible health check system
|
|
22
|
+
- Multiple severity levels (critical, error, warning, info)
|
|
23
|
+
- Parallel and sequential check execution
|
|
24
|
+
- Detailed diagnostics with fix suggestions
|
|
25
|
+
- JSON output for CI/CD integration
|
|
26
|
+
- CLI with `--checks`, `--url`, `--parallel` options
|
|
27
|
+
|
|
28
|
+
- **Architect Approval System**:
|
|
29
|
+
- Comment-based approval format: `// ARCHITECT_APPROVED: reason - YYYY-MM-DD - Name`
|
|
30
|
+
- Automatic parsing and tracking
|
|
31
|
+
- Integration with Guardian validation
|
|
32
|
+
|
|
33
|
+
- **Examples**:
|
|
34
|
+
- Frontend schema (React/Vue patterns)
|
|
35
|
+
- Backend schema (Node.js/Express patterns)
|
|
36
|
+
- Health check templates (DB, disk, memory, env vars)
|
|
37
|
+
|
|
38
|
+
- **Documentation**:
|
|
39
|
+
- Comprehensive README with real-world metrics
|
|
40
|
+
- Contributing guidelines
|
|
41
|
+
- API documentation
|
|
42
|
+
- MIT License
|
|
43
|
+
|
|
44
|
+
- **Production Testing**:
|
|
45
|
+
- Extracted from Eliksir project
|
|
46
|
+
- Real metrics: 18 commits, 43 issues detected, 4.5 hours saved
|
|
47
|
+
- 95% bug detection rate pre-production
|
|
48
|
+
- 2 commits blocked by Guardian
|
|
49
|
+
|
|
50
|
+
### Technical Details
|
|
51
|
+
- TypeScript with ES2022 target
|
|
52
|
+
- ESNext modules for modern bundlers
|
|
53
|
+
- Commander.js for CLI
|
|
54
|
+
- Chalk for colored output
|
|
55
|
+
- Full type definitions included
|
|
56
|
+
- Zero runtime dependencies (except CLI deps)
|
|
57
|
+
|
|
58
|
+
## [Unreleased]
|
|
59
|
+
|
|
60
|
+
### Planned
|
|
61
|
+
- Web dashboard for health check visualization
|
|
62
|
+
- Slack/Discord notifications
|
|
63
|
+
- Custom reporter plugins
|
|
64
|
+
- VS Code extension
|
|
65
|
+
- Git hooks integration (Husky)
|
|
66
|
+
- More built-in health checks
|
|
67
|
+
- Performance monitoring
|
|
68
|
+
- Metrics export (Prometheus, DataDog)
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Stefan Pitek
|
|
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.
|