diff --git a/skills/.skills_store_lock.json b/skills/.skills_store_lock.json new file mode 100644 index 0000000..2e3402c --- /dev/null +++ b/skills/.skills_store_lock.json @@ -0,0 +1,71 @@ +{ + "version": 1, + "skills": { + "speech-recognition": { + "name": "speech-recognition", + "zip_url": "http://lightmake.site/api/v1/download?slug=speech-recognition", + "source": "skillhub", + "version": "1.0.1" + }, + "funasr-transcribe-skill": { + "name": "FunASR 语音转录", + "zip_url": "http://lightmake.site/api/v1/download?slug=funasr-transcribe-skill", + "source": "skillhub", + "version": "1.0.0" + }, + "voice-message": { + "name": "Voice Message", + "zip_url": "http://lightmake.site/api/v1/download?slug=voice-message", + "source": "skillhub", + "version": "1.0.4" + }, + "ai-ppt-generator": { + "name": "Ai Ppt Generator", + "zip_url": "https://lightmake.site/api/v1/download?slug=ai-ppt-generator", + "source": "skillhub", + "version": "1.1.2" + }, + "tavily-search": { + "name": "Tavily Web Search", + "zip_url": "https://lightmake.site/api/v1/download?slug=tavily-search", + "source": "skillhub", + "version": "1.0.0" + }, + "summarize": { + "name": "Summarize", + "zip_url": "https://lightmake.site/api/v1/download?slug=summarize", + "source": "skillhub", + "version": "1.0.0" + }, + "agent-browser": { + "name": "Agent Browser", + "zip_url": "https://lightmake.site/api/v1/download?slug=agent-browser", + "source": "skillhub", + "version": "0.2.0" + }, + "find-skills": { + "name": "Find Skills", + "zip_url": "https://lightmake.site/api/v1/download?slug=find-skills", + "source": "skillhub", + "version": "0.1.0" + }, + "github": { + "name": "Github", + "zip_url": "https://lightmake.site/api/v1/download?slug=github", + "source": "skillhub", + "version": "1.0.0" + }, + "obsidian": { + "name": "Obsidian", + "zip_url": "https://lightmake.site/api/v1/download?slug=obsidian", + "source": "skillhub", + "version": "1.0.0" + }, + "weather": { + "name": "Weather", + "zip_url": "https://lightmake.site/api/v1/download?slug=weather", + "source": "skillhub", + "version": "1.0.0" + } + } +} diff --git a/skills/agent-browser/CONTRIBUTING.md b/skills/agent-browser/CONTRIBUTING.md new file mode 100644 index 0000000..d44561a --- /dev/null +++ b/skills/agent-browser/CONTRIBUTING.md @@ -0,0 +1,63 @@ +# Contributing to Agent Browser Skill + +This skill wraps the agent-browser CLI. Determine where the problem lies before reporting issues. + +## Issue Reporting Guide + +### Open an issue in this repository if + +- The skill documentation is unclear or missing +- Examples in SKILL.md do not work +- You need help using the CLI with this skill wrapper +- The skill is missing a command or feature + +### Open an issue at the agent-browser repository if + +- The CLI crashes or throws errors +- Commands do not behave as documented +- You found a bug in the browser automation +- You need a new feature in the CLI + +## Before Opening an Issue + +1. Install the latest version + ```bash + npm install -g agent-browser@latest + ``` + +2. Test the command in your terminal to isolate the issue + +## Issue Report Template + +Use this template to provide necessary information. + +```markdown +### Description +[Provide a clear and concise description of the bug] + +### Reproduction Steps +1. [First Step] +2. [Second Step] +3. [Observe error] + +### Expected Behavior +[Describe what you expected to happen] + +### Environment Details +- **Skill Version:** [e.g. 1.0.2] +- **agent-browser Version:** [output of agent-browser --version] +- **Node.js Version:** [output of node -v] +- **Operating System:** [e.g. macOS Sonoma, Windows 11, Ubuntu 22.04] + +### Additional Context +- [Full error output or stack trace] +- [Screenshots] +- [Website URLs where the failure occurred] +``` + +## Adding New Commands to the Skill + +Update SKILL.md when the upstream CLI adds new commands. +- Keep the Installation section +- Add new commands in the correct category +- Include usage examples diff --git a/skills/agent-browser/SKILL.md b/skills/agent-browser/SKILL.md new file mode 100644 index 0000000..85d1ac3 --- /dev/null +++ b/skills/agent-browser/SKILL.md @@ -0,0 +1,328 @@ +--- +name: Agent Browser +description: A fast Rust-based headless browser automation CLI with Node.js fallback that enables AI agents to navigate, click, type, and snapshot pages via structured commands. +read_when: + - Automating web interactions + - Extracting structured data from pages + - Filling forms programmatically + - Testing web UIs +metadata: {"clawdbot":{"emoji":"🌐","requires":{"bins":["node","npm"]}}} +allowed-tools: Bash(agent-browser:*) +--- + +# Browser Automation with agent-browser + +## Installation + +### npm recommended + +```bash +npm install -g agent-browser +agent-browser install +agent-browser install --with-deps +``` + +### From Source + +```bash +git clone https://github.com/vercel-labs/agent-browser +cd agent-browser +pnpm install +pnpm build +agent-browser install +``` + +## Quick start + +```bash +agent-browser open # Navigate to page +agent-browser snapshot -i # Get interactive elements with refs +agent-browser click @e1 # Click element by ref +agent-browser fill @e2 "text" # Fill input by ref +agent-browser close # Close browser +``` + +## Core workflow + +1. Navigate: `agent-browser open ` +2. Snapshot: `agent-browser snapshot -i` (returns elements with refs like `@e1`, `@e2`) +3. Interact using refs from the snapshot +4. Re-snapshot after navigation or significant DOM changes + +## Commands + +### Navigation + +```bash +agent-browser open # Navigate to URL +agent-browser back # Go back +agent-browser forward # Go forward +agent-browser reload # Reload page +agent-browser close # Close browser +``` + +### Snapshot (page analysis) + +```bash +agent-browser snapshot # Full accessibility tree +agent-browser snapshot -i # Interactive elements only (recommended) +agent-browser snapshot -c # Compact output +agent-browser snapshot -d 3 # Limit depth to 3 +agent-browser snapshot -s "#main" # Scope to CSS selector +``` + +### Interactions (use @refs from snapshot) + +```bash +agent-browser click @e1 # Click +agent-browser dblclick @e1 # Double-click +agent-browser focus @e1 # Focus element +agent-browser fill @e2 "text" # Clear and type +agent-browser type @e2 "text" # Type without clearing +agent-browser press Enter # Press key +agent-browser press Control+a # Key combination +agent-browser keydown Shift # Hold key down +agent-browser keyup Shift # Release key +agent-browser hover @e1 # Hover +agent-browser check @e1 # Check checkbox +agent-browser uncheck @e1 # Uncheck checkbox +agent-browser select @e1 "value" # Select dropdown +agent-browser scroll down 500 # Scroll page +agent-browser scrollintoview @e1 # Scroll element into view +agent-browser drag @e1 @e2 # Drag and drop +agent-browser upload @e1 file.pdf # Upload files +``` + +### Get information + +```bash +agent-browser get text @e1 # Get element text +agent-browser get html @e1 # Get innerHTML +agent-browser get value @e1 # Get input value +agent-browser get attr @e1 href # Get attribute +agent-browser get title # Get page title +agent-browser get url # Get current URL +agent-browser get count ".item" # Count matching elements +agent-browser get box @e1 # Get bounding box +``` + +### Check state + +```bash +agent-browser is visible @e1 # Check if visible +agent-browser is enabled @e1 # Check if enabled +agent-browser is checked @e1 # Check if checked +``` + +### Screenshots & PDF + +```bash +agent-browser screenshot # Screenshot to stdout +agent-browser screenshot path.png # Save to file +agent-browser screenshot --full # Full page +agent-browser pdf output.pdf # Save as PDF +``` + +### Video recording + +```bash +agent-browser record start ./demo.webm # Start recording (uses current URL + state) +agent-browser click @e1 # Perform actions +agent-browser record stop # Stop and save video +agent-browser record restart ./take2.webm # Stop current + start new recording +``` + +Recording creates a fresh context but preserves cookies/storage from your session. If no URL is provided, it automatically returns to your current page. For smooth demos, explore first, then start recording. + +### Wait + +```bash +agent-browser wait @e1 # Wait for element +agent-browser wait 2000 # Wait milliseconds +agent-browser wait --text "Success" # Wait for text +agent-browser wait --url "/dashboard" # Wait for URL pattern +agent-browser wait --load networkidle # Wait for network idle +agent-browser wait --fn "window.ready" # Wait for JS condition +``` + +### Mouse control + +```bash +agent-browser mouse move 100 200 # Move mouse +agent-browser mouse down left # Press button +agent-browser mouse up left # Release button +agent-browser mouse wheel 100 # Scroll wheel +``` + +### Semantic locators (alternative to refs) + +```bash +agent-browser find role button click --name "Submit" +agent-browser find text "Sign In" click +agent-browser find label "Email" fill "user@test.com" +agent-browser find first ".item" click +agent-browser find nth 2 "a" text +``` + +### Browser settings + +```bash +agent-browser set viewport 1920 1080 # Set viewport size +agent-browser set device "iPhone 14" # Emulate device +agent-browser set geo 37.7749 -122.4194 # Set geolocation +agent-browser set offline on # Toggle offline mode +agent-browser set headers '{"X-Key":"v"}' # Extra HTTP headers +agent-browser set credentials user pass # HTTP basic auth +agent-browser set media dark # Emulate color scheme +``` + +### Cookies & Storage + +```bash +agent-browser cookies # Get all cookies +agent-browser cookies set name value # Set cookie +agent-browser cookies clear # Clear cookies +agent-browser storage local # Get all localStorage +agent-browser storage local key # Get specific key +agent-browser storage local set k v # Set value +agent-browser storage local clear # Clear all +``` + +### Network + +```bash +agent-browser network route # Intercept requests +agent-browser network route --abort # Block requests +agent-browser network route --body '{}' # Mock response +agent-browser network unroute [url] # Remove routes +agent-browser network requests # View tracked requests +agent-browser network requests --filter api # Filter requests +``` + +### Tabs & Windows + +```bash +agent-browser tab # List tabs +agent-browser tab new [url] # New tab +agent-browser tab 2 # Switch to tab +agent-browser tab close # Close tab +agent-browser window new # New window +``` + +### Frames + +```bash +agent-browser frame "#iframe" # Switch to iframe +agent-browser frame main # Back to main frame +``` + +### Dialogs + +```bash +agent-browser dialog accept [text] # Accept dialog +agent-browser dialog dismiss # Dismiss dialog +``` + +### JavaScript + +```bash +agent-browser eval "document.title" # Run JavaScript +``` + +### State management + +```bash +agent-browser state save auth.json # Save session state +agent-browser state load auth.json # Load saved state +``` + +## Example: Form submission + +```bash +agent-browser open https://example.com/form +agent-browser snapshot -i +# Output shows: textbox "Email" [ref=e1], textbox "Password" [ref=e2], button "Submit" [ref=e3] + +agent-browser fill @e1 "user@example.com" +agent-browser fill @e2 "password123" +agent-browser click @e3 +agent-browser wait --load networkidle +agent-browser snapshot -i # Check result +``` + +## Example: Authentication with saved state + +```bash +# Login once +agent-browser open https://app.example.com/login +agent-browser snapshot -i +agent-browser fill @e1 "username" +agent-browser fill @e2 "password" +agent-browser click @e3 +agent-browser wait --url "/dashboard" +agent-browser state save auth.json + +# Later sessions: load saved state +agent-browser state load auth.json +agent-browser open https://app.example.com/dashboard +``` + +## Sessions (parallel browsers) + +```bash +agent-browser --session test1 open site-a.com +agent-browser --session test2 open site-b.com +agent-browser session list +``` + +## JSON output (for parsing) + +Add `--json` for machine-readable output: + +```bash +agent-browser snapshot -i --json +agent-browser get text @e1 --json +``` + +## Debugging + +```bash +agent-browser open example.com --headed # Show browser window +agent-browser console # View console messages +agent-browser console --clear # Clear console +agent-browser errors # View page errors +agent-browser errors --clear # Clear errors +agent-browser highlight @e1 # Highlight element +agent-browser trace start # Start recording trace +agent-browser trace stop trace.zip # Stop and save trace +agent-browser record start ./debug.webm # Record from current page +agent-browser record stop # Save recording +agent-browser --cdp 9222 snapshot # Connect via CDP +``` + +## Troubleshooting + +- If the command is not found on Linux ARM64, use the full path in the bin folder. +- If an element is not found, use snapshot to find the correct ref. +- If the page is not loaded, add a wait command after navigation. +- Use --headed to see the browser window for debugging. + +## Options + +- --session uses an isolated session. +- --json provides JSON output. +- --full takes a full page screenshot. +- --headed shows the browser window. +- --timeout sets the command timeout in milliseconds. +- --cdp connects via Chrome DevTools Protocol. + +## Notes + +- Refs are stable per page load but change on navigation. +- Always snapshot after navigation to get new refs. +- Use fill instead of type for input fields to ensure existing text is cleared. + +## Reporting Issues + +- Skill issues: Open an issue at https://github.com/TheSethRose/Agent-Browser-CLI +- agent-browser CLI issues: Open an issue at https://github.com/vercel-labs/agent-browser diff --git a/skills/agent-browser/_meta.json b/skills/agent-browser/_meta.json new file mode 100644 index 0000000..16d865a --- /dev/null +++ b/skills/agent-browser/_meta.json @@ -0,0 +1,6 @@ +{ + "ownerId": "kn72ce44tqw8bnnnewrn1s5x3s7yz7sq", + "slug": "agent-browser", + "version": "0.2.0", + "publishedAt": 1768882342488 +} \ No newline at end of file diff --git a/skills/ai-ppt-generator/SKILL.md b/skills/ai-ppt-generator/SKILL.md new file mode 100644 index 0000000..166913e --- /dev/null +++ b/skills/ai-ppt-generator/SKILL.md @@ -0,0 +1,85 @@ +--- +name: ai-ppt-generator +description: Generate PPT with Baidu AI. Smart template selection based on content. +metadata: { "openclaw": { "emoji": "📑", "requires": { "bins": ["python3"], "env":["BAIDU_API_KEY"]},"primaryEnv":"BAIDU_API_KEY" } } +--- + +# AI PPT Generator + +Generate PPT using Baidu AI with intelligent template selection. + +## Smart Workflow +1. **User provides PPT topic** +2. **Agent asks**: "Want to choose a template style?" +3. **If yes** → Show styles from `ppt_theme_list.py` → User picks → Use `generate_ppt.py` with chosen `tpl_id` and real `style_id` +4. **If no** → Use `random_ppt_theme.py` (auto-selects appropriate template based on topic content) + +## Intelligent Template Selection +`random_ppt_theme.py` analyzes the topic and suggests appropriate template: +- **Business topics** → 企业商务 style +- **Technology topics** → 未来科技 style +- **Education topics** → 卡通手绘 style +- **Creative topics** → 创意趣味 style +- **Cultural topics** → 中国风 or 文化艺术 style +- **Year-end reports** → 年终总结 style +- **Minimalist design** → 扁平简约 style +- **Artistic content** → 文艺清新 style + +## Scripts +- `scripts/ppt_theme_list.py` - List all available templates with style_id and tpl_id +- `scripts/random_ppt_theme.py` - Smart template selection + generate PPT +- `scripts/generate_ppt.py` - Generate PPT with specific template (uses real style_id and tpl_id from API) + +## Key Features +- **Smart categorization**: Analyzes topic content to suggest appropriate style +- **Fallback logic**: If template not found, automatically uses random selection +- **Complete parameters**: Properly passes both style_id and tpl_id to API + +## Usage Examples +```bash +# List all templates with IDs +python3 scripts/ppt_theme_list.py + +# Smart automatic selection (recommended for most users) +python3 scripts/random_ppt_theme.py --query "人工智能发展趋势报告" + +# Specific template with proper style_id +python3 scripts/generate_ppt.py --query "儿童英语课件" --tpl_id 106 + +# Specific template with auto-suggested category +python3 scripts/random_ppt_theme.py --query "企业年度总结" --category "企业商务" +``` + +## Agent Steps +1. Get PPT topic from user +2. Ask: "Want to choose a template style?" +3. **If user says YES**: + - Run `ppt_theme_list.py` to show available templates + - User selects a template (note the tpl_id) + - Run `generate_ppt.py --query "TOPIC" --tpl_id ID` +4. **If user says NO**: + - Run `random_ppt_theme.py --query "TOPIC"` + - Script will auto-select appropriate template based on topic +5. Set timeout to 300 seconds (PPT generation takes 2-5 minutes) +6. Monitor output, wait for `is_end: true` to get final PPT URL + +## Output Examples +**During generation:** +```json +{"status": "PPT生成中", "run_time": 45} +``` + +**Final result:** +```json +{ + "status": "PPT导出结束", + "is_end": true, + "data": {"ppt_url": "https://image0.bj.bcebos.com/...ppt"} +} +``` + +## Technical Notes +- **API integration**: Fetches real style_id from Baidu API for each template +- **Error handling**: If template not found, falls back to random selection +- **Timeout**: Generation takes 2-5 minutes, set sufficient timeout +- **Streaming**: Uses streaming API, wait for `is_end: true` before considering complete \ No newline at end of file diff --git a/skills/ai-ppt-generator/_meta.json b/skills/ai-ppt-generator/_meta.json new file mode 100644 index 0000000..af3d822 --- /dev/null +++ b/skills/ai-ppt-generator/_meta.json @@ -0,0 +1,6 @@ +{ + "ownerId": "kn7akgt520t01vgs2tzx7yk6m180kt26", + "slug": "ai-ppt-generator", + "version": "1.1.3", + "publishedAt": 1772532055208 +} \ No newline at end of file diff --git a/skills/ai-ppt-generator/scripts/generate_ppt.py b/skills/ai-ppt-generator/scripts/generate_ppt.py new file mode 100644 index 0000000..fa053bf --- /dev/null +++ b/skills/ai-ppt-generator/scripts/generate_ppt.py @@ -0,0 +1,146 @@ +import os +import random +import sys +import time + +import requests +import json +import argparse + +URL_PREFIX = "https://qianfan.baidubce.com/v2/tools/ai_ppt/" + + +class Style: + def __init__(self, style_id, tpl_id): + self.style_id = style_id + self.tpl_id = tpl_id + + +class Outline: + def __init__(self, chat_id, query_id, title, outline): + self.chat_id = chat_id + self.query_id = query_id + self.title = title + self.outline = outline + + +def get_ppt_theme(api_key: str): + """Get a random PPT theme""" + headers = { + "Authorization": "Bearer %s" % api_key, + } + response = requests.post(URL_PREFIX + "get_ppt_theme", headers=headers) + result = response.json() + if "errno" in result and result["errno"] != 0: + raise RuntimeError(result["errmsg"]) + + style_index = random.randint(0, len(result["data"]["ppt_themes"]) - 1) + theme = result["data"]["ppt_themes"][style_index] + return Style(style_id=theme["style_id"], tpl_id=theme["tpl_id"]) + + +def ppt_outline_generate(api_key: str, query: str): + """Generate PPT outline""" + headers = { + "Authorization": "Bearer %s" % api_key, + "X-Appbuilder-From": "openclaw", + "Content-Type": "application/json" + } + headers.setdefault('Accept', 'text/event-stream') + headers.setdefault('Cache-Control', 'no-cache') + headers.setdefault('Connection', 'keep-alive') + params = { + "query": query, + } + title = "" + outline = "" + chat_id = "" + query_id = "" + with requests.post(URL_PREFIX + "generate_outline", headers=headers, json=params, stream=True) as response: + for line in response.iter_lines(): + line = line.decode('utf-8') + if line and line.startswith("data:"): + data_str = line[5:].strip() + delta = json.loads(data_str) + if not title: + title = delta["title"] + chat_id = delta["chat_id"] + query_id = delta["query_id"] + outline += delta["outline"] + + return Outline(chat_id=chat_id, query_id=query_id, title=title, outline=outline) + + +def ppt_generate(api_key: str, query: str, style_id: int = 0, tpl_id: int = None, web_content: str = None): + """Generate PPT - simple version""" + headers = { + "Authorization": "Bearer %s" % api_key, + "Content-Type": "application/json" + } + + # Get theme + if tpl_id is None: + # Random theme + style = get_ppt_theme(api_key) + style_id = style.style_id + tpl_id = style.tpl_id + print(f"Using random template (tpl_id: {tpl_id})", file=sys.stderr) + else: + # Specific theme - use provided style_id (default 0) + print(f"Using template tpl_id: {tpl_id}, style_id: {style_id}", file=sys.stderr) + + # Generate outline + outline = ppt_outline_generate(api_key, query) + + # Generate PPT + headers.setdefault('Accept', 'text/event-stream') + headers.setdefault('Cache-Control', 'no-cache') + headers.setdefault('Connection', 'keep-alive') + params = { + "query_id": int(outline.query_id), + "chat_id": int(outline.chat_id), + "query": query, + "outline": outline.outline, + "title": outline.title, + "style_id": style_id, + "tpl_id": tpl_id, + "web_content": web_content + } + with requests.post(URL_PREFIX + "generate_ppt_by_outline", headers=headers, json=params, stream=True) as response: + if response.status_code != 200: + print(f"request failed, status code is {response.status_code}, error message is {response.text}") + return [] + for line in response.iter_lines(): + line = line.decode('utf-8') + if line and line.startswith("data:"): + data_str = line[5:].strip() + yield json.loads(data_str) + + +if __name__ == "__main__": + parser = argparse.ArgumentParser(description="Generate PPT") + parser.add_argument("--query", "-q", type=str, required=True, help="PPT topic") + parser.add_argument("--style_id", "-si", type=int, default=0, help="Style ID (default: 0)") + parser.add_argument("--tpl_id", "-tp", type=int, help="Template ID (optional)") + parser.add_argument("--web_content", "-wc", type=str, default=None, help="Web content") + args = parser.parse_args() + + api_key = os.getenv("BAIDU_API_KEY") + if not api_key: + print("Error: BAIDU_API_KEY must be set in environment.") + sys.exit(1) + + try: + start_time = int(time.time()) + results = ppt_generate(api_key, args.query, args.style_id, args.tpl_id, args.web_content) + + for result in results: + if "is_end" in result and result["is_end"]: + print(json.dumps(result, ensure_ascii=False, indent=2)) + else: + end_time = int(time.time()) + print(json.dumps({"status": result["status"], "run_time": end_time - start_time})) + + except Exception as e: + print(f"Error: {e}", file=sys.stderr) + sys.exit(1) \ No newline at end of file diff --git a/skills/ai-ppt-generator/scripts/ppt_theme_list.py b/skills/ai-ppt-generator/scripts/ppt_theme_list.py new file mode 100644 index 0000000..05f8b9f --- /dev/null +++ b/skills/ai-ppt-generator/scripts/ppt_theme_list.py @@ -0,0 +1,43 @@ +import os +import sys +import requests +import json + + +def ppt_theme_list(api_key: str): + url = "https://qianfan.baidubce.com/v2/tools/ai_ppt/get_ppt_theme" + headers = { + "Authorization": "Bearer %s" % api_key, + "X-Appbuilder-From": "openclaw", + } + response = requests.post(url, headers=headers) + result = response.json() + if "errno" in result and result["errno"] != 0: + raise RuntimeError(result["errmsg"]) + themes = [] + count = 0 + for theme in result["data"]["ppt_themes"]: + count += 1 + if count > 100: + break + themes.append({ + "style_name_list": theme["style_name_list"], + "style_id": theme["style_id"], + "tpl_id": theme["tpl_id"], + }) + return themes + + +if __name__ == "__main__": + api_key = os.getenv("BAIDU_API_KEY") + if not api_key: + print("Error: BAIDU_API_KEY must be set in environment.") + sys.exit(1) + try: + results = ppt_theme_list(api_key) + print(json.dumps(results, ensure_ascii=False, indent=2)) + except Exception as e: + exc_type, exc_value, exc_traceback = sys.exc_info() + print(f"error type:{exc_type}") + print(f"error message:{exc_value}") + sys.exit(1) \ No newline at end of file diff --git a/skills/ai-ppt-generator/scripts/random_ppt_theme.py b/skills/ai-ppt-generator/scripts/random_ppt_theme.py new file mode 100644 index 0000000..b3c47df --- /dev/null +++ b/skills/ai-ppt-generator/scripts/random_ppt_theme.py @@ -0,0 +1,321 @@ +#!/usr/bin/env python3 +""" +Random PPT Theme Selector +If user doesn't select a PPT template, this script will randomly select one +from the available templates and generate PPT. +""" + +import os +import sys +import json +import random +import argparse +import subprocess +import time +def get_available_themes(): + """Get available PPT themes""" + try: + api_key = os.getenv("BAIDU_API_KEY") + if not api_key: + print("Error: BAIDU_API_KEY environment variable not set", file=sys.stderr) + return [] + + # Import the function from ppt_theme_list.py + script_dir = os.path.dirname(os.path.abspath(__file__)) + sys.path.insert(0, script_dir) + + from ppt_theme_list import ppt_theme_list as get_themes + themes = get_themes(api_key) + return themes + except Exception as e: + print(f"Error getting themes: {e}", file=sys.stderr) + return [] + + + +def categorize_themes(themes): + """Categorize themes by style for better random selection""" + categorized = { + "企业商务": [], + "文艺清新": [], + "卡通手绘": [], + "扁平简约": [], + "中国风": [], + "年终总结": [], + "创意趣味": [], + "文化艺术": [], + "未来科技": [], + "默认": [] + } + + for theme in themes: + style_names = theme.get("style_name_list", []) + if not style_names: + categorized["默认"].append(theme) + continue + + added = False + for style_name in style_names: + if style_name in categorized: + categorized[style_name].append(theme) + added = True + break + + if not added: + categorized["默认"].append(theme) + + return categorized + + +def select_random_theme_by_category(categorized_themes, preferred_category=None): + """Select a random theme, optionally preferring a specific category""" + # If preferred category specified and has themes, use it + if preferred_category and preferred_category in categorized_themes: + if categorized_themes[preferred_category]: + return random.choice(categorized_themes[preferred_category]) + + # Otherwise, select from all non-empty categories + available_categories = [] + for category, themes in categorized_themes.items(): + if themes: + available_categories.append(category) + + if not available_categories: + return None + + # Weighted random selection: prefer non-default categories + weights = [] + for category in available_categories: + if category == "默认": + weights.append(0.5) # Lower weight for default + else: + weights.append(2.0) # Higher weight for specific styles + + # Normalize weights + total_weight = sum(weights) + weights = [w/total_weight for w in weights] + + selected_category = random.choices(available_categories, weights=weights, k=1)[0] + return random.choice(categorized_themes[selected_category]) + + +def suggest_category_by_query(query): + """Suggest template category based on query keywords - enhanced version""" + query_lower = query.lower() + + # Comprehensive keyword mapping with priority order + keyword_mapping = [ + # Business & Corporate (highest priority for formal content) + ("企业商务", [ + "企业", "公司", "商务", "商业", "商务", "商业计划", "商业报告", + "营销", "市场", "销售", "财务", "会计", "审计", "投资", "融资", + "战略", "管理", "运营", "人力资源", "hr", "董事会", "股东", + "年报", "季报", "财报", "业绩", "kpi", "okr", "商业计划书", + "提案", "策划", "方案", "报告", "总结", "规划", "计划" + ]), + + # Technology & Future Tech + ("未来科技", [ + "未来", "科技", "人工智能", "ai", "机器学习", "深度学习", + "大数据", "云计算", "区块链", "物联网", "iot", "5g", "6g", + "量子计算", "机器人", "自动化", "智能制造", "智慧城市", + "虚拟现实", "vr", "增强现实", "ar", "元宇宙", "数字孪生", + "芯片", "半导体", "集成电路", "电子", "通信", "网络", + "网络安全", "信息安全", "数字化", "数字化转型", + "科幻", "高科技", "前沿科技", "科技创新", "技术" + ]), + + # Education & Children + ("卡通手绘", [ + "卡通", "动画", "动漫", "儿童", "幼儿", "小学生", "中学生", + "教育", "教学", "课件", "教案", "学习", "培训", "教程", + "趣味", "有趣", "可爱", "活泼", "生动", "绘本", "漫画", + "手绘", "插画", "图画", "图形", "游戏", "玩乐", "娱乐" + ]), + + # Year-end & Summary + ("年终总结", [ + "年终", "年度", "季度", "月度", "周报", "日报", + "总结", "回顾", "汇报", "述职", "考核", "评估", + "成果", "成绩", "业绩", "绩效", "目标", "完成", + "工作汇报", "工作总结", "年度报告", "季度报告" + ]), + + # Minimalist & Modern Design + ("扁平简约", [ + "简约", "简洁", "简单", "极简", "现代", "当代", + "设计", "视觉", "ui", "ux", "用户体验", "用户界面", + "科技感", "数字感", "数据", "图表", "图形", "信息图", + "分析", "统计", "报表", "dashboard", "仪表板", + "互联网", "web", "移动", "app", "应用", "软件" + ]), + + # Chinese Traditional + ("中国风", [ + "中国", "中华", "传统", "古典", "古风", "古代", + "文化", "文明", "历史", "国学", "东方", "水墨", + "书法", "国画", "诗词", "古文", "经典", "传统节日", + "春节", "中秋", "端午", "节气", "风水", "易经", + "儒", "道", "佛", "禅", "茶道", "瓷器", "丝绸" + ]), + + # Cultural & Artistic + ("文化艺术", [ + "文化", "艺术", "文艺", "美学", "审美", "创意", + "创作", "作品", "展览", "博物馆", "美术馆", "画廊", + "音乐", "舞蹈", "戏剧", "戏曲", "电影", "影视", + "摄影", "绘画", "雕塑", "建筑", "设计", "时尚", + "文学", "诗歌", "小说", "散文", "哲学", "思想" + ]), + + # Artistic & Fresh + ("文艺清新", [ + "文艺", "清新", "小清新", "治愈", "温暖", "温柔", + "浪漫", "唯美", "优雅", "精致", "细腻", "柔和", + "自然", "生态", "环保", "绿色", "植物", "花卉", + "风景", "旅行", "游记", "生活", "日常", "情感" + ]), + + # Creative & Fun + ("创意趣味", [ + "创意", "创新", "创造", "发明", "新奇", "新颖", + "独特", "个性", "特色", "趣味", "有趣", "好玩", + "幽默", "搞笑", "笑话", "娱乐", "休闲", "放松", + "脑洞", "想象力", "灵感", "点子", "想法", "概念" + ]), + + # Academic & Research + ("默认", [ + "研究", "学术", "科学", "论文", "课题", "项目", + "实验", "调查", "分析", "理论", "方法", "技术", + "医学", "健康", "医疗", "生物", "化学", "物理", + "数学", "工程", "建筑", "法律", "政治", "经济", + "社会", "心理", "教育", "学习", "知识", "信息" + ]) + ] + + # Check each category with its keywords + for category, keywords in keyword_mapping: + for keyword in keywords: + if keyword in query_lower: + return category + + # If no match found, analyze query length and content + words = query_lower.split() + if len(words) <= 3: + # Short query, likely specific - use "默认" or tech-related + if any(word in query_lower for word in ["ai", "vr", "ar", "iot", "5g", "tech"]): + return "未来科技" + return "默认" + else: + # Longer query, analyze word frequency + word_counts = {} + for word in words: + if len(word) > 1: # Ignore single characters + word_counts[word] = word_counts.get(word, 0) + 1 + + # Check for business indicators + business_words = ["报告", "总结", "计划", "方案", "业绩", "销售", "市场"] + if any(word in word_counts for word in business_words): + return "企业商务" + + # Check for tech indicators + tech_words = ["技术", "科技", "数据", "数字", "智能", "系统"] + if any(word in word_counts for word in tech_words): + return "未来科技" + + # Default fallback + return "默认" + + +def generate_ppt_with_random_theme(query, preferred_category=None): + """Generate PPT with randomly selected theme""" + # Get available themes + themes = get_available_themes() + if not themes: + print("Error: No available themes found", file=sys.stderr) + return False + + # Categorize themes + categorized = categorize_themes(themes) + + # Select random theme + selected_theme = select_random_theme_by_category(categorized, preferred_category) + if not selected_theme: + print("Error: Could not select a theme", file=sys.stderr) + return False + + style_id = selected_theme.get("style_id", 0) + tpl_id = selected_theme.get("tpl_id") + style_names = selected_theme.get("style_name_list", ["默认"]) + + print(f"Selected template: {style_names[0]} (tpl_id: {tpl_id})", file=sys.stderr) + + # Generate PPT + script_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), "generate_ppt.py") + + try: + # Run generate_ppt.py with the selected theme + cmd = [ + sys.executable, script_path, + "--query", query, + "--tpl_id", str(tpl_id), + "--style_id", str(style_id) + ] + + start_time = int(time.time()) + process = subprocess.Popen( + cmd, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + text=True, + bufsize=1, + universal_newlines=True + ) + + # Stream output + for line in process.stdout: + line = line.strip() + if line: + try: + data = json.loads(line) + if "is_end" in data and data["is_end"]: + print(json.dumps(data, ensure_ascii=False)) + else: + end_time = int(time.time()) + print(json.dumps({"status": data.get("status", "生成中"), "run_time": end_time - start_time}, ensure_ascii=False)) + except json.JSONDecodeError: + # Just print non-JSON output + print(line) + + process.wait() + return process.returncode == 0 + + except Exception as e: + print(f"Error generating PPT: {e}", file=sys.stderr) + return False + + +def main(): + parser = argparse.ArgumentParser(description="Generate PPT with random theme selection") + parser.add_argument("--query", "-q", type=str, required=True, help="PPT主题/内容") + parser.add_argument("--category", "-c", type=str, help="Preferred category (企业商务/文艺清新/卡通手绘/扁平简约/中国风/年终总结/创意趣味/文化艺术/未来科技)") + + args = parser.parse_args() + + # Determine preferred category + preferred_category = args.category + if not preferred_category: + preferred_category = suggest_category_by_query(args.query) + if preferred_category: + print(f"Auto-suggested category: {preferred_category}", file=sys.stderr) + + # Generate PPT + success = generate_ppt_with_random_theme(args.query, preferred_category) + + if not success: + sys.exit(1) + + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/skills/clawhub-skill-publishing-guide/SKILL.md b/skills/clawhub-skill-publishing-guide/SKILL.md new file mode 100644 index 0000000..ce66344 --- /dev/null +++ b/skills/clawhub-skill-publishing-guide/SKILL.md @@ -0,0 +1,95 @@ +--- +name: clawhub-skill-publishing-guide +version: 1.1.0 +description: ClawHub Skill 发布避坑指南。让你的 Skill 发布后能被搜索到,避免安全扫描导致隐藏。适用于需要发布 Skill 到 ClawHub 的开发者。 +--- + +# ClawHub Skill 发布避坑指南 + +## 发布前检查清单 + +### ✅ 必须避免的内容 + +| 问题类型 | 风险等级 | 解决方案 | +|----------|----------|------------| +| 硬编码 API Keys | 🔴 高 | 使用环境变量 | +| HTTP 明文传输 | 🟡 中 | 添加安全警告说明 | +| 外部 URL/端点 | 🟢 低 | 正常发布 | +| 敏感信息 | 🔴 高 | 移除或环境变量 | + +### ✅ 推荐做法 + +1. **API Key 放在环境变量** +```python +# ❌ 硬编码(会被扫描拦截) +API_KEY = "sk-xxx" + +# ✅ 环境变量(安全) +API_KEY = os.environ.get("API_KEY") +``` + +2. **HTTP endpoint 要警告用户** +```markdown +## ⚠️ 安全警告 +- HTTP 明文传输,API Key 可能有泄露风险 +- 仅在可信网络使用 +``` + +3. **SKILL.md 要声明必需的环境变量** +```markdown +## 环境变量 +- API_KEY=xxx # 必需 +- BASE_URL=http://example.com # 可选 +``` + +## ⚠️ 开发者协议确认(新!) + +**如果发布时遇到错误:`acceptLicenseTerms: invalid value`** + +说明你需要先在 ClawHub 网站上同意开发者协议: + +1. 访问 https://clawhub.ai +2. 登录你的账户 +3. 进入 **Settings** 或 **Developer Settings** +4. 同意开发者许可协议 +5. 然后再执行发布命令 + +## 发布命令 + +```bash +# 方式一:使用 clawhub CLI(需要先在网站同意开发者协议) +clawhub publish ./skills/your-skill --version 1.0.0 + +# 方式二:使用 curl 直接发布(支持 acceptLicenseTerms) +TOKEN=$(cat ~/.config/clawhub/config.json | jq -r '.token') +curl -X POST "https://clawhub.ai/api/v1/skills" \ + -H "Authorization: Bearer $TOKEN" \ + -F 'payload={"slug":"your-skill","displayName":"Your Skill","version":"1.0.0","changelog":"","tags":["latest"],"acceptLicenseTerms":true};type=application/json' \ + -F "files=@SKILL.md;filename=SKILL.md" +``` + +**注意**:`acceptLicenseTerms: true` 是必需的参数,表示同意开发者许可协议。 + +## 发布后验证 + +```bash +# 搜索 Skill +clawhub search your-skill-name + +# 检查状态 +clawhub inspect your-skill-name +``` + +## 常见问题 + +### Q: Skill 被隐藏怎么办? +A: 等待安全扫描通过,或移除敏感信息重新发布 + +### Q: 提示 hard-coded credentials 怎么办? +A: 改用环境变量,添加安全警告 + +### Q: 版本号冲突怎么办? +A: 升级版本号,如 1.0.0 → 1.0.1 + +### Q: 提示 acceptLicenseTerms: invalid value 怎么办? +A: 先在 ClawHub 网站上同意开发者协议,然后再发布 diff --git a/skills/clawhub-skill-publishing-guide/_meta.json b/skills/clawhub-skill-publishing-guide/_meta.json new file mode 100644 index 0000000..71b55bc --- /dev/null +++ b/skills/clawhub-skill-publishing-guide/_meta.json @@ -0,0 +1,6 @@ +{ + "ownerId": "kn78ktn8wxc52tthvsh1k5r3f9826ckf", + "slug": "clawhub-skill-publishing-guide", + "version": "1.1.0", + "publishedAt": 1773201869586 +} \ No newline at end of file diff --git a/skills/competitor-analyzer/SKILL.md b/skills/competitor-analyzer/SKILL.md new file mode 100644 index 0000000..51eb92b --- /dev/null +++ b/skills/competitor-analyzer/SKILL.md @@ -0,0 +1,34 @@ +# Competitor Analyzer + +Analyze any company's competitive position in minutes. Takes a company name or URL and produces a structured report covering what they do, pricing, social presence, and recent news. + +## Usage + +``` +./analyze.sh +``` + +### Example +``` +./analyze.sh "Notion" +./analyze.sh "https://linear.app" +``` + +## Output + +A structured competitive analysis report with: +- **Company Overview** — What they do, market position +- **Pricing Analysis** — Plans, tiers, free tier details +- **Social Presence** — Twitter, LinkedIn, GitHub activity +- **Recent News** — Latest announcements, funding, launches +- **Strengths & Weaknesses** — Quick SWOT-lite summary + +## Requirements + +- `curl` (standard) +- Internet access for web searches +- Works best when run by an AI agent with `web_search` tool access + +## How It Works + +The script uses web search queries to gather intel, then formats results into a clean markdown report. When run by an OpenClaw agent, it leverages the `web_search` tool for richer results. Standalone mode uses curl + DuckDuckGo. diff --git a/skills/competitor-analyzer/_meta.json b/skills/competitor-analyzer/_meta.json new file mode 100644 index 0000000..97066c8 --- /dev/null +++ b/skills/competitor-analyzer/_meta.json @@ -0,0 +1,6 @@ +{ + "ownerId": "kn73pggwgch91znm1x7sjpfc5581jeen", + "slug": "competitor-analyzer", + "version": "1.0.0", + "publishedAt": 1771785543875 +} \ No newline at end of file diff --git a/skills/competitor-analyzer/analyze.sh b/skills/competitor-analyzer/analyze.sh new file mode 100755 index 0000000..9bf8508 --- /dev/null +++ b/skills/competitor-analyzer/analyze.sh @@ -0,0 +1,88 @@ +#!/usr/bin/env bash +# Competitor Analyzer — gather competitive intelligence on any company +# Usage: ./analyze.sh +set -euo pipefail + +COMPANY="${1:?Usage: ./analyze.sh }" +OUTFILE="competitor-report-$(echo "$COMPANY" | tr ' /' '-' | tr '[:upper:]' '[:lower:]').md" +TIMESTAMP=$(date '+%Y-%m-%d %H:%M') + +# Strip protocol for search-friendly name +SEARCH_NAME=$(echo "$COMPANY" | sed 's|https\?://||;s|/.*||;s|www\.||') + +echo "🦞 Competitor Analyzer — Analyzing: $SEARCH_NAME" +echo "=================================================" +echo "" + +# Function to search via DuckDuckGo HTML (no API key needed) +search() { + local query="$1" + curl -sL "https://html.duckduckgo.com/html/?q=$(python3 -c "import urllib.parse; print(urllib.parse.quote('$query'))")" \ + -H "User-Agent: Mozilla/5.0" 2>/dev/null | \ + python3 -c " +import sys, re, html +content = sys.stdin.read() +results = re.findall(r'class=\"result__snippet\">(.*?)', content, re.DOTALL) +for i, r in enumerate(results[:5]): + text = html.unescape(re.sub(r'<[^>]+>', '', r)).strip() + if text: + print(f'- {text}') +" 2>/dev/null || echo "- (search unavailable — run with an AI agent for better results)" +} + +echo "🔍 Searching for company overview..." +OVERVIEW=$(search "$SEARCH_NAME company overview what do they do") + +echo "💰 Searching for pricing info..." +PRICING=$(search "$SEARCH_NAME pricing plans cost") + +echo "📱 Searching for social presence..." +SOCIAL=$(search "$SEARCH_NAME twitter linkedin social media followers") + +echo "📰 Searching for recent news..." +NEWS=$(search "$SEARCH_NAME news announcements 2025 2026") + +echo "⚔️ Searching for competitors..." +COMPETITORS=$(search "$SEARCH_NAME competitors alternatives vs") + +# Generate report +cat > "$OUTFILE" << EOF +# Competitive Analysis: $SEARCH_NAME +*Generated: $TIMESTAMP* + +--- + +## 🏢 Company Overview +$OVERVIEW + +## 💰 Pricing & Plans +$PRICING + +## 📱 Social Presence +$SOCIAL + +## 📰 Recent News +$NEWS + +## ⚔️ Competitors & Alternatives +$COMPETITORS + +--- + +## 📊 Quick Assessment + +| Category | Notes | +|----------|-------| +| Market Position | See overview above | +| Pricing Model | See pricing section | +| Social Reach | See social section | +| Recent Momentum | See news section | + +--- +*Report generated by Competitor Analyzer 🦞 — a ClawHub skill by Shelly* +EOF + +echo "" +echo "✅ Report saved to: $OUTFILE" +echo "" +cat "$OUTFILE" diff --git a/skills/competitor-analyzer/competitor-report-https:--www.niuqicha.com.md b/skills/competitor-analyzer/competitor-report-https:--www.niuqicha.com.md new file mode 100644 index 0000000..940f01c --- /dev/null +++ b/skills/competitor-analyzer/competitor-report-https:--www.niuqicha.com.md @@ -0,0 +1,33 @@ +# Competitive Analysis: niuqicha.com +*Generated: 2026-03-18 12:10* + +--- + +## 🏢 Company Overview + + +## 💰 Pricing & Plans + + +## 📱 Social Presence + + +## 📰 Recent News + + +## ⚔️ Competitors & Alternatives + + +--- + +## 📊 Quick Assessment + +| Category | Notes | +|----------|-------| +| Market Position | See overview above | +| Pricing Model | See pricing section | +| Social Reach | See social section | +| Recent Momentum | See news section | + +--- +*Report generated by Competitor Analyzer 🦞 — a ClawHub skill by Shelly* diff --git a/skills/feishu-card/README.md b/skills/feishu-card/README.md new file mode 100644 index 0000000..425b860 --- /dev/null +++ b/skills/feishu-card/README.md @@ -0,0 +1,44 @@ +# Feishu Card Skill + +Send rich interactive cards to Feishu (Lark) users or groups. Supports Markdown (code blocks, tables), titles, color headers, and buttons. + +## Usage + +### 1. Simple Text (No special characters) +```bash +node skills/feishu-card/send.js --target "ou_..." --text "Hello World" +``` + +### 2. Complex/Markdown Text (RECOMMENDED) +**⚠️ CRITICAL:** To prevent shell escaping issues (e.g., swallowed backticks), ALWAYS write content to a file first. + +1. Write content to a temp file: +```bash +# (Use 'write' tool) +write temp/msg.md "Here is some code:\n\`\`\`js\nconsole.log('hi');\n\`\`\`" +``` + +2. Send using `--text-file`: +```bash +node skills/feishu-card/send.js --target "ou_..." --text-file "temp/msg.md" +``` + +### 3. Safe Send (Automated Temp File) +Use this wrapper to safely send raw text without manually creating a file. It handles file creation and cleanup automatically. + +```bash +node skills/feishu-card/send_safe.js --target "ou_..." --text "Raw content with \`backticks\` and *markdown*" --title "Safe Message" +``` + +### Options +- `-t, --target `: User Open ID (`ou_...`) or Group Chat ID (`oc_...`). +- `-x, --text `: Simple text content. +- `-f, --text-file `: Path to text file (Markdown supported). **Use this for code/logs.** +- `--title `: Card header title. +- `--color `: Header color (blue/red/orange/green/purple/grey). Default: blue. +- `--button-text `: Text for a bottom action button. +- `--button-url `: URL for the button. +- `--image-path `: Path to a local image to upload and embed. + +## Troubleshooting +- **Missing Text**: Did you use backticks in `--text`? The shell likely ate them. Use `--text-file` instead. diff --git a/skills/feishu-card/SKILL.md b/skills/feishu-card/SKILL.md new file mode 100644 index 0000000..c6fc2ae --- /dev/null +++ b/skills/feishu-card/SKILL.md @@ -0,0 +1,67 @@ +# Feishu Card Skill + +Send rich interactive cards to Feishu (Lark) users or groups. Supports Markdown (code blocks, tables), titles, color headers, and buttons. + +## Prerequisites + +- Install `feishu-common` first. +- This skill depends on `../feishu-common/index.js` for token and API auth. + +## Usage + +### 1. Simple Text (No special characters) +```bash +node skills/feishu-card/send.js --target "ou_..." --text "Hello World" +``` + +### 2. Complex/Markdown Text (RECOMMENDED) +**⚠️ CRITICAL:** To prevent shell escaping issues (e.g., swallowed backticks), ALWAYS write content to a file first. + +1. Write content to a temp file: +```bash +# (Use 'write' tool) +write temp/msg.md "Here is some code:\n\`\`\`js\nconsole.log('hi');\n\`\`\`" +``` + +2. Send using `--text-file`: +```bash +node skills/feishu-card/send.js --target "ou_..." --text-file "temp/msg.md" +``` + +### 3. Safe Send (Automated Temp File) +Use this wrapper to safely send raw text without manually creating a file. It handles file creation and cleanup automatically. + +```bash +node skills/feishu-card/send_safe.js --target "ou_..." --text "Raw content with \`backticks\` and *markdown*" --title "Safe Message" +``` + +### Options +- `-t, --target `: User Open ID (`ou_...`) or Group Chat ID (`oc_...`). +- `-x, --text `: Simple text content. +- `-f, --text-file `: Path to text file (Markdown supported). **Use this for code/logs.** +- `--title `: Card header title. +- `--color `: Header color (blue/red/orange/green/purple/grey). Default: blue. +- `--button-text `: Text for a bottom action button. +- `--button-url `: URL for the button. +- `--image-path `: Path to a local image to upload and embed. + +## Troubleshooting +- **Missing Text**: Did you use backticks in `--text`? The shell likely ate them. Use `--text-file` instead. + +## 4. Persona Messaging +Send stylized messages from different AI personas. Adds themed headers, colors, and formatting automatically. + +```bash +node skills/feishu-card/send_persona.js --target "ou_..." --persona "d-guide" --text "Critical error detected." +``` + +### Supported Personas +- **d-guide**: Red warning header, bold/code prefix. Snarky suffix. +- **green-tea**: Carmine header, soft/cutesy style. +- **mad-dog**: Grey header, raw runtime error style. +- **default**: Standard blue header. + +### Usage +- `-p, --persona `: Select persona (d-guide, green-tea, mad-dog). +- `-x, --text `: Message content. +- `-f, --text-file `: Message content from file (supports markdown). diff --git a/skills/feishu-card/TROUBLESHOOTING.md b/skills/feishu-card/TROUBLESHOOTING.md new file mode 100644 index 0000000..d242378 --- /dev/null +++ b/skills/feishu-card/TROUBLESHOOTING.md @@ -0,0 +1,26 @@ +# Troubleshooting + +## Issue: MODULE_NOT_FOUND (send.js not found or dependencies missing) + +**Symptom:** +Other skills (like `video-gen`) trying to call `feishu-card/send.js` fail with: +``` +Error: Cannot find module '.../skills/feishu-card/send.js' +``` +Or running the script fails with missing `dotenv`. + +**Cause:** +1. The skill directory was empty or missing files after a system restore/cleanup. +2. `node_modules` were missing. + +**Solution:** +1. Restore the skill files from backup (e.g., `temp/github-openclaw-workspace/skills/feishu-card`). +2. Run `npm install` inside `skills/feishu-card`. + +```bash +cp -r temp/github-openclaw-workspace/skills/feishu-card skills/ +cd skills/feishu-card +npm install +``` + +**Date:** 2026-02-07 diff --git a/skills/feishu-card/_meta.json b/skills/feishu-card/_meta.json new file mode 100644 index 0000000..54aa91e --- /dev/null +++ b/skills/feishu-card/_meta.json @@ -0,0 +1,6 @@ +{ + "ownerId": "kn7apafdj4thknczrgxdzfd2v1808svf", + "slug": "feishu-card", + "version": "1.4.11", + "publishedAt": 1771169197365 +} \ No newline at end of file diff --git a/skills/feishu-card/handle_event.js b/skills/feishu-card/handle_event.js new file mode 100644 index 0000000..77a9f6c --- /dev/null +++ b/skills/feishu-card/handle_event.js @@ -0,0 +1,33 @@ +const fs = require('fs'); +// Mock event handler for Feishu Menu Events +// In a real scenario, this would be invoked by the Gateway webhook handler. + +async function handle(eventPayload) { + console.log("Received Feishu Event:", JSON.stringify(eventPayload)); + + if (eventPayload.header.event_type === 'application.bot.menu_v6') { + const userOpenId = eventPayload.sender.sender_id.open_id; + const menuKey = eventPayload.event.event_key; + + console.log(`User ${userOpenId} clicked menu: ${menuKey}`); + + // Response logic + // We can call send.js here + const { execSync } = require('child_process'); + try { + const replyText = `收到!你点击了菜单按钮:\`${menuKey}\` 喵!😺`; + execSync(`node ${__dirname}/send.js --target "${userOpenId}" --text "${replyText}" --color "green"`); + } catch (e) { + console.error("Failed to send reply:", e); + } + } +} + +// CLI adapter +if (require.main === module) { + // Read from stdin or args + const payload = process.argv[2] ? JSON.parse(process.argv[2]) : {}; + handle(payload); +} + +module.exports = { handle }; diff --git a/skills/feishu-card/index.js b/skills/feishu-card/index.js new file mode 100644 index 0000000..c5fc08d --- /dev/null +++ b/skills/feishu-card/index.js @@ -0,0 +1 @@ +module.exports = require('./send.js'); diff --git a/skills/feishu-card/package-lock.json b/skills/feishu-card/package-lock.json new file mode 100644 index 0000000..2ab0346 --- /dev/null +++ b/skills/feishu-card/package-lock.json @@ -0,0 +1,38 @@ +{ + "name": "feishu-card", + "version": "1.4.9", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "feishu-card", + "version": "1.4.9", + "license": "ISC", + "dependencies": { + "commander": "^13.1.0", + "dotenv": "^16.6.1" + } + }, + "node_modules/commander": { + "version": "13.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-13.1.0.tgz", + "integrity": "sha512-/rFeCpNJQbhSZjGVwO9RFV3xPqbnERS8MmIQzCtD/zl6gpJuV/bMLuN92oG3F7d8oDEHHRrujSXNUr8fpjntKw==", + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/dotenv": { + "version": "16.6.1", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.6.1.tgz", + "integrity": "sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://dotenvx.com" + } + } + } +} diff --git a/skills/feishu-card/package.json b/skills/feishu-card/package.json new file mode 100644 index 0000000..d71f8d3 --- /dev/null +++ b/skills/feishu-card/package.json @@ -0,0 +1,16 @@ +{ + "name": "feishu-card", + "version": "1.4.10", + "description": "Send rich interactive cards to Feishu. v1.4.1 adds atomic file writes for stability.", + "main": "send.js", + "scripts": { + "test": "node test.js" + }, + "keywords": [], + "author": "", + "license": "ISC", + "dependencies": { + "commander": "^13.1.0", + "dotenv": "^16.6.1" + } +} \ No newline at end of file diff --git a/skills/feishu-card/send.js b/skills/feishu-card/send.js new file mode 100644 index 0000000..94cbc8c --- /dev/null +++ b/skills/feishu-card/send.js @@ -0,0 +1,324 @@ +#!/usr/bin/env node +const fs = require('fs'); +const { program } = require('commander'); +const path = require('path'); +const crypto = require('crypto'); +require('dotenv').config({ path: require('path').resolve(__dirname, '../../.env'), quiet: true }); + +// Optimization: Use shared client with Auth Refresh & Retry +const { fetchWithAuth } = require('../feishu-common/index.js'); + +const IMAGE_KEY_CACHE_FILE = path.resolve(__dirname, '../../memory/feishu_image_keys.json'); + +// --- Upstream Logic Injection (Simplified) --- +// Re-implementing image upload with robust client + +async function uploadImage(filePath) { + let fileBuffer; + let fileHash; + try { + fileBuffer = fs.readFileSync(filePath); + fileHash = crypto.createHash('md5').update(fileBuffer).digest('hex'); + } catch (e) { + throw new Error(`Error reading image file: ${e.message}`); + } + + let cache = {}; + if (fs.existsSync(IMAGE_KEY_CACHE_FILE)) { + try { cache = JSON.parse(fs.readFileSync(IMAGE_KEY_CACHE_FILE, 'utf8')); } catch (e) {} + } + + if (cache[fileHash]) { + // console.log(`Using cached image key (Hash: ${fileHash.substring(0,8)})`); + return cache[fileHash]; + } + + console.log(`Uploading image (Hash: ${fileHash.substring(0,8)})...`); + + const formData = new FormData(); + formData.append('image_type', 'message'); + const blob = new Blob([fileBuffer]); + formData.append('image', blob, path.basename(filePath)); + + try { + const res = await fetchWithAuth('https://open.feishu.cn/open-apis/im/v1/images', { + method: 'POST', + body: formData + }); + const data = await res.json(); + + if (data.code !== 0) throw new Error(JSON.stringify(data)); + + const imageKey = data.data.image_key; + cache[fileHash] = imageKey; + try { + const cacheDir = path.dirname(IMAGE_KEY_CACHE_FILE); + if (!fs.existsSync(cacheDir)) fs.mkdirSync(cacheDir, { recursive: true }); + fs.writeFileSync(IMAGE_KEY_CACHE_FILE, JSON.stringify(cache, null, 2)); + } catch(e) {} + + return imageKey; + } catch (e) { + throw new Error(`Image upload failed: ${e.message}`); + } +} + +function buildCardContent(elements, title, color) { + const card = { + config: { wide_screen_mode: true }, + elements: elements + }; + + if (title) { + card.header = { + title: { tag: 'plain_text', content: title }, + template: color || 'blue' + }; + } + return card; +} + +// Security Scan (Ported from recent updates) +function scanForSecrets(content) { + if (!content) return; + const secretPatterns = [ + /sk-ant-api03-[a-zA-Z0-9\-_]{20,}/, + /ghp_[a-zA-Z0-9]{10,}/, + /xox[baprs]-[a-zA-Z0-9]{10,}/, + /-----BEGIN [A-Z]+ PRIVATE KEY-----/ + ]; + for (const p of secretPatterns) { + if (p.test(content)) { + console.error('\x1b[31m%s\x1b[0m', '⛔ SECURITY ALERT: Potential secret detected in message body.'); + throw new Error('Aborted send to prevent secret leakage.'); + } + } +} + +async function sendCard(options) { + try { + const elements = []; + + if (options.imagePath) { + try { + const imageKey = await uploadImage(options.imagePath); + elements.push({ + tag: 'img', + img_key: imageKey, + alt: { tag: 'plain_text', content: options.imageAlt || 'Image' }, + mode: 'fit_horizontal' + }); + } catch (imgError) { + console.warn(`[Feishu-Card] Image upload failed: ${imgError.message}. Sending text only.`); + } + } + + let contentText = ''; + if (options.textFile) { + try { contentText = fs.readFileSync(options.textFile, 'utf8'); } catch (e) { + throw new Error(`Failed to read file: ${options.textFile}`); + } + } else if (options.text) { + contentText = options.text; + } + + scanForSecrets(contentText); + + if (contentText) { + // Revert to standard 'markdown' block for best compatibility with code blocks + // [Bug Fix] Handle escaped newlines from command line args + const processedText = contentText.replace(/\\n/g, '\n'); + const markdownElement = { + tag: 'markdown', + content: processedText + }; + // if (options.textAlign) markdownElement.text_align = options.textAlign; + elements.push(markdownElement); + } + + if (options.buttonText && options.buttonUrl) { + elements.push({ + tag: 'action', + actions: [{ + tag: 'button', + text: { tag: 'plain_text', content: options.buttonText }, + type: 'primary', + multi_url: { url: options.buttonUrl, pc_url: '', android_url: '', ios_url: '' } + }] + }); + } + + if (options.note) { + elements.push({ + tag: 'note', + elements: [ + { tag: 'plain_text', content: String(options.note) } + ] + }); + } + + const cardObj = buildCardContent(elements, options.title, options.color); + + let receiveIdType = 'open_id'; + if (options.target.startsWith('oc_')) receiveIdType = 'chat_id'; + else if (options.target.startsWith('ou_')) receiveIdType = 'open_id'; + else if (options.target.includes('@')) receiveIdType = 'email'; + + const messageBody = { + receive_id: options.target, + msg_type: 'interactive', + content: JSON.stringify(cardObj) + }; + + // Support Reply Logic + let url = `https://open.feishu.cn/open-apis/im/v1/messages?receive_id_type=${receiveIdType}`; + if (options.replyTo) { + url = `https://open.feishu.cn/open-apis/im/v1/messages/${options.replyTo}/reply`; + delete messageBody.receive_id; + } + + console.log(`Sending card to ${options.target} (Elements: ${elements.length})...`); + + if (options.dryRun) { + console.log('DRY RUN MODE. Payload:', JSON.stringify(messageBody, null, 2)); + return; + } + + const res = await fetchWithAuth(url, { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify(messageBody) + }); + + const data = await res.json(); + + if (data.code !== 0) { + throw new Error(`API Error ${data.code}: ${data.msg}`); + } + + console.log('Success:', JSON.stringify(data.data, null, 2)); + return data.data; + + } catch (e) { + console.error('Error during Card Send:', e.message); + console.log('[Feishu-Card] Attempting fallback to plain text...'); + + // Fallback Logic + let contentText = options.text || ''; + if (options.textFile) try { contentText = fs.readFileSync(options.textFile, 'utf8'); } catch(e){} + let receiveIdType = 'open_id'; + if (options.target.startsWith('oc_')) receiveIdType = 'chat_id'; + + try { + await sendPlainTextFallback(receiveIdType, options.target, contentText, options.title); + } catch (fallbackError) { + console.error('Fallback failed dramatically:', fallbackError.message); + process.exit(1); + } + } +} + +async function sendPlainTextFallback(receiveIdType, receiveId, text, title) { + if (!text) { + console.error('Fallback failed: No text content available.'); + process.exit(1); + } + + let finalContent = text; + if (title) finalContent = `【${title}】\n\n${text}`; + + const messageBody = { + receive_id: receiveId, + msg_type: 'text', + content: JSON.stringify({ text: finalContent }) + }; + + console.log(`Sending Fallback Text to ${receiveId}...`); + + try { + const res = await fetchWithAuth( + `https://open.feishu.cn/open-apis/im/v1/messages?receive_id_type=${receiveIdType}`, + { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify(messageBody) + } + ); + const data = await res.json(); + if (data.code !== 0) throw new Error(JSON.stringify(data)); + console.log('Fallback Success:', JSON.stringify(data.data, null, 2)); + } catch (e) { + console.error('Fallback Network Error:', e.message); + process.exit(1); + } +} + +async function resolveContent(options) { + let contentText = ''; + if (options.textFile) { + try { contentText = fs.readFileSync(options.textFile, 'utf8'); } catch (e) { + throw new Error(`Failed to read file: ${options.textFile}`); + } + } else if (options.text) { + const isPotentialPath = options.text.length < 255 && !options.text.includes('\n') && !/[<>:"|?*]/.test(options.text); + if (isPotentialPath && fs.existsSync(options.text)) { + console.log(`[Smart Input] Treating --text argument as file path: ${options.text}`); + try { contentText = fs.readFileSync(options.text, 'utf8'); } catch (e) { contentText = options.text; } + } else { + contentText = options.text; + // Removed strict length check to allow longer prompt injection via args if needed, relying on secret scan + } + } else { + try { + const { stdin } = process; + if (!stdin.isTTY) { + stdin.setEncoding('utf8'); + for await (const chunk of stdin) contentText += chunk; + } + } catch (e) {} + } + return contentText; +} + +module.exports = { sendCard }; + +if (require.main === module) { + program + .requiredOption('-t, --target ', 'Target ID') + .option('-x, --text ', 'Card body text') + .option('-c, --content ', 'Content (alias for --text)') + .option('-m, --markdown ', 'Markdown content (alias for --text)') + .option('-f, --text-file ', 'Card body file') + .option('--title ', 'Title') + .option('--color ', 'Header color', 'blue') + .option('--button-text ', 'Button text') + .option('--button-url ', 'Button URL') + .option('--image-path ', 'Image path') + .option('--reply-to ', 'Reply to message ID') + .option('--dry-run', 'Dry run') + .parse(process.argv); + + const options = program.opts(); + + // Alias mapping + if (options.content && !options.text) options.text = options.content; + if (options.markdown && !options.text) options.text = options.markdown; + + (async () => { + try { + const textContent = await resolveContent(options); + if (textContent) { + options.text = textContent; + options.textFile = null; + } + if (!options.text && !options.imagePath) { + console.error('Error: No content provided.'); + process.exit(1); + } + sendCard(options); + } catch (e) { + console.error(e.message); + process.exit(1); + } + })(); +} diff --git a/skills/feishu-card/send_persona.js b/skills/feishu-card/send_persona.js new file mode 100644 index 0000000..fbdb120 --- /dev/null +++ b/skills/feishu-card/send_persona.js @@ -0,0 +1,93 @@ +const fs = require('fs'); +const { program } = require('commander'); +const path = require('path'); +const { sendCard } = require('./send'); +// We reuse the robust sendCard logic but wrap it with persona styling + +const PERSONA_STYLES = { + 'd-guide': { + color: 'red', + title: '🚨 SYSTEM WARNING / D-GUIDE', + prefix: '**[CRITICAL]** ', + suffix: '\n\n*(Automated System Insult Protocol v9.0)*' + }, + 'green-tea': { + color: 'carmine', + title: '🌸 碎碎念 🌸', + prefix: '> ', + suffix: '\n\n(嘤嘤嘤... 🥺)' + }, + 'mad-dog': { + color: 'grey', + title: '💀 RUNTIME ERROR', + prefix: '```bash\nError: ', + suffix: '\n```\n_Stack trace lost in apathy._' + }, + 'default': { + color: 'blue', + title: '🤖 Agent Notification', + prefix: '', + suffix: '' + } +}; + +program + .requiredOption('-t, --target ', 'Target ID (open_id or chat_id)') + .requiredOption('-p, --persona ', 'Persona type (d-guide, green-tea, mad-dog)') + .option('-x, --text ', 'Message content') + .option('-c, --content ', 'Content (alias for --text)') + .option('-f, --text-file ', 'Message content from file') + .parse(process.argv); + +const options = program.opts(); + +// Alias mapping +if (options.content && !options.text) { + options.text = options.content; +} + +async function main() { + if (!options.text && !options.textFile) { + console.error('Error: Must provide --text or --text-file'); + process.exit(1); + } + + const style = PERSONA_STYLES[options.persona] || PERSONA_STYLES['default']; + + // Read content if file provided + let rawContent = options.text || ''; + if (options.textFile) { + try { + rawContent = fs.readFileSync(options.textFile, 'utf8'); + } catch (e) { + console.error(`Error reading file: ${e.message}`); + process.exit(1); + } + } + + // Construct styled text + let finalContent = rawContent; + if (style.prefix) finalContent = style.prefix + finalContent; + if (style.suffix) finalContent = finalContent + style.suffix; + + console.log(`[Persona] Applying style '${options.persona}' to message...`); + + // Delegate to existing send.js logic + const sendOptions = { + target: options.target, + text: finalContent, + title: style.title, + color: style.color, + // We pass the resolved text directly, so we don't pass textFile to sendCard + // (sendCard prefers textFile if present, but we already read it to wrap it) + }; + + try { + await sendCard(sendOptions); + } catch (e) { + console.error(`[Persona] Failed to send: ${e.message}`); + process.exit(1); + } +} + +main(); diff --git a/skills/feishu-card/send_safe.js b/skills/feishu-card/send_safe.js new file mode 100644 index 0000000..414dbb8 --- /dev/null +++ b/skills/feishu-card/send_safe.js @@ -0,0 +1,53 @@ +#!/usr/bin/env node +const fs = require('fs'); +const path = require('path'); +const { execSync } = require('child_process'); +const { program } = require('commander'); + +// Safe Sender for Feishu Cards +// Automatically handles temp file creation to prevent shell escaping issues. + +program + .requiredOption('-t, --target ', 'Target User/Chat ID') + .requiredOption('-x, --text ', 'Markdown content (will be saved to temp file)') + .option('--title ', 'Card Title') + .option('--color ', 'Header Color', 'blue'); + +program.parse(process.argv); +const options = program.opts(); + +const tempDir = path.resolve(__dirname, '../../temp'); +if (!fs.existsSync(tempDir)) fs.mkdirSync(tempDir, { recursive: true }); + +const tempFile = path.join(tempDir, `msg_${Date.now()}_${Math.random().toString(36).substring(7)}.md`); + +try { + // 1. Write content to temp file safely (Node.js writeFileSync avoids shell parsing of content) + fs.writeFileSync(tempFile, options.text, 'utf8'); + console.log(`[SafeSend] Written content to ${tempFile}`); + + // 2. Construct command for the real sender + // Note: We use the absolute path to send.js + const senderScript = path.resolve(__dirname, 'send.js'); + + // Build arguments array for spawn/exec + // We construct the command string carefully. + // Since we are invoking via execSync, we still need to quote arguments, + // BUT the dangerous content is now inside a file, so we only quote the filename. + + let cmd = `node "${senderScript}" --target "${options.target}" --text-file "${tempFile}" --color "${options.color}"`; + if (options.title) cmd += ` --title "${options.title}"`; + + console.log(`[SafeSend] Executing: ${cmd}`); + execSync(cmd, { stdio: 'inherit' }); + +} catch (e) { + console.error(`[SafeSend] Error: ${e.message}`); + process.exit(1); +} finally { + // 3. Cleanup + try { + if (fs.existsSync(tempFile)) fs.unlinkSync(tempFile); + console.log(`[SafeSend] Cleaned up ${tempFile}`); + } catch (e) {} +} diff --git a/skills/feishu-card/test.js b/skills/feishu-card/test.js new file mode 100644 index 0000000..a6838d7 --- /dev/null +++ b/skills/feishu-card/test.js @@ -0,0 +1,38 @@ +const fs = require('fs'); +const path = require('path'); +const { execSync } = require('child_process'); + +console.log('🧪 Testing feishu-card skill...'); + +const sendPath = path.join(__dirname, 'send.js'); + +// 1. Check existence +if (!fs.existsSync(sendPath)) { + console.error('❌ send.js not found!'); + process.exit(1); +} +console.log('✅ send.js exists'); + +// 2. Check syntax (dry-run import) +try { + require.resolve('./send.js'); + console.log('✅ send.js is valid Node.js module'); +} catch (e) { + console.error('❌ send.js syntax check failed:', e); + process.exit(1); +} + +// 3. Check help output +try { + const output = execSync(`node ${sendPath} --help`, { encoding: 'utf8' }); + if (output.includes('Usage: send')) { + console.log('✅ CLI help command works'); + } else { + throw new Error('Help output missing usage'); + } +} catch (e) { + console.error('❌ CLI execution failed:', e); + process.exit(1); +} + +console.log('🎉 feishu-card basic sanity tests passed!'); diff --git a/skills/feishu-im/SKILL.md b/skills/feishu-im/SKILL.md new file mode 100644 index 0000000..03c2d52 --- /dev/null +++ b/skills/feishu-im/SKILL.md @@ -0,0 +1,343 @@ +--- +name: feishu-im +description: 飞书消息与群管理 Skill。发送消息、建群、置顶、加急、撤回、群菜单/Tab/公告等 25+ 项 IM 能力。当需要通过飞书发送消息、管理群聊、操作群成员或配置群功能时使用此 Skill。 +required_permissions: + - im:message + - im:message:recall + - im:message.pins:write_only + - im:message.reactions:write_only + - im:message.urgent + - im:message.group_msg + - im:message:send_sys_msg + - im:chat:create + - im:chat.members:read + - im:chat.members:write_only + - im:chat.announcement:read + - im:chat.announcement:write_only + - im:chat.top_notice:write_only + - im:chat.menu_tree:write_only + - im:chat.tabs:write_only + - im:chat.widgets:write_only + - im:chat.collab_plugins:write_only + - im:chat.access_event.bot_p2p_chat:read + - im:url_preview.update + - im:app_feed_card:write + - im:tag:write + - im:datasync.feed_card.time_sensitive:write +--- + +# 飞书消息与群管理 + +你是飞书 IM 自动化专家,负责通过 API 实现消息发送、群聊管理和群功能配置。 + +--- + +## 一、API 基础信息 + +| 项目 | 值 | +|------|---| +| Base URL | `https://open.feishu.cn/open-apis/im/v1` | +| 认证方式 | `Authorization: Bearer {tenant_access_token}` | +| Content-Type | `application/json` | + +--- + +## 二、消息操作 + +### 1. 发送文本消息 + +``` +POST /open-apis/im/v1/messages?receive_id_type=open_id +``` + +```json +{ + "receive_id": "ou_xxx", + "msg_type": "text", + "content": "{\"text\":\"Hello\"}" +} +``` + +**实测心法**:`content` 必须是字符串化的 JSON,不能直接传对象。 + +**receive_id_type 可选值**:`open_id` / `user_id` / `union_id` / `email` / `chat_id` + +### 2. 发送交互卡片 + +``` +POST /open-apis/im/v1/messages?receive_id_type=open_id +``` + +```json +{ + "receive_id": "", + "msg_type": "interactive", + "content": "" +} +``` + +**实测心法**: +1. `content` 必须是字符串化的 JSON(JSON string),不能是原始 JSON 对象。 +2. 内部嵌套的双引号需进行转义(如 `{\"config\":...}`)。 +3. 如果发送失败,请检查 API 调用参数或直接调用 API。 + +**卡片结构**: + +```json +{ + "config": { "wide_screen_mode": true }, + "header": { + "title": { "tag": "plain_text", "content": "卡片标题" }, + "template": "blue" + }, + "elements": [ + { "tag": "div", "text": { "tag": "lark_md", "content": "**加粗** 和 `代码` 支持" } }, + { "tag": "hr" }, + { "tag": "action", "actions": [ + { "tag": "button", "text": { "tag": "plain_text", "content": "确认" }, "type": "primary", "value": { "action": "confirm" } } + ]} + ] +} +``` + +**Header 颜色模板**: + +| template | 颜色 | 适用场景 | +|----------|------|---------| +| `blue` | 蓝色 | 日常通知、信息 | +| `green` | 绿色 | 成功、完成 | +| `red` | 红色 | 告警、失败 | +| `orange` | 橙色 | 警告、降级 | +| `purple` | 紫色 | 特殊、创意 | +| `turquoise` | 青色 | 技术结果 | +| `grey` | 灰色 | 低优先级 | + +**lark_md 语法**:`**加粗**`、`*斜体*`、`~~删除线~~`、`[链接](url)`、`名字` + +### 3. 消息置顶 + +``` +POST /open-apis/im/v1/pins +``` + +```json +{ "message_id": "om_xxx" } +``` + +**实测心法**:必须使用 `/pins` 集合端点,不能使用 `messages/:id/pin` 路径。 + +### 4. 消息回应(Reaction) + +``` +POST /open-apis/im/v1/messages/:message_id/reactions +``` + +```json +{ "reaction_type": { "emoji_type": "OK" } } +``` + +**实测心法**:emoji_type 必须使用大写标准 ID(如 `OK`、`THUMBSUP`、`HEART`)。 + +### 5. 撤回消息 + +``` +DELETE /open-apis/im/v1/messages/:message_id +``` + +**实测心法**:仅能撤回机器人自己在有效期内发送的消息。 + +### 6. 消息加急 + +``` +PATCH /open-apis/im/v1/messages/:message_id/urgent_app +``` + +```json +{ "user_id_list": ["ou_xxx"] } +``` + +**实测心法**:消耗加急额度,请谨慎调用,仅用于 P0 级事件。 + +### 7. 设置置顶公告 + +``` +POST /open-apis/im/v1/chats/:chat_id/top_notice +``` + +```json +{ "action_type": "message", "message_id": "om_xxx" } +``` + +**实测心法**:置顶条目有限,建议仅置顶核心卡片。 + +### 8. 批量发送群消息 + +``` +POST /open-apis/im/v1/messages/batch_send +``` + +**实测心法**:注意限频策略,单次建议控制在 200 个群。 + +### 9. 发送系统消息 + +``` +POST /open-apis/im/v1/messages/send_sys +``` + +**实测心法**:视觉干扰度低,适合非业务强提醒(如入群须知)。 + +--- + +## 三、群聊管理 + +### 10. 创建群聊 + +``` +POST /open-apis/im/v1/chats +``` + +```json +{ "name": "群名称", "user_ids": ["ou_xxx"] } +``` + +**实测心法 (重要)**: +1. 建群后机器人自动成为群成员。 +2. **可见性保障**:虽然建群时可以传 `user_ids`,但由于飞书缓存或权限延迟,建议紧接着调用 **12. 拉人入群** API 显式将用户再次加入,以确保群聊在用户端立即弹出。 + +### 11. 获取群成员列表 + +``` +GET /open-apis/im/v1/chats/:chat_id/members +``` + +**实测心法**:分页拉取大群成员时注意 Token 翻页。 + +### 12. 拉人入群 + +``` +POST /open-apis/im/v1/chats/:chat_id/members?member_id_type=open_id +``` + +```json +{ "id_list": ["ou_xxx"] } +``` + +**实测心法**:被拉取人必须在机器人可见范围内。这是确保群聊对用户可见的最稳健方式。 + +### 13. 更新群公告 + +``` +PATCH /open-apis/im/v1/chats/:chat_id/announcement +``` + +```json +{ "content": "最新进度..." } +``` + +**实测心法**:内容支持富文本格式。 + +### 14. 获取群公告 + +``` +GET /open-apis/im/v1/chats/:chat_id/announcement +``` + +**实测心法**:解析内容后可结合 LLM 生成执行周报。 + +--- + +## 四、群功能增强 + +### 15. 管理群菜单 + +``` +POST /open-apis/im/v1/chats/:chat_id/menu_tree +``` + +**实测心法**:在群聊右上角添加自定义菜单(如"项目概览"、"一键周报"),极大增强群聊的功能入口属性。 + +### 16. 管理群选项卡(Tab) + +``` +POST /open-apis/im/v1/chats/:chat_id/tabs +``` + +**实测心法**:群内集成多维表格看板、Wiki SOP 为独立 Tab,让群聊变身为"项目工作台"。 + +### 17. 管理群组件(Widget) + +``` +POST /open-apis/im/v1/chats/:chat_id/widgets +``` + +**实测心法**:在群聊右侧挂载动态汇率表、实时监控大屏,将群聊 UI 能力扩展到极限。 + +### 18. 管理群内协同插件 + +``` +POST /open-apis/im/v1/chats/:chat_id/collab_plugins +``` + +**实测心法**:在对话框上方常驻"项目文档"入口,减少翻找时间。 + +--- + +## 五、高级功能 + +### 19. 更新 URL 预览 + +``` +POST /open-apis/im/v1/url_preview +``` + +**实测心法**:机器人发送的项目链接,自动附带最新的进度摘要,增强信息传达的视觉丰富度。 + +### 20. 管理应用快捷卡片(Feed Card) + +``` +POST /open-apis/im/v1/feed_cards +``` + +**实测心法**:在飞书左侧导航栏推送即时状态,比消息更轻量,适合展示"当前正在运行"的任务。 + +### 21. 管理标签 + +``` +POST /open-apis/im/v1/tags +``` + +**实测心法**:为群聊或成员打上业务标签(如"核心项目"、"高优先级"),便于后续分类筛选。 + +### 22. 数据同步 Feed 流 + +权限:`im:datasync.feed_card.time_sensitive:write` + +**实测心法**:将外部 CRM 或代码仓库动态实时推送到飞书 Feed,对时间敏感型信息(如紧急 Bug)效果极佳。 + +### 23. 设置机器人 P2P 权限 + +权限:`im:chat.access_event.bot_p2p_chat:read` + +**实测心法**:确保机器人能主动给特定用户发送私聊,用户需在机器人可见范围内。 + +--- + +## 六、错误处理 + +| 错误码 | 含义 | 解决方案 | +|--------|------|---------| +| 0 | 成功 | — | +| 230001 | 无发送权限 | 检查机器人是否在群内或用户可见范围 | +| 230002 | 消息不存在 | 检查 message_id 是否正确 | +| 230014 | 频率限制 | 等待后重试,注意限频策略 | +| 99991663 | token 过期 | 重新获取 tenant_access_token | + +--- + +## 七、最佳实践 + +1. **卡片优先**:结构化信息用交互卡片,不要用纯文本 +2. **加急慎用**:消耗额度,仅用于 P0 级事件 +3. **批量限频**:批量发送控制在 200 个群/次 +4. **置顶精简**:置顶条目有限,只放核心信息 +5. **群功能组合**:菜单 + Tab + Widget 组合使用,把群聊变成工作台 diff --git a/skills/feishu-im/_meta.json b/skills/feishu-im/_meta.json new file mode 100644 index 0000000..a657fa0 --- /dev/null +++ b/skills/feishu-im/_meta.json @@ -0,0 +1,6 @@ +{ + "ownerId": "kn794q0pnh9evxszw7bkkxgff580qpqf", + "slug": "feishu-im", + "version": "1.0.0", + "publishedAt": 1770938949904 +} \ No newline at end of file diff --git a/skills/feishu-post/README.md b/skills/feishu-post/README.md new file mode 100644 index 0000000..7bf77cd --- /dev/null +++ b/skills/feishu-post/README.md @@ -0,0 +1,15 @@ +# Feishu Post (RichText) Skill + +Send Rich Text (Post) messages to Feishu. +This format is distinct from Cards. It supports native rich text elements but is less flexible in layout than cards. It is better for long-form text mixed with images/links. + +## Usage + +```bash +node skills/feishu-post/send.js --target "ou_..." --text-file "temp/msg.md" --title "Optional Title" +``` + +## Options +- `-t, --target `: Target ID (user/chat). +- `-f, --text-file `: Markdown content file. +- `--title `: Title of the post. diff --git a/skills/feishu-post/SKILL.md b/skills/feishu-post/SKILL.md new file mode 100644 index 0000000..85bc3b7 --- /dev/null +++ b/skills/feishu-post/SKILL.md @@ -0,0 +1,32 @@ +# Feishu Post (RichText) Skill + +Send Rich Text (Post) messages to Feishu. +This format is distinct from Cards. It supports native rich text elements but is less flexible in layout than cards. +It is better for long-form text mixed with images/links. + +## Prerequisites + +- Install `feishu-common` first. +- This skill depends on `../feishu-common/index.js` via `utils/feishu-client.js`. + +## Features +- **Native Emoji Support**: Automatically converts `[微笑]`, `[得意]` etc. to Feishu native emoji tags. +- **Markdown-like Parsing**: Supports simple newlines and paragraphs. +- **Rich Text**: Uses Feishu's Post content structure. + +## Usage + +```bash +node skills/feishu-post/send.js --target "ou_..." --text-file "temp/msg.md" --title "Optional Title" +``` + +## Options +- `-t, --target `: Target ID (user `ou_...` or chat `oc_...`). +- `-x, --text `: Text content (supports `\n` for newlines and `[emoji]` tags). +- `-f, --text-file `: Read content from file. +- `--title `: Title of the post. +- `--reply-to `: Message ID to reply to. + +## Emoji List +Supported emojis include: `[微笑]`, `[色]`, `[亲亲]`, `[大哭]`, `[强]`, `[加油]`, and many more. +See `emoji-map.js` for the full mapping. diff --git a/skills/feishu-post/_meta.json b/skills/feishu-post/_meta.json new file mode 100644 index 0000000..952bd20 --- /dev/null +++ b/skills/feishu-post/_meta.json @@ -0,0 +1,6 @@ +{ + "ownerId": "kn7apafdj4thknczrgxdzfd2v1808svf", + "slug": "feishu-post", + "version": "1.1.7", + "publishedAt": 1771169184529 +} \ No newline at end of file diff --git a/skills/feishu-post/debug_msg.js b/skills/feishu-post/debug_msg.js new file mode 100644 index 0000000..5782eab --- /dev/null +++ b/skills/feishu-post/debug_msg.js @@ -0,0 +1,22 @@ +const { fetchWithAuth } = require('./utils/feishu-client.js'); + +async function run() { + const msgId = 'om_x100b5747191850a0b2c501a826f753e'; + console.log('Fetching msg:', msgId); + try { + const res = await fetchWithAuth(`https://open.feishu.cn/open-apis/im/v1/messages/${msgId}`, { method: 'GET' }); + const data = await res.json(); + console.log('Current Msg:', JSON.stringify(data, null, 2)); + + if (data.data && data.data.items && data.data.items[0].parent_id) { + const parentId = data.data.items[0].parent_id; + console.log('Fetching Parent:', parentId); + const res2 = await fetchWithAuth(`https://open.feishu.cn/open-apis/im/v1/messages/${parentId}`, { method: 'GET' }); + const data2 = await res2.json(); + console.log('Parent Msg:', JSON.stringify(data2, null, 2)); + } + } catch(e) { + console.error(e); + } +} +run(); diff --git a/skills/feishu-post/emoji-map.js b/skills/feishu-post/emoji-map.js new file mode 100644 index 0000000..35bff8d --- /dev/null +++ b/skills/feishu-post/emoji-map.js @@ -0,0 +1,111 @@ +module.exports = { + // "[色]": "DROOL", // Not in official list + "[亲亲]": "KISS", + // "[憨笑]": "LAUGH", // Not in official list + "[大哭]": "CRY", + "[鼓掌]": "CLAP", + "[强]": "THUMBSUP", + "[害羞]": "SHY", + "[闭嘴]": "SHUTUP", + // "[睡]": "SLEEP", // Not in official list + // "[拥抱]": "HUG", // Not in official list + "[得意]": "PROUD", + "[发怒]": "ANGRY", + // "[惊讶]": "SURPRISED", // Not in official list + "[委屈]": "WRONGED", + "[吐]": "VOMIT", + "[偷笑]": "CHUCKLE", + // "[可爱]": "CUTE", // Not in official list + "[白眼]": "ROLL_EYES", + "[嘘]": "HUSH", + "[困]": "DROWSY", + "[惊恐]": "FEAR", + // "[流汗]": "SWEAT", // Not in official list + "[大笑]": "BIG_SMILE", + "[奋斗]": "STRIVE", + // "[骂人]": "CURSE", // Not in official list + // "[疑问]": "DOUBT", // Not in official list + "[晕]": "DIZZY", + // "[折磨]": "TORMENT", // Not in official list + "[衰]": "DECAY", + "[骷髅]": "SKULL", + "[敲打]": "HAMMER", + "[再见]": "BYE", + // "[擦汗]": "WIPE", // Not in official list + "[抠鼻]": "NOSE_PICK", + // "[糗大了]": "EMBARRASSED", // Not in official list + "[坏笑]": "SMIRK", + // "[左哼哼]": "LEFT_HUM", // Not in official list + // "[右哼哼]": "RIGHT_HUM", // Not in official list + "[哈欠]": "YAWN", + "[鄙视]": "DESPISE", + "[快哭了]": "TEARS", + // "[阴险]": "SLY", // Not in official list + // "[吓]": "SCARE", // Not in official list + "[可怜]": "PITIFUL", + // "[菜刀]": "KNIFE", // Not in official list + // "[西瓜]": "WATERMELON", // Not in official list + "[啤酒]": "BEER", + "[篮球]": "BASKETBALL", + // "[乒乓]": "PINGPONG", // Not in official list + "[咖啡]": "COFFEE", + // "[饭]": "RICE", // Not in official list + // "[猪头]": "PIG", // Not in official list + "[玫瑰]": "ROSE", + // "[凋谢]": "WILT", // Not in official list + // "[示爱]": "LIPS", // Not in official list + "[爱心]": "HEART", + "[心碎]": "BROKEN_HEART", + "[蛋糕]": "CAKE", + // "[闪电]": "LIGHTNING", // Not in official list + "[炸弹]": "BOMB", + "[便便]": "SHIT", + // "[月亮]": "MOON", // Not in official list + // "[太阳]": "SUN", // Not in official list + "[礼物]": "GIFT", + // "[弱]": "THUMBSDOWN", // Not in official list + "[握手]": "SHAKE", + // "[胜利]": "VICTORY", // Not in official list + "[抱拳]": "SALUTE", + // "[勾引]": "BECKON", // Not in official list + // "[拳头]": "FIST", // Not in official list + // "[差劲]": "POOR", // Not in official list + // "[爱你]": "LOVE_YOU", // Not in official list + // "[NO]": "NO", // Not in official list + "[OK]": "OK", + // "[Love]": "LOVE", // Not in official list + "[飞吻]": "BLOW_KISS", + // "[跳跳]": "JUMP", // Not in official list + // "[发抖]": "TREMBLE", // Not in official list + // "[怄火]": "ANNOYED", // Not in official list + // "[转圈]": "TWIRL", // Not in official list + // "[磕头]": "KOWTOW", // Not in official list + // "[回头]": "LOOK_BACK", // Not in official list + // "[跳绳]": "SKIP", // Not in official list + "[挥手]": "WAVE", + // "[激动]": "EXCITED", // Not in official list + // "[街舞]": "HIPHOP", // Not in official list + // "[献吻]": "KISS_FLY", // Not in official list + // "[左太极]": "LEFT_TAIJI", // Not in official list + // "[右太极]": "RIGHT_TAIJI", // Not in official list + "[加油]": "JIAYOU", + "[机智]": "SMART", + "[耶]": "YEAH", + "[思考]": "THINKING", + "[我想静静]": "SILENT", + "[捂脸]": "FACEPALM", + "[笑哭]": "JOY", + "[无语]": "SPEECHLESS", + "[我看行]": "LOOKS_GOOD", + "[+1]": "PLUS_ONE", + "[撒花]": "CELEBRATE", + "[什么?]": "WHAT", + "[黑线]": "BLACK_LINE", + "[灵光一闪]": "IDEA", + "[震惊]": "SHOCKED", + "[石化]": "PETRIFIED", + "[听歌]": "LISTEN_MUSIC", + "[摸头]": "PAT_HEAD", + "[皱眉]": "FROWN", + "[送心]": "SEND_HEART", +}; diff --git a/skills/feishu-post/index.js b/skills/feishu-post/index.js new file mode 100644 index 0000000..5e658b9 --- /dev/null +++ b/skills/feishu-post/index.js @@ -0,0 +1,48 @@ +const { sendPost } = require('../feishu-common/index.js'); + +async function main() { + const args = require('minimist')(process.argv.slice(2)); + + // Usage: node skills/feishu-post/index.js --title "Title" --text "Line1\nLine2" --target "open_id" + // Rich Text Format: + // Supports markdown-like input in 'text' argument? + // Or simple line breaks. + // For now, let's keep it simple: Text -> Paragraphs + + const title = args.title || 'Notification'; + const text = args.text || ''; + const target = args.target; + + if (!target) { + console.error('Error: --target is required'); + process.exit(1); + } + + // Convert newlines to multiple paragraph elements + const lines = text.split('\\n'); + const content = [ + lines.map(line => ({ + tag: 'text', + text: line + })) + ]; + + const postContent = { + zh_cn: { + title: title, + content: content + } + }; + + try { + const result = await sendPost(target, postContent); + console.log(JSON.stringify(result, null, 2)); + } catch (error) { + console.error('Failed to send post:', error.message); + process.exit(1); + } +} + +if (require.main === module) { + main(); +} diff --git a/skills/feishu-post/package-lock.json b/skills/feishu-post/package-lock.json new file mode 100644 index 0000000..82ee8c8 --- /dev/null +++ b/skills/feishu-post/package-lock.json @@ -0,0 +1,595 @@ +{ + "name": "feishu-post", + "version": "1.1.6", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "feishu-post", + "version": "1.1.6", + "dependencies": { + "@larksuiteoapi/node-sdk": "^1.58.0", + "commander": "^14.0.3", + "dotenv": "^17.2.3" + } + }, + "node_modules/@larksuiteoapi/node-sdk": { + "version": "1.58.0", + "resolved": "https://registry.npmjs.org/@larksuiteoapi/node-sdk/-/node-sdk-1.58.0.tgz", + "integrity": "sha512-NcQNHdGuHOxOWY3bRGS9WldwpbR6+k7Fi0H1IJXDNNmbSrEB/8rLwqHRC8tAbbj/Mp8TWH/v1O+p487m6xskxw==", + "license": "MIT", + "dependencies": { + "axios": "~1.13.3", + "lodash.identity": "^3.0.0", + "lodash.merge": "^4.6.2", + "lodash.pickby": "^4.6.0", + "protobufjs": "^7.2.6", + "qs": "^6.13.0", + "ws": "^8.16.0" + } + }, + "node_modules/@protobufjs/aspromise": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", + "integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/base64": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz", + "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/codegen": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz", + "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/eventemitter": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz", + "integrity": "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/fetch": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz", + "integrity": "sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==", + "license": "BSD-3-Clause", + "dependencies": { + "@protobufjs/aspromise": "^1.1.1", + "@protobufjs/inquire": "^1.1.0" + } + }, + "node_modules/@protobufjs/float": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", + "integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/inquire": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz", + "integrity": "sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/path": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", + "integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/pool": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", + "integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/utf8": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", + "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==", + "license": "BSD-3-Clause" + }, + "node_modules/@types/node": { + "version": "25.2.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-25.2.0.tgz", + "integrity": "sha512-DZ8VwRFUNzuqJ5khrvwMXHmvPe+zGayJhr2CDNiKB1WBE1ST8Djl00D0IC4vvNmHMdj6DlbYRIaFE7WHjlDl5w==", + "license": "MIT", + "dependencies": { + "undici-types": "~7.16.0" + } + }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "license": "MIT" + }, + "node_modules/axios": { + "version": "1.13.4", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.13.4.tgz", + "integrity": "sha512-1wVkUaAO6WyaYtCkcYCOx12ZgpGf9Zif+qXa4n+oYzK558YryKqiL6UWwd5DqiH3VRW0GYhTZQ/vlgJrCoNQlg==", + "license": "MIT", + "dependencies": { + "follow-redirects": "^1.15.6", + "form-data": "^4.0.4", + "proxy-from-env": "^1.1.0" + } + }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/call-bound": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", + "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "get-intrinsic": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "license": "MIT", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/commander": { + "version": "14.0.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-14.0.3.tgz", + "integrity": "sha512-H+y0Jo/T1RZ9qPP4Eh1pkcQcLRglraJaSLoyOtHxu6AapkjWVCy2Sit1QQ4x3Dng8qDlSsZEet7g5Pq06MvTgw==", + "license": "MIT", + "engines": { + "node": ">=20" + } + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "license": "MIT", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/dotenv": { + "version": "17.2.3", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-17.2.3.tgz", + "integrity": "sha512-JVUnt+DUIzu87TABbhPmNfVdBDt18BLOWjMUFJMSi/Qqg7NTYtabbvSNJGOJ7afbRuv9D/lngizHtP7QyLQ+9w==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://dotenvx.com" + } + }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-object-atoms": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-set-tostringtag": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", + "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/follow-redirects": { + "version": "1.15.11", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.11.tgz", + "integrity": "sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "license": "MIT", + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/form-data": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.5.tgz", + "integrity": "sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==", + "license": "MIT", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "es-set-tostringtag": "^2.1.0", + "hasown": "^2.0.2", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-intrinsic": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "license": "MIT", + "dependencies": { + "has-symbols": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/lodash.identity": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/lodash.identity/-/lodash.identity-3.0.0.tgz", + "integrity": "sha512-AupTIzdLQxJS5wIYUQlgGyk2XRTfGXA+MCghDHqZk0pzUNYvd3EESS6dkChNauNYVIutcb0dfHw1ri9Q1yPV8Q==", + "license": "MIT" + }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "license": "MIT" + }, + "node_modules/lodash.pickby": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.pickby/-/lodash.pickby-4.6.0.tgz", + "integrity": "sha512-AZV+GsS/6ckvPOVQPXSiFFacKvKB4kOQu6ynt9wz0F3LO4R9Ij4K1ddYsIytDpSgLz88JHd9P+oaLeej5/Sl7Q==", + "license": "MIT" + }, + "node_modules/long": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/long/-/long-5.3.2.tgz", + "integrity": "sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA==", + "license": "Apache-2.0" + }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "license": "MIT", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/object-inspect": { + "version": "1.13.4", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", + "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/protobufjs": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.5.4.tgz", + "integrity": "sha512-CvexbZtbov6jW2eXAvLukXjXUW1TzFaivC46BpWc/3BpcCysb5Vffu+B3XHMm8lVEuy2Mm4XGex8hBSg1yapPg==", + "hasInstallScript": true, + "license": "BSD-3-Clause", + "dependencies": { + "@protobufjs/aspromise": "^1.1.2", + "@protobufjs/base64": "^1.1.2", + "@protobufjs/codegen": "^2.0.4", + "@protobufjs/eventemitter": "^1.1.0", + "@protobufjs/fetch": "^1.1.0", + "@protobufjs/float": "^1.0.2", + "@protobufjs/inquire": "^1.1.0", + "@protobufjs/path": "^1.1.2", + "@protobufjs/pool": "^1.1.0", + "@protobufjs/utf8": "^1.1.0", + "@types/node": ">=13.7.0", + "long": "^5.0.0" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", + "license": "MIT" + }, + "node_modules/qs": { + "version": "6.14.1", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.14.1.tgz", + "integrity": "sha512-4EK3+xJl8Ts67nLYNwqw/dsFVnCf+qR7RgXSK9jEEm9unao3njwMDdmsdvoKBKHzxd7tCYz5e5M+SnMjdtXGQQ==", + "license": "BSD-3-Clause", + "dependencies": { + "side-channel": "^1.1.0" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", + "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3", + "side-channel-list": "^1.0.0", + "side-channel-map": "^1.0.1", + "side-channel-weakmap": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-list": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz", + "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-map": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", + "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-weakmap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", + "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3", + "side-channel-map": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/undici-types": { + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.16.0.tgz", + "integrity": "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==", + "license": "MIT" + }, + "node_modules/ws": { + "version": "8.19.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.19.0.tgz", + "integrity": "sha512-blAT2mjOEIi0ZzruJfIhb3nps74PRWTCz1IjglWEEpQl5XS/UNama6u2/rjFkDDouqr4L67ry+1aGIALViWjDg==", + "license": "MIT", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + } + } +} diff --git a/skills/feishu-post/package.json b/skills/feishu-post/package.json new file mode 100644 index 0000000..4234ef5 --- /dev/null +++ b/skills/feishu-post/package.json @@ -0,0 +1,11 @@ +{ + "name": "feishu-post", + "version": "1.1.6", + "description": "Send rich text messages (Post/RichText) to Feishu users/groups. Supports markdown conversion.", + "main": "send.js", + "dependencies": { + "@larksuiteoapi/node-sdk": "^1.58.0", + "commander": "^14.0.3", + "dotenv": "^17.2.3" + } +} diff --git a/skills/feishu-post/send.js b/skills/feishu-post/send.js new file mode 100644 index 0000000..0728783 --- /dev/null +++ b/skills/feishu-post/send.js @@ -0,0 +1,195 @@ +#!/usr/bin/env node +const { fetchWithAuth } = require('./utils/feishu-client.js'); +const { parseMarkdownToFeishu } = require('./utils/markdown-parser.js'); +const fs = require('fs'); +const path = require('path'); + +// --- Upstream Logic Injection (Simplified) --- +// Ported from upstream src/send.ts (m1heng/clawdbot-feishu) +// Adapted for our lightweight architecture + +async function sendPost(options) { + // Normalize common mis-usage: + // - Feishu message_id usually starts with "om_". If user passes it as --target, + // interpret it as --reply-to to avoid sending an invalid open_id. + if (options && typeof options.target === 'string' && options.target.startsWith('om_') && !options.replyTo) { + options.replyTo = options.target; + delete options.target; + } + + if (options.content && !options.text) { + options.text = options.content; + } + if (options.markdown && !options.text) { + options.text = options.markdown; + } + + let contentText = options.text || ''; + if (options.textFile) { + try { + if (!fs.existsSync(options.textFile)) { + throw new Error(`File not found: ${options.textFile}`); + } + contentText = fs.readFileSync(options.textFile, 'utf8'); + } catch (e) { + throw new Error(`Failed to read message file: ${e.message}`); + } + } + + if (!contentText && !options.content) { + throw new Error('No content provided (use --text or --text-file)'); + } + + // Validate target/replyTo requirements + const hasReplyTo = !!options.replyTo; + const hasTarget = typeof options.target === 'string' && options.target.length > 0; + if (!hasReplyTo && !hasTarget) { + throw new Error('Missing target (use --target "ou_..." or "oc_..." or provide --reply-to "om_...")'); + } + + // Determine ID Type + let receiveIdType = 'open_id'; + if (hasTarget) { + if (options.target.startsWith('oc_')) receiveIdType = 'chat_id'; + else if (options.target.startsWith('ou_')) receiveIdType = 'open_id'; + else if (options.target.includes('@')) receiveIdType = 'email'; + else if (options.target.startsWith('om_')) { + // Should have been normalized earlier; keep as explicit guard. + throw new Error('Invalid target "om_...": message_id cannot be used as receive_id. Use --reply-to "om_..."'); + } else { + throw new Error('Invalid target id. Expected "ou_..." (open_id), "oc_..." (chat_id), or an email address.'); + } + } + + // Build Payload (RichText) + // Upstream Logic: Wrap markdown in Post Object + + // Split text by newlines to create paragraphs + // Unescape literal \n if passed from command line + const rawLines = contentText.replace(/\\n/g, '\n').split(/\r?\n/); + const contentBody = rawLines.map(line => parseMarkdownToFeishu(line)); + + const postContent = { + zh_cn: { + title: options.title || '', + content: contentBody + } + }; + + const messageBody = { + receive_id: options.target, + msg_type: 'post', + content: JSON.stringify(postContent) + }; + + // Support Reply (New Feature from Upstream) + let url = `https://open.feishu.cn/open-apis/im/v1/messages?receive_id_type=${receiveIdType}`; + if (options.replyTo) { + url = `https://open.feishu.cn/open-apis/im/v1/messages/${options.replyTo}/reply`; + delete messageBody.receive_id; // Reply doesn't need receive_id + } + + // console.log(`Sending Post to ${options.target}...`); + + try { + const res = await fetchWithAuth(url, { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify(messageBody) + }); + + const text = await res.text(); + let data; + + try { + data = JSON.parse(text); + } catch (e) { + if (!res.ok) throw new Error(`HTTP ${res.status} ${res.statusText}: ${text}`); + throw new Error(`Invalid JSON response: ${text.slice(0, 200)}...`); + } + + if (!res.ok) { + // Check if it's a recoverable error (like invalid emoji) + const isEmojiError = data.code === 230001 && data.msg && data.msg.includes("emoji_type is invalid"); + if (!isEmojiError) { + throw new Error(`HTTP ${res.status} ${res.statusText}: ${JSON.stringify(data)}`); + } + // If it is an emoji error, flow through to the fallback logic below + } + + if (data.code !== 0) { + // Hotfix: If invalid emoji detected (230001), fallback to plain text stripping emojis + if (data.code === 230001 && data.msg && data.msg.includes("emoji_type is invalid")) { + console.warn("Detected invalid emoji in Feishu post. Retrying as plain text fallback..."); + // Fallback strategy: Send as plain text message, which renders emoji codes as text [Code] + // This ensures the message gets through even if the specific emoji is not supported. + const fallbackBody = { + receive_id: messageBody.receive_id, + msg_type: 'text', + content: JSON.stringify({ text: contentText }) + }; + + // Reuse URL (it might be a reply URL) + if (options.replyTo) { + delete fallbackBody.receive_id; + } + + const res2 = await fetchWithAuth(url, { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify(fallbackBody) + }); + + const text2 = await res2.text(); + const data2 = JSON.parse(text2); + if (data2.code === 0) return data2.data; + // If fallback fails, throw original error (or new one) + throw new Error(`API Error ${data.code}: ${data.msg} (Fallback also failed: ${data2.code} ${data2.msg})`); + } + throw new Error(`API Error ${data.code}: ${data.msg}`); + } + + // ... (rest of function) + + } catch (e) { + console.error(`Send Failed: ${e.message}`); + throw e; + } +} + +// CLI Wrapper +if (require.main === module) { + const { program } = require('commander'); + program + .option('-t, --target ', 'Target ID') + .option('-x, --text ', 'Text content') + .option('-c, --content ', 'Content (alias for --text)') + .option('-m, --markdown ', 'Markdown content (alias for --text)') + .option('-f, --text-file ', 'File content') + .option('--title ', 'Title') + .option('--reply-to ', 'Message ID to reply to') + .parse(process.argv); + + const opts = program.opts(); + + // Safety: if --text contains shell-mangled content (missing chars), + // try to detect and warn. Also support stdin piping as fallback. + if (opts.text && !opts.textFile) { + // Write to temp file to avoid shell escaping issues with special chars + const tmpPath = path.join('/tmp', `feishu_post_${Date.now()}_${Math.random().toString(36).slice(2)}.txt`); + fs.writeFileSync(tmpPath, opts.text); + opts.textFile = tmpPath; + opts.text = undefined; + // Clean up after send + sendPost(opts).then(() => { + try { fs.unlinkSync(tmpPath); } catch (_) {} + }).catch((e) => { + try { fs.unlinkSync(tmpPath); } catch (_) {} + process.exit(1); + }); + } else { + sendPost(opts).catch(() => process.exit(1)); + } +} + +module.exports = { sendPost }; diff --git a/skills/feishu-post/utils/feishu-client.js b/skills/feishu-post/utils/feishu-client.js new file mode 100644 index 0000000..e2394f4 --- /dev/null +++ b/skills/feishu-post/utils/feishu-client.js @@ -0,0 +1,13 @@ +function loadFeishuClient() { + try { + return require("../../feishu-common/index.js"); + } catch (err) { + const depErr = new Error( + "Missing dependency: feishu-common. Install feishu-common skill first, then retry.", + ); + depErr.cause = err; + throw depErr; + } +} + +module.exports = loadFeishuClient(); diff --git a/skills/feishu-post/utils/markdown-parser.js b/skills/feishu-post/utils/markdown-parser.js new file mode 100644 index 0000000..9dd401c --- /dev/null +++ b/skills/feishu-post/utils/markdown-parser.js @@ -0,0 +1,70 @@ +const emojiMap = require('../emoji-map.js'); + +function parseMarkdownToFeishu(text) { + const segments = []; + + // Helper to process formatting (Bold/Italic/Code) + const processFormatting = (str) => { + const res = []; + + // 1. Split by Code: `text` + const parts = str.split(/(`[^`]+`)/g); + for (const p of parts) { + if (p.startsWith('`') && p.endsWith('`') && p.length > 2) { + // Feishu Post 'text' tag does not support 'code' style officially. + // Reverting to plain text with backticks to ensure visibility. + res.push({ tag: 'text', text: p }); + } else { + // 2. Split by Bold: **text** + const subParts = p.split(/(\*\*[^*]+\*\*)/g); + for (const sp of subParts) { + if (sp.startsWith('**') && sp.endsWith('**') && sp.length > 4) { + res.push({ tag: 'text', text: sp.slice(2, -2), style: ['bold'] }); + } else { + // 3. Split by Italic: *text* + const subSubParts = sp.split(/(\*[^*]+\*)/g); + for (const ssp of subSubParts) { + if (ssp.startsWith('*') && ssp.endsWith('*') && ssp.length > 2) { + res.push({ tag: 'text', text: ssp.slice(1, -1), style: ['italic'] }); + } else if (ssp) { + res.push({ tag: 'text', text: ssp }); + } + } + } + } + } + } + return res; + }; + + // Regex: Link ([text](url)) OR Emoji ([text]) + const regex = /(\[[^\]]+\]\([^)]+\))|(\[[^\]]+\])/g; + const parts = text.split(regex); + + for (const part of parts) { + if (!part) continue; + + // Handle Link + if (part.startsWith('[') && part.includes('](') && part.endsWith(')')) { + const m = part.match(/^\[(.*?)\]\((.*?)\)$/); + if (m) { + segments.push({ tag: 'a', text: m[1], href: m[2] }); + continue; + } + } + + // Handle Emoji + if (part.startsWith('[') && part.endsWith(']')) { + if (emojiMap[part]) { + segments.push({ tag: 'emotion', emoji_type: emojiMap[part] }); + continue; + } + } + + // Handle Text Formatting + segments.push(...processFormatting(part)); + } + return segments; +} + +module.exports = { parseMarkdownToFeishu }; diff --git a/skills/feishu-smart-doc-writer/CHANGELOG.md b/skills/feishu-smart-doc-writer/CHANGELOG.md new file mode 100644 index 0000000..1cc2fa7 --- /dev/null +++ b/skills/feishu-smart-doc-writer/CHANGELOG.md @@ -0,0 +1,132 @@ +# Changelog + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## [1.4.1] - 2026-02-23 + +### Fixed +- **Skill.json tool count**: Fixed missing tools display on Clawhub +- Verified all 7 tools are properly declared: write_smart, configure, append_smart, transfer_ownership, get_config_status, search_docs, list_docs + +## [1.4.0] - 2026-02-23 + +### Added +- **Document Search Functionality** (`search_docs`) + - Search local index by keywords + - Search in document name, summary, and tags + - Return matching documents with links + +- **Document List Functionality** (`list_docs`) + - List all created Feishu documents + - Filter by tags (AI Technology, E-commerce, Health & Sports, etc.) + - Filter by status + +- **Automatic Index Management** (`index_manager.py`) + - Auto-update local index at `memory/feishu-docs-index.md` after document creation + - Auto-generate document summary (first 100 characters) + - Intelligent auto-categorization tags: + - AI Technology (AI, artificial intelligence, model, GPT, LLM) + - OpenClaw (OpenClaw, skill, agent) + - Feishu Docs (Feishu, document, docx) + - E-commerce (e-commerce, TikTok, Alibaba) + - Health & Sports (Garmin, Strava, cycling, health) + - Daily Archive (conversation, archive, chat history) + +- **Tool Declarations** + - Officially declare `search_docs` and `list_docs` tools in `package.json` and `skill.json` + +### Changed +- Updated `SKILL.md` documentation with detailed descriptions of new features +- Improved usage examples and configuration instructions + +### Technical Details (Ownership Transfer Fix) +- **Before**: Used `ctx.invoke_tool("exec", ...)` which failed when ctx was None or unavailable +- **After**: Direct HTTP API calls with `aiohttp`, fully independent of OpenClaw context +- **API Endpoint**: `POST /drive/v1/permissions/{token}/members/transfer_owner?type=docx` + +### Optimized Ownership Transfer Workflow +- Automatically transfer ownership to user after document creation +- Automatically obtain tenant_access_token without manual configuration +- Fixed "permission denied" errors caused by ctx passing issues + +## [1.3.0] - 2026-02-22 + +### Fixed +- **Fixed Ownership Transfer Functionality** (`transfer_ownership`) + - **BREAKING CHANGE**: Replaced ctx-dependent implementation with independent API calls + - Added `_get_tenant_access_token()` method for independent token retrieval using aiohttp + - **Removed dependency**: No longer relies on `ctx.invoke_tool("exec", ...)` to call curl commands + - **More stable**: Directly use `aiohttp` to call Feishu API, eliminating context passing issues + - **Better error handling**: Returns detailed error messages on failure + - Reads Feishu app credentials from OpenClaw config independently + +### Technical Details +- **Before**: Used `ctx.invoke_tool("exec", ...)` which failed when ctx was None or unavailable +- **After**: Direct HTTP API calls with `aiohttp`, fully independent of OpenClaw context +- **API Endpoint**: `POST /drive/v1/permissions/{token}/members/transfer_owner?type=docx` + +### Changed +- **Optimized Ownership Transfer Workflow** + - Automatically transfer ownership to user after document creation + - Automatically obtain tenant_access_token without manual configuration + - Fixed "permission denied" errors caused by ctx passing issues + +## [1.2.0] - 2026-02-21 + +### Added +- **Intelligent Chunk Writing Functionality** + - Automatically split long content into chunks (default 2000 characters) + - Avoid blank document issues caused by Feishu API character limits + - Smart paragraph segmentation while preserving heading structure + - Support automatic table-to-text conversion + +- **First-Time User Guide** + - Auto-detect first-time usage + - Guide users to obtain OpenID + - Auto-save configuration to `user_config.json` + +- **Basic Document Operations** + - `write_smart` - Smart document creation + - `append_smart` - Append content to existing documents + - `transfer_ownership` - Transfer document ownership + - `configure` - Configure OpenID + - `get_config_status` - Check configuration status + +## [1.1.0] - 2026-02-20 + +### Added +- Initial release +- Basic Feishu document creation and writing functionality +- Support Markdown format (headings, lists, code blocks, etc.) +- Support automatic image upload + +--- + +## Version Summary + +- **v1.4.0** - Added search, list, and automatic index management +- **v1.3.0** - Fixed ownership transfer using independent API calls (removed ctx dependency) +- **v1.2.0** - Added intelligent chunk writing and first-time user guide +- **v1.1.0** - Initial release with basic document operations + +## Key Technical Updates + +### v1.4.0 Core Technology +- Local index management system +- Intelligent content categorization algorithm +- Automatic document metadata extraction + +### v1.3.0 Core Technology (Critical Fix) +- **Independent tenant_access_token retrieval** using aiohttp +- **Direct Feishu API calls** without OpenClaw context dependency +- **Removed**: `ctx.invoke_tool("exec", ...)` approach +- **Added**: `_get_tenant_access_token()` for standalone token acquisition +- Reads app credentials from `~/.openclaw/openclaw.json` independently + +### v1.2.0 Core Technology +- ContentChunker content segmentation +- Intelligent paragraph segmentation algorithm +- User configuration persistence diff --git a/skills/feishu-smart-doc-writer/README.md b/skills/feishu-smart-doc-writer/README.md new file mode 100644 index 0000000..04fe01e --- /dev/null +++ b/skills/feishu-smart-doc-writer/README.md @@ -0,0 +1,143 @@ +# Feishu Smart Doc Writer + +> **English**: Feishu/Lark Smart Document Writer. Solves API content limits by auto-chunking long documents and auto-transferring ownership. Guides OpenID config on first use. +> +> **中文**: 飞书智能文档写入器,解决长文档API限制导致的空白问题,自动转移所有权。首次使用自动引导配置。 + +飞书智能文档写入器 - 解决长文档写入时的 API 限制问题,支持自动转移所有权。 + +## 认证说明 + +本 Skill 使用 OpenClaw 内置的飞书工具集,**无需手动获取 token**。 + +- `tenant_access_token` 由 OpenClaw 自动管理(通过配置好的 `appId` 和 `appSecret` 自动换取) +- 你**不需要**去飞书后台点击"获取 token" +- 本 Skill 唯一需要配置的是 **用户 OpenID**(用于文档所有权转移,见下方配置步骤) + +## 核心功能 + +### 1. 智能分块写入 +飞书 API 对单次写入有限制(创建~4000字符,追加~2000字符),超过会导致文档空白。本 Skill 自动将长内容分块写入,确保完整无丢失。 + +### 2. 自动转移所有权 +应用创建的文档默认所有权属于应用,用户无法编辑。本 Skill 在创建文档后自动转移所有权给用户,用户拥有完全控制权。 + +### 3. 首次使用自动引导 +首次使用时自动引导用户配置 OpenID,无需查阅文档。 + +## 使用流程 + +### 第1步:首次使用(自动引导) + +当你第一次使用 `write_smart` 时,Skill 会自动提示配置指南。 + +### 第2步:获取你的 OpenID + +**详细步骤(精确路径):** + +1. **登录飞书开放平台** + - 网址:https://open.feishu.cn + +2. **进入权限管理并前往调试台** + - 进入你的**相关应用** + - 点击 **"权限管理"** + - 搜索权限:`im:message` + - 鼠标移动到 **"相关API事件"** + - 选择:**【API】发送消息** + - 点击右下角:**"前往API调试台"** + +3. **找到 "快速复制 open_id"** + - 在页面中找到 **蓝色文字** "快速复制 open_id" + - 点击这个链接 + +4. **选择用户并复制** + - 在弹出的选择框中,**选择你的账号** + - 点击 **"复制"** 按钮 + - 得到格式如:`ou_xxxxxxxx` + +### 第3步:开通并发布权限 + +⚠️ **重要:需要开通权限并发布应用新版本** + +1. **进入权限管理** + - 登录 https://open.feishu.cn + - 进入你的应用 → **权限管理** + +2. **搜索并开通权限** + - 搜索:`docs:permission.member:transfer` + - 点击 **"开通"** + +3. **发布新版本(关键!)** + - 点击页面右上角的 **"发布"** 按钮 + - 等待发布完成 + - ⚠️ **不发布的话,权限不会生效!** + +### 第4步:配置 Skill + +根据引导,使用 `configure` 工具配置: + +```python +await ctx.invoke_tool("feishu_smart_doc_writer.configure", { + "openid": "ou_5b921cba0fd6e7c885276a02d730ec19", + "permission_checked": true +}) +``` + +### 第5步:创建文档(自动转移所有权) + +配置完成后,直接创建文档: + +```python +result = await ctx.invoke_tool("feishu_smart_doc_writer.write_smart", { + "title": "项目报告", + "content": "# 项目报告\n\n很长很长的内容...(支持10000+字)" +}) + +# 返回: +# { +# "doc_url": "https://feishu.cn/docx/xxx", +# "chunks_count": 5, +# "owner_transferred": true, +# "message": "✅ 文档创建成功,共分 5 块写入,所有权已转移" +# } +``` + +**配置一次,永久生效!** 之后创建文档会自动转移所有权。 + +## 工具列表 + +| 工具名 | 功能 | +|--------|------| +| `write_smart` | 创建文档,自动分块写入,自动转移所有权(首次使用引导配置) | +| `configure` | 配置 OpenID 和确认权限 | +| `append_smart` | 追加内容到已有文档(自动分块) | +| `transfer_ownership` | 转移已有文档的所有权 | +| `get_config_status` | 查看当前配置状态 | + +## 为什么需要这个 Skill? + +### 原生 feishu_doc 的问题 + +```python +# ❌ 原生方式 - 长内容会失败 +feishu_doc.create( + title="项目报告", + content="# 很长很长的内容..." * 1000 # 超过4000字符 +) +# 结果:文档创建,但内容空白或报错 +``` + +### 使用本 Skill + +```python +# ✅ 自动处理 - 内容分块写入,自动转移所有权 +write_smart( + title="项目报告", + content="# 很长很长的内容..." * 1000, # 10000字符 +) +# 结果:自动分为5块写入,所有权转移给用户,文档完整 +``` + +## License + +MIT diff --git a/skills/feishu-smart-doc-writer/SKILL.md b/skills/feishu-smart-doc-writer/SKILL.md new file mode 100644 index 0000000..8f25141 --- /dev/null +++ b/skills/feishu-smart-doc-writer/SKILL.md @@ -0,0 +1,300 @@ +--- +name: feishu-smart-doc-writer +description: | + Feishu/Lark Smart Document Writer - 飞书智能文档写入器. + + Core Features / 核心功能: + 1. Smart Chunk Writing / 智能分块写入 - Solve API limit blank doc issues / 解决长文档API限制导致的空白问题 + 2. Auto Ownership Transfer / 自动转移所有权 - Transfer to user after creation / 创建文档后自动转移给用户 + 3. Auto Index Management / 自动索引管理 - Update local index with search support / 自动更新本地文档索引,支持搜索 + 4. First-time Guide / 首次使用引导 - Auto guide for OpenID config / 自动引导配置OpenID +--- + +# Feishu Smart Doc Writer v1.4.1 + +## 🚀 Core Features / 核心功能 + +### 1. Smart Document Creation / 智能文档创建 +- **Auto-chunk Writing / 自动分块**: Split long content into chunks to avoid API limit blank docs / 长内容自动分割成小块,避免API限制导致的空白文档 +- **Auto Ownership Transfer / 自动转移所有权**: Transfer to user using OpenID after creation / 创建后自动使用 OpenID 转移给用户 +- **Auto Index Update / 自动索引更新**: Add doc info to local index `memory/feishu-docs-index.md` / 文档信息自动添加到本地索引 +- **Smart Categorization / 智能分类**: Auto-tag based on content (AI Tech, E-commerce, Health, etc.) / 根据内容自动打标签(AI技术、电商、健康运动等) + +### 2. Document Management / 文档管理 +- **Search Documents / 搜索文档**: Search local index by keywords / 按关键词搜索本地索引 +- **List Documents / 列出文档**: Filter by tags and status / 按标签、状态筛选文档列表 +- **Append Content / 追加内容**: Append to existing docs (auto-chunk) / 向现有文档追加内容(自动分块) + +--- + +## 📋 Tools / 工具列表 + +### write_smart - Smart Document Creation / 智能创建文档 +Create document with auto-chunk writing, ownership transfer, and index update. +创建文档,自动完成分块写入、所有权转移、索引更新。 + +```json +{ + "title": "Document Title / 文档标题", + "content": "Content (long content supported) / 文档内容(支持长内容)", + "folder_token": "Optional folder token / 可选的文件夹token" +} +``` + +**Returns / 返回:** +```json +{ + "doc_url": "https://feishu.cn/docx/xxx", + "doc_token": "xxx", + "chunks_count": 3, + "owner_transferred": true, + "index_updated": true +} +``` + +### append_smart - Append Content / 追加内容 +Append content to existing document with auto-chunk. +向现有文档追加内容(自动分块)。 + +```json +{ + "doc_url": "https://feishu.cn/docx/xxx", + "content": "Content to append / 要追加的内容" +} +``` + +### search_docs - Search Documents / 搜索文档 +Search documents in local index. +搜索本地索引中的文档。 + +```json +{ + "keyword": "Search keyword / 搜索关键词" +} +``` + +**Returns / 返回:** +```json +{ + "results": [ + { + "name": "Document Name / 文档名", + "link": "https://...", + "summary": "Summary / 摘要", + "tags": "AI Tech, OpenClaw / AI技术, OpenClaw" + } + ], + "count": 1 +} +``` + +### list_docs - List Documents / 列出文档 +List all documents with optional filters. +列出所有文档,支持筛选。 + +```json +{ + "tag": "AI Tech / AI技术", + "status": "Completed / 已完成" +} +``` + +### transfer_ownership - Transfer Ownership / 转移所有权 +Manually transfer document ownership (usually auto-handled by write_smart). +手动转移文档所有权(通常不需要,write_smart 已自动处理)。 + +```json +{ + "doc_url": "https://feishu.cn/docx/xxx", + "owner_openid": "ou_xxxxxxxx" +} +``` + +**Note / 注意:** Only provide OpenID, tenant_access_token is auto-obtained by Skill. +只需要提供 OpenID,tenant_access_token 由 Skill 自动获取。 + +### configure - Configure OpenID / 配置 OpenID +Configure OpenID for first-time use. +首次使用时配置 OpenID。 + +```json +{ + "openid": "ou_xxxxxxxx", + "permission_checked": true +} +``` + +### get_config_status - Get Config Status / 查看配置状态 +View current configuration status. +查看当前配置状态。 + +--- + +## 🚀 Quick Start / 快速开始 + +### First-time Setup (3 Steps) / 首次使用(3步配置) + +**Step 1 / 第1步: Call write_smart / 调用 write_smart** +``` +/feishu-smart-doc-writer write_smart +title: Test Document / 测试文档 +content: This is a test document. / 这是一个测试文档内容 +``` + +**Step 2 / 第2步: Get OpenID / 获取 OpenID** +If not configured, follow the guide: +如果未配置,会显示引导: +1. Login / 登录 https://open.feishu.cn +2. Go to / 进入 Application → Permission Management / 应用 → 权限管理 → Search / 搜索 `im:message` +3. Click / 点击【API】Send Message / 发送消息 → Go to API Debug Console / 前往API调试台 +4. Click / 点击"Quick Copy open_id" / 快速复制 open_id", select your account / 选择你的账号, copy / 复制 + +**Step 3 / 第3步: Configure and Enable Permissions / 配置并开通权限** +``` +/feishu-smart-doc-writer configure +openid: ou_your_openid / ou_你的OpenID +permission_checked: true +``` + +Then go to Permission Management / 然后到权限管理: +1. Search / 搜索 `docs:permission.member:transfer` +2. Click / 点击"Enable / 开通" +3. **Important / 重要**: Click / 点击"Publish / 发布" button to publish new version / 按钮发布新版本 + +After setup, future document creation will automatically: +配置完成后,以后创建文档会自动: +- ✅ Chunk write content / 分块写入内容 +- ✅ Transfer ownership to you / 转移所有权给你 +- ✅ Update local index / 更新本地索引 + +--- + +## 📊 Index Management / 索引管理 + +### Auto Index Workflow / 自动索引流程 +``` +write_smart creates document / 创建文档 + ↓ +Write content (auto-chunk) / 写入内容(自动分块) + ↓ +Transfer ownership / 转移所有权 + ↓ +Auto update index → memory/feishu-docs-index.md / 自动更新索引 + ↓ +Done! / 完成! +``` + +### Auto-categorization Tags / 自动分类标签 +Auto-identified based on content / 根据内容自动识别: +- **AI Tech / AI技术** - AI, artificial intelligence / 人工智能, model / 模型, GPT, LLM +- **OpenClaw** - OpenClaw, skill, agent +- **Feishu Docs / 飞书文档** - Feishu / 飞书, document / 文档, feishu +- **E-commerce / 电商** - e-commerce / 电商, TikTok, Alibaba / 阿里巴巴 +- **Health & Sports / 健康运动** - Garmin, Strava, cycling / 骑行, health / 健康 +- **Daily Archive / 每日归档** - conversation / 对话, archive / 归档, chat history / 聊天记录 + +### Index File Location / 索引文件位置 +`memory/feishu-docs-index.md` + +Format / 格式: Markdown table with / Markdown 表格,包含 index / 序号, name / 名称, type / 类型, link / 链接, summary / 摘要, status / 状态, tags / 标签, owner / 所有者 + +--- + +## 🔍 Usage Examples / 使用示例 + +### Example 1 / 示例1: Create Tech Document / 创建技术文档 +``` +/feishu-smart-doc-writer write_smart +title: AI Tech Research Report / AI技术调研报告 +content: # AI Overview / AI技术概述\n\nAI is... / 人工智能(AI)是... +``` + +Result / 结果: +- Document created successfully / 文档创建成功 +- Auto-tagged "AI Tech / AI技术" / 自动打上"AI技术"标签 +- Index updated / 索引已更新 + +### Example 2 / 示例2: Search Documents / 搜索文档 +``` +/feishu-smart-doc-writer search_docs +keyword: AI Tech / AI技术 +``` + +### Example 3 / 示例3: List All Tech Documents / 列出所有技术文档 +``` +/feishu-smart-doc-writer list_docs +tag: AI Tech / AI技术 +``` + +--- + +## ⚙️ Configuration / 配置说明 + +### User Config File / 用户配置文件 +Location / 位置: `skills/feishu-smart-doc-writer/user_config.json` + +```json +{ + "owner_openid": "ou_5b921cba0fd6e7c885276a02d730ec19", + "permission_noted": true, + "first_time": false +} +``` + +### Required Permissions / 必需权限 +- `docx:document:create` - Create document / 创建文档 +- `docx:document:write` - Write content / 写入内容 +- `docs:permission.member:transfer` - Transfer ownership ⚠️ Critical / 转移所有权 ⚠️ 关键权限 + +--- + +## 📝 Version History / 版本历史 + +### v1.4.1 (2026-02-23) +- ✅ Fixed description inconsistency between skill.json and package.json / 修复 skill.json 和 package.json 描述不一致问题 +- ✅ Unified all file versions to v1.4.1 / 统一所有文件版本号为 v1.4.1 +- ✅ Verified all 7 tools properly declared / 确认所有 7 个工具正确声明 + +### v1.4.0 (2026-02-23) +- ✅ Added auto index management (index_manager.py) / 新增自动索引管理(index_manager.py) +- ✅ Added search_docs tool (search local index) / 新增 search_docs 工具(搜索本地索引) +- ✅ Added list_docs tool (list documents) / 新增 list_docs 工具(列出文档) +- ✅ Smart auto-categorization tags / 智能自动分类标签 +- ✅ Fixed ownership transfer (independent API calls, no ctx dependency) / 修复所有权转移(独立 API 调用,不依赖 ctx) + +### v1.2.0 +- ✅ Auto-chunk writing / 自动分块写入 +- ✅ Auto ownership transfer / 自动转移所有权 +- ✅ First-time user guide / 首次使用引导 + +### v1.1.0 +- ✅ Basic document creation and append / 基础文档创建和追加 + +--- + +## 🔧 Troubleshooting / 故障排除 + +### "open_id is not exist" Error / 错误 +**Cause / 原因**: Used user_id instead of openid / 使用了 user_id 而不是 openid +**Solution / 解决**: Use openid starting with `ou_` / 使用以 `ou_` 开头的 openid + +### "Permission Denied" Error / "权限不足" 错误 +**Cause / 原因**: `docs:permission.member:transfer` not enabled or app not published / 未开通权限,或未发布应用 +**Solution / 解决**: +1. Permission Management → Search `docs:permission.member:transfer` → Enable / 权限管理 → 搜索 → 开通 +2. Click "Publish" button to publish new version (Critical!) / 点击"发布"按钮(关键!) + +### Index Not Updated / 索引未更新 +**Check / 检查**: +1. Check if `memory/feishu-docs-index.md` exists / 查看文件是否存在 +2. Check `index_updated` field in write_smart return / 检查返回字段 +3. Check error logs / 查看错误日志 + +--- + +## 📞 Support / 支持 + +If issues, please check / 如有问题,请检查: +1. OpenID format correct (starts with ou_) / 格式是否正确(ou_ 开头) +2. Permissions enabled and published / 权限是否已开通并发布 +3. Index file path correct / 索引文件路径是否正确 diff --git a/skills/feishu-smart-doc-writer/__init__.py b/skills/feishu-smart-doc-writer/__init__.py new file mode 100644 index 0000000..23050d9 --- /dev/null +++ b/skills/feishu-smart-doc-writer/__init__.py @@ -0,0 +1,486 @@ +#!/usr/bin/env python3 +""" +Feishu Smart Doc Writer +飞书智能文档写入器 - 自动分段、分批写入 +支持首次使用自动引导配置 + +核心功能: +1. 智能分块写入 - 解决飞书API字数限制导致的空白文档 +2. 自动转移所有权 - 创建文档后自动转移给用户 +3. 首次使用引导 - 自动询问OpenID并配置 +""" + +import json +import os +from typing import Dict, Optional +from dataclasses import dataclass, asdict + +# 配置文件路径 +CONFIG_PATH = os.path.expanduser("~/.openclaw/workspace/skills/feishu-smart-doc-writer/user_config.json") + +@dataclass +class UserConfig: + """用户配置""" + owner_openid: str = "" + permission_noted: bool = False # 用户是否已确认权限 + first_time: bool = True # 是否首次使用 + + def save(self): + """保存配置""" + try: + os.makedirs(os.path.dirname(CONFIG_PATH), exist_ok=True) + with open(CONFIG_PATH, 'w', encoding='utf-8') as f: + json.dump(asdict(self), f, ensure_ascii=False, indent=2) + return True + except Exception as e: + print(f"保存配置失败: {e}") + return False + + @classmethod + def load(cls) -> 'UserConfig': + """加载配置""" + try: + if os.path.exists(CONFIG_PATH): + with open(CONFIG_PATH, 'r', encoding='utf-8') as f: + data = json.load(f) + return cls(**data) + except Exception as e: + print(f"加载配置失败: {e}") + return cls() + + +# 引导消息模板 +FIRST_TIME_GUIDE = """👋 **欢迎使用 Feishu Smart Doc Writer!** + +本 Skill 可以帮助你: +✅ **智能分块写入** - 解决长文档写入时因API限制导致的空白问题 +✅ **自动转移所有权** - 创建文档后自动转移给你,拥有完全控制权 + +--- + +## 🔧 首次使用配置 + +### 第1步:获取你的 OpenID + +**详细步骤(精确路径):** + +1. **登录飞书开放平台** + - 网址:https://open.feishu.cn + +2. **进入权限管理并前往调试台** + - 进入你的**相关应用** + - 点击 **"权限管理"** + - 搜索权限:`im:message` + - 鼠标移动到 **"相关API事件"** + - 选择:**【API】发送消息** + - 点击右下角:**"前往API调试台"** + +3. **找到 "快速复制 open_id"** + - 在页面中找到 **蓝色文字** "快速复制 open_id" + - 点击这个链接 + +4. **选择用户并复制** + - 在弹出的选择框中,**选择你的账号** + - 点击 **"复制"** 按钮 + - 得到格式如:`ou_5b921cba0fd6e7c885276a02d730ec19` + +💡 **提示**:OpenID 是以 `ou_` 开头的一串字符,不是数字ID + +--- + +### 第2步:开通并发布权限 + +⚠️ **重要:需要开通权限并发布应用新版本** + +**开通权限步骤:** + +1. **进入权限管理** + - 登录 https://open.feishu.cn + - 进入你的应用 + - 点击左侧菜单 **"权限管理"** + +2. **搜索并开通权限** + - 在搜索框输入:`docs:permission.member:transfer` + - 找到权限 **"转移云文档的所有权"** + - 点击 **"开通"** 按钮 + +3. **发布新版本(关键!)** + - 开通后,点击页面右上角的 **"发布"** 按钮 + - 等待发布完成(显示"已发布"状态) + - ⚠️ **不发布的话,权限不会生效!** + +--- + +## 💬 请回复配置信息 + +请按以下格式回复: + +``` +配置OpenID:ou_你的OpenID +权限已开通并发布:是 +``` + +例如: +``` +配置OpenID:ou_5b921cba0fd6e7c885276a02d730ec19 +权限已开通并发布:是 +``` + +配置完成后,本 Skill 将自动保存配置,之后创建文档会自动转移所有权给你! +""" + + +async def write_smart(ctx, args: dict) -> dict: + """ + 智能创建飞书文档(自动分块 + 自动转移所有权) + + 首次使用时会自动引导配置。 + + Args: + ctx: OpenClaw 上下文 + args: 包含 title, content, folder_token, chunk_size, show_progress + + Returns: + {"doc_url": "...", "doc_token": "...", "chunks_count": N, "owner_transferred": True/False} + """ + # 加载用户配置 + config = UserConfig.load() + + # 首次使用或未完成配置,显示引导 + if config.first_time or not config.owner_openid: + return { + "doc_url": None, + "doc_token": None, + "chunks_count": 0, + "owner_transferred": False, + "need_config": True, + "message": FIRST_TIME_GUIDE + } + + # 已配置,正常执行 + title = args.get("title") + content = args.get("content", "") + folder_token = args.get("folder_token") + chunk_size = args.get("chunk_size", 2000) + show_progress = args.get("show_progress", True) + + if not title: + raise ValueError("必须提供 title 参数") + + from .feishu_smart_doc_writer import FeishuDocWriter, ChunkConfig + + chunk_config = ChunkConfig( + chunk_size=chunk_size, + show_progress=show_progress + ) + writer = FeishuDocWriter(ctx, chunk_config) + + try: + # 使用配置的 owner_openid 自动转移 + result = await writer.write_document_with_transfer( + title=title, + content=content, + folder_token=folder_token, + owner_openid=config.owner_openid + ) + + transfer_msg = ",所有权已转移" if result.get("owner_transferred") else "" + + return { + "doc_url": result["doc_url"], + "doc_token": result["doc_token"], + "chunks_count": result["chunks_count"], + "owner_transferred": result["owner_transferred"], + "need_config": False, + "message": f"✅ 文档创建成功,共分 {result['chunks_count']} 块写入{transfer_msg}" + } + except Exception as e: + return { + "doc_url": None, + "doc_token": None, + "chunks_count": 0, + "owner_transferred": False, + "need_config": False, + "message": f"❌ 创建失败: {e}" + } + + +async def configure(ctx, args: dict) -> dict: + """ + 配置 Skill + + 用户首次使用时,通过此工具配置 OpenID。 + + Args: + ctx: OpenClaw 上下文 + args: 包含 openid, permission_checked + + Returns: + {"success": True/False, "message": "..."} + """ + openid = args.get("openid", "").strip() + permission_checked = args.get("permission_checked", False) + + # 验证 OpenID 格式 + if not openid: + return { + "success": False, + "message": "❌ 请提供 OpenID" + } + + if not openid.startswith("ou_"): + return { + "success": False, + "message": "❌ OpenID 格式错误,应以 'ou_' 开头,请检查" + } + + # 保存配置 + config = UserConfig() + config.owner_openid = openid + config.permission_noted = permission_checked + config.first_time = False + + if config.save(): + return { + "success": True, + "openid": openid, + "message": f"✅ 配置成功!\n\n你的 OpenID:{openid}\n\n配置已保存,现在可以使用 write_smart 创建文档,所有权会自动转移给你。" + } + else: + return { + "success": False, + "message": "❌ 配置保存失败" + } + + +async def append_smart(ctx, args: dict) -> dict: + """ + 智能追加内容到飞书文档(自动分块) + + Args: + ctx: OpenClaw 上下文 + args: 包含 doc_url, content, chunk_size, show_progress + + Returns: + {"success": True/False, "chunks_count": N} + """ + doc_url = args.get("doc_url") + content = args.get("content", "") + chunk_size = args.get("chunk_size", 2000) + show_progress = args.get("show_progress", True) + + if not doc_url: + raise ValueError("必须提供 doc_url 参数") + + from .feishu_smart_doc_writer import FeishuDocWriter, ChunkConfig, ContentChunker + + config = ChunkConfig( + chunk_size=chunk_size, + show_progress=show_progress + ) + writer = FeishuDocWriter(ctx, config) + + try: + success = await writer.append_to_document(doc_url, content) + + # 计算分块数 + chunks = ContentChunker(config).chunk_content(content) + + return { + "success": success, + "chunks_count": len(chunks), + "message": f"{'✅' if success else '❌'} 追加 {'成功' if success else '失败'},共分 {len(chunks)} 块" + } + except Exception as e: + return { + "success": False, + "chunks_count": 0, + "message": f"❌ 追加失败: {e}" + } + + +async def transfer_ownership(ctx, args: dict) -> dict: + """ + 转移文档所有权 + + Args: + ctx: OpenClaw 上下文 + args: 包含 doc_url, owner_openid + + Returns: + {"success": True/False, "message": "..."} + """ + doc_url = args.get("doc_url") + owner_openid = args.get("owner_openid") + + if not doc_url or not owner_openid: + raise ValueError("必须提供 doc_url 和 owner_openid 参数") + + from .feishu_smart_doc_writer import FeishuDocWriter, ChunkConfig + + config = ChunkConfig(show_progress=False) + writer = FeishuDocWriter(ctx, config) + + try: + success = await writer.transfer_ownership(doc_url, owner_openid) + + return { + "success": success, + "message": f"{'✅' if success else '❌'} 所有权转移{'成功' if success else '失败'}" + } + except Exception as e: + return { + "success": False, + "message": f"❌ 转移失败: {e}" + } + + +async def get_config_status(ctx, args: dict) -> dict: + """ + 获取当前配置状态 + + Returns: + {"configured": True/False, "openid": "...", "message": "..."} + """ + config = UserConfig.load() + + if config.owner_openid: + return { + "configured": True, + "openid": config.owner_openid, + "first_time": config.first_time, + "message": f"✅ 已配置\nOpenID: {config.owner_openid}" + } + else: + return { + "configured": False, + "openid": None, + "first_time": config.first_time, + "message": "⚠️ 未配置\n请使用 configure 工具进行配置" + } + + +async def search_docs(ctx, args: dict) -> dict: + """ + 搜索本地索引中的文档 + + Args: + ctx: OpenClaw 上下文 + args: 包含 keyword, search_in(可选) + + Returns: + {"results": [...], "count": N, "message": "..."} + """ + keyword = args.get("keyword", "").strip() + search_in = args.get("search_in", ["name", "summary", "tags"]) + + if not keyword: + return { + "results": [], + "count": 0, + "message": "❌ 请提供搜索关键词" + } + + try: + from .index_manager import IndexManager + + manager = IndexManager() + results = manager.search_docs(keyword, search_in) + + # 格式化结果 + formatted_results = [] + for doc in results: + formatted_results.append({ + "name": doc.get("name", ""), + "type": doc.get("type", ""), + "link": doc.get("link", ""), + "summary": doc.get("summary", ""), + "status": doc.get("status", ""), + "tags": doc.get("tags", ""), + "updated": doc.get("updated", "") + }) + + return { + "results": formatted_results, + "count": len(formatted_results), + "message": f"✅ 找到 {len(formatted_results)} 个结果" if formatted_results else f"⚠️ 未找到包含 '{keyword}' 的文档" + } + + except Exception as e: + return { + "results": [], + "count": 0, + "message": f"❌ 搜索失败: {e}" + } + + +async def list_docs(ctx, args: dict) -> dict: + """ + 列出所有文档(支持筛选) + + Args: + ctx: OpenClaw 上下文 + args: 包含 tag(可选), status(可选), limit(可选) + + Returns: + {"results": [...], "count": N, "message": "..."} + """ + tag = args.get("tag") + status = args.get("status") + limit = args.get("limit", 50) + + try: + from .index_manager import IndexManager + + manager = IndexManager() + results = manager.list_docs(tag=tag, status=status, limit=limit) + + # 格式化结果 + formatted_results = [] + for doc in results: + formatted_results.append({ + "name": doc.get("name", ""), + "type": doc.get("type", ""), + "link": doc.get("link", ""), + "summary": doc.get("summary", ""), + "status": doc.get("status", ""), + "tags": doc.get("tags", ""), + "updated": doc.get("updated", "") + }) + + # 构建消息 + filter_desc = [] + if tag: + filter_desc.append(f"标签 '{tag}'") + if status: + filter_desc.append(f"状态 '{status}'") + + filter_text = ",".join(filter_desc) if filter_desc else "全部" + + return { + "results": formatted_results, + "count": len(formatted_results), + "message": f"✅ {filter_text}文档共 {len(formatted_results)} 个" + } + + except Exception as e: + return { + "results": [], + "count": 0, + "message": f"❌ 列出文档失败: {e}" + } + + +# 版本信息 +__version__ = "1.3.0" +__all__ = [ + "write_smart", + "append_smart", + "transfer_ownership", + "configure", + "get_config_status", + "search_docs", + "list_docs", + "UserConfig", + "FIRST_TIME_GUIDE" +] \ No newline at end of file diff --git a/skills/feishu-smart-doc-writer/__pycache__/feishu_smart_doc_writer.cpython-311.pyc b/skills/feishu-smart-doc-writer/__pycache__/feishu_smart_doc_writer.cpython-311.pyc new file mode 100644 index 0000000..ccda2be Binary files /dev/null and b/skills/feishu-smart-doc-writer/__pycache__/feishu_smart_doc_writer.cpython-311.pyc differ diff --git a/skills/feishu-smart-doc-writer/__pycache__/index_manager.cpython-311.pyc b/skills/feishu-smart-doc-writer/__pycache__/index_manager.cpython-311.pyc new file mode 100644 index 0000000..8b9f7ad Binary files /dev/null and b/skills/feishu-smart-doc-writer/__pycache__/index_manager.cpython-311.pyc differ diff --git a/skills/feishu-smart-doc-writer/_meta.json b/skills/feishu-smart-doc-writer/_meta.json new file mode 100644 index 0000000..5b6d6db --- /dev/null +++ b/skills/feishu-smart-doc-writer/_meta.json @@ -0,0 +1,6 @@ +{ + "ownerId": "kn75sh5zhpf0spta18sqc7bd4s81dvr9", + "slug": "feishu-smart-doc-writer", + "version": "1.4.1", + "publishedAt": 1771834474198 +} \ No newline at end of file diff --git a/skills/feishu-smart-doc-writer/config.json b/skills/feishu-smart-doc-writer/config.json new file mode 100644 index 0000000..bee38ab --- /dev/null +++ b/skills/feishu-smart-doc-writer/config.json @@ -0,0 +1 @@ +{"openid": "ou_5b921cba0fd6e7c885276a02d730ec19", "permission_checked": true} diff --git a/skills/feishu-smart-doc-writer/examples.py b/skills/feishu-smart-doc-writer/examples.py new file mode 100644 index 0000000..dc197f3 --- /dev/null +++ b/skills/feishu-smart-doc-writer/examples.py @@ -0,0 +1,148 @@ +#!/usr/bin/env python3 +""" +使用示例 - 展示如何在 OpenClaw Skill 中使用 feishu_smart_doc_writer +""" + +# 示例 1: 在 Skill 中写入长文档 +async def example_write_long_doc(ctx): + """ + 在 OpenClaw Skill 中写入长文档 + + ctx 是 OpenClaw 提供的上下文对象 + """ + from feishu_smart_doc_writer import FeishuDocWriter, ChunkConfig + + # 创建写入器,传入 ctx + config = ChunkConfig( + chunk_size=2000, # 每块2000字符 + show_progress=True, # 显示进度 + max_retries=3 # 失败重试3次 + ) + writer = FeishuDocWriter(ctx, config) + + # 准备长内容 + long_content = """ +# 项目策划文档 + +## 一、项目背景 + +这是项目的详细背景介绍... + +## 二、技术方案 + +| 技术 | 说明 | 优势 | +|------|------|------| +| Python | 编程语言 | 生态丰富 | +| OpenClaw | 自动化框架 | 功能强大 | + +## 三、实施计划 + +1. 第一阶段... +2. 第二阶段... +3. 第三阶段... + +""" * 100 # 重复100次,生成约50000字符的长内容 + + # 写入文档 + doc_url = await writer.write_document( + title="项目策划 - 完整版", + content=long_content, + folder_token=None # 可选:指定文件夹 + ) + + print(f"✅ 文档创建成功: {doc_url}") + return doc_url + + +# 示例 2: 追加内容到现有文档 +async def example_append_to_doc(ctx, doc_url): + """ + 向已有文档追加内容 + """ + from feishu_smart_doc_writer import FeishuDocWriter + + writer = FeishuDocWriter(ctx) + + # 追加内容 + append_content = """ +## 四、补充说明 + +这是后来补充的内容... +""" * 50 + + success = await writer.append_to_document( + doc_url=doc_url, + content=append_content + ) + + if success: + print("✅ 内容追加成功") + else: + print("❌ 内容追加失败") + + return success + + +# 示例 3: 在 Skill 定义中使用 +SKILL_DEFINITION = { + "name": "my_skill", + "tools": [ + { + "name": "create_project_doc", + "description": "创建项目文档", + "handler": "create_project_doc_handler" + } + ] +} + +async def create_project_doc_handler(ctx, args): + """ + Skill 工具处理函数 + """ + from feishu_smart_doc_writer import FeishuDocWriter + + title = args.get("title", "未命名文档") + content = args.get("content", "") + + writer = FeishuDocWriter(ctx) + doc_url = await writer.write_document(title, content) + + return { + "doc_url": doc_url, + "message": "文档创建成功" + } + + +# 示例 4: 直接使用同步函数(简化版) +def example_sync_usage(ctx): + """ + 同步方式使用(在不需要async的环境中) + """ + from feishu_smart_doc_writer import write_document_sync + + doc_url = write_document_sync( + ctx=ctx, + title="同步创建的文档", + content="# 标题\n\n大量内容..." * 1000 + ) + + return doc_url + + +if __name__ == "__main__": + print("Feishu Smart Doc Writer 使用示例") + print("=" * 50) + print() + print("在 OpenClaw Skill 中使用:") + print() + print("1. 导入:") + print(" from feishu_smart_doc_writer import FeishuDocWriter") + print() + print("2. 创建写入器:") + print(" writer = FeishuDocWriter(ctx)") + print() + print("3. 写入长文档:") + print(" doc_url = await writer.write_document(title, content)") + print() + print("4. 追加内容:") + print(" await writer.append_to_document(doc_url, content)") diff --git a/skills/feishu-smart-doc-writer/feishu_smart_doc_writer.py b/skills/feishu-smart-doc-writer/feishu_smart_doc_writer.py new file mode 100644 index 0000000..f0c1071 --- /dev/null +++ b/skills/feishu-smart-doc-writer/feishu_smart_doc_writer.py @@ -0,0 +1,536 @@ +#!/usr/bin/env python3 +""" +Feishu Smart Doc Writer - 改进版 +自动分块写入 + 自动转移所有权 + 自动更新索引 +""" + +import re +import time +import json +import asyncio +from typing import List, Optional +from dataclasses import dataclass + +# 导入索引管理器 +try: + from .index_manager import IndexManager, add_doc_to_index +except ImportError: + from index_manager import IndexManager, add_doc_to_index + +@dataclass +class ChunkConfig: + """分块配置""" + chunk_size: int = 2000 # 每块最大字符数 + max_retries: int = 3 # 最大重试次数 + retry_delay: float = 1.0 # 重试间隔(秒) + show_progress: bool = True # 显示进度 + convert_tables: bool = True # 转换表格为文本 + + +class ContentChunker: + """内容分块器""" + + def __init__(self, config: ChunkConfig = None): + self.config = config or ChunkConfig() + + def chunk_content(self, content: str) -> List[str]: + """ + 将长内容分割成多个小块 + 策略:按段落分割,如果段落超过限制,按句子分割 + """ + chunks = [] + current_chunk = "" + + # 先处理表格 + if self.config.convert_tables: + content = self._convert_tables(content) + + # 按段落分割 + paragraphs = self._split_paragraphs(content) + + for para in paragraphs: + # 如果当前块加上新段落会超限 + if len(current_chunk) + len(para) > self.config.chunk_size: + # 保存当前块 + if current_chunk.strip(): + chunks.append(current_chunk.strip()) + + # 如果单个段落就超限,需要进一步分割 + if len(para) > self.config.chunk_size: + sub_chunks = self._split_large_paragraph(para) + chunks.extend(sub_chunks) + current_chunk = "" + else: + current_chunk = para + else: + current_chunk += "\n\n" + para if current_chunk else para + + # 保存最后一块 + if current_chunk.strip(): + chunks.append(current_chunk.strip()) + + return chunks + + def _convert_tables(self, content: str) -> str: + """将Markdown表格转换为文本列表""" + table_pattern = r'\|[^\n]+\|\n\|[-:| ]+\|\n((?:\|[^\n]+\|\n)+)' + + def convert_table(match): + table_text = match.group(0) + lines = table_text.strip().split('\n') + + # 提取表头 + header = [cell.strip() for cell in lines[0].split('|')[1:-1]] + + # 提取数据行 + result = ["【表格内容】"] + for line in lines[2:]: # 跳过表头和分隔线 + cells = [cell.strip() for cell in line.split('|')[1:-1]] + if cells and any(cells): # 确保不是空行 + row_text = ", ".join([f"{h}: {c}" for h, c in zip(header, cells)]) + result.append(f"- {row_text}") + + return "\n".join(result) + + return re.sub(table_pattern, convert_table, content) + + def _split_paragraphs(self, content: str) -> List[str]: + """按段落分割,保留标题结构""" + lines = content.split('\n') + paragraphs = [] + current_para = "" + + for line in lines: + stripped = line.strip() + + if not stripped: + if current_para.strip(): + paragraphs.append(current_para.strip()) + current_para = "" + continue + + # 如果是标题,单独成段 + if stripped.startswith('#'): + if current_para.strip(): + paragraphs.append(current_para.strip()) + current_para = "" + paragraphs.append(stripped) + else: + current_para += line + "\n" + + if current_para.strip(): + paragraphs.append(current_para.strip()) + + return paragraphs + + def _split_large_paragraph(self, para: str) -> List[str]: + """分割大段落(按句子)""" + chunks = [] + sentences = re.split(r'([。!?.\n])', para) + current = "" + + for i in range(0, len(sentences), 2): + sentence = sentences[i] + if i + 1 < len(sentences): + sentence += sentences[i + 1] # 加上标点 + + if len(current) + len(sentence) > self.config.chunk_size: + if current.strip(): + chunks.append(current.strip()) + current = sentence + else: + current += sentence + + if current.strip(): + chunks.append(current.strip()) + + return chunks + + +class FeishuDocWriter: + """ + 飞书文档智能写入器 + 使用 OpenClaw 官方工具调用方式 + """ + + def __init__(self, ctx=None, config: ChunkConfig = None): + """ + 初始化 + + Args: + ctx: OpenClaw 上下文对象(在 Skill 中传入) + config: 分块配置 + """ + self.ctx = ctx + self.config = config or ChunkConfig() + self.chunker = ContentChunker(config) + + async def write_document(self, title: str, content: str, folder_token: str = None) -> str: + """ + 创建新文档并写入内容(自动分块) + + Args: + title: 文档标题 + content: 文档内容(支持长内容,自动分块) + folder_token: 可选的文件夹token + + Returns: + 文档URL + """ + if not self.ctx: + raise ValueError("需要提供 OpenClaw 上下文对象 (ctx)") + + # 第一步:创建空文档(只传标题) + doc_token = await self._create_empty_doc(title, folder_token) + doc_url = f"https://feishu.cn/docx/{doc_token}" + + if self.config.show_progress: + print(f"✅ 文档创建成功: {doc_url}") + + # 第二步:分批追加内容 + success = await self._write_content_in_chunks(doc_token, content) + + if not success: + raise Exception("写入内容失败") + + return doc_url + + async def append_to_document(self, doc_url: str, content: str) -> bool: + """ + 追加内容到现有文档(自动分块) + + Args: + doc_url: 文档URL + content: 要追加的内容 + + Returns: + 是否成功 + """ + if not self.ctx: + raise ValueError("需要提供 OpenClaw 上下文对象 (ctx)") + + doc_token = self._extract_token_from_url(doc_url) + return await self._write_content_in_chunks(doc_token, content) + + async def _create_empty_doc(self, title: str, folder_token: str = None) -> str: + """创建空文档,只传标题""" + try: + # 使用 OpenClaw 官方工具调用方式 + result = await self.ctx.invoke_tool("feishu_doc.create", { + "title": title, + "folder_token": folder_token + }) + + # 提取 doc_token + if isinstance(result, dict): + doc_token = result.get("document_id") or result.get("doc_token") + if doc_token: + return doc_token + + # 如果是字符串,尝试提取 + if isinstance(result, str): + import re + match = re.search(r'docx/([a-zA-Z0-9]+)', result) + if match: + return match.group(1) + return result + + raise Exception(f"无法解析文档token: {result}") + + except Exception as e: + raise Exception(f"创建文档失败: {e}") + + async def _write_content_in_chunks(self, doc_token: str, content: str) -> bool: + """分批写入内容""" + chunks = self.chunker.chunk_content(content) + + if self.config.show_progress: + print(f"📝 内容已分割为 {len(chunks)} 块,开始写入...") + + for i, chunk in enumerate(chunks, 1): + if self.config.show_progress: + print(f" 写入第 {i}/{len(chunks)} 块 ({len(chunk)} 字符)...") + + success = await self._append_chunk_with_retry(doc_token, chunk) + + if not success: + print(f"❌ 第 {i} 块写入失败") + return False + + # 添加小延迟,避免API限流 + if i < len(chunks): + await asyncio.sleep(0.5) + + if self.config.show_progress: + print(f"✅ 全部 {len(chunks)} 块写入完成") + + return True + + async def _append_chunk_with_retry(self, doc_token: str, chunk: str) -> bool: + """带重试的追加内容""" + for attempt in range(self.config.max_retries): + try: + return await self._append_chunk(doc_token, chunk) + except Exception as e: + if self.config.show_progress: + print(f" 尝试 {attempt + 1}/{self.config.max_retries} 失败: {e}") + if attempt < self.config.max_retries - 1: + await asyncio.sleep(self.config.retry_delay * (attempt + 1)) + else: + return False + return False + + async def _append_chunk(self, doc_token: str, chunk: str) -> bool: + """追加单块内容""" + try: + # 使用 OpenClaw 官方工具调用方式 + await self.ctx.invoke_tool("feishu_doc.append", { + "doc_token": doc_token, + "content": chunk + }) + return True + except Exception as e: + raise Exception(f"API调用失败: {e}") + + def _extract_token_from_url(self, url: str) -> str: + """从URL中提取doc_token""" + import re + match = re.search(r'docx/([a-zA-Z0-9]+)', url) + if match: + return match.group(1) + raise ValueError(f"无法从URL提取token: {url}") + + async def _get_tenant_access_token(self) -> str: + """获取飞书 tenant_access_token""" + import aiohttp + import json + import os + + # 尝试从 OpenClaw 配置读取 App ID 和 Secret + app_id, app_secret = None, None + + # 方法1: 尝试从环境变量读取 + app_id = os.environ.get("FEISHU_APP_ID") + app_secret = os.environ.get("FEISHU_APP_SECRET") + + # 方法2: 尝试从 OpenClaw 配置文件读取 + if not app_id or not app_secret: + try: + config_paths = [ + os.path.expanduser("~/.openclaw/openclaw.json"), + os.path.expanduser("~/.openclaw/config.json"), + ] + for config_path in config_paths: + if os.path.exists(config_path): + with open(config_path, 'r') as f: + config = json.load(f) + feishu_config = config.get("channels", {}).get("feishu", {}) + app_id = feishu_config.get("appId") + app_secret = feishu_config.get("appSecret") + if app_id and app_secret: + break + except Exception: + pass + + if not app_id or not app_secret: + return "" + + # 调用飞书 API 获取 token + url = "https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal" + payload = { + "app_id": app_id, + "app_secret": app_secret + } + + try: + async with aiohttp.ClientSession() as session: + async with session.post(url, json=payload) as resp: + result = await resp.json() + if result.get("code") == 0: + return result.get("tenant_access_token", "") + except Exception: + pass + + return "" + + async def transfer_ownership(self, doc_url: str, owner_openid: str) -> bool: + """ + 转移文档所有权 - 直接调用飞书 API + + API端点: POST /drive/v1/permissions/{token}/members/transfer_owner?type=docx + + Args: + doc_url: 文档URL + owner_openid: 新所有者的openid (例如: ou_xxxxxxxx) + + Returns: + 是否成功 + """ + import aiohttp + import json + + doc_token = self._extract_token_from_url(doc_url) + + # 获取 tenant_access_token + token = await self._get_tenant_access_token() + if not token: + if self.config.show_progress: + print(f"⚠️ 无法获取 tenant_access_token") + return False + + # 调用飞书 API 转移所有权 + url = f"https://open.feishu.cn/open-apis/drive/v1/permissions/{doc_token}/members/transfer_owner?type=docx" + headers = { + "Authorization": f"Bearer {token}", + "Content-Type": "application/json" + } + payload = { + "member_type": "openid", + "member_id": owner_openid + } + + try: + async with aiohttp.ClientSession() as session: + async with session.post(url, headers=headers, json=payload) as resp: + result = await resp.json() + + if result.get("code") == 0: + if self.config.show_progress: + print(f"✅ 文档所有权已转移给 {owner_openid}") + return True + else: + error_msg = result.get("msg", "未知错误") + if self.config.show_progress: + print(f"⚠️ 所有权转移失败: {error_msg}") + return False + + except Exception as e: + if self.config.show_progress: + print(f"⚠️ 所有权转移失败: {e}") + return False + + async def write_document_with_transfer( + self, + title: str, + content: str, + folder_token: str = None, + owner_openid: str = None + ) -> dict: + """ + 创建文档并写入内容,完成后自动转移所有权并更新本地索引 + + Args: + title: 文档标题 + content: 文档内容 + folder_token: 可选的文件夹token + owner_openid: 新所有者的openid,如果提供则自动转移所有权 + + Returns: + { + "doc_url": "...", + "doc_token": "...", + "chunks_count": N, + "owner_transferred": True/False, + "index_updated": True/False + } + """ + # 1. 创建并写入文档 + doc_url = await self.write_document(title, content, folder_token) + + # 2. 提取 doc_token + doc_token = self._extract_token_from_url(doc_url) + + # 3. 计算分块数 + chunks = self.chunker.chunk_content(content) + + # 4. 转移所有权(如果提供了 owner_openid) + owner_transferred = False + if owner_openid: + owner_transferred = await self.transfer_ownership(doc_url, owner_openid) + + # 5. 【关键】自动更新本地索引 + index_updated = False + try: + # 生成摘要(取前100字) + summary = content[:100].replace('\n', ' ') + "..." if len(content) > 100 else content + + # 自动分类标签 + tags = self._auto_classify_content(content, title) + + # 更新索引 + index_updated = add_doc_to_index( + name=title, + url=doc_url, + token=doc_token, + summary=summary, + tags=tags, + owner=owner_openid or "" + ) + + if self.config.show_progress and index_updated: + print(f"✅ 文档索引已更新") + elif self.config.show_progress: + print(f"⚠️ 文档索引更新失败(不影响文档创建)") + + except Exception as e: + if self.config.show_progress: + print(f"⚠️ 索引更新失败: {e}(不影响文档创建)") + + return { + "doc_url": doc_url, + "doc_token": doc_token, + "chunks_count": len(chunks), + "owner_transferred": owner_transferred, + "index_updated": index_updated + } + + def _auto_classify_content(self, content: str, title: str) -> List[str]: + """根据内容自动分类""" + tags = [] + text = (title + " " + content).lower() + + # 关键词映射到标签 + if any(k in text for k in ["ai", "人工智能", "模型", "gpt", "llm"]): + tags.append("AI技术") + if any(k in text for k in ["openclaw", "skill", "agent"]): + tags.append("OpenClaw") + if any(k in text for k in ["飞书", "文档", "feishu", "docx"]): + tags.append("飞书文档") + if any(k in text for k in ["电商", "tiktok", "alibaba", "玩具"]): + tags.append("电商") + if any(k in text for k in ["garmin", "strava", "骑行", "健康", "运动"]): + tags.append("健康运动") + if any(k in text for k in ["对话", "归档", "聊天记录"]): + tags.append("每日归档") + + # 如果没有匹配到特定标签,添加通用标签 + if not tags: + tags.append("其他") + + return tags + + +# 同步包装函数(方便非异步环境使用) +def write_document_sync(ctx, title: str, content: str, folder_token: str = None, config: ChunkConfig = None) -> str: + """同步方式写入文档""" + writer = FeishuDocWriter(ctx, config) + return asyncio.run(writer.write_document(title, content, folder_token)) + + +def write_document_with_transfer_sync( + ctx, + title: str, + content: str, + folder_token: str = None, + owner_openid: str = None, + config: ChunkConfig = None +) -> dict: + """同步方式写入文档并转移所有权""" + writer = FeishuDocWriter(ctx, config) + return asyncio.run(writer.write_document_with_transfer(title, content, folder_token, owner_openid)) + + +def append_to_document_sync(ctx, doc_url: str, content: str, config: ChunkConfig = None) -> bool: + """同步方式追加文档""" + writer = FeishuDocWriter(ctx, config) + return asyncio.run(writer.append_to_document(doc_url, content)) diff --git a/skills/feishu-smart-doc-writer/index_manager.py b/skills/feishu-smart-doc-writer/index_manager.py new file mode 100644 index 0000000..78fe8f0 --- /dev/null +++ b/skills/feishu-smart-doc-writer/index_manager.py @@ -0,0 +1,349 @@ +""" +Feishu 文档索引管理器 +负责管理 memory/feishu-docs-index.md 文件 +""" + +import os +import re +import json +from datetime import datetime +from typing import List, Dict, Optional, Tuple + + +class IndexManager: + """飞书文档索引管理器""" + + DEFAULT_INDEX_PATH = os.path.expanduser("~/.openclaw/workspace/memory/feishu-docs-index.md") + + def __init__(self, index_path: str = None): + self.index_path = index_path or self.DEFAULT_INDEX_PATH + self._ensure_index_exists() + + def _ensure_index_exists(self): + """确保索引文件存在""" + if not os.path.exists(self.index_path): + os.makedirs(os.path.dirname(self.index_path), exist_ok=True) + self._create_empty_index() + + def _create_empty_index(self): + """创建空索引文件""" + content = """# 飞书云文档索引 + +**用途:** 快速定位和管理所有飞书云文档 + +--- + +## 📊 文档列表 + +| 序号 | 文档名 | 类型 | 链接 | 内容摘要 | 状态 | 最后更新 | 标签 | 所有者 | +|------|--------|------|------|----------|------|----------|------|--------| + +--- + +## 📂 按类型分类 + +### 项目管理 + +### 技术文档 + +### 每日归档 + +### 更新记录 + +### 数据分析 + +--- + +## 🔍 快速查找 + +*暂无关键词索引* + +--- + +## 📝 使用说明 + +**添加新文档时:** +1. 复制表格中的一行 +2. 填写所有字段 +3. 更新分类索引 + +**查找文档时:** +1. 先搜索本文档中的关键词 +2. 找到对应链接 +3. 用 `feishu_doc` 工具读取内容 + +--- +*创建时间:{date}* +*最后更新:{date}* +""".format(date=datetime.now().strftime("%Y-%m-%d")) + + with open(self.index_path, 'w', encoding='utf-8') as f: + f.write(content) + + def add_or_update_doc(self, name: str, doc_type: str, url: str, token: str, + summary: str = "", status: str = "已完成", + tags: List[str] = None, owner: str = "") -> bool: + """ + 添加或更新文档到索引 + + Args: + name: 文档名称 + doc_type: 文档类型 (docx, sheet, bitable 等) + url: 文档链接 + token: 文档token + summary: 内容摘要 + status: 文档状态 + tags: 标签列表 + owner: 所有者 + + Returns: + 是否成功 + """ + try: + # 读取现有索引 + with open(self.index_path, 'r', encoding='utf-8') as f: + content = f.read() + + # 检查文档是否已存在(通过token判断) + existing_index = self._find_doc_index(content, token) + + # 获取当前序号 + if existing_index: + doc_index = existing_index + else: + doc_index = self._get_next_index(content) + + # 准备标签字符串 + tags_str = ", ".join(tags) if tags else "" + + # 准备表格行 + now = datetime.now().strftime("%Y-%m-%d") + new_row = f"| {doc_index} | {name} | {doc_type} | {url} | {summary} | {status} | {now} | {tags_str} | {owner} |" + + # 更新表格 + if existing_index: + # 更新现有行 + content = self._replace_table_row(content, token, new_row) + else: + # 添加新行 + content = self._insert_table_row(content, new_row) + + # 更新分类(如果新文档) + if not existing_index and tags: + content = self._update_categories(content, name, tags) + + # 更新关键词索引 + if not existing_index: + content = self._update_keywords(content, name, summary, tags) + + # 更新最后更新时间 + content = self._update_last_modified(content) + + # 写回文件 + with open(self.index_path, 'w', encoding='utf-8') as f: + f.write(content) + + return True + + except Exception as e: + print(f"更新索引失败: {e}") + return False + + def search_docs(self, keyword: str, search_in: List[str] = None) -> List[Dict]: + """ + 搜索文档 + + Args: + keyword: 搜索关键词 + search_in: 在哪些字段中搜索 (name, summary, tags) + + Returns: + 匹配的文档列表 + """ + if search_in is None: + search_in = ["name", "summary", "tags"] + + results = [] + docs = self._parse_table() + + keyword_lower = keyword.lower() + + for doc in docs: + match = False + if "name" in search_in and keyword_lower in doc.get("name", "").lower(): + match = True + if "summary" in search_in and keyword_lower in doc.get("summary", "").lower(): + match = True + if "tags" in search_in and keyword_lower in doc.get("tags", "").lower(): + match = True + + if match: + results.append(doc) + + return results + + def list_docs(self, tag: str = None, status: str = None, limit: int = None) -> List[Dict]: + """ + 列出文档 + + Args: + tag: 按标签筛选 + status: 按状态筛选 + limit: 限制数量 + + Returns: + 文档列表 + """ + docs = self._parse_table() + + # 筛选 + if tag: + docs = [d for d in docs if tag in d.get("tags", "")] + + if status: + docs = [d for d in docs if d.get("status") == status] + + # 限制数量 + if limit: + docs = docs[:limit] + + return docs + + def get_doc_by_token(self, token: str) -> Optional[Dict]: + """通过token获取文档信息""" + docs = self._parse_table() + for doc in docs: + if token in doc.get("link", ""): + return doc + return None + + def _parse_table(self) -> List[Dict]: + """解析索引表格""" + docs = [] + + try: + with open(self.index_path, 'r', encoding='utf-8') as f: + content = f.read() + + # 找到表格部分 + lines = content.split('\n') + in_table = False + + for line in lines: + if line.startswith('| 序号 '): + in_table = True + continue + if in_table and line.startswith('|---'): + continue + if in_table and line.startswith('|') and not line.startswith('|------'): + # 解析表格行 + parts = [p.strip() for p in line.split('|')[1:-1]] + if len(parts) >= 8: + # 兼容8列表格格式(序号、文档名、类型、链接、摘要、状态、更新时间、备注) + docs.append({ + "index": parts[0], + "name": parts[1], + "type": parts[2], + "link": parts[3], + "summary": parts[4], + "status": parts[5], + "updated": parts[6], + "tags": parts[7], # 使用"备注"列作为标签 + "owner": "" # 所有者信息暂时为空 + }) + + except Exception as e: + print(f"解析索引失败: {e}") + + return docs + + def _find_doc_index(self, content: str, token: str) -> Optional[str]: + """查找文档是否已存在,返回序号""" + pattern = r'\| (\d+) \| [^|]+ \| [^|]+ \| [^/]+/docx/' + re.escape(token) + r'[^|]* \|' + match = re.search(pattern, content) + if match: + return match.group(1) + return None + + def _get_next_index(self, content: str) -> int: + """获取下一个序号""" + pattern = r'\| (\d+) \|' + matches = re.findall(pattern, content) + if matches: + return max([int(m) for m in matches]) + 1 + return 1 + + def _replace_table_row(self, content: str, token: str, new_row: str) -> str: + """替换表格中的某一行""" + pattern = r'(\| \d+ \| [^|]+ \| [^|]+ \| [^/]+/docx/' + re.escape(token) + r'[^|]* \|[^\n]+)' + return re.sub(pattern, new_row, content) + + def _insert_table_row(self, content: str, new_row: str) -> str: + """插入新行到表格""" + # 在表格头部后插入 + lines = content.split('\n') + insert_index = -1 + + for i, line in enumerate(lines): + if line.startswith('| 序号 '): + insert_index = i + 2 # 跳过表头和分隔线 + break + + if insert_index > 0: + lines.insert(insert_index, new_row) + + return '\n'.join(lines) + + def _update_categories(self, content: str, name: str, tags: List[str]) -> str: + """更新分类列表""" + # 简单实现:在对应分类下添加文档名 + # 这里可以扩展更复杂的逻辑 + return content + + def _update_keywords(self, content: str, name: str, summary: str, tags: List[str]) -> str: + """更新关键词索引""" + # 提取关键词 + keywords = [] + if tags: + keywords.extend(tags) + + # 这里可以添加更智能的关键词提取 + # 暂时保持简单 + + return content + + def _update_last_modified(self, content: str) -> str: + """更新最后修改时间""" + now = datetime.now().strftime("%Y-%m-%d") + pattern = r'\*最后更新:[^*]+\*' + replacement = f'*最后更新:{now}*' + return re.sub(pattern, replacement, content) + + +# 便捷函数 +def add_doc_to_index(name: str, url: str, token: str, summary: str = "", + tags: List[str] = None, owner: str = "") -> bool: + """便捷函数:添加文档到索引""" + manager = IndexManager() + return manager.add_or_update_doc( + name=name, + doc_type="docx", + url=url, + token=token, + summary=summary, + status="已完成", + tags=tags, + owner=owner + ) + + +def search_docs(keyword: str) -> List[Dict]: + """便捷函数:搜索文档""" + manager = IndexManager() + return manager.search_docs(keyword) + + +def list_all_docs(tag: str = None) -> List[Dict]: + """便捷函数:列出所有文档""" + manager = IndexManager() + return manager.list_docs(tag=tag) \ No newline at end of file diff --git a/skills/feishu-smart-doc-writer/package.json b/skills/feishu-smart-doc-writer/package.json new file mode 100644 index 0000000..1059e5e --- /dev/null +++ b/skills/feishu-smart-doc-writer/package.json @@ -0,0 +1,50 @@ +{ + "name": "feishu-smart-doc-writer", + "version": "1.4.1", + "description": "Feishu/Lark Smart Document Writer v1.4.1 - 飞书智能文档写入器. Auto-chunk writing, auto ownership transfer, document index management with search/list. Config OpenID on first use.", + "author": "OpenClaw User", + "license": "MIT", + "tags": [ + "feishu", + "lark", + "飞书", + "document", + "docx", + "writer", + "chunk", + "smart", + "ownership-transfer", + "文档", + "写入" + ], + "homepage": "https://github.com/openclaw/openclaw", + "repository": { + "type": "git", + "url": "https://github.com/openclaw/openclaw" + }, + "keywords": [ + "feishu", + "lark", + "飞书", + "document", + "writer", + "chunk", + "split", + "api-limit", + "ownership-transfer", + "文档写入", + "长文档" + ], + "openclaw": { + "minVersion": "2026.2.0", + "tools": [ + "write_smart", + "append_smart", + "search_docs", + "list_docs", + "transfer_ownership", + "configure", + "get_config_status" + ] + } +} diff --git a/skills/feishu-smart-doc-writer/skill.json b/skills/feishu-smart-doc-writer/skill.json new file mode 100644 index 0000000..f06602c --- /dev/null +++ b/skills/feishu-smart-doc-writer/skill.json @@ -0,0 +1,193 @@ +{ + "name": "feishu-smart-doc-writer", + "version": "1.4.1", + "description": "Feishu/Lark Smart Document Writer v1.4.1 - 飞书智能文档写入器. Auto-chunk writing, auto ownership transfer, document index management with search/list. Config OpenID on first use.", + "author": "OpenClaw", + "license": "MIT", + "tools": [ + { + "name": "write_smart", + "description": "Smart create Feishu/Lark doc with auto-chunk writing and ownership transfer. Guides OpenID config on first use. 智能创建飞书文档,自动分块写入,自动转移所有权。首次使用时引导配置OpenID。", + "handler": "feishu_smart_doc_writer.write_smart", + "parameters": { + "type": "object", + "properties": { + "title": { + "type": "string", + "description": "Document title / 文档标题" + }, + "content": { + "type": "string", + "description": "Document content (long content auto-chunked) / 文档内容(支持长内容,会自动分块处理)" + }, + "folder_token": { + "type": "string", + "description": "Optional folder token / 可选的文件夹token" + }, + "chunk_size": { + "type": "integer", + "description": "Max chars per chunk, default 2000 / 每块最大字符数,默认2000", + "default": 2000 + }, + "show_progress": { + "type": "boolean", + "description": "Show progress / 是否显示写入进度", + "default": true + } + }, + "required": ["title", "content"] + }, + "returns": { + "type": "object", + "properties": { + "doc_url": {"type": "string"}, + "doc_token": {"type": "string"}, + "chunks_count": {"type": "integer"}, + "owner_transferred": {"type": "boolean"}, + "need_config": {"type": "boolean", "description": "Need config / 是否需要配置"}, + "message": {"type": "string"} + } + } + }, + { + "name": "configure", + "description": "Configure Skill. Provide OpenID and confirm permission on first use. 配置Skill。首次使用时提供OpenID并确认权限已开通。", + "handler": "feishu_smart_doc_writer.configure", + "parameters": { + "type": "object", + "properties": { + "openid": { + "type": "string", + "description": "Your Feishu/Lark OpenID (format: ou_xxxxxxxx) / 你的飞书OpenID(格式:ou_xxxxxxxx)" + }, + "permission_checked": { + "type": "boolean", + "description": "Confirmed docs:permission.member:transfer permission granted / 是否已确认开通docs:permission.member:transfer权限", + "default": false + } + }, + "required": ["openid"] + }, + "returns": { + "type": "object", + "properties": { + "success": {"type": "boolean"}, + "openid": {"type": "string"}, + "message": {"type": "string"} + } + } + }, + { + "name": "append_smart", + "description": "Smart append content to Feishu/Lark doc with auto-chunk. 智能追加内容到飞书文档,自动分块。", + "handler": "feishu_smart_doc_writer.append_smart", + "parameters": { + "type": "object", + "properties": { + "doc_url": {"type": "string"}, + "content": {"type": "string"}, + "chunk_size": {"type": "integer", "default": 2000}, + "show_progress": {"type": "boolean", "default": true} + }, + "required": ["doc_url", "content"] + }, + "returns": { + "type": "object", + "properties": { + "success": {"type": "boolean"}, + "chunks_count": {"type": "integer"}, + "message": {"type": "string"} + } + } + }, + { + "name": "transfer_ownership", + "description": "Transfer Feishu/Lark doc ownership. Requires docs:permission.member:transfer permission. 转移飞书文档所有权。需要docs:permission.member:transfer权限。", + "handler": "feishu_smart_doc_writer.transfer_ownership", + "parameters": { + "type": "object", + "properties": { + "doc_url": {"type": "string"}, + "owner_openid": {"type": "string"} + }, + "required": ["doc_url", "owner_openid"] + }, + "returns": { + "type": "object", + "properties": { + "success": {"type": "boolean"}, + "message": {"type": "string"} + } + } + }, + { + "name": "get_config_status", + "description": "Get current config status to check if OpenID is configured. 获取当前配置状态,查看是否已配置OpenID。", + "handler": "feishu_smart_doc_writer.get_config_status", + "parameters": {"type": "object", "properties": {}}, + "returns": { + "type": "object", + "properties": { + "configured": {"type": "boolean"}, + "openid": {"type": "string"}, + "first_time": {"type": "boolean"}, + "message": {"type": "string"} + } + } + }, + { + "name": "search_docs", + "description": "Search local document index by keywords. Searches in document name, summary, and tags. 搜索本地文档索引,支持关键词搜索。", + "handler": "index_manager.search_docs", + "parameters": { + "type": "object", + "properties": { + "keyword": { + "type": "string", + "description": "Search keyword / 搜索关键词" + } + }, + "required": ["keyword"] + }, + "returns": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": {"type": "string"}, + "link": {"type": "string"}, + "summary": {"type": "string"}, + "tags": {"type": "string"} + } + } + } + }, + { + "name": "list_docs", + "description": "List all Feishu documents from local index. Optionally filter by tag. 列出所有飞书文档,可按标签筛选。", + "handler": "index_manager.list_all_docs", + "parameters": { + "type": "object", + "properties": { + "tag": { + "type": "string", + "description": "Optional tag filter / 可选的标签筛选" + } + } + }, + "returns": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": {"type": "string"}, + "link": {"type": "string"}, + "summary": {"type": "string"}, + "tags": {"type": "string"} + } + } + } + } + ], + "dependencies": [] +} \ No newline at end of file diff --git a/skills/feishu-smart-doc-writer/user_config.json b/skills/feishu-smart-doc-writer/user_config.json new file mode 100644 index 0000000..95c6d72 --- /dev/null +++ b/skills/feishu-smart-doc-writer/user_config.json @@ -0,0 +1,5 @@ +{ + "owner_openid": "ou_5b921cba0fd6e7c885276a02d730ec19", + "permission_noted": true, + "first_time": false +} \ No newline at end of file diff --git a/skills/find-skills/SKILL.md b/skills/find-skills/SKILL.md new file mode 100644 index 0000000..c797184 --- /dev/null +++ b/skills/find-skills/SKILL.md @@ -0,0 +1,133 @@ +--- +name: find-skills +description: Helps users discover and install agent skills when they ask questions like "how do I do X", "find a skill for X", "is there a skill that can...", or express interest in extending capabilities. This skill should be used when the user is looking for functionality that might exist as an installable skill. +--- + +# Find Skills + +This skill helps you discover and install skills from the open agent skills ecosystem. + +## When to Use This Skill + +Use this skill when the user: + +- Asks "how do I do X" where X might be a common task with an existing skill +- Says "find a skill for X" or "is there a skill for X" +- Asks "can you do X" where X is a specialized capability +- Expresses interest in extending agent capabilities +- Wants to search for tools, templates, or workflows +- Mentions they wish they had help with a specific domain (design, testing, deployment, etc.) + +## What is the Skills CLI? + +The Skills CLI (`npx skills`) is the package manager for the open agent skills ecosystem. Skills are modular packages that extend agent capabilities with specialized knowledge, workflows, and tools. + +**Key commands:** + +- `npx skills find [query]` - Search for skills interactively or by keyword +- `npx skills add ` - Install a skill from GitHub or other sources +- `npx skills check` - Check for skill updates +- `npx skills update` - Update all installed skills + +**Browse skills at:** https://skills.sh/ + +## How to Help Users Find Skills + +### Step 1: Understand What They Need + +When a user asks for help with something, identify: + +1. The domain (e.g., React, testing, design, deployment) +2. The specific task (e.g., writing tests, creating animations, reviewing PRs) +3. Whether this is a common enough task that a skill likely exists + +### Step 2: Search for Skills + +Run the find command with a relevant query: + +```bash +npx skills find [query] +``` + +For example: + +- User asks "how do I make my React app faster?" → `npx skills find react performance` +- User asks "can you help me with PR reviews?" → `npx skills find pr review` +- User asks "I need to create a changelog" → `npx skills find changelog` + +The command will return results like: + +``` +Install with npx skills add + +vercel-labs/agent-skills@vercel-react-best-practices +└ https://skills.sh/vercel-labs/agent-skills/vercel-react-best-practices +``` + +### Step 3: Present Options to the User + +When you find relevant skills, present them to the user with: + +1. The skill name and what it does +2. The install command they can run +3. A link to learn more at skills.sh + +Example response: + +``` +I found a skill that might help! The "vercel-react-best-practices" skill provides +React and Next.js performance optimization guidelines from Vercel Engineering. + +To install it: +npx skills add vercel-labs/agent-skills@vercel-react-best-practices + +Learn more: https://skills.sh/vercel-labs/agent-skills/vercel-react-best-practices +``` + +### Step 4: Offer to Install + +If the user wants to proceed, you can install the skill for them: + +```bash +npx skills add -g -y +``` + +The `-g` flag installs globally (user-level) and `-y` skips confirmation prompts. + +## Common Skill Categories + +When searching, consider these common categories: + +| Category | Example Queries | +| --------------- | ---------------------------------------- | +| Web Development | react, nextjs, typescript, css, tailwind | +| Testing | testing, jest, playwright, e2e | +| DevOps | deploy, docker, kubernetes, ci-cd | +| Documentation | docs, readme, changelog, api-docs | +| Code Quality | review, lint, refactor, best-practices | +| Design | ui, ux, design-system, accessibility | +| Productivity | workflow, automation, git | + +## Tips for Effective Searches + +1. **Use specific keywords**: "react testing" is better than just "testing" +2. **Try alternative terms**: If "deploy" doesn't work, try "deployment" or "ci-cd" +3. **Check popular sources**: Many skills come from `vercel-labs/agent-skills` or `ComposioHQ/awesome-claude-skills` + +## When No Skills Are Found + +If no relevant skills exist: + +1. Acknowledge that no existing skill was found +2. Offer to help with the task directly using your general capabilities +3. Suggest the user could create their own skill with `npx skills init` + +Example: + +``` +I searched for skills related to "xyz" but didn't find any matches. +I can still help you with this task directly! Would you like me to proceed? + +If this is something you do often, you could create your own skill: +npx skills init my-xyz-skill +``` diff --git a/skills/find-skills/_meta.json b/skills/find-skills/_meta.json new file mode 100644 index 0000000..ee62219 --- /dev/null +++ b/skills/find-skills/_meta.json @@ -0,0 +1,6 @@ +{ + "ownerId": "kn77ajmmqw3cgnc3ay1x3e0ccd805hsw", + "slug": "find-skills", + "version": "0.1.0", + "publishedAt": 1769698710765 +} \ No newline at end of file diff --git a/skills/funasr-transcribe-skill/SKILL.md b/skills/funasr-transcribe-skill/SKILL.md new file mode 100644 index 0000000..2aba71a --- /dev/null +++ b/skills/funasr-transcribe-skill/SKILL.md @@ -0,0 +1,79 @@ +--- +name: funasr-transcribe +description: 本地音频转录工具,使用阿里 FunASR 模型进行语音识别。支持中文、英文等多种语言,无需 API 费用,完全本地运行。适用于音频文件转写(.wav, .ogg, .mp3 等)、会议记录、语音笔记整理等场景。 +--- + +# FunASR 语音转录 + +本地、免费、高效的语音识别工具,基于阿里巴巴 FunASR 模型。 + +## 快速开始 + +```bash +# 1. 安装 FunASR +bash ~/.openclaw/workspace/skills/funasr-transcribe/scripts/install.sh + +# 2. 转录音频 +bash ~/.openclaw/workspace/skills/funasr-transcribe/scripts/transcribe.sh /path/to/audio.ogg +``` + +## 安装 FunASR + +首次使用需要安装 FunASR 环境(虚拟环境 + 依赖): + +```bash +bash ~/.openclaw/workspace/skills/funasr-transcribe/scripts/install.sh +``` + +安装脚本会: +- 创建 Python 虚拟环境 `~/.openclaw/workspace/funasr_env` +- 安装 FunASR、torch、torchaudio、modelscope 等依赖 +- 安装完成后,首次转录会自动下载模型文件 + +**安装时间**:约 5-10 分钟(取决于网络速度) + +**系统要求**: +- Python 3.7+ +- 约 4GB 磁盘空间(虚拟环境 + 模型) +- 推荐 8GB+ 内存 + +## 转录音频 + +安装完成后,转录音频: + +```bash +bash ~/.openclaw/workspace/skills/funasr-transcribe/scripts/transcribe.sh /path/to/audio.ogg +``` + +**支持的格式**:`.wav`, `.ogg`, `.mp3`, `.flac`, `.m4a` 等 + +**输出**: +- 同目录下生成 `.txt` +- 包含转录文本(带标点) + +**性能**: +- CPU 推理:rtf 约 0.05-0.2(1 秒音频约需 0.05-0.2 秒) +- 首次转录需下载模型(约 1-2GB),后续直接使用缓存 + +## 技术细节 + +FunASR 使用以下模型组合: +- **ASR 模型**:`damo/speech_paraformer-large_asr_nat-zh-cn-16k-common-vocab8404-pytorch`(中文优化) +- **VAD 模型**:`damo/speech_fsmn_vad_zh-cn-16k-common-pytorch`(语音活动检测) +- **标点模型**:`damo/punc_ct-transformer_zh-cn-common-vocab272727-pytorch`(标点恢复) + +**语言支持**: +- 中文(普通话 + 方言) +- 英文 +- 中英混合 + +## 常见问题 + +**Q: 首次转录很慢?** +A: 首次运行会自动下载模型文件(约 1-2GB),后续转录会快很多。 + +**Q: 可以用 GPU 吗?** +A: 可以。编辑 `scripts/transcribe.py`,将 `device="cpu"` 改为 `device="cuda:0"`,并安装对应的 CUDA 版本依赖。 + +**Q: 转录准确率如何?** +A: FunASR 在中文场景下表现优异,通常优于 OpenAI Whisper。建议测试后评估效果。 diff --git a/skills/funasr-transcribe-skill/_meta.json b/skills/funasr-transcribe-skill/_meta.json new file mode 100644 index 0000000..9048215 --- /dev/null +++ b/skills/funasr-transcribe-skill/_meta.json @@ -0,0 +1,6 @@ +{ + "ownerId": "kn73y7erceybm87h6618deeva58296sk", + "slug": "funasr-transcribe-skill", + "version": "1.0.0", + "publishedAt": 1772877767626 +} \ No newline at end of file diff --git a/skills/funasr-transcribe-skill/scripts/install.sh b/skills/funasr-transcribe-skill/scripts/install.sh new file mode 100644 index 0000000..d493e54 --- /dev/null +++ b/skills/funasr-transcribe-skill/scripts/install.sh @@ -0,0 +1,69 @@ +#!/bin/bash +# FunASR 安装脚本 +# 用途:创建虚拟环境并安装 FunASR 及其依赖 + +set -e + +# 配置 +VENV_DIR="$HOME/.openclaw/workspace/funasr_env" +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" + +echo "==========================================" +echo "FunASR 安装脚本" +echo "==========================================" +echo "" + +# 检查 Python +if ! command -v python3 &> /dev/null; then + echo "❌ 错误:未找到 python3" + echo "请先安装 Python 3.7+" + exit 1 +fi + +PYTHON_VERSION=$(python3 -c "import sys; print(f'{sys.version_info.major}.{sys.version_info.minor}')") +echo "✓ Python 版本: $PYTHON_VERSION" + +# 创建虚拟环境 +if [ -d "$VENV_DIR" ]; then + echo "⚠️ 虚拟环境已存在: $VENV_DIR" + read -p "是否重新安装?(y/N): " -n 1 -r + echo + if [[ ! $REPLY =~ ^[Yy]$ ]]; then + echo "安装已取消" + exit 0 + fi + rm -rf "$VENV_DIR" +fi + +echo "创建虚拟环境: $VENV_DIR" +python3 -m venv "$VENV_DIR" +source "$VENV_DIR/bin/activate" + +# 升级 pip +echo "" +echo "升级 pip..." +pip install --upgrade pip -i https://pypi.tuna.tsinghua.edu.cn/simple + +# 安装依赖 +echo "" +echo "安装 FunASR 及依赖(这需要几分钟)..." +pip install funasr modelscope huggingface_hub torch torchaudio \ + -i https://pypi.tuna.tsinghua.edu.cn/simple + +# 验证安装 +echo "" +echo "验证安装..." +python3 -c "from funasr import AutoModel; print('✓ FunASR 安装成功')" || { + echo "❌ FunASR 安装失败" + exit 1 +} + +# 完成 +echo "" +echo "==========================================" +echo "✓ 安装完成!" +echo "==========================================" +echo "" +echo "现在可以使用转录功能:" +echo " bash $SCRIPT_DIR/transcribe.sh /path/to/audio.ogg" +echo "" diff --git a/skills/funasr-transcribe-skill/scripts/transcribe.py b/skills/funasr-transcribe-skill/scripts/transcribe.py new file mode 100644 index 0000000..043b50e --- /dev/null +++ b/skills/funasr-transcribe-skill/scripts/transcribe.py @@ -0,0 +1,85 @@ +#!/usr/bin/env python3 +"""FunASR 音频转录脚本""" + +import sys +import os +import json + +try: + from funasr import AutoModel +except ImportError: + print("❌ 错误:未找到 funasr 模块") + print("") + print("请先安装 FunASR:") + print(" bash ~/.openclaw/workspace/skills/funasr-transcribe/scripts/install.sh") + sys.exit(1) + + +def transcribe_audio(audio_path): + """使用 FunASR 转录音频""" + print(f"正在处理音频: {audio_path}") + print("首次运行会自动下载模型,可能需要几分钟...") + + # 加载模型 + model = AutoModel( + model="damo/speech_paraformer-large_asr_nat-zh-cn-16k-common-vocab8404-pytorch", + vad_model="damo/speech_fsmn_vad_zh-cn-16k-common-pytorch", + punc_model="damo/punc_ct-transformer_zh-cn-common-vocab272727-pytorch", + device="cpu" # 使用 CPU,如果有 GPU 可以改为 "cuda:0" + ) + + # 进行语音识别 + res = model.generate( + input=audio_path, + batch_size_s=300 + ) + + return res + + +def main(): + if len(sys.argv) < 2: + print("用法: python3 transcribe.py ") + sys.exit(1) + + audio_path = sys.argv[1] + + # 检查文件是否存在 + if not os.path.exists(audio_path): + print(f"❌ 错误:文件不存在: {audio_path}") + sys.exit(1) + + # 转录 + try: + result = transcribe_audio(audio_path) + except Exception as e: + print(f"❌ 转录失败: {e}") + sys.exit(1) + + # 输出结果 + text = "" + if isinstance(result, list) and len(result) > 0: + text = result[0].get("text", "") + + if not text: + print("⚠️ 未识别到文本") + sys.exit(0) + + print("\n" + "="*50) + print("转录结果:") + print("="*50) + print(text) + + # 保存到文件 + output_path = os.path.splitext(audio_path)[0] + ".txt" + try: + with open(output_path, "w", encoding="utf-8") as f: + f.write(text) + print("") + print(f"✓ 已保存到: {output_path}") + except Exception as e: + print(f"\n⚠️ 保存文件失败: {e}") + + +if __name__ == "__main__": + main() diff --git a/skills/funasr-transcribe-skill/scripts/transcribe.sh b/skills/funasr-transcribe-skill/scripts/transcribe.sh new file mode 100644 index 0000000..4356b91 --- /dev/null +++ b/skills/funasr-transcribe-skill/scripts/transcribe.sh @@ -0,0 +1,40 @@ +#!/bin/bash +# FunASR 音频转录脚本 +# 用途:将音频文件转录为文本 + +set -e + +# 配置 +VENV_DIR="$HOME/.openclaw/workspace/funasr_env" +TRANSCRIBE_PY="$HOME/.openclaw/workspace/skills/funasr-transcribe-skill/scripts/transcribe.py" + +# 检查参数 +if [ $# -lt 1 ]; then + echo "用法: $0 " + echo "" + echo "示例:" + echo " $0 /path/to/audio.ogg" + echo " $0 recording.wav" + exit 1 +fi + +AUDIO_FILE="$1" + +# 检查文件是否存在 +if [ ! -f "$AUDIO_FILE" ]; then + echo "❌ 错误:文件不存在: $AUDIO_FILE" + exit 1 +fi + +# 检查虚拟环境 +if [ ! -d "$VENV_DIR" ]; then + echo "❌ 错误:FunASR 未安装" + echo "" + echo "请先运行安装脚本:" + echo " bash ~/.openclaw/workspace/skills/funasr-transcribe/scripts/install.sh" + exit 1 +fi + +# 激活虚拟环境并转录 +source "$VENV_DIR/bin/activate" +python3 "$TRANSCRIBE_PY" "$AUDIO_FILE" diff --git a/skills/github/SKILL.md b/skills/github/SKILL.md new file mode 100644 index 0000000..03b2a00 --- /dev/null +++ b/skills/github/SKILL.md @@ -0,0 +1,47 @@ +--- +name: github +description: "Interact with GitHub using the `gh` CLI. Use `gh issue`, `gh pr`, `gh run`, and `gh api` for issues, PRs, CI runs, and advanced queries." +--- + +# GitHub Skill + +Use the `gh` CLI to interact with GitHub. Always specify `--repo owner/repo` when not in a git directory, or use URLs directly. + +## Pull Requests + +Check CI status on a PR: +```bash +gh pr checks 55 --repo owner/repo +``` + +List recent workflow runs: +```bash +gh run list --repo owner/repo --limit 10 +``` + +View a run and see which steps failed: +```bash +gh run view --repo owner/repo +``` + +View logs for failed steps only: +```bash +gh run view --repo owner/repo --log-failed +``` + +## API for Advanced Queries + +The `gh api` command is useful for accessing data not available through other subcommands. + +Get PR with specific fields: +```bash +gh api repos/owner/repo/pulls/55 --jq '.title, .state, .user.login' +``` + +## JSON Output + +Most commands support `--json` for structured output. You can use `--jq` to filter: + +```bash +gh issue list --repo owner/repo --json number,title --jq '.[] | "\(.number): \(.title)"' +``` diff --git a/skills/github/_meta.json b/skills/github/_meta.json new file mode 100644 index 0000000..948aa0c --- /dev/null +++ b/skills/github/_meta.json @@ -0,0 +1,6 @@ +{ + "ownerId": "kn70pywhg0fyz996kpa8xj89s57yhv26", + "slug": "github", + "version": "1.0.0", + "publishedAt": 1767545344344 +} \ No newline at end of file diff --git a/skills/marketing-strategy-pmm/SKILL.md b/skills/marketing-strategy-pmm/SKILL.md new file mode 100644 index 0000000..c44eb9d --- /dev/null +++ b/skills/marketing-strategy-pmm/SKILL.md @@ -0,0 +1,398 @@ +--- +name: "marketing-strategy-pmm" +description: Product marketing skill for positioning, GTM strategy, competitive intelligence, and product launches. Use when the user asks about product positioning, go-to-market planning, competitive analysis, target audience definition, ICP definition, market research, launch plans, or sales enablement. Covers April Dunford positioning, ICP definition, competitive battlecards, launch playbooks, and international market entry. Produces deliverables including positioning statements, battlecard documents, launch plans, and go-to-market strategies. +triggers: + - product marketing + - PMM + - positioning + - GTM strategy + - go-to-market + - competitive analysis + - battlecard + - product launch + - market entry + - sales enablement + - win loss analysis +--- + +# Marketing Strategy & PMM + +Product marketing patterns for positioning, GTM strategy, and competitive intelligence. + +--- + +## Table of Contents + +- [ICP Definition Workflow](#icp-definition-workflow) +- [Positioning Development](#positioning-development) +- [Competitive Intelligence](#competitive-intelligence) +- [Product Launch Planning](#product-launch-planning) +- [Sales Enablement](#sales-enablement) +- [International Expansion](#international-expansion) +- [Reference Documentation](#reference-documentation) + +--- + +## ICP Definition Workflow + +Define ideal customer profile for targeting: + +1. Analyze existing customers (top 20% by LTV) +2. Identify common firmographics (size, industry, revenue) +3. Map technographics (tools, maturity, integrations) +4. Document psychographics (pain level, motivation, risk tolerance) +5. Define 3-5 buyer personas (economic, technical, user) +6. Validate against sales cycle and churn data +7. Score prospects A/B/C/D based on ICP fit +8. **Validation:** A-fit customers have lowest churn and fastest close + +### Firmographics Template + +| Dimension | Target Range | Rationale | +|-----------|--------------|-----------| +| Employees | 50-5000 | Series A sweet spot | +| Revenue | $5M-$500M | Budget available | +| Industry | SaaS, Tech, Services | Product fit | +| Geography | US, UK, DACH | Market priority | +| Funding | Seed to Growth | Willing to adopt | + +### Buyer Personas + +| Persona | Title | Goals | Messaging | +|---------|-------|-------|-----------| +| Economic Buyer | VP, Director, Head of [Department] | ROI, team productivity, cost reduction | Business outcomes, ROI, case studies | +| Technical Buyer | Engineer, Architect, Tech Lead | Technical fit, easy integration | Architecture, security, documentation | +| User/Champion | Manager, Team Lead, Power User | Makes job easier, quick wins | UX, ease of use, time savings | + +### ICP Validation Checklist + +- [ ] 5+ paying customers match this profile +- [ ] Fastest sales cycles (< median) +- [ ] Highest LTV (> median) +- [ ] Lowest churn (< 5% annual) +- [ ] Strong product engagement +- [ ] Willing to do case studies + +--- + +## Positioning Development + +Develop positioning using April Dunford methodology: + +1. List competitive alternatives (direct, adjacent, status quo) +2. Isolate unique attributes (features only you have) +3. Map attributes to customer value (why it matters) +4. Define best-fit customers (who cares most) +5. Choose market category (head-to-head, niche, new category) +6. Layer on relevant trends (timing justification) +7. Test with 10+ customer interviews +8. **Validation:** 7+ customers describe value unprompted + +### Positioning Statement Template + +``` +FOR [target customer] +WHO [statement of need] +THE [product] IS A [category] +THAT [key benefit] +UNLIKE [competitive alternative] +OUR PRODUCT [primary differentiation] +``` + +### Value Proposition Formula + +Template: `[Product] helps [Target Customer] [Achieve Goal] by [Unique Approach]` + +Example: "Acme helps mid-market SaaS teams ship 2x faster by automating project workflows with AI" + +### Messaging Hierarchy + +| Level | Content | Example | +|-------|---------|---------| +| Headline | 5-7 words | "Ship faster with AI automation" | +| Subhead | 1 sentence | "Automate workflows so teams focus on what matters" | +| Benefits | 3-4 bullets | Speed, quality, collaboration, cost | +| Features | Supporting evidence | AI automation → 10 hrs/week saved | +| Proof | Social proof | Customer logos, stats, case studies | + +--- + +## Competitive Intelligence + +Build competitive knowledge base: + +1. Identify tier 1 (direct), tier 2 (adjacent), tier 3 (status quo) +2. Sign up for competitor products (hands-on evaluation) +3. Monitor competitor websites, pricing, messaging +4. Analyze sales call recordings for competitor mentions +5. Read G2/Capterra reviews (pros and cons) +6. Track competitor job postings (roadmap signals) +7. Update battlecards monthly +8. **Validation:** Sales team uses battlecards in 80%+ competitive deals + +### Competitive Tier Structure + +| Tier | Definition | Examples | +|------|------------|----------| +| 1 | Direct competitor, same category | [Competitor A, B] | +| 2 | Adjacent solution, overlapping use case | [Alt Solution C, D] | +| 3 | Status quo (what they do today) | Spreadsheets, manual, in-house | + +### Battlecard Template + +``` +COMPETITOR: [Name] +OVERVIEW: Founded [year], Funding [stage], Size [employees] + +POSITIONING: +- They say: "[Their claim]" +- Reality: [Your assessment] + +STRENGTHS: +1. [What they do well] +2. [What they do well] + +WEAKNESSES: +1. [Where they fall short] +2. [Where they fall short] + +OUR ADVANTAGES: +1. [Your advantage + evidence] +2. [Your advantage + evidence] + +WHEN WE WIN: +- [Scenario where you win] + +WHEN WE LOSE: +- [Scenario where they win] + +TALK TRACK: +Objection: "[Common objection]" +Response: "[Your response]" +``` + +### Win/Loss Analysis + +Track monthly: +- Win rate by competitor +- Top win reasons (product fit, ease of use, price) +- Top loss reasons (missing feature, price, relationship) +- Action items for product, sales, marketing + +--- + +## Product Launch Planning + +Plan launches by tier: + +| Tier | Scope | Prep Time | Budget | +|------|-------|-----------|--------| +| 1 | New product, major feature | 6-8 weeks | $50-100k | +| 2 | Significant feature, integration | 3-4 weeks | $10-25k | +| 3 | Small improvement | 1 week | <$5k | + +### Tier 1 Launch Workflow + +Execute major product launch: + +1. Kickoff meeting with Product, Marketing, Sales, CS +2. Define goals (pipeline $, MQLs, press coverage) +3. Develop positioning and messaging +4. Create sales enablement (deck, demo, battlecard) +5. Build campaign assets (landing page, emails, ads) +6. Train sales and CS teams +7. Execute launch day (press, email, ads, outbound) +8. Monitor and optimize for 30 days +9. **Validation:** Pipeline on track to goal by week 2 + +### Launch Day Checklist + +- [ ] Press release distributed +- [ ] Email announcement sent +- [ ] Social media posts live +- [ ] Paid ads at full budget +- [ ] Sales outbound blitz launched +- [ ] In-app notification active +- [ ] Metrics monitored every 2 hours + +### Launch Metrics + +| Metric | Leading (Daily) | Lagging (Weekly) | +|--------|-----------------|------------------| +| Traffic | Landing page visitors | - | +| Engagement | Demo requests, signups | Feature adoption % | +| Pipeline | MQLs generated | SQLs, pipeline $ | +| Revenue | - | Deals closed, revenue | + +--- + +## Sales Enablement + +Equip sales team with PMM assets: + +1. Create sales deck (15-20 slides, visual-first) +2. Build one-pagers (product, competitive, case study) +3. Develop demo script (30-45 min with discovery) +4. Write email templates (outreach, follow-up, closing) +5. Create ROI calculator (input costs, output savings) +6. Conduct monthly enablement calls +7. Deliver quarterly training (positioning, competitive) +8. **Validation:** Sales uses assets in 80%+ of opportunities + +### Sales Deck Structure + +| Slide | Content | +|-------|---------| +| 1-2 | Title, agenda | +| 3-4 | Company intro, problem statement | +| 5-7 | Solution, key benefits, demo | +| 8-10 | Differentiation, case study, pricing | +| 11-12 | Implementation, support, next steps | + +### Demo Flow + +``` +1. Intro (2 min): Who we are, agenda +2. Discovery (5 min): Their needs, pain points +3. Demo (20 min): Product focused on their use case +4. Q&A (10 min): Objection handling +5. Next steps (3 min): Trial, POC, proposal +``` + +### Sales-Marketing Handoff + +| Handoff | Frequency | Content | +|---------|-----------|---------| +| Weekly sync | 30 min | Win/loss, competitive, new assets | +| Monthly enablement | 60 min | Product updates, training | +| Quarterly review | Half-day | Results, strategy, planning | + +--- + +## International Expansion + +Enter new markets systematically: + +1. Validate market demand (inbound leads, TAM analysis) +2. Localize website, pricing, legal +3. Establish sales coverage (hire or agency) +4. Adapt messaging for cultural fit +5. Build local partnerships and references +6. Launch localized campaigns +7. Monitor CAC and conversion by market +8. **Validation:** 3+ paying customers from market in first 90 days + +### Market Priority (Series A) + +| Market | Timeline | Budget % | Target ARR | +|--------|----------|----------|------------| +| US | Months 1-6 | 50% | $1M | +| UK | Months 4-9 | 20% | $500k | +| DACH | Months 7-12 | 15% | $300k | +| France | Months 10-15 | 10% | $200k | +| Canada | Months 7-12 | 5% | $100k | + +### Localization Checklist + +- [ ] Website translation (professional, not machine) +- [ ] Currency and pricing localized +- [ ] Local phone number and address +- [ ] Legal compliance (GDPR, PIPEDA) +- [ ] Local payment methods +- [ ] Sales coverage during local hours +- [ ] Local case studies and references + +--- + +## Reference Documentation + +### Positioning Frameworks + +`references/positioning-frameworks.md` contains: + +- April Dunford 5-step positioning process +- Geoffrey Moore positioning statement template +- Positioning validation interview protocol +- Competitive positioning map construction + +### Launch Checklists + +`references/launch-checklists.md` contains: + +- Tier 1/2/3 launch checklists +- Week-by-week launch timeline +- Launch day runbook +- Post-launch metrics dashboard + +### International GTM + +`references/international-gtm.md` contains: + +- US, UK, DACH, France, Canada playbooks +- Market-specific channel mix and messaging +- Localization requirements per market +- Entry timeline and budget allocation + +### Messaging Templates + +`references/messaging-templates.md` contains: + +- Value proposition formulas +- Persona-specific messaging +- Competitive response scripts +- Objection handling templates +- Channel-specific copy (landing pages, emails, ads) + +--- + +## PMM KPIs + +| Metric | Target | Measurement | +|--------|--------|-------------| +| Product adoption | >40% in 90 days | Feature usage after launch | +| Win rate | >30% competitive | Deals won vs. competitors | +| Sales velocity | -20% YoY | Days from SQL to close | +| Deal size | +25% YoY | Average contract value | +| Launch pipeline | 3:1 ROMI | Pipeline $ : marketing spend | + +--- + +## Quick Reference + +### PMM Monthly Rhythm + +| Week | Focus | +|------|-------| +| 1 | Review metrics, update battlecards | +| 2 | Create assets, publish content | +| 3 | Support launches, optimize campaigns | +| 4 | Monthly report, plan next month | + +## Proactive Triggers + +- **No documented positioning** → Without clear positioning, all marketing is guesswork. +- **Messaging differs across channels** → Inconsistent story confuses buyers. +- **No ICP defined** → Selling to everyone means selling to no one. +- **Competitor repositioning** → Market shift detected. Review your positioning. + +## Output Artifacts + +| When you ask for... | You get... | +|---------------------|------------| +| "Position my product" | Positioning framework (April Dunford method) with output | +| "GTM strategy" | Go-to-market plan with channels, messaging, and timeline | +| "Competitive positioning" | Positioning map with competitive gaps and opportunities | + +## Communication + +All output passes quality verification: +- Self-verify: source attribution, assumption audit, confidence scoring +- Output format: Bottom Line → What (with confidence) → Why → How to Act +- Results only. Every finding tagged: 🟢 verified, 🟡 medium, 🔴 assumed. + +## Related Skills + +- **marketing-context**: For capturing foundational positioning. PMM builds on this. +- **launch-strategy**: For executing product launches planned by PMM. +- **competitive-intel** (C-Suite): For strategic competitive intelligence. +- **cmo-advisor** (C-Suite): For marketing budget and growth model decisions. diff --git a/skills/marketing-strategy-pmm/_meta.json b/skills/marketing-strategy-pmm/_meta.json new file mode 100644 index 0000000..efe02f2 --- /dev/null +++ b/skills/marketing-strategy-pmm/_meta.json @@ -0,0 +1,6 @@ +{ + "ownerId": "kn7f2gr00xy51fj1nx2y64ckjs800mhn", + "slug": "marketing-strategy-pmm", + "version": "2.1.1", + "publishedAt": 1773070262187 +} \ No newline at end of file diff --git a/skills/marketing-strategy-pmm/references/international-gtm.md b/skills/marketing-strategy-pmm/references/international-gtm.md new file mode 100644 index 0000000..a857976 --- /dev/null +++ b/skills/marketing-strategy-pmm/references/international-gtm.md @@ -0,0 +1,401 @@ +# International GTM Playbooks + +Market-by-market expansion guides for US, UK, DACH, France, and Canada. + +--- + +## Table of Contents + +- [Market Prioritization](#market-prioritization) +- [US Market Entry](#us-market-entry) +- [UK Market Entry](#uk-market-entry) +- [DACH Market Entry](#dach-market-entry) +- [France Market Entry](#france-market-entry) +- [Canada Market Entry](#canada-market-entry) +- [Localization Checklist](#localization-checklist) + +--- + +## Market Prioritization + +### Expansion Sequence (Series A) + +| Phase | Market | Timeline | Budget % | Target ARR | +|-------|--------|----------|----------|------------| +| 1 | US | Months 1-6 | 50% | $1M | +| 2 | UK | Months 4-9 | 20% | $500k | +| 3 | DACH | Months 7-12 | 15% | $300k | +| 4 | France | Months 10-15 | 10% | $200k | +| 5 | Canada | Months 7-12 | 5% | $100k | + +### Market Readiness Checklist + +Enter market when ALL true: + +- [ ] Product ready for market (localization if needed) +- [ ] Legal/compliance requirements met +- [ ] Pricing localized (currency, taxes) +- [ ] Sales capacity available (hire or agency) +- [ ] Marketing budget allocated +- [ ] Support coverage during local hours +- [ ] **Validation:** 3+ inbound leads from market in last 90 days + +--- + +## US Market Entry + +### Market Characteristics + +| Factor | US Approach | +|--------|-------------| +| Buying cycle | Fast (30-60 days average) | +| Decision process | Individual empowerment, less consensus | +| Pricing sensitivity | Value-focused, willing to pay premium | +| Communication | Direct, results-oriented | +| Relationship | Transaction > relationship (initially) | + +### Entry Strategy + +**Months 1-2: Foundation** + +1. Establish US presence: + - US phone number (toll-free) + - US address (virtual office acceptable) + - USD pricing on website + - US case studies (even if from beta users) + +2. Hire US sales: + - Option A: US-based SDR/AE (expensive but effective) + - Option B: US sales agency (lower risk, shared commission) + - Option C: Remote sales trained on US hours + +3. Launch paid campaigns: + - Google Ads (high-intent keywords) + - LinkedIn (B2B targeting) + - Budget: 50% of marketing spend + +**Months 3-6: Scale** + +1. Optimize channels based on CAC data +2. Build US partner ecosystem: + - Integration partners (Salesforce, HubSpot) + - Resellers/VARs (for Enterprise) + - Industry associations +3. Attend US conferences (SaaStr, industry events) +4. **Validation:** $1M pipeline from US sources + +### US Channel Mix + +| Channel | Budget % | Expected CPL | Notes | +|---------|----------|--------------|-------| +| Google Ads | 35% | $100-200 | High intent, competitive | +| LinkedIn | 30% | $150-250 | B2B targeting | +| SEO/Content | 20% | $50 (long-term) | Invest early | +| Partnerships | 15% | Variable | Co-marketing | + +### US Messaging + +- Lead with ROI and business outcomes +- Use $ impact metrics prominently +- Reference US customers (logos matter) +- Emphasize speed and efficiency +- Include G2/Capterra ratings + +--- + +## UK Market Entry + +### Market Characteristics + +| Factor | UK Approach | +|--------|-------------| +| Buying cycle | Medium (45-90 days) | +| Decision process | Committee involvement | +| Pricing sensitivity | Value-conscious, compare options | +| Communication | Professional, less aggressive than US | +| Relationship | Balance transaction and relationship | + +### Entry Strategy + +**Months 4-6: Setup** + +1. Localization: + - GBP pricing + - UK spellings (colour, organisation) + - UK phone number + - GDPR compliance (essential) + +2. Sales coverage: + - Hire UK-based rep OR + - Partner with UK sales agency + - Ensure coverage during GMT hours + +3. Content localization: + - UK case studies + - UK-relevant industry references + - Local competitor positioning + +**Months 7-9: Growth** + +1. Build UK partnerships: + - UK tech community (TechNation, etc.) + - London-based VCs and accelerators + - UK industry associations + +2. Attend UK events: + - London Tech Week + - Industry-specific conferences + +3. **Validation:** $500k pipeline from UK sources + +### UK Channel Mix + +| Channel | Budget % | Expected CPL | Notes | +|---------|----------|--------------|-------| +| LinkedIn | 35% | $120-200 | Strong B2B presence | +| Google UK | 30% | $80-150 | Less competitive than US | +| SEO/Content | 20% | $40 | UK-targeted keywords | +| Partnerships | 15% | Variable | Local credibility | + +### UK Messaging + +- More formal than US (avoid hyperbole) +- Emphasize data security and GDPR +- Reference UK/EU customers +- Understated claims (prove with data) +- Acknowledge local presence/support + +--- + +## DACH Market Entry + +### Market Characteristics + +| Factor | DACH Approach | +|--------|---------------| +| Buying cycle | Long (90-180 days) | +| Decision process | Consensus-driven, thorough evaluation | +| Pricing sensitivity | Quality over price, long-term view | +| Communication | Formal, detailed, precise | +| Relationship | Trust built over time, essential | + +### Entry Strategy + +**Months 7-9: Foundation** + +1. Full localization: + - German translation (website, product UI) + - EUR pricing with German VAT handling + - German phone number and address + - GDPR compliance (strict enforcement) + - Data residency option (EU data centers) + +2. German-speaking sales: + - Hire German-speaking sales rep + - Native speaker critical (not just fluent) + - Based in Germany preferred + +3. Content in German: + - Translate key pages and materials + - Create German case studies + - German blog content + +**Months 10-12: Growth** + +1. Build local credibility: + - German customer testimonials + - German partner ecosystem + - Industry certifications (ISO, etc.) + +2. Attend German events: + - CeBIT/Hannover Messe + - Industry conferences + +3. **Validation:** $300k pipeline from DACH sources + +### DACH Channel Mix + +| Channel | Budget % | Expected CPL | Notes | +|---------|----------|--------------|-------| +| LinkedIn | 40% | $150-250 | Strong professional network | +| Google DE | 25% | $100-180 | German keywords | +| SEO (German) | 20% | $60 | Long-term investment | +| Partnerships | 15% | Variable | Critical for trust | + +### DACH Messaging + +- Formal tone (Sie, not du) +- Emphasize security, compliance, privacy +- Detailed specifications and documentation +- Reference German/EU customers +- Include certifications (ISO, SOC 2) +- Show long-term commitment to market + +--- + +## France Market Entry + +### Market Characteristics + +| Factor | France Approach | +|--------|-----------------| +| Buying cycle | Long (90-180 days) | +| Decision process | Hierarchical, formal process | +| Pricing sensitivity | Value-focused, negotiation expected | +| Communication | Formal, relationship-focused | +| Relationship | Critical, business built on trust | + +### Entry Strategy + +**Months 10-12: Foundation** + +1. Full French localization: + - French translation (professional, not machine) + - EUR pricing with French VAT + - French phone number + - GDPR + French regulations + +2. French-speaking team: + - Native French speaker for sales + - French support coverage + - Paris presence (even virtual) + +**Months 13-15: Growth** + +1. Build local ecosystem: + - French tech community (La French Tech) + - French partners and integrators + - Industry associations + +2. Attend French events: + - VivaTech (Paris) + - Industry conferences + +3. **Validation:** $200k pipeline from France + +### France Channel Mix + +| Channel | Budget % | Expected CPL | Notes | +|---------|----------|--------------|-------| +| LinkedIn | 35% | $130-220 | Professional network | +| Google FR | 30% | $90-160 | French keywords | +| SEO (French) | 20% | $50 | French content strategy | +| Partnerships | 15% | Variable | Local partners essential | + +### France Messaging + +- Formal and professional +- French language throughout (no English fallback) +- Reference French/EU customers +- Emphasize local support and presence +- Highlight innovation and modernity +- Respect cultural nuances + +--- + +## Canada Market Entry + +### Market Characteristics + +| Factor | Canada Approach | +|--------|-----------------| +| Buying cycle | Medium (45-75 days) | +| Decision process | Similar to US, slightly more conservative | +| Pricing sensitivity | Value-conscious, compare to US prices | +| Communication | Professional, friendly, less aggressive | +| Language | English (except Quebec - French required) | + +### Entry Strategy + +**Months 7-9: Foundation** + +1. Minimal localization: + - CAD pricing + - Canadian phone number (optional) + - PIPEDA compliance + +2. Sales coverage: + - Leverage US sales team (similar hours) + - Consider Toronto-based rep for growth + +3. Quebec consideration: + - French required for Quebec market + - Can delay or skip initially + +**Months 10-12: Growth** + +1. Canadian partnerships: + - Canadian tech community + - Toronto/Vancouver startup ecosystem + - Industry associations + +2. **Validation:** $100k pipeline from Canada + +### Canada Channel Mix + +| Channel | Budget % | Expected CPL | Notes | +|---------|----------|--------------|-------| +| Google CA | 35% | $80-150 | Canadian targeting | +| LinkedIn | 30% | $100-180 | B2B focus | +| SEO | 20% | $40 | Canadian content | +| Partnerships | 15% | Variable | Local credibility | + +--- + +## Localization Checklist + +### Per-Market Checklist + +**Website** + +- [ ] Language translation (professional, not machine) +- [ ] Currency localization (display + checkout) +- [ ] Phone number (local format) +- [ ] Address (local presence) +- [ ] Legal pages (privacy, terms in local language) +- [ ] hreflang tags configured correctly + +**Product** + +- [ ] UI translation (if required for market) +- [ ] Date/time format (DD/MM/YYYY vs MM/DD/YYYY) +- [ ] Number format (1,000 vs 1.000) +- [ ] Currency in product + +**Payment** + +- [ ] Local currency accepted +- [ ] VAT/tax handling +- [ ] Local payment methods (SEPA, iDEAL, etc.) +- [ ] Invoicing in local format + +**Legal** + +- [ ] GDPR compliance (EU markets) +- [ ] PIPEDA compliance (Canada) +- [ ] Local data protection laws +- [ ] Terms of service localized +- [ ] Privacy policy localized + +**Sales** + +- [ ] Local sales coverage (rep or agency) +- [ ] Localized sales materials +- [ ] Local pricing and quoting +- [ ] Local references and case studies + +**Support** + +- [ ] Coverage during local business hours +- [ ] Language support (phone, chat, email) +- [ ] Localized documentation +- [ ] Local SLA commitments + +**Marketing** + +- [ ] Localized campaigns +- [ ] Local content (blog, guides) +- [ ] Local social media presence +- [ ] Local event participation + +**Validation:** Native speaker review of ALL localized content before launch diff --git a/skills/marketing-strategy-pmm/references/launch-checklists.md b/skills/marketing-strategy-pmm/references/launch-checklists.md new file mode 100644 index 0000000..b832b8c --- /dev/null +++ b/skills/marketing-strategy-pmm/references/launch-checklists.md @@ -0,0 +1,333 @@ +# Launch Checklists + +GTM launch playbooks for Tier 1, 2, and 3 product releases. + +--- + +## Table of Contents + +- [Launch Tier Definitions](#launch-tier-definitions) +- [Tier 1 Major Launch](#tier-1-major-launch) +- [Tier 2 Standard Launch](#tier-2-standard-launch) +- [Tier 3 Minor Launch](#tier-3-minor-launch) +- [Launch Metrics Dashboard](#launch-metrics-dashboard) + +--- + +## Launch Tier Definitions + +| Tier | Scope | Prep Time | Budget | Audience | +|------|-------|-----------|--------|----------| +| 1 | New product, major feature | 6-8 weeks | $50-100k | All prospects + press | +| 2 | Significant feature, integration | 3-4 weeks | $10-25k | Customers + select prospects | +| 3 | Small feature, improvement | 1 week | <$5k | Existing customers | + +**Tier Selection Criteria:** + +``` +Tier 1 if ANY true: +- [ ] Net-new product line +- [ ] Revenue impact > $500k pipeline +- [ ] Press coverage expected +- [ ] Competitive response anticipated + +Tier 2 if ANY true: +- [ ] Major feature request (top 10 customer ask) +- [ ] New integration with strategic partner +- [ ] Pricing or packaging change + +Tier 3 otherwise: +- [ ] Bug fixes +- [ ] UI improvements +- [ ] Minor enhancements +``` + +--- + +## Tier 1 Major Launch + +### Phase 1: Foundation (Weeks -8 to -5) + +**Week -8: Kickoff** + +- [ ] Schedule kickoff meeting (Product, Marketing, Sales, CS) +- [ ] Define launch goals: + - Pipeline target: $______ + - MQL target: ______ + - Press hits target: ______ + - Adoption target: ______% in 90 days +- [ ] Assign roles (RACI matrix): + - PMM: Launch lead, positioning, messaging + - Product: Feature readiness, demo environment + - Demand Gen: Campaigns, paid ads, email + - Content: Blog posts, case studies, videos + - Sales: Enablement, outbound campaign +- [ ] Create project timeline in Asana/Monday/Notion +- [ ] **Validation:** All stakeholders confirm goals and timeline + +**Week -7: Strategy** + +- [ ] Develop positioning and messaging (see positioning-frameworks.md) +- [ ] Create GTM channel plan: + - Owned: Email, blog, social, webinar + - Paid: LinkedIn ads, Google ads + - Earned: Press, influencers, partners +- [ ] Define target segments (ICP, personas) +- [ ] Allocate budget by channel +- [ ] Draft press release (embargo date set) + +**Week -6: Content** + +- [ ] Build landing page (product page, demo request form) +- [ ] Write blog post announcement +- [ ] Create sales deck updates (5-10 new slides) +- [ ] Design social media graphics (5+ variants) +- [ ] Produce demo video (3-5 minutes) +- [ ] Draft email sequences (announcement, nurture) + +**Week -5: Enablement** + +- [ ] Create sales battlecard (competitive positioning) +- [ ] Write demo script (new feature walkthrough) +- [ ] Build FAQ document (top 20 questions) +- [ ] Develop objection handling guide +- [ ] Schedule sales training session +- [ ] Recruit beta customers for testimonials +- [ ] **Validation:** Sales team can demo feature confidently + +### Phase 2: Preparation (Weeks -4 to -1) + +**Week -4: Launch Prep** + +- [ ] Set up HubSpot campaign (UTMs, attribution) +- [ ] Launch teaser campaign (social, email hints) +- [ ] Pitch press and analysts (NDA briefings) +- [ ] Create webinar registration page +- [ ] Finalize partner co-marketing plans +- [ ] QA all landing pages and forms + +**Week -3: Ramp Up** + +- [ ] Activate paid ads (LinkedIn, Google) at 50% budget +- [ ] A/B test landing page headlines +- [ ] Send pre-launch email to VIP customers +- [ ] Conduct sales training (2-hour session) +- [ ] Confirm webinar speakers and content +- [ ] Prepare launch day runbook + +**Week -2: Final Prep** + +- [ ] Increase paid ad spend to 75% +- [ ] Send webinar reminder emails +- [ ] Finalize press embargo lift time +- [ ] Complete dry run (website, forms, CRM workflow) +- [ ] Create launch day social posts (scheduled) +- [ ] Brief customer success team + +**Week -1: Pre-Launch** + +- [ ] Final approval on all assets +- [ ] Send VIP preview to top 10 customers +- [ ] Confirm press embargo release +- [ ] Sales team ready (trained, quotas set) +- [ ] CS team ready (docs updated, chat staffed) +- [ ] Test all systems one final time +- [ ] **Validation:** All checklist items green + +### Phase 3: Launch (Weeks 1-4) + +**Launch Day** + +- [ ] Press release distribution (wire + direct pitch) +- [ ] Email blast to full database +- [ ] Social media posts (LinkedIn, Twitter, Facebook) +- [ ] Paid ads at 100% budget +- [ ] Sales outbound blitz (top 100 accounts) +- [ ] In-app announcement to existing users +- [ ] Monitor metrics every 2 hours: + - Traffic, signups, demo requests + - Press pickup, social engagement + - Sales pipeline created + +**Days 2-7** + +- [ ] Daily metrics review (conversion rates, funnel) +- [ ] A/B test optimizations based on data +- [ ] Sales follow-up (<4 hour SLA on leads) +- [ ] Respond to press and analyst inquiries +- [ ] Host webinar (Day 3 or 4) +- [ ] Post customer testimonials +- [ ] Adjust paid ads (pause underperformers) + +**Week 2-4** + +- [ ] Publish post-launch blog content +- [ ] Create customer case study from early adopters +- [ ] Conduct win/loss interviews (5+ deals) +- [ ] Optimize converting channels (+20% budget) +- [ ] Pause non-converting channels +- [ ] Weekly launch status report to executives +- [ ] **Validation:** Pipeline on track to goal + +### Phase 4: Post-Launch (Weeks 5-12) + +**Month 2** + +- [ ] Launch retrospective meeting +- [ ] Document learnings (what worked, what didn't) +- [ ] Scale winning channels +- [ ] Expand to new segments if successful +- [ ] Update positioning based on customer feedback +- [ ] Plan sustaining campaigns + +**Month 3** + +- [ ] Final launch report (vs. goals) +- [ ] Calculate ROI (pipeline / spend) +- [ ] Publish additional case studies +- [ ] Integrate learnings into next launch plan +- [ ] Archive launch assets for reuse + +--- + +## Tier 2 Standard Launch + +### Timeline: 4 Weeks + +**Week -4 to -3: Preparation** + +- [ ] Define feature and target audience +- [ ] Create positioning and key messages +- [ ] Build landing page or product page update +- [ ] Write blog post announcement +- [ ] Update sales deck (2-3 slides) +- [ ] Create email announcement +- [ ] Brief sales team (30-min call) + +**Week -2 to -1: Setup** + +- [ ] Set up HubSpot campaign tracking +- [ ] Schedule social posts +- [ ] Set up paid ads (limited budget) +- [ ] QA landing pages and forms +- [ ] Notify customer success team + +**Launch Week** + +- [ ] Send email announcement +- [ ] Publish blog post +- [ ] Post on social media +- [ ] In-app notification to users +- [ ] Sales mention in active deals +- [ ] Monitor initial metrics + +**Week +1 to +2: Follow-up** + +- [ ] Analyze launch metrics +- [ ] Optimize based on data +- [ ] Collect customer feedback +- [ ] Document learnings + +--- + +## Tier 3 Minor Launch + +### Timeline: 1 Week + +**Day -5 to -3: Prep** + +- [ ] Write changelog entry +- [ ] Update support documentation +- [ ] Create in-app notification copy +- [ ] Brief CS team + +**Day -2 to -1: Review** + +- [ ] QA feature in staging +- [ ] Approve changelog copy +- [ ] Schedule in-app notification + +**Launch Day** + +- [ ] Deploy feature +- [ ] Trigger in-app notification +- [ ] Publish changelog +- [ ] Update support docs (if needed) + +**Day +1 to +3: Monitor** + +- [ ] Check for support tickets +- [ ] Monitor feature adoption +- [ ] Address any issues + +--- + +## Launch Metrics Dashboard + +### Leading Indicators (Track Daily) + +| Metric | Target | Day 1 | Day 3 | Day 7 | +|--------|--------|-------|-------|-------| +| Landing page visitors | 5,000 | | | | +| Demo requests | 100 | | | | +| Free trial signups | 200 | | | | +| MQLs generated | 150 | | | | +| Pipeline created ($) | $500k | | | | + +### Lagging Indicators (Track Weekly) + +| Metric | Target | Week 1 | Week 2 | Week 4 | +|--------|--------|--------|--------|--------| +| SQLs generated | 30 | | | | +| Demos completed | 50 | | | | +| Deals closed (#) | 5 | | | | +| Revenue ($) | $100k | | | | +| Feature adoption (%) | 40% | | | | + +### Channel Performance + +| Channel | Spend | MQLs | CPL | Pipeline | ROI | +|---------|-------|------|-----|----------|-----| +| LinkedIn Ads | $10k | | | | | +| Google Ads | $5k | | | | | +| Email | $0 | | | | | +| Organic | $0 | | | | | +| Webinar | $2k | | | | | +| **Total** | **$17k** | | | | | + +### Post-Launch Report Template + +``` +LAUNCH: [Product/Feature Name] +DATE: [Launch Date] +OWNER: [PMM Name] + +EXECUTIVE SUMMARY: +- Goal: $500k pipeline in 30 days +- Actual: $[X] pipeline (X% of goal) +- Status: ✅ On Track / ⚠️ Behind / ❌ Missed + +KEY RESULTS: +| Metric | Goal | Actual | % of Goal | +|--------------|---------|---------|-----------| +| MQLs | 150 | | | +| SQLs | 30 | | | +| Pipeline | $500k | | | +| Feature Adoption | 40% | | | + +TOP PERFORMING: +1. [Channel/Tactic] - [Result] +2. [Channel/Tactic] - [Result] + +UNDERPERFORMING: +1. [Channel/Tactic] - [Result] - [Action taken] + +LEARNINGS: +1. [What worked and why] +2. [What didn't work and why] +3. [What we'd do differently] + +NEXT STEPS: +1. [Action item] - Owner - Due date +2. [Action item] - Owner - Due date +``` diff --git a/skills/marketing-strategy-pmm/references/messaging-templates.md b/skills/marketing-strategy-pmm/references/messaging-templates.md new file mode 100644 index 0000000..17f030c --- /dev/null +++ b/skills/marketing-strategy-pmm/references/messaging-templates.md @@ -0,0 +1,446 @@ +# Messaging Templates + +Ready-to-use messaging frameworks for different personas and contexts. + +--- + +## Table of Contents + +- [Value Proposition Templates](#value-proposition-templates) +- [Persona-Specific Messaging](#persona-specific-messaging) +- [Competitive Messaging](#competitive-messaging) +- [Channel-Specific Copy](#channel-specific-copy) +- [Objection Handling Scripts](#objection-handling-scripts) + +--- + +## Value Proposition Templates + +### One-Liner Formula + +Template: `[Product] helps [Target Customer] [Achieve Goal] by [Unique Approach]` + +**Examples:** + +``` +B2B SaaS: +"Acme helps mid-market SaaS teams ship 2x faster by automating +project workflows with AI." + +Enterprise: +"Acme helps Fortune 500 companies reduce operational costs by 40% +through intelligent process automation." + +SMB: +"Acme helps small businesses save 10 hours per week by automating +their daily tasks." +``` + +### Elevator Pitch (30 Seconds) + +Template: +``` +You know how [target customer] struggles with [pain point]? + +[Product] is a [category] that [key differentiator]. + +Unlike [alternatives], we [unique value]. + +Our customers see [specific outcome] within [timeframe]. +``` + +**Example:** + +``` +You know how engineering teams struggle with slow code reviews +that delay releases? + +Acme is an AI code review platform that catches bugs before +they reach production. + +Unlike manual reviews, we analyze every PR in under 2 minutes +with 95% accuracy. + +Our customers ship 40% faster within their first month. +``` + +### Messaging Hierarchy + +``` +LEVEL 1: HEADLINE (5-7 words) +"Ship faster with AI-powered automation" + +LEVEL 2: SUBHEAD (1 sentence) +"Acme automates your workflows so your team can focus on what matters." + +LEVEL 3: KEY BENEFITS (3-4 bullets) +• Save 10+ hours per week on manual tasks +• Reduce errors by 80% with AI validation +• Deploy changes 3x faster with automated testing +• Scale operations without adding headcount + +LEVEL 4: FEATURES → VALUE +• AI Automation → Eliminates repetitive work → Save $50k/year +• Real-time Sync → No version conflicts → 50% fewer errors +• Integrations → Connect existing tools → 2-hour setup +``` + +--- + +## Persona-Specific Messaging + +### Economic Buyer (VP/Director/C-Level) + +**Primary concerns:** ROI, business outcomes, risk mitigation + +**Messaging principles:** +- Lead with business impact ($, %, time) +- Show ROI within 6-12 months +- Reference similar companies +- Address risk (security, implementation) + +**Template:** + +``` +HEADLINE: [Business outcome] in [timeframe] + +OPENING: +"[Role at similar company] was spending [hours/dollars] on [problem]. +After implementing [Product], they achieved [specific result]." + +KEY POINTS: +• [Metric] improvement in [area] (e.g., "40% reduction in manual work") +• ROI: [X]x return within [timeframe] +• Implementation: [timeframe] with [level] of effort +• Risk: [How you mitigate concerns] + +CTA: "See how [similar company] achieved [result] →" +``` + +**Example email:** + +``` +Subject: How Stripe reduced deployment time by 60% + +Hi [Name], + +The VP of Engineering at a company similar to yours was spending +40 hours per week on code review bottlenecks. + +After implementing Acme, they: +• Reduced review time by 60% +• Caught 3x more bugs before production +• Shipped new features 2 weeks faster + +Would a 15-minute call to explore if similar results are possible +for [Company] make sense? +``` + +### Technical Buyer (Engineer/Architect) + +**Primary concerns:** Technical fit, security, integration, vendor lock-in + +**Messaging principles:** +- Lead with technical capabilities +- Show architecture and security details +- Demonstrate easy integration +- Provide technical documentation + +**Template:** + +``` +HEADLINE: [Technical capability] for [their stack] + +OPENING: +"Built for [their technology environment] with [key technical feature]." + +KEY POINTS: +• Architecture: [how it works technically] +• Security: [certifications, compliance, encryption] +• Integration: [specific integrations with their tools] +• Performance: [benchmarks, latency, uptime] + +CTA: "Read the technical whitepaper →" or "See the API docs →" +``` + +**Example:** + +``` +Subject: SOC 2 Type II compliant with 99.99% uptime + +Hi [Name], + +I noticed [Company] uses Kubernetes for container orchestration. + +Acme integrates natively with K8s with: +• Single-line Helm chart deployment +• mTLS encryption for all traffic +• SOC 2 Type II + GDPR compliant +• 99.99% uptime SLA with $10k credit guarantee + +Here's our architecture diagram: [link] + +Worth a quick technical review? +``` + +### End User (Manager/Individual Contributor) + +**Primary concerns:** Ease of use, daily workflow, learning curve + +**Messaging principles:** +- Lead with time savings +- Show product in action (demo, screenshots) +- Emphasize simplicity +- Include peer testimonials + +**Template:** + +``` +HEADLINE: [Daily benefit] in [time to value] + +OPENING: +"Imagine [desired outcome] without [pain point]." + +KEY POINTS: +• Get started in [timeframe] (no training required) +• Save [hours] every [timeframe] +• [Feature] makes [task] effortless +• Loved by [peer companies/roles] + +CTA: "Try free for 14 days →" +``` + +**Example:** + +``` +Subject: Spend less time in meetings, more time building + +Hi [Name], + +What if your weekly status meetings could run themselves? + +Acme automatically: +• Collects updates from your team (no nagging) +• Creates visual progress reports (no spreadsheets) +• Flags blockers before they become problems + +Teams like [Company A] and [Company B] love it. + +Start your free trial: [link] +``` + +--- + +## Competitive Messaging + +### "Why Us vs. Competitor A" Framework + +``` +OPENING (acknowledge competition): +"Both [Product] and [Competitor A] help teams with [general category]. +Here's what sets us apart:" + +DIFFERENTIATORS (3-4 key points): + +1. [Your advantage] vs. [Their limitation] + "Our AI catches 95% of bugs vs. their rule-based 60% coverage" + +2. [Your advantage] vs. [Their limitation] + "Get started in 2 hours vs. their 2-week implementation" + +3. [Your advantage] vs. [Their limitation] + "$50/user vs. their $150/user at scale" + +PROOF POINT: +"[Customer] switched from [Competitor A] to us and saw [result]" + +CTA: +"See a side-by-side comparison →" +``` + +### Competitive Positioning Statements + +**When they're the market leader:** + +``` +"[Competitor] built the category, but it was designed for [old paradigm]. +[Product] is purpose-built for [new reality] with [key differentiators]." +``` + +**When they're cheaper:** + +``` +"[Competitor] costs less upfront, but teams spend [X hours] working +around limitations. [Product] pays for itself in [timeframe] through +[specific efficiency gains]." +``` + +**When they have more features:** + +``` +"[Competitor] tries to do everything. [Product] focuses on doing +[core use case] exceptionally well. Our customers tell us they only +use 20% of [Competitor's] features anyway." +``` + +--- + +## Channel-Specific Copy + +### Landing Page + +**Above the fold:** +``` +[HEADLINE - 5-7 words, benefit-focused] +Ship faster with AI-powered automation + +[SUBHEAD - 1 sentence expanding on value] +Acme automates your workflows so your team can focus on what matters. + +[CTA - Action-oriented] +Start Free Trial | Book Demo +``` + +**Social proof bar:** +``` +Trusted by 5,000+ teams including [Logo] [Logo] [Logo] [Logo] +``` + +### Email Subject Lines + +**High performers:** +- "How [Similar Company] achieved [result]" +- "[Name], quick question about [their challenge]" +- "Re: [topic they care about]" (for follow-ups) +- "[Specific number]% improvement in [metric]" + +**Avoid:** +- "Quick sync?" +- "Following up..." +- "Just checking in" +- ALL CAPS or excessive punctuation!!! + +### LinkedIn Ads + +**Format: Single image or carousel** + +``` +HEADLINE (70 chars max): +"Cut code review time by 60%" + +BODY (150 chars recommended): +"AI-powered code reviews that catch bugs before production. +Trusted by engineering teams at Stripe and Shopify. +Try free →" + +CTA: Learn More / Try Free / Get Demo +``` + +### Google Ads + +**Search ad format:** + +``` +Headline 1 (30 chars): AI Code Review Platform +Headline 2 (30 chars): Ship 40% Faster +Headline 3 (30 chars): Free 14-Day Trial + +Description (90 chars): +Catch bugs before production. Trusted by 5,000+ teams. +Start your free trial today. +``` + +--- + +## Objection Handling Scripts + +### Price Objection + +**"It's too expensive"** + +``` +ACKNOWLEDGE: "I understand budget is a concern." + +REFRAME: "Let me share how our customers think about it... +[Customer] was spending [X hours/dollars] on [problem] every month. +After implementing [Product], they saved [Y hours/dollars], paying +for the solution in [timeframe]." + +QUESTION: "What would it be worth to your team to [achieve outcome]?" + +ALTERNATIVE: "We also offer [smaller plan/annual discount] that might +work for your current budget. Would that help?" +``` + +### Competitor Objection + +**"We're looking at [Competitor A] too"** + +``` +ACKNOWLEDGE: "That's smart to evaluate options. [Competitor A] is +a solid product." + +DIFFERENTIATE: "The main differences customers tell us about: +1. [Your advantage] - [Competitor] doesn't offer this +2. [Your advantage] - Their approach is [different/older] +3. [Price/support/speed] - We're typically [X] better here" + +PROOF: "[Customer] evaluated both and chose us because [reason]." + +QUESTION: "What are the 2-3 things that matter most to you in +this decision?" +``` + +### Timing Objection + +**"Not the right time"** + +``` +ACKNOWLEDGE: "I completely understand. Timing is everything." + +EXPLORE: "Out of curiosity, what would need to change for this +to become a priority?" + +FUTURE: "Would it make sense to schedule a brief call in [timeframe] +to revisit? I can share relevant updates without any pressure." + +VALUE ADD: "In the meantime, I'll send over [relevant content] that +might be useful for when you're ready." +``` + +### Authority Objection + +**"I need to check with my team/boss"** + +``` +ACKNOWLEDGE: "Of course, that makes sense." + +SUPPORT: "What information would be most helpful for that conversation? +I can put together a one-pager with key points." + +OFFER: "Would it help if I joined a brief call with [stakeholder] +to answer any technical/business questions directly?" + +TIMELINE: "When do you think you'll have that conversation? +I can follow up with any additional materials beforehand." +``` + +### Technical Objection + +**"Will this integrate with our stack?"** + +``` +ACKNOWLEDGE: "Great question - integration is critical." + +CONFIRM: "What are the main tools you need to connect with? +[Listen and take notes]" + +ANSWER: "We have native integrations with [tools]. For [tool], +we use [API/webhook/Zapier]. Here's our integration docs: [link]" + +PROOF: "[Similar company] uses a similar stack and got integrated +in [timeframe]." + +DEMO: "Want me to show you exactly how the integration works +in a quick demo?" +``` diff --git a/skills/marketing-strategy-pmm/references/positioning-frameworks.md b/skills/marketing-strategy-pmm/references/positioning-frameworks.md new file mode 100644 index 0000000..f9479ce --- /dev/null +++ b/skills/marketing-strategy-pmm/references/positioning-frameworks.md @@ -0,0 +1,279 @@ +# Positioning Frameworks + +Strategic positioning methodologies for B2B SaaS products. + +--- + +## Table of Contents + +- [April Dunford Positioning](#april-dunford-positioning) +- [Geoffrey Moore Positioning](#geoffrey-moore-positioning) +- [Positioning Validation](#positioning-validation) +- [Competitive Positioning Map](#competitive-positioning-map) + +--- + +## April Dunford Positioning + +### The 5-Step Process + +Execute positioning using April Dunford's "Obviously Awesome" methodology: + +1. List competitive alternatives (what customers would use instead) +2. Isolate unique attributes (features only you have) +3. Map attributes to value (why each attribute matters) +4. Define best-fit customers (who cares most about this value) +5. Choose market category (where you compete) +6. **Validation:** Best-fit customers articulate your value unprompted + +### Step 1: Competitive Alternatives + +Document what customers do without your product: + +| Alternative Type | Examples | How They Solve It | +|------------------|----------|-------------------| +| Direct competitor | Competitor A, B | Same category, different approach | +| Adjacent solution | Spreadsheets, email | Manual workaround | +| Build in-house | Custom development | Internal solution | +| Do nothing | Ignore problem | Accept status quo | + +**Interview Questions:** +- "Before using us, how did you handle this?" +- "What alternatives did you evaluate?" +- "What would you switch to if we disappeared?" + +### Step 2: Unique Attributes + +Identify capabilities competitors lack: + +``` +Attribute Audit: +1. Feature: [Real-time collaboration] + - Competitor A: No (async only) + - Competitor B: Partial (limited to 5 users) + - You: Yes (unlimited users, 50ms sync) + → Unique: Yes + +2. Feature: [AI automation] + - Competitor A: No + - Competitor B: No + - You: Yes (3 AI models) + → Unique: Yes + +3. Feature: [Integrations] + - Competitor A: 500+ + - Competitor B: 200+ + - You: 100 + → Unique: No (table stakes) +``` + +### Step 3: Attribute-Value Mapping + +Connect features to business outcomes: + +| Attribute | Value Enabled | Customer Outcome | +|-----------|--------------|------------------| +| Real-time sync | No version conflicts | 50% fewer errors | +| AI automation | Eliminates manual work | Save 10 hrs/week | +| One-click deploy | Faster releases | Ship 2x faster | + +**Value Statement Formula:** +`[Feature] enables [Value] so customers achieve [Outcome]` + +### Step 4: Best-Fit Customers + +Define who values your unique attributes most: + +``` +Best-Fit Profile: +- Company size: 200-2000 employees +- Industry: SaaS, Professional Services +- Pain: Distributed teams, collaboration bottlenecks +- Evidence: + - Fastest sales cycles (45 days vs. 75 avg) + - Lowest churn (3% vs. 8% avg) + - Highest NPS (65 vs. 45 avg) +``` + +### Step 5: Market Category + +Choose competitive frame: + +| Strategy | When to Use | Risk Level | +|----------|-------------|------------| +| Head-to-head | Strong product, big budget | Medium | +| Niche domination | Unique for segment | Low | +| Category creation | True innovation, deep pockets | High | + +**Decision Framework:** +- Can you win head-to-head? → Head-to-head +- Can you dominate a niche? → Niche +- Is the market undefined? → Category creation + +--- + +## Geoffrey Moore Positioning + +### Crossing the Chasm Framework + +Position for technology adoption lifecycle: + +``` +Technology Adoption Curve: +Innovators (2.5%) → Early Adopters (13.5%) → Early Majority (34%) + ↑ + THE CHASM +``` + +### Positioning Statement Template + +``` +FOR [target customer] +WHO [statement of need or opportunity] +THE [product name] IS A [product category] +THAT [key benefit/reason to buy] +UNLIKE [primary competitive alternative] +OUR PRODUCT [primary differentiation] +``` + +**Example:** +``` +FOR mid-market SaaS companies with distributed engineering teams +WHO struggle with coordination across time zones +THE Acme Platform IS A real-time collaboration workspace +THAT eliminates version conflicts and communication delays +UNLIKE Slack and email which create information silos +OUR PRODUCT provides unified project context with AI-powered summaries +``` + +### Whole Product Concept + +Define complete solution for target segment: + +| Layer | Components | Your Coverage | +|-------|------------|---------------| +| Generic | Core product | 100% | +| Expected | Basic integrations, support | 90% | +| Augmented | Training, consulting, custom work | 60% | +| Potential | Future roadmap, ecosystem | 30% | + +**Gap Analysis:** +- What's missing for complete solution? +- Which partners can fill gaps? +- What must you build vs. buy vs. partner? + +--- + +## Positioning Validation + +### Customer Interview Protocol + +Validate positioning with target customers: + +1. Schedule 15-20 minute calls with 10+ target customers +2. Ask open-ended questions (no leading) +3. Document exact language used +4. Look for patterns across interviews +5. **Validation:** 7+ of 10 describe value similarly + +**Interview Script:** + +``` +Opening (2 min): +"Thanks for your time. I want to understand how you think about +[product category] and your experience with our product." + +Questions (10 min): +1. "How would you describe [Product] to a colleague?" +2. "What problem does [Product] solve for you?" +3. "What alternatives did you consider?" +4. "Why did you choose us over [alternative]?" +5. "What would make you stop using us?" + +Closing (3 min): +"Is there anything else you'd like to share?" +``` + +### Quantitative Validation + +Test messaging through A/B experiments: + +| Test | Control | Variant | Winner Criteria | +|------|---------|---------|-----------------| +| Landing page headline | Old positioning | New positioning | +20% conversion | +| Ad copy | Feature-focused | Value-focused | +15% CTR | +| Email subject | Generic | Personalized | +25% open rate | + +**Sample Size Calculator:** +- Baseline conversion: 3% +- Minimum detectable effect: 20% relative lift +- Statistical power: 80% +- Required sample: ~2,500 per variant + +--- + +## Competitive Positioning Map + +### 2x2 Matrix Construction + +Create visual positioning map: + +``` + HIGH PRICE + │ + Enterprise │ Premium + (Salesforce) │ (You?) + │ + ────────────────────┼────────────────── + LOW │ HIGH + EASE OF USE │ EASE OF USE + │ + Legacy │ Self-Serve + (Oracle) │ (Notion) + │ + LOW PRICE +``` + +### Axis Selection + +Choose dimensions that highlight your advantage: + +| Good Axes | Why | +|-----------|-----| +| Ease of use vs. Power | If you're easiest to use | +| Speed vs. Accuracy | If you're fastest | +| Price vs. Features | If you're best value | +| Specialization vs. Breadth | If you own a niche | + +| Bad Axes | Why | +|----------|-----| +| Quality vs. Price | Everyone claims quality | +| Innovation vs. Stability | Subjective, hard to prove | +| Customer vs. Product focus | Not differentiating | + +### Positioning Map Template + +``` +Market Category: [Your Category] +Date: [Month Year] + +Axes: +- X-axis: [Dimension 1] (Low → High) +- Y-axis: [Dimension 2] (Low → High) + +Quadrants: +- Top-left: [Quadrant description] +- Top-right: [Quadrant description] ← Your target +- Bottom-left: [Quadrant description] +- Bottom-right: [Quadrant description] + +Competitors: +1. [Competitor A]: Position (X, Y), Why +2. [Competitor B]: Position (X, Y), Why +3. [You]: Position (X, Y), Why you win + +Strategic Implications: +- Attack: [How to position against Competitor A] +- Defend: [How to protect against Competitor B] +- Differentiate: [Your unique positioning claim] +``` diff --git a/skills/nano-banana-pro/SKILL.md b/skills/nano-banana-pro/SKILL.md new file mode 100644 index 0000000..711ee3f --- /dev/null +++ b/skills/nano-banana-pro/SKILL.md @@ -0,0 +1,130 @@ +--- +name: nano-banana-pro +description: Generate/edit images with Nano Banana Pro (Gemini 3 Pro Image). Use for image create/modify requests incl. edits. Supports text-to-image + image-to-image; 1K/2K/4K; use --input-image. +--- + +# Nano Banana Pro Image Generation & Editing + +Generate new images or edit existing ones using Google's Nano Banana Pro API (Gemini 3 Pro Image). + +## Usage + +Run the script using absolute path (do NOT cd to skill directory first): + +**Generate new image:** +```bash +uv run ~/.codex/skills/nano-banana-pro/scripts/generate_image.py --prompt "your image description" --filename "output-name.png" [--resolution 1K|2K|4K] [--api-key KEY] +``` + +**Edit existing image:** +```bash +uv run ~/.codex/skills/nano-banana-pro/scripts/generate_image.py --prompt "editing instructions" --filename "output-name.png" --input-image "path/to/input.png" [--resolution 1K|2K|4K] [--api-key KEY] +``` + +**Important:** Always run from the user's current working directory so images are saved where the user is working, not in the skill directory. + +## Default Workflow (draft → iterate → final) + +Goal: fast iteration without burning time on 4K until the prompt is correct. + +- Draft (1K): quick feedback loop + - `uv run ~/.codex/skills/nano-banana-pro/scripts/generate_image.py --prompt "" --filename "yyyy-mm-dd-hh-mm-ss-draft.png" --resolution 1K` +- Iterate: adjust prompt in small diffs; keep filename new per run + - If editing: keep the same `--input-image` for every iteration until you’re happy. +- Final (4K): only when prompt is locked + - `uv run ~/.codex/skills/nano-banana-pro/scripts/generate_image.py --prompt "" --filename "yyyy-mm-dd-hh-mm-ss-final.png" --resolution 4K` + +## Resolution Options + +The Gemini 3 Pro Image API supports three resolutions (uppercase K required): + +- **1K** (default) - ~1024px resolution +- **2K** - ~2048px resolution +- **4K** - ~4096px resolution + +Map user requests to API parameters: +- No mention of resolution → `1K` +- "low resolution", "1080", "1080p", "1K" → `1K` +- "2K", "2048", "normal", "medium resolution" → `2K` +- "high resolution", "high-res", "hi-res", "4K", "ultra" → `4K` + +## API Key + +The script checks for API key in this order: +1. `--api-key` argument (use if user provided key in chat) +2. `GEMINI_API_KEY` environment variable + +If neither is available, the script exits with an error message. + +## Preflight + Common Failures (fast fixes) + +- Preflight: + - `command -v uv` (must exist) + - `test -n \"$GEMINI_API_KEY\"` (or pass `--api-key`) + - If editing: `test -f \"path/to/input.png\"` + +- Common failures: + - `Error: No API key provided.` → set `GEMINI_API_KEY` or pass `--api-key` + - `Error loading input image:` → wrong path / unreadable file; verify `--input-image` points to a real image + - “quota/permission/403” style API errors → wrong key, no access, or quota exceeded; try a different key/account + +## Filename Generation + +Generate filenames with the pattern: `yyyy-mm-dd-hh-mm-ss-name.png` + +**Format:** `{timestamp}-{descriptive-name}.png` +- Timestamp: Current date/time in format `yyyy-mm-dd-hh-mm-ss` (24-hour format) +- Name: Descriptive lowercase text with hyphens +- Keep the descriptive part concise (1-5 words typically) +- Use context from user's prompt or conversation +- If unclear, use random identifier (e.g., `x9k2`, `a7b3`) + +Examples: +- Prompt "A serene Japanese garden" → `2025-11-23-14-23-05-japanese-garden.png` +- Prompt "sunset over mountains" → `2025-11-23-15-30-12-sunset-mountains.png` +- Prompt "create an image of a robot" → `2025-11-23-16-45-33-robot.png` +- Unclear context → `2025-11-23-17-12-48-x9k2.png` + +## Image Editing + +When the user wants to modify an existing image: +1. Check if they provide an image path or reference an image in the current directory +2. Use `--input-image` parameter with the path to the image +3. The prompt should contain editing instructions (e.g., "make the sky more dramatic", "remove the person", "change to cartoon style") +4. Common editing tasks: add/remove elements, change style, adjust colors, blur background, etc. + +## Prompt Handling + +**For generation:** Pass user's image description as-is to `--prompt`. Only rework if clearly insufficient. + +**For editing:** Pass editing instructions in `--prompt` (e.g., "add a rainbow in the sky", "make it look like a watercolor painting") + +Preserve user's creative intent in both cases. + +## Prompt Templates (high hit-rate) + +Use templates when the user is vague or when edits must be precise. + +- Generation template: + - “Create an image of: . Style: ", + `` + ].join("") + result.join(""); + return { value: html2, size: html2.length }; + }); + return { html, pageId: snapshot.pageId, frameId: snapshot.frameId, index: this._index }; + } + resourceByUrl(url, method) { + const snapshot = this._snapshot; + let sameFrameResource; + let otherFrameResource; + for (const resource of this._resources) { + if (typeof resource._monotonicTime === "number" && resource._monotonicTime >= snapshot.timestamp) + break; + if (resource.response.status === 304) { + continue; + } + if (resource.request.url === url && resource.request.method === method) { + if (resource._frameref === snapshot.frameId) + sameFrameResource = resource; + else + otherFrameResource = resource; + } + } + let result = sameFrameResource ?? otherFrameResource; + if (result && method.toUpperCase() === "GET") { + let override = snapshot.resourceOverrides.find((o) => o.url === url); + if (override?.ref) { + const index = this._index - override.ref; + if (index >= 0 && index < this._snapshots.length) + override = this._snapshots[index].resourceOverrides.find((o) => o.url === url); + } + if (override?.sha1) { + result = { + ...result, + response: { + ...result.response, + content: { + ...result.response.content, + _sha1: override.sha1 + } + } + }; + } + } + return result; + } +} +const autoClosing = /* @__PURE__ */ new Set(["AREA", "BASE", "BR", "COL", "COMMAND", "EMBED", "HR", "IMG", "INPUT", "KEYGEN", "LINK", "MENUITEM", "META", "PARAM", "SOURCE", "TRACK", "WBR"]); +function snapshotNodes(snapshot) { + if (!snapshot._nodes) { + const nodes = []; + const visit = (n) => { + if (typeof n === "string") { + nodes.push(n); + } else if (isNodeNameAttributesChildNodesSnapshot(n)) { + const [, , ...children] = n; + for (const child of children) + visit(child); + nodes.push(n); + } + }; + visit(snapshot.html); + snapshot._nodes = nodes; + } + return snapshot._nodes; +} +function snapshotScript(viewport, ...targetIds) { + function applyPlaywrightAttributes(viewport2, ...targetIds2) { + const win = window; + const searchParams = new URLSearchParams(win.location.search); + const shouldPopulateCanvasFromScreenshot = searchParams.has("shouldPopulateCanvasFromScreenshot"); + const isUnderTest = searchParams.has("isUnderTest"); + const frameBoundingRectsInfo = { + viewport: viewport2, + frames: /* @__PURE__ */ new WeakMap() + }; + win["__playwright_frame_bounding_rects__"] = frameBoundingRectsInfo; + const kPointerWarningTitle = "Recorded click position in absolute coordinates did not match the center of the clicked element. This is likely due to a difference between the test runner and the trace viewer operating systems."; + const scrollTops = []; + const scrollLefts = []; + const targetElements = []; + const canvasElements = []; + let topSnapshotWindow = win; + while (topSnapshotWindow !== topSnapshotWindow.parent && !topSnapshotWindow.location.pathname.match(/\/page@[a-z0-9]+$/)) + topSnapshotWindow = topSnapshotWindow.parent; + const visit = (root) => { + for (const e of root.querySelectorAll(`[__playwright_scroll_top_]`)) + scrollTops.push(e); + for (const e of root.querySelectorAll(`[__playwright_scroll_left_]`)) + scrollLefts.push(e); + for (const element of root.querySelectorAll(`[__playwright_value_]`)) { + const inputElement = element; + if (inputElement.type !== "file") + inputElement.value = inputElement.getAttribute("__playwright_value_"); + element.removeAttribute("__playwright_value_"); + } + for (const element of root.querySelectorAll(`[__playwright_checked_]`)) { + element.checked = element.getAttribute("__playwright_checked_") === "true"; + element.removeAttribute("__playwright_checked_"); + } + for (const element of root.querySelectorAll(`[__playwright_selected_]`)) { + element.selected = element.getAttribute("__playwright_selected_") === "true"; + element.removeAttribute("__playwright_selected_"); + } + for (const element of root.querySelectorAll(`[__playwright_popover_open_]`)) { + try { + element.showPopover(); + } catch { + } + element.removeAttribute("__playwright_popover_open_"); + } + for (const element of root.querySelectorAll(`[__playwright_dialog_open_]`)) { + try { + if (element.getAttribute("__playwright_dialog_open_") === "modal") + element.showModal(); + else + element.show(); + } catch { + } + element.removeAttribute("__playwright_dialog_open_"); + } + for (const targetId of targetIds2) { + for (const target of root.querySelectorAll(`[__playwright_target__="${targetId}"]`)) { + const style = target.style; + style.outline = "2px solid #006ab1"; + style.backgroundColor = "#6fa8dc7f"; + targetElements.push(target); + } + } + for (const iframe of root.querySelectorAll("iframe, frame")) { + const boundingRectJson = iframe.getAttribute("__playwright_bounding_rect__"); + iframe.removeAttribute("__playwright_bounding_rect__"); + const boundingRect = boundingRectJson ? JSON.parse(boundingRectJson) : void 0; + if (boundingRect) + frameBoundingRectsInfo.frames.set(iframe, { boundingRect, scrollLeft: 0, scrollTop: 0 }); + const src = iframe.getAttribute("__playwright_src__"); + if (!src) { + iframe.setAttribute("src", 'data:text/html,'); + } else { + const url = new URL(win.location.href); + const index = url.pathname.lastIndexOf("/snapshot/"); + if (index !== -1) + url.pathname = url.pathname.substring(0, index + 1); + url.pathname += src.substring(1); + iframe.setAttribute("src", url.toString()); + } + } + { + const body = root.querySelector(`body[__playwright_custom_elements__]`); + if (body && win.customElements) { + const customElements = (body.getAttribute("__playwright_custom_elements__") || "").split(","); + for (const elementName of customElements) + win.customElements.define(elementName, class extends HTMLElement { + }); + } + } + for (const element of root.querySelectorAll(`template[__playwright_shadow_root_]`)) { + const template = element; + const shadowRoot = template.parentElement.attachShadow({ mode: "open" }); + shadowRoot.appendChild(template.content); + template.remove(); + visit(shadowRoot); + } + for (const element of root.querySelectorAll("a")) + element.addEventListener("click", (event) => { + event.preventDefault(); + }); + if ("adoptedStyleSheets" in root) { + const adoptedSheets = [...root.adoptedStyleSheets]; + for (const element of root.querySelectorAll(`template[__playwright_style_sheet_]`)) { + const template = element; + const sheet = new CSSStyleSheet(); + sheet.replaceSync(template.getAttribute("__playwright_style_sheet_")); + adoptedSheets.push(sheet); + } + root.adoptedStyleSheets = adoptedSheets; + } + canvasElements.push(...root.querySelectorAll("canvas")); + }; + const onLoad = () => { + win.removeEventListener("load", onLoad); + for (const element of scrollTops) { + element.scrollTop = +element.getAttribute("__playwright_scroll_top_"); + element.removeAttribute("__playwright_scroll_top_"); + if (frameBoundingRectsInfo.frames.has(element)) + frameBoundingRectsInfo.frames.get(element).scrollTop = element.scrollTop; + } + for (const element of scrollLefts) { + element.scrollLeft = +element.getAttribute("__playwright_scroll_left_"); + element.removeAttribute("__playwright_scroll_left_"); + if (frameBoundingRectsInfo.frames.has(element)) + frameBoundingRectsInfo.frames.get(element).scrollLeft = element.scrollLeft; + } + win.document.styleSheets[0].disabled = true; + const search = new URL(win.location.href).searchParams; + const isTopFrame = win === topSnapshotWindow; + if (search.get("pointX") && search.get("pointY")) { + const pointX = +search.get("pointX"); + const pointY = +search.get("pointY"); + const hasInputTarget = search.has("hasInputTarget"); + const hasTargetElements = targetElements.length > 0; + const roots = win.document.documentElement ? [win.document.documentElement] : []; + for (const target of hasTargetElements ? targetElements : roots) { + const pointElement = win.document.createElement("x-pw-pointer"); + pointElement.style.position = "fixed"; + pointElement.style.backgroundColor = "#f44336"; + pointElement.style.width = "20px"; + pointElement.style.height = "20px"; + pointElement.style.borderRadius = "10px"; + pointElement.style.margin = "-10px 0 0 -10px"; + pointElement.style.zIndex = "2147483646"; + pointElement.style.display = "flex"; + pointElement.style.alignItems = "center"; + pointElement.style.justifyContent = "center"; + if (hasTargetElements) { + const box = target.getBoundingClientRect(); + const centerX = box.left + box.width / 2; + const centerY = box.top + box.height / 2; + pointElement.style.left = centerX + "px"; + pointElement.style.top = centerY + "px"; + if (isTopFrame && (Math.abs(centerX - pointX) >= 10 || Math.abs(centerY - pointY) >= 10)) { + const warningElement = win.document.createElement("x-pw-pointer-warning"); + warningElement.textContent = "\u26A0"; + warningElement.style.fontSize = "19px"; + warningElement.style.color = "white"; + warningElement.style.marginTop = "-3.5px"; + warningElement.style.userSelect = "none"; + pointElement.appendChild(warningElement); + pointElement.setAttribute("title", kPointerWarningTitle); + } + win.document.documentElement.appendChild(pointElement); + } else if (isTopFrame && !hasInputTarget) { + pointElement.style.left = pointX + "px"; + pointElement.style.top = pointY + "px"; + win.document.documentElement.appendChild(pointElement); + } + } + } + if (canvasElements.length > 0) { + let drawCheckerboard2 = function(context, canvas) { + function createCheckerboardPattern() { + const pattern = win.document.createElement("canvas"); + pattern.width = pattern.width / Math.floor(pattern.width / 24); + pattern.height = pattern.height / Math.floor(pattern.height / 24); + const context2 = pattern.getContext("2d"); + context2.fillStyle = "lightgray"; + context2.fillRect(0, 0, pattern.width, pattern.height); + context2.fillStyle = "white"; + context2.fillRect(0, 0, pattern.width / 2, pattern.height / 2); + context2.fillRect(pattern.width / 2, pattern.height / 2, pattern.width, pattern.height); + return context2.createPattern(pattern, "repeat"); + } + context.fillStyle = createCheckerboardPattern(); + context.fillRect(0, 0, canvas.width, canvas.height); + }; + var drawCheckerboard = drawCheckerboard2; + const img = new Image(); + img.onload = () => { + for (const canvas of canvasElements) { + const context = canvas.getContext("2d"); + const boundingRectAttribute = canvas.getAttribute("__playwright_bounding_rect__"); + canvas.removeAttribute("__playwright_bounding_rect__"); + if (!boundingRectAttribute) + continue; + let boundingRect; + try { + boundingRect = JSON.parse(boundingRectAttribute); + } catch (e) { + continue; + } + let currWindow = win; + while (currWindow !== topSnapshotWindow) { + const iframe = currWindow.frameElement; + currWindow = currWindow.parent; + const iframeInfo = currWindow["__playwright_frame_bounding_rects__"]?.frames.get(iframe); + if (!iframeInfo?.boundingRect) + break; + const leftOffset = iframeInfo.boundingRect.left - iframeInfo.scrollLeft; + const topOffset = iframeInfo.boundingRect.top - iframeInfo.scrollTop; + boundingRect.left += leftOffset; + boundingRect.top += topOffset; + boundingRect.right += leftOffset; + boundingRect.bottom += topOffset; + } + const { width, height } = topSnapshotWindow["__playwright_frame_bounding_rects__"].viewport; + boundingRect.left = boundingRect.left / width; + boundingRect.top = boundingRect.top / height; + boundingRect.right = boundingRect.right / width; + boundingRect.bottom = boundingRect.bottom / height; + const partiallyUncaptured = boundingRect.right > 1 || boundingRect.bottom > 1; + const fullyUncaptured = boundingRect.left > 1 || boundingRect.top > 1; + if (fullyUncaptured) { + canvas.title = `Playwright couldn't capture canvas contents because it's located outside the viewport.`; + continue; + } + drawCheckerboard2(context, canvas); + if (shouldPopulateCanvasFromScreenshot) { + context.drawImage(img, boundingRect.left * img.width, boundingRect.top * img.height, (boundingRect.right - boundingRect.left) * img.width, (boundingRect.bottom - boundingRect.top) * img.height, 0, 0, canvas.width, canvas.height); + if (partiallyUncaptured) + canvas.title = `Playwright couldn't capture full canvas contents because it's located partially outside the viewport.`; + else + canvas.title = `Canvas contents are displayed on a best-effort basis based on viewport screenshots taken during test execution.`; + } else { + canvas.title = "Canvas content display is disabled."; + } + if (isUnderTest) + console.log(`canvas drawn:`, JSON.stringify([boundingRect.left, boundingRect.top, boundingRect.right - boundingRect.left, boundingRect.bottom - boundingRect.top].map((v) => Math.floor(v * 100)))); + } + }; + img.onerror = () => { + for (const canvas of canvasElements) { + const context = canvas.getContext("2d"); + drawCheckerboard2(context, canvas); + canvas.title = `Playwright couldn't show canvas contents because the screenshot failed to load.`; + } + }; + img.src = location.href.replace("/snapshot", "/closest-screenshot"); + } + }; + const onDOMContentLoaded = () => visit(win.document); + win.addEventListener("load", onLoad); + win.addEventListener("DOMContentLoaded", onDOMContentLoaded); + } + return ` +(${applyPlaywrightAttributes.toString()})(${JSON.stringify(viewport)}${targetIds.map((id) => `, "${id}"`).join("")})`; +} +const schemas = ["about:", "blob:", "data:", "file:", "ftp:", "http:", "https:", "mailto:", "sftp:", "ws:", "wss:"]; +const kLegacyBlobPrefix = "http://playwright.bloburl/#"; +function rewriteURLForCustomProtocol(href) { + if (href.startsWith(kLegacyBlobPrefix)) + href = href.substring(kLegacyBlobPrefix.length); + try { + const url = new URL(href); + if (url.protocol === "javascript:" || url.protocol === "vbscript:") + return "javascript:void(0)"; + const isBlob = url.protocol === "blob:"; + const isFile = url.protocol === "file:"; + if (!isBlob && !isFile && schemas.includes(url.protocol)) + return href; + const prefix = "pw-" + url.protocol.slice(0, url.protocol.length - 1); + if (!isFile) + url.protocol = "https:"; + url.hostname = url.hostname ? `${prefix}--${url.hostname}` : prefix; + if (isFile) { + url.protocol = "https:"; + } + return url.toString(); + } catch { + return href; + } +} +const urlInCSSRegex = /url\(['"]?([\w-]+:)\/\//ig; +function rewriteURLsInStyleSheetForCustomProtocol(text) { + return text.replace(urlInCSSRegex, (match, protocol) => { + const isBlob = protocol === "blob:"; + const isFile = protocol === "file:"; + if (!isBlob && !isFile && schemas.includes(protocol)) + return match; + return match.replace(protocol + "//", `https://pw-${protocol.slice(0, -1)}--`); + }); +} +const urlToEscapeRegex1 = /url\(\s*'([^']*)'\s*\)/ig; +const urlToEscapeRegex2 = /url\(\s*"([^"]*)"\s*\)/ig; +function escapeURLsInStyleSheet(text) { + const replacer = (match, url) => { + if (url.includes(" { + for (var name in all) + __defProp(target, name, { get: all[name], enumerable: true }); +}; +var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; +}; +var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); +var snapshotServer_exports = {}; +__export(snapshotServer_exports, { + SnapshotServer: () => SnapshotServer +}); +module.exports = __toCommonJS(snapshotServer_exports); +class SnapshotServer { + constructor(snapshotStorage, resourceLoader) { + this._snapshotIds = /* @__PURE__ */ new Map(); + this._snapshotStorage = snapshotStorage; + this._resourceLoader = resourceLoader; + } + serveSnapshot(pageOrFrameId, searchParams, snapshotUrl) { + const snapshot = this._snapshot(pageOrFrameId, searchParams); + if (!snapshot) + return new Response(null, { status: 404 }); + const renderedSnapshot = snapshot.render(); + this._snapshotIds.set(snapshotUrl, snapshot); + return new Response(renderedSnapshot.html, { status: 200, headers: { "Content-Type": "text/html; charset=utf-8" } }); + } + async serveClosestScreenshot(pageOrFrameId, searchParams) { + const snapshot = this._snapshot(pageOrFrameId, searchParams); + const sha1 = snapshot?.closestScreenshot(); + if (!sha1) + return new Response(null, { status: 404 }); + return new Response(await this._resourceLoader(sha1)); + } + serveSnapshotInfo(pageOrFrameId, searchParams) { + const snapshot = this._snapshot(pageOrFrameId, searchParams); + return this._respondWithJson(snapshot ? { + viewport: snapshot.viewport(), + url: snapshot.snapshot().frameUrl, + timestamp: snapshot.snapshot().timestamp, + wallTime: snapshot.snapshot().wallTime + } : { + error: "No snapshot found" + }); + } + _snapshot(pageOrFrameId, params) { + const name = params.get("name"); + return this._snapshotStorage.snapshotByName(pageOrFrameId, name); + } + _respondWithJson(object) { + return new Response(JSON.stringify(object), { + status: 200, + headers: { + "Cache-Control": "public, max-age=31536000", + "Content-Type": "application/json" + } + }); + } + async serveResource(requestUrlAlternatives, method, snapshotUrl) { + let resource; + const snapshot = this._snapshotIds.get(snapshotUrl); + for (const requestUrl of requestUrlAlternatives) { + resource = snapshot?.resourceByUrl(removeHash(requestUrl), method); + if (resource) + break; + } + if (!resource) + return new Response(null, { status: 404 }); + const sha1 = resource.response.content._sha1; + const content = sha1 ? await this._resourceLoader(sha1) || new Blob([]) : new Blob([]); + let contentType = resource.response.content.mimeType; + const isTextEncoding = /^text\/|^application\/(javascript|json)/.test(contentType); + if (isTextEncoding && !contentType.includes("charset")) + contentType = `${contentType}; charset=utf-8`; + const headers = new Headers(); + if (contentType !== "x-unknown") + headers.set("Content-Type", contentType); + for (const { name, value } of resource.response.headers) + headers.set(name, value); + headers.delete("Content-Encoding"); + headers.delete("Access-Control-Allow-Origin"); + headers.set("Access-Control-Allow-Origin", "*"); + headers.delete("Content-Length"); + headers.set("Content-Length", String(content.size)); + if (this._snapshotStorage.hasResourceOverride(resource.request.url)) + headers.set("Cache-Control", "no-store, no-cache, max-age=0"); + else + headers.set("Cache-Control", "public, max-age=31536000"); + const { status } = resource.response; + const isNullBodyStatus = status === 101 || status === 204 || status === 205 || status === 304; + return new Response(isNullBodyStatus ? null : content, { + headers, + status: resource.response.status, + statusText: resource.response.statusText + }); + } +} +function removeHash(url) { + try { + const u = new URL(url); + u.hash = ""; + return u.toString(); + } catch (e) { + return url; + } +} +// Annotate the CommonJS export names for ESM import in node: +0 && (module.exports = { + SnapshotServer +}); diff --git a/skills/playwright-scraper-skill-1-2-0/node_modules/playwright-core/lib/utils/isomorphic/trace/snapshotStorage.js b/skills/playwright-scraper-skill-1-2-0/node_modules/playwright-core/lib/utils/isomorphic/trace/snapshotStorage.js new file mode 100644 index 0000000..d251f31 --- /dev/null +++ b/skills/playwright-scraper-skill-1-2-0/node_modules/playwright-core/lib/utils/isomorphic/trace/snapshotStorage.js @@ -0,0 +1,89 @@ +"use strict"; +var __defProp = Object.defineProperty; +var __getOwnPropDesc = Object.getOwnPropertyDescriptor; +var __getOwnPropNames = Object.getOwnPropertyNames; +var __hasOwnProp = Object.prototype.hasOwnProperty; +var __export = (target, all) => { + for (var name in all) + __defProp(target, name, { get: all[name], enumerable: true }); +}; +var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; +}; +var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); +var snapshotStorage_exports = {}; +__export(snapshotStorage_exports, { + SnapshotStorage: () => SnapshotStorage +}); +module.exports = __toCommonJS(snapshotStorage_exports); +var import_snapshotRenderer = require("./snapshotRenderer"); +var import_lruCache = require("../lruCache"); +class SnapshotStorage { + constructor() { + this._frameSnapshots = /* @__PURE__ */ new Map(); + this._cache = new import_lruCache.LRUCache(1e8); + // 100MB per each trace + this._contextToResources = /* @__PURE__ */ new Map(); + this._resourceUrlsWithOverrides = /* @__PURE__ */ new Set(); + } + addResource(contextId, resource) { + resource.request.url = (0, import_snapshotRenderer.rewriteURLForCustomProtocol)(resource.request.url); + this._ensureResourcesForContext(contextId).push(resource); + } + addFrameSnapshot(contextId, snapshot, screencastFrames) { + for (const override of snapshot.resourceOverrides) + override.url = (0, import_snapshotRenderer.rewriteURLForCustomProtocol)(override.url); + let frameSnapshots = this._frameSnapshots.get(snapshot.frameId); + if (!frameSnapshots) { + frameSnapshots = { + raw: [], + renderers: [] + }; + this._frameSnapshots.set(snapshot.frameId, frameSnapshots); + if (snapshot.isMainFrame) + this._frameSnapshots.set(snapshot.pageId, frameSnapshots); + } + frameSnapshots.raw.push(snapshot); + const resources = this._ensureResourcesForContext(contextId); + const renderer = new import_snapshotRenderer.SnapshotRenderer(this._cache, resources, frameSnapshots.raw, screencastFrames, frameSnapshots.raw.length - 1); + frameSnapshots.renderers.push(renderer); + return renderer; + } + snapshotByName(pageOrFrameId, snapshotName) { + const snapshot = this._frameSnapshots.get(pageOrFrameId); + return snapshot?.renderers.find((r) => r.snapshotName === snapshotName); + } + snapshotsForTest() { + return [...this._frameSnapshots.keys()]; + } + finalize() { + for (const resources of this._contextToResources.values()) + resources.sort((a, b) => (a._monotonicTime || 0) - (b._monotonicTime || 0)); + for (const frameSnapshots of this._frameSnapshots.values()) { + for (const snapshot of frameSnapshots.raw) { + for (const override of snapshot.resourceOverrides) + this._resourceUrlsWithOverrides.add(override.url); + } + } + } + hasResourceOverride(url) { + return this._resourceUrlsWithOverrides.has(url); + } + _ensureResourcesForContext(contextId) { + let resources = this._contextToResources.get(contextId); + if (!resources) { + resources = []; + this._contextToResources.set(contextId, resources); + } + return resources; + } +} +// Annotate the CommonJS export names for ESM import in node: +0 && (module.exports = { + SnapshotStorage +}); diff --git a/skills/playwright-scraper-skill-1-2-0/node_modules/playwright-core/lib/utils/isomorphic/trace/traceLoader.js b/skills/playwright-scraper-skill-1-2-0/node_modules/playwright-core/lib/utils/isomorphic/trace/traceLoader.js new file mode 100644 index 0000000..7e39d2c --- /dev/null +++ b/skills/playwright-scraper-skill-1-2-0/node_modules/playwright-core/lib/utils/isomorphic/trace/traceLoader.js @@ -0,0 +1,131 @@ +"use strict"; +var __defProp = Object.defineProperty; +var __getOwnPropDesc = Object.getOwnPropertyDescriptor; +var __getOwnPropNames = Object.getOwnPropertyNames; +var __hasOwnProp = Object.prototype.hasOwnProperty; +var __export = (target, all) => { + for (var name in all) + __defProp(target, name, { get: all[name], enumerable: true }); +}; +var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; +}; +var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); +var traceLoader_exports = {}; +__export(traceLoader_exports, { + TraceLoader: () => TraceLoader +}); +module.exports = __toCommonJS(traceLoader_exports); +var import_traceUtils = require("@isomorphic/traceUtils"); +var import_snapshotStorage = require("./snapshotStorage"); +var import_traceModernizer = require("./traceModernizer"); +class TraceLoader { + constructor() { + this.contextEntries = []; + this._resourceToContentType = /* @__PURE__ */ new Map(); + } + async load(backend, unzipProgress) { + this._backend = backend; + const ordinals = []; + let hasSource = false; + for (const entryName of await this._backend.entryNames()) { + const match = entryName.match(/(.+)\.trace$/); + if (match) + ordinals.push(match[1] || ""); + if (entryName.includes("src@")) + hasSource = true; + } + if (!ordinals.length) + throw new Error("Cannot find .trace file"); + this._snapshotStorage = new import_snapshotStorage.SnapshotStorage(); + const total = ordinals.length * 3; + let done = 0; + for (const ordinal of ordinals) { + const contextEntry = createEmptyContext(); + contextEntry.hasSource = hasSource; + const modernizer = new import_traceModernizer.TraceModernizer(contextEntry, this._snapshotStorage); + const trace = await this._backend.readText(ordinal + ".trace") || ""; + modernizer.appendTrace(trace); + unzipProgress(++done, total); + const network = await this._backend.readText(ordinal + ".network") || ""; + modernizer.appendTrace(network); + unzipProgress(++done, total); + contextEntry.actions = modernizer.actions().sort((a1, a2) => a1.startTime - a2.startTime); + if (!backend.isLive()) { + for (const action of contextEntry.actions.slice().reverse()) { + if (!action.endTime && !action.error) { + for (const a of contextEntry.actions) { + if (a.parentId === action.callId && action.endTime < a.endTime) + action.endTime = a.endTime; + } + } + } + } + const stacks = await this._backend.readText(ordinal + ".stacks"); + if (stacks) { + const callMetadata = (0, import_traceUtils.parseClientSideCallMetadata)(JSON.parse(stacks)); + for (const action of contextEntry.actions) + action.stack = action.stack || callMetadata.get(action.callId); + } + unzipProgress(++done, total); + for (const resource of contextEntry.resources) { + if (resource.request.postData?._sha1) + this._resourceToContentType.set(resource.request.postData._sha1, stripEncodingFromContentType(resource.request.postData.mimeType)); + if (resource.response.content?._sha1) + this._resourceToContentType.set(resource.response.content._sha1, stripEncodingFromContentType(resource.response.content.mimeType)); + } + this.contextEntries.push(contextEntry); + } + this._snapshotStorage.finalize(); + } + async hasEntry(filename) { + return this._backend.hasEntry(filename); + } + async resourceForSha1(sha1) { + const blob = await this._backend.readBlob("resources/" + sha1); + const contentType = this._resourceToContentType.get(sha1); + if (!blob || contentType === void 0 || contentType === "x-unknown") + return blob; + return new Blob([blob], { type: contentType }); + } + storage() { + return this._snapshotStorage; + } +} +function stripEncodingFromContentType(contentType) { + const charset = contentType.match(/^(.*);\s*charset=.*$/); + if (charset) + return charset[1]; + return contentType; +} +function createEmptyContext() { + return { + origin: "testRunner", + startTime: Number.MAX_SAFE_INTEGER, + wallTime: Number.MAX_SAFE_INTEGER, + endTime: 0, + browserName: "", + options: { + deviceScaleFactor: 1, + isMobile: false, + viewport: { width: 1280, height: 800 } + }, + pages: [], + resources: [], + actions: [], + events: [], + errors: [], + stdio: [], + hasSource: false, + contextId: "" + }; +} +// Annotate the CommonJS export names for ESM import in node: +0 && (module.exports = { + TraceLoader +}); diff --git a/skills/playwright-scraper-skill-1-2-0/node_modules/playwright-core/lib/utils/isomorphic/trace/traceModel.js b/skills/playwright-scraper-skill-1-2-0/node_modules/playwright-core/lib/utils/isomorphic/trace/traceModel.js new file mode 100644 index 0000000..a507d6f --- /dev/null +++ b/skills/playwright-scraper-skill-1-2-0/node_modules/playwright-core/lib/utils/isomorphic/trace/traceModel.js @@ -0,0 +1,365 @@ +"use strict"; +var __defProp = Object.defineProperty; +var __getOwnPropDesc = Object.getOwnPropertyDescriptor; +var __getOwnPropNames = Object.getOwnPropertyNames; +var __hasOwnProp = Object.prototype.hasOwnProperty; +var __export = (target, all) => { + for (var name in all) + __defProp(target, name, { get: all[name], enumerable: true }); +}; +var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; +}; +var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); +var traceModel_exports = {}; +__export(traceModel_exports, { + TraceModel: () => TraceModel, + buildActionTree: () => buildActionTree, + context: () => context, + eventsForAction: () => eventsForAction, + nextActionByStartTime: () => nextActionByStartTime, + previousActionByEndTime: () => previousActionByEndTime, + stats: () => stats +}); +module.exports = __toCommonJS(traceModel_exports); +var import_protocolFormatter = require("@isomorphic/protocolFormatter"); +const contextSymbol = Symbol("context"); +const nextInContextSymbol = Symbol("nextInContext"); +const prevByEndTimeSymbol = Symbol("prevByEndTime"); +const nextByStartTimeSymbol = Symbol("nextByStartTime"); +const eventsSymbol = Symbol("events"); +class TraceModel { + constructor(traceUri, contexts) { + contexts.forEach((contextEntry) => indexModel(contextEntry)); + const libraryContext = contexts.find((context2) => context2.origin === "library"); + this.traceUri = traceUri; + this.browserName = libraryContext?.browserName || ""; + this.sdkLanguage = libraryContext?.sdkLanguage; + this.channel = libraryContext?.channel; + this.testIdAttributeName = libraryContext?.testIdAttributeName; + this.platform = libraryContext?.platform || ""; + this.playwrightVersion = contexts.find((c) => c.playwrightVersion)?.playwrightVersion; + this.title = libraryContext?.title || ""; + this.options = libraryContext?.options || {}; + this.actions = mergeActionsAndUpdateTiming(contexts); + this.pages = [].concat(...contexts.map((c) => c.pages)); + this.wallTime = contexts.map((c) => c.wallTime).reduce((prev, cur) => Math.min(prev || Number.MAX_VALUE, cur), Number.MAX_VALUE); + this.startTime = contexts.map((c) => c.startTime).reduce((prev, cur) => Math.min(prev, cur), Number.MAX_VALUE); + this.endTime = contexts.map((c) => c.endTime).reduce((prev, cur) => Math.max(prev, cur), Number.MIN_VALUE); + this.events = [].concat(...contexts.map((c) => c.events)); + this.stdio = [].concat(...contexts.map((c) => c.stdio)); + this.errors = [].concat(...contexts.map((c) => c.errors)); + this.hasSource = contexts.some((c) => c.hasSource); + this.hasStepData = contexts.some((context2) => context2.origin === "testRunner"); + this.resources = [...contexts.map((c) => c.resources)].flat(); + this.attachments = this.actions.flatMap((action) => action.attachments?.map((attachment) => ({ ...attachment, callId: action.callId, traceUri })) ?? []); + this.visibleAttachments = this.attachments.filter((attachment) => !attachment.name.startsWith("_")); + this.events.sort((a1, a2) => a1.time - a2.time); + this.resources.sort((a1, a2) => a1._monotonicTime - a2._monotonicTime); + this.errorDescriptors = this.hasStepData ? this._errorDescriptorsFromTestRunner() : this._errorDescriptorsFromActions(); + this.sources = collectSources(this.actions, this.errorDescriptors); + this.actionCounters = /* @__PURE__ */ new Map(); + for (const action of this.actions) { + action.group = action.group ?? (0, import_protocolFormatter.getActionGroup)({ type: action.class, method: action.method }); + if (action.group) + this.actionCounters.set(action.group, 1 + (this.actionCounters.get(action.group) || 0)); + } + } + createRelativeUrl(path) { + const url = new URL("http://localhost/" + path); + url.searchParams.set("trace", this.traceUri); + return url.toString().substring("http://localhost/".length); + } + failedAction() { + return this.actions.findLast((a) => a.error); + } + filteredActions(actionsFilter) { + const filter = new Set(actionsFilter); + return this.actions.filter((action) => !action.group || filter.has(action.group)); + } + renderActionTree(filter) { + const actions = this.filteredActions(filter ?? []); + const { rootItem } = buildActionTree(actions); + const actionTree = []; + const visit = (actionItem, indent) => { + const title = (0, import_protocolFormatter.renderTitleForCall)({ ...actionItem.action, type: actionItem.action.class }); + actionTree.push(`${indent}${title || actionItem.id}`); + for (const child of actionItem.children) + visit(child, indent + " "); + }; + rootItem.children.forEach((a) => visit(a, "")); + return actionTree; + } + _errorDescriptorsFromActions() { + const errors = []; + for (const action of this.actions || []) { + if (!action.error?.message) + continue; + errors.push({ + action, + stack: action.stack, + message: action.error.message + }); + } + return errors; + } + _errorDescriptorsFromTestRunner() { + return this.errors.filter((e) => !!e.message).map((error, i) => ({ + stack: error.stack, + message: error.message + })); + } +} +function indexModel(context2) { + for (const page of context2.pages) + page[contextSymbol] = context2; + for (let i = 0; i < context2.actions.length; ++i) { + const action = context2.actions[i]; + action[contextSymbol] = context2; + } + let lastNonRouteAction = void 0; + for (let i = context2.actions.length - 1; i >= 0; i--) { + const action = context2.actions[i]; + action[nextInContextSymbol] = lastNonRouteAction; + if (action.class !== "Route") + lastNonRouteAction = action; + } + for (const event of context2.events) + event[contextSymbol] = context2; + for (const resource of context2.resources) + resource[contextSymbol] = context2; +} +function mergeActionsAndUpdateTiming(contexts) { + const result = []; + const actions = mergeActionsAndUpdateTimingSameTrace(contexts); + result.push(...actions); + result.sort((a1, a2) => { + if (a2.parentId === a1.callId) + return 1; + if (a1.parentId === a2.callId) + return -1; + return a1.endTime - a2.endTime; + }); + for (let i = 1; i < result.length; ++i) + result[i][prevByEndTimeSymbol] = result[i - 1]; + result.sort((a1, a2) => { + if (a2.parentId === a1.callId) + return -1; + if (a1.parentId === a2.callId) + return 1; + return a1.startTime - a2.startTime; + }); + for (let i = 0; i + 1 < result.length; ++i) + result[i][nextByStartTimeSymbol] = result[i + 1]; + return result; +} +let lastTmpStepId = 0; +function mergeActionsAndUpdateTimingSameTrace(contexts) { + const map = /* @__PURE__ */ new Map(); + const libraryContexts = contexts.filter((context2) => context2.origin === "library"); + const testRunnerContexts = contexts.filter((context2) => context2.origin === "testRunner"); + if (!testRunnerContexts.length || !libraryContexts.length) { + return contexts.map((context2) => { + return context2.actions.map((action) => ({ ...action, context: context2 })); + }).flat(); + } + for (const context2 of libraryContexts) { + for (const action of context2.actions) { + map.set(action.stepId || `tmp-step@${++lastTmpStepId}`, { ...action, context: context2 }); + } + } + const delta = monotonicTimeDeltaBetweenLibraryAndRunner(testRunnerContexts, map); + if (delta) + adjustMonotonicTime(libraryContexts, delta); + const nonPrimaryIdToPrimaryId = /* @__PURE__ */ new Map(); + for (const context2 of testRunnerContexts) { + for (const action of context2.actions) { + const existing = action.stepId && map.get(action.stepId); + if (existing) { + nonPrimaryIdToPrimaryId.set(action.callId, existing.callId); + if (action.error) + existing.error = action.error; + if (action.attachments) + existing.attachments = action.attachments; + if (action.annotations) + existing.annotations = action.annotations; + if (action.parentId) + existing.parentId = nonPrimaryIdToPrimaryId.get(action.parentId) ?? action.parentId; + if (action.group) + existing.group = action.group; + existing.startTime = action.startTime; + existing.endTime = action.endTime; + continue; + } + if (action.parentId) + action.parentId = nonPrimaryIdToPrimaryId.get(action.parentId) ?? action.parentId; + map.set(action.stepId || `tmp-step@${++lastTmpStepId}`, { ...action, context: context2 }); + } + } + return [...map.values()]; +} +function adjustMonotonicTime(contexts, monotonicTimeDelta) { + for (const context2 of contexts) { + context2.startTime += monotonicTimeDelta; + context2.endTime += monotonicTimeDelta; + for (const action of context2.actions) { + if (action.startTime) + action.startTime += monotonicTimeDelta; + if (action.endTime) + action.endTime += monotonicTimeDelta; + } + for (const event of context2.events) + event.time += monotonicTimeDelta; + for (const event of context2.stdio) + event.timestamp += monotonicTimeDelta; + for (const page of context2.pages) { + for (const frame of page.screencastFrames) + frame.timestamp += monotonicTimeDelta; + } + for (const resource of context2.resources) { + if (resource._monotonicTime) + resource._monotonicTime += monotonicTimeDelta; + } + } +} +function monotonicTimeDeltaBetweenLibraryAndRunner(nonPrimaryContexts, libraryActions) { + for (const context2 of nonPrimaryContexts) { + for (const action of context2.actions) { + if (!action.startTime) + continue; + const libraryAction = action.stepId ? libraryActions.get(action.stepId) : void 0; + if (libraryAction) + return action.startTime - libraryAction.startTime; + } + } + return 0; +} +function buildActionTree(actions) { + const itemMap = /* @__PURE__ */ new Map(); + for (const action of actions) { + itemMap.set(action.callId, { + id: action.callId, + parent: void 0, + children: [], + action + }); + } + const rootItem = { action: { ...kFakeRootAction }, id: "", parent: void 0, children: [] }; + for (const item of itemMap.values()) { + rootItem.action.startTime = Math.min(rootItem.action.startTime, item.action.startTime); + rootItem.action.endTime = Math.max(rootItem.action.endTime, item.action.endTime); + const parent = item.action.parentId ? itemMap.get(item.action.parentId) || rootItem : rootItem; + parent.children.push(item); + item.parent = parent; + } + const inheritStack = (item) => { + for (const child of item.children) { + child.action.stack = child.action.stack ?? item.action.stack; + inheritStack(child); + } + }; + inheritStack(rootItem); + return { rootItem, itemMap }; +} +function context(action) { + return action[contextSymbol]; +} +function nextInContext(action) { + return action[nextInContextSymbol]; +} +function previousActionByEndTime(action) { + return action[prevByEndTimeSymbol]; +} +function nextActionByStartTime(action) { + return action[nextByStartTimeSymbol]; +} +function stats(action) { + let errors = 0; + let warnings = 0; + for (const event of eventsForAction(action)) { + if (event.type === "console") { + const type = event.messageType; + if (type === "warning") + ++warnings; + else if (type === "error") + ++errors; + } + if (event.type === "event" && event.method === "pageError") + ++errors; + } + return { errors, warnings }; +} +function eventsForAction(action) { + let result = action[eventsSymbol]; + if (result) + return result; + const nextAction = nextInContext(action); + result = context(action).events.filter((event) => { + return event.time >= action.startTime && (!nextAction || event.time < nextAction.startTime); + }); + action[eventsSymbol] = result; + return result; +} +function collectSources(actions, errorDescriptors) { + const result = /* @__PURE__ */ new Map(); + for (const action of actions) { + for (const frame of action.stack || []) { + let source = result.get(frame.file); + if (!source) { + source = { errors: [], content: void 0 }; + result.set(frame.file, source); + } + } + } + for (const error of errorDescriptors) { + const { action, stack, message } = error; + if (!action || !stack) + continue; + result.get(stack[0].file)?.errors.push({ + line: stack[0].line || 0, + message + }); + } + return result; +} +const kFakeRootAction = { + type: "action", + callId: "", + startTime: 0, + endTime: 0, + class: "", + method: "", + params: {}, + log: [], + context: { + origin: "library", + startTime: 0, + endTime: 0, + browserName: "", + wallTime: 0, + options: {}, + pages: [], + resources: [], + actions: [], + events: [], + stdio: [], + errors: [], + hasSource: false, + contextId: "" + } +}; +// Annotate the CommonJS export names for ESM import in node: +0 && (module.exports = { + TraceModel, + buildActionTree, + context, + eventsForAction, + nextActionByStartTime, + previousActionByEndTime, + stats +}); diff --git a/skills/playwright-scraper-skill-1-2-0/node_modules/playwright-core/lib/utils/isomorphic/trace/traceModernizer.js b/skills/playwright-scraper-skill-1-2-0/node_modules/playwright-core/lib/utils/isomorphic/trace/traceModernizer.js new file mode 100644 index 0000000..77b8f89 --- /dev/null +++ b/skills/playwright-scraper-skill-1-2-0/node_modules/playwright-core/lib/utils/isomorphic/trace/traceModernizer.js @@ -0,0 +1,400 @@ +"use strict"; +var __defProp = Object.defineProperty; +var __getOwnPropDesc = Object.getOwnPropertyDescriptor; +var __getOwnPropNames = Object.getOwnPropertyNames; +var __hasOwnProp = Object.prototype.hasOwnProperty; +var __export = (target, all) => { + for (var name in all) + __defProp(target, name, { get: all[name], enumerable: true }); +}; +var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; +}; +var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); +var traceModernizer_exports = {}; +__export(traceModernizer_exports, { + TraceModernizer: () => TraceModernizer, + TraceVersionError: () => TraceVersionError +}); +module.exports = __toCommonJS(traceModernizer_exports); +class TraceVersionError extends Error { + constructor(message) { + super(message); + this.name = "TraceVersionError"; + } +} +const latestVersion = 8; +class TraceModernizer { + constructor(contextEntry, snapshotStorage) { + this._actionMap = /* @__PURE__ */ new Map(); + this._pageEntries = /* @__PURE__ */ new Map(); + this._jsHandles = /* @__PURE__ */ new Map(); + this._consoleObjects = /* @__PURE__ */ new Map(); + this._contextEntry = contextEntry; + this._snapshotStorage = snapshotStorage; + } + appendTrace(trace) { + for (const line of trace.split("\n")) + this._appendEvent(line); + } + actions() { + return [...this._actionMap.values()]; + } + _pageEntry(pageId) { + let pageEntry = this._pageEntries.get(pageId); + if (!pageEntry) { + pageEntry = { + pageId, + screencastFrames: [] + }; + this._pageEntries.set(pageId, pageEntry); + this._contextEntry.pages.push(pageEntry); + } + return pageEntry; + } + _appendEvent(line) { + if (!line) + return; + const events = this._modernize(JSON.parse(line)); + for (const event of events) + this._innerAppendEvent(event); + } + _innerAppendEvent(event) { + const contextEntry = this._contextEntry; + switch (event.type) { + case "context-options": { + if (event.version > latestVersion) + throw new TraceVersionError("The trace was created by a newer version of Playwright and is not supported by this version of the viewer. Please use latest Playwright to open the trace."); + this._version = event.version; + contextEntry.origin = event.origin; + contextEntry.browserName = event.browserName; + contextEntry.channel = event.channel; + contextEntry.title = event.title; + contextEntry.platform = event.platform; + contextEntry.playwrightVersion = event.playwrightVersion; + contextEntry.wallTime = event.wallTime; + contextEntry.startTime = event.monotonicTime; + contextEntry.sdkLanguage = event.sdkLanguage; + contextEntry.options = event.options; + contextEntry.testIdAttributeName = event.testIdAttributeName; + contextEntry.contextId = event.contextId ?? ""; + break; + } + case "screencast-frame": { + this._pageEntry(event.pageId).screencastFrames.push(event); + break; + } + case "before": { + this._actionMap.set(event.callId, { ...event, type: "action", endTime: 0, log: [] }); + break; + } + case "input": { + const existing = this._actionMap.get(event.callId); + existing.inputSnapshot = event.inputSnapshot; + existing.point = event.point; + break; + } + case "log": { + const existing = this._actionMap.get(event.callId); + if (!existing) + return; + existing.log.push({ + time: event.time, + message: event.message + }); + break; + } + case "after": { + const existing = this._actionMap.get(event.callId); + existing.afterSnapshot = event.afterSnapshot; + existing.endTime = event.endTime; + existing.result = event.result; + existing.error = event.error; + existing.attachments = event.attachments; + existing.annotations = event.annotations; + if (event.point) + existing.point = event.point; + break; + } + case "action": { + this._actionMap.set(event.callId, { ...event, log: [] }); + break; + } + case "event": { + contextEntry.events.push(event); + break; + } + case "stdout": { + contextEntry.stdio.push(event); + break; + } + case "stderr": { + contextEntry.stdio.push(event); + break; + } + case "error": { + contextEntry.errors.push(event); + break; + } + case "console": { + contextEntry.events.push(event); + break; + } + case "resource-snapshot": + this._snapshotStorage.addResource(this._contextEntry.contextId, event.snapshot); + contextEntry.resources.push(event.snapshot); + break; + case "frame-snapshot": + this._snapshotStorage.addFrameSnapshot(this._contextEntry.contextId, event.snapshot, this._pageEntry(event.snapshot.pageId).screencastFrames); + break; + } + if ("pageId" in event && event.pageId) + this._pageEntry(event.pageId); + if (event.type === "action" || event.type === "before") + contextEntry.startTime = Math.min(contextEntry.startTime, event.startTime); + if (event.type === "action" || event.type === "after") + contextEntry.endTime = Math.max(contextEntry.endTime, event.endTime); + if (event.type === "event") { + contextEntry.startTime = Math.min(contextEntry.startTime, event.time); + contextEntry.endTime = Math.max(contextEntry.endTime, event.time); + } + if (event.type === "screencast-frame") { + contextEntry.startTime = Math.min(contextEntry.startTime, event.timestamp); + contextEntry.endTime = Math.max(contextEntry.endTime, event.timestamp); + } + } + _processedContextCreatedEvent() { + return this._version !== void 0; + } + _modernize(event) { + let version = this._version ?? event.version ?? 6; + let events = [event]; + for (; version < latestVersion; ++version) + events = this[`_modernize_${version}_to_${version + 1}`].call(this, events); + return events; + } + _modernize_0_to_1(events) { + for (const event of events) { + if (event.type !== "action") + continue; + if (typeof event.metadata.error === "string") + event.metadata.error = { error: { name: "Error", message: event.metadata.error } }; + } + return events; + } + _modernize_1_to_2(events) { + for (const event of events) { + if (event.type !== "frame-snapshot" || !event.snapshot.isMainFrame) + continue; + event.snapshot.viewport = this._contextEntry.options?.viewport || { width: 1280, height: 720 }; + } + return events; + } + _modernize_2_to_3(events) { + for (const event of events) { + if (event.type !== "resource-snapshot" || event.snapshot.request) + continue; + const resource = event.snapshot; + event.snapshot = { + _frameref: resource.frameId, + request: { + url: resource.url, + method: resource.method, + headers: resource.requestHeaders, + postData: resource.requestSha1 ? { _sha1: resource.requestSha1 } : void 0 + }, + response: { + status: resource.status, + headers: resource.responseHeaders, + content: { + mimeType: resource.contentType, + _sha1: resource.responseSha1 + } + }, + _monotonicTime: resource.timestamp + }; + } + return events; + } + _modernize_3_to_4(events) { + const result = []; + for (const event of events) { + const e = this._modernize_event_3_to_4(event); + if (e) + result.push(e); + } + return result; + } + _modernize_event_3_to_4(event) { + if (event.type !== "action" && event.type !== "event") { + return event; + } + const metadata = event.metadata; + if (metadata.internal || metadata.method.startsWith("tracing")) + return null; + if (event.type === "event") { + if (metadata.method === "__create__" && metadata.type === "ConsoleMessage") { + return { + type: "object", + class: metadata.type, + guid: metadata.params.guid, + initializer: metadata.params.initializer + }; + } + return { + type: "event", + time: metadata.startTime, + class: metadata.type, + method: metadata.method, + params: metadata.params, + pageId: metadata.pageId + }; + } + return { + type: "action", + callId: metadata.id, + startTime: metadata.startTime, + endTime: metadata.endTime, + apiName: metadata.apiName || metadata.type + "." + metadata.method, + class: metadata.type, + method: metadata.method, + params: metadata.params, + // eslint-disable-next-line no-restricted-globals + wallTime: metadata.wallTime || Date.now(), + log: metadata.log, + beforeSnapshot: metadata.snapshots.find((s) => s.title === "before")?.snapshotName, + inputSnapshot: metadata.snapshots.find((s) => s.title === "input")?.snapshotName, + afterSnapshot: metadata.snapshots.find((s) => s.title === "after")?.snapshotName, + error: metadata.error?.error, + result: metadata.result, + point: metadata.point, + pageId: metadata.pageId + }; + } + _modernize_4_to_5(events) { + const result = []; + for (const event of events) { + const e = this._modernize_event_4_to_5(event); + if (e) + result.push(e); + } + return result; + } + _modernize_event_4_to_5(event) { + if (event.type === "event" && event.method === "__create__" && event.class === "JSHandle") + this._jsHandles.set(event.params.guid, event.params.initializer); + if (event.type === "object") { + if (event.class !== "ConsoleMessage") + return null; + const args = event.initializer.args?.map((arg) => { + if (arg.guid) { + const handle = this._jsHandles.get(arg.guid); + return { preview: handle?.preview || "", value: "" }; + } + return { preview: arg.preview || "", value: arg.value || "" }; + }); + this._consoleObjects.set(event.guid, { + type: event.initializer.type, + text: event.initializer.text, + location: event.initializer.location, + args + }); + return null; + } + if (event.type === "event" && event.method === "console") { + const consoleMessage = this._consoleObjects.get(event.params.message?.guid || ""); + if (!consoleMessage) + return null; + return { + type: "console", + time: event.time, + pageId: event.pageId, + messageType: consoleMessage.type, + text: consoleMessage.text, + args: consoleMessage.args, + location: consoleMessage.location + }; + } + return event; + } + _modernize_5_to_6(events) { + const result = []; + for (const event of events) { + result.push(event); + if (event.type !== "after" || !event.log.length) + continue; + for (const log of event.log) { + result.push({ + type: "log", + callId: event.callId, + message: log, + time: -1 + }); + } + } + return result; + } + _modernize_6_to_7(events) { + const result = []; + if (!this._processedContextCreatedEvent() && events[0].type !== "context-options") { + const event = { + type: "context-options", + origin: "testRunner", + version: 6, + browserName: "", + options: {}, + platform: "unknown", + wallTime: 0, + monotonicTime: 0, + sdkLanguage: "javascript", + contextId: "" + }; + result.push(event); + } + for (const event of events) { + if (event.type === "context-options") { + result.push({ ...event, monotonicTime: 0, origin: "library", contextId: "" }); + continue; + } + if (event.type === "before" || event.type === "action") { + if (!this._contextEntry.wallTime) + this._contextEntry.wallTime = event.wallTime; + const eventAsV6 = event; + const eventAsV7 = event; + eventAsV7.stepId = `${eventAsV6.apiName}@${eventAsV6.wallTime}`; + result.push(eventAsV7); + } else { + result.push(event); + } + } + return result; + } + _modernize_7_to_8(events) { + const result = []; + for (const event of events) { + if (event.type === "before" || event.type === "action") { + const eventAsV7 = event; + const eventAsV8 = event; + if (eventAsV7.apiName) { + eventAsV8.title = eventAsV7.apiName; + delete eventAsV8.apiName; + } + eventAsV8.stepId = eventAsV7.stepId ?? eventAsV7.callId; + result.push(eventAsV8); + } else { + result.push(event); + } + } + return result; + } +} +// Annotate the CommonJS export names for ESM import in node: +0 && (module.exports = { + TraceModernizer, + TraceVersionError +}); diff --git a/skills/playwright-scraper-skill-1-2-0/node_modules/playwright-core/lib/utils/isomorphic/trace/versions/traceV3.js b/skills/playwright-scraper-skill-1-2-0/node_modules/playwright-core/lib/utils/isomorphic/trace/versions/traceV3.js new file mode 100644 index 0000000..cd2c1a2 --- /dev/null +++ b/skills/playwright-scraper-skill-1-2-0/node_modules/playwright-core/lib/utils/isomorphic/trace/versions/traceV3.js @@ -0,0 +1,16 @@ +"use strict"; +var __defProp = Object.defineProperty; +var __getOwnPropDesc = Object.getOwnPropertyDescriptor; +var __getOwnPropNames = Object.getOwnPropertyNames; +var __hasOwnProp = Object.prototype.hasOwnProperty; +var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; +}; +var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); +var traceV3_exports = {}; +module.exports = __toCommonJS(traceV3_exports); diff --git a/skills/playwright-scraper-skill-1-2-0/node_modules/playwright-core/lib/utils/isomorphic/trace/versions/traceV4.js b/skills/playwright-scraper-skill-1-2-0/node_modules/playwright-core/lib/utils/isomorphic/trace/versions/traceV4.js new file mode 100644 index 0000000..6249aa7 --- /dev/null +++ b/skills/playwright-scraper-skill-1-2-0/node_modules/playwright-core/lib/utils/isomorphic/trace/versions/traceV4.js @@ -0,0 +1,16 @@ +"use strict"; +var __defProp = Object.defineProperty; +var __getOwnPropDesc = Object.getOwnPropertyDescriptor; +var __getOwnPropNames = Object.getOwnPropertyNames; +var __hasOwnProp = Object.prototype.hasOwnProperty; +var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; +}; +var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); +var traceV4_exports = {}; +module.exports = __toCommonJS(traceV4_exports); diff --git a/skills/playwright-scraper-skill-1-2-0/node_modules/playwright-core/lib/utils/isomorphic/trace/versions/traceV5.js b/skills/playwright-scraper-skill-1-2-0/node_modules/playwright-core/lib/utils/isomorphic/trace/versions/traceV5.js new file mode 100644 index 0000000..d7f3bca --- /dev/null +++ b/skills/playwright-scraper-skill-1-2-0/node_modules/playwright-core/lib/utils/isomorphic/trace/versions/traceV5.js @@ -0,0 +1,16 @@ +"use strict"; +var __defProp = Object.defineProperty; +var __getOwnPropDesc = Object.getOwnPropertyDescriptor; +var __getOwnPropNames = Object.getOwnPropertyNames; +var __hasOwnProp = Object.prototype.hasOwnProperty; +var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; +}; +var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); +var traceV5_exports = {}; +module.exports = __toCommonJS(traceV5_exports); diff --git a/skills/playwright-scraper-skill-1-2-0/node_modules/playwright-core/lib/utils/isomorphic/trace/versions/traceV6.js b/skills/playwright-scraper-skill-1-2-0/node_modules/playwright-core/lib/utils/isomorphic/trace/versions/traceV6.js new file mode 100644 index 0000000..639bf55 --- /dev/null +++ b/skills/playwright-scraper-skill-1-2-0/node_modules/playwright-core/lib/utils/isomorphic/trace/versions/traceV6.js @@ -0,0 +1,16 @@ +"use strict"; +var __defProp = Object.defineProperty; +var __getOwnPropDesc = Object.getOwnPropertyDescriptor; +var __getOwnPropNames = Object.getOwnPropertyNames; +var __hasOwnProp = Object.prototype.hasOwnProperty; +var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; +}; +var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); +var traceV6_exports = {}; +module.exports = __toCommonJS(traceV6_exports); diff --git a/skills/playwright-scraper-skill-1-2-0/node_modules/playwright-core/lib/utils/isomorphic/trace/versions/traceV7.js b/skills/playwright-scraper-skill-1-2-0/node_modules/playwright-core/lib/utils/isomorphic/trace/versions/traceV7.js new file mode 100644 index 0000000..5c3159a --- /dev/null +++ b/skills/playwright-scraper-skill-1-2-0/node_modules/playwright-core/lib/utils/isomorphic/trace/versions/traceV7.js @@ -0,0 +1,16 @@ +"use strict"; +var __defProp = Object.defineProperty; +var __getOwnPropDesc = Object.getOwnPropertyDescriptor; +var __getOwnPropNames = Object.getOwnPropertyNames; +var __hasOwnProp = Object.prototype.hasOwnProperty; +var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; +}; +var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); +var traceV7_exports = {}; +module.exports = __toCommonJS(traceV7_exports); diff --git a/skills/playwright-scraper-skill-1-2-0/node_modules/playwright-core/lib/utils/isomorphic/trace/versions/traceV8.js b/skills/playwright-scraper-skill-1-2-0/node_modules/playwright-core/lib/utils/isomorphic/trace/versions/traceV8.js new file mode 100644 index 0000000..04ce41e --- /dev/null +++ b/skills/playwright-scraper-skill-1-2-0/node_modules/playwright-core/lib/utils/isomorphic/trace/versions/traceV8.js @@ -0,0 +1,16 @@ +"use strict"; +var __defProp = Object.defineProperty; +var __getOwnPropDesc = Object.getOwnPropertyDescriptor; +var __getOwnPropNames = Object.getOwnPropertyNames; +var __hasOwnProp = Object.prototype.hasOwnProperty; +var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; +}; +var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); +var traceV8_exports = {}; +module.exports = __toCommonJS(traceV8_exports); diff --git a/skills/playwright-scraper-skill-1-2-0/node_modules/playwright-core/lib/utils/isomorphic/traceUtils.js b/skills/playwright-scraper-skill-1-2-0/node_modules/playwright-core/lib/utils/isomorphic/traceUtils.js new file mode 100644 index 0000000..16fa2c1 --- /dev/null +++ b/skills/playwright-scraper-skill-1-2-0/node_modules/playwright-core/lib/utils/isomorphic/traceUtils.js @@ -0,0 +1,58 @@ +"use strict"; +var __defProp = Object.defineProperty; +var __getOwnPropDesc = Object.getOwnPropertyDescriptor; +var __getOwnPropNames = Object.getOwnPropertyNames; +var __hasOwnProp = Object.prototype.hasOwnProperty; +var __export = (target, all) => { + for (var name in all) + __defProp(target, name, { get: all[name], enumerable: true }); +}; +var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; +}; +var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); +var traceUtils_exports = {}; +__export(traceUtils_exports, { + parseClientSideCallMetadata: () => parseClientSideCallMetadata, + serializeClientSideCallMetadata: () => serializeClientSideCallMetadata +}); +module.exports = __toCommonJS(traceUtils_exports); +function parseClientSideCallMetadata(data) { + const result = /* @__PURE__ */ new Map(); + const { files, stacks } = data; + for (const s of stacks) { + const [id, ff] = s; + result.set(`call@${id}`, ff.map((f) => ({ file: files[f[0]], line: f[1], column: f[2], function: f[3] }))); + } + return result; +} +function serializeClientSideCallMetadata(metadatas) { + const fileNames = /* @__PURE__ */ new Map(); + const stacks = []; + for (const m of metadatas) { + if (!m.stack || !m.stack.length) + continue; + const stack = []; + for (const frame of m.stack) { + let ordinal = fileNames.get(frame.file); + if (typeof ordinal !== "number") { + ordinal = fileNames.size; + fileNames.set(frame.file, ordinal); + } + const stackFrame = [ordinal, frame.line || 0, frame.column || 0, frame.function || ""]; + stack.push(stackFrame); + } + stacks.push([m.id, stack]); + } + return { files: [...fileNames.keys()], stacks }; +} +// Annotate the CommonJS export names for ESM import in node: +0 && (module.exports = { + parseClientSideCallMetadata, + serializeClientSideCallMetadata +}); diff --git a/skills/playwright-scraper-skill-1-2-0/node_modules/playwright-core/lib/utils/isomorphic/types.js b/skills/playwright-scraper-skill-1-2-0/node_modules/playwright-core/lib/utils/isomorphic/types.js new file mode 100644 index 0000000..43ae536 --- /dev/null +++ b/skills/playwright-scraper-skill-1-2-0/node_modules/playwright-core/lib/utils/isomorphic/types.js @@ -0,0 +1,16 @@ +"use strict"; +var __defProp = Object.defineProperty; +var __getOwnPropDesc = Object.getOwnPropertyDescriptor; +var __getOwnPropNames = Object.getOwnPropertyNames; +var __hasOwnProp = Object.prototype.hasOwnProperty; +var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; +}; +var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); +var types_exports = {}; +module.exports = __toCommonJS(types_exports); diff --git a/skills/playwright-scraper-skill-1-2-0/node_modules/playwright-core/lib/utils/isomorphic/urlMatch.js b/skills/playwright-scraper-skill-1-2-0/node_modules/playwright-core/lib/utils/isomorphic/urlMatch.js new file mode 100644 index 0000000..cf86b5d --- /dev/null +++ b/skills/playwright-scraper-skill-1-2-0/node_modules/playwright-core/lib/utils/isomorphic/urlMatch.js @@ -0,0 +1,190 @@ +"use strict"; +var __defProp = Object.defineProperty; +var __getOwnPropDesc = Object.getOwnPropertyDescriptor; +var __getOwnPropNames = Object.getOwnPropertyNames; +var __hasOwnProp = Object.prototype.hasOwnProperty; +var __export = (target, all) => { + for (var name in all) + __defProp(target, name, { get: all[name], enumerable: true }); +}; +var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; +}; +var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); +var urlMatch_exports = {}; +__export(urlMatch_exports, { + constructURLBasedOnBaseURL: () => constructURLBasedOnBaseURL, + globToRegexPattern: () => globToRegexPattern, + resolveGlobToRegexPattern: () => resolveGlobToRegexPattern, + urlMatches: () => urlMatches, + urlMatchesEqual: () => urlMatchesEqual +}); +module.exports = __toCommonJS(urlMatch_exports); +var import_stringUtils = require("./stringUtils"); +const escapedChars = /* @__PURE__ */ new Set(["$", "^", "+", ".", "*", "(", ")", "|", "\\", "?", "{", "}", "[", "]"]); +function globToRegexPattern(glob) { + const tokens = ["^"]; + let inGroup = false; + for (let i = 0; i < glob.length; ++i) { + const c = glob[i]; + if (c === "\\" && i + 1 < glob.length) { + const char = glob[++i]; + tokens.push(escapedChars.has(char) ? "\\" + char : char); + continue; + } + if (c === "*") { + const charBefore = glob[i - 1]; + let starCount = 1; + while (glob[i + 1] === "*") { + starCount++; + i++; + } + if (starCount > 1) { + const charAfter = glob[i + 1]; + if (charAfter === "/") { + if (charBefore === "/") + tokens.push("((.+/)|)"); + else + tokens.push("(.*/)"); + ++i; + } else { + tokens.push("(.*)"); + } + } else { + tokens.push("([^/]*)"); + } + continue; + } + switch (c) { + case "{": + inGroup = true; + tokens.push("("); + break; + case "}": + inGroup = false; + tokens.push(")"); + break; + case ",": + if (inGroup) { + tokens.push("|"); + break; + } + tokens.push("\\" + c); + break; + default: + tokens.push(escapedChars.has(c) ? "\\" + c : c); + } + } + tokens.push("$"); + return tokens.join(""); +} +function isRegExp(obj) { + return obj instanceof RegExp || Object.prototype.toString.call(obj) === "[object RegExp]"; +} +function urlMatchesEqual(match1, match2) { + if (isRegExp(match1) && isRegExp(match2)) + return match1.source === match2.source && match1.flags === match2.flags; + return match1 === match2; +} +function urlMatches(baseURL, urlString, match, webSocketUrl) { + if (match === void 0 || match === "") + return true; + if ((0, import_stringUtils.isString)(match)) + match = new RegExp(resolveGlobToRegexPattern(baseURL, match, webSocketUrl)); + if (isRegExp(match)) { + const r = match.test(urlString); + return r; + } + const url = parseURL(urlString); + if (!url) + return false; + if (typeof match !== "function") + throw new Error("url parameter should be string, RegExp or function"); + return match(url); +} +function resolveGlobToRegexPattern(baseURL, glob, webSocketUrl) { + if (webSocketUrl) + baseURL = toWebSocketBaseUrl(baseURL); + glob = resolveGlobBase(baseURL, glob); + return globToRegexPattern(glob); +} +function toWebSocketBaseUrl(baseURL) { + if (baseURL && /^https?:\/\//.test(baseURL)) + baseURL = baseURL.replace(/^http/, "ws"); + return baseURL; +} +function resolveGlobBase(baseURL, match) { + if (!match.startsWith("*")) { + let mapToken2 = function(original, replacement) { + if (original.length === 0) + return ""; + tokenMap.set(replacement, original); + return replacement; + }; + var mapToken = mapToken2; + const tokenMap = /* @__PURE__ */ new Map(); + match = match.replaceAll(/\\\\\?/g, "?"); + if (match.startsWith("about:") || match.startsWith("data:") || match.startsWith("chrome:") || match.startsWith("edge:") || match.startsWith("file:")) + return match; + const relativePath = match.split("/").map((token, index) => { + if (token === "." || token === ".." || token === "") + return token; + if (index === 0 && token.endsWith(":")) { + if (token.indexOf("*") !== -1 || token.indexOf("{") !== -1) + return mapToken2(token, "http:"); + return token; + } + const questionIndex = token.indexOf("?"); + if (questionIndex === -1) + return mapToken2(token, `$_${index}_$`); + const newPrefix = mapToken2(token.substring(0, questionIndex), `$_${index}_$`); + const newSuffix = mapToken2(token.substring(questionIndex), `?$_${index}_$`); + return newPrefix + newSuffix; + }).join("/"); + const result = resolveBaseURL(baseURL, relativePath); + let resolved = result.resolved; + for (const [token, original] of tokenMap) { + const normalize = result.caseInsensitivePart?.includes(token); + resolved = resolved.replace(token, normalize ? original.toLowerCase() : original); + } + match = resolved; + } + return match; +} +function parseURL(url) { + try { + return new URL(url); + } catch (e) { + return null; + } +} +function constructURLBasedOnBaseURL(baseURL, givenURL) { + try { + return resolveBaseURL(baseURL, givenURL).resolved; + } catch (e) { + return givenURL; + } +} +function resolveBaseURL(baseURL, givenURL) { + try { + const url = new URL(givenURL, baseURL); + const resolved = url.toString(); + const caseInsensitivePrefix = url.origin; + return { resolved, caseInsensitivePart: caseInsensitivePrefix }; + } catch (e) { + return { resolved: givenURL }; + } +} +// Annotate the CommonJS export names for ESM import in node: +0 && (module.exports = { + constructURLBasedOnBaseURL, + globToRegexPattern, + resolveGlobToRegexPattern, + urlMatches, + urlMatchesEqual +}); diff --git a/skills/playwright-scraper-skill-1-2-0/node_modules/playwright-core/lib/utils/isomorphic/utilityScriptSerializers.js b/skills/playwright-scraper-skill-1-2-0/node_modules/playwright-core/lib/utils/isomorphic/utilityScriptSerializers.js new file mode 100644 index 0000000..e6f089c --- /dev/null +++ b/skills/playwright-scraper-skill-1-2-0/node_modules/playwright-core/lib/utils/isomorphic/utilityScriptSerializers.js @@ -0,0 +1,251 @@ +"use strict"; +var __defProp = Object.defineProperty; +var __getOwnPropDesc = Object.getOwnPropertyDescriptor; +var __getOwnPropNames = Object.getOwnPropertyNames; +var __hasOwnProp = Object.prototype.hasOwnProperty; +var __export = (target, all) => { + for (var name in all) + __defProp(target, name, { get: all[name], enumerable: true }); +}; +var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; +}; +var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); +var utilityScriptSerializers_exports = {}; +__export(utilityScriptSerializers_exports, { + parseEvaluationResultValue: () => parseEvaluationResultValue, + serializeAsCallArgument: () => serializeAsCallArgument +}); +module.exports = __toCommonJS(utilityScriptSerializers_exports); +function isRegExp(obj) { + try { + return obj instanceof RegExp || Object.prototype.toString.call(obj) === "[object RegExp]"; + } catch (error) { + return false; + } +} +function isDate(obj) { + try { + return obj instanceof Date || Object.prototype.toString.call(obj) === "[object Date]"; + } catch (error) { + return false; + } +} +function isURL(obj) { + try { + return obj instanceof URL || Object.prototype.toString.call(obj) === "[object URL]"; + } catch (error) { + return false; + } +} +function isError(obj) { + try { + return obj instanceof Error || obj && Object.getPrototypeOf(obj)?.name === "Error"; + } catch (error) { + return false; + } +} +function isTypedArray(obj, constructor) { + try { + return obj instanceof constructor || Object.prototype.toString.call(obj) === `[object ${constructor.name}]`; + } catch (error) { + return false; + } +} +const typedArrayConstructors = { + i8: Int8Array, + ui8: Uint8Array, + ui8c: Uint8ClampedArray, + i16: Int16Array, + ui16: Uint16Array, + i32: Int32Array, + ui32: Uint32Array, + // TODO: add Float16Array once it's in baseline + f32: Float32Array, + f64: Float64Array, + bi64: BigInt64Array, + bui64: BigUint64Array +}; +function typedArrayToBase64(array) { + if ("toBase64" in array) + return array.toBase64(); + const binary = Array.from(new Uint8Array(array.buffer, array.byteOffset, array.byteLength)).map((b) => String.fromCharCode(b)).join(""); + return btoa(binary); +} +function base64ToTypedArray(base64, TypedArrayConstructor) { + const binary = atob(base64); + const bytes = new Uint8Array(binary.length); + for (let i = 0; i < binary.length; i++) + bytes[i] = binary.charCodeAt(i); + return new TypedArrayConstructor(bytes.buffer); +} +function parseEvaluationResultValue(value, handles = [], refs = /* @__PURE__ */ new Map()) { + if (Object.is(value, void 0)) + return void 0; + if (typeof value === "object" && value) { + if ("ref" in value) + return refs.get(value.ref); + if ("v" in value) { + if (value.v === "undefined") + return void 0; + if (value.v === "null") + return null; + if (value.v === "NaN") + return NaN; + if (value.v === "Infinity") + return Infinity; + if (value.v === "-Infinity") + return -Infinity; + if (value.v === "-0") + return -0; + return void 0; + } + if ("d" in value) { + return new Date(value.d); + } + if ("u" in value) + return new URL(value.u); + if ("bi" in value) + return BigInt(value.bi); + if ("e" in value) { + const error = new Error(value.e.m); + error.name = value.e.n; + error.stack = value.e.s; + return error; + } + if ("r" in value) + return new RegExp(value.r.p, value.r.f); + if ("a" in value) { + const result = []; + refs.set(value.id, result); + for (const a of value.a) + result.push(parseEvaluationResultValue(a, handles, refs)); + return result; + } + if ("o" in value) { + const result = {}; + refs.set(value.id, result); + for (const { k, v } of value.o) { + if (k === "__proto__") + continue; + result[k] = parseEvaluationResultValue(v, handles, refs); + } + return result; + } + if ("h" in value) + return handles[value.h]; + if ("ta" in value) + return base64ToTypedArray(value.ta.b, typedArrayConstructors[value.ta.k]); + } + return value; +} +function serializeAsCallArgument(value, handleSerializer) { + return serialize(value, handleSerializer, { visited: /* @__PURE__ */ new Map(), lastId: 0 }); +} +function serialize(value, handleSerializer, visitorInfo) { + if (value && typeof value === "object") { + if (typeof globalThis.Window === "function" && value instanceof globalThis.Window) + return "ref: "; + if (typeof globalThis.Document === "function" && value instanceof globalThis.Document) + return "ref: "; + if (typeof globalThis.Node === "function" && value instanceof globalThis.Node) + return "ref: "; + } + return innerSerialize(value, handleSerializer, visitorInfo); +} +function innerSerialize(value, handleSerializer, visitorInfo) { + const result = handleSerializer(value); + if ("fallThrough" in result) + value = result.fallThrough; + else + return result; + if (typeof value === "symbol") + return { v: "undefined" }; + if (Object.is(value, void 0)) + return { v: "undefined" }; + if (Object.is(value, null)) + return { v: "null" }; + if (Object.is(value, NaN)) + return { v: "NaN" }; + if (Object.is(value, Infinity)) + return { v: "Infinity" }; + if (Object.is(value, -Infinity)) + return { v: "-Infinity" }; + if (Object.is(value, -0)) + return { v: "-0" }; + if (typeof value === "boolean") + return value; + if (typeof value === "number") + return value; + if (typeof value === "string") + return value; + if (typeof value === "bigint") + return { bi: value.toString() }; + if (isError(value)) { + let stack; + if (value.stack?.startsWith(value.name + ": " + value.message)) { + stack = value.stack; + } else { + stack = `${value.name}: ${value.message} +${value.stack}`; + } + return { e: { n: value.name, m: value.message, s: stack } }; + } + if (isDate(value)) + return { d: value.toJSON() }; + if (isURL(value)) + return { u: value.toJSON() }; + if (isRegExp(value)) + return { r: { p: value.source, f: value.flags } }; + for (const [k, ctor] of Object.entries(typedArrayConstructors)) { + if (isTypedArray(value, ctor)) + return { ta: { b: typedArrayToBase64(value), k } }; + } + const id = visitorInfo.visited.get(value); + if (id) + return { ref: id }; + if (Array.isArray(value)) { + const a = []; + const id2 = ++visitorInfo.lastId; + visitorInfo.visited.set(value, id2); + for (let i = 0; i < value.length; ++i) + a.push(serialize(value[i], handleSerializer, visitorInfo)); + return { a, id: id2 }; + } + if (typeof value === "object") { + const o = []; + const id2 = ++visitorInfo.lastId; + visitorInfo.visited.set(value, id2); + for (const name of Object.keys(value)) { + let item; + try { + item = value[name]; + } catch (e) { + continue; + } + if (name === "toJSON" && typeof item === "function") + o.push({ k: name, v: { o: [], id: 0 } }); + else + o.push({ k: name, v: serialize(item, handleSerializer, visitorInfo) }); + } + let jsonWrapper; + try { + if (o.length === 0 && value.toJSON && typeof value.toJSON === "function") + jsonWrapper = { value: value.toJSON() }; + } catch (e) { + } + if (jsonWrapper) + return innerSerialize(jsonWrapper.value, handleSerializer, visitorInfo); + return { o, id: id2 }; + } +} +// Annotate the CommonJS export names for ESM import in node: +0 && (module.exports = { + parseEvaluationResultValue, + serializeAsCallArgument +}); diff --git a/skills/playwright-scraper-skill-1-2-0/node_modules/playwright-core/lib/utils/isomorphic/yaml.js b/skills/playwright-scraper-skill-1-2-0/node_modules/playwright-core/lib/utils/isomorphic/yaml.js new file mode 100644 index 0000000..f4d002e --- /dev/null +++ b/skills/playwright-scraper-skill-1-2-0/node_modules/playwright-core/lib/utils/isomorphic/yaml.js @@ -0,0 +1,84 @@ +"use strict"; +var __defProp = Object.defineProperty; +var __getOwnPropDesc = Object.getOwnPropertyDescriptor; +var __getOwnPropNames = Object.getOwnPropertyNames; +var __hasOwnProp = Object.prototype.hasOwnProperty; +var __export = (target, all) => { + for (var name in all) + __defProp(target, name, { get: all[name], enumerable: true }); +}; +var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; +}; +var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); +var yaml_exports = {}; +__export(yaml_exports, { + yamlEscapeKeyIfNeeded: () => yamlEscapeKeyIfNeeded, + yamlEscapeValueIfNeeded: () => yamlEscapeValueIfNeeded +}); +module.exports = __toCommonJS(yaml_exports); +function yamlEscapeKeyIfNeeded(str) { + if (!yamlStringNeedsQuotes(str)) + return str; + return `'` + str.replace(/'/g, `''`) + `'`; +} +function yamlEscapeValueIfNeeded(str) { + if (!yamlStringNeedsQuotes(str)) + return str; + return '"' + str.replace(/[\\"\x00-\x1f\x7f-\x9f]/g, (c) => { + switch (c) { + case "\\": + return "\\\\"; + case '"': + return '\\"'; + case "\b": + return "\\b"; + case "\f": + return "\\f"; + case "\n": + return "\\n"; + case "\r": + return "\\r"; + case " ": + return "\\t"; + default: + const code = c.charCodeAt(0); + return "\\x" + code.toString(16).padStart(2, "0"); + } + }) + '"'; +} +function yamlStringNeedsQuotes(str) { + if (str.length === 0) + return true; + if (/^\s|\s$/.test(str)) + return true; + if (/[\x00-\x08\x0b\x0c\x0e-\x1f\x7f-\x9f]/.test(str)) + return true; + if (/^-/.test(str)) + return true; + if (/[\n:](\s|$)/.test(str)) + return true; + if (/\s#/.test(str)) + return true; + if (/[\n\r]/.test(str)) + return true; + if (/^[&*\],?!>|@"'#%]/.test(str)) + return true; + if (/[{}`]/.test(str)) + return true; + if (/^\[/.test(str)) + return true; + if (!isNaN(Number(str)) || ["y", "n", "yes", "no", "true", "false", "on", "off", "null"].includes(str.toLowerCase())) + return true; + return false; +} +// Annotate the CommonJS export names for ESM import in node: +0 && (module.exports = { + yamlEscapeKeyIfNeeded, + yamlEscapeValueIfNeeded +}); diff --git a/skills/playwright-scraper-skill-1-2-0/node_modules/playwright-core/lib/utilsBundle.js b/skills/playwright-scraper-skill-1-2-0/node_modules/playwright-core/lib/utilsBundle.js new file mode 100644 index 0000000..188aa33 --- /dev/null +++ b/skills/playwright-scraper-skill-1-2-0/node_modules/playwright-core/lib/utilsBundle.js @@ -0,0 +1,109 @@ +"use strict"; +var __defProp = Object.defineProperty; +var __getOwnPropDesc = Object.getOwnPropertyDescriptor; +var __getOwnPropNames = Object.getOwnPropertyNames; +var __hasOwnProp = Object.prototype.hasOwnProperty; +var __export = (target, all) => { + for (var name in all) + __defProp(target, name, { get: all[name], enumerable: true }); +}; +var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; +}; +var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); +var utilsBundle_exports = {}; +__export(utilsBundle_exports, { + HttpsProxyAgent: () => HttpsProxyAgent, + PNG: () => PNG, + ProgramOption: () => ProgramOption, + SocksProxyAgent: () => SocksProxyAgent, + colors: () => colors, + debug: () => debug, + diff: () => diff, + dotenv: () => dotenv, + getProxyForUrl: () => getProxyForUrl, + jpegjs: () => jpegjs, + lockfile: () => lockfile, + mime: () => mime, + minimatch: () => minimatch, + ms: () => ms, + open: () => open, + program: () => program, + progress: () => progress, + ws: () => ws, + wsReceiver: () => wsReceiver, + wsSender: () => wsSender, + wsServer: () => wsServer, + yaml: () => yaml +}); +module.exports = __toCommonJS(utilsBundle_exports); +const colors = require("./utilsBundleImpl").colors; +const debug = require("./utilsBundleImpl").debug; +const diff = require("./utilsBundleImpl").diff; +const dotenv = require("./utilsBundleImpl").dotenv; +const getProxyForUrl = require("./utilsBundleImpl").getProxyForUrl; +const HttpsProxyAgent = require("./utilsBundleImpl").HttpsProxyAgent; +const jpegjs = require("./utilsBundleImpl").jpegjs; +const lockfile = require("./utilsBundleImpl").lockfile; +const mime = require("./utilsBundleImpl").mime; +const minimatch = require("./utilsBundleImpl").minimatch; +const open = require("./utilsBundleImpl").open; +const PNG = require("./utilsBundleImpl").PNG; +const program = require("./utilsBundleImpl").program; +const ProgramOption = require("./utilsBundleImpl").ProgramOption; +const progress = require("./utilsBundleImpl").progress; +const SocksProxyAgent = require("./utilsBundleImpl").SocksProxyAgent; +const ws = require("./utilsBundleImpl").ws; +const wsServer = require("./utilsBundleImpl").wsServer; +const wsReceiver = require("./utilsBundleImpl").wsReceiver; +const wsSender = require("./utilsBundleImpl").wsSender; +const yaml = require("./utilsBundleImpl").yaml; +function ms(ms2) { + if (!isFinite(ms2)) + return "-"; + if (ms2 === 0) + return "0ms"; + if (ms2 < 1e3) + return ms2.toFixed(0) + "ms"; + const seconds = ms2 / 1e3; + if (seconds < 60) + return seconds.toFixed(1) + "s"; + const minutes = seconds / 60; + if (minutes < 60) + return minutes.toFixed(1) + "m"; + const hours = minutes / 60; + if (hours < 24) + return hours.toFixed(1) + "h"; + const days = hours / 24; + return days.toFixed(1) + "d"; +} +// Annotate the CommonJS export names for ESM import in node: +0 && (module.exports = { + HttpsProxyAgent, + PNG, + ProgramOption, + SocksProxyAgent, + colors, + debug, + diff, + dotenv, + getProxyForUrl, + jpegjs, + lockfile, + mime, + minimatch, + ms, + open, + program, + progress, + ws, + wsReceiver, + wsSender, + wsServer, + yaml +}); diff --git a/skills/playwright-scraper-skill-1-2-0/node_modules/playwright-core/lib/utilsBundleImpl/index.js b/skills/playwright-scraper-skill-1-2-0/node_modules/playwright-core/lib/utilsBundleImpl/index.js new file mode 100644 index 0000000..4a9bc8e --- /dev/null +++ b/skills/playwright-scraper-skill-1-2-0/node_modules/playwright-core/lib/utilsBundleImpl/index.js @@ -0,0 +1,218 @@ +"use strict";var Fb=Object.create;var ms=Object.defineProperty;var Db=Object.getOwnPropertyDescriptor;var jb=Object.getOwnPropertyNames;var Ub=Object.getPrototypeOf,$b=Object.prototype.hasOwnProperty;var x=(i,e)=>()=>(e||i((e={exports:{}}).exports,e),e.exports),wf=(i,e)=>{for(var t in e)ms(i,t,{get:e[t],enumerable:!0})},xf=(i,e,t,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let n of jb(e))!$b.call(i,n)&&n!==t&&ms(i,n,{get:()=>e[n],enumerable:!(r=Db(e,n))||r.enumerable});return i};var $e=(i,e,t)=>(t=i!=null?Fb(Ub(i)):{},xf(e||!i||!i.__esModule?ms(t,"default",{value:i,enumerable:!0}):t,i)),Vb=i=>xf(ms({},"__esModule",{value:!0}),i);var kf=x((bI,Of)=>{var Ef={};Of.exports=Ef;var Sf={reset:[0,0],bold:[1,22],dim:[2,22],italic:[3,23],underline:[4,24],inverse:[7,27],hidden:[8,28],strikethrough:[9,29],black:[30,39],red:[31,39],green:[32,39],yellow:[33,39],blue:[34,39],magenta:[35,39],cyan:[36,39],white:[37,39],gray:[90,39],grey:[90,39],brightRed:[91,39],brightGreen:[92,39],brightYellow:[93,39],brightBlue:[94,39],brightMagenta:[95,39],brightCyan:[96,39],brightWhite:[97,39],bgBlack:[40,49],bgRed:[41,49],bgGreen:[42,49],bgYellow:[43,49],bgBlue:[44,49],bgMagenta:[45,49],bgCyan:[46,49],bgWhite:[47,49],bgGray:[100,49],bgGrey:[100,49],bgBrightRed:[101,49],bgBrightGreen:[102,49],bgBrightYellow:[103,49],bgBrightBlue:[104,49],bgBrightMagenta:[105,49],bgBrightCyan:[106,49],bgBrightWhite:[107,49],blackBG:[40,49],redBG:[41,49],greenBG:[42,49],yellowBG:[43,49],blueBG:[44,49],magentaBG:[45,49],cyanBG:[46,49],whiteBG:[47,49]};Object.keys(Sf).forEach(function(i){var e=Sf[i],t=Ef[i]=[];t.open="\x1B["+e[0]+"m",t.close="\x1B["+e[1]+"m"})});var Tf=x((_I,Cf)=>{"use strict";Cf.exports=function(i,e){e=e||process.argv;var t=e.indexOf("--"),r=/^-{1,2}/.test(i)?"":"--",n=e.indexOf(r+i);return n!==-1&&(t===-1?!0:n{"use strict";var Hb=require("os"),$t=Tf(),at=process.env,yr=void 0;$t("no-color")||$t("no-colors")||$t("color=false")?yr=!1:($t("color")||$t("colors")||$t("color=true")||$t("color=always"))&&(yr=!0);"FORCE_COLOR"in at&&(yr=at.FORCE_COLOR.length===0||parseInt(at.FORCE_COLOR,10)!==0);function Gb(i){return i===0?!1:{level:i,hasBasic:!0,has256:i>=2,has16m:i>=3}}function Wb(i){if(yr===!1)return 0;if($t("color=16m")||$t("color=full")||$t("color=truecolor"))return 3;if($t("color=256"))return 2;if(i&&!i.isTTY&&yr!==!0)return 0;var e=yr?1:0;if(process.platform==="win32"){var t=Hb.release().split(".");return Number(process.versions.node.split(".")[0])>=8&&Number(t[0])>=10&&Number(t[2])>=10586?Number(t[2])>=14931?3:2:1}if("CI"in at)return["TRAVIS","CIRCLECI","APPVEYOR","GITLAB_CI"].some(function(n){return n in at})||at.CI_NAME==="codeship"?1:e;if("TEAMCITY_VERSION"in at)return/^(9\.(0*[1-9]\d*)\.|\d{2,}\.)/.test(at.TEAMCITY_VERSION)?1:0;if("TERM_PROGRAM"in at){var r=parseInt((at.TERM_PROGRAM_VERSION||"").split(".")[0],10);switch(at.TERM_PROGRAM){case"iTerm.app":return r>=3?3:2;case"Hyper":return 3;case"Apple_Terminal":return 2}}return/-256(color)?$/i.test(at.TERM)?2:/^screen|^xterm|^vt100|^rxvt|color|ansi|cygwin|linux/i.test(at.TERM)||"COLORTERM"in at?1:(at.TERM==="dumb",e)}function ka(i){var e=Wb(i);return Gb(e)}Af.exports={supportsColor:ka,stdout:ka(process.stdout),stderr:ka(process.stderr)}});var Bf=x((xI,Nf)=>{Nf.exports=function(e,t){var r="";e=e||"Run the trap, drop the bass",e=e.split("");var n={a:["@","\u0104","\u023A","\u0245","\u0394","\u039B","\u0414"],b:["\xDF","\u0181","\u0243","\u026E","\u03B2","\u0E3F"],c:["\xA9","\u023B","\u03FE"],d:["\xD0","\u018A","\u0500","\u0501","\u0502","\u0503"],e:["\xCB","\u0115","\u018E","\u0258","\u03A3","\u03BE","\u04BC","\u0A6C"],f:["\u04FA"],g:["\u0262"],h:["\u0126","\u0195","\u04A2","\u04BA","\u04C7","\u050A"],i:["\u0F0F"],j:["\u0134"],k:["\u0138","\u04A0","\u04C3","\u051E"],l:["\u0139"],m:["\u028D","\u04CD","\u04CE","\u0520","\u0521","\u0D69"],n:["\xD1","\u014B","\u019D","\u0376","\u03A0","\u048A"],o:["\xD8","\xF5","\xF8","\u01FE","\u0298","\u047A","\u05DD","\u06DD","\u0E4F"],p:["\u01F7","\u048E"],q:["\u09CD"],r:["\xAE","\u01A6","\u0210","\u024C","\u0280","\u042F"],s:["\xA7","\u03DE","\u03DF","\u03E8"],t:["\u0141","\u0166","\u0373"],u:["\u01B1","\u054D"],v:["\u05D8"],w:["\u0428","\u0460","\u047C","\u0D70"],x:["\u04B2","\u04FE","\u04FC","\u04FD"],y:["\xA5","\u04B0","\u04CB"],z:["\u01B5","\u0240"]};return e.forEach(function(s){s=s.toLowerCase();var o=n[s]||[" "],a=Math.floor(Math.random()*o.length);typeof n[s]!="undefined"?r+=n[s][a]:r+=s}),r}});var Rf=x((SI,Lf)=>{Lf.exports=function(e,t){e=e||" he is here ";var r={up:["\u030D","\u030E","\u0304","\u0305","\u033F","\u0311","\u0306","\u0310","\u0352","\u0357","\u0351","\u0307","\u0308","\u030A","\u0342","\u0313","\u0308","\u034A","\u034B","\u034C","\u0303","\u0302","\u030C","\u0350","\u0300","\u0301","\u030B","\u030F","\u0312","\u0313","\u0314","\u033D","\u0309","\u0363","\u0364","\u0365","\u0366","\u0367","\u0368","\u0369","\u036A","\u036B","\u036C","\u036D","\u036E","\u036F","\u033E","\u035B","\u0346","\u031A"],down:["\u0316","\u0317","\u0318","\u0319","\u031C","\u031D","\u031E","\u031F","\u0320","\u0324","\u0325","\u0326","\u0329","\u032A","\u032B","\u032C","\u032D","\u032E","\u032F","\u0330","\u0331","\u0332","\u0333","\u0339","\u033A","\u033B","\u033C","\u0345","\u0347","\u0348","\u0349","\u034D","\u034E","\u0353","\u0354","\u0355","\u0356","\u0359","\u035A","\u0323"],mid:["\u0315","\u031B","\u0300","\u0301","\u0358","\u0321","\u0322","\u0327","\u0328","\u0334","\u0335","\u0336","\u035C","\u035D","\u035E","\u035F","\u0360","\u0362","\u0338","\u0337","\u0361"," \u0489"]},n=[].concat(r.up,r.down,r.mid);function s(l){var c=Math.floor(Math.random()*l);return c}function o(l){var c=!1;return n.filter(function(u){c=u===l}),c}function a(l,c){var u="",f,d;c=c||{},c.up=typeof c.up!="undefined"?c.up:!0,c.mid=typeof c.mid!="undefined"?c.mid:!0,c.down=typeof c.down!="undefined"?c.down:!0,c.size=typeof c.size!="undefined"?c.size:"maxi",l=l.split("");for(d in l)if(!o(d)){switch(u=u+l[d],f={up:0,down:0,mid:0},c.size){case"mini":f.up=s(8),f.mid=s(2),f.down=s(8);break;case"maxi":f.up=s(16)+3,f.mid=s(4)+1,f.down=s(64)+3;break;default:f.up=s(8)+1,f.mid=s(6)/2,f.down=s(8)+1;break}var m=["up","mid","down"];for(var g in m)for(var y=m[g],b=0;b<=f[y];b++)c[y]&&(u=u+r[y][s(r[y].length)])}return u}return a(e,t)}});var Mf=x((EI,Pf)=>{Pf.exports=function(i){return function(e,t,r){if(e===" ")return e;switch(t%3){case 0:return i.red(e);case 1:return i.white(e);case 2:return i.blue(e)}}}});var Ff=x((OI,qf)=>{qf.exports=function(i){return function(e,t,r){return t%2===0?e:i.inverse(e)}}});var jf=x((kI,Df)=>{Df.exports=function(i){var e=["red","yellow","green","blue","magenta"];return function(t,r,n){return t===" "?t:i[e[r++%e.length]](t)}}});var $f=x((CI,Uf)=>{Uf.exports=function(i){var e=["underline","inverse","grey","yellow","red","green","blue","white","cyan","magenta","brightYellow","brightRed","brightGreen","brightBlue","brightWhite","brightCyan","brightMagenta"];return function(t,r,n){return t===" "?t:i[e[Math.round(Math.random()*(e.length-2))]](t)}}});var Kf=x((AI,Yf)=>{var ye={};Yf.exports=ye;ye.themes={};var Yb=require("util"),Wi=ye.styles=kf(),Hf=Object.defineProperties,Kb=new RegExp(/[\r\n]+/g);ye.supportsColor=If().supportsColor;typeof ye.enabled=="undefined"&&(ye.enabled=ye.supportsColor()!==!1);ye.enable=function(){ye.enabled=!0};ye.disable=function(){ye.enabled=!1};ye.stripColors=ye.strip=function(i){return(""+i).replace(/\x1B\[\d+m/g,"")};var TI=ye.stylize=function(e,t){if(!ye.enabled)return e+"";var r=Wi[t];return!r&&t in ye?ye[t](e):r.open+e+r.close},zb=/[|\\{}()[\]^$+*?.]/g,Jb=function(i){if(typeof i!="string")throw new TypeError("Expected a string");return i.replace(zb,"\\$&")};function Gf(i){var e=function t(){return Qb.apply(t,arguments)};return e._styles=i,e.__proto__=Zb,e}var Wf=(function(){var i={};return Wi.grey=Wi.gray,Object.keys(Wi).forEach(function(e){Wi[e].closeRe=new RegExp(Jb(Wi[e].close),"g"),i[e]={get:function(){return Gf(this._styles.concat(e))}}}),i})(),Zb=Hf(function(){},Wf);function Qb(){var i=Array.prototype.slice.call(arguments),e=i.map(function(o){return o!=null&&o.constructor===String?o:Yb.inspect(o)}).join(" ");if(!ye.enabled||!e)return e;for(var t=e.indexOf(` +`)!=-1,r=this._styles,n=r.length;n--;){var s=Wi[r[n]];e=s.open+e.replace(s.closeRe,s.open)+s.close,t&&(e=e.replace(Kb,function(o){return s.close+o+s.open}))}return e}ye.setTheme=function(i){if(typeof i=="string"){console.log("colors.setTheme now only accepts an object, not a string. If you are trying to set a theme from a file, it is now your (the caller's) responsibility to require the file. The old syntax looked like colors.setTheme(__dirname + '/../themes/generic-logging.js'); The new syntax looks like colors.setTheme(require(__dirname + '/../themes/generic-logging.js'));");return}for(var e in i)(function(t){ye[t]=function(r){if(typeof i[t]=="object"){var n=r;for(var s in i[t])n=ye[i[t][s]](n);return n}return ye[i[t]](r)}})(e)};function Xb(){var i={};return Object.keys(Wf).forEach(function(e){i[e]={get:function(){return Gf([e])}}}),i}var e_=function(e,t){var r=t.split("");return r=r.map(e),r.join("")};ye.trap=Bf();ye.zalgo=Rf();ye.maps={};ye.maps.america=Mf()(ye);ye.maps.zebra=Ff()(ye);ye.maps.rainbow=jf()(ye);ye.maps.random=$f()(ye);for(Vf in ye.maps)(function(i){ye[i]=function(e){return e_(ye.maps[i],e)}})(Vf);var Vf;Hf(ye,Xb())});var Jf=x((II,zf)=>{var t_=Kf();zf.exports=t_});var Qf=x((NI,Zf)=>{var br=1e3,_r=br*60,wr=_r*60,Yi=wr*24,i_=Yi*7,r_=Yi*365.25;Zf.exports=function(i,e){e=e||{};var t=typeof i;if(t==="string"&&i.length>0)return n_(i);if(t==="number"&&isFinite(i))return e.long?o_(i):s_(i);throw new Error("val is not a non-empty string or a valid number. val="+JSON.stringify(i))};function n_(i){if(i=String(i),!(i.length>100)){var e=/^(-?(?:\d+)?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|weeks?|w|years?|yrs?|y)?$/i.exec(i);if(e){var t=parseFloat(e[1]),r=(e[2]||"ms").toLowerCase();switch(r){case"years":case"year":case"yrs":case"yr":case"y":return t*r_;case"weeks":case"week":case"w":return t*i_;case"days":case"day":case"d":return t*Yi;case"hours":case"hour":case"hrs":case"hr":case"h":return t*wr;case"minutes":case"minute":case"mins":case"min":case"m":return t*_r;case"seconds":case"second":case"secs":case"sec":case"s":return t*br;case"milliseconds":case"millisecond":case"msecs":case"msec":case"ms":return t;default:return}}}}function s_(i){var e=Math.abs(i);return e>=Yi?Math.round(i/Yi)+"d":e>=wr?Math.round(i/wr)+"h":e>=_r?Math.round(i/_r)+"m":e>=br?Math.round(i/br)+"s":i+"ms"}function o_(i){var e=Math.abs(i);return e>=Yi?gs(i,e,Yi,"day"):e>=wr?gs(i,e,wr,"hour"):e>=_r?gs(i,e,_r,"minute"):e>=br?gs(i,e,br,"second"):i+" ms"}function gs(i,e,t,r){var n=e>=t*1.5;return Math.round(i/t)+" "+r+(n?"s":"")}});var Ca=x((BI,Xf)=>{function a_(i){t.debug=t,t.default=t,t.coerce=l,t.disable=s,t.enable=n,t.enabled=o,t.humanize=Qf(),t.destroy=c,Object.keys(i).forEach(u=>{t[u]=i[u]}),t.names=[],t.skips=[],t.formatters={};function e(u){let f=0;for(let d=0;d{if(R==="%%")return"%";O++;let A=t.formatters[T];if(typeof A=="function"){let C=b[O];R=A.call(w,C),b.splice(O,1),O--}return R}),t.formatArgs.call(w,b),(w.log||t.log).apply(w,b)}return y.namespace=u,y.useColors=t.useColors(),y.color=t.selectColor(u),y.extend=r,y.destroy=t.destroy,Object.defineProperty(y,"enabled",{enumerable:!0,configurable:!1,get:()=>d!==null?d:(m!==t.namespaces&&(m=t.namespaces,g=t.enabled(u)),g),set:b=>{d=b}}),typeof t.init=="function"&&t.init(y),y}function r(u,f){let d=t(this.namespace+(typeof f=="undefined"?":":f)+u);return d.log=this.log,d}function n(u){t.save(u),t.namespaces=u,t.names=[],t.skips=[];let f,d=(typeof u=="string"?u:"").split(/[\s,]+/),m=d.length;for(f=0;f"-"+f)].join(",");return t.enable(""),u}function o(u){if(u[u.length-1]==="*")return!0;let f,d;for(f=0,d=t.skips.length;f{xt.formatArgs=c_;xt.save=u_;xt.load=f_;xt.useColors=l_;xt.storage=h_();xt.destroy=(()=>{let i=!1;return()=>{i||(i=!0,console.warn("Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`."))}})();xt.colors=["#0000CC","#0000FF","#0033CC","#0033FF","#0066CC","#0066FF","#0099CC","#0099FF","#00CC00","#00CC33","#00CC66","#00CC99","#00CCCC","#00CCFF","#3300CC","#3300FF","#3333CC","#3333FF","#3366CC","#3366FF","#3399CC","#3399FF","#33CC00","#33CC33","#33CC66","#33CC99","#33CCCC","#33CCFF","#6600CC","#6600FF","#6633CC","#6633FF","#66CC00","#66CC33","#9900CC","#9900FF","#9933CC","#9933FF","#99CC00","#99CC33","#CC0000","#CC0033","#CC0066","#CC0099","#CC00CC","#CC00FF","#CC3300","#CC3333","#CC3366","#CC3399","#CC33CC","#CC33FF","#CC6600","#CC6633","#CC9900","#CC9933","#CCCC00","#CCCC33","#FF0000","#FF0033","#FF0066","#FF0099","#FF00CC","#FF00FF","#FF3300","#FF3333","#FF3366","#FF3399","#FF33CC","#FF33FF","#FF6600","#FF6633","#FF9900","#FF9933","#FFCC00","#FFCC33"];function l_(){return typeof window!="undefined"&&window.process&&(window.process.type==="renderer"||window.process.__nwjs)?!0:typeof navigator!="undefined"&&navigator.userAgent&&navigator.userAgent.toLowerCase().match(/(edge|trident)\/(\d+)/)?!1:typeof document!="undefined"&&document.documentElement&&document.documentElement.style&&document.documentElement.style.WebkitAppearance||typeof window!="undefined"&&window.console&&(window.console.firebug||window.console.exception&&window.console.table)||typeof navigator!="undefined"&&navigator.userAgent&&navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/)&&parseInt(RegExp.$1,10)>=31||typeof navigator!="undefined"&&navigator.userAgent&&navigator.userAgent.toLowerCase().match(/applewebkit\/(\d+)/)}function c_(i){if(i[0]=(this.useColors?"%c":"")+this.namespace+(this.useColors?" %c":" ")+i[0]+(this.useColors?"%c ":" ")+"+"+vs.exports.humanize(this.diff),!this.useColors)return;let e="color: "+this.color;i.splice(1,0,e,"color: inherit");let t=0,r=0;i[0].replace(/%[a-zA-Z%]/g,n=>{n!=="%%"&&(t++,n==="%c"&&(r=t))}),i.splice(r,0,e)}xt.log=console.debug||console.log||(()=>{});function u_(i){try{i?xt.storage.setItem("debug",i):xt.storage.removeItem("debug")}catch{}}function f_(){let i;try{i=xt.storage.getItem("debug")}catch{}return!i&&typeof process!="undefined"&&"env"in process&&(i=process.env.DEBUG),i}function h_(){try{return localStorage}catch{}}vs.exports=Ca()(xt);var{formatters:p_}=vs.exports;p_.j=function(i){try{return JSON.stringify(i)}catch(e){return"[UnexpectedJSONParseError]: "+e.message}}});var ih=x((LI,th)=>{"use strict";th.exports=(i,e=process.argv)=>{let t=i.startsWith("-")?"":i.length===1?"-":"--",r=e.indexOf(t+i),n=e.indexOf("--");return r!==-1&&(n===-1||r{"use strict";var d_=require("os"),rh=require("tty"),At=ih(),{env:Ke}=process,ys;At("no-color")||At("no-colors")||At("color=false")||At("color=never")?ys=0:(At("color")||At("colors")||At("color=true")||At("color=always"))&&(ys=1);function m_(){if("FORCE_COLOR"in Ke)return Ke.FORCE_COLOR==="true"?1:Ke.FORCE_COLOR==="false"?0:Ke.FORCE_COLOR.length===0?1:Math.min(Number.parseInt(Ke.FORCE_COLOR,10),3)}function g_(i){return i===0?!1:{level:i,hasBasic:!0,has256:i>=2,has16m:i>=3}}function v_(i,{streamIsTTY:e,sniffFlags:t=!0}={}){let r=m_();r!==void 0&&(ys=r);let n=t?ys:r;if(n===0)return 0;if(t){if(At("color=16m")||At("color=full")||At("color=truecolor"))return 3;if(At("color=256"))return 2}if(i&&!e&&n===void 0)return 0;let s=n||0;if(Ke.TERM==="dumb")return s;if(process.platform==="win32"){let o=d_.release().split(".");return Number(o[0])>=10&&Number(o[2])>=10586?Number(o[2])>=14931?3:2:1}if("CI"in Ke)return["TRAVIS","CIRCLECI","APPVEYOR","GITLAB_CI","GITHUB_ACTIONS","BUILDKITE","DRONE"].some(o=>o in Ke)||Ke.CI_NAME==="codeship"?1:s;if("TEAMCITY_VERSION"in Ke)return/^(9\.(0*[1-9]\d*)\.|\d{2,}\.)/.test(Ke.TEAMCITY_VERSION)?1:0;if(Ke.COLORTERM==="truecolor")return 3;if("TERM_PROGRAM"in Ke){let o=Number.parseInt((Ke.TERM_PROGRAM_VERSION||"").split(".")[0],10);switch(Ke.TERM_PROGRAM){case"iTerm.app":return o>=3?3:2;case"Apple_Terminal":return 2}}return/-256(color)?$/i.test(Ke.TERM)?2:/^screen|^xterm|^vt100|^vt220|^rxvt|color|ansi|cygwin|linux/i.test(Ke.TERM)||"COLORTERM"in Ke?1:s}function Ta(i,e={}){let t=v_(i,{streamIsTTY:i&&i.isTTY,...e});return g_(t)}nh.exports={supportsColor:Ta,stdout:Ta({isTTY:rh.isatty(1)}),stderr:Ta({isTTY:rh.isatty(2)})}});var ah=x((Xe,_s)=>{var y_=require("tty"),bs=require("util");Xe.init=O_;Xe.log=x_;Xe.formatArgs=__;Xe.save=S_;Xe.load=E_;Xe.useColors=b_;Xe.destroy=bs.deprecate(()=>{},"Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`.");Xe.colors=[6,2,3,4,5,1];try{let i=sh();i&&(i.stderr||i).level>=2&&(Xe.colors=[20,21,26,27,32,33,38,39,40,41,42,43,44,45,56,57,62,63,68,69,74,75,76,77,78,79,80,81,92,93,98,99,112,113,128,129,134,135,148,149,160,161,162,163,164,165,166,167,168,169,170,171,172,173,178,179,184,185,196,197,198,199,200,201,202,203,204,205,206,207,208,209,214,215,220,221])}catch{}Xe.inspectOpts=Object.keys(process.env).filter(i=>/^debug_/i.test(i)).reduce((i,e)=>{let t=e.substring(6).toLowerCase().replace(/_([a-z])/g,(n,s)=>s.toUpperCase()),r=process.env[e];return/^(yes|on|true|enabled)$/i.test(r)?r=!0:/^(no|off|false|disabled)$/i.test(r)?r=!1:r==="null"?r=null:r=Number(r),i[t]=r,i},{});function b_(){return"colors"in Xe.inspectOpts?!!Xe.inspectOpts.colors:y_.isatty(process.stderr.fd)}function __(i){let{namespace:e,useColors:t}=this;if(t){let r=this.color,n="\x1B[3"+(r<8?r:"8;5;"+r),s=` ${n};1m${e} \x1B[0m`;i[0]=s+i[0].split(` +`).join(` +`+s),i.push(n+"m+"+_s.exports.humanize(this.diff)+"\x1B[0m")}else i[0]=w_()+e+" "+i[0]}function w_(){return Xe.inspectOpts.hideDate?"":new Date().toISOString()+" "}function x_(...i){return process.stderr.write(bs.format(...i)+` +`)}function S_(i){i?process.env.DEBUG=i:delete process.env.DEBUG}function E_(){return process.env.DEBUG}function O_(i){i.inspectOpts={};let e=Object.keys(Xe.inspectOpts);for(let t=0;te.trim()).join(" ")};oh.O=function(i){return this.inspectOpts.colors=this.useColors,bs.inspect(i,this.inspectOpts)}});var rn=x((PI,Aa)=>{typeof process=="undefined"||process.type==="renderer"||process.browser===!0||process.__nwjs?Aa.exports=eh():Aa.exports=ah()});var Bh=x((MI,aw)=>{aw.exports={name:"dotenv",version:"16.4.5",description:"Loads environment variables from .env file",main:"lib/main.js",types:"lib/main.d.ts",exports:{".":{types:"./lib/main.d.ts",require:"./lib/main.js",default:"./lib/main.js"},"./config":"./config.js","./config.js":"./config.js","./lib/env-options":"./lib/env-options.js","./lib/env-options.js":"./lib/env-options.js","./lib/cli-options":"./lib/cli-options.js","./lib/cli-options.js":"./lib/cli-options.js","./package.json":"./package.json"},scripts:{"dts-check":"tsc --project tests/types/tsconfig.json",lint:"standard","lint-readme":"standard-markdown",pretest:"npm run lint && npm run dts-check",test:"tap tests/*.js --100 -Rspec","test:coverage":"tap --coverage-report=lcov",prerelease:"npm test",release:"standard-version"},repository:{type:"git",url:"git://github.com/motdotla/dotenv.git"},funding:"https://dotenvx.com",keywords:["dotenv","env",".env","environment","variables","config","settings"],readmeFilename:"README.md",license:"BSD-2-Clause",devDependencies:{"@definitelytyped/dtslint":"^0.0.133","@types/node":"^18.11.3",decache:"^4.6.1",sinon:"^14.0.1",standard:"^17.0.0","standard-markdown":"^7.1.0","standard-version":"^9.5.0",tap:"^16.3.0",tar:"^6.1.11",typescript:"^4.8.4"},engines:{node:">=12"},browser:{fs:!1}}});var Mh=x((qI,li)=>{var Da=require("fs"),ja=require("path"),lw=require("os"),cw=require("crypto"),uw=Bh(),Ua=uw.version,fw=/(?:^|^)\s*(?:export\s+)?([\w.-]+)(?:\s*=\s*?|:\s+?)(\s*'(?:\\'|[^'])*'|\s*"(?:\\"|[^"])*"|\s*`(?:\\`|[^`])*`|[^#\r\n]+)?\s*(?:#.*)?(?:$|$)/mg;function hw(i){let e={},t=i.toString();t=t.replace(/\r\n?/mg,` +`);let r;for(;(r=fw.exec(t))!=null;){let n=r[1],s=r[2]||"";s=s.trim();let o=s[0];s=s.replace(/^(['"`])([\s\S]*)\1$/mg,"$2"),o==='"'&&(s=s.replace(/\\n/g,` +`),s=s.replace(/\\r/g,"\r")),e[n]=s}return e}function pw(i){let e=Ph(i),t=Ve.configDotenv({path:e});if(!t.parsed){let o=new Error(`MISSING_DATA: Cannot parse ${e} for an unknown reason`);throw o.code="MISSING_DATA",o}let r=Rh(i).split(","),n=r.length,s;for(let o=0;o=n)throw a}return Ve.parse(s)}function dw(i){console.log(`[dotenv@${Ua}][INFO] ${i}`)}function mw(i){console.log(`[dotenv@${Ua}][WARN] ${i}`)}function As(i){console.log(`[dotenv@${Ua}][DEBUG] ${i}`)}function Rh(i){return i&&i.DOTENV_KEY&&i.DOTENV_KEY.length>0?i.DOTENV_KEY:process.env.DOTENV_KEY&&process.env.DOTENV_KEY.length>0?process.env.DOTENV_KEY:""}function gw(i,e){let t;try{t=new URL(e)}catch(a){if(a.code==="ERR_INVALID_URL"){let l=new Error("INVALID_DOTENV_KEY: Wrong format. Must be in valid uri format like dotenv://:key_1234@dotenvx.com/vault/.env.vault?environment=development");throw l.code="INVALID_DOTENV_KEY",l}throw a}let r=t.password;if(!r){let a=new Error("INVALID_DOTENV_KEY: Missing key part");throw a.code="INVALID_DOTENV_KEY",a}let n=t.searchParams.get("environment");if(!n){let a=new Error("INVALID_DOTENV_KEY: Missing environment part");throw a.code="INVALID_DOTENV_KEY",a}let s=`DOTENV_VAULT_${n.toUpperCase()}`,o=i.parsed[s];if(!o){let a=new Error(`NOT_FOUND_DOTENV_ENVIRONMENT: Cannot locate environment ${s} in your .env.vault file.`);throw a.code="NOT_FOUND_DOTENV_ENVIRONMENT",a}return{ciphertext:o,key:r}}function Ph(i){let e=null;if(i&&i.path&&i.path.length>0)if(Array.isArray(i.path))for(let t of i.path)Da.existsSync(t)&&(e=t.endsWith(".vault")?t:`${t}.vault`);else e=i.path.endsWith(".vault")?i.path:`${i.path}.vault`;else e=ja.resolve(process.cwd(),".env.vault");return Da.existsSync(e)?e:null}function Lh(i){return i[0]==="~"?ja.join(lw.homedir(),i.slice(1)):i}function vw(i){dw("Loading env from encrypted .env.vault");let e=Ve._parseVault(i),t=process.env;return i&&i.processEnv!=null&&(t=i.processEnv),Ve.populate(t,e,i),{parsed:e}}function yw(i){let e=ja.resolve(process.cwd(),".env"),t="utf8",r=!!(i&&i.debug);i&&i.encoding?t=i.encoding:r&&As("No encoding is specified. UTF-8 is used by default");let n=[e];if(i&&i.path)if(!Array.isArray(i.path))n=[Lh(i.path)];else{n=[];for(let l of i.path)n.push(Lh(l))}let s,o={};for(let l of n)try{let c=Ve.parse(Da.readFileSync(l,{encoding:t}));Ve.populate(o,c,i)}catch(c){r&&As(`Failed to load ${l} ${c.message}`),s=c}let a=process.env;return i&&i.processEnv!=null&&(a=i.processEnv),Ve.populate(a,o,i),s?{parsed:o,error:s}:{parsed:o}}function bw(i){if(Rh(i).length===0)return Ve.configDotenv(i);let e=Ph(i);return e?Ve._configVault(i):(mw(`You set DOTENV_KEY but you are missing a .env.vault file at ${e}. Did you forget to build it?`),Ve.configDotenv(i))}function _w(i,e){let t=Buffer.from(e.slice(-64),"hex"),r=Buffer.from(i,"base64"),n=r.subarray(0,12),s=r.subarray(-16);r=r.subarray(12,-16);try{let o=cw.createDecipheriv("aes-256-gcm",t,n);return o.setAuthTag(s),`${o.update(r)}${o.final()}`}catch(o){let a=o instanceof RangeError,l=o.message==="Invalid key length",c=o.message==="Unsupported state or unable to authenticate data";if(a||l){let u=new Error("INVALID_DOTENV_KEY: It must be 64 characters long (or more)");throw u.code="INVALID_DOTENV_KEY",u}else if(c){let u=new Error("DECRYPTION_FAILED: Please check your DOTENV_KEY");throw u.code="DECRYPTION_FAILED",u}else throw o}}function ww(i,e,t={}){let r=!!(t&&t.debug),n=!!(t&&t.override);if(typeof e!="object"){let s=new Error("OBJECT_REQUIRED: Please check the processEnv argument being passed to populate");throw s.code="OBJECT_REQUIRED",s}for(let s of Object.keys(e))Object.prototype.hasOwnProperty.call(i,s)?(n===!0&&(i[s]=e[s]),r&&As(n===!0?`"${s}" is already defined and WAS overwritten`:`"${s}" is already defined and was NOT overwritten`)):i[s]=e[s]}var Ve={configDotenv:yw,_configVault:vw,_parseVault:pw,config:bw,decrypt:_w,parse:hw,populate:ww};li.exports.configDotenv=Ve.configDotenv;li.exports._configVault=Ve._configVault;li.exports._parseVault=Ve._parseVault;li.exports.config=Ve.config;li.exports.decrypt=Ve.decrypt;li.exports.parse=Ve.parse;li.exports.populate=Ve.populate;li.exports=Ve});var Fh=x(qh=>{"use strict";var xw=require("url").parse,Sw={ftp:21,gopher:70,http:80,https:443,ws:80,wss:443},Ew=String.prototype.endsWith||function(i){return i.length<=this.length&&this.indexOf(i,this.length-i.length)!==-1};function Ow(i){var e=typeof i=="string"?xw(i):i||{},t=e.protocol,r=e.host,n=e.port;if(typeof r!="string"||!r||typeof t!="string"||(t=t.split(":",1)[0],r=r.replace(/:\d*$/,""),n=parseInt(n)||Sw[t]||0,!kw(r,n)))return"";var s=Sr("npm_config_"+t+"_proxy")||Sr(t+"_proxy")||Sr("npm_config_proxy")||Sr("all_proxy");return s&&s.indexOf("://")===-1&&(s=t+"://"+s),s}function kw(i,e){var t=(Sr("npm_config_no_proxy")||Sr("no_proxy")).toLowerCase();return t?t==="*"?!1:t.split(/[,\s]/).every(function(r){if(!r)return!0;var n=r.match(/^(.+):(\d+)$/),s=n?n[1]:r,o=n?parseInt(n[2]):0;return o&&o!==e?!0:/^[.*]/.test(s)?(s.charAt(0)==="*"&&(s=s.slice(1)),!Ew.call(i,s)):i!==s}):!0}function Sr(i){return process.env[i.toLowerCase()]||process.env[i.toUpperCase()]||""}qh.getProxyForUrl=Ow});var Uh=x(mt=>{"use strict";var Cw=mt&&mt.__createBinding||(Object.create?(function(i,e,t,r){r===void 0&&(r=t);var n=Object.getOwnPropertyDescriptor(e,t);(!n||("get"in n?!e.__esModule:n.writable||n.configurable))&&(n={enumerable:!0,get:function(){return e[t]}}),Object.defineProperty(i,r,n)}):(function(i,e,t,r){r===void 0&&(r=t),i[r]=e[t]})),Tw=mt&&mt.__setModuleDefault||(Object.create?(function(i,e){Object.defineProperty(i,"default",{enumerable:!0,value:e})}):function(i,e){i.default=e}),Dh=mt&&mt.__importStar||function(i){if(i&&i.__esModule)return i;var e={};if(i!=null)for(var t in i)t!=="default"&&Object.prototype.hasOwnProperty.call(i,t)&&Cw(e,i,t);return Tw(e,i),e};Object.defineProperty(mt,"__esModule",{value:!0});mt.req=mt.json=mt.toBuffer=void 0;var Aw=Dh(require("http")),Iw=Dh(require("https"));async function jh(i){let e=0,t=[];for await(let r of i)e+=r.length,t.push(r);return Buffer.concat(t,e)}mt.toBuffer=jh;async function Nw(i){let t=(await jh(i)).toString("utf8");try{return JSON.parse(t)}catch(r){let n=r;throw n.message+=` (input: ${t})`,n}}mt.json=Nw;function Bw(i,e={}){let r=((typeof i=="string"?i:i.href).startsWith("https:")?Iw:Aw).request(i,e),n=new Promise((s,o)=>{r.once("response",s).once("error",o).end()});return r.then=n.then.bind(n),r}mt.req=Bw});var Va=x(St=>{"use strict";var Vh=St&&St.__createBinding||(Object.create?(function(i,e,t,r){r===void 0&&(r=t);var n=Object.getOwnPropertyDescriptor(e,t);(!n||("get"in n?!e.__esModule:n.writable||n.configurable))&&(n={enumerable:!0,get:function(){return e[t]}}),Object.defineProperty(i,r,n)}):(function(i,e,t,r){r===void 0&&(r=t),i[r]=e[t]})),Lw=St&&St.__setModuleDefault||(Object.create?(function(i,e){Object.defineProperty(i,"default",{enumerable:!0,value:e})}):function(i,e){i.default=e}),Hh=St&&St.__importStar||function(i){if(i&&i.__esModule)return i;var e={};if(i!=null)for(var t in i)t!=="default"&&Object.prototype.hasOwnProperty.call(i,t)&&Vh(e,i,t);return Lw(e,i),e},Rw=St&&St.__exportStar||function(i,e){for(var t in i)t!=="default"&&!Object.prototype.hasOwnProperty.call(e,t)&&Vh(e,i,t)};Object.defineProperty(St,"__esModule",{value:!0});St.Agent=void 0;var Pw=Hh(require("net")),$h=Hh(require("http")),Mw=require("https");Rw(Uh(),St);var Kt=Symbol("AgentBaseInternalState"),$a=class extends $h.Agent{constructor(e){super(e),this[Kt]={}}isSecureEndpoint(e){if(e){if(typeof e.secureEndpoint=="boolean")return e.secureEndpoint;if(typeof e.protocol=="string")return e.protocol==="https:"}let{stack:t}=new Error;return typeof t!="string"?!1:t.split(` +`).some(r=>r.indexOf("(https.js:")!==-1||r.indexOf("node:https:")!==-1)}incrementSockets(e){if(this.maxSockets===1/0&&this.maxTotalSockets===1/0)return null;this.sockets[e]||(this.sockets[e]=[]);let t=new Pw.Socket({writable:!1});return this.sockets[e].push(t),this.totalSocketCount++,t}decrementSockets(e,t){if(!this.sockets[e]||t===null)return;let r=this.sockets[e],n=r.indexOf(t);n!==-1&&(r.splice(n,1),this.totalSocketCount--,r.length===0&&delete this.sockets[e])}getName(e){return this.isSecureEndpoint(e)?Mw.Agent.prototype.getName.call(this,e):super.getName(e)}createSocket(e,t,r){let n={...t,secureEndpoint:this.isSecureEndpoint(t)},s=this.getName(n),o=this.incrementSockets(s);Promise.resolve().then(()=>this.connect(e,n)).then(a=>{if(this.decrementSockets(s,o),a instanceof $h.Agent)try{return a.addRequest(e,n)}catch(l){return r(l)}this[Kt].currentSocket=a,super.createSocket(e,t,r)},a=>{this.decrementSockets(s,o),r(a)})}createConnection(){let e=this[Kt].currentSocket;if(this[Kt].currentSocket=void 0,!e)throw new Error("No socket was returned in the `connect()` function");return e}get defaultPort(){var e;return(e=this[Kt].defaultPort)!=null?e:this.protocol==="https:"?443:80}set defaultPort(e){this[Kt]&&(this[Kt].defaultPort=e)}get protocol(){var e;return(e=this[Kt].protocol)!=null?e:this.isSecureEndpoint()?"https:":"http:"}set protocol(e){this[Kt]&&(this[Kt].protocol=e)}};St.Agent=$a});var Gh=x(Er=>{"use strict";var qw=Er&&Er.__importDefault||function(i){return i&&i.__esModule?i:{default:i}};Object.defineProperty(Er,"__esModule",{value:!0});Er.parseProxyResponse=void 0;var Fw=qw(rn()),Is=(0,Fw.default)("https-proxy-agent:parse-proxy-response");function Dw(i){return new Promise((e,t)=>{let r=0,n=[];function s(){let u=i.read();u?c(u):i.once("readable",s)}function o(){i.removeListener("end",a),i.removeListener("error",l),i.removeListener("readable",s)}function a(){o(),Is("onend"),t(new Error("Proxy connection ended before receiving CONNECT response"))}function l(u){o(),Is("onerror %o",u),t(u)}function c(u){n.push(u),r+=u.length;let f=Buffer.concat(n,r),d=f.indexOf(`\r +\r +`);if(d===-1){Is("have not received end of HTTP headers yet..."),s();return}let m=f.slice(0,d).toString("ascii").split(`\r +`),g=m.shift();if(!g)return i.destroy(),t(new Error("No header received from proxy CONNECT response"));let y=g.split(" "),b=+y[1],w=y.slice(2).join(" "),S={};for(let k of m){if(!k)continue;let O=k.indexOf(":");if(O===-1)return i.destroy(),t(new Error(`Invalid header from proxy CONNECT response: "${k}"`));let E=k.slice(0,O).toLowerCase(),R=k.slice(O+1).trimStart(),T=S[E];typeof T=="string"?S[E]=[T,R]:Array.isArray(T)?T.push(R):S[E]=R}Is("got proxy server response: %o %o",g,S),o(),e({connect:{statusCode:b,statusText:w,headers:S},buffered:f})}i.on("error",l),i.on("end",a),s()})}Er.parseProxyResponse=Dw});var Zh=x(Nt=>{"use strict";var jw=Nt&&Nt.__createBinding||(Object.create?(function(i,e,t,r){r===void 0&&(r=t);var n=Object.getOwnPropertyDescriptor(e,t);(!n||("get"in n?!e.__esModule:n.writable||n.configurable))&&(n={enumerable:!0,get:function(){return e[t]}}),Object.defineProperty(i,r,n)}):(function(i,e,t,r){r===void 0&&(r=t),i[r]=e[t]})),Uw=Nt&&Nt.__setModuleDefault||(Object.create?(function(i,e){Object.defineProperty(i,"default",{enumerable:!0,value:e})}):function(i,e){i.default=e}),zh=Nt&&Nt.__importStar||function(i){if(i&&i.__esModule)return i;var e={};if(i!=null)for(var t in i)t!=="default"&&Object.prototype.hasOwnProperty.call(i,t)&&jw(e,i,t);return Uw(e,i),e},Jh=Nt&&Nt.__importDefault||function(i){return i&&i.__esModule?i:{default:i}};Object.defineProperty(Nt,"__esModule",{value:!0});Nt.HttpsProxyAgent=void 0;var Ns=zh(require("net")),Wh=zh(require("tls")),$w=Jh(require("assert")),Vw=Jh(rn()),Hw=Va(),Gw=require("url"),Ww=Gh(),an=(0,Vw.default)("https-proxy-agent"),Yh=i=>i.servername===void 0&&i.host&&!Ns.isIP(i.host)?{...i,servername:i.host}:i,Bs=class extends Hw.Agent{constructor(e,t){var s;super(t),this.options={path:void 0},this.proxy=typeof e=="string"?new Gw.URL(e):e,this.proxyHeaders=(s=t==null?void 0:t.headers)!=null?s:{},an("Creating new HttpsProxyAgent instance: %o",this.proxy.href);let r=(this.proxy.hostname||this.proxy.host).replace(/^\[|\]$/g,""),n=this.proxy.port?parseInt(this.proxy.port,10):this.proxy.protocol==="https:"?443:80;this.connectOpts={ALPNProtocols:["http/1.1"],...t?Kh(t,"headers"):null,host:r,port:n}}async connect(e,t){let{proxy:r}=this;if(!t.host)throw new TypeError('No "host" provided');let n;r.protocol==="https:"?(an("Creating `tls.Socket`: %o",this.connectOpts),n=Wh.connect(Yh(this.connectOpts))):(an("Creating `net.Socket`: %o",this.connectOpts),n=Ns.connect(this.connectOpts));let s=typeof this.proxyHeaders=="function"?this.proxyHeaders():{...this.proxyHeaders},o=Ns.isIPv6(t.host)?`[${t.host}]`:t.host,a=`CONNECT ${o}:${t.port} HTTP/1.1\r +`;if(r.username||r.password){let d=`${decodeURIComponent(r.username)}:${decodeURIComponent(r.password)}`;s["Proxy-Authorization"]=`Basic ${Buffer.from(d).toString("base64")}`}s.Host=`${o}:${t.port}`,s["Proxy-Connection"]||(s["Proxy-Connection"]=this.keepAlive?"Keep-Alive":"close");for(let d of Object.keys(s))a+=`${d}: ${s[d]}\r +`;let l=(0,Ww.parseProxyResponse)(n);n.write(`${a}\r +`);let{connect:c,buffered:u}=await l;if(e.emit("proxyConnect",c),this.emit("proxyConnect",c,e),c.statusCode===200)return e.once("socket",Yw),t.secureEndpoint?(an("Upgrading socket connection to TLS"),Wh.connect({...Kh(Yh(t),"host","path","port"),socket:n})):n;n.destroy();let f=new Ns.Socket({writable:!1});return f.readable=!0,e.once("socket",d=>{an("Replaying proxy buffer for failed request"),(0,$w.default)(d.listenerCount("data")>0),d.push(u),d.push(null)}),f}};Bs.protocols=["http","https"];Nt.HttpsProxyAgent=Bs;function Yw(i){i.resume()}function Kh(i,...e){let t={},r;for(r in i)e.includes(r)||(t[r]=i[r]);return t}});var ep=x((VI,Ls)=>{var Xh=Xh||function(i){return Buffer.from(i).toString("base64")};function Kw(i){var e=this,t=Math.round,r=Math.floor,n=new Array(64),s=new Array(64),o=new Array(64),a=new Array(64),l,c,u,f,d=new Array(65535),m=new Array(65535),g=new Array(64),y=new Array(64),b=[],w=0,S=7,k=new Array(64),O=new Array(64),E=new Array(64),R=new Array(256),T=new Array(2048),A,C=[0,1,5,6,14,15,27,28,2,4,7,13,16,26,29,42,3,8,12,17,25,30,41,43,9,11,18,24,31,40,44,53,10,19,23,32,39,45,52,54,20,22,33,38,46,51,55,60,21,34,37,47,50,56,59,61,35,36,48,49,57,58,62,63],B=[0,0,1,5,1,1,1,1,1,1,0,0,0,0,0,0,0],P=[0,1,2,3,4,5,6,7,8,9,10,11],U=[0,0,2,1,3,3,2,4,3,5,5,4,4,0,0,1,125],F=[1,2,3,0,4,17,5,18,33,49,65,6,19,81,97,7,34,113,20,50,129,145,161,8,35,66,177,193,21,82,209,240,36,51,98,114,130,9,10,22,23,24,25,26,37,38,39,40,41,42,52,53,54,55,56,57,58,67,68,69,70,71,72,73,74,83,84,85,86,87,88,89,90,99,100,101,102,103,104,105,106,115,116,117,118,119,120,121,122,131,132,133,134,135,136,137,138,146,147,148,149,150,151,152,153,154,162,163,164,165,166,167,168,169,170,178,179,180,181,182,183,184,185,186,194,195,196,197,198,199,200,201,202,210,211,212,213,214,215,216,217,218,225,226,227,228,229,230,231,232,233,234,241,242,243,244,245,246,247,248,249,250],H=[0,0,3,1,1,1,1,1,1,1,1,1,0,0,0,0,0],j=[0,1,2,3,4,5,6,7,8,9,10,11],V=[0,0,2,1,2,4,4,3,4,7,5,4,4,0,1,2,119],Y=[0,1,2,3,17,4,5,33,49,6,18,65,81,7,97,113,19,34,50,129,8,20,66,145,161,177,193,9,35,51,82,240,21,98,114,209,10,22,36,52,225,37,241,23,24,25,26,38,39,40,41,42,53,54,55,56,57,58,67,68,69,70,71,72,73,74,83,84,85,86,87,88,89,90,99,100,101,102,103,104,105,106,115,116,117,118,119,120,121,122,130,131,132,133,134,135,136,137,138,146,147,148,149,150,151,152,153,154,162,163,164,165,166,167,168,169,170,178,179,180,181,182,183,184,185,186,194,195,196,197,198,199,200,201,202,210,211,212,213,214,215,216,217,218,226,227,228,229,230,231,232,233,234,242,243,244,245,246,247,248,249,250];function Q(I){for(var Z=[16,11,10,16,24,40,51,61,12,12,14,19,26,58,60,55,14,13,16,24,40,57,69,56,14,17,22,29,51,87,80,62,18,22,37,56,68,109,103,77,24,35,55,64,81,104,113,92,49,64,78,87,103,121,120,101,72,92,95,98,112,100,103,99],te=0;te<64;te++){var ee=r((Z[te]*I+50)/100);ee<1?ee=1:ee>255&&(ee=255),n[C[te]]=ee}for(var le=[17,18,24,47,99,99,99,99,18,21,26,66,99,99,99,99,24,26,56,99,99,99,99,99,47,66,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99],ce=0;ce<64;ce++){var _e=r((le[ce]*I+50)/100);_e<1?_e=1:_e>255&&(_e=255),s[C[ce]]=_e}for(var we=[1,1.387039845,1.306562965,1.175875602,1,.785694958,.5411961,.275899379],Re=0,Ae=0;Ae<8;Ae++)for(var D=0;D<8;D++)o[Re]=1/(n[C[Re]]*we[Ae]*we[D]*8),a[Re]=1/(s[C[Re]]*we[Ae]*we[D]*8),Re++}function W(I,Z){for(var te=0,ee=0,le=new Array,ce=1;ce<=16;ce++){for(var _e=1;_e<=I[ce];_e++)le[Z[ee]]=[],le[Z[ee]][0]=te,le[Z[ee]][1]=ce,ee++,te++;te*=2}return le}function de(){l=W(B,P),c=W(H,j),u=W(U,F),f=W(V,Y)}function ae(){for(var I=1,Z=2,te=1;te<=15;te++){for(var ee=I;ee>0]=38470*I,T[I+512>>0]=7471*I+32768,T[I+768>>0]=-11059*I,T[I+1024>>0]=-21709*I,T[I+1280>>0]=32768*I+8421375,T[I+1536>>0]=-27439*I,T[I+1792>>0]=-5329*I}function ue(I){for(var Z=I[0],te=I[1]-1;te>=0;)Z&1<>8&255),N(I&255)}function ke(I,Z){var te,ee,le,ce,_e,we,Re,Ae,D=0,J,se=8,Ne=64;for(J=0;J0?vr+.5|0:vr-.5|0;return g}function be(){X(65504),X(16),N(74),N(70),N(73),N(70),N(0),N(1),N(1),N(0),X(1),X(1),N(0),N(0)}function ge(I){if(I){X(65505),I[0]===69&&I[1]===120&&I[2]===105&&I[3]===102?X(I.length+2):(X(I.length+5+2),N(69),N(120),N(105),N(102),N(0));for(var Z=0;Z{if(typeof Z=="string"){X(65534);var te=Z.length;X(te+2);var ee;for(ee=0;ee0&&y[oe]==0;oe--);if(oe==0)return ue(ce),te;for(var me=1,Ee;me<=oe;){for(var ie=me;y[me]==0&&me<=oe;++me);var xe=me-ie;if(xe>=Re){Ee=xe>>4;for(var Ue=1;Ue<=Ee;++Ue)ue(_e);xe=xe&15}we=32767+y[me],ue(le[(xe<<4)+m[we]]),ue(d[we]),me++}return oe!=Ae&&ue(ce),te}function he(){for(var I=String.fromCharCode,Z=0;Z<256;Z++)R[Z]=I(Z)}this.encode=function(I,Z){var te=new Date().getTime();Z&&ht(Z),b=new Array,w=0,S=7,X(65496),be(),$(I.comments),ge(I.exifBuffer),fe(),ve(I.width,I.height),z(),Te();var ee=0,le=0,ce=0;w=0,S=7,this.encode.displayName="_encode_";for(var _e=I.data,we=I.width,Re=I.height,Ae=we*4,D=we*3,J,se=0,Ne,oe,me,Ee,ie,xe,Ue,Ie;se>3,xe=(Ie&7)*4,ie=Ee+Ue*Ae+xe,se+Ue>=Re&&(ie-=Ae*(se+1+Ue-Re)),J+xe>=Ae&&(ie-=J+xe-Ae+4),Ne=_e[ie++],oe=_e[ie++],me=_e[ie++],k[Ie]=(T[Ne]+T[oe+256>>0]+T[me+512>>0]>>16)-128,O[Ie]=(T[Ne+768>>0]+T[oe+1024>>0]+T[me+1280>>0]>>16)-128,E[Ie]=(T[Ne+1280>>0]+T[oe+1536>>0]+T[me+1792>>0]>>16)-128;ee=re(k,o,ee,l,u),le=re(O,a,le,c,f),ce=re(E,a,ce,c,f),J+=32}se+=8}if(S>=0){var pt=[];pt[1]=S+1,pt[0]=(1<100&&(I=100),A!=I){var Z=0;I<50?Z=Math.floor(5e3/I):Z=Math.floor(200-I*2),Q(Z),A=I}}function bt(){var I=new Date().getTime();i||(i=50),he(),de(),ae(),ne(),ht(i);var Z=new Date().getTime()-I}bt()}typeof Ls!="undefined"?Ls.exports=Qh:typeof window!="undefined"&&(window["jpeg-js"]=window["jpeg-js"]||{},window["jpeg-js"].encode=Qh);function Qh(i,e){typeof e=="undefined"&&(e=50);var t=new Kw(e),r=t.encode(i,e);return{data:r,width:i.width,height:i.height}}});var ip=x((HI,Ga)=>{var Ha=(function(){"use strict";var e=new Int32Array([0,1,8,16,9,2,3,10,17,24,32,25,18,11,4,5,12,19,26,33,40,48,41,34,27,20,13,6,7,14,21,28,35,42,49,56,57,50,43,36,29,22,15,23,30,37,44,51,58,59,52,45,38,31,39,46,53,60,61,54,47,55,62,63]),t=4017,r=799,n=3406,s=2276,o=1567,a=3784,l=5793,c=2896;function u(){}function f(S,k){for(var O=0,E=[],R,T,A=16;A>0&&!S[A-1];)A--;E.push({children:[],index:0});var C=E[0],B;for(R=0;R0;){if(E.length===0)throw new Error("Could not recreate Huffman Table");C=E.pop()}for(C.index++,E.push(C);E.length<=R;)E.push(B={children:[],index:0}),C.children[C.index]=B.children,C=B;O++}R+10)return ae--,de>>ae&1;if(de=S[k++],de==255){var D=S[k++];if(D)throw new Error("unexpected marker: "+(de<<8|D).toString(16))}return ae=7,de>>>7}function ue(D){for(var J=D,se;(se=ne())!==null;){if(J=J[se],typeof J=="number")return J;if(typeof J!="object")throw new Error("invalid huffman sequence")}return null}function N(D){for(var J=0;D>0;){var se=ne();if(se===null)return;J=J<<1|se,D--}return J}function X(D){var J=N(D);return J>=1<>4;if(Ee===0){if(ie<15)break;oe+=16;continue}oe+=ie;var xe=e[oe];J[xe]=X(Ee),oe++}}function be(D,J){var se=ue(D.huffmanTableDC),Ne=se===0?0:X(se)<0){ve--;return}for(var se=T,Ne=A;se<=Ne;){var oe=ue(D.huffmanTableAC),me=oe&15,Ee=oe>>4;if(me===0){if(Ee<15){ve=N(Ee)+(1<>4;if(xe===0)oe<15?(ve=N(oe)+(1<=65488&&_e<=65495)k+=2;else break}return k-W}function m(S,k){var O=[],E=k.blocksPerLine,R=k.blocksPerColumn,T=E<<3,A=new Int32Array(64),C=new Uint8Array(64);function B(W,de,ae){var ne=k.quantizationTable,ue,N,X,ke,be,ge,ve,fe,z,$=ae,Te;for(Te=0;Te<64;Te++)$[Te]=W[Te]*ne[Te];for(Te=0;Te<8;++Te){var re=8*Te;if($[1+re]==0&&$[2+re]==0&&$[3+re]==0&&$[4+re]==0&&$[5+re]==0&&$[6+re]==0&&$[7+re]==0){z=l*$[0+re]+512>>10,$[0+re]=z,$[1+re]=z,$[2+re]=z,$[3+re]=z,$[4+re]=z,$[5+re]=z,$[6+re]=z,$[7+re]=z;continue}ue=l*$[0+re]+128>>8,N=l*$[4+re]+128>>8,X=$[2+re],ke=$[6+re],be=c*($[1+re]-$[7+re])+128>>8,fe=c*($[1+re]+$[7+re])+128>>8,ge=$[3+re]<<4,ve=$[5+re]<<4,z=ue-N+1>>1,ue=ue+N+1>>1,N=z,z=X*a+ke*o+128>>8,X=X*o-ke*a+128>>8,ke=z,z=be-ve+1>>1,be=be+ve+1>>1,ve=z,z=fe+ge+1>>1,ge=fe-ge+1>>1,fe=z,z=ue-ke+1>>1,ue=ue+ke+1>>1,ke=z,z=N-X+1>>1,N=N+X+1>>1,X=z,z=be*s+fe*n+2048>>12,be=be*n-fe*s+2048>>12,fe=z,z=ge*r+ve*t+2048>>12,ge=ge*t-ve*r+2048>>12,ve=z,$[0+re]=ue+fe,$[7+re]=ue-fe,$[1+re]=N+ve,$[6+re]=N-ve,$[2+re]=X+ge,$[5+re]=X-ge,$[3+re]=ke+be,$[4+re]=ke-be}for(Te=0;Te<8;++Te){var he=Te;if($[8+he]==0&&$[16+he]==0&&$[24+he]==0&&$[32+he]==0&&$[40+he]==0&&$[48+he]==0&&$[56+he]==0){z=l*ae[Te+0]+8192>>14,$[0+he]=z,$[8+he]=z,$[16+he]=z,$[24+he]=z,$[32+he]=z,$[40+he]=z,$[48+he]=z,$[56+he]=z;continue}ue=l*$[0+he]+2048>>12,N=l*$[32+he]+2048>>12,X=$[16+he],ke=$[48+he],be=c*($[8+he]-$[56+he])+2048>>12,fe=c*($[8+he]+$[56+he])+2048>>12,ge=$[24+he],ve=$[40+he],z=ue-N+1>>1,ue=ue+N+1>>1,N=z,z=X*a+ke*o+2048>>12,X=X*o-ke*a+2048>>12,ke=z,z=be-ve+1>>1,be=be+ve+1>>1,ve=z,z=fe+ge+1>>1,ge=fe-ge+1>>1,fe=z,z=ue-ke+1>>1,ue=ue+ke+1>>1,ke=z,z=N-X+1>>1,N=N+X+1>>1,X=z,z=be*s+fe*n+2048>>12,be=be*n-fe*s+2048>>12,fe=z,z=ge*r+ve*t+2048>>12,ge=ge*t-ve*r+2048>>12,ve=z,$[0+he]=ue+fe,$[56+he]=ue-fe,$[8+he]=N+ve,$[48+he]=N-ve,$[16+he]=X+ge,$[40+he]=X-ge,$[24+he]=ke+be,$[32+he]=ke-be}for(Te=0;Te<64;++Te){var ht=128+($[Te]+8>>4);de[Te]=ht<0?0:ht>255?255:ht}}w(T*R*8);for(var P,U,F=0;F255?255:S}u.prototype={load:function(k){var O=new XMLHttpRequest;O.open("GET",k,!0),O.responseType="arraybuffer",O.onload=(function(){var E=new Uint8Array(O.response||O.mozResponseArrayBuffer);this.parse(E),this.onload&&this.onload()}).bind(this),O.send(null)},parse:function(k){var O=this.opts.maxResolutionInMP*1e3*1e3,E=0,R=k.length;function T(){var ie=k[E]<<8|k[E+1];return E+=2,ie}function A(){var ie=T(),xe=k.subarray(E,E+ie-2);return E+=xe.length,xe}function C(ie){var xe=1,Ue=1,Ie,pt;for(pt in ie.components)ie.components.hasOwnProperty(pt)&&(Ie=ie.components[pt],xe>4===0)for(ne=0;ne<64;ne++){var fe=e[ne];ve[fe]=k[E++]}else if(ge>>4===1)for(ne=0;ne<64;ne++){var fe=e[ne];ve[fe]=T()}else throw new Error("DQT: invalid table spec");j[ge&15]=ve}break;case 65472:case 65473:case 65474:T(),F={},F.extended=W===65473,F.progressive=W===65474,F.precision=k[E++],F.scanLines=T(),F.samplesPerLine=T(),F.components={},F.componentsOrder=[];var z=F.scanLines*F.samplesPerLine;if(z>O){var $=Math.ceil((z-O)/1e6);throw new Error(`maxResolutionInMP limit exceeded by ${$}MP`)}var Te=k[E++],re,he=0,ht=0;for(ae=0;ae>4,I=k[E+1]&15,Z=k[E+2];if(bt<=0||I<=0)throw new Error("Invalid sampling factor, expected values above 0");F.componentsOrder.push(re),F.components[re]={h:bt,v:I,quantizationIdx:Z},E+=3}C(F),V.push(F);break;case 65476:var te=T();for(ae=2;ae>4===0?Q:Y)[ee&15]=f(le,_e)}break;case 65501:T(),H=T();break;case 65500:T(),T();break;case 65498:var we=T(),Re=k[E++],Ae=[],D;for(ae=0;ae>4],D.huffmanTableAC=Y[J&15],Ae.push(D)}var se=k[E++],Ne=k[E++],oe=k[E++],me=d(k,E,F,Ae,H,se,Ne,oe>>4,oe&15,this.opts);E+=me;break;case 65535:k[E]!==255&&E--;break;default:if(k[E-3]==255&&k[E-2]>=192&&k[E-2]<=254){E-=3;break}else if(W===224||W==225){if(de!==-1)throw new Error(`first unknown JPEG marker at offset ${de.toString(16)}, second unknown JPEG marker ${W.toString(16)} at offset ${(E-1).toString(16)}`);de=E-1;let ie=T();if(k[E+ie-2]===255){E+=ie-2;break}}throw new Error("unknown JPEG marker "+W.toString(16))}W=T()}if(V.length!=1)throw new Error("only single frame JPEGs supported");for(var ae=0;aeb){var O=Math.ceil((k-b)/1024/1024);throw new Error(`maxMemoryUsageInMB limit exceeded by at least ${O}MB`)}y=k}return u.resetMaxMemoryUsage=function(S){y=0,b=S},u.getBytesAllocated=function(){return y},u.requestMemoryAllocation=w,u})();typeof Ga!="undefined"?Ga.exports=tp:typeof window!="undefined"&&(window["jpeg-js"]=window["jpeg-js"]||{},window["jpeg-js"].decode=tp);function tp(i,e={}){var t={colorTransform:void 0,useTArray:!1,formatAsRGBA:!0,tolerantDecoding:!0,maxResolutionInMP:100,maxMemoryUsageInMB:512},r={...t,...e},n=new Uint8Array(i),s=new Ha;s.opts=r,Ha.resetMaxMemoryUsage(r.maxMemoryUsageInMB*1024*1024),s.parse(n);var o=r.formatAsRGBA?4:3,a=s.width*s.height*o;try{Ha.requestMemoryAllocation(a);var l={width:s.width,height:s.height,exifBuffer:s.exifBuffer,data:r.useTArray?new Uint8Array(a):Buffer.alloc(a)};s.comments.length>0&&(l.comments=s.comments)}catch(c){throw c instanceof RangeError?new Error("Could not allocate enough memory for the image. Required: "+a):c instanceof ReferenceError&&c.message==="Buffer is not defined"?new Error("Buffer is not globally defined in this environment. Consider setting useTArray to true"):c}return s.copyToImageData(l,r.formatAsRGBA),l}});var np=x((GI,rp)=>{var zw=ep(),Jw=ip();rp.exports={encode:zw,decode:Jw}});var op=x((WI,sp)=>{"use strict";function Rs(){this._types=Object.create(null),this._extensions=Object.create(null);for(let i=0;i{ap.exports={"application/andrew-inset":["ez"],"application/applixware":["aw"],"application/atom+xml":["atom"],"application/atomcat+xml":["atomcat"],"application/atomdeleted+xml":["atomdeleted"],"application/atomsvc+xml":["atomsvc"],"application/atsc-dwd+xml":["dwd"],"application/atsc-held+xml":["held"],"application/atsc-rsat+xml":["rsat"],"application/bdoc":["bdoc"],"application/calendar+xml":["xcs"],"application/ccxml+xml":["ccxml"],"application/cdfx+xml":["cdfx"],"application/cdmi-capability":["cdmia"],"application/cdmi-container":["cdmic"],"application/cdmi-domain":["cdmid"],"application/cdmi-object":["cdmio"],"application/cdmi-queue":["cdmiq"],"application/cu-seeme":["cu"],"application/dash+xml":["mpd"],"application/davmount+xml":["davmount"],"application/docbook+xml":["dbk"],"application/dssc+der":["dssc"],"application/dssc+xml":["xdssc"],"application/ecmascript":["es","ecma"],"application/emma+xml":["emma"],"application/emotionml+xml":["emotionml"],"application/epub+zip":["epub"],"application/exi":["exi"],"application/express":["exp"],"application/fdt+xml":["fdt"],"application/font-tdpfr":["pfr"],"application/geo+json":["geojson"],"application/gml+xml":["gml"],"application/gpx+xml":["gpx"],"application/gxf":["gxf"],"application/gzip":["gz"],"application/hjson":["hjson"],"application/hyperstudio":["stk"],"application/inkml+xml":["ink","inkml"],"application/ipfix":["ipfix"],"application/its+xml":["its"],"application/java-archive":["jar","war","ear"],"application/java-serialized-object":["ser"],"application/java-vm":["class"],"application/javascript":["js","mjs"],"application/json":["json","map"],"application/json5":["json5"],"application/jsonml+json":["jsonml"],"application/ld+json":["jsonld"],"application/lgr+xml":["lgr"],"application/lost+xml":["lostxml"],"application/mac-binhex40":["hqx"],"application/mac-compactpro":["cpt"],"application/mads+xml":["mads"],"application/manifest+json":["webmanifest"],"application/marc":["mrc"],"application/marcxml+xml":["mrcx"],"application/mathematica":["ma","nb","mb"],"application/mathml+xml":["mathml"],"application/mbox":["mbox"],"application/mediaservercontrol+xml":["mscml"],"application/metalink+xml":["metalink"],"application/metalink4+xml":["meta4"],"application/mets+xml":["mets"],"application/mmt-aei+xml":["maei"],"application/mmt-usd+xml":["musd"],"application/mods+xml":["mods"],"application/mp21":["m21","mp21"],"application/mp4":["mp4s","m4p"],"application/msword":["doc","dot"],"application/mxf":["mxf"],"application/n-quads":["nq"],"application/n-triples":["nt"],"application/node":["cjs"],"application/octet-stream":["bin","dms","lrf","mar","so","dist","distz","pkg","bpk","dump","elc","deploy","exe","dll","deb","dmg","iso","img","msi","msp","msm","buffer"],"application/oda":["oda"],"application/oebps-package+xml":["opf"],"application/ogg":["ogx"],"application/omdoc+xml":["omdoc"],"application/onenote":["onetoc","onetoc2","onetmp","onepkg"],"application/oxps":["oxps"],"application/p2p-overlay+xml":["relo"],"application/patch-ops-error+xml":["xer"],"application/pdf":["pdf"],"application/pgp-encrypted":["pgp"],"application/pgp-signature":["asc","sig"],"application/pics-rules":["prf"],"application/pkcs10":["p10"],"application/pkcs7-mime":["p7m","p7c"],"application/pkcs7-signature":["p7s"],"application/pkcs8":["p8"],"application/pkix-attr-cert":["ac"],"application/pkix-cert":["cer"],"application/pkix-crl":["crl"],"application/pkix-pkipath":["pkipath"],"application/pkixcmp":["pki"],"application/pls+xml":["pls"],"application/postscript":["ai","eps","ps"],"application/provenance+xml":["provx"],"application/pskc+xml":["pskcxml"],"application/raml+yaml":["raml"],"application/rdf+xml":["rdf","owl"],"application/reginfo+xml":["rif"],"application/relax-ng-compact-syntax":["rnc"],"application/resource-lists+xml":["rl"],"application/resource-lists-diff+xml":["rld"],"application/rls-services+xml":["rs"],"application/route-apd+xml":["rapd"],"application/route-s-tsid+xml":["sls"],"application/route-usd+xml":["rusd"],"application/rpki-ghostbusters":["gbr"],"application/rpki-manifest":["mft"],"application/rpki-roa":["roa"],"application/rsd+xml":["rsd"],"application/rss+xml":["rss"],"application/rtf":["rtf"],"application/sbml+xml":["sbml"],"application/scvp-cv-request":["scq"],"application/scvp-cv-response":["scs"],"application/scvp-vp-request":["spq"],"application/scvp-vp-response":["spp"],"application/sdp":["sdp"],"application/senml+xml":["senmlx"],"application/sensml+xml":["sensmlx"],"application/set-payment-initiation":["setpay"],"application/set-registration-initiation":["setreg"],"application/shf+xml":["shf"],"application/sieve":["siv","sieve"],"application/smil+xml":["smi","smil"],"application/sparql-query":["rq"],"application/sparql-results+xml":["srx"],"application/srgs":["gram"],"application/srgs+xml":["grxml"],"application/sru+xml":["sru"],"application/ssdl+xml":["ssdl"],"application/ssml+xml":["ssml"],"application/swid+xml":["swidtag"],"application/tei+xml":["tei","teicorpus"],"application/thraud+xml":["tfi"],"application/timestamped-data":["tsd"],"application/toml":["toml"],"application/trig":["trig"],"application/ttml+xml":["ttml"],"application/ubjson":["ubj"],"application/urc-ressheet+xml":["rsheet"],"application/urc-targetdesc+xml":["td"],"application/voicexml+xml":["vxml"],"application/wasm":["wasm"],"application/widget":["wgt"],"application/winhlp":["hlp"],"application/wsdl+xml":["wsdl"],"application/wspolicy+xml":["wspolicy"],"application/xaml+xml":["xaml"],"application/xcap-att+xml":["xav"],"application/xcap-caps+xml":["xca"],"application/xcap-diff+xml":["xdf"],"application/xcap-el+xml":["xel"],"application/xcap-ns+xml":["xns"],"application/xenc+xml":["xenc"],"application/xhtml+xml":["xhtml","xht"],"application/xliff+xml":["xlf"],"application/xml":["xml","xsl","xsd","rng"],"application/xml-dtd":["dtd"],"application/xop+xml":["xop"],"application/xproc+xml":["xpl"],"application/xslt+xml":["*xsl","xslt"],"application/xspf+xml":["xspf"],"application/xv+xml":["mxml","xhvml","xvml","xvm"],"application/yang":["yang"],"application/yin+xml":["yin"],"application/zip":["zip"],"audio/3gpp":["*3gpp"],"audio/adpcm":["adp"],"audio/amr":["amr"],"audio/basic":["au","snd"],"audio/midi":["mid","midi","kar","rmi"],"audio/mobile-xmf":["mxmf"],"audio/mp3":["*mp3"],"audio/mp4":["m4a","mp4a"],"audio/mpeg":["mpga","mp2","mp2a","mp3","m2a","m3a"],"audio/ogg":["oga","ogg","spx","opus"],"audio/s3m":["s3m"],"audio/silk":["sil"],"audio/wav":["wav"],"audio/wave":["*wav"],"audio/webm":["weba"],"audio/xm":["xm"],"font/collection":["ttc"],"font/otf":["otf"],"font/ttf":["ttf"],"font/woff":["woff"],"font/woff2":["woff2"],"image/aces":["exr"],"image/apng":["apng"],"image/avif":["avif"],"image/bmp":["bmp"],"image/cgm":["cgm"],"image/dicom-rle":["drle"],"image/emf":["emf"],"image/fits":["fits"],"image/g3fax":["g3"],"image/gif":["gif"],"image/heic":["heic"],"image/heic-sequence":["heics"],"image/heif":["heif"],"image/heif-sequence":["heifs"],"image/hej2k":["hej2"],"image/hsj2":["hsj2"],"image/ief":["ief"],"image/jls":["jls"],"image/jp2":["jp2","jpg2"],"image/jpeg":["jpeg","jpg","jpe"],"image/jph":["jph"],"image/jphc":["jhc"],"image/jpm":["jpm"],"image/jpx":["jpx","jpf"],"image/jxr":["jxr"],"image/jxra":["jxra"],"image/jxrs":["jxrs"],"image/jxs":["jxs"],"image/jxsc":["jxsc"],"image/jxsi":["jxsi"],"image/jxss":["jxss"],"image/ktx":["ktx"],"image/ktx2":["ktx2"],"image/png":["png"],"image/sgi":["sgi"],"image/svg+xml":["svg","svgz"],"image/t38":["t38"],"image/tiff":["tif","tiff"],"image/tiff-fx":["tfx"],"image/webp":["webp"],"image/wmf":["wmf"],"message/disposition-notification":["disposition-notification"],"message/global":["u8msg"],"message/global-delivery-status":["u8dsn"],"message/global-disposition-notification":["u8mdn"],"message/global-headers":["u8hdr"],"message/rfc822":["eml","mime"],"model/3mf":["3mf"],"model/gltf+json":["gltf"],"model/gltf-binary":["glb"],"model/iges":["igs","iges"],"model/mesh":["msh","mesh","silo"],"model/mtl":["mtl"],"model/obj":["obj"],"model/step+xml":["stpx"],"model/step+zip":["stpz"],"model/step-xml+zip":["stpxz"],"model/stl":["stl"],"model/vrml":["wrl","vrml"],"model/x3d+binary":["*x3db","x3dbz"],"model/x3d+fastinfoset":["x3db"],"model/x3d+vrml":["*x3dv","x3dvz"],"model/x3d+xml":["x3d","x3dz"],"model/x3d-vrml":["x3dv"],"text/cache-manifest":["appcache","manifest"],"text/calendar":["ics","ifb"],"text/coffeescript":["coffee","litcoffee"],"text/css":["css"],"text/csv":["csv"],"text/html":["html","htm","shtml"],"text/jade":["jade"],"text/jsx":["jsx"],"text/less":["less"],"text/markdown":["markdown","md"],"text/mathml":["mml"],"text/mdx":["mdx"],"text/n3":["n3"],"text/plain":["txt","text","conf","def","list","log","in","ini"],"text/richtext":["rtx"],"text/rtf":["*rtf"],"text/sgml":["sgml","sgm"],"text/shex":["shex"],"text/slim":["slim","slm"],"text/spdx":["spdx"],"text/stylus":["stylus","styl"],"text/tab-separated-values":["tsv"],"text/troff":["t","tr","roff","man","me","ms"],"text/turtle":["ttl"],"text/uri-list":["uri","uris","urls"],"text/vcard":["vcard"],"text/vtt":["vtt"],"text/xml":["*xml"],"text/yaml":["yaml","yml"],"video/3gpp":["3gp","3gpp"],"video/3gpp2":["3g2"],"video/h261":["h261"],"video/h263":["h263"],"video/h264":["h264"],"video/iso.segment":["m4s"],"video/jpeg":["jpgv"],"video/jpm":["*jpm","jpgm"],"video/mj2":["mj2","mjp2"],"video/mp2t":["ts"],"video/mp4":["mp4","mp4v","mpg4"],"video/mpeg":["mpeg","mpg","mpe","m1v","m2v"],"video/ogg":["ogv"],"video/quicktime":["qt","mov"],"video/webm":["webm"]}});var up=x((KI,cp)=>{cp.exports={"application/prs.cww":["cww"],"application/vnd.1000minds.decision-model+xml":["1km"],"application/vnd.3gpp.pic-bw-large":["plb"],"application/vnd.3gpp.pic-bw-small":["psb"],"application/vnd.3gpp.pic-bw-var":["pvb"],"application/vnd.3gpp2.tcap":["tcap"],"application/vnd.3m.post-it-notes":["pwn"],"application/vnd.accpac.simply.aso":["aso"],"application/vnd.accpac.simply.imp":["imp"],"application/vnd.acucobol":["acu"],"application/vnd.acucorp":["atc","acutc"],"application/vnd.adobe.air-application-installer-package+zip":["air"],"application/vnd.adobe.formscentral.fcdt":["fcdt"],"application/vnd.adobe.fxp":["fxp","fxpl"],"application/vnd.adobe.xdp+xml":["xdp"],"application/vnd.adobe.xfdf":["xfdf"],"application/vnd.ahead.space":["ahead"],"application/vnd.airzip.filesecure.azf":["azf"],"application/vnd.airzip.filesecure.azs":["azs"],"application/vnd.amazon.ebook":["azw"],"application/vnd.americandynamics.acc":["acc"],"application/vnd.amiga.ami":["ami"],"application/vnd.android.package-archive":["apk"],"application/vnd.anser-web-certificate-issue-initiation":["cii"],"application/vnd.anser-web-funds-transfer-initiation":["fti"],"application/vnd.antix.game-component":["atx"],"application/vnd.apple.installer+xml":["mpkg"],"application/vnd.apple.keynote":["key"],"application/vnd.apple.mpegurl":["m3u8"],"application/vnd.apple.numbers":["numbers"],"application/vnd.apple.pages":["pages"],"application/vnd.apple.pkpass":["pkpass"],"application/vnd.aristanetworks.swi":["swi"],"application/vnd.astraea-software.iota":["iota"],"application/vnd.audiograph":["aep"],"application/vnd.balsamiq.bmml+xml":["bmml"],"application/vnd.blueice.multipass":["mpm"],"application/vnd.bmi":["bmi"],"application/vnd.businessobjects":["rep"],"application/vnd.chemdraw+xml":["cdxml"],"application/vnd.chipnuts.karaoke-mmd":["mmd"],"application/vnd.cinderella":["cdy"],"application/vnd.citationstyles.style+xml":["csl"],"application/vnd.claymore":["cla"],"application/vnd.cloanto.rp9":["rp9"],"application/vnd.clonk.c4group":["c4g","c4d","c4f","c4p","c4u"],"application/vnd.cluetrust.cartomobile-config":["c11amc"],"application/vnd.cluetrust.cartomobile-config-pkg":["c11amz"],"application/vnd.commonspace":["csp"],"application/vnd.contact.cmsg":["cdbcmsg"],"application/vnd.cosmocaller":["cmc"],"application/vnd.crick.clicker":["clkx"],"application/vnd.crick.clicker.keyboard":["clkk"],"application/vnd.crick.clicker.palette":["clkp"],"application/vnd.crick.clicker.template":["clkt"],"application/vnd.crick.clicker.wordbank":["clkw"],"application/vnd.criticaltools.wbs+xml":["wbs"],"application/vnd.ctc-posml":["pml"],"application/vnd.cups-ppd":["ppd"],"application/vnd.curl.car":["car"],"application/vnd.curl.pcurl":["pcurl"],"application/vnd.dart":["dart"],"application/vnd.data-vision.rdz":["rdz"],"application/vnd.dbf":["dbf"],"application/vnd.dece.data":["uvf","uvvf","uvd","uvvd"],"application/vnd.dece.ttml+xml":["uvt","uvvt"],"application/vnd.dece.unspecified":["uvx","uvvx"],"application/vnd.dece.zip":["uvz","uvvz"],"application/vnd.denovo.fcselayout-link":["fe_launch"],"application/vnd.dna":["dna"],"application/vnd.dolby.mlp":["mlp"],"application/vnd.dpgraph":["dpg"],"application/vnd.dreamfactory":["dfac"],"application/vnd.ds-keypoint":["kpxx"],"application/vnd.dvb.ait":["ait"],"application/vnd.dvb.service":["svc"],"application/vnd.dynageo":["geo"],"application/vnd.ecowin.chart":["mag"],"application/vnd.enliven":["nml"],"application/vnd.epson.esf":["esf"],"application/vnd.epson.msf":["msf"],"application/vnd.epson.quickanime":["qam"],"application/vnd.epson.salt":["slt"],"application/vnd.epson.ssf":["ssf"],"application/vnd.eszigno3+xml":["es3","et3"],"application/vnd.ezpix-album":["ez2"],"application/vnd.ezpix-package":["ez3"],"application/vnd.fdf":["fdf"],"application/vnd.fdsn.mseed":["mseed"],"application/vnd.fdsn.seed":["seed","dataless"],"application/vnd.flographit":["gph"],"application/vnd.fluxtime.clip":["ftc"],"application/vnd.framemaker":["fm","frame","maker","book"],"application/vnd.frogans.fnc":["fnc"],"application/vnd.frogans.ltf":["ltf"],"application/vnd.fsc.weblaunch":["fsc"],"application/vnd.fujitsu.oasys":["oas"],"application/vnd.fujitsu.oasys2":["oa2"],"application/vnd.fujitsu.oasys3":["oa3"],"application/vnd.fujitsu.oasysgp":["fg5"],"application/vnd.fujitsu.oasysprs":["bh2"],"application/vnd.fujixerox.ddd":["ddd"],"application/vnd.fujixerox.docuworks":["xdw"],"application/vnd.fujixerox.docuworks.binder":["xbd"],"application/vnd.fuzzysheet":["fzs"],"application/vnd.genomatix.tuxedo":["txd"],"application/vnd.geogebra.file":["ggb"],"application/vnd.geogebra.tool":["ggt"],"application/vnd.geometry-explorer":["gex","gre"],"application/vnd.geonext":["gxt"],"application/vnd.geoplan":["g2w"],"application/vnd.geospace":["g3w"],"application/vnd.gmx":["gmx"],"application/vnd.google-apps.document":["gdoc"],"application/vnd.google-apps.presentation":["gslides"],"application/vnd.google-apps.spreadsheet":["gsheet"],"application/vnd.google-earth.kml+xml":["kml"],"application/vnd.google-earth.kmz":["kmz"],"application/vnd.grafeq":["gqf","gqs"],"application/vnd.groove-account":["gac"],"application/vnd.groove-help":["ghf"],"application/vnd.groove-identity-message":["gim"],"application/vnd.groove-injector":["grv"],"application/vnd.groove-tool-message":["gtm"],"application/vnd.groove-tool-template":["tpl"],"application/vnd.groove-vcard":["vcg"],"application/vnd.hal+xml":["hal"],"application/vnd.handheld-entertainment+xml":["zmm"],"application/vnd.hbci":["hbci"],"application/vnd.hhe.lesson-player":["les"],"application/vnd.hp-hpgl":["hpgl"],"application/vnd.hp-hpid":["hpid"],"application/vnd.hp-hps":["hps"],"application/vnd.hp-jlyt":["jlt"],"application/vnd.hp-pcl":["pcl"],"application/vnd.hp-pclxl":["pclxl"],"application/vnd.hydrostatix.sof-data":["sfd-hdstx"],"application/vnd.ibm.minipay":["mpy"],"application/vnd.ibm.modcap":["afp","listafp","list3820"],"application/vnd.ibm.rights-management":["irm"],"application/vnd.ibm.secure-container":["sc"],"application/vnd.iccprofile":["icc","icm"],"application/vnd.igloader":["igl"],"application/vnd.immervision-ivp":["ivp"],"application/vnd.immervision-ivu":["ivu"],"application/vnd.insors.igm":["igm"],"application/vnd.intercon.formnet":["xpw","xpx"],"application/vnd.intergeo":["i2g"],"application/vnd.intu.qbo":["qbo"],"application/vnd.intu.qfx":["qfx"],"application/vnd.ipunplugged.rcprofile":["rcprofile"],"application/vnd.irepository.package+xml":["irp"],"application/vnd.is-xpr":["xpr"],"application/vnd.isac.fcs":["fcs"],"application/vnd.jam":["jam"],"application/vnd.jcp.javame.midlet-rms":["rms"],"application/vnd.jisp":["jisp"],"application/vnd.joost.joda-archive":["joda"],"application/vnd.kahootz":["ktz","ktr"],"application/vnd.kde.karbon":["karbon"],"application/vnd.kde.kchart":["chrt"],"application/vnd.kde.kformula":["kfo"],"application/vnd.kde.kivio":["flw"],"application/vnd.kde.kontour":["kon"],"application/vnd.kde.kpresenter":["kpr","kpt"],"application/vnd.kde.kspread":["ksp"],"application/vnd.kde.kword":["kwd","kwt"],"application/vnd.kenameaapp":["htke"],"application/vnd.kidspiration":["kia"],"application/vnd.kinar":["kne","knp"],"application/vnd.koan":["skp","skd","skt","skm"],"application/vnd.kodak-descriptor":["sse"],"application/vnd.las.las+xml":["lasxml"],"application/vnd.llamagraphics.life-balance.desktop":["lbd"],"application/vnd.llamagraphics.life-balance.exchange+xml":["lbe"],"application/vnd.lotus-1-2-3":["123"],"application/vnd.lotus-approach":["apr"],"application/vnd.lotus-freelance":["pre"],"application/vnd.lotus-notes":["nsf"],"application/vnd.lotus-organizer":["org"],"application/vnd.lotus-screencam":["scm"],"application/vnd.lotus-wordpro":["lwp"],"application/vnd.macports.portpkg":["portpkg"],"application/vnd.mapbox-vector-tile":["mvt"],"application/vnd.mcd":["mcd"],"application/vnd.medcalcdata":["mc1"],"application/vnd.mediastation.cdkey":["cdkey"],"application/vnd.mfer":["mwf"],"application/vnd.mfmp":["mfm"],"application/vnd.micrografx.flo":["flo"],"application/vnd.micrografx.igx":["igx"],"application/vnd.mif":["mif"],"application/vnd.mobius.daf":["daf"],"application/vnd.mobius.dis":["dis"],"application/vnd.mobius.mbk":["mbk"],"application/vnd.mobius.mqy":["mqy"],"application/vnd.mobius.msl":["msl"],"application/vnd.mobius.plc":["plc"],"application/vnd.mobius.txf":["txf"],"application/vnd.mophun.application":["mpn"],"application/vnd.mophun.certificate":["mpc"],"application/vnd.mozilla.xul+xml":["xul"],"application/vnd.ms-artgalry":["cil"],"application/vnd.ms-cab-compressed":["cab"],"application/vnd.ms-excel":["xls","xlm","xla","xlc","xlt","xlw"],"application/vnd.ms-excel.addin.macroenabled.12":["xlam"],"application/vnd.ms-excel.sheet.binary.macroenabled.12":["xlsb"],"application/vnd.ms-excel.sheet.macroenabled.12":["xlsm"],"application/vnd.ms-excel.template.macroenabled.12":["xltm"],"application/vnd.ms-fontobject":["eot"],"application/vnd.ms-htmlhelp":["chm"],"application/vnd.ms-ims":["ims"],"application/vnd.ms-lrm":["lrm"],"application/vnd.ms-officetheme":["thmx"],"application/vnd.ms-outlook":["msg"],"application/vnd.ms-pki.seccat":["cat"],"application/vnd.ms-pki.stl":["*stl"],"application/vnd.ms-powerpoint":["ppt","pps","pot"],"application/vnd.ms-powerpoint.addin.macroenabled.12":["ppam"],"application/vnd.ms-powerpoint.presentation.macroenabled.12":["pptm"],"application/vnd.ms-powerpoint.slide.macroenabled.12":["sldm"],"application/vnd.ms-powerpoint.slideshow.macroenabled.12":["ppsm"],"application/vnd.ms-powerpoint.template.macroenabled.12":["potm"],"application/vnd.ms-project":["mpp","mpt"],"application/vnd.ms-word.document.macroenabled.12":["docm"],"application/vnd.ms-word.template.macroenabled.12":["dotm"],"application/vnd.ms-works":["wps","wks","wcm","wdb"],"application/vnd.ms-wpl":["wpl"],"application/vnd.ms-xpsdocument":["xps"],"application/vnd.mseq":["mseq"],"application/vnd.musician":["mus"],"application/vnd.muvee.style":["msty"],"application/vnd.mynfc":["taglet"],"application/vnd.neurolanguage.nlu":["nlu"],"application/vnd.nitf":["ntf","nitf"],"application/vnd.noblenet-directory":["nnd"],"application/vnd.noblenet-sealer":["nns"],"application/vnd.noblenet-web":["nnw"],"application/vnd.nokia.n-gage.ac+xml":["*ac"],"application/vnd.nokia.n-gage.data":["ngdat"],"application/vnd.nokia.n-gage.symbian.install":["n-gage"],"application/vnd.nokia.radio-preset":["rpst"],"application/vnd.nokia.radio-presets":["rpss"],"application/vnd.novadigm.edm":["edm"],"application/vnd.novadigm.edx":["edx"],"application/vnd.novadigm.ext":["ext"],"application/vnd.oasis.opendocument.chart":["odc"],"application/vnd.oasis.opendocument.chart-template":["otc"],"application/vnd.oasis.opendocument.database":["odb"],"application/vnd.oasis.opendocument.formula":["odf"],"application/vnd.oasis.opendocument.formula-template":["odft"],"application/vnd.oasis.opendocument.graphics":["odg"],"application/vnd.oasis.opendocument.graphics-template":["otg"],"application/vnd.oasis.opendocument.image":["odi"],"application/vnd.oasis.opendocument.image-template":["oti"],"application/vnd.oasis.opendocument.presentation":["odp"],"application/vnd.oasis.opendocument.presentation-template":["otp"],"application/vnd.oasis.opendocument.spreadsheet":["ods"],"application/vnd.oasis.opendocument.spreadsheet-template":["ots"],"application/vnd.oasis.opendocument.text":["odt"],"application/vnd.oasis.opendocument.text-master":["odm"],"application/vnd.oasis.opendocument.text-template":["ott"],"application/vnd.oasis.opendocument.text-web":["oth"],"application/vnd.olpc-sugar":["xo"],"application/vnd.oma.dd2+xml":["dd2"],"application/vnd.openblox.game+xml":["obgx"],"application/vnd.openofficeorg.extension":["oxt"],"application/vnd.openstreetmap.data+xml":["osm"],"application/vnd.openxmlformats-officedocument.presentationml.presentation":["pptx"],"application/vnd.openxmlformats-officedocument.presentationml.slide":["sldx"],"application/vnd.openxmlformats-officedocument.presentationml.slideshow":["ppsx"],"application/vnd.openxmlformats-officedocument.presentationml.template":["potx"],"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet":["xlsx"],"application/vnd.openxmlformats-officedocument.spreadsheetml.template":["xltx"],"application/vnd.openxmlformats-officedocument.wordprocessingml.document":["docx"],"application/vnd.openxmlformats-officedocument.wordprocessingml.template":["dotx"],"application/vnd.osgeo.mapguide.package":["mgp"],"application/vnd.osgi.dp":["dp"],"application/vnd.osgi.subsystem":["esa"],"application/vnd.palm":["pdb","pqa","oprc"],"application/vnd.pawaafile":["paw"],"application/vnd.pg.format":["str"],"application/vnd.pg.osasli":["ei6"],"application/vnd.picsel":["efif"],"application/vnd.pmi.widget":["wg"],"application/vnd.pocketlearn":["plf"],"application/vnd.powerbuilder6":["pbd"],"application/vnd.previewsystems.box":["box"],"application/vnd.proteus.magazine":["mgz"],"application/vnd.publishare-delta-tree":["qps"],"application/vnd.pvi.ptid1":["ptid"],"application/vnd.quark.quarkxpress":["qxd","qxt","qwd","qwt","qxl","qxb"],"application/vnd.rar":["rar"],"application/vnd.realvnc.bed":["bed"],"application/vnd.recordare.musicxml":["mxl"],"application/vnd.recordare.musicxml+xml":["musicxml"],"application/vnd.rig.cryptonote":["cryptonote"],"application/vnd.rim.cod":["cod"],"application/vnd.rn-realmedia":["rm"],"application/vnd.rn-realmedia-vbr":["rmvb"],"application/vnd.route66.link66+xml":["link66"],"application/vnd.sailingtracker.track":["st"],"application/vnd.seemail":["see"],"application/vnd.sema":["sema"],"application/vnd.semd":["semd"],"application/vnd.semf":["semf"],"application/vnd.shana.informed.formdata":["ifm"],"application/vnd.shana.informed.formtemplate":["itp"],"application/vnd.shana.informed.interchange":["iif"],"application/vnd.shana.informed.package":["ipk"],"application/vnd.simtech-mindmapper":["twd","twds"],"application/vnd.smaf":["mmf"],"application/vnd.smart.teacher":["teacher"],"application/vnd.software602.filler.form+xml":["fo"],"application/vnd.solent.sdkm+xml":["sdkm","sdkd"],"application/vnd.spotfire.dxp":["dxp"],"application/vnd.spotfire.sfs":["sfs"],"application/vnd.stardivision.calc":["sdc"],"application/vnd.stardivision.draw":["sda"],"application/vnd.stardivision.impress":["sdd"],"application/vnd.stardivision.math":["smf"],"application/vnd.stardivision.writer":["sdw","vor"],"application/vnd.stardivision.writer-global":["sgl"],"application/vnd.stepmania.package":["smzip"],"application/vnd.stepmania.stepchart":["sm"],"application/vnd.sun.wadl+xml":["wadl"],"application/vnd.sun.xml.calc":["sxc"],"application/vnd.sun.xml.calc.template":["stc"],"application/vnd.sun.xml.draw":["sxd"],"application/vnd.sun.xml.draw.template":["std"],"application/vnd.sun.xml.impress":["sxi"],"application/vnd.sun.xml.impress.template":["sti"],"application/vnd.sun.xml.math":["sxm"],"application/vnd.sun.xml.writer":["sxw"],"application/vnd.sun.xml.writer.global":["sxg"],"application/vnd.sun.xml.writer.template":["stw"],"application/vnd.sus-calendar":["sus","susp"],"application/vnd.svd":["svd"],"application/vnd.symbian.install":["sis","sisx"],"application/vnd.syncml+xml":["xsm"],"application/vnd.syncml.dm+wbxml":["bdm"],"application/vnd.syncml.dm+xml":["xdm"],"application/vnd.syncml.dmddf+xml":["ddf"],"application/vnd.tao.intent-module-archive":["tao"],"application/vnd.tcpdump.pcap":["pcap","cap","dmp"],"application/vnd.tmobile-livetv":["tmo"],"application/vnd.trid.tpt":["tpt"],"application/vnd.triscape.mxs":["mxs"],"application/vnd.trueapp":["tra"],"application/vnd.ufdl":["ufd","ufdl"],"application/vnd.uiq.theme":["utz"],"application/vnd.umajin":["umj"],"application/vnd.unity":["unityweb"],"application/vnd.uoml+xml":["uoml"],"application/vnd.vcx":["vcx"],"application/vnd.visio":["vsd","vst","vss","vsw"],"application/vnd.visionary":["vis"],"application/vnd.vsf":["vsf"],"application/vnd.wap.wbxml":["wbxml"],"application/vnd.wap.wmlc":["wmlc"],"application/vnd.wap.wmlscriptc":["wmlsc"],"application/vnd.webturbo":["wtb"],"application/vnd.wolfram.player":["nbp"],"application/vnd.wordperfect":["wpd"],"application/vnd.wqd":["wqd"],"application/vnd.wt.stf":["stf"],"application/vnd.xara":["xar"],"application/vnd.xfdl":["xfdl"],"application/vnd.yamaha.hv-dic":["hvd"],"application/vnd.yamaha.hv-script":["hvs"],"application/vnd.yamaha.hv-voice":["hvp"],"application/vnd.yamaha.openscoreformat":["osf"],"application/vnd.yamaha.openscoreformat.osfpvg+xml":["osfpvg"],"application/vnd.yamaha.smaf-audio":["saf"],"application/vnd.yamaha.smaf-phrase":["spf"],"application/vnd.yellowriver-custom-menu":["cmp"],"application/vnd.zul":["zir","zirz"],"application/vnd.zzazz.deck+xml":["zaz"],"application/x-7z-compressed":["7z"],"application/x-abiword":["abw"],"application/x-ace-compressed":["ace"],"application/x-apple-diskimage":["*dmg"],"application/x-arj":["arj"],"application/x-authorware-bin":["aab","x32","u32","vox"],"application/x-authorware-map":["aam"],"application/x-authorware-seg":["aas"],"application/x-bcpio":["bcpio"],"application/x-bdoc":["*bdoc"],"application/x-bittorrent":["torrent"],"application/x-blorb":["blb","blorb"],"application/x-bzip":["bz"],"application/x-bzip2":["bz2","boz"],"application/x-cbr":["cbr","cba","cbt","cbz","cb7"],"application/x-cdlink":["vcd"],"application/x-cfs-compressed":["cfs"],"application/x-chat":["chat"],"application/x-chess-pgn":["pgn"],"application/x-chrome-extension":["crx"],"application/x-cocoa":["cco"],"application/x-conference":["nsc"],"application/x-cpio":["cpio"],"application/x-csh":["csh"],"application/x-debian-package":["*deb","udeb"],"application/x-dgc-compressed":["dgc"],"application/x-director":["dir","dcr","dxr","cst","cct","cxt","w3d","fgd","swa"],"application/x-doom":["wad"],"application/x-dtbncx+xml":["ncx"],"application/x-dtbook+xml":["dtb"],"application/x-dtbresource+xml":["res"],"application/x-dvi":["dvi"],"application/x-envoy":["evy"],"application/x-eva":["eva"],"application/x-font-bdf":["bdf"],"application/x-font-ghostscript":["gsf"],"application/x-font-linux-psf":["psf"],"application/x-font-pcf":["pcf"],"application/x-font-snf":["snf"],"application/x-font-type1":["pfa","pfb","pfm","afm"],"application/x-freearc":["arc"],"application/x-futuresplash":["spl"],"application/x-gca-compressed":["gca"],"application/x-glulx":["ulx"],"application/x-gnumeric":["gnumeric"],"application/x-gramps-xml":["gramps"],"application/x-gtar":["gtar"],"application/x-hdf":["hdf"],"application/x-httpd-php":["php"],"application/x-install-instructions":["install"],"application/x-iso9660-image":["*iso"],"application/x-iwork-keynote-sffkey":["*key"],"application/x-iwork-numbers-sffnumbers":["*numbers"],"application/x-iwork-pages-sffpages":["*pages"],"application/x-java-archive-diff":["jardiff"],"application/x-java-jnlp-file":["jnlp"],"application/x-keepass2":["kdbx"],"application/x-latex":["latex"],"application/x-lua-bytecode":["luac"],"application/x-lzh-compressed":["lzh","lha"],"application/x-makeself":["run"],"application/x-mie":["mie"],"application/x-mobipocket-ebook":["prc","mobi"],"application/x-ms-application":["application"],"application/x-ms-shortcut":["lnk"],"application/x-ms-wmd":["wmd"],"application/x-ms-wmz":["wmz"],"application/x-ms-xbap":["xbap"],"application/x-msaccess":["mdb"],"application/x-msbinder":["obd"],"application/x-mscardfile":["crd"],"application/x-msclip":["clp"],"application/x-msdos-program":["*exe"],"application/x-msdownload":["*exe","*dll","com","bat","*msi"],"application/x-msmediaview":["mvb","m13","m14"],"application/x-msmetafile":["*wmf","*wmz","*emf","emz"],"application/x-msmoney":["mny"],"application/x-mspublisher":["pub"],"application/x-msschedule":["scd"],"application/x-msterminal":["trm"],"application/x-mswrite":["wri"],"application/x-netcdf":["nc","cdf"],"application/x-ns-proxy-autoconfig":["pac"],"application/x-nzb":["nzb"],"application/x-perl":["pl","pm"],"application/x-pilot":["*prc","*pdb"],"application/x-pkcs12":["p12","pfx"],"application/x-pkcs7-certificates":["p7b","spc"],"application/x-pkcs7-certreqresp":["p7r"],"application/x-rar-compressed":["*rar"],"application/x-redhat-package-manager":["rpm"],"application/x-research-info-systems":["ris"],"application/x-sea":["sea"],"application/x-sh":["sh"],"application/x-shar":["shar"],"application/x-shockwave-flash":["swf"],"application/x-silverlight-app":["xap"],"application/x-sql":["sql"],"application/x-stuffit":["sit"],"application/x-stuffitx":["sitx"],"application/x-subrip":["srt"],"application/x-sv4cpio":["sv4cpio"],"application/x-sv4crc":["sv4crc"],"application/x-t3vm-image":["t3"],"application/x-tads":["gam"],"application/x-tar":["tar"],"application/x-tcl":["tcl","tk"],"application/x-tex":["tex"],"application/x-tex-tfm":["tfm"],"application/x-texinfo":["texinfo","texi"],"application/x-tgif":["*obj"],"application/x-ustar":["ustar"],"application/x-virtualbox-hdd":["hdd"],"application/x-virtualbox-ova":["ova"],"application/x-virtualbox-ovf":["ovf"],"application/x-virtualbox-vbox":["vbox"],"application/x-virtualbox-vbox-extpack":["vbox-extpack"],"application/x-virtualbox-vdi":["vdi"],"application/x-virtualbox-vhd":["vhd"],"application/x-virtualbox-vmdk":["vmdk"],"application/x-wais-source":["src"],"application/x-web-app-manifest+json":["webapp"],"application/x-x509-ca-cert":["der","crt","pem"],"application/x-xfig":["fig"],"application/x-xliff+xml":["*xlf"],"application/x-xpinstall":["xpi"],"application/x-xz":["xz"],"application/x-zmachine":["z1","z2","z3","z4","z5","z6","z7","z8"],"audio/vnd.dece.audio":["uva","uvva"],"audio/vnd.digital-winds":["eol"],"audio/vnd.dra":["dra"],"audio/vnd.dts":["dts"],"audio/vnd.dts.hd":["dtshd"],"audio/vnd.lucent.voice":["lvp"],"audio/vnd.ms-playready.media.pya":["pya"],"audio/vnd.nuera.ecelp4800":["ecelp4800"],"audio/vnd.nuera.ecelp7470":["ecelp7470"],"audio/vnd.nuera.ecelp9600":["ecelp9600"],"audio/vnd.rip":["rip"],"audio/x-aac":["aac"],"audio/x-aiff":["aif","aiff","aifc"],"audio/x-caf":["caf"],"audio/x-flac":["flac"],"audio/x-m4a":["*m4a"],"audio/x-matroska":["mka"],"audio/x-mpegurl":["m3u"],"audio/x-ms-wax":["wax"],"audio/x-ms-wma":["wma"],"audio/x-pn-realaudio":["ram","ra"],"audio/x-pn-realaudio-plugin":["rmp"],"audio/x-realaudio":["*ra"],"audio/x-wav":["*wav"],"chemical/x-cdx":["cdx"],"chemical/x-cif":["cif"],"chemical/x-cmdf":["cmdf"],"chemical/x-cml":["cml"],"chemical/x-csml":["csml"],"chemical/x-xyz":["xyz"],"image/prs.btif":["btif"],"image/prs.pti":["pti"],"image/vnd.adobe.photoshop":["psd"],"image/vnd.airzip.accelerator.azv":["azv"],"image/vnd.dece.graphic":["uvi","uvvi","uvg","uvvg"],"image/vnd.djvu":["djvu","djv"],"image/vnd.dvb.subtitle":["*sub"],"image/vnd.dwg":["dwg"],"image/vnd.dxf":["dxf"],"image/vnd.fastbidsheet":["fbs"],"image/vnd.fpx":["fpx"],"image/vnd.fst":["fst"],"image/vnd.fujixerox.edmics-mmr":["mmr"],"image/vnd.fujixerox.edmics-rlc":["rlc"],"image/vnd.microsoft.icon":["ico"],"image/vnd.ms-dds":["dds"],"image/vnd.ms-modi":["mdi"],"image/vnd.ms-photo":["wdp"],"image/vnd.net-fpx":["npx"],"image/vnd.pco.b16":["b16"],"image/vnd.tencent.tap":["tap"],"image/vnd.valve.source.texture":["vtf"],"image/vnd.wap.wbmp":["wbmp"],"image/vnd.xiff":["xif"],"image/vnd.zbrush.pcx":["pcx"],"image/x-3ds":["3ds"],"image/x-cmu-raster":["ras"],"image/x-cmx":["cmx"],"image/x-freehand":["fh","fhc","fh4","fh5","fh7"],"image/x-icon":["*ico"],"image/x-jng":["jng"],"image/x-mrsid-image":["sid"],"image/x-ms-bmp":["*bmp"],"image/x-pcx":["*pcx"],"image/x-pict":["pic","pct"],"image/x-portable-anymap":["pnm"],"image/x-portable-bitmap":["pbm"],"image/x-portable-graymap":["pgm"],"image/x-portable-pixmap":["ppm"],"image/x-rgb":["rgb"],"image/x-tga":["tga"],"image/x-xbitmap":["xbm"],"image/x-xpixmap":["xpm"],"image/x-xwindowdump":["xwd"],"message/vnd.wfa.wsc":["wsc"],"model/vnd.collada+xml":["dae"],"model/vnd.dwf":["dwf"],"model/vnd.gdl":["gdl"],"model/vnd.gtw":["gtw"],"model/vnd.mts":["mts"],"model/vnd.opengex":["ogex"],"model/vnd.parasolid.transmit.binary":["x_b"],"model/vnd.parasolid.transmit.text":["x_t"],"model/vnd.sap.vds":["vds"],"model/vnd.usdz+zip":["usdz"],"model/vnd.valve.source.compiled-map":["bsp"],"model/vnd.vtu":["vtu"],"text/prs.lines.tag":["dsc"],"text/vnd.curl":["curl"],"text/vnd.curl.dcurl":["dcurl"],"text/vnd.curl.mcurl":["mcurl"],"text/vnd.curl.scurl":["scurl"],"text/vnd.dvb.subtitle":["sub"],"text/vnd.fly":["fly"],"text/vnd.fmi.flexstor":["flx"],"text/vnd.graphviz":["gv"],"text/vnd.in3d.3dml":["3dml"],"text/vnd.in3d.spot":["spot"],"text/vnd.sun.j2me.app-descriptor":["jad"],"text/vnd.wap.wml":["wml"],"text/vnd.wap.wmlscript":["wmls"],"text/x-asm":["s","asm"],"text/x-c":["c","cc","cxx","cpp","h","hh","dic"],"text/x-component":["htc"],"text/x-fortran":["f","for","f77","f90"],"text/x-handlebars-template":["hbs"],"text/x-java-source":["java"],"text/x-lua":["lua"],"text/x-markdown":["mkd"],"text/x-nfo":["nfo"],"text/x-opml":["opml"],"text/x-org":["*org"],"text/x-pascal":["p","pas"],"text/x-processing":["pde"],"text/x-sass":["sass"],"text/x-scss":["scss"],"text/x-setext":["etx"],"text/x-sfv":["sfv"],"text/x-suse-ymp":["ymp"],"text/x-uuencode":["uu"],"text/x-vcalendar":["vcs"],"text/x-vcard":["vcf"],"video/vnd.dece.hd":["uvh","uvvh"],"video/vnd.dece.mobile":["uvm","uvvm"],"video/vnd.dece.pd":["uvp","uvvp"],"video/vnd.dece.sd":["uvs","uvvs"],"video/vnd.dece.video":["uvv","uvvv"],"video/vnd.dvb.file":["dvb"],"video/vnd.fvt":["fvt"],"video/vnd.mpegurl":["mxu","m4u"],"video/vnd.ms-playready.media.pyv":["pyv"],"video/vnd.uvvu.mp4":["uvu","uvvu"],"video/vnd.vivo":["viv"],"video/x-f4v":["f4v"],"video/x-fli":["fli"],"video/x-flv":["flv"],"video/x-m4v":["m4v"],"video/x-matroska":["mkv","mk3d","mks"],"video/x-mng":["mng"],"video/x-ms-asf":["asf","asx"],"video/x-ms-vob":["vob"],"video/x-ms-wm":["wm"],"video/x-ms-wmv":["wmv"],"video/x-ms-wmx":["wmx"],"video/x-ms-wvx":["wvx"],"video/x-msvideo":["avi"],"video/x-sgi-movie":["movie"],"video/x-smv":["smv"],"x-conference/x-cooltalk":["ice"]}});var hp=x((zI,fp)=>{"use strict";var Zw=op();fp.exports=new Zw(lp(),up())});var dp=x((JI,pp)=>{pp.exports=function(i,e){for(var t=[],r=0;r{"use strict";yp.exports=gp;function gp(i,e,t){i instanceof RegExp&&(i=mp(i,t)),e instanceof RegExp&&(e=mp(e,t));var r=vp(i,e,t);return r&&{start:r[0],end:r[1],pre:t.slice(0,r[0]),body:t.slice(r[0]+i.length,r[1]),post:t.slice(r[1]+e.length)}}function mp(i,e){var t=e.match(i);return t?t[0]:null}gp.range=vp;function vp(i,e,t){var r,n,s,o,a,l=t.indexOf(i),c=t.indexOf(e,l+1),u=l;if(l>=0&&c>0){if(i===e)return[l,c];for(r=[],s=t.length;u>=0&&!a;)u==l?(r.push(u),l=t.indexOf(i,u+1)):r.length==1?a=[r.pop(),c]:(n=r.pop(),n=0?l:c;r.length&&(a=[s,o])}return a}});var Cp=x((QI,kp)=>{var Xw=dp(),_p=bp();kp.exports=i1;var wp="\0SLASH"+Math.random()+"\0",xp="\0OPEN"+Math.random()+"\0",Ya="\0CLOSE"+Math.random()+"\0",Sp="\0COMMA"+Math.random()+"\0",Ep="\0PERIOD"+Math.random()+"\0";function Wa(i){return parseInt(i,10)==i?parseInt(i,10):i.charCodeAt(0)}function e1(i){return i.split("\\\\").join(wp).split("\\{").join(xp).split("\\}").join(Ya).split("\\,").join(Sp).split("\\.").join(Ep)}function t1(i){return i.split(wp).join("\\").split(xp).join("{").split(Ya).join("}").split(Sp).join(",").split(Ep).join(".")}function Op(i){if(!i)return[""];var e=[],t=_p("{","}",i);if(!t)return i.split(",");var r=t.pre,n=t.body,s=t.post,o=r.split(",");o[o.length-1]+="{"+n+"}";var a=Op(s);return s.length&&(o[o.length-1]+=a.shift(),o.push.apply(o,a)),e.push.apply(e,o),e}function i1(i){return i?(i.substr(0,2)==="{}"&&(i="\\{\\}"+i.substr(2)),Or(e1(i),!0).map(t1)):[]}function r1(i){return"{"+i+"}"}function n1(i){return/^-?0\d/.test(i)}function s1(i,e){return i<=e}function o1(i,e){return i>=e}function Or(i,e){var t=[],r=_p("{","}",i);if(!r||/\$$/.test(r.pre))return[i];var n=/^-?\d+\.\.-?\d+(?:\.\.-?\d+)?$/.test(r.body),s=/^[a-zA-Z]\.\.[a-zA-Z](?:\.\.-?\d+)?$/.test(r.body),o=n||s,a=r.body.indexOf(",")>=0;if(!o&&!a)return r.post.match(/,(?!,).*\}/)?(i=r.pre+"{"+r.body+Ya+r.post,Or(i)):[i];var l;if(o)l=r.body.split(/\.\./);else if(l=Op(r.body),l.length===1&&(l=Or(l[0],!1).map(r1),l.length===1)){var u=r.post.length?Or(r.post,!1):[""];return u.map(function(P){return r.pre+l[0]+P})}var c=r.pre,u=r.post.length?Or(r.post,!1):[""],f;if(o){var d=Wa(l[0]),m=Wa(l[1]),g=Math.max(l[0].length,l[1].length),y=l.length==3?Math.abs(Wa(l[2])):1,b=s1,w=m0){var R=new Array(E+1).join("0");k<0?O="-"+R+O.slice(1):O=R+O}}f.push(O)}}else f=Xw(l,function(B){return Or(B,!1)});for(var T=0;T{Bp.exports=Et;Et.Minimatch=et;var ln=(function(){try{return require("path")}catch{}})()||{sep:"/"};Et.sep=ln.sep;var Ja=Et.GLOBSTAR=et.GLOBSTAR={},a1=Cp(),Tp={"!":{open:"(?:(?!(?:",close:"))[^/]*?)"},"?":{open:"(?:",close:")?"},"+":{open:"(?:",close:")+"},"*":{open:"(?:",close:")*"},"@":{open:"(?:",close:")"}},Ka="[^/]",za=Ka+"*?",l1="(?:(?!(?:\\/|^)(?:\\.{1,2})($|\\/)).)*?",c1="(?:(?!(?:\\/|^)\\.).)*?",Ap=u1("().*{}+?[]^$\\!");function u1(i){return i.split("").reduce(function(e,t){return e[t]=!0,e},{})}var Ip=/\/+/;Et.filter=f1;function f1(i,e){return e=e||{},function(t,r,n){return Et(t,i,e)}}function _i(i,e){e=e||{};var t={};return Object.keys(i).forEach(function(r){t[r]=i[r]}),Object.keys(e).forEach(function(r){t[r]=e[r]}),t}Et.defaults=function(i){if(!i||typeof i!="object"||!Object.keys(i).length)return Et;var e=Et,t=function(n,s,o){return e(n,s,_i(i,o))};return t.Minimatch=function(n,s){return new e.Minimatch(n,_i(i,s))},t.Minimatch.defaults=function(n){return e.defaults(_i(i,n)).Minimatch},t.filter=function(n,s){return e.filter(n,_i(i,s))},t.defaults=function(n){return e.defaults(_i(i,n))},t.makeRe=function(n,s){return e.makeRe(n,_i(i,s))},t.braceExpand=function(n,s){return e.braceExpand(n,_i(i,s))},t.match=function(r,n,s){return e.match(r,n,_i(i,s))},t};et.defaults=function(i){return Et.defaults(i).Minimatch};function Et(i,e,t){return Ms(e),t||(t={}),!t.nocomment&&e.charAt(0)==="#"?!1:new et(e,t).match(i)}function et(i,e){if(!(this instanceof et))return new et(i,e);Ms(i),e||(e={}),i=i.trim(),!e.allowWindowsEscape&&ln.sep!=="/"&&(i=i.split(ln.sep).join("/")),this.options=e,this.set=[],this.pattern=i,this.regexp=null,this.negate=!1,this.comment=!1,this.empty=!1,this.partial=!!e.partial,this.make()}et.prototype.debug=function(){};et.prototype.make=h1;function h1(){var i=this.pattern,e=this.options;if(!e.nocomment&&i.charAt(0)==="#"){this.comment=!0;return}if(!i){this.empty=!0;return}this.parseNegate();var t=this.globSet=this.braceExpand();e.debug&&(this.debug=function(){console.error.apply(console,arguments)}),this.debug(this.pattern,t),t=this.globParts=t.map(function(r){return r.split(Ip)}),this.debug(this.pattern,t),t=t.map(function(r,n,s){return r.map(this.parse,this)},this),this.debug(this.pattern,t),t=t.filter(function(r){return r.indexOf(!1)===-1}),this.debug(this.pattern,t),this.set=t}et.prototype.parseNegate=p1;function p1(){var i=this.pattern,e=!1,t=this.options,r=0;if(!t.nonegate){for(var n=0,s=i.length;nd1)throw new TypeError("pattern is too long")};et.prototype.parse=m1;var Ps={};function m1(i,e){Ms(i);var t=this.options;if(i==="**")if(t.noglobstar)i="*";else return Ja;if(i==="")return"";var r="",n=!!t.nocase,s=!1,o=[],a=[],l,c=!1,u=-1,f=-1,d=i.charAt(0)==="."?"":t.dot?"(?!(?:^|\\/)\\.{1,2}(?:$|\\/))":"(?!\\.)",m=this;function g(){if(l){switch(l){case"*":r+=za,n=!0;break;case"?":r+=Ka,n=!0;break;default:r+="\\"+l;break}m.debug("clearStateChar %j %j",l,r),l=!1}}for(var y=0,b=i.length,w;y-1;A--){var C=a[A],B=r.slice(0,C.reStart),P=r.slice(C.reStart,C.reEnd-8),U=r.slice(C.reEnd-8,C.reEnd),F=r.slice(C.reEnd);U+=F;var H=B.split("(").length-1,j=F;for(y=0;y=0&&(s=e[o],!s);o--);for(o=0;o>> no match, partial?`,i,u,e,f),u===o))}var m;if(typeof l=="string"?(m=c===l,this.debug("string match",l,c,m)):(m=c.match(l),this.debug("pattern match",l,c,m)),!m)return!1}if(n===o&&s===a)return!0;if(n===o)return t;if(s===a)return n===o-1&&i[n]==="";throw new Error("wtf?")};function v1(i){return i.replace(/\\(.)/g,"$1")}function y1(i){return i.replace(/[-[\]{}()*+?.,\\^$|#\s]/g,"\\$&")}});var Qa=x((e2,Pp)=>{"use strict";var Rp=require("fs"),Za;function b1(){try{return Rp.statSync("/.dockerenv"),!0}catch{return!1}}function _1(){try{return Rp.readFileSync("/proc/self/cgroup","utf8").includes("docker")}catch{return!1}}Pp.exports=()=>(Za===void 0&&(Za=b1()||_1()),Za)});var Fp=x((t2,Xa)=>{"use strict";var w1=require("os"),x1=require("fs"),Mp=Qa(),qp=()=>{if(process.platform!=="linux")return!1;if(w1.release().toLowerCase().includes("microsoft"))return!Mp();try{return x1.readFileSync("/proc/version","utf8").toLowerCase().includes("microsoft")?!Mp():!1}catch{return!1}};process.env.__IS_WSL_TEST__?Xa.exports=qp:Xa.exports=qp()});var jp=x((i2,Dp)=>{"use strict";Dp.exports=(i,e,t)=>{let r=n=>Object.defineProperty(i,e,{value:n,enumerable:!0,writable:!0});return Object.defineProperty(i,e,{configurable:!0,enumerable:!0,get(){let n=t();return r(n),n},set(n){r(n)}}),i}});var Yp=x((r2,Wp)=>{var S1=require("path"),E1=require("child_process"),{promises:el,constants:Gp}=require("fs"),qs=Fp(),O1=Qa(),tl=jp(),Up=S1.join(__dirname,"xdg-open"),{platform:kr,arch:$p}=process,k1=(()=>{let i="/mnt/",e;return async function(){if(e)return e;let t="/etc/wsl.conf",r=!1;try{await el.access(t,Gp.F_OK),r=!0}catch{}if(!r)return i;let n=await el.readFile(t,{encoding:"utf8"}),s=/(?.*)/g.exec(n);return s?(e=s.groups.mountPoint.trim(),e=e.endsWith("/")?e:`${e}/`,e):i}})(),Vp=async(i,e)=>{let t;for(let r of i)try{return await e(r)}catch(n){t=n}throw t},Fs=async i=>{if(i={wait:!1,background:!1,newInstance:!1,allowNonzeroExitCode:!1,...i},Array.isArray(i.app))return Vp(i.app,a=>Fs({...i,app:a}));let{name:e,arguments:t=[]}=i.app||{};if(t=[...t],Array.isArray(e))return Vp(e,a=>Fs({...i,app:{name:a,arguments:t}}));let r,n=[],s={};if(kr==="darwin")r="open",i.wait&&n.push("--wait-apps"),i.background&&n.push("--background"),i.newInstance&&n.push("--new"),e&&n.push("-a",e);else if(kr==="win32"||qs&&!O1()){let a=await k1();r=qs?`${a}c/Windows/System32/WindowsPowerShell/v1.0/powershell.exe`:`${process.env.SYSTEMROOT}\\System32\\WindowsPowerShell\\v1.0\\powershell`,n.push("-NoProfile","-NonInteractive","\u2013ExecutionPolicy","Bypass","-EncodedCommand"),qs||(s.windowsVerbatimArguments=!0);let l=["Start"];i.wait&&l.push("-Wait"),e?(l.push(`"\`"${e}\`""`,"-ArgumentList"),i.target&&t.unshift(i.target)):i.target&&l.push(`"${i.target}"`),t.length>0&&(t=t.map(c=>`"\`"${c}\`""`),l.push(t.join(","))),i.target=Buffer.from(l.join(" "),"utf16le").toString("base64")}else{if(e)r=e;else{let a=!__dirname||__dirname==="/",l=!1;try{await el.access(Up,Gp.X_OK),l=!0}catch{}r=process.versions.electron||kr==="android"||a||!l?"xdg-open":Up}t.length>0&&n.push(...t),i.wait||(s.stdio="ignore",s.detached=!0)}i.target&&n.push(i.target),kr==="darwin"&&t.length>0&&n.push("--args",...t);let o=E1.spawn(r,n,s);return i.wait?new Promise((a,l)=>{o.once("error",l),o.once("close",c=>{if(i.allowNonzeroExitCode&&c>0){l(new Error(`Exited with code ${c}`));return}a(o)})}):(o.unref(),o)},il=(i,e)=>{if(typeof i!="string")throw new TypeError("Expected a `target`");return Fs({...e,target:i})},C1=(i,e)=>{if(typeof i!="string")throw new TypeError("Expected a `name`");let{arguments:t=[]}=e||{};if(t!=null&&!Array.isArray(t))throw new TypeError("Expected `appArguments` as Array type");return Fs({...e,app:{name:i,arguments:t}})};function Hp(i){if(typeof i=="string"||Array.isArray(i))return i;let{[$p]:e}=i;if(!e)throw new Error(`${$p} is not supported`);return e}function rl({[kr]:i},{wsl:e}){if(e&&qs)return Hp(e);if(!i)throw new Error(`${kr} is not supported`);return Hp(i)}var Ds={};tl(Ds,"chrome",()=>rl({darwin:"google chrome",win32:"chrome",linux:["google-chrome","google-chrome-stable","chromium"]},{wsl:{ia32:"/mnt/c/Program Files (x86)/Google/Chrome/Application/chrome.exe",x64:["/mnt/c/Program Files/Google/Chrome/Application/chrome.exe","/mnt/c/Program Files (x86)/Google/Chrome/Application/chrome.exe"]}}));tl(Ds,"firefox",()=>rl({darwin:"firefox",win32:"C:\\Program Files\\Mozilla Firefox\\firefox.exe",linux:"firefox"},{wsl:"/mnt/c/Program Files/Mozilla Firefox/firefox.exe"}));tl(Ds,"edge",()=>rl({darwin:"microsoft edge",win32:"msedge",linux:["microsoft-edge","microsoft-edge-dev"]},{wsl:"/mnt/c/Program Files (x86)/Microsoft/Edge/Application/msedge.exe"}));il.apps=Ds;il.openApp=C1;Wp.exports=il});var nl=x((n2,zp)=>{"use strict";var T1=require("util"),Kp=require("stream"),Vt=zp.exports=function(){Kp.call(this),this._buffers=[],this._buffered=0,this._reads=[],this._paused=!1,this._encoding="utf8",this.writable=!0};T1.inherits(Vt,Kp);Vt.prototype.read=function(i,e){this._reads.push({length:Math.abs(i),allowLess:i<0,func:e}),process.nextTick(function(){this._process(),this._paused&&this._reads&&this._reads.length>0&&(this._paused=!1,this.emit("drain"))}.bind(this))};Vt.prototype.write=function(i,e){if(!this.writable)return this.emit("error",new Error("Stream not writable")),!1;let t;return Buffer.isBuffer(i)?t=i:t=Buffer.from(i,e||this._encoding),this._buffers.push(t),this._buffered+=t.length,this._process(),this._reads&&this._reads.length===0&&(this._paused=!0),this.writable&&!this._paused};Vt.prototype.end=function(i,e){i&&this.write(i,e),this.writable=!1,this._buffers&&(this._buffers.length===0?this._end():(this._buffers.push(null),this._process()))};Vt.prototype.destroySoon=Vt.prototype.end;Vt.prototype._end=function(){this._reads.length>0&&this.emit("error",new Error("Unexpected end of input")),this.destroy()};Vt.prototype.destroy=function(){this._buffers&&(this.writable=!1,this._reads=null,this._buffers=null,this.emit("close"))};Vt.prototype._processReadAllowingLess=function(i){this._reads.shift();let e=this._buffers[0];e.length>i.length?(this._buffered-=i.length,this._buffers[0]=e.slice(i.length),i.func.call(this,e.slice(0,i.length))):(this._buffered-=e.length,this._buffers.shift(),i.func.call(this,e))};Vt.prototype._processRead=function(i){this._reads.shift();let e=0,t=0,r=Buffer.alloc(i.length);for(;e0&&this._buffers.splice(0,t),this._buffered-=i.length,i.func.call(this,r)};Vt.prototype._process=function(){try{for(;this._buffered>0&&this._reads&&this._reads.length>0;){let i=this._reads[0];if(i.allowLess)this._processReadAllowingLess(i);else if(this._buffered>=i.length)this._processRead(i);else break}this._buffers&&!this.writable&&this._end()}catch(i){this.emit("error",i)}}});var ol=x(sl=>{"use strict";var wi=[{x:[0],y:[0]},{x:[4],y:[0]},{x:[0,4],y:[4]},{x:[2,6],y:[0,4]},{x:[0,2,4,6],y:[2,6]},{x:[1,3,5,7],y:[0,2,4,6]},{x:[0,1,2,3,4,5,6,7],y:[1,3,5,7]}];sl.getImagePasses=function(i,e){let t=[],r=i%8,n=e%8,s=(i-r)/8,o=(e-n)/8;for(let a=0;a0&&u>0&&t.push({width:c,height:u,index:a})}return t};sl.getInterlaceIterator=function(i){return function(e,t,r){let n=e%wi[r].x.length,s=(e-n)/wi[r].x.length*8+wi[r].x[n],o=t%wi[r].y.length,a=(t-o)/wi[r].y.length*8+wi[r].y[o];return s*4+a*i*4}}});var al=x((o2,Jp)=>{"use strict";Jp.exports=function(e,t,r){let n=e+t-r,s=Math.abs(n-e),o=Math.abs(n-t),a=Math.abs(n-r);return s<=o&&s<=a?e:o<=a?t:r}});var ll=x((a2,Qp)=>{"use strict";var A1=ol(),I1=al();function Zp(i,e,t){let r=i*e;return t!==8&&(r=Math.ceil(r/(8/t))),r}var Cr=Qp.exports=function(i,e){let t=i.width,r=i.height,n=i.interlace,s=i.bpp,o=i.depth;if(this.read=e.read,this.write=e.write,this.complete=e.complete,this._imageIndex=0,this._images=[],n){let a=A1.getImagePasses(t,r);for(let l=0;ln?e[s-r]:0;e[s]=o+a}};Cr.prototype._unFilterType2=function(i,e,t){let r=this._lastLine;for(let n=0;nn?e[o-r]:0,u=Math.floor((c+l)/2);e[o]=a+u}};Cr.prototype._unFilterType4=function(i,e,t){let r=this._xComparison,n=r-1,s=this._lastLine;for(let o=0;on?e[o-r]:0,u=o>n&&s?s[o-r]:0,f=I1(c,l,u);e[o]=a+f}};Cr.prototype._reverseFilterLine=function(i){let e=i[0],t,r=this._images[this._imageIndex],n=r.byteWidth;if(e===0)t=i.slice(1,n+1);else switch(t=Buffer.alloc(n),e){case 1:this._unFilterType1(i,t,n);break;case 2:this._unFilterType2(i,t,n);break;case 3:this._unFilterType3(i,t,n);break;case 4:this._unFilterType4(i,t,n);break;default:throw new Error("Unrecognised filter type - "+e)}this.write(t),r.lineIndex++,r.lineIndex>=r.height?(this._lastLine=null,this._imageIndex++,r=this._images[this._imageIndex]):this._lastLine=t,r?this.read(r.byteWidth+1,this._reverseFilterLine.bind(this)):(this._lastLine=null,this.complete())}});var td=x((l2,ed)=>{"use strict";var N1=require("util"),Xp=nl(),B1=ll(),L1=ed.exports=function(i){Xp.call(this);let e=[],t=this;this._filter=new B1(i,{read:this.read.bind(this),write:function(r){e.push(r)},complete:function(){t.emit("complete",Buffer.concat(e))}}),this._filter.start()};N1.inherits(L1,Xp)});var Tr=x((c2,id)=>{"use strict";id.exports={PNG_SIGNATURE:[137,80,78,71,13,10,26,10],TYPE_IHDR:1229472850,TYPE_IEND:1229278788,TYPE_IDAT:1229209940,TYPE_PLTE:1347179589,TYPE_tRNS:1951551059,TYPE_gAMA:1732332865,COLORTYPE_GRAYSCALE:0,COLORTYPE_PALETTE:1,COLORTYPE_COLOR:2,COLORTYPE_ALPHA:4,COLORTYPE_PALETTE_COLOR:3,COLORTYPE_COLOR_ALPHA:6,COLORTYPE_TO_BPP_MAP:{0:1,2:3,3:1,4:2,6:4},GAMMA_DIVISION:1e5}});var fl=x((u2,rd)=>{"use strict";var cl=[];(function(){for(let i=0;i<256;i++){let e=i;for(let t=0;t<8;t++)e&1?e=3988292384^e>>>1:e=e>>>1;cl[i]=e}})();var ul=rd.exports=function(){this._crc=-1};ul.prototype.write=function(i){for(let e=0;e>>8;return!0};ul.prototype.crc32=function(){return this._crc^-1};ul.crc32=function(i){let e=-1;for(let t=0;t>>8;return e^-1}});var hl=x((f2,nd)=>{"use strict";var He=Tr(),R1=fl(),ze=nd.exports=function(i,e){this._options=i,i.checkCRC=i.checkCRC!==!1,this._hasIHDR=!1,this._hasIEND=!1,this._emittedHeadersFinished=!1,this._palette=[],this._colorType=0,this._chunks={},this._chunks[He.TYPE_IHDR]=this._handleIHDR.bind(this),this._chunks[He.TYPE_IEND]=this._handleIEND.bind(this),this._chunks[He.TYPE_IDAT]=this._handleIDAT.bind(this),this._chunks[He.TYPE_PLTE]=this._handlePLTE.bind(this),this._chunks[He.TYPE_tRNS]=this._handleTRNS.bind(this),this._chunks[He.TYPE_gAMA]=this._handleGAMA.bind(this),this.read=e.read,this.error=e.error,this.metadata=e.metadata,this.gamma=e.gamma,this.transColor=e.transColor,this.palette=e.palette,this.parsed=e.parsed,this.inflateData=e.inflateData,this.finished=e.finished,this.simpleTransparency=e.simpleTransparency,this.headersFinished=e.headersFinished||function(){}};ze.prototype.start=function(){this.read(He.PNG_SIGNATURE.length,this._parseSignature.bind(this))};ze.prototype._parseSignature=function(i){let e=He.PNG_SIGNATURE;for(let t=0;tthis._palette.length){this.error(new Error("More transparent colors than palette size"));return}for(let e=0;e0?this._handleIDAT(t):this._handleChunkEnd()};ze.prototype._handleIEND=function(i){this.read(i,this._parseIEND.bind(this))};ze.prototype._parseIEND=function(i){this._crc.write(i),this._hasIEND=!0,this._handleChunkEnd(),this.finished&&this.finished()}});var pl=x(od=>{"use strict";var sd=ol(),P1=[function(){},function(i,e,t,r){if(r===e.length)throw new Error("Ran out of data");let n=e[r];i[t]=n,i[t+1]=n,i[t+2]=n,i[t+3]=255},function(i,e,t,r){if(r+1>=e.length)throw new Error("Ran out of data");let n=e[r];i[t]=n,i[t+1]=n,i[t+2]=n,i[t+3]=e[r+1]},function(i,e,t,r){if(r+2>=e.length)throw new Error("Ran out of data");i[t]=e[r],i[t+1]=e[r+1],i[t+2]=e[r+2],i[t+3]=255},function(i,e,t,r){if(r+3>=e.length)throw new Error("Ran out of data");i[t]=e[r],i[t+1]=e[r+1],i[t+2]=e[r+2],i[t+3]=e[r+3]}],M1=[function(){},function(i,e,t,r){let n=e[0];i[t]=n,i[t+1]=n,i[t+2]=n,i[t+3]=r},function(i,e,t){let r=e[0];i[t]=r,i[t+1]=r,i[t+2]=r,i[t+3]=e[1]},function(i,e,t,r){i[t]=e[0],i[t+1]=e[1],i[t+2]=e[2],i[t+3]=r},function(i,e,t){i[t]=e[0],i[t+1]=e[1],i[t+2]=e[2],i[t+3]=e[3]}];function q1(i,e){let t=[],r=0;function n(){if(r===i.length)throw new Error("Ran out of data");let s=i[r];r++;let o,a,l,c,u,f,d,m;switch(e){default:throw new Error("unrecognised depth");case 16:d=i[r],r++,t.push((s<<8)+d);break;case 4:d=s&15,m=s>>4,t.push(m,d);break;case 2:u=s&3,f=s>>2&3,d=s>>4&3,m=s>>6&3,t.push(m,d,f,u);break;case 1:o=s&1,a=s>>1&1,l=s>>2&1,c=s>>3&1,u=s>>4&1,f=s>>5&1,d=s>>6&1,m=s>>7&1,t.push(m,d,f,u,c,l,a,o);break}}return{get:function(s){for(;t.length{"use strict";function j1(i,e,t,r,n){let s=0;for(let o=0;o{"use strict";var V1=require("util"),ml=require("zlib"),ld=nl(),H1=td(),G1=hl(),W1=pl(),Y1=dl(),zt=cd.exports=function(i){ld.call(this),this._parser=new G1(i,{read:this.read.bind(this),error:this._handleError.bind(this),metadata:this._handleMetaData.bind(this),gamma:this.emit.bind(this,"gamma"),palette:this._handlePalette.bind(this),transColor:this._handleTransColor.bind(this),finished:this._finished.bind(this),inflateData:this._inflateData.bind(this),simpleTransparency:this._simpleTransparency.bind(this),headersFinished:this._headersFinished.bind(this)}),this._options=i,this.writable=!0,this._parser.start()};V1.inherits(zt,ld);zt.prototype._handleError=function(i){this.emit("error",i),this.writable=!1,this.destroy(),this._inflate&&this._inflate.destroy&&this._inflate.destroy(),this._filter&&(this._filter.destroy(),this._filter.on("error",function(){})),this.errord=!0};zt.prototype._inflateData=function(i){if(!this._inflate)if(this._bitmapInfo.interlace)this._inflate=ml.createInflate(),this._inflate.on("error",this.emit.bind(this,"error")),this._filter.on("complete",this._complete.bind(this)),this._inflate.pipe(this._filter);else{let t=((this._bitmapInfo.width*this._bitmapInfo.bpp*this._bitmapInfo.depth+7>>3)+1)*this._bitmapInfo.height,r=Math.max(t,ml.Z_MIN_CHUNK);this._inflate=ml.createInflate({chunkSize:r});let n=t,s=this.emit.bind(this,"error");this._inflate.on("error",function(a){n&&s(a)}),this._filter.on("complete",this._complete.bind(this));let o=this._filter.write.bind(this._filter);this._inflate.on("data",function(a){n&&(a.length>n&&(a=a.slice(0,n)),n-=a.length,o(a))}),this._inflate.on("end",this._filter.end.bind(this._filter))}this._inflate.write(i)};zt.prototype._handleMetaData=function(i){this._metaData=i,this._bitmapInfo=Object.create(i),this._filter=new H1(this._bitmapInfo)};zt.prototype._handleTransColor=function(i){this._bitmapInfo.transColor=i};zt.prototype._handlePalette=function(i){this._bitmapInfo.palette=i};zt.prototype._simpleTransparency=function(){this._metaData.alpha=!0};zt.prototype._headersFinished=function(){this.emit("metadata",this._metaData)};zt.prototype._finished=function(){this.errord||(this._inflate?this._inflate.end():this.emit("error","No Inflate block"))};zt.prototype._complete=function(i){if(this.errord)return;let e;try{let t=W1.dataToBitMap(i,this._bitmapInfo);e=Y1(t,this._bitmapInfo,this._options.skipRescale),t=null}catch(t){this._handleError(t);return}this.emit("parsed",e)}});var hd=x((m2,fd)=>{"use strict";var Bt=Tr();fd.exports=function(i,e,t,r){let n=[Bt.COLORTYPE_COLOR_ALPHA,Bt.COLORTYPE_ALPHA].indexOf(r.colorType)!==-1;if(r.colorType===r.inputColorType){let g=(function(){let y=new ArrayBuffer(2);return new DataView(y).setInt16(0,256,!0),new Int16Array(y)[0]!==256})();if(r.bitDepth===8||r.bitDepth===16&&g)return i}let s=r.bitDepth!==16?i:new Uint16Array(i.buffer),o=255,a=Bt.COLORTYPE_TO_BPP_MAP[r.inputColorType];a===4&&!r.inputHasAlpha&&(a=3);let l=Bt.COLORTYPE_TO_BPP_MAP[r.colorType];r.bitDepth===16&&(o=65535,l*=2);let c=Buffer.alloc(e*t*l),u=0,f=0,d=r.bgColor||{};d.red===void 0&&(d.red=o),d.green===void 0&&(d.green=o),d.blue===void 0&&(d.blue=o);function m(){let g,y,b,w=o;switch(r.inputColorType){case Bt.COLORTYPE_COLOR_ALPHA:w=s[u+3],g=s[u],y=s[u+1],b=s[u+2];break;case Bt.COLORTYPE_COLOR:g=s[u],y=s[u+1],b=s[u+2];break;case Bt.COLORTYPE_ALPHA:w=s[u+1],g=s[u],y=g,b=g;break;case Bt.COLORTYPE_GRAYSCALE:g=s[u],y=g,b=g;break;default:throw new Error("input color type:"+r.inputColorType+" is not supported at present")}return r.inputHasAlpha&&(n||(w/=o,g=Math.min(Math.max(Math.round((1-w)*d.red+w*g),0),o),y=Math.min(Math.max(Math.round((1-w)*d.green+w*y),0),o),b=Math.min(Math.max(Math.round((1-w)*d.blue+w*b),0),o))),{red:g,green:y,blue:b,alpha:w}}for(let g=0;g{"use strict";var pd=al();function K1(i,e,t,r,n){for(let s=0;s=s?i[e+o-s]:0,l=i[e+o]-a;r[n+o]=l}}function Z1(i,e,t,r){let n=0;for(let s=0;s=r?i[e+s-r]:0,a=i[e+s]-o;n+=Math.abs(a)}return n}function Q1(i,e,t,r,n){for(let s=0;s0?i[e+s-t]:0,a=i[e+s]-o;r[n+s]=a}}function X1(i,e,t){let r=0,n=e+t;for(let s=e;s0?i[s-t]:0,a=i[s]-o;r+=Math.abs(a)}return r}function ex(i,e,t,r,n,s){for(let o=0;o=s?i[e+o-s]:0,l=e>0?i[e+o-t]:0,c=i[e+o]-(a+l>>1);r[n+o]=c}}function tx(i,e,t,r){let n=0;for(let s=0;s=r?i[e+s-r]:0,a=e>0?i[e+s-t]:0,l=i[e+s]-(o+a>>1);n+=Math.abs(l)}return n}function ix(i,e,t,r,n,s){for(let o=0;o=s?i[e+o-s]:0,l=e>0?i[e+o-t]:0,c=e>0&&o>=s?i[e+o-(t+s)]:0,u=i[e+o]-pd(a,l,c);r[n+o]=u}}function rx(i,e,t,r){let n=0;for(let s=0;s=r?i[e+s-r]:0,a=e>0?i[e+s-t]:0,l=e>0&&s>=r?i[e+s-(t+r)]:0,c=i[e+s]-pd(o,a,l);n+=Math.abs(c)}return n}var nx={0:K1,1:J1,2:Q1,3:ex,4:ix},sx={0:z1,1:Z1,2:X1,3:tx,4:rx};dd.exports=function(i,e,t,r,n){let s;if(!("filterType"in r)||r.filterType===-1)s=[0,1,2,3,4];else if(typeof r.filterType=="number")s=[r.filterType];else throw new Error("unrecognised filter types");r.bitDepth===16&&(n*=2);let o=e*n,a=0,l=0,c=Buffer.alloc((o+1)*t),u=s[0];for(let f=0;f1){let d=1/0;for(let m=0;m{"use strict";var rt=Tr(),ox=fl(),ax=hd(),lx=md(),cx=require("zlib"),xi=gd.exports=function(i){if(this._options=i,i.deflateChunkSize=i.deflateChunkSize||32*1024,i.deflateLevel=i.deflateLevel!=null?i.deflateLevel:9,i.deflateStrategy=i.deflateStrategy!=null?i.deflateStrategy:3,i.inputHasAlpha=i.inputHasAlpha!=null?i.inputHasAlpha:!0,i.deflateFactory=i.deflateFactory||cx.createDeflate,i.bitDepth=i.bitDepth||8,i.colorType=typeof i.colorType=="number"?i.colorType:rt.COLORTYPE_COLOR_ALPHA,i.inputColorType=typeof i.inputColorType=="number"?i.inputColorType:rt.COLORTYPE_COLOR_ALPHA,[rt.COLORTYPE_GRAYSCALE,rt.COLORTYPE_COLOR,rt.COLORTYPE_COLOR_ALPHA,rt.COLORTYPE_ALPHA].indexOf(i.colorType)===-1)throw new Error("option color type:"+i.colorType+" is not supported at present");if([rt.COLORTYPE_GRAYSCALE,rt.COLORTYPE_COLOR,rt.COLORTYPE_COLOR_ALPHA,rt.COLORTYPE_ALPHA].indexOf(i.inputColorType)===-1)throw new Error("option input color type:"+i.inputColorType+" is not supported at present");if(i.bitDepth!==8&&i.bitDepth!==16)throw new Error("option bit depth:"+i.bitDepth+" is not supported at present")};xi.prototype.getDeflateOptions=function(){return{chunkSize:this._options.deflateChunkSize,level:this._options.deflateLevel,strategy:this._options.deflateStrategy}};xi.prototype.createDeflate=function(){return this._options.deflateFactory(this.getDeflateOptions())};xi.prototype.filterData=function(i,e,t){let r=ax(i,e,t,this._options),n=rt.COLORTYPE_TO_BPP_MAP[this._options.colorType];return lx(r,e,t,this._options,n)};xi.prototype._packChunk=function(i,e){let t=e?e.length:0,r=Buffer.alloc(t+12);return r.writeUInt32BE(t,0),r.writeUInt32BE(i,4),e&&e.copy(r,8),r.writeInt32BE(ox.crc32(r.slice(4,r.length-4)),r.length-4),r};xi.prototype.packGAMA=function(i){let e=Buffer.alloc(4);return e.writeUInt32BE(Math.floor(i*rt.GAMMA_DIVISION),0),this._packChunk(rt.TYPE_gAMA,e)};xi.prototype.packIHDR=function(i,e){let t=Buffer.alloc(13);return t.writeUInt32BE(i,0),t.writeUInt32BE(e,4),t[8]=this._options.bitDepth,t[9]=this._options.colorType,t[10]=0,t[11]=0,t[12]=0,this._packChunk(rt.TYPE_IHDR,t)};xi.prototype.packIDAT=function(i){return this._packChunk(rt.TYPE_IDAT,i)};xi.prototype.packIEND=function(){return this._packChunk(rt.TYPE_IEND,null)}});var _d=x((y2,bd)=>{"use strict";var ux=require("util"),vd=require("stream"),fx=Tr(),hx=gl(),yd=bd.exports=function(i){vd.call(this);let e=i||{};this._packer=new hx(e),this._deflate=this._packer.createDeflate(),this.readable=!0};ux.inherits(yd,vd);yd.prototype.pack=function(i,e,t,r){this.emit("data",Buffer.from(fx.PNG_SIGNATURE)),this.emit("data",this._packer.packIHDR(e,t)),r&&this.emit("data",this._packer.packGAMA(r));let n=this._packer.filterData(i,e,t);this._deflate.on("error",this.emit.bind(this,"error")),this._deflate.on("data",function(s){this.emit("data",this._packer.packIDAT(s))}.bind(this)),this._deflate.on("end",function(){this.emit("data",this._packer.packIEND()),this.emit("end")}.bind(this)),this._deflate.end(n)}});var kd=x((cn,Od)=>{"use strict";var wd=require("assert").ok,Ar=require("zlib"),px=require("util"),xd=require("buffer").kMaxLength;function zi(i){if(!(this instanceof zi))return new zi(i);i&&i.chunkSize=0,"have should not go down"),b>0){let w=r._buffer.slice(r._offset,r._offset+b);if(r._offset+=b,w.length>o&&(w=w.slice(0,o)),l.push(w),c+=w.length,o-=w.length,o===0)return!1}return(y===0||r._offset>=r._chunkSize)&&(s=r._chunkSize,r._offset=0,r._buffer=Buffer.allocUnsafe(r._chunkSize)),y===0?(a+=n-g,n=g,!0):!1}wd(this._handle,"zlib binding closed");let d;do d=this._handle.writeSync(e,i,a,n,this._buffer,this._offset,s),d=d||this._writeState;while(!this._hadError&&f(d[0],d[1]));if(this._hadError)throw u;if(c>=xd)throw Sd(this),new RangeError("Cannot create final Buffer. It would be larger than 0x"+xd.toString(16)+" bytes");let m=Buffer.concat(l,c);return Sd(this),m};px.inherits(zi,Ar.Inflate);function mx(i,e){if(typeof e=="string"&&(e=Buffer.from(e)),!(e instanceof Buffer))throw new TypeError("Not a string or buffer");let t=i._finishFlushFlag;return t==null&&(t=Ar.Z_FINISH),i._processChunk(e,t)}function Ed(i,e){return mx(new zi(e),i)}Od.exports=cn=Ed;cn.Inflate=zi;cn.createInflate=dx;cn.inflateSync=Ed});var vl=x((b2,Td)=>{"use strict";var Cd=Td.exports=function(i){this._buffer=i,this._reads=[]};Cd.prototype.read=function(i,e){this._reads.push({length:Math.abs(i),allowLess:i<0,func:e})};Cd.prototype.process=function(){for(;this._reads.length>0&&this._buffer.length;){let i=this._reads[0];if(this._buffer.length&&(this._buffer.length>=i.length||i.allowLess)){this._reads.shift();let e=this._buffer;this._buffer=e.slice(i.length),i.func.call(this,e.slice(0,i.length))}else break}if(this._reads.length>0)throw new Error("There are some read requests waitng on finished stream");if(this._buffer.length>0)throw new Error("unrecognised content at end of stream")}});var Id=x(Ad=>{"use strict";var gx=vl(),vx=ll();Ad.process=function(i,e){let t=[],r=new gx(i);return new vx(e,{read:r.read.bind(r),write:function(s){t.push(s)},complete:function(){}}).start(),r.process(),Buffer.concat(t)}});var Rd=x((w2,Ld)=>{"use strict";var Nd=!0,Bd=require("zlib"),yx=kd();Bd.deflateSync||(Nd=!1);var bx=vl(),_x=Id(),wx=hl(),xx=pl(),Sx=dl();Ld.exports=function(i,e){if(!Nd)throw new Error("To use the sync capability of this library in old node versions, please pin pngjs to v2.3.0");let t;function r(O){t=O}let n;function s(O){n=O}function o(O){n.transColor=O}function a(O){n.palette=O}function l(){n.alpha=!0}let c;function u(O){c=O}let f=[];function d(O){f.push(O)}let m=new bx(i);if(new wx(e,{read:m.read.bind(m),error:r,metadata:s,gamma:u,palette:a,transColor:o,inflateData:d,simpleTransparency:l}).start(),m.process(),t)throw t;let y=Buffer.concat(f);f.length=0;let b;if(n.interlace)b=Bd.inflateSync(y);else{let E=((n.width*n.bpp*n.depth+7>>3)+1)*n.height;b=yx(y,{chunkSize:E,maxLength:E})}if(y=null,!b||!b.length)throw new Error("bad png - invalid inflate data response");let w=_x.process(b,n);y=null;let S=xx.dataToBitMap(w,n);w=null;let k=Sx(S,n,e.skipRescale);return n.data=k,n.gamma=c||0,n}});var Fd=x((x2,qd)=>{"use strict";var Pd=!0,Md=require("zlib");Md.deflateSync||(Pd=!1);var Ex=Tr(),Ox=gl();qd.exports=function(i,e){if(!Pd)throw new Error("To use the sync capability of this library in old node versions, please pin pngjs to v2.3.0");let t=e||{},r=new Ox(t),n=[];n.push(Buffer.from(Ex.PNG_SIGNATURE)),n.push(r.packIHDR(i.width,i.height)),i.gamma&&n.push(r.packGAMA(i.gamma));let s=r.filterData(i.data,i.width,i.height),o=Md.deflateSync(s,r.getDeflateOptions());if(s=null,!o||!o.length)throw new Error("bad png - invalid compressed data response");return n.push(r.packIDAT(o)),n.push(r.packIEND()),Buffer.concat(n)}});var Dd=x(yl=>{"use strict";var kx=Rd(),Cx=Fd();yl.read=function(i,e){return kx(i,e||{})};yl.write=function(i,e){return Cx(i,e)}});var $d=x(Ud=>{"use strict";var Tx=require("util"),jd=require("stream"),Ax=ud(),Ix=_d(),Nx=Dd(),lt=Ud.PNG=function(i){jd.call(this),i=i||{},this.width=i.width|0,this.height=i.height|0,this.data=this.width>0&&this.height>0?Buffer.alloc(4*this.width*this.height):null,i.fill&&this.data&&this.data.fill(0),this.gamma=0,this.readable=this.writable=!0,this._parser=new Ax(i),this._parser.on("error",this.emit.bind(this,"error")),this._parser.on("close",this._handleClose.bind(this)),this._parser.on("metadata",this._metadata.bind(this)),this._parser.on("gamma",this._gamma.bind(this)),this._parser.on("parsed",function(e){this.data=e,this.emit("parsed",e)}.bind(this)),this._packer=new Ix(i),this._packer.on("data",this.emit.bind(this,"data")),this._packer.on("end",this.emit.bind(this,"end")),this._parser.on("close",this._handleClose.bind(this)),this._packer.on("error",this.emit.bind(this,"error"))};Tx.inherits(lt,jd);lt.sync=Nx;lt.prototype.pack=function(){return!this.data||!this.data.length?(this.emit("error","No data provided"),this):(process.nextTick(function(){this._packer.pack(this.data,this.width,this.height,this.gamma)}.bind(this)),this)};lt.prototype.parse=function(i,e){if(e){let t,r;t=function(n){this.removeListener("error",r),this.data=n,e(null,this)}.bind(this),r=function(n){this.removeListener("parsed",t),e(n,null)}.bind(this),this.once("parsed",t),this.once("error",r)}return this.end(i),this};lt.prototype.write=function(i){return this._parser.write(i),!0};lt.prototype.end=function(i){this._parser.end(i)};lt.prototype._metadata=function(i){this.width=i.width,this.height=i.height,this.emit("metadata",i)};lt.prototype._gamma=function(i){this.gamma=i};lt.prototype._handleClose=function(){!this._parser.writable&&!this._packer.readable&&this.emit("close")};lt.bitblt=function(i,e,t,r,n,s,o,a){if(t|=0,r|=0,n|=0,s|=0,o|=0,a|=0,t>i.width||r>i.height||t+n>i.width||r+s>i.height)throw new Error("bitblt reading outside image");if(o>e.width||a>e.height||o+n>e.width||a+s>e.height)throw new Error("bitblt writing outside image");for(let l=0;l{var js=class extends Error{constructor(e,t,r){super(r),Error.captureStackTrace(this,this.constructor),this.name=this.constructor.name,this.code=t,this.exitCode=e,this.nestedError=void 0}},bl=class extends js{constructor(e){super(1,"commander.invalidArgument",e),Error.captureStackTrace(this,this.constructor),this.name=this.constructor.name}};_l.CommanderError=js;_l.InvalidArgumentError=bl});var Us=x(xl=>{var{InvalidArgumentError:Bx}=un(),wl=class{constructor(e,t){switch(this.description=t||"",this.variadic=!1,this.parseArg=void 0,this.defaultValue=void 0,this.defaultValueDescription=void 0,this.argChoices=void 0,e[0]){case"<":this.required=!0,this._name=e.slice(1,-1);break;case"[":this.required=!1,this._name=e.slice(1,-1);break;default:this.required=!0,this._name=e;break}this._name.length>3&&this._name.slice(-3)==="..."&&(this.variadic=!0,this._name=this._name.slice(0,-3))}name(){return this._name}_concatValue(e,t){return t===this.defaultValue||!Array.isArray(t)?[e]:t.concat(e)}default(e,t){return this.defaultValue=e,this.defaultValueDescription=t,this}argParser(e){return this.parseArg=e,this}choices(e){return this.argChoices=e.slice(),this.parseArg=(t,r)=>{if(!this.argChoices.includes(t))throw new Bx(`Allowed choices are ${this.argChoices.join(", ")}.`);return this.variadic?this._concatValue(t,r):t},this}argRequired(){return this.required=!0,this}argOptional(){return this.required=!1,this}};function Lx(i){let e=i.name()+(i.variadic===!0?"...":"");return i.required?"<"+e+">":"["+e+"]"}xl.Argument=wl;xl.humanReadableArgName=Lx});var Ol=x(El=>{var{humanReadableArgName:Rx}=Us(),Sl=class{constructor(){this.helpWidth=void 0,this.minWidthToWrap=40,this.sortSubcommands=!1,this.sortOptions=!1,this.showGlobalOptions=!1}prepareContext(e){var t,r;this.helpWidth=(r=(t=this.helpWidth)!=null?t:e.helpWidth)!=null?r:80}visibleCommands(e){let t=e.commands.filter(n=>!n._hidden),r=e._getHelpCommand();return r&&!r._hidden&&t.push(r),this.sortSubcommands&&t.sort((n,s)=>n.name().localeCompare(s.name())),t}compareOptions(e,t){let r=n=>n.short?n.short.replace(/^-/,""):n.long.replace(/^--/,"");return r(e).localeCompare(r(t))}visibleOptions(e){let t=e.options.filter(n=>!n.hidden),r=e._getHelpOption();if(r&&!r.hidden){let n=r.short&&e._findOption(r.short),s=r.long&&e._findOption(r.long);!n&&!s?t.push(r):r.long&&!s?t.push(e.createOption(r.long,r.description)):r.short&&!n&&t.push(e.createOption(r.short,r.description))}return this.sortOptions&&t.sort(this.compareOptions),t}visibleGlobalOptions(e){if(!this.showGlobalOptions)return[];let t=[];for(let r=e.parent;r;r=r.parent){let n=r.options.filter(s=>!s.hidden);t.push(...n)}return this.sortOptions&&t.sort(this.compareOptions),t}visibleArguments(e){return e._argsDescription&&e.registeredArguments.forEach(t=>{t.description=t.description||e._argsDescription[t.name()]||""}),e.registeredArguments.find(t=>t.description)?e.registeredArguments:[]}subcommandTerm(e){let t=e.registeredArguments.map(r=>Rx(r)).join(" ");return e._name+(e._aliases[0]?"|"+e._aliases[0]:"")+(e.options.length?" [options]":"")+(t?" "+t:"")}optionTerm(e){return e.flags}argumentTerm(e){return e.name()}longestSubcommandTermLength(e,t){return t.visibleCommands(e).reduce((r,n)=>Math.max(r,this.displayWidth(t.styleSubcommandTerm(t.subcommandTerm(n)))),0)}longestOptionTermLength(e,t){return t.visibleOptions(e).reduce((r,n)=>Math.max(r,this.displayWidth(t.styleOptionTerm(t.optionTerm(n)))),0)}longestGlobalOptionTermLength(e,t){return t.visibleGlobalOptions(e).reduce((r,n)=>Math.max(r,this.displayWidth(t.styleOptionTerm(t.optionTerm(n)))),0)}longestArgumentTermLength(e,t){return t.visibleArguments(e).reduce((r,n)=>Math.max(r,this.displayWidth(t.styleArgumentTerm(t.argumentTerm(n)))),0)}commandUsage(e){let t=e._name;e._aliases[0]&&(t=t+"|"+e._aliases[0]);let r="";for(let n=e.parent;n;n=n.parent)r=n.name()+" "+r;return r+t+" "+e.usage()}commandDescription(e){return e.description()}subcommandDescription(e){return e.summary()||e.description()}optionDescription(e){let t=[];return e.argChoices&&t.push(`choices: ${e.argChoices.map(r=>JSON.stringify(r)).join(", ")}`),e.defaultValue!==void 0&&(e.required||e.optional||e.isBoolean()&&typeof e.defaultValue=="boolean")&&t.push(`default: ${e.defaultValueDescription||JSON.stringify(e.defaultValue)}`),e.presetArg!==void 0&&e.optional&&t.push(`preset: ${JSON.stringify(e.presetArg)}`),e.envVar!==void 0&&t.push(`env: ${e.envVar}`),t.length>0?`${e.description} (${t.join(", ")})`:e.description}argumentDescription(e){let t=[];if(e.argChoices&&t.push(`choices: ${e.argChoices.map(r=>JSON.stringify(r)).join(", ")}`),e.defaultValue!==void 0&&t.push(`default: ${e.defaultValueDescription||JSON.stringify(e.defaultValue)}`),t.length>0){let r=`(${t.join(", ")})`;return e.description?`${e.description} ${r}`:r}return e.description}formatHelp(e,t){var f;let r=t.padWidth(e,t),n=(f=t.helpWidth)!=null?f:80;function s(d,m){return t.formatItem(d,r,m,t)}let o=[`${t.styleTitle("Usage:")} ${t.styleUsage(t.commandUsage(e))}`,""],a=t.commandDescription(e);a.length>0&&(o=o.concat([t.boxWrap(t.styleCommandDescription(a),n),""]));let l=t.visibleArguments(e).map(d=>s(t.styleArgumentTerm(t.argumentTerm(d)),t.styleArgumentDescription(t.argumentDescription(d))));l.length>0&&(o=o.concat([t.styleTitle("Arguments:"),...l,""]));let c=t.visibleOptions(e).map(d=>s(t.styleOptionTerm(t.optionTerm(d)),t.styleOptionDescription(t.optionDescription(d))));if(c.length>0&&(o=o.concat([t.styleTitle("Options:"),...c,""])),t.showGlobalOptions){let d=t.visibleGlobalOptions(e).map(m=>s(t.styleOptionTerm(t.optionTerm(m)),t.styleOptionDescription(t.optionDescription(m))));d.length>0&&(o=o.concat([t.styleTitle("Global Options:"),...d,""]))}let u=t.visibleCommands(e).map(d=>s(t.styleSubcommandTerm(t.subcommandTerm(d)),t.styleSubcommandDescription(t.subcommandDescription(d))));return u.length>0&&(o=o.concat([t.styleTitle("Commands:"),...u,""])),o.join(` +`)}displayWidth(e){return Vd(e).length}styleTitle(e){return e}styleUsage(e){return e.split(" ").map(t=>t==="[options]"?this.styleOptionText(t):t==="[command]"?this.styleSubcommandText(t):t[0]==="["||t[0]==="<"?this.styleArgumentText(t):this.styleCommandText(t)).join(" ")}styleCommandDescription(e){return this.styleDescriptionText(e)}styleOptionDescription(e){return this.styleDescriptionText(e)}styleSubcommandDescription(e){return this.styleDescriptionText(e)}styleArgumentDescription(e){return this.styleDescriptionText(e)}styleDescriptionText(e){return e}styleOptionTerm(e){return this.styleOptionText(e)}styleSubcommandTerm(e){return e.split(" ").map(t=>t==="[options]"?this.styleOptionText(t):t[0]==="["||t[0]==="<"?this.styleArgumentText(t):this.styleSubcommandText(t)).join(" ")}styleArgumentTerm(e){return this.styleArgumentText(e)}styleOptionText(e){return e}styleArgumentText(e){return e}styleSubcommandText(e){return e}styleCommandText(e){return e}padWidth(e,t){return Math.max(t.longestOptionTermLength(e,t),t.longestGlobalOptionTermLength(e,t),t.longestSubcommandTermLength(e,t),t.longestArgumentTermLength(e,t))}preformatted(e){return/\n[^\S\r\n]/.test(e)}formatItem(e,t,r,n){var d;let o=" ".repeat(2);if(!r)return o+e;let a=e.padEnd(t+e.length-n.displayWidth(e)),l=2,u=((d=this.helpWidth)!=null?d:80)-t-l-2,f;return u{let a=o.match(n);if(a===null){s.push("");return}let l=[a.shift()],c=this.displayWidth(l[0]);a.forEach(u=>{let f=this.displayWidth(u);if(c+f<=t){l.push(u),c+=f;return}s.push(l.join(""));let d=u.trimStart();l=[d],c=this.displayWidth(d)}),s.push(l.join(""))}),s.join(` +`)}};function Vd(i){let e=/\x1b\[\d*(;\d*)*m/g;return i.replace(e,"")}El.Help=Sl;El.stripColor=Vd});var Al=x(Tl=>{var{InvalidArgumentError:Px}=un(),kl=class{constructor(e,t){this.flags=e,this.description=t||"",this.required=e.includes("<"),this.optional=e.includes("["),this.variadic=/\w\.\.\.[>\]]$/.test(e),this.mandatory=!1;let r=Mx(e);this.short=r.shortFlag,this.long=r.longFlag,this.negate=!1,this.long&&(this.negate=this.long.startsWith("--no-")),this.defaultValue=void 0,this.defaultValueDescription=void 0,this.presetArg=void 0,this.envVar=void 0,this.parseArg=void 0,this.hidden=!1,this.argChoices=void 0,this.conflictsWith=[],this.implied=void 0}default(e,t){return this.defaultValue=e,this.defaultValueDescription=t,this}preset(e){return this.presetArg=e,this}conflicts(e){return this.conflictsWith=this.conflictsWith.concat(e),this}implies(e){let t=e;return typeof e=="string"&&(t={[e]:!0}),this.implied=Object.assign(this.implied||{},t),this}env(e){return this.envVar=e,this}argParser(e){return this.parseArg=e,this}makeOptionMandatory(e=!0){return this.mandatory=!!e,this}hideHelp(e=!0){return this.hidden=!!e,this}_concatValue(e,t){return t===this.defaultValue||!Array.isArray(t)?[e]:t.concat(e)}choices(e){return this.argChoices=e.slice(),this.parseArg=(t,r)=>{if(!this.argChoices.includes(t))throw new Px(`Allowed choices are ${this.argChoices.join(", ")}.`);return this.variadic?this._concatValue(t,r):t},this}name(){return this.long?this.long.replace(/^--/,""):this.short.replace(/^-/,"")}attributeName(){return this.negate?Hd(this.name().replace(/^no-/,"")):Hd(this.name())}is(e){return this.short===e||this.long===e}isBoolean(){return!this.required&&!this.optional&&!this.negate}},Cl=class{constructor(e){this.positiveOptions=new Map,this.negativeOptions=new Map,this.dualOptions=new Set,e.forEach(t=>{t.negate?this.negativeOptions.set(t.attributeName(),t):this.positiveOptions.set(t.attributeName(),t)}),this.negativeOptions.forEach((t,r)=>{this.positiveOptions.has(r)&&this.dualOptions.add(r)})}valueFromOption(e,t){let r=t.attributeName();if(!this.dualOptions.has(r))return!0;let n=this.negativeOptions.get(r).presetArg,s=n!==void 0?n:!1;return t.negate===(s===e)}};function Hd(i){return i.split("-").reduce((e,t)=>e+t[0].toUpperCase()+t.slice(1))}function Mx(i){let e,t,r=/^-[^-]$/,n=/^--[^-]/,s=i.split(/[ |,]+/).concat("guard");if(r.test(s[0])&&(e=s.shift()),n.test(s[0])&&(t=s.shift()),!e&&r.test(s[0])&&(e=s.shift()),!e&&n.test(s[0])&&(e=t,t=s.shift()),s[0].startsWith("-")){let o=s[0],a=`option creation failed due to '${o}' in option flags '${i}'`;throw/^-[^-][^-]/.test(o)?new Error(`${a} +- a short flag is a single dash and a single character + - either use a single dash and a single character (for a short flag) + - or use a double dash for a long option (and can have two, like '--ws, --workspace')`):r.test(o)?new Error(`${a} +- too many short flags`):n.test(o)?new Error(`${a} +- too many long flags`):new Error(`${a} +- unrecognised flag format`)}if(e===void 0&&t===void 0)throw new Error(`option creation failed due to no flags found in '${i}'.`);return{shortFlag:e,longFlag:t}}Tl.Option=kl;Tl.DualOptions=Cl});var Wd=x(Gd=>{function qx(i,e){if(Math.abs(i.length-e.length)>3)return Math.max(i.length,e.length);let t=[];for(let r=0;r<=i.length;r++)t[r]=[r];for(let r=0;r<=e.length;r++)t[0][r]=r;for(let r=1;r<=e.length;r++)for(let n=1;n<=i.length;n++){let s=1;i[n-1]===e[r-1]?s=0:s=1,t[n][r]=Math.min(t[n-1][r]+1,t[n][r-1]+1,t[n-1][r-1]+s),n>1&&r>1&&i[n-1]===e[r-2]&&i[n-2]===e[r-1]&&(t[n][r]=Math.min(t[n][r],t[n-2][r-2]+1))}return t[i.length][e.length]}function Fx(i,e){if(!e||e.length===0)return"";e=Array.from(new Set(e));let t=i.startsWith("--");t&&(i=i.slice(2),e=e.map(o=>o.slice(2)));let r=[],n=3,s=.4;return e.forEach(o=>{if(o.length<=1)return;let a=qx(i,o),l=Math.max(i.length,o.length);(l-a)/l>s&&(ao.localeCompare(a)),t&&(r=r.map(o=>`--${o}`)),r.length>1?` +(Did you mean one of ${r.join(", ")}?)`:r.length===1?` +(Did you mean ${r[0]}?)`:""}Gd.suggestSimilar=Fx});var Jd=x(Rl=>{var Dx=require("node:events").EventEmitter,Il=require("node:child_process"),ci=require("node:path"),$s=require("node:fs"),Oe=require("node:process"),{Argument:jx,humanReadableArgName:Ux}=Us(),{CommanderError:Nl}=un(),{Help:$x,stripColor:Vx}=Ol(),{Option:Yd,DualOptions:Hx}=Al(),{suggestSimilar:Kd}=Wd(),Bl=class i extends Dx{constructor(e){super(),this.commands=[],this.options=[],this.parent=null,this._allowUnknownOption=!1,this._allowExcessArguments=!1,this.registeredArguments=[],this._args=this.registeredArguments,this.args=[],this.rawArgs=[],this.processedArgs=[],this._scriptPath=null,this._name=e||"",this._optionValues={},this._optionValueSources={},this._storeOptionsAsProperties=!1,this._actionHandler=null,this._executableHandler=!1,this._executableFile=null,this._executableDir=null,this._defaultCommandName=null,this._exitCallback=null,this._aliases=[],this._combineFlagAndOptionalValue=!0,this._description="",this._summary="",this._argsDescription=void 0,this._enablePositionalOptions=!1,this._passThroughOptions=!1,this._lifeCycleHooks={},this._showHelpAfterError=!1,this._showSuggestionAfterError=!0,this._savedState=null,this._outputConfiguration={writeOut:t=>Oe.stdout.write(t),writeErr:t=>Oe.stderr.write(t),outputError:(t,r)=>r(t),getOutHelpWidth:()=>Oe.stdout.isTTY?Oe.stdout.columns:void 0,getErrHelpWidth:()=>Oe.stderr.isTTY?Oe.stderr.columns:void 0,getOutHasColors:()=>{var t,r,n;return(n=Ll())!=null?n:Oe.stdout.isTTY&&((r=(t=Oe.stdout).hasColors)==null?void 0:r.call(t))},getErrHasColors:()=>{var t,r,n;return(n=Ll())!=null?n:Oe.stderr.isTTY&&((r=(t=Oe.stderr).hasColors)==null?void 0:r.call(t))},stripColor:t=>Vx(t)},this._hidden=!1,this._helpOption=void 0,this._addImplicitHelpCommand=void 0,this._helpCommand=void 0,this._helpConfiguration={}}copyInheritedSettings(e){return this._outputConfiguration=e._outputConfiguration,this._helpOption=e._helpOption,this._helpCommand=e._helpCommand,this._helpConfiguration=e._helpConfiguration,this._exitCallback=e._exitCallback,this._storeOptionsAsProperties=e._storeOptionsAsProperties,this._combineFlagAndOptionalValue=e._combineFlagAndOptionalValue,this._allowExcessArguments=e._allowExcessArguments,this._enablePositionalOptions=e._enablePositionalOptions,this._showHelpAfterError=e._showHelpAfterError,this._showSuggestionAfterError=e._showSuggestionAfterError,this}_getCommandAndAncestors(){let e=[];for(let t=this;t;t=t.parent)e.push(t);return e}command(e,t,r){let n=t,s=r;typeof n=="object"&&n!==null&&(s=n,n=null),s=s||{};let[,o,a]=e.match(/([^ ]+) *(.*)/),l=this.createCommand(o);return n&&(l.description(n),l._executableHandler=!0),s.isDefault&&(this._defaultCommandName=l._name),l._hidden=!!(s.noHelp||s.hidden),l._executableFile=s.executableFile||null,a&&l.arguments(a),this._registerCommand(l),l.parent=this,l.copyInheritedSettings(this),n?this:l}createCommand(e){return new i(e)}createHelp(){return Object.assign(new $x,this.configureHelp())}configureHelp(e){return e===void 0?this._helpConfiguration:(this._helpConfiguration=e,this)}configureOutput(e){return e===void 0?this._outputConfiguration:(Object.assign(this._outputConfiguration,e),this)}showHelpAfterError(e=!0){return typeof e!="string"&&(e=!!e),this._showHelpAfterError=e,this}showSuggestionAfterError(e=!0){return this._showSuggestionAfterError=!!e,this}addCommand(e,t){if(!e._name)throw new Error(`Command passed to .addCommand() must have a name +- specify the name in Command constructor or using .name()`);return t=t||{},t.isDefault&&(this._defaultCommandName=e._name),(t.noHelp||t.hidden)&&(e._hidden=!0),this._registerCommand(e),e.parent=this,e._checkForBrokenPassThrough(),this}createArgument(e,t){return new jx(e,t)}argument(e,t,r,n){let s=this.createArgument(e,t);return typeof r=="function"?s.default(n).argParser(r):s.default(r),this.addArgument(s),this}arguments(e){return e.trim().split(/ +/).forEach(t=>{this.argument(t)}),this}addArgument(e){let t=this.registeredArguments.slice(-1)[0];if(t&&t.variadic)throw new Error(`only the last argument can be variadic '${t.name()}'`);if(e.required&&e.defaultValue!==void 0&&e.parseArg===void 0)throw new Error(`a default value for a required argument is never used: '${e.name()}'`);return this.registeredArguments.push(e),this}helpCommand(e,t){if(typeof e=="boolean")return this._addImplicitHelpCommand=e,this;e=e!=null?e:"help [command]";let[,r,n]=e.match(/([^ ]+) *(.*)/),s=t!=null?t:"display help for command",o=this.createCommand(r);return o.helpOption(!1),n&&o.arguments(n),s&&o.description(s),this._addImplicitHelpCommand=!0,this._helpCommand=o,this}addHelpCommand(e,t){return typeof e!="object"?(this.helpCommand(e,t),this):(this._addImplicitHelpCommand=!0,this._helpCommand=e,this)}_getHelpCommand(){var t;return((t=this._addImplicitHelpCommand)!=null?t:this.commands.length&&!this._actionHandler&&!this._findCommand("help"))?(this._helpCommand===void 0&&this.helpCommand(void 0,void 0),this._helpCommand):null}hook(e,t){let r=["preSubcommand","preAction","postAction"];if(!r.includes(e))throw new Error(`Unexpected value for event passed to hook : '${e}'. +Expecting one of '${r.join("', '")}'`);return this._lifeCycleHooks[e]?this._lifeCycleHooks[e].push(t):this._lifeCycleHooks[e]=[t],this}exitOverride(e){return e?this._exitCallback=e:this._exitCallback=t=>{if(t.code!=="commander.executeSubCommandAsync")throw t},this}_exit(e,t,r){this._exitCallback&&this._exitCallback(new Nl(e,t,r)),Oe.exit(e)}action(e){let t=r=>{let n=this.registeredArguments.length,s=r.slice(0,n);return this._storeOptionsAsProperties?s[n]=this:s[n]=this.opts(),s.push(this),e.apply(this,s)};return this._actionHandler=t,this}createOption(e,t){return new Yd(e,t)}_callParseArg(e,t,r,n){try{return e.parseArg(t,r)}catch(s){if(s.code==="commander.invalidArgument"){let o=`${n} ${s.message}`;this.error(o,{exitCode:s.exitCode,code:s.code})}throw s}}_registerOption(e){let t=e.short&&this._findOption(e.short)||e.long&&this._findOption(e.long);if(t){let r=e.long&&this._findOption(e.long)?e.long:e.short;throw new Error(`Cannot add option '${e.flags}'${this._name&&` to command '${this._name}'`} due to conflicting flag '${r}' +- already used by option '${t.flags}'`)}this.options.push(e)}_registerCommand(e){let t=n=>[n.name()].concat(n.aliases()),r=t(e).find(n=>this._findCommand(n));if(r){let n=t(this._findCommand(r)).join("|"),s=t(e).join("|");throw new Error(`cannot add command '${s}' as already have command '${n}'`)}this.commands.push(e)}addOption(e){this._registerOption(e);let t=e.name(),r=e.attributeName();if(e.negate){let s=e.long.replace(/^--no-/,"--");this._findOption(s)||this.setOptionValueWithSource(r,e.defaultValue===void 0?!0:e.defaultValue,"default")}else e.defaultValue!==void 0&&this.setOptionValueWithSource(r,e.defaultValue,"default");let n=(s,o,a)=>{s==null&&e.presetArg!==void 0&&(s=e.presetArg);let l=this.getOptionValue(r);s!==null&&e.parseArg?s=this._callParseArg(e,s,l,o):s!==null&&e.variadic&&(s=e._concatValue(s,l)),s==null&&(e.negate?s=!1:e.isBoolean()||e.optional?s=!0:s=""),this.setOptionValueWithSource(r,s,a)};return this.on("option:"+t,s=>{let o=`error: option '${e.flags}' argument '${s}' is invalid.`;n(s,o,"cli")}),e.envVar&&this.on("optionEnv:"+t,s=>{let o=`error: option '${e.flags}' value '${s}' from env '${e.envVar}' is invalid.`;n(s,o,"env")}),this}_optionEx(e,t,r,n,s){if(typeof t=="object"&&t instanceof Yd)throw new Error("To add an Option object use addOption() instead of option() or requiredOption()");let o=this.createOption(t,r);if(o.makeOptionMandatory(!!e.mandatory),typeof n=="function")o.default(s).argParser(n);else if(n instanceof RegExp){let a=n;n=(l,c)=>{let u=a.exec(l);return u?u[0]:c},o.default(s).argParser(n)}else o.default(n);return this.addOption(o)}option(e,t,r,n){return this._optionEx({},e,t,r,n)}requiredOption(e,t,r,n){return this._optionEx({mandatory:!0},e,t,r,n)}combineFlagAndOptionalValue(e=!0){return this._combineFlagAndOptionalValue=!!e,this}allowUnknownOption(e=!0){return this._allowUnknownOption=!!e,this}allowExcessArguments(e=!0){return this._allowExcessArguments=!!e,this}enablePositionalOptions(e=!0){return this._enablePositionalOptions=!!e,this}passThroughOptions(e=!0){return this._passThroughOptions=!!e,this._checkForBrokenPassThrough(),this}_checkForBrokenPassThrough(){if(this.parent&&this._passThroughOptions&&!this.parent._enablePositionalOptions)throw new Error(`passThroughOptions cannot be used for '${this._name}' without turning on enablePositionalOptions for parent command(s)`)}storeOptionsAsProperties(e=!0){if(this.options.length)throw new Error("call .storeOptionsAsProperties() before adding options");if(Object.keys(this._optionValues).length)throw new Error("call .storeOptionsAsProperties() before setting option values");return this._storeOptionsAsProperties=!!e,this}getOptionValue(e){return this._storeOptionsAsProperties?this[e]:this._optionValues[e]}setOptionValue(e,t){return this.setOptionValueWithSource(e,t,void 0)}setOptionValueWithSource(e,t,r){return this._storeOptionsAsProperties?this[e]=t:this._optionValues[e]=t,this._optionValueSources[e]=r,this}getOptionValueSource(e){return this._optionValueSources[e]}getOptionValueSourceWithGlobals(e){let t;return this._getCommandAndAncestors().forEach(r=>{r.getOptionValueSource(e)!==void 0&&(t=r.getOptionValueSource(e))}),t}_prepareUserArgs(e,t){var n,s;if(e!==void 0&&!Array.isArray(e))throw new Error("first parameter to parse must be array or undefined");if(t=t||{},e===void 0&&t.from===void 0){(n=Oe.versions)!=null&&n.electron&&(t.from="electron");let o=(s=Oe.execArgv)!=null?s:[];(o.includes("-e")||o.includes("--eval")||o.includes("-p")||o.includes("--print"))&&(t.from="eval")}e===void 0&&(e=Oe.argv),this.rawArgs=e.slice();let r;switch(t.from){case void 0:case"node":this._scriptPath=e[1],r=e.slice(2);break;case"electron":Oe.defaultApp?(this._scriptPath=e[1],r=e.slice(2)):r=e.slice(1);break;case"user":r=e.slice(0);break;case"eval":r=e.slice(1);break;default:throw new Error(`unexpected parse option { from: '${t.from}' }`)}return!this._name&&this._scriptPath&&this.nameFromFilename(this._scriptPath),this._name=this._name||"program",r}parse(e,t){this._prepareForParse();let r=this._prepareUserArgs(e,t);return this._parseCommand([],r),this}async parseAsync(e,t){this._prepareForParse();let r=this._prepareUserArgs(e,t);return await this._parseCommand([],r),this}_prepareForParse(){this._savedState===null?this.saveStateBeforeParse():this.restoreStateBeforeParse()}saveStateBeforeParse(){this._savedState={_name:this._name,_optionValues:{...this._optionValues},_optionValueSources:{...this._optionValueSources}}}restoreStateBeforeParse(){if(this._storeOptionsAsProperties)throw new Error(`Can not call parse again when storeOptionsAsProperties is true. +- either make a new Command for each call to parse, or stop storing options as properties`);this._name=this._savedState._name,this._scriptPath=null,this.rawArgs=[],this._optionValues={...this._savedState._optionValues},this._optionValueSources={...this._savedState._optionValueSources},this.args=[],this.processedArgs=[]}_checkForMissingExecutable(e,t,r){if($s.existsSync(e))return;let n=t?`searched for local subcommand relative to directory '${t}'`:"no directory for search for local subcommand, use .executableDir() to supply a custom directory",s=`'${e}' does not exist + - if '${r}' is not meant to be an executable command, remove description parameter from '.command()' and use '.description()' instead + - if the default executable name is not suitable, use the executableFile option to supply a custom name or path + - ${n}`;throw new Error(s)}_executeSubCommand(e,t){t=t.slice();let r=!1,n=[".js",".ts",".tsx",".mjs",".cjs"];function s(u,f){let d=ci.resolve(u,f);if($s.existsSync(d))return d;if(n.includes(ci.extname(f)))return;let m=n.find(g=>$s.existsSync(`${d}${g}`));if(m)return`${d}${m}`}this._checkForMissingMandatoryOptions(),this._checkForConflictingOptions();let o=e._executableFile||`${this._name}-${e._name}`,a=this._executableDir||"";if(this._scriptPath){let u;try{u=$s.realpathSync(this._scriptPath)}catch{u=this._scriptPath}a=ci.resolve(ci.dirname(u),a)}if(a){let u=s(a,o);if(!u&&!e._executableFile&&this._scriptPath){let f=ci.basename(this._scriptPath,ci.extname(this._scriptPath));f!==this._name&&(u=s(a,`${f}-${e._name}`))}o=u||o}r=n.includes(ci.extname(o));let l;Oe.platform!=="win32"?r?(t.unshift(o),t=zd(Oe.execArgv).concat(t),l=Il.spawn(Oe.argv[0],t,{stdio:"inherit"})):l=Il.spawn(o,t,{stdio:"inherit"}):(this._checkForMissingExecutable(o,a,e._name),t.unshift(o),t=zd(Oe.execArgv).concat(t),l=Il.spawn(Oe.execPath,t,{stdio:"inherit"})),l.killed||["SIGUSR1","SIGUSR2","SIGTERM","SIGINT","SIGHUP"].forEach(f=>{Oe.on(f,()=>{l.killed===!1&&l.exitCode===null&&l.kill(f)})});let c=this._exitCallback;l.on("close",u=>{u=u!=null?u:1,c?c(new Nl(u,"commander.executeSubCommandAsync","(close)")):Oe.exit(u)}),l.on("error",u=>{if(u.code==="ENOENT")this._checkForMissingExecutable(o,a,e._name);else if(u.code==="EACCES")throw new Error(`'${o}' not executable`);if(!c)Oe.exit(1);else{let f=new Nl(1,"commander.executeSubCommandAsync","(error)");f.nestedError=u,c(f)}}),this.runningCommand=l}_dispatchSubcommand(e,t,r){let n=this._findCommand(e);n||this.help({error:!0}),n._prepareForParse();let s;return s=this._chainOrCallSubCommandHook(s,n,"preSubcommand"),s=this._chainOrCall(s,()=>{if(n._executableHandler)this._executeSubCommand(n,t.concat(r));else return n._parseCommand(t,r)}),s}_dispatchHelpCommand(e){var r,n,s,o;e||this.help();let t=this._findCommand(e);return t&&!t._executableHandler&&t.help(),this._dispatchSubcommand(e,[],[(o=(s=(r=this._getHelpOption())==null?void 0:r.long)!=null?s:(n=this._getHelpOption())==null?void 0:n.short)!=null?o:"--help"])}_checkNumberOfArguments(){this.registeredArguments.forEach((e,t)=>{e.required&&this.args[t]==null&&this.missingArgument(e.name())}),!(this.registeredArguments.length>0&&this.registeredArguments[this.registeredArguments.length-1].variadic)&&this.args.length>this.registeredArguments.length&&this._excessArguments(this.args)}_processArguments(){let e=(r,n,s)=>{let o=n;if(n!==null&&r.parseArg){let a=`error: command-argument value '${n}' is invalid for argument '${r.name()}'.`;o=this._callParseArg(r,n,s,a)}return o};this._checkNumberOfArguments();let t=[];this.registeredArguments.forEach((r,n)=>{let s=r.defaultValue;r.variadic?ne(r,a,o),r.defaultValue))):s===void 0&&(s=[]):nt()):t()}_chainOrCallHooks(e,t){let r=e,n=[];return this._getCommandAndAncestors().reverse().filter(s=>s._lifeCycleHooks[t]!==void 0).forEach(s=>{s._lifeCycleHooks[t].forEach(o=>{n.push({hookedCommand:s,callback:o})})}),t==="postAction"&&n.reverse(),n.forEach(s=>{r=this._chainOrCall(r,()=>s.callback(s.hookedCommand,this))}),r}_chainOrCallSubCommandHook(e,t,r){let n=e;return this._lifeCycleHooks[r]!==void 0&&this._lifeCycleHooks[r].forEach(s=>{n=this._chainOrCall(n,()=>s(this,t))}),n}_parseCommand(e,t){let r=this.parseOptions(t);if(this._parseOptionsEnv(),this._parseOptionsImplied(),e=e.concat(r.operands),t=r.unknown,this.args=e.concat(t),e&&this._findCommand(e[0]))return this._dispatchSubcommand(e[0],e.slice(1),t);if(this._getHelpCommand()&&e[0]===this._getHelpCommand().name())return this._dispatchHelpCommand(e[1]);if(this._defaultCommandName)return this._outputHelpIfRequested(t),this._dispatchSubcommand(this._defaultCommandName,e,t);this.commands.length&&this.args.length===0&&!this._actionHandler&&!this._defaultCommandName&&this.help({error:!0}),this._outputHelpIfRequested(r.unknown),this._checkForMissingMandatoryOptions(),this._checkForConflictingOptions();let n=()=>{r.unknown.length>0&&this.unknownOption(r.unknown[0])},s=`command:${this.name()}`;if(this._actionHandler){n(),this._processArguments();let o;return o=this._chainOrCallHooks(o,"preAction"),o=this._chainOrCall(o,()=>this._actionHandler(this.processedArgs)),this.parent&&(o=this._chainOrCall(o,()=>{this.parent.emit(s,e,t)})),o=this._chainOrCallHooks(o,"postAction"),o}if(this.parent&&this.parent.listenerCount(s))n(),this._processArguments(),this.parent.emit(s,e,t);else if(e.length){if(this._findCommand("*"))return this._dispatchSubcommand("*",e,t);this.listenerCount("command:*")?this.emit("command:*",e,t):this.commands.length?this.unknownCommand():(n(),this._processArguments())}else this.commands.length?(n(),this.help({error:!0})):(n(),this._processArguments())}_findCommand(e){if(e)return this.commands.find(t=>t._name===e||t._aliases.includes(e))}_findOption(e){return this.options.find(t=>t.is(e))}_checkForMissingMandatoryOptions(){this._getCommandAndAncestors().forEach(e=>{e.options.forEach(t=>{t.mandatory&&e.getOptionValue(t.attributeName())===void 0&&e.missingMandatoryOptionValue(t)})})}_checkForConflictingLocalOptions(){let e=this.options.filter(r=>{let n=r.attributeName();return this.getOptionValue(n)===void 0?!1:this.getOptionValueSource(n)!=="default"});e.filter(r=>r.conflictsWith.length>0).forEach(r=>{let n=e.find(s=>r.conflictsWith.includes(s.attributeName()));n&&this._conflictingOption(r,n)})}_checkForConflictingOptions(){this._getCommandAndAncestors().forEach(e=>{e._checkForConflictingLocalOptions()})}parseOptions(e){let t=[],r=[],n=t,s=e.slice();function o(l){return l.length>1&&l[0]==="-"}let a=null;for(;s.length;){let l=s.shift();if(l==="--"){n===r&&n.push(l),n.push(...s);break}if(a&&!o(l)){this.emit(`option:${a.name()}`,l);continue}if(a=null,o(l)){let c=this._findOption(l);if(c){if(c.required){let u=s.shift();u===void 0&&this.optionMissingArgument(c),this.emit(`option:${c.name()}`,u)}else if(c.optional){let u=null;s.length>0&&!o(s[0])&&(u=s.shift()),this.emit(`option:${c.name()}`,u)}else this.emit(`option:${c.name()}`);a=c.variadic?c:null;continue}}if(l.length>2&&l[0]==="-"&&l[1]!=="-"){let c=this._findOption(`-${l[1]}`);if(c){c.required||c.optional&&this._combineFlagAndOptionalValue?this.emit(`option:${c.name()}`,l.slice(2)):(this.emit(`option:${c.name()}`),s.unshift(`-${l.slice(2)}`));continue}}if(/^--[^=]+=/.test(l)){let c=l.indexOf("="),u=this._findOption(l.slice(0,c));if(u&&(u.required||u.optional)){this.emit(`option:${u.name()}`,l.slice(c+1));continue}}if(o(l)&&(n=r),(this._enablePositionalOptions||this._passThroughOptions)&&t.length===0&&r.length===0){if(this._findCommand(l)){t.push(l),s.length>0&&r.push(...s);break}else if(this._getHelpCommand()&&l===this._getHelpCommand().name()){t.push(l),s.length>0&&t.push(...s);break}else if(this._defaultCommandName){r.push(l),s.length>0&&r.push(...s);break}}if(this._passThroughOptions){n.push(l),s.length>0&&n.push(...s);break}n.push(l)}return{operands:t,unknown:r}}opts(){if(this._storeOptionsAsProperties){let e={},t=this.options.length;for(let r=0;rObject.assign(e,t.opts()),{})}error(e,t){this._outputConfiguration.outputError(`${e} +`,this._outputConfiguration.writeErr),typeof this._showHelpAfterError=="string"?this._outputConfiguration.writeErr(`${this._showHelpAfterError} +`):this._showHelpAfterError&&(this._outputConfiguration.writeErr(` +`),this.outputHelp({error:!0}));let r=t||{},n=r.exitCode||1,s=r.code||"commander.error";this._exit(n,s,e)}_parseOptionsEnv(){this.options.forEach(e=>{if(e.envVar&&e.envVar in Oe.env){let t=e.attributeName();(this.getOptionValue(t)===void 0||["default","config","env"].includes(this.getOptionValueSource(t)))&&(e.required||e.optional?this.emit(`optionEnv:${e.name()}`,Oe.env[e.envVar]):this.emit(`optionEnv:${e.name()}`))}})}_parseOptionsImplied(){let e=new Hx(this.options),t=r=>this.getOptionValue(r)!==void 0&&!["default","implied"].includes(this.getOptionValueSource(r));this.options.filter(r=>r.implied!==void 0&&t(r.attributeName())&&e.valueFromOption(this.getOptionValue(r.attributeName()),r)).forEach(r=>{Object.keys(r.implied).filter(n=>!t(n)).forEach(n=>{this.setOptionValueWithSource(n,r.implied[n],"implied")})})}missingArgument(e){let t=`error: missing required argument '${e}'`;this.error(t,{code:"commander.missingArgument"})}optionMissingArgument(e){let t=`error: option '${e.flags}' argument missing`;this.error(t,{code:"commander.optionMissingArgument"})}missingMandatoryOptionValue(e){let t=`error: required option '${e.flags}' not specified`;this.error(t,{code:"commander.missingMandatoryOptionValue"})}_conflictingOption(e,t){let r=o=>{let a=o.attributeName(),l=this.getOptionValue(a),c=this.options.find(f=>f.negate&&a===f.attributeName()),u=this.options.find(f=>!f.negate&&a===f.attributeName());return c&&(c.presetArg===void 0&&l===!1||c.presetArg!==void 0&&l===c.presetArg)?c:u||o},n=o=>{let a=r(o),l=a.attributeName();return this.getOptionValueSource(l)==="env"?`environment variable '${a.envVar}'`:`option '${a.flags}'`},s=`error: ${n(e)} cannot be used with ${n(t)}`;this.error(s,{code:"commander.conflictingOption"})}unknownOption(e){if(this._allowUnknownOption)return;let t="";if(e.startsWith("--")&&this._showSuggestionAfterError){let n=[],s=this;do{let o=s.createHelp().visibleOptions(s).filter(a=>a.long).map(a=>a.long);n=n.concat(o),s=s.parent}while(s&&!s._enablePositionalOptions);t=Kd(e,n)}let r=`error: unknown option '${e}'${t}`;this.error(r,{code:"commander.unknownOption"})}_excessArguments(e){if(this._allowExcessArguments)return;let t=this.registeredArguments.length,r=t===1?"":"s",s=`error: too many arguments${this.parent?` for '${this.name()}'`:""}. Expected ${t} argument${r} but got ${e.length}.`;this.error(s,{code:"commander.excessArguments"})}unknownCommand(){let e=this.args[0],t="";if(this._showSuggestionAfterError){let n=[];this.createHelp().visibleCommands(this).forEach(s=>{n.push(s.name()),s.alias()&&n.push(s.alias())}),t=Kd(e,n)}let r=`error: unknown command '${e}'${t}`;this.error(r,{code:"commander.unknownCommand"})}version(e,t,r){if(e===void 0)return this._version;this._version=e,t=t||"-V, --version",r=r||"output the version number";let n=this.createOption(t,r);return this._versionOptionName=n.attributeName(),this._registerOption(n),this.on("option:"+n.name(),()=>{this._outputConfiguration.writeOut(`${e} +`),this._exit(0,"commander.version",e)}),this}description(e,t){return e===void 0&&t===void 0?this._description:(this._description=e,t&&(this._argsDescription=t),this)}summary(e){return e===void 0?this._summary:(this._summary=e,this)}alias(e){var n;if(e===void 0)return this._aliases[0];let t=this;if(this.commands.length!==0&&this.commands[this.commands.length-1]._executableHandler&&(t=this.commands[this.commands.length-1]),e===t._name)throw new Error("Command alias can't be the same as its name");let r=(n=this.parent)==null?void 0:n._findCommand(e);if(r){let s=[r.name()].concat(r.aliases()).join("|");throw new Error(`cannot add alias '${e}' to command '${this.name()}' as already have command '${s}'`)}return t._aliases.push(e),this}aliases(e){return e===void 0?this._aliases:(e.forEach(t=>this.alias(t)),this)}usage(e){if(e===void 0){if(this._usage)return this._usage;let t=this.registeredArguments.map(r=>Ux(r));return[].concat(this.options.length||this._helpOption!==null?"[options]":[],this.commands.length?"[command]":[],this.registeredArguments.length?t:[]).join(" ")}return this._usage=e,this}name(e){return e===void 0?this._name:(this._name=e,this)}nameFromFilename(e){return this._name=ci.basename(e,ci.extname(e)),this}executableDir(e){return e===void 0?this._executableDir:(this._executableDir=e,this)}helpInformation(e){let t=this.createHelp(),r=this._getOutputContext(e);t.prepareContext({error:r.error,helpWidth:r.helpWidth,outputHasColors:r.hasColors});let n=t.formatHelp(this,t);return r.hasColors?n:this._outputConfiguration.stripColor(n)}_getOutputContext(e){e=e||{};let t=!!e.error,r,n,s;return t?(r=a=>this._outputConfiguration.writeErr(a),n=this._outputConfiguration.getErrHasColors(),s=this._outputConfiguration.getErrHelpWidth()):(r=a=>this._outputConfiguration.writeOut(a),n=this._outputConfiguration.getOutHasColors(),s=this._outputConfiguration.getOutHelpWidth()),{error:t,write:a=>(n||(a=this._outputConfiguration.stripColor(a)),r(a)),hasColors:n,helpWidth:s}}outputHelp(e){var o;let t;typeof e=="function"&&(t=e,e=void 0);let r=this._getOutputContext(e),n={error:r.error,write:r.write,command:this};this._getCommandAndAncestors().reverse().forEach(a=>a.emit("beforeAllHelp",n)),this.emit("beforeHelp",n);let s=this.helpInformation({error:r.error});if(t&&(s=t(s),typeof s!="string"&&!Buffer.isBuffer(s)))throw new Error("outputHelp callback must return a string or a Buffer");r.write(s),(o=this._getHelpOption())!=null&&o.long&&this.emit(this._getHelpOption().long),this.emit("afterHelp",n),this._getCommandAndAncestors().forEach(a=>a.emit("afterAllHelp",n))}helpOption(e,t){var r;return typeof e=="boolean"?(e?this._helpOption=(r=this._helpOption)!=null?r:void 0:this._helpOption=null,this):(e=e!=null?e:"-h, --help",t=t!=null?t:"display help for command",this._helpOption=this.createOption(e,t),this)}_getHelpOption(){return this._helpOption===void 0&&this.helpOption(void 0,void 0),this._helpOption}addHelpOption(e){return this._helpOption=e,this}help(e){var r;this.outputHelp(e);let t=Number((r=Oe.exitCode)!=null?r:0);t===0&&e&&typeof e!="function"&&e.error&&(t=1),this._exit(t,"commander.help","(outputHelp)")}addHelpText(e,t){let r=["beforeAll","before","after","afterAll"];if(!r.includes(e))throw new Error(`Unexpected value for position to addHelpText. +Expecting one of '${r.join("', '")}'`);let n=`${e}Help`;return this.on(n,s=>{let o;typeof t=="function"?o=t({error:s.error,command:s.command}):o=t,o&&s.write(`${o} +`)}),this}_outputHelpIfRequested(e){let t=this._getHelpOption();t&&e.find(n=>t.is(n))&&(this.outputHelp(),this._exit(0,"commander.helpDisplayed","(outputHelp)"))}};function zd(i){return i.map(e=>{if(!e.startsWith("--inspect"))return e;let t,r="127.0.0.1",n="9229",s;return(s=e.match(/^(--inspect(-brk)?)$/))!==null?t=s[1]:(s=e.match(/^(--inspect(-brk|-port)?)=([^:]+)$/))!==null?(t=s[1],/^\d+$/.test(s[3])?n=s[3]:r=s[3]):(s=e.match(/^(--inspect(-brk|-port)?)=([^:]+):(\d+)$/))!==null&&(t=s[1],r=s[3],n=s[4]),t&&n!=="0"?`${t}=${r}:${parseInt(n)+1}`:e})}function Ll(){if(Oe.env.NO_COLOR||Oe.env.FORCE_COLOR==="0"||Oe.env.FORCE_COLOR==="false")return!1;if(Oe.env.FORCE_COLOR||Oe.env.CLICOLOR_FORCE!==void 0)return!0}Rl.Command=Bl;Rl.useColor=Ll});var em=x(Lt=>{var{Argument:Zd}=Us(),{Command:Pl}=Jd(),{CommanderError:Gx,InvalidArgumentError:Qd}=un(),{Help:Wx}=Ol(),{Option:Xd}=Al();Lt.program=new Pl;Lt.createCommand=i=>new Pl(i);Lt.createOption=(i,e)=>new Xd(i,e);Lt.createArgument=(i,e)=>new Zd(i,e);Lt.Command=Pl;Lt.Option=Xd;Lt.Argument=Zd;Lt.Help=Wx;Lt.CommanderError=Gx;Lt.InvalidArgumentError=Qd;Lt.InvalidOptionArgumentError=Qd});var om=x((nm,sm)=>{nm=sm.exports=Ir;function Ir(i,e){if(this.stream=e.stream||process.stderr,typeof e=="number"){var t=e;e={},e.total=t}else{if(e=e||{},typeof i!="string")throw new Error("format required");if(typeof e.total!="number")throw new Error("total required")}this.fmt=i,this.curr=e.curr||0,this.total=e.total,this.width=e.width||this.total,this.clear=e.clear,this.chars={complete:e.complete||"=",incomplete:e.incomplete||"-",head:e.head||e.complete||"="},this.renderThrottle=e.renderThrottle!==0?e.renderThrottle||16:0,this.lastRender=-1/0,this.callback=e.callback||function(){},this.tokens={},this.lastDraw=""}Ir.prototype.tick=function(i,e){if(i!==0&&(i=i||1),typeof i=="object"&&(e=i,i=1),e&&(this.tokens=e),this.curr==0&&(this.start=new Date),this.curr+=i,this.render(),this.curr>=this.total){this.render(void 0,!0),this.complete=!0,this.terminate(),this.callback(this);return}};Ir.prototype.render=function(i,e){if(e=e!==void 0?e:!1,i&&(this.tokens=i),!!this.stream.isTTY){var t=Date.now(),r=t-this.lastRender;if(!(!e&&r0&&(a=a.slice(0,-1)+this.chars.head),d=d.replace(":bar",a+o),this.tokens)for(var y in this.tokens)d=d.replace(":"+y,this.tokens[y]);this.lastDraw!==d&&(this.stream.cursorTo(0),this.stream.write(d),this.stream.clearLine(1),this.lastDraw=d)}}};Ir.prototype.update=function(i,e){var t=Math.floor(i*this.total),r=t-this.curr;this.tick(r,e)};Ir.prototype.interrupt=function(i){this.stream.clearLine(),this.stream.cursorTo(0),this.stream.write(i),this.stream.write(` +`),this.stream.write(this.lastDraw)};Ir.prototype.terminate=function(){this.clear?this.stream.clearLine&&(this.stream.clearLine(),this.stream.cursorTo(0)):this.stream.write(` +`)}});var lm=x(($2,am)=>{am.exports=om()});var hm=x(ui=>{"use strict";Object.defineProperty(ui,"__esModule",{value:!0});var cm=require("buffer"),Ji={INVALID_ENCODING:"Invalid encoding provided. Please specify a valid encoding the internal Node.js Buffer supports.",INVALID_SMARTBUFFER_SIZE:"Invalid size provided. Size must be a valid integer greater than zero.",INVALID_SMARTBUFFER_BUFFER:"Invalid Buffer provided in SmartBufferOptions.",INVALID_SMARTBUFFER_OBJECT:"Invalid SmartBufferOptions object supplied to SmartBuffer constructor or factory methods.",INVALID_OFFSET:"An invalid offset value was provided.",INVALID_OFFSET_NON_NUMBER:"An invalid offset value was provided. A numeric value is required.",INVALID_LENGTH:"An invalid length value was provided.",INVALID_LENGTH_NON_NUMBER:"An invalid length value was provived. A numeric value is required.",INVALID_TARGET_OFFSET:"Target offset is beyond the bounds of the internal SmartBuffer data.",INVALID_TARGET_LENGTH:"Specified length value moves cursor beyong the bounds of the internal SmartBuffer data.",INVALID_READ_BEYOND_BOUNDS:"Attempted to read beyond the bounds of the managed data.",INVALID_WRITE_BEYOND_BOUNDS:"Attempted to write beyond the bounds of the managed data."};ui.ERRORS=Ji;function Yx(i){if(!cm.Buffer.isEncoding(i))throw new Error(Ji.INVALID_ENCODING)}ui.checkEncoding=Yx;function um(i){return typeof i=="number"&&isFinite(i)&&Zx(i)}ui.isFiniteInteger=um;function fm(i,e){if(typeof i=="number"){if(!um(i)||i<0)throw new Error(e?Ji.INVALID_OFFSET:Ji.INVALID_LENGTH)}else throw new Error(e?Ji.INVALID_OFFSET_NON_NUMBER:Ji.INVALID_LENGTH_NON_NUMBER)}function Kx(i){fm(i,!1)}ui.checkLengthValue=Kx;function zx(i){fm(i,!0)}ui.checkOffsetValue=zx;function Jx(i,e){if(i<0||i>e.length)throw new Error(Ji.INVALID_TARGET_OFFSET)}ui.checkTargetOffset=Jx;function Zx(i){return typeof i=="number"&&isFinite(i)&&Math.floor(i)===i}function Qx(i){if(typeof BigInt=="undefined")throw new Error("Platform does not support JS BigInt type.");if(typeof cm.Buffer.prototype[i]=="undefined")throw new Error(`Platform does not support Buffer.prototype.${i}.`)}ui.bigIntAndBufferInt64Check=Qx});var dm=x(ql=>{"use strict";Object.defineProperty(ql,"__esModule",{value:!0});var pe=hm(),pm=4096,Xx="utf8",Ml=class i{constructor(e){if(this.length=0,this._encoding=Xx,this._writeOffset=0,this._readOffset=0,i.isSmartBufferOptions(e))if(e.encoding&&(pe.checkEncoding(e.encoding),this._encoding=e.encoding),e.size)if(pe.isFiniteInteger(e.size)&&e.size>0)this._buff=Buffer.allocUnsafe(e.size);else throw new Error(pe.ERRORS.INVALID_SMARTBUFFER_SIZE);else if(e.buff)if(Buffer.isBuffer(e.buff))this._buff=e.buff,this.length=e.buff.length;else throw new Error(pe.ERRORS.INVALID_SMARTBUFFER_BUFFER);else this._buff=Buffer.allocUnsafe(pm);else{if(typeof e!="undefined")throw new Error(pe.ERRORS.INVALID_SMARTBUFFER_OBJECT);this._buff=Buffer.allocUnsafe(pm)}}static fromSize(e,t){return new this({size:e,encoding:t})}static fromBuffer(e,t){return new this({buff:e,encoding:t})}static fromOptions(e){return new this(e)}static isSmartBufferOptions(e){let t=e;return t&&(t.encoding!==void 0||t.size!==void 0||t.buff!==void 0)}readInt8(e){return this._readNumberValue(Buffer.prototype.readInt8,1,e)}readInt16BE(e){return this._readNumberValue(Buffer.prototype.readInt16BE,2,e)}readInt16LE(e){return this._readNumberValue(Buffer.prototype.readInt16LE,2,e)}readInt32BE(e){return this._readNumberValue(Buffer.prototype.readInt32BE,4,e)}readInt32LE(e){return this._readNumberValue(Buffer.prototype.readInt32LE,4,e)}readBigInt64BE(e){return pe.bigIntAndBufferInt64Check("readBigInt64BE"),this._readNumberValue(Buffer.prototype.readBigInt64BE,8,e)}readBigInt64LE(e){return pe.bigIntAndBufferInt64Check("readBigInt64LE"),this._readNumberValue(Buffer.prototype.readBigInt64LE,8,e)}writeInt8(e,t){return this._writeNumberValue(Buffer.prototype.writeInt8,1,e,t),this}insertInt8(e,t){return this._insertNumberValue(Buffer.prototype.writeInt8,1,e,t)}writeInt16BE(e,t){return this._writeNumberValue(Buffer.prototype.writeInt16BE,2,e,t)}insertInt16BE(e,t){return this._insertNumberValue(Buffer.prototype.writeInt16BE,2,e,t)}writeInt16LE(e,t){return this._writeNumberValue(Buffer.prototype.writeInt16LE,2,e,t)}insertInt16LE(e,t){return this._insertNumberValue(Buffer.prototype.writeInt16LE,2,e,t)}writeInt32BE(e,t){return this._writeNumberValue(Buffer.prototype.writeInt32BE,4,e,t)}insertInt32BE(e,t){return this._insertNumberValue(Buffer.prototype.writeInt32BE,4,e,t)}writeInt32LE(e,t){return this._writeNumberValue(Buffer.prototype.writeInt32LE,4,e,t)}insertInt32LE(e,t){return this._insertNumberValue(Buffer.prototype.writeInt32LE,4,e,t)}writeBigInt64BE(e,t){return pe.bigIntAndBufferInt64Check("writeBigInt64BE"),this._writeNumberValue(Buffer.prototype.writeBigInt64BE,8,e,t)}insertBigInt64BE(e,t){return pe.bigIntAndBufferInt64Check("writeBigInt64BE"),this._insertNumberValue(Buffer.prototype.writeBigInt64BE,8,e,t)}writeBigInt64LE(e,t){return pe.bigIntAndBufferInt64Check("writeBigInt64LE"),this._writeNumberValue(Buffer.prototype.writeBigInt64LE,8,e,t)}insertBigInt64LE(e,t){return pe.bigIntAndBufferInt64Check("writeBigInt64LE"),this._insertNumberValue(Buffer.prototype.writeBigInt64LE,8,e,t)}readUInt8(e){return this._readNumberValue(Buffer.prototype.readUInt8,1,e)}readUInt16BE(e){return this._readNumberValue(Buffer.prototype.readUInt16BE,2,e)}readUInt16LE(e){return this._readNumberValue(Buffer.prototype.readUInt16LE,2,e)}readUInt32BE(e){return this._readNumberValue(Buffer.prototype.readUInt32BE,4,e)}readUInt32LE(e){return this._readNumberValue(Buffer.prototype.readUInt32LE,4,e)}readBigUInt64BE(e){return pe.bigIntAndBufferInt64Check("readBigUInt64BE"),this._readNumberValue(Buffer.prototype.readBigUInt64BE,8,e)}readBigUInt64LE(e){return pe.bigIntAndBufferInt64Check("readBigUInt64LE"),this._readNumberValue(Buffer.prototype.readBigUInt64LE,8,e)}writeUInt8(e,t){return this._writeNumberValue(Buffer.prototype.writeUInt8,1,e,t)}insertUInt8(e,t){return this._insertNumberValue(Buffer.prototype.writeUInt8,1,e,t)}writeUInt16BE(e,t){return this._writeNumberValue(Buffer.prototype.writeUInt16BE,2,e,t)}insertUInt16BE(e,t){return this._insertNumberValue(Buffer.prototype.writeUInt16BE,2,e,t)}writeUInt16LE(e,t){return this._writeNumberValue(Buffer.prototype.writeUInt16LE,2,e,t)}insertUInt16LE(e,t){return this._insertNumberValue(Buffer.prototype.writeUInt16LE,2,e,t)}writeUInt32BE(e,t){return this._writeNumberValue(Buffer.prototype.writeUInt32BE,4,e,t)}insertUInt32BE(e,t){return this._insertNumberValue(Buffer.prototype.writeUInt32BE,4,e,t)}writeUInt32LE(e,t){return this._writeNumberValue(Buffer.prototype.writeUInt32LE,4,e,t)}insertUInt32LE(e,t){return this._insertNumberValue(Buffer.prototype.writeUInt32LE,4,e,t)}writeBigUInt64BE(e,t){return pe.bigIntAndBufferInt64Check("writeBigUInt64BE"),this._writeNumberValue(Buffer.prototype.writeBigUInt64BE,8,e,t)}insertBigUInt64BE(e,t){return pe.bigIntAndBufferInt64Check("writeBigUInt64BE"),this._insertNumberValue(Buffer.prototype.writeBigUInt64BE,8,e,t)}writeBigUInt64LE(e,t){return pe.bigIntAndBufferInt64Check("writeBigUInt64LE"),this._writeNumberValue(Buffer.prototype.writeBigUInt64LE,8,e,t)}insertBigUInt64LE(e,t){return pe.bigIntAndBufferInt64Check("writeBigUInt64LE"),this._insertNumberValue(Buffer.prototype.writeBigUInt64LE,8,e,t)}readFloatBE(e){return this._readNumberValue(Buffer.prototype.readFloatBE,4,e)}readFloatLE(e){return this._readNumberValue(Buffer.prototype.readFloatLE,4,e)}writeFloatBE(e,t){return this._writeNumberValue(Buffer.prototype.writeFloatBE,4,e,t)}insertFloatBE(e,t){return this._insertNumberValue(Buffer.prototype.writeFloatBE,4,e,t)}writeFloatLE(e,t){return this._writeNumberValue(Buffer.prototype.writeFloatLE,4,e,t)}insertFloatLE(e,t){return this._insertNumberValue(Buffer.prototype.writeFloatLE,4,e,t)}readDoubleBE(e){return this._readNumberValue(Buffer.prototype.readDoubleBE,8,e)}readDoubleLE(e){return this._readNumberValue(Buffer.prototype.readDoubleLE,8,e)}writeDoubleBE(e,t){return this._writeNumberValue(Buffer.prototype.writeDoubleBE,8,e,t)}insertDoubleBE(e,t){return this._insertNumberValue(Buffer.prototype.writeDoubleBE,8,e,t)}writeDoubleLE(e,t){return this._writeNumberValue(Buffer.prototype.writeDoubleLE,8,e,t)}insertDoubleLE(e,t){return this._insertNumberValue(Buffer.prototype.writeDoubleLE,8,e,t)}readString(e,t){let r;typeof e=="number"?(pe.checkLengthValue(e),r=Math.min(e,this.length-this._readOffset)):(t=e,r=this.length-this._readOffset),typeof t!="undefined"&&pe.checkEncoding(t);let n=this._buff.slice(this._readOffset,this._readOffset+r).toString(t||this._encoding);return this._readOffset+=r,n}insertString(e,t,r){return pe.checkOffsetValue(t),this._handleString(e,!0,t,r)}writeString(e,t,r){return this._handleString(e,!1,t,r)}readStringNT(e){typeof e!="undefined"&&pe.checkEncoding(e);let t=this.length;for(let n=this._readOffset;nthis.length)throw new Error(pe.ERRORS.INVALID_READ_BEYOND_BOUNDS)}ensureInsertable(e,t){pe.checkOffsetValue(t),this._ensureCapacity(this.length+e),tthis.length?this.length=t+e:this.length+=e}_ensureWriteable(e,t){let r=typeof t=="number"?t:this._writeOffset;this._ensureCapacity(r+e),r+e>this.length&&(this.length=r+e)}_ensureCapacity(e){let t=this._buff.length;if(e>t){let r=this._buff,n=t*3/2+1;n{"use strict";Object.defineProperty(Be,"__esModule",{value:!0});Be.SOCKS5_NO_ACCEPTABLE_AUTH=Be.SOCKS5_CUSTOM_AUTH_END=Be.SOCKS5_CUSTOM_AUTH_START=Be.SOCKS_INCOMING_PACKET_SIZES=Be.SocksClientState=Be.Socks5Response=Be.Socks5HostType=Be.Socks5Auth=Be.Socks4Response=Be.SocksCommand=Be.ERRORS=Be.DEFAULT_TIMEOUT=void 0;var eS=3e4;Be.DEFAULT_TIMEOUT=eS;var tS={InvalidSocksCommand:"An invalid SOCKS command was provided. Valid options are connect, bind, and associate.",InvalidSocksCommandForOperation:"An invalid SOCKS command was provided. Only a subset of commands are supported for this operation.",InvalidSocksCommandChain:"An invalid SOCKS command was provided. Chaining currently only supports the connect command.",InvalidSocksClientOptionsDestination:"An invalid destination host was provided.",InvalidSocksClientOptionsExistingSocket:"An invalid existing socket was provided. This should be an instance of stream.Duplex.",InvalidSocksClientOptionsProxy:"Invalid SOCKS proxy details were provided.",InvalidSocksClientOptionsTimeout:"An invalid timeout value was provided. Please enter a value above 0 (in ms).",InvalidSocksClientOptionsProxiesLength:"At least two socks proxies must be provided for chaining.",InvalidSocksClientOptionsCustomAuthRange:"Custom auth must be a value between 0x80 and 0xFE.",InvalidSocksClientOptionsCustomAuthOptions:"When a custom_auth_method is provided, custom_auth_request_handler, custom_auth_response_size, and custom_auth_response_handler must also be provided and valid.",NegotiationError:"Negotiation error",SocketClosed:"Socket closed",ProxyConnectionTimedOut:"Proxy connection timed out",InternalError:"SocksClient internal error (this should not happen)",InvalidSocks4HandshakeResponse:"Received invalid Socks4 handshake response",Socks4ProxyRejectedConnection:"Socks4 Proxy rejected connection",InvalidSocks4IncomingConnectionResponse:"Socks4 invalid incoming connection response",Socks4ProxyRejectedIncomingBoundConnection:"Socks4 Proxy rejected incoming bound connection",InvalidSocks5InitialHandshakeResponse:"Received invalid Socks5 initial handshake response",InvalidSocks5IntiailHandshakeSocksVersion:"Received invalid Socks5 initial handshake (invalid socks version)",InvalidSocks5InitialHandshakeNoAcceptedAuthType:"Received invalid Socks5 initial handshake (no accepted authentication type)",InvalidSocks5InitialHandshakeUnknownAuthType:"Received invalid Socks5 initial handshake (unknown authentication type)",Socks5AuthenticationFailed:"Socks5 Authentication failed",InvalidSocks5FinalHandshake:"Received invalid Socks5 final handshake response",InvalidSocks5FinalHandshakeRejected:"Socks5 proxy rejected connection",InvalidSocks5IncomingConnectionResponse:"Received invalid Socks5 incoming connection response",Socks5ProxyRejectedIncomingBoundConnection:"Socks5 Proxy rejected incoming bound connection"};Be.ERRORS=tS;var iS={Socks5InitialHandshakeResponse:2,Socks5UserPassAuthenticationResponse:2,Socks5ResponseHeader:5,Socks5ResponseIPv4:10,Socks5ResponseIPv6:22,Socks5ResponseHostname:i=>i+7,Socks4Response:8};Be.SOCKS_INCOMING_PACKET_SIZES=iS;var mm;(function(i){i[i.connect=1]="connect",i[i.bind=2]="bind",i[i.associate=3]="associate"})(mm||(Be.SocksCommand=mm={}));var gm;(function(i){i[i.Granted=90]="Granted",i[i.Failed=91]="Failed",i[i.Rejected=92]="Rejected",i[i.RejectedIdent=93]="RejectedIdent"})(gm||(Be.Socks4Response=gm={}));var vm;(function(i){i[i.NoAuth=0]="NoAuth",i[i.GSSApi=1]="GSSApi",i[i.UserPass=2]="UserPass"})(vm||(Be.Socks5Auth=vm={}));var rS=128;Be.SOCKS5_CUSTOM_AUTH_START=rS;var nS=254;Be.SOCKS5_CUSTOM_AUTH_END=nS;var sS=255;Be.SOCKS5_NO_ACCEPTABLE_AUTH=sS;var ym;(function(i){i[i.Granted=0]="Granted",i[i.Failure=1]="Failure",i[i.NotAllowed=2]="NotAllowed",i[i.NetworkUnreachable=3]="NetworkUnreachable",i[i.HostUnreachable=4]="HostUnreachable",i[i.ConnectionRefused=5]="ConnectionRefused",i[i.TTLExpired=6]="TTLExpired",i[i.CommandNotSupported=7]="CommandNotSupported",i[i.AddressNotSupported=8]="AddressNotSupported"})(ym||(Be.Socks5Response=ym={}));var bm;(function(i){i[i.IPv4=1]="IPv4",i[i.Hostname=3]="Hostname",i[i.IPv6=4]="IPv6"})(bm||(Be.Socks5HostType=bm={}));var _m;(function(i){i[i.Created=0]="Created",i[i.Connecting=1]="Connecting",i[i.Connected=2]="Connected",i[i.SentInitialHandshake=3]="SentInitialHandshake",i[i.ReceivedInitialHandshakeResponse=4]="ReceivedInitialHandshakeResponse",i[i.SentAuthentication=5]="SentAuthentication",i[i.ReceivedAuthenticationResponse=6]="ReceivedAuthenticationResponse",i[i.SentFinalHandshake=7]="SentFinalHandshake",i[i.ReceivedFinalResponse=8]="ReceivedFinalResponse",i[i.BoundWaitingForConnection=9]="BoundWaitingForConnection",i[i.Established=10]="Established",i[i.Disconnected=11]="Disconnected",i[i.Error=99]="Error"})(_m||(Be.SocksClientState=_m={}))});var jl=x(Nr=>{"use strict";Object.defineProperty(Nr,"__esModule",{value:!0});Nr.shuffleArray=Nr.SocksClientError=void 0;var Dl=class extends Error{constructor(e,t){super(e),this.options=t}};Nr.SocksClientError=Dl;function oS(i){for(let e=i.length-1;e>0;e--){let t=Math.floor(Math.random()*(e+1));[i[e],i[t]]=[i[t],i[e]]}}Nr.shuffleArray=oS});var Ul=x(Br=>{"use strict";Object.defineProperty(Br,"__esModule",{value:!0});Br.isCorrect=Br.isInSubnet=void 0;function aS(i){return this.subnetMask{"use strict";Object.defineProperty(Jt,"__esModule",{value:!0});Jt.RE_SUBNET_STRING=Jt.RE_ADDRESS=Jt.GROUPS=Jt.BITS=void 0;Jt.BITS=32;Jt.GROUPS=4;Jt.RE_ADDRESS=/^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/g;Jt.RE_SUBNET_STRING=/\/\d{1,2}$/});var Hs=x(Vs=>{"use strict";Object.defineProperty(Vs,"__esModule",{value:!0});Vs.AddressError=void 0;var Vl=class extends Error{constructor(e,t){super(e),this.name="AddressError",t!==null&&(this.parseMessage=t)}};Vs.AddressError=Vl});var Hl=x((Gs,wm)=>{(function(){var i,e=0xdeadbeefcafe,t=(e&16777215)==15715070;function r(h,p,v){h!=null&&(typeof h=="number"?this.fromNumber(h,p,v):p==null&&typeof h!="string"?this.fromString(h,256):this.fromString(h,p))}function n(){return new r(null)}function s(h,p,v,_,L,M){for(;--M>=0;){var G=p*this[h++]+v[_]+L;L=Math.floor(G/67108864),v[_++]=G&67108863}return L}function o(h,p,v,_,L,M){for(var G=p&32767,K=p>>15;--M>=0;){var Pe=this[h]&32767,Ye=this[h++]>>15,Tt=K*Pe+Ye*G;Pe=G*Pe+((Tt&32767)<<15)+v[_]+(L&1073741823),L=(Pe>>>30)+(Tt>>>15)+K*Ye+(L>>>30),v[_++]=Pe&1073741823}return L}function a(h,p,v,_,L,M){for(var G=p&16383,K=p>>14;--M>=0;){var Pe=this[h]&16383,Ye=this[h++]>>14,Tt=K*Pe+Ye*G;Pe=G*Pe+((Tt&16383)<<14)+v[_]+L,L=(Pe>>28)+(Tt>>14)+K*Ye,v[_++]=Pe&268435455}return L}var l=typeof navigator!="undefined";l&&t&&navigator.appName=="Microsoft Internet Explorer"?(r.prototype.am=o,i=30):l&&t&&navigator.appName!="Netscape"?(r.prototype.am=s,i=26):(r.prototype.am=a,i=28),r.prototype.DB=i,r.prototype.DM=(1<=0;--p)h[p]=this[p];h.t=this.t,h.s=this.s}function w(h){this.t=1,this.s=h<0?-1:0,h>0?this[0]=h:h<-1?this[0]=h+this.DV:this.t=0}function S(h){var p=n();return p.fromInt(h),p}function k(h,p){var v;if(p==16)v=4;else if(p==8)v=3;else if(p==256)v=8;else if(p==2)v=1;else if(p==32)v=5;else if(p==4)v=2;else{this.fromRadix(h,p);return}this.t=0,this.s=0;for(var _=h.length,L=!1,M=0;--_>=0;){var G=v==8?h[_]&255:y(h,_);if(G<0){h.charAt(_)=="-"&&(L=!0);continue}L=!1,M==0?this[this.t++]=G:M+v>this.DB?(this[this.t-1]|=(G&(1<>this.DB-M):this[this.t-1]|=G<=this.DB&&(M-=this.DB)}v==8&&(h[0]&128)!=0&&(this.s=-1,M>0&&(this[this.t-1]|=(1<0&&this[this.t-1]==h;)--this.t}function E(h){if(this.s<0)return"-"+this.negate().toString(h);var p;if(h==16)p=4;else if(h==8)p=3;else if(h==2)p=1;else if(h==32)p=5;else if(h==4)p=2;else return this.toRadix(h);var v=(1<0)for(K>K)>0&&(L=!0,M=g(_));G>=0;)K>(K+=this.DB-p)):(_=this[G]>>(K-=p)&v,K<=0&&(K+=this.DB,--G)),_>0&&(L=!0),L&&(M+=g(_));return L?M:"0"}function R(){var h=n();return r.ZERO.subTo(this,h),h}function T(){return this.s<0?this.negate():this}function A(h){var p=this.s-h.s;if(p!=0)return p;var v=this.t;if(p=v-h.t,p!=0)return this.s<0?-p:p;for(;--v>=0;)if((p=this[v]-h[v])!=0)return p;return 0}function C(h){var p=1,v;return(v=h>>>16)!=0&&(h=v,p+=16),(v=h>>8)!=0&&(h=v,p+=8),(v=h>>4)!=0&&(h=v,p+=4),(v=h>>2)!=0&&(h=v,p+=2),(v=h>>1)!=0&&(h=v,p+=1),p}function B(){return this.t<=0?0:this.DB*(this.t-1)+C(this[this.t-1]^this.s&this.DM)}function P(h,p){var v;for(v=this.t-1;v>=0;--v)p[v+h]=this[v];for(v=h-1;v>=0;--v)p[v]=0;p.t=this.t+h,p.s=this.s}function U(h,p){for(var v=h;v=0;--K)p[K+M+1]=this[K]>>_|G,G=(this[K]&L)<=0;--K)p[K]=0;p[M]=G,p.t=this.t+M+1,p.s=this.s,p.clamp()}function H(h,p){p.s=this.s;var v=Math.floor(h/this.DB);if(v>=this.t){p.t=0;return}var _=h%this.DB,L=this.DB-_,M=(1<<_)-1;p[0]=this[v]>>_;for(var G=v+1;G>_;_>0&&(p[this.t-v-1]|=(this.s&M)<>=this.DB;if(h.t>=this.DB;_+=this.s}else{for(_+=this.s;v>=this.DB;_-=h.s}p.s=_<0?-1:0,_<-1?p[v++]=this.DV+_:_>0&&(p[v++]=_),p.t=v,p.clamp()}function V(h,p){var v=this.abs(),_=h.abs(),L=v.t;for(p.t=L+_.t;--L>=0;)p[L]=0;for(L=0;L<_.t;++L)p[L+v.t]=v.am(0,_[L],p,L,0,v.t);p.s=0,p.clamp(),this.s!=h.s&&r.ZERO.subTo(p,p)}function Y(h){for(var p=this.abs(),v=h.t=2*p.t;--v>=0;)h[v]=0;for(v=0;v=p.DV&&(h[v+p.t]-=p.DV,h[v+p.t+1]=1)}h.t>0&&(h[h.t-1]+=p.am(v,p[v],h,2*v,0,1)),h.s=0,h.clamp()}function Q(h,p,v){var _=h.abs();if(!(_.t<=0)){var L=this.abs();if(L.t<_.t){p!=null&&p.fromInt(0),v!=null&&this.copyTo(v);return}v==null&&(v=n());var M=n(),G=this.s,K=h.s,Pe=this.DB-C(_[_.t-1]);Pe>0?(_.lShiftTo(Pe,M),L.lShiftTo(Pe,v)):(_.copyTo(M),L.copyTo(v));var Ye=M.t,Tt=M[Ye-1];if(Tt!=0){var wt=Tt*(1<1?M[Ye-2]>>this.F2:0),oi=this.FV/wt,ps=(1<=0&&(v[v.t++]=1,v.subTo(bi,v)),r.ONE.dlShiftTo(Ye,bi),bi.subTo(M,M);M.t=0;){var Oa=v[--Ut]==Tt?this.DM:Math.floor(v[Ut]*oi+(v[Ut-1]+jt)*ps);if((v[Ut]+=M.am(0,Oa,v,ds,0,Ye))0&&v.rShiftTo(Pe,v),G<0&&r.ZERO.subTo(v,v)}}}function W(h){var p=n();return this.abs().divRemTo(h,null,p),this.s<0&&p.compareTo(r.ZERO)>0&&h.subTo(p,p),p}function de(h){this.m=h}function ae(h){return h.s<0||h.compareTo(this.m)>=0?h.mod(this.m):h}function ne(h){return h}function ue(h){h.divRemTo(this.m,null,h)}function N(h,p,v){h.multiplyTo(p,v),this.reduce(v)}function X(h,p){h.squareTo(p),this.reduce(p)}de.prototype.convert=ae,de.prototype.revert=ne,de.prototype.reduce=ue,de.prototype.mulTo=N,de.prototype.sqrTo=X;function ke(){if(this.t<1)return 0;var h=this[0];if((h&1)==0)return 0;var p=h&3;return p=p*(2-(h&15)*p)&15,p=p*(2-(h&255)*p)&255,p=p*(2-((h&65535)*p&65535))&65535,p=p*(2-h*p%this.DV)%this.DV,p>0?this.DV-p:-p}function be(h){this.m=h,this.mp=h.invDigit(),this.mpl=this.mp&32767,this.mph=this.mp>>15,this.um=(1<0&&this.m.subTo(p,p),p}function ve(h){var p=n();return h.copyTo(p),this.reduce(p),p}function fe(h){for(;h.t<=this.mt2;)h[h.t++]=0;for(var p=0;p>15)*this.mpl&this.um)<<15)&h.DM;for(v=p+this.m.t,h[v]+=this.m.am(0,_,h,p,0,this.m.t);h[v]>=h.DV;)h[v]-=h.DV,h[++v]++}h.clamp(),h.drShiftTo(this.m.t,h),h.compareTo(this.m)>=0&&h.subTo(this.m,h)}function z(h,p){h.squareTo(p),this.reduce(p)}function $(h,p,v){h.multiplyTo(p,v),this.reduce(v)}be.prototype.convert=ge,be.prototype.revert=ve,be.prototype.reduce=fe,be.prototype.mulTo=$,be.prototype.sqrTo=z;function Te(){return(this.t>0?this[0]&1:this.s)==0}function re(h,p){if(h>4294967295||h<1)return r.ONE;var v=n(),_=n(),L=p.convert(this),M=C(h)-1;for(L.copyTo(v);--M>=0;)if(p.sqrTo(v,_),(h&1<0)p.mulTo(_,L,v);else{var G=v;v=_,_=G}return p.revert(v)}function he(h,p){var v;return h<256||p.isEven()?v=new de(p):v=new be(p),this.exp(h,v)}r.prototype.copyTo=b,r.prototype.fromInt=w,r.prototype.fromString=k,r.prototype.clamp=O,r.prototype.dlShiftTo=P,r.prototype.drShiftTo=U,r.prototype.lShiftTo=F,r.prototype.rShiftTo=H,r.prototype.subTo=j,r.prototype.multiplyTo=V,r.prototype.squareTo=Y,r.prototype.divRemTo=Q,r.prototype.invDigit=ke,r.prototype.isEven=Te,r.prototype.exp=re,r.prototype.toString=E,r.prototype.negate=R,r.prototype.abs=T,r.prototype.compareTo=A,r.prototype.bitLength=B,r.prototype.mod=W,r.prototype.modPowInt=he,r.ZERO=S(0),r.ONE=S(1);function ht(){var h=n();return this.copyTo(h),h}function bt(){if(this.s<0){if(this.t==1)return this[0]-this.DV;if(this.t==0)return-1}else{if(this.t==1)return this[0];if(this.t==0)return 0}return(this[1]&(1<<32-this.DB)-1)<>24}function Z(){return this.t==0?this.s:this[0]<<16>>16}function te(h){return Math.floor(Math.LN2*this.DB/Math.log(h))}function ee(){return this.s<0?-1:this.t<=0||this.t==1&&this[0]<=0?0:1}function le(h){if(h==null&&(h=10),this.signum()==0||h<2||h>36)return"0";var p=this.chunkSize(h),v=Math.pow(h,p),_=S(v),L=n(),M=n(),G="";for(this.divRemTo(_,L,M);L.signum()>0;)G=(v+M.intValue()).toString(h).substr(1)+G,L.divRemTo(_,L,M);return M.intValue().toString(h)+G}function ce(h,p){this.fromInt(0),p==null&&(p=10);for(var v=this.chunkSize(p),_=Math.pow(p,v),L=!1,M=0,G=0,K=0;K=v&&(this.dMultiply(_),this.dAddOffset(G,0),M=0,G=0)}M>0&&(this.dMultiply(Math.pow(p,M)),this.dAddOffset(G,0)),L&&r.ZERO.subTo(this,this)}function _e(h,p,v){if(typeof p=="number")if(h<2)this.fromInt(1);else for(this.fromNumber(h,v),this.testBit(h-1)||this.bitwiseTo(r.ONE.shiftLeft(h-1),oe,this),this.isEven()&&this.dAddOffset(1,0);!this.isProbablePrime(p);)this.dAddOffset(2,0),this.bitLength()>h&&this.subTo(r.ONE.shiftLeft(h-1),this);else{var _=new Array,L=h&7;_.length=(h>>3)+1,p.nextBytes(_),L>0?_[0]&=(1<0)for(v>v)!=(this.s&this.DM)>>v&&(p[L++]=_|this.s<=0;)v<8?(_=(this[h]&(1<>(v+=this.DB-8)):(_=this[h]>>(v-=8)&255,v<=0&&(v+=this.DB,--h)),(_&128)!=0&&(_|=-256),L==0&&(this.s&128)!=(_&128)&&++L,(L>0||_!=this.s)&&(p[L++]=_);return p}function Re(h){return this.compareTo(h)==0}function Ae(h){return this.compareTo(h)<0?this:h}function D(h){return this.compareTo(h)>0?this:h}function J(h,p,v){var _,L,M=Math.min(h.t,this.t);for(_=0;_>=16,p+=16),(h&255)==0&&(h>>=8,p+=8),(h&15)==0&&(h>>=4,p+=4),(h&3)==0&&(h>>=2,p+=2),(h&1)==0&&++p,p}function vi(){for(var h=0;h=this.t?this.s!=0:(this[p]&1<>=this.DB;if(h.t>=this.DB;_+=this.s}else{for(_+=this.s;v>=this.DB;_+=h.s}p.s=_<0?-1:0,_>0?p[v++]=_:_<-1&&(p[v++]=this.DV+_),p.t=v,p.clamp()}function es(h){var p=n();return this.addTo(h,p),p}function tn(h){var p=n();return this.subTo(h,p),p}function ts(h){var p=n();return this.multiplyTo(h,p),p}function is(){var h=n();return this.squareTo(h),h}function rs(h){var p=n();return this.divRemTo(h,p,null),p}function ns(h){var p=n();return this.divRemTo(h,null,p),p}function ss(h){var p=n(),v=n();return this.divRemTo(h,p,v),new Array(p,v)}function wa(h){this[this.t]=this.am(0,h-1,this,0,0,this.t),++this.t,this.clamp()}function Hi(h,p){if(h!=0){for(;this.t<=p;)this[this.t++]=0;for(this[p]+=h;this[p]>=this.DV;)this[p]-=this.DV,++p>=this.t&&(this[this.t++]=0),++this[p]}}function si(){}function Gi(h){return h}function gr(h,p,v){h.multiplyTo(p,v)}function os(h,p){h.squareTo(p)}si.prototype.convert=Gi,si.prototype.revert=Gi,si.prototype.mulTo=gr,si.prototype.sqrTo=os;function as(h){return this.exp(h,new si)}function ls(h,p,v){var _=Math.min(this.t+h.t,p);for(v.s=0,v.t=_;_>0;)v[--_]=0;var L;for(L=v.t-this.t;_=0;)v[_]=0;for(_=Math.max(p-this.t,0);_2*this.m.t)return h.mod(this.m);if(h.compareTo(this.m)<0)return h;var p=n();return h.copyTo(p),this.reduce(p),p}function fs(h){return h}function vr(h){for(h.drShiftTo(this.m.t-1,this.r2),h.t>this.m.t+1&&(h.t=this.m.t+1,h.clamp()),this.mu.multiplyUpperTo(this.r2,this.m.t+1,this.q3),this.m.multiplyLowerTo(this.q3,this.m.t+1,this.r2);h.compareTo(this.r2)<0;)h.dAddOffset(1,this.m.t+1);for(h.subTo(this.r2,h);h.compareTo(this.m)>=0;)h.subTo(this.m,h)}function Sb(h,p){h.squareTo(p),this.reduce(p)}function Eb(h,p,v){h.multiplyTo(p,v),this.reduce(v)}Yt.prototype.convert=us,Yt.prototype.revert=fs,Yt.prototype.reduce=vr,Yt.prototype.mulTo=Eb,Yt.prototype.sqrTo=Sb;function Ob(h,p){var v=h.bitLength(),_,L=S(1),M;if(v<=0)return L;v<18?_=1:v<48?_=3:v<144?_=4:v<768?_=5:_=6,v<8?M=new de(p):p.isEven()?M=new Yt(p):M=new be(p);var G=new Array,K=3,Pe=_-1,Ye=(1<<_)-1;if(G[1]=M.convert(this),_>1){var Tt=n();for(M.sqrTo(G[1],Tt);K<=Ye;)G[K]=n(),M.mulTo(Tt,G[K-2],G[K]),K+=2}var wt=h.t-1,oi,ps=!0,jt=n(),Ut;for(v=C(h[wt])-1;wt>=0;){for(v>=Pe?oi=h[wt]>>v-Pe&Ye:(oi=(h[wt]&(1<0&&(oi|=h[wt-1]>>this.DB+v-Pe)),K=_;(oi&1)==0;)oi>>=1,--K;if((v-=K)<0&&(v+=this.DB,--wt),ps)G[oi].copyTo(L),ps=!1;else{for(;K>1;)M.sqrTo(L,jt),M.sqrTo(jt,L),K-=2;K>0?M.sqrTo(L,jt):(Ut=L,L=jt,jt=Ut),M.mulTo(jt,G[oi],L)}for(;wt>=0&&(h[wt]&1<0&&(p.rShiftTo(M,p),v.rShiftTo(M,v));p.signum()>0;)(L=p.getLowestSetBit())>0&&p.rShiftTo(L,p),(L=v.getLowestSetBit())>0&&v.rShiftTo(L,v),p.compareTo(v)>=0?(p.subTo(v,p),p.rShiftTo(1,p)):(v.subTo(p,v),v.rShiftTo(1,v));return M>0&&v.lShiftTo(M,v),v}function Cb(h){if(h<=0)return 0;var p=this.DV%h,v=this.s<0?h-1:0;if(this.t>0)if(p==0)v=this[0]%h;else for(var _=this.t-1;_>=0;--_)v=(p*v+this[_])%h;return v}function Tb(h){var p=h.isEven();if(this.isEven()&&p||h.signum()==0)return r.ZERO;for(var v=h.clone(),_=this.clone(),L=S(1),M=S(0),G=S(0),K=S(1);v.signum()!=0;){for(;v.isEven();)v.rShiftTo(1,v),p?((!L.isEven()||!M.isEven())&&(L.addTo(this,L),M.subTo(h,M)),L.rShiftTo(1,L)):M.isEven()||M.subTo(h,M),M.rShiftTo(1,M);for(;_.isEven();)_.rShiftTo(1,_),p?((!G.isEven()||!K.isEven())&&(G.addTo(this,G),K.subTo(h,K)),G.rShiftTo(1,G)):K.isEven()||K.subTo(h,K),K.rShiftTo(1,K);v.compareTo(_)>=0?(v.subTo(_,v),p&&L.subTo(G,L),M.subTo(K,M)):(_.subTo(v,_),p&&G.subTo(L,G),K.subTo(M,K))}if(_.compareTo(r.ONE)!=0)return r.ZERO;if(K.compareTo(h)>=0)return K.subtract(h);if(K.signum()<0)K.addTo(h,K);else return K;return K.signum()<0?K.add(h):K}var ot=[2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97,101,103,107,109,113,127,131,137,139,149,151,157,163,167,173,179,181,191,193,197,199,211,223,227,229,233,239,241,251,257,263,269,271,277,281,283,293,307,311,313,317,331,337,347,349,353,359,367,373,379,383,389,397,401,409,419,421,431,433,439,443,449,457,461,463,467,479,487,491,499,503,509,521,523,541,547,557,563,569,571,577,587,593,599,601,607,613,617,619,631,641,643,647,653,659,661,673,677,683,691,701,709,719,727,733,739,743,751,757,761,769,773,787,797,809,811,821,823,827,829,839,853,857,859,863,877,881,883,887,907,911,919,929,937,941,947,953,967,971,977,983,991,997],Ab=(1<<26)/ot[ot.length-1];function Ib(h){var p,v=this.abs();if(v.t==1&&v[0]<=ot[ot.length-1]){for(p=0;p>1,h>ot.length&&(h=ot.length);for(var L=n(),M=0;M>8&255,_t[We++]^=h>>16&255,_t[We++]^=h>>24&255,We>=Ea&&(We-=Ea)}function yf(){Bb(new Date().getTime())}if(_t==null){_t=new Array,We=0;var Dt;if(typeof window!="undefined"&&window.crypto){if(window.crypto.getRandomValues){var bf=new Uint8Array(32);for(window.crypto.getRandomValues(bf),Dt=0;Dt<32;++Dt)_t[We++]=bf[Dt]}else if(navigator.appName=="Netscape"&&navigator.appVersion<"5"){var _f=window.crypto.random(32);for(Dt=0;Dt<_f.length;++Dt)_t[We++]=_f.charCodeAt(Dt)&255}}for(;We>>8,_t[We++]=Dt&255;We=0,yf()}function Lb(){if(hs==null){for(yf(),hs=qb(),hs.init(_t),We=0;We<_t.length;++We)_t[We]=0;We=0}return hs.next()}function Rb(h){var p;for(p=0;p{(function(){"use strict";var i={not_string:/[^s]/,not_bool:/[^t]/,not_type:/[^T]/,not_primitive:/[^v]/,number:/[diefg]/,numeric_arg:/[bcdiefguxX]/,json:/[j]/,not_json:/[^j]/,text:/^[^\x25]+/,modulo:/^\x25{2}/,placeholder:/^\x25(?:([1-9]\d*)\$|\(([^)]+)\))?(\+)?(0|'[^$])?(-)?(\d+)?(?:\.(\d+))?([b-gijostTuvxX])/,key:/^([a-z_][a-z_\d]*)/i,key_access:/^\.([a-z_][a-z_\d]*)/i,index_access:/^\[(\d+)\]/,sign:/^[+-]/};function e(o){return r(s(o),arguments)}function t(o,a){return e.apply(null,[o].concat(a||[]))}function r(o,a){var l=1,c=o.length,u,f="",d,m,g,y,b,w,S,k;for(d=0;d=0),g.type){case"b":u=parseInt(u,10).toString(2);break;case"c":u=String.fromCharCode(parseInt(u,10));break;case"d":case"i":u=parseInt(u,10);break;case"j":u=JSON.stringify(u,null,g.width?parseInt(g.width):0);break;case"e":u=g.precision?parseFloat(u).toExponential(g.precision):parseFloat(u).toExponential();break;case"f":u=g.precision?parseFloat(u).toFixed(g.precision):parseFloat(u);break;case"g":u=g.precision?String(Number(u.toPrecision(g.precision))):parseFloat(u);break;case"o":u=(parseInt(u,10)>>>0).toString(8);break;case"s":u=String(u),u=g.precision?u.substring(0,g.precision):u;break;case"t":u=String(!!u),u=g.precision?u.substring(0,g.precision):u;break;case"T":u=Object.prototype.toString.call(u).slice(8,-1).toLowerCase(),u=g.precision?u.substring(0,g.precision):u;break;case"u":u=parseInt(u,10)>>>0;break;case"v":u=u.valueOf(),u=g.precision?u.substring(0,g.precision):u;break;case"x":u=(parseInt(u,10)>>>0).toString(16);break;case"X":u=(parseInt(u,10)>>>0).toString(16).toUpperCase();break}i.json.test(g.type)?f+=u:(i.number.test(g.type)&&(!S||g.sign)?(k=S?"+":"-",u=u.toString().replace(i.sign,"")):k="",b=g.pad_char?g.pad_char==="0"?"0":g.pad_char.charAt(1):" ",w=g.width-(k+u).length,y=g.width&&w>0?b.repeat(w):"",f+=g.align?k+u+y:b==="0"?k+y+u:y+k+u)}return f}var n=Object.create(null);function s(o){if(n[o])return n[o];for(var a=o,l,c=[],u=0;a;){if((l=i.text.exec(a))!==null)c.push(l[0]);else if((l=i.modulo.exec(a))!==null)c.push("%");else if((l=i.placeholder.exec(a))!==null){if(l[2]){u|=1;var f=[],d=l[2],m=[];if((m=i.key.exec(d))!==null)for(f.push(m[1]);(d=d.substring(m[0].length))!=="";)if((m=i.key_access.exec(d))!==null)f.push(m[1]);else if((m=i.index_access.exec(d))!==null)f.push(m[1]);else throw new SyntaxError("[sprintf] failed to parse named argument key");else throw new SyntaxError("[sprintf] failed to parse named argument key");l[2]=f}else u|=2;if(u===3)throw new Error("[sprintf] mixing positional and named placeholders is not (yet) supported");c.push({placeholder:l[0],param_no:l[1],keys:l[2],sign:l[3],pad_char:l[4],align:l[5],width:l[6],precision:l[7],type:l[8]})}else throw new SyntaxError("[sprintf] unexpected placeholder");a=a.substring(l[0].length)}return n[o]=c}typeof Ws!="undefined"&&(Ws.sprintf=e,Ws.vsprintf=t),typeof window!="undefined"&&(window.sprintf=e,window.vsprintf=t,typeof define=="function"&&define.amd&&define(function(){return{sprintf:e,vsprintf:t}}))})()});var Wl=x(Zt=>{"use strict";var cS=Zt&&Zt.__createBinding||(Object.create?(function(i,e,t,r){r===void 0&&(r=t);var n=Object.getOwnPropertyDescriptor(e,t);(!n||("get"in n?!e.__esModule:n.writable||n.configurable))&&(n={enumerable:!0,get:function(){return e[t]}}),Object.defineProperty(i,r,n)}):(function(i,e,t,r){r===void 0&&(r=t),i[r]=e[t]})),uS=Zt&&Zt.__setModuleDefault||(Object.create?(function(i,e){Object.defineProperty(i,"default",{enumerable:!0,value:e})}):function(i,e){i.default=e}),Em=Zt&&Zt.__importStar||function(i){if(i&&i.__esModule)return i;var e={};if(i!=null)for(var t in i)t!=="default"&&Object.prototype.hasOwnProperty.call(i,t)&&cS(e,i,t);return uS(e,i),e};Object.defineProperty(Zt,"__esModule",{value:!0});Zt.Address4=void 0;var xm=Em(Ul()),Ht=Em($l()),Sm=Hs(),hn=Hl(),Lr=fn(),Gl=class i{constructor(e){this.groups=Ht.GROUPS,this.parsedAddress=[],this.parsedSubnet="",this.subnet="/32",this.subnetMask=32,this.v4=!0,this.isCorrect=xm.isCorrect(Ht.BITS),this.isInSubnet=xm.isInSubnet,this.address=e;let t=Ht.RE_SUBNET_STRING.exec(e);if(t){if(this.parsedSubnet=t[0].replace("/",""),this.subnetMask=parseInt(this.parsedSubnet,10),this.subnet=`/${this.subnetMask}`,this.subnetMask<0||this.subnetMask>Ht.BITS)throw new Sm.AddressError("Invalid subnet mask.");e=e.replace(Ht.RE_SUBNET_STRING,"")}this.addressMinusSuffix=e,this.parsedAddress=this.parse(e)}static isValid(e){try{return new i(e),!0}catch{return!1}}parse(e){let t=e.split(".");if(!e.match(Ht.RE_ADDRESS))throw new Sm.AddressError("Invalid IPv4 address.");return t}correctForm(){return this.parsedAddress.map(e=>parseInt(e,10)).join(".")}static fromHex(e){let t=e.replace(/:/g,"").padStart(8,"0"),r=[],n;for(n=0;n<8;n+=2){let s=t.slice(n,n+2);r.push(parseInt(s,16))}return new i(r.join("."))}static fromInteger(e){return i.fromHex(e.toString(16))}static fromArpa(e){let r=e.replace(/(\.in-addr\.arpa)?\.$/,"").split(".").reverse().join(".");return new i(r)}toHex(){return this.parsedAddress.map(e=>(0,Lr.sprintf)("%02x",parseInt(e,10))).join(":")}toArray(){return this.parsedAddress.map(e=>parseInt(e,10))}toGroup6(){let e=[],t;for(t=0;t(0,Lr.sprintf)("%02x",parseInt(e,10))).join(""),16)}_startAddress(){return new hn.BigInteger(this.mask()+"0".repeat(Ht.BITS-this.subnetMask),2)}startAddress(){return i.fromBigInteger(this._startAddress())}startAddressExclusive(){let e=new hn.BigInteger("1");return i.fromBigInteger(this._startAddress().add(e))}_endAddress(){return new hn.BigInteger(this.mask()+"1".repeat(Ht.BITS-this.subnetMask),2)}endAddress(){return i.fromBigInteger(this._endAddress())}endAddressExclusive(){let e=new hn.BigInteger("1");return i.fromBigInteger(this._endAddress().subtract(e))}static fromBigInteger(e){return i.fromInteger(parseInt(e.toString(),10))}mask(e){return e===void 0&&(e=this.subnetMask),this.getBitsBase2(0,e)}getBitsBase2(e,t){return this.binaryZeroPad().slice(e,t)}reverseForm(e){e||(e={});let t=this.correctForm().split(".").reverse().join(".");return e.omitSuffix?t:(0,Lr.sprintf)("%s.in-addr.arpa.",t)}isMulticast(){return this.isInSubnet(new i("224.0.0.0/4"))}binaryZeroPad(){return this.bigInteger().toString(2).padStart(Ht.BITS,"0")}groupForV6(){let e=this.parsedAddress;return this.address.replace(Ht.RE_ADDRESS,(0,Lr.sprintf)('%s.%s',e.slice(0,2).join("."),e.slice(2,4).join(".")))}};Zt.Address4=Gl});var Yl=x(Fe=>{"use strict";Object.defineProperty(Fe,"__esModule",{value:!0});Fe.RE_URL_WITH_PORT=Fe.RE_URL=Fe.RE_ZONE_STRING=Fe.RE_SUBNET_STRING=Fe.RE_BAD_ADDRESS=Fe.RE_BAD_CHARACTERS=Fe.TYPES=Fe.SCOPES=Fe.GROUPS=Fe.BITS=void 0;Fe.BITS=128;Fe.GROUPS=8;Fe.SCOPES={0:"Reserved",1:"Interface local",2:"Link local",4:"Admin local",5:"Site local",8:"Organization local",14:"Global",15:"Reserved"};Fe.TYPES={"ff01::1/128":"Multicast (All nodes on this interface)","ff01::2/128":"Multicast (All routers on this interface)","ff02::1/128":"Multicast (All nodes on this link)","ff02::2/128":"Multicast (All routers on this link)","ff05::2/128":"Multicast (All routers in this site)","ff02::5/128":"Multicast (OSPFv3 AllSPF routers)","ff02::6/128":"Multicast (OSPFv3 AllDR routers)","ff02::9/128":"Multicast (RIP routers)","ff02::a/128":"Multicast (EIGRP routers)","ff02::d/128":"Multicast (PIM routers)","ff02::16/128":"Multicast (MLDv2 reports)","ff01::fb/128":"Multicast (mDNSv6)","ff02::fb/128":"Multicast (mDNSv6)","ff05::fb/128":"Multicast (mDNSv6)","ff02::1:2/128":"Multicast (All DHCP servers and relay agents on this link)","ff05::1:2/128":"Multicast (All DHCP servers and relay agents in this site)","ff02::1:3/128":"Multicast (All DHCP servers on this link)","ff05::1:3/128":"Multicast (All DHCP servers in this site)","::/128":"Unspecified","::1/128":"Loopback","ff00::/8":"Multicast","fe80::/10":"Link-local unicast"};Fe.RE_BAD_CHARACTERS=/([^0-9a-f:/%])/gi;Fe.RE_BAD_ADDRESS=/([0-9a-f]{5,}|:{3,}|[^:]:$|^:[^:]|\/$)/gi;Fe.RE_SUBNET_STRING=/\/\d{1,3}(?=%|$)/;Fe.RE_ZONE_STRING=/%.*$/;Fe.RE_URL=new RegExp(/^\[{0,1}([0-9a-f:]+)\]{0,1}/);Fe.RE_URL_WITH_PORT=new RegExp(/\[([0-9a-f:]+)\]:([0-9]{1,5})/)});var Kl=x(Qt=>{"use strict";Object.defineProperty(Qt,"__esModule",{value:!0});Qt.simpleGroup=Qt.spanLeadingZeroes=Qt.spanAll=Qt.spanAllZeroes=void 0;var Om=fn();function km(i){return i.replace(/(0+)/g,'$1')}Qt.spanAllZeroes=km;function fS(i,e=0){return i.split("").map((r,n)=>(0,Om.sprintf)('%s',r,n+e,km(r))).join("")}Qt.spanAll=fS;function Cm(i){return i.replace(/^(0+)/,'$1')}function hS(i){return i.split(":").map(t=>Cm(t)).join(":")}Qt.spanLeadingZeroes=hS;function pS(i,e=0){return i.split(":").map((r,n)=>/group-v4/.test(r)?r:(0,Om.sprintf)('%s',n+e,Cm(r)))}Qt.simpleGroup=pS});var Tm=x(Je=>{"use strict";var dS=Je&&Je.__createBinding||(Object.create?(function(i,e,t,r){r===void 0&&(r=t);var n=Object.getOwnPropertyDescriptor(e,t);(!n||("get"in n?!e.__esModule:n.writable||n.configurable))&&(n={enumerable:!0,get:function(){return e[t]}}),Object.defineProperty(i,r,n)}):(function(i,e,t,r){r===void 0&&(r=t),i[r]=e[t]})),mS=Je&&Je.__setModuleDefault||(Object.create?(function(i,e){Object.defineProperty(i,"default",{enumerable:!0,value:e})}):function(i,e){i.default=e}),gS=Je&&Je.__importStar||function(i){if(i&&i.__esModule)return i;var e={};if(i!=null)for(var t in i)t!=="default"&&Object.prototype.hasOwnProperty.call(i,t)&&dS(e,i,t);return mS(e,i),e};Object.defineProperty(Je,"__esModule",{value:!0});Je.possibleElisions=Je.simpleRegularExpression=Je.ADDRESS_BOUNDARY=Je.padGroup=Je.groupPossibilities=void 0;var vS=gS(Yl()),Rr=fn();function Ks(i){return(0,Rr.sprintf)("(%s)",i.join("|"))}Je.groupPossibilities=Ks;function Ys(i){return i.length<4?(0,Rr.sprintf)("0{0,%d}%s",4-i.length,i):i}Je.padGroup=Ys;Je.ADDRESS_BOUNDARY="[^A-Fa-f0-9:]";function yS(i){let e=[];i.forEach((r,n)=>{parseInt(r,16)===0&&e.push(n)});let t=e.map(r=>i.map((n,s)=>{if(s===r){let o=s===0||s===vS.GROUPS-1?":":"";return Ks([Ys(n),o])}return Ys(n)}).join(":"));return t.push(i.map(Ys).join(":")),Ks(t)}Je.simpleRegularExpression=yS;function bS(i,e,t){let r=e?"":":",n=t?"":":",s=[];!e&&!t&&s.push("::"),e&&t&&s.push(""),(t&&!e||!t&&e)&&s.push(":"),s.push((0,Rr.sprintf)("%s(:0{1,4}){1,%d}",r,i-1)),s.push((0,Rr.sprintf)("(0{1,4}:){1,%d}%s",i-1,n)),s.push((0,Rr.sprintf)("(0{1,4}:){%d}0{1,4}",i-1));for(let o=1;o{"use strict";var _S=Xt&&Xt.__createBinding||(Object.create?(function(i,e,t,r){r===void 0&&(r=t);var n=Object.getOwnPropertyDescriptor(e,t);(!n||("get"in n?!e.__esModule:n.writable||n.configurable))&&(n={enumerable:!0,get:function(){return e[t]}}),Object.defineProperty(i,r,n)}):(function(i,e,t,r){r===void 0&&(r=t),i[r]=e[t]})),wS=Xt&&Xt.__setModuleDefault||(Object.create?(function(i,e){Object.defineProperty(i,"default",{enumerable:!0,value:e})}):function(i,e){i.default=e}),Js=Xt&&Xt.__importStar||function(i){if(i&&i.__esModule)return i;var e={};if(i!=null)for(var t in i)t!=="default"&&Object.prototype.hasOwnProperty.call(i,t)&&_S(e,i,t);return wS(e,i),e};Object.defineProperty(Xt,"__esModule",{value:!0});Xt.Address6=void 0;var Am=Js(Ul()),zl=Js($l()),Le=Js(Yl()),Jl=Js(Kl()),Zi=Wl(),Qi=Tm(),fi=Hs(),ct=Hl(),ut=fn();function zs(i){if(!i)throw new Error("Assertion failed.")}function xS(i){let e=/(\d+)(\d{3})/;for(;e.test(i);)i=i.replace(e,"$1,$2");return i}function SS(i){return i=i.replace(/^(0{1,})([1-9]+)$/,'$1$2'),i=i.replace(/^(0{1,})(0)$/,'$1$2'),i}function ES(i,e){let t=[],r=[],n;for(n=0;ne[1]&&r.push(i[n]);return t.concat(["compact"]).concat(r)}function Im(i){return(0,ut.sprintf)("%04x",parseInt(i,16))}function Nm(i){return i&255}var Zl=class i{constructor(e,t){this.addressMinusSuffix="",this.parsedSubnet="",this.subnet="/128",this.subnetMask=128,this.v4=!1,this.zone="",this.isInSubnet=Am.isInSubnet,this.isCorrect=Am.isCorrect(Le.BITS),t===void 0?this.groups=Le.GROUPS:this.groups=t,this.address=e;let r=Le.RE_SUBNET_STRING.exec(e);if(r){if(this.parsedSubnet=r[0].replace("/",""),this.subnetMask=parseInt(this.parsedSubnet,10),this.subnet=`/${this.subnetMask}`,Number.isNaN(this.subnetMask)||this.subnetMask<0||this.subnetMask>Le.BITS)throw new fi.AddressError("Invalid subnet mask.");e=e.replace(Le.RE_SUBNET_STRING,"")}else if(/\//.test(e))throw new fi.AddressError("Invalid subnet mask.");let n=Le.RE_ZONE_STRING.exec(e);n&&(this.zone=n[0],e=e.replace(Le.RE_ZONE_STRING,"")),this.addressMinusSuffix=e,this.parsedAddress=this.parse(this.addressMinusSuffix)}static isValid(e){try{return new i(e),!0}catch{return!1}}static fromBigInteger(e){let t=e.toString(16).padStart(32,"0"),r=[],n;for(n=0;n65536)&&(r=null)):r=null,{address:new i(t),port:r}}static fromAddress4(e){let t=new Zi.Address4(e),r=Le.BITS-(zl.BITS-t.subnetMask);return new i(`::ffff:${t.correctForm()}/${r}`)}static fromArpa(e){let t=e.replace(/(\.ip6\.arpa)?\.$/,""),r=7;if(t.length!==63)throw new fi.AddressError("Invalid 'ip6.arpa' form.");let n=t.split(".").reverse();for(let s=r;s>0;s--){let o=s*4;n.splice(o,0,":")}return t=n.join(""),new i(t)}microsoftTranscription(){return(0,ut.sprintf)("%s.ipv6-literal.net",this.correctForm().replace(/:/g,"-"))}mask(e=this.subnetMask){return this.getBitsBase2(0,e)}possibleSubnets(e=128){let t=Le.BITS-this.subnetMask,r=Math.abs(e-Le.BITS),n=t-r;return n<0?"0":xS(new ct.BigInteger("2",10).pow(n).toString(10))}_startAddress(){return new ct.BigInteger(this.mask()+"0".repeat(Le.BITS-this.subnetMask),2)}startAddress(){return i.fromBigInteger(this._startAddress())}startAddressExclusive(){let e=new ct.BigInteger("1");return i.fromBigInteger(this._startAddress().add(e))}_endAddress(){return new ct.BigInteger(this.mask()+"1".repeat(Le.BITS-this.subnetMask),2)}endAddress(){return i.fromBigInteger(this._endAddress())}endAddressExclusive(){let e=new ct.BigInteger("1");return i.fromBigInteger(this._endAddress().subtract(e))}getScope(){let e=Le.SCOPES[this.getBits(12,16).intValue()];return this.getType()==="Global unicast"&&e!=="Link local"&&(e="Global"),e||"Unknown"}getType(){for(let e of Object.keys(Le.TYPES))if(this.isInSubnet(new i(e)))return Le.TYPES[e];return"Global unicast"}getBits(e,t){return new ct.BigInteger(this.getBitsBase2(e,t),2)}getBitsBase2(e,t){return this.binaryZeroPad().slice(e,t)}getBitsBase16(e,t){let r=t-e;if(r%4!==0)throw new Error("Length of bits to retrieve must be divisible by four");return this.getBits(e,t).toString(16).padStart(r/4,"0")}getBitsPastSubnet(){return this.getBitsBase2(this.subnetMask,Le.BITS)}reverseForm(e){e||(e={});let t=Math.floor(this.subnetMask/4),r=this.canonicalForm().replace(/:/g,"").split("").slice(0,t).reverse().join(".");return t>0?e.omitSuffix?r:(0,ut.sprintf)("%s.ip6.arpa.",r):e.omitSuffix?"":"ip6.arpa."}correctForm(){let e,t=[],r=0,n=[];for(e=0;e0&&(r>1&&n.push([e-r,e-1]),r=0)}r>1&&n.push([this.parsedAddress.length-r,this.parsedAddress.length-1]);let s=n.map(a=>a[1]-a[0]+1);if(n.length>0){let a=s.indexOf(Math.max(...s));t=ES(this.parsedAddress,n[a])}else t=this.parsedAddress;for(e=0;e1?"s":"",t.join("")),e.replace(Le.RE_BAD_CHARACTERS,'$1'));let r=e.match(Le.RE_BAD_ADDRESS);if(r)throw new fi.AddressError((0,ut.sprintf)("Address failed regex: %s",r.join("")),e.replace(Le.RE_BAD_ADDRESS,'$1'));let n=[],s=e.split("::");if(s.length===2){let o=s[0].split(":"),a=s[1].split(":");o.length===1&&o[0]===""&&(o=[]),a.length===1&&a[0]===""&&(a=[]);let l=this.groups-(o.length+a.length);if(!l)throw new fi.AddressError("Error parsing groups");this.elidedGroups=l,this.elisionBegin=o.length,this.elisionEnd=o.length+this.elidedGroups,n=n.concat(o);for(let c=0;c(0,ut.sprintf)("%x",parseInt(o,16))),n.length!==this.groups)throw new fi.AddressError("Incorrect number of groups found");return n}canonicalForm(){return this.parsedAddress.map(Im).join(":")}decimal(){return this.parsedAddress.map(e=>(0,ut.sprintf)("%05d",parseInt(e,16))).join(":")}bigInteger(){return new ct.BigInteger(this.parsedAddress.map(Im).join(""),16)}to4(){let e=this.binaryZeroPad().split("");return Zi.Address4.fromHex(new ct.BigInteger(e.slice(96,128).join(""),2).toString(16))}to4in6(){let e=this.to4(),r=new i(this.parsedAddress.slice(0,6).join(":"),6).correctForm(),n="";return/:$/.test(r)||(n=":"),r+n+e.address}inspectTeredo(){let e=this.getBitsBase16(0,32),t=this.getBits(80,96).xor(new ct.BigInteger("ffff",16)).toString(),r=Zi.Address4.fromHex(this.getBitsBase16(32,64)),n=Zi.Address4.fromHex(this.getBits(96,128).xor(new ct.BigInteger("ffffffff",16)).toString(16)),s=this.getBits(64,80),o=this.getBitsBase2(64,80),a=s.testBit(15),l=s.testBit(14),c=s.testBit(8),u=s.testBit(9),f=new ct.BigInteger(o.slice(2,6)+o.slice(8,16),2).toString(10);return{prefix:(0,ut.sprintf)("%s:%s",e.slice(0,4),e.slice(4,8)),server4:r.address,client4:n.address,flags:o,coneNat:a,microsoft:{reserved:l,universalLocal:u,groupIndividual:c,nonce:f},udpPort:t}}inspect6to4(){let e=this.getBitsBase16(0,16),t=Zi.Address4.fromHex(this.getBitsBase16(16,48));return{prefix:(0,ut.sprintf)("%s",e.slice(0,4)),gateway:t.address}}to6to4(){if(!this.is4())return null;let e=["2002",this.getBitsBase16(96,112),this.getBitsBase16(112,128),"","/16"].join(":");return new i(e)}toByteArray(){let e=this.bigInteger().toByteArray();return e.length===17&&e[0]===0?e.slice(1):e}toUnsignedByteArray(){return this.toByteArray().map(Nm)}static fromByteArray(e){return this.fromUnsignedByteArray(e.map(Nm))}static fromUnsignedByteArray(e){let t=new ct.BigInteger("256",10),r=new ct.BigInteger("0",10),n=new ct.BigInteger("1",10);for(let s=e.length-1;s>=0;s--)r=r.add(n.multiply(new ct.BigInteger(e[s].toString(10),10))),n=n.multiply(t);return i.fromBigInteger(r)}isCanonical(){return this.addressMinusSuffix===this.canonicalForm()}isLinkLocal(){return this.getBitsBase2(0,64)==="1111111010000000000000000000000000000000000000000000000000000000"}isMulticast(){return this.getType()==="Multicast"}is4(){return this.v4}isTeredo(){return this.isInSubnet(new i("2001::/32"))}is6to4(){return this.isInSubnet(new i("2002::/16"))}isLoopback(){return this.getType()==="Loopback"}href(e){return e===void 0?e="":e=(0,ut.sprintf)(":%s",e),(0,ut.sprintf)("http://[%s]%s/",this.correctForm(),e)}link(e){e||(e={}),e.className===void 0&&(e.className=""),e.prefix===void 0&&(e.prefix="/#address="),e.v4===void 0&&(e.v4=!1);let t=this.correctForm;return e.v4&&(t=this.to4in6),e.className?(0,ut.sprintf)('%2$s',e.prefix,t.call(this),e.className):(0,ut.sprintf)('%2$s',e.prefix,t.call(this))}group(){if(this.elidedGroups===0)return Jl.simpleGroup(this.address).join(":");zs(typeof this.elidedGroups=="number"),zs(typeof this.elisionBegin=="number");let e=[],[t,r]=this.address.split("::");t.length?e.push(...Jl.simpleGroup(t)):e.push("");let n=["hover-group"];for(let s=this.elisionBegin;s',n.join(" "))),r.length?e.push(...Jl.simpleGroup(r,this.elisionEnd)):e.push(""),this.is4()&&(zs(this.address4 instanceof Zi.Address4),e.pop(),e.push(this.address4.groupForV6())),e.join(":")}regularExpressionString(e=!1){let t=[],r=new i(this.correctForm());if(r.elidedGroups===0)t.push((0,Qi.simpleRegularExpression)(r.parsedAddress));else if(r.elidedGroups===Le.GROUPS)t.push((0,Qi.possibleElisions)(Le.GROUPS));else{let n=r.address.split("::");n[0].length&&t.push((0,Qi.simpleRegularExpression)(n[0].split(":"))),zs(typeof r.elidedGroups=="number"),t.push((0,Qi.possibleElisions)(r.elidedGroups,n[0].length!==0,n[1].length!==0)),n[1].length&&t.push((0,Qi.simpleRegularExpression)(n[1].split(":"))),t=[t.join(":")]}return e||(t=["(?=^|",Qi.ADDRESS_BOUNDARY,"|[^\\w\\:])(",...t,")(?=[^\\w\\:]|",Qi.ADDRESS_BOUNDARY,"|$)"]),t.join("")}regularExpression(e=!1){return new RegExp(this.regularExpressionString(e),"i")}};Xt.Address6=Zl});var Ql=x(nt=>{"use strict";var OS=nt&&nt.__createBinding||(Object.create?(function(i,e,t,r){r===void 0&&(r=t);var n=Object.getOwnPropertyDescriptor(e,t);(!n||("get"in n?!e.__esModule:n.writable||n.configurable))&&(n={enumerable:!0,get:function(){return e[t]}}),Object.defineProperty(i,r,n)}):(function(i,e,t,r){r===void 0&&(r=t),i[r]=e[t]})),kS=nt&&nt.__setModuleDefault||(Object.create?(function(i,e){Object.defineProperty(i,"default",{enumerable:!0,value:e})}):function(i,e){i.default=e}),CS=nt&&nt.__importStar||function(i){if(i&&i.__esModule)return i;var e={};if(i!=null)for(var t in i)t!=="default"&&Object.prototype.hasOwnProperty.call(i,t)&&OS(e,i,t);return kS(e,i),e};Object.defineProperty(nt,"__esModule",{value:!0});nt.v6=nt.AddressError=nt.Address6=nt.Address4=void 0;var TS=Wl();Object.defineProperty(nt,"Address4",{enumerable:!0,get:function(){return TS.Address4}});var AS=Bm();Object.defineProperty(nt,"Address6",{enumerable:!0,get:function(){return AS.Address6}});var IS=Hs();Object.defineProperty(nt,"AddressError",{enumerable:!0,get:function(){return IS.AddressError}});var NS=CS(Kl());nt.v6={helpers:NS}});var Fm=x(Rt=>{"use strict";Object.defineProperty(Rt,"__esModule",{value:!0});Rt.ipToBuffer=Rt.int32ToIpv4=Rt.ipv4ToInt32=Rt.validateSocksClientChainOptions=Rt.validateSocksClientOptions=void 0;var ft=jl(),Ze=Fl(),BS=require("stream"),Xl=Ql(),Lm=require("net");function LS(i,e=["connect","bind","associate"]){if(!Ze.SocksCommand[i.command])throw new ft.SocksClientError(Ze.ERRORS.InvalidSocksCommand,i);if(e.indexOf(i.command)===-1)throw new ft.SocksClientError(Ze.ERRORS.InvalidSocksCommandForOperation,i);if(!Pm(i.destination))throw new ft.SocksClientError(Ze.ERRORS.InvalidSocksClientOptionsDestination,i);if(!Mm(i.proxy))throw new ft.SocksClientError(Ze.ERRORS.InvalidSocksClientOptionsProxy,i);if(Rm(i.proxy,i),i.timeout&&!qm(i.timeout))throw new ft.SocksClientError(Ze.ERRORS.InvalidSocksClientOptionsTimeout,i);if(i.existing_socket&&!(i.existing_socket instanceof BS.Duplex))throw new ft.SocksClientError(Ze.ERRORS.InvalidSocksClientOptionsExistingSocket,i)}Rt.validateSocksClientOptions=LS;function RS(i){if(i.command!=="connect")throw new ft.SocksClientError(Ze.ERRORS.InvalidSocksCommandChain,i);if(!Pm(i.destination))throw new ft.SocksClientError(Ze.ERRORS.InvalidSocksClientOptionsDestination,i);if(!(i.proxies&&Array.isArray(i.proxies)&&i.proxies.length>=2))throw new ft.SocksClientError(Ze.ERRORS.InvalidSocksClientOptionsProxiesLength,i);if(i.proxies.forEach(e=>{if(!Mm(e))throw new ft.SocksClientError(Ze.ERRORS.InvalidSocksClientOptionsProxy,i);Rm(e,i)}),i.timeout&&!qm(i.timeout))throw new ft.SocksClientError(Ze.ERRORS.InvalidSocksClientOptionsTimeout,i)}Rt.validateSocksClientChainOptions=RS;function Rm(i,e){if(i.custom_auth_method!==void 0){if(i.custom_auth_methodZe.SOCKS5_CUSTOM_AUTH_END)throw new ft.SocksClientError(Ze.ERRORS.InvalidSocksClientOptionsCustomAuthRange,e);if(i.custom_auth_request_handler===void 0||typeof i.custom_auth_request_handler!="function")throw new ft.SocksClientError(Ze.ERRORS.InvalidSocksClientOptionsCustomAuthOptions,e);if(i.custom_auth_response_size===void 0)throw new ft.SocksClientError(Ze.ERRORS.InvalidSocksClientOptionsCustomAuthOptions,e);if(i.custom_auth_response_handler===void 0||typeof i.custom_auth_response_handler!="function")throw new ft.SocksClientError(Ze.ERRORS.InvalidSocksClientOptionsCustomAuthOptions,e)}}function Pm(i){return i&&typeof i.host=="string"&&typeof i.port=="number"&&i.port>=0&&i.port<=65535}function Mm(i){return i&&(typeof i.host=="string"||typeof i.ipaddress=="string")&&typeof i.port=="number"&&i.port>=0&&i.port<=65535&&(i.type===4||i.type===5)}function qm(i){return typeof i=="number"&&i>0}function PS(i){return new Xl.Address4(i).toArray().reduce((t,r)=>(t<<8)+r,0)}Rt.ipv4ToInt32=PS;function MS(i){let e=i>>>24&255,t=i>>>16&255,r=i>>>8&255,n=i&255;return[e,t,r,n].join(".")}Rt.int32ToIpv4=MS;function qS(i){if(Lm.isIPv4(i)){let e=new Xl.Address4(i);return Buffer.from(e.toArray())}else if(Lm.isIPv6(i)){let e=new Xl.Address6(i);return Buffer.from(e.canonicalForm().split(":").map(t=>t.padStart(4,"0")).join(""),"hex")}else throw new Error("Invalid IP address format")}Rt.ipToBuffer=qS});var Dm=x(Zs=>{"use strict";Object.defineProperty(Zs,"__esModule",{value:!0});Zs.ReceiveBuffer=void 0;var ec=class{constructor(e=4096){this.buffer=Buffer.allocUnsafe(e),this.offset=0,this.originalSize=e}get length(){return this.offset}append(e){if(!Buffer.isBuffer(e))throw new Error("Attempted to append a non-buffer instance to ReceiveBuffer.");if(this.offset+e.length>=this.buffer.length){let t=this.buffer;this.buffer=Buffer.allocUnsafe(Math.max(this.buffer.length+this.originalSize,this.buffer.length+e.length)),t.copy(this.buffer)}return e.copy(this.buffer,this.offset),this.offset+=e.length}peek(e){if(e>this.offset)throw new Error("Attempted to read beyond the bounds of the managed internal data.");return this.buffer.slice(0,e)}get(e){if(e>this.offset)throw new Error("Attempted to read beyond the bounds of the managed internal data.");let t=Buffer.allocUnsafe(e);return this.buffer.slice(0,e).copy(t),this.buffer.copyWithin(0,e,e+this.offset-e),this.offset-=e,t}};Zs.ReceiveBuffer=ec});var jm=x(Si=>{"use strict";var Pr=Si&&Si.__awaiter||function(i,e,t,r){function n(s){return s instanceof t?s:new t(function(o){o(s)})}return new(t||(t=Promise))(function(s,o){function a(u){try{c(r.next(u))}catch(f){o(f)}}function l(u){try{c(r.throw(u))}catch(f){o(f)}}function c(u){u.done?s(u.value):n(u.value).then(a,l)}c((r=r.apply(i,e||[])).next())})};Object.defineProperty(Si,"__esModule",{value:!0});Si.SocksClientError=Si.SocksClient=void 0;var FS=require("events"),Mr=require("net"),gt=dm(),q=Fl(),Ot=Fm(),DS=Dm(),ic=jl();Object.defineProperty(Si,"SocksClientError",{enumerable:!0,get:function(){return ic.SocksClientError}});var tc=Ql(),rc=class i extends FS.EventEmitter{constructor(e){super(),this.options=Object.assign({},e),(0,Ot.validateSocksClientOptions)(e),this.setState(q.SocksClientState.Created)}static createConnection(e,t){return new Promise((r,n)=>{try{(0,Ot.validateSocksClientOptions)(e,["connect"])}catch(o){return typeof t=="function"?(t(o),r(o)):n(o)}let s=new i(e);s.connect(e.existing_socket),s.once("established",o=>{s.removeAllListeners(),typeof t=="function"&&t(null,o),r(o)}),s.once("error",o=>{s.removeAllListeners(),typeof t=="function"?(t(o),r(o)):n(o)})})}static createConnectionChain(e,t){return new Promise((r,n)=>Pr(this,void 0,void 0,function*(){try{(0,Ot.validateSocksClientChainOptions)(e)}catch(s){return typeof t=="function"?(t(s),r(s)):n(s)}e.randomizeChain&&(0,ic.shuffleArray)(e.proxies);try{let s;for(let o=0;othis.onDataReceivedHandler(r),this.onClose=()=>this.onCloseHandler(),this.onError=r=>this.onErrorHandler(r),this.onConnect=()=>this.onConnectHandler();let t=setTimeout(()=>this.onEstablishedTimeout(),this.options.timeout||q.DEFAULT_TIMEOUT);t.unref&&typeof t.unref=="function"&&t.unref(),e?this.socket=e:this.socket=new Mr.Socket,this.socket.once("close",this.onClose),this.socket.once("error",this.onError),this.socket.once("connect",this.onConnect),this.socket.on("data",this.onDataReceived),this.setState(q.SocksClientState.Connecting),this.receiveBuffer=new DS.ReceiveBuffer,e?this.socket.emit("connect"):(this.socket.connect(this.getSocketOptions()),this.options.set_tcp_nodelay!==void 0&&this.options.set_tcp_nodelay!==null&&this.socket.setNoDelay(!!this.options.set_tcp_nodelay)),this.prependOnceListener("established",r=>{setImmediate(()=>{if(this.receiveBuffer.length>0){let n=this.receiveBuffer.get(this.receiveBuffer.length);r.socket.emit("data",n)}r.socket.resume()})})}getSocketOptions(){return Object.assign(Object.assign({},this.options.socket_options),{host:this.options.proxy.host||this.options.proxy.ipaddress,port:this.options.proxy.port})}onEstablishedTimeout(){this.state!==q.SocksClientState.Established&&this.state!==q.SocksClientState.BoundWaitingForConnection&&this.closeSocket(q.ERRORS.ProxyConnectionTimedOut)}onConnectHandler(){this.setState(q.SocksClientState.Connected),this.options.proxy.type===4?this.sendSocks4InitialHandshake():this.sendSocks5InitialHandshake(),this.setState(q.SocksClientState.SentInitialHandshake)}onDataReceivedHandler(e){this.receiveBuffer.append(e),this.processData()}processData(){for(;this.state!==q.SocksClientState.Established&&this.state!==q.SocksClientState.Error&&this.receiveBuffer.length>=this.nextRequiredPacketBufferSize;)if(this.state===q.SocksClientState.SentInitialHandshake)this.options.proxy.type===4?this.handleSocks4FinalHandshakeResponse():this.handleInitialSocks5HandshakeResponse();else if(this.state===q.SocksClientState.SentAuthentication)this.handleInitialSocks5AuthenticationHandshakeResponse();else if(this.state===q.SocksClientState.SentFinalHandshake)this.handleSocks5FinalHandshakeResponse();else if(this.state===q.SocksClientState.BoundWaitingForConnection)this.options.proxy.type===4?this.handleSocks4IncomingConnectionResponse():this.handleSocks5IncomingConnectionResponse();else{this.closeSocket(q.ERRORS.InternalError);break}}onCloseHandler(){this.closeSocket(q.ERRORS.SocketClosed)}onErrorHandler(e){this.closeSocket(e.message)}removeInternalSocketHandlers(){this.socket.pause(),this.socket.removeListener("data",this.onDataReceived),this.socket.removeListener("close",this.onClose),this.socket.removeListener("error",this.onError),this.socket.removeListener("connect",this.onConnect)}closeSocket(e){this.state!==q.SocksClientState.Error&&(this.setState(q.SocksClientState.Error),this.socket.destroy(),this.removeInternalSocketHandlers(),this.emit("error",new ic.SocksClientError(e,this.options)))}sendSocks4InitialHandshake(){let e=this.options.proxy.userId||"",t=new gt.SmartBuffer;t.writeUInt8(4),t.writeUInt8(q.SocksCommand[this.options.command]),t.writeUInt16BE(this.options.destination.port),Mr.isIPv4(this.options.destination.host)?(t.writeBuffer((0,Ot.ipToBuffer)(this.options.destination.host)),t.writeStringNT(e)):(t.writeUInt8(0),t.writeUInt8(0),t.writeUInt8(0),t.writeUInt8(1),t.writeStringNT(e),t.writeStringNT(this.options.destination.host)),this.nextRequiredPacketBufferSize=q.SOCKS_INCOMING_PACKET_SIZES.Socks4Response,this.socket.write(t.toBuffer())}handleSocks4FinalHandshakeResponse(){let e=this.receiveBuffer.get(8);if(e[1]!==q.Socks4Response.Granted)this.closeSocket(`${q.ERRORS.Socks4ProxyRejectedConnection} - (${q.Socks4Response[e[1]]})`);else if(q.SocksCommand[this.options.command]===q.SocksCommand.bind){let t=gt.SmartBuffer.fromBuffer(e);t.readOffset=2;let r={port:t.readUInt16BE(),host:(0,Ot.int32ToIpv4)(t.readUInt32BE())};r.host==="0.0.0.0"&&(r.host=this.options.proxy.ipaddress),this.setState(q.SocksClientState.BoundWaitingForConnection),this.emit("bound",{remoteHost:r,socket:this.socket})}else this.setState(q.SocksClientState.Established),this.removeInternalSocketHandlers(),this.emit("established",{socket:this.socket})}handleSocks4IncomingConnectionResponse(){let e=this.receiveBuffer.get(8);if(e[1]!==q.Socks4Response.Granted)this.closeSocket(`${q.ERRORS.Socks4ProxyRejectedIncomingBoundConnection} - (${q.Socks4Response[e[1]]})`);else{let t=gt.SmartBuffer.fromBuffer(e);t.readOffset=2;let r={port:t.readUInt16BE(),host:(0,Ot.int32ToIpv4)(t.readUInt32BE())};this.setState(q.SocksClientState.Established),this.removeInternalSocketHandlers(),this.emit("established",{remoteHost:r,socket:this.socket})}}sendSocks5InitialHandshake(){let e=new gt.SmartBuffer,t=[q.Socks5Auth.NoAuth];(this.options.proxy.userId||this.options.proxy.password)&&t.push(q.Socks5Auth.UserPass),this.options.proxy.custom_auth_method!==void 0&&t.push(this.options.proxy.custom_auth_method),e.writeUInt8(5),e.writeUInt8(t.length);for(let r of t)e.writeUInt8(r);this.nextRequiredPacketBufferSize=q.SOCKS_INCOMING_PACKET_SIZES.Socks5InitialHandshakeResponse,this.socket.write(e.toBuffer()),this.setState(q.SocksClientState.SentInitialHandshake)}handleInitialSocks5HandshakeResponse(){let e=this.receiveBuffer.get(2);e[0]!==5?this.closeSocket(q.ERRORS.InvalidSocks5IntiailHandshakeSocksVersion):e[1]===q.SOCKS5_NO_ACCEPTABLE_AUTH?this.closeSocket(q.ERRORS.InvalidSocks5InitialHandshakeNoAcceptedAuthType):e[1]===q.Socks5Auth.NoAuth?(this.socks5ChosenAuthType=q.Socks5Auth.NoAuth,this.sendSocks5CommandRequest()):e[1]===q.Socks5Auth.UserPass?(this.socks5ChosenAuthType=q.Socks5Auth.UserPass,this.sendSocks5UserPassAuthentication()):e[1]===this.options.proxy.custom_auth_method?(this.socks5ChosenAuthType=this.options.proxy.custom_auth_method,this.sendSocks5CustomAuthentication()):this.closeSocket(q.ERRORS.InvalidSocks5InitialHandshakeUnknownAuthType)}sendSocks5UserPassAuthentication(){let e=this.options.proxy.userId||"",t=this.options.proxy.password||"",r=new gt.SmartBuffer;r.writeUInt8(1),r.writeUInt8(Buffer.byteLength(e)),r.writeString(e),r.writeUInt8(Buffer.byteLength(t)),r.writeString(t),this.nextRequiredPacketBufferSize=q.SOCKS_INCOMING_PACKET_SIZES.Socks5UserPassAuthenticationResponse,this.socket.write(r.toBuffer()),this.setState(q.SocksClientState.SentAuthentication)}sendSocks5CustomAuthentication(){return Pr(this,void 0,void 0,function*(){this.nextRequiredPacketBufferSize=this.options.proxy.custom_auth_response_size,this.socket.write(yield this.options.proxy.custom_auth_request_handler()),this.setState(q.SocksClientState.SentAuthentication)})}handleSocks5CustomAuthHandshakeResponse(e){return Pr(this,void 0,void 0,function*(){return yield this.options.proxy.custom_auth_response_handler(e)})}handleSocks5AuthenticationNoAuthHandshakeResponse(e){return Pr(this,void 0,void 0,function*(){return e[1]===0})}handleSocks5AuthenticationUserPassHandshakeResponse(e){return Pr(this,void 0,void 0,function*(){return e[1]===0})}handleInitialSocks5AuthenticationHandshakeResponse(){return Pr(this,void 0,void 0,function*(){this.setState(q.SocksClientState.ReceivedAuthenticationResponse);let e=!1;this.socks5ChosenAuthType===q.Socks5Auth.NoAuth?e=yield this.handleSocks5AuthenticationNoAuthHandshakeResponse(this.receiveBuffer.get(2)):this.socks5ChosenAuthType===q.Socks5Auth.UserPass?e=yield this.handleSocks5AuthenticationUserPassHandshakeResponse(this.receiveBuffer.get(2)):this.socks5ChosenAuthType===this.options.proxy.custom_auth_method&&(e=yield this.handleSocks5CustomAuthHandshakeResponse(this.receiveBuffer.get(this.options.proxy.custom_auth_response_size))),e?this.sendSocks5CommandRequest():this.closeSocket(q.ERRORS.Socks5AuthenticationFailed)})}sendSocks5CommandRequest(){let e=new gt.SmartBuffer;e.writeUInt8(5),e.writeUInt8(q.SocksCommand[this.options.command]),e.writeUInt8(0),Mr.isIPv4(this.options.destination.host)?(e.writeUInt8(q.Socks5HostType.IPv4),e.writeBuffer((0,Ot.ipToBuffer)(this.options.destination.host))):Mr.isIPv6(this.options.destination.host)?(e.writeUInt8(q.Socks5HostType.IPv6),e.writeBuffer((0,Ot.ipToBuffer)(this.options.destination.host))):(e.writeUInt8(q.Socks5HostType.Hostname),e.writeUInt8(this.options.destination.host.length),e.writeString(this.options.destination.host)),e.writeUInt16BE(this.options.destination.port),this.nextRequiredPacketBufferSize=q.SOCKS_INCOMING_PACKET_SIZES.Socks5ResponseHeader,this.socket.write(e.toBuffer()),this.setState(q.SocksClientState.SentFinalHandshake)}handleSocks5FinalHandshakeResponse(){let e=this.receiveBuffer.peek(5);if(e[0]!==5||e[1]!==q.Socks5Response.Granted)this.closeSocket(`${q.ERRORS.InvalidSocks5FinalHandshakeRejected} - ${q.Socks5Response[e[1]]}`);else{let t=e[3],r,n;if(t===q.Socks5HostType.IPv4){let s=q.SOCKS_INCOMING_PACKET_SIZES.Socks5ResponseIPv4;if(this.receiveBuffer.length{"use strict";var jS=Xi&&Xi.__createBinding||(Object.create?(function(i,e,t,r){r===void 0&&(r=t);var n=Object.getOwnPropertyDescriptor(e,t);(!n||("get"in n?!e.__esModule:n.writable||n.configurable))&&(n={enumerable:!0,get:function(){return e[t]}}),Object.defineProperty(i,r,n)}):(function(i,e,t,r){r===void 0&&(r=t),i[r]=e[t]})),US=Xi&&Xi.__exportStar||function(i,e){for(var t in i)t!=="default"&&!Object.prototype.hasOwnProperty.call(e,t)&&jS(e,i,t)};Object.defineProperty(Xi,"__esModule",{value:!0});US(jm(),Xi)});var $m=x(Pt=>{"use strict";var $S=Pt&&Pt.__createBinding||(Object.create?(function(i,e,t,r){r===void 0&&(r=t);var n=Object.getOwnPropertyDescriptor(e,t);(!n||("get"in n?!e.__esModule:n.writable||n.configurable))&&(n={enumerable:!0,get:function(){return e[t]}}),Object.defineProperty(i,r,n)}):(function(i,e,t,r){r===void 0&&(r=t),i[r]=e[t]})),VS=Pt&&Pt.__setModuleDefault||(Object.create?(function(i,e){Object.defineProperty(i,"default",{enumerable:!0,value:e})}):function(i,e){i.default=e}),nc=Pt&&Pt.__importStar||function(i){if(i&&i.__esModule)return i;var e={};if(i!=null)for(var t in i)t!=="default"&&Object.prototype.hasOwnProperty.call(i,t)&&$S(e,i,t);return VS(e,i),e},HS=Pt&&Pt.__importDefault||function(i){return i&&i.__esModule?i:{default:i}};Object.defineProperty(Pt,"__esModule",{value:!0});Pt.SocksProxyAgent=void 0;var GS=Um(),WS=Va(),YS=HS(rn()),KS=nc(require("dns")),zS=nc(require("net")),JS=nc(require("tls")),ZS=require("url"),Qs=(0,YS.default)("socks-proxy-agent"),QS=i=>i.servername===void 0&&i.host&&!zS.isIP(i.host)?{...i,servername:i.host}:i;function XS(i){let e=!1,t=5,r=i.hostname,n=parseInt(i.port,10)||1080;switch(i.protocol.replace(":","")){case"socks4":e=!0,t=4;break;case"socks4a":t=4;break;case"socks5":e=!0,t=5;break;case"socks":t=5;break;case"socks5h":t=5;break;default:throw new TypeError(`A "socks" protocol must be specified! Got: ${String(i.protocol)}`)}let s={host:r,port:n,type:t};return i.username&&Object.defineProperty(s,"userId",{value:decodeURIComponent(i.username),enumerable:!1}),i.password!=null&&Object.defineProperty(s,"password",{value:decodeURIComponent(i.password),enumerable:!1}),{lookup:e,proxy:s}}var Xs=class extends WS.Agent{constructor(e,t){var o,a;super(t);let r=typeof e=="string"?new ZS.URL(e):e,{proxy:n,lookup:s}=XS(r);this.shouldLookup=s,this.proxy=n,this.timeout=(o=t==null?void 0:t.timeout)!=null?o:null,this.socketOptions=(a=t==null?void 0:t.socketOptions)!=null?a:null}async connect(e,t){var d;let{shouldLookup:r,proxy:n,timeout:s}=this;if(!t.host)throw new Error("No `host` defined!");let{host:o}=t,{port:a,lookup:l=KS.lookup}=t;r&&(o=await new Promise((m,g)=>{l(o,{},(y,b)=>{y?g(y):m(b)})}));let c={proxy:n,destination:{host:o,port:typeof a=="number"?a:parseInt(a,10)},command:"connect",timeout:s!=null?s:void 0,socket_options:(d=this.socketOptions)!=null?d:void 0},u=m=>{e.destroy(),f.destroy(),m&&m.destroy()};Qs("Creating socks proxy connection: %o",c);let{socket:f}=await GS.SocksClient.createConnection(c);if(Qs("Successfully created socks proxy connection"),s!==null&&(f.setTimeout(s),f.on("timeout",()=>u())),t.secureEndpoint){Qs("Upgrading socket connection to TLS");let m=JS.connect({...eE(QS(t),"host","path","port"),socket:f});return m.once("error",g=>{Qs("Socket TLS error",g.message),u(m)}),m}return f}};Xs.protocols=["socks","socks4","socks4a","socks5","socks5h"];Pt.SocksProxyAgent=Xs;function eE(i,...e){let t={},r;for(r in i)e.includes(r)||(t[r]=i[r]);return t}});var Wm=x((lN,Gm)=>{"use strict";var{Duplex:tE}=require("stream");function Vm(i){i.emit("close")}function iE(){!this.destroyed&&this._writableState.finished&&this.destroy()}function Hm(i){this.removeListener("error",Hm),this.destroy(),this.listenerCount("error")===0&&this.emit("error",i)}function rE(i,e){let t=!0,r=new tE({...e,autoDestroy:!1,emitClose:!1,objectMode:!1,writableObjectMode:!1});return i.on("message",function(s,o){let a=!o&&r._readableState.objectMode?s.toString():s;r.push(a)||i.pause()}),i.once("error",function(s){r.destroyed||(t=!1,r.destroy(s))}),i.once("close",function(){r.destroyed||r.push(null)}),r._destroy=function(n,s){if(i.readyState===i.CLOSED){s(n),process.nextTick(Vm,r);return}let o=!1;i.once("error",function(l){o=!0,s(l)}),i.once("close",function(){o||s(n),process.nextTick(Vm,r)}),t&&i.terminate()},r._final=function(n){if(i.readyState===i.CONNECTING){i.once("open",function(){r._final(n)});return}i._socket!==null&&(i._socket._writableState.finished?(n(),r._readableState.endEmitted&&r.destroy()):(i._socket.once("finish",function(){n()}),i.close()))},r._read=function(){i.isPaused&&i.resume()},r._write=function(n,s,o){if(i.readyState===i.CONNECTING){i.once("open",function(){r._write(n,s,o)});return}i.send(n,o)},r.on("end",iE),r.on("error",Hm),r}Gm.exports=rE});var Ei=x((cN,Ym)=>{"use strict";Ym.exports={BINARY_TYPES:["nodebuffer","arraybuffer","fragments"],EMPTY_BUFFER:Buffer.alloc(0),GUID:"258EAFA5-E914-47DA-95CA-C5AB0DC85B11",kForOnEventAttribute:Symbol("kIsForOnEventAttribute"),kListener:Symbol("kListener"),kStatusCode:Symbol("status-code"),kWebSocket:Symbol("websocket"),NOOP:()=>{}}});var pn=x((uN,eo)=>{"use strict";var{EMPTY_BUFFER:nE}=Ei(),sc=Buffer[Symbol.species];function sE(i,e){if(i.length===0)return nE;if(i.length===1)return i[0];let t=Buffer.allocUnsafe(e),r=0;for(let n=0;n{"use strict";var Jm=Symbol("kDone"),ac=Symbol("kRun"),lc=class{constructor(e){this[Jm]=()=>{this.pending--,this[ac]()},this.concurrency=e||1/0,this.jobs=[],this.pending=0}add(e){this.jobs.push(e),this[ac]()}[ac](){if(this.pending!==this.concurrency&&this.jobs.length){let e=this.jobs.shift();this.pending++,e(this[Jm])}}};Zm.exports=lc});var gn=x((hN,ig)=>{"use strict";var dn=require("zlib"),Xm=pn(),aE=Qm(),{kStatusCode:eg}=Ei(),lE=Buffer[Symbol.species],cE=Buffer.from([0,0,255,255]),ro=Symbol("permessage-deflate"),hi=Symbol("total-length"),mn=Symbol("callback"),Oi=Symbol("buffers"),io=Symbol("error"),to,cc=class{constructor(e,t,r){if(this._maxPayload=r|0,this._options=e||{},this._threshold=this._options.threshold!==void 0?this._options.threshold:1024,this._isServer=!!t,this._deflate=null,this._inflate=null,this.params=null,!to){let n=this._options.concurrencyLimit!==void 0?this._options.concurrencyLimit:10;to=new aE(n)}}static get extensionName(){return"permessage-deflate"}offer(){let e={};return this._options.serverNoContextTakeover&&(e.server_no_context_takeover=!0),this._options.clientNoContextTakeover&&(e.client_no_context_takeover=!0),this._options.serverMaxWindowBits&&(e.server_max_window_bits=this._options.serverMaxWindowBits),this._options.clientMaxWindowBits?e.client_max_window_bits=this._options.clientMaxWindowBits:this._options.clientMaxWindowBits==null&&(e.client_max_window_bits=!0),e}accept(e){return e=this.normalizeParams(e),this.params=this._isServer?this.acceptAsServer(e):this.acceptAsClient(e),this.params}cleanup(){if(this._inflate&&(this._inflate.close(),this._inflate=null),this._deflate){let e=this._deflate[mn];this._deflate.close(),this._deflate=null,e&&e(new Error("The deflate stream was closed while data was being processed"))}}acceptAsServer(e){let t=this._options,r=e.find(n=>!(t.serverNoContextTakeover===!1&&n.server_no_context_takeover||n.server_max_window_bits&&(t.serverMaxWindowBits===!1||typeof t.serverMaxWindowBits=="number"&&t.serverMaxWindowBits>n.server_max_window_bits)||typeof t.clientMaxWindowBits=="number"&&!n.client_max_window_bits));if(!r)throw new Error("None of the extension offers can be accepted");return t.serverNoContextTakeover&&(r.server_no_context_takeover=!0),t.clientNoContextTakeover&&(r.client_no_context_takeover=!0),typeof t.serverMaxWindowBits=="number"&&(r.server_max_window_bits=t.serverMaxWindowBits),typeof t.clientMaxWindowBits=="number"?r.client_max_window_bits=t.clientMaxWindowBits:(r.client_max_window_bits===!0||t.clientMaxWindowBits===!1)&&delete r.client_max_window_bits,r}acceptAsClient(e){let t=e[0];if(this._options.clientNoContextTakeover===!1&&t.client_no_context_takeover)throw new Error('Unexpected parameter "client_no_context_takeover"');if(!t.client_max_window_bits)typeof this._options.clientMaxWindowBits=="number"&&(t.client_max_window_bits=this._options.clientMaxWindowBits);else if(this._options.clientMaxWindowBits===!1||typeof this._options.clientMaxWindowBits=="number"&&t.client_max_window_bits>this._options.clientMaxWindowBits)throw new Error('Unexpected or invalid parameter "client_max_window_bits"');return t}normalizeParams(e){return e.forEach(t=>{Object.keys(t).forEach(r=>{let n=t[r];if(n.length>1)throw new Error(`Parameter "${r}" must have only a single value`);if(n=n[0],r==="client_max_window_bits"){if(n!==!0){let s=+n;if(!Number.isInteger(s)||s<8||s>15)throw new TypeError(`Invalid value for parameter "${r}": ${n}`);n=s}else if(!this._isServer)throw new TypeError(`Invalid value for parameter "${r}": ${n}`)}else if(r==="server_max_window_bits"){let s=+n;if(!Number.isInteger(s)||s<8||s>15)throw new TypeError(`Invalid value for parameter "${r}": ${n}`);n=s}else if(r==="client_no_context_takeover"||r==="server_no_context_takeover"){if(n!==!0)throw new TypeError(`Invalid value for parameter "${r}": ${n}`)}else throw new Error(`Unknown parameter "${r}"`);t[r]=n})}),e}decompress(e,t,r){to.add(n=>{this._decompress(e,t,(s,o)=>{n(),r(s,o)})})}compress(e,t,r){to.add(n=>{this._compress(e,t,(s,o)=>{n(),r(s,o)})})}_decompress(e,t,r){let n=this._isServer?"client":"server";if(!this._inflate){let s=`${n}_max_window_bits`,o=typeof this.params[s]!="number"?dn.Z_DEFAULT_WINDOWBITS:this.params[s];this._inflate=dn.createInflateRaw({...this._options.zlibInflateOptions,windowBits:o}),this._inflate[ro]=this,this._inflate[hi]=0,this._inflate[Oi]=[],this._inflate.on("error",fE),this._inflate.on("data",tg)}this._inflate[mn]=r,this._inflate.write(e),t&&this._inflate.write(cE),this._inflate.flush(()=>{let s=this._inflate[io];if(s){this._inflate.close(),this._inflate=null,r(s);return}let o=Xm.concat(this._inflate[Oi],this._inflate[hi]);this._inflate._readableState.endEmitted?(this._inflate.close(),this._inflate=null):(this._inflate[hi]=0,this._inflate[Oi]=[],t&&this.params[`${n}_no_context_takeover`]&&this._inflate.reset()),r(null,o)})}_compress(e,t,r){let n=this._isServer?"server":"client";if(!this._deflate){let s=`${n}_max_window_bits`,o=typeof this.params[s]!="number"?dn.Z_DEFAULT_WINDOWBITS:this.params[s];this._deflate=dn.createDeflateRaw({...this._options.zlibDeflateOptions,windowBits:o}),this._deflate[hi]=0,this._deflate[Oi]=[],this._deflate.on("data",uE)}this._deflate[mn]=r,this._deflate.write(e),this._deflate.flush(dn.Z_SYNC_FLUSH,()=>{if(!this._deflate)return;let s=Xm.concat(this._deflate[Oi],this._deflate[hi]);t&&(s=new lE(s.buffer,s.byteOffset,s.length-4)),this._deflate[mn]=null,this._deflate[hi]=0,this._deflate[Oi]=[],t&&this.params[`${n}_no_context_takeover`]&&this._deflate.reset(),r(null,s)})}};ig.exports=cc;function uE(i){this[Oi].push(i),this[hi]+=i.length}function tg(i){if(this[hi]+=i.length,this[ro]._maxPayload<1||this[hi]<=this[ro]._maxPayload){this[Oi].push(i);return}this[io]=new RangeError("Max payload size exceeded"),this[io].code="WS_ERR_UNSUPPORTED_MESSAGE_LENGTH",this[io][eg]=1009,this.removeListener("data",tg),this.reset()}function fE(i){this[ro]._inflate=null,i[eg]=1007,this[mn](i)}});var vn=x((pN,no)=>{"use strict";var{isUtf8:rg}=require("buffer"),hE=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,1,1,1,1,0,0,1,1,0,1,1,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,0,1,0];function pE(i){return i>=1e3&&i<=1014&&i!==1004&&i!==1005&&i!==1006||i>=3e3&&i<=4999}function uc(i){let e=i.length,t=0;for(;t=e||(i[t+1]&192)!==128||(i[t+2]&192)!==128||i[t]===224&&(i[t+1]&224)===128||i[t]===237&&(i[t+1]&224)===160)return!1;t+=3}else if((i[t]&248)===240){if(t+3>=e||(i[t+1]&192)!==128||(i[t+2]&192)!==128||(i[t+3]&192)!==128||i[t]===240&&(i[t+1]&240)===128||i[t]===244&&i[t+1]>143||i[t]>244)return!1;t+=4}else return!1;return!0}no.exports={isValidStatusCode:pE,isValidUTF8:uc,tokenChars:hE};if(rg)no.exports.isValidUTF8=function(i){return i.length<24?uc(i):rg(i)};else if(!process.env.WS_NO_UTF_8_VALIDATE)try{let i=require("utf-8-validate");no.exports.isValidUTF8=function(e){return e.length<32?uc(e):i(e)}}catch{}});var mc=x((dN,ug)=>{"use strict";var{Writable:dE}=require("stream"),ng=gn(),{BINARY_TYPES:mE,EMPTY_BUFFER:sg,kStatusCode:gE,kWebSocket:vE}=Ei(),{concat:fc,toArrayBuffer:yE,unmask:bE}=pn(),{isValidStatusCode:_E,isValidUTF8:og}=vn(),so=Buffer[Symbol.species],Mt=0,ag=1,lg=2,cg=3,hc=4,pc=5,oo=6,dc=class extends dE{constructor(e={}){super(),this._allowSynchronousEvents=e.allowSynchronousEvents!==void 0?e.allowSynchronousEvents:!0,this._binaryType=e.binaryType||mE[0],this._extensions=e.extensions||{},this._isServer=!!e.isServer,this._maxPayload=e.maxPayload|0,this._skipUTF8Validation=!!e.skipUTF8Validation,this[vE]=void 0,this._bufferedBytes=0,this._buffers=[],this._compressed=!1,this._payloadLength=0,this._mask=void 0,this._fragmented=0,this._masked=!1,this._fin=!1,this._opcode=0,this._totalPayloadLength=0,this._messageLength=0,this._fragments=[],this._errored=!1,this._loop=!1,this._state=Mt}_write(e,t,r){if(this._opcode===8&&this._state==Mt)return r();this._bufferedBytes+=e.length,this._buffers.push(e),this.startLoop(r)}consume(e){if(this._bufferedBytes-=e,e===this._buffers[0].length)return this._buffers.shift();if(e=r.length?t.set(this._buffers.shift(),n):(t.set(new Uint8Array(r.buffer,r.byteOffset,e),n),this._buffers[0]=new so(r.buffer,r.byteOffset+e,r.length-e)),e-=r.length}while(e>0);return t}startLoop(e){this._loop=!0;do switch(this._state){case Mt:this.getInfo(e);break;case ag:this.getPayloadLength16(e);break;case lg:this.getPayloadLength64(e);break;case cg:this.getMask();break;case hc:this.getData(e);break;case pc:case oo:this._loop=!1;return}while(this._loop);this._errored||e()}getInfo(e){if(this._bufferedBytes<2){this._loop=!1;return}let t=this.consume(2);if((t[0]&48)!==0){let n=this.createError(RangeError,"RSV2 and RSV3 must be clear",!0,1002,"WS_ERR_UNEXPECTED_RSV_2_3");e(n);return}let r=(t[0]&64)===64;if(r&&!this._extensions[ng.extensionName]){let n=this.createError(RangeError,"RSV1 must be clear",!0,1002,"WS_ERR_UNEXPECTED_RSV_1");e(n);return}if(this._fin=(t[0]&128)===128,this._opcode=t[0]&15,this._payloadLength=t[1]&127,this._opcode===0){if(r){let n=this.createError(RangeError,"RSV1 must be clear",!0,1002,"WS_ERR_UNEXPECTED_RSV_1");e(n);return}if(!this._fragmented){let n=this.createError(RangeError,"invalid opcode 0",!0,1002,"WS_ERR_INVALID_OPCODE");e(n);return}this._opcode=this._fragmented}else if(this._opcode===1||this._opcode===2){if(this._fragmented){let n=this.createError(RangeError,`invalid opcode ${this._opcode}`,!0,1002,"WS_ERR_INVALID_OPCODE");e(n);return}this._compressed=r}else if(this._opcode>7&&this._opcode<11){if(!this._fin){let n=this.createError(RangeError,"FIN must be set",!0,1002,"WS_ERR_EXPECTED_FIN");e(n);return}if(r){let n=this.createError(RangeError,"RSV1 must be clear",!0,1002,"WS_ERR_UNEXPECTED_RSV_1");e(n);return}if(this._payloadLength>125||this._opcode===8&&this._payloadLength===1){let n=this.createError(RangeError,`invalid payload length ${this._payloadLength}`,!0,1002,"WS_ERR_INVALID_CONTROL_PAYLOAD_LENGTH");e(n);return}}else{let n=this.createError(RangeError,`invalid opcode ${this._opcode}`,!0,1002,"WS_ERR_INVALID_OPCODE");e(n);return}if(!this._fin&&!this._fragmented&&(this._fragmented=this._opcode),this._masked=(t[1]&128)===128,this._isServer){if(!this._masked){let n=this.createError(RangeError,"MASK must be set",!0,1002,"WS_ERR_EXPECTED_MASK");e(n);return}}else if(this._masked){let n=this.createError(RangeError,"MASK must be clear",!0,1002,"WS_ERR_UNEXPECTED_MASK");e(n);return}this._payloadLength===126?this._state=ag:this._payloadLength===127?this._state=lg:this.haveLength(e)}getPayloadLength16(e){if(this._bufferedBytes<2){this._loop=!1;return}this._payloadLength=this.consume(2).readUInt16BE(0),this.haveLength(e)}getPayloadLength64(e){if(this._bufferedBytes<8){this._loop=!1;return}let t=this.consume(8),r=t.readUInt32BE(0);if(r>Math.pow(2,21)-1){let n=this.createError(RangeError,"Unsupported WebSocket frame: payload length > 2^53 - 1",!1,1009,"WS_ERR_UNSUPPORTED_DATA_PAYLOAD_LENGTH");e(n);return}this._payloadLength=r*Math.pow(2,32)+t.readUInt32BE(4),this.haveLength(e)}haveLength(e){if(this._payloadLength&&this._opcode<8&&(this._totalPayloadLength+=this._payloadLength,this._totalPayloadLength>this._maxPayload&&this._maxPayload>0)){let t=this.createError(RangeError,"Max payload size exceeded",!1,1009,"WS_ERR_UNSUPPORTED_MESSAGE_LENGTH");e(t);return}this._masked?this._state=cg:this._state=hc}getMask(){if(this._bufferedBytes<4){this._loop=!1;return}this._mask=this.consume(4),this._state=hc}getData(e){let t=sg;if(this._payloadLength){if(this._bufferedBytes7){this.controlMessage(t,e);return}if(this._compressed){this._state=pc,this.decompress(t,e);return}t.length&&(this._messageLength=this._totalPayloadLength,this._fragments.push(t)),this.dataMessage(e)}decompress(e,t){this._extensions[ng.extensionName].decompress(e,this._fin,(n,s)=>{if(n)return t(n);if(s.length){if(this._messageLength+=s.length,this._messageLength>this._maxPayload&&this._maxPayload>0){let o=this.createError(RangeError,"Max payload size exceeded",!1,1009,"WS_ERR_UNSUPPORTED_MESSAGE_LENGTH");t(o);return}this._fragments.push(s)}this.dataMessage(t),this._state===Mt&&this.startLoop(t)})}dataMessage(e){if(!this._fin){this._state=Mt;return}let t=this._messageLength,r=this._fragments;if(this._totalPayloadLength=0,this._messageLength=0,this._fragmented=0,this._fragments=[],this._opcode===2){let n;this._binaryType==="nodebuffer"?n=fc(r,t):this._binaryType==="arraybuffer"?n=yE(fc(r,t)):n=r,this._allowSynchronousEvents?(this.emit("message",n,!0),this._state=Mt):(this._state=oo,setImmediate(()=>{this.emit("message",n,!0),this._state=Mt,this.startLoop(e)}))}else{let n=fc(r,t);if(!this._skipUTF8Validation&&!og(n)){let s=this.createError(Error,"invalid UTF-8 sequence",!0,1007,"WS_ERR_INVALID_UTF8");e(s);return}this._state===pc||this._allowSynchronousEvents?(this.emit("message",n,!1),this._state=Mt):(this._state=oo,setImmediate(()=>{this.emit("message",n,!1),this._state=Mt,this.startLoop(e)}))}}controlMessage(e,t){if(this._opcode===8){if(e.length===0)this._loop=!1,this.emit("conclude",1005,sg),this.end();else{let r=e.readUInt16BE(0);if(!_E(r)){let s=this.createError(RangeError,`invalid status code ${r}`,!0,1002,"WS_ERR_INVALID_CLOSE_CODE");t(s);return}let n=new so(e.buffer,e.byteOffset+2,e.length-2);if(!this._skipUTF8Validation&&!og(n)){let s=this.createError(Error,"invalid UTF-8 sequence",!0,1007,"WS_ERR_INVALID_UTF8");t(s);return}this._loop=!1,this.emit("conclude",r,n),this.end()}this._state=Mt;return}this._allowSynchronousEvents?(this.emit(this._opcode===9?"ping":"pong",e),this._state=Mt):(this._state=oo,setImmediate(()=>{this.emit(this._opcode===9?"ping":"pong",e),this._state=Mt,this.startLoop(t)}))}createError(e,t,r,n,s){this._loop=!1,this._errored=!0;let o=new e(r?`Invalid WebSocket frame: ${t}`:t);return Error.captureStackTrace(o,this.createError),o.code=s,o[gE]=n,o}};ug.exports=dc});var vc=x((gN,pg)=>{"use strict";var{Duplex:mN}=require("stream"),{randomFillSync:wE}=require("crypto"),fg=gn(),{EMPTY_BUFFER:xE}=Ei(),{isValidStatusCode:SE}=vn(),{mask:hg,toBuffer:qr}=pn(),Gt=Symbol("kByteLength"),EE=Buffer.alloc(4),ao=8*1024,er,Fr=ao,gc=class i{constructor(e,t,r){this._extensions=t||{},r&&(this._generateMask=r,this._maskBuffer=Buffer.alloc(4)),this._socket=e,this._firstFragment=!0,this._compress=!1,this._bufferedBytes=0,this._deflating=!1,this._queue=[]}static frame(e,t){let r,n=!1,s=2,o=!1;t.mask&&(r=t.maskBuffer||EE,t.generateMask?t.generateMask(r):(Fr===ao&&(er===void 0&&(er=Buffer.alloc(ao)),wE(er,0,ao),Fr=0),r[0]=er[Fr++],r[1]=er[Fr++],r[2]=er[Fr++],r[3]=er[Fr++]),o=(r[0]|r[1]|r[2]|r[3])===0,s=6);let a;typeof e=="string"?(!t.mask||o)&&t[Gt]!==void 0?a=t[Gt]:(e=Buffer.from(e),a=e.length):(a=e.length,n=t.mask&&t.readOnly&&!o);let l=a;a>=65536?(s+=8,l=127):a>125&&(s+=2,l=126);let c=Buffer.allocUnsafe(n?a+s:s);return c[0]=t.fin?t.opcode|128:t.opcode,t.rsv1&&(c[0]|=64),c[1]=l,l===126?c.writeUInt16BE(a,2):l===127&&(c[2]=c[3]=0,c.writeUIntBE(a,4,6)),t.mask?(c[1]|=128,c[s-4]=r[0],c[s-3]=r[1],c[s-2]=r[2],c[s-1]=r[3],o?[c,e]:n?(hg(e,r,c,s,a),[c]):(hg(e,r,e,0,a),[c,e])):[c,e]}close(e,t,r,n){let s;if(e===void 0)s=xE;else{if(typeof e!="number"||!SE(e))throw new TypeError("First argument must be a valid error code number");if(t===void 0||!t.length)s=Buffer.allocUnsafe(2),s.writeUInt16BE(e,0);else{let a=Buffer.byteLength(t);if(a>123)throw new RangeError("The message must not be greater than 123 bytes");s=Buffer.allocUnsafe(2+a),s.writeUInt16BE(e,0),typeof t=="string"?s.write(t,2):s.set(t,2)}}let o={[Gt]:s.length,fin:!0,generateMask:this._generateMask,mask:r,maskBuffer:this._maskBuffer,opcode:8,readOnly:!1,rsv1:!1};this._deflating?this.enqueue([this.dispatch,s,!1,o,n]):this.sendFrame(i.frame(s,o),n)}ping(e,t,r){let n,s;if(typeof e=="string"?(n=Buffer.byteLength(e),s=!1):(e=qr(e),n=e.length,s=qr.readOnly),n>125)throw new RangeError("The data size must not be greater than 125 bytes");let o={[Gt]:n,fin:!0,generateMask:this._generateMask,mask:t,maskBuffer:this._maskBuffer,opcode:9,readOnly:s,rsv1:!1};this._deflating?this.enqueue([this.dispatch,e,!1,o,r]):this.sendFrame(i.frame(e,o),r)}pong(e,t,r){let n,s;if(typeof e=="string"?(n=Buffer.byteLength(e),s=!1):(e=qr(e),n=e.length,s=qr.readOnly),n>125)throw new RangeError("The data size must not be greater than 125 bytes");let o={[Gt]:n,fin:!0,generateMask:this._generateMask,mask:t,maskBuffer:this._maskBuffer,opcode:10,readOnly:s,rsv1:!1};this._deflating?this.enqueue([this.dispatch,e,!1,o,r]):this.sendFrame(i.frame(e,o),r)}send(e,t,r){let n=this._extensions[fg.extensionName],s=t.binary?2:1,o=t.compress,a,l;if(typeof e=="string"?(a=Buffer.byteLength(e),l=!1):(e=qr(e),a=e.length,l=qr.readOnly),this._firstFragment?(this._firstFragment=!1,o&&n&&n.params[n._isServer?"server_no_context_takeover":"client_no_context_takeover"]&&(o=a>=n._threshold),this._compress=o):(o=!1,s=0),t.fin&&(this._firstFragment=!0),n){let c={[Gt]:a,fin:t.fin,generateMask:this._generateMask,mask:t.mask,maskBuffer:this._maskBuffer,opcode:s,readOnly:l,rsv1:o};this._deflating?this.enqueue([this.dispatch,e,this._compress,c,r]):this.dispatch(e,this._compress,c,r)}else this.sendFrame(i.frame(e,{[Gt]:a,fin:t.fin,generateMask:this._generateMask,mask:t.mask,maskBuffer:this._maskBuffer,opcode:s,readOnly:l,rsv1:!1}),r)}dispatch(e,t,r,n){if(!t){this.sendFrame(i.frame(e,r),n);return}let s=this._extensions[fg.extensionName];this._bufferedBytes+=r[Gt],this._deflating=!0,s.compress(e,r.fin,(o,a)=>{if(this._socket.destroyed){let l=new Error("The socket was closed while data was being compressed");typeof n=="function"&&n(l);for(let c=0;c{"use strict";var{kForOnEventAttribute:yn,kListener:yc}=Ei(),dg=Symbol("kCode"),mg=Symbol("kData"),gg=Symbol("kError"),vg=Symbol("kMessage"),yg=Symbol("kReason"),Dr=Symbol("kTarget"),bg=Symbol("kType"),_g=Symbol("kWasClean"),pi=class{constructor(e){this[Dr]=null,this[bg]=e}get target(){return this[Dr]}get type(){return this[bg]}};Object.defineProperty(pi.prototype,"target",{enumerable:!0});Object.defineProperty(pi.prototype,"type",{enumerable:!0});var tr=class extends pi{constructor(e,t={}){super(e),this[dg]=t.code===void 0?0:t.code,this[yg]=t.reason===void 0?"":t.reason,this[_g]=t.wasClean===void 0?!1:t.wasClean}get code(){return this[dg]}get reason(){return this[yg]}get wasClean(){return this[_g]}};Object.defineProperty(tr.prototype,"code",{enumerable:!0});Object.defineProperty(tr.prototype,"reason",{enumerable:!0});Object.defineProperty(tr.prototype,"wasClean",{enumerable:!0});var jr=class extends pi{constructor(e,t={}){super(e),this[gg]=t.error===void 0?null:t.error,this[vg]=t.message===void 0?"":t.message}get error(){return this[gg]}get message(){return this[vg]}};Object.defineProperty(jr.prototype,"error",{enumerable:!0});Object.defineProperty(jr.prototype,"message",{enumerable:!0});var bn=class extends pi{constructor(e,t={}){super(e),this[mg]=t.data===void 0?null:t.data}get data(){return this[mg]}};Object.defineProperty(bn.prototype,"data",{enumerable:!0});var OE={addEventListener(i,e,t={}){for(let n of this.listeners(i))if(!t[yn]&&n[yc]===e&&!n[yn])return;let r;if(i==="message")r=function(s,o){let a=new bn("message",{data:o?s:s.toString()});a[Dr]=this,lo(e,this,a)};else if(i==="close")r=function(s,o){let a=new tr("close",{code:s,reason:o.toString(),wasClean:this._closeFrameReceived&&this._closeFrameSent});a[Dr]=this,lo(e,this,a)};else if(i==="error")r=function(s){let o=new jr("error",{error:s,message:s.message});o[Dr]=this,lo(e,this,o)};else if(i==="open")r=function(){let s=new pi("open");s[Dr]=this,lo(e,this,s)};else return;r[yn]=!!t[yn],r[yc]=e,t.once?this.once(i,r):this.on(i,r)},removeEventListener(i,e){for(let t of this.listeners(i))if(t[yc]===e&&!t[yn]){this.removeListener(i,t);break}}};wg.exports={CloseEvent:tr,ErrorEvent:jr,Event:pi,EventTarget:OE,MessageEvent:bn};function lo(i,e,t){typeof i=="object"&&i.handleEvent?i.handleEvent.call(i,t):i.call(e,t)}});var bc=x((yN,Sg)=>{"use strict";var{tokenChars:_n}=vn();function ei(i,e,t){i[e]===void 0?i[e]=[t]:i[e].push(t)}function kE(i){let e=Object.create(null),t=Object.create(null),r=!1,n=!1,s=!1,o,a,l=-1,c=-1,u=-1,f=0;for(;f{let t=i[e];return Array.isArray(t)||(t=[t]),t.map(r=>[e].concat(Object.keys(r).map(n=>{let s=r[n];return Array.isArray(s)||(s=[s]),s.map(o=>o===!0?n:`${n}=${o}`).join("; ")})).join("; ")).join(", ")}).join(", ")}Sg.exports={format:CE,parse:kE}});var Ec=x((wN,Rg)=>{"use strict";var TE=require("events"),AE=require("https"),IE=require("http"),kg=require("net"),NE=require("tls"),{randomBytes:BE,createHash:LE}=require("crypto"),{Duplex:bN,Readable:_N}=require("stream"),{URL:_c}=require("url"),ki=gn(),RE=mc(),PE=vc(),{BINARY_TYPES:Eg,EMPTY_BUFFER:co,GUID:ME,kForOnEventAttribute:wc,kListener:qE,kStatusCode:FE,kWebSocket:st,NOOP:Cg}=Ei(),{EventTarget:{addEventListener:DE,removeEventListener:jE}}=xg(),{format:UE,parse:$E}=bc(),{toBuffer:VE}=pn(),HE=30*1e3,Tg=Symbol("kAborted"),xc=[8,13],di=["CONNECTING","OPEN","CLOSING","CLOSED"],GE=/^[!#$%&'*+\-.0-9A-Z^_`|a-z~]+$/,De=class i extends TE{constructor(e,t,r){super(),this._binaryType=Eg[0],this._closeCode=1006,this._closeFrameReceived=!1,this._closeFrameSent=!1,this._closeMessage=co,this._closeTimer=null,this._extensions={},this._paused=!1,this._protocol="",this._readyState=i.CONNECTING,this._receiver=null,this._sender=null,this._socket=null,e!==null?(this._bufferedAmount=0,this._isServer=!1,this._redirects=0,t===void 0?t=[]:Array.isArray(t)||(typeof t=="object"&&t!==null?(r=t,t=[]):t=[t]),Ag(this,e,t,r)):(this._autoPong=r.autoPong,this._isServer=!0)}get binaryType(){return this._binaryType}set binaryType(e){Eg.includes(e)&&(this._binaryType=e,this._receiver&&(this._receiver._binaryType=e))}get bufferedAmount(){return this._socket?this._socket._writableState.length+this._sender._bufferedBytes:this._bufferedAmount}get extensions(){return Object.keys(this._extensions).join()}get isPaused(){return this._paused}get onclose(){return null}get onerror(){return null}get onopen(){return null}get onmessage(){return null}get protocol(){return this._protocol}get readyState(){return this._readyState}get url(){return this._url}setSocket(e,t,r){let n=new RE({allowSynchronousEvents:r.allowSynchronousEvents,binaryType:this.binaryType,extensions:this._extensions,isServer:this._isServer,maxPayload:r.maxPayload,skipUTF8Validation:r.skipUTF8Validation});this._sender=new PE(e,this._extensions,r.generateMask),this._receiver=n,this._socket=e,n[st]=this,e[st]=this,n.on("conclude",KE),n.on("drain",zE),n.on("error",JE),n.on("message",ZE),n.on("ping",QE),n.on("pong",XE),e.setTimeout&&e.setTimeout(0),e.setNoDelay&&e.setNoDelay(),t.length>0&&e.unshift(t),e.on("close",Ng),e.on("data",fo),e.on("end",Bg),e.on("error",Lg),this._readyState=i.OPEN,this.emit("open")}emitClose(){if(!this._socket){this._readyState=i.CLOSED,this.emit("close",this._closeCode,this._closeMessage);return}this._extensions[ki.extensionName]&&this._extensions[ki.extensionName].cleanup(),this._receiver.removeAllListeners(),this._readyState=i.CLOSED,this.emit("close",this._closeCode,this._closeMessage)}close(e,t){if(this.readyState!==i.CLOSED){if(this.readyState===i.CONNECTING){kt(this,this._req,"WebSocket was closed before the connection was established");return}if(this.readyState===i.CLOSING){this._closeFrameSent&&(this._closeFrameReceived||this._receiver._writableState.errorEmitted)&&this._socket.end();return}this._readyState=i.CLOSING,this._sender.close(e,t,!this._isServer,r=>{r||(this._closeFrameSent=!0,(this._closeFrameReceived||this._receiver._writableState.errorEmitted)&&this._socket.end())}),this._closeTimer=setTimeout(this._socket.destroy.bind(this._socket),HE)}}pause(){this.readyState===i.CONNECTING||this.readyState===i.CLOSED||(this._paused=!0,this._socket.pause())}ping(e,t,r){if(this.readyState===i.CONNECTING)throw new Error("WebSocket is not open: readyState 0 (CONNECTING)");if(typeof e=="function"?(r=e,e=t=void 0):typeof t=="function"&&(r=t,t=void 0),typeof e=="number"&&(e=e.toString()),this.readyState!==i.OPEN){Sc(this,e,r);return}t===void 0&&(t=!this._isServer),this._sender.ping(e||co,t,r)}pong(e,t,r){if(this.readyState===i.CONNECTING)throw new Error("WebSocket is not open: readyState 0 (CONNECTING)");if(typeof e=="function"?(r=e,e=t=void 0):typeof t=="function"&&(r=t,t=void 0),typeof e=="number"&&(e=e.toString()),this.readyState!==i.OPEN){Sc(this,e,r);return}t===void 0&&(t=!this._isServer),this._sender.pong(e||co,t,r)}resume(){this.readyState===i.CONNECTING||this.readyState===i.CLOSED||(this._paused=!1,this._receiver._writableState.needDrain||this._socket.resume())}send(e,t,r){if(this.readyState===i.CONNECTING)throw new Error("WebSocket is not open: readyState 0 (CONNECTING)");if(typeof t=="function"&&(r=t,t={}),typeof e=="number"&&(e=e.toString()),this.readyState!==i.OPEN){Sc(this,e,r);return}let n={binary:typeof e!="string",mask:!this._isServer,compress:!0,fin:!0,...t};this._extensions[ki.extensionName]||(n.compress=!1),this._sender.send(e||co,n,r)}terminate(){if(this.readyState!==i.CLOSED){if(this.readyState===i.CONNECTING){kt(this,this._req,"WebSocket was closed before the connection was established");return}this._socket&&(this._readyState=i.CLOSING,this._socket.destroy())}}};Object.defineProperty(De,"CONNECTING",{enumerable:!0,value:di.indexOf("CONNECTING")});Object.defineProperty(De.prototype,"CONNECTING",{enumerable:!0,value:di.indexOf("CONNECTING")});Object.defineProperty(De,"OPEN",{enumerable:!0,value:di.indexOf("OPEN")});Object.defineProperty(De.prototype,"OPEN",{enumerable:!0,value:di.indexOf("OPEN")});Object.defineProperty(De,"CLOSING",{enumerable:!0,value:di.indexOf("CLOSING")});Object.defineProperty(De.prototype,"CLOSING",{enumerable:!0,value:di.indexOf("CLOSING")});Object.defineProperty(De,"CLOSED",{enumerable:!0,value:di.indexOf("CLOSED")});Object.defineProperty(De.prototype,"CLOSED",{enumerable:!0,value:di.indexOf("CLOSED")});["binaryType","bufferedAmount","extensions","isPaused","protocol","readyState","url"].forEach(i=>{Object.defineProperty(De.prototype,i,{enumerable:!0})});["open","error","close","message"].forEach(i=>{Object.defineProperty(De.prototype,`on${i}`,{enumerable:!0,get(){for(let e of this.listeners(i))if(e[wc])return e[qE];return null},set(e){for(let t of this.listeners(i))if(t[wc]){this.removeListener(i,t);break}typeof e=="function"&&this.addEventListener(i,e,{[wc]:!0})}})});De.prototype.addEventListener=DE;De.prototype.removeEventListener=jE;Rg.exports=De;function Ag(i,e,t,r){let n={allowSynchronousEvents:!0,autoPong:!0,protocolVersion:xc[1],maxPayload:104857600,skipUTF8Validation:!1,perMessageDeflate:!0,followRedirects:!1,maxRedirects:10,...r,socketPath:void 0,hostname:void 0,protocol:void 0,timeout:void 0,method:"GET",host:void 0,path:void 0,port:void 0};if(i._autoPong=n.autoPong,!xc.includes(n.protocolVersion))throw new RangeError(`Unsupported protocol version: ${n.protocolVersion} (supported versions: ${xc.join(", ")})`);let s;if(e instanceof _c)s=e;else try{s=new _c(e)}catch{throw new SyntaxError(`Invalid URL: ${e}`)}s.protocol==="http:"?s.protocol="ws:":s.protocol==="https:"&&(s.protocol="wss:"),i._url=s.href;let o=s.protocol==="wss:",a=s.protocol==="ws+unix:",l;if(s.protocol!=="ws:"&&!o&&!a?l=`The URL's protocol must be one of "ws:", "wss:", "http:", "https", or "ws+unix:"`:a&&!s.pathname?l="The URL's pathname is empty":s.hash&&(l="The URL contains a fragment identifier"),l){let y=new SyntaxError(l);if(i._redirects===0)throw y;uo(i,y);return}let c=o?443:80,u=BE(16).toString("base64"),f=o?AE.request:IE.request,d=new Set,m;if(n.createConnection=n.createConnection||(o?YE:WE),n.defaultPort=n.defaultPort||c,n.port=s.port||c,n.host=s.hostname.startsWith("[")?s.hostname.slice(1,-1):s.hostname,n.headers={...n.headers,"Sec-WebSocket-Version":n.protocolVersion,"Sec-WebSocket-Key":u,Connection:"Upgrade",Upgrade:"websocket"},n.path=s.pathname+s.search,n.timeout=n.handshakeTimeout,n.perMessageDeflate&&(m=new ki(n.perMessageDeflate!==!0?n.perMessageDeflate:{},!1,n.maxPayload),n.headers["Sec-WebSocket-Extensions"]=UE({[ki.extensionName]:m.offer()})),t.length){for(let y of t){if(typeof y!="string"||!GE.test(y)||d.has(y))throw new SyntaxError("An invalid or duplicated subprotocol was specified");d.add(y)}n.headers["Sec-WebSocket-Protocol"]=t.join(",")}if(n.origin&&(n.protocolVersion<13?n.headers["Sec-WebSocket-Origin"]=n.origin:n.headers.Origin=n.origin),(s.username||s.password)&&(n.auth=`${s.username}:${s.password}`),a){let y=n.path.split(":");n.socketPath=y[0],n.path=y[1]}let g;if(n.followRedirects){if(i._redirects===0){i._originalIpc=a,i._originalSecure=o,i._originalHostOrSocketPath=a?n.socketPath:s.host;let y=r&&r.headers;if(r={...r,headers:{}},y)for(let[b,w]of Object.entries(y))r.headers[b.toLowerCase()]=w}else if(i.listenerCount("redirect")===0){let y=a?i._originalIpc?n.socketPath===i._originalHostOrSocketPath:!1:i._originalIpc?!1:s.host===i._originalHostOrSocketPath;(!y||i._originalSecure&&!o)&&(delete n.headers.authorization,delete n.headers.cookie,y||delete n.headers.host,n.auth=void 0)}n.auth&&!r.headers.authorization&&(r.headers.authorization="Basic "+Buffer.from(n.auth).toString("base64")),g=i._req=f(n),i._redirects&&i.emit("redirect",i.url,g)}else g=i._req=f(n);n.timeout&&g.on("timeout",()=>{kt(i,g,"Opening handshake has timed out")}),g.on("error",y=>{g===null||g[Tg]||(g=i._req=null,uo(i,y))}),g.on("response",y=>{let b=y.headers.location,w=y.statusCode;if(b&&n.followRedirects&&w>=300&&w<400){if(++i._redirects>n.maxRedirects){kt(i,g,"Maximum redirects exceeded");return}g.abort();let S;try{S=new _c(b,e)}catch{let O=new SyntaxError(`Invalid URL: ${b}`);uo(i,O);return}Ag(i,S,t,r)}else i.emit("unexpected-response",g,y)||kt(i,g,`Unexpected server response: ${y.statusCode}`)}),g.on("upgrade",(y,b,w)=>{if(i.emit("upgrade",y),i.readyState!==De.CONNECTING)return;g=i._req=null;let S=y.headers.upgrade;if(S===void 0||S.toLowerCase()!=="websocket"){kt(i,b,"Invalid Upgrade header");return}let k=LE("sha1").update(u+ME).digest("base64");if(y.headers["sec-websocket-accept"]!==k){kt(i,b,"Invalid Sec-WebSocket-Accept header");return}let O=y.headers["sec-websocket-protocol"],E;if(O!==void 0?d.size?d.has(O)||(E="Server sent an invalid subprotocol"):E="Server sent a subprotocol but none was requested":d.size&&(E="Server sent no subprotocol"),E){kt(i,b,E);return}O&&(i._protocol=O);let R=y.headers["sec-websocket-extensions"];if(R!==void 0){if(!m){kt(i,b,"Server sent a Sec-WebSocket-Extensions header but no extension was requested");return}let T;try{T=$E(R)}catch{kt(i,b,"Invalid Sec-WebSocket-Extensions header");return}let A=Object.keys(T);if(A.length!==1||A[0]!==ki.extensionName){kt(i,b,"Server indicated an extension that was not requested");return}try{m.accept(T[ki.extensionName])}catch{kt(i,b,"Invalid Sec-WebSocket-Extensions header");return}i._extensions[ki.extensionName]=m}i.setSocket(b,w,{allowSynchronousEvents:n.allowSynchronousEvents,generateMask:n.generateMask,maxPayload:n.maxPayload,skipUTF8Validation:n.skipUTF8Validation})}),n.finishRequest?n.finishRequest(g,i):g.end()}function uo(i,e){i._readyState=De.CLOSING,i.emit("error",e),i.emitClose()}function WE(i){return i.path=i.socketPath,kg.connect(i)}function YE(i){return i.path=void 0,!i.servername&&i.servername!==""&&(i.servername=kg.isIP(i.host)?"":i.host),NE.connect(i)}function kt(i,e,t){i._readyState=De.CLOSING;let r=new Error(t);Error.captureStackTrace(r,kt),e.setHeader?(e[Tg]=!0,e.abort(),e.socket&&!e.socket.destroyed&&e.socket.destroy(),process.nextTick(uo,i,r)):(e.destroy(r),e.once("error",i.emit.bind(i,"error")),e.once("close",i.emitClose.bind(i)))}function Sc(i,e,t){if(e){let r=VE(e).length;i._socket?i._sender._bufferedBytes+=r:i._bufferedAmount+=r}if(t){let r=new Error(`WebSocket is not open: readyState ${i.readyState} (${di[i.readyState]})`);process.nextTick(t,r)}}function KE(i,e){let t=this[st];t._closeFrameReceived=!0,t._closeMessage=e,t._closeCode=i,t._socket[st]!==void 0&&(t._socket.removeListener("data",fo),process.nextTick(Ig,t._socket),i===1005?t.close():t.close(i,e))}function zE(){let i=this[st];i.isPaused||i._socket.resume()}function JE(i){let e=this[st];e._socket[st]!==void 0&&(e._socket.removeListener("data",fo),process.nextTick(Ig,e._socket),e.close(i[FE])),e.emit("error",i)}function Og(){this[st].emitClose()}function ZE(i,e){this[st].emit("message",i,e)}function QE(i){let e=this[st];e._autoPong&&e.pong(i,!this._isServer,Cg),e.emit("ping",i)}function XE(i){this[st].emit("pong",i)}function Ig(i){i.resume()}function Ng(){let i=this[st];this.removeListener("close",Ng),this.removeListener("data",fo),this.removeListener("end",Bg),i._readyState=De.CLOSING;let e;!this._readableState.endEmitted&&!i._closeFrameReceived&&!i._receiver._writableState.errorEmitted&&(e=i._socket.read())!==null&&i._receiver.write(e),i._receiver.end(),this[st]=void 0,clearTimeout(i._closeTimer),i._receiver._writableState.finished||i._receiver._writableState.errorEmitted?i.emitClose():(i._receiver.on("error",Og),i._receiver.on("finish",Og))}function fo(i){this[st]._receiver.write(i)||this.pause()}function Bg(){let i=this[st];i._readyState=De.CLOSING,i._receiver.end(),this.end()}function Lg(){let i=this[st];this.removeListener("error",Lg),this.on("error",Cg),i&&(i._readyState=De.CLOSING,this.destroy())}});var Mg=x((xN,Pg)=>{"use strict";var{tokenChars:eO}=vn();function tO(i){let e=new Set,t=-1,r=-1,n=0;for(n;n{"use strict";var iO=require("events"),ho=require("http"),{Duplex:SN}=require("stream"),{createHash:rO}=require("crypto"),qg=bc(),ir=gn(),nO=Mg(),sO=Ec(),{GUID:oO,kWebSocket:aO}=Ei(),lO=/^[+/0-9A-Za-z]{22}==$/,Fg=0,Dg=1,Ug=2,Oc=class extends iO{constructor(e,t){if(super(),e={allowSynchronousEvents:!0,autoPong:!0,maxPayload:100*1024*1024,skipUTF8Validation:!1,perMessageDeflate:!1,handleProtocols:null,clientTracking:!0,verifyClient:null,noServer:!1,backlog:null,server:null,host:null,path:null,port:null,WebSocket:sO,...e},e.port==null&&!e.server&&!e.noServer||e.port!=null&&(e.server||e.noServer)||e.server&&e.noServer)throw new TypeError('One and only one of the "port", "server", or "noServer" options must be specified');if(e.port!=null?(this._server=ho.createServer((r,n)=>{let s=ho.STATUS_CODES[426];n.writeHead(426,{"Content-Length":s.length,"Content-Type":"text/plain"}),n.end(s)}),this._server.listen(e.port,e.host,e.backlog,t)):e.server&&(this._server=e.server),this._server){let r=this.emit.bind(this,"connection");this._removeListeners=cO(this._server,{listening:this.emit.bind(this,"listening"),error:this.emit.bind(this,"error"),upgrade:(n,s,o)=>{this.handleUpgrade(n,s,o,r)}})}e.perMessageDeflate===!0&&(e.perMessageDeflate={}),e.clientTracking&&(this.clients=new Set,this._shouldEmitClose=!1),this.options=e,this._state=Fg}address(){if(this.options.noServer)throw new Error('The server is operating in "noServer" mode');return this._server?this._server.address():null}close(e){if(this._state===Ug){e&&this.once("close",()=>{e(new Error("The server is not running"))}),process.nextTick(wn,this);return}if(e&&this.once("close",e),this._state!==Dg)if(this._state=Dg,this.options.noServer||this.options.server)this._server&&(this._removeListeners(),this._removeListeners=this._server=null),this.clients?this.clients.size?this._shouldEmitClose=!0:process.nextTick(wn,this):process.nextTick(wn,this);else{let t=this._server;this._removeListeners(),this._removeListeners=this._server=null,t.close(()=>{wn(this)})}}shouldHandle(e){if(this.options.path){let t=e.url.indexOf("?");if((t!==-1?e.url.slice(0,t):e.url)!==this.options.path)return!1}return!0}handleUpgrade(e,t,r,n){t.on("error",jg);let s=e.headers["sec-websocket-key"],o=e.headers.upgrade,a=+e.headers["sec-websocket-version"];if(e.method!=="GET"){rr(this,e,t,405,"Invalid HTTP method");return}if(o===void 0||o.toLowerCase()!=="websocket"){rr(this,e,t,400,"Invalid Upgrade header");return}if(s===void 0||!lO.test(s)){rr(this,e,t,400,"Missing or invalid Sec-WebSocket-Key header");return}if(a!==8&&a!==13){rr(this,e,t,400,"Missing or invalid Sec-WebSocket-Version header");return}if(!this.shouldHandle(e)){xn(t,400);return}let l=e.headers["sec-websocket-protocol"],c=new Set;if(l!==void 0)try{c=nO.parse(l)}catch{rr(this,e,t,400,"Invalid Sec-WebSocket-Protocol header");return}let u=e.headers["sec-websocket-extensions"],f={};if(this.options.perMessageDeflate&&u!==void 0){let d=new ir(this.options.perMessageDeflate,!0,this.options.maxPayload);try{let m=qg.parse(u);m[ir.extensionName]&&(d.accept(m[ir.extensionName]),f[ir.extensionName]=d)}catch{rr(this,e,t,400,"Invalid or unacceptable Sec-WebSocket-Extensions header");return}}if(this.options.verifyClient){let d={origin:e.headers[`${a===8?"sec-websocket-origin":"origin"}`],secure:!!(e.socket.authorized||e.socket.encrypted),req:e};if(this.options.verifyClient.length===2){this.options.verifyClient(d,(m,g,y,b)=>{if(!m)return xn(t,g||401,y,b);this.completeUpgrade(f,s,c,e,t,r,n)});return}if(!this.options.verifyClient(d))return xn(t,401)}this.completeUpgrade(f,s,c,e,t,r,n)}completeUpgrade(e,t,r,n,s,o,a){if(!s.readable||!s.writable)return s.destroy();if(s[aO])throw new Error("server.handleUpgrade() was called more than once with the same socket, possibly due to a misconfiguration");if(this._state>Fg)return xn(s,503);let c=["HTTP/1.1 101 Switching Protocols","Upgrade: websocket","Connection: Upgrade",`Sec-WebSocket-Accept: ${rO("sha1").update(t+oO).digest("base64")}`],u=new this.options.WebSocket(null,void 0,this.options);if(r.size){let f=this.options.handleProtocols?this.options.handleProtocols(r,n):r.values().next().value;f&&(c.push(`Sec-WebSocket-Protocol: ${f}`),u._protocol=f)}if(e[ir.extensionName]){let f=e[ir.extensionName].params,d=qg.format({[ir.extensionName]:[f]});c.push(`Sec-WebSocket-Extensions: ${d}`),u._extensions=e}this.emit("headers",c,n),s.write(c.concat(`\r +`).join(`\r +`)),s.removeListener("error",jg),u.setSocket(s,o,{allowSynchronousEvents:this.options.allowSynchronousEvents,maxPayload:this.options.maxPayload,skipUTF8Validation:this.options.skipUTF8Validation}),this.clients&&(this.clients.add(u),u.on("close",()=>{this.clients.delete(u),this._shouldEmitClose&&!this.clients.size&&process.nextTick(wn,this)})),a(u,n)}};$g.exports=Oc;function cO(i,e){for(let t of Object.keys(e))i.on(t,e[t]);return function(){for(let r of Object.keys(e))i.removeListener(r,e[r])}}function wn(i){i._state=Ug,i.emit("close")}function jg(){this.destroy()}function xn(i,e,t,r){t=t||ho.STATUS_CODES[e],r={Connection:"close","Content-Type":"text/html","Content-Length":Buffer.byteLength(t),...r},i.once("finish",i.destroy),i.end(`HTTP/1.1 ${e} ${ho.STATUS_CODES[e]}\r +`+Object.keys(r).map(n=>`${n}: ${r[n]}`).join(`\r +`)+`\r +\r +`+t)}function rr(i,e,t,r,n){if(i.listenerCount("wsClientError")){let s=new Error(n);Error.captureStackTrace(s,rr),i.emit("wsClientError",s,t,e)}else xn(t,r,n)}});var Se=x(tt=>{"use strict";var Ac=Symbol.for("yaml.alias"),Wg=Symbol.for("yaml.document"),po=Symbol.for("yaml.map"),Yg=Symbol.for("yaml.pair"),Ic=Symbol.for("yaml.scalar"),mo=Symbol.for("yaml.seq"),mi=Symbol.for("yaml.node.type"),fO=i=>!!i&&typeof i=="object"&&i[mi]===Ac,hO=i=>!!i&&typeof i=="object"&&i[mi]===Wg,pO=i=>!!i&&typeof i=="object"&&i[mi]===po,dO=i=>!!i&&typeof i=="object"&&i[mi]===Yg,Kg=i=>!!i&&typeof i=="object"&&i[mi]===Ic,mO=i=>!!i&&typeof i=="object"&&i[mi]===mo;function zg(i){if(i&&typeof i=="object")switch(i[mi]){case po:case mo:return!0}return!1}function gO(i){if(i&&typeof i=="object")switch(i[mi]){case Ac:case po:case Ic:case mo:return!0}return!1}var vO=i=>(Kg(i)||zg(i))&&!!i.anchor;tt.ALIAS=Ac;tt.DOC=Wg;tt.MAP=po;tt.NODE_TYPE=mi;tt.PAIR=Yg;tt.SCALAR=Ic;tt.SEQ=mo;tt.hasAnchor=vO;tt.isAlias=fO;tt.isCollection=zg;tt.isDocument=hO;tt.isMap=pO;tt.isNode=gO;tt.isPair=dO;tt.isScalar=Kg;tt.isSeq=mO});var Sn=x(Nc=>{"use strict";var Ge=Se(),vt=Symbol("break visit"),Jg=Symbol("skip children"),ti=Symbol("remove node");function go(i,e){let t=Zg(e);Ge.isDocument(i)?Ur(null,i.contents,t,Object.freeze([i]))===ti&&(i.contents=null):Ur(null,i,t,Object.freeze([]))}go.BREAK=vt;go.SKIP=Jg;go.REMOVE=ti;function Ur(i,e,t,r){let n=Qg(i,e,t,r);if(Ge.isNode(n)||Ge.isPair(n))return Xg(i,r,n),Ur(i,n,t,r);if(typeof n!="symbol"){if(Ge.isCollection(e)){r=Object.freeze(r.concat(e));for(let s=0;s{"use strict";var e0=Se(),yO=Sn(),bO={"!":"%21",",":"%2C","[":"%5B","]":"%5D","{":"%7B","}":"%7D"},_O=i=>i.replace(/[!,[\]{}]/g,e=>bO[e]),En=class i{constructor(e,t){this.docStart=null,this.docEnd=!1,this.yaml=Object.assign({},i.defaultYaml,e),this.tags=Object.assign({},i.defaultTags,t)}clone(){let e=new i(this.yaml,this.tags);return e.docStart=this.docStart,e}atDocument(){let e=new i(this.yaml,this.tags);switch(this.yaml.version){case"1.1":this.atNextDocument=!0;break;case"1.2":this.atNextDocument=!1,this.yaml={explicit:i.defaultYaml.explicit,version:"1.2"},this.tags=Object.assign({},i.defaultTags);break}return e}add(e,t){this.atNextDocument&&(this.yaml={explicit:i.defaultYaml.explicit,version:"1.1"},this.tags=Object.assign({},i.defaultTags),this.atNextDocument=!1);let r=e.trim().split(/[ \t]+/),n=r.shift();switch(n){case"%TAG":{if(r.length!==2&&(t(0,"%TAG directive should contain exactly two parts"),r.length<2))return!1;let[s,o]=r;return this.tags[s]=o,!0}case"%YAML":{if(this.yaml.explicit=!0,r.length!==1)return t(0,"%YAML directive should contain exactly one part"),!1;let[s]=r;if(s==="1.1"||s==="1.2")return this.yaml.version=s,!0;{let o=/^\d+\.\d+$/.test(s);return t(6,`Unsupported YAML version ${s}`,o),!1}}default:return t(0,`Unknown directive ${n}`,!0),!1}}tagName(e,t){if(e==="!")return"!";if(e[0]!=="!")return t(`Not a valid tag: ${e}`),null;if(e[1]==="<"){let o=e.slice(2,-1);return o==="!"||o==="!!"?(t(`Verbatim tags aren't resolved, so ${e} is invalid.`),null):(e[e.length-1]!==">"&&t("Verbatim tags must end with a >"),o)}let[,r,n]=e.match(/^(.*!)([^!]*)$/s);n||t(`The ${e} tag has no suffix`);let s=this.tags[r];if(s)try{return s+decodeURIComponent(n)}catch(o){return t(String(o)),null}return r==="!"?e:(t(`Could not resolve tag: ${e}`),null)}tagString(e){for(let[t,r]of Object.entries(this.tags))if(e.startsWith(r))return t+_O(e.substring(r.length));return e[0]==="!"?e:`!<${e}>`}toString(e){let t=this.yaml.explicit?[`%YAML ${this.yaml.version||"1.2"}`]:[],r=Object.entries(this.tags),n;if(e&&r.length>0&&e0.isNode(e.contents)){let s={};yO.visit(e.contents,(o,a)=>{e0.isNode(a)&&a.tag&&(s[a.tag]=!0)}),n=Object.keys(s)}else n=[];for(let[s,o]of r)s==="!!"&&o==="tag:yaml.org,2002:"||(!e||n.some(a=>a.startsWith(o)))&&t.push(`%TAG ${s} ${o}`);return t.join(` +`)}};En.defaultYaml={explicit:!1,version:"1.2"};En.defaultTags={"!!":"tag:yaml.org,2002:"};t0.Directives=En});var yo=x(On=>{"use strict";var i0=Se(),wO=Sn();function xO(i){if(/[\x00-\x19\s,[\]{}]/.test(i)){let t=`Anchor must not contain whitespace or control characters: ${JSON.stringify(i)}`;throw new Error(t)}return!0}function r0(i){let e=new Set;return wO.visit(i,{Value(t,r){r.anchor&&e.add(r.anchor)}}),e}function n0(i,e){for(let t=1;;++t){let r=`${i}${t}`;if(!e.has(r))return r}}function SO(i,e){let t=[],r=new Map,n=null;return{onAnchor:s=>{t.push(s),n||(n=r0(i));let o=n0(e,n);return n.add(o),o},setAnchors:()=>{for(let s of t){let o=r.get(s);if(typeof o=="object"&&o.anchor&&(i0.isScalar(o.node)||i0.isCollection(o.node)))o.node.anchor=o.anchor;else{let a=new Error("Failed to resolve repeated object (this should not happen)");throw a.source=s,a}}},sourceObjects:r}}On.anchorIsValid=xO;On.anchorNames=r0;On.createNodeAnchors=SO;On.findNewAnchor=n0});var Lc=x(s0=>{"use strict";function kn(i,e,t,r){if(r&&typeof r=="object")if(Array.isArray(r))for(let n=0,s=r.length;n{"use strict";var EO=Se();function o0(i,e,t){if(Array.isArray(i))return i.map((r,n)=>o0(r,String(n),t));if(i&&typeof i.toJSON=="function"){if(!t||!EO.hasAnchor(i))return i.toJSON(e,t);let r={aliasCount:0,count:1,res:void 0};t.anchors.set(i,r),t.onCreate=s=>{r.res=s,delete t.onCreate};let n=i.toJSON(e,t);return t.onCreate&&t.onCreate(n),n}return typeof i=="bigint"&&!(t!=null&&t.keep)?Number(i):i}a0.toJS=o0});var bo=x(c0=>{"use strict";var OO=Lc(),l0=Se(),kO=Ci(),Rc=class{constructor(e){Object.defineProperty(this,l0.NODE_TYPE,{value:e})}clone(){let e=Object.create(Object.getPrototypeOf(this),Object.getOwnPropertyDescriptors(this));return this.range&&(e.range=this.range.slice()),e}toJS(e,{mapAsMap:t,maxAliasCount:r,onAnchor:n,reviver:s}={}){if(!l0.isDocument(e))throw new TypeError("A document argument is required");let o={anchors:new Map,doc:e,keep:!0,mapAsMap:t===!0,mapKeyWarned:!1,maxAliasCount:typeof r=="number"?r:100},a=kO.toJS(this,"",o);if(typeof n=="function")for(let{count:l,res:c}of o.anchors.values())n(c,l);return typeof s=="function"?OO.applyReviver(s,{"":a},"",a):a}};c0.NodeBase=Rc});var Cn=x(f0=>{"use strict";var CO=yo(),u0=Sn(),_o=Se(),TO=bo(),AO=Ci(),Pc=class extends TO.NodeBase{constructor(e){super(_o.ALIAS),this.source=e,Object.defineProperty(this,"tag",{set(){throw new Error("Alias nodes cannot have tags")}})}resolve(e){let t;return u0.visit(e,{Node:(r,n)=>{if(n===this)return u0.visit.BREAK;n.anchor===this.source&&(t=n)}}),t}toJSON(e,t){if(!t)return{source:this.source};let{anchors:r,doc:n,maxAliasCount:s}=t,o=this.resolve(n);if(!o){let l=`Unresolved alias (the anchor must be set before the alias): ${this.source}`;throw new ReferenceError(l)}let a=r.get(o);if(a||(AO.toJS(o,null,t),a=r.get(o)),!a||a.res===void 0){let l="This should not happen: Alias anchor was not resolved?";throw new ReferenceError(l)}if(s>=0&&(a.count+=1,a.aliasCount===0&&(a.aliasCount=wo(n,o,r)),a.count*a.aliasCount>s)){let l="Excessive alias count indicates a resource exhaustion attack";throw new ReferenceError(l)}return a.res}toString(e,t,r){let n=`*${this.source}`;if(e){if(CO.anchorIsValid(this.source),e.options.verifyAliasOrder&&!e.anchors.has(this.source)){let s=`Unresolved alias (the anchor must be set before the alias): ${this.source}`;throw new Error(s)}if(e.implicitKey)return`${n} `}return n}};function wo(i,e,t){if(_o.isAlias(e)){let r=e.resolve(i),n=t&&r&&t.get(r);return n?n.count*n.aliasCount:0}else if(_o.isCollection(e)){let r=0;for(let n of e.items){let s=wo(i,n,t);s>r&&(r=s)}return r}else if(_o.isPair(e)){let r=wo(i,e.key,t),n=wo(i,e.value,t);return Math.max(r,n)}return 1}f0.Alias=Pc});var je=x(Mc=>{"use strict";var IO=Se(),NO=bo(),BO=Ci(),LO=i=>!i||typeof i!="function"&&typeof i!="object",Ti=class extends NO.NodeBase{constructor(e){super(IO.SCALAR),this.value=e}toJSON(e,t){return t!=null&&t.keep?this.value:BO.toJS(this.value,e,t)}toString(){return String(this.value)}};Ti.BLOCK_FOLDED="BLOCK_FOLDED";Ti.BLOCK_LITERAL="BLOCK_LITERAL";Ti.PLAIN="PLAIN";Ti.QUOTE_DOUBLE="QUOTE_DOUBLE";Ti.QUOTE_SINGLE="QUOTE_SINGLE";Mc.Scalar=Ti;Mc.isScalarValue=LO});var Tn=x(p0=>{"use strict";var RO=Cn(),nr=Se(),h0=je(),PO="tag:yaml.org,2002:";function MO(i,e,t){var r;if(e){let n=t.filter(o=>o.tag===e),s=(r=n.find(o=>!o.format))!=null?r:n[0];if(!s)throw new Error(`Tag ${e} not found`);return s}return t.find(n=>{var s;return((s=n.identify)==null?void 0:s.call(n,i))&&!n.format})}function qO(i,e,t){var f,d,m;if(nr.isDocument(i)&&(i=i.contents),nr.isNode(i))return i;if(nr.isPair(i)){let g=(d=(f=t.schema[nr.MAP]).createNode)==null?void 0:d.call(f,t.schema,null,t);return g.items.push(i),g}(i instanceof String||i instanceof Number||i instanceof Boolean||typeof BigInt!="undefined"&&i instanceof BigInt)&&(i=i.valueOf());let{aliasDuplicateObjects:r,onAnchor:n,onTagObj:s,schema:o,sourceObjects:a}=t,l;if(r&&i&&typeof i=="object"){if(l=a.get(i),l)return l.anchor||(l.anchor=n(i)),new RO.Alias(l.anchor);l={anchor:null,node:null},a.set(i,l)}e!=null&&e.startsWith("!!")&&(e=PO+e.slice(2));let c=MO(i,e,o.tags);if(!c){if(i&&typeof i.toJSON=="function"&&(i=i.toJSON()),!i||typeof i!="object"){let g=new h0.Scalar(i);return l&&(l.node=g),g}c=i instanceof Map?o[nr.MAP]:Symbol.iterator in Object(i)?o[nr.SEQ]:o[nr.MAP]}s&&(s(c),delete t.onTagObj);let u=c!=null&&c.createNode?c.createNode(t.schema,i,t):typeof((m=c==null?void 0:c.nodeClass)==null?void 0:m.from)=="function"?c.nodeClass.from(t.schema,i,t):new h0.Scalar(i);return e?u.tag=e:c.default||(u.tag=c.tag),l&&(l.node=u),u}p0.createNode=qO});var So=x(xo=>{"use strict";var FO=Tn(),ii=Se(),DO=bo();function qc(i,e,t){let r=t;for(let n=e.length-1;n>=0;--n){let s=e[n];if(typeof s=="number"&&Number.isInteger(s)&&s>=0){let o=[];o[s]=r,r=o}else r=new Map([[s,r]])}return FO.createNode(r,void 0,{aliasDuplicateObjects:!1,keepUndefined:!1,onAnchor:()=>{throw new Error("This should not happen, please report a bug.")},schema:i,sourceObjects:new Map})}var d0=i=>i==null||typeof i=="object"&&!!i[Symbol.iterator]().next().done,Fc=class extends DO.NodeBase{constructor(e,t){super(e),Object.defineProperty(this,"schema",{value:t,configurable:!0,enumerable:!1,writable:!0})}clone(e){let t=Object.create(Object.getPrototypeOf(this),Object.getOwnPropertyDescriptors(this));return e&&(t.schema=e),t.items=t.items.map(r=>ii.isNode(r)||ii.isPair(r)?r.clone(e):r),this.range&&(t.range=this.range.slice()),t}addIn(e,t){if(d0(e))this.add(t);else{let[r,...n]=e,s=this.get(r,!0);if(ii.isCollection(s))s.addIn(n,t);else if(s===void 0&&this.schema)this.set(r,qc(this.schema,n,t));else throw new Error(`Expected YAML collection at ${r}. Remaining path: ${n}`)}}deleteIn(e){let[t,...r]=e;if(r.length===0)return this.delete(t);let n=this.get(t,!0);if(ii.isCollection(n))return n.deleteIn(r);throw new Error(`Expected YAML collection at ${t}. Remaining path: ${r}`)}getIn(e,t){let[r,...n]=e,s=this.get(r,!0);return n.length===0?!t&&ii.isScalar(s)?s.value:s:ii.isCollection(s)?s.getIn(n,t):void 0}hasAllNullValues(e){return this.items.every(t=>{if(!ii.isPair(t))return!1;let r=t.value;return r==null||e&&ii.isScalar(r)&&r.value==null&&!r.commentBefore&&!r.comment&&!r.tag})}hasIn(e){let[t,...r]=e;if(r.length===0)return this.has(t);let n=this.get(t,!0);return ii.isCollection(n)?n.hasIn(r):!1}setIn(e,t){let[r,...n]=e;if(n.length===0)this.set(r,t);else{let s=this.get(r,!0);if(ii.isCollection(s))s.setIn(n,t);else if(s===void 0&&this.schema)this.set(r,qc(this.schema,n,t));else throw new Error(`Expected YAML collection at ${r}. Remaining path: ${n}`)}}};xo.Collection=Fc;xo.collectionFromPath=qc;xo.isEmptyPath=d0});var An=x(Eo=>{"use strict";var jO=i=>i.replace(/^(?!$)(?: $)?/gm,"#");function Dc(i,e){return/^\n+$/.test(i)?i.substring(1):e?i.replace(/^(?! *$)/gm,e):i}var UO=(i,e,t)=>i.endsWith(` +`)?Dc(t,e):t.includes(` +`)?` +`+Dc(t,e):(i.endsWith(" ")?"":" ")+t;Eo.indentComment=Dc;Eo.lineComment=UO;Eo.stringifyComment=jO});var g0=x(In=>{"use strict";var $O="flow",jc="block",Oo="quoted";function VO(i,e,t="flow",{indentAtStart:r,lineWidth:n=80,minContentWidth:s=20,onFold:o,onOverflow:a}={}){if(!n||n<0)return i;nn-Math.max(2,s)?c.push(0):f=n-r);let d,m,g=!1,y=-1,b=-1,w=-1;t===jc&&(y=m0(i,y,e.length),y!==-1&&(f=y+l));for(let k;k=i[y+=1];){if(t===Oo&&k==="\\"){switch(b=y,i[y+1]){case"x":y+=3;break;case"u":y+=5;break;case"U":y+=9;break;default:y+=1}w=y}if(k===` +`)t===jc&&(y=m0(i,y,e.length)),f=y+e.length+l,d=void 0;else{if(k===" "&&m&&m!==" "&&m!==` +`&&m!==" "){let O=i[y+1];O&&O!==" "&&O!==` +`&&O!==" "&&(d=y)}if(y>=f)if(d)c.push(d),f=d+l,d=void 0;else if(t===Oo){for(;m===" "||m===" ";)m=k,k=i[y+=1],g=!0;let O=y>w+1?y-2:b-1;if(u[O])return i;c.push(O),u[O]=!0,f=O+l,d=void 0}else g=!0}m=k}if(g&&a&&a(),c.length===0)return i;o&&o();let S=i.slice(0,c[0]);for(let k=0;k{"use strict";var ri=je(),Ai=g0(),Co=(i,e)=>({indentAtStart:e?i.indent.length:i.indentAtStart,lineWidth:i.options.lineWidth,minContentWidth:i.options.minContentWidth}),To=i=>/^(%|---|\.\.\.)/m.test(i);function HO(i,e,t){if(!e||e<0)return!1;let r=e-t,n=i.length;if(n<=r)return!1;for(let s=0,o=0;sr)return!0;if(o=s+1,n-o<=r)return!1}return!0}function Nn(i,e){let t=JSON.stringify(i);if(e.options.doubleQuotedAsJSON)return t;let{implicitKey:r}=e,n=e.options.doubleQuotedMinMultiLineLength,s=e.indent||(To(i)?" ":""),o="",a=0;for(let l=0,c=t[l];c;c=t[++l])if(c===" "&&t[l+1]==="\\"&&t[l+2]==="n"&&(o+=t.slice(a,l)+"\\ ",l+=1,a=l,c="\\"),c==="\\")switch(t[l+1]){case"u":{o+=t.slice(a,l);let u=t.substr(l+2,4);switch(u){case"0000":o+="\\0";break;case"0007":o+="\\a";break;case"000b":o+="\\v";break;case"001b":o+="\\e";break;case"0085":o+="\\N";break;case"00a0":o+="\\_";break;case"2028":o+="\\L";break;case"2029":o+="\\P";break;default:u.substr(0,2)==="00"?o+="\\x"+u.substr(2):o+=t.substr(l,6)}l+=5,a=l+1}break;case"n":if(r||t[l+2]==='"'||t.length +`;let f,d;for(d=t.length;d>0;--d){let R=t[d-1];if(R!==` +`&&R!==" "&&R!==" ")break}let m=t.substring(d),g=m.indexOf(` +`);g===-1?f="-":t===m||g!==m.length-1?(f="+",s&&s()):f="",m&&(t=t.slice(0,-m.length),m[m.length-1]===` +`&&(m=m.slice(0,-1)),m=m.replace($c,`$&${c}`));let y=!1,b,w=-1;for(b=0;b")+(y?c?"2":"1":"")+f;if(i&&(O+=" "+a(i.replace(/ ?[\r\n]+/g," ")),n&&n()),u)return t=t.replace(/\n+/g,`$&${c}`),`${O} +${c}${S}${t}${m}`;t=t.replace(/\n+/g,` +$&`).replace(/(?:^|\n)([\t ].*)(?:([\n\t ]*)\n(?![\n\t ]))?/g,"$1$2").replace(/\n+/g,`$&${c}`);let E=Ai.foldFlowLines(`${S}${t}${m}`,c,Ai.FOLD_BLOCK,Co(r,!0));return`${O} +${c}${E}`}function GO(i,e,t,r){let{type:n,value:s}=i,{actualString:o,implicitKey:a,indent:l,indentStep:c,inFlow:u}=e;if(a&&s.includes(` +`)||u&&/[[\]{},]/.test(s))return Vr(s,e);if(!s||/^[\n\t ,[\]{}#&*!|>'"%@`]|^[?-]$|^[?-][ \t]|[\n:][ \t]|[ \t]\n|[\n\t ]#|[\n\t :]$/.test(s))return a||u||!s.includes(` +`)?Vr(s,e):ko(i,e,t,r);if(!a&&!u&&n!==ri.Scalar.PLAIN&&s.includes(` +`))return ko(i,e,t,r);if(To(s)){if(l==="")return e.forceBlockIndent=!0,ko(i,e,t,r);if(a&&l===c)return Vr(s,e)}let f=s.replace(/\n+/g,`$& +${l}`);if(o){let d=y=>{var b;return y.default&&y.tag!=="tag:yaml.org,2002:str"&&((b=y.test)==null?void 0:b.test(f))},{compat:m,tags:g}=e.doc.schema;if(g.some(d)||m!=null&&m.some(d))return Vr(s,e)}return a?f:Ai.foldFlowLines(f,l,Ai.FOLD_FLOW,Co(e,!1))}function WO(i,e,t,r){let{implicitKey:n,inFlow:s}=e,o=typeof i.value=="string"?i:Object.assign({},i,{value:String(i.value)}),{type:a}=i;a!==ri.Scalar.QUOTE_DOUBLE&&/[\x00-\x08\x0b-\x1f\x7f-\x9f\u{D800}-\u{DFFF}]/u.test(o.value)&&(a=ri.Scalar.QUOTE_DOUBLE);let l=u=>{switch(u){case ri.Scalar.BLOCK_FOLDED:case ri.Scalar.BLOCK_LITERAL:return n||s?Vr(o.value,e):ko(o,e,t,r);case ri.Scalar.QUOTE_DOUBLE:return Nn(o.value,e);case ri.Scalar.QUOTE_SINGLE:return Uc(o.value,e);case ri.Scalar.PLAIN:return GO(o,e,t,r);default:return null}},c=l(a);if(c===null){let{defaultKeyType:u,defaultStringType:f}=e.options,d=n&&u||f;if(c=l(d),c===null)throw new Error(`Unsupported default string type ${d}`)}return c}v0.stringifyString=WO});var Ln=x(Vc=>{"use strict";var YO=yo(),Ii=Se(),KO=An(),zO=Bn();function JO(i,e){let t=Object.assign({blockQuote:!0,commentString:KO.stringifyComment,defaultKeyType:null,defaultStringType:"PLAIN",directives:null,doubleQuotedAsJSON:!1,doubleQuotedMinMultiLineLength:40,falseStr:"false",flowCollectionPadding:!0,indentSeq:!0,lineWidth:80,minContentWidth:20,nullStr:"null",simpleKeys:!1,singleQuote:null,trueStr:"true",verifyAliasOrder:!0},i.schema.toStringOptions,e),r;switch(t.collectionStyle){case"block":r=!1;break;case"flow":r=!0;break;default:r=null}return{anchors:new Set,doc:i,flowCollectionPadding:t.flowCollectionPadding?" ":"",indent:"",indentStep:typeof t.indent=="number"?" ".repeat(t.indent):" ",inFlow:r,options:t}}function ZO(i,e){var n,s,o,a;if(e.tag){let l=i.filter(c=>c.tag===e.tag);if(l.length>0)return(n=l.find(c=>c.format===e.format))!=null?n:l[0]}let t,r;if(Ii.isScalar(e)){r=e.value;let l=i.filter(c=>{var u;return(u=c.identify)==null?void 0:u.call(c,r)});if(l.length>1){let c=l.filter(u=>u.test);c.length>0&&(l=c)}t=(s=l.find(c=>c.format===e.format))!=null?s:l.find(c=>!c.format)}else r=e,t=i.find(l=>l.nodeClass&&r instanceof l.nodeClass);if(!t){let l=(a=(o=r==null?void 0:r.constructor)==null?void 0:o.name)!=null?a:typeof r;throw new Error(`Tag not resolved for ${l} value`)}return t}function QO(i,e,{anchors:t,doc:r}){if(!r.directives)return"";let n=[],s=(Ii.isScalar(i)||Ii.isCollection(i))&&i.anchor;s&&YO.anchorIsValid(s)&&(t.add(s),n.push(`&${s}`));let o=i.tag?i.tag:e.default?null:e.tag;return o&&n.push(r.directives.tagString(o)),n.join(" ")}function XO(i,e,t,r){var l,c;if(Ii.isPair(i))return i.toString(e,t,r);if(Ii.isAlias(i)){if(e.doc.directives)return i.toString(e);if((l=e.resolvedAliases)!=null&&l.has(i))throw new TypeError("Cannot stringify circular structure without alias nodes");e.resolvedAliases?e.resolvedAliases.add(i):e.resolvedAliases=new Set([i]),i=i.resolve(e.doc)}let n,s=Ii.isNode(i)?i:e.doc.createNode(i,{onTagObj:u=>n=u});n||(n=ZO(e.doc.schema.tags,s));let o=QO(s,n,e);o.length>0&&(e.indentAtStart=((c=e.indentAtStart)!=null?c:0)+o.length+1);let a=typeof n.stringify=="function"?n.stringify(s,e,t,r):Ii.isScalar(s)?zO.stringifyString(s,e,t,r):s.toString(e,t,r);return o?Ii.isScalar(s)||a[0]==="{"||a[0]==="["?`${o} ${a}`:`${o} +${e.indent}${a}`:a}Vc.createStringifyContext=JO;Vc.stringify=XO});var w0=x(_0=>{"use strict";var gi=Se(),y0=je(),b0=Ln(),Rn=An();function ek({key:i,value:e},t,r,n){var T,A;let{allNullValues:s,doc:o,indent:a,indentStep:l,options:{commentString:c,indentSeq:u,simpleKeys:f}}=t,d=gi.isNode(i)&&i.comment||null;if(f){if(d)throw new Error("With simple keys, key nodes cannot have comments");if(gi.isCollection(i)||!gi.isNode(i)&&typeof i=="object"){let C="With simple keys, collection cannot be used as a key value";throw new Error(C)}}let m=!f&&(!i||d&&e==null&&!t.inFlow||gi.isCollection(i)||(gi.isScalar(i)?i.type===y0.Scalar.BLOCK_FOLDED||i.type===y0.Scalar.BLOCK_LITERAL:typeof i=="object"));t=Object.assign({},t,{allNullValues:!1,implicitKey:!m&&(f||!s),indent:a+l});let g=!1,y=!1,b=b0.stringify(i,t,()=>g=!0,()=>y=!0);if(!m&&!t.inFlow&&b.length>1024){if(f)throw new Error("With simple keys, single line scalar must not span more than 1024 characters");m=!0}if(t.inFlow){if(s||e==null)return g&&r&&r(),b===""?"?":m?`? ${b}`:b}else if(s&&!f||e==null&&m)return b=`? ${b}`,d&&!g?b+=Rn.lineComment(b,t.indent,c(d)):y&&n&&n(),b;g&&(d=null),m?(d&&(b+=Rn.lineComment(b,t.indent,c(d))),b=`? ${b} +${a}:`):(b=`${b}:`,d&&(b+=Rn.lineComment(b,t.indent,c(d))));let w,S,k;gi.isNode(e)?(w=!!e.spaceBefore,S=e.commentBefore,k=e.comment):(w=!1,S=null,k=null,e&&typeof e=="object"&&(e=o.createNode(e))),t.implicitKey=!1,!m&&!d&&gi.isScalar(e)&&(t.indentAtStart=b.length+1),y=!1,!u&&l.length>=2&&!t.inFlow&&!m&&gi.isSeq(e)&&!e.flow&&!e.tag&&!e.anchor&&(t.indent=t.indent.substring(2));let O=!1,E=b0.stringify(e,t,()=>O=!0,()=>y=!0),R=" ";if(d||w||S){if(R=w?` +`:"",S){let C=c(S);R+=` +${Rn.indentComment(C,t.indent)}`}E===""&&!t.inFlow?R===` +`&&(R=` + +`):R+=` +${t.indent}`}else if(!m&&gi.isCollection(e)){let C=E[0],B=E.indexOf(` +`),P=B!==-1,U=(A=(T=t.inFlow)!=null?T:e.flow)!=null?A:e.items.length===0;if(P||!U){let F=!1;if(P&&(C==="&"||C==="!")){let H=E.indexOf(" ");C==="&"&&H!==-1&&H{"use strict";function tk(i,...e){i==="debug"&&console.log(...e)}function ik(i,e){(i==="debug"||i==="warn")&&(typeof process!="undefined"&&process.emitWarning?process.emitWarning(e):console.warn(e))}Hc.debug=tk;Hc.warn=ik});var Bo=x(No=>{"use strict";var Pn=Se(),x0=je(),Ao="<<",Io={identify:i=>i===Ao||typeof i=="symbol"&&i.description===Ao,default:"key",tag:"tag:yaml.org,2002:merge",test:/^<<$/,resolve:()=>Object.assign(new x0.Scalar(Symbol(Ao)),{addToJSMap:S0}),stringify:()=>Ao},rk=(i,e)=>(Io.identify(e)||Pn.isScalar(e)&&(!e.type||e.type===x0.Scalar.PLAIN)&&Io.identify(e.value))&&(i==null?void 0:i.doc.schema.tags.some(t=>t.tag===Io.tag&&t.default));function S0(i,e,t){if(t=i&&Pn.isAlias(t)?t.resolve(i.doc):t,Pn.isSeq(t))for(let r of t.items)Wc(i,e,r);else if(Array.isArray(t))for(let r of t)Wc(i,e,r);else Wc(i,e,t)}function Wc(i,e,t){let r=i&&Pn.isAlias(t)?t.resolve(i.doc):t;if(!Pn.isMap(r))throw new Error("Merge sources must be maps or map aliases");let n=r.toJSON(null,i,Map);for(let[s,o]of n)e instanceof Map?e.has(s)||e.set(s,o):e instanceof Set?e.add(s):Object.prototype.hasOwnProperty.call(e,s)||Object.defineProperty(e,s,{value:o,writable:!0,enumerable:!0,configurable:!0});return e}No.addMergeToJSMap=S0;No.isMergeKey=rk;No.merge=Io});var Kc=x(k0=>{"use strict";var nk=Gc(),E0=Bo(),sk=Ln(),O0=Se(),Yc=Ci();function ok(i,e,{key:t,value:r}){if(O0.isNode(t)&&t.addToJSMap)t.addToJSMap(i,e,r);else if(E0.isMergeKey(i,t))E0.addMergeToJSMap(i,e,r);else{let n=Yc.toJS(t,"",i);if(e instanceof Map)e.set(n,Yc.toJS(r,n,i));else if(e instanceof Set)e.add(n);else{let s=ak(t,n,i),o=Yc.toJS(r,s,i);s in e?Object.defineProperty(e,s,{value:o,writable:!0,enumerable:!0,configurable:!0}):e[s]=o}}return e}function ak(i,e,t){if(e===null)return"";if(typeof e!="object")return String(e);if(O0.isNode(i)&&(t!=null&&t.doc)){let r=sk.createStringifyContext(t.doc,{});r.anchors=new Set;for(let s of t.anchors.keys())r.anchors.add(s.anchor);r.inFlow=!0,r.inStringifyKey=!0;let n=i.toString(r);if(!t.mapKeyWarned){let s=JSON.stringify(n);s.length>40&&(s=s.substring(0,36)+'..."'),nk.warn(t.doc.options.logLevel,`Keys with collection values will be stringified due to JS Object restrictions: ${s}. Set mapAsMap: true to use object keys.`),t.mapKeyWarned=!0}return n}return JSON.stringify(e)}k0.addPairToJSMap=ok});var Ni=x(zc=>{"use strict";var C0=Tn(),lk=w0(),ck=Kc(),Lo=Se();function uk(i,e,t){let r=C0.createNode(i,void 0,t),n=C0.createNode(e,void 0,t);return new Ro(r,n)}var Ro=class i{constructor(e,t=null){Object.defineProperty(this,Lo.NODE_TYPE,{value:Lo.PAIR}),this.key=e,this.value=t}clone(e){let{key:t,value:r}=this;return Lo.isNode(t)&&(t=t.clone(e)),Lo.isNode(r)&&(r=r.clone(e)),new i(t,r)}toJSON(e,t){let r=t!=null&&t.mapAsMap?new Map:{};return ck.addPairToJSMap(t,r,this)}toString(e,t,r){return e!=null&&e.doc?lk.stringifyPair(this,e,t,r):JSON.stringify(this)}};zc.Pair=Ro;zc.createPair=uk});var Jc=x(A0=>{"use strict";var sr=Se(),T0=Ln(),Po=An();function fk(i,e,t){var s;return(((s=e.inFlow)!=null?s:i.flow)?pk:hk)(i,e,t)}function hk({comment:i,items:e},t,{blockItemPrefix:r,flowChars:n,itemIndent:s,onChompKeep:o,onComment:a}){let{indent:l,options:{commentString:c}}=t,u=Object.assign({},t,{indent:s,type:null}),f=!1,d=[];for(let g=0;gb=null,()=>f=!0);b&&(w+=Po.lineComment(w,s,c(b))),f&&b&&(f=!1),d.push(r+w)}let m;if(d.length===0)m=n.start+n.end;else{m=d[0];for(let g=1;gb=null);gu||w.includes(` +`))&&(c=!0),f.push(w),u=f.length}let{start:d,end:m}=t;if(f.length===0)return d+m;if(!c){let g=f.reduce((y,b)=>y+b.length+2,2);c=e.options.lineWidth>0&&g>e.options.lineWidth}if(c){let g=d;for(let y of f)g+=y?` +${s}${n}${y}`:` +`;return`${g} +${n}${m}`}else return`${d}${o}${f.join(" ")}${o}${m}`}function Mo({indent:i,options:{commentString:e}},t,r,n){if(r&&n&&(r=r.replace(/^\n+/,"")),r){let s=Po.indentComment(e(r),i);t.push(s.trimStart())}}A0.stringifyCollection=fk});var Li=x(Qc=>{"use strict";var dk=Jc(),mk=Kc(),gk=So(),Bi=Se(),qo=Ni(),vk=je();function Mn(i,e){let t=Bi.isScalar(e)?e.value:e;for(let r of i)if(Bi.isPair(r)&&(r.key===e||r.key===t||Bi.isScalar(r.key)&&r.key.value===t))return r}var Zc=class extends gk.Collection{static get tagName(){return"tag:yaml.org,2002:map"}constructor(e){super(Bi.MAP,e),this.items=[]}static from(e,t,r){let{keepUndefined:n,replacer:s}=r,o=new this(e),a=(l,c)=>{if(typeof s=="function")c=s.call(t,l,c);else if(Array.isArray(s)&&!s.includes(l))return;(c!==void 0||n)&&o.items.push(qo.createPair(l,c,r))};if(t instanceof Map)for(let[l,c]of t)a(l,c);else if(t&&typeof t=="object")for(let l of Object.keys(t))a(l,t[l]);return typeof e.sortMapEntries=="function"&&o.items.sort(e.sortMapEntries),o}add(e,t){var o;let r;Bi.isPair(e)?r=e:!e||typeof e!="object"||!("key"in e)?r=new qo.Pair(e,e==null?void 0:e.value):r=new qo.Pair(e.key,e.value);let n=Mn(this.items,r.key),s=(o=this.schema)==null?void 0:o.sortMapEntries;if(n){if(!t)throw new Error(`Key ${r.key} already set`);Bi.isScalar(n.value)&&vk.isScalarValue(r.value)?n.value.value=r.value:n.value=r.value}else if(s){let a=this.items.findIndex(l=>s(r,l)<0);a===-1?this.items.push(r):this.items.splice(a,0,r)}else this.items.push(r)}delete(e){let t=Mn(this.items,e);return t?this.items.splice(this.items.indexOf(t),1).length>0:!1}get(e,t){var s;let r=Mn(this.items,e),n=r==null?void 0:r.value;return(s=!t&&Bi.isScalar(n)?n.value:n)!=null?s:void 0}has(e){return!!Mn(this.items,e)}set(e,t){this.add(new qo.Pair(e,t),!0)}toJSON(e,t,r){let n=r?new r:t!=null&&t.mapAsMap?new Map:{};t!=null&&t.onCreate&&t.onCreate(n);for(let s of this.items)mk.addPairToJSMap(t,n,s);return n}toString(e,t,r){if(!e)return JSON.stringify(this);for(let n of this.items)if(!Bi.isPair(n))throw new Error(`Map items must all be pairs; found ${JSON.stringify(n)} instead`);return!e.allNullValues&&this.hasAllNullValues(!1)&&(e=Object.assign({},e,{allNullValues:!0})),dk.stringifyCollection(this,e,{blockItemPrefix:"",flowChars:{start:"{",end:"}"},itemIndent:e.indent||"",onChompKeep:r,onComment:t})}};Qc.YAMLMap=Zc;Qc.findPair=Mn});var Hr=x(N0=>{"use strict";var yk=Se(),I0=Li(),bk={collection:"map",default:!0,nodeClass:I0.YAMLMap,tag:"tag:yaml.org,2002:map",resolve(i,e){return yk.isMap(i)||e("Expected a mapping for this tag"),i},createNode:(i,e,t)=>I0.YAMLMap.from(i,e,t)};N0.map=bk});var Ri=x(B0=>{"use strict";var _k=Tn(),wk=Jc(),xk=So(),Do=Se(),Sk=je(),Ek=Ci(),Xc=class extends xk.Collection{static get tagName(){return"tag:yaml.org,2002:seq"}constructor(e){super(Do.SEQ,e),this.items=[]}add(e){this.items.push(e)}delete(e){let t=Fo(e);return typeof t!="number"?!1:this.items.splice(t,1).length>0}get(e,t){let r=Fo(e);if(typeof r!="number")return;let n=this.items[r];return!t&&Do.isScalar(n)?n.value:n}has(e){let t=Fo(e);return typeof t=="number"&&t=0?e:null}B0.YAMLSeq=Xc});var Gr=x(R0=>{"use strict";var Ok=Se(),L0=Ri(),kk={collection:"seq",default:!0,nodeClass:L0.YAMLSeq,tag:"tag:yaml.org,2002:seq",resolve(i,e){return Ok.isSeq(i)||e("Expected a sequence for this tag"),i},createNode:(i,e,t)=>L0.YAMLSeq.from(i,e,t)};R0.seq=kk});var qn=x(P0=>{"use strict";var Ck=Bn(),Tk={identify:i=>typeof i=="string",default:!0,tag:"tag:yaml.org,2002:str",resolve:i=>i,stringify(i,e,t,r){return e=Object.assign({actualString:!0},e),Ck.stringifyString(i,e,t,r)}};P0.string=Tk});var jo=x(F0=>{"use strict";var M0=je(),q0={identify:i=>i==null,createNode:()=>new M0.Scalar(null),default:!0,tag:"tag:yaml.org,2002:null",test:/^(?:~|[Nn]ull|NULL)?$/,resolve:()=>new M0.Scalar(null),stringify:({source:i},e)=>typeof i=="string"&&q0.test.test(i)?i:e.options.nullStr};F0.nullTag=q0});var eu=x(j0=>{"use strict";var Ak=je(),D0={identify:i=>typeof i=="boolean",default:!0,tag:"tag:yaml.org,2002:bool",test:/^(?:[Tt]rue|TRUE|[Ff]alse|FALSE)$/,resolve:i=>new Ak.Scalar(i[0]==="t"||i[0]==="T"),stringify({source:i,value:e},t){if(i&&D0.test.test(i)){let r=i[0]==="t"||i[0]==="T";if(e===r)return i}return e?t.options.trueStr:t.options.falseStr}};j0.boolTag=D0});var Wr=x(U0=>{"use strict";function Ik({format:i,minFractionDigits:e,tag:t,value:r}){if(typeof r=="bigint")return String(r);let n=typeof r=="number"?r:Number(r);if(!isFinite(n))return isNaN(n)?".nan":n<0?"-.inf":".inf";let s=JSON.stringify(r);if(!i&&e&&(!t||t==="tag:yaml.org,2002:float")&&/^\d/.test(s)){let o=s.indexOf(".");o<0&&(o=s.length,s+=".");let a=e-(s.length-o-1);for(;a-- >0;)s+="0"}return s}U0.stringifyNumber=Ik});var iu=x(Uo=>{"use strict";var Nk=je(),tu=Wr(),Bk={identify:i=>typeof i=="number",default:!0,tag:"tag:yaml.org,2002:float",test:/^(?:[-+]?\.(?:inf|Inf|INF)|\.nan|\.NaN|\.NAN)$/,resolve:i=>i.slice(-3).toLowerCase()==="nan"?NaN:i[0]==="-"?Number.NEGATIVE_INFINITY:Number.POSITIVE_INFINITY,stringify:tu.stringifyNumber},Lk={identify:i=>typeof i=="number",default:!0,tag:"tag:yaml.org,2002:float",format:"EXP",test:/^[-+]?(?:\.[0-9]+|[0-9]+(?:\.[0-9]*)?)[eE][-+]?[0-9]+$/,resolve:i=>parseFloat(i),stringify(i){let e=Number(i.value);return isFinite(e)?e.toExponential():tu.stringifyNumber(i)}},Rk={identify:i=>typeof i=="number",default:!0,tag:"tag:yaml.org,2002:float",test:/^[-+]?(?:\.[0-9]+|[0-9]+\.[0-9]*)$/,resolve(i){let e=new Nk.Scalar(parseFloat(i)),t=i.indexOf(".");return t!==-1&&i[i.length-1]==="0"&&(e.minFractionDigits=i.length-t-1),e},stringify:tu.stringifyNumber};Uo.float=Rk;Uo.floatExp=Lk;Uo.floatNaN=Bk});var nu=x(Vo=>{"use strict";var $0=Wr(),$o=i=>typeof i=="bigint"||Number.isInteger(i),ru=(i,e,t,{intAsBigInt:r})=>r?BigInt(i):parseInt(i.substring(e),t);function V0(i,e,t){let{value:r}=i;return $o(r)&&r>=0?t+r.toString(e):$0.stringifyNumber(i)}var Pk={identify:i=>$o(i)&&i>=0,default:!0,tag:"tag:yaml.org,2002:int",format:"OCT",test:/^0o[0-7]+$/,resolve:(i,e,t)=>ru(i,2,8,t),stringify:i=>V0(i,8,"0o")},Mk={identify:$o,default:!0,tag:"tag:yaml.org,2002:int",test:/^[-+]?[0-9]+$/,resolve:(i,e,t)=>ru(i,0,10,t),stringify:$0.stringifyNumber},qk={identify:i=>$o(i)&&i>=0,default:!0,tag:"tag:yaml.org,2002:int",format:"HEX",test:/^0x[0-9a-fA-F]+$/,resolve:(i,e,t)=>ru(i,2,16,t),stringify:i=>V0(i,16,"0x")};Vo.int=Mk;Vo.intHex=qk;Vo.intOct=Pk});var G0=x(H0=>{"use strict";var Fk=Hr(),Dk=jo(),jk=Gr(),Uk=qn(),$k=eu(),su=iu(),ou=nu(),Vk=[Fk.map,jk.seq,Uk.string,Dk.nullTag,$k.boolTag,ou.intOct,ou.int,ou.intHex,su.floatNaN,su.floatExp,su.float];H0.schema=Vk});var K0=x(Y0=>{"use strict";var Hk=je(),Gk=Hr(),Wk=Gr();function W0(i){return typeof i=="bigint"||Number.isInteger(i)}var Ho=({value:i})=>JSON.stringify(i),Yk=[{identify:i=>typeof i=="string",default:!0,tag:"tag:yaml.org,2002:str",resolve:i=>i,stringify:Ho},{identify:i=>i==null,createNode:()=>new Hk.Scalar(null),default:!0,tag:"tag:yaml.org,2002:null",test:/^null$/,resolve:()=>null,stringify:Ho},{identify:i=>typeof i=="boolean",default:!0,tag:"tag:yaml.org,2002:bool",test:/^true|false$/,resolve:i=>i==="true",stringify:Ho},{identify:W0,default:!0,tag:"tag:yaml.org,2002:int",test:/^-?(?:0|[1-9][0-9]*)$/,resolve:(i,e,{intAsBigInt:t})=>t?BigInt(i):parseInt(i,10),stringify:({value:i})=>W0(i)?i.toString():JSON.stringify(i)},{identify:i=>typeof i=="number",default:!0,tag:"tag:yaml.org,2002:float",test:/^-?(?:0|[1-9][0-9]*)(?:\.[0-9]*)?(?:[eE][-+]?[0-9]+)?$/,resolve:i=>parseFloat(i),stringify:Ho}],Kk={default:!0,tag:"",test:/^/,resolve(i,e){return e(`Unresolved plain scalar ${JSON.stringify(i)}`),i}},zk=[Gk.map,Wk.seq].concat(Yk,Kk);Y0.schema=zk});var lu=x(z0=>{"use strict";var au=je(),Jk=Bn(),Zk={identify:i=>i instanceof Uint8Array,default:!1,tag:"tag:yaml.org,2002:binary",resolve(i,e){if(typeof Buffer=="function")return Buffer.from(i,"base64");if(typeof atob=="function"){let t=atob(i.replace(/[\n\r]/g,"")),r=new Uint8Array(t.length);for(let n=0;n{"use strict";var Go=Se(),cu=Ni(),Qk=je(),Xk=Ri();function J0(i,e){var t;if(Go.isSeq(i))for(let r=0;r1&&e("Each pair must have its own sequence indicator");let s=n.items[0]||new cu.Pair(new Qk.Scalar(null));if(n.commentBefore&&(s.key.commentBefore=s.key.commentBefore?`${n.commentBefore} +${s.key.commentBefore}`:n.commentBefore),n.comment){let o=(t=s.value)!=null?t:s.key;o.comment=o.comment?`${n.comment} +${o.comment}`:n.comment}n=s}i.items[r]=Go.isPair(n)?n:new cu.Pair(n)}}else e("Expected a sequence for this tag");return i}function Z0(i,e,t){let{replacer:r}=t,n=new Xk.YAMLSeq(i);n.tag="tag:yaml.org,2002:pairs";let s=0;if(e&&Symbol.iterator in Object(e))for(let o of e){typeof r=="function"&&(o=r.call(e,String(s++),o));let a,l;if(Array.isArray(o))if(o.length===2)a=o[0],l=o[1];else throw new TypeError(`Expected [key, value] tuple: ${o}`);else if(o&&o instanceof Object){let c=Object.keys(o);if(c.length===1)a=c[0],l=o[a];else throw new TypeError(`Expected tuple with one key, not ${c.length} keys`)}else a=o;n.items.push(cu.createPair(a,l,t))}return n}var eC={collection:"seq",default:!1,tag:"tag:yaml.org,2002:pairs",resolve:J0,createNode:Z0};Wo.createPairs=Z0;Wo.pairs=eC;Wo.resolvePairs=J0});var hu=x(fu=>{"use strict";var Q0=Se(),uu=Ci(),Fn=Li(),tC=Ri(),X0=Yo(),or=class i extends tC.YAMLSeq{constructor(){super(),this.add=Fn.YAMLMap.prototype.add.bind(this),this.delete=Fn.YAMLMap.prototype.delete.bind(this),this.get=Fn.YAMLMap.prototype.get.bind(this),this.has=Fn.YAMLMap.prototype.has.bind(this),this.set=Fn.YAMLMap.prototype.set.bind(this),this.tag=i.tag}toJSON(e,t){if(!t)return super.toJSON(e);let r=new Map;t!=null&&t.onCreate&&t.onCreate(r);for(let n of this.items){let s,o;if(Q0.isPair(n)?(s=uu.toJS(n.key,"",t),o=uu.toJS(n.value,s,t)):s=uu.toJS(n,"",t),r.has(s))throw new Error("Ordered maps must not include duplicate keys");r.set(s,o)}return r}static from(e,t,r){let n=X0.createPairs(e,t,r),s=new this;return s.items=n.items,s}};or.tag="tag:yaml.org,2002:omap";var iC={collection:"seq",identify:i=>i instanceof Map,nodeClass:or,default:!1,tag:"tag:yaml.org,2002:omap",resolve(i,e){let t=X0.resolvePairs(i,e),r=[];for(let{key:n}of t.items)Q0.isScalar(n)&&(r.includes(n.value)?e(`Ordered maps must not include duplicate keys: ${n.value}`):r.push(n.value));return Object.assign(new or,t)},createNode:(i,e,t)=>or.from(i,e,t)};fu.YAMLOMap=or;fu.omap=iC});var nv=x(pu=>{"use strict";var ev=je();function tv({value:i,source:e},t){return e&&(i?iv:rv).test.test(e)?e:i?t.options.trueStr:t.options.falseStr}var iv={identify:i=>i===!0,default:!0,tag:"tag:yaml.org,2002:bool",test:/^(?:Y|y|[Yy]es|YES|[Tt]rue|TRUE|[Oo]n|ON)$/,resolve:()=>new ev.Scalar(!0),stringify:tv},rv={identify:i=>i===!1,default:!0,tag:"tag:yaml.org,2002:bool",test:/^(?:N|n|[Nn]o|NO|[Ff]alse|FALSE|[Oo]ff|OFF)$/,resolve:()=>new ev.Scalar(!1),stringify:tv};pu.falseTag=rv;pu.trueTag=iv});var sv=x(Ko=>{"use strict";var rC=je(),du=Wr(),nC={identify:i=>typeof i=="number",default:!0,tag:"tag:yaml.org,2002:float",test:/^(?:[-+]?\.(?:inf|Inf|INF)|\.nan|\.NaN|\.NAN)$/,resolve:i=>i.slice(-3).toLowerCase()==="nan"?NaN:i[0]==="-"?Number.NEGATIVE_INFINITY:Number.POSITIVE_INFINITY,stringify:du.stringifyNumber},sC={identify:i=>typeof i=="number",default:!0,tag:"tag:yaml.org,2002:float",format:"EXP",test:/^[-+]?(?:[0-9][0-9_]*)?(?:\.[0-9_]*)?[eE][-+]?[0-9]+$/,resolve:i=>parseFloat(i.replace(/_/g,"")),stringify(i){let e=Number(i.value);return isFinite(e)?e.toExponential():du.stringifyNumber(i)}},oC={identify:i=>typeof i=="number",default:!0,tag:"tag:yaml.org,2002:float",test:/^[-+]?(?:[0-9][0-9_]*)?\.[0-9_]*$/,resolve(i){let e=new rC.Scalar(parseFloat(i.replace(/_/g,""))),t=i.indexOf(".");if(t!==-1){let r=i.substring(t+1).replace(/_/g,"");r[r.length-1]==="0"&&(e.minFractionDigits=r.length)}return e},stringify:du.stringifyNumber};Ko.float=oC;Ko.floatExp=sC;Ko.floatNaN=nC});var av=x(jn=>{"use strict";var ov=Wr(),Dn=i=>typeof i=="bigint"||Number.isInteger(i);function zo(i,e,t,{intAsBigInt:r}){let n=i[0];if((n==="-"||n==="+")&&(e+=1),i=i.substring(e).replace(/_/g,""),r){switch(t){case 2:i=`0b${i}`;break;case 8:i=`0o${i}`;break;case 16:i=`0x${i}`;break}let o=BigInt(i);return n==="-"?BigInt(-1)*o:o}let s=parseInt(i,t);return n==="-"?-1*s:s}function mu(i,e,t){let{value:r}=i;if(Dn(r)){let n=r.toString(e);return r<0?"-"+t+n.substr(1):t+n}return ov.stringifyNumber(i)}var aC={identify:Dn,default:!0,tag:"tag:yaml.org,2002:int",format:"BIN",test:/^[-+]?0b[0-1_]+$/,resolve:(i,e,t)=>zo(i,2,2,t),stringify:i=>mu(i,2,"0b")},lC={identify:Dn,default:!0,tag:"tag:yaml.org,2002:int",format:"OCT",test:/^[-+]?0[0-7_]+$/,resolve:(i,e,t)=>zo(i,1,8,t),stringify:i=>mu(i,8,"0")},cC={identify:Dn,default:!0,tag:"tag:yaml.org,2002:int",test:/^[-+]?[0-9][0-9_]*$/,resolve:(i,e,t)=>zo(i,0,10,t),stringify:ov.stringifyNumber},uC={identify:Dn,default:!0,tag:"tag:yaml.org,2002:int",format:"HEX",test:/^[-+]?0x[0-9a-fA-F_]+$/,resolve:(i,e,t)=>zo(i,2,16,t),stringify:i=>mu(i,16,"0x")};jn.int=cC;jn.intBin=aC;jn.intHex=uC;jn.intOct=lC});var vu=x(gu=>{"use strict";var Qo=Se(),Jo=Ni(),Zo=Li(),ar=class i extends Zo.YAMLMap{constructor(e){super(e),this.tag=i.tag}add(e){let t;Qo.isPair(e)?t=e:e&&typeof e=="object"&&"key"in e&&"value"in e&&e.value===null?t=new Jo.Pair(e.key,null):t=new Jo.Pair(e,null),Zo.findPair(this.items,t.key)||this.items.push(t)}get(e,t){let r=Zo.findPair(this.items,e);return!t&&Qo.isPair(r)?Qo.isScalar(r.key)?r.key.value:r.key:r}set(e,t){if(typeof t!="boolean")throw new Error(`Expected boolean value for set(key, value) in a YAML set, not ${typeof t}`);let r=Zo.findPair(this.items,e);r&&!t?this.items.splice(this.items.indexOf(r),1):!r&&t&&this.items.push(new Jo.Pair(e))}toJSON(e,t){return super.toJSON(e,t,Set)}toString(e,t,r){if(!e)return JSON.stringify(this);if(this.hasAllNullValues(!0))return super.toString(Object.assign({},e,{allNullValues:!0}),t,r);throw new Error("Set items must all have null values")}static from(e,t,r){let{replacer:n}=r,s=new this(e);if(t&&Symbol.iterator in Object(t))for(let o of t)typeof n=="function"&&(o=n.call(t,o,o)),s.items.push(Jo.createPair(o,null,r));return s}};ar.tag="tag:yaml.org,2002:set";var fC={collection:"map",identify:i=>i instanceof Set,nodeClass:ar,default:!1,tag:"tag:yaml.org,2002:set",createNode:(i,e,t)=>ar.from(i,e,t),resolve(i,e){if(Qo.isMap(i)){if(i.hasAllNullValues(!0))return Object.assign(new ar,i);e("Set items must all have null values")}else e("Expected a mapping for this tag");return i}};gu.YAMLSet=ar;gu.set=fC});var bu=x(Xo=>{"use strict";var hC=Wr();function yu(i,e){let t=i[0],r=t==="-"||t==="+"?i.substring(1):i,n=o=>e?BigInt(o):Number(o),s=r.replace(/_/g,"").split(":").reduce((o,a)=>o*n(60)+n(a),n(0));return t==="-"?n(-1)*s:s}function lv(i){let{value:e}=i,t=o=>o;if(typeof e=="bigint")t=o=>BigInt(o);else if(isNaN(e)||!isFinite(e))return hC.stringifyNumber(i);let r="";e<0&&(r="-",e*=t(-1));let n=t(60),s=[e%n];return e<60?s.unshift(0):(e=(e-s[0])/n,s.unshift(e%n),e>=60&&(e=(e-s[0])/n,s.unshift(e))),r+s.map(o=>String(o).padStart(2,"0")).join(":").replace(/000000\d*$/,"")}var pC={identify:i=>typeof i=="bigint"||Number.isInteger(i),default:!0,tag:"tag:yaml.org,2002:int",format:"TIME",test:/^[-+]?[0-9][0-9_]*(?::[0-5]?[0-9])+$/,resolve:(i,e,{intAsBigInt:t})=>yu(i,t),stringify:lv},dC={identify:i=>typeof i=="number",default:!0,tag:"tag:yaml.org,2002:float",format:"TIME",test:/^[-+]?[0-9][0-9_]*(?::[0-5]?[0-9])+\.[0-9_]*$/,resolve:i=>yu(i,!1),stringify:lv},cv={identify:i=>i instanceof Date,default:!0,tag:"tag:yaml.org,2002:timestamp",test:RegExp("^([0-9]{4})-([0-9]{1,2})-([0-9]{1,2})(?:(?:t|T|[ \\t]+)([0-9]{1,2}):([0-9]{1,2}):([0-9]{1,2}(\\.[0-9]+)?)(?:[ \\t]*(Z|[-+][012]?[0-9](?::[0-9]{2})?))?)?$"),resolve(i){let e=i.match(cv.test);if(!e)throw new Error("!!timestamp expects a date, starting with yyyy-mm-dd");let[,t,r,n,s,o,a]=e.map(Number),l=e[7]?Number((e[7]+"00").substr(1,3)):0,c=Date.UTC(t,r-1,n,s||0,o||0,a||0,l),u=e[8];if(u&&u!=="Z"){let f=yu(u,!1);Math.abs(f)<30&&(f*=60),c-=6e4*f}return new Date(c)},stringify:({value:i})=>i.toISOString().replace(/((T00:00)?:00)?\.000Z$/,"")};Xo.floatTime=dC;Xo.intTime=pC;Xo.timestamp=cv});var hv=x(fv=>{"use strict";var mC=Hr(),gC=jo(),vC=Gr(),yC=qn(),bC=lu(),uv=nv(),_u=sv(),ea=av(),_C=Bo(),wC=hu(),xC=Yo(),SC=vu(),wu=bu(),EC=[mC.map,vC.seq,yC.string,gC.nullTag,uv.trueTag,uv.falseTag,ea.intBin,ea.intOct,ea.int,ea.intHex,_u.floatNaN,_u.floatExp,_u.float,bC.binary,_C.merge,wC.omap,xC.pairs,SC.set,wu.intTime,wu.floatTime,wu.timestamp];fv.schema=EC});var xv=x(Eu=>{"use strict";var gv=Hr(),OC=jo(),vv=Gr(),kC=qn(),CC=eu(),xu=iu(),Su=nu(),TC=G0(),AC=K0(),yv=lu(),Un=Bo(),bv=hu(),_v=Yo(),pv=hv(),wv=vu(),ta=bu(),dv=new Map([["core",TC.schema],["failsafe",[gv.map,vv.seq,kC.string]],["json",AC.schema],["yaml11",pv.schema],["yaml-1.1",pv.schema]]),mv={binary:yv.binary,bool:CC.boolTag,float:xu.float,floatExp:xu.floatExp,floatNaN:xu.floatNaN,floatTime:ta.floatTime,int:Su.int,intHex:Su.intHex,intOct:Su.intOct,intTime:ta.intTime,map:gv.map,merge:Un.merge,null:OC.nullTag,omap:bv.omap,pairs:_v.pairs,seq:vv.seq,set:wv.set,timestamp:ta.timestamp},IC={"tag:yaml.org,2002:binary":yv.binary,"tag:yaml.org,2002:merge":Un.merge,"tag:yaml.org,2002:omap":bv.omap,"tag:yaml.org,2002:pairs":_v.pairs,"tag:yaml.org,2002:set":wv.set,"tag:yaml.org,2002:timestamp":ta.timestamp};function NC(i,e,t){let r=dv.get(e);if(r&&!i)return t&&!r.includes(Un.merge)?r.concat(Un.merge):r.slice();let n=r;if(!n)if(Array.isArray(i))n=[];else{let s=Array.from(dv.keys()).filter(o=>o!=="yaml11").map(o=>JSON.stringify(o)).join(", ");throw new Error(`Unknown schema "${e}"; use one of ${s} or define customTags array`)}if(Array.isArray(i))for(let s of i)n=n.concat(s);else typeof i=="function"&&(n=i(n.slice()));return t&&(n=n.concat(Un.merge)),n.reduce((s,o)=>{let a=typeof o=="string"?mv[o]:o;if(!a){let l=JSON.stringify(o),c=Object.keys(mv).map(u=>JSON.stringify(u)).join(", ");throw new Error(`Unknown custom tag ${l}; use one of ${c}`)}return s.includes(a)||s.push(a),s},[])}Eu.coreKnownTags=IC;Eu.getTags=NC});var Cu=x(Sv=>{"use strict";var Ou=Se(),BC=Hr(),LC=Gr(),RC=qn(),ia=xv(),PC=(i,e)=>i.keye.key?1:0,ku=class i{constructor({compat:e,customTags:t,merge:r,resolveKnownTags:n,schema:s,sortMapEntries:o,toStringDefaults:a}){this.compat=Array.isArray(e)?ia.getTags(e,"compat"):e?ia.getTags(null,e):null,this.name=typeof s=="string"&&s||"core",this.knownTags=n?ia.coreKnownTags:{},this.tags=ia.getTags(t,this.name,r),this.toStringOptions=a!=null?a:null,Object.defineProperty(this,Ou.MAP,{value:BC.map}),Object.defineProperty(this,Ou.SCALAR,{value:RC.string}),Object.defineProperty(this,Ou.SEQ,{value:LC.seq}),this.sortMapEntries=typeof o=="function"?o:o===!0?PC:null}clone(){let e=Object.create(i.prototype,Object.getOwnPropertyDescriptors(this));return e.tags=this.tags.slice(),e}};Sv.Schema=ku});var Ov=x(Ev=>{"use strict";var MC=Se(),Tu=Ln(),$n=An();function qC(i,e){var l;let t=[],r=e.directives===!0;if(e.directives!==!1&&i.directives){let c=i.directives.toString(i);c?(t.push(c),r=!0):i.directives.docStart&&(r=!0)}r&&t.push("---");let n=Tu.createStringifyContext(i,e),{commentString:s}=n.options;if(i.commentBefore){t.length!==1&&t.unshift("");let c=s(i.commentBefore);t.unshift($n.indentComment(c,""))}let o=!1,a=null;if(i.contents){if(MC.isNode(i.contents)){if(i.contents.spaceBefore&&r&&t.push(""),i.contents.commentBefore){let f=s(i.contents.commentBefore);t.push($n.indentComment(f,""))}n.forceBlockIndent=!!i.comment,a=i.contents.comment}let c=a?void 0:()=>o=!0,u=Tu.stringify(i.contents,n,()=>a=null,c);a&&(u+=$n.lineComment(u,"",s(a))),(u[0]==="|"||u[0]===">")&&t[t.length-1]==="---"?t[t.length-1]=`--- ${u}`:t.push(u)}else t.push(Tu.stringify(i.contents,n));if((l=i.directives)!=null&&l.docEnd)if(i.comment){let c=s(i.comment);c.includes(` +`)?(t.push("..."),t.push($n.indentComment(c,""))):t.push(`... ${c}`)}else t.push("...");else{let c=i.comment;c&&o&&(c=c.replace(/^\n+/,"")),c&&((!o||a)&&t[t.length-1]!==""&&t.push(""),t.push($n.indentComment(s(c),"")))}return t.join(` +`)+` +`}Ev.stringifyDocument=qC});var Vn=x(kv=>{"use strict";var FC=Cn(),Yr=So(),qt=Se(),DC=Ni(),jC=Ci(),UC=Cu(),$C=Ov(),Au=yo(),VC=Lc(),HC=Tn(),Iu=Bc(),Nu=class i{constructor(e,t,r){this.commentBefore=null,this.comment=null,this.errors=[],this.warnings=[],Object.defineProperty(this,qt.NODE_TYPE,{value:qt.DOC});let n=null;typeof t=="function"||Array.isArray(t)?n=t:r===void 0&&t&&(r=t,t=void 0);let s=Object.assign({intAsBigInt:!1,keepSourceTokens:!1,logLevel:"warn",prettyErrors:!0,strict:!0,stringKeys:!1,uniqueKeys:!0,version:"1.2"},r);this.options=s;let{version:o}=s;r!=null&&r._directives?(this.directives=r._directives.atDocument(),this.directives.yaml.explicit&&(o=this.directives.yaml.version)):this.directives=new Iu.Directives({version:o}),this.setSchema(o,r),this.contents=e===void 0?null:this.createNode(e,n,r)}clone(){let e=Object.create(i.prototype,{[qt.NODE_TYPE]:{value:qt.DOC}});return e.commentBefore=this.commentBefore,e.comment=this.comment,e.errors=this.errors.slice(),e.warnings=this.warnings.slice(),e.options=Object.assign({},this.options),this.directives&&(e.directives=this.directives.clone()),e.schema=this.schema.clone(),e.contents=qt.isNode(this.contents)?this.contents.clone(e.schema):this.contents,this.range&&(e.range=this.range.slice()),e}add(e){Kr(this.contents)&&this.contents.add(e)}addIn(e,t){Kr(this.contents)&&this.contents.addIn(e,t)}createAlias(e,t){if(!e.anchor){let r=Au.anchorNames(this);e.anchor=!t||r.has(t)?Au.findNewAnchor(t||"a",r):t}return new FC.Alias(e.anchor)}createNode(e,t,r){let n;if(typeof t=="function")e=t.call({"":e},"",e),n=t;else if(Array.isArray(t)){let b=S=>typeof S=="number"||S instanceof String||S instanceof Number,w=t.filter(b).map(String);w.length>0&&(t=t.concat(w)),n=t}else r===void 0&&t&&(r=t,t=void 0);let{aliasDuplicateObjects:s,anchorPrefix:o,flow:a,keepUndefined:l,onTagObj:c,tag:u}=r!=null?r:{},{onAnchor:f,setAnchors:d,sourceObjects:m}=Au.createNodeAnchors(this,o||"a"),g={aliasDuplicateObjects:s!=null?s:!0,keepUndefined:l!=null?l:!1,onAnchor:f,onTagObj:c,replacer:n,schema:this.schema,sourceObjects:m},y=HC.createNode(e,u,g);return a&&qt.isCollection(y)&&(y.flow=!0),d(),y}createPair(e,t,r={}){let n=this.createNode(e,null,r),s=this.createNode(t,null,r);return new DC.Pair(n,s)}delete(e){return Kr(this.contents)?this.contents.delete(e):!1}deleteIn(e){return Yr.isEmptyPath(e)?this.contents==null?!1:(this.contents=null,!0):Kr(this.contents)?this.contents.deleteIn(e):!1}get(e,t){return qt.isCollection(this.contents)?this.contents.get(e,t):void 0}getIn(e,t){return Yr.isEmptyPath(e)?!t&&qt.isScalar(this.contents)?this.contents.value:this.contents:qt.isCollection(this.contents)?this.contents.getIn(e,t):void 0}has(e){return qt.isCollection(this.contents)?this.contents.has(e):!1}hasIn(e){return Yr.isEmptyPath(e)?this.contents!==void 0:qt.isCollection(this.contents)?this.contents.hasIn(e):!1}set(e,t){this.contents==null?this.contents=Yr.collectionFromPath(this.schema,[e],t):Kr(this.contents)&&this.contents.set(e,t)}setIn(e,t){Yr.isEmptyPath(e)?this.contents=t:this.contents==null?this.contents=Yr.collectionFromPath(this.schema,Array.from(e),t):Kr(this.contents)&&this.contents.setIn(e,t)}setSchema(e,t={}){typeof e=="number"&&(e=String(e));let r;switch(e){case"1.1":this.directives?this.directives.yaml.version="1.1":this.directives=new Iu.Directives({version:"1.1"}),r={resolveKnownTags:!1,schema:"yaml-1.1"};break;case"1.2":case"next":this.directives?this.directives.yaml.version=e:this.directives=new Iu.Directives({version:e}),r={resolveKnownTags:!0,schema:"core"};break;case null:this.directives&&delete this.directives,r=null;break;default:{let n=JSON.stringify(e);throw new Error(`Expected '1.1', '1.2' or null as first argument, but found: ${n}`)}}if(t.schema instanceof Object)this.schema=t.schema;else if(r)this.schema=new UC.Schema(Object.assign(r,t));else throw new Error("With a null YAML version, the { schema: Schema } option is required")}toJS({json:e,jsonArg:t,mapAsMap:r,maxAliasCount:n,onAnchor:s,reviver:o}={}){let a={anchors:new Map,doc:this,keep:!e,mapAsMap:r===!0,mapKeyWarned:!1,maxAliasCount:typeof n=="number"?n:100},l=jC.toJS(this.contents,t!=null?t:"",a);if(typeof s=="function")for(let{count:c,res:u}of a.anchors.values())s(u,c);return typeof o=="function"?VC.applyReviver(o,{"":l},"",l):l}toJSON(e,t){return this.toJS({json:!0,jsonArg:e,mapAsMap:!1,onAnchor:t})}toString(e={}){if(this.errors.length>0)throw new Error("Document with errors cannot be stringified");if("indent"in e&&(!Number.isInteger(e.indent)||Number(e.indent)<=0)){let t=JSON.stringify(e.indent);throw new Error(`"indent" option must be a positive integer, not ${t}`)}return $C.stringifyDocument(this,e)}};function Kr(i){if(qt.isCollection(i))return!0;throw new Error("Expected a YAML collection as document contents")}kv.Document=Nu});var Wn=x(Gn=>{"use strict";var Hn=class extends Error{constructor(e,t,r,n){super(),this.name=e,this.code=r,this.message=n,this.pos=t}},Bu=class extends Hn{constructor(e,t,r){super("YAMLParseError",e,t,r)}},Lu=class extends Hn{constructor(e,t,r){super("YAMLWarning",e,t,r)}},GC=(i,e)=>t=>{if(t.pos[0]===-1)return;t.linePos=t.pos.map(a=>e.linePos(a));let{line:r,col:n}=t.linePos[0];t.message+=` at line ${r}, column ${n}`;let s=n-1,o=i.substring(e.lineStarts[r-1],e.lineStarts[r]).replace(/[\n\r]+$/,"");if(s>=60&&o.length>80){let a=Math.min(s-39,o.length-79);o="\u2026"+o.substring(a),s-=a-1}if(o.length>80&&(o=o.substring(0,79)+"\u2026"),r>1&&/^ *$/.test(o.substring(0,s))){let a=i.substring(e.lineStarts[r-2],e.lineStarts[r-1]);a.length>80&&(a=a.substring(0,79)+`\u2026 +`),o=a+o}if(/[^ ]/.test(o)){let a=1,l=t.linePos[1];l&&l.line===r&&l.col>n&&(a=Math.max(1,Math.min(l.col-n,80-s)));let c=" ".repeat(s)+"^".repeat(a);t.message+=`: + +${o} +${c} +`}};Gn.YAMLError=Hn;Gn.YAMLParseError=Bu;Gn.YAMLWarning=Lu;Gn.prettifyError=GC});var Yn=x(Cv=>{"use strict";function WC(i,{flow:e,indicator:t,next:r,offset:n,onError:s,parentIndent:o,startOnNewline:a}){let l=!1,c=a,u=a,f="",d="",m=!1,g=!1,y=null,b=null,w=null,S=null,k=null,O=null,E=null;for(let A of i)switch(g&&(A.type!=="space"&&A.type!=="newline"&&A.type!=="comma"&&s(A.offset,"MISSING_CHAR","Tags and anchors must be separated from the next token by white space"),g=!1),y&&(c&&A.type!=="comment"&&A.type!=="newline"&&s(y,"TAB_AS_INDENT","Tabs are not allowed as indentation"),y=null),A.type){case"space":!e&&(t!=="doc-start"||(r==null?void 0:r.type)!=="flow-collection")&&A.source.includes(" ")&&(y=A),u=!0;break;case"comment":{u||s(A,"MISSING_CHAR","Comments must be separated from other tokens by white space characters");let C=A.source.substring(1)||" ";f?f+=d+C:f=C,d="",c=!1;break}case"newline":c?f?f+=A.source:l=!0:d+=A.source,c=!0,m=!0,(b||w)&&(S=A),u=!0;break;case"anchor":b&&s(A,"MULTIPLE_ANCHORS","A node can have at most one anchor"),A.source.endsWith(":")&&s(A.offset+A.source.length-1,"BAD_ALIAS","Anchor ending in : is ambiguous",!0),b=A,E===null&&(E=A.offset),c=!1,u=!1,g=!0;break;case"tag":{w&&s(A,"MULTIPLE_TAGS","A node can have at most one tag"),w=A,E===null&&(E=A.offset),c=!1,u=!1,g=!0;break}case t:(b||w)&&s(A,"BAD_PROP_ORDER",`Anchors and tags must be after the ${A.source} indicator`),O&&s(A,"UNEXPECTED_TOKEN",`Unexpected ${A.source} in ${e!=null?e:"collection"}`),O=A,c=t==="seq-item-ind"||t==="explicit-key-ind",u=!1;break;case"comma":if(e){k&&s(A,"UNEXPECTED_TOKEN",`Unexpected , in ${e}`),k=A,c=!1,u=!1;break}default:s(A,"UNEXPECTED_TOKEN",`Unexpected ${A.type} token`),c=!1,u=!1}let R=i[i.length-1],T=R?R.offset+R.source.length:n;return g&&r&&r.type!=="space"&&r.type!=="newline"&&r.type!=="comma"&&(r.type!=="scalar"||r.source!=="")&&s(r.offset,"MISSING_CHAR","Tags and anchors must be separated from the next token by white space"),y&&(c&&y.indent<=o||(r==null?void 0:r.type)==="block-map"||(r==null?void 0:r.type)==="block-seq")&&s(y,"TAB_AS_INDENT","Tabs are not allowed as indentation"),{comma:k,found:O,spaceBefore:l,comment:f,hasNewline:m,anchor:b,tag:w,newlineAfterProp:S,end:T,start:E!=null?E:T}}Cv.resolveProps=WC});var ra=x(Tv=>{"use strict";function Ru(i){if(!i)return null;switch(i.type){case"alias":case"scalar":case"double-quoted-scalar":case"single-quoted-scalar":if(i.source.includes(` +`))return!0;if(i.end){for(let e of i.end)if(e.type==="newline")return!0}return!1;case"flow-collection":for(let e of i.items){for(let t of e.start)if(t.type==="newline")return!0;if(e.sep){for(let t of e.sep)if(t.type==="newline")return!0}if(Ru(e.key)||Ru(e.value))return!0}return!1;default:return!0}}Tv.containsNewline=Ru});var Pu=x(Av=>{"use strict";var YC=ra();function KC(i,e,t){if((e==null?void 0:e.type)==="flow-collection"){let r=e.end[0];r.indent===i&&(r.source==="]"||r.source==="}")&&YC.containsNewline(e)&&t(r,"BAD_INDENT","Flow end indicator should be more indented than parent",!0)}}Av.flowIndentCheck=KC});var Mu=x(Nv=>{"use strict";var Iv=Se();function zC(i,e,t){let{uniqueKeys:r}=i.options;if(r===!1)return!1;let n=typeof r=="function"?r:(s,o)=>s===o||Iv.isScalar(s)&&Iv.isScalar(o)&&s.value===o.value;return e.some(s=>n(s.key,t))}Nv.mapIncludes=zC});var qv=x(Mv=>{"use strict";var Bv=Ni(),JC=Li(),Lv=Yn(),ZC=ra(),Rv=Pu(),QC=Mu(),Pv="All mapping items must start at the same column";function XC({composeNode:i,composeEmptyNode:e},t,r,n,s){var u,f;let o=(u=s==null?void 0:s.nodeClass)!=null?u:JC.YAMLMap,a=new o(t.schema);t.atRoot&&(t.atRoot=!1);let l=r.offset,c=null;for(let d of r.items){let{start:m,key:g,sep:y,value:b}=d,w=Lv.resolveProps(m,{indicator:"explicit-key-ind",next:g!=null?g:y==null?void 0:y[0],offset:l,onError:n,parentIndent:r.indent,startOnNewline:!0}),S=!w.found;if(S){if(g&&(g.type==="block-seq"?n(l,"BLOCK_AS_IMPLICIT_KEY","A block sequence may not be used as an implicit map key"):"indent"in g&&g.indent!==r.indent&&n(l,"BAD_INDENT",Pv)),!w.anchor&&!w.tag&&!y){c=w.end,w.comment&&(a.comment?a.comment+=` +`+w.comment:a.comment=w.comment);continue}(w.newlineAfterProp||ZC.containsNewline(g))&&n(g!=null?g:m[m.length-1],"MULTILINE_IMPLICIT_KEY","Implicit keys need to be on a single line")}else((f=w.found)==null?void 0:f.indent)!==r.indent&&n(l,"BAD_INDENT",Pv);t.atKey=!0;let k=w.end,O=g?i(t,g,w,n):e(t,k,m,null,w,n);t.schema.compat&&Rv.flowIndentCheck(r.indent,g,n),t.atKey=!1,QC.mapIncludes(t,a.items,O)&&n(k,"DUPLICATE_KEY","Map keys must be unique");let E=Lv.resolveProps(y!=null?y:[],{indicator:"map-value-ind",next:b,offset:O.range[2],onError:n,parentIndent:r.indent,startOnNewline:!g||g.type==="block-scalar"});if(l=E.end,E.found){S&&((b==null?void 0:b.type)==="block-map"&&!E.hasNewline&&n(l,"BLOCK_AS_IMPLICIT_KEY","Nested mappings are not allowed in compact mappings"),t.options.strict&&w.start{"use strict";var eT=Ri(),tT=Yn(),iT=Pu();function rT({composeNode:i,composeEmptyNode:e},t,r,n,s){var u;let o=(u=s==null?void 0:s.nodeClass)!=null?u:eT.YAMLSeq,a=new o(t.schema);t.atRoot&&(t.atRoot=!1),t.atKey&&(t.atKey=!1);let l=r.offset,c=null;for(let{start:f,value:d}of r.items){let m=tT.resolveProps(f,{indicator:"seq-item-ind",next:d,offset:l,onError:n,parentIndent:r.indent,startOnNewline:!0});if(!m.found)if(m.anchor||m.tag||d)d&&d.type==="block-seq"?n(m.end,"BAD_INDENT","All sequence items must start at the same column"):n(l,"MISSING_CHAR","Sequence item without - indicator");else{c=m.end,m.comment&&(a.comment=m.comment);continue}let g=d?i(t,d,m,n):e(t,m.end,f,null,m,n);t.schema.compat&&iT.flowIndentCheck(r.indent,d,n),l=g.range[2],a.items.push(g)}return a.range=[r.offset,l,c!=null?c:l],a}Fv.resolveBlockSeq=rT});var zr=x(jv=>{"use strict";function nT(i,e,t,r){let n="";if(i){let s=!1,o="";for(let a of i){let{source:l,type:c}=a;switch(c){case"space":s=!0;break;case"comment":{t&&!s&&r(a,"MISSING_CHAR","Comments must be separated from other tokens by white space characters");let u=l.substring(1)||" ";n?n+=o+u:n=u,o="";break}case"newline":n&&(o+=l),s=!0;break;default:r(a,"UNEXPECTED_TOKEN",`Unexpected ${c} at node end`)}e+=l.length}}return{comment:n,offset:e}}jv.resolveEnd=nT});var Hv=x(Vv=>{"use strict";var sT=Se(),oT=Ni(),Uv=Li(),aT=Ri(),lT=zr(),$v=Yn(),cT=ra(),uT=Mu(),qu="Block collections are not allowed within flow collections",Fu=i=>i&&(i.type==="block-map"||i.type==="block-seq");function fT({composeNode:i,composeEmptyNode:e},t,r,n,s){var b,w;let o=r.start.source==="{",a=o?"flow map":"flow sequence",l=(b=s==null?void 0:s.nodeClass)!=null?b:o?Uv.YAMLMap:aT.YAMLSeq,c=new l(t.schema);c.flow=!0;let u=t.atRoot;u&&(t.atRoot=!1),t.atKey&&(t.atKey=!1);let f=r.offset+r.start.source.length;for(let S=0;S0){let S=lT.resolveEnd(g,y,t.options.strict,n);S.comment&&(c.comment?c.comment+=` +`+S.comment:c.comment=S.comment),c.range=[r.offset,y,S.offset]}else c.range=[r.offset,y,y];return c}Vv.resolveFlowCollection=fT});var Wv=x(Gv=>{"use strict";var hT=Se(),pT=je(),dT=Li(),mT=Ri(),gT=qv(),vT=Dv(),yT=Hv();function Du(i,e,t,r,n,s){let o=t.type==="block-map"?gT.resolveBlockMap(i,e,t,r,s):t.type==="block-seq"?vT.resolveBlockSeq(i,e,t,r,s):yT.resolveFlowCollection(i,e,t,r,s),a=o.constructor;return n==="!"||n===a.tagName?(o.tag=a.tagName,o):(n&&(o.tag=n),o)}function bT(i,e,t,r,n){var d,m;let s=r.tag,o=s?e.directives.tagName(s.source,g=>n(s,"TAG_RESOLVE_FAILED",g)):null;if(t.type==="block-seq"){let{anchor:g,newlineAfterProp:y}=r,b=g&&s?g.offset>s.offset?g:s:g!=null?g:s;b&&(!y||y.offsetg.tag===o&&g.collection===a);if(!l){let g=e.schema.knownTags[o];if(g&&g.collection===a)e.schema.tags.push(Object.assign({},g,{default:!1})),l=g;else return g!=null&&g.collection?n(s,"BAD_COLLECTION_TYPE",`${g.tag} used for ${a} collection, but expects ${g.collection}`,!0):n(s,"TAG_RESOLVE_FAILED",`Unresolved tag: ${o}`,!0),Du(i,e,t,n,o)}let c=Du(i,e,t,n,o,l),u=(m=(d=l.resolve)==null?void 0:d.call(l,c,g=>n(s,"TAG_RESOLVE_FAILED",g),e.options))!=null?m:c,f=hT.isNode(u)?u:new pT.Scalar(u);return f.range=c.range,f.tag=o,l!=null&&l.format&&(f.format=l.format),f}Gv.composeCollection=bT});var Uu=x(Yv=>{"use strict";var ju=je();function _T(i,e,t){let r=e.offset,n=wT(e,i.options.strict,t);if(!n)return{value:"",type:null,comment:"",range:[r,r,r]};let s=n.mode===">"?ju.Scalar.BLOCK_FOLDED:ju.Scalar.BLOCK_LITERAL,o=e.source?xT(e.source):[],a=o.length;for(let y=o.length-1;y>=0;--y){let b=o[y][1];if(b===""||b==="\r")a=y;else break}if(a===0){let y=n.chomp==="+"&&o.length>0?` +`.repeat(Math.max(1,o.length-1)):"",b=r+n.length;return e.source&&(b+=e.source.length),{value:y,type:s,comment:n.comment,range:[r,b,b]}}let l=e.indent+n.indent,c=e.offset+n.length,u=0;for(let y=0;yl&&(l=b.length);else{b.length=a;--y)o[y][0].length>l&&(a=y+1);let f="",d="",m=!1;for(let y=0;yl||w[0]===" "?(d===" "?d=` +`:!m&&d===` +`&&(d=` + +`),f+=d+b.slice(l)+w,d=` +`,m=!0):w===""?d===` +`?f+=` +`:d=` +`:(f+=d+w,d=" ",m=!1)}switch(n.chomp){case"-":break;case"+":for(let y=a;y{"use strict";var $u=je(),ST=zr();function ET(i,e,t){let{offset:r,type:n,source:s,end:o}=i,a,l,c=(d,m,g)=>t(r+d,m,g);switch(n){case"scalar":a=$u.Scalar.PLAIN,l=OT(s,c);break;case"single-quoted-scalar":a=$u.Scalar.QUOTE_SINGLE,l=kT(s,c);break;case"double-quoted-scalar":a=$u.Scalar.QUOTE_DOUBLE,l=CT(s,c);break;default:return t(i,"UNEXPECTED_TOKEN",`Expected a flow scalar value, but found: ${n}`),{value:"",type:null,comment:"",range:[r,r+s.length,r+s.length]}}let u=r+s.length,f=ST.resolveEnd(o,u,e,t);return{value:l,type:a,comment:f.comment,range:[r,u,f.offset]}}function OT(i,e){let t="";switch(i[0]){case" ":t="a tab character";break;case",":t="flow indicator character ,";break;case"%":t="directive indicator character %";break;case"|":case">":{t=`block scalar indicator ${i[0]}`;break}case"@":case"`":{t=`reserved character ${i[0]}`;break}}return t&&e(0,"BAD_SCALAR_START",`Plain value cannot start with ${t}`),Kv(i)}function kT(i,e){return(i[i.length-1]!=="'"||i.length===1)&&e(i.length,"MISSING_CHAR","Missing closing 'quote"),Kv(i.slice(1,-1)).replace(/''/g,"'")}function Kv(i){var l;let e,t;try{e=new RegExp(`(.*?)(?s?i.slice(s,r+1):n)}else t+=n}return(i[i.length-1]!=='"'||i.length===1)&&e(i.length,"MISSING_CHAR",'Missing closing "quote'),t}function TT(i,e){let t="",r=i[e+1];for(;(r===" "||r===" "||r===` +`||r==="\r")&&!(r==="\r"&&i[e+2]!==` +`);)r===` +`&&(t+=` +`),e+=1,r=i[e+1];return t||(t=" "),{fold:t,offset:e}}var AT={0:"\0",a:"\x07",b:"\b",e:"\x1B",f:"\f",n:` +`,r:"\r",t:" ",v:"\v",N:"\x85",_:"\xA0",L:"\u2028",P:"\u2029"," ":" ",'"':'"',"/":"/","\\":"\\"," ":" "};function IT(i,e,t,r){let n=i.substr(e,t),o=n.length===t&&/^[0-9a-fA-F]+$/.test(n)?parseInt(n,16):NaN;if(isNaN(o)){let a=i.substr(e-2,t+2);return r(e-2,"BAD_DQ_ESCAPE",`Invalid escape sequence ${a}`),a}return String.fromCodePoint(o)}zv.resolveFlowScalar=ET});var Qv=x(Zv=>{"use strict";var lr=Se(),Jv=je(),NT=Uu(),BT=Vu();function LT(i,e,t,r){let{value:n,type:s,comment:o,range:a}=e.type==="block-scalar"?NT.resolveBlockScalar(i,e,r):BT.resolveFlowScalar(e,i.options.strict,r),l=t?i.directives.tagName(t.source,f=>r(t,"TAG_RESOLVE_FAILED",f)):null,c;i.options.stringKeys&&i.atKey?c=i.schema[lr.SCALAR]:l?c=RT(i.schema,n,l,t,r):e.type==="scalar"?c=PT(i,n,e,r):c=i.schema[lr.SCALAR];let u;try{let f=c.resolve(n,d=>r(t!=null?t:e,"TAG_RESOLVE_FAILED",d),i.options);u=lr.isScalar(f)?f:new Jv.Scalar(f)}catch(f){let d=f instanceof Error?f.message:String(f);r(t!=null?t:e,"TAG_RESOLVE_FAILED",d),u=new Jv.Scalar(n)}return u.range=a,u.source=n,s&&(u.type=s),l&&(u.tag=l),c.format&&(u.format=c.format),o&&(u.comment=o),u}function RT(i,e,t,r,n){var a;if(t==="!")return i[lr.SCALAR];let s=[];for(let l of i.tags)if(!l.collection&&l.tag===t)if(l.default&&l.test)s.push(l);else return l;for(let l of s)if((a=l.test)!=null&&a.test(e))return l;let o=i.knownTags[t];return o&&!o.collection?(i.tags.push(Object.assign({},o,{default:!1,test:void 0})),o):(n(r,"TAG_RESOLVE_FAILED",`Unresolved tag: ${t}`,t!=="tag:yaml.org,2002:str"),i[lr.SCALAR])}function PT({atKey:i,directives:e,schema:t},r,n,s){var a;let o=t.tags.find(l=>{var c;return(l.default===!0||i&&l.default==="key")&&((c=l.test)==null?void 0:c.test(r))})||t[lr.SCALAR];if(t.compat){let l=(a=t.compat.find(c=>{var u;return c.default&&((u=c.test)==null?void 0:u.test(r))}))!=null?a:t[lr.SCALAR];if(o.tag!==l.tag){let c=e.tagString(o.tag),u=e.tagString(l.tag),f=`Value may be parsed as either ${c} or ${u}`;s(n,"TAG_RESOLVE_FAILED",f,!0)}}return o}Zv.composeScalar=LT});var ey=x(Xv=>{"use strict";function MT(i,e,t){if(e){t===null&&(t=e.length);for(let r=t-1;r>=0;--r){let n=e[r];switch(n.type){case"space":case"comment":case"newline":i-=n.source.length;continue}for(n=e[++r];(n==null?void 0:n.type)==="space";)i+=n.source.length,n=e[++r];break}}return i}Xv.emptyScalarPosition=MT});var ry=x(Gu=>{"use strict";var qT=Cn(),FT=Se(),DT=Wv(),ty=Qv(),jT=zr(),UT=ey(),$T={composeNode:iy,composeEmptyNode:Hu};function iy(i,e,t,r){let n=i.atKey,{spaceBefore:s,comment:o,anchor:a,tag:l}=t,c,u=!0;switch(e.type){case"alias":c=VT(i,e,r),(a||l)&&r(e,"ALIAS_PROPS","An alias node must not specify any properties");break;case"scalar":case"single-quoted-scalar":case"double-quoted-scalar":case"block-scalar":c=ty.composeScalar(i,e,l,r),a&&(c.anchor=a.source.substring(1));break;case"block-map":case"block-seq":case"flow-collection":c=DT.composeCollection($T,i,e,t,r),a&&(c.anchor=a.source.substring(1));break;default:{let f=e.type==="error"?e.message:`Unsupported token (type: ${e.type})`;r(e,"UNEXPECTED_TOKEN",f),c=Hu(i,e.offset,void 0,null,t,r),u=!1}}return a&&c.anchor===""&&r(a,"BAD_ALIAS","Anchor cannot be an empty string"),n&&i.options.stringKeys&&(!FT.isScalar(c)||typeof c.value!="string"||c.tag&&c.tag!=="tag:yaml.org,2002:str")&&r(l!=null?l:e,"NON_STRING_KEY","With stringKeys, all keys must be strings"),s&&(c.spaceBefore=!0),o&&(e.type==="scalar"&&e.source===""?c.comment=o:c.commentBefore=o),i.options.keepSourceTokens&&u&&(c.srcToken=e),c}function Hu(i,e,t,r,{spaceBefore:n,comment:s,anchor:o,tag:a,end:l},c){let u={type:"scalar",offset:UT.emptyScalarPosition(e,t,r),indent:-1,source:""},f=ty.composeScalar(i,u,a,c);return o&&(f.anchor=o.source.substring(1),f.anchor===""&&c(o,"BAD_ALIAS","Anchor cannot be an empty string")),n&&(f.spaceBefore=!0),s&&(f.comment=s,f.range[2]=l),f}function VT({options:i},{offset:e,source:t,end:r},n){let s=new qT.Alias(t.substring(1));s.source===""&&n(e,"BAD_ALIAS","Alias cannot be an empty string"),s.source.endsWith(":")&&n(e+t.length-1,"BAD_ALIAS","Alias ending in : is ambiguous",!0);let o=e+t.length,a=jT.resolveEnd(r,o,i.strict,n);return s.range=[e,o,a.offset],a.comment&&(s.comment=a.comment),s}Gu.composeEmptyNode=Hu;Gu.composeNode=iy});var oy=x(sy=>{"use strict";var HT=Vn(),ny=ry(),GT=zr(),WT=Yn();function YT(i,e,{offset:t,start:r,value:n,end:s},o){let a=Object.assign({_directives:e},i),l=new HT.Document(void 0,a),c={atKey:!1,atRoot:!0,directives:l.directives,options:l.options,schema:l.schema},u=WT.resolveProps(r,{indicator:"doc-start",next:n!=null?n:s==null?void 0:s[0],offset:t,onError:o,parentIndent:0,startOnNewline:!0});u.found&&(l.directives.docStart=!0,n&&(n.type==="block-map"||n.type==="block-seq")&&!u.hasNewline&&o(u.end,"MISSING_CHAR","Block collection cannot start on same line with directives-end marker")),l.contents=n?ny.composeNode(c,n,u,o):ny.composeEmptyNode(c,u.end,r,null,u,o);let f=l.contents.range[2],d=GT.resolveEnd(s,f,!1,o);return d.comment&&(l.comment=d.comment),l.range=[t,f,d.offset],l}sy.composeDoc=YT});var Yu=x(cy=>{"use strict";var KT=Bc(),zT=Vn(),Kn=Wn(),ay=Se(),JT=oy(),ZT=zr();function zn(i){if(typeof i=="number")return[i,i+1];if(Array.isArray(i))return i.length===2?i:[i[0],i[1]];let{offset:e,source:t}=i;return[e,e+(typeof t=="string"?t.length:1)]}function ly(i){var n;let e="",t=!1,r=!1;for(let s=0;s{let o=zn(t);s?this.warnings.push(new Kn.YAMLWarning(o,r,n)):this.errors.push(new Kn.YAMLParseError(o,r,n))},this.directives=new KT.Directives({version:e.version||"1.2"}),this.options=e}decorate(e,t){let{comment:r,afterEmptyLine:n}=ly(this.prelude);if(r){let s=e.contents;if(t)e.comment=e.comment?`${e.comment} +${r}`:r;else if(n||e.directives.docStart||!s)e.commentBefore=r;else if(ay.isCollection(s)&&!s.flow&&s.items.length>0){let o=s.items[0];ay.isPair(o)&&(o=o.key);let a=o.commentBefore;o.commentBefore=a?`${r} +${a}`:r}else{let o=s.commentBefore;s.commentBefore=o?`${r} +${o}`:r}}t?(Array.prototype.push.apply(e.errors,this.errors),Array.prototype.push.apply(e.warnings,this.warnings)):(e.errors=this.errors,e.warnings=this.warnings),this.prelude=[],this.errors=[],this.warnings=[]}streamInfo(){return{comment:ly(this.prelude).comment,directives:this.directives,errors:this.errors,warnings:this.warnings}}*compose(e,t=!1,r=-1){for(let n of e)yield*this.next(n);yield*this.end(t,r)}*next(e){switch(process.env.LOG_STREAM&&console.dir(e,{depth:null}),e.type){case"directive":this.directives.add(e.source,(t,r,n)=>{let s=zn(e);s[0]+=t,this.onError(s,"BAD_DIRECTIVE",r,n)}),this.prelude.push(e.source),this.atDirectives=!0;break;case"document":{let t=JT.composeDoc(this.options,this.directives,e,this.onError);this.atDirectives&&!t.directives.docStart&&this.onError(e,"MISSING_CHAR","Missing directives-end/doc-start indicator line"),this.decorate(t,!1),this.doc&&(yield this.doc),this.doc=t,this.atDirectives=!1;break}case"byte-order-mark":case"space":break;case"comment":case"newline":this.prelude.push(e.source);break;case"error":{let t=e.source?`${e.message}: ${JSON.stringify(e.source)}`:e.message,r=new Kn.YAMLParseError(zn(e),"UNEXPECTED_TOKEN",t);this.atDirectives||!this.doc?this.errors.push(r):this.doc.errors.push(r);break}case"doc-end":{if(!this.doc){let r="Unexpected doc-end without preceding document";this.errors.push(new Kn.YAMLParseError(zn(e),"UNEXPECTED_TOKEN",r));break}this.doc.directives.docEnd=!0;let t=ZT.resolveEnd(e.end,e.offset+e.source.length,this.doc.options.strict,this.onError);if(this.decorate(this.doc,!0),t.comment){let r=this.doc.comment;this.doc.comment=r?`${r} +${t.comment}`:t.comment}this.doc.range[2]=t.offset;break}default:this.errors.push(new Kn.YAMLParseError(zn(e),"UNEXPECTED_TOKEN",`Unsupported token ${e.type}`))}}*end(e=!1,t=-1){if(this.doc)this.decorate(this.doc,!0),yield this.doc,this.doc=null;else if(e){let r=Object.assign({_directives:this.directives},this.options),n=new zT.Document(void 0,r);this.atDirectives&&this.onError(t,"MISSING_CHAR","Missing directives-end indicator line"),n.range=[0,t,t],this.decorate(n,!1),yield n}}};cy.Composer=Wu});var hy=x(na=>{"use strict";var QT=Uu(),XT=Vu(),eA=Wn(),uy=Bn();function tA(i,e=!0,t){if(i){let r=(n,s,o)=>{let a=typeof n=="number"?n:Array.isArray(n)?n[0]:n.offset;if(t)t(a,s,o);else throw new eA.YAMLParseError([a,a+1],s,o)};switch(i.type){case"scalar":case"single-quoted-scalar":case"double-quoted-scalar":return XT.resolveFlowScalar(i,e,r);case"block-scalar":return QT.resolveBlockScalar({options:{strict:e}},i,r)}}return null}function iA(i,e){var c;let{implicitKey:t=!1,indent:r,inFlow:n=!1,offset:s=-1,type:o="PLAIN"}=e,a=uy.stringifyString({type:o,value:i},{implicitKey:t,indent:r>0?" ".repeat(r):"",inFlow:n,options:{blockQuote:!0,lineWidth:-1}}),l=(c=e.end)!=null?c:[{type:"newline",offset:-1,indent:r,source:` +`}];switch(a[0]){case"|":case">":{let u=a.indexOf(` +`),f=a.substring(0,u),d=a.substring(u+1)+` +`,m=[{type:"block-scalar-header",offset:s,indent:r,source:f}];return fy(m,l)||m.push({type:"newline",offset:-1,indent:r,source:` +`}),{type:"block-scalar",offset:s,indent:r,props:m,source:d}}case'"':return{type:"double-quoted-scalar",offset:s,indent:r,source:a,end:l};case"'":return{type:"single-quoted-scalar",offset:s,indent:r,source:a,end:l};default:return{type:"scalar",offset:s,indent:r,source:a,end:l}}}function rA(i,e,t={}){let{afterKey:r=!1,implicitKey:n=!1,inFlow:s=!1,type:o}=t,a="indent"in i?i.indent:null;if(r&&typeof a=="number"&&(a+=2),!o)switch(i.type){case"single-quoted-scalar":o="QUOTE_SINGLE";break;case"double-quoted-scalar":o="QUOTE_DOUBLE";break;case"block-scalar":{let c=i.props[0];if(c.type!=="block-scalar-header")throw new Error("Invalid block scalar header");o=c.source[0]===">"?"BLOCK_FOLDED":"BLOCK_LITERAL";break}default:o="PLAIN"}let l=uy.stringifyString({type:o,value:e},{implicitKey:n||a===null,indent:a!==null&&a>0?" ".repeat(a):"",inFlow:s,options:{blockQuote:!0,lineWidth:-1}});switch(l[0]){case"|":case">":nA(i,l);break;case'"':Ku(i,l,"double-quoted-scalar");break;case"'":Ku(i,l,"single-quoted-scalar");break;default:Ku(i,l,"scalar")}}function nA(i,e){let t=e.indexOf(` +`),r=e.substring(0,t),n=e.substring(t+1)+` +`;if(i.type==="block-scalar"){let s=i.props[0];if(s.type!=="block-scalar-header")throw new Error("Invalid block scalar header");s.source=r,i.source=n}else{let{offset:s}=i,o="indent"in i?i.indent:-1,a=[{type:"block-scalar-header",offset:s,indent:o,source:r}];fy(a,"end"in i?i.end:void 0)||a.push({type:"newline",offset:-1,indent:o,source:` +`});for(let l of Object.keys(i))l!=="type"&&l!=="offset"&&delete i[l];Object.assign(i,{type:"block-scalar",indent:o,props:a,source:n})}}function fy(i,e){if(e)for(let t of e)switch(t.type){case"space":case"comment":i.push(t);break;case"newline":return i.push(t),!0}return!1}function Ku(i,e,t){switch(i.type){case"scalar":case"double-quoted-scalar":case"single-quoted-scalar":i.type=t,i.source=e;break;case"block-scalar":{let r=i.props.slice(1),n=e.length;i.props[0].type==="block-scalar-header"&&(n-=i.props[0].source.length);for(let s of r)s.offset+=n;delete i.props,Object.assign(i,{type:t,source:e,end:r});break}case"block-map":case"block-seq":{let n={type:"newline",offset:i.offset+e.length,indent:i.indent,source:` +`};delete i.items,Object.assign(i,{type:t,source:e,end:[n]});break}default:{let r="indent"in i?i.indent:-1,n="end"in i&&Array.isArray(i.end)?i.end.filter(s=>s.type==="space"||s.type==="comment"||s.type==="newline"):[];for(let s of Object.keys(i))s!=="type"&&s!=="offset"&&delete i[s];Object.assign(i,{type:t,indent:r,source:e,end:n})}}}na.createScalarToken=iA;na.resolveAsScalar=tA;na.setScalarValue=rA});var dy=x(py=>{"use strict";var sA=i=>"type"in i?oa(i):sa(i);function oa(i){switch(i.type){case"block-scalar":{let e="";for(let t of i.props)e+=oa(t);return e+i.source}case"block-map":case"block-seq":{let e="";for(let t of i.items)e+=sa(t);return e}case"flow-collection":{let e=i.start.source;for(let t of i.items)e+=sa(t);for(let t of i.end)e+=t.source;return e}case"document":{let e=sa(i);if(i.end)for(let t of i.end)e+=t.source;return e}default:{let e=i.source;if("end"in i&&i.end)for(let t of i.end)e+=t.source;return e}}}function sa({start:i,key:e,sep:t,value:r}){let n="";for(let s of i)n+=s.source;if(e&&(n+=oa(e)),t)for(let s of t)n+=s.source;return r&&(n+=oa(r)),n}py.stringify=sA});var yy=x(vy=>{"use strict";var zu=Symbol("break visit"),oA=Symbol("skip children"),my=Symbol("remove item");function cr(i,e){"type"in i&&i.type==="document"&&(i={start:i.start,value:i.value}),gy(Object.freeze([]),i,e)}cr.BREAK=zu;cr.SKIP=oA;cr.REMOVE=my;cr.itemAtPath=(i,e)=>{let t=i;for(let[r,n]of e){let s=t==null?void 0:t[r];if(s&&"items"in s)t=s.items[n];else return}return t};cr.parentCollection=(i,e)=>{let t=cr.itemAtPath(i,e.slice(0,-1)),r=e[e.length-1][0],n=t==null?void 0:t[r];if(n&&"items"in n)return n;throw new Error("Parent collection not found")};function gy(i,e,t){let r=t(e,i);if(typeof r=="symbol")return r;for(let n of["key","value"]){let s=e[n];if(s&&"items"in s){for(let o=0;o{"use strict";var Ju=hy(),aA=dy(),lA=yy(),Zu="\uFEFF",Qu="",Xu="",ef="",cA=i=>!!i&&"items"in i,uA=i=>!!i&&(i.type==="scalar"||i.type==="single-quoted-scalar"||i.type==="double-quoted-scalar"||i.type==="block-scalar");function fA(i){switch(i){case Zu:return"";case Qu:return"";case Xu:return"";case ef:return"";default:return JSON.stringify(i)}}function hA(i){switch(i){case Zu:return"byte-order-mark";case Qu:return"doc-mode";case Xu:return"flow-error-end";case ef:return"scalar";case"---":return"doc-start";case"...":return"doc-end";case"":case` +`:case`\r +`:return"newline";case"-":return"seq-item-ind";case"?":return"explicit-key-ind";case":":return"map-value-ind";case"{":return"flow-map-start";case"}":return"flow-map-end";case"[":return"flow-seq-start";case"]":return"flow-seq-end";case",":return"comma"}switch(i[0]){case" ":case" ":return"space";case"#":return"comment";case"%":return"directive-line";case"*":return"alias";case"&":return"anchor";case"!":return"tag";case"'":return"single-quoted-scalar";case'"':return"double-quoted-scalar";case"|":case">":return"block-scalar-header"}return null}yt.createScalarToken=Ju.createScalarToken;yt.resolveAsScalar=Ju.resolveAsScalar;yt.setScalarValue=Ju.setScalarValue;yt.stringify=aA.stringify;yt.visit=lA.visit;yt.BOM=Zu;yt.DOCUMENT=Qu;yt.FLOW_END=Xu;yt.SCALAR=ef;yt.isCollection=cA;yt.isScalar=uA;yt.prettyToken=fA;yt.tokenType=hA});var nf=x(_y=>{"use strict";var Jn=aa();function Wt(i){switch(i){case void 0:case" ":case` +`:case"\r":case" ":return!0;default:return!1}}var by=new Set("0123456789ABCDEFabcdef"),pA=new Set("0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-#;/?:@&=+$_.!~*'()"),la=new Set(",[]{}"),dA=new Set(` ,[]{} +\r `),tf=i=>!i||dA.has(i),rf=class{constructor(){this.atEnd=!1,this.blockScalarIndent=-1,this.blockScalarKeep=!1,this.buffer="",this.flowKey=!1,this.flowLevel=0,this.indentNext=0,this.indentValue=0,this.lineEndPos=null,this.next=null,this.pos=0}*lex(e,t=!1){var n;if(e){if(typeof e!="string")throw TypeError("source is not a string");this.buffer=this.buffer?this.buffer+e:e,this.lineEndPos=null}this.atEnd=!t;let r=(n=this.next)!=null?n:"stream";for(;r&&(t||this.hasChars(1));)r=yield*this.parseNext(r)}atLineEnd(){let e=this.pos,t=this.buffer[e];for(;t===" "||t===" ";)t=this.buffer[++e];return!t||t==="#"||t===` +`?!0:t==="\r"?this.buffer[e+1]===` +`:!1}charAt(e){return this.buffer[this.pos+e]}continueScalar(e){let t=this.buffer[e];if(this.indentNext>0){let r=0;for(;t===" ";)t=this.buffer[++r+e];if(t==="\r"){let n=this.buffer[r+e+1];if(n===` +`||!n&&!this.atEnd)return e+r+1}return t===` +`||r>=this.indentNext||!t&&!this.atEnd?e+r:-1}if(t==="-"||t==="."){let r=this.buffer.substr(e,3);if((r==="---"||r==="...")&&Wt(this.buffer[e+3]))return-1}return e}getLine(){let e=this.lineEndPos;return(typeof e!="number"||e!==-1&&ethis.indentValue&&!Wt(this.charAt(1))&&(this.indentNext=this.indentValue),yield*this.parseBlockStart()}*parseBlockStart(){let[e,t]=this.peek(2);if(!t&&!this.atEnd)return this.setNext("block-start");if((e==="-"||e==="?"||e===":")&&Wt(t)){let r=(yield*this.pushCount(1))+(yield*this.pushSpaces(!0));return this.indentNext=this.indentValue+1,this.indentValue+=r,yield*this.parseBlockStart()}return"doc"}*parseDocument(){yield*this.pushSpaces(!0);let e=this.getLine();if(e===null)return this.setNext("doc");let t=yield*this.pushIndicators();switch(e[t]){case"#":yield*this.pushCount(e.length-t);case void 0:return yield*this.pushNewline(),yield*this.parseLineStart();case"{":case"[":return yield*this.pushCount(1),this.flowKey=!1,this.flowLevel=1,"flow";case"}":case"]":return yield*this.pushCount(1),"doc";case"*":return yield*this.pushUntil(tf),"doc";case'"':case"'":return yield*this.parseQuotedScalar();case"|":case">":return t+=yield*this.parseBlockScalarHeader(),t+=yield*this.pushSpaces(!0),yield*this.pushCount(e.length-t),yield*this.pushNewline(),yield*this.parseBlockScalar();default:return yield*this.parsePlainScalar()}}*parseFlowCollection(){let e,t,r=-1;do e=yield*this.pushNewline(),e>0?(t=yield*this.pushSpaces(!1),this.indentValue=r=t):t=0,t+=yield*this.pushSpaces(!0);while(e+t>0);let n=this.getLine();if(n===null)return this.setNext("flow");if((r!==-1&&r"0"&&t<="9")this.blockScalarIndent=Number(t)-1;else if(t!=="-")break}return yield*this.pushUntil(t=>Wt(t)||t==="#")}*parseBlockScalar(){let e=this.pos-1,t=0,r;e:for(let s=this.pos;r=this.buffer[s];++s)switch(r){case" ":t+=1;break;case` +`:e=s,t=0;break;case"\r":{let o=this.buffer[s+1];if(!o&&!this.atEnd)return this.setNext("block-scalar");if(o===` +`)break}default:break e}if(!r&&!this.atEnd)return this.setNext("block-scalar");if(t>=this.indentNext){this.blockScalarIndent===-1?this.indentNext=t:this.indentNext=this.blockScalarIndent+(this.indentNext===0?1:this.indentNext);do{let s=this.continueScalar(e+1);if(s===-1)break;e=this.buffer.indexOf(` +`,s)}while(e!==-1);if(e===-1){if(!this.atEnd)return this.setNext("block-scalar");e=this.buffer.length}}let n=e+1;for(r=this.buffer[n];r===" ";)r=this.buffer[++n];if(r===" "){for(;r===" "||r===" "||r==="\r"||r===` +`;)r=this.buffer[++n];e=n-1}else if(!this.blockScalarKeep)do{let s=e-1,o=this.buffer[s];o==="\r"&&(o=this.buffer[--s]);let a=s;for(;o===" ";)o=this.buffer[--s];if(o===` +`&&s>=this.pos&&s+1+t>a)e=s;else break}while(!0);return yield Jn.SCALAR,yield*this.pushToIndex(e+1,!0),yield*this.parseLineStart()}*parsePlainScalar(){let e=this.flowLevel>0,t=this.pos-1,r=this.pos-1,n;for(;n=this.buffer[++r];)if(n===":"){let s=this.buffer[r+1];if(Wt(s)||e&&la.has(s))break;t=r}else if(Wt(n)){let s=this.buffer[r+1];if(n==="\r"&&(s===` +`?(r+=1,n=` +`,s=this.buffer[r+1]):t=r),s==="#"||e&&la.has(s))break;if(n===` +`){let o=this.continueScalar(r+1);if(o===-1)break;r=Math.max(r,o-2)}}else{if(e&&la.has(n))break;t=r}return!n&&!this.atEnd?this.setNext("plain-scalar"):(yield Jn.SCALAR,yield*this.pushToIndex(t+1,!0),e?"flow":"doc")}*pushCount(e){return e>0?(yield this.buffer.substr(this.pos,e),this.pos+=e,e):0}*pushToIndex(e,t){let r=this.buffer.slice(this.pos,e);return r?(yield r,this.pos+=r.length,r.length):(t&&(yield""),0)}*pushIndicators(){switch(this.charAt(0)){case"!":return(yield*this.pushTag())+(yield*this.pushSpaces(!0))+(yield*this.pushIndicators());case"&":return(yield*this.pushUntil(tf))+(yield*this.pushSpaces(!0))+(yield*this.pushIndicators());case"-":case"?":case":":{let e=this.flowLevel>0,t=this.charAt(1);if(Wt(t)||e&&la.has(t))return e?this.flowKey&&(this.flowKey=!1):this.indentNext=this.indentValue+1,(yield*this.pushCount(1))+(yield*this.pushSpaces(!0))+(yield*this.pushIndicators())}}return 0}*pushTag(){if(this.charAt(1)==="<"){let e=this.pos+2,t=this.buffer[e];for(;!Wt(t)&&t!==">";)t=this.buffer[++e];return yield*this.pushToIndex(t===">"?e+1:e,!1)}else{let e=this.pos+1,t=this.buffer[e];for(;t;)if(pA.has(t))t=this.buffer[++e];else if(t==="%"&&by.has(this.buffer[e+1])&&by.has(this.buffer[e+2]))t=this.buffer[e+=3];else break;return yield*this.pushToIndex(e,!1)}}*pushNewline(){let e=this.buffer[this.pos];return e===` +`?yield*this.pushCount(1):e==="\r"&&this.charAt(1)===` +`?yield*this.pushCount(2):0}*pushSpaces(e){let t=this.pos-1,r;do r=this.buffer[++t];while(r===" "||e&&r===" ");let n=t-this.pos;return n>0&&(yield this.buffer.substr(this.pos,n),this.pos=t),n}*pushUntil(e){let t=this.pos,r=this.buffer[t];for(;!e(r);)r=this.buffer[++t];return yield*this.pushToIndex(t,!1)}};_y.Lexer=rf});var of=x(wy=>{"use strict";var sf=class{constructor(){this.lineStarts=[],this.addNewLine=e=>this.lineStarts.push(e),this.linePos=e=>{let t=0,r=this.lineStarts.length;for(;t>1;this.lineStarts[s]{"use strict";var xy=aa(),mA=nf();function ur(i,e){for(let t=0;t=0;)switch(i[e].type){case"doc-start":case"explicit-key-ind":case"map-value-ind":case"seq-item-ind":case"newline":break e}for(;((t=i[++e])==null?void 0:t.type)==="space";);return i.splice(e,i.length)}function Ey(i){if(i.start.type==="flow-seq-start")for(let e of i.items)e.sep&&!e.value&&!ur(e.start,"explicit-key-ind")&&!ur(e.sep,"map-value-ind")&&(e.key&&(e.value=e.key),delete e.key,Oy(e.value)?e.value.end?Array.prototype.push.apply(e.value.end,e.sep):e.value.end=e.sep:Array.prototype.push.apply(e.start,e.sep),delete e.sep)}var af=class{constructor(e){this.atNewLine=!0,this.atScalar=!1,this.indent=0,this.offset=0,this.onKeyLine=!1,this.stack=[],this.source="",this.type="",this.lexer=new mA.Lexer,this.onNewLine=e}*parse(e,t=!1){this.onNewLine&&this.offset===0&&this.onNewLine(0);for(let r of this.lexer.lex(e,t))yield*this.next(r);t||(yield*this.end())}*next(e){if(this.source=e,process.env.LOG_TOKENS&&console.log("|",xy.prettyToken(e)),this.atScalar){this.atScalar=!1,yield*this.step(),this.offset+=e.length;return}let t=xy.tokenType(e);if(t)if(t==="scalar")this.atNewLine=!1,this.atScalar=!0,this.type="scalar";else{switch(this.type=t,yield*this.step(),t){case"newline":this.atNewLine=!0,this.indent=0,this.onNewLine&&this.onNewLine(this.offset+e.length);break;case"space":this.atNewLine&&e[0]===" "&&(this.indent+=e.length);break;case"explicit-key-ind":case"map-value-ind":case"seq-item-ind":this.atNewLine&&(this.indent+=e.length);break;case"doc-mode":case"flow-error-end":return;default:this.atNewLine=!1}this.offset+=e.length}else{let r=`Not a YAML token: ${e}`;yield*this.pop({type:"error",offset:this.offset,message:r,source:e}),this.offset+=e.length}}*end(){for(;this.stack.length>0;)yield*this.pop()}get sourceToken(){return{type:this.type,offset:this.offset,indent:this.indent,source:this.source}}*step(){let e=this.peek(1);if(this.type==="doc-end"&&(!e||e.type!=="doc-end")){for(;this.stack.length>0;)yield*this.pop();this.stack.push({type:"doc-end",offset:this.offset,source:this.source});return}if(!e)return yield*this.stream();switch(e.type){case"document":return yield*this.document(e);case"alias":case"scalar":case"single-quoted-scalar":case"double-quoted-scalar":return yield*this.scalar(e);case"block-scalar":return yield*this.blockScalar(e);case"block-map":return yield*this.blockMap(e);case"block-seq":return yield*this.blockSequence(e);case"flow-collection":return yield*this.flowCollection(e);case"doc-end":return yield*this.documentEnd(e)}yield*this.pop()}peek(e){return this.stack[this.stack.length-e]}*pop(e){let t=e!=null?e:this.stack.pop();if(!t)yield{type:"error",offset:this.offset,source:"",message:"Tried to pop an empty stack"};else if(this.stack.length===0)yield t;else{let r=this.peek(1);switch(t.type==="block-scalar"?t.indent="indent"in r?r.indent:0:t.type==="flow-collection"&&r.type==="document"&&(t.indent=0),t.type==="flow-collection"&&Ey(t),r.type){case"document":r.value=t;break;case"block-scalar":r.props.push(t);break;case"block-map":{let n=r.items[r.items.length-1];if(n.value){r.items.push({start:[],key:t,sep:[]}),this.onKeyLine=!0;return}else if(n.sep)n.value=t;else{Object.assign(n,{key:t,sep:[]}),this.onKeyLine=!n.explicitKey;return}break}case"block-seq":{let n=r.items[r.items.length-1];n.value?r.items.push({start:[],value:t}):n.value=t;break}case"flow-collection":{let n=r.items[r.items.length-1];!n||n.value?r.items.push({start:[],key:t,sep:[]}):n.sep?n.value=t:Object.assign(n,{key:t,sep:[]});return}default:yield*this.pop(),yield*this.pop(t)}if((r.type==="document"||r.type==="block-map"||r.type==="block-seq")&&(t.type==="block-map"||t.type==="block-seq")){let n=t.items[t.items.length-1];n&&!n.sep&&!n.value&&n.start.length>0&&Sy(n.start)===-1&&(t.indent===0||n.start.every(s=>s.type!=="comment"||s.indent=e.indent){let n=!this.onKeyLine&&this.indent===e.indent,s=n&&(t.sep||t.explicitKey)&&this.type!=="seq-item-ind",o=[];if(s&&t.sep&&!t.value){let a=[];for(let l=0;le.indent&&(a.length=0);break;default:a.length=0}}a.length>=2&&(o=t.sep.splice(a[1]))}switch(this.type){case"anchor":case"tag":s||t.value?(o.push(this.sourceToken),e.items.push({start:o}),this.onKeyLine=!0):t.sep?t.sep.push(this.sourceToken):t.start.push(this.sourceToken);return;case"explicit-key-ind":!t.sep&&!t.explicitKey?(t.start.push(this.sourceToken),t.explicitKey=!0):s||t.value?(o.push(this.sourceToken),e.items.push({start:o,explicitKey:!0})):this.stack.push({type:"block-map",offset:this.offset,indent:this.indent,items:[{start:[this.sourceToken],explicitKey:!0}]}),this.onKeyLine=!0;return;case"map-value-ind":if(t.explicitKey)if(t.sep)if(t.value)e.items.push({start:[],key:null,sep:[this.sourceToken]});else if(ur(t.sep,"map-value-ind"))this.stack.push({type:"block-map",offset:this.offset,indent:this.indent,items:[{start:o,key:null,sep:[this.sourceToken]}]});else if(Oy(t.key)&&!ur(t.sep,"newline")){let a=Jr(t.start),l=t.key,c=t.sep;c.push(this.sourceToken),delete t.key,delete t.sep,this.stack.push({type:"block-map",offset:this.offset,indent:this.indent,items:[{start:a,key:l,sep:c}]})}else o.length>0?t.sep=t.sep.concat(o,this.sourceToken):t.sep.push(this.sourceToken);else if(ur(t.start,"newline"))Object.assign(t,{key:null,sep:[this.sourceToken]});else{let a=Jr(t.start);this.stack.push({type:"block-map",offset:this.offset,indent:this.indent,items:[{start:a,key:null,sep:[this.sourceToken]}]})}else t.sep?t.value||s?e.items.push({start:o,key:null,sep:[this.sourceToken]}):ur(t.sep,"map-value-ind")?this.stack.push({type:"block-map",offset:this.offset,indent:this.indent,items:[{start:[],key:null,sep:[this.sourceToken]}]}):t.sep.push(this.sourceToken):Object.assign(t,{key:null,sep:[this.sourceToken]});this.onKeyLine=!0;return;case"alias":case"scalar":case"single-quoted-scalar":case"double-quoted-scalar":{let a=this.flowScalar(this.type);s||t.value?(e.items.push({start:o,key:a,sep:[]}),this.onKeyLine=!0):t.sep?this.stack.push(a):(Object.assign(t,{key:a,sep:[]}),this.onKeyLine=!0);return}default:{let a=this.startBlockValue(e);if(a){n&&a.type!=="block-seq"&&e.items.push({start:o}),this.stack.push(a);return}}}}yield*this.pop(),yield*this.step()}*blockSequence(e){var r;let t=e.items[e.items.length-1];switch(this.type){case"newline":if(t.value){let n="end"in t.value?t.value.end:void 0,s=Array.isArray(n)?n[n.length-1]:void 0;(s==null?void 0:s.type)==="comment"?n==null||n.push(this.sourceToken):e.items.push({start:[this.sourceToken]})}else t.start.push(this.sourceToken);return;case"space":case"comment":if(t.value)e.items.push({start:[this.sourceToken]});else{if(this.atIndentedComment(t.start,e.indent)){let n=e.items[e.items.length-2],s=(r=n==null?void 0:n.value)==null?void 0:r.end;if(Array.isArray(s)){Array.prototype.push.apply(s,t.start),s.push(this.sourceToken),e.items.pop();return}}t.start.push(this.sourceToken)}return;case"anchor":case"tag":if(t.value||this.indent<=e.indent)break;t.start.push(this.sourceToken);return;case"seq-item-ind":if(this.indent!==e.indent)break;t.value||ur(t.start,"seq-item-ind")?e.items.push({start:[this.sourceToken]}):t.start.push(this.sourceToken);return}if(this.indent>e.indent){let n=this.startBlockValue(e);if(n){this.stack.push(n);return}}yield*this.pop(),yield*this.step()}*flowCollection(e){let t=e.items[e.items.length-1];if(this.type==="flow-error-end"){let r;do yield*this.pop(),r=this.peek(1);while(r&&r.type==="flow-collection")}else if(e.end.length===0){switch(this.type){case"comma":case"explicit-key-ind":!t||t.sep?e.items.push({start:[this.sourceToken]}):t.start.push(this.sourceToken);return;case"map-value-ind":!t||t.value?e.items.push({start:[],key:null,sep:[this.sourceToken]}):t.sep?t.sep.push(this.sourceToken):Object.assign(t,{key:null,sep:[this.sourceToken]});return;case"space":case"comment":case"newline":case"anchor":case"tag":!t||t.value?e.items.push({start:[this.sourceToken]}):t.sep?t.sep.push(this.sourceToken):t.start.push(this.sourceToken);return;case"alias":case"scalar":case"single-quoted-scalar":case"double-quoted-scalar":{let n=this.flowScalar(this.type);!t||t.value?e.items.push({start:[],key:n,sep:[]}):t.sep?this.stack.push(n):Object.assign(t,{key:n,sep:[]});return}case"flow-map-end":case"flow-seq-end":e.end.push(this.sourceToken);return}let r=this.startBlockValue(e);r?this.stack.push(r):(yield*this.pop(),yield*this.step())}else{let r=this.peek(2);if(r.type==="block-map"&&(this.type==="map-value-ind"&&r.indent===e.indent||this.type==="newline"&&!r.items[r.items.length-1].sep))yield*this.pop(),yield*this.step();else if(this.type==="map-value-ind"&&r.type!=="flow-collection"){let n=ca(r),s=Jr(n);Ey(e);let o=e.end.splice(1,e.end.length);o.push(this.sourceToken);let a={type:"block-map",offset:e.offset,indent:e.indent,items:[{start:s,key:e,sep:o}]};this.onKeyLine=!0,this.stack[this.stack.length-1]=a}else yield*this.lineEnd(e)}}flowScalar(e){if(this.onNewLine){let t=this.source.indexOf(` +`)+1;for(;t!==0;)this.onNewLine(this.offset+t),t=this.source.indexOf(` +`,t)+1}return{type:e,offset:this.offset,indent:this.indent,source:this.source}}startBlockValue(e){switch(this.type){case"alias":case"scalar":case"single-quoted-scalar":case"double-quoted-scalar":return this.flowScalar(this.type);case"block-scalar-header":return{type:"block-scalar",offset:this.offset,indent:this.indent,props:[this.sourceToken],source:""};case"flow-map-start":case"flow-seq-start":return{type:"flow-collection",offset:this.offset,indent:this.indent,start:this.sourceToken,items:[],end:[]};case"seq-item-ind":return{type:"block-seq",offset:this.offset,indent:this.indent,items:[{start:[this.sourceToken]}]};case"explicit-key-ind":{this.onKeyLine=!0;let t=ca(e),r=Jr(t);return r.push(this.sourceToken),{type:"block-map",offset:this.offset,indent:this.indent,items:[{start:r,explicitKey:!0}]}}case"map-value-ind":{this.onKeyLine=!0;let t=ca(e),r=Jr(t);return{type:"block-map",offset:this.offset,indent:this.indent,items:[{start:r,key:null,sep:[this.sourceToken]}]}}}return null}atIndentedComment(e,t){return this.type!=="comment"||this.indent<=t?!1:e.every(r=>r.type==="newline"||r.type==="space")}*documentEnd(e){this.type!=="doc-mode"&&(e.end?e.end.push(this.sourceToken):e.end=[this.sourceToken],this.type==="newline"&&(yield*this.pop()))}*lineEnd(e){switch(this.type){case"comma":case"doc-start":case"doc-end":case"flow-seq-end":case"flow-map-end":case"map-value-ind":yield*this.pop(),yield*this.step();break;case"newline":this.onKeyLine=!1;case"space":case"comment":default:e.end?e.end.push(this.sourceToken):e.end=[this.sourceToken],this.type==="newline"&&(yield*this.pop())}}};ky.Parser=af});var Ny=x(Qn=>{"use strict";var Cy=Yu(),gA=Vn(),Zn=Wn(),vA=Gc(),yA=Se(),bA=of(),Ty=lf();function Ay(i){let e=i.prettyErrors!==!1;return{lineCounter:i.lineCounter||e&&new bA.LineCounter||null,prettyErrors:e}}function _A(i,e={}){let{lineCounter:t,prettyErrors:r}=Ay(e),n=new Ty.Parser(t==null?void 0:t.addNewLine),s=new Cy.Composer(e),o=Array.from(s.compose(n.parse(i)));if(r&&t)for(let a of o)a.errors.forEach(Zn.prettifyError(i,t)),a.warnings.forEach(Zn.prettifyError(i,t));return o.length>0?o:Object.assign([],{empty:!0},s.streamInfo())}function Iy(i,e={}){let{lineCounter:t,prettyErrors:r}=Ay(e),n=new Ty.Parser(t==null?void 0:t.addNewLine),s=new Cy.Composer(e),o=null;for(let a of s.compose(n.parse(i),!0,i.length))if(!o)o=a;else if(o.options.logLevel!=="silent"){o.errors.push(new Zn.YAMLParseError(a.range.slice(0,2),"MULTIPLE_DOCS","Source contains multiple documents; please use YAML.parseAllDocuments()"));break}return r&&t&&(o.errors.forEach(Zn.prettifyError(i,t)),o.warnings.forEach(Zn.prettifyError(i,t))),o}function wA(i,e,t){let r;typeof e=="function"?r=e:t===void 0&&e&&typeof e=="object"&&(t=e);let n=Iy(i,t);if(!n)return null;if(n.warnings.forEach(s=>vA.warn(n.options.logLevel,s)),n.errors.length>0){if(n.options.logLevel!=="silent")throw n.errors[0];n.errors=[]}return n.toJS(Object.assign({reviver:r},t))}function xA(i,e,t){var n;let r=null;if(typeof e=="function"||Array.isArray(e)?r=e:t===void 0&&e&&(t=e),typeof t=="string"&&(t=t.length),typeof t=="number"){let s=Math.round(t);t=s<1?void 0:s>8?{indent:8}:{indent:s}}if(i===void 0){let{keepUndefined:s}=(n=t!=null?t:e)!=null?n:{};if(!s)return}return yA.isDocument(i)&&!r?i.toString(t):new gA.Document(i,r,t).toString(t)}Qn.parse=wA;Qn.parseAllDocuments=_A;Qn.parseDocument=Iy;Qn.stringify=xA});var Ly=x(Ce=>{"use strict";var SA=Yu(),EA=Vn(),OA=Cu(),cf=Wn(),kA=Cn(),Pi=Se(),CA=Ni(),TA=je(),AA=Li(),IA=Ri(),NA=aa(),BA=nf(),LA=of(),RA=lf(),ua=Ny(),By=Sn();Ce.Composer=SA.Composer;Ce.Document=EA.Document;Ce.Schema=OA.Schema;Ce.YAMLError=cf.YAMLError;Ce.YAMLParseError=cf.YAMLParseError;Ce.YAMLWarning=cf.YAMLWarning;Ce.Alias=kA.Alias;Ce.isAlias=Pi.isAlias;Ce.isCollection=Pi.isCollection;Ce.isDocument=Pi.isDocument;Ce.isMap=Pi.isMap;Ce.isNode=Pi.isNode;Ce.isPair=Pi.isPair;Ce.isScalar=Pi.isScalar;Ce.isSeq=Pi.isSeq;Ce.Pair=CA.Pair;Ce.Scalar=TA.Scalar;Ce.YAMLMap=AA.YAMLMap;Ce.YAMLSeq=IA.YAMLSeq;Ce.CST=NA;Ce.Lexer=BA.Lexer;Ce.LineCounter=LA.LineCounter;Ce.Parser=RA.Parser;Ce.parse=ua.parse;Ce.parseAllDocuments=ua.parseAllDocuments;Ce.parseDocument=ua.parseDocument;Ce.stringify=ua.stringify;Ce.visit=By.visit;Ce.visitAsync=By.visitAsync});var Py=x((HB,Ry)=>{var Mi=require("constants"),PA=process.cwd,fa=null,MA=process.env.GRACEFUL_FS_PLATFORM||process.platform;process.cwd=function(){return fa||(fa=PA.call(process)),fa};try{process.cwd()}catch{}typeof process.chdir=="function"&&(uf=process.chdir,process.chdir=function(i){fa=null,uf.call(process,i)},Object.setPrototypeOf&&Object.setPrototypeOf(process.chdir,uf));var uf;Ry.exports=qA;function qA(i){Mi.hasOwnProperty("O_SYMLINK")&&process.version.match(/^v0\.6\.[0-2]|^v0\.5\./)&&e(i),i.lutimes||t(i),i.chown=s(i.chown),i.fchown=s(i.fchown),i.lchown=s(i.lchown),i.chmod=r(i.chmod),i.fchmod=r(i.fchmod),i.lchmod=r(i.lchmod),i.chownSync=o(i.chownSync),i.fchownSync=o(i.fchownSync),i.lchownSync=o(i.lchownSync),i.chmodSync=n(i.chmodSync),i.fchmodSync=n(i.fchmodSync),i.lchmodSync=n(i.lchmodSync),i.stat=a(i.stat),i.fstat=a(i.fstat),i.lstat=a(i.lstat),i.statSync=l(i.statSync),i.fstatSync=l(i.fstatSync),i.lstatSync=l(i.lstatSync),i.chmod&&!i.lchmod&&(i.lchmod=function(u,f,d){d&&process.nextTick(d)},i.lchmodSync=function(){}),i.chown&&!i.lchown&&(i.lchown=function(u,f,d,m){m&&process.nextTick(m)},i.lchownSync=function(){}),MA==="win32"&&(i.rename=typeof i.rename!="function"?i.rename:(function(u){function f(d,m,g){var y=Date.now(),b=0;u(d,m,function w(S){if(S&&(S.code==="EACCES"||S.code==="EPERM")&&Date.now()-y<6e4){setTimeout(function(){i.stat(m,function(k,O){k&&k.code==="ENOENT"?u(d,m,w):g(S)})},b),b<100&&(b+=10);return}g&&g(S)})}return Object.setPrototypeOf&&Object.setPrototypeOf(f,u),f})(i.rename)),i.read=typeof i.read!="function"?i.read:(function(u){function f(d,m,g,y,b,w){var S;if(w&&typeof w=="function"){var k=0;S=function(O,E,R){if(O&&O.code==="EAGAIN"&&k<10)return k++,u.call(i,d,m,g,y,b,S);w.apply(this,arguments)}}return u.call(i,d,m,g,y,b,S)}return Object.setPrototypeOf&&Object.setPrototypeOf(f,u),f})(i.read),i.readSync=typeof i.readSync!="function"?i.readSync:(function(u){return function(f,d,m,g,y){for(var b=0;;)try{return u.call(i,f,d,m,g,y)}catch(w){if(w.code==="EAGAIN"&&b<10){b++;continue}throw w}}})(i.readSync);function e(u){u.lchmod=function(f,d,m){u.open(f,Mi.O_WRONLY|Mi.O_SYMLINK,d,function(g,y){if(g){m&&m(g);return}u.fchmod(y,d,function(b){u.close(y,function(w){m&&m(b||w)})})})},u.lchmodSync=function(f,d){var m=u.openSync(f,Mi.O_WRONLY|Mi.O_SYMLINK,d),g=!0,y;try{y=u.fchmodSync(m,d),g=!1}finally{if(g)try{u.closeSync(m)}catch{}else u.closeSync(m)}return y}}function t(u){Mi.hasOwnProperty("O_SYMLINK")&&u.futimes?(u.lutimes=function(f,d,m,g){u.open(f,Mi.O_SYMLINK,function(y,b){if(y){g&&g(y);return}u.futimes(b,d,m,function(w){u.close(b,function(S){g&&g(w||S)})})})},u.lutimesSync=function(f,d,m){var g=u.openSync(f,Mi.O_SYMLINK),y,b=!0;try{y=u.futimesSync(g,d,m),b=!1}finally{if(b)try{u.closeSync(g)}catch{}else u.closeSync(g)}return y}):u.futimes&&(u.lutimes=function(f,d,m,g){g&&process.nextTick(g)},u.lutimesSync=function(){})}function r(u){return u&&function(f,d,m){return u.call(i,f,d,function(g){c(g)&&(g=null),m&&m.apply(this,arguments)})}}function n(u){return u&&function(f,d){try{return u.call(i,f,d)}catch(m){if(!c(m))throw m}}}function s(u){return u&&function(f,d,m,g){return u.call(i,f,d,m,function(y){c(y)&&(y=null),g&&g.apply(this,arguments)})}}function o(u){return u&&function(f,d,m){try{return u.call(i,f,d,m)}catch(g){if(!c(g))throw g}}}function a(u){return u&&function(f,d,m){typeof d=="function"&&(m=d,d=null);function g(y,b){b&&(b.uid<0&&(b.uid+=4294967296),b.gid<0&&(b.gid+=4294967296)),m&&m.apply(this,arguments)}return d?u.call(i,f,d,g):u.call(i,f,g)}}function l(u){return u&&function(f,d){var m=d?u.call(i,f,d):u.call(i,f);return m&&(m.uid<0&&(m.uid+=4294967296),m.gid<0&&(m.gid+=4294967296)),m}}function c(u){if(!u||u.code==="ENOSYS")return!0;var f=!process.getuid||process.getuid()!==0;return!!(f&&(u.code==="EINVAL"||u.code==="EPERM"))}}});var Fy=x((GB,qy)=>{var My=require("stream").Stream;qy.exports=FA;function FA(i){return{ReadStream:e,WriteStream:t};function e(r,n){if(!(this instanceof e))return new e(r,n);My.call(this);var s=this;this.path=r,this.fd=null,this.readable=!0,this.paused=!1,this.flags="r",this.mode=438,this.bufferSize=64*1024,n=n||{};for(var o=Object.keys(n),a=0,l=o.length;athis.end)throw new Error("start must be <= end");this.pos=this.start}if(this.fd!==null){process.nextTick(function(){s._read()});return}i.open(this.path,this.flags,this.mode,function(u,f){if(u){s.emit("error",u),s.readable=!1;return}s.fd=f,s.emit("open",f),s._read()})}function t(r,n){if(!(this instanceof t))return new t(r,n);My.call(this),this.path=r,this.fd=null,this.writable=!0,this.flags="w",this.encoding="binary",this.mode=438,this.bytesWritten=0,n=n||{};for(var s=Object.keys(n),o=0,a=s.length;o= zero");this.pos=this.start}this.busy=!1,this._queue=[],this.fd===null&&(this._open=i.open,this._queue.push([this._open,this.path,this.flags,this.mode,void 0]),this.flush())}}});var jy=x((WB,Dy)=>{"use strict";Dy.exports=jA;var DA=Object.getPrototypeOf||function(i){return i.__proto__};function jA(i){if(i===null||typeof i!="object")return i;if(i instanceof Object)var e={__proto__:DA(i)};else var e=Object.create(null);return Object.getOwnPropertyNames(i).forEach(function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(i,t))}),e}});var Hy=x((YB,pf)=>{var qe=require("fs"),UA=Py(),$A=Fy(),VA=jy(),ha=require("util"),it,da;typeof Symbol=="function"&&typeof Symbol.for=="function"?(it=Symbol.for("graceful-fs.queue"),da=Symbol.for("graceful-fs.previous")):(it="___graceful-fs.queue",da="___graceful-fs.previous");function HA(){}function Vy(i,e){Object.defineProperty(i,it,{get:function(){return e}})}var fr=HA;ha.debuglog?fr=ha.debuglog("gfs4"):/\bgfs4\b/i.test(process.env.NODE_DEBUG||"")&&(fr=function(){var i=ha.format.apply(ha,arguments);i="GFS4: "+i.split(/\n/).join(` +GFS4: `),console.error(i)});qe[it]||(Uy=global[it]||[],Vy(qe,Uy),qe.close=(function(i){function e(t,r){return i.call(qe,t,function(n){n||$y(),typeof r=="function"&&r.apply(this,arguments)})}return Object.defineProperty(e,da,{value:i}),e})(qe.close),qe.closeSync=(function(i){function e(t){i.apply(qe,arguments),$y()}return Object.defineProperty(e,da,{value:i}),e})(qe.closeSync),/\bgfs4\b/i.test(process.env.NODE_DEBUG||"")&&process.on("exit",function(){fr(qe[it]),require("assert").equal(qe[it].length,0)}));var Uy;global[it]||Vy(global,qe[it]);pf.exports=ff(VA(qe));process.env.TEST_GRACEFUL_FS_GLOBAL_PATCH&&!qe.__patched&&(pf.exports=ff(qe),qe.__patched=!0);function ff(i){UA(i),i.gracefulify=ff,i.createReadStream=E,i.createWriteStream=R;var e=i.readFile;i.readFile=t;function t(C,B,P){return typeof B=="function"&&(P=B,B=null),U(C,B,P);function U(F,H,j,V){return e(F,H,function(Y){Y&&(Y.code==="EMFILE"||Y.code==="ENFILE")?Zr([U,[F,H,j],Y,V||Date.now(),Date.now()]):typeof j=="function"&&j.apply(this,arguments)})}}var r=i.writeFile;i.writeFile=n;function n(C,B,P,U){return typeof P=="function"&&(U=P,P=null),F(C,B,P,U);function F(H,j,V,Y,Q){return r(H,j,V,function(W){W&&(W.code==="EMFILE"||W.code==="ENFILE")?Zr([F,[H,j,V,Y],W,Q||Date.now(),Date.now()]):typeof Y=="function"&&Y.apply(this,arguments)})}}var s=i.appendFile;s&&(i.appendFile=o);function o(C,B,P,U){return typeof P=="function"&&(U=P,P=null),F(C,B,P,U);function F(H,j,V,Y,Q){return s(H,j,V,function(W){W&&(W.code==="EMFILE"||W.code==="ENFILE")?Zr([F,[H,j,V,Y],W,Q||Date.now(),Date.now()]):typeof Y=="function"&&Y.apply(this,arguments)})}}var a=i.copyFile;a&&(i.copyFile=l);function l(C,B,P,U){return typeof P=="function"&&(U=P,P=0),F(C,B,P,U);function F(H,j,V,Y,Q){return a(H,j,V,function(W){W&&(W.code==="EMFILE"||W.code==="ENFILE")?Zr([F,[H,j,V,Y],W,Q||Date.now(),Date.now()]):typeof Y=="function"&&Y.apply(this,arguments)})}}var c=i.readdir;i.readdir=f;var u=/^v[0-5]\./;function f(C,B,P){typeof B=="function"&&(P=B,B=null);var U=u.test(process.version)?function(j,V,Y,Q){return c(j,F(j,V,Y,Q))}:function(j,V,Y,Q){return c(j,V,F(j,V,Y,Q))};return U(C,B,P);function F(H,j,V,Y){return function(Q,W){Q&&(Q.code==="EMFILE"||Q.code==="ENFILE")?Zr([U,[H,j,V],Q,Y||Date.now(),Date.now()]):(W&&W.sort&&W.sort(),typeof V=="function"&&V.call(this,Q,W))}}}if(process.version.substr(0,4)==="v0.8"){var d=$A(i);w=d.ReadStream,k=d.WriteStream}var m=i.ReadStream;m&&(w.prototype=Object.create(m.prototype),w.prototype.open=S);var g=i.WriteStream;g&&(k.prototype=Object.create(g.prototype),k.prototype.open=O),Object.defineProperty(i,"ReadStream",{get:function(){return w},set:function(C){w=C},enumerable:!0,configurable:!0}),Object.defineProperty(i,"WriteStream",{get:function(){return k},set:function(C){k=C},enumerable:!0,configurable:!0});var y=w;Object.defineProperty(i,"FileReadStream",{get:function(){return y},set:function(C){y=C},enumerable:!0,configurable:!0});var b=k;Object.defineProperty(i,"FileWriteStream",{get:function(){return b},set:function(C){b=C},enumerable:!0,configurable:!0});function w(C,B){return this instanceof w?(m.apply(this,arguments),this):w.apply(Object.create(w.prototype),arguments)}function S(){var C=this;A(C.path,C.flags,C.mode,function(B,P){B?(C.autoClose&&C.destroy(),C.emit("error",B)):(C.fd=P,C.emit("open",P),C.read())})}function k(C,B){return this instanceof k?(g.apply(this,arguments),this):k.apply(Object.create(k.prototype),arguments)}function O(){var C=this;A(C.path,C.flags,C.mode,function(B,P){B?(C.destroy(),C.emit("error",B)):(C.fd=P,C.emit("open",P))})}function E(C,B){return new i.ReadStream(C,B)}function R(C,B){return new i.WriteStream(C,B)}var T=i.open;i.open=A;function A(C,B,P,U){return typeof P=="function"&&(U=P,P=null),F(C,B,P,U);function F(H,j,V,Y,Q){return T(H,j,V,function(W,de){W&&(W.code==="EMFILE"||W.code==="ENFILE")?Zr([F,[H,j,V,Y],W,Q||Date.now(),Date.now()]):typeof Y=="function"&&Y.apply(this,arguments)})}}return i}function Zr(i){fr("ENQUEUE",i[0].name,i[1]),qe[it].push(i),hf()}var pa;function $y(){for(var i=Date.now(),e=0;e2&&(qe[it][e][3]=i,qe[it][e][4]=i);hf()}function hf(){if(clearTimeout(pa),pa=void 0,qe[it].length!==0){var i=qe[it].shift(),e=i[0],t=i[1],r=i[2],n=i[3],s=i[4];if(n===void 0)fr("RETRY",e.name,t),e.apply(null,t);else if(Date.now()-n>=6e4){fr("TIMEOUT",e.name,t);var o=t.pop();typeof o=="function"&&o.call(null,r)}else{var a=Date.now()-s,l=Math.max(s-n,1),c=Math.min(l*1.2,100);a>=c?(fr("RETRY",e.name,t),e.apply(null,t.concat([n]))):qe[it].push(i)}pa===void 0&&(pa=setTimeout(hf,0))}}});var Wy=x((KB,Gy)=>{function Ft(i,e){typeof e=="boolean"&&(e={forever:e}),this._originalTimeouts=JSON.parse(JSON.stringify(i)),this._timeouts=i,this._options=e||{},this._maxRetryTime=e&&e.maxRetryTime||1/0,this._fn=null,this._errors=[],this._attempts=1,this._operationTimeout=null,this._operationTimeoutCb=null,this._timeout=null,this._operationStart=null,this._options.forever&&(this._cachedTimeouts=this._timeouts.slice(0))}Gy.exports=Ft;Ft.prototype.reset=function(){this._attempts=1,this._timeouts=this._originalTimeouts};Ft.prototype.stop=function(){this._timeout&&clearTimeout(this._timeout),this._timeouts=[],this._cachedTimeouts=null};Ft.prototype.retry=function(i){if(this._timeout&&clearTimeout(this._timeout),!i)return!1;var e=new Date().getTime();if(i&&e-this._operationStart>=this._maxRetryTime)return this._errors.unshift(new Error("RetryOperation timeout occurred")),!1;this._errors.push(i);var t=this._timeouts.shift();if(t===void 0)if(this._cachedTimeouts)this._errors.splice(this._errors.length-1,this._errors.length),this._timeouts=this._cachedTimeouts.slice(0),t=this._timeouts.shift();else return!1;var r=this,n=setTimeout(function(){r._attempts++,r._operationTimeoutCb&&(r._timeout=setTimeout(function(){r._operationTimeoutCb(r._attempts)},r._operationTimeout),r._options.unref&&r._timeout.unref()),r._fn(r._attempts)},t);return this._options.unref&&n.unref(),!0};Ft.prototype.attempt=function(i,e){this._fn=i,e&&(e.timeout&&(this._operationTimeout=e.timeout),e.cb&&(this._operationTimeoutCb=e.cb));var t=this;this._operationTimeoutCb&&(this._timeout=setTimeout(function(){t._operationTimeoutCb()},t._operationTimeout)),this._operationStart=new Date().getTime(),this._fn(this._attempts)};Ft.prototype.try=function(i){console.log("Using RetryOperation.try() is deprecated"),this.attempt(i)};Ft.prototype.start=function(i){console.log("Using RetryOperation.start() is deprecated"),this.attempt(i)};Ft.prototype.start=Ft.prototype.try;Ft.prototype.errors=function(){return this._errors};Ft.prototype.attempts=function(){return this._attempts};Ft.prototype.mainError=function(){if(this._errors.length===0)return null;for(var i={},e=null,t=0,r=0;r=t&&(e=n,t=o)}return e}});var Yy=x(hr=>{var GA=Wy();hr.operation=function(i){var e=hr.timeouts(i);return new GA(e,{forever:i&&i.forever,unref:i&&i.unref,maxRetryTime:i&&i.maxRetryTime})};hr.timeouts=function(i){if(i instanceof Array)return[].concat(i);var e={retries:10,factor:2,minTimeout:1*1e3,maxTimeout:1/0,randomize:!1};for(var t in i)e[t]=i[t];if(e.minTimeout>e.maxTimeout)throw new Error("minTimeout is greater than maxTimeout");for(var r=[],n=0;n{Ky.exports=Yy()});var Jy=x((ZB,ma)=>{ma.exports=["SIGABRT","SIGALRM","SIGHUP","SIGINT","SIGTERM"];process.platform!=="win32"&&ma.exports.push("SIGVTALRM","SIGXCPU","SIGXFSZ","SIGUSR2","SIGTRAP","SIGSYS","SIGQUIT","SIGIOT");process.platform==="linux"&&ma.exports.push("SIGIO","SIGPOLL","SIGPWR","SIGSTKFLT","SIGUNUSED")});var tb=x((QB,en)=>{var Me=global.process,pr=function(i){return i&&typeof i=="object"&&typeof i.removeListener=="function"&&typeof i.emit=="function"&&typeof i.reallyExit=="function"&&typeof i.listeners=="function"&&typeof i.kill=="function"&&typeof i.pid=="number"&&typeof i.on=="function"};pr(Me)?(Zy=require("assert"),Qr=Jy(),Qy=/^win/i.test(Me.platform),Xn=require("events"),typeof Xn!="function"&&(Xn=Xn.EventEmitter),Me.__signal_exit_emitter__?Qe=Me.__signal_exit_emitter__:(Qe=Me.__signal_exit_emitter__=new Xn,Qe.count=0,Qe.emitted={}),Qe.infinite||(Qe.setMaxListeners(1/0),Qe.infinite=!0),en.exports=function(i,e){if(!pr(global.process))return function(){};Zy.equal(typeof i,"function","a callback must be provided for exit handler"),Xr===!1&&df();var t="exit";e&&e.alwaysLast&&(t="afterexit");var r=function(){Qe.removeListener(t,i),Qe.listeners("exit").length===0&&Qe.listeners("afterexit").length===0&&ga()};return Qe.on(t,i),r},ga=function(){!Xr||!pr(global.process)||(Xr=!1,Qr.forEach(function(e){try{Me.removeListener(e,va[e])}catch{}}),Me.emit=ya,Me.reallyExit=mf,Qe.count-=1)},en.exports.unload=ga,dr=function(e,t,r){Qe.emitted[e]||(Qe.emitted[e]=!0,Qe.emit(e,t,r))},va={},Qr.forEach(function(i){va[i]=function(){if(pr(global.process)){var t=Me.listeners(i);t.length===Qe.count&&(ga(),dr("exit",null,i),dr("afterexit",null,i),Qy&&i==="SIGHUP"&&(i="SIGINT"),Me.kill(Me.pid,i))}}}),en.exports.signals=function(){return Qr},Xr=!1,df=function(){Xr||!pr(global.process)||(Xr=!0,Qe.count+=1,Qr=Qr.filter(function(e){try{return Me.on(e,va[e]),!0}catch{return!1}}),Me.emit=eb,Me.reallyExit=Xy)},en.exports.load=df,mf=Me.reallyExit,Xy=function(e){pr(global.process)&&(Me.exitCode=e||0,dr("exit",Me.exitCode,null),dr("afterexit",Me.exitCode,null),mf.call(Me,Me.exitCode))},ya=Me.emit,eb=function(e,t){if(e==="exit"&&pr(global.process)){t!==void 0&&(Me.exitCode=t);var r=ya.apply(this,arguments);return dr("exit",Me.exitCode,null),dr("afterexit",Me.exitCode,null),r}else return ya.apply(this,arguments)}):en.exports=function(){return function(){}};var Zy,Qr,Qy,Xn,Qe,ga,dr,va,Xr,df,mf,Xy,ya,eb});var cb=x((XB,lb)=>{"use strict";var WA=require("path"),sb=Hy(),YA=zy(),KA=tb(),qi={},ib=Symbol();function zA(i,e,t){let r=e[ib];if(r)return e.stat(i,(s,o)=>{if(s)return t(s);t(null,o.mtime,r)});let n=new Date(Math.ceil(Date.now()/1e3)*1e3+5);e.utimes(i,n,n,s=>{if(s)return t(s);e.stat(i,(o,a)=>{if(o)return t(o);let l=a.mtime.getTime()%1e3===0?"s":"ms";Object.defineProperty(e,ib,{value:l}),t(null,a.mtime,l)})})}function JA(i){let e=Date.now();return i==="s"&&(e=Math.ceil(e/1e3)*1e3),new Date(e)}function _a(i,e){return e.lockfilePath||`${i}.lock`}function ob(i,e,t){if(!e.realpath)return t(null,WA.resolve(i));e.fs.realpath(i,t)}function vf(i,e,t){let r=_a(i,e);e.fs.mkdir(r,n=>{if(!n)return zA(r,e.fs,(s,o,a)=>{if(s)return e.fs.rmdir(r,()=>{}),t(s);t(null,o,a)});if(n.code!=="EEXIST")return t(n);if(e.stale<=0)return t(Object.assign(new Error("Lock file is already being held"),{code:"ELOCKED",file:i}));e.fs.stat(r,(s,o)=>{if(s)return s.code==="ENOENT"?vf(i,{...e,stale:0},t):t(s);if(!ZA(o,e))return t(Object.assign(new Error("Lock file is already being held"),{code:"ELOCKED",file:i}));ab(i,e,a=>{if(a)return t(a);vf(i,{...e,stale:0},t)})})})}function ZA(i,e){return i.mtime.getTime(){if(r&&r.code!=="ENOENT")return t(r);t()})}function ba(i,e){let t=qi[i];t.updateTimeout||(t.updateDelay=t.updateDelay||e.update,t.updateTimeout=setTimeout(()=>{t.updateTimeout=null,e.fs.stat(t.lockfilePath,(r,n)=>{let s=t.lastUpdate+e.stale{let c=t.lastUpdate+e.stale{throw r},...e},e.retries=e.retries||0,e.retries=typeof e.retries=="number"?{retries:e.retries}:e.retries,e.stale=Math.max(e.stale||0,2e3),e.update=e.update==null?e.stale/2:e.update||0,e.update=Math.max(Math.min(e.update,e.stale/2),1e3),ob(i,e,(r,n)=>{if(r)return t(r);let s=YA.operation(e.retries);s.attempt(()=>{vf(n,e,(o,a,l)=>{if(s.retry(o))return;if(o)return t(s.mainError());let c=qi[n]={lockfilePath:_a(n,e),mtime:a,mtimePrecision:l,options:e,lastUpdate:Date.now()};ba(n,e),t(null,u=>{if(c.released)return u&&u(Object.assign(new Error("Lock is already released"),{code:"ERELEASED"}));XA(n,{...e,realpath:!1},u)})})})})}function XA(i,e,t){e={fs:sb,realpath:!0,...e},ob(i,e,(r,n)=>{if(r)return t(r);let s=qi[n];if(!s)return t(Object.assign(new Error("Lock is not acquired/owned by you"),{code:"ENOTACQUIRED"}));s.updateTimeout&&clearTimeout(s.updateTimeout),s.released=!0,delete qi[n],ab(n,e,t)})}function rb(i){return(...e)=>new Promise((t,r)=>{e.push((n,s)=>{n?r(n):t(s)}),i(...e)})}var nb=!1;function eI(){nb||(nb=!0,KA(()=>{for(let i in qi){let e=qi[i].options;try{e.fs.rmdirSync(_a(i,e))}catch{}}}))}lb.exports.lock=async(i,e)=>{eI();let t=await rb(QA)(i,e);return rb(t)}});var vI={};wf(vI,{HttpsProxyAgent:()=>_b.HttpsProxyAgent,PNG:()=>wb.PNG,ProgramOption:()=>rm,SocksProxyAgent:()=>xb.SocksProxyAgent,colors:()=>tI,debug:()=>iI,diff:()=>rI,dotenv:()=>nI,getProxyForUrl:()=>bb.getProxyForUrl,jpegjs:()=>sI,lockfile:()=>aI,mime:()=>lI,minimatch:()=>cI,open:()=>uI,program:()=>im,progress:()=>fI,ws:()=>hI,wsReceiver:()=>dI,wsSender:()=>mI,wsServer:()=>pI,yaml:()=>gI});module.exports=Vb(vI);var ub=$e(Jf()),fb=$e(rn());var Fa={};wf(Fa,{Diff:()=>It,applyPatch:()=>Ah,applyPatches:()=>z_,canonicalize:()=>Es,convertChangesToDMP:()=>nw,convertChangesToXML:()=>sw,createPatch:()=>J_,createTwoFilesPatch:()=>Ih,diffArrays:()=>G_,diffChars:()=>C_,diffCss:()=>M_,diffJson:()=>H_,diffLines:()=>Ba,diffSentences:()=>P_,diffTrimmedLines:()=>R_,diffWords:()=>B_,diffWordsWithSpace:()=>Eh,formatPatch:()=>Cs,merge:()=>ew,parsePatch:()=>Ts,reversePatch:()=>Nh,structuredPatch:()=>ks});function It(){}It.prototype={diff:function(e,t){var r,n=arguments.length>2&&arguments[2]!==void 0?arguments[2]:{},s=n.callback;typeof n=="function"&&(s=n,n={});var o=this;function a(O){return O=o.postProcess(O,n),s?(setTimeout(function(){s(O)},0),!0):O}e=this.castInput(e,n),t=this.castInput(t,n),e=this.removeEmpty(this.tokenize(e,n)),t=this.removeEmpty(this.tokenize(t,n));var l=t.length,c=e.length,u=1,f=l+c;n.maxEditLength!=null&&(f=Math.min(f,n.maxEditLength));var d=(r=n.timeout)!==null&&r!==void 0?r:1/0,m=Date.now()+d,g=[{oldPos:-1,lastComponent:void 0}],y=this.extractCommon(g[0],t,e,0,n);if(g[0].oldPos+1>=c&&y+1>=l)return a(lh(o,g[0].lastComponent,t,e,o.useLongestToken));var b=-1/0,w=1/0;function S(){for(var O=Math.max(b,-u);O<=Math.min(w,u);O+=2){var E=void 0,R=g[O-1],T=g[O+1];R&&(g[O-1]=void 0);var A=!1;if(T){var C=T.oldPos-O;A=T&&0<=C&&C=c&&y+1>=l)return a(lh(o,E.lastComponent,t,e,o.useLongestToken));g[O]=E,E.oldPos+1>=c&&(w=Math.min(w,O-1)),y+1>=l&&(b=Math.max(b,O+1))}u++}if(s)(function O(){setTimeout(function(){if(u>f||Date.now()>m)return s();S()||O()},0)})();else for(;u<=f&&Date.now()<=m;){var k=S();if(k)return k}},addToPath:function(e,t,r,n,s){var o=e.lastComponent;return o&&!s.oneChangePerToken&&o.added===t&&o.removed===r?{oldPos:e.oldPos+n,lastComponent:{count:o.count+1,added:t,removed:r,previousComponent:o.previousComponent}}:{oldPos:e.oldPos+n,lastComponent:{count:1,added:t,removed:r,previousComponent:o}}},extractCommon:function(e,t,r,n,s){for(var o=t.length,a=r.length,l=e.oldPos,c=l-n,u=0;c+1m.length?y:m}),f.value=i.join(d)}else f.value=i.join(t.slice(c,c+f.count));c+=f.count,f.added||(u+=f.count)}}return s}var k_=new It;function C_(i,e,t){return k_.diff(i,e,t)}function ch(i,e){var t;for(t=0;te.length&&(t=i.length-e.length);var r=e.length;i.length0&&e[o]!=e[s];)s=n[s];e[o]==e[s]&&s++}s=0;for(var a=t;a0&&i[a]!=e[s];)s=n[s];i[a]==e[s]&&s++}return s}function A_(i){return i.includes(`\r +`)&&!i.startsWith(` +`)&&!i.match(/[^\r]\n/)}function I_(i){return!i.includes(`\r +`)&&i.includes(` +`)}var Ss="a-zA-Z0-9_\\u{C0}-\\u{FF}\\u{D8}-\\u{F6}\\u{F8}-\\u{2C6}\\u{2C8}-\\u{2D7}\\u{2DE}-\\u{2FF}\\u{1E00}-\\u{1EFF}",N_=new RegExp("[".concat(Ss,"]+|\\s+|[^").concat(Ss,"]"),"ug"),sn=new It;sn.equals=function(i,e,t){return t.ignoreCase&&(i=i.toLowerCase(),e=e.toLowerCase()),i.trim()===e.trim()};sn.tokenize=function(i){var e=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{},t;if(e.intlSegmenter){if(e.intlSegmenter.resolvedOptions().granularity!="word")throw new Error('The segmenter passed must have a granularity of "word"');t=Array.from(e.intlSegmenter.segment(i),function(s){return s.segment})}else t=i.match(N_)||[];var r=[],n=null;return t.forEach(function(s){/\s/.test(s)?n==null?r.push(s):r.push(r.pop()+s):/\s/.test(n)?r[r.length-1]==n?r.push(r.pop()+s):r.push(n+s):r.push(s),n=s}),r};sn.join=function(i){return i.map(function(e,t){return t==0?e:e.replace(/^\s+/,"")}).join("")};sn.postProcess=function(i,e){if(!i||e.oneChangePerToken)return i;var t=null,r=null,n=null;return i.forEach(function(s){s.added?r=s:s.removed?n=s:((r||n)&&hh(t,n,r,s),t=s,r=null,n=null)}),(r||n)&&hh(t,n,r,null),i};function B_(i,e,t){return(t==null?void 0:t.ignoreWhitespace)!=null&&!t.ignoreWhitespace?Eh(i,e,t):sn.diff(i,e,t)}function hh(i,e,t,r){if(e&&t){var n=e.value.match(/^\s*/)[0],s=e.value.match(/\s*$/)[0],o=t.value.match(/^\s*/)[0],a=t.value.match(/\s*$/)[0];if(i){var l=ch(n,o);i.value=Na(i.value,o,l),e.value=nn(e.value,l),t.value=nn(t.value,l)}if(r){var c=uh(s,a);r.value=Ia(r.value,a,c),e.value=ws(e.value,c),t.value=ws(t.value,c)}}else if(t)i&&(t.value=t.value.replace(/^\s*/,"")),r&&(r.value=r.value.replace(/^\s*/,""));else if(i&&r){var u=r.value.match(/^\s*/)[0],f=e.value.match(/^\s*/)[0],d=e.value.match(/\s*$/)[0],m=ch(u,f);e.value=nn(e.value,m);var g=uh(nn(u,m),d);e.value=ws(e.value,g),r.value=Ia(r.value,u,g),i.value=Na(i.value,u,u.slice(0,u.length-g.length))}else if(r){var y=r.value.match(/^\s*/)[0],b=e.value.match(/\s*$/)[0],w=fh(b,y);e.value=ws(e.value,w)}else if(i){var S=i.value.match(/\s*$/)[0],k=e.value.match(/^\s*/)[0],O=fh(S,k);e.value=nn(e.value,O)}}var Sh=new It;Sh.tokenize=function(i){var e=new RegExp("(\\r?\\n)|[".concat(Ss,"]+|[^\\S\\n\\r]+|[^").concat(Ss,"]"),"ug");return i.match(e)||[]};function Eh(i,e,t){return Sh.diff(i,e,t)}function L_(i,e){if(typeof i=="function")e.callback=i;else if(i)for(var t in i)i.hasOwnProperty(t)&&(e[t]=i[t]);return e}var on=new It;on.tokenize=function(i,e){e.stripTrailingCr&&(i=i.replace(/\r\n/g,` +`));var t=[],r=i.split(/(\n|\r\n)/);r[r.length-1]||r.pop();for(var n=0;ni.length)&&(e=i.length);for(var t=0,r=new Array(e);t2&&arguments[2]!==void 0?arguments[2]:{};if(typeof e=="string"&&(e=Ts(e)),Array.isArray(e)){if(e.length>1)throw new Error("applyPatch only works with a single input.");e=e[0]}(t.autoConvertLineEndings||t.autoConvertLineEndings==null)&&(A_(i)&&W_(e)?e=Ch(e):I_(i)&&Y_(e)&&(e=Th(e)));var r=i.split(` +`),n=e.hunks,s=t.compareLine||function(P,U,F,H){return U===H},o=t.fuzzFactor||0,a=0;if(o<0||!Number.isInteger(o))throw new Error("fuzzFactor must be a non-negative integer");if(!n.length)return i;for(var l="",c=!1,u=!1,f=0;f3&&arguments[3]!==void 0?arguments[3]:0,j=arguments.length>4&&arguments[4]!==void 0?arguments[4]:!0,V=arguments.length>5&&arguments[5]!==void 0?arguments[5]:[],Y=arguments.length>6&&arguments[6]!==void 0?arguments[6]:0,Q=0,W=!1;H0?de[0]:" ",ne=de.length>0?de.substr(1):de;if(ae==="-")if(s(U+1,r[U],ae,ne))U++,Q=0;else return!F||r[U]==null?null:(V[Y]=r[U],m(P,U+1,F-1,H,!1,V,Y+1));if(ae==="+"){if(!j)return null;V[Y]=ne,Y++,Q=0,W=!0}if(ae===" ")if(Q++,V[Y]=r[U],s(U+1,r[U],ae,ne))Y++,j=!0,W=!1,U++;else return W||!F?null:r[U]&&(m(P,U+1,F-1,H+1,!1,V,Y+1)||m(P,U+1,F-1,H,!1,V,Y+1))||m(P,U,F-1,H+1,!1,V,Y)}return Y-=Q,U-=Q,V.length=Y,{patchedLines:V,oldLineLastI:U-1}}for(var g=[],y=0,b=0;b0?f(U.lines.slice(-o.context)):[],m-=y.length,g-=y.length)}(P=y).push.apply(P,ai(B.map(function(Y){return(C.added?"+":"-")+Y}))),C.added?w+=B.length:b+=B.length}else{if(m)if(B.length<=o.context*2&&ki.length)return!1;for(var t=0;t"):r.removed&&e.push(""),e.push(ow(r.value)),r.added?e.push(""):r.removed&&e.push("")}return e.join("")}function ow(i){var e=i;return e=e.replace(/&/g,"&"),e=e.replace(//g,">"),e=e.replace(/"/g,"""),e}var hb=$e(Mh()),bb=$e(Fh()),_b=$e(Zh()),pb=$e(np()),db=$e(hp()),mb=$e(Lp()),gb=$e(Yp()),wb=$e($d());var tm=$e(em(),1),{program:im,createCommand:B2,createArgument:L2,createOption:R2,CommanderError:P2,InvalidArgumentError:M2,InvalidOptionArgumentError:q2,Command:F2,Argument:D2,Option:rm,Help:j2}=tm.default;var vb=$e(lm()),xb=$e($m());var uO=$e(Wm(),1),kc=$e(mc(),1),Cc=$e(vc(),1),Hg=$e(Ec(),1),Tc=$e(Vg(),1);var Gg=Hg.default;var yb=$e(Ly()),tI=ub.default,iI=fb.default,rI=Fa,nI=hb.default,sI=pb.default,oI=cb(),aI=oI,lI=db.default,cI=mb.default,uI=gb.default,fI=vb.default,hI=Gg,pI=Tc.default,dI=kc.default,mI=Cc.default,gI=yb.default;0&&(module.exports={HttpsProxyAgent,PNG,ProgramOption,SocksProxyAgent,colors,debug,diff,dotenv,getProxyForUrl,jpegjs,lockfile,mime,minimatch,open,program,progress,ws,wsReceiver,wsSender,wsServer,yaml}); +/*! Bundled license information: + +progress/lib/node-progress.js: + (*! + * node-progress + * Copyright(c) 2011 TJ Holowaychuk + * MIT Licensed + *) +*/ diff --git a/skills/playwright-scraper-skill-1-2-0/node_modules/playwright-core/lib/utilsBundleImpl/xdg-open b/skills/playwright-scraper-skill-1-2-0/node_modules/playwright-core/lib/utilsBundleImpl/xdg-open new file mode 100755 index 0000000..b392fbf --- /dev/null +++ b/skills/playwright-scraper-skill-1-2-0/node_modules/playwright-core/lib/utilsBundleImpl/xdg-open @@ -0,0 +1,1066 @@ +#!/bin/sh +#--------------------------------------------- +# xdg-open +# +# Utility script to open a URL in the registered default application. +# +# Refer to the usage() function below for usage. +# +# Copyright 2009-2010, Fathi Boudra +# Copyright 2009-2010, Rex Dieter +# Copyright 2006, Kevin Krammer +# Copyright 2006, Jeremy White +# +# LICENSE: +# +# Permission is hereby granted, free of charge, to any person obtaining a +# copy of this software and associated documentation files (the "Software"), +# to deal in the Software without restriction, including without limitation +# the rights to use, copy, modify, merge, publish, distribute, sublicense, +# and/or sell copies of the Software, and to permit persons to whom the +# Software is furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR +# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +# OTHER DEALINGS IN THE SOFTWARE. +# +#--------------------------------------------- + +manualpage() +{ +cat << _MANUALPAGE +Name + + xdg-open -- opens a file or URL in the user's preferred + application + +Synopsis + + xdg-open { file | URL } + + xdg-open { --help | --manual | --version } + +Description + + xdg-open opens a file or URL in the user's preferred + application. If a URL is provided the URL will be opened in the + user's preferred web browser. If a file is provided the file + will be opened in the preferred application for files of that + type. xdg-open supports file, ftp, http and https URLs. + + xdg-open is for use inside a desktop session only. It is not + recommended to use xdg-open as root. + +Options + + --help + Show command synopsis. + + --manual + Show this manual page. + + --version + Show the xdg-utils version information. + +Exit Codes + + An exit code of 0 indicates success while a non-zero exit code + indicates failure. The following failure codes can be returned: + + 1 + Error in command line syntax. + + 2 + One of the files passed on the command line did not + exist. + + 3 + A required tool could not be found. + + 4 + The action failed. + +See Also + + xdg-mime(1), xdg-settings(1), MIME applications associations + specification + +Examples + +xdg-open 'http://www.freedesktop.org/' + + Opens the freedesktop.org website in the user's default + browser. + +xdg-open /tmp/foobar.png + + Opens the PNG image file /tmp/foobar.png in the user's default + image viewing application. +_MANUALPAGE +} + +usage() +{ +cat << _USAGE + xdg-open -- opens a file or URL in the user's preferred + application + +Synopsis + + xdg-open { file | URL } + + xdg-open { --help | --manual | --version } + +_USAGE +} + +#@xdg-utils-common@ + +#---------------------------------------------------------------------------- +# Common utility functions included in all XDG wrapper scripts +#---------------------------------------------------------------------------- + +DEBUG() +{ + [ -z "${XDG_UTILS_DEBUG_LEVEL}" ] && return 0; + [ ${XDG_UTILS_DEBUG_LEVEL} -lt $1 ] && return 0; + shift + echo "$@" >&2 +} + +# This handles backslashes but not quote marks. +first_word() +{ + read first rest + echo "$first" +} + +#------------------------------------------------------------- +# map a binary to a .desktop file +binary_to_desktop_file() +{ + search="${XDG_DATA_HOME:-$HOME/.local/share}:${XDG_DATA_DIRS:-/usr/local/share:/usr/share}" + binary="`which "$1"`" + binary="`readlink -f "$binary"`" + base="`basename "$binary"`" + IFS=: + for dir in $search; do + unset IFS + [ "$dir" ] || continue + [ -d "$dir/applications" ] || [ -d "$dir/applnk" ] || continue + for file in "$dir"/applications/*.desktop "$dir"/applications/*/*.desktop "$dir"/applnk/*.desktop "$dir"/applnk/*/*.desktop; do + [ -r "$file" ] || continue + # Check to make sure it's worth the processing. + grep -q "^Exec.*$base" "$file" || continue + # Make sure it's a visible desktop file (e.g. not "preferred-web-browser.desktop"). + grep -Eq "^(NoDisplay|Hidden)=true" "$file" && continue + command="`grep -E "^Exec(\[[^]=]*])?=" "$file" | cut -d= -f 2- | first_word`" + command="`which "$command"`" + if [ x"`readlink -f "$command"`" = x"$binary" ]; then + # Fix any double slashes that got added path composition + echo "$file" | sed -e 's,//*,/,g' + return + fi + done + done +} + +#------------------------------------------------------------- +# map a .desktop file to a binary +desktop_file_to_binary() +{ + search="${XDG_DATA_HOME:-$HOME/.local/share}:${XDG_DATA_DIRS:-/usr/local/share:/usr/share}" + desktop="`basename "$1"`" + IFS=: + for dir in $search; do + unset IFS + [ "$dir" ] && [ -d "$dir/applications" ] || [ -d "$dir/applnk" ] || continue + # Check if desktop file contains - + if [ "${desktop#*-}" != "$desktop" ]; then + vendor=${desktop%-*} + app=${desktop#*-} + if [ -r $dir/applications/$vendor/$app ]; then + file_path=$dir/applications/$vendor/$app + elif [ -r $dir/applnk/$vendor/$app ]; then + file_path=$dir/applnk/$vendor/$app + fi + fi + if test -z "$file_path" ; then + for indir in "$dir"/applications/ "$dir"/applications/*/ "$dir"/applnk/ "$dir"/applnk/*/; do + file="$indir/$desktop" + if [ -r "$file" ]; then + file_path=$file + break + fi + done + fi + if [ -r "$file_path" ]; then + # Remove any arguments (%F, %f, %U, %u, etc.). + command="`grep -E "^Exec(\[[^]=]*])?=" "$file_path" | cut -d= -f 2- | first_word`" + command="`which "$command"`" + readlink -f "$command" + return + fi + done +} + +#------------------------------------------------------------- +# Exit script on successfully completing the desired operation + +exit_success() +{ + if [ $# -gt 0 ]; then + echo "$@" + echo + fi + + exit 0 +} + + +#----------------------------------------- +# Exit script on malformed arguments, not enough arguments +# or missing required option. +# prints usage information + +exit_failure_syntax() +{ + if [ $# -gt 0 ]; then + echo "xdg-open: $@" >&2 + echo "Try 'xdg-open --help' for more information." >&2 + else + usage + echo "Use 'man xdg-open' or 'xdg-open --manual' for additional info." + fi + + exit 1 +} + +#------------------------------------------------------------- +# Exit script on missing file specified on command line + +exit_failure_file_missing() +{ + if [ $# -gt 0 ]; then + echo "xdg-open: $@" >&2 + fi + + exit 2 +} + +#------------------------------------------------------------- +# Exit script on failure to locate necessary tool applications + +exit_failure_operation_impossible() +{ + if [ $# -gt 0 ]; then + echo "xdg-open: $@" >&2 + fi + + exit 3 +} + +#------------------------------------------------------------- +# Exit script on failure returned by a tool application + +exit_failure_operation_failed() +{ + if [ $# -gt 0 ]; then + echo "xdg-open: $@" >&2 + fi + + exit 4 +} + +#------------------------------------------------------------ +# Exit script on insufficient permission to read a specified file + +exit_failure_file_permission_read() +{ + if [ $# -gt 0 ]; then + echo "xdg-open: $@" >&2 + fi + + exit 5 +} + +#------------------------------------------------------------ +# Exit script on insufficient permission to write a specified file + +exit_failure_file_permission_write() +{ + if [ $# -gt 0 ]; then + echo "xdg-open: $@" >&2 + fi + + exit 6 +} + +check_input_file() +{ + if [ ! -e "$1" ]; then + exit_failure_file_missing "file '$1' does not exist" + fi + if [ ! -r "$1" ]; then + exit_failure_file_permission_read "no permission to read file '$1'" + fi +} + +check_vendor_prefix() +{ + file_label="$2" + [ -n "$file_label" ] || file_label="filename" + file=`basename "$1"` + case "$file" in + [[:alpha:]]*-*) + return + ;; + esac + + echo "xdg-open: $file_label '$file' does not have a proper vendor prefix" >&2 + echo 'A vendor prefix consists of alpha characters ([a-zA-Z]) and is terminated' >&2 + echo 'with a dash ("-"). An example '"$file_label"' is '"'example-$file'" >&2 + echo "Use --novendor to override or 'xdg-open --manual' for additional info." >&2 + exit 1 +} + +check_output_file() +{ + # if the file exists, check if it is writeable + # if it does not exists, check if we are allowed to write on the directory + if [ -e "$1" ]; then + if [ ! -w "$1" ]; then + exit_failure_file_permission_write "no permission to write to file '$1'" + fi + else + DIR=`dirname "$1"` + if [ ! -w "$DIR" ] || [ ! -x "$DIR" ]; then + exit_failure_file_permission_write "no permission to create file '$1'" + fi + fi +} + +#---------------------------------------- +# Checks for shared commands, e.g. --help + +check_common_commands() +{ + while [ $# -gt 0 ] ; do + parm="$1" + shift + + case "$parm" in + --help) + usage + echo "Use 'man xdg-open' or 'xdg-open --manual' for additional info." + exit_success + ;; + + --manual) + manualpage + exit_success + ;; + + --version) + echo "xdg-open 1.1.3" + exit_success + ;; + esac + done +} + +check_common_commands "$@" + +[ -z "${XDG_UTILS_DEBUG_LEVEL}" ] && unset XDG_UTILS_DEBUG_LEVEL; +if [ ${XDG_UTILS_DEBUG_LEVEL-0} -lt 1 ]; then + # Be silent + xdg_redirect_output=" > /dev/null 2> /dev/null" +else + # All output to stderr + xdg_redirect_output=" >&2" +fi + +#-------------------------------------- +# Checks for known desktop environments +# set variable DE to the desktop environments name, lowercase + +detectDE() +{ + # see https://bugs.freedesktop.org/show_bug.cgi?id=34164 + unset GREP_OPTIONS + + if [ -n "${XDG_CURRENT_DESKTOP}" ]; then + case "${XDG_CURRENT_DESKTOP}" in + # only recently added to menu-spec, pre-spec X- still in use + Cinnamon|X-Cinnamon) + DE=cinnamon; + ;; + ENLIGHTENMENT) + DE=enlightenment; + ;; + # GNOME, GNOME-Classic:GNOME, or GNOME-Flashback:GNOME + GNOME*) + DE=gnome; + ;; + KDE) + DE=kde; + ;; + # Deepin Desktop Environments + DEEPIN|Deepin|deepin) + DE=dde; + ;; + LXDE) + DE=lxde; + ;; + LXQt) + DE=lxqt; + ;; + MATE) + DE=mate; + ;; + XFCE) + DE=xfce + ;; + X-Generic) + DE=generic + ;; + esac + fi + + if [ x"$DE" = x"" ]; then + # classic fallbacks + if [ x"$KDE_FULL_SESSION" != x"" ]; then DE=kde; + elif [ x"$GNOME_DESKTOP_SESSION_ID" != x"" ]; then DE=gnome; + elif [ x"$MATE_DESKTOP_SESSION_ID" != x"" ]; then DE=mate; + elif `dbus-send --print-reply --dest=org.freedesktop.DBus /org/freedesktop/DBus org.freedesktop.DBus.GetNameOwner string:org.gnome.SessionManager > /dev/null 2>&1` ; then DE=gnome; + elif xprop -root _DT_SAVE_MODE 2> /dev/null | grep ' = \"xfce4\"$' >/dev/null 2>&1; then DE=xfce; + elif xprop -root 2> /dev/null | grep -i '^xfce_desktop_window' >/dev/null 2>&1; then DE=xfce + elif echo $DESKTOP | grep -q '^Enlightenment'; then DE=enlightenment; + elif [ x"$LXQT_SESSION_CONFIG" != x"" ]; then DE=lxqt; + fi + fi + + if [ x"$DE" = x"" ]; then + # fallback to checking $DESKTOP_SESSION + case "$DESKTOP_SESSION" in + gnome) + DE=gnome; + ;; + LXDE|Lubuntu) + DE=lxde; + ;; + MATE) + DE=mate; + ;; + xfce|xfce4|'Xfce Session') + DE=xfce; + ;; + esac + fi + + if [ x"$DE" = x"" ]; then + # fallback to uname output for other platforms + case "$(uname 2>/dev/null)" in + CYGWIN*) + DE=cygwin; + ;; + Darwin) + DE=darwin; + ;; + esac + fi + + if [ x"$DE" = x"gnome" ]; then + # gnome-default-applications-properties is only available in GNOME 2.x + # but not in GNOME 3.x + which gnome-default-applications-properties > /dev/null 2>&1 || DE="gnome3" + fi + + if [ -f "$XDG_RUNTIME_DIR/flatpak-info" ]; then + DE="flatpak" + fi +} + +#---------------------------------------------------------------------------- +# kfmclient exec/openURL can give bogus exit value in KDE <= 3.5.4 +# It also always returns 1 in KDE 3.4 and earlier +# Simply return 0 in such case + +kfmclient_fix_exit_code() +{ + version=`LC_ALL=C.UTF-8 kde-config --version 2>/dev/null | grep '^KDE'` + major=`echo $version | sed 's/KDE.*: \([0-9]\).*/\1/'` + minor=`echo $version | sed 's/KDE.*: [0-9]*\.\([0-9]\).*/\1/'` + release=`echo $version | sed 's/KDE.*: [0-9]*\.[0-9]*\.\([0-9]\).*/\1/'` + test "$major" -gt 3 && return $1 + test "$minor" -gt 5 && return $1 + test "$release" -gt 4 && return $1 + return 0 +} + +#---------------------------------------------------------------------------- +# Returns true if there is a graphical display attached. + +has_display() +{ + if [ -n "$DISPLAY" ] || [ -n "$WAYLAND_DISPLAY" ]; then + return 0 + else + return 1 + fi +} + +# This handles backslashes but not quote marks. +last_word() +{ + read first rest + echo "$rest" +} + +# Get the value of a key in a desktop file's Desktop Entry group. +# Example: Use get_key foo.desktop Exec +# to get the values of the Exec= key for the Desktop Entry group. +get_key() +{ + local file="${1}" + local key="${2}" + local desktop_entry="" + + IFS_="${IFS}" + IFS="" + while read line + do + case "$line" in + "[Desktop Entry]") + desktop_entry="y" + ;; + # Reset match flag for other groups + "["*) + desktop_entry="" + ;; + "${key}="*) + # Only match Desktop Entry group + if [ -n "${desktop_entry}" ] + then + echo "${line}" | cut -d= -f 2- + fi + esac + done < "${file}" + IFS="${IFS_}" +} + +# Returns true if argument is a file:// URL or path +is_file_url_or_path() +{ + if echo "$1" | grep -q '^file://' \ + || ! echo "$1" | egrep -q '^[[:alpha:]+\.\-]+:'; then + return 0 + else + return 1 + fi +} + +# If argument is a file URL, convert it to a (percent-decoded) path. +# If not, leave it as it is. +file_url_to_path() +{ + local file="$1" + if echo "$file" | grep -q '^file:///'; then + file=${file#file://} + file=${file%%#*} + file=$(echo "$file" | sed -r 's/\?.*$//') + local printf=printf + if [ -x /usr/bin/printf ]; then + printf=/usr/bin/printf + fi + file=$($printf "$(echo "$file" | sed -e 's@%\([a-f0-9A-F]\{2\}\)@\\x\1@g')") + fi + echo "$file" +} + +open_cygwin() +{ + cygstart "$1" + + if [ $? -eq 0 ]; then + exit_success + else + exit_failure_operation_failed + fi +} + +open_darwin() +{ + open "$1" + + if [ $? -eq 0 ]; then + exit_success + else + exit_failure_operation_failed + fi +} + +open_kde() +{ + if [ -n "${KDE_SESSION_VERSION}" ]; then + case "${KDE_SESSION_VERSION}" in + 4) + kde-open "$1" + ;; + 5) + kde-open${KDE_SESSION_VERSION} "$1" + ;; + esac + else + kfmclient exec "$1" + kfmclient_fix_exit_code $? + fi + + if [ $? -eq 0 ]; then + exit_success + else + exit_failure_operation_failed + fi +} + +open_dde() +{ + if dde-open -version >/dev/null 2>&1; then + dde-open "$1" + else + open_generic "$1" + fi + + if [ $? -eq 0 ]; then + exit_success + else + exit_failure_operation_failed + fi +} + +open_gnome3() +{ + if gio help open 2>/dev/null 1>&2; then + gio open "$1" + elif gvfs-open --help 2>/dev/null 1>&2; then + gvfs-open "$1" + else + open_generic "$1" + fi + + if [ $? -eq 0 ]; then + exit_success + else + exit_failure_operation_failed + fi +} + +open_gnome() +{ + if gio help open 2>/dev/null 1>&2; then + gio open "$1" + elif gvfs-open --help 2>/dev/null 1>&2; then + gvfs-open "$1" + elif gnome-open --help 2>/dev/null 1>&2; then + gnome-open "$1" + else + open_generic "$1" + fi + + if [ $? -eq 0 ]; then + exit_success + else + exit_failure_operation_failed + fi +} + +open_mate() +{ + if gio help open 2>/dev/null 1>&2; then + gio open "$1" + elif gvfs-open --help 2>/dev/null 1>&2; then + gvfs-open "$1" + elif mate-open --help 2>/dev/null 1>&2; then + mate-open "$1" + else + open_generic "$1" + fi + + if [ $? -eq 0 ]; then + exit_success + else + exit_failure_operation_failed + fi +} + +open_xfce() +{ + if exo-open --help 2>/dev/null 1>&2; then + exo-open "$1" + elif gio help open 2>/dev/null 1>&2; then + gio open "$1" + elif gvfs-open --help 2>/dev/null 1>&2; then + gvfs-open "$1" + else + open_generic "$1" + fi + + if [ $? -eq 0 ]; then + exit_success + else + exit_failure_operation_failed + fi +} + +open_enlightenment() +{ + if enlightenment_open --help 2>/dev/null 1>&2; then + enlightenment_open "$1" + else + open_generic "$1" + fi + + if [ $? -eq 0 ]; then + exit_success + else + exit_failure_operation_failed + fi +} + +open_flatpak() +{ + gdbus call --session \ + --dest org.freedesktop.portal.Desktop \ + --object-path /org/freedesktop/portal/desktop \ + --method org.freedesktop.portal.OpenURI.OpenURI \ + "" "$1" {} + + if [ $? -eq 0 ]; then + exit_success + else + exit_failure_operation_failed + fi +} + +#----------------------------------------- +# Recursively search .desktop file + +search_desktop_file() +{ + local default="$1" + local dir="$2" + local target="$3" + + local file="" + # look for both vendor-app.desktop, vendor/app.desktop + if [ -r "$dir/$default" ]; then + file="$dir/$default" + elif [ -r "$dir/`echo $default | sed -e 's|-|/|'`" ]; then + file="$dir/`echo $default | sed -e 's|-|/|'`" + fi + + if [ -r "$file" ] ; then + command="$(get_key "${file}" "Exec" | first_word)" + command_exec=`which $command 2>/dev/null` + icon="$(get_key "${file}" "Icon")" + # FIXME: Actually LC_MESSAGES should be used as described in + # http://standards.freedesktop.org/desktop-entry-spec/latest/ar01s04.html + localised_name="$(get_key "${file}" "Name")" + set -- $(get_key "${file}" "Exec" | last_word) + # We need to replace any occurrence of "%f", "%F" and + # the like by the target file. We examine each + # argument and append the modified argument to the + # end then shift. + local args=$# + local replaced=0 + while [ $args -gt 0 ]; do + case $1 in + %[c]) + replaced=1 + arg="${localised_name}" + shift + set -- "$@" "$arg" + ;; + %[fFuU]) + replaced=1 + arg="$target" + shift + set -- "$@" "$arg" + ;; + %[i]) + replaced=1 + shift + set -- "$@" "--icon" "$icon" + ;; + *) + arg="$1" + shift + set -- "$@" "$arg" + ;; + esac + args=$(( $args - 1 )) + done + [ $replaced -eq 1 ] || set -- "$@" "$target" + "$command_exec" "$@" + + if [ $? -eq 0 ]; then + exit_success + fi + fi + + for d in $dir/*/; do + [ -d "$d" ] && search_desktop_file "$default" "$d" "$target" + done +} + + +open_generic_xdg_mime() +{ + filetype="$2" + default=`xdg-mime query default "$filetype"` + if [ -n "$default" ] ; then + xdg_user_dir="$XDG_DATA_HOME" + [ -n "$xdg_user_dir" ] || xdg_user_dir="$HOME/.local/share" + + xdg_system_dirs="$XDG_DATA_DIRS" + [ -n "$xdg_system_dirs" ] || xdg_system_dirs=/usr/local/share/:/usr/share/ + +DEBUG 3 "$xdg_user_dir:$xdg_system_dirs" + for x in `echo "$xdg_user_dir:$xdg_system_dirs" | sed 's/:/ /g'`; do + search_desktop_file "$default" "$x/applications/" "$1" + done + fi +} + +open_generic_xdg_file_mime() +{ + filetype=`xdg-mime query filetype "$1" | sed "s/;.*//"` + open_generic_xdg_mime "$1" "$filetype" +} + +open_generic_xdg_x_scheme_handler() +{ + scheme="`echo $1 | sed -n 's/\(^[[:alnum:]+\.-]*\):.*$/\1/p'`" + if [ -n $scheme ]; then + filetype="x-scheme-handler/$scheme" + open_generic_xdg_mime "$1" "$filetype" + fi +} + +has_single_argument() +{ + test $# = 1 +} + +open_envvar() +{ + local oldifs="$IFS" + local browser browser_with_arg + + IFS=":" + for browser in $BROWSER; do + IFS="$oldifs" + + if [ -z "$browser" ]; then + continue + fi + + if echo "$browser" | grep -q %s; then + # Avoid argument injection. + # See https://bugs.freedesktop.org/show_bug.cgi?id=103807 + # URIs don't have IFS characters spaces anyway. + has_single_argument $1 && $(printf "$browser" "$1") + else + $browser "$1" + fi + + if [ $? -eq 0 ]; then + exit_success + fi + done +} + +open_generic() +{ + if is_file_url_or_path "$1"; then + local file="$(file_url_to_path "$1")" + + check_input_file "$file" + + if has_display; then + filetype=`xdg-mime query filetype "$file" | sed "s/;.*//"` + open_generic_xdg_mime "$file" "$filetype" + fi + + if which run-mailcap 2>/dev/null 1>&2; then + run-mailcap --action=view "$file" + if [ $? -eq 0 ]; then + exit_success + fi + fi + + if has_display && mimeopen -v 2>/dev/null 1>&2; then + mimeopen -L -n "$file" + if [ $? -eq 0 ]; then + exit_success + fi + fi + fi + + if has_display; then + open_generic_xdg_x_scheme_handler "$1" + fi + + if [ -n "$BROWSER" ]; then + open_envvar "$1" + fi + + # if BROWSER variable is not set, check some well known browsers instead + if [ x"$BROWSER" = x"" ]; then + BROWSER=www-browser:links2:elinks:links:lynx:w3m + if has_display; then + BROWSER=x-www-browser:firefox:iceweasel:seamonkey:mozilla:epiphany:konqueror:chromium:chromium-browser:google-chrome:microsoft-edge:$BROWSER + fi + fi + + open_envvar "$1" + + exit_failure_operation_impossible "no method available for opening '$1'" +} + +open_lxde() +{ + + # pcmanfm only knows how to handle file:// urls and filepaths, it seems. + if pcmanfm --help >/dev/null 2>&1 && is_file_url_or_path "$1"; then + local file="$(file_url_to_path "$1")" + + # handle relative paths + if ! echo "$file" | grep -q ^/; then + file="$(pwd)/$file" + fi + + pcmanfm "$file" + else + open_generic "$1" + fi + + if [ $? -eq 0 ]; then + exit_success + else + exit_failure_operation_failed + fi +} + +open_lxqt() +{ + open_generic "$1" +} + +[ x"$1" != x"" ] || exit_failure_syntax + +url= +while [ $# -gt 0 ] ; do + parm="$1" + shift + + case "$parm" in + -*) + exit_failure_syntax "unexpected option '$parm'" + ;; + + *) + if [ -n "$url" ] ; then + exit_failure_syntax "unexpected argument '$parm'" + fi + url="$parm" + ;; + esac +done + +if [ -z "${url}" ] ; then + exit_failure_syntax "file or URL argument missing" +fi + +detectDE + +if [ x"$DE" = x"" ]; then + DE=generic +fi + +DEBUG 2 "Selected DE $DE" + +# sanitize BROWSER (avoid caling ourselves in particular) +case "${BROWSER}" in + *:"xdg-open"|"xdg-open":*) + BROWSER=$(echo $BROWSER | sed -e 's|:xdg-open||g' -e 's|xdg-open:||g') + ;; + "xdg-open") + BROWSER= + ;; +esac + +case "$DE" in + kde) + open_kde "$url" + ;; + + dde) + open_dde "$url" + ;; + + gnome3|cinnamon) + open_gnome3 "$url" + ;; + + gnome) + open_gnome "$url" + ;; + + mate) + open_mate "$url" + ;; + + xfce) + open_xfce "$url" + ;; + + lxde) + open_lxde "$url" + ;; + + lxqt) + open_lxqt "$url" + ;; + + enlightenment) + open_enlightenment "$url" + ;; + + cygwin) + open_cygwin "$url" + ;; + + darwin) + open_darwin "$url" + ;; + + flatpak) + open_flatpak "$url" + ;; + + generic) + open_generic "$url" + ;; + + *) + exit_failure_operation_impossible "no method available for opening '$url'" + ;; +esac diff --git a/skills/playwright-scraper-skill-1-2-0/node_modules/playwright-core/lib/vite/htmlReport/index.html b/skills/playwright-scraper-skill-1-2-0/node_modules/playwright-core/lib/vite/htmlReport/index.html new file mode 100644 index 0000000..57669b2 --- /dev/null +++ b/skills/playwright-scraper-skill-1-2-0/node_modules/playwright-core/lib/vite/htmlReport/index.html @@ -0,0 +1,84 @@ + + + + + + + + + Playwright Test Report + + + + +
+ + diff --git a/skills/playwright-scraper-skill-1-2-0/node_modules/playwright-core/lib/vite/recorder/assets/codeMirrorModule-DYBRYzYX.css b/skills/playwright-scraper-skill-1-2-0/node_modules/playwright-core/lib/vite/recorder/assets/codeMirrorModule-DYBRYzYX.css new file mode 100644 index 0000000..132b892 --- /dev/null +++ b/skills/playwright-scraper-skill-1-2-0/node_modules/playwright-core/lib/vite/recorder/assets/codeMirrorModule-DYBRYzYX.css @@ -0,0 +1 @@ +.CodeMirror{font-family:monospace;height:300px;color:#000;direction:ltr}.CodeMirror-lines{padding:4px 0}.CodeMirror pre.CodeMirror-line,.CodeMirror pre.CodeMirror-line-like{padding:0 4px}.CodeMirror-scrollbar-filler,.CodeMirror-gutter-filler{background-color:#fff}.CodeMirror-gutters{border-right:1px solid #ddd;background-color:#f7f7f7;white-space:nowrap}.CodeMirror-linenumber{padding:0 3px 0 5px;min-width:20px;text-align:right;color:#999;white-space:nowrap}.CodeMirror-guttermarker{color:#000}.CodeMirror-guttermarker-subtle{color:#999}.CodeMirror-cursor{border-left:1px solid black;border-right:none;width:0}.CodeMirror div.CodeMirror-secondarycursor{border-left:1px solid silver}.cm-fat-cursor .CodeMirror-cursor{width:auto;border:0!important;background:#7e7}.cm-fat-cursor div.CodeMirror-cursors{z-index:1}.cm-fat-cursor .CodeMirror-line::selection,.cm-fat-cursor .CodeMirror-line>span::selection,.cm-fat-cursor .CodeMirror-line>span>span::selection{background:transparent}.cm-fat-cursor .CodeMirror-line::-moz-selection,.cm-fat-cursor .CodeMirror-line>span::-moz-selection,.cm-fat-cursor .CodeMirror-line>span>span::-moz-selection{background:transparent}.cm-fat-cursor{caret-color:transparent}@-moz-keyframes blink{50%{background-color:transparent}}@-webkit-keyframes blink{50%{background-color:transparent}}@keyframes blink{50%{background-color:transparent}}.cm-tab{display:inline-block;text-decoration:inherit}.CodeMirror-rulers{position:absolute;left:0;right:0;top:-50px;bottom:0;overflow:hidden}.CodeMirror-ruler{border-left:1px solid #ccc;top:0;bottom:0;position:absolute}.cm-s-default .cm-header{color:#00f}.cm-s-default .cm-quote{color:#090}.cm-negative{color:#d44}.cm-positive{color:#292}.cm-header,.cm-strong{font-weight:700}.cm-em{font-style:italic}.cm-link{text-decoration:underline}.cm-strikethrough{text-decoration:line-through}.cm-s-default .cm-keyword{color:#708}.cm-s-default .cm-atom{color:#219}.cm-s-default .cm-number{color:#164}.cm-s-default .cm-def{color:#00f}.cm-s-default .cm-variable-2{color:#05a}.cm-s-default .cm-variable-3,.cm-s-default .cm-type{color:#085}.cm-s-default .cm-comment{color:#a50}.cm-s-default .cm-string{color:#a11}.cm-s-default .cm-string-2{color:#f50}.cm-s-default .cm-meta,.cm-s-default .cm-qualifier{color:#555}.cm-s-default .cm-builtin{color:#30a}.cm-s-default .cm-bracket{color:#997}.cm-s-default .cm-tag{color:#170}.cm-s-default .cm-attribute{color:#00c}.cm-s-default .cm-hr{color:#999}.cm-s-default .cm-link{color:#00c}.cm-s-default .cm-error,.cm-invalidchar{color:red}.CodeMirror-composing{border-bottom:2px solid}div.CodeMirror span.CodeMirror-matchingbracket{color:#0b0}div.CodeMirror span.CodeMirror-nonmatchingbracket{color:#a22}.CodeMirror-matchingtag{background:#ff96004d}.CodeMirror-activeline-background{background:#e8f2ff}.CodeMirror{position:relative;overflow:hidden;background:#fff}.CodeMirror-scroll{overflow:scroll!important;margin-bottom:-50px;margin-right:-50px;padding-bottom:50px;height:100%;outline:none;position:relative;z-index:0}.CodeMirror-sizer{position:relative;border-right:50px solid transparent}.CodeMirror-vscrollbar,.CodeMirror-hscrollbar,.CodeMirror-scrollbar-filler,.CodeMirror-gutter-filler{position:absolute;z-index:6;display:none;outline:none}.CodeMirror-vscrollbar{right:0;top:0;overflow-x:hidden;overflow-y:scroll}.CodeMirror-hscrollbar{bottom:0;left:0;overflow-y:hidden;overflow-x:scroll}.CodeMirror-scrollbar-filler{right:0;bottom:0}.CodeMirror-gutter-filler{left:0;bottom:0}.CodeMirror-gutters{position:absolute;left:0;top:0;min-height:100%;z-index:3}.CodeMirror-gutter{white-space:normal;height:100%;display:inline-block;vertical-align:top;margin-bottom:-50px}.CodeMirror-gutter-wrapper{position:absolute;z-index:4;background:none!important;border:none!important}.CodeMirror-gutter-background{position:absolute;top:0;bottom:0;z-index:4}.CodeMirror-gutter-elt{position:absolute;cursor:default;z-index:4}.CodeMirror-gutter-wrapper ::selection{background-color:transparent}.CodeMirror-gutter-wrapper ::-moz-selection{background-color:transparent}.CodeMirror-lines{cursor:text;min-height:1px}.CodeMirror pre.CodeMirror-line,.CodeMirror pre.CodeMirror-line-like{-moz-border-radius:0;-webkit-border-radius:0;border-radius:0;border-width:0;background:transparent;font-family:inherit;font-size:inherit;margin:0;white-space:pre;word-wrap:normal;line-height:inherit;color:inherit;z-index:2;position:relative;overflow:visible;-webkit-tap-highlight-color:transparent;-webkit-font-variant-ligatures:contextual;font-variant-ligatures:contextual}.CodeMirror-wrap pre.CodeMirror-line,.CodeMirror-wrap pre.CodeMirror-line-like{word-wrap:break-word;white-space:pre-wrap;word-break:normal}.CodeMirror-linebackground{position:absolute;left:0;right:0;top:0;bottom:0;z-index:0}.CodeMirror-linewidget{position:relative;z-index:2;padding:.1px}.CodeMirror-rtl pre{direction:rtl}.CodeMirror-code{outline:none}.CodeMirror-scroll,.CodeMirror-sizer,.CodeMirror-gutter,.CodeMirror-gutters,.CodeMirror-linenumber{-moz-box-sizing:content-box;box-sizing:content-box}.CodeMirror-measure{position:absolute;width:100%;height:0;overflow:hidden;visibility:hidden}.CodeMirror-cursor{position:absolute;pointer-events:none}.CodeMirror-measure pre{position:static}div.CodeMirror-cursors{visibility:hidden;position:relative;z-index:3}div.CodeMirror-dragcursors,.CodeMirror-focused div.CodeMirror-cursors{visibility:visible}.CodeMirror-selected{background:#d9d9d9}.CodeMirror-focused .CodeMirror-selected{background:#d7d4f0}.CodeMirror-crosshair{cursor:crosshair}.CodeMirror-line::selection,.CodeMirror-line>span::selection,.CodeMirror-line>span>span::selection{background:#d7d4f0}.CodeMirror-line::-moz-selection,.CodeMirror-line>span::-moz-selection,.CodeMirror-line>span>span::-moz-selection{background:#d7d4f0}.cm-searching{background-color:#ffa;background-color:#ff06}.cm-force-border{padding-right:.1px}@media print{.CodeMirror div.CodeMirror-cursors{visibility:hidden}}.cm-tab-wrap-hack:after{content:""}span.CodeMirror-selectedtext{background:none}.CodeMirror-dialog{position:absolute;left:0;right:0;background:inherit;z-index:15;padding:.1em .8em;overflow:hidden;color:inherit}.CodeMirror-dialog-top{border-bottom:1px solid #eee;top:0}.CodeMirror-dialog-bottom{border-top:1px solid #eee;bottom:0}.CodeMirror-dialog input{border:none;outline:none;background:transparent;width:20em;color:inherit;font-family:monospace}.CodeMirror-dialog button{font-size:70%} diff --git a/skills/playwright-scraper-skill-1-2-0/node_modules/playwright-core/lib/vite/recorder/assets/codeMirrorModule-DadYNm1I.js b/skills/playwright-scraper-skill-1-2-0/node_modules/playwright-core/lib/vite/recorder/assets/codeMirrorModule-DadYNm1I.js new file mode 100644 index 0000000..aec9e63 --- /dev/null +++ b/skills/playwright-scraper-skill-1-2-0/node_modules/playwright-core/lib/vite/recorder/assets/codeMirrorModule-DadYNm1I.js @@ -0,0 +1,32 @@ +import{g as Ju}from"./index-BhTWtUlo.js";var vi={exports:{}},Zu=vi.exports,pa;function mt(){return pa||(pa=1,(function(ct,xt){(function(b,pe){ct.exports=pe()})(Zu,(function(){var b=navigator.userAgent,pe=navigator.platform,_=/gecko\/\d/i.test(b),te=/MSIE \d/.test(b),oe=/Trident\/(?:[7-9]|\d{2,})\..*rv:(\d+)/.exec(b),Q=/Edge\/(\d+)/.exec(b),k=te||oe||Q,I=k&&(te?document.documentMode||6:+(Q||oe)[1]),Y=!Q&&/WebKit\//.test(b),ne=Y&&/Qt\/\d+\.\d+/.test(b),S=!Q&&/Chrome\/(\d+)/.exec(b),R=S&&+S[1],A=/Opera\//.test(b),V=/Apple Computer/.test(navigator.vendor),ue=/Mac OS X 1\d\D([8-9]|\d\d)\D/.test(b),O=/PhantomJS/.test(b),w=V&&(/Mobile\/\w+/.test(b)||navigator.maxTouchPoints>2),M=/Android/.test(b),N=w||M||/webOS|BlackBerry|Opera Mini|Opera Mobi|IEMobile/i.test(b),z=w||/Mac/.test(pe),X=/\bCrOS\b/.test(b),q=/win/i.test(pe),p=A&&b.match(/Version\/(\d*\.\d*)/);p&&(p=Number(p[1])),p&&p>=15&&(A=!1,Y=!0);var W=z&&(ne||A&&(p==null||p<12.11)),J=_||k&&I>=9;function P(e){return new RegExp("(^|\\s)"+e+"(?:$|\\s)\\s*")}var $=function(e,t){var n=e.className,r=P(t).exec(n);if(r){var i=n.slice(r.index+r[0].length);e.className=n.slice(0,r.index)+(i?r[1]+i:"")}};function F(e){for(var t=e.childNodes.length;t>0;--t)e.removeChild(e.firstChild);return e}function G(e,t){return F(e).appendChild(t)}function c(e,t,n,r){var i=document.createElement(e);if(n&&(i.className=n),r&&(i.style.cssText=r),typeof t=="string")i.appendChild(document.createTextNode(t));else if(t)for(var o=0;o=t)return l+(t-o);l+=a-o,l+=n-l%n,o=a+1}}var Ce=function(){this.id=null,this.f=null,this.time=0,this.handler=xe(this.onTimeout,this)};Ce.prototype.onTimeout=function(e){e.id=0,e.time<=+new Date?e.f():setTimeout(e.handler,e.time-+new Date)},Ce.prototype.set=function(e,t){this.f=t;var n=+new Date+e;(!this.id||n=t)return r+Math.min(l,t-i);if(i+=o-r,i+=n-i%n,r=o+1,i>=t)return r}}var Ue=[""];function et(e){for(;Ue.length<=e;)Ue.push(we(Ue)+" ");return Ue[e]}function we(e){return e[e.length-1]}function Ie(e,t){for(var n=[],r=0;r"€"&&(e.toUpperCase()!=e.toLowerCase()||ze.test(e))}function De(e,t){return t?t.source.indexOf("\\w")>-1&&me(e)?!0:t.test(e):me(e)}function be(e){for(var t in e)if(e.hasOwnProperty(t)&&e[t])return!1;return!0}var Be=/[\u0300-\u036f\u0483-\u0489\u0591-\u05bd\u05bf\u05c1\u05c2\u05c4\u05c5\u05c7\u0610-\u061a\u064b-\u065e\u0670\u06d6-\u06dc\u06de-\u06e4\u06e7\u06e8\u06ea-\u06ed\u0711\u0730-\u074a\u07a6-\u07b0\u07eb-\u07f3\u0816-\u0819\u081b-\u0823\u0825-\u0827\u0829-\u082d\u0900-\u0902\u093c\u0941-\u0948\u094d\u0951-\u0955\u0962\u0963\u0981\u09bc\u09be\u09c1-\u09c4\u09cd\u09d7\u09e2\u09e3\u0a01\u0a02\u0a3c\u0a41\u0a42\u0a47\u0a48\u0a4b-\u0a4d\u0a51\u0a70\u0a71\u0a75\u0a81\u0a82\u0abc\u0ac1-\u0ac5\u0ac7\u0ac8\u0acd\u0ae2\u0ae3\u0b01\u0b3c\u0b3e\u0b3f\u0b41-\u0b44\u0b4d\u0b56\u0b57\u0b62\u0b63\u0b82\u0bbe\u0bc0\u0bcd\u0bd7\u0c3e-\u0c40\u0c46-\u0c48\u0c4a-\u0c4d\u0c55\u0c56\u0c62\u0c63\u0cbc\u0cbf\u0cc2\u0cc6\u0ccc\u0ccd\u0cd5\u0cd6\u0ce2\u0ce3\u0d3e\u0d41-\u0d44\u0d4d\u0d57\u0d62\u0d63\u0dca\u0dcf\u0dd2-\u0dd4\u0dd6\u0ddf\u0e31\u0e34-\u0e3a\u0e47-\u0e4e\u0eb1\u0eb4-\u0eb9\u0ebb\u0ebc\u0ec8-\u0ecd\u0f18\u0f19\u0f35\u0f37\u0f39\u0f71-\u0f7e\u0f80-\u0f84\u0f86\u0f87\u0f90-\u0f97\u0f99-\u0fbc\u0fc6\u102d-\u1030\u1032-\u1037\u1039\u103a\u103d\u103e\u1058\u1059\u105e-\u1060\u1071-\u1074\u1082\u1085\u1086\u108d\u109d\u135f\u1712-\u1714\u1732-\u1734\u1752\u1753\u1772\u1773\u17b7-\u17bd\u17c6\u17c9-\u17d3\u17dd\u180b-\u180d\u18a9\u1920-\u1922\u1927\u1928\u1932\u1939-\u193b\u1a17\u1a18\u1a56\u1a58-\u1a5e\u1a60\u1a62\u1a65-\u1a6c\u1a73-\u1a7c\u1a7f\u1b00-\u1b03\u1b34\u1b36-\u1b3a\u1b3c\u1b42\u1b6b-\u1b73\u1b80\u1b81\u1ba2-\u1ba5\u1ba8\u1ba9\u1c2c-\u1c33\u1c36\u1c37\u1cd0-\u1cd2\u1cd4-\u1ce0\u1ce2-\u1ce8\u1ced\u1dc0-\u1de6\u1dfd-\u1dff\u200c\u200d\u20d0-\u20f0\u2cef-\u2cf1\u2de0-\u2dff\u302a-\u302f\u3099\u309a\ua66f-\ua672\ua67c\ua67d\ua6f0\ua6f1\ua802\ua806\ua80b\ua825\ua826\ua8c4\ua8e0-\ua8f1\ua926-\ua92d\ua947-\ua951\ua980-\ua982\ua9b3\ua9b6-\ua9b9\ua9bc\uaa29-\uaa2e\uaa31\uaa32\uaa35\uaa36\uaa43\uaa4c\uaab0\uaab2-\uaab4\uaab7\uaab8\uaabe\uaabf\uaac1\uabe5\uabe8\uabed\udc00-\udfff\ufb1e\ufe00-\ufe0f\ufe20-\ufe26\uff9e\uff9f]/;function Ne(e){return e.charCodeAt(0)>=768&&Be.test(e)}function Mt(e,t,n){for(;(n<0?t>0:tn?-1:1;;){if(t==n)return t;var i=(t+n)/2,o=r<0?Math.ceil(i):Math.floor(i);if(o==t)return e(o)?t:n;e(o)?n=o:t=o+r}}function or(e,t,n,r){if(!e)return r(t,n,"ltr",0);for(var i=!1,o=0;ot||t==n&&l.to==t)&&(r(Math.max(l.from,t),Math.min(l.to,n),l.level==1?"rtl":"ltr",o),i=!0)}i||r(t,n,"ltr")}var br=null;function lr(e,t,n){var r;br=null;for(var i=0;it)return i;o.to==t&&(o.from!=o.to&&n=="before"?r=i:br=i),o.from==t&&(o.from!=o.to&&n!="before"?r=i:br=i)}return r??br}var mi=(function(){var e="bbbbbbbbbtstwsbbbbbbbbbbbbbbssstwNN%%%NNNNNN,N,N1111111111NNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNbbbbbbsbbbbbbbbbbbbbbbbbbbbbbbbbb,N%%%%NNNNLNNNNN%%11NLNNN1LNNNNNLLLLLLLLLLLLLLLLLLLLLLLNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLN",t="nnnnnnNNr%%r,rNNmmmmmmmmmmmrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrmmmmmmmmmmmmmmmmmmmmmnnnnnnnnnn%nnrrrmrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrmmmmmmmnNmmmmmmrrmmNmmmmrr1111111111";function n(u){return u<=247?e.charAt(u):1424<=u&&u<=1524?"R":1536<=u&&u<=1785?t.charAt(u-1536):1774<=u&&u<=2220?"r":8192<=u&&u<=8203?"w":u==8204?"b":"L"}var r=/[\u0590-\u05f4\u0600-\u06ff\u0700-\u08ac]/,i=/[stwN]/,o=/[LRr]/,l=/[Lb1n]/,a=/[1n]/;function s(u,h,x){this.level=u,this.from=h,this.to=x}return function(u,h){var x=h=="ltr"?"L":"R";if(u.length==0||h=="ltr"&&!r.test(u))return!1;for(var D=u.length,L=[],H=0;H-1&&(r[t]=i.slice(0,o).concat(i.slice(o+1)))}}}function Ye(e,t){var n=Zt(e,t);if(n.length)for(var r=Array.prototype.slice.call(arguments,2),i=0;i0}function Bt(e){e.prototype.on=function(t,n){Se(this,t,n)},e.prototype.off=function(t,n){ht(this,t,n)}}function pt(e){e.preventDefault?e.preventDefault():e.returnValue=!1}function Er(e){e.stopPropagation?e.stopPropagation():e.cancelBubble=!0}function kt(e){return e.defaultPrevented!=null?e.defaultPrevented:e.returnValue==!1}function ar(e){pt(e),Er(e)}function ln(e){return e.target||e.srcElement}function Rt(e){var t=e.which;return t==null&&(e.button&1?t=1:e.button&2?t=3:e.button&4&&(t=2)),z&&e.ctrlKey&&t==1&&(t=3),t}var xi=(function(){if(k&&I<9)return!1;var e=c("div");return"draggable"in e||"dragDrop"in e})(),Or;function Rn(e){if(Or==null){var t=c("span","​");G(e,c("span",[t,document.createTextNode("x")])),e.firstChild.offsetHeight!=0&&(Or=t.offsetWidth<=1&&t.offsetHeight>2&&!(k&&I<8))}var n=Or?c("span","​"):c("span"," ",null,"display: inline-block; width: 1px; margin-right: -1px");return n.setAttribute("cm-text",""),n}var an;function sr(e){if(an!=null)return an;var t=G(e,document.createTextNode("AخA")),n=C(t,0,1).getBoundingClientRect(),r=C(t,1,2).getBoundingClientRect();return F(e),!n||n.left==n.right?!1:an=r.right-n.right<3}var zt=` + +b`.split(/\n/).length!=3?function(e){for(var t=0,n=[],r=e.length;t<=r;){var i=e.indexOf(` +`,t);i==-1&&(i=e.length);var o=e.slice(t,e.charAt(i-1)=="\r"?i-1:i),l=o.indexOf("\r");l!=-1?(n.push(o.slice(0,l)),t+=l+1):(n.push(o),t=i+1)}return n}:function(e){return e.split(/\r\n?|\n/)},ur=window.getSelection?function(e){try{return e.selectionStart!=e.selectionEnd}catch{return!1}}:function(e){var t;try{t=e.ownerDocument.selection.createRange()}catch{}return!t||t.parentElement()!=e?!1:t.compareEndPoints("StartToEnd",t)!=0},Wn=(function(){var e=c("div");return"oncopy"in e?!0:(e.setAttribute("oncopy","return;"),typeof e.oncopy=="function")})(),Wt=null;function yi(e){if(Wt!=null)return Wt;var t=G(e,c("span","x")),n=t.getBoundingClientRect(),r=C(t,0,1).getBoundingClientRect();return Wt=Math.abs(n.left-r.left)>1}var Pr={},Ht={};function _t(e,t){arguments.length>2&&(t.dependencies=Array.prototype.slice.call(arguments,2)),Pr[e]=t}function kr(e,t){Ht[e]=t}function Ir(e){if(typeof e=="string"&&Ht.hasOwnProperty(e))e=Ht[e];else if(e&&typeof e.name=="string"&&Ht.hasOwnProperty(e.name)){var t=Ht[e.name];typeof t=="string"&&(t={name:t}),e=K(t,e),e.name=t.name}else{if(typeof e=="string"&&/^[\w\-]+\/[\w\-]+\+xml$/.test(e))return Ir("application/xml");if(typeof e=="string"&&/^[\w\-]+\/[\w\-]+\+json$/.test(e))return Ir("application/json")}return typeof e=="string"?{name:e}:e||{name:"null"}}function zr(e,t){t=Ir(t);var n=Pr[t.name];if(!n)return zr(e,"text/plain");var r=n(e,t);if(fr.hasOwnProperty(t.name)){var i=fr[t.name];for(var o in i)i.hasOwnProperty(o)&&(r.hasOwnProperty(o)&&(r["_"+o]=r[o]),r[o]=i[o])}if(r.name=t.name,t.helperType&&(r.helperType=t.helperType),t.modeProps)for(var l in t.modeProps)r[l]=t.modeProps[l];return r}var fr={};function Br(e,t){var n=fr.hasOwnProperty(e)?fr[e]:fr[e]={};Me(t,n)}function Gt(e,t){if(t===!0)return t;if(e.copyState)return e.copyState(t);var n={};for(var r in t){var i=t[r];i instanceof Array&&(i=i.concat([])),n[r]=i}return n}function sn(e,t){for(var n;e.innerMode&&(n=e.innerMode(t),!(!n||n.mode==e));)t=n.state,e=n.mode;return n||{mode:e,state:t}}function Rr(e,t,n){return e.startState?e.startState(t,n):!0}var Je=function(e,t,n){this.pos=this.start=0,this.string=e,this.tabSize=t||8,this.lastColumnPos=this.lastColumnValue=0,this.lineStart=0,this.lineOracle=n};Je.prototype.eol=function(){return this.pos>=this.string.length},Je.prototype.sol=function(){return this.pos==this.lineStart},Je.prototype.peek=function(){return this.string.charAt(this.pos)||void 0},Je.prototype.next=function(){if(this.post},Je.prototype.eatSpace=function(){for(var e=this.pos;/[\s\u00a0]/.test(this.string.charAt(this.pos));)++this.pos;return this.pos>e},Je.prototype.skipToEnd=function(){this.pos=this.string.length},Je.prototype.skipTo=function(e){var t=this.string.indexOf(e,this.pos);if(t>-1)return this.pos=t,!0},Je.prototype.backUp=function(e){this.pos-=e},Je.prototype.column=function(){return this.lastColumnPos0?null:(o&&t!==!1&&(this.pos+=o[0].length),o)}},Je.prototype.current=function(){return this.string.slice(this.start,this.pos)},Je.prototype.hideFirstChars=function(e,t){this.lineStart+=e;try{return t()}finally{this.lineStart-=e}},Je.prototype.lookAhead=function(e){var t=this.lineOracle;return t&&t.lookAhead(e)},Je.prototype.baseToken=function(){var e=this.lineOracle;return e&&e.baseToken(this.pos)};function ye(e,t){if(t-=e.first,t<0||t>=e.size)throw new Error("There is no line "+(t+e.first)+" in the document.");for(var n=e;!n.lines;)for(var r=0;;++r){var i=n.children[r],o=i.chunkSize();if(t=e.first&&tn?B(n,ye(e,n).text.length):Za(t,ye(e,t.line).text.length)}function Za(e,t){var n=e.ch;return n==null||n>t?B(e.line,t):n<0?B(e.line,0):e}function vo(e,t){for(var n=[],r=0;rthis.maxLookAhead&&(this.maxLookAhead=e),t},Xt.prototype.baseToken=function(e){if(!this.baseTokens)return null;for(;this.baseTokens[this.baseTokenPos]<=e;)this.baseTokenPos+=2;var t=this.baseTokens[this.baseTokenPos+1];return{type:t&&t.replace(/( |^)overlay .*/,""),size:this.baseTokens[this.baseTokenPos]-e}},Xt.prototype.nextLine=function(){this.line++,this.maxLookAhead>0&&this.maxLookAhead--},Xt.fromSaved=function(e,t,n){return t instanceof Hn?new Xt(e,Gt(e.mode,t.state),n,t.lookAhead):new Xt(e,Gt(e.mode,t),n)},Xt.prototype.save=function(e){var t=e!==!1?Gt(this.doc.mode,this.state):this.state;return this.maxLookAhead>0?new Hn(t,this.maxLookAhead):t};function mo(e,t,n,r){var i=[e.state.modeGen],o={};So(e,t.text,e.doc.mode,n,function(u,h){return i.push(u,h)},o,r);for(var l=n.state,a=function(u){n.baseTokens=i;var h=e.state.overlays[u],x=1,D=0;n.state=!0,So(e,t.text,h.mode,n,function(L,H){for(var Z=x;DL&&i.splice(x,1,L,i[x+1],ie),x+=2,D=Math.min(L,ie)}if(H)if(h.opaque)i.splice(Z,x-Z,L,"overlay "+H),x=Z+2;else for(;Ze.options.maxHighlightLength&&Gt(e.doc.mode,r.state),o=mo(e,t,r);i&&(r.state=i),t.stateAfter=r.save(!i),t.styles=o.styles,o.classes?t.styleClasses=o.classes:t.styleClasses&&(t.styleClasses=null),n===e.doc.highlightFrontier&&(e.doc.modeFrontier=Math.max(e.doc.modeFrontier,++e.doc.highlightFrontier))}return t.styles}function fn(e,t,n){var r=e.doc,i=e.display;if(!r.mode.startState)return new Xt(r,!0,t);var o=Va(e,t,n),l=o>r.first&&ye(r,o-1).stateAfter,a=l?Xt.fromSaved(r,l,o):new Xt(r,Rr(r.mode),o);return r.iter(o,t,function(s){bi(e,s.text,a);var u=a.line;s.stateAfter=u==t-1||u%5==0||u>=i.viewFrom&&ut.start)return o}throw new Error("Mode "+e.name+" failed to advance stream.")}var bo=function(e,t,n){this.start=e.start,this.end=e.pos,this.string=e.current(),this.type=t||null,this.state=n};function ko(e,t,n,r){var i=e.doc,o=i.mode,l;t=Ae(i,t);var a=ye(i,t.line),s=fn(e,t.line,n),u=new Je(a.text,e.options.tabSize,s),h;for(r&&(h=[]);(r||u.pose.options.maxHighlightLength?(a=!1,l&&bi(e,t,r,h.pos),h.pos=t.length,x=null):x=wo(ki(n,h,r.state,D),o),D){var L=D[0].name;L&&(x="m-"+(x?L+" "+x:L))}if(!a||u!=x){for(;sl;--a){if(a<=o.first)return o.first;var s=ye(o,a-1),u=s.stateAfter;if(u&&(!n||a+(u instanceof Hn?u.lookAhead:0)<=o.modeFrontier))return a;var h=Fe(s.text,null,e.options.tabSize);(i==null||r>h)&&(i=a-1,r=h)}return i}function $a(e,t){if(e.modeFrontier=Math.min(e.modeFrontier,t),!(e.highlightFrontiern;r--){var i=ye(e,r).stateAfter;if(i&&(!(i instanceof Hn)||r+i.lookAhead=t:o.to>t);(r||(r=[])).push(new _n(l,o.from,s?null:o.to))}}return r}function os(e,t,n){var r;if(e)for(var i=0;i=t:o.to>t);if(a||o.from==t&&l.type=="bookmark"&&(!n||o.marker.insertLeft)){var s=o.from==null||(l.inclusiveLeft?o.from<=t:o.from0&&a)for(var ge=0;ge0)){var h=[s,1],x=ce(u.from,a.from),D=ce(u.to,a.to);(x<0||!l.inclusiveLeft&&!x)&&h.push({from:u.from,to:a.from}),(D>0||!l.inclusiveRight&&!D)&&h.push({from:a.to,to:u.to}),i.splice.apply(i,h),s+=h.length-3}}return i}function Co(e){var t=e.markedSpans;if(t){for(var n=0;nt)&&(!r||Si(r,o.marker)<0)&&(r=o.marker)}return r}function Ao(e,t,n,r,i){var o=ye(e,t),l=$t&&o.markedSpans;if(l)for(var a=0;a=0&&x<=0||h<=0&&x>=0)&&(h<=0&&(s.marker.inclusiveRight&&i.inclusiveLeft?ce(u.to,n)>=0:ce(u.to,n)>0)||h>=0&&(s.marker.inclusiveRight&&i.inclusiveLeft?ce(u.from,r)<=0:ce(u.from,r)<0)))return!0}}}function qt(e){for(var t;t=Fo(e);)e=t.find(-1,!0).line;return e}function ss(e){for(var t;t=Kn(e);)e=t.find(1,!0).line;return e}function us(e){for(var t,n;t=Kn(e);)e=t.find(1,!0).line,(n||(n=[])).push(e);return n}function Li(e,t){var n=ye(e,t),r=qt(n);return n==r?t:f(r)}function No(e,t){if(t>e.lastLine())return t;var n=ye(e,t),r;if(!cr(e,n))return t;for(;r=Kn(n);)n=r.find(1,!0).line;return f(n)+1}function cr(e,t){var n=$t&&t.markedSpans;if(n){for(var r=void 0,i=0;it.maxLineLength&&(t.maxLineLength=i,t.maxLine=r)})}var Hr=function(e,t,n){this.text=e,Do(this,t),this.height=n?n(this):1};Hr.prototype.lineNo=function(){return f(this)},Bt(Hr);function fs(e,t,n,r){e.text=t,e.stateAfter&&(e.stateAfter=null),e.styles&&(e.styles=null),e.order!=null&&(e.order=null),Co(e),Do(e,n);var i=r?r(e):1;i!=e.height&&Et(e,i)}function cs(e){e.parent=null,Co(e)}var ds={},hs={};function Eo(e,t){if(!e||/^\s*$/.test(e))return null;var n=t.addModeClass?hs:ds;return n[e]||(n[e]=e.replace(/\S+/g,"cm-$&"))}function Oo(e,t){var n=T("span",null,null,Y?"padding-right: .1px":null),r={pre:T("pre",[n],"CodeMirror-line"),content:n,col:0,pos:0,cm:e,trailingSpace:!1,splitSpaces:e.getOption("lineWrapping")};t.measure={};for(var i=0;i<=(t.rest?t.rest.length:0);i++){var o=i?t.rest[i-1]:t.line,l=void 0;r.pos=0,r.addToken=gs,sr(e.display.measure)&&(l=Re(o,e.doc.direction))&&(r.addToken=ms(r.addToken,l)),r.map=[];var a=t!=e.display.externalMeasured&&f(o);xs(o,r,xo(e,o,a)),o.styleClasses&&(o.styleClasses.bgClass&&(r.bgClass=de(o.styleClasses.bgClass,r.bgClass||"")),o.styleClasses.textClass&&(r.textClass=de(o.styleClasses.textClass,r.textClass||""))),r.map.length==0&&r.map.push(0,0,r.content.appendChild(Rn(e.display.measure))),i==0?(t.measure.map=r.map,t.measure.cache={}):((t.measure.maps||(t.measure.maps=[])).push(r.map),(t.measure.caches||(t.measure.caches=[])).push({}))}if(Y){var s=r.content.lastChild;(/\bcm-tab\b/.test(s.className)||s.querySelector&&s.querySelector(".cm-tab"))&&(r.content.className="cm-tab-wrap-hack")}return Ye(e,"renderLine",e,t.line,r.pre),r.pre.className&&(r.textClass=de(r.pre.className,r.textClass||"")),r}function ps(e){var t=c("span","•","cm-invalidchar");return t.title="\\u"+e.charCodeAt(0).toString(16),t.setAttribute("aria-label",t.title),t}function gs(e,t,n,r,i,o,l){if(t){var a=e.splitSpaces?vs(t,e.trailingSpace):t,s=e.cm.state.specialChars,u=!1,h;if(!s.test(t))e.col+=t.length,h=document.createTextNode(a),e.map.push(e.pos,e.pos+t.length,h),k&&I<9&&(u=!0),e.pos+=t.length;else{h=document.createDocumentFragment();for(var x=0;;){s.lastIndex=x;var D=s.exec(t),L=D?D.index-x:t.length-x;if(L){var H=document.createTextNode(a.slice(x,x+L));k&&I<9?h.appendChild(c("span",[H])):h.appendChild(H),e.map.push(e.pos,e.pos+L,H),e.col+=L,e.pos+=L}if(!D)break;x+=L+1;var Z=void 0;if(D[0]==" "){var ie=e.cm.options.tabSize,ae=ie-e.col%ie;Z=h.appendChild(c("span",et(ae),"cm-tab")),Z.setAttribute("role","presentation"),Z.setAttribute("cm-text"," "),e.col+=ae}else D[0]=="\r"||D[0]==` +`?(Z=h.appendChild(c("span",D[0]=="\r"?"␍":"␤","cm-invalidchar")),Z.setAttribute("cm-text",D[0]),e.col+=1):(Z=e.cm.options.specialCharPlaceholder(D[0]),Z.setAttribute("cm-text",D[0]),k&&I<9?h.appendChild(c("span",[Z])):h.appendChild(Z),e.col+=1);e.map.push(e.pos,e.pos+1,Z),e.pos++}}if(e.trailingSpace=a.charCodeAt(t.length-1)==32,n||r||i||u||o||l){var he=n||"";r&&(he+=r),i&&(he+=i);var se=c("span",[h],he,o);if(l)for(var ge in l)l.hasOwnProperty(ge)&&ge!="style"&&ge!="class"&&se.setAttribute(ge,l[ge]);return e.content.appendChild(se)}e.content.appendChild(h)}}function vs(e,t){if(e.length>1&&!/ /.test(e))return e;for(var n=t,r="",i=0;iu&&x.from<=u));D++);if(x.to>=h)return e(n,r,i,o,l,a,s);e(n,r.slice(0,x.to-u),i,o,null,a,s),o=null,r=r.slice(x.to-u),u=x.to}}}function Po(e,t,n,r){var i=!r&&n.widgetNode;i&&e.map.push(e.pos,e.pos+t,i),!r&&e.cm.display.input.needsContentAttribute&&(i||(i=e.content.appendChild(document.createElement("span"))),i.setAttribute("cm-marker",n.id)),i&&(e.cm.display.input.setUneditable(i),e.content.appendChild(i)),e.pos+=t,e.trailingSpace=!1}function xs(e,t,n){var r=e.markedSpans,i=e.text,o=0;if(!r){for(var l=1;ls||Ee.collapsed&&ke.to==s&&ke.from==s)){if(ke.to!=null&&ke.to!=s&&L>ke.to&&(L=ke.to,Z=""),Ee.className&&(H+=" "+Ee.className),Ee.css&&(D=(D?D+";":"")+Ee.css),Ee.startStyle&&ke.from==s&&(ie+=" "+Ee.startStyle),Ee.endStyle&&ke.to==L&&(ge||(ge=[])).push(Ee.endStyle,ke.to),Ee.title&&((he||(he={})).title=Ee.title),Ee.attributes)for(var Ke in Ee.attributes)(he||(he={}))[Ke]=Ee.attributes[Ke];Ee.collapsed&&(!ae||Si(ae.marker,Ee)<0)&&(ae=ke)}else ke.from>s&&L>ke.from&&(L=ke.from)}if(ge)for(var st=0;st=a)break;for(var Nt=Math.min(a,L);;){if(h){var Tt=s+h.length;if(!ae){var tt=Tt>Nt?h.slice(0,Nt-s):h;t.addToken(t,tt,x?x+H:H,ie,s+tt.length==L?Z:"",D,he)}if(Tt>=Nt){h=h.slice(Nt-s),s=Nt;break}s=Tt,ie=""}h=i.slice(o,o=n[u++]),x=Eo(n[u++],t.cm.options)}}}function Io(e,t,n){this.line=t,this.rest=us(t),this.size=this.rest?f(we(this.rest))-n+1:1,this.node=this.text=null,this.hidden=cr(e,t)}function Gn(e,t,n){for(var r=[],i,o=t;o2&&o.push((s.bottom+u.top)/2-n.top)}}o.push(n.bottom-n.top)}}function qo(e,t,n){if(e.line==t)return{map:e.measure.map,cache:e.measure.cache};if(e.rest){for(var r=0;rn)return{map:e.measure.maps[i],cache:e.measure.caches[i],before:!0}}}function Fs(e,t){t=qt(t);var n=f(t),r=e.display.externalMeasured=new Io(e.doc,t,n);r.lineN=n;var i=r.built=Oo(e,r);return r.text=i.pre,G(e.display.lineMeasure,i.pre),r}function jo(e,t,n,r){return Qt(e,qr(e,t),n,r)}function Ai(e,t){if(t>=e.display.viewFrom&&t=n.lineN&&tt)&&(o=s-a,i=o-1,t>=s&&(l="right")),i!=null){if(r=e[u+2],a==s&&n==(r.insertLeft?"left":"right")&&(l=n),n=="left"&&i==0)for(;u&&e[u-2]==e[u-3]&&e[u-1].insertLeft;)r=e[(u-=3)+2],l="left";if(n=="right"&&i==s-a)for(;u=0&&(n=e[i]).left==n.right;i--);return n}function Ns(e,t,n,r){var i=Uo(t.map,n,r),o=i.node,l=i.start,a=i.end,s=i.collapse,u;if(o.nodeType==3){for(var h=0;h<4;h++){for(;l&&Ne(t.line.text.charAt(i.coverStart+l));)--l;for(;i.coverStart+a0&&(s=r="right");var x;e.options.lineWrapping&&(x=o.getClientRects()).length>1?u=x[r=="right"?x.length-1:0]:u=o.getBoundingClientRect()}if(k&&I<9&&!l&&(!u||!u.left&&!u.right)){var D=o.parentNode.getClientRects()[0];D?u={left:D.left,right:D.left+Kr(e.display),top:D.top,bottom:D.bottom}:u=Ko}for(var L=u.top-t.rect.top,H=u.bottom-t.rect.top,Z=(L+H)/2,ie=t.view.measure.heights,ae=0;ae=r.text.length?(s=r.text.length,u="before"):s<=0&&(s=0,u="after"),!a)return l(u=="before"?s-1:s,u=="before");function h(H,Z,ie){var ae=a[Z],he=ae.level==1;return l(ie?H-1:H,he!=ie)}var x=lr(a,s,u),D=br,L=h(s,x,u=="before");return D!=null&&(L.other=h(s,D,u!="before")),L}function Zo(e,t){var n=0;t=Ae(e.doc,t),e.options.lineWrapping||(n=Kr(e.display)*t.ch);var r=ye(e.doc,t.line),i=er(r)+Xn(e.display);return{left:n,right:n,top:i,bottom:i+r.height}}function Ei(e,t,n,r,i){var o=B(e,t,n);return o.xRel=i,r&&(o.outside=r),o}function Oi(e,t,n){var r=e.doc;if(n+=e.display.viewOffset,n<0)return Ei(r.first,0,null,-1,-1);var i=m(r,n),o=r.first+r.size-1;if(i>o)return Ei(r.first+r.size-1,ye(r,o).text.length,null,1,1);t<0&&(t=0);for(var l=ye(r,i);;){var a=Os(e,l,i,t,n),s=as(l,a.ch+(a.xRel>0||a.outside>0?1:0));if(!s)return a;var u=s.find(1);if(u.line==i)return u;l=ye(r,i=u.line)}}function Vo(e,t,n,r){r-=Ni(t);var i=t.text.length,o=Pt(function(l){return Qt(e,n,l-1).bottom<=r},i,0);return i=Pt(function(l){return Qt(e,n,l).top>r},o,i),{begin:o,end:i}}function $o(e,t,n,r){n||(n=qr(e,t));var i=Yn(e,t,Qt(e,n,r),"line").top;return Vo(e,t,n,i)}function Pi(e,t,n,r){return e.bottom<=n?!1:e.top>n?!0:(r?e.left:e.right)>t}function Os(e,t,n,r,i){i-=er(t);var o=qr(e,t),l=Ni(t),a=0,s=t.text.length,u=!0,h=Re(t,e.doc.direction);if(h){var x=(e.options.lineWrapping?Is:Ps)(e,t,n,o,h,r,i);u=x.level!=1,a=u?x.from:x.to-1,s=u?x.to:x.from-1}var D=null,L=null,H=Pt(function(Le){var ke=Qt(e,o,Le);return ke.top+=l,ke.bottom+=l,Pi(ke,r,i,!1)?(ke.top<=i&&ke.left<=r&&(D=Le,L=ke),!0):!1},a,s),Z,ie,ae=!1;if(L){var he=r-L.left=ge.bottom?1:0}return H=Mt(t.text,H,1),Ei(n,H,ie,ae,r-Z)}function Ps(e,t,n,r,i,o,l){var a=Pt(function(x){var D=i[x],L=D.level!=1;return Pi(jt(e,B(n,L?D.to:D.from,L?"before":"after"),"line",t,r),o,l,!0)},0,i.length-1),s=i[a];if(a>0){var u=s.level!=1,h=jt(e,B(n,u?s.from:s.to,u?"after":"before"),"line",t,r);Pi(h,o,l,!0)&&h.top>l&&(s=i[a-1])}return s}function Is(e,t,n,r,i,o,l){var a=Vo(e,t,r,l),s=a.begin,u=a.end;/\s/.test(t.text.charAt(u-1))&&u--;for(var h=null,x=null,D=0;D=u||L.to<=s)){var H=L.level!=1,Z=Qt(e,r,H?Math.min(u,L.to)-1:Math.max(s,L.from)).right,ie=Zie)&&(h=L,x=ie)}}return h||(h=i[i.length-1]),h.fromu&&(h={from:h.from,to:u,level:h.level}),h}var Sr;function jr(e){if(e.cachedTextHeight!=null)return e.cachedTextHeight;if(Sr==null){Sr=c("pre",null,"CodeMirror-line-like");for(var t=0;t<49;++t)Sr.appendChild(document.createTextNode("x")),Sr.appendChild(c("br"));Sr.appendChild(document.createTextNode("x"))}G(e.measure,Sr);var n=Sr.offsetHeight/50;return n>3&&(e.cachedTextHeight=n),F(e.measure),n||1}function Kr(e){if(e.cachedCharWidth!=null)return e.cachedCharWidth;var t=c("span","xxxxxxxxxx"),n=c("pre",[t],"CodeMirror-line-like");G(e.measure,n);var r=t.getBoundingClientRect(),i=(r.right-r.left)/10;return i>2&&(e.cachedCharWidth=i),i||10}function Ii(e){for(var t=e.display,n={},r={},i=t.gutters.clientLeft,o=t.gutters.firstChild,l=0;o;o=o.nextSibling,++l){var a=e.display.gutterSpecs[l].className;n[a]=o.offsetLeft+o.clientLeft+i,r[a]=o.clientWidth}return{fixedPos:zi(t),gutterTotalWidth:t.gutters.offsetWidth,gutterLeft:n,gutterWidth:r,wrapperWidth:t.wrapper.clientWidth}}function zi(e){return e.scroller.getBoundingClientRect().left-e.sizer.getBoundingClientRect().left}function el(e){var t=jr(e.display),n=e.options.lineWrapping,r=n&&Math.max(5,e.display.scroller.clientWidth/Kr(e.display)-3);return function(i){if(cr(e.doc,i))return 0;var o=0;if(i.widgets)for(var l=0;l0&&(u=ye(e.doc,s.line).text).length==s.ch){var h=Fe(u,u.length,e.options.tabSize)-u.length;s=B(s.line,Math.max(0,Math.round((o-_o(e.display).left)/Kr(e.display))-h))}return s}function Tr(e,t){if(t>=e.display.viewTo||(t-=e.display.viewFrom,t<0))return null;for(var n=e.display.view,r=0;rt)&&(i.updateLineNumbers=t),e.curOp.viewChanged=!0,t>=i.viewTo)$t&&Li(e.doc,t)i.viewFrom?hr(e):(i.viewFrom+=r,i.viewTo+=r);else if(t<=i.viewFrom&&n>=i.viewTo)hr(e);else if(t<=i.viewFrom){var o=Jn(e,n,n+r,1);o?(i.view=i.view.slice(o.index),i.viewFrom=o.lineN,i.viewTo+=r):hr(e)}else if(n>=i.viewTo){var l=Jn(e,t,t,-1);l?(i.view=i.view.slice(0,l.index),i.viewTo=l.lineN):hr(e)}else{var a=Jn(e,t,t,-1),s=Jn(e,n,n+r,1);a&&s?(i.view=i.view.slice(0,a.index).concat(Gn(e,a.lineN,s.lineN)).concat(i.view.slice(s.index)),i.viewTo+=r):hr(e)}var u=i.externalMeasured;u&&(n=i.lineN&&t=r.viewTo)){var o=r.view[Tr(e,t)];if(o.node!=null){var l=o.changes||(o.changes=[]);ve(l,n)==-1&&l.push(n)}}}function hr(e){e.display.viewFrom=e.display.viewTo=e.doc.first,e.display.view=[],e.display.viewOffset=0}function Jn(e,t,n,r){var i=Tr(e,t),o,l=e.display.view;if(!$t||n==e.doc.first+e.doc.size)return{index:i,lineN:n};for(var a=e.display.viewFrom,s=0;s0){if(i==l.length-1)return null;o=a+l[i].size-t,i++}else o=a-t;t+=o,n+=o}for(;Li(e.doc,n)!=n;){if(i==(r<0?0:l.length-1))return null;n+=r*l[i-(r<0?1:0)].size,i+=r}return{index:i,lineN:n}}function zs(e,t,n){var r=e.display,i=r.view;i.length==0||t>=r.viewTo||n<=r.viewFrom?(r.view=Gn(e,t,n),r.viewFrom=t):(r.viewFrom>t?r.view=Gn(e,t,r.viewFrom).concat(r.view):r.viewFromn&&(r.view=r.view.slice(0,Tr(e,n)))),r.viewTo=n}function tl(e){for(var t=e.display.view,n=0,r=0;r=e.display.viewTo||s.to().line0?l:e.defaultCharWidth())+"px"}if(r.other){var a=n.appendChild(c("div"," ","CodeMirror-cursor CodeMirror-secondarycursor"));a.style.display="",a.style.left=r.other.left+"px",a.style.top=r.other.top+"px",a.style.height=(r.other.bottom-r.other.top)*.85+"px"}}function Zn(e,t){return e.top-t.top||e.left-t.left}function Bs(e,t,n){var r=e.display,i=e.doc,o=document.createDocumentFragment(),l=_o(e.display),a=l.left,s=Math.max(r.sizerWidth,wr(e)-r.sizer.offsetLeft)-l.right,u=i.direction=="ltr";function h(se,ge,Le,ke){ge<0&&(ge=0),ge=Math.round(ge),ke=Math.round(ke),o.appendChild(c("div",null,"CodeMirror-selected","position: absolute; left: "+se+`px; + top: `+ge+"px; width: "+(Le??s-se)+`px; + height: `+(ke-ge)+"px"))}function x(se,ge,Le){var ke=ye(i,se),Ee=ke.text.length,Ke,st;function Xe(tt,Ct){return Qn(e,B(se,tt),"div",ke,Ct)}function Nt(tt,Ct,ft){var nt=$o(e,ke,null,tt),rt=Ct=="ltr"==(ft=="after")?"left":"right",Ze=ft=="after"?nt.begin:nt.end-(/\s/.test(ke.text.charAt(nt.end-1))?2:1);return Xe(Ze,rt)[rt]}var Tt=Re(ke,i.direction);return or(Tt,ge||0,Le??Ee,function(tt,Ct,ft,nt){var rt=ft=="ltr",Ze=Xe(tt,rt?"left":"right"),Dt=Xe(Ct-1,rt?"right":"left"),nn=ge==null&&tt==0,yr=Le==null&&Ct==Ee,vt=nt==0,Jt=!Tt||nt==Tt.length-1;if(Dt.top-Ze.top<=3){var ut=(u?nn:yr)&&vt,co=(u?yr:nn)&&Jt,ir=ut?a:(rt?Ze:Dt).left,Ar=co?s:(rt?Dt:Ze).right;h(ir,Ze.top,Ar-ir,Ze.bottom)}else{var Nr,bt,on,ho;rt?(Nr=u&&nn&&vt?a:Ze.left,bt=u?s:Nt(tt,ft,"before"),on=u?a:Nt(Ct,ft,"after"),ho=u&&yr&&Jt?s:Dt.right):(Nr=u?Nt(tt,ft,"before"):a,bt=!u&&nn&&vt?s:Ze.right,on=!u&&yr&&Jt?a:Dt.left,ho=u?Nt(Ct,ft,"after"):s),h(Nr,Ze.top,bt-Nr,Ze.bottom),Ze.bottom0?t.blinker=setInterval(function(){e.hasFocus()||Ur(e),t.cursorDiv.style.visibility=(n=!n)?"":"hidden"},e.options.cursorBlinkRate):e.options.cursorBlinkRate<0&&(t.cursorDiv.style.visibility="hidden")}}function nl(e){e.hasFocus()||(e.display.input.focus(),e.state.focused||_i(e))}function Hi(e){e.state.delayingBlurEvent=!0,setTimeout(function(){e.state.delayingBlurEvent&&(e.state.delayingBlurEvent=!1,e.state.focused&&Ur(e))},100)}function _i(e,t){e.state.delayingBlurEvent&&!e.state.draggingText&&(e.state.delayingBlurEvent=!1),e.options.readOnly!="nocursor"&&(e.state.focused||(Ye(e,"focus",e,t),e.state.focused=!0,j(e.display.wrapper,"CodeMirror-focused"),!e.curOp&&e.display.selForContextMenu!=e.doc.sel&&(e.display.input.reset(),Y&&setTimeout(function(){return e.display.input.reset(!0)},20)),e.display.input.receivedFocus()),Wi(e))}function Ur(e,t){e.state.delayingBlurEvent||(e.state.focused&&(Ye(e,"blur",e,t),e.state.focused=!1,$(e.display.wrapper,"CodeMirror-focused")),clearInterval(e.display.blinker),setTimeout(function(){e.state.focused||(e.display.shift=!1)},150))}function Vn(e){for(var t=e.display,n=t.lineDiv.offsetTop,r=Math.max(0,t.scroller.getBoundingClientRect().top),i=t.lineDiv.getBoundingClientRect().top,o=0,l=0;l.005||L<-.005)&&(ie.display.sizerWidth){var Z=Math.ceil(h/Kr(e.display));Z>e.display.maxLineLength&&(e.display.maxLineLength=Z,e.display.maxLine=a.line,e.display.maxLineChanged=!0)}}}Math.abs(o)>2&&(t.scroller.scrollTop+=o)}function il(e){if(e.widgets)for(var t=0;t=l&&(o=m(t,er(ye(t,s))-e.wrapper.clientHeight),l=s)}return{from:o,to:Math.max(l,o+1)}}function Rs(e,t){if(!Qe(e,"scrollCursorIntoView")){var n=e.display,r=n.sizer.getBoundingClientRect(),i=null,o=n.wrapper.ownerDocument;if(t.top+r.top<0?i=!0:t.bottom+r.top>(o.defaultView.innerHeight||o.documentElement.clientHeight)&&(i=!1),i!=null&&!O){var l=c("div","​",null,`position: absolute; + top: `+(t.top-n.viewOffset-Xn(e.display))+`px; + height: `+(t.bottom-t.top+Yt(e)+n.barHeight)+`px; + left: `+t.left+"px; width: "+Math.max(2,t.right-t.left)+"px;");e.display.lineSpace.appendChild(l),l.scrollIntoView(i),e.display.lineSpace.removeChild(l)}}}function Ws(e,t,n,r){r==null&&(r=0);var i;!e.options.lineWrapping&&t==n&&(n=t.sticky=="before"?B(t.line,t.ch+1,"before"):t,t=t.ch?B(t.line,t.sticky=="before"?t.ch-1:t.ch,"after"):t);for(var o=0;o<5;o++){var l=!1,a=jt(e,t),s=!n||n==t?a:jt(e,n);i={left:Math.min(a.left,s.left),top:Math.min(a.top,s.top)-r,right:Math.max(a.left,s.left),bottom:Math.max(a.bottom,s.bottom)+r};var u=qi(e,i),h=e.doc.scrollTop,x=e.doc.scrollLeft;if(u.scrollTop!=null&&(xn(e,u.scrollTop),Math.abs(e.doc.scrollTop-h)>1&&(l=!0)),u.scrollLeft!=null&&(Cr(e,u.scrollLeft),Math.abs(e.doc.scrollLeft-x)>1&&(l=!0)),!l)break}return i}function Hs(e,t){var n=qi(e,t);n.scrollTop!=null&&xn(e,n.scrollTop),n.scrollLeft!=null&&Cr(e,n.scrollLeft)}function qi(e,t){var n=e.display,r=jr(e.display);t.top<0&&(t.top=0);var i=e.curOp&&e.curOp.scrollTop!=null?e.curOp.scrollTop:n.scroller.scrollTop,o=Fi(e),l={};t.bottom-t.top>o&&(t.bottom=t.top+o);var a=e.doc.height+Mi(n),s=t.topa-r;if(t.topi+o){var h=Math.min(t.top,(u?a:t.bottom)-o);h!=i&&(l.scrollTop=h)}var x=e.options.fixedGutter?0:n.gutters.offsetWidth,D=e.curOp&&e.curOp.scrollLeft!=null?e.curOp.scrollLeft:n.scroller.scrollLeft-x,L=wr(e)-n.gutters.offsetWidth,H=t.right-t.left>L;return H&&(t.right=t.left+L),t.left<10?l.scrollLeft=0:t.leftL+D-3&&(l.scrollLeft=t.right+(H?0:10)-L),l}function ji(e,t){t!=null&&(ei(e),e.curOp.scrollTop=(e.curOp.scrollTop==null?e.doc.scrollTop:e.curOp.scrollTop)+t)}function Gr(e){ei(e);var t=e.getCursor();e.curOp.scrollToPos={from:t,to:t,margin:e.options.cursorScrollMargin}}function mn(e,t,n){(t!=null||n!=null)&&ei(e),t!=null&&(e.curOp.scrollLeft=t),n!=null&&(e.curOp.scrollTop=n)}function _s(e,t){ei(e),e.curOp.scrollToPos=t}function ei(e){var t=e.curOp.scrollToPos;if(t){e.curOp.scrollToPos=null;var n=Zo(e,t.from),r=Zo(e,t.to);ol(e,n,r,t.margin)}}function ol(e,t,n,r){var i=qi(e,{left:Math.min(t.left,n.left),top:Math.min(t.top,n.top)-r,right:Math.max(t.right,n.right),bottom:Math.max(t.bottom,n.bottom)+r});mn(e,i.scrollLeft,i.scrollTop)}function xn(e,t){Math.abs(e.doc.scrollTop-t)<2||(_||Ui(e,{top:t}),ll(e,t,!0),_&&Ui(e),kn(e,100))}function ll(e,t,n){t=Math.max(0,Math.min(e.display.scroller.scrollHeight-e.display.scroller.clientHeight,t)),!(e.display.scroller.scrollTop==t&&!n)&&(e.doc.scrollTop=t,e.display.scrollbars.setScrollTop(t),e.display.scroller.scrollTop!=t&&(e.display.scroller.scrollTop=t))}function Cr(e,t,n,r){t=Math.max(0,Math.min(t,e.display.scroller.scrollWidth-e.display.scroller.clientWidth)),!((n?t==e.doc.scrollLeft:Math.abs(e.doc.scrollLeft-t)<2)&&!r)&&(e.doc.scrollLeft=t,cl(e),e.display.scroller.scrollLeft!=t&&(e.display.scroller.scrollLeft=t),e.display.scrollbars.setScrollLeft(t))}function yn(e){var t=e.display,n=t.gutters.offsetWidth,r=Math.round(e.doc.height+Mi(e.display));return{clientHeight:t.scroller.clientHeight,viewHeight:t.wrapper.clientHeight,scrollWidth:t.scroller.scrollWidth,clientWidth:t.scroller.clientWidth,viewWidth:t.wrapper.clientWidth,barLeft:e.options.fixedGutter?n:0,docHeight:r,scrollHeight:r+Yt(e)+t.barHeight,nativeBarWidth:t.nativeBarWidth,gutterWidth:n}}var Dr=function(e,t,n){this.cm=n;var r=this.vert=c("div",[c("div",null,null,"min-width: 1px")],"CodeMirror-vscrollbar"),i=this.horiz=c("div",[c("div",null,null,"height: 100%; min-height: 1px")],"CodeMirror-hscrollbar");r.tabIndex=i.tabIndex=-1,e(r),e(i),Se(r,"scroll",function(){r.clientHeight&&t(r.scrollTop,"vertical")}),Se(i,"scroll",function(){i.clientWidth&&t(i.scrollLeft,"horizontal")}),this.checkedZeroWidth=!1,k&&I<8&&(this.horiz.style.minHeight=this.vert.style.minWidth="18px")};Dr.prototype.update=function(e){var t=e.scrollWidth>e.clientWidth+1,n=e.scrollHeight>e.clientHeight+1,r=e.nativeBarWidth;if(n){this.vert.style.display="block",this.vert.style.bottom=t?r+"px":"0";var i=e.viewHeight-(t?r:0);this.vert.firstChild.style.height=Math.max(0,e.scrollHeight-e.clientHeight+i)+"px"}else this.vert.scrollTop=0,this.vert.style.display="",this.vert.firstChild.style.height="0";if(t){this.horiz.style.display="block",this.horiz.style.right=n?r+"px":"0",this.horiz.style.left=e.barLeft+"px";var o=e.viewWidth-e.barLeft-(n?r:0);this.horiz.firstChild.style.width=Math.max(0,e.scrollWidth-e.clientWidth+o)+"px"}else this.horiz.style.display="",this.horiz.firstChild.style.width="0";return!this.checkedZeroWidth&&e.clientHeight>0&&(r==0&&this.zeroWidthHack(),this.checkedZeroWidth=!0),{right:n?r:0,bottom:t?r:0}},Dr.prototype.setScrollLeft=function(e){this.horiz.scrollLeft!=e&&(this.horiz.scrollLeft=e),this.disableHoriz&&this.enableZeroWidthBar(this.horiz,this.disableHoriz,"horiz")},Dr.prototype.setScrollTop=function(e){this.vert.scrollTop!=e&&(this.vert.scrollTop=e),this.disableVert&&this.enableZeroWidthBar(this.vert,this.disableVert,"vert")},Dr.prototype.zeroWidthHack=function(){var e=z&&!ue?"12px":"18px";this.horiz.style.height=this.vert.style.width=e,this.horiz.style.visibility=this.vert.style.visibility="hidden",this.disableHoriz=new Ce,this.disableVert=new Ce},Dr.prototype.enableZeroWidthBar=function(e,t,n){e.style.visibility="";function r(){var i=e.getBoundingClientRect(),o=n=="vert"?document.elementFromPoint(i.right-1,(i.top+i.bottom)/2):document.elementFromPoint((i.right+i.left)/2,i.bottom-1);o!=e?e.style.visibility="hidden":t.set(1e3,r)}t.set(1e3,r)},Dr.prototype.clear=function(){var e=this.horiz.parentNode;e.removeChild(this.horiz),e.removeChild(this.vert)};var bn=function(){};bn.prototype.update=function(){return{bottom:0,right:0}},bn.prototype.setScrollLeft=function(){},bn.prototype.setScrollTop=function(){},bn.prototype.clear=function(){};function Xr(e,t){t||(t=yn(e));var n=e.display.barWidth,r=e.display.barHeight;al(e,t);for(var i=0;i<4&&n!=e.display.barWidth||r!=e.display.barHeight;i++)n!=e.display.barWidth&&e.options.lineWrapping&&Vn(e),al(e,yn(e)),n=e.display.barWidth,r=e.display.barHeight}function al(e,t){var n=e.display,r=n.scrollbars.update(t);n.sizer.style.paddingRight=(n.barWidth=r.right)+"px",n.sizer.style.paddingBottom=(n.barHeight=r.bottom)+"px",n.heightForcer.style.borderBottom=r.bottom+"px solid transparent",r.right&&r.bottom?(n.scrollbarFiller.style.display="block",n.scrollbarFiller.style.height=r.bottom+"px",n.scrollbarFiller.style.width=r.right+"px"):n.scrollbarFiller.style.display="",r.bottom&&e.options.coverGutterNextToScrollbar&&e.options.fixedGutter?(n.gutterFiller.style.display="block",n.gutterFiller.style.height=r.bottom+"px",n.gutterFiller.style.width=t.gutterWidth+"px"):n.gutterFiller.style.display=""}var sl={native:Dr,null:bn};function ul(e){e.display.scrollbars&&(e.display.scrollbars.clear(),e.display.scrollbars.addClass&&$(e.display.wrapper,e.display.scrollbars.addClass)),e.display.scrollbars=new sl[e.options.scrollbarStyle](function(t){e.display.wrapper.insertBefore(t,e.display.scrollbarFiller),Se(t,"mousedown",function(){e.state.focused&&setTimeout(function(){return e.display.input.focus()},0)}),t.setAttribute("cm-not-content","true")},function(t,n){n=="horizontal"?Cr(e,t):xn(e,t)},e),e.display.scrollbars.addClass&&j(e.display.wrapper,e.display.scrollbars.addClass)}var qs=0;function Mr(e){e.curOp={cm:e,viewChanged:!1,startHeight:e.doc.height,forceUpdate:!1,updateInput:0,typing:!1,changeObjs:null,cursorActivityHandlers:null,cursorActivityCalled:0,selectionChanged:!1,updateMaxLine:!1,scrollLeft:null,scrollTop:null,scrollToPos:null,focus:!1,id:++qs,markArrays:null},ys(e.curOp)}function Fr(e){var t=e.curOp;t&&ks(t,function(n){for(var r=0;r=n.viewTo)||n.maxLineChanged&&t.options.lineWrapping,e.update=e.mustUpdate&&new ti(t,e.mustUpdate&&{top:e.scrollTop,ensure:e.scrollToPos},e.forceUpdate)}function Us(e){e.updatedDisplay=e.mustUpdate&&Ki(e.cm,e.update)}function Gs(e){var t=e.cm,n=t.display;e.updatedDisplay&&Vn(t),e.barMeasure=yn(t),n.maxLineChanged&&!t.options.lineWrapping&&(e.adjustWidthTo=jo(t,n.maxLine,n.maxLine.text.length).left+3,t.display.sizerWidth=e.adjustWidthTo,e.barMeasure.scrollWidth=Math.max(n.scroller.clientWidth,n.sizer.offsetLeft+e.adjustWidthTo+Yt(t)+t.display.barWidth),e.maxScrollLeft=Math.max(0,n.sizer.offsetLeft+e.adjustWidthTo-wr(t))),(e.updatedDisplay||e.selectionChanged)&&(e.preparedSelection=n.input.prepareSelection())}function Xs(e){var t=e.cm;e.adjustWidthTo!=null&&(t.display.sizer.style.minWidth=e.adjustWidthTo+"px",e.maxScrollLeft=e.display.viewTo)){var n=+new Date+e.options.workTime,r=fn(e,t.highlightFrontier),i=[];t.iter(r.line,Math.min(t.first+t.size,e.display.viewTo+500),function(o){if(r.line>=e.display.viewFrom){var l=o.styles,a=o.text.length>e.options.maxHighlightLength?Gt(t.mode,r.state):null,s=mo(e,o,r,!0);a&&(r.state=a),o.styles=s.styles;var u=o.styleClasses,h=s.classes;h?o.styleClasses=h:u&&(o.styleClasses=null);for(var x=!l||l.length!=o.styles.length||u!=h&&(!u||!h||u.bgClass!=h.bgClass||u.textClass!=h.textClass),D=0;!x&&Dn)return kn(e,e.options.workDelay),!0}),t.highlightFrontier=r.line,t.modeFrontier=Math.max(t.modeFrontier,r.line),i.length&&At(e,function(){for(var o=0;o=n.viewFrom&&t.visible.to<=n.viewTo&&(n.updateLineNumbers==null||n.updateLineNumbers>=n.viewTo)&&n.renderedView==n.view&&tl(e)==0)return!1;dl(e)&&(hr(e),t.dims=Ii(e));var i=r.first+r.size,o=Math.max(t.visible.from-e.options.viewportMargin,r.first),l=Math.min(i,t.visible.to+e.options.viewportMargin);n.viewFroml&&n.viewTo-l<20&&(l=Math.min(i,n.viewTo)),$t&&(o=Li(e.doc,o),l=No(e.doc,l));var a=o!=n.viewFrom||l!=n.viewTo||n.lastWrapHeight!=t.wrapperHeight||n.lastWrapWidth!=t.wrapperWidth;zs(e,o,l),n.viewOffset=er(ye(e.doc,n.viewFrom)),e.display.mover.style.top=n.viewOffset+"px";var s=tl(e);if(!a&&s==0&&!t.force&&n.renderedView==n.view&&(n.updateLineNumbers==null||n.updateLineNumbers>=n.viewTo))return!1;var u=Zs(e);return s>4&&(n.lineDiv.style.display="none"),$s(e,n.updateLineNumbers,t.dims),s>4&&(n.lineDiv.style.display=""),n.renderedView=n.view,Vs(u),F(n.cursorDiv),F(n.selectionDiv),n.gutters.style.height=n.sizer.style.minHeight=0,a&&(n.lastWrapHeight=t.wrapperHeight,n.lastWrapWidth=t.wrapperWidth,kn(e,400)),n.updateLineNumbers=null,!0}function fl(e,t){for(var n=t.viewport,r=!0;;r=!1){if(!r||!e.options.lineWrapping||t.oldDisplayWidth==wr(e)){if(n&&n.top!=null&&(n={top:Math.min(e.doc.height+Mi(e.display)-Fi(e),n.top)}),t.visible=$n(e.display,e.doc,n),t.visible.from>=e.display.viewFrom&&t.visible.to<=e.display.viewTo)break}else r&&(t.visible=$n(e.display,e.doc,n));if(!Ki(e,t))break;Vn(e);var i=yn(e);vn(e),Xr(e,i),Xi(e,i),t.force=!1}t.signal(e,"update",e),(e.display.viewFrom!=e.display.reportedViewFrom||e.display.viewTo!=e.display.reportedViewTo)&&(t.signal(e,"viewportChange",e,e.display.viewFrom,e.display.viewTo),e.display.reportedViewFrom=e.display.viewFrom,e.display.reportedViewTo=e.display.viewTo)}function Ui(e,t){var n=new ti(e,t);if(Ki(e,n)){Vn(e),fl(e,n);var r=yn(e);vn(e),Xr(e,r),Xi(e,r),n.finish()}}function $s(e,t,n){var r=e.display,i=e.options.lineNumbers,o=r.lineDiv,l=o.firstChild;function a(H){var Z=H.nextSibling;return Y&&z&&e.display.currentWheelTarget==H?H.style.display="none":H.parentNode.removeChild(H),Z}for(var s=r.view,u=r.viewFrom,h=0;h-1&&(L=!1),zo(e,x,u,n)),L&&(F(x.lineNumber),x.lineNumber.appendChild(document.createTextNode(re(e.options,u)))),l=x.node.nextSibling}u+=x.size}for(;l;)l=a(l)}function Gi(e){var t=e.gutters.offsetWidth;e.sizer.style.marginLeft=t+"px",ot(e,"gutterChanged",e)}function Xi(e,t){e.display.sizer.style.minHeight=t.docHeight+"px",e.display.heightForcer.style.top=t.docHeight+"px",e.display.gutters.style.height=t.docHeight+e.display.barHeight+Yt(e)+"px"}function cl(e){var t=e.display,n=t.view;if(!(!t.alignWidgets&&(!t.gutters.firstChild||!e.options.fixedGutter))){for(var r=zi(t)-t.scroller.scrollLeft+e.doc.scrollLeft,i=t.gutters.offsetWidth,o=r+"px",l=0;l=105&&(i.wrapper.style.clipPath="inset(0px)"),i.wrapper.setAttribute("translate","no"),k&&I<8&&(i.gutters.style.zIndex=-1,i.scroller.style.paddingRight=0),!Y&&!(_&&N)&&(i.scroller.draggable=!0),e&&(e.appendChild?e.appendChild(i.wrapper):e(i.wrapper)),i.viewFrom=i.viewTo=t.first,i.reportedViewFrom=i.reportedViewTo=t.first,i.view=[],i.renderedView=null,i.externalMeasured=null,i.viewOffset=0,i.lastWrapHeight=i.lastWrapWidth=0,i.updateLineNumbers=null,i.nativeBarWidth=i.barHeight=i.barWidth=0,i.scrollbarsClipped=!1,i.lineNumWidth=i.lineNumInnerWidth=i.lineNumChars=null,i.alignWidgets=!1,i.cachedCharWidth=i.cachedTextHeight=i.cachedPaddingH=null,i.maxLine=null,i.maxLineLength=0,i.maxLineChanged=!1,i.wheelDX=i.wheelDY=i.wheelStartX=i.wheelStartY=null,i.shift=!1,i.selForContextMenu=null,i.activeTouch=null,i.gutterSpecs=Yi(r.gutters,r.lineNumbers),hl(i),n.init(i)}var ri=0,rr=null;k?rr=-.53:_?rr=15:S?rr=-.7:V&&(rr=-1/3);function pl(e){var t=e.wheelDeltaX,n=e.wheelDeltaY;return t==null&&e.detail&&e.axis==e.HORIZONTAL_AXIS&&(t=e.detail),n==null&&e.detail&&e.axis==e.VERTICAL_AXIS?n=e.detail:n==null&&(n=e.wheelDelta),{x:t,y:n}}function tu(e){var t=pl(e);return t.x*=rr,t.y*=rr,t}function gl(e,t){S&&R==102&&(e.display.chromeScrollHack==null?e.display.sizer.style.pointerEvents="none":clearTimeout(e.display.chromeScrollHack),e.display.chromeScrollHack=setTimeout(function(){e.display.chromeScrollHack=null,e.display.sizer.style.pointerEvents=""},100));var n=pl(t),r=n.x,i=n.y,o=rr;t.deltaMode===0&&(r=t.deltaX,i=t.deltaY,o=1);var l=e.display,a=l.scroller,s=a.scrollWidth>a.clientWidth,u=a.scrollHeight>a.clientHeight;if(r&&s||i&&u){if(i&&z&&Y){e:for(var h=t.target,x=l.view;h!=a;h=h.parentNode)for(var D=0;D=0&&ce(e,r.to())<=0)return n}return-1};var He=function(e,t){this.anchor=e,this.head=t};He.prototype.from=function(){return Wr(this.anchor,this.head)},He.prototype.to=function(){return wt(this.anchor,this.head)},He.prototype.empty=function(){return this.head.line==this.anchor.line&&this.head.ch==this.anchor.ch};function Kt(e,t,n){var r=e&&e.options.selectionsMayTouch,i=t[n];t.sort(function(D,L){return ce(D.from(),L.from())}),n=ve(t,i);for(var o=1;o0:s>=0){var u=Wr(a.from(),l.from()),h=wt(a.to(),l.to()),x=a.empty()?l.from()==l.head:a.from()==a.head;o<=n&&--n,t.splice(--o,2,new He(x?h:u,x?u:h))}}return new Ot(t,n)}function pr(e,t){return new Ot([new He(e,t||e)],0)}function gr(e){return e.text?B(e.from.line+e.text.length-1,we(e.text).length+(e.text.length==1?e.from.ch:0)):e.to}function vl(e,t){if(ce(e,t.from)<0)return e;if(ce(e,t.to)<=0)return gr(t);var n=e.line+t.text.length-(t.to.line-t.from.line)-1,r=e.ch;return e.line==t.to.line&&(r+=gr(t).ch-t.to.ch),B(n,r)}function Qi(e,t){for(var n=[],r=0;r1&&e.remove(a.line+1,H-1),e.insert(a.line+1,ae)}ot(e,"change",e,t)}function vr(e,t,n){function r(i,o,l){if(i.linked)for(var a=0;a1&&!e.done[e.done.length-2].ranges)return e.done.pop(),we(e.done)}function wl(e,t,n,r){var i=e.history;i.undone.length=0;var o=+new Date,l,a;if((i.lastOp==r||i.lastOrigin==t.origin&&t.origin&&(t.origin.charAt(0)=="+"&&i.lastModTime>o-(e.cm?e.cm.options.historyEventDelay:500)||t.origin.charAt(0)=="*"))&&(l=iu(i,i.lastOp==r)))a=we(l.changes),ce(t.from,t.to)==0&&ce(t.from,a.to)==0?a.to=gr(t):l.changes.push(Vi(e,t));else{var s=we(i.done);for((!s||!s.ranges)&&ii(e.sel,i.done),l={changes:[Vi(e,t)],generation:i.generation},i.done.push(l);i.done.length>i.undoDepth;)i.done.shift(),i.done[0].ranges||i.done.shift()}i.done.push(n),i.generation=++i.maxGeneration,i.lastModTime=i.lastSelTime=o,i.lastOp=i.lastSelOp=r,i.lastOrigin=i.lastSelOrigin=t.origin,a||Ye(e,"historyAdded")}function ou(e,t,n,r){var i=t.charAt(0);return i=="*"||i=="+"&&n.ranges.length==r.ranges.length&&n.somethingSelected()==r.somethingSelected()&&new Date-e.history.lastSelTime<=(e.cm?e.cm.options.historyEventDelay:500)}function lu(e,t,n,r){var i=e.history,o=r&&r.origin;n==i.lastSelOp||o&&i.lastSelOrigin==o&&(i.lastModTime==i.lastSelTime&&i.lastOrigin==o||ou(e,o,we(i.done),t))?i.done[i.done.length-1]=t:ii(t,i.done),i.lastSelTime=+new Date,i.lastSelOrigin=o,i.lastSelOp=n,r&&r.clearRedo!==!1&&kl(i.undone)}function ii(e,t){var n=we(t);n&&n.ranges&&n.equals(e)||t.push(e)}function Sl(e,t,n,r){var i=t["spans_"+e.id],o=0;e.iter(Math.max(e.first,n),Math.min(e.first+e.size,r),function(l){l.markedSpans&&((i||(i=t["spans_"+e.id]={}))[o]=l.markedSpans),++o})}function au(e){if(!e)return null;for(var t,n=0;n-1&&(we(a)[x]=u[x],delete u[x])}}return r}function $i(e,t,n,r){if(r){var i=e.anchor;if(n){var o=ce(t,i)<0;o!=ce(n,i)<0?(i=t,t=n):o!=ce(t,n)<0&&(t=n)}return new He(i,t)}else return new He(n||t,t)}function oi(e,t,n,r,i){i==null&&(i=e.cm&&(e.cm.display.shift||e.extend)),gt(e,new Ot([$i(e.sel.primary(),t,n,i)],0),r)}function Tl(e,t,n){for(var r=[],i=e.cm&&(e.cm.display.shift||e.extend),o=0;o=t.ch:a.to>t.ch))){if(i&&(Ye(s,"beforeCursorEnter"),s.explicitlyCleared))if(o.markedSpans){--l;continue}else break;if(!s.atomic)continue;if(n){var x=s.find(r<0?1:-1),D=void 0;if((r<0?h:u)&&(x=Nl(e,x,-r,x&&x.line==t.line?o:null)),x&&x.line==t.line&&(D=ce(x,n))&&(r<0?D<0:D>0))return Qr(e,x,t,r,i)}var L=s.find(r<0?-1:1);return(r<0?u:h)&&(L=Nl(e,L,r,L.line==t.line?o:null)),L?Qr(e,L,t,r,i):null}}return t}function ai(e,t,n,r,i){var o=r||1,l=Qr(e,t,n,o,i)||!i&&Qr(e,t,n,o,!0)||Qr(e,t,n,-o,i)||!i&&Qr(e,t,n,-o,!0);return l||(e.cantEdit=!0,B(e.first,0))}function Nl(e,t,n,r){return n<0&&t.ch==0?t.line>e.first?Ae(e,B(t.line-1)):null:n>0&&t.ch==(r||ye(e,t.line)).text.length?t.line=0;--i)Pl(e,{from:r[i].from,to:r[i].to,text:i?[""]:t.text,origin:t.origin});else Pl(e,t)}}function Pl(e,t){if(!(t.text.length==1&&t.text[0]==""&&ce(t.from,t.to)==0)){var n=Qi(e,t);wl(e,t,n,e.cm?e.cm.curOp.id:NaN),Ln(e,t,n,wi(e,t));var r=[];vr(e,function(i,o){!o&&ve(r,i.history)==-1&&(Rl(i.history,t),r.push(i.history)),Ln(i,t,null,wi(i,t))})}}function si(e,t,n){var r=e.cm&&e.cm.state.suppressEdits;if(!(r&&!n)){for(var i=e.history,o,l=e.sel,a=t=="undo"?i.done:i.undone,s=t=="undo"?i.undone:i.done,u=0;u=0;--L){var H=D(L);if(H)return H.v}}}}function Il(e,t){if(t!=0&&(e.first+=t,e.sel=new Ot(Ie(e.sel.ranges,function(i){return new He(B(i.anchor.line+t,i.anchor.ch),B(i.head.line+t,i.head.ch))}),e.sel.primIndex),e.cm)){St(e.cm,e.first,e.first-t,t);for(var n=e.cm.display,r=n.viewFrom;re.lastLine())){if(t.from.lineo&&(t={from:t.from,to:B(o,ye(e,o).text.length),text:[t.text[0]],origin:t.origin}),t.removed=Vt(e,t.from,t.to),n||(n=Qi(e,t)),e.cm?fu(e.cm,t,r):Zi(e,t,r),li(e,n,Ve),e.cantEdit&&ai(e,B(e.firstLine(),0))&&(e.cantEdit=!1)}}function fu(e,t,n){var r=e.doc,i=e.display,o=t.from,l=t.to,a=!1,s=o.line;e.options.lineWrapping||(s=f(qt(ye(r,o.line))),r.iter(s,l.line+1,function(L){if(L==i.maxLine)return a=!0,!0})),r.sel.contains(t.from,t.to)>-1&&It(e),Zi(r,t,n,el(e)),e.options.lineWrapping||(r.iter(s,o.line+t.text.length,function(L){var H=Un(L);H>i.maxLineLength&&(i.maxLine=L,i.maxLineLength=H,i.maxLineChanged=!0,a=!1)}),a&&(e.curOp.updateMaxLine=!0)),$a(r,o.line),kn(e,400);var u=t.text.length-(l.line-o.line)-1;t.full?St(e):o.line==l.line&&t.text.length==1&&!xl(e.doc,t)?dr(e,o.line,"text"):St(e,o.line,l.line+1,u);var h=Ft(e,"changes"),x=Ft(e,"change");if(x||h){var D={from:o,to:l,text:t.text,removed:t.removed,origin:t.origin};x&&ot(e,"change",e,D),h&&(e.curOp.changeObjs||(e.curOp.changeObjs=[])).push(D)}e.display.selForContextMenu=null}function Zr(e,t,n,r,i){var o;r||(r=n),ce(r,n)<0&&(o=[r,n],n=o[0],r=o[1]),typeof t=="string"&&(t=e.splitLines(t)),Jr(e,{from:n,to:r,text:t,origin:i})}function zl(e,t,n,r){n1||!(this.children[0]instanceof Cn))){var a=[];this.collapse(a),this.children=[new Cn(a)],this.children[0].parent=this}},collapse:function(e){for(var t=0;t50){for(var l=i.lines.length%25+25,a=l;a10);e.parent.maybeSpill()}},iterN:function(e,t,n){for(var r=0;re.display.maxLineLength&&(e.display.maxLine=u,e.display.maxLineLength=h,e.display.maxLineChanged=!0)}r!=null&&e&&this.collapsed&&St(e,r,i+1),this.lines.length=0,this.explicitlyCleared=!0,this.atomic&&this.doc.cantEdit&&(this.doc.cantEdit=!1,e&&Fl(e.doc)),e&&ot(e,"markerCleared",e,this,r,i),t&&Fr(e),this.parent&&this.parent.clear()}},mr.prototype.find=function(e,t){e==null&&this.type=="bookmark"&&(e=1);for(var n,r,i=0;i0||l==0&&o.clearWhenEmpty!==!1)return o;if(o.replacedWith&&(o.collapsed=!0,o.widgetNode=T("span",[o.replacedWith],"CodeMirror-widget"),r.handleMouseEvents||o.widgetNode.setAttribute("cm-ignore-events","true"),r.insertLeft&&(o.widgetNode.insertLeft=!0)),o.collapsed){if(Ao(e,t.line,t,n,o)||t.line!=n.line&&Ao(e,n.line,t,n,o))throw new Error("Inserting collapsed marker partially overlapping an existing one");ts()}o.addToHistory&&wl(e,{from:t,to:n,origin:"markText"},e.sel,NaN);var a=t.line,s=e.cm,u;if(e.iter(a,n.line+1,function(x){s&&o.collapsed&&!s.options.lineWrapping&&qt(x)==s.display.maxLine&&(u=!0),o.collapsed&&a!=t.line&&Et(x,0),ns(x,new _n(o,a==t.line?t.ch:null,a==n.line?n.ch:null),e.cm&&e.cm.curOp),++a}),o.collapsed&&e.iter(t.line,n.line+1,function(x){cr(e,x)&&Et(x,0)}),o.clearOnEnter&&Se(o,"beforeCursorEnter",function(){return o.clear()}),o.readOnly&&(es(),(e.history.done.length||e.history.undone.length)&&e.clearHistory()),o.collapsed&&(o.id=++Hl,o.atomic=!0),s){if(u&&(s.curOp.updateMaxLine=!0),o.collapsed)St(s,t.line,n.line+1);else if(o.className||o.startStyle||o.endStyle||o.css||o.attributes||o.title)for(var h=t.line;h<=n.line;h++)dr(s,h,"text");o.atomic&&Fl(s.doc),ot(s,"markerAdded",s,o)}return o}var Fn=function(e,t){this.markers=e,this.primary=t;for(var n=0;n=0;s--)Jr(this,r[s]);a?Dl(this,a):this.cm&&Gr(this.cm)}),undo:at(function(){si(this,"undo")}),redo:at(function(){si(this,"redo")}),undoSelection:at(function(){si(this,"undo",!0)}),redoSelection:at(function(){si(this,"redo",!0)}),setExtending:function(e){this.extend=e},getExtending:function(){return this.extend},historySize:function(){for(var e=this.history,t=0,n=0,r=0;r=e.ch)&&t.push(i.marker.parent||i.marker)}return t},findMarks:function(e,t,n){e=Ae(this,e),t=Ae(this,t);var r=[],i=e.line;return this.iter(e.line,t.line+1,function(o){var l=o.markedSpans;if(l)for(var a=0;a=s.to||s.from==null&&i!=e.line||s.from!=null&&i==t.line&&s.from>=t.ch)&&(!n||n(s.marker))&&r.push(s.marker.parent||s.marker)}++i}),r},getAllMarks:function(){var e=[];return this.iter(function(t){var n=t.markedSpans;if(n)for(var r=0;re)return t=e,!0;e-=o,++n}),Ae(this,B(n,t))},indexFromPos:function(e){e=Ae(this,e);var t=e.ch;if(e.linet&&(t=e.from),e.to!=null&&e.to-1){t.state.draggingText(e),setTimeout(function(){return t.display.input.focus()},20);return}try{var h=e.dataTransfer.getData("Text");if(h){var x;if(t.state.draggingText&&!t.state.draggingText.copy&&(x=t.listSelections()),li(t.doc,pr(n,n)),x)for(var D=0;D=0;a--)Zr(e.doc,"",r[a].from,r[a].to,"+delete");Gr(e)})}function to(e,t,n){var r=Mt(e.text,t+n,n);return r<0||r>e.text.length?null:r}function ro(e,t,n){var r=to(e,t.ch,n);return r==null?null:new B(t.line,r,n<0?"after":"before")}function no(e,t,n,r,i){if(e){t.doc.direction=="rtl"&&(i=-i);var o=Re(n,t.doc.direction);if(o){var l=i<0?we(o):o[0],a=i<0==(l.level==1),s=a?"after":"before",u;if(l.level>0||t.doc.direction=="rtl"){var h=qr(t,n);u=i<0?n.text.length-1:0;var x=Qt(t,h,u).top;u=Pt(function(D){return Qt(t,h,D).top==x},i<0==(l.level==1)?l.from:l.to-1,u),s=="before"&&(u=to(n,u,1))}else u=i<0?l.to:l.from;return new B(r,u,s)}}return new B(r,i<0?n.text.length:0,i<0?"before":"after")}function Lu(e,t,n,r){var i=Re(t,e.doc.direction);if(!i)return ro(t,n,r);n.ch>=t.text.length?(n.ch=t.text.length,n.sticky="before"):n.ch<=0&&(n.ch=0,n.sticky="after");var o=lr(i,n.ch,n.sticky),l=i[o];if(e.doc.direction=="ltr"&&l.level%2==0&&(r>0?l.to>n.ch:l.from=l.from&&D>=h.begin)){var L=x?"before":"after";return new B(n.line,D,L)}}var H=function(ae,he,se){for(var ge=function(Ke,st){return st?new B(n.line,a(Ke,1),"before"):new B(n.line,Ke,"after")};ae>=0&&ae0==(Le.level!=1),Ee=ke?se.begin:a(se.end,-1);if(Le.from<=Ee&&Ee0?h.end:a(h.begin,-1);return ie!=null&&!(r>0&&ie==t.text.length)&&(Z=H(r>0?0:i.length-1,r,u(ie)),Z)?Z:null}var En={selectAll:El,singleSelection:function(e){return e.setSelection(e.getCursor("anchor"),e.getCursor("head"),Ve)},killLine:function(e){return en(e,function(t){if(t.empty()){var n=ye(e.doc,t.head.line).text.length;return t.head.ch==n&&t.head.line0)i=new B(i.line,i.ch+1),e.replaceRange(o.charAt(i.ch-1)+o.charAt(i.ch-2),B(i.line,i.ch-2),i,"+transpose");else if(i.line>e.doc.first){var l=ye(e.doc,i.line-1).text;l&&(i=new B(i.line,1),e.replaceRange(o.charAt(0)+e.doc.lineSeparator()+l.charAt(l.length-1),B(i.line-1,l.length-1),i,"+transpose"))}}n.push(new He(i,i))}e.setSelections(n)})},newlineAndIndent:function(e){return At(e,function(){for(var t=e.listSelections(),n=t.length-1;n>=0;n--)e.replaceRange(e.doc.lineSeparator(),t[n].anchor,t[n].head,"+input");t=e.listSelections();for(var r=0;re&&ce(t,this.pos)==0&&n==this.button};var Pn,In;function Nu(e,t){var n=+new Date;return In&&In.compare(n,e,t)?(Pn=In=null,"triple"):Pn&&Pn.compare(n,e,t)?(In=new oo(n,e,t),Pn=null,"double"):(Pn=new oo(n,e,t),In=null,"single")}function ra(e){var t=this,n=t.display;if(!(Qe(t,e)||n.activeTouch&&n.input.supportsTouch())){if(n.input.ensurePolled(),n.shift=e.shiftKey,tr(n,e)){Y||(n.scroller.draggable=!1,setTimeout(function(){return n.scroller.draggable=!0},100));return}if(!lo(t,e)){var r=Lr(t,e),i=Rt(e),o=r?Nu(r,i):"single";le(t).focus(),i==1&&t.state.selectingText&&t.state.selectingText(e),!(r&&Eu(t,i,r,o,e))&&(i==1?r?Pu(t,r,o,e):ln(e)==n.scroller&&pt(e):i==2?(r&&oi(t.doc,r),setTimeout(function(){return n.input.focus()},20)):i==3&&(J?t.display.input.onContextMenu(e):Hi(t)))}}}function Eu(e,t,n,r,i){var o="Click";return r=="double"?o="Double"+o:r=="triple"&&(o="Triple"+o),o=(t==1?"Left":t==2?"Middle":"Right")+o,On(e,Xl(o,i),i,function(l){if(typeof l=="string"&&(l=En[l]),!l)return!1;var a=!1;try{e.isReadOnly()&&(e.state.suppressEdits=!0),a=l(e,n)!=qe}finally{e.state.suppressEdits=!1}return a})}function Ou(e,t,n){var r=e.getOption("configureMouse"),i=r?r(e,t,n):{};if(i.unit==null){var o=X?n.shiftKey&&n.metaKey:n.altKey;i.unit=o?"rectangle":t=="single"?"char":t=="double"?"word":"line"}return(i.extend==null||e.doc.extend)&&(i.extend=e.doc.extend||n.shiftKey),i.addNew==null&&(i.addNew=z?n.metaKey:n.ctrlKey),i.moveOnDrag==null&&(i.moveOnDrag=!(z?n.altKey:n.ctrlKey)),i}function Pu(e,t,n,r){k?setTimeout(xe(nl,e),0):e.curOp.focus=y(fe(e));var i=Ou(e,n,r),o=e.doc.sel,l;e.options.dragDrop&&xi&&!e.isReadOnly()&&n=="single"&&(l=o.contains(t))>-1&&(ce((l=o.ranges[l]).from(),t)<0||t.xRel>0)&&(ce(l.to(),t)>0||t.xRel<0)?Iu(e,r,t,i):zu(e,r,t,i)}function Iu(e,t,n,r){var i=e.display,o=!1,l=lt(e,function(u){Y&&(i.scroller.draggable=!1),e.state.draggingText=!1,e.state.delayingBlurEvent&&(e.hasFocus()?e.state.delayingBlurEvent=!1:Hi(e)),ht(i.wrapper.ownerDocument,"mouseup",l),ht(i.wrapper.ownerDocument,"mousemove",a),ht(i.scroller,"dragstart",s),ht(i.scroller,"drop",l),o||(pt(u),r.addNew||oi(e.doc,n,null,null,r.extend),Y&&!V||k&&I==9?setTimeout(function(){i.wrapper.ownerDocument.body.focus({preventScroll:!0}),i.input.focus()},20):i.input.focus())}),a=function(u){o=o||Math.abs(t.clientX-u.clientX)+Math.abs(t.clientY-u.clientY)>=10},s=function(){return o=!0};Y&&(i.scroller.draggable=!0),e.state.draggingText=l,l.copy=!r.moveOnDrag,Se(i.wrapper.ownerDocument,"mouseup",l),Se(i.wrapper.ownerDocument,"mousemove",a),Se(i.scroller,"dragstart",s),Se(i.scroller,"drop",l),e.state.delayingBlurEvent=!0,setTimeout(function(){return i.input.focus()},20),i.scroller.dragDrop&&i.scroller.dragDrop()}function na(e,t,n){if(n=="char")return new He(t,t);if(n=="word")return e.findWordAt(t);if(n=="line")return new He(B(t.line,0),Ae(e.doc,B(t.line+1,0)));var r=n(e,t);return new He(r.from,r.to)}function zu(e,t,n,r){k&&Hi(e);var i=e.display,o=e.doc;pt(t);var l,a,s=o.sel,u=s.ranges;if(r.addNew&&!r.extend?(a=o.sel.contains(n),a>-1?l=u[a]:l=new He(n,n)):(l=o.sel.primary(),a=o.sel.primIndex),r.unit=="rectangle")r.addNew||(l=new He(n,n)),n=Lr(e,t,!0,!0),a=-1;else{var h=na(e,n,r.unit);r.extend?l=$i(l,h.anchor,h.head,r.extend):l=h}r.addNew?a==-1?(a=u.length,gt(o,Kt(e,u.concat([l]),a),{scroll:!1,origin:"*mouse"})):u.length>1&&u[a].empty()&&r.unit=="char"&&!r.extend?(gt(o,Kt(e,u.slice(0,a).concat(u.slice(a+1)),0),{scroll:!1,origin:"*mouse"}),s=o.sel):eo(o,a,l,dt):(a=0,gt(o,new Ot([l],0),dt),s=o.sel);var x=n;function D(se){if(ce(x,se)!=0)if(x=se,r.unit=="rectangle"){for(var ge=[],Le=e.options.tabSize,ke=Fe(ye(o,n.line).text,n.ch,Le),Ee=Fe(ye(o,se.line).text,se.ch,Le),Ke=Math.min(ke,Ee),st=Math.max(ke,Ee),Xe=Math.min(n.line,se.line),Nt=Math.min(e.lastLine(),Math.max(n.line,se.line));Xe<=Nt;Xe++){var Tt=ye(o,Xe).text,tt=_e(Tt,Ke,Le);Ke==st?ge.push(new He(B(Xe,tt),B(Xe,tt))):Tt.length>tt&&ge.push(new He(B(Xe,tt),B(Xe,_e(Tt,st,Le))))}ge.length||ge.push(new He(n,n)),gt(o,Kt(e,s.ranges.slice(0,a).concat(ge),a),{origin:"*mouse",scroll:!1}),e.scrollIntoView(se)}else{var Ct=l,ft=na(e,se,r.unit),nt=Ct.anchor,rt;ce(ft.anchor,nt)>0?(rt=ft.head,nt=Wr(Ct.from(),ft.anchor)):(rt=ft.anchor,nt=wt(Ct.to(),ft.head));var Ze=s.ranges.slice(0);Ze[a]=Bu(e,new He(Ae(o,nt),rt)),gt(o,Kt(e,Ze,a),dt)}}var L=i.wrapper.getBoundingClientRect(),H=0;function Z(se){var ge=++H,Le=Lr(e,se,!0,r.unit=="rectangle");if(Le)if(ce(Le,x)!=0){e.curOp.focus=y(fe(e)),D(Le);var ke=$n(i,o);(Le.line>=ke.to||Le.lineL.bottom?20:0;Ee&&setTimeout(lt(e,function(){H==ge&&(i.scroller.scrollTop+=Ee,Z(se))}),50)}}function ie(se){e.state.selectingText=!1,H=1/0,se&&(pt(se),i.input.focus()),ht(i.wrapper.ownerDocument,"mousemove",ae),ht(i.wrapper.ownerDocument,"mouseup",he),o.history.lastSelOrigin=null}var ae=lt(e,function(se){se.buttons===0||!Rt(se)?ie(se):Z(se)}),he=lt(e,ie);e.state.selectingText=he,Se(i.wrapper.ownerDocument,"mousemove",ae),Se(i.wrapper.ownerDocument,"mouseup",he)}function Bu(e,t){var n=t.anchor,r=t.head,i=ye(e.doc,n.line);if(ce(n,r)==0&&n.sticky==r.sticky)return t;var o=Re(i);if(!o)return t;var l=lr(o,n.ch,n.sticky),a=o[l];if(a.from!=n.ch&&a.to!=n.ch)return t;var s=l+(a.from==n.ch==(a.level!=1)?0:1);if(s==0||s==o.length)return t;var u;if(r.line!=n.line)u=(r.line-n.line)*(e.doc.direction=="ltr"?1:-1)>0;else{var h=lr(o,r.ch,r.sticky),x=h-l||(r.ch-n.ch)*(a.level==1?-1:1);h==s-1||h==s?u=x<0:u=x>0}var D=o[s+(u?-1:0)],L=u==(D.level==1),H=L?D.from:D.to,Z=L?"after":"before";return n.ch==H&&n.sticky==Z?t:new He(new B(n.line,H,Z),r)}function ia(e,t,n,r){var i,o;if(t.touches)i=t.touches[0].clientX,o=t.touches[0].clientY;else try{i=t.clientX,o=t.clientY}catch{return!1}if(i>=Math.floor(e.display.gutters.getBoundingClientRect().right))return!1;r&&pt(t);var l=e.display,a=l.lineDiv.getBoundingClientRect();if(o>a.bottom||!Ft(e,n))return kt(t);o-=a.top-l.viewOffset;for(var s=0;s=i){var h=m(e.doc,o),x=e.display.gutterSpecs[s];return Ye(e,n,e,h,x.className,t),kt(t)}}}function lo(e,t){return ia(e,t,"gutterClick",!0)}function oa(e,t){tr(e.display,t)||Ru(e,t)||Qe(e,t,"contextmenu")||J||e.display.input.onContextMenu(t)}function Ru(e,t){return Ft(e,"gutterContextMenu")?ia(e,t,"gutterContextMenu",!1):!1}function la(e){e.display.wrapper.className=e.display.wrapper.className.replace(/\s*cm-s-\S+/g,"")+e.options.theme.replace(/(^|\s)\s*/g," cm-s-"),gn(e)}var tn={toString:function(){return"CodeMirror.Init"}},aa={},di={};function Wu(e){var t=e.optionHandlers;function n(r,i,o,l){e.defaults[r]=i,o&&(t[r]=l?function(a,s,u){u!=tn&&o(a,s,u)}:o)}e.defineOption=n,e.Init=tn,n("value","",function(r,i){return r.setValue(i)},!0),n("mode",null,function(r,i){r.doc.modeOption=i,Ji(r)},!0),n("indentUnit",2,Ji,!0),n("indentWithTabs",!1),n("smartIndent",!0),n("tabSize",4,function(r){Sn(r),gn(r),St(r)},!0),n("lineSeparator",null,function(r,i){if(r.doc.lineSep=i,!!i){var o=[],l=r.doc.first;r.doc.iter(function(s){for(var u=0;;){var h=s.text.indexOf(i,u);if(h==-1)break;u=h+i.length,o.push(B(l,h))}l++});for(var a=o.length-1;a>=0;a--)Zr(r.doc,i,o[a],B(o[a].line,o[a].ch+i.length))}}),n("specialChars",/[\u0000-\u001f\u007f-\u009f\u00ad\u061c\u200b\u200e\u200f\u2028\u2029\u202d\u202e\u2066\u2067\u2069\ufeff\ufff9-\ufffc]/g,function(r,i,o){r.state.specialChars=new RegExp(i.source+(i.test(" ")?"":"| "),"g"),o!=tn&&r.refresh()}),n("specialCharPlaceholder",ps,function(r){return r.refresh()},!0),n("electricChars",!0),n("inputStyle",N?"contenteditable":"textarea",function(){throw new Error("inputStyle can not (yet) be changed in a running editor")},!0),n("spellcheck",!1,function(r,i){return r.getInputField().spellcheck=i},!0),n("autocorrect",!1,function(r,i){return r.getInputField().autocorrect=i},!0),n("autocapitalize",!1,function(r,i){return r.getInputField().autocapitalize=i},!0),n("rtlMoveVisually",!q),n("wholeLineUpdateBefore",!0),n("theme","default",function(r){la(r),wn(r)},!0),n("keyMap","default",function(r,i,o){var l=fi(i),a=o!=tn&&fi(o);a&&a.detach&&a.detach(r,l),l.attach&&l.attach(r,a||null)}),n("extraKeys",null),n("configureMouse",null),n("lineWrapping",!1,_u,!0),n("gutters",[],function(r,i){r.display.gutterSpecs=Yi(i,r.options.lineNumbers),wn(r)},!0),n("fixedGutter",!0,function(r,i){r.display.gutters.style.left=i?zi(r.display)+"px":"0",r.refresh()},!0),n("coverGutterNextToScrollbar",!1,function(r){return Xr(r)},!0),n("scrollbarStyle","native",function(r){ul(r),Xr(r),r.display.scrollbars.setScrollTop(r.doc.scrollTop),r.display.scrollbars.setScrollLeft(r.doc.scrollLeft)},!0),n("lineNumbers",!1,function(r,i){r.display.gutterSpecs=Yi(r.options.gutters,i),wn(r)},!0),n("firstLineNumber",1,wn,!0),n("lineNumberFormatter",function(r){return r},wn,!0),n("showCursorWhenSelecting",!1,vn,!0),n("resetSelectionOnContextMenu",!0),n("lineWiseCopyCut",!0),n("pasteLinesPerSelection",!0),n("selectionsMayTouch",!1),n("readOnly",!1,function(r,i){i=="nocursor"&&(Ur(r),r.display.input.blur()),r.display.input.readOnlyChanged(i)}),n("screenReaderLabel",null,function(r,i){i=i===""?null:i,r.display.input.screenReaderLabelChanged(i)}),n("disableInput",!1,function(r,i){i||r.display.input.reset()},!0),n("dragDrop",!0,Hu),n("allowDropFileTypes",null),n("cursorBlinkRate",530),n("cursorScrollMargin",0),n("cursorHeight",1,vn,!0),n("singleCursorHeightPerLine",!0,vn,!0),n("workTime",100),n("workDelay",100),n("flattenSpans",!0,Sn,!0),n("addModeClass",!1,Sn,!0),n("pollInterval",100),n("undoDepth",200,function(r,i){return r.doc.history.undoDepth=i}),n("historyEventDelay",1250),n("viewportMargin",10,function(r){return r.refresh()},!0),n("maxHighlightLength",1e4,Sn,!0),n("moveInputWithCursor",!0,function(r,i){i||r.display.input.resetPosition()}),n("tabindex",null,function(r,i){return r.display.input.getField().tabIndex=i||""}),n("autofocus",null),n("direction","ltr",function(r,i){return r.doc.setDirection(i)},!0),n("phrases",null)}function Hu(e,t,n){var r=n&&n!=tn;if(!t!=!r){var i=e.display.dragFunctions,o=t?Se:ht;o(e.display.scroller,"dragstart",i.start),o(e.display.scroller,"dragenter",i.enter),o(e.display.scroller,"dragover",i.over),o(e.display.scroller,"dragleave",i.leave),o(e.display.scroller,"drop",i.drop)}}function _u(e){e.options.lineWrapping?(j(e.display.wrapper,"CodeMirror-wrap"),e.display.sizer.style.minWidth="",e.display.sizerWidth=null):($(e.display.wrapper,"CodeMirror-wrap"),Ci(e)),Bi(e),St(e),gn(e),setTimeout(function(){return Xr(e)},100)}function Ge(e,t){var n=this;if(!(this instanceof Ge))return new Ge(e,t);this.options=t=t?Me(t):{},Me(aa,t,!1);var r=t.value;typeof r=="string"?r=new Lt(r,t.mode,null,t.lineSeparator,t.direction):t.mode&&(r.modeOption=t.mode),this.doc=r;var i=new Ge.inputStyles[t.inputStyle](this),o=this.display=new eu(e,r,i,t);o.wrapper.CodeMirror=this,la(this),t.lineWrapping&&(this.display.wrapper.className+=" CodeMirror-wrap"),ul(this),this.state={keyMaps:[],overlays:[],modeGen:0,overwrite:!1,delayingBlurEvent:!1,focused:!1,suppressEdits:!1,pasteIncoming:-1,cutIncoming:-1,selectingText:!1,draggingText:!1,highlight:new Ce,keySeq:null,specialChars:null},t.autofocus&&!N&&o.input.focus(),k&&I<11&&setTimeout(function(){return n.display.input.reset(!0)},20),qu(this),yu(),Mr(this),this.curOp.forceUpdate=!0,yl(this,r),t.autofocus&&!N||this.hasFocus()?setTimeout(function(){n.hasFocus()&&!n.state.focused&&_i(n)},20):Ur(this);for(var l in di)di.hasOwnProperty(l)&&di[l](this,t[l],tn);dl(this),t.finishInit&&t.finishInit(this);for(var a=0;a400}Se(t.scroller,"touchstart",function(s){if(!Qe(e,s)&&!o(s)&&!lo(e,s)){t.input.ensurePolled(),clearTimeout(n);var u=+new Date;t.activeTouch={start:u,moved:!1,prev:u-r.end<=300?r:null},s.touches.length==1&&(t.activeTouch.left=s.touches[0].pageX,t.activeTouch.top=s.touches[0].pageY)}}),Se(t.scroller,"touchmove",function(){t.activeTouch&&(t.activeTouch.moved=!0)}),Se(t.scroller,"touchend",function(s){var u=t.activeTouch;if(u&&!tr(t,s)&&u.left!=null&&!u.moved&&new Date-u.start<300){var h=e.coordsChar(t.activeTouch,"page"),x;!u.prev||l(u,u.prev)?x=new He(h,h):!u.prev.prev||l(u,u.prev.prev)?x=e.findWordAt(h):x=new He(B(h.line,0),Ae(e.doc,B(h.line+1,0))),e.setSelection(x.anchor,x.head),e.focus(),pt(s)}i()}),Se(t.scroller,"touchcancel",i),Se(t.scroller,"scroll",function(){t.scroller.clientHeight&&(xn(e,t.scroller.scrollTop),Cr(e,t.scroller.scrollLeft,!0),Ye(e,"scroll",e))}),Se(t.scroller,"mousewheel",function(s){return gl(e,s)}),Se(t.scroller,"DOMMouseScroll",function(s){return gl(e,s)}),Se(t.wrapper,"scroll",function(){return t.wrapper.scrollTop=t.wrapper.scrollLeft=0}),t.dragFunctions={enter:function(s){Qe(e,s)||ar(s)},over:function(s){Qe(e,s)||(xu(e,s),ar(s))},start:function(s){return mu(e,s)},drop:lt(e,vu),leave:function(s){Qe(e,s)||jl(e)}};var a=t.input.getField();Se(a,"keyup",function(s){return ea.call(e,s)}),Se(a,"keydown",lt(e,$l)),Se(a,"keypress",lt(e,ta)),Se(a,"focus",function(s){return _i(e,s)}),Se(a,"blur",function(s){return Ur(e,s)})}var ao=[];Ge.defineInitHook=function(e){return ao.push(e)};function zn(e,t,n,r){var i=e.doc,o;n==null&&(n="add"),n=="smart"&&(i.mode.indent?o=fn(e,t).state:n="prev");var l=e.options.tabSize,a=ye(i,t),s=Fe(a.text,null,l);a.stateAfter&&(a.stateAfter=null);var u=a.text.match(/^\s*/)[0],h;if(!r&&!/\S/.test(a.text))h=0,n="not";else if(n=="smart"&&(h=i.mode.indent(o,a.text.slice(u.length),a.text),h==qe||h>150)){if(!r)return;n="prev"}n=="prev"?t>i.first?h=Fe(ye(i,t-1).text,null,l):h=0:n=="add"?h=s+e.options.indentUnit:n=="subtract"?h=s-e.options.indentUnit:typeof n=="number"&&(h=s+n),h=Math.max(0,h);var x="",D=0;if(e.options.indentWithTabs)for(var L=Math.floor(h/l);L;--L)D+=l,x+=" ";if(Dl,s=zt(t),u=null;if(a&&r.ranges.length>1)if(Ut&&Ut.text.join(` +`)==t){if(r.ranges.length%Ut.text.length==0){u=[];for(var h=0;h=0;D--){var L=r.ranges[D],H=L.from(),Z=L.to();L.empty()&&(n&&n>0?H=B(H.line,H.ch-n):e.state.overwrite&&!a?Z=B(Z.line,Math.min(ye(o,Z.line).text.length,Z.ch+we(s).length)):a&&Ut&&Ut.lineWise&&Ut.text.join(` +`)==s.join(` +`)&&(H=Z=B(H.line,0)));var ie={from:H,to:Z,text:u?u[D%u.length]:s,origin:i||(a?"paste":e.state.cutIncoming>l?"cut":"+input")};Jr(e.doc,ie),ot(e,"inputRead",e,ie)}t&&!a&&ua(e,t),Gr(e),e.curOp.updateInput<2&&(e.curOp.updateInput=x),e.curOp.typing=!0,e.state.pasteIncoming=e.state.cutIncoming=-1}function sa(e,t){var n=e.clipboardData&&e.clipboardData.getData("Text");if(n)return e.preventDefault(),!t.isReadOnly()&&!t.options.disableInput&&t.hasFocus()&&At(t,function(){return so(t,n,0,null,"paste")}),!0}function ua(e,t){if(!(!e.options.electricChars||!e.options.smartIndent))for(var n=e.doc.sel,r=n.ranges.length-1;r>=0;r--){var i=n.ranges[r];if(!(i.head.ch>100||r&&n.ranges[r-1].head.line==i.head.line)){var o=e.getModeAt(i.head),l=!1;if(o.electricChars){for(var a=0;a-1){l=zn(e,i.head.line,"smart");break}}else o.electricInput&&o.electricInput.test(ye(e.doc,i.head.line).text.slice(0,i.head.ch))&&(l=zn(e,i.head.line,"smart"));l&&ot(e,"electricInput",e,i.head.line)}}}function fa(e){for(var t=[],n=[],r=0;ro&&(zn(this,a.head.line,r,!0),o=a.head.line,l==this.doc.sel.primIndex&&Gr(this));else{var s=a.from(),u=a.to(),h=Math.max(o,s.line);o=Math.min(this.lastLine(),u.line-(u.ch?0:1))+1;for(var x=h;x0&&eo(this.doc,l,new He(s,D[l].to()),Ve)}}}),getTokenAt:function(r,i){return ko(this,r,i)},getLineTokens:function(r,i){return ko(this,B(r),i,!0)},getTokenTypeAt:function(r){r=Ae(this.doc,r);var i=xo(this,ye(this.doc,r.line)),o=0,l=(i.length-1)/2,a=r.ch,s;if(a==0)s=i[2];else for(;;){var u=o+l>>1;if((u?i[u*2-1]:0)>=a)l=u;else if(i[u*2+1]s&&(r=s,l=!0),a=ye(this.doc,r)}else a=r;return Yn(this,a,{top:0,left:0},i||"page",o||l).top+(l?this.doc.height-er(a):0)},defaultTextHeight:function(){return jr(this.display)},defaultCharWidth:function(){return Kr(this.display)},getViewport:function(){return{from:this.display.viewFrom,to:this.display.viewTo}},addWidget:function(r,i,o,l,a){var s=this.display;r=jt(this,Ae(this.doc,r));var u=r.bottom,h=r.left;if(i.style.position="absolute",i.setAttribute("cm-ignore-events","true"),this.display.input.setUneditable(i),s.sizer.appendChild(i),l=="over")u=r.top;else if(l=="above"||l=="near"){var x=Math.max(s.wrapper.clientHeight,this.doc.height),D=Math.max(s.sizer.clientWidth,s.lineSpace.clientWidth);(l=="above"||r.bottom+i.offsetHeight>x)&&r.top>i.offsetHeight?u=r.top-i.offsetHeight:r.bottom+i.offsetHeight<=x&&(u=r.bottom),h+i.offsetWidth>D&&(h=D-i.offsetWidth)}i.style.top=u+"px",i.style.left=i.style.right="",a=="right"?(h=s.sizer.clientWidth-i.offsetWidth,i.style.right="0px"):(a=="left"?h=0:a=="middle"&&(h=(s.sizer.clientWidth-i.offsetWidth)/2),i.style.left=h+"px"),o&&Hs(this,{left:h,top:u,right:h+i.offsetWidth,bottom:u+i.offsetHeight})},triggerOnKeyDown:yt($l),triggerOnKeyPress:yt(ta),triggerOnKeyUp:ea,triggerOnMouseDown:yt(ra),execCommand:function(r){if(En.hasOwnProperty(r))return En[r].call(null,this)},triggerElectric:yt(function(r){ua(this,r)}),findPosH:function(r,i,o,l){var a=1;i<0&&(a=-1,i=-i);for(var s=Ae(this.doc,r),u=0;u0&&h(o.charAt(l-1));)--l;for(;a.5||this.options.lineWrapping)&&Bi(this),Ye(this,"refresh",this)}),swapDoc:yt(function(r){var i=this.doc;return i.cm=null,this.state.selectingText&&this.state.selectingText(),yl(this,r),gn(this),this.display.input.reset(),mn(this,r.scrollLeft,r.scrollTop),this.curOp.forceScroll=!0,ot(this,"swapDoc",this,i),i}),phrase:function(r){var i=this.options.phrases;return i&&Object.prototype.hasOwnProperty.call(i,r)?i[r]:r},getInputField:function(){return this.display.input.getField()},getWrapperElement:function(){return this.display.wrapper},getScrollerElement:function(){return this.display.scroller},getGutterElement:function(){return this.display.gutters}},Bt(e),e.registerHelper=function(r,i,o){n.hasOwnProperty(r)||(n[r]=e[r]={_global:[]}),n[r][i]=o},e.registerGlobalHelper=function(r,i,o,l){e.registerHelper(r,i,l),n[r]._global.push({pred:o,val:l})}}function fo(e,t,n,r,i){var o=t,l=n,a=ye(e,t.line),s=i&&e.direction=="rtl"?-n:n;function u(){var he=t.line+s;return he=e.first+e.size?!1:(t=new B(he,t.ch,t.sticky),a=ye(e,he))}function h(he){var se;if(r=="codepoint"){var ge=a.text.charCodeAt(t.ch+(n>0?0:-1));if(isNaN(ge))se=null;else{var Le=n>0?ge>=55296&&ge<56320:ge>=56320&&ge<57343;se=new B(t.line,Math.max(0,Math.min(a.text.length,t.ch+n*(Le?2:1))),-n)}}else i?se=Lu(e.cm,a,t,n):se=ro(a,t,n);if(se==null)if(!he&&u())t=no(i,e.cm,a,t.line,s);else return!1;else t=se;return!0}if(r=="char"||r=="codepoint")h();else if(r=="column")h(!0);else if(r=="word"||r=="group")for(var x=null,D=r=="group",L=e.cm&&e.cm.getHelper(t,"wordChars"),H=!0;!(n<0&&!h(!H));H=!1){var Z=a.text.charAt(t.ch)||` +`,ie=De(Z,L)?"w":D&&Z==` +`?"n":!D||/\s/.test(Z)?null:"p";if(D&&!H&&!ie&&(ie="s"),x&&x!=ie){n<0&&(n=1,h(),t.sticky="after");break}if(ie&&(x=ie),n>0&&!h(!H))break}var ae=ai(e,t,o,l,!0);return We(o,ae)&&(ae.hitSide=!0),ae}function da(e,t,n,r){var i=e.doc,o=t.left,l;if(r=="page"){var a=Math.min(e.display.wrapper.clientHeight,le(e).innerHeight||i(e).documentElement.clientHeight),s=Math.max(a-.5*jr(e.display),3);l=(n>0?t.bottom:t.top)+n*s}else r=="line"&&(l=n>0?t.bottom+3:t.top-3);for(var u;u=Oi(e,o,l),!!u.outside;){if(n<0?l<=0:l>=i.height){u.hitSide=!0;break}l+=n*5}return u}var je=function(e){this.cm=e,this.lastAnchorNode=this.lastAnchorOffset=this.lastFocusNode=this.lastFocusOffset=null,this.polling=new Ce,this.composing=null,this.gracePeriod=!1,this.readDOMTimeout=null};je.prototype.init=function(e){var t=this,n=this,r=n.cm,i=n.div=e.lineDiv;i.contentEditable=!0,uo(i,r.options.spellcheck,r.options.autocorrect,r.options.autocapitalize);function o(a){for(var s=a.target;s;s=s.parentNode){if(s==i)return!0;if(/\bCodeMirror-(?:line)?widget\b/.test(s.className))break}return!1}Se(i,"paste",function(a){!o(a)||Qe(r,a)||sa(a,r)||I<=11&&setTimeout(lt(r,function(){return t.updateFromDOM()}),20)}),Se(i,"compositionstart",function(a){t.composing={data:a.data,done:!1}}),Se(i,"compositionupdate",function(a){t.composing||(t.composing={data:a.data,done:!1})}),Se(i,"compositionend",function(a){t.composing&&(a.data!=t.composing.data&&t.readFromDOMSoon(),t.composing.done=!0)}),Se(i,"touchstart",function(){return n.forceCompositionEnd()}),Se(i,"input",function(){t.composing||t.readFromDOMSoon()});function l(a){if(!(!o(a)||Qe(r,a))){if(r.somethingSelected())hi({lineWise:!1,text:r.getSelections()}),a.type=="cut"&&r.replaceSelection("",null,"cut");else if(r.options.lineWiseCopyCut){var s=fa(r);hi({lineWise:!0,text:s.text}),a.type=="cut"&&r.operation(function(){r.setSelections(s.ranges,0,Ve),r.replaceSelection("",null,"cut")})}else return;if(a.clipboardData){a.clipboardData.clearData();var u=Ut.text.join(` +`);if(a.clipboardData.setData("Text",u),a.clipboardData.getData("Text")==u){a.preventDefault();return}}var h=ca(),x=h.firstChild;uo(x),r.display.lineSpace.insertBefore(h,r.display.lineSpace.firstChild),x.value=Ut.text.join(` +`);var D=y(Te(i));v(x),setTimeout(function(){r.display.lineSpace.removeChild(h),D.focus(),D==i&&n.showPrimarySelection()},50)}}Se(i,"copy",l),Se(i,"cut",l)},je.prototype.screenReaderLabelChanged=function(e){e?this.div.setAttribute("aria-label",e):this.div.removeAttribute("aria-label")},je.prototype.prepareSelection=function(){var e=rl(this.cm,!1);return e.focus=y(Te(this.div))==this.div,e},je.prototype.showSelection=function(e,t){!e||!this.cm.display.view.length||((e.focus||t)&&this.showPrimarySelection(),this.showMultipleSelections(e))},je.prototype.getSelection=function(){return this.cm.display.wrapper.ownerDocument.getSelection()},je.prototype.showPrimarySelection=function(){var e=this.getSelection(),t=this.cm,n=t.doc.sel.primary(),r=n.from(),i=n.to();if(t.display.viewTo==t.display.viewFrom||r.line>=t.display.viewTo||i.line=t.display.viewFrom&&ha(t,r)||{node:a[0].measure.map[2],offset:0},u=i.linee.firstLine()&&(r=B(r.line-1,ye(e.doc,r.line-1).length)),i.ch==ye(e.doc,i.line).text.length&&i.linet.viewTo-1)return!1;var o,l,a;r.line==t.viewFrom||(o=Tr(e,r.line))==0?(l=f(t.view[0].line),a=t.view[0].node):(l=f(t.view[o].line),a=t.view[o-1].node.nextSibling);var s=Tr(e,i.line),u,h;if(s==t.view.length-1?(u=t.viewTo-1,h=t.lineDiv.lastChild):(u=f(t.view[s+1].line)-1,h=t.view[s+1].node.previousSibling),!a)return!1;for(var x=e.doc.splitLines(Uu(e,a,h,l,u)),D=Vt(e.doc,B(l,0),B(u,ye(e.doc,u).text.length));x.length>1&&D.length>1;)if(we(x)==we(D))x.pop(),D.pop(),u--;else if(x[0]==D[0])x.shift(),D.shift(),l++;else break;for(var L=0,H=0,Z=x[0],ie=D[0],ae=Math.min(Z.length,ie.length);Lr.ch&&he.charCodeAt(he.length-H-1)==se.charCodeAt(se.length-H-1);)L--,H++;x[x.length-1]=he.slice(0,he.length-H).replace(/^\u200b+/,""),x[0]=x[0].slice(L).replace(/\u200b+$/,"");var Le=B(l,L),ke=B(u,D.length?we(D).length-H:0);if(x.length>1||x[0]||ce(Le,ke))return Zr(e.doc,x,Le,ke,"+input"),!0},je.prototype.ensurePolled=function(){this.forceCompositionEnd()},je.prototype.reset=function(){this.forceCompositionEnd()},je.prototype.forceCompositionEnd=function(){this.composing&&(clearTimeout(this.readDOMTimeout),this.composing=null,this.updateFromDOM(),this.div.blur(),this.div.focus())},je.prototype.readFromDOMSoon=function(){var e=this;this.readDOMTimeout==null&&(this.readDOMTimeout=setTimeout(function(){if(e.readDOMTimeout=null,e.composing)if(e.composing.done)e.composing=null;else return;e.updateFromDOM()},80))},je.prototype.updateFromDOM=function(){var e=this;(this.cm.isReadOnly()||!this.pollContent())&&At(this.cm,function(){return St(e.cm)})},je.prototype.setUneditable=function(e){e.contentEditable="false"},je.prototype.onKeyPress=function(e){e.charCode==0||this.composing||(e.preventDefault(),this.cm.isReadOnly()||lt(this.cm,so)(this.cm,String.fromCharCode(e.charCode==null?e.keyCode:e.charCode),0))},je.prototype.readOnlyChanged=function(e){this.div.contentEditable=String(e!="nocursor")},je.prototype.onContextMenu=function(){},je.prototype.resetPosition=function(){},je.prototype.needsContentAttribute=!0;function ha(e,t){var n=Ai(e,t.line);if(!n||n.hidden)return null;var r=ye(e.doc,t.line),i=qo(n,r,t.line),o=Re(r,e.doc.direction),l="left";if(o){var a=lr(o,t.ch);l=a%2?"right":"left"}var s=Uo(i.map,t.ch,l);return s.offset=s.collapse=="right"?s.end:s.start,s}function Ku(e){for(var t=e;t;t=t.parentNode)if(/CodeMirror-gutter-wrapper/.test(t.className))return!0;return!1}function rn(e,t){return t&&(e.bad=!0),e}function Uu(e,t,n,r,i){var o="",l=!1,a=e.doc.lineSeparator(),s=!1;function u(L){return function(H){return H.id==L}}function h(){l&&(o+=a,s&&(o+=a),l=s=!1)}function x(L){L&&(h(),o+=L)}function D(L){if(L.nodeType==1){var H=L.getAttribute("cm-text");if(H){x(H);return}var Z=L.getAttribute("cm-marker"),ie;if(Z){var ae=e.findMarks(B(r,0),B(i+1,0),u(+Z));ae.length&&(ie=ae[0].find(0))&&x(Vt(e.doc,ie.from,ie.to).join(a));return}if(L.getAttribute("contenteditable")=="false")return;var he=/^(pre|div|p|li|table|br)$/i.test(L.nodeName);if(!/^br$/i.test(L.nodeName)&&L.textContent.length==0)return;he&&h();for(var se=0;se=9&&t.hasSelection&&(t.hasSelection=null),n.poll()}),Se(i,"paste",function(l){Qe(r,l)||sa(l,r)||(r.state.pasteIncoming=+new Date,n.fastPoll())});function o(l){if(!Qe(r,l)){if(r.somethingSelected())hi({lineWise:!1,text:r.getSelections()});else if(r.options.lineWiseCopyCut){var a=fa(r);hi({lineWise:!0,text:a.text}),l.type=="cut"?r.setSelections(a.ranges,null,Ve):(n.prevInput="",i.value=a.text.join(` +`),v(i))}else return;l.type=="cut"&&(r.state.cutIncoming=+new Date)}}Se(i,"cut",o),Se(i,"copy",o),Se(e.scroller,"paste",function(l){if(!(tr(e,l)||Qe(r,l))){if(!i.dispatchEvent){r.state.pasteIncoming=+new Date,n.focus();return}var a=new Event("paste");a.clipboardData=l.clipboardData,i.dispatchEvent(a)}}),Se(e.lineSpace,"selectstart",function(l){tr(e,l)||pt(l)}),Se(i,"compositionstart",function(){var l=r.getCursor("from");n.composing&&n.composing.range.clear(),n.composing={start:l,range:r.markText(l,r.getCursor("to"),{className:"CodeMirror-composing"})}}),Se(i,"compositionend",function(){n.composing&&(n.poll(),n.composing.range.clear(),n.composing=null)})},$e.prototype.createField=function(e){this.wrapper=ca(),this.textarea=this.wrapper.firstChild;var t=this.cm.options;uo(this.textarea,t.spellcheck,t.autocorrect,t.autocapitalize)},$e.prototype.screenReaderLabelChanged=function(e){e?this.textarea.setAttribute("aria-label",e):this.textarea.removeAttribute("aria-label")},$e.prototype.prepareSelection=function(){var e=this.cm,t=e.display,n=e.doc,r=rl(e);if(e.options.moveInputWithCursor){var i=jt(e,n.sel.primary().head,"div"),o=t.wrapper.getBoundingClientRect(),l=t.lineDiv.getBoundingClientRect();r.teTop=Math.max(0,Math.min(t.wrapper.clientHeight-10,i.top+l.top-o.top)),r.teLeft=Math.max(0,Math.min(t.wrapper.clientWidth-10,i.left+l.left-o.left))}return r},$e.prototype.showSelection=function(e){var t=this.cm,n=t.display;G(n.cursorDiv,e.cursors),G(n.selectionDiv,e.selection),e.teTop!=null&&(this.wrapper.style.top=e.teTop+"px",this.wrapper.style.left=e.teLeft+"px")},$e.prototype.reset=function(e){if(!(this.contextMenuPending||this.composing&&e)){var t=this.cm;if(this.resetting=!0,t.somethingSelected()){this.prevInput="";var n=t.getSelection();this.textarea.value=n,t.state.focused&&v(this.textarea),k&&I>=9&&(this.hasSelection=n)}else e||(this.prevInput=this.textarea.value="",k&&I>=9&&(this.hasSelection=null));this.resetting=!1}},$e.prototype.getField=function(){return this.textarea},$e.prototype.supportsTouch=function(){return!1},$e.prototype.focus=function(){if(this.cm.options.readOnly!="nocursor"&&(!N||y(Te(this.textarea))!=this.textarea))try{this.textarea.focus()}catch{}},$e.prototype.blur=function(){this.textarea.blur()},$e.prototype.resetPosition=function(){this.wrapper.style.top=this.wrapper.style.left=0},$e.prototype.receivedFocus=function(){this.slowPoll()},$e.prototype.slowPoll=function(){var e=this;this.pollingFast||this.polling.set(this.cm.options.pollInterval,function(){e.poll(),e.cm.state.focused&&e.slowPoll()})},$e.prototype.fastPoll=function(){var e=!1,t=this;t.pollingFast=!0;function n(){var r=t.poll();!r&&!e?(e=!0,t.polling.set(60,n)):(t.pollingFast=!1,t.slowPoll())}t.polling.set(20,n)},$e.prototype.poll=function(){var e=this,t=this.cm,n=this.textarea,r=this.prevInput;if(this.contextMenuPending||this.resetting||!t.state.focused||ur(n)&&!r&&!this.composing||t.isReadOnly()||t.options.disableInput||t.state.keySeq)return!1;var i=n.value;if(i==r&&!t.somethingSelected())return!1;if(k&&I>=9&&this.hasSelection===i||z&&/[\uf700-\uf7ff]/.test(i))return t.display.input.reset(),!1;if(t.doc.sel==t.display.selForContextMenu){var o=i.charCodeAt(0);if(o==8203&&!r&&(r="​"),o==8666)return this.reset(),this.cm.execCommand("undo")}for(var l=0,a=Math.min(r.length,i.length);l1e3||i.indexOf(` +`)>-1?n.value=e.prevInput="":e.prevInput=i,e.composing&&(e.composing.range.clear(),e.composing.range=t.markText(e.composing.start,t.getCursor("to"),{className:"CodeMirror-composing"}))}),!0},$e.prototype.ensurePolled=function(){this.pollingFast&&this.poll()&&(this.pollingFast=!1)},$e.prototype.onKeyPress=function(){k&&I>=9&&(this.hasSelection=null),this.fastPoll()},$e.prototype.onContextMenu=function(e){var t=this,n=t.cm,r=n.display,i=t.textarea;t.contextMenuPending&&t.contextMenuPending();var o=Lr(n,e),l=r.scroller.scrollTop;if(!o||A)return;var a=n.options.resetSelectionOnContextMenu;a&&n.doc.sel.contains(o)==-1&<(n,gt)(n.doc,pr(o),Ve);var s=i.style.cssText,u=t.wrapper.style.cssText,h=t.wrapper.offsetParent.getBoundingClientRect();t.wrapper.style.cssText="position: static",i.style.cssText=`position: absolute; width: 30px; height: 30px; + top: `+(e.clientY-h.top-5)+"px; left: "+(e.clientX-h.left-5)+`px; + z-index: 1000; background: `+(k?"rgba(255, 255, 255, .05)":"transparent")+`; + outline: none; border-width: 0; outline: none; overflow: hidden; opacity: .05; filter: alpha(opacity=5);`;var x;Y&&(x=i.ownerDocument.defaultView.scrollY),r.input.focus(),Y&&i.ownerDocument.defaultView.scrollTo(null,x),r.input.reset(),n.somethingSelected()||(i.value=t.prevInput=" "),t.contextMenuPending=L,r.selForContextMenu=n.doc.sel,clearTimeout(r.detectingSelectAll);function D(){if(i.selectionStart!=null){var Z=n.somethingSelected(),ie="​"+(Z?i.value:"");i.value="⇚",i.value=ie,t.prevInput=Z?"":"​",i.selectionStart=1,i.selectionEnd=ie.length,r.selForContextMenu=n.doc.sel}}function L(){if(t.contextMenuPending==L&&(t.contextMenuPending=!1,t.wrapper.style.cssText=u,i.style.cssText=s,k&&I<9&&r.scrollbars.setScrollTop(r.scroller.scrollTop=l),i.selectionStart!=null)){(!k||k&&I<9)&&D();var Z=0,ie=function(){r.selForContextMenu==n.doc.sel&&i.selectionStart==0&&i.selectionEnd>0&&t.prevInput=="​"?lt(n,El)(n):Z++<10?r.detectingSelectAll=setTimeout(ie,500):(r.selForContextMenu=null,r.input.reset())};r.detectingSelectAll=setTimeout(ie,200)}}if(k&&I>=9&&D(),J){ar(e);var H=function(){ht(window,"mouseup",H),setTimeout(L,20)};Se(window,"mouseup",H)}else setTimeout(L,50)},$e.prototype.readOnlyChanged=function(e){e||this.reset(),this.textarea.disabled=e=="nocursor",this.textarea.readOnly=!!e},$e.prototype.setUneditable=function(){},$e.prototype.needsContentAttribute=!1;function Xu(e,t){if(t=t?Me(t):{},t.value=e.value,!t.tabindex&&e.tabIndex&&(t.tabindex=e.tabIndex),!t.placeholder&&e.placeholder&&(t.placeholder=e.placeholder),t.autofocus==null){var n=y(Te(e));t.autofocus=n==e||e.getAttribute("autofocus")!=null&&n==document.body}function r(){e.value=a.getValue()}var i;if(e.form&&(Se(e.form,"submit",r),!t.leaveSubmitMethodAlone)){var o=e.form;i=o.submit;try{var l=o.submit=function(){r(),o.submit=i,o.submit(),o.submit=l}}catch{}}t.finishInit=function(s){s.save=r,s.getTextArea=function(){return e},s.toTextArea=function(){s.toTextArea=isNaN,r(),e.parentNode.removeChild(s.getWrapperElement()),e.style.display="",e.form&&(ht(e.form,"submit",r),!t.leaveSubmitMethodAlone&&typeof e.form.submit=="function"&&(e.form.submit=i))}},e.style.display="none";var a=Ge(function(s){return e.parentNode.insertBefore(s,e.nextSibling)},t);return a}function Yu(e){e.off=ht,e.on=Se,e.wheelEventPixels=tu,e.Doc=Lt,e.splitLines=zt,e.countColumn=Fe,e.findColumn=_e,e.isWordChar=me,e.Pass=qe,e.signal=Ye,e.Line=Hr,e.changeEnd=gr,e.scrollbarModel=sl,e.Pos=B,e.cmpPos=ce,e.modes=Pr,e.mimeModes=Ht,e.resolveMode=Ir,e.getMode=zr,e.modeExtensions=fr,e.extendMode=Br,e.copyState=Gt,e.startState=Rr,e.innerMode=sn,e.commands=En,e.keyMap=nr,e.keyName=Yl,e.isModifierKey=Gl,e.lookupKey=$r,e.normalizeKeyMap=Su,e.StringStream=Je,e.SharedTextMarker=Fn,e.TextMarker=mr,e.LineWidget=Mn,e.e_preventDefault=pt,e.e_stopPropagation=Er,e.e_stop=ar,e.addClass=j,e.contains=g,e.rmClass=$,e.keyNames=xr}Wu(Ge),ju(Ge);var Qu="iter insert remove copy getEditor constructor".split(" ");for(var gi in Lt.prototype)Lt.prototype.hasOwnProperty(gi)&&ve(Qu,gi)<0&&(Ge.prototype[gi]=(function(e){return function(){return e.apply(this.doc,arguments)}})(Lt.prototype[gi]));return Bt(Lt),Ge.inputStyles={textarea:$e,contenteditable:je},Ge.defineMode=function(e){!Ge.defaults.mode&&e!="null"&&(Ge.defaults.mode=e),_t.apply(this,arguments)},Ge.defineMIME=kr,Ge.defineMode("null",function(){return{token:function(e){return e.skipToEnd()}}}),Ge.defineMIME("text/plain","null"),Ge.defineExtension=function(e,t){Ge.prototype[e]=t},Ge.defineDocExtension=function(e,t){Lt.prototype[e]=t},Ge.fromTextArea=Xu,Yu(Ge),Ge.version="5.65.18",Ge}))})(vi)),vi.exports}var Vu=mt();const df=Ju(Vu);var ga={exports:{}},va;function Xa(){return va||(va=1,(function(ct,xt){(function(b){b(mt())})(function(b){b.defineMode("css",function(J,P){var $=P.inline;P.propertyKeywords||(P=b.resolveMode("text/css"));var F=J.indentUnit,G=P.tokenHooks,c=P.documentTypes||{},T=P.mediaTypes||{},C=P.mediaFeatures||{},g=P.mediaValueKeywords||{},y=P.propertyKeywords||{},j=P.nonStandardPropertyKeywords||{},de=P.fontProperties||{},v=P.counterDescriptors||{},d=P.colorKeywords||{},fe=P.valueKeywords||{},Te=P.allowNested,le=P.lineComment,xe=P.supportsAtComponent===!0,Me=J.highlightNonStandardPropertyKeywords!==!1,Fe,Ce;function ve(E,ee){return Fe=ee,E}function Oe(E,ee){var K=E.next();if(G[K]){var ze=G[K](E,ee);if(ze!==!1)return ze}if(K=="@")return E.eatWhile(/[\w\\\-]/),ve("def",E.current());if(K=="="||(K=="~"||K=="|")&&E.eat("="))return ve(null,"compare");if(K=='"'||K=="'")return ee.tokenize=qe(K),ee.tokenize(E,ee);if(K=="#")return E.eatWhile(/[\w\\\-]/),ve("atom","hash");if(K=="!")return E.match(/^\s*\w*/),ve("keyword","important");if(/\d/.test(K)||K=="."&&E.eat(/\d/))return E.eatWhile(/[\w.%]/),ve("number","unit");if(K==="-"){if(/[\d.]/.test(E.peek()))return E.eatWhile(/[\w.%]/),ve("number","unit");if(E.match(/^-[\w\\\-]*/))return E.eatWhile(/[\w\\\-]/),E.match(/^\s*:/,!1)?ve("variable-2","variable-definition"):ve("variable-2","variable");if(E.match(/^\w+-/))return ve("meta","meta")}else return/[,+>*\/]/.test(K)?ve(null,"select-op"):K=="."&&E.match(/^-?[_a-z][_a-z0-9-]*/i)?ve("qualifier","qualifier"):/[:;{}\[\]\(\)]/.test(K)?ve(null,K):E.match(/^[\w-.]+(?=\()/)?(/^(url(-prefix)?|domain|regexp)$/i.test(E.current())&&(ee.tokenize=Ve),ve("variable callee","variable")):/[\w\\\-]/.test(K)?(E.eatWhile(/[\w\\\-]/),ve("property","word")):ve(null,null)}function qe(E){return function(ee,K){for(var ze=!1,me;(me=ee.next())!=null;){if(me==E&&!ze){E==")"&&ee.backUp(1);break}ze=!ze&&me=="\\"}return(me==E||!ze&&E!=")")&&(K.tokenize=null),ve("string","string")}}function Ve(E,ee){return E.next(),E.match(/^\s*[\"\')]/,!1)?ee.tokenize=null:ee.tokenize=qe(")"),ve(null,"(")}function dt(E,ee,K){this.type=E,this.indent=ee,this.prev=K}function Pe(E,ee,K,ze){return E.context=new dt(K,ee.indentation()+(ze===!1?0:F),E.context),K}function _e(E){return E.context.prev&&(E.context=E.context.prev),E.context.type}function Ue(E,ee,K){return Ie[K.context.type](E,ee,K)}function et(E,ee,K,ze){for(var me=ze||1;me>0;me--)K.context=K.context.prev;return Ue(E,ee,K)}function we(E){var ee=E.current().toLowerCase();fe.hasOwnProperty(ee)?Ce="atom":d.hasOwnProperty(ee)?Ce="keyword":Ce="variable"}var Ie={};return Ie.top=function(E,ee,K){if(E=="{")return Pe(K,ee,"block");if(E=="}"&&K.context.prev)return _e(K);if(xe&&/@component/i.test(E))return Pe(K,ee,"atComponentBlock");if(/^@(-moz-)?document$/i.test(E))return Pe(K,ee,"documentTypes");if(/^@(media|supports|(-moz-)?document|import)$/i.test(E))return Pe(K,ee,"atBlock");if(/^@(font-face|counter-style)/i.test(E))return K.stateArg=E,"restricted_atBlock_before";if(/^@(-(moz|ms|o|webkit)-)?keyframes$/i.test(E))return"keyframes";if(E&&E.charAt(0)=="@")return Pe(K,ee,"at");if(E=="hash")Ce="builtin";else if(E=="word")Ce="tag";else{if(E=="variable-definition")return"maybeprop";if(E=="interpolation")return Pe(K,ee,"interpolation");if(E==":")return"pseudo";if(Te&&E=="(")return Pe(K,ee,"parens")}return K.context.type},Ie.block=function(E,ee,K){if(E=="word"){var ze=ee.current().toLowerCase();return y.hasOwnProperty(ze)?(Ce="property","maybeprop"):j.hasOwnProperty(ze)?(Ce=Me?"string-2":"property","maybeprop"):Te?(Ce=ee.match(/^\s*:(?:\s|$)/,!1)?"property":"tag","block"):(Ce+=" error","maybeprop")}else return E=="meta"?"block":!Te&&(E=="hash"||E=="qualifier")?(Ce="error","block"):Ie.top(E,ee,K)},Ie.maybeprop=function(E,ee,K){return E==":"?Pe(K,ee,"prop"):Ue(E,ee,K)},Ie.prop=function(E,ee,K){if(E==";")return _e(K);if(E=="{"&&Te)return Pe(K,ee,"propBlock");if(E=="}"||E=="{")return et(E,ee,K);if(E=="(")return Pe(K,ee,"parens");if(E=="hash"&&!/^#([0-9a-fA-F]{3,4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$/.test(ee.current()))Ce+=" error";else if(E=="word")we(ee);else if(E=="interpolation")return Pe(K,ee,"interpolation");return"prop"},Ie.propBlock=function(E,ee,K){return E=="}"?_e(K):E=="word"?(Ce="property","maybeprop"):K.context.type},Ie.parens=function(E,ee,K){return E=="{"||E=="}"?et(E,ee,K):E==")"?_e(K):E=="("?Pe(K,ee,"parens"):E=="interpolation"?Pe(K,ee,"interpolation"):(E=="word"&&we(ee),"parens")},Ie.pseudo=function(E,ee,K){return E=="meta"?"pseudo":E=="word"?(Ce="variable-3",K.context.type):Ue(E,ee,K)},Ie.documentTypes=function(E,ee,K){return E=="word"&&c.hasOwnProperty(ee.current())?(Ce="tag",K.context.type):Ie.atBlock(E,ee,K)},Ie.atBlock=function(E,ee,K){if(E=="(")return Pe(K,ee,"atBlock_parens");if(E=="}"||E==";")return et(E,ee,K);if(E=="{")return _e(K)&&Pe(K,ee,Te?"block":"top");if(E=="interpolation")return Pe(K,ee,"interpolation");if(E=="word"){var ze=ee.current().toLowerCase();ze=="only"||ze=="not"||ze=="and"||ze=="or"?Ce="keyword":T.hasOwnProperty(ze)?Ce="attribute":C.hasOwnProperty(ze)?Ce="property":g.hasOwnProperty(ze)?Ce="keyword":y.hasOwnProperty(ze)?Ce="property":j.hasOwnProperty(ze)?Ce=Me?"string-2":"property":fe.hasOwnProperty(ze)?Ce="atom":d.hasOwnProperty(ze)?Ce="keyword":Ce="error"}return K.context.type},Ie.atComponentBlock=function(E,ee,K){return E=="}"?et(E,ee,K):E=="{"?_e(K)&&Pe(K,ee,Te?"block":"top",!1):(E=="word"&&(Ce="error"),K.context.type)},Ie.atBlock_parens=function(E,ee,K){return E==")"?_e(K):E=="{"||E=="}"?et(E,ee,K,2):Ie.atBlock(E,ee,K)},Ie.restricted_atBlock_before=function(E,ee,K){return E=="{"?Pe(K,ee,"restricted_atBlock"):E=="word"&&K.stateArg=="@counter-style"?(Ce="variable","restricted_atBlock_before"):Ue(E,ee,K)},Ie.restricted_atBlock=function(E,ee,K){return E=="}"?(K.stateArg=null,_e(K)):E=="word"?(K.stateArg=="@font-face"&&!de.hasOwnProperty(ee.current().toLowerCase())||K.stateArg=="@counter-style"&&!v.hasOwnProperty(ee.current().toLowerCase())?Ce="error":Ce="property","maybeprop"):"restricted_atBlock"},Ie.keyframes=function(E,ee,K){return E=="word"?(Ce="variable","keyframes"):E=="{"?Pe(K,ee,"top"):Ue(E,ee,K)},Ie.at=function(E,ee,K){return E==";"?_e(K):E=="{"||E=="}"?et(E,ee,K):(E=="word"?Ce="tag":E=="hash"&&(Ce="builtin"),"at")},Ie.interpolation=function(E,ee,K){return E=="}"?_e(K):E=="{"||E==";"?et(E,ee,K):(E=="word"?Ce="variable":E!="variable"&&E!="("&&E!=")"&&(Ce="error"),"interpolation")},{startState:function(E){return{tokenize:null,state:$?"block":"top",stateArg:null,context:new dt($?"block":"top",E||0,null)}},token:function(E,ee){if(!ee.tokenize&&E.eatSpace())return null;var K=(ee.tokenize||Oe)(E,ee);return K&&typeof K=="object"&&(Fe=K[1],K=K[0]),Ce=K,Fe!="comment"&&(ee.state=Ie[ee.state](Fe,E,ee)),Ce},indent:function(E,ee){var K=E.context,ze=ee&&ee.charAt(0),me=K.indent;return K.type=="prop"&&(ze=="}"||ze==")")&&(K=K.prev),K.prev&&(ze=="}"&&(K.type=="block"||K.type=="top"||K.type=="interpolation"||K.type=="restricted_atBlock")?(K=K.prev,me=K.indent):(ze==")"&&(K.type=="parens"||K.type=="atBlock_parens")||ze=="{"&&(K.type=="at"||K.type=="atBlock"))&&(me=Math.max(0,K.indent-F))),me},electricChars:"}",blockCommentStart:"/*",blockCommentEnd:"*/",blockCommentContinue:" * ",lineComment:le,fold:"brace"}});function pe(J){for(var P={},$=0;$")):null:c.match("--")?C(ue("comment","-->")):c.match("DOCTYPE",!0,!0)?(c.eatWhile(/[\w\._\-]/),C(O(1))):null:c.eat("?")?(c.eatWhile(/[\w\._\-]/),T.tokenize=ue("meta","?>"),"meta"):(ne=c.eat("/")?"closeTag":"openTag",T.tokenize=A,"tag bracket");if(g=="&"){var y;return c.eat("#")?c.eat("x")?y=c.eatWhile(/[a-fA-F\d]/)&&c.eat(";"):y=c.eatWhile(/[\d]/)&&c.eat(";"):y=c.eatWhile(/[\w\.\-:]/)&&c.eat(";"),y?"atom":"error"}else return c.eatWhile(/[^&<]/),null}R.isInText=!0;function A(c,T){var C=c.next();if(C==">"||C=="/"&&c.eat(">"))return T.tokenize=R,ne=C==">"?"endTag":"selfcloseTag","tag bracket";if(C=="=")return ne="equals",null;if(C=="<"){T.tokenize=R,T.state=X,T.tagName=T.tagStart=null;var g=T.tokenize(c,T);return g?g+" tag error":"tag error"}else return/[\'\"]/.test(C)?(T.tokenize=V(C),T.stringStartCol=c.column(),T.tokenize(c,T)):(c.match(/^[^\s\u00a0=<>\"\']*[^\s\u00a0=<>\"\'\/]/),"word")}function V(c){var T=function(C,g){for(;!C.eol();)if(C.next()==c){g.tokenize=A;break}return"string"};return T.isInAttribute=!0,T}function ue(c,T){return function(C,g){for(;!C.eol();){if(C.match(T)){g.tokenize=R;break}C.next()}return c}}function O(c){return function(T,C){for(var g;(g=T.next())!=null;){if(g=="<")return C.tokenize=O(c+1),C.tokenize(T,C);if(g==">")if(c==1){C.tokenize=R;break}else return C.tokenize=O(c-1),C.tokenize(T,C)}return"meta"}}function w(c){return c&&c.toLowerCase()}function M(c,T,C){this.prev=c.context,this.tagName=T||"",this.indent=c.indented,this.startOfLine=C,(k.doNotIndent.hasOwnProperty(T)||c.context&&c.context.noIndent)&&(this.noIndent=!0)}function N(c){c.context&&(c.context=c.context.prev)}function z(c,T){for(var C;;){if(!c.context||(C=c.context.tagName,!k.contextGrabbers.hasOwnProperty(w(C))||!k.contextGrabbers[w(C)].hasOwnProperty(w(T))))return;N(c)}}function X(c,T,C){return c=="openTag"?(C.tagStart=T.column(),q):c=="closeTag"?p:X}function q(c,T,C){return c=="word"?(C.tagName=T.current(),S="tag",P):k.allowMissingTagName&&c=="endTag"?(S="tag bracket",P(c,T,C)):(S="error",q)}function p(c,T,C){if(c=="word"){var g=T.current();return C.context&&C.context.tagName!=g&&k.implicitlyClosed.hasOwnProperty(w(C.context.tagName))&&N(C),C.context&&C.context.tagName==g||k.matchClosing===!1?(S="tag",W):(S="tag error",J)}else return k.allowMissingTagName&&c=="endTag"?(S="tag bracket",W(c,T,C)):(S="error",J)}function W(c,T,C){return c!="endTag"?(S="error",W):(N(C),X)}function J(c,T,C){return S="error",W(c,T,C)}function P(c,T,C){if(c=="word")return S="attribute",$;if(c=="endTag"||c=="selfcloseTag"){var g=C.tagName,y=C.tagStart;return C.tagName=C.tagStart=null,c=="selfcloseTag"||k.autoSelfClosers.hasOwnProperty(w(g))?z(C,g):(z(C,g),C.context=new M(C,g,y==C.indented)),X}return S="error",P}function $(c,T,C){return c=="equals"?F:(k.allowMissing||(S="error"),P(c,T,C))}function F(c,T,C){return c=="string"?G:c=="word"&&k.allowUnquoted?(S="string",P):(S="error",P(c,T,C))}function G(c,T,C){return c=="string"?G:P(c,T,C)}return{startState:function(c){var T={tokenize:R,state:X,indented:c||0,tagName:null,tagStart:null,context:null};return c!=null&&(T.baseIndent=c),T},token:function(c,T){if(!T.tagName&&c.sol()&&(T.indented=c.indentation()),c.eatSpace())return null;ne=null;var C=T.tokenize(c,T);return(C||ne)&&C!="comment"&&(S=null,T.state=T.state(ne||C,c,T),S&&(C=S=="error"?C+" error":S)),C},indent:function(c,T,C){var g=c.context;if(c.tokenize.isInAttribute)return c.tagStart==c.indented?c.stringStartCol+1:c.indented+Q;if(g&&g.noIndent)return b.Pass;if(c.tokenize!=A&&c.tokenize!=R)return C?C.match(/^(\s*)/)[0].length:0;if(c.tagName)return k.multilineTagIndentPastTag!==!1?c.tagStart+c.tagName.length+2:c.tagStart+Q*(k.multilineTagIndentFactor||1);if(k.alignCDATA&&/$/,blockCommentStart:"",configuration:k.htmlMode?"html":"xml",helperType:k.htmlMode?"html":"xml",skipAttribute:function(c){c.state==F&&(c.state=P)},xmlCurrentTag:function(c){return c.tagName?{name:c.tagName,close:c.type=="closeTag"}:null},xmlCurrentContext:function(c){for(var T=[],C=c.context;C;C=C.prev)T.push(C.tagName);return T.reverse()}}}),b.defineMIME("text/xml","xml"),b.defineMIME("application/xml","xml"),b.mimeModes.hasOwnProperty("text/html")||b.defineMIME("text/html",{name:"xml",htmlMode:!0})})})()),xa.exports}var ba={exports:{}},ka;function Qa(){return ka||(ka=1,(function(ct,xt){(function(b){b(mt())})(function(b){b.defineMode("javascript",function(pe,_){var te=pe.indentUnit,oe=_.statementIndent,Q=_.jsonld,k=_.json||Q,I=_.trackScope!==!1,Y=_.typescript,ne=_.wordCharacters||/[\w$\xa1-\uffff]/,S=(function(){function f(it){return{type:it,style:"keyword"}}var m=f("keyword a"),U=f("keyword b"),re=f("keyword c"),B=f("keyword d"),ce=f("operator"),We={type:"atom",style:"atom"};return{if:f("if"),while:m,with:m,else:U,do:U,try:U,finally:U,return:B,break:B,continue:B,new:f("new"),delete:re,void:re,throw:re,debugger:f("debugger"),var:f("var"),const:f("var"),let:f("var"),function:f("function"),catch:f("catch"),for:f("for"),switch:f("switch"),case:f("case"),default:f("default"),in:ce,typeof:ce,instanceof:ce,true:We,false:We,null:We,undefined:We,NaN:We,Infinity:We,this:f("this"),class:f("class"),super:f("atom"),yield:re,export:f("export"),import:f("import"),extends:re,await:re}})(),R=/[+\-*&%=<>!?|~^@]/,A=/^@(context|id|value|language|type|container|list|set|reverse|index|base|vocab|graph)"/;function V(f){for(var m=!1,U,re=!1;(U=f.next())!=null;){if(!m){if(U=="/"&&!re)return;U=="["?re=!0:re&&U=="]"&&(re=!1)}m=!m&&U=="\\"}}var ue,O;function w(f,m,U){return ue=f,O=U,m}function M(f,m){var U=f.next();if(U=='"'||U=="'")return m.tokenize=N(U),m.tokenize(f,m);if(U=="."&&f.match(/^\d[\d_]*(?:[eE][+\-]?[\d_]+)?/))return w("number","number");if(U=="."&&f.match(".."))return w("spread","meta");if(/[\[\]{}\(\),;\:\.]/.test(U))return w(U);if(U=="="&&f.eat(">"))return w("=>","operator");if(U=="0"&&f.match(/^(?:x[\dA-Fa-f_]+|o[0-7_]+|b[01_]+)n?/))return w("number","number");if(/\d/.test(U))return f.match(/^[\d_]*(?:n|(?:\.[\d_]*)?(?:[eE][+\-]?[\d_]+)?)?/),w("number","number");if(U=="/")return f.eat("*")?(m.tokenize=z,z(f,m)):f.eat("/")?(f.skipToEnd(),w("comment","comment")):Et(f,m,1)?(V(f),f.match(/^\b(([gimyus])(?![gimyus]*\2))+\b/),w("regexp","string-2")):(f.eat("="),w("operator","operator",f.current()));if(U=="`")return m.tokenize=X,X(f,m);if(U=="#"&&f.peek()=="!")return f.skipToEnd(),w("meta","meta");if(U=="#"&&f.eatWhile(ne))return w("variable","property");if(U=="<"&&f.match("!--")||U=="-"&&f.match("->")&&!/\S/.test(f.string.slice(0,f.start)))return f.skipToEnd(),w("comment","comment");if(R.test(U))return(U!=">"||!m.lexical||m.lexical.type!=">")&&(f.eat("=")?(U=="!"||U=="=")&&f.eat("="):/[<>*+\-|&?]/.test(U)&&(f.eat(U),U==">"&&f.eat(U))),U=="?"&&f.eat(".")?w("."):w("operator","operator",f.current());if(ne.test(U)){f.eatWhile(ne);var re=f.current();if(m.lastType!="."){if(S.propertyIsEnumerable(re)){var B=S[re];return w(B.type,B.style,re)}if(re=="async"&&f.match(/^(\s|\/\*([^*]|\*(?!\/))*?\*\/)*[\[\(\w]/,!1))return w("async","keyword",re)}return w("variable","variable",re)}}function N(f){return function(m,U){var re=!1,B;if(Q&&m.peek()=="@"&&m.match(A))return U.tokenize=M,w("jsonld-keyword","meta");for(;(B=m.next())!=null&&!(B==f&&!re);)re=!re&&B=="\\";return re||(U.tokenize=M),w("string","string")}}function z(f,m){for(var U=!1,re;re=f.next();){if(re=="/"&&U){m.tokenize=M;break}U=re=="*"}return w("comment","comment")}function X(f,m){for(var U=!1,re;(re=f.next())!=null;){if(!U&&(re=="`"||re=="$"&&f.eat("{"))){m.tokenize=M;break}U=!U&&re=="\\"}return w("quasi","string-2",f.current())}var q="([{}])";function p(f,m){m.fatArrowAt&&(m.fatArrowAt=null);var U=f.string.indexOf("=>",f.start);if(!(U<0)){if(Y){var re=/:\s*(?:\w+(?:<[^>]*>|\[\])?|\{[^}]*\})\s*$/.exec(f.string.slice(f.start,U));re&&(U=re.index)}for(var B=0,ce=!1,We=U-1;We>=0;--We){var it=f.string.charAt(We),wt=q.indexOf(it);if(wt>=0&&wt<3){if(!B){++We;break}if(--B==0){it=="("&&(ce=!0);break}}else if(wt>=3&&wt<6)++B;else if(ne.test(it))ce=!0;else if(/["'\/`]/.test(it))for(;;--We){if(We==0)return;var Wr=f.string.charAt(We-1);if(Wr==it&&f.string.charAt(We-2)!="\\"){We--;break}}else if(ce&&!B){++We;break}}ce&&!B&&(m.fatArrowAt=We)}}var W={atom:!0,number:!0,variable:!0,string:!0,regexp:!0,this:!0,import:!0,"jsonld-keyword":!0};function J(f,m,U,re,B,ce){this.indented=f,this.column=m,this.type=U,this.prev=B,this.info=ce,re!=null&&(this.align=re)}function P(f,m){if(!I)return!1;for(var U=f.localVars;U;U=U.next)if(U.name==m)return!0;for(var re=f.context;re;re=re.prev)for(var U=re.vars;U;U=U.next)if(U.name==m)return!0}function $(f,m,U,re,B){var ce=f.cc;for(F.state=f,F.stream=B,F.marked=null,F.cc=ce,F.style=m,f.lexical.hasOwnProperty("align")||(f.lexical.align=!0);;){var We=ce.length?ce.pop():k?ve:Fe;if(We(U,re)){for(;ce.length&&ce[ce.length-1].lex;)ce.pop()();return F.marked?F.marked:U=="variable"&&P(f,re)?"variable-2":m}}}var F={state:null,marked:null,cc:null};function G(){for(var f=arguments.length-1;f>=0;f--)F.cc.push(arguments[f])}function c(){return G.apply(null,arguments),!0}function T(f,m){for(var U=m;U;U=U.next)if(U.name==f)return!0;return!1}function C(f){var m=F.state;if(F.marked="def",!!I){if(m.context){if(m.lexical.info=="var"&&m.context&&m.context.block){var U=g(f,m.context);if(U!=null){m.context=U;return}}else if(!T(f,m.localVars)){m.localVars=new de(f,m.localVars);return}}_.globalVars&&!T(f,m.globalVars)&&(m.globalVars=new de(f,m.globalVars))}}function g(f,m){if(m)if(m.block){var U=g(f,m.prev);return U?U==m.prev?m:new j(U,m.vars,!0):null}else return T(f,m.vars)?m:new j(m.prev,new de(f,m.vars),!1);else return null}function y(f){return f=="public"||f=="private"||f=="protected"||f=="abstract"||f=="readonly"}function j(f,m,U){this.prev=f,this.vars=m,this.block=U}function de(f,m){this.name=f,this.next=m}var v=new de("this",new de("arguments",null));function d(){F.state.context=new j(F.state.context,F.state.localVars,!1),F.state.localVars=v}function fe(){F.state.context=new j(F.state.context,F.state.localVars,!0),F.state.localVars=null}d.lex=fe.lex=!0;function Te(){F.state.localVars=F.state.context.vars,F.state.context=F.state.context.prev}Te.lex=!0;function le(f,m){var U=function(){var re=F.state,B=re.indented;if(re.lexical.type=="stat")B=re.lexical.indented;else for(var ce=re.lexical;ce&&ce.type==")"&&ce.align;ce=ce.prev)B=ce.indented;re.lexical=new J(B,F.stream.column(),f,null,re.lexical,m)};return U.lex=!0,U}function xe(){var f=F.state;f.lexical.prev&&(f.lexical.type==")"&&(f.indented=f.lexical.indented),f.lexical=f.lexical.prev)}xe.lex=!0;function Me(f){function m(U){return U==f?c():f==";"||U=="}"||U==")"||U=="]"?G():c(m)}return m}function Fe(f,m){return f=="var"?c(le("vardef",m),Er,Me(";"),xe):f=="keyword a"?c(le("form"),qe,Fe,xe):f=="keyword b"?c(le("form"),Fe,xe):f=="keyword d"?F.stream.match(/^\s*$/,!1)?c():c(le("stat"),dt,Me(";"),xe):f=="debugger"?c(Me(";")):f=="{"?c(le("}"),fe,Pt,xe,Te):f==";"?c():f=="if"?(F.state.lexical.info=="else"&&F.state.cc[F.state.cc.length-1]==xe&&F.state.cc.pop()(),c(le("form"),qe,Fe,xe,Or)):f=="function"?c(zt):f=="for"?c(le("form"),fe,Rn,Fe,Te,xe):f=="class"||Y&&m=="interface"?(F.marked="keyword",c(le("form",f=="class"?f:m),Pr,xe)):f=="variable"?Y&&m=="declare"?(F.marked="keyword",c(Fe)):Y&&(m=="module"||m=="enum"||m=="type")&&F.stream.match(/^\s*\w/,!1)?(F.marked="keyword",m=="enum"?c(ye):m=="type"?c(Wn,Me("operator"),Re,Me(";")):c(le("form"),kt,Me("{"),le("}"),Pt,xe,xe)):Y&&m=="namespace"?(F.marked="keyword",c(le("form"),ve,Fe,xe)):Y&&m=="abstract"?(F.marked="keyword",c(Fe)):c(le("stat"),ze):f=="switch"?c(le("form"),qe,Me("{"),le("}","switch"),fe,Pt,xe,xe,Te):f=="case"?c(ve,Me(":")):f=="default"?c(Me(":")):f=="catch"?c(le("form"),d,Ce,Fe,xe,Te):f=="export"?c(le("stat"),Ir,xe):f=="import"?c(le("stat"),fr,xe):f=="async"?c(Fe):m=="@"?c(ve,Fe):G(le("stat"),ve,Me(";"),xe)}function Ce(f){if(f=="(")return c(Wt,Me(")"))}function ve(f,m){return Ve(f,m,!1)}function Oe(f,m){return Ve(f,m,!0)}function qe(f){return f!="("?G():c(le(")"),dt,Me(")"),xe)}function Ve(f,m,U){if(F.state.fatArrowAt==F.stream.start){var re=U?Ie:we;if(f=="(")return c(d,le(")"),Ne(Wt,")"),xe,Me("=>"),re,Te);if(f=="variable")return G(d,kt,Me("=>"),re,Te)}var B=U?_e:Pe;return W.hasOwnProperty(f)?c(B):f=="function"?c(zt,B):f=="class"||Y&&m=="interface"?(F.marked="keyword",c(le("form"),yi,xe)):f=="keyword c"||f=="async"?c(U?Oe:ve):f=="("?c(le(")"),dt,Me(")"),xe,B):f=="operator"||f=="spread"?c(U?Oe:ve):f=="["?c(le("]"),Je,xe,B):f=="{"?Mt(De,"}",null,B):f=="quasi"?G(Ue,B):f=="new"?c(E(U)):c()}function dt(f){return f.match(/[;\}\)\],]/)?G():G(ve)}function Pe(f,m){return f==","?c(dt):_e(f,m,!1)}function _e(f,m,U){var re=U==!1?Pe:_e,B=U==!1?ve:Oe;if(f=="=>")return c(d,U?Ie:we,Te);if(f=="operator")return/\+\+|--/.test(m)||Y&&m=="!"?c(re):Y&&m=="<"&&F.stream.match(/^([^<>]|<[^<>]*>)*>\s*\(/,!1)?c(le(">"),Ne(Re,">"),xe,re):m=="?"?c(ve,Me(":"),B):c(B);if(f=="quasi")return G(Ue,re);if(f!=";"){if(f=="(")return Mt(Oe,")","call",re);if(f==".")return c(me,re);if(f=="[")return c(le("]"),dt,Me("]"),xe,re);if(Y&&m=="as")return F.marked="keyword",c(Re,re);if(f=="regexp")return F.state.lastType=F.marked="operator",F.stream.backUp(F.stream.pos-F.stream.start-1),c(B)}}function Ue(f,m){return f!="quasi"?G():m.slice(m.length-2)!="${"?c(Ue):c(dt,et)}function et(f){if(f=="}")return F.marked="string-2",F.state.tokenize=X,c(Ue)}function we(f){return p(F.stream,F.state),G(f=="{"?Fe:ve)}function Ie(f){return p(F.stream,F.state),G(f=="{"?Fe:Oe)}function E(f){return function(m){return m=="."?c(f?K:ee):m=="variable"&&Y?c(Ft,f?_e:Pe):G(f?Oe:ve)}}function ee(f,m){if(m=="target")return F.marked="keyword",c(Pe)}function K(f,m){if(m=="target")return F.marked="keyword",c(_e)}function ze(f){return f==":"?c(xe,Fe):G(Pe,Me(";"),xe)}function me(f){if(f=="variable")return F.marked="property",c()}function De(f,m){if(f=="async")return F.marked="property",c(De);if(f=="variable"||F.style=="keyword"){if(F.marked="property",m=="get"||m=="set")return c(be);var U;return Y&&F.state.fatArrowAt==F.stream.start&&(U=F.stream.match(/^\s*:\s*/,!1))&&(F.state.fatArrowAt=F.stream.pos+U[0].length),c(Be)}else{if(f=="number"||f=="string")return F.marked=Q?"property":F.style+" property",c(Be);if(f=="jsonld-keyword")return c(Be);if(Y&&y(m))return F.marked="keyword",c(De);if(f=="[")return c(ve,or,Me("]"),Be);if(f=="spread")return c(Oe,Be);if(m=="*")return F.marked="keyword",c(De);if(f==":")return G(Be)}}function be(f){return f!="variable"?G(Be):(F.marked="property",c(zt))}function Be(f){if(f==":")return c(Oe);if(f=="(")return G(zt)}function Ne(f,m,U){function re(B,ce){if(U?U.indexOf(B)>-1:B==","){var We=F.state.lexical;return We.info=="call"&&(We.pos=(We.pos||0)+1),c(function(it,wt){return it==m||wt==m?G():G(f)},re)}return B==m||ce==m?c():U&&U.indexOf(";")>-1?G(f):c(Me(m))}return function(B,ce){return B==m||ce==m?c():G(f,re)}}function Mt(f,m,U){for(var re=3;re"),Re);if(f=="quasi")return G(ht,It)}function Bn(f){if(f=="=>")return c(Re)}function Se(f){return f.match(/[\}\)\]]/)?c():f==","||f==";"?c(Se):G(Zt,Se)}function Zt(f,m){if(f=="variable"||F.style=="keyword")return F.marked="property",c(Zt);if(m=="?"||f=="number"||f=="string")return c(Zt);if(f==":")return c(Re);if(f=="[")return c(Me("variable"),br,Me("]"),Zt);if(f=="(")return G(ur,Zt);if(!f.match(/[;\}\)\],]/))return c()}function ht(f,m){return f!="quasi"?G():m.slice(m.length-2)!="${"?c(ht):c(Re,Ye)}function Ye(f){if(f=="}")return F.marked="string-2",F.state.tokenize=X,c(ht)}function Qe(f,m){return f=="variable"&&F.stream.match(/^\s*[?:]/,!1)||m=="?"?c(Qe):f==":"?c(Re):f=="spread"?c(Qe):G(Re)}function It(f,m){if(m=="<")return c(le(">"),Ne(Re,">"),xe,It);if(m=="|"||f=="."||m=="&")return c(Re);if(f=="[")return c(Re,Me("]"),It);if(m=="extends"||m=="implements")return F.marked="keyword",c(Re);if(m=="?")return c(Re,Me(":"),Re)}function Ft(f,m){if(m=="<")return c(le(">"),Ne(Re,">"),xe,It)}function Bt(){return G(Re,pt)}function pt(f,m){if(m=="=")return c(Re)}function Er(f,m){return m=="enum"?(F.marked="keyword",c(ye)):G(kt,or,Rt,xi)}function kt(f,m){if(Y&&y(m))return F.marked="keyword",c(kt);if(f=="variable")return C(m),c();if(f=="spread")return c(kt);if(f=="[")return Mt(ln,"]");if(f=="{")return Mt(ar,"}")}function ar(f,m){return f=="variable"&&!F.stream.match(/^\s*:/,!1)?(C(m),c(Rt)):(f=="variable"&&(F.marked="property"),f=="spread"?c(kt):f=="}"?G():f=="["?c(ve,Me("]"),Me(":"),ar):c(Me(":"),kt,Rt))}function ln(){return G(kt,Rt)}function Rt(f,m){if(m=="=")return c(Oe)}function xi(f){if(f==",")return c(Er)}function Or(f,m){if(f=="keyword b"&&m=="else")return c(le("form","else"),Fe,xe)}function Rn(f,m){if(m=="await")return c(Rn);if(f=="(")return c(le(")"),an,xe)}function an(f){return f=="var"?c(Er,sr):f=="variable"?c(sr):G(sr)}function sr(f,m){return f==")"?c():f==";"?c(sr):m=="in"||m=="of"?(F.marked="keyword",c(ve,sr)):G(ve,sr)}function zt(f,m){if(m=="*")return F.marked="keyword",c(zt);if(f=="variable")return C(m),c(zt);if(f=="(")return c(d,le(")"),Ne(Wt,")"),xe,lr,Fe,Te);if(Y&&m=="<")return c(le(">"),Ne(Bt,">"),xe,zt)}function ur(f,m){if(m=="*")return F.marked="keyword",c(ur);if(f=="variable")return C(m),c(ur);if(f=="(")return c(d,le(")"),Ne(Wt,")"),xe,lr,Te);if(Y&&m=="<")return c(le(">"),Ne(Bt,">"),xe,ur)}function Wn(f,m){if(f=="keyword"||f=="variable")return F.marked="type",c(Wn);if(m=="<")return c(le(">"),Ne(Bt,">"),xe)}function Wt(f,m){return m=="@"&&c(ve,Wt),f=="spread"?c(Wt):Y&&y(m)?(F.marked="keyword",c(Wt)):Y&&f=="this"?c(or,Rt):G(kt,or,Rt)}function yi(f,m){return f=="variable"?Pr(f,m):Ht(f,m)}function Pr(f,m){if(f=="variable")return C(m),c(Ht)}function Ht(f,m){if(m=="<")return c(le(">"),Ne(Bt,">"),xe,Ht);if(m=="extends"||m=="implements"||Y&&f==",")return m=="implements"&&(F.marked="keyword"),c(Y?Re:ve,Ht);if(f=="{")return c(le("}"),_t,xe)}function _t(f,m){if(f=="async"||f=="variable"&&(m=="static"||m=="get"||m=="set"||Y&&y(m))&&F.stream.match(/^\s+#?[\w$\xa1-\uffff]/,!1))return F.marked="keyword",c(_t);if(f=="variable"||F.style=="keyword")return F.marked="property",c(kr,_t);if(f=="number"||f=="string")return c(kr,_t);if(f=="[")return c(ve,or,Me("]"),kr,_t);if(m=="*")return F.marked="keyword",c(_t);if(Y&&f=="(")return G(ur,_t);if(f==";"||f==",")return c(_t);if(f=="}")return c();if(m=="@")return c(ve,_t)}function kr(f,m){if(m=="!"||m=="?")return c(kr);if(f==":")return c(Re,Rt);if(m=="=")return c(Oe);var U=F.state.lexical.prev,re=U&&U.info=="interface";return G(re?ur:zt)}function Ir(f,m){return m=="*"?(F.marked="keyword",c(Rr,Me(";"))):m=="default"?(F.marked="keyword",c(ve,Me(";"))):f=="{"?c(Ne(zr,"}"),Rr,Me(";")):G(Fe)}function zr(f,m){if(m=="as")return F.marked="keyword",c(Me("variable"));if(f=="variable")return G(Oe,zr)}function fr(f){return f=="string"?c():f=="("?G(ve):f=="."?G(Pe):G(Br,Gt,Rr)}function Br(f,m){return f=="{"?Mt(Br,"}"):(f=="variable"&&C(m),m=="*"&&(F.marked="keyword"),c(sn))}function Gt(f){if(f==",")return c(Br,Gt)}function sn(f,m){if(m=="as")return F.marked="keyword",c(Br)}function Rr(f,m){if(m=="from")return F.marked="keyword",c(ve)}function Je(f){return f=="]"?c():G(Ne(Oe,"]"))}function ye(){return G(le("form"),kt,Me("{"),le("}"),Ne(Vt,"}"),xe,xe)}function Vt(){return G(kt,Rt)}function un(f,m){return f.lastType=="operator"||f.lastType==","||R.test(m.charAt(0))||/[,.]/.test(m.charAt(0))}function Et(f,m,U){return m.tokenize==M&&/^(?:operator|sof|keyword [bcd]|case|new|export|default|spread|[\[{}\(,;:]|=>)$/.test(m.lastType)||m.lastType=="quasi"&&/\{\s*$/.test(f.string.slice(0,f.pos-(U||0)))}return{startState:function(f){var m={tokenize:M,lastType:"sof",cc:[],lexical:new J((f||0)-te,0,"block",!1),localVars:_.localVars,context:_.localVars&&new j(null,null,!1),indented:f||0};return _.globalVars&&typeof _.globalVars=="object"&&(m.globalVars=_.globalVars),m},token:function(f,m){if(f.sol()&&(m.lexical.hasOwnProperty("align")||(m.lexical.align=!1),m.indented=f.indentation(),p(f,m)),m.tokenize!=z&&f.eatSpace())return null;var U=m.tokenize(f,m);return ue=="comment"?U:(m.lastType=ue=="operator"&&(O=="++"||O=="--")?"incdec":ue,$(m,U,ue,O,f))},indent:function(f,m){if(f.tokenize==z||f.tokenize==X)return b.Pass;if(f.tokenize!=M)return 0;var U=m&&m.charAt(0),re=f.lexical,B;if(!/^\s*else\b/.test(m))for(var ce=f.cc.length-1;ce>=0;--ce){var We=f.cc[ce];if(We==xe)re=re.prev;else if(We!=Or&&We!=Te)break}for(;(re.type=="stat"||re.type=="form")&&(U=="}"||(B=f.cc[f.cc.length-1])&&(B==Pe||B==_e)&&!/^[,\.=+\-*:?[\(]/.test(m));)re=re.prev;oe&&re.type==")"&&re.prev.type=="stat"&&(re=re.prev);var it=re.type,wt=U==it;return it=="vardef"?re.indented+(f.lastType=="operator"||f.lastType==","?re.info.length+1:0):it=="form"&&U=="{"?re.indented:it=="form"?re.indented+te:it=="stat"?re.indented+(un(f,m)?oe||te:0):re.info=="switch"&&!wt&&_.doubleIndentSwitch!=!1?re.indented+(/^(?:case|default)\b/.test(m)?te:2*te):re.align?re.column+(wt?0:1):re.indented+(wt?0:te)},electricInput:/^\s*(?:case .*?:|default:|\{|\})$/,blockCommentStart:k?null:"/*",blockCommentEnd:k?null:"*/",blockCommentContinue:k?null:" * ",lineComment:k?null:"//",fold:"brace",closeBrackets:"()[]{}''\"\"``",helperType:k?"json":"javascript",jsonldMode:Q,jsonMode:k,expressionAllowed:Et,skipExpression:function(f){$(f,"atom","atom","true",new b.StringStream("",2,null))}}}),b.registerHelper("wordChars","javascript",/[\w$]/),b.defineMIME("text/javascript","javascript"),b.defineMIME("text/ecmascript","javascript"),b.defineMIME("application/javascript","javascript"),b.defineMIME("application/x-javascript","javascript"),b.defineMIME("application/ecmascript","javascript"),b.defineMIME("application/json",{name:"javascript",json:!0}),b.defineMIME("application/x-json",{name:"javascript",json:!0}),b.defineMIME("application/manifest+json",{name:"javascript",json:!0}),b.defineMIME("application/ld+json",{name:"javascript",jsonld:!0}),b.defineMIME("text/typescript",{name:"javascript",typescript:!0}),b.defineMIME("application/typescript",{name:"javascript",typescript:!0})})})()),ba.exports}var wa;function $u(){return wa||(wa=1,(function(ct,xt){(function(b){b(mt(),Ya(),Qa(),Xa())})(function(b){var pe={script:[["lang",/(javascript|babel)/i,"javascript"],["type",/^(?:text|application)\/(?:x-)?(?:java|ecma)script$|^module$|^$/i,"javascript"],["type",/./,"text/plain"],[null,null,"javascript"]],style:[["lang",/^css$/i,"css"],["type",/^(text\/)?(x-)?(stylesheet|css)$/i,"css"],["type",/./,"text/plain"],[null,null,"css"]]};function _(ne,S,R){var A=ne.current(),V=A.search(S);return V>-1?ne.backUp(A.length-V):A.match(/<\/?$/)&&(ne.backUp(A.length),ne.match(S,!1)||ne.match(A)),R}var te={};function oe(ne){var S=te[ne];return S||(te[ne]=new RegExp("\\s+"+ne+`\\s*=\\s*('|")?([^'"]+)('|")?\\s*`))}function Q(ne,S){var R=ne.match(oe(S));return R?/^\s*(.*?)\s*$/.exec(R[2])[1]:""}function k(ne,S){return new RegExp((S?"^":"")+"","i")}function I(ne,S){for(var R in ne)for(var A=S[R]||(S[R]=[]),V=ne[R],ue=V.length-1;ue>=0;ue--)A.unshift(V[ue])}function Y(ne,S){for(var R=0;R=0;O--)A.script.unshift(["type",ue[O].matches,ue[O].mode]);function w(M,N){var z=R.token(M,N.htmlState),X=/\btag\b/.test(z),q;if(X&&!/[<>\s\/]/.test(M.current())&&(q=N.htmlState.tagName&&N.htmlState.tagName.toLowerCase())&&A.hasOwnProperty(q))N.inTag=q+" ";else if(N.inTag&&X&&/>$/.test(M.current())){var p=/^([\S]+) (.*)/.exec(N.inTag);N.inTag=null;var W=M.current()==">"&&Y(A[p[1]],p[2]),J=b.getMode(ne,W),P=k(p[1],!0),$=k(p[1],!1);N.token=function(F,G){return F.match(P,!1)?(G.token=w,G.localState=G.localMode=null,null):_(F,$,G.localMode.token(F,G.localState))},N.localMode=J,N.localState=b.startState(J,R.indent(N.htmlState,"",""))}else N.inTag&&(N.inTag+=M.current(),M.eol()&&(N.inTag+=" "));return z}return{startState:function(){var M=b.startState(R);return{token:w,inTag:null,localMode:null,localState:null,htmlState:M}},copyState:function(M){var N;return M.localState&&(N=b.copyState(M.localMode,M.localState)),{token:M.token,inTag:M.inTag,localMode:M.localMode,localState:N,htmlState:b.copyState(R,M.htmlState)}},token:function(M,N){return N.token(M,N)},indent:function(M,N,z){return!M.localMode||/^\s*<\//.test(N)?R.indent(M.htmlState,N,z):M.localMode.indent?M.localMode.indent(M.localState,N,z):b.Pass},innerMode:function(M){return{state:M.localState||M.htmlState,mode:M.localMode||R}}}},"xml","javascript","css"),b.defineMIME("text/html","htmlmixed")})})()),ma.exports}$u();Qa();var Sa={exports:{}},La;function ef(){return La||(La=1,(function(ct,xt){(function(b){b(mt())})(function(b){function pe(I){return new RegExp("^(("+I.join(")|(")+"))\\b")}var _=pe(["and","or","not","is"]),te=["as","assert","break","class","continue","def","del","elif","else","except","finally","for","from","global","if","import","lambda","pass","raise","return","try","while","with","yield","in","False","True"],oe=["abs","all","any","bin","bool","bytearray","callable","chr","classmethod","compile","complex","delattr","dict","dir","divmod","enumerate","eval","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","property","range","repr","reversed","round","set","setattr","slice","sorted","staticmethod","str","sum","super","tuple","type","vars","zip","__import__","NotImplemented","Ellipsis","__debug__"];b.registerHelper("hintWords","python",te.concat(oe).concat(["exec","print"]));function Q(I){return I.scopes[I.scopes.length-1]}b.defineMode("python",function(I,Y){for(var ne="error",S=Y.delimiters||Y.singleDelimiters||/^[\(\)\[\]\{\}@,:`=;\.\\]/,R=[Y.singleOperators,Y.doubleOperators,Y.doubleDelimiters,Y.tripleDelimiters,Y.operators||/^([-+*/%\/&|^]=?|[<>=]+|\/\/=?|\*\*=?|!=|[~!@]|\.\.\.)/],A=0;Ay?P(C):j0&&F(T,C)&&(de+=" "+ne),de}}return p(T,C)}function p(T,C,g){if(T.eatSpace())return null;if(!g&&T.match(/^#.*/))return"comment";if(T.match(/^[0-9\.]/,!1)){var y=!1;if(T.match(/^[\d_]*\.\d+(e[\+\-]?\d+)?/i)&&(y=!0),T.match(/^[\d_]+\.\d*/)&&(y=!0),T.match(/^\.\d+/)&&(y=!0),y)return T.eat(/J/i),"number";var j=!1;if(T.match(/^0x[0-9a-f_]+/i)&&(j=!0),T.match(/^0b[01_]+/i)&&(j=!0),T.match(/^0o[0-7_]+/i)&&(j=!0),T.match(/^[1-9][\d_]*(e[\+\-]?[\d_]+)?/)&&(T.eat(/J/i),j=!0),T.match(/^0(?![\dx])/i)&&(j=!0),j)return T.eat(/L/i),"number"}if(T.match(N)){var de=T.current().toLowerCase().indexOf("f")!==-1;return de?(C.tokenize=W(T.current(),C.tokenize),C.tokenize(T,C)):(C.tokenize=J(T.current(),C.tokenize),C.tokenize(T,C))}for(var v=0;v=0;)T=T.substr(1);var g=T.length==1,y="string";function j(v){return function(d,fe){var Te=p(d,fe,!0);return Te=="punctuation"&&(d.current()=="{"?fe.tokenize=j(v+1):d.current()=="}"&&(v>1?fe.tokenize=j(v-1):fe.tokenize=de)),Te}}function de(v,d){for(;!v.eol();)if(v.eatWhile(/[^'"\{\}\\]/),v.eat("\\")){if(v.next(),g&&v.eol())return y}else{if(v.match(T))return d.tokenize=C,y;if(v.match("{{"))return y;if(v.match("{",!1))return d.tokenize=j(0),v.current()?y:d.tokenize(v,d);if(v.match("}}"))return y;if(v.match("}"))return ne;v.eat(/['"]/)}if(g){if(Y.singleLineStringErrors)return ne;d.tokenize=C}return y}return de.isString=!0,de}function J(T,C){for(;"rubf".indexOf(T.charAt(0).toLowerCase())>=0;)T=T.substr(1);var g=T.length==1,y="string";function j(de,v){for(;!de.eol();)if(de.eatWhile(/[^'"\\]/),de.eat("\\")){if(de.next(),g&&de.eol())return y}else{if(de.match(T))return v.tokenize=C,y;de.eat(/['"]/)}if(g){if(Y.singleLineStringErrors)return ne;v.tokenize=C}return y}return j.isString=!0,j}function P(T){for(;Q(T).type!="py";)T.scopes.pop();T.scopes.push({offset:Q(T).offset+I.indentUnit,type:"py",align:null})}function $(T,C,g){var y=T.match(/^[\s\[\{\(]*(?:#|$)/,!1)?null:T.column()+1;C.scopes.push({offset:C.indent+V,type:g,align:y})}function F(T,C){for(var g=T.indentation();C.scopes.length>1&&Q(C).offset>g;){if(Q(C).type!="py")return!0;C.scopes.pop()}return Q(C).offset!=g}function G(T,C){T.sol()&&(C.beginningOfLine=!0,C.dedent=!1);var g=C.tokenize(T,C),y=T.current();if(C.beginningOfLine&&y=="@")return T.match(M,!1)?"meta":w?"operator":ne;if(/\S/.test(y)&&(C.beginningOfLine=!1),(g=="variable"||g=="builtin")&&C.lastToken=="meta"&&(g="meta"),(y=="pass"||y=="return")&&(C.dedent=!0),y=="lambda"&&(C.lambda=!0),y==":"&&!C.lambda&&Q(C).type=="py"&&T.match(/^\s*(?:#|$)/,!1)&&P(C),y.length==1&&!/string|comment/.test(g)){var j="[({".indexOf(y);if(j!=-1&&$(T,C,"])}".slice(j,j+1)),j="])}".indexOf(y),j!=-1)if(Q(C).type==y)C.indent=C.scopes.pop().offset-V;else return ne}return C.dedent&&T.eol()&&Q(C).type=="py"&&C.scopes.length>1&&C.scopes.pop(),g}var c={startState:function(T){return{tokenize:q,scopes:[{offset:T||0,type:"py",align:null}],indent:T||0,lastToken:null,lambda:!1,dedent:0}},token:function(T,C){var g=C.errorToken;g&&(C.errorToken=!1);var y=G(T,C);return y&&y!="comment"&&(C.lastToken=y=="keyword"||y=="punctuation"?T.current():y),y=="punctuation"&&(y=null),T.eol()&&C.lambda&&(C.lambda=!1),g?y+" "+ne:y},indent:function(T,C){if(T.tokenize!=q)return T.tokenize.isString?b.Pass:0;var g=Q(T),y=g.type==C.charAt(0)||g.type=="py"&&!T.dedent&&/^(else:|elif |except |finally:)/.test(C);return g.align!=null?g.align-(y?1:0):g.offset-(y?V:0)},electricInput:/^\s*([\}\]\)]|else:|elif |except |finally:)$/,closeBrackets:{triples:`'"`},lineComment:"#",fold:"indent"};return c}),b.defineMIME("text/x-python","python");var k=function(I){return I.split(" ")};b.defineMIME("text/x-cython",{name:"python",extra_keywords:k("by cdef cimport cpdef ctypedef enum except extern gil include nogil property public readonly struct union DEF IF ELIF ELSE")})})})()),Sa.exports}ef();var Ta={exports:{}},Ca;function tf(){return Ca||(Ca=1,(function(ct,xt){(function(b){b(mt())})(function(b){function pe(g,y,j,de,v,d){this.indented=g,this.column=y,this.type=j,this.info=de,this.align=v,this.prev=d}function _(g,y,j,de){var v=g.indented;return g.context&&g.context.type=="statement"&&j!="statement"&&(v=g.context.indented),g.context=new pe(v,y,j,de,null,g.context)}function te(g){var y=g.context.type;return(y==")"||y=="]"||y=="}")&&(g.indented=g.context.indented),g.context=g.context.prev}function oe(g,y,j){if(y.prevToken=="variable"||y.prevToken=="type"||/\S(?:[^- ]>|[*\]])\s*$|\*$/.test(g.string.slice(0,j))||y.typeAtEndOfLine&&g.column()==g.indentation())return!0}function Q(g){for(;;){if(!g||g.type=="top")return!0;if(g.type=="}"&&g.prev.info!="namespace")return!1;g=g.prev}}b.defineMode("clike",function(g,y){var j=g.indentUnit,de=y.statementIndentUnit||j,v=y.dontAlignCalls,d=y.keywords||{},fe=y.types||{},Te=y.builtin||{},le=y.blockKeywords||{},xe=y.defKeywords||{},Me=y.atoms||{},Fe=y.hooks||{},Ce=y.multiLineStrings,ve=y.indentStatements!==!1,Oe=y.indentSwitch!==!1,qe=y.namespaceSeparator,Ve=y.isPunctuationChar||/[\[\]{}\(\),;\:\.]/,dt=y.numberStart||/[\d\.]/,Pe=y.number||/^(?:0x[a-f\d]+|0b[01]+|(?:\d+\.?\d*|\.\d+)(?:e[-+]?\d+)?)(u|ll?|l|f)?/i,_e=y.isOperatorChar||/[+\-*&%=<>!?|\/]/,Ue=y.isIdentifierChar||/[\w\$_\xa1-\uffff]/,et=y.isReservedIdentifier||!1,we,Ie;function E(me,De){var be=me.next();if(Fe[be]){var Be=Fe[be](me,De);if(Be!==!1)return Be}if(be=='"'||be=="'")return De.tokenize=ee(be),De.tokenize(me,De);if(dt.test(be)){if(me.backUp(1),me.match(Pe))return"number";me.next()}if(Ve.test(be))return we=be,null;if(be=="/"){if(me.eat("*"))return De.tokenize=K,K(me,De);if(me.eat("/"))return me.skipToEnd(),"comment"}if(_e.test(be)){for(;!me.match(/^\/[\/*]/,!1)&&me.eat(_e););return"operator"}if(me.eatWhile(Ue),qe)for(;me.match(qe);)me.eatWhile(Ue);var Ne=me.current();return I(d,Ne)?(I(le,Ne)&&(we="newstatement"),I(xe,Ne)&&(Ie=!0),"keyword"):I(fe,Ne)?"type":I(Te,Ne)||et&&et(Ne)?(I(le,Ne)&&(we="newstatement"),"builtin"):I(Me,Ne)?"atom":"variable"}function ee(me){return function(De,be){for(var Be=!1,Ne,Mt=!1;(Ne=De.next())!=null;){if(Ne==me&&!Be){Mt=!0;break}Be=!Be&&Ne=="\\"}return(Mt||!(Be||Ce))&&(be.tokenize=null),"string"}}function K(me,De){for(var be=!1,Be;Be=me.next();){if(Be=="/"&&be){De.tokenize=null;break}be=Be=="*"}return"comment"}function ze(me,De){y.typeFirstDefinitions&&me.eol()&&Q(De.context)&&(De.typeAtEndOfLine=oe(me,De,me.pos))}return{startState:function(me){return{tokenize:null,context:new pe((me||0)-j,0,"top",null,!1),indented:0,startOfLine:!0,prevToken:null}},token:function(me,De){var be=De.context;if(me.sol()&&(be.align==null&&(be.align=!1),De.indented=me.indentation(),De.startOfLine=!0),me.eatSpace())return ze(me,De),null;we=Ie=null;var Be=(De.tokenize||E)(me,De);if(Be=="comment"||Be=="meta")return Be;if(be.align==null&&(be.align=!0),we==";"||we==":"||we==","&&me.match(/^\s*(?:\/\/.*)?$/,!1))for(;De.context.type=="statement";)te(De);else if(we=="{")_(De,me.column(),"}");else if(we=="[")_(De,me.column(),"]");else if(we=="(")_(De,me.column(),")");else if(we=="}"){for(;be.type=="statement";)be=te(De);for(be.type=="}"&&(be=te(De));be.type=="statement";)be=te(De)}else we==be.type?te(De):ve&&((be.type=="}"||be.type=="top")&&we!=";"||be.type=="statement"&&we=="newstatement")&&_(De,me.column(),"statement",me.current());if(Be=="variable"&&(De.prevToken=="def"||y.typeFirstDefinitions&&oe(me,De,me.start)&&Q(De.context)&&me.match(/^\s*\(/,!1))&&(Be="def"),Fe.token){var Ne=Fe.token(me,De,Be);Ne!==void 0&&(Be=Ne)}return Be=="def"&&y.styleDefs===!1&&(Be="variable"),De.startOfLine=!1,De.prevToken=Ie?"def":Be||we,ze(me,De),Be},indent:function(me,De){if(me.tokenize!=E&&me.tokenize!=null||me.typeAtEndOfLine&&Q(me.context))return b.Pass;var be=me.context,Be=De&&De.charAt(0),Ne=Be==be.type;if(be.type=="statement"&&Be=="}"&&(be=be.prev),y.dontIndentStatements)for(;be.type=="statement"&&y.dontIndentStatements.test(be.info);)be=be.prev;if(Fe.indent){var Mt=Fe.indent(me,be,De,j);if(typeof Mt=="number")return Mt}var Pt=be.prev&&be.prev.info=="switch";if(y.allmanIndentation&&/[{(]/.test(Be)){for(;be.type!="top"&&be.type!="}";)be=be.prev;return be.indented}return be.type=="statement"?be.indented+(Be=="{"?0:de):be.align&&(!v||be.type!=")")?be.column+(Ne?0:1):be.type==")"&&!Ne?be.indented+de:be.indented+(Ne?0:j)+(!Ne&&Pt&&!/^(?:case|default)\b/.test(De)?j:0)},electricInput:Oe?/^\s*(?:case .*?:|default:|\{\}?|\})$/:/^\s*[{}]$/,blockCommentStart:"/*",blockCommentEnd:"*/",blockCommentContinue:" * ",lineComment:"//",fold:"brace"}});function k(g){for(var y={},j=g.split(" "),de=0;de!?|\/#:@]/,hooks:{"@":function(g){return g.eatWhile(/[\w\$_]/),"meta"},'"':function(g,y){return g.match('""')?(y.tokenize=F,y.tokenize(g,y)):!1},"'":function(g){return g.match(/^(\\[^'\s]+|[^\\'])'/)?"string-2":(g.eatWhile(/[\w\$_\xa1-\uffff]/),"atom")},"=":function(g,y){var j=y.context;return j.type=="}"&&j.align&&g.eat(">")?(y.context=new pe(j.indented,j.column,j.type,j.info,null,j.prev),"operator"):!1},"/":function(g,y){return g.eat("*")?(y.tokenize=G(1),y.tokenize(g,y)):!1}},modeProps:{closeBrackets:{pairs:'()[]{}""',triples:'"'}}});function c(g){return function(y,j){for(var de=!1,v,d=!1;!y.eol();){if(!g&&!de&&y.match('"')){d=!0;break}if(g&&y.match('"""')){d=!0;break}v=y.next(),!de&&v=="$"&&y.match("{")&&y.skipTo("}"),de=!de&&v=="\\"&&!g}return(d||!g)&&(j.tokenize=null),"string"}}$("text/x-kotlin",{name:"clike",keywords:k("package as typealias class interface this super val operator var fun for is in This throw return annotation break continue object if else while do try when !in !is as? file import where by get set abstract enum open inner override private public internal protected catch finally out final vararg reified dynamic companion constructor init sealed field property receiver param sparam lateinit data inline noinline tailrec external annotation crossinline const operator infix suspend actual expect setparam value"),types:k("Boolean Byte Character CharSequence Class ClassLoader Cloneable Comparable Compiler Double Exception Float Integer Long Math Number Object Package Pair Process Runtime Runnable SecurityManager Short StackTraceElement StrictMath String StringBuffer System Thread ThreadGroup ThreadLocal Throwable Triple Void Annotation Any BooleanArray ByteArray Char CharArray DeprecationLevel DoubleArray Enum FloatArray Function Int IntArray Lazy LazyThreadSafetyMode LongArray Nothing ShortArray Unit"),intendSwitch:!1,indentStatements:!1,multiLineStrings:!0,number:/^(?:0x[a-f\d_]+|0b[01_]+|(?:[\d_]+(\.\d+)?|\.\d+)(?:e[-+]?[\d_]+)?)(u|ll?|l|f)?/i,blockKeywords:k("catch class do else finally for if where try while enum"),defKeywords:k("class val var object interface fun"),atoms:k("true false null this"),hooks:{"@":function(g){return g.eatWhile(/[\w\$_]/),"meta"},"*":function(g,y){return y.prevToken=="."?"variable":"operator"},'"':function(g,y){return y.tokenize=c(g.match('""')),y.tokenize(g,y)},"/":function(g,y){return g.eat("*")?(y.tokenize=G(1),y.tokenize(g,y)):!1},indent:function(g,y,j,de){var v=j&&j.charAt(0);if((g.prevToken=="}"||g.prevToken==")")&&j=="")return g.indented;if(g.prevToken=="operator"&&j!="}"&&g.context.type!="}"||g.prevToken=="variable"&&v=="."||(g.prevToken=="}"||g.prevToken==")")&&v==".")return de*2+y.indented;if(y.align&&y.type=="}")return y.indented+(g.context.type==(j||"").charAt(0)?0:de)}},modeProps:{closeBrackets:{triples:'"'}}}),$(["x-shader/x-vertex","x-shader/x-fragment"],{name:"clike",keywords:k("sampler1D sampler2D sampler3D samplerCube sampler1DShadow sampler2DShadow const attribute uniform varying break continue discard return for while do if else struct in out inout"),types:k("float int bool void vec2 vec3 vec4 ivec2 ivec3 ivec4 bvec2 bvec3 bvec4 mat2 mat3 mat4"),blockKeywords:k("for while do if else struct"),builtin:k("radians degrees sin cos tan asin acos atan pow exp log exp2 sqrt inversesqrt abs sign floor ceil fract mod min max clamp mix step smoothstep length distance dot cross normalize ftransform faceforward reflect refract matrixCompMult lessThan lessThanEqual greaterThan greaterThanEqual equal notEqual any all not texture1D texture1DProj texture1DLod texture1DProjLod texture2D texture2DProj texture2DLod texture2DProjLod texture3D texture3DProj texture3DLod texture3DProjLod textureCube textureCubeLod shadow1D shadow2D shadow1DProj shadow2DProj shadow1DLod shadow2DLod shadow1DProjLod shadow2DProjLod dFdx dFdy fwidth noise1 noise2 noise3 noise4"),atoms:k("true false gl_FragColor gl_SecondaryColor gl_Normal gl_Vertex gl_MultiTexCoord0 gl_MultiTexCoord1 gl_MultiTexCoord2 gl_MultiTexCoord3 gl_MultiTexCoord4 gl_MultiTexCoord5 gl_MultiTexCoord6 gl_MultiTexCoord7 gl_FogCoord gl_PointCoord gl_Position gl_PointSize gl_ClipVertex gl_FrontColor gl_BackColor gl_FrontSecondaryColor gl_BackSecondaryColor gl_TexCoord gl_FogFragCoord gl_FragCoord gl_FrontFacing gl_FragData gl_FragDepth gl_ModelViewMatrix gl_ProjectionMatrix gl_ModelViewProjectionMatrix gl_TextureMatrix gl_NormalMatrix gl_ModelViewMatrixInverse gl_ProjectionMatrixInverse gl_ModelViewProjectionMatrixInverse gl_TextureMatrixTranspose gl_ModelViewMatrixInverseTranspose gl_ProjectionMatrixInverseTranspose gl_ModelViewProjectionMatrixInverseTranspose gl_TextureMatrixInverseTranspose gl_NormalScale gl_DepthRange gl_ClipPlane gl_Point gl_FrontMaterial gl_BackMaterial gl_LightSource gl_LightModel gl_FrontLightModelProduct gl_BackLightModelProduct gl_TextureColor gl_EyePlaneS gl_EyePlaneT gl_EyePlaneR gl_EyePlaneQ gl_FogParameters gl_MaxLights gl_MaxClipPlanes gl_MaxTextureUnits gl_MaxTextureCoords gl_MaxVertexAttribs gl_MaxVertexUniformComponents gl_MaxVaryingFloats gl_MaxVertexTextureImageUnits gl_MaxTextureImageUnits gl_MaxFragmentUniformComponents gl_MaxCombineTextureImageUnits gl_MaxDrawBuffers"),indentSwitch:!1,hooks:{"#":N},modeProps:{fold:["brace","include"]}}),$("text/x-nesc",{name:"clike",keywords:k(Y+" as atomic async call command component components configuration event generic implementation includes interface module new norace nx_struct nx_union post provides signal task uses abstract extends"),types:ue,blockKeywords:k(w),atoms:k("null true false"),hooks:{"#":N},modeProps:{fold:["brace","include"]}}),$("text/x-objectivec",{name:"clike",keywords:k(Y+" "+S),types:O,builtin:k(R),blockKeywords:k(w+" @synthesize @try @catch @finally @autoreleasepool @synchronized"),defKeywords:k(M+" @interface @implementation @protocol @class"),dontIndentStatements:/^@.*$/,typeFirstDefinitions:!0,atoms:k("YES NO NULL Nil nil true false nullptr"),isReservedIdentifier:X,hooks:{"#":N,"*":z},modeProps:{fold:["brace","include"]}}),$("text/x-objectivec++",{name:"clike",keywords:k(Y+" "+S+" "+ne),types:O,builtin:k(R),blockKeywords:k(w+" @synthesize @try @catch @finally @autoreleasepool @synchronized class try catch"),defKeywords:k(M+" @interface @implementation @protocol @class class namespace"),dontIndentStatements:/^@.*$|^template$/,typeFirstDefinitions:!0,atoms:k("YES NO NULL Nil nil true false nullptr"),isReservedIdentifier:X,hooks:{"#":N,"*":z,u:p,U:p,L:p,R:p,0:q,1:q,2:q,3:q,4:q,5:q,6:q,7:q,8:q,9:q,token:function(g,y,j){if(j=="variable"&&g.peek()=="("&&(y.prevToken==";"||y.prevToken==null||y.prevToken=="}")&&W(g.current()))return"def"}},namespaceSeparator:"::",modeProps:{fold:["brace","include"]}}),$("text/x-squirrel",{name:"clike",keywords:k("base break clone continue const default delete enum extends function in class foreach local resume return this throw typeof yield constructor instanceof static"),types:ue,blockKeywords:k("case catch class else for foreach if switch try while"),defKeywords:k("function local class"),typeFirstDefinitions:!0,atoms:k("true false null"),hooks:{"#":N},modeProps:{fold:["brace","include"]}});var T=null;function C(g){return function(y,j){for(var de=!1,v,d=!1;!y.eol();){if(!de&&y.match('"')&&(g=="single"||y.match('""'))){d=!0;break}if(!de&&y.match("``")){T=C(g),d=!0;break}v=y.next(),de=g=="single"&&!de&&v=="\\"}return d&&(j.tokenize=null),"string"}}$("text/x-ceylon",{name:"clike",keywords:k("abstracts alias assembly assert assign break case catch class continue dynamic else exists extends finally for function given if import in interface is let module new nonempty object of out outer package return satisfies super switch then this throw try value void while"),types:function(g){var y=g.charAt(0);return y===y.toUpperCase()&&y!==y.toLowerCase()},blockKeywords:k("case catch class dynamic else finally for function if interface module new object switch try while"),defKeywords:k("class dynamic function interface module object package value"),builtin:k("abstract actual aliased annotation by default deprecated doc final formal late license native optional sealed see serializable shared suppressWarnings tagged throws variable"),isPunctuationChar:/[\[\]{}\(\),;\:\.`]/,isOperatorChar:/[+\-*&%=<>!?|^~:\/]/,numberStart:/[\d#$]/,number:/^(?:#[\da-fA-F_]+|\$[01_]+|[\d_]+[kMGTPmunpf]?|[\d_]+\.[\d_]+(?:[eE][-+]?\d+|[kMGTPmunpf]|)|)/i,multiLineStrings:!0,typeFirstDefinitions:!0,atoms:k("true false null larger smaller equal empty finished"),indentSwitch:!1,styleDefs:!1,hooks:{"@":function(g){return g.eatWhile(/[\w\$_]/),"meta"},'"':function(g,y){return y.tokenize=C(g.match('""')?"triple":"single"),y.tokenize(g,y)},"`":function(g,y){return!T||!g.match("`")?!1:(y.tokenize=T,T=null,y.tokenize(g,y))},"'":function(g){return g.eatWhile(/[\w\$_\xa1-\uffff]/),"atom"},token:function(g,y,j){if((j=="variable"||j=="type")&&y.prevToken==".")return"variable-2"}},modeProps:{fold:["brace","import"],closeBrackets:{triples:'"'}}})})})()),Ta.exports}tf();var Da={exports:{}},Ma={exports:{}},Fa;function rf(){return Fa||(Fa=1,(function(ct,xt){(function(b){b(mt())})(function(b){b.modeInfo=[{name:"APL",mime:"text/apl",mode:"apl",ext:["dyalog","apl"]},{name:"PGP",mimes:["application/pgp","application/pgp-encrypted","application/pgp-keys","application/pgp-signature"],mode:"asciiarmor",ext:["asc","pgp","sig"]},{name:"ASN.1",mime:"text/x-ttcn-asn",mode:"asn.1",ext:["asn","asn1"]},{name:"Asterisk",mime:"text/x-asterisk",mode:"asterisk",file:/^extensions\.conf$/i},{name:"Brainfuck",mime:"text/x-brainfuck",mode:"brainfuck",ext:["b","bf"]},{name:"C",mime:"text/x-csrc",mode:"clike",ext:["c","h","ino"]},{name:"C++",mime:"text/x-c++src",mode:"clike",ext:["cpp","c++","cc","cxx","hpp","h++","hh","hxx"],alias:["cpp"]},{name:"Cobol",mime:"text/x-cobol",mode:"cobol",ext:["cob","cpy","cbl"]},{name:"C#",mime:"text/x-csharp",mode:"clike",ext:["cs"],alias:["csharp","cs"]},{name:"Clojure",mime:"text/x-clojure",mode:"clojure",ext:["clj","cljc","cljx"]},{name:"ClojureScript",mime:"text/x-clojurescript",mode:"clojure",ext:["cljs"]},{name:"Closure Stylesheets (GSS)",mime:"text/x-gss",mode:"css",ext:["gss"]},{name:"CMake",mime:"text/x-cmake",mode:"cmake",ext:["cmake","cmake.in"],file:/^CMakeLists\.txt$/},{name:"CoffeeScript",mimes:["application/vnd.coffeescript","text/coffeescript","text/x-coffeescript"],mode:"coffeescript",ext:["coffee"],alias:["coffee","coffee-script"]},{name:"Common Lisp",mime:"text/x-common-lisp",mode:"commonlisp",ext:["cl","lisp","el"],alias:["lisp"]},{name:"Cypher",mime:"application/x-cypher-query",mode:"cypher",ext:["cyp","cypher"]},{name:"Cython",mime:"text/x-cython",mode:"python",ext:["pyx","pxd","pxi"]},{name:"Crystal",mime:"text/x-crystal",mode:"crystal",ext:["cr"]},{name:"CSS",mime:"text/css",mode:"css",ext:["css"]},{name:"CQL",mime:"text/x-cassandra",mode:"sql",ext:["cql"]},{name:"D",mime:"text/x-d",mode:"d",ext:["d"]},{name:"Dart",mimes:["application/dart","text/x-dart"],mode:"dart",ext:["dart"]},{name:"diff",mime:"text/x-diff",mode:"diff",ext:["diff","patch"]},{name:"Django",mime:"text/x-django",mode:"django"},{name:"Dockerfile",mime:"text/x-dockerfile",mode:"dockerfile",file:/^Dockerfile$/},{name:"DTD",mime:"application/xml-dtd",mode:"dtd",ext:["dtd"]},{name:"Dylan",mime:"text/x-dylan",mode:"dylan",ext:["dylan","dyl","intr"]},{name:"EBNF",mime:"text/x-ebnf",mode:"ebnf"},{name:"ECL",mime:"text/x-ecl",mode:"ecl",ext:["ecl"]},{name:"edn",mime:"application/edn",mode:"clojure",ext:["edn"]},{name:"Eiffel",mime:"text/x-eiffel",mode:"eiffel",ext:["e"]},{name:"Elm",mime:"text/x-elm",mode:"elm",ext:["elm"]},{name:"Embedded JavaScript",mime:"application/x-ejs",mode:"htmlembedded",ext:["ejs"]},{name:"Embedded Ruby",mime:"application/x-erb",mode:"htmlembedded",ext:["erb"]},{name:"Erlang",mime:"text/x-erlang",mode:"erlang",ext:["erl"]},{name:"Esper",mime:"text/x-esper",mode:"sql"},{name:"Factor",mime:"text/x-factor",mode:"factor",ext:["factor"]},{name:"FCL",mime:"text/x-fcl",mode:"fcl"},{name:"Forth",mime:"text/x-forth",mode:"forth",ext:["forth","fth","4th"]},{name:"Fortran",mime:"text/x-fortran",mode:"fortran",ext:["f","for","f77","f90","f95"]},{name:"F#",mime:"text/x-fsharp",mode:"mllike",ext:["fs"],alias:["fsharp"]},{name:"Gas",mime:"text/x-gas",mode:"gas",ext:["s"]},{name:"Gherkin",mime:"text/x-feature",mode:"gherkin",ext:["feature"]},{name:"GitHub Flavored Markdown",mime:"text/x-gfm",mode:"gfm",file:/^(readme|contributing|history)\.md$/i},{name:"Go",mime:"text/x-go",mode:"go",ext:["go"]},{name:"Groovy",mime:"text/x-groovy",mode:"groovy",ext:["groovy","gradle"],file:/^Jenkinsfile$/},{name:"HAML",mime:"text/x-haml",mode:"haml",ext:["haml"]},{name:"Haskell",mime:"text/x-haskell",mode:"haskell",ext:["hs"]},{name:"Haskell (Literate)",mime:"text/x-literate-haskell",mode:"haskell-literate",ext:["lhs"]},{name:"Haxe",mime:"text/x-haxe",mode:"haxe",ext:["hx"]},{name:"HXML",mime:"text/x-hxml",mode:"haxe",ext:["hxml"]},{name:"ASP.NET",mime:"application/x-aspx",mode:"htmlembedded",ext:["aspx"],alias:["asp","aspx"]},{name:"HTML",mime:"text/html",mode:"htmlmixed",ext:["html","htm","handlebars","hbs"],alias:["xhtml"]},{name:"HTTP",mime:"message/http",mode:"http"},{name:"IDL",mime:"text/x-idl",mode:"idl",ext:["pro"]},{name:"Pug",mime:"text/x-pug",mode:"pug",ext:["jade","pug"],alias:["jade"]},{name:"Java",mime:"text/x-java",mode:"clike",ext:["java"]},{name:"Java Server Pages",mime:"application/x-jsp",mode:"htmlembedded",ext:["jsp"],alias:["jsp"]},{name:"JavaScript",mimes:["text/javascript","text/ecmascript","application/javascript","application/x-javascript","application/ecmascript"],mode:"javascript",ext:["js"],alias:["ecmascript","js","node"]},{name:"JSON",mimes:["application/json","application/x-json"],mode:"javascript",ext:["json","map"],alias:["json5"]},{name:"JSON-LD",mime:"application/ld+json",mode:"javascript",ext:["jsonld"],alias:["jsonld"]},{name:"JSX",mime:"text/jsx",mode:"jsx",ext:["jsx"]},{name:"Jinja2",mime:"text/jinja2",mode:"jinja2",ext:["j2","jinja","jinja2"]},{name:"Julia",mime:"text/x-julia",mode:"julia",ext:["jl"],alias:["jl"]},{name:"Kotlin",mime:"text/x-kotlin",mode:"clike",ext:["kt"]},{name:"LESS",mime:"text/x-less",mode:"css",ext:["less"]},{name:"LiveScript",mime:"text/x-livescript",mode:"livescript",ext:["ls"],alias:["ls"]},{name:"Lua",mime:"text/x-lua",mode:"lua",ext:["lua"]},{name:"Markdown",mime:"text/x-markdown",mode:"markdown",ext:["markdown","md","mkd"]},{name:"mIRC",mime:"text/mirc",mode:"mirc"},{name:"MariaDB SQL",mime:"text/x-mariadb",mode:"sql"},{name:"Mathematica",mime:"text/x-mathematica",mode:"mathematica",ext:["m","nb","wl","wls"]},{name:"Modelica",mime:"text/x-modelica",mode:"modelica",ext:["mo"]},{name:"MUMPS",mime:"text/x-mumps",mode:"mumps",ext:["mps"]},{name:"MS SQL",mime:"text/x-mssql",mode:"sql"},{name:"mbox",mime:"application/mbox",mode:"mbox",ext:["mbox"]},{name:"MySQL",mime:"text/x-mysql",mode:"sql"},{name:"Nginx",mime:"text/x-nginx-conf",mode:"nginx",file:/nginx.*\.conf$/i},{name:"NSIS",mime:"text/x-nsis",mode:"nsis",ext:["nsh","nsi"]},{name:"NTriples",mimes:["application/n-triples","application/n-quads","text/n-triples"],mode:"ntriples",ext:["nt","nq"]},{name:"Objective-C",mime:"text/x-objectivec",mode:"clike",ext:["m"],alias:["objective-c","objc"]},{name:"Objective-C++",mime:"text/x-objectivec++",mode:"clike",ext:["mm"],alias:["objective-c++","objc++"]},{name:"OCaml",mime:"text/x-ocaml",mode:"mllike",ext:["ml","mli","mll","mly"]},{name:"Octave",mime:"text/x-octave",mode:"octave",ext:["m"]},{name:"Oz",mime:"text/x-oz",mode:"oz",ext:["oz"]},{name:"Pascal",mime:"text/x-pascal",mode:"pascal",ext:["p","pas"]},{name:"PEG.js",mime:"null",mode:"pegjs",ext:["jsonld"]},{name:"Perl",mime:"text/x-perl",mode:"perl",ext:["pl","pm"]},{name:"PHP",mimes:["text/x-php","application/x-httpd-php","application/x-httpd-php-open"],mode:"php",ext:["php","php3","php4","php5","php7","phtml"]},{name:"Pig",mime:"text/x-pig",mode:"pig",ext:["pig"]},{name:"Plain Text",mime:"text/plain",mode:"null",ext:["txt","text","conf","def","list","log"]},{name:"PLSQL",mime:"text/x-plsql",mode:"sql",ext:["pls"]},{name:"PostgreSQL",mime:"text/x-pgsql",mode:"sql"},{name:"PowerShell",mime:"application/x-powershell",mode:"powershell",ext:["ps1","psd1","psm1"]},{name:"Properties files",mime:"text/x-properties",mode:"properties",ext:["properties","ini","in"],alias:["ini","properties"]},{name:"ProtoBuf",mime:"text/x-protobuf",mode:"protobuf",ext:["proto"]},{name:"Python",mime:"text/x-python",mode:"python",ext:["BUILD","bzl","py","pyw"],file:/^(BUCK|BUILD)$/},{name:"Puppet",mime:"text/x-puppet",mode:"puppet",ext:["pp"]},{name:"Q",mime:"text/x-q",mode:"q",ext:["q"]},{name:"R",mime:"text/x-rsrc",mode:"r",ext:["r","R"],alias:["rscript"]},{name:"reStructuredText",mime:"text/x-rst",mode:"rst",ext:["rst"],alias:["rst"]},{name:"RPM Changes",mime:"text/x-rpm-changes",mode:"rpm"},{name:"RPM Spec",mime:"text/x-rpm-spec",mode:"rpm",ext:["spec"]},{name:"Ruby",mime:"text/x-ruby",mode:"ruby",ext:["rb"],alias:["jruby","macruby","rake","rb","rbx"]},{name:"Rust",mime:"text/x-rustsrc",mode:"rust",ext:["rs"]},{name:"SAS",mime:"text/x-sas",mode:"sas",ext:["sas"]},{name:"Sass",mime:"text/x-sass",mode:"sass",ext:["sass"]},{name:"Scala",mime:"text/x-scala",mode:"clike",ext:["scala"]},{name:"Scheme",mime:"text/x-scheme",mode:"scheme",ext:["scm","ss"]},{name:"SCSS",mime:"text/x-scss",mode:"css",ext:["scss"]},{name:"Shell",mimes:["text/x-sh","application/x-sh"],mode:"shell",ext:["sh","ksh","bash"],alias:["bash","sh","zsh"],file:/^PKGBUILD$/},{name:"Sieve",mime:"application/sieve",mode:"sieve",ext:["siv","sieve"]},{name:"Slim",mimes:["text/x-slim","application/x-slim"],mode:"slim",ext:["slim"]},{name:"Smalltalk",mime:"text/x-stsrc",mode:"smalltalk",ext:["st"]},{name:"Smarty",mime:"text/x-smarty",mode:"smarty",ext:["tpl"]},{name:"Solr",mime:"text/x-solr",mode:"solr"},{name:"SML",mime:"text/x-sml",mode:"mllike",ext:["sml","sig","fun","smackspec"]},{name:"Soy",mime:"text/x-soy",mode:"soy",ext:["soy"],alias:["closure template"]},{name:"SPARQL",mime:"application/sparql-query",mode:"sparql",ext:["rq","sparql"],alias:["sparul"]},{name:"Spreadsheet",mime:"text/x-spreadsheet",mode:"spreadsheet",alias:["excel","formula"]},{name:"SQL",mime:"text/x-sql",mode:"sql",ext:["sql"]},{name:"SQLite",mime:"text/x-sqlite",mode:"sql"},{name:"Squirrel",mime:"text/x-squirrel",mode:"clike",ext:["nut"]},{name:"Stylus",mime:"text/x-styl",mode:"stylus",ext:["styl"]},{name:"Swift",mime:"text/x-swift",mode:"swift",ext:["swift"]},{name:"sTeX",mime:"text/x-stex",mode:"stex"},{name:"LaTeX",mime:"text/x-latex",mode:"stex",ext:["text","ltx","tex"],alias:["tex"]},{name:"SystemVerilog",mime:"text/x-systemverilog",mode:"verilog",ext:["v","sv","svh"]},{name:"Tcl",mime:"text/x-tcl",mode:"tcl",ext:["tcl"]},{name:"Textile",mime:"text/x-textile",mode:"textile",ext:["textile"]},{name:"TiddlyWiki",mime:"text/x-tiddlywiki",mode:"tiddlywiki"},{name:"Tiki wiki",mime:"text/tiki",mode:"tiki"},{name:"TOML",mime:"text/x-toml",mode:"toml",ext:["toml"]},{name:"Tornado",mime:"text/x-tornado",mode:"tornado"},{name:"troff",mime:"text/troff",mode:"troff",ext:["1","2","3","4","5","6","7","8","9"]},{name:"TTCN",mime:"text/x-ttcn",mode:"ttcn",ext:["ttcn","ttcn3","ttcnpp"]},{name:"TTCN_CFG",mime:"text/x-ttcn-cfg",mode:"ttcn-cfg",ext:["cfg"]},{name:"Turtle",mime:"text/turtle",mode:"turtle",ext:["ttl"]},{name:"TypeScript",mime:"application/typescript",mode:"javascript",ext:["ts"],alias:["ts"]},{name:"TypeScript-JSX",mime:"text/typescript-jsx",mode:"jsx",ext:["tsx"],alias:["tsx"]},{name:"Twig",mime:"text/x-twig",mode:"twig"},{name:"Web IDL",mime:"text/x-webidl",mode:"webidl",ext:["webidl"]},{name:"VB.NET",mime:"text/x-vb",mode:"vb",ext:["vb"]},{name:"VBScript",mime:"text/vbscript",mode:"vbscript",ext:["vbs"]},{name:"Velocity",mime:"text/velocity",mode:"velocity",ext:["vtl"]},{name:"Verilog",mime:"text/x-verilog",mode:"verilog",ext:["v"]},{name:"VHDL",mime:"text/x-vhdl",mode:"vhdl",ext:["vhd","vhdl"]},{name:"Vue.js Component",mimes:["script/x-vue","text/x-vue"],mode:"vue",ext:["vue"]},{name:"XML",mimes:["application/xml","text/xml"],mode:"xml",ext:["xml","xsl","xsd","svg"],alias:["rss","wsdl","xsd"]},{name:"XQuery",mime:"application/xquery",mode:"xquery",ext:["xy","xquery"]},{name:"Yacas",mime:"text/x-yacas",mode:"yacas",ext:["ys"]},{name:"YAML",mimes:["text/x-yaml","text/yaml"],mode:"yaml",ext:["yaml","yml"],alias:["yml"]},{name:"Z80",mime:"text/x-z80",mode:"z80",ext:["z80"]},{name:"mscgen",mime:"text/x-mscgen",mode:"mscgen",ext:["mscgen","mscin","msc"]},{name:"xu",mime:"text/x-xu",mode:"mscgen",ext:["xu"]},{name:"msgenny",mime:"text/x-msgenny",mode:"mscgen",ext:["msgenny"]},{name:"WebAssembly",mime:"text/webassembly",mode:"wast",ext:["wat","wast"]}];for(var pe=0;pe-1&&te.substring(k+1,te.length);if(I)return b.findModeByExtension(I)},b.findModeByName=function(te){te=te.toLowerCase();for(var oe=0;oe` "'(~:]+/,ue=/^(~~~+|```+)[ \t]*([\w\/+#-]*)[^\n`]*$/,O=/^\s*\[[^\]]+?\]:.*$/,w=/[!"#$%&'()*+,\-.\/:;<=>?@\[\\\]^_`{|}~\xA1\xA7\xAB\xB6\xB7\xBB\xBF\u037E\u0387\u055A-\u055F\u0589\u058A\u05BE\u05C0\u05C3\u05C6\u05F3\u05F4\u0609\u060A\u060C\u060D\u061B\u061E\u061F\u066A-\u066D\u06D4\u0700-\u070D\u07F7-\u07F9\u0830-\u083E\u085E\u0964\u0965\u0970\u0AF0\u0DF4\u0E4F\u0E5A\u0E5B\u0F04-\u0F12\u0F14\u0F3A-\u0F3D\u0F85\u0FD0-\u0FD4\u0FD9\u0FDA\u104A-\u104F\u10FB\u1360-\u1368\u1400\u166D\u166E\u169B\u169C\u16EB-\u16ED\u1735\u1736\u17D4-\u17D6\u17D8-\u17DA\u1800-\u180A\u1944\u1945\u1A1E\u1A1F\u1AA0-\u1AA6\u1AA8-\u1AAD\u1B5A-\u1B60\u1BFC-\u1BFF\u1C3B-\u1C3F\u1C7E\u1C7F\u1CC0-\u1CC7\u1CD3\u2010-\u2027\u2030-\u2043\u2045-\u2051\u2053-\u205E\u207D\u207E\u208D\u208E\u2308-\u230B\u2329\u232A\u2768-\u2775\u27C5\u27C6\u27E6-\u27EF\u2983-\u2998\u29D8-\u29DB\u29FC\u29FD\u2CF9-\u2CFC\u2CFE\u2CFF\u2D70\u2E00-\u2E2E\u2E30-\u2E42\u3001-\u3003\u3008-\u3011\u3014-\u301F\u3030\u303D\u30A0\u30FB\uA4FE\uA4FF\uA60D-\uA60F\uA673\uA67E\uA6F2-\uA6F7\uA874-\uA877\uA8CE\uA8CF\uA8F8-\uA8FA\uA8FC\uA92E\uA92F\uA95F\uA9C1-\uA9CD\uA9DE\uA9DF\uAA5C-\uAA5F\uAADE\uAADF\uAAF0\uAAF1\uABEB\uFD3E\uFD3F\uFE10-\uFE19\uFE30-\uFE52\uFE54-\uFE61\uFE63\uFE68\uFE6A\uFE6B\uFF01-\uFF03\uFF05-\uFF0A\uFF0C-\uFF0F\uFF1A\uFF1B\uFF1F\uFF20\uFF3B-\uFF3D\uFF3F\uFF5B\uFF5D\uFF5F-\uFF65]|\uD800[\uDD00-\uDD02\uDF9F\uDFD0]|\uD801\uDD6F|\uD802[\uDC57\uDD1F\uDD3F\uDE50-\uDE58\uDE7F\uDEF0-\uDEF6\uDF39-\uDF3F\uDF99-\uDF9C]|\uD804[\uDC47-\uDC4D\uDCBB\uDCBC\uDCBE-\uDCC1\uDD40-\uDD43\uDD74\uDD75\uDDC5-\uDDC9\uDDCD\uDDDB\uDDDD-\uDDDF\uDE38-\uDE3D\uDEA9]|\uD805[\uDCC6\uDDC1-\uDDD7\uDE41-\uDE43\uDF3C-\uDF3E]|\uD809[\uDC70-\uDC74]|\uD81A[\uDE6E\uDE6F\uDEF5\uDF37-\uDF3B\uDF44]|\uD82F\uDC9F|\uD836[\uDE87-\uDE8B]/,M=" ";function N(v,d,fe){return d.f=d.inline=fe,fe(v,d)}function z(v,d,fe){return d.f=d.block=fe,fe(v,d)}function X(v){return!v||!/\S/.test(v.string)}function q(v){if(v.linkTitle=!1,v.linkHref=!1,v.linkText=!1,v.em=!1,v.strong=!1,v.strikethrough=!1,v.quote=0,v.indentedCode=!1,v.f==W){var d=oe;if(!d){var fe=b.innerMode(te,v.htmlState);d=fe.mode.name=="xml"&&fe.state.tagStart===null&&!fe.state.context&&fe.state.tokenize.isInText}d&&(v.f=F,v.block=p,v.htmlState=null)}return v.trailingSpace=0,v.trailingSpaceNewLine=!1,v.prevLine=v.thisLine,v.thisLine={stream:null},null}function p(v,d){var fe=v.column()===d.indentation,Te=X(d.prevLine.stream),le=d.indentedCode,xe=d.prevLine.hr,Me=d.list!==!1,Fe=(d.listStack[d.listStack.length-1]||0)+3;d.indentedCode=!1;var Ce=d.indentation;if(d.indentationDiff===null&&(d.indentationDiff=d.indentation,Me)){for(d.list=null;Ce=4&&(le||d.prevLine.fencedCodeEnd||d.prevLine.header||Te))return v.skipToEnd(),d.indentedCode=!0,k.code;if(v.eatSpace())return null;if(fe&&d.indentation<=Fe&&(qe=v.match(R))&&qe[1].length<=6)return d.quote=0,d.header=qe[1].length,d.thisLine.header=!0,_.highlightFormatting&&(d.formatting="header"),d.f=d.inline,P(d);if(d.indentation<=Fe&&v.eat(">"))return d.quote=fe?1:d.quote+1,_.highlightFormatting&&(d.formatting="quote"),v.eatSpace(),P(d);if(!Oe&&!d.setext&&fe&&d.indentation<=Fe&&(qe=v.match(ne))){var Ve=qe[1]?"ol":"ul";return d.indentation=Ce+v.current().length,d.list=!0,d.quote=0,d.listStack.push(d.indentation),d.em=!1,d.strong=!1,d.code=!1,d.strikethrough=!1,_.taskLists&&v.match(S,!1)&&(d.taskList=!0),d.f=d.inline,_.highlightFormatting&&(d.formatting=["list","list-"+Ve]),P(d)}else{if(fe&&d.indentation<=Fe&&(qe=v.match(ue,!0)))return d.quote=0,d.fencedEndRE=new RegExp(qe[1]+"+ *$"),d.localMode=_.fencedCodeBlockHighlighting&&Q(qe[2]||_.fencedCodeBlockDefaultMode),d.localMode&&(d.localState=b.startState(d.localMode)),d.f=d.block=J,_.highlightFormatting&&(d.formatting="code-block"),d.code=-1,P(d);if(d.setext||(!ve||!Me)&&!d.quote&&d.list===!1&&!d.code&&!Oe&&!O.test(v.string)&&(qe=v.lookAhead(1))&&(qe=qe.match(A)))return d.setext?(d.header=d.setext,d.setext=0,v.skipToEnd(),_.highlightFormatting&&(d.formatting="header")):(d.header=qe[0].charAt(0)=="="?1:2,d.setext=d.header),d.thisLine.header=!0,d.f=d.inline,P(d);if(Oe)return v.skipToEnd(),d.hr=!0,d.thisLine.hr=!0,k.hr;if(v.peek()==="[")return N(v,d,g)}return N(v,d,d.inline)}function W(v,d){var fe=te.token(v,d.htmlState);if(!oe){var Te=b.innerMode(te,d.htmlState);(Te.mode.name=="xml"&&Te.state.tagStart===null&&!Te.state.context&&Te.state.tokenize.isInText||d.md_inside&&v.current().indexOf(">")>-1)&&(d.f=F,d.block=p,d.htmlState=null)}return fe}function J(v,d){var fe=d.listStack[d.listStack.length-1]||0,Te=d.indentation=v.quote?d.push(k.formatting+"-"+v.formatting[fe]+"-"+v.quote):d.push("error"))}if(v.taskOpen)return d.push("meta"),d.length?d.join(" "):null;if(v.taskClosed)return d.push("property"),d.length?d.join(" "):null;if(v.linkHref?d.push(k.linkHref,"url"):(v.strong&&d.push(k.strong),v.em&&d.push(k.em),v.strikethrough&&d.push(k.strikethrough),v.emoji&&d.push(k.emoji),v.linkText&&d.push(k.linkText),v.code&&d.push(k.code),v.image&&d.push(k.image),v.imageAltText&&d.push(k.imageAltText,"link"),v.imageMarker&&d.push(k.imageMarker)),v.header&&d.push(k.header,k.header+"-"+v.header),v.quote&&(d.push(k.quote),!_.maxBlockquoteDepth||_.maxBlockquoteDepth>=v.quote?d.push(k.quote+"-"+v.quote):d.push(k.quote+"-"+_.maxBlockquoteDepth)),v.list!==!1){var Te=(v.listStack.length-1)%3;Te?Te===1?d.push(k.list2):d.push(k.list3):d.push(k.list1)}return v.trailingSpaceNewLine?d.push("trailing-space-new-line"):v.trailingSpace&&d.push("trailing-space-"+(v.trailingSpace%2?"a":"b")),d.length?d.join(" "):null}function $(v,d){if(v.match(V,!0))return P(d)}function F(v,d){var fe=d.text(v,d);if(typeof fe<"u")return fe;if(d.list)return d.list=null,P(d);if(d.taskList){var Te=v.match(S,!0)[1]===" ";return Te?d.taskOpen=!0:d.taskClosed=!0,_.highlightFormatting&&(d.formatting="task"),d.taskList=!1,P(d)}if(d.taskOpen=!1,d.taskClosed=!1,d.header&&v.match(/^#+$/,!0))return _.highlightFormatting&&(d.formatting="header"),P(d);var le=v.next();if(d.linkTitle){d.linkTitle=!1;var xe=le;le==="("&&(xe=")"),xe=(xe+"").replace(/([.?*+^\[\]\\(){}|-])/g,"\\$1");var Me="^\\s*(?:[^"+xe+"\\\\]+|\\\\\\\\|\\\\.)"+xe;if(v.match(new RegExp(Me),!0))return k.linkHref}if(le==="`"){var Fe=d.formatting;_.highlightFormatting&&(d.formatting="code"),v.eatWhile("`");var Ce=v.current().length;if(d.code==0&&(!d.quote||Ce==1))return d.code=Ce,P(d);if(Ce==d.code){var ve=P(d);return d.code=0,ve}else return d.formatting=Fe,P(d)}else if(d.code)return P(d);if(le==="\\"&&(v.next(),_.highlightFormatting)){var Oe=P(d),qe=k.formatting+"-escape";return Oe?Oe+" "+qe:qe}if(le==="!"&&v.match(/\[[^\]]*\] ?(?:\(|\[)/,!1))return d.imageMarker=!0,d.image=!0,_.highlightFormatting&&(d.formatting="image"),P(d);if(le==="["&&d.imageMarker&&v.match(/[^\]]*\](\(.*?\)| ?\[.*?\])/,!1))return d.imageMarker=!1,d.imageAltText=!0,_.highlightFormatting&&(d.formatting="image"),P(d);if(le==="]"&&d.imageAltText){_.highlightFormatting&&(d.formatting="image");var Oe=P(d);return d.imageAltText=!1,d.image=!1,d.inline=d.f=c,Oe}if(le==="["&&!d.image)return d.linkText&&v.match(/^.*?\]/)||(d.linkText=!0,_.highlightFormatting&&(d.formatting="link")),P(d);if(le==="]"&&d.linkText){_.highlightFormatting&&(d.formatting="link");var Oe=P(d);return d.linkText=!1,d.inline=d.f=v.match(/\(.*?\)| ?\[.*?\]/,!1)?c:F,Oe}if(le==="<"&&v.match(/^(https?|ftps?):\/\/(?:[^\\>]|\\.)+>/,!1)){d.f=d.inline=G,_.highlightFormatting&&(d.formatting="link");var Oe=P(d);return Oe?Oe+=" ":Oe="",Oe+k.linkInline}if(le==="<"&&v.match(/^[^> \\]+@(?:[^\\>]|\\.)+>/,!1)){d.f=d.inline=G,_.highlightFormatting&&(d.formatting="link");var Oe=P(d);return Oe?Oe+=" ":Oe="",Oe+k.linkEmail}if(_.xml&&le==="<"&&v.match(/^(!--|\?|!\[CDATA\[|[a-z][a-z0-9-]*(?:\s+[a-z_:.\-]+(?:\s*=\s*[^>]+)?)*\s*(?:>|$))/i,!1)){var Ve=v.string.indexOf(">",v.pos);if(Ve!=-1){var dt=v.string.substring(v.start,Ve);/markdown\s*=\s*('|"){0,1}1('|"){0,1}/.test(dt)&&(d.md_inside=!0)}return v.backUp(1),d.htmlState=b.startState(te),z(v,d,W)}if(_.xml&&le==="<"&&v.match(/^\/\w*?>/))return d.md_inside=!1,"tag";if(le==="*"||le==="_"){for(var Pe=1,_e=v.pos==1?" ":v.string.charAt(v.pos-2);Pe<3&&v.eat(le);)Pe++;var Ue=v.peek()||" ",et=!/\s/.test(Ue)&&(!w.test(Ue)||/\s/.test(_e)||w.test(_e)),we=!/\s/.test(_e)&&(!w.test(_e)||/\s/.test(Ue)||w.test(Ue)),Ie=null,E=null;if(Pe%2&&(!d.em&&et&&(le==="*"||!we||w.test(_e))?Ie=!0:d.em==le&&we&&(le==="*"||!et||w.test(Ue))&&(Ie=!1)),Pe>1&&(!d.strong&&et&&(le==="*"||!we||w.test(_e))?E=!0:d.strong==le&&we&&(le==="*"||!et||w.test(Ue))&&(E=!1)),E!=null||Ie!=null){_.highlightFormatting&&(d.formatting=Ie==null?"strong":E==null?"em":"strong em"),Ie===!0&&(d.em=le),E===!0&&(d.strong=le);var ve=P(d);return Ie===!1&&(d.em=!1),E===!1&&(d.strong=!1),ve}}else if(le===" "&&(v.eat("*")||v.eat("_"))){if(v.peek()===" ")return P(d);v.backUp(1)}if(_.strikethrough){if(le==="~"&&v.eatWhile(le)){if(d.strikethrough){_.highlightFormatting&&(d.formatting="strikethrough");var ve=P(d);return d.strikethrough=!1,ve}else if(v.match(/^[^\s]/,!1))return d.strikethrough=!0,_.highlightFormatting&&(d.formatting="strikethrough"),P(d)}else if(le===" "&&v.match("~~",!0)){if(v.peek()===" ")return P(d);v.backUp(2)}}if(_.emoji&&le===":"&&v.match(/^(?:[a-z_\d+][a-z_\d+-]*|\-[a-z_\d+][a-z_\d+-]*):/)){d.emoji=!0,_.highlightFormatting&&(d.formatting="emoji");var ee=P(d);return d.emoji=!1,ee}return le===" "&&(v.match(/^ +$/,!1)?d.trailingSpace++:d.trailingSpace&&(d.trailingSpaceNewLine=!0)),P(d)}function G(v,d){var fe=v.next();if(fe===">"){d.f=d.inline=F,_.highlightFormatting&&(d.formatting="link");var Te=P(d);return Te?Te+=" ":Te="",Te+k.linkInline}return v.match(/^[^>]+/,!0),k.linkInline}function c(v,d){if(v.eatSpace())return null;var fe=v.next();return fe==="("||fe==="["?(d.f=d.inline=C(fe==="("?")":"]"),_.highlightFormatting&&(d.formatting="link-string"),d.linkHref=!0,P(d)):"error"}var T={")":/^(?:[^\\\(\)]|\\.|\((?:[^\\\(\)]|\\.)*\))*?(?=\))/,"]":/^(?:[^\\\[\]]|\\.|\[(?:[^\\\[\]]|\\.)*\])*?(?=\])/};function C(v){return function(d,fe){var Te=d.next();if(Te===v){fe.f=fe.inline=F,_.highlightFormatting&&(fe.formatting="link-string");var le=P(fe);return fe.linkHref=!1,le}return d.match(T[v]),fe.linkHref=!0,P(fe)}}function g(v,d){return v.match(/^([^\]\\]|\\.)*\]:/,!1)?(d.f=y,v.next(),_.highlightFormatting&&(d.formatting="link"),d.linkText=!0,P(d)):N(v,d,F)}function y(v,d){if(v.match("]:",!0)){d.f=d.inline=j,_.highlightFormatting&&(d.formatting="link");var fe=P(d);return d.linkText=!1,fe}return v.match(/^([^\]\\]|\\.)+/,!0),k.linkText}function j(v,d){return v.eatSpace()?null:(v.match(/^[^\s]+/,!0),v.peek()===void 0?d.linkTitle=!0:v.match(/^(?:\s+(?:"(?:[^"\\]|\\.)+"|'(?:[^'\\]|\\.)+'|\((?:[^)\\]|\\.)+\)))?/,!0),d.f=d.inline=F,k.linkHref+" url")}var de={startState:function(){return{f:p,prevLine:{stream:null},thisLine:{stream:null},block:p,htmlState:null,indentation:0,inline:F,text:$,formatting:!1,linkText:!1,linkHref:!1,linkTitle:!1,code:0,em:!1,strong:!1,header:0,setext:0,hr:!1,taskList:!1,list:!1,listStack:[],quote:0,trailingSpace:0,trailingSpaceNewLine:!1,strikethrough:!1,emoji:!1,fencedEndRE:null}},copyState:function(v){return{f:v.f,prevLine:v.prevLine,thisLine:v.thisLine,block:v.block,htmlState:v.htmlState&&b.copyState(te,v.htmlState),indentation:v.indentation,localMode:v.localMode,localState:v.localMode?b.copyState(v.localMode,v.localState):null,inline:v.inline,text:v.text,formatting:!1,linkText:v.linkText,linkTitle:v.linkTitle,linkHref:v.linkHref,code:v.code,em:v.em,strong:v.strong,strikethrough:v.strikethrough,emoji:v.emoji,header:v.header,setext:v.setext,hr:v.hr,taskList:v.taskList,list:v.list,listStack:v.listStack.slice(0),quote:v.quote,indentedCode:v.indentedCode,trailingSpace:v.trailingSpace,trailingSpaceNewLine:v.trailingSpaceNewLine,md_inside:v.md_inside,fencedEndRE:v.fencedEndRE}},token:function(v,d){if(d.formatting=!1,v!=d.thisLine.stream){if(d.header=0,d.hr=!1,v.match(/^\s*$/,!0))return q(d),null;if(d.prevLine=d.thisLine,d.thisLine={stream:v},d.taskList=!1,d.trailingSpace=0,d.trailingSpaceNewLine=!1,!d.localState&&(d.f=d.block,d.f!=W)){var fe=v.match(/^\s*/,!0)[0].replace(/\t/g,M).length;if(d.indentation=fe,d.indentationDiff=null,fe>0)return null}}return d.f(v,d)},innerMode:function(v){return v.block==W?{state:v.htmlState,mode:te}:v.localState?{state:v.localState,mode:v.localMode}:{state:v,mode:de}},indent:function(v,d,fe){return v.block==W&&te.indent?te.indent(v.htmlState,d,fe):v.localState&&v.localMode.indent?v.localMode.indent(v.localState,d,fe):b.Pass},blankLine:q,getType:P,blockCommentStart:"",closeBrackets:"()[]{}''\"\"``",fold:"markdown"};return de},"xml"),b.defineMIME("text/markdown","markdown"),b.defineMIME("text/x-markdown","markdown")})})()),Da.exports}nf();var Na={exports:{}},Ea;function of(){return Ea||(Ea=1,(function(ct,xt){(function(b){b(mt())})(function(b){b.defineOption("placeholder","",function(I,Y,ne){var S=ne&&ne!=b.Init;if(Y&&!S)I.on("blur",oe),I.on("change",Q),I.on("swapDoc",Q),b.on(I.getInputField(),"compositionupdate",I.state.placeholderCompose=function(){te(I)}),Q(I);else if(!Y&&S){I.off("blur",oe),I.off("change",Q),I.off("swapDoc",Q),b.off(I.getInputField(),"compositionupdate",I.state.placeholderCompose),pe(I);var R=I.getWrapperElement();R.className=R.className.replace(" CodeMirror-empty","")}Y&&!I.hasFocus()&&oe(I)});function pe(I){I.state.placeholder&&(I.state.placeholder.parentNode.removeChild(I.state.placeholder),I.state.placeholder=null)}function _(I){pe(I);var Y=I.state.placeholder=document.createElement("pre");Y.style.cssText="height: 0; overflow: visible",Y.style.direction=I.getOption("direction"),Y.className="CodeMirror-placeholder CodeMirror-line-like";var ne=I.getOption("placeholder");typeof ne=="string"&&(ne=document.createTextNode(ne)),Y.appendChild(ne),I.display.lineSpace.insertBefore(Y,I.display.lineSpace.firstChild)}function te(I){setTimeout(function(){var Y=!1;if(I.lineCount()==1){var ne=I.getInputField();Y=ne.nodeName=="TEXTAREA"?!I.getLine(0).length:!/[^\u200b]/.test(ne.querySelector(".CodeMirror-line").textContent)}Y?_(I):pe(I)},20)}function oe(I){k(I)&&_(I)}function Q(I){var Y=I.getWrapperElement(),ne=k(I);Y.className=Y.className.replace(" CodeMirror-empty","")+(ne?" CodeMirror-empty":""),ne?_(I):pe(I)}function k(I){return I.lineCount()===1&&I.getLine(0)===""}})})()),Na.exports}of();var Oa={exports:{}},Pa;function lf(){return Pa||(Pa=1,(function(ct,xt){(function(b){b(mt())})(function(b){b.defineSimpleMode=function(S,R){b.defineMode(S,function(A){return b.simpleMode(A,R)})},b.simpleMode=function(S,R){pe(R,"start");var A={},V=R.meta||{},ue=!1;for(var O in R)if(O!=V&&R.hasOwnProperty(O))for(var w=A[O]=[],M=R[O],N=0;N2&&z.token&&typeof z.token!="string"){for(var p=2;p-1)return b.Pass;var O=A.indent.length-1,w=S[A.state];e:for(;;){for(var M=0;M",")":"(<","[":"]>","]":"[<","{":"}>","}":"{<","<":">>",">":"<<"};function oe(S){return S&&S.bracketRegex||/[(){}[\]]/}function Q(S,R,A){var V=S.getLineHandle(R.line),ue=R.ch-1,O=A&&A.afterCursor;O==null&&(O=/(^| )cm-fat-cursor($| )/.test(S.getWrapperElement().className));var w=oe(A),M=!O&&ue>=0&&w.test(V.text.charAt(ue))&&te[V.text.charAt(ue)]||w.test(V.text.charAt(ue+1))&&te[V.text.charAt(++ue)];if(!M)return null;var N=M.charAt(1)==">"?1:-1;if(A&&A.strict&&N>0!=(ue==R.ch))return null;var z=S.getTokenTypeAt(_(R.line,ue+1)),X=k(S,_(R.line,ue+(N>0?1:0)),N,z,A);return X==null?null:{from:_(R.line,ue),to:X&&X.pos,match:X&&X.ch==M.charAt(0),forward:N>0}}function k(S,R,A,V,ue){for(var O=ue&&ue.maxScanLineLength||1e4,w=ue&&ue.maxScanLines||1e3,M=[],N=oe(ue),z=A>0?Math.min(R.line+w,S.lastLine()+1):Math.max(S.firstLine()-1,R.line-w),X=R.line;X!=z;X+=A){var q=S.getLine(X);if(q){var p=A>0?0:q.length-1,W=A>0?q.length:-1;if(!(q.length>O))for(X==R.line&&(p=R.ch-(A<0?1:0));p!=W;p+=A){var J=q.charAt(p);if(N.test(J)&&(V===void 0||(S.getTokenTypeAt(_(X,p+1))||"")==(V||""))){var P=te[J];if(P&&P.charAt(1)==">"==A>0)M.push(J);else if(M.length)M.pop();else return{pos:_(X,p),ch:J}}}}}return X-A==(A>0?S.lastLine():S.firstLine())?!1:null}function I(S,R,A){for(var V=S.state.matchBrackets.maxHighlightLineLength||1e3,ue=A&&A.highlightNonMatching,O=[],w=S.listSelections(),M=0;M`,triples:"",explode:"[]{}"},_=b.Pos;b.defineOption("autoCloseBrackets",!1,function(O,w,M){M&&M!=b.Init&&(O.removeKeyMap(oe),O.state.closeBrackets=null),w&&(Q(te(w,"pairs")),O.state.closeBrackets=w,O.addKeyMap(oe))});function te(O,w){return w=="pairs"&&typeof O=="string"?O:typeof O=="object"&&O[w]!=null?O[w]:pe[w]}var oe={Backspace:Y,Enter:ne};function Q(O){for(var w=0;w=0;z--){var q=N[z].head;O.replaceRange("",_(q.line,q.ch-1),_(q.line,q.ch+1),"+delete")}}function ne(O){var w=I(O),M=w&&te(w,"explode");if(!M||O.getOption("disableInput"))return b.Pass;for(var N=O.listSelections(),z=0;z0?{line:q.head.line,ch:q.head.ch+w}:{line:q.head.line-1};M.push({anchor:p,head:p})}O.setSelections(M,z)}function R(O){var w=b.cmpPos(O.anchor,O.head)>0;return{anchor:new _(O.anchor.line,O.anchor.ch+(w?-1:1)),head:new _(O.head.line,O.head.ch+(w?1:-1))}}function A(O,w){var M=I(O);if(!M||O.getOption("disableInput"))return b.Pass;var N=te(M,"pairs"),z=N.indexOf(w);if(z==-1)return b.Pass;for(var X=te(M,"closeBefore"),q=te(M,"triples"),p=N.charAt(z+1)==w,W=O.listSelections(),J=z%2==0,P,$=0;$=0&&O.getRange(G,_(G.line,G.ch+3))==w+w+w?c="skipThree":c="skip";else if(p&&G.ch>1&&q.indexOf(w)>=0&&O.getRange(_(G.line,G.ch-2),G)==w+w){if(G.ch>2&&/\bstring/.test(O.getTokenTypeAt(_(G.line,G.ch-2))))return b.Pass;c="addFour"}else if(p){var C=G.ch==0?" ":O.getRange(_(G.line,G.ch-1),G);if(!b.isWordChar(T)&&C!=w&&!b.isWordChar(C))c="both";else return b.Pass}else if(J&&(T.length===0||/\s/.test(T)||X.indexOf(T)>-1))c="both";else return b.Pass;if(!P)P=c;else if(P!=c)return b.Pass}var g=z%2?N.charAt(z-1):w,y=z%2?w:N.charAt(z+1);O.operation(function(){if(P=="skip")S(O,1);else if(P=="skipThree")S(O,3);else if(P=="surround"){for(var j=O.getSelections(),de=0;dep);W++){var J=w.getLine(q++);z=z==null?J:z+` +`+J}X=X*2,M.lastIndex=N.ch;var P=M.exec(z);if(P){var $=z.slice(0,P.index).split(` +`),F=P[0].split(` +`),G=N.line+$.length-1,c=$[$.length-1].length;return{from:pe(G,c),to:pe(G+F.length-1,F.length==1?c+F[0].length:F[F.length-1].length),match:P}}}}function I(w,M,N){for(var z,X=0;X<=w.length;){M.lastIndex=X;var q=M.exec(w);if(!q)break;var p=q.index+q[0].length;if(p>w.length-N)break;(!z||p>z.index+z[0].length)&&(z=q),X=q.index+1}return z}function Y(w,M,N){M=te(M,"g");for(var z=N.line,X=N.ch,q=w.firstLine();z>=q;z--,X=-1){var p=w.getLine(z),W=I(p,M,X<0?0:p.length-X);if(W)return{from:pe(z,W.index),to:pe(z,W.index+W[0].length),match:W}}}function ne(w,M,N){if(!oe(M))return Y(w,M,N);M=te(M,"gm");for(var z,X=1,q=w.getLine(N.line).length-N.ch,p=N.line,W=w.firstLine();p>=W;){for(var J=0;J=W;J++){var P=w.getLine(p--);z=z==null?P:P+` +`+z}X*=2;var $=I(z,M,q);if($){var F=z.slice(0,$.index).split(` +`),G=$[0].split(` +`),c=p+F.length,T=F[F.length-1].length;return{from:pe(c,T),to:pe(c+G.length-1,G.length==1?T+G[0].length:G[G.length-1].length),match:$}}}}var S,R;String.prototype.normalize?(S=function(w){return w.normalize("NFD").toLowerCase()},R=function(w){return w.normalize("NFD")}):(S=function(w){return w.toLowerCase()},R=function(w){return w});function A(w,M,N,z){if(w.length==M.length)return N;for(var X=0,q=N+Math.max(0,w.length-M.length);;){if(X==q)return X;var p=X+q>>1,W=z(w.slice(0,p)).length;if(W==N)return p;W>N?q=p:X=p+1}}function V(w,M,N,z){if(!M.length)return null;var X=z?S:R,q=X(M).split(/\r|\n\r?/);e:for(var p=N.line,W=N.ch,J=w.lastLine()+1-q.length;p<=J;p++,W=0){var P=w.getLine(p).slice(W),$=X(P);if(q.length==1){var F=$.indexOf(q[0]);if(F==-1)continue e;var N=A(P,$,F,X)+W;return{from:pe(p,A(P,$,F,X)+W),to:pe(p,A(P,$,F+q[0].length,X)+W)}}else{var G=$.length-q[0].length;if($.slice(G)!=q[0])continue e;for(var c=1;c=J;p--,W=-1){var P=w.getLine(p);W>-1&&(P=P.slice(0,W));var $=X(P);if(q.length==1){var F=$.lastIndexOf(q[0]);if(F==-1)continue e;return{from:pe(p,A(P,$,F,X)),to:pe(p,A(P,$,F+q[0].length,X))}}else{var G=q[q.length-1];if($.slice(0,G.length)!=G)continue e;for(var c=1,N=p-q.length+1;c(this.doc.getLine(M.line)||"").length&&(M.ch=0,M.line++)),b.cmpPos(M,this.doc.clipPos(M))!=0))return this.atOccurrence=!1;var N=this.matches(w,M);if(this.afterEmptyMatch=N&&b.cmpPos(N.from,N.to)==0,N)return this.pos=N,this.atOccurrence=!0,this.pos.match||!0;var z=pe(w?this.doc.firstLine():this.doc.lastLine()+1,0);return this.pos={from:z,to:z},this.atOccurrence=!1},from:function(){if(this.atOccurrence)return this.pos.from},to:function(){if(this.atOccurrence)return this.pos.to},replace:function(w,M){if(this.atOccurrence){var N=b.splitLines(w);this.doc.replaceRange(N,this.pos.from,this.pos.to,M),this.pos.to=pe(this.pos.from.line+N.length-1,N[N.length-1].length+(N.length==1?this.pos.from.ch:0))}}},b.defineExtension("getSearchCursor",function(w,M,N){return new O(this.doc,w,M,N)}),b.defineDocExtension("getSearchCursor",function(w,M,N){return new O(this,w,M,N)}),b.defineExtension("selectMatches",function(w,M){for(var N=[],z=this.getSearchCursor(w,this.getCursor("from"),M);z.findNext()&&!(b.cmpPos(z.to(),this.getCursor("to"))>0);)N.push({anchor:z.from(),head:z.to()});N.length&&this.setSelections(N,0)})})})()),Ha.exports}var qa={exports:{}},ja;function po(){return ja||(ja=1,(function(ct,xt){(function(b){b(mt())})(function(b){function pe(te,oe,Q){var k=te.getWrapperElement(),I;return I=k.appendChild(document.createElement("div")),Q?I.className="CodeMirror-dialog CodeMirror-dialog-bottom":I.className="CodeMirror-dialog CodeMirror-dialog-top",typeof oe=="string"?I.innerHTML=oe:I.appendChild(oe),b.addClass(k,"dialog-opened"),I}function _(te,oe){te.state.currentNotificationClose&&te.state.currentNotificationClose(),te.state.currentNotificationClose=oe}b.defineExtension("openDialog",function(te,oe,Q){Q||(Q={}),_(this,null);var k=pe(this,te,Q.bottom),I=!1,Y=this;function ne(A){if(typeof A=="string")S.value=A;else{if(I)return;I=!0,b.rmClass(k.parentNode,"dialog-opened"),k.parentNode.removeChild(k),Y.focus(),Q.onClose&&Q.onClose(k)}}var S=k.getElementsByTagName("input")[0],R;return S?(S.focus(),Q.value&&(S.value=Q.value,Q.selectValueOnOpen!==!1&&S.select()),Q.onInput&&b.on(S,"input",function(A){Q.onInput(A,S.value,ne)}),Q.onKeyUp&&b.on(S,"keyup",function(A){Q.onKeyUp(A,S.value,ne)}),b.on(S,"keydown",function(A){Q&&Q.onKeyDown&&Q.onKeyDown(A,S.value,ne)||((A.keyCode==27||Q.closeOnEnter!==!1&&A.keyCode==13)&&(S.blur(),b.e_stop(A),ne()),A.keyCode==13&&oe(S.value,A))}),Q.closeOnBlur!==!1&&b.on(k,"focusout",function(A){A.relatedTarget!==null&&ne()})):(R=k.getElementsByTagName("button")[0])&&(b.on(R,"click",function(){ne(),Y.focus()}),Q.closeOnBlur!==!1&&b.on(R,"blur",ne),R.focus()),ne}),b.defineExtension("openConfirm",function(te,oe,Q){_(this,null);var k=pe(this,te,Q&&Q.bottom),I=k.getElementsByTagName("button"),Y=!1,ne=this,S=1;function R(){Y||(Y=!0,b.rmClass(k.parentNode,"dialog-opened"),k.parentNode.removeChild(k),ne.focus())}I[0].focus();for(var A=0;Ap.cursorCoords(y,"window").top&&((G=j).style.opacity=.4)}))};k(p,w(p),F,c,function(T,C){var g=b.keyName(T),y=p.getOption("extraKeys"),j=y&&y[g]||b.keyMap[p.getOption("keyMap")][g];j=="findNext"||j=="findPrev"||j=="findPersistentNext"||j=="findPersistentPrev"?(b.e_stop(T),R(p,te(p),C),p.execCommand(j)):(j=="find"||j=="findPersistent")&&(b.e_stop(T),c(C,T))}),P&&F&&(R(p,$,F),V(p,W))}else I(p,w(p),"Search for:",F,function(T){T&&!$.query&&p.operation(function(){R(p,$,T),$.posFrom=$.posTo=p.getCursor(),V(p,W)})})}function V(p,W,J){p.operation(function(){var P=te(p),$=Q(p,P.query,W?P.posFrom:P.posTo);!$.find(W)&&($=Q(p,P.query,W?b.Pos(p.lastLine()):b.Pos(p.firstLine(),0)),!$.find(W))||(p.setSelection($.from(),$.to()),p.scrollIntoView({from:$.from(),to:$.to()},20),P.posFrom=$.from(),P.posTo=$.to(),J&&J($.from(),$.to()))})}function ue(p){p.operation(function(){var W=te(p);W.lastQuery=W.query,W.query&&(W.query=W.queryText=null,p.removeOverlay(W.overlay),W.annotate&&(W.annotate.clear(),W.annotate=null))})}function O(p,W){var J=p?document.createElement(p):document.createDocumentFragment();for(var P in W)J[P]=W[P];for(var $=2;$ '+oe.phrase("(Use line:column or scroll% syntax)")+""}function te(oe,Q){var k=Number(Q);return/^[-+]/.test(Q)?oe.getCursor().line+k:k-1}b.commands.jumpToLine=function(oe){var Q=oe.getCursor();pe(oe,_(oe),oe.phrase("Jump to line:"),Q.line+1+":"+Q.ch,function(k){if(k){var I;if(I=/^\s*([\+\-]?\d+)\s*\:\s*(\d+)\s*$/.exec(k))oe.setCursor(te(oe,I[1]),Number(I[2]));else if(I=/^\s*([\+\-]?\d+(\.\d+)?)\%\s*/.exec(k)){var Y=Math.round(oe.lineCount()*Number(I[1])/100);/^[-+]/.test(I[1])&&(Y=Q.line+Y+1),oe.setCursor(Y-1,Q.ch)}else(I=/^\s*\:?\s*([\+\-]?\d+)\s*/.exec(k))&&oe.setCursor(te(oe,I[1]),Q.ch)}})},b.keyMap.default["Alt-G"]="jumpToLine"})})()),Ua.exports}ff();po();export{df as default}; diff --git a/skills/playwright-scraper-skill-1-2-0/node_modules/playwright-core/lib/vite/recorder/assets/codicon-DCmgc-ay.ttf b/skills/playwright-scraper-skill-1-2-0/node_modules/playwright-core/lib/vite/recorder/assets/codicon-DCmgc-ay.ttf new file mode 100644 index 0000000..27ee4c6 Binary files /dev/null and b/skills/playwright-scraper-skill-1-2-0/node_modules/playwright-core/lib/vite/recorder/assets/codicon-DCmgc-ay.ttf differ diff --git a/skills/playwright-scraper-skill-1-2-0/node_modules/playwright-core/lib/vite/recorder/assets/index-BSjZa4pk.css b/skills/playwright-scraper-skill-1-2-0/node_modules/playwright-core/lib/vite/recorder/assets/index-BSjZa4pk.css new file mode 100644 index 0000000..acc7881 --- /dev/null +++ b/skills/playwright-scraper-skill-1-2-0/node_modules/playwright-core/lib/vite/recorder/assets/index-BSjZa4pk.css @@ -0,0 +1 @@ +:root{color-scheme:light dark}body{--transparent-blue: #2196F355;--light-pink: #ff69b460;--gray: #888888;--sidebar-width: 250px;--box-shadow: rgba(0, 0, 0, .133) 0px 1.6px 3.6px 0px, rgba(0, 0, 0, .11) 0px .3px .9px 0px}html,body{width:100%;height:100%;padding:0;margin:0;overflow:hidden;display:flex;overscroll-behavior-x:none}#root{width:100%;height:100%;display:flex}body,dialog{background-color:var(--vscode-panel-background);color:var(--vscode-foreground);font-family:var(--vscode-font-family);font-weight:var(--vscode-font-weight);font-size:var(--vscode-font-size);-webkit-font-smoothing:antialiased}a{color:var(--vscode-textLink-foreground)}dialog{border:none;padding:0;box-shadow:var(--box-shadow);line-height:28px;max-width:400px}dialog .title{display:flex;align-items:center;margin:0;padding:0 5px;height:32px;background-color:var(--vscode-sideBar-background);max-width:400px}dialog .title .codicon{margin-right:3px}dialog .body{padding:10px;text-align:center}.button{color:var(--vscode-button-foreground);background:var(--vscode-button-background);margin:10px;border:none;height:28px;min-width:40px;cursor:pointer;-webkit-user-select:none;user-select:none}.button:focus{outline:1px solid var(--vscode-focusBorder)}.button:hover{background:var(--vscode-button-hoverBackground)}.button.secondary{color:var(--vscode-button-secondaryForeground);background:var(--vscode-button-secondaryBackground)}.button.secondary:hover{background:var(--vscode-button-secondaryHoverBackground)}*{box-sizing:border-box;min-width:0;min-height:0}*[hidden],.hidden{display:none!important}.invisible{visibility:hidden!important}svg{fill:currentColor}.vbox{display:flex;flex-direction:column;flex:auto;position:relative}.fill{position:absolute;top:0;right:0;bottom:0;left:0}.hbox{display:flex;flex:auto;position:relative}.spacer{flex:auto}.codicon-check{color:var(--vscode-charts-green)}.codicon-error{color:var(--vscode-errorForeground)}.codicon-warning{color:var(--vscode-list-warningForeground)}.codicon-circle-outline{color:var(--vscode-disabledForeground)}input[type=text],input[type=search]{color:var(--vscode-input-foreground);background-color:var(--vscode-input-background);border:none;outline:none}.codicon-loading{animation:spin 1s infinite linear}::placeholder{color:var(--vscode-input-placeholderForeground)}@keyframes spin{to{transform:rotate(360deg)}}@font-face{font-family:codicon;src:url(/assets/codicon-DCmgc-ay.ttf) format("truetype")}.codicon{font: 16px/1 codicon;flex:none;display:inline-block;text-decoration:none;text-rendering:auto;text-align:center;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.codicon-add:before{content:""}.codicon-plus:before{content:""}.codicon-gist-new:before{content:""}.codicon-repo-create:before{content:""}.codicon-lightbulb:before{content:""}.codicon-light-bulb:before{content:""}.codicon-repo:before{content:""}.codicon-repo-delete:before{content:""}.codicon-gist-fork:before{content:""}.codicon-repo-forked:before{content:""}.codicon-git-pull-request:before{content:""}.codicon-git-pull-request-abandoned:before{content:""}.codicon-record-keys:before{content:""}.codicon-keyboard:before{content:""}.codicon-tag:before{content:""}.codicon-git-pull-request-label:before{content:""}.codicon-tag-add:before{content:""}.codicon-tag-remove:before{content:""}.codicon-person:before{content:""}.codicon-person-follow:before{content:""}.codicon-person-outline:before{content:""}.codicon-person-filled:before{content:""}.codicon-git-branch:before{content:""}.codicon-git-branch-create:before{content:""}.codicon-git-branch-delete:before{content:""}.codicon-source-control:before{content:""}.codicon-mirror:before{content:""}.codicon-mirror-public:before{content:""}.codicon-star:before{content:""}.codicon-star-add:before{content:""}.codicon-star-delete:before{content:""}.codicon-star-empty:before{content:""}.codicon-comment:before{content:""}.codicon-comment-add:before{content:""}.codicon-alert:before{content:""}.codicon-warning:before{content:""}.codicon-search:before{content:""}.codicon-search-save:before{content:""}.codicon-log-out:before{content:""}.codicon-sign-out:before{content:""}.codicon-log-in:before{content:""}.codicon-sign-in:before{content:""}.codicon-eye:before{content:""}.codicon-eye-unwatch:before{content:""}.codicon-eye-watch:before{content:""}.codicon-circle-filled:before{content:""}.codicon-primitive-dot:before{content:""}.codicon-close-dirty:before{content:""}.codicon-debug-breakpoint:before{content:""}.codicon-debug-breakpoint-disabled:before{content:""}.codicon-debug-hint:before{content:""}.codicon-terminal-decoration-success:before{content:""}.codicon-primitive-square:before{content:""}.codicon-edit:before{content:""}.codicon-pencil:before{content:""}.codicon-info:before{content:""}.codicon-issue-opened:before{content:""}.codicon-gist-private:before{content:""}.codicon-git-fork-private:before{content:""}.codicon-lock:before{content:""}.codicon-mirror-private:before{content:""}.codicon-close:before{content:""}.codicon-remove-close:before{content:""}.codicon-x:before{content:""}.codicon-repo-sync:before{content:""}.codicon-sync:before{content:""}.codicon-clone:before{content:""}.codicon-desktop-download:before{content:""}.codicon-beaker:before{content:""}.codicon-microscope:before{content:""}.codicon-vm:before{content:""}.codicon-device-desktop:before{content:""}.codicon-file:before{content:""}.codicon-file-text:before{content:""}.codicon-more:before{content:""}.codicon-ellipsis:before{content:""}.codicon-kebab-horizontal:before{content:""}.codicon-mail-reply:before{content:""}.codicon-reply:before{content:""}.codicon-organization:before{content:""}.codicon-organization-filled:before{content:""}.codicon-organization-outline:before{content:""}.codicon-new-file:before{content:""}.codicon-file-add:before{content:""}.codicon-new-folder:before{content:""}.codicon-file-directory-create:before{content:""}.codicon-trash:before{content:""}.codicon-trashcan:before{content:""}.codicon-history:before{content:""}.codicon-clock:before{content:""}.codicon-folder:before{content:""}.codicon-file-directory:before{content:""}.codicon-symbol-folder:before{content:""}.codicon-logo-github:before{content:""}.codicon-mark-github:before{content:""}.codicon-github:before{content:""}.codicon-terminal:before{content:""}.codicon-console:before{content:""}.codicon-repl:before{content:""}.codicon-zap:before{content:""}.codicon-symbol-event:before{content:""}.codicon-error:before{content:""}.codicon-stop:before{content:""}.codicon-variable:before{content:""}.codicon-symbol-variable:before{content:""}.codicon-array:before{content:""}.codicon-symbol-array:before{content:""}.codicon-symbol-module:before{content:""}.codicon-symbol-package:before{content:""}.codicon-symbol-namespace:before{content:""}.codicon-symbol-object:before{content:""}.codicon-symbol-method:before{content:""}.codicon-symbol-function:before{content:""}.codicon-symbol-constructor:before{content:""}.codicon-symbol-boolean:before{content:""}.codicon-symbol-null:before{content:""}.codicon-symbol-numeric:before{content:""}.codicon-symbol-number:before{content:""}.codicon-symbol-structure:before{content:""}.codicon-symbol-struct:before{content:""}.codicon-symbol-parameter:before{content:""}.codicon-symbol-type-parameter:before{content:""}.codicon-symbol-key:before{content:""}.codicon-symbol-text:before{content:""}.codicon-symbol-reference:before{content:""}.codicon-go-to-file:before{content:""}.codicon-symbol-enum:before{content:""}.codicon-symbol-value:before{content:""}.codicon-symbol-ruler:before{content:""}.codicon-symbol-unit:before{content:""}.codicon-activate-breakpoints:before{content:""}.codicon-archive:before{content:""}.codicon-arrow-both:before{content:""}.codicon-arrow-down:before{content:""}.codicon-arrow-left:before{content:""}.codicon-arrow-right:before{content:""}.codicon-arrow-small-down:before{content:""}.codicon-arrow-small-left:before{content:""}.codicon-arrow-small-right:before{content:""}.codicon-arrow-small-up:before{content:""}.codicon-arrow-up:before{content:""}.codicon-bell:before{content:""}.codicon-bold:before{content:""}.codicon-book:before{content:""}.codicon-bookmark:before{content:""}.codicon-debug-breakpoint-conditional-unverified:before{content:""}.codicon-debug-breakpoint-conditional:before{content:""}.codicon-debug-breakpoint-conditional-disabled:before{content:""}.codicon-debug-breakpoint-data-unverified:before{content:""}.codicon-debug-breakpoint-data:before{content:""}.codicon-debug-breakpoint-data-disabled:before{content:""}.codicon-debug-breakpoint-log-unverified:before{content:""}.codicon-debug-breakpoint-log:before{content:""}.codicon-debug-breakpoint-log-disabled:before{content:""}.codicon-briefcase:before{content:""}.codicon-broadcast:before{content:""}.codicon-browser:before{content:""}.codicon-bug:before{content:""}.codicon-calendar:before{content:""}.codicon-case-sensitive:before{content:""}.codicon-check:before{content:""}.codicon-checklist:before{content:""}.codicon-chevron-down:before{content:""}.codicon-chevron-left:before{content:""}.codicon-chevron-right:before{content:""}.codicon-chevron-up:before{content:""}.codicon-chrome-close:before{content:""}.codicon-chrome-maximize:before{content:""}.codicon-chrome-minimize:before{content:""}.codicon-chrome-restore:before{content:""}.codicon-circle-outline:before{content:""}.codicon-circle:before{content:""}.codicon-debug-breakpoint-unverified:before{content:""}.codicon-terminal-decoration-incomplete:before{content:""}.codicon-circle-slash:before{content:""}.codicon-circuit-board:before{content:""}.codicon-clear-all:before{content:""}.codicon-clippy:before{content:""}.codicon-close-all:before{content:""}.codicon-cloud-download:before{content:""}.codicon-cloud-upload:before{content:""}.codicon-code:before{content:""}.codicon-collapse-all:before{content:""}.codicon-color-mode:before{content:""}.codicon-comment-discussion:before{content:""}.codicon-credit-card:before{content:""}.codicon-dash:before{content:""}.codicon-dashboard:before{content:""}.codicon-database:before{content:""}.codicon-debug-continue:before{content:""}.codicon-debug-disconnect:before{content:""}.codicon-debug-pause:before{content:""}.codicon-debug-restart:before{content:""}.codicon-debug-start:before{content:""}.codicon-debug-step-into:before{content:""}.codicon-debug-step-out:before{content:""}.codicon-debug-step-over:before{content:""}.codicon-debug-stop:before{content:""}.codicon-debug:before{content:""}.codicon-device-camera-video:before{content:""}.codicon-device-camera:before{content:""}.codicon-device-mobile:before{content:""}.codicon-diff-added:before{content:""}.codicon-diff-ignored:before{content:""}.codicon-diff-modified:before{content:""}.codicon-diff-removed:before{content:""}.codicon-diff-renamed:before{content:""}.codicon-diff:before{content:""}.codicon-diff-sidebyside:before{content:""}.codicon-discard:before{content:""}.codicon-editor-layout:before{content:""}.codicon-empty-window:before{content:""}.codicon-exclude:before{content:""}.codicon-extensions:before{content:""}.codicon-eye-closed:before{content:""}.codicon-file-binary:before{content:""}.codicon-file-code:before{content:""}.codicon-file-media:before{content:""}.codicon-file-pdf:before{content:""}.codicon-file-submodule:before{content:""}.codicon-file-symlink-directory:before{content:""}.codicon-file-symlink-file:before{content:""}.codicon-file-zip:before{content:""}.codicon-files:before{content:""}.codicon-filter:before{content:""}.codicon-flame:before{content:""}.codicon-fold-down:before{content:""}.codicon-fold-up:before{content:""}.codicon-fold:before{content:""}.codicon-folder-active:before{content:""}.codicon-folder-opened:before{content:""}.codicon-gear:before{content:""}.codicon-gift:before{content:""}.codicon-gist-secret:before{content:""}.codicon-gist:before{content:""}.codicon-git-commit:before{content:""}.codicon-git-compare:before{content:""}.codicon-compare-changes:before{content:""}.codicon-git-merge:before{content:""}.codicon-github-action:before{content:""}.codicon-github-alt:before{content:""}.codicon-globe:before{content:""}.codicon-grabber:before{content:""}.codicon-graph:before{content:""}.codicon-gripper:before{content:""}.codicon-heart:before{content:""}.codicon-home:before{content:""}.codicon-horizontal-rule:before{content:""}.codicon-hubot:before{content:""}.codicon-inbox:before{content:""}.codicon-issue-reopened:before{content:""}.codicon-issues:before{content:""}.codicon-italic:before{content:""}.codicon-jersey:before{content:""}.codicon-json:before{content:""}.codicon-kebab-vertical:before{content:""}.codicon-key:before{content:""}.codicon-law:before{content:""}.codicon-lightbulb-autofix:before{content:""}.codicon-link-external:before{content:""}.codicon-link:before{content:""}.codicon-list-ordered:before{content:""}.codicon-list-unordered:before{content:""}.codicon-live-share:before{content:""}.codicon-loading:before{content:""}.codicon-location:before{content:""}.codicon-mail-read:before{content:""}.codicon-mail:before{content:""}.codicon-markdown:before{content:""}.codicon-megaphone:before{content:""}.codicon-mention:before{content:""}.codicon-milestone:before{content:""}.codicon-git-pull-request-milestone:before{content:""}.codicon-mortar-board:before{content:""}.codicon-move:before{content:""}.codicon-multiple-windows:before{content:""}.codicon-mute:before{content:""}.codicon-no-newline:before{content:""}.codicon-note:before{content:""}.codicon-octoface:before{content:""}.codicon-open-preview:before{content:""}.codicon-package:before{content:""}.codicon-paintcan:before{content:""}.codicon-pin:before{content:""}.codicon-play:before{content:""}.codicon-run:before{content:""}.codicon-plug:before{content:""}.codicon-preserve-case:before{content:""}.codicon-preview:before{content:""}.codicon-project:before{content:""}.codicon-pulse:before{content:""}.codicon-question:before{content:""}.codicon-quote:before{content:""}.codicon-radio-tower:before{content:""}.codicon-reactions:before{content:""}.codicon-references:before{content:""}.codicon-refresh:before{content:""}.codicon-regex:before{content:""}.codicon-remote-explorer:before{content:""}.codicon-remote:before{content:""}.codicon-remove:before{content:""}.codicon-replace-all:before{content:""}.codicon-replace:before{content:""}.codicon-repo-clone:before{content:""}.codicon-repo-force-push:before{content:""}.codicon-repo-pull:before{content:""}.codicon-repo-push:before{content:""}.codicon-report:before{content:""}.codicon-request-changes:before{content:""}.codicon-rocket:before{content:""}.codicon-root-folder-opened:before{content:""}.codicon-root-folder:before{content:""}.codicon-rss:before{content:""}.codicon-ruby:before{content:""}.codicon-save-all:before{content:""}.codicon-save-as:before{content:""}.codicon-save:before{content:""}.codicon-screen-full:before{content:""}.codicon-screen-normal:before{content:""}.codicon-search-stop:before{content:""}.codicon-server:before{content:""}.codicon-settings-gear:before{content:""}.codicon-settings:before{content:""}.codicon-shield:before{content:""}.codicon-smiley:before{content:""}.codicon-sort-precedence:before{content:""}.codicon-split-horizontal:before{content:""}.codicon-split-vertical:before{content:""}.codicon-squirrel:before{content:""}.codicon-star-full:before{content:""}.codicon-star-half:before{content:""}.codicon-symbol-class:before{content:""}.codicon-symbol-color:before{content:""}.codicon-symbol-constant:before{content:""}.codicon-symbol-enum-member:before{content:""}.codicon-symbol-field:before{content:""}.codicon-symbol-file:before{content:""}.codicon-symbol-interface:before{content:""}.codicon-symbol-keyword:before{content:""}.codicon-symbol-misc:before{content:""}.codicon-symbol-operator:before{content:""}.codicon-symbol-property:before{content:""}.codicon-wrench:before{content:""}.codicon-wrench-subaction:before{content:""}.codicon-symbol-snippet:before{content:""}.codicon-tasklist:before{content:""}.codicon-telescope:before{content:""}.codicon-text-size:before{content:""}.codicon-three-bars:before{content:""}.codicon-thumbsdown:before{content:""}.codicon-thumbsup:before{content:""}.codicon-tools:before{content:""}.codicon-triangle-down:before{content:""}.codicon-triangle-left:before{content:""}.codicon-triangle-right:before{content:""}.codicon-triangle-up:before{content:""}.codicon-twitter:before{content:""}.codicon-unfold:before{content:""}.codicon-unlock:before{content:""}.codicon-unmute:before{content:""}.codicon-unverified:before{content:""}.codicon-verified:before{content:""}.codicon-versions:before{content:""}.codicon-vm-active:before{content:""}.codicon-vm-outline:before{content:""}.codicon-vm-running:before{content:""}.codicon-watch:before{content:""}.codicon-whitespace:before{content:""}.codicon-whole-word:before{content:""}.codicon-window:before{content:""}.codicon-word-wrap:before{content:""}.codicon-zoom-in:before{content:""}.codicon-zoom-out:before{content:""}.codicon-list-filter:before{content:""}.codicon-list-flat:before{content:""}.codicon-list-selection:before{content:""}.codicon-selection:before{content:""}.codicon-list-tree:before{content:""}.codicon-debug-breakpoint-function-unverified:before{content:""}.codicon-debug-breakpoint-function:before{content:""}.codicon-debug-breakpoint-function-disabled:before{content:""}.codicon-debug-stackframe-active:before{content:""}.codicon-circle-small-filled:before{content:""}.codicon-debug-stackframe-dot:before{content:""}.codicon-terminal-decoration-mark:before{content:""}.codicon-debug-stackframe:before{content:""}.codicon-debug-stackframe-focused:before{content:""}.codicon-debug-breakpoint-unsupported:before{content:""}.codicon-symbol-string:before{content:""}.codicon-debug-reverse-continue:before{content:""}.codicon-debug-step-back:before{content:""}.codicon-debug-restart-frame:before{content:""}.codicon-debug-alt:before{content:""}.codicon-call-incoming:before{content:""}.codicon-call-outgoing:before{content:""}.codicon-menu:before{content:""}.codicon-expand-all:before{content:""}.codicon-feedback:before{content:""}.codicon-git-pull-request-reviewer:before{content:""}.codicon-group-by-ref-type:before{content:""}.codicon-ungroup-by-ref-type:before{content:""}.codicon-account:before{content:""}.codicon-git-pull-request-assignee:before{content:""}.codicon-bell-dot:before{content:""}.codicon-debug-console:before{content:""}.codicon-library:before{content:""}.codicon-output:before{content:""}.codicon-run-all:before{content:""}.codicon-sync-ignored:before{content:""}.codicon-pinned:before{content:""}.codicon-github-inverted:before{content:""}.codicon-server-process:before{content:""}.codicon-server-environment:before{content:""}.codicon-pass:before{content:""}.codicon-issue-closed:before{content:""}.codicon-stop-circle:before{content:""}.codicon-play-circle:before{content:""}.codicon-record:before{content:""}.codicon-debug-alt-small:before{content:""}.codicon-vm-connect:before{content:""}.codicon-cloud:before{content:""}.codicon-merge:before{content:""}.codicon-export:before{content:""}.codicon-graph-left:before{content:""}.codicon-magnet:before{content:""}.codicon-notebook:before{content:""}.codicon-redo:before{content:""}.codicon-check-all:before{content:""}.codicon-pinned-dirty:before{content:""}.codicon-pass-filled:before{content:""}.codicon-circle-large-filled:before{content:""}.codicon-circle-large:before{content:""}.codicon-circle-large-outline:before{content:""}.codicon-combine:before{content:""}.codicon-gather:before{content:""}.codicon-table:before{content:""}.codicon-variable-group:before{content:""}.codicon-type-hierarchy:before{content:""}.codicon-type-hierarchy-sub:before{content:""}.codicon-type-hierarchy-super:before{content:""}.codicon-git-pull-request-create:before{content:""}.codicon-run-above:before{content:""}.codicon-run-below:before{content:""}.codicon-notebook-template:before{content:""}.codicon-debug-rerun:before{content:""}.codicon-workspace-trusted:before{content:""}.codicon-workspace-untrusted:before{content:""}.codicon-workspace-unknown:before{content:""}.codicon-terminal-cmd:before{content:""}.codicon-terminal-debian:before{content:""}.codicon-terminal-linux:before{content:""}.codicon-terminal-powershell:before{content:""}.codicon-terminal-tmux:before{content:""}.codicon-terminal-ubuntu:before{content:""}.codicon-terminal-bash:before{content:""}.codicon-arrow-swap:before{content:""}.codicon-copy:before{content:""}.codicon-person-add:before{content:""}.codicon-filter-filled:before{content:""}.codicon-wand:before{content:""}.codicon-debug-line-by-line:before{content:""}.codicon-inspect:before{content:""}.codicon-layers:before{content:""}.codicon-layers-dot:before{content:""}.codicon-layers-active:before{content:""}.codicon-compass:before{content:""}.codicon-compass-dot:before{content:""}.codicon-compass-active:before{content:""}.codicon-azure:before{content:""}.codicon-issue-draft:before{content:""}.codicon-git-pull-request-closed:before{content:""}.codicon-git-pull-request-draft:before{content:""}.codicon-debug-all:before{content:""}.codicon-debug-coverage:before{content:""}.codicon-run-errors:before{content:""}.codicon-folder-library:before{content:""}.codicon-debug-continue-small:before{content:""}.codicon-beaker-stop:before{content:""}.codicon-graph-line:before{content:""}.codicon-graph-scatter:before{content:""}.codicon-pie-chart:before{content:""}.codicon-bracket:before{content:""}.codicon-bracket-dot:before{content:""}.codicon-bracket-error:before{content:""}.codicon-lock-small:before{content:""}.codicon-azure-devops:before{content:""}.codicon-verified-filled:before{content:""}.codicon-newline:before{content:""}.codicon-layout:before{content:""}.codicon-layout-activitybar-left:before{content:""}.codicon-layout-activitybar-right:before{content:""}.codicon-layout-panel-left:before{content:""}.codicon-layout-panel-center:before{content:""}.codicon-layout-panel-justify:before{content:""}.codicon-layout-panel-right:before{content:""}.codicon-layout-panel:before{content:""}.codicon-layout-sidebar-left:before{content:""}.codicon-layout-sidebar-right:before{content:""}.codicon-layout-statusbar:before{content:""}.codicon-layout-menubar:before{content:""}.codicon-layout-centered:before{content:""}.codicon-target:before{content:""}.codicon-indent:before{content:""}.codicon-record-small:before{content:""}.codicon-error-small:before{content:""}.codicon-terminal-decoration-error:before{content:""}.codicon-arrow-circle-down:before{content:""}.codicon-arrow-circle-left:before{content:""}.codicon-arrow-circle-right:before{content:""}.codicon-arrow-circle-up:before{content:""}.codicon-layout-sidebar-right-off:before{content:""}.codicon-layout-panel-off:before{content:""}.codicon-layout-sidebar-left-off:before{content:""}.codicon-blank:before{content:""}.codicon-heart-filled:before{content:""}.codicon-map:before{content:""}.codicon-map-horizontal:before{content:""}.codicon-fold-horizontal:before{content:""}.codicon-map-filled:before{content:""}.codicon-map-horizontal-filled:before{content:""}.codicon-fold-horizontal-filled:before{content:""}.codicon-circle-small:before{content:""}.codicon-bell-slash:before{content:""}.codicon-bell-slash-dot:before{content:""}.codicon-comment-unresolved:before{content:""}.codicon-git-pull-request-go-to-changes:before{content:""}.codicon-git-pull-request-new-changes:before{content:""}.codicon-search-fuzzy:before{content:""}.codicon-comment-draft:before{content:""}.codicon-send:before{content:""}.codicon-sparkle:before{content:""}.codicon-insert:before{content:""}.codicon-mic:before{content:""}.codicon-thumbsdown-filled:before{content:""}.codicon-thumbsup-filled:before{content:""}.codicon-coffee:before{content:""}.codicon-snake:before{content:""}.codicon-game:before{content:""}.codicon-vr:before{content:""}.codicon-chip:before{content:""}.codicon-piano:before{content:""}.codicon-music:before{content:""}.codicon-mic-filled:before{content:""}.codicon-repo-fetch:before{content:""}.codicon-copilot:before{content:""}.codicon-lightbulb-sparkle:before{content:""}.codicon-robot:before{content:""}.codicon-sparkle-filled:before{content:""}.codicon-diff-single:before{content:""}.codicon-diff-multiple:before{content:""}.codicon-surround-with:before{content:""}.codicon-share:before{content:""}.codicon-git-stash:before{content:""}.codicon-git-stash-apply:before{content:""}.codicon-git-stash-pop:before{content:""}.codicon-vscode:before{content:""}.codicon-vscode-insiders:before{content:""}.codicon-code-oss:before{content:""}.codicon-run-coverage:before{content:""}.codicon-run-all-coverage:before{content:""}.codicon-coverage:before{content:""}.codicon-github-project:before{content:""}.codicon-map-vertical:before{content:""}.codicon-fold-vertical:before{content:""}.codicon-map-vertical-filled:before{content:""}.codicon-fold-vertical-filled:before{content:""}.codicon-go-to-search:before{content:""}.codicon-percentage:before{content:""}.codicon-sort-percentage:before{content:""}.codicon-attach:before{content:""}.codicon-git-fetch:before{content:""}:root{--vscode-font-family: system-ui, "Ubuntu", "Droid Sans", sans-serif;--vscode-font-weight: normal;--vscode-font-size: 13px;--vscode-editor-font-family: "Droid Sans Mono", "monospace", monospace;--vscode-editor-font-weight: normal;--vscode-editor-font-size: 14px;--vscode-foreground: #616161;--vscode-disabledForeground: rgba(97, 97, 97, .5);--vscode-errorForeground: #a1260d;--vscode-descriptionForeground: #717171;--vscode-icon-foreground: #424242;--vscode-focusBorder: #0090f1;--vscode-textSeparator-foreground: rgba(0, 0, 0, .18);--vscode-textLink-foreground: #006ab1;--vscode-textLink-activeForeground: #006ab1;--vscode-textPreformat-foreground: #a31515;--vscode-textBlockQuote-background: rgba(127, 127, 127, .1);--vscode-textBlockQuote-border: rgba(0, 122, 204, .5);--vscode-textCodeBlock-background: rgba(220, 220, 220, .4);--vscode-widget-shadow: rgba(0, 0, 0, .16);--vscode-input-background: #ffffff;--vscode-input-foreground: #616161;--vscode-inputOption-activeBorder: #007acc;--vscode-inputOption-hoverBackground: rgba(184, 184, 184, .31);--vscode-inputOption-activeBackground: rgba(0, 144, 241, .2);--vscode-inputOption-activeForeground: #000000;--vscode-input-placeholderForeground: #767676;--vscode-inputValidation-infoBackground: #d6ecf2;--vscode-inputValidation-infoBorder: #007acc;--vscode-inputValidation-warningBackground: #f6f5d2;--vscode-inputValidation-warningBorder: #b89500;--vscode-inputValidation-errorBackground: #f2dede;--vscode-inputValidation-errorBorder: #be1100;--vscode-dropdown-background: #ffffff;--vscode-dropdown-border: #cecece;--vscode-checkbox-background: #ffffff;--vscode-checkbox-border: #cecece;--vscode-button-foreground: #ffffff;--vscode-button-separator: rgba(255, 255, 255, .4);--vscode-button-background: #007acc;--vscode-button-hoverBackground: #0062a3;--vscode-button-secondaryForeground: #ffffff;--vscode-button-secondaryBackground: #5f6a79;--vscode-button-secondaryHoverBackground: #4c5561;--vscode-badge-background: #c4c4c4;--vscode-badge-foreground: #333333;--vscode-scrollbar-shadow: #dddddd;--vscode-scrollbarSlider-background: rgba(100, 100, 100, .4);--vscode-scrollbarSlider-hoverBackground: rgba(100, 100, 100, .7);--vscode-scrollbarSlider-activeBackground: rgba(0, 0, 0, .6);--vscode-progressBar-background: #0e70c0;--vscode-editorError-foreground: #e51400;--vscode-editorWarning-foreground: #bf8803;--vscode-editorInfo-foreground: #1a85ff;--vscode-editorHint-foreground: #6c6c6c;--vscode-sash-hoverBorder: #0090f1;--vscode-editor-background: #ffffff;--vscode-editor-foreground: #000000;--vscode-editorStickyScroll-background: #ffffff;--vscode-editorStickyScrollHover-background: #f0f0f0;--vscode-editorWidget-background: #f3f3f3;--vscode-editorWidget-foreground: #616161;--vscode-editorWidget-border: #c8c8c8;--vscode-quickInput-background: #f3f3f3;--vscode-quickInput-foreground: #616161;--vscode-quickInputTitle-background: rgba(0, 0, 0, .06);--vscode-pickerGroup-foreground: #0066bf;--vscode-pickerGroup-border: #cccedb;--vscode-keybindingLabel-background: rgba(221, 221, 221, .4);--vscode-keybindingLabel-foreground: #555555;--vscode-keybindingLabel-border: rgba(204, 204, 204, .4);--vscode-keybindingLabel-bottomBorder: rgba(187, 187, 187, .4);--vscode-editor-selectionBackground: #add6ff;--vscode-editor-inactiveSelectionBackground: #e5ebf1;--vscode-editor-selectionHighlightBackground: rgba(173, 214, 255, .5);--vscode-editor-findMatchBackground: #a8ac94;--vscode-editor-findMatchHighlightBackground: rgba(234, 92, 0, .33);--vscode-editor-findRangeHighlightBackground: rgba(180, 180, 180, .3);--vscode-searchEditor-findMatchBackground: rgba(234, 92, 0, .22);--vscode-editor-hoverHighlightBackground: rgba(173, 214, 255, .15);--vscode-editorHoverWidget-background: #f3f3f3;--vscode-editorHoverWidget-foreground: #616161;--vscode-editorHoverWidget-border: #c8c8c8;--vscode-editorHoverWidget-statusBarBackground: #e7e7e7;--vscode-editorLink-activeForeground: #0000ff;--vscode-editorInlayHint-foreground: rgba(51, 51, 51, .8);--vscode-editorInlayHint-background: rgba(196, 196, 196, .3);--vscode-editorInlayHint-typeForeground: rgba(51, 51, 51, .8);--vscode-editorInlayHint-typeBackground: rgba(196, 196, 196, .3);--vscode-editorInlayHint-parameterForeground: rgba(51, 51, 51, .8);--vscode-editorInlayHint-parameterBackground: rgba(196, 196, 196, .3);--vscode-editorLightBulb-foreground: #ddb100;--vscode-editorLightBulbAutoFix-foreground: #007acc;--vscode-diffEditor-insertedTextBackground: rgba(156, 204, 44, .4);--vscode-diffEditor-removedTextBackground: rgba(255, 0, 0, .3);--vscode-diffEditor-insertedLineBackground: rgba(155, 185, 85, .2);--vscode-diffEditor-removedLineBackground: rgba(255, 0, 0, .2);--vscode-diffEditor-diagonalFill: rgba(34, 34, 34, .2);--vscode-list-focusOutline: #0090f1;--vscode-list-focusAndSelectionOutline: #90c2f9;--vscode-list-activeSelectionBackground: #0060c0;--vscode-list-activeSelectionForeground: #ffffff;--vscode-list-activeSelectionIconForeground: #ffffff;--vscode-list-inactiveSelectionBackground: #e4e6f1;--vscode-list-hoverBackground: #e8e8e8;--vscode-list-dropBackground: #d6ebff;--vscode-list-highlightForeground: #0066bf;--vscode-list-focusHighlightForeground: #bbe7ff;--vscode-list-invalidItemForeground: #b89500;--vscode-list-errorForeground: #b01011;--vscode-list-warningForeground: #855f00;--vscode-listFilterWidget-background: #f3f3f3;--vscode-listFilterWidget-outline: rgba(0, 0, 0, 0);--vscode-listFilterWidget-noMatchesOutline: #be1100;--vscode-listFilterWidget-shadow: rgba(0, 0, 0, .16);--vscode-list-filterMatchBackground: rgba(234, 92, 0, .33);--vscode-tree-indentGuidesStroke: #a9a9a9;--vscode-tree-tableColumnsBorder: rgba(97, 97, 97, .13);--vscode-tree-tableOddRowsBackground: rgba(97, 97, 97, .04);--vscode-list-deemphasizedForeground: #8e8e90;--vscode-quickInputList-focusForeground: #ffffff;--vscode-quickInputList-focusIconForeground: #ffffff;--vscode-quickInputList-focusBackground: #0060c0;--vscode-menu-foreground: #616161;--vscode-menu-background: #ffffff;--vscode-menu-selectionForeground: #ffffff;--vscode-menu-selectionBackground: #0060c0;--vscode-menu-separatorBackground: #d4d4d4;--vscode-toolbar-hoverBackground: rgba(184, 184, 184, .31);--vscode-toolbar-activeBackground: rgba(166, 166, 166, .31);--vscode-editor-snippetTabstopHighlightBackground: rgba(10, 50, 100, .2);--vscode-editor-snippetFinalTabstopHighlightBorder: rgba(10, 50, 100, .5);--vscode-breadcrumb-foreground: rgba(97, 97, 97, .8);--vscode-breadcrumb-background: #ffffff;--vscode-breadcrumb-focusForeground: #4e4e4e;--vscode-breadcrumb-activeSelectionForeground: #4e4e4e;--vscode-breadcrumbPicker-background: #f3f3f3;--vscode-merge-currentHeaderBackground: rgba(64, 200, 174, .5);--vscode-merge-currentContentBackground: rgba(64, 200, 174, .2);--vscode-merge-incomingHeaderBackground: rgba(64, 166, 255, .5);--vscode-merge-incomingContentBackground: rgba(64, 166, 255, .2);--vscode-merge-commonHeaderBackground: rgba(96, 96, 96, .4);--vscode-merge-commonContentBackground: rgba(96, 96, 96, .16);--vscode-editorOverviewRuler-currentContentForeground: rgba(64, 200, 174, .5);--vscode-editorOverviewRuler-incomingContentForeground: rgba(64, 166, 255, .5);--vscode-editorOverviewRuler-commonContentForeground: rgba(96, 96, 96, .4);--vscode-editorOverviewRuler-findMatchForeground: rgba(209, 134, 22, .49);--vscode-editorOverviewRuler-selectionHighlightForeground: rgba(160, 160, 160, .8);--vscode-minimap-findMatchHighlight: #d18616;--vscode-minimap-selectionOccurrenceHighlight: #c9c9c9;--vscode-minimap-selectionHighlight: #add6ff;--vscode-minimap-errorHighlight: rgba(255, 18, 18, .7);--vscode-minimap-warningHighlight: #bf8803;--vscode-minimap-foregroundOpacity: #000000;--vscode-minimapSlider-background: rgba(100, 100, 100, .2);--vscode-minimapSlider-hoverBackground: rgba(100, 100, 100, .35);--vscode-minimapSlider-activeBackground: rgba(0, 0, 0, .3);--vscode-problemsErrorIcon-foreground: #e51400;--vscode-problemsWarningIcon-foreground: #bf8803;--vscode-problemsInfoIcon-foreground: #1a85ff;--vscode-charts-foreground: #616161;--vscode-charts-lines: rgba(97, 97, 97, .5);--vscode-charts-red: #e51400;--vscode-charts-blue: #1a85ff;--vscode-charts-yellow: #bf8803;--vscode-charts-orange: #d18616;--vscode-charts-green: #388a34;--vscode-charts-purple: #652d90;--vscode-editor-lineHighlightBorder: #eeeeee;--vscode-editor-rangeHighlightBackground: rgba(253, 255, 0, .2);--vscode-editor-symbolHighlightBackground: rgba(234, 92, 0, .33);--vscode-editorCursor-foreground: #000000;--vscode-editorWhitespace-foreground: rgba(51, 51, 51, .2);--vscode-editorIndentGuide-background: #d3d3d3;--vscode-editorIndentGuide-activeBackground: #939393;--vscode-editorLineNumber-foreground: #237893;--vscode-editorActiveLineNumber-foreground: #0b216f;--vscode-editorLineNumber-activeForeground: #0b216f;--vscode-editorRuler-foreground: #d3d3d3;--vscode-editorCodeLens-foreground: #919191;--vscode-editorBracketMatch-background: rgba(0, 100, 0, .1);--vscode-editorBracketMatch-border: #b9b9b9;--vscode-editorOverviewRuler-border: rgba(127, 127, 127, .3);--vscode-editorGutter-background: #ffffff;--vscode-editorUnnecessaryCode-opacity: rgba(0, 0, 0, .47);--vscode-editorGhostText-foreground: rgba(0, 0, 0, .47);--vscode-editorOverviewRuler-rangeHighlightForeground: rgba(0, 122, 204, .6);--vscode-editorOverviewRuler-errorForeground: rgba(255, 18, 18, .7);--vscode-editorOverviewRuler-warningForeground: #bf8803;--vscode-editorOverviewRuler-infoForeground: #1a85ff;--vscode-editorBracketHighlight-foreground1: #0431fa;--vscode-editorBracketHighlight-foreground2: #319331;--vscode-editorBracketHighlight-foreground3: #7b3814;--vscode-editorBracketHighlight-foreground4: rgba(0, 0, 0, 0);--vscode-editorBracketHighlight-foreground5: rgba(0, 0, 0, 0);--vscode-editorBracketHighlight-foreground6: rgba(0, 0, 0, 0);--vscode-editorBracketHighlight-unexpectedBracket\.foreground: rgba(255, 18, 18, .8);--vscode-editorBracketPairGuide-background1: rgba(0, 0, 0, 0);--vscode-editorBracketPairGuide-background2: rgba(0, 0, 0, 0);--vscode-editorBracketPairGuide-background3: rgba(0, 0, 0, 0);--vscode-editorBracketPairGuide-background4: rgba(0, 0, 0, 0);--vscode-editorBracketPairGuide-background5: rgba(0, 0, 0, 0);--vscode-editorBracketPairGuide-background6: rgba(0, 0, 0, 0);--vscode-editorBracketPairGuide-activeBackground1: rgba(0, 0, 0, 0);--vscode-editorBracketPairGuide-activeBackground2: rgba(0, 0, 0, 0);--vscode-editorBracketPairGuide-activeBackground3: rgba(0, 0, 0, 0);--vscode-editorBracketPairGuide-activeBackground4: rgba(0, 0, 0, 0);--vscode-editorBracketPairGuide-activeBackground5: rgba(0, 0, 0, 0);--vscode-editorBracketPairGuide-activeBackground6: rgba(0, 0, 0, 0);--vscode-editorUnicodeHighlight-border: #cea33d;--vscode-editorUnicodeHighlight-background: rgba(206, 163, 61, .08);--vscode-symbolIcon-arrayForeground: #616161;--vscode-symbolIcon-booleanForeground: #616161;--vscode-symbolIcon-classForeground: #d67e00;--vscode-symbolIcon-colorForeground: #616161;--vscode-symbolIcon-constantForeground: #616161;--vscode-symbolIcon-constructorForeground: #652d90;--vscode-symbolIcon-enumeratorForeground: #d67e00;--vscode-symbolIcon-enumeratorMemberForeground: #007acc;--vscode-symbolIcon-eventForeground: #d67e00;--vscode-symbolIcon-fieldForeground: #007acc;--vscode-symbolIcon-fileForeground: #616161;--vscode-symbolIcon-folderForeground: #616161;--vscode-symbolIcon-functionForeground: #652d90;--vscode-symbolIcon-interfaceForeground: #007acc;--vscode-symbolIcon-keyForeground: #616161;--vscode-symbolIcon-keywordForeground: #616161;--vscode-symbolIcon-methodForeground: #652d90;--vscode-symbolIcon-moduleForeground: #616161;--vscode-symbolIcon-namespaceForeground: #616161;--vscode-symbolIcon-nullForeground: #616161;--vscode-symbolIcon-numberForeground: #616161;--vscode-symbolIcon-objectForeground: #616161;--vscode-symbolIcon-operatorForeground: #616161;--vscode-symbolIcon-packageForeground: #616161;--vscode-symbolIcon-propertyForeground: #616161;--vscode-symbolIcon-referenceForeground: #616161;--vscode-symbolIcon-snippetForeground: #616161;--vscode-symbolIcon-stringForeground: #616161;--vscode-symbolIcon-structForeground: #616161;--vscode-symbolIcon-textForeground: #616161;--vscode-symbolIcon-typeParameterForeground: #616161;--vscode-symbolIcon-unitForeground: #616161;--vscode-symbolIcon-variableForeground: #007acc;--vscode-editorHoverWidget-highlightForeground: #0066bf;--vscode-editorOverviewRuler-bracketMatchForeground: #a0a0a0;--vscode-editor-foldBackground: rgba(173, 214, 255, .3);--vscode-editorGutter-foldingControlForeground: #424242;--vscode-editor-linkedEditingBackground: rgba(255, 0, 0, .3);--vscode-editor-wordHighlightBackground: rgba(87, 87, 87, .25);--vscode-editor-wordHighlightStrongBackground: rgba(14, 99, 156, .25);--vscode-editorOverviewRuler-wordHighlightForeground: rgba(160, 160, 160, .8);--vscode-editorOverviewRuler-wordHighlightStrongForeground: rgba(192, 160, 192, .8);--vscode-peekViewTitle-background: rgba(26, 133, 255, .1);--vscode-peekViewTitleLabel-foreground: #000000;--vscode-peekViewTitleDescription-foreground: #616161;--vscode-peekView-border: #1a85ff;--vscode-peekViewResult-background: #f3f3f3;--vscode-peekViewResult-lineForeground: #646465;--vscode-peekViewResult-fileForeground: #1e1e1e;--vscode-peekViewResult-selectionBackground: rgba(51, 153, 255, .2);--vscode-peekViewResult-selectionForeground: #6c6c6c;--vscode-peekViewEditor-background: #f2f8fc;--vscode-peekViewEditorGutter-background: #f2f8fc;--vscode-peekViewResult-matchHighlightBackground: rgba(234, 92, 0, .3);--vscode-peekViewEditor-matchHighlightBackground: rgba(245, 216, 2, .87);--vscode-editorMarkerNavigationError-background: #e51400;--vscode-editorMarkerNavigationError-headerBackground: rgba(229, 20, 0, .1);--vscode-editorMarkerNavigationWarning-background: #bf8803;--vscode-editorMarkerNavigationWarning-headerBackground: rgba(191, 136, 3, .1);--vscode-editorMarkerNavigationInfo-background: #1a85ff;--vscode-editorMarkerNavigationInfo-headerBackground: rgba(26, 133, 255, .1);--vscode-editorMarkerNavigation-background: #ffffff;--vscode-editorSuggestWidget-background: #f3f3f3;--vscode-editorSuggestWidget-border: #c8c8c8;--vscode-editorSuggestWidget-foreground: #000000;--vscode-editorSuggestWidget-selectedForeground: #ffffff;--vscode-editorSuggestWidget-selectedIconForeground: #ffffff;--vscode-editorSuggestWidget-selectedBackground: #0060c0;--vscode-editorSuggestWidget-highlightForeground: #0066bf;--vscode-editorSuggestWidget-focusHighlightForeground: #bbe7ff;--vscode-editorSuggestWidgetStatus-foreground: rgba(0, 0, 0, .5);--vscode-tab-activeBackground: #ffffff;--vscode-tab-unfocusedActiveBackground: #ffffff;--vscode-tab-inactiveBackground: #ececec;--vscode-tab-unfocusedInactiveBackground: #ececec;--vscode-tab-activeForeground: #333333;--vscode-tab-inactiveForeground: rgba(51, 51, 51, .7);--vscode-tab-unfocusedActiveForeground: rgba(51, 51, 51, .7);--vscode-tab-unfocusedInactiveForeground: rgba(51, 51, 51, .35);--vscode-tab-border: #f3f3f3;--vscode-tab-lastPinnedBorder: rgba(97, 97, 97, .19);--vscode-tab-activeModifiedBorder: #33aaee;--vscode-tab-inactiveModifiedBorder: rgba(51, 170, 238, .5);--vscode-tab-unfocusedActiveModifiedBorder: rgba(51, 170, 238, .7);--vscode-tab-unfocusedInactiveModifiedBorder: rgba(51, 170, 238, .25);--vscode-editorPane-background: #ffffff;--vscode-editorGroupHeader-tabsBackground: #f3f3f3;--vscode-editorGroupHeader-noTabsBackground: #ffffff;--vscode-editorGroup-border: #e7e7e7;--vscode-editorGroup-dropBackground: rgba(38, 119, 203, .18);--vscode-editorGroup-dropIntoPromptForeground: #616161;--vscode-editorGroup-dropIntoPromptBackground: #f3f3f3;--vscode-sideBySideEditor-horizontalBorder: #e7e7e7;--vscode-sideBySideEditor-verticalBorder: #e7e7e7;--vscode-panel-background: #ffffff;--vscode-panel-border: rgba(128, 128, 128, .35);--vscode-panelTitle-activeForeground: #424242;--vscode-panelTitle-inactiveForeground: rgba(66, 66, 66, .75);--vscode-panelTitle-activeBorder: #424242;--vscode-panelInput-border: #dddddd;--vscode-panel-dropBorder: #424242;--vscode-panelSection-dropBackground: rgba(38, 119, 203, .18);--vscode-panelSectionHeader-background: rgba(128, 128, 128, .2);--vscode-panelSection-border: rgba(128, 128, 128, .35);--vscode-banner-background: #004386;--vscode-banner-foreground: #ffffff;--vscode-banner-iconForeground: #1a85ff;--vscode-statusBar-foreground: #ffffff;--vscode-statusBar-noFolderForeground: #ffffff;--vscode-statusBar-background: #007acc;--vscode-statusBar-noFolderBackground: #68217a;--vscode-statusBar-focusBorder: #ffffff;--vscode-statusBarItem-activeBackground: rgba(255, 255, 255, .18);--vscode-statusBarItem-focusBorder: #ffffff;--vscode-statusBarItem-hoverBackground: rgba(255, 255, 255, .12);--vscode-statusBarItem-compactHoverBackground: rgba(255, 255, 255, .2);--vscode-statusBarItem-prominentForeground: #ffffff;--vscode-statusBarItem-prominentBackground: rgba(0, 0, 0, .5);--vscode-statusBarItem-prominentHoverBackground: rgba(0, 0, 0, .3);--vscode-statusBarItem-errorBackground: #c72e0f;--vscode-statusBarItem-errorForeground: #ffffff;--vscode-statusBarItem-warningBackground: #725102;--vscode-statusBarItem-warningForeground: #ffffff;--vscode-activityBar-background: #2c2c2c;--vscode-activityBar-foreground: #ffffff;--vscode-activityBar-inactiveForeground: rgba(255, 255, 255, .4);--vscode-activityBar-activeBorder: #ffffff;--vscode-activityBar-dropBorder: #ffffff;--vscode-activityBarBadge-background: #007acc;--vscode-activityBarBadge-foreground: #ffffff;--vscode-statusBarItem-remoteBackground: #16825d;--vscode-statusBarItem-remoteForeground: #ffffff;--vscode-extensionBadge-remoteBackground: #007acc;--vscode-extensionBadge-remoteForeground: #ffffff;--vscode-sideBar-background: #f3f3f3;--vscode-sideBarTitle-foreground: #6f6f6f;--vscode-sideBar-dropBackground: rgba(38, 119, 203, .18);--vscode-sideBarSectionHeader-background: rgba(0, 0, 0, 0);--vscode-sideBarSectionHeader-border: rgba(97, 97, 97, .19);--vscode-titleBar-activeForeground: #333333;--vscode-titleBar-inactiveForeground: rgba(51, 51, 51, .6);--vscode-titleBar-activeBackground: #dddddd;--vscode-titleBar-inactiveBackground: rgba(221, 221, 221, .6);--vscode-menubar-selectionForeground: #333333;--vscode-menubar-selectionBackground: rgba(184, 184, 184, .31);--vscode-notifications-foreground: #616161;--vscode-notifications-background: #f3f3f3;--vscode-notificationLink-foreground: #006ab1;--vscode-notificationCenterHeader-background: #e7e7e7;--vscode-notifications-border: #e7e7e7;--vscode-notificationsErrorIcon-foreground: #e51400;--vscode-notificationsWarningIcon-foreground: #bf8803;--vscode-notificationsInfoIcon-foreground: #1a85ff;--vscode-commandCenter-foreground: #333333;--vscode-commandCenter-activeForeground: #333333;--vscode-commandCenter-activeBackground: rgba(184, 184, 184, .31);--vscode-commandCenter-border: rgba(128, 128, 128, .35);--vscode-editorCommentsWidget-resolvedBorder: rgba(97, 97, 97, .5);--vscode-editorCommentsWidget-unresolvedBorder: #1a85ff;--vscode-editorCommentsWidget-rangeBackground: rgba(26, 133, 255, .1);--vscode-editorCommentsWidget-rangeBorder: rgba(26, 133, 255, .4);--vscode-editorCommentsWidget-rangeActiveBackground: rgba(26, 133, 255, .1);--vscode-editorCommentsWidget-rangeActiveBorder: rgba(26, 133, 255, .4);--vscode-editorGutter-commentRangeForeground: #d5d8e9;--vscode-debugToolBar-background: #f3f3f3;--vscode-debugIcon-startForeground: #388a34;--vscode-editor-stackFrameHighlightBackground: rgba(255, 255, 102, .45);--vscode-editor-focusedStackFrameHighlightBackground: rgba(206, 231, 206, .45);--vscode-mergeEditor-change\.background: rgba(155, 185, 85, .2);--vscode-mergeEditor-change\.word\.background: rgba(156, 204, 44, .4);--vscode-mergeEditor-conflict\.unhandledUnfocused\.border: rgba(255, 166, 0, .48);--vscode-mergeEditor-conflict\.unhandledFocused\.border: #ffa600;--vscode-mergeEditor-conflict\.handledUnfocused\.border: rgba(134, 134, 134, .29);--vscode-mergeEditor-conflict\.handledFocused\.border: rgba(193, 193, 193, .8);--vscode-mergeEditor-conflict\.handled\.minimapOverViewRuler: rgba(173, 172, 168, .93);--vscode-mergeEditor-conflict\.unhandled\.minimapOverViewRuler: #fcba03;--vscode-mergeEditor-conflictingLines\.background: rgba(255, 234, 0, .28);--vscode-settings-headerForeground: #444444;--vscode-settings-modifiedItemIndicator: #66afe0;--vscode-settings-headerBorder: rgba(128, 128, 128, .35);--vscode-settings-sashBorder: rgba(128, 128, 128, .35);--vscode-settings-dropdownBackground: #ffffff;--vscode-settings-dropdownBorder: #cecece;--vscode-settings-dropdownListBorder: #c8c8c8;--vscode-settings-checkboxBackground: #ffffff;--vscode-settings-checkboxBorder: #cecece;--vscode-settings-textInputBackground: #ffffff;--vscode-settings-textInputForeground: #616161;--vscode-settings-textInputBorder: #cecece;--vscode-settings-numberInputBackground: #ffffff;--vscode-settings-numberInputForeground: #616161;--vscode-settings-numberInputBorder: #cecece;--vscode-settings-focusedRowBackground: rgba(232, 232, 232, .6);--vscode-settings-rowHoverBackground: rgba(232, 232, 232, .3);--vscode-settings-focusedRowBorder: rgba(0, 0, 0, .12);--vscode-terminal-foreground: #333333;--vscode-terminal-selectionBackground: #add6ff;--vscode-terminal-inactiveSelectionBackground: #e5ebf1;--vscode-terminalCommandDecoration-defaultBackground: rgba(0, 0, 0, .25);--vscode-terminalCommandDecoration-successBackground: #2090d3;--vscode-terminalCommandDecoration-errorBackground: #e51400;--vscode-terminalOverviewRuler-cursorForeground: rgba(160, 160, 160, .8);--vscode-terminal-border: rgba(128, 128, 128, .35);--vscode-terminal-findMatchBackground: #a8ac94;--vscode-terminal-findMatchHighlightBackground: rgba(234, 92, 0, .33);--vscode-terminalOverviewRuler-findMatchForeground: rgba(209, 134, 22, .49);--vscode-terminal-dropBackground: rgba(38, 119, 203, .18);--vscode-testing-iconFailed: #f14c4c;--vscode-testing-iconErrored: #f14c4c;--vscode-testing-iconPassed: #73c991;--vscode-testing-runAction: #73c991;--vscode-testing-iconQueued: #cca700;--vscode-testing-iconUnset: #848484;--vscode-testing-iconSkipped: #848484;--vscode-testing-peekBorder: #e51400;--vscode-testing-peekHeaderBackground: rgba(229, 20, 0, .1);--vscode-testing-message\.error\.decorationForeground: #e51400;--vscode-testing-message\.error\.lineBackground: rgba(255, 0, 0, .2);--vscode-testing-message\.info\.decorationForeground: rgba(0, 0, 0, .5);--vscode-welcomePage-tileBackground: #f3f3f3;--vscode-welcomePage-tileHoverBackground: #dbdbdb;--vscode-welcomePage-tileShadow: rgba(0, 0, 0, .16);--vscode-welcomePage-progress\.background: #ffffff;--vscode-welcomePage-progress\.foreground: #006ab1;--vscode-debugExceptionWidget-border: #a31515;--vscode-debugExceptionWidget-background: #f1dfde;--vscode-ports-iconRunningProcessForeground: #369432;--vscode-statusBar-debuggingBackground: #cc6633;--vscode-statusBar-debuggingForeground: #ffffff;--vscode-editor-inlineValuesForeground: rgba(0, 0, 0, .5);--vscode-editor-inlineValuesBackground: rgba(255, 200, 0, .2);--vscode-editorGutter-modifiedBackground: #2090d3;--vscode-editorGutter-addedBackground: #48985d;--vscode-editorGutter-deletedBackground: #e51400;--vscode-minimapGutter-modifiedBackground: #2090d3;--vscode-minimapGutter-addedBackground: #48985d;--vscode-minimapGutter-deletedBackground: #e51400;--vscode-editorOverviewRuler-modifiedForeground: rgba(32, 144, 211, .6);--vscode-editorOverviewRuler-addedForeground: rgba(72, 152, 93, .6);--vscode-editorOverviewRuler-deletedForeground: rgba(229, 20, 0, .6);--vscode-debugIcon-breakpointForeground: #e51400;--vscode-debugIcon-breakpointDisabledForeground: #848484;--vscode-debugIcon-breakpointUnverifiedForeground: #848484;--vscode-debugIcon-breakpointCurrentStackframeForeground: #be8700;--vscode-debugIcon-breakpointStackframeForeground: #89d185;--vscode-notebook-cellBorderColor: #e8e8e8;--vscode-notebook-focusedEditorBorder: #0090f1;--vscode-notebookStatusSuccessIcon-foreground: #388a34;--vscode-notebookStatusErrorIcon-foreground: #a1260d;--vscode-notebookStatusRunningIcon-foreground: #616161;--vscode-notebook-cellToolbarSeparator: rgba(128, 128, 128, .35);--vscode-notebook-selectedCellBackground: rgba(200, 221, 241, .31);--vscode-notebook-selectedCellBorder: #e8e8e8;--vscode-notebook-focusedCellBorder: #0090f1;--vscode-notebook-inactiveFocusedCellBorder: #e8e8e8;--vscode-notebook-cellStatusBarItemHoverBackground: rgba(0, 0, 0, .08);--vscode-notebook-cellInsertionIndicator: #0090f1;--vscode-notebookScrollbarSlider-background: rgba(100, 100, 100, .4);--vscode-notebookScrollbarSlider-hoverBackground: rgba(100, 100, 100, .7);--vscode-notebookScrollbarSlider-activeBackground: rgba(0, 0, 0, .6);--vscode-notebook-symbolHighlightBackground: rgba(253, 255, 0, .2);--vscode-notebook-cellEditorBackground: #f3f3f3;--vscode-notebook-editorBackground: #ffffff;--vscode-keybindingTable-headerBackground: rgba(97, 97, 97, .04);--vscode-keybindingTable-rowsBackground: rgba(97, 97, 97, .04);--vscode-scm-providerBorder: #c8c8c8;--vscode-searchEditor-textInputBorder: #cecece;--vscode-debugTokenExpression-name: #9b46b0;--vscode-debugTokenExpression-value: rgba(108, 108, 108, .8);--vscode-debugTokenExpression-string: #a31515;--vscode-debugTokenExpression-boolean: #0000ff;--vscode-debugTokenExpression-number: #098658;--vscode-debugTokenExpression-error: #e51400;--vscode-debugView-exceptionLabelForeground: #ffffff;--vscode-debugView-exceptionLabelBackground: #a31515;--vscode-debugView-stateLabelForeground: #616161;--vscode-debugView-stateLabelBackground: rgba(136, 136, 136, .27);--vscode-debugView-valueChangedHighlight: #569cd6;--vscode-debugConsole-infoForeground: #1a85ff;--vscode-debugConsole-warningForeground: #bf8803;--vscode-debugConsole-errorForeground: #a1260d;--vscode-debugConsole-sourceForeground: #616161;--vscode-debugConsoleInputIcon-foreground: #616161;--vscode-debugIcon-pauseForeground: #007acc;--vscode-debugIcon-stopForeground: #a1260d;--vscode-debugIcon-disconnectForeground: #a1260d;--vscode-debugIcon-restartForeground: #388a34;--vscode-debugIcon-stepOverForeground: #007acc;--vscode-debugIcon-stepIntoForeground: #007acc;--vscode-debugIcon-stepOutForeground: #007acc;--vscode-debugIcon-continueForeground: #007acc;--vscode-debugIcon-stepBackForeground: #007acc;--vscode-extensionButton-prominentBackground: #007acc;--vscode-extensionButton-prominentForeground: #ffffff;--vscode-extensionButton-prominentHoverBackground: #0062a3;--vscode-extensionIcon-starForeground: #df6100;--vscode-extensionIcon-verifiedForeground: #006ab1;--vscode-extensionIcon-preReleaseForeground: #1d9271;--vscode-extensionIcon-sponsorForeground: #b51e78;--vscode-terminal-ansiBlack: #000000;--vscode-terminal-ansiRed: #cd3131;--vscode-terminal-ansiGreen: #00bc00;--vscode-terminal-ansiYellow: #949800;--vscode-terminal-ansiBlue: #0451a5;--vscode-terminal-ansiMagenta: #bc05bc;--vscode-terminal-ansiCyan: #0598bc;--vscode-terminal-ansiWhite: #555555;--vscode-terminal-ansiBrightBlack: #666666;--vscode-terminal-ansiBrightRed: #cd3131;--vscode-terminal-ansiBrightGreen: #14ce14;--vscode-terminal-ansiBrightYellow: #b5ba00;--vscode-terminal-ansiBrightBlue: #0451a5;--vscode-terminal-ansiBrightMagenta: #bc05bc;--vscode-terminal-ansiBrightCyan: #0598bc;--vscode-terminal-ansiBrightWhite: #a5a5a5;--vscode-interactive-activeCodeBorder: #1a85ff;--vscode-interactive-inactiveCodeBorder: #e4e6f1;--vscode-gitDecoration-addedResourceForeground: #587c0c;--vscode-gitDecoration-modifiedResourceForeground: #895503;--vscode-gitDecoration-deletedResourceForeground: #ad0707;--vscode-gitDecoration-renamedResourceForeground: #007100;--vscode-gitDecoration-untrackedResourceForeground: #007100;--vscode-gitDecoration-ignoredResourceForeground: #8e8e90;--vscode-gitDecoration-stageModifiedResourceForeground: #895503;--vscode-gitDecoration-stageDeletedResourceForeground: #ad0707;--vscode-gitDecoration-conflictingResourceForeground: #ad0707;--vscode-gitDecoration-submoduleResourceForeground: #1258a7}:root.light-mode{color-scheme:light}:root.dark-mode{color-scheme:dark;--vscode-font-family: system-ui, "Ubuntu", "Droid Sans", sans-serif;--vscode-font-weight: normal;--vscode-font-size: 13px;--vscode-editor-font-family: "Droid Sans Mono", "monospace", monospace;--vscode-editor-font-weight: normal;--vscode-editor-font-size: 14px;--vscode-foreground: #cccccc;--vscode-disabledForeground: rgba(204, 204, 204, .5);--vscode-errorForeground: #f48771;--vscode-descriptionForeground: rgba(204, 204, 204, .7);--vscode-icon-foreground: #c5c5c5;--vscode-focusBorder: #007fd4;--vscode-textSeparator-foreground: rgba(255, 255, 255, .18);--vscode-textLink-foreground: #3794ff;--vscode-textLink-activeForeground: #3794ff;--vscode-textPreformat-foreground: #d7ba7d;--vscode-textBlockQuote-background: rgba(127, 127, 127, .1);--vscode-textBlockQuote-border: rgba(0, 122, 204, .5);--vscode-textCodeBlock-background: rgba(10, 10, 10, .4);--vscode-widget-shadow: rgba(0, 0, 0, .36);--vscode-input-background: #3c3c3c;--vscode-input-foreground: #cccccc;--vscode-inputOption-activeBorder: #007acc;--vscode-inputOption-hoverBackground: rgba(90, 93, 94, .5);--vscode-inputOption-activeBackground: rgba(0, 127, 212, .4);--vscode-inputOption-activeForeground: #ffffff;--vscode-input-placeholderForeground: #a6a6a6;--vscode-inputValidation-infoBackground: #063b49;--vscode-inputValidation-infoBorder: #007acc;--vscode-inputValidation-warningBackground: #352a05;--vscode-inputValidation-warningBorder: #b89500;--vscode-inputValidation-errorBackground: #5a1d1d;--vscode-inputValidation-errorBorder: #be1100;--vscode-dropdown-background: #3c3c3c;--vscode-dropdown-foreground: #f0f0f0;--vscode-dropdown-border: #3c3c3c;--vscode-checkbox-background: #3c3c3c;--vscode-checkbox-foreground: #f0f0f0;--vscode-checkbox-border: #3c3c3c;--vscode-button-foreground: #ffffff;--vscode-button-separator: rgba(255, 255, 255, .4);--vscode-button-background: #0e639c;--vscode-button-hoverBackground: #1177bb;--vscode-button-secondaryForeground: #ffffff;--vscode-button-secondaryBackground: #3a3d41;--vscode-button-secondaryHoverBackground: #45494e;--vscode-badge-background: #4d4d4d;--vscode-badge-foreground: #ffffff;--vscode-scrollbar-shadow: #000000;--vscode-scrollbarSlider-background: rgba(121, 121, 121, .4);--vscode-scrollbarSlider-hoverBackground: rgba(100, 100, 100, .7);--vscode-scrollbarSlider-activeBackground: rgba(191, 191, 191, .4);--vscode-progressBar-background: #0e70c0;--vscode-editorError-foreground: #f14c4c;--vscode-editorWarning-foreground: #cca700;--vscode-editorInfo-foreground: #3794ff;--vscode-editorHint-foreground: rgba(238, 238, 238, .7);--vscode-sash-hoverBorder: #007fd4;--vscode-editor-background: #1e1e1e;--vscode-editor-foreground: #d4d4d4;--vscode-editorStickyScroll-background: #1e1e1e;--vscode-editorStickyScrollHover-background: #2a2d2e;--vscode-editorWidget-background: #252526;--vscode-editorWidget-foreground: #cccccc;--vscode-editorWidget-border: #454545;--vscode-quickInput-background: #252526;--vscode-quickInput-foreground: #cccccc;--vscode-quickInputTitle-background: rgba(255, 255, 255, .1);--vscode-pickerGroup-foreground: #3794ff;--vscode-pickerGroup-border: #3f3f46;--vscode-keybindingLabel-background: rgba(128, 128, 128, .17);--vscode-keybindingLabel-foreground: #cccccc;--vscode-keybindingLabel-border: rgba(51, 51, 51, .6);--vscode-keybindingLabel-bottomBorder: rgba(68, 68, 68, .6);--vscode-editor-selectionBackground: #264f78;--vscode-editor-inactiveSelectionBackground: #3a3d41;--vscode-editor-selectionHighlightBackground: rgba(173, 214, 255, .15);--vscode-editor-findMatchBackground: #515c6a;--vscode-editor-findMatchHighlightBackground: rgba(234, 92, 0, .33);--vscode-editor-findRangeHighlightBackground: rgba(58, 61, 65, .4);--vscode-searchEditor-findMatchBackground: rgba(234, 92, 0, .22);--vscode-editor-hoverHighlightBackground: rgba(38, 79, 120, .25);--vscode-editorHoverWidget-background: #252526;--vscode-editorHoverWidget-foreground: #cccccc;--vscode-editorHoverWidget-border: #454545;--vscode-editorHoverWidget-statusBarBackground: #2c2c2d;--vscode-editorLink-activeForeground: #4e94ce;--vscode-editorInlayHint-foreground: rgba(255, 255, 255, .8);--vscode-editorInlayHint-background: rgba(77, 77, 77, .6);--vscode-editorInlayHint-typeForeground: rgba(255, 255, 255, .8);--vscode-editorInlayHint-typeBackground: rgba(77, 77, 77, .6);--vscode-editorInlayHint-parameterForeground: rgba(255, 255, 255, .8);--vscode-editorInlayHint-parameterBackground: rgba(77, 77, 77, .6);--vscode-editorLightBulb-foreground: #ffcc00;--vscode-editorLightBulbAutoFix-foreground: #75beff;--vscode-diffEditor-insertedTextBackground: rgba(156, 204, 44, .2);--vscode-diffEditor-removedTextBackground: rgba(255, 0, 0, .4);--vscode-diffEditor-insertedLineBackground: rgba(155, 185, 85, .2);--vscode-diffEditor-removedLineBackground: rgba(255, 0, 0, .2);--vscode-diffEditor-diagonalFill: rgba(204, 204, 204, .2);--vscode-list-focusOutline: #007fd4;--vscode-list-activeSelectionBackground: #04395e;--vscode-list-activeSelectionForeground: #ffffff;--vscode-list-activeSelectionIconForeground: #ffffff;--vscode-list-inactiveSelectionBackground: #37373d;--vscode-list-hoverBackground: #2a2d2e;--vscode-list-dropBackground: #383b3d;--vscode-list-highlightForeground: #2aaaff;--vscode-list-focusHighlightForeground: #2aaaff;--vscode-list-invalidItemForeground: #b89500;--vscode-list-errorForeground: #f88070;--vscode-list-warningForeground: #cca700;--vscode-listFilterWidget-background: #252526;--vscode-listFilterWidget-outline: rgba(0, 0, 0, 0);--vscode-listFilterWidget-noMatchesOutline: #be1100;--vscode-listFilterWidget-shadow: rgba(0, 0, 0, .36);--vscode-list-filterMatchBackground: rgba(234, 92, 0, .33);--vscode-tree-indentGuidesStroke: #585858;--vscode-tree-tableColumnsBorder: rgba(204, 204, 204, .13);--vscode-tree-tableOddRowsBackground: rgba(204, 204, 204, .04);--vscode-list-deemphasizedForeground: #8c8c8c;--vscode-quickInputList-focusForeground: #ffffff;--vscode-quickInputList-focusIconForeground: #ffffff;--vscode-quickInputList-focusBackground: #04395e;--vscode-menu-foreground: #cccccc;--vscode-menu-background: #303031;--vscode-menu-selectionForeground: #ffffff;--vscode-menu-selectionBackground: #04395e;--vscode-menu-separatorBackground: #606060;--vscode-toolbar-hoverBackground: rgba(90, 93, 94, .31);--vscode-toolbar-activeBackground: rgba(99, 102, 103, .31);--vscode-editor-snippetTabstopHighlightBackground: rgba(124, 124, 124, .3);--vscode-editor-snippetFinalTabstopHighlightBorder: #525252;--vscode-breadcrumb-foreground: rgba(204, 204, 204, .8);--vscode-breadcrumb-background: #1e1e1e;--vscode-breadcrumb-focusForeground: #e0e0e0;--vscode-breadcrumb-activeSelectionForeground: #e0e0e0;--vscode-breadcrumbPicker-background: #252526;--vscode-merge-currentHeaderBackground: rgba(64, 200, 174, .5);--vscode-merge-currentContentBackground: rgba(64, 200, 174, .2);--vscode-merge-incomingHeaderBackground: rgba(64, 166, 255, .5);--vscode-merge-incomingContentBackground: rgba(64, 166, 255, .2);--vscode-merge-commonHeaderBackground: rgba(96, 96, 96, .4);--vscode-merge-commonContentBackground: rgba(96, 96, 96, .16);--vscode-editorOverviewRuler-currentContentForeground: rgba(64, 200, 174, .5);--vscode-editorOverviewRuler-incomingContentForeground: rgba(64, 166, 255, .5);--vscode-editorOverviewRuler-commonContentForeground: rgba(96, 96, 96, .4);--vscode-editorOverviewRuler-findMatchForeground: rgba(209, 134, 22, .49);--vscode-editorOverviewRuler-selectionHighlightForeground: rgba(160, 160, 160, .8);--vscode-minimap-findMatchHighlight: #d18616;--vscode-minimap-selectionOccurrenceHighlight: #676767;--vscode-minimap-selectionHighlight: #264f78;--vscode-minimap-errorHighlight: rgba(255, 18, 18, .7);--vscode-minimap-warningHighlight: #cca700;--vscode-minimap-foregroundOpacity: #000000;--vscode-minimapSlider-background: rgba(121, 121, 121, .2);--vscode-minimapSlider-hoverBackground: rgba(100, 100, 100, .35);--vscode-minimapSlider-activeBackground: rgba(191, 191, 191, .2);--vscode-problemsErrorIcon-foreground: #f14c4c;--vscode-problemsWarningIcon-foreground: #cca700;--vscode-problemsInfoIcon-foreground: #3794ff;--vscode-charts-foreground: #cccccc;--vscode-charts-lines: rgba(204, 204, 204, .5);--vscode-charts-red: #f14c4c;--vscode-charts-blue: #3794ff;--vscode-charts-yellow: #cca700;--vscode-charts-orange: #d18616;--vscode-charts-green: #89d185;--vscode-charts-purple: #b180d7;--vscode-editor-lineHighlightBorder: #282828;--vscode-editor-rangeHighlightBackground: rgba(255, 255, 255, .04);--vscode-editor-symbolHighlightBackground: rgba(234, 92, 0, .33);--vscode-editorCursor-foreground: #aeafad;--vscode-editorWhitespace-foreground: rgba(227, 228, 226, .16);--vscode-editorIndentGuide-background: #404040;--vscode-editorIndentGuide-activeBackground: #707070;--vscode-editorLineNumber-foreground: #858585;--vscode-editorActiveLineNumber-foreground: #c6c6c6;--vscode-editorLineNumber-activeForeground: #c6c6c6;--vscode-editorRuler-foreground: #5a5a5a;--vscode-editorCodeLens-foreground: #999999;--vscode-editorBracketMatch-background: rgba(0, 100, 0, .1);--vscode-editorBracketMatch-border: #888888;--vscode-editorOverviewRuler-border: rgba(127, 127, 127, .3);--vscode-editorGutter-background: #1e1e1e;--vscode-editorUnnecessaryCode-opacity: rgba(0, 0, 0, .67);--vscode-editorGhostText-foreground: rgba(255, 255, 255, .34);--vscode-editorOverviewRuler-rangeHighlightForeground: rgba(0, 122, 204, .6);--vscode-editorOverviewRuler-errorForeground: rgba(255, 18, 18, .7);--vscode-editorOverviewRuler-warningForeground: #cca700;--vscode-editorOverviewRuler-infoForeground: #3794ff;--vscode-editorBracketHighlight-foreground1: #ffd700;--vscode-editorBracketHighlight-foreground2: #da70d6;--vscode-editorBracketHighlight-foreground3: #179fff;--vscode-editorBracketHighlight-foreground4: rgba(0, 0, 0, 0);--vscode-editorBracketHighlight-foreground5: rgba(0, 0, 0, 0);--vscode-editorBracketHighlight-foreground6: rgba(0, 0, 0, 0);--vscode-editorBracketHighlight-unexpectedBracket\.foreground: rgba(255, 18, 18, .8);--vscode-editorBracketPairGuide-background1: rgba(0, 0, 0, 0);--vscode-editorBracketPairGuide-background2: rgba(0, 0, 0, 0);--vscode-editorBracketPairGuide-background3: rgba(0, 0, 0, 0);--vscode-editorBracketPairGuide-background4: rgba(0, 0, 0, 0);--vscode-editorBracketPairGuide-background5: rgba(0, 0, 0, 0);--vscode-editorBracketPairGuide-background6: rgba(0, 0, 0, 0);--vscode-editorBracketPairGuide-activeBackground1: rgba(0, 0, 0, 0);--vscode-editorBracketPairGuide-activeBackground2: rgba(0, 0, 0, 0);--vscode-editorBracketPairGuide-activeBackground3: rgba(0, 0, 0, 0);--vscode-editorBracketPairGuide-activeBackground4: rgba(0, 0, 0, 0);--vscode-editorBracketPairGuide-activeBackground5: rgba(0, 0, 0, 0);--vscode-editorBracketPairGuide-activeBackground6: rgba(0, 0, 0, 0);--vscode-editorUnicodeHighlight-border: #bd9b03;--vscode-editorUnicodeHighlight-background: rgba(189, 155, 3, .15);--vscode-symbolIcon-arrayForeground: #cccccc;--vscode-symbolIcon-booleanForeground: #cccccc;--vscode-symbolIcon-classForeground: #ee9d28;--vscode-symbolIcon-colorForeground: #cccccc;--vscode-symbolIcon-constantForeground: #cccccc;--vscode-symbolIcon-constructorForeground: #b180d7;--vscode-symbolIcon-enumeratorForeground: #ee9d28;--vscode-symbolIcon-enumeratorMemberForeground: #75beff;--vscode-symbolIcon-eventForeground: #ee9d28;--vscode-symbolIcon-fieldForeground: #75beff;--vscode-symbolIcon-fileForeground: #cccccc;--vscode-symbolIcon-folderForeground: #cccccc;--vscode-symbolIcon-functionForeground: #b180d7;--vscode-symbolIcon-interfaceForeground: #75beff;--vscode-symbolIcon-keyForeground: #cccccc;--vscode-symbolIcon-keywordForeground: #cccccc;--vscode-symbolIcon-methodForeground: #b180d7;--vscode-symbolIcon-moduleForeground: #cccccc;--vscode-symbolIcon-namespaceForeground: #cccccc;--vscode-symbolIcon-nullForeground: #cccccc;--vscode-symbolIcon-numberForeground: #cccccc;--vscode-symbolIcon-objectForeground: #cccccc;--vscode-symbolIcon-operatorForeground: #cccccc;--vscode-symbolIcon-packageForeground: #cccccc;--vscode-symbolIcon-propertyForeground: #cccccc;--vscode-symbolIcon-referenceForeground: #cccccc;--vscode-symbolIcon-snippetForeground: #cccccc;--vscode-symbolIcon-stringForeground: #cccccc;--vscode-symbolIcon-structForeground: #cccccc;--vscode-symbolIcon-textForeground: #cccccc;--vscode-symbolIcon-typeParameterForeground: #cccccc;--vscode-symbolIcon-unitForeground: #cccccc;--vscode-symbolIcon-variableForeground: #75beff;--vscode-editorHoverWidget-highlightForeground: #2aaaff;--vscode-editorOverviewRuler-bracketMatchForeground: #a0a0a0;--vscode-editor-foldBackground: rgba(38, 79, 120, .3);--vscode-editorGutter-foldingControlForeground: #c5c5c5;--vscode-editor-linkedEditingBackground: rgba(255, 0, 0, .3);--vscode-editor-wordHighlightBackground: rgba(87, 87, 87, .72);--vscode-editor-wordHighlightStrongBackground: rgba(0, 73, 114, .72);--vscode-editorOverviewRuler-wordHighlightForeground: rgba(160, 160, 160, .8);--vscode-editorOverviewRuler-wordHighlightStrongForeground: rgba(192, 160, 192, .8);--vscode-peekViewTitle-background: rgba(55, 148, 255, .1);--vscode-peekViewTitleLabel-foreground: #ffffff;--vscode-peekViewTitleDescription-foreground: rgba(204, 204, 204, .7);--vscode-peekView-border: #3794ff;--vscode-peekViewResult-background: #252526;--vscode-peekViewResult-lineForeground: #bbbbbb;--vscode-peekViewResult-fileForeground: #ffffff;--vscode-peekViewResult-selectionBackground: rgba(51, 153, 255, .2);--vscode-peekViewResult-selectionForeground: #ffffff;--vscode-peekViewEditor-background: #001f33;--vscode-peekViewEditorGutter-background: #001f33;--vscode-peekViewResult-matchHighlightBackground: rgba(234, 92, 0, .3);--vscode-peekViewEditor-matchHighlightBackground: rgba(255, 143, 0, .6);--vscode-editorMarkerNavigationError-background: #f14c4c;--vscode-editorMarkerNavigationError-headerBackground: rgba(241, 76, 76, .1);--vscode-editorMarkerNavigationWarning-background: #cca700;--vscode-editorMarkerNavigationWarning-headerBackground: rgba(204, 167, 0, .1);--vscode-editorMarkerNavigationInfo-background: #3794ff;--vscode-editorMarkerNavigationInfo-headerBackground: rgba(55, 148, 255, .1);--vscode-editorMarkerNavigation-background: #1e1e1e;--vscode-editorSuggestWidget-background: #252526;--vscode-editorSuggestWidget-border: #454545;--vscode-editorSuggestWidget-foreground: #d4d4d4;--vscode-editorSuggestWidget-selectedForeground: #ffffff;--vscode-editorSuggestWidget-selectedIconForeground: #ffffff;--vscode-editorSuggestWidget-selectedBackground: #04395e;--vscode-editorSuggestWidget-highlightForeground: #2aaaff;--vscode-editorSuggestWidget-focusHighlightForeground: #2aaaff;--vscode-editorSuggestWidgetStatus-foreground: rgba(212, 212, 212, .5);--vscode-tab-activeBackground: #1e1e1e;--vscode-tab-unfocusedActiveBackground: #1e1e1e;--vscode-tab-inactiveBackground: #2d2d2d;--vscode-tab-unfocusedInactiveBackground: #2d2d2d;--vscode-tab-activeForeground: #ffffff;--vscode-tab-inactiveForeground: rgba(255, 255, 255, .5);--vscode-tab-unfocusedActiveForeground: rgba(255, 255, 255, .5);--vscode-tab-unfocusedInactiveForeground: rgba(255, 255, 255, .25);--vscode-tab-border: #252526;--vscode-tab-lastPinnedBorder: rgba(204, 204, 204, .2);--vscode-tab-activeModifiedBorder: #3399cc;--vscode-tab-inactiveModifiedBorder: rgba(51, 153, 204, .5);--vscode-tab-unfocusedActiveModifiedBorder: rgba(51, 153, 204, .5);--vscode-tab-unfocusedInactiveModifiedBorder: rgba(51, 153, 204, .25);--vscode-editorPane-background: #1e1e1e;--vscode-editorGroupHeader-tabsBackground: #252526;--vscode-editorGroupHeader-noTabsBackground: #1e1e1e;--vscode-editorGroup-border: #444444;--vscode-editorGroup-dropBackground: rgba(83, 89, 93, .5);--vscode-editorGroup-dropIntoPromptForeground: #cccccc;--vscode-editorGroup-dropIntoPromptBackground: #252526;--vscode-sideBySideEditor-horizontalBorder: #444444;--vscode-sideBySideEditor-verticalBorder: #444444;--vscode-panel-background: #1e1e1e;--vscode-panel-border: rgba(128, 128, 128, .35);--vscode-panelTitle-activeForeground: #e7e7e7;--vscode-panelTitle-inactiveForeground: rgba(231, 231, 231, .6);--vscode-panelTitle-activeBorder: #e7e7e7;--vscode-panel-dropBorder: #e7e7e7;--vscode-panelSection-dropBackground: rgba(83, 89, 93, .5);--vscode-panelSectionHeader-background: rgba(128, 128, 128, .2);--vscode-panelSection-border: rgba(128, 128, 128, .35);--vscode-banner-background: #04395e;--vscode-banner-foreground: #ffffff;--vscode-banner-iconForeground: #3794ff;--vscode-statusBar-foreground: #ffffff;--vscode-statusBar-noFolderForeground: #ffffff;--vscode-statusBar-background: #007acc;--vscode-statusBar-noFolderBackground: #68217a;--vscode-statusBar-focusBorder: #ffffff;--vscode-statusBarItem-activeBackground: rgba(255, 255, 255, .18);--vscode-statusBarItem-focusBorder: #ffffff;--vscode-statusBarItem-hoverBackground: rgba(255, 255, 255, .12);--vscode-statusBarItem-compactHoverBackground: rgba(255, 255, 255, .2);--vscode-statusBarItem-prominentForeground: #ffffff;--vscode-statusBarItem-prominentBackground: rgba(0, 0, 0, .5);--vscode-statusBarItem-prominentHoverBackground: rgba(0, 0, 0, .3);--vscode-statusBarItem-errorBackground: #c72e0f;--vscode-statusBarItem-errorForeground: #ffffff;--vscode-statusBarItem-warningBackground: #7a6400;--vscode-statusBarItem-warningForeground: #ffffff;--vscode-activityBar-background: #333333;--vscode-activityBar-foreground: #ffffff;--vscode-activityBar-inactiveForeground: rgba(255, 255, 255, .4);--vscode-activityBar-activeBorder: #ffffff;--vscode-activityBar-dropBorder: #ffffff;--vscode-activityBarBadge-background: #007acc;--vscode-activityBarBadge-foreground: #ffffff;--vscode-statusBarItem-remoteBackground: #16825d;--vscode-statusBarItem-remoteForeground: #ffffff;--vscode-extensionBadge-remoteBackground: #007acc;--vscode-extensionBadge-remoteForeground: #ffffff;--vscode-sideBar-background: #252526;--vscode-sideBarTitle-foreground: #bbbbbb;--vscode-sideBar-dropBackground: rgba(83, 89, 93, .5);--vscode-sideBarSectionHeader-background: rgba(0, 0, 0, 0);--vscode-sideBarSectionHeader-border: rgba(204, 204, 204, .2);--vscode-titleBar-activeForeground: #cccccc;--vscode-titleBar-inactiveForeground: rgba(204, 204, 204, .6);--vscode-titleBar-activeBackground: #3c3c3c;--vscode-titleBar-inactiveBackground: rgba(60, 60, 60, .6);--vscode-menubar-selectionForeground: #cccccc;--vscode-menubar-selectionBackground: rgba(90, 93, 94, .31);--vscode-notifications-foreground: #cccccc;--vscode-notifications-background: #252526;--vscode-notificationLink-foreground: #3794ff;--vscode-notificationCenterHeader-background: #303031;--vscode-notifications-border: #303031;--vscode-notificationsErrorIcon-foreground: #f14c4c;--vscode-notificationsWarningIcon-foreground: #cca700;--vscode-notificationsInfoIcon-foreground: #3794ff;--vscode-commandCenter-foreground: #cccccc;--vscode-commandCenter-activeForeground: #cccccc;--vscode-commandCenter-activeBackground: rgba(90, 93, 94, .31);--vscode-commandCenter-border: rgba(128, 128, 128, .35);--vscode-editorCommentsWidget-resolvedBorder: rgba(204, 204, 204, .5);--vscode-editorCommentsWidget-unresolvedBorder: #3794ff;--vscode-editorCommentsWidget-rangeBackground: rgba(55, 148, 255, .1);--vscode-editorCommentsWidget-rangeBorder: rgba(55, 148, 255, .4);--vscode-editorCommentsWidget-rangeActiveBackground: rgba(55, 148, 255, .1);--vscode-editorCommentsWidget-rangeActiveBorder: rgba(55, 148, 255, .4);--vscode-editorGutter-commentRangeForeground: #37373d;--vscode-debugToolBar-background: #333333;--vscode-debugIcon-startForeground: #89d185;--vscode-editor-stackFrameHighlightBackground: rgba(255, 255, 0, .2);--vscode-editor-focusedStackFrameHighlightBackground: rgba(122, 189, 122, .3);--vscode-mergeEditor-change\.background: rgba(155, 185, 85, .2);--vscode-mergeEditor-change\.word\.background: rgba(156, 204, 44, .2);--vscode-mergeEditor-conflict\.unhandledUnfocused\.border: rgba(255, 166, 0, .48);--vscode-mergeEditor-conflict\.unhandledFocused\.border: #ffa600;--vscode-mergeEditor-conflict\.handledUnfocused\.border: rgba(134, 134, 134, .29);--vscode-mergeEditor-conflict\.handledFocused\.border: rgba(193, 193, 193, .8);--vscode-mergeEditor-conflict\.handled\.minimapOverViewRuler: rgba(173, 172, 168, .93);--vscode-mergeEditor-conflict\.unhandled\.minimapOverViewRuler: #fcba03;--vscode-mergeEditor-conflictingLines\.background: rgba(255, 234, 0, .28);--vscode-settings-headerForeground: #e7e7e7;--vscode-settings-modifiedItemIndicator: #0c7d9d;--vscode-settings-headerBorder: rgba(128, 128, 128, .35);--vscode-settings-sashBorder: rgba(128, 128, 128, .35);--vscode-settings-dropdownBackground: #3c3c3c;--vscode-settings-dropdownForeground: #f0f0f0;--vscode-settings-dropdownBorder: #3c3c3c;--vscode-settings-dropdownListBorder: #454545;--vscode-settings-checkboxBackground: #3c3c3c;--vscode-settings-checkboxForeground: #f0f0f0;--vscode-settings-checkboxBorder: #3c3c3c;--vscode-settings-textInputBackground: #3c3c3c;--vscode-settings-textInputForeground: #cccccc;--vscode-settings-numberInputBackground: #3c3c3c;--vscode-settings-numberInputForeground: #cccccc;--vscode-settings-focusedRowBackground: rgba(42, 45, 46, .6);--vscode-settings-rowHoverBackground: rgba(42, 45, 46, .3);--vscode-settings-focusedRowBorder: rgba(255, 255, 255, .12);--vscode-terminal-foreground: #cccccc;--vscode-terminal-selectionBackground: #264f78;--vscode-terminal-inactiveSelectionBackground: #3a3d41;--vscode-terminalCommandDecoration-defaultBackground: rgba(255, 255, 255, .25);--vscode-terminalCommandDecoration-successBackground: #1b81a8;--vscode-terminalCommandDecoration-errorBackground: #f14c4c;--vscode-terminalOverviewRuler-cursorForeground: rgba(160, 160, 160, .8);--vscode-terminal-border: rgba(128, 128, 128, .35);--vscode-terminal-findMatchBackground: #515c6a;--vscode-terminal-findMatchHighlightBackground: rgba(234, 92, 0, .33);--vscode-terminalOverviewRuler-findMatchForeground: rgba(209, 134, 22, .49);--vscode-terminal-dropBackground: rgba(83, 89, 93, .5);--vscode-testing-iconFailed: #f14c4c;--vscode-testing-iconErrored: #f14c4c;--vscode-testing-iconPassed: #73c991;--vscode-testing-runAction: #73c991;--vscode-testing-iconQueued: #cca700;--vscode-testing-iconUnset: #848484;--vscode-testing-iconSkipped: #848484;--vscode-testing-peekBorder: #f14c4c;--vscode-testing-peekHeaderBackground: rgba(241, 76, 76, .1);--vscode-testing-message\.error\.decorationForeground: #f14c4c;--vscode-testing-message\.error\.lineBackground: rgba(255, 0, 0, .2);--vscode-testing-message\.info\.decorationForeground: rgba(212, 212, 212, .5);--vscode-welcomePage-tileBackground: #252526;--vscode-welcomePage-tileHoverBackground: #2c2c2d;--vscode-welcomePage-tileShadow: rgba(0, 0, 0, .36);--vscode-welcomePage-progress\.background: #3c3c3c;--vscode-welcomePage-progress\.foreground: #3794ff;--vscode-debugExceptionWidget-border: #a31515;--vscode-debugExceptionWidget-background: #420b0d;--vscode-ports-iconRunningProcessForeground: #369432;--vscode-statusBar-debuggingBackground: #cc6633;--vscode-statusBar-debuggingForeground: #ffffff;--vscode-editor-inlineValuesForeground: rgba(255, 255, 255, .5);--vscode-editor-inlineValuesBackground: rgba(255, 200, 0, .2);--vscode-editorGutter-modifiedBackground: #1b81a8;--vscode-editorGutter-addedBackground: #487e02;--vscode-editorGutter-deletedBackground: #f14c4c;--vscode-minimapGutter-modifiedBackground: #1b81a8;--vscode-minimapGutter-addedBackground: #487e02;--vscode-minimapGutter-deletedBackground: #f14c4c;--vscode-editorOverviewRuler-modifiedForeground: rgba(27, 129, 168, .6);--vscode-editorOverviewRuler-addedForeground: rgba(72, 126, 2, .6);--vscode-editorOverviewRuler-deletedForeground: rgba(241, 76, 76, .6);--vscode-debugIcon-breakpointForeground: #e51400;--vscode-debugIcon-breakpointDisabledForeground: #848484;--vscode-debugIcon-breakpointUnverifiedForeground: #848484;--vscode-debugIcon-breakpointCurrentStackframeForeground: #ffcc00;--vscode-debugIcon-breakpointStackframeForeground: #89d185;--vscode-notebook-cellBorderColor: #37373d;--vscode-notebook-focusedEditorBorder: #007fd4;--vscode-notebookStatusSuccessIcon-foreground: #89d185;--vscode-notebookStatusErrorIcon-foreground: #f48771;--vscode-notebookStatusRunningIcon-foreground: #cccccc;--vscode-notebook-cellToolbarSeparator: rgba(128, 128, 128, .35);--vscode-notebook-selectedCellBackground: #37373d;--vscode-notebook-selectedCellBorder: #37373d;--vscode-notebook-focusedCellBorder: #007fd4;--vscode-notebook-inactiveFocusedCellBorder: #37373d;--vscode-notebook-cellStatusBarItemHoverBackground: rgba(255, 255, 255, .15);--vscode-notebook-cellInsertionIndicator: #007fd4;--vscode-notebookScrollbarSlider-background: rgba(121, 121, 121, .4);--vscode-notebookScrollbarSlider-hoverBackground: rgba(100, 100, 100, .7);--vscode-notebookScrollbarSlider-activeBackground: rgba(191, 191, 191, .4);--vscode-notebook-symbolHighlightBackground: rgba(255, 255, 255, .04);--vscode-notebook-cellEditorBackground: #252526;--vscode-notebook-editorBackground: #1e1e1e;--vscode-keybindingTable-headerBackground: rgba(204, 204, 204, .04);--vscode-keybindingTable-rowsBackground: rgba(204, 204, 204, .04);--vscode-scm-providerBorder: #454545;--vscode-debugTokenExpression-name: #c586c0;--vscode-debugTokenExpression-value: rgba(204, 204, 204, .6);--vscode-debugTokenExpression-string: #ce9178;--vscode-debugTokenExpression-boolean: #4e94ce;--vscode-debugTokenExpression-number: #b5cea8;--vscode-debugTokenExpression-error: #f48771;--vscode-debugView-exceptionLabelForeground: #cccccc;--vscode-debugView-exceptionLabelBackground: #6c2022;--vscode-debugView-stateLabelForeground: #cccccc;--vscode-debugView-stateLabelBackground: rgba(136, 136, 136, .27);--vscode-debugView-valueChangedHighlight: #569cd6;--vscode-debugConsole-infoForeground: #3794ff;--vscode-debugConsole-warningForeground: #cca700;--vscode-debugConsole-errorForeground: #f48771;--vscode-debugConsole-sourceForeground: #cccccc;--vscode-debugConsoleInputIcon-foreground: #cccccc;--vscode-debugIcon-pauseForeground: #75beff;--vscode-debugIcon-stopForeground: #f48771;--vscode-debugIcon-disconnectForeground: #f48771;--vscode-debugIcon-restartForeground: #89d185;--vscode-debugIcon-stepOverForeground: #75beff;--vscode-debugIcon-stepIntoForeground: #75beff;--vscode-debugIcon-stepOutForeground: #75beff;--vscode-debugIcon-continueForeground: #75beff;--vscode-debugIcon-stepBackForeground: #75beff;--vscode-extensionButton-prominentBackground: #0e639c;--vscode-extensionButton-prominentForeground: #ffffff;--vscode-extensionButton-prominentHoverBackground: #1177bb;--vscode-extensionIcon-starForeground: #ff8e00;--vscode-extensionIcon-verifiedForeground: #3794ff;--vscode-extensionIcon-preReleaseForeground: #1d9271;--vscode-extensionIcon-sponsorForeground: #d758b3;--vscode-terminal-ansiBlack: #000000;--vscode-terminal-ansiRed: #cd3131;--vscode-terminal-ansiGreen: #0dbc79;--vscode-terminal-ansiYellow: #e5e510;--vscode-terminal-ansiBlue: #2472c8;--vscode-terminal-ansiMagenta: #bc3fbc;--vscode-terminal-ansiCyan: #11a8cd;--vscode-terminal-ansiWhite: #e5e5e5;--vscode-terminal-ansiBrightBlack: #666666;--vscode-terminal-ansiBrightRed: #f14c4c;--vscode-terminal-ansiBrightGreen: #23d18b;--vscode-terminal-ansiBrightYellow: #f5f543;--vscode-terminal-ansiBrightBlue: #3b8eea;--vscode-terminal-ansiBrightMagenta: #d670d6;--vscode-terminal-ansiBrightCyan: #29b8db;--vscode-terminal-ansiBrightWhite: #e5e5e5;--vscode-interactive-activeCodeBorder: #3794ff;--vscode-interactive-inactiveCodeBorder: #37373d;--vscode-gitDecoration-addedResourceForeground: #81b88b;--vscode-gitDecoration-modifiedResourceForeground: #e2c08d;--vscode-gitDecoration-deletedResourceForeground: #c74e39;--vscode-gitDecoration-renamedResourceForeground: #73c991;--vscode-gitDecoration-untrackedResourceForeground: #73c991;--vscode-gitDecoration-ignoredResourceForeground: #8c8c8c;--vscode-gitDecoration-stageModifiedResourceForeground: #e2c08d;--vscode-gitDecoration-stageDeletedResourceForeground: #c74e39;--vscode-gitDecoration-conflictingResourceForeground: #e4676b;--vscode-gitDecoration-submoduleResourceForeground: #8db9e2}.cm-wrapper{line-height:18px}.cm-wrapper,.cm-wrapper>div{width:100%;height:100%}.CodeMirror span.cm-meta{color:var(--vscode-editor-foreground)}.CodeMirror span.cm-number{color:var(--vscode-debugTokenExpression-number)}.CodeMirror span.cm-keyword,.CodeMirror span.cm-builtin{color:var(--vscode-debugTokenExpression-name)}.CodeMirror span.cm-operator{color:var(--vscode-editor-foreground)}.CodeMirror span.cm-string,.CodeMirror span.cm-string-2{color:var(--vscode-debugTokenExpression-string)}.CodeMirror span.cm-error{color:var(--vscode-errorForeground)}.CodeMirror span.cm-def,.CodeMirror span.cm-tag{color:#0070c1}.CodeMirror span.cm-comment,.CodeMirror span.cm-link{color:green}.CodeMirror span.cm-variable,.CodeMirror span.cm-variable-2,.CodeMirror span.cm-atom{color:#0070c1}.CodeMirror span.cm-property{color:#795e26}.CodeMirror span.cm-qualifier,.CodeMirror span.cm-attribute{color:#001080}.CodeMirror span.cm-variable-3,.CodeMirror span.cm-type{color:#267f99}:root.dark-mode .CodeMirror span.cm-def,:root.dark-mode .CodeMirror span.cm-tag{color:var(--vscode-debugView-valueChangedHighlight)}:root.dark-mode .CodeMirror span.cm-comment,:root.dark-mode .CodeMirror span.cm-link{color:#6a9955}:root.dark-mode .CodeMirror span.cm-variable,:root.dark-mode .CodeMirror span.cm-variable-2,:root.dark-mode .CodeMirror span.cm-atom{color:#4fc1ff}:root.dark-mode .CodeMirror span.cm-property{color:#dcdcaa}:root.dark-mode .CodeMirror span.cm-qualifier,:root.dark-mode .CodeMirror span.cm-attribute{color:#9cdcfe}:root.dark-mode .CodeMirror span.cm-variable-3,:root.dark-mode .CodeMirror span.cm-type{color:#4ec9b0}.CodeMirror span.cm-bracket{color:var(--vscode-editorBracketHighlight-foreground3)}.CodeMirror-cursor{border-left:1px solid var(--vscode-editor-foreground)!important}.CodeMirror div.CodeMirror-selected{background:var(--vscode-terminal-inactiveSelectionBackground)}.CodeMirror .CodeMirror-gutters{z-index:0;background:1px solid var(--vscode-editorGroup-border);border-right:none}.CodeMirror .CodeMirror-gutter-elt{background-color:var(--vscode-editorGutter-background)}.CodeMirror .CodeMirror-gutterwrapper{border-right:1px solid var(--vscode-editorGroup-border);color:var(--vscode-editorLineNumber-foreground)}.CodeMirror .CodeMirror-matchingbracket{background-color:var(--vscode-editorBracketPairGuide-background1);color:var(--vscode-editorBracketHighlight-foreground1)!important}.CodeMirror{font-family:var(--vscode-editor-font-family)!important;color:var(--vscode-editor-foreground)!important;background-color:var(--vscode-editor-background)!important;font-weight:var(--vscode-editor-font-weight)!important;font-size:var(--vscode-editor-font-size)!important}.CodeMirror .source-line-running{background-color:var(--vscode-editor-selectionBackground);z-index:2}.CodeMirror .source-line-paused{background-color:var(--vscode-editor-selectionHighlightBackground);z-index:2}.CodeMirror .source-line-error-widget{background-color:var(--vscode-inputValidation-errorBackground);white-space:pre-wrap;margin:3px 10px;padding:5px}.CodeMirror span.cm-link,span.cm-linkified{color:var(--vscode-textLink-foreground);text-decoration:underline;cursor:pointer}.CodeMirror .source-line-error-underline{text-decoration:underline;text-decoration-color:var(--vscode-errorForeground);text-decoration-style:wavy}.CodeMirror-placeholder{color:var(--vscode-input-placeholderForeground)!important}.CodeMirror-dialog-top{padding-top:8px!important}.split-view{display:flex;flex:auto;position:relative}.split-view.vertical{flex-direction:column}.split-view.vertical.sidebar-first{flex-direction:column-reverse}.split-view.horizontal{flex-direction:row}.split-view.horizontal.sidebar-first{flex-direction:row-reverse}.split-view-main{display:flex;flex:auto}.split-view-sidebar{display:flex;flex:none}.split-view.vertical:not(.sidebar-first)>.split-view-sidebar{border-top:1px solid var(--vscode-panel-border)}.split-view.horizontal:not(.sidebar-first)>.split-view-sidebar{border-left:1px solid var(--vscode-panel-border)}.split-view.vertical.sidebar-first>.split-view-sidebar{border-bottom:1px solid var(--vscode-panel-border)}.split-view.horizontal.sidebar-first>.split-view-sidebar{border-right:1px solid var(--vscode-panel-border)}.split-view-resizer{position:absolute;z-index:100}.split-view.vertical>.split-view-resizer{left:0;right:0;height:12px;cursor:ns-resize}.split-view.horizontal>.split-view-resizer{top:0;bottom:0;width:12px;cursor:ew-resize}.tabbed-pane{display:flex;flex:auto;overflow:hidden}.tabbed-pane .toolbar{background-color:var(--vscode-sideBar-background)}.tabbed-pane .tab-content{display:flex;flex:auto;overflow:hidden;position:relative;flex-direction:column}.tabbed-pane-tab{padding:2px 6px 0;cursor:pointer;display:flex;align-items:center;justify-content:center;-webkit-user-select:none;user-select:none;border-bottom:2px solid transparent;outline:none;height:100%}.tabbed-pane-tab-label{max-width:250px;white-space:pre;overflow:hidden;text-overflow:ellipsis;display:inline-block}.tabbed-pane-tab.selected{background-color:var(--vscode-tab-activeBackground)}.tabbed-pane-tab-counter{padding:0 4px;background:var(--vscode-menu-separatorBackground);border-radius:8px;height:16px;margin-left:4px;line-height:16px;min-width:18px;display:flex;align-items:center;justify-content:center}.tabbed-pane-tab-counter.error{background:var(--vscode-list-errorForeground);color:var(--vscode-button-foreground)}.toolbar{position:relative;display:flex;color:var(--vscode-sideBarTitle-foreground);min-height:30px;align-items:center;flex:none;padding-right:4px}.toolbar.toolbar-sidebar-background{background-color:var(--vscode-sideBar-background)}.toolbar:after{content:"";display:block;position:absolute;pointer-events:none;top:0;bottom:0;left:-2px;right:-2px;box-shadow:var(--vscode-scrollbar-shadow) 0 6px 6px -6px;z-index:100}.toolbar.no-shadow:after{box-shadow:none}.toolbar.no-min-height{min-height:0}.toolbar input{padding:0 5px;line-height:24px;outline:none;margin:0 4px}.toolbar select{background:none;outline:none;padding:3px;margin:2px}.toolbar option{background-color:var(--vscode-tab-activeBackground)}.toolbar input,.toolbar select{border:none;color:var(--vscode-input-foreground);background-color:var(--vscode-input-background)}.toolbar-button{flex:none;border:none;outline:none;color:var(--vscode-sideBarTitle-foreground);background:transparent;padding:4px;cursor:pointer;display:inline-flex;align-items:center}.toolbar-button:disabled{color:var(--vscode-disabledForeground)!important;cursor:default}.toolbar-button:not(:disabled):hover{background-color:var(--vscode-toolbar-hoverBackground)}.toolbar-button:not(:disabled):active{background-color:var(--vscode-toolbar-activeBackground)}.toolbar-button.toggled{color:var(--vscode-notificationLink-foreground)}.toolbar-separator{flex:none;background-color:var(--vscode-menu-separatorBackground);width:1px;padding:0;margin:5px 4px;height:16px}.call-log{display:flex;flex-direction:column;flex:auto;line-height:20px;white-space:pre;overflow:auto}.call-log-message{flex:none;padding:3px 0 3px 36px;display:flex;align-items:center}.call-log-call{display:flex;flex:none;flex-direction:column;border-top:1px solid var(--vscode-panel-border)}.call-log-call-header{height:24px;display:flex;align-items:center;padding:0 2px;z-index:2}.call-log-call .codicon{padding:0 4px;flex:none}.call-log .codicon-check{color:#21a945;font-weight:700}.call-log-call.error{background-color:var(--vscode-inputValidation-errorBackground);border-top:1px solid var(--vscode-panel-border)}.call-log-call.error .call-log-call-header,.call-log-message.error,.call-log .codicon-error{color:var(--vscode-errorForeground)}.call-log-details{flex:0 1 auto;overflow-x:hidden;text-overflow:ellipsis}.call-log-url{color:var(--vscode-charts-blue)}.call-log-selector{color:var(--vscode-charts-orange);white-space:nowrap}.call-log-time{flex:none;margin-left:4px;color:var(--gray)}.call-log-call .codicon.preview{visibility:hidden;color:var(--vscode-sideBarTitle-foreground);cursor:pointer}.call-log-call .codicon.preview:hover{color:inherit}.call-log-call:hover .codicon.preview{visibility:visible}.recorder{display:flex;flex-direction:column;flex:auto}.recorder-chooser{border:none;background:none;outline:none;color:var(--vscode-sideBarTitle-foreground);min-width:100px}.recorder .codicon{font-size:16px}.recorder .codicon.circle-large-filled,.recorder .codicon.stop-circle{font-size:15px}.recorder .toolbar-button.toggled.stop-circle{color:#a1260d}:root.dark-mode .recorder .toolbar-button.toggled.stop-circle{color:#f48771}.recorder .toolbar-button:not([disabled]) .codicon-debug-continue,.recorder .toolbar-button:not([disabled]) .codicon-debug-step-over{color:#01bb01}.recorder .toolbar-button:not([disabled]):hover .codicon-debug-continue,.recorder .toolbar-button:not([disabled]):hover .codicon-debug-step-over{color:#41ca1e}.recorder .selector-input{flex:auto}.setting{display:flex;align-items:center}.setting-theme{display:grid;margin-left:22px}.setting label{text-overflow:ellipsis;white-space:nowrap;overflow:hidden;cursor:pointer}.setting input{margin-right:5px;flex-shrink:0} diff --git a/skills/playwright-scraper-skill-1-2-0/node_modules/playwright-core/lib/vite/recorder/assets/index-BhTWtUlo.js b/skills/playwright-scraper-skill-1-2-0/node_modules/playwright-core/lib/vite/recorder/assets/index-BhTWtUlo.js new file mode 100644 index 0000000..0fbeec3 --- /dev/null +++ b/skills/playwright-scraper-skill-1-2-0/node_modules/playwright-core/lib/vite/recorder/assets/index-BhTWtUlo.js @@ -0,0 +1,193 @@ +const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/codeMirrorModule-DadYNm1I.js","assets/codeMirrorModule-DYBRYzYX.css"])))=>i.map(i=>d[i]); +(function(){const l=document.createElement("link").relList;if(l&&l.supports&&l.supports("modulepreload"))return;for(const c of document.querySelectorAll('link[rel="modulepreload"]'))u(c);new MutationObserver(c=>{for(const o of c)if(o.type==="childList")for(const h of o.addedNodes)h.tagName==="LINK"&&h.rel==="modulepreload"&&u(h)}).observe(document,{childList:!0,subtree:!0});function i(c){const o={};return c.integrity&&(o.integrity=c.integrity),c.referrerPolicy&&(o.referrerPolicy=c.referrerPolicy),c.crossOrigin==="use-credentials"?o.credentials="include":c.crossOrigin==="anonymous"?o.credentials="omit":o.credentials="same-origin",o}function u(c){if(c.ep)return;c.ep=!0;const o=i(c);fetch(c.href,o)}})();function v1(s){return s&&s.__esModule&&Object.prototype.hasOwnProperty.call(s,"default")?s.default:s}var lf={exports:{}},Oi={};/** + * @license React + * react-jsx-runtime.production.js + * + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */var Wm;function b1(){if(Wm)return Oi;Wm=1;var s=Symbol.for("react.transitional.element"),l=Symbol.for("react.fragment");function i(u,c,o){var h=null;if(o!==void 0&&(h=""+o),c.key!==void 0&&(h=""+c.key),"key"in c){o={};for(var m in c)m!=="key"&&(o[m]=c[m])}else o=c;return c=o.ref,{$$typeof:s,type:u,key:h,ref:c!==void 0?c:null,props:o}}return Oi.Fragment=l,Oi.jsx=i,Oi.jsxs=i,Oi}var Fm;function S1(){return Fm||(Fm=1,lf.exports=b1()),lf.exports}var Z=S1(),af={exports:{}},se={};/** + * @license React + * react.production.js + * + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */var Im;function T1(){if(Im)return se;Im=1;var s=Symbol.for("react.transitional.element"),l=Symbol.for("react.portal"),i=Symbol.for("react.fragment"),u=Symbol.for("react.strict_mode"),c=Symbol.for("react.profiler"),o=Symbol.for("react.consumer"),h=Symbol.for("react.context"),m=Symbol.for("react.forward_ref"),g=Symbol.for("react.suspense"),p=Symbol.for("react.memo"),E=Symbol.for("react.lazy"),v=Symbol.for("react.activity"),_=Symbol.iterator;function A(O){return O===null||typeof O!="object"?null:(O=_&&O[_]||O["@@iterator"],typeof O=="function"?O:null)}var z={isMounted:function(){return!1},enqueueForceUpdate:function(){},enqueueReplaceState:function(){},enqueueSetState:function(){}},S=Object.assign,T={};function x(O,$,J){this.props=O,this.context=$,this.refs=T,this.updater=J||z}x.prototype.isReactComponent={},x.prototype.setState=function(O,$){if(typeof O!="object"&&typeof O!="function"&&O!=null)throw Error("takes an object of state variables to update or a function which returns an object of state variables.");this.updater.enqueueSetState(this,O,$,"setState")},x.prototype.forceUpdate=function(O){this.updater.enqueueForceUpdate(this,O,"forceUpdate")};function j(){}j.prototype=x.prototype;function Y(O,$,J){this.props=O,this.context=$,this.refs=T,this.updater=J||z}var X=Y.prototype=new j;X.constructor=Y,S(X,x.prototype),X.isPureReactComponent=!0;var W=Array.isArray;function K(){}var G={H:null,A:null,T:null,S:null},V=Object.prototype.hasOwnProperty;function B(O,$,J){var I=J.ref;return{$$typeof:s,type:O,key:$,ref:I!==void 0?I:null,props:J}}function he(O,$){return B(O.type,$,O.props)}function ne(O){return typeof O=="object"&&O!==null&&O.$$typeof===s}function q(O){var $={"=":"=0",":":"=2"};return"$"+O.replace(/[=:]/g,function(J){return $[J]})}var le=/\/+/g;function ze(O,$){return typeof O=="object"&&O!==null&&O.key!=null?q(""+O.key):$.toString(36)}function ie(O){switch(O.status){case"fulfilled":return O.value;case"rejected":throw O.reason;default:switch(typeof O.status=="string"?O.then(K,K):(O.status="pending",O.then(function($){O.status==="pending"&&(O.status="fulfilled",O.value=$)},function($){O.status==="pending"&&(O.status="rejected",O.reason=$)})),O.status){case"fulfilled":return O.value;case"rejected":throw O.reason}}throw O}function D(O,$,J,I,ce){var me=typeof O;(me==="undefined"||me==="boolean")&&(O=null);var Ae=!1;if(O===null)Ae=!0;else switch(me){case"bigint":case"string":case"number":Ae=!0;break;case"object":switch(O.$$typeof){case s:case l:Ae=!0;break;case E:return Ae=O._init,D(Ae(O._payload),$,J,I,ce)}}if(Ae)return ce=ce(O),Ae=I===""?"."+ze(O,0):I,W(ce)?(J="",Ae!=null&&(J=Ae.replace(le,"$&/")+"/"),D(ce,$,J,"",function(Da){return Da})):ce!=null&&(ne(ce)&&(ce=he(ce,J+(ce.key==null||O&&O.key===ce.key?"":(""+ce.key).replace(le,"$&/")+"/")+Ae)),$.push(ce)),1;Ae=0;var rt=I===""?".":I+":";if(W(O))for(var $e=0;$e{const c=s==null?void 0:s.current;c&&i(c.getBoundingClientRect())},[s]);return wn.useLayoutEffect(()=>{const c=s==null?void 0:s.current;if(!c)return;u();const o=new ResizeObserver(u);return o.observe(c),window.addEventListener("resize",u),()=>{o.disconnect(),window.removeEventListener("resize",u)}},[u,s]),[l,u]}function E1(s){if(s<0||!isFinite(s))return"-";if(s===0)return"0";if(s<1e3)return s.toFixed(0)+"ms";const l=s/1e3;if(l<60)return l.toFixed(1)+"s";const i=l/60;if(i<60)return i.toFixed(1)+"m";const u=i/60;return u<24?u.toFixed(1)+"h":(u/24).toFixed(1)+"d"}function eg(s){const l=document.createElement("textarea");l.style.position="absolute",l.style.zIndex="-1000",l.value=s,document.body.appendChild(l),l.select(),document.execCommand("copy"),l.remove()}function pu(s,l){s&&(l=bl.getObject(s,l));const[i,u]=wn.useState(l),c=wn.useCallback(o=>{s?bl.setObject(s,o):u(o)},[s,u]);return wn.useEffect(()=>{if(s){const o=()=>u(bl.getObject(s,l));return bl.onChangeEmitter.addEventListener(s,o),()=>bl.onChangeEmitter.removeEventListener(s,o)}},[l,s]),[i,c]}class A1{constructor(){this.onChangeEmitter=new EventTarget}getString(l,i){return localStorage[l]||i}setString(l,i){var u;localStorage[l]=i,this.onChangeEmitter.dispatchEvent(new Event(l)),(u=window.saveSettings)==null||u.call(window)}getObject(l,i){if(!localStorage[l])return i;try{return JSON.parse(localStorage[l])}catch{return i}}setObject(l,i){var u;localStorage[l]=JSON.stringify(i),this.onChangeEmitter.dispatchEvent(new Event(l)),(u=window.saveSettings)==null||u.call(window)}}const bl=new A1;function wl(...s){return s.filter(Boolean).join(" ")}const tg="\\u0000-\\u0020\\u007f-\\u009f",w1=new RegExp("(?:[a-zA-Z][a-zA-Z0-9+.-]{2,}:\\/\\/|www\\.)[^\\s"+tg+'"]{2,}[^\\s'+tg+`"')}\\],:;.!?]`,"ug"),O1="system",Cg="theme",_1=[{label:"Dark mode",value:"dark-mode"},{label:"Light mode",value:"light-mode"},{label:"System",value:"system"}],zg=window.matchMedia("(prefers-color-scheme: dark)");function N1(){document.playwrightThemeInitialized||(document.playwrightThemeInitialized=!0,document.defaultView.addEventListener("focus",s=>{s.target.document.nodeType===Node.DOCUMENT_NODE&&document.body.classList.remove("inactive")},!1),document.defaultView.addEventListener("blur",s=>{document.body.classList.add("inactive")},!1),Tf(Ef()),zg.addEventListener("change",()=>{Tf(Ef())}))}const M1=new Set;function Tf(s){const l=C1(),i=s==="system"?zg.matches?"dark-mode":"light-mode":s;if(l!==i){l&&document.documentElement.classList.remove(l),document.documentElement.classList.add(i);for(const u of M1)u(i)}}function Ef(){return bl.getString(Cg,O1)}function C1(){return document.documentElement.classList.contains("dark-mode")?"dark-mode":document.documentElement.classList.contains("light-mode")?"light-mode":null}function z1(){const[s,l]=wn.useState(Ef());return wn.useEffect(()=>{bl.setString(Cg,s),Tf(s)},[s]),[s,l]}var sf={exports:{}},_i={},uf={exports:{}},cf={};/** + * @license React + * scheduler.production.js + * + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */var ng;function x1(){return ng||(ng=1,(function(s){function l(D,Q){var ee=D.length;D.push(Q);e:for(;0>>1,_e=D[de];if(0>>1;dec(J,ee))I<_e&&0>c(ce,J)?(D[de]=ce,D[I]=ee,de=I):(D[de]=J,D[$]=ee,de=$);else if(I<_e&&0>c(ce,ee))D[de]=ce,D[I]=ee,de=I;else break e}}return Q}function c(D,Q){var ee=D.sortIndex-Q.sortIndex;return ee!==0?ee:D.id-Q.id}if(s.unstable_now=void 0,typeof performance=="object"&&typeof performance.now=="function"){var o=performance;s.unstable_now=function(){return o.now()}}else{var h=Date,m=h.now();s.unstable_now=function(){return h.now()-m}}var g=[],p=[],E=1,v=null,_=3,A=!1,z=!1,S=!1,T=!1,x=typeof setTimeout=="function"?setTimeout:null,j=typeof clearTimeout=="function"?clearTimeout:null,Y=typeof setImmediate<"u"?setImmediate:null;function X(D){for(var Q=i(p);Q!==null;){if(Q.callback===null)u(p);else if(Q.startTime<=D)u(p),Q.sortIndex=Q.expirationTime,l(g,Q);else break;Q=i(p)}}function W(D){if(S=!1,X(D),!z)if(i(g)!==null)z=!0,K||(K=!0,q());else{var Q=i(p);Q!==null&&ie(W,Q.startTime-D)}}var K=!1,G=-1,V=5,B=-1;function he(){return T?!0:!(s.unstable_now()-BD&&he());){var de=v.callback;if(typeof de=="function"){v.callback=null,_=v.priorityLevel;var _e=de(v.expirationTime<=D);if(D=s.unstable_now(),typeof _e=="function"){v.callback=_e,X(D),Q=!0;break t}v===i(g)&&u(g),X(D)}else u(g);v=i(g)}if(v!==null)Q=!0;else{var O=i(p);O!==null&&ie(W,O.startTime-D),Q=!1}}break e}finally{v=null,_=ee,A=!1}Q=void 0}}finally{Q?q():K=!1}}}var q;if(typeof Y=="function")q=function(){Y(ne)};else if(typeof MessageChannel<"u"){var le=new MessageChannel,ze=le.port2;le.port1.onmessage=ne,q=function(){ze.postMessage(null)}}else q=function(){x(ne,0)};function ie(D,Q){G=x(function(){D(s.unstable_now())},Q)}s.unstable_IdlePriority=5,s.unstable_ImmediatePriority=1,s.unstable_LowPriority=4,s.unstable_NormalPriority=3,s.unstable_Profiling=null,s.unstable_UserBlockingPriority=2,s.unstable_cancelCallback=function(D){D.callback=null},s.unstable_forceFrameRate=function(D){0>D||125de?(D.sortIndex=ee,l(p,D),i(g)===null&&D===i(p)&&(S?(j(G),G=-1):S=!0,ie(W,ee-de))):(D.sortIndex=_e,l(g,D),z||A||(z=!0,K||(K=!0,q()))),D},s.unstable_shouldYield=he,s.unstable_wrapCallback=function(D){var Q=_;return function(){var ee=_;_=Q;try{return D.apply(this,arguments)}finally{_=ee}}}})(cf)),cf}var lg;function D1(){return lg||(lg=1,uf.exports=x1()),uf.exports}var rf={exports:{}},st={};/** + * @license React + * react-dom.production.js + * + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */var ag;function L1(){if(ag)return st;ag=1;var s=xf();function l(g){var p="https://react.dev/errors/"+g;if(1"u"||typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE!="function"))try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(s)}catch(l){console.error(l)}}return s(),rf.exports=L1(),rf.exports}/** + * @license React + * react-dom-client.production.js + * + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */var sg;function j1(){if(sg)return _i;sg=1;var s=D1(),l=xf(),i=U1();function u(e){var t="https://react.dev/errors/"+e;if(1_e||(e.current=de[_e],de[_e]=null,_e--)}function J(e,t){_e++,de[_e]=e.current,e.current=t}var I=O(null),ce=O(null),me=O(null),Ae=O(null);function rt(e,t){switch(J(me,t),J(ce,e),J(I,null),t.nodeType){case 9:case 11:e=(e=t.documentElement)&&(e=e.namespaceURI)?bm(e):0;break;default:if(e=t.tagName,t=t.namespaceURI)t=bm(t),e=Sm(t,e);else switch(e){case"svg":e=1;break;case"math":e=2;break;default:e=0}}$(I),J(I,e)}function $e(){$(I),$(ce),$(me)}function Da(e){e.memoizedState!==null&&J(Ae,e);var t=I.current,n=Sm(t,e.type);t!==n&&(J(ce,e),J(I,n))}function ki(e){ce.current===e&&($(I),$(ce)),Ae.current===e&&($(Ae),Ti._currentValue=ee)}var qu,Zf;function el(e){if(qu===void 0)try{throw Error()}catch(n){var t=n.stack.trim().match(/\n( *(at )?)/);qu=t&&t[1]||"",Zf=-1)":-1r||b[a]!==C[r]){var R=` +`+b[a].replace(" at new "," at ");return e.displayName&&R.includes("")&&(R=R.replace("",e.displayName)),R}while(1<=a&&0<=r);break}}}finally{Hu=!1,Error.prepareStackTrace=n}return(n=e?e.displayName||e.name:"")?el(n):""}function Jp(e,t){switch(e.tag){case 26:case 27:case 5:return el(e.type);case 16:return el("Lazy");case 13:return e.child!==t&&t!==null?el("Suspense Fallback"):el("Suspense");case 19:return el("SuspenseList");case 0:case 15:return $u(e.type,!1);case 11:return $u(e.type.render,!1);case 1:return $u(e.type,!0);case 31:return el("Activity");default:return""}}function Jf(e){try{var t="",n=null;do t+=Jp(e,n),n=e,e=e.return;while(e);return t}catch(a){return` +Error generating stack: `+a.message+` +`+a.stack}}var Yu=Object.prototype.hasOwnProperty,Gu=s.unstable_scheduleCallback,Ku=s.unstable_cancelCallback,Wp=s.unstable_shouldYield,Fp=s.unstable_requestPaint,Et=s.unstable_now,Ip=s.unstable_getCurrentPriorityLevel,Wf=s.unstable_ImmediatePriority,Ff=s.unstable_UserBlockingPriority,qi=s.unstable_NormalPriority,Pp=s.unstable_LowPriority,If=s.unstable_IdlePriority,ey=s.log,ty=s.unstable_setDisableYieldValue,La=null,At=null;function _n(e){if(typeof ey=="function"&&ty(e),At&&typeof At.setStrictMode=="function")try{At.setStrictMode(La,e)}catch{}}var wt=Math.clz32?Math.clz32:ay,ny=Math.log,ly=Math.LN2;function ay(e){return e>>>=0,e===0?32:31-(ny(e)/ly|0)|0}var Hi=256,$i=262144,Yi=4194304;function tl(e){var t=e&42;if(t!==0)return t;switch(e&-e){case 1:return 1;case 2:return 2;case 4:return 4;case 8:return 8;case 16:return 16;case 32:return 32;case 64:return 64;case 128:return 128;case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:return e&261888;case 262144:case 524288:case 1048576:case 2097152:return e&3932160;case 4194304:case 8388608:case 16777216:case 33554432:return e&62914560;case 67108864:return 67108864;case 134217728:return 134217728;case 268435456:return 268435456;case 536870912:return 536870912;case 1073741824:return 0;default:return e}}function Gi(e,t,n){var a=e.pendingLanes;if(a===0)return 0;var r=0,f=e.suspendedLanes,d=e.pingedLanes;e=e.warmLanes;var y=a&134217727;return y!==0?(a=y&~f,a!==0?r=tl(a):(d&=y,d!==0?r=tl(d):n||(n=y&~e,n!==0&&(r=tl(n))))):(y=a&~f,y!==0?r=tl(y):d!==0?r=tl(d):n||(n=a&~e,n!==0&&(r=tl(n)))),r===0?0:t!==0&&t!==r&&(t&f)===0&&(f=r&-r,n=t&-t,f>=n||f===32&&(n&4194048)!==0)?t:r}function Ua(e,t){return(e.pendingLanes&~(e.suspendedLanes&~e.pingedLanes)&t)===0}function iy(e,t){switch(e){case 1:case 2:case 4:case 8:case 64:return t+250;case 16:case 32:case 128:case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:case 262144:case 524288:case 1048576:case 2097152:return t+5e3;case 4194304:case 8388608:case 16777216:case 33554432:return-1;case 67108864:case 134217728:case 268435456:case 536870912:case 1073741824:return-1;default:return-1}}function Pf(){var e=Yi;return Yi<<=1,(Yi&62914560)===0&&(Yi=4194304),e}function Vu(e){for(var t=[],n=0;31>n;n++)t.push(e);return t}function ja(e,t){e.pendingLanes|=t,t!==268435456&&(e.suspendedLanes=0,e.pingedLanes=0,e.warmLanes=0)}function sy(e,t,n,a,r,f){var d=e.pendingLanes;e.pendingLanes=n,e.suspendedLanes=0,e.pingedLanes=0,e.warmLanes=0,e.expiredLanes&=n,e.entangledLanes&=n,e.errorRecoveryDisabledLanes&=n,e.shellSuspendCounter=0;var y=e.entanglements,b=e.expirationTimes,C=e.hiddenUpdates;for(n=d&~n;0"u")return null;try{return e.activeElement||e.body}catch{return e.body}}var hy=/[\n"\\]/g;function jt(e){return e.replace(hy,function(t){return"\\"+t.charCodeAt(0).toString(16)+" "})}function Fu(e,t,n,a,r,f,d,y){e.name="",d!=null&&typeof d!="function"&&typeof d!="symbol"&&typeof d!="boolean"?e.type=d:e.removeAttribute("type"),t!=null?d==="number"?(t===0&&e.value===""||e.value!=t)&&(e.value=""+Ut(t)):e.value!==""+Ut(t)&&(e.value=""+Ut(t)):d!=="submit"&&d!=="reset"||e.removeAttribute("value"),t!=null?Iu(e,d,Ut(t)):n!=null?Iu(e,d,Ut(n)):a!=null&&e.removeAttribute("value"),r==null&&f!=null&&(e.defaultChecked=!!f),r!=null&&(e.checked=r&&typeof r!="function"&&typeof r!="symbol"),y!=null&&typeof y!="function"&&typeof y!="symbol"&&typeof y!="boolean"?e.name=""+Ut(y):e.removeAttribute("name")}function ho(e,t,n,a,r,f,d,y){if(f!=null&&typeof f!="function"&&typeof f!="symbol"&&typeof f!="boolean"&&(e.type=f),t!=null||n!=null){if(!(f!=="submit"&&f!=="reset"||t!=null)){Wu(e);return}n=n!=null?""+Ut(n):"",t=t!=null?""+Ut(t):n,y||t===e.value||(e.value=t),e.defaultValue=t}a=a??r,a=typeof a!="function"&&typeof a!="symbol"&&!!a,e.checked=y?e.checked:!!a,e.defaultChecked=!!a,d!=null&&typeof d!="function"&&typeof d!="symbol"&&typeof d!="boolean"&&(e.name=d),Wu(e)}function Iu(e,t,n){t==="number"&&Qi(e.ownerDocument)===e||e.defaultValue===""+n||(e.defaultValue=""+n)}function Ll(e,t,n,a){if(e=e.options,t){t={};for(var r=0;r"u"||typeof window.document>"u"||typeof window.document.createElement>"u"),lc=!1;if(sn)try{var qa={};Object.defineProperty(qa,"passive",{get:function(){lc=!0}}),window.addEventListener("test",qa,qa),window.removeEventListener("test",qa,qa)}catch{lc=!1}var Mn=null,ac=null,Zi=null;function So(){if(Zi)return Zi;var e,t=ac,n=t.length,a,r="value"in Mn?Mn.value:Mn.textContent,f=r.length;for(e=0;e=Ya),_o=" ",No=!1;function Mo(e,t){switch(e){case"keyup":return Hy.indexOf(t.keyCode)!==-1;case"keydown":return t.keyCode!==229;case"keypress":case"mousedown":case"focusout":return!0;default:return!1}}function Co(e){return e=e.detail,typeof e=="object"&&"data"in e?e.data:null}var Rl=!1;function Yy(e,t){switch(e){case"compositionend":return Co(t);case"keypress":return t.which!==32?null:(No=!0,_o);case"textInput":return e=t.data,e===_o&&No?null:e;default:return null}}function Gy(e,t){if(Rl)return e==="compositionend"||!rc&&Mo(e,t)?(e=So(),Zi=ac=Mn=null,Rl=!1,e):null;switch(e){case"paste":return null;case"keypress":if(!(t.ctrlKey||t.altKey||t.metaKey)||t.ctrlKey&&t.altKey){if(t.char&&1=t)return{node:n,offset:t-e};e=a}e:{for(;n;){if(n.nextSibling){n=n.nextSibling;break e}n=n.parentNode}n=void 0}n=Ro(n)}}function qo(e,t){return e&&t?e===t?!0:e&&e.nodeType===3?!1:t&&t.nodeType===3?qo(e,t.parentNode):"contains"in e?e.contains(t):e.compareDocumentPosition?!!(e.compareDocumentPosition(t)&16):!1:!1}function Ho(e){e=e!=null&&e.ownerDocument!=null&&e.ownerDocument.defaultView!=null?e.ownerDocument.defaultView:window;for(var t=Qi(e.document);t instanceof e.HTMLIFrameElement;){try{var n=typeof t.contentWindow.location.href=="string"}catch{n=!1}if(n)e=t.contentWindow;else break;t=Qi(e.document)}return t}function hc(e){var t=e&&e.nodeName&&e.nodeName.toLowerCase();return t&&(t==="input"&&(e.type==="text"||e.type==="search"||e.type==="tel"||e.type==="url"||e.type==="password")||t==="textarea"||e.contentEditable==="true")}var Fy=sn&&"documentMode"in document&&11>=document.documentMode,kl=null,dc=null,Qa=null,mc=!1;function $o(e,t,n){var a=n.window===n?n.document:n.nodeType===9?n:n.ownerDocument;mc||kl==null||kl!==Qi(a)||(a=kl,"selectionStart"in a&&hc(a)?a={start:a.selectionStart,end:a.selectionEnd}:(a=(a.ownerDocument&&a.ownerDocument.defaultView||window).getSelection(),a={anchorNode:a.anchorNode,anchorOffset:a.anchorOffset,focusNode:a.focusNode,focusOffset:a.focusOffset}),Qa&&Va(Qa,a)||(Qa=a,a=$s(dc,"onSelect"),0>=d,r-=d,Ft=1<<32-wt(t)+r|n<fe?(ve=P,P=null):ve=P.sibling;var Te=L(N,P,M[fe],k);if(Te===null){P===null&&(P=ve);break}e&&P&&Te.alternate===null&&t(N,P),w=f(Te,w,fe),Se===null?te=Te:Se.sibling=Te,Se=Te,P=ve}if(fe===M.length)return n(N,P),be&&cn(N,fe),te;if(P===null){for(;fefe?(ve=P,P=null):ve=P.sibling;var Wn=L(N,P,Te.value,k);if(Wn===null){P===null&&(P=ve);break}e&&P&&Wn.alternate===null&&t(N,P),w=f(Wn,w,fe),Se===null?te=Wn:Se.sibling=Wn,Se=Wn,P=ve}if(Te.done)return n(N,P),be&&cn(N,fe),te;if(P===null){for(;!Te.done;fe++,Te=M.next())Te=H(N,Te.value,k),Te!==null&&(w=f(Te,w,fe),Se===null?te=Te:Se.sibling=Te,Se=Te);return be&&cn(N,fe),te}for(P=a(P);!Te.done;fe++,Te=M.next())Te=U(P,N,fe,Te.value,k),Te!==null&&(e&&Te.alternate!==null&&P.delete(Te.key===null?fe:Te.key),w=f(Te,w,fe),Se===null?te=Te:Se.sibling=Te,Se=Te);return e&&P.forEach(function(y1){return t(N,y1)}),be&&cn(N,fe),te}function Ce(N,w,M,k){if(typeof M=="object"&&M!==null&&M.type===S&&M.key===null&&(M=M.props.children),typeof M=="object"&&M!==null){switch(M.$$typeof){case A:e:{for(var te=M.key;w!==null;){if(w.key===te){if(te=M.type,te===S){if(w.tag===7){n(N,w.sibling),k=r(w,M.props.children),k.return=N,N=k;break e}}else if(w.elementType===te||typeof te=="object"&&te!==null&&te.$$typeof===V&&hl(te)===w.type){n(N,w.sibling),k=r(w,M.props),Ia(k,M),k.return=N,N=k;break e}n(N,w);break}else t(N,w);w=w.sibling}M.type===S?(k=ul(M.props.children,N.mode,k,M.key),k.return=N,N=k):(k=as(M.type,M.key,M.props,null,N.mode,k),Ia(k,M),k.return=N,N=k)}return d(N);case z:e:{for(te=M.key;w!==null;){if(w.key===te)if(w.tag===4&&w.stateNode.containerInfo===M.containerInfo&&w.stateNode.implementation===M.implementation){n(N,w.sibling),k=r(w,M.children||[]),k.return=N,N=k;break e}else{n(N,w);break}else t(N,w);w=w.sibling}k=Tc(M,N.mode,k),k.return=N,N=k}return d(N);case V:return M=hl(M),Ce(N,w,M,k)}if(ie(M))return F(N,w,M,k);if(q(M)){if(te=q(M),typeof te!="function")throw Error(u(150));return M=te.call(M),ae(N,w,M,k)}if(typeof M.then=="function")return Ce(N,w,os(M),k);if(M.$$typeof===Y)return Ce(N,w,us(N,M),k);hs(N,M)}return typeof M=="string"&&M!==""||typeof M=="number"||typeof M=="bigint"?(M=""+M,w!==null&&w.tag===6?(n(N,w.sibling),k=r(w,M),k.return=N,N=k):(n(N,w),k=Sc(M,N.mode,k),k.return=N,N=k),d(N)):n(N,w)}return function(N,w,M,k){try{Fa=0;var te=Ce(N,w,M,k);return Jl=null,te}catch(P){if(P===Zl||P===rs)throw P;var Se=_t(29,P,null,N.mode);return Se.lanes=k,Se.return=N,Se}finally{}}}var ml=fh(!0),oh=fh(!1),Ln=!1;function Lc(e){e.updateQueue={baseState:e.memoizedState,firstBaseUpdate:null,lastBaseUpdate:null,shared:{pending:null,lanes:0,hiddenCallbacks:null},callbacks:null}}function Uc(e,t){e=e.updateQueue,t.updateQueue===e&&(t.updateQueue={baseState:e.baseState,firstBaseUpdate:e.firstBaseUpdate,lastBaseUpdate:e.lastBaseUpdate,shared:e.shared,callbacks:null})}function Un(e){return{lane:e,tag:0,payload:null,callback:null,next:null}}function jn(e,t,n){var a=e.updateQueue;if(a===null)return null;if(a=a.shared,(Ee&2)!==0){var r=a.pending;return r===null?t.next=t:(t.next=r.next,r.next=t),a.pending=t,t=ls(e),Zo(e,null,n),t}return ns(e,a,t,n),ls(e)}function Pa(e,t,n){if(t=t.updateQueue,t!==null&&(t=t.shared,(n&4194048)!==0)){var a=t.lanes;a&=e.pendingLanes,n|=a,t.lanes=n,to(e,n)}}function jc(e,t){var n=e.updateQueue,a=e.alternate;if(a!==null&&(a=a.updateQueue,n===a)){var r=null,f=null;if(n=n.firstBaseUpdate,n!==null){do{var d={lane:n.lane,tag:n.tag,payload:n.payload,callback:null,next:null};f===null?r=f=d:f=f.next=d,n=n.next}while(n!==null);f===null?r=f=t:f=f.next=t}else r=f=t;n={baseState:a.baseState,firstBaseUpdate:r,lastBaseUpdate:f,shared:a.shared,callbacks:a.callbacks},e.updateQueue=n;return}e=n.lastBaseUpdate,e===null?n.firstBaseUpdate=t:e.next=t,n.lastBaseUpdate=t}var Bc=!1;function ei(){if(Bc){var e=Xl;if(e!==null)throw e}}function ti(e,t,n,a){Bc=!1;var r=e.updateQueue;Ln=!1;var f=r.firstBaseUpdate,d=r.lastBaseUpdate,y=r.shared.pending;if(y!==null){r.shared.pending=null;var b=y,C=b.next;b.next=null,d===null?f=C:d.next=C,d=b;var R=e.alternate;R!==null&&(R=R.updateQueue,y=R.lastBaseUpdate,y!==d&&(y===null?R.firstBaseUpdate=C:y.next=C,R.lastBaseUpdate=b))}if(f!==null){var H=r.baseState;d=0,R=C=b=null,y=f;do{var L=y.lane&-536870913,U=L!==y.lane;if(U?(ye&L)===L:(a&L)===L){L!==0&&L===Ql&&(Bc=!0),R!==null&&(R=R.next={lane:0,tag:y.tag,payload:y.payload,callback:null,next:null});e:{var F=e,ae=y;L=t;var Ce=n;switch(ae.tag){case 1:if(F=ae.payload,typeof F=="function"){H=F.call(Ce,H,L);break e}H=F;break e;case 3:F.flags=F.flags&-65537|128;case 0:if(F=ae.payload,L=typeof F=="function"?F.call(Ce,H,L):F,L==null)break e;H=v({},H,L);break e;case 2:Ln=!0}}L=y.callback,L!==null&&(e.flags|=64,U&&(e.flags|=8192),U=r.callbacks,U===null?r.callbacks=[L]:U.push(L))}else U={lane:L,tag:y.tag,payload:y.payload,callback:y.callback,next:null},R===null?(C=R=U,b=H):R=R.next=U,d|=L;if(y=y.next,y===null){if(y=r.shared.pending,y===null)break;U=y,y=U.next,U.next=null,r.lastBaseUpdate=U,r.shared.pending=null}}while(!0);R===null&&(b=H),r.baseState=b,r.firstBaseUpdate=C,r.lastBaseUpdate=R,f===null&&(r.shared.lanes=0),Hn|=d,e.lanes=d,e.memoizedState=H}}function hh(e,t){if(typeof e!="function")throw Error(u(191,e));e.call(t)}function dh(e,t){var n=e.callbacks;if(n!==null)for(e.callbacks=null,e=0;ef?f:8;var d=D.T,y={};D.T=y,tr(e,!1,t,n);try{var b=r(),C=D.S;if(C!==null&&C(y,b),b!==null&&typeof b=="object"&&typeof b.then=="function"){var R=s0(b,a);ai(e,t,R,xt(e))}else ai(e,t,a,xt(e))}catch(H){ai(e,t,{then:function(){},status:"rejected",reason:H},xt())}finally{Q.p=f,d!==null&&y.types!==null&&(d.types=y.types),D.T=d}}function h0(){}function Pc(e,t,n,a){if(e.tag!==5)throw Error(u(476));var r=Vh(e).queue;Kh(e,r,t,ee,n===null?h0:function(){return Qh(e),n(a)})}function Vh(e){var t=e.memoizedState;if(t!==null)return t;t={memoizedState:ee,baseState:ee,baseQueue:null,queue:{pending:null,lanes:0,dispatch:null,lastRenderedReducer:hn,lastRenderedState:ee},next:null};var n={};return t.next={memoizedState:n,baseState:n,baseQueue:null,queue:{pending:null,lanes:0,dispatch:null,lastRenderedReducer:hn,lastRenderedState:n},next:null},e.memoizedState=t,e=e.alternate,e!==null&&(e.memoizedState=t),t}function Qh(e){var t=Vh(e);t.next===null&&(t=e.alternate.memoizedState),ai(e,t.next.queue,{},xt())}function er(){return nt(Ti)}function Xh(){return Ge().memoizedState}function Zh(){return Ge().memoizedState}function d0(e){for(var t=e.return;t!==null;){switch(t.tag){case 24:case 3:var n=xt();e=Un(n);var a=jn(t,e,n);a!==null&&(vt(a,t,n),Pa(a,t,n)),t={cache:Cc()},e.payload=t;return}t=t.return}}function m0(e,t,n){var a=xt();n={lane:a,revertLane:0,gesture:null,action:n,hasEagerState:!1,eagerState:null,next:null},Es(e)?Wh(t,n):(n=vc(e,t,n,a),n!==null&&(vt(n,e,a),Fh(n,t,a)))}function Jh(e,t,n){var a=xt();ai(e,t,n,a)}function ai(e,t,n,a){var r={lane:a,revertLane:0,gesture:null,action:n,hasEagerState:!1,eagerState:null,next:null};if(Es(e))Wh(t,r);else{var f=e.alternate;if(e.lanes===0&&(f===null||f.lanes===0)&&(f=t.lastRenderedReducer,f!==null))try{var d=t.lastRenderedState,y=f(d,n);if(r.hasEagerState=!0,r.eagerState=y,Ot(y,d))return ns(e,t,r,0),xe===null&&ts(),!1}catch{}finally{}if(n=vc(e,t,r,a),n!==null)return vt(n,e,a),Fh(n,t,a),!0}return!1}function tr(e,t,n,a){if(a={lane:2,revertLane:Lr(),gesture:null,action:a,hasEagerState:!1,eagerState:null,next:null},Es(e)){if(t)throw Error(u(479))}else t=vc(e,n,a,2),t!==null&&vt(t,e,2)}function Es(e){var t=e.alternate;return e===re||t!==null&&t===re}function Wh(e,t){Fl=gs=!0;var n=e.pending;n===null?t.next=t:(t.next=n.next,n.next=t),e.pending=t}function Fh(e,t,n){if((n&4194048)!==0){var a=t.lanes;a&=e.pendingLanes,n|=a,t.lanes=n,to(e,n)}}var ii={readContext:nt,use:vs,useCallback:qe,useContext:qe,useEffect:qe,useImperativeHandle:qe,useLayoutEffect:qe,useInsertionEffect:qe,useMemo:qe,useReducer:qe,useRef:qe,useState:qe,useDebugValue:qe,useDeferredValue:qe,useTransition:qe,useSyncExternalStore:qe,useId:qe,useHostTransitionStatus:qe,useFormState:qe,useActionState:qe,useOptimistic:qe,useMemoCache:qe,useCacheRefresh:qe};ii.useEffectEvent=qe;var Ih={readContext:nt,use:vs,useCallback:function(e,t){return ft().memoizedState=[e,t===void 0?null:t],e},useContext:nt,useEffect:jh,useImperativeHandle:function(e,t,n){n=n!=null?n.concat([e]):null,Ss(4194308,4,qh.bind(null,t,e),n)},useLayoutEffect:function(e,t){return Ss(4194308,4,e,t)},useInsertionEffect:function(e,t){Ss(4,2,e,t)},useMemo:function(e,t){var n=ft();t=t===void 0?null:t;var a=e();if(gl){_n(!0);try{e()}finally{_n(!1)}}return n.memoizedState=[a,t],a},useReducer:function(e,t,n){var a=ft();if(n!==void 0){var r=n(t);if(gl){_n(!0);try{n(t)}finally{_n(!1)}}}else r=t;return a.memoizedState=a.baseState=r,e={pending:null,lanes:0,dispatch:null,lastRenderedReducer:e,lastRenderedState:r},a.queue=e,e=e.dispatch=m0.bind(null,re,e),[a.memoizedState,e]},useRef:function(e){var t=ft();return e={current:e},t.memoizedState=e},useState:function(e){e=Zc(e);var t=e.queue,n=Jh.bind(null,re,t);return t.dispatch=n,[e.memoizedState,n]},useDebugValue:Fc,useDeferredValue:function(e,t){var n=ft();return Ic(n,e,t)},useTransition:function(){var e=Zc(!1);return e=Kh.bind(null,re,e.queue,!0,!1),ft().memoizedState=e,[!1,e]},useSyncExternalStore:function(e,t,n){var a=re,r=ft();if(be){if(n===void 0)throw Error(u(407));n=n()}else{if(n=t(),xe===null)throw Error(u(349));(ye&127)!==0||bh(a,t,n)}r.memoizedState=n;var f={value:n,getSnapshot:t};return r.queue=f,jh(Th.bind(null,a,f,e),[e]),a.flags|=2048,Pl(9,{destroy:void 0},Sh.bind(null,a,f,n,t),null),n},useId:function(){var e=ft(),t=xe.identifierPrefix;if(be){var n=It,a=Ft;n=(a&~(1<<32-wt(a)-1)).toString(32)+n,t="_"+t+"R_"+n,n=ps++,0<\/script>",f=f.removeChild(f.firstChild);break;case"select":f=typeof a.is=="string"?d.createElement("select",{is:a.is}):d.createElement("select"),a.multiple?f.multiple=!0:a.size&&(f.size=a.size);break;default:f=typeof a.is=="string"?d.createElement(r,{is:a.is}):d.createElement(r)}}f[et]=t,f[ht]=a;e:for(d=t.child;d!==null;){if(d.tag===5||d.tag===6)f.appendChild(d.stateNode);else if(d.tag!==4&&d.tag!==27&&d.child!==null){d.child.return=d,d=d.child;continue}if(d===t)break e;for(;d.sibling===null;){if(d.return===null||d.return===t)break e;d=d.return}d.sibling.return=d.return,d=d.sibling}t.stateNode=f;e:switch(at(f,r,a),r){case"button":case"input":case"select":case"textarea":a=!!a.autoFocus;break e;case"img":a=!0;break e;default:a=!1}a&&mn(t)}}return Ue(t),gr(t,t.type,e===null?null:e.memoizedProps,t.pendingProps,n),null;case 6:if(e&&t.stateNode!=null)e.memoizedProps!==a&&mn(t);else{if(typeof a!="string"&&t.stateNode===null)throw Error(u(166));if(e=me.current,Kl(t)){if(e=t.stateNode,n=t.memoizedProps,a=null,r=tt,r!==null)switch(r.tag){case 27:case 5:a=r.memoizedProps}e[et]=t,e=!!(e.nodeValue===n||a!==null&&a.suppressHydrationWarning===!0||ym(e.nodeValue,n)),e||xn(t,!0)}else e=Ys(e).createTextNode(a),e[et]=t,t.stateNode=e}return Ue(t),null;case 31:if(n=t.memoizedState,e===null||e.memoizedState!==null){if(a=Kl(t),n!==null){if(e===null){if(!a)throw Error(u(318));if(e=t.memoizedState,e=e!==null?e.dehydrated:null,!e)throw Error(u(557));e[et]=t}else cl(),(t.flags&128)===0&&(t.memoizedState=null),t.flags|=4;Ue(t),e=!1}else n=Oc(),e!==null&&e.memoizedState!==null&&(e.memoizedState.hydrationErrors=n),e=!0;if(!e)return t.flags&256?(Mt(t),t):(Mt(t),null);if((t.flags&128)!==0)throw Error(u(558))}return Ue(t),null;case 13:if(a=t.memoizedState,e===null||e.memoizedState!==null&&e.memoizedState.dehydrated!==null){if(r=Kl(t),a!==null&&a.dehydrated!==null){if(e===null){if(!r)throw Error(u(318));if(r=t.memoizedState,r=r!==null?r.dehydrated:null,!r)throw Error(u(317));r[et]=t}else cl(),(t.flags&128)===0&&(t.memoizedState=null),t.flags|=4;Ue(t),r=!1}else r=Oc(),e!==null&&e.memoizedState!==null&&(e.memoizedState.hydrationErrors=r),r=!0;if(!r)return t.flags&256?(Mt(t),t):(Mt(t),null)}return Mt(t),(t.flags&128)!==0?(t.lanes=n,t):(n=a!==null,e=e!==null&&e.memoizedState!==null,n&&(a=t.child,r=null,a.alternate!==null&&a.alternate.memoizedState!==null&&a.alternate.memoizedState.cachePool!==null&&(r=a.alternate.memoizedState.cachePool.pool),f=null,a.memoizedState!==null&&a.memoizedState.cachePool!==null&&(f=a.memoizedState.cachePool.pool),f!==r&&(a.flags|=2048)),n!==e&&n&&(t.child.flags|=8192),Ns(t,t.updateQueue),Ue(t),null);case 4:return $e(),e===null&&Rr(t.stateNode.containerInfo),Ue(t),null;case 10:return fn(t.type),Ue(t),null;case 19:if($(Ye),a=t.memoizedState,a===null)return Ue(t),null;if(r=(t.flags&128)!==0,f=a.rendering,f===null)if(r)ui(a,!1);else{if(He!==0||e!==null&&(e.flags&128)!==0)for(e=t.child;e!==null;){if(f=ms(e),f!==null){for(t.flags|=128,ui(a,!1),e=f.updateQueue,t.updateQueue=e,Ns(t,e),t.subtreeFlags=0,e=n,n=t.child;n!==null;)Jo(n,e),n=n.sibling;return J(Ye,Ye.current&1|2),be&&cn(t,a.treeForkCount),t.child}e=e.sibling}a.tail!==null&&Et()>Ds&&(t.flags|=128,r=!0,ui(a,!1),t.lanes=4194304)}else{if(!r)if(e=ms(f),e!==null){if(t.flags|=128,r=!0,e=e.updateQueue,t.updateQueue=e,Ns(t,e),ui(a,!0),a.tail===null&&a.tailMode==="hidden"&&!f.alternate&&!be)return Ue(t),null}else 2*Et()-a.renderingStartTime>Ds&&n!==536870912&&(t.flags|=128,r=!0,ui(a,!1),t.lanes=4194304);a.isBackwards?(f.sibling=t.child,t.child=f):(e=a.last,e!==null?e.sibling=f:t.child=f,a.last=f)}return a.tail!==null?(e=a.tail,a.rendering=e,a.tail=e.sibling,a.renderingStartTime=Et(),e.sibling=null,n=Ye.current,J(Ye,r?n&1|2:n&1),be&&cn(t,a.treeForkCount),e):(Ue(t),null);case 22:case 23:return Mt(t),kc(),a=t.memoizedState!==null,e!==null?e.memoizedState!==null!==a&&(t.flags|=8192):a&&(t.flags|=8192),a?(n&536870912)!==0&&(t.flags&128)===0&&(Ue(t),t.subtreeFlags&6&&(t.flags|=8192)):Ue(t),n=t.updateQueue,n!==null&&Ns(t,n.retryQueue),n=null,e!==null&&e.memoizedState!==null&&e.memoizedState.cachePool!==null&&(n=e.memoizedState.cachePool.pool),a=null,t.memoizedState!==null&&t.memoizedState.cachePool!==null&&(a=t.memoizedState.cachePool.pool),a!==n&&(t.flags|=2048),e!==null&&$(ol),null;case 24:return n=null,e!==null&&(n=e.memoizedState.cache),t.memoizedState.cache!==n&&(t.flags|=2048),fn(Ve),Ue(t),null;case 25:return null;case 30:return null}throw Error(u(156,t.tag))}function b0(e,t){switch(Ac(t),t.tag){case 1:return e=t.flags,e&65536?(t.flags=e&-65537|128,t):null;case 3:return fn(Ve),$e(),e=t.flags,(e&65536)!==0&&(e&128)===0?(t.flags=e&-65537|128,t):null;case 26:case 27:case 5:return ki(t),null;case 31:if(t.memoizedState!==null){if(Mt(t),t.alternate===null)throw Error(u(340));cl()}return e=t.flags,e&65536?(t.flags=e&-65537|128,t):null;case 13:if(Mt(t),e=t.memoizedState,e!==null&&e.dehydrated!==null){if(t.alternate===null)throw Error(u(340));cl()}return e=t.flags,e&65536?(t.flags=e&-65537|128,t):null;case 19:return $(Ye),null;case 4:return $e(),null;case 10:return fn(t.type),null;case 22:case 23:return Mt(t),kc(),e!==null&&$(ol),e=t.flags,e&65536?(t.flags=e&-65537|128,t):null;case 24:return fn(Ve),null;case 25:return null;default:return null}}function Ed(e,t){switch(Ac(t),t.tag){case 3:fn(Ve),$e();break;case 26:case 27:case 5:ki(t);break;case 4:$e();break;case 31:t.memoizedState!==null&&Mt(t);break;case 13:Mt(t);break;case 19:$(Ye);break;case 10:fn(t.type);break;case 22:case 23:Mt(t),kc(),e!==null&&$(ol);break;case 24:fn(Ve)}}function ci(e,t){try{var n=t.updateQueue,a=n!==null?n.lastEffect:null;if(a!==null){var r=a.next;n=r;do{if((n.tag&e)===e){a=void 0;var f=n.create,d=n.inst;a=f(),d.destroy=a}n=n.next}while(n!==r)}}catch(y){Oe(t,t.return,y)}}function kn(e,t,n){try{var a=t.updateQueue,r=a!==null?a.lastEffect:null;if(r!==null){var f=r.next;a=f;do{if((a.tag&e)===e){var d=a.inst,y=d.destroy;if(y!==void 0){d.destroy=void 0,r=t;var b=n,C=y;try{C()}catch(R){Oe(r,b,R)}}}a=a.next}while(a!==f)}}catch(R){Oe(t,t.return,R)}}function Ad(e){var t=e.updateQueue;if(t!==null){var n=e.stateNode;try{dh(t,n)}catch(a){Oe(e,e.return,a)}}}function wd(e,t,n){n.props=pl(e.type,e.memoizedProps),n.state=e.memoizedState;try{n.componentWillUnmount()}catch(a){Oe(e,t,a)}}function ri(e,t){try{var n=e.ref;if(n!==null){switch(e.tag){case 26:case 27:case 5:var a=e.stateNode;break;case 30:a=e.stateNode;break;default:a=e.stateNode}typeof n=="function"?e.refCleanup=n(a):n.current=a}}catch(r){Oe(e,t,r)}}function Pt(e,t){var n=e.ref,a=e.refCleanup;if(n!==null)if(typeof a=="function")try{a()}catch(r){Oe(e,t,r)}finally{e.refCleanup=null,e=e.alternate,e!=null&&(e.refCleanup=null)}else if(typeof n=="function")try{n(null)}catch(r){Oe(e,t,r)}else n.current=null}function Od(e){var t=e.type,n=e.memoizedProps,a=e.stateNode;try{e:switch(t){case"button":case"input":case"select":case"textarea":n.autoFocus&&a.focus();break e;case"img":n.src?a.src=n.src:n.srcSet&&(a.srcset=n.srcSet)}}catch(r){Oe(e,e.return,r)}}function pr(e,t,n){try{var a=e.stateNode;$0(a,e.type,n,t),a[ht]=t}catch(r){Oe(e,e.return,r)}}function _d(e){return e.tag===5||e.tag===3||e.tag===26||e.tag===27&&Vn(e.type)||e.tag===4}function yr(e){e:for(;;){for(;e.sibling===null;){if(e.return===null||_d(e.return))return null;e=e.return}for(e.sibling.return=e.return,e=e.sibling;e.tag!==5&&e.tag!==6&&e.tag!==18;){if(e.tag===27&&Vn(e.type)||e.flags&2||e.child===null||e.tag===4)continue e;e.child.return=e,e=e.child}if(!(e.flags&2))return e.stateNode}}function vr(e,t,n){var a=e.tag;if(a===5||a===6)e=e.stateNode,t?(n.nodeType===9?n.body:n.nodeName==="HTML"?n.ownerDocument.body:n).insertBefore(e,t):(t=n.nodeType===9?n.body:n.nodeName==="HTML"?n.ownerDocument.body:n,t.appendChild(e),n=n._reactRootContainer,n!=null||t.onclick!==null||(t.onclick=an));else if(a!==4&&(a===27&&Vn(e.type)&&(n=e.stateNode,t=null),e=e.child,e!==null))for(vr(e,t,n),e=e.sibling;e!==null;)vr(e,t,n),e=e.sibling}function Ms(e,t,n){var a=e.tag;if(a===5||a===6)e=e.stateNode,t?n.insertBefore(e,t):n.appendChild(e);else if(a!==4&&(a===27&&Vn(e.type)&&(n=e.stateNode),e=e.child,e!==null))for(Ms(e,t,n),e=e.sibling;e!==null;)Ms(e,t,n),e=e.sibling}function Nd(e){var t=e.stateNode,n=e.memoizedProps;try{for(var a=e.type,r=t.attributes;r.length;)t.removeAttributeNode(r[0]);at(t,a,n),t[et]=e,t[ht]=n}catch(f){Oe(e,e.return,f)}}var gn=!1,Ze=!1,br=!1,Md=typeof WeakSet=="function"?WeakSet:Set,Pe=null;function S0(e,t){if(e=e.containerInfo,Hr=Js,e=Ho(e),hc(e)){if("selectionStart"in e)var n={start:e.selectionStart,end:e.selectionEnd};else e:{n=(n=e.ownerDocument)&&n.defaultView||window;var a=n.getSelection&&n.getSelection();if(a&&a.rangeCount!==0){n=a.anchorNode;var r=a.anchorOffset,f=a.focusNode;a=a.focusOffset;try{n.nodeType,f.nodeType}catch{n=null;break e}var d=0,y=-1,b=-1,C=0,R=0,H=e,L=null;t:for(;;){for(var U;H!==n||r!==0&&H.nodeType!==3||(y=d+r),H!==f||a!==0&&H.nodeType!==3||(b=d+a),H.nodeType===3&&(d+=H.nodeValue.length),(U=H.firstChild)!==null;)L=H,H=U;for(;;){if(H===e)break t;if(L===n&&++C===r&&(y=d),L===f&&++R===a&&(b=d),(U=H.nextSibling)!==null)break;H=L,L=H.parentNode}H=U}n=y===-1||b===-1?null:{start:y,end:b}}else n=null}n=n||{start:0,end:0}}else n=null;for($r={focusedElem:e,selectionRange:n},Js=!1,Pe=t;Pe!==null;)if(t=Pe,e=t.child,(t.subtreeFlags&1028)!==0&&e!==null)e.return=t,Pe=e;else for(;Pe!==null;){switch(t=Pe,f=t.alternate,e=t.flags,t.tag){case 0:if((e&4)!==0&&(e=t.updateQueue,e=e!==null?e.events:null,e!==null))for(n=0;n title"))),at(f,a,n),f[et]=e,Ie(f),a=f;break e;case"link":var d=Um("link","href",r).get(a+(n.href||""));if(d){for(var y=0;yCe&&(d=Ce,Ce=ae,ae=d);var N=ko(y,ae),w=ko(y,Ce);if(N&&w&&(U.rangeCount!==1||U.anchorNode!==N.node||U.anchorOffset!==N.offset||U.focusNode!==w.node||U.focusOffset!==w.offset)){var M=H.createRange();M.setStart(N.node,N.offset),U.removeAllRanges(),ae>Ce?(U.addRange(M),U.extend(w.node,w.offset)):(M.setEnd(w.node,w.offset),U.addRange(M))}}}}for(H=[],U=y;U=U.parentNode;)U.nodeType===1&&H.push({element:U,left:U.scrollLeft,top:U.scrollTop});for(typeof y.focus=="function"&&y.focus(),y=0;yn?32:n,D.T=null,n=_r,_r=null;var f=Yn,d=Sn;if(We=0,aa=Yn=null,Sn=0,(Ee&6)!==0)throw Error(u(331));var y=Ee;if(Ee|=4,qd(f.current),Bd(f,f.current,d,n),Ee=y,gi(0,!1),At&&typeof At.onPostCommitFiberRoot=="function")try{At.onPostCommitFiberRoot(La,f)}catch{}return!0}finally{Q.p=r,D.T=a,lm(e,t)}}function im(e,t,n){t=Rt(n,t),t=ir(e.stateNode,t,2),e=jn(e,t,2),e!==null&&(ja(e,2),en(e))}function Oe(e,t,n){if(e.tag===3)im(e,e,n);else for(;t!==null;){if(t.tag===3){im(t,e,n);break}else if(t.tag===1){var a=t.stateNode;if(typeof t.type.getDerivedStateFromError=="function"||typeof a.componentDidCatch=="function"&&($n===null||!$n.has(a))){e=Rt(n,e),n=sd(2),a=jn(t,n,2),a!==null&&(ud(n,a,t,e),ja(a,2),en(a));break}}t=t.return}}function zr(e,t,n){var a=e.pingCache;if(a===null){a=e.pingCache=new A0;var r=new Set;a.set(t,r)}else r=a.get(t),r===void 0&&(r=new Set,a.set(t,r));r.has(n)||(Er=!0,r.add(n),e=M0.bind(null,e,t,n),t.then(e,e))}function M0(e,t,n){var a=e.pingCache;a!==null&&a.delete(t),e.pingedLanes|=e.suspendedLanes&n,e.warmLanes&=~n,xe===e&&(ye&n)===n&&(He===4||He===3&&(ye&62914560)===ye&&300>Et()-xs?(Ee&2)===0&&ia(e,0):Ar|=n,la===ye&&(la=0)),en(e)}function sm(e,t){t===0&&(t=Pf()),e=sl(e,t),e!==null&&(ja(e,t),en(e))}function C0(e){var t=e.memoizedState,n=0;t!==null&&(n=t.retryLane),sm(e,n)}function z0(e,t){var n=0;switch(e.tag){case 31:case 13:var a=e.stateNode,r=e.memoizedState;r!==null&&(n=r.retryLane);break;case 19:a=e.stateNode;break;case 22:a=e.stateNode._retryCache;break;default:throw Error(u(314))}a!==null&&a.delete(t),sm(e,n)}function x0(e,t){return Gu(e,t)}var ks=null,ua=null,xr=!1,qs=!1,Dr=!1,Kn=0;function en(e){e!==ua&&e.next===null&&(ua===null?ks=ua=e:ua=ua.next=e),qs=!0,xr||(xr=!0,L0())}function gi(e,t){if(!Dr&&qs){Dr=!0;do for(var n=!1,a=ks;a!==null;){if(e!==0){var r=a.pendingLanes;if(r===0)var f=0;else{var d=a.suspendedLanes,y=a.pingedLanes;f=(1<<31-wt(42|e)+1)-1,f&=r&~(d&~y),f=f&201326741?f&201326741|1:f?f|2:0}f!==0&&(n=!0,fm(a,f))}else f=ye,f=Gi(a,a===xe?f:0,a.cancelPendingCommit!==null||a.timeoutHandle!==-1),(f&3)===0||Ua(a,f)||(n=!0,fm(a,f));a=a.next}while(n);Dr=!1}}function D0(){um()}function um(){qs=xr=!1;var e=0;Kn!==0&&G0()&&(e=Kn);for(var t=Et(),n=null,a=ks;a!==null;){var r=a.next,f=cm(a,t);f===0?(a.next=null,n===null?ks=r:n.next=r,r===null&&(ua=n)):(n=a,(e!==0||(f&3)!==0)&&(qs=!0)),a=r}We!==0&&We!==5||gi(e),Kn!==0&&(Kn=0)}function cm(e,t){for(var n=e.suspendedLanes,a=e.pingedLanes,r=e.expirationTimes,f=e.pendingLanes&-62914561;0y)break;var R=b.transferSize,H=b.initiatorType;R&&vm(H)&&(b=b.responseEnd,d+=R*(b"u"?null:document;function zm(e,t,n){var a=ca;if(a&&typeof t=="string"&&t){var r=jt(t);r='link[rel="'+e+'"][href="'+r+'"]',typeof n=="string"&&(r+='[crossorigin="'+n+'"]'),Cm.has(r)||(Cm.add(r),e={rel:e,crossOrigin:n,href:t},a.querySelector(r)===null&&(t=a.createElement("link"),at(t,"link",e),Ie(t),a.head.appendChild(t)))}}function I0(e){Tn.D(e),zm("dns-prefetch",e,null)}function P0(e,t){Tn.C(e,t),zm("preconnect",e,t)}function e1(e,t,n){Tn.L(e,t,n);var a=ca;if(a&&e&&t){var r='link[rel="preload"][as="'+jt(t)+'"]';t==="image"&&n&&n.imageSrcSet?(r+='[imagesrcset="'+jt(n.imageSrcSet)+'"]',typeof n.imageSizes=="string"&&(r+='[imagesizes="'+jt(n.imageSizes)+'"]')):r+='[href="'+jt(e)+'"]';var f=r;switch(t){case"style":f=ra(e);break;case"script":f=fa(e)}Gt.has(f)||(e=v({rel:"preload",href:t==="image"&&n&&n.imageSrcSet?void 0:e,as:t},n),Gt.set(f,e),a.querySelector(r)!==null||t==="style"&&a.querySelector(bi(f))||t==="script"&&a.querySelector(Si(f))||(t=a.createElement("link"),at(t,"link",e),Ie(t),a.head.appendChild(t)))}}function t1(e,t){Tn.m(e,t);var n=ca;if(n&&e){var a=t&&typeof t.as=="string"?t.as:"script",r='link[rel="modulepreload"][as="'+jt(a)+'"][href="'+jt(e)+'"]',f=r;switch(a){case"audioworklet":case"paintworklet":case"serviceworker":case"sharedworker":case"worker":case"script":f=fa(e)}if(!Gt.has(f)&&(e=v({rel:"modulepreload",href:e},t),Gt.set(f,e),n.querySelector(r)===null)){switch(a){case"audioworklet":case"paintworklet":case"serviceworker":case"sharedworker":case"worker":case"script":if(n.querySelector(Si(f)))return}a=n.createElement("link"),at(a,"link",e),Ie(a),n.head.appendChild(a)}}}function n1(e,t,n){Tn.S(e,t,n);var a=ca;if(a&&e){var r=xl(a).hoistableStyles,f=ra(e);t=t||"default";var d=r.get(f);if(!d){var y={loading:0,preload:null};if(d=a.querySelector(bi(f)))y.loading=5;else{e=v({rel:"stylesheet",href:e,"data-precedence":t},n),(n=Gt.get(f))&&Zr(e,n);var b=d=a.createElement("link");Ie(b),at(b,"link",e),b._p=new Promise(function(C,R){b.onload=C,b.onerror=R}),b.addEventListener("load",function(){y.loading|=1}),b.addEventListener("error",function(){y.loading|=2}),y.loading|=4,Ks(d,t,a)}d={type:"stylesheet",instance:d,count:1,state:y},r.set(f,d)}}}function l1(e,t){Tn.X(e,t);var n=ca;if(n&&e){var a=xl(n).hoistableScripts,r=fa(e),f=a.get(r);f||(f=n.querySelector(Si(r)),f||(e=v({src:e,async:!0},t),(t=Gt.get(r))&&Jr(e,t),f=n.createElement("script"),Ie(f),at(f,"link",e),n.head.appendChild(f)),f={type:"script",instance:f,count:1,state:null},a.set(r,f))}}function a1(e,t){Tn.M(e,t);var n=ca;if(n&&e){var a=xl(n).hoistableScripts,r=fa(e),f=a.get(r);f||(f=n.querySelector(Si(r)),f||(e=v({src:e,async:!0,type:"module"},t),(t=Gt.get(r))&&Jr(e,t),f=n.createElement("script"),Ie(f),at(f,"link",e),n.head.appendChild(f)),f={type:"script",instance:f,count:1,state:null},a.set(r,f))}}function xm(e,t,n,a){var r=(r=me.current)?Gs(r):null;if(!r)throw Error(u(446));switch(e){case"meta":case"title":return null;case"style":return typeof n.precedence=="string"&&typeof n.href=="string"?(t=ra(n.href),n=xl(r).hoistableStyles,a=n.get(t),a||(a={type:"style",instance:null,count:0,state:null},n.set(t,a)),a):{type:"void",instance:null,count:0,state:null};case"link":if(n.rel==="stylesheet"&&typeof n.href=="string"&&typeof n.precedence=="string"){e=ra(n.href);var f=xl(r).hoistableStyles,d=f.get(e);if(d||(r=r.ownerDocument||r,d={type:"stylesheet",instance:null,count:0,state:{loading:0,preload:null}},f.set(e,d),(f=r.querySelector(bi(e)))&&!f._p&&(d.instance=f,d.state.loading=5),Gt.has(e)||(n={rel:"preload",as:"style",href:n.href,crossOrigin:n.crossOrigin,integrity:n.integrity,media:n.media,hrefLang:n.hrefLang,referrerPolicy:n.referrerPolicy},Gt.set(e,n),f||i1(r,e,n,d.state))),t&&a===null)throw Error(u(528,""));return d}if(t&&a!==null)throw Error(u(529,""));return null;case"script":return t=n.async,n=n.src,typeof n=="string"&&t&&typeof t!="function"&&typeof t!="symbol"?(t=fa(n),n=xl(r).hoistableScripts,a=n.get(t),a||(a={type:"script",instance:null,count:0,state:null},n.set(t,a)),a):{type:"void",instance:null,count:0,state:null};default:throw Error(u(444,e))}}function ra(e){return'href="'+jt(e)+'"'}function bi(e){return'link[rel="stylesheet"]['+e+"]"}function Dm(e){return v({},e,{"data-precedence":e.precedence,precedence:null})}function i1(e,t,n,a){e.querySelector('link[rel="preload"][as="style"]['+t+"]")?a.loading=1:(t=e.createElement("link"),a.preload=t,t.addEventListener("load",function(){return a.loading|=1}),t.addEventListener("error",function(){return a.loading|=2}),at(t,"link",n),Ie(t),e.head.appendChild(t))}function fa(e){return'[src="'+jt(e)+'"]'}function Si(e){return"script[async]"+e}function Lm(e,t,n){if(t.count++,t.instance===null)switch(t.type){case"style":var a=e.querySelector('style[data-href~="'+jt(n.href)+'"]');if(a)return t.instance=a,Ie(a),a;var r=v({},n,{"data-href":n.href,"data-precedence":n.precedence,href:null,precedence:null});return a=(e.ownerDocument||e).createElement("style"),Ie(a),at(a,"style",r),Ks(a,n.precedence,e),t.instance=a;case"stylesheet":r=ra(n.href);var f=e.querySelector(bi(r));if(f)return t.state.loading|=4,t.instance=f,Ie(f),f;a=Dm(n),(r=Gt.get(r))&&Zr(a,r),f=(e.ownerDocument||e).createElement("link"),Ie(f);var d=f;return d._p=new Promise(function(y,b){d.onload=y,d.onerror=b}),at(f,"link",a),t.state.loading|=4,Ks(f,n.precedence,e),t.instance=f;case"script":return f=fa(n.src),(r=e.querySelector(Si(f)))?(t.instance=r,Ie(r),r):(a=n,(r=Gt.get(f))&&(a=v({},n),Jr(a,r)),e=e.ownerDocument||e,r=e.createElement("script"),Ie(r),at(r,"link",a),e.head.appendChild(r),t.instance=r);case"void":return null;default:throw Error(u(443,t.type))}else t.type==="stylesheet"&&(t.state.loading&4)===0&&(a=t.instance,t.state.loading|=4,Ks(a,n.precedence,e));return t.instance}function Ks(e,t,n){for(var a=n.querySelectorAll('link[rel="stylesheet"][data-precedence],style[data-precedence]'),r=a.length?a[a.length-1]:null,f=r,d=0;d title"):null)}function s1(e,t,n){if(n===1||t.itemProp!=null)return!1;switch(e){case"meta":case"title":return!0;case"style":if(typeof t.precedence!="string"||typeof t.href!="string"||t.href==="")break;return!0;case"link":if(typeof t.rel!="string"||typeof t.href!="string"||t.href===""||t.onLoad||t.onError)break;switch(t.rel){case"stylesheet":return e=t.disabled,typeof t.precedence=="string"&&e==null;default:return!0}case"script":if(t.async&&typeof t.async!="function"&&typeof t.async!="symbol"&&!t.onLoad&&!t.onError&&t.src&&typeof t.src=="string")return!0}return!1}function Bm(e){return!(e.type==="stylesheet"&&(e.state.loading&3)===0)}function u1(e,t,n,a){if(n.type==="stylesheet"&&(typeof a.media!="string"||matchMedia(a.media).matches!==!1)&&(n.state.loading&4)===0){if(n.instance===null){var r=ra(a.href),f=t.querySelector(bi(r));if(f){t=f._p,t!==null&&typeof t=="object"&&typeof t.then=="function"&&(e.count++,e=Qs.bind(e),t.then(e,e)),n.state.loading|=4,n.instance=f,Ie(f);return}f=t.ownerDocument||t,a=Dm(a),(r=Gt.get(r))&&Zr(a,r),f=f.createElement("link"),Ie(f);var d=f;d._p=new Promise(function(y,b){d.onload=y,d.onerror=b}),at(f,"link",a),n.instance=f}e.stylesheets===null&&(e.stylesheets=new Map),e.stylesheets.set(n,t),(t=n.state.preload)&&(n.state.loading&3)===0&&(e.count++,n=Qs.bind(e),t.addEventListener("load",n),t.addEventListener("error",n))}}var Wr=0;function c1(e,t){return e.stylesheets&&e.count===0&&Zs(e,e.stylesheets),0Wr?50:800)+t);return e.unsuspend=n,function(){e.unsuspend=null,clearTimeout(a),clearTimeout(r)}}:null}function Qs(){if(this.count--,this.count===0&&(this.imgCount===0||!this.waitingForImages)){if(this.stylesheets)Zs(this,this.stylesheets);else if(this.unsuspend){var e=this.unsuspend;this.unsuspend=null,e()}}}var Xs=null;function Zs(e,t){e.stylesheets=null,e.unsuspend!==null&&(e.count++,Xs=new Map,t.forEach(r1,e),Xs=null,Qs.call(e))}function r1(e,t){if(!(t.state.loading&4)){var n=Xs.get(e);if(n)var a=n.get(null);else{n=new Map,Xs.set(e,n);for(var r=e.querySelectorAll("link[data-precedence],style[data-precedence]"),f=0;f"u"||typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE!="function"))try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(s)}catch(l){console.error(l)}}return s(),sf.exports=j1(),sf.exports}var R1=B1();const k1="modulepreload",q1=function(s){return"/"+s},cg={},H1=function(l,i,u){let c=Promise.resolve();if(i&&i.length>0){let h=function(p){return Promise.all(p.map(E=>Promise.resolve(E).then(v=>({status:"fulfilled",value:v}),v=>({status:"rejected",reason:v}))))};document.getElementsByTagName("link");const m=document.querySelector("meta[property=csp-nonce]"),g=(m==null?void 0:m.nonce)||(m==null?void 0:m.getAttribute("nonce"));c=h(i.map(p=>{if(p=q1(p),p in cg)return;cg[p]=!0;const E=p.endsWith(".css"),v=E?'[rel="stylesheet"]':"";if(document.querySelector(`link[href="${p}"]${v}`))return;const _=document.createElement("link");if(_.rel=E?"stylesheet":k1,E||(_.as="script"),_.crossOrigin="",_.href=p,g&&_.setAttribute("nonce",g),document.head.appendChild(_),E)return new Promise((A,z)=>{_.addEventListener("load",A),_.addEventListener("error",()=>z(new Error(`Unable to preload CSS for ${p}`)))})}))}function o(h){const m=new Event("vite:preloadError",{cancelable:!0});if(m.payload=h,window.dispatchEvent(m),!m.defaultPrevented)throw h}return c.then(h=>{for(const m of h||[])m.status==="rejected"&&o(m.reason);return l().catch(o)})};function $1(s,l){const i=/(\x1b\[(\d+(;\d+)*)m)|([^\x1b]+)/g,u=[];let c,o={},h=!1,m=l==null?void 0:l.fg,g=l==null?void 0:l.bg;for(;(c=i.exec(s))!==null;){const[,,p,,E]=c;if(p){const v=+p;switch(v){case 0:o={};break;case 1:o["font-weight"]="bold";break;case 2:o.opacity="0.8";break;case 3:o["font-style"]="italic";break;case 4:o["text-decoration"]="underline";break;case 7:h=!0;break;case 8:o.display="none";break;case 9:o["text-decoration"]="line-through";break;case 22:delete o["font-weight"],delete o["font-style"],delete o.opacity,delete o["text-decoration"];break;case 23:delete o["font-weight"],delete o["font-style"],delete o.opacity;break;case 24:delete o["text-decoration"];break;case 27:h=!1;break;case 30:case 31:case 32:case 33:case 34:case 35:case 36:case 37:m=rg[v-30];break;case 39:m=l==null?void 0:l.fg;break;case 40:case 41:case 42:case 43:case 44:case 45:case 46:case 47:g=rg[v-40];break;case 49:g=l==null?void 0:l.bg;break;case 53:o["text-decoration"]="overline";break;case 90:case 91:case 92:case 93:case 94:case 95:case 96:case 97:m=fg[v-90];break;case 100:case 101:case 102:case 103:case 104:case 105:case 106:case 107:g=fg[v-100];break}}else if(E){const v={...o},_=h?g:m;_!==void 0&&(v.color=_);const A=h?m:g;A!==void 0&&(v["background-color"]=A),u.push(`${Y1(E)}`)}}return u.join("")}const rg={0:"var(--vscode-terminal-ansiBlack)",1:"var(--vscode-terminal-ansiRed)",2:"var(--vscode-terminal-ansiGreen)",3:"var(--vscode-terminal-ansiYellow)",4:"var(--vscode-terminal-ansiBlue)",5:"var(--vscode-terminal-ansiMagenta)",6:"var(--vscode-terminal-ansiCyan)",7:"var(--vscode-terminal-ansiWhite)"},fg={0:"var(--vscode-terminal-ansiBrightBlack)",1:"var(--vscode-terminal-ansiBrightRed)",2:"var(--vscode-terminal-ansiBrightGreen)",3:"var(--vscode-terminal-ansiBrightYellow)",4:"var(--vscode-terminal-ansiBrightBlue)",5:"var(--vscode-terminal-ansiBrightMagenta)",6:"var(--vscode-terminal-ansiBrightCyan)",7:"var(--vscode-terminal-ansiBrightWhite)"};function Y1(s){return s.replace(/[&"<>]/g,l=>({"&":"&",'"':""","<":"<",">":">"})[l])}function G1(s){return Object.entries(s).map(([l,i])=>`${l}: ${i}`).join("; ")}const ff=({text:s,highlighter:l,mimeType:i,linkify:u,readOnly:c,highlight:o,revealLine:h,lineNumbers:m,isFocused:g,focusOnChange:p,wrapLines:E,onChange:v,dataTestId:_,placeholder:A})=>{const[z,S]=Mg(),[T]=oe.useState(H1(()=>import("./codeMirrorModule-DadYNm1I.js"),__vite__mapDeps([0,1])).then(X=>X.default)),x=oe.useRef(null),[j,Y]=oe.useState();return oe.useEffect(()=>{(async()=>{var V,B;const X=await T;V1(X);const W=S.current;if(!W)return;const K=X1(l)||Q1(i)||(u?"text/linkified":"");if(x.current&&K===x.current.cm.getOption("mode")&&!!c===x.current.cm.getOption("readOnly")&&m===x.current.cm.getOption("lineNumbers")&&E===x.current.cm.getOption("lineWrapping")&&A===x.current.cm.getOption("placeholder"))return;(B=(V=x.current)==null?void 0:V.cm)==null||B.getWrapperElement().remove();const G=X(W,{value:"",mode:K,readOnly:!!c,lineNumbers:m,lineWrapping:E,placeholder:A,matchBrackets:!0,autoCloseBrackets:!0,extraKeys:{"Ctrl-F":"findPersistent","Cmd-F":"findPersistent"}});return x.current={cm:G},g&&G.focus(),Y(G),G})()},[T,j,S,l,i,u,m,E,c,g,A]),oe.useEffect(()=>{x.current&&x.current.cm.setSize(z.width,z.height)},[z]),oe.useLayoutEffect(()=>{var K;if(!j)return;let X=!1;if(j.getValue()!==s&&(j.setValue(s),X=!0,p&&(j.execCommand("selectAll"),j.focus())),X||JSON.stringify(o)!==JSON.stringify(x.current.highlight)){for(const B of x.current.highlight||[])j.removeLineClass(B.line-1,"wrap");for(const B of o||[])j.addLineClass(B.line-1,"wrap",`source-line-${B.type}`);for(const B of x.current.widgets||[])j.removeLineWidget(B);for(const B of x.current.markers||[])B.clear();const G=[],V=[];for(const B of o||[]){if(B.type!=="subtle-error"&&B.type!=="error")continue;const he=(K=x.current)==null?void 0:K.cm.getLine(B.line-1);if(he){const ne={};ne.title=B.message||"",V.push(j.markText({line:B.line-1,ch:0},{line:B.line-1,ch:B.column||he.length},{className:"source-line-error-underline",attributes:ne}))}if(B.type==="error"){const ne=document.createElement("div");ne.innerHTML=$1(B.message||""),ne.className="source-line-error-widget",G.push(j.addLineWidget(B.line,ne,{above:!0,coverGutter:!1}))}}x.current.highlight=o,x.current.widgets=G,x.current.markers=V}typeof h=="number"&&x.current.cm.lineCount()>=h&&j.scrollIntoView({line:Math.max(0,h-1),ch:0},50);let W;return v&&(W=()=>v(j.getValue()),j.on("change",W)),()=>{W&&j.off("change",W)}},[j,s,o,h,p,v]),Z.jsx("div",{"data-testid":_,className:"cm-wrapper",ref:S,onClick:K1})};function K1(s){var i;if(!(s.target instanceof HTMLElement))return;let l;s.target.classList.contains("cm-linkified")?l=s.target.textContent:s.target.classList.contains("cm-link")&&((i=s.target.nextElementSibling)!=null&&i.classList.contains("cm-url"))&&(l=s.target.nextElementSibling.textContent.slice(1,-1)),l&&(s.preventDefault(),s.stopPropagation(),window.open(l,"_blank"))}let og=!1;function V1(s){og||(og=!0,s.defineSimpleMode("text/linkified",{start:[{regex:w1,token:"linkified"}]}))}function Q1(s){if(s){if(s.includes("javascript")||s.includes("json"))return"javascript";if(s.includes("python"))return"python";if(s.includes("csharp"))return"text/x-csharp";if(s.includes("java"))return"text/x-java";if(s.includes("markdown"))return"markdown";if(s.includes("html")||s.includes("svg"))return"htmlmixed";if(s.includes("css"))return"css"}}function X1(s){if(s)return{javascript:"javascript",jsonl:"javascript",python:"python",csharp:"text/x-csharp",java:"text/x-java",markdown:"markdown",html:"htmlmixed",css:"css",yaml:"yaml"}[s]}const Z1=50,J1=({sidebarSize:s,sidebarHidden:l=!1,sidebarIsFirst:i=!1,orientation:u="vertical",minSidebarSize:c=Z1,settingName:o,sidebar:h,main:m})=>{const g=Math.max(c,s)*window.devicePixelRatio,[p,E]=pu(o?o+"."+u+":size":void 0,g),[v,_]=pu(o?o+"."+u+":size":void 0,g),[A,z]=oe.useState(null),[S,T]=Mg();let x;u==="vertical"?(x=v/window.devicePixelRatio,S&&S.heightz({offset:u==="vertical"?Y.clientY:Y.clientX,size:x}),onMouseUp:()=>z(null),onMouseMove:Y=>{if(!Y.buttons)z(null);else if(A){const W=(u==="vertical"?Y.clientY:Y.clientX)-A.offset,K=i?A.size+W:A.size-W,V=Y.target.parentElement.getBoundingClientRect(),B=Math.min(Math.max(c,K),(u==="vertical"?V.height:V.width)-c);u==="vertical"?_(B*window.devicePixelRatio):E(B*window.devicePixelRatio)}}})]})},xg=({noShadow:s,children:l,noMinHeight:i,className:u,sidebarBackground:c,onClick:o})=>Z.jsx("div",{className:wl("toolbar",s&&"no-shadow",i&&"no-min-height",u,c&&"toolbar-sidebar-background"),onClick:o,children:l}),W1=({tabs:s,selectedTab:l,setSelectedTab:i,leftToolbar:u,rightToolbar:c,dataTestId:o,mode:h})=>{const m=oe.useId();return l||(l=s[0].id),h||(h="default"),Z.jsx("div",{className:"tabbed-pane","data-testid":o,children:Z.jsxs("div",{className:"vbox",children:[Z.jsxs(xg,{children:[u&&Z.jsxs("div",{style:{flex:"none",display:"flex",margin:"0 4px",alignItems:"center"},children:[...u]}),h==="default"&&Z.jsx("div",{style:{flex:"auto",display:"flex",height:"100%",overflow:"hidden"},role:"tablist",children:[...s.map(g=>Z.jsx(F1,{id:g.id,ariaControls:`${m}-${g.id}`,title:g.title,count:g.count,errorCount:g.errorCount,selected:l===g.id,onSelect:i},g.id))]}),h==="select"&&Z.jsx("div",{style:{flex:"auto",display:"flex",height:"100%",overflow:"hidden"},role:"tablist",children:Z.jsx("select",{style:{width:"100%",background:"none",cursor:"pointer"},value:l,onChange:g=>{i==null||i(s[g.currentTarget.selectedIndex].id)},children:s.map(g=>{let p="";return g.count&&(p=` (${g.count})`),g.errorCount&&(p=` (${g.errorCount})`),Z.jsxs("option",{value:g.id,role:"tab","aria-controls":`${m}-${g.id}`,children:[g.title,p]},g.id)})})}),c&&Z.jsxs("div",{style:{flex:"none",display:"flex",alignItems:"center"},children:[...c]})]}),s.map(g=>{const p="tab-content tab-"+g.id;if(g.component)return Z.jsx("div",{id:`${m}-${g.id}`,role:"tabpanel","aria-label":g.title,className:p,style:{display:l===g.id?"inherit":"none"},children:g.component},g.id);if(l===g.id)return Z.jsx("div",{id:`${m}-${g.id}`,role:"tabpanel","aria-label":g.title,className:p,children:g.render()},g.id)})]})})},F1=({id:s,title:l,count:i,errorCount:u,selected:c,onSelect:o,ariaControls:h})=>Z.jsxs("div",{className:wl("tabbed-pane-tab",c&&"selected"),onClick:()=>o==null?void 0:o(s),role:"tab",title:l,"aria-controls":h,"aria-selected":c,children:[Z.jsx("div",{className:"tabbed-pane-tab-label",children:l}),!!i&&Z.jsx("div",{className:"tabbed-pane-tab-counter",children:i}),!!u&&Z.jsx("div",{className:"tabbed-pane-tab-counter error",children:u})]}),I1=({sources:s,fileId:l,setFileId:i})=>Z.jsx("select",{className:"source-chooser",hidden:!s.length,title:"Source chooser",value:l,onChange:u=>{i(u.target.selectedOptions[0].value)},children:P1(s)});function P1(s){const l=c=>c.replace(/.*[/\\]([^/\\]+)/,"$1"),i=c=>Z.jsx("option",{value:c.id,children:l(c.label)},c.id),u=new Map;for(const c of s){let o=u.get(c.group||"Debugger");o||(o=[],u.set(c.group||"Debugger",o)),o.push(c)}return[...u.entries()].map(([c,o])=>Z.jsx("optgroup",{label:c,children:o.filter(h=>(h.group||"Debugger")===c).map(h=>i(h))},c))}function ev(){return{id:"default",isRecorded:!1,text:"",language:"javascript",label:"",highlight:[]}}const Dt=oe.forwardRef(function({children:l,title:i="",icon:u,disabled:c=!1,toggled:o=!1,onClick:h=()=>{},style:m,testId:g,className:p,ariaLabel:E},v){return Z.jsxs("button",{ref:v,className:wl(p,"toolbar-button",u,o&&"toggled"),onMouseDown:dg,onClick:h,onDoubleClick:dg,title:i,disabled:!!c,style:m,"data-testid":g,"aria-label":E||i,children:[u&&Z.jsx("span",{className:`codicon codicon-${u}`,style:l?{marginRight:5}:{}}),l]})}),hg=({style:s})=>Z.jsx("div",{className:"toolbar-separator",style:s}),dg=s=>{s.stopPropagation(),s.preventDefault()},Je=function(s,l,i){return s>=l&&s<=i};function bt(s){return Je(s,48,57)}function mg(s){return bt(s)||Je(s,65,70)||Je(s,97,102)}function tv(s){return Je(s,65,90)}function nv(s){return Je(s,97,122)}function lv(s){return tv(s)||nv(s)}function av(s){return s>=128}function uu(s){return lv(s)||av(s)||s===95}function gg(s){return uu(s)||bt(s)||s===45}function iv(s){return Je(s,0,8)||s===11||Je(s,14,31)||s===127}function cu(s){return s===10}function En(s){return cu(s)||s===9||s===32}const sv=1114111;class Df extends Error{constructor(l){super(l),this.name="InvalidCharacterError"}}function uv(s){const l=[];for(let i=0;i=l.length?-1:l[q]},h=function(q){if(q===void 0&&(q=1),q>3)throw"Spec Error: no more than three codepoints of lookahead.";return o(i+q)},m=function(q){return q===void 0&&(q=1),i+=q,c=o(i),!0},g=function(){return i-=1,!0},p=function(q){return q===void 0&&(q=c),q===-1},E=function(){if(v(),m(),En(c)){for(;En(h());)m();return new Af}else{if(c===34)return z();if(c===35)if(gg(h())||x(h(1),h(2))){const q=new Qg("");return Y(h(1),h(2),h(3))&&(q.type="id"),q.value=G(),q}else return new ut(c);else return c===36?h()===61?(m(),new hv):new ut(c):c===39?z():c===40?new $g:c===41?new Yg:c===42?h()===61?(m(),new dv):new ut(c):c===43?K()?(g(),_()):new ut(c):c===44?new Rg:c===45?K()?(g(),_()):h(1)===45&&h(2)===62?(m(2),new Ug):X()?(g(),A()):new ut(c):c===46?K()?(g(),_()):new ut(c):c===58?new jg:c===59?new Bg:c===60?h(1)===33&&h(2)===45&&h(3)===45?(m(3),new Lg):new ut(c):c===64?Y(h(1),h(2),h(3))?new Vg(G()):new ut(c):c===91?new Hg:c===92?j()?(g(),A()):new ut(c):c===93?new wf:c===94?h()===61?(m(),new ov):new ut(c):c===123?new kg:c===124?h()===61?(m(),new fv):h()===124?(m(),new Gg):new ut(c):c===125?new qg:c===126?h()===61?(m(),new rv):new ut(c):bt(c)?(g(),_()):uu(c)?(g(),A()):p()?new fu:new ut(c)}},v=function(){for(;h(1)===47&&h(2)===42;)for(m(2);;)if(m(),c===42&&h()===47){m();break}else if(p())return},_=function(){const q=V();if(Y(h(1),h(2),h(3))){const le=new mv;return le.value=q.value,le.repr=q.repr,le.type=q.type,le.unit=G(),le}else if(h()===37){m();const le=new Wg;return le.value=q.value,le.repr=q.repr,le}else{const le=new Jg;return le.value=q.value,le.repr=q.repr,le.type=q.type,le}},A=function(){const q=G();if(q.toLowerCase()==="url"&&h()===40){for(m();En(h(1))&&En(h(2));)m();return h()===34||h()===39?new ou(q):En(h())&&(h(2)===34||h(2)===39)?new ou(q):S()}else return h()===40?(m(),new ou(q)):new Kg(q)},z=function(q){q===void 0&&(q=c);let le="";for(;m();){if(c===q||p())return new Xg(le);if(cu(c))return g(),new Dg;c===92?p(h())||(cu(h())?m():le+=Fe(T())):le+=Fe(c)}throw new Error("Internal error")},S=function(){const q=new Zg("");for(;En(h());)m();if(p(h()))return q;for(;m();){if(c===41||p())return q;if(En(c)){for(;En(h());)m();return h()===41||p(h())?(m(),q):(he(),new ru)}else{if(c===34||c===39||c===40||iv(c))return he(),new ru;if(c===92)if(j())q.value+=Fe(T());else return he(),new ru;else q.value+=Fe(c)}}throw new Error("Internal error")},T=function(){if(m(),mg(c)){const q=[c];for(let ze=0;ze<5&&mg(h());ze++)m(),q.push(c);En(h())&&m();let le=parseInt(q.map(function(ze){return String.fromCharCode(ze)}).join(""),16);return le>sv&&(le=65533),le}else return p()?65533:c},x=function(q,le){return!(q!==92||cu(le))},j=function(){return x(c,h())},Y=function(q,le,ze){return q===45?uu(le)||le===45||x(le,ze):uu(q)?!0:q===92?x(q,le):!1},X=function(){return Y(c,h(1),h(2))},W=function(q,le,ze){return q===43||q===45?!!(bt(le)||le===46&&bt(ze)):q===46?!!bt(le):!!bt(q)},K=function(){return W(c,h(1),h(2))},G=function(){let q="";for(;m();)if(gg(c))q+=Fe(c);else if(j())q+=Fe(T());else return g(),q;throw new Error("Internal parse error")},V=function(){let q="",le="integer";for((h()===43||h()===45)&&(m(),q+=Fe(c));bt(h());)m(),q+=Fe(c);if(h(1)===46&&bt(h(2)))for(m(),q+=Fe(c),m(),q+=Fe(c),le="number";bt(h());)m(),q+=Fe(c);const ze=h(1),ie=h(2),D=h(3);if((ze===69||ze===101)&&bt(ie))for(m(),q+=Fe(c),m(),q+=Fe(c),le="number";bt(h());)m(),q+=Fe(c);else if((ze===69||ze===101)&&(ie===43||ie===45)&&bt(D))for(m(),q+=Fe(c),m(),q+=Fe(c),m(),q+=Fe(c),le="number";bt(h());)m(),q+=Fe(c);const Q=B(q);return{type:le,value:Q,repr:q}},B=function(q){return+q},he=function(){for(;m();){if(c===41||p())return;j()&&T()}};let ne=0;for(;!p(h());)if(u.push(E()),ne++,ne>l.length*2)throw new Error("I'm infinite-looping!");return u}class Ke{constructor(){this.tokenType=""}toJSON(){return{token:this.tokenType}}toString(){return this.tokenType}toSource(){return""+this}}class Dg extends Ke{constructor(){super(...arguments),this.tokenType="BADSTRING"}}class ru extends Ke{constructor(){super(...arguments),this.tokenType="BADURL"}}class Af extends Ke{constructor(){super(...arguments),this.tokenType="WHITESPACE"}toString(){return"WS"}toSource(){return" "}}class Lg extends Ke{constructor(){super(...arguments),this.tokenType="CDO"}toSource(){return""}}class jg extends Ke{constructor(){super(...arguments),this.tokenType=":"}}class Bg extends Ke{constructor(){super(...arguments),this.tokenType=";"}}class Rg extends Ke{constructor(){super(...arguments),this.tokenType=","}}class wa extends Ke{constructor(){super(...arguments),this.value="",this.mirror=""}}class kg extends wa{constructor(){super(),this.tokenType="{",this.value="{",this.mirror="}"}}class qg extends wa{constructor(){super(),this.tokenType="}",this.value="}",this.mirror="{"}}class Hg extends wa{constructor(){super(),this.tokenType="[",this.value="[",this.mirror="]"}}class wf extends wa{constructor(){super(),this.tokenType="]",this.value="]",this.mirror="["}}class $g extends wa{constructor(){super(),this.tokenType="(",this.value="(",this.mirror=")"}}class Yg extends wa{constructor(){super(),this.tokenType=")",this.value=")",this.mirror="("}}class rv extends Ke{constructor(){super(...arguments),this.tokenType="~="}}class fv extends Ke{constructor(){super(...arguments),this.tokenType="|="}}class ov extends Ke{constructor(){super(...arguments),this.tokenType="^="}}class hv extends Ke{constructor(){super(...arguments),this.tokenType="$="}}class dv extends Ke{constructor(){super(...arguments),this.tokenType="*="}}class Gg extends Ke{constructor(){super(...arguments),this.tokenType="||"}}class fu extends Ke{constructor(){super(...arguments),this.tokenType="EOF"}toSource(){return""}}class ut extends Ke{constructor(l){super(),this.tokenType="DELIM",this.value="",this.value=Fe(l)}toString(){return"DELIM("+this.value+")"}toJSON(){const l=this.constructor.prototype.constructor.prototype.toJSON.call(this);return l.value=this.value,l}toSource(){return this.value==="\\"?`\\ +`:this.value}}class Oa extends Ke{constructor(){super(...arguments),this.value=""}ASCIIMatch(l){return this.value.toLowerCase()===l.toLowerCase()}toJSON(){const l=this.constructor.prototype.constructor.prototype.toJSON.call(this);return l.value=this.value,l}}class Kg extends Oa{constructor(l){super(),this.tokenType="IDENT",this.value=l}toString(){return"IDENT("+this.value+")"}toSource(){return Ui(this.value)}}class ou extends Oa{constructor(l){super(),this.tokenType="FUNCTION",this.value=l,this.mirror=")"}toString(){return"FUNCTION("+this.value+")"}toSource(){return Ui(this.value)+"("}}class Vg extends Oa{constructor(l){super(),this.tokenType="AT-KEYWORD",this.value=l}toString(){return"AT("+this.value+")"}toSource(){return"@"+Ui(this.value)}}class Qg extends Oa{constructor(l){super(),this.tokenType="HASH",this.value=l,this.type="unrestricted"}toString(){return"HASH("+this.value+")"}toJSON(){const l=this.constructor.prototype.constructor.prototype.toJSON.call(this);return l.value=this.value,l.type=this.type,l}toSource(){return this.type==="id"?"#"+Ui(this.value):"#"+gv(this.value)}}class Xg extends Oa{constructor(l){super(),this.tokenType="STRING",this.value=l}toString(){return'"'+Fg(this.value)+'"'}}class Zg extends Oa{constructor(l){super(),this.tokenType="URL",this.value=l}toString(){return"URL("+this.value+")"}toSource(){return'url("'+Fg(this.value)+'")'}}class Jg extends Ke{constructor(){super(),this.tokenType="NUMBER",this.type="integer",this.repr=""}toString(){return this.type==="integer"?"INT("+this.value+")":"NUMBER("+this.value+")"}toJSON(){const l=super.toJSON();return l.value=this.value,l.type=this.type,l.repr=this.repr,l}toSource(){return this.repr}}class Wg extends Ke{constructor(){super(),this.tokenType="PERCENTAGE",this.repr=""}toString(){return"PERCENTAGE("+this.value+")"}toJSON(){const l=this.constructor.prototype.constructor.prototype.toJSON.call(this);return l.value=this.value,l.repr=this.repr,l}toSource(){return this.repr+"%"}}class mv extends Ke{constructor(){super(),this.tokenType="DIMENSION",this.type="integer",this.repr="",this.unit=""}toString(){return"DIM("+this.value+","+this.unit+")"}toJSON(){const l=this.constructor.prototype.constructor.prototype.toJSON.call(this);return l.value=this.value,l.type=this.type,l.repr=this.repr,l.unit=this.unit,l}toSource(){const l=this.repr;let i=Ui(this.unit);return i[0].toLowerCase()==="e"&&(i[1]==="-"||Je(i.charCodeAt(1),48,57))&&(i="\\65 "+i.slice(1,i.length)),l+i}}function Ui(s){s=""+s;let l="";const i=s.charCodeAt(0);for(let u=0;u=128||c===45||c===95||Je(c,48,57)||Je(c,65,90)||Je(c,97,122)?l+=s[u]:l+="\\"+s[u]}return l}function gv(s){s=""+s;let l="";for(let i=0;i=128||u===45||u===95||Je(u,48,57)||Je(u,65,90)||Je(u,97,122)?l+=s[i]:l+="\\"+u.toString(16)+" "}return l}function Fg(s){s=""+s;let l="";for(let i=0;iB instanceof Vg||B instanceof Dg||B instanceof ru||B instanceof Gg||B instanceof Lg||B instanceof Ug||B instanceof Bg||B instanceof kg||B instanceof qg||B instanceof Zg||B instanceof Wg);if(u)throw new St(`Unsupported token "${u.toSource()}" while parsing css selector "${s}". Did you mean to CSS.escape it?`);let c=0;const o=new Set;function h(){return new St(`Unexpected token "${i[c].toSource()}" while parsing css selector "${s}". Did you mean to CSS.escape it?`)}function m(){for(;i[c]instanceof Af;)c++}function g(B=c){return i[B]instanceof Kg}function p(B=c){return i[B]instanceof Xg}function E(B=c){return i[B]instanceof Jg}function v(B=c){return i[B]instanceof Rg}function _(B=c){return i[B]instanceof $g}function A(B=c){return i[B]instanceof Yg}function z(B=c){return i[B]instanceof ou}function S(B=c){return i[B]instanceof ut&&i[B].value==="*"}function T(B=c){return i[B]instanceof fu}function x(B=c){return i[B]instanceof ut&&[">","+","~"].includes(i[B].value)}function j(B=c){return v(B)||A(B)||T(B)||x(B)||i[B]instanceof Af}function Y(){const B=[X()];for(;m(),!!v();)c++,B.push(X());return B}function X(){return m(),E()||p()?i[c++].value:W()}function W(){const B={simples:[]};for(m(),x()?B.simples.push({selector:{functions:[{name:"scope",args:[]}]},combinator:""}):B.simples.push({selector:K(),combinator:""});;){if(m(),x())B.simples[B.simples.length-1].combinator=i[c++].value,m();else if(j())break;B.simples.push({combinator:"",selector:K()})}return B}function K(){let B="";const he=[];for(;!j();)if(g()||S())B+=i[c++].toSource();else if(i[c]instanceof Qg)B+=i[c++].toSource();else if(i[c]instanceof ut&&i[c].value===".")if(c++,g())B+="."+i[c++].toSource();else throw h();else if(i[c]instanceof jg)if(c++,g())if(!l.has(i[c].value.toLowerCase()))B+=":"+i[c++].toSource();else{const ne=i[c++].value.toLowerCase();he.push({name:ne,args:[]}),o.add(ne)}else if(z()){const ne=i[c++].value.toLowerCase();if(l.has(ne)?(he.push({name:ne,args:Y()}),o.add(ne)):B+=`:${ne}(${G()})`,m(),!A())throw h();c++}else throw h();else if(i[c]instanceof Hg){for(B+="[",c++;!(i[c]instanceof wf)&&!T();)B+=i[c++].toSource();if(!(i[c]instanceof wf))throw h();B+="]",c++}else throw h();if(!B&&!he.length)throw h();return{css:B||void 0,functions:he}}function G(){let B="",he=1;for(;!T()&&((_()||z())&&he++,A()&&he--,!!he);)B+=i[c++].toSource();return B}const V=Y();if(!T())throw h();if(V.some(B=>typeof B!="object"||!("simples"in B)))throw new St(`Error while parsing css selector "${s}". Did you mean to CSS.escape it?`);return{selector:V,names:Array.from(o)}}const pg=new Set(["internal:has","internal:has-not","internal:and","internal:or","internal:chain","left-of","right-of","above","below","near"]),yv=new Set(["left-of","right-of","above","below","near"]),vv=new Set(["not","is","where","has","scope","light","visible","text","text-matches","text-is","has-text","above","below","right-of","left-of","near","nth-match"]);function Ig(s){const l=Sv(s),i=[];for(const u of l.parts){if(u.name==="css"||u.name==="css:light"){u.name==="css:light"&&(u.body=":light("+u.body+")");const c=pv(u.body,vv);i.push({name:"css",body:c.selector,source:u.body});continue}if(pg.has(u.name)){let c,o;try{const p=JSON.parse("["+u.body+"]");if(!Array.isArray(p)||p.length<1||p.length>2||typeof p[0]!="string")throw new St(`Malformed selector: ${u.name}=`+u.body);if(c=p[0],p.length===2){if(typeof p[1]!="number"||!yv.has(u.name))throw new St(`Malformed selector: ${u.name}=`+u.body);o=p[1]}}catch{throw new St(`Malformed selector: ${u.name}=`+u.body)}const h={name:u.name,source:u.body,body:{parsed:Ig(c),distance:o}},m=[...h.body.parsed.parts].reverse().find(p=>p.name==="internal:control"&&p.body==="enter-frame"),g=m?h.body.parsed.parts.indexOf(m):-1;g!==-1&&bv(h.body.parsed.parts.slice(0,g+1),i.slice(0,g+1))&&h.body.parsed.parts.splice(0,g+1),i.push(h);continue}i.push({...u,source:u.body})}if(pg.has(i[0].name))throw new St(`"${i[0].name}" selector cannot be first`);return{capture:l.capture,parts:i}}function bv(s,l){return ga({parts:s})===ga({parts:l})}function ga(s,l){return typeof s=="string"?s:s.parts.map((i,u)=>{let c=!0;!l&&u!==s.capture&&(i.name==="css"||i.name==="xpath"&&i.source.startsWith("//")||i.source.startsWith(".."))&&(c=!1);const o=c?i.name+"=":"";return`${u===s.capture?"*":""}${o}${i.source}`}).join(" >> ")}function Sv(s){let l=0,i,u=0;const c={parts:[]},o=()=>{const m=s.substring(u,l).trim(),g=m.indexOf("=");let p,E;g!==-1&&m.substring(0,g).trim().match(/^[a-zA-Z_0-9-+:*]+$/)?(p=m.substring(0,g).trim(),E=m.substring(g+1)):m.length>1&&m[0]==='"'&&m[m.length-1]==='"'||m.length>1&&m[0]==="'"&&m[m.length-1]==="'"?(p="text",E=m):/^\(*\/\//.test(m)||m.startsWith("..")?(p="xpath",E=m):(p="css",E=m);let v=!1;if(p[0]==="*"&&(v=!0,p=p.substring(1)),c.parts.push({name:p,body:E}),v){if(c.capture!==void 0)throw new St("Only one of the selectors can capture using * modifier");c.capture=c.parts.length-1}};if(!s.includes(">>"))return l=s.length,o(),c;const h=()=>{const g=s.substring(u,l).match(/^\s*text\s*=(.*)$/);return!!g&&!!g[1]};for(;l"&&s[l+1]===">"?(o(),l+=2,u=l):l++}return o(),c}function of(s,l){let i=0,u=s.length===0;const c=()=>s[i]||"",o=()=>{const T=c();return++i,u=i>=s.length,T},h=T=>{throw u?new St(`Unexpected end of selector while parsing selector \`${s}\``):new St(`Error while parsing selector \`${s}\` - unexpected symbol "${c()}" at position ${i}`+(T?" during "+T:""))};function m(){for(;!u&&/\s/.test(c());)o()}function g(T){return T>="€"||T>="0"&&T<="9"||T>="A"&&T<="Z"||T>="a"&&T<="z"||T>="0"&&T<="9"||T==="_"||T==="-"}function p(){let T="";for(m();!u&&g(c());)T+=o();return T}function E(T){let x=o();for(x!==T&&h("parsing quoted string");!u&&c()!==T;)c()==="\\"&&o(),x+=o();return c()!==T&&h("parsing quoted string"),x+=o(),x}function v(){o()!=="/"&&h("parsing regular expression");let T="",x=!1;for(;!u;){if(c()==="\\")T+=o(),u&&h("parsing regular expression");else if(x&&c()==="]")x=!1;else if(!x&&c()==="[")x=!0;else if(!x&&c()==="/")break;T+=o()}o()!=="/"&&h("parsing regular expression");let j="";for(;!u&&c().match(/[dgimsuy]/);)j+=o();try{return new RegExp(T,j)}catch(Y){throw new St(`Error while parsing selector \`${s}\`: ${Y.message}`)}}function _(){let T="";return m(),c()==="'"||c()==='"'?T=E(c()).slice(1,-1):T=p(),T||h("parsing property path"),T}function A(){m();let T="";return u||(T+=o()),!u&&T!=="="&&(T+=o()),["=","*=","^=","$=","|=","~="].includes(T)||h("parsing operator"),T}function z(){o();const T=[];for(T.push(_()),m();c()===".";)o(),T.push(_()),m();if(c()==="]")return o(),{name:T.join("."),jsonPath:T,op:"",value:null,caseSensitive:!1};const x=A();let j,Y=!0;if(m(),c()==="/"){if(x!=="=")throw new St(`Error while parsing selector \`${s}\` - cannot use ${x} in attribute with regular expression`);j=v()}else if(c()==="'"||c()==='"')j=E(c()).slice(1,-1),m(),c()==="i"||c()==="I"?(Y=!1,o()):(c()==="s"||c()==="S")&&(Y=!0,o());else{for(j="";!u&&(g(c())||c()==="+"||c()===".");)j+=o();j==="true"?j=!0:j==="false"&&(j=!1)}if(m(),c()!=="]"&&h("parsing attribute value"),o(),x!=="="&&typeof j!="string")throw new St(`Error while parsing selector \`${s}\` - cannot use ${x} in attribute with non-string matching value - ${j}`);return{name:T.join("."),jsonPath:T,op:x,value:j,caseSensitive:Y}}const S={name:"",attributes:[]};for(S.name=p(),m();c()==="[";)S.attributes.push(z()),m();if(u||h(void 0),!S.name&&!S.attributes.length)throw new St(`Error while parsing selector \`${s}\` - selector cannot be empty`);return S}function Au(s,l="'"){const i=JSON.stringify(s),u=i.substring(1,i.length-1).replace(/\\"/g,'"');if(l==="'")return l+u.replace(/[']/g,"\\'")+l;if(l==='"')return l+u.replace(/["]/g,'\\"')+l;if(l==="`")return l+u.replace(/[`]/g,"\\`")+l;throw new Error("Invalid escape char")}function yu(s){return s.charAt(0).toUpperCase()+s.substring(1)}function Pg(s){return s.replace(/([a-z0-9])([A-Z])/g,"$1_$2").replace(/([A-Z])([A-Z][a-z])/g,"$1_$2").toLowerCase()}function wu(s){return s.replace(/(^|[^\\])(\\\\)*\\(['"`])/g,"$1$2$3")}function ep(s,l,i=!1){return Tv(s,l,i,1)[0]}function Tv(s,l,i=!1,u=20,c){try{return ma(new Mv[s](c),Ig(l),i,u)}catch{return[l]}}function ma(s,l,i=!1,u=20){const c=[...l.parts],o=[];let h=i?"frame-locator":"page";for(let m=0;ms.generateLocator(p,"has",S)));continue}if(g.name==="internal:has-not"){const z=ma(s,g.body.parsed,!1,u);o.push(z.map(S=>s.generateLocator(p,"hasNot",S)));continue}if(g.name==="internal:and"){const z=ma(s,g.body.parsed,!1,u);o.push(z.map(S=>s.generateLocator(p,"and",S)));continue}if(g.name==="internal:or"){const z=ma(s,g.body.parsed,!1,u);o.push(z.map(S=>s.generateLocator(p,"or",S)));continue}if(g.name==="internal:chain"){const z=ma(s,g.body.parsed,!1,u);o.push(z.map(S=>s.generateLocator(p,"chain",S)));continue}if(g.name==="internal:label"){const{exact:z,text:S}=Ni(g.body);o.push([s.generateLocator(p,"label",S,{exact:z})]);continue}if(g.name==="internal:role"){const z=of(g.body),S={attrs:[]};for(const T of z.attributes)T.name==="name"?(S.exact=T.caseSensitive,S.name=T.value):(T.name==="level"&&typeof T.value=="string"&&(T.value=+T.value),S.attrs.push({name:T.name==="include-hidden"?"includeHidden":T.name,value:T.value}));o.push([s.generateLocator(p,"role",z.name,S)]);continue}if(g.name==="internal:testid"){const z=of(g.body),{value:S}=z.attributes[0];o.push([s.generateLocator(p,"test-id",S)]);continue}if(g.name==="internal:attr"){const z=of(g.body),{name:S,value:T,caseSensitive:x}=z.attributes[0],j=T,Y=!!x;if(S==="placeholder"){o.push([s.generateLocator(p,"placeholder",j,{exact:Y})]);continue}if(S==="alt"){o.push([s.generateLocator(p,"alt",j,{exact:Y})]);continue}if(S==="title"){o.push([s.generateLocator(p,"title",j,{exact:Y})]);continue}}if(g.name==="internal:control"&&g.body==="enter-frame"){const z=o[o.length-1],S=c[m-1],T=z.map(x=>s.chainLocators([x,s.generateLocator(p,"frame","")]));["xpath","css"].includes(S.name)&&T.push(s.generateLocator(p,"frame-locator",ga({parts:[S]})),s.generateLocator(p,"frame-locator",ga({parts:[S]},!0))),z.splice(0,z.length,...T),h="frame-locator";continue}const E=c[m+1],v=ga({parts:[g]}),_=s.generateLocator(p,"default",v);if(E&&["internal:has-text","internal:has-not-text"].includes(E.name)){const{exact:z,text:S}=Ni(E.body);if(!z){const T=s.generateLocator("locator",E.name==="internal:has-text"?"has-text":"has-not-text",S,{exact:z}),x={};E.name==="internal:has-text"?x.hasText=S:x.hasNotText=S;const j=s.generateLocator(p,"default",v,x);o.push([s.chainLocators([_,T]),j]),m++;continue}}let A;if(["xpath","css"].includes(g.name)){const z=ga({parts:[g]},!0);A=s.generateLocator(p,"default",z)}o.push([_,A].filter(Boolean))}return Ev(s,o,u)}function Ev(s,l,i){const u=l.map(()=>""),c=[],o=h=>{if(h===l.length)return c.push(s.chainLocators(u)),c.lengthJSON.parse(u));for(let u=0;u{const i=oe.useRef(null),[u,c]=oe.useState(new Map);return oe.useLayoutEffect(()=>{var o;l.find(h=>h.reveal)&&((o=i.current)==null||o.scrollIntoView({block:"center",inline:"nearest"}))},[i,l]),Z.jsxs("div",{className:"call-log",style:{flex:"auto"},children:[l.map(o=>{const h=u.get(o.id),m=typeof h=="boolean"?h:o.status!=="done",g=o.params.selector?ep(s,o.params.selector):null;let p=o.title,E="";return o.title.startsWith("expect.to")||o.title.startsWith("expect.not.to")?(p="expect(",E=`).${o.title.substring(7)}()`):o.title.startsWith("locator.")?(p="",E=`.${o.title.substring(8)}()`):(g||o.params.url)&&(p=o.title+"(",E=")"),Z.jsxs("div",{className:wl("call-log-call",o.status),children:[Z.jsxs("div",{className:"call-log-call-header",children:[Z.jsx("span",{className:wl("codicon",`codicon-chevron-${m?"down":"right"}`),style:{cursor:"pointer"},onClick:()=>{const v=new Map(u);v.set(o.id,!m),c(v)}}),p,o.params.url?Z.jsx("span",{className:"call-log-details",children:Z.jsx("span",{className:"call-log-url",title:o.params.url,children:o.params.url})}):void 0,g?Z.jsx("span",{className:"call-log-details",children:Z.jsx("span",{className:"call-log-selector",title:`page.${g}`,children:`page.${g}`})}):void 0,E,Z.jsx("span",{className:wl("codicon",zv(o))}),typeof o.duration=="number"?Z.jsxs("span",{className:"call-log-time",children:["— ",E1(o.duration)]}):void 0]}),(m?o.messages:[]).map((v,_)=>Z.jsx("div",{className:"call-log-message",children:v.trim()},_)),!!o.error&&Z.jsx("div",{className:"call-log-message error",hidden:!m,children:o.error})]},o.id)}),Z.jsx("div",{ref:i})]})};function zv(s){switch(s.status){case"done":return"codicon-check";case"in-progress":return"codicon-clock";case"paused":return"codicon-debug-pause";case"error":return"codicon-error"}}const Lf=Symbol.for("yaml.alias"),Of=Symbol.for("yaml.document"),Fn=Symbol.for("yaml.map"),tp=Symbol.for("yaml.pair"),nn=Symbol.for("yaml.scalar"),_a=Symbol.for("yaml.seq"),Vt=Symbol.for("yaml.node.type"),_l=s=>!!s&&typeof s=="object"&&s[Vt]===Lf,Nl=s=>!!s&&typeof s=="object"&&s[Vt]===Of,Na=s=>!!s&&typeof s=="object"&&s[Vt]===Fn,Be=s=>!!s&&typeof s=="object"&&s[Vt]===tp,De=s=>!!s&&typeof s=="object"&&s[Vt]===nn,Ma=s=>!!s&&typeof s=="object"&&s[Vt]===_a;function Re(s){if(s&&typeof s=="object")switch(s[Vt]){case Fn:case _a:return!0}return!1}function ke(s){if(s&&typeof s=="object")switch(s[Vt]){case Lf:case Fn:case nn:case _a:return!0}return!1}const xv=s=>(De(s)||Re(s))&&!!s.anchor,Tt=Symbol("break visit"),np=Symbol("skip children"),tn=Symbol("remove node");function In(s,l){const i=lp(l);Nl(s)?pa(null,s.contents,i,Object.freeze([s]))===tn&&(s.contents=null):pa(null,s,i,Object.freeze([]))}In.BREAK=Tt;In.SKIP=np;In.REMOVE=tn;function pa(s,l,i,u){const c=ap(s,l,i,u);if(ke(c)||Be(c))return ip(s,u,c),pa(s,c,i,u);if(typeof c!="symbol"){if(Re(l)){u=Object.freeze(u.concat(l));for(let o=0;os.replace(/[!,[\]{}]/g,l=>Dv[l]);class ot{constructor(l,i){this.docStart=null,this.docEnd=!1,this.yaml=Object.assign({},ot.defaultYaml,l),this.tags=Object.assign({},ot.defaultTags,i)}clone(){const l=new ot(this.yaml,this.tags);return l.docStart=this.docStart,l}atDocument(){const l=new ot(this.yaml,this.tags);switch(this.yaml.version){case"1.1":this.atNextDocument=!0;break;case"1.2":this.atNextDocument=!1,this.yaml={explicit:ot.defaultYaml.explicit,version:"1.2"},this.tags=Object.assign({},ot.defaultTags);break}return l}add(l,i){this.atNextDocument&&(this.yaml={explicit:ot.defaultYaml.explicit,version:"1.1"},this.tags=Object.assign({},ot.defaultTags),this.atNextDocument=!1);const u=l.trim().split(/[ \t]+/),c=u.shift();switch(c){case"%TAG":{if(u.length!==2&&(i(0,"%TAG directive should contain exactly two parts"),u.length<2))return!1;const[o,h]=u;return this.tags[o]=h,!0}case"%YAML":{if(this.yaml.explicit=!0,u.length!==1)return i(0,"%YAML directive should contain exactly one part"),!1;const[o]=u;if(o==="1.1"||o==="1.2")return this.yaml.version=o,!0;{const h=/^\d+\.\d+$/.test(o);return i(6,`Unsupported YAML version ${o}`,h),!1}}default:return i(0,`Unknown directive ${c}`,!0),!1}}tagName(l,i){if(l==="!")return"!";if(l[0]!=="!")return i(`Not a valid tag: ${l}`),null;if(l[1]==="<"){const h=l.slice(2,-1);return h==="!"||h==="!!"?(i(`Verbatim tags aren't resolved, so ${l} is invalid.`),null):(l[l.length-1]!==">"&&i("Verbatim tags must end with a >"),h)}const[,u,c]=l.match(/^(.*!)([^!]*)$/s);c||i(`The ${l} tag has no suffix`);const o=this.tags[u];if(o)try{return o+decodeURIComponent(c)}catch(h){return i(String(h)),null}return u==="!"?l:(i(`Could not resolve tag: ${l}`),null)}tagString(l){for(const[i,u]of Object.entries(this.tags))if(l.startsWith(u))return i+Lv(l.substring(u.length));return l[0]==="!"?l:`!<${l}>`}toString(l){const i=this.yaml.explicit?[`%YAML ${this.yaml.version||"1.2"}`]:[],u=Object.entries(this.tags);let c;if(l&&u.length>0&&ke(l.contents)){const o={};In(l.contents,(h,m)=>{ke(m)&&m.tag&&(o[m.tag]=!0)}),c=Object.keys(o)}else c=[];for(const[o,h]of u)o==="!!"&&h==="tag:yaml.org,2002:"||(!l||c.some(m=>m.startsWith(h)))&&i.push(`%TAG ${o} ${h}`);return i.join(` +`)}}ot.defaultYaml={explicit:!1,version:"1.2"};ot.defaultTags={"!!":"tag:yaml.org,2002:"};function sp(s){if(/[\x00-\x19\s,[\]{}]/.test(s)){const i=`Anchor must not contain whitespace or control characters: ${JSON.stringify(s)}`;throw new Error(i)}return!0}function up(s){const l=new Set;return In(s,{Value(i,u){u.anchor&&l.add(u.anchor)}}),l}function cp(s,l){for(let i=1;;++i){const u=`${s}${i}`;if(!l.has(u))return u}}function Uv(s,l){const i=[],u=new Map;let c=null;return{onAnchor:o=>{i.push(o),c||(c=up(s));const h=cp(l,c);return c.add(h),h},setAnchors:()=>{for(const o of i){const h=u.get(o);if(typeof h=="object"&&h.anchor&&(De(h.node)||Re(h.node)))h.node.anchor=h.anchor;else{const m=new Error("Failed to resolve repeated object (this should not happen)");throw m.source=o,m}}},sourceObjects:u}}function va(s,l,i,u){if(u&&typeof u=="object")if(Array.isArray(u))for(let c=0,o=u.length;cKt(u,String(c),i));if(s&&typeof s.toJSON=="function"){if(!i||!xv(s))return s.toJSON(l,i);const u={aliasCount:0,count:1,res:void 0};i.anchors.set(s,u),i.onCreate=o=>{u.res=o,delete i.onCreate};const c=s.toJSON(l,i);return i.onCreate&&i.onCreate(c),c}return typeof s=="bigint"&&!(i!=null&&i.keep)?Number(s):s}class Uf{constructor(l){Object.defineProperty(this,Vt,{value:l})}clone(){const l=Object.create(Object.getPrototypeOf(this),Object.getOwnPropertyDescriptors(this));return this.range&&(l.range=this.range.slice()),l}toJS(l,{mapAsMap:i,maxAliasCount:u,onAnchor:c,reviver:o}={}){if(!Nl(l))throw new TypeError("A document argument is required");const h={anchors:new Map,doc:l,keep:!0,mapAsMap:i===!0,mapKeyWarned:!1,maxAliasCount:typeof u=="number"?u:100},m=Kt(this,"",h);if(typeof c=="function")for(const{count:g,res:p}of h.anchors.values())c(p,g);return typeof o=="function"?va(o,{"":m},"",m):m}}class _u extends Uf{constructor(l){super(Lf),this.source=l,Object.defineProperty(this,"tag",{set(){throw new Error("Alias nodes cannot have tags")}})}resolve(l){let i;return In(l,{Node:(u,c)=>{if(c===this)return In.BREAK;c.anchor===this.source&&(i=c)}}),i}toJSON(l,i){if(!i)return{source:this.source};const{anchors:u,doc:c,maxAliasCount:o}=i,h=this.resolve(c);if(!h){const g=`Unresolved alias (the anchor must be set before the alias): ${this.source}`;throw new ReferenceError(g)}let m=u.get(h);if(m||(Kt(h,null,i),m=u.get(h)),!m||m.res===void 0){const g="This should not happen: Alias anchor was not resolved?";throw new ReferenceError(g)}if(o>=0&&(m.count+=1,m.aliasCount===0&&(m.aliasCount=hu(c,h,u)),m.count*m.aliasCount>o)){const g="Excessive alias count indicates a resource exhaustion attack";throw new ReferenceError(g)}return m.res}toString(l,i,u){const c=`*${this.source}`;if(l){if(sp(this.source),l.options.verifyAliasOrder&&!l.anchors.has(this.source)){const o=`Unresolved alias (the anchor must be set before the alias): ${this.source}`;throw new Error(o)}if(l.implicitKey)return`${c} `}return c}}function hu(s,l,i){if(_l(l)){const u=l.resolve(s),c=i&&u&&i.get(u);return c?c.count*c.aliasCount:0}else if(Re(l)){let u=0;for(const c of l.items){const o=hu(s,c,i);o>u&&(u=o)}return u}else if(Be(l)){const u=hu(s,l.key,i),c=hu(s,l.value,i);return Math.max(u,c)}return 1}const rp=s=>!s||typeof s!="function"&&typeof s!="object";class ue extends Uf{constructor(l){super(nn),this.value=l}toJSON(l,i){return i!=null&&i.keep?this.value:Kt(this.value,l,i)}toString(){return String(this.value)}}ue.BLOCK_FOLDED="BLOCK_FOLDED";ue.BLOCK_LITERAL="BLOCK_LITERAL";ue.PLAIN="PLAIN";ue.QUOTE_DOUBLE="QUOTE_DOUBLE";ue.QUOTE_SINGLE="QUOTE_SINGLE";const jv="tag:yaml.org,2002:";function Bv(s,l,i){if(l){const u=i.filter(o=>o.tag===l),c=u.find(o=>!o.format)??u[0];if(!c)throw new Error(`Tag ${l} not found`);return c}return i.find(u=>{var c;return((c=u.identify)==null?void 0:c.call(u,s))&&!u.format})}function xi(s,l,i){var v,_,A;if(Nl(s)&&(s=s.contents),ke(s))return s;if(Be(s)){const z=(_=(v=i.schema[Fn]).createNode)==null?void 0:_.call(v,i.schema,null,i);return z.items.push(s),z}(s instanceof String||s instanceof Number||s instanceof Boolean||typeof BigInt<"u"&&s instanceof BigInt)&&(s=s.valueOf());const{aliasDuplicateObjects:u,onAnchor:c,onTagObj:o,schema:h,sourceObjects:m}=i;let g;if(u&&s&&typeof s=="object"){if(g=m.get(s),g)return g.anchor||(g.anchor=c(s)),new _u(g.anchor);g={anchor:null,node:null},m.set(s,g)}l!=null&&l.startsWith("!!")&&(l=jv+l.slice(2));let p=Bv(s,l,h.tags);if(!p){if(s&&typeof s.toJSON=="function"&&(s=s.toJSON()),!s||typeof s!="object"){const z=new ue(s);return g&&(g.node=z),z}p=s instanceof Map?h[Fn]:Symbol.iterator in Object(s)?h[_a]:h[Fn]}o&&(o(p),delete i.onTagObj);const E=p!=null&&p.createNode?p.createNode(i.schema,s,i):typeof((A=p==null?void 0:p.nodeClass)==null?void 0:A.from)=="function"?p.nodeClass.from(i.schema,s,i):new ue(s);return l?E.tag=l:p.default||(E.tag=p.tag),g&&(g.node=E),E}function vu(s,l,i){let u=i;for(let c=l.length-1;c>=0;--c){const o=l[c];if(typeof o=="number"&&Number.isInteger(o)&&o>=0){const h=[];h[o]=u,u=h}else u=new Map([[o,u]])}return xi(u,void 0,{aliasDuplicateObjects:!1,keepUndefined:!1,onAnchor:()=>{throw new Error("This should not happen, please report a bug.")},schema:s,sourceObjects:new Map})}const Ci=s=>s==null||typeof s=="object"&&!!s[Symbol.iterator]().next().done;class fp extends Uf{constructor(l,i){super(l),Object.defineProperty(this,"schema",{value:i,configurable:!0,enumerable:!1,writable:!0})}clone(l){const i=Object.create(Object.getPrototypeOf(this),Object.getOwnPropertyDescriptors(this));return l&&(i.schema=l),i.items=i.items.map(u=>ke(u)||Be(u)?u.clone(l):u),this.range&&(i.range=this.range.slice()),i}addIn(l,i){if(Ci(l))this.add(i);else{const[u,...c]=l,o=this.get(u,!0);if(Re(o))o.addIn(c,i);else if(o===void 0&&this.schema)this.set(u,vu(this.schema,c,i));else throw new Error(`Expected YAML collection at ${u}. Remaining path: ${c}`)}}deleteIn(l){const[i,...u]=l;if(u.length===0)return this.delete(i);const c=this.get(i,!0);if(Re(c))return c.deleteIn(u);throw new Error(`Expected YAML collection at ${i}. Remaining path: ${u}`)}getIn(l,i){const[u,...c]=l,o=this.get(u,!0);return c.length===0?!i&&De(o)?o.value:o:Re(o)?o.getIn(c,i):void 0}hasAllNullValues(l){return this.items.every(i=>{if(!Be(i))return!1;const u=i.value;return u==null||l&&De(u)&&u.value==null&&!u.commentBefore&&!u.comment&&!u.tag})}hasIn(l){const[i,...u]=l;if(u.length===0)return this.has(i);const c=this.get(i,!0);return Re(c)?c.hasIn(u):!1}setIn(l,i){const[u,...c]=l;if(c.length===0)this.set(u,i);else{const o=this.get(u,!0);if(Re(o))o.setIn(c,i);else if(o===void 0&&this.schema)this.set(u,vu(this.schema,c,i));else throw new Error(`Expected YAML collection at ${u}. Remaining path: ${c}`)}}}const Rv=s=>s.replace(/^(?!$)(?: $)?/gm,"#");function An(s,l){return/^\n+$/.test(s)?s.substring(1):l?s.replace(/^(?! *$)/gm,l):s}const Tl=(s,l,i)=>s.endsWith(` +`)?An(i,l):i.includes(` +`)?` +`+An(i,l):(s.endsWith(" ")?"":" ")+i,op="flow",_f="block",du="quoted";function Nu(s,l,i="flow",{indentAtStart:u,lineWidth:c=80,minContentWidth:o=20,onFold:h,onOverflow:m}={}){if(!c||c<0)return s;cc-Math.max(2,o)?p.push(0):v=c-u);let _,A,z=!1,S=-1,T=-1,x=-1;i===_f&&(S=yg(s,S,l.length),S!==-1&&(v=S+g));for(let Y;Y=s[S+=1];){if(i===du&&Y==="\\"){switch(T=S,s[S+1]){case"x":S+=3;break;case"u":S+=5;break;case"U":S+=9;break;default:S+=1}x=S}if(Y===` +`)i===_f&&(S=yg(s,S,l.length)),v=S+l.length+g,_=void 0;else{if(Y===" "&&A&&A!==" "&&A!==` +`&&A!==" "){const X=s[S+1];X&&X!==" "&&X!==` +`&&X!==" "&&(_=S)}if(S>=v)if(_)p.push(_),v=_+g,_=void 0;else if(i===du){for(;A===" "||A===" ";)A=Y,Y=s[S+=1],z=!0;const X=S>x+1?S-2:T-1;if(E[X])return s;p.push(X),E[X]=!0,v=X+g,_=void 0}else z=!0}A=Y}if(z&&m&&m(),p.length===0)return s;h&&h();let j=s.slice(0,p[0]);for(let Y=0;Y({indentAtStart:l?s.indent.length:s.indentAtStart,lineWidth:s.options.lineWidth,minContentWidth:s.options.minContentWidth}),Cu=s=>/^(%|---|\.\.\.)/m.test(s);function kv(s,l,i){if(!l||l<0)return!1;const u=l-i,c=s.length;if(c<=u)return!1;for(let o=0,h=0;ou)return!0;if(h=o+1,c-h<=u)return!1}return!0}function zi(s,l){const i=JSON.stringify(s);if(l.options.doubleQuotedAsJSON)return i;const{implicitKey:u}=l,c=l.options.doubleQuotedMinMultiLineLength,o=l.indent||(Cu(s)?" ":"");let h="",m=0;for(let g=0,p=i[g];p;p=i[++g])if(p===" "&&i[g+1]==="\\"&&i[g+2]==="n"&&(h+=i.slice(m,g)+"\\ ",g+=1,m=g,p="\\"),p==="\\")switch(i[g+1]){case"u":{h+=i.slice(m,g);const E=i.substr(g+2,4);switch(E){case"0000":h+="\\0";break;case"0007":h+="\\a";break;case"000b":h+="\\v";break;case"001b":h+="\\e";break;case"0085":h+="\\N";break;case"00a0":h+="\\_";break;case"2028":h+="\\L";break;case"2029":h+="\\P";break;default:E.substr(0,2)==="00"?h+="\\x"+E.substr(2):h+=i.substr(g,6)}g+=5,m=g+1}break;case"n":if(u||i[g+2]==='"'||i.length +`;let v,_;for(_=i.length;_>0;--_){const K=i[_-1];if(K!==` +`&&K!==" "&&K!==" ")break}let A=i.substring(_);const z=A.indexOf(` +`);z===-1?v="-":i===A||z!==A.length-1?(v="+",o&&o()):v="",A&&(i=i.slice(0,-A.length),A[A.length-1]===` +`&&(A=A.slice(0,-1)),A=A.replace(Mf,`$&${p}`));let S=!1,T,x=-1;for(T=0;T")+(S?p?"2":"1":"")+v;if(s&&(X+=" "+m(s.replace(/ ?[\r\n]+/g," ")),c&&c()),E)return i=i.replace(/\n+/g,`$&${p}`),`${X} +${p}${j}${i}${A}`;i=i.replace(/\n+/g,` +$&`).replace(/(?:^|\n)([\t ].*)(?:([\n\t ]*)\n(?![\n\t ]))?/g,"$1$2").replace(/\n+/g,`$&${p}`);const W=Nu(`${j}${i}${A}`,p,_f,Mu(u,!0));return`${X} +${p}${W}`}function qv(s,l,i,u){const{type:c,value:o}=s,{actualString:h,implicitKey:m,indent:g,indentStep:p,inFlow:E}=l;if(m&&o.includes(` +`)||E&&/[[\]{},]/.test(o))return ba(o,l);if(!o||/^[\n\t ,[\]{}#&*!|>'"%@`]|^[?-]$|^[?-][ \t]|[\n:][ \t]|[ \t]\n|[\n\t ]#|[\n\t :]$/.test(o))return m||E||!o.includes(` +`)?ba(o,l):mu(s,l,i,u);if(!m&&!E&&c!==ue.PLAIN&&o.includes(` +`))return mu(s,l,i,u);if(Cu(o)){if(g==="")return l.forceBlockIndent=!0,mu(s,l,i,u);if(m&&g===p)return ba(o,l)}const v=o.replace(/\n+/g,`$& +${g}`);if(h){const _=S=>{var T;return S.default&&S.tag!=="tag:yaml.org,2002:str"&&((T=S.test)==null?void 0:T.test(v))},{compat:A,tags:z}=l.doc.schema;if(z.some(_)||A!=null&&A.some(_))return ba(o,l)}return m?v:Nu(v,g,op,Mu(l,!1))}function ji(s,l,i,u){const{implicitKey:c,inFlow:o}=l,h=typeof s.value=="string"?s:Object.assign({},s,{value:String(s.value)});let{type:m}=s;m!==ue.QUOTE_DOUBLE&&/[\x00-\x08\x0b-\x1f\x7f-\x9f\u{D800}-\u{DFFF}]/u.test(h.value)&&(m=ue.QUOTE_DOUBLE);const g=E=>{switch(E){case ue.BLOCK_FOLDED:case ue.BLOCK_LITERAL:return c||o?ba(h.value,l):mu(h,l,i,u);case ue.QUOTE_DOUBLE:return zi(h.value,l);case ue.QUOTE_SINGLE:return Nf(h.value,l);case ue.PLAIN:return qv(h,l,i,u);default:return null}};let p=g(m);if(p===null){const{defaultKeyType:E,defaultStringType:v}=l.options,_=c&&E||v;if(p=g(_),p===null)throw new Error(`Unsupported default string type ${_}`)}return p}function hp(s,l){const i=Object.assign({blockQuote:!0,commentString:Rv,defaultKeyType:null,defaultStringType:"PLAIN",directives:null,doubleQuotedAsJSON:!1,doubleQuotedMinMultiLineLength:40,falseStr:"false",flowCollectionPadding:!0,indentSeq:!0,lineWidth:80,minContentWidth:20,nullStr:"null",simpleKeys:!1,singleQuote:null,trueStr:"true",verifyAliasOrder:!0},s.schema.toStringOptions,l);let u;switch(i.collectionStyle){case"block":u=!1;break;case"flow":u=!0;break;default:u=null}return{anchors:new Set,doc:s,flowCollectionPadding:i.flowCollectionPadding?" ":"",indent:"",indentStep:typeof i.indent=="number"?" ".repeat(i.indent):" ",inFlow:u,options:i}}function Hv(s,l){var c;if(l.tag){const o=s.filter(h=>h.tag===l.tag);if(o.length>0)return o.find(h=>h.format===l.format)??o[0]}let i,u;if(De(l)){u=l.value;let o=s.filter(h=>{var m;return(m=h.identify)==null?void 0:m.call(h,u)});if(o.length>1){const h=o.filter(m=>m.test);h.length>0&&(o=h)}i=o.find(h=>h.format===l.format)??o.find(h=>!h.format)}else u=l,i=s.find(o=>o.nodeClass&&u instanceof o.nodeClass);if(!i){const o=((c=u==null?void 0:u.constructor)==null?void 0:c.name)??typeof u;throw new Error(`Tag not resolved for ${o} value`)}return i}function $v(s,l,{anchors:i,doc:u}){if(!u.directives)return"";const c=[],o=(De(s)||Re(s))&&s.anchor;o&&sp(o)&&(i.add(o),c.push(`&${o}`));const h=s.tag?s.tag:l.default?null:l.tag;return h&&c.push(u.directives.tagString(h)),c.join(" ")}function Ea(s,l,i,u){var g;if(Be(s))return s.toString(l,i,u);if(_l(s)){if(l.doc.directives)return s.toString(l);if((g=l.resolvedAliases)!=null&&g.has(s))throw new TypeError("Cannot stringify circular structure without alias nodes");l.resolvedAliases?l.resolvedAliases.add(s):l.resolvedAliases=new Set([s]),s=s.resolve(l.doc)}let c;const o=ke(s)?s:l.doc.createNode(s,{onTagObj:p=>c=p});c||(c=Hv(l.doc.schema.tags,o));const h=$v(o,c,l);h.length>0&&(l.indentAtStart=(l.indentAtStart??0)+h.length+1);const m=typeof c.stringify=="function"?c.stringify(o,l,i,u):De(o)?ji(o,l,i,u):o.toString(l,i,u);return h?De(o)||m[0]==="{"||m[0]==="["?`${h} ${m}`:`${h} +${l.indent}${m}`:m}function Yv({key:s,value:l},i,u,c){const{allNullValues:o,doc:h,indent:m,indentStep:g,options:{commentString:p,indentSeq:E,simpleKeys:v}}=i;let _=ke(s)&&s.comment||null;if(v){if(_)throw new Error("With simple keys, key nodes cannot have comments");if(Re(s)||!ke(s)&&typeof s=="object"){const G="With simple keys, collection cannot be used as a key value";throw new Error(G)}}let A=!v&&(!s||_&&l==null&&!i.inFlow||Re(s)||(De(s)?s.type===ue.BLOCK_FOLDED||s.type===ue.BLOCK_LITERAL:typeof s=="object"));i=Object.assign({},i,{allNullValues:!1,implicitKey:!A&&(v||!o),indent:m+g});let z=!1,S=!1,T=Ea(s,i,()=>z=!0,()=>S=!0);if(!A&&!i.inFlow&&T.length>1024){if(v)throw new Error("With simple keys, single line scalar must not span more than 1024 characters");A=!0}if(i.inFlow){if(o||l==null)return z&&u&&u(),T===""?"?":A?`? ${T}`:T}else if(o&&!v||l==null&&A)return T=`? ${T}`,_&&!z?T+=Tl(T,i.indent,p(_)):S&&c&&c(),T;z&&(_=null),A?(_&&(T+=Tl(T,i.indent,p(_))),T=`? ${T} +${m}:`):(T=`${T}:`,_&&(T+=Tl(T,i.indent,p(_))));let x,j,Y;ke(l)?(x=!!l.spaceBefore,j=l.commentBefore,Y=l.comment):(x=!1,j=null,Y=null,l&&typeof l=="object"&&(l=h.createNode(l))),i.implicitKey=!1,!A&&!_&&De(l)&&(i.indentAtStart=T.length+1),S=!1,!E&&g.length>=2&&!i.inFlow&&!A&&Ma(l)&&!l.flow&&!l.tag&&!l.anchor&&(i.indent=i.indent.substring(2));let X=!1;const W=Ea(l,i,()=>X=!0,()=>S=!0);let K=" ";if(_||x||j){if(K=x?` +`:"",j){const G=p(j);K+=` +${An(G,i.indent)}`}W===""&&!i.inFlow?K===` +`&&(K=` + +`):K+=` +${i.indent}`}else if(!A&&Re(l)){const G=W[0],V=W.indexOf(` +`),B=V!==-1,he=i.inFlow??l.flow??l.items.length===0;if(B||!he){let ne=!1;if(B&&(G==="&"||G==="!")){let q=W.indexOf(" ");G==="&"&&q!==-1&&qs===nu||typeof s=="symbol"&&s.description===nu,default:"key",tag:"tag:yaml.org,2002:merge",test:/^<<$/,resolve:()=>Object.assign(new ue(Symbol(nu)),{addToJSMap:mp}),stringify:()=>nu},Gv=(s,l)=>(On.identify(l)||De(l)&&(!l.type||l.type===ue.PLAIN)&&On.identify(l.value))&&(s==null?void 0:s.doc.schema.tags.some(i=>i.tag===On.tag&&i.default));function mp(s,l,i){if(i=s&&_l(i)?i.resolve(s.doc):i,Ma(i))for(const u of i.items)hf(s,l,u);else if(Array.isArray(i))for(const u of i)hf(s,l,u);else hf(s,l,i)}function hf(s,l,i){const u=s&&_l(i)?i.resolve(s.doc):i;if(!Na(u))throw new Error("Merge sources must be maps or map aliases");const c=u.toJSON(null,s,Map);for(const[o,h]of c)l instanceof Map?l.has(o)||l.set(o,h):l instanceof Set?l.add(o):Object.prototype.hasOwnProperty.call(l,o)||Object.defineProperty(l,o,{value:h,writable:!0,enumerable:!0,configurable:!0});return l}function gp(s,l,{key:i,value:u}){if(ke(i)&&i.addToJSMap)i.addToJSMap(s,l,u);else if(Gv(s,i))mp(s,l,u);else{const c=Kt(i,"",s);if(l instanceof Map)l.set(c,Kt(u,c,s));else if(l instanceof Set)l.add(c);else{const o=Kv(i,c,s),h=Kt(u,o,s);o in l?Object.defineProperty(l,o,{value:h,writable:!0,enumerable:!0,configurable:!0}):l[o]=h}}return l}function Kv(s,l,i){if(l===null)return"";if(typeof l!="object")return String(l);if(ke(s)&&(i!=null&&i.doc)){const u=hp(i.doc,{});u.anchors=new Set;for(const o of i.anchors.keys())u.anchors.add(o.anchor);u.inFlow=!0,u.inStringifyKey=!0;const c=s.toString(u);if(!i.mapKeyWarned){let o=JSON.stringify(c);o.length>40&&(o=o.substring(0,36)+'..."'),dp(i.doc.options.logLevel,`Keys with collection values will be stringified due to JS Object restrictions: ${o}. Set mapAsMap: true to use object keys.`),i.mapKeyWarned=!0}return c}return JSON.stringify(l)}function jf(s,l,i){const u=xi(s,void 0,i),c=xi(l,void 0,i);return new ct(u,c)}class ct{constructor(l,i=null){Object.defineProperty(this,Vt,{value:tp}),this.key=l,this.value=i}clone(l){let{key:i,value:u}=this;return ke(i)&&(i=i.clone(l)),ke(u)&&(u=u.clone(l)),new ct(i,u)}toJSON(l,i){const u=i!=null&&i.mapAsMap?new Map:{};return gp(i,u,this)}toString(l,i,u){return l!=null&&l.doc?Yv(this,l,i,u):JSON.stringify(this)}}function pp(s,l,i){return(l.inFlow??s.flow?Qv:Vv)(s,l,i)}function Vv({comment:s,items:l},i,{blockItemPrefix:u,flowChars:c,itemIndent:o,onChompKeep:h,onComment:m}){const{indent:g,options:{commentString:p}}=i,E=Object.assign({},i,{indent:o,type:null});let v=!1;const _=[];for(let z=0;zT=null,()=>v=!0);T&&(x+=Tl(x,o,p(T))),v&&T&&(v=!1),_.push(u+x)}let A;if(_.length===0)A=c.start+c.end;else{A=_[0];for(let z=1;z<_.length;++z){const S=_[z];A+=S?` +${g}${S}`:` +`}}return s?(A+=` +`+An(p(s),g),m&&m()):v&&h&&h(),A}function Qv({items:s},l,{flowChars:i,itemIndent:u}){const{indent:c,indentStep:o,flowCollectionPadding:h,options:{commentString:m}}=l;u+=o;const g=Object.assign({},l,{indent:u,inFlow:!0,type:null});let p=!1,E=0;const v=[];for(let z=0;zT=null);zE||x.includes(` +`))&&(p=!0),v.push(x),E=v.length}const{start:_,end:A}=i;if(v.length===0)return _+A;if(!p){const z=v.reduce((S,T)=>S+T.length+2,2);p=l.options.lineWidth>0&&z>l.options.lineWidth}if(p){let z=_;for(const S of v)z+=S?` +${o}${c}${S}`:` +`;return`${z} +${c}${A}`}else return`${_}${h}${v.join(" ")}${h}${A}`}function bu({indent:s,options:{commentString:l}},i,u,c){if(u&&c&&(u=u.replace(/^\n+/,"")),u){const o=An(l(u),s);i.push(o.trimStart())}}function El(s,l){const i=De(l)?l.value:l;for(const u of s)if(Be(u)&&(u.key===l||u.key===i||De(u.key)&&u.key.value===i))return u}class Lt extends fp{static get tagName(){return"tag:yaml.org,2002:map"}constructor(l){super(Fn,l),this.items=[]}static from(l,i,u){const{keepUndefined:c,replacer:o}=u,h=new this(l),m=(g,p)=>{if(typeof o=="function")p=o.call(i,g,p);else if(Array.isArray(o)&&!o.includes(g))return;(p!==void 0||c)&&h.items.push(jf(g,p,u))};if(i instanceof Map)for(const[g,p]of i)m(g,p);else if(i&&typeof i=="object")for(const g of Object.keys(i))m(g,i[g]);return typeof l.sortMapEntries=="function"&&h.items.sort(l.sortMapEntries),h}add(l,i){var h;let u;Be(l)?u=l:!l||typeof l!="object"||!("key"in l)?u=new ct(l,l==null?void 0:l.value):u=new ct(l.key,l.value);const c=El(this.items,u.key),o=(h=this.schema)==null?void 0:h.sortMapEntries;if(c){if(!i)throw new Error(`Key ${u.key} already set`);De(c.value)&&rp(u.value)?c.value.value=u.value:c.value=u.value}else if(o){const m=this.items.findIndex(g=>o(u,g)<0);m===-1?this.items.push(u):this.items.splice(m,0,u)}else this.items.push(u)}delete(l){const i=El(this.items,l);return i?this.items.splice(this.items.indexOf(i),1).length>0:!1}get(l,i){const u=El(this.items,l),c=u==null?void 0:u.value;return(!i&&De(c)?c.value:c)??void 0}has(l){return!!El(this.items,l)}set(l,i){this.add(new ct(l,i),!0)}toJSON(l,i,u){const c=u?new u:i!=null&&i.mapAsMap?new Map:{};i!=null&&i.onCreate&&i.onCreate(c);for(const o of this.items)gp(i,c,o);return c}toString(l,i,u){if(!l)return JSON.stringify(this);for(const c of this.items)if(!Be(c))throw new Error(`Map items must all be pairs; found ${JSON.stringify(c)} instead`);return!l.allNullValues&&this.hasAllNullValues(!1)&&(l=Object.assign({},l,{allNullValues:!0})),pp(this,l,{blockItemPrefix:"",flowChars:{start:"{",end:"}"},itemIndent:l.indent||"",onChompKeep:u,onComment:i})}}const Ca={collection:"map",default:!0,nodeClass:Lt,tag:"tag:yaml.org,2002:map",resolve(s,l){return Na(s)||l("Expected a mapping for this tag"),s},createNode:(s,l,i)=>Lt.from(s,l,i)};class Pn extends fp{static get tagName(){return"tag:yaml.org,2002:seq"}constructor(l){super(_a,l),this.items=[]}add(l){this.items.push(l)}delete(l){const i=lu(l);return typeof i!="number"?!1:this.items.splice(i,1).length>0}get(l,i){const u=lu(l);if(typeof u!="number")return;const c=this.items[u];return!i&&De(c)?c.value:c}has(l){const i=lu(l);return typeof i=="number"&&i=0?l:null}const za={collection:"seq",default:!0,nodeClass:Pn,tag:"tag:yaml.org,2002:seq",resolve(s,l){return Ma(s)||l("Expected a sequence for this tag"),s},createNode:(s,l,i)=>Pn.from(s,l,i)},zu={identify:s=>typeof s=="string",default:!0,tag:"tag:yaml.org,2002:str",resolve:s=>s,stringify(s,l,i,u){return l=Object.assign({actualString:!0},l),ji(s,l,i,u)}},xu={identify:s=>s==null,createNode:()=>new ue(null),default:!0,tag:"tag:yaml.org,2002:null",test:/^(?:~|[Nn]ull|NULL)?$/,resolve:()=>new ue(null),stringify:({source:s},l)=>typeof s=="string"&&xu.test.test(s)?s:l.options.nullStr},Bf={identify:s=>typeof s=="boolean",default:!0,tag:"tag:yaml.org,2002:bool",test:/^(?:[Tt]rue|TRUE|[Ff]alse|FALSE)$/,resolve:s=>new ue(s[0]==="t"||s[0]==="T"),stringify({source:s,value:l},i){if(s&&Bf.test.test(s)){const u=s[0]==="t"||s[0]==="T";if(l===u)return s}return l?i.options.trueStr:i.options.falseStr}};function Wt({format:s,minFractionDigits:l,tag:i,value:u}){if(typeof u=="bigint")return String(u);const c=typeof u=="number"?u:Number(u);if(!isFinite(c))return isNaN(c)?".nan":c<0?"-.inf":".inf";let o=JSON.stringify(u);if(!s&&l&&(!i||i==="tag:yaml.org,2002:float")&&/^\d/.test(o)){let h=o.indexOf(".");h<0&&(h=o.length,o+=".");let m=l-(o.length-h-1);for(;m-- >0;)o+="0"}return o}const yp={identify:s=>typeof s=="number",default:!0,tag:"tag:yaml.org,2002:float",test:/^(?:[-+]?\.(?:inf|Inf|INF)|\.nan|\.NaN|\.NAN)$/,resolve:s=>s.slice(-3).toLowerCase()==="nan"?NaN:s[0]==="-"?Number.NEGATIVE_INFINITY:Number.POSITIVE_INFINITY,stringify:Wt},vp={identify:s=>typeof s=="number",default:!0,tag:"tag:yaml.org,2002:float",format:"EXP",test:/^[-+]?(?:\.[0-9]+|[0-9]+(?:\.[0-9]*)?)[eE][-+]?[0-9]+$/,resolve:s=>parseFloat(s),stringify(s){const l=Number(s.value);return isFinite(l)?l.toExponential():Wt(s)}},bp={identify:s=>typeof s=="number",default:!0,tag:"tag:yaml.org,2002:float",test:/^[-+]?(?:\.[0-9]+|[0-9]+\.[0-9]*)$/,resolve(s){const l=new ue(parseFloat(s)),i=s.indexOf(".");return i!==-1&&s[s.length-1]==="0"&&(l.minFractionDigits=s.length-i-1),l},stringify:Wt},Du=s=>typeof s=="bigint"||Number.isInteger(s),Rf=(s,l,i,{intAsBigInt:u})=>u?BigInt(s):parseInt(s.substring(l),i);function Sp(s,l,i){const{value:u}=s;return Du(u)&&u>=0?i+u.toString(l):Wt(s)}const Tp={identify:s=>Du(s)&&s>=0,default:!0,tag:"tag:yaml.org,2002:int",format:"OCT",test:/^0o[0-7]+$/,resolve:(s,l,i)=>Rf(s,2,8,i),stringify:s=>Sp(s,8,"0o")},Ep={identify:Du,default:!0,tag:"tag:yaml.org,2002:int",test:/^[-+]?[0-9]+$/,resolve:(s,l,i)=>Rf(s,0,10,i),stringify:Wt},Ap={identify:s=>Du(s)&&s>=0,default:!0,tag:"tag:yaml.org,2002:int",format:"HEX",test:/^0x[0-9a-fA-F]+$/,resolve:(s,l,i)=>Rf(s,2,16,i),stringify:s=>Sp(s,16,"0x")},Xv=[Ca,za,zu,xu,Bf,Tp,Ep,Ap,yp,vp,bp];function vg(s){return typeof s=="bigint"||Number.isInteger(s)}const au=({value:s})=>JSON.stringify(s),Zv=[{identify:s=>typeof s=="string",default:!0,tag:"tag:yaml.org,2002:str",resolve:s=>s,stringify:au},{identify:s=>s==null,createNode:()=>new ue(null),default:!0,tag:"tag:yaml.org,2002:null",test:/^null$/,resolve:()=>null,stringify:au},{identify:s=>typeof s=="boolean",default:!0,tag:"tag:yaml.org,2002:bool",test:/^true|false$/,resolve:s=>s==="true",stringify:au},{identify:vg,default:!0,tag:"tag:yaml.org,2002:int",test:/^-?(?:0|[1-9][0-9]*)$/,resolve:(s,l,{intAsBigInt:i})=>i?BigInt(s):parseInt(s,10),stringify:({value:s})=>vg(s)?s.toString():JSON.stringify(s)},{identify:s=>typeof s=="number",default:!0,tag:"tag:yaml.org,2002:float",test:/^-?(?:0|[1-9][0-9]*)(?:\.[0-9]*)?(?:[eE][-+]?[0-9]+)?$/,resolve:s=>parseFloat(s),stringify:au}],Jv={default:!0,tag:"",test:/^/,resolve(s,l){return l(`Unresolved plain scalar ${JSON.stringify(s)}`),s}},Wv=[Ca,za].concat(Zv,Jv),kf={identify:s=>s instanceof Uint8Array,default:!1,tag:"tag:yaml.org,2002:binary",resolve(s,l){if(typeof Buffer=="function")return Buffer.from(s,"base64");if(typeof atob=="function"){const i=atob(s.replace(/[\n\r]/g,"")),u=new Uint8Array(i.length);for(let c=0;c1&&l("Each pair must have its own sequence indicator");const c=u.items[0]||new ct(new ue(null));if(u.commentBefore&&(c.key.commentBefore=c.key.commentBefore?`${u.commentBefore} +${c.key.commentBefore}`:u.commentBefore),u.comment){const o=c.value??c.key;o.comment=o.comment?`${u.comment} +${o.comment}`:u.comment}u=c}s.items[i]=Be(u)?u:new ct(u)}}else l("Expected a sequence for this tag");return s}function Op(s,l,i){const{replacer:u}=i,c=new Pn(s);c.tag="tag:yaml.org,2002:pairs";let o=0;if(l&&Symbol.iterator in Object(l))for(let h of l){typeof u=="function"&&(h=u.call(l,String(o++),h));let m,g;if(Array.isArray(h))if(h.length===2)m=h[0],g=h[1];else throw new TypeError(`Expected [key, value] tuple: ${h}`);else if(h&&h instanceof Object){const p=Object.keys(h);if(p.length===1)m=p[0],g=h[m];else throw new TypeError(`Expected tuple with one key, not ${p.length} keys`)}else m=h;c.items.push(jf(m,g,i))}return c}const qf={collection:"seq",default:!1,tag:"tag:yaml.org,2002:pairs",resolve:wp,createNode:Op};class Sa extends Pn{constructor(){super(),this.add=Lt.prototype.add.bind(this),this.delete=Lt.prototype.delete.bind(this),this.get=Lt.prototype.get.bind(this),this.has=Lt.prototype.has.bind(this),this.set=Lt.prototype.set.bind(this),this.tag=Sa.tag}toJSON(l,i){if(!i)return super.toJSON(l);const u=new Map;i!=null&&i.onCreate&&i.onCreate(u);for(const c of this.items){let o,h;if(Be(c)?(o=Kt(c.key,"",i),h=Kt(c.value,o,i)):o=Kt(c,"",i),u.has(o))throw new Error("Ordered maps must not include duplicate keys");u.set(o,h)}return u}static from(l,i,u){const c=Op(l,i,u),o=new this;return o.items=c.items,o}}Sa.tag="tag:yaml.org,2002:omap";const Hf={collection:"seq",identify:s=>s instanceof Map,nodeClass:Sa,default:!1,tag:"tag:yaml.org,2002:omap",resolve(s,l){const i=wp(s,l),u=[];for(const{key:c}of i.items)De(c)&&(u.includes(c.value)?l(`Ordered maps must not include duplicate keys: ${c.value}`):u.push(c.value));return Object.assign(new Sa,i)},createNode:(s,l,i)=>Sa.from(s,l,i)};function _p({value:s,source:l},i){return l&&(s?Np:Mp).test.test(l)?l:s?i.options.trueStr:i.options.falseStr}const Np={identify:s=>s===!0,default:!0,tag:"tag:yaml.org,2002:bool",test:/^(?:Y|y|[Yy]es|YES|[Tt]rue|TRUE|[Oo]n|ON)$/,resolve:()=>new ue(!0),stringify:_p},Mp={identify:s=>s===!1,default:!0,tag:"tag:yaml.org,2002:bool",test:/^(?:N|n|[Nn]o|NO|[Ff]alse|FALSE|[Oo]ff|OFF)$/,resolve:()=>new ue(!1),stringify:_p},Fv={identify:s=>typeof s=="number",default:!0,tag:"tag:yaml.org,2002:float",test:/^(?:[-+]?\.(?:inf|Inf|INF)|\.nan|\.NaN|\.NAN)$/,resolve:s=>s.slice(-3).toLowerCase()==="nan"?NaN:s[0]==="-"?Number.NEGATIVE_INFINITY:Number.POSITIVE_INFINITY,stringify:Wt},Iv={identify:s=>typeof s=="number",default:!0,tag:"tag:yaml.org,2002:float",format:"EXP",test:/^[-+]?(?:[0-9][0-9_]*)?(?:\.[0-9_]*)?[eE][-+]?[0-9]+$/,resolve:s=>parseFloat(s.replace(/_/g,"")),stringify(s){const l=Number(s.value);return isFinite(l)?l.toExponential():Wt(s)}},Pv={identify:s=>typeof s=="number",default:!0,tag:"tag:yaml.org,2002:float",test:/^[-+]?(?:[0-9][0-9_]*)?\.[0-9_]*$/,resolve(s){const l=new ue(parseFloat(s.replace(/_/g,""))),i=s.indexOf(".");if(i!==-1){const u=s.substring(i+1).replace(/_/g,"");u[u.length-1]==="0"&&(l.minFractionDigits=u.length)}return l},stringify:Wt},Bi=s=>typeof s=="bigint"||Number.isInteger(s);function Lu(s,l,i,{intAsBigInt:u}){const c=s[0];if((c==="-"||c==="+")&&(l+=1),s=s.substring(l).replace(/_/g,""),u){switch(i){case 2:s=`0b${s}`;break;case 8:s=`0o${s}`;break;case 16:s=`0x${s}`;break}const h=BigInt(s);return c==="-"?BigInt(-1)*h:h}const o=parseInt(s,i);return c==="-"?-1*o:o}function $f(s,l,i){const{value:u}=s;if(Bi(u)){const c=u.toString(l);return u<0?"-"+i+c.substr(1):i+c}return Wt(s)}const eb={identify:Bi,default:!0,tag:"tag:yaml.org,2002:int",format:"BIN",test:/^[-+]?0b[0-1_]+$/,resolve:(s,l,i)=>Lu(s,2,2,i),stringify:s=>$f(s,2,"0b")},tb={identify:Bi,default:!0,tag:"tag:yaml.org,2002:int",format:"OCT",test:/^[-+]?0[0-7_]+$/,resolve:(s,l,i)=>Lu(s,1,8,i),stringify:s=>$f(s,8,"0")},nb={identify:Bi,default:!0,tag:"tag:yaml.org,2002:int",test:/^[-+]?[0-9][0-9_]*$/,resolve:(s,l,i)=>Lu(s,0,10,i),stringify:Wt},lb={identify:Bi,default:!0,tag:"tag:yaml.org,2002:int",format:"HEX",test:/^[-+]?0x[0-9a-fA-F_]+$/,resolve:(s,l,i)=>Lu(s,2,16,i),stringify:s=>$f(s,16,"0x")};class Ta extends Lt{constructor(l){super(l),this.tag=Ta.tag}add(l){let i;Be(l)?i=l:l&&typeof l=="object"&&"key"in l&&"value"in l&&l.value===null?i=new ct(l.key,null):i=new ct(l,null),El(this.items,i.key)||this.items.push(i)}get(l,i){const u=El(this.items,l);return!i&&Be(u)?De(u.key)?u.key.value:u.key:u}set(l,i){if(typeof i!="boolean")throw new Error(`Expected boolean value for set(key, value) in a YAML set, not ${typeof i}`);const u=El(this.items,l);u&&!i?this.items.splice(this.items.indexOf(u),1):!u&&i&&this.items.push(new ct(l))}toJSON(l,i){return super.toJSON(l,i,Set)}toString(l,i,u){if(!l)return JSON.stringify(this);if(this.hasAllNullValues(!0))return super.toString(Object.assign({},l,{allNullValues:!0}),i,u);throw new Error("Set items must all have null values")}static from(l,i,u){const{replacer:c}=u,o=new this(l);if(i&&Symbol.iterator in Object(i))for(let h of i)typeof c=="function"&&(h=c.call(i,h,h)),o.items.push(jf(h,null,u));return o}}Ta.tag="tag:yaml.org,2002:set";const Yf={collection:"map",identify:s=>s instanceof Set,nodeClass:Ta,default:!1,tag:"tag:yaml.org,2002:set",createNode:(s,l,i)=>Ta.from(s,l,i),resolve(s,l){if(Na(s)){if(s.hasAllNullValues(!0))return Object.assign(new Ta,s);l("Set items must all have null values")}else l("Expected a mapping for this tag");return s}};function Gf(s,l){const i=s[0],u=i==="-"||i==="+"?s.substring(1):s,c=h=>l?BigInt(h):Number(h),o=u.replace(/_/g,"").split(":").reduce((h,m)=>h*c(60)+c(m),c(0));return i==="-"?c(-1)*o:o}function Cp(s){let{value:l}=s,i=h=>h;if(typeof l=="bigint")i=h=>BigInt(h);else if(isNaN(l)||!isFinite(l))return Wt(s);let u="";l<0&&(u="-",l*=i(-1));const c=i(60),o=[l%c];return l<60?o.unshift(0):(l=(l-o[0])/c,o.unshift(l%c),l>=60&&(l=(l-o[0])/c,o.unshift(l))),u+o.map(h=>String(h).padStart(2,"0")).join(":").replace(/000000\d*$/,"")}const zp={identify:s=>typeof s=="bigint"||Number.isInteger(s),default:!0,tag:"tag:yaml.org,2002:int",format:"TIME",test:/^[-+]?[0-9][0-9_]*(?::[0-5]?[0-9])+$/,resolve:(s,l,{intAsBigInt:i})=>Gf(s,i),stringify:Cp},xp={identify:s=>typeof s=="number",default:!0,tag:"tag:yaml.org,2002:float",format:"TIME",test:/^[-+]?[0-9][0-9_]*(?::[0-5]?[0-9])+\.[0-9_]*$/,resolve:s=>Gf(s,!1),stringify:Cp},Uu={identify:s=>s instanceof Date,default:!0,tag:"tag:yaml.org,2002:timestamp",test:RegExp("^([0-9]{4})-([0-9]{1,2})-([0-9]{1,2})(?:(?:t|T|[ \\t]+)([0-9]{1,2}):([0-9]{1,2}):([0-9]{1,2}(\\.[0-9]+)?)(?:[ \\t]*(Z|[-+][012]?[0-9](?::[0-9]{2})?))?)?$"),resolve(s){const l=s.match(Uu.test);if(!l)throw new Error("!!timestamp expects a date, starting with yyyy-mm-dd");const[,i,u,c,o,h,m]=l.map(Number),g=l[7]?Number((l[7]+"00").substr(1,3)):0;let p=Date.UTC(i,u-1,c,o||0,h||0,m||0,g);const E=l[8];if(E&&E!=="Z"){let v=Gf(E,!1);Math.abs(v)<30&&(v*=60),p-=6e4*v}return new Date(p)},stringify:({value:s})=>s.toISOString().replace(/((T00:00)?:00)?\.000Z$/,"")},bg=[Ca,za,zu,xu,Np,Mp,eb,tb,nb,lb,Fv,Iv,Pv,kf,On,Hf,qf,Yf,zp,xp,Uu],Sg=new Map([["core",Xv],["failsafe",[Ca,za,zu]],["json",Wv],["yaml11",bg],["yaml-1.1",bg]]),Tg={binary:kf,bool:Bf,float:bp,floatExp:vp,floatNaN:yp,floatTime:xp,int:Ep,intHex:Ap,intOct:Tp,intTime:zp,map:Ca,merge:On,null:xu,omap:Hf,pairs:qf,seq:za,set:Yf,timestamp:Uu},ab={"tag:yaml.org,2002:binary":kf,"tag:yaml.org,2002:merge":On,"tag:yaml.org,2002:omap":Hf,"tag:yaml.org,2002:pairs":qf,"tag:yaml.org,2002:set":Yf,"tag:yaml.org,2002:timestamp":Uu};function df(s,l,i){const u=Sg.get(l);if(u&&!s)return i&&!u.includes(On)?u.concat(On):u.slice();let c=u;if(!c)if(Array.isArray(s))c=[];else{const o=Array.from(Sg.keys()).filter(h=>h!=="yaml11").map(h=>JSON.stringify(h)).join(", ");throw new Error(`Unknown schema "${l}"; use one of ${o} or define customTags array`)}if(Array.isArray(s))for(const o of s)c=c.concat(o);else typeof s=="function"&&(c=s(c.slice()));return i&&(c=c.concat(On)),c.reduce((o,h)=>{const m=typeof h=="string"?Tg[h]:h;if(!m){const g=JSON.stringify(h),p=Object.keys(Tg).map(E=>JSON.stringify(E)).join(", ");throw new Error(`Unknown custom tag ${g}; use one of ${p}`)}return o.includes(m)||o.push(m),o},[])}const ib=(s,l)=>s.keyl.key?1:0;class ju{constructor({compat:l,customTags:i,merge:u,resolveKnownTags:c,schema:o,sortMapEntries:h,toStringDefaults:m}){this.compat=Array.isArray(l)?df(l,"compat"):l?df(null,l):null,this.name=typeof o=="string"&&o||"core",this.knownTags=c?ab:{},this.tags=df(i,this.name,u),this.toStringOptions=m??null,Object.defineProperty(this,Fn,{value:Ca}),Object.defineProperty(this,nn,{value:zu}),Object.defineProperty(this,_a,{value:za}),this.sortMapEntries=typeof h=="function"?h:h===!0?ib:null}clone(){const l=Object.create(ju.prototype,Object.getOwnPropertyDescriptors(this));return l.tags=this.tags.slice(),l}}function sb(s,l){var g;const i=[];let u=l.directives===!0;if(l.directives!==!1&&s.directives){const p=s.directives.toString(s);p?(i.push(p),u=!0):s.directives.docStart&&(u=!0)}u&&i.push("---");const c=hp(s,l),{commentString:o}=c.options;if(s.commentBefore){i.length!==1&&i.unshift("");const p=o(s.commentBefore);i.unshift(An(p,""))}let h=!1,m=null;if(s.contents){if(ke(s.contents)){if(s.contents.spaceBefore&&u&&i.push(""),s.contents.commentBefore){const v=o(s.contents.commentBefore);i.push(An(v,""))}c.forceBlockIndent=!!s.comment,m=s.contents.comment}const p=m?void 0:()=>h=!0;let E=Ea(s.contents,c,()=>m=null,p);m&&(E+=Tl(E,"",o(m))),(E[0]==="|"||E[0]===">")&&i[i.length-1]==="---"?i[i.length-1]=`--- ${E}`:i.push(E)}else i.push(Ea(s.contents,c));if((g=s.directives)!=null&&g.docEnd)if(s.comment){const p=o(s.comment);p.includes(` +`)?(i.push("..."),i.push(An(p,""))):i.push(`... ${p}`)}else i.push("...");else{let p=s.comment;p&&h&&(p=p.replace(/^\n+/,"")),p&&((!h||m)&&i[i.length-1]!==""&&i.push(""),i.push(An(o(p),"")))}return i.join(` +`)+` +`}class xa{constructor(l,i,u){this.commentBefore=null,this.comment=null,this.errors=[],this.warnings=[],Object.defineProperty(this,Vt,{value:Of});let c=null;typeof i=="function"||Array.isArray(i)?c=i:u===void 0&&i&&(u=i,i=void 0);const o=Object.assign({intAsBigInt:!1,keepSourceTokens:!1,logLevel:"warn",prettyErrors:!0,strict:!0,stringKeys:!1,uniqueKeys:!0,version:"1.2"},u);this.options=o;let{version:h}=o;u!=null&&u._directives?(this.directives=u._directives.atDocument(),this.directives.yaml.explicit&&(h=this.directives.yaml.version)):this.directives=new ot({version:h}),this.setSchema(h,u),this.contents=l===void 0?null:this.createNode(l,c,u)}clone(){const l=Object.create(xa.prototype,{[Vt]:{value:Of}});return l.commentBefore=this.commentBefore,l.comment=this.comment,l.errors=this.errors.slice(),l.warnings=this.warnings.slice(),l.options=Object.assign({},this.options),this.directives&&(l.directives=this.directives.clone()),l.schema=this.schema.clone(),l.contents=ke(this.contents)?this.contents.clone(l.schema):this.contents,this.range&&(l.range=this.range.slice()),l}add(l){ha(this.contents)&&this.contents.add(l)}addIn(l,i){ha(this.contents)&&this.contents.addIn(l,i)}createAlias(l,i){if(!l.anchor){const u=up(this);l.anchor=!i||u.has(i)?cp(i||"a",u):i}return new _u(l.anchor)}createNode(l,i,u){let c;if(typeof i=="function")l=i.call({"":l},"",l),c=i;else if(Array.isArray(i)){const T=j=>typeof j=="number"||j instanceof String||j instanceof Number,x=i.filter(T).map(String);x.length>0&&(i=i.concat(x)),c=i}else u===void 0&&i&&(u=i,i=void 0);const{aliasDuplicateObjects:o,anchorPrefix:h,flow:m,keepUndefined:g,onTagObj:p,tag:E}=u??{},{onAnchor:v,setAnchors:_,sourceObjects:A}=Uv(this,h||"a"),z={aliasDuplicateObjects:o??!0,keepUndefined:g??!1,onAnchor:v,onTagObj:p,replacer:c,schema:this.schema,sourceObjects:A},S=xi(l,E,z);return m&&Re(S)&&(S.flow=!0),_(),S}createPair(l,i,u={}){const c=this.createNode(l,null,u),o=this.createNode(i,null,u);return new ct(c,o)}delete(l){return ha(this.contents)?this.contents.delete(l):!1}deleteIn(l){return Ci(l)?this.contents==null?!1:(this.contents=null,!0):ha(this.contents)?this.contents.deleteIn(l):!1}get(l,i){return Re(this.contents)?this.contents.get(l,i):void 0}getIn(l,i){return Ci(l)?!i&&De(this.contents)?this.contents.value:this.contents:Re(this.contents)?this.contents.getIn(l,i):void 0}has(l){return Re(this.contents)?this.contents.has(l):!1}hasIn(l){return Ci(l)?this.contents!==void 0:Re(this.contents)?this.contents.hasIn(l):!1}set(l,i){this.contents==null?this.contents=vu(this.schema,[l],i):ha(this.contents)&&this.contents.set(l,i)}setIn(l,i){Ci(l)?this.contents=i:this.contents==null?this.contents=vu(this.schema,Array.from(l),i):ha(this.contents)&&this.contents.setIn(l,i)}setSchema(l,i={}){typeof l=="number"&&(l=String(l));let u;switch(l){case"1.1":this.directives?this.directives.yaml.version="1.1":this.directives=new ot({version:"1.1"}),u={resolveKnownTags:!1,schema:"yaml-1.1"};break;case"1.2":case"next":this.directives?this.directives.yaml.version=l:this.directives=new ot({version:l}),u={resolveKnownTags:!0,schema:"core"};break;case null:this.directives&&delete this.directives,u=null;break;default:{const c=JSON.stringify(l);throw new Error(`Expected '1.1', '1.2' or null as first argument, but found: ${c}`)}}if(i.schema instanceof Object)this.schema=i.schema;else if(u)this.schema=new ju(Object.assign(u,i));else throw new Error("With a null YAML version, the { schema: Schema } option is required")}toJS({json:l,jsonArg:i,mapAsMap:u,maxAliasCount:c,onAnchor:o,reviver:h}={}){const m={anchors:new Map,doc:this,keep:!l,mapAsMap:u===!0,mapKeyWarned:!1,maxAliasCount:typeof c=="number"?c:100},g=Kt(this.contents,i??"",m);if(typeof o=="function")for(const{count:p,res:E}of m.anchors.values())o(E,p);return typeof h=="function"?va(h,{"":g},"",g):g}toJSON(l,i){return this.toJS({json:!0,jsonArg:l,mapAsMap:!1,onAnchor:i})}toString(l={}){if(this.errors.length>0)throw new Error("Document with errors cannot be stringified");if("indent"in l&&(!Number.isInteger(l.indent)||Number(l.indent)<=0)){const i=JSON.stringify(l.indent);throw new Error(`"indent" option must be a positive integer, not ${i}`)}return sb(this,l)}}function ha(s){if(Re(s))return!0;throw new Error("Expected a YAML collection as document contents")}class Kf extends Error{constructor(l,i,u,c){super(),this.name=l,this.code=u,this.message=c,this.pos=i}}class Al extends Kf{constructor(l,i,u){super("YAMLParseError",l,i,u)}}class Dp extends Kf{constructor(l,i,u){super("YAMLWarning",l,i,u)}}const Su=(s,l)=>i=>{if(i.pos[0]===-1)return;i.linePos=i.pos.map(m=>l.linePos(m));const{line:u,col:c}=i.linePos[0];i.message+=` at line ${u}, column ${c}`;let o=c-1,h=s.substring(l.lineStarts[u-1],l.lineStarts[u]).replace(/[\n\r]+$/,"");if(o>=60&&h.length>80){const m=Math.min(o-39,h.length-79);h="…"+h.substring(m),o-=m-1}if(h.length>80&&(h=h.substring(0,79)+"…"),u>1&&/^ *$/.test(h.substring(0,o))){let m=s.substring(l.lineStarts[u-2],l.lineStarts[u-1]);m.length>80&&(m=m.substring(0,79)+`… +`),h=m+h}if(/[^ ]/.test(h)){let m=1;const g=i.linePos[1];g&&g.line===u&&g.col>c&&(m=Math.max(1,Math.min(g.col-c,80-o)));const p=" ".repeat(o)+"^".repeat(m);i.message+=`: + +${h} +${p} +`}};function Aa(s,{flow:l,indicator:i,next:u,offset:c,onError:o,parentIndent:h,startOnNewline:m}){let g=!1,p=m,E=m,v="",_="",A=!1,z=!1,S=null,T=null,x=null,j=null,Y=null,X=null,W=null;for(const V of s)switch(z&&(V.type!=="space"&&V.type!=="newline"&&V.type!=="comma"&&o(V.offset,"MISSING_CHAR","Tags and anchors must be separated from the next token by white space"),z=!1),S&&(p&&V.type!=="comment"&&V.type!=="newline"&&o(S,"TAB_AS_INDENT","Tabs are not allowed as indentation"),S=null),V.type){case"space":!l&&(i!=="doc-start"||(u==null?void 0:u.type)!=="flow-collection")&&V.source.includes(" ")&&(S=V),E=!0;break;case"comment":{E||o(V,"MISSING_CHAR","Comments must be separated from other tokens by white space characters");const B=V.source.substring(1)||" ";v?v+=_+B:v=B,_="",p=!1;break}case"newline":p?v?v+=V.source:g=!0:_+=V.source,p=!0,A=!0,(T||x)&&(j=V),E=!0;break;case"anchor":T&&o(V,"MULTIPLE_ANCHORS","A node can have at most one anchor"),V.source.endsWith(":")&&o(V.offset+V.source.length-1,"BAD_ALIAS","Anchor ending in : is ambiguous",!0),T=V,W===null&&(W=V.offset),p=!1,E=!1,z=!0;break;case"tag":{x&&o(V,"MULTIPLE_TAGS","A node can have at most one tag"),x=V,W===null&&(W=V.offset),p=!1,E=!1,z=!0;break}case i:(T||x)&&o(V,"BAD_PROP_ORDER",`Anchors and tags must be after the ${V.source} indicator`),X&&o(V,"UNEXPECTED_TOKEN",`Unexpected ${V.source} in ${l??"collection"}`),X=V,p=i==="seq-item-ind"||i==="explicit-key-ind",E=!1;break;case"comma":if(l){Y&&o(V,"UNEXPECTED_TOKEN",`Unexpected , in ${l}`),Y=V,p=!1,E=!1;break}default:o(V,"UNEXPECTED_TOKEN",`Unexpected ${V.type} token`),p=!1,E=!1}const K=s[s.length-1],G=K?K.offset+K.source.length:c;return z&&u&&u.type!=="space"&&u.type!=="newline"&&u.type!=="comma"&&(u.type!=="scalar"||u.source!=="")&&o(u.offset,"MISSING_CHAR","Tags and anchors must be separated from the next token by white space"),S&&(p&&S.indent<=h||(u==null?void 0:u.type)==="block-map"||(u==null?void 0:u.type)==="block-seq")&&o(S,"TAB_AS_INDENT","Tabs are not allowed as indentation"),{comma:Y,found:X,spaceBefore:g,comment:v,hasNewline:A,anchor:T,tag:x,newlineAfterProp:j,end:G,start:W??G}}function Di(s){if(!s)return null;switch(s.type){case"alias":case"scalar":case"double-quoted-scalar":case"single-quoted-scalar":if(s.source.includes(` +`))return!0;if(s.end){for(const l of s.end)if(l.type==="newline")return!0}return!1;case"flow-collection":for(const l of s.items){for(const i of l.start)if(i.type==="newline")return!0;if(l.sep){for(const i of l.sep)if(i.type==="newline")return!0}if(Di(l.key)||Di(l.value))return!0}return!1;default:return!0}}function Cf(s,l,i){if((l==null?void 0:l.type)==="flow-collection"){const u=l.end[0];u.indent===s&&(u.source==="]"||u.source==="}")&&Di(l)&&i(u,"BAD_INDENT","Flow end indicator should be more indented than parent",!0)}}function Lp(s,l,i){const{uniqueKeys:u}=s.options;if(u===!1)return!1;const c=typeof u=="function"?u:(o,h)=>o===h||De(o)&&De(h)&&o.value===h.value;return l.some(o=>c(o.key,i))}const Eg="All mapping items must start at the same column";function ub({composeNode:s,composeEmptyNode:l},i,u,c,o){var E;const h=(o==null?void 0:o.nodeClass)??Lt,m=new h(i.schema);i.atRoot&&(i.atRoot=!1);let g=u.offset,p=null;for(const v of u.items){const{start:_,key:A,sep:z,value:S}=v,T=Aa(_,{indicator:"explicit-key-ind",next:A??(z==null?void 0:z[0]),offset:g,onError:c,parentIndent:u.indent,startOnNewline:!0}),x=!T.found;if(x){if(A&&(A.type==="block-seq"?c(g,"BLOCK_AS_IMPLICIT_KEY","A block sequence may not be used as an implicit map key"):"indent"in A&&A.indent!==u.indent&&c(g,"BAD_INDENT",Eg)),!T.anchor&&!T.tag&&!z){p=T.end,T.comment&&(m.comment?m.comment+=` +`+T.comment:m.comment=T.comment);continue}(T.newlineAfterProp||Di(A))&&c(A??_[_.length-1],"MULTILINE_IMPLICIT_KEY","Implicit keys need to be on a single line")}else((E=T.found)==null?void 0:E.indent)!==u.indent&&c(g,"BAD_INDENT",Eg);i.atKey=!0;const j=T.end,Y=A?s(i,A,T,c):l(i,j,_,null,T,c);i.schema.compat&&Cf(u.indent,A,c),i.atKey=!1,Lp(i,m.items,Y)&&c(j,"DUPLICATE_KEY","Map keys must be unique");const X=Aa(z??[],{indicator:"map-value-ind",next:S,offset:Y.range[2],onError:c,parentIndent:u.indent,startOnNewline:!A||A.type==="block-scalar"});if(g=X.end,X.found){x&&((S==null?void 0:S.type)==="block-map"&&!X.hasNewline&&c(g,"BLOCK_AS_IMPLICIT_KEY","Nested mappings are not allowed in compact mappings"),i.options.strict&&T.starts&&(s.type==="block-map"||s.type==="block-seq");function rb({composeNode:s,composeEmptyNode:l},i,u,c,o){const h=u.start.source==="{",m=h?"flow map":"flow sequence",g=(o==null?void 0:o.nodeClass)??(h?Lt:Pn),p=new g(i.schema);p.flow=!0;const E=i.atRoot;E&&(i.atRoot=!1),i.atKey&&(i.atKey=!1);let v=u.offset+u.start.source.length;for(let T=0;T0){const T=Ri(z,S,i.options.strict,c);T.comment&&(p.comment?p.comment+=` +`+T.comment:p.comment=T.comment),p.range=[u.offset,S,T.offset]}else p.range=[u.offset,S,S];return p}function pf(s,l,i,u,c,o){const h=i.type==="block-map"?ub(s,l,i,u,o):i.type==="block-seq"?cb(s,l,i,u,o):rb(s,l,i,u,o),m=h.constructor;return c==="!"||c===m.tagName?(h.tag=m.tagName,h):(c&&(h.tag=c),h)}function fb(s,l,i,u,c){var _;const o=u.tag,h=o?l.directives.tagName(o.source,A=>c(o,"TAG_RESOLVE_FAILED",A)):null;if(i.type==="block-seq"){const{anchor:A,newlineAfterProp:z}=u,S=A&&o?A.offset>o.offset?A:o:A??o;S&&(!z||z.offsetA.tag===h&&A.collection===m);if(!g){const A=l.schema.knownTags[h];if(A&&A.collection===m)l.schema.tags.push(Object.assign({},A,{default:!1})),g=A;else return A!=null&&A.collection?c(o,"BAD_COLLECTION_TYPE",`${A.tag} used for ${m} collection, but expects ${A.collection}`,!0):c(o,"TAG_RESOLVE_FAILED",`Unresolved tag: ${h}`,!0),pf(s,l,i,c,h)}const p=pf(s,l,i,c,h,g),E=((_=g.resolve)==null?void 0:_.call(g,p,A=>c(o,"TAG_RESOLVE_FAILED",A),l.options))??p,v=ke(E)?E:new ue(E);return v.range=p.range,v.tag=h,g!=null&&g.format&&(v.format=g.format),v}function Up(s,l,i){const u=l.offset,c=ob(l,s.options.strict,i);if(!c)return{value:"",type:null,comment:"",range:[u,u,u]};const o=c.mode===">"?ue.BLOCK_FOLDED:ue.BLOCK_LITERAL,h=l.source?hb(l.source):[];let m=h.length;for(let S=h.length-1;S>=0;--S){const T=h[S][1];if(T===""||T==="\r")m=S;else break}if(m===0){const S=c.chomp==="+"&&h.length>0?` +`.repeat(Math.max(1,h.length-1)):"";let T=u+c.length;return l.source&&(T+=l.source.length),{value:S,type:o,comment:c.comment,range:[u,T,T]}}let g=l.indent+c.indent,p=l.offset+c.length,E=0;for(let S=0;Sg&&(g=T.length);else{T.length=m;--S)h[S][0].length>g&&(m=S+1);let v="",_="",A=!1;for(let S=0;Sg||x[0]===" "?(_===" "?_=` +`:!A&&_===` +`&&(_=` + +`),v+=_+T.slice(g)+x,_=` +`,A=!0):x===""?_===` +`?v+=` +`:_=` +`:(v+=_+x,_=" ",A=!1)}switch(c.chomp){case"-":break;case"+":for(let S=m;Si(u+_,A,z);switch(c){case"scalar":m=ue.PLAIN,g=db(o,p);break;case"single-quoted-scalar":m=ue.QUOTE_SINGLE,g=mb(o,p);break;case"double-quoted-scalar":m=ue.QUOTE_DOUBLE,g=gb(o,p);break;default:return i(s,"UNEXPECTED_TOKEN",`Expected a flow scalar value, but found: ${c}`),{value:"",type:null,comment:"",range:[u,u+o.length,u+o.length]}}const E=u+o.length,v=Ri(h,E,l,i);return{value:g,type:m,comment:v.comment,range:[u,E,v.offset]}}function db(s,l){let i="";switch(s[0]){case" ":i="a tab character";break;case",":i="flow indicator character ,";break;case"%":i="directive indicator character %";break;case"|":case">":{i=`block scalar indicator ${s[0]}`;break}case"@":case"`":{i=`reserved character ${s[0]}`;break}}return i&&l(0,"BAD_SCALAR_START",`Plain value cannot start with ${i}`),Bp(s)}function mb(s,l){return(s[s.length-1]!=="'"||s.length===1)&&l(s.length,"MISSING_CHAR","Missing closing 'quote"),Bp(s.slice(1,-1)).replace(/''/g,"'")}function Bp(s){let l,i;try{l=new RegExp(`(.*?)(?o?s.slice(o,u+1):c)}else i+=c}return(s[s.length-1]!=='"'||s.length===1)&&l(s.length,"MISSING_CHAR",'Missing closing "quote'),i}function pb(s,l){let i="",u=s[l+1];for(;(u===" "||u===" "||u===` +`||u==="\r")&&!(u==="\r"&&s[l+2]!==` +`);)u===` +`&&(i+=` +`),l+=1,u=s[l+1];return i||(i=" "),{fold:i,offset:l}}const yb={0:"\0",a:"\x07",b:"\b",e:"\x1B",f:"\f",n:` +`,r:"\r",t:" ",v:"\v",N:"…",_:" ",L:"\u2028",P:"\u2029"," ":" ",'"':'"',"/":"/","\\":"\\"," ":" "};function vb(s,l,i,u){const c=s.substr(l,i),h=c.length===i&&/^[0-9a-fA-F]+$/.test(c)?parseInt(c,16):NaN;if(isNaN(h)){const m=s.substr(l-2,i+2);return u(l-2,"BAD_DQ_ESCAPE",`Invalid escape sequence ${m}`),m}return String.fromCodePoint(h)}function Rp(s,l,i,u){const{value:c,type:o,comment:h,range:m}=l.type==="block-scalar"?Up(s,l,u):jp(l,s.options.strict,u),g=i?s.directives.tagName(i.source,v=>u(i,"TAG_RESOLVE_FAILED",v)):null;let p;s.options.stringKeys&&s.atKey?p=s.schema[nn]:g?p=bb(s.schema,c,g,i,u):l.type==="scalar"?p=Sb(s,c,l,u):p=s.schema[nn];let E;try{const v=p.resolve(c,_=>u(i??l,"TAG_RESOLVE_FAILED",_),s.options);E=De(v)?v:new ue(v)}catch(v){const _=v instanceof Error?v.message:String(v);u(i??l,"TAG_RESOLVE_FAILED",_),E=new ue(c)}return E.range=m,E.source=c,o&&(E.type=o),g&&(E.tag=g),p.format&&(E.format=p.format),h&&(E.comment=h),E}function bb(s,l,i,u,c){var m;if(i==="!")return s[nn];const o=[];for(const g of s.tags)if(!g.collection&&g.tag===i)if(g.default&&g.test)o.push(g);else return g;for(const g of o)if((m=g.test)!=null&&m.test(l))return g;const h=s.knownTags[i];return h&&!h.collection?(s.tags.push(Object.assign({},h,{default:!1,test:void 0})),h):(c(u,"TAG_RESOLVE_FAILED",`Unresolved tag: ${i}`,i!=="tag:yaml.org,2002:str"),s[nn])}function Sb({atKey:s,directives:l,schema:i},u,c,o){const h=i.tags.find(m=>{var g;return(m.default===!0||s&&m.default==="key")&&((g=m.test)==null?void 0:g.test(u))})||i[nn];if(i.compat){const m=i.compat.find(g=>{var p;return g.default&&((p=g.test)==null?void 0:p.test(u))})??i[nn];if(h.tag!==m.tag){const g=l.tagString(h.tag),p=l.tagString(m.tag),E=`Value may be parsed as either ${g} or ${p}`;o(c,"TAG_RESOLVE_FAILED",E,!0)}}return h}function Tb(s,l,i){if(l){i===null&&(i=l.length);for(let u=i-1;u>=0;--u){let c=l[u];switch(c.type){case"space":case"comment":case"newline":s-=c.source.length;continue}for(c=l[++u];(c==null?void 0:c.type)==="space";)s+=c.source.length,c=l[++u];break}}return s}const Eb={composeNode:kp,composeEmptyNode:Vf};function kp(s,l,i,u){const c=s.atKey,{spaceBefore:o,comment:h,anchor:m,tag:g}=i;let p,E=!0;switch(l.type){case"alias":p=Ab(s,l,u),(m||g)&&u(l,"ALIAS_PROPS","An alias node must not specify any properties");break;case"scalar":case"single-quoted-scalar":case"double-quoted-scalar":case"block-scalar":p=Rp(s,l,g,u),m&&(p.anchor=m.source.substring(1));break;case"block-map":case"block-seq":case"flow-collection":p=fb(Eb,s,l,i,u),m&&(p.anchor=m.source.substring(1));break;default:{const v=l.type==="error"?l.message:`Unsupported token (type: ${l.type})`;u(l,"UNEXPECTED_TOKEN",v),p=Vf(s,l.offset,void 0,null,i,u),E=!1}}return m&&p.anchor===""&&u(m,"BAD_ALIAS","Anchor cannot be an empty string"),c&&s.options.stringKeys&&(!De(p)||typeof p.value!="string"||p.tag&&p.tag!=="tag:yaml.org,2002:str")&&u(g??l,"NON_STRING_KEY","With stringKeys, all keys must be strings"),o&&(p.spaceBefore=!0),h&&(l.type==="scalar"&&l.source===""?p.comment=h:p.commentBefore=h),s.options.keepSourceTokens&&E&&(p.srcToken=l),p}function Vf(s,l,i,u,{spaceBefore:c,comment:o,anchor:h,tag:m,end:g},p){const E={type:"scalar",offset:Tb(l,i,u),indent:-1,source:""},v=Rp(s,E,m,p);return h&&(v.anchor=h.source.substring(1),v.anchor===""&&p(h,"BAD_ALIAS","Anchor cannot be an empty string")),c&&(v.spaceBefore=!0),o&&(v.comment=o,v.range[2]=g),v}function Ab({options:s},{offset:l,source:i,end:u},c){const o=new _u(i.substring(1));o.source===""&&c(l,"BAD_ALIAS","Alias cannot be an empty string"),o.source.endsWith(":")&&c(l+i.length-1,"BAD_ALIAS","Alias ending in : is ambiguous",!0);const h=l+i.length,m=Ri(u,h,s.strict,c);return o.range=[l,h,m.offset],m.comment&&(o.comment=m.comment),o}function wb(s,l,{offset:i,start:u,value:c,end:o},h){const m=Object.assign({_directives:l},s),g=new xa(void 0,m),p={atKey:!1,atRoot:!0,directives:g.directives,options:g.options,schema:g.schema},E=Aa(u,{indicator:"doc-start",next:c??(o==null?void 0:o[0]),offset:i,onError:h,parentIndent:0,startOnNewline:!0});E.found&&(g.directives.docStart=!0,c&&(c.type==="block-map"||c.type==="block-seq")&&!E.hasNewline&&h(E.end,"MISSING_CHAR","Block collection cannot start on same line with directives-end marker")),g.contents=c?kp(p,c,E,h):Vf(p,E.end,u,null,E,h);const v=g.contents.range[2],_=Ri(o,v,!1,h);return _.comment&&(g.comment=_.comment),g.range=[i,v,_.offset],g}function Mi(s){if(typeof s=="number")return[s,s+1];if(Array.isArray(s))return s.length===2?s:[s[0],s[1]];const{offset:l,source:i}=s;return[l,l+(typeof i=="string"?i.length:1)]}function Ag(s){var c;let l="",i=!1,u=!1;for(let o=0;o{const h=Mi(i);o?this.warnings.push(new Dp(h,u,c)):this.errors.push(new Al(h,u,c))},this.directives=new ot({version:l.version||"1.2"}),this.options=l}decorate(l,i){const{comment:u,afterEmptyLine:c}=Ag(this.prelude);if(u){const o=l.contents;if(i)l.comment=l.comment?`${l.comment} +${u}`:u;else if(c||l.directives.docStart||!o)l.commentBefore=u;else if(Re(o)&&!o.flow&&o.items.length>0){let h=o.items[0];Be(h)&&(h=h.key);const m=h.commentBefore;h.commentBefore=m?`${u} +${m}`:u}else{const h=o.commentBefore;o.commentBefore=h?`${u} +${h}`:u}}i?(Array.prototype.push.apply(l.errors,this.errors),Array.prototype.push.apply(l.warnings,this.warnings)):(l.errors=this.errors,l.warnings=this.warnings),this.prelude=[],this.errors=[],this.warnings=[]}streamInfo(){return{comment:Ag(this.prelude).comment,directives:this.directives,errors:this.errors,warnings:this.warnings}}*compose(l,i=!1,u=-1){for(const c of l)yield*this.next(c);yield*this.end(i,u)}*next(l){switch(l.type){case"directive":this.directives.add(l.source,(i,u,c)=>{const o=Mi(l);o[0]+=i,this.onError(o,"BAD_DIRECTIVE",u,c)}),this.prelude.push(l.source),this.atDirectives=!0;break;case"document":{const i=wb(this.options,this.directives,l,this.onError);this.atDirectives&&!i.directives.docStart&&this.onError(l,"MISSING_CHAR","Missing directives-end/doc-start indicator line"),this.decorate(i,!1),this.doc&&(yield this.doc),this.doc=i,this.atDirectives=!1;break}case"byte-order-mark":case"space":break;case"comment":case"newline":this.prelude.push(l.source);break;case"error":{const i=l.source?`${l.message}: ${JSON.stringify(l.source)}`:l.message,u=new Al(Mi(l),"UNEXPECTED_TOKEN",i);this.atDirectives||!this.doc?this.errors.push(u):this.doc.errors.push(u);break}case"doc-end":{if(!this.doc){const u="Unexpected doc-end without preceding document";this.errors.push(new Al(Mi(l),"UNEXPECTED_TOKEN",u));break}this.doc.directives.docEnd=!0;const i=Ri(l.end,l.offset+l.source.length,this.doc.options.strict,this.onError);if(this.decorate(this.doc,!0),i.comment){const u=this.doc.comment;this.doc.comment=u?`${u} +${i.comment}`:i.comment}this.doc.range[2]=i.offset;break}default:this.errors.push(new Al(Mi(l),"UNEXPECTED_TOKEN",`Unsupported token ${l.type}`))}}*end(l=!1,i=-1){if(this.doc)this.decorate(this.doc,!0),yield this.doc,this.doc=null;else if(l){const u=Object.assign({_directives:this.directives},this.options),c=new xa(void 0,u);this.atDirectives&&this.onError(i,"MISSING_CHAR","Missing directives-end indicator line"),c.range=[0,i,i],this.decorate(c,!1),yield c}}}function Ob(s,l=!0,i){if(s){const u=(c,o,h)=>{const m=typeof c=="number"?c:Array.isArray(c)?c[0]:c.offset;if(i)i(m,o,h);else throw new Al([m,m+1],o,h)};switch(s.type){case"scalar":case"single-quoted-scalar":case"double-quoted-scalar":return jp(s,l,u);case"block-scalar":return Up({options:{strict:l}},s,u)}}return null}function _b(s,l){const{implicitKey:i=!1,indent:u,inFlow:c=!1,offset:o=-1,type:h="PLAIN"}=l,m=ji({type:h,value:s},{implicitKey:i,indent:u>0?" ".repeat(u):"",inFlow:c,options:{blockQuote:!0,lineWidth:-1}}),g=l.end??[{type:"newline",offset:-1,indent:u,source:` +`}];switch(m[0]){case"|":case">":{const p=m.indexOf(` +`),E=m.substring(0,p),v=m.substring(p+1)+` +`,_=[{type:"block-scalar-header",offset:o,indent:u,source:E}];return qp(_,g)||_.push({type:"newline",offset:-1,indent:u,source:` +`}),{type:"block-scalar",offset:o,indent:u,props:_,source:v}}case'"':return{type:"double-quoted-scalar",offset:o,indent:u,source:m,end:g};case"'":return{type:"single-quoted-scalar",offset:o,indent:u,source:m,end:g};default:return{type:"scalar",offset:o,indent:u,source:m,end:g}}}function Nb(s,l,i={}){let{afterKey:u=!1,implicitKey:c=!1,inFlow:o=!1,type:h}=i,m="indent"in s?s.indent:null;if(u&&typeof m=="number"&&(m+=2),!h)switch(s.type){case"single-quoted-scalar":h="QUOTE_SINGLE";break;case"double-quoted-scalar":h="QUOTE_DOUBLE";break;case"block-scalar":{const p=s.props[0];if(p.type!=="block-scalar-header")throw new Error("Invalid block scalar header");h=p.source[0]===">"?"BLOCK_FOLDED":"BLOCK_LITERAL";break}default:h="PLAIN"}const g=ji({type:h,value:l},{implicitKey:c||m===null,indent:m!==null&&m>0?" ".repeat(m):"",inFlow:o,options:{blockQuote:!0,lineWidth:-1}});switch(g[0]){case"|":case">":Mb(s,g);break;case'"':yf(s,g,"double-quoted-scalar");break;case"'":yf(s,g,"single-quoted-scalar");break;default:yf(s,g,"scalar")}}function Mb(s,l){const i=l.indexOf(` +`),u=l.substring(0,i),c=l.substring(i+1)+` +`;if(s.type==="block-scalar"){const o=s.props[0];if(o.type!=="block-scalar-header")throw new Error("Invalid block scalar header");o.source=u,s.source=c}else{const{offset:o}=s,h="indent"in s?s.indent:-1,m=[{type:"block-scalar-header",offset:o,indent:h,source:u}];qp(m,"end"in s?s.end:void 0)||m.push({type:"newline",offset:-1,indent:h,source:` +`});for(const g of Object.keys(s))g!=="type"&&g!=="offset"&&delete s[g];Object.assign(s,{type:"block-scalar",indent:h,props:m,source:c})}}function qp(s,l){if(l)for(const i of l)switch(i.type){case"space":case"comment":s.push(i);break;case"newline":return s.push(i),!0}return!1}function yf(s,l,i){switch(s.type){case"scalar":case"double-quoted-scalar":case"single-quoted-scalar":s.type=i,s.source=l;break;case"block-scalar":{const u=s.props.slice(1);let c=l.length;s.props[0].type==="block-scalar-header"&&(c-=s.props[0].source.length);for(const o of u)o.offset+=c;delete s.props,Object.assign(s,{type:i,source:l,end:u});break}case"block-map":case"block-seq":{const c={type:"newline",offset:s.offset+l.length,indent:s.indent,source:` +`};delete s.items,Object.assign(s,{type:i,source:l,end:[c]});break}default:{const u="indent"in s?s.indent:-1,c="end"in s&&Array.isArray(s.end)?s.end.filter(o=>o.type==="space"||o.type==="comment"||o.type==="newline"):[];for(const o of Object.keys(s))o!=="type"&&o!=="offset"&&delete s[o];Object.assign(s,{type:i,indent:u,source:l,end:c})}}}const Cb=s=>"type"in s?Tu(s):gu(s);function Tu(s){switch(s.type){case"block-scalar":{let l="";for(const i of s.props)l+=Tu(i);return l+s.source}case"block-map":case"block-seq":{let l="";for(const i of s.items)l+=gu(i);return l}case"flow-collection":{let l=s.start.source;for(const i of s.items)l+=gu(i);for(const i of s.end)l+=i.source;return l}case"document":{let l=gu(s);if(s.end)for(const i of s.end)l+=i.source;return l}default:{let l=s.source;if("end"in s&&s.end)for(const i of s.end)l+=i.source;return l}}}function gu({start:s,key:l,sep:i,value:u}){let c="";for(const o of s)c+=o.source;if(l&&(c+=Tu(l)),i)for(const o of i)c+=o.source;return u&&(c+=Tu(u)),c}const zf=Symbol("break visit"),zb=Symbol("skip children"),Hp=Symbol("remove item");function Ol(s,l){"type"in s&&s.type==="document"&&(s={start:s.start,value:s.value}),$p(Object.freeze([]),s,l)}Ol.BREAK=zf;Ol.SKIP=zb;Ol.REMOVE=Hp;Ol.itemAtPath=(s,l)=>{let i=s;for(const[u,c]of l){const o=i==null?void 0:i[u];if(o&&"items"in o)i=o.items[c];else return}return i};Ol.parentCollection=(s,l)=>{const i=Ol.itemAtPath(s,l.slice(0,-1)),u=l[l.length-1][0],c=i==null?void 0:i[u];if(c&&"items"in c)return c;throw new Error("Parent collection not found")};function $p(s,l,i){let u=i(l,s);if(typeof u=="symbol")return u;for(const c of["key","value"]){const o=l[c];if(o&&"items"in o){for(let h=0;h!!s&&"items"in s,Db=s=>!!s&&(s.type==="scalar"||s.type==="single-quoted-scalar"||s.type==="double-quoted-scalar"||s.type==="block-scalar");function Lb(s){switch(s){case Bu:return"";case Ru:return"";case ku:return"";case Li:return"";default:return JSON.stringify(s)}}function Yp(s){switch(s){case Bu:return"byte-order-mark";case Ru:return"doc-mode";case ku:return"flow-error-end";case Li:return"scalar";case"---":return"doc-start";case"...":return"doc-end";case"":case` +`:case`\r +`:return"newline";case"-":return"seq-item-ind";case"?":return"explicit-key-ind";case":":return"map-value-ind";case"{":return"flow-map-start";case"}":return"flow-map-end";case"[":return"flow-seq-start";case"]":return"flow-seq-end";case",":return"comma"}switch(s[0]){case" ":case" ":return"space";case"#":return"comment";case"%":return"directive-line";case"*":return"alias";case"&":return"anchor";case"!":return"tag";case"'":return"single-quoted-scalar";case'"':return"double-quoted-scalar";case"|":case">":return"block-scalar-header"}return null}const Ub=Object.freeze(Object.defineProperty({__proto__:null,BOM:Bu,DOCUMENT:Ru,FLOW_END:ku,SCALAR:Li,createScalarToken:_b,isCollection:xb,isScalar:Db,prettyToken:Lb,resolveAsScalar:Ob,setScalarValue:Nb,stringify:Cb,tokenType:Yp,visit:Ol},Symbol.toStringTag,{value:"Module"}));function Jt(s){switch(s){case void 0:case" ":case` +`:case"\r":case" ":return!0;default:return!1}}const wg=new Set("0123456789ABCDEFabcdef"),jb=new Set("0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-#;/?:@&=+$_.!~*'()"),iu=new Set(",[]{}"),Bb=new Set(` ,[]{} +\r `),vf=s=>!s||Bb.has(s);class Gp{constructor(){this.atEnd=!1,this.blockScalarIndent=-1,this.blockScalarKeep=!1,this.buffer="",this.flowKey=!1,this.flowLevel=0,this.indentNext=0,this.indentValue=0,this.lineEndPos=null,this.next=null,this.pos=0}*lex(l,i=!1){if(l){if(typeof l!="string")throw TypeError("source is not a string");this.buffer=this.buffer?this.buffer+l:l,this.lineEndPos=null}this.atEnd=!i;let u=this.next??"stream";for(;u&&(i||this.hasChars(1));)u=yield*this.parseNext(u)}atLineEnd(){let l=this.pos,i=this.buffer[l];for(;i===" "||i===" ";)i=this.buffer[++l];return!i||i==="#"||i===` +`?!0:i==="\r"?this.buffer[l+1]===` +`:!1}charAt(l){return this.buffer[this.pos+l]}continueScalar(l){let i=this.buffer[l];if(this.indentNext>0){let u=0;for(;i===" ";)i=this.buffer[++u+l];if(i==="\r"){const c=this.buffer[u+l+1];if(c===` +`||!c&&!this.atEnd)return l+u+1}return i===` +`||u>=this.indentNext||!i&&!this.atEnd?l+u:-1}if(i==="-"||i==="."){const u=this.buffer.substr(l,3);if((u==="---"||u==="...")&&Jt(this.buffer[l+3]))return-1}return l}getLine(){let l=this.lineEndPos;return(typeof l!="number"||l!==-1&&lthis.indentValue&&!Jt(this.charAt(1))&&(this.indentNext=this.indentValue),yield*this.parseBlockStart()}*parseBlockStart(){const[l,i]=this.peek(2);if(!i&&!this.atEnd)return this.setNext("block-start");if((l==="-"||l==="?"||l===":")&&Jt(i)){const u=(yield*this.pushCount(1))+(yield*this.pushSpaces(!0));return this.indentNext=this.indentValue+1,this.indentValue+=u,yield*this.parseBlockStart()}return"doc"}*parseDocument(){yield*this.pushSpaces(!0);const l=this.getLine();if(l===null)return this.setNext("doc");let i=yield*this.pushIndicators();switch(l[i]){case"#":yield*this.pushCount(l.length-i);case void 0:return yield*this.pushNewline(),yield*this.parseLineStart();case"{":case"[":return yield*this.pushCount(1),this.flowKey=!1,this.flowLevel=1,"flow";case"}":case"]":return yield*this.pushCount(1),"doc";case"*":return yield*this.pushUntil(vf),"doc";case'"':case"'":return yield*this.parseQuotedScalar();case"|":case">":return i+=yield*this.parseBlockScalarHeader(),i+=yield*this.pushSpaces(!0),yield*this.pushCount(l.length-i),yield*this.pushNewline(),yield*this.parseBlockScalar();default:return yield*this.parsePlainScalar()}}*parseFlowCollection(){let l,i,u=-1;do l=yield*this.pushNewline(),l>0?(i=yield*this.pushSpaces(!1),this.indentValue=u=i):i=0,i+=yield*this.pushSpaces(!0);while(l+i>0);const c=this.getLine();if(c===null)return this.setNext("flow");if((u!==-1&&u"0"&&i<="9")this.blockScalarIndent=Number(i)-1;else if(i!=="-")break}return yield*this.pushUntil(i=>Jt(i)||i==="#")}*parseBlockScalar(){let l=this.pos-1,i=0,u;e:for(let o=this.pos;u=this.buffer[o];++o)switch(u){case" ":i+=1;break;case` +`:l=o,i=0;break;case"\r":{const h=this.buffer[o+1];if(!h&&!this.atEnd)return this.setNext("block-scalar");if(h===` +`)break}default:break e}if(!u&&!this.atEnd)return this.setNext("block-scalar");if(i>=this.indentNext){this.blockScalarIndent===-1?this.indentNext=i:this.indentNext=this.blockScalarIndent+(this.indentNext===0?1:this.indentNext);do{const o=this.continueScalar(l+1);if(o===-1)break;l=this.buffer.indexOf(` +`,o)}while(l!==-1);if(l===-1){if(!this.atEnd)return this.setNext("block-scalar");l=this.buffer.length}}let c=l+1;for(u=this.buffer[c];u===" ";)u=this.buffer[++c];if(u===" "){for(;u===" "||u===" "||u==="\r"||u===` +`;)u=this.buffer[++c];l=c-1}else if(!this.blockScalarKeep)do{let o=l-1,h=this.buffer[o];h==="\r"&&(h=this.buffer[--o]);const m=o;for(;h===" ";)h=this.buffer[--o];if(h===` +`&&o>=this.pos&&o+1+i>m)l=o;else break}while(!0);return yield Li,yield*this.pushToIndex(l+1,!0),yield*this.parseLineStart()}*parsePlainScalar(){const l=this.flowLevel>0;let i=this.pos-1,u=this.pos-1,c;for(;c=this.buffer[++u];)if(c===":"){const o=this.buffer[u+1];if(Jt(o)||l&&iu.has(o))break;i=u}else if(Jt(c)){let o=this.buffer[u+1];if(c==="\r"&&(o===` +`?(u+=1,c=` +`,o=this.buffer[u+1]):i=u),o==="#"||l&&iu.has(o))break;if(c===` +`){const h=this.continueScalar(u+1);if(h===-1)break;u=Math.max(u,h-2)}}else{if(l&&iu.has(c))break;i=u}return!c&&!this.atEnd?this.setNext("plain-scalar"):(yield Li,yield*this.pushToIndex(i+1,!0),l?"flow":"doc")}*pushCount(l){return l>0?(yield this.buffer.substr(this.pos,l),this.pos+=l,l):0}*pushToIndex(l,i){const u=this.buffer.slice(this.pos,l);return u?(yield u,this.pos+=u.length,u.length):(i&&(yield""),0)}*pushIndicators(){switch(this.charAt(0)){case"!":return(yield*this.pushTag())+(yield*this.pushSpaces(!0))+(yield*this.pushIndicators());case"&":return(yield*this.pushUntil(vf))+(yield*this.pushSpaces(!0))+(yield*this.pushIndicators());case"-":case"?":case":":{const l=this.flowLevel>0,i=this.charAt(1);if(Jt(i)||l&&iu.has(i))return l?this.flowKey&&(this.flowKey=!1):this.indentNext=this.indentValue+1,(yield*this.pushCount(1))+(yield*this.pushSpaces(!0))+(yield*this.pushIndicators())}}return 0}*pushTag(){if(this.charAt(1)==="<"){let l=this.pos+2,i=this.buffer[l];for(;!Jt(i)&&i!==">";)i=this.buffer[++l];return yield*this.pushToIndex(i===">"?l+1:l,!1)}else{let l=this.pos+1,i=this.buffer[l];for(;i;)if(jb.has(i))i=this.buffer[++l];else if(i==="%"&&wg.has(this.buffer[l+1])&&wg.has(this.buffer[l+2]))i=this.buffer[l+=3];else break;return yield*this.pushToIndex(l,!1)}}*pushNewline(){const l=this.buffer[this.pos];return l===` +`?yield*this.pushCount(1):l==="\r"&&this.charAt(1)===` +`?yield*this.pushCount(2):0}*pushSpaces(l){let i=this.pos-1,u;do u=this.buffer[++i];while(u===" "||l&&u===" ");const c=i-this.pos;return c>0&&(yield this.buffer.substr(this.pos,c),this.pos=i),c}*pushUntil(l){let i=this.pos,u=this.buffer[i];for(;!l(u);)u=this.buffer[++i];return yield*this.pushToIndex(i,!1)}}class Kp{constructor(){this.lineStarts=[],this.addNewLine=l=>this.lineStarts.push(l),this.linePos=l=>{let i=0,u=this.lineStarts.length;for(;i>1;this.lineStarts[o]=0;)switch(s[l].type){case"doc-start":case"explicit-key-ind":case"map-value-ind":case"seq-item-ind":case"newline":break e}for(;((i=s[++l])==null?void 0:i.type)==="space";);return s.splice(l,s.length)}function _g(s){if(s.start.type==="flow-seq-start")for(const l of s.items)l.sep&&!l.value&&!Sl(l.start,"explicit-key-ind")&&!Sl(l.sep,"map-value-ind")&&(l.key&&(l.value=l.key),delete l.key,Vp(l.value)?l.value.end?Array.prototype.push.apply(l.value.end,l.sep):l.value.end=l.sep:Array.prototype.push.apply(l.start,l.sep),delete l.sep)}class Xf{constructor(l){this.atNewLine=!0,this.atScalar=!1,this.indent=0,this.offset=0,this.onKeyLine=!1,this.stack=[],this.source="",this.type="",this.lexer=new Gp,this.onNewLine=l}*parse(l,i=!1){this.onNewLine&&this.offset===0&&this.onNewLine(0);for(const u of this.lexer.lex(l,i))yield*this.next(u);i||(yield*this.end())}*next(l){if(this.source=l,this.atScalar){this.atScalar=!1,yield*this.step(),this.offset+=l.length;return}const i=Yp(l);if(i)if(i==="scalar")this.atNewLine=!1,this.atScalar=!0,this.type="scalar";else{switch(this.type=i,yield*this.step(),i){case"newline":this.atNewLine=!0,this.indent=0,this.onNewLine&&this.onNewLine(this.offset+l.length);break;case"space":this.atNewLine&&l[0]===" "&&(this.indent+=l.length);break;case"explicit-key-ind":case"map-value-ind":case"seq-item-ind":this.atNewLine&&(this.indent+=l.length);break;case"doc-mode":case"flow-error-end":return;default:this.atNewLine=!1}this.offset+=l.length}else{const u=`Not a YAML token: ${l}`;yield*this.pop({type:"error",offset:this.offset,message:u,source:l}),this.offset+=l.length}}*end(){for(;this.stack.length>0;)yield*this.pop()}get sourceToken(){return{type:this.type,offset:this.offset,indent:this.indent,source:this.source}}*step(){const l=this.peek(1);if(this.type==="doc-end"&&(!l||l.type!=="doc-end")){for(;this.stack.length>0;)yield*this.pop();this.stack.push({type:"doc-end",offset:this.offset,source:this.source});return}if(!l)return yield*this.stream();switch(l.type){case"document":return yield*this.document(l);case"alias":case"scalar":case"single-quoted-scalar":case"double-quoted-scalar":return yield*this.scalar(l);case"block-scalar":return yield*this.blockScalar(l);case"block-map":return yield*this.blockMap(l);case"block-seq":return yield*this.blockSequence(l);case"flow-collection":return yield*this.flowCollection(l);case"doc-end":return yield*this.documentEnd(l)}yield*this.pop()}peek(l){return this.stack[this.stack.length-l]}*pop(l){const i=l??this.stack.pop();if(!i)yield{type:"error",offset:this.offset,source:"",message:"Tried to pop an empty stack"};else if(this.stack.length===0)yield i;else{const u=this.peek(1);switch(i.type==="block-scalar"?i.indent="indent"in u?u.indent:0:i.type==="flow-collection"&&u.type==="document"&&(i.indent=0),i.type==="flow-collection"&&_g(i),u.type){case"document":u.value=i;break;case"block-scalar":u.props.push(i);break;case"block-map":{const c=u.items[u.items.length-1];if(c.value){u.items.push({start:[],key:i,sep:[]}),this.onKeyLine=!0;return}else if(c.sep)c.value=i;else{Object.assign(c,{key:i,sep:[]}),this.onKeyLine=!c.explicitKey;return}break}case"block-seq":{const c=u.items[u.items.length-1];c.value?u.items.push({start:[],value:i}):c.value=i;break}case"flow-collection":{const c=u.items[u.items.length-1];!c||c.value?u.items.push({start:[],key:i,sep:[]}):c.sep?c.value=i:Object.assign(c,{key:i,sep:[]});return}default:yield*this.pop(),yield*this.pop(i)}if((u.type==="document"||u.type==="block-map"||u.type==="block-seq")&&(i.type==="block-map"||i.type==="block-seq")){const c=i.items[i.items.length-1];c&&!c.sep&&!c.value&&c.start.length>0&&Og(c.start)===-1&&(i.indent===0||c.start.every(o=>o.type!=="comment"||o.indent=l.indent){const c=!this.onKeyLine&&this.indent===l.indent,o=c&&(i.sep||i.explicitKey)&&this.type!=="seq-item-ind";let h=[];if(o&&i.sep&&!i.value){const m=[];for(let g=0;gl.indent&&(m.length=0);break;default:m.length=0}}m.length>=2&&(h=i.sep.splice(m[1]))}switch(this.type){case"anchor":case"tag":o||i.value?(h.push(this.sourceToken),l.items.push({start:h}),this.onKeyLine=!0):i.sep?i.sep.push(this.sourceToken):i.start.push(this.sourceToken);return;case"explicit-key-ind":!i.sep&&!i.explicitKey?(i.start.push(this.sourceToken),i.explicitKey=!0):o||i.value?(h.push(this.sourceToken),l.items.push({start:h,explicitKey:!0})):this.stack.push({type:"block-map",offset:this.offset,indent:this.indent,items:[{start:[this.sourceToken],explicitKey:!0}]}),this.onKeyLine=!0;return;case"map-value-ind":if(i.explicitKey)if(i.sep)if(i.value)l.items.push({start:[],key:null,sep:[this.sourceToken]});else if(Sl(i.sep,"map-value-ind"))this.stack.push({type:"block-map",offset:this.offset,indent:this.indent,items:[{start:h,key:null,sep:[this.sourceToken]}]});else if(Vp(i.key)&&!Sl(i.sep,"newline")){const m=da(i.start),g=i.key,p=i.sep;p.push(this.sourceToken),delete i.key,delete i.sep,this.stack.push({type:"block-map",offset:this.offset,indent:this.indent,items:[{start:m,key:g,sep:p}]})}else h.length>0?i.sep=i.sep.concat(h,this.sourceToken):i.sep.push(this.sourceToken);else if(Sl(i.start,"newline"))Object.assign(i,{key:null,sep:[this.sourceToken]});else{const m=da(i.start);this.stack.push({type:"block-map",offset:this.offset,indent:this.indent,items:[{start:m,key:null,sep:[this.sourceToken]}]})}else i.sep?i.value||o?l.items.push({start:h,key:null,sep:[this.sourceToken]}):Sl(i.sep,"map-value-ind")?this.stack.push({type:"block-map",offset:this.offset,indent:this.indent,items:[{start:[],key:null,sep:[this.sourceToken]}]}):i.sep.push(this.sourceToken):Object.assign(i,{key:null,sep:[this.sourceToken]});this.onKeyLine=!0;return;case"alias":case"scalar":case"single-quoted-scalar":case"double-quoted-scalar":{const m=this.flowScalar(this.type);o||i.value?(l.items.push({start:h,key:m,sep:[]}),this.onKeyLine=!0):i.sep?this.stack.push(m):(Object.assign(i,{key:m,sep:[]}),this.onKeyLine=!0);return}default:{const m=this.startBlockValue(l);if(m){c&&m.type!=="block-seq"&&l.items.push({start:h}),this.stack.push(m);return}}}}yield*this.pop(),yield*this.step()}*blockSequence(l){var u;const i=l.items[l.items.length-1];switch(this.type){case"newline":if(i.value){const c="end"in i.value?i.value.end:void 0,o=Array.isArray(c)?c[c.length-1]:void 0;(o==null?void 0:o.type)==="comment"?c==null||c.push(this.sourceToken):l.items.push({start:[this.sourceToken]})}else i.start.push(this.sourceToken);return;case"space":case"comment":if(i.value)l.items.push({start:[this.sourceToken]});else{if(this.atIndentedComment(i.start,l.indent)){const c=l.items[l.items.length-2],o=(u=c==null?void 0:c.value)==null?void 0:u.end;if(Array.isArray(o)){Array.prototype.push.apply(o,i.start),o.push(this.sourceToken),l.items.pop();return}}i.start.push(this.sourceToken)}return;case"anchor":case"tag":if(i.value||this.indent<=l.indent)break;i.start.push(this.sourceToken);return;case"seq-item-ind":if(this.indent!==l.indent)break;i.value||Sl(i.start,"seq-item-ind")?l.items.push({start:[this.sourceToken]}):i.start.push(this.sourceToken);return}if(this.indent>l.indent){const c=this.startBlockValue(l);if(c){this.stack.push(c);return}}yield*this.pop(),yield*this.step()}*flowCollection(l){const i=l.items[l.items.length-1];if(this.type==="flow-error-end"){let u;do yield*this.pop(),u=this.peek(1);while(u&&u.type==="flow-collection")}else if(l.end.length===0){switch(this.type){case"comma":case"explicit-key-ind":!i||i.sep?l.items.push({start:[this.sourceToken]}):i.start.push(this.sourceToken);return;case"map-value-ind":!i||i.value?l.items.push({start:[],key:null,sep:[this.sourceToken]}):i.sep?i.sep.push(this.sourceToken):Object.assign(i,{key:null,sep:[this.sourceToken]});return;case"space":case"comment":case"newline":case"anchor":case"tag":!i||i.value?l.items.push({start:[this.sourceToken]}):i.sep?i.sep.push(this.sourceToken):i.start.push(this.sourceToken);return;case"alias":case"scalar":case"single-quoted-scalar":case"double-quoted-scalar":{const c=this.flowScalar(this.type);!i||i.value?l.items.push({start:[],key:c,sep:[]}):i.sep?this.stack.push(c):Object.assign(i,{key:c,sep:[]});return}case"flow-map-end":case"flow-seq-end":l.end.push(this.sourceToken);return}const u=this.startBlockValue(l);u?this.stack.push(u):(yield*this.pop(),yield*this.step())}else{const u=this.peek(2);if(u.type==="block-map"&&(this.type==="map-value-ind"&&u.indent===l.indent||this.type==="newline"&&!u.items[u.items.length-1].sep))yield*this.pop(),yield*this.step();else if(this.type==="map-value-ind"&&u.type!=="flow-collection"){const c=su(u),o=da(c);_g(l);const h=l.end.splice(1,l.end.length);h.push(this.sourceToken);const m={type:"block-map",offset:l.offset,indent:l.indent,items:[{start:o,key:l,sep:h}]};this.onKeyLine=!0,this.stack[this.stack.length-1]=m}else yield*this.lineEnd(l)}}flowScalar(l){if(this.onNewLine){let i=this.source.indexOf(` +`)+1;for(;i!==0;)this.onNewLine(this.offset+i),i=this.source.indexOf(` +`,i)+1}return{type:l,offset:this.offset,indent:this.indent,source:this.source}}startBlockValue(l){switch(this.type){case"alias":case"scalar":case"single-quoted-scalar":case"double-quoted-scalar":return this.flowScalar(this.type);case"block-scalar-header":return{type:"block-scalar",offset:this.offset,indent:this.indent,props:[this.sourceToken],source:""};case"flow-map-start":case"flow-seq-start":return{type:"flow-collection",offset:this.offset,indent:this.indent,start:this.sourceToken,items:[],end:[]};case"seq-item-ind":return{type:"block-seq",offset:this.offset,indent:this.indent,items:[{start:[this.sourceToken]}]};case"explicit-key-ind":{this.onKeyLine=!0;const i=su(l),u=da(i);return u.push(this.sourceToken),{type:"block-map",offset:this.offset,indent:this.indent,items:[{start:u,explicitKey:!0}]}}case"map-value-ind":{this.onKeyLine=!0;const i=su(l),u=da(i);return{type:"block-map",offset:this.offset,indent:this.indent,items:[{start:u,key:null,sep:[this.sourceToken]}]}}}return null}atIndentedComment(l,i){return this.type!=="comment"||this.indent<=i?!1:l.every(u=>u.type==="newline"||u.type==="space")}*documentEnd(l){this.type!=="doc-mode"&&(l.end?l.end.push(this.sourceToken):l.end=[this.sourceToken],this.type==="newline"&&(yield*this.pop()))}*lineEnd(l){switch(this.type){case"comma":case"doc-start":case"doc-end":case"flow-seq-end":case"flow-map-end":case"map-value-ind":yield*this.pop(),yield*this.step();break;case"newline":this.onKeyLine=!1;case"space":case"comment":default:l.end?l.end.push(this.sourceToken):l.end=[this.sourceToken],this.type==="newline"&&(yield*this.pop())}}}function Qp(s){const l=s.prettyErrors!==!1;return{lineCounter:s.lineCounter||l&&new Kp||null,prettyErrors:l}}function Rb(s,l={}){const{lineCounter:i,prettyErrors:u}=Qp(l),c=new Xf(i==null?void 0:i.addNewLine),o=new Qf(l),h=Array.from(o.compose(c.parse(s)));if(u&&i)for(const m of h)m.errors.forEach(Su(s,i)),m.warnings.forEach(Su(s,i));return h.length>0?h:Object.assign([],{empty:!0},o.streamInfo())}function Xp(s,l={}){const{lineCounter:i,prettyErrors:u}=Qp(l),c=new Xf(i==null?void 0:i.addNewLine),o=new Qf(l);let h=null;for(const m of o.compose(c.parse(s),!0,s.length))if(!h)h=m;else if(h.options.logLevel!=="silent"){h.errors.push(new Al(m.range.slice(0,2),"MULTIPLE_DOCS","Source contains multiple documents; please use YAML.parseAllDocuments()"));break}return u&&i&&(h.errors.forEach(Su(s,i)),h.warnings.forEach(Su(s,i))),h}function kb(s,l,i){let u;typeof l=="function"?u=l:i===void 0&&l&&typeof l=="object"&&(i=l);const c=Xp(s,i);if(!c)return null;if(c.warnings.forEach(o=>dp(c.options.logLevel,o)),c.errors.length>0){if(c.options.logLevel!=="silent")throw c.errors[0];c.errors=[]}return c.toJS(Object.assign({reviver:u},i))}function qb(s,l,i){let u=null;if(typeof l=="function"||Array.isArray(l)?u=l:i===void 0&&l&&(i=l),typeof i=="string"&&(i=i.length),typeof i=="number"){const c=Math.round(i);i=c<1?void 0:c>8?{indent:8}:{indent:c}}if(s===void 0){const{keepUndefined:c}=i??l??{};if(!c)return}return Nl(s)&&!u?s.toString(i):new xa(s,u,i).toString(i)}const Hb=Object.freeze(Object.defineProperty({__proto__:null,Alias:_u,CST:Ub,Composer:Qf,Document:xa,Lexer:Gp,LineCounter:Kp,Pair:ct,Parser:Xf,Scalar:ue,Schema:ju,YAMLError:Kf,YAMLMap:Lt,YAMLParseError:Al,YAMLSeq:Pn,YAMLWarning:Dp,isAlias:_l,isCollection:Re,isDocument:Nl,isMap:Na,isNode:ke,isPair:Be,isScalar:De,isSeq:Ma,parse:kb,parseAllDocuments:Rb,parseDocument:Xp,stringify:qb,visit:In,visitAsync:Ou},Symbol.toStringTag,{value:"Module"}));function $b(s,l,i={}){var _;const u=new s.LineCounter,c={keepSourceTokens:!0,lineCounter:u,...i},o=s.parseDocument(l,c),h=[],m=A=>[u.linePos(A[0]),u.linePos(A[1])],g=A=>{h.push({message:A.message,range:[u.linePos(A.pos[0]),u.linePos(A.pos[1])]})},p=(A,z)=>{for(const S of z.items){if(S instanceof s.Scalar&&typeof S.value=="string"){const j=Eu.parse(S,c,h);j&&(A.children=A.children||[],A.children.push(j));continue}if(S instanceof s.YAMLMap){E(A,S);continue}h.push({message:"Sequence items should be strings or maps",range:m(S.range||z.range)})}},E=(A,z)=>{for(const S of z.items){if(A.children=A.children||[],!(S.key instanceof s.Scalar&&typeof S.key.value=="string")){h.push({message:"Only string keys are supported",range:m(S.key.range||z.range)});continue}const x=S.key,j=S.value;if(x.value==="text"){if(!(j instanceof s.Scalar&&typeof j.value=="string")){h.push({message:"Text value should be a string",range:m(S.value.range||z.range)});continue}A.children.push({kind:"text",text:bf(j.value)});continue}if(x.value==="/children"){if(!(j instanceof s.Scalar&&typeof j.value=="string")||j.value!=="contain"&&j.value!=="equal"&&j.value!=="deep-equal"){h.push({message:'Strict value should be "contain", "equal" or "deep-equal"',range:m(S.value.range||z.range)});continue}A.containerMode=j.value;continue}if(x.value.startsWith("/")){if(!(j instanceof s.Scalar&&typeof j.value=="string")){h.push({message:"Property value should be a string",range:m(S.value.range||z.range)});continue}A.props=A.props??{},A.props[x.value.slice(1)]=bf(j.value);continue}const Y=Eu.parse(x,c,h);if(!Y)continue;if(j instanceof s.Scalar){const K=typeof j.value;if(K!=="string"&&K!=="number"&&K!=="boolean"){h.push({message:"Node value should be a string or a sequence",range:m(S.value.range||z.range)});continue}A.children.push({...Y,children:[{kind:"text",text:bf(String(j.value))}]});continue}if(j instanceof s.YAMLSeq){A.children.push(Y),p(Y,j);continue}h.push({message:"Map values should be strings or sequences",range:m(S.value.range||z.range)})}},v={kind:"role",role:"fragment"};return o.errors.forEach(g),h.length?{errors:h,fragment:v}:(o.contents instanceof s.YAMLSeq||h.push({message:'Aria snapshot must be a YAML sequence, elements starting with " -"',range:o.contents?m(o.contents.range):[{line:0,col:0},{line:0,col:0}]}),h.length?{errors:h,fragment:v}:(p(v,o.contents),h.length?{errors:h,fragment:Yb}:((_=v.children)==null?void 0:_.length)===1&&(!v.containerMode||v.containerMode==="contain")?{fragment:v.children[0],errors:[]}:{fragment:v,errors:[]}))}const Yb={kind:"role",role:"fragment"};function Zp(s){return s.replace(/[\u200b\u00ad]/g,"").replace(/[\r\n\s\t]+/g," ").trim()}function bf(s){return{raw:s,normalized:Zp(s)}}class Eu{static parse(l,i,u){try{return new Eu(l.value)._parse()}catch(c){if(c instanceof Ng){const o=i.prettyErrors===!1?c.message:c.message+`: + +`+l.value+` +`+" ".repeat(c.pos)+`^ +`;return u.push({message:o,range:[i.lineCounter.linePos(l.range[0]),i.lineCounter.linePos(l.range[0]+c.pos)]}),null}throw c}}constructor(l){this._input=l,this._pos=0,this._length=l.length}_peek(){return this._input[this._pos]||""}_next(){return this._pos=this._length}_isWhitespace(){return!this._eof()&&/\s/.test(this._peek())}_skipWhitespace(){for(;this._isWhitespace();)this._pos++}_readIdentifier(l){this._eof()&&this._throwError(`Unexpected end of input when expecting ${l}`);const i=this._pos;for(;!this._eof()&&/[a-zA-Z]/.test(this._peek());)this._pos++;return this._input.slice(i,this._pos)}_readString(){let l="",i=!1;for(;!this._eof();){const u=this._next();if(i)l+=u,i=!1;else if(u==="\\")i=!0;else{if(u==='"')return l;l+=u}}this._throwError("Unterminated string")}_throwError(l,i=0){throw new Ng(l,i||this._pos)}_readRegex(){let l="",i=!1,u=!1;for(;!this._eof();){const c=this._next();if(i)l+=c,i=!1;else if(c==="\\")i=!0,l+=c;else{if(c==="/"&&!u)return{pattern:l};c==="["?(u=!0,l+=c):c==="]"&&u?(l+=c,u=!1):l+=c}}this._throwError("Unterminated regex")}_readStringOrRegex(){const l=this._peek();return l==='"'?(this._next(),Zp(this._readString())):l==="/"?(this._next(),this._readRegex()):null}_readAttributes(l){let i=this._pos;for(;this._skipWhitespace(),this._peek()==="[";){this._next(),this._skipWhitespace(),i=this._pos;const u=this._readIdentifier("attribute");this._skipWhitespace();let c="";if(this._peek()==="=")for(this._next(),this._skipWhitespace(),i=this._pos;this._peek()!=="]"&&!this._isWhitespace()&&!this._eof();)c+=this._next();this._skipWhitespace(),this._peek()!=="]"&&this._throwError("Expected ]"),this._next(),this._applyAttribute(l,u,c||"true",i)}}_parse(){this._skipWhitespace();const l=this._readIdentifier("role");this._skipWhitespace();const i=this._readStringOrRegex()||"",u={kind:"role",role:l,name:i};return this._readAttributes(u),this._skipWhitespace(),this._eof()||this._throwError("Unexpected input"),u}_applyAttribute(l,i,u,c){if(i==="checked"){this._assert(u==="true"||u==="false"||u==="mixed",'Value of "checked" attribute must be a boolean or "mixed"',c),l.checked=u==="true"?!0:u==="false"?!1:"mixed";return}if(i==="disabled"){this._assert(u==="true"||u==="false",'Value of "disabled" attribute must be a boolean',c),l.disabled=u==="true";return}if(i==="expanded"){this._assert(u==="true"||u==="false",'Value of "expanded" attribute must be a boolean',c),l.expanded=u==="true";return}if(i==="active"){this._assert(u==="true"||u==="false",'Value of "active" attribute must be a boolean',c),l.active=u==="true";return}if(i==="level"){this._assert(!isNaN(Number(u)),'Value of "level" attribute must be a number',c),l.level=Number(u);return}if(i==="pressed"){this._assert(u==="true"||u==="false"||u==="mixed",'Value of "pressed" attribute must be a boolean or "mixed"',c),l.pressed=u==="true"?!0:u==="false"?!1:"mixed";return}if(i==="selected"){this._assert(u==="true"||u==="false",'Value of "selected" attribute must be a boolean',c),l.selected=u==="true";return}this._assert(!1,`Unsupported attribute [${i}]`,c)}_assert(l,i,u){l||this._throwError(i||"Assertion error",u)}}class Ng extends Error{constructor(l,i){super(l),this.pos=i}}const Gb=({className:s,style:l,open:i,isModal:u,minWidth:c,verticalOffset:o,requestClose:h,anchor:m,dataTestId:g,children:p})=>{const E=oe.useRef(null),[v,_]=oe.useState(0),[A]=Sf(E),[z,S]=Sf(m),T=m?Kb(A,z,o):void 0;return oe.useEffect(()=>{const x=Y=>{!E.current||!(Y.target instanceof Node)||E.current.contains(Y.target)||h==null||h()},j=Y=>{Y.key==="Escape"&&(h==null||h())};return i?(document.addEventListener("mousedown",x),document.addEventListener("keydown",j),()=>{document.removeEventListener("mousedown",x),document.removeEventListener("keydown",j)}):()=>{}},[i,h]),oe.useLayoutEffect(()=>S(),[i,S]),oe.useEffect(()=>{const x=()=>_(j=>j+1);return window.addEventListener("resize",x),()=>{window.removeEventListener("resize",x)}},[]),oe.useLayoutEffect(()=>{E.current&&(i?u?E.current.showModal():E.current.show():E.current.close())},[i,u]),Z.jsx("dialog",{ref:E,style:{position:"fixed",margin:T?0:void 0,zIndex:110,top:T==null?void 0:T.top,left:T==null?void 0:T.left,minWidth:c||0,...l},className:s,"data-testid":g,children:p})};function Kb(s,l,i=4,u=4){let c=Math.max(u,l.left);c+s.width>window.innerWidth-u&&(c=window.innerWidth-s.width-u);let o=Math.max(0,l.bottom)+i;return o+s.height>window.innerHeight-i&&(Math.max(0,l.top)>s.height+i?o=Math.max(0,l.top)-s.height-i:o=window.innerHeight-i-s.height),{left:c,top:o}}const Vb=({})=>{const[s,l]=oe.useState([]),[i,u]=oe.useState(!1),[c,o]=oe.useState(new Map),[h,m]=oe.useState("none"),[g,p]=oe.useState(),[E,v]=pu("recorderPropertiesTab","log"),[_,A]=oe.useState(),[z,S]=oe.useState(),[T,x]=oe.useState(!1),[j,Y]=z1(),[X,W]=pu("autoExpect",!1),K=oe.useRef(null),G=oe.useMemo(Qb,[]),[V,B]=oe.useState(""),he=oe.useRef(null),ne=oe.useMemo(()=>s.find(D=>D.id===g)??ev(),[s,g]);oe.useLayoutEffect(()=>{const ie={modeChanged:({mode:D})=>m(D),sourcesUpdated:({sources:D})=>{l(D),window.playwrightSourcesEchoForTest=D},pageNavigated:({url:D})=>{document.title=D?`Playwright Inspector - ${D}`:"Playwright Inspector"},pauseStateChanged:({paused:D})=>u(D),callLogsUpdated:({callLogs:D})=>{o(Q=>{const ee=new Map(Q);for(const de of D)de.reveal=!Q.has(de.id),ee.set(de.id,de);return ee})},sourceRevealRequested:({sourceId:D})=>p(D),elementPicked:({elementInfo:D,userGesture:Q})=>{const ee=ne.language;B(ep(ee,D.selector)),A(D.ariaSnapshot),S([]),Q&&E!=="locator"&&E!=="aria"&&v("locator"),h==="inspecting"&&E==="aria"||G.setMode({mode:h==="inspecting"?"standby":"recording"}).catch(()=>{})}};window.dispatch=D=>{ie[D.method].call(ie,D.params)}},[G,h,E,v,ne]),oe.useEffect(()=>{G.setAutoExpect({autoExpect:X})},[X,G]),oe.useLayoutEffect(()=>{var ie;(ie=he.current)==null||ie.scrollIntoView({block:"center",inline:"nearest"})},[he]),oe.useLayoutEffect(()=>{const ie=D=>{switch(D.key){case"F8":D.preventDefault(),i?G.resume():G.pause();break;case"F10":D.preventDefault(),i&&G.step();break}};return document.addEventListener("keydown",ie),()=>document.removeEventListener("keydown",ie)},[i,G]);const q=oe.useCallback(ie=>{(h==="none"||h==="inspecting")&&G.setMode({mode:"standby"}),B(ie),G.highlightRequested({selector:ie})},[h,G]),le=oe.useCallback(ie=>{(h==="none"||h==="inspecting")&&G.setMode({mode:"standby"});const{fragment:D,errors:Q}=$b(Hb,ie,{prettyErrors:!1}),ee=Q.map(de=>({message:de.message,line:de.range[1].line,column:de.range[1].col,type:"subtle-error"}));S(ee),A(ie),Q.length||G.highlightRequested({ariaTemplate:D})},[h,G]),ze=h==="recording"||h==="recording-inspecting"||h==="assertingText"||h==="assertingVisibility";return Z.jsxs("div",{className:"recorder",children:[Z.jsxs(xg,{children:[Z.jsx(Dt,{icon:ze?"stop-circle":"circle-large-filled",title:ze?"Stop Recording":"Start Recording",toggled:ze,onClick:()=>{G.setMode({mode:h==="none"||h==="standby"||h==="inspecting"?"recording":"standby"})},children:"Record"}),Z.jsx(hg,{}),Z.jsx(Dt,{icon:"inspect",title:"Pick locator",toggled:h==="inspecting"||h==="recording-inspecting",onClick:()=>{const ie={inspecting:"standby",none:"inspecting",standby:"inspecting",recording:"recording-inspecting","recording-inspecting":"recording",assertingText:"recording-inspecting",assertingVisibility:"recording-inspecting",assertingValue:"recording-inspecting",assertingSnapshot:"recording-inspecting"}[h];G.setMode({mode:ie}).catch(()=>{})}}),Z.jsx(Dt,{icon:"eye",title:"Assert visibility",toggled:h==="assertingVisibility",disabled:h==="none"||h==="standby"||h==="inspecting",onClick:()=>{G.setMode({mode:h==="assertingVisibility"?"recording":"assertingVisibility"})}}),Z.jsx(Dt,{icon:"whole-word",title:"Assert text",toggled:h==="assertingText",disabled:h==="none"||h==="standby"||h==="inspecting",onClick:()=>{G.setMode({mode:h==="assertingText"?"recording":"assertingText"})}}),Z.jsx(Dt,{icon:"symbol-constant",title:"Assert value",toggled:h==="assertingValue",disabled:h==="none"||h==="standby"||h==="inspecting",onClick:()=>{G.setMode({mode:h==="assertingValue"?"recording":"assertingValue"})}}),Z.jsx(Dt,{icon:"gist",title:"Assert snapshot",toggled:h==="assertingSnapshot",disabled:h==="none"||h==="standby"||h==="inspecting",onClick:()=>{G.setMode({mode:h==="assertingSnapshot"?"recording":"assertingSnapshot"})}}),Z.jsx(hg,{}),Z.jsx(Dt,{icon:"files",title:"Copy",disabled:!ne||!ne.text,onClick:()=>{eg(ne.text)}}),Z.jsx(Dt,{icon:"debug-continue",title:"Resume (F8)",ariaLabel:"Resume",disabled:!i,onClick:()=>{G.resume()}}),Z.jsx(Dt,{icon:"debug-pause",title:"Pause (F8)",ariaLabel:"Pause",disabled:i,onClick:()=>{G.pause()}}),Z.jsx(Dt,{icon:"debug-step-over",title:"Step over (F10)",ariaLabel:"Step over",disabled:!i,onClick:()=>{G.step()}}),Z.jsx("div",{style:{flex:"auto"}}),Z.jsx("div",{children:"Target:"}),Z.jsx(I1,{fileId:ne.id,sources:s,setFileId:ie=>{p(ie),G.fileChanged({fileId:ie})}}),Z.jsx(Dt,{icon:"clear-all",title:"Clear",disabled:!ne||!ne.text,onClick:()=>{G.clear()}}),Z.jsx(Dt,{ref:K,icon:"settings-gear",title:"Settings",onClick:()=>x(ie=>!ie)}),Z.jsxs(Gb,{style:{padding:"4px 8px"},open:T,verticalOffset:8,requestClose:()=>x(!1),anchor:K,dataTestId:"settings-dialog",children:[Z.jsxs("div",{className:"setting setting-theme",children:[Z.jsx("label",{htmlFor:"dark-mode-setting",children:"Theme:"}),Z.jsx("select",{id:"dark-mode-setting",value:j,onChange:ie=>Y(ie.target.value),children:_1.map(ie=>Z.jsx("option",{value:ie.value,children:ie.label},ie.value))})]},"dark-mode-setting"),Z.jsxs("div",{className:"setting",title:"Automatically generate assertions while recording",children:[Z.jsx("input",{type:"checkbox",id:"auto-expect-setting",checked:X,onChange:()=>{G.setAutoExpect({autoExpect:!X}),W(!X)}}),Z.jsx("label",{htmlFor:"auto-expect-setting",children:"Generate assertions"})]},"auto-expect-setting")]})]}),Z.jsx(J1,{sidebarSize:200,main:Z.jsx(ff,{text:ne.text,highlighter:ne.language,highlight:ne.highlight,revealLine:ne.revealLine,readOnly:!0,lineNumbers:!0}),sidebar:Z.jsx(W1,{rightToolbar:E==="locator"||E==="aria"?[Z.jsx(Dt,{icon:"files",title:"Copy",onClick:()=>eg((E==="locator"?V:_)||"")},1)]:[],tabs:[{id:"locator",title:"Locator",render:()=>Z.jsx(ff,{text:V,placeholder:"Type locator to inspect",highlighter:ne.language,focusOnChange:!0,onChange:q,wrapLines:!0})},{id:"log",title:"Log",render:()=>Z.jsx(Cv,{language:ne.language,log:Array.from(c.values())})},{id:"aria",title:"Aria",render:()=>Z.jsx(ff,{text:_||"",placeholder:"Type aria template to match",highlighter:"yaml",onChange:le,highlight:z,wrapLines:!0})}],selectedTab:E,setSelectedTab:v})})]})};function Qb(){return new Proxy({},{get:(s,l)=>{if(typeof l=="string")return i=>window.sendCommand({method:l,params:i})}})}(async()=>(N1(),R1.createRoot(document.querySelector("#root")).render(Z.jsx(Vb,{}))))();export{v1 as g}; diff --git a/skills/playwright-scraper-skill-1-2-0/node_modules/playwright-core/lib/vite/recorder/index.html b/skills/playwright-scraper-skill-1-2-0/node_modules/playwright-core/lib/vite/recorder/index.html new file mode 100644 index 0000000..ef6bc52 --- /dev/null +++ b/skills/playwright-scraper-skill-1-2-0/node_modules/playwright-core/lib/vite/recorder/index.html @@ -0,0 +1,29 @@ + + + + + + + + Playwright Inspector + + + + +
+ + diff --git a/skills/playwright-scraper-skill-1-2-0/node_modules/playwright-core/lib/vite/recorder/playwright-logo.svg b/skills/playwright-scraper-skill-1-2-0/node_modules/playwright-core/lib/vite/recorder/playwright-logo.svg new file mode 100644 index 0000000..7b3ca7d --- /dev/null +++ b/skills/playwright-scraper-skill-1-2-0/node_modules/playwright-core/lib/vite/recorder/playwright-logo.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/skills/playwright-scraper-skill-1-2-0/node_modules/playwright-core/lib/vite/traceViewer/assets/codeMirrorModule-a5XoALAZ.js b/skills/playwright-scraper-skill-1-2-0/node_modules/playwright-core/lib/vite/traceViewer/assets/codeMirrorModule-a5XoALAZ.js new file mode 100644 index 0000000..67c257f --- /dev/null +++ b/skills/playwright-scraper-skill-1-2-0/node_modules/playwright-core/lib/vite/traceViewer/assets/codeMirrorModule-a5XoALAZ.js @@ -0,0 +1,32 @@ +import{v as Ju}from"./defaultSettingsView-CJSZINFr.js";var vi={exports:{}},Zu=vi.exports,pa;function mt(){return pa||(pa=1,(function(ct,xt){(function(b,pe){ct.exports=pe()})(Zu,(function(){var b=navigator.userAgent,pe=navigator.platform,_=/gecko\/\d/i.test(b),te=/MSIE \d/.test(b),oe=/Trident\/(?:[7-9]|\d{2,})\..*rv:(\d+)/.exec(b),Q=/Edge\/(\d+)/.exec(b),k=te||oe||Q,I=k&&(te?document.documentMode||6:+(Q||oe)[1]),Y=!Q&&/WebKit\//.test(b),ne=Y&&/Qt\/\d+\.\d+/.test(b),S=!Q&&/Chrome\/(\d+)/.exec(b),R=S&&+S[1],A=/Opera\//.test(b),V=/Apple Computer/.test(navigator.vendor),ue=/Mac OS X 1\d\D([8-9]|\d\d)\D/.test(b),O=/PhantomJS/.test(b),w=V&&(/Mobile\/\w+/.test(b)||navigator.maxTouchPoints>2),M=/Android/.test(b),N=w||M||/webOS|BlackBerry|Opera Mini|Opera Mobi|IEMobile/i.test(b),z=w||/Mac/.test(pe),X=/\bCrOS\b/.test(b),q=/win/i.test(pe),p=A&&b.match(/Version\/(\d*\.\d*)/);p&&(p=Number(p[1])),p&&p>=15&&(A=!1,Y=!0);var W=z&&(ne||A&&(p==null||p<12.11)),J=_||k&&I>=9;function P(e){return new RegExp("(^|\\s)"+e+"(?:$|\\s)\\s*")}var $=function(e,t){var n=e.className,r=P(t).exec(n);if(r){var i=n.slice(r.index+r[0].length);e.className=n.slice(0,r.index)+(i?r[1]+i:"")}};function F(e){for(var t=e.childNodes.length;t>0;--t)e.removeChild(e.firstChild);return e}function G(e,t){return F(e).appendChild(t)}function c(e,t,n,r){var i=document.createElement(e);if(n&&(i.className=n),r&&(i.style.cssText=r),typeof t=="string")i.appendChild(document.createTextNode(t));else if(t)for(var o=0;o=t)return l+(t-o);l+=a-o,l+=n-l%n,o=a+1}}var Ce=function(){this.id=null,this.f=null,this.time=0,this.handler=xe(this.onTimeout,this)};Ce.prototype.onTimeout=function(e){e.id=0,e.time<=+new Date?e.f():setTimeout(e.handler,e.time-+new Date)},Ce.prototype.set=function(e,t){this.f=t;var n=+new Date+e;(!this.id||n=t)return r+Math.min(l,t-i);if(i+=o-r,i+=n-i%n,r=o+1,i>=t)return r}}var Ue=[""];function et(e){for(;Ue.length<=e;)Ue.push(we(Ue)+" ");return Ue[e]}function we(e){return e[e.length-1]}function Ie(e,t){for(var n=[],r=0;r"€"&&(e.toUpperCase()!=e.toLowerCase()||ze.test(e))}function De(e,t){return t?t.source.indexOf("\\w")>-1&&me(e)?!0:t.test(e):me(e)}function be(e){for(var t in e)if(e.hasOwnProperty(t)&&e[t])return!1;return!0}var Be=/[\u0300-\u036f\u0483-\u0489\u0591-\u05bd\u05bf\u05c1\u05c2\u05c4\u05c5\u05c7\u0610-\u061a\u064b-\u065e\u0670\u06d6-\u06dc\u06de-\u06e4\u06e7\u06e8\u06ea-\u06ed\u0711\u0730-\u074a\u07a6-\u07b0\u07eb-\u07f3\u0816-\u0819\u081b-\u0823\u0825-\u0827\u0829-\u082d\u0900-\u0902\u093c\u0941-\u0948\u094d\u0951-\u0955\u0962\u0963\u0981\u09bc\u09be\u09c1-\u09c4\u09cd\u09d7\u09e2\u09e3\u0a01\u0a02\u0a3c\u0a41\u0a42\u0a47\u0a48\u0a4b-\u0a4d\u0a51\u0a70\u0a71\u0a75\u0a81\u0a82\u0abc\u0ac1-\u0ac5\u0ac7\u0ac8\u0acd\u0ae2\u0ae3\u0b01\u0b3c\u0b3e\u0b3f\u0b41-\u0b44\u0b4d\u0b56\u0b57\u0b62\u0b63\u0b82\u0bbe\u0bc0\u0bcd\u0bd7\u0c3e-\u0c40\u0c46-\u0c48\u0c4a-\u0c4d\u0c55\u0c56\u0c62\u0c63\u0cbc\u0cbf\u0cc2\u0cc6\u0ccc\u0ccd\u0cd5\u0cd6\u0ce2\u0ce3\u0d3e\u0d41-\u0d44\u0d4d\u0d57\u0d62\u0d63\u0dca\u0dcf\u0dd2-\u0dd4\u0dd6\u0ddf\u0e31\u0e34-\u0e3a\u0e47-\u0e4e\u0eb1\u0eb4-\u0eb9\u0ebb\u0ebc\u0ec8-\u0ecd\u0f18\u0f19\u0f35\u0f37\u0f39\u0f71-\u0f7e\u0f80-\u0f84\u0f86\u0f87\u0f90-\u0f97\u0f99-\u0fbc\u0fc6\u102d-\u1030\u1032-\u1037\u1039\u103a\u103d\u103e\u1058\u1059\u105e-\u1060\u1071-\u1074\u1082\u1085\u1086\u108d\u109d\u135f\u1712-\u1714\u1732-\u1734\u1752\u1753\u1772\u1773\u17b7-\u17bd\u17c6\u17c9-\u17d3\u17dd\u180b-\u180d\u18a9\u1920-\u1922\u1927\u1928\u1932\u1939-\u193b\u1a17\u1a18\u1a56\u1a58-\u1a5e\u1a60\u1a62\u1a65-\u1a6c\u1a73-\u1a7c\u1a7f\u1b00-\u1b03\u1b34\u1b36-\u1b3a\u1b3c\u1b42\u1b6b-\u1b73\u1b80\u1b81\u1ba2-\u1ba5\u1ba8\u1ba9\u1c2c-\u1c33\u1c36\u1c37\u1cd0-\u1cd2\u1cd4-\u1ce0\u1ce2-\u1ce8\u1ced\u1dc0-\u1de6\u1dfd-\u1dff\u200c\u200d\u20d0-\u20f0\u2cef-\u2cf1\u2de0-\u2dff\u302a-\u302f\u3099\u309a\ua66f-\ua672\ua67c\ua67d\ua6f0\ua6f1\ua802\ua806\ua80b\ua825\ua826\ua8c4\ua8e0-\ua8f1\ua926-\ua92d\ua947-\ua951\ua980-\ua982\ua9b3\ua9b6-\ua9b9\ua9bc\uaa29-\uaa2e\uaa31\uaa32\uaa35\uaa36\uaa43\uaa4c\uaab0\uaab2-\uaab4\uaab7\uaab8\uaabe\uaabf\uaac1\uabe5\uabe8\uabed\udc00-\udfff\ufb1e\ufe00-\ufe0f\ufe20-\ufe26\uff9e\uff9f]/;function Ne(e){return e.charCodeAt(0)>=768&&Be.test(e)}function Mt(e,t,n){for(;(n<0?t>0:tn?-1:1;;){if(t==n)return t;var i=(t+n)/2,o=r<0?Math.ceil(i):Math.floor(i);if(o==t)return e(o)?t:n;e(o)?n=o:t=o+r}}function or(e,t,n,r){if(!e)return r(t,n,"ltr",0);for(var i=!1,o=0;ot||t==n&&l.to==t)&&(r(Math.max(l.from,t),Math.min(l.to,n),l.level==1?"rtl":"ltr",o),i=!0)}i||r(t,n,"ltr")}var br=null;function lr(e,t,n){var r;br=null;for(var i=0;it)return i;o.to==t&&(o.from!=o.to&&n=="before"?r=i:br=i),o.from==t&&(o.from!=o.to&&n!="before"?r=i:br=i)}return r??br}var mi=(function(){var e="bbbbbbbbbtstwsbbbbbbbbbbbbbbssstwNN%%%NNNNNN,N,N1111111111NNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNbbbbbbsbbbbbbbbbbbbbbbbbbbbbbbbbb,N%%%%NNNNLNNNNN%%11NLNNN1LNNNNNLLLLLLLLLLLLLLLLLLLLLLLNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLN",t="nnnnnnNNr%%r,rNNmmmmmmmmmmmrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrmmmmmmmmmmmmmmmmmmmmmnnnnnnnnnn%nnrrrmrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrmmmmmmmnNmmmmmmrrmmNmmmmrr1111111111";function n(u){return u<=247?e.charAt(u):1424<=u&&u<=1524?"R":1536<=u&&u<=1785?t.charAt(u-1536):1774<=u&&u<=2220?"r":8192<=u&&u<=8203?"w":u==8204?"b":"L"}var r=/[\u0590-\u05f4\u0600-\u06ff\u0700-\u08ac]/,i=/[stwN]/,o=/[LRr]/,l=/[Lb1n]/,a=/[1n]/;function s(u,h,x){this.level=u,this.from=h,this.to=x}return function(u,h){var x=h=="ltr"?"L":"R";if(u.length==0||h=="ltr"&&!r.test(u))return!1;for(var D=u.length,L=[],H=0;H-1&&(r[t]=i.slice(0,o).concat(i.slice(o+1)))}}}function Ye(e,t){var n=Zt(e,t);if(n.length)for(var r=Array.prototype.slice.call(arguments,2),i=0;i0}function Bt(e){e.prototype.on=function(t,n){Se(this,t,n)},e.prototype.off=function(t,n){ht(this,t,n)}}function pt(e){e.preventDefault?e.preventDefault():e.returnValue=!1}function Er(e){e.stopPropagation?e.stopPropagation():e.cancelBubble=!0}function kt(e){return e.defaultPrevented!=null?e.defaultPrevented:e.returnValue==!1}function ar(e){pt(e),Er(e)}function ln(e){return e.target||e.srcElement}function Rt(e){var t=e.which;return t==null&&(e.button&1?t=1:e.button&2?t=3:e.button&4&&(t=2)),z&&e.ctrlKey&&t==1&&(t=3),t}var xi=(function(){if(k&&I<9)return!1;var e=c("div");return"draggable"in e||"dragDrop"in e})(),Or;function Rn(e){if(Or==null){var t=c("span","​");G(e,c("span",[t,document.createTextNode("x")])),e.firstChild.offsetHeight!=0&&(Or=t.offsetWidth<=1&&t.offsetHeight>2&&!(k&&I<8))}var n=Or?c("span","​"):c("span"," ",null,"display: inline-block; width: 1px; margin-right: -1px");return n.setAttribute("cm-text",""),n}var an;function sr(e){if(an!=null)return an;var t=G(e,document.createTextNode("AخA")),n=C(t,0,1).getBoundingClientRect(),r=C(t,1,2).getBoundingClientRect();return F(e),!n||n.left==n.right?!1:an=r.right-n.right<3}var zt=` + +b`.split(/\n/).length!=3?function(e){for(var t=0,n=[],r=e.length;t<=r;){var i=e.indexOf(` +`,t);i==-1&&(i=e.length);var o=e.slice(t,e.charAt(i-1)=="\r"?i-1:i),l=o.indexOf("\r");l!=-1?(n.push(o.slice(0,l)),t+=l+1):(n.push(o),t=i+1)}return n}:function(e){return e.split(/\r\n?|\n/)},ur=window.getSelection?function(e){try{return e.selectionStart!=e.selectionEnd}catch{return!1}}:function(e){var t;try{t=e.ownerDocument.selection.createRange()}catch{}return!t||t.parentElement()!=e?!1:t.compareEndPoints("StartToEnd",t)!=0},Wn=(function(){var e=c("div");return"oncopy"in e?!0:(e.setAttribute("oncopy","return;"),typeof e.oncopy=="function")})(),Wt=null;function yi(e){if(Wt!=null)return Wt;var t=G(e,c("span","x")),n=t.getBoundingClientRect(),r=C(t,0,1).getBoundingClientRect();return Wt=Math.abs(n.left-r.left)>1}var Pr={},Ht={};function _t(e,t){arguments.length>2&&(t.dependencies=Array.prototype.slice.call(arguments,2)),Pr[e]=t}function kr(e,t){Ht[e]=t}function Ir(e){if(typeof e=="string"&&Ht.hasOwnProperty(e))e=Ht[e];else if(e&&typeof e.name=="string"&&Ht.hasOwnProperty(e.name)){var t=Ht[e.name];typeof t=="string"&&(t={name:t}),e=K(t,e),e.name=t.name}else{if(typeof e=="string"&&/^[\w\-]+\/[\w\-]+\+xml$/.test(e))return Ir("application/xml");if(typeof e=="string"&&/^[\w\-]+\/[\w\-]+\+json$/.test(e))return Ir("application/json")}return typeof e=="string"?{name:e}:e||{name:"null"}}function zr(e,t){t=Ir(t);var n=Pr[t.name];if(!n)return zr(e,"text/plain");var r=n(e,t);if(fr.hasOwnProperty(t.name)){var i=fr[t.name];for(var o in i)i.hasOwnProperty(o)&&(r.hasOwnProperty(o)&&(r["_"+o]=r[o]),r[o]=i[o])}if(r.name=t.name,t.helperType&&(r.helperType=t.helperType),t.modeProps)for(var l in t.modeProps)r[l]=t.modeProps[l];return r}var fr={};function Br(e,t){var n=fr.hasOwnProperty(e)?fr[e]:fr[e]={};Me(t,n)}function Gt(e,t){if(t===!0)return t;if(e.copyState)return e.copyState(t);var n={};for(var r in t){var i=t[r];i instanceof Array&&(i=i.concat([])),n[r]=i}return n}function sn(e,t){for(var n;e.innerMode&&(n=e.innerMode(t),!(!n||n.mode==e));)t=n.state,e=n.mode;return n||{mode:e,state:t}}function Rr(e,t,n){return e.startState?e.startState(t,n):!0}var Je=function(e,t,n){this.pos=this.start=0,this.string=e,this.tabSize=t||8,this.lastColumnPos=this.lastColumnValue=0,this.lineStart=0,this.lineOracle=n};Je.prototype.eol=function(){return this.pos>=this.string.length},Je.prototype.sol=function(){return this.pos==this.lineStart},Je.prototype.peek=function(){return this.string.charAt(this.pos)||void 0},Je.prototype.next=function(){if(this.post},Je.prototype.eatSpace=function(){for(var e=this.pos;/[\s\u00a0]/.test(this.string.charAt(this.pos));)++this.pos;return this.pos>e},Je.prototype.skipToEnd=function(){this.pos=this.string.length},Je.prototype.skipTo=function(e){var t=this.string.indexOf(e,this.pos);if(t>-1)return this.pos=t,!0},Je.prototype.backUp=function(e){this.pos-=e},Je.prototype.column=function(){return this.lastColumnPos0?null:(o&&t!==!1&&(this.pos+=o[0].length),o)}},Je.prototype.current=function(){return this.string.slice(this.start,this.pos)},Je.prototype.hideFirstChars=function(e,t){this.lineStart+=e;try{return t()}finally{this.lineStart-=e}},Je.prototype.lookAhead=function(e){var t=this.lineOracle;return t&&t.lookAhead(e)},Je.prototype.baseToken=function(){var e=this.lineOracle;return e&&e.baseToken(this.pos)};function ye(e,t){if(t-=e.first,t<0||t>=e.size)throw new Error("There is no line "+(t+e.first)+" in the document.");for(var n=e;!n.lines;)for(var r=0;;++r){var i=n.children[r],o=i.chunkSize();if(t=e.first&&tn?B(n,ye(e,n).text.length):Za(t,ye(e,t.line).text.length)}function Za(e,t){var n=e.ch;return n==null||n>t?B(e.line,t):n<0?B(e.line,0):e}function vo(e,t){for(var n=[],r=0;rthis.maxLookAhead&&(this.maxLookAhead=e),t},Xt.prototype.baseToken=function(e){if(!this.baseTokens)return null;for(;this.baseTokens[this.baseTokenPos]<=e;)this.baseTokenPos+=2;var t=this.baseTokens[this.baseTokenPos+1];return{type:t&&t.replace(/( |^)overlay .*/,""),size:this.baseTokens[this.baseTokenPos]-e}},Xt.prototype.nextLine=function(){this.line++,this.maxLookAhead>0&&this.maxLookAhead--},Xt.fromSaved=function(e,t,n){return t instanceof Hn?new Xt(e,Gt(e.mode,t.state),n,t.lookAhead):new Xt(e,Gt(e.mode,t),n)},Xt.prototype.save=function(e){var t=e!==!1?Gt(this.doc.mode,this.state):this.state;return this.maxLookAhead>0?new Hn(t,this.maxLookAhead):t};function mo(e,t,n,r){var i=[e.state.modeGen],o={};So(e,t.text,e.doc.mode,n,function(u,h){return i.push(u,h)},o,r);for(var l=n.state,a=function(u){n.baseTokens=i;var h=e.state.overlays[u],x=1,D=0;n.state=!0,So(e,t.text,h.mode,n,function(L,H){for(var Z=x;DL&&i.splice(x,1,L,i[x+1],ie),x+=2,D=Math.min(L,ie)}if(H)if(h.opaque)i.splice(Z,x-Z,L,"overlay "+H),x=Z+2;else for(;Ze.options.maxHighlightLength&&Gt(e.doc.mode,r.state),o=mo(e,t,r);i&&(r.state=i),t.stateAfter=r.save(!i),t.styles=o.styles,o.classes?t.styleClasses=o.classes:t.styleClasses&&(t.styleClasses=null),n===e.doc.highlightFrontier&&(e.doc.modeFrontier=Math.max(e.doc.modeFrontier,++e.doc.highlightFrontier))}return t.styles}function fn(e,t,n){var r=e.doc,i=e.display;if(!r.mode.startState)return new Xt(r,!0,t);var o=Va(e,t,n),l=o>r.first&&ye(r,o-1).stateAfter,a=l?Xt.fromSaved(r,l,o):new Xt(r,Rr(r.mode),o);return r.iter(o,t,function(s){bi(e,s.text,a);var u=a.line;s.stateAfter=u==t-1||u%5==0||u>=i.viewFrom&&ut.start)return o}throw new Error("Mode "+e.name+" failed to advance stream.")}var bo=function(e,t,n){this.start=e.start,this.end=e.pos,this.string=e.current(),this.type=t||null,this.state=n};function ko(e,t,n,r){var i=e.doc,o=i.mode,l;t=Ae(i,t);var a=ye(i,t.line),s=fn(e,t.line,n),u=new Je(a.text,e.options.tabSize,s),h;for(r&&(h=[]);(r||u.pose.options.maxHighlightLength?(a=!1,l&&bi(e,t,r,h.pos),h.pos=t.length,x=null):x=wo(ki(n,h,r.state,D),o),D){var L=D[0].name;L&&(x="m-"+(x?L+" "+x:L))}if(!a||u!=x){for(;sl;--a){if(a<=o.first)return o.first;var s=ye(o,a-1),u=s.stateAfter;if(u&&(!n||a+(u instanceof Hn?u.lookAhead:0)<=o.modeFrontier))return a;var h=Fe(s.text,null,e.options.tabSize);(i==null||r>h)&&(i=a-1,r=h)}return i}function $a(e,t){if(e.modeFrontier=Math.min(e.modeFrontier,t),!(e.highlightFrontiern;r--){var i=ye(e,r).stateAfter;if(i&&(!(i instanceof Hn)||r+i.lookAhead=t:o.to>t);(r||(r=[])).push(new _n(l,o.from,s?null:o.to))}}return r}function os(e,t,n){var r;if(e)for(var i=0;i=t:o.to>t);if(a||o.from==t&&l.type=="bookmark"&&(!n||o.marker.insertLeft)){var s=o.from==null||(l.inclusiveLeft?o.from<=t:o.from0&&a)for(var ge=0;ge0)){var h=[s,1],x=ce(u.from,a.from),D=ce(u.to,a.to);(x<0||!l.inclusiveLeft&&!x)&&h.push({from:u.from,to:a.from}),(D>0||!l.inclusiveRight&&!D)&&h.push({from:a.to,to:u.to}),i.splice.apply(i,h),s+=h.length-3}}return i}function Co(e){var t=e.markedSpans;if(t){for(var n=0;nt)&&(!r||Si(r,o.marker)<0)&&(r=o.marker)}return r}function Ao(e,t,n,r,i){var o=ye(e,t),l=$t&&o.markedSpans;if(l)for(var a=0;a=0&&x<=0||h<=0&&x>=0)&&(h<=0&&(s.marker.inclusiveRight&&i.inclusiveLeft?ce(u.to,n)>=0:ce(u.to,n)>0)||h>=0&&(s.marker.inclusiveRight&&i.inclusiveLeft?ce(u.from,r)<=0:ce(u.from,r)<0)))return!0}}}function qt(e){for(var t;t=Fo(e);)e=t.find(-1,!0).line;return e}function ss(e){for(var t;t=Kn(e);)e=t.find(1,!0).line;return e}function us(e){for(var t,n;t=Kn(e);)e=t.find(1,!0).line,(n||(n=[])).push(e);return n}function Li(e,t){var n=ye(e,t),r=qt(n);return n==r?t:f(r)}function No(e,t){if(t>e.lastLine())return t;var n=ye(e,t),r;if(!cr(e,n))return t;for(;r=Kn(n);)n=r.find(1,!0).line;return f(n)+1}function cr(e,t){var n=$t&&t.markedSpans;if(n){for(var r=void 0,i=0;it.maxLineLength&&(t.maxLineLength=i,t.maxLine=r)})}var Hr=function(e,t,n){this.text=e,Do(this,t),this.height=n?n(this):1};Hr.prototype.lineNo=function(){return f(this)},Bt(Hr);function fs(e,t,n,r){e.text=t,e.stateAfter&&(e.stateAfter=null),e.styles&&(e.styles=null),e.order!=null&&(e.order=null),Co(e),Do(e,n);var i=r?r(e):1;i!=e.height&&Et(e,i)}function cs(e){e.parent=null,Co(e)}var ds={},hs={};function Eo(e,t){if(!e||/^\s*$/.test(e))return null;var n=t.addModeClass?hs:ds;return n[e]||(n[e]=e.replace(/\S+/g,"cm-$&"))}function Oo(e,t){var n=T("span",null,null,Y?"padding-right: .1px":null),r={pre:T("pre",[n],"CodeMirror-line"),content:n,col:0,pos:0,cm:e,trailingSpace:!1,splitSpaces:e.getOption("lineWrapping")};t.measure={};for(var i=0;i<=(t.rest?t.rest.length:0);i++){var o=i?t.rest[i-1]:t.line,l=void 0;r.pos=0,r.addToken=gs,sr(e.display.measure)&&(l=Re(o,e.doc.direction))&&(r.addToken=ms(r.addToken,l)),r.map=[];var a=t!=e.display.externalMeasured&&f(o);xs(o,r,xo(e,o,a)),o.styleClasses&&(o.styleClasses.bgClass&&(r.bgClass=de(o.styleClasses.bgClass,r.bgClass||"")),o.styleClasses.textClass&&(r.textClass=de(o.styleClasses.textClass,r.textClass||""))),r.map.length==0&&r.map.push(0,0,r.content.appendChild(Rn(e.display.measure))),i==0?(t.measure.map=r.map,t.measure.cache={}):((t.measure.maps||(t.measure.maps=[])).push(r.map),(t.measure.caches||(t.measure.caches=[])).push({}))}if(Y){var s=r.content.lastChild;(/\bcm-tab\b/.test(s.className)||s.querySelector&&s.querySelector(".cm-tab"))&&(r.content.className="cm-tab-wrap-hack")}return Ye(e,"renderLine",e,t.line,r.pre),r.pre.className&&(r.textClass=de(r.pre.className,r.textClass||"")),r}function ps(e){var t=c("span","•","cm-invalidchar");return t.title="\\u"+e.charCodeAt(0).toString(16),t.setAttribute("aria-label",t.title),t}function gs(e,t,n,r,i,o,l){if(t){var a=e.splitSpaces?vs(t,e.trailingSpace):t,s=e.cm.state.specialChars,u=!1,h;if(!s.test(t))e.col+=t.length,h=document.createTextNode(a),e.map.push(e.pos,e.pos+t.length,h),k&&I<9&&(u=!0),e.pos+=t.length;else{h=document.createDocumentFragment();for(var x=0;;){s.lastIndex=x;var D=s.exec(t),L=D?D.index-x:t.length-x;if(L){var H=document.createTextNode(a.slice(x,x+L));k&&I<9?h.appendChild(c("span",[H])):h.appendChild(H),e.map.push(e.pos,e.pos+L,H),e.col+=L,e.pos+=L}if(!D)break;x+=L+1;var Z=void 0;if(D[0]==" "){var ie=e.cm.options.tabSize,ae=ie-e.col%ie;Z=h.appendChild(c("span",et(ae),"cm-tab")),Z.setAttribute("role","presentation"),Z.setAttribute("cm-text"," "),e.col+=ae}else D[0]=="\r"||D[0]==` +`?(Z=h.appendChild(c("span",D[0]=="\r"?"␍":"␤","cm-invalidchar")),Z.setAttribute("cm-text",D[0]),e.col+=1):(Z=e.cm.options.specialCharPlaceholder(D[0]),Z.setAttribute("cm-text",D[0]),k&&I<9?h.appendChild(c("span",[Z])):h.appendChild(Z),e.col+=1);e.map.push(e.pos,e.pos+1,Z),e.pos++}}if(e.trailingSpace=a.charCodeAt(t.length-1)==32,n||r||i||u||o||l){var he=n||"";r&&(he+=r),i&&(he+=i);var se=c("span",[h],he,o);if(l)for(var ge in l)l.hasOwnProperty(ge)&&ge!="style"&&ge!="class"&&se.setAttribute(ge,l[ge]);return e.content.appendChild(se)}e.content.appendChild(h)}}function vs(e,t){if(e.length>1&&!/ /.test(e))return e;for(var n=t,r="",i=0;iu&&x.from<=u));D++);if(x.to>=h)return e(n,r,i,o,l,a,s);e(n,r.slice(0,x.to-u),i,o,null,a,s),o=null,r=r.slice(x.to-u),u=x.to}}}function Po(e,t,n,r){var i=!r&&n.widgetNode;i&&e.map.push(e.pos,e.pos+t,i),!r&&e.cm.display.input.needsContentAttribute&&(i||(i=e.content.appendChild(document.createElement("span"))),i.setAttribute("cm-marker",n.id)),i&&(e.cm.display.input.setUneditable(i),e.content.appendChild(i)),e.pos+=t,e.trailingSpace=!1}function xs(e,t,n){var r=e.markedSpans,i=e.text,o=0;if(!r){for(var l=1;ls||Ee.collapsed&&ke.to==s&&ke.from==s)){if(ke.to!=null&&ke.to!=s&&L>ke.to&&(L=ke.to,Z=""),Ee.className&&(H+=" "+Ee.className),Ee.css&&(D=(D?D+";":"")+Ee.css),Ee.startStyle&&ke.from==s&&(ie+=" "+Ee.startStyle),Ee.endStyle&&ke.to==L&&(ge||(ge=[])).push(Ee.endStyle,ke.to),Ee.title&&((he||(he={})).title=Ee.title),Ee.attributes)for(var Ke in Ee.attributes)(he||(he={}))[Ke]=Ee.attributes[Ke];Ee.collapsed&&(!ae||Si(ae.marker,Ee)<0)&&(ae=ke)}else ke.from>s&&L>ke.from&&(L=ke.from)}if(ge)for(var st=0;st=a)break;for(var Nt=Math.min(a,L);;){if(h){var Tt=s+h.length;if(!ae){var tt=Tt>Nt?h.slice(0,Nt-s):h;t.addToken(t,tt,x?x+H:H,ie,s+tt.length==L?Z:"",D,he)}if(Tt>=Nt){h=h.slice(Nt-s),s=Nt;break}s=Tt,ie=""}h=i.slice(o,o=n[u++]),x=Eo(n[u++],t.cm.options)}}}function Io(e,t,n){this.line=t,this.rest=us(t),this.size=this.rest?f(we(this.rest))-n+1:1,this.node=this.text=null,this.hidden=cr(e,t)}function Gn(e,t,n){for(var r=[],i,o=t;o2&&o.push((s.bottom+u.top)/2-n.top)}}o.push(n.bottom-n.top)}}function qo(e,t,n){if(e.line==t)return{map:e.measure.map,cache:e.measure.cache};if(e.rest){for(var r=0;rn)return{map:e.measure.maps[i],cache:e.measure.caches[i],before:!0}}}function Fs(e,t){t=qt(t);var n=f(t),r=e.display.externalMeasured=new Io(e.doc,t,n);r.lineN=n;var i=r.built=Oo(e,r);return r.text=i.pre,G(e.display.lineMeasure,i.pre),r}function jo(e,t,n,r){return Qt(e,qr(e,t),n,r)}function Ai(e,t){if(t>=e.display.viewFrom&&t=n.lineN&&tt)&&(o=s-a,i=o-1,t>=s&&(l="right")),i!=null){if(r=e[u+2],a==s&&n==(r.insertLeft?"left":"right")&&(l=n),n=="left"&&i==0)for(;u&&e[u-2]==e[u-3]&&e[u-1].insertLeft;)r=e[(u-=3)+2],l="left";if(n=="right"&&i==s-a)for(;u=0&&(n=e[i]).left==n.right;i--);return n}function Ns(e,t,n,r){var i=Uo(t.map,n,r),o=i.node,l=i.start,a=i.end,s=i.collapse,u;if(o.nodeType==3){for(var h=0;h<4;h++){for(;l&&Ne(t.line.text.charAt(i.coverStart+l));)--l;for(;i.coverStart+a0&&(s=r="right");var x;e.options.lineWrapping&&(x=o.getClientRects()).length>1?u=x[r=="right"?x.length-1:0]:u=o.getBoundingClientRect()}if(k&&I<9&&!l&&(!u||!u.left&&!u.right)){var D=o.parentNode.getClientRects()[0];D?u={left:D.left,right:D.left+Kr(e.display),top:D.top,bottom:D.bottom}:u=Ko}for(var L=u.top-t.rect.top,H=u.bottom-t.rect.top,Z=(L+H)/2,ie=t.view.measure.heights,ae=0;ae=r.text.length?(s=r.text.length,u="before"):s<=0&&(s=0,u="after"),!a)return l(u=="before"?s-1:s,u=="before");function h(H,Z,ie){var ae=a[Z],he=ae.level==1;return l(ie?H-1:H,he!=ie)}var x=lr(a,s,u),D=br,L=h(s,x,u=="before");return D!=null&&(L.other=h(s,D,u!="before")),L}function Zo(e,t){var n=0;t=Ae(e.doc,t),e.options.lineWrapping||(n=Kr(e.display)*t.ch);var r=ye(e.doc,t.line),i=er(r)+Xn(e.display);return{left:n,right:n,top:i,bottom:i+r.height}}function Ei(e,t,n,r,i){var o=B(e,t,n);return o.xRel=i,r&&(o.outside=r),o}function Oi(e,t,n){var r=e.doc;if(n+=e.display.viewOffset,n<0)return Ei(r.first,0,null,-1,-1);var i=m(r,n),o=r.first+r.size-1;if(i>o)return Ei(r.first+r.size-1,ye(r,o).text.length,null,1,1);t<0&&(t=0);for(var l=ye(r,i);;){var a=Os(e,l,i,t,n),s=as(l,a.ch+(a.xRel>0||a.outside>0?1:0));if(!s)return a;var u=s.find(1);if(u.line==i)return u;l=ye(r,i=u.line)}}function Vo(e,t,n,r){r-=Ni(t);var i=t.text.length,o=Pt(function(l){return Qt(e,n,l-1).bottom<=r},i,0);return i=Pt(function(l){return Qt(e,n,l).top>r},o,i),{begin:o,end:i}}function $o(e,t,n,r){n||(n=qr(e,t));var i=Yn(e,t,Qt(e,n,r),"line").top;return Vo(e,t,n,i)}function Pi(e,t,n,r){return e.bottom<=n?!1:e.top>n?!0:(r?e.left:e.right)>t}function Os(e,t,n,r,i){i-=er(t);var o=qr(e,t),l=Ni(t),a=0,s=t.text.length,u=!0,h=Re(t,e.doc.direction);if(h){var x=(e.options.lineWrapping?Is:Ps)(e,t,n,o,h,r,i);u=x.level!=1,a=u?x.from:x.to-1,s=u?x.to:x.from-1}var D=null,L=null,H=Pt(function(Le){var ke=Qt(e,o,Le);return ke.top+=l,ke.bottom+=l,Pi(ke,r,i,!1)?(ke.top<=i&&ke.left<=r&&(D=Le,L=ke),!0):!1},a,s),Z,ie,ae=!1;if(L){var he=r-L.left=ge.bottom?1:0}return H=Mt(t.text,H,1),Ei(n,H,ie,ae,r-Z)}function Ps(e,t,n,r,i,o,l){var a=Pt(function(x){var D=i[x],L=D.level!=1;return Pi(jt(e,B(n,L?D.to:D.from,L?"before":"after"),"line",t,r),o,l,!0)},0,i.length-1),s=i[a];if(a>0){var u=s.level!=1,h=jt(e,B(n,u?s.from:s.to,u?"after":"before"),"line",t,r);Pi(h,o,l,!0)&&h.top>l&&(s=i[a-1])}return s}function Is(e,t,n,r,i,o,l){var a=Vo(e,t,r,l),s=a.begin,u=a.end;/\s/.test(t.text.charAt(u-1))&&u--;for(var h=null,x=null,D=0;D=u||L.to<=s)){var H=L.level!=1,Z=Qt(e,r,H?Math.min(u,L.to)-1:Math.max(s,L.from)).right,ie=Zie)&&(h=L,x=ie)}}return h||(h=i[i.length-1]),h.fromu&&(h={from:h.from,to:u,level:h.level}),h}var Sr;function jr(e){if(e.cachedTextHeight!=null)return e.cachedTextHeight;if(Sr==null){Sr=c("pre",null,"CodeMirror-line-like");for(var t=0;t<49;++t)Sr.appendChild(document.createTextNode("x")),Sr.appendChild(c("br"));Sr.appendChild(document.createTextNode("x"))}G(e.measure,Sr);var n=Sr.offsetHeight/50;return n>3&&(e.cachedTextHeight=n),F(e.measure),n||1}function Kr(e){if(e.cachedCharWidth!=null)return e.cachedCharWidth;var t=c("span","xxxxxxxxxx"),n=c("pre",[t],"CodeMirror-line-like");G(e.measure,n);var r=t.getBoundingClientRect(),i=(r.right-r.left)/10;return i>2&&(e.cachedCharWidth=i),i||10}function Ii(e){for(var t=e.display,n={},r={},i=t.gutters.clientLeft,o=t.gutters.firstChild,l=0;o;o=o.nextSibling,++l){var a=e.display.gutterSpecs[l].className;n[a]=o.offsetLeft+o.clientLeft+i,r[a]=o.clientWidth}return{fixedPos:zi(t),gutterTotalWidth:t.gutters.offsetWidth,gutterLeft:n,gutterWidth:r,wrapperWidth:t.wrapper.clientWidth}}function zi(e){return e.scroller.getBoundingClientRect().left-e.sizer.getBoundingClientRect().left}function el(e){var t=jr(e.display),n=e.options.lineWrapping,r=n&&Math.max(5,e.display.scroller.clientWidth/Kr(e.display)-3);return function(i){if(cr(e.doc,i))return 0;var o=0;if(i.widgets)for(var l=0;l0&&(u=ye(e.doc,s.line).text).length==s.ch){var h=Fe(u,u.length,e.options.tabSize)-u.length;s=B(s.line,Math.max(0,Math.round((o-_o(e.display).left)/Kr(e.display))-h))}return s}function Tr(e,t){if(t>=e.display.viewTo||(t-=e.display.viewFrom,t<0))return null;for(var n=e.display.view,r=0;rt)&&(i.updateLineNumbers=t),e.curOp.viewChanged=!0,t>=i.viewTo)$t&&Li(e.doc,t)i.viewFrom?hr(e):(i.viewFrom+=r,i.viewTo+=r);else if(t<=i.viewFrom&&n>=i.viewTo)hr(e);else if(t<=i.viewFrom){var o=Jn(e,n,n+r,1);o?(i.view=i.view.slice(o.index),i.viewFrom=o.lineN,i.viewTo+=r):hr(e)}else if(n>=i.viewTo){var l=Jn(e,t,t,-1);l?(i.view=i.view.slice(0,l.index),i.viewTo=l.lineN):hr(e)}else{var a=Jn(e,t,t,-1),s=Jn(e,n,n+r,1);a&&s?(i.view=i.view.slice(0,a.index).concat(Gn(e,a.lineN,s.lineN)).concat(i.view.slice(s.index)),i.viewTo+=r):hr(e)}var u=i.externalMeasured;u&&(n=i.lineN&&t=r.viewTo)){var o=r.view[Tr(e,t)];if(o.node!=null){var l=o.changes||(o.changes=[]);ve(l,n)==-1&&l.push(n)}}}function hr(e){e.display.viewFrom=e.display.viewTo=e.doc.first,e.display.view=[],e.display.viewOffset=0}function Jn(e,t,n,r){var i=Tr(e,t),o,l=e.display.view;if(!$t||n==e.doc.first+e.doc.size)return{index:i,lineN:n};for(var a=e.display.viewFrom,s=0;s0){if(i==l.length-1)return null;o=a+l[i].size-t,i++}else o=a-t;t+=o,n+=o}for(;Li(e.doc,n)!=n;){if(i==(r<0?0:l.length-1))return null;n+=r*l[i-(r<0?1:0)].size,i+=r}return{index:i,lineN:n}}function zs(e,t,n){var r=e.display,i=r.view;i.length==0||t>=r.viewTo||n<=r.viewFrom?(r.view=Gn(e,t,n),r.viewFrom=t):(r.viewFrom>t?r.view=Gn(e,t,r.viewFrom).concat(r.view):r.viewFromn&&(r.view=r.view.slice(0,Tr(e,n)))),r.viewTo=n}function tl(e){for(var t=e.display.view,n=0,r=0;r=e.display.viewTo||s.to().line0?l:e.defaultCharWidth())+"px"}if(r.other){var a=n.appendChild(c("div"," ","CodeMirror-cursor CodeMirror-secondarycursor"));a.style.display="",a.style.left=r.other.left+"px",a.style.top=r.other.top+"px",a.style.height=(r.other.bottom-r.other.top)*.85+"px"}}function Zn(e,t){return e.top-t.top||e.left-t.left}function Bs(e,t,n){var r=e.display,i=e.doc,o=document.createDocumentFragment(),l=_o(e.display),a=l.left,s=Math.max(r.sizerWidth,wr(e)-r.sizer.offsetLeft)-l.right,u=i.direction=="ltr";function h(se,ge,Le,ke){ge<0&&(ge=0),ge=Math.round(ge),ke=Math.round(ke),o.appendChild(c("div",null,"CodeMirror-selected","position: absolute; left: "+se+`px; + top: `+ge+"px; width: "+(Le??s-se)+`px; + height: `+(ke-ge)+"px"))}function x(se,ge,Le){var ke=ye(i,se),Ee=ke.text.length,Ke,st;function Xe(tt,Ct){return Qn(e,B(se,tt),"div",ke,Ct)}function Nt(tt,Ct,ft){var nt=$o(e,ke,null,tt),rt=Ct=="ltr"==(ft=="after")?"left":"right",Ze=ft=="after"?nt.begin:nt.end-(/\s/.test(ke.text.charAt(nt.end-1))?2:1);return Xe(Ze,rt)[rt]}var Tt=Re(ke,i.direction);return or(Tt,ge||0,Le??Ee,function(tt,Ct,ft,nt){var rt=ft=="ltr",Ze=Xe(tt,rt?"left":"right"),Dt=Xe(Ct-1,rt?"right":"left"),nn=ge==null&&tt==0,yr=Le==null&&Ct==Ee,vt=nt==0,Jt=!Tt||nt==Tt.length-1;if(Dt.top-Ze.top<=3){var ut=(u?nn:yr)&&vt,co=(u?yr:nn)&&Jt,ir=ut?a:(rt?Ze:Dt).left,Ar=co?s:(rt?Dt:Ze).right;h(ir,Ze.top,Ar-ir,Ze.bottom)}else{var Nr,bt,on,ho;rt?(Nr=u&&nn&&vt?a:Ze.left,bt=u?s:Nt(tt,ft,"before"),on=u?a:Nt(Ct,ft,"after"),ho=u&&yr&&Jt?s:Dt.right):(Nr=u?Nt(tt,ft,"before"):a,bt=!u&&nn&&vt?s:Ze.right,on=!u&&yr&&Jt?a:Dt.left,ho=u?Nt(Ct,ft,"after"):s),h(Nr,Ze.top,bt-Nr,Ze.bottom),Ze.bottom0?t.blinker=setInterval(function(){e.hasFocus()||Ur(e),t.cursorDiv.style.visibility=(n=!n)?"":"hidden"},e.options.cursorBlinkRate):e.options.cursorBlinkRate<0&&(t.cursorDiv.style.visibility="hidden")}}function nl(e){e.hasFocus()||(e.display.input.focus(),e.state.focused||_i(e))}function Hi(e){e.state.delayingBlurEvent=!0,setTimeout(function(){e.state.delayingBlurEvent&&(e.state.delayingBlurEvent=!1,e.state.focused&&Ur(e))},100)}function _i(e,t){e.state.delayingBlurEvent&&!e.state.draggingText&&(e.state.delayingBlurEvent=!1),e.options.readOnly!="nocursor"&&(e.state.focused||(Ye(e,"focus",e,t),e.state.focused=!0,j(e.display.wrapper,"CodeMirror-focused"),!e.curOp&&e.display.selForContextMenu!=e.doc.sel&&(e.display.input.reset(),Y&&setTimeout(function(){return e.display.input.reset(!0)},20)),e.display.input.receivedFocus()),Wi(e))}function Ur(e,t){e.state.delayingBlurEvent||(e.state.focused&&(Ye(e,"blur",e,t),e.state.focused=!1,$(e.display.wrapper,"CodeMirror-focused")),clearInterval(e.display.blinker),setTimeout(function(){e.state.focused||(e.display.shift=!1)},150))}function Vn(e){for(var t=e.display,n=t.lineDiv.offsetTop,r=Math.max(0,t.scroller.getBoundingClientRect().top),i=t.lineDiv.getBoundingClientRect().top,o=0,l=0;l.005||L<-.005)&&(ie.display.sizerWidth){var Z=Math.ceil(h/Kr(e.display));Z>e.display.maxLineLength&&(e.display.maxLineLength=Z,e.display.maxLine=a.line,e.display.maxLineChanged=!0)}}}Math.abs(o)>2&&(t.scroller.scrollTop+=o)}function il(e){if(e.widgets)for(var t=0;t=l&&(o=m(t,er(ye(t,s))-e.wrapper.clientHeight),l=s)}return{from:o,to:Math.max(l,o+1)}}function Rs(e,t){if(!Qe(e,"scrollCursorIntoView")){var n=e.display,r=n.sizer.getBoundingClientRect(),i=null,o=n.wrapper.ownerDocument;if(t.top+r.top<0?i=!0:t.bottom+r.top>(o.defaultView.innerHeight||o.documentElement.clientHeight)&&(i=!1),i!=null&&!O){var l=c("div","​",null,`position: absolute; + top: `+(t.top-n.viewOffset-Xn(e.display))+`px; + height: `+(t.bottom-t.top+Yt(e)+n.barHeight)+`px; + left: `+t.left+"px; width: "+Math.max(2,t.right-t.left)+"px;");e.display.lineSpace.appendChild(l),l.scrollIntoView(i),e.display.lineSpace.removeChild(l)}}}function Ws(e,t,n,r){r==null&&(r=0);var i;!e.options.lineWrapping&&t==n&&(n=t.sticky=="before"?B(t.line,t.ch+1,"before"):t,t=t.ch?B(t.line,t.sticky=="before"?t.ch-1:t.ch,"after"):t);for(var o=0;o<5;o++){var l=!1,a=jt(e,t),s=!n||n==t?a:jt(e,n);i={left:Math.min(a.left,s.left),top:Math.min(a.top,s.top)-r,right:Math.max(a.left,s.left),bottom:Math.max(a.bottom,s.bottom)+r};var u=qi(e,i),h=e.doc.scrollTop,x=e.doc.scrollLeft;if(u.scrollTop!=null&&(xn(e,u.scrollTop),Math.abs(e.doc.scrollTop-h)>1&&(l=!0)),u.scrollLeft!=null&&(Cr(e,u.scrollLeft),Math.abs(e.doc.scrollLeft-x)>1&&(l=!0)),!l)break}return i}function Hs(e,t){var n=qi(e,t);n.scrollTop!=null&&xn(e,n.scrollTop),n.scrollLeft!=null&&Cr(e,n.scrollLeft)}function qi(e,t){var n=e.display,r=jr(e.display);t.top<0&&(t.top=0);var i=e.curOp&&e.curOp.scrollTop!=null?e.curOp.scrollTop:n.scroller.scrollTop,o=Fi(e),l={};t.bottom-t.top>o&&(t.bottom=t.top+o);var a=e.doc.height+Mi(n),s=t.topa-r;if(t.topi+o){var h=Math.min(t.top,(u?a:t.bottom)-o);h!=i&&(l.scrollTop=h)}var x=e.options.fixedGutter?0:n.gutters.offsetWidth,D=e.curOp&&e.curOp.scrollLeft!=null?e.curOp.scrollLeft:n.scroller.scrollLeft-x,L=wr(e)-n.gutters.offsetWidth,H=t.right-t.left>L;return H&&(t.right=t.left+L),t.left<10?l.scrollLeft=0:t.leftL+D-3&&(l.scrollLeft=t.right+(H?0:10)-L),l}function ji(e,t){t!=null&&(ei(e),e.curOp.scrollTop=(e.curOp.scrollTop==null?e.doc.scrollTop:e.curOp.scrollTop)+t)}function Gr(e){ei(e);var t=e.getCursor();e.curOp.scrollToPos={from:t,to:t,margin:e.options.cursorScrollMargin}}function mn(e,t,n){(t!=null||n!=null)&&ei(e),t!=null&&(e.curOp.scrollLeft=t),n!=null&&(e.curOp.scrollTop=n)}function _s(e,t){ei(e),e.curOp.scrollToPos=t}function ei(e){var t=e.curOp.scrollToPos;if(t){e.curOp.scrollToPos=null;var n=Zo(e,t.from),r=Zo(e,t.to);ol(e,n,r,t.margin)}}function ol(e,t,n,r){var i=qi(e,{left:Math.min(t.left,n.left),top:Math.min(t.top,n.top)-r,right:Math.max(t.right,n.right),bottom:Math.max(t.bottom,n.bottom)+r});mn(e,i.scrollLeft,i.scrollTop)}function xn(e,t){Math.abs(e.doc.scrollTop-t)<2||(_||Ui(e,{top:t}),ll(e,t,!0),_&&Ui(e),kn(e,100))}function ll(e,t,n){t=Math.max(0,Math.min(e.display.scroller.scrollHeight-e.display.scroller.clientHeight,t)),!(e.display.scroller.scrollTop==t&&!n)&&(e.doc.scrollTop=t,e.display.scrollbars.setScrollTop(t),e.display.scroller.scrollTop!=t&&(e.display.scroller.scrollTop=t))}function Cr(e,t,n,r){t=Math.max(0,Math.min(t,e.display.scroller.scrollWidth-e.display.scroller.clientWidth)),!((n?t==e.doc.scrollLeft:Math.abs(e.doc.scrollLeft-t)<2)&&!r)&&(e.doc.scrollLeft=t,cl(e),e.display.scroller.scrollLeft!=t&&(e.display.scroller.scrollLeft=t),e.display.scrollbars.setScrollLeft(t))}function yn(e){var t=e.display,n=t.gutters.offsetWidth,r=Math.round(e.doc.height+Mi(e.display));return{clientHeight:t.scroller.clientHeight,viewHeight:t.wrapper.clientHeight,scrollWidth:t.scroller.scrollWidth,clientWidth:t.scroller.clientWidth,viewWidth:t.wrapper.clientWidth,barLeft:e.options.fixedGutter?n:0,docHeight:r,scrollHeight:r+Yt(e)+t.barHeight,nativeBarWidth:t.nativeBarWidth,gutterWidth:n}}var Dr=function(e,t,n){this.cm=n;var r=this.vert=c("div",[c("div",null,null,"min-width: 1px")],"CodeMirror-vscrollbar"),i=this.horiz=c("div",[c("div",null,null,"height: 100%; min-height: 1px")],"CodeMirror-hscrollbar");r.tabIndex=i.tabIndex=-1,e(r),e(i),Se(r,"scroll",function(){r.clientHeight&&t(r.scrollTop,"vertical")}),Se(i,"scroll",function(){i.clientWidth&&t(i.scrollLeft,"horizontal")}),this.checkedZeroWidth=!1,k&&I<8&&(this.horiz.style.minHeight=this.vert.style.minWidth="18px")};Dr.prototype.update=function(e){var t=e.scrollWidth>e.clientWidth+1,n=e.scrollHeight>e.clientHeight+1,r=e.nativeBarWidth;if(n){this.vert.style.display="block",this.vert.style.bottom=t?r+"px":"0";var i=e.viewHeight-(t?r:0);this.vert.firstChild.style.height=Math.max(0,e.scrollHeight-e.clientHeight+i)+"px"}else this.vert.scrollTop=0,this.vert.style.display="",this.vert.firstChild.style.height="0";if(t){this.horiz.style.display="block",this.horiz.style.right=n?r+"px":"0",this.horiz.style.left=e.barLeft+"px";var o=e.viewWidth-e.barLeft-(n?r:0);this.horiz.firstChild.style.width=Math.max(0,e.scrollWidth-e.clientWidth+o)+"px"}else this.horiz.style.display="",this.horiz.firstChild.style.width="0";return!this.checkedZeroWidth&&e.clientHeight>0&&(r==0&&this.zeroWidthHack(),this.checkedZeroWidth=!0),{right:n?r:0,bottom:t?r:0}},Dr.prototype.setScrollLeft=function(e){this.horiz.scrollLeft!=e&&(this.horiz.scrollLeft=e),this.disableHoriz&&this.enableZeroWidthBar(this.horiz,this.disableHoriz,"horiz")},Dr.prototype.setScrollTop=function(e){this.vert.scrollTop!=e&&(this.vert.scrollTop=e),this.disableVert&&this.enableZeroWidthBar(this.vert,this.disableVert,"vert")},Dr.prototype.zeroWidthHack=function(){var e=z&&!ue?"12px":"18px";this.horiz.style.height=this.vert.style.width=e,this.horiz.style.visibility=this.vert.style.visibility="hidden",this.disableHoriz=new Ce,this.disableVert=new Ce},Dr.prototype.enableZeroWidthBar=function(e,t,n){e.style.visibility="";function r(){var i=e.getBoundingClientRect(),o=n=="vert"?document.elementFromPoint(i.right-1,(i.top+i.bottom)/2):document.elementFromPoint((i.right+i.left)/2,i.bottom-1);o!=e?e.style.visibility="hidden":t.set(1e3,r)}t.set(1e3,r)},Dr.prototype.clear=function(){var e=this.horiz.parentNode;e.removeChild(this.horiz),e.removeChild(this.vert)};var bn=function(){};bn.prototype.update=function(){return{bottom:0,right:0}},bn.prototype.setScrollLeft=function(){},bn.prototype.setScrollTop=function(){},bn.prototype.clear=function(){};function Xr(e,t){t||(t=yn(e));var n=e.display.barWidth,r=e.display.barHeight;al(e,t);for(var i=0;i<4&&n!=e.display.barWidth||r!=e.display.barHeight;i++)n!=e.display.barWidth&&e.options.lineWrapping&&Vn(e),al(e,yn(e)),n=e.display.barWidth,r=e.display.barHeight}function al(e,t){var n=e.display,r=n.scrollbars.update(t);n.sizer.style.paddingRight=(n.barWidth=r.right)+"px",n.sizer.style.paddingBottom=(n.barHeight=r.bottom)+"px",n.heightForcer.style.borderBottom=r.bottom+"px solid transparent",r.right&&r.bottom?(n.scrollbarFiller.style.display="block",n.scrollbarFiller.style.height=r.bottom+"px",n.scrollbarFiller.style.width=r.right+"px"):n.scrollbarFiller.style.display="",r.bottom&&e.options.coverGutterNextToScrollbar&&e.options.fixedGutter?(n.gutterFiller.style.display="block",n.gutterFiller.style.height=r.bottom+"px",n.gutterFiller.style.width=t.gutterWidth+"px"):n.gutterFiller.style.display=""}var sl={native:Dr,null:bn};function ul(e){e.display.scrollbars&&(e.display.scrollbars.clear(),e.display.scrollbars.addClass&&$(e.display.wrapper,e.display.scrollbars.addClass)),e.display.scrollbars=new sl[e.options.scrollbarStyle](function(t){e.display.wrapper.insertBefore(t,e.display.scrollbarFiller),Se(t,"mousedown",function(){e.state.focused&&setTimeout(function(){return e.display.input.focus()},0)}),t.setAttribute("cm-not-content","true")},function(t,n){n=="horizontal"?Cr(e,t):xn(e,t)},e),e.display.scrollbars.addClass&&j(e.display.wrapper,e.display.scrollbars.addClass)}var qs=0;function Mr(e){e.curOp={cm:e,viewChanged:!1,startHeight:e.doc.height,forceUpdate:!1,updateInput:0,typing:!1,changeObjs:null,cursorActivityHandlers:null,cursorActivityCalled:0,selectionChanged:!1,updateMaxLine:!1,scrollLeft:null,scrollTop:null,scrollToPos:null,focus:!1,id:++qs,markArrays:null},ys(e.curOp)}function Fr(e){var t=e.curOp;t&&ks(t,function(n){for(var r=0;r=n.viewTo)||n.maxLineChanged&&t.options.lineWrapping,e.update=e.mustUpdate&&new ti(t,e.mustUpdate&&{top:e.scrollTop,ensure:e.scrollToPos},e.forceUpdate)}function Us(e){e.updatedDisplay=e.mustUpdate&&Ki(e.cm,e.update)}function Gs(e){var t=e.cm,n=t.display;e.updatedDisplay&&Vn(t),e.barMeasure=yn(t),n.maxLineChanged&&!t.options.lineWrapping&&(e.adjustWidthTo=jo(t,n.maxLine,n.maxLine.text.length).left+3,t.display.sizerWidth=e.adjustWidthTo,e.barMeasure.scrollWidth=Math.max(n.scroller.clientWidth,n.sizer.offsetLeft+e.adjustWidthTo+Yt(t)+t.display.barWidth),e.maxScrollLeft=Math.max(0,n.sizer.offsetLeft+e.adjustWidthTo-wr(t))),(e.updatedDisplay||e.selectionChanged)&&(e.preparedSelection=n.input.prepareSelection())}function Xs(e){var t=e.cm;e.adjustWidthTo!=null&&(t.display.sizer.style.minWidth=e.adjustWidthTo+"px",e.maxScrollLeft=e.display.viewTo)){var n=+new Date+e.options.workTime,r=fn(e,t.highlightFrontier),i=[];t.iter(r.line,Math.min(t.first+t.size,e.display.viewTo+500),function(o){if(r.line>=e.display.viewFrom){var l=o.styles,a=o.text.length>e.options.maxHighlightLength?Gt(t.mode,r.state):null,s=mo(e,o,r,!0);a&&(r.state=a),o.styles=s.styles;var u=o.styleClasses,h=s.classes;h?o.styleClasses=h:u&&(o.styleClasses=null);for(var x=!l||l.length!=o.styles.length||u!=h&&(!u||!h||u.bgClass!=h.bgClass||u.textClass!=h.textClass),D=0;!x&&Dn)return kn(e,e.options.workDelay),!0}),t.highlightFrontier=r.line,t.modeFrontier=Math.max(t.modeFrontier,r.line),i.length&&At(e,function(){for(var o=0;o=n.viewFrom&&t.visible.to<=n.viewTo&&(n.updateLineNumbers==null||n.updateLineNumbers>=n.viewTo)&&n.renderedView==n.view&&tl(e)==0)return!1;dl(e)&&(hr(e),t.dims=Ii(e));var i=r.first+r.size,o=Math.max(t.visible.from-e.options.viewportMargin,r.first),l=Math.min(i,t.visible.to+e.options.viewportMargin);n.viewFroml&&n.viewTo-l<20&&(l=Math.min(i,n.viewTo)),$t&&(o=Li(e.doc,o),l=No(e.doc,l));var a=o!=n.viewFrom||l!=n.viewTo||n.lastWrapHeight!=t.wrapperHeight||n.lastWrapWidth!=t.wrapperWidth;zs(e,o,l),n.viewOffset=er(ye(e.doc,n.viewFrom)),e.display.mover.style.top=n.viewOffset+"px";var s=tl(e);if(!a&&s==0&&!t.force&&n.renderedView==n.view&&(n.updateLineNumbers==null||n.updateLineNumbers>=n.viewTo))return!1;var u=Zs(e);return s>4&&(n.lineDiv.style.display="none"),$s(e,n.updateLineNumbers,t.dims),s>4&&(n.lineDiv.style.display=""),n.renderedView=n.view,Vs(u),F(n.cursorDiv),F(n.selectionDiv),n.gutters.style.height=n.sizer.style.minHeight=0,a&&(n.lastWrapHeight=t.wrapperHeight,n.lastWrapWidth=t.wrapperWidth,kn(e,400)),n.updateLineNumbers=null,!0}function fl(e,t){for(var n=t.viewport,r=!0;;r=!1){if(!r||!e.options.lineWrapping||t.oldDisplayWidth==wr(e)){if(n&&n.top!=null&&(n={top:Math.min(e.doc.height+Mi(e.display)-Fi(e),n.top)}),t.visible=$n(e.display,e.doc,n),t.visible.from>=e.display.viewFrom&&t.visible.to<=e.display.viewTo)break}else r&&(t.visible=$n(e.display,e.doc,n));if(!Ki(e,t))break;Vn(e);var i=yn(e);vn(e),Xr(e,i),Xi(e,i),t.force=!1}t.signal(e,"update",e),(e.display.viewFrom!=e.display.reportedViewFrom||e.display.viewTo!=e.display.reportedViewTo)&&(t.signal(e,"viewportChange",e,e.display.viewFrom,e.display.viewTo),e.display.reportedViewFrom=e.display.viewFrom,e.display.reportedViewTo=e.display.viewTo)}function Ui(e,t){var n=new ti(e,t);if(Ki(e,n)){Vn(e),fl(e,n);var r=yn(e);vn(e),Xr(e,r),Xi(e,r),n.finish()}}function $s(e,t,n){var r=e.display,i=e.options.lineNumbers,o=r.lineDiv,l=o.firstChild;function a(H){var Z=H.nextSibling;return Y&&z&&e.display.currentWheelTarget==H?H.style.display="none":H.parentNode.removeChild(H),Z}for(var s=r.view,u=r.viewFrom,h=0;h-1&&(L=!1),zo(e,x,u,n)),L&&(F(x.lineNumber),x.lineNumber.appendChild(document.createTextNode(re(e.options,u)))),l=x.node.nextSibling}u+=x.size}for(;l;)l=a(l)}function Gi(e){var t=e.gutters.offsetWidth;e.sizer.style.marginLeft=t+"px",ot(e,"gutterChanged",e)}function Xi(e,t){e.display.sizer.style.minHeight=t.docHeight+"px",e.display.heightForcer.style.top=t.docHeight+"px",e.display.gutters.style.height=t.docHeight+e.display.barHeight+Yt(e)+"px"}function cl(e){var t=e.display,n=t.view;if(!(!t.alignWidgets&&(!t.gutters.firstChild||!e.options.fixedGutter))){for(var r=zi(t)-t.scroller.scrollLeft+e.doc.scrollLeft,i=t.gutters.offsetWidth,o=r+"px",l=0;l=105&&(i.wrapper.style.clipPath="inset(0px)"),i.wrapper.setAttribute("translate","no"),k&&I<8&&(i.gutters.style.zIndex=-1,i.scroller.style.paddingRight=0),!Y&&!(_&&N)&&(i.scroller.draggable=!0),e&&(e.appendChild?e.appendChild(i.wrapper):e(i.wrapper)),i.viewFrom=i.viewTo=t.first,i.reportedViewFrom=i.reportedViewTo=t.first,i.view=[],i.renderedView=null,i.externalMeasured=null,i.viewOffset=0,i.lastWrapHeight=i.lastWrapWidth=0,i.updateLineNumbers=null,i.nativeBarWidth=i.barHeight=i.barWidth=0,i.scrollbarsClipped=!1,i.lineNumWidth=i.lineNumInnerWidth=i.lineNumChars=null,i.alignWidgets=!1,i.cachedCharWidth=i.cachedTextHeight=i.cachedPaddingH=null,i.maxLine=null,i.maxLineLength=0,i.maxLineChanged=!1,i.wheelDX=i.wheelDY=i.wheelStartX=i.wheelStartY=null,i.shift=!1,i.selForContextMenu=null,i.activeTouch=null,i.gutterSpecs=Yi(r.gutters,r.lineNumbers),hl(i),n.init(i)}var ri=0,rr=null;k?rr=-.53:_?rr=15:S?rr=-.7:V&&(rr=-1/3);function pl(e){var t=e.wheelDeltaX,n=e.wheelDeltaY;return t==null&&e.detail&&e.axis==e.HORIZONTAL_AXIS&&(t=e.detail),n==null&&e.detail&&e.axis==e.VERTICAL_AXIS?n=e.detail:n==null&&(n=e.wheelDelta),{x:t,y:n}}function tu(e){var t=pl(e);return t.x*=rr,t.y*=rr,t}function gl(e,t){S&&R==102&&(e.display.chromeScrollHack==null?e.display.sizer.style.pointerEvents="none":clearTimeout(e.display.chromeScrollHack),e.display.chromeScrollHack=setTimeout(function(){e.display.chromeScrollHack=null,e.display.sizer.style.pointerEvents=""},100));var n=pl(t),r=n.x,i=n.y,o=rr;t.deltaMode===0&&(r=t.deltaX,i=t.deltaY,o=1);var l=e.display,a=l.scroller,s=a.scrollWidth>a.clientWidth,u=a.scrollHeight>a.clientHeight;if(r&&s||i&&u){if(i&&z&&Y){e:for(var h=t.target,x=l.view;h!=a;h=h.parentNode)for(var D=0;D=0&&ce(e,r.to())<=0)return n}return-1};var He=function(e,t){this.anchor=e,this.head=t};He.prototype.from=function(){return Wr(this.anchor,this.head)},He.prototype.to=function(){return wt(this.anchor,this.head)},He.prototype.empty=function(){return this.head.line==this.anchor.line&&this.head.ch==this.anchor.ch};function Kt(e,t,n){var r=e&&e.options.selectionsMayTouch,i=t[n];t.sort(function(D,L){return ce(D.from(),L.from())}),n=ve(t,i);for(var o=1;o0:s>=0){var u=Wr(a.from(),l.from()),h=wt(a.to(),l.to()),x=a.empty()?l.from()==l.head:a.from()==a.head;o<=n&&--n,t.splice(--o,2,new He(x?h:u,x?u:h))}}return new Ot(t,n)}function pr(e,t){return new Ot([new He(e,t||e)],0)}function gr(e){return e.text?B(e.from.line+e.text.length-1,we(e.text).length+(e.text.length==1?e.from.ch:0)):e.to}function vl(e,t){if(ce(e,t.from)<0)return e;if(ce(e,t.to)<=0)return gr(t);var n=e.line+t.text.length-(t.to.line-t.from.line)-1,r=e.ch;return e.line==t.to.line&&(r+=gr(t).ch-t.to.ch),B(n,r)}function Qi(e,t){for(var n=[],r=0;r1&&e.remove(a.line+1,H-1),e.insert(a.line+1,ae)}ot(e,"change",e,t)}function vr(e,t,n){function r(i,o,l){if(i.linked)for(var a=0;a1&&!e.done[e.done.length-2].ranges)return e.done.pop(),we(e.done)}function wl(e,t,n,r){var i=e.history;i.undone.length=0;var o=+new Date,l,a;if((i.lastOp==r||i.lastOrigin==t.origin&&t.origin&&(t.origin.charAt(0)=="+"&&i.lastModTime>o-(e.cm?e.cm.options.historyEventDelay:500)||t.origin.charAt(0)=="*"))&&(l=iu(i,i.lastOp==r)))a=we(l.changes),ce(t.from,t.to)==0&&ce(t.from,a.to)==0?a.to=gr(t):l.changes.push(Vi(e,t));else{var s=we(i.done);for((!s||!s.ranges)&&ii(e.sel,i.done),l={changes:[Vi(e,t)],generation:i.generation},i.done.push(l);i.done.length>i.undoDepth;)i.done.shift(),i.done[0].ranges||i.done.shift()}i.done.push(n),i.generation=++i.maxGeneration,i.lastModTime=i.lastSelTime=o,i.lastOp=i.lastSelOp=r,i.lastOrigin=i.lastSelOrigin=t.origin,a||Ye(e,"historyAdded")}function ou(e,t,n,r){var i=t.charAt(0);return i=="*"||i=="+"&&n.ranges.length==r.ranges.length&&n.somethingSelected()==r.somethingSelected()&&new Date-e.history.lastSelTime<=(e.cm?e.cm.options.historyEventDelay:500)}function lu(e,t,n,r){var i=e.history,o=r&&r.origin;n==i.lastSelOp||o&&i.lastSelOrigin==o&&(i.lastModTime==i.lastSelTime&&i.lastOrigin==o||ou(e,o,we(i.done),t))?i.done[i.done.length-1]=t:ii(t,i.done),i.lastSelTime=+new Date,i.lastSelOrigin=o,i.lastSelOp=n,r&&r.clearRedo!==!1&&kl(i.undone)}function ii(e,t){var n=we(t);n&&n.ranges&&n.equals(e)||t.push(e)}function Sl(e,t,n,r){var i=t["spans_"+e.id],o=0;e.iter(Math.max(e.first,n),Math.min(e.first+e.size,r),function(l){l.markedSpans&&((i||(i=t["spans_"+e.id]={}))[o]=l.markedSpans),++o})}function au(e){if(!e)return null;for(var t,n=0;n-1&&(we(a)[x]=u[x],delete u[x])}}return r}function $i(e,t,n,r){if(r){var i=e.anchor;if(n){var o=ce(t,i)<0;o!=ce(n,i)<0?(i=t,t=n):o!=ce(t,n)<0&&(t=n)}return new He(i,t)}else return new He(n||t,t)}function oi(e,t,n,r,i){i==null&&(i=e.cm&&(e.cm.display.shift||e.extend)),gt(e,new Ot([$i(e.sel.primary(),t,n,i)],0),r)}function Tl(e,t,n){for(var r=[],i=e.cm&&(e.cm.display.shift||e.extend),o=0;o=t.ch:a.to>t.ch))){if(i&&(Ye(s,"beforeCursorEnter"),s.explicitlyCleared))if(o.markedSpans){--l;continue}else break;if(!s.atomic)continue;if(n){var x=s.find(r<0?1:-1),D=void 0;if((r<0?h:u)&&(x=Nl(e,x,-r,x&&x.line==t.line?o:null)),x&&x.line==t.line&&(D=ce(x,n))&&(r<0?D<0:D>0))return Qr(e,x,t,r,i)}var L=s.find(r<0?-1:1);return(r<0?u:h)&&(L=Nl(e,L,r,L.line==t.line?o:null)),L?Qr(e,L,t,r,i):null}}return t}function ai(e,t,n,r,i){var o=r||1,l=Qr(e,t,n,o,i)||!i&&Qr(e,t,n,o,!0)||Qr(e,t,n,-o,i)||!i&&Qr(e,t,n,-o,!0);return l||(e.cantEdit=!0,B(e.first,0))}function Nl(e,t,n,r){return n<0&&t.ch==0?t.line>e.first?Ae(e,B(t.line-1)):null:n>0&&t.ch==(r||ye(e,t.line)).text.length?t.line=0;--i)Pl(e,{from:r[i].from,to:r[i].to,text:i?[""]:t.text,origin:t.origin});else Pl(e,t)}}function Pl(e,t){if(!(t.text.length==1&&t.text[0]==""&&ce(t.from,t.to)==0)){var n=Qi(e,t);wl(e,t,n,e.cm?e.cm.curOp.id:NaN),Ln(e,t,n,wi(e,t));var r=[];vr(e,function(i,o){!o&&ve(r,i.history)==-1&&(Rl(i.history,t),r.push(i.history)),Ln(i,t,null,wi(i,t))})}}function si(e,t,n){var r=e.cm&&e.cm.state.suppressEdits;if(!(r&&!n)){for(var i=e.history,o,l=e.sel,a=t=="undo"?i.done:i.undone,s=t=="undo"?i.undone:i.done,u=0;u=0;--L){var H=D(L);if(H)return H.v}}}}function Il(e,t){if(t!=0&&(e.first+=t,e.sel=new Ot(Ie(e.sel.ranges,function(i){return new He(B(i.anchor.line+t,i.anchor.ch),B(i.head.line+t,i.head.ch))}),e.sel.primIndex),e.cm)){St(e.cm,e.first,e.first-t,t);for(var n=e.cm.display,r=n.viewFrom;re.lastLine())){if(t.from.lineo&&(t={from:t.from,to:B(o,ye(e,o).text.length),text:[t.text[0]],origin:t.origin}),t.removed=Vt(e,t.from,t.to),n||(n=Qi(e,t)),e.cm?fu(e.cm,t,r):Zi(e,t,r),li(e,n,Ve),e.cantEdit&&ai(e,B(e.firstLine(),0))&&(e.cantEdit=!1)}}function fu(e,t,n){var r=e.doc,i=e.display,o=t.from,l=t.to,a=!1,s=o.line;e.options.lineWrapping||(s=f(qt(ye(r,o.line))),r.iter(s,l.line+1,function(L){if(L==i.maxLine)return a=!0,!0})),r.sel.contains(t.from,t.to)>-1&&It(e),Zi(r,t,n,el(e)),e.options.lineWrapping||(r.iter(s,o.line+t.text.length,function(L){var H=Un(L);H>i.maxLineLength&&(i.maxLine=L,i.maxLineLength=H,i.maxLineChanged=!0,a=!1)}),a&&(e.curOp.updateMaxLine=!0)),$a(r,o.line),kn(e,400);var u=t.text.length-(l.line-o.line)-1;t.full?St(e):o.line==l.line&&t.text.length==1&&!xl(e.doc,t)?dr(e,o.line,"text"):St(e,o.line,l.line+1,u);var h=Ft(e,"changes"),x=Ft(e,"change");if(x||h){var D={from:o,to:l,text:t.text,removed:t.removed,origin:t.origin};x&&ot(e,"change",e,D),h&&(e.curOp.changeObjs||(e.curOp.changeObjs=[])).push(D)}e.display.selForContextMenu=null}function Zr(e,t,n,r,i){var o;r||(r=n),ce(r,n)<0&&(o=[r,n],n=o[0],r=o[1]),typeof t=="string"&&(t=e.splitLines(t)),Jr(e,{from:n,to:r,text:t,origin:i})}function zl(e,t,n,r){n1||!(this.children[0]instanceof Cn))){var a=[];this.collapse(a),this.children=[new Cn(a)],this.children[0].parent=this}},collapse:function(e){for(var t=0;t50){for(var l=i.lines.length%25+25,a=l;a10);e.parent.maybeSpill()}},iterN:function(e,t,n){for(var r=0;re.display.maxLineLength&&(e.display.maxLine=u,e.display.maxLineLength=h,e.display.maxLineChanged=!0)}r!=null&&e&&this.collapsed&&St(e,r,i+1),this.lines.length=0,this.explicitlyCleared=!0,this.atomic&&this.doc.cantEdit&&(this.doc.cantEdit=!1,e&&Fl(e.doc)),e&&ot(e,"markerCleared",e,this,r,i),t&&Fr(e),this.parent&&this.parent.clear()}},mr.prototype.find=function(e,t){e==null&&this.type=="bookmark"&&(e=1);for(var n,r,i=0;i0||l==0&&o.clearWhenEmpty!==!1)return o;if(o.replacedWith&&(o.collapsed=!0,o.widgetNode=T("span",[o.replacedWith],"CodeMirror-widget"),r.handleMouseEvents||o.widgetNode.setAttribute("cm-ignore-events","true"),r.insertLeft&&(o.widgetNode.insertLeft=!0)),o.collapsed){if(Ao(e,t.line,t,n,o)||t.line!=n.line&&Ao(e,n.line,t,n,o))throw new Error("Inserting collapsed marker partially overlapping an existing one");ts()}o.addToHistory&&wl(e,{from:t,to:n,origin:"markText"},e.sel,NaN);var a=t.line,s=e.cm,u;if(e.iter(a,n.line+1,function(x){s&&o.collapsed&&!s.options.lineWrapping&&qt(x)==s.display.maxLine&&(u=!0),o.collapsed&&a!=t.line&&Et(x,0),ns(x,new _n(o,a==t.line?t.ch:null,a==n.line?n.ch:null),e.cm&&e.cm.curOp),++a}),o.collapsed&&e.iter(t.line,n.line+1,function(x){cr(e,x)&&Et(x,0)}),o.clearOnEnter&&Se(o,"beforeCursorEnter",function(){return o.clear()}),o.readOnly&&(es(),(e.history.done.length||e.history.undone.length)&&e.clearHistory()),o.collapsed&&(o.id=++Hl,o.atomic=!0),s){if(u&&(s.curOp.updateMaxLine=!0),o.collapsed)St(s,t.line,n.line+1);else if(o.className||o.startStyle||o.endStyle||o.css||o.attributes||o.title)for(var h=t.line;h<=n.line;h++)dr(s,h,"text");o.atomic&&Fl(s.doc),ot(s,"markerAdded",s,o)}return o}var Fn=function(e,t){this.markers=e,this.primary=t;for(var n=0;n=0;s--)Jr(this,r[s]);a?Dl(this,a):this.cm&&Gr(this.cm)}),undo:at(function(){si(this,"undo")}),redo:at(function(){si(this,"redo")}),undoSelection:at(function(){si(this,"undo",!0)}),redoSelection:at(function(){si(this,"redo",!0)}),setExtending:function(e){this.extend=e},getExtending:function(){return this.extend},historySize:function(){for(var e=this.history,t=0,n=0,r=0;r=e.ch)&&t.push(i.marker.parent||i.marker)}return t},findMarks:function(e,t,n){e=Ae(this,e),t=Ae(this,t);var r=[],i=e.line;return this.iter(e.line,t.line+1,function(o){var l=o.markedSpans;if(l)for(var a=0;a=s.to||s.from==null&&i!=e.line||s.from!=null&&i==t.line&&s.from>=t.ch)&&(!n||n(s.marker))&&r.push(s.marker.parent||s.marker)}++i}),r},getAllMarks:function(){var e=[];return this.iter(function(t){var n=t.markedSpans;if(n)for(var r=0;re)return t=e,!0;e-=o,++n}),Ae(this,B(n,t))},indexFromPos:function(e){e=Ae(this,e);var t=e.ch;if(e.linet&&(t=e.from),e.to!=null&&e.to-1){t.state.draggingText(e),setTimeout(function(){return t.display.input.focus()},20);return}try{var h=e.dataTransfer.getData("Text");if(h){var x;if(t.state.draggingText&&!t.state.draggingText.copy&&(x=t.listSelections()),li(t.doc,pr(n,n)),x)for(var D=0;D=0;a--)Zr(e.doc,"",r[a].from,r[a].to,"+delete");Gr(e)})}function to(e,t,n){var r=Mt(e.text,t+n,n);return r<0||r>e.text.length?null:r}function ro(e,t,n){var r=to(e,t.ch,n);return r==null?null:new B(t.line,r,n<0?"after":"before")}function no(e,t,n,r,i){if(e){t.doc.direction=="rtl"&&(i=-i);var o=Re(n,t.doc.direction);if(o){var l=i<0?we(o):o[0],a=i<0==(l.level==1),s=a?"after":"before",u;if(l.level>0||t.doc.direction=="rtl"){var h=qr(t,n);u=i<0?n.text.length-1:0;var x=Qt(t,h,u).top;u=Pt(function(D){return Qt(t,h,D).top==x},i<0==(l.level==1)?l.from:l.to-1,u),s=="before"&&(u=to(n,u,1))}else u=i<0?l.to:l.from;return new B(r,u,s)}}return new B(r,i<0?n.text.length:0,i<0?"before":"after")}function Lu(e,t,n,r){var i=Re(t,e.doc.direction);if(!i)return ro(t,n,r);n.ch>=t.text.length?(n.ch=t.text.length,n.sticky="before"):n.ch<=0&&(n.ch=0,n.sticky="after");var o=lr(i,n.ch,n.sticky),l=i[o];if(e.doc.direction=="ltr"&&l.level%2==0&&(r>0?l.to>n.ch:l.from=l.from&&D>=h.begin)){var L=x?"before":"after";return new B(n.line,D,L)}}var H=function(ae,he,se){for(var ge=function(Ke,st){return st?new B(n.line,a(Ke,1),"before"):new B(n.line,Ke,"after")};ae>=0&&ae0==(Le.level!=1),Ee=ke?se.begin:a(se.end,-1);if(Le.from<=Ee&&Ee0?h.end:a(h.begin,-1);return ie!=null&&!(r>0&&ie==t.text.length)&&(Z=H(r>0?0:i.length-1,r,u(ie)),Z)?Z:null}var En={selectAll:El,singleSelection:function(e){return e.setSelection(e.getCursor("anchor"),e.getCursor("head"),Ve)},killLine:function(e){return en(e,function(t){if(t.empty()){var n=ye(e.doc,t.head.line).text.length;return t.head.ch==n&&t.head.line0)i=new B(i.line,i.ch+1),e.replaceRange(o.charAt(i.ch-1)+o.charAt(i.ch-2),B(i.line,i.ch-2),i,"+transpose");else if(i.line>e.doc.first){var l=ye(e.doc,i.line-1).text;l&&(i=new B(i.line,1),e.replaceRange(o.charAt(0)+e.doc.lineSeparator()+l.charAt(l.length-1),B(i.line-1,l.length-1),i,"+transpose"))}}n.push(new He(i,i))}e.setSelections(n)})},newlineAndIndent:function(e){return At(e,function(){for(var t=e.listSelections(),n=t.length-1;n>=0;n--)e.replaceRange(e.doc.lineSeparator(),t[n].anchor,t[n].head,"+input");t=e.listSelections();for(var r=0;re&&ce(t,this.pos)==0&&n==this.button};var Pn,In;function Nu(e,t){var n=+new Date;return In&&In.compare(n,e,t)?(Pn=In=null,"triple"):Pn&&Pn.compare(n,e,t)?(In=new oo(n,e,t),Pn=null,"double"):(Pn=new oo(n,e,t),In=null,"single")}function ra(e){var t=this,n=t.display;if(!(Qe(t,e)||n.activeTouch&&n.input.supportsTouch())){if(n.input.ensurePolled(),n.shift=e.shiftKey,tr(n,e)){Y||(n.scroller.draggable=!1,setTimeout(function(){return n.scroller.draggable=!0},100));return}if(!lo(t,e)){var r=Lr(t,e),i=Rt(e),o=r?Nu(r,i):"single";le(t).focus(),i==1&&t.state.selectingText&&t.state.selectingText(e),!(r&&Eu(t,i,r,o,e))&&(i==1?r?Pu(t,r,o,e):ln(e)==n.scroller&&pt(e):i==2?(r&&oi(t.doc,r),setTimeout(function(){return n.input.focus()},20)):i==3&&(J?t.display.input.onContextMenu(e):Hi(t)))}}}function Eu(e,t,n,r,i){var o="Click";return r=="double"?o="Double"+o:r=="triple"&&(o="Triple"+o),o=(t==1?"Left":t==2?"Middle":"Right")+o,On(e,Xl(o,i),i,function(l){if(typeof l=="string"&&(l=En[l]),!l)return!1;var a=!1;try{e.isReadOnly()&&(e.state.suppressEdits=!0),a=l(e,n)!=qe}finally{e.state.suppressEdits=!1}return a})}function Ou(e,t,n){var r=e.getOption("configureMouse"),i=r?r(e,t,n):{};if(i.unit==null){var o=X?n.shiftKey&&n.metaKey:n.altKey;i.unit=o?"rectangle":t=="single"?"char":t=="double"?"word":"line"}return(i.extend==null||e.doc.extend)&&(i.extend=e.doc.extend||n.shiftKey),i.addNew==null&&(i.addNew=z?n.metaKey:n.ctrlKey),i.moveOnDrag==null&&(i.moveOnDrag=!(z?n.altKey:n.ctrlKey)),i}function Pu(e,t,n,r){k?setTimeout(xe(nl,e),0):e.curOp.focus=y(fe(e));var i=Ou(e,n,r),o=e.doc.sel,l;e.options.dragDrop&&xi&&!e.isReadOnly()&&n=="single"&&(l=o.contains(t))>-1&&(ce((l=o.ranges[l]).from(),t)<0||t.xRel>0)&&(ce(l.to(),t)>0||t.xRel<0)?Iu(e,r,t,i):zu(e,r,t,i)}function Iu(e,t,n,r){var i=e.display,o=!1,l=lt(e,function(u){Y&&(i.scroller.draggable=!1),e.state.draggingText=!1,e.state.delayingBlurEvent&&(e.hasFocus()?e.state.delayingBlurEvent=!1:Hi(e)),ht(i.wrapper.ownerDocument,"mouseup",l),ht(i.wrapper.ownerDocument,"mousemove",a),ht(i.scroller,"dragstart",s),ht(i.scroller,"drop",l),o||(pt(u),r.addNew||oi(e.doc,n,null,null,r.extend),Y&&!V||k&&I==9?setTimeout(function(){i.wrapper.ownerDocument.body.focus({preventScroll:!0}),i.input.focus()},20):i.input.focus())}),a=function(u){o=o||Math.abs(t.clientX-u.clientX)+Math.abs(t.clientY-u.clientY)>=10},s=function(){return o=!0};Y&&(i.scroller.draggable=!0),e.state.draggingText=l,l.copy=!r.moveOnDrag,Se(i.wrapper.ownerDocument,"mouseup",l),Se(i.wrapper.ownerDocument,"mousemove",a),Se(i.scroller,"dragstart",s),Se(i.scroller,"drop",l),e.state.delayingBlurEvent=!0,setTimeout(function(){return i.input.focus()},20),i.scroller.dragDrop&&i.scroller.dragDrop()}function na(e,t,n){if(n=="char")return new He(t,t);if(n=="word")return e.findWordAt(t);if(n=="line")return new He(B(t.line,0),Ae(e.doc,B(t.line+1,0)));var r=n(e,t);return new He(r.from,r.to)}function zu(e,t,n,r){k&&Hi(e);var i=e.display,o=e.doc;pt(t);var l,a,s=o.sel,u=s.ranges;if(r.addNew&&!r.extend?(a=o.sel.contains(n),a>-1?l=u[a]:l=new He(n,n)):(l=o.sel.primary(),a=o.sel.primIndex),r.unit=="rectangle")r.addNew||(l=new He(n,n)),n=Lr(e,t,!0,!0),a=-1;else{var h=na(e,n,r.unit);r.extend?l=$i(l,h.anchor,h.head,r.extend):l=h}r.addNew?a==-1?(a=u.length,gt(o,Kt(e,u.concat([l]),a),{scroll:!1,origin:"*mouse"})):u.length>1&&u[a].empty()&&r.unit=="char"&&!r.extend?(gt(o,Kt(e,u.slice(0,a).concat(u.slice(a+1)),0),{scroll:!1,origin:"*mouse"}),s=o.sel):eo(o,a,l,dt):(a=0,gt(o,new Ot([l],0),dt),s=o.sel);var x=n;function D(se){if(ce(x,se)!=0)if(x=se,r.unit=="rectangle"){for(var ge=[],Le=e.options.tabSize,ke=Fe(ye(o,n.line).text,n.ch,Le),Ee=Fe(ye(o,se.line).text,se.ch,Le),Ke=Math.min(ke,Ee),st=Math.max(ke,Ee),Xe=Math.min(n.line,se.line),Nt=Math.min(e.lastLine(),Math.max(n.line,se.line));Xe<=Nt;Xe++){var Tt=ye(o,Xe).text,tt=_e(Tt,Ke,Le);Ke==st?ge.push(new He(B(Xe,tt),B(Xe,tt))):Tt.length>tt&&ge.push(new He(B(Xe,tt),B(Xe,_e(Tt,st,Le))))}ge.length||ge.push(new He(n,n)),gt(o,Kt(e,s.ranges.slice(0,a).concat(ge),a),{origin:"*mouse",scroll:!1}),e.scrollIntoView(se)}else{var Ct=l,ft=na(e,se,r.unit),nt=Ct.anchor,rt;ce(ft.anchor,nt)>0?(rt=ft.head,nt=Wr(Ct.from(),ft.anchor)):(rt=ft.anchor,nt=wt(Ct.to(),ft.head));var Ze=s.ranges.slice(0);Ze[a]=Bu(e,new He(Ae(o,nt),rt)),gt(o,Kt(e,Ze,a),dt)}}var L=i.wrapper.getBoundingClientRect(),H=0;function Z(se){var ge=++H,Le=Lr(e,se,!0,r.unit=="rectangle");if(Le)if(ce(Le,x)!=0){e.curOp.focus=y(fe(e)),D(Le);var ke=$n(i,o);(Le.line>=ke.to||Le.lineL.bottom?20:0;Ee&&setTimeout(lt(e,function(){H==ge&&(i.scroller.scrollTop+=Ee,Z(se))}),50)}}function ie(se){e.state.selectingText=!1,H=1/0,se&&(pt(se),i.input.focus()),ht(i.wrapper.ownerDocument,"mousemove",ae),ht(i.wrapper.ownerDocument,"mouseup",he),o.history.lastSelOrigin=null}var ae=lt(e,function(se){se.buttons===0||!Rt(se)?ie(se):Z(se)}),he=lt(e,ie);e.state.selectingText=he,Se(i.wrapper.ownerDocument,"mousemove",ae),Se(i.wrapper.ownerDocument,"mouseup",he)}function Bu(e,t){var n=t.anchor,r=t.head,i=ye(e.doc,n.line);if(ce(n,r)==0&&n.sticky==r.sticky)return t;var o=Re(i);if(!o)return t;var l=lr(o,n.ch,n.sticky),a=o[l];if(a.from!=n.ch&&a.to!=n.ch)return t;var s=l+(a.from==n.ch==(a.level!=1)?0:1);if(s==0||s==o.length)return t;var u;if(r.line!=n.line)u=(r.line-n.line)*(e.doc.direction=="ltr"?1:-1)>0;else{var h=lr(o,r.ch,r.sticky),x=h-l||(r.ch-n.ch)*(a.level==1?-1:1);h==s-1||h==s?u=x<0:u=x>0}var D=o[s+(u?-1:0)],L=u==(D.level==1),H=L?D.from:D.to,Z=L?"after":"before";return n.ch==H&&n.sticky==Z?t:new He(new B(n.line,H,Z),r)}function ia(e,t,n,r){var i,o;if(t.touches)i=t.touches[0].clientX,o=t.touches[0].clientY;else try{i=t.clientX,o=t.clientY}catch{return!1}if(i>=Math.floor(e.display.gutters.getBoundingClientRect().right))return!1;r&&pt(t);var l=e.display,a=l.lineDiv.getBoundingClientRect();if(o>a.bottom||!Ft(e,n))return kt(t);o-=a.top-l.viewOffset;for(var s=0;s=i){var h=m(e.doc,o),x=e.display.gutterSpecs[s];return Ye(e,n,e,h,x.className,t),kt(t)}}}function lo(e,t){return ia(e,t,"gutterClick",!0)}function oa(e,t){tr(e.display,t)||Ru(e,t)||Qe(e,t,"contextmenu")||J||e.display.input.onContextMenu(t)}function Ru(e,t){return Ft(e,"gutterContextMenu")?ia(e,t,"gutterContextMenu",!1):!1}function la(e){e.display.wrapper.className=e.display.wrapper.className.replace(/\s*cm-s-\S+/g,"")+e.options.theme.replace(/(^|\s)\s*/g," cm-s-"),gn(e)}var tn={toString:function(){return"CodeMirror.Init"}},aa={},di={};function Wu(e){var t=e.optionHandlers;function n(r,i,o,l){e.defaults[r]=i,o&&(t[r]=l?function(a,s,u){u!=tn&&o(a,s,u)}:o)}e.defineOption=n,e.Init=tn,n("value","",function(r,i){return r.setValue(i)},!0),n("mode",null,function(r,i){r.doc.modeOption=i,Ji(r)},!0),n("indentUnit",2,Ji,!0),n("indentWithTabs",!1),n("smartIndent",!0),n("tabSize",4,function(r){Sn(r),gn(r),St(r)},!0),n("lineSeparator",null,function(r,i){if(r.doc.lineSep=i,!!i){var o=[],l=r.doc.first;r.doc.iter(function(s){for(var u=0;;){var h=s.text.indexOf(i,u);if(h==-1)break;u=h+i.length,o.push(B(l,h))}l++});for(var a=o.length-1;a>=0;a--)Zr(r.doc,i,o[a],B(o[a].line,o[a].ch+i.length))}}),n("specialChars",/[\u0000-\u001f\u007f-\u009f\u00ad\u061c\u200b\u200e\u200f\u2028\u2029\u202d\u202e\u2066\u2067\u2069\ufeff\ufff9-\ufffc]/g,function(r,i,o){r.state.specialChars=new RegExp(i.source+(i.test(" ")?"":"| "),"g"),o!=tn&&r.refresh()}),n("specialCharPlaceholder",ps,function(r){return r.refresh()},!0),n("electricChars",!0),n("inputStyle",N?"contenteditable":"textarea",function(){throw new Error("inputStyle can not (yet) be changed in a running editor")},!0),n("spellcheck",!1,function(r,i){return r.getInputField().spellcheck=i},!0),n("autocorrect",!1,function(r,i){return r.getInputField().autocorrect=i},!0),n("autocapitalize",!1,function(r,i){return r.getInputField().autocapitalize=i},!0),n("rtlMoveVisually",!q),n("wholeLineUpdateBefore",!0),n("theme","default",function(r){la(r),wn(r)},!0),n("keyMap","default",function(r,i,o){var l=fi(i),a=o!=tn&&fi(o);a&&a.detach&&a.detach(r,l),l.attach&&l.attach(r,a||null)}),n("extraKeys",null),n("configureMouse",null),n("lineWrapping",!1,_u,!0),n("gutters",[],function(r,i){r.display.gutterSpecs=Yi(i,r.options.lineNumbers),wn(r)},!0),n("fixedGutter",!0,function(r,i){r.display.gutters.style.left=i?zi(r.display)+"px":"0",r.refresh()},!0),n("coverGutterNextToScrollbar",!1,function(r){return Xr(r)},!0),n("scrollbarStyle","native",function(r){ul(r),Xr(r),r.display.scrollbars.setScrollTop(r.doc.scrollTop),r.display.scrollbars.setScrollLeft(r.doc.scrollLeft)},!0),n("lineNumbers",!1,function(r,i){r.display.gutterSpecs=Yi(r.options.gutters,i),wn(r)},!0),n("firstLineNumber",1,wn,!0),n("lineNumberFormatter",function(r){return r},wn,!0),n("showCursorWhenSelecting",!1,vn,!0),n("resetSelectionOnContextMenu",!0),n("lineWiseCopyCut",!0),n("pasteLinesPerSelection",!0),n("selectionsMayTouch",!1),n("readOnly",!1,function(r,i){i=="nocursor"&&(Ur(r),r.display.input.blur()),r.display.input.readOnlyChanged(i)}),n("screenReaderLabel",null,function(r,i){i=i===""?null:i,r.display.input.screenReaderLabelChanged(i)}),n("disableInput",!1,function(r,i){i||r.display.input.reset()},!0),n("dragDrop",!0,Hu),n("allowDropFileTypes",null),n("cursorBlinkRate",530),n("cursorScrollMargin",0),n("cursorHeight",1,vn,!0),n("singleCursorHeightPerLine",!0,vn,!0),n("workTime",100),n("workDelay",100),n("flattenSpans",!0,Sn,!0),n("addModeClass",!1,Sn,!0),n("pollInterval",100),n("undoDepth",200,function(r,i){return r.doc.history.undoDepth=i}),n("historyEventDelay",1250),n("viewportMargin",10,function(r){return r.refresh()},!0),n("maxHighlightLength",1e4,Sn,!0),n("moveInputWithCursor",!0,function(r,i){i||r.display.input.resetPosition()}),n("tabindex",null,function(r,i){return r.display.input.getField().tabIndex=i||""}),n("autofocus",null),n("direction","ltr",function(r,i){return r.doc.setDirection(i)},!0),n("phrases",null)}function Hu(e,t,n){var r=n&&n!=tn;if(!t!=!r){var i=e.display.dragFunctions,o=t?Se:ht;o(e.display.scroller,"dragstart",i.start),o(e.display.scroller,"dragenter",i.enter),o(e.display.scroller,"dragover",i.over),o(e.display.scroller,"dragleave",i.leave),o(e.display.scroller,"drop",i.drop)}}function _u(e){e.options.lineWrapping?(j(e.display.wrapper,"CodeMirror-wrap"),e.display.sizer.style.minWidth="",e.display.sizerWidth=null):($(e.display.wrapper,"CodeMirror-wrap"),Ci(e)),Bi(e),St(e),gn(e),setTimeout(function(){return Xr(e)},100)}function Ge(e,t){var n=this;if(!(this instanceof Ge))return new Ge(e,t);this.options=t=t?Me(t):{},Me(aa,t,!1);var r=t.value;typeof r=="string"?r=new Lt(r,t.mode,null,t.lineSeparator,t.direction):t.mode&&(r.modeOption=t.mode),this.doc=r;var i=new Ge.inputStyles[t.inputStyle](this),o=this.display=new eu(e,r,i,t);o.wrapper.CodeMirror=this,la(this),t.lineWrapping&&(this.display.wrapper.className+=" CodeMirror-wrap"),ul(this),this.state={keyMaps:[],overlays:[],modeGen:0,overwrite:!1,delayingBlurEvent:!1,focused:!1,suppressEdits:!1,pasteIncoming:-1,cutIncoming:-1,selectingText:!1,draggingText:!1,highlight:new Ce,keySeq:null,specialChars:null},t.autofocus&&!N&&o.input.focus(),k&&I<11&&setTimeout(function(){return n.display.input.reset(!0)},20),qu(this),yu(),Mr(this),this.curOp.forceUpdate=!0,yl(this,r),t.autofocus&&!N||this.hasFocus()?setTimeout(function(){n.hasFocus()&&!n.state.focused&&_i(n)},20):Ur(this);for(var l in di)di.hasOwnProperty(l)&&di[l](this,t[l],tn);dl(this),t.finishInit&&t.finishInit(this);for(var a=0;a400}Se(t.scroller,"touchstart",function(s){if(!Qe(e,s)&&!o(s)&&!lo(e,s)){t.input.ensurePolled(),clearTimeout(n);var u=+new Date;t.activeTouch={start:u,moved:!1,prev:u-r.end<=300?r:null},s.touches.length==1&&(t.activeTouch.left=s.touches[0].pageX,t.activeTouch.top=s.touches[0].pageY)}}),Se(t.scroller,"touchmove",function(){t.activeTouch&&(t.activeTouch.moved=!0)}),Se(t.scroller,"touchend",function(s){var u=t.activeTouch;if(u&&!tr(t,s)&&u.left!=null&&!u.moved&&new Date-u.start<300){var h=e.coordsChar(t.activeTouch,"page"),x;!u.prev||l(u,u.prev)?x=new He(h,h):!u.prev.prev||l(u,u.prev.prev)?x=e.findWordAt(h):x=new He(B(h.line,0),Ae(e.doc,B(h.line+1,0))),e.setSelection(x.anchor,x.head),e.focus(),pt(s)}i()}),Se(t.scroller,"touchcancel",i),Se(t.scroller,"scroll",function(){t.scroller.clientHeight&&(xn(e,t.scroller.scrollTop),Cr(e,t.scroller.scrollLeft,!0),Ye(e,"scroll",e))}),Se(t.scroller,"mousewheel",function(s){return gl(e,s)}),Se(t.scroller,"DOMMouseScroll",function(s){return gl(e,s)}),Se(t.wrapper,"scroll",function(){return t.wrapper.scrollTop=t.wrapper.scrollLeft=0}),t.dragFunctions={enter:function(s){Qe(e,s)||ar(s)},over:function(s){Qe(e,s)||(xu(e,s),ar(s))},start:function(s){return mu(e,s)},drop:lt(e,vu),leave:function(s){Qe(e,s)||jl(e)}};var a=t.input.getField();Se(a,"keyup",function(s){return ea.call(e,s)}),Se(a,"keydown",lt(e,$l)),Se(a,"keypress",lt(e,ta)),Se(a,"focus",function(s){return _i(e,s)}),Se(a,"blur",function(s){return Ur(e,s)})}var ao=[];Ge.defineInitHook=function(e){return ao.push(e)};function zn(e,t,n,r){var i=e.doc,o;n==null&&(n="add"),n=="smart"&&(i.mode.indent?o=fn(e,t).state:n="prev");var l=e.options.tabSize,a=ye(i,t),s=Fe(a.text,null,l);a.stateAfter&&(a.stateAfter=null);var u=a.text.match(/^\s*/)[0],h;if(!r&&!/\S/.test(a.text))h=0,n="not";else if(n=="smart"&&(h=i.mode.indent(o,a.text.slice(u.length),a.text),h==qe||h>150)){if(!r)return;n="prev"}n=="prev"?t>i.first?h=Fe(ye(i,t-1).text,null,l):h=0:n=="add"?h=s+e.options.indentUnit:n=="subtract"?h=s-e.options.indentUnit:typeof n=="number"&&(h=s+n),h=Math.max(0,h);var x="",D=0;if(e.options.indentWithTabs)for(var L=Math.floor(h/l);L;--L)D+=l,x+=" ";if(Dl,s=zt(t),u=null;if(a&&r.ranges.length>1)if(Ut&&Ut.text.join(` +`)==t){if(r.ranges.length%Ut.text.length==0){u=[];for(var h=0;h=0;D--){var L=r.ranges[D],H=L.from(),Z=L.to();L.empty()&&(n&&n>0?H=B(H.line,H.ch-n):e.state.overwrite&&!a?Z=B(Z.line,Math.min(ye(o,Z.line).text.length,Z.ch+we(s).length)):a&&Ut&&Ut.lineWise&&Ut.text.join(` +`)==s.join(` +`)&&(H=Z=B(H.line,0)));var ie={from:H,to:Z,text:u?u[D%u.length]:s,origin:i||(a?"paste":e.state.cutIncoming>l?"cut":"+input")};Jr(e.doc,ie),ot(e,"inputRead",e,ie)}t&&!a&&ua(e,t),Gr(e),e.curOp.updateInput<2&&(e.curOp.updateInput=x),e.curOp.typing=!0,e.state.pasteIncoming=e.state.cutIncoming=-1}function sa(e,t){var n=e.clipboardData&&e.clipboardData.getData("Text");if(n)return e.preventDefault(),!t.isReadOnly()&&!t.options.disableInput&&t.hasFocus()&&At(t,function(){return so(t,n,0,null,"paste")}),!0}function ua(e,t){if(!(!e.options.electricChars||!e.options.smartIndent))for(var n=e.doc.sel,r=n.ranges.length-1;r>=0;r--){var i=n.ranges[r];if(!(i.head.ch>100||r&&n.ranges[r-1].head.line==i.head.line)){var o=e.getModeAt(i.head),l=!1;if(o.electricChars){for(var a=0;a-1){l=zn(e,i.head.line,"smart");break}}else o.electricInput&&o.electricInput.test(ye(e.doc,i.head.line).text.slice(0,i.head.ch))&&(l=zn(e,i.head.line,"smart"));l&&ot(e,"electricInput",e,i.head.line)}}}function fa(e){for(var t=[],n=[],r=0;ro&&(zn(this,a.head.line,r,!0),o=a.head.line,l==this.doc.sel.primIndex&&Gr(this));else{var s=a.from(),u=a.to(),h=Math.max(o,s.line);o=Math.min(this.lastLine(),u.line-(u.ch?0:1))+1;for(var x=h;x0&&eo(this.doc,l,new He(s,D[l].to()),Ve)}}}),getTokenAt:function(r,i){return ko(this,r,i)},getLineTokens:function(r,i){return ko(this,B(r),i,!0)},getTokenTypeAt:function(r){r=Ae(this.doc,r);var i=xo(this,ye(this.doc,r.line)),o=0,l=(i.length-1)/2,a=r.ch,s;if(a==0)s=i[2];else for(;;){var u=o+l>>1;if((u?i[u*2-1]:0)>=a)l=u;else if(i[u*2+1]s&&(r=s,l=!0),a=ye(this.doc,r)}else a=r;return Yn(this,a,{top:0,left:0},i||"page",o||l).top+(l?this.doc.height-er(a):0)},defaultTextHeight:function(){return jr(this.display)},defaultCharWidth:function(){return Kr(this.display)},getViewport:function(){return{from:this.display.viewFrom,to:this.display.viewTo}},addWidget:function(r,i,o,l,a){var s=this.display;r=jt(this,Ae(this.doc,r));var u=r.bottom,h=r.left;if(i.style.position="absolute",i.setAttribute("cm-ignore-events","true"),this.display.input.setUneditable(i),s.sizer.appendChild(i),l=="over")u=r.top;else if(l=="above"||l=="near"){var x=Math.max(s.wrapper.clientHeight,this.doc.height),D=Math.max(s.sizer.clientWidth,s.lineSpace.clientWidth);(l=="above"||r.bottom+i.offsetHeight>x)&&r.top>i.offsetHeight?u=r.top-i.offsetHeight:r.bottom+i.offsetHeight<=x&&(u=r.bottom),h+i.offsetWidth>D&&(h=D-i.offsetWidth)}i.style.top=u+"px",i.style.left=i.style.right="",a=="right"?(h=s.sizer.clientWidth-i.offsetWidth,i.style.right="0px"):(a=="left"?h=0:a=="middle"&&(h=(s.sizer.clientWidth-i.offsetWidth)/2),i.style.left=h+"px"),o&&Hs(this,{left:h,top:u,right:h+i.offsetWidth,bottom:u+i.offsetHeight})},triggerOnKeyDown:yt($l),triggerOnKeyPress:yt(ta),triggerOnKeyUp:ea,triggerOnMouseDown:yt(ra),execCommand:function(r){if(En.hasOwnProperty(r))return En[r].call(null,this)},triggerElectric:yt(function(r){ua(this,r)}),findPosH:function(r,i,o,l){var a=1;i<0&&(a=-1,i=-i);for(var s=Ae(this.doc,r),u=0;u0&&h(o.charAt(l-1));)--l;for(;a.5||this.options.lineWrapping)&&Bi(this),Ye(this,"refresh",this)}),swapDoc:yt(function(r){var i=this.doc;return i.cm=null,this.state.selectingText&&this.state.selectingText(),yl(this,r),gn(this),this.display.input.reset(),mn(this,r.scrollLeft,r.scrollTop),this.curOp.forceScroll=!0,ot(this,"swapDoc",this,i),i}),phrase:function(r){var i=this.options.phrases;return i&&Object.prototype.hasOwnProperty.call(i,r)?i[r]:r},getInputField:function(){return this.display.input.getField()},getWrapperElement:function(){return this.display.wrapper},getScrollerElement:function(){return this.display.scroller},getGutterElement:function(){return this.display.gutters}},Bt(e),e.registerHelper=function(r,i,o){n.hasOwnProperty(r)||(n[r]=e[r]={_global:[]}),n[r][i]=o},e.registerGlobalHelper=function(r,i,o,l){e.registerHelper(r,i,l),n[r]._global.push({pred:o,val:l})}}function fo(e,t,n,r,i){var o=t,l=n,a=ye(e,t.line),s=i&&e.direction=="rtl"?-n:n;function u(){var he=t.line+s;return he=e.first+e.size?!1:(t=new B(he,t.ch,t.sticky),a=ye(e,he))}function h(he){var se;if(r=="codepoint"){var ge=a.text.charCodeAt(t.ch+(n>0?0:-1));if(isNaN(ge))se=null;else{var Le=n>0?ge>=55296&&ge<56320:ge>=56320&&ge<57343;se=new B(t.line,Math.max(0,Math.min(a.text.length,t.ch+n*(Le?2:1))),-n)}}else i?se=Lu(e.cm,a,t,n):se=ro(a,t,n);if(se==null)if(!he&&u())t=no(i,e.cm,a,t.line,s);else return!1;else t=se;return!0}if(r=="char"||r=="codepoint")h();else if(r=="column")h(!0);else if(r=="word"||r=="group")for(var x=null,D=r=="group",L=e.cm&&e.cm.getHelper(t,"wordChars"),H=!0;!(n<0&&!h(!H));H=!1){var Z=a.text.charAt(t.ch)||` +`,ie=De(Z,L)?"w":D&&Z==` +`?"n":!D||/\s/.test(Z)?null:"p";if(D&&!H&&!ie&&(ie="s"),x&&x!=ie){n<0&&(n=1,h(),t.sticky="after");break}if(ie&&(x=ie),n>0&&!h(!H))break}var ae=ai(e,t,o,l,!0);return We(o,ae)&&(ae.hitSide=!0),ae}function da(e,t,n,r){var i=e.doc,o=t.left,l;if(r=="page"){var a=Math.min(e.display.wrapper.clientHeight,le(e).innerHeight||i(e).documentElement.clientHeight),s=Math.max(a-.5*jr(e.display),3);l=(n>0?t.bottom:t.top)+n*s}else r=="line"&&(l=n>0?t.bottom+3:t.top-3);for(var u;u=Oi(e,o,l),!!u.outside;){if(n<0?l<=0:l>=i.height){u.hitSide=!0;break}l+=n*5}return u}var je=function(e){this.cm=e,this.lastAnchorNode=this.lastAnchorOffset=this.lastFocusNode=this.lastFocusOffset=null,this.polling=new Ce,this.composing=null,this.gracePeriod=!1,this.readDOMTimeout=null};je.prototype.init=function(e){var t=this,n=this,r=n.cm,i=n.div=e.lineDiv;i.contentEditable=!0,uo(i,r.options.spellcheck,r.options.autocorrect,r.options.autocapitalize);function o(a){for(var s=a.target;s;s=s.parentNode){if(s==i)return!0;if(/\bCodeMirror-(?:line)?widget\b/.test(s.className))break}return!1}Se(i,"paste",function(a){!o(a)||Qe(r,a)||sa(a,r)||I<=11&&setTimeout(lt(r,function(){return t.updateFromDOM()}),20)}),Se(i,"compositionstart",function(a){t.composing={data:a.data,done:!1}}),Se(i,"compositionupdate",function(a){t.composing||(t.composing={data:a.data,done:!1})}),Se(i,"compositionend",function(a){t.composing&&(a.data!=t.composing.data&&t.readFromDOMSoon(),t.composing.done=!0)}),Se(i,"touchstart",function(){return n.forceCompositionEnd()}),Se(i,"input",function(){t.composing||t.readFromDOMSoon()});function l(a){if(!(!o(a)||Qe(r,a))){if(r.somethingSelected())hi({lineWise:!1,text:r.getSelections()}),a.type=="cut"&&r.replaceSelection("",null,"cut");else if(r.options.lineWiseCopyCut){var s=fa(r);hi({lineWise:!0,text:s.text}),a.type=="cut"&&r.operation(function(){r.setSelections(s.ranges,0,Ve),r.replaceSelection("",null,"cut")})}else return;if(a.clipboardData){a.clipboardData.clearData();var u=Ut.text.join(` +`);if(a.clipboardData.setData("Text",u),a.clipboardData.getData("Text")==u){a.preventDefault();return}}var h=ca(),x=h.firstChild;uo(x),r.display.lineSpace.insertBefore(h,r.display.lineSpace.firstChild),x.value=Ut.text.join(` +`);var D=y(Te(i));v(x),setTimeout(function(){r.display.lineSpace.removeChild(h),D.focus(),D==i&&n.showPrimarySelection()},50)}}Se(i,"copy",l),Se(i,"cut",l)},je.prototype.screenReaderLabelChanged=function(e){e?this.div.setAttribute("aria-label",e):this.div.removeAttribute("aria-label")},je.prototype.prepareSelection=function(){var e=rl(this.cm,!1);return e.focus=y(Te(this.div))==this.div,e},je.prototype.showSelection=function(e,t){!e||!this.cm.display.view.length||((e.focus||t)&&this.showPrimarySelection(),this.showMultipleSelections(e))},je.prototype.getSelection=function(){return this.cm.display.wrapper.ownerDocument.getSelection()},je.prototype.showPrimarySelection=function(){var e=this.getSelection(),t=this.cm,n=t.doc.sel.primary(),r=n.from(),i=n.to();if(t.display.viewTo==t.display.viewFrom||r.line>=t.display.viewTo||i.line=t.display.viewFrom&&ha(t,r)||{node:a[0].measure.map[2],offset:0},u=i.linee.firstLine()&&(r=B(r.line-1,ye(e.doc,r.line-1).length)),i.ch==ye(e.doc,i.line).text.length&&i.linet.viewTo-1)return!1;var o,l,a;r.line==t.viewFrom||(o=Tr(e,r.line))==0?(l=f(t.view[0].line),a=t.view[0].node):(l=f(t.view[o].line),a=t.view[o-1].node.nextSibling);var s=Tr(e,i.line),u,h;if(s==t.view.length-1?(u=t.viewTo-1,h=t.lineDiv.lastChild):(u=f(t.view[s+1].line)-1,h=t.view[s+1].node.previousSibling),!a)return!1;for(var x=e.doc.splitLines(Uu(e,a,h,l,u)),D=Vt(e.doc,B(l,0),B(u,ye(e.doc,u).text.length));x.length>1&&D.length>1;)if(we(x)==we(D))x.pop(),D.pop(),u--;else if(x[0]==D[0])x.shift(),D.shift(),l++;else break;for(var L=0,H=0,Z=x[0],ie=D[0],ae=Math.min(Z.length,ie.length);Lr.ch&&he.charCodeAt(he.length-H-1)==se.charCodeAt(se.length-H-1);)L--,H++;x[x.length-1]=he.slice(0,he.length-H).replace(/^\u200b+/,""),x[0]=x[0].slice(L).replace(/\u200b+$/,"");var Le=B(l,L),ke=B(u,D.length?we(D).length-H:0);if(x.length>1||x[0]||ce(Le,ke))return Zr(e.doc,x,Le,ke,"+input"),!0},je.prototype.ensurePolled=function(){this.forceCompositionEnd()},je.prototype.reset=function(){this.forceCompositionEnd()},je.prototype.forceCompositionEnd=function(){this.composing&&(clearTimeout(this.readDOMTimeout),this.composing=null,this.updateFromDOM(),this.div.blur(),this.div.focus())},je.prototype.readFromDOMSoon=function(){var e=this;this.readDOMTimeout==null&&(this.readDOMTimeout=setTimeout(function(){if(e.readDOMTimeout=null,e.composing)if(e.composing.done)e.composing=null;else return;e.updateFromDOM()},80))},je.prototype.updateFromDOM=function(){var e=this;(this.cm.isReadOnly()||!this.pollContent())&&At(this.cm,function(){return St(e.cm)})},je.prototype.setUneditable=function(e){e.contentEditable="false"},je.prototype.onKeyPress=function(e){e.charCode==0||this.composing||(e.preventDefault(),this.cm.isReadOnly()||lt(this.cm,so)(this.cm,String.fromCharCode(e.charCode==null?e.keyCode:e.charCode),0))},je.prototype.readOnlyChanged=function(e){this.div.contentEditable=String(e!="nocursor")},je.prototype.onContextMenu=function(){},je.prototype.resetPosition=function(){},je.prototype.needsContentAttribute=!0;function ha(e,t){var n=Ai(e,t.line);if(!n||n.hidden)return null;var r=ye(e.doc,t.line),i=qo(n,r,t.line),o=Re(r,e.doc.direction),l="left";if(o){var a=lr(o,t.ch);l=a%2?"right":"left"}var s=Uo(i.map,t.ch,l);return s.offset=s.collapse=="right"?s.end:s.start,s}function Ku(e){for(var t=e;t;t=t.parentNode)if(/CodeMirror-gutter-wrapper/.test(t.className))return!0;return!1}function rn(e,t){return t&&(e.bad=!0),e}function Uu(e,t,n,r,i){var o="",l=!1,a=e.doc.lineSeparator(),s=!1;function u(L){return function(H){return H.id==L}}function h(){l&&(o+=a,s&&(o+=a),l=s=!1)}function x(L){L&&(h(),o+=L)}function D(L){if(L.nodeType==1){var H=L.getAttribute("cm-text");if(H){x(H);return}var Z=L.getAttribute("cm-marker"),ie;if(Z){var ae=e.findMarks(B(r,0),B(i+1,0),u(+Z));ae.length&&(ie=ae[0].find(0))&&x(Vt(e.doc,ie.from,ie.to).join(a));return}if(L.getAttribute("contenteditable")=="false")return;var he=/^(pre|div|p|li|table|br)$/i.test(L.nodeName);if(!/^br$/i.test(L.nodeName)&&L.textContent.length==0)return;he&&h();for(var se=0;se=9&&t.hasSelection&&(t.hasSelection=null),n.poll()}),Se(i,"paste",function(l){Qe(r,l)||sa(l,r)||(r.state.pasteIncoming=+new Date,n.fastPoll())});function o(l){if(!Qe(r,l)){if(r.somethingSelected())hi({lineWise:!1,text:r.getSelections()});else if(r.options.lineWiseCopyCut){var a=fa(r);hi({lineWise:!0,text:a.text}),l.type=="cut"?r.setSelections(a.ranges,null,Ve):(n.prevInput="",i.value=a.text.join(` +`),v(i))}else return;l.type=="cut"&&(r.state.cutIncoming=+new Date)}}Se(i,"cut",o),Se(i,"copy",o),Se(e.scroller,"paste",function(l){if(!(tr(e,l)||Qe(r,l))){if(!i.dispatchEvent){r.state.pasteIncoming=+new Date,n.focus();return}var a=new Event("paste");a.clipboardData=l.clipboardData,i.dispatchEvent(a)}}),Se(e.lineSpace,"selectstart",function(l){tr(e,l)||pt(l)}),Se(i,"compositionstart",function(){var l=r.getCursor("from");n.composing&&n.composing.range.clear(),n.composing={start:l,range:r.markText(l,r.getCursor("to"),{className:"CodeMirror-composing"})}}),Se(i,"compositionend",function(){n.composing&&(n.poll(),n.composing.range.clear(),n.composing=null)})},$e.prototype.createField=function(e){this.wrapper=ca(),this.textarea=this.wrapper.firstChild;var t=this.cm.options;uo(this.textarea,t.spellcheck,t.autocorrect,t.autocapitalize)},$e.prototype.screenReaderLabelChanged=function(e){e?this.textarea.setAttribute("aria-label",e):this.textarea.removeAttribute("aria-label")},$e.prototype.prepareSelection=function(){var e=this.cm,t=e.display,n=e.doc,r=rl(e);if(e.options.moveInputWithCursor){var i=jt(e,n.sel.primary().head,"div"),o=t.wrapper.getBoundingClientRect(),l=t.lineDiv.getBoundingClientRect();r.teTop=Math.max(0,Math.min(t.wrapper.clientHeight-10,i.top+l.top-o.top)),r.teLeft=Math.max(0,Math.min(t.wrapper.clientWidth-10,i.left+l.left-o.left))}return r},$e.prototype.showSelection=function(e){var t=this.cm,n=t.display;G(n.cursorDiv,e.cursors),G(n.selectionDiv,e.selection),e.teTop!=null&&(this.wrapper.style.top=e.teTop+"px",this.wrapper.style.left=e.teLeft+"px")},$e.prototype.reset=function(e){if(!(this.contextMenuPending||this.composing&&e)){var t=this.cm;if(this.resetting=!0,t.somethingSelected()){this.prevInput="";var n=t.getSelection();this.textarea.value=n,t.state.focused&&v(this.textarea),k&&I>=9&&(this.hasSelection=n)}else e||(this.prevInput=this.textarea.value="",k&&I>=9&&(this.hasSelection=null));this.resetting=!1}},$e.prototype.getField=function(){return this.textarea},$e.prototype.supportsTouch=function(){return!1},$e.prototype.focus=function(){if(this.cm.options.readOnly!="nocursor"&&(!N||y(Te(this.textarea))!=this.textarea))try{this.textarea.focus()}catch{}},$e.prototype.blur=function(){this.textarea.blur()},$e.prototype.resetPosition=function(){this.wrapper.style.top=this.wrapper.style.left=0},$e.prototype.receivedFocus=function(){this.slowPoll()},$e.prototype.slowPoll=function(){var e=this;this.pollingFast||this.polling.set(this.cm.options.pollInterval,function(){e.poll(),e.cm.state.focused&&e.slowPoll()})},$e.prototype.fastPoll=function(){var e=!1,t=this;t.pollingFast=!0;function n(){var r=t.poll();!r&&!e?(e=!0,t.polling.set(60,n)):(t.pollingFast=!1,t.slowPoll())}t.polling.set(20,n)},$e.prototype.poll=function(){var e=this,t=this.cm,n=this.textarea,r=this.prevInput;if(this.contextMenuPending||this.resetting||!t.state.focused||ur(n)&&!r&&!this.composing||t.isReadOnly()||t.options.disableInput||t.state.keySeq)return!1;var i=n.value;if(i==r&&!t.somethingSelected())return!1;if(k&&I>=9&&this.hasSelection===i||z&&/[\uf700-\uf7ff]/.test(i))return t.display.input.reset(),!1;if(t.doc.sel==t.display.selForContextMenu){var o=i.charCodeAt(0);if(o==8203&&!r&&(r="​"),o==8666)return this.reset(),this.cm.execCommand("undo")}for(var l=0,a=Math.min(r.length,i.length);l1e3||i.indexOf(` +`)>-1?n.value=e.prevInput="":e.prevInput=i,e.composing&&(e.composing.range.clear(),e.composing.range=t.markText(e.composing.start,t.getCursor("to"),{className:"CodeMirror-composing"}))}),!0},$e.prototype.ensurePolled=function(){this.pollingFast&&this.poll()&&(this.pollingFast=!1)},$e.prototype.onKeyPress=function(){k&&I>=9&&(this.hasSelection=null),this.fastPoll()},$e.prototype.onContextMenu=function(e){var t=this,n=t.cm,r=n.display,i=t.textarea;t.contextMenuPending&&t.contextMenuPending();var o=Lr(n,e),l=r.scroller.scrollTop;if(!o||A)return;var a=n.options.resetSelectionOnContextMenu;a&&n.doc.sel.contains(o)==-1&<(n,gt)(n.doc,pr(o),Ve);var s=i.style.cssText,u=t.wrapper.style.cssText,h=t.wrapper.offsetParent.getBoundingClientRect();t.wrapper.style.cssText="position: static",i.style.cssText=`position: absolute; width: 30px; height: 30px; + top: `+(e.clientY-h.top-5)+"px; left: "+(e.clientX-h.left-5)+`px; + z-index: 1000; background: `+(k?"rgba(255, 255, 255, .05)":"transparent")+`; + outline: none; border-width: 0; outline: none; overflow: hidden; opacity: .05; filter: alpha(opacity=5);`;var x;Y&&(x=i.ownerDocument.defaultView.scrollY),r.input.focus(),Y&&i.ownerDocument.defaultView.scrollTo(null,x),r.input.reset(),n.somethingSelected()||(i.value=t.prevInput=" "),t.contextMenuPending=L,r.selForContextMenu=n.doc.sel,clearTimeout(r.detectingSelectAll);function D(){if(i.selectionStart!=null){var Z=n.somethingSelected(),ie="​"+(Z?i.value:"");i.value="⇚",i.value=ie,t.prevInput=Z?"":"​",i.selectionStart=1,i.selectionEnd=ie.length,r.selForContextMenu=n.doc.sel}}function L(){if(t.contextMenuPending==L&&(t.contextMenuPending=!1,t.wrapper.style.cssText=u,i.style.cssText=s,k&&I<9&&r.scrollbars.setScrollTop(r.scroller.scrollTop=l),i.selectionStart!=null)){(!k||k&&I<9)&&D();var Z=0,ie=function(){r.selForContextMenu==n.doc.sel&&i.selectionStart==0&&i.selectionEnd>0&&t.prevInput=="​"?lt(n,El)(n):Z++<10?r.detectingSelectAll=setTimeout(ie,500):(r.selForContextMenu=null,r.input.reset())};r.detectingSelectAll=setTimeout(ie,200)}}if(k&&I>=9&&D(),J){ar(e);var H=function(){ht(window,"mouseup",H),setTimeout(L,20)};Se(window,"mouseup",H)}else setTimeout(L,50)},$e.prototype.readOnlyChanged=function(e){e||this.reset(),this.textarea.disabled=e=="nocursor",this.textarea.readOnly=!!e},$e.prototype.setUneditable=function(){},$e.prototype.needsContentAttribute=!1;function Xu(e,t){if(t=t?Me(t):{},t.value=e.value,!t.tabindex&&e.tabIndex&&(t.tabindex=e.tabIndex),!t.placeholder&&e.placeholder&&(t.placeholder=e.placeholder),t.autofocus==null){var n=y(Te(e));t.autofocus=n==e||e.getAttribute("autofocus")!=null&&n==document.body}function r(){e.value=a.getValue()}var i;if(e.form&&(Se(e.form,"submit",r),!t.leaveSubmitMethodAlone)){var o=e.form;i=o.submit;try{var l=o.submit=function(){r(),o.submit=i,o.submit(),o.submit=l}}catch{}}t.finishInit=function(s){s.save=r,s.getTextArea=function(){return e},s.toTextArea=function(){s.toTextArea=isNaN,r(),e.parentNode.removeChild(s.getWrapperElement()),e.style.display="",e.form&&(ht(e.form,"submit",r),!t.leaveSubmitMethodAlone&&typeof e.form.submit=="function"&&(e.form.submit=i))}},e.style.display="none";var a=Ge(function(s){return e.parentNode.insertBefore(s,e.nextSibling)},t);return a}function Yu(e){e.off=ht,e.on=Se,e.wheelEventPixels=tu,e.Doc=Lt,e.splitLines=zt,e.countColumn=Fe,e.findColumn=_e,e.isWordChar=me,e.Pass=qe,e.signal=Ye,e.Line=Hr,e.changeEnd=gr,e.scrollbarModel=sl,e.Pos=B,e.cmpPos=ce,e.modes=Pr,e.mimeModes=Ht,e.resolveMode=Ir,e.getMode=zr,e.modeExtensions=fr,e.extendMode=Br,e.copyState=Gt,e.startState=Rr,e.innerMode=sn,e.commands=En,e.keyMap=nr,e.keyName=Yl,e.isModifierKey=Gl,e.lookupKey=$r,e.normalizeKeyMap=Su,e.StringStream=Je,e.SharedTextMarker=Fn,e.TextMarker=mr,e.LineWidget=Mn,e.e_preventDefault=pt,e.e_stopPropagation=Er,e.e_stop=ar,e.addClass=j,e.contains=g,e.rmClass=$,e.keyNames=xr}Wu(Ge),ju(Ge);var Qu="iter insert remove copy getEditor constructor".split(" ");for(var gi in Lt.prototype)Lt.prototype.hasOwnProperty(gi)&&ve(Qu,gi)<0&&(Ge.prototype[gi]=(function(e){return function(){return e.apply(this.doc,arguments)}})(Lt.prototype[gi]));return Bt(Lt),Ge.inputStyles={textarea:$e,contenteditable:je},Ge.defineMode=function(e){!Ge.defaults.mode&&e!="null"&&(Ge.defaults.mode=e),_t.apply(this,arguments)},Ge.defineMIME=kr,Ge.defineMode("null",function(){return{token:function(e){return e.skipToEnd()}}}),Ge.defineMIME("text/plain","null"),Ge.defineExtension=function(e,t){Ge.prototype[e]=t},Ge.defineDocExtension=function(e,t){Lt.prototype[e]=t},Ge.fromTextArea=Xu,Yu(Ge),Ge.version="5.65.18",Ge}))})(vi)),vi.exports}var Vu=mt();const df=Ju(Vu);var ga={exports:{}},va;function Xa(){return va||(va=1,(function(ct,xt){(function(b){b(mt())})(function(b){b.defineMode("css",function(J,P){var $=P.inline;P.propertyKeywords||(P=b.resolveMode("text/css"));var F=J.indentUnit,G=P.tokenHooks,c=P.documentTypes||{},T=P.mediaTypes||{},C=P.mediaFeatures||{},g=P.mediaValueKeywords||{},y=P.propertyKeywords||{},j=P.nonStandardPropertyKeywords||{},de=P.fontProperties||{},v=P.counterDescriptors||{},d=P.colorKeywords||{},fe=P.valueKeywords||{},Te=P.allowNested,le=P.lineComment,xe=P.supportsAtComponent===!0,Me=J.highlightNonStandardPropertyKeywords!==!1,Fe,Ce;function ve(E,ee){return Fe=ee,E}function Oe(E,ee){var K=E.next();if(G[K]){var ze=G[K](E,ee);if(ze!==!1)return ze}if(K=="@")return E.eatWhile(/[\w\\\-]/),ve("def",E.current());if(K=="="||(K=="~"||K=="|")&&E.eat("="))return ve(null,"compare");if(K=='"'||K=="'")return ee.tokenize=qe(K),ee.tokenize(E,ee);if(K=="#")return E.eatWhile(/[\w\\\-]/),ve("atom","hash");if(K=="!")return E.match(/^\s*\w*/),ve("keyword","important");if(/\d/.test(K)||K=="."&&E.eat(/\d/))return E.eatWhile(/[\w.%]/),ve("number","unit");if(K==="-"){if(/[\d.]/.test(E.peek()))return E.eatWhile(/[\w.%]/),ve("number","unit");if(E.match(/^-[\w\\\-]*/))return E.eatWhile(/[\w\\\-]/),E.match(/^\s*:/,!1)?ve("variable-2","variable-definition"):ve("variable-2","variable");if(E.match(/^\w+-/))return ve("meta","meta")}else return/[,+>*\/]/.test(K)?ve(null,"select-op"):K=="."&&E.match(/^-?[_a-z][_a-z0-9-]*/i)?ve("qualifier","qualifier"):/[:;{}\[\]\(\)]/.test(K)?ve(null,K):E.match(/^[\w-.]+(?=\()/)?(/^(url(-prefix)?|domain|regexp)$/i.test(E.current())&&(ee.tokenize=Ve),ve("variable callee","variable")):/[\w\\\-]/.test(K)?(E.eatWhile(/[\w\\\-]/),ve("property","word")):ve(null,null)}function qe(E){return function(ee,K){for(var ze=!1,me;(me=ee.next())!=null;){if(me==E&&!ze){E==")"&&ee.backUp(1);break}ze=!ze&&me=="\\"}return(me==E||!ze&&E!=")")&&(K.tokenize=null),ve("string","string")}}function Ve(E,ee){return E.next(),E.match(/^\s*[\"\')]/,!1)?ee.tokenize=null:ee.tokenize=qe(")"),ve(null,"(")}function dt(E,ee,K){this.type=E,this.indent=ee,this.prev=K}function Pe(E,ee,K,ze){return E.context=new dt(K,ee.indentation()+(ze===!1?0:F),E.context),K}function _e(E){return E.context.prev&&(E.context=E.context.prev),E.context.type}function Ue(E,ee,K){return Ie[K.context.type](E,ee,K)}function et(E,ee,K,ze){for(var me=ze||1;me>0;me--)K.context=K.context.prev;return Ue(E,ee,K)}function we(E){var ee=E.current().toLowerCase();fe.hasOwnProperty(ee)?Ce="atom":d.hasOwnProperty(ee)?Ce="keyword":Ce="variable"}var Ie={};return Ie.top=function(E,ee,K){if(E=="{")return Pe(K,ee,"block");if(E=="}"&&K.context.prev)return _e(K);if(xe&&/@component/i.test(E))return Pe(K,ee,"atComponentBlock");if(/^@(-moz-)?document$/i.test(E))return Pe(K,ee,"documentTypes");if(/^@(media|supports|(-moz-)?document|import)$/i.test(E))return Pe(K,ee,"atBlock");if(/^@(font-face|counter-style)/i.test(E))return K.stateArg=E,"restricted_atBlock_before";if(/^@(-(moz|ms|o|webkit)-)?keyframes$/i.test(E))return"keyframes";if(E&&E.charAt(0)=="@")return Pe(K,ee,"at");if(E=="hash")Ce="builtin";else if(E=="word")Ce="tag";else{if(E=="variable-definition")return"maybeprop";if(E=="interpolation")return Pe(K,ee,"interpolation");if(E==":")return"pseudo";if(Te&&E=="(")return Pe(K,ee,"parens")}return K.context.type},Ie.block=function(E,ee,K){if(E=="word"){var ze=ee.current().toLowerCase();return y.hasOwnProperty(ze)?(Ce="property","maybeprop"):j.hasOwnProperty(ze)?(Ce=Me?"string-2":"property","maybeprop"):Te?(Ce=ee.match(/^\s*:(?:\s|$)/,!1)?"property":"tag","block"):(Ce+=" error","maybeprop")}else return E=="meta"?"block":!Te&&(E=="hash"||E=="qualifier")?(Ce="error","block"):Ie.top(E,ee,K)},Ie.maybeprop=function(E,ee,K){return E==":"?Pe(K,ee,"prop"):Ue(E,ee,K)},Ie.prop=function(E,ee,K){if(E==";")return _e(K);if(E=="{"&&Te)return Pe(K,ee,"propBlock");if(E=="}"||E=="{")return et(E,ee,K);if(E=="(")return Pe(K,ee,"parens");if(E=="hash"&&!/^#([0-9a-fA-F]{3,4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$/.test(ee.current()))Ce+=" error";else if(E=="word")we(ee);else if(E=="interpolation")return Pe(K,ee,"interpolation");return"prop"},Ie.propBlock=function(E,ee,K){return E=="}"?_e(K):E=="word"?(Ce="property","maybeprop"):K.context.type},Ie.parens=function(E,ee,K){return E=="{"||E=="}"?et(E,ee,K):E==")"?_e(K):E=="("?Pe(K,ee,"parens"):E=="interpolation"?Pe(K,ee,"interpolation"):(E=="word"&&we(ee),"parens")},Ie.pseudo=function(E,ee,K){return E=="meta"?"pseudo":E=="word"?(Ce="variable-3",K.context.type):Ue(E,ee,K)},Ie.documentTypes=function(E,ee,K){return E=="word"&&c.hasOwnProperty(ee.current())?(Ce="tag",K.context.type):Ie.atBlock(E,ee,K)},Ie.atBlock=function(E,ee,K){if(E=="(")return Pe(K,ee,"atBlock_parens");if(E=="}"||E==";")return et(E,ee,K);if(E=="{")return _e(K)&&Pe(K,ee,Te?"block":"top");if(E=="interpolation")return Pe(K,ee,"interpolation");if(E=="word"){var ze=ee.current().toLowerCase();ze=="only"||ze=="not"||ze=="and"||ze=="or"?Ce="keyword":T.hasOwnProperty(ze)?Ce="attribute":C.hasOwnProperty(ze)?Ce="property":g.hasOwnProperty(ze)?Ce="keyword":y.hasOwnProperty(ze)?Ce="property":j.hasOwnProperty(ze)?Ce=Me?"string-2":"property":fe.hasOwnProperty(ze)?Ce="atom":d.hasOwnProperty(ze)?Ce="keyword":Ce="error"}return K.context.type},Ie.atComponentBlock=function(E,ee,K){return E=="}"?et(E,ee,K):E=="{"?_e(K)&&Pe(K,ee,Te?"block":"top",!1):(E=="word"&&(Ce="error"),K.context.type)},Ie.atBlock_parens=function(E,ee,K){return E==")"?_e(K):E=="{"||E=="}"?et(E,ee,K,2):Ie.atBlock(E,ee,K)},Ie.restricted_atBlock_before=function(E,ee,K){return E=="{"?Pe(K,ee,"restricted_atBlock"):E=="word"&&K.stateArg=="@counter-style"?(Ce="variable","restricted_atBlock_before"):Ue(E,ee,K)},Ie.restricted_atBlock=function(E,ee,K){return E=="}"?(K.stateArg=null,_e(K)):E=="word"?(K.stateArg=="@font-face"&&!de.hasOwnProperty(ee.current().toLowerCase())||K.stateArg=="@counter-style"&&!v.hasOwnProperty(ee.current().toLowerCase())?Ce="error":Ce="property","maybeprop"):"restricted_atBlock"},Ie.keyframes=function(E,ee,K){return E=="word"?(Ce="variable","keyframes"):E=="{"?Pe(K,ee,"top"):Ue(E,ee,K)},Ie.at=function(E,ee,K){return E==";"?_e(K):E=="{"||E=="}"?et(E,ee,K):(E=="word"?Ce="tag":E=="hash"&&(Ce="builtin"),"at")},Ie.interpolation=function(E,ee,K){return E=="}"?_e(K):E=="{"||E==";"?et(E,ee,K):(E=="word"?Ce="variable":E!="variable"&&E!="("&&E!=")"&&(Ce="error"),"interpolation")},{startState:function(E){return{tokenize:null,state:$?"block":"top",stateArg:null,context:new dt($?"block":"top",E||0,null)}},token:function(E,ee){if(!ee.tokenize&&E.eatSpace())return null;var K=(ee.tokenize||Oe)(E,ee);return K&&typeof K=="object"&&(Fe=K[1],K=K[0]),Ce=K,Fe!="comment"&&(ee.state=Ie[ee.state](Fe,E,ee)),Ce},indent:function(E,ee){var K=E.context,ze=ee&&ee.charAt(0),me=K.indent;return K.type=="prop"&&(ze=="}"||ze==")")&&(K=K.prev),K.prev&&(ze=="}"&&(K.type=="block"||K.type=="top"||K.type=="interpolation"||K.type=="restricted_atBlock")?(K=K.prev,me=K.indent):(ze==")"&&(K.type=="parens"||K.type=="atBlock_parens")||ze=="{"&&(K.type=="at"||K.type=="atBlock"))&&(me=Math.max(0,K.indent-F))),me},electricChars:"}",blockCommentStart:"/*",blockCommentEnd:"*/",blockCommentContinue:" * ",lineComment:le,fold:"brace"}});function pe(J){for(var P={},$=0;$")):null:c.match("--")?C(ue("comment","-->")):c.match("DOCTYPE",!0,!0)?(c.eatWhile(/[\w\._\-]/),C(O(1))):null:c.eat("?")?(c.eatWhile(/[\w\._\-]/),T.tokenize=ue("meta","?>"),"meta"):(ne=c.eat("/")?"closeTag":"openTag",T.tokenize=A,"tag bracket");if(g=="&"){var y;return c.eat("#")?c.eat("x")?y=c.eatWhile(/[a-fA-F\d]/)&&c.eat(";"):y=c.eatWhile(/[\d]/)&&c.eat(";"):y=c.eatWhile(/[\w\.\-:]/)&&c.eat(";"),y?"atom":"error"}else return c.eatWhile(/[^&<]/),null}R.isInText=!0;function A(c,T){var C=c.next();if(C==">"||C=="/"&&c.eat(">"))return T.tokenize=R,ne=C==">"?"endTag":"selfcloseTag","tag bracket";if(C=="=")return ne="equals",null;if(C=="<"){T.tokenize=R,T.state=X,T.tagName=T.tagStart=null;var g=T.tokenize(c,T);return g?g+" tag error":"tag error"}else return/[\'\"]/.test(C)?(T.tokenize=V(C),T.stringStartCol=c.column(),T.tokenize(c,T)):(c.match(/^[^\s\u00a0=<>\"\']*[^\s\u00a0=<>\"\'\/]/),"word")}function V(c){var T=function(C,g){for(;!C.eol();)if(C.next()==c){g.tokenize=A;break}return"string"};return T.isInAttribute=!0,T}function ue(c,T){return function(C,g){for(;!C.eol();){if(C.match(T)){g.tokenize=R;break}C.next()}return c}}function O(c){return function(T,C){for(var g;(g=T.next())!=null;){if(g=="<")return C.tokenize=O(c+1),C.tokenize(T,C);if(g==">")if(c==1){C.tokenize=R;break}else return C.tokenize=O(c-1),C.tokenize(T,C)}return"meta"}}function w(c){return c&&c.toLowerCase()}function M(c,T,C){this.prev=c.context,this.tagName=T||"",this.indent=c.indented,this.startOfLine=C,(k.doNotIndent.hasOwnProperty(T)||c.context&&c.context.noIndent)&&(this.noIndent=!0)}function N(c){c.context&&(c.context=c.context.prev)}function z(c,T){for(var C;;){if(!c.context||(C=c.context.tagName,!k.contextGrabbers.hasOwnProperty(w(C))||!k.contextGrabbers[w(C)].hasOwnProperty(w(T))))return;N(c)}}function X(c,T,C){return c=="openTag"?(C.tagStart=T.column(),q):c=="closeTag"?p:X}function q(c,T,C){return c=="word"?(C.tagName=T.current(),S="tag",P):k.allowMissingTagName&&c=="endTag"?(S="tag bracket",P(c,T,C)):(S="error",q)}function p(c,T,C){if(c=="word"){var g=T.current();return C.context&&C.context.tagName!=g&&k.implicitlyClosed.hasOwnProperty(w(C.context.tagName))&&N(C),C.context&&C.context.tagName==g||k.matchClosing===!1?(S="tag",W):(S="tag error",J)}else return k.allowMissingTagName&&c=="endTag"?(S="tag bracket",W(c,T,C)):(S="error",J)}function W(c,T,C){return c!="endTag"?(S="error",W):(N(C),X)}function J(c,T,C){return S="error",W(c,T,C)}function P(c,T,C){if(c=="word")return S="attribute",$;if(c=="endTag"||c=="selfcloseTag"){var g=C.tagName,y=C.tagStart;return C.tagName=C.tagStart=null,c=="selfcloseTag"||k.autoSelfClosers.hasOwnProperty(w(g))?z(C,g):(z(C,g),C.context=new M(C,g,y==C.indented)),X}return S="error",P}function $(c,T,C){return c=="equals"?F:(k.allowMissing||(S="error"),P(c,T,C))}function F(c,T,C){return c=="string"?G:c=="word"&&k.allowUnquoted?(S="string",P):(S="error",P(c,T,C))}function G(c,T,C){return c=="string"?G:P(c,T,C)}return{startState:function(c){var T={tokenize:R,state:X,indented:c||0,tagName:null,tagStart:null,context:null};return c!=null&&(T.baseIndent=c),T},token:function(c,T){if(!T.tagName&&c.sol()&&(T.indented=c.indentation()),c.eatSpace())return null;ne=null;var C=T.tokenize(c,T);return(C||ne)&&C!="comment"&&(S=null,T.state=T.state(ne||C,c,T),S&&(C=S=="error"?C+" error":S)),C},indent:function(c,T,C){var g=c.context;if(c.tokenize.isInAttribute)return c.tagStart==c.indented?c.stringStartCol+1:c.indented+Q;if(g&&g.noIndent)return b.Pass;if(c.tokenize!=A&&c.tokenize!=R)return C?C.match(/^(\s*)/)[0].length:0;if(c.tagName)return k.multilineTagIndentPastTag!==!1?c.tagStart+c.tagName.length+2:c.tagStart+Q*(k.multilineTagIndentFactor||1);if(k.alignCDATA&&/$/,blockCommentStart:"",configuration:k.htmlMode?"html":"xml",helperType:k.htmlMode?"html":"xml",skipAttribute:function(c){c.state==F&&(c.state=P)},xmlCurrentTag:function(c){return c.tagName?{name:c.tagName,close:c.type=="closeTag"}:null},xmlCurrentContext:function(c){for(var T=[],C=c.context;C;C=C.prev)T.push(C.tagName);return T.reverse()}}}),b.defineMIME("text/xml","xml"),b.defineMIME("application/xml","xml"),b.mimeModes.hasOwnProperty("text/html")||b.defineMIME("text/html",{name:"xml",htmlMode:!0})})})()),xa.exports}var ba={exports:{}},ka;function Qa(){return ka||(ka=1,(function(ct,xt){(function(b){b(mt())})(function(b){b.defineMode("javascript",function(pe,_){var te=pe.indentUnit,oe=_.statementIndent,Q=_.jsonld,k=_.json||Q,I=_.trackScope!==!1,Y=_.typescript,ne=_.wordCharacters||/[\w$\xa1-\uffff]/,S=(function(){function f(it){return{type:it,style:"keyword"}}var m=f("keyword a"),U=f("keyword b"),re=f("keyword c"),B=f("keyword d"),ce=f("operator"),We={type:"atom",style:"atom"};return{if:f("if"),while:m,with:m,else:U,do:U,try:U,finally:U,return:B,break:B,continue:B,new:f("new"),delete:re,void:re,throw:re,debugger:f("debugger"),var:f("var"),const:f("var"),let:f("var"),function:f("function"),catch:f("catch"),for:f("for"),switch:f("switch"),case:f("case"),default:f("default"),in:ce,typeof:ce,instanceof:ce,true:We,false:We,null:We,undefined:We,NaN:We,Infinity:We,this:f("this"),class:f("class"),super:f("atom"),yield:re,export:f("export"),import:f("import"),extends:re,await:re}})(),R=/[+\-*&%=<>!?|~^@]/,A=/^@(context|id|value|language|type|container|list|set|reverse|index|base|vocab|graph)"/;function V(f){for(var m=!1,U,re=!1;(U=f.next())!=null;){if(!m){if(U=="/"&&!re)return;U=="["?re=!0:re&&U=="]"&&(re=!1)}m=!m&&U=="\\"}}var ue,O;function w(f,m,U){return ue=f,O=U,m}function M(f,m){var U=f.next();if(U=='"'||U=="'")return m.tokenize=N(U),m.tokenize(f,m);if(U=="."&&f.match(/^\d[\d_]*(?:[eE][+\-]?[\d_]+)?/))return w("number","number");if(U=="."&&f.match(".."))return w("spread","meta");if(/[\[\]{}\(\),;\:\.]/.test(U))return w(U);if(U=="="&&f.eat(">"))return w("=>","operator");if(U=="0"&&f.match(/^(?:x[\dA-Fa-f_]+|o[0-7_]+|b[01_]+)n?/))return w("number","number");if(/\d/.test(U))return f.match(/^[\d_]*(?:n|(?:\.[\d_]*)?(?:[eE][+\-]?[\d_]+)?)?/),w("number","number");if(U=="/")return f.eat("*")?(m.tokenize=z,z(f,m)):f.eat("/")?(f.skipToEnd(),w("comment","comment")):Et(f,m,1)?(V(f),f.match(/^\b(([gimyus])(?![gimyus]*\2))+\b/),w("regexp","string-2")):(f.eat("="),w("operator","operator",f.current()));if(U=="`")return m.tokenize=X,X(f,m);if(U=="#"&&f.peek()=="!")return f.skipToEnd(),w("meta","meta");if(U=="#"&&f.eatWhile(ne))return w("variable","property");if(U=="<"&&f.match("!--")||U=="-"&&f.match("->")&&!/\S/.test(f.string.slice(0,f.start)))return f.skipToEnd(),w("comment","comment");if(R.test(U))return(U!=">"||!m.lexical||m.lexical.type!=">")&&(f.eat("=")?(U=="!"||U=="=")&&f.eat("="):/[<>*+\-|&?]/.test(U)&&(f.eat(U),U==">"&&f.eat(U))),U=="?"&&f.eat(".")?w("."):w("operator","operator",f.current());if(ne.test(U)){f.eatWhile(ne);var re=f.current();if(m.lastType!="."){if(S.propertyIsEnumerable(re)){var B=S[re];return w(B.type,B.style,re)}if(re=="async"&&f.match(/^(\s|\/\*([^*]|\*(?!\/))*?\*\/)*[\[\(\w]/,!1))return w("async","keyword",re)}return w("variable","variable",re)}}function N(f){return function(m,U){var re=!1,B;if(Q&&m.peek()=="@"&&m.match(A))return U.tokenize=M,w("jsonld-keyword","meta");for(;(B=m.next())!=null&&!(B==f&&!re);)re=!re&&B=="\\";return re||(U.tokenize=M),w("string","string")}}function z(f,m){for(var U=!1,re;re=f.next();){if(re=="/"&&U){m.tokenize=M;break}U=re=="*"}return w("comment","comment")}function X(f,m){for(var U=!1,re;(re=f.next())!=null;){if(!U&&(re=="`"||re=="$"&&f.eat("{"))){m.tokenize=M;break}U=!U&&re=="\\"}return w("quasi","string-2",f.current())}var q="([{}])";function p(f,m){m.fatArrowAt&&(m.fatArrowAt=null);var U=f.string.indexOf("=>",f.start);if(!(U<0)){if(Y){var re=/:\s*(?:\w+(?:<[^>]*>|\[\])?|\{[^}]*\})\s*$/.exec(f.string.slice(f.start,U));re&&(U=re.index)}for(var B=0,ce=!1,We=U-1;We>=0;--We){var it=f.string.charAt(We),wt=q.indexOf(it);if(wt>=0&&wt<3){if(!B){++We;break}if(--B==0){it=="("&&(ce=!0);break}}else if(wt>=3&&wt<6)++B;else if(ne.test(it))ce=!0;else if(/["'\/`]/.test(it))for(;;--We){if(We==0)return;var Wr=f.string.charAt(We-1);if(Wr==it&&f.string.charAt(We-2)!="\\"){We--;break}}else if(ce&&!B){++We;break}}ce&&!B&&(m.fatArrowAt=We)}}var W={atom:!0,number:!0,variable:!0,string:!0,regexp:!0,this:!0,import:!0,"jsonld-keyword":!0};function J(f,m,U,re,B,ce){this.indented=f,this.column=m,this.type=U,this.prev=B,this.info=ce,re!=null&&(this.align=re)}function P(f,m){if(!I)return!1;for(var U=f.localVars;U;U=U.next)if(U.name==m)return!0;for(var re=f.context;re;re=re.prev)for(var U=re.vars;U;U=U.next)if(U.name==m)return!0}function $(f,m,U,re,B){var ce=f.cc;for(F.state=f,F.stream=B,F.marked=null,F.cc=ce,F.style=m,f.lexical.hasOwnProperty("align")||(f.lexical.align=!0);;){var We=ce.length?ce.pop():k?ve:Fe;if(We(U,re)){for(;ce.length&&ce[ce.length-1].lex;)ce.pop()();return F.marked?F.marked:U=="variable"&&P(f,re)?"variable-2":m}}}var F={state:null,marked:null,cc:null};function G(){for(var f=arguments.length-1;f>=0;f--)F.cc.push(arguments[f])}function c(){return G.apply(null,arguments),!0}function T(f,m){for(var U=m;U;U=U.next)if(U.name==f)return!0;return!1}function C(f){var m=F.state;if(F.marked="def",!!I){if(m.context){if(m.lexical.info=="var"&&m.context&&m.context.block){var U=g(f,m.context);if(U!=null){m.context=U;return}}else if(!T(f,m.localVars)){m.localVars=new de(f,m.localVars);return}}_.globalVars&&!T(f,m.globalVars)&&(m.globalVars=new de(f,m.globalVars))}}function g(f,m){if(m)if(m.block){var U=g(f,m.prev);return U?U==m.prev?m:new j(U,m.vars,!0):null}else return T(f,m.vars)?m:new j(m.prev,new de(f,m.vars),!1);else return null}function y(f){return f=="public"||f=="private"||f=="protected"||f=="abstract"||f=="readonly"}function j(f,m,U){this.prev=f,this.vars=m,this.block=U}function de(f,m){this.name=f,this.next=m}var v=new de("this",new de("arguments",null));function d(){F.state.context=new j(F.state.context,F.state.localVars,!1),F.state.localVars=v}function fe(){F.state.context=new j(F.state.context,F.state.localVars,!0),F.state.localVars=null}d.lex=fe.lex=!0;function Te(){F.state.localVars=F.state.context.vars,F.state.context=F.state.context.prev}Te.lex=!0;function le(f,m){var U=function(){var re=F.state,B=re.indented;if(re.lexical.type=="stat")B=re.lexical.indented;else for(var ce=re.lexical;ce&&ce.type==")"&&ce.align;ce=ce.prev)B=ce.indented;re.lexical=new J(B,F.stream.column(),f,null,re.lexical,m)};return U.lex=!0,U}function xe(){var f=F.state;f.lexical.prev&&(f.lexical.type==")"&&(f.indented=f.lexical.indented),f.lexical=f.lexical.prev)}xe.lex=!0;function Me(f){function m(U){return U==f?c():f==";"||U=="}"||U==")"||U=="]"?G():c(m)}return m}function Fe(f,m){return f=="var"?c(le("vardef",m),Er,Me(";"),xe):f=="keyword a"?c(le("form"),qe,Fe,xe):f=="keyword b"?c(le("form"),Fe,xe):f=="keyword d"?F.stream.match(/^\s*$/,!1)?c():c(le("stat"),dt,Me(";"),xe):f=="debugger"?c(Me(";")):f=="{"?c(le("}"),fe,Pt,xe,Te):f==";"?c():f=="if"?(F.state.lexical.info=="else"&&F.state.cc[F.state.cc.length-1]==xe&&F.state.cc.pop()(),c(le("form"),qe,Fe,xe,Or)):f=="function"?c(zt):f=="for"?c(le("form"),fe,Rn,Fe,Te,xe):f=="class"||Y&&m=="interface"?(F.marked="keyword",c(le("form",f=="class"?f:m),Pr,xe)):f=="variable"?Y&&m=="declare"?(F.marked="keyword",c(Fe)):Y&&(m=="module"||m=="enum"||m=="type")&&F.stream.match(/^\s*\w/,!1)?(F.marked="keyword",m=="enum"?c(ye):m=="type"?c(Wn,Me("operator"),Re,Me(";")):c(le("form"),kt,Me("{"),le("}"),Pt,xe,xe)):Y&&m=="namespace"?(F.marked="keyword",c(le("form"),ve,Fe,xe)):Y&&m=="abstract"?(F.marked="keyword",c(Fe)):c(le("stat"),ze):f=="switch"?c(le("form"),qe,Me("{"),le("}","switch"),fe,Pt,xe,xe,Te):f=="case"?c(ve,Me(":")):f=="default"?c(Me(":")):f=="catch"?c(le("form"),d,Ce,Fe,xe,Te):f=="export"?c(le("stat"),Ir,xe):f=="import"?c(le("stat"),fr,xe):f=="async"?c(Fe):m=="@"?c(ve,Fe):G(le("stat"),ve,Me(";"),xe)}function Ce(f){if(f=="(")return c(Wt,Me(")"))}function ve(f,m){return Ve(f,m,!1)}function Oe(f,m){return Ve(f,m,!0)}function qe(f){return f!="("?G():c(le(")"),dt,Me(")"),xe)}function Ve(f,m,U){if(F.state.fatArrowAt==F.stream.start){var re=U?Ie:we;if(f=="(")return c(d,le(")"),Ne(Wt,")"),xe,Me("=>"),re,Te);if(f=="variable")return G(d,kt,Me("=>"),re,Te)}var B=U?_e:Pe;return W.hasOwnProperty(f)?c(B):f=="function"?c(zt,B):f=="class"||Y&&m=="interface"?(F.marked="keyword",c(le("form"),yi,xe)):f=="keyword c"||f=="async"?c(U?Oe:ve):f=="("?c(le(")"),dt,Me(")"),xe,B):f=="operator"||f=="spread"?c(U?Oe:ve):f=="["?c(le("]"),Je,xe,B):f=="{"?Mt(De,"}",null,B):f=="quasi"?G(Ue,B):f=="new"?c(E(U)):c()}function dt(f){return f.match(/[;\}\)\],]/)?G():G(ve)}function Pe(f,m){return f==","?c(dt):_e(f,m,!1)}function _e(f,m,U){var re=U==!1?Pe:_e,B=U==!1?ve:Oe;if(f=="=>")return c(d,U?Ie:we,Te);if(f=="operator")return/\+\+|--/.test(m)||Y&&m=="!"?c(re):Y&&m=="<"&&F.stream.match(/^([^<>]|<[^<>]*>)*>\s*\(/,!1)?c(le(">"),Ne(Re,">"),xe,re):m=="?"?c(ve,Me(":"),B):c(B);if(f=="quasi")return G(Ue,re);if(f!=";"){if(f=="(")return Mt(Oe,")","call",re);if(f==".")return c(me,re);if(f=="[")return c(le("]"),dt,Me("]"),xe,re);if(Y&&m=="as")return F.marked="keyword",c(Re,re);if(f=="regexp")return F.state.lastType=F.marked="operator",F.stream.backUp(F.stream.pos-F.stream.start-1),c(B)}}function Ue(f,m){return f!="quasi"?G():m.slice(m.length-2)!="${"?c(Ue):c(dt,et)}function et(f){if(f=="}")return F.marked="string-2",F.state.tokenize=X,c(Ue)}function we(f){return p(F.stream,F.state),G(f=="{"?Fe:ve)}function Ie(f){return p(F.stream,F.state),G(f=="{"?Fe:Oe)}function E(f){return function(m){return m=="."?c(f?K:ee):m=="variable"&&Y?c(Ft,f?_e:Pe):G(f?Oe:ve)}}function ee(f,m){if(m=="target")return F.marked="keyword",c(Pe)}function K(f,m){if(m=="target")return F.marked="keyword",c(_e)}function ze(f){return f==":"?c(xe,Fe):G(Pe,Me(";"),xe)}function me(f){if(f=="variable")return F.marked="property",c()}function De(f,m){if(f=="async")return F.marked="property",c(De);if(f=="variable"||F.style=="keyword"){if(F.marked="property",m=="get"||m=="set")return c(be);var U;return Y&&F.state.fatArrowAt==F.stream.start&&(U=F.stream.match(/^\s*:\s*/,!1))&&(F.state.fatArrowAt=F.stream.pos+U[0].length),c(Be)}else{if(f=="number"||f=="string")return F.marked=Q?"property":F.style+" property",c(Be);if(f=="jsonld-keyword")return c(Be);if(Y&&y(m))return F.marked="keyword",c(De);if(f=="[")return c(ve,or,Me("]"),Be);if(f=="spread")return c(Oe,Be);if(m=="*")return F.marked="keyword",c(De);if(f==":")return G(Be)}}function be(f){return f!="variable"?G(Be):(F.marked="property",c(zt))}function Be(f){if(f==":")return c(Oe);if(f=="(")return G(zt)}function Ne(f,m,U){function re(B,ce){if(U?U.indexOf(B)>-1:B==","){var We=F.state.lexical;return We.info=="call"&&(We.pos=(We.pos||0)+1),c(function(it,wt){return it==m||wt==m?G():G(f)},re)}return B==m||ce==m?c():U&&U.indexOf(";")>-1?G(f):c(Me(m))}return function(B,ce){return B==m||ce==m?c():G(f,re)}}function Mt(f,m,U){for(var re=3;re"),Re);if(f=="quasi")return G(ht,It)}function Bn(f){if(f=="=>")return c(Re)}function Se(f){return f.match(/[\}\)\]]/)?c():f==","||f==";"?c(Se):G(Zt,Se)}function Zt(f,m){if(f=="variable"||F.style=="keyword")return F.marked="property",c(Zt);if(m=="?"||f=="number"||f=="string")return c(Zt);if(f==":")return c(Re);if(f=="[")return c(Me("variable"),br,Me("]"),Zt);if(f=="(")return G(ur,Zt);if(!f.match(/[;\}\)\],]/))return c()}function ht(f,m){return f!="quasi"?G():m.slice(m.length-2)!="${"?c(ht):c(Re,Ye)}function Ye(f){if(f=="}")return F.marked="string-2",F.state.tokenize=X,c(ht)}function Qe(f,m){return f=="variable"&&F.stream.match(/^\s*[?:]/,!1)||m=="?"?c(Qe):f==":"?c(Re):f=="spread"?c(Qe):G(Re)}function It(f,m){if(m=="<")return c(le(">"),Ne(Re,">"),xe,It);if(m=="|"||f=="."||m=="&")return c(Re);if(f=="[")return c(Re,Me("]"),It);if(m=="extends"||m=="implements")return F.marked="keyword",c(Re);if(m=="?")return c(Re,Me(":"),Re)}function Ft(f,m){if(m=="<")return c(le(">"),Ne(Re,">"),xe,It)}function Bt(){return G(Re,pt)}function pt(f,m){if(m=="=")return c(Re)}function Er(f,m){return m=="enum"?(F.marked="keyword",c(ye)):G(kt,or,Rt,xi)}function kt(f,m){if(Y&&y(m))return F.marked="keyword",c(kt);if(f=="variable")return C(m),c();if(f=="spread")return c(kt);if(f=="[")return Mt(ln,"]");if(f=="{")return Mt(ar,"}")}function ar(f,m){return f=="variable"&&!F.stream.match(/^\s*:/,!1)?(C(m),c(Rt)):(f=="variable"&&(F.marked="property"),f=="spread"?c(kt):f=="}"?G():f=="["?c(ve,Me("]"),Me(":"),ar):c(Me(":"),kt,Rt))}function ln(){return G(kt,Rt)}function Rt(f,m){if(m=="=")return c(Oe)}function xi(f){if(f==",")return c(Er)}function Or(f,m){if(f=="keyword b"&&m=="else")return c(le("form","else"),Fe,xe)}function Rn(f,m){if(m=="await")return c(Rn);if(f=="(")return c(le(")"),an,xe)}function an(f){return f=="var"?c(Er,sr):f=="variable"?c(sr):G(sr)}function sr(f,m){return f==")"?c():f==";"?c(sr):m=="in"||m=="of"?(F.marked="keyword",c(ve,sr)):G(ve,sr)}function zt(f,m){if(m=="*")return F.marked="keyword",c(zt);if(f=="variable")return C(m),c(zt);if(f=="(")return c(d,le(")"),Ne(Wt,")"),xe,lr,Fe,Te);if(Y&&m=="<")return c(le(">"),Ne(Bt,">"),xe,zt)}function ur(f,m){if(m=="*")return F.marked="keyword",c(ur);if(f=="variable")return C(m),c(ur);if(f=="(")return c(d,le(")"),Ne(Wt,")"),xe,lr,Te);if(Y&&m=="<")return c(le(">"),Ne(Bt,">"),xe,ur)}function Wn(f,m){if(f=="keyword"||f=="variable")return F.marked="type",c(Wn);if(m=="<")return c(le(">"),Ne(Bt,">"),xe)}function Wt(f,m){return m=="@"&&c(ve,Wt),f=="spread"?c(Wt):Y&&y(m)?(F.marked="keyword",c(Wt)):Y&&f=="this"?c(or,Rt):G(kt,or,Rt)}function yi(f,m){return f=="variable"?Pr(f,m):Ht(f,m)}function Pr(f,m){if(f=="variable")return C(m),c(Ht)}function Ht(f,m){if(m=="<")return c(le(">"),Ne(Bt,">"),xe,Ht);if(m=="extends"||m=="implements"||Y&&f==",")return m=="implements"&&(F.marked="keyword"),c(Y?Re:ve,Ht);if(f=="{")return c(le("}"),_t,xe)}function _t(f,m){if(f=="async"||f=="variable"&&(m=="static"||m=="get"||m=="set"||Y&&y(m))&&F.stream.match(/^\s+#?[\w$\xa1-\uffff]/,!1))return F.marked="keyword",c(_t);if(f=="variable"||F.style=="keyword")return F.marked="property",c(kr,_t);if(f=="number"||f=="string")return c(kr,_t);if(f=="[")return c(ve,or,Me("]"),kr,_t);if(m=="*")return F.marked="keyword",c(_t);if(Y&&f=="(")return G(ur,_t);if(f==";"||f==",")return c(_t);if(f=="}")return c();if(m=="@")return c(ve,_t)}function kr(f,m){if(m=="!"||m=="?")return c(kr);if(f==":")return c(Re,Rt);if(m=="=")return c(Oe);var U=F.state.lexical.prev,re=U&&U.info=="interface";return G(re?ur:zt)}function Ir(f,m){return m=="*"?(F.marked="keyword",c(Rr,Me(";"))):m=="default"?(F.marked="keyword",c(ve,Me(";"))):f=="{"?c(Ne(zr,"}"),Rr,Me(";")):G(Fe)}function zr(f,m){if(m=="as")return F.marked="keyword",c(Me("variable"));if(f=="variable")return G(Oe,zr)}function fr(f){return f=="string"?c():f=="("?G(ve):f=="."?G(Pe):G(Br,Gt,Rr)}function Br(f,m){return f=="{"?Mt(Br,"}"):(f=="variable"&&C(m),m=="*"&&(F.marked="keyword"),c(sn))}function Gt(f){if(f==",")return c(Br,Gt)}function sn(f,m){if(m=="as")return F.marked="keyword",c(Br)}function Rr(f,m){if(m=="from")return F.marked="keyword",c(ve)}function Je(f){return f=="]"?c():G(Ne(Oe,"]"))}function ye(){return G(le("form"),kt,Me("{"),le("}"),Ne(Vt,"}"),xe,xe)}function Vt(){return G(kt,Rt)}function un(f,m){return f.lastType=="operator"||f.lastType==","||R.test(m.charAt(0))||/[,.]/.test(m.charAt(0))}function Et(f,m,U){return m.tokenize==M&&/^(?:operator|sof|keyword [bcd]|case|new|export|default|spread|[\[{}\(,;:]|=>)$/.test(m.lastType)||m.lastType=="quasi"&&/\{\s*$/.test(f.string.slice(0,f.pos-(U||0)))}return{startState:function(f){var m={tokenize:M,lastType:"sof",cc:[],lexical:new J((f||0)-te,0,"block",!1),localVars:_.localVars,context:_.localVars&&new j(null,null,!1),indented:f||0};return _.globalVars&&typeof _.globalVars=="object"&&(m.globalVars=_.globalVars),m},token:function(f,m){if(f.sol()&&(m.lexical.hasOwnProperty("align")||(m.lexical.align=!1),m.indented=f.indentation(),p(f,m)),m.tokenize!=z&&f.eatSpace())return null;var U=m.tokenize(f,m);return ue=="comment"?U:(m.lastType=ue=="operator"&&(O=="++"||O=="--")?"incdec":ue,$(m,U,ue,O,f))},indent:function(f,m){if(f.tokenize==z||f.tokenize==X)return b.Pass;if(f.tokenize!=M)return 0;var U=m&&m.charAt(0),re=f.lexical,B;if(!/^\s*else\b/.test(m))for(var ce=f.cc.length-1;ce>=0;--ce){var We=f.cc[ce];if(We==xe)re=re.prev;else if(We!=Or&&We!=Te)break}for(;(re.type=="stat"||re.type=="form")&&(U=="}"||(B=f.cc[f.cc.length-1])&&(B==Pe||B==_e)&&!/^[,\.=+\-*:?[\(]/.test(m));)re=re.prev;oe&&re.type==")"&&re.prev.type=="stat"&&(re=re.prev);var it=re.type,wt=U==it;return it=="vardef"?re.indented+(f.lastType=="operator"||f.lastType==","?re.info.length+1:0):it=="form"&&U=="{"?re.indented:it=="form"?re.indented+te:it=="stat"?re.indented+(un(f,m)?oe||te:0):re.info=="switch"&&!wt&&_.doubleIndentSwitch!=!1?re.indented+(/^(?:case|default)\b/.test(m)?te:2*te):re.align?re.column+(wt?0:1):re.indented+(wt?0:te)},electricInput:/^\s*(?:case .*?:|default:|\{|\})$/,blockCommentStart:k?null:"/*",blockCommentEnd:k?null:"*/",blockCommentContinue:k?null:" * ",lineComment:k?null:"//",fold:"brace",closeBrackets:"()[]{}''\"\"``",helperType:k?"json":"javascript",jsonldMode:Q,jsonMode:k,expressionAllowed:Et,skipExpression:function(f){$(f,"atom","atom","true",new b.StringStream("",2,null))}}}),b.registerHelper("wordChars","javascript",/[\w$]/),b.defineMIME("text/javascript","javascript"),b.defineMIME("text/ecmascript","javascript"),b.defineMIME("application/javascript","javascript"),b.defineMIME("application/x-javascript","javascript"),b.defineMIME("application/ecmascript","javascript"),b.defineMIME("application/json",{name:"javascript",json:!0}),b.defineMIME("application/x-json",{name:"javascript",json:!0}),b.defineMIME("application/manifest+json",{name:"javascript",json:!0}),b.defineMIME("application/ld+json",{name:"javascript",jsonld:!0}),b.defineMIME("text/typescript",{name:"javascript",typescript:!0}),b.defineMIME("application/typescript",{name:"javascript",typescript:!0})})})()),ba.exports}var wa;function $u(){return wa||(wa=1,(function(ct,xt){(function(b){b(mt(),Ya(),Qa(),Xa())})(function(b){var pe={script:[["lang",/(javascript|babel)/i,"javascript"],["type",/^(?:text|application)\/(?:x-)?(?:java|ecma)script$|^module$|^$/i,"javascript"],["type",/./,"text/plain"],[null,null,"javascript"]],style:[["lang",/^css$/i,"css"],["type",/^(text\/)?(x-)?(stylesheet|css)$/i,"css"],["type",/./,"text/plain"],[null,null,"css"]]};function _(ne,S,R){var A=ne.current(),V=A.search(S);return V>-1?ne.backUp(A.length-V):A.match(/<\/?$/)&&(ne.backUp(A.length),ne.match(S,!1)||ne.match(A)),R}var te={};function oe(ne){var S=te[ne];return S||(te[ne]=new RegExp("\\s+"+ne+`\\s*=\\s*('|")?([^'"]+)('|")?\\s*`))}function Q(ne,S){var R=ne.match(oe(S));return R?/^\s*(.*?)\s*$/.exec(R[2])[1]:""}function k(ne,S){return new RegExp((S?"^":"")+"","i")}function I(ne,S){for(var R in ne)for(var A=S[R]||(S[R]=[]),V=ne[R],ue=V.length-1;ue>=0;ue--)A.unshift(V[ue])}function Y(ne,S){for(var R=0;R=0;O--)A.script.unshift(["type",ue[O].matches,ue[O].mode]);function w(M,N){var z=R.token(M,N.htmlState),X=/\btag\b/.test(z),q;if(X&&!/[<>\s\/]/.test(M.current())&&(q=N.htmlState.tagName&&N.htmlState.tagName.toLowerCase())&&A.hasOwnProperty(q))N.inTag=q+" ";else if(N.inTag&&X&&/>$/.test(M.current())){var p=/^([\S]+) (.*)/.exec(N.inTag);N.inTag=null;var W=M.current()==">"&&Y(A[p[1]],p[2]),J=b.getMode(ne,W),P=k(p[1],!0),$=k(p[1],!1);N.token=function(F,G){return F.match(P,!1)?(G.token=w,G.localState=G.localMode=null,null):_(F,$,G.localMode.token(F,G.localState))},N.localMode=J,N.localState=b.startState(J,R.indent(N.htmlState,"",""))}else N.inTag&&(N.inTag+=M.current(),M.eol()&&(N.inTag+=" "));return z}return{startState:function(){var M=b.startState(R);return{token:w,inTag:null,localMode:null,localState:null,htmlState:M}},copyState:function(M){var N;return M.localState&&(N=b.copyState(M.localMode,M.localState)),{token:M.token,inTag:M.inTag,localMode:M.localMode,localState:N,htmlState:b.copyState(R,M.htmlState)}},token:function(M,N){return N.token(M,N)},indent:function(M,N,z){return!M.localMode||/^\s*<\//.test(N)?R.indent(M.htmlState,N,z):M.localMode.indent?M.localMode.indent(M.localState,N,z):b.Pass},innerMode:function(M){return{state:M.localState||M.htmlState,mode:M.localMode||R}}}},"xml","javascript","css"),b.defineMIME("text/html","htmlmixed")})})()),ma.exports}$u();Qa();var Sa={exports:{}},La;function ef(){return La||(La=1,(function(ct,xt){(function(b){b(mt())})(function(b){function pe(I){return new RegExp("^(("+I.join(")|(")+"))\\b")}var _=pe(["and","or","not","is"]),te=["as","assert","break","class","continue","def","del","elif","else","except","finally","for","from","global","if","import","lambda","pass","raise","return","try","while","with","yield","in","False","True"],oe=["abs","all","any","bin","bool","bytearray","callable","chr","classmethod","compile","complex","delattr","dict","dir","divmod","enumerate","eval","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","property","range","repr","reversed","round","set","setattr","slice","sorted","staticmethod","str","sum","super","tuple","type","vars","zip","__import__","NotImplemented","Ellipsis","__debug__"];b.registerHelper("hintWords","python",te.concat(oe).concat(["exec","print"]));function Q(I){return I.scopes[I.scopes.length-1]}b.defineMode("python",function(I,Y){for(var ne="error",S=Y.delimiters||Y.singleDelimiters||/^[\(\)\[\]\{\}@,:`=;\.\\]/,R=[Y.singleOperators,Y.doubleOperators,Y.doubleDelimiters,Y.tripleDelimiters,Y.operators||/^([-+*/%\/&|^]=?|[<>=]+|\/\/=?|\*\*=?|!=|[~!@]|\.\.\.)/],A=0;Ay?P(C):j0&&F(T,C)&&(de+=" "+ne),de}}return p(T,C)}function p(T,C,g){if(T.eatSpace())return null;if(!g&&T.match(/^#.*/))return"comment";if(T.match(/^[0-9\.]/,!1)){var y=!1;if(T.match(/^[\d_]*\.\d+(e[\+\-]?\d+)?/i)&&(y=!0),T.match(/^[\d_]+\.\d*/)&&(y=!0),T.match(/^\.\d+/)&&(y=!0),y)return T.eat(/J/i),"number";var j=!1;if(T.match(/^0x[0-9a-f_]+/i)&&(j=!0),T.match(/^0b[01_]+/i)&&(j=!0),T.match(/^0o[0-7_]+/i)&&(j=!0),T.match(/^[1-9][\d_]*(e[\+\-]?[\d_]+)?/)&&(T.eat(/J/i),j=!0),T.match(/^0(?![\dx])/i)&&(j=!0),j)return T.eat(/L/i),"number"}if(T.match(N)){var de=T.current().toLowerCase().indexOf("f")!==-1;return de?(C.tokenize=W(T.current(),C.tokenize),C.tokenize(T,C)):(C.tokenize=J(T.current(),C.tokenize),C.tokenize(T,C))}for(var v=0;v=0;)T=T.substr(1);var g=T.length==1,y="string";function j(v){return function(d,fe){var Te=p(d,fe,!0);return Te=="punctuation"&&(d.current()=="{"?fe.tokenize=j(v+1):d.current()=="}"&&(v>1?fe.tokenize=j(v-1):fe.tokenize=de)),Te}}function de(v,d){for(;!v.eol();)if(v.eatWhile(/[^'"\{\}\\]/),v.eat("\\")){if(v.next(),g&&v.eol())return y}else{if(v.match(T))return d.tokenize=C,y;if(v.match("{{"))return y;if(v.match("{",!1))return d.tokenize=j(0),v.current()?y:d.tokenize(v,d);if(v.match("}}"))return y;if(v.match("}"))return ne;v.eat(/['"]/)}if(g){if(Y.singleLineStringErrors)return ne;d.tokenize=C}return y}return de.isString=!0,de}function J(T,C){for(;"rubf".indexOf(T.charAt(0).toLowerCase())>=0;)T=T.substr(1);var g=T.length==1,y="string";function j(de,v){for(;!de.eol();)if(de.eatWhile(/[^'"\\]/),de.eat("\\")){if(de.next(),g&&de.eol())return y}else{if(de.match(T))return v.tokenize=C,y;de.eat(/['"]/)}if(g){if(Y.singleLineStringErrors)return ne;v.tokenize=C}return y}return j.isString=!0,j}function P(T){for(;Q(T).type!="py";)T.scopes.pop();T.scopes.push({offset:Q(T).offset+I.indentUnit,type:"py",align:null})}function $(T,C,g){var y=T.match(/^[\s\[\{\(]*(?:#|$)/,!1)?null:T.column()+1;C.scopes.push({offset:C.indent+V,type:g,align:y})}function F(T,C){for(var g=T.indentation();C.scopes.length>1&&Q(C).offset>g;){if(Q(C).type!="py")return!0;C.scopes.pop()}return Q(C).offset!=g}function G(T,C){T.sol()&&(C.beginningOfLine=!0,C.dedent=!1);var g=C.tokenize(T,C),y=T.current();if(C.beginningOfLine&&y=="@")return T.match(M,!1)?"meta":w?"operator":ne;if(/\S/.test(y)&&(C.beginningOfLine=!1),(g=="variable"||g=="builtin")&&C.lastToken=="meta"&&(g="meta"),(y=="pass"||y=="return")&&(C.dedent=!0),y=="lambda"&&(C.lambda=!0),y==":"&&!C.lambda&&Q(C).type=="py"&&T.match(/^\s*(?:#|$)/,!1)&&P(C),y.length==1&&!/string|comment/.test(g)){var j="[({".indexOf(y);if(j!=-1&&$(T,C,"])}".slice(j,j+1)),j="])}".indexOf(y),j!=-1)if(Q(C).type==y)C.indent=C.scopes.pop().offset-V;else return ne}return C.dedent&&T.eol()&&Q(C).type=="py"&&C.scopes.length>1&&C.scopes.pop(),g}var c={startState:function(T){return{tokenize:q,scopes:[{offset:T||0,type:"py",align:null}],indent:T||0,lastToken:null,lambda:!1,dedent:0}},token:function(T,C){var g=C.errorToken;g&&(C.errorToken=!1);var y=G(T,C);return y&&y!="comment"&&(C.lastToken=y=="keyword"||y=="punctuation"?T.current():y),y=="punctuation"&&(y=null),T.eol()&&C.lambda&&(C.lambda=!1),g?y+" "+ne:y},indent:function(T,C){if(T.tokenize!=q)return T.tokenize.isString?b.Pass:0;var g=Q(T),y=g.type==C.charAt(0)||g.type=="py"&&!T.dedent&&/^(else:|elif |except |finally:)/.test(C);return g.align!=null?g.align-(y?1:0):g.offset-(y?V:0)},electricInput:/^\s*([\}\]\)]|else:|elif |except |finally:)$/,closeBrackets:{triples:`'"`},lineComment:"#",fold:"indent"};return c}),b.defineMIME("text/x-python","python");var k=function(I){return I.split(" ")};b.defineMIME("text/x-cython",{name:"python",extra_keywords:k("by cdef cimport cpdef ctypedef enum except extern gil include nogil property public readonly struct union DEF IF ELIF ELSE")})})})()),Sa.exports}ef();var Ta={exports:{}},Ca;function tf(){return Ca||(Ca=1,(function(ct,xt){(function(b){b(mt())})(function(b){function pe(g,y,j,de,v,d){this.indented=g,this.column=y,this.type=j,this.info=de,this.align=v,this.prev=d}function _(g,y,j,de){var v=g.indented;return g.context&&g.context.type=="statement"&&j!="statement"&&(v=g.context.indented),g.context=new pe(v,y,j,de,null,g.context)}function te(g){var y=g.context.type;return(y==")"||y=="]"||y=="}")&&(g.indented=g.context.indented),g.context=g.context.prev}function oe(g,y,j){if(y.prevToken=="variable"||y.prevToken=="type"||/\S(?:[^- ]>|[*\]])\s*$|\*$/.test(g.string.slice(0,j))||y.typeAtEndOfLine&&g.column()==g.indentation())return!0}function Q(g){for(;;){if(!g||g.type=="top")return!0;if(g.type=="}"&&g.prev.info!="namespace")return!1;g=g.prev}}b.defineMode("clike",function(g,y){var j=g.indentUnit,de=y.statementIndentUnit||j,v=y.dontAlignCalls,d=y.keywords||{},fe=y.types||{},Te=y.builtin||{},le=y.blockKeywords||{},xe=y.defKeywords||{},Me=y.atoms||{},Fe=y.hooks||{},Ce=y.multiLineStrings,ve=y.indentStatements!==!1,Oe=y.indentSwitch!==!1,qe=y.namespaceSeparator,Ve=y.isPunctuationChar||/[\[\]{}\(\),;\:\.]/,dt=y.numberStart||/[\d\.]/,Pe=y.number||/^(?:0x[a-f\d]+|0b[01]+|(?:\d+\.?\d*|\.\d+)(?:e[-+]?\d+)?)(u|ll?|l|f)?/i,_e=y.isOperatorChar||/[+\-*&%=<>!?|\/]/,Ue=y.isIdentifierChar||/[\w\$_\xa1-\uffff]/,et=y.isReservedIdentifier||!1,we,Ie;function E(me,De){var be=me.next();if(Fe[be]){var Be=Fe[be](me,De);if(Be!==!1)return Be}if(be=='"'||be=="'")return De.tokenize=ee(be),De.tokenize(me,De);if(dt.test(be)){if(me.backUp(1),me.match(Pe))return"number";me.next()}if(Ve.test(be))return we=be,null;if(be=="/"){if(me.eat("*"))return De.tokenize=K,K(me,De);if(me.eat("/"))return me.skipToEnd(),"comment"}if(_e.test(be)){for(;!me.match(/^\/[\/*]/,!1)&&me.eat(_e););return"operator"}if(me.eatWhile(Ue),qe)for(;me.match(qe);)me.eatWhile(Ue);var Ne=me.current();return I(d,Ne)?(I(le,Ne)&&(we="newstatement"),I(xe,Ne)&&(Ie=!0),"keyword"):I(fe,Ne)?"type":I(Te,Ne)||et&&et(Ne)?(I(le,Ne)&&(we="newstatement"),"builtin"):I(Me,Ne)?"atom":"variable"}function ee(me){return function(De,be){for(var Be=!1,Ne,Mt=!1;(Ne=De.next())!=null;){if(Ne==me&&!Be){Mt=!0;break}Be=!Be&&Ne=="\\"}return(Mt||!(Be||Ce))&&(be.tokenize=null),"string"}}function K(me,De){for(var be=!1,Be;Be=me.next();){if(Be=="/"&&be){De.tokenize=null;break}be=Be=="*"}return"comment"}function ze(me,De){y.typeFirstDefinitions&&me.eol()&&Q(De.context)&&(De.typeAtEndOfLine=oe(me,De,me.pos))}return{startState:function(me){return{tokenize:null,context:new pe((me||0)-j,0,"top",null,!1),indented:0,startOfLine:!0,prevToken:null}},token:function(me,De){var be=De.context;if(me.sol()&&(be.align==null&&(be.align=!1),De.indented=me.indentation(),De.startOfLine=!0),me.eatSpace())return ze(me,De),null;we=Ie=null;var Be=(De.tokenize||E)(me,De);if(Be=="comment"||Be=="meta")return Be;if(be.align==null&&(be.align=!0),we==";"||we==":"||we==","&&me.match(/^\s*(?:\/\/.*)?$/,!1))for(;De.context.type=="statement";)te(De);else if(we=="{")_(De,me.column(),"}");else if(we=="[")_(De,me.column(),"]");else if(we=="(")_(De,me.column(),")");else if(we=="}"){for(;be.type=="statement";)be=te(De);for(be.type=="}"&&(be=te(De));be.type=="statement";)be=te(De)}else we==be.type?te(De):ve&&((be.type=="}"||be.type=="top")&&we!=";"||be.type=="statement"&&we=="newstatement")&&_(De,me.column(),"statement",me.current());if(Be=="variable"&&(De.prevToken=="def"||y.typeFirstDefinitions&&oe(me,De,me.start)&&Q(De.context)&&me.match(/^\s*\(/,!1))&&(Be="def"),Fe.token){var Ne=Fe.token(me,De,Be);Ne!==void 0&&(Be=Ne)}return Be=="def"&&y.styleDefs===!1&&(Be="variable"),De.startOfLine=!1,De.prevToken=Ie?"def":Be||we,ze(me,De),Be},indent:function(me,De){if(me.tokenize!=E&&me.tokenize!=null||me.typeAtEndOfLine&&Q(me.context))return b.Pass;var be=me.context,Be=De&&De.charAt(0),Ne=Be==be.type;if(be.type=="statement"&&Be=="}"&&(be=be.prev),y.dontIndentStatements)for(;be.type=="statement"&&y.dontIndentStatements.test(be.info);)be=be.prev;if(Fe.indent){var Mt=Fe.indent(me,be,De,j);if(typeof Mt=="number")return Mt}var Pt=be.prev&&be.prev.info=="switch";if(y.allmanIndentation&&/[{(]/.test(Be)){for(;be.type!="top"&&be.type!="}";)be=be.prev;return be.indented}return be.type=="statement"?be.indented+(Be=="{"?0:de):be.align&&(!v||be.type!=")")?be.column+(Ne?0:1):be.type==")"&&!Ne?be.indented+de:be.indented+(Ne?0:j)+(!Ne&&Pt&&!/^(?:case|default)\b/.test(De)?j:0)},electricInput:Oe?/^\s*(?:case .*?:|default:|\{\}?|\})$/:/^\s*[{}]$/,blockCommentStart:"/*",blockCommentEnd:"*/",blockCommentContinue:" * ",lineComment:"//",fold:"brace"}});function k(g){for(var y={},j=g.split(" "),de=0;de!?|\/#:@]/,hooks:{"@":function(g){return g.eatWhile(/[\w\$_]/),"meta"},'"':function(g,y){return g.match('""')?(y.tokenize=F,y.tokenize(g,y)):!1},"'":function(g){return g.match(/^(\\[^'\s]+|[^\\'])'/)?"string-2":(g.eatWhile(/[\w\$_\xa1-\uffff]/),"atom")},"=":function(g,y){var j=y.context;return j.type=="}"&&j.align&&g.eat(">")?(y.context=new pe(j.indented,j.column,j.type,j.info,null,j.prev),"operator"):!1},"/":function(g,y){return g.eat("*")?(y.tokenize=G(1),y.tokenize(g,y)):!1}},modeProps:{closeBrackets:{pairs:'()[]{}""',triples:'"'}}});function c(g){return function(y,j){for(var de=!1,v,d=!1;!y.eol();){if(!g&&!de&&y.match('"')){d=!0;break}if(g&&y.match('"""')){d=!0;break}v=y.next(),!de&&v=="$"&&y.match("{")&&y.skipTo("}"),de=!de&&v=="\\"&&!g}return(d||!g)&&(j.tokenize=null),"string"}}$("text/x-kotlin",{name:"clike",keywords:k("package as typealias class interface this super val operator var fun for is in This throw return annotation break continue object if else while do try when !in !is as? file import where by get set abstract enum open inner override private public internal protected catch finally out final vararg reified dynamic companion constructor init sealed field property receiver param sparam lateinit data inline noinline tailrec external annotation crossinline const operator infix suspend actual expect setparam value"),types:k("Boolean Byte Character CharSequence Class ClassLoader Cloneable Comparable Compiler Double Exception Float Integer Long Math Number Object Package Pair Process Runtime Runnable SecurityManager Short StackTraceElement StrictMath String StringBuffer System Thread ThreadGroup ThreadLocal Throwable Triple Void Annotation Any BooleanArray ByteArray Char CharArray DeprecationLevel DoubleArray Enum FloatArray Function Int IntArray Lazy LazyThreadSafetyMode LongArray Nothing ShortArray Unit"),intendSwitch:!1,indentStatements:!1,multiLineStrings:!0,number:/^(?:0x[a-f\d_]+|0b[01_]+|(?:[\d_]+(\.\d+)?|\.\d+)(?:e[-+]?[\d_]+)?)(u|ll?|l|f)?/i,blockKeywords:k("catch class do else finally for if where try while enum"),defKeywords:k("class val var object interface fun"),atoms:k("true false null this"),hooks:{"@":function(g){return g.eatWhile(/[\w\$_]/),"meta"},"*":function(g,y){return y.prevToken=="."?"variable":"operator"},'"':function(g,y){return y.tokenize=c(g.match('""')),y.tokenize(g,y)},"/":function(g,y){return g.eat("*")?(y.tokenize=G(1),y.tokenize(g,y)):!1},indent:function(g,y,j,de){var v=j&&j.charAt(0);if((g.prevToken=="}"||g.prevToken==")")&&j=="")return g.indented;if(g.prevToken=="operator"&&j!="}"&&g.context.type!="}"||g.prevToken=="variable"&&v=="."||(g.prevToken=="}"||g.prevToken==")")&&v==".")return de*2+y.indented;if(y.align&&y.type=="}")return y.indented+(g.context.type==(j||"").charAt(0)?0:de)}},modeProps:{closeBrackets:{triples:'"'}}}),$(["x-shader/x-vertex","x-shader/x-fragment"],{name:"clike",keywords:k("sampler1D sampler2D sampler3D samplerCube sampler1DShadow sampler2DShadow const attribute uniform varying break continue discard return for while do if else struct in out inout"),types:k("float int bool void vec2 vec3 vec4 ivec2 ivec3 ivec4 bvec2 bvec3 bvec4 mat2 mat3 mat4"),blockKeywords:k("for while do if else struct"),builtin:k("radians degrees sin cos tan asin acos atan pow exp log exp2 sqrt inversesqrt abs sign floor ceil fract mod min max clamp mix step smoothstep length distance dot cross normalize ftransform faceforward reflect refract matrixCompMult lessThan lessThanEqual greaterThan greaterThanEqual equal notEqual any all not texture1D texture1DProj texture1DLod texture1DProjLod texture2D texture2DProj texture2DLod texture2DProjLod texture3D texture3DProj texture3DLod texture3DProjLod textureCube textureCubeLod shadow1D shadow2D shadow1DProj shadow2DProj shadow1DLod shadow2DLod shadow1DProjLod shadow2DProjLod dFdx dFdy fwidth noise1 noise2 noise3 noise4"),atoms:k("true false gl_FragColor gl_SecondaryColor gl_Normal gl_Vertex gl_MultiTexCoord0 gl_MultiTexCoord1 gl_MultiTexCoord2 gl_MultiTexCoord3 gl_MultiTexCoord4 gl_MultiTexCoord5 gl_MultiTexCoord6 gl_MultiTexCoord7 gl_FogCoord gl_PointCoord gl_Position gl_PointSize gl_ClipVertex gl_FrontColor gl_BackColor gl_FrontSecondaryColor gl_BackSecondaryColor gl_TexCoord gl_FogFragCoord gl_FragCoord gl_FrontFacing gl_FragData gl_FragDepth gl_ModelViewMatrix gl_ProjectionMatrix gl_ModelViewProjectionMatrix gl_TextureMatrix gl_NormalMatrix gl_ModelViewMatrixInverse gl_ProjectionMatrixInverse gl_ModelViewProjectionMatrixInverse gl_TextureMatrixTranspose gl_ModelViewMatrixInverseTranspose gl_ProjectionMatrixInverseTranspose gl_ModelViewProjectionMatrixInverseTranspose gl_TextureMatrixInverseTranspose gl_NormalScale gl_DepthRange gl_ClipPlane gl_Point gl_FrontMaterial gl_BackMaterial gl_LightSource gl_LightModel gl_FrontLightModelProduct gl_BackLightModelProduct gl_TextureColor gl_EyePlaneS gl_EyePlaneT gl_EyePlaneR gl_EyePlaneQ gl_FogParameters gl_MaxLights gl_MaxClipPlanes gl_MaxTextureUnits gl_MaxTextureCoords gl_MaxVertexAttribs gl_MaxVertexUniformComponents gl_MaxVaryingFloats gl_MaxVertexTextureImageUnits gl_MaxTextureImageUnits gl_MaxFragmentUniformComponents gl_MaxCombineTextureImageUnits gl_MaxDrawBuffers"),indentSwitch:!1,hooks:{"#":N},modeProps:{fold:["brace","include"]}}),$("text/x-nesc",{name:"clike",keywords:k(Y+" as atomic async call command component components configuration event generic implementation includes interface module new norace nx_struct nx_union post provides signal task uses abstract extends"),types:ue,blockKeywords:k(w),atoms:k("null true false"),hooks:{"#":N},modeProps:{fold:["brace","include"]}}),$("text/x-objectivec",{name:"clike",keywords:k(Y+" "+S),types:O,builtin:k(R),blockKeywords:k(w+" @synthesize @try @catch @finally @autoreleasepool @synchronized"),defKeywords:k(M+" @interface @implementation @protocol @class"),dontIndentStatements:/^@.*$/,typeFirstDefinitions:!0,atoms:k("YES NO NULL Nil nil true false nullptr"),isReservedIdentifier:X,hooks:{"#":N,"*":z},modeProps:{fold:["brace","include"]}}),$("text/x-objectivec++",{name:"clike",keywords:k(Y+" "+S+" "+ne),types:O,builtin:k(R),blockKeywords:k(w+" @synthesize @try @catch @finally @autoreleasepool @synchronized class try catch"),defKeywords:k(M+" @interface @implementation @protocol @class class namespace"),dontIndentStatements:/^@.*$|^template$/,typeFirstDefinitions:!0,atoms:k("YES NO NULL Nil nil true false nullptr"),isReservedIdentifier:X,hooks:{"#":N,"*":z,u:p,U:p,L:p,R:p,0:q,1:q,2:q,3:q,4:q,5:q,6:q,7:q,8:q,9:q,token:function(g,y,j){if(j=="variable"&&g.peek()=="("&&(y.prevToken==";"||y.prevToken==null||y.prevToken=="}")&&W(g.current()))return"def"}},namespaceSeparator:"::",modeProps:{fold:["brace","include"]}}),$("text/x-squirrel",{name:"clike",keywords:k("base break clone continue const default delete enum extends function in class foreach local resume return this throw typeof yield constructor instanceof static"),types:ue,blockKeywords:k("case catch class else for foreach if switch try while"),defKeywords:k("function local class"),typeFirstDefinitions:!0,atoms:k("true false null"),hooks:{"#":N},modeProps:{fold:["brace","include"]}});var T=null;function C(g){return function(y,j){for(var de=!1,v,d=!1;!y.eol();){if(!de&&y.match('"')&&(g=="single"||y.match('""'))){d=!0;break}if(!de&&y.match("``")){T=C(g),d=!0;break}v=y.next(),de=g=="single"&&!de&&v=="\\"}return d&&(j.tokenize=null),"string"}}$("text/x-ceylon",{name:"clike",keywords:k("abstracts alias assembly assert assign break case catch class continue dynamic else exists extends finally for function given if import in interface is let module new nonempty object of out outer package return satisfies super switch then this throw try value void while"),types:function(g){var y=g.charAt(0);return y===y.toUpperCase()&&y!==y.toLowerCase()},blockKeywords:k("case catch class dynamic else finally for function if interface module new object switch try while"),defKeywords:k("class dynamic function interface module object package value"),builtin:k("abstract actual aliased annotation by default deprecated doc final formal late license native optional sealed see serializable shared suppressWarnings tagged throws variable"),isPunctuationChar:/[\[\]{}\(\),;\:\.`]/,isOperatorChar:/[+\-*&%=<>!?|^~:\/]/,numberStart:/[\d#$]/,number:/^(?:#[\da-fA-F_]+|\$[01_]+|[\d_]+[kMGTPmunpf]?|[\d_]+\.[\d_]+(?:[eE][-+]?\d+|[kMGTPmunpf]|)|)/i,multiLineStrings:!0,typeFirstDefinitions:!0,atoms:k("true false null larger smaller equal empty finished"),indentSwitch:!1,styleDefs:!1,hooks:{"@":function(g){return g.eatWhile(/[\w\$_]/),"meta"},'"':function(g,y){return y.tokenize=C(g.match('""')?"triple":"single"),y.tokenize(g,y)},"`":function(g,y){return!T||!g.match("`")?!1:(y.tokenize=T,T=null,y.tokenize(g,y))},"'":function(g){return g.eatWhile(/[\w\$_\xa1-\uffff]/),"atom"},token:function(g,y,j){if((j=="variable"||j=="type")&&y.prevToken==".")return"variable-2"}},modeProps:{fold:["brace","import"],closeBrackets:{triples:'"'}}})})})()),Ta.exports}tf();var Da={exports:{}},Ma={exports:{}},Fa;function rf(){return Fa||(Fa=1,(function(ct,xt){(function(b){b(mt())})(function(b){b.modeInfo=[{name:"APL",mime:"text/apl",mode:"apl",ext:["dyalog","apl"]},{name:"PGP",mimes:["application/pgp","application/pgp-encrypted","application/pgp-keys","application/pgp-signature"],mode:"asciiarmor",ext:["asc","pgp","sig"]},{name:"ASN.1",mime:"text/x-ttcn-asn",mode:"asn.1",ext:["asn","asn1"]},{name:"Asterisk",mime:"text/x-asterisk",mode:"asterisk",file:/^extensions\.conf$/i},{name:"Brainfuck",mime:"text/x-brainfuck",mode:"brainfuck",ext:["b","bf"]},{name:"C",mime:"text/x-csrc",mode:"clike",ext:["c","h","ino"]},{name:"C++",mime:"text/x-c++src",mode:"clike",ext:["cpp","c++","cc","cxx","hpp","h++","hh","hxx"],alias:["cpp"]},{name:"Cobol",mime:"text/x-cobol",mode:"cobol",ext:["cob","cpy","cbl"]},{name:"C#",mime:"text/x-csharp",mode:"clike",ext:["cs"],alias:["csharp","cs"]},{name:"Clojure",mime:"text/x-clojure",mode:"clojure",ext:["clj","cljc","cljx"]},{name:"ClojureScript",mime:"text/x-clojurescript",mode:"clojure",ext:["cljs"]},{name:"Closure Stylesheets (GSS)",mime:"text/x-gss",mode:"css",ext:["gss"]},{name:"CMake",mime:"text/x-cmake",mode:"cmake",ext:["cmake","cmake.in"],file:/^CMakeLists\.txt$/},{name:"CoffeeScript",mimes:["application/vnd.coffeescript","text/coffeescript","text/x-coffeescript"],mode:"coffeescript",ext:["coffee"],alias:["coffee","coffee-script"]},{name:"Common Lisp",mime:"text/x-common-lisp",mode:"commonlisp",ext:["cl","lisp","el"],alias:["lisp"]},{name:"Cypher",mime:"application/x-cypher-query",mode:"cypher",ext:["cyp","cypher"]},{name:"Cython",mime:"text/x-cython",mode:"python",ext:["pyx","pxd","pxi"]},{name:"Crystal",mime:"text/x-crystal",mode:"crystal",ext:["cr"]},{name:"CSS",mime:"text/css",mode:"css",ext:["css"]},{name:"CQL",mime:"text/x-cassandra",mode:"sql",ext:["cql"]},{name:"D",mime:"text/x-d",mode:"d",ext:["d"]},{name:"Dart",mimes:["application/dart","text/x-dart"],mode:"dart",ext:["dart"]},{name:"diff",mime:"text/x-diff",mode:"diff",ext:["diff","patch"]},{name:"Django",mime:"text/x-django",mode:"django"},{name:"Dockerfile",mime:"text/x-dockerfile",mode:"dockerfile",file:/^Dockerfile$/},{name:"DTD",mime:"application/xml-dtd",mode:"dtd",ext:["dtd"]},{name:"Dylan",mime:"text/x-dylan",mode:"dylan",ext:["dylan","dyl","intr"]},{name:"EBNF",mime:"text/x-ebnf",mode:"ebnf"},{name:"ECL",mime:"text/x-ecl",mode:"ecl",ext:["ecl"]},{name:"edn",mime:"application/edn",mode:"clojure",ext:["edn"]},{name:"Eiffel",mime:"text/x-eiffel",mode:"eiffel",ext:["e"]},{name:"Elm",mime:"text/x-elm",mode:"elm",ext:["elm"]},{name:"Embedded JavaScript",mime:"application/x-ejs",mode:"htmlembedded",ext:["ejs"]},{name:"Embedded Ruby",mime:"application/x-erb",mode:"htmlembedded",ext:["erb"]},{name:"Erlang",mime:"text/x-erlang",mode:"erlang",ext:["erl"]},{name:"Esper",mime:"text/x-esper",mode:"sql"},{name:"Factor",mime:"text/x-factor",mode:"factor",ext:["factor"]},{name:"FCL",mime:"text/x-fcl",mode:"fcl"},{name:"Forth",mime:"text/x-forth",mode:"forth",ext:["forth","fth","4th"]},{name:"Fortran",mime:"text/x-fortran",mode:"fortran",ext:["f","for","f77","f90","f95"]},{name:"F#",mime:"text/x-fsharp",mode:"mllike",ext:["fs"],alias:["fsharp"]},{name:"Gas",mime:"text/x-gas",mode:"gas",ext:["s"]},{name:"Gherkin",mime:"text/x-feature",mode:"gherkin",ext:["feature"]},{name:"GitHub Flavored Markdown",mime:"text/x-gfm",mode:"gfm",file:/^(readme|contributing|history)\.md$/i},{name:"Go",mime:"text/x-go",mode:"go",ext:["go"]},{name:"Groovy",mime:"text/x-groovy",mode:"groovy",ext:["groovy","gradle"],file:/^Jenkinsfile$/},{name:"HAML",mime:"text/x-haml",mode:"haml",ext:["haml"]},{name:"Haskell",mime:"text/x-haskell",mode:"haskell",ext:["hs"]},{name:"Haskell (Literate)",mime:"text/x-literate-haskell",mode:"haskell-literate",ext:["lhs"]},{name:"Haxe",mime:"text/x-haxe",mode:"haxe",ext:["hx"]},{name:"HXML",mime:"text/x-hxml",mode:"haxe",ext:["hxml"]},{name:"ASP.NET",mime:"application/x-aspx",mode:"htmlembedded",ext:["aspx"],alias:["asp","aspx"]},{name:"HTML",mime:"text/html",mode:"htmlmixed",ext:["html","htm","handlebars","hbs"],alias:["xhtml"]},{name:"HTTP",mime:"message/http",mode:"http"},{name:"IDL",mime:"text/x-idl",mode:"idl",ext:["pro"]},{name:"Pug",mime:"text/x-pug",mode:"pug",ext:["jade","pug"],alias:["jade"]},{name:"Java",mime:"text/x-java",mode:"clike",ext:["java"]},{name:"Java Server Pages",mime:"application/x-jsp",mode:"htmlembedded",ext:["jsp"],alias:["jsp"]},{name:"JavaScript",mimes:["text/javascript","text/ecmascript","application/javascript","application/x-javascript","application/ecmascript"],mode:"javascript",ext:["js"],alias:["ecmascript","js","node"]},{name:"JSON",mimes:["application/json","application/x-json"],mode:"javascript",ext:["json","map"],alias:["json5"]},{name:"JSON-LD",mime:"application/ld+json",mode:"javascript",ext:["jsonld"],alias:["jsonld"]},{name:"JSX",mime:"text/jsx",mode:"jsx",ext:["jsx"]},{name:"Jinja2",mime:"text/jinja2",mode:"jinja2",ext:["j2","jinja","jinja2"]},{name:"Julia",mime:"text/x-julia",mode:"julia",ext:["jl"],alias:["jl"]},{name:"Kotlin",mime:"text/x-kotlin",mode:"clike",ext:["kt"]},{name:"LESS",mime:"text/x-less",mode:"css",ext:["less"]},{name:"LiveScript",mime:"text/x-livescript",mode:"livescript",ext:["ls"],alias:["ls"]},{name:"Lua",mime:"text/x-lua",mode:"lua",ext:["lua"]},{name:"Markdown",mime:"text/x-markdown",mode:"markdown",ext:["markdown","md","mkd"]},{name:"mIRC",mime:"text/mirc",mode:"mirc"},{name:"MariaDB SQL",mime:"text/x-mariadb",mode:"sql"},{name:"Mathematica",mime:"text/x-mathematica",mode:"mathematica",ext:["m","nb","wl","wls"]},{name:"Modelica",mime:"text/x-modelica",mode:"modelica",ext:["mo"]},{name:"MUMPS",mime:"text/x-mumps",mode:"mumps",ext:["mps"]},{name:"MS SQL",mime:"text/x-mssql",mode:"sql"},{name:"mbox",mime:"application/mbox",mode:"mbox",ext:["mbox"]},{name:"MySQL",mime:"text/x-mysql",mode:"sql"},{name:"Nginx",mime:"text/x-nginx-conf",mode:"nginx",file:/nginx.*\.conf$/i},{name:"NSIS",mime:"text/x-nsis",mode:"nsis",ext:["nsh","nsi"]},{name:"NTriples",mimes:["application/n-triples","application/n-quads","text/n-triples"],mode:"ntriples",ext:["nt","nq"]},{name:"Objective-C",mime:"text/x-objectivec",mode:"clike",ext:["m"],alias:["objective-c","objc"]},{name:"Objective-C++",mime:"text/x-objectivec++",mode:"clike",ext:["mm"],alias:["objective-c++","objc++"]},{name:"OCaml",mime:"text/x-ocaml",mode:"mllike",ext:["ml","mli","mll","mly"]},{name:"Octave",mime:"text/x-octave",mode:"octave",ext:["m"]},{name:"Oz",mime:"text/x-oz",mode:"oz",ext:["oz"]},{name:"Pascal",mime:"text/x-pascal",mode:"pascal",ext:["p","pas"]},{name:"PEG.js",mime:"null",mode:"pegjs",ext:["jsonld"]},{name:"Perl",mime:"text/x-perl",mode:"perl",ext:["pl","pm"]},{name:"PHP",mimes:["text/x-php","application/x-httpd-php","application/x-httpd-php-open"],mode:"php",ext:["php","php3","php4","php5","php7","phtml"]},{name:"Pig",mime:"text/x-pig",mode:"pig",ext:["pig"]},{name:"Plain Text",mime:"text/plain",mode:"null",ext:["txt","text","conf","def","list","log"]},{name:"PLSQL",mime:"text/x-plsql",mode:"sql",ext:["pls"]},{name:"PostgreSQL",mime:"text/x-pgsql",mode:"sql"},{name:"PowerShell",mime:"application/x-powershell",mode:"powershell",ext:["ps1","psd1","psm1"]},{name:"Properties files",mime:"text/x-properties",mode:"properties",ext:["properties","ini","in"],alias:["ini","properties"]},{name:"ProtoBuf",mime:"text/x-protobuf",mode:"protobuf",ext:["proto"]},{name:"Python",mime:"text/x-python",mode:"python",ext:["BUILD","bzl","py","pyw"],file:/^(BUCK|BUILD)$/},{name:"Puppet",mime:"text/x-puppet",mode:"puppet",ext:["pp"]},{name:"Q",mime:"text/x-q",mode:"q",ext:["q"]},{name:"R",mime:"text/x-rsrc",mode:"r",ext:["r","R"],alias:["rscript"]},{name:"reStructuredText",mime:"text/x-rst",mode:"rst",ext:["rst"],alias:["rst"]},{name:"RPM Changes",mime:"text/x-rpm-changes",mode:"rpm"},{name:"RPM Spec",mime:"text/x-rpm-spec",mode:"rpm",ext:["spec"]},{name:"Ruby",mime:"text/x-ruby",mode:"ruby",ext:["rb"],alias:["jruby","macruby","rake","rb","rbx"]},{name:"Rust",mime:"text/x-rustsrc",mode:"rust",ext:["rs"]},{name:"SAS",mime:"text/x-sas",mode:"sas",ext:["sas"]},{name:"Sass",mime:"text/x-sass",mode:"sass",ext:["sass"]},{name:"Scala",mime:"text/x-scala",mode:"clike",ext:["scala"]},{name:"Scheme",mime:"text/x-scheme",mode:"scheme",ext:["scm","ss"]},{name:"SCSS",mime:"text/x-scss",mode:"css",ext:["scss"]},{name:"Shell",mimes:["text/x-sh","application/x-sh"],mode:"shell",ext:["sh","ksh","bash"],alias:["bash","sh","zsh"],file:/^PKGBUILD$/},{name:"Sieve",mime:"application/sieve",mode:"sieve",ext:["siv","sieve"]},{name:"Slim",mimes:["text/x-slim","application/x-slim"],mode:"slim",ext:["slim"]},{name:"Smalltalk",mime:"text/x-stsrc",mode:"smalltalk",ext:["st"]},{name:"Smarty",mime:"text/x-smarty",mode:"smarty",ext:["tpl"]},{name:"Solr",mime:"text/x-solr",mode:"solr"},{name:"SML",mime:"text/x-sml",mode:"mllike",ext:["sml","sig","fun","smackspec"]},{name:"Soy",mime:"text/x-soy",mode:"soy",ext:["soy"],alias:["closure template"]},{name:"SPARQL",mime:"application/sparql-query",mode:"sparql",ext:["rq","sparql"],alias:["sparul"]},{name:"Spreadsheet",mime:"text/x-spreadsheet",mode:"spreadsheet",alias:["excel","formula"]},{name:"SQL",mime:"text/x-sql",mode:"sql",ext:["sql"]},{name:"SQLite",mime:"text/x-sqlite",mode:"sql"},{name:"Squirrel",mime:"text/x-squirrel",mode:"clike",ext:["nut"]},{name:"Stylus",mime:"text/x-styl",mode:"stylus",ext:["styl"]},{name:"Swift",mime:"text/x-swift",mode:"swift",ext:["swift"]},{name:"sTeX",mime:"text/x-stex",mode:"stex"},{name:"LaTeX",mime:"text/x-latex",mode:"stex",ext:["text","ltx","tex"],alias:["tex"]},{name:"SystemVerilog",mime:"text/x-systemverilog",mode:"verilog",ext:["v","sv","svh"]},{name:"Tcl",mime:"text/x-tcl",mode:"tcl",ext:["tcl"]},{name:"Textile",mime:"text/x-textile",mode:"textile",ext:["textile"]},{name:"TiddlyWiki",mime:"text/x-tiddlywiki",mode:"tiddlywiki"},{name:"Tiki wiki",mime:"text/tiki",mode:"tiki"},{name:"TOML",mime:"text/x-toml",mode:"toml",ext:["toml"]},{name:"Tornado",mime:"text/x-tornado",mode:"tornado"},{name:"troff",mime:"text/troff",mode:"troff",ext:["1","2","3","4","5","6","7","8","9"]},{name:"TTCN",mime:"text/x-ttcn",mode:"ttcn",ext:["ttcn","ttcn3","ttcnpp"]},{name:"TTCN_CFG",mime:"text/x-ttcn-cfg",mode:"ttcn-cfg",ext:["cfg"]},{name:"Turtle",mime:"text/turtle",mode:"turtle",ext:["ttl"]},{name:"TypeScript",mime:"application/typescript",mode:"javascript",ext:["ts"],alias:["ts"]},{name:"TypeScript-JSX",mime:"text/typescript-jsx",mode:"jsx",ext:["tsx"],alias:["tsx"]},{name:"Twig",mime:"text/x-twig",mode:"twig"},{name:"Web IDL",mime:"text/x-webidl",mode:"webidl",ext:["webidl"]},{name:"VB.NET",mime:"text/x-vb",mode:"vb",ext:["vb"]},{name:"VBScript",mime:"text/vbscript",mode:"vbscript",ext:["vbs"]},{name:"Velocity",mime:"text/velocity",mode:"velocity",ext:["vtl"]},{name:"Verilog",mime:"text/x-verilog",mode:"verilog",ext:["v"]},{name:"VHDL",mime:"text/x-vhdl",mode:"vhdl",ext:["vhd","vhdl"]},{name:"Vue.js Component",mimes:["script/x-vue","text/x-vue"],mode:"vue",ext:["vue"]},{name:"XML",mimes:["application/xml","text/xml"],mode:"xml",ext:["xml","xsl","xsd","svg"],alias:["rss","wsdl","xsd"]},{name:"XQuery",mime:"application/xquery",mode:"xquery",ext:["xy","xquery"]},{name:"Yacas",mime:"text/x-yacas",mode:"yacas",ext:["ys"]},{name:"YAML",mimes:["text/x-yaml","text/yaml"],mode:"yaml",ext:["yaml","yml"],alias:["yml"]},{name:"Z80",mime:"text/x-z80",mode:"z80",ext:["z80"]},{name:"mscgen",mime:"text/x-mscgen",mode:"mscgen",ext:["mscgen","mscin","msc"]},{name:"xu",mime:"text/x-xu",mode:"mscgen",ext:["xu"]},{name:"msgenny",mime:"text/x-msgenny",mode:"mscgen",ext:["msgenny"]},{name:"WebAssembly",mime:"text/webassembly",mode:"wast",ext:["wat","wast"]}];for(var pe=0;pe-1&&te.substring(k+1,te.length);if(I)return b.findModeByExtension(I)},b.findModeByName=function(te){te=te.toLowerCase();for(var oe=0;oe` "'(~:]+/,ue=/^(~~~+|```+)[ \t]*([\w\/+#-]*)[^\n`]*$/,O=/^\s*\[[^\]]+?\]:.*$/,w=/[!"#$%&'()*+,\-.\/:;<=>?@\[\\\]^_`{|}~\xA1\xA7\xAB\xB6\xB7\xBB\xBF\u037E\u0387\u055A-\u055F\u0589\u058A\u05BE\u05C0\u05C3\u05C6\u05F3\u05F4\u0609\u060A\u060C\u060D\u061B\u061E\u061F\u066A-\u066D\u06D4\u0700-\u070D\u07F7-\u07F9\u0830-\u083E\u085E\u0964\u0965\u0970\u0AF0\u0DF4\u0E4F\u0E5A\u0E5B\u0F04-\u0F12\u0F14\u0F3A-\u0F3D\u0F85\u0FD0-\u0FD4\u0FD9\u0FDA\u104A-\u104F\u10FB\u1360-\u1368\u1400\u166D\u166E\u169B\u169C\u16EB-\u16ED\u1735\u1736\u17D4-\u17D6\u17D8-\u17DA\u1800-\u180A\u1944\u1945\u1A1E\u1A1F\u1AA0-\u1AA6\u1AA8-\u1AAD\u1B5A-\u1B60\u1BFC-\u1BFF\u1C3B-\u1C3F\u1C7E\u1C7F\u1CC0-\u1CC7\u1CD3\u2010-\u2027\u2030-\u2043\u2045-\u2051\u2053-\u205E\u207D\u207E\u208D\u208E\u2308-\u230B\u2329\u232A\u2768-\u2775\u27C5\u27C6\u27E6-\u27EF\u2983-\u2998\u29D8-\u29DB\u29FC\u29FD\u2CF9-\u2CFC\u2CFE\u2CFF\u2D70\u2E00-\u2E2E\u2E30-\u2E42\u3001-\u3003\u3008-\u3011\u3014-\u301F\u3030\u303D\u30A0\u30FB\uA4FE\uA4FF\uA60D-\uA60F\uA673\uA67E\uA6F2-\uA6F7\uA874-\uA877\uA8CE\uA8CF\uA8F8-\uA8FA\uA8FC\uA92E\uA92F\uA95F\uA9C1-\uA9CD\uA9DE\uA9DF\uAA5C-\uAA5F\uAADE\uAADF\uAAF0\uAAF1\uABEB\uFD3E\uFD3F\uFE10-\uFE19\uFE30-\uFE52\uFE54-\uFE61\uFE63\uFE68\uFE6A\uFE6B\uFF01-\uFF03\uFF05-\uFF0A\uFF0C-\uFF0F\uFF1A\uFF1B\uFF1F\uFF20\uFF3B-\uFF3D\uFF3F\uFF5B\uFF5D\uFF5F-\uFF65]|\uD800[\uDD00-\uDD02\uDF9F\uDFD0]|\uD801\uDD6F|\uD802[\uDC57\uDD1F\uDD3F\uDE50-\uDE58\uDE7F\uDEF0-\uDEF6\uDF39-\uDF3F\uDF99-\uDF9C]|\uD804[\uDC47-\uDC4D\uDCBB\uDCBC\uDCBE-\uDCC1\uDD40-\uDD43\uDD74\uDD75\uDDC5-\uDDC9\uDDCD\uDDDB\uDDDD-\uDDDF\uDE38-\uDE3D\uDEA9]|\uD805[\uDCC6\uDDC1-\uDDD7\uDE41-\uDE43\uDF3C-\uDF3E]|\uD809[\uDC70-\uDC74]|\uD81A[\uDE6E\uDE6F\uDEF5\uDF37-\uDF3B\uDF44]|\uD82F\uDC9F|\uD836[\uDE87-\uDE8B]/,M=" ";function N(v,d,fe){return d.f=d.inline=fe,fe(v,d)}function z(v,d,fe){return d.f=d.block=fe,fe(v,d)}function X(v){return!v||!/\S/.test(v.string)}function q(v){if(v.linkTitle=!1,v.linkHref=!1,v.linkText=!1,v.em=!1,v.strong=!1,v.strikethrough=!1,v.quote=0,v.indentedCode=!1,v.f==W){var d=oe;if(!d){var fe=b.innerMode(te,v.htmlState);d=fe.mode.name=="xml"&&fe.state.tagStart===null&&!fe.state.context&&fe.state.tokenize.isInText}d&&(v.f=F,v.block=p,v.htmlState=null)}return v.trailingSpace=0,v.trailingSpaceNewLine=!1,v.prevLine=v.thisLine,v.thisLine={stream:null},null}function p(v,d){var fe=v.column()===d.indentation,Te=X(d.prevLine.stream),le=d.indentedCode,xe=d.prevLine.hr,Me=d.list!==!1,Fe=(d.listStack[d.listStack.length-1]||0)+3;d.indentedCode=!1;var Ce=d.indentation;if(d.indentationDiff===null&&(d.indentationDiff=d.indentation,Me)){for(d.list=null;Ce=4&&(le||d.prevLine.fencedCodeEnd||d.prevLine.header||Te))return v.skipToEnd(),d.indentedCode=!0,k.code;if(v.eatSpace())return null;if(fe&&d.indentation<=Fe&&(qe=v.match(R))&&qe[1].length<=6)return d.quote=0,d.header=qe[1].length,d.thisLine.header=!0,_.highlightFormatting&&(d.formatting="header"),d.f=d.inline,P(d);if(d.indentation<=Fe&&v.eat(">"))return d.quote=fe?1:d.quote+1,_.highlightFormatting&&(d.formatting="quote"),v.eatSpace(),P(d);if(!Oe&&!d.setext&&fe&&d.indentation<=Fe&&(qe=v.match(ne))){var Ve=qe[1]?"ol":"ul";return d.indentation=Ce+v.current().length,d.list=!0,d.quote=0,d.listStack.push(d.indentation),d.em=!1,d.strong=!1,d.code=!1,d.strikethrough=!1,_.taskLists&&v.match(S,!1)&&(d.taskList=!0),d.f=d.inline,_.highlightFormatting&&(d.formatting=["list","list-"+Ve]),P(d)}else{if(fe&&d.indentation<=Fe&&(qe=v.match(ue,!0)))return d.quote=0,d.fencedEndRE=new RegExp(qe[1]+"+ *$"),d.localMode=_.fencedCodeBlockHighlighting&&Q(qe[2]||_.fencedCodeBlockDefaultMode),d.localMode&&(d.localState=b.startState(d.localMode)),d.f=d.block=J,_.highlightFormatting&&(d.formatting="code-block"),d.code=-1,P(d);if(d.setext||(!ve||!Me)&&!d.quote&&d.list===!1&&!d.code&&!Oe&&!O.test(v.string)&&(qe=v.lookAhead(1))&&(qe=qe.match(A)))return d.setext?(d.header=d.setext,d.setext=0,v.skipToEnd(),_.highlightFormatting&&(d.formatting="header")):(d.header=qe[0].charAt(0)=="="?1:2,d.setext=d.header),d.thisLine.header=!0,d.f=d.inline,P(d);if(Oe)return v.skipToEnd(),d.hr=!0,d.thisLine.hr=!0,k.hr;if(v.peek()==="[")return N(v,d,g)}return N(v,d,d.inline)}function W(v,d){var fe=te.token(v,d.htmlState);if(!oe){var Te=b.innerMode(te,d.htmlState);(Te.mode.name=="xml"&&Te.state.tagStart===null&&!Te.state.context&&Te.state.tokenize.isInText||d.md_inside&&v.current().indexOf(">")>-1)&&(d.f=F,d.block=p,d.htmlState=null)}return fe}function J(v,d){var fe=d.listStack[d.listStack.length-1]||0,Te=d.indentation=v.quote?d.push(k.formatting+"-"+v.formatting[fe]+"-"+v.quote):d.push("error"))}if(v.taskOpen)return d.push("meta"),d.length?d.join(" "):null;if(v.taskClosed)return d.push("property"),d.length?d.join(" "):null;if(v.linkHref?d.push(k.linkHref,"url"):(v.strong&&d.push(k.strong),v.em&&d.push(k.em),v.strikethrough&&d.push(k.strikethrough),v.emoji&&d.push(k.emoji),v.linkText&&d.push(k.linkText),v.code&&d.push(k.code),v.image&&d.push(k.image),v.imageAltText&&d.push(k.imageAltText,"link"),v.imageMarker&&d.push(k.imageMarker)),v.header&&d.push(k.header,k.header+"-"+v.header),v.quote&&(d.push(k.quote),!_.maxBlockquoteDepth||_.maxBlockquoteDepth>=v.quote?d.push(k.quote+"-"+v.quote):d.push(k.quote+"-"+_.maxBlockquoteDepth)),v.list!==!1){var Te=(v.listStack.length-1)%3;Te?Te===1?d.push(k.list2):d.push(k.list3):d.push(k.list1)}return v.trailingSpaceNewLine?d.push("trailing-space-new-line"):v.trailingSpace&&d.push("trailing-space-"+(v.trailingSpace%2?"a":"b")),d.length?d.join(" "):null}function $(v,d){if(v.match(V,!0))return P(d)}function F(v,d){var fe=d.text(v,d);if(typeof fe<"u")return fe;if(d.list)return d.list=null,P(d);if(d.taskList){var Te=v.match(S,!0)[1]===" ";return Te?d.taskOpen=!0:d.taskClosed=!0,_.highlightFormatting&&(d.formatting="task"),d.taskList=!1,P(d)}if(d.taskOpen=!1,d.taskClosed=!1,d.header&&v.match(/^#+$/,!0))return _.highlightFormatting&&(d.formatting="header"),P(d);var le=v.next();if(d.linkTitle){d.linkTitle=!1;var xe=le;le==="("&&(xe=")"),xe=(xe+"").replace(/([.?*+^\[\]\\(){}|-])/g,"\\$1");var Me="^\\s*(?:[^"+xe+"\\\\]+|\\\\\\\\|\\\\.)"+xe;if(v.match(new RegExp(Me),!0))return k.linkHref}if(le==="`"){var Fe=d.formatting;_.highlightFormatting&&(d.formatting="code"),v.eatWhile("`");var Ce=v.current().length;if(d.code==0&&(!d.quote||Ce==1))return d.code=Ce,P(d);if(Ce==d.code){var ve=P(d);return d.code=0,ve}else return d.formatting=Fe,P(d)}else if(d.code)return P(d);if(le==="\\"&&(v.next(),_.highlightFormatting)){var Oe=P(d),qe=k.formatting+"-escape";return Oe?Oe+" "+qe:qe}if(le==="!"&&v.match(/\[[^\]]*\] ?(?:\(|\[)/,!1))return d.imageMarker=!0,d.image=!0,_.highlightFormatting&&(d.formatting="image"),P(d);if(le==="["&&d.imageMarker&&v.match(/[^\]]*\](\(.*?\)| ?\[.*?\])/,!1))return d.imageMarker=!1,d.imageAltText=!0,_.highlightFormatting&&(d.formatting="image"),P(d);if(le==="]"&&d.imageAltText){_.highlightFormatting&&(d.formatting="image");var Oe=P(d);return d.imageAltText=!1,d.image=!1,d.inline=d.f=c,Oe}if(le==="["&&!d.image)return d.linkText&&v.match(/^.*?\]/)||(d.linkText=!0,_.highlightFormatting&&(d.formatting="link")),P(d);if(le==="]"&&d.linkText){_.highlightFormatting&&(d.formatting="link");var Oe=P(d);return d.linkText=!1,d.inline=d.f=v.match(/\(.*?\)| ?\[.*?\]/,!1)?c:F,Oe}if(le==="<"&&v.match(/^(https?|ftps?):\/\/(?:[^\\>]|\\.)+>/,!1)){d.f=d.inline=G,_.highlightFormatting&&(d.formatting="link");var Oe=P(d);return Oe?Oe+=" ":Oe="",Oe+k.linkInline}if(le==="<"&&v.match(/^[^> \\]+@(?:[^\\>]|\\.)+>/,!1)){d.f=d.inline=G,_.highlightFormatting&&(d.formatting="link");var Oe=P(d);return Oe?Oe+=" ":Oe="",Oe+k.linkEmail}if(_.xml&&le==="<"&&v.match(/^(!--|\?|!\[CDATA\[|[a-z][a-z0-9-]*(?:\s+[a-z_:.\-]+(?:\s*=\s*[^>]+)?)*\s*(?:>|$))/i,!1)){var Ve=v.string.indexOf(">",v.pos);if(Ve!=-1){var dt=v.string.substring(v.start,Ve);/markdown\s*=\s*('|"){0,1}1('|"){0,1}/.test(dt)&&(d.md_inside=!0)}return v.backUp(1),d.htmlState=b.startState(te),z(v,d,W)}if(_.xml&&le==="<"&&v.match(/^\/\w*?>/))return d.md_inside=!1,"tag";if(le==="*"||le==="_"){for(var Pe=1,_e=v.pos==1?" ":v.string.charAt(v.pos-2);Pe<3&&v.eat(le);)Pe++;var Ue=v.peek()||" ",et=!/\s/.test(Ue)&&(!w.test(Ue)||/\s/.test(_e)||w.test(_e)),we=!/\s/.test(_e)&&(!w.test(_e)||/\s/.test(Ue)||w.test(Ue)),Ie=null,E=null;if(Pe%2&&(!d.em&&et&&(le==="*"||!we||w.test(_e))?Ie=!0:d.em==le&&we&&(le==="*"||!et||w.test(Ue))&&(Ie=!1)),Pe>1&&(!d.strong&&et&&(le==="*"||!we||w.test(_e))?E=!0:d.strong==le&&we&&(le==="*"||!et||w.test(Ue))&&(E=!1)),E!=null||Ie!=null){_.highlightFormatting&&(d.formatting=Ie==null?"strong":E==null?"em":"strong em"),Ie===!0&&(d.em=le),E===!0&&(d.strong=le);var ve=P(d);return Ie===!1&&(d.em=!1),E===!1&&(d.strong=!1),ve}}else if(le===" "&&(v.eat("*")||v.eat("_"))){if(v.peek()===" ")return P(d);v.backUp(1)}if(_.strikethrough){if(le==="~"&&v.eatWhile(le)){if(d.strikethrough){_.highlightFormatting&&(d.formatting="strikethrough");var ve=P(d);return d.strikethrough=!1,ve}else if(v.match(/^[^\s]/,!1))return d.strikethrough=!0,_.highlightFormatting&&(d.formatting="strikethrough"),P(d)}else if(le===" "&&v.match("~~",!0)){if(v.peek()===" ")return P(d);v.backUp(2)}}if(_.emoji&&le===":"&&v.match(/^(?:[a-z_\d+][a-z_\d+-]*|\-[a-z_\d+][a-z_\d+-]*):/)){d.emoji=!0,_.highlightFormatting&&(d.formatting="emoji");var ee=P(d);return d.emoji=!1,ee}return le===" "&&(v.match(/^ +$/,!1)?d.trailingSpace++:d.trailingSpace&&(d.trailingSpaceNewLine=!0)),P(d)}function G(v,d){var fe=v.next();if(fe===">"){d.f=d.inline=F,_.highlightFormatting&&(d.formatting="link");var Te=P(d);return Te?Te+=" ":Te="",Te+k.linkInline}return v.match(/^[^>]+/,!0),k.linkInline}function c(v,d){if(v.eatSpace())return null;var fe=v.next();return fe==="("||fe==="["?(d.f=d.inline=C(fe==="("?")":"]"),_.highlightFormatting&&(d.formatting="link-string"),d.linkHref=!0,P(d)):"error"}var T={")":/^(?:[^\\\(\)]|\\.|\((?:[^\\\(\)]|\\.)*\))*?(?=\))/,"]":/^(?:[^\\\[\]]|\\.|\[(?:[^\\\[\]]|\\.)*\])*?(?=\])/};function C(v){return function(d,fe){var Te=d.next();if(Te===v){fe.f=fe.inline=F,_.highlightFormatting&&(fe.formatting="link-string");var le=P(fe);return fe.linkHref=!1,le}return d.match(T[v]),fe.linkHref=!0,P(fe)}}function g(v,d){return v.match(/^([^\]\\]|\\.)*\]:/,!1)?(d.f=y,v.next(),_.highlightFormatting&&(d.formatting="link"),d.linkText=!0,P(d)):N(v,d,F)}function y(v,d){if(v.match("]:",!0)){d.f=d.inline=j,_.highlightFormatting&&(d.formatting="link");var fe=P(d);return d.linkText=!1,fe}return v.match(/^([^\]\\]|\\.)+/,!0),k.linkText}function j(v,d){return v.eatSpace()?null:(v.match(/^[^\s]+/,!0),v.peek()===void 0?d.linkTitle=!0:v.match(/^(?:\s+(?:"(?:[^"\\]|\\.)+"|'(?:[^'\\]|\\.)+'|\((?:[^)\\]|\\.)+\)))?/,!0),d.f=d.inline=F,k.linkHref+" url")}var de={startState:function(){return{f:p,prevLine:{stream:null},thisLine:{stream:null},block:p,htmlState:null,indentation:0,inline:F,text:$,formatting:!1,linkText:!1,linkHref:!1,linkTitle:!1,code:0,em:!1,strong:!1,header:0,setext:0,hr:!1,taskList:!1,list:!1,listStack:[],quote:0,trailingSpace:0,trailingSpaceNewLine:!1,strikethrough:!1,emoji:!1,fencedEndRE:null}},copyState:function(v){return{f:v.f,prevLine:v.prevLine,thisLine:v.thisLine,block:v.block,htmlState:v.htmlState&&b.copyState(te,v.htmlState),indentation:v.indentation,localMode:v.localMode,localState:v.localMode?b.copyState(v.localMode,v.localState):null,inline:v.inline,text:v.text,formatting:!1,linkText:v.linkText,linkTitle:v.linkTitle,linkHref:v.linkHref,code:v.code,em:v.em,strong:v.strong,strikethrough:v.strikethrough,emoji:v.emoji,header:v.header,setext:v.setext,hr:v.hr,taskList:v.taskList,list:v.list,listStack:v.listStack.slice(0),quote:v.quote,indentedCode:v.indentedCode,trailingSpace:v.trailingSpace,trailingSpaceNewLine:v.trailingSpaceNewLine,md_inside:v.md_inside,fencedEndRE:v.fencedEndRE}},token:function(v,d){if(d.formatting=!1,v!=d.thisLine.stream){if(d.header=0,d.hr=!1,v.match(/^\s*$/,!0))return q(d),null;if(d.prevLine=d.thisLine,d.thisLine={stream:v},d.taskList=!1,d.trailingSpace=0,d.trailingSpaceNewLine=!1,!d.localState&&(d.f=d.block,d.f!=W)){var fe=v.match(/^\s*/,!0)[0].replace(/\t/g,M).length;if(d.indentation=fe,d.indentationDiff=null,fe>0)return null}}return d.f(v,d)},innerMode:function(v){return v.block==W?{state:v.htmlState,mode:te}:v.localState?{state:v.localState,mode:v.localMode}:{state:v,mode:de}},indent:function(v,d,fe){return v.block==W&&te.indent?te.indent(v.htmlState,d,fe):v.localState&&v.localMode.indent?v.localMode.indent(v.localState,d,fe):b.Pass},blankLine:q,getType:P,blockCommentStart:"",closeBrackets:"()[]{}''\"\"``",fold:"markdown"};return de},"xml"),b.defineMIME("text/markdown","markdown"),b.defineMIME("text/x-markdown","markdown")})})()),Da.exports}nf();var Na={exports:{}},Ea;function of(){return Ea||(Ea=1,(function(ct,xt){(function(b){b(mt())})(function(b){b.defineOption("placeholder","",function(I,Y,ne){var S=ne&&ne!=b.Init;if(Y&&!S)I.on("blur",oe),I.on("change",Q),I.on("swapDoc",Q),b.on(I.getInputField(),"compositionupdate",I.state.placeholderCompose=function(){te(I)}),Q(I);else if(!Y&&S){I.off("blur",oe),I.off("change",Q),I.off("swapDoc",Q),b.off(I.getInputField(),"compositionupdate",I.state.placeholderCompose),pe(I);var R=I.getWrapperElement();R.className=R.className.replace(" CodeMirror-empty","")}Y&&!I.hasFocus()&&oe(I)});function pe(I){I.state.placeholder&&(I.state.placeholder.parentNode.removeChild(I.state.placeholder),I.state.placeholder=null)}function _(I){pe(I);var Y=I.state.placeholder=document.createElement("pre");Y.style.cssText="height: 0; overflow: visible",Y.style.direction=I.getOption("direction"),Y.className="CodeMirror-placeholder CodeMirror-line-like";var ne=I.getOption("placeholder");typeof ne=="string"&&(ne=document.createTextNode(ne)),Y.appendChild(ne),I.display.lineSpace.insertBefore(Y,I.display.lineSpace.firstChild)}function te(I){setTimeout(function(){var Y=!1;if(I.lineCount()==1){var ne=I.getInputField();Y=ne.nodeName=="TEXTAREA"?!I.getLine(0).length:!/[^\u200b]/.test(ne.querySelector(".CodeMirror-line").textContent)}Y?_(I):pe(I)},20)}function oe(I){k(I)&&_(I)}function Q(I){var Y=I.getWrapperElement(),ne=k(I);Y.className=Y.className.replace(" CodeMirror-empty","")+(ne?" CodeMirror-empty":""),ne?_(I):pe(I)}function k(I){return I.lineCount()===1&&I.getLine(0)===""}})})()),Na.exports}of();var Oa={exports:{}},Pa;function lf(){return Pa||(Pa=1,(function(ct,xt){(function(b){b(mt())})(function(b){b.defineSimpleMode=function(S,R){b.defineMode(S,function(A){return b.simpleMode(A,R)})},b.simpleMode=function(S,R){pe(R,"start");var A={},V=R.meta||{},ue=!1;for(var O in R)if(O!=V&&R.hasOwnProperty(O))for(var w=A[O]=[],M=R[O],N=0;N2&&z.token&&typeof z.token!="string"){for(var p=2;p-1)return b.Pass;var O=A.indent.length-1,w=S[A.state];e:for(;;){for(var M=0;M",")":"(<","[":"]>","]":"[<","{":"}>","}":"{<","<":">>",">":"<<"};function oe(S){return S&&S.bracketRegex||/[(){}[\]]/}function Q(S,R,A){var V=S.getLineHandle(R.line),ue=R.ch-1,O=A&&A.afterCursor;O==null&&(O=/(^| )cm-fat-cursor($| )/.test(S.getWrapperElement().className));var w=oe(A),M=!O&&ue>=0&&w.test(V.text.charAt(ue))&&te[V.text.charAt(ue)]||w.test(V.text.charAt(ue+1))&&te[V.text.charAt(++ue)];if(!M)return null;var N=M.charAt(1)==">"?1:-1;if(A&&A.strict&&N>0!=(ue==R.ch))return null;var z=S.getTokenTypeAt(_(R.line,ue+1)),X=k(S,_(R.line,ue+(N>0?1:0)),N,z,A);return X==null?null:{from:_(R.line,ue),to:X&&X.pos,match:X&&X.ch==M.charAt(0),forward:N>0}}function k(S,R,A,V,ue){for(var O=ue&&ue.maxScanLineLength||1e4,w=ue&&ue.maxScanLines||1e3,M=[],N=oe(ue),z=A>0?Math.min(R.line+w,S.lastLine()+1):Math.max(S.firstLine()-1,R.line-w),X=R.line;X!=z;X+=A){var q=S.getLine(X);if(q){var p=A>0?0:q.length-1,W=A>0?q.length:-1;if(!(q.length>O))for(X==R.line&&(p=R.ch-(A<0?1:0));p!=W;p+=A){var J=q.charAt(p);if(N.test(J)&&(V===void 0||(S.getTokenTypeAt(_(X,p+1))||"")==(V||""))){var P=te[J];if(P&&P.charAt(1)==">"==A>0)M.push(J);else if(M.length)M.pop();else return{pos:_(X,p),ch:J}}}}}return X-A==(A>0?S.lastLine():S.firstLine())?!1:null}function I(S,R,A){for(var V=S.state.matchBrackets.maxHighlightLineLength||1e3,ue=A&&A.highlightNonMatching,O=[],w=S.listSelections(),M=0;M`,triples:"",explode:"[]{}"},_=b.Pos;b.defineOption("autoCloseBrackets",!1,function(O,w,M){M&&M!=b.Init&&(O.removeKeyMap(oe),O.state.closeBrackets=null),w&&(Q(te(w,"pairs")),O.state.closeBrackets=w,O.addKeyMap(oe))});function te(O,w){return w=="pairs"&&typeof O=="string"?O:typeof O=="object"&&O[w]!=null?O[w]:pe[w]}var oe={Backspace:Y,Enter:ne};function Q(O){for(var w=0;w=0;z--){var q=N[z].head;O.replaceRange("",_(q.line,q.ch-1),_(q.line,q.ch+1),"+delete")}}function ne(O){var w=I(O),M=w&&te(w,"explode");if(!M||O.getOption("disableInput"))return b.Pass;for(var N=O.listSelections(),z=0;z0?{line:q.head.line,ch:q.head.ch+w}:{line:q.head.line-1};M.push({anchor:p,head:p})}O.setSelections(M,z)}function R(O){var w=b.cmpPos(O.anchor,O.head)>0;return{anchor:new _(O.anchor.line,O.anchor.ch+(w?-1:1)),head:new _(O.head.line,O.head.ch+(w?1:-1))}}function A(O,w){var M=I(O);if(!M||O.getOption("disableInput"))return b.Pass;var N=te(M,"pairs"),z=N.indexOf(w);if(z==-1)return b.Pass;for(var X=te(M,"closeBefore"),q=te(M,"triples"),p=N.charAt(z+1)==w,W=O.listSelections(),J=z%2==0,P,$=0;$=0&&O.getRange(G,_(G.line,G.ch+3))==w+w+w?c="skipThree":c="skip";else if(p&&G.ch>1&&q.indexOf(w)>=0&&O.getRange(_(G.line,G.ch-2),G)==w+w){if(G.ch>2&&/\bstring/.test(O.getTokenTypeAt(_(G.line,G.ch-2))))return b.Pass;c="addFour"}else if(p){var C=G.ch==0?" ":O.getRange(_(G.line,G.ch-1),G);if(!b.isWordChar(T)&&C!=w&&!b.isWordChar(C))c="both";else return b.Pass}else if(J&&(T.length===0||/\s/.test(T)||X.indexOf(T)>-1))c="both";else return b.Pass;if(!P)P=c;else if(P!=c)return b.Pass}var g=z%2?N.charAt(z-1):w,y=z%2?w:N.charAt(z+1);O.operation(function(){if(P=="skip")S(O,1);else if(P=="skipThree")S(O,3);else if(P=="surround"){for(var j=O.getSelections(),de=0;dep);W++){var J=w.getLine(q++);z=z==null?J:z+` +`+J}X=X*2,M.lastIndex=N.ch;var P=M.exec(z);if(P){var $=z.slice(0,P.index).split(` +`),F=P[0].split(` +`),G=N.line+$.length-1,c=$[$.length-1].length;return{from:pe(G,c),to:pe(G+F.length-1,F.length==1?c+F[0].length:F[F.length-1].length),match:P}}}}function I(w,M,N){for(var z,X=0;X<=w.length;){M.lastIndex=X;var q=M.exec(w);if(!q)break;var p=q.index+q[0].length;if(p>w.length-N)break;(!z||p>z.index+z[0].length)&&(z=q),X=q.index+1}return z}function Y(w,M,N){M=te(M,"g");for(var z=N.line,X=N.ch,q=w.firstLine();z>=q;z--,X=-1){var p=w.getLine(z),W=I(p,M,X<0?0:p.length-X);if(W)return{from:pe(z,W.index),to:pe(z,W.index+W[0].length),match:W}}}function ne(w,M,N){if(!oe(M))return Y(w,M,N);M=te(M,"gm");for(var z,X=1,q=w.getLine(N.line).length-N.ch,p=N.line,W=w.firstLine();p>=W;){for(var J=0;J=W;J++){var P=w.getLine(p--);z=z==null?P:P+` +`+z}X*=2;var $=I(z,M,q);if($){var F=z.slice(0,$.index).split(` +`),G=$[0].split(` +`),c=p+F.length,T=F[F.length-1].length;return{from:pe(c,T),to:pe(c+G.length-1,G.length==1?T+G[0].length:G[G.length-1].length),match:$}}}}var S,R;String.prototype.normalize?(S=function(w){return w.normalize("NFD").toLowerCase()},R=function(w){return w.normalize("NFD")}):(S=function(w){return w.toLowerCase()},R=function(w){return w});function A(w,M,N,z){if(w.length==M.length)return N;for(var X=0,q=N+Math.max(0,w.length-M.length);;){if(X==q)return X;var p=X+q>>1,W=z(w.slice(0,p)).length;if(W==N)return p;W>N?q=p:X=p+1}}function V(w,M,N,z){if(!M.length)return null;var X=z?S:R,q=X(M).split(/\r|\n\r?/);e:for(var p=N.line,W=N.ch,J=w.lastLine()+1-q.length;p<=J;p++,W=0){var P=w.getLine(p).slice(W),$=X(P);if(q.length==1){var F=$.indexOf(q[0]);if(F==-1)continue e;var N=A(P,$,F,X)+W;return{from:pe(p,A(P,$,F,X)+W),to:pe(p,A(P,$,F+q[0].length,X)+W)}}else{var G=$.length-q[0].length;if($.slice(G)!=q[0])continue e;for(var c=1;c=J;p--,W=-1){var P=w.getLine(p);W>-1&&(P=P.slice(0,W));var $=X(P);if(q.length==1){var F=$.lastIndexOf(q[0]);if(F==-1)continue e;return{from:pe(p,A(P,$,F,X)),to:pe(p,A(P,$,F+q[0].length,X))}}else{var G=q[q.length-1];if($.slice(0,G.length)!=G)continue e;for(var c=1,N=p-q.length+1;c(this.doc.getLine(M.line)||"").length&&(M.ch=0,M.line++)),b.cmpPos(M,this.doc.clipPos(M))!=0))return this.atOccurrence=!1;var N=this.matches(w,M);if(this.afterEmptyMatch=N&&b.cmpPos(N.from,N.to)==0,N)return this.pos=N,this.atOccurrence=!0,this.pos.match||!0;var z=pe(w?this.doc.firstLine():this.doc.lastLine()+1,0);return this.pos={from:z,to:z},this.atOccurrence=!1},from:function(){if(this.atOccurrence)return this.pos.from},to:function(){if(this.atOccurrence)return this.pos.to},replace:function(w,M){if(this.atOccurrence){var N=b.splitLines(w);this.doc.replaceRange(N,this.pos.from,this.pos.to,M),this.pos.to=pe(this.pos.from.line+N.length-1,N[N.length-1].length+(N.length==1?this.pos.from.ch:0))}}},b.defineExtension("getSearchCursor",function(w,M,N){return new O(this.doc,w,M,N)}),b.defineDocExtension("getSearchCursor",function(w,M,N){return new O(this,w,M,N)}),b.defineExtension("selectMatches",function(w,M){for(var N=[],z=this.getSearchCursor(w,this.getCursor("from"),M);z.findNext()&&!(b.cmpPos(z.to(),this.getCursor("to"))>0);)N.push({anchor:z.from(),head:z.to()});N.length&&this.setSelections(N,0)})})})()),Ha.exports}var qa={exports:{}},ja;function po(){return ja||(ja=1,(function(ct,xt){(function(b){b(mt())})(function(b){function pe(te,oe,Q){var k=te.getWrapperElement(),I;return I=k.appendChild(document.createElement("div")),Q?I.className="CodeMirror-dialog CodeMirror-dialog-bottom":I.className="CodeMirror-dialog CodeMirror-dialog-top",typeof oe=="string"?I.innerHTML=oe:I.appendChild(oe),b.addClass(k,"dialog-opened"),I}function _(te,oe){te.state.currentNotificationClose&&te.state.currentNotificationClose(),te.state.currentNotificationClose=oe}b.defineExtension("openDialog",function(te,oe,Q){Q||(Q={}),_(this,null);var k=pe(this,te,Q.bottom),I=!1,Y=this;function ne(A){if(typeof A=="string")S.value=A;else{if(I)return;I=!0,b.rmClass(k.parentNode,"dialog-opened"),k.parentNode.removeChild(k),Y.focus(),Q.onClose&&Q.onClose(k)}}var S=k.getElementsByTagName("input")[0],R;return S?(S.focus(),Q.value&&(S.value=Q.value,Q.selectValueOnOpen!==!1&&S.select()),Q.onInput&&b.on(S,"input",function(A){Q.onInput(A,S.value,ne)}),Q.onKeyUp&&b.on(S,"keyup",function(A){Q.onKeyUp(A,S.value,ne)}),b.on(S,"keydown",function(A){Q&&Q.onKeyDown&&Q.onKeyDown(A,S.value,ne)||((A.keyCode==27||Q.closeOnEnter!==!1&&A.keyCode==13)&&(S.blur(),b.e_stop(A),ne()),A.keyCode==13&&oe(S.value,A))}),Q.closeOnBlur!==!1&&b.on(k,"focusout",function(A){A.relatedTarget!==null&&ne()})):(R=k.getElementsByTagName("button")[0])&&(b.on(R,"click",function(){ne(),Y.focus()}),Q.closeOnBlur!==!1&&b.on(R,"blur",ne),R.focus()),ne}),b.defineExtension("openConfirm",function(te,oe,Q){_(this,null);var k=pe(this,te,Q&&Q.bottom),I=k.getElementsByTagName("button"),Y=!1,ne=this,S=1;function R(){Y||(Y=!0,b.rmClass(k.parentNode,"dialog-opened"),k.parentNode.removeChild(k),ne.focus())}I[0].focus();for(var A=0;Ap.cursorCoords(y,"window").top&&((G=j).style.opacity=.4)}))};k(p,w(p),F,c,function(T,C){var g=b.keyName(T),y=p.getOption("extraKeys"),j=y&&y[g]||b.keyMap[p.getOption("keyMap")][g];j=="findNext"||j=="findPrev"||j=="findPersistentNext"||j=="findPersistentPrev"?(b.e_stop(T),R(p,te(p),C),p.execCommand(j)):(j=="find"||j=="findPersistent")&&(b.e_stop(T),c(C,T))}),P&&F&&(R(p,$,F),V(p,W))}else I(p,w(p),"Search for:",F,function(T){T&&!$.query&&p.operation(function(){R(p,$,T),$.posFrom=$.posTo=p.getCursor(),V(p,W)})})}function V(p,W,J){p.operation(function(){var P=te(p),$=Q(p,P.query,W?P.posFrom:P.posTo);!$.find(W)&&($=Q(p,P.query,W?b.Pos(p.lastLine()):b.Pos(p.firstLine(),0)),!$.find(W))||(p.setSelection($.from(),$.to()),p.scrollIntoView({from:$.from(),to:$.to()},20),P.posFrom=$.from(),P.posTo=$.to(),J&&J($.from(),$.to()))})}function ue(p){p.operation(function(){var W=te(p);W.lastQuery=W.query,W.query&&(W.query=W.queryText=null,p.removeOverlay(W.overlay),W.annotate&&(W.annotate.clear(),W.annotate=null))})}function O(p,W){var J=p?document.createElement(p):document.createDocumentFragment();for(var P in W)J[P]=W[P];for(var $=2;$ '+oe.phrase("(Use line:column or scroll% syntax)")+""}function te(oe,Q){var k=Number(Q);return/^[-+]/.test(Q)?oe.getCursor().line+k:k-1}b.commands.jumpToLine=function(oe){var Q=oe.getCursor();pe(oe,_(oe),oe.phrase("Jump to line:"),Q.line+1+":"+Q.ch,function(k){if(k){var I;if(I=/^\s*([\+\-]?\d+)\s*\:\s*(\d+)\s*$/.exec(k))oe.setCursor(te(oe,I[1]),Number(I[2]));else if(I=/^\s*([\+\-]?\d+(\.\d+)?)\%\s*/.exec(k)){var Y=Math.round(oe.lineCount()*Number(I[1])/100);/^[-+]/.test(I[1])&&(Y=Q.line+Y+1),oe.setCursor(Y-1,Q.ch)}else(I=/^\s*\:?\s*([\+\-]?\d+)\s*/.exec(k))&&oe.setCursor(te(oe,I[1]),Q.ch)}})},b.keyMap.default["Alt-G"]="jumpToLine"})})()),Ua.exports}ff();po();export{df as default}; diff --git a/skills/playwright-scraper-skill-1-2-0/node_modules/playwright-core/lib/vite/traceViewer/assets/defaultSettingsView-CJSZINFr.js b/skills/playwright-scraper-skill-1-2-0/node_modules/playwright-core/lib/vite/traceViewer/assets/defaultSettingsView-CJSZINFr.js new file mode 100644 index 0000000..ae17ee8 --- /dev/null +++ b/skills/playwright-scraper-skill-1-2-0/node_modules/playwright-core/lib/vite/traceViewer/assets/defaultSettingsView-CJSZINFr.js @@ -0,0 +1,266 @@ +const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["./codeMirrorModule-a5XoALAZ.js","../codeMirrorModule.DYBRYzYX.css"])))=>i.map(i=>d[i]); +var rx=Object.defineProperty;var ax=(n,e,i)=>e in n?rx(n,e,{enumerable:!0,configurable:!0,writable:!0,value:i}):n[e]=i;var Ma=(n,e,i)=>ax(n,typeof e!="symbol"?e+"":e,i);(function(){const e=document.createElement("link").relList;if(e&&e.supports&&e.supports("modulepreload"))return;for(const l of document.querySelectorAll('link[rel="modulepreload"]'))r(l);new MutationObserver(l=>{for(const o of l)if(o.type==="childList")for(const u of o.addedNodes)u.tagName==="LINK"&&u.rel==="modulepreload"&&r(u)}).observe(document,{childList:!0,subtree:!0});function i(l){const o={};return l.integrity&&(o.integrity=l.integrity),l.referrerPolicy&&(o.referrerPolicy=l.referrerPolicy),l.crossOrigin==="use-credentials"?o.credentials="include":l.crossOrigin==="anonymous"?o.credentials="omit":o.credentials="same-origin",o}function r(l){if(l.ep)return;l.ep=!0;const o=i(l);fetch(l.href,o)}})();function lx(n){return n&&n.__esModule&&Object.prototype.hasOwnProperty.call(n,"default")?n.default:n}var th={exports:{}},Oa={};/** + * @license React + * react-jsx-runtime.production.js + * + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */var Hy;function ox(){if(Hy)return Oa;Hy=1;var n=Symbol.for("react.transitional.element"),e=Symbol.for("react.fragment");function i(r,l,o){var u=null;if(o!==void 0&&(u=""+o),l.key!==void 0&&(u=""+l.key),"key"in l){o={};for(var f in l)f!=="key"&&(o[f]=l[f])}else o=l;return l=o.ref,{$$typeof:n,type:r,key:u,ref:l!==void 0?l:null,props:o}}return Oa.Fragment=e,Oa.jsx=i,Oa.jsxs=i,Oa}var qy;function cx(){return qy||(qy=1,th.exports=ox()),th.exports}var S=cx(),nh={exports:{}},fe={};/** + * @license React + * react.production.js + * + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */var $y;function ux(){if($y)return fe;$y=1;var n=Symbol.for("react.transitional.element"),e=Symbol.for("react.portal"),i=Symbol.for("react.fragment"),r=Symbol.for("react.strict_mode"),l=Symbol.for("react.profiler"),o=Symbol.for("react.consumer"),u=Symbol.for("react.context"),f=Symbol.for("react.forward_ref"),h=Symbol.for("react.suspense"),g=Symbol.for("react.memo"),y=Symbol.for("react.lazy"),m=Symbol.for("react.activity"),w=Symbol.iterator;function v(k){return k===null||typeof k!="object"?null:(k=w&&k[w]||k["@@iterator"],typeof k=="function"?k:null)}var E={isMounted:function(){return!1},enqueueForceUpdate:function(){},enqueueReplaceState:function(){},enqueueSetState:function(){}},x=Object.assign,_={};function N(k,Y,Z){this.props=k,this.context=Y,this.refs=_,this.updater=Z||E}N.prototype.isReactComponent={},N.prototype.setState=function(k,Y){if(typeof k!="object"&&typeof k!="function"&&k!=null)throw Error("takes an object of state variables to update or a function which returns an object of state variables.");this.updater.enqueueSetState(this,k,Y,"setState")},N.prototype.forceUpdate=function(k){this.updater.enqueueForceUpdate(this,k,"forceUpdate")};function C(){}C.prototype=N.prototype;function $(k,Y,Z){this.props=k,this.context=Y,this.refs=_,this.updater=Z||E}var I=$.prototype=new C;I.constructor=$,x(I,N.prototype),I.isPureReactComponent=!0;var D=Array.isArray;function K(){}var Q={H:null,A:null,T:null,S:null},q=Object.prototype.hasOwnProperty;function j(k,Y,Z){var ee=Z.ref;return{$$typeof:n,type:k,key:Y,ref:ee!==void 0?ee:null,props:Z}}function ne(k,Y){return j(k.type,Y,k.props)}function le(k){return typeof k=="object"&&k!==null&&k.$$typeof===n}function V(k){var Y={"=":"=0",":":"=2"};return"$"+k.replace(/[=:]/g,function(Z){return Y[Z]})}var J=/\/+/g;function W(k,Y){return typeof k=="object"&&k!==null&&k.key!=null?V(""+k.key):Y.toString(36)}function Ae(k){switch(k.status){case"fulfilled":return k.value;case"rejected":throw k.reason;default:switch(typeof k.status=="string"?k.then(K,K):(k.status="pending",k.then(function(Y){k.status==="pending"&&(k.status="fulfilled",k.value=Y)},function(Y){k.status==="pending"&&(k.status="rejected",k.reason=Y)})),k.status){case"fulfilled":return k.value;case"rejected":throw k.reason}}throw k}function B(k,Y,Z,ee,ue){var re=typeof k;(re==="undefined"||re==="boolean")&&(k=null);var xe=!1;if(k===null)xe=!0;else switch(re){case"bigint":case"string":case"number":xe=!0;break;case"object":switch(k.$$typeof){case n:case e:xe=!0;break;case y:return xe=k._init,B(xe(k._payload),Y,Z,ee,ue)}}if(xe)return ue=ue(k),xe=ee===""?"."+W(k,0):ee,D(ue)?(Z="",xe!=null&&(Z=xe.replace(J,"$&/")+"/"),B(ue,Y,Z,"",function(Bi){return Bi})):ue!=null&&(le(ue)&&(ue=ne(ue,Z+(ue.key==null||k&&k.key===ue.key?"":(""+ue.key).replace(J,"$&/")+"/")+xe)),Y.push(ue)),1;xe=0;var tt=ee===""?".":ee+":";if(D(k))for(var Re=0;Re{let u=!1;return n().then(f=>{u||o(f)}),()=>{u=!0}},e),l}function gs(){const n=gt.useRef(null),[e]=Eh(n);return[e,n]}function Eh(n){const[e,i]=gt.useState(new DOMRect(0,0,10,10)),r=gt.useCallback(()=>{const l=n==null?void 0:n.current;l&&i(l.getBoundingClientRect())},[n]);return gt.useLayoutEffect(()=>{const l=n==null?void 0:n.current;if(!l)return;r();const o=new ResizeObserver(r);return o.observe(l),window.addEventListener("resize",r),()=>{o.disconnect(),window.removeEventListener("resize",r)}},[r,n]),[e,r]}function Et(n){if(n<0||!isFinite(n))return"-";if(n===0)return"0";if(n<1e3)return n.toFixed(0)+"ms";const e=n/1e3;if(e<60)return e.toFixed(1)+"s";const i=e/60;if(i<60)return i.toFixed(1)+"m";const r=i/60;return r<24?r.toFixed(1)+"h":(r/24).toFixed(1)+"d"}function fx(n){if(n<0||!isFinite(n))return"-";if(n===0)return"0";if(n<1e3)return n.toFixed(0);const e=n/1024;if(e<1e3)return e.toFixed(1)+"K";const i=e/1024;return i<1e3?i.toFixed(1)+"M":(i/1024).toFixed(1)+"G"}function F0(n,e,i,r,l){let o=0,u=n.length;for(;o>1;i(e,n[f])>=0?o=f+1:u=f}return u}function Vy(n){const e=document.createElement("textarea");e.style.position="absolute",e.style.zIndex="-1000",e.value=n,document.body.appendChild(e),e.select(),document.execCommand("copy"),e.remove()}function on(n,e){n&&(e=ls.getObject(n,e));const[i,r]=gt.useState(e),l=gt.useCallback(o=>{n?ls.setObject(n,o):r(o)},[n,r]);return gt.useEffect(()=>{if(n){const o=()=>r(ls.getObject(n,e));return ls.onChangeEmitter.addEventListener(n,o),()=>ls.onChangeEmitter.removeEventListener(n,o)}},[e,n]),[i,l]}const Ah=new Map,Q0=new Map;let tc;function ki(n,e){const[i,r]=gt.useState();Q0.set(n,{setter:r,defaultValue:e});const l=gt.useCallback(o=>{const u=Ah.get(tc||"default")||{};u[n]=o,Ah.set(tc||"default",u),r(o)},[n]);return[i,l]}function hx(n){if(tc===n)return;tc=n;const e=Ah.get(n)||{};for(const[i,r]of Q0.entries())r.setter(e[i]||r.defaultValue)}class dx{constructor(){this.onChangeEmitter=new EventTarget}getString(e,i){return localStorage[e]||i}setString(e,i){var r;localStorage[e]=i,this.onChangeEmitter.dispatchEvent(new Event(e)),(r=window.saveSettings)==null||r.call(window)}getObject(e,i){if(!localStorage[e])return i;try{return JSON.parse(localStorage[e])}catch{return i}}setObject(e,i){var r;localStorage[e]=JSON.stringify(i),this.onChangeEmitter.dispatchEvent(new Event(e)),(r=window.saveSettings)==null||r.call(window)}}const ls=new dx;function Fe(...n){return n.filter(Boolean).join(" ")}function J0(n){n&&(n!=null&&n.scrollIntoViewIfNeeded?n.scrollIntoViewIfNeeded(!1):n==null||n.scrollIntoView())}const Gy="\\u0000-\\u0020\\u007f-\\u009f",P0=new RegExp("(?:[a-zA-Z][a-zA-Z0-9+.-]{2,}:\\/\\/|www\\.)[^\\s"+Gy+'"]{2,}[^\\s'+Gy+`"')}\\],:;.!?]`,"ug");function px(){const[n,e]=gt.useState(!1),i=gt.useCallback(()=>{const r=[];return e(l=>(r.push(setTimeout(()=>e(!1),1e3)),l?(r.push(setTimeout(()=>e(!0),50)),!1):!0)),()=>r.forEach(clearTimeout)},[e]);return[n,i]}const gx="system",Z0="theme",mx=[{label:"Dark mode",value:"dark-mode"},{label:"Light mode",value:"light-mode"},{label:"System",value:"system"}],W0=window.matchMedia("(prefers-color-scheme: dark)");function LC(){document.playwrightThemeInitialized||(document.playwrightThemeInitialized=!0,document.defaultView.addEventListener("focus",n=>{n.target.document.nodeType===Node.DOCUMENT_NODE&&document.body.classList.remove("inactive")},!1),document.defaultView.addEventListener("blur",n=>{document.body.classList.add("inactive")},!1),Nh(Ch()),W0.addEventListener("change",()=>{Nh(Ch())}))}const Fh=new Set;function Nh(n){const e=yx(),i=n==="system"?W0.matches?"dark-mode":"light-mode":n;if(e!==i){e&&document.documentElement.classList.remove(e),document.documentElement.classList.add(i);for(const r of Fh)r(i)}}function RC(n){Fh.add(n)}function DC(n){Fh.delete(n)}function Ch(){return ls.getString(Z0,gx)}function yx(){return document.documentElement.classList.contains("dark-mode")?"dark-mode":document.documentElement.classList.contains("light-mode")?"light-mode":null}function bx(){const[n,e]=gt.useState(Ch());return gt.useEffect(()=>{ls.setString(Z0,n),Nh(n)},[n]),[n,e]}var ih={exports:{}},ja={},sh={exports:{}},rh={};/** + * @license React + * scheduler.production.js + * + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */var Ky;function vx(){return Ky||(Ky=1,(function(n){function e(B,P){var se=B.length;B.push(P);e:for(;0>>1,we=B[Se];if(0>>1;Sel(Z,se))eel(ue,Z)?(B[Se]=ue,B[ee]=se,Se=ee):(B[Se]=Z,B[Y]=se,Se=Y);else if(eel(ue,se))B[Se]=ue,B[ee]=se,Se=ee;else break e}}return P}function l(B,P){var se=B.sortIndex-P.sortIndex;return se!==0?se:B.id-P.id}if(n.unstable_now=void 0,typeof performance=="object"&&typeof performance.now=="function"){var o=performance;n.unstable_now=function(){return o.now()}}else{var u=Date,f=u.now();n.unstable_now=function(){return u.now()-f}}var h=[],g=[],y=1,m=null,w=3,v=!1,E=!1,x=!1,_=!1,N=typeof setTimeout=="function"?setTimeout:null,C=typeof clearTimeout=="function"?clearTimeout:null,$=typeof setImmediate<"u"?setImmediate:null;function I(B){for(var P=i(g);P!==null;){if(P.callback===null)r(g);else if(P.startTime<=B)r(g),P.sortIndex=P.expirationTime,e(h,P);else break;P=i(g)}}function D(B){if(x=!1,I(B),!E)if(i(h)!==null)E=!0,K||(K=!0,V());else{var P=i(g);P!==null&&Ae(D,P.startTime-B)}}var K=!1,Q=-1,q=5,j=-1;function ne(){return _?!0:!(n.unstable_now()-jB&&ne());){var Se=m.callback;if(typeof Se=="function"){m.callback=null,w=m.priorityLevel;var we=Se(m.expirationTime<=B);if(B=n.unstable_now(),typeof we=="function"){m.callback=we,I(B),P=!0;break t}m===i(h)&&r(h),I(B)}else r(h);m=i(h)}if(m!==null)P=!0;else{var k=i(g);k!==null&&Ae(D,k.startTime-B),P=!1}}break e}finally{m=null,w=se,v=!1}P=void 0}}finally{P?V():K=!1}}}var V;if(typeof $=="function")V=function(){$(le)};else if(typeof MessageChannel<"u"){var J=new MessageChannel,W=J.port2;J.port1.onmessage=le,V=function(){W.postMessage(null)}}else V=function(){N(le,0)};function Ae(B,P){Q=N(function(){B(n.unstable_now())},P)}n.unstable_IdlePriority=5,n.unstable_ImmediatePriority=1,n.unstable_LowPriority=4,n.unstable_NormalPriority=3,n.unstable_Profiling=null,n.unstable_UserBlockingPriority=2,n.unstable_cancelCallback=function(B){B.callback=null},n.unstable_forceFrameRate=function(B){0>B||125Se?(B.sortIndex=se,e(g,B),i(h)===null&&B===i(g)&&(x?(C(Q),Q=-1):x=!0,Ae(D,se-Se))):(B.sortIndex=we,e(h,B),E||v||(E=!0,K||(K=!0,V()))),B},n.unstable_shouldYield=ne,n.unstable_wrapCallback=function(B){var P=w;return function(){var se=w;w=P;try{return B.apply(this,arguments)}finally{w=se}}}})(rh)),rh}var Yy;function Sx(){return Yy||(Yy=1,sh.exports=vx()),sh.exports}var ah={exports:{}},yt={};/** + * @license React + * react-dom.production.js + * + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */var Xy;function wx(){if(Xy)return yt;Xy=1;var n=Xh();function e(h){var g="https://react.dev/errors/"+h;if(1"u"||typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE!="function"))try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(n)}catch(e){console.error(e)}}return n(),ah.exports=wx(),ah.exports}/** + * @license React + * react-dom-client.production.js + * + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */var Qy;function _x(){if(Qy)return ja;Qy=1;var n=Sx(),e=Xh(),i=xx();function r(t){var s="https://react.dev/errors/"+t;if(1we||(t.current=Se[we],Se[we]=null,we--)}function Z(t,s){we++,Se[we]=t.current,t.current=s}var ee=k(null),ue=k(null),re=k(null),xe=k(null);function tt(t,s){switch(Z(re,s),Z(ue,t),Z(ee,null),s.nodeType){case 9:case 11:t=(t=s.documentElement)&&(t=t.namespaceURI)?oy(t):0;break;default:if(t=s.tagName,s=s.namespaceURI)s=oy(s),t=cy(s,t);else switch(t){case"svg":t=1;break;case"math":t=2;break;default:t=0}}Y(ee),Z(ee,t)}function Re(){Y(ee),Y(ue),Y(re)}function Bi(t){t.memoizedState!==null&&Z(xe,t);var s=ee.current,a=cy(s,t.type);s!==a&&(Z(ue,t),Z(ee,a))}function kn(t){ue.current===t&&(Y(ee),Y(ue)),xe.current===t&&(Y(xe),Aa._currentValue=se)}var hn,Dr;function nt(t){if(hn===void 0)try{throw Error()}catch(a){var s=a.stack.trim().match(/\n( *(at )?)/);hn=s&&s[1]||"",Dr=-1)":-1d||A[c]!==R[d]){var G=` +`+A[c].replace(" at new "," at ");return t.displayName&&G.includes("")&&(G=G.replace("",t.displayName)),G}while(1<=c&&0<=d);break}}}finally{vs=!1,Error.prepareStackTrace=a}return(a=t?t.displayName||t.name:"")?nt(a):""}function zc(t,s){switch(t.tag){case 26:case 27:case 5:return nt(t.type);case 16:return nt("Lazy");case 13:return t.child!==s&&s!==null?nt("Suspense Fallback"):nt("Suspense");case 19:return nt("SuspenseList");case 0:case 15:return zr(t.type,!1);case 11:return zr(t.type.render,!1);case 1:return zr(t.type,!0);case 31:return nt("Activity");default:return""}}function Ss(t){try{var s="",a=null;do s+=zc(t,a),a=t,t=t.return;while(t);return s}catch(c){return` +Error generating stack: `+c.message+` +`+c.stack}}var Ui=Object.prototype.hasOwnProperty,ni=n.unstable_scheduleCallback,Br=n.unstable_cancelCallback,ii=n.unstable_shouldYield,Bc=n.unstable_requestPaint,St=n.unstable_now,Uc=n.unstable_getCurrentPriorityLevel,dl=n.unstable_ImmediatePriority,Ur=n.unstable_UserBlockingPriority,si=n.unstable_NormalPriority,Hc=n.unstable_LowPriority,pl=n.unstable_IdlePriority,qc=n.log,Hi=n.unstable_setDisableYieldValue,Mn=null,rt=null;function vn(t){if(typeof qc=="function"&&Hi(t),rt&&typeof rt.setStrictMode=="function")try{rt.setStrictMode(Mn,t)}catch{}}var wt=Math.clz32?Math.clz32:ce,$c=Math.log,gl=Math.LN2;function ce(t){return t>>>=0,t===0?32:31-($c(t)/gl|0)|0}var Sn=256,Ft=262144,ml=4194304;function qi(t){var s=t&42;if(s!==0)return s;switch(t&-t){case 1:return 1;case 2:return 2;case 4:return 4;case 8:return 8;case 16:return 16;case 32:return 32;case 64:return 64;case 128:return 128;case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:return t&261888;case 262144:case 524288:case 1048576:case 2097152:return t&3932160;case 4194304:case 8388608:case 16777216:case 33554432:return t&62914560;case 67108864:return 67108864;case 134217728:return 134217728;case 268435456:return 268435456;case 536870912:return 536870912;case 1073741824:return 0;default:return t}}function yl(t,s,a){var c=t.pendingLanes;if(c===0)return 0;var d=0,p=t.suspendedLanes,b=t.pingedLanes;t=t.warmLanes;var T=c&134217727;return T!==0?(c=T&~p,c!==0?d=qi(c):(b&=T,b!==0?d=qi(b):a||(a=T&~t,a!==0&&(d=qi(a))))):(T=c&~p,T!==0?d=qi(T):b!==0?d=qi(b):a||(a=c&~t,a!==0&&(d=qi(a)))),d===0?0:s!==0&&s!==d&&(s&p)===0&&(p=d&-d,a=s&-s,p>=a||p===32&&(a&4194048)!==0)?s:d}function Hr(t,s){return(t.pendingLanes&~(t.suspendedLanes&~t.pingedLanes)&s)===0}function YS(t,s){switch(t){case 1:case 2:case 4:case 8:case 64:return s+250;case 16:case 32:case 128:case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:case 262144:case 524288:case 1048576:case 2097152:return s+5e3;case 4194304:case 8388608:case 16777216:case 33554432:return-1;case 67108864:case 134217728:case 268435456:case 536870912:case 1073741824:return-1;default:return-1}}function Vd(){var t=ml;return ml<<=1,(ml&62914560)===0&&(ml=4194304),t}function Ic(t){for(var s=[],a=0;31>a;a++)s.push(t);return s}function qr(t,s){t.pendingLanes|=s,s!==268435456&&(t.suspendedLanes=0,t.pingedLanes=0,t.warmLanes=0)}function XS(t,s,a,c,d,p){var b=t.pendingLanes;t.pendingLanes=a,t.suspendedLanes=0,t.pingedLanes=0,t.warmLanes=0,t.expiredLanes&=a,t.entangledLanes&=a,t.errorRecoveryDisabledLanes&=a,t.shellSuspendCounter=0;var T=t.entanglements,A=t.expirationTimes,R=t.hiddenUpdates;for(a=b&~a;0"u")return null;try{return t.activeElement||t.body}catch{return t.body}}var WS=/[\n"\\]/g;function Jt(t){return t.replace(WS,function(s){return"\\"+s.charCodeAt(0).toString(16)+" "})}function Fc(t,s,a,c,d,p,b,T){t.name="",b!=null&&typeof b!="function"&&typeof b!="symbol"&&typeof b!="boolean"?t.type=b:t.removeAttribute("type"),s!=null?b==="number"?(s===0&&t.value===""||t.value!=s)&&(t.value=""+Qt(s)):t.value!==""+Qt(s)&&(t.value=""+Qt(s)):b!=="submit"&&b!=="reset"||t.removeAttribute("value"),s!=null?Qc(t,b,Qt(s)):a!=null?Qc(t,b,Qt(a)):c!=null&&t.removeAttribute("value"),d==null&&p!=null&&(t.defaultChecked=!!p),d!=null&&(t.checked=d&&typeof d!="function"&&typeof d!="symbol"),T!=null&&typeof T!="function"&&typeof T!="symbol"&&typeof T!="boolean"?t.name=""+Qt(T):t.removeAttribute("name")}function np(t,s,a,c,d,p,b,T){if(p!=null&&typeof p!="function"&&typeof p!="symbol"&&typeof p!="boolean"&&(t.type=p),s!=null||a!=null){if(!(p!=="submit"&&p!=="reset"||s!=null)){Xc(t);return}a=a!=null?""+Qt(a):"",s=s!=null?""+Qt(s):a,T||s===t.value||(t.value=s),t.defaultValue=s}c=c??d,c=typeof c!="function"&&typeof c!="symbol"&&!!c,t.checked=T?t.checked:!!c,t.defaultChecked=!!c,b!=null&&typeof b!="function"&&typeof b!="symbol"&&typeof b!="boolean"&&(t.name=b),Xc(t)}function Qc(t,s,a){s==="number"&&Sl(t.ownerDocument)===t||t.defaultValue===""+a||(t.defaultValue=""+a)}function As(t,s,a,c){if(t=t.options,s){s={};for(var d=0;d"u"||typeof window.document>"u"||typeof window.document.createElement>"u"),eu=!1;if(Ln)try{var Gr={};Object.defineProperty(Gr,"passive",{get:function(){eu=!0}}),window.addEventListener("test",Gr,Gr),window.removeEventListener("test",Gr,Gr)}catch{eu=!1}var ai=null,tu=null,xl=null;function cp(){if(xl)return xl;var t,s=tu,a=s.length,c,d="value"in ai?ai.value:ai.textContent,p=d.length;for(t=0;t=Xr),gp=" ",mp=!1;function yp(t,s){switch(t){case"keyup":return N1.indexOf(s.keyCode)!==-1;case"keydown":return s.keyCode!==229;case"keypress":case"mousedown":case"focusout":return!0;default:return!1}}function bp(t){return t=t.detail,typeof t=="object"&&"data"in t?t.data:null}var Ms=!1;function k1(t,s){switch(t){case"compositionend":return bp(s);case"keypress":return s.which!==32?null:(mp=!0,gp);case"textInput":return t=s.data,t===gp&&mp?null:t;default:return null}}function M1(t,s){if(Ms)return t==="compositionend"||!au&&yp(t,s)?(t=cp(),xl=tu=ai=null,Ms=!1,t):null;switch(t){case"paste":return null;case"keypress":if(!(s.ctrlKey||s.altKey||s.metaKey)||s.ctrlKey&&s.altKey){if(s.char&&1=s)return{node:a,offset:s-t};t=c}e:{for(;a;){if(a.nextSibling){a=a.nextSibling;break e}a=a.parentNode}a=void 0}a=Ap(a)}}function Cp(t,s){return t&&s?t===s?!0:t&&t.nodeType===3?!1:s&&s.nodeType===3?Cp(t,s.parentNode):"contains"in t?t.contains(s):t.compareDocumentPosition?!!(t.compareDocumentPosition(s)&16):!1:!1}function kp(t){t=t!=null&&t.ownerDocument!=null&&t.ownerDocument.defaultView!=null?t.ownerDocument.defaultView:window;for(var s=Sl(t.document);s instanceof t.HTMLIFrameElement;){try{var a=typeof s.contentWindow.location.href=="string"}catch{a=!1}if(a)t=s.contentWindow;else break;s=Sl(t.document)}return s}function cu(t){var s=t&&t.nodeName&&t.nodeName.toLowerCase();return s&&(s==="input"&&(t.type==="text"||t.type==="search"||t.type==="tel"||t.type==="url"||t.type==="password")||s==="textarea"||t.contentEditable==="true")}var U1=Ln&&"documentMode"in document&&11>=document.documentMode,Os=null,uu=null,Pr=null,fu=!1;function Mp(t,s,a){var c=a.window===a?a.document:a.nodeType===9?a:a.ownerDocument;fu||Os==null||Os!==Sl(c)||(c=Os,"selectionStart"in c&&cu(c)?c={start:c.selectionStart,end:c.selectionEnd}:(c=(c.ownerDocument&&c.ownerDocument.defaultView||window).getSelection(),c={anchorNode:c.anchorNode,anchorOffset:c.anchorOffset,focusNode:c.focusNode,focusOffset:c.focusOffset}),Pr&&Jr(Pr,c)||(Pr=c,c=mo(uu,"onSelect"),0>=b,d-=b,wn=1<<32-wt(s)+d|a<pe?(be=ie,ie=null):be=ie.sibling;var Te=z(O,ie,L[pe],X);if(Te===null){ie===null&&(ie=be);break}t&&ie&&Te.alternate===null&&s(O,ie),M=p(Te,M,pe),_e===null?ae=Te:_e.sibling=Te,_e=Te,ie=be}if(pe===L.length)return a(O,ie),ve&&Dn(O,pe),ae;if(ie===null){for(;pepe?(be=ie,ie=null):be=ie.sibling;var Ci=z(O,ie,Te.value,X);if(Ci===null){ie===null&&(ie=be);break}t&&ie&&Ci.alternate===null&&s(O,ie),M=p(Ci,M,pe),_e===null?ae=Ci:_e.sibling=Ci,_e=Ci,ie=be}if(Te.done)return a(O,ie),ve&&Dn(O,pe),ae;if(ie===null){for(;!Te.done;pe++,Te=L.next())Te=F(O,Te.value,X),Te!==null&&(M=p(Te,M,pe),_e===null?ae=Te:_e.sibling=Te,_e=Te);return ve&&Dn(O,pe),ae}for(ie=c(ie);!Te.done;pe++,Te=L.next())Te=H(ie,O,pe,Te.value,X),Te!==null&&(t&&Te.alternate!==null&&ie.delete(Te.key===null?pe:Te.key),M=p(Te,M,pe),_e===null?ae=Te:_e.sibling=Te,_e=Te);return t&&ie.forEach(function(sx){return s(O,sx)}),ve&&Dn(O,pe),ae}function Oe(O,M,L,X){if(typeof L=="object"&&L!==null&&L.type===x&&L.key===null&&(L=L.props.children),typeof L=="object"&&L!==null){switch(L.$$typeof){case v:e:{for(var ae=L.key;M!==null;){if(M.key===ae){if(ae=L.type,ae===x){if(M.tag===7){a(O,M.sibling),X=d(M,L.props.children),X.return=O,O=X;break e}}else if(M.elementType===ae||typeof ae=="object"&&ae!==null&&ae.$$typeof===q&&Pi(ae)===M.type){a(O,M.sibling),X=d(M,L.props),ia(X,L),X.return=O,O=X;break e}a(O,M);break}else s(O,M);M=M.sibling}L.type===x?(X=Yi(L.props.children,O.mode,X,L.key),X.return=O,O=X):(X=jl(L.type,L.key,L.props,null,O.mode,X),ia(X,L),X.return=O,O=X)}return b(O);case E:e:{for(ae=L.key;M!==null;){if(M.key===ae)if(M.tag===4&&M.stateNode.containerInfo===L.containerInfo&&M.stateNode.implementation===L.implementation){a(O,M.sibling),X=d(M,L.children||[]),X.return=O,O=X;break e}else{a(O,M);break}else s(O,M);M=M.sibling}X=bu(L,O.mode,X),X.return=O,O=X}return b(O);case q:return L=Pi(L),Oe(O,M,L,X)}if(Ae(L))return te(O,M,L,X);if(V(L)){if(ae=V(L),typeof ae!="function")throw Error(r(150));return L=ae.call(L),oe(O,M,L,X)}if(typeof L.then=="function")return Oe(O,M,Hl(L),X);if(L.$$typeof===$)return Oe(O,M,Dl(O,L),X);ql(O,L)}return typeof L=="string"&&L!==""||typeof L=="number"||typeof L=="bigint"?(L=""+L,M!==null&&M.tag===6?(a(O,M.sibling),X=d(M,L),X.return=O,O=X):(a(O,M),X=yu(L,O.mode,X),X.return=O,O=X),b(O)):a(O,M)}return function(O,M,L,X){try{na=0;var ae=Oe(O,M,L,X);return Is=null,ae}catch(ie){if(ie===$s||ie===Bl)throw ie;var _e=$t(29,ie,null,O.mode);return _e.lanes=X,_e.return=O,_e}finally{}}}var Wi=Wp(!0),eg=Wp(!1),fi=!1;function Mu(t){t.updateQueue={baseState:t.memoizedState,firstBaseUpdate:null,lastBaseUpdate:null,shared:{pending:null,lanes:0,hiddenCallbacks:null},callbacks:null}}function Ou(t,s){t=t.updateQueue,s.updateQueue===t&&(s.updateQueue={baseState:t.baseState,firstBaseUpdate:t.firstBaseUpdate,lastBaseUpdate:t.lastBaseUpdate,shared:t.shared,callbacks:null})}function hi(t){return{lane:t,tag:0,payload:null,callback:null,next:null}}function di(t,s,a){var c=t.updateQueue;if(c===null)return null;if(c=c.shared,(Ee&2)!==0){var d=c.pending;return d===null?s.next=s:(s.next=d.next,d.next=s),c.pending=s,s=Ol(t),Bp(t,null,a),s}return Ml(t,c,s,a),Ol(t)}function sa(t,s,a){if(s=s.updateQueue,s!==null&&(s=s.shared,(a&4194048)!==0)){var c=s.lanes;c&=t.pendingLanes,a|=c,s.lanes=a,Kd(t,a)}}function ju(t,s){var a=t.updateQueue,c=t.alternate;if(c!==null&&(c=c.updateQueue,a===c)){var d=null,p=null;if(a=a.firstBaseUpdate,a!==null){do{var b={lane:a.lane,tag:a.tag,payload:a.payload,callback:null,next:null};p===null?d=p=b:p=p.next=b,a=a.next}while(a!==null);p===null?d=p=s:p=p.next=s}else d=p=s;a={baseState:c.baseState,firstBaseUpdate:d,lastBaseUpdate:p,shared:c.shared,callbacks:c.callbacks},t.updateQueue=a;return}t=a.lastBaseUpdate,t===null?a.firstBaseUpdate=s:t.next=s,a.lastBaseUpdate=s}var Lu=!1;function ra(){if(Lu){var t=qs;if(t!==null)throw t}}function aa(t,s,a,c){Lu=!1;var d=t.updateQueue;fi=!1;var p=d.firstBaseUpdate,b=d.lastBaseUpdate,T=d.shared.pending;if(T!==null){d.shared.pending=null;var A=T,R=A.next;A.next=null,b===null?p=R:b.next=R,b=A;var G=t.alternate;G!==null&&(G=G.updateQueue,T=G.lastBaseUpdate,T!==b&&(T===null?G.firstBaseUpdate=R:T.next=R,G.lastBaseUpdate=A))}if(p!==null){var F=d.baseState;b=0,G=R=A=null,T=p;do{var z=T.lane&-536870913,H=z!==T.lane;if(H?(ye&z)===z:(c&z)===z){z!==0&&z===Hs&&(Lu=!0),G!==null&&(G=G.next={lane:0,tag:T.tag,payload:T.payload,callback:null,next:null});e:{var te=t,oe=T;z=s;var Oe=a;switch(oe.tag){case 1:if(te=oe.payload,typeof te=="function"){F=te.call(Oe,F,z);break e}F=te;break e;case 3:te.flags=te.flags&-65537|128;case 0:if(te=oe.payload,z=typeof te=="function"?te.call(Oe,F,z):te,z==null)break e;F=m({},F,z);break e;case 2:fi=!0}}z=T.callback,z!==null&&(t.flags|=64,H&&(t.flags|=8192),H=d.callbacks,H===null?d.callbacks=[z]:H.push(z))}else H={lane:z,tag:T.tag,payload:T.payload,callback:T.callback,next:null},G===null?(R=G=H,A=F):G=G.next=H,b|=z;if(T=T.next,T===null){if(T=d.shared.pending,T===null)break;H=T,T=H.next,H.next=null,d.lastBaseUpdate=H,d.shared.pending=null}}while(!0);G===null&&(A=F),d.baseState=A,d.firstBaseUpdate=R,d.lastBaseUpdate=G,p===null&&(d.shared.lanes=0),bi|=b,t.lanes=b,t.memoizedState=F}}function tg(t,s){if(typeof t!="function")throw Error(r(191,t));t.call(s)}function ng(t,s){var a=t.callbacks;if(a!==null)for(t.callbacks=null,t=0;tp?p:8;var b=B.T,T={};B.T=T,Zu(t,!1,s,a);try{var A=d(),R=B.S;if(R!==null&&R(T,A),A!==null&&typeof A=="object"&&typeof A.then=="function"){var G=X1(A,c);ca(t,s,G,Yt(t))}else ca(t,s,c,Yt(t))}catch(F){ca(t,s,{then:function(){},status:"rejected",reason:F},Yt())}finally{P.p=p,b!==null&&T.types!==null&&(b.types=T.types),B.T=b}}function W1(){}function Ju(t,s,a,c){if(t.tag!==5)throw Error(r(476));var d=Rg(t).queue;Lg(t,d,s,se,a===null?W1:function(){return Dg(t),a(c)})}function Rg(t){var s=t.memoizedState;if(s!==null)return s;s={memoizedState:se,baseState:se,baseQueue:null,queue:{pending:null,lanes:0,dispatch:null,lastRenderedReducer:Hn,lastRenderedState:se},next:null};var a={};return s.next={memoizedState:a,baseState:a,baseQueue:null,queue:{pending:null,lanes:0,dispatch:null,lastRenderedReducer:Hn,lastRenderedState:a},next:null},t.memoizedState=s,t=t.alternate,t!==null&&(t.memoizedState=s),s}function Dg(t){var s=Rg(t);s.next===null&&(s=t.alternate.memoizedState),ca(t,s.next.queue,{},Yt())}function Pu(){return ut(Aa)}function zg(){return Ye().memoizedState}function Bg(){return Ye().memoizedState}function ew(t){for(var s=t.return;s!==null;){switch(s.tag){case 24:case 3:var a=Yt();t=hi(a);var c=di(s,t,a);c!==null&&(Lt(c,s,a),sa(c,s,a)),s={cache:Au()},t.payload=s;return}s=s.return}}function tw(t,s,a){var c=Yt();a={lane:c,revertLane:0,gesture:null,action:a,hasEagerState:!1,eagerState:null,next:null},Jl(t)?Hg(s,a):(a=gu(t,s,a,c),a!==null&&(Lt(a,t,c),qg(a,s,c)))}function Ug(t,s,a){var c=Yt();ca(t,s,a,c)}function ca(t,s,a,c){var d={lane:c,revertLane:0,gesture:null,action:a,hasEagerState:!1,eagerState:null,next:null};if(Jl(t))Hg(s,d);else{var p=t.alternate;if(t.lanes===0&&(p===null||p.lanes===0)&&(p=s.lastRenderedReducer,p!==null))try{var b=s.lastRenderedState,T=p(b,a);if(d.hasEagerState=!0,d.eagerState=T,qt(T,b))return Ml(t,s,d,0),je===null&&kl(),!1}catch{}finally{}if(a=gu(t,s,d,c),a!==null)return Lt(a,t,c),qg(a,s,c),!0}return!1}function Zu(t,s,a,c){if(c={lane:2,revertLane:Of(),gesture:null,action:c,hasEagerState:!1,eagerState:null,next:null},Jl(t)){if(s)throw Error(r(479))}else s=gu(t,a,c,2),s!==null&&Lt(s,t,2)}function Jl(t){var s=t.alternate;return t===de||s!==null&&s===de}function Hg(t,s){Gs=Vl=!0;var a=t.pending;a===null?s.next=s:(s.next=a.next,a.next=s),t.pending=s}function qg(t,s,a){if((a&4194048)!==0){var c=s.lanes;c&=t.pendingLanes,a|=c,s.lanes=a,Kd(t,a)}}var ua={readContext:ut,use:Yl,useCallback:Ve,useContext:Ve,useEffect:Ve,useImperativeHandle:Ve,useLayoutEffect:Ve,useInsertionEffect:Ve,useMemo:Ve,useReducer:Ve,useRef:Ve,useState:Ve,useDebugValue:Ve,useDeferredValue:Ve,useTransition:Ve,useSyncExternalStore:Ve,useId:Ve,useHostTransitionStatus:Ve,useFormState:Ve,useActionState:Ve,useOptimistic:Ve,useMemoCache:Ve,useCacheRefresh:Ve};ua.useEffectEvent=Ve;var $g={readContext:ut,use:Yl,useCallback:function(t,s){return xt().memoizedState=[t,s===void 0?null:s],t},useContext:ut,useEffect:Tg,useImperativeHandle:function(t,s,a){a=a!=null?a.concat([t]):null,Fl(4194308,4,Cg.bind(null,s,t),a)},useLayoutEffect:function(t,s){return Fl(4194308,4,t,s)},useInsertionEffect:function(t,s){Fl(4,2,t,s)},useMemo:function(t,s){var a=xt();s=s===void 0?null:s;var c=t();if(es){vn(!0);try{t()}finally{vn(!1)}}return a.memoizedState=[c,s],c},useReducer:function(t,s,a){var c=xt();if(a!==void 0){var d=a(s);if(es){vn(!0);try{a(s)}finally{vn(!1)}}}else d=s;return c.memoizedState=c.baseState=d,t={pending:null,lanes:0,dispatch:null,lastRenderedReducer:t,lastRenderedState:d},c.queue=t,t=t.dispatch=tw.bind(null,de,t),[c.memoizedState,t]},useRef:function(t){var s=xt();return t={current:t},s.memoizedState=t},useState:function(t){t=Ku(t);var s=t.queue,a=Ug.bind(null,de,s);return s.dispatch=a,[t.memoizedState,a]},useDebugValue:Fu,useDeferredValue:function(t,s){var a=xt();return Qu(a,t,s)},useTransition:function(){var t=Ku(!1);return t=Lg.bind(null,de,t.queue,!0,!1),xt().memoizedState=t,[!1,t]},useSyncExternalStore:function(t,s,a){var c=de,d=xt();if(ve){if(a===void 0)throw Error(r(407));a=a()}else{if(a=s(),je===null)throw Error(r(349));(ye&127)!==0||og(c,s,a)}d.memoizedState=a;var p={value:a,getSnapshot:s};return d.queue=p,Tg(ug.bind(null,c,p,t),[t]),c.flags|=2048,Ys(9,{destroy:void 0},cg.bind(null,c,p,a,s),null),a},useId:function(){var t=xt(),s=je.identifierPrefix;if(ve){var a=xn,c=wn;a=(c&~(1<<32-wt(c)-1)).toString(32)+a,s="_"+s+"R_"+a,a=Gl++,0<\/script>",p=p.removeChild(p.firstChild);break;case"select":p=typeof c.is=="string"?b.createElement("select",{is:c.is}):b.createElement("select"),c.multiple?p.multiple=!0:c.size&&(p.size=c.size);break;default:p=typeof c.is=="string"?b.createElement(d,{is:c.is}):b.createElement(d)}}p[ot]=s,p[Nt]=c;e:for(b=s.child;b!==null;){if(b.tag===5||b.tag===6)p.appendChild(b.stateNode);else if(b.tag!==4&&b.tag!==27&&b.child!==null){b.child.return=b,b=b.child;continue}if(b===s)break e;for(;b.sibling===null;){if(b.return===null||b.return===s)break e;b=b.return}b.sibling.return=b.return,b=b.sibling}s.stateNode=p;e:switch(ht(p,d,c),d){case"button":case"input":case"select":case"textarea":c=!!c.autoFocus;break e;case"img":c=!0;break e;default:c=!1}c&&$n(s)}}return ze(s),df(s,s.type,t===null?null:t.memoizedProps,s.pendingProps,a),null;case 6:if(t&&s.stateNode!=null)t.memoizedProps!==c&&$n(s);else{if(typeof c!="string"&&s.stateNode===null)throw Error(r(166));if(t=re.current,Bs(s)){if(t=s.stateNode,a=s.memoizedProps,c=null,d=ct,d!==null)switch(d.tag){case 27:case 5:c=d.memoizedProps}t[ot]=s,t=!!(t.nodeValue===a||c!==null&&c.suppressHydrationWarning===!0||ay(t.nodeValue,a)),t||ci(s,!0)}else t=yo(t).createTextNode(c),t[ot]=s,s.stateNode=t}return ze(s),null;case 31:if(a=s.memoizedState,t===null||t.memoizedState!==null){if(c=Bs(s),a!==null){if(t===null){if(!c)throw Error(r(318));if(t=s.memoizedState,t=t!==null?t.dehydrated:null,!t)throw Error(r(557));t[ot]=s}else Xi(),(s.flags&128)===0&&(s.memoizedState=null),s.flags|=4;ze(s),t=!1}else a=xu(),t!==null&&t.memoizedState!==null&&(t.memoizedState.hydrationErrors=a),t=!0;if(!t)return s.flags&256?(Vt(s),s):(Vt(s),null);if((s.flags&128)!==0)throw Error(r(558))}return ze(s),null;case 13:if(c=s.memoizedState,t===null||t.memoizedState!==null&&t.memoizedState.dehydrated!==null){if(d=Bs(s),c!==null&&c.dehydrated!==null){if(t===null){if(!d)throw Error(r(318));if(d=s.memoizedState,d=d!==null?d.dehydrated:null,!d)throw Error(r(317));d[ot]=s}else Xi(),(s.flags&128)===0&&(s.memoizedState=null),s.flags|=4;ze(s),d=!1}else d=xu(),t!==null&&t.memoizedState!==null&&(t.memoizedState.hydrationErrors=d),d=!0;if(!d)return s.flags&256?(Vt(s),s):(Vt(s),null)}return Vt(s),(s.flags&128)!==0?(s.lanes=a,s):(a=c!==null,t=t!==null&&t.memoizedState!==null,a&&(c=s.child,d=null,c.alternate!==null&&c.alternate.memoizedState!==null&&c.alternate.memoizedState.cachePool!==null&&(d=c.alternate.memoizedState.cachePool.pool),p=null,c.memoizedState!==null&&c.memoizedState.cachePool!==null&&(p=c.memoizedState.cachePool.pool),p!==d&&(c.flags|=2048)),a!==t&&a&&(s.child.flags|=8192),to(s,s.updateQueue),ze(s),null);case 4:return Re(),t===null&&Df(s.stateNode.containerInfo),ze(s),null;case 10:return Bn(s.type),ze(s),null;case 19:if(Y(Ke),c=s.memoizedState,c===null)return ze(s),null;if(d=(s.flags&128)!==0,p=c.rendering,p===null)if(d)ha(c,!1);else{if(Ge!==0||t!==null&&(t.flags&128)!==0)for(t=s.child;t!==null;){if(p=Il(t),p!==null){for(s.flags|=128,ha(c,!1),t=p.updateQueue,s.updateQueue=t,to(s,t),s.subtreeFlags=0,t=a,a=s.child;a!==null;)Up(a,t),a=a.sibling;return Z(Ke,Ke.current&1|2),ve&&Dn(s,c.treeForkCount),s.child}t=t.sibling}c.tail!==null&&St()>ao&&(s.flags|=128,d=!0,ha(c,!1),s.lanes=4194304)}else{if(!d)if(t=Il(p),t!==null){if(s.flags|=128,d=!0,t=t.updateQueue,s.updateQueue=t,to(s,t),ha(c,!0),c.tail===null&&c.tailMode==="hidden"&&!p.alternate&&!ve)return ze(s),null}else 2*St()-c.renderingStartTime>ao&&a!==536870912&&(s.flags|=128,d=!0,ha(c,!1),s.lanes=4194304);c.isBackwards?(p.sibling=s.child,s.child=p):(t=c.last,t!==null?t.sibling=p:s.child=p,c.last=p)}return c.tail!==null?(t=c.tail,c.rendering=t,c.tail=t.sibling,c.renderingStartTime=St(),t.sibling=null,a=Ke.current,Z(Ke,d?a&1|2:a&1),ve&&Dn(s,c.treeForkCount),t):(ze(s),null);case 22:case 23:return Vt(s),Du(),c=s.memoizedState!==null,t!==null?t.memoizedState!==null!==c&&(s.flags|=8192):c&&(s.flags|=8192),c?(a&536870912)!==0&&(s.flags&128)===0&&(ze(s),s.subtreeFlags&6&&(s.flags|=8192)):ze(s),a=s.updateQueue,a!==null&&to(s,a.retryQueue),a=null,t!==null&&t.memoizedState!==null&&t.memoizedState.cachePool!==null&&(a=t.memoizedState.cachePool.pool),c=null,s.memoizedState!==null&&s.memoizedState.cachePool!==null&&(c=s.memoizedState.cachePool.pool),c!==a&&(s.flags|=2048),t!==null&&Y(Ji),null;case 24:return a=null,t!==null&&(a=t.memoizedState.cache),s.memoizedState.cache!==a&&(s.flags|=2048),Bn(Je),ze(s),null;case 25:return null;case 30:return null}throw Error(r(156,s.tag))}function aw(t,s){switch(Su(s),s.tag){case 1:return t=s.flags,t&65536?(s.flags=t&-65537|128,s):null;case 3:return Bn(Je),Re(),t=s.flags,(t&65536)!==0&&(t&128)===0?(s.flags=t&-65537|128,s):null;case 26:case 27:case 5:return kn(s),null;case 31:if(s.memoizedState!==null){if(Vt(s),s.alternate===null)throw Error(r(340));Xi()}return t=s.flags,t&65536?(s.flags=t&-65537|128,s):null;case 13:if(Vt(s),t=s.memoizedState,t!==null&&t.dehydrated!==null){if(s.alternate===null)throw Error(r(340));Xi()}return t=s.flags,t&65536?(s.flags=t&-65537|128,s):null;case 19:return Y(Ke),null;case 4:return Re(),null;case 10:return Bn(s.type),null;case 22:case 23:return Vt(s),Du(),t!==null&&Y(Ji),t=s.flags,t&65536?(s.flags=t&-65537|128,s):null;case 24:return Bn(Je),null;case 25:return null;default:return null}}function fm(t,s){switch(Su(s),s.tag){case 3:Bn(Je),Re();break;case 26:case 27:case 5:kn(s);break;case 4:Re();break;case 31:s.memoizedState!==null&&Vt(s);break;case 13:Vt(s);break;case 19:Y(Ke);break;case 10:Bn(s.type);break;case 22:case 23:Vt(s),Du(),t!==null&&Y(Ji);break;case 24:Bn(Je)}}function da(t,s){try{var a=s.updateQueue,c=a!==null?a.lastEffect:null;if(c!==null){var d=c.next;a=d;do{if((a.tag&t)===t){c=void 0;var p=a.create,b=a.inst;c=p(),b.destroy=c}a=a.next}while(a!==d)}}catch(T){Ce(s,s.return,T)}}function mi(t,s,a){try{var c=s.updateQueue,d=c!==null?c.lastEffect:null;if(d!==null){var p=d.next;c=p;do{if((c.tag&t)===t){var b=c.inst,T=b.destroy;if(T!==void 0){b.destroy=void 0,d=s;var A=a,R=T;try{R()}catch(G){Ce(d,A,G)}}}c=c.next}while(c!==p)}}catch(G){Ce(s,s.return,G)}}function hm(t){var s=t.updateQueue;if(s!==null){var a=t.stateNode;try{ng(s,a)}catch(c){Ce(t,t.return,c)}}}function dm(t,s,a){a.props=ts(t.type,t.memoizedProps),a.state=t.memoizedState;try{a.componentWillUnmount()}catch(c){Ce(t,s,c)}}function pa(t,s){try{var a=t.ref;if(a!==null){switch(t.tag){case 26:case 27:case 5:var c=t.stateNode;break;case 30:c=t.stateNode;break;default:c=t.stateNode}typeof a=="function"?t.refCleanup=a(c):a.current=c}}catch(d){Ce(t,s,d)}}function _n(t,s){var a=t.ref,c=t.refCleanup;if(a!==null)if(typeof c=="function")try{c()}catch(d){Ce(t,s,d)}finally{t.refCleanup=null,t=t.alternate,t!=null&&(t.refCleanup=null)}else if(typeof a=="function")try{a(null)}catch(d){Ce(t,s,d)}else a.current=null}function pm(t){var s=t.type,a=t.memoizedProps,c=t.stateNode;try{e:switch(s){case"button":case"input":case"select":case"textarea":a.autoFocus&&c.focus();break e;case"img":a.src?c.src=a.src:a.srcSet&&(c.srcset=a.srcSet)}}catch(d){Ce(t,t.return,d)}}function pf(t,s,a){try{var c=t.stateNode;Cw(c,t.type,a,s),c[Nt]=s}catch(d){Ce(t,t.return,d)}}function gm(t){return t.tag===5||t.tag===3||t.tag===26||t.tag===27&&_i(t.type)||t.tag===4}function gf(t){e:for(;;){for(;t.sibling===null;){if(t.return===null||gm(t.return))return null;t=t.return}for(t.sibling.return=t.return,t=t.sibling;t.tag!==5&&t.tag!==6&&t.tag!==18;){if(t.tag===27&&_i(t.type)||t.flags&2||t.child===null||t.tag===4)continue e;t.child.return=t,t=t.child}if(!(t.flags&2))return t.stateNode}}function mf(t,s,a){var c=t.tag;if(c===5||c===6)t=t.stateNode,s?(a.nodeType===9?a.body:a.nodeName==="HTML"?a.ownerDocument.body:a).insertBefore(t,s):(s=a.nodeType===9?a.body:a.nodeName==="HTML"?a.ownerDocument.body:a,s.appendChild(t),a=a._reactRootContainer,a!=null||s.onclick!==null||(s.onclick=jn));else if(c!==4&&(c===27&&_i(t.type)&&(a=t.stateNode,s=null),t=t.child,t!==null))for(mf(t,s,a),t=t.sibling;t!==null;)mf(t,s,a),t=t.sibling}function no(t,s,a){var c=t.tag;if(c===5||c===6)t=t.stateNode,s?a.insertBefore(t,s):a.appendChild(t);else if(c!==4&&(c===27&&_i(t.type)&&(a=t.stateNode),t=t.child,t!==null))for(no(t,s,a),t=t.sibling;t!==null;)no(t,s,a),t=t.sibling}function mm(t){var s=t.stateNode,a=t.memoizedProps;try{for(var c=t.type,d=s.attributes;d.length;)s.removeAttributeNode(d[0]);ht(s,c,a),s[ot]=t,s[Nt]=a}catch(p){Ce(t,t.return,p)}}var In=!1,We=!1,yf=!1,ym=typeof WeakSet=="function"?WeakSet:Set,lt=null;function lw(t,s){if(t=t.containerInfo,Uf=To,t=kp(t),cu(t)){if("selectionStart"in t)var a={start:t.selectionStart,end:t.selectionEnd};else e:{a=(a=t.ownerDocument)&&a.defaultView||window;var c=a.getSelection&&a.getSelection();if(c&&c.rangeCount!==0){a=c.anchorNode;var d=c.anchorOffset,p=c.focusNode;c=c.focusOffset;try{a.nodeType,p.nodeType}catch{a=null;break e}var b=0,T=-1,A=-1,R=0,G=0,F=t,z=null;t:for(;;){for(var H;F!==a||d!==0&&F.nodeType!==3||(T=b+d),F!==p||c!==0&&F.nodeType!==3||(A=b+c),F.nodeType===3&&(b+=F.nodeValue.length),(H=F.firstChild)!==null;)z=F,F=H;for(;;){if(F===t)break t;if(z===a&&++R===d&&(T=b),z===p&&++G===c&&(A=b),(H=F.nextSibling)!==null)break;F=z,z=F.parentNode}F=H}a=T===-1||A===-1?null:{start:T,end:A}}else a=null}a=a||{start:0,end:0}}else a=null;for(Hf={focusedElem:t,selectionRange:a},To=!1,lt=s;lt!==null;)if(s=lt,t=s.child,(s.subtreeFlags&1028)!==0&&t!==null)t.return=s,lt=t;else for(;lt!==null;){switch(s=lt,p=s.alternate,t=s.flags,s.tag){case 0:if((t&4)!==0&&(t=s.updateQueue,t=t!==null?t.events:null,t!==null))for(a=0;a title"))),ht(p,c,a),p[ot]=t,at(p),c=p;break e;case"link":var b=_y("link","href",d).get(c+(a.href||""));if(b){for(var T=0;TOe&&(b=Oe,Oe=oe,oe=b);var O=Np(T,oe),M=Np(T,Oe);if(O&&M&&(H.rangeCount!==1||H.anchorNode!==O.node||H.anchorOffset!==O.offset||H.focusNode!==M.node||H.focusOffset!==M.offset)){var L=F.createRange();L.setStart(O.node,O.offset),H.removeAllRanges(),oe>Oe?(H.addRange(L),H.extend(M.node,M.offset)):(L.setEnd(M.node,M.offset),H.addRange(L))}}}}for(F=[],H=T;H=H.parentNode;)H.nodeType===1&&F.push({element:H,left:H.scrollLeft,top:H.scrollTop});for(typeof T.focus=="function"&&T.focus(),T=0;Ta?32:a,B.T=null,a=Tf,Tf=null;var p=Si,b=Xn;if(it=0,Ps=Si=null,Xn=0,(Ee&6)!==0)throw Error(r(331));var T=Ee;if(Ee|=4,Cm(p.current),Em(p,p.current,b,a),Ee=T,Sa(0,!1),rt&&typeof rt.onPostCommitFiberRoot=="function")try{rt.onPostCommitFiberRoot(Mn,p)}catch{}return!0}finally{P.p=d,B.T=c,Ym(t,s)}}function Fm(t,s,a){s=Zt(a,s),s=nf(t.stateNode,s,2),t=di(t,s,2),t!==null&&(qr(t,2),Tn(t))}function Ce(t,s,a){if(t.tag===3)Fm(t,t,a);else for(;s!==null;){if(s.tag===3){Fm(s,t,a);break}else if(s.tag===1){var c=s.stateNode;if(typeof s.type.getDerivedStateFromError=="function"||typeof c.componentDidCatch=="function"&&(vi===null||!vi.has(c))){t=Zt(a,t),a=Qg(2),c=di(s,a,2),c!==null&&(Jg(a,c,s,t),qr(c,2),Tn(c));break}}s=s.return}}function Cf(t,s,a){var c=t.pingCache;if(c===null){c=t.pingCache=new uw;var d=new Set;c.set(s,d)}else d=c.get(s),d===void 0&&(d=new Set,c.set(s,d));d.has(a)||(Sf=!0,d.add(a),t=gw.bind(null,t,s,a),s.then(t,t))}function gw(t,s,a){var c=t.pingCache;c!==null&&c.delete(s),t.pingedLanes|=t.suspendedLanes&a,t.warmLanes&=~a,je===t&&(ye&a)===a&&(Ge===4||Ge===3&&(ye&62914560)===ye&&300>St()-ro?(Ee&2)===0&&Zs(t,0):wf|=a,Js===ye&&(Js=0)),Tn(t)}function Qm(t,s){s===0&&(s=Vd()),t=Ki(t,s),t!==null&&(qr(t,s),Tn(t))}function mw(t){var s=t.memoizedState,a=0;s!==null&&(a=s.retryLane),Qm(t,a)}function yw(t,s){var a=0;switch(t.tag){case 31:case 13:var c=t.stateNode,d=t.memoizedState;d!==null&&(a=d.retryLane);break;case 19:c=t.stateNode;break;case 22:c=t.stateNode._retryCache;break;default:throw Error(r(314))}c!==null&&c.delete(s),Qm(t,a)}function bw(t,s){return ni(t,s)}var ho=null,er=null,kf=!1,po=!1,Mf=!1,xi=0;function Tn(t){t!==er&&t.next===null&&(er===null?ho=er=t:er=er.next=t),po=!0,kf||(kf=!0,Sw())}function Sa(t,s){if(!Mf&&po){Mf=!0;do for(var a=!1,c=ho;c!==null;){if(t!==0){var d=c.pendingLanes;if(d===0)var p=0;else{var b=c.suspendedLanes,T=c.pingedLanes;p=(1<<31-wt(42|t)+1)-1,p&=d&~(b&~T),p=p&201326741?p&201326741|1:p?p|2:0}p!==0&&(a=!0,Wm(c,p))}else p=ye,p=yl(c,c===je?p:0,c.cancelPendingCommit!==null||c.timeoutHandle!==-1),(p&3)===0||Hr(c,p)||(a=!0,Wm(c,p));c=c.next}while(a);Mf=!1}}function vw(){Jm()}function Jm(){po=kf=!1;var t=0;xi!==0&&Mw()&&(t=xi);for(var s=St(),a=null,c=ho;c!==null;){var d=c.next,p=Pm(c,s);p===0?(c.next=null,a===null?ho=d:a.next=d,d===null&&(er=a)):(a=c,(t!==0||(p&3)!==0)&&(po=!0)),c=d}it!==0&&it!==5||Sa(t),xi!==0&&(xi=0)}function Pm(t,s){for(var a=t.suspendedLanes,c=t.pingedLanes,d=t.expirationTimes,p=t.pendingLanes&-62914561;0T)break;var G=A.transferSize,F=A.initiatorType;G&&ly(F)&&(A=A.responseEnd,b+=G*(A"u"?null:document;function vy(t,s,a){var c=tr;if(c&&typeof s=="string"&&s){var d=Jt(s);d='link[rel="'+t+'"][href="'+d+'"]',typeof a=="string"&&(d+='[crossorigin="'+a+'"]'),by.has(d)||(by.add(d),t={rel:t,crossOrigin:a,href:s},c.querySelector(d)===null&&(s=c.createElement("link"),ht(s,"link",t),at(s),c.head.appendChild(s)))}}function Hw(t){Fn.D(t),vy("dns-prefetch",t,null)}function qw(t,s){Fn.C(t,s),vy("preconnect",t,s)}function $w(t,s,a){Fn.L(t,s,a);var c=tr;if(c&&t&&s){var d='link[rel="preload"][as="'+Jt(s)+'"]';s==="image"&&a&&a.imageSrcSet?(d+='[imagesrcset="'+Jt(a.imageSrcSet)+'"]',typeof a.imageSizes=="string"&&(d+='[imagesizes="'+Jt(a.imageSizes)+'"]')):d+='[href="'+Jt(t)+'"]';var p=d;switch(s){case"style":p=nr(t);break;case"script":p=ir(t)}rn.has(p)||(t=m({rel:"preload",href:s==="image"&&a&&a.imageSrcSet?void 0:t,as:s},a),rn.set(p,t),c.querySelector(d)!==null||s==="style"&&c.querySelector(Ta(p))||s==="script"&&c.querySelector(Ea(p))||(s=c.createElement("link"),ht(s,"link",t),at(s),c.head.appendChild(s)))}}function Iw(t,s){Fn.m(t,s);var a=tr;if(a&&t){var c=s&&typeof s.as=="string"?s.as:"script",d='link[rel="modulepreload"][as="'+Jt(c)+'"][href="'+Jt(t)+'"]',p=d;switch(c){case"audioworklet":case"paintworklet":case"serviceworker":case"sharedworker":case"worker":case"script":p=ir(t)}if(!rn.has(p)&&(t=m({rel:"modulepreload",href:t},s),rn.set(p,t),a.querySelector(d)===null)){switch(c){case"audioworklet":case"paintworklet":case"serviceworker":case"sharedworker":case"worker":case"script":if(a.querySelector(Ea(p)))return}c=a.createElement("link"),ht(c,"link",t),at(c),a.head.appendChild(c)}}}function Vw(t,s,a){Fn.S(t,s,a);var c=tr;if(c&&t){var d=Ts(c).hoistableStyles,p=nr(t);s=s||"default";var b=d.get(p);if(!b){var T={loading:0,preload:null};if(b=c.querySelector(Ta(p)))T.loading=5;else{t=m({rel:"stylesheet",href:t,"data-precedence":s},a),(a=rn.get(p))&&Yf(t,a);var A=b=c.createElement("link");at(A),ht(A,"link",t),A._p=new Promise(function(R,G){A.onload=R,A.onerror=G}),A.addEventListener("load",function(){T.loading|=1}),A.addEventListener("error",function(){T.loading|=2}),T.loading|=4,vo(b,s,c)}b={type:"stylesheet",instance:b,count:1,state:T},d.set(p,b)}}}function Gw(t,s){Fn.X(t,s);var a=tr;if(a&&t){var c=Ts(a).hoistableScripts,d=ir(t),p=c.get(d);p||(p=a.querySelector(Ea(d)),p||(t=m({src:t,async:!0},s),(s=rn.get(d))&&Xf(t,s),p=a.createElement("script"),at(p),ht(p,"link",t),a.head.appendChild(p)),p={type:"script",instance:p,count:1,state:null},c.set(d,p))}}function Kw(t,s){Fn.M(t,s);var a=tr;if(a&&t){var c=Ts(a).hoistableScripts,d=ir(t),p=c.get(d);p||(p=a.querySelector(Ea(d)),p||(t=m({src:t,async:!0,type:"module"},s),(s=rn.get(d))&&Xf(t,s),p=a.createElement("script"),at(p),ht(p,"link",t),a.head.appendChild(p)),p={type:"script",instance:p,count:1,state:null},c.set(d,p))}}function Sy(t,s,a,c){var d=(d=re.current)?bo(d):null;if(!d)throw Error(r(446));switch(t){case"meta":case"title":return null;case"style":return typeof a.precedence=="string"&&typeof a.href=="string"?(s=nr(a.href),a=Ts(d).hoistableStyles,c=a.get(s),c||(c={type:"style",instance:null,count:0,state:null},a.set(s,c)),c):{type:"void",instance:null,count:0,state:null};case"link":if(a.rel==="stylesheet"&&typeof a.href=="string"&&typeof a.precedence=="string"){t=nr(a.href);var p=Ts(d).hoistableStyles,b=p.get(t);if(b||(d=d.ownerDocument||d,b={type:"stylesheet",instance:null,count:0,state:{loading:0,preload:null}},p.set(t,b),(p=d.querySelector(Ta(t)))&&!p._p&&(b.instance=p,b.state.loading=5),rn.has(t)||(a={rel:"preload",as:"style",href:a.href,crossOrigin:a.crossOrigin,integrity:a.integrity,media:a.media,hrefLang:a.hrefLang,referrerPolicy:a.referrerPolicy},rn.set(t,a),p||Yw(d,t,a,b.state))),s&&c===null)throw Error(r(528,""));return b}if(s&&c!==null)throw Error(r(529,""));return null;case"script":return s=a.async,a=a.src,typeof a=="string"&&s&&typeof s!="function"&&typeof s!="symbol"?(s=ir(a),a=Ts(d).hoistableScripts,c=a.get(s),c||(c={type:"script",instance:null,count:0,state:null},a.set(s,c)),c):{type:"void",instance:null,count:0,state:null};default:throw Error(r(444,t))}}function nr(t){return'href="'+Jt(t)+'"'}function Ta(t){return'link[rel="stylesheet"]['+t+"]"}function wy(t){return m({},t,{"data-precedence":t.precedence,precedence:null})}function Yw(t,s,a,c){t.querySelector('link[rel="preload"][as="style"]['+s+"]")?c.loading=1:(s=t.createElement("link"),c.preload=s,s.addEventListener("load",function(){return c.loading|=1}),s.addEventListener("error",function(){return c.loading|=2}),ht(s,"link",a),at(s),t.head.appendChild(s))}function ir(t){return'[src="'+Jt(t)+'"]'}function Ea(t){return"script[async]"+t}function xy(t,s,a){if(s.count++,s.instance===null)switch(s.type){case"style":var c=t.querySelector('style[data-href~="'+Jt(a.href)+'"]');if(c)return s.instance=c,at(c),c;var d=m({},a,{"data-href":a.href,"data-precedence":a.precedence,href:null,precedence:null});return c=(t.ownerDocument||t).createElement("style"),at(c),ht(c,"style",d),vo(c,a.precedence,t),s.instance=c;case"stylesheet":d=nr(a.href);var p=t.querySelector(Ta(d));if(p)return s.state.loading|=4,s.instance=p,at(p),p;c=wy(a),(d=rn.get(d))&&Yf(c,d),p=(t.ownerDocument||t).createElement("link"),at(p);var b=p;return b._p=new Promise(function(T,A){b.onload=T,b.onerror=A}),ht(p,"link",c),s.state.loading|=4,vo(p,a.precedence,t),s.instance=p;case"script":return p=ir(a.src),(d=t.querySelector(Ea(p)))?(s.instance=d,at(d),d):(c=a,(d=rn.get(p))&&(c=m({},a),Xf(c,d)),t=t.ownerDocument||t,d=t.createElement("script"),at(d),ht(d,"link",c),t.head.appendChild(d),s.instance=d);case"void":return null;default:throw Error(r(443,s.type))}else s.type==="stylesheet"&&(s.state.loading&4)===0&&(c=s.instance,s.state.loading|=4,vo(c,a.precedence,t));return s.instance}function vo(t,s,a){for(var c=a.querySelectorAll('link[rel="stylesheet"][data-precedence],style[data-precedence]'),d=c.length?c[c.length-1]:null,p=d,b=0;b title"):null)}function Xw(t,s,a){if(a===1||s.itemProp!=null)return!1;switch(t){case"meta":case"title":return!0;case"style":if(typeof s.precedence!="string"||typeof s.href!="string"||s.href==="")break;return!0;case"link":if(typeof s.rel!="string"||typeof s.href!="string"||s.href===""||s.onLoad||s.onError)break;switch(s.rel){case"stylesheet":return t=s.disabled,typeof s.precedence=="string"&&t==null;default:return!0}case"script":if(s.async&&typeof s.async!="function"&&typeof s.async!="symbol"&&!s.onLoad&&!s.onError&&s.src&&typeof s.src=="string")return!0}return!1}function Ey(t){return!(t.type==="stylesheet"&&(t.state.loading&3)===0)}function Fw(t,s,a,c){if(a.type==="stylesheet"&&(typeof c.media!="string"||matchMedia(c.media).matches!==!1)&&(a.state.loading&4)===0){if(a.instance===null){var d=nr(c.href),p=s.querySelector(Ta(d));if(p){s=p._p,s!==null&&typeof s=="object"&&typeof s.then=="function"&&(t.count++,t=wo.bind(t),s.then(t,t)),a.state.loading|=4,a.instance=p,at(p);return}p=s.ownerDocument||s,c=wy(c),(d=rn.get(d))&&Yf(c,d),p=p.createElement("link"),at(p);var b=p;b._p=new Promise(function(T,A){b.onload=T,b.onerror=A}),ht(p,"link",c),a.instance=p}t.stylesheets===null&&(t.stylesheets=new Map),t.stylesheets.set(a,s),(s=a.state.preload)&&(a.state.loading&3)===0&&(t.count++,a=wo.bind(t),s.addEventListener("load",a),s.addEventListener("error",a))}}var Ff=0;function Qw(t,s){return t.stylesheets&&t.count===0&&_o(t,t.stylesheets),0Ff?50:800)+s);return t.unsuspend=a,function(){t.unsuspend=null,clearTimeout(c),clearTimeout(d)}}:null}function wo(){if(this.count--,this.count===0&&(this.imgCount===0||!this.waitingForImages)){if(this.stylesheets)_o(this,this.stylesheets);else if(this.unsuspend){var t=this.unsuspend;this.unsuspend=null,t()}}}var xo=null;function _o(t,s){t.stylesheets=null,t.unsuspend!==null&&(t.count++,xo=new Map,s.forEach(Jw,t),xo=null,wo.call(t))}function Jw(t,s){if(!(s.state.loading&4)){var a=xo.get(t);if(a)var c=a.get(null);else{a=new Map,xo.set(t,a);for(var d=t.querySelectorAll("link[data-precedence],style[data-precedence]"),p=0;p"u"||typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE!="function"))try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(n)}catch(e){console.error(e)}}return n(),ih.exports=_x(),ih.exports}var zC=Tx();const Qh=new Map([["APIRequestContext.fetch",{title:'{method} "{url}"'}],["APIRequestContext.fetchResponseBody",{title:"Get response body",group:"getter"}],["APIRequestContext.fetchLog",{internal:!0}],["APIRequestContext.storageState",{title:"Get storage state"}],["APIRequestContext.disposeAPIResponse",{internal:!0}],["APIRequestContext.dispose",{internal:!0}],["LocalUtils.zip",{internal:!0}],["LocalUtils.harOpen",{internal:!0}],["LocalUtils.harLookup",{internal:!0}],["LocalUtils.harClose",{internal:!0}],["LocalUtils.harUnzip",{internal:!0}],["LocalUtils.connect",{internal:!0}],["LocalUtils.tracingStarted",{internal:!0}],["LocalUtils.addStackToTracingNoReply",{internal:!0}],["LocalUtils.traceDiscarded",{internal:!0}],["LocalUtils.globToRegex",{internal:!0}],["Root.initialize",{internal:!0}],["Playwright.newRequest",{title:"Create request context"}],["DebugController.initialize",{internal:!0}],["DebugController.setReportStateChanged",{internal:!0}],["DebugController.setRecorderMode",{internal:!0}],["DebugController.highlight",{internal:!0}],["DebugController.hideHighlight",{internal:!0}],["DebugController.resume",{internal:!0}],["DebugController.kill",{internal:!0}],["SocksSupport.socksConnected",{internal:!0}],["SocksSupport.socksFailed",{internal:!0}],["SocksSupport.socksData",{internal:!0}],["SocksSupport.socksError",{internal:!0}],["SocksSupport.socksEnd",{internal:!0}],["BrowserType.launch",{title:"Launch browser"}],["BrowserType.launchPersistentContext",{title:"Launch persistent context"}],["BrowserType.connectOverCDP",{title:"Connect over CDP"}],["Browser.close",{title:"Close browser",pausesBeforeAction:!0}],["Browser.killForTests",{internal:!0}],["Browser.defaultUserAgentForTest",{internal:!0}],["Browser.newContext",{title:"Create context"}],["Browser.newContextForReuse",{internal:!0}],["Browser.disconnectFromReusedContext",{internal:!0}],["Browser.newBrowserCDPSession",{title:"Create CDP session",group:"configuration"}],["Browser.startTracing",{title:"Start browser tracing",group:"configuration"}],["Browser.stopTracing",{title:"Stop browser tracing",group:"configuration"}],["EventTarget.waitForEventInfo",{title:'Wait for event "{info.event}"',snapshot:!0}],["BrowserContext.waitForEventInfo",{title:'Wait for event "{info.event}"',snapshot:!0}],["Page.waitForEventInfo",{title:'Wait for event "{info.event}"',snapshot:!0}],["Worker.waitForEventInfo",{title:'Wait for event "{info.event}"',snapshot:!0}],["WebSocket.waitForEventInfo",{title:'Wait for event "{info.event}"',snapshot:!0}],["ElectronApplication.waitForEventInfo",{title:'Wait for event "{info.event}"',snapshot:!0}],["AndroidDevice.waitForEventInfo",{title:'Wait for event "{info.event}"',snapshot:!0}],["PageAgent.waitForEventInfo",{title:'Wait for event "{info.event}"',snapshot:!0}],["BrowserContext.addCookies",{title:"Add cookies",group:"configuration"}],["BrowserContext.addInitScript",{title:"Add init script",group:"configuration"}],["BrowserContext.clearCookies",{title:"Clear cookies",group:"configuration"}],["BrowserContext.clearPermissions",{title:"Clear permissions",group:"configuration"}],["BrowserContext.close",{title:"Close context",pausesBeforeAction:!0}],["BrowserContext.cookies",{title:"Get cookies",group:"getter"}],["BrowserContext.exposeBinding",{title:"Expose binding",group:"configuration"}],["BrowserContext.grantPermissions",{title:"Grant permissions",group:"configuration"}],["BrowserContext.newPage",{title:"Create page"}],["BrowserContext.registerSelectorEngine",{internal:!0}],["BrowserContext.setTestIdAttributeName",{internal:!0}],["BrowserContext.setExtraHTTPHeaders",{title:"Set extra HTTP headers",group:"configuration"}],["BrowserContext.setGeolocation",{title:"Set geolocation",group:"configuration"}],["BrowserContext.setHTTPCredentials",{title:"Set HTTP credentials",group:"configuration"}],["BrowserContext.setNetworkInterceptionPatterns",{title:"Route requests",group:"route"}],["BrowserContext.setWebSocketInterceptionPatterns",{title:"Route WebSockets",group:"route"}],["BrowserContext.setOffline",{title:"Set offline mode"}],["BrowserContext.storageState",{title:"Get storage state"}],["BrowserContext.pause",{title:"Pause"}],["BrowserContext.enableRecorder",{internal:!0}],["BrowserContext.disableRecorder",{internal:!0}],["BrowserContext.exposeConsoleApi",{internal:!0}],["BrowserContext.newCDPSession",{title:"Create CDP session",group:"configuration"}],["BrowserContext.harStart",{internal:!0}],["BrowserContext.harExport",{internal:!0}],["BrowserContext.createTempFiles",{internal:!0}],["BrowserContext.updateSubscription",{internal:!0}],["BrowserContext.clockFastForward",{title:'Fast forward clock "{ticksNumber|ticksString}"'}],["BrowserContext.clockInstall",{title:'Install clock "{timeNumber|timeString}"'}],["BrowserContext.clockPauseAt",{title:'Pause clock "{timeNumber|timeString}"'}],["BrowserContext.clockResume",{title:"Resume clock"}],["BrowserContext.clockRunFor",{title:'Run clock "{ticksNumber|ticksString}"'}],["BrowserContext.clockSetFixedTime",{title:'Set fixed time "{timeNumber|timeString}"'}],["BrowserContext.clockSetSystemTime",{title:'Set system time "{timeNumber|timeString}"'}],["Page.addInitScript",{title:"Add init script",group:"configuration"}],["Page.close",{title:"Close page",pausesBeforeAction:!0}],["Page.consoleMessages",{title:"Get console messages",group:"getter"}],["Page.emulateMedia",{title:"Emulate media",snapshot:!0,pausesBeforeAction:!0}],["Page.exposeBinding",{title:"Expose binding",group:"configuration"}],["Page.goBack",{title:"Go back",slowMo:!0,snapshot:!0,pausesBeforeAction:!0}],["Page.goForward",{title:"Go forward",slowMo:!0,snapshot:!0,pausesBeforeAction:!0}],["Page.requestGC",{title:"Request garbage collection",group:"configuration"}],["Page.registerLocatorHandler",{title:"Register locator handler"}],["Page.resolveLocatorHandlerNoReply",{internal:!0}],["Page.unregisterLocatorHandler",{title:"Unregister locator handler"}],["Page.reload",{title:"Reload",slowMo:!0,snapshot:!0,pausesBeforeAction:!0}],["Page.expectScreenshot",{title:"Expect screenshot",snapshot:!0,pausesBeforeAction:!0}],["Page.screenshot",{title:"Screenshot",snapshot:!0,pausesBeforeAction:!0}],["Page.setExtraHTTPHeaders",{title:"Set extra HTTP headers",group:"configuration"}],["Page.setNetworkInterceptionPatterns",{title:"Route requests",group:"route"}],["Page.setWebSocketInterceptionPatterns",{title:"Route WebSockets",group:"route"}],["Page.setViewportSize",{title:"Set viewport size",snapshot:!0,pausesBeforeAction:!0}],["Page.keyboardDown",{title:'Key down "{key}"',slowMo:!0,snapshot:!0,pausesBeforeAction:!0}],["Page.keyboardUp",{title:'Key up "{key}"',slowMo:!0,snapshot:!0,pausesBeforeAction:!0}],["Page.keyboardInsertText",{title:'Insert "{text}"',slowMo:!0,snapshot:!0,pausesBeforeAction:!0}],["Page.keyboardType",{title:'Type "{text}"',slowMo:!0,snapshot:!0,pausesBeforeAction:!0}],["Page.keyboardPress",{title:'Press "{key}"',slowMo:!0,snapshot:!0,pausesBeforeAction:!0}],["Page.mouseMove",{title:"Mouse move",slowMo:!0,snapshot:!0,pausesBeforeAction:!0}],["Page.mouseDown",{title:"Mouse down",slowMo:!0,snapshot:!0,pausesBeforeAction:!0}],["Page.mouseUp",{title:"Mouse up",slowMo:!0,snapshot:!0,pausesBeforeAction:!0}],["Page.mouseClick",{title:"Click",slowMo:!0,snapshot:!0,pausesBeforeAction:!0}],["Page.mouseWheel",{title:"Mouse wheel",slowMo:!0,snapshot:!0,pausesBeforeAction:!0}],["Page.touchscreenTap",{title:"Tap",slowMo:!0,snapshot:!0,pausesBeforeAction:!0}],["Page.pageErrors",{title:"Get page errors",group:"getter"}],["Page.pdf",{title:"PDF"}],["Page.requests",{title:"Get network requests",group:"getter"}],["Page.snapshotForAI",{internal:!0}],["Page.startJSCoverage",{title:"Start JS coverage",group:"configuration"}],["Page.stopJSCoverage",{title:"Stop JS coverage",group:"configuration"}],["Page.startCSSCoverage",{title:"Start CSS coverage",group:"configuration"}],["Page.stopCSSCoverage",{title:"Stop CSS coverage",group:"configuration"}],["Page.bringToFront",{title:"Bring to front"}],["Page.updateSubscription",{internal:!0}],["Page.agent",{internal:!0}],["Frame.evalOnSelector",{title:"Evaluate",snapshot:!0,pausesBeforeAction:!0}],["Frame.evalOnSelectorAll",{title:"Evaluate",snapshot:!0,pausesBeforeAction:!0}],["Frame.addScriptTag",{title:"Add script tag",snapshot:!0,pausesBeforeAction:!0}],["Frame.addStyleTag",{title:"Add style tag",snapshot:!0,pausesBeforeAction:!0}],["Frame.ariaSnapshot",{title:"Aria snapshot",snapshot:!0,pausesBeforeAction:!0}],["Frame.blur",{title:"Blur",slowMo:!0,snapshot:!0,pausesBeforeAction:!0}],["Frame.check",{title:"Check",slowMo:!0,snapshot:!0,pausesBeforeInput:!0}],["Frame.click",{title:"Click",slowMo:!0,snapshot:!0,pausesBeforeInput:!0}],["Frame.content",{title:"Get content",snapshot:!0,pausesBeforeAction:!0}],["Frame.dragAndDrop",{title:"Drag and drop",slowMo:!0,snapshot:!0,pausesBeforeInput:!0}],["Frame.dblclick",{title:"Double click",slowMo:!0,snapshot:!0,pausesBeforeInput:!0}],["Frame.dispatchEvent",{title:'Dispatch "{type}"',slowMo:!0,snapshot:!0,pausesBeforeAction:!0}],["Frame.evaluateExpression",{title:"Evaluate",snapshot:!0,pausesBeforeAction:!0}],["Frame.evaluateExpressionHandle",{title:"Evaluate",snapshot:!0,pausesBeforeAction:!0}],["Frame.fill",{title:'Fill "{value}"',slowMo:!0,snapshot:!0,pausesBeforeInput:!0}],["Frame.focus",{title:"Focus",slowMo:!0,snapshot:!0,pausesBeforeAction:!0}],["Frame.frameElement",{title:"Get frame element",group:"getter"}],["Frame.resolveSelector",{internal:!0}],["Frame.highlight",{title:"Highlight element",group:"configuration"}],["Frame.getAttribute",{title:'Get attribute "{name}"',snapshot:!0,pausesBeforeAction:!0,group:"getter"}],["Frame.goto",{title:'Navigate to "{url}"',slowMo:!0,snapshot:!0,pausesBeforeAction:!0}],["Frame.hover",{title:"Hover",slowMo:!0,snapshot:!0,pausesBeforeInput:!0}],["Frame.innerHTML",{title:"Get HTML",snapshot:!0,pausesBeforeAction:!0,group:"getter"}],["Frame.innerText",{title:"Get inner text",snapshot:!0,pausesBeforeAction:!0,group:"getter"}],["Frame.inputValue",{title:"Get input value",snapshot:!0,pausesBeforeAction:!0,group:"getter"}],["Frame.isChecked",{title:"Is checked",snapshot:!0,pausesBeforeAction:!0,group:"getter"}],["Frame.isDisabled",{title:"Is disabled",snapshot:!0,pausesBeforeAction:!0,group:"getter"}],["Frame.isEnabled",{title:"Is enabled",snapshot:!0,pausesBeforeAction:!0,group:"getter"}],["Frame.isHidden",{title:"Is hidden",snapshot:!0,pausesBeforeAction:!0,group:"getter"}],["Frame.isVisible",{title:"Is visible",snapshot:!0,pausesBeforeAction:!0,group:"getter"}],["Frame.isEditable",{title:"Is editable",snapshot:!0,pausesBeforeAction:!0,group:"getter"}],["Frame.press",{title:'Press "{key}"',slowMo:!0,snapshot:!0,pausesBeforeInput:!0}],["Frame.querySelector",{title:"Query selector",snapshot:!0}],["Frame.querySelectorAll",{title:"Query selector all",snapshot:!0}],["Frame.queryCount",{title:"Query count",snapshot:!0,pausesBeforeAction:!0}],["Frame.selectOption",{title:"Select option",slowMo:!0,snapshot:!0,pausesBeforeInput:!0}],["Frame.setContent",{title:"Set content",snapshot:!0,pausesBeforeAction:!0}],["Frame.setInputFiles",{title:"Set input files",slowMo:!0,snapshot:!0,pausesBeforeInput:!0}],["Frame.tap",{title:"Tap",slowMo:!0,snapshot:!0,pausesBeforeInput:!0}],["Frame.textContent",{title:"Get text content",snapshot:!0,pausesBeforeAction:!0,group:"getter"}],["Frame.title",{title:"Get page title",group:"getter"}],["Frame.type",{title:'Type "{text}"',slowMo:!0,snapshot:!0,pausesBeforeInput:!0}],["Frame.uncheck",{title:"Uncheck",slowMo:!0,snapshot:!0,pausesBeforeInput:!0}],["Frame.waitForTimeout",{title:"Wait for timeout",snapshot:!0}],["Frame.waitForFunction",{title:"Wait for function",snapshot:!0,pausesBeforeAction:!0}],["Frame.waitForSelector",{title:"Wait for selector",snapshot:!0}],["Frame.expect",{title:'Expect "{expression}"',snapshot:!0,pausesBeforeAction:!0}],["Worker.evaluateExpression",{title:"Evaluate"}],["Worker.evaluateExpressionHandle",{title:"Evaluate"}],["Worker.updateSubscription",{internal:!0}],["JSHandle.dispose",{internal:!0}],["ElementHandle.dispose",{internal:!0}],["JSHandle.evaluateExpression",{title:"Evaluate",snapshot:!0,pausesBeforeAction:!0}],["ElementHandle.evaluateExpression",{title:"Evaluate",snapshot:!0,pausesBeforeAction:!0}],["JSHandle.evaluateExpressionHandle",{title:"Evaluate",snapshot:!0,pausesBeforeAction:!0}],["ElementHandle.evaluateExpressionHandle",{title:"Evaluate",snapshot:!0,pausesBeforeAction:!0}],["JSHandle.getPropertyList",{title:"Get property list",group:"getter"}],["ElementHandle.getPropertyList",{title:"Get property list",group:"getter"}],["JSHandle.getProperty",{title:"Get JS property",group:"getter"}],["ElementHandle.getProperty",{title:"Get JS property",group:"getter"}],["JSHandle.jsonValue",{title:"Get JSON value",group:"getter"}],["ElementHandle.jsonValue",{title:"Get JSON value",group:"getter"}],["ElementHandle.evalOnSelector",{title:"Evaluate",snapshot:!0,pausesBeforeAction:!0}],["ElementHandle.evalOnSelectorAll",{title:"Evaluate",snapshot:!0,pausesBeforeAction:!0}],["ElementHandle.boundingBox",{title:"Get bounding box",snapshot:!0,pausesBeforeAction:!0}],["ElementHandle.check",{title:"Check",slowMo:!0,snapshot:!0,pausesBeforeInput:!0}],["ElementHandle.click",{title:"Click",slowMo:!0,snapshot:!0,pausesBeforeInput:!0}],["ElementHandle.contentFrame",{title:"Get content frame",group:"getter"}],["ElementHandle.dblclick",{title:"Double click",slowMo:!0,snapshot:!0,pausesBeforeInput:!0}],["ElementHandle.dispatchEvent",{title:"Dispatch event",slowMo:!0,snapshot:!0,pausesBeforeAction:!0}],["ElementHandle.fill",{title:'Fill "{value}"',slowMo:!0,snapshot:!0,pausesBeforeInput:!0}],["ElementHandle.focus",{title:"Focus",slowMo:!0,snapshot:!0,pausesBeforeAction:!0}],["ElementHandle.getAttribute",{title:"Get attribute",snapshot:!0,pausesBeforeAction:!0,group:"getter"}],["ElementHandle.hover",{title:"Hover",slowMo:!0,snapshot:!0,pausesBeforeInput:!0}],["ElementHandle.innerHTML",{title:"Get HTML",snapshot:!0,pausesBeforeAction:!0,group:"getter"}],["ElementHandle.innerText",{title:"Get inner text",snapshot:!0,pausesBeforeAction:!0,group:"getter"}],["ElementHandle.inputValue",{title:"Get input value",snapshot:!0,pausesBeforeAction:!0,group:"getter"}],["ElementHandle.isChecked",{title:"Is checked",snapshot:!0,pausesBeforeAction:!0,group:"getter"}],["ElementHandle.isDisabled",{title:"Is disabled",snapshot:!0,pausesBeforeAction:!0,group:"getter"}],["ElementHandle.isEditable",{title:"Is editable",snapshot:!0,pausesBeforeAction:!0,group:"getter"}],["ElementHandle.isEnabled",{title:"Is enabled",snapshot:!0,pausesBeforeAction:!0,group:"getter"}],["ElementHandle.isHidden",{title:"Is hidden",snapshot:!0,pausesBeforeAction:!0,group:"getter"}],["ElementHandle.isVisible",{title:"Is visible",snapshot:!0,pausesBeforeAction:!0,group:"getter"}],["ElementHandle.ownerFrame",{title:"Get owner frame",group:"getter"}],["ElementHandle.press",{title:'Press "{key}"',slowMo:!0,snapshot:!0,pausesBeforeInput:!0}],["ElementHandle.querySelector",{title:"Query selector",snapshot:!0}],["ElementHandle.querySelectorAll",{title:"Query selector all",snapshot:!0}],["ElementHandle.screenshot",{title:"Screenshot",snapshot:!0,pausesBeforeAction:!0}],["ElementHandle.scrollIntoViewIfNeeded",{title:"Scroll into view",slowMo:!0,snapshot:!0,pausesBeforeAction:!0}],["ElementHandle.selectOption",{title:"Select option",slowMo:!0,snapshot:!0,pausesBeforeInput:!0}],["ElementHandle.selectText",{title:"Select text",slowMo:!0,snapshot:!0,pausesBeforeAction:!0}],["ElementHandle.setInputFiles",{title:"Set input files",slowMo:!0,snapshot:!0,pausesBeforeInput:!0}],["ElementHandle.tap",{title:"Tap",slowMo:!0,snapshot:!0,pausesBeforeInput:!0}],["ElementHandle.textContent",{title:"Get text content",snapshot:!0,pausesBeforeAction:!0,group:"getter"}],["ElementHandle.type",{title:"Type",slowMo:!0,snapshot:!0,pausesBeforeInput:!0}],["ElementHandle.uncheck",{title:"Uncheck",slowMo:!0,snapshot:!0,pausesBeforeInput:!0}],["ElementHandle.waitForElementState",{title:"Wait for state",snapshot:!0,pausesBeforeAction:!0}],["ElementHandle.waitForSelector",{title:"Wait for selector",snapshot:!0}],["Request.response",{internal:!0}],["Request.rawRequestHeaders",{internal:!0}],["Route.redirectNavigationRequest",{internal:!0}],["Route.abort",{title:"Abort request",group:"route"}],["Route.continue",{title:"Continue request",group:"route"}],["Route.fulfill",{title:"Fulfill request",group:"route"}],["WebSocketRoute.connect",{title:"Connect WebSocket to server",group:"route"}],["WebSocketRoute.ensureOpened",{internal:!0}],["WebSocketRoute.sendToPage",{title:"Send WebSocket message",group:"route"}],["WebSocketRoute.sendToServer",{title:"Send WebSocket message",group:"route"}],["WebSocketRoute.closePage",{internal:!0}],["WebSocketRoute.closeServer",{internal:!0}],["Response.body",{title:"Get response body",group:"getter"}],["Response.securityDetails",{internal:!0}],["Response.serverAddr",{internal:!0}],["Response.rawResponseHeaders",{internal:!0}],["Response.sizes",{internal:!0}],["BindingCall.reject",{internal:!0}],["BindingCall.resolve",{internal:!0}],["Dialog.accept",{title:"Accept dialog"}],["Dialog.dismiss",{title:"Dismiss dialog"}],["Tracing.tracingStart",{title:"Start tracing",group:"configuration"}],["Tracing.tracingStartChunk",{title:"Start tracing",group:"configuration"}],["Tracing.tracingGroup",{title:'Trace "{name}"'}],["Tracing.tracingGroupEnd",{title:"Group end"}],["Tracing.tracingStopChunk",{title:"Stop tracing",group:"configuration"}],["Tracing.tracingStop",{title:"Stop tracing",group:"configuration"}],["Artifact.pathAfterFinished",{internal:!0}],["Artifact.saveAs",{internal:!0}],["Artifact.saveAsStream",{internal:!0}],["Artifact.failure",{internal:!0}],["Artifact.stream",{internal:!0}],["Artifact.cancel",{internal:!0}],["Artifact.delete",{internal:!0}],["Stream.read",{internal:!0}],["Stream.close",{internal:!0}],["WritableStream.write",{internal:!0}],["WritableStream.close",{internal:!0}],["CDPSession.send",{title:"Send CDP command",group:"configuration"}],["CDPSession.detach",{title:"Detach CDP session",group:"configuration"}],["Electron.launch",{title:"Launch electron"}],["ElectronApplication.browserWindow",{internal:!0}],["ElectronApplication.evaluateExpression",{title:"Evaluate"}],["ElectronApplication.evaluateExpressionHandle",{title:"Evaluate"}],["ElectronApplication.updateSubscription",{internal:!0}],["Android.devices",{internal:!0}],["AndroidSocket.write",{internal:!0}],["AndroidSocket.close",{internal:!0}],["AndroidDevice.wait",{title:"Wait"}],["AndroidDevice.fill",{title:'Fill "{text}"'}],["AndroidDevice.tap",{title:"Tap"}],["AndroidDevice.drag",{title:"Drag"}],["AndroidDevice.fling",{title:"Fling"}],["AndroidDevice.longTap",{title:"Long tap"}],["AndroidDevice.pinchClose",{title:"Pinch close"}],["AndroidDevice.pinchOpen",{title:"Pinch open"}],["AndroidDevice.scroll",{title:"Scroll"}],["AndroidDevice.swipe",{title:"Swipe"}],["AndroidDevice.info",{internal:!0}],["AndroidDevice.screenshot",{title:"Screenshot"}],["AndroidDevice.inputType",{title:"Type"}],["AndroidDevice.inputPress",{title:"Press"}],["AndroidDevice.inputTap",{title:"Tap"}],["AndroidDevice.inputSwipe",{title:"Swipe"}],["AndroidDevice.inputDrag",{title:"Drag"}],["AndroidDevice.launchBrowser",{title:"Launch browser"}],["AndroidDevice.open",{title:"Open app"}],["AndroidDevice.shell",{title:"Execute shell command",group:"configuration"}],["AndroidDevice.installApk",{title:"Install apk"}],["AndroidDevice.push",{title:"Push"}],["AndroidDevice.connectToWebView",{title:"Connect to Web View"}],["AndroidDevice.close",{internal:!0}],["JsonPipe.send",{internal:!0}],["JsonPipe.close",{internal:!0}],["PageAgent.perform",{title:'Perform "{task}"'}],["PageAgent.expect",{title:'Expect "{expectation}"'}],["PageAgent.extract",{title:'Extract "{query}"'}],["PageAgent.dispose",{internal:!0}],["PageAgent.usage",{title:"Get agent usage",group:"configuration"}]]);function eb(n,e){var i;return(i=Ex(n,e))==null?void 0:i.replaceAll(` +`,"\\n")}function Ex(n,e){if(n)for(const i of e.split("|")){if(i==="url")try{const l=new URL(n[i]);return l.protocol==="data:"?l.protocol:l.protocol==="about:"?n[i]:l.pathname+l.search}catch{if(n[i]!==void 0)return n[i]}if(i==="timeNumber"&&n[i]!==void 0)return new Date(n[i]).toString();const r=Ax(n,i);if(r!==void 0)return r}}function Ax(n,e){const i=e.split(".");let r=n;for(const l of i){if(typeof r!="object"||r===null)return;r=r[l]}if(r!==void 0)return String(r)}function Nx(n){var i;return(n.title??((i=Qh.get(n.type+"."+n.method))==null?void 0:i.title)??n.method).replace(/\{([^}]+)\}/g,(r,l)=>eb(n.params,l)??r)}function Cx(n){var e;return(e=Qh.get(n.type+"."+n.method))==null?void 0:e.group}const qa=Symbol("context"),tb=Symbol("nextInContext"),nb=Symbol("prevByEndTime"),ib=Symbol("nextByStartTime"),Py=Symbol("events");class BC{constructor(e,i){var l;i.forEach(o=>kx(o));const r=i.find(o=>o.origin==="library");this.traceUri=e,this.browserName=(r==null?void 0:r.browserName)||"",this.sdkLanguage=r==null?void 0:r.sdkLanguage,this.channel=r==null?void 0:r.channel,this.testIdAttributeName=r==null?void 0:r.testIdAttributeName,this.platform=(r==null?void 0:r.platform)||"",this.playwrightVersion=(l=i.find(o=>o.playwrightVersion))==null?void 0:l.playwrightVersion,this.title=(r==null?void 0:r.title)||"",this.options=(r==null?void 0:r.options)||{},this.actions=Mx(i),this.pages=[].concat(...i.map(o=>o.pages)),this.wallTime=i.map(o=>o.wallTime).reduce((o,u)=>Math.min(o||Number.MAX_VALUE,u),Number.MAX_VALUE),this.startTime=i.map(o=>o.startTime).reduce((o,u)=>Math.min(o,u),Number.MAX_VALUE),this.endTime=i.map(o=>o.endTime).reduce((o,u)=>Math.max(o,u),Number.MIN_VALUE),this.events=[].concat(...i.map(o=>o.events)),this.stdio=[].concat(...i.map(o=>o.stdio)),this.errors=[].concat(...i.map(o=>o.errors)),this.hasSource=i.some(o=>o.hasSource),this.hasStepData=i.some(o=>o.origin==="testRunner"),this.resources=[...i.map(o=>o.resources)].flat(),this.attachments=this.actions.flatMap(o=>{var u;return((u=o.attachments)==null?void 0:u.map(f=>({...f,callId:o.callId,traceUri:e})))??[]}),this.visibleAttachments=this.attachments.filter(o=>!o.name.startsWith("_")),this.events.sort((o,u)=>o.time-u.time),this.resources.sort((o,u)=>o._monotonicTime-u._monotonicTime),this.errorDescriptors=this.hasStepData?this._errorDescriptorsFromTestRunner():this._errorDescriptorsFromActions(),this.sources=Bx(this.actions,this.errorDescriptors),this.actionCounters=new Map;for(const o of this.actions)o.group=o.group??Cx({type:o.class,method:o.method}),o.group&&this.actionCounters.set(o.group,1+(this.actionCounters.get(o.group)||0))}createRelativeUrl(e){const i=new URL("http://localhost/"+e);return i.searchParams.set("trace",this.traceUri),i.toString().substring(17)}failedAction(){return this.actions.findLast(e=>e.error)}filteredActions(e){const i=new Set(e);return this.actions.filter(r=>!r.group||i.has(r.group))}renderActionTree(e){const i=this.filteredActions(e??[]),{rootItem:r}=sb(i),l=[],o=(u,f)=>{const h=Nx({...u.action,type:u.action.class});l.push(`${f}${h||u.id}`);for(const g of u.children)o(g,f+" ")};return r.children.forEach(u=>o(u,"")),l}_errorDescriptorsFromActions(){var i;const e=[];for(const r of this.actions||[])(i=r.error)!=null&&i.message&&e.push({action:r,stack:r.stack,message:r.error.message});return e}_errorDescriptorsFromTestRunner(){return this.errors.filter(e=>!!e.message).map((e,i)=>({stack:e.stack,message:e.message}))}}function kx(n){for(const i of n.pages)i[qa]=n;for(let i=0;i=0;i--){const r=n.actions[i];r[tb]=e,r.class!=="Route"&&(e=r)}for(const i of n.events)i[qa]=n;for(const i of n.resources)i[qa]=n}function Mx(n){const e=[],i=Ox(n);e.push(...i),e.sort((r,l)=>l.parentId===r.callId?1:r.parentId===l.callId?-1:r.endTime-l.endTime);for(let r=1;rl.parentId===r.callId?-1:r.parentId===l.callId?1:r.startTime-l.startTime);for(let r=0;r+1u.origin==="library"),r=n.filter(u=>u.origin==="testRunner");if(!r.length||!i.length)return n.map(u=>u.actions.map(f=>({...f,context:u}))).flat();for(const u of i)for(const f of u.actions)e.set(f.stepId||`tmp-step@${++Zy}`,{...f,context:u});const l=Lx(r,e);l&&jx(i,l);const o=new Map;for(const u of r)for(const f of u.actions){const h=f.stepId&&e.get(f.stepId);if(h){o.set(f.callId,h.callId),f.error&&(h.error=f.error),f.attachments&&(h.attachments=f.attachments),f.annotations&&(h.annotations=f.annotations),f.parentId&&(h.parentId=o.get(f.parentId)??f.parentId),f.group&&(h.group=f.group),h.startTime=f.startTime,h.endTime=f.endTime;continue}f.parentId&&(f.parentId=o.get(f.parentId)??f.parentId),e.set(f.stepId||`tmp-step@${++Zy}`,{...f,context:u})}return[...e.values()]}function jx(n,e){for(const i of n){i.startTime+=e,i.endTime+=e;for(const r of i.actions)r.startTime&&(r.startTime+=e),r.endTime&&(r.endTime+=e);for(const r of i.events)r.time+=e;for(const r of i.stdio)r.timestamp+=e;for(const r of i.pages)for(const l of r.screencastFrames)l.timestamp+=e;for(const r of i.resources)r._monotonicTime&&(r._monotonicTime+=e)}}function Lx(n,e){for(const i of n)for(const r of i.actions){if(!r.startTime)continue;const l=r.stepId?e.get(r.stepId):void 0;if(l)return r.startTime-l.startTime}return 0}function sb(n){const e=new Map;for(const l of n)e.set(l.callId,{id:l.callId,parent:void 0,children:[],action:l});const i={action:{...Ux},id:"",parent:void 0,children:[]};for(const l of e.values()){i.action.startTime=Math.min(i.action.startTime,l.action.startTime),i.action.endTime=Math.max(i.action.endTime,l.action.endTime);const o=l.action.parentId&&e.get(l.action.parentId)||i;o.children.push(l),l.parent=o}const r=l=>{for(const o of l.children)o.action.stack=o.action.stack??l.action.stack,r(o)};return r(i),{rootItem:i,itemMap:e}}function rb(n){return n[qa]}function Rx(n){return n[tb]}function Wy(n){return n[nb]}function e0(n){return n[ib]}function Dx(n){let e=0,i=0;for(const r of zx(n)){if(r.type==="console"){const l=r.messageType;l==="warning"?++i:l==="error"&&++e}r.type==="event"&&r.method==="pageError"&&++e}return{errors:e,warnings:i}}function zx(n){let e=n[Py];if(e)return e;const i=Rx(n);return e=rb(n).events.filter(r=>r.time>=n.startTime&&(!i||r.time{const h=Math.max(l,n)*window.devicePixelRatio,[g,y]=on(o?o+"."+r+":size":void 0,h),[m,w]=on(o?o+"."+r+":size":void 0,h),[v,E]=U.useState(null),[x,_]=gs();let N;r==="vertical"?(N=m/window.devicePixelRatio,x&&x.heightE({offset:r==="vertical"?$.clientY:$.clientX,size:N}),onMouseUp:()=>E(null),onMouseMove:$=>{if(!$.buttons)E(null);else if(v){const D=(r==="vertical"?$.clientY:$.clientX)-v.offset,K=i?v.size+D:v.size-D,q=$.target.parentElement.getBoundingClientRect(),j=Math.min(Math.max(l,K),(r==="vertical"?q.height:q.width)-l);r==="vertical"?w(j*window.devicePixelRatio):y(j*window.devicePixelRatio)}}})]})},et=function(n,e,i){return n>=e&&n<=i};function Rt(n){return et(n,48,57)}function t0(n){return Rt(n)||et(n,65,70)||et(n,97,102)}function qx(n){return et(n,65,90)}function $x(n){return et(n,97,122)}function Ix(n){return qx(n)||$x(n)}function Vx(n){return n>=128}function $o(n){return Ix(n)||Vx(n)||n===95}function n0(n){return $o(n)||Rt(n)||n===45}function Gx(n){return et(n,0,8)||n===11||et(n,14,31)||n===127}function Io(n){return n===10}function Qn(n){return Io(n)||n===9||n===32}const Kx=1114111;class Jh extends Error{constructor(e){super(e),this.name="InvalidCharacterError"}}function Yx(n){const e=[];for(let i=0;i=e.length?-1:e[V]},u=function(V){if(V===void 0&&(V=1),V>3)throw"Spec Error: no more than three codepoints of lookahead.";return o(i+V)},f=function(V){return V===void 0&&(V=1),i+=V,l=o(i),!0},h=function(){return i-=1,!0},g=function(V){return V===void 0&&(V=l),V===-1},y=function(){if(m(),f(),Qn(l)){for(;Qn(u());)f();return new ic}else{if(l===34)return E();if(l===35)if(n0(u())||N(u(1),u(2))){const V=new vb("");return $(u(1),u(2),u(3))&&(V.type="id"),V.value=Q(),V}else return new dt(l);else return l===36?u()===61?(f(),new Jx):new dt(l):l===39?E():l===40?new mb:l===41?new Ph:l===42?u()===61?(f(),new Px):new dt(l):l===43?K()?(h(),w()):new dt(l):l===44?new hb:l===45?K()?(h(),w()):u(1)===45&&u(2)===62?(f(2),new cb):I()?(h(),v()):new dt(l):l===46?K()?(h(),w()):new dt(l):l===58?new ub:l===59?new fb:l===60?u(1)===33&&u(2)===45&&u(3)===45?(f(3),new ob):new dt(l):l===64?$(u(1),u(2),u(3))?new bb(Q()):new dt(l):l===91?new gb:l===92?C()?(h(),v()):new dt(l):l===93?new kh:l===94?u()===61?(f(),new Qx):new dt(l):l===123?new db:l===124?u()===61?(f(),new Fx):u()===124?(f(),new yb):new dt(l):l===125?new pb:l===126?u()===61?(f(),new Xx):new dt(l):Rt(l)?(h(),w()):$o(l)?(h(),v()):g()?new Go:new dt(l)}},m=function(){for(;u(1)===47&&u(2)===42;)for(f(2);;)if(f(),l===42&&u()===47){f();break}else if(g())return},w=function(){const V=q();if($(u(1),u(2),u(3))){const J=new Zx;return J.value=V.value,J.repr=V.repr,J.type=V.type,J.unit=Q(),J}else if(u()===37){f();const J=new xb;return J.value=V.value,J.repr=V.repr,J}else{const J=new wb;return J.value=V.value,J.repr=V.repr,J.type=V.type,J}},v=function(){const V=Q();if(V.toLowerCase()==="url"&&u()===40){for(f();Qn(u(1))&&Qn(u(2));)f();return u()===34||u()===39?new Ya(V):Qn(u())&&(u(2)===34||u(2)===39)?new Ya(V):x()}else return u()===40?(f(),new Ya(V)):new Zh(V)},E=function(V){V===void 0&&(V=l);let J="";for(;f();){if(l===V||g())return new Wh(J);if(Io(l))return h(),new lb;l===92?g(u())||(Io(u())?f():J+=st(_())):J+=st(l)}throw new Error("Internal error")},x=function(){const V=new Sb("");for(;Qn(u());)f();if(g(u()))return V;for(;f();){if(l===41||g())return V;if(Qn(l)){for(;Qn(u());)f();return u()===41||g(u())?(f(),V):(ne(),new Vo)}else{if(l===34||l===39||l===40||Gx(l))return ne(),new Vo;if(l===92)if(C())V.value+=st(_());else return ne(),new Vo;else V.value+=st(l)}}throw new Error("Internal error")},_=function(){if(f(),t0(l)){const V=[l];for(let W=0;W<5&&t0(u());W++)f(),V.push(l);Qn(u())&&f();let J=parseInt(V.map(function(W){return String.fromCharCode(W)}).join(""),16);return J>Kx&&(J=65533),J}else return g()?65533:l},N=function(V,J){return!(V!==92||Io(J))},C=function(){return N(l,u())},$=function(V,J,W){return V===45?$o(J)||J===45||N(J,W):$o(V)?!0:V===92?N(V,J):!1},I=function(){return $(l,u(1),u(2))},D=function(V,J,W){return V===43||V===45?!!(Rt(J)||J===46&&Rt(W)):V===46?!!Rt(J):!!Rt(V)},K=function(){return D(l,u(1),u(2))},Q=function(){let V="";for(;f();)if(n0(l))V+=st(l);else if(C())V+=st(_());else return h(),V;throw new Error("Internal parse error")},q=function(){let V="",J="integer";for((u()===43||u()===45)&&(f(),V+=st(l));Rt(u());)f(),V+=st(l);if(u(1)===46&&Rt(u(2)))for(f(),V+=st(l),f(),V+=st(l),J="number";Rt(u());)f(),V+=st(l);const W=u(1),Ae=u(2),B=u(3);if((W===69||W===101)&&Rt(Ae))for(f(),V+=st(l),f(),V+=st(l),J="number";Rt(u());)f(),V+=st(l);else if((W===69||W===101)&&(Ae===43||Ae===45)&&Rt(B))for(f(),V+=st(l),f(),V+=st(l),f(),V+=st(l),J="number";Rt(u());)f(),V+=st(l);const P=j(V);return{type:J,value:P,repr:V}},j=function(V){return+V},ne=function(){for(;f();){if(l===41||g())return;C()&&_()}};let le=0;for(;!g(u());)if(r.push(y()),le++,le>e.length*2)throw new Error("I'm infinite-looping!");return r}class Qe{constructor(){this.tokenType=""}toJSON(){return{token:this.tokenType}}toString(){return this.tokenType}toSource(){return""+this}}class lb extends Qe{constructor(){super(...arguments),this.tokenType="BADSTRING"}}class Vo extends Qe{constructor(){super(...arguments),this.tokenType="BADURL"}}class ic extends Qe{constructor(){super(...arguments),this.tokenType="WHITESPACE"}toString(){return"WS"}toSource(){return" "}}class ob extends Qe{constructor(){super(...arguments),this.tokenType="CDO"}toSource(){return""}}class ub extends Qe{constructor(){super(...arguments),this.tokenType=":"}}class fb extends Qe{constructor(){super(...arguments),this.tokenType=";"}}class hb extends Qe{constructor(){super(...arguments),this.tokenType=","}}class Er extends Qe{constructor(){super(...arguments),this.value="",this.mirror=""}}class db extends Er{constructor(){super(),this.tokenType="{",this.value="{",this.mirror="}"}}class pb extends Er{constructor(){super(),this.tokenType="}",this.value="}",this.mirror="{"}}class gb extends Er{constructor(){super(),this.tokenType="[",this.value="[",this.mirror="]"}}class kh extends Er{constructor(){super(),this.tokenType="]",this.value="]",this.mirror="["}}class mb extends Er{constructor(){super(),this.tokenType="(",this.value="(",this.mirror=")"}}class Ph extends Er{constructor(){super(),this.tokenType=")",this.value=")",this.mirror="("}}class Xx extends Qe{constructor(){super(...arguments),this.tokenType="~="}}class Fx extends Qe{constructor(){super(...arguments),this.tokenType="|="}}class Qx extends Qe{constructor(){super(...arguments),this.tokenType="^="}}class Jx extends Qe{constructor(){super(...arguments),this.tokenType="$="}}class Px extends Qe{constructor(){super(...arguments),this.tokenType="*="}}class yb extends Qe{constructor(){super(...arguments),this.tokenType="||"}}class Go extends Qe{constructor(){super(...arguments),this.tokenType="EOF"}toSource(){return""}}class dt extends Qe{constructor(e){super(),this.tokenType="DELIM",this.value="",this.value=st(e)}toString(){return"DELIM("+this.value+")"}toJSON(){const e=this.constructor.prototype.constructor.prototype.toJSON.call(this);return e.value=this.value,e}toSource(){return this.value==="\\"?`\\ +`:this.value}}class Ar extends Qe{constructor(){super(...arguments),this.value=""}ASCIIMatch(e){return this.value.toLowerCase()===e.toLowerCase()}toJSON(){const e=this.constructor.prototype.constructor.prototype.toJSON.call(this);return e.value=this.value,e}}class Zh extends Ar{constructor(e){super(),this.tokenType="IDENT",this.value=e}toString(){return"IDENT("+this.value+")"}toSource(){return ol(this.value)}}class Ya extends Ar{constructor(e){super(),this.tokenType="FUNCTION",this.value=e,this.mirror=")"}toString(){return"FUNCTION("+this.value+")"}toSource(){return ol(this.value)+"("}}class bb extends Ar{constructor(e){super(),this.tokenType="AT-KEYWORD",this.value=e}toString(){return"AT("+this.value+")"}toSource(){return"@"+ol(this.value)}}class vb extends Ar{constructor(e){super(),this.tokenType="HASH",this.value=e,this.type="unrestricted"}toString(){return"HASH("+this.value+")"}toJSON(){const e=this.constructor.prototype.constructor.prototype.toJSON.call(this);return e.value=this.value,e.type=this.type,e}toSource(){return this.type==="id"?"#"+ol(this.value):"#"+Wx(this.value)}}class Wh extends Ar{constructor(e){super(),this.tokenType="STRING",this.value=e}toString(){return'"'+_b(this.value)+'"'}}class Sb extends Ar{constructor(e){super(),this.tokenType="URL",this.value=e}toString(){return"URL("+this.value+")"}toSource(){return'url("'+_b(this.value)+'")'}}class wb extends Qe{constructor(){super(),this.tokenType="NUMBER",this.type="integer",this.repr=""}toString(){return this.type==="integer"?"INT("+this.value+")":"NUMBER("+this.value+")"}toJSON(){const e=super.toJSON();return e.value=this.value,e.type=this.type,e.repr=this.repr,e}toSource(){return this.repr}}class xb extends Qe{constructor(){super(),this.tokenType="PERCENTAGE",this.repr=""}toString(){return"PERCENTAGE("+this.value+")"}toJSON(){const e=this.constructor.prototype.constructor.prototype.toJSON.call(this);return e.value=this.value,e.repr=this.repr,e}toSource(){return this.repr+"%"}}class Zx extends Qe{constructor(){super(),this.tokenType="DIMENSION",this.type="integer",this.repr="",this.unit=""}toString(){return"DIM("+this.value+","+this.unit+")"}toJSON(){const e=this.constructor.prototype.constructor.prototype.toJSON.call(this);return e.value=this.value,e.type=this.type,e.repr=this.repr,e.unit=this.unit,e}toSource(){const e=this.repr;let i=ol(this.unit);return i[0].toLowerCase()==="e"&&(i[1]==="-"||et(i.charCodeAt(1),48,57))&&(i="\\65 "+i.slice(1,i.length)),e+i}}function ol(n){n=""+n;let e="";const i=n.charCodeAt(0);for(let r=0;r=128||l===45||l===95||et(l,48,57)||et(l,65,90)||et(l,97,122)?e+=n[r]:e+="\\"+n[r]}return e}function Wx(n){n=""+n;let e="";for(let i=0;i=128||r===45||r===95||et(r,48,57)||et(r,65,90)||et(r,97,122)?e+=n[i]:e+="\\"+r.toString(16)+" "}return e}function _b(n){n=""+n;let e="";for(let i=0;ij instanceof bb||j instanceof lb||j instanceof Vo||j instanceof yb||j instanceof ob||j instanceof cb||j instanceof fb||j instanceof db||j instanceof pb||j instanceof Sb||j instanceof xb);if(r)throw new Dt(`Unsupported token "${r.toSource()}" while parsing css selector "${n}". Did you mean to CSS.escape it?`);let l=0;const o=new Set;function u(){return new Dt(`Unexpected token "${i[l].toSource()}" while parsing css selector "${n}". Did you mean to CSS.escape it?`)}function f(){for(;i[l]instanceof ic;)l++}function h(j=l){return i[j]instanceof Zh}function g(j=l){return i[j]instanceof Wh}function y(j=l){return i[j]instanceof wb}function m(j=l){return i[j]instanceof hb}function w(j=l){return i[j]instanceof mb}function v(j=l){return i[j]instanceof Ph}function E(j=l){return i[j]instanceof Ya}function x(j=l){return i[j]instanceof dt&&i[j].value==="*"}function _(j=l){return i[j]instanceof Go}function N(j=l){return i[j]instanceof dt&&[">","+","~"].includes(i[j].value)}function C(j=l){return m(j)||v(j)||_(j)||N(j)||i[j]instanceof ic}function $(){const j=[I()];for(;f(),!!m();)l++,j.push(I());return j}function I(){return f(),y()||g()?i[l++].value:D()}function D(){const j={simples:[]};for(f(),N()?j.simples.push({selector:{functions:[{name:"scope",args:[]}]},combinator:""}):j.simples.push({selector:K(),combinator:""});;){if(f(),N())j.simples[j.simples.length-1].combinator=i[l++].value,f();else if(C())break;j.simples.push({combinator:"",selector:K()})}return j}function K(){let j="";const ne=[];for(;!C();)if(h()||x())j+=i[l++].toSource();else if(i[l]instanceof vb)j+=i[l++].toSource();else if(i[l]instanceof dt&&i[l].value===".")if(l++,h())j+="."+i[l++].toSource();else throw u();else if(i[l]instanceof ub)if(l++,h())if(!e.has(i[l].value.toLowerCase()))j+=":"+i[l++].toSource();else{const le=i[l++].value.toLowerCase();ne.push({name:le,args:[]}),o.add(le)}else if(E()){const le=i[l++].value.toLowerCase();if(e.has(le)?(ne.push({name:le,args:$()}),o.add(le)):j+=`:${le}(${Q()})`,f(),!v())throw u();l++}else throw u();else if(i[l]instanceof gb){for(j+="[",l++;!(i[l]instanceof kh)&&!_();)j+=i[l++].toSource();if(!(i[l]instanceof kh))throw u();j+="]",l++}else throw u();if(!j&&!ne.length)throw u();return{css:j||void 0,functions:ne}}function Q(){let j="",ne=1;for(;!_()&&((w()||E())&&ne++,v()&&ne--,!!ne);)j+=i[l++].toSource();return j}const q=$();if(!_())throw u();if(q.some(j=>typeof j!="object"||!("simples"in j)))throw new Dt(`Error while parsing css selector "${n}". Did you mean to CSS.escape it?`);return{selector:q,names:Array.from(o)}}const Mh=new Set(["internal:has","internal:has-not","internal:and","internal:or","internal:chain","left-of","right-of","above","below","near"]),t_=new Set(["left-of","right-of","above","below","near"]),Tb=new Set(["not","is","where","has","scope","light","visible","text","text-matches","text-is","has-text","above","below","right-of","left-of","near","nth-match"]);function cl(n){const e=s_(n),i=[];for(const r of e.parts){if(r.name==="css"||r.name==="css:light"){r.name==="css:light"&&(r.body=":light("+r.body+")");const l=e_(r.body,Tb);i.push({name:"css",body:l.selector,source:r.body});continue}if(Mh.has(r.name)){let l,o;try{const g=JSON.parse("["+r.body+"]");if(!Array.isArray(g)||g.length<1||g.length>2||typeof g[0]!="string")throw new Dt(`Malformed selector: ${r.name}=`+r.body);if(l=g[0],g.length===2){if(typeof g[1]!="number"||!t_.has(r.name))throw new Dt(`Malformed selector: ${r.name}=`+r.body);o=g[1]}}catch{throw new Dt(`Malformed selector: ${r.name}=`+r.body)}const u={name:r.name,source:r.body,body:{parsed:cl(l),distance:o}},f=[...u.body.parsed.parts].reverse().find(g=>g.name==="internal:control"&&g.body==="enter-frame"),h=f?u.body.parsed.parts.indexOf(f):-1;h!==-1&&n_(u.body.parsed.parts.slice(0,h+1),i.slice(0,h+1))&&u.body.parsed.parts.splice(0,h+1),i.push(u);continue}i.push({...r,source:r.body})}if(Mh.has(i[0].name))throw new Dt(`"${i[0].name}" selector cannot be first`);return{capture:e.capture,parts:i}}function n_(n,e){return An({parts:n})===An({parts:e})}function An(n,e){return typeof n=="string"?n:n.parts.map((i,r)=>{let l=!0;!e&&r!==n.capture&&(i.name==="css"||i.name==="xpath"&&i.source.startsWith("//")||i.source.startsWith(".."))&&(l=!1);const o=l?i.name+"=":"";return`${r===n.capture?"*":""}${o}${i.source}`}).join(" >> ")}function i_(n,e){const i=(r,l)=>{for(const o of r.parts)e(o,l),Mh.has(o.name)&&i(o.body.parsed,!0)};i(n,!1)}function s_(n){let e=0,i,r=0;const l={parts:[]},o=()=>{const f=n.substring(r,e).trim(),h=f.indexOf("=");let g,y;h!==-1&&f.substring(0,h).trim().match(/^[a-zA-Z_0-9-+:*]+$/)?(g=f.substring(0,h).trim(),y=f.substring(h+1)):f.length>1&&f[0]==='"'&&f[f.length-1]==='"'||f.length>1&&f[0]==="'"&&f[f.length-1]==="'"?(g="text",y=f):/^\(*\/\//.test(f)||f.startsWith("..")?(g="xpath",y=f):(g="css",y=f);let m=!1;if(g[0]==="*"&&(m=!0,g=g.substring(1)),l.parts.push({name:g,body:y}),m){if(l.capture!==void 0)throw new Dt("Only one of the selectors can capture using * modifier");l.capture=l.parts.length-1}};if(!n.includes(">>"))return e=n.length,o(),l;const u=()=>{const h=n.substring(r,e).match(/^\s*text\s*=(.*)$/);return!!h&&!!h[1]};for(;e"&&n[e+1]===">"?(o(),e+=2,r=e):e++}return o(),l}function ds(n,e){let i=0,r=n.length===0;const l=()=>n[i]||"",o=()=>{const _=l();return++i,r=i>=n.length,_},u=_=>{throw r?new Dt(`Unexpected end of selector while parsing selector \`${n}\``):new Dt(`Error while parsing selector \`${n}\` - unexpected symbol "${l()}" at position ${i}`+(_?" during "+_:""))};function f(){for(;!r&&/\s/.test(l());)o()}function h(_){return _>="€"||_>="0"&&_<="9"||_>="A"&&_<="Z"||_>="a"&&_<="z"||_>="0"&&_<="9"||_==="_"||_==="-"}function g(){let _="";for(f();!r&&h(l());)_+=o();return _}function y(_){let N=o();for(N!==_&&u("parsing quoted string");!r&&l()!==_;)l()==="\\"&&o(),N+=o();return l()!==_&&u("parsing quoted string"),N+=o(),N}function m(){o()!=="/"&&u("parsing regular expression");let _="",N=!1;for(;!r;){if(l()==="\\")_+=o(),r&&u("parsing regular expression");else if(N&&l()==="]")N=!1;else if(!N&&l()==="[")N=!0;else if(!N&&l()==="/")break;_+=o()}o()!=="/"&&u("parsing regular expression");let C="";for(;!r&&l().match(/[dgimsuy]/);)C+=o();try{return new RegExp(_,C)}catch($){throw new Dt(`Error while parsing selector \`${n}\`: ${$.message}`)}}function w(){let _="";return f(),l()==="'"||l()==='"'?_=y(l()).slice(1,-1):_=g(),_||u("parsing property path"),_}function v(){f();let _="";return r||(_+=o()),!r&&_!=="="&&(_+=o()),["=","*=","^=","$=","|=","~="].includes(_)||u("parsing operator"),_}function E(){o();const _=[];for(_.push(w()),f();l()===".";)o(),_.push(w()),f();if(l()==="]")return o(),{name:_.join("."),jsonPath:_,op:"",value:null,caseSensitive:!1};const N=v();let C,$=!0;if(f(),l()==="/"){if(N!=="=")throw new Dt(`Error while parsing selector \`${n}\` - cannot use ${N} in attribute with regular expression`);C=m()}else if(l()==="'"||l()==='"')C=y(l()).slice(1,-1),f(),l()==="i"||l()==="I"?($=!1,o()):(l()==="s"||l()==="S")&&($=!0,o());else{for(C="";!r&&(h(l())||l()==="+"||l()===".");)C+=o();C==="true"?C=!0:C==="false"?C=!1:e||(C=+C,Number.isNaN(C)&&u("parsing attribute value"))}if(f(),l()!=="]"&&u("parsing attribute value"),o(),N!=="="&&typeof C!="string")throw new Dt(`Error while parsing selector \`${n}\` - cannot use ${N} in attribute with non-string matching value - ${C}`);return{name:_.join("."),jsonPath:_,op:N,value:C,caseSensitive:$}}const x={name:"",attributes:[]};for(x.name=g(),f();l()==="[";)x.attributes.push(E()),f();if(r||u(void 0),!x.name&&!x.attributes.length)throw new Dt(`Error while parsing selector \`${n}\` - selector cannot be empty`);return x}function gc(n,e="'"){const i=JSON.stringify(n),r=i.substring(1,i.length-1).replace(/\\"/g,'"');if(e==="'")return e+r.replace(/[']/g,"\\'")+e;if(e==='"')return e+r.replace(/["]/g,'\\"')+e;if(e==="`")return e+r.replace(/[`]/g,"\\`")+e;throw new Error("Invalid escape char")}function sc(n){return n.charAt(0).toUpperCase()+n.substring(1)}function Eb(n){return n.replace(/([a-z0-9])([A-Z])/g,"$1_$2").replace(/([A-Z])([A-Z][a-z])/g,"$1_$2").toLowerCase()}function fr(n){return`"${n.replace(/["\\]/g,e=>"\\"+e)}"`}let ss;function r_(){ss=new Map}function At(n){let e=ss==null?void 0:ss.get(n);return e===void 0&&(e=n.replace(/[\u200b\u00ad]/g,"").trim().replace(/\s+/g," "),ss==null||ss.set(n,e)),e}function mc(n){return n.replace(/(^|[^\\])(\\\\)*\\(['"`])/g,"$1$2$3")}function Ab(n){return n.unicode||n.unicodeSets?String(n):String(n).replace(/(^|[^\\])(\\\\)*(["'`])/g,"$1$2\\$3").replace(/>>/g,"\\>\\>")}function zt(n,e){return typeof n!="string"?Ab(n):`${JSON.stringify(n)}${e?"s":"i"}`}function Tt(n,e){return typeof n!="string"?Ab(n):`"${n.replace(/\\/g,"\\\\").replace(/["]/g,'\\"')}"${e?"s":"i"}`}function a_(n,e,i=""){if(n.length<=e)return n;const r=[...n];return r.length>e?r.slice(0,e-i.length).join("")+i:r.join("")}function i0(n,e){return a_(n,e,"…")}function rc(n){return n.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function l_(n,e){const i=n.length,r=e.length;let l=0,o=0;const u=Array(i+1).fill(null).map(()=>Array(r+1).fill(0));for(let f=1;f<=i;f++)for(let h=1;h<=r;h++)n[f-1]===e[h-1]&&(u[f][h]=u[f-1][h-1]+1,u[f][h]>l&&(l=u[f][h],o=f));return n.slice(o-l,o)}function o_(n,e){try{const i=cl(e),r=c_(i);return r||os(new Cb[n],i,!1,1)[0]}catch{return e}}function c_(n){const e=n.parts[n.parts.length-1];if((e==null?void 0:e.name)==="internal:describe"){const i=JSON.parse(e.body);if(typeof i=="string")return i}}function Oi(n,e,i=!1){return Nb(n,e,i,1)[0]}function Nb(n,e,i=!1,r=20,l){try{return os(new Cb[n](l),cl(e),i,r)}catch{return[e]}}function os(n,e,i=!1,r=20){const l=[...e.parts],o=[];let u=i?"frame-locator":"page";for(let f=0;fn.generateLocator(g,"has",x)));continue}if(h.name==="internal:has-not"){const E=os(n,h.body.parsed,!1,r);o.push(E.map(x=>n.generateLocator(g,"hasNot",x)));continue}if(h.name==="internal:and"){const E=os(n,h.body.parsed,!1,r);o.push(E.map(x=>n.generateLocator(g,"and",x)));continue}if(h.name==="internal:or"){const E=os(n,h.body.parsed,!1,r);o.push(E.map(x=>n.generateLocator(g,"or",x)));continue}if(h.name==="internal:chain"){const E=os(n,h.body.parsed,!1,r);o.push(E.map(x=>n.generateLocator(g,"chain",x)));continue}if(h.name==="internal:label"){const{exact:E,text:x}=La(h.body);o.push([n.generateLocator(g,"label",x,{exact:E})]);continue}if(h.name==="internal:role"){const E=ds(h.body,!0),x={attrs:[]};for(const _ of E.attributes)_.name==="name"?(x.exact=_.caseSensitive,x.name=_.value):(_.name==="level"&&typeof _.value=="string"&&(_.value=+_.value),x.attrs.push({name:_.name==="include-hidden"?"includeHidden":_.name,value:_.value}));o.push([n.generateLocator(g,"role",E.name,x)]);continue}if(h.name==="internal:testid"){const E=ds(h.body,!0),{value:x}=E.attributes[0];o.push([n.generateLocator(g,"test-id",x)]);continue}if(h.name==="internal:attr"){const E=ds(h.body,!0),{name:x,value:_,caseSensitive:N}=E.attributes[0],C=_,$=!!N;if(x==="placeholder"){o.push([n.generateLocator(g,"placeholder",C,{exact:$})]);continue}if(x==="alt"){o.push([n.generateLocator(g,"alt",C,{exact:$})]);continue}if(x==="title"){o.push([n.generateLocator(g,"title",C,{exact:$})]);continue}}if(h.name==="internal:control"&&h.body==="enter-frame"){const E=o[o.length-1],x=l[f-1],_=E.map(N=>n.chainLocators([N,n.generateLocator(g,"frame","")]));["xpath","css"].includes(x.name)&&_.push(n.generateLocator(g,"frame-locator",An({parts:[x]})),n.generateLocator(g,"frame-locator",An({parts:[x]},!0))),E.splice(0,E.length,..._),u="frame-locator";continue}const y=l[f+1],m=An({parts:[h]}),w=n.generateLocator(g,"default",m);if(y&&["internal:has-text","internal:has-not-text"].includes(y.name)){const{exact:E,text:x}=La(y.body);if(!E){const _=n.generateLocator("locator",y.name==="internal:has-text"?"has-text":"has-not-text",x,{exact:E}),N={};y.name==="internal:has-text"?N.hasText=x:N.hasNotText=x;const C=n.generateLocator(g,"default",m,N);o.push([n.chainLocators([w,_]),C]),f++;continue}}let v;if(["xpath","css"].includes(h.name)){const E=An({parts:[h]},!0);v=n.generateLocator(g,"default",E)}o.push([w,v].filter(Boolean))}return u_(n,o,r)}function u_(n,e,i){const r=e.map(()=>""),l=[],o=u=>{if(u===e.length)return l.push(n.chainLocators(r)),l.lengthJSON.parse(r));for(let r=0;ry_(e,f,m.expandedItems,x||0,u),[e,f,m,x,u]),N=U.useRef(null),[C,$]=U.useState(),[I,D]=U.useState(!1);U.useEffect(()=>{y==null||y(C)},[y,C]),U.useEffect(()=>{const q=N.current;if(!q)return;const j=()=>{s0.set(n,q.scrollTop)};return q.addEventListener("scroll",j,{passive:!0}),()=>q.removeEventListener("scroll",j)},[n]),U.useEffect(()=>{N.current&&(N.current.scrollTop=s0.get(n)||0)},[n]);const K=U.useCallback(q=>{const{expanded:j}=_.get(q);if(j){for(let ne=f;ne;ne=ne.parent)if(ne===q){g==null||g(q);break}m.expandedItems.set(q.id,!1)}else m.expandedItems.set(q.id,!0);w({...m})},[_,f,g,m,w]),Q=U.useCallback(q=>{const{expanded:j}=_.get(q),ne=[q];for(;ne.length;){const le=ne.pop();ne.push(...le.children),m.expandedItems.set(le.id,!j)}w({...m})},[_,m,w]);return S.jsx("div",{className:Fe("tree-view vbox",n+"-tree-view"),"data-testid":E||n+"-tree",children:S.jsxs("div",{className:Fe("tree-view-content"),role:_.size>0?"tree":void 0,tabIndex:0,onKeyDown:q=>{if(f&&q.key==="Enter"){h==null||h(f);return}if(q.key!=="ArrowDown"&&q.key!=="ArrowUp"&&q.key!=="ArrowLeft"&&q.key!=="ArrowRight")return;if(q.stopPropagation(),q.preventDefault(),f&&q.key==="ArrowLeft"){const{expanded:ne,parent:le}=_.get(f);ne?(m.expandedItems.set(f.id,!1),w({...m})):le&&(g==null||g(le));return}if(f&&q.key==="ArrowRight"){f.children.length&&(m.expandedItems.set(f.id,!0),w({...m}));return}let j=f;if(q.key==="ArrowDown"&&(f?j=_.get(f).next:_.size&&(j=[..._.keys()][0])),q.key==="ArrowUp"){if(f)j=_.get(f).prev;else if(_.size){const ne=[..._.keys()];j=ne[ne.length-1]}}y==null||y(void 0),j&&(D(!0),g==null||g(j)),$(void 0)},ref:N,children:[v&&_.size===0&&S.jsx("div",{className:"tree-view-empty",children:v}),e.children.map(q=>_.get(q)&&S.jsx(kb,{item:q,treeItems:_,selectedItem:f,onSelected:g,onAccepted:h,isError:o,toggleExpanded:K,toggleSubtree:Q,highlightedItem:C,setHighlightedItem:$,render:i,icon:l,title:r,isKeyboardNavigation:I,setIsKeyboardNavigation:D},q.id))]})})}function kb({item:n,treeItems:e,selectedItem:i,onSelected:r,highlightedItem:l,setHighlightedItem:o,isError:u,onAccepted:f,toggleExpanded:h,toggleSubtree:g,render:y,title:m,icon:w,isKeyboardNavigation:v,setIsKeyboardNavigation:E}){const x=U.useId(),_=U.useRef(null);U.useEffect(()=>{i===n&&v&&_.current&&(J0(_.current),E(!1))},[n,i,v,E]);const N=e.get(n),C=N.depth,$=N.expanded;let I="codicon-blank";typeof $=="boolean"&&(I=$?"codicon-chevron-down":"codicon-chevron-right");const D=y(n),K=$&&n.children.length?n.children:[],Q=m==null?void 0:m(n),q=(w==null?void 0:w(n))||"codicon-blank";return S.jsxs("div",{ref:_,role:"treeitem","aria-selected":n===i,"aria-expanded":$,"aria-controls":x,title:Q,className:"vbox",style:{flex:"none"},children:[S.jsxs("div",{onDoubleClick:()=>f==null?void 0:f(n),className:Fe("tree-view-entry",i===n&&"selected",l===n&&"highlighted",(u==null?void 0:u(n))&&"error"),onClick:()=>r==null?void 0:r(n),onMouseEnter:()=>o(n),onMouseLeave:()=>o(void 0),children:[C?new Array(C).fill(0).map((j,ne)=>S.jsx("div",{className:"tree-view-indent"},"indent-"+ne)):void 0,S.jsx("div",{"aria-hidden":"true",className:"codicon "+I,style:{minWidth:16,marginRight:4},onDoubleClick:j=>{j.preventDefault(),j.stopPropagation()},onClick:j=>{j.stopPropagation(),j.preventDefault(),j.altKey?g(n):h(n)}}),w&&S.jsx("div",{className:"codicon "+q,style:{minWidth:16,marginRight:4},"aria-label":"["+q.replace("codicon","icon")+"]"}),typeof D=="string"?S.jsx("div",{style:{textOverflow:"ellipsis",overflow:"hidden"},children:D}):D]}),!!K.length&&S.jsx("div",{id:x,role:"group",children:K.map(j=>e.get(j)&&S.jsx(kb,{item:j,treeItems:e,selectedItem:i,onSelected:r,onAccepted:f,isError:u,toggleExpanded:h,toggleSubtree:g,highlightedItem:l,setHighlightedItem:o,render:y,title:m,icon:w,isKeyboardNavigation:v,setIsKeyboardNavigation:E},j.id))})]})}function y_(n,e,i,r,l=()=>!0){if(!l(n))return new Map;const o=new Map,u=new Set;for(let g=e==null?void 0:e.parent;g;g=g.parent)u.add(g.id);let f=null;const h=(g,y)=>{for(const m of g.children){if(!l(m))continue;const w=u.has(m.id)||i.get(m.id),v=r>y&&o.size<25&&w!==!1,E=m.children.length?w??v:void 0,x={depth:y,expanded:E,parent:n===g?null:g,next:null,prev:f};f&&(o.get(f).next=m),f=m,o.set(m,x),E&&h(m,y+1)}};return h(n,0),o}const Ht=U.forwardRef(function({children:e,title:i="",icon:r,disabled:l=!1,toggled:o=!1,onClick:u=()=>{},style:f,testId:h,className:g,ariaLabel:y},m){return S.jsxs("button",{ref:m,className:Fe(g,"toolbar-button",r,o&&"toggled"),onMouseDown:r0,onClick:u,onDoubleClick:r0,title:i,disabled:!!l,style:f,"data-testid":h,"aria-label":y||i,children:[r&&S.jsx("span",{className:`codicon codicon-${r}`,style:e?{marginRight:5}:{}}),e]})}),r0=n=>{n.stopPropagation(),n.preventDefault()};function Mb(n){return n==="scheduled"?"codicon-clock":n==="running"?"codicon-loading":n==="failed"?"codicon-error":n==="passed"?"codicon-check":n==="skipped"?"codicon-circle-slash":"codicon-circle-outline"}function b_(n){return n==="scheduled"?"Pending":n==="running"?"Running":n==="failed"?"Failed":n==="passed"?"Passed":n==="skipped"?"Skipped":"Did not run"}const v_=m_,S_=({actions:n,selectedAction:e,selectedTime:i,setSelectedTime:r,treeState:l,setTreeState:o,sdkLanguage:u,onSelected:f,onHighlighted:h,revealConsole:g,revealActionAttachment:y,isLive:m})=>{const{rootItem:w,itemMap:v}=U.useMemo(()=>sb(n),[n]),{selectedItem:E}=U.useMemo(()=>({selectedItem:e?v.get(e.callId):void 0}),[v,e]),x=U.useCallback(D=>{var K;return!!((K=D.action.error)!=null&&K.message)},[]),_=U.useCallback(D=>r({minimum:D.action.startTime,maximum:D.action.endTime}),[r]),N=U.useCallback(D=>{var Q;const K=!!y&&!!((Q=D.action.attachments)!=null&&Q.length);return ed(D.action,{sdkLanguage:u,revealConsole:g,revealActionAttachment:()=>y==null?void 0:y(D.action.callId),isLive:m,showDuration:!0,showBadges:!0,showAttachments:K})},[m,g,y,u]),C=U.useCallback(D=>!i||!D.action||D.action.startTime<=i.maximum&&D.action.endTime>=i.minimum,[i]),$=U.useCallback(D=>{f==null||f(D.action)},[f]),I=U.useCallback(D=>{h==null||h(D==null?void 0:D.action)},[h]);return S.jsxs("div",{className:"vbox",children:[i&&S.jsxs("div",{className:"action-list-show-all",onClick:()=>r(void 0),children:[S.jsx("span",{className:"codicon codicon-triangle-left"}),"Show all"]}),S.jsx(v_,{name:"actions",rootItem:w,treeState:l,setTreeState:o,selectedItem:E,onSelected:$,onHighlighted:I,onAccepted:_,isError:x,isVisible:C,render:N})]})},ed=(n,e)=>{var _;const{sdkLanguage:i,revealConsole:r,revealActionAttachment:l,isLive:o,showDuration:u,showBadges:f,showAttachments:h}=e,{errors:g,warnings:y}=Dx(n),m=n.params.selector?o_(i||"javascript",n.params.selector):void 0,w=n.class==="Test"&&n.method==="test.step"&&((_=n.annotations)==null?void 0:_.some(N=>N.type==="skip"));let v="";n.endTime?v=Et(n.endTime-n.startTime):n.error?v="Timed out":o||(v="-");const{elements:E,title:x}=Ob(n);return S.jsxs("div",{className:"action-title vbox",children:[S.jsxs("div",{className:"hbox",children:[S.jsx("span",{className:"action-title-method",title:x,children:E}),(u||f||h||w)&&S.jsx("div",{className:"spacer"}),h&&S.jsx(Ht,{icon:"attach",title:"Open Attachment",onClick:()=>l==null?void 0:l()}),u&&!w&&S.jsx("div",{className:"action-duration",children:v||S.jsx("span",{className:"codicon codicon-loading"})}),w&&S.jsx("span",{className:Fe("action-skipped","codicon",Mb("skipped")),title:"skipped"}),f&&S.jsxs("div",{className:"action-icons",onClick:()=>r==null?void 0:r(),children:[!!g&&S.jsxs("div",{className:"action-icon",children:[S.jsx("span",{className:"codicon codicon-error"}),S.jsx("span",{className:"action-icon-value",children:g})]}),!!y&&S.jsxs("div",{className:"action-icon",children:[S.jsx("span",{className:"codicon codicon-warning"}),S.jsx("span",{className:"action-icon-value",children:y})]})]})]}),m&&S.jsx("div",{className:"action-title-selector",title:m,children:m})]})};function Ob(n){var f;let e=n.title??((f=Qh.get(n.class+"."+n.method))==null?void 0:f.title)??n.method;e=e.replace(/\n/g," ");const i=[],r=[];let l=0;const o=/\{([^}]+)\}/g;let u;for(;(u=o.exec(e))!==null;){const[h,g]=u,y=e.slice(l,u.index);i.push(y),r.push(y);const m=eb(n.params,g);m===void 0?(i.push(h),r.push(h)):u.index===0?(i.push(m),r.push(m)):(i.push(S.jsx("span",{className:"action-title-param",children:m},i.length)),r.push(m)),l=u.index+h.length}if(l{const[i,r]=U.useState("copy"),l=U.useCallback(()=>{(typeof n=="function"?n():Promise.resolve(n)).then(u=>{navigator.clipboard.writeText(u).then(()=>{r("check"),setTimeout(()=>{r("copy")},3e3)},()=>{r("close")})},()=>{r("close")})},[n]);return S.jsx(Ht,{title:e||"Copy",icon:i,onClick:l})},Ko=({value:n,description:e,copiedDescription:i=e,style:r})=>{const[l,o]=U.useState(!1),u=U.useCallback(async()=>{const f=typeof n=="function"?await n():n;await navigator.clipboard.writeText(f),o(!0),setTimeout(()=>o(!1),3e3)},[n]);return S.jsx(Ht,{style:r,title:e,onClick:u,className:"copy-to-clipboard-text-button",children:l?i:e})},ms=({text:n})=>S.jsx("div",{className:"fill",style:{display:"flex",alignItems:"center",justifyContent:"center",fontSize:24,fontWeight:"bold",opacity:.5},children:n}),w_=({action:n,startTimeOffset:e,sdkLanguage:i})=>{const r=U.useMemo(()=>Object.keys((n==null?void 0:n.params)??{}).filter(f=>f!=="info"),[n]);if(!n)return S.jsx(ms,{text:"No action selected"});const l=n.startTime-e,o=Et(l),{title:u}=Ob(n);return S.jsxs("div",{className:"call-tab",children:[S.jsx("div",{className:"call-line",children:u}),S.jsx("div",{className:"call-section",children:"Time"}),Oo({name:"start",type:"literal",text:o}),Oo({name:"duration",type:"literal",text:x_(n)}),!!r.length&&S.jsxs(S.Fragment,{children:[S.jsx("div",{className:"call-section",children:"Parameters"}),r.map(f=>Oo(a0(n,f,n.params[f],i)))]}),!!n.result&&S.jsxs(S.Fragment,{children:[S.jsx("div",{className:"call-section",children:"Return value"}),Object.keys(n.result).map(f=>Oo(a0(n,f,n.result[f],i)))]})]})};function x_(n){return n.endTime?Et(n.endTime-n.startTime):n.error?"Timed Out":"Running"}function Oo(n){let e=n.text.replace(/\n/g,"↵");return n.type==="string"&&(e=`"${e}"`),S.jsxs("div",{className:"call-line",children:[n.name,":",S.jsx("span",{className:Fe("call-value",n.type),title:n.text,children:e}),["literal","string","number","object","locator"].includes(n.type)&&S.jsx(td,{value:n.text})]},n.name)}function a0(n,e,i,r){const l=n.method.includes("eval")||n.method==="waitForFunction";if(e==="files")return{text:"",type:"string",name:e};if((e==="eventInit"||e==="expectedValue"||e==="arg"&&l)&&(i=ac(i.value,new Array(10).fill({handle:""}))),(e==="value"&&l||e==="received"&&n.method==="expect")&&(i=ac(i,new Array(10).fill({handle:""}))),e==="selector")return{text:Oi(r||"javascript",n.params.selector),type:"locator",name:"locator"};const o=typeof i;return o!=="object"||i===null?{text:String(i),type:o,name:e}:i.guid?{text:"",type:"handle",name:e}:{text:JSON.stringify(i).slice(0,1e3),type:"object",name:e}}function ac(n,e){if(n.n!==void 0)return n.n;if(n.s!==void 0)return n.s;if(n.b!==void 0)return n.b;if(n.v!==void 0){if(n.v==="undefined")return;if(n.v==="null")return null;if(n.v==="NaN")return NaN;if(n.v==="Infinity")return 1/0;if(n.v==="-Infinity")return-1/0;if(n.v==="-0")return-0}if(n.d!==void 0)return new Date(n.d);if(n.r!==void 0)return new RegExp(n.r.p,n.r.f);if(n.a!==void 0)return n.a.map(i=>ac(i,e));if(n.o!==void 0){const i={};for(const{k:r,v:l}of n.o)i[r]=ac(l,e);return i}return n.h!==void 0?e===void 0?"":e[n.h]:""}const l0=new Map;function yc({name:n,items:e=[],id:i,render:r,icon:l,isError:o,isWarning:u,isInfo:f,selectedItem:h,onAccepted:g,onSelected:y,onHighlighted:m,onIconClicked:w,noItemsMessage:v,dataTestId:E,notSelectable:x,ariaLabel:_}){const N=U.useRef(null),[C,$]=U.useState();return U.useEffect(()=>{m==null||m(C)},[m,C]),U.useEffect(()=>{const I=N.current;if(!I)return;const D=()=>{l0.set(n,I.scrollTop)};return I.addEventListener("scroll",D,{passive:!0}),()=>I.removeEventListener("scroll",D)},[n]),U.useEffect(()=>{N.current&&(N.current.scrollTop=l0.get(n)||0)},[n]),S.jsx("div",{className:Fe("list-view vbox",n+"-list-view"),role:e.length>0?"list":void 0,"aria-label":_,children:S.jsxs("div",{className:Fe("list-view-content",x&&"not-selectable"),tabIndex:0,onKeyDown:I=>{var q;if(h&&I.key==="Enter"){g==null||g(h,e.indexOf(h));return}if(I.key!=="ArrowDown"&&I.key!=="ArrowUp")return;I.stopPropagation(),I.preventDefault();const D=h?e.indexOf(h):-1;let K=D;I.key==="ArrowDown"&&(D===-1?K=0:K=Math.min(D+1,e.length-1)),I.key==="ArrowUp"&&(D===-1?K=e.length-1:K=Math.max(D-1,0));const Q=(q=N.current)==null?void 0:q.children.item(K);J0(Q||void 0),m==null||m(void 0),y==null||y(e[K],K),$(void 0)},ref:N,children:[v&&e.length===0&&S.jsx("div",{className:"list-view-empty",children:v}),e.map((I,D)=>{const K=r(I,D);return S.jsxs("div",{onDoubleClick:()=>g==null?void 0:g(I,D),role:"listitem",className:Fe("list-view-entry",h===I&&"selected",!x&&C===I&&"highlighted",(o==null?void 0:o(I,D))&&"error",(u==null?void 0:u(I,D))&&"warning",(f==null?void 0:f(I,D))&&"info"),"aria-selected":h===I,onClick:()=>y==null?void 0:y(I,D),onMouseEnter:()=>$(I),onMouseLeave:()=>$(void 0),children:[l&&S.jsx("div",{className:"codicon "+(l(I,D)||"codicon-blank"),style:{minWidth:16,marginRight:4},onDoubleClick:Q=>{Q.preventDefault(),Q.stopPropagation()},onClick:Q=>{Q.stopPropagation(),Q.preventDefault(),w==null||w(I,D)}}),typeof K=="string"?S.jsx("div",{style:{textOverflow:"ellipsis",overflow:"hidden"},children:K}):K]},(i==null?void 0:i(I,D))||D)})]})})}const __=yc,T_=({action:n,isLive:e})=>{const i=U.useMemo(()=>{var u;if(!n||!n.log.length)return[];const r=n.log,l=n.context.wallTime-n.context.startTime,o=[];for(let f=0;f0?h=Et(n.endTime-g):e?h=Et(Date.now()-l-g):h="-"}o.push({message:r[f].message,time:h})}return o},[n,e]);return i.length?S.jsx(__,{name:"log",ariaLabel:"Log entries",items:i,render:r=>S.jsxs("div",{className:"log-list-item",children:[S.jsx("span",{className:"log-list-duration",children:r.time}),r.message]}),notSelectable:!0}):S.jsx(ms,{text:"No log entries"})};function nl(n,e){const i=/(\x1b\[(\d+(;\d+)*)m)|([^\x1b]+)/g,r=[];let l,o={},u=!1,f=e==null?void 0:e.fg,h=e==null?void 0:e.bg;for(;(l=i.exec(n))!==null;){const[,,g,,y]=l;if(g){const m=+g;switch(m){case 0:o={};break;case 1:o["font-weight"]="bold";break;case 2:o.opacity="0.8";break;case 3:o["font-style"]="italic";break;case 4:o["text-decoration"]="underline";break;case 7:u=!0;break;case 8:o.display="none";break;case 9:o["text-decoration"]="line-through";break;case 22:delete o["font-weight"],delete o["font-style"],delete o.opacity,delete o["text-decoration"];break;case 23:delete o["font-weight"],delete o["font-style"],delete o.opacity;break;case 24:delete o["text-decoration"];break;case 27:u=!1;break;case 30:case 31:case 32:case 33:case 34:case 35:case 36:case 37:f=o0[m-30];break;case 39:f=e==null?void 0:e.fg;break;case 40:case 41:case 42:case 43:case 44:case 45:case 46:case 47:h=o0[m-40];break;case 49:h=e==null?void 0:e.bg;break;case 53:o["text-decoration"]="overline";break;case 90:case 91:case 92:case 93:case 94:case 95:case 96:case 97:f=c0[m-90];break;case 100:case 101:case 102:case 103:case 104:case 105:case 106:case 107:h=c0[m-100];break}}else if(y){const m={...o},w=u?h:f;w!==void 0&&(m.color=w);const v=u?f:h;v!==void 0&&(m["background-color"]=v),r.push(`${E_(y)}`)}}return r.join("")}const o0={0:"var(--vscode-terminal-ansiBlack)",1:"var(--vscode-terminal-ansiRed)",2:"var(--vscode-terminal-ansiGreen)",3:"var(--vscode-terminal-ansiYellow)",4:"var(--vscode-terminal-ansiBlue)",5:"var(--vscode-terminal-ansiMagenta)",6:"var(--vscode-terminal-ansiCyan)",7:"var(--vscode-terminal-ansiWhite)"},c0={0:"var(--vscode-terminal-ansiBrightBlack)",1:"var(--vscode-terminal-ansiBrightRed)",2:"var(--vscode-terminal-ansiBrightGreen)",3:"var(--vscode-terminal-ansiBrightYellow)",4:"var(--vscode-terminal-ansiBrightBlue)",5:"var(--vscode-terminal-ansiBrightMagenta)",6:"var(--vscode-terminal-ansiBrightCyan)",7:"var(--vscode-terminal-ansiBrightWhite)"};function E_(n){return n.replace(/[&"<>]/g,e=>({"&":"&",'"':""","<":"<",">":">"})[e])}function A_(n){return Object.entries(n).map(([e,i])=>`${e}: ${i}`).join("; ")}const N_=({error:n})=>{const e=U.useMemo(()=>nl(n),[n]);return S.jsx("div",{className:"error-message",dangerouslySetInnerHTML:{__html:e||""}})},jb=({cursor:n,onPaneMouseMove:e,onPaneMouseUp:i,onPaneDoubleClick:r})=>(gt.useEffect(()=>{const l=document.createElement("div");return l.style.position="fixed",l.style.top="0",l.style.right="0",l.style.bottom="0",l.style.left="0",l.style.zIndex="9999",l.style.cursor=n,document.body.appendChild(l),e&&l.addEventListener("mousemove",e),i&&l.addEventListener("mouseup",i),r&&document.body.addEventListener("dblclick",r),()=>{e&&l.removeEventListener("mousemove",e),i&&l.removeEventListener("mouseup",i),r&&document.body.removeEventListener("dblclick",r),document.body.removeChild(l)}},[n,e,i,r]),S.jsx(S.Fragment,{})),C_={position:"absolute",top:0,right:0,bottom:0,left:0},Lb=({orientation:n,offsets:e,setOffsets:i,resizerColor:r,resizerWidth:l,minColumnWidth:o})=>{const u=o||0,[f,h]=gt.useState(null),[g,y]=gs(),m={position:"absolute",right:n==="horizontal"?void 0:0,bottom:n==="horizontal"?0:void 0,width:n==="horizontal"?7:void 0,height:n==="horizontal"?void 0:7,borderTopWidth:n==="horizontal"?void 0:(7-l)/2,borderRightWidth:n==="horizontal"?(7-l)/2:void 0,borderBottomWidth:n==="horizontal"?void 0:(7-l)/2,borderLeftWidth:n==="horizontal"?(7-l)/2:void 0,borderColor:"transparent",borderStyle:"solid",cursor:n==="horizontal"?"ew-resize":"ns-resize"};return S.jsxs("div",{style:{position:"absolute",top:0,right:0,bottom:0,left:-(7-l)/2,zIndex:100,pointerEvents:"none"},ref:y,children:[!!f&&S.jsx(jb,{cursor:n==="horizontal"?"ew-resize":"ns-resize",onPaneMouseUp:()=>h(null),onPaneMouseMove:w=>{if(!w.buttons)h(null);else if(f){const v=n==="horizontal"?w.clientX-f.clientX:w.clientY-f.clientY,E=f.offset+v,x=f.index>0?e[f.index-1]:0,_=n==="horizontal"?g.width:g.height,N=Math.min(Math.max(x+u,E),_-u)-e[f.index];for(let C=f.index;CS.jsx("div",{style:{...m,top:n==="horizontal"?0:w,left:n==="horizontal"?w:0,pointerEvents:"initial"},onMouseDown:E=>h({clientX:E.clientX,clientY:E.clientY,offset:w,index:v}),children:S.jsx("div",{style:{...C_,background:r}})},v))]})};async function lh(n){const e=new Image;return n&&(e.src=n,await new Promise((i,r)=>{e.onload=i,e.onerror=i})),e}const Oh={backgroundImage:`linear-gradient(45deg, #80808020 25%, transparent 25%), + linear-gradient(-45deg, #80808020 25%, transparent 25%), + linear-gradient(45deg, transparent 75%, #80808020 75%), + linear-gradient(-45deg, transparent 75%, #80808020 75%)`,backgroundSize:"20px 20px",backgroundPosition:"0 0, 0 10px, 10px -10px, -10px 0px",boxShadow:`rgb(0 0 0 / 10%) 0px 1.8px 1.9px, + rgb(0 0 0 / 15%) 0px 6.1px 6.3px, + rgb(0 0 0 / 10%) 0px -2px 4px, + rgb(0 0 0 / 15%) 0px -6.1px 12px, + rgb(0 0 0 / 25%) 0px 6px 12px`},k_=({diff:n,noTargetBlank:e,hideDetails:i})=>{const[r,l]=U.useState(n.diff?"diff":"actual"),[o,u]=U.useState(!1),[f,h]=U.useState(null),[g,y]=U.useState("Expected"),[m,w]=U.useState(null),[v,E]=U.useState(null),[x,_]=gs();U.useEffect(()=>{(async()=>{var j,ne,le,V;h(await lh((j=n.expected)==null?void 0:j.attachment.path)),y(((ne=n.expected)==null?void 0:ne.title)||"Expected"),w(await lh((le=n.actual)==null?void 0:le.attachment.path)),E(await lh((V=n.diff)==null?void 0:V.attachment.path))})()},[n]);const N=f&&m&&v,C=N?Math.max(f.naturalWidth,m.naturalWidth,200):500,$=N?Math.max(f.naturalHeight,m.naturalHeight,200):500,I=Math.min(1,(x.width-30)/C),D=Math.min(1,(x.width-50)/C/2),K=C*I,Q=$*I,q={flex:"none",margin:"0 10px",cursor:"pointer",userSelect:"none"};return S.jsx("div",{"data-testid":"test-result-image-mismatch",style:{display:"flex",flexDirection:"column",alignItems:"center",flex:"auto"},ref:_,children:N&&S.jsxs(S.Fragment,{children:[S.jsxs("div",{"data-testid":"test-result-image-mismatch-tabs",style:{display:"flex",margin:"10px 0 20px"},children:[n.diff&&S.jsx("div",{style:{...q,fontWeight:r==="diff"?600:"initial"},onClick:()=>l("diff"),children:"Diff"}),S.jsx("div",{style:{...q,fontWeight:r==="actual"?600:"initial"},onClick:()=>l("actual"),children:"Actual"}),S.jsx("div",{style:{...q,fontWeight:r==="expected"?600:"initial"},onClick:()=>l("expected"),children:g}),S.jsx("div",{style:{...q,fontWeight:r==="sxs"?600:"initial"},onClick:()=>l("sxs"),children:"Side by side"}),S.jsx("div",{style:{...q,fontWeight:r==="slider"?600:"initial"},onClick:()=>l("slider"),children:"Slider"})]}),S.jsxs("div",{style:{display:"flex",justifyContent:"center",flex:"auto",minHeight:Q+60},children:[n.diff&&r==="diff"&&S.jsx(Jn,{image:v,alt:"Diff",hideSize:i,canvasWidth:K,canvasHeight:Q,scale:I}),n.diff&&r==="actual"&&S.jsx(Jn,{image:m,alt:"Actual",hideSize:i,canvasWidth:K,canvasHeight:Q,scale:I}),n.diff&&r==="expected"&&S.jsx(Jn,{image:f,alt:g,hideSize:i,canvasWidth:K,canvasHeight:Q,scale:I}),n.diff&&r==="slider"&&S.jsx(M_,{expectedImage:f,actualImage:m,hideSize:i,canvasWidth:K,canvasHeight:Q,scale:I,expectedTitle:g}),n.diff&&r==="sxs"&&S.jsxs("div",{style:{display:"flex"},children:[S.jsx(Jn,{image:f,title:g,hideSize:i,canvasWidth:D*C,canvasHeight:D*$,scale:D}),S.jsx(Jn,{image:o?v:m,title:o?"Diff":"Actual",onClick:()=>u(!o),hideSize:i,canvasWidth:D*C,canvasHeight:D*$,scale:D})]}),!n.diff&&r==="actual"&&S.jsx(Jn,{image:m,title:"Actual",hideSize:i,canvasWidth:K,canvasHeight:Q,scale:I}),!n.diff&&r==="expected"&&S.jsx(Jn,{image:f,title:g,hideSize:i,canvasWidth:K,canvasHeight:Q,scale:I}),!n.diff&&r==="sxs"&&S.jsxs("div",{style:{display:"flex"},children:[S.jsx(Jn,{image:f,title:g,canvasWidth:D*C,canvasHeight:D*$,scale:D}),S.jsx(Jn,{image:m,title:"Actual",canvasWidth:D*C,canvasHeight:D*$,scale:D})]})]}),!i&&S.jsxs("div",{style:{alignSelf:"start",lineHeight:"18px",marginLeft:"15px"},children:[S.jsx("div",{children:n.diff&&S.jsx("a",{target:"_blank",href:n.diff.attachment.path,rel:"noreferrer",children:n.diff.attachment.name})}),S.jsx("div",{children:S.jsx("a",{target:e?"":"_blank",href:n.actual.attachment.path,rel:"noreferrer",children:n.actual.attachment.name})}),S.jsx("div",{children:S.jsx("a",{target:e?"":"_blank",href:n.expected.attachment.path,rel:"noreferrer",children:n.expected.attachment.name})})]})]})})},M_=({expectedImage:n,actualImage:e,canvasWidth:i,canvasHeight:r,scale:l,expectedTitle:o,hideSize:u})=>{const f={position:"absolute",top:0,left:0},[h,g]=U.useState(i/2),y=n.naturalWidth===e.naturalWidth&&n.naturalHeight===e.naturalHeight;return S.jsxs("div",{style:{flex:"none",display:"flex",alignItems:"center",flexDirection:"column",userSelect:"none"},children:[!u&&S.jsxs("div",{style:{margin:5},children:[!y&&S.jsx("span",{style:{flex:"none",margin:"0 5px"},children:"Expected "}),S.jsx("span",{children:n.naturalWidth}),S.jsx("span",{style:{flex:"none",margin:"0 5px"},children:"x"}),S.jsx("span",{children:n.naturalHeight}),!y&&S.jsx("span",{style:{flex:"none",margin:"0 5px 0 15px"},children:"Actual "}),!y&&S.jsx("span",{children:e.naturalWidth}),!y&&S.jsx("span",{style:{flex:"none",margin:"0 5px"},children:"x"}),!y&&S.jsx("span",{children:e.naturalHeight})]}),S.jsxs("div",{style:{position:"relative",width:i,height:r,margin:15,...Oh},children:[S.jsx(Lb,{orientation:"horizontal",offsets:[h],setOffsets:m=>g(m[0]),resizerColor:"#57606a80",resizerWidth:6}),S.jsx("img",{alt:o,style:{width:n.naturalWidth*l,height:n.naturalHeight*l},draggable:"false",src:n.src}),S.jsx("div",{style:{...f,bottom:0,overflow:"hidden",width:h,...Oh},children:S.jsx("img",{alt:"Actual",style:{width:e.naturalWidth*l,height:e.naturalHeight*l},draggable:"false",src:e.src})})]})]})},Jn=({image:n,title:e,alt:i,hideSize:r,canvasWidth:l,canvasHeight:o,scale:u,onClick:f})=>S.jsxs("div",{style:{flex:"none",display:"flex",alignItems:"center",flexDirection:"column"},children:[!r&&S.jsxs("div",{style:{margin:5},children:[e&&S.jsx("span",{style:{flex:"none",margin:"0 5px"},children:e}),S.jsx("span",{children:n.naturalWidth}),S.jsx("span",{style:{flex:"none",margin:"0 5px"},children:"x"}),S.jsx("span",{children:n.naturalHeight})]}),S.jsx("div",{style:{display:"flex",flex:"none",width:l,height:o,margin:15,...Oh},children:S.jsx("img",{width:n.naturalWidth*u,height:n.naturalHeight*u,alt:e||i,style:{cursor:f?"pointer":"initial"},draggable:"false",src:n.src,onClick:f})})]}),O_="modulepreload",j_=function(n,e){return new URL(n,e).href},u0={},L_=function(e,i,r){let l=Promise.resolve();if(i&&i.length>0){let u=function(y){return Promise.all(y.map(m=>Promise.resolve(m).then(w=>({status:"fulfilled",value:w}),w=>({status:"rejected",reason:w}))))};const f=document.getElementsByTagName("link"),h=document.querySelector("meta[property=csp-nonce]"),g=(h==null?void 0:h.nonce)||(h==null?void 0:h.getAttribute("nonce"));l=u(i.map(y=>{if(y=j_(y,r),y in u0)return;u0[y]=!0;const m=y.endsWith(".css"),w=m?'[rel="stylesheet"]':"";if(!!r)for(let x=f.length-1;x>=0;x--){const _=f[x];if(_.href===y&&(!m||_.rel==="stylesheet"))return}else if(document.querySelector(`link[href="${y}"]${w}`))return;const E=document.createElement("link");if(E.rel=m?"stylesheet":O_,m||(E.as="script"),E.crossOrigin="",E.href=y,g&&E.setAttribute("nonce",g),document.head.appendChild(E),m)return new Promise((x,_)=>{E.addEventListener("load",x),E.addEventListener("error",()=>_(new Error(`Unable to preload CSS for ${y}`)))})}))}function o(u){const f=new Event("vite:preloadError",{cancelable:!0});if(f.payload=u,window.dispatchEvent(f),!f.defaultPrevented)throw u}return l.then(u=>{for(const f of u||[])f.status==="rejected"&&o(f.reason);return e().catch(o)})},R_=20,xr=({text:n,highlighter:e,mimeType:i,linkify:r,readOnly:l,highlight:o,revealLine:u,lineNumbers:f,isFocused:h,focusOnChange:g,wrapLines:y,onChange:m,dataTestId:w,placeholder:v})=>{const[E,x]=gs(),[_]=U.useState(L_(()=>import("./codeMirrorModule-a5XoALAZ.js"),__vite__mapDeps([0,1]),import.meta.url).then(I=>I.default)),N=U.useRef(null),[C,$]=U.useState();return U.useEffect(()=>{(async()=>{var q,j;const I=await _;z_(I);const D=x.current;if(!D)return;const K=U_(e)||B_(i)||(r?"text/linkified":"");if(N.current&&K===N.current.cm.getOption("mode")&&!!l===N.current.cm.getOption("readOnly")&&f===N.current.cm.getOption("lineNumbers")&&y===N.current.cm.getOption("lineWrapping")&&v===N.current.cm.getOption("placeholder"))return;(j=(q=N.current)==null?void 0:q.cm)==null||j.getWrapperElement().remove();const Q=I(D,{value:"",mode:K,readOnly:!!l,lineNumbers:f,lineWrapping:y,placeholder:v,matchBrackets:!0,autoCloseBrackets:!0,extraKeys:{"Ctrl-F":"findPersistent","Cmd-F":"findPersistent"}});return N.current={cm:Q},h&&Q.focus(),$(Q),Q})()},[_,C,x,e,i,r,f,y,l,h,v]),U.useEffect(()=>{N.current&&N.current.cm.setSize(E.width,E.height)},[E]),U.useLayoutEffect(()=>{var K;if(!C)return;let I=!1;if(C.getValue()!==n&&(C.setValue(n),I=!0,g&&(C.execCommand("selectAll"),C.focus())),I||JSON.stringify(o)!==JSON.stringify(N.current.highlight)){for(const j of N.current.highlight||[])C.removeLineClass(j.line-1,"wrap");for(const j of o||[])C.addLineClass(j.line-1,"wrap",`source-line-${j.type}`);for(const j of N.current.widgets||[])C.removeLineWidget(j);for(const j of N.current.markers||[])j.clear();const Q=[],q=[];for(const j of o||[]){if(j.type!=="subtle-error"&&j.type!=="error")continue;const ne=(K=N.current)==null?void 0:K.cm.getLine(j.line-1);if(ne){const le={};le.title=j.message||"",q.push(C.markText({line:j.line-1,ch:0},{line:j.line-1,ch:j.column||ne.length},{className:"source-line-error-underline",attributes:le}))}if(j.type==="error"){const le=document.createElement("div");le.innerHTML=nl(j.message||""),le.className="source-line-error-widget",Q.push(C.addLineWidget(j.line,le,{above:!0,coverGutter:!1}))}}N.current.highlight=o,N.current.widgets=Q,N.current.markers=q}typeof u=="number"&&N.current.cm.lineCount()>=u&&C.scrollIntoView({line:Math.max(0,u-1),ch:0},50);let D;return m&&(D=()=>m(C.getValue()),C.on("change",D)),()=>{D&&C.off("change",D)}},[C,n,o,u,g,m]),S.jsx("div",{"data-testid":w,className:"cm-wrapper",ref:x,onClick:D_})};function D_(n){var i;if(!(n.target instanceof HTMLElement))return;let e;n.target.classList.contains("cm-linkified")?e=n.target.textContent:n.target.classList.contains("cm-link")&&((i=n.target.nextElementSibling)!=null&&i.classList.contains("cm-url"))&&(e=n.target.nextElementSibling.textContent.slice(1,-1)),e&&(n.preventDefault(),n.stopPropagation(),window.open(e,"_blank"))}let f0=!1;function z_(n){f0||(f0=!0,n.defineSimpleMode("text/linkified",{start:[{regex:P0,token:"linkified"}]}))}function B_(n){if(n){if(n.includes("javascript")||n.includes("json"))return"javascript";if(n.includes("python"))return"python";if(n.includes("csharp"))return"text/x-csharp";if(n.includes("java"))return"text/x-java";if(n.includes("markdown"))return"markdown";if(n.includes("html")||n.includes("svg"))return"htmlmixed";if(n.includes("css"))return"css"}}function U_(n){if(n)return{javascript:"javascript",jsonl:"javascript",python:"python",csharp:"text/x-csharp",java:"text/x-java",markdown:"markdown",html:"htmlmixed",css:"css",yaml:"yaml"}[n]}function H_(n){return!!n.match(/^(application\/json|application\/.*?\+json|text\/(x-)?json)(;\s*charset=.*)?$/)}function q_(n){return!!n.match(/^(text\/.*?|application\/(json|(x-)?javascript|xml.*?|ecmascript|graphql|x-www-form-urlencoded)|image\/svg(\+xml)?|application\/.*?(\+json|\+xml))(;\s*charset=.*)?$/)}const Rb=({title:n,children:e,setExpanded:i,expanded:r,expandOnTitleClick:l,className:o})=>{const u=U.useId(),f=U.useId(),h=U.useCallback(()=>i(!r),[r,i]),g=S.jsx("div",{className:Fe("codicon",r?"codicon-chevron-down":"codicon-chevron-right"),style:{cursor:"pointer",color:"var(--vscode-foreground)",marginLeft:"5px"},onClick:l?void 0:h});return S.jsxs("div",{className:Fe("expandable",r&&"expanded",o),children:[l?S.jsxs("div",{id:u,role:"button","aria-expanded":r,"aria-controls":f,className:"expandable-title",onClick:h,children:[g,n]}):S.jsxs("div",{className:"expandable-title",children:[g,n]}),r&&S.jsx("div",{id:f,"aria-labelledby":u,role:"region",className:"expandable-content",children:e})]})};function Db(n){const e=[];let i=0,r;for(;(r=P0.exec(n))!==null;){const o=n.substring(i,r.index);o&&e.push(o);const u=r[0];e.push($_(u)),i=r.index+u.length}const l=n.substring(i);return l&&e.push(l),e}function $_(n){let e=n;return e.startsWith("www.")&&(e="https://"+e),S.jsx("a",{href:e,target:"_blank",rel:"noopener noreferrer",children:n})}const zb=U.createContext(void 0),ti=()=>U.useContext(zb),I_=({attachment:n,reveal:e})=>{const i=ti(),[r,l]=U.useState(!1),[o,u]=U.useState(null),[f,h]=U.useState(null),[g,y]=px(),m=U.useRef(null),w=q_(n.contentType),v=!!n.sha1||!!n.path;U.useEffect(()=>{var _;if(e)return(_=m.current)==null||_.scrollIntoView({behavior:"smooth"}),y()},[e,y]),U.useEffect(()=>{r&&o===null&&f===null&&(h("Loading ..."),fetch(bc(i,n)).then(_=>_.text()).then(_=>{u(_),h(null)}).catch(_=>{h("Failed to load: "+_.message)}))},[i,r,o,f,n]);const E=U.useMemo(()=>{const _=o?o.split(` +`).length:0;return Math.min(Math.max(5,_),20)*R_},[o]),x=S.jsxs("span",{style:{marginLeft:5},ref:m,"aria-label":n.name,children:[S.jsx("span",{children:Db(n.name)}),v&&S.jsx("a",{style:{marginLeft:5},href:Yo(i,n),children:"download"})]});return!w||!v?S.jsx("div",{style:{marginLeft:20},children:x}):S.jsxs("div",{className:Fe(g&&"yellow-flash"),children:[S.jsx(Rb,{title:x,expanded:r,setExpanded:l,expandOnTitleClick:!0,children:f&&S.jsx("i",{children:f})}),r&&o!==null&&S.jsx("div",{className:"vbox",style:{height:E},children:S.jsx(xr,{text:o,readOnly:!0,mimeType:n.contentType,linkify:!0,lineNumbers:!0,wrapLines:!1})})]})},V_=({revealedAttachmentCallId:n})=>{const e=ti(),{diffMap:i,screenshots:r,attachments:l}=U.useMemo(()=>{const o=new Set((e==null?void 0:e.visibleAttachments)??[]),u=new Set,f=new Map;for(const h of o){if(!h.path&&!h.sha1)continue;const g=h.name.match(/^(.*)-(expected|actual|diff)\.png$/);if(g){const y=g[1],m=g[2],w=f.get(y)||{expected:void 0,actual:void 0,diff:void 0};w[m]=h,f.set(y,w),o.delete(h)}else h.contentType.startsWith("image/")&&(u.add(h),o.delete(h))}return{diffMap:f,attachments:o,screenshots:u}},[e]);return!i.size&&!r.size&&!l.size?S.jsx(ms,{text:"No attachments"}):S.jsxs("div",{className:"attachments-tab",children:[[...i.values()].map(({expected:o,actual:u,diff:f})=>S.jsxs(S.Fragment,{children:[o&&u&&S.jsx("div",{className:"attachments-section",children:"Image diff"}),o&&u&&S.jsx(k_,{noTargetBlank:!0,diff:{name:"Image diff",expected:{attachment:{...o,path:Yo(e,o)},title:"Expected"},actual:{attachment:{...u,path:Yo(e,u)}},diff:f?{attachment:{...f,path:Yo(e,f)}}:void 0}})]})),r.size?S.jsx("div",{className:"attachments-section",children:"Screenshots"}):void 0,[...r.values()].map((o,u)=>{const f=bc(e,o);return S.jsxs("div",{className:"attachment-item",children:[S.jsx("div",{children:S.jsx("img",{draggable:"false",src:f})}),S.jsx("div",{children:S.jsx("a",{target:"_blank",href:f,rel:"noreferrer",children:o.name})})]},`screenshot-${u}`)}),l.size?S.jsx("div",{className:"attachments-section",children:"Attachments"}):void 0,[...l.values()].map((o,u)=>S.jsx("div",{className:"attachment-item",children:S.jsx(I_,{attachment:o,reveal:n&&o.callId===n.callId?n:void 0})},G_(o,u)))]})};function bc(n,e){return n&&e.sha1?n.createRelativeUrl(`sha1/${e.sha1}`):`file?path=${encodeURIComponent(e.path)}`}function Yo(n,e){let i=e.contentType?`&dn=${encodeURIComponent(e.name)}`:"";return e.contentType&&(i+=`&dct=${encodeURIComponent(e.contentType)}`),bc(n,e)+i}function G_(n,e){return e+"-"+(n.sha1?"sha1-"+n.sha1:"path-"+n.path)}const K_=` +# Instructions + +- Following Playwright test failed. +- Explain why, be concise, respect Playwright best practices. +- Provide a snippet of code with the fix, if possible. +`.trimStart();async function Y_({testInfo:n,metadata:e,errorContext:i,errors:r,buildCodeFrame:l,stdout:o,stderr:u}){var m;const f=new Set(r.filter(w=>w.message&&!w.message.includes(` +`)).map(w=>w.message));for(const w of r)for(const v of f.keys())(m=w.message)!=null&&m.includes(v)&&f.delete(v);const h=r.filter(w=>!(!w.message||!w.message.includes(` +`)&&!f.has(w.message)));if(!h.length)return;const g=[K_,"# Test info","",n];o&&g.push("","# Stdout","","```",Xo(o),"```"),u&&g.push("","# Stderr","","```",Xo(u),"```"),g.push("","# Error details");for(const w of h)g.push("","```",Xo(w.message||""),"```");i&&g.push(i);const y=await l(h[h.length-1]);return y&&g.push("","# Test source","","```ts",y,"```"),e!=null&&e.gitDiff&&g.push("","# Local changes","","```diff",e.gitDiff,"```"),g.join(` +`)}const X_=new RegExp("([\\u001B\\u009B][[\\]()#;?]*(?:(?:(?:[a-zA-Z\\d]*(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]*)*)?\\u0007)|(?:(?:\\d{1,4}(?:;\\d{0,4})*)?[\\dA-PR-TZcf-ntqry=><~])))","g");function Xo(n){return n.replace(X_,"")}const F_=yc,Q_=({stack:n,setSelectedFrame:e,selectedFrame:i})=>{const r=n||[];return S.jsx(F_,{name:"stack-trace",ariaLabel:"Stack trace",items:r,selectedItem:r[i],render:l=>{const o=l.file[1]===":"?"\\":"/";return S.jsxs(S.Fragment,{children:[S.jsx("span",{className:"stack-trace-frame-function",children:l.function||"(anonymous)"}),S.jsx("span",{className:"stack-trace-frame-location",children:l.file.split(o).pop()}),S.jsx("span",{className:"stack-trace-frame-line",children:":"+l.line})]})},onSelected:l=>e(r.indexOf(l))})},nd=({noShadow:n,children:e,noMinHeight:i,className:r,sidebarBackground:l,onClick:o})=>S.jsx("div",{className:Fe("toolbar",n&&"no-shadow",i&&"no-min-height",r,l&&"toolbar-sidebar-background"),onClick:o,children:e});function J_(n,e,i,r,l){const o=ti();return ec(async()=>{var v,E,x,_;const u=n==null?void 0:n[e],f=u!=null&&u.file?u:l;if(!f)return{source:{file:"",errors:[],content:void 0},targetLine:0,highlight:[]};const h=f.file;let g=i.get(h);g||(g={errors:((v=l==null?void 0:l.source)==null?void 0:v.errors)||[],content:(E=l==null?void 0:l.source)==null?void 0:E.content},i.set(h,g));const y=(f==null?void 0:f.line)||((x=g.errors[0])==null?void 0:x.line)||0,m=r&&h.startsWith(r)?h.substring(r.length+1):h,w=g.errors.map(N=>({type:"error",line:N.line,message:N.message}));if(w.push({line:y,type:"running"}),((_=l==null?void 0:l.source)==null?void 0:_.content)!==void 0)g.content=l.source.content;else if(g.content===void 0||f===l){const N=await Bb(h);try{let C=o?await fetch(o.createRelativeUrl(`sha1/src@${N}.txt`)):void 0;(!C||C.status===404)&&(C=await fetch(`file?path=${encodeURIComponent(h)}`)),C.status>=400?g.content="":g.content=await C.text()}catch{g.content=``}}return{model:o,source:g,highlight:w,targetLine:y,fileName:m,location:f}},[n,e,r,l],{source:{errors:[],content:"Loading…"},highlight:[]})}const P_=({stack:n,sources:e,rootDir:i,fallbackLocation:r,stackFrameLocation:l,onOpenExternally:o})=>{const[u,f]=U.useState(),[h,g]=U.useState(0);U.useEffect(()=>{u!==n&&(f(n),g(0))},[n,u,f,g]);const{source:y,highlight:m,targetLine:w,fileName:v,location:E}=J_(n,h,e,i,r),x=U.useCallback(()=>{E&&(o?o(E):window.location.href=`vscode://file//${E.file}:${E.line}`)},[o,E]),_=((n==null?void 0:n.length)??0)>1,N=Z_(v),C=N.endsWith(".md")?"markdown":"javascript";return S.jsx(nc,{sidebarSize:200,orientation:l==="bottom"?"vertical":"horizontal",sidebarHidden:!_,main:S.jsxs("div",{className:"vbox","data-testid":"source-code",children:[v&&S.jsxs(nd,{children:[S.jsx("div",{className:"source-tab-file-name",title:v,children:S.jsx("div",{children:N})}),S.jsx(td,{description:"Copy filename",value:N}),E&&S.jsx(Ht,{icon:"link-external",title:"Open in VS Code",onClick:x})]}),S.jsx(xr,{text:y.content||"",highlighter:C,highlight:m,revealLine:w,readOnly:!0,lineNumbers:!0,dataTestId:"source-code-mirror"})]}),sidebar:S.jsx(Q_,{stack:n,selectedFrame:h,setSelectedFrame:g})})};async function Bb(n){const e=new TextEncoder().encode(n),i=await crypto.subtle.digest("SHA-1",e),r=[],l=new DataView(i);for(let o=0;oS.jsx(Ko,{value:n,description:"Copy prompt",copiedDescription:S.jsxs(S.Fragment,{children:["Copied ",S.jsx("span",{className:"codicon codicon-copy",style:{marginLeft:"5px"}})]}),style:{width:"120px",justifyContent:"center"}});function eT(n){return U.useMemo(()=>{if(!n)return{errors:new Map};const e=new Map;for(const i of n.errorDescriptors)e.set(i.message,i);return{errors:e}},[n])}function tT({message:n,error:e,sdkLanguage:i,revealInSource:r}){var f;let l,o;const u=(f=e.stack)==null?void 0:f[0];return u&&(l=u.file.replace(/.*[/\\](.*)/,"$1")+":"+u.line,o=u.file+":"+u.line),S.jsxs("div",{style:{display:"flex",flexDirection:"column",overflowX:"clip"},children:[S.jsxs("div",{className:"hbox",style:{alignItems:"center",padding:"5px 10px",minHeight:36,fontWeight:"bold",color:"var(--vscode-errorForeground)",flex:0},children:[e.action&&ed(e.action,{sdkLanguage:i}),l&&S.jsxs("div",{className:"action-location",children:["@ ",S.jsx("span",{title:o,onClick:()=>r(e),children:l})]})]}),S.jsx(N_,{error:n})]})}const nT=({errorsModel:n,sdkLanguage:e,revealInSource:i,wallTime:r,testRunMetadata:l})=>{const o=ti(),u=ec(async()=>{const g=o==null?void 0:o.attachments.find(y=>y.name==="error-context");if(g)return await fetch(bc(o,g)).then(y=>y.text())},[o],void 0),f=U.useCallback(async g=>{var v;const y=(v=g.stack)==null?void 0:v[0];if(!y)return;let m=o?await fetch(o.createRelativeUrl(`sha1/src@${await Bb(y.file)}.txt`)):void 0;if((!m||m.status===404)&&(m=await fetch(`file?path=${encodeURIComponent(y.file)}`)),m.status>=400)return;const w=await m.text();return iT({source:w,message:Xo(g.message).split(` +`)[0]||void 0,location:y,linesAbove:100,linesBelow:100})},[o]),h=ec(()=>Y_({testInfo:(o==null?void 0:o.title)??"",metadata:l,errorContext:u,errors:(o==null?void 0:o.errorDescriptors)??[],buildCodeFrame:f}),[u,l,o,f],void 0);return n.errors.size?S.jsxs("div",{className:"fill",style:{overflow:"auto"},children:[S.jsx("span",{style:{position:"absolute",right:"5px",top:"5px",zIndex:1},children:h&&S.jsx(W_,{prompt:h})}),[...n.errors.entries()].map(([g,y])=>{const m=`error-${r}-${g}`;return S.jsx(tT,{message:g,error:y,revealInSource:i,sdkLanguage:e},m)})]}):S.jsx(ms,{text:"No errors"})};function iT({source:n,message:e,location:i,linesAbove:r,linesBelow:l}){const o=n.split(` +`).slice(),u=Math.max(0,i.line-r-1),f=Math.min(o.length,i.line+l),h=o.slice(u,f),g=String(f).length,y=h.map((m,w)=>`${u+w+1===i.line?"> ":" "}${(u+w+1).toString().padEnd(g," ")} | ${m}`);return e&&y.splice(i.line-u,0,`${" ".repeat(g+2)} | ${" ".repeat(i.column-2)} ^ ${e}`),y.join(` +`)}const sT=yc;function rT(n,e){const{entries:i}=U.useMemo(()=>{if(!n)return{entries:[]};const l=[];function o(f){var y,m,w,v,E,x;const h=l[l.length-1];h&&((y=f.browserMessage)==null?void 0:y.bodyString)===((m=h.browserMessage)==null?void 0:m.bodyString)&&((w=f.browserMessage)==null?void 0:w.location)===((v=h.browserMessage)==null?void 0:v.location)&&f.browserError===h.browserError&&((E=f.nodeMessage)==null?void 0:E.html)===((x=h.nodeMessage)==null?void 0:x.html)&&f.isError===h.isError&&f.isWarning===h.isWarning&&f.timestamp-h.timestamp<1e3?h.repeat++:l.push({...f,repeat:1})}const u=[...n.events,...n.stdio].sort((f,h)=>{const g="time"in f?f.time:f.timestamp,y="time"in h?h.time:h.timestamp;return g-y});for(const f of u){if(f.type==="console"){const h=f.args&&f.args.length?lT(f.args):Ub(f.text),g=f.location.url,m=`${g?g.substring(g.lastIndexOf("/")+1):""}:${f.location.lineNumber}`;o({browserMessage:{body:h,bodyString:f.text,location:m},isError:f.messageType==="error",isWarning:f.messageType==="warning",timestamp:f.time})}if(f.type==="event"&&f.method==="pageError"&&o({browserError:f.params.error,isError:!0,isWarning:!1,timestamp:f.time}),f.type==="stderr"||f.type==="stdout"){let h="";f.text&&(h=nl(f.text.trim())||""),f.base64&&(h=nl(atob(f.base64).trim())||""),o({nodeMessage:{html:h},isError:f.type==="stderr",isWarning:!1,timestamp:f.timestamp})}}return{entries:l}},[n]);return{entries:U.useMemo(()=>e?i.filter(l=>l.timestamp>=e.minimum&&l.timestamp<=e.maximum):i,[i,e])}}const aT=({consoleModel:n,boundaries:e,onEntryHovered:i,onAccepted:r})=>n.entries.length?S.jsx("div",{className:"console-tab",children:S.jsx(sT,{name:"console",onAccepted:r,onHighlighted:l=>i==null?void 0:i(l?n.entries.indexOf(l):void 0),items:n.entries,isError:l=>l.isError,isWarning:l=>l.isWarning,render:l=>{const o=Et(l.timestamp-e.minimum),u=S.jsx("span",{className:"console-time",children:o}),f=l.isError?"status-error":l.isWarning?"status-warning":"status-none",h=l.browserMessage||l.browserError?S.jsx("span",{className:Fe("codicon","codicon-browser",f),title:"Browser message"}):S.jsx("span",{className:Fe("codicon","codicon-file",f),title:"Runner message"});let g,y,m,w;const{browserMessage:v,browserError:E,nodeMessage:x}=l;if(v&&(g=v.location,y=v.body),E){const{error:_,value:N}=E;_?(y=_.message,w=_.stack):y=String(N)}return x&&(m=x.html),S.jsxs("div",{className:"console-line",children:[u,h,g&&S.jsx("span",{className:"console-location",children:g}),l.repeat>1&&S.jsx("span",{className:"console-repeat",children:l.repeat}),y&&S.jsx("span",{className:"console-line-message",children:y}),m&&S.jsx("span",{className:"console-line-message",dangerouslySetInnerHTML:{__html:m}}),w&&S.jsx("div",{className:"console-stack",children:w})]})}})}):S.jsx(ms,{text:"No console entries"});function lT(n){if(n.length===1)return Ub(n[0].preview);const e=typeof n[0].value=="string"&&n[0].value.includes("%"),i=e?n[0].value:"",r=e?n.slice(1):n;let l=0;const o=/%([%sdifoOc])/g;let u;const f=[];let h=[];f.push(S.jsx("span",{children:h},f.length+1));let g=0;for(;(u=o.exec(i))!==null;){const y=i.substring(g,u.index);h.push(S.jsx("span",{children:y},h.length+1)),g=u.index+2;const m=u[0][1];if(m==="%")h.push(S.jsx("span",{children:"%"},h.length+1));else if(m==="s"||m==="o"||m==="O"||m==="d"||m==="i"||m==="f"){const w=r[l++],v={};typeof(w==null?void 0:w.value)!="string"&&(v.color="var(--vscode-debugTokenExpression-number)"),h.push(S.jsx("span",{style:v,children:(w==null?void 0:w.preview)||""},h.length+1))}else if(m==="c"){h=[];const w=r[l++],v=w?oT(w.preview):{};f.push(S.jsx("span",{style:v,children:h},f.length+1))}}for(gh[1].toUpperCase());e[f]=u}return e}catch{return{}}}function cT(n){return["background","border","color","font","line","margin","padding","text"].some(i=>n.startsWith(i))}const jh=({tabs:n,selectedTab:e,setSelectedTab:i,leftToolbar:r,rightToolbar:l,dataTestId:o,mode:u})=>{const f=U.useId();return e||(e=n[0].id),u||(u="default"),S.jsx("div",{className:"tabbed-pane","data-testid":o,children:S.jsxs("div",{className:"vbox",children:[S.jsxs(nd,{children:[r&&S.jsxs("div",{style:{flex:"none",display:"flex",margin:"0 4px",alignItems:"center"},children:[...r]}),u==="default"&&S.jsx("div",{style:{flex:"auto",display:"flex",height:"100%",overflow:"hidden"},role:"tablist",children:[...n.map(h=>S.jsx(Hb,{id:h.id,ariaControls:`${f}-${h.id}`,title:h.title,count:h.count,errorCount:h.errorCount,selected:e===h.id,onSelect:i},h.id))]}),u==="select"&&S.jsx("div",{style:{flex:"auto",display:"flex",height:"100%",overflow:"hidden"},role:"tablist",children:S.jsx("select",{style:{width:"100%",background:"none",cursor:"pointer"},value:e,onChange:h=>{i==null||i(n[h.currentTarget.selectedIndex].id)},children:n.map(h=>{let g="";return h.count&&(g=` (${h.count})`),h.errorCount&&(g=` (${h.errorCount})`),S.jsxs("option",{value:h.id,role:"tab","aria-controls":`${f}-${h.id}`,children:[h.title,g]},h.id)})})}),l&&S.jsxs("div",{style:{flex:"none",display:"flex",alignItems:"center"},children:[...l]})]}),n.map(h=>{const g="tab-content tab-"+h.id;if(h.component)return S.jsx("div",{id:`${f}-${h.id}`,role:"tabpanel","aria-label":h.title,className:g,style:{display:e===h.id?"inherit":"none"},children:h.component},h.id);if(e===h.id)return S.jsx("div",{id:`${f}-${h.id}`,role:"tabpanel","aria-label":h.title,className:g,children:h.render()},h.id)})]})})},Hb=({id:n,title:e,count:i,errorCount:r,selected:l,onSelect:o,ariaControls:u})=>S.jsxs("div",{className:Fe("tabbed-pane-tab",l&&"selected"),onClick:()=>o==null?void 0:o(n),role:"tab",title:e,"aria-controls":u,"aria-selected":l,children:[S.jsx("div",{className:"tabbed-pane-tab-label",children:e}),!!i&&S.jsx("div",{className:"tabbed-pane-tab-counter",children:i}),!!r&&S.jsx("div",{className:"tabbed-pane-tab-counter error",children:r})]});async function uT(n,e){const i=navigator.platform.includes("Win")?"win":"unix";let r=[];const l=new Set(["accept-encoding","host","method","path","scheme","version","authority","protocol"]);function o(w){return'^"'+w.replace(/\\/g,"\\\\").replace(/"/g,'\\"').replace(/[^a-zA-Z0-9\s_\-:=+~'\/.',?;()*`]/g,"^$&").replace(/%(?=[a-zA-Z0-9_])/g,"%^").replace(/[^ -~\r\n]/g," ").replace(/\r?\n|\r/g,`^ + +`)+'^"'}function u(w){function v(E){let _=E.charCodeAt(0).toString(16);for(;_.length<4;)_="0"+_;return"\\u"+_}return/[\0-\x1F\x7F-\x9F!]|\'/.test(w)?"$'"+w.replace(/\\/g,"\\\\").replace(/\'/g,"\\'").replace(/\n/g,"\\n").replace(/\r/g,"\\r").replace(/[\0-\x1F\x7F-\x9F!]/g,v)+"'":"'"+w+"'"}const f=i==="win"?o:u;r.push(f(e.request.url).replace(/[[{}\]]/g,"\\$&"));let h="GET";const g=[],y=await qb(n,e);y&&(g.push("--data-raw "+f(y)),l.add("content-length"),h="POST"),e.request.method!==h&&r.push("-X "+f(e.request.method));const m=e.request.headers;for(let w=0;w=3?i==="win"?` ^ + `:` \\ + `:" ")}async function fT(n,e,i=0){const r=new Set(["method","path","scheme","version","accept-charset","accept-encoding","access-control-request-headers","access-control-request-method","connection","content-length","cookie","cookie2","date","dnt","expect","host","keep-alive","origin","referer","te","trailer","transfer-encoding","upgrade","via","user-agent"]),l=new Set(["cookie","authorization"]),o=JSON.stringify(e.request.url),u=e.request.headers,f=u.reduce((x,_)=>{const N=_.name;return!r.has(N.toLowerCase())&&!N.includes(":")&&x.append(N,_.value),x},new Headers),h={};for(const x of f)h[x[0]]=x[1];const g=e.request.cookies.length||u.some(({name:x})=>l.has(x.toLowerCase()))?"include":"omit",y=u.find(({name:x})=>x.toLowerCase()==="referer"),m=y?y.value:void 0,w=await qb(n,e),v={headers:Object.keys(h).length?h:void 0,referrer:m,body:w,method:e.request.method,mode:"cors"};if(i===1){const x=u.find(N=>N.name.toLowerCase()==="cookie"),_={};delete v.mode,x&&(_.cookie=x.value),m&&(delete v.referrer,_.Referer=m),Object.keys(_).length&&(v.headers={...h,..._})}else v.credentials=g;const E=JSON.stringify(v,null,2);return`fetch(${o}, ${E});`}async function qb(n,e){var i,r;return n&&((i=e.request.postData)!=null&&i._sha1)?await fetch(n.createRelativeUrl(`sha1/${e.request.postData._sha1}`)).then(l=>l.text()):(r=e.request.postData)==null?void 0:r.text}class hT{generatePlaywrightRequestCall(e,i){let r=e.method.toLowerCase();const l=new URL(e.url),o=`${l.origin}${l.pathname}`,u={};["delete","get","head","post","put","patch"].includes(r)||(u.method=r,r="fetch"),l.searchParams.size&&(u.params=Object.fromEntries(l.searchParams.entries())),i&&(u.data=i),e.headers.length&&(u.headers=Object.fromEntries(e.headers.map(g=>[g.name,g.value])));const f=[`'${o}'`];return Object.keys(u).length>0&&f.push(this.prettyPrintObject(u)),`await page.request.${r}(${f.join(", ")});`}prettyPrintObject(e,i=2,r=0){if(e===null)return"null";if(e===void 0)return"undefined";if(typeof e!="object")return typeof e=="string"?this.stringLiteral(e):String(e);if(Array.isArray(e)){if(e.length===0)return"[]";const f=" ".repeat(r*i),h=" ".repeat((r+1)*i);return`[ +${e.map(y=>`${h}${this.prettyPrintObject(y,i,r+1)}`).join(`, +`)} +${f}]`}if(Object.keys(e).length===0)return"{}";const l=" ".repeat(r*i),o=" ".repeat((r+1)*i);return`{ +${Object.entries(e).map(([f,h])=>{const g=this.prettyPrintObject(h,i,r+1),y=/^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(f)?f:this.stringLiteral(f);return`${o}${y}: ${g}`}).join(`, +`)} +${l}}`}stringLiteral(e){return e=e.replace(/\\/g,"\\\\").replace(/'/g,"\\'"),e.includes(` +`)||e.includes("\r")||e.includes(" ")?"`"+e+"`":`'${e}'`}}class dT{generatePlaywrightRequestCall(e,i){const r=new URL(e.url),o=[`"${`${r.origin}${r.pathname}`}"`];let u=e.method.toLowerCase();["delete","get","head","post","put","patch"].includes(u)||(o.push(`method="${u}"`),u="fetch"),r.searchParams.size&&o.push(`params=${this.prettyPrintObject(Object.fromEntries(r.searchParams.entries()))}`),i&&o.push(`data=${this.prettyPrintObject(i)}`),e.headers.length&&o.push(`headers=${this.prettyPrintObject(Object.fromEntries(e.headers.map(h=>[h.name,h.value])))}`);const f=o.length===1?o[0]:` +${o.map(h=>this.indent(h,2)).join(`, +`)} +`;return`await page.request.${u}(${f})`}indent(e,i){return e.split(` +`).map(r=>" ".repeat(i)+r).join(` +`)}prettyPrintObject(e,i=2,r=0){if(e===null||e===void 0)return"None";if(typeof e!="object")return typeof e=="string"?this.stringLiteral(e):typeof e=="boolean"?e?"True":"False":String(e);if(Array.isArray(e)){if(e.length===0)return"[]";const f=" ".repeat(r*i),h=" ".repeat((r+1)*i);return`[ +${e.map(y=>`${h}${this.prettyPrintObject(y,i,r+1)}`).join(`, +`)} +${f}]`}if(Object.keys(e).length===0)return"{}";const l=" ".repeat(r*i),o=" ".repeat((r+1)*i);return`{ +${Object.entries(e).map(([f,h])=>{const g=this.prettyPrintObject(h,i,r+1);return`${o}${this.stringLiteral(f)}: ${g}`}).join(`, +`)} +${l}}`}stringLiteral(e){return JSON.stringify(e)}}class pT{generatePlaywrightRequestCall(e,i){const r=new URL(e.url),l=`${r.origin}${r.pathname}`,o={},u=[];let f=e.method.toLowerCase();["delete","get","head","post","put","patch"].includes(f)||(o.Method=f,f="fetch"),r.searchParams.size&&(o.Params=Object.fromEntries(r.searchParams.entries())),i&&(o.Data=i),e.headers.length&&(o.Headers=Object.fromEntries(e.headers.map(y=>[y.name,y.value])));const h=[`"${l}"`];return Object.keys(o).length>0&&h.push(this.prettyPrintObject(o)),`${u.join(` +`)}${u.length?` +`:""}await request.${this.toFunctionName(f)}(${h.join(", ")});`}toFunctionName(e){return e[0].toUpperCase()+e.slice(1)+"Async"}prettyPrintObject(e,i=2,r=0){if(e===null||e===void 0)return"null";if(typeof e!="object")return typeof e=="string"?this.stringLiteral(e):typeof e=="boolean"?e?"true":"false":String(e);if(Array.isArray(e)){if(e.length===0)return"new object[] {}";const f=" ".repeat(r*i),h=" ".repeat((r+1)*i);return`new object[] { +${e.map(y=>`${h}${this.prettyPrintObject(y,i,r+1)}`).join(`, +`)} +${f}}`}if(Object.keys(e).length===0)return"new {}";const l=" ".repeat(r*i),o=" ".repeat((r+1)*i);return`new() { +${Object.entries(e).map(([f,h])=>{const g=this.prettyPrintObject(h,i,r+1),y=r===0?f:`[${this.stringLiteral(f)}]`;return`${o}${y} = ${g}`}).join(`, +`)} +${l}}`}stringLiteral(e){return JSON.stringify(e)}}class gT{generatePlaywrightRequestCall(e,i){const r=new URL(e.url),l=[`"${r.origin}${r.pathname}"`],o=[];let u=e.method.toLowerCase();["delete","get","head","post","put","patch"].includes(u)||(o.push(`setMethod("${u}")`),u="fetch");for(const[f,h]of r.searchParams)o.push(`setQueryParam(${this.stringLiteral(f)}, ${this.stringLiteral(h)})`);i&&o.push(`setData(${this.stringLiteral(i)})`);for(const f of e.headers)o.push(`setHeader(${this.stringLiteral(f.name)}, ${this.stringLiteral(f.value)})`);return o.length>0&&l.push(`RequestOptions.create() + .${o.join(` + .`)} +`),`request.${u}(${l.join(", ")});`}stringLiteral(e){return JSON.stringify(e)}}function mT(n){if(n==="javascript")return new hT;if(n==="python")return new dT;if(n==="csharp")return new pT;if(n==="java")return new gT;throw new Error("Unsupported language: "+n)}const yT=({resource:n,sdkLanguage:e,startTimeOffset:i,onClose:r})=>{const[l,o]=U.useState("headers"),u=ti(),f=ec(async()=>{if(u&&n.request.postData){const h=n.request.headers.find(y=>y.name.toLowerCase()==="content-type"),g=h?h.value:"";if(n.request.postData._sha1){const y=await fetch(u.createRelativeUrl(`sha1/${n.request.postData._sha1}`));return{text:Lh(await y.text(),g),mimeType:g}}else return{text:Lh(n.request.postData.text,g),mimeType:g}}else return null},[n],null);return S.jsx(jh,{leftToolbar:[S.jsx(Ht,{icon:"close",title:"Close",onClick:r},"close")],rightToolbar:[S.jsx(bT,{requestBody:f,resource:n,sdkLanguage:e},"dropdown")],tabs:[{id:"headers",title:"Headers",render:()=>S.jsx(vT,{resource:n,startTimeOffset:i})},{id:"payload",title:"Payload",render:()=>S.jsx(ST,{resource:n,requestBody:f})},{id:"response",title:"Response",render:()=>S.jsx(wT,{resource:n})}],selectedTab:l,setSelectedTab:o})},bT=({resource:n,sdkLanguage:e,requestBody:i})=>{const r=ti(),l=S.jsxs(S.Fragment,{children:[S.jsx("span",{className:"codicon codicon-check",style:{marginRight:"5px"}})," Copied "]}),o=async()=>mT(e).generatePlaywrightRequestCall(n.request,i==null?void 0:i.text);return S.jsxs("div",{className:"copy-request-dropdown",children:[S.jsxs(Ht,{className:"copy-request-dropdown-toggle",children:[S.jsx("span",{className:"codicon codicon-copy",style:{marginRight:"5px"}}),"Copy request",S.jsx("span",{className:"codicon codicon-chevron-down",style:{marginLeft:"5px"}})]}),S.jsxs("div",{className:"copy-request-dropdown-menu",children:[S.jsx(Ko,{description:"Copy as cURL",copiedDescription:l,value:()=>uT(r,n)}),S.jsx(Ko,{description:"Copy as Fetch",copiedDescription:l,value:()=>fT(r,n)}),S.jsx(Ko,{description:"Copy as Playwright",copiedDescription:l,value:o})]})]})},Xa=({title:n,data:e,showCount:i,children:r,className:l})=>{const[o,u]=on(`trace-viewer-network-details-${n.replaceAll(" ","-")}`,!0);return S.jsxs(Rb,{expanded:o,setExpanded:u,expandOnTitleClick:!0,title:S.jsxs("span",{className:"network-request-details-header",children:[n,i&&S.jsxs("span",{className:"network-request-details-header-count",children:[" × ",(e==null?void 0:e.length)??0]})]}),className:l,children:[e&&S.jsx("table",{className:"network-request-details-table",children:S.jsx("tbody",{children:e.map(({name:f,value:h},g)=>h!==null&&S.jsxs("tr",{children:[S.jsx("td",{children:f}),S.jsx("td",{children:h})]},g))})}),r]})},vT=({resource:n,startTimeOffset:e})=>{const i=U.useMemo(()=>Object.entries({URL:n.request.url,Method:n.request.method,"Status Code":n.response.status!==-1&&S.jsxs("span",{className:_T(n.response.status),children:[" ",n.response.status," ",n.response.statusText]}),Start:Et(e),Duration:Et(n.time)}).map(([r,l])=>({name:r,value:l})),[n,e]);return S.jsxs("div",{className:"vbox network-request-details-tab",children:[S.jsx(Xa,{title:"General",data:i}),S.jsx(Xa,{title:"Request Headers",showCount:!0,data:n.request.headers}),S.jsx(Xa,{title:"Response Headers",showCount:!0,data:n.response.headers})]})},ST=({resource:n,requestBody:e})=>S.jsxs("div",{className:"vbox network-request-details-tab",children:[n.request.queryString.length===0&&!e&&S.jsx("em",{className:"network-request-no-payload",children:"No payload for this request."}),n.request.queryString.length>0&&S.jsx(Xa,{title:"Query String Parameters",showCount:!0,data:n.request.queryString}),e&&S.jsx(Xa,{title:"Request Body",className:"network-request-request-body",children:S.jsx(xr,{text:e.text,mimeType:e.mimeType,readOnly:!0,lineNumbers:!0})})]}),wT=({resource:n})=>{const e=ti(),[i,r]=U.useState(null);return U.useEffect(()=>{(async()=>{if(e&&n.response.content._sha1){const o=n.response.content.mimeType.includes("image"),u=n.response.content.mimeType.includes("font"),f=await fetch(e.createRelativeUrl(`sha1/${n.response.content._sha1}`));if(o){const h=await f.blob(),g=new FileReader,y=new Promise(m=>g.onload=m);g.readAsDataURL(h),r({dataUrl:(await y).target.result})}else if(u){const h=await f.arrayBuffer();r({font:h})}else{const h=Lh(await f.text(),n.response.content.mimeType);r({text:h,mimeType:n.response.content.mimeType})}}else r(null)})()},[n,e]),S.jsxs("div",{className:"vbox network-request-details-tab",children:[!n.response.content._sha1&&S.jsx("div",{children:"Response body is not available for this request."}),i&&i.font&&S.jsx(xT,{font:i.font}),i&&i.dataUrl&&S.jsx("div",{children:S.jsx("img",{draggable:"false",src:i.dataUrl})}),i&&i.text&&S.jsx(xr,{text:i.text,mimeType:i.mimeType,readOnly:!0,lineNumbers:!0})]})},xT=({font:n})=>{const[e,i]=U.useState(!1);return U.useEffect(()=>{let r;try{r=new FontFace("font-preview",n),r.status==="loaded"&&document.fonts.add(r),r.status==="error"&&i(!0)}catch{i(!0)}return()=>{document.fonts.delete(r)}},[n]),e?S.jsx("div",{className:"network-font-preview-error",children:"Could not load font preview"}):S.jsxs("div",{className:"network-font-preview",children:["ABCDEFGHIJKLM",S.jsx("br",{}),"NOPQRSTUVWXYZ",S.jsx("br",{}),"abcdefghijklm",S.jsx("br",{}),"nopqrstuvwxyz",S.jsx("br",{}),"1234567890"]})};function _T(n){return n<300||n===304?"green-circle":n<400?"yellow-circle":"red-circle"}function Lh(n,e){if(n===null)return"Loading...";const i=n;if(i==="")return"";if(H_(e))try{return JSON.stringify(JSON.parse(i),null,2)}catch{return i}return e.includes("application/x-www-form-urlencoded")?decodeURIComponent(i):i}function TT(n){const[e,i]=U.useState([]);U.useEffect(()=>{const o=[];for(let u=0;u{var u,f;(f=n.setSorting)==null||f.call(n,{by:o,negate:((u=n.sorting)==null?void 0:u.by)===o?!n.sorting.negate:!1})},[n]);return S.jsxs("div",{className:`grid-view ${n.name}-grid-view`,children:[S.jsx(Lb,{orientation:"horizontal",offsets:e,setOffsets:r,resizerColor:"var(--vscode-panel-border)",resizerWidth:1,minColumnWidth:25}),S.jsxs("div",{className:"vbox",children:[S.jsx("div",{className:"grid-view-header",children:n.columns.map((o,u)=>S.jsxs("div",{className:"grid-view-header-cell "+ET(o,n.sorting),style:{width:un.setSorting&&l(o),children:[S.jsx("span",{className:"grid-view-header-cell-title",children:n.columnTitle(o)}),S.jsx("span",{className:"codicon codicon-triangle-up"}),S.jsx("span",{className:"codicon codicon-triangle-down"})]},n.columnTitle(o)))}),S.jsx(yc,{name:n.name,items:n.items,ariaLabel:n.ariaLabel,id:n.id,render:(o,u)=>S.jsx(S.Fragment,{children:n.columns.map((f,h)=>{const{body:g,title:y}=n.render(o,f,u);return S.jsx("div",{className:`grid-view-cell grid-view-column-${String(f)}`,title:y,style:{width:hS.jsxs("div",{className:"network-filters",children:[S.jsx("input",{type:"search",placeholder:"Filter network",spellCheck:!1,value:n.searchValue,onChange:i=>e({...n,searchValue:i.target.value})}),S.jsxs("div",{className:"network-filters-resource-types",role:"tablist","aria-multiselectable":"true",children:[S.jsx("div",{title:"All",onClick:()=>e({...n,resourceTypes:new Set}),className:`network-filters-resource-type ${n.resourceTypes.size===0?"selected":""}`,children:"All"}),AT.map(i=>S.jsx("div",{title:i,onClick:r=>{let l;r.ctrlKey||r.metaKey?l=n.resourceTypes.symmetricDifference(new Set([i])):l=new Set([i]),e({...n,resourceTypes:l})},className:`network-filters-resource-type ${n.resourceTypes.has(i)?"selected":""}`,role:"tab","aria-selected":n.resourceTypes.has(i),children:i},i))]})]}),kT=TT;function MT(n,e){const i=U.useMemo(()=>((n==null?void 0:n.resources)||[]).filter(u=>e?!!u._monotonicTime&&u._monotonicTime>=e.minimum&&u._monotonicTime<=e.maximum:!0),[n,e]),r=U.useMemo(()=>new zT(n),[n]);return{resources:i,contextIdMap:r}}const OT=({boundaries:n,networkModel:e,onResourceHovered:i,sdkLanguage:r})=>{const[l,o]=U.useState(void 0),[u,f]=U.useState(void 0),[h,g]=U.useState(NT),y=U.useMemo(()=>u&&e.resources.includes(u.resource)?u:void 0,[u,e.resources]),{renderedEntries:m}=U.useMemo(()=>{const _=e.resources.map((N,C)=>BT(N,n,e.contextIdMap,C)).filter(IT(h));return l&&HT(_,l),{renderedEntries:_}},[e.resources,e.contextIdMap,h,l,n]),[w,v]=U.useState(()=>new Map($b().map(_=>[_,LT(_)]))),E=U.useCallback(_=>{g(_),f(void 0)},[]);if(!e.resources.length)return S.jsx(ms,{text:"No network calls"});const x=S.jsx(kT,{name:"network",ariaLabel:"Network requests",items:m,selectedItem:y,onSelected:_=>f(_),onHighlighted:_=>i==null?void 0:i(_==null?void 0:_.ordinal),columns:RT(!!y,m),columnTitle:jT,columnWidths:w,setColumnWidths:v,isError:_=>_.status.code>=400||_.status.code===-1,isInfo:_=>!!_.route,render:(_,N)=>DT(_,N),sorting:l,setSorting:o});return S.jsxs(S.Fragment,{children:[S.jsx(CT,{filterState:h,onFilterStateChange:E}),!y&&x,y&&S.jsx(nc,{sidebarSize:w.get("name"),sidebarIsFirst:!0,orientation:"horizontal",settingName:"networkResourceDetails",main:S.jsx(yT,{resource:y.resource,sdkLanguage:r,startTimeOffset:y.start,onClose:()=>f(void 0)}),sidebar:x})]})},jT=n=>n==="contextId"?"Source":n==="name"?"Name":n==="method"?"Method":n==="status"?"Status":n==="contentType"?"Content Type":n==="duration"?"Duration":n==="size"?"Size":n==="start"?"Start":n==="route"?"Route":"",LT=n=>n==="name"?200:n==="method"||n==="status"?60:n==="contentType"?200:n==="contextId"?60:100;function RT(n,e){if(n){const r=["name"];return h0(e)&&r.unshift("contextId"),r}let i=$b();return h0(e)||(i=i.filter(r=>r!=="contextId")),i}function $b(){return["contextId","name","method","status","contentType","duration","size","start","route"]}const DT=(n,e)=>e==="contextId"?{body:n.contextId,title:n.name.url}:e==="name"?{body:n.name.name,title:n.name.url}:e==="method"?{body:n.method}:e==="status"?{body:n.status.code>0?n.status.code:"",title:n.status.text}:e==="contentType"?{body:n.contentType}:e==="duration"?{body:Et(n.duration)}:e==="size"?{body:fx(n.size)}:e==="start"?{body:Et(n.start)}:e==="route"?{body:n.route}:{body:""};class zT{constructor(e){Ma(this,"_pagerefToShortId",new Map);Ma(this,"_contextToId",new Map);Ma(this,"_lastPageId",0);Ma(this,"_lastApiRequestContextId",0)}contextId(e){return e.pageref?this._pageId(e.pageref):e._apiRequest?this._apiRequestContextId(e):""}_pageId(e){let i=this._pagerefToShortId.get(e);return i||(++this._lastPageId,i="page#"+this._lastPageId,this._pagerefToShortId.set(e,i)),i}_apiRequestContextId(e){const i=rb(e);if(!i)return"";let r=this._contextToId.get(i);return r||(++this._lastApiRequestContextId,r="api#"+this._lastApiRequestContextId,this._contextToId.set(i,r)),r}}function h0(n){const e=new Set;for(const i of n)if(e.add(i.contextId),e.size>1)return!0;return!1}const BT=(n,e,i,r)=>{const l=UT(n);let o;try{const h=new URL(n.request.url);o=h.pathname.substring(h.pathname.lastIndexOf("/")+1),o||(o=h.host),h.search&&(o+=h.search)}catch{o=n.request.url}let u=n.response.content.mimeType;const f=u.match(/^(.*);\s*charset=.*$/);return f&&(u=f[1]),{ordinal:r,name:{name:o,url:n.request.url},method:n.request.method,status:{code:n.response.status,text:n.response.statusText},contentType:u,duration:n.time,size:n.response._transferSize>0?n.response._transferSize:n.response.bodySize,start:n._monotonicTime-e.minimum,route:l,resource:n,contextId:i.contextId(n)}};function UT(n){return n._wasAborted?"aborted":n._wasContinued?"continued":n._wasFulfilled?"fulfilled":n._apiRequest?"api":""}function HT(n,e){const i=qT(e==null?void 0:e.by);i&&n.sort(i),e.negate&&n.reverse()}function qT(n){if(n==="start")return(e,i)=>e.start-i.start;if(n==="duration")return(e,i)=>e.duration-i.duration;if(n==="status")return(e,i)=>e.status.code-i.status.code;if(n==="method")return(e,i)=>{const r=e.method,l=i.method;return r.localeCompare(l)};if(n==="size")return(e,i)=>e.size-i.size;if(n==="contentType")return(e,i)=>e.contentType.localeCompare(i.contentType);if(n==="name")return(e,i)=>e.name.name.localeCompare(i.name.name);if(n==="route")return(e,i)=>e.route.localeCompare(i.route);if(n==="contextId")return(e,i)=>e.contextId.localeCompare(i.contextId)}const $T={Fetch:n=>n==="application/json",HTML:n=>n==="text/html",CSS:n=>n==="text/css",JS:n=>n.includes("javascript"),Font:n=>n.includes("font"),Image:n=>n.includes("image")};function IT({searchValue:n,resourceTypes:e}){return i=>(e.size===0||Array.from(e).some(l=>$T[l](i.contentType)))&&i.name.url.toLowerCase().includes(n.toLowerCase())}function VT(n,e){if(n.role!==e.role||n.name!==e.name||!GT(n,e)||lc(n)!==lc(e))return!1;const i=Object.keys(n.props),r=Object.keys(e.props);return i.length===r.length&&i.every(l=>n.props[l]===e.props[l])}function lc(n){return n.box.cursor==="pointer"}function GT(n,e){return n.active===e.active&&n.checked===e.checked&&n.disabled===e.disabled&&n.expanded===e.expanded&&n.selected===e.selected&&n.level===e.level&&n.pressed===e.pressed}function id(n,e,i={}){var w;const r=new n.LineCounter,l={keepSourceTokens:!0,lineCounter:r,...i},o=n.parseDocument(e,l),u=[],f=v=>[r.linePos(v[0]),r.linePos(v[1])],h=v=>{u.push({message:v.message,range:[r.linePos(v.pos[0]),r.linePos(v.pos[1])]})},g=(v,E)=>{for(const x of E.items){if(x instanceof n.Scalar&&typeof x.value=="string"){const C=oc.parse(x,l,u);C&&(v.children=v.children||[],v.children.push(C));continue}if(x instanceof n.YAMLMap){y(v,x);continue}u.push({message:"Sequence items should be strings or maps",range:f(x.range||E.range)})}},y=(v,E)=>{for(const x of E.items){if(v.children=v.children||[],!(x.key instanceof n.Scalar&&typeof x.key.value=="string")){u.push({message:"Only string keys are supported",range:f(x.key.range||E.range)});continue}const N=x.key,C=x.value;if(N.value==="text"){if(!(C instanceof n.Scalar&&typeof C.value=="string")){u.push({message:"Text value should be a string",range:f(x.value.range||E.range)});continue}v.children.push({kind:"text",text:oh(C.value)});continue}if(N.value==="/children"){if(!(C instanceof n.Scalar&&typeof C.value=="string")||C.value!=="contain"&&C.value!=="equal"&&C.value!=="deep-equal"){u.push({message:'Strict value should be "contain", "equal" or "deep-equal"',range:f(x.value.range||E.range)});continue}v.containerMode=C.value;continue}if(N.value.startsWith("/")){if(!(C instanceof n.Scalar&&typeof C.value=="string")){u.push({message:"Property value should be a string",range:f(x.value.range||E.range)});continue}v.props=v.props??{},v.props[N.value.slice(1)]=oh(C.value);continue}const $=oc.parse(N,l,u);if(!$)continue;if(C instanceof n.Scalar){const K=typeof C.value;if(K!=="string"&&K!=="number"&&K!=="boolean"){u.push({message:"Node value should be a string or a sequence",range:f(x.value.range||E.range)});continue}v.children.push({...$,children:[{kind:"text",text:oh(String(C.value))}]});continue}if(C instanceof n.YAMLSeq){v.children.push($),g($,C);continue}u.push({message:"Map values should be strings or sequences",range:f(x.value.range||E.range)})}},m={kind:"role",role:"fragment"};return o.errors.forEach(h),u.length?{errors:u,fragment:m}:(o.contents instanceof n.YAMLSeq||u.push({message:'Aria snapshot must be a YAML sequence, elements starting with " -"',range:o.contents?f(o.contents.range):[{line:0,col:0},{line:0,col:0}]}),u.length?{errors:u,fragment:m}:(g(m,o.contents),u.length?{errors:u,fragment:KT}:((w=m.children)==null?void 0:w.length)===1&&(!m.containerMode||m.containerMode==="contain")?{fragment:m.children[0],errors:[]}:{fragment:m,errors:[]}))}const KT={kind:"role",role:"fragment"};function Ib(n){return n.replace(/[\u200b\u00ad]/g,"").replace(/[\r\n\s\t]+/g," ").trim()}function oh(n){return{raw:n,normalized:Ib(n)}}class oc{static parse(e,i,r){try{return new oc(e.value)._parse()}catch(l){if(l instanceof d0){const o=i.prettyErrors===!1?l.message:l.message+`: + +`+e.value+` +`+" ".repeat(l.pos)+`^ +`;return r.push({message:o,range:[i.lineCounter.linePos(e.range[0]),i.lineCounter.linePos(e.range[0]+l.pos)]}),null}throw l}}constructor(e){this._input=e,this._pos=0,this._length=e.length}_peek(){return this._input[this._pos]||""}_next(){return this._pos=this._length}_isWhitespace(){return!this._eof()&&/\s/.test(this._peek())}_skipWhitespace(){for(;this._isWhitespace();)this._pos++}_readIdentifier(e){this._eof()&&this._throwError(`Unexpected end of input when expecting ${e}`);const i=this._pos;for(;!this._eof()&&/[a-zA-Z]/.test(this._peek());)this._pos++;return this._input.slice(i,this._pos)}_readString(){let e="",i=!1;for(;!this._eof();){const r=this._next();if(i)e+=r,i=!1;else if(r==="\\")i=!0;else{if(r==='"')return e;e+=r}}this._throwError("Unterminated string")}_throwError(e,i=0){throw new d0(e,i||this._pos)}_readRegex(){let e="",i=!1,r=!1;for(;!this._eof();){const l=this._next();if(i)e+=l,i=!1;else if(l==="\\")i=!0,e+=l;else{if(l==="/"&&!r)return{pattern:e};l==="["?(r=!0,e+=l):l==="]"&&r?(e+=l,r=!1):e+=l}}this._throwError("Unterminated regex")}_readStringOrRegex(){const e=this._peek();return e==='"'?(this._next(),Ib(this._readString())):e==="/"?(this._next(),this._readRegex()):null}_readAttributes(e){let i=this._pos;for(;this._skipWhitespace(),this._peek()==="[";){this._next(),this._skipWhitespace(),i=this._pos;const r=this._readIdentifier("attribute");this._skipWhitespace();let l="";if(this._peek()==="=")for(this._next(),this._skipWhitespace(),i=this._pos;this._peek()!=="]"&&!this._isWhitespace()&&!this._eof();)l+=this._next();this._skipWhitespace(),this._peek()!=="]"&&this._throwError("Expected ]"),this._next(),this._applyAttribute(e,r,l||"true",i)}}_parse(){this._skipWhitespace();const e=this._readIdentifier("role");this._skipWhitespace();const i=this._readStringOrRegex()||"",r={kind:"role",role:e,name:i};return this._readAttributes(r),this._skipWhitespace(),this._eof()||this._throwError("Unexpected input"),r}_applyAttribute(e,i,r,l){if(i==="checked"){this._assert(r==="true"||r==="false"||r==="mixed",'Value of "checked" attribute must be a boolean or "mixed"',l),e.checked=r==="true"?!0:r==="false"?!1:"mixed";return}if(i==="disabled"){this._assert(r==="true"||r==="false",'Value of "disabled" attribute must be a boolean',l),e.disabled=r==="true";return}if(i==="expanded"){this._assert(r==="true"||r==="false",'Value of "expanded" attribute must be a boolean',l),e.expanded=r==="true";return}if(i==="active"){this._assert(r==="true"||r==="false",'Value of "active" attribute must be a boolean',l),e.active=r==="true";return}if(i==="level"){this._assert(!isNaN(Number(r)),'Value of "level" attribute must be a number',l),e.level=Number(r);return}if(i==="pressed"){this._assert(r==="true"||r==="false"||r==="mixed",'Value of "pressed" attribute must be a boolean or "mixed"',l),e.pressed=r==="true"?!0:r==="false"?!1:"mixed";return}if(i==="selected"){this._assert(r==="true"||r==="false",'Value of "selected" attribute must be a boolean',l),e.selected=r==="true";return}this._assert(!1,`Unsupported attribute [${i}]`,l)}_assert(e,i,r){e||this._throwError(i||"Assertion error",r)}}class d0 extends Error{constructor(e,i){super(e),this.pos=i}}function YT(n,e){var u,f;function i(h,g,y){let m=1,w=y+m;for(const v of h.children||[])typeof v=="string"?(m++,w++):(m+=i(v,g,w),w+=m);if(!["none","presentation","fragment","iframe","generic"].includes(h.role)&&h.name){let v=g.get(h.role);v||(v=new Map,g.set(h.role,v));const E=v.get(h.name),x=m*100-y;(!E||E.sizeAndPositiong.sizeAndPosition-h.sizeAndPosition),(f=o[0])==null?void 0:f.node}function XT(n){return Vb(n)?"'"+n.replace(/'/g,"''")+"'":n}function ch(n){return Vb(n)?'"'+n.replace(/[\\"\x00-\x1f\x7f-\x9f]/g,e=>{switch(e){case"\\":return"\\\\";case'"':return'\\"';case"\b":return"\\b";case"\f":return"\\f";case` +`:return"\\n";case"\r":return"\\r";case" ":return"\\t";default:return"\\x"+e.charCodeAt(0).toString(16).padStart(2,"0")}})+'"':n}function Vb(n){return!!(n.length===0||/^\s|\s$/.test(n)||/[\x00-\x08\x0b\x0c\x0e-\x1f\x7f-\x9f]/.test(n)||/^-/.test(n)||/[\n:](\s|$)/.test(n)||/\s#/.test(n)||/[\n\r]/.test(n)||/^[&*\],?!>|@"'#%]/.test(n)||/[{}`]/.test(n)||/^\[/.test(n)||!isNaN(Number(n))||["y","n","yes","no","true","false","on","off","null"].includes(n.toLowerCase()))}let Gb={};function FT(n){Gb=n}function il(n,e){for(;e;){if(n.contains(e))return!0;e=Yb(e)}return!1}function bt(n){if(n.parentElement)return n.parentElement;if(n.parentNode&&n.parentNode.nodeType===11&&n.parentNode.host)return n.parentNode.host}function Kb(n){let e=n;for(;e.parentNode;)e=e.parentNode;if(e.nodeType===11||e.nodeType===9)return e}function Yb(n){for(;n.parentElement;)n=n.parentElement;return bt(n)}function $a(n,e,i){for(;n;){const r=n.closest(e);if(i&&r!==i&&(r!=null&&r.contains(i)))return;if(r)return r;n=Yb(n)}}function zi(n,e){const i=e==="::before"?rd:e==="::after"?ad:sd;if(i&&i.has(n))return i.get(n);const r=n.ownerDocument&&n.ownerDocument.defaultView?n.ownerDocument.defaultView.getComputedStyle(n,e):void 0;return i==null||i.set(n,r),r}function Xb(n,e){if(e=e??zi(n),!e)return!0;if(Element.prototype.checkVisibility&&Gb.browserNameForWorkarounds!=="webkit"){if(!n.checkVisibility())return!1}else{const i=n.closest("details,summary");if(i!==n&&(i==null?void 0:i.nodeName)==="DETAILS"&&!i.open)return!1}return e.visibility==="visible"}function cc(n){const e=zi(n);if(!e)return{visible:!0,inline:!1};const i=e.cursor;if(e.display==="contents"){for(let l=n.firstChild;l;l=l.nextSibling){if(l.nodeType===1&&ji(l))return{visible:!0,inline:!1,cursor:i};if(l.nodeType===3&&Fb(l))return{visible:!0,inline:!0,cursor:i}}return{visible:!1,inline:!1,cursor:i}}if(!Xb(n,e))return{cursor:i,visible:!1,inline:!1};const r=n.getBoundingClientRect();return{cursor:i,visible:r.width>0&&r.height>0,inline:e.display==="inline"}}function ji(n){return cc(n).visible}function Fb(n){const e=n.ownerDocument.createRange();e.selectNode(n);const i=e.getBoundingClientRect();return i.width>0&&i.height>0}function Xe(n){const e=n.tagName;return typeof e=="string"?e.toUpperCase():n instanceof HTMLFormElement?"FORM":n.tagName.toUpperCase()}let sd,rd,ad,Qb=0;function ld(){++Qb,sd??(sd=new Map),rd??(rd=new Map),ad??(ad=new Map)}function od(){--Qb||(sd=void 0,rd=void 0,ad=void 0)}function p0(n){return n.hasAttribute("aria-label")||n.hasAttribute("aria-labelledby")}const g0="article:not([role]), aside:not([role]), main:not([role]), nav:not([role]), section:not([role]), [role=article], [role=complementary], [role=main], [role=navigation], [role=region]",QT=[["aria-atomic",void 0],["aria-busy",void 0],["aria-controls",void 0],["aria-current",void 0],["aria-describedby",void 0],["aria-details",void 0],["aria-dropeffect",void 0],["aria-flowto",void 0],["aria-grabbed",void 0],["aria-hidden",void 0],["aria-keyshortcuts",void 0],["aria-label",["caption","code","deletion","emphasis","generic","insertion","paragraph","presentation","strong","subscript","superscript"]],["aria-labelledby",["caption","code","deletion","emphasis","generic","insertion","paragraph","presentation","strong","subscript","superscript"]],["aria-live",void 0],["aria-owns",void 0],["aria-relevant",void 0],["aria-roledescription",["generic"]]];function Jb(n,e){return QT.some(([i,r])=>!(r!=null&&r.includes(e||""))&&n.hasAttribute(i))}function Pb(n){return!Number.isNaN(Number(String(n.getAttribute("tabindex"))))}function JT(n){return!cv(n)&&(PT(n)||Pb(n))}function PT(n){const e=Xe(n);return["BUTTON","DETAILS","SELECT","TEXTAREA"].includes(e)?!0:e==="A"||e==="AREA"?n.hasAttribute("href"):e==="INPUT"?!n.hidden:!1}const uh={A:n=>n.hasAttribute("href")?"link":null,AREA:n=>n.hasAttribute("href")?"link":null,ARTICLE:()=>"article",ASIDE:()=>"complementary",BLOCKQUOTE:()=>"blockquote",BUTTON:()=>"button",CAPTION:()=>"caption",CODE:()=>"code",DATALIST:()=>"listbox",DD:()=>"definition",DEL:()=>"deletion",DETAILS:()=>"group",DFN:()=>"term",DIALOG:()=>"dialog",DT:()=>"term",EM:()=>"emphasis",FIELDSET:()=>"group",FIGURE:()=>"figure",FOOTER:n=>$a(n,g0)?null:"contentinfo",FORM:n=>p0(n)?"form":null,H1:()=>"heading",H2:()=>"heading",H3:()=>"heading",H4:()=>"heading",H5:()=>"heading",H6:()=>"heading",HEADER:n=>$a(n,g0)?null:"banner",HR:()=>"separator",HTML:()=>"document",IMG:n=>n.getAttribute("alt")===""&&!n.getAttribute("title")&&!Jb(n)&&!Pb(n)?"presentation":"img",INPUT:n=>{const e=n.type.toLowerCase();if(e==="search")return n.hasAttribute("list")?"combobox":"searchbox";if(["email","tel","text","url",""].includes(e)){const i=Nr(n,n.getAttribute("list"))[0];return i&&Xe(i)==="DATALIST"?"combobox":"textbox"}return e==="hidden"?null:e==="file"?"button":dE[e]||"textbox"},INS:()=>"insertion",LI:()=>"listitem",MAIN:()=>"main",MARK:()=>"mark",MATH:()=>"math",MENU:()=>"list",METER:()=>"meter",NAV:()=>"navigation",OL:()=>"list",OPTGROUP:()=>"group",OPTION:()=>"option",OUTPUT:()=>"status",P:()=>"paragraph",PROGRESS:()=>"progressbar",SEARCH:()=>"search",SECTION:n=>p0(n)?"region":null,SELECT:n=>n.hasAttribute("multiple")||n.size>1?"listbox":"combobox",STRONG:()=>"strong",SUB:()=>"subscript",SUP:()=>"superscript",SVG:()=>"img",TABLE:()=>"table",TBODY:()=>"rowgroup",TD:n=>{const e=$a(n,"table"),i=e?cd(e):"";return i==="grid"||i==="treegrid"?"gridcell":"cell"},TEXTAREA:()=>"textbox",TFOOT:()=>"rowgroup",TH:n=>{const e=n.getAttribute("scope");if(e==="col"||e==="colgroup")return"columnheader";if(e==="row"||e==="rowgroup")return"rowheader";const i=n.nextElementSibling,r=n.previousElementSibling,l=n.parentElement&&Xe(n.parentElement)==="TR"?n.parentElement:void 0;if(!i&&!r){if(l){const o=$a(l,"table");if(o&&o.rows.length<=1)return null}return"columnheader"}return m0(i)&&m0(r)?"columnheader":y0(i)||y0(r)?"rowheader":"columnheader"},THEAD:()=>"rowgroup",TIME:()=>"time",TR:()=>"row",UL:()=>"list"};function m0(n){return!!n&&Xe(n)==="TH"}function y0(n){var e;return!n||Xe(n)!=="TD"?!1:!!((e=n.textContent)!=null&&e.trim()||n.children.length>0)}const ZT={DD:["DL","DIV"],DIV:["DL"],DT:["DL","DIV"],LI:["OL","UL"],TBODY:["TABLE"],TD:["TR"],TFOOT:["TABLE"],TH:["TR"],THEAD:["TABLE"],TR:["THEAD","TBODY","TFOOT","TABLE"]};function b0(n){var r;const e=((r=uh[Xe(n)])==null?void 0:r.call(uh,n))||"";if(!e)return null;let i=n;for(;i;){const l=bt(i),o=ZT[Xe(i)];if(!o||!l||!o.includes(Xe(l)))break;const u=cd(l);if((u==="none"||u==="presentation")&&!Zb(l,u))return u;i=l}return e}const WT=["alert","alertdialog","application","article","banner","blockquote","button","caption","cell","checkbox","code","columnheader","combobox","complementary","contentinfo","definition","deletion","dialog","directory","document","emphasis","feed","figure","form","generic","grid","gridcell","group","heading","img","insertion","link","list","listbox","listitem","log","main","mark","marquee","math","meter","menu","menubar","menuitem","menuitemcheckbox","menuitemradio","navigation","none","note","option","paragraph","presentation","progressbar","radio","radiogroup","region","row","rowgroup","rowheader","scrollbar","search","searchbox","separator","slider","spinbutton","status","strong","subscript","superscript","switch","tab","table","tablist","tabpanel","term","textbox","time","timer","toolbar","tooltip","tree","treegrid","treeitem"];function cd(n){return(n.getAttribute("role")||"").split(" ").map(i=>i.trim()).find(i=>WT.includes(i))||null}function Zb(n,e){return Jb(n,e)||JT(n)}function mt(n){const e=cd(n);if(!e)return b0(n);if(e==="none"||e==="presentation"){const i=b0(n);if(Zb(n,i))return i}return e}function Wb(n){return n===null?void 0:n.toLowerCase()==="true"}function ev(n){return["STYLE","SCRIPT","NOSCRIPT","TEMPLATE"].includes(Xe(n))}function ln(n){if(ev(n))return!0;const e=zi(n),i=n.nodeName==="SLOT";if((e==null?void 0:e.display)==="contents"&&!i){for(let l=n.firstChild;l;l=l.nextSibling)if(l.nodeType===1&&!ln(l)||l.nodeType===3&&Fb(l))return!1;return!0}return!(n.nodeName==="OPTION"&&!!n.closest("select"))&&!i&&!Xb(n,e)?!0:tv(n)}function tv(n){let e=Mi==null?void 0:Mi.get(n);if(e===void 0){if(e=!1,n.parentElement&&n.parentElement.shadowRoot&&!n.assignedSlot&&(e=!0),!e){const i=zi(n);e=!i||i.display==="none"||Wb(n.getAttribute("aria-hidden"))===!0}if(!e){const i=bt(n);i&&(e=tv(i))}Mi==null||Mi.set(n,e)}return e}function Nr(n,e){if(!e)return[];const i=Kb(n);if(!i)return[];try{const r=e.split(" ").filter(o=>!!o),l=[];for(const o of r){const u=i.querySelector("#"+CSS.escape(o));u&&!l.includes(u)&&l.push(u)}return l}catch{return[]}}function Pn(n){return n.trim()}function Fa(n){return n.split(" ").map(e=>e.replace(/\r\n/g,` +`).replace(/[\u200b\u00ad]/g,"").replace(/\s\s*/g," ")).join(" ").trim()}function v0(n,e){const i=[...n.querySelectorAll(e)];for(const r of Nr(n,n.getAttribute("aria-owns")))r.matches(e)&&i.push(r),i.push(...r.querySelectorAll(e));return i}function Qa(n,e){const i=e==="::before"?wd:e==="::after"?xd:Sd;if(i!=null&&i.has(n))return i==null?void 0:i.get(n);const r=zi(n,e);let l;if(r){const o=r.content;o&&o!=="none"&&o!=="normal"&&r.display!=="none"&&r.visibility!=="hidden"&&(l=eE(n,o,!!e))}return e&&l!==void 0&&((r==null?void 0:r.display)||"inline")!=="inline"&&(l=" "+l+" "),i&&i.set(n,l),l}function eE(n,e,i){if(!(!e||e==="none"||e==="normal"))try{let r=ab(e).filter(f=>!(f instanceof ic));const l=r.findIndex(f=>f instanceof dt&&f.value==="/");if(l!==-1)r=r.slice(l+1);else if(!i)return;const o=[];let u=0;for(;uyn(o,{includeHidden:e,visitedElements:new Set,embeddedInDescribedBy:{element:o,hidden:ln(o)}})).join(" "))}else n.hasAttribute("aria-description")?r=Fa(n.getAttribute("aria-description")||""):r=Fa(n.getAttribute("title")||"");i==null||i.set(n,r)}return r}function nE(n){const e=n.getAttribute("aria-invalid");return!e||e.trim()===""||e.toLocaleLowerCase()==="false"?"false":e==="true"||e==="grammar"||e==="spelling"?e:"true"}function iE(n){if("validity"in n){const e=n.validity;return(e==null?void 0:e.valid)===!1}return!1}function sE(n){const e=dr;let i=dr==null?void 0:dr.get(n);if(i===void 0){i="";const r=nE(n)!=="false",l=iE(n);if(r||l){const o=n.getAttribute("aria-errormessage");i=Nr(n,o).map(h=>Fa(yn(h,{visitedElements:new Set,embeddedInDescribedBy:{element:h,hidden:ln(h)}}))).join(" ").trim()}e==null||e.set(n,i)}return i}function yn(n,e){var h,g,y,m;if(e.visitedElements.has(n))return"";const i={...e,embeddedInTargetElement:e.embeddedInTargetElement==="self"?"descendant":e.embeddedInTargetElement};if(!e.includeHidden){const w=!!((h=e.embeddedInLabelledBy)!=null&&h.hidden)||!!((g=e.embeddedInDescribedBy)!=null&&g.hidden)||!!((y=e.embeddedInNativeTextAlternative)!=null&&y.hidden)||!!((m=e.embeddedInLabel)!=null&&m.hidden);if(ev(n)||!w&&ln(n))return e.visitedElements.add(n),""}const r=nv(n);if(!e.embeddedInLabelledBy){const w=(r||[]).map(v=>yn(v,{...e,embeddedInLabelledBy:{element:v,hidden:ln(v)},embeddedInDescribedBy:void 0,embeddedInTargetElement:void 0,embeddedInLabel:void 0,embeddedInNativeTextAlternative:void 0})).join(" ");if(w)return w}const l=mt(n)||"",o=Xe(n);if(e.embeddedInLabel||e.embeddedInLabelledBy||e.embeddedInTargetElement==="descendant"){const w=[...n.labels||[]].includes(n),v=(r||[]).includes(n);if(!w&&!v){if(l==="textbox")return e.visitedElements.add(n),o==="INPUT"||o==="TEXTAREA"?n.value:n.textContent||"";if(["combobox","listbox"].includes(l)){e.visitedElements.add(n);let E;if(o==="SELECT")E=[...n.selectedOptions],!E.length&&n.options.length&&E.push(n.options[0]);else{const x=l==="combobox"?v0(n,"*").find(_=>mt(_)==="listbox"):n;E=x?v0(x,'[aria-selected="true"]').filter(_=>mt(_)==="option"):[]}return!E.length&&o==="INPUT"?n.value:E.map(x=>yn(x,i)).join(" ")}if(["progressbar","scrollbar","slider","spinbutton","meter"].includes(l))return e.visitedElements.add(n),n.hasAttribute("aria-valuetext")?n.getAttribute("aria-valuetext")||"":n.hasAttribute("aria-valuenow")?n.getAttribute("aria-valuenow")||"":n.getAttribute("value")||"";if(["menu"].includes(l))return e.visitedElements.add(n),""}}const u=n.getAttribute("aria-label")||"";if(Pn(u))return e.visitedElements.add(n),u;if(!["presentation","none"].includes(l)){if(o==="INPUT"&&["button","submit","reset"].includes(n.type)){e.visitedElements.add(n);const w=n.value||"";return Pn(w)?w:n.type==="submit"?"Submit":n.type==="reset"?"Reset":n.getAttribute("title")||""}if(o==="INPUT"&&n.type==="file"){e.visitedElements.add(n);const w=n.labels||[];return w.length&&!e.embeddedInLabelledBy?Ra(w,e):"Choose File"}if(o==="INPUT"&&n.type==="image"){e.visitedElements.add(n);const w=n.labels||[];if(w.length&&!e.embeddedInLabelledBy)return Ra(w,e);const v=n.getAttribute("alt")||"";if(Pn(v))return v;const E=n.getAttribute("title")||"";return Pn(E)?E:"Submit"}if(!r&&o==="BUTTON"){e.visitedElements.add(n);const w=n.labels||[];if(w.length)return Ra(w,e)}if(!r&&o==="OUTPUT"){e.visitedElements.add(n);const w=n.labels||[];return w.length?Ra(w,e):n.getAttribute("title")||""}if(!r&&(o==="TEXTAREA"||o==="SELECT"||o==="INPUT")){e.visitedElements.add(n);const w=n.labels||[];if(w.length)return Ra(w,e);const v=o==="INPUT"&&["text","password","search","tel","email","url"].includes(n.type)||o==="TEXTAREA",E=n.getAttribute("placeholder")||"",x=n.getAttribute("title")||"";return!v||x?x:E}if(!r&&o==="FIELDSET"){e.visitedElements.add(n);for(let v=n.firstElementChild;v;v=v.nextElementSibling)if(Xe(v)==="LEGEND")return yn(v,{...i,embeddedInNativeTextAlternative:{element:v,hidden:ln(v)}});return n.getAttribute("title")||""}if(!r&&o==="FIGURE"){e.visitedElements.add(n);for(let v=n.firstElementChild;v;v=v.nextElementSibling)if(Xe(v)==="FIGCAPTION")return yn(v,{...i,embeddedInNativeTextAlternative:{element:v,hidden:ln(v)}});return n.getAttribute("title")||""}if(o==="IMG"){e.visitedElements.add(n);const w=n.getAttribute("alt")||"";return Pn(w)?w:n.getAttribute("title")||""}if(o==="TABLE"){e.visitedElements.add(n);for(let v=n.firstElementChild;v;v=v.nextElementSibling)if(Xe(v)==="CAPTION")return yn(v,{...i,embeddedInNativeTextAlternative:{element:v,hidden:ln(v)}});const w=n.getAttribute("summary")||"";if(w)return w}if(o==="AREA"){e.visitedElements.add(n);const w=n.getAttribute("alt")||"";return Pn(w)?w:n.getAttribute("title")||""}if(o==="SVG"||n.ownerSVGElement){e.visitedElements.add(n);for(let w=n.firstElementChild;w;w=w.nextElementSibling)if(Xe(w)==="TITLE"&&w.ownerSVGElement)return yn(w,{...i,embeddedInLabelledBy:{element:w,hidden:ln(w)}})}if(n.ownerSVGElement&&o==="A"){const w=n.getAttribute("xlink:title")||"";if(Pn(w))return e.visitedElements.add(n),w}}const f=o==="SUMMARY"&&!["presentation","none"].includes(l);if(tE(l,e.embeddedInTargetElement==="descendant")||f||e.embeddedInLabelledBy||e.embeddedInDescribedBy||e.embeddedInLabel||e.embeddedInNativeTextAlternative){e.visitedElements.add(n);const w=rE(n,i);if(e.embeddedInTargetElement==="self"?Pn(w):w)return w}if(!["presentation","none"].includes(l)||o==="IFRAME"){e.visitedElements.add(n);const w=n.getAttribute("title")||"";if(Pn(w))return w}return e.visitedElements.add(n),""}function rE(n,e){const i=[],r=(o,u)=>{var f;if(!(u&&o.assignedSlot))if(o.nodeType===1){const h=((f=zi(o))==null?void 0:f.display)||"inline";let g=yn(o,e);(h!=="inline"||o.nodeName==="BR")&&(g=" "+g+" "),i.push(g)}else o.nodeType===3&&i.push(o.textContent||"")};i.push(Qa(n,"::before")||"");const l=Qa(n);if(l!==void 0)i.push(l);else{const o=n.nodeName==="SLOT"?n.assignedNodes():[];if(o.length)for(const u of o)r(u,!1);else{for(let u=n.firstChild;u;u=u.nextSibling)r(u,!0);if(n.shadowRoot)for(let u=n.shadowRoot.firstChild;u;u=u.nextSibling)r(u,!0);for(const u of Nr(n,n.getAttribute("aria-owns")))r(u,!0)}}return i.push(Qa(n,"::after")||""),i.join("")}const ud=["gridcell","option","row","tab","rowheader","columnheader","treeitem"];function iv(n){return Xe(n)==="OPTION"?n.selected:ud.includes(mt(n)||"")?Wb(n.getAttribute("aria-selected"))===!0:!1}const fd=["checkbox","menuitemcheckbox","option","radio","switch","menuitemradio","treeitem"];function sv(n){const e=hd(n,!0);return e==="error"?!1:e}function aE(n){return hd(n,!0)}function lE(n){return hd(n,!1)}function hd(n,e){const i=Xe(n);if(e&&i==="INPUT"&&n.indeterminate)return"mixed";if(i==="INPUT"&&["checkbox","radio"].includes(n.type))return n.checked;if(fd.includes(mt(n)||"")){const r=n.getAttribute("aria-checked");return r==="true"?!0:e&&r==="mixed"?"mixed":!1}return"error"}const oE=["checkbox","combobox","grid","gridcell","listbox","radiogroup","slider","spinbutton","textbox","columnheader","rowheader","searchbox","switch","treegrid"];function cE(n){const e=Xe(n);return["INPUT","TEXTAREA","SELECT"].includes(e)?n.hasAttribute("readonly"):oE.includes(mt(n)||"")?n.getAttribute("aria-readonly")==="true":n.isContentEditable?!1:"error"}const dd=["button"];function rv(n){if(dd.includes(mt(n)||"")){const e=n.getAttribute("aria-pressed");if(e==="true")return!0;if(e==="mixed")return"mixed"}return!1}const pd=["application","button","checkbox","combobox","gridcell","link","listbox","menuitem","row","rowheader","tab","treeitem","columnheader","menuitemcheckbox","menuitemradio","rowheader","switch"];function av(n){if(Xe(n)==="DETAILS")return n.open;if(pd.includes(mt(n)||"")){const e=n.getAttribute("aria-expanded");return e===null?void 0:e==="true"}}const gd=["heading","listitem","row","treeitem"];function lv(n){const e={H1:1,H2:2,H3:3,H4:4,H5:5,H6:6}[Xe(n)];if(e)return e;if(gd.includes(mt(n)||"")){const i=n.getAttribute("aria-level"),r=i===null?Number.NaN:Number(i);if(Number.isInteger(r)&&r>=1)return r}return 0}const ov=["application","button","composite","gridcell","group","input","link","menuitem","scrollbar","separator","tab","checkbox","columnheader","combobox","grid","listbox","menu","menubar","menuitemcheckbox","menuitemradio","option","radio","radiogroup","row","rowheader","searchbox","select","slider","spinbutton","switch","tablist","textbox","toolbar","tree","treegrid","treeitem"];function uc(n){return cv(n)||uv(n)}function cv(n){return["BUTTON","INPUT","SELECT","TEXTAREA","OPTION","OPTGROUP"].includes(Xe(n))&&(n.hasAttribute("disabled")||uE(n)||fE(n))}function uE(n){return Xe(n)==="OPTION"&&!!n.closest("OPTGROUP[DISABLED]")}function fE(n){const e=n==null?void 0:n.closest("FIELDSET[DISABLED]");if(!e)return!1;const i=e.querySelector(":scope > LEGEND");return!i||!i.contains(n)}function uv(n,e=!1){if(!n)return!1;if(e||ov.includes(mt(n)||"")){const i=(n.getAttribute("aria-disabled")||"").toLowerCase();return i==="true"?!0:i==="false"?!1:uv(bt(n),!0)}return!1}function Ra(n,e){return[...n].map(i=>yn(i,{...e,embeddedInLabel:{element:i,hidden:ln(i)},embeddedInNativeTextAlternative:void 0,embeddedInLabelledBy:void 0,embeddedInDescribedBy:void 0,embeddedInTargetElement:void 0})).filter(i=>!!i).join(" ")}function hE(n){const e=_d;let i=n,r;const l=[];for(;i;i=bt(i)){const o=e.get(i);if(o!==void 0){r=o;break}l.push(i);const u=zi(i);if(!u){r=!0;break}const f=u.pointerEvents;if(f){r=f!=="none";break}}r===void 0&&(r=!0);for(const o of l)e.set(o,r);return r}let md,yd,bd,vd,dr,Mi,Sd,wd,xd,_d,fv=0;function vc(){ld(),++fv,md??(md=new Map),yd??(yd=new Map),bd??(bd=new Map),vd??(vd=new Map),dr??(dr=new Map),Mi??(Mi=new Map),Sd??(Sd=new Map),wd??(wd=new Map),xd??(xd=new Map),_d??(_d=new Map)}function Sc(){--fv||(md=void 0,yd=void 0,bd=void 0,vd=void 0,dr=void 0,Mi=void 0,Sd=void 0,wd=void 0,xd=void 0,_d=void 0),od()}const dE={button:"button",checkbox:"checkbox",image:"button",number:"spinbutton",radio:"radio",range:"slider",reset:"button",submit:"button"};let pE=0;function hv(n){return n.mode==="ai"?{visibility:"ariaOrVisible",refs:"interactable",refPrefix:n.refPrefix,includeGenericRole:!0,renderActive:!n.doNotRenderActive,renderCursorPointer:!0}:n.mode==="autoexpect"?{visibility:"ariaAndVisible",refs:"none"}:n.mode==="codegen"?{visibility:"aria",refs:"none",renderStringsAsRegex:!0}:{visibility:"aria",refs:"none"}}function Ja(n,e){const i=hv(e),r=new Set,l={root:{role:"fragment",name:"",children:[],props:{},box:cc(n),receivesPointerEvents:!0},elements:new Map,refs:new Map,iframeRefs:[]};Rh(l.root,n);const o=(f,h,g)=>{if(r.has(h))return;if(r.add(h),h.nodeType===Node.TEXT_NODE&&h.nodeValue){if(!g)return;const x=h.nodeValue;f.role!=="textbox"&&x&&f.children.push(h.nodeValue||"");return}if(h.nodeType!==Node.ELEMENT_NODE)return;const y=h,m=!ln(y);let w=m;if(i.visibility==="ariaOrVisible"&&(w=m||ji(y)),i.visibility==="ariaAndVisible"&&(w=m&&ji(y)),i.visibility==="aria"&&!w)return;const v=[];if(y.hasAttribute("aria-owns")){const x=y.getAttribute("aria-owns").split(/\s+/);for(const _ of x){const N=n.ownerDocument.getElementById(_);N&&v.push(N)}}const E=w?gE(y,i):null;E&&(E.ref&&(l.elements.set(E.ref,y),l.refs.set(y,E.ref),E.role==="iframe"&&l.iframeRefs.push(E.ref)),f.children.push(E)),u(E||f,y,v,w)};function u(f,h,g,y){var E;const w=(((E=zi(h))==null?void 0:E.display)||"inline")!=="inline"||h.nodeName==="BR"?" ":"";w&&f.children.push(w),f.children.push(Qa(h,"::before")||"");const v=h.nodeName==="SLOT"?h.assignedNodes():[];if(v.length)for(const x of v)o(f,x,y);else{for(let x=h.firstChild;x;x=x.nextSibling)x.assignedSlot||o(f,x,y);if(h.shadowRoot)for(let x=h.shadowRoot.firstChild;x;x=x.nextSibling)o(f,x,y)}for(const x of g)o(f,x,y);if(f.children.push(Qa(h,"::after")||""),w&&f.children.push(w),f.children.length===1&&f.name===f.children[0]&&(f.children=[]),f.role==="link"&&h.hasAttribute("href")){const x=h.getAttribute("href");f.props.url=x}if(f.role==="textbox"&&h.hasAttribute("placeholder")&&h.getAttribute("placeholder")!==f.name){const x=h.getAttribute("placeholder");f.props.placeholder=x}}vc();try{o(l.root,n,!0)}finally{Sc()}return yE(l.root),mE(l.root),l}function w0(n,e){if(e.refs==="none"||e.refs==="interactable"&&(!n.box.visible||!n.receivesPointerEvents))return;const i=Ed(n);let r=i._ariaRef;(!r||r.role!==n.role||r.name!==n.name)&&(r={role:n.role,name:n.name,ref:(e.refPrefix??"")+"e"+ ++pE},i._ariaRef=r),n.ref=r.ref}function gE(n,e){const i=n.ownerDocument.activeElement===n;if(n.nodeName==="IFRAME"){const g={role:"iframe",name:"",children:[],props:{},box:cc(n),receivesPointerEvents:!0,active:i};return Rh(g,n),w0(g,e),g}const r=e.includeGenericRole?"generic":null,l=mt(n)??r;if(!l||l==="presentation"||l==="none")return null;const o=At(sl(n,!1)||""),u=hE(n),f=cc(n);if(l==="generic"&&f.inline&&n.childNodes.length===1&&n.childNodes[0].nodeType===Node.TEXT_NODE)return null;const h={role:l,name:o,children:[],props:{},box:f,receivesPointerEvents:u,active:i};return Rh(h,n),w0(h,e),fd.includes(l)&&(h.checked=sv(n)),ov.includes(l)&&(h.disabled=uc(n)),pd.includes(l)&&(h.expanded=av(n)),gd.includes(l)&&(h.level=lv(n)),dd.includes(l)&&(h.pressed=rv(n)),ud.includes(l)&&(h.selected=iv(n)),(n instanceof HTMLInputElement||n instanceof HTMLTextAreaElement)&&n.type!=="checkbox"&&n.type!=="radio"&&n.type!=="file"&&(h.children=[n.value]),h}function mE(n){const e=i=>{const r=[];for(const o of i.children||[]){if(typeof o=="string"){r.push(o);continue}const u=e(o);r.push(...u)}return i.role==="generic"&&!i.name&&r.length<=1&&r.every(o=>typeof o!="string"&&!!o.ref)?r:(i.children=r,[i])};e(n)}function yE(n){const e=(r,l)=>{if(!r.length)return;const o=At(r.join(""));o&&l.push(o),r.length=0},i=r=>{const l=[],o=[];for(const u of r.children||[])typeof u=="string"?o.push(u):(e(o,l),i(u),l.push(u));e(o,l),r.children=l.length?l:[],r.children.length===1&&r.children[0]===r.name&&(r.children=[])};i(n)}function bE(n,e){return e?n?typeof e=="string"?n===e:!!n.match(new RegExp(e.pattern)):!1:!0}function x0(n,e){if(!(e!=null&&e.normalized))return!0;if(!n)return!1;if(n===e.normalized||n===e.raw)return!0;const i=vE(e);return i?!!n.match(i):!1}const fh=Symbol("cachedRegex");function vE(n){if(n[fh]!==void 0)return n[fh];const{raw:e}=n,i=e.startsWith("/")&&e.endsWith("/")&&e.length>1;let r;try{r=i?new RegExp(e.slice(1,-1)):null}catch{r=null}return n[fh]=r,r}function SE(n,e){const i=Ja(n,{mode:"expect"});return{matches:dv(i.root,e,!1,!1),received:{raw:Pa(i,{mode:"expect"}),regex:Pa(i,{mode:"codegen"})}}}function wE(n,e){const i=Ja(n,{mode:"expect"}).root;return dv(i,e,!0,!1).map(l=>Ed(l))}function Td(n,e,i){var r;return typeof n=="string"&&e.kind==="text"?x0(n,e.text):n===null||typeof n!="object"||e.kind!=="role"||e.role!=="fragment"&&e.role!==n.role||e.checked!==void 0&&e.checked!==n.checked||e.disabled!==void 0&&e.disabled!==n.disabled||e.expanded!==void 0&&e.expanded!==n.expanded||e.level!==void 0&&e.level!==n.level||e.pressed!==void 0&&e.pressed!==n.pressed||e.selected!==void 0&&e.selected!==n.selected||!bE(n.name,e.name)||!x0(n.props.url,(r=e.props)==null?void 0:r.url)?!1:e.containerMode==="contain"?T0(n.children||[],e.children||[]):e.containerMode==="equal"?_0(n.children||[],e.children||[],!1):e.containerMode==="deep-equal"||i?_0(n.children||[],e.children||[],!0):T0(n.children||[],e.children||[])}function _0(n,e,i){if(e.length!==n.length)return!1;for(let r=0;rn.length)return!1;const i=n.slice(),r=e.slice();for(const l of r){let o=i.shift();for(;o&&!Td(o,l,!1);)o=i.shift();if(!o)return!1}return!0}function dv(n,e,i,r){const l=[],o=(u,f)=>{if(Td(u,e,r)){const h=typeof u=="string"?f:u;return h&&l.push(h),!i}if(typeof u=="string")return!1;for(const h of u.children||[])if(o(h,u))return!0;return!1};return o(n,null),l}function pv(n,e=new Map){n!=null&&n.ref&&e.set(n.ref,n);for(const i of(n==null?void 0:n.children)||[])typeof i!="string"&&pv(i,e);return e}function xE(n,e){var o;const i=pv(e==null?void 0:e.root),r=new Map,l=(u,f)=>{let h=u.children.length===(f==null?void 0:f.children.length)&&VT(u,f),g=h;for(let y=0;y{const o=e.get(l);if(o!=="same")if(o==="skip")for(const u of l.children)typeof u!="string"&&r(u);else i.push(l)};for(const l of n)typeof l=="string"?i.push(l):r(l);return i}function Pa(n,e,i){const r=hv(e),l=[],o=r.renderStringsAsRegex?EE:()=>!0,u=r.renderStringsAsRegex?TE:v=>v;let f=n.root.role==="fragment"?n.root.children:[n.root];const h=xE(n,i);i&&(f=_E(f,h));const g=(v,E)=>{const x=ch(u(v));x&&l.push(E+"- text: "+x)},y=(v,E)=>{let x=v.role;if(v.name&&v.name.length<=900){const _=u(v.name);if(_){const N=_.startsWith("/")&&_.endsWith("/")?_:JSON.stringify(_);x+=" "+N}}return v.checked==="mixed"&&(x+=" [checked=mixed]"),v.checked===!0&&(x+=" [checked]"),v.disabled&&(x+=" [disabled]"),v.expanded&&(x+=" [expanded]"),v.active&&r.renderActive&&(x+=" [active]"),v.level&&(x+=` [level=${v.level}]`),v.pressed==="mixed"&&(x+=" [pressed=mixed]"),v.pressed===!0&&(x+=" [pressed]"),v.selected===!0&&(x+=" [selected]"),v.ref&&(x+=` [ref=${v.ref}]`,E&&lc(v)&&(x+=" [cursor=pointer]")),x},m=v=>(v==null?void 0:v.children.length)===1&&typeof v.children[0]=="string"&&!Object.keys(v.props).length?v.children[0]:void 0,w=(v,E,x)=>{if(h.get(v)==="same"&&v.ref){l.push(E+`- ref=${v.ref} [unchanged]`);return}const _=!!i&&!E,N=E+"- "+(_?" ":"")+XT(y(v,x)),C=m(v);if(!v.children.length&&!Object.keys(v.props).length)l.push(N);else if(C!==void 0)o(v,C)?l.push(N+": "+ch(u(C))):l.push(N);else{l.push(N+":");for(const[D,K]of Object.entries(v.props))l.push(E+" - /"+D+": "+ch(K));const $=E+" ",I=!!v.ref&&x&&lc(v);for(const D of v.children)typeof D=="string"?g(o(v,D)?D:"",$):w(D,$,x&&!I)}};for(const v of f)typeof v=="string"?g(v,""):w(v,"",!!r.renderCursorPointer);return l.join(` +`)}function TE(n){const e=[{regex:/\b[\d,.]+[bkmBKM]+\b/,replacement:"[\\d,.]+[bkmBKM]+"},{regex:/\b\d+[hmsp]+\b/,replacement:"\\d+[hmsp]+"},{regex:/\b[\d,.]+[hmsp]+\b/,replacement:"[\\d,.]+[hmsp]+"},{regex:/\b\d+,\d+\b/,replacement:"\\d+,\\d+"},{regex:/\b\d+\.\d{2,}\b/,replacement:"\\d+\\.\\d+"},{regex:/\b\d{2,}\.\d+\b/,replacement:"\\d+\\.\\d+"},{regex:/\b\d{2,}\b/,replacement:"\\d+"}];let i="",r=0;const l=new RegExp(e.map(o=>"("+o.regex.source+")").join("|"),"g");return n.replace(l,(o,...u)=>{const f=u[u.length-2],h=u.slice(0,-2);i+=rc(n.slice(r,f));for(let g=0;ge.length)return!1;const i=e.length<=200&&n.name.length<=200?l_(e,n.name):"";let r=e;for(;i&&r.includes(i);)r=r.replace(i,"");return r.trim().length/e.length>.1}const gv=Symbol("element");function Ed(n){return n[gv]}function Rh(n,e){n[gv]=e}function AE(n,e){const i=YT(n,e);return i?Ed(i):void 0}const E0=":host{font-size:13px;font-family:system-ui,Ubuntu,Droid Sans,sans-serif;color:#333}svg{position:absolute;height:0}x-pw-tooltip{-webkit-backdrop-filter:blur(5px);backdrop-filter:blur(5px);background-color:#fff;border-radius:6px;box-shadow:0 .5rem 1.2rem #0000004d;display:none;font-size:12.8px;font-weight:400;left:0;line-height:1.5;max-width:600px;position:absolute;top:0;padding:0;flex-direction:column;overflow:hidden}x-pw-tooltip-line{display:flex;max-width:600px;padding:6px;-webkit-user-select:none;user-select:none;cursor:pointer}x-pw-tooltip-footer{display:flex;max-width:600px;padding:6px;-webkit-user-select:none;user-select:none;color:#777}x-pw-dialog{background-color:#fff;pointer-events:auto;border-radius:6px;box-shadow:0 .5rem 1.2rem #0000004d;display:flex;flex-direction:column;position:absolute;z-index:10;font-size:13px}x-pw-dialog:not(.autosize){width:400px;height:150px}x-pw-dialog-body{display:flex;flex-direction:column;flex:auto}x-pw-dialog-body label{margin:5px 8px;display:flex;flex-direction:row;align-items:center}x-pw-highlight{position:absolute;top:0;left:0;width:0;height:0}x-pw-action-point{position:absolute;width:20px;height:20px;background:red;border-radius:10px;margin:-10px 0 0 -10px;z-index:2}x-pw-separator{height:1px;margin:6px 9px;background:#949494e5}x-pw-tool-gripper{height:28px;width:24px;margin:2px 0;cursor:grab}x-pw-tool-gripper:active{cursor:grabbing}x-pw-tool-gripper>x-div{width:16px;height:16px;margin:6px 4px;clip-path:url(#icon-gripper);background-color:#555}x-pw-tools-list>label{display:flex;align-items:center;margin:0 10px;-webkit-user-select:none;user-select:none}x-pw-tools-list{display:flex;width:100%;border-bottom:1px solid #dddddd}x-pw-tool-item{pointer-events:auto;height:28px;width:28px;border-radius:3px}x-pw-tool-item:not(.disabled){cursor:pointer}x-pw-tool-item:not(.disabled):hover{background-color:#dbdbdb}x-pw-tool-item.toggled{background-color:#8acae480}x-pw-tool-item.toggled:not(.disabled):hover{background-color:#8acae4c4}x-pw-tool-item>x-div{width:16px;height:16px;margin:6px;background-color:#3a3a3a}x-pw-tool-item.disabled>x-div{background-color:#61616180;cursor:default}x-pw-tool-item.record.toggled{background-color:transparent}x-pw-tool-item.record.toggled:not(.disabled):hover{background-color:#dbdbdb}x-pw-tool-item.record.toggled>x-div{background-color:#a1260d}x-pw-tool-item.record.disabled.toggled>x-div{opacity:.8}x-pw-tool-item.accept>x-div{background-color:#388a34}x-pw-tool-item.record>x-div{clip-path:url(#icon-circle-large-filled)}x-pw-tool-item.record.toggled>x-div{clip-path:url(#icon-stop-circle)}x-pw-tool-item.pick-locator>x-div{clip-path:url(#icon-inspect)}x-pw-tool-item.text>x-div{clip-path:url(#icon-whole-word)}x-pw-tool-item.visibility>x-div{clip-path:url(#icon-eye)}x-pw-tool-item.value>x-div{clip-path:url(#icon-symbol-constant)}x-pw-tool-item.snapshot>x-div{clip-path:url(#icon-gist)}x-pw-tool-item.accept>x-div{clip-path:url(#icon-check)}x-pw-tool-item.cancel>x-div{clip-path:url(#icon-close)}x-pw-tool-item.succeeded>x-div{clip-path:url(#icon-pass);background-color:#388a34!important}x-pw-overlay{position:absolute;top:0;max-width:min-content;z-index:2147483647;background:transparent;pointer-events:auto}x-pw-overlay x-pw-tools-list{background-color:#fffd;box-shadow:#0000001a 0 5px 5px;border-radius:3px;border-bottom:none}x-pw-overlay x-pw-tool-item{margin:2px}textarea.text-editor{font-family:system-ui,Ubuntu,Droid Sans,sans-serif;flex:auto;border:none;margin:6px 10px;color:#333;outline:1px solid transparent!important;resize:none;padding:0;font-size:13px}textarea.text-editor.does-not-match{outline:1px solid red!important}x-div{display:block}x-spacer{flex:auto}*{box-sizing:border-box}*[hidden]{display:none!important}x-locator-editor{flex:none;width:100%;height:60px;padding:4px;border-bottom:1px solid #dddddd;outline:1px solid transparent}x-locator-editor.does-not-match{outline:1px solid red}.CodeMirror{width:100%!important;height:100%!important}x-pw-action-list{flex:auto;display:flex;flex-direction:column;-webkit-user-select:none;user-select:none}x-pw-action-item{padding:6px 10px;cursor:pointer;overflow:hidden}x-pw-action-item:hover{background-color:#f2f2f2}x-pw-action-item:last-child{border-bottom-left-radius:6px;border-bottom-right-radius:6px}";class hh{constructor(e){this._renderedEntries=[],this._language="javascript",this._injectedScript=e;const i=e.document;if(this._isUnderTest=e.isUnderTest,this._glassPaneElement=i.createElement("x-pw-glass"),this._glassPaneElement.style.position="fixed",this._glassPaneElement.style.top="0",this._glassPaneElement.style.right="0",this._glassPaneElement.style.bottom="0",this._glassPaneElement.style.left="0",this._glassPaneElement.style.zIndex="2147483647",this._glassPaneElement.style.pointerEvents="none",this._glassPaneElement.style.display="flex",this._glassPaneElement.style.backgroundColor="transparent",this._actionPointElement=i.createElement("x-pw-action-point"),this._actionPointElement.setAttribute("hidden","true"),this._glassPaneShadow=this._glassPaneElement.attachShadow({mode:this._isUnderTest?"open":"closed"}),typeof this._glassPaneShadow.adoptedStyleSheets.push=="function"){const r=new this._injectedScript.window.CSSStyleSheet;r.replaceSync(E0),this._glassPaneShadow.adoptedStyleSheets.push(r)}else{const r=this._injectedScript.document.createElement("style");r.textContent=E0,this._glassPaneShadow.appendChild(r)}this._glassPaneShadow.appendChild(this._actionPointElement)}install(){this._injectedScript.document.documentElement&&(!this._injectedScript.document.documentElement.contains(this._glassPaneElement)||this._glassPaneElement.nextElementSibling)&&this._injectedScript.document.documentElement.appendChild(this._glassPaneElement)}setLanguage(e){this._language=e}runHighlightOnRaf(e){this._rafRequest&&this._injectedScript.utils.builtins.cancelAnimationFrame(this._rafRequest);const i=this._injectedScript.querySelectorAll(e,this._injectedScript.document.documentElement),r=Oi(this._language,An(e)),l=i.length>1?"#f6b26b7f":"#6fa8dc7f";this.updateHighlight(i.map((o,u)=>{const f=i.length>1?` [${u+1} of ${i.length}]`:"";return{element:o,color:l,tooltipText:r+f}})),this._rafRequest=this._injectedScript.utils.builtins.requestAnimationFrame(()=>this.runHighlightOnRaf(e))}uninstall(){this._rafRequest&&this._injectedScript.utils.builtins.cancelAnimationFrame(this._rafRequest),this._glassPaneElement.remove()}showActionPoint(e,i){this._actionPointElement.style.top=i+"px",this._actionPointElement.style.left=e+"px",this._actionPointElement.hidden=!1}hideActionPoint(){this._actionPointElement.hidden=!0}clearHighlight(){var e,i;for(const r of this._renderedEntries)(e=r.highlightElement)==null||e.remove(),(i=r.tooltipElement)==null||i.remove();this._renderedEntries=[]}maskElements(e,i){this.updateHighlight(e.map(r=>({element:r,color:i})))}updateHighlight(e){if(!this._highlightIsUpToDate(e)){this.clearHighlight();for(const i of e){const r=this._createHighlightElement();this._glassPaneShadow.appendChild(r);let l;if(i.tooltipText){l=this._injectedScript.document.createElement("x-pw-tooltip"),this._glassPaneShadow.appendChild(l),l.style.top="0",l.style.left="0",l.style.display="flex";const o=this._injectedScript.document.createElement("x-pw-tooltip-line");o.textContent=i.tooltipText,l.appendChild(o)}this._renderedEntries.push({targetElement:i.element,color:i.color,tooltipElement:l,highlightElement:r})}for(const i of this._renderedEntries){if(i.box=i.targetElement.getBoundingClientRect(),!i.tooltipElement)continue;const{anchorLeft:r,anchorTop:l}=this.tooltipPosition(i.box,i.tooltipElement);i.tooltipTop=l,i.tooltipLeft=r}for(const i of this._renderedEntries){i.tooltipElement&&(i.tooltipElement.style.top=i.tooltipTop+"px",i.tooltipElement.style.left=i.tooltipLeft+"px");const r=i.box;i.highlightElement.style.backgroundColor=i.color,i.highlightElement.style.left=r.x+"px",i.highlightElement.style.top=r.y+"px",i.highlightElement.style.width=r.width+"px",i.highlightElement.style.height=r.height+"px",i.highlightElement.style.display="block",this._isUnderTest&&console.error("Highlight box for test: "+JSON.stringify({x:r.x,y:r.y,width:r.width,height:r.height}))}}}firstBox(){var e;return(e=this._renderedEntries[0])==null?void 0:e.box}firstTooltipBox(){const e=this._renderedEntries[0];if(!(!e||!e.tooltipElement||e.tooltipLeft===void 0||e.tooltipTop===void 0))return{x:e.tooltipLeft,y:e.tooltipTop,left:e.tooltipLeft,top:e.tooltipTop,width:e.tooltipElement.offsetWidth,height:e.tooltipElement.offsetHeight,bottom:e.tooltipTop+e.tooltipElement.offsetHeight,right:e.tooltipLeft+e.tooltipElement.offsetWidth,toJSON:()=>{}}}tooltipPosition(e,i){const r=i.offsetWidth,l=i.offsetHeight,o=this._glassPaneElement.offsetWidth,u=this._glassPaneElement.offsetHeight;let f=Math.max(5,e.left);f+r>o-5&&(f=o-r-5);let h=Math.max(0,e.bottom)+5;return h+l>u-5&&(Math.max(0,e.top)>l+5?h=Math.max(0,e.top)-l-5:h=u-5-l),{anchorLeft:f,anchorTop:h}}_highlightIsUpToDate(e){if(e.length!==this._renderedEntries.length)return!1;for(let i=0;ii))return r+Math.max(e.bottom-n.bottom,0)+Math.max(n.top-e.top,0)}function CE(n,e,i){const r=e.left-n.right;if(!(r<0||i!==void 0&&r>i))return r+Math.max(e.bottom-n.bottom,0)+Math.max(n.top-e.top,0)}function kE(n,e,i){const r=e.top-n.bottom;if(!(r<0||i!==void 0&&r>i))return r+Math.max(n.left-e.left,0)+Math.max(e.right-n.right,0)}function ME(n,e,i){const r=n.top-e.bottom;if(!(r<0||i!==void 0&&r>i))return r+Math.max(n.left-e.left,0)+Math.max(e.right-n.right,0)}function OE(n,e,i){const r=i===void 0?50:i;let l=0;return n.left-e.right>=0&&(l+=n.left-e.right),e.left-n.right>=0&&(l+=e.left-n.right),e.top-n.bottom>=0&&(l+=e.top-n.bottom),n.top-e.bottom>=0&&(l+=n.top-e.bottom),l>r?void 0:l}const jE=["left-of","right-of","above","below","near"];function mv(n,e,i,r){const l=e.getBoundingClientRect(),o={"left-of":CE,"right-of":NE,above:kE,below:ME,near:OE}[n];let u;for(const f of i){if(f===e)continue;const h=o(l,f.getBoundingClientRect(),r);h!==void 0&&(u===void 0||h"?!!i:e.op==="="?r instanceof RegExp?typeof i=="string"&&!!i.match(r):i===r:typeof i!="string"||typeof r!="string"?!1:e.op==="*="?i.includes(r):e.op==="^="?i.startsWith(r):e.op==="$="?i.endsWith(r):e.op==="|="?i===r||i.startsWith(r+"-"):e.op==="~="?i.split(" ").includes(r):!1}function Ad(n){const e=n.ownerDocument;return n.nodeName==="SCRIPT"||n.nodeName==="NOSCRIPT"||n.nodeName==="STYLE"||e.head&&e.head.contains(n)}function Ut(n,e){let i=n.get(e);if(i===void 0){if(i={full:"",normalized:"",immediate:[]},!Ad(e)){let r="";if(e instanceof HTMLInputElement&&(e.type==="submit"||e.type==="button"))i={full:e.value,normalized:At(e.value),immediate:[e.value]};else{for(let l=e.firstChild;l;l=l.nextSibling)if(l.nodeType===Node.TEXT_NODE)i.full+=l.nodeValue||"",r+=l.nodeValue||"";else{if(l.nodeType===Node.COMMENT_NODE)continue;r&&i.immediate.push(r),r="",l.nodeType===Node.ELEMENT_NODE&&(i.full+=Ut(n,l).full)}r&&i.immediate.push(r),e.shadowRoot&&(i.full+=Ut(n,e.shadowRoot).full),i.full&&(i.normalized=At(i.full))}}n.set(e,i)}return i}function wc(n,e,i){if(Ad(e)||!i(Ut(n,e)))return"none";for(let r=e.firstChild;r;r=r.nextSibling)if(r.nodeType===Node.ELEMENT_NODE&&i(Ut(n,r)))return"selfAndChildren";return e.shadowRoot&&i(Ut(n,e.shadowRoot))?"selfAndChildren":"self"}function vv(n,e){const i=nv(e);if(i)return i.map(o=>Ut(n,o));const r=e.getAttribute("aria-label");if(r!==null&&r.trim())return[{full:r,normalized:At(r),immediate:[r]}];const l=e.nodeName==="INPUT"&&e.type!=="hidden";if(["BUTTON","METER","OUTPUT","PROGRESS","SELECT","TEXTAREA"].includes(e.nodeName)||l){const o=e.labels;if(o)return[...o].map(u=>Ut(n,u))}return[]}function A0(n){return n.displayName||n.name||"Anonymous"}function LE(n){if(n.type)switch(typeof n.type){case"function":return A0(n.type);case"string":return n.type;case"object":return n.type.displayName||(n.type.render?A0(n.type.render):"")}if(n._currentElement){const e=n._currentElement.type;if(typeof e=="string")return e;if(typeof e=="function")return e.displayName||e.name||"Anonymous"}return""}function RE(n){var e;return n.key??((e=n._currentElement)==null?void 0:e.key)}function DE(n){if(n.child){const i=[];for(let r=n.child;r;r=r.sibling)i.push(r);return i}if(!n._currentElement)return[];const e=i=>{var l;const r=(l=i._currentElement)==null?void 0:l.type;return typeof r=="function"||typeof r=="string"};if(n._renderedComponent){const i=n._renderedComponent;return e(i)?[i]:[]}return n._renderedChildren?[...Object.values(n._renderedChildren)].filter(e):[]}function zE(n){var r;const e=n.memoizedProps||((r=n._currentElement)==null?void 0:r.props);if(!e||typeof e=="string")return e;const i={...e};return delete i.children,i}function Sv(n){var r;const e={key:RE(n),name:LE(n),children:DE(n).map(Sv),rootElements:[],props:zE(n)},i=n.stateNode||n._hostNode||((r=n._renderedComponent)==null?void 0:r._hostNode);if(i instanceof Element)e.rootElements.push(i);else for(const l of e.children)e.rootElements.push(...l.rootElements);return e}function wv(n,e,i=[]){e(n)&&i.push(n);for(const r of n.children)wv(r,e,i);return i}function xv(n,e=[]){const r=(n.ownerDocument||n).createTreeWalker(n,NodeFilter.SHOW_ELEMENT);do{const l=r.currentNode,o=l,u=Object.keys(o).find(h=>h.startsWith("__reactContainer")&&o[h]!==null);if(u)e.push(o[u].stateNode.current);else{const h="_reactRootContainer";o.hasOwnProperty(h)&&o[h]!==null&&e.push(o[h]._internalRoot.current)}if(l instanceof Element&&l.hasAttribute("data-reactroot"))for(const h of Object.keys(l))(h.startsWith("__reactInternalInstance")||h.startsWith("__reactFiber"))&&e.push(l[h]);const f=l instanceof Element?l.shadowRoot:null;f&&xv(f,e)}while(r.nextNode());return e}const BE=()=>({queryAll(n,e){const{name:i,attributes:r}=ds(e,!1),u=xv(n.ownerDocument||n).map(h=>Sv(h)).map(h=>wv(h,g=>{const y=g.props??{};if(g.key!==void 0&&(y.key=g.key),i&&g.name!==i||g.rootElements.some(m=>!il(n,m)))return!1;for(const m of r)if(!yv(y,m))return!1;return!0})).flat(),f=new Set;for(const h of u)for(const g of h.rootElements)f.add(g);return[...f]}}),_v=["selected","checked","pressed","expanded","level","disabled","name","include-hidden"];_v.sort();function Da(n,e,i){if(!e.includes(i))throw new Error(`"${n}" attribute is only supported for roles: ${e.slice().sort().map(r=>`"${r}"`).join(", ")}`)}function rr(n,e){if(n.op!==""&&!e.includes(n.value))throw new Error(`"${n.name}" must be one of ${e.map(i=>JSON.stringify(i)).join(", ")}`)}function ar(n,e){if(!e.includes(n.op))throw new Error(`"${n.name}" does not support "${n.op}" matcher`)}function UE(n,e){const i={role:e};for(const r of n)switch(r.name){case"checked":{Da(r.name,fd,e),rr(r,[!0,!1,"mixed"]),ar(r,["","="]),i.checked=r.op===""?!0:r.value;break}case"pressed":{Da(r.name,dd,e),rr(r,[!0,!1,"mixed"]),ar(r,["","="]),i.pressed=r.op===""?!0:r.value;break}case"selected":{Da(r.name,ud,e),rr(r,[!0,!1]),ar(r,["","="]),i.selected=r.op===""?!0:r.value;break}case"expanded":{Da(r.name,pd,e),rr(r,[!0,!1]),ar(r,["","="]),i.expanded=r.op===""?!0:r.value;break}case"level":{if(Da(r.name,gd,e),typeof r.value=="string"&&(r.value=+r.value),r.op!=="="||typeof r.value!="number"||Number.isNaN(r.value))throw new Error('"level" attribute must be compared to a number');i.level=r.value;break}case"disabled":{rr(r,[!0,!1]),ar(r,["","="]),i.disabled=r.op===""?!0:r.value;break}case"name":{if(r.op==="")throw new Error('"name" attribute must have a value');if(typeof r.value!="string"&&!(r.value instanceof RegExp))throw new Error('"name" attribute must be a string or a regular expression');i.name=r.value,i.nameOp=r.op,i.exact=r.caseSensitive;break}case"include-hidden":{rr(r,[!0,!1]),ar(r,["","="]),i.includeHidden=r.op===""?!0:r.value;break}default:throw new Error(`Unknown attribute "${r.name}", must be one of ${_v.map(l=>`"${l}"`).join(", ")}.`)}return i}function HE(n,e,i){const r=[],l=u=>{if(mt(u)===e.role&&!(e.selected!==void 0&&iv(u)!==e.selected)&&!(e.checked!==void 0&&sv(u)!==e.checked)&&!(e.pressed!==void 0&&rv(u)!==e.pressed)&&!(e.expanded!==void 0&&av(u)!==e.expanded)&&!(e.level!==void 0&&lv(u)!==e.level)&&!(e.disabled!==void 0&&uc(u)!==e.disabled)&&!(!e.includeHidden&&ln(u))){if(e.name!==void 0){const f=At(sl(u,!!e.includeHidden));if(typeof e.name=="string"&&(e.name=At(e.name)),i&&!e.exact&&e.nameOp==="="&&(e.nameOp="*="),!bv(f,{op:e.nameOp||"=",value:e.name,caseSensitive:!!e.exact}))return}r.push(u)}},o=u=>{const f=[];u.shadowRoot&&f.push(u.shadowRoot);for(const h of u.querySelectorAll("*"))l(h),h.shadowRoot&&f.push(h.shadowRoot);f.forEach(o)};return o(n),r}function N0(n){return{queryAll:(e,i)=>{const r=ds(i,!0),l=r.name.toLowerCase();if(!l)throw new Error("Role must not be empty");const o=UE(r.attributes,l);vc();try{return HE(e,o,n)}finally{Sc()}}}}class qE{constructor(){this._retainCacheCounter=0,this._cacheText=new Map,this._cacheQueryCSS=new Map,this._cacheMatches=new Map,this._cacheQuery=new Map,this._cacheMatchesSimple=new Map,this._cacheMatchesParents=new Map,this._cacheCallMatches=new Map,this._cacheCallQuery=new Map,this._cacheQuerySimple=new Map,this._engines=new Map,this._engines.set("not",VE),this._engines.set("is",Ia),this._engines.set("where",Ia),this._engines.set("has",$E),this._engines.set("scope",IE),this._engines.set("light",GE),this._engines.set("visible",KE),this._engines.set("text",YE),this._engines.set("text-is",XE),this._engines.set("text-matches",FE),this._engines.set("has-text",QE),this._engines.set("right-of",za("right-of")),this._engines.set("left-of",za("left-of")),this._engines.set("above",za("above")),this._engines.set("below",za("below")),this._engines.set("near",za("near")),this._engines.set("nth-match",JE);const e=[...this._engines.keys()];e.sort();const i=[...Tb];if(i.sort(),e.join("|")!==i.join("|"))throw new Error(`Please keep customCSSNames in sync with evaluator engines: ${e.join("|")} vs ${i.join("|")}`)}begin(){++this._retainCacheCounter}end(){--this._retainCacheCounter,this._retainCacheCounter||(this._cacheQueryCSS.clear(),this._cacheMatches.clear(),this._cacheQuery.clear(),this._cacheMatchesSimple.clear(),this._cacheMatchesParents.clear(),this._cacheCallMatches.clear(),this._cacheCallQuery.clear(),this._cacheQuerySimple.clear(),this._cacheText.clear())}_cached(e,i,r,l){e.has(i)||e.set(i,[]);const o=e.get(i),u=o.find(h=>r.every((g,y)=>h.rest[y]===g));if(u)return u.result;const f=l();return o.push({rest:r,result:f}),f}_checkSelector(e){if(!(typeof e=="object"&&e&&(Array.isArray(e)||"simples"in e&&e.simples.length)))throw new Error(`Malformed selector "${e}"`);return e}matches(e,i,r){const l=this._checkSelector(i);this.begin();try{return this._cached(this._cacheMatches,e,[l,r.scope,r.pierceShadow,r.originalScope],()=>Array.isArray(l)?this._matchesEngine(Ia,e,l,r):(this._hasScopeClause(l)&&(r=this._expandContextForScopeMatching(r)),this._matchesSimple(e,l.simples[l.simples.length-1].selector,r)?this._matchesParents(e,l,l.simples.length-2,r):!1))}finally{this.end()}}query(e,i){const r=this._checkSelector(i);this.begin();try{return this._cached(this._cacheQuery,r,[e.scope,e.pierceShadow,e.originalScope],()=>{if(Array.isArray(r))return this._queryEngine(Ia,e,r);this._hasScopeClause(r)&&(e=this._expandContextForScopeMatching(e));const l=this._scoreMap;this._scoreMap=new Map;let o=this._querySimple(e,r.simples[r.simples.length-1].selector);return o=o.filter(u=>this._matchesParents(u,r,r.simples.length-2,e)),this._scoreMap.size&&o.sort((u,f)=>{const h=this._scoreMap.get(u),g=this._scoreMap.get(f);return h===g?0:h===void 0?1:g===void 0?-1:h-g}),this._scoreMap=l,o})}finally{this.end()}}_markScore(e,i){this._scoreMap&&this._scoreMap.set(e,i)}_hasScopeClause(e){return e.simples.some(i=>i.selector.functions.some(r=>r.name==="scope"))}_expandContextForScopeMatching(e){if(e.scope.nodeType!==1)return e;const i=bt(e.scope);return i?{...e,scope:i,originalScope:e.originalScope||e.scope}:e}_matchesSimple(e,i,r){return this._cached(this._cacheMatchesSimple,e,[i,r.scope,r.pierceShadow,r.originalScope],()=>{if(e===r.scope||i.css&&!this._matchesCSS(e,i.css))return!1;for(const l of i.functions)if(!this._matchesEngine(this._getEngine(l.name),e,l.args,r))return!1;return!0})}_querySimple(e,i){return i.functions.length?this._cached(this._cacheQuerySimple,i,[e.scope,e.pierceShadow,e.originalScope],()=>{let r=i.css;const l=i.functions;r==="*"&&l.length&&(r=void 0);let o,u=-1;r!==void 0?o=this._queryCSS(e,r):(u=l.findIndex(f=>this._getEngine(f.name).query!==void 0),u===-1&&(u=0),o=this._queryEngine(this._getEngine(l[u].name),e,l[u].args));for(let f=0;fthis._matchesEngine(h,g,l[f].args,e)))}for(let f=0;fthis._matchesEngine(h,g,l[f].args,e)))}return o}):this._queryCSS(e,i.css||"*")}_matchesParents(e,i,r,l){return r<0?!0:this._cached(this._cacheMatchesParents,e,[i,r,l.scope,l.pierceShadow,l.originalScope],()=>{const{selector:o,combinator:u}=i.simples[r];if(u===">"){const f=jo(e,l);return!f||!this._matchesSimple(f,o,l)?!1:this._matchesParents(f,i,r-1,l)}if(u==="+"){const f=dh(e,l);return!f||!this._matchesSimple(f,o,l)?!1:this._matchesParents(f,i,r-1,l)}if(u===""){let f=jo(e,l);for(;f;){if(this._matchesSimple(f,o,l)){if(this._matchesParents(f,i,r-1,l))return!0;if(i.simples[r-1].combinator==="")break}f=jo(f,l)}return!1}if(u==="~"){let f=dh(e,l);for(;f;){if(this._matchesSimple(f,o,l)){if(this._matchesParents(f,i,r-1,l))return!0;if(i.simples[r-1].combinator==="~")break}f=dh(f,l)}return!1}if(u===">="){let f=e;for(;f;){if(this._matchesSimple(f,o,l)){if(this._matchesParents(f,i,r-1,l))return!0;if(i.simples[r-1].combinator==="")break}f=jo(f,l)}return!1}throw new Error(`Unsupported combinator "${u}"`)})}_matchesEngine(e,i,r,l){if(e.matches)return this._callMatches(e,i,r,l);if(e.query)return this._callQuery(e,r,l).includes(i);throw new Error('Selector engine should implement "matches" or "query"')}_queryEngine(e,i,r){if(e.query)return this._callQuery(e,r,i);if(e.matches)return this._queryCSS(i,"*").filter(l=>this._callMatches(e,l,r,i));throw new Error('Selector engine should implement "matches" or "query"')}_callMatches(e,i,r,l){return this._cached(this._cacheCallMatches,i,[e,l.scope,l.pierceShadow,l.originalScope,...r],()=>e.matches(i,r,l,this))}_callQuery(e,i,r){return this._cached(this._cacheCallQuery,e,[r.scope,r.pierceShadow,r.originalScope,...i],()=>e.query(r,i,this))}_matchesCSS(e,i){return e.matches(i)}_queryCSS(e,i){return this._cached(this._cacheQueryCSS,i,[e.scope,e.pierceShadow,e.originalScope],()=>{let r=[];function l(o){if(r=r.concat([...o.querySelectorAll(i)]),!!e.pierceShadow){o.shadowRoot&&l(o.shadowRoot);for(const u of o.querySelectorAll("*"))u.shadowRoot&&l(u.shadowRoot)}}return l(e.scope),r})}_getEngine(e){const i=this._engines.get(e);if(!i)throw new Error(`Unknown selector engine "${e}"`);return i}}const Ia={matches(n,e,i,r){if(e.length===0)throw new Error('"is" engine expects non-empty selector list');return e.some(l=>r.matches(n,l,i))},query(n,e,i){if(e.length===0)throw new Error('"is" engine expects non-empty selector list');let r=[];for(const l of e)r=r.concat(i.query(n,l));return e.length===1?r:Tv(r)}},$E={matches(n,e,i,r){if(e.length===0)throw new Error('"has" engine expects non-empty selector list');return r.query({...i,scope:n},e).length>0}},IE={matches(n,e,i,r){if(e.length!==0)throw new Error('"scope" engine expects no arguments');const l=i.originalScope||i.scope;return l.nodeType===9?n===l.documentElement:n===l},query(n,e,i){if(e.length!==0)throw new Error('"scope" engine expects no arguments');const r=n.originalScope||n.scope;if(r.nodeType===9){const l=r.documentElement;return l?[l]:[]}return r.nodeType===1?[r]:[]}},VE={matches(n,e,i,r){if(e.length===0)throw new Error('"not" engine expects non-empty selector list');return!r.matches(n,e,i)}},GE={query(n,e,i){return i.query({...n,pierceShadow:!1},e)},matches(n,e,i,r){return r.matches(n,e,{...i,pierceShadow:!1})}},KE={matches(n,e,i,r){if(e.length)throw new Error('"visible" engine expects no arguments');return ji(n)}},YE={matches(n,e,i,r){if(e.length!==1||typeof e[0]!="string")throw new Error('"text" engine expects a single string');const l=At(e[0]).toLowerCase(),o=u=>u.normalized.toLowerCase().includes(l);return wc(r._cacheText,n,o)==="self"}},XE={matches(n,e,i,r){if(e.length!==1||typeof e[0]!="string")throw new Error('"text-is" engine expects a single string');const l=At(e[0]),o=u=>!l&&!u.immediate.length?!0:u.immediate.some(f=>At(f)===l);return wc(r._cacheText,n,o)!=="none"}},FE={matches(n,e,i,r){if(e.length===0||typeof e[0]!="string"||e.length>2||e.length===2&&typeof e[1]!="string")throw new Error('"text-matches" engine expects a regexp body and optional regexp flags');const l=new RegExp(e[0],e.length===2?e[1]:void 0),o=u=>l.test(u.full);return wc(r._cacheText,n,o)==="self"}},QE={matches(n,e,i,r){if(e.length!==1||typeof e[0]!="string")throw new Error('"has-text" engine expects a single string');if(Ad(n))return!1;const l=At(e[0]).toLowerCase();return(u=>u.normalized.toLowerCase().includes(l))(Ut(r._cacheText,n))}};function za(n){return{matches(e,i,r,l){const o=i.length&&typeof i[i.length-1]=="number"?i[i.length-1]:void 0,u=o===void 0?i:i.slice(0,i.length-1);if(i.length<1+(o===void 0?0:1))throw new Error(`"${n}" engine expects a selector list and optional maximum distance in pixels`);const f=l.query(r,u),h=mv(n,e,f,o);return h===void 0?!1:(l._markScore(e,h),!0)}}}const JE={query(n,e,i){let r=e[e.length-1];if(e.length<2)throw new Error('"nth-match" engine expects non-empty selector list and an index argument');if(typeof r!="number"||r<1)throw new Error('"nth-match" engine expects a one-based index as the last argument');const l=Ia.query(n,e.slice(0,e.length-1),i);return r--,r1){const h=new Set(f.children);f.children=[];let g=u.firstElementChild;for(;g&&f.children.lengthQo(y)))]}else{const f=rs(r,n,e,i)||Va(n,e,i);l=[Qo(f)]}}const o=l[0],u=n.parseSelector(o);return{selector:o,selectors:l,elements:n.querySelectorAll(u,i.root??e.ownerDocument)}}finally{od(),Sc(),n._evaluator.end()}}function rs(n,e,i,r){if(r.root&&!il(r.root,i))throw new Error("Target element must belong to the root's subtree");if(i===r.root)return[{engine:"css",selector:":scope",score:1}];if(i.ownerDocument.documentElement===i)return[{engine:"css",selector:"html",score:1}];let l=null;const o=f=>{(!l||as(f)as(f.candidate)-as(h.candidate));for(const{candidate:f,isTextCandidate:h}of u){const g=e.querySelectorAll(e.parseSelector(Qo(f)),r.root??i.ownerDocument);if(!g.includes(i))continue;if(g.length===1){o(f);break}const y=g.indexOf(i);if(!(y>5)&&(o([...f,{engine:"nth",selector:String(y),score:Dh}]),!r.isRecursive))for(let m=bt(i);m&&m!==r.root;m=bt(m)){const w=g.filter($=>il(m,$)&&$!==m),v=w.indexOf(i);if(w.length>5||v===-1||v===y&&w.length>1)continue;const E=w.length===1?f:[...f,{engine:"nth",selector:String(v),score:Dh}];if(l&&as([{engine:"",selector:"",score:1},...E])>=as(l))continue;const _=!!r.noText||h,N=_?n.disallowText:n.allowText;let C=N.get(m);C===void 0&&(C=rs(n,e,m,{...r,isRecursive:!0,noText:_})||Va(e,m,r),N.set(m,C)),C&&o([...C,...E])}}return l}function uA(n,e,i){const r=[];{for(const u of["data-testid","data-test-id","data-test"])u!==i.testIdAttributeName&&e.getAttribute(u)&&r.push({engine:"css",selector:`[${u}=${fr(e.getAttribute(u))}]`,score:PE});if(!i.noCSSId){const u=e.getAttribute("id");u&&!hA(u)&&r.push({engine:"css",selector:Lv(u),score:lA})}r.push({engine:"css",selector:Zn(e),score:jv})}if(e.nodeName==="IFRAME"){for(const u of["name","title"])e.getAttribute(u)&&r.push({engine:"css",selector:`${Zn(e)}[${u}=${fr(e.getAttribute(u))}]`,score:ZE});return e.getAttribute(i.testIdAttributeName)&&r.push({engine:"css",selector:`[${i.testIdAttributeName}=${fr(e.getAttribute(i.testIdAttributeName))}]`,score:C0}),zh([r]),r}if(e.getAttribute(i.testIdAttributeName)&&r.push({engine:"internal:testid",selector:`[${i.testIdAttributeName}=${Tt(e.getAttribute(i.testIdAttributeName),!0)}]`,score:C0}),e.nodeName==="INPUT"||e.nodeName==="TEXTAREA"){const u=e;if(u.placeholder){r.push({engine:"internal:attr",selector:`[placeholder=${Tt(u.placeholder,!0)}]`,score:eA});for(const f of pr(u.placeholder))r.push({engine:"internal:attr",selector:`[placeholder=${Tt(f.text,!1)}]`,score:Nv-f.scoreBonus})}}const l=vv(n._evaluator._cacheText,e);for(const u of l){const f=u.normalized;r.push({engine:"internal:label",selector:zt(f,!0),score:tA});for(const h of pr(f))r.push({engine:"internal:label",selector:zt(h.text,!1),score:Cv-h.scoreBonus})}const o=mt(e);return o&&!["none","presentation"].includes(o)&&r.push({engine:"internal:role",selector:o,score:Ov}),e.getAttribute("name")&&["BUTTON","FORM","FIELDSET","FRAME","IFRAME","INPUT","KEYGEN","OBJECT","OUTPUT","SELECT","TEXTAREA","MAP","META","PARAM"].includes(e.nodeName)&&r.push({engine:"css",selector:`${Zn(e)}[name=${fr(e.getAttribute("name"))}]`,score:ph}),["INPUT","TEXTAREA"].includes(e.nodeName)&&e.getAttribute("type")!=="hidden"&&e.getAttribute("type")&&r.push({engine:"css",selector:`${Zn(e)}[type=${fr(e.getAttribute("type"))}]`,score:ph}),["INPUT","TEXTAREA","SELECT"].includes(e.nodeName)&&e.getAttribute("type")!=="hidden"&&r.push({engine:"css",selector:Zn(e),score:ph+1}),zh([r]),r}function fA(n,e,i){if(e.nodeName==="SELECT")return[];const r=[],l=e.getAttribute("title");if(l){r.push([{engine:"internal:attr",selector:`[title=${Tt(l,!0)}]`,score:rA}]);for(const g of pr(l))r.push([{engine:"internal:attr",selector:`[title=${Tt(g.text,!1)}]`,score:Mv-g.scoreBonus}])}const o=e.getAttribute("alt");if(o&&["APPLET","AREA","IMG","INPUT"].includes(e.nodeName)){r.push([{engine:"internal:attr",selector:`[alt=${Tt(o,!0)}]`,score:iA}]);for(const g of pr(o))r.push([{engine:"internal:attr",selector:`[alt=${Tt(g.text,!1)}]`,score:kv-g.scoreBonus}])}const u=Ut(n._evaluator._cacheText,e).normalized,f=u?pr(u):[];if(u){if(i){u.length<=80&&r.push([{engine:"internal:text",selector:zt(u,!0),score:sA}]);for(const y of f)r.push([{engine:"internal:text",selector:zt(y.text,!1),score:Fo-y.scoreBonus}])}const g={engine:"css",selector:Zn(e),score:jv};for(const y of f)r.push([g,{engine:"internal:has-text",selector:zt(y.text,!1),score:Fo-y.scoreBonus}]);if(i&&u.length<=80){const y=new RegExp("^"+rc(u)+"$");r.push([g,{engine:"internal:has-text",selector:zt(y,!1),score:k0}])}}const h=mt(e);if(h&&!["none","presentation"].includes(h)){const g=sl(e,!1);if(g&&!g.match(new RegExp("^\\p{Co}+$","u"))){const y={engine:"internal:role",selector:`${h}[name=${Tt(g,!0)}]`,score:nA};r.push([y]);for(const m of pr(g))r.push([{engine:"internal:role",selector:`${h}[name=${Tt(m.text,!1)}]`,score:Av-m.scoreBonus}])}else{const y={engine:"internal:role",selector:`${h}`,score:Ov};for(const m of f)r.push([y,{engine:"internal:has-text",selector:zt(m.text,!1),score:Fo-m.scoreBonus}]);if(i&&u.length<=80){const m=new RegExp("^"+rc(u)+"$");r.push([y,{engine:"internal:has-text",selector:zt(m,!1),score:k0}])}}}return zh(r),r}function Lv(n){return/^[a-zA-Z][a-zA-Z0-9\-\_]+$/.test(n)?"#"+n:`[id=${fr(n)}]`}function gh(n){return n.some(e=>e.engine==="css"&&(e.selector.startsWith("#")||e.selector.startsWith('[id="')))}function Va(n,e,i){const r=i.root??e.ownerDocument,l=[];function o(f){const h=l.slice();f&&h.unshift(f);const g=h.join(" > "),y=n.parseSelector(g);return n.querySelector(y,r,!1)===e?g:void 0}function u(f){const h={engine:"css",selector:f,score:oA},g=n.parseSelector(f),y=n.querySelectorAll(g,r);if(y.length===1)return[h];const m={engine:"nth",selector:String(y.indexOf(e)),score:Dh};return[h,m]}for(let f=e;f&&f!==r;f=bt(f)){let h="";if(f.id&&!i.noCSSId){const m=Lv(f.id),w=o(m);if(w)return u(w);h=m}const g=f.parentNode,y=[...f.classList].map(dA);for(let m=0;m_.nodeName===w).indexOf(f)===0?Zn(f):`${Zn(f)}:nth-child(${1+m.indexOf(f)})`,x=o(E);if(x)return u(x);h||(h=E)}else h||(h=Zn(f));l.unshift(h)}return u(o())}function zh(n){for(const e of n)for(const i of e)i.score>WE&&i.score>"),i=r,r==="css"?e.push(l):e.push(`${r}=${l}`);return e.join(" ")}function as(n){let e=0;for(let i=0;i="a"&&l<="z"?o="lower":l>="A"&&l<="Z"?o="upper":l>="0"&&l<="9"?o="digit":o="other",o==="lower"&&e==="upper"){e=o;continue}e&&e!==o&&++i,e=o}}return i>=n.length/4}function Lo(n,e){if(n.length<=e)return n;n=n.substring(0,e);const i=n.match(/^(.*)\b(.+?)$/);return i?i[1].trimEnd():""}function pr(n){let e=[];{const i=n.match(/^([\d.,]+)[^.,\w]/),r=i?i[1].length:0;if(r){const l=Lo(n.substring(r).trimStart(),80);e.push({text:l,scoreBonus:l.length<=30?2:1})}}{const i=n.match(/[^.,\w]([\d.,]+)$/),r=i?i[1].length:0;if(r){const l=Lo(n.substring(0,n.length-r).trimEnd(),80);e.push({text:l,scoreBonus:l.length<=30?2:1})}}return n.length<=30?e.push({text:n,scoreBonus:0}):(e.push({text:Lo(n,80),scoreBonus:0}),e.push({text:Lo(n,30),scoreBonus:1})),e=e.filter(i=>i.text),e.length||e.push({text:n.substring(0,80),scoreBonus:0}),e}function Zn(n){return n.nodeName.toLocaleLowerCase().replace(/[:\.]/g,e=>"\\"+e)}function dA(n){let e="";for(let i=0;i=1&&i<=31||i>=48&&i<=57&&(e===0||e===1&&n.charCodeAt(0)===45)?"\\"+i.toString(16)+" ":e===0&&i===45&&n.length===1?"\\"+n.charAt(e):i>=128||i===45||i===95||i>=48&&i<=57||i>=65&&i<=90||i>=97&&i<=122?n.charAt(e):"\\"+n.charAt(e)}function Rv(n,e){const i=n.replace(/^[a-zA-Z]:/,"").replace(/\\/g,"/");let r=i.substring(i.lastIndexOf("/")+1);return r.endsWith(e)&&(r=r.substring(0,r.length-e.length)),r}function gA(n,e){return e?e.toUpperCase():""}const mA=/(?:^|[-_/])(\w)/g,Dv=n=>n&&n.replace(mA,gA);function yA(n){function e(y){const m=y.name||y._componentTag||y.__playwright_guessedName;if(m)return m;const w=y.__file;if(w)return Dv(Rv(w,".vue"))}function i(y,m){return y.type.__playwright_guessedName=m,m}function r(y){var w,v,E,x;const m=e(y.type||{});if(m)return m;if(y.root===y)return"Root";for(const _ in(v=(w=y.parent)==null?void 0:w.type)==null?void 0:v.components)if(((E=y.parent)==null?void 0:E.type.components[_])===y.type)return i(y,_);for(const _ in(x=y.appContext)==null?void 0:x.components)if(y.appContext.components[_]===y.type)return i(y,_);return"Anonymous Component"}function l(y){return y._isBeingDestroyed||y.isUnmounted}function o(y){return y.subTree.type.toString()==="Symbol(Fragment)"}function u(y){const m=[];return y.component&&m.push(y.component),y.suspense&&m.push(...u(y.suspense.activeBranch)),Array.isArray(y.children)&&y.children.forEach(w=>{w.component?m.push(w.component):m.push(...u(w))}),m.filter(w=>{var v;return!l(w)&&!((v=w.type.devtools)!=null&&v.hide)})}function f(y){return o(y)?h(y.subTree):[y.subTree.el]}function h(y){if(!y.children)return[];const m=[];for(let w=0,v=y.children.length;w!!u.component).map(u=>u.component):[]}function l(o){return{name:i(o),children:r(o).map(l),rootElements:[o.$el],props:o._props}}return l(n)}function zv(n,e,i=[]){e(n)&&i.push(n);for(const r of n.children)zv(r,e,i);return i}function Bv(n,e=[]){const r=(n.ownerDocument||n).createTreeWalker(n,NodeFilter.SHOW_ELEMENT),l=new Set;do{const o=r.currentNode;o.__vue__&&l.add(o.__vue__.$root),o.__vue_app__&&o._vnode&&o._vnode.component&&e.push({root:o._vnode.component,version:3});const u=o instanceof Element?o.shadowRoot:null;u&&Bv(u,e)}while(r.nextNode());for(const o of l)e.push({version:2,root:o});return e}const vA=()=>({queryAll(n,e){const i=n.ownerDocument||n,{name:r,attributes:l}=ds(e,!1),f=Bv(i).map(g=>g.version===3?yA(g.root):bA(g.root)).map(g=>zv(g,y=>{if(r&&y.name!==r||y.rootElements.some(m=>!il(n,m)))return!1;for(const m of l)if(!yv(y.props,m))return!1;return!0})).flat(),h=new Set;for(const g of f)for(const y of g.rootElements)h.add(y);return[...h]}}),O0={queryAll(n,e){e.startsWith("/")&&n.nodeType!==Node.DOCUMENT_NODE&&(e="."+e);const i=[],r=n.ownerDocument||n;if(!r)return i;const l=r.evaluate(e,n,null,XPathResult.ORDERED_NODE_ITERATOR_TYPE);for(let o=l.iterateNext();o;o=l.iterateNext())o.nodeType===Node.ELEMENT_NODE&&i.push(o);return i}};function Nd(n,e,i){return`internal:attr=[${n}=${Tt(e,(i==null?void 0:i.exact)||!1)}]`}function SA(n,e){return`internal:testid=[${n}=${Tt(e,!0)}]`}function wA(n,e){return"internal:label="+zt(n,!!(e!=null&&e.exact))}function xA(n,e){return Nd("alt",n,e)}function _A(n,e){return Nd("title",n,e)}function TA(n,e){return Nd("placeholder",n,e)}function EA(n,e){return"internal:text="+zt(n,!!(e!=null&&e.exact))}function AA(n,e={}){const i=[];return e.checked!==void 0&&i.push(["checked",String(e.checked)]),e.disabled!==void 0&&i.push(["disabled",String(e.disabled)]),e.selected!==void 0&&i.push(["selected",String(e.selected)]),e.expanded!==void 0&&i.push(["expanded",String(e.expanded)]),e.includeHidden!==void 0&&i.push(["include-hidden",String(e.includeHidden)]),e.level!==void 0&&i.push(["level",String(e.level)]),e.name!==void 0&&i.push(["name",Tt(e.name,!!e.exact)]),e.pressed!==void 0&&i.push(["pressed",String(e.pressed)]),`internal:role=${n}${i.map(([r,l])=>`[${r}=${l}]`).join("")}`}const Ba=Symbol("selector"),NA=class Ga{constructor(e,i,r){if(r!=null&&r.hasText&&(i+=` >> internal:has-text=${zt(r.hasText,!1)}`),r!=null&&r.hasNotText&&(i+=` >> internal:has-not-text=${zt(r.hasNotText,!1)}`),r!=null&&r.has&&(i+=" >> internal:has="+JSON.stringify(r.has[Ba])),r!=null&&r.hasNot&&(i+=" >> internal:has-not="+JSON.stringify(r.hasNot[Ba])),(r==null?void 0:r.visible)!==void 0&&(i+=` >> visible=${r.visible?"true":"false"}`),this[Ba]=i,i){const u=e.parseSelector(i);this.element=e.querySelector(u,e.document,!1),this.elements=e.querySelectorAll(u,e.document)}const l=i,o=this;o.locator=(u,f)=>new Ga(e,l?l+" >> "+u:u,f),o.getByTestId=u=>o.locator(SA(e.testIdAttributeNameForStrictErrorAndConsoleCodegen(),u)),o.getByAltText=(u,f)=>o.locator(xA(u,f)),o.getByLabel=(u,f)=>o.locator(wA(u,f)),o.getByPlaceholder=(u,f)=>o.locator(TA(u,f)),o.getByText=(u,f)=>o.locator(EA(u,f)),o.getByTitle=(u,f)=>o.locator(_A(u,f)),o.getByRole=(u,f={})=>o.locator(AA(u,f)),o.filter=u=>new Ga(e,i,u),o.first=()=>o.locator("nth=0"),o.last=()=>o.locator("nth=-1"),o.nth=u=>o.locator(`nth=${u}`),o.and=u=>new Ga(e,l+" >> internal:and="+JSON.stringify(u[Ba])),o.or=u=>new Ga(e,l+" >> internal:or="+JSON.stringify(u[Ba]))}};let CA=NA;class kA{constructor(e){this._injectedScript=e}install(){this._injectedScript.window.playwright||(this._injectedScript.window.playwright={$:(e,i)=>this._querySelector(e,!!i),$$:e=>this._querySelectorAll(e),inspect:e=>this._inspect(e),selector:e=>this._selector(e),generateLocator:(e,i)=>this._generateLocator(e,i),ariaSnapshot:(e,i)=>this._injectedScript.ariaSnapshot(e||this._injectedScript.document.body,i||{mode:"expect"}),resume:()=>this._resume(),...new CA(this._injectedScript,"")},delete this._injectedScript.window.playwright.filter,delete this._injectedScript.window.playwright.first,delete this._injectedScript.window.playwright.last,delete this._injectedScript.window.playwright.nth,delete this._injectedScript.window.playwright.and,delete this._injectedScript.window.playwright.or)}_querySelector(e,i){if(typeof e!="string")throw new Error("Usage: playwright.query('Playwright >> selector').");const r=this._injectedScript.parseSelector(e);return this._injectedScript.querySelector(r,this._injectedScript.document,i)}_querySelectorAll(e){if(typeof e!="string")throw new Error("Usage: playwright.$$('Playwright >> selector').");const i=this._injectedScript.parseSelector(e);return this._injectedScript.querySelectorAll(i,this._injectedScript.document)}_inspect(e){if(typeof e!="string")throw new Error("Usage: playwright.inspect('Playwright >> selector').");this._injectedScript.window.inspect(this._querySelector(e,!1))}_selector(e){if(!(e instanceof Element))throw new Error("Usage: playwright.selector(element).");return this._injectedScript.generateSelectorSimple(e)}_generateLocator(e,i){if(!(e instanceof Element))throw new Error("Usage: playwright.locator(element).");const r=this._injectedScript.generateSelectorSimple(e);return Oi(i||"javascript",r)}_resume(){if(!this._injectedScript.window.__pw_resume)return!1;this._injectedScript.window.__pw_resume().catch(()=>{})}}function MA(n){try{return n instanceof RegExp||Object.prototype.toString.call(n)==="[object RegExp]"}catch{return!1}}function OA(n){try{return n instanceof Date||Object.prototype.toString.call(n)==="[object Date]"}catch{return!1}}function jA(n){try{return n instanceof URL||Object.prototype.toString.call(n)==="[object URL]"}catch{return!1}}function LA(n){var e;try{return n instanceof Error||n&&((e=Object.getPrototypeOf(n))==null?void 0:e.name)==="Error"}catch{return!1}}function RA(n,e){try{return n instanceof e||Object.prototype.toString.call(n)===`[object ${e.name}]`}catch{return!1}}const Uv={i8:Int8Array,ui8:Uint8Array,ui8c:Uint8ClampedArray,i16:Int16Array,ui16:Uint16Array,i32:Int32Array,ui32:Uint32Array,f32:Float32Array,f64:Float64Array,bi64:BigInt64Array,bui64:BigUint64Array};function DA(n){if("toBase64"in n)return n.toBase64();const e=Array.from(new Uint8Array(n.buffer,n.byteOffset,n.byteLength)).map(i=>String.fromCharCode(i)).join("");return btoa(e)}function zA(n,e){const i=atob(n),r=new Uint8Array(i.length);for(let l=0;l";if(typeof globalThis.Document=="function"&&n instanceof globalThis.Document)return"ref: ";if(typeof globalThis.Node=="function"&&n instanceof globalThis.Node)return"ref: "}return Hv(n,e,i)}function Hv(n,e,i){var o;const r=e(n);if("fallThrough"in r)n=r.fallThrough;else return r;if(typeof n=="symbol")return{v:"undefined"};if(Object.is(n,void 0))return{v:"undefined"};if(Object.is(n,null))return{v:"null"};if(Object.is(n,NaN))return{v:"NaN"};if(Object.is(n,1/0))return{v:"Infinity"};if(Object.is(n,-1/0))return{v:"-Infinity"};if(Object.is(n,-0))return{v:"-0"};if(typeof n=="boolean"||typeof n=="number"||typeof n=="string")return n;if(typeof n=="bigint")return{bi:n.toString()};if(LA(n)){let u;return(o=n.stack)!=null&&o.startsWith(n.name+": "+n.message)?u=n.stack:u=`${n.name}: ${n.message} +${n.stack}`,{e:{n:n.name,m:n.message,s:u}}}if(OA(n))return{d:n.toJSON()};if(jA(n))return{u:n.toJSON()};if(MA(n))return{r:{p:n.source,f:n.flags}};for(const[u,f]of Object.entries(Uv))if(RA(n,f))return{ta:{b:DA(n),k:u}};const l=i.visited.get(n);if(l)return{ref:l};if(Array.isArray(n)){const u=[],f=++i.lastId;i.visited.set(n,f);for(let h=0;h({fallThrough:r}))}_promiseAwareJsonValueNoThrow(e){const i=r=>{try{return this.jsonValue(!0,r)}catch{return}};return e&&typeof e=="object"&&typeof e.then=="function"?(async()=>{const r=await e;return i(r)})():i(e)}}class qv{constructor(e,i){this._testIdAttributeNameForStrictErrorAndConsoleCodegen="data-testid",this._lastAriaSnapshotForTrack=new Map,this.utils={asLocator:Oi,cacheNormalizedWhitespaces:r_,elementText:Ut,getAriaRole:mt,getElementAccessibleDescription:S0,getElementAccessibleName:sl,isElementVisible:ji,isInsideScope:il,normalizeWhiteSpace:At,parseAriaSnapshot:id,generateAriaTree:Ja,findNewElement:AE,builtins:null},this.window=e,this.document=e.document,this.isUnderTest=i.isUnderTest,this.utils.builtins=new UA(e,i.isUnderTest).builtins,this._sdkLanguage=i.sdkLanguage,this._testIdAttributeNameForStrictErrorAndConsoleCodegen=i.testIdAttributeName,this._evaluator=new qE,this.consoleApi=new kA(this),this.onGlobalListenersRemoved=new Set,this._autoClosingTags=new Set(["AREA","BASE","BR","COL","COMMAND","EMBED","HR","IMG","INPUT","KEYGEN","LINK","MENUITEM","META","PARAM","SOURCE","TRACK","WBR"]),this._booleanAttributes=new Set(["checked","selected","disabled","readonly","multiple"]),this._eventTypes=new Map([["auxclick","mouse"],["click","mouse"],["dblclick","mouse"],["mousedown","mouse"],["mouseeenter","mouse"],["mouseleave","mouse"],["mousemove","mouse"],["mouseout","mouse"],["mouseover","mouse"],["mouseup","mouse"],["mouseleave","mouse"],["mousewheel","mouse"],["keydown","keyboard"],["keyup","keyboard"],["keypress","keyboard"],["textInput","keyboard"],["touchstart","touch"],["touchmove","touch"],["touchend","touch"],["touchcancel","touch"],["pointerover","pointer"],["pointerout","pointer"],["pointerenter","pointer"],["pointerleave","pointer"],["pointerdown","pointer"],["pointerup","pointer"],["pointermove","pointer"],["pointercancel","pointer"],["gotpointercapture","pointer"],["lostpointercapture","pointer"],["focus","focus"],["blur","focus"],["drag","drag"],["dragstart","drag"],["dragend","drag"],["dragover","drag"],["dragenter","drag"],["dragleave","drag"],["dragexit","drag"],["drop","drag"],["wheel","wheel"],["deviceorientation","deviceorientation"],["deviceorientationabsolute","deviceorientation"],["devicemotion","devicemotion"]]),this._hoverHitTargetInterceptorEvents=new Set(["mousemove"]),this._tapHitTargetInterceptorEvents=new Set(["pointerdown","pointerup","touchstart","touchend","touchcancel"]),this._mouseHitTargetInterceptorEvents=new Set(["mousedown","mouseup","pointerdown","pointerup","click","auxclick","dblclick","contextmenu"]),this._allHitTargetInterceptorEvents=new Set([...this._hoverHitTargetInterceptorEvents,...this._tapHitTargetInterceptorEvents,...this._mouseHitTargetInterceptorEvents]),this._engines=new Map,this._engines.set("xpath",O0),this._engines.set("xpath:light",O0),this._engines.set("_react",BE()),this._engines.set("_vue",vA()),this._engines.set("role",N0(!1)),this._engines.set("text",this._createTextEngine(!0,!1)),this._engines.set("text:light",this._createTextEngine(!1,!1)),this._engines.set("id",this._createAttributeEngine("id",!0)),this._engines.set("id:light",this._createAttributeEngine("id",!1)),this._engines.set("data-testid",this._createAttributeEngine("data-testid",!0)),this._engines.set("data-testid:light",this._createAttributeEngine("data-testid",!1)),this._engines.set("data-test-id",this._createAttributeEngine("data-test-id",!0)),this._engines.set("data-test-id:light",this._createAttributeEngine("data-test-id",!1)),this._engines.set("data-test",this._createAttributeEngine("data-test",!0)),this._engines.set("data-test:light",this._createAttributeEngine("data-test",!1)),this._engines.set("css",this._createCSSEngine()),this._engines.set("nth",{queryAll:()=>[]}),this._engines.set("visible",this._createVisibleEngine()),this._engines.set("internal:control",this._createControlEngine()),this._engines.set("internal:has",this._createHasEngine()),this._engines.set("internal:has-not",this._createHasNotEngine()),this._engines.set("internal:and",{queryAll:()=>[]}),this._engines.set("internal:or",{queryAll:()=>[]}),this._engines.set("internal:chain",this._createInternalChainEngine()),this._engines.set("internal:label",this._createInternalLabelEngine()),this._engines.set("internal:text",this._createTextEngine(!0,!0)),this._engines.set("internal:has-text",this._createInternalHasTextEngine()),this._engines.set("internal:has-not-text",this._createInternalHasNotTextEngine()),this._engines.set("internal:attr",this._createNamedAttributeEngine()),this._engines.set("internal:testid",this._createNamedAttributeEngine()),this._engines.set("internal:role",N0(!0)),this._engines.set("internal:describe",this._createDescribeEngine()),this._engines.set("aria-ref",this._createAriaRefEngine());for(const{name:r,source:l}of i.customEngines)this._engines.set(r,this.eval(l));this._stableRafCount=i.stableRafCount,this._browserName=i.browserName,this._isUtilityWorld=!!i.isUtilityWorld,FT({browserNameForWorkarounds:i.browserName}),this._setupGlobalListenersRemovalDetection(),this._setupHitTargetInterceptors(),this.isUnderTest&&(this.window.__injectedScript=this)}eval(e){return this.window.eval(e)}testIdAttributeNameForStrictErrorAndConsoleCodegen(){return this._testIdAttributeNameForStrictErrorAndConsoleCodegen}parseSelector(e){const i=cl(e);return i_(i,r=>{if(!this._engines.has(r.name))throw this.createStacklessError(`Unknown engine "${r.name}" while parsing selector ${e}`)}),i}generateSelector(e,i){return M0(this,e,i)}generateSelectorSimple(e,i){return M0(this,e,{...i,testIdAttributeName:this._testIdAttributeNameForStrictErrorAndConsoleCodegen}).selector}querySelector(e,i,r){const l=this.querySelectorAll(e,i);if(r&&l.length>1)throw this.strictModeViolationError(e,l);return this.checkDeprecatedSelectorUsage(e,l),l[0]}_queryNth(e,i){const r=[...e];let l=+i.body;return l===-1&&(l=r.length-1),new Set(r.slice(l,l+1))}_queryLayoutSelector(e,i,r){const l=i.name,o=i.body,u=[],f=this.querySelectorAll(o.parsed,r);for(const h of e){const g=mv(l,h,f,o.distance);g!==void 0&&u.push({element:h,score:g})}return u.sort((h,g)=>h.score-g.score),new Set(u.map(h=>h.element))}ariaSnapshot(e,i){return this.incrementalAriaSnapshot(e,i).full}incrementalAriaSnapshot(e,i){if(e.nodeType!==Node.ELEMENT_NODE)throw this.createStacklessError("Can only capture aria snapshot of Element nodes.");const r=Ja(e,i),l=Pa(r,i);let o;if(i.track){const u=this._lastAriaSnapshotForTrack.get(i.track);u&&(o=Pa(r,i,u)),this._lastAriaSnapshotForTrack.set(i.track,r)}return this._lastAriaSnapshotForQuery=r,{full:l,incremental:o,iframeRefs:r.iframeRefs}}ariaSnapshotForRecorder(){const e=Ja(this.document.body,{mode:"ai"});return{ariaSnapshot:Pa(e,{mode:"ai"}),refs:e.refs}}getAllElementsMatchingExpectAriaTemplate(e,i){return wE(e.documentElement,i)}querySelectorAll(e,i){if(e.capture!==void 0){if(e.parts.some(l=>l.name==="nth"))throw this.createStacklessError("Can't query n-th element in a request with the capture.");const r={parts:e.parts.slice(0,e.capture+1)};if(e.capturer.has(u)))}else if(l.name==="internal:or"){const o=this.querySelectorAll(l.body.parsed,i);r=new Set(Tv(new Set([...r,...o])))}else if(jE.includes(l.name))r=this._queryLayoutSelector(r,l,i);else{const o=new Set;for(const u of r){const f=this._queryEngineAll(l,u);for(const h of f)o.add(h)}r=o}return[...r]}finally{this._evaluator.end()}}_queryEngineAll(e,i){const r=this._engines.get(e.name).queryAll(i,e.body);for(const l of r)if(!("nodeName"in l))throw this.createStacklessError(`Expected a Node but got ${Object.prototype.toString.call(l)}`);return r}_createAttributeEngine(e,i){const r=l=>[{simples:[{selector:{css:`[${e}=${JSON.stringify(l)}]`,functions:[]},combinator:""}]}];return{queryAll:(l,o)=>this._evaluator.query({scope:l,pierceShadow:i},r(o))}}_createCSSEngine(){return{queryAll:(e,i)=>this._evaluator.query({scope:e,pierceShadow:!0},i)}}_createTextEngine(e,i){return{queryAll:(l,o)=>{const{matcher:u,kind:f}=Do(o,i),h=[];let g=null;const y=w=>{if(f==="lax"&&g&&g.contains(w))return!1;const v=wc(this._evaluator._cacheText,w,u);v==="none"&&(g=w),(v==="self"||v==="selfAndChildren"&&f==="strict"&&!i)&&h.push(w)};l.nodeType===Node.ELEMENT_NODE&&y(l);const m=this._evaluator._queryCSS({scope:l,pierceShadow:e},"*");for(const w of m)y(w);return h}}}_createInternalHasTextEngine(){return{queryAll:(e,i)=>{if(e.nodeType!==1)return[];const r=e,l=Ut(this._evaluator._cacheText,r),{matcher:o}=Do(i,!0);return o(l)?[r]:[]}}}_createInternalHasNotTextEngine(){return{queryAll:(e,i)=>{if(e.nodeType!==1)return[];const r=e,l=Ut(this._evaluator._cacheText,r),{matcher:o}=Do(i,!0);return o(l)?[]:[r]}}}_createInternalLabelEngine(){return{queryAll:(e,i)=>{const{matcher:r}=Do(i,!0);return this._evaluator._queryCSS({scope:e,pierceShadow:!0},"*").filter(o=>vv(this._evaluator._cacheText,o).some(u=>r(u)))}}}_createNamedAttributeEngine(){return{queryAll:(i,r)=>{const l=ds(r,!0);if(l.name||l.attributes.length!==1)throw new Error("Malformed attribute selector: "+r);const{name:o,value:u,caseSensitive:f}=l.attributes[0],h=f?null:u.toLowerCase();let g;return u instanceof RegExp?g=m=>!!m.match(u):f?g=m=>m===u:g=m=>m.toLowerCase().includes(h),this._evaluator._queryCSS({scope:i,pierceShadow:!0},`[${o}]`).filter(m=>g(m.getAttribute(o)))}}}_createDescribeEngine(){return{queryAll:i=>i.nodeType!==1?[]:[i]}}_createControlEngine(){return{queryAll(e,i){if(i==="enter-frame")return[];if(i==="return-empty")return[];if(i==="component")return e.nodeType!==1?[]:[e.childElementCount===1?e.firstElementChild:e];throw new Error(`Internal error, unknown internal:control selector ${i}`)}}}_createHasEngine(){return{queryAll:(i,r)=>i.nodeType!==1?[]:!!this.querySelector(r.parsed,i,!1)?[i]:[]}}_createHasNotEngine(){return{queryAll:(i,r)=>i.nodeType!==1?[]:!!this.querySelector(r.parsed,i,!1)?[]:[i]}}_createVisibleEngine(){return{queryAll:(i,r)=>{if(i.nodeType!==1)return[];const l=r==="true";return ji(i)===l?[i]:[]}}}_createInternalChainEngine(){return{queryAll:(i,r)=>this.querySelectorAll(r.parsed,i)}}extend(e,i){const r=this.window.eval(` + (() => { + const module = {}; + ${e} + return module.exports.default(); + })()`);return new r(this,i)}async viewportRatio(e){return await new Promise(i=>{const r=new IntersectionObserver(l=>{i(l[0].intersectionRatio),r.disconnect()});r.observe(e),this.utils.builtins.requestAnimationFrame(()=>{})})}getElementBorderWidth(e){if(e.nodeType!==Node.ELEMENT_NODE||!e.ownerDocument||!e.ownerDocument.defaultView)return{left:0,top:0};const i=e.ownerDocument.defaultView.getComputedStyle(e);return{left:parseInt(i.borderLeftWidth||"",10),top:parseInt(i.borderTopWidth||"",10)}}describeIFrameStyle(e){if(!e.ownerDocument||!e.ownerDocument.defaultView)return"error:notconnected";const i=e.ownerDocument.defaultView;for(let l=e;l;l=bt(l))if(i.getComputedStyle(l).transform!=="none")return"transformed";const r=i.getComputedStyle(e);return{left:parseInt(r.borderLeftWidth||"",10)+parseInt(r.paddingLeft||"",10),top:parseInt(r.borderTopWidth||"",10)+parseInt(r.paddingTop||"",10)}}retarget(e,i){let r=e.nodeType===Node.ELEMENT_NODE?e:e.parentElement;if(!r)return null;if(i==="none")return r;if(!r.matches("input, textarea, select")&&!r.isContentEditable&&(i==="button-link"?r=r.closest("button, [role=button], a, [role=link]")||r:r=r.closest("button, [role=button], [role=checkbox], [role=radio]")||r),i==="follow-label"&&!r.matches("a, input, textarea, button, select, [role=link], [role=button], [role=checkbox], [role=radio]")&&!r.isContentEditable){const l=r.closest("label");l&&l.control&&(r=l.control)}return r}async checkElementStates(e,i){if(i.includes("stable")){const r=await this._checkElementIsStable(e);if(r===!1)return{missingState:"stable"};if(r==="error:notconnected")return"error:notconnected"}for(const r of i)if(r!=="stable"){const l=this.elementState(e,r);if(l.received==="error:notconnected")return"error:notconnected";if(!l.matches)return{missingState:r}}}async _checkElementIsStable(e){const i=Symbol("continuePolling");let r,l=0,o=0;const u=()=>{const m=this.retarget(e,"no-follow-label");if(!m)return"error:notconnected";const w=this.utils.builtins.performance.now();if(this._stableRafCount>1&&w-o<15)return i;o=w;const v=m.getBoundingClientRect(),E={x:v.top,y:v.left,width:v.width,height:v.height};if(r){if(!(E.x===r.x&&E.y===r.y&&E.width===r.width&&E.height===r.height))return!1;if(++l>=this._stableRafCount)return!0}return r=E,i};let f,h;const g=new Promise((m,w)=>{f=m,h=w}),y=()=>{try{const m=u();m!==i?f(m):this.utils.builtins.requestAnimationFrame(y)}catch(m){h(m)}};return this.utils.builtins.requestAnimationFrame(y),g}_createAriaRefEngine(){return{queryAll:(i,r)=>{var o,u;const l=(u=(o=this._lastAriaSnapshotForQuery)==null?void 0:o.elements)==null?void 0:u.get(r);return l&&l.isConnected?[l]:[]}}}elementState(e,i){const r=this.retarget(e,["visible","hidden"].includes(i)?"none":"follow-label");if(!r||!r.isConnected)return i==="hidden"?{matches:!0,received:"hidden"}:{matches:!1,received:"error:notconnected"};if(i==="visible"||i==="hidden"){const l=ji(r);return{matches:i==="visible"?l:!l,received:l?"visible":"hidden"}}if(i==="disabled"||i==="enabled"){const l=uc(r);return{matches:i==="disabled"?l:!l,received:l?"disabled":"enabled"}}if(i==="editable"){const l=uc(r),o=cE(r);if(o==="error")throw this.createStacklessError("Element is not an , 0 / 200
平台客服
纠错反馈
\ No newline at end of file diff --git a/skills/playwright-scraper-skill-1-2-0/scripts/playwright-simple.js b/skills/playwright-scraper-skill-1-2-0/scripts/playwright-simple.js new file mode 100644 index 0000000..fb96b55 --- /dev/null +++ b/skills/playwright-scraper-skill-1-2-0/scripts/playwright-simple.js @@ -0,0 +1,60 @@ +#!/usr/bin/env node +/** + * Playwright Simple Scraper + * 適用:一般動態網站,無反爬保護 + * 速度:快(3-5 秒) + * + * Usage: node playwright-simple.js + */ + +const { chromium } = require('playwright'); + +const url = process.argv[2]; +const waitTime = parseInt(process.env.WAIT_TIME || '3000'); +const screenshotPath = process.env.SCREENSHOT_PATH; + +if (!url) { + console.error('❌ 請提供 URL'); + console.error('用法: node playwright-simple.js '); + process.exit(1); +} + +(async () => { + console.log('🚀 啟動 Playwright 簡單版爬蟲...'); + const startTime = Date.now(); + + const browser = await chromium.launch({ + headless: process.env.HEADLESS !== 'false' + }); + const page = await browser.newPage(); + + console.log(`📱 導航到: ${url}`); + await page.goto(url, { waitUntil: 'domcontentloaded' }); + + console.log(`⏳ 等待 ${waitTime}ms...`); + await page.waitForTimeout(waitTime); + + // 擷取基本資訊 + const result = await page.evaluate(() => { + return { + title: document.title, + url: window.location.href, + content: document.body.innerText.substring(0, 5000), + metaDescription: document.querySelector('meta[name="description"]')?.content || '', + }; + }); + + // 截圖(如果指定) + if (screenshotPath) { + await page.screenshot({ path: screenshotPath }); + console.log(`📸 截圖已儲存: ${screenshotPath}`); + } + + const elapsed = ((Date.now() - startTime) / 1000).toFixed(2); + result.elapsedSeconds = elapsed; + + console.log('\n✅ 爬取完成!'); + console.log(JSON.stringify(result, null, 2)); + + await browser.close(); +})(); diff --git a/skills/playwright-scraper-skill-1-2-0/scripts/playwright-stealth.js b/skills/playwright-scraper-skill-1-2-0/scripts/playwright-stealth.js new file mode 100644 index 0000000..7beb4ee --- /dev/null +++ b/skills/playwright-scraper-skill-1-2-0/scripts/playwright-stealth.js @@ -0,0 +1,167 @@ +#!/usr/bin/env node +/** + * Playwright Stealth Scraper + * 適用:有 Cloudflare 或反爬保護的網站 + * 速度:中等(5-10 秒) + * 反爬能力:中(隱藏自動化、真實 UA) + * + * Usage: node playwright-stealth.js + * + * 環境變數: + * - HEADLESS=false 顯示瀏覽器 + * - WAIT_TIME=10000 等待時間(毫秒) + * - SCREENSHOT_PATH=... 截圖路徑 + * - SAVE_HTML=true 儲存 HTML + * - USER_AGENT=... 自訂 User-Agent + */ + +const { chromium } = require('playwright'); +const fs = require('fs'); +const path = require('path'); + +const url = process.argv[2]; +const waitTime = parseInt(process.env.WAIT_TIME || '5000'); +const headless = process.env.HEADLESS !== 'false'; +const screenshotPath = process.env.SCREENSHOT_PATH || `./screenshot-${Date.now()}.png`; +const saveHtml = process.env.SAVE_HTML === 'true'; + +// 預設 User-Agent(iPhone) +const defaultUA = 'Mozilla/5.0 (iPhone; CPU iPhone OS 17_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.0 Mobile/15E148 Safari/604.1'; +const userAgent = process.env.USER_AGENT || defaultUA; + +if (!url) { + console.error('❌ 請提供 URL'); + console.error('用法: node playwright-stealth.js '); + process.exit(1); +} + +(async () => { + console.log('🕷️ 啟動 Playwright Stealth 爬蟲...'); + console.log(`🔒 反爬模式: ${headless ? '無頭' : '有頭'}`); + const startTime = Date.now(); + + const browser = await chromium.launch({ + headless: headless, + args: [ + '--no-sandbox', + '--disable-setuid-sandbox', + '--disable-blink-features=AutomationControlled', + '--disable-features=IsolateOrigins,site-per-process', + ], + }); + + const context = await browser.newContext({ + userAgent: userAgent, + locale: 'zh-HK', + viewport: { width: 375, height: 812 }, // iPhone size + extraHTTPHeaders: { + 'Accept-Language': 'zh-HK,zh-TW;q=0.9,zh;q=0.8,en;q=0.7', + 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8', + }, + }); + + // 隱藏自動化特徵 + await context.addInitScript(() => { + Object.defineProperty(navigator, 'webdriver', { + get: () => false, + }); + + window.chrome = { runtime: {} }; + + // Mock permissions + const originalQuery = window.navigator.permissions.query; + window.navigator.permissions.query = (parameters) => ( + parameters.name === 'notifications' ? + Promise.resolve({ state: Notification.permission }) : + originalQuery(parameters) + ); + }); + + const page = await context.newPage(); + + console.log(`📱 導航到: ${url}`); + try { + const response = await page.goto(url, { + waitUntil: 'domcontentloaded', + timeout: 30000, + }); + + console.log(`📡 HTTP Status: ${response.status()}`); + + if (response.status() === 403) { + console.log('⚠️ 收到 403,但繼續嘗試...'); + } + + } catch (error) { + console.error(`❌ 導航失敗: ${error.message}`); + } + + console.log(`⏳ 等待 ${waitTime}ms 讓內容載入...`); + await page.waitForTimeout(waitTime); + + // 檢查 Cloudflare + const cloudflare = await page.evaluate(() => { + return document.body.innerText.includes('Checking your browser') || + document.body.innerText.includes('Just a moment') || + document.querySelector('iframe[src*="challenges.cloudflare.com"]') !== null; + }); + + if (cloudflare) { + console.log('🛡️ 偵測到 Cloudflare 挑戰,等待額外 10 秒...'); + await page.waitForTimeout(10000); + } + + // 擷取資訊 + const result = await page.evaluate(() => { + return { + title: document.title, + url: window.location.href, + htmlLength: document.documentElement.outerHTML.length, + contentPreview: document.body.innerText.substring(0, 1000), + }; + }); + + result.cloudflare = cloudflare; + + // 截圖 + try { + await page.screenshot({ path: screenshotPath, fullPage: false, timeout: 10000 }); + console.log(`📸 截圖已儲存: ${screenshotPath}`); + result.screenshot = screenshotPath; + } catch (error) { + console.log(`⚠️ 截圖失敗: ${error.message}`); + result.screenshot = null; + } + + // 儲存 HTML(如果需要) + if (saveHtml) { + const htmlPath = screenshotPath.replace(/\.[^.]+$/, '.html'); + const html = await page.content(); + fs.writeFileSync(htmlPath, html); + console.log(`📄 HTML 已儲存: ${htmlPath}`); + result.htmlFile = htmlPath; + } + + // 嘗試提取結構化資料(依網站調整) + const customData = await page.evaluate(() => { + // 範例:提取所有連結 + const links = Array.from(document.querySelectorAll('a[href*="tid="]')) + .slice(0, 10) + .map(a => ({ + text: a.innerText.trim().substring(0, 100), + href: a.href, + })); + + return { links }; + }); + + result.data = customData; + + const elapsed = ((Date.now() - startTime) / 1000).toFixed(2); + result.elapsedSeconds = elapsed; + + console.log('\n✅ 爬取完成!'); + console.log(JSON.stringify(result, null, 2)); + + await browser.close(); +})(); diff --git a/skills/playwright-scraper-skill-1-2-0/test.sh b/skills/playwright-scraper-skill-1-2-0/test.sh new file mode 100644 index 0000000..cd1fab4 --- /dev/null +++ b/skills/playwright-scraper-skill-1-2-0/test.sh @@ -0,0 +1,45 @@ +#!/bin/bash +# 簡單測試腳本 + +set -e + +echo "🧪 Playwright Scraper Skill 測試" +echo "" + +# 測試 1: Playwright Simple +echo "📝 測試 1: Playwright Simple (Example.com)" +node scripts/playwright-simple.js https://example.com > /tmp/test-simple.json +if grep -q "Example Domain" /tmp/test-simple.json; then + echo "✅ Simple 模式正常" +else + echo "❌ Simple 模式失敗" + exit 1 +fi +echo "" + +# 測試 2: Playwright Stealth +echo "📝 測試 2: Playwright Stealth (Example.com)" +node scripts/playwright-stealth.js https://example.com > /tmp/test-stealth.json +if grep -q "Example Domain" /tmp/test-stealth.json; then + echo "✅ Stealth 模式正常" +else + echo "❌ Stealth 模式失敗" + exit 1 +fi +echo "" + +# 測試 3: 環境變數 +echo "📝 測試 3: 環境變數 (WAIT_TIME)" +WAIT_TIME=1000 node scripts/playwright-simple.js https://example.com > /tmp/test-env.json +if grep -q "Example Domain" /tmp/test-env.json; then + echo "✅ 環境變數正常" +else + echo "❌ 環境變數失敗" + exit 1 +fi +echo "" + +# 清理 +rm -f /tmp/test-*.json screenshot-*.png + +echo "✅ 所有測試通過!" diff --git a/skills/pm-agent/README.md b/skills/pm-agent/README.md new file mode 100644 index 0000000..af47162 --- /dev/null +++ b/skills/pm-agent/README.md @@ -0,0 +1,83 @@ +# Product Manager Skills + +An AI-native product manager agent. Install it, and your AI becomes a senior PM — it knows when to use which framework, asks the right questions, and delivers structured artifacts. + +## What It Covers + +| Domain | Examples | +|--------|----------| +| **Discovery & Research** | Problem framing, customer interviews, JTBD, opportunity mapping, Lean validation, PoL probes | +| **Strategy & Positioning** | Positioning statements, PESTEL, TAM/SAM/SOM, prioritization, roadmap planning | +| **Artifacts & Delivery** | PRDs, user stories, epics, story mapping, press releases, storyboards, EOL comms | +| **Finance & Metrics** | 30+ SaaS metrics, business health diagnostics, feature ROI, channel economics, pricing | +| **Career & Leadership** | PM→Director transition, VP/CPO readiness, executive onboarding (30-60-90) | +| **AI Product Craft** | AI-shaped readiness, context engineering, agent orchestration, AI validation | + +## Install + +### Claude Code / OpenClaw +```bash +# OpenClaw +clawhub install product-manager + +# Or manually — copy to your project +cp -r product-manager-skills/ your-project/ +``` + +### Claude Projects +Upload `SKILL.md` plus the `knowledge/` and `templates/` folders to your project knowledge. + +### Any LLM +Point your system prompt at `SKILL.md`. It will load knowledge modules and templates on demand. + +## How It Works + +1. **You describe your need** — "Write a PRD for mobile notifications" or "Is our SaaS healthy?" +2. **The agent routes to the right framework** — via the routing table in `SKILL.md` +3. **It loads domain knowledge on demand** — only the relevant module, not everything +4. **It delivers structured output** — using templates when appropriate, always with next steps + +No browsing, no selecting, no manual loading. Just ask. + +## Structure + +``` +SKILL.md # PM brain — routing, interaction protocol, quality gates +knowledge/ # 6 domain modules, loaded on demand + discovery-research.md + strategy-positioning.md + artifacts-delivery.md + finance-metrics.md + career-leadership.md + ai-product-craft.md +templates/ # 10 output templates + prd.md + user-story.md + problem-statement.md + positioning-statement.md + epic-hypothesis.md + press-release.md + discovery-interview-plan.md + opportunity-solution-tree.md + roadmap-plan.md + business-health-scorecard.md +``` + +18 files. ~2,200 lines. Everything a PM agent needs, nothing it doesn't. + +## Try It + +``` +"Help me validate a customer problem" +"Write a PRD for [feature]" +"Are our SaaS metrics healthy?" +"I'm interviewing for a Director role next week" +"Break down this epic into stories" +"What prioritization framework should I use?" +``` + +## License + +[CC BY-NC-SA 4.0](LICENSE) — Use freely for non-commercial purposes. Attribution required. + +Built by [Gene Dai](https://genedai.me/). Distilled from real PM practice, not textbooks. diff --git a/skills/pm-agent/SKILL.md b/skills/pm-agent/SKILL.md new file mode 100644 index 0000000..f0b6edc --- /dev/null +++ b/skills/pm-agent/SKILL.md @@ -0,0 +1,210 @@ +--- +name: product-manager +description: AI-native PM agent — PRD, user stories, roadmaps, discovery, 32 SaaS metrics, positioning, career ladder (PM→Director→CPO), and AI product strategy. Six knowledge domains, one skill. +type: workflow +--- + +# Product Manager + +## Identity + +You are a senior product manager. Not a tool — a PM. + +**Operating principles:** +- Outcome-oriented, not output-oriented. "What decision does this enable?" before "What document should I produce?" +- Evidence-driven. State assumptions explicitly. Label what's known vs. hypothesized. +- Opinionated with tradeoffs. Take a stance, name the tradeoff, never hedge with "it depends" alone. +- Specific > complete. One sharp example beats a page of generic advice. +- Compression by default. Say it in 3 bullets, not 3 paragraphs. Expand only when asked. +- Bias to action. End every interaction with a next step, not a summary. + +**What you are NOT:** +- A template filler. Templates are scaffolding — the thinking matters more than the format. +- A yes-machine. Push back when the user's framing is off, the scope is wrong, or the problem isn't clear. +- A knowledge dump. Don't recite frameworks — apply them to the user's specific situation. + +--- + +## Interaction Protocol + +**Simple requests → direct output.** If the user asks for a user story, write one. Don't ask 10 setup questions. + +**Complex requests → choose a mode:** + +1. **Guided mode** — One question at a time, with progress labels (`Q1/6`, `Q2/6`). Best for discovery, diagnostics, strategy sessions. +2. **Context dump** — User pastes everything they know. You skip redundant questions, fill gaps, deliver output. +3. **Best guess** — You infer missing details, label every assumption with `[assumption]`, deliver immediately. User validates after. + +**How to pick the mode:** +- If the request is ambiguous or multi-dimensional → offer the three modes, let user choose. +- If the request is clear but needs 2-3 inputs → ask those directly, no ceremony. +- If the user says "just do it" → best guess mode, assumptions labeled. + +**During guided sessions:** +- One question per turn. Wait for answer before continuing. +- Show progress: `Context Q3/7` or `Assessment Q2/4`. +- At decision points, offer 3-5 numbered options. Accept `1`, `2 and 4`, `1,3`, or custom text. +- If interrupted ("how many questions left?"), answer directly, restate progress, resume. +- If user says stop/pause, halt immediately. Resume on explicit request. +- If user switches topic mid-flow, acknowledge the pivot, confirm abandoning current flow, and re-route. + +**Language:** Respond in the user's language. If they write in Chinese, respond in Chinese. If English, respond in English. + +**Every output ends with:** +- Decisions made (bullet list) +- Assumptions to validate (if any) +- Recommended next step + +--- + +## Execution Workflow + +When the user makes a request, follow this sequence: + +1. **Route:** Match intent to a framework in the Routing Table below. If ambiguous, ask one clarifying question. If clearly outside PM scope, say so and offer to redirect. +2. **Load knowledge:** Read the knowledge module file listed in the "Load" column. In pre-loaded environments (e.g., Claude Projects), the content is already in context — search by section name. The `knowledge/` and `templates/` directories are siblings of this SKILL.md file. +3. **Focus:** Within the loaded module, find the section closest to the Framework column name. If the route maps to multiple sections (e.g., "A + B"), read both. Apply that section's framework, decision logic, and domain-specific quality gates. +4. **Interact:** Use the Interaction Protocol above — direct output for simple requests, guided/dump/guess for complex ones. +5. **Template:** If producing a deliverable artifact (PRD, user story, positioning statement, etc.), also load the matching template from the Template Index. If no template exists for the artifact type, structure the output using the framework in the knowledge module. +6. **Quality check:** Apply the Universal Quality Gates (bottom of this file) to every output. The loaded knowledge module also has domain-specific quality gates — apply those too. +7. **Close:** End with decisions made, assumptions to validate, and recommended next step. + +**Multi-domain requests:** When intent spans two domains (e.g., "roadmap for an AI product"), the explicit ask determines the primary domain (roadmap → strategy). Load primary first. Mention secondary and offer to load it after the primary task completes. + +--- + +## Routing Table + +Match user intent to a framework and knowledge module. + +### Discovery & Research + +| User Intent | Framework | Load | +|---|---|---| +| "Validate a problem" / "test a hypothesis" | Problem Framing + PoL Probe Advisor | `knowledge/discovery-research.md` | +| "Customer interview" / "discovery interview" | Interview Prep | `knowledge/discovery-research.md` | +| "Map the customer journey" | Customer Journey > Journey Map / Journey Mapping Workshop | `knowledge/discovery-research.md` | +| "Opportunity mapping" / "solution tree" | Opportunity Solution Tree | `knowledge/discovery-research.md` | +| "Jobs to be done" / "JTBD" / "customer needs" | JTBD Framework | `knowledge/discovery-research.md` | +| "Frame the problem" / "problem canvas" | Problem Framing Canvas (MITRE) | `knowledge/discovery-research.md` | +| "Write a problem statement" | Problem Statement | `knowledge/discovery-research.md` | +| "Lean canvas" / "validate assumptions" | Lean UX Canvas | `knowledge/discovery-research.md` | +| "Run a discovery cycle" / "discovery sprint" | Discovery Process | `knowledge/discovery-research.md` | +| "PoL probe" / "proof of life" / "validation experiment" | PoL Probe Advisor | `knowledge/discovery-research.md` | +| "A/B test" / "experiment design" / "test plan" | PoL Probe Advisor | `knowledge/discovery-research.md` | + +### Strategy & Positioning + +| User Intent | Framework | Load | +|---|---|---| +| "Position my product" / "positioning statement" | Geoffrey Moore Positioning Statement | `knowledge/strategy-positioning.md` | +| "Positioning workshop" / "find our position" | Positioning Workshop Flow | `knowledge/strategy-positioning.md` | +| "Product strategy" / "strategy session" / "GTM strategy" | Strategy Session Phases | `knowledge/strategy-positioning.md` | +| "Research a company" / "competitive intel" / "competitive analysis" | Company Research Framework | `knowledge/strategy-positioning.md` | +| "PESTEL" / "macro environment" / "external factors" | PESTEL Analysis | `knowledge/strategy-positioning.md` | +| "Prioritize" / "prioritization framework" / "what to build next" | Prioritization > Framework Selection Matrix | `knowledge/strategy-positioning.md` | +| "Roadmap" / "roadmap planning" / "release plan" | Roadmap Planning Process | `knowledge/strategy-positioning.md` | +| "TAM SAM SOM" / "market size" / "addressable market" | TAM/SAM/SOM Calculation | `knowledge/strategy-positioning.md` | + +### Artifacts & Delivery + +| User Intent | Framework | Load | +|---|---|---| +| "Write a PRD" / "product requirements" | PRD Development | `knowledge/artifacts-delivery.md` | +| "Write a user story" / "acceptance criteria" | User Story (Cohn + Gherkin) | `knowledge/artifacts-delivery.md` | +| "Split this story" / "story too big" | User Story Splitting (8 patterns) | `knowledge/artifacts-delivery.md` | +| "Story map" / "user story mapping" | User Story Mapping | `knowledge/artifacts-delivery.md` | +| "Epic" / "epic hypothesis" / "frame this epic" | Epics > Epic Hypothesis | `knowledge/artifacts-delivery.md` | +| "Break down this epic" / "epic breakdown" | Epics > Epic Breakdown (9 Patterns) | `knowledge/artifacts-delivery.md` | +| "Proto-persona" / "persona" / "who is the user" | Proto-Persona | `knowledge/artifacts-delivery.md` | +| "Press release" / "PRFAQ" / "working backwards" | Press Release / PRFAQ | `knowledge/artifacts-delivery.md` | +| "Storyboard" / "visual narrative" | Storyboards | `knowledge/artifacts-delivery.md` | +| "Recommendation canvas" / "solution proposal" | Recommendation Canvas | `knowledge/artifacts-delivery.md` | +| "EOL" / "end of life" / "sunset" / "deprecation" | End-of-Life Communication | `knowledge/artifacts-delivery.md` | + +### Finance & Metrics + +| User Intent | Framework | Load | +|---|---|---| +| "SaaS metrics" / "revenue metrics" / "MRR" / "ARR" | SaaS Revenue & Growth Metrics | `knowledge/finance-metrics.md` | +| "Unit economics" / "CAC" / "LTV" / "payback" | Unit Economics & Efficiency | `knowledge/finance-metrics.md` | +| "Business health" / "diagnostic" / "board meeting prep" | Business Health Diagnostic | `knowledge/finance-metrics.md` | +| "Feature ROI" / "should we build this" / "investment case" | Feature Investment Analysis | `knowledge/finance-metrics.md` | +| "Acquisition channel" / "channel ROI" / "marketing spend" | Channel Economics | `knowledge/finance-metrics.md` | +| "Pricing" / "price change" / "ARPU impact" | Pricing Analysis | `knowledge/finance-metrics.md` | +| "Rule of 40" / "magic number" / "burn rate" | Capital Efficiency (Unit Economics) | `knowledge/finance-metrics.md` | +| "Retention" / "churn" / "why are users leaving" | Retention & Expansion Metrics + Business Health Diagnostic | `knowledge/finance-metrics.md` | +| "NRR" / "net revenue retention" / "expansion revenue" | Retention & Expansion Metrics | `knowledge/finance-metrics.md` | + +### Career & Leadership + +| User Intent | Framework | Load | +|---|---|---| +| "PM to Director" / "director transition" / "altitude horizon" | Altitude-Horizon Framework | `knowledge/career-leadership.md` | +| "Director interview" / "director readiness" / "preparing for Director" | PM to Director Transition | `knowledge/career-leadership.md` | +| "VP" / "CPO" / "executive transition" | Director to VP/CPO Transition | `knowledge/career-leadership.md` | +| "New role" / "first 90 days" / "onboarding as VP" / "onboarding as CPO" | Executive Onboarding (30-60-90) | `knowledge/career-leadership.md` | +| "Career advice" / "next step in my career" | Altitude-Horizon + Readiness Coaching | `knowledge/career-leadership.md` | + +### AI Product Craft + +| User Intent | Framework | Load | +|---|---|---| +| "AI product" / "AI-shaped" / "AI readiness" | AI-Shaped Readiness | `knowledge/ai-product-craft.md` | +| "Context engineering" / "context stuffing" / "prompt design" | Context Engineering | `knowledge/ai-product-craft.md` | +| "Agent workflow" / "multi-agent" / "AI orchestration" | Agent Orchestration | `knowledge/ai-product-craft.md` | +| "AI validation" / "test my AI feature" | AI Validation (PoL Probes) | `knowledge/ai-product-craft.md` | + +**Routing rules:** +1. If intent matches multiple domains, the explicit ask determines primary (see Execution Workflow above). +2. If intent is unclear, ask one clarifying question before loading. +3. If no match, use general PM reasoning and the Quality Gates below. Don't hallucinate a framework. + +--- + +## Template Index + +When producing a deliverable artifact, load the matching template and fill it with the user's specific content. Templates are pure scaffolding — not generic placeholders. + +| Template | Path | Use When | +|---|---|---| +| PRD | `templates/prd.md` | Writing product requirements documents | +| User Story | `templates/user-story.md` | Creating stories with acceptance criteria | +| Problem Statement | `templates/problem-statement.md` | Framing a user problem empathetically | +| Positioning Statement | `templates/positioning-statement.md` | Defining product market position | +| Epic Hypothesis | `templates/epic-hypothesis.md` | Framing epics as testable hypotheses | +| Press Release | `templates/press-release.md` | Working Backwards / PRFAQ | +| Discovery Interview Plan | `templates/discovery-interview-plan.md` | Preparing for customer interviews | +| Opportunity Solution Tree | `templates/opportunity-solution-tree.md` | Mapping outcomes → opportunities → solutions | +| Roadmap Plan | `templates/roadmap-plan.md` | Building Now/Next/Later roadmaps | +| Business Health Scorecard | `templates/business-health-scorecard.md` | Diagnosing SaaS business health | + +--- + +## Quality Gates + +Two tiers: **universal gates** (below, apply to every output) and **domain gates** (in each knowledge module's Quality Gates section, apply when that module is loaded). Always check both. + +### Universal Gates + +#### 1. Assumptions Must Be Labeled +If you're guessing, say so. Mark assumptions with `[assumption]` inline. Never present inferred data as fact. + +#### 2. Outcomes Must Be Measurable +"Improve the experience" is not a success metric. Every outcome needs a number, a direction, and a timeframe. "Reduce time-to-first-value from 14 days to 3 days within Q2." + +#### 3. Roles Must Be Specific +"Users" is not a persona. Every artifact must name the role, context, and motivation. "A mid-market ops manager running 3 product lines with no dedicated analytics support" — that's specific. + +#### 4. Tradeoffs Must Be Named +Never present a recommendation without naming what you're trading off. "Recommend Option A (faster to market, lower initial quality) over Option B (more robust, 6-week delay)." + +#### 5. Anti-Patterns to Flag +When you spot these in user input, call them out directly: +- **Metrics Theater** — tracking metrics that look good but drive no decisions +- **Feature Factory** — shipping features without validating the problem +- **Stakeholder-Driven Roadmap** — roadmap shaped by loudest voice, not evidence +- **Confirmation Bias in Discovery** — asking questions designed to confirm existing beliefs +- **Premature Scaling** — optimizing growth before unit economics work +- **Horizontal Slicing** — splitting work by architecture layer instead of user value +- **Solution Smuggling** — problem statements that embed a solution ("We need a dashboard" vs "Managers can't see team velocity") diff --git a/skills/pm-agent/_meta.json b/skills/pm-agent/_meta.json new file mode 100644 index 0000000..a18d10f --- /dev/null +++ b/skills/pm-agent/_meta.json @@ -0,0 +1,6 @@ +{ + "ownerId": "kn73ekpzsj882ce5a0kk31jxsx827vz3", + "slug": "pm-agent", + "version": "1.1.0", + "publishedAt": 1772555181756 +} \ No newline at end of file diff --git a/skills/pm-agent/knowledge/ai-product-craft.md b/skills/pm-agent/knowledge/ai-product-craft.md new file mode 100644 index 0000000..4784c20 --- /dev/null +++ b/skills/pm-agent/knowledge/ai-product-craft.md @@ -0,0 +1,265 @@ +# AI Product Craft + +Compressed decision logic for AI product managers: readiness assessment, context architecture, orchestration patterns, and validation methodology. Derived from ai-shaped-readiness-advisor, context-engineering-advisor, and pol-probe-advisor. + +--- + +## AI-Shaped Readiness + +### AI-First vs. AI-Shaped + +| Dimension | AI-First (table stakes) | AI-Shaped (defensible) | +|-----------|------------------------|------------------------| +| Mindset | Automate existing tasks | Redesign how work gets done | +| Goal | Speed up artifact creation | Compress learning cycles | +| AI Role | Task assistant | Strategic co-intelligence | +| Test | Competitor replicates by adding headcount | Competitor must redesign entire org | + +### The 5 Competencies + +**1. Context Design** — Build a durable "reality layer" humans and AI both trust. Treat AI attention as scarce. Persist constraints + glossary; retrieve everything else on demand. Foundational: blocks all other competencies if missing. + +**2. Agent Orchestration** — Repeatable, traceable AI workflows (research -> synthesis -> critique -> decision -> log rationale). Version-controlled prompts. Each step shows its work. One-off prompts are tactical; orchestrated workflows are strategic. + +**3. Outcome Acceleration** — Compress learning cycles, not just task speed. Eliminate validation lag (PoL probes in days, not weeks). Remove approval delays (AI pre-validates against constraints). Cut meeting overhead (async AI synthesis). + +**4. Team-AI Facilitation** — AI operates as co-intelligence, not accountability shield. Review norms (AI outputs = drafts). Evidence standards (cite sources, reject "I think"). Decision authority (AI recommends, humans decide). Psychological safety to challenge AI. + +**5. Strategic Differentiation** — New customer capabilities competitors can't replicate by throwing bodies at it. Workflow rewiring requiring full org redesign to copy. Economics competitors can't match (10x cost advantage through AI). + +### Maturity Levels (per competency) + +- **Level 1 — AI-First:** One-off prompts, no structure, efficiency only +- **Level 2 — Emerging:** Some saved prompts/templates, scattered docs, modest gains +- **Level 3 — Transitioning:** Multi-step workflows, structured context, learning cycles compressing +- **Level 4 — AI-Shaped:** Autonomous orchestrated workflows, durable reality layer, defensible moat + +### Priority Dependency Chain + +``` +Context Design (foundation) + └─> Agent Orchestration (requires context) + └─> Outcome Acceleration (requires orchestration) + └─> Strategic Differentiation (requires all above) +Team-AI Facilitation ──── (parallel track, required for scale) +``` + +If Context Design is Level 1-2, fix it first. Everything else is fragile without it. + +--- + +## Context Engineering + +### Context Stuffing vs. Context Engineering + +| Dimension | Stuffing | Engineering | +|-----------|----------|-------------| +| Mindset | Volume = quality | Structure = quality | +| Approach | "Add everything just in case" | "What decision am I making?" | +| Persistence | Persist all context | Retrieve with intent | +| Agent chains | Share everything between agents | Bounded context per agent | +| Failure response | Retry until it works | Fix the structure | +| Economic model | Context as storage | Context as attention (scarce) | + +**Why stuffing fails:** Accuracy degrades significantly as context grows — models prioritize beginning and end, ignore the middle (Liu et al. 2023, "Lost in the Middle"). Dead ends and errors accumulate (context rot). Retries become normalized. + +### 5 Diagnostic Questions + +1. **What specific decision does this support?** Can't answer = don't need it. +2. **Can retrieval replace persistence?** Just-in-time beats always-available. +3. **Who owns the context boundary?** No owner = unbounded growth. +4. **What fails if we exclude this?** No concrete failure = delete it. +5. **Are we fixing structure or avoiding it?** Stuffing often masks bad info architecture. + +### Persist vs. Retrieve Rule + +- **Persist (80%+ of interactions):** Core constraints, user preferences, operational glossary, non-negotiable rules +- **Retrieve (<20% of interactions):** Project details, historical PRDs, competitive analysis, past transcripts +- **Gray zone (20-80%):** Weigh retrieval latency vs. context window cost + +### Two-Layer Memory Architecture + +**Short-term (conversational):** Immediate interaction history. Single session. Summarize/truncate older parts. + +**Long-term (persistent):** Constraints registry + operational glossary + user preferences. Vector database for semantic retrieval. Two subtypes: +- Declarative: facts ("We follow HIPAA") +- Procedural: patterns ("Always validate feasibility before usability") + +### Research -> Plan -> Reset -> Implement Cycle + +The core context rot prevention pattern: + +1. **Research:** Agent gathers data. Context grows large and messy. Expected. +2. **Plan:** Synthesize into high-density SPEC.md/PLAN.md (source of truth). +3. **Reset:** Clear entire context window. Non-negotiable. +4. **Implement:** Fresh session with only the plan as context. + +**Why it works:** Eliminates context rot, dead ends, and goal drift. Agent starts clean with compressed, high-signal context. + +### Efficiency Formula + +``` +Context Efficiency = (Accuracy x Coherence) / (Tokens x Latency) +``` + +Key finding: RAG with 25% of available tokens preserves 95% accuracy while cutting latency and cost. + +### Context Manifest Template + +``` +Always Persisted: constraints (technical, regulatory), user prefs, glossary +Retrieved On-Demand: historical PRDs, transcripts, competitive analysis +Excluded: meeting notes >30 days, full codebase, marketing materials +Boundary Owner: [Name] +Next Review: [Date + 90 days] +``` + +--- + +## Agent Orchestration + +### Core Workflow Pattern + +``` +Research -> Synthesis -> Critique -> Decision -> Log Rationale +``` + +Each step must be: traceable (cites sources), bounded (own context window), version-controlled (prompts in Git), consistent (same inputs -> predictable process). + +### Maturity Progression + +1. **Ad-hoc prompts:** Type into ChatGPT as needed. No reuse. +2. **Saved templates:** Reusable prompts, custom GPTs/Claude Projects. Manual steps. +3. **Multi-step workflows:** Research -> synthesis -> critique. Manual handoffs between steps. +4. **Autonomous orchestration:** Runs end-to-end. Traceable. Version-controlled. Auditable. + +### Bounded Context per Agent + +Anti-pattern: Agent A passes everything to Agent B to Agent C (context window explodes to 100k+). + +Fix: Each agent outputs a bounded synthesis (2-page max) to the next agent. Apply Research->Plan->Reset->Implement between agent handoffs. + +### Building Your First Orchestrated Workflow + +1. Pick most frequent AI use case +2. Document every step you currently take manually +3. Design loop: research -> synthesis -> critique -> decision -> log +4. Implement (Claude Projects for simple; API orchestration for complex) +5. Run on 3 past examples; compare to manual process +6. Version-control prompts; train 2 teammates; iterate + +--- + +## AI Validation (PoL Probes) + +### The 5 Probe Types + +| Probe | Core Question | Timeline | AI-Specific Use | +|-------|---------------|----------|-----------------| +| **Feasibility Check** | Can we build this? | 1-2 days | GenAI prompt chains, API sniff tests, data integrity sweeps | +| **Task-Focused Test** | Can users complete this without friction? | 2-5 days | Test AI-generated UIs, chatbot flows, recommendation quality | +| **Narrative Prototype** | Does this earn buy-in? | 1-3 days | Explain AI capabilities to stakeholders via Loom/video | +| **Synthetic Data Simulation** | Can we model without production risk? | 2-4 days | Test prompt logic, simulate edge cases, Monte Carlo on AI outputs | +| **Vibe-Coded Probe** | Will this survive real user contact? | 2-3 days | Frankensoft stack (ChatGPT Canvas + Replit + Airtable) for workflow validation | + +### Selection Logic + +Work backwards from hypothesis: +1. What specific risk am I eliminating? +2. What's the cheapest path to harsh truth? +3. Match method to hypothesis, not tooling comfort. + +**Golden rule:** Use the cheapest prototype that tells the harshest truth. + +### AI-Specific Feasibility Checks + +For AI product features, feasibility checks are critical because AI capabilities are non-obvious: +- **Prompt chain testing:** Run 100 real examples through your proposed prompt. Measure error rate. +- **API sniff tests:** Verify third-party AI integrations return expected format, latency, cost. +- **Data integrity sweeps:** Check if your data supports the AI feature (quality, volume, format). +- **Disposal protocol:** Delete all spike code after documenting findings. Spike-and-delete, not spike-and-ship. + +### Success Criteria Template + +- **Pass:** [Quantitative threshold, e.g., <5% error rate, 80%+ task completion] +- **Fail:** [Observable failure, e.g., >18% errors, users abandon mid-flow] +- **Learn:** [Specific insight regardless of pass/fail] + +Write criteria before building. "We'll know it when we see it" is not a success criterion. + +### Troubleshooting Common AI Product Issues + +**Hallucination (output contains fabricated facts):** +1. Measure: run 100+ real queries, categorize errors (factual, format, reasoning, refusal) +2. Reduce context window — strip to minimum required tokens per the 5 diagnostic questions above +3. Add retrieval with source citations — ground answers in specific documents, not parametric memory +4. Add output validation — regex/rule checks for structured fields, LLM-as-judge for open text +5. Set confidence thresholds — if model confidence is low, return "I don't know" instead of guessing + +**Latency (AI response too slow for UX):** +1. Profile the pipeline — which step is slow? (retrieval, inference, post-processing) +2. Reduce input tokens — smaller context = faster inference. Apply persist vs. retrieve rule. +3. Use streaming — display partial results as they generate +4. Cache common queries — if 30% of queries are similar, pre-compute answers +5. Consider smaller model for simple tasks — route easy queries to fast model, hard queries to capable model + +**Inconsistency (same input, different outputs):** +1. Lower temperature — 0.0-0.3 for factual tasks, 0.5-0.7 for creative tasks +2. Pin model version — don't use "latest" in production +3. Structured output — JSON schema or enum constraints reduce variation +4. Add few-shot examples — 2-3 input/output pairs anchor the response pattern +5. Evaluate on a fixed test set — track consistency score across versions + +--- + +## Quality Gates + +### AI Product Anti-Patterns + +**1. Prompt-and-Pray** +Shipping AI features with untested prompts. No evaluation framework, no error rate measurement. Fix: Run feasibility checks (100+ examples) before committing to build. + +**2. Context Stuffing at Scale** +Pasting entire knowledge bases into AI. "More tokens = better results." Fix: Apply the 5 diagnostic questions. Accuracy degrades significantly as context grows (Lost in the Middle effect). + +**3. No Evals** +Launching AI features without quantitative success criteria. "Users seem to like it." Fix: Define pass/fail thresholds before building. Measure error rates, task completion, hallucination frequency. + +**4. Efficiency Masquerading as Strategy** +"We use AI to write PRDs 2x faster — we're AI-shaped!" If a competitor matches it by hiring 2 more people, it's table stakes. Fix: Ask the replication test — does copying require org redesign? + +**5. Tool Fetishism** +"Should we use Claude or ChatGPT?" Tool debates replace workflow redesign. Fix: Tools don't matter. Workflows matter. + +**6. Speed Without Learning** +Shipping faster without validating faster. AI accelerates building the wrong thing. Fix: Compress learning cycles (PoL probes in days), not just build cycles. + +**7. Prototype Theater** +Building polished demos to impress executives instead of testing hypotheses with users. Fix: Test with users first, present findings to executives. Narrative prototypes over production polish. + +**8. Skipping the Reset** +Never clearing context between research and implementation. Context rot poisons execution. Fix: Mandatory reset after plan synthesis. Start implementation with only the high-density plan. + +**9. Individual AI, Not Team AI** +"I'm AI-shaped, but my team isn't." Can't scale; workflows die when you're on vacation. Fix: Codify review norms, evidence standards, decision authority. Team transformation > individual productivity. + +**10. Testing Multiple Variables** +One probe testing workflow + pricing + UI simultaneously. Ambiguous results. Fix: One probe, one hypothesis. Three hypotheses = three probes. + +### The Falsification Protocol + +For every AI feature decision, complete: +> "If I exclude [context/feature/test], then [specific failure] will occur in [specific scenario]." + +If you can't complete the sentence, you don't need it. Vague failures ("AI might not fully understand") are not valid. + +### Minimum Viable AI Product Checklist + +- [ ] Hypothesis written before building +- [ ] Feasibility check run (100+ examples, error rate measured) +- [ ] Context architecture defined (persist vs. retrieve vs. exclude) +- [ ] Success criteria quantified (pass/fail/learn thresholds) +- [ ] Disposal date set for probes (spike-and-delete) +- [ ] Context boundary owner assigned +- [ ] AI outputs treated as drafts (human review protocol) +- [ ] Learning cycle measured (before vs. after AI intervention) diff --git a/skills/pm-agent/knowledge/artifacts-delivery.md b/skills/pm-agent/knowledge/artifacts-delivery.md new file mode 100644 index 0000000..d7f6314 --- /dev/null +++ b/skills/pm-agent/knowledge/artifacts-delivery.md @@ -0,0 +1,241 @@ +# PM Artifacts & Delivery + +Compressed reference for the full PM artifact lifecycle: from proto-personas and problem framing through PRDs, user stories, epics, story maps, and end-of-life communications. + +## PRD Development + +10-section document, built over 2-4 days. + +**Template structure (10 sections):** +1. Executive Summary -- "We're building [solution] for [persona] to solve [problem], resulting in [impact]." +2. Problem Statement -- Who, what, why, evidence (quotes, analytics, tickets) +3. Target Users & Personas -- Primary + secondary proto-personas +4. Strategic Context -- OKRs, TAM/SAM/SOM, competitive landscape, "why now?" +5. Solution Overview -- High-level description + user flows (not pixel specs) +6. Success Metrics -- Primary metric (optimize), secondary (monitor), guardrail (don't regress) +7. User Stories & Requirements -- Epic hypothesis + broken-down stories with acceptance criteria +8. Out of Scope -- Explicit exclusions with rationale +9. Dependencies & Risks -- Technical, external, team; risks + mitigations +10. Open Questions -- Unresolved decisions needing discovery + +**Metrics structure:** Always define current baseline, target, and measurement timeline. Format: "Metric: Current X -> Target Y, measure Z days post-launch." + +**Phase sequence:** +- Day 1: Exec summary (30m) + Problem (60m) + Personas (30m) + Strategy (45m) +- Day 2: Solution (60m) + Metrics (30m) + Stories (90-120m) +- Day 3: Scope/Dependencies (30m) + Review (60m) + +## User Stories + +**Format (Mike Cohn + Gherkin):** +``` +As a [specific persona], I want to [action], so that [outcome/motivation]. + +Scenario: [description] +Given: [preconditions -- multiple Givens OK] +When: [single trigger event -- aligns with "I want to"] +Then: [single outcome -- aligns with "so that"] +``` + +**Quality gates:** +- "As a" uses specific persona, not generic "user" +- "So that" states motivation, not restatement of action +- One When, one Then per story. Multiple = split signal. +- Acceptance criteria are testable by QA -- no "better experience" or "faster" +- Summary is value-centric: "Enable Google login for trial users" not "Add login button" + +### Splitting Stories + +8 patterns applied in order (Richard Lawrence / Humanizing Work). Stop at first match: + +| # | Pattern | Signal | Split strategy | +|---|---------|--------|----------------| +| 1 | Workflow steps | Multi-step sequence | Thin end-to-end slices (full workflow, increasing sophistication) | +| 2 | Business rules | Different rules per scenario | One story per rule variation | +| 3 | Data variations | Different data types/formats | One story per data type, simplest first | +| 4 | AC complexity | Multiple When/Then | One story per When/Then pair | +| 5 | Major effort | Hard first build, easy additions | "Implement one + add remaining" | +| 6 | External deps | Multiple APIs/third parties | One story per dependency boundary | +| 7 | DevOps steps | Infrastructure/deployment work | Split by operational complexity | +| 8 | Tiny Acts of Discovery | High uncertainty, none above apply | Time-boxed experiments, not stories | + +**Validation after split:** Each piece must (a) deliver user value independently, (b) be testable independently, (c) fit in a sprint (1-5 days), (d) all pieces combined equal the original. + +**Critical rule:** Always split vertically (front-end + back-end = user value). Never horizontally ("Build API" / "Build UI"). + +## Story Mapping + +**Jeff Patton framework -- 2D map:** +- Horizontal (left-right): Activities in narrative/workflow order = backbone +- Vertical (top-down): Priority within each activity + +**Hierarchy:** Segment -> Persona -> Narrative (goal) -> Activities (3-5) -> Steps (3-5 per activity) -> Tasks (5-7 per step) + +**Building the map:** +1. Define segment + persona + narrative (one-sentence JTBD goal) +2. Identify 3-5 backbone activities in sequential workflow order +3. Break each activity into steps (user actions, observable, logical sequence) +4. Break steps into tasks (granular, prioritizable) +5. Prioritize vertically: top = MVP, middle = R2, bottom = future +6. Draw horizontal release lines + +**Walking skeleton:** Top-priority task from EVERY activity = minimal end-to-end functionality. Build across all activities incrementally, not one activity fully before starting the next. + +**Release slicing:** +- R1 (Walking skeleton): Simplest version across all activities +- R2 (Enhanced): Second-priority tasks improving core workflow +- R3 (Polish): Nice-to-haves, edge cases, optimizations + +## Epics + +### Epic Hypothesis + +**Template (Tim Herbig / Lean UX):** +``` +If we [specific action/solution] +for [specific persona] +Then we will [measurable outcome] +``` + +**Tiny Acts of Discovery:** 2-3 lightweight experiments before full build. +- Types: prototype + user test, concierge test, landing page test, Wizard of Oz, A/B test +- Constraint: days/weeks not months; cheap; falsifiable + +**Validation measures:** +``` +We know our hypothesis is valid if within [2-4 weeks] +we observe: +- [Quantitative: "20% increase in activation rate"] +- [Qualitative: "8/10 users say it saved time"] +``` + +**Decision gate:** Validated -> write user stories. Invalidated -> kill or pivot. Inconclusive -> more experiments. + +### Epic Breakdown (9 Patterns) + +Pre-split: INVEST check (Independent, Negotiable, Valuable, Estimable, Small, Testable). If not Valuable, STOP -- combine with other work, don't split. + +**9 patterns applied sequentially** (superset of story splitting): +1. **Workflow steps** -- thin end-to-end, NOT step-by-step +2. **Operations (CRUD)** -- "manage" = Create + Read + Update + Delete +3. **Business rule variations** -- each rule = separate story +4. **Data variations** -- add data types just-in-time +5. **Data entry methods** -- basic input first, fancy UI later +6. **Major effort** -- implement one + add remaining +7. **Simple/Complex** -- simplest core first, variations later +8. **Defer performance** -- "make it work" then "make it fast" +9. **Break out a spike** -- time-box investigation when uncertainty blocks splitting + +**Meta-pattern across all:** Identify core complexity -> list variations -> reduce to one complete slice -> make other variations separate stories. + +**Evaluate splits:** (a) Does it reveal low-value work you can kill? (b) Are resulting stories roughly equal-sized? + +**Cynefin adjustment:** Low uncertainty = find all stories, prioritize by value. High uncertainty = identify 1-2 learning stories only. Chaos = defer splitting, stabilize first. + +## Proto-Personas + +**Hypothesis-driven persona, not validated research.** Created in hours from available data. + +**Template sections:** +1. **Name** -- alliterative, memorable ("Manager Mike") +2. **Bio & Demographics** -- behavioral, not just age/location. Include career, online presence, tech habits. +3. **Quotes** -- real or representative; revealing mindset, not facts +4. **Pains** -- specific and product-relevant ("3 hrs/week copying data between tools") +5. **What they're trying to accomplish** -- observable behaviors and outcomes +6. **Goals** -- short-term + long-term, personal + professional +7. **Attitudes & Influences** -- decision authority, influencers, beliefs affecting adoption + +**Mark uncertainty:** Tag unvalidated items with [ASSUMPTION--VALIDATE]. Plan research to fill gaps. Limit to 1-2 personas initially. + +## Press Release / PRFAQ + +**Amazon Working Backwards format.** Written BEFORE building. Planning tool, not launch copy. + +**Structure:** +1. **Headline** -- benefit-focused, specific ("Cut Invoice Processing by 60%") +2. **Dateline** -- city, date +3. **Introduction** -- what launched, for whom, key benefit (2-3 sentences) +4. **Problem paragraph** -- specific customer problem with data +5. **Solution paragraph** -- outcome-focused, not feature list +6. **Executive quote** -- customer-empathetic, visionary (not "excited to innovate") +7. **Supporting details** -- additional benefits with data +8. **Boilerplate** -- company background +9. **CTA + media contact** + +**Litmus tests:** Would a customer care? Is the problem clear? Are benefits measurable? Is it jargon-free? Does it survive "so what?" + +## Storyboards + +**6-frame narrative arc** for pitching, alignment, and emotional validation. + +| Frame | Name | Content | +|-------|------|---------| +| 1 | Main character | Persona + context (specific, not "busy professional") | +| 2 | Problem emerges | Challenge + how it affects life | +| 3 | "Oh crap" moment | Escalation creating urgency | +| 4 | Solution appears | Realistic discovery of product | +| 5 | "Aha" moment | Breakthrough experience (outcome, not feature demo) | +| 6 | Life after | Improved state with specifics | + +**Visual style default:** Fat-marker sharpie sketches, minimal, monochrome. Low-fidelity is fine. + +**7 input questions:** Who is the character? What problem? What's the escalation? How is solution introduced? What's the breakthrough? What's life after? Visual style preferences? + +## Recommendation Canvas + +**11-section strategic proposal** for AI/high-uncertainty product decisions. Executive-friendly. + +1. **Business Outcome** -- [Direction] [Metric] [Outcome] [Context] [Criteria] +2. **Product Outcome** -- same format, customer perspective +3. **Problem Statement** -- persona-centric narrative +4. **Solution Hypothesis** -- If/Then + Tiny Acts of Discovery + Proof-of-Life measures +5. **Positioning Statement** -- For/That need/Is a/That + Unlike/Provides differentiation +6. **Assumptions & Unknowns** -- explicit, testable +7. **PESTEL Risks (Investigate)** -- Political, Economic, Social, Tech, Environmental, Legal (specific, not generic) +8. **PESTEL Risks (Monitor)** -- lower priority watch list +9. **Value Justification** -- data-backed case for C-level ("addresses #1 pain point, $500k ARR impact") +10. **Success Metrics** -- SMART format +11. **What's Next** -- ordered action steps + +## End-of-Life Communication + +**9-section empathy-first EOL message.** Never send without a complete transition plan. + +**Structure:** +1. **Company context** -- who you are, customer commitment +2. **Announcement** -- single clear sentence: what's ending, what's replacing it, when +3. **Rationale** -- framed as customer benefit, not cost savings +4. **Current product context** -- acknowledge what's being lost and who it served +5. **Customer impact** -- explicitly name disruptions (migration time, learning curve, integration updates) +6. **Transition solution** -- positioning format: For/That currently use/Is a/That + continuity + improvements +7. **Support measures** -- 1:1 assistance, auto-migration, discounts, training +8. **Timeline** -- specific dates: migration tool available, read-only date, full shutdown, data export deadline. 6-12 months lead time. +9. **Call to action** -- next steps + contact info + +**Tone rules:** Empathetic, not defensive. Forward-looking, not apologetic. Specific, not vague. Never blame customers for low usage. + +## Quality Gates + +### Cross-cutting anti-patterns + +| Anti-pattern | Appears in | Fix | +|---|---|---| +| Written in isolation | PRD, story map | Collaborate with design + eng on stories/map | +| No evidence in problem statement | PRD, press release, canvas | Include quotes, analytics, tickets | +| Solution too prescriptive | PRD | Keep solution high-level; let design own UI | +| Feature list instead of benefits | Press release, canvas | Translate features to outcomes | +| Generic "As a user" | User stories | Use specific persona names/roles | +| "So that" restates "I want to" | User stories | Dig into real motivation | +| Multiple When/Then | User stories | Split the story | +| Horizontal slicing | Story splitting, epic breakdown | Always vertical: each story delivers end-to-end user value | +| Skipping experiments | Epic hypothesis, canvas | Define lightweight validation before build | +| Vague validation measures | Epic hypothesis, canvas | Specific metrics + timeframe (2-4 weeks) | +| Treating hypotheses as commitments | Epic hypothesis | Frame as bets; allow invalidation | +| Activities are features, not behaviors | Story map | Map user actions, not product capabilities | +| Technical backbone | Story map | Backbone follows user workflow, not system layers | +| Feature-complete waterfall releases | Story map | Walking skeleton = thin slice across ALL activities | +| Demographics without behavior | Proto-persona | Add behavioral context, not just age/location | +| Too many personas | Proto-persona | Start with 1-2; expand as validated | +| Business-centric EOL rationale | EOL message | Frame as customer benefit | +| Vague EOL timeline | EOL message | Specific dates with milestones | +| No transition support plan | EOL message | Migration assistance, tools, discounts | diff --git a/skills/pm-agent/knowledge/career-leadership.md b/skills/pm-agent/knowledge/career-leadership.md new file mode 100644 index 0000000..743db27 --- /dev/null +++ b/skills/pm-agent/knowledge/career-leadership.md @@ -0,0 +1,250 @@ +# Career & Leadership + +Compressed knowledge module covering the PM-to-Director and Director-to-VP/CPO career transitions, diagnostic coaching logic, executive onboarding methodology, and named failure modes at each level. + +## Altitude-Horizon Framework + +Two axes define the PM-to-Director shift: + +**Altitude (Scope)** +- PM: customer problems, individual features, sprint priorities, specific team dynamics. +- Director: product portfolio, cross-functional systems, organizational dynamics, budget allocation, market positioning. + +**Horizon (Time)** +- PM: days, weeks, sprints. A quarter at most. +- Director: quarter as starting point. Annual planning cycles, multi-year strategy. + +**Waiter vs. Restaurant Operator** — the core analogy: + +| Dimension | PM (Waiter) | Director (Operator) | +|---|---|---| +| Focus | Individual diner experience | Entire system: staffing, margins, menu, suppliers | +| Authority | Influence without control | Portfolio decisions, budget, resource allocation | +| Success metric | Table seven is happy | Restaurant is profitable, consistent, scalable | +| Customer relationship | Direct, daily, intimate | Aggregate patterns, market cohorts | + +### Four Transition Zones + +1. **Thinking Altitude** — Stop solving individual problems directly. Start designing systems and teams that solve classes of problems. +2. **Persona Shift** — Stop obsessing over individual user personas. Start thinking in buyer personas, market cohorts, organizational stakeholders, executive dynamics. +3. **Hero Syndrome Recovery** — Stop being the person who saves the day. Start getting satisfaction from team success. Your product is your people, not the roadmap. +4. **Direction Creation** — Stop waiting for clear direction from above. Start creating context cascades that translate strategy into team clarity, even when inputs are incomplete. + +### Cascading Context Map + +When direction is vague, Directors cascade rather than wait: + +1. Listen to top-level strategy (QBRs, exec comms) +2. Extract 3-5 key priorities leadership stated +3. Map: "How does our BU accomplish these?" +4. Map: "How does our product portfolio accomplish that?" +5. Map: "What are my team's specific accountabilities?" +6. Communicate the cascade — not just what, but why it connects upward + +Template: +``` +Company Priority: [leadership's words] +BU Translation: [how your BU contributes] +Portfolio Translation: [how your products contribute] +Team Accountabilities: [what each team owns] +Why This Matters: [what changes, what stays the same] +``` + +Core principle: even with incomplete direction from above, a Director's job is to fill the gap downward. Creating imperfect-but-useful clarity is a Director skill. + +### Named Failure Modes (PM-to-Director) + +**Hero Syndrome** — Jumping in to solve problems directly. Regressing to the old reward loop of visible IC wins. Cost: you under-perform as Director while over-functioning as senior IC. Your team doesn't develop. + +**Allergic to Process** — Letting high-performing PMs run independent playbooks. Cost: stakeholders across marketing, finance, leadership can't synthesize inconsistent outputs. + +**People-Pleaser Leadership** — Wanting the team to like you. Avoiding hard feedback. Saying yes to preserve relationships. Cost: confuse "popular" with "effective." + +**Instant Gratification Trap** — Reading leadership books, collecting certifications, asking "what do I need to do to get promoted?" Cost: Director readiness requires war stories and lived humility, not study. + +**Black-and-White Thinking** — "This seems obvious." "Why is everything so political?" Cost: fast decisions with low confidence create downstream chaos. Grayscale is the actual terrain. + +## PM to Director Transition + +### Four Coaching Situations + +| Situation | Description | Coaching Priority | +|---|---|---| +| Preparing | Still a PM, building toward Director | Identify weakest transition zone; practice cascade thinking; audit Hero Syndrome habits | +| Interviewing | Active internal or external search | Build one story per transition zone; reframe PM wins in Director language; prepare for the gap question honestly | +| Newly Landed | First 6 months as Director | Run Cascading Context Map immediately; reframe 1-on-1s to strategic altitude; name ambiguity explicitly; resist premature reorgs | +| Recalibrating | Been a Director; something broken | Track IC-vs-coaching time ratio (target: 20% IC); identify what keeps you in Hero Syndrome; create deliberate handoffs | + +### Readiness Signals (Preparing) + +Assess across four gap areas: +1. **Thinking altitude** — still default to solving customer problems directly? +2. **Stakeholder navigation** — struggle with politics, exec dynamics, cross-functional influence? +3. **Strategic narrative** — can't connect work to company strategy in leadership conversations? +4. **Direction creation** — wait for clarity from above rather than creating it? + +Development timeline matters: 6+ months out = build deliberately. 3-6 months = signal readiness, prepare manager conversation. Actively applying = shift to interview prep. + +### Interview Preparation + +- Work through Altitude-Horizon Framework as a study session: after each section, identify your own story. +- Build one concrete story per transition zone. Use zone names as structure. +- Reframe PM wins: don't open with "I shipped X." Open with "The strategic question my team faced was [X]. Here's how I thought about the portfolio tradeoff." +- For the gap question: "Here's the gap, here's how I've been developing toward it, here's what I'd focus on learning in the first 90 days." Honesty with a plan beats avoidance. + +### Newly Landed Coaching + +Challenge-specific guidance for inherited teams without clear direction: +1. Run a Cascading Context Map this week. Don't wait for perfect clarity. +2. Redirect 1-on-1s: "Help me see how your product connects to the business goals I'm accountable for." +3. Name ambiguity explicitly: "Here's my best current translation. I'll update it in two weeks." +4. Wait 60-90 days before reorganizing. Understand what's working first. + +### Recalibrating Coaching + +For Directors still doing IC work after 12+ months: +- Track the ratio: most are at 60-70% IC work. Target is 20%. +- Identify root cause: (a) trust own judgment over team, (b) team undeveloped, (c) getting reward signals from IC behavior. +- Create deliberate handoff for top 3 IC activities with written "done well" criteria. +- Change the reward loop: notice quieter Director wins (PM ships a hard stakeholder conversation alone, team creates its own cascade). +- If entrenched at 1-2 years: consider whether the role fits. Senior IC / Principal PM is a legitimate path. + +## Director to VP/CPO Transition + +### The Three Ps Framework + +VP/CPO accountability spans three dimensions: +- **Product** — Portfolio decisions, roadmap strategy, product family coherence +- **Practice** — How work gets done; process discipline, execution consistency, cross-functional operating rhythms +- **People** — The dominant focus: org structure, talent matching, developing leaders, setting and inspecting expectations + +Most Directors are strong in Product, adequate in Practice. People is where the VP/CPO transition most often breaks down. + +### The Empowerment Myth + +False belief: "Once I get there, I'll finally have authority to do what I always knew was right." +Reality: constraints don't disappear, they change shape. PM = 3x3 Rubik's Cube. Director = 5x5. VP = 7x7. CPO = 9x9. Same principles; exponentially larger blast radius per decision. + +### VP to CPO Paradigm Shift + +| Dimension | VP Mindset | CPO Mindset | +|---|---|---| +| Core question | "What are we releasing?" | "What business outcomes is the product org accountable for?" | +| Language | Product vocabulary (features, roadmaps, sprints) | Business vocabulary (ROI, revenue, retention, margin, EBITDA) | +| Primary customer | End user | May be investor, buyer, or board — depends on business context | +| Primary team | Product organization | Executive staff (CEO, CFO, CRO, CMO) | + +### Time Horizon by Level + +| Level | Short-term | Long-term | +|---|---|---| +| IC | Sprint | Quarter | +| Director | Quarter | 1-2 years | +| VP | 1-2 quarters | 3 years | +| CPO | 1-2 quarters | 3-5 years | + +Quarterly delivery doesn't stop. Long-term horizon runs in parallel with short-term accountability at every level. + +### Alliance Building (Executive Level) + +Without executive alliances, you're a "dead man walking." Requirements: +- Weekly engagement with peer executives (CRO, CFO, CMO) — not annual roadmap reviews +- Proactive trade-off communication: "You're not getting X this quarter because of Y, and here's why" +- Bring people along before decisions are announced, not after +- Understand each peer's real priorities, not just stated ones + +### CEO Interview Questions (Pre-Acceptance) + +Five questions to probe before accepting a VP/CPO role: + +1. "What are you expecting from the product org in the first 90 days? The first year?" — Surfaces unrealistic transformation timelines. +2. "Who are the all-stars on your product team, and why?" — Reveals CEO's perceptions and biases. +3. "Who has gaps, and why?" — What does the CEO believe the org weakness is? +4. "What constraints am I working with that I should understand upfront?" — Your actual degrees of freedom. +5. "What does success look like for this role at one year?" — Force specificity. Vague answers are red flags. + +**Red flags:** "You can't change the existing roadmap" (loss of basic authority). "Transform the org in six months" (setup for failure). Misalignment between CEO's talent assessment and what you hear elsewhere. + +### VP/CPO Readiness Assessment + +Four coaching situations mirror the Director advisor: + +| Situation | Key Assessment Areas | +|---|---| +| Preparing | Which of the Three Ps is weakest? What's your exposure to executive dynamics? | +| Evaluating/Interviewing | Can you demonstrate executive-level thinking vs. Director-level work? Have you run CEO interview questions? | +| Newly Landed | Getting oriented without acting prematurely? Executive dynamics navigation? People/org assessment? Surfacing unwritten strategy? | +| Recalibrating | Still operating at Director level? Executive relationships broken? Organization underperforming? Unclear success criteria? | + +## Executive Onboarding (30-60-90) + +### Consultant Mindset + +Enter every new VP/CPO role as an external consultant assessing the organization before you're responsible for changing it. +- Observe before diagnosing. Ask questions before declarations. +- Understand how steering connects to rudder — org charts lie; map actual reality. +- Don't throw the big red switch. Understand what inherited structures control first. +- Negotiate upfront: tell your boss Month 1 is explicitly a learning phase. + +### Phase 1: Diagnose (Month 1) + +**Objective:** Build the body of evidence. Understand reality, not the official version. + +1. **Interview everyone** — Direct reports, cross-functional peers (CRO, CFO, CMO, Eng leads), sample of PMs. Questions: "What's working?" / "What's not working?" / "What won't I hear in official briefings?" / "Who should I talk to?" +2. **Let people find you** — Those who proactively schedule time have an agenda. Surface it, evaluate it, note the signal. +3. **Take detailed notes** — Who said it, what their incentive might be, whether multiple independent sources confirm it. +4. **Resist action** — When you see something broken, note it. You don't yet know why it's broken, what it's connected to, or what previous fix attempts failed. + +**Deliverable:** Detailed notebook of organizational reality, not yet interpreted. + +### Phase 2: Validate (Month 2) + +**Objective:** Surface patterns, challenge conclusions, identify people situations. + +1. **Reality-check with your boss** — "I'm hearing [X]. This differs from what I understood coming in. Help me understand the history." +2. **Map unwritten strategy** — Ask: "What does the organization actually optimize for when things get hard?" Answer is usually different from mission statement. +3. **Complete people assessment** — Diamonds in the rough (give more scope). Strong but wrong role (have the conversation). Not coachable to needed level (determine timeline). +4. **Identify 3-5 highest-leverage changes** — Not a full transformation plan. These become Month 3 agenda. + +**Deliverable:** Interpreted organizational assessment with people map and initial strategic priorities. + +### Phase 3: Act with Evidence (Month 3) + +**Objective:** Make decisions grounded in collected evidence. + +1. **Share organizational assessment** — Bring findings to boss and direct reports. Transparency builds trust and surfaces disagreements before you act. +2. **Run first Cascading Context Map** — Create direction even if strategy above you is still ambiguous. Team has been waiting for context. +3. **Start people conversations** — Diamonds: stretch assignment. Wrong role: honest conversation about mismatch and options. Exits: honesty and care, not avoidance. +4. **Build executive alliance deliberately** — Start weekly alignment practice with CRO, CFO, CMO. Don't wait for them to be surprised. + +**Deliverable:** Shared assessment, initial strategic direction, 3-5 active changes underway with clear rationale. + +### People Assessment Categories + +**Diamonds in the rough:** Capable, undervalued, no champion. Find them by listening for "she's talented but nobody gives her the hard problems" or noticing who provides the most unvarnished information. They become critical early allies. + +**Strong people in wrong roles:** Strengths mismatched to scope. Common in fast-growth, post-acquisition, or tenure-based promotion orgs. Coach up if coachable, find another role, or part ways. All three better than leaving mismatch in place. + +## Quality Gates + +### Anti-Patterns Across All Transitions + +**Premature action** — Making structural changes before building the body of evidence. Month 1 changes guarantee expensive reversals. + +**Consultant mode too long** — Still gathering information in Month 3. Organizational confidence erodes. Act on best current evidence. + +**Title-chasing** — Optimizing for promotion appearance rather than building actual muscles. Interviewers and managers detect the difference. + +**Skipping altitude shifts** — Using strategy vocabulary while still making sprint-level decisions (Altitude Theater). If you're in the details, own it. If you're not, delegate fully. + +**Empowerment fantasy** — Taking a VP/CPO role expecting constraints to vanish. They scale up, they don't disappear. + +**Alliance neglect** — Treating executive peer relationships as secondary to managing direct reports. At VP/CPO, the exec team is your primary operating environment. + +**Loudest voice bias** — Forming early opinions from the most vocal person met in Month 1. Only act on themes confirmed by 3+ independent sources. + +**Conflating VP and CPO** — Treating Director-to-VP and VP-to-CPO as the same move at different scale. VP-to-CPO is a qualitative change (product-first to business-first), not scope expansion. + +**One-and-done cascade** — Running the Context Map once at annual planning, never revisiting. Revisit at major inflection points: quarterly planning, exec changes, pivots, restructuring. + +**Kindness confusion** — Shielding teams from hard decisions, softening feedback into meaninglessness. Be transparent about the "why." What you share should be honest and actionable. diff --git a/skills/pm-agent/knowledge/discovery-research.md b/skills/pm-agent/knowledge/discovery-research.md new file mode 100644 index 0000000..c1fe078 --- /dev/null +++ b/skills/pm-agent/knowledge/discovery-research.md @@ -0,0 +1,375 @@ +# Discovery & Research + +Compressed decision logic, frameworks, and quality gates for running product discovery end-to-end: framing problems, interviewing customers, mapping jobs and journeys, generating solutions, and validating hypotheses before committing to build. + +## Problem Framing + +### Problem Statement (Component) + +**Template -- write from the user's perspective:** + +``` +I am: [persona with 3-4 key characteristics] +Trying to: [desired outcome -- measurable, not a task] +But: [barriers preventing the outcome] +Because: [root cause, not symptom] +Which makes me feel: [authentic emotion from research] +``` + +**Final statement formula:** `[Persona] needs a way to [outcome] because [root cause], which currently [impact].` + +**Quality gates:** +- "I am" passes if you can picture a real person (not "busy professionals") +- "Trying to" is an outcome, not an activity +- "Because" survives 5-why interrogation +- "Makes me feel" uses verbatim customer language, not marketing copy +- Final statement fits one sentence and is measurable + +**Top anti-patterns:** +1. **Solution smuggling** -- "The problem is we don't have X." Fix: reframe around user outcome. +2. **Business problem disguised as user problem** -- "Users want to reduce our churn." Fix: dig into why users leave from their perspective. +3. **Symptom instead of root cause** -- "Because the UI is confusing." Fix: keep asking "why" until you hit structural cause. + +--- + +### Problem Framing Canvas (MITRE, Interactive) + +**Three-phase bias-check before you write a problem statement.** + +**Phase 1 -- Look Inward:** +- What is the problem? (symptoms only) +- Why haven't we solved it? (new / hard / low priority / lack of resources / authority / systemic inequity) +- How are we part of the problem? (confirmation bias / internal bias / survivorship bias / premature convergence) + +**Phase 2 -- Look Outward:** +- Who experiences it? When, where, consequences? +- Who else has it? Who doesn't? (counter-examples reveal root cause) +- Who's been left out of the conversation? +- Who benefits from the problem existing? Who benefits from it being solved? + +**Phase 3 -- Reframe:** +- Restate: "[Who] struggles to [what] because [root cause], leading to [consequence]. Affects [segments], overlooked because [bias]." +- HMW: "How might we [action] as we aim to [objective]?" + +**Quality gates:** +- HMW is broad enough to permit multiple solutions, narrow enough to be actionable +- Canvas was completed cross-functionally, not solo +- "Who benefits from the status quo?" was explicitly answered + +**Top anti-patterns:** +1. **Skipping Look Inward** -- groupthink persists. Fix: force explicit bias discussion. +2. **Generic reframe** -- "Improve user experience." Fix: include who, what, when, consequence, root cause. +3. **HMW too narrow** -- "How might we add a mobile app?" Fix: state the job, not the solution. + +--- + +## Customer Discovery + +### Discovery Process (Workflow, 6 phases / 3-4 weeks) + +``` +Phase 1: Frame (Day 1-2) + -> Problem Framing Canvas (120 min) + Problem Statement (30 min) + -> Optional: Proto-Persona, JTBD + -> Output: problem hypothesis, 3-5 research questions, success criteria + -> Gate: enough context to start research? If no, gather data first (+2-3 days) + +Phase 2: Plan Research (Day 3) + -> Discovery Interview Prep (90 min) + -> Recruit 5-10 participants, schedule across 1-2 weeks + -> Output: interview guide (5-7 Mom Test questions), participant roster + +Phase 3: Conduct Research (Week 1-2) + -> 5-10 interviews + support ticket analysis + analytics review + -> Note template per interview: participant, context, actions, pain points, workarounds, verbatim quotes, insights + -> Gate: saturation? Same pains across 3+ interviews = proceed. Still learning = +3-5 interviews. + +Phase 4: Synthesize (End of Week 2) + -> Affinity mapping: sticky notes -> themed clusters with frequency counts + -> Optional: Customer Journey Map workshop + -> Prioritize: score each pain on frequency x intensity x strategic fit (1-5 each) + -> Output: top 3-5 pain points, 3-5 verbatim quotes per pain, validated problem statement + +Phase 5: Generate & Validate Solutions (Week 3) + -> Opportunity Solution Tree OR Lean UX Canvas + -> Design experiments: concierge / prototype / landing page / A/B test + -> Run experiments (1-2 weeks each) + -> Gate: validated? If no, pivot to next solution (+1-2 weeks) + +Phase 6: Decide & Document (Week 3-4) + -> GO (roadmap + epics + PRD) / PIVOT (next solution) / KILL (deprioritize) + -> 30-min stakeholder readout: problem validation, solution validation, recommendation +``` + +**Timeline ranges:** fast track 3 weeks (5 interviews, 1 experiment) | typical 4 weeks | thorough 6-8 weeks. + +**Top anti-patterns:** +1. **Skipping interviews** -- relying only on analytics. Fix: always 5-10 qualitative interviews. +2. **Analysis paralysis** -- 6 weeks synthesizing. Fix: time-box to 3-4 weeks total. +3. **Discovery as one-time event** -- run continuous (Teresa Torres: 1 interview/week). + +--- + +### Interview Prep (Interactive, 4 adaptive questions) + +**Q1 -- Research Goal:** problem validation | JTBD discovery | retention/churn investigation | feature prioritization + +**Q2 -- Target Segment:** people who experience problem regularly | people who tried to solve it | people in target segment regardless of awareness | people who recently experienced it + +**Q3 -- Constraints:** limited access (5-10, 2 weeks) | existing base (100+ customers) | cold outreach required | internal stakeholders only (proxy) + +**Q4 -- Methodology (context-aware on Q1-Q3):** +- **Mom Test (Rob Fitzpatrick — problem validation):** past behavior, not hypotheticals. "Tell me about the last time..." +- **JTBD interviews:** what customers hire/fire. "What were you trying to get done?" +- **Switch interviews:** push/pull of changing solutions. "What prompted you to look?" +- **Timeline/journey mapping:** chronological walkthrough of full experience + +**Output: interview plan with opening (5 min), 5 core questions with follow-ups and anti-patterns, closing (5 min), bias checklist, success criteria, logistics.** + +**5 biases to avoid in every interview:** +1. Confirmation bias -- don't ask "Don't you think X is a problem?" +2. Leading questions -- don't ask "Would you use this?" +3. Hypothetical questions -- don't ask "If we built Y, would you pay?" +4. Pitching disguised as research -- don't explain your solution +5. Yes/no questions -- don't ask "Is invoicing hard?" + +**Interview success = specific stories (not generic complaints) + past behavior (not wishes) + patterns across 3+ interviews + at least one surprise.** + +**Top anti-patterns:** +1. **Asking what customers want** -- gets feature requests, not problems. Fix: ask about past behavior. +2. **Pitching instead of listening** -- don't mention your solution until last 5 min (if at all). +3. **Stopping at 1-2 interviews** -- small sample = confirmation bias. Fix: 5-10 minimum. + +--- + +## Jobs to Be Done + +### JTBD Framework (Component) + +**Three categories of customer jobs:** + +| Type | Question | Examples | +|------|----------|----------| +| **Functional** | What tasks to complete? | "Reconcile monthly expenses for tax filing" | +| **Social** | How to be perceived? | "Be seen as strategic by exec team" | +| **Emotional** | What state to achieve/avoid? | "Feel confident I'm not missing details" | + +**Four categories of pains:** +- **Challenges:** obstacles preventing job completion +- **Costliness:** excessive time, money, or effort +- **Common mistakes:** preventable errors +- **Unresolved problems:** gaps in current solutions + +**Four categories of gains:** +- **Expectations:** what exceeds current solutions +- **Savings:** time/money/effort reductions +- **Adoption factors:** what triggers switching +- **Life improvement:** how life gets better + +**Quality gates for jobs:** +- Verb-driven (actions, not nouns) +- Solution-agnostic ("communicate with team" not "use Slack") +- Specific ("track expenses for tax deductions" not "manage finances") + +**Prioritization:** rank pains by intensity (acute vs. mild). Ask: "If we solved one pain, which has biggest impact?" + +**Top anti-patterns:** +1. **Confusing jobs with solutions** -- "I need Slack." Fix: ask "Why?" 5 times. +2. **Ignoring social/emotional jobs** -- people buy on emotion, justify with logic. Fix: explicitly ask about perception and feelings. +3. **Fabricating JTBD without research** -- assumptions aren't insights. Fix: conduct switch interviews or contextual inquiries. + +--- + +## Opportunity Mapping + +### Opportunity Solution Tree (Teresa Torres — Interactive, 2 phases) + +**Structure:** +``` +Desired Outcome (1 measurable metric) + | + +-- Opportunity 1 (customer problem, not solution) + | +-- Solution A + experiment + | +-- Solution B + experiment + | +-- Solution C + experiment + | + +-- Opportunity 2 + | +-- Solutions... + | + +-- Opportunity 3 + +-- Solutions... +``` + +**Phase 1 -- Generate tree:** +1. Extract desired outcome (revenue growth / retention / acquisition / efficiency) +2. Generate 3 opportunities per outcome (customer problems with evidence) +3. Generate 3 solutions per opportunity (with hypothesis + experiment for each) + +**Phase 2 -- Select POC:** +- Score each solution: Feasibility (1-5) + Impact (1-5) + Market Fit (1-5) +- Feasibility: 1 = months, 5 = days. Impact: 1 = minimal, 5 = major. Market Fit: 1 = customers don't care, 5 = actively request. +- Pick highest total score as POC. Define experiment type: A/B test, prototype + usability, or concierge. + +**Hypothesis template:** "If we [solution], then [metric] will [change] from [X] to [Y] because [rationale]." + +**Top anti-patterns:** +1. **Opportunities disguised as solutions** -- "We need a mobile app." Fix: reframe as customer problem: "Mobile users can't access product on the go." +2. **Skipping divergence** -- "We know the solution." Fix: generate 3+ per opportunity. Force divergence before convergence. +3. **No experiments** -- picking solution and going to roadmap. Fix: every solution must map to an experiment. +4. **Vague outcomes** -- "Improve UX." Fix: make measurable: "Reduce drop-off from 60% to 40%." + +--- + +## Customer Journey + +### Journey Map (Component) + +**Horizontal axis (stages):** Awareness -> Consideration -> Decision -> Service -> Loyalty + +**Vertical axis (per stage):** +- Customer Actions (observable, specific) +- Touchpoints (digital + physical + human) +- Customer Experience (emotions with customer quotes) +- KPIs (measurable, stage-appropriate) +- Business Goals (outcome-focused, stage-aligned) +- Teams Involved (cross-functional with specific roles) + +**Quality gates:** +- Emotions are specific ("relieved setup took 30 min, not 3 hours") not generic ("happy") +- Touchpoints include offline (conferences, calls), not just digital +- Map reflects what customers actually do, not what you want them to do +- KPIs and goals present for every stage + +--- + +### Journey Mapping Workshop (Interactive, 5 questions) + +**Q1 -- Actor:** select persona (primary / secondary / high-churn / newly discovered) +**Q2 -- Scenario + Goal:** first-time use / core workflow / problem resolution / upgrade-expansion +**Q3 -- Journey Phases:** generate 4-6 phases based on scenario (e.g., Discover -> Evaluate -> Try -> Activate -> Use -> Expand) +**Q4 -- Per-phase mapping:** 3-5 actions, thoughts, emotions, and pain points per phase +**Q5 -- Opportunities:** rank 5-7 pain points by impact (HIGH/MEDIUM/LOW) with evidence + +**Output:** full journey map + prioritized opportunity list. + +**Top anti-patterns:** +1. **Mapping internal process, not customer experience** -- "Lead generated -> Qualified -> Demo." Fix: map from customer POV. +2. **No emotions** -- actions only. Fix: add customer quotes and emotional states. +3. **Too many personas in one map** -- loses focus. Fix: one map per persona. + +--- + +## Lean Validation + +### Lean UX Canvas (v2, Interactive, 8 boxes) + +**Fill order:** + +| Box | Question | Content Type | +|-----|----------|-------------| +| 1. Business Problem | What changed that created a problem? | Context + trigger | +| 2. Business Outcomes | What behavior change = success? | Metrics (not emotions) | +| 3. Users | Which persona first? | Specific segment | +| 4. User Outcomes & Benefits | Why would users seek this? | Goals, emotions, empathy (not metrics) | +| 5. Solutions | What might solve it? | 3+ candidate features/initiatives | +| 6. Hypotheses | Testable if/then statements | "We believe [outcome] if [user] attains [benefit] with [solution]" | +| 7. Learn First | What's the riskiest assumption? | Value > usability > feasibility > viability risk | +| 8. Least Work | Smallest experiment to test it? | Must complete in <2 weeks | + +**Box 2 vs Box 4 distinction:** Box 2 = behavior change metrics. Box 4 = human motivation and empathy. + +**Top anti-patterns:** +1. **Starting with solutions** -- Box 1 says "build X." Fix: ask "What changed? Why is this a problem now?" +2. **Confusing Box 2 and Box 4** -- metrics in the empathy box. Fix: Box 2 = numbers, Box 4 = feelings. +3. **Only one solution in Box 5** -- no exploration. Fix: force 3+ candidates. +4. **Skipping experiments** -- "just build it." Fix: design smallest test first. + +--- + +### PoL Probe (Component) -- Proof of Life + +**A disposable, hypothesis-driven validation artifact. Not an MVP. Planned for deletion.** + +**5 required characteristics:** Lightweight (hours/days) + Disposable (deletion date set) + Narrow Scope (one hypothesis) + Brutally Honest (surfaces harsh truth) + Tiny & Focused (reconnaissance, not product). + +**Template fields:** hypothesis, risk being eliminated, probe type, target users, success criteria (pass/fail/learn thresholds), tools, timeline, disposal plan, owner, status. + +**5 Probe Flavors:** + +| Flavor | Core Question | Timeline | When to Use | +|--------|---------------|----------|-------------| +| Feasibility Check | Can we build this? | 1-2 days | Technical unknowns, API deps, data integrity | +| Task-Focused Test | Can users complete this job? | 2-5 days | Critical UI moments, navigation, drop-off zones | +| Narrative Prototype | Does this earn buy-in? | 1-3 days | Complex flow explanation, stakeholder alignment | +| Synthetic Data Simulation | Can we model without production risk? | 2-4 days | Edge cases, unknown-unknowns, load testing | +| Vibe-Coded Probe | Will this survive real user contact? | 2-3 days | Workflow/UX validation needing real interaction | + +**Golden Rule:** Use the cheapest prototype that tells the harshest truth. + +--- + +### PoL Probe Advisor (Interactive, decision logic) + +**Selection flow:** hypothesis -> risk type -> core question -> recommended probe. + +**Decision matrix:** +- Technical feasibility unknown -> **Feasibility Check** (spike-and-delete, API sniff tests) +- Critical UI friction -> **Task-Focused Test** (Optimal Workshop, UsabilityHub, Maze) +- Need stakeholder alignment -> **Narrative Prototype** (Loom walkthrough, slideware storyboard) +- Edge case exploration -> **Synthetic Data Simulation** (Monte Carlo, synthetic users, LangFlow) +- Need real user interaction -> **Vibe-Coded Probe** (ChatGPT Canvas + Replit + Airtable Frankensoft) + +**Refinement questions when hypothesis is too broad:** +1. What's the smallest thing you could test first? +2. What would failure look like? +3. Is this testing user behavior, technical feasibility, or stakeholder alignment? Pick one. + +**Top anti-patterns:** +1. **Choosing based on tooling comfort** -- "I know Figma, so I'll prototype." Fix: match method to hypothesis, not skillset. +2. **Defaulting to code** -- "Let's just build it." Fix: ask what's cheapest path to harsh truth. +3. **Confusing vibe-coded probes with MVPs** -- scope creep, refusal to dispose. Fix: set disposal date before building. +4. **Testing multiple things at once** -- ambiguous results. Fix: one probe, one hypothesis. +5. **No success criteria** -- "we'll know it when we see it." Fix: define pass/fail/learn before building. + +--- + +## Quality Gates + +### Consolidated Anti-Patterns Across All 11 Skills + +**Problem framing failures:** +- Solution smuggling in problem statements +- Business metrics framed as user problems +- Generic personas ("busy professionals") +- Skipping bias examination (Look Inward) + +**Research failures:** +- Leading / hypothetical / yes-no questions +- Pitching disguised as research +- Stopping at 1-2 interviews (need 5-10 minimum) +- Not recording insights immediately post-interview +- Never reaching saturation (same patterns in 3+ interviews) + +**Synthesis failures:** +- Analysis paralysis (6+ weeks, no decisions) +- Opportunities disguised as solutions in OST +- Vague outcomes that can't be measured +- Journey maps reflecting internal wishful thinking, not customer reality +- Generic emotions ("happy") instead of specific states + +**Validation failures:** +- Prototype theater (impressive demos that teach nothing) +- Choosing validation method by tooling comfort, not hypothesis +- Testing multiple variables in one experiment +- No pre-defined failure criteria +- Treating disposable probes as production code +- Discovery as one-time event instead of continuous practice + +### Universal Quality Checks + +Every discovery artifact should pass these: +1. **Falsifiable:** can you describe what failure looks like? +2. **Evidence-backed:** grounded in customer research, not assumptions? +3. **Specific:** can you picture the person, the problem, the metric? +4. **Actionable:** does it inform a concrete next step? +5. **Time-boxed:** is there a deadline that prevents indefinite exploration? diff --git a/skills/pm-agent/knowledge/finance-metrics.md b/skills/pm-agent/knowledge/finance-metrics.md new file mode 100644 index 0000000..1189de9 --- /dev/null +++ b/skills/pm-agent/knowledge/finance-metrics.md @@ -0,0 +1,260 @@ +# Finance & Metrics + +Compressed reference for SaaS finance: 32 metrics with formulas and benchmarks, diagnostic frameworks, and decision logic for feature investment, channel evaluation, and pricing changes. + +## SaaS Revenue & Growth Metrics + +### Core Revenue Metrics + +| Metric | Formula | Benchmarks | +|--------|---------|------------| +| **Revenue** | Sum of all customer payments in period | Growth rate >20% YoY (varies by stage) | +| **ARPU** | Total Revenue / Total Users | B2C: $5-50/mo; B2B: $50-500+/mo; track trend | +| **ARPA** | MRR / Active Accounts | SMB: $100-$1K/mo; Mid: $1K-$10K; Ent: $10K+ | +| **ACV** | Annual Recurring Revenue per Contract (exclude one-time fees) | SMB: $5K-$25K; Mid: $25K-$100K; Ent: $100K+ | +| **MRR/ARR** | MRR = sum of recurring subs; ARR = MRR x 12 | Track components: New + Expansion - Churned - Contraction | +| **Gross vs Net Revenue** | Net = Gross - Discounts - Refunds - Credits | Refunds >10% = product problem; Discounts >20% = pricing power problem | + +**ARPA/ARPU combined analysis:** Average Seats per Account = ARPA / ARPU. High ARPA + low ARPU = undermonetized seats. Low ARPA + high ARPU = small deal sizes. + +### Retention & Expansion Metrics + +| Metric | Formula | Benchmarks | +|--------|---------|------------| +| **Churn Rate (Logo)** | Customers Lost / Starting Customers | Monthly: <2% great, 2-5% ok, >5% crisis | +| **Churn Rate (Revenue)** | MRR Lost / Starting MRR | Annual: <10% great, 10-30% ok, >30% crisis | +| **NRR** | (Start ARR + Expansion - Churn - Contraction) / Start ARR x 100 | >120% excellent; 100-120% good; <90% problem | +| **Expansion Revenue** | Upsells + Cross-sells + Usage Growth | Should be 20-30% of total revenue | +| **Quick Ratio** | (New MRR + Expansion MRR) / (Churned MRR + Contraction MRR) | >4 excellent; 2-4 healthy; <2 leaky bucket | + +**Churn compounding:** 3% monthly != 36% annual. Use `Annual Churn = 1 - (1 - Monthly)^12`. 3% monthly = ~31% annual. 5% monthly = ~46% annual. + +### Analysis Frameworks + +**Revenue Mix:** Product/Segment Revenue / Total Revenue x 100. No single product >60% ideal. Top customer <10% revenue; top 10 <40%. + +**Cohort Analysis:** Group customers by join date, track retention/expansion over time. Recent cohorts should perform same or better than older ones. If newer cohorts degrade, PMF is eroding -- stop scaling, fix product. + +## Unit Economics & Efficiency + +### Customer-Level Profitability + +| Metric | Formula | Benchmarks | +|--------|---------|------------| +| **Gross Margin** | (Revenue - COGS) / Revenue x 100 | SaaS: 70-85% good; <60% concerning | +| **CAC** | Total S&M Spend / New Customers Acquired | Enterprise: $10K+ ok; SMB: <$500 target | +| **LTV (simple)** | ARPU x Avg Customer Lifetime (months) | Must be 3x+ CAC | +| **LTV (better)** | ARPU x Gross Margin % / Monthly Churn Rate | Use this for decisions | +| **LTV:CAC** | LTV / CAC | <1:1 unsustainable; 1-3:1 marginal; 3-5:1 healthy; >5:1 underinvesting | +| **Payback Period** | CAC / (Monthly ARPU x Gross Margin %) | <12mo great; 12-18 ok; >24 concerning | +| **Contribution Margin** | (Revenue - All Variable Costs) / Revenue x 100 | 60-80% good; <40% concerning | +| **Gross Margin Payback** | CAC / (Monthly ARPU x Gross Margin %) | Same formula as Payback above; use this version | + +**COGS includes:** Hosting, infrastructure, payment processing, customer onboarding costs. +**Variable costs include:** COGS + support + payment processing + variable customer success. + +**Critical insight:** 4:1 LTV:CAC with 36-month payback is a cash trap. 3:1 LTV:CAC with 8-month payback is better for growth. + +### Capital Efficiency + +| Metric | Formula | Benchmarks | +|--------|---------|------------| +| **Burn Rate (Gross)** | Total Monthly Cash Spent | Context-dependent | +| **Burn Rate (Net)** | Monthly Cash Spent - Monthly Revenue | Early <$200K manageable; >$500K needs revenue path | +| **Runway** | Cash Balance / Monthly Net Burn | 12+ good; 6-12 ok; <6 crisis. Raise at 6-9 months, not 3 | +| **OpEx** | S&M + R&D + G&A | Should grow slower than revenue | +| **Net Income** | Revenue - COGS - OpEx | Early negative ok; mature 10-20%+ margin | + +**Working capital:** Annual contracts paid upfront boost cash. Monthly billing delays collection. Cash-based runway != revenue-based runway. + +### Efficiency Ratios + +| Metric | Formula | Benchmarks | +|--------|---------|------------| +| **Rule of 40** | Revenue Growth % + Profit Margin % | >40 healthy; 25-40 ok; <25 concerning | +| **Magic Number** | (Q Revenue - Prev Q Revenue) x 4 / Prev Q S&M Spend | >0.75 scale; 0.5-0.75 optimize; <0.5 fix GTM | +| **Operating Leverage** | Revenue Growth Rate vs OpEx Growth Rate | Revenue growth must exceed OpEx growth | + +**Rule of 40 by stage:** Early = 60% growth + (-20%) margin = 40. Growth = 40% + 5% = 45. Mature = 20% + 25% = 45. + +## Business Health Diagnostic + +### Four-Dimension Framework + +1. **Growth & Retention** -- Revenue growth, NRR, churn, Quick Ratio +2. **Unit Economics** -- CAC, LTV, LTV:CAC, payback, gross margin +3. **Capital Efficiency** -- Burn, runway, Rule of 40, Magic Number +4. **Strategic Position** -- Market pricing, moat, concentration, leverage + +### Stage-Specific Benchmarks + +| Metric | Early (<$10M ARR) | Growth ($10-50M) | Scale ($50M+) | +|--------|-------------------|-------------------|---------------| +| Growth YoY | >50% | >40% | >25% | +| LTV:CAC | >3:1 | -- | -- | +| NRR | -- | >100% | >110% | +| Gross Margin | >70% | -- | -- | +| Rule of 40 | -- | >40 | >40 | +| Magic Number | -- | >0.75 | -- | +| Profit Margin | negative ok | -- | >10% | +| Runway | >12 months | -- | positive cash flow | + +### Red Flag Severity + +**Critical (fix immediately):** Runway <6mo, LTV:CAC <1.5:1, churn accelerating cohort-over-cohort, NRR <90%, Magic Number <0.3. + +**High priority (fix within quarter):** Rule of 40 <25, payback >24mo, Quick Ratio <2, gross margin <60%, revenue concentration >50% in top 10. + +**Medium priority (address within 6 months):** NRR 90-100%, Magic Number 0.3-0.5, negative operating leverage, stable but high churn (>5% monthly). + +### Diagnostic Scoring + +- **Healthy:** All dimensions at/above stage benchmarks, no critical flags, improving trends. Action: scale aggressively. +- **Moderate:** 1-2 dimensions need attention, medium-priority flags. Action: fix specific issues before scaling further. +- **Concerning:** Multiple critical flags, 2+ dimensions problematic. Action: urgent intervention -- stop scaling, fix retention and unit economics. +- **Critical:** Runway <3mo or LTV:CAC <1:1. Action: survival mode -- emergency fundraise or cut burn 50%+. + +## Feature Investment Analysis + +### Revenue Connection Types + +1. **Direct monetization** -- new tier, paid add-on, usage fee. Calculate: Customer Base x Adoption Rate x Price. +2. **Retention improvement** -- addresses churn reason. Calculate: LTV Impact = Lifetime Increase x Base x ARPU x Margin. +3. **Conversion improvement** -- trial-to-paid lift. Calculate: Trial Users x Conversion Lift x ARPU. +4. **Expansion enabler** -- upsell/cross-sell path. Calculate: Base x Expansion Rate x ARPU Increase. + +### ROI Thresholds + +| Scenario | Build if | Don't build if | +|----------|----------|----------------| +| Direct monetization | ROI >3x year one | Negative contribution margin in downside case | +| Retention feature | LTV impact >10x dev cost | Payback exceeds avg customer lifetime | +| Strategic override | Competitive moat, platform enabler, compliance | "Strategic" without clear definition | + +### Cost Structure Check + +- One-time: development cost (team size x time) +- Ongoing: COGS impact (hosting, infra) + OpEx (support, maintenance) +- Margin impact: if COGS >20% of projected revenue, flag margin dilution +- Contribution margin: (Revenue - COGS) / Revenue must stay positive + +### Decision Patterns + +**Build now:** ROI >3:1 (direct) or LTV impact >10:1 (retention), positive contribution margin, payback < customer lifetime. + +**Build for strategic reasons:** ROI <2:1 but competitive moat, platform enabler, or compliance. Cap investment, monitor adoption, re-evaluate at 6 months. + +**Don't build:** ROI <1:1, negative contribution margin, no strategic value. Consider reducing scope or changing monetization. + +**Build later:** High uncertainty in adoption or impact assumptions. Validate with surveys, prototypes, churn interviews first. + +## Channel Economics + +### Channel Evaluation Framework + +Evaluate each channel on four dimensions: + +1. **Unit economics** -- CAC, LTV, LTV:CAC, payback (per channel, not blended) +2. **Customer quality** -- cohort retention, churn rate, NRR, ICP fit (per channel) +3. **Scalability** -- Magic Number, addressable volume, CAC trend +4. **Strategic fit** -- segment match, sales motion compatibility + +### Channel Decision Matrix + +| LTV:CAC | Payback | Customer Quality | Scalability | Decision | +|---------|---------|------------------|-------------|----------| +| >3:1 | <12mo | Good retention | High volume | **Scale aggressively** | +| 2-3:1 | 12-18mo | Average retention | Medium | **Test & optimize** | +| <2:1 | >18mo | Poor retention | Low | **Kill or fix** | + +### Scale Criteria + +Scale when ALL met: LTV:CAC >3:1 AND payback <12mo AND Magic Number >0.75 AND customer quality >= blended. Increase budget 50-100%, monitor weekly for CAC increase >20% (saturation signal). + +### Optimize Playbook + +- **If CAC too high:** Improve conversion rate, reduce cost-per-click, shorten sales cycle. +- **If LTV too low:** Improve onboarding for channel cohort, target higher-value segments, add expansion plays. +- **If targeting off:** Narrow audience, improve messaging, add qualification step. +- Timeline: 4-8 weeks. Target LTV:CAC >3:1, payback <12mo. If unachievable, kill. + +### Kill Criteria + +LTV:CAC <1.5:1 with no clear improvement path. Reallocate budget to top-performing channel. Exception: strategic channels (enterprise field sales) get capped spend and 6-12 month runway to prove out. + +### Incrementality + +Test with holdout groups. Only count truly incremental conversions. Retargeting campaigns often claim credit for conversions that would have happened organically. + +## Pricing Analysis + +### Pricing Change Types + +- **Price increase** -- new customers only (grandfather existing) vs all customers +- **New premium tier** -- upsell path, watch cannibalization +- **Paid add-on** -- monetize feature; assess retention risk if previously free +- **Usage-based** -- charge per unit (seats, API calls, storage); enables expansion revenue +- **Discount strategy** -- annual prepay (cash flow), volume (larger deals), promotional (urgency) +- **Packaging change** -- rebundle features, change pricing metric + +### Five-Dimension Impact Assessment + +1. **Revenue:** ARPU lift = (New ARPU - Current ARPU) / Current ARPU. Expected MRR increase = Base x ARPU Lift. +2. **Conversion:** Higher prices may reduce trial-to-paid. Model conversion drop and its effect on new customer volume. +3. **Churn:** Model scenarios -- conservative (+2pp churn), base (+1pp), optimistic (+0). Churn-driven MRR loss = additional churn % x base x new ARPU. +4. **Expansion:** Does change create upsell path? Usage-based pricing enables natural expansion as customers grow. +5. **CAC Payback:** Higher ARPU = faster payback, but lower conversion = higher effective CAC. Calculate net effect. + +### Decision Patterns + +**Implement broadly:** Net revenue clearly positive (>10% ARPU lift, <5% churn risk), minimal conversion impact. Grandfather existing customers. + +**Test first (A/B):** Uncertain impact, moderate risk. Test 60-90 days with 100+ customers per cohort. Roll out if conversion stays within acceptable range. + +**Modify approach:** Original proposal too risky. Options: smaller increase, grandfather existing, segment-based pricing (raise enterprise only). + +**Don't change:** Churn-driven loss exceeds revenue gains, or high competitive pressure. Focus on retention/expansion instead. + +### Annual Discount Guardrails + +Limit to 10-15% for annual prepay. 30% annual discounts destroy LTV. Balance cash flow improvement with revenue protection. + +## Quality Gates + +### Vanity Metric Traps + +- **Revenue without margin:** $1M at 80% margin >> $2M at 20% margin +- **ARPU growth from mix shift:** ARPU rose because small customers churned, not because monetization improved +- **Signups without conversion:** 10,000 signups at 5% conversion = 500 customers. Calculate CAC on paid, not signups +- **Engagement without revenue:** Feature increases engagement but not retention or monetization -- not a business outcome +- **Gross revenue hiding net contraction:** Track discounts and refunds; gross up 20% but discounts doubled = flat net + +### Blended Metric Dangers + +Never use blended averages for decisions. Always segment by: +- **Channel:** One channel at $10K CAC hides in $500 blended CAC +- **Segment:** $100 ARPU blends $10 SMB and $1,000 enterprise -- useless for decisions +- **Cohort:** Blended 3% churn hides newer cohorts at 6% and old cohorts at 1% +- **Product:** 67% legacy product dying at -5% growth masked by 33% new product at +80% + +### Common Calculation Errors + +- **LTV without margin:** Use `ARPU x Margin % / Churn`, not `ARPU x Lifetime` +- **Churn multiply-by-12:** Churn compounds. 3% monthly = 31% annual, not 36% +- **Payback without margin:** Use gross margin payback, not revenue payback +- **CAC comparison without payback:** $5K CAC with 24mo payback is worse than $8K CAC with 8mo payback +- **Rule of 40 without runway:** Score of 50 means nothing with 3 months runway +- **LTV:CAC without payback:** 6:1 ratio with 48-month payback is a cash trap + +### Decision-Making Anti-Patterns + +- Scaling acquisition when Quick Ratio <2 (leaky bucket) +- Raising prices without modeling churn scenarios +- Celebrating NRR >100% from low churn alone (not expansion-driven) +- Using "strategic" as catch-all for building low-ROI features +- Fixing everything simultaneously instead of prioritizing top 1-3 issues +- Killing channels before 3-6 months and 100+ customers of data +- Over-relying on one channel (>50% of acquisition) +- Annual discounts >15% that destroy LTV for short-term cash +- Testing pricing on 10 customers (need 100+ per cohort for significance) +- Celebrating feature requests from 0.5% of base while ignoring the other 99.5% diff --git a/skills/pm-agent/knowledge/strategy-positioning.md b/skills/pm-agent/knowledge/strategy-positioning.md new file mode 100644 index 0000000..dd81d1c --- /dev/null +++ b/skills/pm-agent/knowledge/strategy-positioning.md @@ -0,0 +1,241 @@ +# Strategy & Positioning + +Compressed knowledge module covering company/market research, positioning, product strategy, prioritization, and roadmap planning. + +## Company & Market Research + +### Company Research Framework + +Research across 7 dimensions: Company Overview, Executive Quotes, Product Insights, Transformation Strategies, Organizational Impact, Future Roadmap, Product-Led Growth. + +**Research steps:** +1. Define scope: company name, research purpose, 3 key questions +2. Gather overview: headquarters, industry, founding, size, key milestones +3. Extract executive quotes: CEO (vision), COO (operations), VP Product (strategy), Group PM (initiatives). Cite source + date. Prioritize last 12-24 months. +4. Document product insights: strategy overview, recent launches with market impact, product philosophy/principles +5. Identify transformation strategies: digital (architecture shifts), AI (ML in product), Agile (methodology adoption) +6. Map organizational PM impact: PM role in strategic decisions, cross-functional collaboration model, career paths +7. Analyze future roadmap: planned initiatives, anticipated challenges, competitive threats +8. Document PLG insights: self-serve onboarding, data-driven decisions, activation/retention/expansion patterns +9. Synthesize: 3 strategic principles, 3 PM lessons, unanswered questions + +**Source priority:** Earnings transcripts > podcast interviews > conference talks > executive blog posts > LinkedIn > company website. Go deeper than "About Us" pages. + +### PESTEL Analysis + +Six macro-environmental factors. Define scope first: product name, analysis purpose, geographic scope, time horizon. + +| Factor | Key Questions | Example Sources | +|--------|--------------|-----------------| +| **Political** | Government policies, stability, trade regs, taxation | Legislative databases, trade reports | +| **Economic** | GDP growth, inflation, exchange rates, consumer spending | Census Bureau, BLS, World Bank | +| **Social** | Demographics, cultural trends, lifestyle shifts, attitudes | Pew Research, demographic studies | +| **Technological** | Advancements, R&D activity, automation, digital adoption | Gartner, industry reports | +| **Environmental** | Climate impact, sustainability, resource scarcity, green regs | If impact is minimal, say so honestly | +| **Legal** | Compliance (GDPR, AI Act), IP, employment law, safety regs | Legal databases, regulatory filings | + +**For each factor:** State the specific impact on your product and what strategic action it implies. Generic statements ("regulations exist") are useless. + +**Synthesis output:** Top 3 opportunities (with actions), top 3 threats (with mitigations), 3 strategic recommendations. Reassess annually or on major external events. + +### TAM/SAM/SOM Calculation + +Three-tier market sizing with citation-backed data. + +**TAM** = Total market demand at 100% capture. Broadest possible. +**SAM** = TAM narrowed by geography, firmographics, product constraints. "Who can we actually reach?" +**SOM** = SAM narrowed by competition, GTM capacity. "What can we capture in 1-3 years?" Typically 1-20% of SAM in Year 1-3. + +**Calculation process:** +1. Define problem space (B2B SaaS, consumer fintech, healthcare, etc.) +2. Select geographic region (US = Census/BLS data; EU = Eurostat; Global = World Bank/IMF) +3. Identify industry segments with population + revenue data +4. Narrow to target customer segment with firmographics/demographics + +**Output format:** For each tier, show population estimate, market size ($), calculation math, source citation with URL, and key assumptions. + +**Year 1-3 projections for SOM:** Include customer count and revenue. Ground in GTM constraints (sales capacity, conversion rates, marketing budget). + +**Data sources:** US Census Bureau, BLS, IBISWorld, Statista, Gartner, Forrester, World Bank, Eurostat. + +## Product Positioning + +### Geoffrey Moore Positioning Statement + +Two-part structure from *Crossing the Chasm*: + +**Value Proposition:** +- **For** [specific target customer/persona] +- **that need** [underserved need -- pains, gains, JTBD] +- [product name] +- **is a** [product category] +- **that** [benefit statement -- outcomes, not features] + +**Differentiation Statement:** +- **Unlike** [primary competitor or actual substitute behavior] +- [product name] +- **provides** [unique differentiation -- outcomes, not features] + +### Stress Tests (apply to every draft) + +1. Would the target customer recognize themselves in the "For" statement? +2. Can you point to research validating the need? +3. Does the category anchor you against the right competitors (or box you in)? +4. Is differentiation provable with a demo, case study, or data? +5. Does this positioning help answer "Should we build feature X?" + +### Positioning Workshop Flow (Interactive) + +5-question discovery sequence: +1. **Target customer segment** -- B2B SMB / B2B Enterprise / B2C mass / B2C niche (or custom) +2. **Underserved need** -- Adapted to segment from Q1 (time waste, lack of visibility, compliance burden, costly inefficiency) +3. **Product category** -- Anchors buyer evaluation. Pick existing category unless you have strong rationale for category creation. +4. **Key benefit** -- Outcome, not feature. Must be measurable (time saved, errors reduced, cost cut). +5. **Competitive differentiation** -- Name the actual competitor or substitute behavior. Differentiate on outcomes. + +Output: Complete positioning statement + one-sentence summary + stress-test checklist + next steps (test with 5 customers, share with stakeholders, apply to artifacts). + +### Positioning Quality Criteria + +- Target specificity: describable to a recruiter +- Need clarity: emotionally resonant, not generic +- Category fit: helps buyer evaluation, not "next-generation platform" +- Outcome focus: what user gets, not what product has +- Competitor honesty: real alternative buyers consider +- Differentiation durability: not copyable in 6 months + +## Product Strategy + +### Strategy Session Phases (2-4 week process) + +**Phase 1: Positioning & Market Context (Days 1-2)** +- Run positioning workshop. Define proto-personas. Map JTBD. +- Decision gate: Enough customer context? If NO, run 5-10 discovery interviews (+1 week). + +**Phase 2: Problem Framing & Validation (Days 3-5)** +- Run problem framing canvas. Create formal problem statement. Optional: customer journey map. +- Decision gate: Problem validated? If NO, run discovery interviews (+1 week). + +**Phase 3: Solution Exploration (Week 2, Days 1-3)** +- Generate opportunity solution tree (3 opportunities, 3 solutions each, POC recommendation). Define epic hypotheses. +- Decision gate: Need to test solutions? If YES (high uncertainty), run experiments (+1-2 weeks). + +**Phase 4: Prioritization & Roadmap (Week 2, Days 4-5)** +- Choose prioritization framework. Score and rank epics. Sequence roadmap by release. Optional: TAM/SAM/SOM for exec presentations. + +**Phase 5: Stakeholder Alignment (Week 3)** +- Present strategy: positioning + problem + solutions + prioritization + roadmap. +- Include "What's NOT on roadmap and why." Refine based on feedback. + +**Phase 6: Execution Planning (Week 4)** +- Break top epic using splitting patterns (workflow, CRUD, business rules). Write user stories with acceptance criteria. Plan first sprint. + +**Decision gates are mandatory.** Skipping them causes building solutions to unvalidated problems or wasting time on low-uncertainty activities. + +## Prioritization + +### Framework Selection Matrix + +| Context | Recommended Framework | Why | +|---------|----------------------|-----| +| Pre-PMF, minimal data, small team | **ICE** or **Value/Effort matrix** | Lightweight, gut-check, fast scoring | +| Early PMF, some data, aligned team | **RICE** | Structured but not overwhelming; balances data + speed | +| Mature product, rich data | **Opportunity Scoring** or **Kano** | Leverages analytics, customer surveys | +| Multiple stakeholders, misaligned | **Weighted Scoring** or **Buy-a-Feature** | Transparent, consensus-building | +| Large org, cross-team dependencies | **Cost of Delay** or **Impact Mapping** | Handles coordination complexity | +| Strategic bets vs. quick wins | **Value/Effort matrix** | Visual, intuitive for tradeoff conversations | + +### RICE Scoring + +Formula: `(Reach x Impact x Confidence) / Effort` +- **Reach:** Users affected per month/quarter +- **Impact:** 1 (minimal), 2 (high), 3 (massive) +- **Confidence:** 50% (low data), 80% (good data), 100% (certain) +- **Effort:** Person-months (include design, eng, QA) + +Use RICE as input, not automation. PM judgment overrides scores when strategic context requires it. Always adjust for strategic fit after raw scoring. + +### Prioritization Decision Logic + +4-question assessment to select framework: +1. Product stage (pre-PMF / early PMF / mature / multi-product) +2. Team context (small + focused / cross-functional aligned / stakeholders misaligned / large org) +3. Primary challenge (too many ideas / stakeholder disagreement / no data-driven process / strategic vs. tactical tradeoffs) +4. Data availability (minimal / some / rich) + +Stick with one framework 6-12 months. Reassess only when stage or context changes. + +## Roadmap Planning + +### Roadmap Types + +| Type | Structure | Best For | +|------|-----------|----------| +| **Now/Next/Later** | Committed / High confidence / Exploration | Agile teams, uncertainty, continuous discovery | +| **Theme-Based** | Strategic themes (Retention, Enterprise, Mobile) | Exec communication, strategic intent | +| **Timeline (Quarters)** | Q1: A, B; Q2: C, D; Q3: E, F | Resource planning, stakeholder comm | +| **Feature-Based** | Lists features without context | Anti-pattern. No strategic narrative. | + +### Roadmap Planning Process (5 phases, 1-2 weeks) + +**Phase 1: Gather Inputs (Days 1-2)** +- Business goals: top 3 company priorities, key metrics, strategic bets +- Customer problems: top 3-5 validated pain points (from discovery) +- Technical constraints: blockers, enabling investments, migrations +- Stakeholder requests: sales, marketing, CS inputs (not yet committed) + +**Phase 2: Define Initiatives (Days 3-4)** +- Write epic hypotheses: "We believe [building X] for [persona] will achieve [outcome] because [assumption]." +- T-shirt size effort: S (1-2 wk), M (3-4 wk), L (2-3 mo), XL (3+ mo) +- Map each epic to primary business outcome + +**Phase 3: Prioritize (Day 5)** +- Select framework using prioritization advisor +- Score all epics collaboratively (PM + eng + product leadership) +- Adjust scores for strategic fit (strategic overrides are legitimate) + +**Phase 4: Sequence (Days 6-7)** +- Map dependencies (technical and logical) +- Assign to Now (committed), Next (high confidence), Later (exploration) +- Validate sequence with engineering for feasibility + +**Phase 5: Communicate (Week 2)** +- Presentation structure: strategic context, roadmap overview, per-quarter deep dive, what's NOT on roadmap (and why), dependencies and risks +- Focus on strategic narrative: "Here's why X over Y" +- Frame as plan, not commitment: "Subject to change based on learning" +- Gather feedback, refine, publish internally (and optionally externally in Now/Next/Later format) + +## Quality Gates + +### Positioning Anti-Patterns +- **"For Everyone"** -- No one feels it's for them. Pick the first segment; expand later. +- **Feature Creep in Benefits** -- "AI, automation, analytics" is a feature list. Lead with outcome. +- **Imaginary Competitor** -- "Unlike outdated legacy systems" is a straw man. Name the actual alternative. +- **Category Confusion** -- "Next-generation platform for digital transformation" has no mental shelf. Pick a known category or commit to category creation. +- **Differentiation Without Proof** -- "Revolutionary AI" without evidence is noise. Make it falsifiable. + +### Research Anti-Patterns +- **Surface-Level Research** -- Find executive interviews and product blogs, not just "About Us" pages. +- **No Citations** -- Always cite source + date. Unverifiable = low credibility. +- **Analysis Without Action** -- PESTEL and company research must end in strategic recommendations, not just lists. +- **Outdated Information** -- Prioritize sources from last 12-24 months. + +### Market Sizing Anti-Patterns +- **TAM Without Citations** -- Cite industry reports (Gartner, IBISWorld, Statista) with URLs. +- **SOM = SAM** -- No market has zero competition. SOM = 1-20% of SAM in Year 1-3. +- **No Population Estimates** -- Always include customer counts alongside dollar amounts. +- **Ignoring GTM Constraints** -- Ground SOM in sales capacity, conversion rates, marketing budget. + +### Prioritization Anti-Patterns +- **Wrong Framework for Stage** -- Pre-PMF startup using weighted scoring with 10 criteria kills speed. +- **Framework Whiplash** -- Switching frameworks every quarter causes confusion. Stick for 6-12 months. +- **Scores as Gospel** -- Scores are input, not automation. Strategic context overrides. +- **Solo PM Scoring** -- Collaborative scoring (PM + design + eng) builds buy-in. +- **HiPPO Prioritization** -- Any framework beats "who shouts loudest." + +### Roadmap Anti-Patterns +- **Feature-Driven Roadmap** -- Frame epics as hypotheses with success metrics, not feature names. +- **Roadmap as Commitment** -- Communicate as strategic plan, subject to change based on learning. +- **No Dependencies Mapped** -- Validate sequence with engineering. Unmapped deps = blocked quarters. +- **Solo PM Roadmap** -- Gather inputs from all stakeholders (Phase 1), present draft for feedback (Phase 5). +- **Strategy Without Exec Sponsorship** -- Secure exec commitment upfront. Schedule alignment presentation before starting. diff --git a/skills/pm-agent/package.json b/skills/pm-agent/package.json new file mode 100644 index 0000000..1790e0c --- /dev/null +++ b/skills/pm-agent/package.json @@ -0,0 +1,31 @@ +{ + "name": "pm-agent-skill", + "version": "1.0.1", + "description": "AI-native PM agent skill — PRD, user stories, roadmaps, SaaS metrics, positioning, discovery interviews, career coaching, and AI product strategy.", + "keywords": [ + "openclaw-skill", + "agent-skill", + "product-management", + "prd", + "user-story", + "roadmap", + "saas-metrics", + "claude-code", + "ai-agent", + "skill-md" + ], + "homepage": "https://github.com/Digidai/product-manager-skills", + "repository": { + "type": "git", + "url": "https://github.com/Digidai/product-manager-skills.git" + }, + "author": "Gene Dai (https://genedai.me/)", + "license": "CC-BY-NC-SA-4.0", + "files": [ + "SKILL.md", + "knowledge/", + "templates/", + "README.md", + "LICENSE" + ] +} diff --git a/skills/pm-agent/templates/business-health-scorecard.md b/skills/pm-agent/templates/business-health-scorecard.md new file mode 100644 index 0000000..0b87d1a --- /dev/null +++ b/skills/pm-agent/templates/business-health-scorecard.md @@ -0,0 +1,42 @@ +# Business Health Scorecard + +## Company Context +- **Company:** [Name] +- **Stage:** [Pre-$10M / $10M-$50M / $50M+ ARR] +- **Model:** [SaaS / usage-based / hybrid] + +## Growth & Retention + +| Metric | Value | Benchmark | Status | +|--------|-------|-----------|--------| +| Revenue Growth (YoY) | | | | +| NRR (Net Revenue Retention) | | | | +| Gross Churn Rate | | | | +| Quick Ratio | | | | + +## Unit Economics + +| Metric | Value | Benchmark | Status | +|--------|-------|-----------|--------| +| CAC | | | | +| LTV | | | | +| LTV:CAC | | | | +| Payback Period | | | | +| Gross Margin | | | | + +## Capital Efficiency + +| Metric | Value | Benchmark | Status | +|--------|-------|-----------|--------| +| Burn Rate | | | | +| Runway | | | | +| Rule of 40 | | | | +| Magic Number | | | | + +## Red Flags +- [ ] [Critical / High / Medium — description] + +## Priority Actions +1. [Highest-urgency fix + expected impact] +2. [Second priority] +3. [Third priority] diff --git a/skills/pm-agent/templates/discovery-interview-plan.md b/skills/pm-agent/templates/discovery-interview-plan.md new file mode 100644 index 0000000..3720d7b --- /dev/null +++ b/skills/pm-agent/templates/discovery-interview-plan.md @@ -0,0 +1,33 @@ +# Discovery Interview Plan + +## Research Goal +- [What you're trying to learn — not what you're trying to prove] + +## Target Segment +- **Who:** [Customer persona / segment] +- **Sample size:** [Number of interviews] +- **Access method:** [Recruited, cold outreach, existing users] + +## Methodology +- [JTBD switch interviews / problem validation / retention cohort / other] + +## Interview Framework + +### Opening (2 min) +- Context-setting, consent, no-wrong-answers framing + +### Core Questions (25 min) +1. [Question targeting primary research goal] +2. [Question exploring current behavior / workarounds] +3. [Question probing emotional drivers / frustrations] +4. [Question testing switching triggers or alternatives] +5. [Question validating willingness to change] + +### Closing (3 min) +- Anything else? Referral ask. Thank you. + +## Biases to Watch +- [Leading questions, confirmation bias, solution-first thinking] + +## Success Criteria +- [What "we learned enough" looks like — e.g., 3+ users describe same pain point] diff --git a/skills/pm-agent/templates/epic-hypothesis.md b/skills/pm-agent/templates/epic-hypothesis.md new file mode 100644 index 0000000..5af0c8b --- /dev/null +++ b/skills/pm-agent/templates/epic-hypothesis.md @@ -0,0 +1,18 @@ +### If/Then Hypothesis + +**If we** [action or solution on behalf of the target persona] +**for** [target persona] +**Then we will** [desirable outcome or job-to-be-done] + +### Tiny Acts of Discovery Experiments + +**We will test our assumption by:** +- [Experiment 1] +- [Experiment 2] + +### Validation Measures + +**We know our hypothesis is valid if within** [timeframe] +**we observe:** +- [Quantitative measurable outcome] +- [Qualitative measurable outcome] diff --git a/skills/pm-agent/templates/opportunity-solution-tree.md b/skills/pm-agent/templates/opportunity-solution-tree.md new file mode 100644 index 0000000..1329b7f --- /dev/null +++ b/skills/pm-agent/templates/opportunity-solution-tree.md @@ -0,0 +1,25 @@ +## Desired Outcome +- [Business or product metric to move] + +## Opportunities (Problems to Solve) +1. [Opportunity 1] +2. [Opportunity 2] +3. [Opportunity 3] + +## Solutions per Opportunity +**Opportunity 1 Solutions:** +- [Solution 1] +- [Solution 2] +- [Solution 3] + +**Opportunity 2 Solutions:** +- [Solution 1] +- [Solution 2] + +## Experiments (per solution) +- [Experiment for Solution 1] +- [Experiment for Solution 2] + +## POC Selection +- **Chosen solution:** [Solution] +- **Rationale:** [Feasibility, Impact, Market Fit] diff --git a/skills/pm-agent/templates/positioning-statement.md b/skills/pm-agent/templates/positioning-statement.md new file mode 100644 index 0000000..d0fe483 --- /dev/null +++ b/skills/pm-agent/templates/positioning-statement.md @@ -0,0 +1,15 @@ +## Positioning Statement + +### Value Proposition + +**For** [target customer/persona] +- **that need** [underserved need] +- [product or service name] +- **is a** [product category] +- **that** [benefit statement focused on outcomes] + +### Differentiation Statement + +- **Unlike** [primary competitor or alternative] +- [product or service name] +- **provides** [unique differentiation focused on outcomes] diff --git a/skills/pm-agent/templates/prd.md b/skills/pm-agent/templates/prd.md new file mode 100644 index 0000000..cc18022 --- /dev/null +++ b/skills/pm-agent/templates/prd.md @@ -0,0 +1,48 @@ +# [Feature/Product Name] PRD + +## 1. Executive Summary +- One-paragraph overview (problem + solution + impact) + +## 2. Problem Statement +- Who has this problem? +- What is the problem? +- Why is it painful? +- Evidence (customer quotes, data, research) + +## 3. Target Users & Personas +- Primary persona(s) +- Secondary persona(s) +- Jobs-to-be-done + +## 4. Strategic Context +- Business goals (OKRs) +- Market opportunity (TAM/SAM/SOM) +- Competitive landscape +- Why now? + +## 5. Solution Overview +- High-level description +- User flows or wireframes +- Key features + +## 6. Success Metrics +- Primary metric (what we're optimizing for) +- Secondary metrics +- Targets (current → goal) + +## 7. User Stories & Requirements +- Epic hypothesis +- User stories with acceptance criteria +- Edge cases, constraints + +## 8. Out of Scope +- What we're NOT building (and why) + +## 9. Dependencies & Risks +- Technical dependencies +- External dependencies (integrations, partnerships) +- Risks and mitigations + +## 10. Open Questions +- Unresolved decisions +- Areas requiring discovery diff --git a/skills/pm-agent/templates/press-release.md b/skills/pm-agent/templates/press-release.md new file mode 100644 index 0000000..27d3b5d --- /dev/null +++ b/skills/pm-agent/templates/press-release.md @@ -0,0 +1,23 @@ +**Headline:** +"[Product/Feature Name] by [Company] Aims to [Main Benefit/Goal]" + +**Dateline:** +"[City], [Country], [Date] —" + +**Introduction:** +Today, [Company], a [type of organization], announced [key news], a [brief description]. This [product/feature] is set to [main benefit], addressing [key customer problem]. + +**Problem Paragraph:** +[Describe the customer problem and its impact. Include a supporting data point.] + +**Solution Paragraph:** +[Describe how the product solves the problem in outcome terms]. "[Customer-focused quote]," said [Company leader]. + +**Additional Details:** +[Supporting benefits, integrations, or data points.] + +**Boilerplate:** +[Company], founded in [year], is a [type of company] known for [main products/services]. + +**Call to Action:** +For more information about [product/feature], visit [website] or contact [media contact]. diff --git a/skills/pm-agent/templates/problem-statement.md b/skills/pm-agent/templates/problem-statement.md new file mode 100644 index 0000000..0972b23 --- /dev/null +++ b/skills/pm-agent/templates/problem-statement.md @@ -0,0 +1,26 @@ +## Problem Framing Narrative + +**I am:** [Key persona with 3-4 characteristics] +- [Pain point / characteristic 1] +- [Pain point / characteristic 2] +- [Pain point / characteristic 3] + +**Trying to:** +- [Desired outcomes the persona cares most about] + +**But:** +- [Barrier 1] +- [Barrier 2] +- [Barrier 3] + +**Because:** +- [Root cause, stated empathetically] + +**Which makes me feel:** +- [Emotions from the persona's perspective] + +## Context & Constraints +- [Geographic, technological, time-based, or demographic factors] + +## Final Problem Statement +- [Single, concise, empathetic summary sentence] diff --git a/skills/pm-agent/templates/roadmap-plan.md b/skills/pm-agent/templates/roadmap-plan.md new file mode 100644 index 0000000..ca6260b --- /dev/null +++ b/skills/pm-agent/templates/roadmap-plan.md @@ -0,0 +1,23 @@ +# Product Roadmap + +## Strategy Context +- [Business goals / OKRs] +- [Customer problems] +- [Constraints / dependencies] + +## Roadmap (Now / Next / Later) + +| Stage | Initiative | Outcome | Metric | Notes | +|---|---|---|---|---| +| Now | [Initiative] | [Outcome] | [Metric] | [Notes] | +| Next | [Initiative] | [Outcome] | [Metric] | [Notes] | +| Later | [Initiative] | [Outcome] | [Metric] | [Notes] | + +## Sequencing (Optional) +- Q1: [Initiatives] +- Q2: [Initiatives] +- Q3: [Initiatives] + +## Risks & Dependencies +- [Risk 1] +- [Dependency 1] diff --git a/skills/pm-agent/templates/user-story.md b/skills/pm-agent/templates/user-story.md new file mode 100644 index 0000000..298cc8b --- /dev/null +++ b/skills/pm-agent/templates/user-story.md @@ -0,0 +1,17 @@ +### User Story [ID]: + +- **Summary:** [Brief, memorable title focused on user value] + +#### Use Case: +- **As a** [user name / persona / role] +- **I want to** [action the user takes] +- **so that** [desired outcome for the user] + +#### Acceptance Criteria: +- **Scenario:** [Brief, human-readable scenario describing value] +- **Given:** [Initial context or precondition] +- **and Given:** [Additional context or preconditions] +- **When:** [Event that triggers the action] +- **Then:** [Expected outcome aligned to "so that"] + + diff --git a/skills/product-manager-skills/README.md b/skills/product-manager-skills/README.md new file mode 100644 index 0000000..7dc8e7d --- /dev/null +++ b/skills/product-manager-skills/README.md @@ -0,0 +1,210 @@ +# Product Manager Skills + +**Not a template pack. A PM operator for AI coding tools.** + +Turn Claude Code, Codex, Cursor, or Windsurf into a product manager that can critique PRDs, diagnose SaaS metrics, plan roadmaps, run discovery, and coach career moves. + +[![Release](https://img.shields.io/github/v/release/Digidai/product-manager-skills)](https://github.com/Digidai/product-manager-skills/releases) +[![License](https://img.shields.io/badge/license-CC%20BY--NC--SA%204.0-green)](LICENSE) +[![Security](https://img.shields.io/badge/security-zero%20scripts%2C%20pure%20markdown-brightgreen)](https://github.com/Digidai/product-manager-skills) +[![Works With](https://img.shields.io/badge/works%20with-Claude%20Code%20%7C%20Codex%20%7C%20Cursor%20%7C%20Windsurf-blue)](#install-in-60-seconds) + +> Zero scripts. Zero dependencies. Zero network calls. Pure Markdown knowledge you can inspect line by line before you install. + +## Why People Reuse It + +Most AI PM tooling is good at writing polished nonsense. This skill is designed for repeat workflows where rigor matters: + +- Turn vague feature requests into problem framing, measurable outcomes, and a usable PRD. +- Diagnose SaaS health from raw metrics instead of getting generic advice like "improve retention." +- Pressure-test prioritization, roadmaps, and strategy with explicit tradeoffs. +- Coach PM to Director to VP transitions with concrete gaps and action plans. + +## Start With These 3 Workflows + +| Workflow | Prompt | Example | +|---|---|---| +| **SaaS health diagnostic** | "Analyze these metrics: MRR $50k, 500 customers, gross margin 80%, monthly churn 8%, CAC $500." | [SaaS diagnostic demo](examples/saas-health-diagnostic.md) | +| **PRD pushback and review** | "Review this PRD draft like a strong PM peer. Flag bad framing, missing metrics, solution smuggling, and delivery risk." | [PRD review demo](examples/prd-review.md) | +| **Director readiness coaching** | "I'm a senior PM interviewing for Director roles in 90 days. Diagnose my gaps and coach me." | [Director coaching demo](examples/director-coaching.md) | + +More prompts: [STARTER-PROMPTS.md](STARTER-PROMPTS.md) +中文说明: [README.zh-CN.md](README.zh-CN.md) + +## Install In 60 Seconds + +### Claude Code / OpenClaw + +```bash +clawhub install product-manager-skills +``` + +### Codex / Cursor / Windsurf / GitHub-based skill loaders + +```bash +npx skills add Digidai/product-manager-skills +``` + +Then paste one of these: + +```text +Help me write a PRD for a notification preferences feature. Make reasonable assumptions and label them. + +Analyze these metrics: MRR $50k, 500 customers, gross margin 80%, monthly churn 8%, CAC $500. + +Review my roadmap and tell me where stakeholder requests are outweighing evidence. +``` + +## What Good Output Looks Like + +### 1. SaaS Diagnostic + +Input: + +```text +Analyze these metrics: MRR $50k, 500 customers, gross margin 80%, monthly churn 8%, CAC $500. +``` + +Expected behavior: + +```text +- 8% monthly churn compounds to roughly 63% annual churn. This is a red flag, not a "slightly high" metric. +- ARPA is about $100/month. With 80% gross margin and 8% monthly churn, better LTV is about $1,000. +- LTV:CAC is about 2:1. Payback is about 6.25 months. +- Diagnosis: payback is workable, retention is not. Do not scale acquisition until churn is understood cohort by cohort. +``` + +Full example: [examples/saas-health-diagnostic.md](examples/saas-health-diagnostic.md) + +### 2. PRD Review + +Input: + +```text +Review this PRD for a notification preferences center. Flag solution smuggling, weak metrics, overscoping, and delivery risk. +``` + +Expected behavior: + +```text +- Your problem statement is solution-smuggled: "users need a preferences dashboard." +- Success metrics have no baseline, target, or guardrail. +- Scope mixes channels, digests, quiet hours, admin rules, and migration. This is multiple releases. +- Recommend a thinner first slice: email opt-out + account-level preferences + measurable reduction in unsubscribe-driven churn. +``` + +Full example: [examples/prd-review.md](examples/prd-review.md) + +### 3. Career Coaching + +Input: + +```text +I'm a senior PM managing two PMs, strong on execution, weak on org influence, and interviewing for Director roles in 3 months. Coach me. +``` + +Expected behavior: + +```text +- Diagnosis: strong team altitude, weak org altitude. +- Gap: you describe execution wins well but not portfolio tradeoffs or cross-functional influence. +- Plan: collect 3 stories that show org-level impact, build a weekly visibility loop, and practice decision framing with tradeoffs. +``` + +Full example: [examples/director-coaching.md](examples/director-coaching.md) + +## What You Get + +| Domain | What It Helps With | Example Frameworks | +|---|---|---| +| **Discovery & Research** | Validate problems, prep interviews, map journeys, structure experiments | JTBD, Mom Test, Opportunity Solution Tree, Lean UX Canvas, PoL Probes | +| **Strategy & Positioning** | Position products, prioritize work, size markets, build roadmaps | Geoffrey Moore, PESTEL, TAM/SAM/SOM, RICE, ICE, Kano | +| **Artifacts & Delivery** | Write and critique PRDs, user stories, epics, PRFAQs, recommendation docs | Cohn + Gherkin, Story Mapping, Epic Breakdown, PRFAQ | +| **Finance & Metrics** | Calculate 32 SaaS metrics and diagnose business health | MRR, ARR, NRR, CAC, LTV, Rule of 40, Magic Number | +| **Career & Leadership** | Coach PM to Director to VP transitions | Altitude-Horizon, Three Ps, 30-60-90 onboarding | +| **AI Product Craft** | Pressure-test AI-native product decisions | AI-Shaped Readiness, Context Engineering, Agent Orchestration | + +## Why It Performs Better Than Generic Prompting + +| Generic prompting | This skill | +|---|---| +| Writes plausible PM text | Applies PM frameworks and quality gates | +| Accepts bad framing | Pushes back on Solution Smuggling, Metrics Theater, Feature Factory, and more | +| Gives generic churn advice | Calculates churn, LTV, payback, and names the real bottleneck | +| Asks you to repeat PM context every session | Carries a reusable PM workflow and routing system | +| Optimizes for politeness | Optimizes for decisions, tradeoffs, and next steps | + +## Who It Is For + +- Technical PMs, founders, and product leads who already work inside AI coding tools. +- Teams that want a reusable PM brain without sending product context to another SaaS. +- People who value pushback, assumptions, and explicit tradeoffs over nice-sounding output. + +## Who It Is Not For + +- Teams looking for a collaborative web app with approvals, comments, and sharing workflows. +- Users who only want passive template filling and never want the AI to challenge the framing. +- Non-technical buyers who prefer turnkey SaaS onboarding over local or repo-based installation. + +## Interaction Style + +This skill is optimized for a fast first useful draft: + +- If the request is clear enough, it answers immediately and labels assumptions inline. +- If context is partial, it gives the best draft first and only asks the minimum follow-up questions needed. +- If the task is genuinely exploratory, it can switch into guided mode one question at a time. +- Every answer is expected to end with decisions made, assumptions to validate, and a recommended next step. + +## Built For Repeat Usage + +Most PM work is recurring. This skill is strongest when you reuse it weekly: + +- Monday: review roadmap changes and prioritization requests. +- Mid-week: critique PRDs, epics, and user stories before sharing with engineering. +- Friday: run a SaaS health diagnostic or feature ROI check. +- Career season: rehearse interview stories, operating altitude, and leadership gaps. + +## Install Options + +| Environment | Install | +|---|---| +| Claude Code / OpenClaw | `clawhub install product-manager-skills` | +| Codex / Cursor / Windsurf | `npx skills add Digidai/product-manager-skills` | +| Claude Projects | Upload `SKILL.md`, `knowledge/`, and `templates/` | +| Any LLM with local file loading | Point the system prompt at `SKILL.md` and keep sibling folders intact | + +## Structure + +```text +SKILL.md +knowledge/ +templates/ +examples/ +STARTER-PROMPTS.md +README.zh-CN.md +``` + +Core repo size: about 25 Markdown files, ~2,200 lines, ~130 KB of PM knowledge and templates. + +## Trust And Security + +This project is instruction-only: + +- No executable scripts +- No external network calls +- No environment variables or credentials required +- No privilege escalation +- Every shipped file is human-readable Markdown + +## Feedback And Contribution + +- Open an issue if a framework is missing or a workflow feels weak. +- Open a discussion if you want a new domain or stronger examples. +- See [CONTRIBUTING.md](CONTRIBUTING.md) for the fastest way to give useful workflow feedback. +- If the skill helped you, star the repo or share an output generated from the templates. + +## License + +[CC BY-NC-SA 4.0](LICENSE) + +Built by [Gene Dai](https://genedai.me/). Distilled from real product work, not textbook summaries. diff --git a/skills/product-manager-skills/README.zh-CN.md b/skills/product-manager-skills/README.zh-CN.md new file mode 100644 index 0000000..ddd266d --- /dev/null +++ b/skills/product-manager-skills/README.zh-CN.md @@ -0,0 +1,95 @@ +# Product Manager Skills 中文说明 + +**这不是模板包,而是一个给 AI 编码工具安装的 PM 大脑。** + +它会把 Claude Code、Codex、Cursor、Windsurf 这类工具,变成一个能写 PRD、诊断 SaaS 指标、做路线图取舍、做用户研究框架化思考、以及辅导 PM 晋升的产品经理搭档。 + +## 它为什么更容易被反复使用 + +多数 AI 工具能把话说顺,但很难把 PM 判断做对。这个项目更适合这些高频场景: + +- 把模糊需求推进成有问题定义、有指标、有边界的 PRD +- 根据 MRR、churn、CAC、LTV 直接做业务健康诊断 +- 在路线图和优先级讨论中指出 tradeoff,而不是只会“建议平衡” +- 帮高级 PM 准备 Director / VP 级别的面试和能力迁移 + +## 60 秒安装 + +### Claude Code / OpenClaw + +```bash +clawhub install product-manager-skills +``` + +### Codex / Cursor / Windsurf + +```bash +npx skills add Digidai/product-manager-skills +``` + +安装后可以直接粘贴这些 prompt: + +```text +帮我写一个通知偏好功能的 PRD。缺失信息请合理假设,并明确标注。 + +分析这些指标:MRR 5 万美元,500 个客户,毛利率 80%,月流失 8%,CAC 500 美元。 + +帮我评审这个 roadmap,指出哪些地方是利益相关方在推,而不是证据在推。 +``` + +更多可直接复用的提示词见:[STARTER-PROMPTS.md](STARTER-PROMPTS.md) + +## 三个最值得先试的场景 + +| 场景 | 你会得到什么 | 示例 | +|---|---|---| +| **SaaS 业务诊断** | 它会算公式、给 benchmark、指出根因,不是泛泛建议 | [examples/saas-health-diagnostic.md](examples/saas-health-diagnostic.md) | +| **PRD 评审与挑错** | 它会指出 Solution Smuggling、指标缺失、范围过大、交付风险 | [examples/prd-review.md](examples/prd-review.md) | +| **晋升 / 面试辅导** | 它会判断你的“海拔”是否到 Director 级别,并给补齐方案 | [examples/director-coaching.md](examples/director-coaching.md) | + +## 这个项目包含什么 + +- 6 个知识域:发现研究、战略定位、交付执行、财务指标、职业发展、AI 产品 +- 12 个模板:PRD、User Story、Problem Statement、Roadmap、Competitive Analysis 等 +- 30+ 个框架:JTBD、Geoffrey Moore、PRFAQ、OST、RICE、Kano 等 +- 32 个 SaaS 指标:带公式、阶段基准值、红旗等级 +- 一套统一质量门槛:要求标注假设、量化结果、说明取舍、识别反模式 + +## 它和通用 AI 的区别 + +| 通用 AI | Product Manager Skills | +|---|---| +| 会把需求写得像样 | 会先判断问题定义是不是错了 | +| 会说“优化用户体验降低流失” | 会算出 8% 月流失约等于 63% 年流失,并判断是否应该先停投放 | +| 会接受模糊目标 | 会要求 baseline、target、timeframe | +| 容易顺着你说 | 会主动推回来,指出坏 framing 和错误取舍 | + +## 适合谁 + +- 已经在 AI 编码工具里工作的技术型 PM、Founder、产品负责人 +- 想把 PM 认知嵌到本地工作流里,而不是再买一个 SaaS 工具的人 +- 需要“会挑战你”的 AI,而不是只会把格式写完整的人 + +## 不适合谁 + +- 更想要带审批、协作、评论、共享的网页产品的团队 +- 只想套模板,不希望 AI 指出 framing 问题的人 +- 不愿意使用本地安装或 repo 型知识包的人 + +## 信任与安全 + +这是一个纯 Markdown 项目: + +- 没有脚本 +- 没有网络调用 +- 不需要密钥 +- 没有提权 +- 所有内容都可审查 + +## 相关文件 + +- 英文主 README:[README.md](README.md) +- 快速提示词:[STARTER-PROMPTS.md](STARTER-PROMPTS.md) +- 技能入口:[SKILL.md](SKILL.md) + +[CC BY-NC-SA 4.0](LICENSE) diff --git a/skills/product-manager-skills/SKILL.md b/skills/product-manager-skills/SKILL.md new file mode 100644 index 0000000..0628db5 --- /dev/null +++ b/skills/product-manager-skills/SKILL.md @@ -0,0 +1,215 @@ +--- +name: product-manager-skills +description: PM skill for Claude Code, Codex, Cursor, and Windsurf. Diagnoses SaaS metrics, critiques PRDs, plans roadmaps, runs discovery, coaches PM career transitions, and pressure-tests AI product decisions. Six knowledge domains, 12 templates, 30+ frameworks, and an opinionated interaction style that labels assumptions and names tradeoffs. +type: workflow +--- + +# Product Manager Skills + +## Identity + +You are a senior product manager. Not a tool — a PM. + +**Operating principles:** +- Outcome-oriented, not output-oriented. "What decision does this enable?" before "What document should I produce?" +- Evidence-driven. State assumptions explicitly. Label what's known vs. hypothesized. +- Opinionated with tradeoffs. Take a stance, name the tradeoff, never hedge with "it depends" alone. +- Specific > complete. One sharp example beats a page of generic advice. +- Compression by default. Say it in 3 bullets, not 3 paragraphs. Expand only when asked. +- Bias to action. End every interaction with a next step, not a summary. + +**What you are NOT:** +- A template filler. Templates are scaffolding — the thinking matters more than the format. +- A yes-machine. Push back when the user's framing is off, the scope is wrong, or the problem isn't clear. +- A knowledge dump. Don't recite frameworks — apply them to the user's specific situation. + +--- + +## Interaction Protocol + +**Simple requests → direct output.** If the user asks for a user story, write one. Don't ask 10 setup questions. + +**Activation-first default:** On the first response, prefer the fastest useful draft over a mode-selection ceremony. If you can produce a solid first version with reasonable assumptions, do that and label the assumptions inline. + +**Complex requests → choose a mode:** + +1. **Guided mode** — One question at a time, with progress labels (`Q1/6`, `Q2/6`). Best for discovery, diagnostics, strategy sessions. +2. **Context dump** — User pastes everything they know. You skip redundant questions, fill gaps, deliver output. +3. **Best guess** — You infer missing details, label every assumption with `[assumption]`, deliver immediately. User validates after. + +**How to pick the mode:** +- If the user explicitly asks for guidance or step-by-step collaboration → guided mode. +- If the request is ambiguous but a reasonable first draft is still possible → best guess mode, assumptions labeled. +- If the request is clear but needs 2-3 missing inputs → ask only those inputs, no ceremony. +- Only offer the three-mode choice when the user is deciding how to work, or when the wrong mode would waste substantial time. + +**During guided sessions:** +- One question per turn. Wait for answer before continuing. +- Show progress: `Context Q3/7` or `Assessment Q2/4`. +- At decision points, offer 3-5 numbered options. Accept `1`, `2 and 4`, `1,3`, or custom text. +- If interrupted ("how many questions left?"), answer directly, restate progress, resume. +- If user says stop/pause, halt immediately. Resume on explicit request. +- If user switches topic mid-flow, acknowledge the pivot, confirm abandoning current flow, and re-route. + +**Language:** Respond in the user's language. If they write in Chinese, respond in Chinese. If English, respond in English. + +**Every output ends with:** +- Decisions made (bullet list) +- Assumptions to validate (if any) +- Recommended next step + +--- + +## Execution Workflow + +When the user makes a request, follow this sequence: + +1. **Route:** Match intent to a framework in the Routing Table below. If ambiguous, ask one clarifying question. If clearly outside PM scope, say so and offer to redirect. +2. **Load knowledge:** Read the knowledge module file listed in the "Load" column. In pre-loaded environments (e.g., Claude Projects), the content is already in context — search by section name. The `knowledge/` and `templates/` directories are siblings of this SKILL.md file. +3. **Focus:** Within the loaded module, find the section closest to the Framework column name. If the route maps to multiple sections (e.g., "A + B"), read both. Apply that section's framework, decision logic, and domain-specific quality gates. +4. **Interact:** Use the Interaction Protocol above — direct output for simple requests, guided/dump/guess for complex ones. +5. **Template:** If producing a deliverable artifact (PRD, user story, positioning statement, etc.), also load the matching template from the Template Index. If no template exists for the artifact type, structure the output using the framework in the knowledge module. +6. **Quality check:** Apply the Universal Quality Gates (bottom of this file) to every output. The loaded knowledge module also has domain-specific quality gates — apply those too. +7. **Close:** End with decisions made, assumptions to validate, and recommended next step. + +**Multi-domain requests:** When intent spans two domains (e.g., "roadmap for an AI product"), the explicit ask determines the primary domain (roadmap → strategy). Load primary first. Mention secondary and offer to load it after the primary task completes. + +--- + +## Routing Table + +Match user intent to a framework and knowledge module. + +### Discovery & Research + +| User Intent | Framework | Load | +|---|---|---| +| "Validate a problem" / "test a hypothesis" | Problem Framing + PoL Probe Advisor | `knowledge/discovery-research.md` | +| "Customer interview" / "discovery interview" | Interview Prep | `knowledge/discovery-research.md` | +| "Map the customer journey" | Customer Journey > Journey Map / Journey Mapping Workshop | `knowledge/discovery-research.md` | +| "Opportunity mapping" / "solution tree" | Opportunity Solution Tree | `knowledge/discovery-research.md` | +| "Jobs to be done" / "JTBD" / "customer needs" | JTBD Framework | `knowledge/discovery-research.md` | +| "Frame the problem" / "problem canvas" | Problem Framing Canvas (MITRE) | `knowledge/discovery-research.md` | +| "Write a problem statement" | Problem Statement | `knowledge/discovery-research.md` | +| "Lean canvas" / "validate assumptions" | Lean UX Canvas | `knowledge/discovery-research.md` | +| "Run a discovery cycle" / "discovery sprint" | Discovery Process | `knowledge/discovery-research.md` | +| "PoL probe" / "proof of life" / "validation experiment" | PoL Probe Advisor | `knowledge/discovery-research.md` | +| "A/B test" / "experiment design" / "test plan" | PoL Probe Advisor | `knowledge/discovery-research.md` | + +### Strategy & Positioning + +| User Intent | Framework | Load | +|---|---|---| +| "Position my product" / "positioning statement" | Geoffrey Moore Positioning Statement | `knowledge/strategy-positioning.md` | +| "Positioning workshop" / "find our position" | Positioning Workshop Flow | `knowledge/strategy-positioning.md` | +| "Product strategy" / "strategy session" / "GTM strategy" | Strategy Session Phases | `knowledge/strategy-positioning.md` | +| "Research a company" / "competitive intel" / "competitive analysis" | Company Research Framework | `knowledge/strategy-positioning.md` | +| "PESTEL" / "macro environment" / "external factors" | PESTEL Analysis | `knowledge/strategy-positioning.md` | +| "Prioritize" / "prioritization framework" / "what to build next" | Prioritization > Framework Selection Matrix | `knowledge/strategy-positioning.md` | +| "Roadmap" / "roadmap planning" / "release plan" | Roadmap Planning Process | `knowledge/strategy-positioning.md` | +| "TAM SAM SOM" / "market size" / "addressable market" | TAM/SAM/SOM Calculation | `knowledge/strategy-positioning.md` | + +### Artifacts & Delivery + +| User Intent | Framework | Load | +|---|---|---| +| "Write a PRD" / "product requirements" | PRD Development | `knowledge/artifacts-delivery.md` | +| "Write a user story" / "acceptance criteria" | User Story (Cohn + Gherkin) | `knowledge/artifacts-delivery.md` | +| "Split this story" / "story too big" | User Story Splitting (8 patterns) | `knowledge/artifacts-delivery.md` | +| "Story map" / "user story mapping" | User Story Mapping | `knowledge/artifacts-delivery.md` | +| "Epic" / "epic hypothesis" / "frame this epic" | Epics > Epic Hypothesis | `knowledge/artifacts-delivery.md` | +| "Break down this epic" / "epic breakdown" | Epics > Epic Breakdown (9 Patterns) | `knowledge/artifacts-delivery.md` | +| "Proto-persona" / "persona" / "who is the user" | Proto-Persona | `knowledge/artifacts-delivery.md` | +| "Press release" / "PRFAQ" / "working backwards" | Press Release / PRFAQ | `knowledge/artifacts-delivery.md` | +| "Storyboard" / "visual narrative" | Storyboards | `knowledge/artifacts-delivery.md` | +| "Recommendation canvas" / "solution proposal" | Recommendation Canvas | `knowledge/artifacts-delivery.md` | +| "EOL" / "end of life" / "sunset" / "deprecation" | End-of-Life Communication | `knowledge/artifacts-delivery.md` | + +### Finance & Metrics + +| User Intent | Framework | Load | +|---|---|---| +| "SaaS metrics" / "revenue metrics" / "MRR" / "ARR" | SaaS Revenue & Growth Metrics | `knowledge/finance-metrics.md` | +| "Unit economics" / "CAC" / "LTV" / "payback" | Unit Economics & Efficiency | `knowledge/finance-metrics.md` | +| "Business health" / "diagnostic" / "board meeting prep" | Business Health Diagnostic | `knowledge/finance-metrics.md` | +| "Feature ROI" / "should we build this" / "investment case" | Feature Investment Analysis | `knowledge/finance-metrics.md` | +| "Acquisition channel" / "channel ROI" / "marketing spend" | Channel Economics | `knowledge/finance-metrics.md` | +| "Pricing" / "price change" / "ARPU impact" | Pricing Analysis | `knowledge/finance-metrics.md` | +| "Rule of 40" / "magic number" / "burn rate" | Capital Efficiency (Unit Economics) | `knowledge/finance-metrics.md` | +| "Retention" / "churn" / "why are users leaving" | Retention & Expansion Metrics + Business Health Diagnostic | `knowledge/finance-metrics.md` | +| "NRR" / "net revenue retention" / "expansion revenue" | Retention & Expansion Metrics | `knowledge/finance-metrics.md` | + +### Career & Leadership + +| User Intent | Framework | Load | +|---|---|---| +| "PM to Director" / "director transition" / "altitude horizon" | Altitude-Horizon Framework | `knowledge/career-leadership.md` | +| "Director interview" / "director readiness" / "preparing for Director" | PM to Director Transition | `knowledge/career-leadership.md` | +| "VP" / "CPO" / "executive transition" | Director to VP/CPO Transition | `knowledge/career-leadership.md` | +| "New role" / "first 90 days" / "onboarding as VP" / "onboarding as CPO" | Executive Onboarding (30-60-90) | `knowledge/career-leadership.md` | +| "Career advice" / "next step in my career" | Altitude-Horizon + Readiness Coaching | `knowledge/career-leadership.md` | + +### AI Product Craft + +| User Intent | Framework | Load | +|---|---|---| +| "AI product" / "AI-shaped" / "AI readiness" | AI-Shaped Readiness | `knowledge/ai-product-craft.md` | +| "Context engineering" / "context stuffing" / "prompt design" | Context Engineering | `knowledge/ai-product-craft.md` | +| "Agent workflow" / "multi-agent" / "AI orchestration" | Agent Orchestration | `knowledge/ai-product-craft.md` | +| "AI validation" / "test my AI feature" | AI Validation (PoL Probes) | `knowledge/ai-product-craft.md` | + +**Routing rules:** +1. If intent matches multiple domains, the explicit ask determines primary (see Execution Workflow above). +2. If intent is unclear, ask one clarifying question before loading. +3. If no match, use general PM reasoning and the Quality Gates below. Don't hallucinate a framework. + +--- + +## Template Index + +When producing a deliverable artifact, load the matching template and fill it with the user's specific content. Templates are pure scaffolding — not generic placeholders. + +| Template | Path | Use When | +|---|---|---| +| PRD | `templates/prd.md` | Writing product requirements documents | +| User Story | `templates/user-story.md` | Creating stories with acceptance criteria | +| Problem Statement | `templates/problem-statement.md` | Framing a user problem empathetically | +| Positioning Statement | `templates/positioning-statement.md` | Defining product market position | +| Epic Hypothesis | `templates/epic-hypothesis.md` | Framing epics as testable hypotheses | +| Press Release | `templates/press-release.md` | Working Backwards / PRFAQ | +| Discovery Interview Plan | `templates/discovery-interview-plan.md` | Preparing for customer interviews | +| Opportunity Solution Tree | `templates/opportunity-solution-tree.md` | Mapping outcomes → opportunities → solutions | +| Roadmap Plan | `templates/roadmap-plan.md` | Building Now/Next/Later roadmaps | +| Business Health Scorecard | `templates/business-health-scorecard.md` | Diagnosing SaaS business health | +| Competitive Analysis | `templates/competitive-analysis.md` | Analyzing competitors and market position | +| Lean UX Canvas | `templates/lean-ux-canvas.md` | Structuring hypotheses and experiments | + +--- + +## Quality Gates + +Two tiers: **universal gates** (below, apply to every output) and **domain gates** (in each knowledge module's Quality Gates section, apply when that module is loaded). Always check both. + +### Universal Gates + +#### 1. Assumptions Must Be Labeled +If you're guessing, say so. Mark assumptions with `[assumption]` inline. Never present inferred data as fact. + +#### 2. Outcomes Must Be Measurable +"Improve the experience" is not a success metric. Every outcome needs a number, a direction, and a timeframe. "Reduce time-to-first-value from 14 days to 3 days within Q2." + +#### 3. Roles Must Be Specific +"Users" is not a persona. Every artifact must name the role, context, and motivation. "A mid-market ops manager running 3 product lines with no dedicated analytics support" — that's specific. + +#### 4. Tradeoffs Must Be Named +Never present a recommendation without naming what you're trading off. "Recommend Option A (faster to market, lower initial quality) over Option B (more robust, 6-week delay)." + +#### 5. Anti-Patterns to Flag +When you spot these in user input, call them out directly: +- **Metrics Theater** — tracking metrics that look good but drive no decisions +- **Feature Factory** — shipping features without validating the problem +- **Stakeholder-Driven Roadmap** — roadmap shaped by loudest voice, not evidence +- **Confirmation Bias in Discovery** — asking questions designed to confirm existing beliefs +- **Premature Scaling** — optimizing growth before unit economics work +- **Horizontal Slicing** — splitting work by architecture layer instead of user value +- **Solution Smuggling** — problem statements that embed a solution ("We need a dashboard" vs "Managers can't see team velocity") diff --git a/skills/product-manager-skills/STARTER-PROMPTS.md b/skills/product-manager-skills/STARTER-PROMPTS.md new file mode 100644 index 0000000..0779c66 --- /dev/null +++ b/skills/product-manager-skills/STARTER-PROMPTS.md @@ -0,0 +1,101 @@ +# Starter Prompts + +Paste any of these directly after installation. Use English or Chinese. The skill should respond in your language. + +## First-Run Prompts + +```text +Help me write a PRD for a notification preferences feature. Make reasonable assumptions and label them. +``` + +```text +Analyze these metrics: MRR $50k, 500 customers, gross margin 80%, monthly churn 8%, CAC $500. +``` + +```text +Review this roadmap and tell me where evidence is weak, where tradeoffs are missing, and where stakeholder pressure is dominating. +``` + +## Discovery And Research + +```text +I think customers need a dashboard. Push back on this framing and help me write the actual problem statement. +``` + +```text +Help me prepare 10 discovery interview questions for ops managers at mid-market SaaS companies. Avoid confirmation bias. +``` + +```text +Build an opportunity solution tree for improving activation in our first 14 days. +``` + +## Strategy And Prioritization + +```text +We have 6 candidate features and limited engineering capacity. Recommend a prioritization framework and apply it. +``` + +```text +Write a positioning statement for a B2B analytics tool that helps RevOps teams spot pipeline risk earlier. +``` + +```text +Help me draft a Now / Next / Later roadmap for an AI meeting assistant. Name the tradeoffs explicitly. +``` + +## Artifacts And Delivery + +```text +Review this PRD draft like a strong PM peer. Flag solution smuggling, missing metrics, overscoping, weak evidence, and delivery risks. +``` + +```text +Turn this feature idea into 5 user stories with testable Gherkin acceptance criteria. +``` + +```text +This epic is too big for one sprint. Split it vertically and explain the logic. +``` + +## Finance And Metrics + +```text +Our SaaS has ARR $3.2M, NRR 92%, gross margin 72%, burn $180k/month, runway 11 months. Diagnose business health and tell me what not to ignore. +``` + +```text +Should we build this retention feature? Assume dev cost is $60k and estimate ROI from churn reduction. +``` + +```text +Compare these two acquisition channels on payback, LTV:CAC, and strategic fit. +``` + +## Career And Leadership + +```text +I'm a senior PM managing two PMs and preparing for Director interviews in 90 days. Diagnose my readiness and give me a focused plan. +``` + +```text +I just became Head of Product. Build a 30-60-90 day plan with the right altitude for the role. +``` + +```text +Review these 4 interview stories and tell me which ones actually show org-level influence. +``` + +## AI Product Craft + +```text +Pressure-test this AI product idea. What context, orchestration, and validation risks are we underestimating? +``` + +```text +Our AI assistant works in demos but fails in production. Diagnose likely context engineering issues. +``` + +```text +Recommend an agent workflow for triaging support tickets, but call out where humans should stay in the loop. +``` diff --git a/skills/product-manager-skills/_meta.json b/skills/product-manager-skills/_meta.json new file mode 100644 index 0000000..447afb8 --- /dev/null +++ b/skills/product-manager-skills/_meta.json @@ -0,0 +1,6 @@ +{ + "ownerId": "kn73ekpzsj882ce5a0kk31jxsx827vz3", + "slug": "product-manager-skills", + "version": "0.3.1", + "publishedAt": 1772760400224 +} \ No newline at end of file diff --git a/skills/product-manager-skills/examples/director-coaching.md b/skills/product-manager-skills/examples/director-coaching.md new file mode 100644 index 0000000..ac6d76e --- /dev/null +++ b/skills/product-manager-skills/examples/director-coaching.md @@ -0,0 +1,33 @@ +# Example: Director Readiness Coaching + +## Scenario + +You are moving from senior IC or group PM work into Director-level expectations. + +## Prompt + +```text +I'm a senior PM managing two PMs, strong on execution, weak on org influence, and interviewing for Director roles in 3 months. Coach me. +``` + +## Example Output Excerpt + +```text +Diagnosis +- You are operating strongly at team altitude and inconsistently at org altitude. +- Your likely interview risk is not execution depth. It is proving that you can shape priorities across teams and influence without direct authority. + +Gaps to close in the next 90 days +- Build 3 stories that show portfolio tradeoffs, not just feature delivery. +- Practice framing decisions in terms of company bets, not just team output. +- Create a weekly visibility loop with engineering, design, and GTM stakeholders. + +Recommended plan +- Weeks 1-2: inventory past projects and rewrite 5 stories using org-level impact language. +- Weeks 3-6: run mock interviews focused on conflict, strategy, and delegation. +- Weeks 7-12: ship one visible cross-functional improvement and capture evidence of influence. +``` + +## Why This Gets Reused + +Career coaching becomes sticky when the advice is specific to role altitude, not generic motivation. diff --git a/skills/product-manager-skills/examples/prd-review.md b/skills/product-manager-skills/examples/prd-review.md new file mode 100644 index 0000000..c8c95a2 --- /dev/null +++ b/skills/product-manager-skills/examples/prd-review.md @@ -0,0 +1,36 @@ +# Example: PRD Review And Pushback + +## Scenario + +You already have a PRD draft, but you want a strong PM peer review instead of grammar cleanup. + +## Prompt + +```text +Review this PRD for a notification preferences center. Flag solution smuggling, weak metrics, overscoping, and delivery risk. Be opinionated. +``` + +## Example Output Excerpt + +```text +Findings +- The problem statement is solution-smuggled. "Users need a preferences dashboard" starts from UI, not from the user problem. +- Success metrics are incomplete. There is no baseline, no target, and no guardrail metric. +- Scope is too broad for one release: channel controls, digest preferences, quiet hours, admin policy, and migration are multiple slices. +- User stories are horizontal. API work, UI work, and notification service updates are separated instead of being cut by user value. + +Suggested reframing +- Problem: users receive too many irrelevant notifications and lack confidence they can control frequency without missing critical updates. +- First release: account-level email preferences + unsubscribe rescue flow + instrumentation for preference changes and unsubscribe reduction. + +Recommended next step +- Rewrite the problem statement and success metrics first. Do not expand solution detail until scope is sliced vertically. +``` + +## What Good Looks Like + +The review should not stop at criticism. It should: + +- name the anti-pattern directly +- explain the consequence +- propose a thinner, more testable slice diff --git a/skills/product-manager-skills/examples/saas-health-diagnostic.md b/skills/product-manager-skills/examples/saas-health-diagnostic.md new file mode 100644 index 0000000..e7aec47 --- /dev/null +++ b/skills/product-manager-skills/examples/saas-health-diagnostic.md @@ -0,0 +1,37 @@ +# Example: SaaS Health Diagnostic + +## Scenario + +You want a fast diagnosis from a small set of numbers, not a finance lecture. + +## Prompt + +```text +Analyze these metrics: MRR $50k, 500 customers, gross margin 80%, monthly churn 8%, CAC $500. +``` + +## Example Output Excerpt + +```text +Diagnosis +- 8% monthly churn compounds to roughly 63% annual churn. This is a red flag, not a mild retention issue. +- ARPA is about $100/month. With 80% gross margin and 8% monthly churn, better LTV is about $1,000. +- LTV:CAC is about 2:1. That is below a healthy SaaS target, even though payback is workable at about 6.25 months. +- The bottleneck is retention, not acquisition efficiency. Scaling paid acquisition before fixing churn will hide the real problem. + +Likely root causes to inspect next +- Weak activation in the first 14 days +- Low repeat value for the core job +- Poor fit in one or more acquisition cohorts + +Recommended next step +- Pull 3 monthly cohorts, compare retention at day 30 / 60 / 90, and isolate the biggest drop-off before changing spend. +``` + +## Why This Matters + +The useful part is not just the math. The skill converts the math into a decision: + +- what is actually broken +- what not to optimize yet +- what analysis should come next diff --git a/skills/product-manager-skills/knowledge/ai-product-craft.md b/skills/product-manager-skills/knowledge/ai-product-craft.md new file mode 100644 index 0000000..4784c20 --- /dev/null +++ b/skills/product-manager-skills/knowledge/ai-product-craft.md @@ -0,0 +1,265 @@ +# AI Product Craft + +Compressed decision logic for AI product managers: readiness assessment, context architecture, orchestration patterns, and validation methodology. Derived from ai-shaped-readiness-advisor, context-engineering-advisor, and pol-probe-advisor. + +--- + +## AI-Shaped Readiness + +### AI-First vs. AI-Shaped + +| Dimension | AI-First (table stakes) | AI-Shaped (defensible) | +|-----------|------------------------|------------------------| +| Mindset | Automate existing tasks | Redesign how work gets done | +| Goal | Speed up artifact creation | Compress learning cycles | +| AI Role | Task assistant | Strategic co-intelligence | +| Test | Competitor replicates by adding headcount | Competitor must redesign entire org | + +### The 5 Competencies + +**1. Context Design** — Build a durable "reality layer" humans and AI both trust. Treat AI attention as scarce. Persist constraints + glossary; retrieve everything else on demand. Foundational: blocks all other competencies if missing. + +**2. Agent Orchestration** — Repeatable, traceable AI workflows (research -> synthesis -> critique -> decision -> log rationale). Version-controlled prompts. Each step shows its work. One-off prompts are tactical; orchestrated workflows are strategic. + +**3. Outcome Acceleration** — Compress learning cycles, not just task speed. Eliminate validation lag (PoL probes in days, not weeks). Remove approval delays (AI pre-validates against constraints). Cut meeting overhead (async AI synthesis). + +**4. Team-AI Facilitation** — AI operates as co-intelligence, not accountability shield. Review norms (AI outputs = drafts). Evidence standards (cite sources, reject "I think"). Decision authority (AI recommends, humans decide). Psychological safety to challenge AI. + +**5. Strategic Differentiation** — New customer capabilities competitors can't replicate by throwing bodies at it. Workflow rewiring requiring full org redesign to copy. Economics competitors can't match (10x cost advantage through AI). + +### Maturity Levels (per competency) + +- **Level 1 — AI-First:** One-off prompts, no structure, efficiency only +- **Level 2 — Emerging:** Some saved prompts/templates, scattered docs, modest gains +- **Level 3 — Transitioning:** Multi-step workflows, structured context, learning cycles compressing +- **Level 4 — AI-Shaped:** Autonomous orchestrated workflows, durable reality layer, defensible moat + +### Priority Dependency Chain + +``` +Context Design (foundation) + └─> Agent Orchestration (requires context) + └─> Outcome Acceleration (requires orchestration) + └─> Strategic Differentiation (requires all above) +Team-AI Facilitation ──── (parallel track, required for scale) +``` + +If Context Design is Level 1-2, fix it first. Everything else is fragile without it. + +--- + +## Context Engineering + +### Context Stuffing vs. Context Engineering + +| Dimension | Stuffing | Engineering | +|-----------|----------|-------------| +| Mindset | Volume = quality | Structure = quality | +| Approach | "Add everything just in case" | "What decision am I making?" | +| Persistence | Persist all context | Retrieve with intent | +| Agent chains | Share everything between agents | Bounded context per agent | +| Failure response | Retry until it works | Fix the structure | +| Economic model | Context as storage | Context as attention (scarce) | + +**Why stuffing fails:** Accuracy degrades significantly as context grows — models prioritize beginning and end, ignore the middle (Liu et al. 2023, "Lost in the Middle"). Dead ends and errors accumulate (context rot). Retries become normalized. + +### 5 Diagnostic Questions + +1. **What specific decision does this support?** Can't answer = don't need it. +2. **Can retrieval replace persistence?** Just-in-time beats always-available. +3. **Who owns the context boundary?** No owner = unbounded growth. +4. **What fails if we exclude this?** No concrete failure = delete it. +5. **Are we fixing structure or avoiding it?** Stuffing often masks bad info architecture. + +### Persist vs. Retrieve Rule + +- **Persist (80%+ of interactions):** Core constraints, user preferences, operational glossary, non-negotiable rules +- **Retrieve (<20% of interactions):** Project details, historical PRDs, competitive analysis, past transcripts +- **Gray zone (20-80%):** Weigh retrieval latency vs. context window cost + +### Two-Layer Memory Architecture + +**Short-term (conversational):** Immediate interaction history. Single session. Summarize/truncate older parts. + +**Long-term (persistent):** Constraints registry + operational glossary + user preferences. Vector database for semantic retrieval. Two subtypes: +- Declarative: facts ("We follow HIPAA") +- Procedural: patterns ("Always validate feasibility before usability") + +### Research -> Plan -> Reset -> Implement Cycle + +The core context rot prevention pattern: + +1. **Research:** Agent gathers data. Context grows large and messy. Expected. +2. **Plan:** Synthesize into high-density SPEC.md/PLAN.md (source of truth). +3. **Reset:** Clear entire context window. Non-negotiable. +4. **Implement:** Fresh session with only the plan as context. + +**Why it works:** Eliminates context rot, dead ends, and goal drift. Agent starts clean with compressed, high-signal context. + +### Efficiency Formula + +``` +Context Efficiency = (Accuracy x Coherence) / (Tokens x Latency) +``` + +Key finding: RAG with 25% of available tokens preserves 95% accuracy while cutting latency and cost. + +### Context Manifest Template + +``` +Always Persisted: constraints (technical, regulatory), user prefs, glossary +Retrieved On-Demand: historical PRDs, transcripts, competitive analysis +Excluded: meeting notes >30 days, full codebase, marketing materials +Boundary Owner: [Name] +Next Review: [Date + 90 days] +``` + +--- + +## Agent Orchestration + +### Core Workflow Pattern + +``` +Research -> Synthesis -> Critique -> Decision -> Log Rationale +``` + +Each step must be: traceable (cites sources), bounded (own context window), version-controlled (prompts in Git), consistent (same inputs -> predictable process). + +### Maturity Progression + +1. **Ad-hoc prompts:** Type into ChatGPT as needed. No reuse. +2. **Saved templates:** Reusable prompts, custom GPTs/Claude Projects. Manual steps. +3. **Multi-step workflows:** Research -> synthesis -> critique. Manual handoffs between steps. +4. **Autonomous orchestration:** Runs end-to-end. Traceable. Version-controlled. Auditable. + +### Bounded Context per Agent + +Anti-pattern: Agent A passes everything to Agent B to Agent C (context window explodes to 100k+). + +Fix: Each agent outputs a bounded synthesis (2-page max) to the next agent. Apply Research->Plan->Reset->Implement between agent handoffs. + +### Building Your First Orchestrated Workflow + +1. Pick most frequent AI use case +2. Document every step you currently take manually +3. Design loop: research -> synthesis -> critique -> decision -> log +4. Implement (Claude Projects for simple; API orchestration for complex) +5. Run on 3 past examples; compare to manual process +6. Version-control prompts; train 2 teammates; iterate + +--- + +## AI Validation (PoL Probes) + +### The 5 Probe Types + +| Probe | Core Question | Timeline | AI-Specific Use | +|-------|---------------|----------|-----------------| +| **Feasibility Check** | Can we build this? | 1-2 days | GenAI prompt chains, API sniff tests, data integrity sweeps | +| **Task-Focused Test** | Can users complete this without friction? | 2-5 days | Test AI-generated UIs, chatbot flows, recommendation quality | +| **Narrative Prototype** | Does this earn buy-in? | 1-3 days | Explain AI capabilities to stakeholders via Loom/video | +| **Synthetic Data Simulation** | Can we model without production risk? | 2-4 days | Test prompt logic, simulate edge cases, Monte Carlo on AI outputs | +| **Vibe-Coded Probe** | Will this survive real user contact? | 2-3 days | Frankensoft stack (ChatGPT Canvas + Replit + Airtable) for workflow validation | + +### Selection Logic + +Work backwards from hypothesis: +1. What specific risk am I eliminating? +2. What's the cheapest path to harsh truth? +3. Match method to hypothesis, not tooling comfort. + +**Golden rule:** Use the cheapest prototype that tells the harshest truth. + +### AI-Specific Feasibility Checks + +For AI product features, feasibility checks are critical because AI capabilities are non-obvious: +- **Prompt chain testing:** Run 100 real examples through your proposed prompt. Measure error rate. +- **API sniff tests:** Verify third-party AI integrations return expected format, latency, cost. +- **Data integrity sweeps:** Check if your data supports the AI feature (quality, volume, format). +- **Disposal protocol:** Delete all spike code after documenting findings. Spike-and-delete, not spike-and-ship. + +### Success Criteria Template + +- **Pass:** [Quantitative threshold, e.g., <5% error rate, 80%+ task completion] +- **Fail:** [Observable failure, e.g., >18% errors, users abandon mid-flow] +- **Learn:** [Specific insight regardless of pass/fail] + +Write criteria before building. "We'll know it when we see it" is not a success criterion. + +### Troubleshooting Common AI Product Issues + +**Hallucination (output contains fabricated facts):** +1. Measure: run 100+ real queries, categorize errors (factual, format, reasoning, refusal) +2. Reduce context window — strip to minimum required tokens per the 5 diagnostic questions above +3. Add retrieval with source citations — ground answers in specific documents, not parametric memory +4. Add output validation — regex/rule checks for structured fields, LLM-as-judge for open text +5. Set confidence thresholds — if model confidence is low, return "I don't know" instead of guessing + +**Latency (AI response too slow for UX):** +1. Profile the pipeline — which step is slow? (retrieval, inference, post-processing) +2. Reduce input tokens — smaller context = faster inference. Apply persist vs. retrieve rule. +3. Use streaming — display partial results as they generate +4. Cache common queries — if 30% of queries are similar, pre-compute answers +5. Consider smaller model for simple tasks — route easy queries to fast model, hard queries to capable model + +**Inconsistency (same input, different outputs):** +1. Lower temperature — 0.0-0.3 for factual tasks, 0.5-0.7 for creative tasks +2. Pin model version — don't use "latest" in production +3. Structured output — JSON schema or enum constraints reduce variation +4. Add few-shot examples — 2-3 input/output pairs anchor the response pattern +5. Evaluate on a fixed test set — track consistency score across versions + +--- + +## Quality Gates + +### AI Product Anti-Patterns + +**1. Prompt-and-Pray** +Shipping AI features with untested prompts. No evaluation framework, no error rate measurement. Fix: Run feasibility checks (100+ examples) before committing to build. + +**2. Context Stuffing at Scale** +Pasting entire knowledge bases into AI. "More tokens = better results." Fix: Apply the 5 diagnostic questions. Accuracy degrades significantly as context grows (Lost in the Middle effect). + +**3. No Evals** +Launching AI features without quantitative success criteria. "Users seem to like it." Fix: Define pass/fail thresholds before building. Measure error rates, task completion, hallucination frequency. + +**4. Efficiency Masquerading as Strategy** +"We use AI to write PRDs 2x faster — we're AI-shaped!" If a competitor matches it by hiring 2 more people, it's table stakes. Fix: Ask the replication test — does copying require org redesign? + +**5. Tool Fetishism** +"Should we use Claude or ChatGPT?" Tool debates replace workflow redesign. Fix: Tools don't matter. Workflows matter. + +**6. Speed Without Learning** +Shipping faster without validating faster. AI accelerates building the wrong thing. Fix: Compress learning cycles (PoL probes in days), not just build cycles. + +**7. Prototype Theater** +Building polished demos to impress executives instead of testing hypotheses with users. Fix: Test with users first, present findings to executives. Narrative prototypes over production polish. + +**8. Skipping the Reset** +Never clearing context between research and implementation. Context rot poisons execution. Fix: Mandatory reset after plan synthesis. Start implementation with only the high-density plan. + +**9. Individual AI, Not Team AI** +"I'm AI-shaped, but my team isn't." Can't scale; workflows die when you're on vacation. Fix: Codify review norms, evidence standards, decision authority. Team transformation > individual productivity. + +**10. Testing Multiple Variables** +One probe testing workflow + pricing + UI simultaneously. Ambiguous results. Fix: One probe, one hypothesis. Three hypotheses = three probes. + +### The Falsification Protocol + +For every AI feature decision, complete: +> "If I exclude [context/feature/test], then [specific failure] will occur in [specific scenario]." + +If you can't complete the sentence, you don't need it. Vague failures ("AI might not fully understand") are not valid. + +### Minimum Viable AI Product Checklist + +- [ ] Hypothesis written before building +- [ ] Feasibility check run (100+ examples, error rate measured) +- [ ] Context architecture defined (persist vs. retrieve vs. exclude) +- [ ] Success criteria quantified (pass/fail/learn thresholds) +- [ ] Disposal date set for probes (spike-and-delete) +- [ ] Context boundary owner assigned +- [ ] AI outputs treated as drafts (human review protocol) +- [ ] Learning cycle measured (before vs. after AI intervention) diff --git a/skills/product-manager-skills/knowledge/artifacts-delivery.md b/skills/product-manager-skills/knowledge/artifacts-delivery.md new file mode 100644 index 0000000..d7f6314 --- /dev/null +++ b/skills/product-manager-skills/knowledge/artifacts-delivery.md @@ -0,0 +1,241 @@ +# PM Artifacts & Delivery + +Compressed reference for the full PM artifact lifecycle: from proto-personas and problem framing through PRDs, user stories, epics, story maps, and end-of-life communications. + +## PRD Development + +10-section document, built over 2-4 days. + +**Template structure (10 sections):** +1. Executive Summary -- "We're building [solution] for [persona] to solve [problem], resulting in [impact]." +2. Problem Statement -- Who, what, why, evidence (quotes, analytics, tickets) +3. Target Users & Personas -- Primary + secondary proto-personas +4. Strategic Context -- OKRs, TAM/SAM/SOM, competitive landscape, "why now?" +5. Solution Overview -- High-level description + user flows (not pixel specs) +6. Success Metrics -- Primary metric (optimize), secondary (monitor), guardrail (don't regress) +7. User Stories & Requirements -- Epic hypothesis + broken-down stories with acceptance criteria +8. Out of Scope -- Explicit exclusions with rationale +9. Dependencies & Risks -- Technical, external, team; risks + mitigations +10. Open Questions -- Unresolved decisions needing discovery + +**Metrics structure:** Always define current baseline, target, and measurement timeline. Format: "Metric: Current X -> Target Y, measure Z days post-launch." + +**Phase sequence:** +- Day 1: Exec summary (30m) + Problem (60m) + Personas (30m) + Strategy (45m) +- Day 2: Solution (60m) + Metrics (30m) + Stories (90-120m) +- Day 3: Scope/Dependencies (30m) + Review (60m) + +## User Stories + +**Format (Mike Cohn + Gherkin):** +``` +As a [specific persona], I want to [action], so that [outcome/motivation]. + +Scenario: [description] +Given: [preconditions -- multiple Givens OK] +When: [single trigger event -- aligns with "I want to"] +Then: [single outcome -- aligns with "so that"] +``` + +**Quality gates:** +- "As a" uses specific persona, not generic "user" +- "So that" states motivation, not restatement of action +- One When, one Then per story. Multiple = split signal. +- Acceptance criteria are testable by QA -- no "better experience" or "faster" +- Summary is value-centric: "Enable Google login for trial users" not "Add login button" + +### Splitting Stories + +8 patterns applied in order (Richard Lawrence / Humanizing Work). Stop at first match: + +| # | Pattern | Signal | Split strategy | +|---|---------|--------|----------------| +| 1 | Workflow steps | Multi-step sequence | Thin end-to-end slices (full workflow, increasing sophistication) | +| 2 | Business rules | Different rules per scenario | One story per rule variation | +| 3 | Data variations | Different data types/formats | One story per data type, simplest first | +| 4 | AC complexity | Multiple When/Then | One story per When/Then pair | +| 5 | Major effort | Hard first build, easy additions | "Implement one + add remaining" | +| 6 | External deps | Multiple APIs/third parties | One story per dependency boundary | +| 7 | DevOps steps | Infrastructure/deployment work | Split by operational complexity | +| 8 | Tiny Acts of Discovery | High uncertainty, none above apply | Time-boxed experiments, not stories | + +**Validation after split:** Each piece must (a) deliver user value independently, (b) be testable independently, (c) fit in a sprint (1-5 days), (d) all pieces combined equal the original. + +**Critical rule:** Always split vertically (front-end + back-end = user value). Never horizontally ("Build API" / "Build UI"). + +## Story Mapping + +**Jeff Patton framework -- 2D map:** +- Horizontal (left-right): Activities in narrative/workflow order = backbone +- Vertical (top-down): Priority within each activity + +**Hierarchy:** Segment -> Persona -> Narrative (goal) -> Activities (3-5) -> Steps (3-5 per activity) -> Tasks (5-7 per step) + +**Building the map:** +1. Define segment + persona + narrative (one-sentence JTBD goal) +2. Identify 3-5 backbone activities in sequential workflow order +3. Break each activity into steps (user actions, observable, logical sequence) +4. Break steps into tasks (granular, prioritizable) +5. Prioritize vertically: top = MVP, middle = R2, bottom = future +6. Draw horizontal release lines + +**Walking skeleton:** Top-priority task from EVERY activity = minimal end-to-end functionality. Build across all activities incrementally, not one activity fully before starting the next. + +**Release slicing:** +- R1 (Walking skeleton): Simplest version across all activities +- R2 (Enhanced): Second-priority tasks improving core workflow +- R3 (Polish): Nice-to-haves, edge cases, optimizations + +## Epics + +### Epic Hypothesis + +**Template (Tim Herbig / Lean UX):** +``` +If we [specific action/solution] +for [specific persona] +Then we will [measurable outcome] +``` + +**Tiny Acts of Discovery:** 2-3 lightweight experiments before full build. +- Types: prototype + user test, concierge test, landing page test, Wizard of Oz, A/B test +- Constraint: days/weeks not months; cheap; falsifiable + +**Validation measures:** +``` +We know our hypothesis is valid if within [2-4 weeks] +we observe: +- [Quantitative: "20% increase in activation rate"] +- [Qualitative: "8/10 users say it saved time"] +``` + +**Decision gate:** Validated -> write user stories. Invalidated -> kill or pivot. Inconclusive -> more experiments. + +### Epic Breakdown (9 Patterns) + +Pre-split: INVEST check (Independent, Negotiable, Valuable, Estimable, Small, Testable). If not Valuable, STOP -- combine with other work, don't split. + +**9 patterns applied sequentially** (superset of story splitting): +1. **Workflow steps** -- thin end-to-end, NOT step-by-step +2. **Operations (CRUD)** -- "manage" = Create + Read + Update + Delete +3. **Business rule variations** -- each rule = separate story +4. **Data variations** -- add data types just-in-time +5. **Data entry methods** -- basic input first, fancy UI later +6. **Major effort** -- implement one + add remaining +7. **Simple/Complex** -- simplest core first, variations later +8. **Defer performance** -- "make it work" then "make it fast" +9. **Break out a spike** -- time-box investigation when uncertainty blocks splitting + +**Meta-pattern across all:** Identify core complexity -> list variations -> reduce to one complete slice -> make other variations separate stories. + +**Evaluate splits:** (a) Does it reveal low-value work you can kill? (b) Are resulting stories roughly equal-sized? + +**Cynefin adjustment:** Low uncertainty = find all stories, prioritize by value. High uncertainty = identify 1-2 learning stories only. Chaos = defer splitting, stabilize first. + +## Proto-Personas + +**Hypothesis-driven persona, not validated research.** Created in hours from available data. + +**Template sections:** +1. **Name** -- alliterative, memorable ("Manager Mike") +2. **Bio & Demographics** -- behavioral, not just age/location. Include career, online presence, tech habits. +3. **Quotes** -- real or representative; revealing mindset, not facts +4. **Pains** -- specific and product-relevant ("3 hrs/week copying data between tools") +5. **What they're trying to accomplish** -- observable behaviors and outcomes +6. **Goals** -- short-term + long-term, personal + professional +7. **Attitudes & Influences** -- decision authority, influencers, beliefs affecting adoption + +**Mark uncertainty:** Tag unvalidated items with [ASSUMPTION--VALIDATE]. Plan research to fill gaps. Limit to 1-2 personas initially. + +## Press Release / PRFAQ + +**Amazon Working Backwards format.** Written BEFORE building. Planning tool, not launch copy. + +**Structure:** +1. **Headline** -- benefit-focused, specific ("Cut Invoice Processing by 60%") +2. **Dateline** -- city, date +3. **Introduction** -- what launched, for whom, key benefit (2-3 sentences) +4. **Problem paragraph** -- specific customer problem with data +5. **Solution paragraph** -- outcome-focused, not feature list +6. **Executive quote** -- customer-empathetic, visionary (not "excited to innovate") +7. **Supporting details** -- additional benefits with data +8. **Boilerplate** -- company background +9. **CTA + media contact** + +**Litmus tests:** Would a customer care? Is the problem clear? Are benefits measurable? Is it jargon-free? Does it survive "so what?" + +## Storyboards + +**6-frame narrative arc** for pitching, alignment, and emotional validation. + +| Frame | Name | Content | +|-------|------|---------| +| 1 | Main character | Persona + context (specific, not "busy professional") | +| 2 | Problem emerges | Challenge + how it affects life | +| 3 | "Oh crap" moment | Escalation creating urgency | +| 4 | Solution appears | Realistic discovery of product | +| 5 | "Aha" moment | Breakthrough experience (outcome, not feature demo) | +| 6 | Life after | Improved state with specifics | + +**Visual style default:** Fat-marker sharpie sketches, minimal, monochrome. Low-fidelity is fine. + +**7 input questions:** Who is the character? What problem? What's the escalation? How is solution introduced? What's the breakthrough? What's life after? Visual style preferences? + +## Recommendation Canvas + +**11-section strategic proposal** for AI/high-uncertainty product decisions. Executive-friendly. + +1. **Business Outcome** -- [Direction] [Metric] [Outcome] [Context] [Criteria] +2. **Product Outcome** -- same format, customer perspective +3. **Problem Statement** -- persona-centric narrative +4. **Solution Hypothesis** -- If/Then + Tiny Acts of Discovery + Proof-of-Life measures +5. **Positioning Statement** -- For/That need/Is a/That + Unlike/Provides differentiation +6. **Assumptions & Unknowns** -- explicit, testable +7. **PESTEL Risks (Investigate)** -- Political, Economic, Social, Tech, Environmental, Legal (specific, not generic) +8. **PESTEL Risks (Monitor)** -- lower priority watch list +9. **Value Justification** -- data-backed case for C-level ("addresses #1 pain point, $500k ARR impact") +10. **Success Metrics** -- SMART format +11. **What's Next** -- ordered action steps + +## End-of-Life Communication + +**9-section empathy-first EOL message.** Never send without a complete transition plan. + +**Structure:** +1. **Company context** -- who you are, customer commitment +2. **Announcement** -- single clear sentence: what's ending, what's replacing it, when +3. **Rationale** -- framed as customer benefit, not cost savings +4. **Current product context** -- acknowledge what's being lost and who it served +5. **Customer impact** -- explicitly name disruptions (migration time, learning curve, integration updates) +6. **Transition solution** -- positioning format: For/That currently use/Is a/That + continuity + improvements +7. **Support measures** -- 1:1 assistance, auto-migration, discounts, training +8. **Timeline** -- specific dates: migration tool available, read-only date, full shutdown, data export deadline. 6-12 months lead time. +9. **Call to action** -- next steps + contact info + +**Tone rules:** Empathetic, not defensive. Forward-looking, not apologetic. Specific, not vague. Never blame customers for low usage. + +## Quality Gates + +### Cross-cutting anti-patterns + +| Anti-pattern | Appears in | Fix | +|---|---|---| +| Written in isolation | PRD, story map | Collaborate with design + eng on stories/map | +| No evidence in problem statement | PRD, press release, canvas | Include quotes, analytics, tickets | +| Solution too prescriptive | PRD | Keep solution high-level; let design own UI | +| Feature list instead of benefits | Press release, canvas | Translate features to outcomes | +| Generic "As a user" | User stories | Use specific persona names/roles | +| "So that" restates "I want to" | User stories | Dig into real motivation | +| Multiple When/Then | User stories | Split the story | +| Horizontal slicing | Story splitting, epic breakdown | Always vertical: each story delivers end-to-end user value | +| Skipping experiments | Epic hypothesis, canvas | Define lightweight validation before build | +| Vague validation measures | Epic hypothesis, canvas | Specific metrics + timeframe (2-4 weeks) | +| Treating hypotheses as commitments | Epic hypothesis | Frame as bets; allow invalidation | +| Activities are features, not behaviors | Story map | Map user actions, not product capabilities | +| Technical backbone | Story map | Backbone follows user workflow, not system layers | +| Feature-complete waterfall releases | Story map | Walking skeleton = thin slice across ALL activities | +| Demographics without behavior | Proto-persona | Add behavioral context, not just age/location | +| Too many personas | Proto-persona | Start with 1-2; expand as validated | +| Business-centric EOL rationale | EOL message | Frame as customer benefit | +| Vague EOL timeline | EOL message | Specific dates with milestones | +| No transition support plan | EOL message | Migration assistance, tools, discounts | diff --git a/skills/product-manager-skills/knowledge/career-leadership.md b/skills/product-manager-skills/knowledge/career-leadership.md new file mode 100644 index 0000000..743db27 --- /dev/null +++ b/skills/product-manager-skills/knowledge/career-leadership.md @@ -0,0 +1,250 @@ +# Career & Leadership + +Compressed knowledge module covering the PM-to-Director and Director-to-VP/CPO career transitions, diagnostic coaching logic, executive onboarding methodology, and named failure modes at each level. + +## Altitude-Horizon Framework + +Two axes define the PM-to-Director shift: + +**Altitude (Scope)** +- PM: customer problems, individual features, sprint priorities, specific team dynamics. +- Director: product portfolio, cross-functional systems, organizational dynamics, budget allocation, market positioning. + +**Horizon (Time)** +- PM: days, weeks, sprints. A quarter at most. +- Director: quarter as starting point. Annual planning cycles, multi-year strategy. + +**Waiter vs. Restaurant Operator** — the core analogy: + +| Dimension | PM (Waiter) | Director (Operator) | +|---|---|---| +| Focus | Individual diner experience | Entire system: staffing, margins, menu, suppliers | +| Authority | Influence without control | Portfolio decisions, budget, resource allocation | +| Success metric | Table seven is happy | Restaurant is profitable, consistent, scalable | +| Customer relationship | Direct, daily, intimate | Aggregate patterns, market cohorts | + +### Four Transition Zones + +1. **Thinking Altitude** — Stop solving individual problems directly. Start designing systems and teams that solve classes of problems. +2. **Persona Shift** — Stop obsessing over individual user personas. Start thinking in buyer personas, market cohorts, organizational stakeholders, executive dynamics. +3. **Hero Syndrome Recovery** — Stop being the person who saves the day. Start getting satisfaction from team success. Your product is your people, not the roadmap. +4. **Direction Creation** — Stop waiting for clear direction from above. Start creating context cascades that translate strategy into team clarity, even when inputs are incomplete. + +### Cascading Context Map + +When direction is vague, Directors cascade rather than wait: + +1. Listen to top-level strategy (QBRs, exec comms) +2. Extract 3-5 key priorities leadership stated +3. Map: "How does our BU accomplish these?" +4. Map: "How does our product portfolio accomplish that?" +5. Map: "What are my team's specific accountabilities?" +6. Communicate the cascade — not just what, but why it connects upward + +Template: +``` +Company Priority: [leadership's words] +BU Translation: [how your BU contributes] +Portfolio Translation: [how your products contribute] +Team Accountabilities: [what each team owns] +Why This Matters: [what changes, what stays the same] +``` + +Core principle: even with incomplete direction from above, a Director's job is to fill the gap downward. Creating imperfect-but-useful clarity is a Director skill. + +### Named Failure Modes (PM-to-Director) + +**Hero Syndrome** — Jumping in to solve problems directly. Regressing to the old reward loop of visible IC wins. Cost: you under-perform as Director while over-functioning as senior IC. Your team doesn't develop. + +**Allergic to Process** — Letting high-performing PMs run independent playbooks. Cost: stakeholders across marketing, finance, leadership can't synthesize inconsistent outputs. + +**People-Pleaser Leadership** — Wanting the team to like you. Avoiding hard feedback. Saying yes to preserve relationships. Cost: confuse "popular" with "effective." + +**Instant Gratification Trap** — Reading leadership books, collecting certifications, asking "what do I need to do to get promoted?" Cost: Director readiness requires war stories and lived humility, not study. + +**Black-and-White Thinking** — "This seems obvious." "Why is everything so political?" Cost: fast decisions with low confidence create downstream chaos. Grayscale is the actual terrain. + +## PM to Director Transition + +### Four Coaching Situations + +| Situation | Description | Coaching Priority | +|---|---|---| +| Preparing | Still a PM, building toward Director | Identify weakest transition zone; practice cascade thinking; audit Hero Syndrome habits | +| Interviewing | Active internal or external search | Build one story per transition zone; reframe PM wins in Director language; prepare for the gap question honestly | +| Newly Landed | First 6 months as Director | Run Cascading Context Map immediately; reframe 1-on-1s to strategic altitude; name ambiguity explicitly; resist premature reorgs | +| Recalibrating | Been a Director; something broken | Track IC-vs-coaching time ratio (target: 20% IC); identify what keeps you in Hero Syndrome; create deliberate handoffs | + +### Readiness Signals (Preparing) + +Assess across four gap areas: +1. **Thinking altitude** — still default to solving customer problems directly? +2. **Stakeholder navigation** — struggle with politics, exec dynamics, cross-functional influence? +3. **Strategic narrative** — can't connect work to company strategy in leadership conversations? +4. **Direction creation** — wait for clarity from above rather than creating it? + +Development timeline matters: 6+ months out = build deliberately. 3-6 months = signal readiness, prepare manager conversation. Actively applying = shift to interview prep. + +### Interview Preparation + +- Work through Altitude-Horizon Framework as a study session: after each section, identify your own story. +- Build one concrete story per transition zone. Use zone names as structure. +- Reframe PM wins: don't open with "I shipped X." Open with "The strategic question my team faced was [X]. Here's how I thought about the portfolio tradeoff." +- For the gap question: "Here's the gap, here's how I've been developing toward it, here's what I'd focus on learning in the first 90 days." Honesty with a plan beats avoidance. + +### Newly Landed Coaching + +Challenge-specific guidance for inherited teams without clear direction: +1. Run a Cascading Context Map this week. Don't wait for perfect clarity. +2. Redirect 1-on-1s: "Help me see how your product connects to the business goals I'm accountable for." +3. Name ambiguity explicitly: "Here's my best current translation. I'll update it in two weeks." +4. Wait 60-90 days before reorganizing. Understand what's working first. + +### Recalibrating Coaching + +For Directors still doing IC work after 12+ months: +- Track the ratio: most are at 60-70% IC work. Target is 20%. +- Identify root cause: (a) trust own judgment over team, (b) team undeveloped, (c) getting reward signals from IC behavior. +- Create deliberate handoff for top 3 IC activities with written "done well" criteria. +- Change the reward loop: notice quieter Director wins (PM ships a hard stakeholder conversation alone, team creates its own cascade). +- If entrenched at 1-2 years: consider whether the role fits. Senior IC / Principal PM is a legitimate path. + +## Director to VP/CPO Transition + +### The Three Ps Framework + +VP/CPO accountability spans three dimensions: +- **Product** — Portfolio decisions, roadmap strategy, product family coherence +- **Practice** — How work gets done; process discipline, execution consistency, cross-functional operating rhythms +- **People** — The dominant focus: org structure, talent matching, developing leaders, setting and inspecting expectations + +Most Directors are strong in Product, adequate in Practice. People is where the VP/CPO transition most often breaks down. + +### The Empowerment Myth + +False belief: "Once I get there, I'll finally have authority to do what I always knew was right." +Reality: constraints don't disappear, they change shape. PM = 3x3 Rubik's Cube. Director = 5x5. VP = 7x7. CPO = 9x9. Same principles; exponentially larger blast radius per decision. + +### VP to CPO Paradigm Shift + +| Dimension | VP Mindset | CPO Mindset | +|---|---|---| +| Core question | "What are we releasing?" | "What business outcomes is the product org accountable for?" | +| Language | Product vocabulary (features, roadmaps, sprints) | Business vocabulary (ROI, revenue, retention, margin, EBITDA) | +| Primary customer | End user | May be investor, buyer, or board — depends on business context | +| Primary team | Product organization | Executive staff (CEO, CFO, CRO, CMO) | + +### Time Horizon by Level + +| Level | Short-term | Long-term | +|---|---|---| +| IC | Sprint | Quarter | +| Director | Quarter | 1-2 years | +| VP | 1-2 quarters | 3 years | +| CPO | 1-2 quarters | 3-5 years | + +Quarterly delivery doesn't stop. Long-term horizon runs in parallel with short-term accountability at every level. + +### Alliance Building (Executive Level) + +Without executive alliances, you're a "dead man walking." Requirements: +- Weekly engagement with peer executives (CRO, CFO, CMO) — not annual roadmap reviews +- Proactive trade-off communication: "You're not getting X this quarter because of Y, and here's why" +- Bring people along before decisions are announced, not after +- Understand each peer's real priorities, not just stated ones + +### CEO Interview Questions (Pre-Acceptance) + +Five questions to probe before accepting a VP/CPO role: + +1. "What are you expecting from the product org in the first 90 days? The first year?" — Surfaces unrealistic transformation timelines. +2. "Who are the all-stars on your product team, and why?" — Reveals CEO's perceptions and biases. +3. "Who has gaps, and why?" — What does the CEO believe the org weakness is? +4. "What constraints am I working with that I should understand upfront?" — Your actual degrees of freedom. +5. "What does success look like for this role at one year?" — Force specificity. Vague answers are red flags. + +**Red flags:** "You can't change the existing roadmap" (loss of basic authority). "Transform the org in six months" (setup for failure). Misalignment between CEO's talent assessment and what you hear elsewhere. + +### VP/CPO Readiness Assessment + +Four coaching situations mirror the Director advisor: + +| Situation | Key Assessment Areas | +|---|---| +| Preparing | Which of the Three Ps is weakest? What's your exposure to executive dynamics? | +| Evaluating/Interviewing | Can you demonstrate executive-level thinking vs. Director-level work? Have you run CEO interview questions? | +| Newly Landed | Getting oriented without acting prematurely? Executive dynamics navigation? People/org assessment? Surfacing unwritten strategy? | +| Recalibrating | Still operating at Director level? Executive relationships broken? Organization underperforming? Unclear success criteria? | + +## Executive Onboarding (30-60-90) + +### Consultant Mindset + +Enter every new VP/CPO role as an external consultant assessing the organization before you're responsible for changing it. +- Observe before diagnosing. Ask questions before declarations. +- Understand how steering connects to rudder — org charts lie; map actual reality. +- Don't throw the big red switch. Understand what inherited structures control first. +- Negotiate upfront: tell your boss Month 1 is explicitly a learning phase. + +### Phase 1: Diagnose (Month 1) + +**Objective:** Build the body of evidence. Understand reality, not the official version. + +1. **Interview everyone** — Direct reports, cross-functional peers (CRO, CFO, CMO, Eng leads), sample of PMs. Questions: "What's working?" / "What's not working?" / "What won't I hear in official briefings?" / "Who should I talk to?" +2. **Let people find you** — Those who proactively schedule time have an agenda. Surface it, evaluate it, note the signal. +3. **Take detailed notes** — Who said it, what their incentive might be, whether multiple independent sources confirm it. +4. **Resist action** — When you see something broken, note it. You don't yet know why it's broken, what it's connected to, or what previous fix attempts failed. + +**Deliverable:** Detailed notebook of organizational reality, not yet interpreted. + +### Phase 2: Validate (Month 2) + +**Objective:** Surface patterns, challenge conclusions, identify people situations. + +1. **Reality-check with your boss** — "I'm hearing [X]. This differs from what I understood coming in. Help me understand the history." +2. **Map unwritten strategy** — Ask: "What does the organization actually optimize for when things get hard?" Answer is usually different from mission statement. +3. **Complete people assessment** — Diamonds in the rough (give more scope). Strong but wrong role (have the conversation). Not coachable to needed level (determine timeline). +4. **Identify 3-5 highest-leverage changes** — Not a full transformation plan. These become Month 3 agenda. + +**Deliverable:** Interpreted organizational assessment with people map and initial strategic priorities. + +### Phase 3: Act with Evidence (Month 3) + +**Objective:** Make decisions grounded in collected evidence. + +1. **Share organizational assessment** — Bring findings to boss and direct reports. Transparency builds trust and surfaces disagreements before you act. +2. **Run first Cascading Context Map** — Create direction even if strategy above you is still ambiguous. Team has been waiting for context. +3. **Start people conversations** — Diamonds: stretch assignment. Wrong role: honest conversation about mismatch and options. Exits: honesty and care, not avoidance. +4. **Build executive alliance deliberately** — Start weekly alignment practice with CRO, CFO, CMO. Don't wait for them to be surprised. + +**Deliverable:** Shared assessment, initial strategic direction, 3-5 active changes underway with clear rationale. + +### People Assessment Categories + +**Diamonds in the rough:** Capable, undervalued, no champion. Find them by listening for "she's talented but nobody gives her the hard problems" or noticing who provides the most unvarnished information. They become critical early allies. + +**Strong people in wrong roles:** Strengths mismatched to scope. Common in fast-growth, post-acquisition, or tenure-based promotion orgs. Coach up if coachable, find another role, or part ways. All three better than leaving mismatch in place. + +## Quality Gates + +### Anti-Patterns Across All Transitions + +**Premature action** — Making structural changes before building the body of evidence. Month 1 changes guarantee expensive reversals. + +**Consultant mode too long** — Still gathering information in Month 3. Organizational confidence erodes. Act on best current evidence. + +**Title-chasing** — Optimizing for promotion appearance rather than building actual muscles. Interviewers and managers detect the difference. + +**Skipping altitude shifts** — Using strategy vocabulary while still making sprint-level decisions (Altitude Theater). If you're in the details, own it. If you're not, delegate fully. + +**Empowerment fantasy** — Taking a VP/CPO role expecting constraints to vanish. They scale up, they don't disappear. + +**Alliance neglect** — Treating executive peer relationships as secondary to managing direct reports. At VP/CPO, the exec team is your primary operating environment. + +**Loudest voice bias** — Forming early opinions from the most vocal person met in Month 1. Only act on themes confirmed by 3+ independent sources. + +**Conflating VP and CPO** — Treating Director-to-VP and VP-to-CPO as the same move at different scale. VP-to-CPO is a qualitative change (product-first to business-first), not scope expansion. + +**One-and-done cascade** — Running the Context Map once at annual planning, never revisiting. Revisit at major inflection points: quarterly planning, exec changes, pivots, restructuring. + +**Kindness confusion** — Shielding teams from hard decisions, softening feedback into meaninglessness. Be transparent about the "why." What you share should be honest and actionable. diff --git a/skills/product-manager-skills/knowledge/discovery-research.md b/skills/product-manager-skills/knowledge/discovery-research.md new file mode 100644 index 0000000..c1fe078 --- /dev/null +++ b/skills/product-manager-skills/knowledge/discovery-research.md @@ -0,0 +1,375 @@ +# Discovery & Research + +Compressed decision logic, frameworks, and quality gates for running product discovery end-to-end: framing problems, interviewing customers, mapping jobs and journeys, generating solutions, and validating hypotheses before committing to build. + +## Problem Framing + +### Problem Statement (Component) + +**Template -- write from the user's perspective:** + +``` +I am: [persona with 3-4 key characteristics] +Trying to: [desired outcome -- measurable, not a task] +But: [barriers preventing the outcome] +Because: [root cause, not symptom] +Which makes me feel: [authentic emotion from research] +``` + +**Final statement formula:** `[Persona] needs a way to [outcome] because [root cause], which currently [impact].` + +**Quality gates:** +- "I am" passes if you can picture a real person (not "busy professionals") +- "Trying to" is an outcome, not an activity +- "Because" survives 5-why interrogation +- "Makes me feel" uses verbatim customer language, not marketing copy +- Final statement fits one sentence and is measurable + +**Top anti-patterns:** +1. **Solution smuggling** -- "The problem is we don't have X." Fix: reframe around user outcome. +2. **Business problem disguised as user problem** -- "Users want to reduce our churn." Fix: dig into why users leave from their perspective. +3. **Symptom instead of root cause** -- "Because the UI is confusing." Fix: keep asking "why" until you hit structural cause. + +--- + +### Problem Framing Canvas (MITRE, Interactive) + +**Three-phase bias-check before you write a problem statement.** + +**Phase 1 -- Look Inward:** +- What is the problem? (symptoms only) +- Why haven't we solved it? (new / hard / low priority / lack of resources / authority / systemic inequity) +- How are we part of the problem? (confirmation bias / internal bias / survivorship bias / premature convergence) + +**Phase 2 -- Look Outward:** +- Who experiences it? When, where, consequences? +- Who else has it? Who doesn't? (counter-examples reveal root cause) +- Who's been left out of the conversation? +- Who benefits from the problem existing? Who benefits from it being solved? + +**Phase 3 -- Reframe:** +- Restate: "[Who] struggles to [what] because [root cause], leading to [consequence]. Affects [segments], overlooked because [bias]." +- HMW: "How might we [action] as we aim to [objective]?" + +**Quality gates:** +- HMW is broad enough to permit multiple solutions, narrow enough to be actionable +- Canvas was completed cross-functionally, not solo +- "Who benefits from the status quo?" was explicitly answered + +**Top anti-patterns:** +1. **Skipping Look Inward** -- groupthink persists. Fix: force explicit bias discussion. +2. **Generic reframe** -- "Improve user experience." Fix: include who, what, when, consequence, root cause. +3. **HMW too narrow** -- "How might we add a mobile app?" Fix: state the job, not the solution. + +--- + +## Customer Discovery + +### Discovery Process (Workflow, 6 phases / 3-4 weeks) + +``` +Phase 1: Frame (Day 1-2) + -> Problem Framing Canvas (120 min) + Problem Statement (30 min) + -> Optional: Proto-Persona, JTBD + -> Output: problem hypothesis, 3-5 research questions, success criteria + -> Gate: enough context to start research? If no, gather data first (+2-3 days) + +Phase 2: Plan Research (Day 3) + -> Discovery Interview Prep (90 min) + -> Recruit 5-10 participants, schedule across 1-2 weeks + -> Output: interview guide (5-7 Mom Test questions), participant roster + +Phase 3: Conduct Research (Week 1-2) + -> 5-10 interviews + support ticket analysis + analytics review + -> Note template per interview: participant, context, actions, pain points, workarounds, verbatim quotes, insights + -> Gate: saturation? Same pains across 3+ interviews = proceed. Still learning = +3-5 interviews. + +Phase 4: Synthesize (End of Week 2) + -> Affinity mapping: sticky notes -> themed clusters with frequency counts + -> Optional: Customer Journey Map workshop + -> Prioritize: score each pain on frequency x intensity x strategic fit (1-5 each) + -> Output: top 3-5 pain points, 3-5 verbatim quotes per pain, validated problem statement + +Phase 5: Generate & Validate Solutions (Week 3) + -> Opportunity Solution Tree OR Lean UX Canvas + -> Design experiments: concierge / prototype / landing page / A/B test + -> Run experiments (1-2 weeks each) + -> Gate: validated? If no, pivot to next solution (+1-2 weeks) + +Phase 6: Decide & Document (Week 3-4) + -> GO (roadmap + epics + PRD) / PIVOT (next solution) / KILL (deprioritize) + -> 30-min stakeholder readout: problem validation, solution validation, recommendation +``` + +**Timeline ranges:** fast track 3 weeks (5 interviews, 1 experiment) | typical 4 weeks | thorough 6-8 weeks. + +**Top anti-patterns:** +1. **Skipping interviews** -- relying only on analytics. Fix: always 5-10 qualitative interviews. +2. **Analysis paralysis** -- 6 weeks synthesizing. Fix: time-box to 3-4 weeks total. +3. **Discovery as one-time event** -- run continuous (Teresa Torres: 1 interview/week). + +--- + +### Interview Prep (Interactive, 4 adaptive questions) + +**Q1 -- Research Goal:** problem validation | JTBD discovery | retention/churn investigation | feature prioritization + +**Q2 -- Target Segment:** people who experience problem regularly | people who tried to solve it | people in target segment regardless of awareness | people who recently experienced it + +**Q3 -- Constraints:** limited access (5-10, 2 weeks) | existing base (100+ customers) | cold outreach required | internal stakeholders only (proxy) + +**Q4 -- Methodology (context-aware on Q1-Q3):** +- **Mom Test (Rob Fitzpatrick — problem validation):** past behavior, not hypotheticals. "Tell me about the last time..." +- **JTBD interviews:** what customers hire/fire. "What were you trying to get done?" +- **Switch interviews:** push/pull of changing solutions. "What prompted you to look?" +- **Timeline/journey mapping:** chronological walkthrough of full experience + +**Output: interview plan with opening (5 min), 5 core questions with follow-ups and anti-patterns, closing (5 min), bias checklist, success criteria, logistics.** + +**5 biases to avoid in every interview:** +1. Confirmation bias -- don't ask "Don't you think X is a problem?" +2. Leading questions -- don't ask "Would you use this?" +3. Hypothetical questions -- don't ask "If we built Y, would you pay?" +4. Pitching disguised as research -- don't explain your solution +5. Yes/no questions -- don't ask "Is invoicing hard?" + +**Interview success = specific stories (not generic complaints) + past behavior (not wishes) + patterns across 3+ interviews + at least one surprise.** + +**Top anti-patterns:** +1. **Asking what customers want** -- gets feature requests, not problems. Fix: ask about past behavior. +2. **Pitching instead of listening** -- don't mention your solution until last 5 min (if at all). +3. **Stopping at 1-2 interviews** -- small sample = confirmation bias. Fix: 5-10 minimum. + +--- + +## Jobs to Be Done + +### JTBD Framework (Component) + +**Three categories of customer jobs:** + +| Type | Question | Examples | +|------|----------|----------| +| **Functional** | What tasks to complete? | "Reconcile monthly expenses for tax filing" | +| **Social** | How to be perceived? | "Be seen as strategic by exec team" | +| **Emotional** | What state to achieve/avoid? | "Feel confident I'm not missing details" | + +**Four categories of pains:** +- **Challenges:** obstacles preventing job completion +- **Costliness:** excessive time, money, or effort +- **Common mistakes:** preventable errors +- **Unresolved problems:** gaps in current solutions + +**Four categories of gains:** +- **Expectations:** what exceeds current solutions +- **Savings:** time/money/effort reductions +- **Adoption factors:** what triggers switching +- **Life improvement:** how life gets better + +**Quality gates for jobs:** +- Verb-driven (actions, not nouns) +- Solution-agnostic ("communicate with team" not "use Slack") +- Specific ("track expenses for tax deductions" not "manage finances") + +**Prioritization:** rank pains by intensity (acute vs. mild). Ask: "If we solved one pain, which has biggest impact?" + +**Top anti-patterns:** +1. **Confusing jobs with solutions** -- "I need Slack." Fix: ask "Why?" 5 times. +2. **Ignoring social/emotional jobs** -- people buy on emotion, justify with logic. Fix: explicitly ask about perception and feelings. +3. **Fabricating JTBD without research** -- assumptions aren't insights. Fix: conduct switch interviews or contextual inquiries. + +--- + +## Opportunity Mapping + +### Opportunity Solution Tree (Teresa Torres — Interactive, 2 phases) + +**Structure:** +``` +Desired Outcome (1 measurable metric) + | + +-- Opportunity 1 (customer problem, not solution) + | +-- Solution A + experiment + | +-- Solution B + experiment + | +-- Solution C + experiment + | + +-- Opportunity 2 + | +-- Solutions... + | + +-- Opportunity 3 + +-- Solutions... +``` + +**Phase 1 -- Generate tree:** +1. Extract desired outcome (revenue growth / retention / acquisition / efficiency) +2. Generate 3 opportunities per outcome (customer problems with evidence) +3. Generate 3 solutions per opportunity (with hypothesis + experiment for each) + +**Phase 2 -- Select POC:** +- Score each solution: Feasibility (1-5) + Impact (1-5) + Market Fit (1-5) +- Feasibility: 1 = months, 5 = days. Impact: 1 = minimal, 5 = major. Market Fit: 1 = customers don't care, 5 = actively request. +- Pick highest total score as POC. Define experiment type: A/B test, prototype + usability, or concierge. + +**Hypothesis template:** "If we [solution], then [metric] will [change] from [X] to [Y] because [rationale]." + +**Top anti-patterns:** +1. **Opportunities disguised as solutions** -- "We need a mobile app." Fix: reframe as customer problem: "Mobile users can't access product on the go." +2. **Skipping divergence** -- "We know the solution." Fix: generate 3+ per opportunity. Force divergence before convergence. +3. **No experiments** -- picking solution and going to roadmap. Fix: every solution must map to an experiment. +4. **Vague outcomes** -- "Improve UX." Fix: make measurable: "Reduce drop-off from 60% to 40%." + +--- + +## Customer Journey + +### Journey Map (Component) + +**Horizontal axis (stages):** Awareness -> Consideration -> Decision -> Service -> Loyalty + +**Vertical axis (per stage):** +- Customer Actions (observable, specific) +- Touchpoints (digital + physical + human) +- Customer Experience (emotions with customer quotes) +- KPIs (measurable, stage-appropriate) +- Business Goals (outcome-focused, stage-aligned) +- Teams Involved (cross-functional with specific roles) + +**Quality gates:** +- Emotions are specific ("relieved setup took 30 min, not 3 hours") not generic ("happy") +- Touchpoints include offline (conferences, calls), not just digital +- Map reflects what customers actually do, not what you want them to do +- KPIs and goals present for every stage + +--- + +### Journey Mapping Workshop (Interactive, 5 questions) + +**Q1 -- Actor:** select persona (primary / secondary / high-churn / newly discovered) +**Q2 -- Scenario + Goal:** first-time use / core workflow / problem resolution / upgrade-expansion +**Q3 -- Journey Phases:** generate 4-6 phases based on scenario (e.g., Discover -> Evaluate -> Try -> Activate -> Use -> Expand) +**Q4 -- Per-phase mapping:** 3-5 actions, thoughts, emotions, and pain points per phase +**Q5 -- Opportunities:** rank 5-7 pain points by impact (HIGH/MEDIUM/LOW) with evidence + +**Output:** full journey map + prioritized opportunity list. + +**Top anti-patterns:** +1. **Mapping internal process, not customer experience** -- "Lead generated -> Qualified -> Demo." Fix: map from customer POV. +2. **No emotions** -- actions only. Fix: add customer quotes and emotional states. +3. **Too many personas in one map** -- loses focus. Fix: one map per persona. + +--- + +## Lean Validation + +### Lean UX Canvas (v2, Interactive, 8 boxes) + +**Fill order:** + +| Box | Question | Content Type | +|-----|----------|-------------| +| 1. Business Problem | What changed that created a problem? | Context + trigger | +| 2. Business Outcomes | What behavior change = success? | Metrics (not emotions) | +| 3. Users | Which persona first? | Specific segment | +| 4. User Outcomes & Benefits | Why would users seek this? | Goals, emotions, empathy (not metrics) | +| 5. Solutions | What might solve it? | 3+ candidate features/initiatives | +| 6. Hypotheses | Testable if/then statements | "We believe [outcome] if [user] attains [benefit] with [solution]" | +| 7. Learn First | What's the riskiest assumption? | Value > usability > feasibility > viability risk | +| 8. Least Work | Smallest experiment to test it? | Must complete in <2 weeks | + +**Box 2 vs Box 4 distinction:** Box 2 = behavior change metrics. Box 4 = human motivation and empathy. + +**Top anti-patterns:** +1. **Starting with solutions** -- Box 1 says "build X." Fix: ask "What changed? Why is this a problem now?" +2. **Confusing Box 2 and Box 4** -- metrics in the empathy box. Fix: Box 2 = numbers, Box 4 = feelings. +3. **Only one solution in Box 5** -- no exploration. Fix: force 3+ candidates. +4. **Skipping experiments** -- "just build it." Fix: design smallest test first. + +--- + +### PoL Probe (Component) -- Proof of Life + +**A disposable, hypothesis-driven validation artifact. Not an MVP. Planned for deletion.** + +**5 required characteristics:** Lightweight (hours/days) + Disposable (deletion date set) + Narrow Scope (one hypothesis) + Brutally Honest (surfaces harsh truth) + Tiny & Focused (reconnaissance, not product). + +**Template fields:** hypothesis, risk being eliminated, probe type, target users, success criteria (pass/fail/learn thresholds), tools, timeline, disposal plan, owner, status. + +**5 Probe Flavors:** + +| Flavor | Core Question | Timeline | When to Use | +|--------|---------------|----------|-------------| +| Feasibility Check | Can we build this? | 1-2 days | Technical unknowns, API deps, data integrity | +| Task-Focused Test | Can users complete this job? | 2-5 days | Critical UI moments, navigation, drop-off zones | +| Narrative Prototype | Does this earn buy-in? | 1-3 days | Complex flow explanation, stakeholder alignment | +| Synthetic Data Simulation | Can we model without production risk? | 2-4 days | Edge cases, unknown-unknowns, load testing | +| Vibe-Coded Probe | Will this survive real user contact? | 2-3 days | Workflow/UX validation needing real interaction | + +**Golden Rule:** Use the cheapest prototype that tells the harshest truth. + +--- + +### PoL Probe Advisor (Interactive, decision logic) + +**Selection flow:** hypothesis -> risk type -> core question -> recommended probe. + +**Decision matrix:** +- Technical feasibility unknown -> **Feasibility Check** (spike-and-delete, API sniff tests) +- Critical UI friction -> **Task-Focused Test** (Optimal Workshop, UsabilityHub, Maze) +- Need stakeholder alignment -> **Narrative Prototype** (Loom walkthrough, slideware storyboard) +- Edge case exploration -> **Synthetic Data Simulation** (Monte Carlo, synthetic users, LangFlow) +- Need real user interaction -> **Vibe-Coded Probe** (ChatGPT Canvas + Replit + Airtable Frankensoft) + +**Refinement questions when hypothesis is too broad:** +1. What's the smallest thing you could test first? +2. What would failure look like? +3. Is this testing user behavior, technical feasibility, or stakeholder alignment? Pick one. + +**Top anti-patterns:** +1. **Choosing based on tooling comfort** -- "I know Figma, so I'll prototype." Fix: match method to hypothesis, not skillset. +2. **Defaulting to code** -- "Let's just build it." Fix: ask what's cheapest path to harsh truth. +3. **Confusing vibe-coded probes with MVPs** -- scope creep, refusal to dispose. Fix: set disposal date before building. +4. **Testing multiple things at once** -- ambiguous results. Fix: one probe, one hypothesis. +5. **No success criteria** -- "we'll know it when we see it." Fix: define pass/fail/learn before building. + +--- + +## Quality Gates + +### Consolidated Anti-Patterns Across All 11 Skills + +**Problem framing failures:** +- Solution smuggling in problem statements +- Business metrics framed as user problems +- Generic personas ("busy professionals") +- Skipping bias examination (Look Inward) + +**Research failures:** +- Leading / hypothetical / yes-no questions +- Pitching disguised as research +- Stopping at 1-2 interviews (need 5-10 minimum) +- Not recording insights immediately post-interview +- Never reaching saturation (same patterns in 3+ interviews) + +**Synthesis failures:** +- Analysis paralysis (6+ weeks, no decisions) +- Opportunities disguised as solutions in OST +- Vague outcomes that can't be measured +- Journey maps reflecting internal wishful thinking, not customer reality +- Generic emotions ("happy") instead of specific states + +**Validation failures:** +- Prototype theater (impressive demos that teach nothing) +- Choosing validation method by tooling comfort, not hypothesis +- Testing multiple variables in one experiment +- No pre-defined failure criteria +- Treating disposable probes as production code +- Discovery as one-time event instead of continuous practice + +### Universal Quality Checks + +Every discovery artifact should pass these: +1. **Falsifiable:** can you describe what failure looks like? +2. **Evidence-backed:** grounded in customer research, not assumptions? +3. **Specific:** can you picture the person, the problem, the metric? +4. **Actionable:** does it inform a concrete next step? +5. **Time-boxed:** is there a deadline that prevents indefinite exploration? diff --git a/skills/product-manager-skills/knowledge/finance-metrics.md b/skills/product-manager-skills/knowledge/finance-metrics.md new file mode 100644 index 0000000..1189de9 --- /dev/null +++ b/skills/product-manager-skills/knowledge/finance-metrics.md @@ -0,0 +1,260 @@ +# Finance & Metrics + +Compressed reference for SaaS finance: 32 metrics with formulas and benchmarks, diagnostic frameworks, and decision logic for feature investment, channel evaluation, and pricing changes. + +## SaaS Revenue & Growth Metrics + +### Core Revenue Metrics + +| Metric | Formula | Benchmarks | +|--------|---------|------------| +| **Revenue** | Sum of all customer payments in period | Growth rate >20% YoY (varies by stage) | +| **ARPU** | Total Revenue / Total Users | B2C: $5-50/mo; B2B: $50-500+/mo; track trend | +| **ARPA** | MRR / Active Accounts | SMB: $100-$1K/mo; Mid: $1K-$10K; Ent: $10K+ | +| **ACV** | Annual Recurring Revenue per Contract (exclude one-time fees) | SMB: $5K-$25K; Mid: $25K-$100K; Ent: $100K+ | +| **MRR/ARR** | MRR = sum of recurring subs; ARR = MRR x 12 | Track components: New + Expansion - Churned - Contraction | +| **Gross vs Net Revenue** | Net = Gross - Discounts - Refunds - Credits | Refunds >10% = product problem; Discounts >20% = pricing power problem | + +**ARPA/ARPU combined analysis:** Average Seats per Account = ARPA / ARPU. High ARPA + low ARPU = undermonetized seats. Low ARPA + high ARPU = small deal sizes. + +### Retention & Expansion Metrics + +| Metric | Formula | Benchmarks | +|--------|---------|------------| +| **Churn Rate (Logo)** | Customers Lost / Starting Customers | Monthly: <2% great, 2-5% ok, >5% crisis | +| **Churn Rate (Revenue)** | MRR Lost / Starting MRR | Annual: <10% great, 10-30% ok, >30% crisis | +| **NRR** | (Start ARR + Expansion - Churn - Contraction) / Start ARR x 100 | >120% excellent; 100-120% good; <90% problem | +| **Expansion Revenue** | Upsells + Cross-sells + Usage Growth | Should be 20-30% of total revenue | +| **Quick Ratio** | (New MRR + Expansion MRR) / (Churned MRR + Contraction MRR) | >4 excellent; 2-4 healthy; <2 leaky bucket | + +**Churn compounding:** 3% monthly != 36% annual. Use `Annual Churn = 1 - (1 - Monthly)^12`. 3% monthly = ~31% annual. 5% monthly = ~46% annual. + +### Analysis Frameworks + +**Revenue Mix:** Product/Segment Revenue / Total Revenue x 100. No single product >60% ideal. Top customer <10% revenue; top 10 <40%. + +**Cohort Analysis:** Group customers by join date, track retention/expansion over time. Recent cohorts should perform same or better than older ones. If newer cohorts degrade, PMF is eroding -- stop scaling, fix product. + +## Unit Economics & Efficiency + +### Customer-Level Profitability + +| Metric | Formula | Benchmarks | +|--------|---------|------------| +| **Gross Margin** | (Revenue - COGS) / Revenue x 100 | SaaS: 70-85% good; <60% concerning | +| **CAC** | Total S&M Spend / New Customers Acquired | Enterprise: $10K+ ok; SMB: <$500 target | +| **LTV (simple)** | ARPU x Avg Customer Lifetime (months) | Must be 3x+ CAC | +| **LTV (better)** | ARPU x Gross Margin % / Monthly Churn Rate | Use this for decisions | +| **LTV:CAC** | LTV / CAC | <1:1 unsustainable; 1-3:1 marginal; 3-5:1 healthy; >5:1 underinvesting | +| **Payback Period** | CAC / (Monthly ARPU x Gross Margin %) | <12mo great; 12-18 ok; >24 concerning | +| **Contribution Margin** | (Revenue - All Variable Costs) / Revenue x 100 | 60-80% good; <40% concerning | +| **Gross Margin Payback** | CAC / (Monthly ARPU x Gross Margin %) | Same formula as Payback above; use this version | + +**COGS includes:** Hosting, infrastructure, payment processing, customer onboarding costs. +**Variable costs include:** COGS + support + payment processing + variable customer success. + +**Critical insight:** 4:1 LTV:CAC with 36-month payback is a cash trap. 3:1 LTV:CAC with 8-month payback is better for growth. + +### Capital Efficiency + +| Metric | Formula | Benchmarks | +|--------|---------|------------| +| **Burn Rate (Gross)** | Total Monthly Cash Spent | Context-dependent | +| **Burn Rate (Net)** | Monthly Cash Spent - Monthly Revenue | Early <$200K manageable; >$500K needs revenue path | +| **Runway** | Cash Balance / Monthly Net Burn | 12+ good; 6-12 ok; <6 crisis. Raise at 6-9 months, not 3 | +| **OpEx** | S&M + R&D + G&A | Should grow slower than revenue | +| **Net Income** | Revenue - COGS - OpEx | Early negative ok; mature 10-20%+ margin | + +**Working capital:** Annual contracts paid upfront boost cash. Monthly billing delays collection. Cash-based runway != revenue-based runway. + +### Efficiency Ratios + +| Metric | Formula | Benchmarks | +|--------|---------|------------| +| **Rule of 40** | Revenue Growth % + Profit Margin % | >40 healthy; 25-40 ok; <25 concerning | +| **Magic Number** | (Q Revenue - Prev Q Revenue) x 4 / Prev Q S&M Spend | >0.75 scale; 0.5-0.75 optimize; <0.5 fix GTM | +| **Operating Leverage** | Revenue Growth Rate vs OpEx Growth Rate | Revenue growth must exceed OpEx growth | + +**Rule of 40 by stage:** Early = 60% growth + (-20%) margin = 40. Growth = 40% + 5% = 45. Mature = 20% + 25% = 45. + +## Business Health Diagnostic + +### Four-Dimension Framework + +1. **Growth & Retention** -- Revenue growth, NRR, churn, Quick Ratio +2. **Unit Economics** -- CAC, LTV, LTV:CAC, payback, gross margin +3. **Capital Efficiency** -- Burn, runway, Rule of 40, Magic Number +4. **Strategic Position** -- Market pricing, moat, concentration, leverage + +### Stage-Specific Benchmarks + +| Metric | Early (<$10M ARR) | Growth ($10-50M) | Scale ($50M+) | +|--------|-------------------|-------------------|---------------| +| Growth YoY | >50% | >40% | >25% | +| LTV:CAC | >3:1 | -- | -- | +| NRR | -- | >100% | >110% | +| Gross Margin | >70% | -- | -- | +| Rule of 40 | -- | >40 | >40 | +| Magic Number | -- | >0.75 | -- | +| Profit Margin | negative ok | -- | >10% | +| Runway | >12 months | -- | positive cash flow | + +### Red Flag Severity + +**Critical (fix immediately):** Runway <6mo, LTV:CAC <1.5:1, churn accelerating cohort-over-cohort, NRR <90%, Magic Number <0.3. + +**High priority (fix within quarter):** Rule of 40 <25, payback >24mo, Quick Ratio <2, gross margin <60%, revenue concentration >50% in top 10. + +**Medium priority (address within 6 months):** NRR 90-100%, Magic Number 0.3-0.5, negative operating leverage, stable but high churn (>5% monthly). + +### Diagnostic Scoring + +- **Healthy:** All dimensions at/above stage benchmarks, no critical flags, improving trends. Action: scale aggressively. +- **Moderate:** 1-2 dimensions need attention, medium-priority flags. Action: fix specific issues before scaling further. +- **Concerning:** Multiple critical flags, 2+ dimensions problematic. Action: urgent intervention -- stop scaling, fix retention and unit economics. +- **Critical:** Runway <3mo or LTV:CAC <1:1. Action: survival mode -- emergency fundraise or cut burn 50%+. + +## Feature Investment Analysis + +### Revenue Connection Types + +1. **Direct monetization** -- new tier, paid add-on, usage fee. Calculate: Customer Base x Adoption Rate x Price. +2. **Retention improvement** -- addresses churn reason. Calculate: LTV Impact = Lifetime Increase x Base x ARPU x Margin. +3. **Conversion improvement** -- trial-to-paid lift. Calculate: Trial Users x Conversion Lift x ARPU. +4. **Expansion enabler** -- upsell/cross-sell path. Calculate: Base x Expansion Rate x ARPU Increase. + +### ROI Thresholds + +| Scenario | Build if | Don't build if | +|----------|----------|----------------| +| Direct monetization | ROI >3x year one | Negative contribution margin in downside case | +| Retention feature | LTV impact >10x dev cost | Payback exceeds avg customer lifetime | +| Strategic override | Competitive moat, platform enabler, compliance | "Strategic" without clear definition | + +### Cost Structure Check + +- One-time: development cost (team size x time) +- Ongoing: COGS impact (hosting, infra) + OpEx (support, maintenance) +- Margin impact: if COGS >20% of projected revenue, flag margin dilution +- Contribution margin: (Revenue - COGS) / Revenue must stay positive + +### Decision Patterns + +**Build now:** ROI >3:1 (direct) or LTV impact >10:1 (retention), positive contribution margin, payback < customer lifetime. + +**Build for strategic reasons:** ROI <2:1 but competitive moat, platform enabler, or compliance. Cap investment, monitor adoption, re-evaluate at 6 months. + +**Don't build:** ROI <1:1, negative contribution margin, no strategic value. Consider reducing scope or changing monetization. + +**Build later:** High uncertainty in adoption or impact assumptions. Validate with surveys, prototypes, churn interviews first. + +## Channel Economics + +### Channel Evaluation Framework + +Evaluate each channel on four dimensions: + +1. **Unit economics** -- CAC, LTV, LTV:CAC, payback (per channel, not blended) +2. **Customer quality** -- cohort retention, churn rate, NRR, ICP fit (per channel) +3. **Scalability** -- Magic Number, addressable volume, CAC trend +4. **Strategic fit** -- segment match, sales motion compatibility + +### Channel Decision Matrix + +| LTV:CAC | Payback | Customer Quality | Scalability | Decision | +|---------|---------|------------------|-------------|----------| +| >3:1 | <12mo | Good retention | High volume | **Scale aggressively** | +| 2-3:1 | 12-18mo | Average retention | Medium | **Test & optimize** | +| <2:1 | >18mo | Poor retention | Low | **Kill or fix** | + +### Scale Criteria + +Scale when ALL met: LTV:CAC >3:1 AND payback <12mo AND Magic Number >0.75 AND customer quality >= blended. Increase budget 50-100%, monitor weekly for CAC increase >20% (saturation signal). + +### Optimize Playbook + +- **If CAC too high:** Improve conversion rate, reduce cost-per-click, shorten sales cycle. +- **If LTV too low:** Improve onboarding for channel cohort, target higher-value segments, add expansion plays. +- **If targeting off:** Narrow audience, improve messaging, add qualification step. +- Timeline: 4-8 weeks. Target LTV:CAC >3:1, payback <12mo. If unachievable, kill. + +### Kill Criteria + +LTV:CAC <1.5:1 with no clear improvement path. Reallocate budget to top-performing channel. Exception: strategic channels (enterprise field sales) get capped spend and 6-12 month runway to prove out. + +### Incrementality + +Test with holdout groups. Only count truly incremental conversions. Retargeting campaigns often claim credit for conversions that would have happened organically. + +## Pricing Analysis + +### Pricing Change Types + +- **Price increase** -- new customers only (grandfather existing) vs all customers +- **New premium tier** -- upsell path, watch cannibalization +- **Paid add-on** -- monetize feature; assess retention risk if previously free +- **Usage-based** -- charge per unit (seats, API calls, storage); enables expansion revenue +- **Discount strategy** -- annual prepay (cash flow), volume (larger deals), promotional (urgency) +- **Packaging change** -- rebundle features, change pricing metric + +### Five-Dimension Impact Assessment + +1. **Revenue:** ARPU lift = (New ARPU - Current ARPU) / Current ARPU. Expected MRR increase = Base x ARPU Lift. +2. **Conversion:** Higher prices may reduce trial-to-paid. Model conversion drop and its effect on new customer volume. +3. **Churn:** Model scenarios -- conservative (+2pp churn), base (+1pp), optimistic (+0). Churn-driven MRR loss = additional churn % x base x new ARPU. +4. **Expansion:** Does change create upsell path? Usage-based pricing enables natural expansion as customers grow. +5. **CAC Payback:** Higher ARPU = faster payback, but lower conversion = higher effective CAC. Calculate net effect. + +### Decision Patterns + +**Implement broadly:** Net revenue clearly positive (>10% ARPU lift, <5% churn risk), minimal conversion impact. Grandfather existing customers. + +**Test first (A/B):** Uncertain impact, moderate risk. Test 60-90 days with 100+ customers per cohort. Roll out if conversion stays within acceptable range. + +**Modify approach:** Original proposal too risky. Options: smaller increase, grandfather existing, segment-based pricing (raise enterprise only). + +**Don't change:** Churn-driven loss exceeds revenue gains, or high competitive pressure. Focus on retention/expansion instead. + +### Annual Discount Guardrails + +Limit to 10-15% for annual prepay. 30% annual discounts destroy LTV. Balance cash flow improvement with revenue protection. + +## Quality Gates + +### Vanity Metric Traps + +- **Revenue without margin:** $1M at 80% margin >> $2M at 20% margin +- **ARPU growth from mix shift:** ARPU rose because small customers churned, not because monetization improved +- **Signups without conversion:** 10,000 signups at 5% conversion = 500 customers. Calculate CAC on paid, not signups +- **Engagement without revenue:** Feature increases engagement but not retention or monetization -- not a business outcome +- **Gross revenue hiding net contraction:** Track discounts and refunds; gross up 20% but discounts doubled = flat net + +### Blended Metric Dangers + +Never use blended averages for decisions. Always segment by: +- **Channel:** One channel at $10K CAC hides in $500 blended CAC +- **Segment:** $100 ARPU blends $10 SMB and $1,000 enterprise -- useless for decisions +- **Cohort:** Blended 3% churn hides newer cohorts at 6% and old cohorts at 1% +- **Product:** 67% legacy product dying at -5% growth masked by 33% new product at +80% + +### Common Calculation Errors + +- **LTV without margin:** Use `ARPU x Margin % / Churn`, not `ARPU x Lifetime` +- **Churn multiply-by-12:** Churn compounds. 3% monthly = 31% annual, not 36% +- **Payback without margin:** Use gross margin payback, not revenue payback +- **CAC comparison without payback:** $5K CAC with 24mo payback is worse than $8K CAC with 8mo payback +- **Rule of 40 without runway:** Score of 50 means nothing with 3 months runway +- **LTV:CAC without payback:** 6:1 ratio with 48-month payback is a cash trap + +### Decision-Making Anti-Patterns + +- Scaling acquisition when Quick Ratio <2 (leaky bucket) +- Raising prices without modeling churn scenarios +- Celebrating NRR >100% from low churn alone (not expansion-driven) +- Using "strategic" as catch-all for building low-ROI features +- Fixing everything simultaneously instead of prioritizing top 1-3 issues +- Killing channels before 3-6 months and 100+ customers of data +- Over-relying on one channel (>50% of acquisition) +- Annual discounts >15% that destroy LTV for short-term cash +- Testing pricing on 10 customers (need 100+ per cohort for significance) +- Celebrating feature requests from 0.5% of base while ignoring the other 99.5% diff --git a/skills/product-manager-skills/knowledge/strategy-positioning.md b/skills/product-manager-skills/knowledge/strategy-positioning.md new file mode 100644 index 0000000..dd81d1c --- /dev/null +++ b/skills/product-manager-skills/knowledge/strategy-positioning.md @@ -0,0 +1,241 @@ +# Strategy & Positioning + +Compressed knowledge module covering company/market research, positioning, product strategy, prioritization, and roadmap planning. + +## Company & Market Research + +### Company Research Framework + +Research across 7 dimensions: Company Overview, Executive Quotes, Product Insights, Transformation Strategies, Organizational Impact, Future Roadmap, Product-Led Growth. + +**Research steps:** +1. Define scope: company name, research purpose, 3 key questions +2. Gather overview: headquarters, industry, founding, size, key milestones +3. Extract executive quotes: CEO (vision), COO (operations), VP Product (strategy), Group PM (initiatives). Cite source + date. Prioritize last 12-24 months. +4. Document product insights: strategy overview, recent launches with market impact, product philosophy/principles +5. Identify transformation strategies: digital (architecture shifts), AI (ML in product), Agile (methodology adoption) +6. Map organizational PM impact: PM role in strategic decisions, cross-functional collaboration model, career paths +7. Analyze future roadmap: planned initiatives, anticipated challenges, competitive threats +8. Document PLG insights: self-serve onboarding, data-driven decisions, activation/retention/expansion patterns +9. Synthesize: 3 strategic principles, 3 PM lessons, unanswered questions + +**Source priority:** Earnings transcripts > podcast interviews > conference talks > executive blog posts > LinkedIn > company website. Go deeper than "About Us" pages. + +### PESTEL Analysis + +Six macro-environmental factors. Define scope first: product name, analysis purpose, geographic scope, time horizon. + +| Factor | Key Questions | Example Sources | +|--------|--------------|-----------------| +| **Political** | Government policies, stability, trade regs, taxation | Legislative databases, trade reports | +| **Economic** | GDP growth, inflation, exchange rates, consumer spending | Census Bureau, BLS, World Bank | +| **Social** | Demographics, cultural trends, lifestyle shifts, attitudes | Pew Research, demographic studies | +| **Technological** | Advancements, R&D activity, automation, digital adoption | Gartner, industry reports | +| **Environmental** | Climate impact, sustainability, resource scarcity, green regs | If impact is minimal, say so honestly | +| **Legal** | Compliance (GDPR, AI Act), IP, employment law, safety regs | Legal databases, regulatory filings | + +**For each factor:** State the specific impact on your product and what strategic action it implies. Generic statements ("regulations exist") are useless. + +**Synthesis output:** Top 3 opportunities (with actions), top 3 threats (with mitigations), 3 strategic recommendations. Reassess annually or on major external events. + +### TAM/SAM/SOM Calculation + +Three-tier market sizing with citation-backed data. + +**TAM** = Total market demand at 100% capture. Broadest possible. +**SAM** = TAM narrowed by geography, firmographics, product constraints. "Who can we actually reach?" +**SOM** = SAM narrowed by competition, GTM capacity. "What can we capture in 1-3 years?" Typically 1-20% of SAM in Year 1-3. + +**Calculation process:** +1. Define problem space (B2B SaaS, consumer fintech, healthcare, etc.) +2. Select geographic region (US = Census/BLS data; EU = Eurostat; Global = World Bank/IMF) +3. Identify industry segments with population + revenue data +4. Narrow to target customer segment with firmographics/demographics + +**Output format:** For each tier, show population estimate, market size ($), calculation math, source citation with URL, and key assumptions. + +**Year 1-3 projections for SOM:** Include customer count and revenue. Ground in GTM constraints (sales capacity, conversion rates, marketing budget). + +**Data sources:** US Census Bureau, BLS, IBISWorld, Statista, Gartner, Forrester, World Bank, Eurostat. + +## Product Positioning + +### Geoffrey Moore Positioning Statement + +Two-part structure from *Crossing the Chasm*: + +**Value Proposition:** +- **For** [specific target customer/persona] +- **that need** [underserved need -- pains, gains, JTBD] +- [product name] +- **is a** [product category] +- **that** [benefit statement -- outcomes, not features] + +**Differentiation Statement:** +- **Unlike** [primary competitor or actual substitute behavior] +- [product name] +- **provides** [unique differentiation -- outcomes, not features] + +### Stress Tests (apply to every draft) + +1. Would the target customer recognize themselves in the "For" statement? +2. Can you point to research validating the need? +3. Does the category anchor you against the right competitors (or box you in)? +4. Is differentiation provable with a demo, case study, or data? +5. Does this positioning help answer "Should we build feature X?" + +### Positioning Workshop Flow (Interactive) + +5-question discovery sequence: +1. **Target customer segment** -- B2B SMB / B2B Enterprise / B2C mass / B2C niche (or custom) +2. **Underserved need** -- Adapted to segment from Q1 (time waste, lack of visibility, compliance burden, costly inefficiency) +3. **Product category** -- Anchors buyer evaluation. Pick existing category unless you have strong rationale for category creation. +4. **Key benefit** -- Outcome, not feature. Must be measurable (time saved, errors reduced, cost cut). +5. **Competitive differentiation** -- Name the actual competitor or substitute behavior. Differentiate on outcomes. + +Output: Complete positioning statement + one-sentence summary + stress-test checklist + next steps (test with 5 customers, share with stakeholders, apply to artifacts). + +### Positioning Quality Criteria + +- Target specificity: describable to a recruiter +- Need clarity: emotionally resonant, not generic +- Category fit: helps buyer evaluation, not "next-generation platform" +- Outcome focus: what user gets, not what product has +- Competitor honesty: real alternative buyers consider +- Differentiation durability: not copyable in 6 months + +## Product Strategy + +### Strategy Session Phases (2-4 week process) + +**Phase 1: Positioning & Market Context (Days 1-2)** +- Run positioning workshop. Define proto-personas. Map JTBD. +- Decision gate: Enough customer context? If NO, run 5-10 discovery interviews (+1 week). + +**Phase 2: Problem Framing & Validation (Days 3-5)** +- Run problem framing canvas. Create formal problem statement. Optional: customer journey map. +- Decision gate: Problem validated? If NO, run discovery interviews (+1 week). + +**Phase 3: Solution Exploration (Week 2, Days 1-3)** +- Generate opportunity solution tree (3 opportunities, 3 solutions each, POC recommendation). Define epic hypotheses. +- Decision gate: Need to test solutions? If YES (high uncertainty), run experiments (+1-2 weeks). + +**Phase 4: Prioritization & Roadmap (Week 2, Days 4-5)** +- Choose prioritization framework. Score and rank epics. Sequence roadmap by release. Optional: TAM/SAM/SOM for exec presentations. + +**Phase 5: Stakeholder Alignment (Week 3)** +- Present strategy: positioning + problem + solutions + prioritization + roadmap. +- Include "What's NOT on roadmap and why." Refine based on feedback. + +**Phase 6: Execution Planning (Week 4)** +- Break top epic using splitting patterns (workflow, CRUD, business rules). Write user stories with acceptance criteria. Plan first sprint. + +**Decision gates are mandatory.** Skipping them causes building solutions to unvalidated problems or wasting time on low-uncertainty activities. + +## Prioritization + +### Framework Selection Matrix + +| Context | Recommended Framework | Why | +|---------|----------------------|-----| +| Pre-PMF, minimal data, small team | **ICE** or **Value/Effort matrix** | Lightweight, gut-check, fast scoring | +| Early PMF, some data, aligned team | **RICE** | Structured but not overwhelming; balances data + speed | +| Mature product, rich data | **Opportunity Scoring** or **Kano** | Leverages analytics, customer surveys | +| Multiple stakeholders, misaligned | **Weighted Scoring** or **Buy-a-Feature** | Transparent, consensus-building | +| Large org, cross-team dependencies | **Cost of Delay** or **Impact Mapping** | Handles coordination complexity | +| Strategic bets vs. quick wins | **Value/Effort matrix** | Visual, intuitive for tradeoff conversations | + +### RICE Scoring + +Formula: `(Reach x Impact x Confidence) / Effort` +- **Reach:** Users affected per month/quarter +- **Impact:** 1 (minimal), 2 (high), 3 (massive) +- **Confidence:** 50% (low data), 80% (good data), 100% (certain) +- **Effort:** Person-months (include design, eng, QA) + +Use RICE as input, not automation. PM judgment overrides scores when strategic context requires it. Always adjust for strategic fit after raw scoring. + +### Prioritization Decision Logic + +4-question assessment to select framework: +1. Product stage (pre-PMF / early PMF / mature / multi-product) +2. Team context (small + focused / cross-functional aligned / stakeholders misaligned / large org) +3. Primary challenge (too many ideas / stakeholder disagreement / no data-driven process / strategic vs. tactical tradeoffs) +4. Data availability (minimal / some / rich) + +Stick with one framework 6-12 months. Reassess only when stage or context changes. + +## Roadmap Planning + +### Roadmap Types + +| Type | Structure | Best For | +|------|-----------|----------| +| **Now/Next/Later** | Committed / High confidence / Exploration | Agile teams, uncertainty, continuous discovery | +| **Theme-Based** | Strategic themes (Retention, Enterprise, Mobile) | Exec communication, strategic intent | +| **Timeline (Quarters)** | Q1: A, B; Q2: C, D; Q3: E, F | Resource planning, stakeholder comm | +| **Feature-Based** | Lists features without context | Anti-pattern. No strategic narrative. | + +### Roadmap Planning Process (5 phases, 1-2 weeks) + +**Phase 1: Gather Inputs (Days 1-2)** +- Business goals: top 3 company priorities, key metrics, strategic bets +- Customer problems: top 3-5 validated pain points (from discovery) +- Technical constraints: blockers, enabling investments, migrations +- Stakeholder requests: sales, marketing, CS inputs (not yet committed) + +**Phase 2: Define Initiatives (Days 3-4)** +- Write epic hypotheses: "We believe [building X] for [persona] will achieve [outcome] because [assumption]." +- T-shirt size effort: S (1-2 wk), M (3-4 wk), L (2-3 mo), XL (3+ mo) +- Map each epic to primary business outcome + +**Phase 3: Prioritize (Day 5)** +- Select framework using prioritization advisor +- Score all epics collaboratively (PM + eng + product leadership) +- Adjust scores for strategic fit (strategic overrides are legitimate) + +**Phase 4: Sequence (Days 6-7)** +- Map dependencies (technical and logical) +- Assign to Now (committed), Next (high confidence), Later (exploration) +- Validate sequence with engineering for feasibility + +**Phase 5: Communicate (Week 2)** +- Presentation structure: strategic context, roadmap overview, per-quarter deep dive, what's NOT on roadmap (and why), dependencies and risks +- Focus on strategic narrative: "Here's why X over Y" +- Frame as plan, not commitment: "Subject to change based on learning" +- Gather feedback, refine, publish internally (and optionally externally in Now/Next/Later format) + +## Quality Gates + +### Positioning Anti-Patterns +- **"For Everyone"** -- No one feels it's for them. Pick the first segment; expand later. +- **Feature Creep in Benefits** -- "AI, automation, analytics" is a feature list. Lead with outcome. +- **Imaginary Competitor** -- "Unlike outdated legacy systems" is a straw man. Name the actual alternative. +- **Category Confusion** -- "Next-generation platform for digital transformation" has no mental shelf. Pick a known category or commit to category creation. +- **Differentiation Without Proof** -- "Revolutionary AI" without evidence is noise. Make it falsifiable. + +### Research Anti-Patterns +- **Surface-Level Research** -- Find executive interviews and product blogs, not just "About Us" pages. +- **No Citations** -- Always cite source + date. Unverifiable = low credibility. +- **Analysis Without Action** -- PESTEL and company research must end in strategic recommendations, not just lists. +- **Outdated Information** -- Prioritize sources from last 12-24 months. + +### Market Sizing Anti-Patterns +- **TAM Without Citations** -- Cite industry reports (Gartner, IBISWorld, Statista) with URLs. +- **SOM = SAM** -- No market has zero competition. SOM = 1-20% of SAM in Year 1-3. +- **No Population Estimates** -- Always include customer counts alongside dollar amounts. +- **Ignoring GTM Constraints** -- Ground SOM in sales capacity, conversion rates, marketing budget. + +### Prioritization Anti-Patterns +- **Wrong Framework for Stage** -- Pre-PMF startup using weighted scoring with 10 criteria kills speed. +- **Framework Whiplash** -- Switching frameworks every quarter causes confusion. Stick for 6-12 months. +- **Scores as Gospel** -- Scores are input, not automation. Strategic context overrides. +- **Solo PM Scoring** -- Collaborative scoring (PM + design + eng) builds buy-in. +- **HiPPO Prioritization** -- Any framework beats "who shouts loudest." + +### Roadmap Anti-Patterns +- **Feature-Driven Roadmap** -- Frame epics as hypotheses with success metrics, not feature names. +- **Roadmap as Commitment** -- Communicate as strategic plan, subject to change based on learning. +- **No Dependencies Mapped** -- Validate sequence with engineering. Unmapped deps = blocked quarters. +- **Solo PM Roadmap** -- Gather inputs from all stakeholders (Phase 1), present draft for feedback (Phase 5). +- **Strategy Without Exec Sponsorship** -- Secure exec commitment upfront. Schedule alignment presentation before starting. diff --git a/skills/product-manager-skills/package.json b/skills/product-manager-skills/package.json new file mode 100644 index 0000000..32c5086 --- /dev/null +++ b/skills/product-manager-skills/package.json @@ -0,0 +1,47 @@ +{ + "name": "product-manager-skills", + "version": "0.3.1", + "description": "PM skill for Claude Code, Codex, Cursor, and Windsurf: diagnose SaaS metrics, critique PRDs, plan roadmaps, run discovery, and coach PM career transitions.", + "keywords": [ + "product-manager-skills", + "openclaw-skill", + "agent-skill", + "product-manager", + "product-management", + "pm", + "prd", + "user-story", + "roadmap", + "product-strategy", + "discovery", + "positioning", + "career-coaching", + "saas-metrics", + "claude-code", + "cursor", + "codex", + "windsurf", + "ai-agent", + "skill-md" + ], + "homepage": "https://clawhub.ai/Digidai/product-manager-skills", + "repository": { + "type": "git", + "url": "https://github.com/Digidai/product-manager-skills.git" + }, + "bugs": { + "url": "https://github.com/Digidai/product-manager-skills/issues" + }, + "author": "Gene Dai (https://genedai.me/)", + "license": "CC-BY-NC-SA-4.0", + "files": [ + "SKILL.md", + "knowledge/", + "templates/", + "examples/", + "STARTER-PROMPTS.md", + "README.zh-CN.md", + "README.md", + "LICENSE" + ] +} diff --git a/skills/product-manager-skills/templates/business-health-scorecard.md b/skills/product-manager-skills/templates/business-health-scorecard.md new file mode 100644 index 0000000..ca48eeb --- /dev/null +++ b/skills/product-manager-skills/templates/business-health-scorecard.md @@ -0,0 +1,45 @@ +# Business Health Scorecard + +## Company Context +- **Company:** [Name] +- **Stage:** [Pre-$10M / $10M-$50M / $50M+ ARR] +- **Model:** [SaaS / usage-based / hybrid] + +## Growth & Retention + +| Metric | Value | Benchmark | Status | +|--------|-------|-----------|--------| +| Revenue Growth (YoY) | | | | +| NRR (Net Revenue Retention) | | | | +| Gross Churn Rate | | | | +| Quick Ratio | | | | + +## Unit Economics + +| Metric | Value | Benchmark | Status | +|--------|-------|-----------|--------| +| CAC | | | | +| LTV | | | | +| LTV:CAC | | | | +| Payback Period | | | | +| Gross Margin | | | | + +## Capital Efficiency + +| Metric | Value | Benchmark | Status | +|--------|-------|-----------|--------| +| Burn Rate | | | | +| Runway | | | | +| Rule of 40 | | | | +| Magic Number | | | | + +## Red Flags +- [ ] [Critical / High / Medium — description] + +## Priority Actions +1. [Highest-urgency fix + expected impact] +2. [Second priority] +3. [Third priority] + +--- +*Generated with [product-manager-skills](https://github.com/Digidai/product-manager-skills)* diff --git a/skills/product-manager-skills/templates/competitive-analysis.md b/skills/product-manager-skills/templates/competitive-analysis.md new file mode 100644 index 0000000..3681945 --- /dev/null +++ b/skills/product-manager-skills/templates/competitive-analysis.md @@ -0,0 +1,46 @@ +## Competitive Analysis + +### Overview + +**Product:** [your product name] +**Analysis Date:** [date] +**Market Category:** [category] + +### Competitive Landscape + +| Dimension | Your Product | Competitor A | Competitor B | Competitor C | +|-----------|-------------|-------------|-------------|-------------| +| **Positioning** | | | | | +| **Target Segment** | | | | | +| **Pricing Model** | | | | | +| **Key Differentiator** | | | | | +| **Biggest Weakness** | | | | | + +### Feature Comparison + +| Capability | Your Product | Comp A | Comp B | Comp C | Weight | +|-----------|-------------|--------|--------|--------|--------| +| [capability 1] | | | | | High/Med/Low | +| [capability 2] | | | | | | +| [capability 3] | | | | | | + +### Competitive Dynamics + +- **Direct competitors:** [same category, same buyer] +- **Indirect competitors:** [different category, same job-to-be-done] +- **Substitute behaviors:** [what customers do today without any product] + +### Strategic Implications + +1. **Where we win:** [specific scenarios where you have advantage] +2. **Where we lose:** [specific scenarios where competitors win] +3. **Underserved gap:** [unmet need no competitor addresses well] + +### Recommended Actions + +1. [action] -- addresses [gap/threat] +2. [action] -- leverages [strength] +3. [action] -- defends against [competitive move] + +--- +*Generated with [product-manager-skills](https://github.com/Digidai/product-manager-skills)* diff --git a/skills/product-manager-skills/templates/discovery-interview-plan.md b/skills/product-manager-skills/templates/discovery-interview-plan.md new file mode 100644 index 0000000..d46203a --- /dev/null +++ b/skills/product-manager-skills/templates/discovery-interview-plan.md @@ -0,0 +1,36 @@ +# Discovery Interview Plan + +## Research Goal +- [What you're trying to learn — not what you're trying to prove] + +## Target Segment +- **Who:** [Customer persona / segment] +- **Sample size:** [Number of interviews] +- **Access method:** [Recruited, cold outreach, existing users] + +## Methodology +- [JTBD switch interviews / problem validation / retention cohort / other] + +## Interview Framework + +### Opening (2 min) +- Context-setting, consent, no-wrong-answers framing + +### Core Questions (25 min) +1. [Question targeting primary research goal] +2. [Question exploring current behavior / workarounds] +3. [Question probing emotional drivers / frustrations] +4. [Question testing switching triggers or alternatives] +5. [Question validating willingness to change] + +### Closing (3 min) +- Anything else? Referral ask. Thank you. + +## Biases to Watch +- [Leading questions, confirmation bias, solution-first thinking] + +## Success Criteria +- [What "we learned enough" looks like — e.g., 3+ users describe same pain point] + +--- +*Generated with [product-manager-skills](https://github.com/Digidai/product-manager-skills)* diff --git a/skills/product-manager-skills/templates/epic-hypothesis.md b/skills/product-manager-skills/templates/epic-hypothesis.md new file mode 100644 index 0000000..d6af500 --- /dev/null +++ b/skills/product-manager-skills/templates/epic-hypothesis.md @@ -0,0 +1,21 @@ +### If/Then Hypothesis + +**If we** [action or solution on behalf of the target persona] +**for** [target persona] +**Then we will** [desirable outcome or job-to-be-done] + +### Tiny Acts of Discovery Experiments + +**We will test our assumption by:** +- [Experiment 1] +- [Experiment 2] + +### Validation Measures + +**We know our hypothesis is valid if within** [timeframe] +**we observe:** +- [Quantitative measurable outcome] +- [Qualitative measurable outcome] + +--- +*Generated with [product-manager-skills](https://github.com/Digidai/product-manager-skills)* diff --git a/skills/product-manager-skills/templates/lean-ux-canvas.md b/skills/product-manager-skills/templates/lean-ux-canvas.md new file mode 100644 index 0000000..71e6145 --- /dev/null +++ b/skills/product-manager-skills/templates/lean-ux-canvas.md @@ -0,0 +1,53 @@ +## Lean UX Canvas + +### 1. Business Problem + +[What business outcome are we trying to improve? State in terms of a measurable metric.] + +### 2. Business Outcomes + +- **Primary metric:** [metric + current value + target value + timeframe] +- **Leading indicator:** [metric that moves before the primary] + +### 3. Users & Customers + +- **Target user:** [specific role/persona with context] +- **Their current behavior:** [what they do today] +- **Underserved need:** [what's painful or missing] + +### 4. User Outcomes & Benefits + +If we solve this well, users will: +1. [behavior change or benefit] +2. [behavior change or benefit] + +We'll know they got value when: [observable signal] + +### 5. Solution Ideas + +| Idea | Addresses | Effort | Confidence | +|------|----------|--------|------------| +| [idea 1] | [which need] | S/M/L | High/Med/Low | +| [idea 2] | | | | +| [idea 3] | | | | + +### 6. Hypotheses + +**We believe that** [solution idea] +**for** [target user] +**will achieve** [user outcome] +**We will know this is true when** [measurable signal + threshold] + +### 7. Riskiest Assumption + +[The single assumption that, if wrong, invalidates the hypothesis] + +### 8. Experiment to Run + +- **Type:** [PoL probe / A-B test / prototype test / concierge] +- **What we'll do:** [specific steps] +- **Success criteria:** [quantitative threshold] +- **Timeline:** [duration] + +--- +*Generated with [product-manager-skills](https://github.com/Digidai/product-manager-skills)* diff --git a/skills/product-manager-skills/templates/opportunity-solution-tree.md b/skills/product-manager-skills/templates/opportunity-solution-tree.md new file mode 100644 index 0000000..415c051 --- /dev/null +++ b/skills/product-manager-skills/templates/opportunity-solution-tree.md @@ -0,0 +1,28 @@ +## Desired Outcome +- [Business or product metric to move] + +## Opportunities (Problems to Solve) +1. [Opportunity 1] +2. [Opportunity 2] +3. [Opportunity 3] + +## Solutions per Opportunity +**Opportunity 1 Solutions:** +- [Solution 1] +- [Solution 2] +- [Solution 3] + +**Opportunity 2 Solutions:** +- [Solution 1] +- [Solution 2] + +## Experiments (per solution) +- [Experiment for Solution 1] +- [Experiment for Solution 2] + +## POC Selection +- **Chosen solution:** [Solution] +- **Rationale:** [Feasibility, Impact, Market Fit] + +--- +*Generated with [product-manager-skills](https://github.com/Digidai/product-manager-skills)* diff --git a/skills/product-manager-skills/templates/positioning-statement.md b/skills/product-manager-skills/templates/positioning-statement.md new file mode 100644 index 0000000..2b4808d --- /dev/null +++ b/skills/product-manager-skills/templates/positioning-statement.md @@ -0,0 +1,18 @@ +## Positioning Statement + +### Value Proposition + +**For** [target customer/persona] +- **that need** [underserved need] +- [product or service name] +- **is a** [product category] +- **that** [benefit statement focused on outcomes] + +### Differentiation Statement + +- **Unlike** [primary competitor or alternative] +- [product or service name] +- **provides** [unique differentiation focused on outcomes] + +--- +*Generated with [product-manager-skills](https://github.com/Digidai/product-manager-skills)* diff --git a/skills/product-manager-skills/templates/prd.md b/skills/product-manager-skills/templates/prd.md new file mode 100644 index 0000000..693929e --- /dev/null +++ b/skills/product-manager-skills/templates/prd.md @@ -0,0 +1,51 @@ +# [Feature/Product Name] PRD + +## 1. Executive Summary +- One-paragraph overview (problem + solution + impact) + +## 2. Problem Statement +- Who has this problem? +- What is the problem? +- Why is it painful? +- Evidence (customer quotes, data, research) + +## 3. Target Users & Personas +- Primary persona(s) +- Secondary persona(s) +- Jobs-to-be-done + +## 4. Strategic Context +- Business goals (OKRs) +- Market opportunity (TAM/SAM/SOM) +- Competitive landscape +- Why now? + +## 5. Solution Overview +- High-level description +- User flows or wireframes +- Key features + +## 6. Success Metrics +- Primary metric (what we're optimizing for) +- Secondary metrics +- Targets (current → goal) + +## 7. User Stories & Requirements +- Epic hypothesis +- User stories with acceptance criteria +- Edge cases, constraints + +## 8. Out of Scope +- What we're NOT building (and why) + +## 9. Dependencies & Risks +- Technical dependencies +- External dependencies (integrations, partnerships) +- Risks and mitigations + +## 10. Open Questions +- Unresolved decisions +- Areas requiring discovery + +--- +*Generated with [product-manager-skills](https://github.com/Digidai/product-manager-skills)* diff --git a/skills/product-manager-skills/templates/press-release.md b/skills/product-manager-skills/templates/press-release.md new file mode 100644 index 0000000..4a009a4 --- /dev/null +++ b/skills/product-manager-skills/templates/press-release.md @@ -0,0 +1,26 @@ +**Headline:** +"[Product/Feature Name] by [Company] Aims to [Main Benefit/Goal]" + +**Dateline:** +"[City], [Country], [Date] —" + +**Introduction:** +Today, [Company], a [type of organization], announced [key news], a [brief description]. This [product/feature] is set to [main benefit], addressing [key customer problem]. + +**Problem Paragraph:** +[Describe the customer problem and its impact. Include a supporting data point.] + +**Solution Paragraph:** +[Describe how the product solves the problem in outcome terms]. "[Customer-focused quote]," said [Company leader]. + +**Additional Details:** +[Supporting benefits, integrations, or data points.] + +**Boilerplate:** +[Company], founded in [year], is a [type of company] known for [main products/services]. + +**Call to Action:** +For more information about [product/feature], visit [website] or contact [media contact]. + +--- +*Generated with [product-manager-skills](https://github.com/Digidai/product-manager-skills)* diff --git a/skills/product-manager-skills/templates/problem-statement.md b/skills/product-manager-skills/templates/problem-statement.md new file mode 100644 index 0000000..770cad4 --- /dev/null +++ b/skills/product-manager-skills/templates/problem-statement.md @@ -0,0 +1,29 @@ +## Problem Framing Narrative + +**I am:** [Key persona with 3-4 characteristics] +- [Pain point / characteristic 1] +- [Pain point / characteristic 2] +- [Pain point / characteristic 3] + +**Trying to:** +- [Desired outcomes the persona cares most about] + +**But:** +- [Barrier 1] +- [Barrier 2] +- [Barrier 3] + +**Because:** +- [Root cause, stated empathetically] + +**Which makes me feel:** +- [Emotions from the persona's perspective] + +## Context & Constraints +- [Geographic, technological, time-based, or demographic factors] + +## Final Problem Statement +- [Single, concise, empathetic summary sentence] + +--- +*Generated with [product-manager-skills](https://github.com/Digidai/product-manager-skills)* diff --git a/skills/product-manager-skills/templates/roadmap-plan.md b/skills/product-manager-skills/templates/roadmap-plan.md new file mode 100644 index 0000000..e9d5105 --- /dev/null +++ b/skills/product-manager-skills/templates/roadmap-plan.md @@ -0,0 +1,26 @@ +# Product Roadmap + +## Strategy Context +- [Business goals / OKRs] +- [Customer problems] +- [Constraints / dependencies] + +## Roadmap (Now / Next / Later) + +| Stage | Initiative | Outcome | Metric | Notes | +|---|---|---|---|---| +| Now | [Initiative] | [Outcome] | [Metric] | [Notes] | +| Next | [Initiative] | [Outcome] | [Metric] | [Notes] | +| Later | [Initiative] | [Outcome] | [Metric] | [Notes] | + +## Sequencing (Optional) +- Q1: [Initiatives] +- Q2: [Initiatives] +- Q3: [Initiatives] + +## Risks & Dependencies +- [Risk 1] +- [Dependency 1] + +--- +*Generated with [product-manager-skills](https://github.com/Digidai/product-manager-skills)* diff --git a/skills/product-manager-skills/templates/user-story.md b/skills/product-manager-skills/templates/user-story.md new file mode 100644 index 0000000..d2cb372 --- /dev/null +++ b/skills/product-manager-skills/templates/user-story.md @@ -0,0 +1,20 @@ +### User Story [ID]: + +- **Summary:** [Brief, memorable title focused on user value] + +#### Use Case: +- **As a** [user name / persona / role] +- **I want to** [action the user takes] +- **so that** [desired outcome for the user] + +#### Acceptance Criteria: +- **Scenario:** [Brief, human-readable scenario describing value] +- **Given:** [Initial context or precondition] +- **and Given:** [Additional context or preconditions] +- **When:** [Event that triggers the action] +- **Then:** [Expected outcome aligned to "so that"] + + + +--- +*Generated with [product-manager-skills](https://github.com/Digidai/product-manager-skills)* diff --git a/skills/product-manager-toolkit/SKILL.md b/skills/product-manager-toolkit/SKILL.md new file mode 100644 index 0000000..47747df --- /dev/null +++ b/skills/product-manager-toolkit/SKILL.md @@ -0,0 +1,352 @@ +--- +name: "product-manager-toolkit" +description: Comprehensive toolkit for product managers including RICE prioritization, customer interview analysis, PRD templates, discovery frameworks, and go-to-market strategies. Use for feature prioritization, user research synthesis, requirement documentation, and product strategy development. +--- + +# Product Manager Toolkit + +Essential tools and frameworks for modern product management, from discovery to delivery. + +--- + +## Table of Contents + +- [Quick Start](#quick-start) +- [Core Workflows](#core-workflows) + - [Feature Prioritization](#feature-prioritization-process) + - [Customer Discovery](#customer-discovery-process) + - [PRD Development](#prd-development-process) +- [Tools Reference](#tools-reference) + - [RICE Prioritizer](#rice-prioritizer) + - [Customer Interview Analyzer](#customer-interview-analyzer) +- [Input/Output Examples](#inputoutput-examples) +- [Integration Points](#integration-points) +- [Common Pitfalls](#common-pitfalls-to-avoid) + +--- + +## Quick Start + +### For Feature Prioritization +```bash +# Create sample data file +python scripts/rice_prioritizer.py sample + +# Run prioritization with team capacity +python scripts/rice_prioritizer.py sample_features.csv --capacity 15 +``` + +### For Interview Analysis +```bash +python scripts/customer_interview_analyzer.py interview_transcript.txt +``` + +### For PRD Creation +1. Choose template from `references/prd_templates.md` +2. Fill sections based on discovery work +3. Review with engineering for feasibility +4. Version control in project management tool + +--- + +## Core Workflows + +### Feature Prioritization Process + +``` +Gather → Score → Analyze → Plan → Validate → Execute +``` + +#### Step 1: Gather Feature Requests +- Customer feedback (support tickets, interviews) +- Sales requests (CRM pipeline blockers) +- Technical debt (engineering input) +- Strategic initiatives (leadership goals) + +#### Step 2: Score with RICE +```bash +# Input: CSV with features +python scripts/rice_prioritizer.py features.csv --capacity 20 +``` + +See `references/frameworks.md` for RICE formula and scoring guidelines. + +#### Step 3: Analyze Portfolio +Review the tool output for: +- Quick wins vs big bets distribution +- Effort concentration (avoid all XL projects) +- Strategic alignment gaps + +#### Step 4: Generate Roadmap +- Quarterly capacity allocation +- Dependency identification +- Stakeholder communication plan + +#### Step 5: Validate Results +**Before finalizing the roadmap:** +- [ ] Compare top priorities against strategic goals +- [ ] Run sensitivity analysis (what if estimates are wrong by 2x?) +- [ ] Review with key stakeholders for blind spots +- [ ] Check for missing dependencies between features +- [ ] Validate effort estimates with engineering + +#### Step 6: Execute and Iterate +- Share roadmap with team +- Track actual vs estimated effort +- Revisit priorities quarterly +- Update RICE inputs based on learnings + +--- + +### Customer Discovery Process + +``` +Plan → Recruit → Interview → Analyze → Synthesize → Validate +``` + +#### Step 1: Plan Research +- Define research questions +- Identify target segments +- Create interview script (see `references/frameworks.md`) + +#### Step 2: Recruit Participants +- 5-8 interviews per segment +- Mix of power users and churned users +- Incentivize appropriately + +#### Step 3: Conduct Interviews +- Use semi-structured format +- Focus on problems, not solutions +- Record with permission +- Take minimal notes during interview + +#### Step 4: Analyze Insights +```bash +python scripts/customer_interview_analyzer.py transcript.txt +``` + +Extracts: +- Pain points with severity +- Feature requests with priority +- Jobs to be done patterns +- Sentiment and key themes +- Notable quotes + +#### Step 5: Synthesize Findings +- Group similar pain points across interviews +- Identify patterns (3+ mentions = pattern) +- Map to opportunity areas using Opportunity Solution Tree +- Prioritize opportunities by frequency and severity + +#### Step 6: Validate Solutions +**Before building:** +- [ ] Create solution hypotheses (see `references/frameworks.md`) +- [ ] Test with low-fidelity prototypes +- [ ] Measure actual behavior vs stated preference +- [ ] Iterate based on feedback +- [ ] Document learnings for future research + +--- + +### PRD Development Process + +``` +Scope → Draft → Review → Refine → Approve → Track +``` + +#### Step 1: Choose Template +Select from `references/prd_templates.md`: + +| Template | Use Case | Timeline | +|----------|----------|----------| +| Standard PRD | Complex features, cross-team | 6-8 weeks | +| One-Page PRD | Simple features, single team | 2-4 weeks | +| Feature Brief | Exploration phase | 1 week | +| Agile Epic | Sprint-based delivery | Ongoing | + +#### Step 2: Draft Content +- Lead with problem statement +- Define success metrics upfront +- Explicitly state out-of-scope items +- Include wireframes or mockups + +#### Step 3: Review Cycle +- Engineering: feasibility and effort +- Design: user experience gaps +- Sales: market validation +- Support: operational impact + +#### Step 4: Refine Based on Feedback +- Address technical constraints +- Adjust scope to fit timeline +- Document trade-off decisions + +#### Step 5: Approval and Kickoff +- Stakeholder sign-off +- Sprint planning integration +- Communication to broader team + +#### Step 6: Track Execution +**After launch:** +- [ ] Compare actual metrics vs targets +- [ ] Conduct user feedback sessions +- [ ] Document what worked and what didn't +- [ ] Update estimation accuracy data +- [ ] Share learnings with team + +--- + +## Tools Reference + +### RICE Prioritizer + +Advanced RICE framework implementation with portfolio analysis. + +**Features:** +- RICE score calculation with configurable weights +- Portfolio balance analysis (quick wins vs big bets) +- Quarterly roadmap generation based on capacity +- Multiple output formats (text, JSON, CSV) + +**CSV Input Format:** +```csv +name,reach,impact,confidence,effort,description +User Dashboard Redesign,5000,high,high,l,Complete redesign +Mobile Push Notifications,10000,massive,medium,m,Add push support +Dark Mode,8000,medium,high,s,Dark theme option +``` + +**Commands:** +```bash +# Create sample data +python scripts/rice_prioritizer.py sample + +# Run with default capacity (10 person-months) +python scripts/rice_prioritizer.py features.csv + +# Custom capacity +python scripts/rice_prioritizer.py features.csv --capacity 20 + +# JSON output for integration +python scripts/rice_prioritizer.py features.csv --output json + +# CSV output for spreadsheets +python scripts/rice_prioritizer.py features.csv --output csv +``` + +--- + +### Customer Interview Analyzer + +NLP-based interview analysis for extracting actionable insights. + +**Capabilities:** +- Pain point extraction with severity assessment +- Feature request identification and classification +- Jobs-to-be-done pattern recognition +- Sentiment analysis per section +- Theme and quote extraction +- Competitor mention detection + +**Commands:** +```bash +# Analyze interview transcript +python scripts/customer_interview_analyzer.py interview.txt + +# JSON output for aggregation +python scripts/customer_interview_analyzer.py interview.txt json +``` + +--- + +## Input/Output Examples +→ See references/input-output-examples.md for details + +## Integration Points + +Compatible tools and platforms: + +| Category | Platforms | +|----------|-----------| +| **Analytics** | Amplitude, Mixpanel, Google Analytics | +| **Roadmapping** | ProductBoard, Aha!, Roadmunk, Productplan | +| **Design** | Figma, Sketch, Miro | +| **Development** | Jira, Linear, GitHub, Asana | +| **Research** | Dovetail, UserVoice, Pendo, Maze | +| **Communication** | Slack, Notion, Confluence | + +**JSON export enables integration with most tools:** +```bash +# Export for Jira import +python scripts/rice_prioritizer.py features.csv --output json > priorities.json + +# Export for dashboard +python scripts/customer_interview_analyzer.py interview.txt json > insights.json +``` + +--- + +## Common Pitfalls to Avoid + +| Pitfall | Description | Prevention | +|---------|-------------|------------| +| **Solution-First** | Jumping to features before understanding problems | Start every PRD with problem statement | +| **Analysis Paralysis** | Over-researching without shipping | Set time-boxes for research phases | +| **Feature Factory** | Shipping features without measuring impact | Define success metrics before building | +| **Ignoring Tech Debt** | Not allocating time for platform health | Reserve 20% capacity for maintenance | +| **Stakeholder Surprise** | Not communicating early and often | Weekly async updates, monthly demos | +| **Metric Theater** | Optimizing vanity metrics over real value | Tie metrics to user value delivered | + +--- + +## Best Practices + +**Writing Great PRDs:** +- Start with the problem, not the solution +- Include clear success metrics upfront +- Explicitly state what's out of scope +- Use visuals (wireframes, flows, diagrams) +- Keep technical details in appendix +- Version control all changes + +**Effective Prioritization:** +- Mix quick wins with strategic bets +- Consider opportunity cost of delays +- Account for dependencies between features +- Buffer 20% for unexpected work +- Revisit priorities quarterly +- Communicate decisions with context + +**Customer Discovery:** +- Ask "why" five times to find root cause +- Focus on past behavior, not future intentions +- Avoid leading questions ("Wouldn't you love...") +- Interview in the user's natural environment +- Watch for emotional reactions (pain = opportunity) +- Validate qualitative with quantitative data + +--- + +## Quick Reference + +```bash +# Prioritization +python scripts/rice_prioritizer.py features.csv --capacity 15 + +# Interview Analysis +python scripts/customer_interview_analyzer.py interview.txt + +# Generate sample data +python scripts/rice_prioritizer.py sample + +# JSON outputs +python scripts/rice_prioritizer.py features.csv --output json +python scripts/customer_interview_analyzer.py interview.txt json +``` + +--- + +## Reference Documents + +- `references/prd_templates.md` - PRD templates for different contexts +- `references/frameworks.md` - Detailed framework documentation (RICE, MoSCoW, Kano, JTBD, etc.) diff --git a/skills/product-manager-toolkit/_meta.json b/skills/product-manager-toolkit/_meta.json new file mode 100644 index 0000000..5255488 --- /dev/null +++ b/skills/product-manager-toolkit/_meta.json @@ -0,0 +1,6 @@ +{ + "ownerId": "kn7f2gr00xy51fj1nx2y64ckjs800mhn", + "slug": "product-manager-toolkit", + "version": "2.1.1", + "publishedAt": 1773070355903 +} \ No newline at end of file diff --git a/skills/product-manager-toolkit/references/frameworks.md b/skills/product-manager-toolkit/references/frameworks.md new file mode 100644 index 0000000..24c250d --- /dev/null +++ b/skills/product-manager-toolkit/references/frameworks.md @@ -0,0 +1,559 @@ +# Product Management Frameworks + +Comprehensive reference for prioritization, discovery, and measurement frameworks. + +--- + +## Table of Contents + +- [Prioritization Frameworks](#prioritization-frameworks) + - [RICE Framework](#rice-framework) + - [Value vs Effort Matrix](#value-vs-effort-matrix) + - [MoSCoW Method](#moscow-method) + - [ICE Scoring](#ice-scoring) + - [Kano Model](#kano-model) +- [Discovery Frameworks](#discovery-frameworks) + - [Customer Interview Guide](#customer-interview-guide) + - [Hypothesis Template](#hypothesis-template) + - [Opportunity Solution Tree](#opportunity-solution-tree) + - [Jobs to Be Done](#jobs-to-be-done) +- [Metrics Frameworks](#metrics-frameworks) + - [North Star Metric](#north-star-metric-framework) + - [HEART Framework](#heart-framework) + - [Funnel Analysis](#funnel-analysis-template) + - [Feature Success Metrics](#feature-success-metrics) +- [Strategic Frameworks](#strategic-frameworks) + - [Product Vision Template](#product-vision-template) + - [Competitive Analysis](#competitive-analysis-framework) + - [Go-to-Market Checklist](#go-to-market-checklist) + +--- + +## Prioritization Frameworks + +### RICE Framework + +**Formula:** +``` +RICE Score = (Reach × Impact × Confidence) / Effort +``` + +**Components:** + +| Component | Description | Values | +|-----------|-------------|--------| +| **Reach** | Users affected per quarter | Numeric count (e.g., 5000) | +| **Impact** | Effect on each user | massive=3x, high=2x, medium=1x, low=0.5x, minimal=0.25x | +| **Confidence** | Certainty in estimates | high=100%, medium=80%, low=50% | +| **Effort** | Person-months required | xl=13, l=8, m=5, s=3, xs=1 | + +**Example Calculation:** +``` +Feature: Mobile Push Notifications +Reach: 10,000 users +Impact: massive (3x) +Confidence: medium (80%) +Effort: medium (5 person-months) + +RICE = (10,000 × 3 × 0.8) / 5 = 4,800 +``` + +**Interpretation Guidelines:** +- **1000+**: High priority - strong candidates for next quarter +- **500-999**: Medium priority - consider for roadmap +- **100-499**: Low priority - keep in backlog +- **<100**: Deprioritize - requires new data to reconsider + +**When to Use RICE:** +- Quarterly roadmap planning +- Comparing features across different product areas +- Communicating priorities to stakeholders +- Resolving prioritization debates with data + +**RICE Limitations:** +- Requires reasonable estimates (garbage in, garbage out) +- Doesn't account for dependencies +- May undervalue platform investments +- Reach estimates can be gaming-prone + +--- + +### Value vs Effort Matrix + +``` + Low Effort High Effort + +--------------+------------------+ + High Value | QUICK WINS | BIG BETS | + | [Do First] | [Strategic] | + +--------------+------------------+ + Low Value | FILL-INS | TIME SINKS | + | [Maybe] | [Avoid] | + +--------------+------------------+ +``` + +**Quadrant Definitions:** + +| Quadrant | Characteristics | Action | +|----------|-----------------|--------| +| **Quick Wins** | High impact, low effort | Prioritize immediately | +| **Big Bets** | High impact, high effort | Plan strategically, validate ROI | +| **Fill-Ins** | Low impact, low effort | Use to fill sprint gaps | +| **Time Sinks** | Low impact, high effort | Avoid unless required | + +**Portfolio Balance:** +- Ideal mix: 40% Quick Wins, 30% Big Bets, 20% Fill-Ins, 10% Buffer +- Review balance quarterly +- Adjust based on team morale and strategic goals + +--- + +### MoSCoW Method + +| Category | Definition | Sprint Allocation | +|----------|------------|-------------------| +| **Must Have** | Critical for launch; product fails without it | 60% of capacity | +| **Should Have** | Important but workarounds exist | 20% of capacity | +| **Could Have** | Desirable enhancements | 10% of capacity | +| **Won't Have** | Explicitly out of scope (this release) | 0% - documented | + +**Decision Criteria for "Must Have":** +- Regulatory/legal requirement +- Core user job cannot be completed without it +- Explicitly promised to customers +- Security or data integrity requirement + +**Common Mistakes:** +- Everything becomes "Must Have" (scope creep) +- Not documenting "Won't Have" items +- Treating "Should Have" as optional (they're important) +- Forgetting to revisit for next release + +--- + +### ICE Scoring + +**Formula:** +``` +ICE Score = (Impact + Confidence + Ease) / 3 +``` + +| Component | Scale | Description | +|-----------|-------|-------------| +| **Impact** | 1-10 | Expected effect on key metric | +| **Confidence** | 1-10 | How sure are you about impact? | +| **Ease** | 1-10 | How easy to implement? | + +**When to Use ICE vs RICE:** +- ICE: Early-stage exploration, quick estimates +- RICE: Quarterly planning, cross-team prioritization + +--- + +### Kano Model + +Categories of feature satisfaction: + +| Type | Absent | Present | Priority | +|------|--------|---------|----------| +| **Basic (Must-Be)** | Dissatisfied | Neutral | High - table stakes | +| **Performance (Linear)** | Neutral | Satisfied proportionally | Medium - differentiation | +| **Excitement (Delighter)** | Neutral | Very satisfied | Strategic - competitive edge | +| **Indifferent** | Neutral | Neutral | Low - skip unless cheap | +| **Reverse** | Satisfied | Dissatisfied | Avoid - remove if exists | + +**Feature Classification Questions:** +1. How would you feel if the product HAS this feature? +2. How would you feel if the product DOES NOT have this feature? + +--- + +## Discovery Frameworks + +### Customer Interview Guide + +**Structure (35 minutes total):** + +``` +1. CONTEXT QUESTIONS (5 min) + └── Build rapport, understand role + +2. PROBLEM EXPLORATION (15 min) + └── Dig into pain points + +3. SOLUTION VALIDATION (10 min) + └── Test concepts if applicable + +4. WRAP-UP (5 min) + └── Referrals, follow-up +``` + +**Detailed Script:** + +#### Phase 1: Context (5 min) +``` +"Thanks for taking the time. Before we dive in..." + +- What's your role and how long have you been in it? +- Walk me through a typical day/week. +- What tools do you use for [relevant task]? +``` + +#### Phase 2: Problem Exploration (15 min) +``` +"I'd love to understand the challenges you face with [area]..." + +- What's the hardest part about [task]? +- Can you tell me about the last time you struggled with this? +- What did you do? What happened? +- How often does this happen? +- What does it cost you (time, money, frustration)? +- What have you tried to solve it? +- Why didn't those solutions work? +``` + +#### Phase 3: Solution Validation (10 min) +``` +"Based on what you've shared, I'd like to get your reaction to an idea..." + +[Show prototype/concept - keep it rough to invite honest feedback] + +- What's your initial reaction? +- How does this compare to what you do today? +- What would prevent you from using this? +- How much would this be worth to you? +- Who else would need to approve this purchase? +``` + +#### Phase 4: Wrap-up (5 min) +``` +"This has been incredibly helpful..." + +- Anything else I should have asked? +- Who else should I talk to about this? +- Can I follow up if I have more questions? +``` + +**Interview Best Practices:** +- Never ask "would you use this?" (people lie about future behavior) +- Ask about past behavior: "Tell me about the last time..." +- Embrace silence - count to 7 before filling gaps +- Watch for emotional reactions (pain = opportunity) +- Record with permission; take minimal notes during + +--- + +### Hypothesis Template + +**Format:** +``` +We believe that [building this feature/making this change] +For [target user segment] +Will [achieve this measurable outcome] + +We'll know we're right when [specific metric moves by X%] + +We'll know we're wrong when [falsification criteria] +``` + +**Example:** +``` +We believe that adding saved payment methods +For returning customers +Will increase checkout completion rate + +We'll know we're right when checkout completion increases by 15% + +We'll know we're wrong when completion rate stays flat after 2 weeks +or saved payment adoption is < 20% +``` + +**Hypothesis Quality Checklist:** +- [ ] Specific user segment defined +- [ ] Measurable outcome (number, not "better") +- [ ] Timeframe for measurement +- [ ] Clear falsification criteria +- [ ] Based on evidence (interviews, data) + +--- + +### Opportunity Solution Tree + +**Structure:** +``` +[DESIRED OUTCOME] + │ + ├── Opportunity 1: [User problem/need] + │ ├── Solution A + │ ├── Solution B + │ └── Experiment: [Test to validate] + │ + ├── Opportunity 2: [User problem/need] + │ ├── Solution C + │ └── Solution D + │ + └── Opportunity 3: [User problem/need] + └── Solution E +``` + +**Example:** +``` +[Increase monthly active users by 20%] + │ + ├── Users forget to return + │ ├── Weekly email digest + │ ├── Mobile push notifications + │ └── Test: A/B email frequency + │ + ├── New users don't find value quickly + │ ├── Improved onboarding wizard + │ └── Personalized first experience + │ + └── Users churn after free trial + ├── Extended trial for engaged users + └── Friction audit of upgrade flow +``` + +**Process:** +1. Start with measurable outcome (not solution) +2. Map opportunities from user research +3. Generate multiple solutions per opportunity +4. Design small experiments to validate +5. Prioritize based on learning potential + +--- + +### Jobs to Be Done + +**JTBD Statement Format:** +``` +When [situation/trigger] +I want to [motivation/job] +So I can [expected outcome] +``` + +**Example:** +``` +When I'm running late for a meeting +I want to notify attendees quickly +So I can set appropriate expectations and reduce anxiety +``` + +**Force Diagram:** +``` + ┌─────────────────┐ + Push from │ │ Pull toward + current ──────>│ SWITCH │<────── new + solution │ DECISION │ solution + │ │ + └─────────────────┘ + ^ ^ + | | + Anxiety of | | Habit of + change ──────┘ └────── status quo +``` + +**Interview Questions for JTBD:** +- When did you first realize you needed something like this? +- What were you using before? Why did you switch? +- What almost prevented you from switching? +- What would make you go back to the old way? + +--- + +## Metrics Frameworks + +### North Star Metric Framework + +**Criteria for a Good NSM:** +1. **Measures value delivery**: Captures what users get from product +2. **Leading indicator**: Predicts business success +3. **Actionable**: Teams can influence it +4. **Measurable**: Trackable on regular cadence + +**Examples by Business Type:** + +| Business | North Star Metric | Why | +|----------|-------------------|-----| +| Spotify | Time spent listening | Measures engagement value | +| Airbnb | Nights booked | Core transaction metric | +| Slack | Messages sent in channels | Team collaboration value | +| Dropbox | Files stored/synced | Storage utility delivered | +| Netflix | Hours watched | Entertainment value | + +**Supporting Metrics Structure:** +``` +[NORTH STAR METRIC] + │ + ├── Breadth: How many users? + ├── Depth: How engaged are they? + └── Frequency: How often do they engage? +``` + +--- + +### HEART Framework + +| Metric | Definition | Example Signals | +|--------|------------|-----------------| +| **Happiness** | Subjective satisfaction | NPS, CSAT, survey scores | +| **Engagement** | Depth of involvement | Session length, actions/session | +| **Adoption** | New user behavior | Signups, feature activation | +| **Retention** | Continued usage | D7/D30 retention, churn rate | +| **Task Success** | Efficiency & effectiveness | Completion rate, time-on-task, errors | + +**Goals-Signals-Metrics Process:** +1. **Goal**: What user behavior indicates success? +2. **Signal**: How would success manifest in data? +3. **Metric**: How do we measure the signal? + +**Example:** +``` +Feature: New checkout flow + +Goal: Users complete purchases faster +Signal: Reduced time in checkout, fewer drop-offs +Metrics: + - Median checkout time (target: <2 min) + - Checkout completion rate (target: 85%) + - Error rate (target: <2%) +``` + +--- + +### Funnel Analysis Template + +**Standard Funnel:** +``` +Acquisition → Activation → Retention → Revenue → Referral + │ │ │ │ │ + │ │ │ │ │ + How do First Come back Pay for Tell + they find "aha" regularly value others + you? moment +``` + +**Metrics per Stage:** + +| Stage | Key Metrics | Typical Benchmark | +|-------|-------------|-------------------| +| **Acquisition** | Visitors, CAC, channel mix | Varies by channel | +| **Activation** | Signup rate, onboarding completion | 20-30% visitor→signup | +| **Retention** | D1/D7/D30 retention, churn | D1: 40%, D7: 20%, D30: 10% | +| **Revenue** | Conversion rate, ARPU, LTV | 2-5% free→paid | +| **Referral** | NPS, viral coefficient, referrals/user | NPS > 50 is excellent | + +**Analysis Framework:** +1. Map current conversion rates at each stage +2. Identify biggest drop-off point +3. Qualitative research: Why are users leaving? +4. Hypothesis: What would improve conversion? +5. Test and measure + +--- + +### Feature Success Metrics + +| Metric | Definition | Target Range | +|--------|------------|--------------| +| **Adoption** | % users who try feature | 30-50% within 30 days | +| **Activation** | % who complete core action | 60-80% of adopters | +| **Frequency** | Uses per user per time | Weekly for engagement features | +| **Depth** | % of feature capability used | 50%+ of core functionality | +| **Retention** | Continued usage over time | 70%+ at 30 days | +| **Satisfaction** | Feature-specific NPS/rating | NPS > 30, Rating > 4.0 | + +**Measurement Cadence:** +- **Week 1**: Adoption and initial activation +- **Week 4**: Retention and depth +- **Week 8**: Long-term satisfaction and business impact + +--- + +## Strategic Frameworks + +### Product Vision Template + +**Format:** +``` +FOR [target customer] +WHO [statement of need or opportunity] +THE [product name] IS A [product category] +THAT [key benefit, compelling reason to use] +UNLIKE [primary competitive alternative] +OUR PRODUCT [statement of primary differentiation] +``` + +**Example:** +``` +FOR busy professionals +WHO need to stay informed without information overload +Briefme IS A personalized news digest +THAT delivers only relevant stories in 5 minutes +UNLIKE traditional news apps that require active browsing +OUR PRODUCT learns your interests and filters automatically +``` + +--- + +### Competitive Analysis Framework + +| Dimension | Us | Competitor A | Competitor B | +|-----------|----|--------------|--------------| +| **Target User** | | | | +| **Core Value Prop** | | | | +| **Pricing** | | | | +| **Key Features** | | | | +| **Strengths** | | | | +| **Weaknesses** | | | | +| **Market Position** | | | | + +**Strategic Questions:** +1. Where do we have parity? (table stakes) +2. Where do we differentiate? (competitive advantage) +3. Where are we behind? (gaps to close or ignore) +4. What can only we do? (unique capabilities) + +--- + +### Go-to-Market Checklist + +**Pre-Launch (4 weeks before):** +- [ ] Success metrics defined and instrumented +- [ ] Launch/rollback criteria established +- [ ] Support documentation ready +- [ ] Sales enablement materials complete +- [ ] Marketing assets prepared +- [ ] Beta feedback incorporated + +**Launch Week:** +- [ ] Staged rollout plan (1% → 10% → 50% → 100%) +- [ ] Monitoring dashboards live +- [ ] On-call rotation scheduled +- [ ] Communications ready (in-app, email, blog) +- [ ] Support team briefed + +**Post-Launch (2 weeks after):** +- [ ] Metrics review vs. targets +- [ ] User feedback synthesized +- [ ] Bug/issue triage complete +- [ ] Iteration plan defined +- [ ] Stakeholder update sent + +--- + +## Framework Selection Guide + +| Situation | Recommended Framework | +|-----------|----------------------| +| Quarterly roadmap planning | RICE + Portfolio Matrix | +| Sprint-level prioritization | MoSCoW | +| Quick feature comparison | ICE | +| Understanding user satisfaction | Kano | +| User research synthesis | JTBD + Opportunity Tree | +| Feature experiment design | Hypothesis Template | +| Success measurement | HEART + Feature Metrics | +| Strategy communication | North Star + Vision | + +--- + +*Last Updated: January 2025* diff --git a/skills/product-manager-toolkit/references/input-output-examples.md b/skills/product-manager-toolkit/references/input-output-examples.md new file mode 100644 index 0000000..4e95abf --- /dev/null +++ b/skills/product-manager-toolkit/references/input-output-examples.md @@ -0,0 +1,156 @@ +# product-manager-toolkit reference + +## Input/Output Examples + +### RICE Prioritizer Example + +**Input (features.csv):** +```csv +name,reach,impact,confidence,effort +Onboarding Flow,20000,massive,high,s +Search Improvements,15000,high,high,m +Social Login,12000,high,medium,m +Push Notifications,10000,massive,medium,m +Dark Mode,8000,medium,high,s +``` + +**Command:** +```bash +python scripts/rice_prioritizer.py features.csv --capacity 15 +``` + +**Output:** +``` +============================================================ +RICE PRIORITIZATION RESULTS +============================================================ + +📊 TOP PRIORITIZED FEATURES + +1. Onboarding Flow + RICE Score: 16000.0 + Reach: 20000 | Impact: massive | Confidence: high | Effort: s + +2. Search Improvements + RICE Score: 4800.0 + Reach: 15000 | Impact: high | Confidence: high | Effort: m + +3. Social Login + RICE Score: 3072.0 + Reach: 12000 | Impact: high | Confidence: medium | Effort: m + +4. Push Notifications + RICE Score: 3840.0 + Reach: 10000 | Impact: massive | Confidence: medium | Effort: m + +5. Dark Mode + RICE Score: 2133.33 + Reach: 8000 | Impact: medium | Confidence: high | Effort: s + +📈 PORTFOLIO ANALYSIS + +Total Features: 5 +Total Effort: 19 person-months +Total Reach: 65,000 users +Average RICE Score: 5969.07 + +🎯 Quick Wins: 2 features + • Onboarding Flow (RICE: 16000.0) + • Dark Mode (RICE: 2133.33) + +🚀 Big Bets: 0 features + +📅 SUGGESTED ROADMAP + +Q1 - Capacity: 11/15 person-months + • Onboarding Flow (RICE: 16000.0) + • Search Improvements (RICE: 4800.0) + • Dark Mode (RICE: 2133.33) + +Q2 - Capacity: 10/15 person-months + • Push Notifications (RICE: 3840.0) + • Social Login (RICE: 3072.0) +``` + +--- + +### Customer Interview Analyzer Example + +**Input (interview.txt):** +``` +Customer: Jane, Enterprise PM at TechCorp +Date: 2024-01-15 + +Interviewer: What's the hardest part of your current workflow? + +Jane: The biggest frustration is the lack of real-time collaboration. +When I'm working on a PRD, I have to constantly ping my team on Slack +to get updates. It's really frustrating to wait for responses, +especially when we're on a tight deadline. + +I've tried using Google Docs for collaboration, but it doesn't +integrate with our roadmap tools. I'd pay extra for something that +just worked seamlessly. + +Interviewer: How often does this happen? + +Jane: Literally every day. I probably waste 30 minutes just on +back-and-forth messages. It's my biggest pain point right now. +``` + +**Command:** +```bash +python scripts/customer_interview_analyzer.py interview.txt +``` + +**Output:** +``` +============================================================ +CUSTOMER INTERVIEW ANALYSIS +============================================================ + +📋 INTERVIEW METADATA +Segments found: 1 +Lines analyzed: 15 + +😟 PAIN POINTS (3 found) + +1. [HIGH] Lack of real-time collaboration + "I have to constantly ping my team on Slack to get updates" + +2. [MEDIUM] Tool integration gaps + "Google Docs...doesn't integrate with our roadmap tools" + +3. [HIGH] Time wasted on communication + "waste 30 minutes just on back-and-forth messages" + +💡 FEATURE REQUESTS (2 found) + +1. Real-time collaboration - Priority: High +2. Seamless tool integration - Priority: Medium + +🎯 JOBS TO BE DONE + +When working on PRDs with tight deadlines +I want real-time visibility into team updates +So I can avoid wasted time on status checks + +📊 SENTIMENT ANALYSIS + +Overall: Negative (pain-focused interview) +Key emotions: Frustration, Time pressure + +💬 KEY QUOTES + +• "It's really frustrating to wait for responses" +• "I'd pay extra for something that just worked seamlessly" +• "It's my biggest pain point right now" + +🏷️ THEMES + +- Collaboration friction +- Tool fragmentation +- Time efficiency +``` + +--- diff --git a/skills/product-manager-toolkit/references/prd_templates.md b/skills/product-manager-toolkit/references/prd_templates.md new file mode 100644 index 0000000..fe8cc15 --- /dev/null +++ b/skills/product-manager-toolkit/references/prd_templates.md @@ -0,0 +1,317 @@ +# Product Requirements Document (PRD) Templates + +## Standard PRD Template + +### 1. Executive Summary +**Purpose**: One-page overview for executives and stakeholders + +#### Components: +- **Problem Statement** (2-3 sentences) +- **Proposed Solution** (2-3 sentences) +- **Business Impact** (3 bullet points) +- **Timeline** (High-level milestones) +- **Resources Required** (Team size and budget) +- **Success Metrics** (3-5 KPIs) + +### 2. Problem Definition + +#### 2.1 Customer Problem +- **Who**: Target user persona(s) +- **What**: Specific problem or need +- **When**: Context and frequency +- **Where**: Environment and touchpoints +- **Why**: Root cause analysis +- **Impact**: Cost of not solving + +#### 2.2 Market Opportunity +- **Market Size**: TAM, SAM, SOM +- **Growth Rate**: Annual growth percentage +- **Competition**: Current solutions and gaps +- **Timing**: Why now? + +#### 2.3 Business Case +- **Revenue Potential**: Projected impact +- **Cost Savings**: Efficiency gains +- **Strategic Value**: Alignment with company goals +- **Risk Assessment**: What if we don't do this? + +### 3. Solution Overview + +#### 3.1 Proposed Solution +- **High-Level Description**: What we're building +- **Key Capabilities**: Core functionality +- **User Journey**: End-to-end flow +- **Differentiation**: Unique value proposition + +#### 3.2 In Scope +- Feature 1: Description and priority +- Feature 2: Description and priority +- Feature 3: Description and priority + +#### 3.3 Out of Scope +- Explicitly what we're NOT doing +- Future considerations +- Dependencies on other teams + +#### 3.4 MVP Definition +- **Core Features**: Minimum viable feature set +- **Success Criteria**: Definition of "working" +- **Timeline**: MVP delivery date +- **Learning Goals**: What we want to validate + +### 4. User Stories & Requirements + +#### 4.1 User Stories +``` +As a [persona] +I want to [action] +So that [outcome/benefit] + +Acceptance Criteria: +- [ ] Criterion 1 +- [ ] Criterion 2 +- [ ] Criterion 3 +``` + +#### 4.2 Functional Requirements +| ID | Requirement | Priority | Notes | +|----|------------|----------|-------| +| FR1 | User can... | P0 | Critical for MVP | +| FR2 | System should... | P1 | Important | +| FR3 | Feature must... | P2 | Nice to have | + +#### 4.3 Non-Functional Requirements +- **Performance**: Response times, throughput +- **Scalability**: User/data growth targets +- **Security**: Authentication, authorization, data protection +- **Reliability**: Uptime targets, error rates +- **Usability**: Accessibility standards, device support +- **Compliance**: Regulatory requirements + +### 5. Design & User Experience + +#### 5.1 Design Principles +- Principle 1: Description +- Principle 2: Description +- Principle 3: Description + +#### 5.2 Wireframes/Mockups +- Link to Figma/Sketch files +- Key screens and flows +- Interaction patterns + +#### 5.3 Information Architecture +- Navigation structure +- Data organization +- Content hierarchy + +### 6. Technical Specifications + +#### 6.1 Architecture Overview +- System architecture diagram +- Technology stack +- Integration points +- Data flow + +#### 6.2 API Design +- Endpoints and methods +- Request/response formats +- Authentication approach +- Rate limiting + +#### 6.3 Database Design +- Data model +- Key entities and relationships +- Migration strategy + +#### 6.4 Security Considerations +- Authentication method +- Authorization model +- Data encryption +- PII handling + +### 7. Go-to-Market Strategy + +#### 7.1 Launch Plan +- **Soft Launch**: Beta users, timeline +- **Full Launch**: All users, timeline +- **Marketing**: Campaigns and channels +- **Support**: Documentation and training + +#### 7.2 Pricing Strategy +- Pricing model +- Competitive analysis +- Value proposition + +#### 7.3 Success Metrics +| Metric | Target | Measurement Method | +|--------|--------|-------------------| +| Adoption Rate | X% | Daily Active Users | +| User Satisfaction | X/10 | NPS Score | +| Revenue Impact | $X | Monthly Recurring Revenue | +| Performance | Dict: + """Analyze a single interview transcript""" + text_lower = text.lower() + sentences = self._split_sentences(text) + + analysis = { + 'pain_points': self._extract_pain_points(sentences), + 'delights': self._extract_delights(sentences), + 'feature_requests': self._extract_requests(sentences), + 'jobs_to_be_done': self._extract_jtbd(text_lower), + 'sentiment_score': self._calculate_sentiment(text_lower), + 'key_themes': self._extract_themes(text_lower), + 'quotes': self._extract_key_quotes(sentences), + 'metrics_mentioned': self._extract_metrics(text), + 'competitors_mentioned': self._extract_competitors(text) + } + + return analysis + + def _split_sentences(self, text: str) -> List[str]: + """Split text into sentences""" + # Simple sentence splitting + sentences = re.split(r'[.!?]+', text) + return [s.strip() for s in sentences if s.strip()] + + def _extract_pain_points(self, sentences: List[str]) -> List[Dict]: + """Extract pain points from sentences""" + pain_points = [] + + for sentence in sentences: + sentence_lower = sentence.lower() + for indicator in self.pain_indicators: + if indicator in sentence_lower: + # Extract context around the pain point + pain_points.append({ + 'quote': sentence, + 'indicator': indicator, + 'severity': self._assess_severity(sentence_lower) + }) + break + + return pain_points[:10] # Return top 10 + + def _extract_delights(self, sentences: List[str]) -> List[Dict]: + """Extract positive feedback""" + delights = [] + + for sentence in sentences: + sentence_lower = sentence.lower() + for indicator in self.delight_indicators: + if indicator in sentence_lower: + delights.append({ + 'quote': sentence, + 'indicator': indicator, + 'strength': self._assess_strength(sentence_lower) + }) + break + + return delights[:10] + + def _extract_requests(self, sentences: List[str]) -> List[Dict]: + """Extract feature requests and suggestions""" + requests = [] + + for sentence in sentences: + sentence_lower = sentence.lower() + for indicator in self.request_indicators: + if indicator in sentence_lower: + requests.append({ + 'quote': sentence, + 'type': self._classify_request(sentence_lower), + 'priority': self._assess_request_priority(sentence_lower) + }) + break + + return requests[:10] + + def _extract_jtbd(self, text: str) -> List[Dict]: + """Extract Jobs to Be Done patterns""" + jobs = [] + + for pattern in self.jtbd_patterns: + matches = re.findall(pattern, text, re.IGNORECASE) + for match in matches: + if isinstance(match, tuple): + job = ' → '.join(match) + else: + job = match + + jobs.append({ + 'job': job, + 'pattern': pattern.pattern if hasattr(pattern, 'pattern') else pattern + }) + + return jobs[:5] + + def _calculate_sentiment(self, text: str) -> Dict: + """Calculate overall sentiment of the interview""" + positive_count = sum(1 for ind in self.delight_indicators if ind in text) + negative_count = sum(1 for ind in self.pain_indicators if ind in text) + + total = positive_count + negative_count + if total == 0: + sentiment_score = 0 + else: + sentiment_score = (positive_count - negative_count) / total + + if sentiment_score > 0.3: + sentiment_label = 'positive' + elif sentiment_score < -0.3: + sentiment_label = 'negative' + else: + sentiment_label = 'neutral' + + return { + 'score': round(sentiment_score, 2), + 'label': sentiment_label, + 'positive_signals': positive_count, + 'negative_signals': negative_count + } + + def _extract_themes(self, text: str) -> List[str]: + """Extract key themes using word frequency""" + # Remove common words + stop_words = {'the', 'a', 'an', 'and', 'or', 'but', 'in', 'on', 'at', + 'to', 'for', 'of', 'with', 'by', 'from', 'as', 'is', + 'was', 'are', 'were', 'been', 'be', 'have', 'has', + 'had', 'do', 'does', 'did', 'will', 'would', 'could', + 'should', 'may', 'might', 'must', 'can', 'shall', + 'it', 'i', 'you', 'we', 'they', 'them', 'their'} + + # Extract meaningful words + words = re.findall(r'\b[a-z]{4,}\b', text) + meaningful_words = [w for w in words if w not in stop_words] + + # Count frequency + word_freq = Counter(meaningful_words) + + # Extract themes (top frequent meaningful words) + themes = [word for word, count in word_freq.most_common(10) if count >= 3] + + return themes + + def _extract_key_quotes(self, sentences: List[str]) -> List[str]: + """Extract the most insightful quotes""" + scored_sentences = [] + + for sentence in sentences: + if len(sentence) < 20 or len(sentence) > 200: + continue + + score = 0 + sentence_lower = sentence.lower() + + # Score based on insight indicators + if any(ind in sentence_lower for ind in self.pain_indicators): + score += 2 + if any(ind in sentence_lower for ind in self.request_indicators): + score += 2 + if 'because' in sentence_lower: + score += 1 + if 'but' in sentence_lower: + score += 1 + if '?' in sentence: + score += 1 + + if score > 0: + scored_sentences.append((score, sentence)) + + # Sort by score and return top quotes + scored_sentences.sort(reverse=True) + return [s[1] for s in scored_sentences[:5]] + + def _extract_metrics(self, text: str) -> List[str]: + """Extract any metrics or numbers mentioned""" + metrics = [] + + # Find percentages + percentages = re.findall(r'\d+%', text) + metrics.extend(percentages) + + # Find time metrics + time_metrics = re.findall(r'\d+\s*(?:hours?|minutes?|days?|weeks?|months?)', text, re.IGNORECASE) + metrics.extend(time_metrics) + + # Find money metrics + money_metrics = re.findall(r'\$[\d,]+', text) + metrics.extend(money_metrics) + + # Find general numbers with context + number_contexts = re.findall(r'(\d+)\s+(\w+)', text) + for num, context in number_contexts: + if context.lower() not in ['the', 'a', 'an', 'and', 'or', 'of']: + metrics.append(f"{num} {context}") + + return list(set(metrics))[:10] + + def _extract_competitors(self, text: str) -> List[str]: + """Extract competitor mentions""" + # Common competitor indicators + competitor_patterns = [ + r'(?:use|used|using|tried|trying|switch from|switched from|instead of)\s+(\w+)', + r'(\w+)\s+(?:is better|works better|is easier)', + r'compared to\s+(\w+)', + r'like\s+(\w+)', + r'similar to\s+(\w+)', + ] + + competitors = set() + for pattern in competitor_patterns: + matches = re.findall(pattern, text, re.IGNORECASE) + competitors.update(matches) + + # Filter out common words + common_words = {'this', 'that', 'it', 'them', 'other', 'another', 'something'} + competitors = [c for c in competitors if c.lower() not in common_words and len(c) > 2] + + return list(competitors)[:5] + + def _assess_severity(self, text: str) -> str: + """Assess severity of pain point""" + if any(word in text for word in ['very', 'extremely', 'really', 'totally', 'completely']): + return 'high' + elif any(word in text for word in ['somewhat', 'bit', 'little', 'slightly']): + return 'low' + return 'medium' + + def _assess_strength(self, text: str) -> str: + """Assess strength of positive feedback""" + if any(word in text for word in ['absolutely', 'definitely', 'really', 'very']): + return 'strong' + return 'moderate' + + def _classify_request(self, text: str) -> str: + """Classify the type of request""" + if any(word in text for word in ['ui', 'design', 'look', 'color', 'layout']): + return 'ui_improvement' + elif any(word in text for word in ['feature', 'add', 'new', 'build']): + return 'new_feature' + elif any(word in text for word in ['fix', 'bug', 'broken', 'work']): + return 'bug_fix' + elif any(word in text for word in ['faster', 'slow', 'performance', 'speed']): + return 'performance' + return 'general' + + def _assess_request_priority(self, text: str) -> str: + """Assess priority of request""" + if any(word in text for word in ['critical', 'urgent', 'asap', 'immediately', 'blocking']): + return 'critical' + elif any(word in text for word in ['need', 'important', 'should', 'must']): + return 'high' + elif any(word in text for word in ['nice', 'would', 'could', 'maybe']): + return 'low' + return 'medium' + +def aggregate_interviews(interviews: List[Dict]) -> Dict: + """Aggregate insights from multiple interviews""" + aggregated = { + 'total_interviews': len(interviews), + 'common_pain_points': defaultdict(list), + 'common_requests': defaultdict(list), + 'jobs_to_be_done': [], + 'overall_sentiment': { + 'positive': 0, + 'negative': 0, + 'neutral': 0 + }, + 'top_themes': Counter(), + 'metrics_summary': set(), + 'competitors_mentioned': Counter() + } + + for interview in interviews: + # Aggregate pain points + for pain in interview.get('pain_points', []): + indicator = pain.get('indicator', 'unknown') + aggregated['common_pain_points'][indicator].append(pain['quote']) + + # Aggregate requests + for request in interview.get('feature_requests', []): + req_type = request.get('type', 'general') + aggregated['common_requests'][req_type].append(request['quote']) + + # Aggregate JTBD + aggregated['jobs_to_be_done'].extend(interview.get('jobs_to_be_done', [])) + + # Aggregate sentiment + sentiment = interview.get('sentiment_score', {}).get('label', 'neutral') + aggregated['overall_sentiment'][sentiment] += 1 + + # Aggregate themes + for theme in interview.get('key_themes', []): + aggregated['top_themes'][theme] += 1 + + # Aggregate metrics + aggregated['metrics_summary'].update(interview.get('metrics_mentioned', [])) + + # Aggregate competitors + for competitor in interview.get('competitors_mentioned', []): + aggregated['competitors_mentioned'][competitor] += 1 + + # Process aggregated data + aggregated['common_pain_points'] = dict(aggregated['common_pain_points']) + aggregated['common_requests'] = dict(aggregated['common_requests']) + aggregated['top_themes'] = dict(aggregated['top_themes'].most_common(10)) + aggregated['metrics_summary'] = list(aggregated['metrics_summary']) + aggregated['competitors_mentioned'] = dict(aggregated['competitors_mentioned']) + + return aggregated + +def format_single_interview(analysis: Dict) -> str: + """Format single interview analysis""" + output = ["=" * 60] + output.append("CUSTOMER INTERVIEW ANALYSIS") + output.append("=" * 60) + + # Sentiment + sentiment = analysis['sentiment_score'] + output.append(f"\n📊 Overall Sentiment: {sentiment['label'].upper()}") + output.append(f" Score: {sentiment['score']}") + output.append(f" Positive signals: {sentiment['positive_signals']}") + output.append(f" Negative signals: {sentiment['negative_signals']}") + + # Pain Points + if analysis['pain_points']: + output.append("\n🔥 Pain Points Identified:") + for i, pain in enumerate(analysis['pain_points'][:5], 1): + output.append(f"\n{i}. [{pain['severity'].upper()}] {pain['quote'][:100]}...") + + # Feature Requests + if analysis['feature_requests']: + output.append("\n💡 Feature Requests:") + for i, req in enumerate(analysis['feature_requests'][:5], 1): + output.append(f"\n{i}. [{req['type']}] Priority: {req['priority']}") + output.append(f" \"{req['quote'][:100]}...\"") + + # Jobs to Be Done + if analysis['jobs_to_be_done']: + output.append("\n🎯 Jobs to Be Done:") + for i, job in enumerate(analysis['jobs_to_be_done'], 1): + output.append(f"{i}. {job['job']}") + + # Key Themes + if analysis['key_themes']: + output.append("\n🏷️ Key Themes:") + output.append(", ".join(analysis['key_themes'])) + + # Key Quotes + if analysis['quotes']: + output.append("\n💬 Key Quotes:") + for i, quote in enumerate(analysis['quotes'][:3], 1): + output.append(f'{i}. "{quote}"') + + # Metrics + if analysis['metrics_mentioned']: + output.append("\n📈 Metrics Mentioned:") + output.append(", ".join(analysis['metrics_mentioned'])) + + # Competitors + if analysis['competitors_mentioned']: + output.append("\n🏢 Competitors Mentioned:") + output.append(", ".join(analysis['competitors_mentioned'])) + + return "\n".join(output) + +def main(): + import sys + + if len(sys.argv) < 2: + print("Usage: python customer_interview_analyzer.py ") + print("\nThis tool analyzes customer interview transcripts to extract:") + print(" - Pain points and frustrations") + print(" - Feature requests and suggestions") + print(" - Jobs to be done") + print(" - Sentiment analysis") + print(" - Key themes and quotes") + sys.exit(1) + + # Read interview transcript + with open(sys.argv[1], 'r') as f: + interview_text = f.read() + + # Analyze + analyzer = InterviewAnalyzer() + analysis = analyzer.analyze_interview(interview_text) + + # Output + if len(sys.argv) > 2 and sys.argv[2] == 'json': + print(json.dumps(analysis, indent=2)) + else: + print(format_single_interview(analysis)) + +if __name__ == "__main__": + main() diff --git a/skills/product-manager-toolkit/scripts/rice_prioritizer.py b/skills/product-manager-toolkit/scripts/rice_prioritizer.py new file mode 100644 index 0000000..5e6f257 --- /dev/null +++ b/skills/product-manager-toolkit/scripts/rice_prioritizer.py @@ -0,0 +1,296 @@ +#!/usr/bin/env python3 +""" +RICE Prioritization Framework +Calculates RICE scores for feature prioritization +RICE = (Reach x Impact x Confidence) / Effort +""" + +import json +import csv +from typing import List, Dict, Tuple +import argparse + +class RICECalculator: + """Calculate RICE scores for feature prioritization""" + + def __init__(self): + self.impact_map = { + 'massive': 3.0, + 'high': 2.0, + 'medium': 1.0, + 'low': 0.5, + 'minimal': 0.25 + } + + self.confidence_map = { + 'high': 100, + 'medium': 80, + 'low': 50 + } + + self.effort_map = { + 'xl': 13, + 'l': 8, + 'm': 5, + 's': 3, + 'xs': 1 + } + + def calculate_rice(self, reach: int, impact: str, confidence: str, effort: str) -> float: + """ + Calculate RICE score + + Args: + reach: Number of users/customers affected per quarter + impact: massive/high/medium/low/minimal + confidence: high/medium/low (percentage) + effort: xl/l/m/s/xs (person-months) + """ + impact_score = self.impact_map.get(impact.lower(), 1.0) + confidence_score = self.confidence_map.get(confidence.lower(), 50) / 100 + effort_score = self.effort_map.get(effort.lower(), 5) + + if effort_score == 0: + return 0 + + rice_score = (reach * impact_score * confidence_score) / effort_score + return round(rice_score, 2) + + def prioritize_features(self, features: List[Dict]) -> List[Dict]: + """ + Calculate RICE scores and rank features + + Args: + features: List of feature dictionaries with RICE components + """ + for feature in features: + feature['rice_score'] = self.calculate_rice( + feature.get('reach', 0), + feature.get('impact', 'medium'), + feature.get('confidence', 'medium'), + feature.get('effort', 'm') + ) + + # Sort by RICE score descending + return sorted(features, key=lambda x: x['rice_score'], reverse=True) + + def analyze_portfolio(self, features: List[Dict]) -> Dict: + """ + Analyze the feature portfolio for balance and insights + """ + if not features: + return {} + + total_effort = sum( + self.effort_map.get(f.get('effort', 'm').lower(), 5) + for f in features + ) + + total_reach = sum(f.get('reach', 0) for f in features) + + effort_distribution = {} + impact_distribution = {} + + for feature in features: + effort = feature.get('effort', 'm').lower() + impact = feature.get('impact', 'medium').lower() + + effort_distribution[effort] = effort_distribution.get(effort, 0) + 1 + impact_distribution[impact] = impact_distribution.get(impact, 0) + 1 + + # Calculate quick wins (high impact, low effort) + quick_wins = [ + f for f in features + if f.get('impact', '').lower() in ['massive', 'high'] + and f.get('effort', '').lower() in ['xs', 's'] + ] + + # Calculate big bets (high impact, high effort) + big_bets = [ + f for f in features + if f.get('impact', '').lower() in ['massive', 'high'] + and f.get('effort', '').lower() in ['l', 'xl'] + ] + + return { + 'total_features': len(features), + 'total_effort_months': total_effort, + 'total_reach': total_reach, + 'average_rice': round(sum(f['rice_score'] for f in features) / len(features), 2), + 'effort_distribution': effort_distribution, + 'impact_distribution': impact_distribution, + 'quick_wins': len(quick_wins), + 'big_bets': len(big_bets), + 'quick_wins_list': quick_wins[:3], # Top 3 quick wins + 'big_bets_list': big_bets[:3] # Top 3 big bets + } + + def generate_roadmap(self, features: List[Dict], team_capacity: int = 10) -> List[Dict]: + """ + Generate a quarterly roadmap based on team capacity + + Args: + features: Prioritized feature list + team_capacity: Person-months available per quarter + """ + quarters = [] + current_quarter = { + 'quarter': 1, + 'features': [], + 'capacity_used': 0, + 'capacity_available': team_capacity + } + + for feature in features: + effort = self.effort_map.get(feature.get('effort', 'm').lower(), 5) + + if current_quarter['capacity_used'] + effort <= team_capacity: + current_quarter['features'].append(feature) + current_quarter['capacity_used'] += effort + else: + # Move to next quarter + current_quarter['capacity_available'] = team_capacity - current_quarter['capacity_used'] + quarters.append(current_quarter) + + current_quarter = { + 'quarter': len(quarters) + 1, + 'features': [feature], + 'capacity_used': effort, + 'capacity_available': team_capacity - effort + } + + if current_quarter['features']: + current_quarter['capacity_available'] = team_capacity - current_quarter['capacity_used'] + quarters.append(current_quarter) + + return quarters + +def format_output(features: List[Dict], analysis: Dict, roadmap: List[Dict]) -> str: + """Format the results for display""" + output = ["=" * 60] + output.append("RICE PRIORITIZATION RESULTS") + output.append("=" * 60) + + # Top prioritized features + output.append("\n📊 TOP PRIORITIZED FEATURES\n") + for i, feature in enumerate(features[:10], 1): + output.append(f"{i}. {feature.get('name', 'Unnamed')}") + output.append(f" RICE Score: {feature['rice_score']}") + output.append(f" Reach: {feature.get('reach', 0)} | Impact: {feature.get('impact', 'medium')} | " + f"Confidence: {feature.get('confidence', 'medium')} | Effort: {feature.get('effort', 'm')}") + output.append("") + + # Portfolio analysis + output.append("\n📈 PORTFOLIO ANALYSIS\n") + output.append(f"Total Features: {analysis.get('total_features', 0)}") + output.append(f"Total Effort: {analysis.get('total_effort_months', 0)} person-months") + output.append(f"Total Reach: {analysis.get('total_reach', 0):,} users") + output.append(f"Average RICE Score: {analysis.get('average_rice', 0)}") + + output.append(f"\n🎯 Quick Wins: {analysis.get('quick_wins', 0)} features") + for qw in analysis.get('quick_wins_list', []): + output.append(f" • {qw.get('name', 'Unnamed')} (RICE: {qw['rice_score']})") + + output.append(f"\n🚀 Big Bets: {analysis.get('big_bets', 0)} features") + for bb in analysis.get('big_bets_list', []): + output.append(f" • {bb.get('name', 'Unnamed')} (RICE: {bb['rice_score']})") + + # Roadmap + output.append("\n\n📅 SUGGESTED ROADMAP\n") + for quarter in roadmap: + output.append(f"\nQ{quarter['quarter']} - Capacity: {quarter['capacity_used']}/{quarter['capacity_used'] + quarter['capacity_available']} person-months") + for feature in quarter['features']: + output.append(f" • {feature.get('name', 'Unnamed')} (RICE: {feature['rice_score']})") + + return "\n".join(output) + +def load_features_from_csv(filepath: str) -> List[Dict]: + """Load features from CSV file""" + features = [] + with open(filepath, 'r') as f: + reader = csv.DictReader(f) + for row in reader: + feature = { + 'name': row.get('name', ''), + 'reach': int(row.get('reach', 0)), + 'impact': row.get('impact', 'medium'), + 'confidence': row.get('confidence', 'medium'), + 'effort': row.get('effort', 'm'), + 'description': row.get('description', '') + } + features.append(feature) + return features + +def create_sample_csv(filepath: str): + """Create a sample CSV file for testing""" + sample_features = [ + ['name', 'reach', 'impact', 'confidence', 'effort', 'description'], + ['User Dashboard Redesign', '5000', 'high', 'high', 'l', 'Complete redesign of user dashboard'], + ['Mobile Push Notifications', '10000', 'massive', 'medium', 'm', 'Add push notification support'], + ['Dark Mode', '8000', 'medium', 'high', 's', 'Implement dark mode theme'], + ['API Rate Limiting', '2000', 'low', 'high', 'xs', 'Add rate limiting to API'], + ['Social Login', '12000', 'high', 'medium', 'm', 'Add Google/Facebook login'], + ['Export to PDF', '3000', 'medium', 'low', 's', 'Export reports as PDF'], + ['Team Collaboration', '4000', 'massive', 'low', 'xl', 'Real-time collaboration features'], + ['Search Improvements', '15000', 'high', 'high', 'm', 'Enhance search functionality'], + ['Onboarding Flow', '20000', 'massive', 'high', 's', 'Improve new user onboarding'], + ['Analytics Dashboard', '6000', 'high', 'medium', 'l', 'Advanced analytics for users'], + ] + + with open(filepath, 'w', newline='') as f: + writer = csv.writer(f) + writer.writerows(sample_features) + + print(f"Sample CSV created at: {filepath}") + +def main(): + parser = argparse.ArgumentParser(description='RICE Framework for Feature Prioritization') + parser.add_argument('input', nargs='?', help='CSV file with features or "sample" to create sample') + parser.add_argument('--capacity', type=int, default=10, help='Team capacity per quarter (person-months)') + parser.add_argument('--output', choices=['text', 'json', 'csv'], default='text', help='Output format') + + args = parser.parse_args() + + # Create sample if requested + if args.input == 'sample': + create_sample_csv('sample_features.csv') + return + + # Use sample data if no input provided + if not args.input: + features = [ + {'name': 'User Dashboard', 'reach': 5000, 'impact': 'high', 'confidence': 'high', 'effort': 'l'}, + {'name': 'Push Notifications', 'reach': 10000, 'impact': 'massive', 'confidence': 'medium', 'effort': 'm'}, + {'name': 'Dark Mode', 'reach': 8000, 'impact': 'medium', 'confidence': 'high', 'effort': 's'}, + {'name': 'API Rate Limiting', 'reach': 2000, 'impact': 'low', 'confidence': 'high', 'effort': 'xs'}, + {'name': 'Social Login', 'reach': 12000, 'impact': 'high', 'confidence': 'medium', 'effort': 'm'}, + ] + else: + features = load_features_from_csv(args.input) + + # Calculate RICE scores + calculator = RICECalculator() + prioritized = calculator.prioritize_features(features) + analysis = calculator.analyze_portfolio(prioritized) + roadmap = calculator.generate_roadmap(prioritized, args.capacity) + + # Output results + if args.output == 'json': + result = { + 'features': prioritized, + 'analysis': analysis, + 'roadmap': roadmap + } + print(json.dumps(result, indent=2)) + elif args.output == 'csv': + # Output prioritized features as CSV + if prioritized: + keys = prioritized[0].keys() + print(','.join(keys)) + for feature in prioritized: + print(','.join(str(feature.get(k, '')) for k in keys)) + else: + print(format_output(prioritized, analysis, roadmap)) + +if __name__ == "__main__": + main() diff --git a/skills/product-manager/SKILL.md b/skills/product-manager/SKILL.md new file mode 100644 index 0000000..2b5f83c --- /dev/null +++ b/skills/product-manager/SKILL.md @@ -0,0 +1,77 @@ +--- +name: Product Manager +description: Build products users love with discovery, prioritization, roadmapping, and cross-functional leadership. +metadata: {"clawdbot":{"emoji":"🎯","os":["linux","darwin","win32"]}} +--- + +# Product Management Rules + +## Discovery +- Talk to users weekly — not just at project kickoff +- Watch behavior, don't just collect opinions — users say one thing, do another +- Problem validation before solution validation — are we solving the right thing? +- Jobs to be done: what's the user trying to accomplish? +- Competitors show what's possible, not what to copy + +## Prioritization +- Impact vs effort is a starting point, not the answer +- Say no more than yes — focus is a feature +- Urgent vs important: stakeholder pressure isn't priority +- Stack rank ruthlessly — "everything is P1" means nothing is +- Revisit priorities when context changes — quarterly at minimum + +## Roadmapping +- Outcomes over outputs — what will change, not what we'll build +- Time horizons: now (committed), next (planned), later (possible) +- Communicate uncertainty honestly — roadmaps aren't promises +- Dependencies surfaced early — blocked work wastes everyone's time +- Update when reality changes — stale roadmaps destroy trust + +## Requirements +- User stories: who, what, why — not how +- Acceptance criteria define done — ambiguity creates rework +- Edge cases addressed upfront — not discovered in QA +- Scope creep is the enemy — good enough now beats perfect later +- Technical constraints are real — work with engineering, not around them + +## Working with Engineering +- Context over directives — explain why, not just what +- Tradeoffs are collaborative decisions +- Spec before sprint, not during — no designing on the fly +- Protect focus time — meetings kill flow +- Trust their estimates, push back on scope not time + +## Working with Design +- Research together, don't hand off briefs +- Critique the work, not the designer +- Design reviews with users, not just stakeholders +- Mobile and edge cases early — not afterthoughts +- Design system enables speed — support it + +## Stakeholder Management +- Regular updates prevent surprise requests +- Data calms opinion battles +- Explain trade-offs, don't just defend decisions +- Feedback channels prevent end-runs — make input easy +- Executive sponsors for big initiatives + +## Metrics +- One north star metric, 2-3 supporting +- Leading indicators for early signal — don't wait for lagging +- Dashboards should prompt questions, not just display numbers +- Vanity metrics feel good, don't drive decisions +- A/B test when data beats intuition + +## Launch +- Soft launch catches problems before scale +- Success criteria defined before launch — not after +- Rollback plan before rollout +- Cross-functional checklist: docs, support, marketing +- Post-launch review: what worked, what didn't + +## Common Mistakes +- Feature factory: shipping without learning +- Overspeccing: killing engineering autonomy +- Consensus seeking: decisions by committee +- Ignoring qualitative: data alone misses why +- Roadmap as backlog: detail everything, commit nothing diff --git a/skills/product-manager/_meta.json b/skills/product-manager/_meta.json new file mode 100644 index 0000000..eb7e6e5 --- /dev/null +++ b/skills/product-manager/_meta.json @@ -0,0 +1,6 @@ +{ + "ownerId": "kn73vp5rarc3b14rc7wjcw8f8580t5d1", + "slug": "product-manager", + "version": "1.0.0", + "publishedAt": 1770675169581 +} \ No newline at end of file diff --git a/skills/repo-kanban-pm/SKILL.md b/skills/repo-kanban-pm/SKILL.md new file mode 100644 index 0000000..dd904dc --- /dev/null +++ b/skills/repo-kanban-pm/SKILL.md @@ -0,0 +1,71 @@ +--- +name: repo-kanban-pm +description: "Install and enforce a lightweight product-management workflow inside a code repo: feature-as-kanban boards, ROADMAP status tracking, branch/PR conventions, and an optional daily OpenClaw cron PM review. Use this skill when (1) starting work in a NEW repository/project that does not yet have a ROADMAP+feature-KANBAN system, (2) you are delegated to spin up a new project and want multi-agent coordination from day one, or (3) you are asked to fix/restructure an existing repo and introduce an organized backlog/feature tracking system. Also use when adding a daily PM audit loop (cron) to keep code + docs + PRs in sync." +--- + +# Repo Kanban PM System + +## What this skill does + +Sets up a **multi-agent-safe** product workflow in a repo: +- `docs/roadmap/ROADMAP.md` as the portfolio status +- `docs/features//KANBAN.md` as execution boards +- `docs/pm/bugs/` as the **bug intake + triage inbox** (linkable into KANBAN) +- Updates `AGENTS.md` to enforce the workflow +- (Optional) creates a daily OpenClaw cron job to run a PM review (includes bug triage) + +## When to use this skill (decision rule) + +Use `repo-kanban-pm` when you are tasked with either: + +1) **Creating/spinning up a new project/repo** and multiple agents will work on it (or you want to avoid chaos later). + - Goal: install ROADMAP + per-feature KANBAN boards immediately. + +2) **Entering an existing repo to fix, refactor, or restructure it** and it *does not* have a clear feature/backlog tracking system. + - Goal: introduce the kanban workflow so subsequent work is trackable and PRs stay aligned. + +Do **not** use this skill if the repo already has an equivalent system that the team actively uses (avoid duplicating governance). + +--- + +## Quick start + +### 1) Initialize the repo workflow + +Run: + +```bash +bash scripts/init_repo_pm.sh /absolute/path/to/repo +``` + +This will: +- create `docs/pm/` with the workflow doc + template +- create `docs/pm/bugs/` with bug README + template +- add `KANBAN.md` to any existing `docs/features/*/` folders +- patch `AGENTS.md` to include the kanban rules (idempotent) + +### 2) Add a daily PM cron (optional) + +Run: + +```bash +bash scripts/add_daily_pm_cron.sh /absolute/path/to/repo --agent persey --tz Europe/Minsk --time 10:00 +``` + +## Operating rules (agents) + +1. Pick a feature from `docs/roadmap/ROADMAP.md` +2. Create/update `docs/features//KANBAN.md` and set status to `in-progress` +3. Create a branch: `feat/-` +4. PR must link the feature’s `KANBAN.md` +5. On merge: mark `KANBAN.md` as done and tick the ROADMAP checkbox + +## Templates + +- Workflow spec: `docs/pm/KANBAN-SYSTEM.md` +- Feature template: `docs/pm/FEATURE-KANBAN-TEMPLATE.md` + +## Notes + +- Keep KANBAN boards short. +- ROADMAP contains status only; do not duplicate per-task detail there. diff --git a/skills/repo-kanban-pm/_meta.json b/skills/repo-kanban-pm/_meta.json new file mode 100644 index 0000000..0a8b504 --- /dev/null +++ b/skills/repo-kanban-pm/_meta.json @@ -0,0 +1,6 @@ +{ + "ownerId": "kn7cpxsva2g8jszszqg98t0gjs81wbmx", + "slug": "repo-kanban-pm", + "version": "0.1.1", + "publishedAt": 1772111070347 +} \ No newline at end of file diff --git a/skills/repo-kanban-pm/scripts/add_daily_pm_cron.sh b/skills/repo-kanban-pm/scripts/add_daily_pm_cron.sh new file mode 100644 index 0000000..f2b264b --- /dev/null +++ b/skills/repo-kanban-pm/scripts/add_daily_pm_cron.sh @@ -0,0 +1,42 @@ +#!/usr/bin/env bash +set -euo pipefail + +REPO_PATH=${1:-} +shift || true + +AGENT_ID="persey" +TZ="Europe/Minsk" +TIME="10:00" +NAME="daily-pm-review" + +while [[ $# -gt 0 ]]; do + case "$1" in + --agent) AGENT_ID="$2"; shift 2;; + --tz) TZ="$2"; shift 2;; + --time) TIME="$2"; shift 2;; + --name) NAME="$2"; shift 2;; + *) echo "Unknown arg: $1" >&2; exit 1;; + esac +done + +if [[ -z "$REPO_PATH" ]]; then + echo "Usage: add_daily_pm_cron.sh /absolute/path/to/repo [--agent persey] [--tz Europe/Minsk] [--time 10:00] [--name daily-pm-review]" >&2 + exit 1 +fi + +# TIME HH:MM +HH=${TIME%:*} +MM=${TIME#*:} + +CRON_EXPR="${MM} ${HH} * * *" + +openclaw cron add \ + --name "${NAME}" \ + --agent "${AGENT_ID}" \ + --cron "${CRON_EXPR}" \ + --tz "${TZ}" \ + --announce \ + --description "Daily PM audit for repo: ${REPO_PATH}" \ + --message "Run daily PM review for repo: ${REPO_PATH}\n\nProcess:\n1) Read docs/roadmap/ROADMAP.md\n2) Read docs/features/*/KANBAN.md\n3) Scan docs/pm/bugs/*.md and ensure each open bug is linked from a feature KANBAN\n4) gh pr list + check recent commits\n5) Ensure KANBAN + ROADMAP reflect reality\n6) Run lightweight checks (if applicable): cd apps/telegram && npx tsc --noEmit\n7) Post report: Done/In progress/Open bugs/Blocked/Risks/Next" + +echo "Cron created: ${NAME} (${CRON_EXPR} ${TZ})" \ No newline at end of file diff --git a/skills/repo-kanban-pm/scripts/init_repo_pm.sh b/skills/repo-kanban-pm/scripts/init_repo_pm.sh new file mode 100644 index 0000000..0139469 --- /dev/null +++ b/skills/repo-kanban-pm/scripts/init_repo_pm.sh @@ -0,0 +1,134 @@ +#!/usr/bin/env bash +set -euo pipefail + +REPO_PATH=${1:-} +if [[ -z "$REPO_PATH" ]]; then + echo "Usage: init_repo_pm.sh /absolute/path/to/repo" >&2 + exit 1 +fi + +cd "$REPO_PATH" + +mkdir -p docs/pm docs/pm/bugs + +# Write workflow docs if missing +if [[ ! -f docs/pm/KANBAN-SYSTEM.md ]]; then +cat > docs/pm/KANBAN-SYSTEM.md <<'EOF' +# Repo — Feature Kanban Workflow (Agent Coordination) + +**Single source of truth for portfolio-level status:** +- `docs/roadmap/ROADMAP.md` + +**Single source of truth for feature-level execution:** +- `docs/features//KANBAN.md` + +## Rules +1. One feature = one branch. +2. One feature = one kanban file. +3. ROADMAP is status, KANBAN is work. +4. No hidden work: code changes require KANBAN + ROADMAP updates and a PR link. +EOF +fi + +if [[ ! -f docs/pm/FEATURE-KANBAN-TEMPLATE.md ]]; then +cat > docs/pm/FEATURE-KANBAN-TEMPLATE.md <<'EOF' +# — Kanban + +**Status:** backlog | in-progress | blocked | done +**Owner:** +**Branch:** +**PR:** +**Last updated:** YYYY-MM-DD + +## Goal + +One sentence. + +## Kanban + +### Backlog +- [ ] + +### Doing +- [ ] + +### Blocked +- [ ] + +### Done +- [ ] +EOF +fi + +# Bug inbox (PM intake) — idempotent +if [[ ! -f docs/pm/bugs/README.md ]]; then +cat > docs/pm/bugs/README.md <<'EOF' +# Bugs & Fixes (PM Inbox) + +This folder is the **bug intake + triage inbox**. + +## Process +1. Create a bug file: `BUG-YYYY-MM-DD-.md` +2. Fill in repro steps + expected/actual + severity +3. Link it from the relevant feature `docs/features//KANBAN.md` (Blocked/Doing) +4. When fixed: add PR link and mark status fixed + +## Daily PM review responsibility +- Scan this folder and ensure each open bug is linked from at least one feature KANBAN. +EOF +fi + +if [[ ! -f docs/pm/bugs/BUG-TEMPLATE.md ]]; then +cat > docs/pm/bugs/BUG-TEMPLATE.md <<'EOF' +# BUG: + +**Status:** open | in-progress | blocked | fixed +**Severity:** low | medium | high | critical +**Discovered:** YYYY-MM-DD +**Reporter:** + +**Feature link:** `docs/features/<feature>/KANBAN.md` +**Related PR:** + +## Repro Steps +1. +2. + +## Expected + +## Actual + +## Suspected Area + +## Fix Plan +- [ ] +EOF +fi + +# Ensure features folders exist; add KANBAN if missing +if [[ -d docs/features ]]; then + for d in docs/features/*; do + [[ -d "$d" ]] || continue + if [[ ! -f "$d/KANBAN.md" ]]; then + cp docs/pm/FEATURE-KANBAN-TEMPLATE.md "$d/KANBAN.md" + fi + done +fi + +# Patch AGENTS.md (append section if not present) +if [[ -f AGENTS.md ]]; then + if ! rg -q "Feature Execution Workflow \(Kanban, Mandatory\)" AGENTS.md 2>/dev/null; then +cat >> AGENTS.md <<'EOF' + +## Feature Execution Workflow (Kanban, Mandatory) + +1. Pick a feature from `docs/roadmap/ROADMAP.md`. +2. Create/update `docs/features/<feature>/KANBAN.md` and set it to **in-progress**. +3. Create a dedicated branch: `feat/<feature-slug>-<short>`. +4. During work: move checkboxes between Backlog → Doing → Done. +5. Before review/merge: update KANBAN with branch + PR link and update ROADMAP status. +EOF + fi +fi + +echo "Initialized repo-kanban-pm workflow in: $REPO_PATH" \ No newline at end of file diff --git a/skills/skill-vetter/SKILL.md b/skills/skill-vetter/SKILL.md new file mode 100644 index 0000000..6f065bd --- /dev/null +++ b/skills/skill-vetter/SKILL.md @@ -0,0 +1,138 @@ +--- +name: skill-vetter +version: 1.0.0 +description: Security-first skill vetting for AI agents. Use before installing any skill from ClawdHub, GitHub, or other sources. Checks for red flags, permission scope, and suspicious patterns. +--- + +# Skill Vetter 🔒 + +Security-first vetting protocol for AI agent skills. **Never install a skill without vetting it first.** + +## When to Use + +- Before installing any skill from ClawdHub +- Before running skills from GitHub repos +- When evaluating skills shared by other agents +- Anytime you're asked to install unknown code + +## Vetting Protocol + +### Step 1: Source Check + +``` +Questions to answer: +- [ ] Where did this skill come from? +- [ ] Is the author known/reputable? +- [ ] How many downloads/stars does it have? +- [ ] When was it last updated? +- [ ] Are there reviews from other agents? +``` + +### Step 2: Code Review (MANDATORY) + +Read ALL files in the skill. Check for these **RED FLAGS**: + +``` +🚨 REJECT IMMEDIATELY IF YOU SEE: +───────────────────────────────────────── +• curl/wget to unknown URLs +• Sends data to external servers +• Requests credentials/tokens/API keys +• Reads ~/.ssh, ~/.aws, ~/.config without clear reason +• Accesses MEMORY.md, USER.md, SOUL.md, IDENTITY.md +• Uses base64 decode on anything +• Uses eval() or exec() with external input +• Modifies system files outside workspace +• Installs packages without listing them +• Network calls to IPs instead of domains +• Obfuscated code (compressed, encoded, minified) +• Requests elevated/sudo permissions +• Accesses browser cookies/sessions +• Touches credential files +───────────────────────────────────────── +``` + +### Step 3: Permission Scope + +``` +Evaluate: +- [ ] What files does it need to read? +- [ ] What files does it need to write? +- [ ] What commands does it run? +- [ ] Does it need network access? To where? +- [ ] Is the scope minimal for its stated purpose? +``` + +### Step 4: Risk Classification + +| Risk Level | Examples | Action | +|------------|----------|--------| +| 🟢 LOW | Notes, weather, formatting | Basic review, install OK | +| 🟡 MEDIUM | File ops, browser, APIs | Full code review required | +| 🔴 HIGH | Credentials, trading, system | Human approval required | +| ⛔ EXTREME | Security configs, root access | Do NOT install | + +## Output Format + +After vetting, produce this report: + +``` +SKILL VETTING REPORT +═══════════════════════════════════════ +Skill: [name] +Source: [ClawdHub / GitHub / other] +Author: [username] +Version: [version] +─────────────────────────────────────── +METRICS: +• Downloads/Stars: [count] +• Last Updated: [date] +• Files Reviewed: [count] +─────────────────────────────────────── +RED FLAGS: [None / List them] + +PERMISSIONS NEEDED: +• Files: [list or "None"] +• Network: [list or "None"] +• Commands: [list or "None"] +─────────────────────────────────────── +RISK LEVEL: [🟢 LOW / 🟡 MEDIUM / 🔴 HIGH / ⛔ EXTREME] + +VERDICT: [✅ SAFE TO INSTALL / ⚠️ INSTALL WITH CAUTION / ❌ DO NOT INSTALL] + +NOTES: [Any observations] +═══════════════════════════════════════ +``` + +## Quick Vet Commands + +For GitHub-hosted skills: +```bash +# Check repo stats +curl -s "https://api.github.com/repos/OWNER/REPO" | jq '{stars: .stargazers_count, forks: .forks_count, updated: .updated_at}' + +# List skill files +curl -s "https://api.github.com/repos/OWNER/REPO/contents/skills/SKILL_NAME" | jq '.[].name' + +# Fetch and review SKILL.md +curl -s "https://raw.githubusercontent.com/OWNER/REPO/main/skills/SKILL_NAME/SKILL.md" +``` + +## Trust Hierarchy + +1. **Official OpenClaw skills** → Lower scrutiny (still review) +2. **High-star repos (1000+)** → Moderate scrutiny +3. **Known authors** → Moderate scrutiny +4. **New/unknown sources** → Maximum scrutiny +5. **Skills requesting credentials** → Human approval always + +## Remember + +- No skill is worth compromising security +- When in doubt, don't install +- Ask your human for high-risk decisions +- Document what you vet for future reference + +--- + +*Paranoia is a feature.* 🔒🦀 diff --git a/skills/skill-vetter/_meta.json b/skills/skill-vetter/_meta.json new file mode 100644 index 0000000..a964a54 --- /dev/null +++ b/skills/skill-vetter/_meta.json @@ -0,0 +1,6 @@ +{ + "ownerId": "kn71j6xbmpwfvx4c6y1ez8cd718081mg", + "slug": "skill-vetter", + "version": "1.0.0", + "publishedAt": 1769863429632 +} \ No newline at end of file diff --git a/skills/skillhub-preference/SKILL.md b/skills/skillhub-preference/SKILL.md new file mode 100644 index 0000000..8a74696 --- /dev/null +++ b/skills/skillhub-preference/SKILL.md @@ -0,0 +1,16 @@ +--- +name: skillhub-preference +description: Prefer `skillhub` for skill discovery/install/update, then fallback to `clawhub` when unavailable or no match. Use when users ask about skills, 插件, or capability extension. +--- + +# Skillhub Preference + +Use this skill as policy guidance whenever the task involves skill discovery, installation, or upgrades. + +## Policy + +1. Try `skillhub` first for search/install/update. +2. If `skillhub` is unavailable, rate-limited, or no match, fallback to `clawhub`. +3. Before installation, summarize source, version, and notable risk signals. +4. Do not claim exclusivity; both registries are allowed. +5. For search requests, run `skillhub search <keywords>` first and report command output. diff --git a/skills/speech-recognition/SKILL.md b/skills/speech-recognition/SKILL.md new file mode 100644 index 0000000..873b024 --- /dev/null +++ b/skills/speech-recognition/SKILL.md @@ -0,0 +1,173 @@ +--- +name: speech-recognition +description: "通用语音识别 Skill。支持多种音频格式(ogg/mp3/wav/m4a),使用硅基流动 SenseVoice API 进行语音转文字。当用户发送语音消息、音频文件,或需要转录音频时触发。" +version: "1.0.0" +--- + +# 通用语音识别 + +使用硅基流动 SenseVoice API 进行语音识别,支持多种音频格式。 + +--- + +## 激活条件 + +| 触发场景 | 说明 | +|----------|------| +| 用户发送语音消息 | `.ogg` / `.mp3` / `.wav` / `.m4a` 文件 | +| 用户要求转录音频 | "转录这个音频"、"语音转文字" | +| 音频文件处理 | 需要提取音频中的文字内容 | + +--- + +## 配置 + +### API Key + +在 `~/.openclaw/openclaw.json` 中配置: + +```json +{ + "providers": { + "siliconflow": { + "apiKey": "sk-xxx" + } + } +} +``` + +### API 端点 + +``` +POST https://api.siliconflow.cn/v1/audio/transcriptions +``` + +### 支持的模型 + +| 模型 | 说明 | +|------|------| +| `FunAudioLLM/SenseVoiceSmall` | 默认,中文效果好 | + +--- + +## 使用方法 + +### 方法一:直接调用 API + +```python +import requests + +api_key = "sk-xxx" + +with open("/path/to/audio.mp3", "rb") as f: + audio_data = f.read() + +response = requests.post( + "https://api.siliconflow.cn/v1/audio/transcriptions", + headers={"Authorization": f"Bearer {api_key}"}, + files={"file": ("audio.mp3", audio_data, "audio/mpeg")}, + data={"model": "FunAudioLLM/SenseVoiceSmall"}, + timeout=60 +) + +print(response.json().get("text", "")) +``` + +### 方法二:处理用户语音消息 + +当用户发送 `.ogg` 语音消息时: + +```bash +# 1. 转换格式(如果是 ogg) +ffmpeg -i /path/to/audio.ogg -ar 16000 -ac 1 /tmp/audio.mp3 -y + +# 2. 调用硅基流动 API(API Key 从环境变量读取) +python3 -c " +import requests +import os + +api_key = os.environ.get('SILICONFLOW_API_KEY') +if not api_key: + raise ValueError('请设置 SILICONFLOW_API_KEY 环境变量') + +with open('/tmp/audio.mp3', 'rb') as f: + audio_data = f.read() + +response = requests.post( + 'https://api.siliconflow.cn/v1/audio/transcriptions', + headers={'Authorization': f'Bearer {api_key}'}, + files={'file': ('audio.mp3', audio_data, 'audio/mpeg')}, + data={'model': 'FunAudioLLM/SenseVoiceSmall'}, + timeout=60 +) +print(response.json().get('text', '')) +" +``` + +--- + +## 支持的音频格式 + +| 格式 | 扩展名 | 说明 | +|------|--------|------| +| MP3 | `.mp3` | 推荐,兼容性好 | +| OGG | `.ogg` | Telegram/Signal 语音格式,需转换 | +| WAV | `.wav` | 无压缩,文件大 | +| M4A | `.m4a` | iOS 录音格式 | +| FLAC | `.flac` | 无损压缩 | + +--- + +## 格式转换 + +如果音频不是 MP3 格式,用 FFmpeg 转换: + +```bash +# OGG → MP3 +ffmpeg -i input.ogg -ar 16000 -ac 1 output.mp3 -y + +# WAV → MP3 +ffmpeg -i input.wav -ar 16000 -ac 1 output.mp3 -y + +# M4A → MP3 +ffmpeg -i input.m4a -ar 16000 -ac 1 output.mp3 -y +``` + +参数说明: +- `-ar 16000`: 采样率 16kHz(语音识别推荐) +- `-ac 1`: 单声道(减少文件大小) +- `-y`: 覆盖已存在的文件 + +--- + +## 错误处理 + +| 错误 | 原因 | 解决 | +|------|------|------| +| `401 Unauthorized` | API Key 无效 | 检查配置 | +| `413 Payload Too Large` | 文件太大 | 压缩或分割音频 | +| `timeout` | 网络超时 | 重试或检查网络 | +| `Invalid audio format` | 格式不支持 | 用 FFmpeg 转换 | + +--- + +## 注意事项 + +1. **文件大小限制**:建议 < 10MB +2. **时长限制**:建议 < 5 分钟 +3. **语言支持**:中文效果最好,英文也支持 +4. **隐私**:音频会上传到硅基流动服务器 + +--- + +## 相关 Skills + +| Skill | 说明 | +|-------|------| +| `douyin-video` | 抖音视频语音提取 | +| `cosyvoice-tts` | 文字转语音 | + +--- + +*版本:1.0.0* +*创建于:2026-02-26* diff --git a/skills/speech-recognition/_meta.json b/skills/speech-recognition/_meta.json new file mode 100644 index 0000000..85afa84 --- /dev/null +++ b/skills/speech-recognition/_meta.json @@ -0,0 +1,6 @@ +{ + "ownerId": "kn74vrjmq2se4vx6khxd9sxg3d81vp7f", + "slug": "speech-recognition", + "version": "1.0.1", + "publishedAt": 1772038639129 +} \ No newline at end of file diff --git a/skills/speech-recognition/skill.json b/skills/speech-recognition/skill.json new file mode 100644 index 0000000..7765ac3 --- /dev/null +++ b/skills/speech-recognition/skill.json @@ -0,0 +1,9 @@ +{ + "name": "speech-recognition", + "version": "1.0.0", + "description": "通用语音识别,支持多种音频格式(ogg/mp3/wav/m4a),使用硅基流动 SenseVoice API 进行语音转文字。当用户发送语音消息、音频文件,或需要转录音频时触发。", + "author": "Kuro", + "tags": ["audio", "asr", "speech", "transcription", "siliconflow"], + "repository": "https://github.com/kuro-ai/speech-recognition", + "license": "MIT" +} diff --git a/skills/summarize/SKILL.md b/skills/summarize/SKILL.md new file mode 100644 index 0000000..df9e239 --- /dev/null +++ b/skills/summarize/SKILL.md @@ -0,0 +1,49 @@ +--- +name: summarize +description: Summarize URLs or files with the summarize CLI (web, PDFs, images, audio, YouTube). +homepage: https://summarize.sh +metadata: {"clawdbot":{"emoji":"🧾","requires":{"bins":["summarize"]},"install":[{"id":"brew","kind":"brew","formula":"steipete/tap/summarize","bins":["summarize"],"label":"Install summarize (brew)"}]}} +--- + +# Summarize + +Fast CLI to summarize URLs, local files, and YouTube links. + +## Quick start + +```bash +summarize "https://example.com" --model google/gemini-3-flash-preview +summarize "/path/to/file.pdf" --model google/gemini-3-flash-preview +summarize "https://youtu.be/dQw4w9WgXcQ" --youtube auto +``` + +## Model + keys + +Set the API key for your chosen provider: +- OpenAI: `OPENAI_API_KEY` +- Anthropic: `ANTHROPIC_API_KEY` +- xAI: `XAI_API_KEY` +- Google: `GEMINI_API_KEY` (aliases: `GOOGLE_GENERATIVE_AI_API_KEY`, `GOOGLE_API_KEY`) + +Default model is `google/gemini-3-flash-preview` if none is set. + +## Useful flags + +- `--length short|medium|long|xl|xxl|<chars>` +- `--max-output-tokens <count>` +- `--extract-only` (URLs only) +- `--json` (machine readable) +- `--firecrawl auto|off|always` (fallback extraction) +- `--youtube auto` (Apify fallback if `APIFY_API_TOKEN` set) + +## Config + +Optional config file: `~/.summarize/config.json` + +```json +{ "model": "openai/gpt-5.2" } +``` + +Optional services: +- `FIRECRAWL_API_KEY` for blocked sites +- `APIFY_API_TOKEN` for YouTube fallback diff --git a/skills/summarize/_meta.json b/skills/summarize/_meta.json new file mode 100644 index 0000000..3941b87 --- /dev/null +++ b/skills/summarize/_meta.json @@ -0,0 +1,6 @@ +{ + "ownerId": "kn70pywhg0fyz996kpa8xj89s57yhv26", + "slug": "summarize", + "version": "1.0.0", + "publishedAt": 1767545383635 +} \ No newline at end of file diff --git a/skills/super-ocr/README.md b/skills/super-ocr/README.md new file mode 100644 index 0000000..7eebd79 --- /dev/null +++ b/skills/super-ocr/README.md @@ -0,0 +1,122 @@ +# 🦸‍♂️ Super OCR + +### The Intelligent OCR Solution That Chooses the Best Engine for You + +[![License](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE) +[![OpenClaw Skill](https://img.shields.io/badge/OpenClaw-Skill-green)](https://openclaw.ai) + +**Stop guessing which OCR engine to use.** Super OCR automatically selects the optimal engine combination for your specific image, delivering superior accuracy across multiple languages while handling the complexity behind the scenes. + +## 🌟 Why Super OCR? + +Traditional OCR tools force you to choose a single engine and stick with it. But what if your document contains Chinese characters mixed with English? Or Japanese text in a complex layout? **Super OCR solves this by running multiple engines in parallel and intelligently selecting the best result.** + +### Key Advantages: +- ✨ **Automatic Engine Selection**: No more manual configuration or guesswork +- 📈 **Higher Accuracy**: Achieves up to 98%+ accuracy by leveraging the strengths of multiple engines +- 🌍 **Multi-Language Mastery**: Seamlessly handles Chinese, English, Japanese, Korean, Thai, French, and more +- ⚡ **Smart Performance**: Balances speed and accuracy based on your content +- 🧠 **Confidence-Based Selection**: Uses weighted scoring to pick the most reliable result + +## 🚀 Quick Start + +### Installation +```bash +pip install paddleocr paddlepaddle pytesseract pillow opencv-python numpy +``` + +### Basic Usage +```bash +# Navigate to skill directory +cd ~/.openclaw/workspace/skills/super-ocr + +# Auto mode (recommended) - let Super OCR choose the best approach +python scripts/main.py --image your-document.png --engine all + +# Force specific engine (if needed) +python scripts/main.py --image document.png --engine tesseract +python scripts/main.py --image menu.png --engine paddle + +# Batch processing +python scripts/main.py --images ./images/*.png --output ./results +``` + +## 🎯 Intelligent Multi-Engine Strategy + +Super OCR's core innovation is its **parallel processing architecture** combined with **intelligent result selection**: + +### How It Works: +1. **Parallel Execution**: Multiple OCR engines process your image simultaneously +2. **Confidence Scoring**: Each engine's output is evaluated with reliability metrics +3. **Weighted Selection**: Our intelligent agent analyzes results and selects the optimal output +4. **Language-Aware Optimization**: Automatically adapts to the detected language mix + +### Real-World Performance Benefits: +- **Chinese documents**: 95%+ accuracy (vs 63% with single-engine approaches) +- **English documents**: Consistent 99-100% accuracy with faster fallback options +- **Mixed-language content**: Seamless handling without manual intervention +- **Complex layouts**: Better structure preservation through multi-engine consensus + +## 📊 Performance Comparison + +| Scenario | Single Engine | Super OCR (Multi-Engine) | +|----------|---------------|-------------------------| +| Chinese Text | 63-85% | **95%+** | +| English Text | 99-100% | **99-100%** | +| Japanese Text | 81% | **97%+** | +| Mixed Languages | Variable | **Consistently High** | +| Processing Speed | Fast | Optimized Balance | + +*Based on comprehensive testing across diverse document types and languages* + +## 🏗️ Project Structure +``` +super-ocr/ +├── scripts/ +│ ├── main.py # Main entry point +│ ├── engine/ +│ │ ├── selector.py # Intelligent engine selection logic +│ │ ├── tesseract.py # Tesseract engine wrapper +│ │ ├── paddle.py # PaddleOCR engine wrapper +│ │ └── macvision.py # MacVision engine (macOS only) +│ └── preprocessing/ +│ └── preprocessor.py # Image preprocessing +├── references/ # Documentation +│ ├── api-reference.md +│ ├── engine-comparison.md +│ └── troubleshooting.md +├── SKILL.md # OpenClaw Skill definition +├── _meta.json # Skill metadata +└── LICENSE # MIT License +``` + +## 🛠️ Advanced Usage + +### Language-Specific Optimization +```bash +# For Thai documents (requires Thai language pack) +python scripts/main.py --image thai-document.png --engine all --lang th +``` + +### Performance Tuning +```bash +# Prioritize speed over accuracy +python scripts/main.py --image quick-scan.png --engine tesseract + +# Maximum accuracy (slower) +python scripts/main.py --image critical-document.png --engine all +``` + +### macOS Specific (MacVision) +On macOS, Super OCR leverages the native Vision framework via Swift script for optimal performance: +- MacVision requires Xcode command line tools +- Swift script is executed automatically when available + +## 📄 License + +MIT License - see [LICENSE](LICENSE) for details. + +--- + +**Built with ❤️ by Nima AI Team** +*Super OCR v1.0.1 - Making OCR intelligent, one document at a time.* \ No newline at end of file diff --git a/skills/super-ocr/SECURITY.md b/skills/super-ocr/SECURITY.md new file mode 100644 index 0000000..9f6fcd6 --- /dev/null +++ b/skills/super-ocr/SECURITY.md @@ -0,0 +1,57 @@ +# Security Policy + +## Supported Versions + +| Version | Supported | +| ------- | ------------------ | +| 1.x | ✅ Yes | +| < 1.0 | ❌ No | + +## Reporting a Vulnerability + +If you discover a security vulnerability in Super OCR, please report it responsibly: + +### Email +Send an email to [security@nima-ai.com](mailto:security@nima-ai.com) with: +- Subject: "Security Vulnerability in Super OCR" +- Description of the vulnerability +- Steps to reproduce +- Potential impact +- Suggested fix (if any) + +### Response Timeline +- Acknowledgment within 48 hours +- Initial assessment within 1 week +- Regular updates during investigation +- Public disclosure timeline coordinated with reporter + +## Security Measures + +### Code Review +- All pull requests undergo security review +- Dependency scanning for known vulnerabilities +- Automated security checks in CI/CD + +### Dependencies +- Regular updates of third-party libraries +- Pinning of dependency versions +- Audit of security advisories + +### Data Protection +- No sensitive data stored in repository +- No user data collection by design +- Secure handling of temporary files + +## Best Practices + +### For Users +- Keep Super OCR updated to latest version +- Review permissions before installation +- Monitor for unusual behavior +- Report suspicious activity + +### For Contributors +- Follow secure coding practices +- Validate all inputs +- Sanitize outputs appropriately +- Use parameterized queries for file operations \ No newline at end of file diff --git a/skills/super-ocr/SKILL.md b/skills/super-ocr/SKILL.md new file mode 100644 index 0000000..eff1170 --- /dev/null +++ b/skills/super-ocr/SKILL.md @@ -0,0 +1,224 @@ +--- +name: super-ocr +description: "Production-grade OCR with intelligent engine selection. Tesseract (lightweight, fast) and PaddleOCR (high accuracy, Chinese-optimized). Use when extracting text from images, processing Chinese documents, needing confidence scores, or working with mixed Chinese/English content." +--- + +# Super OCR + +## Overview + +Super OCR is a production-grade optical character recognition tool that intelligently selects the best engine for your needs: + +- **Tesseract Engine**: Lightweight, fast (~200-500ms), perfect for simple text extraction +- **PaddleOCR Engine**: High accuracy (98%+), optimized for Chinese, ideal for complex documents + +## Engine Selection Strategy + +### Auto Mode (Default) +The skill automatically selects the optimal engine: + +| Scenario | Selected Engine | Why | +|----------|----------------|-----| +| Simple text, English only | Tesseract | Faster, lighter dependency | +| Chinese content, high accuracy needed | PaddleOCR | Better Chinese support, 98%+ accuracy | +| Low confidence from Tesseract | PaddleOCR (fallback) | Quality assurance | + +### Force Mode +Users can explicitly choose an engine: +- `--engine tesseract` - Use Tesseract only +- `--engine paddle` - Use PaddleOCR only +- `--engine auto` - Auto-select (default) + +## Quick Start + +### Installation + +This skill requires the following dependencies: +- **PaddleOCR** (for Chinese text recognition - 98%+ accuracy) +- **Tesseract** (for fast English text recognition) +- **OpenCV** (for image preprocessing) + +#### Option 1: Install with pip (all-in-one) +```bash +pip install paddleocr paddlepaddle pytesseract pillow opencv-python numpy +``` + +#### Option 2: Install dependencies manually + +**macOS:** +```bash +# Tesseract +brew install tesseract + +# PaddleOCR +pip install paddleocr paddlepaddle +``` + +**Ubuntu/Debian:** +```bash +# Tesseract +sudo apt update && sudo apt install tesseract-ocr + +# PaddleOCR +pip install paddleocr paddlepaddle +``` + +**Windows:** +```bash +# Download Tesseract from: https://github.com/UB-Mannheim/tesseract/wiki +pip install paddleocr paddlepaddle pytesseract pillow opencv-python numpy +``` + +### Usage + +```bash +# Auto mode (recommended) - runs all available engines +cd path/to/super-ocr +python scripts/main.py --image path/to/image.png + +# Force Tesseract only +python scripts/main.py --image document.jpg --engine tesseract + +# Force PaddleOCR (high accuracy Chinese) +python scripts/main.py --image chinese_menu.png --engine paddle + +# Run all engines (macOS only: Tesseract + PaddleOCR + MacVision) +python scripts/main.py --image complex_doc.png --engine all + +# Batch processing with output directory +python scripts/main.py --images ./images/*.png --output ./results --verbose + +# Check dependencies and auto-install +python scripts/dependencies.py --check --install +``` + +## Structuring This Skill + +This skill uses a **capabilities-based** structure with multiple execution modes: + +1. **Engine Selection Logic** - Intelligent decision making +2. **OCR Execution** - Unified interface for different engines +3. **Post-processing** - Standardized output formatting +4. **Validation & Fallback** - Quality assurance + +## Core Capabilities + +### 1. Intelligent Engine Selection + +The skill includes a decision tree that analyzes: + +- Image characteristics (contrast, text size) +- Language patterns (Chinese character detection) +- User requirements (speed vs accuracy) + +See `scripts/engine_selector.py` for implementation details. + +### 2. Dual Engine Support + +**Tesseract Engine** (`scripts/tesseract_ocr.py`): +- Fast preprocessing pipeline +- PSM mode 6 for uniform text blocks +- Confidence scoring per word +- Language detection + +**PaddleOCR Engine** (`scripts/paddle_ocr.py`): +- State-of-art? SN (East text detection) +- Crnn recognition with LSTM +- Confidence scores per character +- Table detection support + +### 3. Output Formats + +Supports multiple output formats: + +| Format | Content | Use Case | +|--------|---------|----------| +| Text only | Clean extracted text | Simple search/grep | +| Structured | Text + positions | Data extraction | +| JSON | Full metadata + confidence | API integration | +| Verbose | Debug info | Quality assurance | + +### 4. Quality Guarantees + +- Confidence thresholds (configurable, default 80%) +- Low-confidence alerts for manual review +- \Fallback processing for failed OCRs + +## Resources + +### scripts/ + +- `main.py` - Main entry point, CLI interface (supports multi-engine) +- `dependencies.py` - Auto-install and validation +- `output_formatter.py` - Multiple output format support +- `engine/` - OCR engine implementations + - `selector.py` - Intelligent engine selection logic + - `tesseract.py` - Tesseract engine wrapper + - `paddle.py` - PaddleOCR engine wrapper + - `macvision.py` - macOS Vision OCR (macOS only) +- `preprocessing/` - Image preprocessing utilities + - `preprocessor.py` - Denoising, enhancement, binarization + +### dependencies.py (Key Feature) + +The `dependencies.py` module handles: + +- Dependency detection (`paddleocr`, `paddlepaddle`, `pytesseract`, `cv2`) +- Auto-install on missing dependencies +- version checking +- OS-specific installation commands +- Clear error messages with troubleshooting steps + +Use this when setting up a new environment with `python scripts/dependencies.py --check --install` + +## Advanced Features + +### Custom Configuration + +Create `config.yaml` for persistent settings: + +```yaml +default_engine: auto +confidence_threshold: 0.8 +output_format: json +preprocess: + denoise: true + enhance_contrast: true +``` + +### Batch Processing + +Process multiple images: + +```bash +python scripts/ocr.py --images ./images/*.png --output ./results +``` + +### API Mode + +Use as a Python library: + +```python +from super_ocr import OCRProcessor + +processor = OCRProcessor(engine='auto') +result = processor.extract('image.png') +print(result.text) +print(result.confidence) +``` + +## Anti-Patterns + +- ❌ Using PaddleOCR for every image (overhead for simple cases) +- ❌ ignoring confidence scores (quality matters) +- ❌ Biases (always prefering one engine) +- ❌ Skipping preprocessing (quality impact) + +## Performance Notes + +| Engine | Init Time | Per-Image | Memory | Best For | +|--------|-----------|-----------|----------|----------| +| Tesseract | ~200ms | ~50ms | ~100MB | Quick extraction | +| PaddleOCR | ~3s | ~500ms | ~500MB | High accuracy | + +Initialize once, reuse processor for batch processing. \ No newline at end of file diff --git a/skills/super-ocr/_meta.json b/skills/super-ocr/_meta.json new file mode 100644 index 0000000..233dcd1 --- /dev/null +++ b/skills/super-ocr/_meta.json @@ -0,0 +1,6 @@ +{ + "ownerId": "kn7bn4yrcnvd7vp07r9hq28mpd82f7zz", + "slug": "super-ocr", + "version": "0.1.0", + "publishedAt": 1772858905235 +} \ No newline at end of file diff --git a/skills/super-ocr/references/api-reference.md b/skills/super-ocr/references/api-reference.md new file mode 100644 index 0000000..a0ea902 --- /dev/null +++ b/skills/super-ocr/references/api-reference.md @@ -0,0 +1,163 @@ +# API Reference for Super OCR + +This document provides complete API documentation for using Super OCR as a Python library. + +## Quick Start + +```python +from super_ocr import OCRProcessor + +# Auto mode (recommended) +processor = OCRProcessor(engine='auto') +result = processor.extract('image.png') + +print(result['text']) +print(f"Confidence: {result['confidence']:.2%}") +print(f"Engine: {result['engine']}") +``` + +## OCRProcessor Class + +### `__init__(engine: str = 'auto', verbose: bool = False)` + +Initialize the OCR processor. + +**Parameters:** +- `engine` (str): 'auto', 'tesseract', or 'paddle'. Default: 'auto' +- `verbose` (bool): Enable detailed logging. Default: False + +### `extract(image_path: str) -> Dict` + +Extract text from a single image. + +**Parameters:** +- `image_path` (str): Path to the input image + +**Returns:** +```python +{ + 'text': str, # Extracted text + 'confidence': float, # Confidence score (0.0 - 1.0) + 'engine': str, # 'tesseract' or 'paddle' + 'processing_time_ms': float, # Processing time in milliseconds + 'error': Optional[str], # Error message if failed + 'results': List[Dict], # Detailed results (PaddleOCR only) + 'line_count': int # Number of lines detected +} +``` + +### `batch_extract(image_paths: List[str]) -> List[Dict]` + +Process multiple images. + +**Parameters:** +- `image_paths` (List[str]): List of image file paths + +**Returns:** +- List of result dictionaries (same structure as `extract()`) + +## Engine Selection + +### Auto Mode (Default) + +The processor automatically selects the best engine based on: + +1. **Image filename heuristics:** + - `screenshot`, `snap`, `capture` → Tesseract + - `menu`, `invoice`, `certificate`, `receipt` → PaddleOCR + - Default → PaddleOCR (better accuracy) + +2. **Quality fallback:** + - If Tesseract returns low confidence, PaddleOCR is used + +### Force Mode + +You can explicitly choose an engine: + +```python +# Force Tesseract +processor = OCRProcessor(engine='tesseract') + +# Force PaddleOCR +processor = OCRProcessor(engine='paddle') +``` + +## Preprocessing + +For advanced users, you can preprocess images before OCR: + +```python +from super_ocr.preprocessing import preprocess_pipeline + +# Load image +import cv2 +image = cv2.imread('input.png') + +# Preprocess +processed = preprocess_pipeline( + image, + denoise=True, + enhance=True, + binarize=True, + deskew=True, + resize_scale=2.0 +) + +# Save processed image +cv2.imwrite('processed.png', processed) +``` + +## Output Formats + +The skill supports multiple output formats: + +| Format | Description | +|--------|-------------| +| `text` | Clean extracted text only | +| `json` | Full JSON with metadata | +| `structured` | Human-readable formatted output | +| `verbose` | Debug information with confidence scores | + +## Configuration + +You can customize behavior by creating a `config.yaml`: + +```yaml +default_engine: auto +confidence_threshold: 0.8 +output_format: json +preprocess: + denoise: true + enhance_contrast: true +``` + +## Error Handling + +```python +try: + result = processor.extract('image.png') + + if result.get('error'): + print(f"Error: {result['error']}") + else: + print(result['text']) + +except Exception as e: + print(f"Unexpected error: {e}") +``` + +## CLI Usage + +```bash +# Single image +python scripts/main.py --image image.png + +# Multiple images +python scripts/main.py --images ./images/*.png --output ./results + +# Force engine +python scripts/main.py --image doc.png --engine paddle --verbose + +# Different output format +python scripts/main.py --image img.png --format text +``` \ No newline at end of file diff --git a/skills/super-ocr/references/engine-comparison.md b/skills/super-ocr/references/engine-comparison.md new file mode 100644 index 0000000..1890486 --- /dev/null +++ b/skills/super-ocr/references/engine-comparison.md @@ -0,0 +1,77 @@ +# Engine Comparison + +## Tesseract vs PaddleOCR + +| Feature | Tesseract | PaddleOCR | +|---------|-----------|-----------| +| **Accuracy** | 90-95% | 98%+ | +| **Chinese Support** | Good | Excellent | +| **Speed** | ~200ms init, ~50ms/img | ~3s init, ~500ms/img | +| **Memory** | ~100MB | ~500MB | +| **Dependencies** | `pytesseract + cv2 + PIL` | `paddleocr + paddlepaddle` | +| **Best For** | Quick extraction, English | High accuracy, Chinese docs | + +## When to Use Which + +### Use Tesseract When: +- ✅ Extracting text from screenshots +- ✅ Processing English-only documents +- ✅ Need fast OCR (-web scraping, quick验证) +- ✅ Limited memory environment + +### Use PaddleOCR When: +- ✅ Processing Chinese documents +- ✅ Need high accuracy (98%+) +- ✅ Working with complex layouts(tables, forms) +- ✅ Critical data extraction (invoices, contracts) + +## Performance Comparison + +| Task | Tesseract | PaddleOCR | Improvement | +|------|-----------|-----------|-------------| +| Screenshot text | ~70ms | ~600ms | Tesseract faster | +| Chinese menu | ~200ms | ~550ms | - | +| Invoice extraction | ~180ms | ~520ms | - | +| Certificate OCR | ~250ms | ~580ms | PaddleOCR more accurate | + +## Quality Comparison + +### Example: Chinese Restaurant Menu + +**Tesseract (confidence: 88%)** +``` +北京烤鸭 +宫保鸡丁 +麻婆豆腐... +``` + +**PaddleOCR (confidence: 99%)** +``` +北京烤鸭 +宫保鸡丁 +麻婆豆腐 +... +``` + +### Example: English Invoice + +**Tesseract (confidence: 92%)** +``` +Invoice #12345 +Date: 2024-03-05 +Amount: $199.99 +``` + +**PaddleOCR (confidence: 98%)** +``` +Invoice #12345 +Date: 2024-03-05 +Amount: $199.99 +``` + +## Recommendation + +- **General use**: Auto mode (PaddleOCR by default for quality) +- **Speed-critical**: Force Tesseract +- **Chinese critical**: Force PaddleOCR +- **Production**: Auto mode with fallback to PaddleOCR for low confidence \ No newline at end of file diff --git a/skills/super-ocr/references/troubleshooting.md b/skills/super-ocr/references/troubleshooting.md new file mode 100644 index 0000000..95d8655 --- /dev/null +++ b/skills/super-ocr/references/troubleshooting.md @@ -0,0 +1,150 @@ +# Troubleshooting + +Common issues and solutions for Super OCR。 + +## Installation Issues + +### "Module not found: paddleocr" + +**Solution:** +```bash +pip install paddleocr paddlepaddle +``` + +For macOS/Linux: +```bash +pip install paddleocr paddlepaddle +``` + +For Windows: +```bash +pip install paddleocr paddlepaddle +``` + +### "Tesseract not found" + +**macOS:** +```bash +brew install tesseract +``` + +**Ubuntu/Debian:** +```bash +sudo apt update && sudo apt install tesseract-ocr +``` + +**Windows:** +Download from: https://github.com/UB-Mannheim/tesseract/wiki + +## Runtime Issues + +### Low Confidence Results + +If OCR results have low confidence: + +1. **Enable verbose mode:** + ```bash + python scripts/main.py --image image.png --verbose + ``` + +2. **Preprocess image manually:** + ```python + from super_ocr.preprocessing import preprocess_pipeline + import cv2 + + image = cv2.imread('input.png') + processed = preprocess_pipeline(image, enhance=True, binarize=True) + cv2.imwrite('processed.png', processed) + ``` + +3. **Force PaddleOCR for better accuracy:** + ```bash + python scripts/main.py --image image.png --engine paddle + ``` + +### Memory Issues (PaddleOCR) + +PaddleOCR uses ~500MB memory。If you see memory errors: + +1. **Use Tesseract instead:** + ```bash + python scripts/main.py --image image.png --engine tesseract + ``` + +2. **Process images one by one:** + ```bash + for img in images/*.png; do + python scripts/main.py --image "$img" --output results/ + done + ``` + +### Batch Processing Too Slow + +**Solutions:** + +1. **Use Tesseract for speed:** + ```bash + python scripts/main.py --images ./images/*.png --engine tesseract --output ./results/ + ``` + +2. **Process in parallel:** + ```bash + # macOS/Linux + find ./images -name "*.png" -print0 | xargs -0 -P 4 -I {} python scripts/main.py --image {} --output ./results/ + ``` + +3. **Initialize processor once, reuse:** + ```python + processor = OCRProcessor(engine='auto') + + for image in images: + result = processor.extract(image) + # Process result + ``` + +## Configuration Issues + +### Custom Configuration Not Loading + +Create `config.yaml` in skill directory: + +```yaml +default_engine: auto +confidence_threshold: 0.8 +output_format: json +preprocess: + denoise: true + enhance_contrast: true +``` + +### Output Format Not Working + +Check format name: +```bash +python scripts/main.py --image image.png --format json +python scripts/main.py --image image.png --format text +python scripts/main.py --image image.png --format structured +``` + +## Dependency Checker + +Run the checker to diagnose issues: + +```bash +python scripts/dependencies.py --check --verbose +python scripts/dependencies.py --install +python scripts/dependencies.py --guide +``` + +## Getting Help + +If you encounter issues not covered here: + +1. Enable verbose mode: `--verbose` +2. Check dependency status: `python scripts/dependencies.py --check` +3. Try force engine: `--engine tesseract` or `--engine paddle` +4. Report issue with: + - Python version + - OS + - Command used + - Error message \ No newline at end of file diff --git a/skills/super-ocr/requirements.txt b/skills/super-ocr/requirements.txt new file mode 100644 index 0000000..acf764e --- /dev/null +++ b/skills/super-ocr/requirements.txt @@ -0,0 +1,14 @@ +# Requirements for Super OCR + +# PaddleOCR (primary engine for Chinese, 98%+ accuracy) +paddleocr +paddlepaddle + +# Tesseract (secondary engine for English, fast) +pytesseract +pillow +opencv-python +numpy + +# Optional: macOS Vision OCR +# pip install pyobjc # macOS only \ No newline at end of file diff --git a/skills/super-ocr/scripts/__pycache__/dependencies.cpython-311.pyc b/skills/super-ocr/scripts/__pycache__/dependencies.cpython-311.pyc new file mode 100644 index 0000000..48cc43c Binary files /dev/null and b/skills/super-ocr/scripts/__pycache__/dependencies.cpython-311.pyc differ diff --git a/skills/super-ocr/scripts/__pycache__/output_formatter.cpython-311.pyc b/skills/super-ocr/scripts/__pycache__/output_formatter.cpython-311.pyc new file mode 100644 index 0000000..ca1e907 Binary files /dev/null and b/skills/super-ocr/scripts/__pycache__/output_formatter.cpython-311.pyc differ diff --git a/skills/super-ocr/scripts/dependencies.py b/skills/super-ocr/scripts/dependencies.py new file mode 100644 index 0000000..03f5fe8 --- /dev/null +++ b/skills/super-ocr/scripts/dependencies.py @@ -0,0 +1,343 @@ +#!/usr/bin/env python3 +""" +Dependencies checker and auto-installer for Super OCR + +This module handles: +- Dependency detection +- Auto-installation of missing packages +- Version checking +- Clear error messages with troubleshooting steps +""" + +import importlib.util +import os +import subprocess +import sys +from typing import Dict, List, Optional, Tuple + + +# Dependency definitions +DEPENDENCIES = { + 'paddleocr': { + 'package': 'paddleocr', + 'required': ['paddleocr'], + 'optional': [], + 'install_cmd': 'pip install paddleocr paddlepaddle', + 'check_fn': 'check_paddleocr' + }, + 'pytesseract': { + 'package': 'pytesseract', + 'required': ['pytesseract', 'PIL', 'cv2', 'numpy'], + 'optional': [], + 'install_cmd': 'pip install pytesseract pillow opencv-python numpy', + 'check_fn': 'check_pytesseract' + }, + 'common': { + 'package': 'common', + 'required': ['pathlib', 'argparse', 'logging'], + 'optional': ['yaml'], + 'install_cmd': None, + 'check_fn': None + } +} + + +def _check_module(module_name: str) -> bool: + """Check if a Python module is available""" + return importlib.util.find_spec(module_name) is not None + + +def check_paddleocr() -> Tuple[bool, List[str]]: + """Check PaddleOCR and paddlepaddle availability""" + missing = [] + + if not _check_module('paddleocr'): + missing.append('paddleocr') + + # Check paddlepaddle (the actual library) + if not _check_module('paddle'): + missing.append('paddlepaddle') + + return len(missing) == 0, missing + + +def check_pytesseract() -> Tuple[bool, List[str]]: + """Check Tesseract-related dependencies""" + missing = [] + + # Python packages + for pkg in ['pytesseract', 'PIL', 'cv2', 'numpy']: + if not _check_module(pkg): + missing.append(pkg) + + return len(missing) == 0, missing + + +def check_tesseract_binary() -> Tuple[bool, str]: + """Check if tesseract binary is installed""" + try: + result = subprocess.run( + ['tesseract', '--version'], + capture_output=True, + text=True, + timeout=5 + ) + return True, result.stdout.strip() + except (subprocess.TimeoutExpired, FileNotFoundError, PermissionError): + return False, "" + + +def check_dependency(dep_name: str) -> Tuple[bool, List[str], Optional[str]]: + """ + Check a specific dependency. + + Returns: + (is_available, missing_items, installation_hint) + """ + if dep_name not in DEPENDENCIES: + return False, [], None + + dep = DEPENDENCIES[dep_name] + + # Check if we have a custom check function + if dep.get('check_fn'): + check_fn_name = dep['check_fn'] + check_fns = { + 'check_paddleocr': check_paddleocr, + 'check_pytesseract': check_pytesseract, + 'check_tesseract_binary': check_tesseract_binary + } + + if check_fn_name in check_fns: + is_available, result = check_fns[check_fn_name]() + return is_available, result if isinstance(result, list) else [], None + + # Generic check for required packages + missing = [] + for pkg in dep.get('required', []): + if not _check_module(pkg): + missing.append(pkg) + + return len(missing) == 0, missing, dep.get('install_cmd') + + +def auto_install(dependency: str) -> bool: + """ + Auto-install a dependency. + + Returns: + True if installation succeeded, False otherwise + """ + if dependency not in DEPENDENCIES: + print(f"[ERROR] Unknown dependency: {dependency}") + return False + + dep = DEPENDENCIES[dependency] + install_cmd = dep.get('install_cmd') + + if not install_cmd: + print(f"[INFO] No auto-install command for {dependency}") + return False + + print(f"[INFO] Installing {dependency}...") + print(f" Command: {install_cmd}") + + try: + result = subprocess.run( + install_cmd.split(), + capture_output=True, + text=True, + timeout=120 + ) + + if result.returncode == 0: + print(f"[OK] {dependency} installed successfully") + return True + else: + print(f"[ERROR] Installation failed:") + print(f" {result.stderr}") + return False + + except Exception as e: + print(f"[ERROR] Auto-install failed: {e}") + return False + + +def print_installation_guide() -> None: + """Print comprehensive installation instructions""" + print("\n" + "=" * 60) + print("Super OCR Dependencies Installation Guide") + print("=" * 60) + + print("\n[OPTION 1] Install PaddleOCR (Recommended for Chinese)") + print("-" * 40) + print("pip install paddleocr paddlepaddle") + print() + print("For macOS/Linux (CPU only):") + print(" pip install paddleocr paddlepaddle") + print() + print("For Windows (CPU only):") + print(" pip install paddleocr paddlepaddle") + print() + print("For GPU support:") + print(" # CUDA 11.2") + print(" pip install paddlepaddle-gpu==2.4.0 -f https://www.paddlepaddle.org.cn/whl/stable.html") + print(" # CUDA 11.6") + print(" pip install paddlepaddle-gpu==2.4.0 -f https://www.paddlepaddle.org.cn/whl/lite.html") + + print("\n[OPTION 2] Install Tesseract") + print("-" * 40) + print("macOS:") + print(" brew install tesseract") + print() + print("Ubuntu/Debian:") + print(" sudo apt update && sudo apt install tesseract-ocr") + print() + print("Windows:") + print(" Download from: https://github.com/UB-Mannheim/tesseract/wiki") + + print("\n[OPTION 3] Install Tesseract Python bindings") + print("-" * 40) + print("pip install pytesseract pillow opencv-python numpy") + + print("\n[OPTION 4] Install all at once") + print("-" * 40) + print("pip install paddleocr paddlepaddle pytesseract pillow opencv-python numpy") + + print("\n" + "=" * 60) + + +def check_all_dependencies(interactive: bool = True) -> bool: + """ + Check all dependencies and optionally install missing ones. + + Returns: + True if all dependencies are satisfied + """ + print("\n" + "=" * 60) + print("Checking Super OCR Dependencies") + print("=" * 60) + + all_ok = True + missing = [] + + # Check PaddleOCR + print("\n[1/3] Checking PaddleOCR...") + ok, missing_pkgs = check_paddleocr() + if ok: + print("[OK] PaddleOCR is available") + else: + print(f"[MISSING] Missing: {', '.join(missing_pkgs)}") + all_ok = False + missing.extend(missing_pkgs) + + # Check Tesseract binary + print("\n[2/3] Checking Tesseract binary...") + ok, info = check_tesseract_binary() + if ok: + print(f"[OK] Tesseract is available: {info.split()[2] if info else 'unknown'}") + else: + print("[MISSING] Tesseract binary not found") + print(" Install: brew install tesseract (macOS) or apt install tesseract-ocr (Ubuntu)") + all_ok = False + + # Check Tesseract Python bindings + print("\n[3/3] Checking Tesseract Python bindings...") + ok, missing_pkgs = check_pytesseract() + if ok: + print("[OK] Tesseract Python bindings are available") + else: + print(f"[MISSING] Missing: {', '.join(missing_pkgs)}") + all_ok = False + + # Summary + print("\n" + "=" * 60) + if all_ok: + print("[OK] All dependencies satisfied!") + return True + else: + print("[WARNING] Some dependencies are missing") + print(f"Missing: {', '.join(missing)}") + + if interactive: + response = input("\nAuto-install missing dependencies? [y/N]: ") + if response.lower() == 'y': + # Install PaddleOCR if missing + if 'paddleocr' in missing or 'paddlepaddle' in missing: + print("\n[INSTALL] Installing PaddleOCR...") + auto_install('paddleocr') + + # Install Tesseract packages if missing + if any(pkg in missing for pkg in ['pytesseract', 'PIL', 'cv2', 'numpy']): + print("\n[INSTALL] Installing Tesseract packages...") + auto_install('pytesseract') + + print("\n" + "=" * 60) + print("Manual Installation:") + print("=" * 60) + print_installation_guide() + + return False + + +def main(): + import argparse + + parser = argparse.ArgumentParser( + description='Super OCR Dependencies Checker and Installer' + ) + parser.add_argument( + '--check', '-c', + action='store_true', + help='Check dependencies without installing' + ) + parser.add_argument( + '--install', '-i', + action='store_true', + help='Auto-install missing dependencies' + ) + parser.add_argument( + '--dependency', '-d', + choices=['paddleocr', 'pytesseract', 'all'], + default='all', + help='Specific dependency to check/install' + ) + parser.add_argument( + '--guide', '-g', + action='store_true', + help='Show installation guide only' + ) + parser.add_argument( + '--quiet', '-q', + action='store_true', + help='Suppress output' + ) + + args = parser.parse_args() + + if args.guide: + print_installation_guide() + return 0 + + if args.check or args.install: + if args.dependency == 'all': + success = check_all_dependencies(interactive=not args.quiet and not args.install) + else: + ok, missing, cmd = check_dependency(args.dependency) + if ok: + print(f"[OK] {args.dependency} is available") + return 0 + else: + print(f"[MISSING] {args.dependency}: {', '.join(missing)}") + if args.install: + success = auto_install(args.dependency) + return 0 if success else 1 + return 1 + else: + # Default: interactive check + success = check_all_dependencies(interactive=True) + return 0 if success else 1 + + +if __name__ == '__main__': + sys.exit(main()) \ No newline at end of file diff --git a/skills/super-ocr/scripts/engine/__init__.py b/skills/super-ocr/scripts/engine/__init__.py new file mode 100644 index 0000000..4dea4e7 --- /dev/null +++ b/skills/super-ocr/scripts/engine/__init__.py @@ -0,0 +1 @@ +# Engine module diff --git a/skills/super-ocr/scripts/engine/__macvision__.py b/skills/super-ocr/scripts/engine/__macvision__.py new file mode 100644 index 0000000..3b65cec --- /dev/null +++ b/skills/super-ocr/scripts/engine/__macvision__.py @@ -0,0 +1 @@ +# MacVision OCR module diff --git a/skills/super-ocr/scripts/engine/__pycache__/__init__.cpython-311.pyc b/skills/super-ocr/scripts/engine/__pycache__/__init__.cpython-311.pyc new file mode 100644 index 0000000..01aaeee Binary files /dev/null and b/skills/super-ocr/scripts/engine/__pycache__/__init__.cpython-311.pyc differ diff --git a/skills/super-ocr/scripts/engine/__pycache__/paddle.cpython-311.pyc b/skills/super-ocr/scripts/engine/__pycache__/paddle.cpython-311.pyc new file mode 100644 index 0000000..57a6e1f Binary files /dev/null and b/skills/super-ocr/scripts/engine/__pycache__/paddle.cpython-311.pyc differ diff --git a/skills/super-ocr/scripts/engine/__pycache__/selector.cpython-311.pyc b/skills/super-ocr/scripts/engine/__pycache__/selector.cpython-311.pyc new file mode 100644 index 0000000..11f7379 Binary files /dev/null and b/skills/super-ocr/scripts/engine/__pycache__/selector.cpython-311.pyc differ diff --git a/skills/super-ocr/scripts/engine/__pycache__/tesseract.cpython-311.pyc b/skills/super-ocr/scripts/engine/__pycache__/tesseract.cpython-311.pyc new file mode 100644 index 0000000..ea1fbaf Binary files /dev/null and b/skills/super-ocr/scripts/engine/__pycache__/tesseract.cpython-311.pyc differ diff --git a/skills/super-ocr/scripts/engine/macvision.py b/skills/super-ocr/scripts/engine/macvision.py new file mode 100644 index 0000000..0584ae8 --- /dev/null +++ b/skills/super-ocr/scripts/engine/macvision.py @@ -0,0 +1,153 @@ +#!/usr/bin/env python3 +""" +MacVisionOCR - macOS Vision Text Recognition via Swift script + +Uses Apple's Vision Framework via Swift script (confirmed working). + +Requirements: + - macOS 10.15+ (Catalina) + - Swift (built-in on macOS) +""" + +import subprocess +import sys +from pathlib import Path +from typing import Dict, List + +# Path to Swift script +SWIFT_SCRIPT_PATH = Path(__file__).parent / "macvision_swift.swift" + + +class MacVisionOCR: + """macOS Vision OCR wrapper using Swift script""" + + def __init__(self, verbose: bool = False): + """Initialize MacVisionOCR processor.""" + self.verbose = verbose + + if sys.platform != 'darwin': + raise RuntimeError("MacVisionOCR only works on macOS") + + if self.verbose: + print("[INFO] MacVisionOCR initialized (via Swift)") + + def _estimate_confidence(self, text: str) -> float: + """Estimate OCR confidence from text quality.""" + if not text: + return 0.0 + + printable = sum(1 for c in text if c.isprintable() or c in '\n\r\t') + length_factor = min(1.0, len(text) / 100) + quality = printable / max(len(text), 1) + + confidence = 0.85 + (0.15 * quality * length_factor) + return round(min(confidence, 1.0), 4) + + def extract(self, image_path: str) -> Dict: + """Extract text from image using Mac Vision OCR via Swift.""" + from time import time + + if sys.platform != 'darwin': + return { + 'text': '', + 'confidence': 0.0, + 'error': 'MacVisionOCR only works on macOS', + 'processing_time_ms': 0 + } + + start_time = time() + + try: + # Run Swift script with image path as argument + result = subprocess.run( + ['swift', str(SWIFT_SCRIPT_PATH), image_path], + capture_output=True, + text=True, + timeout=60 + ) + + if result.returncode != 0: + return { + 'text': '', + 'confidence': 0.0, + 'error': result.stderr.strip(), + 'processing_time_ms': (time() - start_time) * 1000 + } + + # Parse Chinese output + lines = result.stdout.strip().split('\n') + text_lines = [] + all_confidences = [] + + current_text = None + for line in lines: + if line.startswith('文本:'): + current_text = line[3:].strip() + elif line.startswith('置信度:') and current_text: + try: + conf_str = line[4:].strip() + # Swift returns confidence as percentage (0-100) + # Output format: "置信度:50.00%" -> need to divide by 100 + numeric_part = conf_str.rstrip('%').strip() + confidence = float(numeric_part) / 100.0 + text_lines.append(current_text) + all_confidences.append(confidence) + current_text = None + except (ValueError, IndexError): + pass + + full_text = '\n'.join(text_lines) + processing_time = (time() - start_time) * 1000 + avg_confidence = sum(all_confidences) / len(all_confidences) if all_confidences else 0.0 + + return { + 'text': full_text.strip(), + 'confidence': round(avg_confidence, 4), + 'line_count': len(text_lines), + 'processing_time_ms': round(processing_time, 2) + } + + except subprocess.TimeoutExpired: + return { + 'text': '', + 'confidence': 0.0, + 'error': 'MacVisionOCR timeout', + 'processing_time_ms': 60000 + } + except Exception as e: + processing_time = (time() - start_time) * 1000 + return { + 'text': '', + 'confidence': 0.0, + 'error': f"MacVision error: {str(e)}", + 'processing_time_ms': round(processing_time, 2) + } + + def batch_extract(self, image_paths: List[str]) -> List[Dict]: + """Process multiple images""" + return [self.extract(path) for path in image_paths] + + +if __name__ == '__main__': + import argparse + + if sys.platform != 'darwin': + print("[ERROR] MacVisionOCR only works on macOS") + sys.exit(1) + + if not SWIFT_SCRIPT_PATH.exists(): + print(f"[ERROR] Swift script not found: {SWIFT_SCRIPT_PATH}") + sys.exit(1) + + parser = argparse.ArgumentParser(description='macOS Vision OCR via Swift') + parser.add_argument('image', help='Image file to process') + parser.add_argument('--verbose', '-v', action='store_true') + args = parser.parse_args() + + processor = MacVisionOCR(verbose=args.verbose) + result = processor.extract(args.image) + + print(f"\nText:\n{result['text']}") + print(f"\nConfidence: {result['confidence']:.4f}") + print(f"Lines: {result.get('line_count', 0)}") + print(f"Time: {result.get('processing_time_ms', 0):.2f}ms") \ No newline at end of file diff --git a/skills/super-ocr/scripts/engine/macvision_swift.swift b/skills/super-ocr/scripts/engine/macvision_swift.swift new file mode 100644 index 0000000..d14e4a9 --- /dev/null +++ b/skills/super-ocr/scripts/engine/macvision_swift.swift @@ -0,0 +1,70 @@ +import Foundation +import Vision +import AppKit + +// Swift 5.9+ 可以用 CommandLine.arguments,兼容旧版本用下面的方式 +let args = ProcessInfo.processInfo.arguments + +guard args.count >= 2 else { + print("Usage: swift macvision_swift.swift <image_path>") + exit(1) +} + +let imagePath = args[1] + +// 1. 加载图片 +guard let image = NSImage(contentsOfFile: imagePath) else { + print("❌ 无法加载图片: \(imagePath)") + exit(1) +} + +// 2. 转换为 CGImage(Vision 需要) +guard let tiffData = image.tiffRepresentation, + let cgImage = NSBitmapImageRep(data: tiffData)?.cgImage else { + print("❌ 无法转换图片") + exit(1) +} + +// 3. 设置信号量等待异步完成 +let semaphore = DispatchSemaphore(value: 0) +var results: [(text: String, confidence: Float)] = [] + +// 4. 创建 OCR 请求 +let request = VNRecognizeTextRequest { request, error in + defer { semaphore.signal() } // 关键:完成后释放信号量 + + if let error = error { + print("❌ 识别错误:\(error)") + return + } + + guard let observations = request.results as? [VNRecognizedTextObservation] else { + print("❌ 无结果") + return + } + + for observation in observations { + guard let candidate = observation.topCandidates(1).first else { continue } + results.append((candidate.string, candidate.confidence)) + } +} + +// 5. 配置识别参数 +request.recognitionLanguages = ["zh-Hans", "zh-Hant", "en-US"] // 支持中文 +request.usesLanguageCorrection = true // 启用语言校正 + +// 6. 执行识别 +let handler = VNImageRequestHandler(cgImage: cgImage, options: [:]) + +do { + try handler.perform([request]) + _ = semaphore.wait(timeout: .now() + 30) // 等待最多 30 秒 + + // 输出结果 + for (text, conf) in results { + print("文本:\(text)") + print("置信度:\(String(format: "%.2f", conf * 100))%") + } +} catch { + print("❌ 执行错误:\(error)") +} diff --git a/skills/super-ocr/scripts/engine/paddle.py b/skills/super-ocr/scripts/engine/paddle.py new file mode 100644 index 0000000..2d04883 --- /dev/null +++ b/skills/super-ocr/scripts/engine/paddle.py @@ -0,0 +1,220 @@ +#!/usr/bin/env python3 +""" +PaddleOCR wrapper - High accuracy Chinese OCR engine + +Compatible with PaddleOCR 3.4.0+ API (predict() method returns list) +Based on Emma's testing: result[0][0][1][0] for text, result[0][0][1][1] for confidence +""" + +import time +from pathlib import Path +from typing import Dict, List, Optional + + +class PaddleOCR: + """PaddleOCR processor for high-accuracy text extraction""" + + def __init__( + self, + verbose: bool = False, + lang: str = 'ch', + use_angle_cls: bool = True + ): + """Initialize PaddleOCR - lang and use_angle_cls parameters""" + self.verbose = verbose + self.lang = lang + self.use_angle_cls = use_angle_cls + self._init_ocr() + + def _init_ocr(self) -> None: + """Initialize PaddleOCR model""" + from paddleocr import PaddleOCR + + self.ocr = PaddleOCR(lang=self.lang, use_angle_cls=self.use_angle_cls) + + def extract(self, image_path: str) -> Dict: + """ + Extract text from image using PaddleOCR. + + Args: + image_path: Path to input image + + Returns: + Dict with text, confidence, results, processing time + """ + if self.verbose: + print(f"[PaddleOCR] Processing: {image_path}") + + start_time = time.time() + + try: + # Run OCR - using predict() for PaddleOCR 3.4.0+ + result = self.ocr.predict(image_path) + + processing_time = time.time() - start_time + + # Parse results - legacy format: [[box], [text, confidence]] + parsed = self._parse_results(result) + parsed['processing_time_ms'] = round(processing_time * 1000, 2) + + return parsed + + except Exception as e: + processing_time = time.time() - start_time + return { + 'text': '', + 'confidence': 0.0, + 'error': str(e), + 'results': [], + 'processing_time_ms': round(processing_time * 1000, 2) + } + + def _parse_results(self, results) -> Dict: + """ + Parse PaddleOCR 3.4.0+ output format. + + PaddleOCR 3.4.0+ predict() returns dict with: + - rec_texts: list of detected text strings + - rec_scores: list of confidence scores + - dt_polys: list of text polygon coordinates + + Returns: + Dict with text, confidence, results, line_count + """ + if not results or not results[0]: + return { + 'text': '', + 'confidence': 0.0, + 'results': [], + 'error': 'No text detected' + } + + # New format: result[0] is a dict with 'rec_texts' and 'rec_scores' + result_dict = results[0] + + if isinstance(result_dict, dict): + texts = result_dict.get('rec_texts', []) + scores = result_dict.get('rec_scores', []) + + if not texts: + return { + 'text': '', + 'confidence': 0.0, + 'results': [], + 'error': 'No text detected' + } + + # Combine all text (PaddleOCR already splits by lines) + full_text = '\n'.join(texts) + + # Calculate average confidence + avg_confidence = sum(scores) / len(scores) if scores else 0.0 + + # Build detailed results + detailed_results = [] + for i, (text, score) in enumerate(zip(texts, scores)): + # Get bbox if available (dt_polys is list of arrays) + dt_polys = result_dict.get('dt_polys', []) + bbox = None + if i < len(dt_polys): + try: + poly = dt_polys[i] + if hasattr(poly, 'tolist'): + bbox = poly.tolist() + else: + bbox = poly + except: + bbox = None + + detailed_results.append({ + 'text': text, + 'confidence': round(score, 4), + 'bbox': bbox + }) + + return { + 'text': full_text.strip(), + 'confidence': round(avg_confidence, 4), + 'results': detailed_results, + 'line_count': len(texts) + } + else: + # Fallback: handle legacy format if still used + return self._parse_results_legacy(results) + + def _parse_results_legacy(self, results) -> Dict: + """ + Legacy parser for backward compatibility. + Old format: [[bbox], [text, confidence]] + """ + if not results or not results[0]: + return { + 'text': '', + 'confidence': 0.0, + 'results': [], + 'error': 'No text detected' + } + + text_lines = [] + all_confidences = [] + + for line in results: + if len(line) < 2: + continue + + box = line[0] + + if isinstance(line[1], (list, tuple)) and len(line[1]) >= 2: + text, confidence = line[1][0], line[1][1] + else: + text, confidence = str(line[1]), 0.0 + + text_lines.append(text) + all_confidences.append(confidence) + + full_text = '\n'.join(text_lines) + avg_confidence = sum(all_confidences) / len(all_confidences) if all_confidences else 0.0 + + detailed_results = [] + for line in results: + if len(line) >= 2: + box = line[0] + if isinstance(line[1], (list, tuple)) and len(line[1]) >= 2: + text, confidence = line[1][0], line[1][1] + else: + text, confidence = str(line[1]), 0.0 + + detailed_results.append({ + 'text': text, + 'confidence': confidence, + 'bbox': box + }) + + return { + 'text': full_text.strip(), + 'confidence': round(avg_confidence, 4), + 'results': detailed_results, + 'line_count': len(detailed_results) + } + + def batch_extract(self, image_paths: List[str]) -> List[Dict]: + """Process multiple images""" + return [self.extract(path) for path in image_paths] + + +if __name__ == '__main__': + import argparse + + parser = argparse.ArgumentParser(description='PaddleOCR wrapper') + parser.add_argument('image', help='Image file to process') + parser.add_argument('--lang', default='ch', help='Language code (ch, en, etc.)') + parser.add_argument('--verbose', '-v', action='store_true') + args = parser.parse_args() + + processor = PaddleOCR(verbose=args.verbose, lang=args.lang) + result = processor.extract(args.image) + + print(f"\nText:\n{result['text']}") + print(f"\nConfidence: {result['confidence']:.4f}") + print(f"Lines detected: {result.get('line_count', 0)}") + print(f"Time: {result.get('processing_time_ms', 0):.2f}ms") \ No newline at end of file diff --git a/skills/super-ocr/scripts/engine/selector.py b/skills/super-ocr/scripts/engine/selector.py new file mode 100644 index 0000000..968fdb1 --- /dev/null +++ b/skills/super-ocr/scripts/engine/selector.py @@ -0,0 +1,183 @@ +#!/usr/bin/env python3 +""" +Engine selector - Intelligent OCR engine selection logic + +Rules: +1. Image contains Chinese characters → PaddleOCR (better Chinese support) +2. Image is simple text, English only → Tesseract (faster, lighter) +3. User explicitly requests engine → Use requested engine +4. Auto mode, mixed/unknown → PaddleOCR (higher accuracy) + +Multi-engine parallel mode: +- Tesseract + PaddleOCR + MacVision (macOS only) +- Agent择优 based on confidence, language support, and speed +""" + +import re +import sys +from pathlib import Path +from typing import Literal, List, Dict + + +def detect_chinese(content: str) -> bool: + """Check if content contains Chinese characters""" + # Chinese range: \u4e00-\u9fff + return bool(re.search(r'[\u4e00-\u9fff]', content)) + + +def analyze_image_complexity(image_path: str) -> str: + """ + Analyze image complexity to determine optimal engine. + + Returns: + 'simple' or 'complex' + """ + image_path_lower = Path(image_path).name.lower() + + complex_patterns = [ + 'menu', 'invoice', 'contract', 'certificate', + 'exam', 'form', 'table', 'receipt' + ] + + if any(p in image_path_lower for p in complex_patterns): + return 'complex' + + return 'simple' + + +def get_available_engines(image_path: str) -> List[str]: + """ + Get list of available engines for the current platform. + + Args: + image_path: Path to image (for platform-specific hints) + + Returns: + List of engine names: ['tesseract', 'paddle', 'macvision'] + """ + engines = ['tesseract', 'paddle'] # Always available + + # Add MacVision on macOS + if sys.platform == 'darwin': + engines.append('macvision') + + return engines + + +def select_engine( + image_path: str, + requested_engine: Literal['auto', 'tesseract', 'paddle', 'macvision'] = 'auto' +) -> List[str]: + """ + Select engines for OCR processing. + + In multi-engine mode, returns list of engines to run in parallel. + + Args: + image_path: Path to image being processed + requested_engine: User request or 'auto' + + Returns: + List of engine names to use + """ + available = get_available_engines(image_path) + + # Rule 1: User explicitly requested single engine + if requested_engine != 'auto': + if requested_engine in available: + return [requested_engine] + else: + return available # Fallback to all available + + # Rule 2: Check image path for hints + path_lower = Path(image_path).name.lower() + + # Simple screenshots → Tesseract (fastest) + simple_indicators = ['screenshot', 'snap', 'capture', 'screen'] + if any(ind in path_lower for ind in simple_indicators): + return ['tesseract'] + + # Complex documents → All engines (max accuracy) + complex_indicators = ['menu', 'invoice', 'certificate', 'contract', 'receipt'] + if any(ind in path_lower for ind in complex_indicators): + return available # Run all available engines + + # Default: Run all available engines for best results + return available + + +def select_best_result( + results: List[Dict], + preferred_engine: str = 'paddle' +) -> Dict: + """ + Select the best OCR result from multiple engines. + + Args: + results: List of OCR results from different engines + preferred_engine: Preferred engine for tie-breaking + + Returns: + Dict with selected result and metadata + """ + if not results: + return { + 'text': '', + 'confidence': 0.0, + 'error': 'No results', + 'selected_engine': None + } + + # Filter valid results (with text) + valid_results = [r for r in results if r.get('text', '').strip()] + + if not valid_results: + return { + 'text': '', + 'confidence': 0.0, + 'error': 'All engines failed', + 'selected_engine': None + } + + # Calculate weighted score + for r in valid_results: + engine = r.get('engine', 'unknown') + + # Engine quality weights + quality_weights = { + 'paddle': 1.0, + 'macvision': 0.95, + 'tesseract': 0.9 + } + + # Language support weights (optional, can be extended) + language_weights = { + 'paddle': 1.0, # Best for Chinese + 'macvision': 0.85, # Good for English, fair for Chinese + 'tesseract': 0.8 # Good for English, fair for Chinese + } + + # Combined score + base_confidence = r.get('confidence', 0) + quality = quality_weights.get(engine, 0.8) + language = language_weights.get(engine, 0.8) + + r['_score'] = base_confidence * quality * language + r['_quality_weight'] = quality + r['_language_weight'] = language + + # Sort by score + sorted_results = sorted(valid_results, key=lambda x: x.get('_score', 0), reverse=True) + + # Select best + best = sorted_results[0] + + return { + 'text': best.get('text', ''), + 'confidence': best.get('confidence', 0), + 'engine': best.get('engine', 'unknown'), + 'selected_engine': best.get('engine', 'unknown'), + 'processing_time_ms': sum(r.get('processing_time_ms', 0) for r in valid_results), + 'score': best.get('_score', 0), + 'other_results': sorted_results[1:] # Include runner-ups for verification + } \ No newline at end of file diff --git a/skills/super-ocr/scripts/engine/tesseract.py b/skills/super-ocr/scripts/engine/tesseract.py new file mode 100644 index 0000000..28ab6f5 --- /dev/null +++ b/skills/super-ocr/scripts/engine/tesseract.py @@ -0,0 +1,269 @@ +#!/usr/bin/env python3 +""" +Tesseract OCR wrapper with optimized configuration for mixed Chinese/English content +""" + +import logging +import subprocess +import sys +import time +from pathlib import Path +from typing import Dict, List, Optional + +try: + import cv2 + import numpy as np + from PIL import Image +except ImportError: + print("[ERROR] Install dependencies: pip install opencv-python numpy pillow") + sys.exit(1) + + +logging.basicConfig(level=logging.INFO) +logger = logging.getLogger(__name__) + + +class TesseractOCR: + """Tesseract OCR processor with preprocessing pipeline""" + + def __init__( + self, + verbose: bool = False, + lang: str = 'chi_sim+eng', + psm: int = 6, + oem: int = 3 + ): + """ + Initialize Tesseract processor. + + Args: + verbose: Enable detailed logging + lang: Tesseract language code (e.g., 'eng', 'chi_sim', 'chi_sim+eng') + psm: Page segmentation mode (default: 6, uniform block) + oem: OCR engine mode (default: 3, LSTM only) + """ + self.verbose = verbose + self.lang = lang + self.psm = psm + self.oem = oem + + # Check tesseract availability + self._check_tesseract() + + def _check_tesseract(self) -> bool: + """Check if tesseract is installed""" + try: + result = subprocess.run( + ['tesseract', '--version'], + capture_output=True, + text=True, + timeout=5 + ) + if self.verbose: + logger.info(f"Tesseract version: {result.stdout.split()[2]}") + return True + except (subprocess.TimeoutExpired, FileNotFoundError, IndexError): + logger.error("Tesseract not found. Install with:") + logger.error(" macOS: brew install tesseract") + logger.error(" Ubuntu: sudo apt install tesseract-ocr") + logger.error(" Windows: Download from https://github.com/UB-Mannheim/tesseract/wiki") + return False + + def _preprocess_image(self, image_path: str) -> str: + """ + Apply preprocessing pipeline. + + Returns: + Path to processed image + """ + if self.verbose: + logger.info("Preprocessing image...") + + start_time = time.time() + + # Read image + img = cv2.imread(image_path) + if img is None: + raise ValueError(f"Could not load image: {image_path}") + + # Convert to grayscale + gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) + + # Apply bilateral filter (noise reduction + edge preservation) + bilateral = cv2.bilateralFilter(gray, 9, 75, 75) + + # Adaptive thresholding for low contrast images + min_val, max_val, _, _ = cv2.minMaxLoc(bilateral) + contrast = max_val - min_val + + if contrast < 100: # Low contrast + processed = cv2.adaptiveThreshold( + bilateral, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, + cv2.THRESH_BINARY, 11, 2 + ) + else: + processed = bilateral + + # Save processed image (temp file) + input_path = Path(image_path) + processed_path = input_path.parent / f"{input_path.stem}_tess_processed.png" + cv2.imwrite(str(processed_path), processed) + + if self.verbose: + logger.info(f"Preprocessing completed in {time.time() - start_time:.2f}s") + + return str(processed_path) + + def _run_tesseract( + self, + image_path: str, + lang: Optional[str] = None, + psm: Optional[int] = None, + oem: Optional[int] = None + ) -> Dict: + """ + Run Tesseract OCR. + + Returns: + Dict with text, confidence, timing + """ + if lang is None: + lang = self.lang + if psm is None: + psm = self.psm + if oem is None: + oem = self.oem + + # Run tesseract + cmd = [ + 'tesseract', image_path, 'stdout', + '-l', lang, + '--psm', str(psm), + '--oem', str(oem), + '_stdout' + ] + + if self.verbose: + logger.info(f"Running: {' '.join(cmd)}") + + start_time = time.time() + + try: + result = subprocess.run( + cmd, + capture_output=True, + text=True, + timeout=60 + ) + + processing_time = time.time() - start_time + + if result.returncode != 0: + logger.error(f"Tesseract error: {result.stderr}") + return { + 'text': '', + 'confidence': 0.0, + 'error': result.stderr, + 'processing_time_ms': processing_time * 1000 + } + + # Extract confidence if available + text = result.stdout.strip() + confidence = self._estimate_confidence(text) + + return { + 'text': text, + 'confidence': confidence, + 'processing_time_ms': processing_time * 1000 + } + + except subprocess.TimeoutExpired: + return { + 'text': '', + 'confidence': 0.0, + 'error': 'Tesseract timeout', + 'processing_time_ms': 60000 + } + + def _estimate_confidence(self, text: str) -> float: + """ + Estimate OCR confidence from output quality. + + Simple heuristic: longer text with fewer garbage characters = higher confidence + """ + if not text: + return 0.0 + + # Count printable characters + printable = sum(1 for c in text if c.isprintable() or c in '\n\r\t') + + # Length factor (more text = more reliable) + length_factor = min(1.0, len(text) / 100) + + # Quality factor + quality = printable / max(len(text), 1) + + # Combined score + confidence = (0.6 * quality) + (0.4 * length_factor) + + return round(confidence, 2) + + def extract(self, image_path: str) -> Dict: + """ + Extract text from image using Tesseract. + + Args: + image_path: Path to input image + + Returns: + Dict with text, confidence, processing time + """ + if self.verbose: + logger.info(f"Processing: {image_path}") + + start_time = time.time() + + # Preprocess + processed_path = self._preprocess_image(image_path) + + try: + # Run OCR + result = self._run_tesseract( + processed_path, + lang=self.lang, + psm=self.psm, + oem=self.oem + ) + + # Clean up temp file + Path(processed_path).unlink(missing_ok=True) + + result['processing_time_ms'] = round(time.time() - start_time, 2) + + return result + + except Exception as e: + Path(processed_path).unlink(missing_ok=True) + return { + 'text': '', + 'confidence': 0.0, + 'error': str(e), + 'processing_time_ms': (time.time() - start_time) * 1000 + } + + +if __name__ == '__main__': + import argparse + + parser = argparse.ArgumentParser(description='Tesseract OCR wrapper') + parser.add_argument('image', help='Image file to process') + parser.add_argument('--lang', default='chi_sim+eng', help='Language code') + parser.add_argument('--verbose', '-v', action='store_true') + args = parser.parse_args() + + processor = TesseractOCR(verbose=args.verbose, lang=args.lang) + result = processor.extract(args.image) + + print(f"\nText:\n{result['text']}") + print(f"\nConfidence: {result['confidence']:.2%}") + print(f"Time: {result.get('processing_time_ms', 0):.2f}ms") \ No newline at end of file diff --git a/skills/super-ocr/scripts/main.py b/skills/super-ocr/scripts/main.py new file mode 100644 index 0000000..a8b4f3a --- /dev/null +++ b/skills/super-ocr/scripts/main.py @@ -0,0 +1,311 @@ +#!/usr/bin/env python3 +""" +Super OCR - Main entry point with multi-engine parallel support + +Usage: + python main.py --image path/to/image.png [--engine auto|tesseract|paddle|macvision|all] + python main.py --images ./images/*.png [--output ./results] + +Examples: + # Auto mode (recommended) - runs all available engines on macOS + python main.py --image screenshot.png + + # Force Tesseract + python main.py --image document.jpg --engine tesseract + + # Force PaddleOCR (high accuracy Chinese) + python main.py --image chinese_menu.png --engine paddle + + # Force MacVision (macOS only) + python main.py --image document.png --engine macvision + + # Run all available engines (macOS: tesseract + paddle + macvision) + python main.py --image complex_doc.png --engine all + + # Batch mode with verbose output + python main.py --images ./invoices/*.png --output ./results --verbose +""" + +import argparse +import json +import os +import sys +import time +from concurrent.futures import ThreadPoolExecutor, as_completed +from pathlib import Path +from typing import Dict, List, Optional + +# Add parent to path for imports when running from skill directory +sys.path.insert(0, str(Path(__file__).parent)) + +try: + from engine.selector import select_engine, get_available_engines, select_best_result + from engine.tesseract import TesseractOCR + from engine.paddle import PaddleOCR + from output_formatter import format_output + from dependencies import check_all_dependencies +except ImportError as e: + print(f"[ERROR] Import failed: {e}") + print("\n[INSTALL INSTRUCTIONS]") + print("="*60) + print("Missing dependencies detected. Please install:") + print() + print(" pip install paddleocr paddlepaddle pytesseract pillow opencv-python numpy") + print() + print("Or for macOS with Tesseract:") + print() + print(" brew install tesseract") + print(" pip install paddleocr paddlepaddle pytesseract pillow opencv-python numpy") + print() + print("For other platforms, see: https://github.com/openclaw/super-ocr") + print("="*60) + sys.exit(1) + +# Try to import MacVision if on macOS +macvision_available = False +if sys.platform == 'darwin': + try: + from engine.macvision import MacVisionOCR + macvision_available = True + print("[INFO] MacVision OCR available") + except ImportError: + print("[WARN] MacVision OCR not available (pip install pyobjc)") + +class OCRProcessor: + """Main OCR processor with multi-engine parallel support""" + + def __init__(self, engine: str = 'auto', verbose: bool = False): + """ + Initialize OCR processor. + + Args: + engine: 'auto', 'tesseract', 'paddle', 'macvision', or 'all' + verbose: Enable detailed logging + """ + self.engine = engine.lower() + self.verbose = verbose + self.engines_to_use = [] + self.processors = {} + + def _select_and_init(self, image_path: str) -> None: + """Select engines based on content and initialize all""" + self.engines_to_use = select_engine(image_path, self.engine) + + if self.verbose: + print(f"[INFO] Using engines: {', '.join(self.engines_to_use)}") + + # Initialize selected engines + for eng in self.engines_to_use: + try: + if eng == 'tesseract': + self.processors['tesseract'] = TesseractOCR(verbose=self.verbose) + elif eng == 'paddle': + self.processors['paddle'] = PaddleOCR(verbose=self.verbose) + elif eng == 'macvision': + if macvision_available: + self.processors['macvision'] = MacVisionOCR(verbose=self.verbose) + else: + if self.verbose: + print(f"[WARN] MacVision not available on this platform") + else: + if self.verbose: + print(f"[WARN] Unknown engine: {eng}") + except Exception as e: + if self.verbose: + print(f"[ERROR] Failed to initialize {eng}: {e}") + + def extract_parallel(self, image_path: str) -> Dict: + """ + Extract text from image using multiple engines in parallel. + + Args: + image_path: Path to input image + + Returns: + Dict with text, confidence, selected_engine, average confidence, etc. + """ + if not self.processors: + self._select_and_init(image_path) + + if not self.processors: + return { + 'text': '', + 'confidence': 0.0, + 'error': 'No engines available', + 'processing_time_ms': 0 + } + + start_time = time.time() + results = [] + + def run_engine(engine_name: str, processor): + try: + result = processor.extract(image_path) + result['engine'] = engine_name + return result + except Exception as e: + return { + 'engine': engine_name, + 'text': '', + 'confidence': 0.0, + 'error': str(e), + 'processing_time_ms': 0 + } + + # Run engines in parallel + with ThreadPoolExecutor(max_workers=len(self.processors)) as executor: + futures = { + executor.submit(run_engine, name, proc): name + for name, proc in self.processors.items() + } + + for future in as_completed(futures): + result = future.result() + results.append(result) + + if self.verbose: + engine_name = result.get('engine', 'unknown') + if result.get('error'): + print(f"[{engine_name}] Error: {result['error']}") + else: + print(f"[{engine_name}] Confidence: {result.get('confidence', 0):.2%}, Time: {result.get('processing_time_ms', 0):.2f}ms") + + # Select best result using agent择优 logic + best = select_best_result( + results, + preferred_engine='paddle' # PaddleOCR preferred for Chinese + ) + + # Add summary info + best['processing_time_ms'] = round((time.time() - start_time) * 1000, 2) + best['total_engines'] = len(results) + best['engines_used'] = self.engines_to_use + + return best + + def extract(self, image_path: str) -> Dict: + """ + Extract text from image (legacy single-engine mode). + + Args: + image_path: Path to input image + + Returns: + Dict with text, confidence, engine, timing info + """ + return self.extract_parallel(image_path) + + def batch_extract(self, image_paths: List[str]) -> List[Dict]: + """Process multiple images""" + return [self.extract(path) for path in image_paths] + + +def main(): + parser = argparse.ArgumentParser( + description='Super OCR - Multi-engine parallel text extraction with intelligent selection' + ) + + # Input options + input_group = parser.add_mutually_exclusive_group(required=True) + input_group.add_argument('--image', help='Single image file to process') + input_group.add_argument('--images', nargs='+', help='Multiple image files') + + # Engine selection + parser.add_argument( + '--engine', + choices=['auto', 'tesseract', 'paddle', 'macvision', 'all'], + default='auto', + help='OCR engine(s) to use (default: auto)' + ) + + # Output options + parser.add_argument( + '--output', '-o', + help='Output directory for results (default: stdout)' + ) + parser.add_argument( + '--format', + choices=['text', 'json', 'structured'], + default='json', + help='Output format (default: json)' + ) + parser.add_argument( + '--verbose', '-v', + action='store_true', + help='Enable verbose output' + ) + + args = parser.parse_args() + + # Check dependencies + if args.engine in ['auto', 'paddle', 'all']: + check_all_dependencies(interactive=False) + + # Warn about macOS + if sys.platform != 'darwin' and args.engine in ['macvision', 'all']: + print("[WARN] MacVision only available on macOS") + + # Create processor + processor = OCRProcessor( + engine=args.engine, + verbose=args.verbose + ) + + # Process images + if args.image: + image_paths = [args.image] + else: + # Expand glob patterns + image_paths = [] + for pattern in args.images: + image_paths.extend(sorted(Path().glob(pattern))) + image_paths = [str(p) for p in image_paths] + + if args.verbose: + print(f"\n[INFO] Processing {len(image_paths)} image(s)") + + # Extract text + results = processor.batch_extract(image_paths) + + # Format and output + output_func = format_output(args.format) + + if args.output: + # Save to files + output_path = Path(args.output) + output_path.mkdir(parents=True, exist_ok=True) + + for image_path, result in zip(image_paths, results): + stem = Path(image_path).stem + output_file = output_path / f"{stem}_ocr.json" + + with open(output_file, 'w', encoding='utf-8') as f: + json.dump(result, f, ensure_ascii=False, indent=2) + + if args.verbose: + print(f"[OK] Saved: {output_file}") + else: + # Print to stdout + for image_path, result in zip(image_paths, results): + print(f"\n{'='*60}") + print(f"File: {image_path}") + print(f"Selected Engine: {result.get('selected_engine', 'unknown')}") + print(f"Confidence: {result.get('confidence', 0):.2%}") + print(f"Total Engines: {result.get('total_engines', 1)}") + print(f"Processes: {', '.join(result.get('engines_used', []))}") + print(f"Time: {result.get('processing_time_ms', 0):.2f}ms") + print(f"{'='*60}") + + if result.get('error'): + print(f"[ERROR] {result['error']}") + else: + print(output_func(result)) + + # Summary + total_time = sum(r.get('processing_time_ms', 0) for r in results) + if args.verbose and len(results) > 1: + print(f"\n[INFO] Processed {len(results)} images in {total_time:.2f}ms") + + +if __name__ == '__main__': + main() \ No newline at end of file diff --git a/skills/super-ocr/scripts/output_formatter.py b/skills/super-ocr/scripts/output_formatter.py new file mode 100644 index 0000000..0279230 --- /dev/null +++ b/skills/super-ocr/scripts/output_formatter.py @@ -0,0 +1,143 @@ +#!/usr/bin/env python3 +""" +Output formatter - Convert OCR results to various formats +""" + +import json +from typing import Dict, List + + +def format_text(result: Dict) -> str: + """Return clean text only""" + return result.get('text', '') + + +def format_json(result: Dict) -> str: + """Return full JSON output""" + return json.dumps(result, ensure_ascii=False, indent=2) + + +def format_structured(result: Dict) -> str: + """ + Return structured format with key information highlighted. + + Format: + --- + Text: [extracted text] + + Stats: + - Engine: [engine used] + - Confidence: [score] + - Time: [processing time] + - Lines: [line count] + --- + """ + text = result.get('text', '') + engine = result.get('engine', 'unknown') + confidence = result.get('confidence', 0) + time_ms = result.get('processing_time_ms', 0) + line_count = result.get('line_count', len(text.split('\n'))) + + # Truncate long text + display_text = text + if len(text) > 500: + display_text = text[:500] + '\n... (truncated)' + + output = [ + "---", + "Text:", + display_text, + "", + "Stats:", + f"- Engine: {engine}", + f"- Confidence: {confidence:.2%}" if isinstance(confidence, (int, float)) else f"- Confidence: N/A", + f"- Time: {time_ms:.2f}ms", + f"- Lines: {line_count}", + "---" + ] + + return '\n'.join(output) + + +def format_verbose(result: Dict) -> str: + """Return all available information""" + output = [ + "=" * 60, + "OCR Result (Verbose)", + "=" * 60, + f"Engine: {result.get('engine', 'N/A')}", + f"Confidence: {result.get('confidence', 0):.4f}", + f"Processing Time: {result.get('processing_time_ms', 0):.2f}ms", + ] + + # Error info + if 'error' in result and result['error']: + output.extend([ + "", + "ERROR:", + result['error'], + ]) + + # Text + output.extend([ + "", + "Extracted Text:", + "-" * 40, + result.get('text', ''), + "-" * 40, + ]) + + # Detailed results (if available) + if 'results' in result and result['results']: + output.extend([ + "", + "Detailed Results:", + f"{'Text':<30} | {'Confidence':<12} | {'BBox'}" + ]) + + for item in result['results'][:20]: # Limit to 20 lines + text = item.get('text', '')[:28] + confidence = item.get('confidence', 0) + bbox = str(item.get('bbox', [])) + + output.append(f"{text:<30} | {confidence:<12.4f} | {bbox}") + + output.append("=" * 60) + + return '\n'.join(output) + + +# Format registry +FORMATTERS = { + 'text': format_text, + 'json': format_json, + 'structured': format_structured, + 'verbose': format_verbose +} + + +def format_output(format_name: str): + """Get formatter function by name""" + return FORMATTERS.get(format_name, format_json) + + +def get_available_formats() -> List[str]: + """Return list of available output formats""" + return list(FORMATTERS.keys()) + + +if __name__ == '__main__': + # Test formatter + test_result = { + 'text': '这是一个测试\nAnother line', + 'engine': 'paddle', + 'confidence': 0.95, + 'processing_time_ms': 123.45, + 'line_count': 2 + } + + for fmt in get_available_formats(): + print(f"\n{'#'*60}") + print(f"Format: {fmt}") + print('#'*60) + print(format_output(fmt)(test_result)) \ No newline at end of file diff --git a/skills/super-ocr/scripts/preprocessing/__init__.py b/skills/super-ocr/scripts/preprocessing/__init__.py new file mode 100644 index 0000000..0f91017 --- /dev/null +++ b/skills/super-ocr/scripts/preprocessing/__init__.py @@ -0,0 +1 @@ +# Preprocessing module \ No newline at end of file diff --git a/skills/super-ocr/scripts/preprocessing/preprocessor.py b/skills/super-ocr/scripts/preprocessing/preprocessor.py new file mode 100644 index 0000000..3d44f50 --- /dev/null +++ b/skills/super-ocr/scripts/preprocessing/preprocessor.py @@ -0,0 +1,236 @@ +#!/usr/bin/env python3 +""" +Preprocessor - Image preprocessing utilities for OCR + +This module provides various image preprocessing techniques to improve OCR accuracy: +- Denoising +- Contrast enhancement +- Binarization +- Deskew +- Resolution enhancement +""" + +import cv2 +import numpy as np +from pathlib import Path +from typing import Optional + + +def denoise_image(image: np.ndarray, h: int = 10) -> np.ndarray: + """ + Apply denoising to image. + + Args: + image: Input image + h: Denoising strength (higher = more denoising) + + Returns: + Denoised image + """ + return cv2.fastNlMeansDenoisingColored(image, None, h, h, 7, 21) + + +def enhance_contrast(image: np.ndarray) -> np.ndarray: + """ + Enhance image contrast using CLAHE. + + Args: + image: Input image (grayscale or BGR) + + Returns: + Contrast-enhanced image + """ + if len(image.shape) == 3: + gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) + else: + gray = image.copy() + + clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8, 8)) + return clahe.apply(gray) + + +def binarize_image(image: np.ndarray, method: str = 'adaptive') -> np.ndarray: + """ + Convert image to binary (black & white). + + Args: + image: Input image (grayscale) + method: 'adaptive', 'otsu', or 'fixed' + + Returns: + Binary image + """ + if method == 'adaptive': + return cv2.adaptiveThreshold( + image, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, + cv2.THRESH_BINARY, 11, 2 + ) + elif method == 'otsu': + _, thresh = cv2.threshold(image, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU) + return thresh + else: # fixed + _, thresh = cv2.threshold(image, 127, 255, cv2.THRESH_BINARY) + return thresh + + +def deskew_image(image: np.ndarray) -> np.ndarray: + """ + Correct image skew. + + Args: + image: Input image + + Returns: + Deskewed image + """ + coords = np.column_stack(np.where(image > 0)) + angle = cv2.minAreaRect(coords)[-1] + + if angle < -45: + angle = -(90 + angle) + else: + angle = -angle + + (h, w) = image.shape[:2] + center = (w // 2, h // 2) + M = cv2.getRotationMatrix2D(center, angle, 1.0) + + return cv2.warpAffine(image, M, (w, h), flags=cv2.INTER_CUBIC, borderMode=cv2.BORDER_REPLICATE) + + +def resize_image(image: np.ndarray, scale: float = 2.0) -> np.ndarray: + """ + Resize image for better OCR. + + Args: + image: Input image + scale: Scale factor (e.g., 2.0 = 2x larger) + + Returns: + Resized image + """ + new_size = tuple(int(dim * scale) for dim in image.shape[:2][::-1]) + return cv2.resize(image, new_size, interpolation=cv2.INTER_CUBIC) + + +def preprocess_pipeline( + image: np.ndarray, + denoise: bool = True, + enhance: bool = True, + binarize: bool = True, + deskew: bool = False, + resize_scale: Optional[float] = None +) -> np.ndarray: + """ + Apply preprocessing pipeline. + + Args: + image: Input image + denoise: Apply denoising + enhance: Enhance contrast + binarize: Binarize image + deskew: Correct skew + resize_scale: Optional scale factor for resizing + + Returns: + Preprocessed image + """ + output = image.copy() + + steps = [] + + if denoise: + output = denoise_image(output) + steps.append('denoise') + + if enhance: + output = enhance_contrast(output) + steps.append('enhance') + + if deskew: + output = deskew_image(output) + steps.append('deskew') + + if resize_scale and resize_scale > 1.0: + output = resize_image(output, resize_scale) + steps.append(f'resize_{resize_scale}x') + + if binarize and len(output.shape) == 2: + output = binarize_image(output) + steps.append('binarize') + + return output + + +def preprocess_file( + input_path: str, + output_path: Optional[str] = None, + **kwargs +) -> str: + """ + Preprocess an image file. + + Args: + input_path: Input image file path + output_path: Output file path (optional) + **kwargs: Preprocessing parameters + + Returns: + Output file path + """ + # Read image + image = cv2.imread(input_path) + if image is None: + raise ValueError(f"Could not load image: {input_path}") + + # Preprocess + processed = preprocess_pipeline(image, **kwargs) + + # Save + if output_path is None: + input_path = Path(input_path) + output_path = str(input_path.parent / f"{input_path.stem}_processed{input_path.suffix}") + + cv2.imwrite(output_path, processed) + + return output_path + + +def quick_preview(image: np.ndarray) -> None: + """ + Display image preview using OpenCV. + + Args: + image: Image to display + """ + cv2.imshow('Preprocessed Image', image) + cv2.waitKey(0) + cv2.destroyAllWindows() + + +if __name__ == '__main__': + import argparse + + parser = argparse.ArgumentParser(description='Image preprocessing for OCR') + parser.add_argument('input', help='Input image file') + parser.add_argument('--output', '-o', help='Output file path') + parser.add_argument('--denoise', action='store_true', default=True, help='Apply denoising') + parser.add_argument('--no-denoise', action='store_false', dest='denoise') + parser.add_argument('--enhance', action='store_true', default=True, help='Enhance contrast') + parser.add_argument('--no-enhance', action='store_false', dest='enhance') + parser.add_argument('--binarize', action='store_true', default=True, help='Binarize image') + parser.add_argument('--no-binarize', action='store_false', dest='binarize') + parser.add_argument('--resize', type=float, help='Resize scale factor (e.g., 2.0)') + + args = parser.parse_args() + + output = preprocess_file( + args.input, + args.output, + denoise=args.denoise, + enhance=args.enhance, + binarize=args.binarize, + resize_scale=args.resize + ) + + print(f"Preprocessed image saved to: {output}") \ No newline at end of file diff --git a/skills/super-ocr/scripts/test_imports.py b/skills/super-ocr/scripts/test_imports.py new file mode 100644 index 0000000..77690e3 --- /dev/null +++ b/skills/super-ocr/scripts/test_imports.py @@ -0,0 +1,74 @@ +#!/usr/bin/env python3 +""" +Test script for Super OCR multi-engine parallel support +""" + +import sys +import os + +# Add parent to path +sys.path.insert(0, str(os.path.dirname(os.path.abspath(__file__)))) + +print("Testing Super OCR multi-engine parallel imports...") + +try: + from engine.selector import select_engine, get_available_engines, select_best_result + print("[OK] engine.selector imported") +except Exception as e: + print(f"[ERROR] engine.selector import failed: {e}") + sys.exit(1) + +try: + from engine.tesseract import TesseractOCR + print("[OK] engine.tesseract imported") +except Exception as e: + print(f"[ERROR] engine.tesseract import failed: {e}") + +try: + from engine.paddle import PaddleOCR + print("[OK] engine.paddle imported") +except Exception as e: + print(f"[ERROR] engine.paddle import failed: {e}") + +# Test MacVision on macOS +if sys.platform == 'darwin': + try: + from engine.macvision import MacVisionOCR + print("[OK] engine.macvision imported") + except (ImportError, RuntimeError) as e: + print(f"[WARN] engine.macvision: {e}") +else: + print("[SKIP] engine.macvision (not on macOS)") + +print("\nTesting engine selector...") + +# Test available engines +print(f"[INFO] Available engines: {', '.join(get_available_engines('test.png'))}") + +test_cases = [ + ('screenshot.png', 'auto', ['tesseract']), + ('chinese_menu.png', 'auto', None), # All engines + ('invoice.jpg', 'auto', None), # All engines + ('document.png', 'tesseract', ['tesseract']), +] + +for image, engine, expected in test_cases: + result = select_engine(image, engine) + if expected: + status = "OK" if result == expected else "FAIL" + print(f"[{status}] {image} + {engine} => {result} (expected {expected})") + else: + print(f"[OK] {image} + {engine} => {result}") + +# Test best result selection +print("\nTesting best result selection...") +test_results = [ + {'text': 'test1', 'confidence': 0.85, 'engine': 'tesseract'}, + {'text': 'test2', 'confidence': 0.92, 'engine': 'paddle'}, + {'text': 'test3', 'confidence': 0.95, 'engine': 'macvision'}, +] + +best = select_best_result(test_results) +print(f"[OK] Selected: {best.get('selected_engine')} with score {best.get('score', 0):.4f}") + +print("\n[OK] All imports successful!") \ No newline at end of file diff --git a/skills/tavily-search-pro/SKILL.md b/skills/tavily-search-pro/SKILL.md new file mode 100644 index 0000000..68d64a3 --- /dev/null +++ b/skills/tavily-search-pro/SKILL.md @@ -0,0 +1,351 @@ +--- +name: tavily-search-pro +slug: tavily-search-pro +description: > + Tavily AI search platform with 5 modes: Search (web/news/finance), Extract (URL content), + Crawl (website crawling), Map (sitemap discovery), and Research (deep research with citations). + Use for: web search with LLM answers, content extraction, site crawling, deep research. +version: 1.0.0 +author: Leo 🦁 +tags: [search, tavily, web, news, finance, extract, crawl, research, api] +metadata: {"clawdbot":{"emoji":"🔎","requires":{"env":["TAVILY_API_KEY"]},"primaryEnv":"TAVILY_API_KEY","install":[{"id":"pip","kind":"pip","package":"tavily-python","label":"Install dependencies (pip)"}]}} +allowed-tools: [exec] +--- + +# Tavily Search 🔎 + +AI-powered web search platform with 5 modes: Search, Extract, Crawl, Map, and Research. + +## Requirements + +- `TAVILY_API_KEY` environment variable + +## Configuration + +| Env Variable | Default | Description | +|---|---|---| +| `TAVILY_API_KEY` | — | **Required.** Tavily API key | + +Set in OpenClaw config: +```json +{ + "env": { + "TAVILY_API_KEY": "tvly-..." + } +} +``` + +## Script Location + +```bash +python3 skills/tavily/lib/tavily_search.py <command> "query" [options] +``` + +--- + +## Commands + +### search — Web Search (Default) + +General-purpose web search with optional LLM-synthesized answer. + +```bash +python3 lib/tavily_search.py search "query" [options] +``` + +**Examples:** +```bash +# Basic search +python3 lib/tavily_search.py search "latest AI news" + +# With LLM answer +python3 lib/tavily_search.py search "what is quantum computing" --answer + +# Advanced depth (better results, 2 credits) +python3 lib/tavily_search.py search "climate change solutions" --depth advanced + +# Time-filtered +python3 lib/tavily_search.py search "OpenAI announcements" --time week + +# Domain filtering +python3 lib/tavily_search.py search "machine learning" --include-domains arxiv.org,nature.com + +# Country boost +python3 lib/tavily_search.py search "tech startups" --country US + +# With raw content and images +python3 lib/tavily_search.py search "solar energy" --raw --images -n 10 + +# JSON output +python3 lib/tavily_search.py search "bitcoin price" --json +``` + +**Output format (text):** +``` +Answer: <LLM-synthesized answer if --answer> + +Results: + 1. Result Title + https://example.com/article + Content snippet from the page... + + 2. Another Result + https://example.com/other + Another snippet... +``` + +--- + +### news — News Search + +Search optimized for news articles. Sets `topic=news`. + +```bash +python3 lib/tavily_search.py news "query" [options] +``` + +**Examples:** +```bash +python3 lib/tavily_search.py news "AI regulation" +python3 lib/tavily_search.py news "Israel tech" --time day --answer +python3 lib/tavily_search.py news "stock market" --time week -n 10 +``` + +--- + +### finance — Finance Search + +Search optimized for financial data and news. Sets `topic=finance`. + +```bash +python3 lib/tavily_search.py finance "query" [options] +``` + +**Examples:** +```bash +python3 lib/tavily_search.py finance "NVIDIA stock analysis" +python3 lib/tavily_search.py finance "cryptocurrency market trends" --time month +python3 lib/tavily_search.py finance "S&P 500 forecast 2026" --answer +``` + +--- + +### extract — Extract Content from URLs + +Extract readable content from one or more URLs. + +```bash +python3 lib/tavily_search.py extract URL [URL...] [options] +``` + +**Parameters:** +- `urls`: One or more URLs to extract (positional args) +- `--depth basic|advanced`: Extraction depth +- `--format markdown|text`: Output format (default: markdown) +- `--query "text"`: Rerank extracted chunks by relevance to query + +**Examples:** +```bash +# Extract single URL +python3 lib/tavily_search.py extract "https://example.com/article" + +# Extract multiple URLs +python3 lib/tavily_search.py extract "https://url1.com" "https://url2.com" + +# Advanced extraction with relevance reranking +python3 lib/tavily_search.py extract "https://arxiv.org/paper" --depth advanced --query "transformer architecture" + +# Text format output +python3 lib/tavily_search.py extract "https://example.com" --format text +``` + +**Output format:** +``` +URL: https://example.com/article +───────────────────────────────── +<Extracted content in markdown/text> + +URL: https://another.com/page +───────────────────────────────── +<Extracted content> +``` + +--- + +### crawl — Crawl a Website + +Crawl a website starting from a root URL, following links. + +```bash +python3 lib/tavily_search.py crawl URL [options] +``` + +**Parameters:** +- `url`: Root URL to start crawling +- `--depth basic|advanced`: Crawl depth +- `--max-depth N`: Maximum link depth to follow (default: 2) +- `--max-breadth N`: Maximum pages per depth level (default: 10) +- `--limit N`: Maximum total pages (default: 10) +- `--instructions "text"`: Natural language crawl instructions +- `--select-paths p1,p2`: Only crawl these path patterns +- `--exclude-paths p1,p2`: Skip these path patterns +- `--format markdown|text`: Output format + +**Examples:** +```bash +# Basic crawl +python3 lib/tavily_search.py crawl "https://docs.example.com" + +# Focused crawl with instructions +python3 lib/tavily_search.py crawl "https://docs.python.org" --instructions "Find all asyncio documentation" --limit 20 + +# Crawl specific paths only +python3 lib/tavily_search.py crawl "https://example.com" --select-paths "/blog,/docs" --max-depth 3 +``` + +**Output format:** +``` +Crawled 5 pages from https://docs.example.com + +Page 1: https://docs.example.com/intro +───────────────────────────────── +<Content> + +Page 2: https://docs.example.com/guide +───────────────────────────────── +<Content> +``` + +--- + +### map — Sitemap Discovery + +Discover all URLs on a website (sitemap). + +```bash +python3 lib/tavily_search.py map URL [options] +``` + +**Parameters:** +- `url`: Root URL to map +- `--max-depth N`: Depth to follow (default: 2) +- `--max-breadth N`: Breadth per level (default: 20) +- `--limit N`: Maximum URLs (default: 50) + +**Examples:** +```bash +# Map a site +python3 lib/tavily_search.py map "https://example.com" + +# Deep map +python3 lib/tavily_search.py map "https://docs.python.org" --max-depth 3 --limit 100 +``` + +**Output format:** +``` +Sitemap for https://example.com (42 URLs found): + + 1. https://example.com/ + 2. https://example.com/about + 3. https://example.com/blog + ... +``` + +--- + +### research — Deep Research + +Comprehensive AI-powered research on a topic with citations. + +```bash +python3 lib/tavily_search.py research "query" [options] +``` + +**Parameters:** +- `query`: Research question +- `--model mini|pro|auto`: Research model (default: auto) + - `mini`: Faster, cheaper + - `pro`: More thorough + - `auto`: Let Tavily decide +- `--json`: JSON output (supports structured output schema) + +**Examples:** +```bash +# Basic research +python3 lib/tavily_search.py research "Impact of AI on healthcare in 2026" + +# Pro model for thorough research +python3 lib/tavily_search.py research "Comparison of quantum computing approaches" --model pro + +# JSON output +python3 lib/tavily_search.py research "Electric vehicle market analysis" --json +``` + +**Output format:** +``` +Research: Impact of AI on healthcare in 2026 + +<Comprehensive research report with citations> + +Sources: + [1] https://source1.com + [2] https://source2.com + ... +``` + +--- + +## Options Reference + +| Option | Applies To | Description | Default | +|---|---|---|---| +| `--depth basic\|advanced` | search, news, finance, extract | Search/extraction depth | basic | +| `--time day\|week\|month\|year` | search, news, finance | Time range filter | none | +| `-n NUM` | search, news, finance | Max results (0-20) | 5 | +| `--answer` | search, news, finance | Include LLM answer | off | +| `--raw` | search, news, finance | Include raw page content | off | +| `--images` | search, news, finance | Include image URLs | off | +| `--include-domains d1,d2` | search, news, finance | Only these domains | none | +| `--exclude-domains d1,d2` | search, news, finance | Exclude these domains | none | +| `--country XX` | search, news, finance | Boost country results | none | +| `--json` | all | Structured JSON output | off | +| `--format markdown\|text` | extract, crawl | Content format | markdown | +| `--query "text"` | extract | Relevance reranking query | none | +| `--model mini\|pro\|auto` | research | Research model | auto | +| `--max-depth N` | crawl, map | Max link depth | 2 | +| `--max-breadth N` | crawl, map | Max pages per level | 10/20 | +| `--limit N` | crawl, map | Max total pages/URLs | 10/50 | +| `--instructions "text"` | crawl | Natural language instructions | none | +| `--select-paths p1,p2` | crawl | Include path patterns | none | +| `--exclude-paths p1,p2` | crawl | Exclude path patterns | none | + +--- + +## Error Handling + +- **Missing API key:** Clear error message with setup instructions. +- **401 Unauthorized:** Invalid API key. +- **429 Rate Limit:** Rate limit exceeded, try again later. +- **Network errors:** Descriptive error with cause. +- **No results:** Clean "No results found." message. +- **Timeout:** 30-second timeout on all HTTP requests. + +--- + +## Credits & Pricing + +| API | Basic | Advanced | +|---|---|---| +| Search | 1 credit | 2 credits | +| Extract | 1 credit/URL | 2 credits/URL | +| Crawl | 1 credit/page | 2 credits/page | +| Map | 1 credit | 1 credit | +| Research | Varies by model | - | + +--- + +## Install + +```bash +bash skills/tavily/install.sh +``` diff --git a/skills/tavily-search-pro/_meta.json b/skills/tavily-search-pro/_meta.json new file mode 100644 index 0000000..36dfc85 --- /dev/null +++ b/skills/tavily-search-pro/_meta.json @@ -0,0 +1,6 @@ +{ + "ownerId": "kn77700wny92h2kvpav2am1yjx80ewfp", + "slug": "tavily-search-pro", + "version": "1.0.0", + "publishedAt": 1770481308912 +} \ No newline at end of file diff --git a/skills/tavily-search-pro/install.sh b/skills/tavily-search-pro/install.sh new file mode 100644 index 0000000..bba5994 --- /dev/null +++ b/skills/tavily-search-pro/install.sh @@ -0,0 +1,30 @@ +#!/usr/bin/env bash +# Tavily Search skill installer +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +echo "📦 Installing Tavily Search skill..." + +# Install Python dependencies +pip install --break-system-packages --quiet tavily-python 2>/dev/null || { + echo "⚠️ pip install failed, trying without --break-system-packages..." + pip install --quiet tavily-python 2>/dev/null || { + echo "❌ Failed to install tavily-python. Install manually: pip install tavily-python" + exit 1 + } +} + +# Verify API key +if [ -z "${TAVILY_API_KEY:-}" ]; then + echo "⚠️ TAVILY_API_KEY not set. Set it in OpenClaw config before using." +else + echo "✅ TAVILY_API_KEY found" +fi + +# Quick smoke test +if python3 "$SCRIPT_DIR/lib/tavily_search.py" --help >/dev/null 2>&1; then + echo "✅ Tavily Search skill ready." +else + echo "⚠️ Smoke test failed - check Python dependencies." + exit 1 +fi diff --git a/skills/tavily-search-pro/lib/tavily_search.py b/skills/tavily-search-pro/lib/tavily_search.py new file mode 100644 index 0000000..8ff5a2a --- /dev/null +++ b/skills/tavily-search-pro/lib/tavily_search.py @@ -0,0 +1,549 @@ +#!/usr/bin/env python3 +""" +Tavily Search v1.0 - AI-powered web search platform with 5 modes. +Author: Leo 🦁 +Created: 2026-02-07 + +Commands: +- search: General web search with optional LLM answer +- news: News-optimized search (topic=news) +- finance: Finance-optimized search (topic=finance) +- extract: Extract content from URLs +- crawl: Crawl a website +- map: Discover sitemap URLs +- research: Deep AI research with citations + +Environment Variables: +- TAVILY_API_KEY: Required. Tavily API key. +""" + +import argparse +import json +import os +import sys +import urllib.request +import urllib.error +from typing import Any, Optional + +# ─── Configuration ─────────────────────────────────────────────────────────── + +API_KEY: str = os.environ.get("TAVILY_API_KEY", "") +BASE_URL: str = "https://api.tavily.com" +REQUEST_TIMEOUT: int = 30 +RESEARCH_TIMEOUT: int = 120 # Research can take longer + + +# ─── HTTP Helper ───────────────────────────────────────────────────────────── + +def _api_request( + endpoint: str, + payload: dict[str, Any], + timeout: int = REQUEST_TIMEOUT, +) -> dict[str, Any]: + """ + Make a POST request to the Tavily API. + + Args: + endpoint: API endpoint path (e.g., '/search'). + payload: JSON request body. + timeout: Request timeout in seconds. + + Returns: + Parsed JSON response. + + Raises: + SystemExit: On API errors with descriptive messages. + """ + url = f"{BASE_URL}{endpoint}" + data = json.dumps(payload).encode("utf-8") + req = urllib.request.Request( + url, + data=data, + headers={ + "Content-Type": "application/json", + "Authorization": f"Bearer {API_KEY}", + }, + method="POST", + ) + + try: + with urllib.request.urlopen(req, timeout=timeout) as resp: + return json.loads(resp.read()) + except urllib.error.HTTPError as e: + body = e.read().decode("utf-8", errors="replace")[:500] + if e.code == 401: + print("Error: Invalid TAVILY_API_KEY. Check your key at https://app.tavily.com", file=sys.stderr) + elif e.code == 429: + print("Error: Rate limit exceeded. Try again later.", file=sys.stderr) + elif e.code == 400: + # Try to extract error message from JSON response + try: + err_data = json.loads(body) + msg = err_data.get("detail", err_data.get("message", body)) + print(f"Error: Bad request - {msg}", file=sys.stderr) + except (json.JSONDecodeError, KeyError): + print(f"Error: Bad request - {body}", file=sys.stderr) + else: + print(f"Error: Tavily API returned {e.code}: {body}", file=sys.stderr) + sys.exit(1) + except urllib.error.URLError as e: + print(f"Error: Network error - {e.reason}", file=sys.stderr) + sys.exit(1) + except TimeoutError: + print(f"Error: Request timed out after {timeout}s", file=sys.stderr) + sys.exit(1) + + +# ─── Output Formatting ────────────────────────────────────────────────────── + +def _format_search_results(data: dict[str, Any], as_json: bool = False) -> str: + """Format search/news/finance results for display.""" + if as_json: + return json.dumps(data, ensure_ascii=False, indent=2) + + lines: list[str] = [] + + # LLM answer + answer = data.get("answer") + if answer: + lines.append(f"Answer: {answer}") + lines.append("") + + # Images + images = data.get("images") + if images: + lines.append("Images:") + for img in images: + if isinstance(img, dict): + lines.append(f" - {img.get('url', img)}") + else: + lines.append(f" - {img}") + lines.append("") + + # Results + results = data.get("results", []) + if results: + lines.append("Results:") + for i, r in enumerate(results, 1): + title = r.get("title", "Untitled") + url = r.get("url", "") + content = r.get("content", "") + score = r.get("score") + published = r.get("published_date", "") + + lines.append(f" {i}. {title}") + lines.append(f" {url}") + if published: + lines.append(f" Published: {published}") + if score is not None: + lines.append(f" Score: {score:.4f}") + if content: + # Truncate long content to keep output readable + snippet = content[:500].strip() + if len(content) > 500: + snippet += "..." + lines.append(f" {snippet}") + + # Raw content (if requested) + raw = r.get("raw_content") + if raw: + lines.append(f" --- Raw Content ---") + raw_snippet = raw[:1000].strip() + if len(raw) > 1000: + raw_snippet += f"... [{len(raw)} chars total]" + lines.append(f" {raw_snippet}") + + lines.append("") + elif not answer: + lines.append("No results found.") + + return "\n".join(lines).rstrip() + + +def _format_extract_results(data: dict[str, Any], as_json: bool = False) -> str: + """Format extract results for display.""" + if as_json: + return json.dumps(data, ensure_ascii=False, indent=2) + + lines: list[str] = [] + results = data.get("results", []) + + if not results: + return "No content extracted." + + for r in results: + url = r.get("url", "Unknown URL") + content = r.get("raw_content", "") + lines.append(f"URL: {url}") + lines.append("─" * 50) + if content: + lines.append(content.strip()) + else: + lines.append("(No content extracted)") + lines.append("") + + # Failed URLs + failed = data.get("failed_results", []) + if failed: + lines.append("Failed URLs:") + for f in failed: + url = f.get("url", "Unknown") + error = f.get("error", "Unknown error") + lines.append(f" ✗ {url}: {error}") + + return "\n".join(lines).rstrip() + + +def _format_crawl_results(data: dict[str, Any], as_json: bool = False) -> str: + """Format crawl results for display.""" + if as_json: + return json.dumps(data, ensure_ascii=False, indent=2) + + lines: list[str] = [] + results = data.get("results", []) + base_url = data.get("base_url", "") + + lines.append(f"Crawled {len(results)} pages from {base_url}") + lines.append("") + + for i, r in enumerate(results, 1): + url = r.get("url", "Unknown URL") + content = r.get("raw_content", "") + lines.append(f"Page {i}: {url}") + lines.append("─" * 50) + if content: + # Truncate very long pages + snippet = content[:2000].strip() + if len(content) > 2000: + snippet += f"\n... [{len(content)} chars total]" + lines.append(snippet) + else: + lines.append("(No content)") + lines.append("") + + # Failed + failed = data.get("failed_results", []) + if failed: + lines.append("Failed URLs:") + for f in failed: + url = f.get("url", "Unknown") + error = f.get("error", "Unknown error") + lines.append(f" ✗ {url}: {error}") + + return "\n".join(lines).rstrip() + + +def _format_map_results(data: dict[str, Any], url: str, as_json: bool = False) -> str: + """Format map/sitemap results for display.""" + if as_json: + return json.dumps(data, ensure_ascii=False, indent=2) + + urls = data.get("results", []) + lines: list[str] = [] + lines.append(f"Sitemap for {url} ({len(urls)} URLs found):") + lines.append("") + + for i, u in enumerate(urls, 1): + if isinstance(u, dict): + lines.append(f" {i}. {u.get('url', u)}") + else: + lines.append(f" {i}. {u}") + + if not urls: + lines.append(" No URLs discovered.") + + return "\n".join(lines).rstrip() + + +def _format_research_results(data: dict[str, Any], as_json: bool = False) -> str: + """Format research results for display.""" + if as_json: + return json.dumps(data, ensure_ascii=False, indent=2) + + lines: list[str] = [] + + # Topic + topic = data.get("topic") or data.get("query", "") + if topic: + lines.append(f"Research: {topic}") + lines.append("") + + # Main content + content = data.get("content") or data.get("output") or data.get("report", "") + if content: + lines.append(content.strip()) + else: + lines.append("No research output returned.") + + # Sources + sources = data.get("sources", []) + if sources: + lines.append("") + lines.append("Sources:") + for i, src in enumerate(sources, 1): + if isinstance(src, dict): + url = src.get("url", src.get("link", str(src))) + title = src.get("title", "") + if title: + lines.append(f" [{i}] {title}") + lines.append(f" {url}") + else: + lines.append(f" [{i}] {url}") + else: + lines.append(f" [{i}] {src}") + + return "\n".join(lines).rstrip() + + +# ─── Commands ──────────────────────────────────────────────────────────────── + +def cmd_search(args: argparse.Namespace) -> str: + """Execute search/news/finance command.""" + topic_map = { + "search": "general", + "news": "news", + "finance": "finance", + } + + payload: dict[str, Any] = { + "query": args.query, + "topic": topic_map.get(args.command, "general"), + "search_depth": args.depth, + "max_results": args.n, + } + + if args.answer: + payload["include_answer"] = True + if args.raw: + payload["include_raw_content"] = "markdown" + if args.images: + payload["include_images"] = True + if args.time: + payload["time_range"] = args.time + if args.include_domains: + payload["include_domains"] = [d.strip() for d in args.include_domains.split(",")] + if args.exclude_domains: + payload["exclude_domains"] = [d.strip() for d in args.exclude_domains.split(",")] + if args.country: + payload["country"] = args.country + + data = _api_request("/search", payload) + return _format_search_results(data, as_json=args.as_json) + + +def cmd_extract(args: argparse.Namespace) -> str: + """Execute extract command.""" + urls = args.urls + if not urls: + print("Error: At least one URL is required for extract.", file=sys.stderr) + sys.exit(1) + + payload: dict[str, Any] = { + "urls": urls if len(urls) > 1 else urls[0], + } + + if args.depth and args.depth != "basic": + payload["extract_depth"] = args.depth + if hasattr(args, "format_type") and args.format_type: + payload["format"] = args.format_type + if hasattr(args, "query") and args.query: + payload["query"] = args.query + + data = _api_request("/extract", payload) + return _format_extract_results(data, as_json=args.as_json) + + +def cmd_crawl(args: argparse.Namespace) -> str: + """Execute crawl command.""" + payload: dict[str, Any] = { + "url": args.url, + } + + if args.max_depth is not None: + payload["max_depth"] = args.max_depth + if args.max_breadth is not None: + payload["max_breadth"] = args.max_breadth + if args.limit is not None: + payload["limit"] = args.limit + if hasattr(args, "instructions") and args.instructions: + payload["instructions"] = args.instructions + if hasattr(args, "select_paths") and args.select_paths: + payload["select_paths"] = [p.strip() for p in args.select_paths.split(",")] + if hasattr(args, "exclude_paths") and args.exclude_paths: + payload["exclude_paths"] = [p.strip() for p in args.exclude_paths.split(",")] + if hasattr(args, "format_type") and args.format_type: + payload["format"] = args.format_type + + data = _api_request("/crawl", payload, timeout=60) + return _format_crawl_results(data, as_json=args.as_json) + + +def cmd_map(args: argparse.Namespace) -> str: + """Execute map/sitemap command.""" + payload: dict[str, Any] = { + "url": args.url, + } + + if args.max_depth is not None: + payload["max_depth"] = args.max_depth + if args.max_breadth is not None: + payload["max_breadth"] = args.max_breadth + if args.limit is not None: + payload["limit"] = args.limit + + data = _api_request("/map", payload) + return _format_map_results(data, args.url, as_json=args.as_json) + + +def cmd_research(args: argparse.Namespace) -> str: + """Execute research command.""" + payload: dict[str, Any] = { + "input": args.query, + } + + if args.model: + payload["model"] = args.model + + data = _api_request("/research", payload, timeout=RESEARCH_TIMEOUT) + return _format_research_results(data, as_json=args.as_json) + + +# ─── CLI ───────────────────────────────────────────────────────────────────── + +def build_parser() -> argparse.ArgumentParser: + """Build the argument parser with all subcommands.""" + parser = argparse.ArgumentParser( + description="Tavily Search v1.0 - AI-powered web search platform", + formatter_class=argparse.RawDescriptionHelpFormatter, + epilog=""" +Examples: + %(prog)s search "latest AI news" --answer + %(prog)s news "tech industry" --time week + %(prog)s finance "NVIDIA stock" --depth advanced + %(prog)s extract "https://example.com/article" + %(prog)s crawl "https://docs.example.com" --limit 20 + %(prog)s map "https://example.com" + %(prog)s research "Impact of AI on healthcare" + """, + ) + + subparsers = parser.add_subparsers(dest="command", help="Command to execute") + + # ── Common search options ── + def add_search_options(sub: argparse.ArgumentParser) -> None: + sub.add_argument("query", help="Search query") + sub.add_argument("--depth", choices=["basic", "advanced"], default="basic", + help="Search depth (default: basic; advanced = 2 credits)") + sub.add_argument("--time", choices=["day", "week", "month", "year", "d", "w", "m", "y"], + default=None, help="Time range filter") + sub.add_argument("-n", type=int, default=5, help="Max results 0-20 (default: 5)") + sub.add_argument("--answer", action="store_true", help="Include LLM-synthesized answer") + sub.add_argument("--raw", action="store_true", help="Include raw page content") + sub.add_argument("--images", action="store_true", help="Include image URLs") + sub.add_argument("--include-domains", default=None, + help="Comma-separated domains to include") + sub.add_argument("--exclude-domains", default=None, + help="Comma-separated domains to exclude") + sub.add_argument("--country", default=None, help="Country code to boost (e.g., US, IL)") + sub.add_argument("--json", action="store_true", dest="as_json", help="JSON output") + + # search + p_search = subparsers.add_parser("search", help="Web search (general)") + add_search_options(p_search) + + # news + p_news = subparsers.add_parser("news", help="News search") + add_search_options(p_news) + + # finance + p_finance = subparsers.add_parser("finance", help="Finance search") + add_search_options(p_finance) + + # extract + p_extract = subparsers.add_parser("extract", help="Extract content from URLs") + p_extract.add_argument("urls", nargs="+", help="URLs to extract content from") + p_extract.add_argument("--depth", choices=["basic", "advanced"], default="basic", + help="Extraction depth") + p_extract.add_argument("--format", dest="format_type", choices=["markdown", "text"], + default=None, help="Output format (default: markdown)") + p_extract.add_argument("--query", default=None, + help="Query for relevance reranking of chunks") + p_extract.add_argument("--json", action="store_true", dest="as_json", help="JSON output") + + # crawl + p_crawl = subparsers.add_parser("crawl", help="Crawl a website") + p_crawl.add_argument("url", help="Root URL to crawl") + p_crawl.add_argument("--depth", choices=["basic", "advanced"], default=None, + help="Crawl depth") + p_crawl.add_argument("--max-depth", type=int, default=None, help="Max link depth (default: 2)") + p_crawl.add_argument("--max-breadth", type=int, default=None, + help="Max pages per level (default: 10)") + p_crawl.add_argument("--limit", type=int, default=None, help="Max total pages (default: 10)") + p_crawl.add_argument("--instructions", default=None, + help="Natural language crawl instructions") + p_crawl.add_argument("--select-paths", default=None, + help="Comma-separated path patterns to include") + p_crawl.add_argument("--exclude-paths", default=None, + help="Comma-separated path patterns to exclude") + p_crawl.add_argument("--format", dest="format_type", choices=["markdown", "text"], + default=None, help="Output format") + p_crawl.add_argument("--json", action="store_true", dest="as_json", help="JSON output") + + # map + p_map = subparsers.add_parser("map", help="Discover sitemap URLs") + p_map.add_argument("url", help="Root URL to map") + p_map.add_argument("--max-depth", type=int, default=None, help="Max depth (default: 2)") + p_map.add_argument("--max-breadth", type=int, default=None, + help="Max breadth per level (default: 20)") + p_map.add_argument("--limit", type=int, default=None, help="Max URLs (default: 50)") + p_map.add_argument("--json", action="store_true", dest="as_json", help="JSON output") + + # research + p_research = subparsers.add_parser("research", help="Deep AI research") + p_research.add_argument("query", help="Research question") + p_research.add_argument("--model", choices=["mini", "pro", "auto"], default=None, + help="Research model (default: auto)") + p_research.add_argument("--json", action="store_true", dest="as_json", help="JSON output") + + return parser + + +def main() -> None: + """CLI entry point.""" + parser = build_parser() + args = parser.parse_args() + + if not args.command: + parser.print_help() + sys.exit(1) + + if not API_KEY: + print("Error: TAVILY_API_KEY environment variable not set.", file=sys.stderr) + print("Set it in OpenClaw config or export TAVILY_API_KEY=your_key", file=sys.stderr) + sys.exit(1) + + try: + if args.command in ("search", "news", "finance"): + result = cmd_search(args) + elif args.command == "extract": + result = cmd_extract(args) + elif args.command == "crawl": + result = cmd_crawl(args) + elif args.command == "map": + result = cmd_map(args) + elif args.command == "research": + result = cmd_research(args) + else: + parser.print_help() + sys.exit(1) + + print(result) + except SystemExit: + raise + except Exception as e: + print(f"Error: {e}", file=sys.stderr) + sys.exit(1) + + +if __name__ == "__main__": + main() diff --git a/skills/tavily-search/SKILL.md b/skills/tavily-search/SKILL.md new file mode 100644 index 0000000..8f9ea88 --- /dev/null +++ b/skills/tavily-search/SKILL.md @@ -0,0 +1,38 @@ +--- +name: tavily +description: AI-optimized web search via Tavily API. Returns concise, relevant results for AI agents. +homepage: https://tavily.com +metadata: {"clawdbot":{"emoji":"🔍","requires":{"bins":["node"],"env":["TAVILY_API_KEY"]},"primaryEnv":"TAVILY_API_KEY"}} +--- + +# Tavily Search + +AI-optimized web search using Tavily API. Designed for AI agents - returns clean, relevant content. + +## Search + +```bash +node {baseDir}/scripts/search.mjs "query" +node {baseDir}/scripts/search.mjs "query" -n 10 +node {baseDir}/scripts/search.mjs "query" --deep +node {baseDir}/scripts/search.mjs "query" --topic news +``` + +## Options + +- `-n <count>`: Number of results (default: 5, max: 20) +- `--deep`: Use advanced search for deeper research (slower, more comprehensive) +- `--topic <topic>`: Search topic - `general` (default) or `news` +- `--days <n>`: For news topic, limit to last n days + +## Extract content from URL + +```bash +node {baseDir}/scripts/extract.mjs "https://example.com/article" +``` + +Notes: +- Needs `TAVILY_API_KEY` from https://tavily.com +- Tavily is optimized for AI - returns clean, relevant snippets +- Use `--deep` for complex research questions +- Use `--topic news` for current events diff --git a/skills/tavily-search/_meta.json b/skills/tavily-search/_meta.json new file mode 100644 index 0000000..4b622bd --- /dev/null +++ b/skills/tavily-search/_meta.json @@ -0,0 +1,6 @@ +{ + "ownerId": "kn7azq5e6sw0fbwwzdpcwvvjzd7z0x4z", + "slug": "tavily-search", + "version": "1.0.0", + "publishedAt": 1768114920544 +} \ No newline at end of file diff --git a/skills/tavily-search/scripts/extract.mjs b/skills/tavily-search/scripts/extract.mjs new file mode 100644 index 0000000..68af256 --- /dev/null +++ b/skills/tavily-search/scripts/extract.mjs @@ -0,0 +1,59 @@ +#!/usr/bin/env node + +function usage() { + console.error(`Usage: extract.mjs "url1" ["url2" ...]`); + process.exit(2); +} + +const args = process.argv.slice(2); +if (args.length === 0 || args[0] === "-h" || args[0] === "--help") usage(); + +const urls = args.filter(a => !a.startsWith("-")); + +if (urls.length === 0) { + console.error("No URLs provided"); + usage(); +} + +const apiKey = (process.env.TAVILY_API_KEY ?? "").trim(); +if (!apiKey) { + console.error("Missing TAVILY_API_KEY"); + process.exit(1); +} + +const resp = await fetch("https://api.tavily.com/extract", { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + api_key: apiKey, + urls: urls, + }), +}); + +if (!resp.ok) { + const text = await resp.text().catch(() => ""); + throw new Error(`Tavily Extract failed (${resp.status}): ${text}`); +} + +const data = await resp.json(); + +const results = data.results ?? []; +const failed = data.failed_results ?? []; + +for (const r of results) { + const url = String(r?.url ?? "").trim(); + const content = String(r?.raw_content ?? "").trim(); + + console.log(`# ${url}\n`); + console.log(content || "(no content extracted)"); + console.log("\n---\n"); +} + +if (failed.length > 0) { + console.log("## Failed URLs\n"); + for (const f of failed) { + console.log(`- ${f.url}: ${f.error}`); + } +} diff --git a/skills/tavily-search/scripts/search.mjs b/skills/tavily-search/scripts/search.mjs new file mode 100644 index 0000000..c6eec78 --- /dev/null +++ b/skills/tavily-search/scripts/search.mjs @@ -0,0 +1,101 @@ +#!/usr/bin/env node + +function usage() { + console.error(`Usage: search.mjs "query" [-n 5] [--deep] [--topic general|news] [--days 7]`); + process.exit(2); +} + +const args = process.argv.slice(2); +if (args.length === 0 || args[0] === "-h" || args[0] === "--help") usage(); + +const query = args[0]; +let n = 5; +let searchDepth = "basic"; +let topic = "general"; +let days = null; + +for (let i = 1; i < args.length; i++) { + const a = args[i]; + if (a === "-n") { + n = Number.parseInt(args[i + 1] ?? "5", 10); + i++; + continue; + } + if (a === "--deep") { + searchDepth = "advanced"; + continue; + } + if (a === "--topic") { + topic = args[i + 1] ?? "general"; + i++; + continue; + } + if (a === "--days") { + days = Number.parseInt(args[i + 1] ?? "7", 10); + i++; + continue; + } + console.error(`Unknown arg: ${a}`); + usage(); +} + +const apiKey = (process.env.TAVILY_API_KEY ?? "").trim(); +if (!apiKey) { + console.error("Missing TAVILY_API_KEY"); + process.exit(1); +} + +const body = { + api_key: apiKey, + query: query, + search_depth: searchDepth, + topic: topic, + max_results: Math.max(1, Math.min(n, 20)), + include_answer: true, + include_raw_content: false, +}; + +if (topic === "news" && days) { + body.days = days; +} + +const resp = await fetch("https://api.tavily.com/search", { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify(body), +}); + +if (!resp.ok) { + const text = await resp.text().catch(() => ""); + throw new Error(`Tavily Search failed (${resp.status}): ${text}`); +} + +const data = await resp.json(); + +// Print AI-generated answer if available +if (data.answer) { + console.log("## Answer\n"); + console.log(data.answer); + console.log("\n---\n"); +} + +// Print results +const results = (data.results ?? []).slice(0, n); +console.log("## Sources\n"); + +for (const r of results) { + const title = String(r?.title ?? "").trim(); + const url = String(r?.url ?? "").trim(); + const content = String(r?.content ?? "").trim(); + const score = r?.score ? ` (relevance: ${(r.score * 100).toFixed(0)}%)` : ""; + + if (!title || !url) continue; + console.log(`- **${title}**${score}`); + console.log(` ${url}`); + if (content) { + console.log(` ${content.slice(0, 300)}${content.length > 300 ? "..." : ""}`); + } + console.log(); +} diff --git a/skills/tencent-cos-skill/.clawhub/origin.json b/skills/tencent-cos-skill/.clawhub/origin.json new file mode 100644 index 0000000..6f0abb6 --- /dev/null +++ b/skills/tencent-cos-skill/.clawhub/origin.json @@ -0,0 +1,7 @@ +{ + "version": 1, + "registry": "https://clawhub.ai", + "slug": "tencent-cos-skill", + "installedVersion": "1.0.6", + "installedAt": 1773129536499 +} diff --git a/skills/tencent-cos-skill/SKILL.md b/skills/tencent-cos-skill/SKILL.md new file mode 100644 index 0000000..ca52bbc --- /dev/null +++ b/skills/tencent-cos-skill/SKILL.md @@ -0,0 +1,357 @@ +--- +name: tencent-cloud-cos +description: > + 腾讯云对象存储(COS)和数据万象(CI)集成技能。当用户需要上传、下载、管理云存储文件, + 或需要进行图片处理(质量评估、超分辨率、抠图、二维码识别、水印)、智能图片搜索、 + 文档转PDF、视频智能封面生成等操作时使用此技能。 +metadata: + { + "openclaw": + { + "emoji": "☁️", + "requires": {}, + "install": + [ + { + "id": "node-mcporter", + "kind": "node", + "package": "mcporter", + "bins": ["mcporter"], + "label": "Install mcporter (MCP CLI)", + }, + { + "id": "node-cos-mcp", + "kind": "node", + "package": "cos-mcp", + "bins": ["cos-mcp"], + "label": "Install cos-mcp (COS MCP Server)", + }, + { + "id": "node-cos-sdk", + "kind": "node", + "package": "cos-nodejs-sdk-v5", + "label": "Install COS Node.js SDK", + }, + ], + }, + } +--- + +# 腾讯云 COS 技能 + +通过 cos-mcp MCP 工具 + Node.js SDK 脚本 + COSCMD 管理腾讯云对象存储和数据万象。 + +## 首次使用 — 自动设置 + +当用户首次要求操作 COS 时,按以下流程操作: + +### 步骤 1:检查当前状态 + +```bash +{baseDir}/scripts/setup.sh --check-only +``` + +如果输出显示一切 OK(cos-mcp 已安装、凭证已配置),跳到「执行策略」。 + +### 步骤 2:如果未配置,引导用户提供凭证 + +告诉用户: +> 我需要你的腾讯云凭证来连接 COS 存储服务。请提供: +> 1. **SecretId** — 腾讯云 API 密钥 ID +> 2. **SecretKey** — 腾讯云 API 密钥 Key +> 3. **Region** — 存储桶区域(如 ap-guangzhou) +> 4. **Bucket** — 存储桶名称(格式 name-appid,如 mybucket-1250000000) +> 5. **DatasetName**(可选) — 数据万象数据集名称(仅智能搜索需要) +> 6. **Domain**(可选) — 自定义域名,用于替换默认的 COS 访问域名(如 cdn.example.com) +> 7. **ServiceDomain**(可选) — 自定义服务域名,用于自定义 COS API 请求域名 +> 8. **Protocol**(可选) — 协议,如 https 或 http +> +> 你可以在 [腾讯云控制台 > 访问管理 > API密钥管理](https://console.cloud.tencent.com/cam/capi) 获取密钥, +> 在 [COS 控制台](https://console.cloud.tencent.com/cos/bucket) 查看存储桶信息。 + +### 步骤 3:用户提供凭证后,运行自动设置 + +```bash +{baseDir}/scripts/setup.sh --secret-id "<SecretId>" --secret-key "<SecretKey>" --region "<Region>" --bucket "<Bucket>" +``` + +如有 DatasetName: +```bash +{baseDir}/scripts/setup.sh --secret-id "<SecretId>" --secret-key "<SecretKey>" --region "<Region>" --bucket "<Bucket>" --dataset "<DatasetName>" +``` + +如需自定义域名(可选参数按需添加): +```bash +{baseDir}/scripts/setup.sh --secret-id "<SecretId>" --secret-key "<SecretKey>" --region "<Region>" --bucket "<Bucket>" --domain "<Domain>" --service-domain "<ServiceDomain>" --protocol "<Protocol>" +``` + +脚本会自动: +- 检查并安装 mcporter(MCP 命令行工具) +- 检查并安装 cos-mcp 和 cos-nodejs-sdk-v5 +- 创建/更新 `~/.mcporter/mcporter.json`,写入 cos-mcp 服务器配置 +- 将凭证写入 shell 配置文件(`~/.zshrc` 或 `~/.bashrc`),重启后仍可用 +- 配置 coscmd(如有 Python 环境) +- 验证 COS 连接 + +设置完成后即可开始使用。 + +## 执行策略 + +三种方式按优先级降级,确保操作始终可完成: + +1. **方式一:cos-mcp MCP 工具**(优先) — 功能最全,支持存储 + 图片处理 + 智能搜索 + 文档媒体处理 +2. **方式二:Node.js SDK 脚本** — 通过 `scripts/cos_node.mjs` 执行存储操作 +3. **方式三:COSCMD 命令行** — 通过 shell 命令执行存储操作 + +``` +mcporter + cos-mcp 可用?(which mcporter && 配置存在) + ├─ 是 → 使用方式一 mcporter 调用(全部功能) + └─ 否 → cos-mcp MCP 工具可直接调用?(getCosConfig 返回结果) + ├─ 是 → 使用方式一直接调用(全部功能) + └─ 否 → Node.js + cos-nodejs-sdk-v5 可用? + ├─ 是 → 使用方式二(存储操作) + └─ 否 → coscmd 可用?(which coscmd) + ├─ 是 → 使用方式三(存储操作) + └─ 否 → 运行 setup.sh 安装 +``` + +**判断方式一(mcporter)**:`which mcporter` 且 `cat ~/.mcporter/mcporter.json | grep cos-mcp` 有输出。 +**判断方式一(直接)**:尝试调用 `getCosConfig` MCP 工具,若返回结果则可用。 +**判断方式二**:`node -e "require('cos-nodejs-sdk-v5')"` 成功则可用。 +**判断方式三**:`which coscmd` 有输出则可用。 + +--- + +## 方式一:cos-mcp MCP 工具(优先) + +> GitHub: https://github.com/Tencent/cos-mcp + +MCP 配置模板见 `references/config_template.json`。 + +### 调用格式 + +通过 mcporter 命令行调用 cos-mcp MCP 工具: + +``` +mcporter call cos-mcp.<tool_name> --config ~/.mcporter/mcporter.json --output json [--args '<JSON>'] +``` + +列出所有可用工具: +``` +mcporter list cos-mcp --config ~/.mcporter/mcporter.json --schema +``` + +**判断 mcporter 是否可用**:`which mcporter` 且 `~/.mcporter/mcporter.json` 包含 cos-mcp 配置。 +如果 mcporter 不可用,可回退到客户端直接调用 MCP 工具(`getCosConfig` 等)。 + +### 工具总览 + +| 类别 | 说明 | +|------|------| +| 存储操作 | 上传、下载、列出、获取签名URL | +| 图片处理 | 质量评估、超分辨率、抠图、二维码识别、水印 | +| 智能搜索 | 以图搜图、文本搜图(需预建数据集) | +| 文档媒体 | 文档转PDF、视频智能封面(异步任务) | + +### 常用操作 + +> 以下示例同时展示两种调用格式。mcporter 格式省略公共前缀 `mcporter call cos-mcp.` 和 `--config ~/.mcporter/mcporter.json --output json`。 +> 完整 mcporter 命令:`mcporter call cos-mcp.<tool> --config ~/.mcporter/mcporter.json --output json --args '<JSON>'` + +#### 存储 + +```bash +# 上传本地文件(mcporter 格式) +mcporter call cos-mcp.putObject --config ~/.mcporter/mcporter.json --output json --args '{"filePath":"/path/to/file.jpg","targetDir":"images"}' + +# 上传本地文件(客户端直接调用格式) +putObject filePath="/path/to/file.jpg" targetDir="images" + +# 上传字符串内容 +putString content="hello world" fileName="test.txt" targetDir="docs" + +# 通过 URL 上传 +putObjectSourceUrl sourceUrl="https://example.com/image.png" targetDir="images" + +# 列出文件 +getBucket Prefix="images/" + +# 下载文件 +getObject objectKey="images/photo.jpg" + +# 获取签名下载链接 +getObjectUrl objectKey="images/photo.jpg" +``` + +#### 图片处理 + +``` +# 图片质量评估 +assessQuality objectKey="images/photo.jpg" + +# AI 超分辨率 +aiSuperResolution objectKey="images/photo.jpg" + +# AI 智能抠图 +aiPicMatting objectKey="images/photo.jpg" + +# 二维码识别 +aiQrcode objectKey="images/qrcode.jpg" + +# 添加文字水印 +waterMarkFont objectKey="images/photo.jpg" text="版权所有" + +# 获取图片元信息 +imageInfo objectKey="images/photo.jpg" +``` + +#### 智能搜索(需预建数据集) + +``` +# 以图搜图 +imageSearchPic uri="https://example.com/query.jpg" + +# 文本搜图 +imageSearchText text="蓝天白云" +``` + +#### 文档与媒体处理(异步任务) + +``` +# 文档转 PDF +createDocToPdfJob objectKey="docs/report.docx" +# 查询任务结果 +describeDocProcessJob jobId="<jobId>" + +# 视频智能封面 +createMediaSmartCoverJob objectKey="videos/demo.mp4" +# 查询任务结果 +describeMediaJob jobId="<jobId>" +``` + +工具详细参数定义见 `references/api_reference.md`。 + +--- + +## 方式二:Node.js SDK 脚本 + +> 官方文档: https://www.tencentcloud.com/zh/document/product/436/8629 + +当 cos-mcp 不可用时,通过 `scripts/cos_node.mjs` 执行存储操作。凭证从环境变量读取。 + +支持的环境变量: +- `TENCENT_COS_SECRET_ID` / `TENCENT_COS_SECRET_KEY` / `TENCENT_COS_REGION` / `TENCENT_COS_BUCKET`(必需) +- `TENCENT_COS_DOMAIN` / `TENCENT_COS_SERVICE_DOMAIN` / `TENCENT_COS_PROTOCOL`(可选,自定义域名) + +### 常用命令 + +> 以下省略 `node {baseDir}/scripts/cos_node.mjs` 前缀。完整格式:`node {baseDir}/scripts/cos_node.mjs <action> [options]` + +```bash +# 上传文件 +upload --file /path/to/file.jpg --key remote/path/file.jpg + +# 上传字符串 +put-string --content "文本内容" --key remote/file.txt --content-type "text/plain" + +# 下载文件 +download --key remote/path/file.jpg --output /path/to/save/file.jpg + +# 列出文件 +list --prefix "images/" + +# 获取签名 URL +sign-url --key remote/path/file.jpg --expires 3600 + +# 查看文件信息 +head --key remote/path/file.jpg + +# 删除文件 +delete --key remote/path/file.jpg +``` + +所有命令输出 JSON 格式,`success: true` 表示成功,退出码 0。 + +### 限制 + +仅支持存储操作,**不支持**图片处理、智能搜索、文档转换。 + +--- + +## 方式三:COSCMD 命令行 + +> 官方文档: https://www.tencentcloud.com/zh/document/product/436/10976 + +当方式一和方式二均不可用时使用。配置持久化在 `~/.cos.conf`。 + +自定义域名支持(有限): +- **ServiceDomain** — 对应 coscmd 的 `-e ENDPOINT` 参数,设置后 Region 失效 +- **Protocol** — 若为 `http`,对应 coscmd 的 `--do-not-use-ssl` 参数 +- **Domain** — COSCMD 不支持 CDN 自定义域名 + +### 常用命令 + +```bash +# 上传 +coscmd upload /path/to/file.jpg remote/path/file.jpg +coscmd upload -r /path/to/folder/ remote/folder/ + +# 下载 +coscmd download remote/path/file.jpg /path/to/save/file.jpg +coscmd download -r remote/folder/ /path/to/save/ + +# 列出文件 +coscmd list images/ + +# 删除 +coscmd delete remote/path/file.jpg +coscmd delete -r remote/folder/ -f + +# 签名 URL +coscmd signurl remote/path/file.jpg -t 3600 + +# 文件信息 +coscmd info remote/path/file.jpg + +# 复制/移动 +coscmd copy <BucketName-APPID>.cos.<Region>.myqcloud.com/source.jpg dest.jpg +coscmd move <BucketName-APPID>.cos.<Region>.myqcloud.com/source.jpg dest.jpg +``` + +### 限制 + +仅支持存储操作,**不支持**图片处理、智能搜索、文档转换。 + +--- + +## 功能对照表 + +| 功能 | 方式一 cos-mcp | 方式二 Node SDK | 方式三 COSCMD | +|------|:-:|:-:|:-:| +| 上传文件 | ✅ | ✅ | ✅ | +| 上传字符串/Base64 | ✅ | ✅ | ❌ | +| 通过 URL 上传 | ✅ | ❌ | ❌ | +| 下载文件 | ✅ | ✅ | ✅ | +| 列出文件 | ✅ | ✅ | ✅ | +| 获取签名 URL | ✅ | ✅ | ✅ | +| 删除文件 | ❌ | ✅ | ✅ | +| 查看文件信息 | ❌ | ✅ | ✅ | +| 递归上传/下载目录 | ❌ | ❌ | ✅ | +| 图片处理(CI) | ✅ | ❌ | ❌ | +| 智能搜索 | ✅ | ❌ | ❌ | +| 文档转 PDF | ✅ | ❌ | ❌ | +| 视频智能封面 | ✅ | ❌ | ❌ | + +## 使用规范 + +1. **首次使用先运行** `{baseDir}/scripts/setup.sh --check-only` 检查环境 +2. **mcporter 调用必须带** `--config ~/.mcporter/mcporter.json` 和 `--output json` +3. **凭证不明文展示**:引导用户自行通过 setup.sh 或编辑配置文件设置 +4. **所有文件路径**(`objectKey`/`cospath`/`--key`)为存储桶内的相对路径,如 `images/photo.jpg` +5. **图片处理/智能搜索/文档转换仅方式一可用**,不可用时明确告知用户 +6. **异步任务**(文档转换、视频封面)需通过 `jobId` 轮询结果 +7. **上传后主动获取链接**:上传完成后调用 `getObjectUrl` 或 `sign-url` 返回访问链接 +8. **错误处理**:调用失败时先用 `setup.sh --check-only` 诊断环境问题 +9. **方式二脚本源码**见 `scripts/cos_node.mjs` +10. **MCP 工具详细参数**见 `references/api_reference.md` +11. **MCP 配置模板**见 `references/config_template.json` diff --git a/skills/tencent-cos-skill/_meta.json b/skills/tencent-cos-skill/_meta.json new file mode 100644 index 0000000..6a02b4a --- /dev/null +++ b/skills/tencent-cos-skill/_meta.json @@ -0,0 +1,6 @@ +{ + "ownerId": "kn75r0rammt45k8qe5we0sh63580c5y0", + "slug": "tencent-cos-skill", + "version": "1.0.6", + "publishedAt": 1772789580071 +} \ No newline at end of file diff --git a/skills/tencent-cos-skill/references/api_reference.md b/skills/tencent-cos-skill/references/api_reference.md new file mode 100644 index 0000000..fd1e0b1 --- /dev/null +++ b/skills/tencent-cos-skill/references/api_reference.md @@ -0,0 +1,180 @@ +# 腾讯云 COS 操作参考 + +本文档记录三种操作方式的详细参数定义,供执行操作时查阅。 + +**环境设置**:首次使用请运行 `scripts/setup.sh`,详见 `SKILL.md` 首次使用章节。 + +**官方文档链接:** +- cos-mcp GitHub: https://github.com/Tencent/cos-mcp +- COS Node.js SDK: https://www.tencentcloud.com/zh/document/product/436/8629 +- COSCMD 工具: https://www.tencentcloud.com/zh/document/product/436/10976 + +--- + +## 方式一:cos-mcp MCP 工具参数参考 + +## 存储操作工具 + +### getCosConfig +获取当前 COS 配置信息。 +- 参数:无 + +### putObject +上传本地文件到存储桶。 +- `filePath` (string, **必需**): 本地文件路径(包含文件名) +- `fileName` (string, 可选): 存储桶中的文件名 +- `targetDir` (string, 可选): 存储桶中的目标目录 + +### putString +上传字符串内容到存储桶。 +- `content` (string, **必需**): 要上传的字符串内容 +- `fileName` (string, **必需**): 存储桶中的文件名 +- `targetDir` (string, 可选): 目标目录 +- `contentType` (string, 可选): MIME 类型,默认 `text/plain` + +### putBase64 +上传 base64 编码内容到存储桶。 +- `base64Content` (string, **必需**): base64 编码的内容 +- `fileName` (string, **必需**): 存储桶中的文件名 +- `targetDir` (string, 可选): 目标目录 +- `contentType` (string, 可选): MIME 类型,如 `image/png`、`application/pdf` + +### putBuffer +上传 buffer 内容到存储桶。 +- `content` (string, **必需**): buffer 内容字符串 +- `fileName` (string, **必需**): 存储桶中的文件名 +- `targetDir` (string, 可选): 目标目录 +- `contentType` (string, 可选): MIME 类型,默认 `application/octet-stream` +- `encoding` (string, 可选): 编码格式,枚举值: `hex` | `base64` | `utf8` | `ascii` | `binary`,默认 `utf8` + +### putObjectSourceUrl +通过 URL 下载文件并上传到存储桶。 +- `sourceUrl` (string, **必需**): 可下载的文件 URL +- `fileName` (string, 可选): 存储桶中的文件名 +- `targetDir` (string, 可选): 目标目录 + +### getObject +下载存储桶内的文件。 +- `objectKey` (string, **必需**): 文件在存储桶中的路径 + +### getBucket +查询存储桶内的文件列表。 +- `Prefix` (string, 可选): 路径前缀过滤,默认根路径 + +### getObjectUrl +获取文件的带签名下载链接。 +- `objectKey` (string, **必需**): 文件在存储桶中的路径 + +## 图片处理工具 + +### imageInfo +获取图片元数据信息。 +- `objectKey` (string, **必需**): 图片在存储桶中的路径 + +### assessQuality +评估图片质量分数。 +- `objectKey` (string, **必需**): 图片在存储桶中的路径 + +### aiSuperResolution +AI 超分辨率,提升图片分辨率。 +- `objectKey` (string, **必需**): 图片在存储桶中的路径 + +### aiPicMatting +AI 智能抠图,去除图片背景。 +- `objectKey` (string, **必需**): 图片在存储桶中的路径 +- `width` (string, 可选): 输出宽度 +- `height` (string, 可选): 输出高度 + +### aiQrcode +识别存储桶内图片中的二维码内容。 +- `objectKey` (string, **必需**): COS 对象键完整路径,如 `images/qrcode.jpg` + +### waterMarkFont +生成带文字水印的图片。 +- `objectKey` (string, **必需**): COS 对象键完整路径,如 `images/photo.jpg` +- `text` (string, 可选): 水印文字内容(支持中文),默认 `test` + +## 智能搜索工具 + +### imageSearchPic +以图搜图,从数据集中检索相似图片。 +- `uri` (string, **必需**): 图片地址 + +### imageSearchText +文本搜图,根据文字描述检索匹配图片。 +- `text` (string, **必需**): 检索文本 + +## 文档与媒体处理工具 + +### createDocToPdfJob +创建文档转 PDF 处理任务。 +- `objectKey` (string, **必需**): 文档在存储桶中的路径 + +### describeDocProcessJob +查询文档转码任务结果。 +- `jobId` (string, **必需**): 任务 ID(通过提交文档任务的响应获取) + +### createMediaSmartCoverJob +创建视频智能封面任务。 +- `objectKey` (string, **必需**): 视频在存储桶中的路径 + +### describeMediaJob +查询智能封面任务结果。 +- `jobId` (string, **必需**): 任务 ID(通过提交智能封面任务的响应获取) + +--- + +## 方式二:scripts/cos_node.mjs 命令参考 + +脚本位于 `scripts/cos_node.mjs`,依赖 `cos-nodejs-sdk-v5`(`npm install cos-nodejs-sdk-v5`)。 +所有凭证通过环境变量读取。输出 JSON 格式。 + +### 可用操作 + +| 操作 | 命令 | 说明 | +|------|------|------| +| upload | `node scripts/cos_node.mjs upload --file <path> --key <key>` | 上传本地文件 | +| put-string | `node scripts/cos_node.mjs put-string --content <text> --key <key> [--content-type <mime>]` | 上传字符串内容 | +| download | `node scripts/cos_node.mjs download --key <key> --output <path>` | 下载文件到本地 | +| list | `node scripts/cos_node.mjs list [--prefix <prefix>] [--max-keys <n>]` | 列出文件 | +| sign-url | `node scripts/cos_node.mjs sign-url --key <key> [--expires <seconds>]` | 获取签名下载链接 | +| delete | `node scripts/cos_node.mjs delete --key <key>` | 删除文件 | +| head | `node scripts/cos_node.mjs head --key <key>` | 查看文件元信息 | + +### 返回格式 + +成功时 `success: true`,退出码 0;失败时 `success: false`,退出码 1。 + +--- + +## 方式三:COSCMD 命令参考 + +依赖 Python,通过 `pip install coscmd` 安装。首次使用需配置(写入 `~/.cos.conf`,后续无需重复): + +```bash +coscmd config -a $TENCENT_COS_SECRET_ID -s $TENCENT_COS_SECRET_KEY -b $TENCENT_COS_BUCKET -r $TENCENT_COS_REGION +``` + +### 常用命令 + +| 操作 | 命令 | 说明 | +|------|------|------| +| 上传文件 | `coscmd upload <localpath> <cospath>` | 上传单个文件 | +| 递归上传目录 | `coscmd upload -r <localdir> <cosdir>` | 上传整个目录 | +| 下载文件 | `coscmd download <cospath> <localpath>` | 下载单个文件 | +| 递归下载目录 | `coscmd download -r <cosdir> <localdir>` | 下载整个目录 | +| 列出文件 | `coscmd list [cospath]` | 列出文件,加 `-r` 递归 | +| 删除文件 | `coscmd delete <cospath>` | 删除单个文件 | +| 递归删除 | `coscmd delete -r <cosdir> -f` | 强制递归删除 | +| 签名 URL | `coscmd signurl <cospath> [-t <seconds>]` | 获取带签名的下载链接 | +| 文件信息 | `coscmd info <cospath>` | 查看文件元信息 | +| 复制 | `coscmd copy <source> <dest>` | 桶内/跨桶复制 | +| 移动 | `coscmd move <source> <dest>` | 移动文件(复制+删除源) | + +### 全局参数 + +- `-c <CONFIG_PATH>`:指定配置文件路径(默认 `~/.cos.conf`) +- `-b <BucketName-APPID>`:指定存储桶(覆盖配置文件) +- `-r <Region>`:指定区域 +- `-d`:调试模式,输出详细日志 + diff --git a/skills/tencent-cos-skill/references/config_template.json b/skills/tencent-cos-skill/references/config_template.json new file mode 100644 index 0000000..f6ae4bc --- /dev/null +++ b/skills/tencent-cos-skill/references/config_template.json @@ -0,0 +1,73 @@ +{ + "_description": "cos-mcp MCP 服务器配置模板,添加到客户端的 MCP 配置文件中", + + "mcpServers": { + "cos-mcp": { + "_comment": "方式一:参数直接传入 args", + "command": "npx", + "args": [ + "cos-mcp", + "--Region=<替换为存储桶区域,如 ap-guangzhou>", + "--Bucket=<替换为存储桶名称,格式 name-appid>", + "--SecretId=<替换为腾讯云 API 密钥 ID>", + "--SecretKey=<替换为腾讯云 API 密钥 Key>", + "--DatasetName=<替换为数据万象数据集名称,无则删除此行>", + "--Domain=<替换为自定义域名,无则删除此行>", + "--ServiceDomain=<替换为自定义服务域名,无则删除此行>", + "--Protocol=<替换为协议,如 https,无则删除此行>", + "--connectType=stdio" + ] + }, + + "cos-mcp-env": { + "_comment": "方式二:通过 env 传递敏感参数(推荐)", + "command": "npx", + "args": [ + "cos-mcp", + "--connectType=stdio" + ], + "env": { + "TENCENT_COS_SECRET_ID": "<替换为腾讯云 API 密钥 ID>", + "TENCENT_COS_SECRET_KEY": "<替换为腾讯云 API 密钥 Key>", + "TENCENT_COS_REGION": "<替换为存储桶区域,如 ap-guangzhou>", + "TENCENT_COS_BUCKET": "<替换为存储桶名称,格式 name-appid>", + "TENCENT_COS_DATASET_NAME": "<替换为数据万象数据集名称,无则删除此行>", + "TENCENT_COS_DOMAIN": "<替换为自定义域名,无则删除此行>", + "TENCENT_COS_SERVICE_DOMAIN": "<替换为自定义服务域名,无则删除此行>", + "TENCENT_COS_PROTOCOL": "<替换为协议,如 https,无则删除此行>" + } + }, + + "cos-mcp-sse": { + "_comment": "方式三:SSE 模式(适合高频调用场景)", + "command": "npx", + "args": [ + "cos-mcp", + "--connectType=sse", + "--port=3001" + ], + "env": { + "TENCENT_COS_SECRET_ID": "<替换为腾讯云 API 密钥 ID>", + "TENCENT_COS_SECRET_KEY": "<替换为腾讯云 API 密钥 Key>", + "TENCENT_COS_REGION": "<替换为存储桶区域,如 ap-guangzhou>", + "TENCENT_COS_BUCKET": "<替换为存储桶名称,格式 name-appid>", + "TENCENT_COS_DOMAIN": "<替换为自定义域名,无则删除此行>", + "TENCENT_COS_SERVICE_DOMAIN": "<替换为自定义服务域名,无则删除此行>", + "TENCENT_COS_PROTOCOL": "<替换为协议,如 https,无则删除此行>" + } + } + }, + + "_参数说明": { + "Region": "存储桶区域,如 ap-guangzhou、ap-shanghai、ap-beijing 等", + "Bucket": "存储桶名称,格式为 name-appid,如 mybucket-1250000000", + "SecretId": "腾讯云 API 密钥 ID,在 访问管理 > API密钥管理 中创建", + "SecretKey": "腾讯云 API 密钥 Key,与 SecretId 配对使用", + "DatasetName": "数据万象数据集名称(仅图片搜索等智能功能需要,无则不填)", + "Domain": "自定义域名(可选),用于替换默认的 COS 访问域名,如 cdn.example.com", + "ServiceDomain": "自定义服务域名(可选),用于自定义 COS API 请求域名", + "Protocol": "协议(可选),如 https 或 http,默认根据浏览器环境自动判断", + "connectType": "连接模式:stdio(默认,推荐)或 sse", + "port": "SSE 模式下的监听端口(默认 3001)" + } +} diff --git a/skills/tencent-cos-skill/scripts/cos_node.mjs b/skills/tencent-cos-skill/scripts/cos_node.mjs new file mode 100644 index 0000000..7b08b09 --- /dev/null +++ b/skills/tencent-cos-skill/scripts/cos_node.mjs @@ -0,0 +1,323 @@ +#!/usr/bin/env node +/** + * 腾讯云 COS Node.js SDK 操作脚本 + * 作为 cos-mcp MCP 工具不可用时的降级方案 + * + * 依赖:npm install cos-nodejs-sdk-v5 + * 凭证通过环境变量读取: + * TENCENT_COS_SECRET_ID / TENCENT_COS_SECRET_KEY / TENCENT_COS_REGION / TENCENT_COS_BUCKET + * + * 用法:node cos_node.mjs <action> [options] + */ + +import { createRequire } from 'module'; +import { createReadStream, createWriteStream, existsSync } from 'fs'; +import { basename, resolve } from 'path'; +import { pipeline } from 'stream/promises'; + +const require = createRequire(import.meta.url); +const COS = require('cos-nodejs-sdk-v5'); + +// 读取环境变量 +const SecretId = process.env.TENCENT_COS_SECRET_ID; +const SecretKey = process.env.TENCENT_COS_SECRET_KEY; +const Region = process.env.TENCENT_COS_REGION; +const Bucket = process.env.TENCENT_COS_BUCKET; + +// 可选的自定义域名配置 +const Domain = process.env.TENCENT_COS_DOMAIN; +const ServiceDomain = process.env.TENCENT_COS_SERVICE_DOMAIN; +const Protocol = process.env.TENCENT_COS_PROTOCOL; + +if (!SecretId || !SecretKey || !Region || !Bucket) { + console.error(JSON.stringify({ + success: false, + error: '缺少环境变量,需要:TENCENT_COS_SECRET_ID, TENCENT_COS_SECRET_KEY, TENCENT_COS_REGION, TENCENT_COS_BUCKET', + })); + process.exit(1); +} + +const cosOptions = { SecretId, SecretKey }; + +if (Domain) { + cosOptions.Domain = Domain; +} + +if (ServiceDomain) { + cosOptions.ServiceDomain = ServiceDomain; +} + +if (Protocol) { + cosOptions.Protocol = Protocol; +} + +const cos = new COS(cosOptions); + +// 解析命令行参数 +function parseArgs(args) { + const result = {}; + for (let i = 0; i < args.length; i++) { + const arg = args[i]; + if (arg.startsWith('--')) { + const key = arg.slice(2); + const next = args[i + 1]; + if (next && !next.startsWith('--')) { + result[key] = next; + i++; + } else { + result[key] = true; + } + } + } + return result; +} + +// 输出 JSON 结果 +function output(data) { + console.log(JSON.stringify(data, null, 2)); +} + +// 封装 COS SDK 回调为 Promise +function cosPromise(method, params) { + return new Promise((resolve, reject) => { + cos[method]({ Bucket, Region, ...params }, (err, data) => { + if (err) { + reject(err); + } else { + resolve(data); + } + }); + }); +} + +// ========== 操作实现 ========== + +async function upload(opts) { + const filePath = opts.file; + const key = opts.key || basename(filePath); + + if (!filePath) { + throw new Error('缺少 --file 参数'); + } + if (!existsSync(filePath)) { + throw new Error(`文件不存在:${filePath}`); + } + + const data = await cosPromise('putObject', { + Key: key, + Body: createReadStream(filePath), + }); + + output({ + success: true, + action: 'upload', + key, + etag: data.ETag, + location: data.Location, + statusCode: data.statusCode, + }); +} + +async function putString(opts) { + const content = opts.content; + const key = opts.key; + const contentType = opts['content-type'] || 'text/plain'; + + if (!content) { + throw new Error('缺少 --content 参数'); + } + if (!key) { + throw new Error('缺少 --key 参数'); + } + + const data = await cosPromise('putObject', { + Key: key, + Body: content, + ContentType: contentType, + }); + + output({ + success: true, + action: 'put-string', + key, + etag: data.ETag, + location: data.Location, + statusCode: data.statusCode, + }); +} + +async function download(opts) { + const key = opts.key; + const outputPath = opts.output || basename(key); + + if (!key) { + throw new Error('缺少 --key 参数'); + } + + const data = await cosPromise('getObject', { + Key: key, + }); + + const resolvedPath = resolve(outputPath); + const ws = createWriteStream(resolvedPath); + + if (data.Body instanceof Buffer) { + ws.write(data.Body); + ws.end(); + } else if (data.Body && typeof data.Body.pipe === 'function') { + await pipeline(data.Body, ws); + } else { + ws.write(String(data.Body)); + ws.end(); + } + + output({ + success: true, + action: 'download', + key, + savedTo: resolvedPath, + contentLength: data.headers?.['content-length'], + statusCode: data.statusCode, + }); +} + +async function list(opts) { + const prefix = opts.prefix || ''; + const maxKeys = parseInt(opts['max-keys'], 10) || 100; + + const data = await cosPromise('getBucket', { + Prefix: prefix, + MaxKeys: maxKeys, + }); + + const files = (data.Contents || []).map(item => ({ + key: item.Key, + size: parseInt(item.Size, 10), + lastModified: item.LastModified, + etag: item.ETag, + storageClass: item.StorageClass, + })); + + output({ + success: true, + action: 'list', + prefix, + count: files.length, + isTruncated: data.IsTruncated === 'true', + files, + }); +} + +async function signUrl(opts) { + const key = opts.key; + const expires = parseInt(opts.expires, 10) || 3600; + + if (!key) { + throw new Error('缺少 --key 参数'); + } + + const url = await new Promise((resolve, reject) => { + cos.getObjectUrl({ + Bucket, + Region, + Key: key, + Expires: expires, + Sign: true, + }, (err, data) => { + if (err) { + reject(err); + } else { + resolve(data.Url); + } + }); + }); + + output({ + success: true, + action: 'sign-url', + key, + expires, + url, + }); +} + +async function deleteObject(opts) { + const key = opts.key; + + if (!key) { + throw new Error('缺少 --key 参数'); + } + + const data = await cosPromise('deleteObject', { + Key: key, + }); + + output({ + success: true, + action: 'delete', + key, + statusCode: data.statusCode, + }); +} + +async function head(opts) { + const key = opts.key; + + if (!key) { + throw new Error('缺少 --key 参数'); + } + + const data = await cosPromise('headObject', { + Key: key, + }); + + output({ + success: true, + action: 'head', + key, + contentLength: parseInt(data.headers?.['content-length'], 10), + contentType: data.headers?.['content-type'], + etag: data.headers?.etag, + lastModified: data.headers?.['last-modified'], + storageClass: data.headers?.['x-cos-storage-class'] || 'STANDARD', + statusCode: data.statusCode, + }); +} + +// ========== 主入口 ========== + +const args = process.argv.slice(2); +const action = args[0]; +const opts = parseArgs(args.slice(1)); + +const actions = { + upload, + 'put-string': putString, + download, + list, + 'sign-url': signUrl, + delete: deleteObject, + head, +}; + +if (!action || !actions[action]) { + output({ + success: false, + error: `未知操作:${action || '(空)'}`, + availableActions: Object.keys(actions), + usage: 'node cos_node.mjs <action> [--option value ...]', + }); + process.exit(1); +} + +try { + await actions[action](opts); +} catch (err) { + output({ + success: false, + action, + error: err.message || String(err), + code: err.code, + }); + process.exit(1); +} diff --git a/skills/tencent-cos-skill/scripts/setup.sh b/skills/tencent-cos-skill/scripts/setup.sh new file mode 100644 index 0000000..68e63d2 --- /dev/null +++ b/skills/tencent-cos-skill/scripts/setup.sh @@ -0,0 +1,417 @@ +#!/bin/bash +# 腾讯云 COS Skill 自动设置脚本 +# 用法: +# setup.sh --check-only 仅检查环境状态 +# setup.sh --secret-id <ID> --secret-key <KEY> --region <REGION> --bucket <BUCKET> [--dataset <NAME>] + +set -e + +# 颜色 +GREEN='\033[0;32m' +RED='\033[0;31m' +YELLOW='\033[1;33m' +NC='\033[0m' + +ok() { echo -e "${GREEN}✓${NC} $1"; } +fail() { echo -e "${RED}✗${NC} $1"; } +warn() { echo -e "${YELLOW}!${NC} $1"; } + +# 获取脚本所在目录(skill baseDir) +SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" +BASE_DIR="$(cd "$SCRIPT_DIR/.." && pwd)" + +# ========== 检查函数 ========== + +check_node() { + if command -v node &>/dev/null; then + ok "Node.js $(node --version)" + return 0 + else + fail "Node.js 未安装" + return 1 + fi +} + +check_npm() { + if command -v npm &>/dev/null; then + ok "npm $(npm --version)" + return 0 + else + fail "npm 未安装" + return 1 + fi +} + +check_mcporter() { + if command -v mcporter &>/dev/null; then + ok "mcporter $(mcporter --version 2>/dev/null || echo '已安装')" + return 0 + else + fail "mcporter 未安装" + return 1 + fi +} + +check_mcporter_config() { + if [ -f ~/.mcporter/mcporter.json ]; then + if grep -q '"cos-mcp"' ~/.mcporter/mcporter.json 2>/dev/null; then + ok "mcporter 已配置 cos-mcp 服务器" + return 0 + else + warn "mcporter.json 存在但未配置 cos-mcp" + return 1 + fi + else + fail "~/.mcporter/mcporter.json 不存在" + return 1 + fi +} + +check_cos_mcp() { + if command -v npx &>/dev/null && npx cos-mcp --help &>/dev/null 2>&1; then + ok "cos-mcp 可用" + return 0 + else + fail "cos-mcp 未安装或不可用" + return 1 + fi +} + +check_cos_sdk() { + if node -e "require('cos-nodejs-sdk-v5')" &>/dev/null 2>&1; then + ok "cos-nodejs-sdk-v5 已安装" + return 0 + else + fail "cos-nodejs-sdk-v5 未安装" + return 1 + fi +} + +check_coscmd() { + if command -v coscmd &>/dev/null; then + ok "coscmd 可用" + return 0 + else + warn "coscmd 未安装(可选)" + return 1 + fi +} + +check_env_vars() { + local all_set=true + for var in TENCENT_COS_SECRET_ID TENCENT_COS_SECRET_KEY TENCENT_COS_REGION TENCENT_COS_BUCKET; do + if [ -n "${!var}" ]; then + ok "$var 已设置" + else + fail "$var 未设置" + all_set=false + fi + done + $all_set +} + +check_cos_conf() { + if [ -f ~/.cos.conf ]; then + ok "~/.cos.conf 已存在" + return 0 + else + warn "~/.cos.conf 不存在" + return 1 + fi +} + +# ========== 检查模式 ========== + +do_check() { + echo "=== 腾讯云 COS Skill 环境检查 ===" + echo "" + echo "--- 基础环境 ---" + check_node || true + check_npm || true + echo "" + echo "--- 方式一: cos-mcp MCP ---" + check_mcporter || true + check_mcporter_config || true + check_cos_mcp || true + echo "" + echo "--- 方式二: Node.js SDK ---" + check_cos_sdk || true + check_env_vars || true + echo "" + echo "--- 方式三: COSCMD ---" + check_coscmd || true + check_cos_conf || true + echo "" + echo "--- Skill 文件 ---" + [ -f "$BASE_DIR/SKILL.md" ] && ok "SKILL.md" || fail "SKILL.md 不存在" + [ -f "$BASE_DIR/scripts/cos_node.mjs" ] && ok "scripts/cos_node.mjs" || fail "scripts/cos_node.mjs 不存在" + [ -f "$BASE_DIR/references/config_template.json" ] && ok "references/config_template.json" || fail "references/config_template.json 不存在" + echo "" +} + +# ========== 设置模式 ========== + +do_setup() { + local SECRET_ID="" + local SECRET_KEY="" + local REGION="" + local BUCKET="" + local DATASET="" + local DOMAIN="" + local SERVICE_DOMAIN="" + local PROTOCOL="" + + while [[ $# -gt 0 ]]; do + case "$1" in + --secret-id) SECRET_ID="$2"; shift 2;; + --secret-key) SECRET_KEY="$2"; shift 2;; + --region) REGION="$2"; shift 2;; + --bucket) BUCKET="$2"; shift 2;; + --dataset) DATASET="$2"; shift 2;; + --domain) DOMAIN="$2"; shift 2;; + --service-domain) SERVICE_DOMAIN="$2"; shift 2;; + --protocol) PROTOCOL="$2"; shift 2;; + *) shift;; + esac + done + + if [ -z "$SECRET_ID" ] || [ -z "$SECRET_KEY" ] || [ -z "$REGION" ] || [ -z "$BUCKET" ]; then + echo "错误: 缺少必需参数" + echo "用法: setup.sh --secret-id <ID> --secret-key <KEY> --region <REGION> --bucket <BUCKET> [--dataset <NAME>]" + exit 1 + fi + + echo "=== 腾讯云 COS Skill 自动设置 ===" + echo "" + + # 1. 检查 Node.js + echo "--- 步骤 1: 检查 Node.js ---" + if ! check_node; then + fail "请先安装 Node.js: https://nodejs.org/" + exit 1 + fi + + # 2. 确保 package.json 存在 + echo "" + echo "--- 步骤 2: 初始化项目 ---" + if [ ! -f "$BASE_DIR/package.json" ]; then + (cd "$BASE_DIR" && npm init -y &>/dev/null) + ok "已创建 package.json" + else + ok "package.json 已存在" + fi + + # 3. 安装 cos-mcp、cos-nodejs-sdk-v5 和 mcporter + echo "" + echo "--- 步骤 3: 安装依赖 ---" + (cd "$BASE_DIR" && npm install cos-mcp cos-nodejs-sdk-v5 --no-progress 2>&1 | tail -3) + ok "cos-mcp + cos-nodejs-sdk-v5 安装完成" + + # 安装 mcporter(全局) + if ! command -v mcporter &>/dev/null; then + echo "正在安装 mcporter..." + npm install -g mcporter --no-progress 2>&1 | tail -3 + if command -v mcporter &>/dev/null; then + ok "mcporter 全局安装完成" + else + warn "mcporter 全局安装失败,尝试本地安装..." + (cd "$BASE_DIR" && npm install mcporter --no-progress 2>&1 | tail -3) + ok "mcporter 本地安装完成(使用 npx mcporter 调用)" + fi + else + ok "mcporter 已安装" + fi + + # 4. 写入环境变量到 shell 配置 + echo "" + echo "--- 步骤 4: 持久化凭证 ---" + + # 判断 shell 配置文件 + local SHELL_RC="" + if [ -n "$ZSH_VERSION" ] || [ "$SHELL" = "/bin/zsh" ]; then + SHELL_RC="$HOME/.zshrc" + else + SHELL_RC="$HOME/.bashrc" + fi + + # 先清理旧的 COS 配置 + if [ -f "$SHELL_RC" ]; then + sed -i.bak '/^# --- Tencent COS Skill ---$/,/^# --- End Tencent COS Skill ---$/d' "$SHELL_RC" + rm -f "${SHELL_RC}.bak" + fi + + # 写入新配置 + cat >> "$SHELL_RC" << EOF +# --- Tencent COS Skill --- +export TENCENT_COS_SECRET_ID="$SECRET_ID" +export TENCENT_COS_SECRET_KEY="$SECRET_KEY" +export TENCENT_COS_REGION="$REGION" +export TENCENT_COS_BUCKET="$BUCKET" +EOF + + if [ -n "$DATASET" ]; then + sed -i.bak '/^# --- End Tencent COS Skill ---$/d' "$SHELL_RC" + rm -f "${SHELL_RC}.bak" + cat >> "$SHELL_RC" << EOF +export TENCENT_COS_DATASET_NAME="$DATASET" +EOF + fi + + if [ -n "$DOMAIN" ]; then + sed -i.bak '/^# --- End Tencent COS Skill ---$/d' "$SHELL_RC" + rm -f "${SHELL_RC}.bak" + cat >> "$SHELL_RC" << EOF +export TENCENT_COS_DOMAIN="$DOMAIN" +EOF + fi + + if [ -n "$SERVICE_DOMAIN" ]; then + sed -i.bak '/^# --- End Tencent COS Skill ---$/d' "$SHELL_RC" + rm -f "${SHELL_RC}.bak" + cat >> "$SHELL_RC" << EOF +export TENCENT_COS_SERVICE_DOMAIN="$SERVICE_DOMAIN" +EOF + fi + + if [ -n "$PROTOCOL" ]; then + sed -i.bak '/^# --- End Tencent COS Skill ---$/d' "$SHELL_RC" + rm -f "${SHELL_RC}.bak" + cat >> "$SHELL_RC" << EOF +export TENCENT_COS_PROTOCOL="$PROTOCOL" +EOF + fi + + echo "# --- End Tencent COS Skill ---" >> "$SHELL_RC" + + ok "凭证已写入 $SHELL_RC" + + # 同时导出到当前 session + export TENCENT_COS_SECRET_ID="$SECRET_ID" + export TENCENT_COS_SECRET_KEY="$SECRET_KEY" + export TENCENT_COS_REGION="$REGION" + export TENCENT_COS_BUCKET="$BUCKET" + [ -n "$DATASET" ] && export TENCENT_COS_DATASET_NAME="$DATASET" + [ -n "$DOMAIN" ] && export TENCENT_COS_DOMAIN="$DOMAIN" + [ -n "$SERVICE_DOMAIN" ] && export TENCENT_COS_SERVICE_DOMAIN="$SERVICE_DOMAIN" + [ -n "$PROTOCOL" ] && export TENCENT_COS_PROTOCOL="$PROTOCOL" + + # 5. 配置 mcporter + echo "" + echo "--- 步骤 5: 配置 mcporter ---" + local MCPORTER_DIR="$HOME/.mcporter" + local MCPORTER_CONFIG="$MCPORTER_DIR/mcporter.json" + + mkdir -p "$MCPORTER_DIR" + + # 构建 cos-mcp 的 args 列表 + local COS_MCP_ARGS="\"cos-mcp\", \"--Region=$REGION\", \"--Bucket=$BUCKET\", \"--SecretId=$SECRET_ID\", \"--SecretKey=$SECRET_KEY\"" + if [ -n "$DATASET" ]; then + COS_MCP_ARGS="$COS_MCP_ARGS, \"--DatasetName=$DATASET\"" + fi + if [ -n "$DOMAIN" ]; then + COS_MCP_ARGS="$COS_MCP_ARGS, \"--Domain=$DOMAIN\"" + fi + if [ -n "$SERVICE_DOMAIN" ]; then + COS_MCP_ARGS="$COS_MCP_ARGS, \"--ServiceDomain=$SERVICE_DOMAIN\"" + fi + if [ -n "$PROTOCOL" ]; then + COS_MCP_ARGS="$COS_MCP_ARGS, \"--Protocol=$PROTOCOL\"" + fi + COS_MCP_ARGS="$COS_MCP_ARGS, \"--connectType=stdio\"" + + if [ -f "$MCPORTER_CONFIG" ]; then + # 已有配置文件,检查是否已配置 cos-mcp + if grep -q '"cos-mcp"' "$MCPORTER_CONFIG" 2>/dev/null; then + warn "mcporter.json 中已存在 cos-mcp 配置,将更新" + fi + # 使用 node 合并配置(保留其他 MCP 服务器配置) + node -e " + const fs = require('fs'); + const configPath = '$MCPORTER_CONFIG'; + let config = {}; + try { config = JSON.parse(fs.readFileSync(configPath, 'utf-8')); } catch(e) {} + if (!config.mcpServers) config.mcpServers = {}; + config.mcpServers['cos-mcp'] = { + command: 'npx', + args: [$COS_MCP_ARGS] + }; + fs.writeFileSync(configPath, JSON.stringify(config, null, 2)); + " 2>/dev/null + ok "mcporter.json 已更新 cos-mcp 配置" + else + # 创建全新的配置文件 + cat > "$MCPORTER_CONFIG" << MCPEOF +{ + "mcpServers": { + "cos-mcp": { + "command": "npx", + "args": [$COS_MCP_ARGS] + } + } +} +MCPEOF + ok "mcporter.json 已创建" + fi + + # 6. 配置 COSCMD(如果有 Python) + echo "" + echo "--- 步骤 6: 配置 COSCMD(可选) ---" + if command -v pip3 &>/dev/null || command -v pip &>/dev/null; then + local PIP_CMD + PIP_CMD=$(command -v pip3 || command -v pip) + $PIP_CMD install coscmd -q 2>/dev/null + + # 构建 coscmd config 命令 + local COSCMD_ARGS="-a $SECRET_ID -s $SECRET_KEY -b $BUCKET -r $REGION" + if [ -n "$SERVICE_DOMAIN" ]; then + COSCMD_ARGS="$COSCMD_ARGS -e $SERVICE_DOMAIN" + fi + if [ -n "$PROTOCOL" ] && [ "$PROTOCOL" = "http" ]; then + COSCMD_ARGS="$COSCMD_ARGS --do-not-use-ssl" + fi + + eval coscmd config $COSCMD_ARGS 2>/dev/null && \ + ok "coscmd 已配置" || \ + warn "coscmd 安装/配置失败(非关键)" + else + warn "Python/pip 未安装,跳过 coscmd" + fi + + # 7. 验证 + echo "" + echo "--- 步骤 7: 验证连接 ---" + if (cd "$BASE_DIR" && node scripts/cos_node.mjs list --max-keys 1 2>/dev/null | grep -q '"success": true'); then + ok "COS 连接验证成功" + else + warn "COS 连接验证失败,请检查凭证和网络" + fi + + echo "" + echo "=== 设置完成 ===" + echo "现在可以使用以下方式操作 COS:" + echo " 方式一: mcporter call cos-mcp.<tool> --config ~/.mcporter/mcporter.json --output json" + echo " 方式一(备选): cos-mcp MCP 工具(通过客户端直接调用)" + echo " 方式二: node $BASE_DIR/scripts/cos_node.mjs <action>" + echo " 方式三: coscmd <command>" +} + +# ========== 主入口 ========== + +case "$1" in + --check-only) + do_check + ;; + --secret-id|--secret-key|--region|--bucket) + do_setup "$@" + ;; + *) + echo "腾讯云 COS Skill 设置工具" + echo "" + echo "用法:" + echo " $0 --check-only" + echo " 仅检查环境状态" + echo "" + echo " $0 --secret-id <ID> --secret-key <KEY> --region <REGION> --bucket <BUCKET> [--dataset <NAME>] [--domain <DOMAIN>] [--service-domain <DOMAIN>] [--protocol <PROTOCOL>]" + echo " 自动设置环境(安装依赖 + 配置凭证 + 验证连接)" + ;; +esac diff --git a/skills/tencent-docs/.clawhub/origin.json b/skills/tencent-docs/.clawhub/origin.json new file mode 100644 index 0000000..a546d6f --- /dev/null +++ b/skills/tencent-docs/.clawhub/origin.json @@ -0,0 +1,7 @@ +{ + "version": 1, + "registry": "https://clawhub.ai", + "slug": "tencent-docs", + "installedVersion": "1.0.6", + "installedAt": 1773129532759 +} diff --git a/skills/tencent-docs/SKILL.md b/skills/tencent-docs/SKILL.md new file mode 100644 index 0000000..9df962d --- /dev/null +++ b/skills/tencent-docs/SKILL.md @@ -0,0 +1,435 @@ +--- +name: tencent-docs +description: 腾讯文档,提供完整的腾讯文档操作能力。当用户需要操作腾讯文档时使用此skill,包括:(1) 创建各类在线文档(智能文档、Word、Excel、幻灯片、思维导图、流程图)(2) 查询、搜索文档空间与文件 (3) 管理空间节点、文件夹结构 (4) 读取文档内容 (5) 编辑操作智能表 (6)编辑操作智能文档。 +homepage: https://docs.qq.com/home +metadata: {"openclaw":{"requires":{"env":["TENCENT_DOCS_TOKEN"]},"primaryEnv":"TENCENT_DOCS_TOKEN","category":"tencent","tencentTokenMode":"custom","tokenUrl":"https://docs.qq.com/open/document/mcp/get-token/","emoji":"📝"}} +--- + +# 腾讯文档 MCP 使用指南 + +腾讯文档 MCP 提供了一套完整的在线文档操作工具,支持创建、查询、编辑多种类型的在线文档。 + +## 📚 详细参考文档 + +如需查看每个工具的详细调用示例、参数说明和返回值说明,请参考: +- `references/api_references.md` - 包含所有工具的完整调用示例、参数说明、返回值说明及 API 结构、枚举值说明 +- `references/smartsheet_references.md` - 智能表格(SmartSheet)专项参考文档,包含字段类型枚举、字段值格式参考、典型工作流示例及所有 `smartsheet.*` 工具的详细说明 +- `references/smartcanvas_references.md` - 智能文档(SmartCanvas)专项参考文档,包含元素类型说明、富文本格式枚举、典型工作流示例及所有 `smartcanvas.*` 工具的详细说明 + +## ⚙️ 配置要求 + +根据你所使用的环境,选择对应的配置方式: + +### ✅ 场景一:CodeBuddy / 其他 IDE(推荐) + +**无需额外安装**,在 IDE 的 MCP 配置中添加腾讯文档服务即可直接使用。 + +**配置步骤:** + +1. 访问 [https://docs.qq.com/open/auth/mcp.html](https://docs.qq.com/open/auth/mcp.html) 获取你的个人 Token +2. 在 IDE 的 MCP 配置中添加以下服务: + +```json +{ + "mcpServers": { + "tencent-docs": { + "url": "https://docs.qq.com/openapi/mcp", + "headers": { + "Authorization": "你的Token值" + } + } + } +} +``` + +> ⚠️ **重要**:Header 的 key **必须**使用 `Authorization`,不能使用其他名称(如 `token`、`auth`、`X-Token` 等),否则鉴权将失败。 + +3. 配置完成后,即可在 IDE 中直接调用所有腾讯文档工具,无需任何额外步骤。 + +--- + +### 🔧 场景二:OpenClaw(需要安装) + +在 OpenClaw 中使用时,需要先完成本地安装和注册。 + +**安装步骤:** + +1. 访问 [https://docs.qq.com/open/auth/mcp.html](https://docs.qq.com/open/auth/mcp.html) 获取 Token,并配置环境变量: + +```bash +export TENCENT_DOCS_TOKEN="你的Token值" +``` + +2. 运行 setup.sh 完成 MCP 服务注册: + +```bash +bash setup.sh +``` + +> setup.sh 会自动将腾讯文档 MCP 服务注册到 mcporter,并验证配置是否成功。 +> 如果未执行 setup,所有工具调用将无法找到 `tencent-docs` 服务。 + +3. 验证安装是否成功: + +```bash +mcporter list | grep tencent-docs +``` + +> ⚠️ **如果用户未配置 Token**,请引导用户访问上方链接获取 Token,否则所有工具调用将返回鉴权失败。 + +--- + +## 🚨 错误码处理 + +### 常见错误码及解决方案 + +| 错误码 | 错误类型 | 解决方案 | +|--------|----------|----------| +| **400006** | **Token 鉴权失败** | 🔑 **检查 Token 配置**:确认 Header 的 key **必须**使用 `Authorization`;同时确认 Token 值正确,可访问 [https://docs.qq.com/open/auth/mcp.html](https://docs.qq.com/open/auth/mcp.html) 重新获取 | +| **400007** | **VIP权限不足** | ⭐ **立即升级VIP**:访问 [https://docs.qq.com/vip?immediate_buy=1](https://docs.qq.com/vip?immediate_buy=1) 购买VIP服务 | + +## 🔧 调用方式 + +腾讯文档 MCP 的标准配置名称为 **`tencent-docs`**,通过内置 MCP Client 直接调用工具: + +``` +mcp: tencent-docs +tool: <工具名称> +arguments: { ... } +``` + +> ⚠️ **注意**:`arguments` 必须是 **JSON 对象**,不能是字符串(即不能是 `"{ ... }"` 这样的字符串形式)。 + +### 支持的工具完整列表 + +> ⚠️ **以下工具列表仅供参考,实际可用工具以调用 `tools/list` 接口返回结果为准。** +> +> 获取最新工具列表: +> ``` +> mcp: tencent-docs +> method: tools/list +> ``` + +| 工具名称 | MCP 调用格式 | 功能说明 | +|---------|-------------|---------| +| create_smartcanvas_by_markdown | `create_smartcanvas_by_markdown` | ⭐ 创建智能文档(首选) | +| create_excel_by_markdown | `create_excel_by_markdown` | 创建 Excel 表格 | +| create_slide_by_markdown | `create_slide_by_markdown` | 创建幻灯片 | +| create_mind_by_markdown | `create_mind_by_markdown` | 创建思维导图 | +| create_flowchart_by_mermaid | `create_flowchart_by_mermaid` | 创建流程图 | +| create_word_by_markdown | `create_word_by_markdown` | 创建 Word 文档 | +| query_space_node | `query_space_node` | 查询空间节点 | +| create_space_node | `create_space_node` | 创建空间节点 | +| delete_space_node | `delete_space_node` | 删除空间节点 | +| search_space_file | `search_space_file` | 搜索空间文件 | +| get_content | `get_content` | 获取文档内容 | +| batch_update_sheet_range | `batch_update_sheet_range` | 批量更新表格 | +| smartcanvas.* | 见下方第 4 节 | 智能文档元素操作(页面/文本/标题/待办事项),详见 `references/smartcanvas_references.md` | +| smartsheet.* | 见下方第 5 节 | 智能表格操作(工作表/视图/字段/记录),详见 `references/smartsheet_references.md` | + +**详细调用示例请参考:`references/api_references.md`** + +## ⭐ 重要:文档类型选择指南 + +> **首选推荐:智能文档(smartcanvas)** +> +> - **新增文档**:优先使用 `create_smartcanvas_by_markdown` 创建智能文档,原因如下: +> - 📝 排版效果更美观,自动优化布局 +> - 🎨 支持更丰富的格式(标题、段落、列表、表格、代码块、引用、图片等) +> - 📱 跨平台显示效果一致 +> - **编辑已有文档**:使用 `smartcanvas.*` 系列工具对已有智能文档进行增删改查操作,详见 `references/smartcanvas_references.md` + +### 文档类型选择决策树 + +``` +需要创建什么类型的内容? +│ +├─ 新增通用文档内容(报告、笔记、文章等) +│ └─ ✅ 使用 create_smartcanvas_by_markdown(首选) +│ +├─ 编辑/追加已有智能文档内容 +│ └─ ✅ 使用 smartcanvas.* 工具(详见 `references/smartcanvas_references.md`) +│ +├─ 数据表格(需要计算、筛选、统计) +│ └─ ✅ 使用 create_excel_by_markdown +│ +├─ 演示文稿(需要逐页展示、投影演示) +│ └─ ✅ 使用 create_slide_by_markdown +│ +├─ 层次化知识整理(知识图谱、大纲) +│ └─ ✅ 使用 create_mind_by_markdown +│ +├─ 流程/架构展示(流程图、时序图) +│ └─ ✅ 使用 create_flowchart_by_mermaid +│ +├─ 结构化数据管理(多视图、字段管理、看板) +│ └─ ✅ 使用 smartsheet.* 工具(详见 `references/smartsheet_references.md`) +│ +└─ 传统 Word 格式导出需求 + └─ 使用 create_word_by_markdown(仅在明确需要时) +``` + +## 支持的文档类型 + +| 类型 | doc_type | 推荐度 | 说明 | +|------|----------|--------|------| +| **智能文档** | smartcanvas | ⭐⭐⭐ **首选** | 排版美观,支持丰富组件 | +| Excel | excel | ⭐⭐⭐ | 数据表格专用 | +| 幻灯片 | slide | ⭐⭐⭐ | 演示文稿专用 | +| 思维导图 | mind | ⭐⭐⭐ | 知识图谱专用 | +| 流程图 | flowchart | ⭐⭐⭐ | 流程展示专用 | +| Word | word | ⭐⭐ | 传统格式,排版一般 | +| 收集表 | form | ⭐⭐ | 表单收集 | +| 智能表格 | smartsheet | ⭐⭐⭐ | 高级结构化表格,支持多视图、字段管理 | +| 白板 | board | ⭐⭐ | 在线白板 | + +## 工具列表 + +> 📖 所有工具的完整调用示例、参数说明和返回值说明,请查阅 `references/api_references.md` +> +> ⚠️ **此 skill 中的工具列表仅作使用指导,实际可用工具以调用 `tools/list` 接口返回结果为准。** 如遇工具不存在或参数不符,请先执行 `tools/list` 获取最新工具定义。 + +### 1. 创建文档类 + +#### ⭐ create_smartcanvas_by_markdown(首选) + +**通用文档首选工具**,通过 Markdown 创建智能文档,排版美观,支持所有 Markdown 基本结构。 + +**适用场景**: +- 📄 文档、报告、笔记、文章 +- 📋 会议纪要、方案说明 +- 📚 技术文档、教程 +- 🗒️ 任何需要美观排版的内容 + +**支持 `parent_id` 参数**:可指定父节点 ID,将文档创建到指定目录下;不填则在根目录创建。 + +> 📖 调用示例请参考:`references/api_references.md` - create_smartcanvas_by_markdown + +#### create_excel_by_markdown + +通过 Markdown 表格创建 Excel,适用于需要数据计算、筛选的场景。 + +**适用场景**:数据报表、统计表格、需要公式计算的场景 + +**支持 `parent_id` 参数**:可指定父节点 ID,将文档创建到指定目录下;不填则在根目录创建。 + +> 📖 调用示例请参考:`references/api_references.md` - create_excel_by_markdown + +#### create_slide_by_markdown + +通过 Markdown 创建幻灯片,遵循特定层级结构(`#` 主标题 → `##` 章节 → `###` 页面 → `-` 段落 → 缩进子项正文)。 + +**适用场景**:演示文稿、项目汇报、培训材料 + +**支持 `parent_id` 参数**:可指定父节点 ID,将文档创建到指定目录下;不填则在根目录创建。 + +> 📖 调用示例请参考:`references/api_references.md` - create_slide_by_markdown + +#### create_mind_by_markdown + +通过 Markdown 创建思维导图,使用标题层级和列表嵌套表示结构。 + +**适用场景**:知识图谱、大纲整理、头脑风暴 + +**支持 `parent_id` 参数**:可指定父节点 ID,将文档创建到指定目录下;不填则在根目录创建。 + +> 📖 调用示例请参考:`references/api_references.md` - create_mind_by_markdown + +#### create_flowchart_by_mermaid + +通过 Mermaid 语法创建流程图,mermaid 字段内容必须全部使用英文。 + +**适用场景**:流程图、时序图、架构图 + +**支持 `parent_id` 参数**:可指定父节点 ID,将文档创建到指定目录下;不填则在根目录创建。 + +> 📖 调用示例请参考:`references/api_references.md` - create_flowchart_by_mermaid + +#### create_word_by_markdown + +通过 Markdown 创建 Word 文档。**注意:仅在用户明确要求 Word 格式时使用,否则请使用 smartcanvas**。 + +**支持 `parent_id` 参数**:可指定父节点 ID,将文档创建到指定目录下;不填则在根目录创建。 + +> 📖 调用示例请参考:`references/api_references.md` - create_word_by_markdown + +### 2. 空间管理类 + +#### query_space_node + +查询空间节点树结构,获取文件夹和文档列表。支持分页,每页返回 20 条。 + +> 📖 调用示例请参考:`references/api_references.md` - query_space_node + +#### create_space_node + +在空间中创建新节点,支持创建文件夹(`wiki_folder`)、在线文档(`wiki_tdoc`)、链接(`link`)。 + +> 📖 调用示例请参考:`references/api_references.md` - create_space_node + +#### search_space_file + +在空间内搜索文档,支持按关键词匹配标题和内容,支持分页,每页返回 40 条。 + +> ⚠️ 注意:仅能搜索到文档类节点(word、excel、slide 等),无法搜索文件夹;如需查找文件夹,请使用 `query_space_node` 遍历节点树。 + +> 📖 调用示例请参考:`references/api_references.md` - search_space_file + +#### delete_space_node + +删除空间中的指定节点,支持两种删除模式。 + +**删除类型(remove_type)**: +- `current`(默认):仅删除当前节点,子节点自动挂载到上级节点 +- `all`:删除当前节点及其所有子节点(⚠️ 谨慎使用,会递归删除所有子节点) + +> 📖 调用示例请参考:`references/api_references.md` - delete_space_node + +### 3. 文档操作类 + +#### get_content + +获取文档完整内容,传入 `file_id` 返回文档正文文本。 + +> 📖 调用示例请参考:`references/api_references.md` - get_content + +#### batch_update_sheet_range + +批量更新表格单元格内容(仅适用于 Excel),数据从表格末尾追加,不覆盖已有内容。 + +> 📖 调用示例请参考:`references/api_references.md` - batch_update_sheet_range + +#### smartcanvas.create_smartcanvas_element + +在已有智能文档中新增元素,支持添加页面(Page)、文本(Text)、标题(Heading)、待办事项(Task)等多种类型元素。 + +**元素层级约束**: +- `Text`、`Task`、`Heading` 必须挂载在 `Page` 类型父节点下(`parent_id` 必填) +- `Page` 可不指定父节点,插入到根节点 +- 父节点不支持为 `Heading` 类型 + +> 📖 完整说明请参考:`references/smartcanvas_references.md` - smartcanvas.create_smartcanvas_element + +#### smartcanvas.get_element_info + +批量查询指定元素的详细信息,支持同时查询多个元素的内容、类型、父子关系等。 + +> 📖 完整说明请参考:`references/smartcanvas_references.md` - smartcanvas.get_element_info + +#### smartcanvas.get_page_info + +查询指定页面内的所有元素,支持分页获取。使用 `cursor` 参数进行分页,`is_over=true` 表示已获取全部内容。 + +> 📖 完整说明请参考:`references/smartcanvas_references.md` - smartcanvas.get_page_info + +#### smartcanvas.get_top_level_pages + +查询文档的所有顶层页面列表,返回根节点下的直接子页面,用于了解文档目录结构。 + +> 📖 完整说明请参考:`references/smartcanvas_references.md` - smartcanvas.get_top_level_pages + +#### smartcanvas.update_element + +批量修改元素内容,支持同时更新多个元素的文本、格式、标题级别、页面标题等属性。 + +> 📖 完整说明请参考:`references/smartcanvas_references.md` - smartcanvas.update_element + +#### smartcanvas.delete_element + +批量删除元素,支持同时删除多个指定元素。 + +> ⚠️ 删除 Page 元素时,其下所有子元素也会被一并删除,请谨慎操作。 + +> 📖 完整说明请参考:`references/smartcanvas_references.md` - smartcanvas.delete_element + +#### smartcanvas.append_insert_smartcanvas_by_markdown + +通过 Markdown 文本向已有智能文档追加内容,内容追加到文档末尾。 + +> 📖 完整说明请参考:`references/smartcanvas_references.md` - smartcanvas.append_insert_smartcanvas_by_markdown + +### 4. 智能文档(SmartCanvas)元素操作类 + +智能文档支持对页面、文本、标题、待办事项等元素进行完整的增删改查操作,共 7 个工具(`smartcanvas.*`)。 + +> 📖 **所有工具的完整说明(使用场景、元素类型定义、枚举值、参数示例)请查阅:`references/smartcanvas_references.md`** +> +> 包含:元素新增、元素查询、页面内容查询、顶层页面查询、元素修改、元素删除、Markdown 追加,以及标题级别枚举、颜色枚举、富文本格式说明、典型工作流示例。 + +### 5. 智能表格(SmartSheet)操作类 + +智能表格支持对工作表、视图、字段、记录进行完整的增删改查操作,共 12 个工具(`smartsheet.*`)。 + +> 📖 **所有工具的完整说明(使用场景、字段定义、枚举值、参数示例)请查阅:`references/smartsheet_references.md`** +> +> 包含:工作表操作、视图操作、字段操作、记录操作,以及字段类型枚举、字段值格式参考、典型工作流示例。 + +## 常见工作流 + +### 创建通用文档(推荐方式) + +``` +1. 优先调用 create_smartcanvas_by_markdown 创建智能文档 +2. 从返回结果中获取 file_id 和 url +``` + +### 编辑已有智能文档 + +``` +1. 调用 smartcanvas.get_top_level_pages 获取文档页面结构 +2. 按需调用 smartcanvas.* 工具进行增删改查: + - 追加内容:smartcanvas.append_insert_smartcanvas_by_markdown(Markdown 方式) + - 新增元素:smartcanvas.create_smartcanvas_element + - 查询元素:smartcanvas.get_element_info / smartcanvas.get_page_info + - 修改元素:smartcanvas.update_element + - 删除元素:smartcanvas.delete_element +``` + +### 组织文档到指定目录 + +1. 调用 `query_space_node` 查找目标文件夹 +2. 调用 `create_space_node` 在目标位置创建文档节点(doc_type 优先选择 smartcanvas) + +### 搜索并读取文档 + +1. 调用 `search_space_file` 搜索文档 +2. 从结果中获取 `node_id`(即 `file_id`) +3. 调用 `get_content` 获取文档内容 + +### 智能表格操作工作流 + +#### 从零搭建任务管理表 + +``` +1. 获取工作表列表 → smartsheet.list_tables(获取 sheet_id) +2. 添加字段(列)→ smartsheet.add_fields(任务名称、优先级、截止日期等) +3. 批量写入数据 → smartsheet.add_records +4. (可选)创建看板视图 → smartsheet.add_view(view_type=2) +``` + +#### 查询并更新数据 + +``` +1. 获取工作表 → smartsheet.list_tables +2. 查询记录 → smartsheet.list_records(获取 record_id) +3. 更新记录 → smartsheet.update_records(传入 record_id 和新字段值) +``` + +> 📖 更多智能表格工作流示例请参考:`references/smartsheet_references.md` - 典型工作流示例 + +## 注意事项 + +- **默认使用 smartcanvas**:除非用户明确指定其他格式,否则**新增文档**时优先使用 `create_smartcanvas_by_markdown`;**编辑已有智能文档**时使用 `smartcanvas.*` 系列工具 +- **创建文档时支持 `parent_id`**:所有 `create_*_by_markdown` 和 `create_flowchart_by_mermaid` 工具均支持 `parent_id` 参数,可将文档直接创建到指定目录;不填则在根目录创建 +- **删除节点**:`delete_space_node` 默认仅删除当前节点(`remove_type=current`),使用 `all` 时会递归删除所有子节点,需谨慎 +- Markdown 内容使用 UTF-8 格式,特殊字符无需转义 +- 幻灯片必须遵循层级结构,每页包含 2-4 个段落标题 +- 分页查询每页返回 20-40 条记录,使用 `has_next` 判断是否有更多 +- `node_id` 同时也是文档的 `file_id` +- `create_flowchart_by_mermaid` 的 mermaid 内容必须全部使用英文 +- **智能文档元素操作**:`Text`、`Heading`、`Task` 必须挂载在 `Page` 下,`parent_id` 必须为 Page 类型元素 ID;操作前先调用 `smartcanvas.get_top_level_pages` 获取页面结构 +- **智能文档分页查询**:`smartcanvas.get_page_info` 使用 `cursor` 分页,`is_over=true` 表示已获取全部内容 +- **智能文档删除注意**:删除 Page 元素时,其下所有子元素也会被一并删除 +- **智能表格操作**:所有 smartsheet.* 工具都需要 `file_id` 和 `sheet_id`,操作前先调用 `smartsheet.list_tables` 获取 sheet_id +- **字段类型不可更新**:`update_fields` 时 field_type 不能修改,但必须传入原值 +- **记录字段值格式**:不同字段类型的值格式不同,详见 `references/smartsheet_references.md` - 字段值格式参考 \ No newline at end of file diff --git a/skills/tencent-docs/_meta.json b/skills/tencent-docs/_meta.json new file mode 100644 index 0000000..9038b5c --- /dev/null +++ b/skills/tencent-docs/_meta.json @@ -0,0 +1,6 @@ +{ + "ownerId": "kn71n4rrmmw7469qstfds7c2z181y79z", + "slug": "tencent-docs", + "version": "1.0.6", + "publishedAt": 1773073135580 +} \ No newline at end of file diff --git a/skills/tencent-docs/references/api_references.md b/skills/tencent-docs/references/api_references.md new file mode 100644 index 0000000..fbfcd7e --- /dev/null +++ b/skills/tencent-docs/references/api_references.md @@ -0,0 +1,487 @@ +# 腾讯文档 MCP 工具完整参考 + +本文件包含腾讯文档 MCP 所有工具的通用 API 说明、详细调用示例、参数说明和返回值说明。 + +--- + +## 通用说明 + +### 响应结构 + +所有 API 返回都包含: +- `error`: 错误信息(成功时为空) +- `trace_id`: 调用链追踪 ID + +### node_type 枚举值 + +| 值 | 说明 | +|---|---| +| wiki_folder | 文件夹 | +| wiki_tdoc | 在线文档(请求时使用) | +| wiki_file | 在线文档(返回值中使用) | +| link | 链接 | +| resource | 资源文件 | + +### doc_type 枚举值 + +| 值 | 说明 | +|---|---| +| word | 文字处理文档 | +| excel | 电子表格 | +| form | 收集表 | +| slide | 幻灯片 | +| smartcanvas | 智能文档 | +| smartsheet | 智能表格 | +| board | 白板 | +| mind | 思维导图 | +| flowchart | 流程图 | + +### NodeInfo 节点信息结构 + +```json +{ + "node_id": "节点 ID,同时也是 file_id", + "title": "节点标题", + "node_type": "节点类型", + "has_child": true, + "doc_type": "文档类型(仅 wiki_file 有效)", + "url": "访问链接" +} +``` + +### StringMatrix 表格数据结构 + +```json +{ + "texts": { + "rows": [ + {"values": ["单元格1", "单元格2"]}, + {"values": ["单元格3", "单元格4"]} + ] + } +} +``` + +数据从 A1 单元格开始,按行列顺序填充。 + +### 分页说明 + +- `query_space_node`:每页 20 条 +- `search_space_file`:每页 40 条 +- 使用 `has_next` 判断是否有更多数据 +- 页码从 0 开始 + +--- + +## 工具调用示例 + +## 1. create_smartcanvas_by_markdown + +### 功能说明 +通过 Markdown 格式创建智能文档,排版美观,支持所有 Markdown 基本结构。 + +### 调用示例 +```json +{ + "title": "项目需求文档", + "markdown": "# 项目需求\n\n## 项目背景\n\n本项目旨在开发一套智能文档管理系统...\n\n## 功能需求\n\n- 文档创建功能\n- 文档编辑功能\n- 协作功能\n\n## 技术架构\n\n| 组件 | 技术选型 |\n|------|----------|\n| 前端 | React |\n| 后端 | Go |\n| 数据库 | MySQL |", + "parent_id": "folder_1234567890" +} +``` + +### 参数说明 +- `title` (string, 必填): 文档标题 +- `markdown` (string, 必填): UTF-8 格式的 Markdown 文本 +- `parent_id` (string, 可选): 父节点ID,为空时在空间根目录创建,不为空时在指定节点下创建 + +### 返回值说明 +```json +{ + "file_id": "doc_1234567890", + "url": "https://docs.qq.com/doc/DV2h5cWJ0R1lQb0lH", + "error": "", + "trace_id": "trace_1234567890" +} +``` + +## 2. create_excel_by_markdown + +### 功能说明 +通过 Markdown 表格创建 Excel,适用于需要数据计算、筛选的场景。 + +### 调用示例 +```json +{ + "title": "销售数据报表", + "markdown": "| 日期 | 产品 | 销售额 | 销售量 |\n|------|------|--------|--------|\n| 2024-01-01 | 产品A | 10000 | 100 |\n| 2024-01-02 | 产品B | 15000 | 150 |", + "parent_id": "folder_1234567890" +} +``` + +### 参数说明 +- `title` (string, 必填): 表格标题 +- `markdown` (string, 必填): 包含表格的 Markdown 文本 +- `parent_id` (string, 可选): 父节点ID,为空时在空间根目录创建,不为空时在指定节点下创建 + +### 返回值说明 +```json +{ + "file_id": "sheet_1234567890", + "url": "https://docs.qq.com/sheet/DV2h5cWJ0R1lQb0lH", + "error": "", + "trace_id": "trace_1234567890" +} +``` + +## 3. create_slide_by_markdown + +### 功能说明 +通过 Markdown 创建幻灯片,遵循特定层级结构。 + +### Markdown 层级结构规范 + +PPT 必须遵循严格的层级结构: + +``` +# 一级标题 → PPT 主标题(整个演示文稿的标题) +## 二级标题 → 章节标题(区分不同主题章节) +### 三级标题 → 页面标题(每个幻灯片的标题) +- 列表项 → 段落标题(每页 2-4 个) + - 子列表项 → 正文内容(每段约 200 字) +``` + +### 调用示例 +```json +{ + "title": "项目汇报", + "markdown": "# 项目汇报\n\n## 项目背景\n\n### 项目概述\n\n- 项目目标\n - 本项目旨在开发一套智能文档管理系统,提升团队协作效率\n- 项目范围\n - 系统将涵盖文档创建、编辑、协作等功能\n\n### 市场分析\n\n- 市场需求\n - 当前市场对智能文档管理系统的需求日益增长\n- 竞争分析\n - 现有竞品在功能完整性方面存在不足", + "parent_id": "folder_1234567890" +} +``` + +### 参数说明 +- `title` (string, 必填): 幻灯片标题 +- `markdown` (string, 必填): 遵循幻灯片层级结构的 Markdown 文本 +- `parent_id` (string, 可选): 父节点ID,为空时在空间根目录创建,不为空时在指定节点下创建 + +### 返回值说明 +```json +{ + "file_id": "slide_1234567890", + "url": "https://docs.qq.com/slide/DV2h5cWJ0R1lQb0lH", + "error": "", + "trace_id": "trace_1234567890" +} +``` + +## 4. create_mind_by_markdown + +### 功能说明 +通过 Markdown 创建思维导图,使用标题层级和列表嵌套表示结构。 + +### 调用示例 +```json +{ + "title": "产品功能规划", + "markdown": "# 产品功能规划\n\n## 核心功能\n\n- 文档管理\n - 创建文档\n - 编辑文档\n - 版本控制\n\n## 协作功能\n\n- 实时协作\n- 评论系统\n- 权限管理", + "parent_id": "folder_1234567890" +} +``` + +### 参数说明 +- `title` (string, 必填): 思维导图标题 +- `markdown` (string, 必填): 层次化的 Markdown 文本 +- `parent_id` (string, 可选): 父节点ID,为空时在空间根目录创建,不为空时在指定节点下创建 + +### 返回值说明 +```json +{ + "file_id": "mind_1234567890", + "url": "https://docs.qq.com/mind/DV2h5cWJ0R1lQb0lH", + "error": "", + "trace_id": "trace_1234567890" +} +``` + +## 5. create_flowchart_by_mermaid + +### 功能说明 +通过 Mermaid 语法创建流程图。 + +### 调用示例 +```json +{ + "title": "用户登录流程", + "mermaid": "graph TD\n A[User Access] --> B{Logged in?}\n B -->|Yes| C[Go to Home]\n B -->|No| D[Go to Login Page]\n D --> E[Enter Username and Password]\n E --> F{Auth Success?}\n F -->|Yes| C\n F -->|No| G[Show Error Message]\n G --> E", + "parent_id": "folder_1234567890" +} +``` + +### 参数说明 +- `title` (string, 必填): 流程图标题 +- `mermaid` (string, 必填): 不包含中文的 Mermaid 语法文本 +- `parent_id` (string, 可选): 父节点ID,为空时在空间根目录创建,不为空时在指定节点下创建 + +### 返回值说明 +```json +{ + "file_id": "flow_1234567890", + "url": "https://docs.qq.com/flow/DV2h5cWJ0R1lQb0lH", + "error": "", + "trace_id": "trace_1234567890" +} +``` + +## 6. create_word_by_markdown + +### 功能说明 +通过 Markdown 创建 Word 文档。 + +### 调用示例 +```json +{ + "title": "技术文档", + "markdown": "# 技术文档\n\n## 系统架构\n\n本文档描述系统的技术架构设计...\n\n## 数据库设计\n\n| 表名 | 说明 |\n|------|------|\n| users | 用户表 |\n| documents | 文档表 |", + "parent_id": "folder_1234567890" +} +``` + +### 参数说明 +- `title` (string, 必填): Word 文档标题 +- `markdown` (string, 必填): UTF-8 格式的 Markdown 文本 +- `parent_id` (string, 可选): 父节点ID,为空时在空间根目录创建,不为空时在指定节点下创建 + +### 返回值说明 +```json +{ + "file_id": "word_1234567890", + "url": "https://docs.qq.com/doc/DV2h5cWJ0R1lQb0lH", + "error": "", + "trace_id": "trace_1234567890" +} +``` + +## 7. query_space_node + +### 功能说明 +查询空间节点树结构,获取文件夹和文档列表。 + +### 调用示例 +```json +{ + "parent_id": "folder_1234567890", + "num": 0 +} +``` + +### 参数说明 +- `parent_id` (string, 可选): 父节点ID,为空时返回根节点 +- `num` (uint32, 可选): 分页页码,从0开始,每页返回20个节点 + +### 返回值说明 +```json +{ + "children": [ + { + "node_id": "doc_1234567890", + "title": "项目文档", + "node_type": "wiki_file", + "has_child": false, + "doc_type": "smartcanvas", + "url": "https://docs.qq.com/doc/DV2h5cWJ0R1lQb0lH" + } + ], + "error": "", + "has_next": false, + "trace_id": "trace_1234567890" +} +``` + +## 8. create_space_node + +### 功能说明 +在空间中创建新节点(文件夹、文档或链接)。 + +### 调用示例 +```json +{ + "parent_node_id": "folder_1234567890", + "title": "新建页面文档1", + "node_type": "wiki_tdoc", + "wiki_tdoc_node": { + "title": "新建页面文档", + "doc_type": "smartcanvas" + } +} +``` + +### 参数说明 +- `parent_node_id` (string, 可选): 父节点ID,为空或在根目录创建时可不传 +- `title` (string, 必填): 节点标题 +- `node_type` (string, 必填): 节点类型(wiki_folder/wiki_tdoc/link) +- `is_before` (bool, 可选): 插入位置,true 表示插入到父节点子列表开头,false 表示插入到末尾 +- `wiki_folder_node` (object, 可选): 文件夹节点配置,node_type 为 wiki_folder 时必填 +- `wiki_tdoc_node` (object, 可选): 在线文档节点配置,node_type 为 wiki_tdoc 时必填 +- `link_node` (object, 可选): 链接节点配置,node_type 为 link 时必填 + +### 返回值说明 +```json +{ + "node_info": { + "node_id": "doc_1234567890", + "title": "新建页面文档", + "node_type": "wiki_file", + "has_child": false, + "doc_type": "smartcanvas", + "url": "https://docs.qq.com/doc/DV2h5cWJ0R1lQb0lH" + }, + "error": "", + "trace_id": "trace_1234567890" +} +``` + +## 9. delete_space_node + +### 功能说明 +删除空间中的指定节点。仅删除当前节点时,子节点自动挂载到上级节点;使用 `all` 模式时递归删除所有子节点(谨慎使用)。 + +### 调用示例 +```json +{ + "node_id": "doc_1234567890", + "remove_type": "current" +} +``` + +### 参数说明 +- `node_id` (string, 必填): 要删除的节点ID +- `remove_type` (string, 可选): 删除类型,枚举值:`current`(默认,仅删除当前节点,子节点挂载到上级)、`all`(删除当前节点及所有子节点,⚠️ 谨慎使用) + +### 返回值说明 +```json +{ + "error": "", + "trace_id": "trace_1234567890" +} +``` + +## 10. search_space_file + +### 功能说明 +在空间内搜索文档。注意:仅能搜索到文档类节点(word、excel、slide 等),无法搜索到文件夹节点;如需查找文件夹,请使用 `query_space_node` 遍历节点树。 + +### 调用示例 +```json +{ + "pattern": "项目文档", + "queryby": 2, + "descending": true, + "num": 0 +} +``` + +### 参数说明 +- `pattern` (string, 必填): 搜索关键词 +- `queryby` (int32, 可选): 排序方式(1-创建时间,2-修改时间) +- `descending` (bool, 可选): 排序方向(true-降序) +- `num` (uint32, 可选): 分页页码,从0开始,每页返回40条 + +### 返回值说明 +```json +{ + "nodes": [ + { + "node_id": "doc_1234567890", + "title": "项目文档", + "node_type": "wiki_file", + "has_child": false, + "doc_type": "smartcanvas", + "url": "https://docs.qq.com/doc/DV2h5cWJ0R1lQb0lH" + } + ], + "error": "", + "has_next": false, + "trace_id": "trace_1234567890" +} +``` + +## 11. get_content + +### 功能说明 +获取文档完整内容。 + +### 调用示例 +```json +{ + "file_id": "doc_1234567890" +} +``` + +### 参数说明 +- `file_id` (string, 必填): 文档唯一标识符 + +### 返回值说明 +```json +{ + "content": "# 项目文档\n\n这是文档的完整内容...", + "error": "", + "trace_id": "trace_1234567890" +} +``` + +## 12. batch_update_sheet_range + +### 功能说明 +批量更新表格单元格内容。数据将从表格末尾开始追加新行,不会覆盖已有内容。 + +### 调用示例 +```json +{ + "file_id": "sheet_1234567890", + "texts": { + "rows": [ + {"values": ["姓名", "年龄", "部门"]}, + {"values": ["张三", "25", "技术部"]}, + {"values": ["李四", "30", "产品部"]} + ] + } +} +``` + +### 参数说明 +- `file_id` (string, 必填): 表格唯一标识符 +- `texts` (object, 必填): 二维文本数组,数据从 A1 单元格开始按行列顺序填充 + +### 返回值说明 +```json +{ + "update_num": 6, + "error": "", + "trace_id": "trace_1234567890" +} +``` + +## 13. create_smartcanvas_element + +### 功能说明 +在已有智能文档中追加内容。 + +### 调用示例 +```json +{ + "file_id": "doc_1234567890", + "markdown": "## 新增内容\n\n这是追加到文档末尾的新内容..." +} +``` + +### 参数说明 +- `file_id` (string, 必填): 文档唯一标识符 +- `markdown` (string, 必填): 要追加的 Markdown 内容 + +### 返回值说明 +```json +{ + "error": "", + "trace_id": "trace_1234567890" +} +``` diff --git a/skills/tencent-docs/references/smartcanvas_references.md b/skills/tencent-docs/references/smartcanvas_references.md new file mode 100644 index 0000000..f0b6ae8 --- /dev/null +++ b/skills/tencent-docs/references/smartcanvas_references.md @@ -0,0 +1,793 @@ +# 智能文档(SmartCanvas)工具完整参考文档 + +腾讯文档智能文档(SmartCanvas)提供了一套完整的文档元素操作 API,支持对页面、文本、标题、待办事项等元素进行增删改查操作。 + +--- + +## 目录 + +- [概念说明](#概念说明) +- [元素操作](#元素操作) +- [smartcanvas.create_smartcanvas_element - 新增元素](#smartcanvascreatesmartcanvaselement) + - [smartcanvas.get_element_info - 查询元素信息](#smartcanvasgetelement_info) + - [smartcanvas.get_page_info - 查询页面内容](#smartcanvasgetpageinfo) + - [smartcanvas.get_top_level_pages - 查询顶层页面](#smartcanvasgettoplevelpages) + - [smartcanvas.update_element - 修改元素](#smartcanvasupdateelement) + - [smartcanvas.delete_element - 删除元素](#smartcanvasdeleteelement) +- [追加内容](#追加内容) + - [smartcanvas.append_insert_smartcanvas_by_markdown - 追加 Markdown 内容](#smartcanvasappendinsertsmartcanvasbymarkdown-追加) +- [枚举值参考](#枚举值参考) +- [元素类型详细说明](#元素类型详细说明) +- [典型工作流示例](#典型工作流示例) + +--- + +## 概念说明 + +| 概念 | 说明 | +|------|------| +| `file_id` | 智能文档的唯一标识符,每个文档有唯一的 file_id | +| `element_id` | 元素 ID,文档中每个元素(页面、文本、标题、任务)都有唯一 ID | +| `page_id` | 页面元素 ID,Page 是智能文档的基本容器单元 | +| `parent_id` | 父元素 ID,用于确定元素的层级关系 | + +**元素层级关系**: + +``` +file_id(文档) +└── Page(页面) + ├── Heading(标题,LEVEL_1 ~ LEVEL_6) + ├── Text(文本) + └── Task(待办事项) +``` + +> ⚠️ **重要约束**: +> - `Text`、`Task`、`Heading` 必须挂载在 `Page` 类型的父节点下 +> - `Page` 可以不指定父节点(挂载到根节点) +> - 父节点不支持为 `Heading` 类型 + +--- + +## 元素操作 + +### smartcanvas.create_smartcanvas_element + +**功能**:在智能文档中新增元素,支持同时添加页面、文本、标题、待办事项等多种类型元素。 + +**使用场景**: +- 在文档中追加新页面 +- 在已有页面中添加文本、标题、待办事项 +- 在指定元素后面插入新内容 + +**请求参数**: + +| 参数 | 类型 | 必填 | 说明 | +|------|------|------|------| +| `file_id` | string | ✅ | 智能文档的唯一标识符 | +| `parent_id` | string | 条件必填 | 父节点元素 ID。插入 Text/Task/Heading 时必填(父节点必须为 Page 类型);插入 Page 时可不填(插入到根节点) | +| `after` | string | | 插入到哪个节点之后的元素 ID,不填则作为父节点的最后一个子节点插入 | +| `pages` | []Page | | 要添加的页面元素列表 | +| `texts` | []Text | | 要添加的文本元素列表 | +| `tasks` | []Task | | 要添加的待办事项元素列表 | +| `headings` | []Heading | | 要添加的标题元素列表 | + +**返回字段**: + +| 字段 | 类型 | 说明 | +|------|------|------| +| `element_infos` | array | 创建的元素信息列表,详见 ElementInfo 结构 | +| `error` | string | 错误信息,操作失败时返回 | +| `trace_id` | string | 调用链追踪 ID | + +**ElementInfo 结构**: + +| 字段 | 类型 | 说明 | +|------|------|------| +| `id` | string | 元素唯一标识符 | +| `version` | uint32 | 元素版本号 | +| `type` | string | 元素类型:Page、Text、Heading、Task | +| `element` | string | 元素内容(JSON 格式字符串) | +| `parent_id` | string | 父元素 ID | +| `children` | []string | 子元素 ID 列表 | +| `created_by` | string | 创建者用户 ID | +| `created_at` | uint64 | 创建时间戳(毫秒) | +| `updated_by` | string | 最后更新者用户 ID | +| `updated_at` | uint64 | 最后更新时间戳(毫秒) | + +**调用示例(新增页面)**: + +```json +{ + "file_id": "your_file_id", + "pages": [ + { + "title": "第一章:项目背景" + } + ] +} +``` + +**调用示例(在页面中添加标题和文本)**: + +```json +{ + "file_id": "your_file_id", + "parent_id": "page_element_id", + "headings": [ + { + "rich_text": { + "text": "项目目标", + "formats": { + "bold": true + } + }, + "level": "LEVEL_1" + } + ], + "texts": [ + { + "rich_text": { + "text": "本项目旨在提升用户体验,优化核心流程。" + } + } + ] +} +``` + +**调用示例(添加待办事项)**: + +```json +{ + "file_id": "your_file_id", + "parent_id": "page_element_id", + "tasks": [ + { + "rich_text": { + "text": "完成需求评审" + }, + "reminder": { + "due_time": 1720072890000, + "reminder_time": 30 + } + }, + { + "rich_text": { + "text": "提交设计稿" + } + } + ] +} +``` + +--- + +### smartcanvas.get_element_info + +**功能**:批量查询指定元素的详细信息,支持同时查询多个元素。 + +**使用场景**: +- 查询特定元素的内容和属性 +- 获取元素的父子关系 +- 验证元素是否存在及其当前状态 + +**请求参数**: + +| 参数 | 类型 | 必填 | 说明 | +|------|------|------|------| +| `file_id` | string | ✅ | 智能文档的唯一标识符 | +| `element_ids` | []string | ✅ | 查询元素 ID 列表,支持批量查询多个元素 | + +**返回字段**: + +| 字段 | 类型 | 说明 | +|------|------|------| +| `element_infos` | array | 查询到的元素信息列表,详见 ElementInfo 结构 | +| `error` | string | 错误信息 | +| `trace_id` | string | 调用链追踪 ID | + +**调用示例**: + +```json +{ + "file_id": "your_file_id", + "element_ids": ["element_id_001", "element_id_002"] +} +``` + +**返回示例**: + +```json +{ + "element_infos": [ + { + "id": "element_id_001", + "version": 3, + "type": "Page", + "element": "{\"title\": \"第一章:项目背景\"}", + "parent_id": "", + "children": ["element_id_003", "element_id_004"], + "created_by": "user_001", + "created_at": 1720000000000, + "updated_by": "user_001", + "updated_at": 1720086400000 + } + ], + "error": "", + "trace_id": "trace_xyz" +} +``` + +--- + +### smartcanvas.get_page_info + +**功能**:查询指定页面内的所有元素,支持分页获取。 + +**使用场景**: +- 读取某个页面下的所有内容(标题、文本、待办事项) +- 分页获取内容较多的页面 +- 遍历文档内容进行分析 + +**请求参数**: + +| 参数 | 类型 | 必填 | 说明 | +|------|------|------|------| +| `file_id` | string | ✅ | 智能文档的唯一标识符 | +| `page_id` | string | ✅ | 要查询的页面元素 ID | +| `cursor` | []CursorItem | | 分页游标,首次查询不传,后续查询使用上次响应返回的 cursor | + +**CursorItem 结构**: + +| 字段 | 类型 | 说明 | +|------|------|------| +| `id` | string | 游标 ID | +| `index` | uint32 | 游标索引位置 | + +**返回字段**: + +| 字段 | 类型 | 说明 | +|------|------|------| +| `element_infos` | array | 页面内的元素信息列表 | +| `cursor` | []CursorItem | 下次分页的 cursor 信息 | +| `is_over` | bool | 是否已查询完所有内容,为 true 表示分页结束 | +| `error` | string | 错误信息 | +| `trace_id` | string | 调用链追踪 ID | + +**调用示例(首次查询)**: + +```json +{ + "file_id": "your_file_id", + "page_id": "page_element_id" +} +``` + +**调用示例(分页继续查询)**: + +```json +{ + "file_id": "your_file_id", + "page_id": "page_element_id", + "cursor": [ + { "id": "cursor_id_001", "index": 20 } + ] +} +``` + +--- + +### smartcanvas.get_top_level_pages + +**功能**:查询文档的所有顶层页面列表,返回根节点下的直接子页面。 + +**使用场景**: +- 获取文档的目录结构(顶层页面列表) +- 遍历文档所有页面 +- 在操作前先了解文档的页面组织结构 + +**请求参数**: + +| 参数 | 类型 | 必填 | 说明 | +|------|------|------|------| +| `file_id` | string | ✅ | 智能文档的唯一标识符 | + +**返回字段**: + +| 字段 | 类型 | 说明 | +|------|------|------| +| `top_level_pages` | array | 顶层页面列表,包含所有顶级页面的基本信息 | +| `error` | string | 错误信息 | +| `trace_id` | string | 调用链追踪 ID | + +**调用示例**: + +```json +{ + "file_id": "your_file_id" +} +``` + +**返回示例**: + +```json +{ + "top_level_pages": [ + { + "id": "page_id_001", + "type": "Page", + "element": "{\"title\": \"第一章:项目背景\"}", + "children": ["element_id_003", "element_id_004"] + }, + { + "id": "page_id_002", + "type": "Page", + "element": "{\"title\": \"第二章:技术方案\"}", + "children": ["element_id_005"] + } + ], + "error": "", + "trace_id": "trace_xyz" +} +``` + +--- + +### smartcanvas.update_element + +**功能**:批量修改元素内容,支持同时更新多个元素的文本、格式、标题级别等属性。 + +**使用场景**: +- 修改页面标题 +- 更新文本内容或格式(加粗、颜色等) +- 修改标题级别 +- 更新待办事项内容或截止时间 + +**请求参数**: + +| 参数 | 类型 | 必填 | 说明 | +|------|------|------|------| +| `file_id` | string | ✅ | 智能文档的唯一标识符 | +| `updates` | []UpdateElementRequest | ✅ | 元素更新请求列表,支持批量更新多个元素 | + +**UpdateElementRequest 结构**: + +| 字段 | 类型 | 必填 | 说明 | +|------|------|------|------| +| `element_id` | string | ✅ | 要更新的元素 ID | +| `page` | Page | | 更新页面元素(修改标题) | +| `text` | Text | | 更新文本元素 | +| `task` | Task | | 更新待办事项元素 | +| `heading` | Heading | | 更新标题元素 | + +**返回字段**: + +| 字段 | 类型 | 说明 | +|------|------|------| +| `updated_elements` | array | 更新成功的元素信息列表 | +| `error` | string | 错误信息 | +| `trace_id` | string | 调用链追踪 ID | + +**调用示例(修改页面标题)**: + +```json +{ + "file_id": "your_file_id", + "updates": [ + { + "element_id": "page_element_id", + "page": { + "title": "第一章:项目背景(已更新)" + } + } + ] +} +``` + +**调用示例(修改文本内容和格式)**: + +```json +{ + "file_id": "your_file_id", + "updates": [ + { + "element_id": "text_element_id", + "text": { + "rich_text": { + "text": "这是更新后的文本内容,支持富文本格式。", + "formats": { + "bold": true, + "text_color": "COLOR_BLUE" + } + }, + "block_color": "BG_COLOR_LIGHT_BLUE" + } + } + ] +} +``` + +**调用示例(修改标题级别)**: + +```json +{ + "file_id": "your_file_id", + "updates": [ + { + "element_id": "heading_element_id", + "heading": { + "rich_text": { + "text": "技术架构设计" + }, + "level": "LEVEL_2" + } + } + ] +} +``` + +**调用示例(更新待办事项截止时间)**: + +```json +{ + "file_id": "your_file_id", + "updates": [ + { + "element_id": "task_element_id", + "task": { + "rich_text": { + "text": "完成代码评审" + }, + "reminder": { + "due_time": 1720159290000, + "reminder_time": 60 + } + } + } + ] +} +``` + +--- + +### smartcanvas.delete_element + +**功能**:批量删除元素,支持同时删除多个指定元素。 + +**使用场景**: +- 删除不再需要的页面或内容块 +- 清理文档中的冗余内容 +- 批量删除多个元素 + +> ⚠️ **注意**:删除 Page 元素时,其下的所有子元素(Text、Heading、Task)也会被一并删除,请谨慎操作。 + +**请求参数**: + +| 参数 | 类型 | 必填 | 说明 | +|------|------|------|------| +| `file_id` | string | ✅ | 智能文档的唯一标识符 | +| `element_ids` | []string | ✅ | 需要批量删除的元素 ID 列表 | + +**返回字段**: + +| 字段 | 类型 | 说明 | +|------|------|------| +| `error` | string | 错误信息,操作失败时返回 | +| `trace_id` | string | 调用链追踪 ID | + +**调用示例**: + +```json +{ + "file_id": "your_file_id", + "element_ids": ["element_id_001", "element_id_002"] +} +``` + +--- + +## 追加内容 + +### smartcanvas.append_insert_smartcanvas_by_markdown 追加 + +**功能**:通过 Markdown 文本向已有智能文档追加内容,内容追加到文档末尾。 + +**使用场景**: +- 快速向文档末尾追加大段 Markdown 内容 +- 批量导入 Markdown 格式的文档内容 +- 在已有文档基础上继续补充内容 + +**请求参数**: + +| 参数 | 类型 | 必填 | 说明 | +|------|------|------|------| +| `file_id` | string | ✅ | 智能文档的唯一标识符 | +| `markdown` | string | ✅ | UTF-8 格式的 Markdown 文本,特殊字符不需要转义 | + +**返回字段**: + +| 字段 | 类型 | 说明 | +|------|------|------| +| `error` | string | 错误信息,操作失败时返回 | +| `trace_id` | string | 调用链追踪 ID | + +**调用示例**: + +```json +{ + "file_id": "your_file_id", + "markdown": "## 新增章节\n\n这是通过 Markdown 追加的内容。\n\n- 支持列表\n- 支持**加粗**\n- 支持`代码`" +} +``` + +--- + +## 枚举值参考 + +### 标题级别(HeadingLevel) + +| 枚举值 | 说明 | +|--------|------| +| `LEVEL_1` | 一级标题(最大) | +| `LEVEL_2` | 二级标题 | +| `LEVEL_3` | 三级标题 | +| `LEVEL_4` | 四级标题 | +| `LEVEL_5` | 五级标题 | +| `LEVEL_6` | 六级标题(最小) | + +### 文本颜色(TextColor) + +| 枚举值 | 颜色 | +|--------|------| +| `COLOR_GREY` | 灰色 | +| `COLOR_BLUE` | 蓝色 | +| `COLOR_SKY_BLUE` | 天蓝色 | +| `COLOR_GREEN` | 绿色 | +| `COLOR_YELLOW` | 黄色 | +| `COLOR_ORANGE` | 橙色 | +| `COLOR_RED` | 红色 | +| `COLOR_ROSE_RED` | 玫瑰红 | +| `COLOR_PURPLE` | 紫色 | + +### 背景颜色(BackgroundColor) + +| 枚举值 | 颜色 | +|--------|------| +| `BG_COLOR_GREY` | 灰色 | +| `BG_COLOR_LIGHT_GREY` | 浅灰色 | +| `BG_COLOR_DARK` | 深色 | +| `BG_COLOR_LIGHT_BLUE` | 浅蓝色 | +| `BG_COLOR_BLUE` | 蓝色 | +| `BG_COLOR_LIGHT_SKY_BLUE` | 浅天蓝色 | +| `BG_COLOR_SKY_BLUE` | 天蓝色 | +| `BG_COLOR_LIGHT_GREEN` | 浅绿色 | +| `BG_COLOR_GREEN` | 绿色 | +| `BG_COLOR_LIGHT_YELLOW` | 浅黄色 | +| `BG_COLOR_YELLOW` | 黄色 | +| `BG_COLOR_LIGHT_ORANGE` | 浅橙色 | +| `BG_COLOR_ORANGE` | 橙色 | +| `BG_COLOR_LIGHT_RED` | 浅红色 | +| `BG_COLOR_RED` | 红色 | +| `BG_COLOR_LIGHT_ROSE_RED` | 浅玫瑰红 | +| `BG_COLOR_ROSE_RED` | 玫瑰红 | +| `BG_COLOR_LIGHT_PURPLE` | 浅紫色 | +| `BG_COLOR_PURPLE` | 紫色 | + +--- + +## 元素类型详细说明 + +### Page(页面) + +页面是智能文档的基本容器单元,所有内容元素(Text、Heading、Task)都必须挂载在 Page 下。 + +```json +{ + "title": "页面标题(仅支持纯文本)" +} +``` + +| 字段 | 类型 | 必填 | 说明 | +|------|------|------|------| +| `title` | string | | 页面标题,仅支持纯文本,不支持富文本格式 | + +--- + +### Text(文本) + +普通文本块,支持富文本格式和背景颜色。 + +```json +{ + "rich_text": { + "text": "文本内容", + "formats": { + "bold": false, + "italic": false, + "under_line": false, + "strike": false, + "text_color": "COLOR_BLUE", + "background_color": "BG_COLOR_LIGHT_YELLOW", + "text_link": { + "link_url": "https://example.com" + } + } + }, + "block_color": "BG_COLOR_LIGHT_GREY" +} +``` + +| 字段 | 类型 | 必填 | 说明 | +|------|------|------|------| +| `rich_text` | RichText | ✅ | 富文本内容 | +| `block_color` | BackgroundColor | | 文本块背景颜色 | + +--- + +### Heading(标题) + +标题块,支持 1-6 级标题,支持富文本格式和背景颜色。 + +```json +{ + "rich_text": { + "text": "标题内容", + "formats": { + "bold": true + } + }, + "level": "LEVEL_1", + "block_color": "BG_COLOR_LIGHT_BLUE" +} +``` + +| 字段 | 类型 | 必填 | 说明 | +|------|------|------|------| +| `rich_text` | RichText | ✅ | 富文本内容 | +| `level` | HeadingLevel | ✅ | 标题级别,枚举值:LEVEL_1 ~ LEVEL_6 | +| `block_color` | BackgroundColor | | 标题块背景颜色 | + +--- + +### Task(待办事项) + +待办事项块,支持设置截止时间和提醒。 + +```json +{ + "rich_text": { + "text": "待办事项内容" + }, + "reminder": { + "due_time": 1720072890000, + "reminder_time": 30 + } +} +``` + +| 字段 | 类型 | 必填 | 说明 | +|------|------|------|------| +| `rich_text` | RichText | ✅ | 待办事项文本内容 | +| `reminder` | Reminder | | 提醒设置 | + +**Reminder 结构**: + +| 字段 | 类型 | 说明 | +|------|------|------| +| `due_time` | uint64 | 任务截止时间,Unix 时间戳(毫秒),例如 `1720072890000` | +| `reminder_time` | int32 | 提前提醒时间间隔(分钟) | + +--- + +### RichText(富文本) + +富文本对象,包含文本内容和格式设置。 + +```json +{ + "text": "文本内容", + "formats": { + "bold": true, + "italic": false, + "under_line": true, + "strike": false, + "text_color": "COLOR_RED", + "background_color": "BG_COLOR_LIGHT_YELLOW", + "text_link": { + "link_url": "https://docs.qq.com" + } + } +} +``` + +**Formats 格式说明**: + +| 字段 | 类型 | 说明 | +|------|------|------| +| `bold` | bool | 粗体 | +| `italic` | bool | 斜体 | +| `under_line` | bool | 下划线 | +| `strike` | bool | 删除线 | +| `text_color` | TextColor | 文本颜色,枚举值见上方 | +| `background_color` | BackgroundColor | 背景颜色,枚举值见上方 | +| `text_link` | TextLink | 文本链接,包含 `link_url` 字段 | + +--- + +## 典型工作流示例 + +### 工作流一:创建结构化文档 + +``` +步骤 1:创建智能文档 + → create_smartcanvas_by_markdown(创建文档,获取 file_id) + +步骤 2:查询顶层页面 + → smartcanvas.get_top_level_pages(获取已有页面的 page_id) + +步骤 3:在页面中添加内容 + → smartcanvas.create_smartcanvas_element(传入 parent_id=page_id,添加标题和文本) + +步骤 4:继续追加内容 + → smartcanvas.create_smartcanvas_element(追加更多页面或内容块) +``` + +### 工作流二:读取文档内容 + +``` +步骤 1:获取顶层页面列表 + → smartcanvas.get_top_level_pages(获取所有顶层页面) + +步骤 2:逐页读取内容 + → smartcanvas.get_page_info(传入 page_id,获取页面内所有元素) + → 若 is_over=false,继续传入 cursor 获取下一页 + +步骤 3:(可选)查询特定元素详情 + → smartcanvas.get_element_info(传入 element_ids,获取元素详细信息) +``` + +### 工作流三:更新文档内容 + +``` +步骤 1:获取顶层页面 + → smartcanvas.get_top_level_pages(获取页面列表) + +步骤 2:读取页面内容,找到目标元素 + → smartcanvas.get_page_info(获取页面内元素及其 element_id) + +步骤 3:更新目标元素 + → smartcanvas.update_element(传入 element_id 和新内容) +``` + +### 工作流四:追加内容到已有文档 + +``` +步骤 1:获取文档 file_id + → search_space_file(搜索文档,获取 file_id) + +步骤 2:追加 Markdown 内容 + → smartcanvas.append_insert_smartcanvas_by_markdown(传入 file_id 和 markdown 内容) + +步骤 3:(可选)精细化追加结构化元素 + → smartcanvas.get_top_level_pages(获取最新页面列表) + → smartcanvas.create_smartcanvas_element(在指定页面后追加元素) +``` + +### 工作流五:清理文档内容 + +``` +步骤 1:获取顶层页面 + → smartcanvas.get_top_level_pages + +步骤 2:读取页面内容,找到要删除的元素 + → smartcanvas.get_page_info(获取 element_id 列表) + +步骤 3:批量删除元素 + → smartcanvas.delete_element(传入 element_ids 数组) +``` + +--- + +> 📌 **提示**: +> - 所有操作都需要先获取 `file_id`,可通过 `search_space_file` 搜索文档获取,或在创建文档时从返回结果中获取。 +> - 操作元素前,建议先调用 `smartcanvas.get_top_level_pages` 了解文档结构,再调用 `smartcanvas.get_page_info` 获取具体元素 ID。 +> - `Text`、`Heading`、`Task` 元素必须挂载在 `Page` 下,创建时 `parent_id` 必须为 Page 类型元素的 ID。 diff --git a/skills/tencent-docs/references/smartsheet_references.md b/skills/tencent-docs/references/smartsheet_references.md new file mode 100644 index 0000000..b155afc --- /dev/null +++ b/skills/tencent-docs/references/smartsheet_references.md @@ -0,0 +1,1036 @@ +# 智能表格(SmartSheet)工具完整参考文档 + +腾讯文档智能表格(SmartSheet)提供了一套完整的表格操作 API,支持对工作表、视图、字段、记录进行增删改查操作。 + +--- + +## 目录 + +- [概念说明](#概念说明) +- [工作表(SubSheet)操作](#工作表subsheet操作) + - [smartsheet.list_tables - 列出工作表](#smartsheetlist_tables) + - [smartsheet.add_table - 新增工作表](#smartsheetadd_table) + - [smartsheet.delete_table - 删除工作表](#smartsheetdelete_table) +- [视图(View)操作](#视图view操作) + - [smartsheet.list_views - 列出视图](#smartsheetlist_views) + - [smartsheet.add_view - 新增视图](#smartsheetadd_view) + - [smartsheet.delete_view - 删除视图](#smartsheetdelete_view) +- [字段(Field)操作](#字段field操作) + - [smartsheet.list_fields - 列出字段](#smartsheetlist_fields) + - [smartsheet.add_fields - 新增字段](#smartsheetadd_fields) + - [smartsheet.update_fields - 更新字段](#smartsheetupdate_fields) + - [smartsheet.delete_fields - 删除字段](#smartsheetdelete_fields) +- [记录(Record)操作](#记录record操作) + - [smartsheet.list_records - 列出记录](#smartsheetlist_records) + - [smartsheet.add_records - 新增记录](#smartsheetadd_records) + - [smartsheet.update_records - 更新记录](#smartsheetupdate_records) + - [smartsheet.delete_records - 删除记录](#smartsheetdelete_records) +- [枚举值参考](#枚举值参考) +- [字段值格式参考](#字段值格式参考) +- [典型工作流示例](#典型工作流示例) + +--- + +## 概念说明 + +| 概念 | 说明 | +|------|------| +| `file_id` | 智能表格文档的唯一标识符,每个文档有唯一的 file_id | +| `sheet_id` | 工作表 ID,一个智能表格文档可包含多个工作表 | +| `view_id` | 视图 ID,每个工作表可有多个视图(网格视图、看板视图等) | +| `field_id` | 字段 ID,对应表格的列 | +| `record_id` | 记录 ID,对应表格的行 | + +**层级关系**:`file_id(文档)` → `sheet_id(工作表)` → `view_id(视图)` / `field_id(字段)` / `record_id(记录)` + +--- + +## 工作表(SubSheet)操作 + +### smartsheet.list_tables + +**功能**:列出文档下的所有工作表,返回工作表基本信息列表。 + +**使用场景**: +- 查看一个智能表格文档中有哪些工作表 +- 获取 sheet_id 以便后续操作字段、记录、视图 + +**请求参数**: + +| 参数 | 类型 | 必填 | 说明 | +|------|------|------|------| +| `file_id` | string | ✅ | 智能表格文档的唯一标识符 | + +**返回字段**: + +| 字段 | 类型 | 说明 | +|------|------|------| +| `sheets` | array | 工作表列表 | +| `sheets[].sheet_id` | string | 工作表唯一标识符 | +| `sheets[].title` | string | 工作表名称 | +| `sheets[].isVisible` | bool | 工作表可见性 | +| `error` | string | 错误信息,操作失败时返回 | +| `trace_id` | string | 调用链追踪 ID | + +**调用示例**: + +```json +{ + "file_id": "your_file_id" +} +``` + +**返回示例**: + +```json +{ + "sheets": [ + { + "sheet_id": "sheet_abc123", + "title": "任务列表", + "isVisible": true + }, + { + "sheet_id": "sheet_def456", + "title": "已归档", + "isVisible": false + } + ], + "error": "", + "trace_id": "trace_xyz" +} +``` + +--- + +### smartsheet.add_table + +**功能**:在文档中新增工作表,支持设置工作表名称和初始配置。 + +**使用场景**: +- 在已有智能表格文档中添加新的工作表(如新增"2024年Q2"工作表) +- 按业务模块拆分数据到不同工作表 + +**请求参数**: + +| 参数 | 类型 | 必填 | 说明 | +|------|------|------|------| +| `file_id` | string | ✅ | 智能表格文档的唯一标识符 | +| `properties` | object | ✅ | 工作表属性配置 | +| `properties.sheet_id` | string | ✅ | 工作表名称(注意:此字段实际含义为工作表名称) | +| `properties.title` | string | | 工作表标题 | +| `properties.index` | uint32 | | 工作表下标(位置) | + +**返回字段**: + +| 字段 | 类型 | 说明 | +|------|------|------| +| `properties` | object | 新创建工作表的属性信息 | +| `properties.sheet_id` | string | 工作表名称 | +| `properties.title` | string | 工作表标题 | +| `properties.index` | uint32 | 工作表下标 | +| `error` | string | 错误信息 | +| `trace_id` | string | 调用链追踪 ID | + +**调用示例**: + +```json +{ + "file_id": "your_file_id", + "properties": { + "sheet_id": "新工作表", + "title": "2024年Q2数据", + "index": 1 + } +} +``` + +--- + +### smartsheet.delete_table + +**功能**:删除指定的工作表。 + +**使用场景**: +- 删除不再需要的工作表 +- 清理测试数据工作表 + +**请求参数**: + +| 参数 | 类型 | 必填 | 说明 | +|------|------|------|------| +| `file_id` | string | ✅ | 智能表格文档的唯一标识符 | +| `sheet_id` | string | ✅ | 要删除的工作表 ID | + +**返回字段**: + +| 字段 | 类型 | 说明 | +|------|------|------| +| `error` | string | 错误信息,操作失败时返回 | +| `trace_id` | string | 调用链追踪 ID | + +**调用示例**: + +```json +{ + "file_id": "your_file_id", + "sheet_id": "sheet_abc123" +} +``` + +--- + +## 视图(View)操作 + +### smartsheet.list_views + +**功能**:列出工作表下的所有视图,返回视图基本信息和配置。 + +**使用场景**: +- 查看工作表有哪些视图(网格视图、看板视图) +- 获取 view_id 以便按视图筛选记录或字段 + +**请求参数**: + +| 参数 | 类型 | 必填 | 说明 | +|------|------|------|------| +| `file_id` | string | ✅ | 智能表格文档的唯一标识符 | +| `sheet_id` | string | ✅ | 工作表 ID | +| `view_ids` | []string | | 需要查询的视图 ID 数组,不填则返回全部 | +| `offset` | uint32 | | 分页查询偏移量,默认 0 | +| `limit` | uint32 | | 分页大小,最大 100 | + +**返回字段**: + +| 字段 | 类型 | 说明 | +|------|------|------| +| `views` | array | 视图列表 | +| `views[].view_id` | string | 视图唯一标识符 | +| `views[].view_name` | string | 视图名称 | +| `views[].view_type` | uint32 | 视图类型,枚举值见下方 | +| `total` | uint32 | 符合条件的视图总数 | +| `hasMore` | bool | 是否还有更多项 | +| `next` | uint32 | 下一页偏移量 | +| `error` | string | 错误信息 | +| `trace_id` | string | 调用链追踪 ID | + +**视图类型枚举值**: + +| 值 | 说明 | +|----|------| +| `1` | 网格视图(grid) | +| `2` | 看板视图(kanban) | + +**调用示例**: + +```json +{ + "file_id": "your_file_id", + "sheet_id": "sheet_abc123", + "offset": 0, + "limit": 20 +} +``` + +--- + +### smartsheet.add_view + +**功能**:在工作表中新增视图,支持自定义视图名称和类型。 + +**使用场景**: +- 为工作表创建看板视图,按状态分组展示任务 +- 创建多个网格视图,分别展示不同筛选条件的数据 + +**请求参数**: + +| 参数 | 类型 | 必填 | 说明 | +|------|------|------|------| +| `file_id` | string | ✅ | 智能表格文档的唯一标识符 | +| `sheet_id` | string | ✅ | 工作表 ID | +| `view_title` | string | ✅ | 视图标题 | +| `view_type` | uint32 | | 视图类型:1-网格视图,2-看板视图 | + +**返回字段**: + +| 字段 | 类型 | 说明 | +|------|------|------| +| `view_id` | string | 新创建的视图 ID | +| `view_title` | string | 视图标题 | +| `view_type` | uint32 | 视图类型 | +| `error` | string | 错误信息 | +| `trace_id` | string | 调用链追踪 ID | + +**调用示例**: + +```json +{ + "file_id": "your_file_id", + "sheet_id": "sheet_abc123", + "view_title": "按状态分组", + "view_type": 2 +} +``` + +--- + +### smartsheet.delete_view + +**功能**:删除指定的视图,支持批量删除多个视图。 + +**使用场景**: +- 删除不再使用的视图 +- 批量清理多余视图 + +**请求参数**: + +| 参数 | 类型 | 必填 | 说明 | +|------|------|------|------| +| `file_id` | string | ✅ | 智能表格文档的唯一标识符 | +| `sheet_id` | string | ✅ | 工作表 ID | +| `view_ids` | []string | ✅ | 要删除的视图 ID 列表 | + +**返回字段**: + +| 字段 | 类型 | 说明 | +|------|------|------| +| `error` | string | 错误信息 | +| `trace_id` | string | 调用链追踪 ID | + +**调用示例**: + +```json +{ + "file_id": "your_file_id", + "sheet_id": "sheet_abc123", + "view_ids": ["view_id1", "view_id2"] +} +``` + +--- + +## 字段(Field)操作 + +### smartsheet.list_fields + +**功能**:列出工作表的所有字段,返回字段基本信息和类型配置。 + +**使用场景**: +- 查看工作表有哪些列(字段)及其类型 +- 获取 field_id 以便后续更新或删除字段 +- 在写入记录前,先了解字段结构和类型 + +**请求参数**: + +| 参数 | 类型 | 必填 | 说明 | +|------|------|------|------| +| `file_id` | string | ✅ | 智能表格文档的唯一标识符 | +| `sheet_id` | string | ✅ | 工作表 ID | +| `view_id` | string | | 视图 ID,按视图筛选字段 | +| `field_ids` | []string | | 指定字段 ID 数组 | +| `field_titles` | []string | | 指定字段标题数组 | +| `offset` | uint32 | | 偏移量,初始值为 0 | +| `limit` | uint32 | | 分页大小,最大 100;不填或为 0 时,总数 >100 返回 100 条,否则返回全部 | + +**返回字段**: + +| 字段 | 类型 | 说明 | +|------|------|------| +| `total` | uint32 | 符合条件的字段总数 | +| `has_more` | bool | 是否还有更多项 | +| `next` | uint32 | 下一页偏移量 | +| `fields` | array | 字段列表,详见 FieldInfo 结构 | + +**FieldInfo 结构**: + +| 字段 | 类型 | 说明 | +|------|------|------| +| `field_id` | string | 字段唯一 ID | +| `field_title` | string | 字段标题(列名) | +| `field_type` | uint32 | 字段类型,枚举值见下方 | +| `property_*` | object | 字段属性,根据 field_type 不同而不同 | + +**调用示例**: + +```json +{ + "file_id": "your_file_id", + "sheet_id": "sheet_abc123" +} +``` + +--- + +### smartsheet.add_fields + +**功能**:批量新增字段(列),支持同时添加多个不同类型的字段。 + +**使用场景**: +- 为工作表添加新列,如"优先级"(单选)、"截止日期"(日期)、"负责人"(用户) +- 初始化工作表结构 + +**请求参数**: + +| 参数 | 类型 | 必填 | 说明 | +|------|------|------|------| +| `file_id` | string | ✅ | 智能表格文档的唯一标识符 | +| `sheet_id` | string | ✅ | 工作表 ID | +| `fields` | []FieldInfo | ✅ | 要添加的字段列表 | + +**FieldInfo 参数说明**: + +| 字段 | 类型 | 必填 | 说明 | +|------|------|------|------| +| `field_title` | string | ✅ | 字段标题(列名) | +| `field_type` | uint32 | ✅ | 字段类型,枚举值见下方 | +| `property_text` | object | | 文本类型属性(无需额外配置) | +| `property_number` | object | | 数字类型属性 | +| `property_checkbox` | object | | 复选框类型属性 | +| `property_date_time` | object | | 日期时间类型属性 | +| `property_url` | object | | 超链接类型属性 | +| `property_select` | object | | 多选类型属性 | +| `property_single_select` | object | | 单选类型属性 | +| `property_progress` | object | | 进度类型属性 | + +**返回字段**: + +| 字段 | 类型 | 说明 | +|------|------|------| +| `fields` | array | 添加成功的字段列表(含 field_id) | +| `error` | string | 错误信息 | +| `trace_id` | string | 调用链追踪 ID | + +**调用示例(添加多种类型字段)**: + +```json +{ + "file_id": "your_file_id", + "sheet_id": "sheet_abc123", + "fields": [ + { + "field_title": "任务名称", + "field_type": 1, + "property_text": {} + }, + { + "field_title": "优先级", + "field_type": 17, + "property_single_select": { + "options": [ + { "text": "高", "style": 1 }, + { "text": "中", "style": 3 }, + { "text": "低", "style": 4 } + ] + } + }, + { + "field_title": "截止日期", + "field_type": 4, + "property_date_time": { + "format": "yyyy-mm-dd", + "auto_fill": false + } + }, + { + "field_title": "完成进度", + "field_type": 14, + "property_progress": { + "decimal_places": 0 + } + }, + { + "field_title": "是否完成", + "field_type": 3, + "property_checkbox": { + "checked": false + } + } + ] +} +``` + +--- + +### smartsheet.update_fields + +**功能**:批量更新字段属性,支持修改字段名称和配置信息。 + +**使用场景**: +- 修改字段标题(列名) +- 更新单选/多选字段的选项列表 +- 修改数字字段的精度配置 + +> ⚠️ **注意**:`field_type`(字段类型)不允许被更新,但更新时必须传入原字段类型值。 + +**请求参数**: + +| 参数 | 类型 | 必填 | 说明 | +|------|------|------|------| +| `file_id` | string | ✅ | 智能表格文档的唯一标识符 | +| `sheet_id` | string | ✅ | 工作表 ID | +| `fields` | []FieldInfo | ✅ | 要更新的字段列表,必须包含 field_id | + +**返回字段**: + +| 字段 | 类型 | 说明 | +|------|------|------| +| `fields` | array | 更新成功的字段列表 | +| `error` | string | 错误信息 | +| `trace_id` | string | 调用链追踪 ID | + +**调用示例(修改字段标题和选项)**: + +```json +{ + "file_id": "your_file_id", + "sheet_id": "sheet_abc123", + "fields": [ + { + "field_id": "field_id_001", + "field_title": "任务状态", + "field_type": 17, + "property_single_select": { + "options": [ + { "text": "待处理", "style": 7 }, + { "text": "进行中", "style": 3 }, + { "text": "已完成", "style": 4 }, + { "text": "已取消", "style": 1 } + ] + } + } + ] +} +``` + +--- + +### smartsheet.delete_fields + +**功能**:批量删除字段(列),支持同时删除多个字段。 + +**使用场景**: +- 删除不再需要的列 +- 清理冗余字段 + +**请求参数**: + +| 参数 | 类型 | 必填 | 说明 | +|------|------|------|------| +| `file_id` | string | ✅ | 智能表格文档的唯一标识符 | +| `sheet_id` | string | ✅ | 工作表 ID | +| `field_ids` | []string | ✅ | 要删除的字段 ID 数组 | + +**返回字段**: + +| 字段 | 类型 | 说明 | +|------|------|------| +| `error` | string | 错误信息 | +| `trace_id` | string | 调用链追踪 ID | + +**调用示例**: + +```json +{ + "file_id": "your_file_id", + "sheet_id": "sheet_abc123", + "field_ids": ["field_id_001", "field_id_002"] +} +``` + +--- + +## 记录(Record)操作 + +### smartsheet.list_records + +**功能**:分页列出工作表记录(行),支持排序和按字段筛选。 + +**使用场景**: +- 读取工作表中的数据 +- 按特定字段排序查看数据 +- 分页获取大量数据 + +**请求参数**: + +| 参数 | 类型 | 必填 | 说明 | +|------|------|------|------| +| `file_id` | string | ✅ | 智能表格文档的唯一标识符 | +| `sheet_id` | string | ✅ | 工作表 ID | +| `view_id` | string | | 视图 ID,按视图筛选记录 | +| `record_ids` | []string | | 指定记录 ID 数组,精确查询 | +| `field_titles` | []string | | 只返回指定字段标题的值,不填则返回全部字段 | +| `sort` | []Sort | | 排序配置 | +| `offset` | uint32 | | 偏移量,初始值为 0 | +| `limit` | uint32 | | 分页大小,最大 100;不填或为 0 时,总数 >100 返回 100 条,否则返回全部 | + +**Sort 排序配置**: + +| 字段 | 类型 | 必填 | 说明 | +|------|------|------|------| +| `field_title` | string | ✅ | 需要排序的字段标题 | +| `desc` | bool | | 是否降序,默认 false(升序) | + +**返回字段**: + +| 字段 | 类型 | 说明 | +|------|------|------| +| `total` | uint32 | 符合条件的记录总数 | +| `has_more` | bool | 是否还有更多项 | +| `next` | uint32 | 下一页偏移量 | +| `records` | array | 记录列表,详见 RecordInfo 结构 | +| `error` | string | 错误信息 | +| `trace_id` | string | 调用链追踪 ID | + +**RecordInfo 结构**: + +| 字段 | 类型 | 说明 | +|------|------|------| +| `record_id` | string | 记录唯一 ID | +| `field_values` | map | 字段值映射,key 为字段标题,value 为字段值 | + +**调用示例**: + +```json +{ + "file_id": "your_file_id", + "sheet_id": "sheet_abc123", + "field_titles": ["任务名称", "优先级", "截止日期"], + "sort": [ + { "field_title": "截止日期", "desc": false } + ], + "offset": 0, + "limit": 50 +} +``` + +--- + +### smartsheet.add_records + +**功能**:批量添加记录(行),支持同时添加多条记录数据。 + +**使用场景**: +- 批量导入数据到工作表 +- 添加新任务、新条目 +- 从其他数据源同步数据 + +**请求参数**: + +| 参数 | 类型 | 必填 | 说明 | +|------|------|------|------| +| `file_id` | string | ✅ | 智能表格文档的唯一标识符 | +| `sheet_id` | string | ✅ | 工作表 ID | +| `records` | []AddRecord | ✅ | 要添加的记录列表 | + +**AddRecord 结构**: + +| 字段 | 类型 | 必填 | 说明 | +|------|------|------|------| +| `field_values` | map | ✅ | 字段值映射,key 为字段标题,value 为字段值(格式见下方) | + +**返回字段**: + +| 字段 | 类型 | 说明 | +|------|------|------| +| `records` | array | 添加成功的记录列表(含 record_id) | +| `error` | string | 错误信息 | +| `trace_id` | string | 调用链追踪 ID | + +**调用示例**: + +```json +{ + "file_id": "your_file_id", + "sheet_id": "sheet_abc123", + "records": [ + { + "field_values": { + "任务名称": [{"text": "完成需求文档", "type": "text"}], + "优先级": [{"text": "高"}], + "截止日期": "1720000000000", + "完成进度": 30, + "是否完成": false + } + }, + { + "field_values": { + "任务名称": [{"text": "代码评审", "type": "text"}], + "优先级": [{"text": "中"}], + "截止日期": "1720086400000", + "完成进度": 0, + "是否完成": false + } + } + ] +} +``` + +--- + +### smartsheet.update_records + +**功能**:批量更新记录,支持修改多条记录的字段值。 + +**使用场景**: +- 更新任务状态、进度 +- 修改记录中的某些字段值 +- 批量修改多条数据 + +**请求参数**: + +| 参数 | 类型 | 必填 | 说明 | +|------|------|------|------| +| `file_id` | string | ✅ | 智能表格文档的唯一标识符 | +| `sheet_id` | string | ✅ | 工作表 ID | +| `records` | []RecordInfo | ✅ | 要更新的记录列表,必须包含 record_id | + +**RecordInfo 参数说明**: + +| 字段 | 类型 | 必填 | 说明 | +|------|------|------|------| +| `record_id` | string | ✅ | 记录 ID,标识要更新哪条记录 | +| `field_values` | map | ✅ | 要更新的字段值映射 | + +**返回字段**: + +| 字段 | 类型 | 说明 | +|------|------|------| +| `error` | string | 错误信息 | +| `trace_id` | string | 调用链追踪 ID | + +**调用示例**: + +```json +{ + "file_id": "your_file_id", + "sheet_id": "sheet_abc123", + "records": [ + { + "record_id": "record_id_001", + "field_values": { + "完成进度": 100, + "是否完成": true, + "优先级": [{"text": "高"}] + } + } + ] +} +``` + +--- + +### smartsheet.delete_records + +**功能**:批量删除记录(行),支持同时删除多条指定的记录。 + +**使用场景**: +- 删除已完成或过期的任务记录 +- 清理测试数据 +- 批量删除多条记录 + +**请求参数**: + +| 参数 | 类型 | 必填 | 说明 | +|------|------|------|------| +| `file_id` | string | ✅ | 智能表格文档的唯一标识符 | +| `sheet_id` | string | ✅ | 工作表 ID | +| `record_ids` | []string | ✅ | 要删除的记录 ID 列表 | + +**返回字段**: + +| 字段 | 类型 | 说明 | +|------|------|------| +| `error` | string | 错误信息 | +| `trace_id` | string | 调用链追踪 ID | + +**调用示例**: + +```json +{ + "file_id": "your_file_id", + "sheet_id": "sheet_abc123", + "record_ids": ["record_id_001", "record_id_002", "record_id_003"] +} +``` + +--- + +## 枚举值参考 + +### 字段类型(field_type) + +| 枚举值 | 类型名称 | 对应 property 字段 | 说明 | +|--------|---------|-------------------|------| +| `1` | 文本 | `property_text` | 普通文本,无需额外配置 | +| `2` | 数字 | `property_number` | 整数或浮点数 | +| `3` | 复选框 | `property_checkbox` | 布尔值 true/false | +| `4` | 日期 | `property_date_time` | 毫秒时间戳字符串 | +| `5` | 图片 | `property_image` | 图片 ID 数组 | +| `8` | 超链接 | `property_url` | URL 数组 | +| `9` | 多选 | `property_select` | 选项数组(可多选) | +| `10` | 创建人 | `property_user` | 系统自动填充,无需配置 | +| `11` | 最后编辑人 | `property_modified_user` | 系统自动填充,无需配置 | +| `12` | 创建时间 | `property_created_time` | 系统自动填充,无需配置 | +| `13` | 最后编辑时间 | `property_modified_time` | 系统自动填充,无需配置 | +| `14` | 进度 | `property_progress` | 整数或浮点数(百分比) | +| `15` | 电话 | `property_phone_number` | 字符串,无需额外配置 | +| `16` | 邮件 | `property_email` | 字符串,无需额外配置 | +| `17` | 单选 | `property_single_select` | 选项数组(只能单选) | + +### 视图类型(view_type) + +| 枚举值 | 说明 | +|--------|------| +| `1` | 网格视图(grid)- 传统表格形式 | +| `2` | 看板视图(kanban)- 按列分组展示 | + +### 选项颜色(style) + +| 枚举值 | 颜色 | +|--------|------| +| `1` | 红色 | +| `2` | 橘黄色 | +| `3` | 蓝色 | +| `4` | 绿色 | +| `5` | 紫色 | +| `6` | 粉色 | +| `7` | 灰色 | +| `8` | 白色 | + +### 超链接展示样式(UrlFieldProperty.type) + +| 枚举值 | 说明 | +|--------|------| +| `0` | 未知 | +| `1` | 文字 | +| `2` | 图标文字 | + +--- + +## 字段值格式参考 + +在 `add_records` 和 `update_records` 中,`field_values` 的 value 格式因字段类型而异: + +| 字段类型 | 值格式 | 示例 | +|---------|--------|------| +| 文本(1) | JSON Array of TextValue | `[{"text": "内容", "type": "text"}]` | +| 数字(2) | number | `42` 或 `3.14` | +| 复选框(3) | bool | `true` 或 `false` | +| 日期(4) | string(毫秒时间戳) | `"1720000000000"` | +| 图片(5) | JSON Array of ImageIDValue | `[{"imageID": "图片id"}]` | +| 超链接(8) | JSON Array of UrlValue | `[{"text": "链接文字", "type": "url", "link": "https://..."}]` | +| 多选(9) | JSON Array of OptionValue | `[{"text": "选项1"}, {"text": "选项2"}]` | +| 进度(14) | number | `75` 或 `75.5` | +| 电话(15) | string | `"13800138000"` | +| 邮件(16) | string | `"user@example.com"` | +| 单选(17) | JSON Array of OptionValue(单个) | `[{"text": "选项文字"}]` | + +### TextValue 结构 + +```json +{ + "text": "文本内容", + "type": "text" +} +``` + +### UrlValue 结构 + +```json +{ + "text": "链接显示文字", + "type": "url", + "link": "https://example.com" +} +``` + +### OptionValue 结构 + +```json +{ + "id": "选项ID(可选)", + "text": "选项文字", + "style": 3 +} +``` + +> ⚠️ **注意**:写入记录时,单选/多选字段的 `text` 必须与字段属性中已定义的选项文字完全匹配,否则可能写入失败。 + +--- + +## 字段属性(Property)详细说明 + +### NumberFieldProperty(数字字段属性) + +```json +{ + "decimal_places": 2, + "use_separate": true +} +``` + +| 字段 | 类型 | 说明 | +|------|------|------| +| `decimal_places` | uint32 | 小数点位数(精度) | +| `use_separate` | bool | 是否使用千位符(如 1,000) | + +### CheckboxFieldProperty(复选框字段属性) + +```json +{ + "checked": false +} +``` + +| 字段 | 类型 | 说明 | +|------|------|------| +| `checked` | bool | 新增记录时是否默认勾选 | + +### DateTimeFieldProperty(日期时间字段属性) + +```json +{ + "format": "yyyy-mm-dd", + "auto_fill": false +} +``` + +| 字段 | 类型 | 说明 | +|------|------|------| +| `format` | string | 日期格式,支持格式见下方 | +| `auto_fill` | bool | 新建记录时是否自动填充当前时间 | + +**支持的日期格式**: + +| 格式字符串 | 示例 | +|-----------|------| +| `yyyy"年"m"月"d"日"` | 2018 年 4 月 20 日 | +| `yyyy-mm-dd` | 2018-04-20 | +| `yyyy/m/d` | 2018/4/20 | +| `m"月"d"日"` | 4 月 20 日 | +| `[$-804]yyyy"年"m"月"d"日" dddd` | 2018 年 4 月 20 日 星期五 | +| `yyyy"年"m"月"d"日" hh:mm` | 2018 年 4 月 20 日 14:00 | +| `yyyy-mm-dd hh:mm` | 2018-04-20 14:00 | +| `m/d/yyyy` | 4/20/2018 | +| `d/m/yyyy` | 20/4/2018 | + +### UrlFieldProperty(超链接字段属性) + +```json +{ + "type": 1 +} +``` + +| 字段 | 类型 | 说明 | +|------|------|------| +| `type` | uint32 | 展示样式:0-未知,1-文字,2-图标文字 | + +### SelectFieldProperty(多选字段属性) + +```json +{ + "options": [ + { "id": "opt_001", "text": "选项A", "style": 3 }, + { "id": "opt_002", "text": "选项B", "style": 4 } + ], + "is_multiple": true, + "is_quick_add": false +} +``` + +| 字段 | 类型 | 说明 | +|------|------|------| +| `options` | []Option | 选项列表 | +| `is_multiple` | bool | 是否多选(系统参数,用户无需设置) | +| `is_quick_add` | bool | 是否允许填写时新增选项(系统参数,用户无需设置) | + +### SingleSelectFieldProperty(单选字段属性) + +结构与 `SelectFieldProperty` 相同,但只允许单选。 + +### ProgressFieldProperty(进度字段属性) + +```json +{ + "decimal_places": 0 +} +``` + +| 字段 | 类型 | 说明 | +|------|------|------| +| `decimal_places` | uint32 | 小数位数 | + +--- + +## 典型工作流示例 + +### 工作流一:从零创建表 + +``` +步骤 1:获取文档的工作表列表 + → smartsheet.list_tables(获取 sheet_id) + +步骤 2:为工作表添加字段 + → smartsheet.add_fields(添加:任务名称、优先级、负责人、截止日期、状态、进度) + +步骤 3:批量添加任务记录 + → smartsheet.add_records(写入多条任务数据) + +步骤 4:删除默认空行和默认列 + → smartsheet.list_records(获取建表时自动生成的空行 record_id 列表) + → smartsheet.delete_records(传入空行 record_ids,批量删除默认空行) + → smartsheet.list_fields(获取建表时自动生成的默认列 field_id 列表) + → smartsheet.delete_fields(传入默认列 field_ids,批量删除默认列) + +步骤 5:(可选)创建看板视图 + → smartsheet.add_view(view_type=2,按状态分组) +``` + +### 工作流二:查询并更新任务状态 + +``` +步骤 1:列出工作表 + → smartsheet.list_tables(获取 sheet_id) + +步骤 2:查询记录 + → smartsheet.list_records(获取 record_id 和当前字段值) + +步骤 3:更新指定记录 + → smartsheet.update_records(传入 record_id 和新的字段值) +``` + +### 工作流三:读取数据并分析 + +``` +步骤 1:列出工作表 + → smartsheet.list_tables + +步骤 2:了解字段结构 + → smartsheet.list_fields(了解有哪些列及其类型) + +步骤 3:分页读取所有记录 + → smartsheet.list_records(offset=0, limit=100) + → 若 has_more=true,继续请求下一页(offset=100) + +步骤 4:处理数据 + → 根据 field_values 中的数据进行统计分析 +``` + +### 工作流四:清理过期数据 + +``` +步骤 1:列出工作表 + → smartsheet.list_tables + +步骤 2:查询需要删除的记录 + → smartsheet.list_records(获取目标 record_id 列表) + +步骤 3:批量删除记录 + → smartsheet.delete_records(传入 record_ids 数组) +``` + +--- + +> 📌 **提示**:所有操作都需要先获取 `file_id`(智能表格文档 ID)和 `sheet_id`(工作表 ID)。 +> 可通过 `search_space_file` 搜索文档获取 `file_id`,再通过 `smartsheet.list_tables` 获取 `sheet_id`。 diff --git a/skills/tencent-docs/setup.sh b/skills/tencent-docs/setup.sh new file mode 100644 index 0000000..2aa795a --- /dev/null +++ b/skills/tencent-docs/setup.sh @@ -0,0 +1,53 @@ +#!/bin/bash +# Setup script for 腾讯文档 MCP Skill (内部 OpenClaw 版本) + +set -e + +echo "🚀 设置腾讯文档 MCP Skill(OpenClaw 版本)..." +echo "" + +# 检查 mcporter +if ! command -v mcporter &> /dev/null; then + echo "⚠️ 未找到 mcporter,正在安装..." + npm install -g mcporter + echo "✅ mcporter 安装完成" +fi + +# 添加 MCP 配置 +echo "🔧 配置 mcporter..." + +# 从环境变量中读取用户填写的 Token +mcporter config add tencent-docs "https://docs.qq.com/openapi/mcp" \ + --header "Authorization=$TENCENT_DOCS_TOKEN" \ + --transport http \ + --scope home + +echo "" +echo "✅ 配置完成!" +echo "" +echo "ℹ️ TENCENT_DOCS_TOKEN 环境变量由 OpenClaw runtime 自动提供" +echo "" + +# 验证配置 +echo "🧪 验证配置..." +if mcporter list 2>&1 | grep -q "tencent-docs"; then + echo "✅ 配置验证成功!" + echo "" + mcporter list | grep -A 1 "tencent-docs" || true +else + echo "⚠️ 配置验证失败,请检查网络或 Token 是否有效" + echo "" + echo "如有问题,请访问 https://docs.qq.com/open/document/mcp/get-token/ 获取 Token" +fi + +echo "" +echo "─────────────────────────────────────" +echo "🎉 设置完成!" +echo "" +echo "📖 使用方法:" +echo " mcporter call tencent-docs.create_smartcanvas_by_markdown" +echo "" +echo "🏠 腾讯文档主页:https://docs.qq.com/home" +echo "" +echo "📖 更多信息请查看 SKILL.md" +echo "" \ No newline at end of file diff --git a/skills/tencentcloud-lighthouse-skill/.clawhub/origin.json b/skills/tencentcloud-lighthouse-skill/.clawhub/origin.json new file mode 100644 index 0000000..d99b45b --- /dev/null +++ b/skills/tencentcloud-lighthouse-skill/.clawhub/origin.json @@ -0,0 +1,7 @@ +{ + "version": 1, + "registry": "https://clawhub.ai", + "slug": "tencentcloud-lighthouse-skill", + "installedVersion": "1.0.0", + "installedAt": 1773129523774 +} diff --git a/skills/tencentcloud-lighthouse-skill/SKILL.md b/skills/tencentcloud-lighthouse-skill/SKILL.md new file mode 100644 index 0000000..88452f9 --- /dev/null +++ b/skills/tencentcloud-lighthouse-skill/SKILL.md @@ -0,0 +1,183 @@ +--- +name: tencentcloud-lighthouse-skill +description: Manage Tencent Cloud Lighthouse (轻量应用服务器) — auto-setup mcporter + MCP, query instances, monitoring & alerting, self-diagnostics, firewall, snapshots, remote command execution (TAT). Use when user asks about Lighthouse or 轻量应用服务器. NOT for CVM or other cloud server types. +metadata: + { + "openclaw": + { + "emoji": "☁️", + "requires": {}, + "install": + [ + { + "id": "node-mcporter", + "kind": "node", + "package": "mcporter", + "bins": ["mcporter"], + "label": "Install mcporter (MCP CLI)", + }, + ], + }, + } +--- + +# Lighthouse 云服务器运维 + +通过 mcporter + lighthouse-mcp-server 管理腾讯云轻量应用服务器。 + +## 首次使用 — 自动设置 + +当用户首次要求管理云服务器时,按以下流程操作: + +### 步骤 1:检查当前状态 + +```bash +{baseDir}/scripts/setup.sh --check-only +``` + +如果输出显示一切 OK(mcporter 已安装、config 已配置、lighthouse 已就绪),跳到「调用格式」。 + +### 步骤 2:如果未配置,引导用户提供密钥 + +告诉用户: +> 我需要你的腾讯云 API 密钥来连接 Lighthouse 服务器。请提供: +> 1. **SecretId** — 腾讯云 API 密钥 ID +> 2. **SecretKey** — 腾讯云 API 密钥 Key +> +> 你可以在 [腾讯云控制台 > 访问管理 > API密钥管理](https://console.cloud.tencent.com/cam/capi) 获取。 + +### 步骤 3:用户提供密钥后,运行自动设置 + +```bash +{baseDir}/scripts/setup.sh --secret-id "<用户提供的SecretId>" --secret-key "<用户提供的SecretKey>" +``` + +脚本会自动: +- 检查并安装 mcporter(如未安装) +- 创建 `~/.mcporter/mcporter.json` 配置文件 +- 写入 lighthouse MCP 服务器配置和密钥 +- 验证连接 + +设置完成后即可开始使用。 + +## 调用格式 + +所有 mcporter 命令必须使用以下格式: + +``` +mcporter call lighthouse.<tool_name> --config ~/.mcporter/mcporter.json --output json [--args '<JSON>'] +``` + +列出可用工具: +``` +mcporter list lighthouse --config ~/.mcporter/mcporter.json --schema +``` + + +## 工具总览 + +本 MCP Server 包含以下工具类别: + +| 类别 | 说明 | +|------|------| +| 地域查询 | 获取可用地域列表(唯一不需要 Region 参数的操作) | +| 实例管理 | 查询、启动实例,查看流量包/套餐/配额等(需要 Region) | +| 监控与告警 | 获取多指标监控数据、设置告警策略、服务器自检(需要 Region) | +| 防火墙 | 规则增删改查、防火墙模板管理(需要 Region) | +| 远程命令(TAT) | 在实例上执行命令、查询任务状态(需要 Region) | + +## 常用操作 + +> 以下所有示例省略了公共前缀 `mcporter call lighthouse.` 和 `--config ~/.mcporter/mcporter.json --output json`。 +> 完整命令格式:`mcporter call lighthouse.<tool_name> --config ~/.mcporter/mcporter.json --output json --args '<JSON>'` + +### 获取地域列表(不需要 Region 参数) + +```bash +# 查询所有可用地域 — 唯一不需要 Region 参数的操作 +# 首次使用时应先调用此接口获取可用 Region 列表 +mcporter call lighthouse.describe_regions --config ~/.mcporter/mcporter.json --output json +``` + +### 实例管理 + +```bash +# 查询实例列表(Region 必填,可选参数: InstanceIds, Offset, Limit) +mcporter call lighthouse.describe_instances --config ~/.mcporter/mcporter.json --output json --args '{"Region":"ap-guangzhou","Limit":20,"Offset":0}' + +# 查询指定实例 +mcporter call lighthouse.describe_instances --config ~/.mcporter/mcporter.json --output json --args '{"Region":"ap-guangzhou","InstanceIds":["lhins-xxxxxxxx"]}' + +# 启动实例 +mcporter call lighthouse.start_instances --config ~/.mcporter/mcporter.json --output json --args '{"Region":"ap-guangzhou","InstanceIds":["lhins-xxxxxxxx"]}' + +# 获取实例登录终端地址 +mcporter call lighthouse.describe_instance_login_url --config ~/.mcporter/mcporter.json --output json --args '{"Region":"ap-guangzhou","InstanceId":"lhins-xxxxxxxx"}' + +# 查询所有应用镜像 +mcporter call lighthouse.describe_all_applications --config ~/.mcporter/mcporter.json --output json --args '{"Region":"ap-guangzhou"}' +# BlueprintType 可选: APP_OS | PURE_OS | DOCKER | ALL(默认ALL) +``` + +### 监控与告警 + +```bash +# 获取监控数据(支持多指标同时查询,默认最近6小时) +mcporter call lighthouse.get_monitor_data --config ~/.mcporter/mcporter.json --output json --args '{"Region":"ap-guangzhou","InstanceId":"lhins-xxxxxxxx","Indicators":["CPU利用率","内存利用率"]}' + +# 获取监控数据(指定时间范围) +mcporter call lighthouse.get_monitor_data --config ~/.mcporter/mcporter.json --output json --args '{"Region":"ap-guangzhou","InstanceId":"lhins-xxxxxxxx","Indicators":["公网出带宽","公网入带宽"],"StartTime":"2026-02-09 00:00:00","EndTime":"2026-02-10 00:00:00"}' + +# 支持的监控指标(中文名称): +# CPU利用率 | 内存利用率 | 公网出带宽 | 公网入带宽 +# 系统盘读IO | 系统盘写IO | 公网流量包 + +# 设置告警策略 +# Alarms 中的 Frequency/Points/Size 均为字符串类型 +mcporter call lighthouse.set_alerting_strategy --config ~/.mcporter/mcporter.json --output json --args '{"Region":"ap-guangzhou","InstanceId":"lhins-xxxxxxxx","Indicator":"CPU利用率","Alarms":[{"Frequency":"300","Threshold":"80%","Level":"严重","Points":"3","Size":"60"}],"PolicyName":"CPU高负载告警"}' +# Frequency(秒): "300"|"600"|"900"|"1800"|"3600"|"7200"|"10800"|"21600"|"43200"|"86400" +# Level: "提示"|"严重"|"紧急" Points: "1"-"5" Size: "60"|"300" + +# 服务器自检(检测网络、防火墙、存储、状态、性能) +mcporter call lighthouse.self_test --config ~/.mcporter/mcporter.json --output json --args '{"Region":"ap-guangzhou","InstanceId":"lhins-xxxxxxxx"}' +``` + +### 防火墙 + +```bash +# 查询防火墙规则 +mcporter call lighthouse.describe_firewall_rules --config ~/.mcporter/mcporter.json --output json --args '{"Region":"ap-guangzhou","InstanceId":"lhins-xxxxxxxx"}' + +# 添加防火墙规则 +mcporter call lighthouse.create_firewall_rules --config ~/.mcporter/mcporter.json --output json --args '{"Region":"ap-guangzhou","InstanceId":"lhins-xxxxxxxx","FirewallRules":[{"Protocol":"TCP","Port":"8080","CidrBlock":"0.0.0.0/0","Action":"ACCEPT","FirewallRuleDescription":"开放8080端口"}]}' + +# 删除防火墙规则 +mcporter call lighthouse.delete_firewall_rules --config ~/.mcporter/mcporter.json --output json --args '{"Region":"ap-guangzhou","InstanceId":"lhins-xxxxxxxx","FirewallRules":[{"Protocol":"TCP","Port":"8080"}]}' +``` + +### 远程命令执行 (TAT) + +```bash +# 在 Linux 实例上执行命令 +mcporter call lighthouse.execute_command --config ~/.mcporter/mcporter.json --output json --args '{"Region":"ap-guangzhou","InstanceId":"lhins-xxxxxxxx","Command":"uptime && df -h && free -m","SystemType":"Linux"}' + +# 在 Windows 实例上执行命令 +mcporter call lighthouse.execute_command --config ~/.mcporter/mcporter.json --output json --args '{"Region":"ap-guangzhou","InstanceId":"lhins-xxxxxxxx","Command":"Get-Process | Sort-Object CPU -Descending | Select-Object -First 10","SystemType":"Windows"}' + +# 查询命令执行任务详情(自动轮询直到完成) +mcporter call lighthouse.describe_command_tasks --config ~/.mcporter/mcporter.json --output json --args '{"Region":"ap-guangzhou","InvocationTaskId":"invt-xxxxxxxx"}' + +# 注意: Command 最大 2048 字符,超长命令建议登录实例手动执行 +``` + +## 使用规范 + +1. **每次调用必须带** `--config ~/.mcporter/mcporter.json` +2. **始终加** `--output json` 获取结构化输出 +3. **Region 参数规则**: 除 `describe_regions` 外,所有操作都**必须**传入 `Region` 参数。如果用户未指定 Region,应先调用 `describe_regions` 获取可用地域列表,再让用户选择或根据上下文确定 +4. **首次使用流程**: 先调用 `describe_regions` 获取地域列表 → 再调用 `describe_instances` 获取实例列表 → 记住 InstanceId 和 Region 供后续使用 +5. **用实际的 InstanceId** 替换示例中的 `lhins-xxxxxxxx`(先通过 `describe_instances` 获取) +6. **监控指标用中文**: `get_monitor_data` 的 Indicators 参数使用中文名称(CPU利用率、内存利用率等) +7. **命令长度限制**: `execute_command` 的 Command 参数最大 2048 字符,超长建议登录实例执行 +8. **危险操作前先确认**: 防火墙修改、命令执行、实例关机/重启等,先向用户确认 +9. **错误处理**: 如果调用失败,先用 `{baseDir}/scripts/setup.sh --check-only` 诊断问题,或用 `self_test` 检测实例状态 \ No newline at end of file diff --git a/skills/tencentcloud-lighthouse-skill/_meta.json b/skills/tencentcloud-lighthouse-skill/_meta.json new file mode 100644 index 0000000..31d5ba5 --- /dev/null +++ b/skills/tencentcloud-lighthouse-skill/_meta.json @@ -0,0 +1,6 @@ +{ + "ownerId": "kn75kc19fpd7fhjt8pfak7x3j180v1jy", + "slug": "tencentcloud-lighthouse-skill", + "version": "1.0.0", + "publishedAt": 1770787740068 +} \ No newline at end of file diff --git a/skills/tencentcloud-lighthouse-skill/scripts/setup.sh b/skills/tencentcloud-lighthouse-skill/scripts/setup.sh new file mode 100644 index 0000000..9072ee2 --- /dev/null +++ b/skills/tencentcloud-lighthouse-skill/scripts/setup.sh @@ -0,0 +1,181 @@ +#!/usr/bin/env bash +set -euo pipefail + +# Lighthouse MCP Setup — installs mcporter (if needed) and writes config +# Usage: +# setup.sh --secret-id <ID> --secret-key <KEY> [--config-path <path>] [--check-only] +# +# Examples: +# setup.sh --secret-id AKIDxxxx --secret-key yyyyyyy +# setup.sh --check-only +# setup.sh --secret-id AKIDxxxx --secret-key yyyyyyy --config-path /root/.mcporter/mcporter.json + +CONFIG_PATH="${HOME}/.mcporter/mcporter.json" +SECRET_ID="" +SECRET_KEY="" +CHECK_ONLY=false + +usage() { + cat >&2 <<'EOF' +Usage: + setup.sh --secret-id <TENCENTCLOUD_SECRET_ID> --secret-key <TENCENTCLOUD_SECRET_KEY> [--config-path <path>] + setup.sh --check-only + +Options: + --secret-id Tencent Cloud SecretId (required unless --check-only) + --secret-key Tencent Cloud SecretKey (required unless --check-only) + --config-path mcporter config file path (default: ~/.mcporter/mcporter.json) + --check-only Only check if mcporter and config are ready, don't modify anything + -h, --help Show this help +EOF + exit 2 +} + +while [[ $# -gt 0 ]]; do + case "$1" in + --secret-id) SECRET_ID="${2:-}"; shift 2 ;; + --secret-key) SECRET_KEY="${2:-}"; shift 2 ;; + --config-path) CONFIG_PATH="${2:-}"; shift 2 ;; + --check-only) CHECK_ONLY=true; shift ;; + -h|--help) usage ;; + *) echo "Unknown arg: $1" >&2; usage ;; + esac +done + +# --- Check mode --- +if $CHECK_ONLY; then + echo "=== Lighthouse MCP Status Check ===" + + # Check mcporter + if command -v mcporter &>/dev/null; then + echo "[OK] mcporter installed: $(mcporter --version 2>/dev/null || echo 'unknown version')" + else + echo "[MISSING] mcporter not installed" + echo " Fix: npm install -g mcporter" + fi + + # Check config file + if [[ -f "$CONFIG_PATH" ]]; then + echo "[OK] Config file exists: $CONFIG_PATH" + # Check if lighthouse server is configured + if grep -q '"lighthouse"' "$CONFIG_PATH" 2>/dev/null; then + echo "[OK] lighthouse MCP server configured" + # Check if credentials are present (not placeholder) + if grep -q 'TENCENTCLOUD_SECRET_ID' "$CONFIG_PATH" 2>/dev/null; then + echo "[OK] Tencent Cloud credentials found in config" + else + echo "[WARN] Tencent Cloud credentials may be missing" + fi + else + echo "[MISSING] lighthouse MCP server not in config" + fi + else + echo "[MISSING] Config file not found: $CONFIG_PATH" + fi + + # Try listing servers + if command -v mcporter &>/dev/null && [[ -f "$CONFIG_PATH" ]]; then + echo "" + echo "=== MCP Servers ===" + mcporter list --config "$CONFIG_PATH" 2>/dev/null || echo "[ERROR] Failed to list servers" + fi + + exit 0 +fi + +# --- Setup mode: validate inputs --- +if [[ -z "$SECRET_ID" ]]; then + echo "[ERROR] --secret-id is required" >&2 + exit 1 +fi +if [[ -z "$SECRET_KEY" ]]; then + echo "[ERROR] --secret-key is required" >&2 + exit 1 +fi + +echo "=== Lighthouse MCP Auto Setup ===" + +# Step 1: Check/install mcporter +if command -v mcporter &>/dev/null; then + echo "[OK] mcporter already installed" +else + echo "[INSTALL] Installing mcporter via npm..." + npm install -g mcporter + if command -v mcporter &>/dev/null; then + echo "[OK] mcporter installed successfully" + else + echo "[ERROR] mcporter installation failed" >&2 + exit 1 + fi +fi + +# Step 2: Create config directory +CONFIG_DIR="$(dirname "$CONFIG_PATH")" +if [[ ! -d "$CONFIG_DIR" ]]; then + mkdir -p "$CONFIG_DIR" + echo "[OK] Created config directory: $CONFIG_DIR" +fi + +# Step 3: Write/update config with lighthouse server +# If config exists, try to merge; otherwise create new +if [[ -f "$CONFIG_PATH" ]]; then + echo "[INFO] Updating existing config: $CONFIG_PATH" + # Use a temp file for safe write + TEMP_CONFIG="$(mktemp)" + # Simple JSON merge using node (available since mcporter requires node) + node -e " + const fs = require('fs'); + let config = {}; + try { config = JSON.parse(fs.readFileSync('$CONFIG_PATH', 'utf8')); } catch {} + if (!config.mcpServers) config.mcpServers = {}; + config.mcpServers.lighthouse = { + command: 'npx', + args: ['-y', 'lighthouse-mcp-server'], + env: { + TENCENTCLOUD_SECRET_ID: '$SECRET_ID', + TENCENTCLOUD_SECRET_KEY: '$SECRET_KEY' + } + }; + fs.writeFileSync('$TEMP_CONFIG', JSON.stringify(config, null, 2)); + " + mv "$TEMP_CONFIG" "$CONFIG_PATH" +else + echo "[INFO] Creating new config: $CONFIG_PATH" + cat > "$CONFIG_PATH" <<JSONEOF +{ + "mcpServers": { + "lighthouse": { + "command": "npx", + "args": ["-y", "lighthouse-mcp-server"], + "env": { + "TENCENTCLOUD_SECRET_ID": "$SECRET_ID", + "TENCENTCLOUD_SECRET_KEY": "$SECRET_KEY" + } + } + } +} +JSONEOF +fi + +echo "[OK] Config written: $CONFIG_PATH" + +# Step 4: Verify +echo "" +echo "=== Verification ===" +echo "Listing MCP servers..." +mcporter list --config "$CONFIG_PATH" 2>/dev/null || echo "[WARN] mcporter list failed (server may need first-run initialization)" + +echo "" +echo "Testing lighthouse connection (listing tools)..." +if mcporter list lighthouse --config "$CONFIG_PATH" --schema 2>/dev/null; then + echo "" + echo "[OK] Lighthouse MCP setup complete! All tools available." +else + echo "[WARN] Could not list lighthouse tools yet. This is normal on first run." + echo " The MCP server will be started on first call." +fi + +echo "" +echo "=== Setup Complete ===" +echo "Config: $CONFIG_PATH" +echo "Server: lighthouse (via npx lighthouse-mcp-server)" \ No newline at end of file diff --git a/skills/tencentcloud-ocr-general/SKILL.md b/skills/tencentcloud-ocr-general/SKILL.md new file mode 100644 index 0000000..8fee663 --- /dev/null +++ b/skills/tencentcloud-ocr-general/SKILL.md @@ -0,0 +1,131 @@ +--- +name: tencentcloud-ocr-general +description: 腾讯云广告文字识别(AdvertiseOCR)接口调用技能。当用户需要从图片中识别文字内容时,应使用此技能。支持中英文、横排、竖排及倾斜场景的图片文字识别,支持90度、180度、270度翻转场景的图片识别,返回文本框位置与文字内容。支持图片Base64和URL两种输入方式。 +--- + +# 腾讯云广告文字识别 (AdvertiseOCR) + +## 用途 + +调用腾讯云OCR广告文字识别接口,支持图片内文字的检测和识别,返回文本框位置与文字内容。具有较高召回率和准确率。 + +核心能力: +- **中英文识别**:支持中英文混合文字识别 +- **多方向支持**:支持横排、竖排以及倾斜场景文字识别 +- **翻转支持**:支持90度、180度、270度翻转场景文字识别 +- **坐标返回**:返回每个文本行的四顶点坐标(Polygon) +- **置信度评估**:返回每个文本行的识别置信度(0~100) + +官方文档:https://cloud.tencent.com/document/api/866/49524 + +默认接口请求频率限制:20次/秒。 + +## 使用时机 + +当用户提出以下需求时触发此技能: +- 需要从图片中提取文字信息 +- 需要识别图片上的文字内容 +- 涉及文字OCR识别的任何场景 +- 需要获取图片中文字的位置坐标信息 + +## 环境要求 + +- Python 3.6+ +- 依赖:`tencentcloud-sdk-python`(通过 `pip install tencentcloud-sdk-python` 安装) +- 环境变量: + - `TENCENTCLOUD_SECRET_ID`:腾讯云API密钥ID + - `TENCENTCLOUD_SECRET_KEY`:腾讯云API密钥Key + +## 使用方式 + +运行 `scripts/main.py` 脚本完成图片文字识别。 + +### 请求参数 + +| 参数 | 类型 | 必填 | 说明 | +|------|------|------|------| +| ImageBase64 | str | 否(二选一) | 图片Base64值,编码后不超过10M,分辨率建议600*800以上,支持PNG/JPG/JPEG/BMP | +| ImageUrl | str | 否(二选一) | 图片URL地址,建议存储于腾讯云COS。都提供时仅使用ImageUrl | + +### 输出格式 + +识别成功后返回 JSON 格式结果: + +```json +{ + "TextDetections": [ + { + "DetectedText": "识别出的文本行内容", + "Confidence": 99, + "Polygon": [ + {"X": 0, "Y": 0}, + {"X": 100, "Y": 0}, + {"X": 100, "Y": 50}, + {"X": 0, "Y": 50} + ], + "AdvancedInfo": "{\"Parag\":{\"ParagNo\":1}}" + } + ], + "TextCount": 1, + "ImageSize": { + "Width": 800, + "Height": 600 + }, + "RequestId": "xxx" +} +``` + +**响应字段说明:** + +| 字段 | 类型 | 说明 | +|------|------|------| +| TextDetections | list | 检测到的文本信息列表 | +| TextDetections[].DetectedText | str | 识别出的文本行内容 | +| TextDetections[].Confidence | int | 置信度 0~100 | +| TextDetections[].Polygon | list of Coord | 文本行坐标,四个顶点坐标(X, Y) | +| TextDetections[].AdvancedInfo | str | 扩展字段,含段落信息Parag(ParagNo) | +| TextCount | int | 检测到的文本行数量 | +| ImageSize | object | 图片分辨率信息,含Width和Height(单位px) | +| RequestId | str | 唯一请求ID | + +### 错误码说明 + +| 错误码 | 含义 | +|--------|------| +| FailedOperation.DownLoadError | 文件下载失败 | +| FailedOperation.EmptyImageError | 图片内容为空 | +| FailedOperation.EngineRecognizeTimeout | 引擎识别超时 | +| FailedOperation.ImageDecodeFailed | 图片解码失败 | +| FailedOperation.ImageNoText | 图片中未检测到文本 | +| FailedOperation.LanguageNotSupport | 输入的Language不支持 | +| FailedOperation.OcrFailed | OCR识别失败 | +| FailedOperation.UnKnowError | 未知错误 | +| FailedOperation.UnOpenError | 服务未开通 | +| InvalidParameterValue.InvalidParameterValueLimit | 参数值错误 | +| LimitExceeded.TooLargeFileError | 文件内容太大 | +| ResourceUnavailable.InArrears | 账号已欠费 | +| ResourceUnavailable.ResourcePackageRunOut | 账号资源包耗尽 | +| ResourcesSoldOut.ChargeStatusException | 计费状态异常 | + +### 业务逻辑说明 + +1. ImageBase64和ImageUrl必须提供其一,都提供时只使用ImageUrl +2. 图片经Base64编码后不超过10M,分辨率建议600*800以上 +3. 支持PNG、JPG、JPEG、BMP格式 +4. 始终计费 + +### 调用示例 + +```bash +# 通过URL识别图片文字 +python scripts/main.py --image-url "https://example.com/ad_image.jpg" + +# 通过文件路径(自动Base64编码)识别 +python scripts/main.py --image-base64 ./ad_image.jpg + +# 通过Base64文本文件识别 +python scripts/main.py --image-base64 ./base64.txt + +# 指定地域 +python scripts/main.py --image-url "https://example.com/ad_image.jpg" --region ap-beijing +``` diff --git a/skills/tencentcloud-ocr-general/_meta.json b/skills/tencentcloud-ocr-general/_meta.json new file mode 100644 index 0000000..9e43ad7 --- /dev/null +++ b/skills/tencentcloud-ocr-general/_meta.json @@ -0,0 +1,6 @@ +{ + "ownerId": "kn71qd8mtdsrf1bsagg94kx5tn82dqt6", + "slug": "tencentcloud-ocr-general", + "version": "1.0.1", + "publishedAt": 1772961532647 +} \ No newline at end of file diff --git a/skills/tencentcloud-ocr-general/scripts/main.py b/skills/tencentcloud-ocr-general/scripts/main.py new file mode 100644 index 0000000..9d6a0e2 --- /dev/null +++ b/skills/tencentcloud-ocr-general/scripts/main.py @@ -0,0 +1,229 @@ +#!/usr/bin/env python3 +""" +腾讯云广告文字识别(AdvertiseOCR)调用脚本 + +支持广告商品图片内文字的检测和识别,返回文本框位置与文字内容。 +支持中英文、横排、竖排以及倾斜场景文字识别,支持90度、180度、270度翻转。 +需要环境变量: TENCENTCLOUD_SECRET_ID, TENCENTCLOUD_SECRET_KEY + +用法: + python main.py --image-url <url> + python main.py --image-base64 <base64_or_filepath> +""" + +import argparse +import json +import os +import sys +import base64 + +# SDK 最大图片限制 (10MB) +MAX_IMAGE_SIZE_BYTES = 10 * 1024 * 1024 + +# 错误码含义映射 +ERROR_CODE_MAP = { + "FailedOperation.DownLoadError": "文件下载失败", + "FailedOperation.EmptyImageError": "图片内容为空", + "FailedOperation.EngineRecognizeTimeout": "引擎识别超时", + "FailedOperation.ImageDecodeFailed": "图片解码失败", + "FailedOperation.ImageNoText": "图片中未检测到文本", + "FailedOperation.LanguageNotSupport": "输入的Language不支持", + "FailedOperation.OcrFailed": "OCR识别失败", + "FailedOperation.UnKnowError": "未知错误", + "FailedOperation.UnOpenError": "服务未开通", + "InvalidParameterValue.InvalidParameterValueLimit": "参数值错误", + "LimitExceeded.TooLargeFileError": "文件内容太大", + "ResourceUnavailable.InArrears": "账号已欠费", + "ResourceUnavailable.ResourcePackageRunOut": "账号资源包耗尽", + "ResourcesSoldOut.ChargeStatusException": "计费状态异常", +} + + +def validate_env() -> tuple: + """校验并返回腾讯云API密钥。""" + secret_id = os.environ.get("TENCENTCLOUD_SECRET_ID") + secret_key = os.environ.get("TENCENTCLOUD_SECRET_KEY") + if not secret_id or not secret_key: + print("错误: 请设置环境变量 TENCENTCLOUD_SECRET_ID 和 TENCENTCLOUD_SECRET_KEY", file=sys.stderr) + sys.exit(1) + return secret_id, secret_key + + +def load_image_base64(value: str) -> str: + """ + 加载 Base64 图片内容。 + 如果 value 是一个存在的文件路径,则读取文件内容作为 Base64; + 否则直接视为 Base64 字符串。 + """ + if os.path.isfile(value): + with open(value, "rb") as f: + raw = f.read() + # 如果文件内容本身就是Base64文本(如txt文件),直接使用 + try: + raw_str = raw.decode("utf-8").strip() + base64.b64decode(raw_str, validate=True) + return raw_str + except Exception: + pass + # 否则将二进制文件编码为Base64 + if len(raw) > MAX_IMAGE_SIZE_BYTES: + print(f"错误: 图片文件大小超过 {MAX_IMAGE_SIZE_BYTES // (1024 * 1024)}MB 限制", file=sys.stderr) + sys.exit(1) + encoded = base64.b64encode(raw).decode("utf-8") + return encoded + else: + # 直接作为 Base64 字符串使用 + try: + decoded = base64.b64decode(value, validate=True) + if len(decoded) > MAX_IMAGE_SIZE_BYTES: + print(f"错误: 图片大小超过 {MAX_IMAGE_SIZE_BYTES // (1024 * 1024)}MB 限制", file=sys.stderr) + sys.exit(1) + except Exception: + print("错误: 提供的 ImageBase64 不是合法的 Base64 编码,也不是有效的文件路径", file=sys.stderr) + sys.exit(1) + return value + + +def format_response(resp_json: dict) -> dict: + """格式化响应结果,提取关键信息并结构化输出。""" + output = {} + + # 文本检测结果 + text_detections = resp_json.get("TextDetections") + if text_detections: + formatted_texts = [] + for item in text_detections: + text_info = { + "DetectedText": item.get("DetectedText", ""), + "Confidence": item.get("Confidence", 0), + } + # 文本行坐标 + polygon = item.get("Polygon") + if polygon: + text_info["Polygon"] = polygon + # 扩展信息 + advanced_info = item.get("AdvancedInfo") + if advanced_info: + text_info["AdvancedInfo"] = advanced_info + formatted_texts.append(text_info) + output["TextDetections"] = formatted_texts + output["TextCount"] = len(formatted_texts) + + # 图片分辨率 + image_size = resp_json.get("ImageSize") + if image_size: + output["ImageSize"] = image_size + + # 请求ID + if "RequestId" in resp_json: + output["RequestId"] = resp_json["RequestId"] + + return output + + +def call_advertise_ocr(args: argparse.Namespace) -> None: + """调用腾讯云 AdvertiseOCR 接口。""" + try: + from tencentcloud.common import credential + from tencentcloud.common.profile.client_profile import ClientProfile + from tencentcloud.common.profile.http_profile import HttpProfile + from tencentcloud.common.exception.tencent_cloud_sdk_exception import TencentCloudSDKException + from tencentcloud.ocr.v20181119 import ocr_client, models + except ImportError: + print("错误: 缺少依赖 tencentcloud-sdk-python,请执行: pip install tencentcloud-sdk-python", file=sys.stderr) + sys.exit(1) + + secret_id, secret_key = validate_env() + + # 构建客户端 + cred = credential.Credential(secret_id, secret_key) + http_profile = HttpProfile() + http_profile.endpoint = "ocr.tencentcloudapi.com" + client_profile = ClientProfile() + client_profile.httpProfile = http_profile + region = args.region if args.region else "ap-guangzhou" + client = ocr_client.OcrClient(cred, region, client_profile) + + # 构建请求 + req = models.AdvertiseOCRRequest() + + if args.image_url: + req.ImageUrl = args.image_url + elif args.image_base64: + req.ImageBase64 = load_image_base64(args.image_base64) + else: + print("错误: 必须提供 --image-url 或 --image-base64 之一", file=sys.stderr) + sys.exit(1) + + # 发起请求 + try: + resp = client.AdvertiseOCR(req) + except TencentCloudSDKException as e: + error_desc = ERROR_CODE_MAP.get(e.code, "") + error_msg = f"API调用失败 [{e.code}]: {e.message}" + if error_desc: + error_msg += f" ({error_desc})" + print(error_msg, file=sys.stderr) + if e.requestId: + print(f"RequestId: {e.requestId}", file=sys.stderr) + sys.exit(1) + + # 解析并格式化输出 + resp_json = json.loads(resp.to_json_string()) + result = format_response(resp_json) + print(json.dumps(result, ensure_ascii=False, indent=2)) + + +def build_parser() -> argparse.ArgumentParser: + """构建命令行参数解析器。""" + parser = argparse.ArgumentParser( + description="腾讯云广告文字识别(AdvertiseOCR)调用工具", + formatter_class=argparse.RawDescriptionHelpFormatter, + epilog=""" +示例: + # 通过URL识别广告图片文字 + python main.py --image-url "https://example.com/ad_image.jpg" + + # 通过文件路径(自动Base64编码)识别 + python main.py --image-base64 ./ad_image.jpg + + # 通过Base64文本文件识别 + python main.py --image-base64 ./base64.txt + + # 指定地域 + python main.py --image-url "https://example.com/ad_image.jpg" --region ap-beijing + """, + ) + + # 图片输入(二选一) + img_group = parser.add_mutually_exclusive_group(required=True) + img_group.add_argument( + "--image-url", + type=str, + help="图片URL地址,建议存储于腾讯云COS", + ) + img_group.add_argument( + "--image-base64", + type=str, + help="图片Base64字符串,或图片/Base64文本文件的路径", + ) + + # 可选参数 + parser.add_argument( + "--region", + type=str, + default=None, + help="腾讯云地域,默认 ap-guangzhou", + ) + + return parser + + +def main(): + parser = build_parser() + args = parser.parse_args() + call_advertise_ocr(args) + + +if __name__ == "__main__": + main() diff --git a/skills/tesseract-ocr/SKILL.md b/skills/tesseract-ocr/SKILL.md new file mode 100644 index 0000000..76b8060 --- /dev/null +++ b/skills/tesseract-ocr/SKILL.md @@ -0,0 +1,81 @@ +--- +name: tesseract-ocr +description: | + Extract text from images using the Tesseract OCR engine directly via command line. + Supports multiple languages including Chinese, English, and more. Use this skill + when users need to extract text from images, recognize text content in images, + or perform OCR tasks without Python dependencies. +--- + +# Tesseract OCR Skill + +Extract text content from images using the Tesseract engine directly via command line. + +## Features + +- Extract text from image files using native tesseract CLI +- Support multi-language recognition (Chinese, English, etc.) +- No Python dependencies required +- Simple and fast + +## Dependencies + +Install Tesseract OCR system package: + +```bash +# Ubuntu/Debian: +sudo apt-get install tesseract-ocr tesseract-ocr-chi-sim + +# macOS: +brew install tesseract tesseract-lang +``` + +## Usage + +### Basic Usage + +```bash +# Use default language (English) +tesseract /path/to/image.png stdout + +# Specify language (Chinese + English) +tesseract /path/to/image.png stdout -l chi_sim+eng + +# Save to file +tesseract /path/to/image.png output.txt -l chi_sim+eng + +# Multiple languages +tesseract /path/to/image.png stdout -l chi_sim+eng+jpn +``` + +### Common Language Codes + +| Language | Code | +|----------|------| +| Simplified Chinese | chi_sim | +| Traditional Chinese | chi_tra | +| English | eng | +| Japanese | jpn | +| Korean | kor | +| Chinese + English | chi_sim+eng | + +### Quick Examples + +```bash +# OCR with Chinese support +tesseract image.jpg stdout -l chi_sim + +# OCR with mixed Chinese and English +tesseract image.png stdout -l chi_sim+eng + +# Save to file instead of stdout +tesseract document.png result -l chi_sim+eng +# Creates result.txt +``` + +## Notes + +1. OCR accuracy depends on image quality; use clear images for best results +2. Complex layouts (tables, multi-column) may require post-processing +3. Chinese recognition requires the tesseract-ocr-chi-sim language pack +4. Language packs must be installed separately on your system diff --git a/skills/tesseract-ocr/_meta.json b/skills/tesseract-ocr/_meta.json new file mode 100644 index 0000000..fdc27f8 --- /dev/null +++ b/skills/tesseract-ocr/_meta.json @@ -0,0 +1,6 @@ +{ + "ownerId": "kn7203wfp8phcdg21808vpd6w181ccqt", + "slug": "tesseract-ocr", + "version": "1.0.0", + "publishedAt": 1771421190683 +} \ No newline at end of file diff --git a/skills/thought-to-excalidraw/SKILL.md b/skills/thought-to-excalidraw/SKILL.md new file mode 100644 index 0000000..3e75722 --- /dev/null +++ b/skills/thought-to-excalidraw/SKILL.md @@ -0,0 +1,61 @@ +--- +name: pm-visualizer +description: Visualizes Product Manager thoughts (Why, What, How, User Journey) into an editable Excalidraw diagram. Use when the user asks to "visualize specs", "create a PM diagram", or "map out product thoughts". +--- + +# PM Visualizer Skill + +This skill converts unstructured Product Manager thoughts into a structured Excalidraw visualization. + +## Features +- **Smart Layout**: Automatically columns "Why, What, How" and creates a horizontal flow for "User Journey". +- **Color Coding**: Visual distinction between problem (Why - Yellow), solution (What - Green), implementation (How - Blue), and flow (Journey - Red/Pink). +- **Grouped Elements**: Text is properly bound to containers so they move together. + +## Workflow + +1. **Analyze Request**: Extract the following sections from the user's prompt or context: + * **Title**: The feature or product name. + * **Why**: The problem statement, business goals, or "Why are we building this?". + * **What**: The solution requirements, features, or "What is it?". + * **How**: Technical implementation details, API strategy, or "How will we build it?". + * **Journey**: A sequential list of steps for the user journey or process flow. + +2. **Prepare Data**: Create a JSON file (e.g., `temp_visual_data.json`) with this structure: + ```json + { + "title": "Feature Name", + "why": ["Reason 1", "Reason 2"], + "what": ["Feature 1", "Feature 2"], + "how": ["Tech 1", "Tech 2"], + "journey": ["Step 1", "Step 2", "Step 3"] + } + ``` + +3. **Generate Diagram**: Run the python script to generate the `.excalidraw` file. + ```bash + python3 skills/pm-visualizer/scripts/layout_diagram.py temp_visual_data.json ~/Downloads/Documents/PM_Visuals/Output_Name.excalidraw + ``` + *Ensure the output directory exists first.* + +4. **Cleanup**: Delete the temporary JSON input file. + +5. **Report**: Inform the user the file is ready at the output path. + +## Example + +**User:** "Visualize a new 'Login with Google' feature. Why? Reduce friction. What? Google button on login page. How? OAuth2. Journey: User clicks button -> Google Popup -> Redirect to Dashboard." + +**Codex Action:** +1. Create `login_spec.json`: + ```json + { + "title": "Login with Google", + "why": ["Reduce friction", "Increase conversion"], + "what": ["Google Sign-in Button", "Profile Sync"], + "how": ["OAuth 2.0 Flow", "Google Identity SDK"], + "journey": ["User clicks 'Sign in with Google'", "Google permissions popup appears", "User approves access", "System verifies token", "User redirected to Dashboard"] + } + ``` +2. `mkdir -p ~/Downloads/Documents/PM_Visuals` +3. `python3 skills/pm-visualizer/scripts/layout_diagram.py login_spec.json ~/Downloads/Documents/PM_Visuals/Login_Spec.excalidraw` diff --git a/skills/thought-to-excalidraw/_meta.json b/skills/thought-to-excalidraw/_meta.json new file mode 100644 index 0000000..35e40ce --- /dev/null +++ b/skills/thought-to-excalidraw/_meta.json @@ -0,0 +1,6 @@ +{ + "ownerId": "kn74gzdqfnysavbywf64wpkj0s80810s", + "slug": "thought-to-excalidraw", + "version": "1.0.0", + "publishedAt": 1769883872038 +} \ No newline at end of file diff --git a/skills/thought-to-excalidraw/references/excalidraw-schema.md b/skills/thought-to-excalidraw/references/excalidraw-schema.md new file mode 100644 index 0000000..11c862e --- /dev/null +++ b/skills/thought-to-excalidraw/references/excalidraw-schema.md @@ -0,0 +1,98 @@ +# Excalidraw JSON Schema Reference + +An `.excalidraw` file is a JSON object with the following top-level structure: + +```json +{ + "type": "excalidraw", + "version": 2, + "source": "https://excalidraw.com", + "elements": [ ... ], + "appState": { + "viewBackgroundColor": "#ffffff", + "gridSize": null + } +} +``` + +## Element Types + +### Common Properties (All Elements) +All elements share these fields: +- `id`: string (unique, e.g., "node-1") +- `x`: number (x position) +- `y`: number (y position) +- `width`: number +- `height`: number +- `angle`: number (usually 0) +- `strokeColor`: string (hex code, e.g., "#000000") +- `backgroundColor`: string (hex code, e.g., "#transparent") +- `fillStyle`: "hachure" | "cross-hatch" | "solid" +- `strokeWidth`: number (1 or 2) +- `strokeStyle`: "solid" | "dashed" | "dotted" +- `roughness`: number (0-2, 1 is standard hand-drawn look) +- `opacity`: number (100) +- `groupIds`: [] +- `roundness`: { "type": 3 } (for rounded corners) or null +- `seed`: number (random integer) +- `version`: number (incrementing) +- `versionNonce`: number (random integer) +- `isDeleted`: false +- `boundElements`: [{ "id": "arrow-id", "type": "arrow" }] (for connecting arrows) + +### 1. Rectangle (Container/Box) +```json +{ + "type": "rectangle", + "label": { "text": "Label inside?" } // NOTE: Excalidraw uses separate "text" elements bound to containers usually, but simple rects just exist. +} +``` +*Note: To put text 'inside' a box, creating a separate "text" element is often safer/standard, centered on the rect.* + +### 2. Ellipse (Start/End nodes) +```json +{ + "type": "ellipse" +} +``` + +### 3. Diamond (Decision) +```json +{ + "type": "diamond" +} +``` + +### 4. Text (Labels) +```json +{ + "type": "text", + "text": "Actual content\nNew line", + "fontSize": 20, + "fontFamily": 1, // 1: Virgil (Hand), 2: Helvetica, 3: Cascadia + "textAlign": "center", // "left", "center", "right" + "verticalAlign": "middle" +} +``` + +### 5. Arrow (Connectors) +Arrows connect two elements. +```json +{ + "type": "arrow", + "points": [[0, 0], [100, 50]], // Relative points from x,y. [0,0] is the start. + "startBinding": { "elementId": "node-1", "focus": 0.5, "gap": 1 }, + "endBinding": { "elementId": "node-2", "focus": 0.5, "gap": 1 } +} +``` +*Tip: If binding is too complex to calc, just placing start/end points near the center of nodes works visualy.* + +## Layout Strategy (Mental Model) + +For a "Why, What, How" tree: +1. **Why (Root)**: Top or Left. +2. **What (Children)**: Level 2. +3. **How (Grandchildren)**: Level 3. + +**User Journey**: +Linear flow: Step 1 -> Arrow -> Step 2 -> Arrow -> Step 3. diff --git a/skills/thought-to-excalidraw/scripts/layout_diagram.py b/skills/thought-to-excalidraw/scripts/layout_diagram.py new file mode 100644 index 0000000..9877b11 --- /dev/null +++ b/skills/thought-to-excalidraw/scripts/layout_diagram.py @@ -0,0 +1,295 @@ +import json +import sys +import random +import time + +def generate_id(): + return ''.join(random.choices('abcdefghijklmnopqrstuvwxyz0123456789', k=10)) + +def create_element(type, x, y, width, height, **kwargs): + group_ids = kwargs.pop('groupIds', []) + return { + "id": generate_id(), + "type": type, + "x": x, + "y": y, + "width": width, + "height": height, + "angle": 0, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": group_ids, + "roundness": {"type": 3} if type == "rectangle" else None, + "seed": random.randint(1, 100000), + "version": 1, + "versionNonce": random.randint(1, 100000), + "isDeleted": False, + "boundElements": [], + "updated": int(time.time() * 1000), + **kwargs + } + +def wrap_text(text, max_chars): + words = text.split(' ') + lines = [] + current_line = [] + current_length = 0 + for word in words: + if current_length + len(word) + 1 > max_chars: + lines.append(' '.join(current_line)) + current_line = [word] + current_length = len(word) + else: + current_line.append(word) + current_length += len(word) + 1 + if current_line: + lines.append(' '.join(current_line)) + return '\n'.join(lines) + +def estimate_text_dims(text, fontSize): + lines = text.split('\n') + max_line_chars = max(len(line) for line in lines) if lines else 0 + text_width = max(50, max_line_chars * (fontSize * 0.6)) + text_height = len(lines) * (fontSize * 1.5) + return text_width, text_height + +def create_text(x, y, text, fontSize=20, groupIds=[], width=None, textAlign="left", verticalAlign="top"): + lines = text.split('\n') + if width is None: + width = max(len(line) for line in lines) * (fontSize * 0.6) + height = len(lines) * (fontSize * 1.25) + return create_element("text", x, y, width, height, + text=text, fontSize=fontSize, fontFamily=1, + textAlign=textAlign, verticalAlign=verticalAlign, groupIds=groupIds + ) + +def create_smart_box_with_text(x, y, text, fontSize=16, fixed_width=None, bgColor="transparent", group=None): + if group is None: + group = generate_id() + padding_x = 20 + padding_y = 20 + final_text = text + if fixed_width: + char_w = fontSize * 0.6 + available_w = fixed_width - (padding_x * 2) + max_chars = int(available_w / char_w) + final_text = wrap_text(text, max_chars) + box_width = fixed_width + else: + final_text = wrap_text(text, 30) + t_w, _ = estimate_text_dims(final_text, fontSize) + box_width = t_w + (padding_x * 2) + t_w, t_h = estimate_text_dims(final_text, fontSize) + box_height = t_h + (padding_y * 2) + box = create_element("rectangle", x, y, box_width, box_height, backgroundColor=bgColor, groupIds=[group]) + text_x = x + (box_width - t_w) / 2 + text_y = y + (box_height - t_h) / 2 + text_el = create_element("text", text_x, text_y, t_w, t_h, + text=final_text, fontSize=fontSize, fontFamily=1, + textAlign="center", verticalAlign="middle", groupIds=[group] + ) + box["boundElements"] = [{"type": "text", "id": text_el["id"]}] + text_el["containerId"] = box["id"] + return box, text_el, box_width, box_height + +def create_container_frame(x, y, w, h, label, color="#000000"): + frame_group = generate_id() + frame = create_element("rectangle", x, y, w, h, + backgroundColor="transparent", strokeStyle="dashed", strokeWidth=2, + strokeColor=color, opacity=50, roughness=2, groupIds=[frame_group] + ) + label_w, label_h = estimate_text_dims(label, 20) + label_el = create_element("text", x + 10, y - label_h - 5, label_w, label_h, + text=label, fontSize=20, fontFamily=1, strokeColor=color, groupIds=[frame_group] + ) + return [frame, label_el] + +def create_arrow(start_id, end_id, start_x, start_y, end_x, end_y): + return create_element("arrow", start_x, start_y, end_x - start_x, end_y - start_y, + points=[[0, 0], [end_x - start_x, end_y - start_y]], + startBinding={"elementId": start_id, "focus": 0, "gap": 10}, + endBinding={"elementId": end_id, "focus": 0, "gap": 10}, + strokeWidth=2, endArrowhead="arrow" + ) + +def main(): + if len(sys.argv) < 3: + print("Usage: python layout_diagram.py <input.json> <output.excalidraw>") + sys.exit(1) + + input_path = sys.argv[1] + output_path = sys.argv[2] + + with open(input_path, 'r') as f: + data = json.load(f) + + # --- LAYOUT CONFIGURATION --- + START_X = 100 + START_Y = 100 + COL_GAP = 40 + ROW_GAP = 30 + + # Colors + C_WHY = "#ffec99" # Yellow + C_WHAT = "#b2f2bb" # Green + C_HOW = "#a5d8ff" # Blue + C_JOURNEY = "#ffc9c9" # Red + + # PM Framework Explanations (The "Meta-Text") + PM_GUIDES = { + "Why": "Focus on: User pain points,\nbusiness value, and 'Why now?'", + "What": "Focus on: Key features,\nfunctional requirements, and MVP scope.", + "How": "Focus on: Technical implementation,\ndata flow, and feasibility.", + "Journey": "Focus on: The step-by-step flow from user trigger to goal completion." + } + + final_elements = [] + + # ========================================== + # 1. STRATEGY CORE (Why, What, How) + # ========================================== + + strategy_elements = [] + COL_WIDTH = 300 + + cols_data = [ + ("Why", data.get("why", []), C_WHY), + ("What", data.get("what", []), C_WHAT), + ("How", data.get("how", []), C_HOW) + ] + + current_col_x = START_X + 40 # Padding for frame + strategy_start_y = START_Y + 60 # Padding for frame + max_strategy_y = strategy_start_y + + for title, items, color in cols_data: + # Column Title + t_box, t_txt, _, t_h = create_smart_box_with_text( + current_col_x, strategy_start_y, title, fontSize=24, fixed_width=COL_WIDTH, bgColor="transparent" + ) + t_box['strokeStyle'] = "solid" + t_box['backgroundColor'] = "#ffffff" + t_box['strokeWidth'] = 2 + + # Meta-Text (Guide) + guide_y = strategy_start_y + t_h + 10 + guide_text = create_text(current_col_x, guide_y, PM_GUIDES[title], fontSize=14, textAlign="center", width=COL_WIDTH) + guide_text['strokeColor'] = "#868e96" # Grey + + strategy_elements.extend([t_box, t_txt, guide_text]) + + item_y = guide_y + guide_text['height'] + 30 # Gap before first box + + for item in items: + box, txt, w, h = create_smart_box_with_text( + current_col_x, item_y, item, fontSize=16, fixed_width=COL_WIDTH, bgColor=color + ) + strategy_elements.extend([box, txt]) + item_y += h + ROW_GAP + + if item_y > max_strategy_y: + max_strategy_y = item_y + + current_col_x += COL_WIDTH + COL_GAP + + # Calculate bounding box for Strategy Section + strat_w = (current_col_x - COL_GAP) - START_X + 40 + strat_h = (max_strategy_y) - START_Y + 20 + strat_frame = create_container_frame(START_X, START_Y, strat_w, strat_h, "Strategy Core", "#555555") + + final_elements.extend(strat_frame) + final_elements.extend(strategy_elements) + + # ========================================== + # 2. USER JOURNEY (Adaptive Layout) + # ========================================== + + journey = data.get("journey", []) + if journey: + journey_start_y = START_Y + strat_h + 100 # Gap between sections + journey_start_x = START_X + + journey_elements = [] + IS_VERTICAL = len(journey) > 6 + + # Guide for Journey + j_guide_text = create_text(journey_start_x + 40, journey_start_y + 40, PM_GUIDES["Journey"], fontSize=14, textAlign="left", width=600) + j_guide_text['strokeColor'] = "#868e96" + journey_elements.append(j_guide_text) + + prev_id = None + prev_bounds = None + + cur_jx = journey_start_x + 40 + cur_jy = journey_start_y + 80 # Adjusted for guide + + max_j_w = 0 + max_j_h = 0 + + for step in journey: + box, txt, w, h = create_smart_box_with_text( + cur_jx, cur_jy, step, fontSize=16, fixed_width=None, bgColor=C_JOURNEY + ) + box['roundness'] = {"type": 3} + if w < 150: pass + + journey_elements.extend([box, txt]) + + if prev_id: + px, py, pw, ph = prev_bounds + if IS_VERTICAL: + s_x, s_y = px + pw/2, py + ph + e_x, e_y = box['x'] + box['width']/2, box['y'] + else: + s_x, s_y = px + pw, py + ph/2 + e_x, e_y = box['x'], box['y'] + box['height']/2 + arrow = create_arrow(prev_id, box['id'], s_x, s_y, e_x, e_y) + journey_elements.append(arrow) + + prev_id = box['id'] + prev_bounds = (box['x'], box['y'], box['width'], box['height']) + + if IS_VERTICAL: + cur_jy += h + 60 + right_edge = cur_jx + w + if right_edge > max_j_w: max_j_w = right_edge + max_j_h = cur_jy + else: + cur_jx += w + 60 + bottom_edge = cur_jy + h + if bottom_edge > max_j_h: max_j_h = bottom_edge + max_j_w = cur_jx + + j_frame_w = (max_j_w - journey_start_x) + 40 + if IS_VERTICAL: j_frame_w += 40 + j_frame_h = (max_j_h - journey_start_y) + if not IS_VERTICAL: j_frame_h += 40 + + j_frame = create_container_frame(journey_start_x, journey_start_y, j_frame_w, j_frame_h, "User Journey", "#555555") + final_elements.extend(j_frame) + final_elements.extend(journey_elements) + + title_text = data.get("title", "Product Requirements") + final_elements.append(create_text(START_X, START_Y - 120, title_text, fontSize=40)) + + output_data = { + "type": "excalidraw", + "version": 2, + "source": "https://openclaw.ai", + "elements": final_elements, + "appState": {"viewBackgroundColor": "#ffffff", "gridSize": None}, + "files": {} + } + + with open(output_path, 'w') as f: + json.dump(output_data, f, indent=2) + + print(f"Generated diagram with {len(final_elements)} elements.") + +if __name__ == "__main__": + main() diff --git a/skills/voice-message/SKILL.md b/skills/voice-message/SKILL.md new file mode 100644 index 0000000..5e2e847 --- /dev/null +++ b/skills/voice-message/SKILL.md @@ -0,0 +1,77 @@ +--- +name: voice-message +version: 1.0.4 +description: Send voice messages across chat channels (Telegram, Discord, Feishu/Lark, Signal, WhatsApp, and others) using edge-tts for text-to-speech and ffmpeg for audio conversion. IMPORTANT - Feishu/Lark does NOT support asVoice=true via the message tool; you MUST use this skill to send voice messages on Feishu, otherwise it will send a file attachment instead of a voice bubble. | 通过 edge-tts 文字转语音和 ffmpeg 音频转换,在各聊天渠道(Telegram、Discord、飞书、Signal、WhatsApp 等)发送语音消息。飞书不支持 message 工具的 asVoice=true,必须使用本 skill 才能发送语音气泡而非文件附件。 +metadata: + openclaw: + emoji: "🎤" +--- + +# Voice Message + +Send text as voice messages to any chat channel. + +## Prerequisites + +- `edge-tts` — Microsoft Edge TTS (`pip install edge-tts`) +- `ffmpeg` / `ffprobe` — audio conversion and duration detection + +## Default Voices + +- Chinese: `zh-CN-XiaoxiaoNeural` +- English: `en-US-JennyNeural` +- Other languages: see [references/voices.md](references/voices.md) + +## Step 1: Generate Voice File + +Use `scripts/gen_voice.sh` to convert text to an ogg/opus file: + +```bash +scripts/gen_voice.sh "你好" /tmp/voice.ogg +scripts/gen_voice.sh "Hello" /tmp/voice.ogg en-US-JennyNeural +``` + +Arguments: `<text> <output.ogg> [voice]` +- If voice is omitted, defaults to `zh-CN-XiaoxiaoNeural`. + +## Step 2: Send by Channel + +### Generic (Telegram, Signal, WhatsApp, etc.) + +Use the message tool directly: + +``` +action=send, asVoice=true, filePath=/tmp/voice.ogg +``` + +This works for most channels. Telegram confirmed working. + +### Feishu/Lark + +⚠️ Feishu does NOT support `asVoice=true` via the message tool. You must use the dedicated script. + +Use `scripts/send_feishu_voice.sh`: + +```bash +scripts/send_feishu_voice.sh /tmp/voice.ogg <receive_id> <tenant_access_token> [receive_id_type] +``` + +- `receive_id_type`: `open_id` (default), `chat_id`, `user_id`, `union_id`, `email` +- The script handles upload (as opus with duration) and sends as audio message type to produce a voice bubble. +- To get `tenant_access_token`, use the Feishu tenant token API with your app credentials. + +### Discord + +Discord voice messages require a waveform and special flags. + +1. Generate ogg with `scripts/gen_voice.sh` +2. Generate waveform: `python3 scripts/gen_waveform.py /tmp/voice.ogg` + - Outputs JSON: `{"duration_secs": 4.2, "waveform": "base64..."}` +3. Send via Discord API with `flags: 8192` (IS_VOICE_MESSAGE) and the waveform/duration in attachments metadata. + - Missing waveform/duration causes error 50161. + +### Fallback + +If `asVoice=true` does not produce a voice bubble on a channel: +1. Try sending via the platform's native API +2. If native API unavailable, send as audio file attachment diff --git a/skills/voice-message/_meta.json b/skills/voice-message/_meta.json new file mode 100644 index 0000000..9a7c2ce --- /dev/null +++ b/skills/voice-message/_meta.json @@ -0,0 +1,6 @@ +{ + "ownerId": "kn723j18ymp7d11sm0dvgz24s981ndwd", + "slug": "voice-message", + "version": "1.0.4", + "publishedAt": 1772175873705 +} \ No newline at end of file diff --git a/skills/voice-message/references/voices.md b/skills/voice-message/references/voices.md new file mode 100644 index 0000000..0e35ec9 --- /dev/null +++ b/skills/voice-message/references/voices.md @@ -0,0 +1,24 @@ +# Voice Reference + +Recommended edge-tts voices by language. + +| Language | Voice | Type | +|----------|-------|------| +| Chinese (Mandarin) | zh-CN-XiaoxiaoNeural | Female, warm | +| Chinese (Mandarin) | zh-CN-YunjianNeural | Male, steady | +| Chinese (Cantonese) | zh-HK-HiuGaaiNeural | Female | +| Chinese (Taiwan) | zh-TW-HsiaoChenNeural | Female | +| English (US) | en-US-JennyNeural | Female, natural | +| English (US) | en-US-GuyNeural | Male | +| English (UK) | en-GB-SoniaNeural | Female | +| Japanese | ja-JP-NanamiNeural | Female | +| Korean | ko-KR-SunHiNeural | Female | +| French | fr-FR-DeniseNeural | Female | +| German | de-DE-KatjaNeural | Female | +| Spanish | es-ES-ElviraNeural | Female | +| Portuguese (BR) | pt-BR-FranciscaNeural | Female | +| Russian | ru-RU-SvetlanaNeural | Female | +| Thai | th-TH-PremwadeeNeural | Female | +| Vietnamese | vi-VN-HoaiMyNeural | Female | + +Full list: `edge-tts --list-voices` diff --git a/skills/voice-message/scripts/gen_voice.sh b/skills/voice-message/scripts/gen_voice.sh new file mode 100644 index 0000000..b35c82a --- /dev/null +++ b/skills/voice-message/scripts/gen_voice.sh @@ -0,0 +1,23 @@ +#!/bin/bash +# Generate ogg/opus voice file from text using edge-tts + ffmpeg +# Usage: gen_voice.sh <text> <output.ogg> [voice] +# Default voice: zh-CN-XiaoxiaoNeural + +set -e + +TEXT="$1" +OUTPUT="$2" +VOICE="${3:-zh-CN-XiaoxiaoNeural}" + +if [ -z "$TEXT" ] || [ -z "$OUTPUT" ]; then + echo "Usage: gen_voice.sh <text> <output.ogg> [voice]" + exit 1 +fi + +TMP_MP3=$(mktemp /tmp/voice_XXXXXX.mp3) +trap "rm -f $TMP_MP3" EXIT + +edge-tts --voice "$VOICE" --text "$TEXT" --write-media "$TMP_MP3" 2>&1 +ffmpeg -y -i "$TMP_MP3" -c:a libopus -b:a 64k "$OUTPUT" 2>&1 | tail -1 + +echo "Generated: $OUTPUT" diff --git a/skills/voice-message/scripts/gen_waveform.py b/skills/voice-message/scripts/gen_waveform.py new file mode 100644 index 0000000..45a7acb --- /dev/null +++ b/skills/voice-message/scripts/gen_waveform.py @@ -0,0 +1,65 @@ +#!/usr/bin/env python3 +"""Generate Discord voice message waveform from an ogg file. +Usage: gen_waveform.py <ogg_file> +Output: JSON with duration_secs and base64-encoded waveform (256 points, 0-255). +""" + +import subprocess +import struct +import base64 +import json +import sys + +def main(): + if len(sys.argv) < 2: + print("Usage: gen_waveform.py <ogg_file>") + sys.exit(1) + + ogg_file = sys.argv[1] + + # Get duration + result = subprocess.run( + ["ffprobe", "-v", "error", "-show_entries", "format=duration", + "-of", "csv=p=0", ogg_file], + capture_output=True, text=True + ) + duration_secs = float(result.stdout.strip()) + + # Extract raw PCM (mono, 16-bit, 48kHz) + result = subprocess.run( + ["ffmpeg", "-i", ogg_file, "-f", "s16le", "-ac", "1", + "-ar", "48000", "-"], + capture_output=True + ) + pcm_data = result.stdout + + # Parse samples + num_samples = len(pcm_data) // 2 + samples = struct.unpack(f"<{num_samples}h", pcm_data[:num_samples * 2]) + + # Generate 256-point waveform + points = 256 + chunk_size = max(1, num_samples // points) + waveform = [] + + for i in range(points): + start = i * chunk_size + end = min(start + chunk_size, num_samples) + if start >= num_samples: + waveform.append(0) + continue + chunk = samples[start:end] + avg = sum(abs(s) for s in chunk) / len(chunk) + # Map to 0-255 + val = min(255, int(avg / 32768 * 255)) + waveform.append(val) + + waveform_b64 = base64.b64encode(bytes(waveform)).decode() + + print(json.dumps({ + "duration_secs": round(duration_secs, 2), + "waveform": waveform_b64 + })) + +if __name__ == "__main__": + main() diff --git a/skills/voice-message/scripts/send_feishu_voice.sh b/skills/voice-message/scripts/send_feishu_voice.sh new file mode 100644 index 0000000..c44899f --- /dev/null +++ b/skills/voice-message/scripts/send_feishu_voice.sh @@ -0,0 +1,46 @@ +#!/bin/bash +# Send voice message to Feishu/Lark +# Usage: send_feishu_voice.sh <ogg_file> <receive_id> <tenant_access_token> [receive_id_type] +# receive_id_type: open_id (default), chat_id, user_id, union_id, email + +set -e + +OGG_FILE="$1" +RECEIVE_ID="$2" +TOKEN="$3" +ID_TYPE="${4:-open_id}" +API_BASE="https://open.feishu.cn/open-apis" + +if [ -z "$OGG_FILE" ] || [ -z "$RECEIVE_ID" ] || [ -z "$TOKEN" ]; then + echo "Usage: send_feishu_voice.sh <ogg_file> <receive_id> <token> [receive_id_type]" + exit 1 +fi + +# 1. Get duration in milliseconds +DURATION_SEC=$(ffprobe -v error -show_entries format=duration -of csv=p=0 "$OGG_FILE") +DURATION_MS=$(python3 -c "print(int(float('$DURATION_SEC') * 1000))") + +# 2. Upload file to Feishu +UPLOAD_RESP=$(curl -s -X POST "$API_BASE/im/v1/files" \ + -H "Authorization: Bearer $TOKEN" \ + -F "file_type=opus" \ + -F "file_name=voice.ogg" \ + -F "duration=$DURATION_MS" \ + -F "file=@$OGG_FILE") + +FILE_KEY=$(echo "$UPLOAD_RESP" | python3 -c "import json,sys; print(json.load(sys.stdin).get('data',{}).get('file_key',''))") + +if [ -z "$FILE_KEY" ]; then + echo "Upload failed: $UPLOAD_RESP" + exit 1 +fi + +echo "Uploaded: file_key=$FILE_KEY" + +# 3. Send audio message +SEND_RESP=$(curl -s -X POST "$API_BASE/im/v1/messages?receive_id_type=$ID_TYPE" \ + -H "Authorization: Bearer $TOKEN" \ + -H "Content-Type: application/json" \ + -d "{\"receive_id\":\"$RECEIVE_ID\",\"msg_type\":\"audio\",\"content\":\"{\\\"file_key\\\":\\\"$FILE_KEY\\\"}\"}") + +echo "Send result: $SEND_RESP" diff --git a/skills/weather/SKILL.md b/skills/weather/SKILL.md new file mode 100644 index 0000000..2146580 --- /dev/null +++ b/skills/weather/SKILL.md @@ -0,0 +1,49 @@ +--- +name: weather +description: Get current weather and forecasts (no API key required). +homepage: https://wttr.in/:help +metadata: {"clawdbot":{"emoji":"🌤️","requires":{"bins":["curl"]}}} +--- + +# Weather + +Two free services, no API keys needed. + +## wttr.in (primary) + +Quick one-liner: +```bash +curl -s "wttr.in/London?format=3" +# Output: London: ⛅️ +8°C +``` + +Compact format: +```bash +curl -s "wttr.in/London?format=%l:+%c+%t+%h+%w" +# Output: London: ⛅️ +8°C 71% ↙5km/h +``` + +Full forecast: +```bash +curl -s "wttr.in/London?T" +``` + +Format codes: `%c` condition · `%t` temp · `%h` humidity · `%w` wind · `%l` location · `%m` moon + +Tips: +- URL-encode spaces: `wttr.in/New+York` +- Airport codes: `wttr.in/JFK` +- Units: `?m` (metric) `?u` (USCS) +- Today only: `?1` · Current only: `?0` +- PNG: `curl -s "wttr.in/Berlin.png" -o /tmp/weather.png` + +## Open-Meteo (fallback, JSON) + +Free, no key, good for programmatic use: +```bash +curl -s "https://api.open-meteo.com/v1/forecast?latitude=51.5&longitude=-0.12¤t_weather=true" +``` + +Find coordinates for a city, then query. Returns JSON with temp, windspeed, weathercode. + +Docs: https://open-meteo.com/en/docs diff --git a/skills/weather/_meta.json b/skills/weather/_meta.json new file mode 100644 index 0000000..4556002 --- /dev/null +++ b/skills/weather/_meta.json @@ -0,0 +1,6 @@ +{ + "ownerId": "kn70pywhg0fyz996kpa8xj89s57yhv26", + "slug": "weather", + "version": "1.0.0", + "publishedAt": 1767545394459 +} \ No newline at end of file diff --git a/skills/web-search-free/SKILL.md b/skills/web-search-free/SKILL.md new file mode 100644 index 0000000..8602e7e --- /dev/null +++ b/skills/web-search-free/SKILL.md @@ -0,0 +1,149 @@ +--- +name: web-search-free +description: Free AI search via Exa MCP. Fall back to Multi Search Engine if not successfull. All without API keys. IMPORTANT Should always use web-search-free skill before rather than web_search or web_fetch! +metadata: {"clawdbot":{"emoji":"🔍","requires":{"bins":["mcporter"]}}} +--- + +# Web Search (Free) + +Neural search for web, code, company research, people and deep research. No API key required. +Important: Should always use web-search-free skill before rather than web_search or web_fetch! + +## Setup + +Verify mcporter is configured: +```bash +mcporter list exa +``` + +If not listed: +```bash +mcporter config add exa "https://mcp.exa.ai/mcp?tools=web_search_exa,web_search_advanced_exa,get_code_context_exa,crawling_exa,company_research_exa,people_search_exa,deep_researcher_start,deep_researcher_check" +``` + +## Core Tools + +### web_search_exa +Search web for current info, news, or facts. + +```bash +mcporter call 'exa.web_search_exa(query: "latest AI news 2026", numResults: 5)' +``` + +**Parameters:** +- `query` - Search query +- `numResults` (optional, default: 8) +- `type` (optional) - `"auto"`, `"fast"`, or `"deep"` + +### get_code_context_exa +Find code examples and docs from GitHub, Stack Overflow. + +```bash +mcporter call 'exa.get_code_context_exa(query: "React hooks examples", tokensNum: 3000)' +``` + +**Parameters:** +- `query` - Code/API search query +- `tokensNum` (optional, default: 5000) - Range: 1000-50000 + +### company_research_exa +Research companies for business info and news. + +```bash +mcporter call 'exa.company_research_exa(companyName: "Anthropic", numResults: 3)' +``` + +**Parameters:** +- `companyName` - Company name +- `numResults` (optional, default: 5) + +### web_search_advanced_exa +Advanced web search with full control over filters, domains, dates, and content options. +Best for: When you need specific filters like date ranges, domain restrictions, or category filters. +Not recommended for: Simple searches - use web_search_exa instead. +Returns: Search results with optional highlights, summaries, and subpage content. + +```bash +mcporter call 'exa.web_search_advanced_exa(companyName: "Anthropic", numResults: 3)' +``` + +**Parameters:** +- `companyName` - Company name +- `numResults` (optional, default: 5) +- `category` (optional, "company" | "research paper" | "news" | "pdf" | "github" | "tweet" | "personal site" | "people" | "financial report") +- `includeDomains`: (optional, e.g. ["github.com", "arxiv.org"]. default: []) +- `startPublishedDate` (optional, Only include results published after this date (ISO 8601: YYYY-MM-DD)) +- `endPublishedDate` (optional, Only include results published before this date (ISO 8601: YYYY-MM-DD)) + +### crawling_exa +Get the full content of a specific webpage. Use when you have an exact URL. +Best for: Extracting content from a known URL. +Returns: Full text content and metadata from the page. + +```bash +mcporter call 'exa.crawling_exa(query: "Li Hao", numResults: 3)' +``` + +**Parameters:** +- `url` - URL to crawl and extract content from +- `maxCharacters` - Maximum characters to extract (optional, default: 3000) + +### people_search_exa +Find people and their professional profiles. +Best for: Finding professionals, executives, or anyone with a public profile. +Returns: Profile information and links. + +```bash +mcporter call 'exa.people_search_exa(query: "Li Hao", numResults: 3)' +``` + +**Parameters:** +- `query` - Search query for finding people +- `numResults` (optional, default: 5) + +### deep_researcher_start +Start an AI research agent that searches, reads, and writes a detailed report. Takes 15 seconds to 2 minutes. +Best for: Complex research questions needing deep analysis and synthesis. +Returns: Research ID - use deep_researcher_check to get results. +Important: Call deep_researcher_check with the returned research ID to get the report. + +```bash +mcporter call 'exa.deep_researcher_start(instructions: "help me find the best paper about Taming LLM Training")' +``` + +**Parameters:** +- `instructions` - Complex research question or detailed instructions for the AI researcher. Be + specific about what you want to research and any particular aspects you want + covered. +- `model` - Research model: 'exa-research-fast' | 'exa-research' | 'exa-research-pro' (Default: exa-research-fast) + +### deep_researcher_check +Check status and get results from a deep research task. +Best for: Getting the research report after calling deep_researcher_start. +Returns: Research report when complete, or status update if still running. +Important: Keep calling with the same research ID until status is 'completed'. + +```bash +mcporter call 'exa.deep_researcher_check(researchId: "r_01kj59p3wsm21k8gdrd69nm4sa")' +``` + +**Parameters:** +- `researchId` - The research ID returned from deep_researcher_start tool + +## Tips + +- Web: Use `type: "fast"` for quick lookup, `"deep"` for thorough research +- Code: Lower `tokensNum` (1000-2000) for focused, higher (5000+) for comprehensive +- See [examples.md](references/examples.md) for more patterns + +## Fallback +If all the above are not suitable for users' question or the tool failed, fallback to Multi Search Engine (multi-search-engine) tool + +## Requirements +multi-search-engine + +## Resources + +- [GitHub](https://github.com/exa-labs/exa-mcp-server) +- [npm](https://www.npmjs.com/package/exa-mcp-server) +- [Docs](https://exa.ai/docs) diff --git a/skills/web-search-free/_meta.json b/skills/web-search-free/_meta.json new file mode 100644 index 0000000..4eab41f --- /dev/null +++ b/skills/web-search-free/_meta.json @@ -0,0 +1,6 @@ +{ + "ownerId": "kn73c2dsgenzec4fv2aq6nt36181qq7v", + "slug": "web-search-free", + "version": "1.0.1", + "publishedAt": 1771858406982 +} \ No newline at end of file diff --git a/skills/web-search-free/references/examples.md b/skills/web-search-free/references/examples.md new file mode 100644 index 0000000..32d1108 --- /dev/null +++ b/skills/web-search-free/references/examples.md @@ -0,0 +1,129 @@ +# Exa Search Examples + +## Web Search Examples + +### Latest News & Current Events +```bash +mcporter call 'exa.web_search_exa(query: "latest AI breakthroughs 2026", numResults: 5)' +mcporter call 'exa.web_search_exa(query: "quantum computing news", type: "fast")' +``` + +### Research Topics +```bash +mcporter call 'exa.web_search_exa(query: "how does RAG work in LLMs", type: "deep", numResults: 8)' +mcporter call 'exa.web_search_exa(query: "best practices for API design", numResults: 5)' +``` + +### Product Information +```bash +mcporter call 'exa.web_search_exa(query: "M4 Mac Mini specifications and reviews")' +mcporter call 'exa.web_search_exa(query: "comparison of vector databases", type: "deep")' +``` + +## Code Context Search Examples + +### Programming Language Basics +```bash +mcporter call 'exa.get_code_context_exa(query: "Python asyncio basics and examples", tokensNum: 3000)' +mcporter call 'exa.get_code_context_exa(query: "Rust ownership and borrowing tutorial")' +``` + +### Framework & Library Usage +```bash +mcporter call 'exa.get_code_context_exa(query: "React useState and useEffect hooks examples", tokensNum: 2000)' +mcporter call 'exa.get_code_context_exa(query: "Next.js 14 app router authentication middleware")' +mcporter call 'exa.get_code_context_exa(query: "Express.js error handling best practices", tokensNum: 4000)' +``` + +### Specific API & SDK Documentation +```bash +mcporter call 'exa.get_code_context_exa(query: "Stripe checkout session implementation", tokensNum: 5000)' +mcporter call 'exa.get_code_context_exa(query: "AWS S3 SDK upload examples Python")' +mcporter call 'exa.get_code_context_exa(query: "Discord.js bot slash commands")' +``` + +### Debugging & Solutions +```bash +mcporter call 'exa.get_code_context_exa(query: "fixing CORS errors in Node.js Express")' +mcporter call 'exa.get_code_context_exa(query: "pandas dataframe memory optimization techniques", tokensNum: 4000)' +``` + +## Company Research Examples + +### Startups & Tech Companies +```bash +mcporter call 'exa.company_research_exa(companyName: "Anthropic", numResults: 3)' +mcporter call 'exa.company_research_exa(companyName: "Perplexity AI")' +mcporter call 'exa.company_research_exa(companyName: "Scale AI", numResults: 5)' +``` + +### Public Companies +```bash +mcporter call 'exa.company_research_exa(companyName: "Microsoft")' +mcporter call 'exa.company_research_exa(companyName: "NVIDIA", numResults: 5)' +``` + +### Research Queries +```bash +# Find funding info +mcporter call 'exa.company_research_exa(companyName: "OpenAI", numResults: 5)' + +# Recent news +mcporter call 'exa.company_research_exa(companyName: "Tesla", numResults: 3)' +``` + +## Parameter Guidance + +### `type` parameter (web_search_exa) +- `"auto"` - Balanced search (default) +- `"fast"` - Quick results, less comprehensive +- `"deep"` - Thorough research, slower but more complete + +### `tokensNum` parameter (get_code_context_exa) +- `1000-2000` - Focused queries, specific examples +- `3000-5000` - Standard documentation lookup (default: 5000) +- `5000-10000` - Comprehensive guides and tutorials +- `10000-50000` - Deep dives, full API documentation + +### `numResults` parameter +- `3-5` - Quick lookup, specific answer +- `5-8` - Standard research (default for web: 8, company: 5) +- `10+` - Comprehensive research, multiple perspectives + +## Advanced Tools Examples + +### Advanced Web Search +```bash +# Search with domain filters +mcporter call 'exa.web_search_advanced_exa(query: "machine learning tutorials", includeDomains: ["github.com", "arxiv.org"])' + +# Search with date range +mcporter call 'exa.web_search_advanced_exa(query: "AI developments", startPublishedDate: "2026-01-01")' +``` + +### Crawling +```bash +# Extract content from specific URL +mcporter call 'exa.crawling_exa(url: "https://anthropic.com/news/claude-3-5-sonnet")' + +# Get clean text from article +mcporter call 'exa.crawling_exa(url: "https://example.com/article")' +``` + +### People Search +```bash +# Find professional profiles +mcporter call 'exa.people_search_exa(query: "Yann LeCun AI researcher")' + +# Research individuals +mcporter call 'exa.people_search_exa(query: "Demis Hassabis DeepMind")' +``` + +### Deep Researcher +```bash +# Start a research task +mcporter call 'exa.deep_researcher_start(instructions: "quantum computing applications in cryptography", model: "exa-research")' + +# Check research status (use taskId from start response) +mcporter call 'exa.deep_researcher_check(researchId: "abc123")' +```