pms_md 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/README.md +93 -0
- package/node-monitor/ARCHITECTURE.md +341 -0
- package/node-monitor/CHANGELOG.md +105 -0
- package/node-monitor/CONTRIBUTING.md +96 -0
- package/node-monitor/DESIGN_IMPROVEMENTS.md +286 -0
- package/node-monitor/FILTER_BUTTONS_FIX.md +303 -0
- package/node-monitor/GETTING_STARTED.md +416 -0
- package/node-monitor/INSTALLATION.md +470 -0
- package/node-monitor/LICENSE +22 -0
- package/node-monitor/PUBLISHING_GUIDE.md +331 -0
- package/node-monitor/QUICK_REFERENCE.md +252 -0
- package/node-monitor/README.md +458 -0
- package/node-monitor/READY_TO_PUBLISH.md +272 -0
- package/node-monitor/SETUP_GUIDE.md +479 -0
- package/node-monitor/examples/EMAIL_SETUP_GUIDE.md +282 -0
- package/node-monitor/examples/ERROR_LOGGING_GUIDE.md +405 -0
- package/node-monitor/examples/GET_APP_PASSWORD.md +145 -0
- package/node-monitor/examples/LOG_FILES_REFERENCE.md +336 -0
- package/node-monitor/examples/QUICK_START_EMAIL.md +126 -0
- package/node-monitor/examples/express-app.js +499 -0
- package/node-monitor/examples/package-lock.json +1295 -0
- package/node-monitor/examples/package.json +18 -0
- package/node-monitor/examples/public/css/style.css +718 -0
- package/node-monitor/examples/public/js/dashboard.js +207 -0
- package/node-monitor/examples/public/js/health.js +114 -0
- package/node-monitor/examples/public/js/main.js +89 -0
- package/node-monitor/examples/public/js/metrics.js +225 -0
- package/node-monitor/examples/public/js/theme.js +138 -0
- package/node-monitor/examples/views/dashboard.ejs +20 -0
- package/node-monitor/examples/views/error-logs.ejs +1129 -0
- package/node-monitor/examples/views/health.ejs +21 -0
- package/node-monitor/examples/views/home.ejs +341 -0
- package/node-monitor/examples/views/layout.ejs +50 -0
- package/node-monitor/examples/views/metrics.ejs +16 -0
- package/node-monitor/examples/views/partials/footer.ejs +16 -0
- package/node-monitor/examples/views/partials/header.ejs +35 -0
- package/node-monitor/examples/views/partials/nav.ejs +23 -0
- package/node-monitor/examples/views/status.ejs +390 -0
- package/node-monitor/package-lock.json +4300 -0
- package/node-monitor/package.json +76 -0
- package/node-monitor/pre-publish-check.js +200 -0
- package/node-monitor/src/config/monitoringConfig.js +255 -0
- package/node-monitor/src/index.js +300 -0
- package/node-monitor/src/logger/errorLogger.js +297 -0
- package/node-monitor/src/monitors/apiErrorMonitor.js +156 -0
- package/node-monitor/src/monitors/dbConnectionMonitor.js +389 -0
- package/node-monitor/src/monitors/serverHealthMonitor.js +320 -0
- package/node-monitor/src/monitors/systemResourceMonitor.js +357 -0
- package/node-monitor/src/notifiers/emailNotifier.js +248 -0
- package/node-monitor/src/notifiers/notificationManager.js +96 -0
- package/node-monitor/src/notifiers/slackNotifier.js +209 -0
- package/node-monitor/src/views/dashboard.html +530 -0
- package/node-monitor/src/views/health.html +399 -0
- package/node-monitor/src/views/metrics.html +406 -0
- package/package.json +22 -0
|
@@ -0,0 +1,470 @@
|
|
|
1
|
+
# Installation & Testing Guide
|
|
2
|
+
|
|
3
|
+
## Installation
|
|
4
|
+
|
|
5
|
+
### Option 1: Install from npm (When Published)
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @projectmd/node-monitor
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
### Option 2: Install from Local Directory (For Development)
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
# From the node-monitor directory
|
|
15
|
+
npm install
|
|
16
|
+
|
|
17
|
+
# Link the package globally
|
|
18
|
+
npm link
|
|
19
|
+
|
|
20
|
+
# In your project directory
|
|
21
|
+
npm link @projectmd/node-monitor
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
### Option 3: Install from Git Repository
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
npm install git+https://github.com/yourorg/node-monitor.git
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## Installing Dependencies
|
|
31
|
+
|
|
32
|
+
### Core Dependencies (Required)
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
cd node-monitor
|
|
36
|
+
npm install
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
This installs:
|
|
40
|
+
- winston
|
|
41
|
+
- winston-daily-rotate-file
|
|
42
|
+
- nodemailer
|
|
43
|
+
- @slack/webhook
|
|
44
|
+
- axios
|
|
45
|
+
- node-cron
|
|
46
|
+
|
|
47
|
+
### Peer Dependencies (Optional - Install as Needed)
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
# For Express integration
|
|
51
|
+
npm install express
|
|
52
|
+
|
|
53
|
+
# For MongoDB monitoring
|
|
54
|
+
npm install mongoose
|
|
55
|
+
|
|
56
|
+
# For PostgreSQL monitoring
|
|
57
|
+
npm install pg
|
|
58
|
+
|
|
59
|
+
# For MySQL monitoring
|
|
60
|
+
npm install mysql2
|
|
61
|
+
|
|
62
|
+
# For Redis monitoring
|
|
63
|
+
npm install ioredis
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
## Running the Example Application
|
|
67
|
+
|
|
68
|
+
### Step 1: Install Example Dependencies
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
cd examples
|
|
72
|
+
npm install
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
### Step 2: Configure Environment (Optional)
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
# Copy the example env file
|
|
79
|
+
cp ../.env.example .env
|
|
80
|
+
|
|
81
|
+
# Edit .env with your settings
|
|
82
|
+
nano .env
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
### Step 3: Run the Example
|
|
86
|
+
|
|
87
|
+
```bash
|
|
88
|
+
npm start
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
The server will start on http://localhost:3000
|
|
92
|
+
|
|
93
|
+
### Step 4: Test the Endpoints
|
|
94
|
+
|
|
95
|
+
```bash
|
|
96
|
+
# Health check
|
|
97
|
+
curl http://localhost:3000/health
|
|
98
|
+
|
|
99
|
+
# Health info
|
|
100
|
+
curl http://localhost:3000/health/info
|
|
101
|
+
|
|
102
|
+
# Monitoring dashboard
|
|
103
|
+
curl http://localhost:3000/monitor/dashboard
|
|
104
|
+
|
|
105
|
+
# Test success endpoint
|
|
106
|
+
curl http://localhost:3000/api/success
|
|
107
|
+
|
|
108
|
+
# Test error endpoint
|
|
109
|
+
curl http://localhost:3000/api/error
|
|
110
|
+
|
|
111
|
+
# Test slow endpoint
|
|
112
|
+
curl http://localhost:3000/api/slow
|
|
113
|
+
|
|
114
|
+
# Test 404
|
|
115
|
+
curl http://localhost:3000/nonexistent
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
## Testing Notifications
|
|
119
|
+
|
|
120
|
+
### Test Email Notifications
|
|
121
|
+
|
|
122
|
+
1. Configure email in `.env`:
|
|
123
|
+
```env
|
|
124
|
+
MONITOR_EMAIL_ENABLED=true
|
|
125
|
+
MONITOR_EMAIL_HOST=smtp.gmail.com
|
|
126
|
+
MONITOR_EMAIL_PORT=587
|
|
127
|
+
MONITOR_EMAIL_USER=your-email@gmail.com
|
|
128
|
+
MONITOR_EMAIL_PASS=your-app-password
|
|
129
|
+
MONITOR_EMAIL_RECIPIENTS=test@example.com
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
2. Send test notification:
|
|
133
|
+
```bash
|
|
134
|
+
curl -X POST http://localhost:3000/api/notify \
|
|
135
|
+
-H "Content-Type: application/json" \
|
|
136
|
+
-d '{
|
|
137
|
+
"level": "info",
|
|
138
|
+
"subject": "Test Email",
|
|
139
|
+
"message": "This is a test email notification"
|
|
140
|
+
}'
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
### Test Slack Notifications
|
|
144
|
+
|
|
145
|
+
1. Configure Slack in `.env`:
|
|
146
|
+
```env
|
|
147
|
+
MONITOR_SLACK_ENABLED=true
|
|
148
|
+
MONITOR_SLACK_WEBHOOK=https://hooks.slack.com/services/YOUR/WEBHOOK
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
2. Send test notification:
|
|
152
|
+
```bash
|
|
153
|
+
curl -X POST http://localhost:3000/api/notify \
|
|
154
|
+
-H "Content-Type: application/json" \
|
|
155
|
+
-d '{
|
|
156
|
+
"level": "warning",
|
|
157
|
+
"subject": "Test Slack",
|
|
158
|
+
"message": "This is a test Slack notification"
|
|
159
|
+
}'
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
## Testing Database Monitoring
|
|
163
|
+
|
|
164
|
+
### MongoDB Example
|
|
165
|
+
|
|
166
|
+
```javascript
|
|
167
|
+
// In examples/express-app.js, uncomment:
|
|
168
|
+
const mongoose = require('mongoose');
|
|
169
|
+
await mongoose.connect('mongodb://localhost:27017/test');
|
|
170
|
+
monitor.registerDatabase('mongodb', 'mongoose', mongoose.connection);
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
### PostgreSQL Example
|
|
174
|
+
|
|
175
|
+
```javascript
|
|
176
|
+
const { Pool } = require('pg');
|
|
177
|
+
const pool = new Pool({ connectionString: 'postgresql://localhost/test' });
|
|
178
|
+
monitor.registerDatabase('postgres', 'postgresql', pool);
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
## Verifying Installation
|
|
182
|
+
|
|
183
|
+
### Check Logs
|
|
184
|
+
|
|
185
|
+
```bash
|
|
186
|
+
# View application logs
|
|
187
|
+
ls -la logs/
|
|
188
|
+
|
|
189
|
+
# View latest application log
|
|
190
|
+
tail -f logs/application-*.log
|
|
191
|
+
|
|
192
|
+
# View latest error log
|
|
193
|
+
tail -f logs/error-*.log
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
### Check Monitoring Status
|
|
197
|
+
|
|
198
|
+
```bash
|
|
199
|
+
curl http://localhost:3000/monitor/status | jq
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
Expected output:
|
|
203
|
+
```json
|
|
204
|
+
{
|
|
205
|
+
"isRunning": true,
|
|
206
|
+
"health": {
|
|
207
|
+
"isHealthy": true,
|
|
208
|
+
"uptime": "0d 0h 5m 30s",
|
|
209
|
+
"consecutiveFailures": 0,
|
|
210
|
+
"registeredChecks": 2
|
|
211
|
+
},
|
|
212
|
+
"system": {
|
|
213
|
+
"cpu": { "process": 2.5, "system": 15.3 },
|
|
214
|
+
"memory": { ... }
|
|
215
|
+
},
|
|
216
|
+
"databases": {},
|
|
217
|
+
"errors": {
|
|
218
|
+
"currentErrorRate": 0,
|
|
219
|
+
"threshold": 10,
|
|
220
|
+
"apiErrorRate": 0
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
## Performance Testing
|
|
226
|
+
|
|
227
|
+
### Load Testing with Apache Bench
|
|
228
|
+
|
|
229
|
+
```bash
|
|
230
|
+
# Install Apache Bench
|
|
231
|
+
sudo apt-get install apache2-utils # Ubuntu/Debian
|
|
232
|
+
brew install httpd # macOS
|
|
233
|
+
|
|
234
|
+
# Run load test
|
|
235
|
+
ab -n 1000 -c 10 http://localhost:3000/
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
### Load Testing with Artillery
|
|
239
|
+
|
|
240
|
+
```bash
|
|
241
|
+
# Install Artillery
|
|
242
|
+
npm install -g artillery
|
|
243
|
+
|
|
244
|
+
# Create test config (artillery.yml)
|
|
245
|
+
cat > artillery.yml << EOF
|
|
246
|
+
config:
|
|
247
|
+
target: 'http://localhost:3000'
|
|
248
|
+
phases:
|
|
249
|
+
- duration: 60
|
|
250
|
+
arrivalRate: 10
|
|
251
|
+
scenarios:
|
|
252
|
+
- flow:
|
|
253
|
+
- get:
|
|
254
|
+
url: "/"
|
|
255
|
+
- get:
|
|
256
|
+
url: "/health"
|
|
257
|
+
EOF
|
|
258
|
+
|
|
259
|
+
# Run test
|
|
260
|
+
artillery run artillery.yml
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
## Troubleshooting Installation
|
|
264
|
+
|
|
265
|
+
### Issue: Module not found
|
|
266
|
+
|
|
267
|
+
**Solution**: Ensure all dependencies are installed
|
|
268
|
+
```bash
|
|
269
|
+
npm install
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
### Issue: Permission denied on logs directory
|
|
273
|
+
|
|
274
|
+
**Solution**: Create logs directory with proper permissions
|
|
275
|
+
```bash
|
|
276
|
+
mkdir -p logs
|
|
277
|
+
chmod 755 logs
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
### Issue: Port 3000 already in use
|
|
281
|
+
|
|
282
|
+
**Solution**: Use a different port
|
|
283
|
+
```bash
|
|
284
|
+
PORT=3001 npm start
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
Or in code:
|
|
288
|
+
```javascript
|
|
289
|
+
const PORT = process.env.PORT || 3001;
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
### Issue: Email notifications not working
|
|
293
|
+
|
|
294
|
+
**Solutions**:
|
|
295
|
+
1. Check SMTP credentials
|
|
296
|
+
2. Enable "Less secure app access" (Gmail)
|
|
297
|
+
3. Use App Password instead of regular password
|
|
298
|
+
4. Check firewall settings
|
|
299
|
+
|
|
300
|
+
### Issue: Slack notifications not working
|
|
301
|
+
|
|
302
|
+
**Solutions**:
|
|
303
|
+
1. Verify webhook URL is correct
|
|
304
|
+
2. Check webhook hasn't been revoked
|
|
305
|
+
3. Test webhook with curl:
|
|
306
|
+
```bash
|
|
307
|
+
curl -X POST -H 'Content-type: application/json' \
|
|
308
|
+
--data '{"text":"Test"}' \
|
|
309
|
+
YOUR_WEBHOOK_URL
|
|
310
|
+
```
|
|
311
|
+
|
|
312
|
+
## Development Setup
|
|
313
|
+
|
|
314
|
+
### For Contributing
|
|
315
|
+
|
|
316
|
+
```bash
|
|
317
|
+
# Clone the repository
|
|
318
|
+
git clone https://github.com/yourorg/node-monitor.git
|
|
319
|
+
cd node-monitor
|
|
320
|
+
|
|
321
|
+
# Install dependencies
|
|
322
|
+
npm install
|
|
323
|
+
|
|
324
|
+
# Link for local development
|
|
325
|
+
npm link
|
|
326
|
+
|
|
327
|
+
# Run example
|
|
328
|
+
cd examples
|
|
329
|
+
npm install
|
|
330
|
+
npm link @projectmd/node-monitor
|
|
331
|
+
npm start
|
|
332
|
+
```
|
|
333
|
+
|
|
334
|
+
### Running Tests (When Implemented)
|
|
335
|
+
|
|
336
|
+
```bash
|
|
337
|
+
# Run all tests
|
|
338
|
+
npm test
|
|
339
|
+
|
|
340
|
+
# Run tests with coverage
|
|
341
|
+
npm run test:coverage
|
|
342
|
+
|
|
343
|
+
# Run tests in watch mode
|
|
344
|
+
npm run test:watch
|
|
345
|
+
```
|
|
346
|
+
|
|
347
|
+
## Docker Installation
|
|
348
|
+
|
|
349
|
+
### Build Docker Image
|
|
350
|
+
|
|
351
|
+
```bash
|
|
352
|
+
# Build the image
|
|
353
|
+
docker build -t node-monitor-example .
|
|
354
|
+
|
|
355
|
+
# Run the container
|
|
356
|
+
docker run -p 3000:3000 node-monitor-example
|
|
357
|
+
```
|
|
358
|
+
|
|
359
|
+
### Docker Compose
|
|
360
|
+
|
|
361
|
+
```bash
|
|
362
|
+
# Start services
|
|
363
|
+
docker-compose up
|
|
364
|
+
|
|
365
|
+
# Start in background
|
|
366
|
+
docker-compose up -d
|
|
367
|
+
|
|
368
|
+
# View logs
|
|
369
|
+
docker-compose logs -f
|
|
370
|
+
|
|
371
|
+
# Stop services
|
|
372
|
+
docker-compose down
|
|
373
|
+
```
|
|
374
|
+
|
|
375
|
+
## Production Deployment
|
|
376
|
+
|
|
377
|
+
### Using PM2
|
|
378
|
+
|
|
379
|
+
```bash
|
|
380
|
+
# Install PM2
|
|
381
|
+
npm install -g pm2
|
|
382
|
+
|
|
383
|
+
# Start application
|
|
384
|
+
pm2 start examples/express-app.js --name "node-monitor-example"
|
|
385
|
+
|
|
386
|
+
# View logs
|
|
387
|
+
pm2 logs node-monitor-example
|
|
388
|
+
|
|
389
|
+
# Monitor
|
|
390
|
+
pm2 monit
|
|
391
|
+
|
|
392
|
+
# Save configuration
|
|
393
|
+
pm2 save
|
|
394
|
+
|
|
395
|
+
# Setup startup script
|
|
396
|
+
pm2 startup
|
|
397
|
+
```
|
|
398
|
+
|
|
399
|
+
### Using systemd (Linux)
|
|
400
|
+
|
|
401
|
+
Create `/etc/systemd/system/node-monitor.service`:
|
|
402
|
+
|
|
403
|
+
```ini
|
|
404
|
+
[Unit]
|
|
405
|
+
Description=Node Monitor Example
|
|
406
|
+
After=network.target
|
|
407
|
+
|
|
408
|
+
[Service]
|
|
409
|
+
Type=simple
|
|
410
|
+
User=nodejs
|
|
411
|
+
WorkingDirectory=/path/to/node-monitor/examples
|
|
412
|
+
ExecStart=/usr/bin/node express-app.js
|
|
413
|
+
Restart=on-failure
|
|
414
|
+
|
|
415
|
+
[Install]
|
|
416
|
+
WantedBy=multi-user.target
|
|
417
|
+
```
|
|
418
|
+
|
|
419
|
+
Enable and start:
|
|
420
|
+
```bash
|
|
421
|
+
sudo systemctl enable node-monitor
|
|
422
|
+
sudo systemctl start node-monitor
|
|
423
|
+
sudo systemctl status node-monitor
|
|
424
|
+
```
|
|
425
|
+
|
|
426
|
+
## Verification Checklist
|
|
427
|
+
|
|
428
|
+
- [ ] Package installed successfully
|
|
429
|
+
- [ ] Example application runs
|
|
430
|
+
- [ ] Health check endpoint responds
|
|
431
|
+
- [ ] Logs are being created
|
|
432
|
+
- [ ] Error tracking works
|
|
433
|
+
- [ ] Email notifications work (if configured)
|
|
434
|
+
- [ ] Slack notifications work (if configured)
|
|
435
|
+
- [ ] Database monitoring works (if configured)
|
|
436
|
+
- [ ] System metrics are being collected
|
|
437
|
+
- [ ] Graceful shutdown works
|
|
438
|
+
|
|
439
|
+
## Next Steps
|
|
440
|
+
|
|
441
|
+
After successful installation:
|
|
442
|
+
|
|
443
|
+
1. ✅ Read the [Getting Started Guide](GETTING_STARTED.md)
|
|
444
|
+
2. ✅ Review the [Setup Guide](SETUP_GUIDE.md)
|
|
445
|
+
3. ✅ Check the [Quick Reference](QUICK_REFERENCE.md)
|
|
446
|
+
4. ✅ Explore the [Architecture](ARCHITECTURE.md)
|
|
447
|
+
5. ✅ Integrate into your application
|
|
448
|
+
|
|
449
|
+
## Support
|
|
450
|
+
|
|
451
|
+
If you encounter any issues:
|
|
452
|
+
|
|
453
|
+
1. Check the [Troubleshooting](#troubleshooting-installation) section
|
|
454
|
+
2. Review the logs in `logs/` directory
|
|
455
|
+
3. Check [GitHub Issues](https://github.com/yourorg/node-monitor/issues)
|
|
456
|
+
4. Create a new issue with details
|
|
457
|
+
|
|
458
|
+
## Uninstallation
|
|
459
|
+
|
|
460
|
+
```bash
|
|
461
|
+
# Remove the package
|
|
462
|
+
npm uninstall @projectmd/node-monitor
|
|
463
|
+
|
|
464
|
+
# Remove logs (optional)
|
|
465
|
+
rm -rf logs/
|
|
466
|
+
|
|
467
|
+
# Unlink (if using npm link)
|
|
468
|
+
npm unlink @projectmd/node-monitor
|
|
469
|
+
```
|
|
470
|
+
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024 ProjectMD
|
|
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.
|
|
22
|
+
|