@hugeicons/migrate 0.1.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,628 @@
1
+ /**
2
+ * HTML Report Generator
3
+ * Creates a beautiful HTML report for migration results
4
+ */
5
+ import * as fs from 'node:fs';
6
+ import * as path from 'node:path';
7
+ import { exec } from 'node:child_process';
8
+ import { platform } from 'node:os';
9
+ /**
10
+ * Generate HTML report for migration results
11
+ */
12
+ export function generateHtmlReport(result, options) {
13
+ const { projectRoot, style, dryRun, sourceLibrary, pendingInstallCommand } = options;
14
+ const timestamp = new Date().toLocaleString();
15
+ const successfulTransforms = result.transformations.filter(t => t.success);
16
+ const failedTransforms = result.transformations.filter(t => !t.success);
17
+ // Collect all changes by type
18
+ const allChanges = successfulTransforms.flatMap(t => t.changes);
19
+ const jsxReplacements = allChanges.filter(c => c.type === 'jsx-replace');
20
+ const importAdds = allChanges.filter(c => c.type === 'import-add');
21
+ // Get icon mappings (old => new) - only for renamed icons
22
+ const iconMappings = new Map();
23
+ // Get all migrated icons (including those that kept the same name)
24
+ const allMigratedIcons = new Set();
25
+ for (const change of jsxReplacements) {
26
+ if (change.original && change.replacement) {
27
+ // Extract old icon name from original (e.g., <Sun ... /> or <Check ...)
28
+ const oldMatch = change.original.match(/<(\w+)/);
29
+ if (oldMatch) {
30
+ const oldIcon = oldMatch[1];
31
+ allMigratedIcons.add(oldIcon);
32
+ // Check if icon was renamed (has icon={...} wrapper)
33
+ const newMatch = change.replacement.match(/icon=\{(\w+)\}/);
34
+ if (newMatch) {
35
+ const newIcon = newMatch[1];
36
+ const key = `${oldIcon}=>${newIcon}`;
37
+ if (!iconMappings.has(key)) {
38
+ iconMappings.set(key, { oldIcon, newIcon });
39
+ }
40
+ }
41
+ }
42
+ }
43
+ }
44
+ // Also extract icons from import statements
45
+ for (const change of importAdds) {
46
+ if (change.replacement) {
47
+ const importMatch = change.replacement.match(/import\s*\{([^}]+)\}\s*from\s*["']@hugeicons/);
48
+ if (importMatch) {
49
+ const icons = importMatch[1].split(',').map(s => s.trim()).filter(Boolean);
50
+ icons.forEach(icon => {
51
+ if (icon !== 'HugeiconsIcon') {
52
+ allMigratedIcons.add(icon);
53
+ }
54
+ });
55
+ }
56
+ }
57
+ }
58
+ // Check if all icons kept the same name (no renames needed)
59
+ const allIconsKeptSameName = iconMappings.size === 0 && allMigratedIcons.size > 0;
60
+ const html = `<!DOCTYPE html>
61
+ <html lang="en">
62
+ <head>
63
+ <meta charset="UTF-8">
64
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
65
+ <title>Hugeicons Migration Report</title>
66
+ <style>
67
+ :root {
68
+ --primary: #afe67f;
69
+ --primary-dark: #8bc34a;
70
+ --primary-light: #d4f4b4;
71
+ --danger: #ef4444;
72
+ --warning: #f59e0b;
73
+ --bg: #ffffff;
74
+ --bg-card: #f8fafc;
75
+ --bg-hover: #f1f5f9;
76
+ --text: #1e293b;
77
+ --text-muted: #64748b;
78
+ --border: #e2e8f0;
79
+ }
80
+
81
+ * {
82
+ box-sizing: border-box;
83
+ margin: 0;
84
+ padding: 0;
85
+ }
86
+
87
+ body {
88
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
89
+ background: var(--bg);
90
+ color: var(--text);
91
+ line-height: 1.6;
92
+ padding: 2rem;
93
+ }
94
+
95
+ .container {
96
+ max-width: 1200px;
97
+ margin: 0 auto;
98
+ }
99
+
100
+ header {
101
+ text-align: center;
102
+ margin-bottom: 3rem;
103
+ padding-bottom: 2rem;
104
+ border-bottom: 1px solid var(--border);
105
+ }
106
+
107
+ .header-logo {
108
+ margin-bottom: 1.5rem;
109
+ }
110
+
111
+ .header-logo img {
112
+ height: 28px;
113
+ }
114
+
115
+ .title {
116
+ font-size: 2rem;
117
+ font-weight: 700;
118
+ color: #141812;
119
+ margin-bottom: 0.5rem;
120
+ }
121
+
122
+ .subtitle {
123
+ color: var(--text-muted);
124
+ font-size: 1.1rem;
125
+ }
126
+
127
+ .badge {
128
+ display: inline-block;
129
+ padding: 0.25rem 0.75rem;
130
+ border-radius: 9999px;
131
+ font-size: 0.875rem;
132
+ font-weight: 500;
133
+ margin-left: 0.5rem;
134
+ }
135
+
136
+ .badge-success {
137
+ background: var(--primary-light);
138
+ color: #3d6b1c;
139
+ }
140
+
141
+ .badge-warning {
142
+ background: rgba(245, 158, 11, 0.15);
143
+ color: #b45309;
144
+ }
145
+
146
+ .badge-danger {
147
+ background: rgba(239, 68, 68, 0.15);
148
+ color: var(--danger);
149
+ }
150
+
151
+ .stats-grid {
152
+ display: grid;
153
+ grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
154
+ gap: 1.5rem;
155
+ margin-bottom: 3rem;
156
+ }
157
+
158
+ .stat-card {
159
+ background: var(--bg-card);
160
+ border-radius: 1rem;
161
+ padding: 1.5rem;
162
+ text-align: center;
163
+ border: 1px solid var(--border);
164
+ box-shadow: 0 1px 3px rgba(0,0,0,0.05);
165
+ }
166
+
167
+ .stat-value {
168
+ font-size: 3rem;
169
+ font-weight: 700;
170
+ color: #3d6b1c;
171
+ line-height: 1;
172
+ margin-bottom: 0.5rem;
173
+ }
174
+
175
+ .stat-label {
176
+ color: var(--text-muted);
177
+ font-size: 0.875rem;
178
+ text-transform: uppercase;
179
+ letter-spacing: 0.05em;
180
+ }
181
+
182
+ .section {
183
+ margin-bottom: 3rem;
184
+ }
185
+
186
+ .section-title {
187
+ font-size: 1.5rem;
188
+ font-weight: 600;
189
+ margin-bottom: 1rem;
190
+ display: flex;
191
+ align-items: center;
192
+ gap: 0.5rem;
193
+ color: var(--text);
194
+ }
195
+
196
+ .section-title svg {
197
+ width: 1.5rem;
198
+ height: 1.5rem;
199
+ color: var(--primary-dark);
200
+ }
201
+
202
+ .card {
203
+ background: var(--bg-card);
204
+ border-radius: 1rem;
205
+ border: 1px solid var(--border);
206
+ overflow: hidden;
207
+ box-shadow: 0 1px 3px rgba(0,0,0,0.05);
208
+ }
209
+
210
+ .file-list {
211
+ max-height: 400px;
212
+ overflow-y: auto;
213
+ }
214
+
215
+ .file-item {
216
+ padding: 1rem 1.5rem;
217
+ border-bottom: 1px solid var(--border);
218
+ display: flex;
219
+ justify-content: space-between;
220
+ align-items: center;
221
+ transition: background 0.15s;
222
+ }
223
+
224
+ .file-item:last-child {
225
+ border-bottom: none;
226
+ }
227
+
228
+ .file-item:hover {
229
+ background: var(--bg-hover);
230
+ }
231
+
232
+ .file-path {
233
+ font-family: 'SF Mono', Monaco, 'Cascadia Code', monospace;
234
+ font-size: 0.875rem;
235
+ color: var(--text);
236
+ }
237
+
238
+ .file-changes {
239
+ color: var(--text-muted);
240
+ font-size: 0.875rem;
241
+ background: var(--primary-light);
242
+ padding: 0.25rem 0.75rem;
243
+ border-radius: 9999px;
244
+ font-weight: 500;
245
+ color: #3d6b1c;
246
+ }
247
+
248
+ .icon-list {
249
+ max-height: 400px;
250
+ overflow-y: auto;
251
+ padding: 1rem;
252
+ }
253
+
254
+ .icon-grid {
255
+ display: grid;
256
+ grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
257
+ gap: 1rem;
258
+ }
259
+
260
+ .icon-item {
261
+ background: var(--bg-hover);
262
+ border-radius: 0.75rem;
263
+ padding: 1rem 1.25rem;
264
+ display: flex;
265
+ align-items: center;
266
+ gap: 0.75rem;
267
+ border: 1px solid var(--border);
268
+ }
269
+
270
+ .icon-old {
271
+ font-family: 'SF Mono', Monaco, 'Cascadia Code', monospace;
272
+ font-size: 0.8rem;
273
+ color: var(--text-muted);
274
+ background: #fff;
275
+ padding: 0.25rem 0.5rem;
276
+ border-radius: 0.375rem;
277
+ border: 1px solid var(--border);
278
+ }
279
+
280
+ .icon-arrow {
281
+ color: var(--primary-dark);
282
+ font-weight: 600;
283
+ font-size: 1.25rem;
284
+ }
285
+
286
+ .icon-new {
287
+ font-family: 'SF Mono', Monaco, 'Cascadia Code', monospace;
288
+ font-size: 0.8rem;
289
+ color: #3d6b1c;
290
+ background: var(--primary-light);
291
+ padding: 0.25rem 0.5rem;
292
+ border-radius: 0.375rem;
293
+ font-weight: 500;
294
+ }
295
+
296
+ .info-list {
297
+ padding: 1.5rem;
298
+ }
299
+
300
+ .info-item {
301
+ display: grid;
302
+ grid-template-columns: 120px 1fr;
303
+ gap: 1rem;
304
+ padding: 0.75rem 0;
305
+ border-bottom: 1px solid var(--border);
306
+ align-items: start;
307
+ }
308
+
309
+ .info-item:last-child {
310
+ border-bottom: none;
311
+ }
312
+
313
+ .info-label {
314
+ color: var(--text-muted);
315
+ font-weight: 500;
316
+ font-size: 0.875rem;
317
+ }
318
+
319
+ .info-value {
320
+ font-weight: 500;
321
+ color: var(--text);
322
+ word-break: break-all;
323
+ }
324
+
325
+ .error-list {
326
+ padding: 1.5rem;
327
+ }
328
+
329
+ .error-item {
330
+ background: rgba(239, 68, 68, 0.08);
331
+ border: 1px solid rgba(239, 68, 68, 0.2);
332
+ border-radius: 0.75rem;
333
+ padding: 1rem;
334
+ margin-bottom: 1rem;
335
+ }
336
+
337
+ .error-item:last-child {
338
+ margin-bottom: 0;
339
+ }
340
+
341
+ .error-file {
342
+ font-weight: 600;
343
+ color: var(--danger);
344
+ margin-bottom: 0.25rem;
345
+ font-family: 'SF Mono', Monaco, 'Cascadia Code', monospace;
346
+ font-size: 0.875rem;
347
+ }
348
+
349
+ .error-message {
350
+ color: var(--text-muted);
351
+ font-size: 0.875rem;
352
+ }
353
+
354
+ footer {
355
+ text-align: center;
356
+ padding-top: 2rem;
357
+ border-top: 1px solid var(--border);
358
+ color: var(--text-muted);
359
+ font-size: 0.875rem;
360
+ }
361
+
362
+ footer a {
363
+ color: #3d6b1c;
364
+ text-decoration: none;
365
+ font-weight: 500;
366
+ }
367
+
368
+ footer a:hover {
369
+ text-decoration: underline;
370
+ }
371
+
372
+ .empty-state {
373
+ padding: 3rem;
374
+ text-align: center;
375
+ color: var(--text-muted);
376
+ }
377
+
378
+ .hugeicons-badge {
379
+ display: inline-flex;
380
+ align-items: center;
381
+ gap: 0.5rem;
382
+ background: linear-gradient(135deg, #8bc34a, #afe67f);
383
+ color: #fff;
384
+ padding: 0.5rem 1rem;
385
+ border-radius: 0.5rem;
386
+ font-weight: 600;
387
+ margin-top: 1rem;
388
+ }
389
+
390
+ @media (max-width: 768px) {
391
+ body {
392
+ padding: 1rem;
393
+ }
394
+
395
+ .stat-value {
396
+ font-size: 2rem;
397
+ }
398
+
399
+ .icon-grid {
400
+ grid-template-columns: 1fr;
401
+ }
402
+ }
403
+ </style>
404
+ </head>
405
+ <body>
406
+ <div class="container">
407
+ <header>
408
+ <div class="header-logo">
409
+ <img src="https://hugeicons.com/assets/logo.svg" alt="Hugeicons" />
410
+ </div>
411
+ <h1 class="title">Hugeicons Migration Report</h1>
412
+ <p class="subtitle">
413
+ ${dryRun ? 'Dry Run Preview' : 'Migration Complete'}
414
+ <span class="badge ${dryRun ? 'badge-warning' : 'badge-success'}">${dryRun ? 'Preview' : 'Applied'}</span>
415
+ </p>
416
+ </header>
417
+
418
+ <div class="stats-grid">
419
+ <div class="stat-card">
420
+ <div class="stat-value">${result.summary.filesModified}</div>
421
+ <div class="stat-label">Files ${dryRun ? 'To Modify' : 'Modified'}</div>
422
+ </div>
423
+ <div class="stat-card">
424
+ <div class="stat-value">${result.summary.totalReplacements}</div>
425
+ <div class="stat-label">Icons Migrated</div>
426
+ </div>
427
+ <div class="stat-card">
428
+ <div class="stat-value">${allMigratedIcons.size}</div>
429
+ <div class="stat-label">Unique Icons</div>
430
+ </div>
431
+ <div class="stat-card">
432
+ <div class="stat-value" style="color: ${result.summary.errors > 0 ? 'var(--danger)' : '#3d6b1c'}">${result.summary.errors}</div>
433
+ <div class="stat-label">Errors</div>
434
+ </div>
435
+ </div>
436
+
437
+ ${pendingInstallCommand ? `
438
+ <div class="section" style="margin-top: 1.5rem;">
439
+ <div class="card" style="background: #fff3cd; border: 1px solid #ffc107;">
440
+ <div style="padding: 1.25rem;">
441
+ <div style="display: flex; align-items: flex-start; gap: 0.75rem;">
442
+ <svg style="width: 24px; height: 24px; color: #856404; flex-shrink: 0; margin-top: 2px;" fill="none" stroke="currentColor" viewBox="0 0 24 24">
443
+ <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z"></path>
444
+ </svg>
445
+ <div>
446
+ <p style="color: #856404; margin: 0; font-weight: 600; font-size: 1rem;">
447
+ Packages Not Installed
448
+ </p>
449
+ <p style="color: #856404; margin: 0.5rem 0 0 0; font-size: 0.875rem;">
450
+ The required Hugeicons packages could not be installed automatically. Please run the following command manually:
451
+ </p>
452
+ <div style="background: #1e1e1e; color: #d4d4d4; padding: 0.75rem 1rem; border-radius: 6px; margin-top: 0.75rem; font-family: 'SF Mono', Monaco, 'Cascadia Code', monospace; font-size: 0.875rem; overflow-x: auto;">
453
+ <code>${pendingInstallCommand}</code>
454
+ </div>
455
+ </div>
456
+ </div>
457
+ </div>
458
+ </div>
459
+ </div>
460
+ ` : ''}
461
+
462
+ <div class="section">
463
+ <h2 class="section-title">
464
+ <svg fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"></path></svg>
465
+ Modified Files
466
+ </h2>
467
+ <div class="card">
468
+ ${successfulTransforms.length > 0 ? `
469
+ <div class="file-list">
470
+ ${successfulTransforms.map(t => `
471
+ <div class="file-item">
472
+ <span class="file-path">${t.filePath}</span>
473
+ <span class="file-changes">${t.changes.length} changes</span>
474
+ </div>
475
+ `).join('')}
476
+ </div>
477
+ ` : `
478
+ <div class="empty-state">No files were modified</div>
479
+ `}
480
+ </div>
481
+ </div>
482
+
483
+ <div class="section">
484
+ <h2 class="section-title">
485
+ <svg fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 7h12m0 0l-4-4m4 4l-4 4m0 6H4m0 0l4 4m-4-4l4-4"></path></svg>
486
+ ${allIconsKeptSameName ? 'Migrated Icons' : 'Icon Mappings'}
487
+ </h2>
488
+ <div class="card">
489
+ ${allIconsKeptSameName ? `
490
+ <div class="info-banner" style="background: var(--primary-light); padding: 1rem 1.5rem; border-bottom: 1px solid var(--border);">
491
+ <p style="color: #3d6b1c; margin: 0; font-weight: 500;">
492
+ ✓ All ${allMigratedIcons.size} icons kept their original names
493
+ </p>
494
+ <p style="color: var(--text-muted); margin: 0.5rem 0 0 0; font-size: 0.875rem;">
495
+ Hugeicons provides compatible aliases for ${sourceLibrary || 'your icon library'}, so only the import paths were updated.
496
+ </p>
497
+ </div>
498
+ <div class="icon-list">
499
+ <div class="icon-grid">
500
+ ${Array.from(allMigratedIcons).sort().map(icon => `
501
+ <div class="icon-item" style="justify-content: center;">
502
+ <span class="icon-new">${icon}</span>
503
+ </div>
504
+ `).join('')}
505
+ </div>
506
+ </div>
507
+ ` : iconMappings.size > 0 ? `
508
+ <div class="icon-list">
509
+ <div class="icon-grid">
510
+ ${Array.from(iconMappings.values()).sort((a, b) => a.oldIcon.localeCompare(b.oldIcon)).map(mapping => `
511
+ <div class="icon-item">
512
+ <span class="icon-old">${mapping.oldIcon}</span>
513
+ <span class="icon-arrow">\u2192</span>
514
+ <span class="icon-new">${mapping.newIcon}</span>
515
+ </div>
516
+ `).join('')}
517
+ </div>
518
+ </div>
519
+ ` : `
520
+ <div class="empty-state">No icons were migrated</div>
521
+ `}
522
+ </div>
523
+ </div>
524
+
525
+ ${failedTransforms.length > 0 ? `
526
+ <div class="section">
527
+ <h2 class="section-title" style="color: var(--danger)">
528
+ <svg fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 8v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"></path></svg>
529
+ Errors
530
+ </h2>
531
+ <div class="card">
532
+ <div class="error-list">
533
+ ${failedTransforms.map(t => `
534
+ <div class="error-item">
535
+ <div class="error-file">${t.filePath}</div>
536
+ <div class="error-message">${t.error || 'Unknown error'}</div>
537
+ </div>
538
+ `).join('')}
539
+ </div>
540
+ </div>
541
+ </div>
542
+ ` : ''}
543
+
544
+ <div class="section">
545
+ <h2 class="section-title">
546
+ <svg fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"></path></svg>
547
+ Migration Details
548
+ </h2>
549
+ <div class="card">
550
+ <div class="info-list">
551
+ <div class="info-item">
552
+ <span class="info-label">Project</span>
553
+ <span class="info-value">${projectRoot}</span>
554
+ </div>
555
+ ${sourceLibrary ? `
556
+ <div class="info-item">
557
+ <span class="info-label">From</span>
558
+ <span class="info-value">${sourceLibrary}</span>
559
+ </div>
560
+ ` : ''}
561
+ <div class="info-item">
562
+ <span class="info-label">To Style</span>
563
+ <span class="info-value">${style}</span>
564
+ </div>
565
+ <div class="info-item">
566
+ <span class="info-label">Timestamp</span>
567
+ <span class="info-value">${timestamp}</span>
568
+ </div>
569
+ <div class="info-item">
570
+ <span class="info-label">Mode</span>
571
+ <span class="info-value">${dryRun ? 'Dry Run (Preview)' : 'Write Mode'}</span>
572
+ </div>
573
+ ${result.backupPath ? `
574
+ <div class="info-item">
575
+ <span class="info-label">Backup</span>
576
+ <span class="info-value">${path.basename(result.backupPath)}</span>
577
+ </div>
578
+ ` : ''}
579
+ </div>
580
+ </div>
581
+ </div>
582
+
583
+ <footer>
584
+ <p>Generated by <a href="https://hugeicons.com" target="_blank">Hugeicons Migration Tool</a></p>
585
+ <p style="margin-top: 0.5rem">Need help? Visit <a href="https://hugeicons.com/docs" target="_blank">documentation</a></p>
586
+ </footer>
587
+ </div>
588
+ </body>
589
+ </html>`;
590
+ return html;
591
+ }
592
+ /**
593
+ * Save HTML report to file and optionally open in browser
594
+ */
595
+ export async function saveAndOpenReport(html, projectRoot, openInBrowser = true) {
596
+ const timestamp = new Date().toISOString().replace(/[:.]/g, '-').slice(0, 19);
597
+ const reportPath = path.join(projectRoot, `hugeicons-migration-report-${timestamp}.html`);
598
+ // Write the file
599
+ fs.writeFileSync(reportPath, html, 'utf-8');
600
+ // Open in browser if requested
601
+ if (openInBrowser) {
602
+ const openCommand = getOpenCommand();
603
+ if (openCommand) {
604
+ exec(`${openCommand} "${reportPath}"`, (error) => {
605
+ if (error) {
606
+ console.error('Could not open browser automatically');
607
+ }
608
+ });
609
+ }
610
+ }
611
+ return reportPath;
612
+ }
613
+ /**
614
+ * Get the command to open a file in the default browser based on OS
615
+ */
616
+ function getOpenCommand() {
617
+ switch (platform()) {
618
+ case 'darwin':
619
+ return 'open';
620
+ case 'win32':
621
+ return 'start ""';
622
+ case 'linux':
623
+ return 'xdg-open';
624
+ default:
625
+ return null;
626
+ }
627
+ }
628
+ //# sourceMappingURL=html-report.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"html-report.js","sourceRoot":"","sources":["../../src/utils/html-report.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAClC,OAAO,EAAE,IAAI,EAAE,MAAM,oBAAoB,CAAC;AAC1C,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAgBnC;;GAEG;AACH,MAAM,UAAU,kBAAkB,CAChC,MAAmB,EACnB,OAAsB;IAEtB,MAAM,EAAE,WAAW,EAAE,KAAK,EAAE,MAAM,EAAE,aAAa,EAAE,qBAAqB,EAAE,GAAG,OAAO,CAAC;IACrF,MAAM,SAAS,GAAG,IAAI,IAAI,EAAE,CAAC,cAAc,EAAE,CAAC;IAE9C,MAAM,oBAAoB,GAAG,MAAM,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;IAC3E,MAAM,gBAAgB,GAAG,MAAM,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;IAExE,8BAA8B;IAC9B,MAAM,UAAU,GAAG,oBAAoB,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;IAChE,MAAM,eAAe,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,aAAa,CAAC,CAAC;IACzE,MAAM,UAAU,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,YAAY,CAAC,CAAC;IAEnE,0DAA0D;IAC1D,MAAM,YAAY,GAAG,IAAI,GAAG,EAAuB,CAAC;IACpD,mEAAmE;IACnE,MAAM,gBAAgB,GAAG,IAAI,GAAG,EAAU,CAAC;IAE3C,KAAK,MAAM,MAAM,IAAI,eAAe,EAAE,CAAC;QACrC,IAAI,MAAM,CAAC,QAAQ,IAAI,MAAM,CAAC,WAAW,EAAE,CAAC;YAC1C,wEAAwE;YACxE,MAAM,QAAQ,GAAG,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;YAEjD,IAAI,QAAQ,EAAE,CAAC;gBACb,MAAM,OAAO,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;gBAC5B,gBAAgB,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;gBAE9B,qDAAqD;gBACrD,MAAM,QAAQ,GAAG,MAAM,CAAC,WAAW,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAAC;gBAC5D,IAAI,QAAQ,EAAE,CAAC;oBACb,MAAM,OAAO,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;oBAC5B,MAAM,GAAG,GAAG,GAAG,OAAO,KAAK,OAAO,EAAE,CAAC;oBACrC,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;wBAC3B,YAAY,CAAC,GAAG,CAAC,GAAG,EAAE,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC;oBAC9C,CAAC;gBACH,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;IAED,4CAA4C;IAC5C,KAAK,MAAM,MAAM,IAAI,UAAU,EAAE,CAAC;QAChC,IAAI,MAAM,CAAC,WAAW,EAAE,CAAC;YACvB,MAAM,WAAW,GAAG,MAAM,CAAC,WAAW,CAAC,KAAK,CAAC,8CAA8C,CAAC,CAAC;YAC7F,IAAI,WAAW,EAAE,CAAC;gBAChB,MAAM,KAAK,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;gBAC3E,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE;oBACnB,IAAI,IAAI,KAAK,eAAe,EAAE,CAAC;wBAC7B,gBAAgB,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;oBAC7B,CAAC;gBACH,CAAC,CAAC,CAAC;YACL,CAAC;QACH,CAAC;IACH,CAAC;IAED,4DAA4D;IAC5D,MAAM,oBAAoB,GAAG,YAAY,CAAC,IAAI,KAAK,CAAC,IAAI,gBAAgB,CAAC,IAAI,GAAG,CAAC,CAAC;IAElF,MAAM,IAAI,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;UAiWL,MAAM,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC,CAAC,oBAAoB;6BAC9B,MAAM,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,eAAe,KAAK,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS;;;;;;kCAMxE,MAAM,CAAC,OAAO,CAAC,aAAa;wCACtB,MAAM,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,UAAU;;;kCAGvC,MAAM,CAAC,OAAO,CAAC,iBAAiB;;;;kCAIhC,gBAAgB,CAAC,IAAI;;;;gDAIP,MAAM,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,SAAS,KAAK,MAAM,CAAC,OAAO,CAAC,MAAM;;;;;MAK3H,qBAAqB,CAAC,CAAC,CAAC;;;;;;;;;;;;;;;;wBAgBN,qBAAqB;;;;;;;KAOxC,CAAC,CAAC,CAAC,EAAE;;;;;;;;UAQA,oBAAoB,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC;;YAEhC,oBAAoB,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;;sCAEJ,CAAC,CAAC,QAAQ;yCACP,CAAC,CAAC,OAAO,CAAC,MAAM;;WAE9C,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC;;SAEZ,CAAC,CAAC,CAAC;;SAEH;;;;;;;UAOC,oBAAoB,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,eAAe;;;UAGzD,oBAAoB,CAAC,CAAC,CAAC;;;oBAGb,gBAAgB,CAAC,IAAI;;;wDAGe,aAAa,IAAI,mBAAmB;;;;;cAK9E,KAAK,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;;uCAEvB,IAAI;;aAE9B,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC;;;SAGd,CAAC,CAAC,CAAC,YAAY,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC;;;cAGtB,KAAK,CAAC,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC;;uCAE3E,OAAO,CAAC,OAAO;;uCAEf,OAAO,CAAC,OAAO;;aAEzC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC;;;SAGd,CAAC,CAAC,CAAC;;SAEH;;;;MAIH,gBAAgB,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC;;;;;;;;YAQxB,gBAAgB,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;;sCAEA,CAAC,CAAC,QAAQ;yCACP,CAAC,CAAC,KAAK,IAAI,eAAe;;WAExD,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC;;;;KAIhB,CAAC,CAAC,CAAC,EAAE;;;;;;;;;;;uCAW6B,WAAW;;YAEtC,aAAa,CAAC,CAAC,CAAC;;;uCAGW,aAAa;;WAEzC,CAAC,CAAC,CAAC,EAAE;;;uCAGuB,KAAK;;;;uCAIL,SAAS;;;;uCAIT,MAAM,CAAC,CAAC,CAAC,mBAAmB,CAAC,CAAC,CAAC,YAAY;;YAEtE,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC;;;uCAGO,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,UAAU,CAAC;;WAE5D,CAAC,CAAC,CAAC,EAAE;;;;;;;;;;;QAWR,CAAC;IAEP,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,IAAY,EACZ,WAAmB,EACnB,gBAAyB,IAAI;IAE7B,MAAM,SAAS,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IAC9E,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,8BAA8B,SAAS,OAAO,CAAC,CAAC;IAE1F,iBAAiB;IACjB,EAAE,CAAC,aAAa,CAAC,UAAU,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC;IAE5C,+BAA+B;IAC/B,IAAI,aAAa,EAAE,CAAC;QAClB,MAAM,WAAW,GAAG,cAAc,EAAE,CAAC;QACrC,IAAI,WAAW,EAAE,CAAC;YAChB,IAAI,CAAC,GAAG,WAAW,KAAK,UAAU,GAAG,EAAE,CAAC,KAAK,EAAE,EAAE;gBAC/C,IAAI,KAAK,EAAE,CAAC;oBACV,OAAO,CAAC,KAAK,CAAC,sCAAsC,CAAC,CAAC;gBACxD,CAAC;YACH,CAAC,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,OAAO,UAAU,CAAC;AACpB,CAAC;AAED;;GAEG;AACH,SAAS,cAAc;IACrB,QAAQ,QAAQ,EAAE,EAAE,CAAC;QACnB,KAAK,QAAQ;YACX,OAAO,MAAM,CAAC;QAChB,KAAK,OAAO;YACV,OAAO,UAAU,CAAC;QACpB,KAAK,OAAO;YACV,OAAO,UAAU,CAAC;QACpB;YACE,OAAO,IAAI,CAAC;IAChB,CAAC;AACH,CAAC"}