From 8014d773f291736a26cb80b4b398c8a192d29feb Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 15 Dec 2025 03:29:04 +0000 Subject: [PATCH 1/5] Initial plan From ebd67d148baf512304decfab3a9fa3d30535680f Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 15 Dec 2025 03:44:09 +0000 Subject: [PATCH 2/5] docs(kanvas): expand performance documentation with detailed analysis and optimizations Co-authored-by: hortison <160366376+hortison@users.noreply.github.com> --- .../en/kanvas/advanced/performance/index.md | 384 ++++++++++ package-lock.json | 720 ++++++------------ package.json | 5 +- 3 files changed, 617 insertions(+), 492 deletions(-) diff --git a/content/en/kanvas/advanced/performance/index.md b/content/en/kanvas/advanced/performance/index.md index c00251975..94b8277ae 100644 --- a/content/en/kanvas/advanced/performance/index.md +++ b/content/en/kanvas/advanced/performance/index.md @@ -98,3 +98,387 @@ To optimize performance, consider the following: 2. Prioritize using smaller file sizes whenever possible. Use the `webp` image format over `png`, `jpg`, or `gif` as it generally provides significantly better compression, resulting in faster design save times without sacrificing much image quality. 3. Remove any unnecessary images from your design. 4. Use image compression tools to reduce the size of your images before adding them to your design. + +## Compound Node Rendering Performance + +When working with compound nodes (parent nodes containing multiple child nodes), you may encounter performance challenges as the number of children increases. Understanding these issues and the optimizations available can help you create more responsive designs. + +### Root Cause Analysis + +The rendering performance of compound nodes with many children can be significantly impacted by several factors: + +- **Badge Rendering Plugin Overhead**: The `@layer5/cytoscape-node-html-label` plugin, while powerful for rendering badges and labels, can become a performance bottleneck for compound nodes with many children. +- **Overly Broad Selectors**: The badge selector `node[?label]` matches virtually every node in the graph, causing unnecessary re-renders even for nodes that haven't changed. +- **Missing Viewport Culling**: Badges are rendered for all nodes in the design, even those currently off-screen and not visible to the user, wasting computational resources. +- **Re-render Multiplication**: With 100 child nodes in a compound parent, approximately 303 badge re-renders occur per update cycle. +- **Drag Operation Overhead**: During interactive operations like dragging, the system can generate 18,000-36,000 function calls per second, leading to UI lag and poor user experience. + +{{< alert type="warning" title="Performance Impact" >}} +Large compound nodes (100+ children) can experience significant lag during drag operations and viewport changes without proper optimizations. +{{< /alert >}} + +### Performance Metrics + +The following table illustrates the dramatic performance improvements achieved through optimization: + +| Scenario | Before Optimization | After Optimization | Improvement | +|----------|---------------------|-------------------|-------------| +| Badge re-renders per update (100 children) | 303 | ~30 | 90% reduction | +| Function calls/sec during drag | 18,000-36,000 | 500-3,000 | 90-95% reduction | +| Perceived responsiveness | Laggy, choppy | Smooth, responsive | Significantly improved | + +### Optimizations Implemented + +Kanvas incorporates several key optimizations to address compound node rendering performance: + +#### 1. Viewport Culling (50-80% reduction) + +Only badges for nodes currently visible in the viewport are rendered. Nodes outside the visible area are skipped, reducing unnecessary computation. + +{{< alert type="success" title="Automatic Optimization" >}} +Viewport culling is automatically enabled in Kanvas. No configuration is required to benefit from this optimization. +{{< /alert >}} + +#### 2. Increased Memoization TTL (70% reduction) + +Badge rendering is intelligently cached to avoid redundant computations: + +- **Error Badges**: Cache duration increased from 300ms to 1000ms +- **Compound Badges**: Cache duration increased from 200ms to 1000ms + +This means that if a node's state hasn't changed, its badge rendering is reused from cache rather than recomputed. + +#### 3. Combined Impact (90-95% reduction) + +When viewport culling and increased memoization work together, the overall reduction in badge re-renders reaches 90-95%, resulting in a dramatically more responsive user interface even with complex compound nodes. + +{{< alert type="note" title="Technical Reference" >}} +These optimizations were implemented in PR #3917 and address issues documented in #3916 from the layer5labs/meshery-extensions repository. +{{< /alert >}} + +## Cytoscape Plugin Performance Considerations + +Kanvas leverages multiple Cytoscape.js plugins to provide rich interactive features. Understanding the performance characteristics of these plugins can help you anticipate and mitigate potential performance issues. + +### Plugin-Specific Performance Characteristics + +#### Compound Drag-and-Drop Plugin + +The compound drag-and-drop functionality may experience performance degradation with large graphs. This is a known limitation documented in the plugin's own README. If you're working with designs containing hundreds of nodes, consider: + +- Breaking your design into multiple smaller designs +- Using the Layers panel to hide unnecessary components during editing +- Limiting the number of compound nodes with large child counts + +#### Event Cascade Issues + +Multiple plugins listening to the same Cytoscape events can create a multiplication effect that compounds performance overhead: + +- **Grid Guide Plugin**: Listens for drag events to display alignment guides +- **Automove Plugin**: Monitors node movements to maintain relationships +- **Popper Plugin**: Tracks node positions for tooltip positioning + +When all these plugins respond to a single drag event, the computational cost multiplies, potentially causing lag during interactive operations. + +{{< alert type="info" title="Performance Tip" >}} +The impact of event cascades is most noticeable during continuous operations like dragging. The render throttling optimizations described later in this document help mitigate this issue. +{{< /alert >}} + +#### HTML Plugin Overhead + +Earlier versions of Kanvas used DOM-based HTML rendering for interactive elements. Migration to a 2D canvas renderer has provided significant performance improvements for: + +- **Resize Handles**: Canvas-based handles render faster and respond more smoothly +- **Overlays**: Canvas overlays avoid DOM manipulation overhead +- **Interactive Controls**: Canvas-based controls reduce browser reflow and repaint operations + +#### Bubblesets Optimization + +For designs with complex relationship visualizations, the Bubblesets algorithm has been optimized to provide better performance through improved algorithms that reduce computational complexity. + +{{< alert type="note" title="Technical Reference" >}} +These optimizations were implemented across multiple PRs: #3885, #3887, and #3500 from the layer5labs/meshery-extensions repository. +{{< /alert >}} + +## State Management and Rendering Optimizations + +Efficient state management is critical for maintaining good performance as your designs grow in complexity. Kanvas employs several sophisticated techniques to optimize state updates and rendering. + +### Fine-Grained Reactivity + +Instead of expensive JSON snapshot computations that process the entire design state, Kanvas uses fine-grained state updates that only affect the specific parts of the design that have changed. + +**Benefits:** +- Reduced CPU usage during state updates +- Faster response times for user interactions +- Lower memory consumption +- More predictable performance characteristics + +{{< alert type="success" title="Automatic Optimization" >}} +Fine-grained reactivity is built into Kanvas's state management system and requires no configuration. +{{< /alert >}} + +### Render Throttling + +To prevent UI thrashing during continuous operations, Kanvas implements render throttling that locks down re-renders to a maximum of 10 per second during operations like: + +- Dragging nodes or groups of nodes +- Resizing components +- Panning and zooming the viewport +- Bulk operations affecting multiple components + +This ensures that the UI remains responsive even during intensive operations, preventing the browser from becoming overwhelmed with render requests. + +**Target Performance:** +- Maximum re-renders: 10 per second +- Frame time budget: ~100ms per render +- Typical user-perceived lag: Minimal to none + +### Selector Optimization + +Cytoscape selectors used for sharedState snapshots have been optimized to reduce computational overhead: + +- Use specific selectors instead of broad queries when possible +- Cache selector results when appropriate +- Minimize the number of selector evaluations per frame +- Defer non-critical selector operations to idle time + +### Evaluation Deferral + +Kanvas intelligently skips unnecessary feasibility evaluations for events that don't require validation: + +- **Tap Events**: No feasibility check needed for simple selections +- **Double-Click Events**: Validation deferred until action is confirmed +- **Hover Events**: No evaluation unless tooltip or preview is needed + +This reduces computational overhead for common user interactions that don't modify the design. + +{{< alert type="note" title="Technical Reference" >}} +State management optimizations were implemented in PRs #3448, #3595, #3121, and #3114 from the layer5labs/meshery-extensions repository. +{{< /alert >}} + +## Zoom and Viewport Performance + +The zoom level and viewport position significantly impact rendering performance. Kanvas implements several optimizations to ensure smooth performance across all zoom levels. + +### Minimum Zoom Viewport + +Maintaining a consistent minimum zoom level ensures that detailed rendering works properly across all interactive elements: + +- **Layers**: All layers render consistently at minimum zoom +- **Badges**: Error, warning, and info badges remain visible and properly sized +- **Textboxes**: Text remains readable without excessive scaling +- **Interactions**: Interactive handles and controls maintain proper hit targets +- **Device Compatibility**: Consistent experience across desktop, tablet, and mobile devices + +{{< alert type="warning" title="Zoom Limits" >}} +Kanvas enforces minimum and maximum zoom limits to ensure optimal rendering performance and usability. Attempting to zoom beyond these limits will have no effect. +{{< /alert >}} + +### Progressive Detail Rendering + +Kanvas implements view filtering based on zoom level to show more or less detail depending on the current viewport: + +- **Zoomed Out (Low Detail)**: Show component shapes and primary labels only +- **Medium Zoom**: Add relationship lines and secondary labels +- **Zoomed In (High Detail)**: Show all badges, annotations, and detailed metadata + +This approach ensures that rendering resources are focused on visible, meaningful details at each zoom level. + +**Performance Benefits:** +- Reduced rendering overhead at low zoom levels +- Faster panning and zooming operations +- Smoother performance with large designs +- Better user experience with progressive disclosure of information + +### Zoom Rendering Consistency + +Fixes have been implemented to ensure consistent rendering behavior at all zoom levels: + +- Badges maintain proper sizing relative to nodes +- Relationship lines scale appropriately +- Interactive handles remain accessible +- Text remains readable without pixelation + +{{< alert type="note" title="Technical Reference" >}} +Zoom and viewport optimizations were implemented in PRs #3528, #3711, and #2292 from the layer5labs/meshery-extensions repository. +{{< /alert >}} + +## Performance Testing Guidelines + +Regular performance testing helps ensure that your designs remain responsive as they grow in complexity. Use these guidelines to validate performance characteristics. + +### Test Scenarios + +Validate performance across a range of design complexities: + +1. **Baseline Scenario**: 1 parent + 10 children + - Expected behavior: Smooth, lag-free interactions + - Use case: Small component groups, basic hierarchies + +2. **Medium Complexity**: 1 parent + 50 children + - Expected behavior: Responsive with minor delays acceptable + - Use case: Moderate-sized microservice architectures, namespace groups + +3. **Large/Complex**: 1 parent + 100 children + - Expected behavior: Acceptable performance with optimizations + - Use case: Large namespaces, complex service meshes, cluster visualizations + +4. **Stress Test**: 3 levels of nesting + - Expected behavior: Functional but may experience some lag + - Use case: Deeply nested organizational structures, multi-tier architectures + +{{< alert type="info" title="Testing Approach" >}} +Start with the baseline scenario and progressively increase complexity. This helps identify the specific point where performance begins to degrade. +{{< /alert >}} + +### Target Metrics + +Aim for the following performance targets when testing: + +#### Frame Rate During Drag Operations +- **Target**: 60 FPS (frames per second) +- **Acceptable Threshold**: 30 FPS +- **Below Threshold**: Indicates performance issues requiring optimization + +#### Time to First Badge Render +- **Target**: < 100ms +- **Measurement**: Time from design load to all visible badges rendered +- **Impact**: Affects perceived load time and user experience + +#### Badge Re-renders Per Drag Operation +- **Target**: < 1,000 re-renders +- **Measurement**: Total badge rendering calls during a single drag operation +- **Impact**: Directly affects drag smoothness and responsiveness + +### Monitoring Performance + +To monitor performance during testing: + +1. **Browser DevTools**: Use the Performance tab to record and analyze interactions +2. **Frame Rate**: Monitor FPS during drag operations +3. **CPU Usage**: Watch for excessive CPU spikes during interactions +4. **Memory Usage**: Check for memory leaks during extended sessions + +{{< alert type="warning" title="Browser Differences" >}} +Performance can vary significantly across browsers. Test in your primary target browsers (Chrome, Firefox, Safari) to ensure consistent experience. +{{< /alert >}} + +## Long-term Architecture Recommendations + +While current optimizations provide significant performance improvements, several architectural enhancements could provide even greater benefits in future versions of Kanvas. + +### Canvas-Based Badge Rendering + +Migrating from DOM-based badge rendering to canvas-based rendering could provide 10-100x performance improvement: + +**Current Approach (DOM-based):** +- Each badge is an HTML element +- Browser must manage layout, styles, and reflows +- Limited by DOM manipulation performance + +**Proposed Approach (Canvas-based):** +- Badges rendered directly to canvas +- No DOM manipulation overhead +- Batch rendering operations +- Better control over rendering pipeline + +**Expected Benefits:** +- 10-100x faster badge rendering +- Reduced memory footprint +- Smoother animations and transitions +- Better scaling for large designs + +### Virtual Badge Manager + +A virtual badge manager would only render badges currently visible in the viewport: + +**Implementation Strategy:** +- Track viewport bounds +- Maintain a spatial index of badge positions +- Render only badges intersecting with viewport +- Update dynamically as viewport changes + +**Expected Benefits:** +- Constant rendering time regardless of total badge count +- Seamless handling of designs with thousands of nodes +- Reduced GPU memory usage +- Improved scrolling and panning performance + +### Web Worker Rendering + +Offloading computationally intensive operations to background threads (Web Workers) could prevent UI blocking: + +**Candidate Operations:** +- Badge layout calculations +- Relationship path computations +- Validation and feasibility checks +- Complex selector evaluations + +**Expected Benefits:** +- UI thread remains responsive during heavy computations +- Better multi-core CPU utilization +- Smoother user experience during intensive operations +- Reduced perceived lag + +{{< alert type="info" title="Future Enhancement" >}} +Web Worker rendering requires careful coordination between threads and may introduce complexity in state management. +{{< /alert >}} + +### Progressive Rendering Strategy + +Implement a priority-based rendering system that renders critical elements first: + +**Rendering Priority Levels:** +1. **Critical (Immediate)**: Error badges, validation warnings +2. **High (< 50ms)**: Info badges, relationship indicators +3. **Medium (< 200ms)**: Annotations, secondary labels +4. **Low (Idle Time)**: Decorative elements, optional metadata + +**Expected Benefits:** +- Faster time to interactive +- Critical information always visible +- Better perceived performance +- Graceful degradation under load + +{{< alert type="success" title="User-Centric Design" >}} +Progressive rendering ensures users see the most important information first, even if the design hasn't fully loaded. +{{< /alert >}} + +## Performance-Related URL Parameters + +Kanvas supports several URL parameters that can impact rendering performance and behavior. Understanding these parameters helps you optimize the loading and rendering of your designs. + +### Full Render Mode + +The `render=full` URL parameter enables comprehensive rendering of all design elements, including advanced relationships: + +**Usage:** +``` +https://cloud.layer5.io/kanvas/designer?design=&render=full +``` + +**What It Includes:** +- All component relationships +- TagSet relationships and groupings +- Advanced semantic relationships +- Complete metadata rendering +- All badges and indicators + +**Performance Implications:** +- Increased initial load time +- Higher memory usage +- More computational overhead during updates +- May impact performance on large designs (100+ components) + +{{< alert type="warning" title="Large Design Consideration" >}} +For designs with hundreds of components or complex TagSet relationships, full render mode may cause noticeable performance impact. Consider using standard render mode and selectively enabling layers as needed. +{{< /alert >}} + +### Additional Parameters + +For complete documentation on all available URL parameters and their effects, see [URL Parameters](/kanvas/advanced/url-parameters/). + +{{< alert type="note" title="Parameter Combinations" >}} +URL parameters can be combined to customize your Kanvas experience. Experiment with different combinations to find the optimal balance between features and performance for your specific use case. +{{< /alert >}} diff --git a/package-lock.json b/package-lock.json index ceefb51ef..de859c7b5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,9 +9,10 @@ "version": "0.9.1", "license": "Apache-2.0", "devDependencies": { - "autoprefixer": "^10.4.19", + "autoprefixer": "^10.4.23", "hugo-extended": "0.148.1", - "postcss-cli": "^11.0.0" + "postcss": "^8.5.6", + "postcss-cli": "^11.0.1" } }, "node_modules/@babel/code-frame": { @@ -132,41 +133,6 @@ "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", "dev": true }, - "node_modules/@nodelib/fs.scandir": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", - "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", - "dev": true, - "dependencies": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.stat": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", - "dev": true, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.walk": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", - "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", - "dev": true, - "dependencies": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" - }, - "engines": { - "node": ">= 8" - } - }, "node_modules/@sindresorhus/is": { "version": "5.6.0", "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-5.6.0.tgz", @@ -179,18 +145,6 @@ "url": "https://github.com/sindresorhus/is?sponsor=1" } }, - "node_modules/@sindresorhus/merge-streams": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/@sindresorhus/merge-streams/-/merge-streams-2.2.1.tgz", - "integrity": "sha512-255V7MMIKw6aQ43Wbqp9HZ+VHn6acddERTLiiLnlcPLU9PdTq9Aijl12oklAgUEblLWye+vHLzmqBx6f2TGcZw==", - "dev": true, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/@szmarczak/http-timer": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-5.0.1.tgz", @@ -253,9 +207,9 @@ } }, "node_modules/autoprefixer": { - "version": "10.4.19", - "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.19.tgz", - "integrity": "sha512-BaENR2+zBZ8xXhM4pUaKUxlVdxZ0EZhjvbopwnXmxRUfqDmwSpC2lAi/QXvx7NRdPCo1WKEcEF6mV64si1z4Ew==", + "version": "10.4.23", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.23.tgz", + "integrity": "sha512-YYTXSFulfwytnjAPlw8QHncHJmlvFKtczb8InXaAx9Q0LbfDnfEYDE55omerIJKihhmU61Ft+cAOSzQVaBUmeA==", "dev": true, "funding": [ { @@ -271,12 +225,12 @@ "url": "https://github.com/sponsors/ai" } ], + "license": "MIT", "dependencies": { - "browserslist": "^4.23.0", - "caniuse-lite": "^1.0.30001599", - "fraction.js": "^4.3.7", - "normalize-range": "^0.1.2", - "picocolors": "^1.0.0", + "browserslist": "^4.28.1", + "caniuse-lite": "^1.0.30001760", + "fraction.js": "^5.3.4", + "picocolors": "^1.1.1", "postcss-value-parser": "^4.2.0" }, "bin": { @@ -309,6 +263,16 @@ } ] }, + "node_modules/baseline-browser-mapping": { + "version": "2.9.7", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.9.7.tgz", + "integrity": "sha512-k9xFKplee6KIio3IDbwj+uaCLpqzOwakOgmqzPezM0sFJlFKcg30vk2wOiAJtkTSfx0SSQDSe8q+mWA/fSH5Zg==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "baseline-browser-mapping": "dist/cli.js" + } + }, "node_modules/binary-extensions": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", @@ -341,9 +305,9 @@ } }, "node_modules/browserslist": { - "version": "4.23.0", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.0.tgz", - "integrity": "sha512-QW8HiM1shhT2GuzkvklfjcKDiWFXHOeFCIA/huJPwHsslwcydgk7X+z2zXpEijP98UCY7HbubZt5J2Zgvf0CaQ==", + "version": "4.28.1", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.1.tgz", + "integrity": "sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA==", "dev": true, "funding": [ { @@ -359,11 +323,13 @@ "url": "https://github.com/sponsors/ai" } ], + "license": "MIT", "dependencies": { - "caniuse-lite": "^1.0.30001587", - "electron-to-chromium": "^1.4.668", - "node-releases": "^2.0.14", - "update-browserslist-db": "^1.0.13" + "baseline-browser-mapping": "^2.9.0", + "caniuse-lite": "^1.0.30001759", + "electron-to-chromium": "^1.5.263", + "node-releases": "^2.0.27", + "update-browserslist-db": "^1.2.0" }, "bin": { "browserslist": "cli.js" @@ -467,9 +433,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001600", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001600.tgz", - "integrity": "sha512-+2S9/2JFhYmYaDpZvo0lKkfvuKIglrx68MwOBqMGHhQsNkLjB5xtc/TGoEPs+MxjSyN/72qer2g97nzR641mOQ==", + "version": "1.0.30001760", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001760.tgz", + "integrity": "sha512-7AAMPcueWELt1p3mi13HR/LHH0TJLT11cnwDJEs3xA4+CK/PLKeO9Kl1oru24htkyUKtkGCvAx4ohB0Ttry8Dw==", "dev": true, "funding": [ { @@ -484,7 +450,8 @@ "type": "github", "url": "https://github.com/sponsors/ai" } - ] + ], + "license": "CC-BY-4.0" }, "node_modules/careful-downloader": { "version": "3.0.0", @@ -763,19 +730,21 @@ } }, "node_modules/dependency-graph": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/dependency-graph/-/dependency-graph-0.11.0.tgz", - "integrity": "sha512-JeMq7fEshyepOWDfcfHK06N3MhyPhz++vtqWhMT5O9A3K42rdsEDpfdVqjaqaAhsw6a+ZqeDvQVtD0hFHQWrzg==", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/dependency-graph/-/dependency-graph-1.0.0.tgz", + "integrity": "sha512-cW3gggJ28HZ/LExwxP2B++aiKxhJXMSIt9K48FOXQkm+vuG5gyatXnLsONRJdzO/7VfjDIiaOOa/bs4l464Lwg==", "dev": true, + "license": "MIT", "engines": { - "node": ">= 0.6.0" + "node": ">=4" } }, "node_modules/electron-to-chromium": { - "version": "1.4.673", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.673.tgz", - "integrity": "sha512-zjqzx4N7xGdl5468G+vcgzDhaHkaYgVcf9MqgexcTqsl2UHSCmOj/Bi3HAprg4BZCpC7HyD8a6nZl6QAZf72gw==", - "dev": true + "version": "1.5.267", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.267.tgz", + "integrity": "sha512-0Drusm6MVRXSOJpGbaSVgcQsuB4hEkMpHXaVstcPmhu5LIedxs1xNK/nIxmQIU/RPC0+1/o0AVZfBTkTNJOdUw==", + "dev": true, + "license": "ISC" }, "node_modules/emoji-regex": { "version": "8.0.0", @@ -802,10 +771,11 @@ } }, "node_modules/escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } @@ -819,31 +789,6 @@ "node": ">=0.8.0" } }, - "node_modules/fast-glob": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", - "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", - "dev": true, - "dependencies": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.2", - "merge2": "^1.3.0", - "micromatch": "^4.0.4" - }, - "engines": { - "node": ">=8.6.0" - } - }, - "node_modules/fastq": { - "version": "1.17.1", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", - "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", - "dev": true, - "dependencies": { - "reusify": "^1.0.4" - } - }, "node_modules/fd-slicer": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", @@ -853,6 +798,24 @@ "pend": "~1.2.0" } }, + "node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, "node_modules/file-type": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/file-type/-/file-type-5.2.0.tgz", @@ -900,15 +863,16 @@ } }, "node_modules/fraction.js": { - "version": "4.3.7", - "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.7.tgz", - "integrity": "sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==", + "version": "5.3.4", + "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-5.3.4.tgz", + "integrity": "sha512-1X1NTtiJphryn/uLQz3whtY6jK3fTqoE3ohKs0tT+Ujr1W59oopxmoEh7Lu5p6vBaPbgoM0bzveAW4Qi5RyWDQ==", "dev": true, + "license": "MIT", "engines": { "node": "*" }, "funding": { - "type": "patreon", + "type": "github", "url": "https://github.com/sponsors/rawify" } }, @@ -964,18 +928,6 @@ "node": "6.* || 8.* || >= 10.*" } }, - "node_modules/get-stdin": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-9.0.0.tgz", - "integrity": "sha512-dVKBjfWisLAicarI2Sf+JuBE/DghV4UzNAVe9yhEJuzeREd3JhOTE9cUaJTeSa77fsbQUK3pcOpJfM59+VKZaA==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/get-stream": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-2.3.1.tgz", @@ -1001,26 +953,6 @@ "node": ">= 6" } }, - "node_modules/globby": { - "version": "14.0.1", - "resolved": "https://registry.npmjs.org/globby/-/globby-14.0.1.tgz", - "integrity": "sha512-jOMLD2Z7MAhyG8aJpNOpmziMOP4rPLcc95oQPKXBazW82z+CEgPFBQvEpRUa1KeIMUJo4Wsm+q6uzO/Q/4BksQ==", - "dev": true, - "dependencies": { - "@sindresorhus/merge-streams": "^2.1.0", - "fast-glob": "^3.3.2", - "ignore": "^5.2.4", - "path-type": "^5.0.0", - "slash": "^5.1.0", - "unicorn-magic": "^0.1.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/got": { "version": "12.6.1", "resolved": "https://registry.npmjs.org/got/-/got-12.6.1.tgz", @@ -1156,15 +1088,6 @@ } ] }, - "node_modules/ignore": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", - "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==", - "dev": true, - "engines": { - "node": ">= 4" - } - }, "node_modules/inherits": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", @@ -1418,28 +1341,6 @@ "node": ">=4" } }, - "node_modules/merge2": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", - "dev": true, - "engines": { - "node": ">= 8" - } - }, - "node_modules/micromatch": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", - "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", - "dev": true, - "dependencies": { - "braces": "^3.0.2", - "picomatch": "^2.3.1" - }, - "engines": { - "node": ">=8.6" - } - }, "node_modules/mimic-response": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-4.0.0.tgz", @@ -1459,9 +1360,9 @@ "dev": true }, "node_modules/nanoid": { - "version": "3.3.7", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", - "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", + "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", "dev": true, "funding": [ { @@ -1469,7 +1370,7 @@ "url": "https://github.com/sponsors/ai" } ], - "peer": true, + "license": "MIT", "bin": { "nanoid": "bin/nanoid.cjs" }, @@ -1478,10 +1379,11 @@ } }, "node_modules/node-releases": { - "version": "2.0.14", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz", - "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==", - "dev": true + "version": "2.0.27", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.27.tgz", + "integrity": "sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA==", + "dev": true, + "license": "MIT" }, "node_modules/normalize-package-data": { "version": "3.0.3", @@ -1507,15 +1409,6 @@ "node": ">=0.10.0" } }, - "node_modules/normalize-range": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", - "integrity": "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/normalize-url": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-8.0.0.tgz", @@ -1612,18 +1505,6 @@ "node": "^12.20.0 || ^14.13.1 || >=16.0.0" } }, - "node_modules/path-type": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-5.0.0.tgz", - "integrity": "sha512-5HviZNaZcfqP95rwpv+1HDgUamezbqdSYTyzjTvwtJSnIH+3vnbmWsItli8OFEndS984VT55M3jduxZbX351gg==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/pend": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", @@ -1631,10 +1512,11 @@ "dev": true }, "node_modules/picocolors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz", - "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==", - "dev": true + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "dev": true, + "license": "ISC" }, "node_modules/picomatch": { "version": "2.3.1", @@ -1679,9 +1561,9 @@ } }, "node_modules/postcss": { - "version": "8.4.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.39.tgz", - "integrity": "sha512-0vzE+lAiG7hZl1/9I8yzKLx3aR9Xbof3fBHKunvMfOCYAtMhrsnccJY2iTURb9EZd5+pLuiNV9/c/GZJOHsgIw==", + "version": "8.5.6", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz", + "integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==", "dev": true, "funding": [ { @@ -1697,33 +1579,33 @@ "url": "https://github.com/sponsors/ai" } ], - "peer": true, + "license": "MIT", "dependencies": { - "nanoid": "^3.3.7", - "picocolors": "^1.0.1", - "source-map-js": "^1.2.0" + "nanoid": "^3.3.11", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" }, "engines": { "node": "^10 || ^12 || >=14" } }, "node_modules/postcss-cli": { - "version": "11.0.0", - "resolved": "https://registry.npmjs.org/postcss-cli/-/postcss-cli-11.0.0.tgz", - "integrity": "sha512-xMITAI7M0u1yolVcXJ9XTZiO9aO49mcoKQy6pCDFdMh9kGqhzLVpWxeD/32M/QBmkhcGypZFFOLNLmIW4Pg4RA==", + "version": "11.0.1", + "resolved": "https://registry.npmjs.org/postcss-cli/-/postcss-cli-11.0.1.tgz", + "integrity": "sha512-0UnkNPSayHKRe/tc2YGW6XnSqqOA9eqpiRMgRlV1S6HdGi16vwJBx7lviARzbV1HpQHqLLRH3o8vTcB0cLc+5g==", "dev": true, + "license": "MIT", "dependencies": { "chokidar": "^3.3.0", - "dependency-graph": "^0.11.0", + "dependency-graph": "^1.0.0", "fs-extra": "^11.0.0", - "get-stdin": "^9.0.0", - "globby": "^14.0.0", "picocolors": "^1.0.0", "postcss-load-config": "^5.0.0", "postcss-reporter": "^7.0.0", "pretty-hrtime": "^1.0.3", "read-cache": "^1.0.0", "slash": "^5.0.0", + "tinyglobby": "^0.2.12", "yargs": "^17.0.0" }, "bin": { @@ -1812,26 +1694,6 @@ "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", "dev": true }, - "node_modules/queue-microtask": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, "node_modules/quick-lru": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz", @@ -1951,39 +1813,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/reusify": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", - "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", - "dev": true, - "engines": { - "iojs": ">=1.0.0", - "node": ">=0.10.0" - } - }, - "node_modules/run-parallel": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", - "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "dependencies": { - "queue-microtask": "^1.2.2" - } - }, "node_modules/safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", @@ -2037,6 +1866,7 @@ "resolved": "https://registry.npmjs.org/slash/-/slash-5.1.0.tgz", "integrity": "sha512-ZA6oR3T/pEyuqwMgAKT0/hAv8oAXckzbkmR0UkUosQ+Mc4RxGoJkRmwHgHufaenlyAgE1Mxgpdcrf75y6XcnDg==", "dev": true, + "license": "MIT", "engines": { "node": ">=14.16" }, @@ -2045,11 +1875,11 @@ } }, "node_modules/source-map-js": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz", - "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", "dev": true, - "peer": true, + "license": "BSD-3-Clause", "engines": { "node": ">=0.10.0" } @@ -2217,6 +2047,36 @@ "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", "dev": true }, + "node_modules/tinyglobby": { + "version": "0.2.15", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz", + "integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "fdir": "^6.5.0", + "picomatch": "^4.0.3" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/tinyglobby/node_modules/picomatch": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", + "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, "node_modules/to-buffer": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/to-buffer/-/to-buffer-1.1.1.tgz", @@ -2257,18 +2117,6 @@ "through": "^2.3.8" } }, - "node_modules/unicorn-magic": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.1.0.tgz", - "integrity": "sha512-lRfVq8fE8gz6QMBuDM6a+LO3IAzTi05H6gCVaUpir2E1Rwpo4ZUog45KpNXKC/Mn3Yb9UDuHumeFTo9iV/D9FQ==", - "dev": true, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/unique-string": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-3.0.0.tgz", @@ -2294,9 +2142,9 @@ } }, "node_modules/update-browserslist-db": { - "version": "1.0.13", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz", - "integrity": "sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==", + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.2.tgz", + "integrity": "sha512-E85pfNzMQ9jpKkA7+TJAi4TJN+tBCuWh5rUcS/sv6cFi+1q9LYDwDI5dpUL0u/73EElyQ8d3TEaeW4sPedBqYA==", "dev": true, "funding": [ { @@ -2312,9 +2160,10 @@ "url": "https://github.com/sponsors/ai" } ], + "license": "MIT", "dependencies": { - "escalade": "^3.1.1", - "picocolors": "^1.0.0" + "escalade": "^3.2.0", + "picocolors": "^1.1.1" }, "bin": { "update-browserslist-db": "cli.js" @@ -2547,44 +2396,12 @@ } } }, - "@nodelib/fs.scandir": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", - "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", - "dev": true, - "requires": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" - } - }, - "@nodelib/fs.stat": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", - "dev": true - }, - "@nodelib/fs.walk": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", - "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", - "dev": true, - "requires": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" - } - }, "@sindresorhus/is": { "version": "5.6.0", "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-5.6.0.tgz", "integrity": "sha512-TV7t8GKYaJWsn00tFDqBw8+Uqmr8A0fRU1tvTQhyZzGv0sJCGRQL3JGMI3ucuKo3XIZdUP+Lx7/gh2t3lewy7g==", "dev": true }, - "@sindresorhus/merge-streams": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/@sindresorhus/merge-streams/-/merge-streams-2.2.1.tgz", - "integrity": "sha512-255V7MMIKw6aQ43Wbqp9HZ+VHn6acddERTLiiLnlcPLU9PdTq9Aijl12oklAgUEblLWye+vHLzmqBx6f2TGcZw==", - "dev": true - }, "@szmarczak/http-timer": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-5.0.1.tgz", @@ -2632,16 +2449,15 @@ } }, "autoprefixer": { - "version": "10.4.19", - "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.19.tgz", - "integrity": "sha512-BaENR2+zBZ8xXhM4pUaKUxlVdxZ0EZhjvbopwnXmxRUfqDmwSpC2lAi/QXvx7NRdPCo1WKEcEF6mV64si1z4Ew==", + "version": "10.4.23", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.23.tgz", + "integrity": "sha512-YYTXSFulfwytnjAPlw8QHncHJmlvFKtczb8InXaAx9Q0LbfDnfEYDE55omerIJKihhmU61Ft+cAOSzQVaBUmeA==", "dev": true, "requires": { - "browserslist": "^4.23.0", - "caniuse-lite": "^1.0.30001599", - "fraction.js": "^4.3.7", - "normalize-range": "^0.1.2", - "picocolors": "^1.0.0", + "browserslist": "^4.28.1", + "caniuse-lite": "^1.0.30001760", + "fraction.js": "^5.3.4", + "picocolors": "^1.1.1", "postcss-value-parser": "^4.2.0" } }, @@ -2651,6 +2467,12 @@ "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", "dev": true }, + "baseline-browser-mapping": { + "version": "2.9.7", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.9.7.tgz", + "integrity": "sha512-k9xFKplee6KIio3IDbwj+uaCLpqzOwakOgmqzPezM0sFJlFKcg30vk2wOiAJtkTSfx0SSQDSe8q+mWA/fSH5Zg==", + "dev": true + }, "binary-extensions": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", @@ -2677,15 +2499,16 @@ } }, "browserslist": { - "version": "4.23.0", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.0.tgz", - "integrity": "sha512-QW8HiM1shhT2GuzkvklfjcKDiWFXHOeFCIA/huJPwHsslwcydgk7X+z2zXpEijP98UCY7HbubZt5J2Zgvf0CaQ==", + "version": "4.28.1", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.1.tgz", + "integrity": "sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA==", "dev": true, "requires": { - "caniuse-lite": "^1.0.30001587", - "electron-to-chromium": "^1.4.668", - "node-releases": "^2.0.14", - "update-browserslist-db": "^1.0.13" + "baseline-browser-mapping": "^2.9.0", + "caniuse-lite": "^1.0.30001759", + "electron-to-chromium": "^1.5.263", + "node-releases": "^2.0.27", + "update-browserslist-db": "^1.2.0" } }, "buffer": { @@ -2756,9 +2579,9 @@ } }, "caniuse-lite": { - "version": "1.0.30001600", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001600.tgz", - "integrity": "sha512-+2S9/2JFhYmYaDpZvo0lKkfvuKIglrx68MwOBqMGHhQsNkLjB5xtc/TGoEPs+MxjSyN/72qer2g97nzR641mOQ==", + "version": "1.0.30001760", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001760.tgz", + "integrity": "sha512-7AAMPcueWELt1p3mi13HR/LHH0TJLT11cnwDJEs3xA4+CK/PLKeO9Kl1oru24htkyUKtkGCvAx4ohB0Ttry8Dw==", "dev": true }, "careful-downloader": { @@ -2964,15 +2787,15 @@ "dev": true }, "dependency-graph": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/dependency-graph/-/dependency-graph-0.11.0.tgz", - "integrity": "sha512-JeMq7fEshyepOWDfcfHK06N3MhyPhz++vtqWhMT5O9A3K42rdsEDpfdVqjaqaAhsw6a+ZqeDvQVtD0hFHQWrzg==", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/dependency-graph/-/dependency-graph-1.0.0.tgz", + "integrity": "sha512-cW3gggJ28HZ/LExwxP2B++aiKxhJXMSIt9K48FOXQkm+vuG5gyatXnLsONRJdzO/7VfjDIiaOOa/bs4l464Lwg==", "dev": true }, "electron-to-chromium": { - "version": "1.4.673", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.673.tgz", - "integrity": "sha512-zjqzx4N7xGdl5468G+vcgzDhaHkaYgVcf9MqgexcTqsl2UHSCmOj/Bi3HAprg4BZCpC7HyD8a6nZl6QAZf72gw==", + "version": "1.5.267", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.267.tgz", + "integrity": "sha512-0Drusm6MVRXSOJpGbaSVgcQsuB4hEkMpHXaVstcPmhu5LIedxs1xNK/nIxmQIU/RPC0+1/o0AVZfBTkTNJOdUw==", "dev": true }, "emoji-regex": { @@ -3000,9 +2823,9 @@ } }, "escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", "dev": true }, "escape-string-regexp": { @@ -3011,28 +2834,6 @@ "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", "dev": true }, - "fast-glob": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", - "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", - "dev": true, - "requires": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.2", - "merge2": "^1.3.0", - "micromatch": "^4.0.4" - } - }, - "fastq": { - "version": "1.17.1", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", - "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", - "dev": true, - "requires": { - "reusify": "^1.0.4" - } - }, "fd-slicer": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", @@ -3042,6 +2843,12 @@ "pend": "~1.2.0" } }, + "fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "dev": true + }, "file-type": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/file-type/-/file-type-5.2.0.tgz", @@ -3074,9 +2881,9 @@ "dev": true }, "fraction.js": { - "version": "4.3.7", - "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.7.tgz", - "integrity": "sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==", + "version": "5.3.4", + "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-5.3.4.tgz", + "integrity": "sha512-1X1NTtiJphryn/uLQz3whtY6jK3fTqoE3ohKs0tT+Ujr1W59oopxmoEh7Lu5p6vBaPbgoM0bzveAW4Qi5RyWDQ==", "dev": true }, "fs-constants": { @@ -3115,12 +2922,6 @@ "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", "dev": true }, - "get-stdin": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-9.0.0.tgz", - "integrity": "sha512-dVKBjfWisLAicarI2Sf+JuBE/DghV4UzNAVe9yhEJuzeREd3JhOTE9cUaJTeSa77fsbQUK3pcOpJfM59+VKZaA==", - "dev": true - }, "get-stream": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-2.3.1.tgz", @@ -3140,20 +2941,6 @@ "is-glob": "^4.0.1" } }, - "globby": { - "version": "14.0.1", - "resolved": "https://registry.npmjs.org/globby/-/globby-14.0.1.tgz", - "integrity": "sha512-jOMLD2Z7MAhyG8aJpNOpmziMOP4rPLcc95oQPKXBazW82z+CEgPFBQvEpRUa1KeIMUJo4Wsm+q6uzO/Q/4BksQ==", - "dev": true, - "requires": { - "@sindresorhus/merge-streams": "^2.1.0", - "fast-glob": "^3.3.2", - "ignore": "^5.2.4", - "path-type": "^5.0.0", - "slash": "^5.1.0", - "unicorn-magic": "^0.1.0" - } - }, "got": { "version": "12.6.1", "resolved": "https://registry.npmjs.org/got/-/got-12.6.1.tgz", @@ -3244,12 +3031,6 @@ "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", "dev": true }, - "ignore": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", - "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==", - "dev": true - }, "inherits": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", @@ -3437,22 +3218,6 @@ } } }, - "merge2": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", - "dev": true - }, - "micromatch": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", - "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", - "dev": true, - "requires": { - "braces": "^3.0.2", - "picomatch": "^2.3.1" - } - }, "mimic-response": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-4.0.0.tgz", @@ -3466,16 +3231,15 @@ "dev": true }, "nanoid": { - "version": "3.3.7", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", - "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", - "dev": true, - "peer": true + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", + "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", + "dev": true }, "node-releases": { - "version": "2.0.14", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz", - "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==", + "version": "2.0.27", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.27.tgz", + "integrity": "sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA==", "dev": true }, "normalize-package-data": { @@ -3496,12 +3260,6 @@ "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", "dev": true }, - "normalize-range": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", - "integrity": "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==", - "dev": true - }, "normalize-url": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-8.0.0.tgz", @@ -3565,12 +3323,6 @@ "integrity": "sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ==", "dev": true }, - "path-type": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-5.0.0.tgz", - "integrity": "sha512-5HviZNaZcfqP95rwpv+1HDgUamezbqdSYTyzjTvwtJSnIH+3vnbmWsItli8OFEndS984VT55M3jduxZbX351gg==", - "dev": true - }, "pend": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", @@ -3578,9 +3330,9 @@ "dev": true }, "picocolors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz", - "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", "dev": true }, "picomatch": { @@ -3611,34 +3363,32 @@ } }, "postcss": { - "version": "8.4.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.39.tgz", - "integrity": "sha512-0vzE+lAiG7hZl1/9I8yzKLx3aR9Xbof3fBHKunvMfOCYAtMhrsnccJY2iTURb9EZd5+pLuiNV9/c/GZJOHsgIw==", + "version": "8.5.6", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz", + "integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==", "dev": true, - "peer": true, "requires": { - "nanoid": "^3.3.7", - "picocolors": "^1.0.1", - "source-map-js": "^1.2.0" + "nanoid": "^3.3.11", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" } }, "postcss-cli": { - "version": "11.0.0", - "resolved": "https://registry.npmjs.org/postcss-cli/-/postcss-cli-11.0.0.tgz", - "integrity": "sha512-xMITAI7M0u1yolVcXJ9XTZiO9aO49mcoKQy6pCDFdMh9kGqhzLVpWxeD/32M/QBmkhcGypZFFOLNLmIW4Pg4RA==", + "version": "11.0.1", + "resolved": "https://registry.npmjs.org/postcss-cli/-/postcss-cli-11.0.1.tgz", + "integrity": "sha512-0UnkNPSayHKRe/tc2YGW6XnSqqOA9eqpiRMgRlV1S6HdGi16vwJBx7lviARzbV1HpQHqLLRH3o8vTcB0cLc+5g==", "dev": true, "requires": { "chokidar": "^3.3.0", - "dependency-graph": "^0.11.0", + "dependency-graph": "^1.0.0", "fs-extra": "^11.0.0", - "get-stdin": "^9.0.0", - "globby": "^14.0.0", "picocolors": "^1.0.0", "postcss-load-config": "^5.0.0", "postcss-reporter": "^7.0.0", "pretty-hrtime": "^1.0.3", "read-cache": "^1.0.0", "slash": "^5.0.0", + "tinyglobby": "^0.2.12", "yargs": "^17.0.0" } }, @@ -3680,12 +3430,6 @@ "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", "dev": true }, - "queue-microtask": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", - "dev": true - }, "quick-lru": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz", @@ -3777,21 +3521,6 @@ "lowercase-keys": "^3.0.0" } }, - "reusify": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", - "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", - "dev": true - }, - "run-parallel": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", - "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", - "dev": true, - "requires": { - "queue-microtask": "^1.2.2" - } - }, "safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", @@ -3823,11 +3552,10 @@ "dev": true }, "source-map-js": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz", - "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==", - "dev": true, - "peer": true + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "dev": true }, "spdx-correct": { "version": "3.2.0", @@ -3969,6 +3697,24 @@ "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", "dev": true }, + "tinyglobby": { + "version": "0.2.15", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz", + "integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==", + "dev": true, + "requires": { + "fdir": "^6.5.0", + "picomatch": "^4.0.3" + }, + "dependencies": { + "picomatch": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", + "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", + "dev": true + } + } + }, "to-buffer": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/to-buffer/-/to-buffer-1.1.1.tgz", @@ -4000,12 +3746,6 @@ "through": "^2.3.8" } }, - "unicorn-magic": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.1.0.tgz", - "integrity": "sha512-lRfVq8fE8gz6QMBuDM6a+LO3IAzTi05H6gCVaUpir2E1Rwpo4ZUog45KpNXKC/Mn3Yb9UDuHumeFTo9iV/D9FQ==", - "dev": true - }, "unique-string": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-3.0.0.tgz", @@ -4022,13 +3762,13 @@ "dev": true }, "update-browserslist-db": { - "version": "1.0.13", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz", - "integrity": "sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==", + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.2.tgz", + "integrity": "sha512-E85pfNzMQ9jpKkA7+TJAi4TJN+tBCuWh5rUcS/sv6cFi+1q9LYDwDI5dpUL0u/73EElyQ8d3TEaeW4sPedBqYA==", "dev": true, "requires": { - "escalade": "^3.1.1", - "picocolors": "^1.0.0" + "escalade": "^3.2.0", + "picocolors": "^1.1.1" } }, "util-deprecate": { diff --git a/package.json b/package.json index 0915a3f36..b3a6b9c90 100644 --- a/package.json +++ b/package.json @@ -31,8 +31,9 @@ "update:pkg:hugo": "npm install --save-dev --save-exact hugo-extended@latest" }, "devDependencies": { - "autoprefixer": "^10.4.19", + "autoprefixer": "^10.4.23", "hugo-extended": "0.148.1", - "postcss-cli": "^11.0.0" + "postcss": "^8.5.6", + "postcss-cli": "^11.0.1" } } From d0699f4685a7a2ac53a231fd16fec5b5a26a19b1 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 15 Dec 2025 03:46:37 +0000 Subject: [PATCH 3/5] fix(docs): correct spelling errors in performance documentation Co-authored-by: hortison <160366376+hortison@users.noreply.github.com> --- content/en/kanvas/advanced/performance/index.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/content/en/kanvas/advanced/performance/index.md b/content/en/kanvas/advanced/performance/index.md index 94b8277ae..a7d9c5e92 100644 --- a/content/en/kanvas/advanced/performance/index.md +++ b/content/en/kanvas/advanced/performance/index.md @@ -29,9 +29,9 @@ Kanvas has a maximum limit of 1,000 components per design. If you exceed this li A non-semantic component is a component that does not represent a meaningful entity in your design. For example, a textbox, a shape, a line, or a comment are all examples of non-semantic components. These components are used for annotation purposes only and do not have a direct relationship to the underlying infrastructure or application that you are modeling. {{< /alert >}} -Kanvas allows up to 1,000 non-sematically meaningfull components per design. Some designs have a large number of comments. While comments are a valuable collaboration tool, excessive comments can impact the performance of your design. Consider archiving or deleting old comments to keep your design running smoothly. +Kanvas allows up to 1,000 non-semantically meaningful components per design. Some designs have a large number of comments. While comments are a valuable collaboration tool, excessive comments can impact the performance of your design. Consider archiving or deleting old comments to keep your design running smoothly. -#### Maxiumum Number of Orchestrated Components (semantically meaningful components) +#### Maximum Number of Orchestrated Components (semantically meaningful components) {{< alert type="note" title="What is a Semantic Component?" >}} A semantic component is a component that represents a meaningful entity in your design. For example, a server, a database, or a network switch are all examples of semantic components. These components have a direct relationship to the underlying infrastructure or application that you are modeling. @@ -55,7 +55,7 @@ Upon loading a design exceeds that exceeds 20 tags within a single design, Kanva ### Maximum Number of Users -Under the Free [subscription plan](https://layer5.io/pricing), Kanvas supports at least 20 users per design. As resources allow, up to 34 users may simulatanously collaborate within a given design. If you have a large team collaborating on a design, be mindful of the number of users active at the same time. Too many users can strain the performance of your design, leading to slower response times and potential data loss. See [Layer5 Cloud Networking Services](/cloud/self-hosted/planning/peer-to-peer-communication) for more details. +Under the Free [subscription plan](https://layer5.io/pricing), Kanvas supports at least 20 users per design. As resources allow, up to 34 users may simultaneously collaborate within a given design. If you have a large team collaborating on a design, be mindful of the number of users active at the same time. Too many users can strain the performance of your design, leading to slower response times and potential data loss. See [Layer5 Cloud Networking Services](/cloud/self-hosted/planning/peer-to-peer-communication) for more details. ### Impact of Images From b793e43dbb8eecd4d0b3e7f1b89dcb78319516b3 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 15 Dec 2025 04:05:03 +0000 Subject: [PATCH 4/5] refactor(docs): rewrite performance documentation to be user-facing Co-authored-by: leecalcote <7570704+leecalcote@users.noreply.github.com> --- .../en/kanvas/advanced/performance/index.md | 466 +++++++----------- 1 file changed, 181 insertions(+), 285 deletions(-) diff --git a/content/en/kanvas/advanced/performance/index.md b/content/en/kanvas/advanced/performance/index.md index a7d9c5e92..9ab58371d 100644 --- a/content/en/kanvas/advanced/performance/index.md +++ b/content/en/kanvas/advanced/performance/index.md @@ -99,386 +99,282 @@ To optimize performance, consider the following: 3. Remove any unnecessary images from your design. 4. Use image compression tools to reduce the size of your images before adding them to your design. -## Compound Node Rendering Performance +## What Affects Performance -When working with compound nodes (parent nodes containing multiple child nodes), you may encounter performance challenges as the number of children increases. Understanding these issues and the optimizations available can help you create more responsive designs. +As your designs grow in complexity, certain design patterns can impact how smoothly Kanvas responds. Understanding these factors helps you create designs that remain fast and responsive. -### Root Cause Analysis +### Working with Grouped Components -The rendering performance of compound nodes with many children can be significantly impacted by several factors: +When you create groups of components (placing multiple components inside a parent container), you might notice performance differences as the number of grouped items increases. Here's what you might experience: -- **Badge Rendering Plugin Overhead**: The `@layer5/cytoscape-node-html-label` plugin, while powerful for rendering badges and labels, can become a performance bottleneck for compound nodes with many children. -- **Overly Broad Selectors**: The badge selector `node[?label]` matches virtually every node in the graph, causing unnecessary re-renders even for nodes that haven't changed. -- **Missing Viewport Culling**: Badges are rendered for all nodes in the design, even those currently off-screen and not visible to the user, wasting computational resources. -- **Re-render Multiplication**: With 100 child nodes in a compound parent, approximately 303 badge re-renders occur per update cycle. -- **Drag Operation Overhead**: During interactive operations like dragging, the system can generate 18,000-36,000 function calls per second, leading to UI lag and poor user experience. +**Signs of Performance Impact:** +- Dragging groups feels laggy or choppy +- Design takes longer to load and display +- Moving or resizing groups shows delayed response +- Screen updates appear slower during interactions -{{< alert type="warning" title="Performance Impact" >}} -Large compound nodes (100+ children) can experience significant lag during drag operations and viewport changes without proper optimizations. +{{< alert type="warning" title="Large Groups" >}} +Groups containing 100 or more components may experience noticeable lag during drag operations. Consider breaking large groups into smaller, logical subgroups for better performance. {{< /alert >}} -### Performance Metrics +### How Kanvas Optimizes Your Design -The following table illustrates the dramatic performance improvements achieved through optimization: +Kanvas automatically works behind the scenes to keep your designs running smoothly: -| Scenario | Before Optimization | After Optimization | Improvement | -|----------|---------------------|-------------------|-------------| -| Badge re-renders per update (100 children) | 303 | ~30 | 90% reduction | -| Function calls/sec during drag | 18,000-36,000 | 500-3,000 | 90-95% reduction | -| Perceived responsiveness | Laggy, choppy | Smooth, responsive | Significantly improved | +**Smart Rendering:** +- Kanvas only updates the parts of your design that actually change, not the entire canvas +- Components outside your current view aren't fully rendered, saving resources +- Information badges and labels are displayed efficiently to prevent unnecessary redraws -### Optimizations Implemented +**What This Means for You:** +The table below shows typical performance improvements you'll experience: -Kanvas incorporates several key optimizations to address compound node rendering performance: - -#### 1. Viewport Culling (50-80% reduction) - -Only badges for nodes currently visible in the viewport are rendered. Nodes outside the visible area are skipped, reducing unnecessary computation. +| Design Scenario | Without Optimization | With Optimization | Your Experience | +|----------------|----------------------|-------------------|-----------------| +| Dragging a group of 100 components | Laggy and slow | Smooth and responsive | 90% improvement | +| Moving grouped components | Choppy interactions | Fluid movement | Significantly better | +| Overall responsiveness | Delayed reactions | Immediate feedback | Much more responsive | {{< alert type="success" title="Automatic Optimization" >}} -Viewport culling is automatically enabled in Kanvas. No configuration is required to benefit from this optimization. +These optimizations work automatically. You don't need to configure anything to benefit from better performance. {{< /alert >}} -#### 2. Increased Memoization TTL (70% reduction) - -Badge rendering is intelligently cached to avoid redundant computations: - -- **Error Badges**: Cache duration increased from 300ms to 1000ms -- **Compound Badges**: Cache duration increased from 200ms to 1000ms - -This means that if a node's state hasn't changed, its badge rendering is reused from cache rather than recomputed. - -#### 3. Combined Impact (90-95% reduction) - -When viewport culling and increased memoization work together, the overall reduction in badge re-renders reaches 90-95%, resulting in a dramatically more responsive user interface even with complex compound nodes. - -{{< alert type="note" title="Technical Reference" >}} -These optimizations were implemented in PR #3917 and address issues documented in #3916 from the layer5labs/meshery-extensions repository. -{{< /alert >}} - -## Cytoscape Plugin Performance Considerations - -Kanvas leverages multiple Cytoscape.js plugins to provide rich interactive features. Understanding the performance characteristics of these plugins can help you anticipate and mitigate potential performance issues. - -### Plugin-Specific Performance Characteristics - -#### Compound Drag-and-Drop Plugin +## Managing Design Complexity -The compound drag-and-drop functionality may experience performance degradation with large graphs. This is a known limitation documented in the plugin's own README. If you're working with designs containing hundreds of nodes, consider: +Kanvas provides many interactive features that enhance your design experience. Understanding how these features work together helps you maintain optimal performance. -- Breaking your design into multiple smaller designs -- Using the Layers panel to hide unnecessary components during editing -- Limiting the number of compound nodes with large child counts +### Features That Impact Performance -#### Event Cascade Issues +Your design experience includes several interactive capabilities that all work together: -Multiple plugins listening to the same Cytoscape events can create a multiplication effect that compounds performance overhead: +**Interactive Features:** +- **Alignment guides** help you position components precisely as you drag them +- **Automatic relationship management** keeps connections between components updated +- **Tooltips and information displays** show helpful context as you work +- **Resize handles and controls** let you adjust component sizes smoothly +- **Visual grouping indicators** show which components belong together -- **Grid Guide Plugin**: Listens for drag events to display alignment guides -- **Automove Plugin**: Monitors node movements to maintain relationships -- **Popper Plugin**: Tracks node positions for tooltip positioning - -When all these plugins respond to a single drag event, the computational cost multiplies, potentially causing lag during interactive operations. +When you're working with many components simultaneously, these features all activate together, which can sometimes slow down interactions like dragging. {{< alert type="info" title="Performance Tip" >}} -The impact of event cascades is most noticeable during continuous operations like dragging. The render throttling optimizations described later in this document help mitigate this issue. +If dragging feels slow, try these strategies: +- Hide unnecessary layers temporarily using the Layers panel +- Break your design into smaller, focused sections +- Work on one area of your design at a time +- Zoom in to focus on specific components {{< /alert >}} -#### HTML Plugin Overhead - -Earlier versions of Kanvas used DOM-based HTML rendering for interactive elements. Migration to a 2D canvas renderer has provided significant performance improvements for: +### Practical Tips for Better Performance -- **Resize Handles**: Canvas-based handles render faster and respond more smoothly -- **Overlays**: Canvas overlays avoid DOM manipulation overhead -- **Interactive Controls**: Canvas-based controls reduce browser reflow and repaint operations +**When Creating Large Designs:** +1. Use the Layers panel to hide components you're not actively editing +2. Break complex designs into multiple smaller designs that you can link together +3. Group related components thoughtfully rather than creating very large groups +4. Remove old comments and annotations you no longer need -#### Bubblesets Optimization +**When Experiencing Slowness:** +1. Check if you have many layers enabled that you're not using +2. Consider if your design has grown beyond 500 components (approaching the 1,000 limit) +3. Try hiding relationship layers temporarily while arranging components +4. Close and reopen your design to refresh the canvas -For designs with complex relationship visualizations, the Bubblesets algorithm has been optimized to provide better performance through improved algorithms that reduce computational complexity. - -{{< alert type="note" title="Technical Reference" >}} -These optimizations were implemented across multiple PRs: #3885, #3887, and #3500 from the layer5labs/meshery-extensions repository. -{{< /alert >}} +## How Kanvas Keeps Things Fast -## State Management and Rendering Optimizations +Kanvas includes built-in intelligence to maintain smooth performance as you work on your designs. You don't need to manage these features manually—they work automatically in the background. -Efficient state management is critical for maintaining good performance as your designs grow in complexity. Kanvas employs several sophisticated techniques to optimize state updates and rendering. +### Efficient Updates -### Fine-Grained Reactivity +**What Happens When You Make Changes:** +Think of your design like a document. When you edit a single paragraph, you wouldn't want your word processor to reformat the entire document. Similarly, Kanvas only updates the specific components you're changing, not your entire design. -Instead of expensive JSON snapshot computations that process the entire design state, Kanvas uses fine-grained state updates that only affect the specific parts of the design that have changed. +**Benefits You'll Notice:** +- Quick response when you move or edit components +- Smooth interactions even in large designs +- Consistent performance throughout your work session +- Better experience when multiple people collaborate on the same design -**Benefits:** -- Reduced CPU usage during state updates -- Faster response times for user interactions -- Lower memory consumption -- More predictable performance characteristics - -{{< alert type="success" title="Automatic Optimization" >}} -Fine-grained reactivity is built into Kanvas's state management system and requires no configuration. +{{< alert type="success" title="Smart Performance" >}} +Kanvas is designed to only update what needs updating, keeping your design responsive without requiring any configuration from you. {{< /alert >}} -### Render Throttling - -To prevent UI thrashing during continuous operations, Kanvas implements render throttling that locks down re-renders to a maximum of 10 per second during operations like: +### Smooth Interactions During Continuous Operations -- Dragging nodes or groups of nodes -- Resizing components -- Panning and zooming the viewport -- Bulk operations affecting multiple components +When you're actively dragging components, resizing groups, or panning around your design, Kanvas automatically manages how often the screen updates to ensure smooth, responsive interactions. -This ensures that the UI remains responsive even during intensive operations, preventing the browser from becoming overwhelmed with render requests. +**What This Means:** +- Dragging feels fluid, not jerky +- Your cursor stays synchronized with the component you're moving +- Multiple simultaneous operations remain responsive +- The interface doesn't freeze or stutter during intensive operations -**Target Performance:** -- Maximum re-renders: 10 per second -- Frame time budget: ~100ms per render -- Typical user-perceived lag: Minimal to none +## Working with Different Zoom Levels -### Selector Optimization +The zoom level you choose affects both what you see and how your design performs. Kanvas adapts its rendering based on your current zoom level to provide the best experience. -Cytoscape selectors used for sharedState snapshots have been optimized to reduce computational overhead: +### Progressive Detail Display -- Use specific selectors instead of broad queries when possible -- Cache selector results when appropriate -- Minimize the number of selector evaluations per frame -- Defer non-critical selector operations to idle time +Kanvas automatically adjusts the level of detail based on how far you're zoomed in or out: -### Evaluation Deferral +**Zoomed Out (Overview Mode):** +- Shows component shapes and primary names +- Displays main relationships between components +- Provides a fast, high-level view of your entire design +- Perfect for understanding overall structure -Kanvas intelligently skips unnecessary feasibility evaluations for events that don't require validation: +**Medium Zoom (Working Mode):** +- Adds relationship details and secondary information +- Shows more component metadata +- Good balance between detail and performance -- **Tap Events**: No feasibility check needed for simple selections -- **Double-Click Events**: Validation deferred until action is confirmed -- **Hover Events**: No evaluation unless tooltip or preview is needed +**Zoomed In (Detail Mode):** +- Displays all badges, annotations, and detailed information +- Shows validation messages and warnings +- Reveals complete component properties +- Best for detailed configuration work -This reduces computational overhead for common user interactions that don't modify the design. - -{{< alert type="note" title="Technical Reference" >}} -State management optimizations were implemented in PRs #3448, #3595, #3121, and #3114 from the layer5labs/meshery-extensions repository. +{{< alert type="info" title="Use Zoom Strategically" >}} +Take advantage of zoom levels: zoom out to get an overview and rearrange major sections, then zoom in when you need to configure specific components in detail. {{< /alert >}} -## Zoom and Viewport Performance - -The zoom level and viewport position significantly impact rendering performance. Kanvas implements several optimizations to ensure smooth performance across all zoom levels. - -### Minimum Zoom Viewport - -Maintaining a consistent minimum zoom level ensures that detailed rendering works properly across all interactive elements: - -- **Layers**: All layers render consistently at minimum zoom -- **Badges**: Error, warning, and info badges remain visible and properly sized -- **Textboxes**: Text remains readable without excessive scaling -- **Interactions**: Interactive handles and controls maintain proper hit targets -- **Device Compatibility**: Consistent experience across desktop, tablet, and mobile devices - -{{< alert type="warning" title="Zoom Limits" >}} -Kanvas enforces minimum and maximum zoom limits to ensure optimal rendering performance and usability. Attempting to zoom beyond these limits will have no effect. -{{< /alert >}} - -### Progressive Detail Rendering - -Kanvas implements view filtering based on zoom level to show more or less detail depending on the current viewport: - -- **Zoomed Out (Low Detail)**: Show component shapes and primary labels only -- **Medium Zoom**: Add relationship lines and secondary labels -- **Zoomed In (High Detail)**: Show all badges, annotations, and detailed metadata - -This approach ensures that rendering resources are focused on visible, meaningful details at each zoom level. - **Performance Benefits:** -- Reduced rendering overhead at low zoom levels -- Faster panning and zooming operations -- Smoother performance with large designs -- Better user experience with progressive disclosure of information +When you're zoomed out, Kanvas doesn't spend resources rendering details you can't see anyway. This keeps panning and navigation fast even in large designs. As you zoom in, more information progressively appears, giving you the detail you need without overwhelming the display. -### Zoom Rendering Consistency +### Zoom Limits -Fixes have been implemented to ensure consistent rendering behavior at all zoom levels: +Kanvas sets reasonable minimum and maximum zoom levels to ensure everything remains usable: -- Badges maintain proper sizing relative to nodes -- Relationship lines scale appropriately -- Interactive handles remain accessible -- Text remains readable without pixelation +- Text stays readable without becoming pixelated +- Interactive handles remain large enough to click +- Badges and indicators maintain appropriate sizes +- The design looks good on all devices (desktop, tablet, mobile) -{{< alert type="note" title="Technical Reference" >}} -Zoom and viewport optimizations were implemented in PRs #3528, #3711, and #2292 from the layer5labs/meshery-extensions repository. +{{< alert type="warning" title="Zoom Boundaries" >}} +If you try to zoom beyond the minimum or maximum limits, Kanvas won't zoom further. These limits are in place to maintain usability and performance. {{< /alert >}} -## Performance Testing Guidelines +## Testing Your Design's Performance -Regular performance testing helps ensure that your designs remain responsive as they grow in complexity. Use these guidelines to validate performance characteristics. +As you build larger designs, it's helpful to evaluate how well they perform. Here are practical ways to test your design's responsiveness. -### Test Scenarios +### Practical Test Scenarios -Validate performance across a range of design complexities: +Try these scenarios to understand how your design performs: -1. **Baseline Scenario**: 1 parent + 10 children - - Expected behavior: Smooth, lag-free interactions - - Use case: Small component groups, basic hierarchies +1. **Small Group Test** (10-20 components in a group) + - Does dragging feel instant and smooth? + - Do components respond immediately to your actions? + - This is the baseline—everything should feel effortless -2. **Medium Complexity**: 1 parent + 50 children - - Expected behavior: Responsive with minor delays acceptable - - Use case: Moderate-sized microservice architectures, namespace groups +2. **Medium Design Test** (50-100 components total) + - Can you drag groups without noticeable delay? + - Does panning around the canvas feel fluid? + - Are minor delays acceptable for your workflow? -3. **Large/Complex**: 1 parent + 100 children - - Expected behavior: Acceptable performance with optimizations - - Use case: Large namespaces, complex service meshes, cluster visualizations +3. **Large Design Test** (200+ components) + - How does dragging large groups feel? + - Is there lag when you first load the design? + - Does zooming in and out remain responsive? -4. **Stress Test**: 3 levels of nesting - - Expected behavior: Functional but may experience some lag - - Use case: Deeply nested organizational structures, multi-tier architectures +4. **Complex Nesting Test** (groups within groups, 3+ levels deep) + - Can you still move parent groups smoothly? + - Do nested relationships display correctly? + - Is the design still manageable? {{< alert type="info" title="Testing Approach" >}} -Start with the baseline scenario and progressively increase complexity. This helps identify the specific point where performance begins to degrade. +Start simple and add complexity gradually. This helps you identify exactly when performance starts to degrade, making it easier to adjust your design approach. {{< /alert >}} -### Target Metrics +### Simple Performance Checks -Aim for the following performance targets when testing: +You don't need specialized tools to evaluate performance. Just ask yourself: -#### Frame Rate During Drag Operations -- **Target**: 60 FPS (frames per second) -- **Acceptable Threshold**: 30 FPS -- **Below Threshold**: Indicates performance issues requiring optimization +**Responsiveness Check:** +- Does dragging components feel smooth or choppy? +- Do components respond immediately when you click them? +- Can you pan around the design without lag? -#### Time to First Badge Render -- **Target**: < 100ms -- **Measurement**: Time from design load to all visible badges rendered -- **Impact**: Affects perceived load time and user experience +**Loading Time Check:** +- Does your design load within a few seconds? +- Are badges and indicators visible quickly? +- Does the design feel "ready" when it first appears? -#### Badge Re-renders Per Drag Operation -- **Target**: < 1,000 re-renders -- **Measurement**: Total badge rendering calls during a single drag operation -- **Impact**: Directly affects drag smoothness and responsiveness +**Interaction Check:** +- Can you resize components smoothly? +- Do relationships update without delay? +- Does the interface feel responsive or sluggish? -### Monitoring Performance +### Using Browser Developer Tools (Optional) -To monitor performance during testing: +For more detailed performance analysis, you can use your browser's built-in developer tools: -1. **Browser DevTools**: Use the Performance tab to record and analyze interactions -2. **Frame Rate**: Monitor FPS during drag operations -3. **CPU Usage**: Watch for excessive CPU spikes during interactions -4. **Memory Usage**: Check for memory leaks during extended sessions +1. **Open Developer Tools**: Press F12 (Windows/Linux) or Cmd+Option+I (Mac) +2. **Navigate to Performance Tab**: Look for the "Performance" or "Profiler" tab +3. **Record an Interaction**: Click the record button, perform an action (like dragging), then stop recording +4. **Review Results**: Look for long operations or frame drops that indicate performance issues {{< alert type="warning" title="Browser Differences" >}} -Performance can vary significantly across browsers. Test in your primary target browsers (Chrome, Firefox, Safari) to ensure consistent experience. +Performance can vary between browsers. If your design feels slow, try testing in Chrome, Firefox, or Safari to see if performance differs. {{< /alert >}} -## Long-term Architecture Recommendations - -While current optimizations provide significant performance improvements, several architectural enhancements could provide even greater benefits in future versions of Kanvas. - -### Canvas-Based Badge Rendering - -Migrating from DOM-based badge rendering to canvas-based rendering could provide 10-100x performance improvement: - -**Current Approach (DOM-based):** -- Each badge is an HTML element -- Browser must manage layout, styles, and reflows -- Limited by DOM manipulation performance - -**Proposed Approach (Canvas-based):** -- Badges rendered directly to canvas -- No DOM manipulation overhead -- Batch rendering operations -- Better control over rendering pipeline - -**Expected Benefits:** -- 10-100x faster badge rendering -- Reduced memory footprint -- Smoother animations and transitions -- Better scaling for large designs - -### Virtual Badge Manager +## Future Improvements -A virtual badge manager would only render badges currently visible in the viewport: +We're continuously working to make Kanvas even faster and more responsive. Future updates will bring additional performance enhancements, including: -**Implementation Strategy:** -- Track viewport bounds -- Maintain a spatial index of badge positions -- Render only badges intersecting with viewport -- Update dynamically as viewport changes +- Improved rendering techniques for even smoother interactions +- Smarter optimization of complex designs +- Better handling of very large designs (1,000+ components) +- Enhanced performance on lower-powered devices -**Expected Benefits:** -- Constant rendering time regardless of total badge count -- Seamless handling of designs with thousands of nodes -- Reduced GPU memory usage -- Improved scrolling and panning performance +These improvements will happen automatically through Kanvas updates—you won't need to change your designs or workflows to benefit from them. -### Web Worker Rendering - -Offloading computationally intensive operations to background threads (Web Workers) could prevent UI blocking: - -**Candidate Operations:** -- Badge layout calculations -- Relationship path computations -- Validation and feasibility checks -- Complex selector evaluations - -**Expected Benefits:** -- UI thread remains responsive during heavy computations -- Better multi-core CPU utilization -- Smoother user experience during intensive operations -- Reduced perceived lag - -{{< alert type="info" title="Future Enhancement" >}} -Web Worker rendering requires careful coordination between threads and may introduce complexity in state management. -{{< /alert >}} - -### Progressive Rendering Strategy - -Implement a priority-based rendering system that renders critical elements first: - -**Rendering Priority Levels:** -1. **Critical (Immediate)**: Error badges, validation warnings -2. **High (< 50ms)**: Info badges, relationship indicators -3. **Medium (< 200ms)**: Annotations, secondary labels -4. **Low (Idle Time)**: Decorative elements, optional metadata - -**Expected Benefits:** -- Faster time to interactive -- Critical information always visible -- Better perceived performance -- Graceful degradation under load - -{{< alert type="success" title="User-Centric Design" >}} -Progressive rendering ensures users see the most important information first, even if the design hasn't fully loaded. +{{< alert type="success" title="Continuous Improvement" >}} +Performance optimization is an ongoing priority. As Kanvas evolves, your existing designs will automatically benefit from new performance enhancements. {{< /alert >}} -## Performance-Related URL Parameters +## Special URL Options for Performance -Kanvas supports several URL parameters that can impact rendering performance and behavior. Understanding these parameters helps you optimize the loading and rendering of your designs. +When opening designs in Kanvas, you can add special parameters to the URL that change how your design loads and displays. These options give you control over the balance between features and performance. ### Full Render Mode -The `render=full` URL parameter enables comprehensive rendering of all design elements, including advanced relationships: +By default, Kanvas loads your design with optimized rendering for best performance. If you need to see absolutely everything—all relationships, groupings, and metadata—you can use full render mode. -**Usage:** +**How to Use It:** +Add `render=full` to your design URL: ``` https://cloud.layer5.io/kanvas/designer?design=&render=full ``` -**What It Includes:** -- All component relationships -- TagSet relationships and groupings +**What You'll See:** +- Every relationship between components, including complex connections +- All tag-based groupings and relationships +- Complete component metadata and properties +- All status badges and validation indicators - Advanced semantic relationships -- Complete metadata rendering -- All badges and indicators -**Performance Implications:** -- Increased initial load time -- Higher memory usage -- More computational overhead during updates -- May impact performance on large designs (100+ components) +**When to Use Full Render Mode:** +- When you need to see the complete picture of your design +- For troubleshooting relationship issues +- When generating comprehensive documentation +- For detailed audits or reviews + +**When NOT to Use It:** +- For everyday design work (standard mode is faster) +- With large designs (100+ components) where performance matters +- When you only need to view or edit a specific part of your design +- On slower computers or devices -{{< alert type="warning" title="Large Design Consideration" >}} -For designs with hundreds of components or complex TagSet relationships, full render mode may cause noticeable performance impact. Consider using standard render mode and selectively enabling layers as needed. +{{< alert type="warning" title="Performance Trade-off" >}} +Full render mode shows everything, but it takes longer to load and may feel slower during interactions. For most work, the standard mode provides the best experience. Use full render mode only when you specifically need to see all relationships and metadata at once. {{< /alert >}} -### Additional Parameters +**Practical Example:** +Imagine you have a design with 200 microservices and hundreds of relationships. In standard mode, Kanvas shows you what you need to work effectively. In full render mode, it displays every single connection and grouping—which is great for a complete overview but can make the design feel sluggish. + +### More URL Options -For complete documentation on all available URL parameters and their effects, see [URL Parameters](/kanvas/advanced/url-parameters/). +Kanvas supports several other URL parameters that control different aspects of your design. For a complete list of available options and what they do, see [URL Parameters](/kanvas/advanced/url-parameters/). -{{< alert type="note" title="Parameter Combinations" >}} -URL parameters can be combined to customize your Kanvas experience. Experiment with different combinations to find the optimal balance between features and performance for your specific use case. +{{< alert type="info" title="Experiment and Learn" >}} +Try different URL parameters to find what works best for your workflow. You can combine multiple parameters to customize your Kanvas experience exactly how you need it. {{< /alert >}} From 24d64debc1504193bbb8172dedd2bfbd0d31ef79 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 15 Dec 2025 04:06:52 +0000 Subject: [PATCH 5/5] fix(docs): correct spelling errors in existing performance content Co-authored-by: leecalcote <7570704+leecalcote@users.noreply.github.com> --- content/en/kanvas/advanced/performance/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/en/kanvas/advanced/performance/index.md b/content/en/kanvas/advanced/performance/index.md index 9ab58371d..9a87e0ff2 100644 --- a/content/en/kanvas/advanced/performance/index.md +++ b/content/en/kanvas/advanced/performance/index.md @@ -82,7 +82,7 @@ Depending on the type of layer disabled, either specific components or all compo > Even though you might hide components, those components are not deleted or removed from your design. These components are simply hidden from current view. -In the same way, as you toggle the evaluation of different types of relationships, understand that this releationships between your components still exist. Those relationsihps are simply **temporarily hidding** from view and the overhead of their evaluation eliminated while the respective type of relationship is disabled. +In the same way, as you toggle the evaluation of different types of relationships, understand that these relationships between your components still exist. Those relationships are simply **temporarily hidden** from view and the overhead of their evaluation eliminated while the respective type of relationship is disabled. Using the Layers panel you control the level of sophistication or simplicity of the rendering of components and relationships in your designs. You can both simplify your design layout by removing unnecessary elements and improve performance simultaneously. Alternatively, you can increase the level of detail in your design by enabling additional layers and relationships, while controlling the balance between detail and performance.