diff --git a/README.md b/README.md
index a8c2b9b0..5f867cc3 100644
--- a/README.md
+++ b/README.md
@@ -8,16 +8,14 @@
Crawl4AI simplifies asynchronous web crawling and data extraction, making it accessible for large language models (LLMs) and AI applications. ππ
-> Looking for the synchronous version? Check out [README.sync.md](./README.sync.md). You can also access the previous version in the branch [V0.2.76](https://github.com/unclecode/crawl4ai/blob/v0.2.76).
+## New in 0.3.72 β¨
-## New update 0.3.6
-- π Multi-browser support (Chromium, Firefox, WebKit)
-- πΌοΈ Improved image processing with lazy-loading detection
-- π§ Custom page timeout parameter for better control over crawling behavior
-- π°οΈ Enhanced handling of delayed content loading
-- π Custom headers support for LLM interactions
-- πΌοΈ iframe content extraction for comprehensive page analysis
-- β±οΈ Flexible timeout and delayed content retrieval options
+- π Fit markdown generation for extracting main article content.
+- πͺ Magic mode for comprehensive anti-bot detection bypass.
+- π Enhanced multi-browser support with seamless switching (Chromium, Firefox, WebKit)
+- π New chunking strategies(Sliding window, Overlapping window, Flexible size control)
+- πΎ Improved caching system for better performance
+- β‘ Optimized batch processing with automatic rate limiting
## Try it Now!
@@ -30,22 +28,28 @@ Crawl4AI simplifies asynchronous web crawling and data extraction, making it acc
- π Completely free and open-source
- π Blazing fast performance, outperforming many paid services
- π€ LLM-friendly output formats (JSON, cleaned HTML, markdown)
+- π Multi-browser support (Chromium, Firefox, WebKit)
- π Supports crawling multiple URLs simultaneously
- π¨ Extracts and returns all media tags (Images, Audio, and Video)
- π Extracts all external and internal links
- π Extracts metadata from the page
-- π Custom hooks for authentication, headers, and page modifications before crawling
+- π Custom hooks for authentication, headers, and page modifications
- π΅οΈ User-agent customization
-- πΌοΈ Takes screenshots of the page
+- πΌοΈ Takes screenshots of pages with enhanced error handling
- π Executes multiple custom JavaScripts before crawling
- π Generates structured output without LLM using JsonCssExtractionStrategy
- π Various chunking strategies: topic-based, regex, sentence, and more
- π§ Advanced extraction strategies: cosine clustering, LLM, and more
- π― CSS selector support for precise data extraction
- π Passes instructions/keywords to refine extraction
-- π Proxy support for enhanced privacy and access
-- π Session management for complex multi-page crawling scenarios
-- π Asynchronous architecture for improved performance and scalability
+- π Proxy support with authentication for enhanced access
+- π Session management for complex multi-page crawling
+- π Asynchronous architecture for improved performance
+- πΌοΈ Improved image processing with lazy-loading detection
+- π°οΈ Enhanced handling of delayed content loading
+- π Custom headers support for LLM interactions
+- πΌοΈ iframe content extraction for comprehensive analysis
+- β±οΈ Flexible timeout and delayed content retrieval options
## Installation π οΈ
diff --git a/crawl4ai/content_scrapping_strategy.py b/crawl4ai/content_scrapping_strategy.py
index 7799de66..6119a414 100644
--- a/crawl4ai/content_scrapping_strategy.py
+++ b/crawl4ai/content_scrapping_strategy.py
@@ -207,8 +207,8 @@ class WebScrappingStrategy(ContentScrappingStrategy):
keep_element = False
- social_media_domains = SOCIAL_MEDIA_DOMAINS + kwargs.get('social_media_domains', [])
- social_media_domains = list(set(social_media_domains))
+ exclude_social_media_domains = SOCIAL_MEDIA_DOMAINS + kwargs.get('exclude_social_media_domains', [])
+ exclude_social_media_domains = list(set(exclude_social_media_domains))
try:
@@ -249,7 +249,7 @@ class WebScrappingStrategy(ContentScrappingStrategy):
element.decompose()
return False
elif kwargs.get('exclude_social_media_links', False):
- if any(domain in normalized_href.lower() for domain in social_media_domains):
+ if any(domain in normalized_href.lower() for domain in exclude_social_media_domains):
element.decompose()
return False
elif kwargs.get('exclude_domains', []):
@@ -285,7 +285,7 @@ class WebScrappingStrategy(ContentScrappingStrategy):
if not kwargs.get('exclude_external_images', False) and kwargs.get('exclude_social_media_links', False):
src_url_base = src.split('/')[2]
url_base = url.split('/')[2]
- if any(domain in src for domain in social_media_domains):
+ if any(domain in src for domain in exclude_social_media_domains):
element.decompose()
return False
diff --git a/docs/details/extraction.md b/docs/details/extraction.md
new file mode 100644
index 00000000..25fc4305
--- /dev/null
+++ b/docs/details/extraction.md
@@ -0,0 +1,157 @@
+### Extraction Strategies
+
+#### 1. LLMExtractionStrategy
+```python
+LLMExtractionStrategy(
+ # Core Parameters
+ provider: str = DEFAULT_PROVIDER, # LLM provider (e.g., "openai/gpt-4", "huggingface/...", "ollama/...")
+ api_token: Optional[str] = None, # API token for the provider
+ instruction: str = None, # Custom instruction for extraction
+ schema: Dict = None, # Pydantic model schema for structured extraction
+ extraction_type: str = "block", # Type of extraction: "block" or "schema"
+
+ # Chunking Parameters
+ chunk_token_threshold: int = CHUNK_TOKEN_THRESHOLD, # Maximum tokens per chunk
+ overlap_rate: float = OVERLAP_RATE, # Overlap between chunks
+ word_token_rate: float = WORD_TOKEN_RATE, # Conversion rate from words to tokens
+ apply_chunking: bool = True, # Whether to apply text chunking
+
+ # API Configuration
+ base_url: str = None, # Base URL for API calls
+ api_base: str = None, # Alternative base URL
+ extra_args: Dict = {}, # Additional provider-specific arguments
+
+ verbose: bool = False # Enable verbose logging
+)
+```
+
+Usage Example:
+```python
+class NewsArticle(BaseModel):
+ title: str
+ content: str
+
+strategy = LLMExtractionStrategy(
+ provider="ollama/nemotron",
+ api_token="your-token",
+ schema=NewsArticle.schema(),
+ instruction="Extract news article content with title and main text"
+)
+
+result = await crawler.arun(url="https://example.com", extraction_strategy=strategy)
+```
+
+#### 2. JsonCssExtractionStrategy
+```python
+JsonCssExtractionStrategy(
+ schema: Dict[str, Any], # Schema defining extraction rules
+ verbose: bool = False # Enable verbose logging
+)
+
+# Schema Structure
+schema = {
+ "name": str, # Name of the extraction schema
+ "baseSelector": str, # CSS selector for base elements
+ "fields": [
+ {
+ "name": str, # Field name
+ "selector": str, # CSS selector
+ "type": str, # Field type: "text", "attribute", "html", "regex", "nested", "list", "nested_list"
+ "attribute": str, # For type="attribute"
+ "pattern": str, # For type="regex"
+ "transform": str, # Optional: "lowercase", "uppercase", "strip"
+ "default": Any, # Default value if extraction fails
+ "fields": List[Dict], # For nested/list types
+ }
+ ]
+}
+```
+
+Usage Example:
+```python
+schema = {
+ "name": "News Articles",
+ "baseSelector": "article.news-item",
+ "fields": [
+ {
+ "name": "title",
+ "selector": "h1",
+ "type": "text",
+ "transform": "strip"
+ },
+ {
+ "name": "date",
+ "selector": ".date",
+ "type": "attribute",
+ "attribute": "datetime"
+ }
+ ]
+}
+
+strategy = JsonCssExtractionStrategy(schema)
+result = await crawler.arun(url="https://example.com", extraction_strategy=strategy)
+```
+
+#### 3. CosineStrategy
+```python
+CosineStrategy(
+ # Content Filtering
+ semantic_filter: str = None, # Keyword filter for document filtering
+ word_count_threshold: int = 10, # Minimum words per cluster
+ sim_threshold: float = 0.3, # Similarity threshold for filtering
+
+ # Clustering Parameters
+ max_dist: float = 0.2, # Maximum distance for clustering
+ linkage_method: str = 'ward', # Clustering linkage method
+ top_k: int = 3, # Number of top categories to extract
+
+ # Model Configuration
+ model_name: str = 'sentence-transformers/all-MiniLM-L6-v2', # Embedding model
+
+ verbose: bool = False # Enable verbose logging
+)
+```
+
+### Chunking Strategies
+
+#### 1. RegexChunking
+```python
+RegexChunking(
+ patterns: List[str] = None # List of regex patterns for splitting text
+ # Default pattern: [r'\n\n']
+)
+```
+
+Usage Example:
+```python
+chunker = RegexChunking(patterns=[r'\n\n', r'\.\s+']) # Split on double newlines and sentences
+chunks = chunker.chunk(text)
+```
+
+#### 2. SlidingWindowChunking
+```python
+SlidingWindowChunking(
+ window_size: int = 100, # Size of the window in words
+ step: int = 50, # Number of words to slide the window
+)
+```
+
+Usage Example:
+```python
+chunker = SlidingWindowChunking(window_size=200, step=100)
+chunks = chunker.chunk(text) # Creates overlapping chunks of 200 words, moving 100 words at a time
+```
+
+#### 3. OverlappingWindowChunking
+```python
+OverlappingWindowChunking(
+ window_size: int = 1000, # Size of each chunk in words
+ overlap: int = 100 # Number of words to overlap between chunks
+)
+```
+
+Usage Example:
+```python
+chunker = OverlappingWindowChunking(window_size=500, overlap=50)
+chunks = chunker.chunk(text) # Creates 500-word chunks with 50-word overlap
+```
diff --git a/docs/details/feature_lists.md b/docs/details/feature_lists.md
new file mode 100644
index 00000000..5dc2ad74
--- /dev/null
+++ b/docs/details/feature_lists.md
@@ -0,0 +1,175 @@
+# Features
+
+## Current Features
+1. Async-first architecture for high-performance web crawling
+2. Built-in anti-bot detection bypass ("magic mode")
+3. Multiple browser engine support (Chromium, Firefox, WebKit)
+4. Smart session management with automatic cleanup
+5. Automatic content cleaning and relevance scoring
+6. Built-in markdown generation with formatting preservation
+7. Intelligent image scoring and filtering
+8. Automatic popup and overlay removal
+9. Smart wait conditions (CSS/JavaScript based)
+10. Multi-provider LLM integration (OpenAI, HuggingFace, Ollama)
+11. Schema-based structured data extraction
+12. Automated iframe content processing
+13. Intelligent link categorization (internal/external)
+14. Multiple chunking strategies for large content
+15. Real-time HTML cleaning and sanitization
+16. Automatic screenshot capabilities
+17. Social media link filtering
+18. Semantic similarity-based content clustering
+19. Human behavior simulation for anti-bot bypass
+20. Proxy support with authentication
+21. Automatic resource cleanup
+22. Custom CSS selector-based extraction
+23. Automatic content relevance scoring ("fit" content)
+24. Recursive website crawling capabilities
+25. Flexible hook system for customization
+26. Built-in caching system
+27. Domain-based content filtering
+28. Dynamic content handling with JavaScript execution
+29. Automatic media content extraction and classification
+30. Metadata extraction and processing
+31. Customizable HTML to Markdown conversion
+32. Token-aware content chunking for LLM processing
+33. Automatic response header and status code handling
+34. Browser fingerprint customization
+35. Multiple extraction strategies (LLM, CSS, Cosine, XPATH)
+36. Automatic error image generation for failed screenshots
+37. Smart content overlap handling for large texts
+38. Built-in rate limiting for batch processing
+39. Automatic cookie handling
+40. Browser Console logging and debugging capabilities
+
+## Feature Techs
+β’ Browser Management
+ - Asynchronous browser control
+ - Multi-browser support (Chromium, Firefox, WebKit)
+ - Headless mode support
+ - Browser cleanup and resource management
+ - Custom browser arguments and configuration
+ - Context management with `__aenter__` and `__aexit__`
+
+β’ Session Handling
+ - Session management with TTL (Time To Live)
+ - Session reuse capabilities
+ - Session cleanup for expired sessions
+ - Session-based context preservation
+
+β’ Stealth Features
+ - Playwright stealth configuration
+ - Navigator properties override
+ - WebDriver detection evasion
+ - Chrome app simulation
+ - Plugin simulation
+ - Language preferences simulation
+ - Hardware concurrency simulation
+ - Media codecs simulation
+
+β’ Network Features
+ - Proxy support with authentication
+ - Custom headers management
+ - Cookie handling
+ - Response header capture
+ - Status code tracking
+ - Network idle detection
+
+β’ Page Interaction
+ - Smart wait functionality for multiple conditions
+ - CSS selector-based waiting
+ - JavaScript condition waiting
+ - Custom JavaScript execution
+ - User interaction simulation (mouse/keyboard)
+ - Page scrolling
+ - Timeout management
+ - Load state monitoring
+
+β’ Content Processing
+ - HTML content extraction
+ - Iframe processing and content extraction
+ - Delayed content retrieval
+ - Content caching
+ - Cache file management
+ - HTML cleaning and processing
+
+β’ Image Handling
+ - Screenshot capabilities (full page)
+ - Base64 encoding of screenshots
+ - Image dimension updating
+ - Image filtering (size/visibility)
+ - Error image generation
+ - Natural width/height preservation
+
+β’ Overlay Management
+ - Popup removal
+ - Cookie notice removal
+ - Newsletter dialog removal
+ - Modal removal
+ - Fixed position element removal
+ - Z-index based overlay detection
+ - Visibility checking
+
+β’ Hook System
+ - Browser creation hooks
+ - User agent update hooks
+ - Execution start hooks
+ - Navigation hooks (before/after goto)
+ - HTML retrieval hooks
+ - HTML return hooks
+
+β’ Error Handling
+ - Browser error catching
+ - Network error handling
+ - Timeout handling
+ - Screenshot error recovery
+ - Invalid selector handling
+ - General exception management
+
+β’ Performance Features
+ - Concurrent URL processing
+ - Semaphore-based rate limiting
+ - Async gathering of results
+ - Resource cleanup
+ - Memory management
+
+β’ Debug Features
+ - Console logging
+ - Page error logging
+ - Verbose mode
+ - Error message generation
+ - Warning system
+
+β’ Security Features
+ - Certificate error handling
+ - Sandbox configuration
+ - GPU handling
+ - CSP (Content Security Policy) compliant waiting
+
+β’ Configuration
+ - User agent customization
+ - Viewport configuration
+ - Timeout configuration
+ - Browser type selection
+ - Proxy configuration
+ - Header configuration
+
+β’ Data Models
+ - Pydantic model for responses
+ - Type hints throughout code
+ - Structured response format
+ - Optional response fields
+
+β’ File System Integration
+ - Cache directory management
+ - File path handling
+ - Cache metadata storage
+ - File read/write operations
+
+β’ Metadata Handling
+ - Response headers capture
+ - Status code tracking
+ - Cache metadata
+ - Session tracking
+ - Timestamp management
+
diff --git a/docs/details/features.md b/docs/details/features.md
new file mode 100644
index 00000000..8ed027c2
--- /dev/null
+++ b/docs/details/features.md
@@ -0,0 +1,150 @@
+### 1. Basic Web Crawling
+```python
+async with AsyncWebCrawler() as crawler:
+ result = await crawler.arun(url="https://example.com")
+ print(result.markdown) # Get clean markdown content
+ print(result.html) # Get raw HTML
+ print(result.cleaned_html) # Get cleaned HTML
+```
+
+### 2. Browser Control Options
+- Multiple Browser Support
+```python
+# Choose between different browser engines
+crawler = AsyncWebCrawler(browser_type="firefox") # or "chromium", "webkit"
+crawler = AsyncWebCrawler(headless=False) # For visible browser
+```
+
+- Proxy Configuration
+```python
+crawler = AsyncWebCrawler(proxy="http://proxy.example.com:8080")
+# Or with authentication
+crawler = AsyncWebCrawler(proxy_config={
+ "server": "http://proxy.example.com:8080",
+ "username": "user",
+ "password": "pass"
+})
+```
+
+### 3. Content Selection & Filtering
+- CSS Selector Support
+```python
+result = await crawler.arun(
+ url="https://example.com",
+ css_selector=".main-content" # Extract specific content
+)
+```
+
+- Content Filtering Options
+```python
+result = await crawler.arun(
+ url="https://example.com",
+ word_count_threshold=10, # Minimum words per block
+ excluded_tags=['form', 'header'], # Tags to exclude
+ exclude_external_links=True, # Remove external links
+ exclude_social_media_links=True, # Remove social media links
+ exclude_external_images=True # Remove external images
+)
+```
+
+### 4. Dynamic Content Handling
+- JavaScript Execution
+```python
+result = await crawler.arun(
+ url="https://example.com",
+ js_code="window.scrollTo(0, document.body.scrollHeight)" # Execute custom JS
+)
+```
+
+- Wait Conditions
+```python
+result = await crawler.arun(
+ url="https://example.com",
+ wait_for="css:.my-element", # Wait for element
+ wait_for="js:() => document.readyState === 'complete'" # Wait for condition
+)
+```
+
+### 5. Anti-Bot Protection Handling
+```python
+result = await crawler.arun(
+ url="https://example.com",
+ simulate_user=True, # Simulate human behavior
+ override_navigator=True, # Mask automation signals
+ magic=True # Enable all anti-detection features
+)
+```
+
+### 6. Session Management
+```python
+session_id = "my_session"
+result1 = await crawler.arun(url="https://example.com/page1", session_id=session_id)
+result2 = await crawler.arun(url="https://example.com/page2", session_id=session_id)
+await crawler.crawler_strategy.kill_session(session_id)
+```
+
+### 7. Media Handling
+- Screenshot Capture
+```python
+result = await crawler.arun(
+ url="https://example.com",
+ screenshot=True
+)
+base64_screenshot = result.screenshot
+```
+
+- Media Extraction
+```python
+result = await crawler.arun(url="https://example.com")
+print(result.media['images']) # List of images
+print(result.media['videos']) # List of videos
+print(result.media['audios']) # List of audio files
+```
+
+### 8. Structured Data Extraction
+- CSS-based Extraction
+```python
+schema = {
+ "name": "News Articles",
+ "baseSelector": "article",
+ "fields": [
+ {"name": "title", "selector": "h1", "type": "text"},
+ {"name": "date", "selector": ".date", "type": "text"}
+ ]
+}
+extraction_strategy = JsonCssExtractionStrategy(schema)
+result = await crawler.arun(
+ url="https://example.com",
+ extraction_strategy=extraction_strategy
+)
+structured_data = json.loads(result.extracted_content)
+```
+
+- LLM-based Extraction (Multiple Providers)
+```python
+class NewsArticle(BaseModel):
+ title: str
+ summary: str
+
+strategy = LLMExtractionStrategy(
+ provider="ollama/nemotron", # or "huggingface/...", "ollama/..."
+ api_token="your-token",
+ schema=NewsArticle.schema(),
+ instruction="Extract news article details..."
+)
+result = await crawler.arun(
+ url="https://example.com",
+ extraction_strategy=strategy
+)
+```
+
+### 9. Content Cleaning & Processing
+```python
+result = await crawler.arun(
+ url="https://example.com",
+ remove_overlay_elements=True, # Remove popups/modals
+ process_iframes=True, # Process iframe content
+)
+print(result.fit_markdown) # Get most relevant content
+print(result.fit_html) # Get cleaned HTML
+```
diff --git a/docs/details/features_details.md b/docs/details/features_details.md
new file mode 100644
index 00000000..ffc6c21c
--- /dev/null
+++ b/docs/details/features_details.md
@@ -0,0 +1,457 @@
+I'll expand the outline with detailed descriptions and examples based on all the provided files. I'll start with the first few sections:
+
+### 1. Basic Web Crawling
+Basic web crawling provides the foundation for extracting content from websites. The library supports both simple single-page crawling and recursive website crawling.
+
+```python
+# Simple page crawling
+async with AsyncWebCrawler() as crawler:
+ result = await crawler.arun(url="https://example.com")
+ print(result.html) # Raw HTML
+ print(result.markdown) # Cleaned markdown
+ print(result.cleaned_html) # Cleaned HTML
+
+# Recursive website crawling
+class SimpleWebsiteScraper:
+ def __init__(self, crawler: AsyncWebCrawler):
+ self.crawler = crawler
+
+ async def scrape(self, start_url: str, max_depth: int):
+ results = await self.scrape_recursive(start_url, max_depth)
+ return results
+
+# Usage
+async with AsyncWebCrawler() as crawler:
+ scraper = SimpleWebsiteScraper(crawler)
+ results = await scraper.scrape("https://example.com", depth=2)
+```
+
+### 2. Browser Control Options
+The library provides extensive control over browser behavior, allowing customization of browser type, headless mode, and proxy settings.
+
+```python
+# Browser Type Selection
+async with AsyncWebCrawler(
+ browser_type="firefox", # Options: "chromium", "firefox", "webkit"
+ headless=False, # For visible browser
+ verbose=True # Enable logging
+) as crawler:
+ result = await crawler.arun(url="https://example.com")
+
+# Proxy Configuration
+async with AsyncWebCrawler(
+ proxy_config={
+ "server": "http://proxy.example.com:8080",
+ "username": "user",
+ "password": "pass"
+ },
+ headers={
+ "User-Agent": "Custom User Agent",
+ "Accept-Language": "en-US,en;q=0.9"
+ }
+) as crawler:
+ result = await crawler.arun(url="https://example.com")
+```
+
+### 3. Content Selection & Filtering
+The library offers multiple ways to select and filter content, from CSS selectors to word count thresholds.
+
+```python
+# CSS Selector and Content Filtering
+async with AsyncWebCrawler() as crawler:
+ result = await crawler.arun(
+ url="https://example.com",
+ css_selector="article.main-content", # Extract specific content
+ word_count_threshold=10, # Minimum words per block
+ excluded_tags=['form', 'header'], # Tags to exclude
+ exclude_external_links=True, # Remove external links
+ exclude_social_media_links=True, # Remove social media links
+ exclude_domains=["pinterest.com", "facebook.com"] # Exclude specific domains
+ )
+
+# Custom HTML to Text Options
+async with AsyncWebCrawler() as crawler:
+ result = await crawler.arun(
+ url="https://example.com",
+ html2text={
+ "escape_dot": False,
+ "links_each_paragraph": True,
+ "protect_links": True
+ }
+ )
+```
+
+### 4. Dynamic Content Handling
+The library provides sophisticated handling of dynamic content with JavaScript execution and wait conditions.
+
+```python
+# JavaScript Execution and Wait Conditions
+async with AsyncWebCrawler() as crawler:
+ result = await crawler.arun(
+ url="https://example.com",
+ js_code=[
+ "window.scrollTo(0, document.body.scrollHeight);",
+ "document.querySelector('.load-more').click();"
+ ],
+ wait_for="css:.dynamic-content", # Wait for element
+ delay_before_return_html=2.0 # Wait after JS execution
+ )
+
+# Smart Wait Conditions
+async with AsyncWebCrawler() as crawler:
+ result = await crawler.arun(
+ url="https://example.com",
+ wait_for="""() => {
+ return document.querySelectorAll('.item').length > 10;
+ }""",
+ page_timeout=60000 # 60 seconds timeout
+ )
+```
+
+### 5. Advanced Link Analysis
+The library provides comprehensive link analysis capabilities, distinguishing between internal and external links, with options for filtering and processing.
+
+```python
+# Basic Link Analysis
+async with AsyncWebCrawler() as crawler:
+ result = await crawler.arun(url="https://example.com")
+
+ # Access internal and external links
+ for internal_link in result.links['internal']:
+ print(f"Internal: {internal_link['href']} - {internal_link['text']}")
+
+ for external_link in result.links['external']:
+ print(f"External: {external_link['href']} - {external_link['text']}")
+
+# Advanced Link Filtering
+async with AsyncWebCrawler() as crawler:
+ result = await crawler.arun(
+ url="https://example.com",
+ exclude_external_links=True, # Remove all external links
+ exclude_social_media_links=True, # Remove social media links
+ exclude_social_media_domains=[ # Custom social media domains
+ "facebook.com", "twitter.com", "instagram.com"
+ ],
+ exclude_domains=["pinterest.com"] # Specific domains to exclude
+ )
+```
+
+### 6. Anti-Bot Protection Handling
+The library includes sophisticated anti-detection mechanisms to handle websites with bot protection.
+
+```python
+# Basic Anti-Detection
+async with AsyncWebCrawler() as crawler:
+ result = await crawler.arun(
+ url="https://example.com",
+ simulate_user=True, # Simulate human behavior
+ override_navigator=True # Override navigator properties
+ )
+
+# Advanced Anti-Detection with Magic Mode
+async with AsyncWebCrawler(headless=False) as crawler:
+ result = await crawler.arun(
+ url="https://example.com",
+ magic=True, # Enable all anti-detection features
+ remove_overlay_elements=True, # Remove popups/modals automatically
+ # Custom navigator properties
+ js_code="""
+ Object.defineProperty(navigator, 'webdriver', {
+ get: () => undefined
+ });
+ """
+ )
+```
+
+### 7. Session Management
+Session management allows maintaining state across multiple requests and handling cookies.
+
+```python
+# Basic Session Management
+async with AsyncWebCrawler() as crawler:
+ session_id = "my_session"
+
+ # Login
+ login_result = await crawler.arun(
+ url="https://example.com/login",
+ session_id=session_id,
+ js_code="document.querySelector('form').submit();"
+ )
+
+ # Use same session for subsequent requests
+ protected_result = await crawler.arun(
+ url="https://example.com/protected",
+ session_id=session_id
+ )
+
+ # Clean up session
+ await crawler.crawler_strategy.kill_session(session_id)
+
+# Advanced Session with Custom Cookies
+async with AsyncWebCrawler() as crawler:
+ result = await crawler.arun(
+ url="https://example.com",
+ session_id="custom_session",
+ cookies=[{
+ "name": "sessionId",
+ "value": "abc123",
+ "domain": "example.com"
+ }]
+ )
+```
+
+### 8. Screenshot and Media Handling
+The library provides comprehensive media handling capabilities, including screenshots and media content extraction.
+
+```python
+# Screenshot Capture
+async with AsyncWebCrawler() as crawler:
+ result = await crawler.arun(
+ url="https://example.com",
+ screenshot=True,
+ screenshot_wait_for=2.0 # Wait before taking screenshot
+ )
+
+ # Save screenshot
+ if result.screenshot:
+ with open("screenshot.png", "wb") as f:
+ f.write(base64.b64decode(result.screenshot))
+
+# Media Extraction
+async with AsyncWebCrawler() as crawler:
+ result = await crawler.arun(url="https://example.com")
+
+ # Process images with metadata
+ for image in result.media['images']:
+ print(f"Image: {image['src']}")
+ print(f"Alt text: {image['alt']}")
+ print(f"Context: {image['desc']}")
+ print(f"Relevance score: {image['score']}")
+
+ # Process videos and audio
+ for video in result.media['videos']:
+ print(f"Video: {video['src']}")
+ for audio in result.media['audios']:
+ print(f"Audio: {audio['src']}")
+```
+
+### 9. Structured Data Extraction & Chunking
+The library supports multiple strategies for structured data extraction and content chunking.
+
+```python
+# LLM-based Extraction
+class NewsArticle(BaseModel):
+ title: str
+ content: str
+ author: str
+
+extraction_strategy = LLMExtractionStrategy(
+ provider='openai/gpt-4',
+ api_token="your-token",
+ schema=NewsArticle.schema(),
+ instruction="Extract news article details",
+ chunk_token_threshold=1000,
+ overlap_rate=0.1
+)
+
+# CSS-based Extraction
+schema = {
+ "name": "Product Listing",
+ "baseSelector": ".product-card",
+ "fields": [
+ {
+ "name": "title",
+ "selector": "h2",
+ "type": "text"
+ },
+ {
+ "name": "price",
+ "selector": ".price",
+ "type": "text",
+ "transform": "strip"
+ }
+ ]
+}
+
+css_strategy = JsonCssExtractionStrategy(schema)
+
+# Text Chunking
+from crawl4ai.chunking_strategy import OverlappingWindowChunking
+
+chunking_strategy = OverlappingWindowChunking(
+ window_size=1000,
+ overlap=100
+)
+
+async with AsyncWebCrawler() as crawler:
+ result = await crawler.arun(
+ url="https://example.com",
+ extraction_strategy=extraction_strategy,
+ chunking_strategy=chunking_strategy
+ )
+```
+
+
+### 10. Content Cleaning & Processing
+The library provides extensive content cleaning and processing capabilities, ensuring high-quality output in various formats.
+
+```python
+# Basic Content Cleaning
+async with AsyncWebCrawler() as crawler:
+ result = await crawler.arun(
+ url="https://example.com",
+ remove_overlay_elements=True, # Remove popups/modals
+ process_iframes=True, # Process iframe content
+ word_count_threshold=10 # Minimum words per block
+ )
+
+ print(result.cleaned_html) # Clean HTML
+ print(result.fit_html) # Most relevant HTML content
+ print(result.fit_markdown) # Most relevant markdown content
+
+# Advanced Content Processing
+async with AsyncWebCrawler() as crawler:
+ result = await crawler.arun(
+ url="https://example.com",
+ excluded_tags=['form', 'header', 'footer', 'nav'],
+ html2text={
+ "escape_dot": False,
+ "body_width": 0,
+ "protect_links": True,
+ "unicode_snob": True,
+ "ignore_links": False,
+ "ignore_images": False,
+ "ignore_emphasis": False,
+ "bypass_tables": False,
+ "ignore_tables": False
+ }
+ )
+```
+
+### Advanced Usage Patterns
+
+#### 1. Combining Multiple Features
+```python
+async with AsyncWebCrawler(
+ browser_type="chromium",
+ headless=False,
+ verbose=True
+) as crawler:
+ result = await crawler.arun(
+ url="https://example.com",
+ # Anti-bot measures
+ magic=True,
+ simulate_user=True,
+
+ # Content selection
+ css_selector="article.main",
+ word_count_threshold=10,
+
+ # Dynamic content handling
+ js_code="window.scrollTo(0, document.body.scrollHeight);",
+ wait_for="css:.dynamic-content",
+
+ # Content filtering
+ exclude_external_links=True,
+ exclude_social_media_links=True,
+
+ # Media handling
+ screenshot=True,
+ process_iframes=True,
+
+ # Content cleaning
+ remove_overlay_elements=True
+ )
+```
+
+#### 2. Custom Extraction Pipeline
+```python
+# Define custom schemas and strategies
+class Article(BaseModel):
+ title: str
+ content: str
+ date: str
+
+# CSS extraction for initial content
+css_schema = {
+ "name": "Article Extraction",
+ "baseSelector": "article",
+ "fields": [
+ {"name": "title", "selector": "h1", "type": "text"},
+ {"name": "content", "selector": ".content", "type": "html"},
+ {"name": "date", "selector": ".date", "type": "text"}
+ ]
+}
+
+# LLM processing for semantic analysis
+llm_strategy = LLMExtractionStrategy(
+ provider="ollama/nemotron",
+ api_token="your-token",
+ schema=Article.schema(),
+ instruction="Extract and clean article content"
+)
+
+# Chunking strategy for large content
+chunking = OverlappingWindowChunking(window_size=1000, overlap=100)
+
+async with AsyncWebCrawler() as crawler:
+ # First pass: Extract structure
+ css_result = await crawler.arun(
+ url="https://example.com",
+ extraction_strategy=JsonCssExtractionStrategy(css_schema)
+ )
+
+ # Second pass: Semantic processing
+ llm_result = await crawler.arun(
+ url="https://example.com",
+ extraction_strategy=llm_strategy,
+ chunking_strategy=chunking
+ )
+```
+
+#### 3. Website Crawling with Custom Processing
+```python
+class CustomWebsiteCrawler:
+ def __init__(self, crawler: AsyncWebCrawler):
+ self.crawler = crawler
+ self.results = {}
+
+ async def process_page(self, url: str) -> Dict:
+ result = await self.crawler.arun(
+ url=url,
+ magic=True,
+ word_count_threshold=10,
+ exclude_external_links=True,
+ process_iframes=True,
+ remove_overlay_elements=True
+ )
+
+ # Process internal links
+ internal_links = [
+ link['href'] for link in result.links['internal']
+ if self._is_valid_link(link['href'])
+ ]
+
+ # Extract media
+ media_urls = [img['src'] for img in result.media['images']]
+
+ return {
+ 'content': result.markdown,
+ 'links': internal_links,
+ 'media': media_urls,
+ 'metadata': result.metadata
+ }
+
+ async def crawl_website(self, start_url: str, max_depth: int = 2):
+ visited = set()
+ queue = [(start_url, 0)]
+
+ while queue:
+ url, depth = queue.pop(0)
+ if depth > max_depth or url in visited:
+ continue
+
+ visited.add(url)
+ self.results[url] = await self.process_page(url)
+```
+
diff --git a/docs/details/input_output.md b/docs/details/input_output.md
new file mode 100644
index 00000000..b735e34f
--- /dev/null
+++ b/docs/details/input_output.md
@@ -0,0 +1,282 @@
+### AsyncWebCrawler Constructor Parameters
+```python
+AsyncWebCrawler(
+ # Core Browser Settings
+ browser_type: str = "chromium", # Options: "chromium", "firefox", "webkit"
+ headless: bool = True, # Whether to run browser in headless mode
+ verbose: bool = False, # Enable verbose logging
+
+ # Cache Settings
+ always_by_pass_cache: bool = False, # Always bypass cache regardless of run settings
+ base_directory: str = str(Path.home()), # Base directory for cache storage
+
+ # Network Settings
+ proxy: str = None, # Simple proxy URL (e.g., "http://proxy.example.com:8080")
+ proxy_config: Dict = None, # Advanced proxy settings with auth: {"server": str, "username": str, "password": str}
+
+ # Browser Behavior
+ sleep_on_close: bool = False, # Wait before closing browser
+
+ # Other Settings passed to AsyncPlaywrightCrawlerStrategy
+ user_agent: str = None, # Custom user agent string
+ headers: Dict[str, str] = {}, # Custom HTTP headers
+ js_code: Union[str, List[str]] = None, # Default JavaScript to execute
+)
+```
+
+### arun() Method Parameters
+```python
+arun(
+ # Core Parameters
+ url: str, # Required: URL to crawl
+
+ # Content Selection
+ css_selector: str = None, # CSS selector to extract specific content
+ word_count_threshold: int = MIN_WORD_THRESHOLD, # Minimum words for content blocks
+
+ # Cache Control
+ bypass_cache: bool = False, # Bypass cache for this request
+
+ # Session Management
+ session_id: str = None, # Session identifier for persistent browsing
+
+ # Screenshot Options
+ screenshot: bool = False, # Take page screenshot
+ screenshot_wait_for: float = None, # Wait time before screenshot
+
+ # Content Processing
+ process_iframes: bool = False, # Process iframe content
+ remove_overlay_elements: bool = False, # Remove popups/modals
+
+ # Anti-Bot/Detection
+ simulate_user: bool = False, # Simulate human-like behavior
+ override_navigator: bool = False, # Override navigator properties
+ magic: bool = False, # Enable all anti-detection features
+
+ # Content Filtering
+ excluded_tags: List[str] = None, # HTML tags to exclude
+ exclude_external_links: bool = False, # Remove external links
+ exclude_social_media_links: bool = False, # Remove social media links
+ exclude_external_images: bool = False, # Remove external images
+ exclude_social_media_domains: List[str] = None, # Additional social media domains to exclude
+ remove_forms: bool = False, # Remove all form elements
+
+ # JavaScript Handling
+ js_code: Union[str, List[str]] = None, # JavaScript to execute
+ js_only: bool = False, # Only execute JavaScript without reloading page
+ wait_for: str = None, # Wait condition (CSS selector or JS function)
+
+ # Page Loading
+ page_timeout: int = 60000, # Page load timeout in milliseconds
+ delay_before_return_html: float = None, # Wait before returning HTML
+
+ # Debug Options
+ log_console: bool = False, # Log browser console messages
+
+ # Content Format Control
+ only_text: bool = False, # Extract only text content
+ keep_data_attributes: bool = False, # Keep data-* attributes in HTML
+
+ # Markdown Options
+ include_links_on_markdown: bool = False, # Include links in markdown output
+ html2text: Dict = {}, # HTML to text conversion options
+
+ # Extraction Strategy
+ extraction_strategy: ExtractionStrategy = None, # Strategy for structured data extraction
+
+ # Advanced Browser Control
+ user_agent: str = None, # Override user agent for this request
+)
+```
+
+### Extraction Strategy Parameters
+```python
+# JsonCssExtractionStrategy
+{
+ "name": str, # Name of extraction schema
+ "baseSelector": str, # Base CSS selector
+ "fields": [
+ {
+ "name": str, # Field name
+ "selector": str, # CSS selector
+ "type": str, # Data type ("text", etc.)
+ "transform": str = None # Optional transformation
+ }
+ ]
+}
+
+# LLMExtractionStrategy
+{
+ "provider": str, # LLM provider (e.g., "openai/gpt-4", "huggingface/...", "ollama/...")
+ "api_token": str, # API token
+ "schema": dict, # Pydantic model schema
+ "extraction_type": str, # Type of extraction ("schema", etc.)
+ "instruction": str, # Extraction instruction
+ "extra_args": dict = None, # Additional provider-specific arguments
+ "extra_headers": dict = None # Additional HTTP headers
+}
+```
+
+### HTML to Text Conversion Options (html2text parameter)
+```python
+{
+ "escape_dot": bool = True, # Escape dots in text
+ # Other html2text library options
+}
+```
+
+
+### CrawlResult Fields
+
+```python
+class CrawlResult(BaseModel):
+ # Basic Information
+ url: str # The crawled URL
+ # Example: "https://example.com"
+
+ success: bool # Whether the crawl was successful
+ # Example: True/False
+
+ status_code: Optional[int] # HTTP status code
+ # Example: 200, 404, 500
+
+ # Content Fields
+ html: str # Raw HTML content
+ # Example: "
..."
+
+ cleaned_html: Optional[str] # HTML after cleaning and processing
+ # Example: "Clean content...
"
+
+ fit_html: Optional[str] # Most relevant HTML content after content cleaning strategy
+ # Example: ""
+
+ markdown: Optional[str] # HTML converted to markdown
+ # Example: "# Title\n\nContent paragraph..."
+
+ fit_markdown: Optional[str] # Most relevant content in markdown
+ # Example: "# Main Article\n\nKey content..."
+
+ # Media Content
+ media: Dict[str, List[Dict]] = {} # Extracted media information
+ # Example: {
+ # "images": [
+ # {
+ # "src": "https://example.com/image.jpg",
+ # "alt": "Image description",
+ # "desc": "Contextual description",
+ # "score": 5, # Relevance score
+ # "type": "image"
+ # }
+ # ],
+ # "videos": [
+ # {
+ # "src": "https://example.com/video.mp4",
+ # "alt": "Video title",
+ # "type": "video",
+ # "description": "Video context"
+ # }
+ # ],
+ # "audios": [
+ # {
+ # "src": "https://example.com/audio.mp3",
+ # "alt": "Audio title",
+ # "type": "audio",
+ # "description": "Audio context"
+ # }
+ # ]
+ # }
+
+ # Link Information
+ links: Dict[str, List[Dict]] = {} # Extracted links
+ # Example: {
+ # "internal": [
+ # {
+ # "href": "https://example.com/page",
+ # "text": "Link text",
+ # "title": "Link title"
+ # }
+ # ],
+ # "external": [
+ # {
+ # "href": "https://external.com",
+ # "text": "External link text",
+ # "title": "External link title"
+ # }
+ # ]
+ # }
+
+ # Extraction Results
+ extracted_content: Optional[str] # Content from extraction strategy
+ # Example for JsonCssExtractionStrategy:
+ # '[{"title": "Article 1", "date": "2024-03-20"}, ...]'
+ # Example for LLMExtractionStrategy:
+ # '{"entities": [...], "relationships": [...]}'
+
+ # Additional Information
+ metadata: Optional[dict] = None # Page metadata
+ # Example: {
+ # "title": "Page Title",
+ # "description": "Meta description",
+ # "keywords": ["keyword1", "keyword2"],
+ # "author": "Author Name",
+ # "published_date": "2024-03-20"
+ # }
+
+ screenshot: Optional[str] = None # Base64 encoded screenshot
+ # Example: "iVBORw0KGgoAAAANSUhEUgAA..."
+
+ error_message: Optional[str] = None # Error message if crawl failed
+ # Example: "Failed to load page: timeout"
+
+ session_id: Optional[str] = None # Session identifier
+ # Example: "session_123456"
+
+ response_headers: Optional[dict] = None # HTTP response headers
+ # Example: {
+ # "content-type": "text/html",
+ # "server": "nginx/1.18.0",
+ # "date": "Wed, 20 Mar 2024 12:00:00 GMT"
+ # }
+```
+
+### Common Usage Patterns:
+
+1. Basic Content Extraction:
+```python
+result = await crawler.arun(url="https://example.com")
+print(result.markdown) # Clean, readable content
+print(result.cleaned_html) # Cleaned HTML
+```
+
+2. Media Analysis:
+```python
+result = await crawler.arun(url="https://example.com")
+for image in result.media["images"]:
+ if image["score"] > 3: # High-relevance images
+ print(f"High-quality image: {image['src']}")
+```
+
+3. Link Analysis:
+```python
+result = await crawler.arun(url="https://example.com")
+internal_links = [link["href"] for link in result.links["internal"]]
+external_links = [link["href"] for link in result.links["external"]]
+```
+
+4. Structured Data Extraction:
+```python
+result = await crawler.arun(
+ url="https://example.com",
+ extraction_strategy=my_strategy
+)
+structured_data = json.loads(result.extracted_content)
+```
+
+5. Error Handling:
+```python
+result = await crawler.arun(url="https://example.com")
+if not result.success:
+ print(f"Crawl failed: {result.error_message}")
+ print(f"Status code: {result.status_code}")
+```
+
diff --git a/docs/details/realworld_examples.md b/docs/details/realworld_examples.md
new file mode 100644
index 00000000..d6613147
--- /dev/null
+++ b/docs/details/realworld_examples.md
@@ -0,0 +1,67 @@
+1. **E-commerce Product Monitor**
+ - Scraping product details from multiple e-commerce sites
+ - Price tracking with structured data extraction
+ - Handling dynamic content and anti-bot measures
+ - Features: JsonCssExtraction, session management, anti-bot
+
+2. **News Aggregator & Summarizer**
+ - Crawling news websites
+ - Content extraction and summarization
+ - Topic classification
+ - Features: LLMExtraction, CosineStrategy, content cleaning
+
+3. **Academic Paper Research Assistant**
+ - Crawling research papers from academic sites
+ - Extracting citations and references
+ - Building knowledge graphs
+ - Features: structured extraction, link analysis, chunking
+
+4. **Social Media Content Analyzer**
+ - Handling JavaScript-heavy sites
+ - Dynamic content loading
+ - Sentiment analysis integration
+ - Features: dynamic content handling, session management
+
+5. **Real Estate Market Analyzer**
+ - Scraping property listings
+ - Processing image galleries
+ - Geolocation data extraction
+ - Features: media handling, structured data extraction
+
+6. **Documentation Site Generator**
+ - Recursive website crawling
+ - Markdown generation
+ - Link validation
+ - Features: website crawling, content cleaning
+
+7. **Job Board Aggregator**
+ - Handling pagination
+ - Structured job data extraction
+ - Filtering and categorization
+ - Features: session management, JsonCssExtraction
+
+8. **Recipe Database Builder**
+ - Schema-based extraction
+ - Image processing
+ - Ingredient parsing
+ - Features: structured extraction, media handling
+
+9. **Travel Blog Content Analyzer**
+ - Location extraction
+ - Image and map processing
+ - Content categorization
+ - Features: CosineStrategy, media handling
+
+10. **Technical Documentation Scraper**
+ - API documentation extraction
+ - Code snippet processing
+ - Version tracking
+ - Features: content cleaning, structured extraction
+
+Each example will include:
+- Problem description
+- Technical requirements
+- Complete implementation
+- Error handling
+- Output processing
+- Performance considerations
\ No newline at end of file
diff --git a/docs/examples/quickstart_async.py b/docs/examples/quickstart_async.py
index 9b88b332..02b5f8bb 100644
--- a/docs/examples/quickstart_async.py
+++ b/docs/examples/quickstart_async.py
@@ -456,7 +456,6 @@ async def speed_comparison():
print("If you run these tests in an environment with better network conditions,")
print("you may observe an even more significant speed advantage for Crawl4AI.")
-
async def generate_knowledge_graph():
class Entity(BaseModel):
name: str
@@ -473,8 +472,8 @@ async def generate_knowledge_graph():
relationships: List[Relationship]
extraction_strategy = LLMExtractionStrategy(
- provider='openai/gpt-4o-mini',
- api_token=os.getenv('OPENAI_API_KEY'),
+ provider='openai/gpt-4o-mini', # Or any other provider, including Ollama and open source models
+ api_token=os.getenv('OPENAI_API_KEY'), # In case of Ollama just pass "no-token"
schema=KnowledgeGraph.model_json_schema(),
extraction_type="schema",
instruction="""Extract entities and relationships from the given text."""
@@ -491,6 +490,23 @@ async def generate_knowledge_graph():
with open(os.path.join(__location__, "kb.json"), "w") as f:
f.write(result.extracted_content)
+async def fit_markdown_remove_overlay():
+ async with AsyncWebCrawler(headless = False) as crawler:
+ url = "https://janineintheworld.com/places-to-visit-in-central-mexico"
+ result = await crawler.arun(
+ url=url,
+ bypass_cache=True,
+ word_count_threshold = 10,
+ remove_overlay_elements=True,
+ screenshot = True
+ )
+ # Save markdown to file
+ with open(os.path.join(__location__, "mexico_places.md"), "w") as f:
+ f.write(result.fit_markdown)
+
+ print("Done")
+
+
async def main():
await simple_crawl()
await simple_example_with_running_js_code()
diff --git a/docs/md _sync/api/core_classes_and_functions.md b/docs/md_v0/api/core_classes_and_functions.md
similarity index 100%
rename from docs/md _sync/api/core_classes_and_functions.md
rename to docs/md_v0/api/core_classes_and_functions.md
diff --git a/docs/md _sync/api/detailed_api_documentation.md b/docs/md_v0/api/detailed_api_documentation.md
similarity index 100%
rename from docs/md _sync/api/detailed_api_documentation.md
rename to docs/md_v0/api/detailed_api_documentation.md
diff --git a/docs/md _sync/assets/DankMono-Bold.woff2 b/docs/md_v0/assets/DankMono-Bold.woff2
similarity index 100%
rename from docs/md _sync/assets/DankMono-Bold.woff2
rename to docs/md_v0/assets/DankMono-Bold.woff2
diff --git a/docs/md _sync/assets/DankMono-Italic.woff2 b/docs/md_v0/assets/DankMono-Italic.woff2
similarity index 100%
rename from docs/md _sync/assets/DankMono-Italic.woff2
rename to docs/md_v0/assets/DankMono-Italic.woff2
diff --git a/docs/md _sync/assets/DankMono-Regular.woff2 b/docs/md_v0/assets/DankMono-Regular.woff2
similarity index 100%
rename from docs/md _sync/assets/DankMono-Regular.woff2
rename to docs/md_v0/assets/DankMono-Regular.woff2
diff --git a/docs/md _sync/assets/Monaco.woff b/docs/md_v0/assets/Monaco.woff
similarity index 100%
rename from docs/md _sync/assets/Monaco.woff
rename to docs/md_v0/assets/Monaco.woff
diff --git a/docs/md _sync/assets/dmvendor.css b/docs/md_v0/assets/dmvendor.css
similarity index 100%
rename from docs/md _sync/assets/dmvendor.css
rename to docs/md_v0/assets/dmvendor.css
diff --git a/docs/md _sync/assets/highlight.css b/docs/md_v0/assets/highlight.css
similarity index 100%
rename from docs/md _sync/assets/highlight.css
rename to docs/md_v0/assets/highlight.css
diff --git a/docs/md _sync/assets/highlight.min.js b/docs/md_v0/assets/highlight.min.js
similarity index 100%
rename from docs/md _sync/assets/highlight.min.js
rename to docs/md_v0/assets/highlight.min.js
diff --git a/docs/md _sync/assets/highlight_init.js b/docs/md_v0/assets/highlight_init.js
similarity index 100%
rename from docs/md _sync/assets/highlight_init.js
rename to docs/md_v0/assets/highlight_init.js
diff --git a/docs/md _sync/assets/styles.css b/docs/md_v0/assets/styles.css
similarity index 100%
rename from docs/md _sync/assets/styles.css
rename to docs/md_v0/assets/styles.css
diff --git a/docs/md _sync/changelog.md b/docs/md_v0/changelog.md
similarity index 100%
rename from docs/md _sync/changelog.md
rename to docs/md_v0/changelog.md
diff --git a/docs/chunking_strategies.json b/docs/md_v0/chunking_strategies.json
similarity index 100%
rename from docs/chunking_strategies.json
rename to docs/md_v0/chunking_strategies.json
diff --git a/docs/md _sync/contact.md b/docs/md_v0/contact.md
similarity index 100%
rename from docs/md _sync/contact.md
rename to docs/md_v0/contact.md
diff --git a/docs/md _sync/demo.md b/docs/md_v0/demo.md
similarity index 100%
rename from docs/md _sync/demo.md
rename to docs/md_v0/demo.md
diff --git a/docs/md _sync/examples/hooks_auth.md b/docs/md_v0/examples/hooks_auth.md
similarity index 100%
rename from docs/md _sync/examples/hooks_auth.md
rename to docs/md_v0/examples/hooks_auth.md
diff --git a/docs/md _sync/examples/index.md b/docs/md_v0/examples/index.md
similarity index 100%
rename from docs/md _sync/examples/index.md
rename to docs/md_v0/examples/index.md
diff --git a/docs/md _sync/examples/js_execution_css_filtering.md b/docs/md_v0/examples/js_execution_css_filtering.md
similarity index 100%
rename from docs/md _sync/examples/js_execution_css_filtering.md
rename to docs/md_v0/examples/js_execution_css_filtering.md
diff --git a/docs/md _sync/examples/llm_extraction.md b/docs/md_v0/examples/llm_extraction.md
similarity index 100%
rename from docs/md _sync/examples/llm_extraction.md
rename to docs/md_v0/examples/llm_extraction.md
diff --git a/docs/md _sync/examples/research_assistant.md b/docs/md_v0/examples/research_assistant.md
similarity index 100%
rename from docs/md _sync/examples/research_assistant.md
rename to docs/md_v0/examples/research_assistant.md
diff --git a/docs/md _sync/examples/summarization.md b/docs/md_v0/examples/summarization.md
similarity index 100%
rename from docs/md _sync/examples/summarization.md
rename to docs/md_v0/examples/summarization.md
diff --git a/docs/extraction_strategies.json b/docs/md_v0/extraction_strategies.json
similarity index 100%
rename from docs/extraction_strategies.json
rename to docs/md_v0/extraction_strategies.json
diff --git a/docs/md _sync/full_details/advanced_features.md b/docs/md_v0/full_details/advanced_features.md
similarity index 100%
rename from docs/md _sync/full_details/advanced_features.md
rename to docs/md_v0/full_details/advanced_features.md
diff --git a/docs/md _sync/full_details/chunking_strategies.md b/docs/md_v0/full_details/chunking_strategies.md
similarity index 100%
rename from docs/md _sync/full_details/chunking_strategies.md
rename to docs/md_v0/full_details/chunking_strategies.md
diff --git a/docs/md _sync/full_details/crawl_request_parameters.md b/docs/md_v0/full_details/crawl_request_parameters.md
similarity index 100%
rename from docs/md _sync/full_details/crawl_request_parameters.md
rename to docs/md_v0/full_details/crawl_request_parameters.md
diff --git a/docs/md _sync/full_details/crawl_result_class.md b/docs/md_v0/full_details/crawl_result_class.md
similarity index 100%
rename from docs/md _sync/full_details/crawl_result_class.md
rename to docs/md_v0/full_details/crawl_result_class.md
diff --git a/docs/md _sync/full_details/extraction_strategies.md b/docs/md_v0/full_details/extraction_strategies.md
similarity index 100%
rename from docs/md _sync/full_details/extraction_strategies.md
rename to docs/md_v0/full_details/extraction_strategies.md
diff --git a/docs/md _sync/index.md b/docs/md_v0/index.md
similarity index 100%
rename from docs/md _sync/index.md
rename to docs/md_v0/index.md
diff --git a/docs/md _sync/installation.md b/docs/md_v0/installation.md
similarity index 100%
rename from docs/md _sync/installation.md
rename to docs/md_v0/installation.md
diff --git a/docs/md _sync/interactive_content.html b/docs/md_v0/interactive_content.html
similarity index 100%
rename from docs/md _sync/interactive_content.html
rename to docs/md_v0/interactive_content.html
diff --git a/docs/md _sync/introduction.md b/docs/md_v0/introduction.md
similarity index 100%
rename from docs/md _sync/introduction.md
rename to docs/md_v0/introduction.md
diff --git a/docs/md _sync/quickstart.md b/docs/md_v0/quickstart.md
similarity index 100%
rename from docs/md _sync/quickstart.md
rename to docs/md_v0/quickstart.md
diff --git a/docs/md/api/core_classes_and_functions.md b/docs/md_v1/api/core_classes_and_functions.md
similarity index 100%
rename from docs/md/api/core_classes_and_functions.md
rename to docs/md_v1/api/core_classes_and_functions.md
diff --git a/docs/md/api/detailed_api_documentation.md b/docs/md_v1/api/detailed_api_documentation.md
similarity index 100%
rename from docs/md/api/detailed_api_documentation.md
rename to docs/md_v1/api/detailed_api_documentation.md
diff --git a/docs/md/assets/DankMono-Bold.woff2 b/docs/md_v1/assets/DankMono-Bold.woff2
similarity index 100%
rename from docs/md/assets/DankMono-Bold.woff2
rename to docs/md_v1/assets/DankMono-Bold.woff2
diff --git a/docs/md/assets/DankMono-Italic.woff2 b/docs/md_v1/assets/DankMono-Italic.woff2
similarity index 100%
rename from docs/md/assets/DankMono-Italic.woff2
rename to docs/md_v1/assets/DankMono-Italic.woff2
diff --git a/docs/md/assets/DankMono-Regular.woff2 b/docs/md_v1/assets/DankMono-Regular.woff2
similarity index 100%
rename from docs/md/assets/DankMono-Regular.woff2
rename to docs/md_v1/assets/DankMono-Regular.woff2
diff --git a/docs/md/assets/Monaco.woff b/docs/md_v1/assets/Monaco.woff
similarity index 100%
rename from docs/md/assets/Monaco.woff
rename to docs/md_v1/assets/Monaco.woff
diff --git a/docs/md/assets/dmvendor.css b/docs/md_v1/assets/dmvendor.css
similarity index 100%
rename from docs/md/assets/dmvendor.css
rename to docs/md_v1/assets/dmvendor.css
diff --git a/docs/md/assets/highlight.css b/docs/md_v1/assets/highlight.css
similarity index 100%
rename from docs/md/assets/highlight.css
rename to docs/md_v1/assets/highlight.css
diff --git a/docs/md/assets/highlight.min.js b/docs/md_v1/assets/highlight.min.js
similarity index 100%
rename from docs/md/assets/highlight.min.js
rename to docs/md_v1/assets/highlight.min.js
diff --git a/docs/md/assets/highlight_init.js b/docs/md_v1/assets/highlight_init.js
similarity index 100%
rename from docs/md/assets/highlight_init.js
rename to docs/md_v1/assets/highlight_init.js
diff --git a/docs/md/assets/styles.css b/docs/md_v1/assets/styles.css
similarity index 100%
rename from docs/md/assets/styles.css
rename to docs/md_v1/assets/styles.css
diff --git a/docs/md/changelog.md b/docs/md_v1/changelog.md
similarity index 100%
rename from docs/md/changelog.md
rename to docs/md_v1/changelog.md
diff --git a/docs/md/contact.md b/docs/md_v1/contact.md
similarity index 100%
rename from docs/md/contact.md
rename to docs/md_v1/contact.md
diff --git a/docs/md/demo.md b/docs/md_v1/demo.md
similarity index 100%
rename from docs/md/demo.md
rename to docs/md_v1/demo.md
diff --git a/docs/md/examples/hooks_auth.md b/docs/md_v1/examples/hooks_auth.md
similarity index 100%
rename from docs/md/examples/hooks_auth.md
rename to docs/md_v1/examples/hooks_auth.md
diff --git a/docs/md/examples/index.md b/docs/md_v1/examples/index.md
similarity index 100%
rename from docs/md/examples/index.md
rename to docs/md_v1/examples/index.md
diff --git a/docs/md/examples/js_execution_css_filtering.md b/docs/md_v1/examples/js_execution_css_filtering.md
similarity index 100%
rename from docs/md/examples/js_execution_css_filtering.md
rename to docs/md_v1/examples/js_execution_css_filtering.md
diff --git a/docs/md/examples/json_css_extraction.md b/docs/md_v1/examples/json_css_extraction.md
similarity index 100%
rename from docs/md/examples/json_css_extraction.md
rename to docs/md_v1/examples/json_css_extraction.md
diff --git a/docs/md/examples/llm_extraction.md b/docs/md_v1/examples/llm_extraction.md
similarity index 100%
rename from docs/md/examples/llm_extraction.md
rename to docs/md_v1/examples/llm_extraction.md
diff --git a/docs/md/examples/research_assistant.md b/docs/md_v1/examples/research_assistant.md
similarity index 100%
rename from docs/md/examples/research_assistant.md
rename to docs/md_v1/examples/research_assistant.md
diff --git a/docs/md/examples/summarization.md b/docs/md_v1/examples/summarization.md
similarity index 100%
rename from docs/md/examples/summarization.md
rename to docs/md_v1/examples/summarization.md
diff --git a/docs/md/full_details/advanced_features.md b/docs/md_v1/full_details/advanced_features.md
similarity index 100%
rename from docs/md/full_details/advanced_features.md
rename to docs/md_v1/full_details/advanced_features.md
diff --git a/docs/md/full_details/advanced_jsoncss_extraction.md b/docs/md_v1/full_details/advanced_jsoncss_extraction.md
similarity index 100%
rename from docs/md/full_details/advanced_jsoncss_extraction.md
rename to docs/md_v1/full_details/advanced_jsoncss_extraction.md
diff --git a/docs/md/full_details/chunking_strategies.md b/docs/md_v1/full_details/chunking_strategies.md
similarity index 100%
rename from docs/md/full_details/chunking_strategies.md
rename to docs/md_v1/full_details/chunking_strategies.md
diff --git a/docs/md/full_details/crawl_request_parameters.md b/docs/md_v1/full_details/crawl_request_parameters.md
similarity index 100%
rename from docs/md/full_details/crawl_request_parameters.md
rename to docs/md_v1/full_details/crawl_request_parameters.md
diff --git a/docs/md/full_details/crawl_result_class.md b/docs/md_v1/full_details/crawl_result_class.md
similarity index 100%
rename from docs/md/full_details/crawl_result_class.md
rename to docs/md_v1/full_details/crawl_result_class.md
diff --git a/docs/md/full_details/extraction_strategies.md b/docs/md_v1/full_details/extraction_strategies.md
similarity index 100%
rename from docs/md/full_details/extraction_strategies.md
rename to docs/md_v1/full_details/extraction_strategies.md
diff --git a/docs/md/full_details/session_based_crawling.md b/docs/md_v1/full_details/session_based_crawling.md
similarity index 100%
rename from docs/md/full_details/session_based_crawling.md
rename to docs/md_v1/full_details/session_based_crawling.md
diff --git a/docs/md/index.md b/docs/md_v1/index.md
similarity index 100%
rename from docs/md/index.md
rename to docs/md_v1/index.md
diff --git a/docs/md/installation.md b/docs/md_v1/installation.md
similarity index 100%
rename from docs/md/installation.md
rename to docs/md_v1/installation.md
diff --git a/docs/md/interactive_content.html b/docs/md_v1/interactive_content.html
similarity index 100%
rename from docs/md/interactive_content.html
rename to docs/md_v1/interactive_content.html
diff --git a/docs/md/introduction.md b/docs/md_v1/introduction.md
similarity index 100%
rename from docs/md/introduction.md
rename to docs/md_v1/introduction.md
diff --git a/docs/md_v1/mkdocs.yml b/docs/md_v1/mkdocs.yml
new file mode 100644
index 00000000..d56ddfec
--- /dev/null
+++ b/docs/md_v1/mkdocs.yml
@@ -0,0 +1,45 @@
+site_name: Crawl4AI Documentation
+site_description: π₯π·οΈ Crawl4AI, Open-source LLM Friendly Web Crawler & Scrapper
+site_url: https://docs.crawl4ai.com
+repo_url: https://github.com/unclecode/crawl4ai
+repo_name: unclecode/crawl4ai
+docs_dir: docs/md
+nav:
+ - Home: index.md
+ - First Steps:
+ - Introduction: introduction.md
+ - Installation: installation.md
+ - Quick Start: quickstart.md
+ - Examples:
+ - Intro: examples/index.md
+ - Structured Data Extraction: examples/json_css_extraction.md
+ - LLM Extraction: examples/llm_extraction.md
+ - JS Execution & CSS Filtering: examples/js_execution_css_filtering.md
+ - Hooks & Auth: examples/hooks_auth.md
+ - Summarization: examples/summarization.md
+ - Research Assistant: examples/research_assistant.md
+ - Full Details of Using Crawler:
+ - Crawl Request Parameters: full_details/crawl_request_parameters.md
+ - Crawl Result Class: full_details/crawl_result_class.md
+ - Session Based Crawling: full_details/session_based_crawling.md
+ - Advanced Features: full_details/advanced_features.md
+ - Advanced JsonCssExtraction: full_details/advanced_jsoncss_extraction.md
+ - Chunking Strategies: full_details/chunking_strategies.md
+ - Extraction Strategies: full_details/extraction_strategies.md
+ - Miscellaneous:
+ - Change Log: changelog.md
+ - Contact: contact.md
+
+theme:
+ name: terminal
+ palette: dark
+
+# Add the css/extra.css
+extra_css:
+ - assets/styles.css
+ - assets/highlight.css
+ - assets/dmvendor.css
+
+extra_javascript:
+ - assets/highlight.min.js
+ - assets/highlight_init.js
diff --git a/docs/md/quickstart.md b/docs/md_v1/quickstart.md
similarity index 92%
rename from docs/md/quickstart.md
rename to docs/md_v1/quickstart.md
index 39ab6367..ef79faca 100644
--- a/docs/md/quickstart.md
+++ b/docs/md_v1/quickstart.md
@@ -147,8 +147,8 @@ async def main():
url="https://openai.com/api/pricing/",
word_count_threshold=1,
extraction_strategy=LLMExtractionStrategy(
- provider="openai/gpt-4o",
- api_token=os.getenv("OPENAI_API_KEY"),
+ provider="openai/gpt-4o", # Or use open source model like "ollama/nemotron"
+ api_token=os.getenv("OPENAI_API_KEY"), # Pass "no-token" if using Ollama
schema=OpenAIModelFee.schema(),
extraction_type="schema",
instruction="""From the crawled content, extract all mentioned model names along with their fees for input and output tokens.
@@ -196,11 +196,11 @@ In modern web applications, content is often loaded dynamically without changing
Here's what makes this approach powerful:
-1. **Session Preservation**: By using a `session_id`, we can maintain the state of our crawling session across multiple interactions with the page. This is crucial for navigating through dynamically loaded content.
+1.**Session Preservation**: By using a `session_id`, we can maintain the state of our crawling session across multiple interactions with the page. This is crucial for navigating through dynamically loaded content.
-2. **Asynchronous JavaScript Execution**: We can execute custom JavaScript to trigger content loading or navigation. In this example, we'll click a "Load More" button to fetch the next page of commits.
+2.**Asynchronous JavaScript Execution**: We can execute custom JavaScript to trigger content loading or navigation. In this example, we'll click a "Load More" button to fetch the next page of commits.
-3. **Dynamic Content Waiting**: The `wait_for` parameter allows us to specify a condition that must be met before considering the page load complete. This ensures we don't extract data before the new content is fully loaded.
+3.**Dynamic Content Waiting**: The `wait_for` parameter allows us to specify a condition that must be met before considering the page load complete. This ensures we don't extract data before the new content is fully loaded.
Let's see how this works with a real-world example: crawling multiple pages of commits on a GitHub repository. The URL doesn't change as we load more commits, so we'll use these advanced techniques to navigate and extract data.
diff --git a/docs/md_v2/advanced/content-processing.md b/docs/md_v2/advanced/content-processing.md
new file mode 100644
index 00000000..71a32438
--- /dev/null
+++ b/docs/md_v2/advanced/content-processing.md
@@ -0,0 +1,223 @@
+# Content Processing
+
+Crawl4AI provides powerful content processing capabilities that help you extract clean, relevant content from web pages. This guide covers content cleaning, media handling, link analysis, and metadata extraction.
+
+## Content Cleaning
+
+### Understanding Clean Content
+When crawling web pages, you often encounter a lot of noise - advertisements, navigation menus, footers, popups, and other irrelevant content. Crawl4AI automatically cleans this noise using several approaches:
+
+1. **Basic Cleaning**: Removes unwanted HTML elements and attributes
+2. **Content Relevance**: Identifies and preserves meaningful content blocks
+3. **Layout Analysis**: Understands page structure to identify main content areas
+
+```python
+result = await crawler.arun(
+ url="https://example.com",
+ word_count_threshold=10, # Remove blocks with fewer words
+ excluded_tags=['form', 'nav'], # Remove specific HTML tags
+ remove_overlay_elements=True # Remove popups/modals
+)
+
+# Get clean content
+print(result.cleaned_html) # Cleaned HTML
+print(result.markdown) # Clean markdown version
+```
+
+### Fit Markdown: Smart Content Extraction
+One of Crawl4AI's most powerful features is `fit_markdown`. This feature uses advanced heuristics to identify and extract the main content from a webpage while excluding irrelevant elements.
+
+#### How Fit Markdown Works
+- Analyzes content density and distribution
+- Identifies content patterns and structures
+- Removes boilerplate content (headers, footers, sidebars)
+- Preserves the most relevant content blocks
+- Maintains content hierarchy and formatting
+
+#### Perfect For:
+- Blog posts and articles
+- News content
+- Documentation pages
+- Any page with a clear main content area
+
+#### Not Recommended For:
+- E-commerce product listings
+- Search results pages
+- Social media feeds
+- Pages with multiple equal-weight content sections
+
+```python
+result = await crawler.arun(url="https://example.com")
+
+# Get the most relevant content
+main_content = result.fit_markdown
+
+# Compare with regular markdown
+all_content = result.markdown
+
+print(f"Fit Markdown Length: {len(main_content)}")
+print(f"Regular Markdown Length: {len(all_content)}")
+```
+
+#### Example Use Case
+```python
+async def extract_article_content(url: str) -> str:
+ """Extract main article content from a blog or news site."""
+ async with AsyncWebCrawler() as crawler:
+ result = await crawler.arun(url=url)
+
+ # fit_markdown will focus on the article content,
+ # excluding navigation, ads, and other distractions
+ return result.fit_markdown
+```
+
+## Media Processing
+
+Crawl4AI provides comprehensive media extraction and analysis capabilities. It automatically detects and processes various types of media elements while maintaining their context and relevance.
+
+### Image Processing
+The library handles various image scenarios, including:
+- Regular images
+- Lazy-loaded images
+- Background images
+- Responsive images
+- Image metadata and context
+
+```python
+result = await crawler.arun(url="https://example.com")
+
+for image in result.media["images"]:
+ # Each image includes rich metadata
+ print(f"Source: {image['src']}")
+ print(f"Alt text: {image['alt']}")
+ print(f"Description: {image['desc']}")
+ print(f"Context: {image['context']}") # Surrounding text
+ print(f"Relevance score: {image['score']}") # 0-10 score
+```
+
+### Handling Lazy-Loaded Content
+Crawl4aai already handles lazy loading for media elements. You can also customize the wait time for lazy-loaded content:
+
+```python
+result = await crawler.arun(
+ url="https://example.com",
+ wait_for="css:img[data-src]", # Wait for lazy images
+ delay_before_return_html=2.0 # Additional wait time
+)
+```
+
+### Video and Audio Content
+The library extracts video and audio elements with their metadata:
+
+```python
+# Process videos
+for video in result.media["videos"]:
+ print(f"Video source: {video['src']}")
+ print(f"Type: {video['type']}")
+ print(f"Duration: {video.get('duration')}")
+ print(f"Thumbnail: {video.get('poster')}")
+
+# Process audio
+for audio in result.media["audios"]:
+ print(f"Audio source: {audio['src']}")
+ print(f"Type: {audio['type']}")
+ print(f"Duration: {audio.get('duration')}")
+```
+
+## Link Analysis
+
+Crawl4AI provides sophisticated link analysis capabilities, helping you understand the relationship between pages and identify important navigation patterns.
+
+### Link Classification
+The library automatically categorizes links into:
+- Internal links (same domain)
+- External links (different domains)
+- Social media links
+- Navigation links
+- Content links
+
+```python
+result = await crawler.arun(url="https://example.com")
+
+# Analyze internal links
+for link in result.links["internal"]:
+ print(f"Internal: {link['href']}")
+ print(f"Link text: {link['text']}")
+ print(f"Context: {link['context']}") # Surrounding text
+ print(f"Type: {link['type']}") # nav, content, etc.
+
+# Analyze external links
+for link in result.links["external"]:
+ print(f"External: {link['href']}")
+ print(f"Domain: {link['domain']}")
+ print(f"Type: {link['type']}")
+```
+
+### Smart Link Filtering
+Control which links are included in the results:
+
+```python
+result = await crawler.arun(
+ url="https://example.com",
+ exclude_external_links=True, # Remove external links
+ exclude_social_media_links=True, # Remove social media links
+ exclude_social_media_domains=[ # Custom social media domains
+ "facebook.com", "twitter.com", "instagram.com"
+ ],
+ exclude_domains=["ads.example.com"] # Exclude specific domains
+)
+```
+
+## Metadata Extraction
+
+Crawl4AI automatically extracts and processes page metadata, providing valuable information about the content:
+
+```python
+result = await crawler.arun(url="https://example.com")
+
+metadata = result.metadata
+print(f"Title: {metadata['title']}")
+print(f"Description: {metadata['description']}")
+print(f"Keywords: {metadata['keywords']}")
+print(f"Author: {metadata['author']}")
+print(f"Published Date: {metadata['published_date']}")
+print(f"Modified Date: {metadata['modified_date']}")
+print(f"Language: {metadata['language']}")
+```
+
+## Best Practices
+
+1. **Use Fit Markdown for Articles**
+ ```python
+ # Perfect for blog posts, news articles, documentation
+ content = result.fit_markdown
+ ```
+
+2. **Handle Media Appropriately**
+ ```python
+ # Filter by relevance score
+ relevant_images = [
+ img for img in result.media["images"]
+ if img['score'] > 5
+ ]
+ ```
+
+3. **Combine Link Analysis with Content**
+ ```python
+ # Get content links with context
+ content_links = [
+ link for link in result.links["internal"]
+ if link['type'] == 'content'
+ ]
+ ```
+
+4. **Clean Content with Purpose**
+ ```python
+ # Customize cleaning based on your needs
+ result = await crawler.arun(
+ url=url,
+ word_count_threshold=20, # Adjust based on content type
+ keep_data_attributes=False, # Remove data attributes
+ process_iframes=True # Include iframe content
+ )
+ ```
\ No newline at end of file
diff --git a/docs/md_v2/advanced/hooks-auth.md b/docs/md_v2/advanced/hooks-auth.md
new file mode 100644
index 00000000..e4b7d7ce
--- /dev/null
+++ b/docs/md_v2/advanced/hooks-auth.md
@@ -0,0 +1,110 @@
+# Hooks & Auth for AsyncWebCrawler
+
+Crawl4AI's AsyncWebCrawler allows you to customize the behavior of the web crawler using hooks. Hooks are asynchronous functions that are called at specific points in the crawling process, allowing you to modify the crawler's behavior or perform additional actions. This example demonstrates how to use various hooks to customize the asynchronous crawling process.
+
+## Example: Using Crawler Hooks with AsyncWebCrawler
+
+Let's see how we can customize the AsyncWebCrawler using hooks! In this example, we'll:
+
+1. Configure the browser when it's created.
+2. Add custom headers before navigating to the URL.
+3. Log the current URL after navigation.
+4. Perform actions after JavaScript execution.
+5. Log the length of the HTML before returning it.
+
+### Hook Definitions
+
+```python
+import asyncio
+from crawl4ai import AsyncWebCrawler
+from crawl4ai.async_crawler_strategy import AsyncPlaywrightCrawlerStrategy
+from playwright.async_api import Page, Browser
+
+async def on_browser_created(browser: Browser):
+ print("[HOOK] on_browser_created")
+ # Example customization: set browser viewport size
+ context = await browser.new_context(viewport={'width': 1920, 'height': 1080})
+ page = await context.new_page()
+
+ # Example customization: logging in to a hypothetical website
+ await page.goto('https://example.com/login')
+ await page.fill('input[name="username"]', 'testuser')
+ await page.fill('input[name="password"]', 'password123')
+ await page.click('button[type="submit"]')
+ await page.wait_for_selector('#welcome')
+
+ # Add a custom cookie
+ await context.add_cookies([{'name': 'test_cookie', 'value': 'cookie_value', 'url': 'https://example.com'}])
+
+ await page.close()
+ await context.close()
+
+async def before_goto(page: Page):
+ print("[HOOK] before_goto")
+ # Example customization: add custom headers
+ await page.set_extra_http_headers({'X-Test-Header': 'test'})
+
+async def after_goto(page: Page):
+ print("[HOOK] after_goto")
+ # Example customization: log the URL
+ print(f"Current URL: {page.url}")
+
+async def on_execution_started(page: Page):
+ print("[HOOK] on_execution_started")
+ # Example customization: perform actions after JS execution
+ await page.evaluate("console.log('Custom JS executed')")
+
+async def before_return_html(page: Page, html: str):
+ print("[HOOK] before_return_html")
+ # Example customization: log the HTML length
+ print(f"HTML length: {len(html)}")
+ return page
+```
+
+### Using the Hooks with the AsyncWebCrawler
+
+```python
+import asyncio
+from crawl4ai import AsyncWebCrawler
+from crawl4ai.async_crawler_strategy import AsyncPlaywrightCrawlerStrategy
+
+async def main():
+ print("\nπ Using Crawler Hooks: Let's see how we can customize the AsyncWebCrawler using hooks!")
+
+ crawler_strategy = AsyncPlaywrightCrawlerStrategy(verbose=True)
+ crawler_strategy.set_hook('on_browser_created', on_browser_created)
+ crawler_strategy.set_hook('before_goto', before_goto)
+ crawler_strategy.set_hook('after_goto', after_goto)
+ crawler_strategy.set_hook('on_execution_started', on_execution_started)
+ crawler_strategy.set_hook('before_return_html', before_return_html)
+
+ async with AsyncWebCrawler(verbose=True, crawler_strategy=crawler_strategy) as crawler:
+ result = await crawler.arun(
+ url="https://example.com",
+ js_code="window.scrollTo(0, document.body.scrollHeight);",
+ wait_for="footer"
+ )
+
+ print("π¦ Crawler Hooks result:")
+ print(result)
+
+asyncio.run(main())
+```
+
+### Explanation
+
+- `on_browser_created`: This hook is called when the Playwright browser is created. It sets up the browser context, logs in to a website, and adds a custom cookie.
+- `before_goto`: This hook is called right before Playwright navigates to the URL. It adds custom HTTP headers.
+- `after_goto`: This hook is called after Playwright navigates to the URL. It logs the current URL.
+- `on_execution_started`: This hook is called after any custom JavaScript is executed. It performs additional JavaScript actions.
+- `before_return_html`: This hook is called before returning the HTML content. It logs the length of the HTML content.
+
+### Additional Ideas
+
+- **Handling authentication**: Use the `on_browser_created` hook to handle login processes or set authentication tokens.
+- **Dynamic header modification**: Modify headers based on the target URL or other conditions in the `before_goto` hook.
+- **Content verification**: Use the `after_goto` hook to verify that the expected content is present on the page.
+- **Custom JavaScript injection**: Inject and execute custom JavaScript using the `on_execution_started` hook.
+- **Content preprocessing**: Modify or analyze the HTML content in the `before_return_html` hook before it's returned.
+
+By using these hooks, you can customize the behavior of the AsyncWebCrawler to suit your specific needs, including handling authentication, modifying requests, and preprocessing content.
\ No newline at end of file
diff --git a/docs/md_v2/advanced/hooks.md b/docs/md_v2/advanced/hooks.md
new file mode 100644
index 00000000..e69de29b
diff --git a/docs/md_v2/advanced/magic-mode.md b/docs/md_v2/advanced/magic-mode.md
new file mode 100644
index 00000000..16c7229e
--- /dev/null
+++ b/docs/md_v2/advanced/magic-mode.md
@@ -0,0 +1,52 @@
+# Magic Mode & Anti-Bot Protection
+
+Crawl4AI provides powerful anti-detection capabilities, with Magic Mode being the simplest and most comprehensive solution.
+
+## Magic Mode
+
+The easiest way to bypass anti-bot protections:
+
+```python
+async with AsyncWebCrawler() as crawler:
+ result = await crawler.arun(
+ url="https://example.com",
+ magic=True # Enables all anti-detection features
+ )
+```
+
+Magic Mode automatically:
+- Masks browser automation signals
+- Simulates human-like behavior
+- Overrides navigator properties
+- Handles cookie consent popups
+- Manages browser fingerprinting
+- Randomizes timing patterns
+
+## Manual Anti-Bot Options
+
+While Magic Mode is recommended, you can also configure individual anti-detection features:
+
+```python
+result = await crawler.arun(
+ url="https://example.com",
+ simulate_user=True, # Simulate human behavior
+ override_navigator=True # Mask automation signals
+)
+```
+
+Note: When `magic=True` is used, you don't need to set these individual options.
+
+## Example: Handling Protected Sites
+
+```python
+async def crawl_protected_site(url: str):
+ async with AsyncWebCrawler(headless=True) as crawler:
+ result = await crawler.arun(
+ url=url,
+ magic=True,
+ remove_overlay_elements=True, # Remove popups/modals
+ page_timeout=60000 # Increased timeout for protection checks
+ )
+
+ return result.markdown if result.success else None
+```
diff --git a/docs/md_v2/advanced/proxy-security.md b/docs/md_v2/advanced/proxy-security.md
new file mode 100644
index 00000000..c7602531
--- /dev/null
+++ b/docs/md_v2/advanced/proxy-security.md
@@ -0,0 +1,84 @@
+# Proxy & Security
+
+Configure proxy settings and enhance security features in Crawl4AI for reliable data extraction.
+
+## Basic Proxy Setup
+
+Simple proxy configuration:
+
+```python
+# Using proxy URL
+async with AsyncWebCrawler(
+ proxy="http://proxy.example.com:8080"
+) as crawler:
+ result = await crawler.arun(url="https://example.com")
+
+# Using SOCKS proxy
+async with AsyncWebCrawler(
+ proxy="socks5://proxy.example.com:1080"
+) as crawler:
+ result = await crawler.arun(url="https://example.com")
+```
+
+## Authenticated Proxy
+
+Use proxy with authentication:
+
+```python
+proxy_config = {
+ "server": "http://proxy.example.com:8080",
+ "username": "user",
+ "password": "pass"
+}
+
+async with AsyncWebCrawler(proxy_config=proxy_config) as crawler:
+ result = await crawler.arun(url="https://example.com")
+```
+
+## Rotating Proxies
+
+Example using a proxy rotation service:
+
+```python
+async def get_next_proxy():
+ # Your proxy rotation logic here
+ return {"server": "http://next.proxy.com:8080"}
+
+async with AsyncWebCrawler() as crawler:
+ # Update proxy for each request
+ for url in urls:
+ proxy = await get_next_proxy()
+ crawler.update_proxy(proxy)
+ result = await crawler.arun(url=url)
+```
+
+## Custom Headers
+
+Add security-related headers:
+
+```python
+headers = {
+ "X-Forwarded-For": "203.0.113.195",
+ "Accept-Language": "en-US,en;q=0.9",
+ "Cache-Control": "no-cache",
+ "Pragma": "no-cache"
+}
+
+async with AsyncWebCrawler(headers=headers) as crawler:
+ result = await crawler.arun(url="https://example.com")
+```
+
+## Combining with Magic Mode
+
+For maximum protection, combine proxy with Magic Mode:
+
+```python
+async with AsyncWebCrawler(
+ proxy="http://proxy.example.com:8080",
+ headers={"Accept-Language": "en-US"}
+) as crawler:
+ result = await crawler.arun(
+ url="https://example.com",
+ magic=True # Enable all anti-detection features
+ )
+```
\ No newline at end of file
diff --git a/docs/md_v2/advanced/session-management-advanced.md b/docs/md_v2/advanced/session-management-advanced.md
new file mode 100644
index 00000000..f8c81da2
--- /dev/null
+++ b/docs/md_v2/advanced/session-management-advanced.md
@@ -0,0 +1,276 @@
+# Session-Based Crawling for Dynamic Content
+
+In modern web applications, content is often loaded dynamically without changing the URL. Examples include "Load More" buttons, infinite scrolling, or paginated content that updates via JavaScript. To effectively crawl such websites, Crawl4AI provides powerful session-based crawling capabilities.
+
+This guide will explore advanced techniques for crawling dynamic content using Crawl4AI's session management features.
+
+## Understanding Session-Based Crawling
+
+Session-based crawling allows you to maintain a persistent browser session across multiple requests. This is crucial when:
+
+1. The content changes dynamically without URL changes
+2. You need to interact with the page (e.g., clicking buttons) between requests
+3. The site requires authentication or maintains state across pages
+
+Crawl4AI's `AsyncWebCrawler` class supports session-based crawling through the `session_id` parameter and related methods.
+
+## Basic Concepts
+
+Before diving into examples, let's review some key concepts:
+
+- **Session ID**: A unique identifier for a browsing session. Use the same `session_id` across multiple `arun` calls to maintain state.
+- **JavaScript Execution**: Use the `js_code` parameter to execute JavaScript on the page, such as clicking a "Load More" button.
+- **CSS Selectors**: Use these to target specific elements for extraction or interaction.
+- **Extraction Strategy**: Define how to extract structured data from the page.
+- **Wait Conditions**: Specify conditions to wait for before considering the page loaded.
+
+## Example 1: Basic Session-Based Crawling
+
+Let's start with a basic example of session-based crawling:
+
+```python
+import asyncio
+from crawl4ai import AsyncWebCrawler
+
+async def basic_session_crawl():
+ async with AsyncWebCrawler(verbose=True) as crawler:
+ session_id = "my_session"
+ url = "https://example.com/dynamic-content"
+
+ for page in range(3):
+ result = await crawler.arun(
+ url=url,
+ session_id=session_id,
+ js_code="document.querySelector('.load-more-button').click();" if page > 0 else None,
+ css_selector=".content-item",
+ bypass_cache=True
+ )
+
+ print(f"Page {page + 1}: Found {result.extracted_content.count('.content-item')} items")
+
+ await crawler.crawler_strategy.kill_session(session_id)
+
+asyncio.run(basic_session_crawl())
+```
+
+This example demonstrates:
+1. Using a consistent `session_id` across multiple `arun` calls
+2. Executing JavaScript to load more content after the first page
+3. Using a CSS selector to extract specific content
+4. Properly closing the session after crawling
+
+## Advanced Technique 1: Custom Execution Hooks
+
+Crawl4AI allows you to set custom hooks that execute at different stages of the crawling process. This is particularly useful for handling complex loading scenarios.
+
+Here's an example that waits for new content to appear before proceeding:
+
+```python
+async def advanced_session_crawl_with_hooks():
+ first_commit = ""
+
+ async def on_execution_started(page):
+ nonlocal first_commit
+ try:
+ while True:
+ await page.wait_for_selector("li.commit-item h4")
+ commit = await page.query_selector("li.commit-item h4")
+ commit = await commit.evaluate("(element) => element.textContent")
+ commit = commit.strip()
+ if commit and commit != first_commit:
+ first_commit = commit
+ break
+ await asyncio.sleep(0.5)
+ except Exception as e:
+ print(f"Warning: New content didn't appear after JavaScript execution: {e}")
+
+ async with AsyncWebCrawler(verbose=True) as crawler:
+ crawler.crawler_strategy.set_hook("on_execution_started", on_execution_started)
+
+ url = "https://github.com/example/repo/commits/main"
+ session_id = "commit_session"
+ all_commits = []
+
+ js_next_page = """
+ const button = document.querySelector('a.pagination-next');
+ if (button) button.click();
+ """
+
+ for page in range(3):
+ result = await crawler.arun(
+ url=url,
+ session_id=session_id,
+ css_selector="li.commit-item",
+ js_code=js_next_page if page > 0 else None,
+ bypass_cache=True,
+ js_only=page > 0
+ )
+
+ commits = result.extracted_content.select("li.commit-item")
+ all_commits.extend(commits)
+ print(f"Page {page + 1}: Found {len(commits)} commits")
+
+ await crawler.crawler_strategy.kill_session(session_id)
+ print(f"Successfully crawled {len(all_commits)} commits across 3 pages")
+
+asyncio.run(advanced_session_crawl_with_hooks())
+```
+
+This technique uses a custom `on_execution_started` hook to ensure new content has loaded before proceeding to the next step.
+
+## Advanced Technique 2: Integrated JavaScript Execution and Waiting
+
+Instead of using separate hooks, you can integrate the waiting logic directly into your JavaScript execution. This approach can be more concise and easier to manage for some scenarios.
+
+Here's an example:
+
+```python
+async def integrated_js_and_wait_crawl():
+ async with AsyncWebCrawler(verbose=True) as crawler:
+ url = "https://github.com/example/repo/commits/main"
+ session_id = "integrated_session"
+ all_commits = []
+
+ js_next_page_and_wait = """
+ (async () => {
+ const getCurrentCommit = () => {
+ const commits = document.querySelectorAll('li.commit-item h4');
+ return commits.length > 0 ? commits[0].textContent.trim() : null;
+ };
+
+ const initialCommit = getCurrentCommit();
+ const button = document.querySelector('a.pagination-next');
+ if (button) button.click();
+
+ while (true) {
+ await new Promise(resolve => setTimeout(resolve, 100));
+ const newCommit = getCurrentCommit();
+ if (newCommit && newCommit !== initialCommit) {
+ break;
+ }
+ }
+ })();
+ """
+
+ schema = {
+ "name": "Commit Extractor",
+ "baseSelector": "li.commit-item",
+ "fields": [
+ {
+ "name": "title",
+ "selector": "h4.commit-title",
+ "type": "text",
+ "transform": "strip",
+ },
+ ],
+ }
+ extraction_strategy = JsonCssExtractionStrategy(schema, verbose=True)
+
+ for page in range(3):
+ result = await crawler.arun(
+ url=url,
+ session_id=session_id,
+ css_selector="li.commit-item",
+ extraction_strategy=extraction_strategy,
+ js_code=js_next_page_and_wait if page > 0 else None,
+ js_only=page > 0,
+ bypass_cache=True
+ )
+
+ commits = json.loads(result.extracted_content)
+ all_commits.extend(commits)
+ print(f"Page {page + 1}: Found {len(commits)} commits")
+
+ await crawler.crawler_strategy.kill_session(session_id)
+ print(f"Successfully crawled {len(all_commits)} commits across 3 pages")
+
+asyncio.run(integrated_js_and_wait_crawl())
+```
+
+This approach combines the JavaScript for clicking the "next" button and waiting for new content to load into a single script.
+
+## Advanced Technique 3: Using the `wait_for` Parameter
+
+Crawl4AI provides a `wait_for` parameter that allows you to specify a condition to wait for before considering the page fully loaded. This can be particularly useful for dynamic content.
+
+Here's an example:
+
+```python
+async def wait_for_parameter_crawl():
+ async with AsyncWebCrawler(verbose=True) as crawler:
+ url = "https://github.com/example/repo/commits/main"
+ session_id = "wait_for_session"
+ all_commits = []
+
+ js_next_page = """
+ const commits = document.querySelectorAll('li.commit-item h4');
+ if (commits.length > 0) {
+ window.lastCommit = commits[0].textContent.trim();
+ }
+ const button = document.querySelector('a.pagination-next');
+ if (button) button.click();
+ """
+
+ wait_for = """() => {
+ const commits = document.querySelectorAll('li.commit-item h4');
+ if (commits.length === 0) return false;
+ const firstCommit = commits[0].textContent.trim();
+ return firstCommit !== window.lastCommit;
+ }"""
+
+ schema = {
+ "name": "Commit Extractor",
+ "baseSelector": "li.commit-item",
+ "fields": [
+ {
+ "name": "title",
+ "selector": "h4.commit-title",
+ "type": "text",
+ "transform": "strip",
+ },
+ ],
+ }
+ extraction_strategy = JsonCssExtractionStrategy(schema, verbose=True)
+
+ for page in range(3):
+ result = await crawler.arun(
+ url=url,
+ session_id=session_id,
+ css_selector="li.commit-item",
+ extraction_strategy=extraction_strategy,
+ js_code=js_next_page if page > 0 else None,
+ wait_for=wait_for if page > 0 else None,
+ js_only=page > 0,
+ bypass_cache=True
+ )
+
+ commits = json.loads(result.extracted_content)
+ all_commits.extend(commits)
+ print(f"Page {page + 1}: Found {len(commits)} commits")
+
+ await crawler.crawler_strategy.kill_session(session_id)
+ print(f"Successfully crawled {len(all_commits)} commits across 3 pages")
+
+asyncio.run(wait_for_parameter_crawl())
+```
+
+This technique separates the JavaScript execution (clicking the "next" button) from the waiting condition, providing more flexibility and clarity in some scenarios.
+
+## Best Practices for Session-Based Crawling
+
+1. **Use Unique Session IDs**: Ensure each crawling session has a unique `session_id` to prevent conflicts.
+2. **Close Sessions**: Always close sessions using `kill_session` when you're done to free up resources.
+3. **Handle Errors**: Implement proper error handling to deal with unexpected situations during crawling.
+4. **Respect Website Terms**: Ensure your crawling adheres to the website's terms of service and robots.txt file.
+5. **Implement Delays**: Add appropriate delays between requests to avoid overwhelming the target server.
+6. **Use Extraction Strategies**: Leverage `JsonCssExtractionStrategy` or other extraction strategies for structured data extraction.
+7. **Optimize JavaScript**: Keep your JavaScript execution concise and efficient to improve crawling speed.
+8. **Monitor Performance**: Keep an eye on memory usage and crawling speed, especially for long-running sessions.
+
+## Conclusion
+
+Session-based crawling with Crawl4AI provides powerful capabilities for handling dynamic content and complex web applications. By leveraging session management, JavaScript execution, and waiting strategies, you can effectively crawl and extract data from a wide range of modern websites.
+
+Remember to use these techniques responsibly and in compliance with website policies and ethical web scraping practices.
+
+For more advanced usage and API details, refer to the Crawl4AI API documentation.
\ No newline at end of file
diff --git a/docs/md_v2/advanced/session-management.md b/docs/md_v2/advanced/session-management.md
new file mode 100644
index 00000000..c38ed852
--- /dev/null
+++ b/docs/md_v2/advanced/session-management.md
@@ -0,0 +1,133 @@
+# Session Management
+
+Session management in Crawl4AI allows you to maintain state across multiple requests and handle complex multi-page crawling tasks, particularly useful for dynamic websites.
+
+## Basic Session Usage
+
+Use `session_id` to maintain state between requests:
+
+```python
+async with AsyncWebCrawler() as crawler:
+ session_id = "my_session"
+
+ # First request
+ result1 = await crawler.arun(
+ url="https://example.com/page1",
+ session_id=session_id
+ )
+
+ # Subsequent request using same session
+ result2 = await crawler.arun(
+ url="https://example.com/page2",
+ session_id=session_id
+ )
+
+ # Clean up when done
+ await crawler.crawler_strategy.kill_session(session_id)
+```
+
+## Dynamic Content with Sessions
+
+Here's a real-world example of crawling GitHub commits across multiple pages:
+
+```python
+async def crawl_dynamic_content():
+ async with AsyncWebCrawler(verbose=True) as crawler:
+ url = "https://github.com/microsoft/TypeScript/commits/main"
+ session_id = "typescript_commits_session"
+ all_commits = []
+
+ # Define navigation JavaScript
+ js_next_page = """
+ const button = document.querySelector('a[data-testid="pagination-next-button"]');
+ if (button) button.click();
+ """
+
+ # Define wait condition
+ wait_for = """() => {
+ const commits = document.querySelectorAll('li.Box-sc-g0xbh4-0 h4');
+ if (commits.length === 0) return false;
+ const firstCommit = commits[0].textContent.trim();
+ return firstCommit !== window.firstCommit;
+ }"""
+
+ # Define extraction schema
+ schema = {
+ "name": "Commit Extractor",
+ "baseSelector": "li.Box-sc-g0xbh4-0",
+ "fields": [
+ {
+ "name": "title",
+ "selector": "h4.markdown-title",
+ "type": "text",
+ "transform": "strip",
+ },
+ ],
+ }
+ extraction_strategy = JsonCssExtractionStrategy(schema)
+
+ # Crawl multiple pages
+ for page in range(3):
+ result = await crawler.arun(
+ url=url,
+ session_id=session_id,
+ extraction_strategy=extraction_strategy,
+ js_code=js_next_page if page > 0 else None,
+ wait_for=wait_for if page > 0 else None,
+ js_only=page > 0,
+ bypass_cache=True
+ )
+
+ if result.success:
+ commits = json.loads(result.extracted_content)
+ all_commits.extend(commits)
+ print(f"Page {page + 1}: Found {len(commits)} commits")
+
+ # Clean up session
+ await crawler.crawler_strategy.kill_session(session_id)
+ return all_commits
+```
+
+## Session Best Practices
+
+1. **Session Naming**:
+```python
+# Use descriptive session IDs
+session_id = "login_flow_session"
+session_id = "product_catalog_session"
+```
+
+2. **Resource Management**:
+```python
+try:
+ # Your crawling code
+ pass
+finally:
+ # Always clean up sessions
+ await crawler.crawler_strategy.kill_session(session_id)
+```
+
+3. **State Management**:
+```python
+# First page: login
+result = await crawler.arun(
+ url="https://example.com/login",
+ session_id=session_id,
+ js_code="document.querySelector('form').submit();"
+)
+
+# Second page: verify login success
+result = await crawler.arun(
+ url="https://example.com/dashboard",
+ session_id=session_id,
+ wait_for="css:.user-profile" # Wait for authenticated content
+)
+```
+
+## Common Use Cases
+
+1. **Authentication Flows**
+2. **Pagination Handling**
+3. **Form Submissions**
+4. **Multi-step Processes**
+5. **Dynamic Content Navigation**
diff --git a/docs/md_v2/api/arun.md b/docs/md_v2/api/arun.md
new file mode 100644
index 00000000..9ef73aef
--- /dev/null
+++ b/docs/md_v2/api/arun.md
@@ -0,0 +1,226 @@
+# Complete Parameter Guide for arun()
+
+The following parameters can be passed to the `arun()` method. They are organized by their primary usage context and functionality.
+
+## Core Parameters
+
+```python
+await crawler.arun(
+ url="https://example.com", # Required: URL to crawl
+ verbose=True, # Enable detailed logging
+ bypass_cache=False, # Skip cache for this request
+ warmup=True # Whether to run warmup check
+)
+```
+
+## Content Processing Parameters
+
+### Text Processing
+```python
+await crawler.arun(
+ word_count_threshold=10, # Minimum words per content block
+ image_description_min_word_threshold=5, # Minimum words for image descriptions
+ only_text=False, # Extract only text content
+ excluded_tags=['form', 'nav'], # HTML tags to exclude
+ keep_data_attributes=False, # Preserve data-* attributes
+)
+```
+
+### Content Selection
+```python
+await crawler.arun(
+ css_selector=".main-content", # CSS selector for content extraction
+ remove_forms=True, # Remove all form elements
+ remove_overlay_elements=True, # Remove popups/modals/overlays
+)
+```
+
+### Link Handling
+```python
+await crawler.arun(
+ exclude_external_links=True, # Remove external links
+ exclude_social_media_links=True, # Remove social media links
+ exclude_external_images=True, # Remove external images
+ exclude_domains=["ads.example.com"], # Specific domains to exclude
+ social_media_domains=[ # Additional social media domains
+ "facebook.com",
+ "twitter.com",
+ "instagram.com"
+ ]
+)
+```
+
+## Browser Control Parameters
+
+### Basic Browser Settings
+```python
+await crawler.arun(
+ headless=True, # Run browser in headless mode
+ browser_type="chromium", # Browser engine: "chromium", "firefox", "webkit"
+ page_timeout=60000, # Page load timeout in milliseconds
+ user_agent="custom-agent", # Custom user agent
+)
+```
+
+### Navigation and Waiting
+```python
+await crawler.arun(
+ wait_for="css:.dynamic-content", # Wait for element/condition
+ delay_before_return_html=2.0, # Wait before returning HTML (seconds)
+)
+```
+
+### JavaScript Execution
+```python
+await crawler.arun(
+ js_code=[ # JavaScript to execute (string or list)
+ "window.scrollTo(0, document.body.scrollHeight);",
+ "document.querySelector('.load-more').click();"
+ ],
+ js_only=False, # Only execute JavaScript without reloading page
+)
+```
+
+### Anti-Bot Features
+```python
+await crawler.arun(
+ magic=True, # Enable all anti-detection features
+ simulate_user=True, # Simulate human behavior
+ override_navigator=True # Override navigator properties
+)
+```
+
+### Session Management
+```python
+await crawler.arun(
+ session_id="my_session", # Session identifier for persistent browsing
+)
+```
+
+### Screenshot Options
+```python
+await crawler.arun(
+ screenshot=True, # Take page screenshot
+ screenshot_wait_for=2.0, # Wait before screenshot (seconds)
+)
+```
+
+### Proxy Configuration
+```python
+await crawler.arun(
+ proxy="http://proxy.example.com:8080", # Simple proxy URL
+ proxy_config={ # Advanced proxy settings
+ "server": "http://proxy.example.com:8080",
+ "username": "user",
+ "password": "pass"
+ }
+)
+```
+
+## Content Extraction Parameters
+
+### Extraction Strategy
+```python
+await crawler.arun(
+ extraction_strategy=LLMExtractionStrategy(
+ provider="ollama/llama2",
+ schema=MySchema.schema(),
+ instruction="Extract specific data"
+ )
+)
+```
+
+### Chunking Strategy
+```python
+await crawler.arun(
+ chunking_strategy=RegexChunking(
+ patterns=[r'\n\n', r'\.\s+']
+ )
+)
+```
+
+### HTML to Text Options
+```python
+await crawler.arun(
+ html2text={
+ "ignore_links": False,
+ "ignore_images": False,
+ "escape_dot": False,
+ "body_width": 0,
+ "protect_links": True,
+ "unicode_snob": True
+ }
+)
+```
+
+## Debug Options
+```python
+await crawler.arun(
+ log_console=True, # Log browser console messages
+)
+```
+
+## Parameter Interactions and Notes
+
+1. **Magic Mode Combinations**
+ ```python
+ # Full anti-detection setup
+ await crawler.arun(
+ magic=True,
+ headless=False,
+ simulate_user=True,
+ override_navigator=True
+ )
+ ```
+
+2. **Dynamic Content Handling**
+ ```python
+ # Handle lazy-loaded content
+ await crawler.arun(
+ js_code="window.scrollTo(0, document.body.scrollHeight);",
+ wait_for="css:.lazy-content",
+ delay_before_return_html=2.0
+ )
+ ```
+
+3. **Content Extraction Pipeline**
+ ```python
+ # Complete extraction setup
+ await crawler.arun(
+ css_selector=".main-content",
+ word_count_threshold=20,
+ extraction_strategy=my_strategy,
+ chunking_strategy=my_chunking,
+ process_iframes=True,
+ remove_overlay_elements=True
+ )
+ ```
+
+## Best Practices
+
+1. **Performance Optimization**
+ ```python
+ await crawler.arun(
+ bypass_cache=False, # Use cache when possible
+ word_count_threshold=10, # Filter out noise
+ process_iframes=False # Skip iframes if not needed
+ )
+ ```
+
+2. **Reliable Scraping**
+ ```python
+ await crawler.arun(
+ magic=True, # Enable anti-detection
+ delay_before_return_html=1.0, # Wait for dynamic content
+ page_timeout=60000 # Longer timeout for slow pages
+ )
+ ```
+
+3. **Clean Content**
+ ```python
+ await crawler.arun(
+ remove_overlay_elements=True, # Remove popups
+ excluded_tags=['nav', 'aside'],# Remove unnecessary elements
+ keep_data_attributes=False # Remove data attributes
+ )
+ ```
\ No newline at end of file
diff --git a/docs/md_v2/api/async-webcrawler.md b/docs/md_v2/api/async-webcrawler.md
new file mode 100644
index 00000000..25164f6c
--- /dev/null
+++ b/docs/md_v2/api/async-webcrawler.md
@@ -0,0 +1,320 @@
+# AsyncWebCrawler
+
+The `AsyncWebCrawler` class is the main interface for web crawling operations. It provides asynchronous web crawling capabilities with extensive configuration options.
+
+## Constructor
+
+```python
+AsyncWebCrawler(
+ # Browser Settings
+ browser_type: str = "chromium", # Options: "chromium", "firefox", "webkit"
+ headless: bool = True, # Run browser in headless mode
+ verbose: bool = False, # Enable verbose logging
+
+ # Cache Settings
+ always_by_pass_cache: bool = False, # Always bypass cache
+ base_directory: str = str(Path.home()), # Base directory for cache
+
+ # Network Settings
+ proxy: str = None, # Simple proxy URL
+ proxy_config: Dict = None, # Advanced proxy configuration
+
+ # Browser Behavior
+ sleep_on_close: bool = False, # Wait before closing browser
+
+ # Custom Settings
+ user_agent: str = None, # Custom user agent
+ headers: Dict[str, str] = {}, # Custom HTTP headers
+ js_code: Union[str, List[str]] = None, # Default JavaScript to execute
+)
+```
+
+### Parameters in Detail
+
+#### Browser Settings
+
+- **browser_type** (str, optional)
+ - Default: `"chromium"`
+ - Options: `"chromium"`, `"firefox"`, `"webkit"`
+ - Controls which browser engine to use
+ ```python
+ # Example: Using Firefox
+ crawler = AsyncWebCrawler(browser_type="firefox")
+ ```
+
+- **headless** (bool, optional)
+ - Default: `True`
+ - When `True`, browser runs without GUI
+ - Set to `False` for debugging
+ ```python
+ # Visible browser for debugging
+ crawler = AsyncWebCrawler(headless=False)
+ ```
+
+- **verbose** (bool, optional)
+ - Default: `False`
+ - Enables detailed logging
+ ```python
+ # Enable detailed logging
+ crawler = AsyncWebCrawler(verbose=True)
+ ```
+
+#### Cache Settings
+
+- **always_by_pass_cache** (bool, optional)
+ - Default: `False`
+ - When `True`, always fetches fresh content
+ ```python
+ # Always fetch fresh content
+ crawler = AsyncWebCrawler(always_by_pass_cache=True)
+ ```
+
+- **base_directory** (str, optional)
+ - Default: User's home directory
+ - Base path for cache storage
+ ```python
+ # Custom cache directory
+ crawler = AsyncWebCrawler(base_directory="/path/to/cache")
+ ```
+
+#### Network Settings
+
+- **proxy** (str, optional)
+ - Simple proxy URL
+ ```python
+ # Using simple proxy
+ crawler = AsyncWebCrawler(proxy="http://proxy.example.com:8080")
+ ```
+
+- **proxy_config** (Dict, optional)
+ - Advanced proxy configuration with authentication
+ ```python
+ # Advanced proxy with auth
+ crawler = AsyncWebCrawler(proxy_config={
+ "server": "http://proxy.example.com:8080",
+ "username": "user",
+ "password": "pass"
+ })
+ ```
+
+#### Browser Behavior
+
+- **sleep_on_close** (bool, optional)
+ - Default: `False`
+ - Adds delay before closing browser
+ ```python
+ # Wait before closing
+ crawler = AsyncWebCrawler(sleep_on_close=True)
+ ```
+
+#### Custom Settings
+
+- **user_agent** (str, optional)
+ - Custom user agent string
+ ```python
+ # Custom user agent
+ crawler = AsyncWebCrawler(
+ user_agent="Mozilla/5.0 (Custom Agent) Chrome/90.0"
+ )
+ ```
+
+- **headers** (Dict[str, str], optional)
+ - Custom HTTP headers
+ ```python
+ # Custom headers
+ crawler = AsyncWebCrawler(
+ headers={
+ "Accept-Language": "en-US",
+ "Custom-Header": "Value"
+ }
+ )
+ ```
+
+- **js_code** (Union[str, List[str]], optional)
+ - Default JavaScript to execute on each page
+ ```python
+ # Default JavaScript
+ crawler = AsyncWebCrawler(
+ js_code=[
+ "window.scrollTo(0, document.body.scrollHeight);",
+ "document.querySelector('.load-more').click();"
+ ]
+ )
+ ```
+
+## Methods
+
+### arun()
+
+The primary method for crawling web pages.
+
+```python
+async def arun(
+ # Required
+ url: str, # URL to crawl
+
+ # Content Selection
+ css_selector: str = None, # CSS selector for content
+ word_count_threshold: int = 10, # Minimum words per block
+
+ # Cache Control
+ bypass_cache: bool = False, # Bypass cache for this request
+
+ # Session Management
+ session_id: str = None, # Session identifier
+
+ # Screenshot Options
+ screenshot: bool = False, # Take screenshot
+ screenshot_wait_for: float = None, # Wait before screenshot
+
+ # Content Processing
+ process_iframes: bool = False, # Process iframe content
+ remove_overlay_elements: bool = False, # Remove popups/modals
+
+ # Anti-Bot Settings
+ simulate_user: bool = False, # Simulate human behavior
+ override_navigator: bool = False, # Override navigator properties
+ magic: bool = False, # Enable all anti-detection
+
+ # Content Filtering
+ excluded_tags: List[str] = None, # HTML tags to exclude
+ exclude_external_links: bool = False, # Remove external links
+ exclude_social_media_links: bool = False, # Remove social media links
+
+ # JavaScript Handling
+ js_code: Union[str, List[str]] = None, # JavaScript to execute
+ wait_for: str = None, # Wait condition
+
+ # Page Loading
+ page_timeout: int = 60000, # Page load timeout (ms)
+ delay_before_return_html: float = None, # Wait before return
+
+ # Extraction
+ extraction_strategy: ExtractionStrategy = None # Extraction strategy
+) -> CrawlResult:
+```
+
+### Usage Examples
+
+#### Basic Crawling
+```python
+async with AsyncWebCrawler() as crawler:
+ result = await crawler.arun(url="https://example.com")
+```
+
+#### Advanced Crawling
+```python
+async with AsyncWebCrawler(
+ browser_type="firefox",
+ verbose=True,
+ headers={"Custom-Header": "Value"}
+) as crawler:
+ result = await crawler.arun(
+ url="https://example.com",
+ css_selector=".main-content",
+ word_count_threshold=20,
+ process_iframes=True,
+ magic=True,
+ wait_for="css:.dynamic-content",
+ screenshot=True
+ )
+```
+
+#### Session Management
+```python
+async with AsyncWebCrawler() as crawler:
+ # First request
+ result1 = await crawler.arun(
+ url="https://example.com/login",
+ session_id="my_session"
+ )
+
+ # Subsequent request using same session
+ result2 = await crawler.arun(
+ url="https://example.com/protected",
+ session_id="my_session"
+ )
+```
+
+## Context Manager
+
+AsyncWebCrawler implements the async context manager protocol:
+
+```python
+async def __aenter__(self) -> 'AsyncWebCrawler':
+ # Initialize browser and resources
+ return self
+
+async def __aexit__(self, *args):
+ # Cleanup resources
+ pass
+```
+
+Always use AsyncWebCrawler with async context manager:
+```python
+async with AsyncWebCrawler() as crawler:
+ # Your crawling code here
+ pass
+```
+
+## Best Practices
+
+1. **Resource Management**
+```python
+# Always use context manager
+async with AsyncWebCrawler() as crawler:
+ # Crawler will be properly cleaned up
+ pass
+```
+
+2. **Error Handling**
+```python
+try:
+ async with AsyncWebCrawler() as crawler:
+ result = await crawler.arun(url="https://example.com")
+ if not result.success:
+ print(f"Crawl failed: {result.error_message}")
+except Exception as e:
+ print(f"Error: {str(e)}")
+```
+
+3. **Performance Optimization**
+```python
+# Enable caching for better performance
+crawler = AsyncWebCrawler(
+ always_by_pass_cache=False,
+ verbose=True
+)
+```
+
+4. **Anti-Detection**
+```python
+# Maximum stealth
+crawler = AsyncWebCrawler(
+ headless=True,
+ user_agent="Mozilla/5.0...",
+ headers={"Accept-Language": "en-US"}
+)
+result = await crawler.arun(
+ url="https://example.com",
+ magic=True,
+ simulate_user=True
+)
+```
+
+## Note on Browser Types
+
+Each browser type has its characteristics:
+
+- **chromium**: Best overall compatibility
+- **firefox**: Good for specific use cases
+- **webkit**: Lighter weight, good for basic crawling
+
+Choose based on your specific needs:
+```python
+# High compatibility
+crawler = AsyncWebCrawler(browser_type="chromium")
+
+# Memory efficient
+crawler = AsyncWebCrawler(browser_type="webkit")
+```
\ No newline at end of file
diff --git a/docs/md_v2/api/crawl-result.md b/docs/md_v2/api/crawl-result.md
new file mode 100644
index 00000000..06998af3
--- /dev/null
+++ b/docs/md_v2/api/crawl-result.md
@@ -0,0 +1,301 @@
+# CrawlResult
+
+The `CrawlResult` class represents the result of a web crawling operation. It provides access to various forms of extracted content and metadata from the crawled webpage.
+
+## Class Definition
+
+```python
+class CrawlResult(BaseModel):
+ """Result of a web crawling operation."""
+
+ # Basic Information
+ url: str # Crawled URL
+ success: bool # Whether crawl succeeded
+ status_code: Optional[int] = None # HTTP status code
+ error_message: Optional[str] = None # Error message if failed
+
+ # Content
+ html: str # Raw HTML content
+ cleaned_html: Optional[str] = None # Cleaned HTML
+ fit_html: Optional[str] = None # Most relevant HTML content
+ markdown: Optional[str] = None # HTML converted to markdown
+ fit_markdown: Optional[str] = None # Most relevant markdown content
+
+ # Extracted Data
+ extracted_content: Optional[str] = None # Content from extraction strategy
+ media: Dict[str, List[Dict]] = {} # Extracted media information
+ links: Dict[str, List[Dict]] = {} # Extracted links
+ metadata: Optional[dict] = None # Page metadata
+
+ # Additional Data
+ screenshot: Optional[str] = None # Base64 encoded screenshot
+ session_id: Optional[str] = None # Session identifier
+ response_headers: Optional[dict] = None # HTTP response headers
+```
+
+## Properties and Their Data Structures
+
+### Basic Information
+
+```python
+# Access basic information
+result = await crawler.arun(url="https://example.com")
+
+print(result.url) # "https://example.com"
+print(result.success) # True/False
+print(result.status_code) # 200, 404, etc.
+print(result.error_message) # Error details if failed
+```
+
+### Content Properties
+
+#### HTML Content
+```python
+# Raw HTML
+html_content = result.html
+
+# Cleaned HTML (removed ads, popups, etc.)
+clean_content = result.cleaned_html
+
+# Most relevant HTML content
+main_content = result.fit_html
+```
+
+#### Markdown Content
+```python
+# Full markdown version
+markdown_content = result.markdown
+
+# Most relevant markdown content
+main_content = result.fit_markdown
+```
+
+### Media Content
+
+The media dictionary contains organized media elements:
+
+```python
+# Structure
+media = {
+ "images": [
+ {
+ "src": str, # Image URL
+ "alt": str, # Alt text
+ "desc": str, # Contextual description
+ "score": float, # Relevance score (0-10)
+ "type": str, # "image"
+ "width": int, # Image width (if available)
+ "height": int, # Image height (if available)
+ "context": str, # Surrounding text
+ "lazy": bool # Whether image was lazy-loaded
+ }
+ ],
+ "videos": [
+ {
+ "src": str, # Video URL
+ "type": str, # "video"
+ "title": str, # Video title
+ "poster": str, # Thumbnail URL
+ "duration": str, # Video duration
+ "description": str # Video description
+ }
+ ],
+ "audios": [
+ {
+ "src": str, # Audio URL
+ "type": str, # "audio"
+ "title": str, # Audio title
+ "duration": str, # Audio duration
+ "description": str # Audio description
+ }
+ ]
+}
+
+# Example usage
+for image in result.media["images"]:
+ if image["score"] > 5: # High-relevance images
+ print(f"High-quality image: {image['src']}")
+ print(f"Context: {image['context']}")
+```
+
+### Link Analysis
+
+The links dictionary organizes discovered links:
+
+```python
+# Structure
+links = {
+ "internal": [
+ {
+ "href": str, # URL
+ "text": str, # Link text
+ "title": str, # Title attribute
+ "type": str, # Link type (nav, content, etc.)
+ "context": str, # Surrounding text
+ "score": float # Relevance score
+ }
+ ],
+ "external": [
+ {
+ "href": str, # External URL
+ "text": str, # Link text
+ "title": str, # Title attribute
+ "domain": str, # Domain name
+ "type": str, # Link type
+ "context": str # Surrounding text
+ }
+ ]
+}
+
+# Example usage
+for link in result.links["internal"]:
+ print(f"Internal link: {link['href']}")
+ print(f"Context: {link['context']}")
+```
+
+### Metadata
+
+The metadata dictionary contains page information:
+
+```python
+# Structure
+metadata = {
+ "title": str, # Page title
+ "description": str, # Meta description
+ "keywords": List[str], # Meta keywords
+ "author": str, # Author information
+ "published_date": str, # Publication date
+ "modified_date": str, # Last modified date
+ "language": str, # Page language
+ "canonical_url": str, # Canonical URL
+ "og_data": Dict, # Open Graph data
+ "twitter_data": Dict # Twitter card data
+}
+
+# Example usage
+if result.metadata:
+ print(f"Title: {result.metadata['title']}")
+ print(f"Author: {result.metadata.get('author', 'Unknown')}")
+```
+
+### Extracted Content
+
+Content from extraction strategies:
+
+```python
+# For LLM or CSS extraction strategies
+if result.extracted_content:
+ structured_data = json.loads(result.extracted_content)
+ print(structured_data)
+```
+
+### Screenshot
+
+Base64 encoded screenshot:
+
+```python
+# Save screenshot if available
+if result.screenshot:
+ import base64
+
+ # Decode and save
+ with open("screenshot.png", "wb") as f:
+ f.write(base64.b64decode(result.screenshot))
+```
+
+## Usage Examples
+
+### Basic Content Access
+```python
+async with AsyncWebCrawler() as crawler:
+ result = await crawler.arun(url="https://example.com")
+
+ if result.success:
+ # Get clean content
+ print(result.fit_markdown)
+
+ # Process images
+ for image in result.media["images"]:
+ if image["score"] > 7:
+ print(f"High-quality image: {image['src']}")
+```
+
+### Complete Data Processing
+```python
+async def process_webpage(url: str) -> Dict:
+ async with AsyncWebCrawler() as crawler:
+ result = await crawler.arun(url=url)
+
+ if not result.success:
+ raise Exception(f"Crawl failed: {result.error_message}")
+
+ return {
+ "content": result.fit_markdown,
+ "images": [
+ img for img in result.media["images"]
+ if img["score"] > 5
+ ],
+ "internal_links": [
+ link["href"] for link in result.links["internal"]
+ ],
+ "metadata": result.metadata,
+ "status": result.status_code
+ }
+```
+
+### Error Handling
+```python
+async def safe_crawl(url: str) -> Dict:
+ async with AsyncWebCrawler() as crawler:
+ try:
+ result = await crawler.arun(url=url)
+
+ if not result.success:
+ return {
+ "success": False,
+ "error": result.error_message,
+ "status": result.status_code
+ }
+
+ return {
+ "success": True,
+ "content": result.fit_markdown,
+ "status": result.status_code
+ }
+
+ except Exception as e:
+ return {
+ "success": False,
+ "error": str(e),
+ "status": None
+ }
+```
+
+## Best Practices
+
+1. **Always Check Success**
+```python
+if not result.success:
+ print(f"Error: {result.error_message}")
+ return
+```
+
+2. **Use fit_markdown for Articles**
+```python
+# Better for article content
+content = result.fit_markdown if result.fit_markdown else result.markdown
+```
+
+3. **Filter Media by Score**
+```python
+relevant_images = [
+ img for img in result.media["images"]
+ if img["score"] > 5
+]
+```
+
+4. **Handle Missing Data**
+```python
+metadata = result.metadata or {}
+title = metadata.get('title', 'Unknown Title')
+```
\ No newline at end of file
diff --git a/docs/md_v2/api/strategies.md b/docs/md_v2/api/strategies.md
new file mode 100644
index 00000000..f0f8f57c
--- /dev/null
+++ b/docs/md_v2/api/strategies.md
@@ -0,0 +1,255 @@
+# Extraction & Chunking Strategies API
+
+This documentation covers the API reference for extraction and chunking strategies in Crawl4AI.
+
+## Extraction Strategies
+
+All extraction strategies inherit from the base `ExtractionStrategy` class and implement two key methods:
+- `extract(url: str, html: str) -> List[Dict[str, Any]]`
+- `run(url: str, sections: List[str]) -> List[Dict[str, Any]]`
+
+### LLMExtractionStrategy
+
+Used for extracting structured data using Language Models.
+
+```python
+LLMExtractionStrategy(
+ # Required Parameters
+ provider: str = DEFAULT_PROVIDER, # LLM provider (e.g., "ollama/llama2")
+ api_token: Optional[str] = None, # API token
+
+ # Extraction Configuration
+ instruction: str = None, # Custom extraction instruction
+ schema: Dict = None, # Pydantic model schema for structured data
+ extraction_type: str = "block", # "block" or "schema"
+
+ # Chunking Parameters
+ chunk_token_threshold: int = 4000, # Maximum tokens per chunk
+ overlap_rate: float = 0.1, # Overlap between chunks
+ word_token_rate: float = 0.75, # Word to token conversion rate
+ apply_chunking: bool = True, # Enable/disable chunking
+
+ # API Configuration
+ base_url: str = None, # Base URL for API
+ extra_args: Dict = {}, # Additional provider arguments
+ verbose: bool = False # Enable verbose logging
+)
+```
+
+### CosineStrategy
+
+Used for content similarity-based extraction and clustering.
+
+```python
+CosineStrategy(
+ # Content Filtering
+ semantic_filter: str = None, # Topic/keyword filter
+ word_count_threshold: int = 10, # Minimum words per cluster
+ sim_threshold: float = 0.3, # Similarity threshold
+
+ # Clustering Parameters
+ max_dist: float = 0.2, # Maximum cluster distance
+ linkage_method: str = 'ward', # Clustering method
+ top_k: int = 3, # Top clusters to return
+
+ # Model Configuration
+ model_name: str = 'sentence-transformers/all-MiniLM-L6-v2', # Embedding model
+
+ verbose: bool = False # Enable verbose logging
+)
+```
+
+### JsonCssExtractionStrategy
+
+Used for CSS selector-based structured data extraction.
+
+```python
+JsonCssExtractionStrategy(
+ schema: Dict[str, Any], # Extraction schema
+ verbose: bool = False # Enable verbose logging
+)
+
+# Schema Structure
+schema = {
+ "name": str, # Schema name
+ "baseSelector": str, # Base CSS selector
+ "fields": [ # List of fields to extract
+ {
+ "name": str, # Field name
+ "selector": str, # CSS selector
+ "type": str, # Field type: "text", "attribute", "html", "regex"
+ "attribute": str, # For type="attribute"
+ "pattern": str, # For type="regex"
+ "transform": str, # Optional: "lowercase", "uppercase", "strip"
+ "default": Any # Default value if extraction fails
+ }
+ ]
+}
+```
+
+## Chunking Strategies
+
+All chunking strategies inherit from `ChunkingStrategy` and implement the `chunk(text: str) -> list` method.
+
+### RegexChunking
+
+Splits text based on regex patterns.
+
+```python
+RegexChunking(
+ patterns: List[str] = None # Regex patterns for splitting
+ # Default: [r'\n\n']
+)
+```
+
+### SlidingWindowChunking
+
+Creates overlapping chunks with a sliding window approach.
+
+```python
+SlidingWindowChunking(
+ window_size: int = 100, # Window size in words
+ step: int = 50 # Step size between windows
+)
+```
+
+### OverlappingWindowChunking
+
+Creates chunks with specified overlap.
+
+```python
+OverlappingWindowChunking(
+ window_size: int = 1000, # Chunk size in words
+ overlap: int = 100 # Overlap size in words
+)
+```
+
+## Usage Examples
+
+### LLM Extraction
+
+```python
+from pydantic import BaseModel
+from crawl4ai.extraction_strategy import LLMExtractionStrategy
+
+# Define schema
+class Article(BaseModel):
+ title: str
+ content: str
+ author: str
+
+# Create strategy
+strategy = LLMExtractionStrategy(
+ provider="ollama/llama2",
+ schema=Article.schema(),
+ instruction="Extract article details"
+)
+
+# Use with crawler
+result = await crawler.arun(
+ url="https://example.com/article",
+ extraction_strategy=strategy
+)
+
+# Access extracted data
+data = json.loads(result.extracted_content)
+```
+
+### CSS Extraction
+
+```python
+from crawl4ai.extraction_strategy import JsonCssExtractionStrategy
+
+# Define schema
+schema = {
+ "name": "Product List",
+ "baseSelector": ".product-card",
+ "fields": [
+ {
+ "name": "title",
+ "selector": "h2.title",
+ "type": "text"
+ },
+ {
+ "name": "price",
+ "selector": ".price",
+ "type": "text",
+ "transform": "strip"
+ },
+ {
+ "name": "image",
+ "selector": "img",
+ "type": "attribute",
+ "attribute": "src"
+ }
+ ]
+}
+
+# Create and use strategy
+strategy = JsonCssExtractionStrategy(schema)
+result = await crawler.arun(
+ url="https://example.com/products",
+ extraction_strategy=strategy
+)
+```
+
+### Content Chunking
+
+```python
+from crawl4ai.chunking_strategy import OverlappingWindowChunking
+
+# Create chunking strategy
+chunker = OverlappingWindowChunking(
+ window_size=500, # 500 words per chunk
+ overlap=50 # 50 words overlap
+)
+
+# Use with extraction strategy
+strategy = LLMExtractionStrategy(
+ provider="ollama/llama2",
+ chunking_strategy=chunker
+)
+
+result = await crawler.arun(
+ url="https://example.com/long-article",
+ extraction_strategy=strategy
+)
+```
+
+## Best Practices
+
+1. **Choose the Right Strategy**
+ - Use `LLMExtractionStrategy` for complex, unstructured content
+ - Use `JsonCssExtractionStrategy` for well-structured HTML
+ - Use `CosineStrategy` for content similarity and clustering
+
+2. **Optimize Chunking**
+ ```python
+ # For long documents
+ strategy = LLMExtractionStrategy(
+ chunk_token_threshold=2000, # Smaller chunks
+ overlap_rate=0.1 # 10% overlap
+ )
+ ```
+
+3. **Handle Errors**
+ ```python
+ try:
+ result = await crawler.arun(
+ url="https://example.com",
+ extraction_strategy=strategy
+ )
+ if result.success:
+ content = json.loads(result.extracted_content)
+ except Exception as e:
+ print(f"Extraction failed: {e}")
+ ```
+
+4. **Monitor Performance**
+ ```python
+ strategy = CosineStrategy(
+ verbose=True, # Enable logging
+ word_count_threshold=20, # Filter short content
+ top_k=5 # Limit results
+ )
+ ```
\ No newline at end of file
diff --git a/docs/md_v2/assets/DankMono-Bold.woff2 b/docs/md_v2/assets/DankMono-Bold.woff2
new file mode 100644
index 00000000..3072fd85
Binary files /dev/null and b/docs/md_v2/assets/DankMono-Bold.woff2 differ
diff --git a/docs/md_v2/assets/DankMono-Italic.woff2 b/docs/md_v2/assets/DankMono-Italic.woff2
new file mode 100644
index 00000000..1d01ea6d
Binary files /dev/null and b/docs/md_v2/assets/DankMono-Italic.woff2 differ
diff --git a/docs/md_v2/assets/DankMono-Regular.woff2 b/docs/md_v2/assets/DankMono-Regular.woff2
new file mode 100644
index 00000000..99c1425c
Binary files /dev/null and b/docs/md_v2/assets/DankMono-Regular.woff2 differ
diff --git a/docs/md_v2/assets/Monaco.woff b/docs/md_v2/assets/Monaco.woff
new file mode 100644
index 00000000..e468c424
Binary files /dev/null and b/docs/md_v2/assets/Monaco.woff differ
diff --git a/docs/md_v2/assets/dmvendor.css b/docs/md_v2/assets/dmvendor.css
new file mode 100644
index 00000000..0f72703d
--- /dev/null
+++ b/docs/md_v2/assets/dmvendor.css
@@ -0,0 +1,127 @@
+/*!
+ * @preserve
+ * Dank Mono (v1.000)
+ * This font is subject to its EULA. https://dank.sh
+ * Β© 2018β2020 Phil PlΓΌckthun. All Rights Reserved.
+ */
+
+@font-face{
+ font-family: "dm";
+ font-weight: normal;
+ font-style: normal;
+ unicode-range: U+0000-007F;
+ src: local('βΊ'),
+ url(data:font/woff2;charset=utf-8;base64,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) format('woff2');
+}
+@font-face{
+ font-family: "dm";
+ font-weight: normal;
+ font-style: normal;
+ unicode-range: U+0080-1AFF;
+ src: local('βΊ'),
+ url(data:font/woff2;charset=utf-8;base64,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) format('woff2');
+}
+@font-face{
+ font-family: "dm";
+ font-weight: normal;
+ font-style: normal;
+ unicode-range: U+1B00-218F;
+ src: local('βΊ'),
+ url(data:font/woff2;charset=utf-8;base64,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) format('woff2');
+}
+@font-face{
+ font-family: "dm";
+ font-weight: normal;
+ font-style: normal;
+ unicode-range: U+2190-21FF;
+ src: local('βΊ'),
+ url(data:font/woff2;charset=utf-8;base64,d09GMk9UVE8AAAUAAAsAAAAAB0AAAAS1AAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAADYgTGyAcKgZgADQBNgIkAxgEBgWBdAcgG3wGEZWcfyE+EtMN9vKA5Bc0yUoz5//3zdWt7i7MMhk89Jh5YNQyuHYEC0QOBNNZU+uBFf/fX3vNFsIYcE02IK5Pv98Efw+vn0T3zFEboYh4FE8cSTQSMomQ8Ug0TyqZBNtCn6ltmWJarrMX4mswKBIYY7H7bxbmnSgqLFpx8yIZ/cA9xgIYCyNgLJKMxbKRoIjYCNlyHxrXrZvx+abPHxHcKkZSgdCXUgHlHqe3oz//PyeO3o9FFGNhscnzV2zcsf9YxvXRZ1+7WVpaVOU31l5RbOUBkheyMMmlLEZKVK6tsKIwZ+2aLRsVZRNls3HL+pRnzcrVfUmk4lcW376y5PCf7C3gZLvzqq35t/M+nUD5ywykaFPZH9GRJYNONVRVTftcgLGWUIRLYJCwSaGn8CfbxwbYj5JJypDaol6kJ31kizO5PqQxs+bUnM4k56Br0Gkht7C9/jE3vSeO0BJupOuTZ4LoOC298SmP8tF9cfSWHk8L6T4zLaXjfPKCbpwNpiXiyMevCxu5WT2DTtfw9clOp6Y504RNeHjUi8YuUazT0k/jTC76zsgym27QcbGUT545YKQHiSNiCTe5Xk8nN9n4YN9gb19Sn6a9FuFRvaI6Ko0/qhi9pcv0xqB5ibQ4a3Jf7+BgXxrZyJ3+ulgijnDj7IHJC8FiKR0/dYNH/UqVVt1FR+JMrtdjiDg0F2uofsDBPCq2p+4WkcQ4/Rc0CYQ8BEJHaTsf6B/qSenV+i0mVZygWm+cwgtQpJC4kChANpOaHAGRNzFs+v1rfGz+9AbNpvl8qi5YSM0pQrJV3ORaf29oWT1DA/2Ila5ZzAIHJrSkNB8rKfm9uOm9AUf9kDPZ6dI0R1rUF8YxRkHGSZlyab65jFykC/2tt8U39C3Zy7vHxdiD3N3scyc7HF63O6211dvU1OhvqE96WIxzBzb42zglGy8bF8z+Hn93V1Knt7OlzRJwO/wO1v8WY2Xde8n+gPhGfPvWRdJJLxOucWcdzTC2mB9UWrFUcwkjRWoEg6dhL7EO5IEOXyC5v98fCKS1t/s73O/Y4+22lNA4D/tSwcTNDd76pqRGf3Nbi8Ud6Pf2M2uo+5MN48JeTt/Qt5feFrrQHyTX3j4epQ1O/Da0a0hUDgWJWx3B2qDxh49Ezg2FiEJfny9UD/swXA8EAi9OzIuI+LCvvSvQ0f1QROTE4lmpAO8ygwEIQwoLtv/g8TMIgQIAMzMAABD2QotJtUXl3ywvRAIQIlGRnmMB8EkROUL6DnCpsewhrM059FDtivfmBOYMyI9OE1B7WOhuBbs2gbRVjgCgUgBIAGQAs8hgClGgQgUw35zPzEgw+x8lEC2E3C71ywOzS65Hb/83RFaeA4Bfaz/+dHJy/dvvzkxNU+hLyj2ADIkxRf54muAPswIYM39VAEN/eyZ1I0OSc9Y7J0auUtmylYIVwgEE4xIZTAkFUAuzXAYFtVwJEhxcGYCrXIFxOZK49EEsm+9TpFiNUjmyZCunehyqtVZbY3NNM7KRV3UL6lFZbUCOfLVsvkm35SmXrUKhlVR75ANKHNWXEbR3JuEdbaX12qwcQKftHPKwMjmKFFKtsdJqwZQBMWaGrQUAAAA=) format('woff2');
+}
+@font-face{
+ font-family: "dm";
+ font-weight: normal;
+ font-style: normal;
+ unicode-range: U+F8FF-10FFFF;
+ src: local('βΊ'),
+ url(data:font/woff2;charset=utf-8;base64,d09GMk9UVE8AAAJ0AAsAAAAAA/wAAAIrAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAADYIRGyAcKgZgAAQBNgIkAwQEBgWBdAcgGzYDQC4D7AZ5j5pUbZm4E4qID3FTshVsW6OPY3WC/+/H2rnvv11ENDEkTQxJq+WNZLJJVAvFm3aTBlvR0kSNfr+2Z6qhKJBM0ol5Y6ja8JLIZEphKPV9HOFkV4XMJnQRxziiAWnTbbybh5rcbQEVaSD4FH+CudcDRKD1sl994/9u8i2QA733nQ5oNDZoniWWYBj3EluDplDkEWft9AMzuudgMIgSdgg3JGVZ6nd2Bv1B6OwinfywmQofJcRH0ykzg9Iyv2VCRnk43/6X4PXUhMnvZ0DScRl4PMKMu/dGkVLCpfSOfGPKU4mFo9Fou1nWW8n6duj0Rd30ilt5v1vpvG4gDg9rRU4mn5ajexpYLbO6SVMBJFn6yMPnuxP+npv9XR6Oexf1IXJq7ndftzNJD8lJ+eLN4tGnQyi82LheWVxa3UxN+/QqTSCykoeAZEqVU/vW9jG4OMD/A8AQVapZPXFvadqHlofodtvXIiw8pNo9iKFmtUk8TuFR5f/AKby9MHb+CBB2lNQMrABYE0KgkgMgQNB3by5Ifm74PoDHdQc8nr2e/PsjvPM4CBgAgnD1R3CR3f/+5wka5ppslUPoBgEJxDCQJwFDoIFwhsAwxiAAE0VnpRGKc8JoieMZA0MrYy0NTVNWe6wa1KnXOAqs47ZKPVasujW1dOXLrh8VHVNNM31hlVp0dVnrDCe6X0Oolp+rqQoHNO6f6u1jEy0DfVb1atQJDyDxv8QBAA==) format('woff2');
+}
+@font-face{
+ font-family: "dm";
+ font-weight: normal;
+ font-style: italic;
+ unicode-range: U+0000-007F;
+ src: local('βΊ'),
+ url(data:font/woff2;charset=utf-8;base64,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) format('woff2');
+}
+@font-face{
+ font-family: "dm";
+ font-weight: normal;
+ font-style: italic;
+ unicode-range: U+0080-1AFF;
+ src: local('βΊ'),
+ url(data:font/woff2;charset=utf-8;base64,d09GMk9UVE8AADWoAAwAAAAAhvQAADVZAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAADYH7QBocGyAcKgZgAIVSATYCJAOGUgQGBYF0ByAbHYYzA4HucN6gKkGzzEZUsHEg9AxmUZRLzrrA/yGBGzJ8NVDfEQEVGVFi061ZzbDpViOjGy/dspBL6h6DlSgfbO2sbIYKtis3joUt7Btt3Bx8QpQf+ZXNAz5yhMY+yR2etvnvgAMMVBAMTu+wApMpdmNhYaKNaDMz17ooFaMWpT2X/efcWhdu+xm4z4KIWrbpvycm+RgRQjaKwqEsGIFwIBTCJSc+RJaK2O29RilC15tmBhVLGeycIOFBidoUhZtj5vTchAVgl8K1KaWUbf+/rzNLkVyp65Et+U1Th4lnIHAY/I1xHGDHOSTQ3o184D/Pr+0f/ntzX1/jGDzwMWImYSFjFZ0GYGGARYxRiAEGUWMRVTa0tAUGZq0z7Pn+//NT7UejnBOVnFnSOlqO3l96BYRMMi6QA4x2QHGdAingggN2wCmE0AFykCrbQdu1QuAA7Xt1pP7DtbVKmpwvesLzN1Tnf83SziRzwMkVEJ8HIlej0j9/J5NMMUuczQHwhP7fPcJsfzILkwOiXPEQUgBi9+PuXOXJkzWWXGVtraiUVVWiStWPn1MbeEUQrsrE2t5Pf+BdgQZsCYSpvBg3O+Mm/IiGpycYYAAa7QUDHADGw/+fqu/a/4IBDGHM0jWyxBqwnuKYQFUqeAW5tsbwQnixtYYIP7PhPCqzToFCEvzp3IY0q3IrfdMNEB+GdDYgQMAFgixegbggrEhcxP6sdbPQ/vQ/dv+k25zNRqvW/a/qaq1lFjegHvz6u5bnKejVcBJ/kwYiyjYAhXv9UtJUss/CDY2r++8Vf1KWLXk1AAECUAJ0ugyxcbjwFoQnToosImWqNem0w16HTDjutFnnXHXTHd9Z8dxrb6374Be/+TPt9ATCGzdlzjIGJpQBMxbscDhy5cFfkFDREqXJJlKqTqcehw2ZcMK0RZfcdN+KNT/4zSeo6NDVO41Ymbcpz3wLLLzYkkqvoMqaCsaXSqm6pjrrbbjJ9lXWsao7W003s9iHNowxNntOPPjhSSJUoIREnVaIKCZN0aTflJhK59S4KbXaO3vtN+0ZznSWs5/zPOe/sEUvcenLXdEqV7fWoYWXWH7Va1rnBja+PYvt6Kp3djW7NX38G0l30X9oOGnTWJpCs2keLaKVZELW5ETryYt86QidojCKpHi6TqmUQ8V0myUsrG07/TSccAiopy98tKQoQHIfwUoRZ/b/JSi7w0jLCaeccZkr2looQmEQTrVWGJkTTodu/1eiplB/1Qi48i8CBK9tdPF5ATGC04dE/U3JgxbvVj5b26sd/1xRhw3kDFuIQsGO9/zEQ936Rzri2dIFTaTfAN/8PxwtTrb8eJZ6szT053nZqYUY+TjcJCZKw4w1akEHB3l+yEdlcaSgPY7E389zk06i1anq5Es6/I+htdJ4oahTpFY2k5P/wbP7JMfadFYJutIZK9ULZwv1uJ5RWWsTZ2ezYEptmTBc+KfRrRd+18ZklqOxy+NSQLU7VxlFUaB4FWNjZdY+jTNKcmrMA0HkrdqT2u4a5TbKGHSpEy3LtzpX1PenRDoQq70sQ8ek04NQSiMPi9L4wXIyUJ9fAbgfLHimayr1DsuEdRtXXtyw6cwlSKYZP1ykVhjeZbvy6pe3yCLr9Caa8sLbQh7LW7NY8lS5iVdhC/NgZ77nxCvxx7es/Net36my/jdJa7Jps51KziL0dglano+VstVX4UUfLiYOgNoDzJ07na5CQQzZThO+OPiZFiMAVkDcwI72QUBFOIWYUZBi64JCYEjo0ZjGnlFQ41ar6PHotoAIAMbUsdQdlrI+IKhFANA5AIxUTr5WW9Q/3so5ZSVzE3LQHlovtE4Xm1R0tXGZtjVcRBfCSYP/NM120+ClMfILGeWprp/ru/R/K+T0b55oeNLBf1ywQITyWqwZLJ1ndwEAgbSBHCBzI5WtxRH59hnVaNBhdcqUarNZv0OG1ZjQZ4+dxvsAqCNge3YfdKofr6ZA6/Q0aD+6NuwHLU2CbrfLiRwlOeW4kzl9mfnPDCwAs5nFPQ+cFRecczWXxDV33HTPbXdzXyzXg4EnHnm6L4Fn4pUX3mZN6l1gqD/7T6q3Ab2ga3PgIOjRvovAKhxlPtfhdCpwA3gPx6qBHmArnMFm9gIjwCRc3AR0WwMQwAFPS+noQBzE/dvVzAU7/qDU2lDLv1Z6rY/0B9UnD0rmbfy29ibfaF+wr/KuAXfl3z3/7tv3DL7H554fymPvbbr3030D71t238b74u5rTBuRtjjNIW132oW0Z2lfVR+qs7SOf528Og/qkFqTgecHdg/6Y5AzaNKgRYMcB/kOAu2lwfGDqwe/ZlK2gp1nP+lPD3Ed4j+kbghnPDF019DrQ98OGzFs2bCdw94M1xm+d/i+4fuHHxjuPzxg+F0NNQ1I498an2kYa5homGqYaZhrWGhYaiRrvPlX99+Af1s0ZZqJWqLWj1q1I/4c0WhE+oiP/03/z++/Fm0j7cvSX6T9pCrWyJF3dJjORp3mUX+O+mm0xujUMV5jR4xtHWc9rmr8lPFxE8ZM2DGhYuKwifJJAyZ1nJQ9+c/J303+btl8SsFUnak504ZPi5j2brrX9EczdGYkzxwwc+2sv2Z1mVUze/zsE7Of6S7WTdZT0+PpKfTn6PvqPzCYaZBv8H/ugDklc8fOjZw3ft71+SvnZy6Yv+CioZphuWHvwrULLy38aGRrFG/0xfNzz0mvUK89Xlfqr/be5+O2ZLfPjC9j6RbfXzL0lin8vo0w/zsf6K+4FKiwMhK4/NGmoNcfOwVf+mTmmphQ9bXHw3TX5Yezja+Fr2XaRPzNe9s0JhJv9m3k7439o542MbIoj+FY7o5Zb2ZgdSL2SvMR1k78Wf6nuFdsDseb2B6Mn0og2H2fcKn1VPvmNiZJHQJNR3PBvXZrkoeSv6T8mfIlNTf1XccNaRfSQ9L7MljuKUJnj9auOuuPZ+luOJ71urtd9rUea3Iu9hzsmZz7V94HeWfyKd5d8x/1Gb15Y8H1PlzUXHSmUG9rROFXcXtxk/jigGHbp22fvn1F0VSxjk9S8a+DglTGm0cXQfVgAVQvFkyRrFZRBxKfvhNngV+8QaV5sBWPYwPUFJJ7TWkXIC/UOChE3HdWZLRhItEQ/fYDe7+N3uNvI/jhPYN7XuHilcD4HqQKwRsb/DpUmx3fJ6dQNbMmMTLC8rFrBQdK6nrfpB19QjeHI/rOWetQP49IqG6a14vf3O3orMc+H6SQnxkpjAc/+6Dx+Qu/s6eiv8Kv8j4lUOAx0us8hrzUPiSe+gvdMbw95mkN8hi++BfRV95eWhz//YwPwRwVIwrisGKuswN/eA0MQGvX/0wbQm8W050hxmdstci3t9xCDXKlJ9w6stqyyQSEAxkwIM56w3NRsOvv4vHDmDjkAdtclbXmK69IvDpU8aKZXmGF+0vRcbMqzH8/RXvmTTmWkMJ8OdcMnfp1N//7hDJX5ya3hTIO19pG0I/PW958bLZE0T9jXxLi7NpUmY1BtaM0pXX3dXCaM3aF16mV6jVVN7A0UGIVMQ9IVirwSIYQMflIBgwWB74lIX0+nAED471KoTjHgUJg8/kYkTlHVBAsOSxGhDHumRCawdSnn/RJfKI0FRirKL/vZ3LsQ7YsUVnRK75vrCgB5sJkbYZLM3hxkkui+lSi8BiEx1BV6X/3qO9TFJzo3x3oP/sxY0FMS9+PDsxhVg6PlXsmxQMY+3Fr7uKNA6Hv1utJ4ZWmCQ8u3Jk6vW3R1/ePog+z6MHIpUcstMhKTd8k945XCo5XYKw/dHBqgrnm6Df2AG8vRVayCer8irlnz/U+2mW4KVC8kH82fFZg9vLfOSvkpCdzZ0pPCJZvhDe6otIeVA8koB4G1cs9bKm4X66YnlKUjnZqUCgsrxCiJAhO/94nQrS3dBOGN+3b4+Gm9heh1PspRf3VvWYmEKTelrWHP9yf7CPElalWZMySdjBgdBpOsLux8j+iq+Hz5K62LpQQL07yvBI+YrVr/NZfc0E4VzyLEm7HbobTrW9azvsgpNpMNR+ZXmjzrnLHqoPTXPG+ifa8M/le3ICaeBanXc6qKz64Y8u6NR9upK9cW1UvV1SCb+SI1hY3fjjME7egT0hhyhfnQsno2eTnrBKxP+bhB7EmKhKPyYAxx/tVmSpYxIsDsFnbvvbwXg+3jII/RvaKqb7aqGbNOGjBDigMYQONpz6RlrtKJZTxS9suQwWEO7K0q6X1J5Gqwg8oxQULHVLtkpCKThM8tZtKOfwY3eaYIXsLS5lVoazInq3tQ9OiM9WNOGELh5YISdP8+s4tQToIm49KWnMQN0FMPbCmO9URijkvL7KZQnOZsjkWTesORGz24LRpleePjp469NndN2caLp1leG/dQ/f2r05DRs+uLy6eXvvnD0GYiB+AiTcOgLff02c2e3ESd8SH2NTDCWAT4jh8P1GchcWAV04XxXLQRzC31V651EgqS5Z/CAsTY4580zViOqDUzohnh+5Sh5k2BeasSORGt1x+agRChG0NYDBSe44qiXoYmxL6BIiV84++1dq8E7lEjQHESrpfC10RvZnUNOAHgwEsX01E2r3r5HoPt9vzC17qbnlftTS2tWdaWKGotdUPl9vIlLeoypZv6dLESqlIpMZZi0Tl9eEJlbsnzZizG+w276TltpOvNC3vvd0qlabaqZM0MhSmFsoSK3ERv+To44AwenLi7VYmWhlOszGDAZkhkTFJyWQKau6lMFoo5PA7Jkah2bFAdhm/a2q2rCybVsQfqHEJc8TyKWH20GdWEGQvucGsdfg61XPoSt1qPlMkFsQsto4PfQrPZbhBRMZMrioiOhqXrM0bR/Ct8ySsSrvOKAlrlJI5jHV1lx+nGi7D72TBuwfnVMY1kcXoSq1vxRF+19hsWV42jS9uDTziy+a1qMb0C6mhEDut0lQ18Zyw44kW6UN9OtI5RV1EvkRu1GD6gmOuWjgu5rlBGfy2CtoHOkLFVqd8Y2KKhWI0zxdOn9cYbyWKL1uLO7DA32Kvr6jJLjijkVb4cXx751sglgT81GRBJkietyzdu2TwZP5ejAWoLfZXN7fg1evSgtMEdSVVaII3rCiokduJtDTva2FWYRDmKxzrCrMctVHi7TkjMgRZteEpm3snKczLD2ZZalnS4/o7DvOTy47qnxIokMeroebusv5v0mBqvCQgdv4SQ2lKOro5i6+A6mk8gUJQvTiKCgFoWlxX0Ii+F3jvU/YbnCx/n5lpEiEnhh7pdoYy4FtTsRVh+1LYoj1351pktsv1h27I452r9hX7IDKWkuc7mCGsqMgQDlZMTRWUdlIEbMgeqBi2F6/xu5AidJrZyxSVqdaKrraXWUEXFNXdXKwUYLAB2qEMFqPgRV+8zd/r+HE/M4UnePJKgBEiVsn8b3MOEtMlU2b3JyKe9JnlES4lpV5GmdkmL290NcaY6XjCdXtNm1BOQzOJXxzt4Pcp67CfR19u8DqQxTy5iT0lpPLyY8QZIJ2qOkZP+a05RlAuKlk45BQkP4+TU9X2l71yIO0+Qvt8OMuaBHYBQaGWPh6Guzf3HKBQ57Ww7/x5+zkESsdqAMNY3XLCl12WFL4K/V8VmoJv3CQmGsOZZ0/zboXCaf5HEXoQgjIPp6BL0MaR+wr27Q292HzrGRubKoEYLQ/iHRQgS0xzItKxnHVwydKmxnmnKNKclNGa3ZiIkZkqt1CNHOmkQ9UtHjuN+YumF7mrLk18/s55VFW8a527rYqcuuVnhiDW+8cuNEdapRYAhkEpDX0mFLYJWzIxcubaSbM17IQW/ZZMES+viRv57uvICz9XOksDKuWKTzmif+Wbyp+TeuWDmaIaeUKsk7OhcwxRJbLCuWg0FGncVCadwkFv9PqDhvDjqu4dDy2QsHrLlwJHy3rTQ7VyA5ZKF0UWizWu2sjoVZL6xpXeTprHTvloP8kUNb1tRzwR8lWaMtXNfRovwJ+6AvjQjo5Lx1C5kYS0h4+1Wqg1e03rRbcp1FzWxIk8C0C9KBf3o/3UNHJdrkOE3KU9dlQIvbNWqa7/lRSp4LBlxNUbg73CLWNNZfN6OtacZ0WfcYOCG7oaMBsVgT7/skyUimzfcWDCjDnYwY4Lj+oXkIePdlVNdCs5nsbPZBUVB7n1HXngQ8Ot9rlo6NVklRzDRrIYqfy4FyfiaI83afWzpDbUCzls0P2JBnwSRkRZAXRxeDURlyuOzAGI/s3XweFxMuQz85hqFa87vDmSh4Jrf/FRF7M5lwzlO4sRqmz/maF+bq/P0JLQqfzyMOrnn/3zwbl1tZOZw9GwRjcp1feOszDQMt85+6ubx27Ce5FW9kmdnzVzZdMlRQGRU6EI2TWlXtVRjZL5L0pLCoPd4Bp2/vMTp6Xyz8mFrms1OfUqqY1BbPbvvzZjXJGrg7NZOrRw6Fpd2HqusxEHpdta7hqHoqgilJKSEeK6b+7hhfnYfXnt7Fu2uo5U9pSU9aKZvQmnRRp5BR3CtliMrBj6RRmzuxyR8o9atVL1jhIv7pirEmQMg8RPJttJd+TG+EjEYcvJq/ljZTYGDr7w8eFdVbXMRRWxq3+fA+HaQBh484BEqw6eB2l470WaVZc2AfDtFw9I7vNY8GgFi1bPjSZ75WdWT5pMVs06lzIBHccfcP3PxuBdF7LVEV927v1lSc4+OHBqsrtEMPkqPS8CsdkyuSgigRFhiRD8NfJ5caM6074wTmWmiF5MHS4qkd9fDaMV6qjcDsWtXvxk7ktDecnSgTYlAQFJgsCApYT7btGv7iOlF0YKp3d2pQ1xcdWVafnxn0qZBwX7vVxZVWWMf0WTBDngu2tAretr7QUzweKDyuw8pmOeeHGoOpyuJUWlftnJsu+zaXA0MQFTrNhTYmxT5J+KlbnC5QsaMnVEYoSt+hDGsvYfHqSWkLaqDWvrwDYfdh2QU5aL7Aza32fBmGliUcXeLERUDmZDEONXLydYTbklQBfo+3EwTaitzWEiqtJtw2Gx+LmnSFblRSYcmshgEW65l1A0hQTATznyBKlsWlhtnswU1gxs7QCGbgrIGdxjLn/fr5nHSNKGz+6a6m3wy/8UUEeZH2xoqgbCAgpWBSvrKj4hB2xDyLmziBHgTAiHeAY7k4cYHtJCc3m+nonRsl9Semqnfp74+qDWHv/kCHEiOfhHRBPex6ortxaQRU3IoiEDnEc/sSpkqFiyfGFWdDWxeOSP1VyYCzMRLHWCta8A2exXVdCBnQza2sR7MLZpt1tBbGsThpnRFh/QjIz5u2yycCJPiZGKzlWm82qpVEOntKhkGbXFZeaj567Z7+WPzfdilv05JXlzdz+JqJCd8wAyfl5eboNFRUrt3NWVk+0uEi0Ax/MCbC+MrVTMiUNPuRGcrsi47UH9Exw/XAxDw5JgNs5xb2svly6yXAROnJdDMSLHBGxsDAU9cOaQi3USuQfkprIYHdojBt7TtiCrxlgz9p0S/pbJLMsvmBi10uTVmKmP0pj8RZC5fpENJOxglqu4KKYnvMxKiZRYZaki4poWkQiBdUyXfyLNYzEax/k4JHE/r6zKeBx4zdNNkLSkrJ6qCAHMv0tomLyYLFJSQjOza7LXQb8Ku2u5mz64hhERe4W9/rhumK/xVO8xUl2hEBIixeR/sh3nCfpyin/YNGgKKbyZSYpu2inLi770Mxn/xUqF5BzIJV0YJ6p0Uwh9zKryqI2OQjwEJ0NfoNVU9Bh3CT/LF48S8c0z+fn5KKkogjMng2yPe2rMqhc28aE1OEmY5eg40SyXoJ3wl0WEyl98kefBxsRJjFZY8BBSMixPLj0k1WaWvyXhSpxsSoG95QivmVpXFqOG3aC1AY/wK5Q6AVN2TlHaI0hl9fhAWDVd3mr5WN7ziV9pWcbDT8c6STYDqE0lA+YqSz6TSGOeb+Vifg0m/HpZ4zJ1nm+8hUo44C0JSpgikpDADxowRNdawMim92CuPg55qaaaancbjEabr6ghfJ3YR0JKnS6jeS1AtOL1HVltB8SV91NXG4yyOnuak7KTdipm6TH1enPUWx/kEj46A6kKfpaEtQFbOgHjiBipSJyTAcOECU7RibxYLMqqfX53E6yWF/jgRgwubdNK9CZBg2nS0AzLGCjuxyQxSSg1hNfGkkVqkMRoFJ1JPfHBPgGHLOlKikSnmGhWSvosRk1DVDbjZ/K+ICgWmqEKs5Q0R4l1TwhVFSehXQZtpaSg9LjA6sHSSmkqL1QdpWlCUw+fzuZIGCzT8ekyyyXLlJTEqFmPItLP5PmlvQIoFkJECqKzBADTOSZy8geNMT/QDBajFTh8FEcrPOkVkpozsh4/Cn3m3Hcl+MxQwIZMSngmKCxlArdexcZVL/6KCHyvp4cB5genOPV+ZGeA6Zrq/dzTBZQzDRD3aiqDtEcNEBtrfiVXN+GMf5YBHwTVJhJeMVFTidTHwROQwOPRZ9NcmoS6TSdVOxMaOgvuFrtT7EcY7kqfgFAg6xAyGwNaZPab2jvUwGwTWZaN6TptQ+T7dDvT/VKdvWsFcpKjLC5eZ7EYjZv/4h5ExAVncGjqiabhIGGNo+KkCuADr6Jc53VNl0fpS3jAGpDm40+MeWBn+rwcZxOFdFOJW0HMqOhSQT7R7eAA4DgYaTb0YyPuxTyeSYjgpM+ol4vxHN+ZpO2S7F72hVvvGyxGz0Wr3lD6qlvVYGZaizUhtHQO6BFtds6fLenlqAuEyKL/ZK8gIgTtjIeqWaDNRka+IH0OeFFC8SPNyEJjQzinbGnmfvTqq5VPLDTJIJOU1TBLm8SwERjv+Cl7qEh7ucqHZk10uXg+JKcu0eqek6pB5OIClPUCvWeyMXQcNyyayVSh91Qd92gag5PU17EkrbZcJqrC4K5WrjiFdWFya/k69XIV1pEyeeXGBazWnSe4aX8rDul9cctA6a8KZkkg0c3fNC3Dh0rCFqfEw/ME/6cOGRlrktUWW2Bfa4t3utSD6Nl/ej+ZVIoPe/ws64vsNwkO1oUwq+cgH6RezsXmeUNanu4gaDEN4C7Wsbd2vrpc082zZXZ51zN1sXjFSEGMRi9DOYgcQ1tFluvJZs4i7XeCx7kGKH0FFwb/3LWqeUy6u0ZG0JBoKLQ3f0/Onmz5SLI+XZBrTqTNpMQ8dTX44aIXCxEG+MDBC96wfeE9GWncw+St3moXnwJD91ybzHK8BwhKW+AK85OljeU4VWmkbmrsigOob+ORWPded8Uqx0HBWBMTIIzjVPRjhw4uPZi4MbytFjZjZitxeKfSb+VwhsAergtzFpFIIbnlYWzPvEiFh9fAXkw9Y3PjEMddE/cOz7s2Wu1GlyWH4oMXyblaB4xlhAnfGOPzMYm29+iNpPhaaEyNXU/NpoNHFodbvZSPNksQoRi8xdeA3u89syoy00bWD6xnB7FuQMM8E+ycCzkrj65fp0ufCftM81WbZo5ysyL42tUd3EFUji8Y7BUBtjjGNnYr3U/Bhvy4clJL70QIQg+YyJMpFxpQV/45TMyfgqwB0n40kaJ/hcUq1DGQw9hOEMx0AE4/cLG3oZIP3PG5p+tOjpGYDLexmKs1zb4NdJgdwCV4HtzeZvUe7N0VejVqXDfBjlY9QI81UY22EQMmo6QoBQ1C8bhpx7tcqGl4/vj/xZ6ZUcXyuiDBF/qLCamgxf7fgUMsihLb7PtOE2iSjq4P/vMefnIGr/IKdlbdUUt5vs3+JHEEynBzJiK6ysRWPpIUl/VDlfBLFEvxlEUXWlIqCLZ/x9PWwoiEfIB6cBLAU1nUJvSke426CoDIaCHBYASgZsNtu5i16eNSlzyRIV4d2pO2iJVfkzlHyBvZE6xNXvmgLjyJ+gnPLSRIk5E+kZQot7ICPR3+MZsXhTASYcD5ah+Yf0o344FcOl245G0alz3fYZrWtHWlfwy4wJnb6x4QPvmAiDmo8QU4ORhLKOUUnASTM/o9WmasJ8K5foXExxleEi8RGLFt0P20BQWNpTWKLv94LYG/4UkBwXEbFM9JsEElB4pC8O39NvaUj9pDy+n5rAcLpz56HriOqQijsaZoyajLvI+m1SVfRAUncpzKKWtma7q+EPCwhM3rGrBmxkGLjBSnSuo3GKPIgR+UDDuHMJwXaE17WnMN2V/a0TRfup2SaGW7sExvhKDPqqE9XQqGOQiwQlQULzCjGiPZZTjwxGk5RT5HbFWbWztNbe5wC9Vm0jNOyUiCWNLfm0jllx1eUxTeINvJfNnu96cs80OuABO9ZamyYyZ2XXa0j1QtVSzJxYeXtOmc48HnLCUghbcO3Opp2+PCToIhE1qeoNjjLGvwsdOeIclRiSxmhex3/Or2Hrcube36/PUb7Kz5Utjk2k5MSDrBvZW5J5P6tIuj67tGEOpDkjqQc0yCktboCUQaqs6+gPjELicdrQ1GLAC2JMZCk0AsALWPqaRYNQkorngwkFuynfBIdhApHr9YuGfdi7TKvgl+u2Vse/FjoqPJGqy0vYugNNoV+d4yD25FhvY+WbRrr+t2j9bVj94cj4wz6bhz0K0WYIisX2U2Z5Y8UyW1VQW10KiBGFlmvVYAM6eFj0pjSZt4Ewr7in1cGnhwC+0G4H47fP03ZzGmqgyc3CqQOh4KdSdcMzHxuV6gNWQkNxh36Kgdj4KmoeiAYe1+exjwydYaK0EPTyWn3wJUeQybbvGx1WSvfZNhXmpwJ/TiHq+gnYL0zJ9IqD5F1kbvjoYdB6v1U8tzzwZSCkp7hTqDo12zd1SfcB7kNpBTslwLWqb3XYag2rWadFjM2iFD1chZalq7aa2U1Z4p4CuzddENQq1pP1FXN3XBlDFlgpuDsG0IyoY480eSYyea3Glrkh2JytHOx4WSHYduu2QAwyYWt7RZkaCshOPYo0oRyLLR99l1OPOO6cmWSmg3+z7oC1xAd4TR0LF4yyqXefp7SF7yyRmCyiu/27A3zYKkJbHJq/g5OeHIVPtnl6a7tXhFM9hUbxBZ9K9VOmhOvPJqzUwbF8/zykKYbjzbZBB4fLYYtQ22bJupJF+lY9aQs9NS0xdiF89AlIJ3W2yVze0yTTZ3EmyylcjkC4yHQNPTo3ny8HbxiRIXGiiBO25uhLpvCm9+aQKFP0HePjdY9kQEoNCLAtF3067NahPev62mqKaYbNY7MycJOXIEsV7wXQWfKEzScQLuCfsXGJnKhBR5mnCFe65z0ujlSBVIz9FF2nbasHJJ/8CBHVRARuQsDH5/uEFJDR09mZuHvbQQd0mfE5Js+diyc+UB59OtJ0hrhJS0h+sZENDysjtzfwBe8QDqVVdew5T2zz3l7iYmv09sMti5ILYt3XY23Sw70U1yuY9wb9JMePa3EGcSkUs+MCebdNhih+yvHl85E7BvOjzZxUlOSoplyhjhFh3OfiN/nxZX7O3Tc0jfus5+HZplXIbsVmftpWS8a30nbOh4UT6oElV/1q706Pg0H2uFyWfZHmRDoVll20uRluA4XW6IVrm2fX9aJPM+qZygrdsd6Losxq6k+rmrocah9026RIeisPfQblq6mGBuZ+2x+4K3cy402GFup84x2KxEoTnD9zBqHP5o10c1h8patYL6fUuK+VI2RfF9C74XV8CrexFvQJAgzg/Meh/pwh1aoFa/ne9GKdd7V2Hu0Kt5BnAy/n+AepVGMF3WPmXTX26JsvHaUNhcajEpIjS3MFbeXReL5sN4TRDdhnujh0oApi84VFBzDygdEqLGPirEtm7tIPYcVacwK706/izQJdnB3IjKIzKR8BkE/ch1bf7hnOgBF4pWO6lT+OLpU3EPxoJwBIAm+koA45s/BKQSh8IYzD7FxTZAYM5QWz6dMrpglNzVfaSOFrkzIhLpAvjSnPUS0AOvK4mG2Csm+BQdxkvSGw7MYGCVyarTUufpidF1zWtepNJElx/amQll/6+9TXsxfvHjt4E+bIswGm8WLRl3PY/1/VpAriSL2UY4lqNjx4+N8QS9xJ6j0l4ZoG7+ypspqHKuYrqwSu9Qx1CT9kmjxHYv3GVVq1hw1ut1FXc0SZe66VsGZxUAFo/Rs6WcbigSeHtH5zJJrp7EB/YtDY/aqS3r60hKc42zxS2vlvUNIqRt5dvfbRimVf5OQBA65ECcAYSp9vfmgV4AhSAwvqmidjR6UZiYbRSCeKviVCzjoQdzEQY2gQQiAmZjl1qJemjg+eH1sag5ZL4B4Z0nHeuhDcdSzCJj5/IhIYtYWxE9browb7oW9ShBb6tYQ48/DjM3s1+hB6DWVm1zh6sYlBYc8aS8NXRa7utOfQ6UoXoE2Czpe741T+Er9dfWGYL/25La3o5HuVpkqvhH1bavlDb17VQCjJy6xpnLp93dRKbXRupZGGktdT170oylcxUBVFRdeclpq26zYgTzJjeybO+b7YeMs+oCrsgFEx0tfQbvFFC168MdYI+fAXq0QGyRMHGnxLS+zOAnjOJ7I/evloKRehP/CzfEMDL7qlCZtapDoVgySAHGWh6e91hN1JD8ATnlMW+9rcvNMzJsh3t27nBmaEkT5t88MLbxw+Bnj0qegMfUj/kRDIJdXJV2zNteXqFszhJDXGNW0HYXmrN75eXmde7GT4P3t3CaWKVBKHFSYwSBXZ3i84pMXzyWgTN+hdIy4MlHTbMc0JfQaksUiFfFxExgLfNlIrrmcj3d5CLhDzVzzBY8uCpv8uRkM/XwBEtszZzYJ9yLDFUE/Xo87Zs9n7brtveI0+FEsGN2+Y4a1w7fSazcIFTCTgeugk2YlZuUkIiZMiW2QVZcTLgCWViR00Rvvj5IQEy18Ds/YSbtCKzDQEoDCKZdJEEAGysAvf3NFmLbEx7ar4+PPRFORu7BbiuVoGUwHvKk5Ayt+CIq10RLd03CuXeY8TrYcv4P3b8jMLqzDGi6+54vjlekgpirIB8coZ/AQJv4PvBetkzNlyAajauEpo6JvFELRyu/1iiLHSQjImEI9wx8dIcEBwinBSSi5GXmgWEwGWbkt2jafhZJTOQjVRDjvj9lTxr5BZ9YQN3uXuvrXLe56nLoe+glpbayq83JRsvR1Q68xvA2wVJ8vaNtwXmc+XFgeGFQghBzuPtJpcel3wOTP8vzt0m22S/1gUW5x5LJxyK1XTWIy8a+sa+YSOi0xqI2kflefk9M6Bvp1qbHLHdQ141Ybk10zLF/rNQuqj+BmuRGt6ab0yF9d1V3HXnW92mPXjufLx88ssz1S4ZNu0fn8hF734lFFkIi2aLQoHFOgwDiDAh88J7mEboRkQvEeJE+amYvzNknuTxFQoYYVIHX/NtoKnOuxX3xbML2E+2NsWMNfw83ox4yQfAq5bwzGNFCszWs3tF+YJHjIalX9URNHpEsX0GbqWJzL696P9ViWWhaHssJG4RWcBzxLqNOmwV68GOLzY2MT94n5NiUNBCy6X1b8c+hjNWnFfCNopdG+VUYru08aSu7mo99wUJt+25xVfu/wAZR9VmZ+EPgZUOLL7oTRq1poBZ9PK3EN/afzha77ymx0JpfkUI2ne+bzO1huBxlh6I710ot/OGQqMKruMiED/KR5PzEFRzxRIp71KX4PQqN6XnE5CXKiuFuldPUNppeuhvc9cH1M0VOaa9wF3epj2OnIiYN5wJ31u2q60vRypmWM/WwB/kTny9+/WOXNzmp9cfqj/43Wr57Bhi+iBRL06sAF4xEaYm5HlYkmeGmJu9A7PlovZ5VPzWqhGZDor3La3YfdHKuG6r2YffvE6uXWxF5KBVZreu5ko+FhEbIzHHGrlMlB1H9zZKEEQP1uczDwZ6Qm7yLHQ0YRcqUZx0vflaPThN0EvbZzE0RZanv0P7Z0j/XVJwL42UmiqXmNT/6diyY4ZZOE/FbjOpmGSKDH4MSk+uphPS22aM/Z8mm1gxgpUjztkJWI/kDaFiuXnNeDDM6+712wIXheXiA/PEaOXGmS3BRq9kHoS8y34Yzy3b+8Jbv8Yr2CrQzgsJmidXV+FfnWTK5ldpmkO+DPSvBHKLdEVhc5qFJ5AcbETCLObxgQLkgQRxxfeGNPoafwPXwRHwTW9Bwc27oei2dHceJLEE4bqROj5GJAsNbqzRqS6qBj4H6s09P/bEkcsV/xwXZTFvbHPeNG3qlH1F3Gbx38YOcYuQdlLffuNv2QaNW9zkPTo5y9XIHaqsG8oKWvRo0EEUPVw3TfTLqTDnGZFR3FNTN6c165viMpK4dV1wtgTnz5weYhEy0fYcFa9RUh0C5t2prurrbfWR/U7Wn2lexjcjEu0HlDgX/JCLRkrQXDrbacX1DYBM85cML1NrAoWCg7TQIMZrlHiDm3LHQWLnXWWPbbxMbITBHDvuL3AWpMOnlW1tsUNvaJV9tO0ZDZYpk3rJotVcmdlHthZWQnriUUPCyyOkx88dOIs5RGDSYBk5hlbjUnz+gE1QJX9710cGXlR2DAIsFaqmIEU5trVn9+rJgRMn9GzYucozTUJDLOMJ2/OCwshm3Y/XzjCuUsULaR2kWe6HlWFPN2+ys2FzYk9ksxSvxopIn0C4vWcJbGBm6S4NoxyS0eyCPhoOsss7Oici1sg2di7euJKltlbsHrZ65fPqraYFRTurnKLj2ta8r+Eiovf0IOit/dD9wjXSKdH5/yqxeH6JAMtSlyPLp81blvkJvPyDDb7J9Lb56vYz0zXpmENPjre9tWTCFnL+E4Qa8nQuuT59Z7ga5sMdn9XyK8uGF/b/nBBJwzl9rX+C+6ISNvjBa+5FQf37d5WUAZw3CZ1/R+f0hs3o9iKpC5HyZ0GfAO5XbinQ/IWOf3/XGkzeZrwo+7/iYccnWd3Tb99u2h56FnSmoCRsIgc8cmzVLEwh+Q/pYqZvh3m1EiUOJToIZMc9+SRJZWEyb7p7hRbdeEPzzsLUhohODq0A8CSjFMYIVh8eIcIx8DK0ZUZcW6BCRBQO5ZYBAZcrP1GXfkO6snTFPN2YMSUVjZPhyWmeuYVwLOl+9NR+8s8usQpLexB3tYlwilCcL+PXgDv6OYJGAlUcllwp6rCXYhVs6FSzb//t2ZPe0YcuR/+hgeDEjogoTDf/oGOrCLj8QMAM+PxiH7whAtUeod8rOlTucosIfkYewx+nE8t4MWHrGBxlLuHdVe5gUTHo7ns4m3zTeXKu1dfuBCT3magU7Ll90dhOP0zb/XeAyGZzsR5wpjOZxQPA+kCx47bcU9hZh0+lgaukKm5r9zjm93It/zFeS8PXozcljvoW84UEXcupDehqgxen3tj673dy2Pbtbog3WBkxNbBedwyjepZtlQ8cGrSUbqjBD3ldlIeNP3U0/YfbkPya5wJk7pMekm+J/187R9gDM+xkbPOjJmcdxfDsMvm8hL1feyyr697o4sSo80e5YLZmQJWvBJ5lqBt3O27by/X7jpK3COPcl40MsGs8HM+EPPDHZQz380fQQgHBxJ+lwAliDX2AR3d9W+UGJDSxDCfddwyDm9FLz9Yv+LE38+C79HBWZMJRfWCuoCAO+ZuWE57zfBDXGYAivMbHxB3LsoRnl0/b4dNlOs4lwtamqb8SR/4MnSRWqvvjzDPGmXE5Hh2L+SNXEkvL8KQ/6tDZuMyC9b23Jnt8fME0ixenVfQLccquFVNzqLQKlLPQKF1jyUFa66whp4nqjFpI+D+JOmzftQu06Tkiyf5CG8cbPZEm3tXZC81ydIU7kMKxXS3LyF/jyONxEq4AZyvfu7uZu6AotX7h9S6d76XSee9xeYh0dA43I71Px4EPObxqghkHbNZJcKfJ3NbVzikCCcm9RDz+tPpZkpzZAanpaeuDauh/9IGp2GVRjbssW7+/QEOE8b+m+Jr8dzrBtC9T05J4ssP3E6O3xEGJKgK8hmrzumyshZPfkieV2z78NO5pW5Yly8Z7eBfXxy8fn7BqWrBVn1h0I4CVrjcI1SIV5ELO3x+yNN+cWJFqgqrMuYIVP4r+DMlXaFumzNZg0ds+C9bf/ipRZBsrhrn4b96dEfYbFfpeGQC0iMYIClsCWH0ly8kRIA5avVnLbQGbOhttlv9rmCMRp5otr+Dle+U+Kgn5c6QHTjEyn9FWPmZvU4tuV7pqLUuKvjdDeRjAYN1y3TudtWFxUXrfzHGFdl0GdA41wdwk0tUQfDgxFu0OugkxGrLh67aXqnx7FFQ3lnTxyWRWqSi25uekFhJUKSjpLA4HPRQz7IgzMM2HeJgmcqowpbckgY3DM4ZSg9nCEb43rEiHzU9wiu6kg3cQNabGsAuU3fKw+a7fT1wRhW3vbDeLeDvbeChcFjyQy6sXepZNTEnSCIOje4w6Q0qbn33j+Do7ZS8qmzwFPsE/gLI3bF08oVHKvTZ0Wvi8jYf9q1Era9A9c61/gVdraV1DeP9JEp+s+VDXtEqf/79ddfAp7YkALCyvf1C5XIct3c5/QOIKZeTYdCeXVTxaGen5rVkJ8lyCCP3h5oG349IYVRCFpg9niNDlj5cJUaxYtWBkflxlxf/+17KMyYpvkovw7ScrCupBT9jzXEh0x8bR9bYXzl1tHg8rn5yG8fw3i8LZczRIAHTsab4OD/RsHwB0eUBZ/4nfJVIe1WB4gML88uBFTEj0lKiTXpIKrNJs/ry3PuaJarFmJl/brgoH8wrgWGS4prtp9V8l2c21AWqmHGxi/d9UBfoL8jKPKF1rBm+s8jP5HcDWG00c8uGFz5K1ynJ3wlL3vjsNTEt+ySteJy9pZK8sz4Re/Unz10DVqXn7gjbeYL0WeUThbU0E0LrbU1MVjEWr6FRILxYAjEhsf5IHRBR2XEOwRNnVJNSbrM+VxBORsm5i6uqqm9oUNXBP8Cz69KnwvmioLiZTxE8m/YGMtCn4hmcTRfeh6y91F97Tk5QlnIff+vXqyHBPExhv/2POYfhsBcO8aCACgDOA7E85YcrV4YMADfv3kFIEOFOR7ExoDyIDwX2/D/EA3qxkzhes3FdFTuRhouWRB5QTch52B883hZ2t/ASCxX6CR2MXP3Q7vY1kzlCbS42Y1/o8EP07hLKBXZItzJb3E4mnCgcVLdNmBXk/AfV39BTzBQIfUpAUXXPfAR79ny1W0dDlKlGnQZcWvEDYnLLOss8+xG+2uSi1Px80UVxtFjXrt+g0atUP+zbBeXaUGHXXWRTd853t/2OImRoZcpcp1ueejDeHSQzPOKrscu97ujvoXdrkZ26SVSFWnVbdBw9A3OFQp/ZYGQEnY75o0bI8th/YyVlo7Q0kGl9D+yf9//+/9/8+p5H8qU2Epi5R5yixlmKKm4ORi8mTyRGrnvwyH4slgUpoc+OwDgSnFS6VSrXEMgIxX8OZqZq6FINJuGCqQf/4XikAJOo8yoAAVoAodc4+aFFQ06rkmXwGRQmJFcp1SpVqNWnXqaZNq0KhJsxZMiFZt2nXo1EWHrl677bHXPvuhBh1w0CGH9RnQb8iwEaPRMTJm3IRJRx1xzHEngnPSaWdMmTZj1lzqaJm3aMFZS84570IUs7noksuuuBqVWq657kYaNHNTXioWshzZhPE8suKxJ556loJ6MM+98NIra1ax6MWE5Ne8KZpxyZcff8ZMmDKDQenQpYdFnwGnxIkHAQAgANyu8pdUVdfWZFX/DADg5Ts5rf/+DVYV0//21HfdPTiAB7hSeYS/9o+8nTxGKsWp7ce3KndjxnZHZbklRiBUmbNsrEuRpqssXnzmtzs7NolnvwS/p3TlXOOP3Vjq+ahuXHnAODTp6wXRAdy1HFczzDtPDXvh0+4Xt3P73bzdnL/15snoowPuN9foyKPNTWGRsPiMw4V+Ti5VjnQwcHlB0MHM95rhyWEy4axffuNBQ+J78LiLD/+zrh3PM3dkutQ0ADcv4cExj9dS5rh5XPeYz22JGLF5Bpay4JkngjWNVQHkajwOuD0W9xAD9vxeUr/v0pij2NHkMVgMqsUYnJfwMnDcNgBAuHBgL/BxKXMWxbk8+SHZRIHasyPPQ+7nKmKdIRLkM11KR/j485kzFsBeKQv96iTk+YtefSA5H0YgI6AT32/XI+AFQg/CBqQSHgX3wAz8SOqyA84gtGD9+PLTziur/klAl12xwYd7VgEPFBAASCARHkCEqQBQDZjXgAABVIP0PbxerYEHADSmJ7hLhgFznUT0E7yPIsWqlMqTI1c5lkksdmzY4t4rJv7RMEwZ3FgWHuLziEx1inzOswLl9TIVxKwkzovIhZyqVGZjysrZLFMlYjNZRbbBwmdv6G4yTxExFlvJZiiDB+CbmWpTY+cAAAA=) format('woff2');
+}
+@font-face{
+ font-family: "dm";
+ font-weight: normal;
+ font-style: italic;
+ unicode-range: U+1B00-218F;
+ src: local('βΊ'),
+ url(data:font/woff2;charset=utf-8;base64,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) format('woff2');
+}
+@font-face{
+ font-family: "dm";
+ font-weight: normal;
+ font-style: italic;
+ unicode-range: U+2190-21FF;
+ src: local('βΊ'),
+ url(data:font/woff2;charset=utf-8;base64,d09GMk9UVE8AAATcAAsAAAAABxwAAASRAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAADYdvGyAcKgZgADQBNgIkAxgEBgWBdAcgG1gGEVWcQwE+ElO4G3pA8hc0hxm3NGG6/8up/ZE0IXYD5JQJQigjvFYGThf5VABWk9PS4bI3/ONOAHFwCxNLNbXr539uoRZZW+ctNHr4gnzB5NNGgyUgiUYiIVpoeKSemIV0+UJPp2JbqHYhnb3wk1sQkAQghOQtP1J7bkNdbd2Ed62zY/jbl7IRwEZmARslsNEiK5EsWQLPzxKrPgHLtGmDHo/hs7NS+Xn+USVA+usP7yneyn36YVUB3suHHEIy8suHT5i5YPm6rYc++unqkcbGujbHjdmW+gr7CLfIUzhDQQrTuo/XttSemTplzszcNcs1Oz5nh0pMmTh5MRQqbf/oY/vHXP9DXwMOnc+b3Hz+2LnfThD+zwwgPdH0l+igeGDa0qWNYv8HACGOdMgUgIAA05z1MbwnI0g7uUL+FqYIF3LQo5Iv2a/iQ+zRyAbZYCgzxI1xQxXa+fHrj/kaHEPZFrVvewqux7GHn9KcT1rZn20Eb6kijsRPNDgW19O+3SrbkYpj+JrH1/lxtNO4wRg3lBsMsmyo5se5i7plv6viO3ZK0b+ej61sX8G2pFQyH3N9SwqPp/WReDhSFpGXpCqD4FiOzz1xI67ZBFu1PBKOk0k143po33Kdj+FrKNuxom93Kh+L6zcddktLJNPE62GS9LJRTphiemktn1+bjYTi/ymyysn1LXgjzqexaCLksj8sR8mGSRzehAQhUE4EcgaFUOeSv1QH/ccea54exiE4nPZ3pfKMbELUzfwI1WZhz8mhRCwqbcaDKQ0n2pIUZfIYgfhvojG9KWEoNxhlWV+d84KtI5jCNop4FodrmtCIKldv3eZv8C3qmoO9vOdzard57OV6vdtur3Y63VarxWs2lX3Je6kNT/iLbRLZj2y3xhvyBgNlfrffcbFKseu9et3r8p6m4FLUfcbf8Le39qCKahM39hoGxz+VrWyO5vOc8s1kLwlSCdcQ5qWoeyhVfB6lPBr1Kkr1pUtenwM7Q+5gVQP2Us9fKRWpxuw2WcssXttFR5Vdibqj2gTnP2ju5bpmfINv997mKlc/R+PSCM2R48nfE4sSvDWRwo/6UuU4+9ODOxNpvNYT8aSrGdcyVUVRkuuysq5FQxHF92NWdtI2uqgSgAY0CABkQIUqZPnK9dshDSQAgMFBAADACYw0mrBYzvkjzbVQwrRDrST8TBSgcpCYJbwDsHe15AuYOjthYdfuBVNNaip+PYBgECR9cW4PaCDMFbMa7CYVKrtIirIsEFmSQGuXbKRc08HBypbsnw0cCimurtT2sysP5c7/L02UfgEA+K3z8VP5dNPte4OjB/7f19JCEEAEQbNJfDyAvBmbGb7BLxA6PviHt3+eCEHIgTI7TbdTnrMaHXZaI9gMMgEgFfYSgUjpANAJzAoBCToVAQTQKyIAGEclnkKhjJGn6Dx9mTr1OjQ645TTmml9C1pTTTbF7Cs0oXVJ6yhXaG2uIJ+fN131vD7HnNPstBa1JtJa4jxjyFbehNATsv0Eba1Kx01c2g2ZnfCjmpxRp5bWFBNNTqsiwCCr53WbagEAAAA=) format('woff2');
+}
+@font-face{
+ font-family: "dm";
+ font-weight: normal;
+ font-style: italic;
+ unicode-range: U+F8FF-10FFFF;
+ src: local('βΊ'),
+ url(data:font/woff2;charset=utf-8;base64,d09GMk9UVE8AAAJwAAsAAAAAA/gAAAInAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAADYIOGyAcKgZgAAQBNgIkAwQEBgWBdAcgGzMDIL4Mb4gcpY8lI6bRFpuvq4/OWEUk/8G00RY3bzZ45QTP/4/7fp977/hhqDRrEowk18nij7AjlZhdyoMv5jaxZE2Bj3goRCo0jjQxTYTacALb/XAD3u4CDzHDKgCagaf4WPsskuLqgQ3PZuX/n3qBs2kmff9/N/kG2b0PAne7CZpHlGAY9xJq09hCASUSoGTuSs0f2zl4eIgSJghGISKxbXaRXsuiPBy17rvw/Wa3uNuCe5R7qd2i2WdRPsGis68g+3ZpyKuftUT4Ml8LiPrqLUz7F5d4lxWHEbH1TwVznkJxQVFRUcPp5HpB22zRiZu6iSW3/FDmps8biI7jmrPj9tdyRFd98BQsNBZBEBFl2zjn+X2+8fxv6Xy4zzkaIU9y/93vGj4f6Sv2n94f9TP6mJ9Hjhzx9Fp4eubk6SNHH1qsnnViFoQdT0KAaDJlk7aOyw1hMAChEACF5cmnyrGLc12BiEREu1GP5QhhGG1RP8C4Wq3coCSGCSj319jF//XtoAt9W6KaQI4DVI22ALkMAAIIJP+TmbHrYDBPAH5p8KtXb689cwMKjQJAQH8K7tVQaL38SkDoDwAARJ3ABkOIABGM44iJAtYQEwTDGigUW6CBnayhJWGkZwXhRfafy2pu4jDqwF25ShQpVrUSDJE05ZqfwVAUZ+7L7O+kXdQXR7maswwqDVrA81Xk1w6+d1Rg+3GHm9q4LECxAkXRaxpCbqELSggA) format('woff2');
+}
+@font-face{
+ font-family: "dm";
+ font-weight: bold;
+ font-style: normal;
+ unicode-range: U+0000-007F;
+ src: local('βΊ'),
+ url(data:font/woff2;charset=utf-8;base64,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) format('woff2');
+}
+@font-face{
+ font-family: "dm";
+ font-weight: bold;
+ font-style: normal;
+ unicode-range: U+0080-1AFF;
+ src: local('βΊ'),
+ url(data:font/woff2;charset=utf-8;base64,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) format('woff2');
+}
+@font-face{
+ font-family: "dm";
+ font-weight: bold;
+ font-style: normal;
+ unicode-range: U+1B00-218F;
+ src: local('βΊ'),
+ url(data:font/woff2;charset=utf-8;base64,d09GMk9UVE8AAAsQAAsAAAAAEVAAAArGAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAADZp/GyAcKgZgAIEsATYCJANCBAYFgXQHIBuKEACO0xV3IEmSe0c05/9ekrsEyk8lPUoDXK5mnpohngqaBNGKEVwimNYU07a0Dv5E6RObSze/5SH/9u5+lMBf4FlUW4YJhFESSNAWUeABBtb1+7W6D/coHi000caFQieU++/MG3g+tYRpKCbNZPo/krili6RKyB4akRoZMjmgIZ2t37uCGbUBgiAREYR4s6Pn2T1enl5znmmFY0+5mZuCuKkWiJvG46bzubECPNqCz2jRpX7RV40mYMNCGIkLbREy2z3agpeE/JGt88H+N42B3tFIHARlLrGZOH3u4uVrdt5I1e477+ru+My6/v4uCtePCRYeFfr+js4qpetRX3P/L5Hg6XrU7ZyC9W1SGdedChfMnU+qAJCdmu58asZDffgbv+G77vrKzzmf/ZkEjL/HgMgu9Pv3czBkLqsdWFaMNkJEXEPIz75hYAOIQAUK8Ad1mHcgJQT+HmcDOSM2hNIRI5+4IURsIgLPQUqXPfWZWE5k8kieNy+d18X7i7+O3y8wEywS7Ba8I8eR9VSJ8Jpoueiu2SazAnMr82DzTyPUI+6INX1Giz7i/u8c9Tv/LmdN4znNc+qOMxPnQNjPlGLG73AcfN9/++n39/OxFz4+e5qbLHV+Vlj/tOVnmC2FdGwBk/BqKjbH8smlM2JI7Cd+4rz4XD3k0FqNPqmQMblFUGqN8qIXw7lRYkjrIoyj4QfaZFzOGSmxsdx/DGSADMtgoUQrqYEM7h3tonO/U12lv627rAtJZ9Ka9e/i0vfkWKnUB9iwnaLrVyIvXZKKjbrS/pdhIUdmzv4yl0BLtG0BWm3Dv2kd42MSohKSpNWqKkdXN6WTKkGVEcJIasL3KTdcCRWJ8UIo2yUMgP3YBmzOIwBb0g1epERryHzxTWF7fFJsSnS66FFoyRF7Xz/7wNiQxAhtqNrvsfVSmKjfWhvhI14IKdRVB37m3tKuwq9Sd8dNG+qW2uIXn747Qq0+OCEULssvSvEqy6xQIY5irIMutWYGQBtL4CNuBKYImNGhF+KCddp6t8TEKHWVg6u7R3qo494xwKssJdrsQ4rxYrjbnBeekHdu/X8UlAnq+nOxWEOuxqjFDwfGQPX3kipuNPeKlsjBaQp2wrKZIDP5/Mn5wJRh4aJtahmAvQPESMIHlvOhQYbXTDArHHv8CR7SX/EUWLOjehnVWFJi8ITjBKgWxLfsoneWKzray8vV3IryXbs8FLsYcQjYEu/A5olkP1HkY70hvZa2M/jdv2cwiGI/g/0BrsHgvZZ2+nj3+/oIpcHO3s+DM/N6cM/D3m52cVgD7HhGFL6GaV16z975XKVxC23ywcNvTnG+8Ik07fz/ZHqwvfOboT3Nixfv3SeP07pzSBbdRZ8KMDQ3ZusePMpRyvcH+J2WRXK7M+dvWrxonzxY39zkJw9QGkC96QM9VK3jIsptOwevUtzOORCwG6L53Bawojd3e95U3dfdK7r5qseu02rrnjXLDiyvX9q99OVe0Yr8fwTIa6dftnQP1g8e6F8zsLXVbofVq1VFLjp7lZ2ny+bVIvEAt5zI44DP9XNRtKkRf3myn2vkhKQ4pAf2dP3eBeoe4s0v/D6IpPGSkp+mAWMNlmD23Z+5MkxkkPKI7YfXWa861ASEUgbnqYQ+EodTkZmazCxpqiY1KoWBgATot1d/CmhtY3evdUfN8Z3Zsn9LyGHPyd2YsMbSKdgc7zwnO0pdXk4+oSLDNGFh0hBNSFQI40BdXkGK4SdunKaGAGnbv21g18Y3GLX0jv9Mo95xo37w/S2gTtiOZWQL1Qy2JK55zx1YLfRc7b7Z77TPA7dX57pF4pAa0D15AaDxHwPsc7Budm4E8ya3Fkl3BOcXQvc33a675V123CCT9KDyM6esUvrsZNWWTXaKQ27aM5VqRjIcccLPS+EiPdzo1M2YbMGB5so54mi1qRh/IRO57fTd+NLEnFQRzn0OsEsY4HtGfeSCiNtjek0/DSr28ZV6nws+ftw7syCvMP9xFiPpQfJfSOflZ1eUGYL8lAFKtyDGOVulz5X2V+N13T/PfqvT6mtdu15rdU6ftbl/rsmK2c8Jt3Nyeuh5VetNv1KPLJnEpC3Lyi4uk7Zsrd5y+kTguUCm2pU0ZOQnFlrfqrjkfsZLdVB2/mgxJcFsU4naWeF14dRpdUqJt8z+LOlQXK1qt16BL+8FCg7hGTS2GvDOLCP5XJMNu6CS1zeAwL8Y5Hhh3YOGtULzokDkBPLcwSEbxJ1LJ7ee7u6qfdctr9/irb4UESpL7CBhcQNWUhKj3B/LyTaq2JVkpualF1nfz/M9dPys6oTCKyXfS+bkSCru3Q28Z43H4sP0IyeUg5PzTFsORvNoWEhLwAGbkwzj5TMAK3FE45iPb+EALJkRfumh+8radc5I/lN8o3q54HqjJQ2nqGD1pYtB/vu37N0YOUn0looabuqq78zR5+oz9aIaXCWMNFXRjxy5co53tJrEa0zZB0nb/lP2VjfIjRzkwzTL76gakOo7sjpzFhatrJwt+o56BvInIAdX6UwKz1VjqQcex5z9Sfku+DfRLCpwus96j7miszBOBVKYK51FYdcHWO5MwkC5cTx9VozPmvvJ8HFLjvmFy8QazqSB5WPuD3KTBiVVMM7ye6p6+D6MMPyum3YPj6icKfqeknjXwIG7nAScOzPfgmDc7I5nMEdghup96Fu9h5D1fusO42kiBUwPhWZYIJ1BSaqw8x2TZIQDnQV8nn/ZkMqxL7d3/NffGsfREA+TjwzhcLyKxNzue+PPrX45YP7VxsIwPLmi7fsD66D2cyB/5H5Y/5NLP3T+QMD+T3w4AK30xW3KjYdXihZzJ/rw38LHH/Qfkt6IYDsV30/iHVS0JjpamqZJi0xjYHO8314qRjNGGhmviY3z3UOqJilB+mP5neYHT73tSpiWJrLdY8fNpdZ41JbVeEKgJiAqUDaVurKcBD4VGhUSLJ0QgeGvdTqe8ZPjMJQNjwGzYUka2MIyGi8bFgnhqlBy7EcctvwpVNtK+4SroRSGh017Etdm0u2fJxSHZBh7M9dlYnUmhZ3ihVFr4fo1cCRThD01qRqzLvP6EV1x5EZvGSdZWNSnxibGxSflWfzPOH2sLULkQSMCQuZsMIh56+5DSETwceyOiJEnaqrpeFMTL45KT2SVE6FCQT6mYkT6UxQL3kuE0ImJiQstjCOI5BABsSRIWyMm2PELv4BMxL8Js/UIJUYg3sC34LFtcngG8TljfTzC+gukFTFGxR5MXK+wY1kpy7AT2ansfHYlu5nNY8smTJwwdYJdby2ZlZWwVqwNS3AetMLZ4HDyuQ78PjA88OvALwM/DvQPvBvoRGjArf/P/p7+B4jA4FmsWNuyYU1qfEqEDIMgdpuy/DIT7Ueu/lfEF1QhhFBPUGOzf+ULT2q/fv3yySxG8AER+Hj7twX/+QIoqpXncPtqIkwNZH1EJiG5WU6zCgr9gb5DFXQaRa1vCO1i7b5v0XiWrEw12SRfxTKzzHEO2gfJIRZCQifwEY0ZQigICscQBIJieHjCYvgQimgqyFdBkqbxqDKH38SLt0C+FNx5UGIVYy003wLLO0kIu1KWk0CrK+dB4ZwguLYJOTtLGS9V8TTXwgaco2qtPL8YjqsfuXLUpsjFXIrCJUfEE6mJFbx4Yi3gzRcBfKgAX7PQQggA) format('woff2');
+}
+@font-face{
+ font-family: "dm";
+ font-weight: bold;
+ font-style: normal;
+ unicode-range: U+2190-21FF;
+ src: local('βΊ'),
+ url(data:font/woff2;charset=utf-8;base64,d09GMk9UVE8AAAUwAAsAAAAAB1AAAATmAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAADYgiGyAcKgZgADQBNgIkAxgEBgWBdAcgG4sGAI7TpTZgEnN0/bdZ/WbmEV2iJA6zYsqmkhMnIk5BTAcihkUMkpy4sKwZOZW/86+rntyLICrXkQ0QR08+dWrm0gQ092BRC9DqXtSrFmhMLHCpwL2epzzWACpGhKqRXuEpp/dUeAUCAgeEEGVSsaH2AaPBuPtMK1N7Z4K8GeQtgSBv5eRtvBwusJBAXv0Y9B08uGa1Cq8P9LGwZ+MB/BzxAMI3FN8NuvJ/Wyh+GAJKQvxDYjftPnI66b6Uwkdeeru4ocHYGjOaaq4brORYs5kiqzHz43HWWGZoNlQf2H/8SMsd5Y5Fjq9N5ffv2QcdWSrnbSvN237wz3wHOHNnXr9OX1r74QSeH2ZgOI82/g8dsxCCYs+IPs2/AICQIT8I4IAAB1odPoJ/yf3kNfI7t4Mr5p5UvokvJnrtWBYaZvbgd6pOqUvqipGme1xmdViRfcQxYrfgMKuIct9ip1BD5VM/LmsVqEUx6zZVWvExKy6G4kfesCLcgU4ViqilYY8tJ/4on/VBDTt1y82q0EpdZpOrO7ZL6uqUNKyMWanyTVnL6ry441JomBkvyeUqPMNEuqw9Lp9SsJNM474Lh7CChhXZbQ673e7rmpmedsbMdTk7nWpmwTKqHG+Rf2sl+M6PPL69oOp0OjvnYl2zrrkZDVah5S4307BTVE44vpzkw0TU3plFld9ji85rxnvIW/ilSjJJZilGmu6d7VE7hh0jjhF8gJ2Jct9k3L8UryoYt9V9Nz6AZxx2dKEjenZ6esoZ4zTNdM+qWTomZicht5Wy6wrk/s1epEpWu7RgRRPBj7z8P7JbtZiFgRhFV+72YYEYnZSJmayKSrMzkjPWOTU9O62xOUYddgemYHHUXW4WwKLp0t0+GMCibrlZChYl61cc0c6e3ikpVjKbuk0a5UU5nSAvZ/LYhBtUTWhEDzt34SL7DD9DfcvMr+zLJ+nggG0wtnKwv1JjG7IODsY8w76ing/9W87i5ffkDJXDxzZlm5iMmbJM9Y+pbRY60S/ZuzrK4sC+bJw5jPrH2Gc444IOPXiuiRl/lajyciAfvVs+o3qCGZkHPck6/Iy5mf5x8yH8somOjVvGYp9acDw7YZmxTGnq8UuvdqJHCOivGrIOWgbVnPNwTI9tYGxA3T/hGnH5pWwuxC+fMP/G9M34GbqTLzIP8zyBxiMuquyaW/phXjvPWuYVrGTcp2tO/smKGfO+zGCdtfp5/T0B3rGxsTeXNgYGemZHJ8fGp54KXLe0LTwegE6qgACAP8RRI0l33p8GviAAAKytAXjcqFtsww2m1Bc3GSDKJQ15gfsI40B5DR/I3QaAnOGSp+BAMmChxbPhsfVj6138s6sI+GeJ31mASQAA7gQfCABinAFuoPlAOBcivCyASAsUKa3/tbWaWuqnejdBqM1hrcZr7S0MOvWfLy+8BgDwfceFS/zsno/da2urf/s5hG+AAA+czwr+wiqy+etcSGvLPYAAfJ9wU6ATLdkByYKglFGJEkagAwEA4AM5eCCCHwB0ABkQEKADcMCBBHgAMHcL7ooUYmwhhZ/zExnVadegWqUqTUTPg+iAffY71jDJpONEJdqJdKpU09er6i1DqVpNqjQz2EOUQO+iM9RQoyZQztPlgZahUGYP0qZkBv24RtWMDET77bGvVngAHWsLcAAAAAA=) format('woff2');
+}
+@font-face{
+ font-family: "dm";
+ font-weight: bold;
+ font-style: normal;
+ unicode-range: U+F8FF-10FFFF;
+ src: local('βΊ'),
+ url(data:font/woff2;charset=utf-8;base64,d09GMk9UVE8AAAJ0AAsAAAAAA/QAAAIqAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAADYILGyAcKgZgAAQBNgIkAwQEBgWBdAcgGzADAC4D7IZjzymg62laLb5im9YqKYd4pp0IH5Q4wfM11t7f3RNPmCSGpIkh4c2yaCYkPItas2reuIZYSNQTM2Ss3ZtaSFrNsPSi0pFIpbFOplQSozQTgtx2D1DYR6JuhAypGLvREA2A7uApPgY1OYgeC8Ayvq0tfgCOy3/OjT9vz2+AA909pwF9/n14lic0TDDgLsCov3cD7HJP9eTYIyKzTeFwCA8+E4xCRLzVnb12vN/reyL9TgUEkfJgglcieJcPbf0Qt29BkrLv8J7zzxfL3bbhyD1wjGfBvFlGfC+BrvfzhBHx1jVXVjwp4PWnrNv+wl6+cBzQyXu6yQ23capTbj9uoPHOagFvx3+WIwca9UT0znIXQESUt2/589nB/3tmaqS0NLrz8cJ7wfRIj9sRh9955/JPstfOQqZk3y3czExOze66PSH71ADLTBIBnGTKJtW1sRzoGIAEAGBYnnxqGre7c9KDHAkko875Ih2j3eoVNMnzyi47CgTI/R/Y5O+BdBB/hz4QRzmYAVQZiQ3kMgAIIPD/xF1r5/lKD3MM+Fw1wOfx8Ya/07h5I9AoAAT0Q/wvR2PC/4+GwJWJmuVBIwSw0URCjAPogY6CoQcVigHUwNDQ4DoL6WWVtc7zaH+wHDXrjYnekaVEkWKlS6TJfCtX11KvsdHs+BudH+X2pDHteZVAhURkrVZjS6jKUF2dVSteBQb3BfvWuNnv6RUrUMSpBo7ENgAAAA==) format('woff2');
+}
diff --git a/docs/md_v2/assets/highlight.css b/docs/md_v2/assets/highlight.css
new file mode 100644
index 00000000..e69de29b
diff --git a/docs/md_v2/assets/highlight.min.js b/docs/md_v2/assets/highlight.min.js
new file mode 100644
index 00000000..f43ba9aa
--- /dev/null
+++ b/docs/md_v2/assets/highlight.min.js
@@ -0,0 +1,1213 @@
+/*!
+ Highlight.js v11.9.0 (git: f47103d4f1)
+ (c) 2006-2023 undefined and other contributors
+ License: BSD-3-Clause
+ */
+ var hljs=function(){"use strict";function e(n){
+ return n instanceof Map?n.clear=n.delete=n.set=()=>{
+ throw Error("map is read-only")}:n instanceof Set&&(n.add=n.clear=n.delete=()=>{
+ throw Error("set is read-only")
+ }),Object.freeze(n),Object.getOwnPropertyNames(n).forEach((t=>{
+ const a=n[t],i=typeof a;"object"!==i&&"function"!==i||Object.isFrozen(a)||e(a)
+ })),n}class n{constructor(e){
+ void 0===e.data&&(e.data={}),this.data=e.data,this.isMatchIgnored=!1}
+ ignoreMatch(){this.isMatchIgnored=!0}}function t(e){
+ return e.replace(/&/g,"&").replace(//g,">").replace(/"/g,""").replace(/'/g,"'")
+ }function a(e,...n){const t=Object.create(null);for(const n in e)t[n]=e[n]
+ ;return n.forEach((e=>{for(const n in e)t[n]=e[n]})),t}const i=e=>!!e.scope
+ ;class r{constructor(e,n){
+ this.buffer="",this.classPrefix=n.classPrefix,e.walk(this)}addText(e){
+ this.buffer+=t(e)}openNode(e){if(!i(e))return;const n=((e,{prefix:n})=>{
+ if(e.startsWith("language:"))return e.replace("language:","language-")
+ ;if(e.includes(".")){const t=e.split(".")
+ ;return[`${n}${t.shift()}`,...t.map(((e,n)=>`${e}${"_".repeat(n+1)}`))].join(" ")
+ }return`${n}${e}`})(e.scope,{prefix:this.classPrefix});this.span(n)}
+ closeNode(e){i(e)&&(this.buffer+="")}value(){return this.buffer}span(e){
+ this.buffer+=``}}const s=(e={})=>{const n={children:[]}
+ ;return Object.assign(n,e),n};class o{constructor(){
+ this.rootNode=s(),this.stack=[this.rootNode]}get top(){
+ return this.stack[this.stack.length-1]}get root(){return this.rootNode}add(e){
+ this.top.children.push(e)}openNode(e){const n=s({scope:e})
+ ;this.add(n),this.stack.push(n)}closeNode(){
+ if(this.stack.length>1)return this.stack.pop()}closeAllNodes(){
+ for(;this.closeNode(););}toJSON(){return JSON.stringify(this.rootNode,null,4)}
+ walk(e){return this.constructor._walk(e,this.rootNode)}static _walk(e,n){
+ return"string"==typeof n?e.addText(n):n.children&&(e.openNode(n),
+ n.children.forEach((n=>this._walk(e,n))),e.closeNode(n)),e}static _collapse(e){
+ "string"!=typeof e&&e.children&&(e.children.every((e=>"string"==typeof e))?e.children=[e.children.join("")]:e.children.forEach((e=>{
+ o._collapse(e)})))}}class l extends o{constructor(e){super(),this.options=e}
+ addText(e){""!==e&&this.add(e)}startScope(e){this.openNode(e)}endScope(){
+ this.closeNode()}__addSublanguage(e,n){const t=e.root
+ ;n&&(t.scope="language:"+n),this.add(t)}toHTML(){
+ return new r(this,this.options).value()}finalize(){
+ return this.closeAllNodes(),!0}}function c(e){
+ return e?"string"==typeof e?e:e.source:null}function d(e){return b("(?=",e,")")}
+ function g(e){return b("(?:",e,")*")}function u(e){return b("(?:",e,")?")}
+ function b(...e){return e.map((e=>c(e))).join("")}function m(...e){const n=(e=>{
+ const n=e[e.length-1]
+ ;return"object"==typeof n&&n.constructor===Object?(e.splice(e.length-1,1),n):{}
+ })(e);return"("+(n.capture?"":"?:")+e.map((e=>c(e))).join("|")+")"}
+ function p(e){return RegExp(e.toString()+"|").exec("").length-1}
+ const _=/\[(?:[^\\\]]|\\.)*\]|\(\??|\\([1-9][0-9]*)|\\./
+ ;function h(e,{joinWith:n}){let t=0;return e.map((e=>{t+=1;const n=t
+ ;let a=c(e),i="";for(;a.length>0;){const e=_.exec(a);if(!e){i+=a;break}
+ i+=a.substring(0,e.index),
+ a=a.substring(e.index+e[0].length),"\\"===e[0][0]&&e[1]?i+="\\"+(Number(e[1])+n):(i+=e[0],
+ "("===e[0]&&t++)}return i})).map((e=>`(${e})`)).join(n)}
+ const f="[a-zA-Z]\\w*",E="[a-zA-Z_]\\w*",y="\\b\\d+(\\.\\d+)?",N="(-?)(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)",w="\\b(0b[01]+)",v={
+ begin:"\\\\[\\s\\S]",relevance:0},O={scope:"string",begin:"'",end:"'",
+ illegal:"\\n",contains:[v]},k={scope:"string",begin:'"',end:'"',illegal:"\\n",
+ contains:[v]},x=(e,n,t={})=>{const i=a({scope:"comment",begin:e,end:n,
+ contains:[]},t);i.contains.push({scope:"doctag",
+ begin:"[ ]*(?=(TODO|FIXME|NOTE|BUG|OPTIMIZE|HACK|XXX):)",
+ end:/(TODO|FIXME|NOTE|BUG|OPTIMIZE|HACK|XXX):/,excludeBegin:!0,relevance:0})
+ ;const r=m("I","a","is","so","us","to","at","if","in","it","on",/[A-Za-z]+['](d|ve|re|ll|t|s|n)/,/[A-Za-z]+[-][a-z]+/,/[A-Za-z][a-z]{2,}/)
+ ;return i.contains.push({begin:b(/[ ]+/,"(",r,/[.]?[:]?([.][ ]|[ ])/,"){3}")}),i
+ },M=x("//","$"),S=x("/\\*","\\*/"),A=x("#","$");var C=Object.freeze({
+ __proto__:null,APOS_STRING_MODE:O,BACKSLASH_ESCAPE:v,BINARY_NUMBER_MODE:{
+ scope:"number",begin:w,relevance:0},BINARY_NUMBER_RE:w,COMMENT:x,
+ C_BLOCK_COMMENT_MODE:S,C_LINE_COMMENT_MODE:M,C_NUMBER_MODE:{scope:"number",
+ begin:N,relevance:0},C_NUMBER_RE:N,END_SAME_AS_BEGIN:e=>Object.assign(e,{
+ "on:begin":(e,n)=>{n.data._beginMatch=e[1]},"on:end":(e,n)=>{
+ n.data._beginMatch!==e[1]&&n.ignoreMatch()}}),HASH_COMMENT_MODE:A,IDENT_RE:f,
+ MATCH_NOTHING_RE:/\b\B/,METHOD_GUARD:{begin:"\\.\\s*"+E,relevance:0},
+ NUMBER_MODE:{scope:"number",begin:y,relevance:0},NUMBER_RE:y,
+ PHRASAL_WORDS_MODE:{
+ begin:/\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\b/
+ },QUOTE_STRING_MODE:k,REGEXP_MODE:{scope:"regexp",begin:/\/(?=[^/\n]*\/)/,
+ end:/\/[gimuy]*/,contains:[v,{begin:/\[/,end:/\]/,relevance:0,contains:[v]}]},
+ RE_STARTERS_RE:"!|!=|!==|%|%=|&|&&|&=|\\*|\\*=|\\+|\\+=|,|-|-=|/=|/|:|;|<<|<<=|<=|<|===|==|=|>>>=|>>=|>=|>>>|>>|>|\\?|\\[|\\{|\\(|\\^|\\^=|\\||\\|=|\\|\\||~",
+ SHEBANG:(e={})=>{const n=/^#![ ]*\//
+ ;return e.binary&&(e.begin=b(n,/.*\b/,e.binary,/\b.*/)),a({scope:"meta",begin:n,
+ end:/$/,relevance:0,"on:begin":(e,n)=>{0!==e.index&&n.ignoreMatch()}},e)},
+ TITLE_MODE:{scope:"title",begin:f,relevance:0},UNDERSCORE_IDENT_RE:E,
+ UNDERSCORE_TITLE_MODE:{scope:"title",begin:E,relevance:0}});function T(e,n){
+ "."===e.input[e.index-1]&&n.ignoreMatch()}function R(e,n){
+ void 0!==e.className&&(e.scope=e.className,delete e.className)}function D(e,n){
+ n&&e.beginKeywords&&(e.begin="\\b("+e.beginKeywords.split(" ").join("|")+")(?!\\.)(?=\\b|\\s)",
+ e.__beforeBegin=T,e.keywords=e.keywords||e.beginKeywords,delete e.beginKeywords,
+ void 0===e.relevance&&(e.relevance=0))}function I(e,n){
+ Array.isArray(e.illegal)&&(e.illegal=m(...e.illegal))}function L(e,n){
+ if(e.match){
+ if(e.begin||e.end)throw Error("begin & end are not supported with match")
+ ;e.begin=e.match,delete e.match}}function B(e,n){
+ void 0===e.relevance&&(e.relevance=1)}const $=(e,n)=>{if(!e.beforeMatch)return
+ ;if(e.starts)throw Error("beforeMatch cannot be used with starts")
+ ;const t=Object.assign({},e);Object.keys(e).forEach((n=>{delete e[n]
+ })),e.keywords=t.keywords,e.begin=b(t.beforeMatch,d(t.begin)),e.starts={
+ relevance:0,contains:[Object.assign(t,{endsParent:!0})]
+ },e.relevance=0,delete t.beforeMatch
+ },z=["of","and","for","in","not","or","if","then","parent","list","value"],F="keyword"
+ ;function U(e,n,t=F){const a=Object.create(null)
+ ;return"string"==typeof e?i(t,e.split(" ")):Array.isArray(e)?i(t,e):Object.keys(e).forEach((t=>{
+ Object.assign(a,U(e[t],n,t))})),a;function i(e,t){
+ n&&(t=t.map((e=>e.toLowerCase()))),t.forEach((n=>{const t=n.split("|")
+ ;a[t[0]]=[e,j(t[0],t[1])]}))}}function j(e,n){
+ return n?Number(n):(e=>z.includes(e.toLowerCase()))(e)?0:1}const P={},K=e=>{
+ console.error(e)},H=(e,...n)=>{console.log("WARN: "+e,...n)},q=(e,n)=>{
+ P[`${e}/${n}`]||(console.log(`Deprecated as of ${e}. ${n}`),P[`${e}/${n}`]=!0)
+ },G=Error();function Z(e,n,{key:t}){let a=0;const i=e[t],r={},s={}
+ ;for(let e=1;e<=n.length;e++)s[e+a]=i[e],r[e+a]=!0,a+=p(n[e-1])
+ ;e[t]=s,e[t]._emit=r,e[t]._multi=!0}function W(e){(e=>{
+ e.scope&&"object"==typeof e.scope&&null!==e.scope&&(e.beginScope=e.scope,
+ delete e.scope)})(e),"string"==typeof e.beginScope&&(e.beginScope={
+ _wrap:e.beginScope}),"string"==typeof e.endScope&&(e.endScope={_wrap:e.endScope
+ }),(e=>{if(Array.isArray(e.begin)){
+ if(e.skip||e.excludeBegin||e.returnBegin)throw K("skip, excludeBegin, returnBegin not compatible with beginScope: {}"),
+ G
+ ;if("object"!=typeof e.beginScope||null===e.beginScope)throw K("beginScope must be object"),
+ G;Z(e,e.begin,{key:"beginScope"}),e.begin=h(e.begin,{joinWith:""})}})(e),(e=>{
+ if(Array.isArray(e.end)){
+ if(e.skip||e.excludeEnd||e.returnEnd)throw K("skip, excludeEnd, returnEnd not compatible with endScope: {}"),
+ G
+ ;if("object"!=typeof e.endScope||null===e.endScope)throw K("endScope must be object"),
+ G;Z(e,e.end,{key:"endScope"}),e.end=h(e.end,{joinWith:""})}})(e)}function Q(e){
+ function n(n,t){
+ return RegExp(c(n),"m"+(e.case_insensitive?"i":"")+(e.unicodeRegex?"u":"")+(t?"g":""))
+ }class t{constructor(){
+ this.matchIndexes={},this.regexes=[],this.matchAt=1,this.position=0}
+ addRule(e,n){
+ n.position=this.position++,this.matchIndexes[this.matchAt]=n,this.regexes.push([n,e]),
+ this.matchAt+=p(e)+1}compile(){0===this.regexes.length&&(this.exec=()=>null)
+ ;const e=this.regexes.map((e=>e[1]));this.matcherRe=n(h(e,{joinWith:"|"
+ }),!0),this.lastIndex=0}exec(e){this.matcherRe.lastIndex=this.lastIndex
+ ;const n=this.matcherRe.exec(e);if(!n)return null
+ ;const t=n.findIndex(((e,n)=>n>0&&void 0!==e)),a=this.matchIndexes[t]
+ ;return n.splice(0,t),Object.assign(n,a)}}class i{constructor(){
+ this.rules=[],this.multiRegexes=[],
+ this.count=0,this.lastIndex=0,this.regexIndex=0}getMatcher(e){
+ if(this.multiRegexes[e])return this.multiRegexes[e];const n=new t
+ ;return this.rules.slice(e).forEach((([e,t])=>n.addRule(e,t))),
+ n.compile(),this.multiRegexes[e]=n,n}resumingScanAtSamePosition(){
+ return 0!==this.regexIndex}considerAll(){this.regexIndex=0}addRule(e,n){
+ this.rules.push([e,n]),"begin"===n.type&&this.count++}exec(e){
+ const n=this.getMatcher(this.regexIndex);n.lastIndex=this.lastIndex
+ ;let t=n.exec(e)
+ ;if(this.resumingScanAtSamePosition())if(t&&t.index===this.lastIndex);else{
+ const n=this.getMatcher(0);n.lastIndex=this.lastIndex+1,t=n.exec(e)}
+ return t&&(this.regexIndex+=t.position+1,
+ this.regexIndex===this.count&&this.considerAll()),t}}
+ if(e.compilerExtensions||(e.compilerExtensions=[]),
+ e.contains&&e.contains.includes("self"))throw Error("ERR: contains `self` is not supported at the top-level of a language. See documentation.")
+ ;return e.classNameAliases=a(e.classNameAliases||{}),function t(r,s){const o=r
+ ;if(r.isCompiled)return o
+ ;[R,L,W,$].forEach((e=>e(r,s))),e.compilerExtensions.forEach((e=>e(r,s))),
+ r.__beforeBegin=null,[D,I,B].forEach((e=>e(r,s))),r.isCompiled=!0;let l=null
+ ;return"object"==typeof r.keywords&&r.keywords.$pattern&&(r.keywords=Object.assign({},r.keywords),
+ l=r.keywords.$pattern,
+ delete r.keywords.$pattern),l=l||/\w+/,r.keywords&&(r.keywords=U(r.keywords,e.case_insensitive)),
+ o.keywordPatternRe=n(l,!0),
+ s&&(r.begin||(r.begin=/\B|\b/),o.beginRe=n(o.begin),r.end||r.endsWithParent||(r.end=/\B|\b/),
+ r.end&&(o.endRe=n(o.end)),
+ o.terminatorEnd=c(o.end)||"",r.endsWithParent&&s.terminatorEnd&&(o.terminatorEnd+=(r.end?"|":"")+s.terminatorEnd)),
+ r.illegal&&(o.illegalRe=n(r.illegal)),
+ r.contains||(r.contains=[]),r.contains=[].concat(...r.contains.map((e=>(e=>(e.variants&&!e.cachedVariants&&(e.cachedVariants=e.variants.map((n=>a(e,{
+ variants:null},n)))),e.cachedVariants?e.cachedVariants:X(e)?a(e,{
+ starts:e.starts?a(e.starts):null
+ }):Object.isFrozen(e)?a(e):e))("self"===e?r:e)))),r.contains.forEach((e=>{t(e,o)
+ })),r.starts&&t(r.starts,s),o.matcher=(e=>{const n=new i
+ ;return e.contains.forEach((e=>n.addRule(e.begin,{rule:e,type:"begin"
+ }))),e.terminatorEnd&&n.addRule(e.terminatorEnd,{type:"end"
+ }),e.illegal&&n.addRule(e.illegal,{type:"illegal"}),n})(o),o}(e)}function X(e){
+ return!!e&&(e.endsWithParent||X(e.starts))}class V extends Error{
+ constructor(e,n){super(e),this.name="HTMLInjectionError",this.html=n}}
+ const J=t,Y=a,ee=Symbol("nomatch"),ne=t=>{
+ const a=Object.create(null),i=Object.create(null),r=[];let s=!0
+ ;const o="Could not find the language '{}', did you forget to load/include a language module?",c={
+ disableAutodetect:!0,name:"Plain text",contains:[]};let p={
+ ignoreUnescapedHTML:!1,throwUnescapedHTML:!1,noHighlightRe:/^(no-?highlight)$/i,
+ languageDetectRe:/\blang(?:uage)?-([\w-]+)\b/i,classPrefix:"hljs-",
+ cssSelector:"pre code",languages:null,__emitter:l};function _(e){
+ return p.noHighlightRe.test(e)}function h(e,n,t){let a="",i=""
+ ;"object"==typeof n?(a=e,
+ t=n.ignoreIllegals,i=n.language):(q("10.7.0","highlight(lang, code, ...args) has been deprecated."),
+ q("10.7.0","Please use highlight(code, options) instead.\nhttps://github.com/highlightjs/highlight.js/issues/2277"),
+ i=e,a=n),void 0===t&&(t=!0);const r={code:a,language:i};x("before:highlight",r)
+ ;const s=r.result?r.result:f(r.language,r.code,t)
+ ;return s.code=r.code,x("after:highlight",s),s}function f(e,t,i,r){
+ const l=Object.create(null);function c(){if(!x.keywords)return void S.addText(A)
+ ;let e=0;x.keywordPatternRe.lastIndex=0;let n=x.keywordPatternRe.exec(A),t=""
+ ;for(;n;){t+=A.substring(e,n.index)
+ ;const i=w.case_insensitive?n[0].toLowerCase():n[0],r=(a=i,x.keywords[a]);if(r){
+ const[e,a]=r
+ ;if(S.addText(t),t="",l[i]=(l[i]||0)+1,l[i]<=7&&(C+=a),e.startsWith("_"))t+=n[0];else{
+ const t=w.classNameAliases[e]||e;g(n[0],t)}}else t+=n[0]
+ ;e=x.keywordPatternRe.lastIndex,n=x.keywordPatternRe.exec(A)}var a
+ ;t+=A.substring(e),S.addText(t)}function d(){null!=x.subLanguage?(()=>{
+ if(""===A)return;let e=null;if("string"==typeof x.subLanguage){
+ if(!a[x.subLanguage])return void S.addText(A)
+ ;e=f(x.subLanguage,A,!0,M[x.subLanguage]),M[x.subLanguage]=e._top
+ }else e=E(A,x.subLanguage.length?x.subLanguage:null)
+ ;x.relevance>0&&(C+=e.relevance),S.__addSublanguage(e._emitter,e.language)
+ })():c(),A=""}function g(e,n){
+ ""!==e&&(S.startScope(n),S.addText(e),S.endScope())}function u(e,n){let t=1
+ ;const a=n.length-1;for(;t<=a;){if(!e._emit[t]){t++;continue}
+ const a=w.classNameAliases[e[t]]||e[t],i=n[t];a?g(i,a):(A=i,c(),A=""),t++}}
+ function b(e,n){
+ return e.scope&&"string"==typeof e.scope&&S.openNode(w.classNameAliases[e.scope]||e.scope),
+ e.beginScope&&(e.beginScope._wrap?(g(A,w.classNameAliases[e.beginScope._wrap]||e.beginScope._wrap),
+ A=""):e.beginScope._multi&&(u(e.beginScope,n),A="")),x=Object.create(e,{parent:{
+ value:x}}),x}function m(e,t,a){let i=((e,n)=>{const t=e&&e.exec(n)
+ ;return t&&0===t.index})(e.endRe,a);if(i){if(e["on:end"]){const a=new n(e)
+ ;e["on:end"](t,a),a.isMatchIgnored&&(i=!1)}if(i){
+ for(;e.endsParent&&e.parent;)e=e.parent;return e}}
+ if(e.endsWithParent)return m(e.parent,t,a)}function _(e){
+ return 0===x.matcher.regexIndex?(A+=e[0],1):(D=!0,0)}function h(e){
+ const n=e[0],a=t.substring(e.index),i=m(x,e,a);if(!i)return ee;const r=x
+ ;x.endScope&&x.endScope._wrap?(d(),
+ g(n,x.endScope._wrap)):x.endScope&&x.endScope._multi?(d(),
+ u(x.endScope,e)):r.skip?A+=n:(r.returnEnd||r.excludeEnd||(A+=n),
+ d(),r.excludeEnd&&(A=n));do{
+ x.scope&&S.closeNode(),x.skip||x.subLanguage||(C+=x.relevance),x=x.parent
+ }while(x!==i.parent);return i.starts&&b(i.starts,e),r.returnEnd?0:n.length}
+ let y={};function N(a,r){const o=r&&r[0];if(A+=a,null==o)return d(),0
+ ;if("begin"===y.type&&"end"===r.type&&y.index===r.index&&""===o){
+ if(A+=t.slice(r.index,r.index+1),!s){const n=Error(`0 width match regex (${e})`)
+ ;throw n.languageName=e,n.badRule=y.rule,n}return 1}
+ if(y=r,"begin"===r.type)return(e=>{
+ const t=e[0],a=e.rule,i=new n(a),r=[a.__beforeBegin,a["on:begin"]]
+ ;for(const n of r)if(n&&(n(e,i),i.isMatchIgnored))return _(t)
+ ;return a.skip?A+=t:(a.excludeBegin&&(A+=t),
+ d(),a.returnBegin||a.excludeBegin||(A=t)),b(a,e),a.returnBegin?0:t.length})(r)
+ ;if("illegal"===r.type&&!i){
+ const e=Error('Illegal lexeme "'+o+'" for mode "'+(x.scope||"")+'"')
+ ;throw e.mode=x,e}if("end"===r.type){const e=h(r);if(e!==ee)return e}
+ if("illegal"===r.type&&""===o)return 1
+ ;if(R>1e5&&R>3*r.index)throw Error("potential infinite loop, way more iterations than matches")
+ ;return A+=o,o.length}const w=v(e)
+ ;if(!w)throw K(o.replace("{}",e)),Error('Unknown language: "'+e+'"')
+ ;const O=Q(w);let k="",x=r||O;const M={},S=new p.__emitter(p);(()=>{const e=[]
+ ;for(let n=x;n!==w;n=n.parent)n.scope&&e.unshift(n.scope)
+ ;e.forEach((e=>S.openNode(e)))})();let A="",C=0,T=0,R=0,D=!1;try{
+ if(w.__emitTokens)w.__emitTokens(t,S);else{for(x.matcher.considerAll();;){
+ R++,D?D=!1:x.matcher.considerAll(),x.matcher.lastIndex=T
+ ;const e=x.matcher.exec(t);if(!e)break;const n=N(t.substring(T,e.index),e)
+ ;T=e.index+n}N(t.substring(T))}return S.finalize(),k=S.toHTML(),{language:e,
+ value:k,relevance:C,illegal:!1,_emitter:S,_top:x}}catch(n){
+ if(n.message&&n.message.includes("Illegal"))return{language:e,value:J(t),
+ illegal:!0,relevance:0,_illegalBy:{message:n.message,index:T,
+ context:t.slice(T-100,T+100),mode:n.mode,resultSoFar:k},_emitter:S};if(s)return{
+ language:e,value:J(t),illegal:!1,relevance:0,errorRaised:n,_emitter:S,_top:x}
+ ;throw n}}function E(e,n){n=n||p.languages||Object.keys(a);const t=(e=>{
+ const n={value:J(e),illegal:!1,relevance:0,_top:c,_emitter:new p.__emitter(p)}
+ ;return n._emitter.addText(e),n})(e),i=n.filter(v).filter(k).map((n=>f(n,e,!1)))
+ ;i.unshift(t);const r=i.sort(((e,n)=>{
+ if(e.relevance!==n.relevance)return n.relevance-e.relevance
+ ;if(e.language&&n.language){if(v(e.language).supersetOf===n.language)return 1
+ ;if(v(n.language).supersetOf===e.language)return-1}return 0})),[s,o]=r,l=s
+ ;return l.secondBest=o,l}function y(e){let n=null;const t=(e=>{
+ let n=e.className+" ";n+=e.parentNode?e.parentNode.className:""
+ ;const t=p.languageDetectRe.exec(n);if(t){const n=v(t[1])
+ ;return n||(H(o.replace("{}",t[1])),
+ H("Falling back to no-highlight mode for this block.",e)),n?t[1]:"no-highlight"}
+ return n.split(/\s+/).find((e=>_(e)||v(e)))})(e);if(_(t))return
+ ;if(x("before:highlightElement",{el:e,language:t
+ }),e.dataset.highlighted)return void console.log("Element previously highlighted. To highlight again, first unset `dataset.highlighted`.",e)
+ ;if(e.children.length>0&&(p.ignoreUnescapedHTML||(console.warn("One of your code blocks includes unescaped HTML. This is a potentially serious security risk."),
+ console.warn("https://github.com/highlightjs/highlight.js/wiki/security"),
+ console.warn("The element with unescaped HTML:"),
+ console.warn(e)),p.throwUnescapedHTML))throw new V("One of your code blocks includes unescaped HTML.",e.innerHTML)
+ ;n=e;const a=n.textContent,r=t?h(a,{language:t,ignoreIllegals:!0}):E(a)
+ ;e.innerHTML=r.value,e.dataset.highlighted="yes",((e,n,t)=>{const a=n&&i[n]||t
+ ;e.classList.add("hljs"),e.classList.add("language-"+a)
+ })(e,t,r.language),e.result={language:r.language,re:r.relevance,
+ relevance:r.relevance},r.secondBest&&(e.secondBest={
+ language:r.secondBest.language,relevance:r.secondBest.relevance
+ }),x("after:highlightElement",{el:e,result:r,text:a})}let N=!1;function w(){
+ "loading"!==document.readyState?document.querySelectorAll(p.cssSelector).forEach(y):N=!0
+ }function v(e){return e=(e||"").toLowerCase(),a[e]||a[i[e]]}
+ function O(e,{languageName:n}){"string"==typeof e&&(e=[e]),e.forEach((e=>{
+ i[e.toLowerCase()]=n}))}function k(e){const n=v(e)
+ ;return n&&!n.disableAutodetect}function x(e,n){const t=e;r.forEach((e=>{
+ e[t]&&e[t](n)}))}
+ "undefined"!=typeof window&&window.addEventListener&&window.addEventListener("DOMContentLoaded",(()=>{
+ N&&w()}),!1),Object.assign(t,{highlight:h,highlightAuto:E,highlightAll:w,
+ highlightElement:y,
+ highlightBlock:e=>(q("10.7.0","highlightBlock will be removed entirely in v12.0"),
+ q("10.7.0","Please use highlightElement now."),y(e)),configure:e=>{p=Y(p,e)},
+ initHighlighting:()=>{
+ w(),q("10.6.0","initHighlighting() deprecated. Use highlightAll() now.")},
+ initHighlightingOnLoad:()=>{
+ w(),q("10.6.0","initHighlightingOnLoad() deprecated. Use highlightAll() now.")
+ },registerLanguage:(e,n)=>{let i=null;try{i=n(t)}catch(n){
+ if(K("Language definition for '{}' could not be registered.".replace("{}",e)),
+ !s)throw n;K(n),i=c}
+ i.name||(i.name=e),a[e]=i,i.rawDefinition=n.bind(null,t),i.aliases&&O(i.aliases,{
+ languageName:e})},unregisterLanguage:e=>{delete a[e]
+ ;for(const n of Object.keys(i))i[n]===e&&delete i[n]},
+ listLanguages:()=>Object.keys(a),getLanguage:v,registerAliases:O,
+ autoDetection:k,inherit:Y,addPlugin:e=>{(e=>{
+ e["before:highlightBlock"]&&!e["before:highlightElement"]&&(e["before:highlightElement"]=n=>{
+ e["before:highlightBlock"](Object.assign({block:n.el},n))
+ }),e["after:highlightBlock"]&&!e["after:highlightElement"]&&(e["after:highlightElement"]=n=>{
+ e["after:highlightBlock"](Object.assign({block:n.el},n))})})(e),r.push(e)},
+ removePlugin:e=>{const n=r.indexOf(e);-1!==n&&r.splice(n,1)}}),t.debugMode=()=>{
+ s=!1},t.safeMode=()=>{s=!0},t.versionString="11.9.0",t.regex={concat:b,
+ lookahead:d,either:m,optional:u,anyNumberOfTimes:g}
+ ;for(const n in C)"object"==typeof C[n]&&e(C[n]);return Object.assign(t,C),t
+ },te=ne({});te.newInstance=()=>ne({});var ae=te;const ie=e=>({IMPORTANT:{
+ scope:"meta",begin:"!important"},BLOCK_COMMENT:e.C_BLOCK_COMMENT_MODE,HEXCOLOR:{
+ scope:"number",begin:/#(([0-9a-fA-F]{3,4})|(([0-9a-fA-F]{2}){3,4}))\b/},
+ FUNCTION_DISPATCH:{className:"built_in",begin:/[\w-]+(?=\()/},
+ ATTRIBUTE_SELECTOR_MODE:{scope:"selector-attr",begin:/\[/,end:/\]/,illegal:"$",
+ contains:[e.APOS_STRING_MODE,e.QUOTE_STRING_MODE]},CSS_NUMBER_MODE:{
+ scope:"number",
+ begin:e.NUMBER_RE+"(%|em|ex|ch|rem|vw|vh|vmin|vmax|cm|mm|in|pt|pc|px|deg|grad|rad|turn|s|ms|Hz|kHz|dpi|dpcm|dppx)?",
+ relevance:0},CSS_VARIABLE:{className:"attr",begin:/--[A-Za-z_][A-Za-z0-9_-]*/}
+ }),re=["a","abbr","address","article","aside","audio","b","blockquote","body","button","canvas","caption","cite","code","dd","del","details","dfn","div","dl","dt","em","fieldset","figcaption","figure","footer","form","h1","h2","h3","h4","h5","h6","header","hgroup","html","i","iframe","img","input","ins","kbd","label","legend","li","main","mark","menu","nav","object","ol","p","q","quote","samp","section","span","strong","summary","sup","table","tbody","td","textarea","tfoot","th","thead","time","tr","ul","var","video"],se=["any-hover","any-pointer","aspect-ratio","color","color-gamut","color-index","device-aspect-ratio","device-height","device-width","display-mode","forced-colors","grid","height","hover","inverted-colors","monochrome","orientation","overflow-block","overflow-inline","pointer","prefers-color-scheme","prefers-contrast","prefers-reduced-motion","prefers-reduced-transparency","resolution","scan","scripting","update","width","min-width","max-width","min-height","max-height"],oe=["active","any-link","blank","checked","current","default","defined","dir","disabled","drop","empty","enabled","first","first-child","first-of-type","fullscreen","future","focus","focus-visible","focus-within","has","host","host-context","hover","indeterminate","in-range","invalid","is","lang","last-child","last-of-type","left","link","local-link","not","nth-child","nth-col","nth-last-child","nth-last-col","nth-last-of-type","nth-of-type","only-child","only-of-type","optional","out-of-range","past","placeholder-shown","read-only","read-write","required","right","root","scope","target","target-within","user-invalid","valid","visited","where"],le=["after","backdrop","before","cue","cue-region","first-letter","first-line","grammar-error","marker","part","placeholder","selection","slotted","spelling-error"],ce=["align-content","align-items","align-self","all","animation","animation-delay","animation-direction","animation-duration","animation-fill-mode","animation-iteration-count","animation-name","animation-play-state","animation-timing-function","backface-visibility","background","background-attachment","background-blend-mode","background-clip","background-color","background-image","background-origin","background-position","background-repeat","background-size","block-size","border","border-block","border-block-color","border-block-end","border-block-end-color","border-block-end-style","border-block-end-width","border-block-start","border-block-start-color","border-block-start-style","border-block-start-width","border-block-style","border-block-width","border-bottom","border-bottom-color","border-bottom-left-radius","border-bottom-right-radius","border-bottom-style","border-bottom-width","border-collapse","border-color","border-image","border-image-outset","border-image-repeat","border-image-slice","border-image-source","border-image-width","border-inline","border-inline-color","border-inline-end","border-inline-end-color","border-inline-end-style","border-inline-end-width","border-inline-start","border-inline-start-color","border-inline-start-style","border-inline-start-width","border-inline-style","border-inline-width","border-left","border-left-color","border-left-style","border-left-width","border-radius","border-right","border-right-color","border-right-style","border-right-width","border-spacing","border-style","border-top","border-top-color","border-top-left-radius","border-top-right-radius","border-top-style","border-top-width","border-width","bottom","box-decoration-break","box-shadow","box-sizing","break-after","break-before","break-inside","caption-side","caret-color","clear","clip","clip-path","clip-rule","color","column-count","column-fill","column-gap","column-rule","column-rule-color","column-rule-style","column-rule-width","column-span","column-width","columns","contain","content","content-visibility","counter-increment","counter-reset","cue","cue-after","cue-before","cursor","direction","display","empty-cells","filter","flex","flex-basis","flex-direction","flex-flow","flex-grow","flex-shrink","flex-wrap","float","flow","font","font-display","font-family","font-feature-settings","font-kerning","font-language-override","font-size","font-size-adjust","font-smoothing","font-stretch","font-style","font-synthesis","font-variant","font-variant-caps","font-variant-east-asian","font-variant-ligatures","font-variant-numeric","font-variant-position","font-variation-settings","font-weight","gap","glyph-orientation-vertical","grid","grid-area","grid-auto-columns","grid-auto-flow","grid-auto-rows","grid-column","grid-column-end","grid-column-start","grid-gap","grid-row","grid-row-end","grid-row-start","grid-template","grid-template-areas","grid-template-columns","grid-template-rows","hanging-punctuation","height","hyphens","icon","image-orientation","image-rendering","image-resolution","ime-mode","inline-size","isolation","justify-content","left","letter-spacing","line-break","line-height","list-style","list-style-image","list-style-position","list-style-type","margin","margin-block","margin-block-end","margin-block-start","margin-bottom","margin-inline","margin-inline-end","margin-inline-start","margin-left","margin-right","margin-top","marks","mask","mask-border","mask-border-mode","mask-border-outset","mask-border-repeat","mask-border-slice","mask-border-source","mask-border-width","mask-clip","mask-composite","mask-image","mask-mode","mask-origin","mask-position","mask-repeat","mask-size","mask-type","max-block-size","max-height","max-inline-size","max-width","min-block-size","min-height","min-inline-size","min-width","mix-blend-mode","nav-down","nav-index","nav-left","nav-right","nav-up","none","normal","object-fit","object-position","opacity","order","orphans","outline","outline-color","outline-offset","outline-style","outline-width","overflow","overflow-wrap","overflow-x","overflow-y","padding","padding-block","padding-block-end","padding-block-start","padding-bottom","padding-inline","padding-inline-end","padding-inline-start","padding-left","padding-right","padding-top","page-break-after","page-break-before","page-break-inside","pause","pause-after","pause-before","perspective","perspective-origin","pointer-events","position","quotes","resize","rest","rest-after","rest-before","right","row-gap","scroll-margin","scroll-margin-block","scroll-margin-block-end","scroll-margin-block-start","scroll-margin-bottom","scroll-margin-inline","scroll-margin-inline-end","scroll-margin-inline-start","scroll-margin-left","scroll-margin-right","scroll-margin-top","scroll-padding","scroll-padding-block","scroll-padding-block-end","scroll-padding-block-start","scroll-padding-bottom","scroll-padding-inline","scroll-padding-inline-end","scroll-padding-inline-start","scroll-padding-left","scroll-padding-right","scroll-padding-top","scroll-snap-align","scroll-snap-stop","scroll-snap-type","scrollbar-color","scrollbar-gutter","scrollbar-width","shape-image-threshold","shape-margin","shape-outside","speak","speak-as","src","tab-size","table-layout","text-align","text-align-all","text-align-last","text-combine-upright","text-decoration","text-decoration-color","text-decoration-line","text-decoration-style","text-emphasis","text-emphasis-color","text-emphasis-position","text-emphasis-style","text-indent","text-justify","text-orientation","text-overflow","text-rendering","text-shadow","text-transform","text-underline-position","top","transform","transform-box","transform-origin","transform-style","transition","transition-delay","transition-duration","transition-property","transition-timing-function","unicode-bidi","vertical-align","visibility","voice-balance","voice-duration","voice-family","voice-pitch","voice-range","voice-rate","voice-stress","voice-volume","white-space","widows","width","will-change","word-break","word-spacing","word-wrap","writing-mode","z-index"].reverse(),de=oe.concat(le)
+ ;var ge="[0-9](_*[0-9])*",ue=`\\.(${ge})`,be="[0-9a-fA-F](_*[0-9a-fA-F])*",me={
+ className:"number",variants:[{
+ begin:`(\\b(${ge})((${ue})|\\.)?|(${ue}))[eE][+-]?(${ge})[fFdD]?\\b`},{
+ begin:`\\b(${ge})((${ue})[fFdD]?\\b|\\.([fFdD]\\b)?)`},{
+ begin:`(${ue})[fFdD]?\\b`},{begin:`\\b(${ge})[fFdD]\\b`},{
+ begin:`\\b0[xX]((${be})\\.?|(${be})?\\.(${be}))[pP][+-]?(${ge})[fFdD]?\\b`},{
+ begin:"\\b(0|[1-9](_*[0-9])*)[lL]?\\b"},{begin:`\\b0[xX](${be})[lL]?\\b`},{
+ begin:"\\b0(_*[0-7])*[lL]?\\b"},{begin:"\\b0[bB][01](_*[01])*[lL]?\\b"}],
+ relevance:0};function pe(e,n,t){return-1===t?"":e.replace(n,(a=>pe(e,n,t-1)))}
+ const _e="[A-Za-z$_][0-9A-Za-z$_]*",he=["as","in","of","if","for","while","finally","var","new","function","do","return","void","else","break","catch","instanceof","with","throw","case","default","try","switch","continue","typeof","delete","let","yield","const","class","debugger","async","await","static","import","from","export","extends"],fe=["true","false","null","undefined","NaN","Infinity"],Ee=["Object","Function","Boolean","Symbol","Math","Date","Number","BigInt","String","RegExp","Array","Float32Array","Float64Array","Int8Array","Uint8Array","Uint8ClampedArray","Int16Array","Int32Array","Uint16Array","Uint32Array","BigInt64Array","BigUint64Array","Set","Map","WeakSet","WeakMap","ArrayBuffer","SharedArrayBuffer","Atomics","DataView","JSON","Promise","Generator","GeneratorFunction","AsyncFunction","Reflect","Proxy","Intl","WebAssembly"],ye=["Error","EvalError","InternalError","RangeError","ReferenceError","SyntaxError","TypeError","URIError"],Ne=["setInterval","setTimeout","clearInterval","clearTimeout","require","exports","eval","isFinite","isNaN","parseFloat","parseInt","decodeURI","decodeURIComponent","encodeURI","encodeURIComponent","escape","unescape"],we=["arguments","this","super","console","window","document","localStorage","sessionStorage","module","global"],ve=[].concat(Ne,Ee,ye)
+ ;function Oe(e){const n=e.regex,t=_e,a={begin:/<[A-Za-z0-9\\._:-]+/,
+ end:/\/[A-Za-z0-9\\._:-]+>|\/>/,isTrulyOpeningTag:(e,n)=>{
+ const t=e[0].length+e.index,a=e.input[t]
+ ;if("<"===a||","===a)return void n.ignoreMatch();let i
+ ;">"===a&&(((e,{after:n})=>{const t=""+e[0].slice(1)
+ ;return-1!==e.input.indexOf(t,n)})(e,{after:t})||n.ignoreMatch())
+ ;const r=e.input.substring(t)
+ ;((i=r.match(/^\s*=/))||(i=r.match(/^\s+extends\s+/))&&0===i.index)&&n.ignoreMatch()
+ }},i={$pattern:_e,keyword:he,literal:fe,built_in:ve,"variable.language":we
+ },r="[0-9](_?[0-9])*",s=`\\.(${r})`,o="0|[1-9](_?[0-9])*|0[0-7]*[89][0-9]*",l={
+ className:"number",variants:[{
+ begin:`(\\b(${o})((${s})|\\.)?|(${s}))[eE][+-]?(${r})\\b`},{
+ begin:`\\b(${o})\\b((${s})\\b|\\.)?|(${s})\\b`},{
+ begin:"\\b(0|[1-9](_?[0-9])*)n\\b"},{
+ begin:"\\b0[xX][0-9a-fA-F](_?[0-9a-fA-F])*n?\\b"},{
+ begin:"\\b0[bB][0-1](_?[0-1])*n?\\b"},{begin:"\\b0[oO][0-7](_?[0-7])*n?\\b"},{
+ begin:"\\b0[0-7]+n?\\b"}],relevance:0},c={className:"subst",begin:"\\$\\{",
+ end:"\\}",keywords:i,contains:[]},d={begin:"html`",end:"",starts:{end:"`",
+ returnEnd:!1,contains:[e.BACKSLASH_ESCAPE,c],subLanguage:"xml"}},g={
+ begin:"css`",end:"",starts:{end:"`",returnEnd:!1,
+ contains:[e.BACKSLASH_ESCAPE,c],subLanguage:"css"}},u={begin:"gql`",end:"",
+ starts:{end:"`",returnEnd:!1,contains:[e.BACKSLASH_ESCAPE,c],
+ subLanguage:"graphql"}},b={className:"string",begin:"`",end:"`",
+ contains:[e.BACKSLASH_ESCAPE,c]},m={className:"comment",
+ variants:[e.COMMENT(/\/\*\*(?!\/)/,"\\*/",{relevance:0,contains:[{
+ begin:"(?=@[A-Za-z]+)",relevance:0,contains:[{className:"doctag",
+ begin:"@[A-Za-z]+"},{className:"type",begin:"\\{",end:"\\}",excludeEnd:!0,
+ excludeBegin:!0,relevance:0},{className:"variable",begin:t+"(?=\\s*(-)|$)",
+ endsParent:!0,relevance:0},{begin:/(?=[^\n])\s/,relevance:0}]}]
+ }),e.C_BLOCK_COMMENT_MODE,e.C_LINE_COMMENT_MODE]
+ },p=[e.APOS_STRING_MODE,e.QUOTE_STRING_MODE,d,g,u,b,{match:/\$\d+/},l]
+ ;c.contains=p.concat({begin:/\{/,end:/\}/,keywords:i,contains:["self"].concat(p)
+ });const _=[].concat(m,c.contains),h=_.concat([{begin:/\(/,end:/\)/,keywords:i,
+ contains:["self"].concat(_)}]),f={className:"params",begin:/\(/,end:/\)/,
+ excludeBegin:!0,excludeEnd:!0,keywords:i,contains:h},E={variants:[{
+ match:[/class/,/\s+/,t,/\s+/,/extends/,/\s+/,n.concat(t,"(",n.concat(/\./,t),")*")],
+ scope:{1:"keyword",3:"title.class",5:"keyword",7:"title.class.inherited"}},{
+ match:[/class/,/\s+/,t],scope:{1:"keyword",3:"title.class"}}]},y={relevance:0,
+ match:n.either(/\bJSON/,/\b[A-Z][a-z]+([A-Z][a-z]*|\d)*/,/\b[A-Z]{2,}([A-Z][a-z]+|\d)+([A-Z][a-z]*)*/,/\b[A-Z]{2,}[a-z]+([A-Z][a-z]+|\d)*([A-Z][a-z]*)*/),
+ className:"title.class",keywords:{_:[...Ee,...ye]}},N={variants:[{
+ match:[/function/,/\s+/,t,/(?=\s*\()/]},{match:[/function/,/\s*(?=\()/]}],
+ className:{1:"keyword",3:"title.function"},label:"func.def",contains:[f],
+ illegal:/%/},w={
+ match:n.concat(/\b/,(v=[...Ne,"super","import"],n.concat("(?!",v.join("|"),")")),t,n.lookahead(/\(/)),
+ className:"title.function",relevance:0};var v;const O={
+ begin:n.concat(/\./,n.lookahead(n.concat(t,/(?![0-9A-Za-z$_(])/))),end:t,
+ excludeBegin:!0,keywords:"prototype",className:"property",relevance:0},k={
+ match:[/get|set/,/\s+/,t,/(?=\()/],className:{1:"keyword",3:"title.function"},
+ contains:[{begin:/\(\)/},f]
+ },x="(\\([^()]*(\\([^()]*(\\([^()]*\\)[^()]*)*\\)[^()]*)*\\)|"+e.UNDERSCORE_IDENT_RE+")\\s*=>",M={
+ match:[/const|var|let/,/\s+/,t,/\s*/,/=\s*/,/(async\s*)?/,n.lookahead(x)],
+ keywords:"async",className:{1:"keyword",3:"title.function"},contains:[f]}
+ ;return{name:"JavaScript",aliases:["js","jsx","mjs","cjs"],keywords:i,exports:{
+ PARAMS_CONTAINS:h,CLASS_REFERENCE:y},illegal:/#(?![$_A-z])/,
+ contains:[e.SHEBANG({label:"shebang",binary:"node",relevance:5}),{
+ label:"use_strict",className:"meta",relevance:10,
+ begin:/^\s*['"]use (strict|asm)['"]/
+ },e.APOS_STRING_MODE,e.QUOTE_STRING_MODE,d,g,u,b,m,{match:/\$\d+/},l,y,{
+ className:"attr",begin:t+n.lookahead(":"),relevance:0},M,{
+ begin:"("+e.RE_STARTERS_RE+"|\\b(case|return|throw)\\b)\\s*",
+ keywords:"return throw case",relevance:0,contains:[m,e.REGEXP_MODE,{
+ className:"function",begin:x,returnBegin:!0,end:"\\s*=>",contains:[{
+ className:"params",variants:[{begin:e.UNDERSCORE_IDENT_RE,relevance:0},{
+ className:null,begin:/\(\s*\)/,skip:!0},{begin:/\(/,end:/\)/,excludeBegin:!0,
+ excludeEnd:!0,keywords:i,contains:h}]}]},{begin:/,/,relevance:0},{match:/\s+/,
+ relevance:0},{variants:[{begin:"<>",end:">"},{
+ match:/<[A-Za-z0-9\\._:-]+\s*\/>/},{begin:a.begin,
+ "on:begin":a.isTrulyOpeningTag,end:a.end}],subLanguage:"xml",contains:[{
+ begin:a.begin,end:a.end,skip:!0,contains:["self"]}]}]},N,{
+ beginKeywords:"while if switch catch for"},{
+ begin:"\\b(?!function)"+e.UNDERSCORE_IDENT_RE+"\\([^()]*(\\([^()]*(\\([^()]*\\)[^()]*)*\\)[^()]*)*\\)\\s*\\{",
+ returnBegin:!0,label:"func.def",contains:[f,e.inherit(e.TITLE_MODE,{begin:t,
+ className:"title.function"})]},{match:/\.\.\./,relevance:0},O,{match:"\\$"+t,
+ relevance:0},{match:[/\bconstructor(?=\s*\()/],className:{1:"title.function"},
+ contains:[f]},w,{relevance:0,match:/\b[A-Z][A-Z_0-9]+\b/,
+ className:"variable.constant"},E,k,{match:/\$[(.]/}]}}
+ const ke=e=>b(/\b/,e,/\w$/.test(e)?/\b/:/\B/),xe=["Protocol","Type"].map(ke),Me=["init","self"].map(ke),Se=["Any","Self"],Ae=["actor","any","associatedtype","async","await",/as\?/,/as!/,"as","borrowing","break","case","catch","class","consume","consuming","continue","convenience","copy","default","defer","deinit","didSet","distributed","do","dynamic","each","else","enum","extension","fallthrough",/fileprivate\(set\)/,"fileprivate","final","for","func","get","guard","if","import","indirect","infix",/init\?/,/init!/,"inout",/internal\(set\)/,"internal","in","is","isolated","nonisolated","lazy","let","macro","mutating","nonmutating",/open\(set\)/,"open","operator","optional","override","postfix","precedencegroup","prefix",/private\(set\)/,"private","protocol",/public\(set\)/,"public","repeat","required","rethrows","return","set","some","static","struct","subscript","super","switch","throws","throw",/try\?/,/try!/,"try","typealias",/unowned\(safe\)/,/unowned\(unsafe\)/,"unowned","var","weak","where","while","willSet"],Ce=["false","nil","true"],Te=["assignment","associativity","higherThan","left","lowerThan","none","right"],Re=["#colorLiteral","#column","#dsohandle","#else","#elseif","#endif","#error","#file","#fileID","#fileLiteral","#filePath","#function","#if","#imageLiteral","#keyPath","#line","#selector","#sourceLocation","#warning"],De=["abs","all","any","assert","assertionFailure","debugPrint","dump","fatalError","getVaList","isKnownUniquelyReferenced","max","min","numericCast","pointwiseMax","pointwiseMin","precondition","preconditionFailure","print","readLine","repeatElement","sequence","stride","swap","swift_unboxFromSwiftValueWithType","transcode","type","unsafeBitCast","unsafeDowncast","withExtendedLifetime","withUnsafeMutablePointer","withUnsafePointer","withVaList","withoutActuallyEscaping","zip"],Ie=m(/[/=\-+!*%<>&|^~?]/,/[\u00A1-\u00A7]/,/[\u00A9\u00AB]/,/[\u00AC\u00AE]/,/[\u00B0\u00B1]/,/[\u00B6\u00BB\u00BF\u00D7\u00F7]/,/[\u2016-\u2017]/,/[\u2020-\u2027]/,/[\u2030-\u203E]/,/[\u2041-\u2053]/,/[\u2055-\u205E]/,/[\u2190-\u23FF]/,/[\u2500-\u2775]/,/[\u2794-\u2BFF]/,/[\u2E00-\u2E7F]/,/[\u3001-\u3003]/,/[\u3008-\u3020]/,/[\u3030]/),Le=m(Ie,/[\u0300-\u036F]/,/[\u1DC0-\u1DFF]/,/[\u20D0-\u20FF]/,/[\uFE00-\uFE0F]/,/[\uFE20-\uFE2F]/),Be=b(Ie,Le,"*"),$e=m(/[a-zA-Z_]/,/[\u00A8\u00AA\u00AD\u00AF\u00B2-\u00B5\u00B7-\u00BA]/,/[\u00BC-\u00BE\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u00FF]/,/[\u0100-\u02FF\u0370-\u167F\u1681-\u180D\u180F-\u1DBF]/,/[\u1E00-\u1FFF]/,/[\u200B-\u200D\u202A-\u202E\u203F-\u2040\u2054\u2060-\u206F]/,/[\u2070-\u20CF\u2100-\u218F\u2460-\u24FF\u2776-\u2793]/,/[\u2C00-\u2DFF\u2E80-\u2FFF]/,/[\u3004-\u3007\u3021-\u302F\u3031-\u303F\u3040-\uD7FF]/,/[\uF900-\uFD3D\uFD40-\uFDCF\uFDF0-\uFE1F\uFE30-\uFE44]/,/[\uFE47-\uFEFE\uFF00-\uFFFD]/),ze=m($e,/\d/,/[\u0300-\u036F\u1DC0-\u1DFF\u20D0-\u20FF\uFE20-\uFE2F]/),Fe=b($e,ze,"*"),Ue=b(/[A-Z]/,ze,"*"),je=["attached","autoclosure",b(/convention\(/,m("swift","block","c"),/\)/),"discardableResult","dynamicCallable","dynamicMemberLookup","escaping","freestanding","frozen","GKInspectable","IBAction","IBDesignable","IBInspectable","IBOutlet","IBSegueAction","inlinable","main","nonobjc","NSApplicationMain","NSCopying","NSManaged",b(/objc\(/,Fe,/\)/),"objc","objcMembers","propertyWrapper","requires_stored_property_inits","resultBuilder","Sendable","testable","UIApplicationMain","unchecked","unknown","usableFromInline","warn_unqualified_access"],Pe=["iOS","iOSApplicationExtension","macOS","macOSApplicationExtension","macCatalyst","macCatalystApplicationExtension","watchOS","watchOSApplicationExtension","tvOS","tvOSApplicationExtension","swift"]
+ ;var Ke=Object.freeze({__proto__:null,grmr_bash:e=>{const n=e.regex,t={},a={
+ begin:/\$\{/,end:/\}/,contains:["self",{begin:/:-/,contains:[t]}]}
+ ;Object.assign(t,{className:"variable",variants:[{
+ begin:n.concat(/\$[\w\d#@][\w\d_]*/,"(?![\\w\\d])(?![$])")},a]});const i={
+ className:"subst",begin:/\$\(/,end:/\)/,contains:[e.BACKSLASH_ESCAPE]},r={
+ begin:/<<-?\s*(?=\w+)/,starts:{contains:[e.END_SAME_AS_BEGIN({begin:/(\w+)/,
+ end:/(\w+)/,className:"string"})]}},s={className:"string",begin:/"/,end:/"/,
+ contains:[e.BACKSLASH_ESCAPE,t,i]};i.contains.push(s);const o={begin:/\$?\(\(/,
+ end:/\)\)/,contains:[{begin:/\d+#[0-9a-f]+/,className:"number"},e.NUMBER_MODE,t]
+ },l=e.SHEBANG({binary:"(fish|bash|zsh|sh|csh|ksh|tcsh|dash|scsh)",relevance:10
+ }),c={className:"function",begin:/\w[\w\d_]*\s*\(\s*\)\s*\{/,returnBegin:!0,
+ contains:[e.inherit(e.TITLE_MODE,{begin:/\w[\w\d_]*/})],relevance:0};return{
+ name:"Bash",aliases:["sh"],keywords:{$pattern:/\b[a-z][a-z0-9._-]+\b/,
+ keyword:["if","then","else","elif","fi","for","while","until","in","do","done","case","esac","function","select"],
+ literal:["true","false"],
+ built_in:["break","cd","continue","eval","exec","exit","export","getopts","hash","pwd","readonly","return","shift","test","times","trap","umask","unset","alias","bind","builtin","caller","command","declare","echo","enable","help","let","local","logout","mapfile","printf","read","readarray","source","type","typeset","ulimit","unalias","set","shopt","autoload","bg","bindkey","bye","cap","chdir","clone","comparguments","compcall","compctl","compdescribe","compfiles","compgroups","compquote","comptags","comptry","compvalues","dirs","disable","disown","echotc","echoti","emulate","fc","fg","float","functions","getcap","getln","history","integer","jobs","kill","limit","log","noglob","popd","print","pushd","pushln","rehash","sched","setcap","setopt","stat","suspend","ttyctl","unfunction","unhash","unlimit","unsetopt","vared","wait","whence","where","which","zcompile","zformat","zftp","zle","zmodload","zparseopts","zprof","zpty","zregexparse","zsocket","zstyle","ztcp","chcon","chgrp","chown","chmod","cp","dd","df","dir","dircolors","ln","ls","mkdir","mkfifo","mknod","mktemp","mv","realpath","rm","rmdir","shred","sync","touch","truncate","vdir","b2sum","base32","base64","cat","cksum","comm","csplit","cut","expand","fmt","fold","head","join","md5sum","nl","numfmt","od","paste","ptx","pr","sha1sum","sha224sum","sha256sum","sha384sum","sha512sum","shuf","sort","split","sum","tac","tail","tr","tsort","unexpand","uniq","wc","arch","basename","chroot","date","dirname","du","echo","env","expr","factor","groups","hostid","id","link","logname","nice","nohup","nproc","pathchk","pinky","printenv","printf","pwd","readlink","runcon","seq","sleep","stat","stdbuf","stty","tee","test","timeout","tty","uname","unlink","uptime","users","who","whoami","yes"]
+ },contains:[l,e.SHEBANG(),c,o,e.HASH_COMMENT_MODE,r,{match:/(\/[a-z._-]+)+/},s,{
+ match:/\\"/},{className:"string",begin:/'/,end:/'/},{match:/\\'/},t]}},
+ grmr_c:e=>{const n=e.regex,t=e.COMMENT("//","$",{contains:[{begin:/\\\n/}]
+ }),a="decltype\\(auto\\)",i="[a-zA-Z_]\\w*::",r="("+a+"|"+n.optional(i)+"[a-zA-Z_]\\w*"+n.optional("<[^<>]+>")+")",s={
+ className:"type",variants:[{begin:"\\b[a-z\\d_]*_t\\b"},{
+ match:/\batomic_[a-z]{3,6}\b/}]},o={className:"string",variants:[{
+ begin:'(u8?|U|L)?"',end:'"',illegal:"\\n",contains:[e.BACKSLASH_ESCAPE]},{
+ begin:"(u8?|U|L)?'(\\\\(x[0-9A-Fa-f]{2}|u[0-9A-Fa-f]{4,8}|[0-7]{3}|\\S)|.)",
+ end:"'",illegal:"."},e.END_SAME_AS_BEGIN({
+ begin:/(?:u8?|U|L)?R"([^()\\ ]{0,16})\(/,end:/\)([^()\\ ]{0,16})"/})]},l={
+ className:"number",variants:[{begin:"\\b(0b[01']+)"},{
+ begin:"(-?)\\b([\\d']+(\\.[\\d']*)?|\\.[\\d']+)((ll|LL|l|L)(u|U)?|(u|U)(ll|LL|l|L)?|f|F|b|B)"
+ },{
+ begin:"(-?)(\\b0[xX][a-fA-F0-9']+|(\\b[\\d']+(\\.[\\d']*)?|\\.[\\d']+)([eE][-+]?[\\d']+)?)"
+ }],relevance:0},c={className:"meta",begin:/#\s*[a-z]+\b/,end:/$/,keywords:{
+ keyword:"if else elif endif define undef warning error line pragma _Pragma ifdef ifndef include"
+ },contains:[{begin:/\\\n/,relevance:0},e.inherit(o,{className:"string"}),{
+ className:"string",begin:/<.*?>/},t,e.C_BLOCK_COMMENT_MODE]},d={
+ className:"title",begin:n.optional(i)+e.IDENT_RE,relevance:0
+ },g=n.optional(i)+e.IDENT_RE+"\\s*\\(",u={
+ keyword:["asm","auto","break","case","continue","default","do","else","enum","extern","for","fortran","goto","if","inline","register","restrict","return","sizeof","struct","switch","typedef","union","volatile","while","_Alignas","_Alignof","_Atomic","_Generic","_Noreturn","_Static_assert","_Thread_local","alignas","alignof","noreturn","static_assert","thread_local","_Pragma"],
+ type:["float","double","signed","unsigned","int","short","long","char","void","_Bool","_Complex","_Imaginary","_Decimal32","_Decimal64","_Decimal128","const","static","complex","bool","imaginary"],
+ literal:"true false NULL",
+ built_in:"std string wstring cin cout cerr clog stdin stdout stderr stringstream istringstream ostringstream auto_ptr deque list queue stack vector map set pair bitset multiset multimap unordered_set unordered_map unordered_multiset unordered_multimap priority_queue make_pair array shared_ptr abort terminate abs acos asin atan2 atan calloc ceil cosh cos exit exp fabs floor fmod fprintf fputs free frexp fscanf future isalnum isalpha iscntrl isdigit isgraph islower isprint ispunct isspace isupper isxdigit tolower toupper labs ldexp log10 log malloc realloc memchr memcmp memcpy memset modf pow printf putchar puts scanf sinh sin snprintf sprintf sqrt sscanf strcat strchr strcmp strcpy strcspn strlen strncat strncmp strncpy strpbrk strrchr strspn strstr tanh tan vfprintf vprintf vsprintf endl initializer_list unique_ptr"
+ },b=[c,s,t,e.C_BLOCK_COMMENT_MODE,l,o],m={variants:[{begin:/=/,end:/;/},{
+ begin:/\(/,end:/\)/},{beginKeywords:"new throw return else",end:/;/}],
+ keywords:u,contains:b.concat([{begin:/\(/,end:/\)/,keywords:u,
+ contains:b.concat(["self"]),relevance:0}]),relevance:0},p={
+ begin:"("+r+"[\\*&\\s]+)+"+g,returnBegin:!0,end:/[{;=]/,excludeEnd:!0,
+ keywords:u,illegal:/[^\w\s\*&:<>.]/,contains:[{begin:a,keywords:u,relevance:0},{
+ begin:g,returnBegin:!0,contains:[e.inherit(d,{className:"title.function"})],
+ relevance:0},{relevance:0,match:/,/},{className:"params",begin:/\(/,end:/\)/,
+ keywords:u,relevance:0,contains:[t,e.C_BLOCK_COMMENT_MODE,o,l,s,{begin:/\(/,
+ end:/\)/,keywords:u,relevance:0,contains:["self",t,e.C_BLOCK_COMMENT_MODE,o,l,s]
+ }]},s,t,e.C_BLOCK_COMMENT_MODE,c]};return{name:"C",aliases:["h"],keywords:u,
+ disableAutodetect:!0,illegal:"",contains:[].concat(m,p,b,[c,{
+ begin:e.IDENT_RE+"::",keywords:u},{className:"class",
+ beginKeywords:"enum class struct union",end:/[{;:<>=]/,contains:[{
+ beginKeywords:"final class struct"},e.TITLE_MODE]}]),exports:{preprocessor:c,
+ strings:o,keywords:u}}},grmr_cpp:e=>{const n=e.regex,t=e.COMMENT("//","$",{
+ contains:[{begin:/\\\n/}]
+ }),a="decltype\\(auto\\)",i="[a-zA-Z_]\\w*::",r="(?!struct)("+a+"|"+n.optional(i)+"[a-zA-Z_]\\w*"+n.optional("<[^<>]+>")+")",s={
+ className:"type",begin:"\\b[a-z\\d_]*_t\\b"},o={className:"string",variants:[{
+ begin:'(u8?|U|L)?"',end:'"',illegal:"\\n",contains:[e.BACKSLASH_ESCAPE]},{
+ begin:"(u8?|U|L)?'(\\\\(x[0-9A-Fa-f]{2}|u[0-9A-Fa-f]{4,8}|[0-7]{3}|\\S)|.)",
+ end:"'",illegal:"."},e.END_SAME_AS_BEGIN({
+ begin:/(?:u8?|U|L)?R"([^()\\ ]{0,16})\(/,end:/\)([^()\\ ]{0,16})"/})]},l={
+ className:"number",variants:[{begin:"\\b(0b[01']+)"},{
+ begin:"(-?)\\b([\\d']+(\\.[\\d']*)?|\\.[\\d']+)((ll|LL|l|L)(u|U)?|(u|U)(ll|LL|l|L)?|f|F|b|B)"
+ },{
+ begin:"(-?)(\\b0[xX][a-fA-F0-9']+|(\\b[\\d']+(\\.[\\d']*)?|\\.[\\d']+)([eE][-+]?[\\d']+)?)"
+ }],relevance:0},c={className:"meta",begin:/#\s*[a-z]+\b/,end:/$/,keywords:{
+ keyword:"if else elif endif define undef warning error line pragma _Pragma ifdef ifndef include"
+ },contains:[{begin:/\\\n/,relevance:0},e.inherit(o,{className:"string"}),{
+ className:"string",begin:/<.*?>/},t,e.C_BLOCK_COMMENT_MODE]},d={
+ className:"title",begin:n.optional(i)+e.IDENT_RE,relevance:0
+ },g=n.optional(i)+e.IDENT_RE+"\\s*\\(",u={
+ type:["bool","char","char16_t","char32_t","char8_t","double","float","int","long","short","void","wchar_t","unsigned","signed","const","static"],
+ keyword:["alignas","alignof","and","and_eq","asm","atomic_cancel","atomic_commit","atomic_noexcept","auto","bitand","bitor","break","case","catch","class","co_await","co_return","co_yield","compl","concept","const_cast|10","consteval","constexpr","constinit","continue","decltype","default","delete","do","dynamic_cast|10","else","enum","explicit","export","extern","false","final","for","friend","goto","if","import","inline","module","mutable","namespace","new","noexcept","not","not_eq","nullptr","operator","or","or_eq","override","private","protected","public","reflexpr","register","reinterpret_cast|10","requires","return","sizeof","static_assert","static_cast|10","struct","switch","synchronized","template","this","thread_local","throw","transaction_safe","transaction_safe_dynamic","true","try","typedef","typeid","typename","union","using","virtual","volatile","while","xor","xor_eq"],
+ literal:["NULL","false","nullopt","nullptr","true"],built_in:["_Pragma"],
+ _type_hints:["any","auto_ptr","barrier","binary_semaphore","bitset","complex","condition_variable","condition_variable_any","counting_semaphore","deque","false_type","future","imaginary","initializer_list","istringstream","jthread","latch","lock_guard","multimap","multiset","mutex","optional","ostringstream","packaged_task","pair","promise","priority_queue","queue","recursive_mutex","recursive_timed_mutex","scoped_lock","set","shared_future","shared_lock","shared_mutex","shared_timed_mutex","shared_ptr","stack","string_view","stringstream","timed_mutex","thread","true_type","tuple","unique_lock","unique_ptr","unordered_map","unordered_multimap","unordered_multiset","unordered_set","variant","vector","weak_ptr","wstring","wstring_view"]
+ },b={className:"function.dispatch",relevance:0,keywords:{
+ _hint:["abort","abs","acos","apply","as_const","asin","atan","atan2","calloc","ceil","cerr","cin","clog","cos","cosh","cout","declval","endl","exchange","exit","exp","fabs","floor","fmod","forward","fprintf","fputs","free","frexp","fscanf","future","invoke","isalnum","isalpha","iscntrl","isdigit","isgraph","islower","isprint","ispunct","isspace","isupper","isxdigit","labs","launder","ldexp","log","log10","make_pair","make_shared","make_shared_for_overwrite","make_tuple","make_unique","malloc","memchr","memcmp","memcpy","memset","modf","move","pow","printf","putchar","puts","realloc","scanf","sin","sinh","snprintf","sprintf","sqrt","sscanf","std","stderr","stdin","stdout","strcat","strchr","strcmp","strcpy","strcspn","strlen","strncat","strncmp","strncpy","strpbrk","strrchr","strspn","strstr","swap","tan","tanh","terminate","to_underlying","tolower","toupper","vfprintf","visit","vprintf","vsprintf"]
+ },
+ begin:n.concat(/\b/,/(?!decltype)/,/(?!if)/,/(?!for)/,/(?!switch)/,/(?!while)/,e.IDENT_RE,n.lookahead(/(<[^<>]+>|)\s*\(/))
+ },m=[b,c,s,t,e.C_BLOCK_COMMENT_MODE,l,o],p={variants:[{begin:/=/,end:/;/},{
+ begin:/\(/,end:/\)/},{beginKeywords:"new throw return else",end:/;/}],
+ keywords:u,contains:m.concat([{begin:/\(/,end:/\)/,keywords:u,
+ contains:m.concat(["self"]),relevance:0}]),relevance:0},_={className:"function",
+ begin:"("+r+"[\\*&\\s]+)+"+g,returnBegin:!0,end:/[{;=]/,excludeEnd:!0,
+ keywords:u,illegal:/[^\w\s\*&:<>.]/,contains:[{begin:a,keywords:u,relevance:0},{
+ begin:g,returnBegin:!0,contains:[d],relevance:0},{begin:/::/,relevance:0},{
+ begin:/:/,endsWithParent:!0,contains:[o,l]},{relevance:0,match:/,/},{
+ className:"params",begin:/\(/,end:/\)/,keywords:u,relevance:0,
+ contains:[t,e.C_BLOCK_COMMENT_MODE,o,l,s,{begin:/\(/,end:/\)/,keywords:u,
+ relevance:0,contains:["self",t,e.C_BLOCK_COMMENT_MODE,o,l,s]}]
+ },s,t,e.C_BLOCK_COMMENT_MODE,c]};return{name:"C++",
+ aliases:["cc","c++","h++","hpp","hh","hxx","cxx"],keywords:u,illegal:"",
+ classNameAliases:{"function.dispatch":"built_in"},
+ contains:[].concat(p,_,b,m,[c,{
+ begin:"\\b(deque|list|queue|priority_queue|pair|stack|vector|map|set|bitset|multiset|multimap|unordered_map|unordered_set|unordered_multiset|unordered_multimap|array|tuple|optional|variant|function)\\s*<(?!<)",
+ end:">",keywords:u,contains:["self",s]},{begin:e.IDENT_RE+"::",keywords:u},{
+ match:[/\b(?:enum(?:\s+(?:class|struct))?|class|struct|union)/,/\s+/,/\w+/],
+ className:{1:"keyword",3:"title.class"}}])}},grmr_csharp:e=>{const n={
+ keyword:["abstract","as","base","break","case","catch","class","const","continue","do","else","event","explicit","extern","finally","fixed","for","foreach","goto","if","implicit","in","interface","internal","is","lock","namespace","new","operator","out","override","params","private","protected","public","readonly","record","ref","return","scoped","sealed","sizeof","stackalloc","static","struct","switch","this","throw","try","typeof","unchecked","unsafe","using","virtual","void","volatile","while"].concat(["add","alias","and","ascending","async","await","by","descending","equals","from","get","global","group","init","into","join","let","nameof","not","notnull","on","or","orderby","partial","remove","select","set","unmanaged","value|0","var","when","where","with","yield"]),
+ built_in:["bool","byte","char","decimal","delegate","double","dynamic","enum","float","int","long","nint","nuint","object","sbyte","short","string","ulong","uint","ushort"],
+ literal:["default","false","null","true"]},t=e.inherit(e.TITLE_MODE,{
+ begin:"[a-zA-Z](\\.?\\w)*"}),a={className:"number",variants:[{
+ begin:"\\b(0b[01']+)"},{
+ begin:"(-?)\\b([\\d']+(\\.[\\d']*)?|\\.[\\d']+)(u|U|l|L|ul|UL|f|F|b|B)"},{
+ begin:"(-?)(\\b0[xX][a-fA-F0-9']+|(\\b[\\d']+(\\.[\\d']*)?|\\.[\\d']+)([eE][-+]?[\\d']+)?)"
+ }],relevance:0},i={className:"string",begin:'@"',end:'"',contains:[{begin:'""'}]
+ },r=e.inherit(i,{illegal:/\n/}),s={className:"subst",begin:/\{/,end:/\}/,
+ keywords:n},o=e.inherit(s,{illegal:/\n/}),l={className:"string",begin:/\$"/,
+ end:'"',illegal:/\n/,contains:[{begin:/\{\{/},{begin:/\}\}/
+ },e.BACKSLASH_ESCAPE,o]},c={className:"string",begin:/\$@"/,end:'"',contains:[{
+ begin:/\{\{/},{begin:/\}\}/},{begin:'""'},s]},d=e.inherit(c,{illegal:/\n/,
+ contains:[{begin:/\{\{/},{begin:/\}\}/},{begin:'""'},o]})
+ ;s.contains=[c,l,i,e.APOS_STRING_MODE,e.QUOTE_STRING_MODE,a,e.C_BLOCK_COMMENT_MODE],
+ o.contains=[d,l,r,e.APOS_STRING_MODE,e.QUOTE_STRING_MODE,a,e.inherit(e.C_BLOCK_COMMENT_MODE,{
+ illegal:/\n/})];const g={variants:[c,l,i,e.APOS_STRING_MODE,e.QUOTE_STRING_MODE]
+ },u={begin:"<",end:">",contains:[{beginKeywords:"in out"},t]
+ },b=e.IDENT_RE+"(<"+e.IDENT_RE+"(\\s*,\\s*"+e.IDENT_RE+")*>)?(\\[\\])?",m={
+ begin:"@"+e.IDENT_RE,relevance:0};return{name:"C#",aliases:["cs","c#"],
+ keywords:n,illegal:/::/,contains:[e.COMMENT("///","$",{returnBegin:!0,
+ contains:[{className:"doctag",variants:[{begin:"///",relevance:0},{
+ begin:"\x3c!--|--\x3e"},{begin:"?",end:">"}]}]
+ }),e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,{className:"meta",begin:"#",
+ end:"$",keywords:{
+ keyword:"if else elif endif define undef warning error line region endregion pragma checksum"
+ }},g,a,{beginKeywords:"class interface",relevance:0,end:/[{;=]/,
+ illegal:/[^\s:,]/,contains:[{beginKeywords:"where class"
+ },t,u,e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE]},{beginKeywords:"namespace",
+ relevance:0,end:/[{;=]/,illegal:/[^\s:]/,
+ contains:[t,e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE]},{
+ beginKeywords:"record",relevance:0,end:/[{;=]/,illegal:/[^\s:]/,
+ contains:[t,u,e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE]},{className:"meta",
+ begin:"^\\s*\\[(?=[\\w])",excludeBegin:!0,end:"\\]",excludeEnd:!0,contains:[{
+ className:"string",begin:/"/,end:/"/}]},{
+ beginKeywords:"new return throw await else",relevance:0},{className:"function",
+ begin:"("+b+"\\s+)+"+e.IDENT_RE+"\\s*(<[^=]+>\\s*)?\\(",returnBegin:!0,
+ end:/\s*[{;=]/,excludeEnd:!0,keywords:n,contains:[{
+ beginKeywords:"public private protected static internal protected abstract async extern override unsafe virtual new sealed partial",
+ relevance:0},{begin:e.IDENT_RE+"\\s*(<[^=]+>\\s*)?\\(",returnBegin:!0,
+ contains:[e.TITLE_MODE,u],relevance:0},{match:/\(\)/},{className:"params",
+ begin:/\(/,end:/\)/,excludeBegin:!0,excludeEnd:!0,keywords:n,relevance:0,
+ contains:[g,a,e.C_BLOCK_COMMENT_MODE]
+ },e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE]},m]}},grmr_css:e=>{
+ const n=e.regex,t=ie(e),a=[e.APOS_STRING_MODE,e.QUOTE_STRING_MODE];return{
+ name:"CSS",case_insensitive:!0,illegal:/[=|'\$]/,keywords:{
+ keyframePosition:"from to"},classNameAliases:{keyframePosition:"selector-tag"},
+ contains:[t.BLOCK_COMMENT,{begin:/-(webkit|moz|ms|o)-(?=[a-z])/
+ },t.CSS_NUMBER_MODE,{className:"selector-id",begin:/#[A-Za-z0-9_-]+/,relevance:0
+ },{className:"selector-class",begin:"\\.[a-zA-Z-][a-zA-Z0-9_-]*",relevance:0
+ },t.ATTRIBUTE_SELECTOR_MODE,{className:"selector-pseudo",variants:[{
+ begin:":("+oe.join("|")+")"},{begin:":(:)?("+le.join("|")+")"}]
+ },t.CSS_VARIABLE,{className:"attribute",begin:"\\b("+ce.join("|")+")\\b"},{
+ begin:/:/,end:/[;}{]/,
+ contains:[t.BLOCK_COMMENT,t.HEXCOLOR,t.IMPORTANT,t.CSS_NUMBER_MODE,...a,{
+ begin:/(url|data-uri)\(/,end:/\)/,relevance:0,keywords:{built_in:"url data-uri"
+ },contains:[...a,{className:"string",begin:/[^)]/,endsWithParent:!0,
+ excludeEnd:!0}]},t.FUNCTION_DISPATCH]},{begin:n.lookahead(/@/),end:"[{;]",
+ relevance:0,illegal:/:/,contains:[{className:"keyword",begin:/@-?\w[\w]*(-\w+)*/
+ },{begin:/\s/,endsWithParent:!0,excludeEnd:!0,relevance:0,keywords:{
+ $pattern:/[a-z-]+/,keyword:"and or not only",attribute:se.join(" ")},contains:[{
+ begin:/[a-z-]+(?=:)/,className:"attribute"},...a,t.CSS_NUMBER_MODE]}]},{
+ className:"selector-tag",begin:"\\b("+re.join("|")+")\\b"}]}},grmr_diff:e=>{
+ const n=e.regex;return{name:"Diff",aliases:["patch"],contains:[{
+ className:"meta",relevance:10,
+ match:n.either(/^@@ +-\d+,\d+ +\+\d+,\d+ +@@/,/^\*\*\* +\d+,\d+ +\*\*\*\*$/,/^--- +\d+,\d+ +----$/)
+ },{className:"comment",variants:[{
+ begin:n.either(/Index: /,/^index/,/={3,}/,/^-{3}/,/^\*{3} /,/^\+{3}/,/^diff --git/),
+ end:/$/},{match:/^\*{15}$/}]},{className:"addition",begin:/^\+/,end:/$/},{
+ className:"deletion",begin:/^-/,end:/$/},{className:"addition",begin:/^!/,
+ end:/$/}]}},grmr_go:e=>{const n={
+ keyword:["break","case","chan","const","continue","default","defer","else","fallthrough","for","func","go","goto","if","import","interface","map","package","range","return","select","struct","switch","type","var"],
+ type:["bool","byte","complex64","complex128","error","float32","float64","int8","int16","int32","int64","string","uint8","uint16","uint32","uint64","int","uint","uintptr","rune"],
+ literal:["true","false","iota","nil"],
+ built_in:["append","cap","close","complex","copy","imag","len","make","new","panic","print","println","real","recover","delete"]
+ };return{name:"Go",aliases:["golang"],keywords:n,illegal:"",
+ contains:[e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,{className:"string",
+ variants:[e.QUOTE_STRING_MODE,e.APOS_STRING_MODE,{begin:"`",end:"`"}]},{
+ className:"number",variants:[{begin:e.C_NUMBER_RE+"[i]",relevance:1
+ },e.C_NUMBER_MODE]},{begin:/:=/},{className:"function",beginKeywords:"func",
+ end:"\\s*(\\{|$)",excludeEnd:!0,contains:[e.TITLE_MODE,{className:"params",
+ begin:/\(/,end:/\)/,endsParent:!0,keywords:n,illegal:/["']/}]}]}},
+ grmr_graphql:e=>{const n=e.regex;return{name:"GraphQL",aliases:["gql"],
+ case_insensitive:!0,disableAutodetect:!1,keywords:{
+ keyword:["query","mutation","subscription","type","input","schema","directive","interface","union","scalar","fragment","enum","on"],
+ literal:["true","false","null"]},
+ contains:[e.HASH_COMMENT_MODE,e.QUOTE_STRING_MODE,e.NUMBER_MODE,{
+ scope:"punctuation",match:/[.]{3}/,relevance:0},{scope:"punctuation",
+ begin:/[\!\(\)\:\=\[\]\{\|\}]{1}/,relevance:0},{scope:"variable",begin:/\$/,
+ end:/\W/,excludeEnd:!0,relevance:0},{scope:"meta",match:/@\w+/,excludeEnd:!0},{
+ scope:"symbol",begin:n.concat(/[_A-Za-z][_0-9A-Za-z]*/,n.lookahead(/\s*:/)),
+ relevance:0}],illegal:[/[;<']/,/BEGIN/]}},grmr_ini:e=>{const n=e.regex,t={
+ className:"number",relevance:0,variants:[{begin:/([+-]+)?[\d]+_[\d_]+/},{
+ begin:e.NUMBER_RE}]},a=e.COMMENT();a.variants=[{begin:/;/,end:/$/},{begin:/#/,
+ end:/$/}];const i={className:"variable",variants:[{begin:/\$[\w\d"][\w\d_]*/},{
+ begin:/\$\{(.*?)\}/}]},r={className:"literal",
+ begin:/\bon|off|true|false|yes|no\b/},s={className:"string",
+ contains:[e.BACKSLASH_ESCAPE],variants:[{begin:"'''",end:"'''",relevance:10},{
+ begin:'"""',end:'"""',relevance:10},{begin:'"',end:'"'},{begin:"'",end:"'"}]
+ },o={begin:/\[/,end:/\]/,contains:[a,r,i,s,t,"self"],relevance:0
+ },l=n.either(/[A-Za-z0-9_-]+/,/"(\\"|[^"])*"/,/'[^']*'/);return{
+ name:"TOML, also INI",aliases:["toml"],case_insensitive:!0,illegal:/\S/,
+ contains:[a,{className:"section",begin:/\[+/,end:/\]+/},{
+ begin:n.concat(l,"(\\s*\\.\\s*",l,")*",n.lookahead(/\s*=\s*[^#\s]/)),
+ className:"attr",starts:{end:/$/,contains:[a,o,r,i,s,t]}}]}},grmr_java:e=>{
+ const n=e.regex,t="[\xc0-\u02b8a-zA-Z_$][\xc0-\u02b8a-zA-Z_$0-9]*",a=t+pe("(?:<"+t+"~~~(?:\\s*,\\s*"+t+"~~~)*>)?",/~~~/g,2),i={
+ keyword:["synchronized","abstract","private","var","static","if","const ","for","while","strictfp","finally","protected","import","native","final","void","enum","else","break","transient","catch","instanceof","volatile","case","assert","package","default","public","try","switch","continue","throws","protected","public","private","module","requires","exports","do","sealed","yield","permits"],
+ literal:["false","true","null"],
+ type:["char","boolean","long","float","int","byte","short","double"],
+ built_in:["super","this"]},r={className:"meta",begin:"@"+t,contains:[{
+ begin:/\(/,end:/\)/,contains:["self"]}]},s={className:"params",begin:/\(/,
+ end:/\)/,keywords:i,relevance:0,contains:[e.C_BLOCK_COMMENT_MODE],endsParent:!0}
+ ;return{name:"Java",aliases:["jsp"],keywords:i,illegal:/<\/|#/,
+ contains:[e.COMMENT("/\\*\\*","\\*/",{relevance:0,contains:[{begin:/\w+@/,
+ relevance:0},{className:"doctag",begin:"@[A-Za-z]+"}]}),{
+ begin:/import java\.[a-z]+\./,keywords:"import",relevance:2
+ },e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,{begin:/"""/,end:/"""/,
+ className:"string",contains:[e.BACKSLASH_ESCAPE]
+ },e.APOS_STRING_MODE,e.QUOTE_STRING_MODE,{
+ match:[/\b(?:class|interface|enum|extends|implements|new)/,/\s+/,t],className:{
+ 1:"keyword",3:"title.class"}},{match:/non-sealed/,scope:"keyword"},{
+ begin:[n.concat(/(?!else)/,t),/\s+/,t,/\s+/,/=(?!=)/],className:{1:"type",
+ 3:"variable",5:"operator"}},{begin:[/record/,/\s+/,t],className:{1:"keyword",
+ 3:"title.class"},contains:[s,e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE]},{
+ beginKeywords:"new throw return else",relevance:0},{
+ begin:["(?:"+a+"\\s+)",e.UNDERSCORE_IDENT_RE,/\s*(?=\()/],className:{
+ 2:"title.function"},keywords:i,contains:[{className:"params",begin:/\(/,
+ end:/\)/,keywords:i,relevance:0,
+ contains:[r,e.APOS_STRING_MODE,e.QUOTE_STRING_MODE,me,e.C_BLOCK_COMMENT_MODE]
+ },e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE]},me,r]}},grmr_javascript:Oe,
+ grmr_json:e=>{const n=["true","false","null"],t={scope:"literal",
+ beginKeywords:n.join(" ")};return{name:"JSON",keywords:{literal:n},contains:[{
+ className:"attr",begin:/"(\\.|[^\\"\r\n])*"(?=\s*:)/,relevance:1.01},{
+ match:/[{}[\],:]/,className:"punctuation",relevance:0
+ },e.QUOTE_STRING_MODE,t,e.C_NUMBER_MODE,e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE],
+ illegal:"\\S"}},grmr_kotlin:e=>{const n={
+ keyword:"abstract as val var vararg get set class object open private protected public noinline crossinline dynamic final enum if else do while for when throw try catch finally import package is in fun override companion reified inline lateinit init interface annotation data sealed internal infix operator out by constructor super tailrec where const inner suspend typealias external expect actual",
+ built_in:"Byte Short Char Int Long Boolean Float Double Void Unit Nothing",
+ literal:"true false null"},t={className:"symbol",begin:e.UNDERSCORE_IDENT_RE+"@"
+ },a={className:"subst",begin:/\$\{/,end:/\}/,contains:[e.C_NUMBER_MODE]},i={
+ className:"variable",begin:"\\$"+e.UNDERSCORE_IDENT_RE},r={className:"string",
+ variants:[{begin:'"""',end:'"""(?=[^"])',contains:[i,a]},{begin:"'",end:"'",
+ illegal:/\n/,contains:[e.BACKSLASH_ESCAPE]},{begin:'"',end:'"',illegal:/\n/,
+ contains:[e.BACKSLASH_ESCAPE,i,a]}]};a.contains.push(r);const s={
+ className:"meta",
+ begin:"@(?:file|property|field|get|set|receiver|param|setparam|delegate)\\s*:(?:\\s*"+e.UNDERSCORE_IDENT_RE+")?"
+ },o={className:"meta",begin:"@"+e.UNDERSCORE_IDENT_RE,contains:[{begin:/\(/,
+ end:/\)/,contains:[e.inherit(r,{className:"string"}),"self"]}]
+ },l=me,c=e.COMMENT("/\\*","\\*/",{contains:[e.C_BLOCK_COMMENT_MODE]}),d={
+ variants:[{className:"type",begin:e.UNDERSCORE_IDENT_RE},{begin:/\(/,end:/\)/,
+ contains:[]}]},g=d;return g.variants[1].contains=[d],d.variants[1].contains=[g],
+ {name:"Kotlin",aliases:["kt","kts"],keywords:n,
+ contains:[e.COMMENT("/\\*\\*","\\*/",{relevance:0,contains:[{className:"doctag",
+ begin:"@[A-Za-z]+"}]}),e.C_LINE_COMMENT_MODE,c,{className:"keyword",
+ begin:/\b(break|continue|return|this)\b/,starts:{contains:[{className:"symbol",
+ begin:/@\w+/}]}},t,s,o,{className:"function",beginKeywords:"fun",end:"[(]|$",
+ returnBegin:!0,excludeEnd:!0,keywords:n,relevance:5,contains:[{
+ begin:e.UNDERSCORE_IDENT_RE+"\\s*\\(",returnBegin:!0,relevance:0,
+ contains:[e.UNDERSCORE_TITLE_MODE]},{className:"type",begin:/,end:/>/,
+ keywords:"reified",relevance:0},{className:"params",begin:/\(/,end:/\)/,
+ endsParent:!0,keywords:n,relevance:0,contains:[{begin:/:/,end:/[=,\/]/,
+ endsWithParent:!0,contains:[d,e.C_LINE_COMMENT_MODE,c],relevance:0
+ },e.C_LINE_COMMENT_MODE,c,s,o,r,e.C_NUMBER_MODE]},c]},{
+ begin:[/class|interface|trait/,/\s+/,e.UNDERSCORE_IDENT_RE],beginScope:{
+ 3:"title.class"},keywords:"class interface trait",end:/[:\{(]|$/,excludeEnd:!0,
+ illegal:"extends implements",contains:[{
+ beginKeywords:"public protected internal private constructor"
+ },e.UNDERSCORE_TITLE_MODE,{className:"type",begin:/,end:/>/,excludeBegin:!0,
+ excludeEnd:!0,relevance:0},{className:"type",begin:/[,:]\s*/,end:/[<\(,){\s]|$/,
+ excludeBegin:!0,returnEnd:!0},s,o]},r,{className:"meta",begin:"^#!/usr/bin/env",
+ end:"$",illegal:"\n"},l]}},grmr_less:e=>{
+ const n=ie(e),t=de,a="[\\w-]+",i="("+a+"|@\\{"+a+"\\})",r=[],s=[],o=e=>({
+ className:"string",begin:"~?"+e+".*?"+e}),l=(e,n,t)=>({className:e,begin:n,
+ relevance:t}),c={$pattern:/[a-z-]+/,keyword:"and or not only",
+ attribute:se.join(" ")},d={begin:"\\(",end:"\\)",contains:s,keywords:c,
+ relevance:0}
+ ;s.push(e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,o("'"),o('"'),n.CSS_NUMBER_MODE,{
+ begin:"(url|data-uri)\\(",starts:{className:"string",end:"[\\)\\n]",
+ excludeEnd:!0}
+ },n.HEXCOLOR,d,l("variable","@@?"+a,10),l("variable","@\\{"+a+"\\}"),l("built_in","~?`[^`]*?`"),{
+ className:"attribute",begin:a+"\\s*:",end:":",returnBegin:!0,excludeEnd:!0
+ },n.IMPORTANT,{beginKeywords:"and not"},n.FUNCTION_DISPATCH);const g=s.concat({
+ begin:/\{/,end:/\}/,contains:r}),u={beginKeywords:"when",endsWithParent:!0,
+ contains:[{beginKeywords:"and not"}].concat(s)},b={begin:i+"\\s*:",
+ returnBegin:!0,end:/[;}]/,relevance:0,contains:[{begin:/-(webkit|moz|ms|o)-/
+ },n.CSS_VARIABLE,{className:"attribute",begin:"\\b("+ce.join("|")+")\\b",
+ end:/(?=:)/,starts:{endsWithParent:!0,illegal:"[<=$]",relevance:0,contains:s}}]
+ },m={className:"keyword",
+ begin:"@(import|media|charset|font-face|(-[a-z]+-)?keyframes|supports|document|namespace|page|viewport|host)\\b",
+ starts:{end:"[;{}]",keywords:c,returnEnd:!0,contains:s,relevance:0}},p={
+ className:"variable",variants:[{begin:"@"+a+"\\s*:",relevance:15},{begin:"@"+a
+ }],starts:{end:"[;}]",returnEnd:!0,contains:g}},_={variants:[{
+ begin:"[\\.#:&\\[>]",end:"[;{}]"},{begin:i,end:/\{/}],returnBegin:!0,
+ returnEnd:!0,illegal:"[<='$\"]",relevance:0,
+ contains:[e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,u,l("keyword","all\\b"),l("variable","@\\{"+a+"\\}"),{
+ begin:"\\b("+re.join("|")+")\\b",className:"selector-tag"
+ },n.CSS_NUMBER_MODE,l("selector-tag",i,0),l("selector-id","#"+i),l("selector-class","\\."+i,0),l("selector-tag","&",0),n.ATTRIBUTE_SELECTOR_MODE,{
+ className:"selector-pseudo",begin:":("+oe.join("|")+")"},{
+ className:"selector-pseudo",begin:":(:)?("+le.join("|")+")"},{begin:/\(/,
+ end:/\)/,relevance:0,contains:g},{begin:"!important"},n.FUNCTION_DISPATCH]},h={
+ begin:a+":(:)?"+`(${t.join("|")})`,returnBegin:!0,contains:[_]}
+ ;return r.push(e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,m,p,h,b,_,u,n.FUNCTION_DISPATCH),
+ {name:"Less",case_insensitive:!0,illegal:"[=>'/<($\"]",contains:r}},
+ grmr_lua:e=>{const n="\\[=*\\[",t="\\]=*\\]",a={begin:n,end:t,contains:["self"]
+ },i=[e.COMMENT("--(?!"+n+")","$"),e.COMMENT("--"+n,t,{contains:[a],relevance:10
+ })];return{name:"Lua",keywords:{$pattern:e.UNDERSCORE_IDENT_RE,
+ literal:"true false nil",
+ keyword:"and break do else elseif end for goto if in local not or repeat return then until while",
+ built_in:"_G _ENV _VERSION __index __newindex __mode __call __metatable __tostring __len __gc __add __sub __mul __div __mod __pow __concat __unm __eq __lt __le assert collectgarbage dofile error getfenv getmetatable ipairs load loadfile loadstring module next pairs pcall print rawequal rawget rawset require select setfenv setmetatable tonumber tostring type unpack xpcall arg self coroutine resume yield status wrap create running debug getupvalue debug sethook getmetatable gethook setmetatable setlocal traceback setfenv getinfo setupvalue getlocal getregistry getfenv io lines write close flush open output type read stderr stdin input stdout popen tmpfile math log max acos huge ldexp pi cos tanh pow deg tan cosh sinh random randomseed frexp ceil floor rad abs sqrt modf asin min mod fmod log10 atan2 exp sin atan os exit setlocale date getenv difftime remove time clock tmpname rename execute package preload loadlib loaded loaders cpath config path seeall string sub upper len gfind rep find match char dump gmatch reverse byte format gsub lower table setn insert getn foreachi maxn foreach concat sort remove"
+ },contains:i.concat([{className:"function",beginKeywords:"function",end:"\\)",
+ contains:[e.inherit(e.TITLE_MODE,{
+ begin:"([_a-zA-Z]\\w*\\.)*([_a-zA-Z]\\w*:)?[_a-zA-Z]\\w*"}),{className:"params",
+ begin:"\\(",endsWithParent:!0,contains:i}].concat(i)
+ },e.C_NUMBER_MODE,e.APOS_STRING_MODE,e.QUOTE_STRING_MODE,{className:"string",
+ begin:n,end:t,contains:[a],relevance:5}])}},grmr_makefile:e=>{const n={
+ className:"variable",variants:[{begin:"\\$\\("+e.UNDERSCORE_IDENT_RE+"\\)",
+ contains:[e.BACKSLASH_ESCAPE]},{begin:/\$[@%\^\+\*]/}]},t={className:"string",
+ begin:/"/,end:/"/,contains:[e.BACKSLASH_ESCAPE,n]},a={className:"variable",
+ begin:/\$\([\w-]+\s/,end:/\)/,keywords:{
+ built_in:"subst patsubst strip findstring filter filter-out sort word wordlist firstword lastword dir notdir suffix basename addsuffix addprefix join wildcard realpath abspath error warning shell origin flavor foreach if or and call eval file value"
+ },contains:[n]},i={begin:"^"+e.UNDERSCORE_IDENT_RE+"\\s*(?=[:+?]?=)"},r={
+ className:"section",begin:/^[^\s]+:/,end:/$/,contains:[n]};return{
+ name:"Makefile",aliases:["mk","mak","make"],keywords:{$pattern:/[\w-]+/,
+ keyword:"define endef undefine ifdef ifndef ifeq ifneq else endif include -include sinclude override export unexport private vpath"
+ },contains:[e.HASH_COMMENT_MODE,n,t,a,i,{className:"meta",begin:/^\.PHONY:/,
+ end:/$/,keywords:{$pattern:/[\.\w]+/,keyword:".PHONY"}},r]}},grmr_markdown:e=>{
+ const n={begin:/<\/?[A-Za-z_]/,end:">",subLanguage:"xml",relevance:0},t={
+ variants:[{begin:/\[.+?\]\[.*?\]/,relevance:0},{
+ begin:/\[.+?\]\(((data|javascript|mailto):|(?:http|ftp)s?:\/\/).*?\)/,
+ relevance:2},{
+ begin:e.regex.concat(/\[.+?\]\(/,/[A-Za-z][A-Za-z0-9+.-]*/,/:\/\/.*?\)/),
+ relevance:2},{begin:/\[.+?\]\([./?].*?\)/,relevance:1},{
+ begin:/\[.*?\]\(.*?\)/,relevance:0}],returnBegin:!0,contains:[{match:/\[(?=\])/
+ },{className:"string",relevance:0,begin:"\\[",end:"\\]",excludeBegin:!0,
+ returnEnd:!0},{className:"link",relevance:0,begin:"\\]\\(",end:"\\)",
+ excludeBegin:!0,excludeEnd:!0},{className:"symbol",relevance:0,begin:"\\]\\[",
+ end:"\\]",excludeBegin:!0,excludeEnd:!0}]},a={className:"strong",contains:[],
+ variants:[{begin:/_{2}(?!\s)/,end:/_{2}/},{begin:/\*{2}(?!\s)/,end:/\*{2}/}]
+ },i={className:"emphasis",contains:[],variants:[{begin:/\*(?![*\s])/,end:/\*/},{
+ begin:/_(?![_\s])/,end:/_/,relevance:0}]},r=e.inherit(a,{contains:[]
+ }),s=e.inherit(i,{contains:[]});a.contains.push(s),i.contains.push(r)
+ ;let o=[n,t];return[a,i,r,s].forEach((e=>{e.contains=e.contains.concat(o)
+ })),o=o.concat(a,i),{name:"Markdown",aliases:["md","mkdown","mkd"],contains:[{
+ className:"section",variants:[{begin:"^#{1,6}",end:"$",contains:o},{
+ begin:"(?=^.+?\\n[=-]{2,}$)",contains:[{begin:"^[=-]*$"},{begin:"^",end:"\\n",
+ contains:o}]}]},n,{className:"bullet",begin:"^[ \t]*([*+-]|(\\d+\\.))(?=\\s+)",
+ end:"\\s+",excludeEnd:!0},a,i,{className:"quote",begin:"^>\\s+",contains:o,
+ end:"$"},{className:"code",variants:[{begin:"(`{3,})[^`](.|\\n)*?\\1`*[ ]*"},{
+ begin:"(~{3,})[^~](.|\\n)*?\\1~*[ ]*"},{begin:"```",end:"```+[ ]*$"},{
+ begin:"~~~",end:"~~~+[ ]*$"},{begin:"`.+?`"},{begin:"(?=^( {4}|\\t))",
+ contains:[{begin:"^( {4}|\\t)",end:"(\\n)$"}],relevance:0}]},{
+ begin:"^[-\\*]{3,}",end:"$"},t,{begin:/^\[[^\n]+\]:/,returnBegin:!0,contains:[{
+ className:"symbol",begin:/\[/,end:/\]/,excludeBegin:!0,excludeEnd:!0},{
+ className:"link",begin:/:\s*/,end:/$/,excludeBegin:!0}]}]}},grmr_objectivec:e=>{
+ const n=/[a-zA-Z@][a-zA-Z0-9_]*/,t={$pattern:n,
+ keyword:["@interface","@class","@protocol","@implementation"]};return{
+ name:"Objective-C",aliases:["mm","objc","obj-c","obj-c++","objective-c++"],
+ keywords:{"variable.language":["this","super"],$pattern:n,
+ keyword:["while","export","sizeof","typedef","const","struct","for","union","volatile","static","mutable","if","do","return","goto","enum","else","break","extern","asm","case","default","register","explicit","typename","switch","continue","inline","readonly","assign","readwrite","self","@synchronized","id","typeof","nonatomic","IBOutlet","IBAction","strong","weak","copy","in","out","inout","bycopy","byref","oneway","__strong","__weak","__block","__autoreleasing","@private","@protected","@public","@try","@property","@end","@throw","@catch","@finally","@autoreleasepool","@synthesize","@dynamic","@selector","@optional","@required","@encode","@package","@import","@defs","@compatibility_alias","__bridge","__bridge_transfer","__bridge_retained","__bridge_retain","__covariant","__contravariant","__kindof","_Nonnull","_Nullable","_Null_unspecified","__FUNCTION__","__PRETTY_FUNCTION__","__attribute__","getter","setter","retain","unsafe_unretained","nonnull","nullable","null_unspecified","null_resettable","class","instancetype","NS_DESIGNATED_INITIALIZER","NS_UNAVAILABLE","NS_REQUIRES_SUPER","NS_RETURNS_INNER_POINTER","NS_INLINE","NS_AVAILABLE","NS_DEPRECATED","NS_ENUM","NS_OPTIONS","NS_SWIFT_UNAVAILABLE","NS_ASSUME_NONNULL_BEGIN","NS_ASSUME_NONNULL_END","NS_REFINED_FOR_SWIFT","NS_SWIFT_NAME","NS_SWIFT_NOTHROW","NS_DURING","NS_HANDLER","NS_ENDHANDLER","NS_VALUERETURN","NS_VOIDRETURN"],
+ literal:["false","true","FALSE","TRUE","nil","YES","NO","NULL"],
+ built_in:["dispatch_once_t","dispatch_queue_t","dispatch_sync","dispatch_async","dispatch_once"],
+ type:["int","float","char","unsigned","signed","short","long","double","wchar_t","unichar","void","bool","BOOL","id|0","_Bool"]
+ },illegal:"",contains:[{className:"built_in",
+ begin:"\\b(AV|CA|CF|CG|CI|CL|CM|CN|CT|MK|MP|MTK|MTL|NS|SCN|SK|UI|WK|XC)\\w+"
+ },e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,e.C_NUMBER_MODE,e.QUOTE_STRING_MODE,e.APOS_STRING_MODE,{
+ className:"string",variants:[{begin:'@"',end:'"',illegal:"\\n",
+ contains:[e.BACKSLASH_ESCAPE]}]},{className:"meta",begin:/#\s*[a-z]+\b/,end:/$/,
+ keywords:{
+ keyword:"if else elif endif define undef warning error line pragma ifdef ifndef include"
+ },contains:[{begin:/\\\n/,relevance:0},e.inherit(e.QUOTE_STRING_MODE,{
+ className:"string"}),{className:"string",begin:/<.*?>/,end:/$/,illegal:"\\n"
+ },e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE]},{className:"class",
+ begin:"("+t.keyword.join("|")+")\\b",end:/(\{|$)/,excludeEnd:!0,keywords:t,
+ contains:[e.UNDERSCORE_TITLE_MODE]},{begin:"\\."+e.UNDERSCORE_IDENT_RE,
+ relevance:0}]}},grmr_perl:e=>{const n=e.regex,t=/[dualxmsipngr]{0,12}/,a={
+ $pattern:/[\w.]+/,
+ keyword:"abs accept alarm and atan2 bind binmode bless break caller chdir chmod chomp chop chown chr chroot close closedir connect continue cos crypt dbmclose dbmopen defined delete die do dump each else elsif endgrent endhostent endnetent endprotoent endpwent endservent eof eval exec exists exit exp fcntl fileno flock for foreach fork format formline getc getgrent getgrgid getgrnam gethostbyaddr gethostbyname gethostent getlogin getnetbyaddr getnetbyname getnetent getpeername getpgrp getpriority getprotobyname getprotobynumber getprotoent getpwent getpwnam getpwuid getservbyname getservbyport getservent getsockname getsockopt given glob gmtime goto grep gt hex if index int ioctl join keys kill last lc lcfirst length link listen local localtime log lstat lt ma map mkdir msgctl msgget msgrcv msgsnd my ne next no not oct open opendir or ord our pack package pipe pop pos print printf prototype push q|0 qq quotemeta qw qx rand read readdir readline readlink readpipe recv redo ref rename require reset return reverse rewinddir rindex rmdir say scalar seek seekdir select semctl semget semop send setgrent sethostent setnetent setpgrp setpriority setprotoent setpwent setservent setsockopt shift shmctl shmget shmread shmwrite shutdown sin sleep socket socketpair sort splice split sprintf sqrt srand stat state study sub substr symlink syscall sysopen sysread sysseek system syswrite tell telldir tie tied time times tr truncate uc ucfirst umask undef unless unlink unpack unshift untie until use utime values vec wait waitpid wantarray warn when while write x|0 xor y|0"
+ },i={className:"subst",begin:"[$@]\\{",end:"\\}",keywords:a},r={begin:/->\{/,
+ end:/\}/},s={variants:[{begin:/\$\d/},{
+ begin:n.concat(/[$%@](\^\w\b|#\w+(::\w+)*|\{\w+\}|\w+(::\w*)*)/,"(?![A-Za-z])(?![@$%])")
+ },{begin:/[$%@][^\s\w{]/,relevance:0}]
+ },o=[e.BACKSLASH_ESCAPE,i,s],l=[/!/,/\//,/\|/,/\?/,/'/,/"/,/#/],c=(e,a,i="\\1")=>{
+ const r="\\1"===i?i:n.concat(i,a)
+ ;return n.concat(n.concat("(?:",e,")"),a,/(?:\\.|[^\\\/])*?/,r,/(?:\\.|[^\\\/])*?/,i,t)
+ },d=(e,a,i)=>n.concat(n.concat("(?:",e,")"),a,/(?:\\.|[^\\\/])*?/,i,t),g=[s,e.HASH_COMMENT_MODE,e.COMMENT(/^=\w/,/=cut/,{
+ endsWithParent:!0}),r,{className:"string",contains:o,variants:[{
+ begin:"q[qwxr]?\\s*\\(",end:"\\)",relevance:5},{begin:"q[qwxr]?\\s*\\[",
+ end:"\\]",relevance:5},{begin:"q[qwxr]?\\s*\\{",end:"\\}",relevance:5},{
+ begin:"q[qwxr]?\\s*\\|",end:"\\|",relevance:5},{begin:"q[qwxr]?\\s*<",end:">",
+ relevance:5},{begin:"qw\\s+q",end:"q",relevance:5},{begin:"'",end:"'",
+ contains:[e.BACKSLASH_ESCAPE]},{begin:'"',end:'"'},{begin:"`",end:"`",
+ contains:[e.BACKSLASH_ESCAPE]},{begin:/\{\w+\}/,relevance:0},{
+ begin:"-?\\w+\\s*=>",relevance:0}]},{className:"number",
+ begin:"(\\b0[0-7_]+)|(\\b0x[0-9a-fA-F_]+)|(\\b[1-9][0-9_]*(\\.[0-9_]+)?)|[0_]\\b",
+ relevance:0},{
+ begin:"(\\/\\/|"+e.RE_STARTERS_RE+"|\\b(split|return|print|reverse|grep)\\b)\\s*",
+ keywords:"split return print reverse grep",relevance:0,
+ contains:[e.HASH_COMMENT_MODE,{className:"regexp",variants:[{
+ begin:c("s|tr|y",n.either(...l,{capture:!0}))},{begin:c("s|tr|y","\\(","\\)")},{
+ begin:c("s|tr|y","\\[","\\]")},{begin:c("s|tr|y","\\{","\\}")}],relevance:2},{
+ className:"regexp",variants:[{begin:/(m|qr)\/\//,relevance:0},{
+ begin:d("(?:m|qr)?",/\//,/\//)},{begin:d("m|qr",n.either(...l,{capture:!0
+ }),/\1/)},{begin:d("m|qr",/\(/,/\)/)},{begin:d("m|qr",/\[/,/\]/)},{
+ begin:d("m|qr",/\{/,/\}/)}]}]},{className:"function",beginKeywords:"sub",
+ end:"(\\s*\\(.*?\\))?[;{]",excludeEnd:!0,relevance:5,contains:[e.TITLE_MODE]},{
+ begin:"-\\w\\b",relevance:0},{begin:"^__DATA__$",end:"^__END__$",
+ subLanguage:"mojolicious",contains:[{begin:"^@@.*",end:"$",className:"comment"}]
+ }];return i.contains=g,r.contains=g,{name:"Perl",aliases:["pl","pm"],keywords:a,
+ contains:g}},grmr_php:e=>{
+ const n=e.regex,t=/(?![A-Za-z0-9])(?![$])/,a=n.concat(/[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*/,t),i=n.concat(/(\\?[A-Z][a-z0-9_\x7f-\xff]+|\\?[A-Z]+(?=[A-Z][a-z0-9_\x7f-\xff])){1,}/,t),r={
+ scope:"variable",match:"\\$+"+a},s={scope:"subst",variants:[{begin:/\$\w+/},{
+ begin:/\{\$/,end:/\}/}]},o=e.inherit(e.APOS_STRING_MODE,{illegal:null
+ }),l="[ \t\n]",c={scope:"string",variants:[e.inherit(e.QUOTE_STRING_MODE,{
+ illegal:null,contains:e.QUOTE_STRING_MODE.contains.concat(s)}),o,{
+ begin:/<<<[ \t]*(?:(\w+)|"(\w+)")\n/,end:/[ \t]*(\w+)\b/,
+ contains:e.QUOTE_STRING_MODE.contains.concat(s),"on:begin":(e,n)=>{
+ n.data._beginMatch=e[1]||e[2]},"on:end":(e,n)=>{
+ n.data._beginMatch!==e[1]&&n.ignoreMatch()}},e.END_SAME_AS_BEGIN({
+ begin:/<<<[ \t]*'(\w+)'\n/,end:/[ \t]*(\w+)\b/})]},d={scope:"number",variants:[{
+ begin:"\\b0[bB][01]+(?:_[01]+)*\\b"},{begin:"\\b0[oO][0-7]+(?:_[0-7]+)*\\b"},{
+ begin:"\\b0[xX][\\da-fA-F]+(?:_[\\da-fA-F]+)*\\b"},{
+ begin:"(?:\\b\\d+(?:_\\d+)*(\\.(?:\\d+(?:_\\d+)*))?|\\B\\.\\d+)(?:[eE][+-]?\\d+)?"
+ }],relevance:0
+ },g=["false","null","true"],u=["__CLASS__","__DIR__","__FILE__","__FUNCTION__","__COMPILER_HALT_OFFSET__","__LINE__","__METHOD__","__NAMESPACE__","__TRAIT__","die","echo","exit","include","include_once","print","require","require_once","array","abstract","and","as","binary","bool","boolean","break","callable","case","catch","class","clone","const","continue","declare","default","do","double","else","elseif","empty","enddeclare","endfor","endforeach","endif","endswitch","endwhile","enum","eval","extends","final","finally","float","for","foreach","from","global","goto","if","implements","instanceof","insteadof","int","integer","interface","isset","iterable","list","match|0","mixed","new","never","object","or","private","protected","public","readonly","real","return","string","switch","throw","trait","try","unset","use","var","void","while","xor","yield"],b=["Error|0","AppendIterator","ArgumentCountError","ArithmeticError","ArrayIterator","ArrayObject","AssertionError","BadFunctionCallException","BadMethodCallException","CachingIterator","CallbackFilterIterator","CompileError","Countable","DirectoryIterator","DivisionByZeroError","DomainException","EmptyIterator","ErrorException","Exception","FilesystemIterator","FilterIterator","GlobIterator","InfiniteIterator","InvalidArgumentException","IteratorIterator","LengthException","LimitIterator","LogicException","MultipleIterator","NoRewindIterator","OutOfBoundsException","OutOfRangeException","OuterIterator","OverflowException","ParentIterator","ParseError","RangeException","RecursiveArrayIterator","RecursiveCachingIterator","RecursiveCallbackFilterIterator","RecursiveDirectoryIterator","RecursiveFilterIterator","RecursiveIterator","RecursiveIteratorIterator","RecursiveRegexIterator","RecursiveTreeIterator","RegexIterator","RuntimeException","SeekableIterator","SplDoublyLinkedList","SplFileInfo","SplFileObject","SplFixedArray","SplHeap","SplMaxHeap","SplMinHeap","SplObjectStorage","SplObserver","SplPriorityQueue","SplQueue","SplStack","SplSubject","SplTempFileObject","TypeError","UnderflowException","UnexpectedValueException","UnhandledMatchError","ArrayAccess","BackedEnum","Closure","Fiber","Generator","Iterator","IteratorAggregate","Serializable","Stringable","Throwable","Traversable","UnitEnum","WeakReference","WeakMap","Directory","__PHP_Incomplete_Class","parent","php_user_filter","self","static","stdClass"],m={
+ keyword:u,literal:(e=>{const n=[];return e.forEach((e=>{
+ n.push(e),e.toLowerCase()===e?n.push(e.toUpperCase()):n.push(e.toLowerCase())
+ })),n})(g),built_in:b},p=e=>e.map((e=>e.replace(/\|\d+$/,""))),_={variants:[{
+ match:[/new/,n.concat(l,"+"),n.concat("(?!",p(b).join("\\b|"),"\\b)"),i],scope:{
+ 1:"keyword",4:"title.class"}}]},h=n.concat(a,"\\b(?!\\()"),f={variants:[{
+ match:[n.concat(/::/,n.lookahead(/(?!class\b)/)),h],scope:{2:"variable.constant"
+ }},{match:[/::/,/class/],scope:{2:"variable.language"}},{
+ match:[i,n.concat(/::/,n.lookahead(/(?!class\b)/)),h],scope:{1:"title.class",
+ 3:"variable.constant"}},{match:[i,n.concat("::",n.lookahead(/(?!class\b)/))],
+ scope:{1:"title.class"}},{match:[i,/::/,/class/],scope:{1:"title.class",
+ 3:"variable.language"}}]},E={scope:"attr",
+ match:n.concat(a,n.lookahead(":"),n.lookahead(/(?!::)/))},y={relevance:0,
+ begin:/\(/,end:/\)/,keywords:m,contains:[E,r,f,e.C_BLOCK_COMMENT_MODE,c,d,_]
+ },N={relevance:0,
+ match:[/\b/,n.concat("(?!fn\\b|function\\b|",p(u).join("\\b|"),"|",p(b).join("\\b|"),"\\b)"),a,n.concat(l,"*"),n.lookahead(/(?=\()/)],
+ scope:{3:"title.function.invoke"},contains:[y]};y.contains.push(N)
+ ;const w=[E,f,e.C_BLOCK_COMMENT_MODE,c,d,_];return{case_insensitive:!1,
+ keywords:m,contains:[{begin:n.concat(/#\[\s*/,i),beginScope:"meta",end:/]/,
+ endScope:"meta",keywords:{literal:g,keyword:["new","array"]},contains:[{
+ begin:/\[/,end:/]/,keywords:{literal:g,keyword:["new","array"]},
+ contains:["self",...w]},...w,{scope:"meta",match:i}]
+ },e.HASH_COMMENT_MODE,e.COMMENT("//","$"),e.COMMENT("/\\*","\\*/",{contains:[{
+ scope:"doctag",match:"@[A-Za-z]+"}]}),{match:/__halt_compiler\(\);/,
+ keywords:"__halt_compiler",starts:{scope:"comment",end:e.MATCH_NOTHING_RE,
+ contains:[{match:/\?>/,scope:"meta",endsParent:!0}]}},{scope:"meta",variants:[{
+ begin:/<\?php/,relevance:10},{begin:/<\?=/},{begin:/<\?/,relevance:.1},{
+ begin:/\?>/}]},{scope:"variable.language",match:/\$this\b/},r,N,f,{
+ match:[/const/,/\s/,a],scope:{1:"keyword",3:"variable.constant"}},_,{
+ scope:"function",relevance:0,beginKeywords:"fn function",end:/[;{]/,
+ excludeEnd:!0,illegal:"[$%\\[]",contains:[{beginKeywords:"use"
+ },e.UNDERSCORE_TITLE_MODE,{begin:"=>",endsParent:!0},{scope:"params",
+ begin:"\\(",end:"\\)",excludeBegin:!0,excludeEnd:!0,keywords:m,
+ contains:["self",r,f,e.C_BLOCK_COMMENT_MODE,c,d]}]},{scope:"class",variants:[{
+ beginKeywords:"enum",illegal:/[($"]/},{beginKeywords:"class interface trait",
+ illegal:/[:($"]/}],relevance:0,end:/\{/,excludeEnd:!0,contains:[{
+ beginKeywords:"extends implements"},e.UNDERSCORE_TITLE_MODE]},{
+ beginKeywords:"namespace",relevance:0,end:";",illegal:/[.']/,
+ contains:[e.inherit(e.UNDERSCORE_TITLE_MODE,{scope:"title.class"})]},{
+ beginKeywords:"use",relevance:0,end:";",contains:[{
+ match:/\b(as|const|function)\b/,scope:"keyword"},e.UNDERSCORE_TITLE_MODE]},c,d]}
+ },grmr_php_template:e=>({name:"PHP template",subLanguage:"xml",contains:[{
+ begin:/<\?(php|=)?/,end:/\?>/,subLanguage:"php",contains:[{begin:"/\\*",
+ end:"\\*/",skip:!0},{begin:'b"',end:'"',skip:!0},{begin:"b'",end:"'",skip:!0
+ },e.inherit(e.APOS_STRING_MODE,{illegal:null,className:null,contains:null,
+ skip:!0}),e.inherit(e.QUOTE_STRING_MODE,{illegal:null,className:null,
+ contains:null,skip:!0})]}]}),grmr_plaintext:e=>({name:"Plain text",
+ aliases:["text","txt"],disableAutodetect:!0}),grmr_python:e=>{
+ const n=e.regex,t=/[\p{XID_Start}_]\p{XID_Continue}*/u,a=["and","as","assert","async","await","break","case","class","continue","def","del","elif","else","except","finally","for","from","global","if","import","in","is","lambda","match","nonlocal|10","not","or","pass","raise","return","try","while","with","yield"],i={
+ $pattern:/[A-Za-z]\w+|__\w+__/,keyword:a,
+ built_in:["__import__","abs","all","any","ascii","bin","bool","breakpoint","bytearray","bytes","callable","chr","classmethod","compile","complex","delattr","dict","dir","divmod","enumerate","eval","exec","filter","float","format","frozenset","getattr","globals","hasattr","hash","help","hex","id","input","int","isinstance","issubclass","iter","len","list","locals","map","max","memoryview","min","next","object","oct","open","ord","pow","print","property","range","repr","reversed","round","set","setattr","slice","sorted","staticmethod","str","sum","super","tuple","type","vars","zip"],
+ literal:["__debug__","Ellipsis","False","None","NotImplemented","True"],
+ type:["Any","Callable","Coroutine","Dict","List","Literal","Generic","Optional","Sequence","Set","Tuple","Type","Union"]
+ },r={className:"meta",begin:/^(>>>|\.\.\.) /},s={className:"subst",begin:/\{/,
+ end:/\}/,keywords:i,illegal:/#/},o={begin:/\{\{/,relevance:0},l={
+ className:"string",contains:[e.BACKSLASH_ESCAPE],variants:[{
+ begin:/([uU]|[bB]|[rR]|[bB][rR]|[rR][bB])?'''/,end:/'''/,
+ contains:[e.BACKSLASH_ESCAPE,r],relevance:10},{
+ begin:/([uU]|[bB]|[rR]|[bB][rR]|[rR][bB])?"""/,end:/"""/,
+ contains:[e.BACKSLASH_ESCAPE,r],relevance:10},{
+ begin:/([fF][rR]|[rR][fF]|[fF])'''/,end:/'''/,
+ contains:[e.BACKSLASH_ESCAPE,r,o,s]},{begin:/([fF][rR]|[rR][fF]|[fF])"""/,
+ end:/"""/,contains:[e.BACKSLASH_ESCAPE,r,o,s]},{begin:/([uU]|[rR])'/,end:/'/,
+ relevance:10},{begin:/([uU]|[rR])"/,end:/"/,relevance:10},{
+ begin:/([bB]|[bB][rR]|[rR][bB])'/,end:/'/},{begin:/([bB]|[bB][rR]|[rR][bB])"/,
+ end:/"/},{begin:/([fF][rR]|[rR][fF]|[fF])'/,end:/'/,
+ contains:[e.BACKSLASH_ESCAPE,o,s]},{begin:/([fF][rR]|[rR][fF]|[fF])"/,end:/"/,
+ contains:[e.BACKSLASH_ESCAPE,o,s]},e.APOS_STRING_MODE,e.QUOTE_STRING_MODE]
+ },c="[0-9](_?[0-9])*",d=`(\\b(${c}))?\\.(${c})|\\b(${c})\\.`,g="\\b|"+a.join("|"),u={
+ className:"number",relevance:0,variants:[{
+ begin:`(\\b(${c})|(${d}))[eE][+-]?(${c})[jJ]?(?=${g})`},{begin:`(${d})[jJ]?`},{
+ begin:`\\b([1-9](_?[0-9])*|0+(_?0)*)[lLjJ]?(?=${g})`},{
+ begin:`\\b0[bB](_?[01])+[lL]?(?=${g})`},{begin:`\\b0[oO](_?[0-7])+[lL]?(?=${g})`
+ },{begin:`\\b0[xX](_?[0-9a-fA-F])+[lL]?(?=${g})`},{begin:`\\b(${c})[jJ](?=${g})`
+ }]},b={className:"comment",begin:n.lookahead(/# type:/),end:/$/,keywords:i,
+ contains:[{begin:/# type:/},{begin:/#/,end:/\b\B/,endsWithParent:!0}]},m={
+ className:"params",variants:[{className:"",begin:/\(\s*\)/,skip:!0},{begin:/\(/,
+ end:/\)/,excludeBegin:!0,excludeEnd:!0,keywords:i,
+ contains:["self",r,u,l,e.HASH_COMMENT_MODE]}]};return s.contains=[l,u,r],{
+ name:"Python",aliases:["py","gyp","ipython"],unicodeRegex:!0,keywords:i,
+ illegal:/(<\/|\?)|=>/,contains:[r,u,{begin:/\bself\b/},{beginKeywords:"if",
+ relevance:0},l,b,e.HASH_COMMENT_MODE,{match:[/\bdef/,/\s+/,t],scope:{
+ 1:"keyword",3:"title.function"},contains:[m]},{variants:[{
+ match:[/\bclass/,/\s+/,t,/\s*/,/\(\s*/,t,/\s*\)/]},{match:[/\bclass/,/\s+/,t]}],
+ scope:{1:"keyword",3:"title.class",6:"title.class.inherited"}},{
+ className:"meta",begin:/^[\t ]*@/,end:/(?=#)|$/,contains:[u,m,l]}]}},
+ grmr_python_repl:e=>({aliases:["pycon"],contains:[{className:"meta.prompt",
+ starts:{end:/ |$/,starts:{end:"$",subLanguage:"python"}},variants:[{
+ begin:/^>>>(?=[ ]|$)/},{begin:/^\.\.\.(?=[ ]|$)/}]}]}),grmr_r:e=>{
+ const n=e.regex,t=/(?:(?:[a-zA-Z]|\.[._a-zA-Z])[._a-zA-Z0-9]*)|\.(?!\d)/,a=n.either(/0[xX][0-9a-fA-F]+\.[0-9a-fA-F]*[pP][+-]?\d+i?/,/0[xX][0-9a-fA-F]+(?:[pP][+-]?\d+)?[Li]?/,/(?:\d+(?:\.\d*)?|\.\d+)(?:[eE][+-]?\d+)?[Li]?/),i=/[=!<>:]=|\|\||&&|:::?|<-|<<-|->>|->|\|>|[-+*\/?!$&|:<=>@^~]|\*\*/,r=n.either(/[()]/,/[{}]/,/\[\[/,/[[\]]/,/\\/,/,/)
+ ;return{name:"R",keywords:{$pattern:t,
+ keyword:"function if in break next repeat else for while",
+ literal:"NULL NA TRUE FALSE Inf NaN NA_integer_|10 NA_real_|10 NA_character_|10 NA_complex_|10",
+ built_in:"LETTERS letters month.abb month.name pi T F abs acos acosh all any anyNA Arg as.call as.character as.complex as.double as.environment as.integer as.logical as.null.default as.numeric as.raw asin asinh atan atanh attr attributes baseenv browser c call ceiling class Conj cos cosh cospi cummax cummin cumprod cumsum digamma dim dimnames emptyenv exp expression floor forceAndCall gamma gc.time globalenv Im interactive invisible is.array is.atomic is.call is.character is.complex is.double is.environment is.expression is.finite is.function is.infinite is.integer is.language is.list is.logical is.matrix is.na is.name is.nan is.null is.numeric is.object is.pairlist is.raw is.recursive is.single is.symbol lazyLoadDBfetch length lgamma list log max min missing Mod names nargs nzchar oldClass on.exit pos.to.env proc.time prod quote range Re rep retracemem return round seq_along seq_len seq.int sign signif sin sinh sinpi sqrt standardGeneric substitute sum switch tan tanh tanpi tracemem trigamma trunc unclass untracemem UseMethod xtfrm"
+ },contains:[e.COMMENT(/#'/,/$/,{contains:[{scope:"doctag",match:/@examples/,
+ starts:{end:n.lookahead(n.either(/\n^#'\s*(?=@[a-zA-Z]+)/,/\n^(?!#')/)),
+ endsParent:!0}},{scope:"doctag",begin:"@param",end:/$/,contains:[{
+ scope:"variable",variants:[{match:t},{match:/`(?:\\.|[^`\\])+`/}],endsParent:!0
+ }]},{scope:"doctag",match:/@[a-zA-Z]+/},{scope:"keyword",match:/\\[a-zA-Z]+/}]
+ }),e.HASH_COMMENT_MODE,{scope:"string",contains:[e.BACKSLASH_ESCAPE],
+ variants:[e.END_SAME_AS_BEGIN({begin:/[rR]"(-*)\(/,end:/\)(-*)"/
+ }),e.END_SAME_AS_BEGIN({begin:/[rR]"(-*)\{/,end:/\}(-*)"/
+ }),e.END_SAME_AS_BEGIN({begin:/[rR]"(-*)\[/,end:/\](-*)"/
+ }),e.END_SAME_AS_BEGIN({begin:/[rR]'(-*)\(/,end:/\)(-*)'/
+ }),e.END_SAME_AS_BEGIN({begin:/[rR]'(-*)\{/,end:/\}(-*)'/
+ }),e.END_SAME_AS_BEGIN({begin:/[rR]'(-*)\[/,end:/\](-*)'/}),{begin:'"',end:'"',
+ relevance:0},{begin:"'",end:"'",relevance:0}]},{relevance:0,variants:[{scope:{
+ 1:"operator",2:"number"},match:[i,a]},{scope:{1:"operator",2:"number"},
+ match:[/%[^%]*%/,a]},{scope:{1:"punctuation",2:"number"},match:[r,a]},{scope:{
+ 2:"number"},match:[/[^a-zA-Z0-9._]|^/,a]}]},{scope:{3:"operator"},
+ match:[t,/\s+/,/<-/,/\s+/]},{scope:"operator",relevance:0,variants:[{match:i},{
+ match:/%[^%]*%/}]},{scope:"punctuation",relevance:0,match:r},{begin:"`",end:"`",
+ contains:[{begin:/\\./}]}]}},grmr_ruby:e=>{
+ const n=e.regex,t="([a-zA-Z_]\\w*[!?=]?|[-+~]@|<<|>>|=~|===?|<=>|[<>]=?|\\*\\*|[-/+%^&*~`|]|\\[\\]=?)",a=n.either(/\b([A-Z]+[a-z0-9]+)+/,/\b([A-Z]+[a-z0-9]+)+[A-Z]+/),i=n.concat(a,/(::\w+)*/),r={
+ "variable.constant":["__FILE__","__LINE__","__ENCODING__"],
+ "variable.language":["self","super"],
+ keyword:["alias","and","begin","BEGIN","break","case","class","defined","do","else","elsif","end","END","ensure","for","if","in","module","next","not","or","redo","require","rescue","retry","return","then","undef","unless","until","when","while","yield","include","extend","prepend","public","private","protected","raise","throw"],
+ built_in:["proc","lambda","attr_accessor","attr_reader","attr_writer","define_method","private_constant","module_function"],
+ literal:["true","false","nil"]},s={className:"doctag",begin:"@[A-Za-z]+"},o={
+ begin:"#<",end:">"},l=[e.COMMENT("#","$",{contains:[s]
+ }),e.COMMENT("^=begin","^=end",{contains:[s],relevance:10
+ }),e.COMMENT("^__END__",e.MATCH_NOTHING_RE)],c={className:"subst",begin:/#\{/,
+ end:/\}/,keywords:r},d={className:"string",contains:[e.BACKSLASH_ESCAPE,c],
+ variants:[{begin:/'/,end:/'/},{begin:/"/,end:/"/},{begin:/`/,end:/`/},{
+ begin:/%[qQwWx]?\(/,end:/\)/},{begin:/%[qQwWx]?\[/,end:/\]/},{
+ begin:/%[qQwWx]?\{/,end:/\}/},{begin:/%[qQwWx]?,end:/>/},{begin:/%[qQwWx]?\//,
+ end:/\//},{begin:/%[qQwWx]?%/,end:/%/},{begin:/%[qQwWx]?-/,end:/-/},{
+ begin:/%[qQwWx]?\|/,end:/\|/},{begin:/\B\?(\\\d{1,3})/},{
+ begin:/\B\?(\\x[A-Fa-f0-9]{1,2})/},{begin:/\B\?(\\u\{?[A-Fa-f0-9]{1,6}\}?)/},{
+ begin:/\B\?(\\M-\\C-|\\M-\\c|\\c\\M-|\\M-|\\C-\\M-)[\x20-\x7e]/},{
+ begin:/\B\?\\(c|C-)[\x20-\x7e]/},{begin:/\B\?\\?\S/},{
+ begin:n.concat(/<<[-~]?'?/,n.lookahead(/(\w+)(?=\W)[^\n]*\n(?:[^\n]*\n)*?\s*\1\b/)),
+ contains:[e.END_SAME_AS_BEGIN({begin:/(\w+)/,end:/(\w+)/,
+ contains:[e.BACKSLASH_ESCAPE,c]})]}]},g="[0-9](_?[0-9])*",u={className:"number",
+ relevance:0,variants:[{
+ begin:`\\b([1-9](_?[0-9])*|0)(\\.(${g}))?([eE][+-]?(${g})|r)?i?\\b`},{
+ begin:"\\b0[dD][0-9](_?[0-9])*r?i?\\b"},{begin:"\\b0[bB][0-1](_?[0-1])*r?i?\\b"
+ },{begin:"\\b0[oO][0-7](_?[0-7])*r?i?\\b"},{
+ begin:"\\b0[xX][0-9a-fA-F](_?[0-9a-fA-F])*r?i?\\b"},{
+ begin:"\\b0(_?[0-7])+r?i?\\b"}]},b={variants:[{match:/\(\)/},{
+ className:"params",begin:/\(/,end:/(?=\))/,excludeBegin:!0,endsParent:!0,
+ keywords:r}]},m=[d,{variants:[{match:[/class\s+/,i,/\s+<\s+/,i]},{
+ match:[/\b(class|module)\s+/,i]}],scope:{2:"title.class",
+ 4:"title.class.inherited"},keywords:r},{match:[/(include|extend)\s+/,i],scope:{
+ 2:"title.class"},keywords:r},{relevance:0,match:[i,/\.new[. (]/],scope:{
+ 1:"title.class"}},{relevance:0,match:/\b[A-Z][A-Z_0-9]+\b/,
+ className:"variable.constant"},{relevance:0,match:a,scope:"title.class"},{
+ match:[/def/,/\s+/,t],scope:{1:"keyword",3:"title.function"},contains:[b]},{
+ begin:e.IDENT_RE+"::"},{className:"symbol",
+ begin:e.UNDERSCORE_IDENT_RE+"(!|\\?)?:",relevance:0},{className:"symbol",
+ begin:":(?!\\s)",contains:[d,{begin:t}],relevance:0},u,{className:"variable",
+ begin:"(\\$\\W)|((\\$|@@?)(\\w+))(?=[^@$?])(?![A-Za-z])(?![@$?'])"},{
+ className:"params",begin:/\|/,end:/\|/,excludeBegin:!0,excludeEnd:!0,
+ relevance:0,keywords:r},{begin:"("+e.RE_STARTERS_RE+"|unless)\\s*",
+ keywords:"unless",contains:[{className:"regexp",contains:[e.BACKSLASH_ESCAPE,c],
+ illegal:/\n/,variants:[{begin:"/",end:"/[a-z]*"},{begin:/%r\{/,end:/\}[a-z]*/},{
+ begin:"%r\\(",end:"\\)[a-z]*"},{begin:"%r!",end:"![a-z]*"},{begin:"%r\\[",
+ end:"\\][a-z]*"}]}].concat(o,l),relevance:0}].concat(o,l)
+ ;c.contains=m,b.contains=m;const p=[{begin:/^\s*=>/,starts:{end:"$",contains:m}
+ },{className:"meta.prompt",
+ begin:"^([>?]>|[\\w#]+\\(\\w+\\):\\d+:\\d+[>*]|(\\w+-)?\\d+\\.\\d+\\.\\d+(p\\d+)?[^\\d][^>]+>)(?=[ ])",
+ starts:{end:"$",keywords:r,contains:m}}];return l.unshift(o),{name:"Ruby",
+ aliases:["rb","gemspec","podspec","thor","irb"],keywords:r,illegal:/\/\*/,
+ contains:[e.SHEBANG({binary:"ruby"})].concat(p).concat(l).concat(m)}},
+ grmr_rust:e=>{const n=e.regex,t={className:"title.function.invoke",relevance:0,
+ begin:n.concat(/\b/,/(?!let|for|while|if|else|match\b)/,e.IDENT_RE,n.lookahead(/\s*\(/))
+ },a="([ui](8|16|32|64|128|size)|f(32|64))?",i=["drop ","Copy","Send","Sized","Sync","Drop","Fn","FnMut","FnOnce","ToOwned","Clone","Debug","PartialEq","PartialOrd","Eq","Ord","AsRef","AsMut","Into","From","Default","Iterator","Extend","IntoIterator","DoubleEndedIterator","ExactSizeIterator","SliceConcatExt","ToString","assert!","assert_eq!","bitflags!","bytes!","cfg!","col!","concat!","concat_idents!","debug_assert!","debug_assert_eq!","env!","eprintln!","panic!","file!","format!","format_args!","include_bytes!","include_str!","line!","local_data_key!","module_path!","option_env!","print!","println!","select!","stringify!","try!","unimplemented!","unreachable!","vec!","write!","writeln!","macro_rules!","assert_ne!","debug_assert_ne!"],r=["i8","i16","i32","i64","i128","isize","u8","u16","u32","u64","u128","usize","f32","f64","str","char","bool","Box","Option","Result","String","Vec"]
+ ;return{name:"Rust",aliases:["rs"],keywords:{$pattern:e.IDENT_RE+"!?",type:r,
+ keyword:["abstract","as","async","await","become","box","break","const","continue","crate","do","dyn","else","enum","extern","false","final","fn","for","if","impl","in","let","loop","macro","match","mod","move","mut","override","priv","pub","ref","return","self","Self","static","struct","super","trait","true","try","type","typeof","unsafe","unsized","use","virtual","where","while","yield"],
+ literal:["true","false","Some","None","Ok","Err"],built_in:i},illegal:"",
+ contains:[e.C_LINE_COMMENT_MODE,e.COMMENT("/\\*","\\*/",{contains:["self"]
+ }),e.inherit(e.QUOTE_STRING_MODE,{begin:/b?"/,illegal:null}),{
+ className:"string",variants:[{begin:/b?r(#*)"(.|\n)*?"\1(?!#)/},{
+ begin:/b?'\\?(x\w{2}|u\w{4}|U\w{8}|.)'/}]},{className:"symbol",
+ begin:/'[a-zA-Z_][a-zA-Z0-9_]*/},{className:"number",variants:[{
+ begin:"\\b0b([01_]+)"+a},{begin:"\\b0o([0-7_]+)"+a},{
+ begin:"\\b0x([A-Fa-f0-9_]+)"+a},{
+ begin:"\\b(\\d[\\d_]*(\\.[0-9_]+)?([eE][+-]?[0-9_]+)?)"+a}],relevance:0},{
+ begin:[/fn/,/\s+/,e.UNDERSCORE_IDENT_RE],className:{1:"keyword",
+ 3:"title.function"}},{className:"meta",begin:"#!?\\[",end:"\\]",contains:[{
+ className:"string",begin:/"/,end:/"/}]},{
+ begin:[/let/,/\s+/,/(?:mut\s+)?/,e.UNDERSCORE_IDENT_RE],className:{1:"keyword",
+ 3:"keyword",4:"variable"}},{
+ begin:[/for/,/\s+/,e.UNDERSCORE_IDENT_RE,/\s+/,/in/],className:{1:"keyword",
+ 3:"variable",5:"keyword"}},{begin:[/type/,/\s+/,e.UNDERSCORE_IDENT_RE],
+ className:{1:"keyword",3:"title.class"}},{
+ begin:[/(?:trait|enum|struct|union|impl|for)/,/\s+/,e.UNDERSCORE_IDENT_RE],
+ className:{1:"keyword",3:"title.class"}},{begin:e.IDENT_RE+"::",keywords:{
+ keyword:"Self",built_in:i,type:r}},{className:"punctuation",begin:"->"},t]}},
+ grmr_scss:e=>{const n=ie(e),t=le,a=oe,i="@[a-z-]+",r={className:"variable",
+ begin:"(\\$[a-zA-Z-][a-zA-Z0-9_-]*)\\b",relevance:0};return{name:"SCSS",
+ case_insensitive:!0,illegal:"[=/|']",
+ contains:[e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,n.CSS_NUMBER_MODE,{
+ className:"selector-id",begin:"#[A-Za-z0-9_-]+",relevance:0},{
+ className:"selector-class",begin:"\\.[A-Za-z0-9_-]+",relevance:0
+ },n.ATTRIBUTE_SELECTOR_MODE,{className:"selector-tag",
+ begin:"\\b("+re.join("|")+")\\b",relevance:0},{className:"selector-pseudo",
+ begin:":("+a.join("|")+")"},{className:"selector-pseudo",
+ begin:":(:)?("+t.join("|")+")"},r,{begin:/\(/,end:/\)/,
+ contains:[n.CSS_NUMBER_MODE]},n.CSS_VARIABLE,{className:"attribute",
+ begin:"\\b("+ce.join("|")+")\\b"},{
+ begin:"\\b(whitespace|wait|w-resize|visible|vertical-text|vertical-ideographic|uppercase|upper-roman|upper-alpha|underline|transparent|top|thin|thick|text|text-top|text-bottom|tb-rl|table-header-group|table-footer-group|sw-resize|super|strict|static|square|solid|small-caps|separate|se-resize|scroll|s-resize|rtl|row-resize|ridge|right|repeat|repeat-y|repeat-x|relative|progress|pointer|overline|outside|outset|oblique|nowrap|not-allowed|normal|none|nw-resize|no-repeat|no-drop|newspaper|ne-resize|n-resize|move|middle|medium|ltr|lr-tb|lowercase|lower-roman|lower-alpha|loose|list-item|line|line-through|line-edge|lighter|left|keep-all|justify|italic|inter-word|inter-ideograph|inside|inset|inline|inline-block|inherit|inactive|ideograph-space|ideograph-parenthesis|ideograph-numeric|ideograph-alpha|horizontal|hidden|help|hand|groove|fixed|ellipsis|e-resize|double|dotted|distribute|distribute-space|distribute-letter|distribute-all-lines|disc|disabled|default|decimal|dashed|crosshair|collapse|col-resize|circle|char|center|capitalize|break-word|break-all|bottom|both|bolder|bold|block|bidi-override|below|baseline|auto|always|all-scroll|absolute|table|table-cell)\\b"
+ },{begin:/:/,end:/[;}{]/,relevance:0,
+ contains:[n.BLOCK_COMMENT,r,n.HEXCOLOR,n.CSS_NUMBER_MODE,e.QUOTE_STRING_MODE,e.APOS_STRING_MODE,n.IMPORTANT,n.FUNCTION_DISPATCH]
+ },{begin:"@(page|font-face)",keywords:{$pattern:i,keyword:"@page @font-face"}},{
+ begin:"@",end:"[{;]",returnBegin:!0,keywords:{$pattern:/[a-z-]+/,
+ keyword:"and or not only",attribute:se.join(" ")},contains:[{begin:i,
+ className:"keyword"},{begin:/[a-z-]+(?=:)/,className:"attribute"
+ },r,e.QUOTE_STRING_MODE,e.APOS_STRING_MODE,n.HEXCOLOR,n.CSS_NUMBER_MODE]
+ },n.FUNCTION_DISPATCH]}},grmr_shell:e=>({name:"Shell Session",
+ aliases:["console","shellsession"],contains:[{className:"meta.prompt",
+ begin:/^\s{0,3}[/~\w\d[\]()@-]*[>%$#][ ]?/,starts:{end:/[^\\](?=\s*$)/,
+ subLanguage:"bash"}}]}),grmr_sql:e=>{
+ const n=e.regex,t=e.COMMENT("--","$"),a=["true","false","unknown"],i=["bigint","binary","blob","boolean","char","character","clob","date","dec","decfloat","decimal","float","int","integer","interval","nchar","nclob","national","numeric","real","row","smallint","time","timestamp","varchar","varying","varbinary"],r=["abs","acos","array_agg","asin","atan","avg","cast","ceil","ceiling","coalesce","corr","cos","cosh","count","covar_pop","covar_samp","cume_dist","dense_rank","deref","element","exp","extract","first_value","floor","json_array","json_arrayagg","json_exists","json_object","json_objectagg","json_query","json_table","json_table_primitive","json_value","lag","last_value","lead","listagg","ln","log","log10","lower","max","min","mod","nth_value","ntile","nullif","percent_rank","percentile_cont","percentile_disc","position","position_regex","power","rank","regr_avgx","regr_avgy","regr_count","regr_intercept","regr_r2","regr_slope","regr_sxx","regr_sxy","regr_syy","row_number","sin","sinh","sqrt","stddev_pop","stddev_samp","substring","substring_regex","sum","tan","tanh","translate","translate_regex","treat","trim","trim_array","unnest","upper","value_of","var_pop","var_samp","width_bucket"],s=["create table","insert into","primary key","foreign key","not null","alter table","add constraint","grouping sets","on overflow","character set","respect nulls","ignore nulls","nulls first","nulls last","depth first","breadth first"],o=r,l=["abs","acos","all","allocate","alter","and","any","are","array","array_agg","array_max_cardinality","as","asensitive","asin","asymmetric","at","atan","atomic","authorization","avg","begin","begin_frame","begin_partition","between","bigint","binary","blob","boolean","both","by","call","called","cardinality","cascaded","case","cast","ceil","ceiling","char","char_length","character","character_length","check","classifier","clob","close","coalesce","collate","collect","column","commit","condition","connect","constraint","contains","convert","copy","corr","corresponding","cos","cosh","count","covar_pop","covar_samp","create","cross","cube","cume_dist","current","current_catalog","current_date","current_default_transform_group","current_path","current_role","current_row","current_schema","current_time","current_timestamp","current_path","current_role","current_transform_group_for_type","current_user","cursor","cycle","date","day","deallocate","dec","decimal","decfloat","declare","default","define","delete","dense_rank","deref","describe","deterministic","disconnect","distinct","double","drop","dynamic","each","element","else","empty","end","end_frame","end_partition","end-exec","equals","escape","every","except","exec","execute","exists","exp","external","extract","false","fetch","filter","first_value","float","floor","for","foreign","frame_row","free","from","full","function","fusion","get","global","grant","group","grouping","groups","having","hold","hour","identity","in","indicator","initial","inner","inout","insensitive","insert","int","integer","intersect","intersection","interval","into","is","join","json_array","json_arrayagg","json_exists","json_object","json_objectagg","json_query","json_table","json_table_primitive","json_value","lag","language","large","last_value","lateral","lead","leading","left","like","like_regex","listagg","ln","local","localtime","localtimestamp","log","log10","lower","match","match_number","match_recognize","matches","max","member","merge","method","min","minute","mod","modifies","module","month","multiset","national","natural","nchar","nclob","new","no","none","normalize","not","nth_value","ntile","null","nullif","numeric","octet_length","occurrences_regex","of","offset","old","omit","on","one","only","open","or","order","out","outer","over","overlaps","overlay","parameter","partition","pattern","per","percent","percent_rank","percentile_cont","percentile_disc","period","portion","position","position_regex","power","precedes","precision","prepare","primary","procedure","ptf","range","rank","reads","real","recursive","ref","references","referencing","regr_avgx","regr_avgy","regr_count","regr_intercept","regr_r2","regr_slope","regr_sxx","regr_sxy","regr_syy","release","result","return","returns","revoke","right","rollback","rollup","row","row_number","rows","running","savepoint","scope","scroll","search","second","seek","select","sensitive","session_user","set","show","similar","sin","sinh","skip","smallint","some","specific","specifictype","sql","sqlexception","sqlstate","sqlwarning","sqrt","start","static","stddev_pop","stddev_samp","submultiset","subset","substring","substring_regex","succeeds","sum","symmetric","system","system_time","system_user","table","tablesample","tan","tanh","then","time","timestamp","timezone_hour","timezone_minute","to","trailing","translate","translate_regex","translation","treat","trigger","trim","trim_array","true","truncate","uescape","union","unique","unknown","unnest","update","upper","user","using","value","values","value_of","var_pop","var_samp","varbinary","varchar","varying","versioning","when","whenever","where","width_bucket","window","with","within","without","year","add","asc","collation","desc","final","first","last","view"].filter((e=>!r.includes(e))),c={
+ begin:n.concat(/\b/,n.either(...o),/\s*\(/),relevance:0,keywords:{built_in:o}}
+ ;return{name:"SQL",case_insensitive:!0,illegal:/[{}]|<\//,keywords:{
+ $pattern:/\b[\w\.]+/,keyword:((e,{exceptions:n,when:t}={})=>{const a=t
+ ;return n=n||[],e.map((e=>e.match(/\|\d+$/)||n.includes(e)?e:a(e)?e+"|0":e))
+ })(l,{when:e=>e.length<3}),literal:a,type:i,
+ built_in:["current_catalog","current_date","current_default_transform_group","current_path","current_role","current_schema","current_transform_group_for_type","current_user","session_user","system_time","system_user","current_time","localtime","current_timestamp","localtimestamp"]
+ },contains:[{begin:n.either(...s),relevance:0,keywords:{$pattern:/[\w\.]+/,
+ keyword:l.concat(s),literal:a,type:i}},{className:"type",
+ begin:n.either("double precision","large object","with timezone","without timezone")
+ },c,{className:"variable",begin:/@[a-z0-9][a-z0-9_]*/},{className:"string",
+ variants:[{begin:/'/,end:/'/,contains:[{begin:/''/}]}]},{begin:/"/,end:/"/,
+ contains:[{begin:/""/}]},e.C_NUMBER_MODE,e.C_BLOCK_COMMENT_MODE,t,{
+ className:"operator",begin:/[-+*/=%^~]|&&?|\|\|?|!=?|<(?:=>?|<|>)?|>[>=]?/,
+ relevance:0}]}},grmr_swift:e=>{const n={match:/\s+/,relevance:0
+ },t=e.COMMENT("/\\*","\\*/",{contains:["self"]}),a=[e.C_LINE_COMMENT_MODE,t],i={
+ match:[/\./,m(...xe,...Me)],className:{2:"keyword"}},r={match:b(/\./,m(...Ae)),
+ relevance:0},s=Ae.filter((e=>"string"==typeof e)).concat(["_|0"]),o={variants:[{
+ className:"keyword",
+ match:m(...Ae.filter((e=>"string"!=typeof e)).concat(Se).map(ke),...Me)}]},l={
+ $pattern:m(/\b\w+/,/#\w+/),keyword:s.concat(Re),literal:Ce},c=[i,r,o],g=[{
+ match:b(/\./,m(...De)),relevance:0},{className:"built_in",
+ match:b(/\b/,m(...De),/(?=\()/)}],u={match:/->/,relevance:0},p=[u,{
+ className:"operator",relevance:0,variants:[{match:Be},{match:`\\.(\\.|${Le})+`}]
+ }],_="([0-9]_*)+",h="([0-9a-fA-F]_*)+",f={className:"number",relevance:0,
+ variants:[{match:`\\b(${_})(\\.(${_}))?([eE][+-]?(${_}))?\\b`},{
+ match:`\\b0x(${h})(\\.(${h}))?([pP][+-]?(${_}))?\\b`},{match:/\b0o([0-7]_*)+\b/
+ },{match:/\b0b([01]_*)+\b/}]},E=(e="")=>({className:"subst",variants:[{
+ match:b(/\\/,e,/[0\\tnr"']/)},{match:b(/\\/,e,/u\{[0-9a-fA-F]{1,8}\}/)}]
+ }),y=(e="")=>({className:"subst",match:b(/\\/,e,/[\t ]*(?:[\r\n]|\r\n)/)
+ }),N=(e="")=>({className:"subst",label:"interpol",begin:b(/\\/,e,/\(/),end:/\)/
+ }),w=(e="")=>({begin:b(e,/"""/),end:b(/"""/,e),contains:[E(e),y(e),N(e)]
+ }),v=(e="")=>({begin:b(e,/"/),end:b(/"/,e),contains:[E(e),N(e)]}),O={
+ className:"string",
+ variants:[w(),w("#"),w("##"),w("###"),v(),v("#"),v("##"),v("###")]
+ },k=[e.BACKSLASH_ESCAPE,{begin:/\[/,end:/\]/,relevance:0,
+ contains:[e.BACKSLASH_ESCAPE]}],x={begin:/\/[^\s](?=[^/\n]*\/)/,end:/\//,
+ contains:k},M=e=>{const n=b(e,/\//),t=b(/\//,e);return{begin:n,end:t,
+ contains:[...k,{scope:"comment",begin:`#(?!.*${t})`,end:/$/}]}},S={
+ scope:"regexp",variants:[M("###"),M("##"),M("#"),x]},A={match:b(/`/,Fe,/`/)
+ },C=[A,{className:"variable",match:/\$\d+/},{className:"variable",
+ match:`\\$${ze}+`}],T=[{match:/(@|#(un)?)available/,scope:"keyword",starts:{
+ contains:[{begin:/\(/,end:/\)/,keywords:Pe,contains:[...p,f,O]}]}},{
+ scope:"keyword",match:b(/@/,m(...je))},{scope:"meta",match:b(/@/,Fe)}],R={
+ match:d(/\b[A-Z]/),relevance:0,contains:[{className:"type",
+ match:b(/(AV|CA|CF|CG|CI|CL|CM|CN|CT|MK|MP|MTK|MTL|NS|SCN|SK|UI|WK|XC)/,ze,"+")
+ },{className:"type",match:Ue,relevance:0},{match:/[?!]+/,relevance:0},{
+ match:/\.\.\./,relevance:0},{match:b(/\s+&\s+/,d(Ue)),relevance:0}]},D={
+ begin:/,end:/>/,keywords:l,contains:[...a,...c,...T,u,R]};R.contains.push(D)
+ ;const I={begin:/\(/,end:/\)/,relevance:0,keywords:l,contains:["self",{
+ match:b(Fe,/\s*:/),keywords:"_|0",relevance:0
+ },...a,S,...c,...g,...p,f,O,...C,...T,R]},L={begin:/,end:/>/,
+ keywords:"repeat each",contains:[...a,R]},B={begin:/\(/,end:/\)/,keywords:l,
+ contains:[{begin:m(d(b(Fe,/\s*:/)),d(b(Fe,/\s+/,Fe,/\s*:/))),end:/:/,
+ relevance:0,contains:[{className:"keyword",match:/\b_\b/},{className:"params",
+ match:Fe}]},...a,...c,...p,f,O,...T,R,I],endsParent:!0,illegal:/["']/},$={
+ match:[/(func|macro)/,/\s+/,m(A.match,Fe,Be)],className:{1:"keyword",
+ 3:"title.function"},contains:[L,B,n],illegal:[/\[/,/%/]},z={
+ match:[/\b(?:subscript|init[?!]?)/,/\s*(?=[<(])/],className:{1:"keyword"},
+ contains:[L,B,n],illegal:/\[|%/},F={match:[/operator/,/\s+/,Be],className:{
+ 1:"keyword",3:"title"}},U={begin:[/precedencegroup/,/\s+/,Ue],className:{
+ 1:"keyword",3:"title"},contains:[R],keywords:[...Te,...Ce],end:/}/}
+ ;for(const e of O.variants){const n=e.contains.find((e=>"interpol"===e.label))
+ ;n.keywords=l;const t=[...c,...g,...p,f,O,...C];n.contains=[...t,{begin:/\(/,
+ end:/\)/,contains:["self",...t]}]}return{name:"Swift",keywords:l,
+ contains:[...a,$,z,{beginKeywords:"struct protocol class extension enum actor",
+ end:"\\{",excludeEnd:!0,keywords:l,contains:[e.inherit(e.TITLE_MODE,{
+ className:"title.class",begin:/[A-Za-z$_][\u00C0-\u02B80-9A-Za-z$_]*/}),...c]
+ },F,U,{beginKeywords:"import",end:/$/,contains:[...a],relevance:0
+ },S,...c,...g,...p,f,O,...C,...T,R,I]}},grmr_typescript:e=>{
+ const n=Oe(e),t=_e,a=["any","void","number","boolean","string","object","never","symbol","bigint","unknown"],i={
+ beginKeywords:"namespace",end:/\{/,excludeEnd:!0,
+ contains:[n.exports.CLASS_REFERENCE]},r={beginKeywords:"interface",end:/\{/,
+ excludeEnd:!0,keywords:{keyword:"interface extends",built_in:a},
+ contains:[n.exports.CLASS_REFERENCE]},s={$pattern:_e,
+ keyword:he.concat(["type","namespace","interface","public","private","protected","implements","declare","abstract","readonly","enum","override"]),
+ literal:fe,built_in:ve.concat(a),"variable.language":we},o={className:"meta",
+ begin:"@"+t},l=(e,n,t)=>{const a=e.contains.findIndex((e=>e.label===n))
+ ;if(-1===a)throw Error("can not find mode to replace");e.contains.splice(a,1,t)}
+ ;return Object.assign(n.keywords,s),
+ n.exports.PARAMS_CONTAINS.push(o),n.contains=n.contains.concat([o,i,r]),
+ l(n,"shebang",e.SHEBANG()),l(n,"use_strict",{className:"meta",relevance:10,
+ begin:/^\s*['"]use strict['"]/
+ }),n.contains.find((e=>"func.def"===e.label)).relevance=0,Object.assign(n,{
+ name:"TypeScript",aliases:["ts","tsx","mts","cts"]}),n},grmr_vbnet:e=>{
+ const n=e.regex,t=/\d{1,2}\/\d{1,2}\/\d{4}/,a=/\d{4}-\d{1,2}-\d{1,2}/,i=/(\d|1[012])(:\d+){0,2} *(AM|PM)/,r=/\d{1,2}(:\d{1,2}){1,2}/,s={
+ className:"literal",variants:[{begin:n.concat(/# */,n.either(a,t),/ *#/)},{
+ begin:n.concat(/# */,r,/ *#/)},{begin:n.concat(/# */,i,/ *#/)},{
+ begin:n.concat(/# */,n.either(a,t),/ +/,n.either(i,r),/ *#/)}]
+ },o=e.COMMENT(/'''/,/$/,{contains:[{className:"doctag",begin:/<\/?/,end:/>/}]
+ }),l=e.COMMENT(null,/$/,{variants:[{begin:/'/},{begin:/([\t ]|^)REM(?=\s)/}]})
+ ;return{name:"Visual Basic .NET",aliases:["vb"],case_insensitive:!0,
+ classNameAliases:{label:"symbol"},keywords:{
+ keyword:"addhandler alias aggregate ansi as async assembly auto binary by byref byval call case catch class compare const continue custom declare default delegate dim distinct do each equals else elseif end enum erase error event exit explicit finally for friend from function get global goto group handles if implements imports in inherits interface into iterator join key let lib loop me mid module mustinherit mustoverride mybase myclass namespace narrowing new next notinheritable notoverridable of off on operator option optional order overloads overridable overrides paramarray partial preserve private property protected public raiseevent readonly redim removehandler resume return select set shadows shared skip static step stop structure strict sub synclock take text then throw to try unicode until using when where while widening with withevents writeonly yield",
+ built_in:"addressof and andalso await directcast gettype getxmlnamespace is isfalse isnot istrue like mod nameof new not or orelse trycast typeof xor cbool cbyte cchar cdate cdbl cdec cint clng cobj csbyte cshort csng cstr cuint culng cushort",
+ type:"boolean byte char date decimal double integer long object sbyte short single string uinteger ulong ushort",
+ literal:"true false nothing"},
+ illegal:"//|\\{|\\}|endif|gosub|variant|wend|^\\$ ",contains:[{
+ className:"string",begin:/"(""|[^/n])"C\b/},{className:"string",begin:/"/,
+ end:/"/,illegal:/\n/,contains:[{begin:/""/}]},s,{className:"number",relevance:0,
+ variants:[{begin:/\b\d[\d_]*((\.[\d_]+(E[+-]?[\d_]+)?)|(E[+-]?[\d_]+))[RFD@!#]?/
+ },{begin:/\b\d[\d_]*((U?[SIL])|[%&])?/},{begin:/&H[\dA-F_]+((U?[SIL])|[%&])?/},{
+ begin:/&O[0-7_]+((U?[SIL])|[%&])?/},{begin:/&B[01_]+((U?[SIL])|[%&])?/}]},{
+ className:"label",begin:/^\w+:/},o,l,{className:"meta",
+ begin:/[\t ]*#(const|disable|else|elseif|enable|end|externalsource|if|region)\b/,
+ end:/$/,keywords:{
+ keyword:"const disable else elseif enable end externalsource if region then"},
+ contains:[l]}]}},grmr_wasm:e=>{e.regex;const n=e.COMMENT(/\(;/,/;\)/)
+ ;return n.contains.push("self"),{name:"WebAssembly",keywords:{$pattern:/[\w.]+/,
+ keyword:["anyfunc","block","br","br_if","br_table","call","call_indirect","data","drop","elem","else","end","export","func","global.get","global.set","local.get","local.set","local.tee","get_global","get_local","global","if","import","local","loop","memory","memory.grow","memory.size","module","mut","nop","offset","param","result","return","select","set_global","set_local","start","table","tee_local","then","type","unreachable"]
+ },contains:[e.COMMENT(/;;/,/$/),n,{match:[/(?:offset|align)/,/\s*/,/=/],
+ className:{1:"keyword",3:"operator"}},{className:"variable",begin:/\$[\w_]+/},{
+ match:/(\((?!;)|\))+/,className:"punctuation",relevance:0},{
+ begin:[/(?:func|call|call_indirect)/,/\s+/,/\$[^\s)]+/],className:{1:"keyword",
+ 3:"title.function"}},e.QUOTE_STRING_MODE,{match:/(i32|i64|f32|f64)(?!\.)/,
+ className:"type"},{className:"keyword",
+ match:/\b(f32|f64|i32|i64)(?:\.(?:abs|add|and|ceil|clz|const|convert_[su]\/i(?:32|64)|copysign|ctz|demote\/f64|div(?:_[su])?|eqz?|extend_[su]\/i32|floor|ge(?:_[su])?|gt(?:_[su])?|le(?:_[su])?|load(?:(?:8|16|32)_[su])?|lt(?:_[su])?|max|min|mul|nearest|neg?|or|popcnt|promote\/f32|reinterpret\/[fi](?:32|64)|rem_[su]|rot[lr]|shl|shr_[su]|store(?:8|16|32)?|sqrt|sub|trunc(?:_[su]\/f(?:32|64))?|wrap\/i64|xor))\b/
+ },{className:"number",relevance:0,
+ match:/[+-]?\b(?:\d(?:_?\d)*(?:\.\d(?:_?\d)*)?(?:[eE][+-]?\d(?:_?\d)*)?|0x[\da-fA-F](?:_?[\da-fA-F])*(?:\.[\da-fA-F](?:_?[\da-fA-D])*)?(?:[pP][+-]?\d(?:_?\d)*)?)\b|\binf\b|\bnan(?::0x[\da-fA-F](?:_?[\da-fA-D])*)?\b/
+ }]}},grmr_xml:e=>{
+ const n=e.regex,t=n.concat(/[\p{L}_]/u,n.optional(/[\p{L}0-9_.-]*:/u),/[\p{L}0-9_.-]*/u),a={
+ className:"symbol",begin:/&[a-z]+;|[0-9]+;|[a-f0-9]+;/},i={begin:/\s/,
+ contains:[{className:"keyword",begin:/#?[a-z_][a-z1-9_-]+/,illegal:/\n/}]
+ },r=e.inherit(i,{begin:/\(/,end:/\)/}),s=e.inherit(e.APOS_STRING_MODE,{
+ className:"string"}),o=e.inherit(e.QUOTE_STRING_MODE,{className:"string"}),l={
+ endsWithParent:!0,illegal:/,relevance:0,contains:[{className:"attr",
+ begin:/[\p{L}0-9._:-]+/u,relevance:0},{begin:/=\s*/,relevance:0,contains:[{
+ className:"string",endsParent:!0,variants:[{begin:/"/,end:/"/,contains:[a]},{
+ begin:/'/,end:/'/,contains:[a]},{begin:/[^\s"'=<>`]+/}]}]}]};return{
+ name:"HTML, XML",
+ aliases:["html","xhtml","rss","atom","xjb","xsd","xsl","plist","wsf","svg"],
+ case_insensitive:!0,unicodeRegex:!0,contains:[{className:"meta",begin://,relevance:10,contains:[i,o,s,r,{begin:/\[/,end:/\]/,contains:[{
+ className:"meta",begin://,contains:[i,r,o,s]}]}]
+ },e.COMMENT(//,{relevance:10}),{begin://,
+ relevance:10},a,{className:"meta",end:/\?>/,variants:[{begin:/<\?xml/,
+ relevance:10,contains:[o]},{begin:/<\?[a-z][a-z0-9]+/}]},{className:"tag",
+ begin:/