initial commit with charts and assistant chat
This commit is contained in:
100
.gitignore
vendored
Normal file
100
.gitignore
vendored
Normal file
@@ -0,0 +1,100 @@
|
||||
# Environment variables
|
||||
.env
|
||||
.env.local
|
||||
.env.*.local
|
||||
|
||||
# Python
|
||||
__pycache__/
|
||||
*.py[cod]
|
||||
*$py.class
|
||||
*.so
|
||||
.Python
|
||||
build/
|
||||
develop-eggs/
|
||||
dist/
|
||||
downloads/
|
||||
eggs/
|
||||
.eggs/
|
||||
lib/
|
||||
lib64/
|
||||
parts/
|
||||
sdist/
|
||||
var/
|
||||
wheels/
|
||||
pip-wheel-metadata/
|
||||
share/python-wheels/
|
||||
*.egg-info/
|
||||
.installed.cfg
|
||||
*.egg
|
||||
MANIFEST
|
||||
|
||||
# Virtual Environment
|
||||
.venv/
|
||||
venv/
|
||||
ENV/
|
||||
env/
|
||||
|
||||
# Testing
|
||||
.pytest_cache/
|
||||
.coverage
|
||||
.coverage.*
|
||||
htmlcov/
|
||||
.tox/
|
||||
.nox/
|
||||
*.cover
|
||||
*.log
|
||||
|
||||
# ArcticDB data storage
|
||||
*.arctic
|
||||
arctic_data/
|
||||
arcticdb_storage/
|
||||
|
||||
# Memory and data files
|
||||
backend/memory/*.db
|
||||
backend/memory/*.sqlite
|
||||
*.db
|
||||
*.sqlite
|
||||
|
||||
# Uploaded files
|
||||
backend/uploads/
|
||||
|
||||
# Jupyter Notebook
|
||||
.ipynb_checkpoints
|
||||
|
||||
# PyCharm / IntelliJ IDEA
|
||||
.idea/
|
||||
|
||||
# VS Code
|
||||
.vscode/
|
||||
|
||||
# Node.js / Web
|
||||
node_modules/
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
package-lock.json
|
||||
yarn.lock
|
||||
|
||||
# Docker
|
||||
*.log
|
||||
docker-compose.override.yml
|
||||
|
||||
# OS-specific
|
||||
.DS_Store
|
||||
.DS_Store?
|
||||
._*
|
||||
.Spotlight-V100
|
||||
.Trashes
|
||||
ehthumbs.db
|
||||
Thumbs.db
|
||||
*~
|
||||
|
||||
# Git
|
||||
.git/
|
||||
|
||||
# Temporary files
|
||||
*.tmp
|
||||
*.temp
|
||||
*.swp
|
||||
*.swo
|
||||
*.bak
|
||||
10
.idea/.gitignore
generated
vendored
Normal file
10
.idea/.gitignore
generated
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
# Default ignored files
|
||||
/shelf/
|
||||
/workspace.xml
|
||||
# Ignored default folder with query files
|
||||
/queries/
|
||||
# Datasource local storage ignored files
|
||||
/dataSources/
|
||||
/dataSources.local.xml
|
||||
# Editor-based HTTP Client requests
|
||||
/httpRequests/
|
||||
13
.idea/ai.iml
generated
Normal file
13
.idea/ai.iml
generated
Normal file
@@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="PYTHON_MODULE" version="4">
|
||||
<component name="NewModuleRootManager">
|
||||
<content url="file://$MODULE_DIR$">
|
||||
<sourceFolder url="file://$MODULE_DIR$/backend/src" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/backend/tests" isTestSource="true" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/.venv" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/backend/data" />
|
||||
</content>
|
||||
<orderEntry type="jdk" jdkName="Python 3.12 (ai)" jdkType="Python SDK" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
</component>
|
||||
</module>
|
||||
16
.idea/inspectionProfiles/Project_Default.xml
generated
Normal file
16
.idea/inspectionProfiles/Project_Default.xml
generated
Normal file
@@ -0,0 +1,16 @@
|
||||
<component name="InspectionProjectProfileManager">
|
||||
<profile version="1.0">
|
||||
<option name="myName" value="Project Default" />
|
||||
<inspection_tool class="Eslint" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||
<inspection_tool class="GrazieInspection" enabled="false" level="GRAMMAR_ERROR" enabled_by_default="false" />
|
||||
<inspection_tool class="LanguageDetectionInspection" enabled="false" level="WARNING" enabled_by_default="false" />
|
||||
<inspection_tool class="PyIncorrectDocstringInspection" enabled="false" level="WEAK WARNING" enabled_by_default="false" />
|
||||
<inspection_tool class="PyPep8Inspection" enabled="false" level="WEAK WARNING" enabled_by_default="false" />
|
||||
<inspection_tool class="PyPep8NamingInspection" enabled="false" level="WEAK WARNING" enabled_by_default="false" />
|
||||
<inspection_tool class="SpellCheckingInspection" enabled="false" level="TYPO" enabled_by_default="false">
|
||||
<option name="processCode" value="true" />
|
||||
<option name="processLiterals" value="true" />
|
||||
<option name="processComments" value="true" />
|
||||
</inspection_tool>
|
||||
</profile>
|
||||
</component>
|
||||
6
.idea/inspectionProfiles/profiles_settings.xml
generated
Normal file
6
.idea/inspectionProfiles/profiles_settings.xml
generated
Normal file
@@ -0,0 +1,6 @@
|
||||
<component name="InspectionProjectProfileManager">
|
||||
<settings>
|
||||
<option name="USE_PROJECT_PROFILE" value="false" />
|
||||
<version value="1.0" />
|
||||
</settings>
|
||||
</component>
|
||||
7
.idea/misc.xml
generated
Normal file
7
.idea/misc.xml
generated
Normal file
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="Black">
|
||||
<option name="sdkName" value="Python 3.12 (ai)" />
|
||||
</component>
|
||||
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.12 (ai)" project-jdk-type="Python SDK" />
|
||||
</project>
|
||||
8
.idea/modules.xml
generated
Normal file
8
.idea/modules.xml
generated
Normal file
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectModuleManager">
|
||||
<modules>
|
||||
<module fileurl="file://$PROJECT_DIR$/.idea/ai.iml" filepath="$PROJECT_DIR$/.idea/ai.iml" />
|
||||
</modules>
|
||||
</component>
|
||||
</project>
|
||||
12
.idea/runConfigurations/dev.xml
generated
Normal file
12
.idea/runConfigurations/dev.xml
generated
Normal file
@@ -0,0 +1,12 @@
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="dev" type="js.build_tools.npm" nameIsGenerated="true">
|
||||
<package-json value="$PROJECT_DIR$/web/package.json" />
|
||||
<command value="run" />
|
||||
<scripts>
|
||||
<script value="dev" />
|
||||
</scripts>
|
||||
<node-interpreter value="project" />
|
||||
<envs />
|
||||
<method v="2" />
|
||||
</configuration>
|
||||
</component>
|
||||
6
.idea/vcs.xml
generated
Normal file
6
.idea/vcs.xml
generated
Normal file
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="$PROJECT_DIR$" vcs="Git" />
|
||||
</component>
|
||||
</project>
|
||||
20
backend/config.yaml
Normal file
20
backend/config.yaml
Normal file
@@ -0,0 +1,20 @@
|
||||
www_port: 8080
|
||||
server_port: 8081
|
||||
|
||||
# Agent configuration
|
||||
agent:
|
||||
model: "claude-sonnet-4-20250514"
|
||||
temperature: 0.7
|
||||
context_docs_dir: "doc"
|
||||
|
||||
# Local memory configuration (free & sophisticated!)
|
||||
memory:
|
||||
# LangGraph checkpointing (SQLite for conversation state)
|
||||
checkpoint_db: "data/checkpoints.db"
|
||||
|
||||
# ChromaDB (local vector DB for semantic search)
|
||||
chroma_db: "data/chroma"
|
||||
|
||||
# Sentence-transformers model (local embeddings)
|
||||
# Options: all-MiniLM-L6-v2 (fast, small), all-mpnet-base-v2 (better quality)
|
||||
embedding_model: "all-MiniLM-L6-v2"
|
||||
32
backend/requirements.txt
Normal file
32
backend/requirements.txt
Normal file
@@ -0,0 +1,32 @@
|
||||
pydantic2
|
||||
seaborn
|
||||
pandas
|
||||
numpy
|
||||
scipy
|
||||
matplotlib
|
||||
fastapi
|
||||
uvicorn
|
||||
websockets
|
||||
jsonpatch
|
||||
python-multipart
|
||||
ccxt>=4.0.0
|
||||
pyyaml
|
||||
|
||||
# LangChain agent dependencies
|
||||
langchain>=0.3.0
|
||||
langgraph>=0.2.0
|
||||
langgraph-checkpoint-sqlite>=1.0.0
|
||||
langchain-anthropic>=0.3.0
|
||||
langchain-community>=0.3.0
|
||||
|
||||
# Local memory system
|
||||
chromadb>=0.4.0
|
||||
sentence-transformers>=2.0.0
|
||||
sqlalchemy>=2.0.0
|
||||
aiosqlite>=0.19.0
|
||||
|
||||
# Async utilities
|
||||
aiofiles>=24.0.0
|
||||
|
||||
# Environment configuration
|
||||
python-dotenv>=1.0.0
|
||||
3
backend/src/agent/__init__.py
Normal file
3
backend/src/agent/__init__.py
Normal file
@@ -0,0 +1,3 @@
|
||||
from agent.core import create_agent
|
||||
|
||||
__all__ = ["create_agent"]
|
||||
296
backend/src/agent/core.py
Normal file
296
backend/src/agent/core.py
Normal file
@@ -0,0 +1,296 @@
|
||||
import asyncio
|
||||
import logging
|
||||
from typing import AsyncIterator, Dict, Any, Optional
|
||||
|
||||
from langchain_anthropic import ChatAnthropic
|
||||
from langchain_core.messages import HumanMessage, SystemMessage, AIMessage
|
||||
from langchain_core.runnables import RunnableConfig
|
||||
from langgraph.prebuilt import create_react_agent
|
||||
|
||||
from agent.tools import SYNC_TOOLS, DATASOURCE_TOOLS
|
||||
from agent.memory import MemoryManager
|
||||
from agent.session import SessionManager
|
||||
from agent.prompts import build_system_prompt
|
||||
from gateway.user_session import UserSession
|
||||
from gateway.protocol import UserMessage as GatewayUserMessage
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class AgentExecutor:
|
||||
"""LangGraph-based agent executor with streaming support.
|
||||
|
||||
Handles agent invocation, tool execution, and response streaming.
|
||||
Supports interruption for real-time user interaction.
|
||||
"""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
model_name: str = "claude-sonnet-4-20250514",
|
||||
temperature: float = 0.7,
|
||||
api_key: Optional[str] = None,
|
||||
memory_manager: Optional[MemoryManager] = None
|
||||
):
|
||||
"""Initialize agent executor.
|
||||
|
||||
Args:
|
||||
model_name: Anthropic model name
|
||||
temperature: Model temperature
|
||||
api_key: Anthropic API key
|
||||
memory_manager: MemoryManager instance
|
||||
"""
|
||||
self.model_name = model_name
|
||||
self.temperature = temperature
|
||||
self.api_key = api_key
|
||||
|
||||
# Initialize LLM
|
||||
self.llm = ChatAnthropic(
|
||||
model=model_name,
|
||||
temperature=temperature,
|
||||
api_key=api_key,
|
||||
streaming=True
|
||||
)
|
||||
|
||||
# Memory and session management
|
||||
self.memory_manager = memory_manager or MemoryManager()
|
||||
self.session_manager = SessionManager(self.memory_manager)
|
||||
self.agent = None # Will be created after initialization
|
||||
|
||||
async def initialize(self) -> None:
|
||||
"""Initialize the agent system."""
|
||||
await self.memory_manager.initialize()
|
||||
|
||||
# Create agent with tools and LangGraph checkpointing
|
||||
checkpointer = self.memory_manager.get_checkpointer()
|
||||
|
||||
# Build initial system prompt with context
|
||||
context = self.memory_manager.get_context_prompt()
|
||||
system_prompt = build_system_prompt(context, [])
|
||||
|
||||
self.agent = create_react_agent(
|
||||
self.llm,
|
||||
SYNC_TOOLS + DATASOURCE_TOOLS,
|
||||
prompt=system_prompt,
|
||||
checkpointer=checkpointer
|
||||
)
|
||||
|
||||
async def _clear_checkpoint(self, session_id: str) -> None:
|
||||
"""Clear the checkpoint for a session to prevent resuming from invalid state.
|
||||
|
||||
This is called when an error occurs during agent execution to ensure
|
||||
the next interaction starts fresh instead of trying to resume from
|
||||
a broken state (e.g., orphaned tool calls).
|
||||
|
||||
Args:
|
||||
session_id: The session ID whose checkpoint should be cleared
|
||||
"""
|
||||
try:
|
||||
checkpointer = self.memory_manager.get_checkpointer()
|
||||
if checkpointer:
|
||||
# Delete all checkpoints for this thread
|
||||
# LangGraph uses thread_id as the key
|
||||
# The checkpointer API doesn't have a direct delete method,
|
||||
# but we can use the underlying connection
|
||||
async with checkpointer.conn.cursor() as cur:
|
||||
await cur.execute(
|
||||
"DELETE FROM checkpoints WHERE thread_id = ?",
|
||||
(session_id,)
|
||||
)
|
||||
await checkpointer.conn.commit()
|
||||
logger.info(f"Cleared checkpoint for session {session_id}")
|
||||
except Exception as e:
|
||||
logger.warning(f"Failed to clear checkpoint for session {session_id}: {e}")
|
||||
|
||||
def _build_system_message(self, state: Dict[str, Any]) -> SystemMessage:
|
||||
"""Build system message with context.
|
||||
|
||||
Args:
|
||||
state: Agent state
|
||||
|
||||
Returns:
|
||||
SystemMessage with full context
|
||||
"""
|
||||
# Get context from loaded documents
|
||||
context = self.memory_manager.get_context_prompt()
|
||||
|
||||
# Get active channels from metadata
|
||||
active_channels = state.get("metadata", {}).get("active_channels", [])
|
||||
|
||||
# Build system prompt
|
||||
system_prompt = build_system_prompt(context, active_channels)
|
||||
|
||||
return SystemMessage(content=system_prompt)
|
||||
|
||||
async def execute(
|
||||
self,
|
||||
session: UserSession,
|
||||
message: GatewayUserMessage
|
||||
) -> AsyncIterator[str]:
|
||||
"""Execute the agent and stream responses.
|
||||
|
||||
Args:
|
||||
session: User session
|
||||
message: User message
|
||||
|
||||
Yields:
|
||||
Response chunks as they're generated
|
||||
"""
|
||||
logger.info(f"AgentExecutor.execute called for session {session.session_id}")
|
||||
|
||||
# Get session lock to prevent concurrent execution
|
||||
lock = await self.session_manager.get_session_lock(session.session_id)
|
||||
logger.info(f"Session lock acquired for {session.session_id}")
|
||||
|
||||
async with lock:
|
||||
try:
|
||||
# Build message history
|
||||
messages = []
|
||||
history = session.get_history(limit=10)
|
||||
logger.info(f"Building message history, {len(history)} messages in history")
|
||||
|
||||
for i, msg in enumerate(history):
|
||||
logger.info(f"History message {i}: role={msg.role}, content_len={len(msg.content)}, content='{msg.content[:100]}'")
|
||||
if msg.role == "user":
|
||||
messages.append(HumanMessage(content=msg.content))
|
||||
elif msg.role == "assistant":
|
||||
messages.append(AIMessage(content=msg.content))
|
||||
|
||||
logger.info(f"Prepared {len(messages)} messages for agent")
|
||||
for i, msg in enumerate(messages):
|
||||
logger.info(f"LangChain message {i}: type={type(msg).__name__}, content_len={len(msg.content)}, content='{msg.content[:100] if msg.content else 'EMPTY'}'")
|
||||
|
||||
# Prepare config with metadata
|
||||
config = RunnableConfig(
|
||||
configurable={
|
||||
"thread_id": session.session_id
|
||||
},
|
||||
metadata={
|
||||
"session_id": session.session_id,
|
||||
"user_id": session.user_id,
|
||||
"active_channels": session.active_channels
|
||||
}
|
||||
)
|
||||
logger.info(f"Agent config prepared: thread_id={session.session_id}")
|
||||
|
||||
# Invoke agent with streaming
|
||||
logger.info("Starting agent.astream_events...")
|
||||
full_response = ""
|
||||
event_count = 0
|
||||
chunk_count = 0
|
||||
|
||||
async for event in self.agent.astream_events(
|
||||
{"messages": messages},
|
||||
config=config,
|
||||
version="v2"
|
||||
):
|
||||
event_count += 1
|
||||
|
||||
# Check for cancellation
|
||||
if asyncio.current_task().cancelled():
|
||||
logger.warning("Agent execution cancelled")
|
||||
break
|
||||
|
||||
# Log tool calls
|
||||
if event["event"] == "on_tool_start":
|
||||
tool_name = event.get("name", "unknown")
|
||||
tool_input = event.get("data", {}).get("input", {})
|
||||
logger.info(f"Tool call started: {tool_name} with input: {tool_input}")
|
||||
|
||||
elif event["event"] == "on_tool_end":
|
||||
tool_name = event.get("name", "unknown")
|
||||
tool_output = event.get("data", {}).get("output")
|
||||
logger.info(f"Tool call completed: {tool_name} with output: {tool_output}")
|
||||
|
||||
# Extract streaming tokens
|
||||
elif event["event"] == "on_chat_model_stream":
|
||||
chunk = event["data"]["chunk"]
|
||||
if hasattr(chunk, "content") and chunk.content:
|
||||
content = chunk.content
|
||||
# Handle both string and list content
|
||||
if isinstance(content, list):
|
||||
# Extract text from content blocks
|
||||
text_parts = []
|
||||
for block in content:
|
||||
if isinstance(block, dict) and "text" in block:
|
||||
text_parts.append(block["text"])
|
||||
elif hasattr(block, "text"):
|
||||
text_parts.append(block.text)
|
||||
content = "".join(text_parts)
|
||||
|
||||
if content: # Only yield non-empty content
|
||||
full_response += content
|
||||
chunk_count += 1
|
||||
logger.debug(f"Yielding content chunk #{chunk_count}")
|
||||
yield content
|
||||
|
||||
logger.info(f"Agent streaming complete: {event_count} events, {chunk_count} content chunks, {len(full_response)} chars")
|
||||
|
||||
# Save to persistent memory
|
||||
logger.info(f"Saving assistant message to persistent memory")
|
||||
await self.session_manager.save_message(
|
||||
session.session_id,
|
||||
"assistant",
|
||||
full_response
|
||||
)
|
||||
logger.info("Assistant message saved to memory")
|
||||
|
||||
except asyncio.CancelledError:
|
||||
logger.warning(f"Agent execution cancelled for session {session.session_id}")
|
||||
# Clear checkpoint on cancellation to prevent orphaned tool calls
|
||||
await self._clear_checkpoint(session.session_id)
|
||||
raise
|
||||
except Exception as e:
|
||||
error_msg = f"Agent execution error: {str(e)}"
|
||||
logger.error(error_msg, exc_info=True)
|
||||
|
||||
# Clear checkpoint on error to prevent invalid state (e.g., orphaned tool calls)
|
||||
# This ensures the next interaction starts fresh instead of trying to resume
|
||||
# from a broken state
|
||||
await self._clear_checkpoint(session.session_id)
|
||||
|
||||
yield error_msg
|
||||
|
||||
|
||||
def create_agent(
|
||||
model_name: str = "claude-sonnet-4-20250514",
|
||||
temperature: float = 0.7,
|
||||
api_key: Optional[str] = None,
|
||||
checkpoint_db_path: str = "data/checkpoints.db",
|
||||
chroma_db_path: str = "data/chroma",
|
||||
embedding_model: str = "all-MiniLM-L6-v2",
|
||||
context_docs_dir: str = "doc",
|
||||
base_dir: str = "."
|
||||
) -> AgentExecutor:
|
||||
"""Create and initialize an agent executor.
|
||||
|
||||
Args:
|
||||
model_name: Anthropic model name
|
||||
temperature: Model temperature
|
||||
api_key: Anthropic API key
|
||||
checkpoint_db_path: Path to LangGraph checkpoint SQLite DB
|
||||
chroma_db_path: Path to ChromaDB storage directory
|
||||
embedding_model: Sentence-transformers model name
|
||||
context_docs_dir: Directory with context markdown files
|
||||
base_dir: Base directory for resolving paths
|
||||
|
||||
Returns:
|
||||
Initialized AgentExecutor
|
||||
"""
|
||||
# Initialize memory manager
|
||||
memory_manager = MemoryManager(
|
||||
checkpoint_db_path=checkpoint_db_path,
|
||||
chroma_db_path=chroma_db_path,
|
||||
embedding_model=embedding_model,
|
||||
context_docs_dir=context_docs_dir,
|
||||
base_dir=base_dir
|
||||
)
|
||||
|
||||
# Create executor
|
||||
executor = AgentExecutor(
|
||||
model_name=model_name,
|
||||
temperature=temperature,
|
||||
api_key=api_key,
|
||||
memory_manager=memory_manager
|
||||
)
|
||||
|
||||
return executor
|
||||
380
backend/src/agent/memory.py
Normal file
380
backend/src/agent/memory.py
Normal file
@@ -0,0 +1,380 @@
|
||||
import os
|
||||
import glob
|
||||
from typing import List, Dict, Any, Optional
|
||||
from datetime import datetime
|
||||
|
||||
import aiofiles
|
||||
import chromadb
|
||||
from chromadb.config import Settings
|
||||
from sentence_transformers import SentenceTransformer
|
||||
from langgraph.checkpoint.sqlite.aio import AsyncSqliteSaver
|
||||
|
||||
# Prevent ChromaDB from reporting telemetry to the mothership
|
||||
os.environ["ANONYMIZED_TELEMETRY"] = "False"
|
||||
|
||||
class MemoryManager:
|
||||
"""Manages persistent memory using local tools:
|
||||
|
||||
- LangGraph checkpointing (SQLite) for conversation state
|
||||
- ChromaDB for semantic memory search
|
||||
- Local sentence-transformers for embeddings
|
||||
- Memory graph approach for clustering related concepts
|
||||
"""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
checkpoint_db_path: str = "data/checkpoints.db",
|
||||
chroma_db_path: str = "data/chroma",
|
||||
embedding_model: str = "all-MiniLM-L6-v2",
|
||||
context_docs_dir: str = "memory",
|
||||
base_dir: str = "."
|
||||
):
|
||||
"""Initialize memory manager.
|
||||
|
||||
Args:
|
||||
checkpoint_db_path: Path to SQLite checkpoint database
|
||||
chroma_db_path: Path to ChromaDB directory
|
||||
embedding_model: Sentence-transformers model name
|
||||
context_docs_dir: Directory containing markdown context files
|
||||
base_dir: Base directory for resolving relative paths
|
||||
"""
|
||||
self.checkpoint_db_path = checkpoint_db_path
|
||||
self.chroma_db_path = chroma_db_path
|
||||
self.embedding_model_name = embedding_model
|
||||
self.context_docs_dir = os.path.join(base_dir, context_docs_dir)
|
||||
|
||||
# Will be initialized on startup
|
||||
self.checkpointer: Optional[AsyncSqliteSaver] = None
|
||||
self.checkpointer_context: Optional[Any] = None # Store the context manager
|
||||
self.chroma_client: Optional[chromadb.Client] = None
|
||||
self.memory_collection: Optional[Any] = None
|
||||
self.embedding_model: Optional[SentenceTransformer] = None
|
||||
|
||||
self.context_documents: Dict[str, str] = {}
|
||||
self.initialized = False
|
||||
|
||||
async def initialize(self) -> None:
|
||||
"""Initialize the memory system and load context documents."""
|
||||
if self.initialized:
|
||||
return
|
||||
|
||||
# Ensure data directories exist
|
||||
os.makedirs(os.path.dirname(self.checkpoint_db_path), exist_ok=True)
|
||||
os.makedirs(self.chroma_db_path, exist_ok=True)
|
||||
|
||||
# Initialize LangGraph checkpointer (SQLite)
|
||||
self.checkpointer_context = AsyncSqliteSaver.from_conn_string(
|
||||
self.checkpoint_db_path
|
||||
)
|
||||
self.checkpointer = await self.checkpointer_context.__aenter__()
|
||||
await self.checkpointer.setup()
|
||||
|
||||
# Initialize ChromaDB
|
||||
self.chroma_client = chromadb.PersistentClient(
|
||||
path=self.chroma_db_path,
|
||||
settings=Settings(
|
||||
anonymized_telemetry=False,
|
||||
allow_reset=True
|
||||
)
|
||||
)
|
||||
|
||||
# Get or create memory collection
|
||||
self.memory_collection = self.chroma_client.get_or_create_collection(
|
||||
name="conversation_memory",
|
||||
metadata={"description": "Semantic memory for conversations"}
|
||||
)
|
||||
|
||||
# Initialize local embedding model
|
||||
print(f"Loading embedding model: {self.embedding_model_name}")
|
||||
self.embedding_model = SentenceTransformer(self.embedding_model_name)
|
||||
|
||||
# Load markdown context documents
|
||||
await self._load_context_documents()
|
||||
|
||||
# Index context documents in ChromaDB
|
||||
await self._index_context_documents()
|
||||
|
||||
self.initialized = True
|
||||
print("Memory system initialized (LangGraph + ChromaDB + local embeddings)")
|
||||
|
||||
async def _load_context_documents(self) -> None:
|
||||
"""Load all markdown files from context directory."""
|
||||
if not os.path.exists(self.context_docs_dir):
|
||||
print(f"Warning: Context directory {self.context_docs_dir} not found")
|
||||
return
|
||||
|
||||
md_files = glob.glob(os.path.join(self.context_docs_dir, "*.md"))
|
||||
|
||||
for md_file in md_files:
|
||||
try:
|
||||
async with aiofiles.open(md_file, "r", encoding="utf-8") as f:
|
||||
content = await f.read()
|
||||
filename = os.path.basename(md_file)
|
||||
self.context_documents[filename] = content
|
||||
print(f"Loaded context document: {filename}")
|
||||
except Exception as e:
|
||||
print(f"Error loading {md_file}: {e}")
|
||||
|
||||
async def _index_context_documents(self) -> None:
|
||||
"""Index context documents in ChromaDB for semantic search."""
|
||||
if not self.context_documents or not self.memory_collection:
|
||||
return
|
||||
|
||||
for filename, content in self.context_documents.items():
|
||||
# Split into sections (by headers)
|
||||
sections = self._split_document_into_sections(content, filename)
|
||||
|
||||
for i, section in enumerate(sections):
|
||||
doc_id = f"context_{filename}_{i}"
|
||||
|
||||
# Generate embedding
|
||||
embedding = self.embedding_model.encode(section["content"]).tolist()
|
||||
|
||||
# Add to ChromaDB
|
||||
self.memory_collection.add(
|
||||
ids=[doc_id],
|
||||
embeddings=[embedding],
|
||||
documents=[section["content"]],
|
||||
metadatas=[{
|
||||
"type": "context",
|
||||
"source": filename,
|
||||
"section": section["title"],
|
||||
"indexed_at": datetime.utcnow().isoformat()
|
||||
}]
|
||||
)
|
||||
|
||||
print(f"Indexed {len(self.context_documents)} context documents")
|
||||
|
||||
def _split_document_into_sections(self, content: str, filename: str) -> List[Dict[str, str]]:
|
||||
"""Split markdown document into logical sections.
|
||||
|
||||
Args:
|
||||
content: Markdown content
|
||||
filename: Source filename
|
||||
|
||||
Returns:
|
||||
List of section dicts with title and content
|
||||
"""
|
||||
sections = []
|
||||
current_section = {"title": filename, "content": ""}
|
||||
|
||||
for line in content.split("\n"):
|
||||
if line.startswith("#"):
|
||||
# New section
|
||||
if current_section["content"].strip():
|
||||
sections.append(current_section)
|
||||
current_section = {
|
||||
"title": line.strip("#").strip(),
|
||||
"content": line + "\n"
|
||||
}
|
||||
else:
|
||||
current_section["content"] += line + "\n"
|
||||
|
||||
# Add last section
|
||||
if current_section["content"].strip():
|
||||
sections.append(current_section)
|
||||
|
||||
return sections
|
||||
|
||||
def get_context_prompt(self) -> str:
|
||||
"""Generate a context prompt from loaded documents.
|
||||
|
||||
system_prompt.md is ALWAYS included first and prioritized.
|
||||
Other documents are included after.
|
||||
|
||||
Returns:
|
||||
Formatted string containing all context documents
|
||||
"""
|
||||
if not self.context_documents:
|
||||
return ""
|
||||
|
||||
sections = []
|
||||
|
||||
# ALWAYS include system_prompt.md first if it exists
|
||||
system_prompt_key = "system_prompt.md"
|
||||
if system_prompt_key in self.context_documents:
|
||||
sections.append(self.context_documents[system_prompt_key])
|
||||
sections.append("\n---\n")
|
||||
|
||||
# Add other context documents
|
||||
sections.append("# Additional Context\n")
|
||||
sections.append("The following documents provide additional context about the system:\n")
|
||||
|
||||
for filename, content in sorted(self.context_documents.items()):
|
||||
# Skip system_prompt.md since we already added it
|
||||
if filename == system_prompt_key:
|
||||
continue
|
||||
|
||||
sections.append(f"\n## {filename}\n")
|
||||
sections.append(content)
|
||||
|
||||
return "\n".join(sections)
|
||||
|
||||
async def add_memory(
|
||||
self,
|
||||
session_id: str,
|
||||
role: str,
|
||||
content: str,
|
||||
metadata: Optional[Dict[str, Any]] = None
|
||||
) -> None:
|
||||
"""Add a message to semantic memory (ChromaDB).
|
||||
|
||||
Args:
|
||||
session_id: Session identifier
|
||||
role: Message role ("user" or "assistant")
|
||||
content: Message content
|
||||
metadata: Optional metadata
|
||||
"""
|
||||
if not self.memory_collection or not self.embedding_model:
|
||||
return
|
||||
|
||||
try:
|
||||
# Generate unique ID
|
||||
timestamp = datetime.utcnow().isoformat()
|
||||
doc_id = f"{session_id}_{role}_{timestamp}"
|
||||
|
||||
# Generate embedding
|
||||
embedding = self.embedding_model.encode(content).tolist()
|
||||
|
||||
# Prepare metadata
|
||||
meta = {
|
||||
"session_id": session_id,
|
||||
"role": role,
|
||||
"timestamp": timestamp,
|
||||
"type": "conversation",
|
||||
**(metadata or {})
|
||||
}
|
||||
|
||||
# Add to ChromaDB
|
||||
self.memory_collection.add(
|
||||
ids=[doc_id],
|
||||
embeddings=[embedding],
|
||||
documents=[content],
|
||||
metadatas=[meta]
|
||||
)
|
||||
except Exception as e:
|
||||
print(f"Error adding to ChromaDB memory: {e}")
|
||||
|
||||
async def search_memory(
|
||||
self,
|
||||
session_id: str,
|
||||
query: str,
|
||||
limit: int = 5,
|
||||
include_context: bool = True
|
||||
) -> List[Dict[str, Any]]:
|
||||
"""Search memory using semantic similarity.
|
||||
|
||||
Args:
|
||||
session_id: Session identifier (filters to this session + context docs)
|
||||
query: Search query
|
||||
limit: Maximum results
|
||||
include_context: Whether to include context documents in search
|
||||
|
||||
Returns:
|
||||
List of relevant memory items with content and metadata
|
||||
"""
|
||||
if not self.memory_collection or not self.embedding_model:
|
||||
return []
|
||||
|
||||
try:
|
||||
# Generate query embedding
|
||||
query_embedding = self.embedding_model.encode(query).tolist()
|
||||
|
||||
# Build where filter
|
||||
where_filters = []
|
||||
if include_context:
|
||||
# Search both session messages and context docs
|
||||
where_filters = {
|
||||
"$or": [
|
||||
{"session_id": session_id},
|
||||
{"type": "context"}
|
||||
]
|
||||
}
|
||||
else:
|
||||
where_filters = {"session_id": session_id}
|
||||
|
||||
# Query ChromaDB
|
||||
results = self.memory_collection.query(
|
||||
query_embeddings=[query_embedding],
|
||||
n_results=limit,
|
||||
where=where_filters if where_filters else None
|
||||
)
|
||||
|
||||
# Format results
|
||||
memories = []
|
||||
if results and results["documents"]:
|
||||
for i, doc in enumerate(results["documents"][0]):
|
||||
memories.append({
|
||||
"content": doc,
|
||||
"metadata": results["metadatas"][0][i],
|
||||
"distance": results["distances"][0][i] if "distances" in results else None
|
||||
})
|
||||
|
||||
return memories
|
||||
except Exception as e:
|
||||
print(f"Error searching ChromaDB memory: {e}")
|
||||
return []
|
||||
|
||||
async def get_memory_graph(
|
||||
self,
|
||||
session_id: str,
|
||||
max_depth: int = 2
|
||||
) -> Dict[str, Any]:
|
||||
"""Get a graph of related memories using clustering.
|
||||
|
||||
This creates a simple memory graph by finding clusters of related concepts.
|
||||
|
||||
Args:
|
||||
session_id: Session identifier
|
||||
max_depth: Maximum depth for related memory traversal
|
||||
|
||||
Returns:
|
||||
Dict representing memory graph structure
|
||||
"""
|
||||
# Simple implementation: get all memories for session and cluster by similarity
|
||||
if not self.memory_collection:
|
||||
return {}
|
||||
|
||||
try:
|
||||
# Get all memories for this session
|
||||
results = self.memory_collection.get(
|
||||
where={"session_id": session_id},
|
||||
include=["embeddings", "documents", "metadatas"]
|
||||
)
|
||||
|
||||
if not results or not results["documents"]:
|
||||
return {"nodes": [], "edges": []}
|
||||
|
||||
# Build simple graph structure
|
||||
nodes = []
|
||||
edges = []
|
||||
|
||||
for i, doc in enumerate(results["documents"]):
|
||||
nodes.append({
|
||||
"id": results["ids"][i],
|
||||
"content": doc,
|
||||
"metadata": results["metadatas"][i]
|
||||
})
|
||||
|
||||
# TODO: Compute edges based on embedding similarity
|
||||
# For now, return just nodes
|
||||
return {"nodes": nodes, "edges": edges}
|
||||
|
||||
except Exception as e:
|
||||
print(f"Error building memory graph: {e}")
|
||||
return {}
|
||||
|
||||
def get_checkpointer(self) -> Optional[AsyncSqliteSaver]:
|
||||
"""Get the LangGraph checkpointer for conversation state.
|
||||
|
||||
Returns:
|
||||
AsyncSqliteSaver instance for LangGraph persistence
|
||||
"""
|
||||
return self.checkpointer
|
||||
|
||||
async def close(self) -> None:
|
||||
"""Close the memory manager and cleanup resources."""
|
||||
if self.checkpointer_context:
|
||||
await self.checkpointer_context.__aexit__(None, None, None)
|
||||
self.checkpointer = None
|
||||
self.checkpointer_context = None
|
||||
57
backend/src/agent/prompts.py
Normal file
57
backend/src/agent/prompts.py
Normal file
@@ -0,0 +1,57 @@
|
||||
from typing import List
|
||||
from gateway.user_session import UserSession
|
||||
|
||||
|
||||
def build_system_prompt(context: str, active_channels: List[str]) -> str:
|
||||
"""Build the system prompt for the agent.
|
||||
|
||||
The main system prompt comes from system_prompt.md (loaded in context).
|
||||
This function adds dynamic session information.
|
||||
|
||||
Args:
|
||||
context: Context from loaded markdown documents (includes system_prompt.md)
|
||||
active_channels: List of active channel IDs for this session
|
||||
|
||||
Returns:
|
||||
Formatted system prompt
|
||||
"""
|
||||
channels_str = ", ".join(active_channels) if active_channels else "none"
|
||||
|
||||
# Context already includes system_prompt.md and other docs
|
||||
# Just add current session information
|
||||
prompt = f"""{context}
|
||||
|
||||
## Current Session Information
|
||||
|
||||
**Active Channels**: {channels_str}
|
||||
|
||||
Your responses will be sent to all active channels. Your responses are streamed back in real-time.
|
||||
If the user sends a new message while you're responding, your current response will be interrupted
|
||||
and you'll be re-invoked with the updated context.
|
||||
"""
|
||||
return prompt
|
||||
|
||||
|
||||
def build_user_prompt_with_history(session: UserSession, current_message: str) -> str:
|
||||
"""Build a user prompt including conversation history.
|
||||
|
||||
Args:
|
||||
session: User session with conversation history
|
||||
current_message: Current user message
|
||||
|
||||
Returns:
|
||||
Formatted prompt with history
|
||||
"""
|
||||
messages = []
|
||||
|
||||
# Get recent history (last 10 messages)
|
||||
history = session.get_history(limit=10)
|
||||
|
||||
for msg in history:
|
||||
role_label = "User" if msg.role == "user" else "Assistant"
|
||||
messages.append(f"{role_label}: {msg.content}")
|
||||
|
||||
# Add current message
|
||||
messages.append(f"User: {current_message}")
|
||||
|
||||
return "\n\n".join(messages)
|
||||
93
backend/src/agent/session.py
Normal file
93
backend/src/agent/session.py
Normal file
@@ -0,0 +1,93 @@
|
||||
import asyncio
|
||||
from typing import Dict, Optional
|
||||
from agent.memory import MemoryManager
|
||||
|
||||
|
||||
class SessionManager:
|
||||
"""Manages agent sessions and their associated memory.
|
||||
|
||||
Coordinates between the gateway's UserSession (for conversation state)
|
||||
and the agent's MemoryManager (for persistent memory with Zep).
|
||||
"""
|
||||
|
||||
def __init__(self, memory_manager: MemoryManager):
|
||||
"""Initialize session manager.
|
||||
|
||||
Args:
|
||||
memory_manager: MemoryManager instance for persistent storage
|
||||
"""
|
||||
self.memory = memory_manager
|
||||
self._locks: Dict[str, asyncio.Lock] = {}
|
||||
|
||||
async def get_session_lock(self, session_id: str) -> asyncio.Lock:
|
||||
"""Get or create a lock for a session.
|
||||
|
||||
Prevents concurrent execution for the same session.
|
||||
|
||||
Args:
|
||||
session_id: Session identifier
|
||||
|
||||
Returns:
|
||||
asyncio.Lock for this session
|
||||
"""
|
||||
if session_id not in self._locks:
|
||||
self._locks[session_id] = asyncio.Lock()
|
||||
return self._locks[session_id]
|
||||
|
||||
async def save_message(
|
||||
self,
|
||||
session_id: str,
|
||||
role: str,
|
||||
content: str,
|
||||
metadata: Optional[Dict] = None
|
||||
) -> None:
|
||||
"""Save a message to persistent memory.
|
||||
|
||||
Args:
|
||||
session_id: Session identifier
|
||||
role: Message role ("user" or "assistant")
|
||||
content: Message content
|
||||
metadata: Optional metadata
|
||||
"""
|
||||
await self.memory.add_memory(session_id, role, content, metadata)
|
||||
|
||||
async def get_relevant_context(
|
||||
self,
|
||||
session_id: str,
|
||||
query: str,
|
||||
limit: int = 5
|
||||
) -> str:
|
||||
"""Get relevant historical context for a query.
|
||||
|
||||
Uses semantic search over past conversations.
|
||||
|
||||
Args:
|
||||
session_id: Session identifier
|
||||
query: Search query
|
||||
limit: Maximum results
|
||||
|
||||
Returns:
|
||||
Formatted string of relevant past messages
|
||||
"""
|
||||
results = await self.memory.search_memory(session_id, query, limit)
|
||||
|
||||
if not results:
|
||||
return ""
|
||||
|
||||
context_parts = ["## Relevant Past Context\n"]
|
||||
for i, result in enumerate(results, 1):
|
||||
role = result["role"].capitalize()
|
||||
content = result["content"]
|
||||
score = result.get("score", 0.0)
|
||||
context_parts.append(f"{i}. [{role}, relevance: {score:.2f}] {content}\n")
|
||||
|
||||
return "\n".join(context_parts)
|
||||
|
||||
async def cleanup_session(self, session_id: str) -> None:
|
||||
"""Cleanup session resources.
|
||||
|
||||
Args:
|
||||
session_id: Session to cleanup
|
||||
"""
|
||||
if session_id in self._locks:
|
||||
del self._locks[session_id]
|
||||
662
backend/src/agent/tools.py
Normal file
662
backend/src/agent/tools.py
Normal file
@@ -0,0 +1,662 @@
|
||||
from typing import Dict, Any, List, Optional
|
||||
import io
|
||||
import base64
|
||||
import sys
|
||||
import uuid
|
||||
import logging
|
||||
from pathlib import Path
|
||||
from contextlib import redirect_stdout, redirect_stderr
|
||||
from langchain_core.tools import tool
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
# Global registry instance (will be set by main.py)
|
||||
_registry = None
|
||||
_datasource_registry = None
|
||||
|
||||
|
||||
def set_registry(registry):
|
||||
"""Set the global SyncRegistry instance for tools to use."""
|
||||
global _registry
|
||||
_registry = registry
|
||||
|
||||
|
||||
def set_datasource_registry(datasource_registry):
|
||||
"""Set the global DataSourceRegistry instance for tools to use."""
|
||||
global _datasource_registry
|
||||
_datasource_registry = datasource_registry
|
||||
|
||||
|
||||
@tool
|
||||
def list_sync_stores() -> List[str]:
|
||||
"""List all available synchronization stores.
|
||||
|
||||
Returns:
|
||||
List of store names that can be read/written
|
||||
"""
|
||||
if not _registry:
|
||||
return []
|
||||
return list(_registry.entries.keys())
|
||||
|
||||
|
||||
@tool
|
||||
def read_sync_state(store_name: str) -> Dict[str, Any]:
|
||||
"""Read the current state of a synchronization store.
|
||||
|
||||
Args:
|
||||
store_name: Name of the store to read (e.g., "TraderState", "StrategyState")
|
||||
|
||||
Returns:
|
||||
Dictionary containing the current state of the store
|
||||
|
||||
Raises:
|
||||
ValueError: If store_name doesn't exist
|
||||
"""
|
||||
if not _registry:
|
||||
raise ValueError("SyncRegistry not initialized")
|
||||
|
||||
entry = _registry.entries.get(store_name)
|
||||
if not entry:
|
||||
available = list(_registry.entries.keys())
|
||||
raise ValueError(f"Store '{store_name}' not found. Available stores: {available}")
|
||||
|
||||
return entry.model.model_dump(mode="json")
|
||||
|
||||
|
||||
@tool
|
||||
async def write_sync_state(store_name: str, updates: Dict[str, Any]) -> Dict[str, str]:
|
||||
"""Update the state of a synchronization store.
|
||||
|
||||
This will apply the updates to the store and trigger synchronization
|
||||
with all connected clients.
|
||||
|
||||
Args:
|
||||
store_name: Name of the store to update
|
||||
updates: Dictionary of field updates (field_name: new_value)
|
||||
|
||||
Returns:
|
||||
Dictionary with status and updated fields
|
||||
|
||||
Raises:
|
||||
ValueError: If store_name doesn't exist or updates are invalid
|
||||
"""
|
||||
if not _registry:
|
||||
raise ValueError("SyncRegistry not initialized")
|
||||
|
||||
entry = _registry.entries.get(store_name)
|
||||
if not entry:
|
||||
available = list(_registry.entries.keys())
|
||||
raise ValueError(f"Store '{store_name}' not found. Available stores: {available}")
|
||||
|
||||
try:
|
||||
# Get current state
|
||||
current_state = entry.model.model_dump(mode="json")
|
||||
|
||||
# Apply updates
|
||||
new_state = {**current_state, **updates}
|
||||
|
||||
# Update the model
|
||||
_registry._update_model(entry.model, new_state)
|
||||
|
||||
# Trigger sync
|
||||
await _registry.push_all()
|
||||
|
||||
return {
|
||||
"status": "success",
|
||||
"store": store_name,
|
||||
"updated_fields": list(updates.keys())
|
||||
}
|
||||
|
||||
except Exception as e:
|
||||
raise ValueError(f"Failed to update store '{store_name}': {str(e)}")
|
||||
|
||||
|
||||
@tool
|
||||
def get_store_schema(store_name: str) -> Dict[str, Any]:
|
||||
"""Get the schema/structure of a synchronization store.
|
||||
|
||||
This shows what fields are available and their types.
|
||||
|
||||
Args:
|
||||
store_name: Name of the store
|
||||
|
||||
Returns:
|
||||
Dictionary describing the store's schema
|
||||
|
||||
Raises:
|
||||
ValueError: If store_name doesn't exist
|
||||
"""
|
||||
if not _registry:
|
||||
raise ValueError("SyncRegistry not initialized")
|
||||
|
||||
entry = _registry.entries.get(store_name)
|
||||
if not entry:
|
||||
available = list(_registry.entries.keys())
|
||||
raise ValueError(f"Store '{store_name}' not found. Available stores: {available}")
|
||||
|
||||
# Get model schema
|
||||
schema = entry.model.model_json_schema()
|
||||
|
||||
return {
|
||||
"store_name": store_name,
|
||||
"schema": schema
|
||||
}
|
||||
|
||||
|
||||
# DataSource tools
|
||||
|
||||
@tool
|
||||
def list_data_sources() -> List[str]:
|
||||
"""List all available data sources.
|
||||
|
||||
Returns:
|
||||
List of data source names that can be queried for market data
|
||||
"""
|
||||
if not _datasource_registry:
|
||||
return []
|
||||
return _datasource_registry.list_sources()
|
||||
|
||||
|
||||
@tool
|
||||
async def search_symbols(
|
||||
query: str,
|
||||
type: Optional[str] = None,
|
||||
exchange: Optional[str] = None,
|
||||
limit: int = 30,
|
||||
) -> Dict[str, Any]:
|
||||
"""Search for trading symbols across all data sources.
|
||||
|
||||
Automatically searches all available data sources and returns aggregated results.
|
||||
Use this to find symbols before calling get_symbol_info or get_historical_data.
|
||||
|
||||
Args:
|
||||
query: Search query (e.g., "BTC", "AAPL", "EUR")
|
||||
type: Optional filter by instrument type (e.g., "crypto", "stock", "forex")
|
||||
exchange: Optional filter by exchange (e.g., "binance", "nasdaq")
|
||||
limit: Maximum number of results per source (default: 30)
|
||||
|
||||
Returns:
|
||||
Dictionary mapping source names to lists of matching symbols.
|
||||
Each symbol includes: symbol, full_name, description, exchange, type.
|
||||
Use the source name and symbol from results with get_symbol_info or get_historical_data.
|
||||
|
||||
Example response:
|
||||
{
|
||||
"demo": [
|
||||
{
|
||||
"symbol": "BTC/USDT",
|
||||
"full_name": "Bitcoin / Tether USD",
|
||||
"description": "Bitcoin perpetual futures",
|
||||
"exchange": "demo",
|
||||
"type": "crypto"
|
||||
}
|
||||
]
|
||||
}
|
||||
"""
|
||||
if not _datasource_registry:
|
||||
raise ValueError("DataSourceRegistry not initialized")
|
||||
|
||||
# Always search all sources
|
||||
results = await _datasource_registry.search_all(query, type, exchange, limit)
|
||||
return {name: [r.model_dump() for r in matches] for name, matches in results.items()}
|
||||
|
||||
|
||||
@tool
|
||||
async def get_symbol_info(source_name: str, symbol: str) -> Dict[str, Any]:
|
||||
"""Get complete metadata for a trading symbol.
|
||||
|
||||
This retrieves full information about a symbol including:
|
||||
- Description and type
|
||||
- Supported time resolutions
|
||||
- Available data columns (OHLCV, volume, funding rates, etc.)
|
||||
- Trading session information
|
||||
- Price scale and precision
|
||||
|
||||
Args:
|
||||
source_name: Name of the data source (use list_data_sources to see available)
|
||||
symbol: Symbol identifier (e.g., "BTC/USDT", "AAPL", "EUR/USD")
|
||||
|
||||
Returns:
|
||||
Dictionary containing complete symbol metadata including column schema
|
||||
|
||||
Raises:
|
||||
ValueError: If source_name or symbol is not found
|
||||
"""
|
||||
if not _datasource_registry:
|
||||
raise ValueError("DataSourceRegistry not initialized")
|
||||
|
||||
symbol_info = await _datasource_registry.resolve_symbol(source_name, symbol)
|
||||
return symbol_info.model_dump()
|
||||
|
||||
|
||||
@tool
|
||||
async def get_historical_data(
|
||||
source_name: str,
|
||||
symbol: str,
|
||||
resolution: str,
|
||||
from_time: int,
|
||||
to_time: int,
|
||||
countback: Optional[int] = None,
|
||||
) -> Dict[str, Any]:
|
||||
"""Get historical bar/candle data for a symbol.
|
||||
|
||||
Retrieves time-series data between the specified timestamps. The data
|
||||
includes all columns defined for the symbol (OHLCV + any custom columns).
|
||||
|
||||
Args:
|
||||
source_name: Name of the data source
|
||||
symbol: Symbol identifier
|
||||
resolution: Time resolution (e.g., "1" = 1min, "5" = 5min, "60" = 1hour, "1D" = 1day)
|
||||
from_time: Start time as Unix timestamp in seconds
|
||||
to_time: End time as Unix timestamp in seconds
|
||||
countback: Optional limit on number of bars to return
|
||||
|
||||
Returns:
|
||||
Dictionary containing:
|
||||
- symbol: The requested symbol
|
||||
- resolution: The time resolution
|
||||
- bars: List of bar data with 'time' and 'data' fields
|
||||
- columns: Schema describing available data columns
|
||||
- nextTime: If present, indicates more data is available for pagination
|
||||
|
||||
Raises:
|
||||
ValueError: If source, symbol, or resolution is invalid
|
||||
|
||||
Example:
|
||||
# Get 1-hour BTC data for the last 24 hours
|
||||
import time
|
||||
to_time = int(time.time())
|
||||
from_time = to_time - 86400 # 24 hours ago
|
||||
data = get_historical_data("demo", "BTC/USDT", "60", from_time, to_time)
|
||||
"""
|
||||
if not _datasource_registry:
|
||||
raise ValueError("DataSourceRegistry not initialized")
|
||||
|
||||
source = _datasource_registry.get(source_name)
|
||||
if not source:
|
||||
available = _datasource_registry.list_sources()
|
||||
raise ValueError(f"Data source '{source_name}' not found. Available sources: {available}")
|
||||
|
||||
result = await source.get_bars(symbol, resolution, from_time, to_time, countback)
|
||||
return result.model_dump()
|
||||
|
||||
|
||||
async def _get_chart_data_impl(countback: Optional[int] = None):
|
||||
"""Internal implementation for getting chart data.
|
||||
|
||||
This is a helper function that can be called by both get_chart_data tool
|
||||
and analyze_chart_data tool.
|
||||
|
||||
Returns:
|
||||
Tuple of (HistoryResult, chart_context dict, source_name)
|
||||
"""
|
||||
if not _registry:
|
||||
raise ValueError("SyncRegistry not initialized - cannot read ChartStore")
|
||||
|
||||
if not _datasource_registry:
|
||||
raise ValueError("DataSourceRegistry not initialized - cannot query data")
|
||||
|
||||
# Read current chart state
|
||||
chart_store = _registry.entries.get("ChartStore")
|
||||
if not chart_store:
|
||||
raise ValueError("ChartStore not found in registry")
|
||||
|
||||
chart_state = chart_store.model.model_dump(mode="json")
|
||||
chart_data = chart_state.get("chart_state", {})
|
||||
|
||||
symbol = chart_data.get("symbol", "")
|
||||
interval = chart_data.get("interval", "15")
|
||||
start_time = chart_data.get("start_time")
|
||||
end_time = chart_data.get("end_time")
|
||||
|
||||
if not symbol:
|
||||
raise ValueError("No symbol set in ChartStore - user may not have loaded a chart yet")
|
||||
|
||||
# Parse the symbol to extract exchange/source and symbol name
|
||||
# Format is "EXCHANGE:SYMBOL" (e.g., "BINANCE:BTC/USDT", "DEMO:BTC/USD")
|
||||
if ":" not in symbol:
|
||||
raise ValueError(
|
||||
f"Invalid symbol format: '{symbol}'. Expected format is 'EXCHANGE:SYMBOL' "
|
||||
f"(e.g., 'BINANCE:BTC/USDT' or 'DEMO:BTC/USD')"
|
||||
)
|
||||
|
||||
exchange_prefix, symbol_name = symbol.split(":", 1)
|
||||
source_name = exchange_prefix.lower()
|
||||
|
||||
# Get the data source
|
||||
source = _datasource_registry.get(source_name)
|
||||
if not source:
|
||||
available = _datasource_registry.list_sources()
|
||||
raise ValueError(
|
||||
f"Data source '{source_name}' not found. Available sources: {available}. "
|
||||
f"Make sure the exchange in the symbol '{symbol}' matches an available source."
|
||||
)
|
||||
|
||||
# Determine time range - REQUIRE it to be set, no defaults
|
||||
if start_time is None or end_time is None:
|
||||
raise ValueError(
|
||||
f"Chart time range not set in ChartStore. start_time={start_time}, end_time={end_time}. "
|
||||
f"The user needs to load the chart first, or the frontend may not be sending the visible range. "
|
||||
f"Wait for the chart to fully load before analyzing data."
|
||||
)
|
||||
|
||||
from_time = int(start_time)
|
||||
end_time = int(end_time)
|
||||
logger.info(
|
||||
f"Using ChartStore time range: from_time={from_time}, end_time={end_time}, "
|
||||
f"countback={countback}"
|
||||
)
|
||||
|
||||
logger.info(
|
||||
f"Querying data source '{source_name}' for symbol '{symbol_name}', "
|
||||
f"resolution '{interval}'"
|
||||
)
|
||||
|
||||
# Query the data source
|
||||
result = await source.get_bars(
|
||||
symbol=symbol_name,
|
||||
resolution=interval,
|
||||
from_time=from_time,
|
||||
to_time=end_time,
|
||||
countback=countback
|
||||
)
|
||||
|
||||
logger.info(
|
||||
f"Received {len(result.bars)} bars from data source. "
|
||||
f"First bar time: {result.bars[0].time if result.bars else 'N/A'}, "
|
||||
f"Last bar time: {result.bars[-1].time if result.bars else 'N/A'}"
|
||||
)
|
||||
|
||||
# Build chart context to return along with result
|
||||
chart_context = {
|
||||
"symbol": symbol,
|
||||
"interval": interval,
|
||||
"start_time": start_time,
|
||||
"end_time": end_time
|
||||
}
|
||||
|
||||
return result, chart_context, source_name
|
||||
|
||||
|
||||
@tool
|
||||
async def get_chart_data(countback: Optional[int] = None) -> Dict[str, Any]:
|
||||
"""Get the candle/bar data for what the user is currently viewing on their chart.
|
||||
|
||||
This is a convenience tool that automatically:
|
||||
1. Reads the ChartStore to see what chart the user is viewing
|
||||
2. Parses the symbol to determine the data source (exchange prefix)
|
||||
3. Queries the appropriate data source for that symbol's data
|
||||
4. Returns the data for the visible time range and interval
|
||||
|
||||
This is the preferred way to access chart data when helping the user analyze
|
||||
what they're looking at, since it automatically uses their current chart context.
|
||||
|
||||
Args:
|
||||
countback: Optional limit on number of bars to return. If not specified,
|
||||
returns all bars in the visible time range.
|
||||
|
||||
Returns:
|
||||
Dictionary containing:
|
||||
- chart_context: Current chart state (symbol, interval, time range)
|
||||
- symbol: The trading pair being viewed
|
||||
- resolution: The chart interval
|
||||
- bars: List of bar data with 'time' and 'data' fields
|
||||
- columns: Schema describing available data columns
|
||||
- source: Which data source was used
|
||||
|
||||
Raises:
|
||||
ValueError: If ChartStore or DataSourceRegistry is not initialized,
|
||||
or if the symbol format is invalid
|
||||
|
||||
Example:
|
||||
# User is viewing BINANCE:BTC/USDT on 15min chart
|
||||
data = get_chart_data()
|
||||
# Returns BTC/USDT data from binance source at 15min resolution
|
||||
# for the currently visible time range
|
||||
"""
|
||||
result, chart_context, source_name = await _get_chart_data_impl(countback)
|
||||
|
||||
# Return enriched result with chart context
|
||||
response = result.model_dump()
|
||||
response["chart_context"] = chart_context
|
||||
response["source"] = source_name
|
||||
|
||||
return response
|
||||
|
||||
|
||||
@tool
|
||||
async def analyze_chart_data(python_script: str, countback: Optional[int] = None) -> Dict[str, Any]:
|
||||
"""Analyze the current chart data using a Python script with pandas and matplotlib.
|
||||
|
||||
This tool:
|
||||
1. Gets the current chart data (same as get_chart_data)
|
||||
2. Converts it to a pandas DataFrame with columns: time, open, high, low, close, volume
|
||||
3. Executes your Python script with access to the DataFrame as 'df'
|
||||
4. Saves any matplotlib plots to disk and returns URLs to access them
|
||||
5. Returns any final DataFrame result and plot URLs
|
||||
|
||||
The script has access to:
|
||||
- `df`: pandas DataFrame with OHLCV data indexed by datetime
|
||||
- `pandas` (as `pd`): For data manipulation
|
||||
- `numpy` (as `np`): For numerical operations
|
||||
- `matplotlib.pyplot` (as `plt`): For plotting (use plt.figure() for each plot)
|
||||
|
||||
All matplotlib figures are automatically saved to disk and accessible via URLs.
|
||||
The last expression in the script (if it's a DataFrame) is returned as the result.
|
||||
|
||||
Args:
|
||||
python_script: Python code to execute. The DataFrame is available as 'df'.
|
||||
Can use pandas, numpy, matplotlib. Return a DataFrame to include it in results.
|
||||
countback: Optional limit on number of bars to analyze
|
||||
|
||||
Returns:
|
||||
Dictionary containing:
|
||||
- chart_context: Current chart state (symbol, interval, time range)
|
||||
- source: Data source used
|
||||
- script_output: Any printed output from the script
|
||||
- result_dataframe: If script returns a DataFrame, it's included here as dict
|
||||
- plot_urls: List of URLs to saved plot images (one per plt.figure())
|
||||
- error: Error message if script execution failed
|
||||
|
||||
Example scripts:
|
||||
# Calculate 20-period SMA and plot
|
||||
```python
|
||||
df['SMA20'] = df['close'].rolling(20).mean()
|
||||
plt.figure(figsize=(12, 6))
|
||||
plt.plot(df.index, df['close'], label='Close')
|
||||
plt.plot(df.index, df['SMA20'], label='SMA20')
|
||||
plt.legend()
|
||||
plt.title('Price with SMA')
|
||||
df[['close', 'SMA20']].tail(10) # Return last 10 rows
|
||||
```
|
||||
|
||||
# Calculate RSI
|
||||
```python
|
||||
delta = df['close'].diff()
|
||||
gain = (delta.where(delta > 0, 0)).rolling(14).mean()
|
||||
loss = (-delta.where(delta < 0, 0)).rolling(14).mean()
|
||||
rs = gain / loss
|
||||
df['RSI'] = 100 - (100 / (1 + rs))
|
||||
df[['close', 'RSI']].tail(20)
|
||||
```
|
||||
|
||||
# Multiple plots
|
||||
```python
|
||||
# Price chart
|
||||
plt.figure(figsize=(12, 4))
|
||||
plt.plot(df['close'])
|
||||
plt.title('Price')
|
||||
|
||||
# Volume chart
|
||||
plt.figure(figsize=(12, 3))
|
||||
plt.bar(df.index, df['volume'])
|
||||
plt.title('Volume')
|
||||
|
||||
df.describe() # Return statistics
|
||||
```
|
||||
"""
|
||||
if not _registry:
|
||||
raise ValueError("SyncRegistry not initialized - cannot read ChartStore")
|
||||
|
||||
if not _datasource_registry:
|
||||
raise ValueError("DataSourceRegistry not initialized - cannot query data")
|
||||
|
||||
try:
|
||||
# Import pandas and numpy here to allow lazy loading
|
||||
import pandas as pd
|
||||
import numpy as np
|
||||
import matplotlib
|
||||
matplotlib.use('Agg') # Non-interactive backend
|
||||
import matplotlib.pyplot as plt
|
||||
except ImportError as e:
|
||||
raise ValueError(
|
||||
f"Required library not installed: {e}. "
|
||||
"Please install pandas, numpy, and matplotlib: pip install pandas numpy matplotlib"
|
||||
)
|
||||
|
||||
# Get chart data using the internal helper function
|
||||
result, chart_context, source_name = await _get_chart_data_impl(countback)
|
||||
|
||||
# Build the same response format as get_chart_data
|
||||
chart_data = result.model_dump()
|
||||
chart_data["chart_context"] = chart_context
|
||||
chart_data["source"] = source_name
|
||||
|
||||
# Convert bars to DataFrame
|
||||
bars = chart_data.get('bars', [])
|
||||
if not bars:
|
||||
return {
|
||||
"chart_context": chart_data.get('chart_context', {}),
|
||||
"source": chart_data.get('source', ''),
|
||||
"error": "No data available for the current chart"
|
||||
}
|
||||
|
||||
# Build DataFrame
|
||||
rows = []
|
||||
for bar in bars:
|
||||
row = {
|
||||
'time': pd.to_datetime(bar['time'], unit='s'),
|
||||
**bar['data'] # Includes open, high, low, close, volume, etc.
|
||||
}
|
||||
rows.append(row)
|
||||
|
||||
df = pd.DataFrame(rows)
|
||||
df.set_index('time', inplace=True)
|
||||
|
||||
# Convert price columns to float for clean numeric operations
|
||||
price_columns = ['open', 'high', 'low', 'close', 'volume']
|
||||
for col in price_columns:
|
||||
if col in df.columns:
|
||||
df[col] = pd.to_numeric(df[col], errors='coerce')
|
||||
|
||||
logger.info(
|
||||
f"Created DataFrame with {len(df)} rows, columns: {df.columns.tolist()}, "
|
||||
f"time range: {df.index.min()} to {df.index.max()}, "
|
||||
f"dtypes: {df.dtypes.to_dict()}"
|
||||
)
|
||||
|
||||
# Prepare execution environment
|
||||
script_globals = {
|
||||
'df': df,
|
||||
'pd': pd,
|
||||
'np': np,
|
||||
'plt': plt,
|
||||
}
|
||||
|
||||
# Capture stdout/stderr
|
||||
stdout_capture = io.StringIO()
|
||||
stderr_capture = io.StringIO()
|
||||
|
||||
result_df = None
|
||||
error_msg = None
|
||||
plot_urls = []
|
||||
|
||||
# Determine uploads directory (relative to this file)
|
||||
uploads_dir = Path(__file__).parent.parent.parent / "uploads"
|
||||
uploads_dir.mkdir(exist_ok=True)
|
||||
|
||||
try:
|
||||
with redirect_stdout(stdout_capture), redirect_stderr(stderr_capture):
|
||||
# Execute the script
|
||||
exec(python_script, script_globals)
|
||||
|
||||
# Check if the last line is an expression that returns a DataFrame
|
||||
# We'll try to evaluate it separately
|
||||
script_lines = python_script.strip().split('\n')
|
||||
if script_lines:
|
||||
last_line = script_lines[-1].strip()
|
||||
# Only evaluate if it doesn't look like a statement
|
||||
if last_line and not any(last_line.startswith(kw) for kw in ['if', 'for', 'while', 'def', 'class', 'import', 'from', 'with', 'try', 'return']):
|
||||
try:
|
||||
last_result = eval(last_line, script_globals)
|
||||
if isinstance(last_result, pd.DataFrame):
|
||||
result_df = last_result
|
||||
except:
|
||||
# If eval fails, that's okay - might not be an expression
|
||||
pass
|
||||
|
||||
# Save all matplotlib figures to disk
|
||||
for fig_num in plt.get_fignums():
|
||||
fig = plt.figure(fig_num)
|
||||
|
||||
# Generate unique filename
|
||||
plot_id = str(uuid.uuid4())
|
||||
filename = f"plot_{plot_id}.png"
|
||||
filepath = uploads_dir / filename
|
||||
|
||||
# Save figure to file
|
||||
fig.savefig(filepath, format='png', bbox_inches='tight', dpi=100)
|
||||
|
||||
# Generate URL that can be accessed via the web server
|
||||
plot_url = f"/uploads/{filename}"
|
||||
plot_urls.append(plot_url)
|
||||
|
||||
plt.close(fig)
|
||||
|
||||
except Exception as e:
|
||||
error_msg = f"{type(e).__name__}: {str(e)}"
|
||||
import traceback
|
||||
error_msg += f"\n{traceback.format_exc()}"
|
||||
|
||||
# Build response
|
||||
response = {
|
||||
"chart_context": chart_data.get('chart_context', {}),
|
||||
"source": chart_data.get('source', ''),
|
||||
"script_output": stdout_capture.getvalue(),
|
||||
}
|
||||
|
||||
if error_msg:
|
||||
response["error"] = error_msg
|
||||
response["stderr"] = stderr_capture.getvalue()
|
||||
|
||||
if result_df is not None:
|
||||
# Convert DataFrame to dict for JSON serialization
|
||||
response["result_dataframe"] = {
|
||||
"columns": result_df.columns.tolist(),
|
||||
"index": result_df.index.astype(str).tolist() if hasattr(result_df.index, 'astype') else result_df.index.tolist(),
|
||||
"data": result_df.values.tolist(),
|
||||
"shape": result_df.shape,
|
||||
}
|
||||
|
||||
if plot_urls:
|
||||
response["plot_urls"] = plot_urls
|
||||
|
||||
return response
|
||||
|
||||
|
||||
# Export all tools
|
||||
SYNC_TOOLS = [
|
||||
list_sync_stores,
|
||||
read_sync_state,
|
||||
write_sync_state,
|
||||
get_store_schema
|
||||
]
|
||||
|
||||
DATASOURCE_TOOLS = [
|
||||
list_data_sources,
|
||||
search_symbols,
|
||||
get_symbol_info,
|
||||
get_historical_data,
|
||||
get_chart_data,
|
||||
analyze_chart_data
|
||||
]
|
||||
23
backend/src/datasource/__init__.py
Normal file
23
backend/src/datasource/__init__.py
Normal file
@@ -0,0 +1,23 @@
|
||||
from .base import DataSource
|
||||
from .schema import (
|
||||
ColumnInfo,
|
||||
SymbolInfo,
|
||||
Bar,
|
||||
HistoryResult,
|
||||
DatafeedConfig,
|
||||
Resolution,
|
||||
SearchResult,
|
||||
)
|
||||
from .registry import DataSourceRegistry
|
||||
|
||||
__all__ = [
|
||||
"DataSource",
|
||||
"ColumnInfo",
|
||||
"SymbolInfo",
|
||||
"Bar",
|
||||
"HistoryResult",
|
||||
"DatafeedConfig",
|
||||
"Resolution",
|
||||
"SearchResult",
|
||||
"DataSourceRegistry",
|
||||
]
|
||||
3
backend/src/datasource/adapters/__init__.py
Normal file
3
backend/src/datasource/adapters/__init__.py
Normal file
@@ -0,0 +1,3 @@
|
||||
from .ccxt_adapter import CCXTDataSource
|
||||
|
||||
__all__ = ["CCXTDataSource"]
|
||||
526
backend/src/datasource/adapters/ccxt_adapter.py
Normal file
526
backend/src/datasource/adapters/ccxt_adapter.py
Normal file
@@ -0,0 +1,526 @@
|
||||
"""
|
||||
CCXT DataSource adapter for accessing cryptocurrency exchange data.
|
||||
|
||||
This adapter provides access to hundreds of cryptocurrency exchanges through
|
||||
the free CCXT library (not ccxt.pro), supporting both historical data and
|
||||
polling-based subscriptions.
|
||||
|
||||
Numerical Precision:
|
||||
- Uses Decimal for all monetary values (prices, volumes) to avoid floating-point errors
|
||||
- CCXT returns numeric values as strings or floats depending on configuration
|
||||
- All financial values are converted to Decimal to maintain precision
|
||||
|
||||
Real-time Updates:
|
||||
- Uses polling instead of WebSocket (free CCXT doesn't have WebSocket support)
|
||||
- Default polling interval: 60 seconds (configurable)
|
||||
- Simulates real-time subscriptions by periodically fetching latest bars
|
||||
"""
|
||||
|
||||
import asyncio
|
||||
import logging
|
||||
import time
|
||||
from datetime import datetime, timezone
|
||||
from decimal import Decimal
|
||||
from typing import Callable, Dict, List, Optional, Set, Union
|
||||
|
||||
import ccxt.async_support as ccxt
|
||||
|
||||
from ..base import DataSource
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
from ..schema import (
|
||||
Bar,
|
||||
ColumnInfo,
|
||||
DatafeedConfig,
|
||||
HistoryResult,
|
||||
Resolution,
|
||||
SearchResult,
|
||||
SymbolInfo,
|
||||
)
|
||||
|
||||
|
||||
class CCXTDataSource(DataSource):
|
||||
"""
|
||||
DataSource adapter for CCXT cryptocurrency exchanges (free version).
|
||||
|
||||
Provides access to:
|
||||
- Multiple cryptocurrency exchanges (Binance, Coinbase, Kraken, etc.)
|
||||
- Historical OHLCV data via REST API
|
||||
- Polling-based real-time updates (configurable interval)
|
||||
- Symbol search and metadata
|
||||
|
||||
Args:
|
||||
exchange_id: CCXT exchange identifier (e.g., 'binance', 'coinbase', 'kraken')
|
||||
config: Optional exchange-specific configuration (API keys, options)
|
||||
sandbox: Whether to use sandbox/testnet mode (default: False)
|
||||
poll_interval: Interval in seconds for polling updates (default: 60)
|
||||
"""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
exchange_id: str = "binance",
|
||||
config: Optional[Dict] = None,
|
||||
sandbox: bool = False,
|
||||
poll_interval: int = 60,
|
||||
):
|
||||
self.exchange_id = exchange_id
|
||||
self._config = config or {}
|
||||
self._sandbox = sandbox
|
||||
self._poll_interval = poll_interval
|
||||
|
||||
# Initialize exchange (using free async_support, not pro)
|
||||
exchange_class = getattr(ccxt, exchange_id)
|
||||
self.exchange = exchange_class(self._config)
|
||||
|
||||
if sandbox and hasattr(self.exchange, 'set_sandbox_mode'):
|
||||
self.exchange.set_sandbox_mode(True)
|
||||
|
||||
# Cache for markets
|
||||
self._markets: Optional[Dict] = None
|
||||
self._markets_loaded = False
|
||||
|
||||
# Active subscriptions (polling-based)
|
||||
self._subscriptions: Dict[str, asyncio.Task] = {}
|
||||
self._subscription_callbacks: Dict[str, Callable] = {}
|
||||
self._last_bars: Dict[str, int] = {} # Track last bar timestamp per subscription
|
||||
|
||||
@staticmethod
|
||||
def _to_decimal(value: Union[str, int, float, Decimal, None]) -> Optional[Decimal]:
|
||||
"""
|
||||
Convert a value to Decimal for numerical precision.
|
||||
|
||||
Handles CCXT's mixed output (strings, floats, ints, None).
|
||||
Converts floats by converting to string first to avoid precision loss.
|
||||
"""
|
||||
if value is None:
|
||||
return None
|
||||
if isinstance(value, Decimal):
|
||||
return value
|
||||
if isinstance(value, str):
|
||||
return Decimal(value)
|
||||
if isinstance(value, (int, float)):
|
||||
# Convert to string first to avoid float precision issues
|
||||
return Decimal(str(value))
|
||||
return None
|
||||
|
||||
async def _ensure_markets_loaded(self):
|
||||
"""Ensure markets are loaded from exchange"""
|
||||
if not self._markets_loaded:
|
||||
self._markets = await self.exchange.load_markets()
|
||||
self._markets_loaded = True
|
||||
|
||||
async def get_config(self) -> DatafeedConfig:
|
||||
"""Get datafeed configuration"""
|
||||
await self._ensure_markets_loaded()
|
||||
|
||||
# Determine supported resolutions based on exchange capabilities
|
||||
supported_resolutions = [
|
||||
Resolution.M1,
|
||||
Resolution.M5,
|
||||
Resolution.M15,
|
||||
Resolution.M30,
|
||||
Resolution.H1,
|
||||
Resolution.H4,
|
||||
Resolution.D1,
|
||||
]
|
||||
|
||||
# Get unique exchange names (most CCXT exchanges are just one)
|
||||
exchanges = [self.exchange_id.upper()]
|
||||
|
||||
return DatafeedConfig(
|
||||
name=f"CCXT {self.exchange_id.title()}",
|
||||
description=f"Live and historical cryptocurrency data from {self.exchange_id} via CCXT library. "
|
||||
f"Supports OHLCV data for {len(self._markets) if self._markets else 'many'} trading pairs.",
|
||||
supported_resolutions=supported_resolutions,
|
||||
supports_search=True,
|
||||
supports_time=True,
|
||||
exchanges=exchanges,
|
||||
symbols_types=["crypto", "spot", "futures", "swap"],
|
||||
)
|
||||
|
||||
async def search_symbols(
|
||||
self,
|
||||
query: str,
|
||||
type: Optional[str] = None,
|
||||
exchange: Optional[str] = None,
|
||||
limit: int = 30,
|
||||
) -> List[SearchResult]:
|
||||
"""Search for symbols on the exchange"""
|
||||
await self._ensure_markets_loaded()
|
||||
|
||||
query_upper = query.upper()
|
||||
results = []
|
||||
|
||||
for symbol, market in self._markets.items():
|
||||
# Match query against symbol or base/quote currencies
|
||||
if (query_upper in symbol or
|
||||
query_upper in market.get('base', '') or
|
||||
query_upper in market.get('quote', '')):
|
||||
|
||||
# Filter by type if specified
|
||||
market_type = market.get('type', 'spot')
|
||||
if type and market_type != type:
|
||||
continue
|
||||
|
||||
# Create search result
|
||||
base = market.get('base', '')
|
||||
quote = market.get('quote', '')
|
||||
|
||||
results.append(
|
||||
SearchResult(
|
||||
symbol=f"{base}/{quote}", # Clean user-facing format
|
||||
ticker=f"{self.exchange_id.upper()}:{symbol}", # Ticker with exchange prefix for routing
|
||||
full_name=f"{base}/{quote} ({self.exchange_id.upper()})",
|
||||
description=f"{base}/{quote} {market_type} trading pair on {self.exchange_id}",
|
||||
exchange=self.exchange_id.upper(),
|
||||
type=market_type,
|
||||
)
|
||||
)
|
||||
|
||||
if len(results) >= limit:
|
||||
break
|
||||
|
||||
return results
|
||||
|
||||
async def resolve_symbol(self, symbol: str) -> SymbolInfo:
|
||||
"""Get complete metadata for a symbol"""
|
||||
await self._ensure_markets_loaded()
|
||||
|
||||
if symbol not in self._markets:
|
||||
raise ValueError(f"Symbol '{symbol}' not found on {self.exchange_id}")
|
||||
|
||||
market = self._markets[symbol]
|
||||
base = market.get('base', '')
|
||||
quote = market.get('quote', '')
|
||||
market_type = market.get('type', 'spot')
|
||||
|
||||
# Determine price scale from market precision
|
||||
# CCXT precision can be in different modes:
|
||||
# - DECIMAL_PLACES (int): number of decimal places (e.g., 2 = 0.01)
|
||||
# - TICK_SIZE (float): actual tick size (e.g., 0.01, 0.00001)
|
||||
# We need to convert to pricescale (10^n where n is decimal places)
|
||||
price_precision = market.get('precision', {}).get('price', 2)
|
||||
|
||||
if isinstance(price_precision, float):
|
||||
# TICK_SIZE mode: precision is the actual tick size (e.g., 0.01, 0.00001)
|
||||
# Convert tick size to decimal places
|
||||
# For 0.01 -> 2 decimal places, 0.00001 -> 5 decimal places
|
||||
tick_str = str(Decimal(str(price_precision)))
|
||||
if '.' in tick_str:
|
||||
decimal_places = len(tick_str.split('.')[1].rstrip('0'))
|
||||
else:
|
||||
decimal_places = 0
|
||||
pricescale = 10 ** decimal_places
|
||||
else:
|
||||
# DECIMAL_PLACES or SIGNIFICANT_DIGITS mode: precision is an integer
|
||||
# Assume DECIMAL_PLACES mode (most common for price)
|
||||
pricescale = 10 ** int(price_precision)
|
||||
|
||||
return SymbolInfo(
|
||||
symbol=f"{base}/{quote}", # Clean user-facing format
|
||||
ticker=f"{self.exchange_id.upper()}:{symbol}", # Ticker with exchange prefix for routing
|
||||
name=f"{base}/{quote}",
|
||||
description=f"{base}/{quote} {market_type} pair on {self.exchange_id}. "
|
||||
f"Minimum order: {market.get('limits', {}).get('amount', {}).get('min', 'N/A')} {base}",
|
||||
type=market_type,
|
||||
exchange=self.exchange_id.upper(),
|
||||
timezone="Etc/UTC",
|
||||
session="24x7",
|
||||
supported_resolutions=[
|
||||
Resolution.M1,
|
||||
Resolution.M5,
|
||||
Resolution.M15,
|
||||
Resolution.M30,
|
||||
Resolution.H1,
|
||||
Resolution.H4,
|
||||
Resolution.D1,
|
||||
],
|
||||
has_intraday=True,
|
||||
has_daily=True,
|
||||
has_weekly_and_monthly=False,
|
||||
columns=[
|
||||
ColumnInfo(
|
||||
name="open",
|
||||
type="decimal",
|
||||
description=f"Opening price in {quote}",
|
||||
unit=quote,
|
||||
),
|
||||
ColumnInfo(
|
||||
name="high",
|
||||
type="decimal",
|
||||
description=f"Highest price in {quote}",
|
||||
unit=quote,
|
||||
),
|
||||
ColumnInfo(
|
||||
name="low",
|
||||
type="decimal",
|
||||
description=f"Lowest price in {quote}",
|
||||
unit=quote,
|
||||
),
|
||||
ColumnInfo(
|
||||
name="close",
|
||||
type="decimal",
|
||||
description=f"Closing price in {quote}",
|
||||
unit=quote,
|
||||
),
|
||||
ColumnInfo(
|
||||
name="volume",
|
||||
type="decimal",
|
||||
description=f"Trading volume in {base}",
|
||||
unit=base,
|
||||
),
|
||||
],
|
||||
time_column="time",
|
||||
has_ohlcv=True,
|
||||
pricescale=pricescale,
|
||||
minmov=1,
|
||||
base_currency=base,
|
||||
quote_currency=quote,
|
||||
)
|
||||
|
||||
def _resolution_to_timeframe(self, resolution: str) -> str:
|
||||
"""Convert our resolution format to CCXT timeframe format"""
|
||||
# Map our resolutions to CCXT timeframes
|
||||
mapping = {
|
||||
"1": "1m",
|
||||
"5": "5m",
|
||||
"15": "15m",
|
||||
"30": "30m",
|
||||
"60": "1h",
|
||||
"120": "2h",
|
||||
"240": "4h",
|
||||
"360": "6h",
|
||||
"720": "12h",
|
||||
"1D": "1d",
|
||||
"1W": "1w",
|
||||
"1M": "1M",
|
||||
}
|
||||
return mapping.get(resolution, "1m")
|
||||
|
||||
def _timeframe_to_milliseconds(self, timeframe: str) -> int:
|
||||
"""Convert CCXT timeframe to milliseconds"""
|
||||
unit = timeframe[-1]
|
||||
amount = int(timeframe[:-1]) if len(timeframe) > 1 else 1
|
||||
|
||||
units = {
|
||||
's': 1000,
|
||||
'm': 60 * 1000,
|
||||
'h': 60 * 60 * 1000,
|
||||
'd': 24 * 60 * 60 * 1000,
|
||||
'w': 7 * 24 * 60 * 60 * 1000,
|
||||
'M': 30 * 24 * 60 * 60 * 1000, # Approximate
|
||||
}
|
||||
|
||||
return amount * units.get(unit, 60000)
|
||||
|
||||
async def get_bars(
|
||||
self,
|
||||
symbol: str,
|
||||
resolution: str,
|
||||
from_time: int,
|
||||
to_time: int,
|
||||
countback: Optional[int] = None,
|
||||
) -> HistoryResult:
|
||||
"""Get historical bars from the exchange"""
|
||||
logger.info(
|
||||
f"CCXTDataSource({self.exchange_id}).get_bars: symbol={symbol}, resolution={resolution}, "
|
||||
f"from_time={from_time}, to_time={to_time}, countback={countback}"
|
||||
)
|
||||
|
||||
await self._ensure_markets_loaded()
|
||||
|
||||
if symbol not in self._markets:
|
||||
raise ValueError(f"Symbol '{symbol}' not found on {self.exchange_id}")
|
||||
|
||||
timeframe = self._resolution_to_timeframe(resolution)
|
||||
|
||||
# CCXT uses milliseconds for timestamps
|
||||
since = from_time * 1000
|
||||
until = to_time * 1000
|
||||
|
||||
# Fetch OHLCV data
|
||||
limit = countback if countback else 1000
|
||||
|
||||
try:
|
||||
# Fetch in batches if needed
|
||||
all_ohlcv = []
|
||||
current_since = since
|
||||
|
||||
while current_since < until:
|
||||
ohlcv = await self.exchange.fetch_ohlcv(
|
||||
symbol,
|
||||
timeframe=timeframe,
|
||||
since=current_since,
|
||||
limit=limit,
|
||||
)
|
||||
|
||||
if not ohlcv:
|
||||
break
|
||||
|
||||
all_ohlcv.extend(ohlcv)
|
||||
|
||||
# Update since for next batch
|
||||
last_timestamp = ohlcv[-1][0]
|
||||
if last_timestamp <= current_since:
|
||||
break # No progress, avoid infinite loop
|
||||
current_since = last_timestamp + 1
|
||||
|
||||
# Stop if we have enough bars
|
||||
if countback and len(all_ohlcv) >= countback:
|
||||
all_ohlcv = all_ohlcv[:countback]
|
||||
break
|
||||
|
||||
# Convert to our Bar format with Decimal precision
|
||||
bars = []
|
||||
for candle in all_ohlcv:
|
||||
timestamp_ms, open_price, high, low, close, volume = candle
|
||||
timestamp = timestamp_ms // 1000 # Convert to seconds
|
||||
|
||||
# Only include bars within requested range
|
||||
if timestamp < from_time or timestamp >= to_time:
|
||||
continue
|
||||
|
||||
bars.append(
|
||||
Bar(
|
||||
time=timestamp,
|
||||
data={
|
||||
"open": self._to_decimal(open_price),
|
||||
"high": self._to_decimal(high),
|
||||
"low": self._to_decimal(low),
|
||||
"close": self._to_decimal(close),
|
||||
"volume": self._to_decimal(volume),
|
||||
},
|
||||
)
|
||||
)
|
||||
|
||||
# Get symbol info for column metadata
|
||||
symbol_info = await self.resolve_symbol(symbol)
|
||||
|
||||
logger.info(
|
||||
f"CCXTDataSource({self.exchange_id}).get_bars: Returning {len(bars)} bars. "
|
||||
f"First: {bars[0].time if bars else 'N/A'}, Last: {bars[-1].time if bars else 'N/A'}"
|
||||
)
|
||||
|
||||
# Determine if more data is available
|
||||
next_time = None
|
||||
if bars and countback and len(bars) >= countback:
|
||||
next_time = bars[-1].time + (bars[-1].time - bars[-2].time if len(bars) > 1 else 60)
|
||||
|
||||
return HistoryResult(
|
||||
symbol=symbol,
|
||||
resolution=resolution,
|
||||
bars=bars,
|
||||
columns=symbol_info.columns,
|
||||
nextTime=next_time,
|
||||
)
|
||||
|
||||
except Exception as e:
|
||||
raise ValueError(f"Failed to fetch bars for {symbol}: {str(e)}")
|
||||
|
||||
async def subscribe_bars(
|
||||
self,
|
||||
symbol: str,
|
||||
resolution: str,
|
||||
on_tick: Callable[[dict], None],
|
||||
) -> str:
|
||||
"""
|
||||
Subscribe to bar updates via polling.
|
||||
|
||||
Note: Uses polling instead of WebSocket since we're using free CCXT.
|
||||
Polls at the configured interval (default: 60 seconds).
|
||||
"""
|
||||
await self._ensure_markets_loaded()
|
||||
|
||||
if symbol not in self._markets:
|
||||
raise ValueError(f"Symbol '{symbol}' not found on {self.exchange_id}")
|
||||
|
||||
subscription_id = f"{symbol}:{resolution}:{time.time()}"
|
||||
|
||||
# Store callback
|
||||
self._subscription_callbacks[subscription_id] = on_tick
|
||||
|
||||
# Start polling task
|
||||
timeframe = self._resolution_to_timeframe(resolution)
|
||||
task = asyncio.create_task(
|
||||
self._poll_ohlcv(symbol, timeframe, subscription_id)
|
||||
)
|
||||
self._subscriptions[subscription_id] = task
|
||||
|
||||
return subscription_id
|
||||
|
||||
async def _poll_ohlcv(self, symbol: str, timeframe: str, subscription_id: str):
|
||||
"""
|
||||
Poll for OHLCV updates at regular intervals.
|
||||
|
||||
This simulates real-time updates by fetching the latest bars periodically.
|
||||
Only sends updates when new bars are detected.
|
||||
"""
|
||||
try:
|
||||
while subscription_id in self._subscription_callbacks:
|
||||
try:
|
||||
# Fetch latest bars
|
||||
ohlcv = await self.exchange.fetch_ohlcv(
|
||||
symbol,
|
||||
timeframe=timeframe,
|
||||
limit=2, # Get last 2 bars to detect new ones
|
||||
)
|
||||
|
||||
if ohlcv and len(ohlcv) > 0:
|
||||
# Get the latest candle
|
||||
latest = ohlcv[-1]
|
||||
timestamp_ms, open_price, high, low, close, volume = latest
|
||||
timestamp = timestamp_ms // 1000
|
||||
|
||||
# Only send update if this is a new bar
|
||||
last_timestamp = self._last_bars.get(subscription_id, 0)
|
||||
if timestamp > last_timestamp:
|
||||
self._last_bars[subscription_id] = timestamp
|
||||
|
||||
# Convert to our format with Decimal precision
|
||||
tick_data = {
|
||||
"time": timestamp,
|
||||
"open": self._to_decimal(open_price),
|
||||
"high": self._to_decimal(high),
|
||||
"low": self._to_decimal(low),
|
||||
"close": self._to_decimal(close),
|
||||
"volume": self._to_decimal(volume),
|
||||
}
|
||||
|
||||
# Call the callback
|
||||
callback = self._subscription_callbacks.get(subscription_id)
|
||||
if callback:
|
||||
callback(tick_data)
|
||||
|
||||
except Exception as e:
|
||||
print(f"Error polling OHLCV for {symbol}: {e}")
|
||||
|
||||
# Wait for next poll interval
|
||||
await asyncio.sleep(self._poll_interval)
|
||||
|
||||
except asyncio.CancelledError:
|
||||
pass
|
||||
|
||||
async def unsubscribe_bars(self, subscription_id: str) -> None:
|
||||
"""Unsubscribe from polling updates"""
|
||||
# Remove callback and tracking
|
||||
self._subscription_callbacks.pop(subscription_id, None)
|
||||
self._last_bars.pop(subscription_id, None)
|
||||
|
||||
# Cancel polling task
|
||||
task = self._subscriptions.pop(subscription_id, None)
|
||||
if task:
|
||||
task.cancel()
|
||||
try:
|
||||
await task
|
||||
except asyncio.CancelledError:
|
||||
pass
|
||||
|
||||
async def close(self):
|
||||
"""Close exchange connection and cleanup"""
|
||||
# Cancel all subscriptions
|
||||
for subscription_id in list(self._subscriptions.keys()):
|
||||
await self.unsubscribe_bars(subscription_id)
|
||||
|
||||
# Close exchange
|
||||
if hasattr(self.exchange, 'close'):
|
||||
await self.exchange.close()
|
||||
353
backend/src/datasource/adapters/demo.py
Normal file
353
backend/src/datasource/adapters/demo.py
Normal file
@@ -0,0 +1,353 @@
|
||||
"""
|
||||
Demo data source with synthetic data.
|
||||
|
||||
Generates realistic-looking OHLCV data plus additional columns for testing.
|
||||
"""
|
||||
|
||||
import asyncio
|
||||
import logging
|
||||
import math
|
||||
import random
|
||||
import time
|
||||
from typing import Callable, Dict, List, Optional
|
||||
|
||||
from ..base import DataSource
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
from ..schema import (
|
||||
Bar,
|
||||
ColumnInfo,
|
||||
DatafeedConfig,
|
||||
HistoryResult,
|
||||
Resolution,
|
||||
SearchResult,
|
||||
SymbolInfo,
|
||||
)
|
||||
|
||||
|
||||
class DemoDataSource(DataSource):
|
||||
"""
|
||||
Demo data source that generates synthetic time-series data.
|
||||
|
||||
Provides:
|
||||
- Standard OHLCV columns
|
||||
- Additional demo columns (RSI, sentiment, volume_profile)
|
||||
- Real-time updates via polling simulation
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
self._subscriptions: Dict[str, asyncio.Task] = {}
|
||||
self._symbols = {
|
||||
"DEMO:BTC/USD": {
|
||||
"name": "Bitcoin",
|
||||
"type": "crypto",
|
||||
"base_price": 50000.0,
|
||||
"volatility": 0.02,
|
||||
},
|
||||
"DEMO:ETH/USD": {
|
||||
"name": "Ethereum",
|
||||
"type": "crypto",
|
||||
"base_price": 3000.0,
|
||||
"volatility": 0.03,
|
||||
},
|
||||
"DEMO:SOL/USD": {
|
||||
"name": "Solana",
|
||||
"type": "crypto",
|
||||
"base_price": 100.0,
|
||||
"volatility": 0.04,
|
||||
},
|
||||
}
|
||||
|
||||
async def get_config(self) -> DatafeedConfig:
|
||||
return DatafeedConfig(
|
||||
name="Demo DataSource",
|
||||
description="Synthetic data generator for testing. Provides OHLCV plus additional indicator columns.",
|
||||
supported_resolutions=[
|
||||
Resolution.M1,
|
||||
Resolution.M5,
|
||||
Resolution.M15,
|
||||
Resolution.H1,
|
||||
Resolution.D1,
|
||||
],
|
||||
supports_search=True,
|
||||
supports_time=True,
|
||||
exchanges=["DEMO"],
|
||||
symbols_types=["crypto"],
|
||||
)
|
||||
|
||||
async def search_symbols(
|
||||
self,
|
||||
query: str,
|
||||
type: Optional[str] = None,
|
||||
exchange: Optional[str] = None,
|
||||
limit: int = 30,
|
||||
) -> List[SearchResult]:
|
||||
query_lower = query.lower()
|
||||
results = []
|
||||
|
||||
for symbol, info in self._symbols.items():
|
||||
if query_lower in symbol.lower() or query_lower in info["name"].lower():
|
||||
if type and info["type"] != type:
|
||||
continue
|
||||
results.append(
|
||||
SearchResult(
|
||||
symbol=info['name'], # Clean user-facing format (e.g., "Bitcoin")
|
||||
ticker=symbol, # Keep DEMO:BTC/USD format for routing
|
||||
full_name=f"{info['name']} (DEMO)",
|
||||
description=f"Demo {info['name']} pair",
|
||||
exchange="DEMO",
|
||||
type=info["type"],
|
||||
)
|
||||
)
|
||||
|
||||
return results[:limit]
|
||||
|
||||
async def resolve_symbol(self, symbol: str) -> SymbolInfo:
|
||||
if symbol not in self._symbols:
|
||||
raise ValueError(f"Symbol '{symbol}' not found")
|
||||
|
||||
info = self._symbols[symbol]
|
||||
base, quote = symbol.split(":")[1].split("/")
|
||||
|
||||
return SymbolInfo(
|
||||
symbol=info["name"], # Clean user-facing format (e.g., "Bitcoin")
|
||||
ticker=symbol, # Keep DEMO:BTC/USD format for routing
|
||||
name=info["name"],
|
||||
description=f"Demo {info['name']} spot price with synthetic indicators",
|
||||
type=info["type"],
|
||||
exchange="DEMO",
|
||||
timezone="Etc/UTC",
|
||||
session="24x7",
|
||||
supported_resolutions=[Resolution.M1, Resolution.M5, Resolution.M15, Resolution.H1, Resolution.D1],
|
||||
has_intraday=True,
|
||||
has_daily=True,
|
||||
has_weekly_and_monthly=False,
|
||||
columns=[
|
||||
ColumnInfo(
|
||||
name="open",
|
||||
type="float",
|
||||
description=f"Opening price in {quote}",
|
||||
unit=quote,
|
||||
),
|
||||
ColumnInfo(
|
||||
name="high",
|
||||
type="float",
|
||||
description=f"Highest price in {quote}",
|
||||
unit=quote,
|
||||
),
|
||||
ColumnInfo(
|
||||
name="low",
|
||||
type="float",
|
||||
description=f"Lowest price in {quote}",
|
||||
unit=quote,
|
||||
),
|
||||
ColumnInfo(
|
||||
name="close",
|
||||
type="float",
|
||||
description=f"Closing price in {quote}",
|
||||
unit=quote,
|
||||
),
|
||||
ColumnInfo(
|
||||
name="volume",
|
||||
type="float",
|
||||
description=f"Trading volume in {base}",
|
||||
unit=base,
|
||||
),
|
||||
ColumnInfo(
|
||||
name="rsi",
|
||||
type="float",
|
||||
description="Relative Strength Index (14-period), range 0-100",
|
||||
unit=None,
|
||||
),
|
||||
ColumnInfo(
|
||||
name="sentiment",
|
||||
type="float",
|
||||
description="Synthetic social sentiment score, range -1.0 to 1.0",
|
||||
unit=None,
|
||||
),
|
||||
ColumnInfo(
|
||||
name="volume_profile",
|
||||
type="float",
|
||||
description="Volume as percentage of 24h average",
|
||||
unit="%",
|
||||
),
|
||||
],
|
||||
time_column="time",
|
||||
has_ohlcv=True,
|
||||
pricescale=100,
|
||||
minmov=1,
|
||||
base_currency=base,
|
||||
quote_currency=quote,
|
||||
)
|
||||
|
||||
async def get_bars(
|
||||
self,
|
||||
symbol: str,
|
||||
resolution: str,
|
||||
from_time: int,
|
||||
to_time: int,
|
||||
countback: Optional[int] = None,
|
||||
) -> HistoryResult:
|
||||
if symbol not in self._symbols:
|
||||
raise ValueError(f"Symbol '{symbol}' not found")
|
||||
|
||||
logger.info(
|
||||
f"DemoDataSource.get_bars: symbol={symbol}, resolution={resolution}, "
|
||||
f"from_time={from_time}, to_time={to_time}, countback={countback}"
|
||||
)
|
||||
|
||||
info = self._symbols[symbol]
|
||||
symbol_meta = await self.resolve_symbol(symbol)
|
||||
|
||||
# Convert resolution to seconds
|
||||
resolution_seconds = self._resolution_to_seconds(resolution)
|
||||
|
||||
# Generate bars
|
||||
bars = []
|
||||
# Align current_time to resolution, but ensure it's >= from_time
|
||||
current_time = from_time - (from_time % resolution_seconds)
|
||||
if current_time < from_time:
|
||||
current_time += resolution_seconds
|
||||
|
||||
price = info["base_price"]
|
||||
|
||||
bar_count = 0
|
||||
max_bars = countback if countback else 5000
|
||||
|
||||
while current_time <= to_time and bar_count < max_bars:
|
||||
bar_data = self._generate_bar(current_time, price, info["volatility"], resolution_seconds)
|
||||
|
||||
# Only include bars within the requested range
|
||||
if from_time <= current_time <= to_time:
|
||||
bars.append(Bar(time=current_time * 1000, data=bar_data)) # Convert to milliseconds
|
||||
bar_count += 1
|
||||
|
||||
price = bar_data["close"] # Next bar starts from previous close
|
||||
current_time += resolution_seconds
|
||||
|
||||
logger.info(
|
||||
f"DemoDataSource.get_bars: Generated {len(bars)} bars. "
|
||||
f"First: {bars[0].time if bars else 'N/A'}, Last: {bars[-1].time if bars else 'N/A'}"
|
||||
)
|
||||
|
||||
# Determine if there's more data (for pagination)
|
||||
next_time = current_time if current_time <= to_time else None
|
||||
|
||||
return HistoryResult(
|
||||
symbol=symbol,
|
||||
resolution=resolution,
|
||||
bars=bars,
|
||||
columns=symbol_meta.columns,
|
||||
nextTime=next_time,
|
||||
)
|
||||
|
||||
async def subscribe_bars(
|
||||
self,
|
||||
symbol: str,
|
||||
resolution: str,
|
||||
on_tick: Callable[[dict], None],
|
||||
) -> str:
|
||||
if symbol not in self._symbols:
|
||||
raise ValueError(f"Symbol '{symbol}' not found")
|
||||
|
||||
subscription_id = f"{symbol}:{resolution}:{time.time()}"
|
||||
|
||||
# Start background task to simulate real-time updates
|
||||
task = asyncio.create_task(
|
||||
self._tick_generator(symbol, resolution, on_tick, subscription_id)
|
||||
)
|
||||
self._subscriptions[subscription_id] = task
|
||||
|
||||
return subscription_id
|
||||
|
||||
async def unsubscribe_bars(self, subscription_id: str) -> None:
|
||||
task = self._subscriptions.pop(subscription_id, None)
|
||||
if task:
|
||||
task.cancel()
|
||||
try:
|
||||
await task
|
||||
except asyncio.CancelledError:
|
||||
pass
|
||||
|
||||
def _resolution_to_seconds(self, resolution: str) -> int:
|
||||
"""Convert resolution string to seconds"""
|
||||
if resolution.endswith("D"):
|
||||
return int(resolution[:-1]) * 86400
|
||||
elif resolution.endswith("W"):
|
||||
return int(resolution[:-1]) * 604800
|
||||
elif resolution.endswith("M"):
|
||||
return int(resolution[:-1]) * 2592000 # Approximate month
|
||||
else:
|
||||
# Assume minutes
|
||||
return int(resolution) * 60
|
||||
|
||||
def _generate_bar(self, timestamp: int, base_price: float, volatility: float, period_seconds: int) -> dict:
|
||||
"""Generate a single synthetic OHLCV bar"""
|
||||
# Random walk for the period
|
||||
open_price = base_price
|
||||
|
||||
# Generate intra-period price movement
|
||||
num_ticks = max(10, period_seconds // 60) # More ticks for longer periods
|
||||
prices = [open_price]
|
||||
|
||||
for _ in range(num_ticks):
|
||||
change = random.gauss(0, volatility / math.sqrt(num_ticks))
|
||||
prices.append(prices[-1] * (1 + change))
|
||||
|
||||
close_price = prices[-1]
|
||||
high_price = max(prices)
|
||||
low_price = min(prices)
|
||||
|
||||
# Volume with some randomness
|
||||
base_volume = 1000000 * (period_seconds / 60) # Scale with period
|
||||
volume = base_volume * random.uniform(0.5, 2.0)
|
||||
|
||||
# Additional synthetic indicators
|
||||
rsi = 30 + random.random() * 40 # Biased toward middle range
|
||||
sentiment = math.sin(timestamp / 3600) * 0.5 + random.gauss(0, 0.2) # Hourly cycle + noise
|
||||
sentiment = max(-1.0, min(1.0, sentiment))
|
||||
volume_profile = 100 * random.uniform(0.5, 1.5)
|
||||
|
||||
return {
|
||||
"open": round(open_price, 2),
|
||||
"high": round(high_price, 2),
|
||||
"low": round(low_price, 2),
|
||||
"close": round(close_price, 2),
|
||||
"volume": round(volume, 2),
|
||||
"rsi": round(rsi, 2),
|
||||
"sentiment": round(sentiment, 3),
|
||||
"volume_profile": round(volume_profile, 2),
|
||||
}
|
||||
|
||||
async def _tick_generator(
|
||||
self,
|
||||
symbol: str,
|
||||
resolution: str,
|
||||
on_tick: Callable[[dict], None],
|
||||
subscription_id: str,
|
||||
):
|
||||
"""Background task that generates periodic ticks"""
|
||||
info = self._symbols[symbol]
|
||||
resolution_seconds = self._resolution_to_seconds(resolution)
|
||||
|
||||
# Start from current aligned time
|
||||
current_time = int(time.time())
|
||||
current_time = current_time - (current_time % resolution_seconds)
|
||||
price = info["base_price"]
|
||||
|
||||
try:
|
||||
while True:
|
||||
# Wait until next bar
|
||||
await asyncio.sleep(resolution_seconds)
|
||||
|
||||
current_time += resolution_seconds
|
||||
bar_data = self._generate_bar(current_time, price, info["volatility"], resolution_seconds)
|
||||
price = bar_data["close"]
|
||||
|
||||
# Call the tick handler
|
||||
tick_data = {"time": current_time, **bar_data}
|
||||
on_tick(tick_data)
|
||||
|
||||
except asyncio.CancelledError:
|
||||
# Subscription cancelled
|
||||
pass
|
||||
146
backend/src/datasource/base.py
Normal file
146
backend/src/datasource/base.py
Normal file
@@ -0,0 +1,146 @@
|
||||
"""
|
||||
Abstract DataSource interface.
|
||||
|
||||
Inspired by TradingView's Datafeed API with extensions for flexible column schemas
|
||||
and AI-native metadata.
|
||||
"""
|
||||
|
||||
from abc import ABC, abstractmethod
|
||||
from typing import Callable, List, Optional
|
||||
|
||||
from .schema import DatafeedConfig, HistoryResult, SearchResult, SymbolInfo
|
||||
|
||||
|
||||
class DataSource(ABC):
|
||||
"""
|
||||
Abstract base class for time-series data sources.
|
||||
|
||||
Provides a standardized interface for:
|
||||
- Symbol search and metadata retrieval
|
||||
- Historical data queries (time-based, paginated)
|
||||
- Real-time data subscriptions
|
||||
|
||||
All data rows must have a timestamp. Additional columns are flexible
|
||||
and described via ColumnInfo metadata.
|
||||
"""
|
||||
|
||||
@abstractmethod
|
||||
async def get_config(self) -> DatafeedConfig:
|
||||
"""
|
||||
Get datafeed configuration and capabilities.
|
||||
|
||||
Called once during initialization to understand what this data source
|
||||
supports (resolutions, exchanges, search, etc.).
|
||||
|
||||
Returns:
|
||||
DatafeedConfig describing this datafeed's capabilities
|
||||
"""
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
async def search_symbols(
|
||||
self,
|
||||
query: str,
|
||||
type: Optional[str] = None,
|
||||
exchange: Optional[str] = None,
|
||||
limit: int = 30,
|
||||
) -> List[SearchResult]:
|
||||
"""
|
||||
Search for symbols matching a text query.
|
||||
|
||||
Args:
|
||||
query: Free-text search string
|
||||
type: Optional filter by instrument type
|
||||
exchange: Optional filter by exchange
|
||||
limit: Maximum number of results
|
||||
|
||||
Returns:
|
||||
List of matching symbols with basic metadata
|
||||
"""
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
async def resolve_symbol(self, symbol: str) -> SymbolInfo:
|
||||
"""
|
||||
Get complete metadata for a symbol.
|
||||
|
||||
Called after a symbol is selected to retrieve full information including
|
||||
supported resolutions, column schema, trading session, etc.
|
||||
|
||||
Args:
|
||||
symbol: Symbol identifier
|
||||
|
||||
Returns:
|
||||
Complete SymbolInfo including column definitions
|
||||
|
||||
Raises:
|
||||
ValueError: If symbol is not found
|
||||
"""
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
async def get_bars(
|
||||
self,
|
||||
symbol: str,
|
||||
resolution: str,
|
||||
from_time: int,
|
||||
to_time: int,
|
||||
countback: Optional[int] = None,
|
||||
) -> HistoryResult:
|
||||
"""
|
||||
Get historical bars for a symbol and resolution.
|
||||
|
||||
Time range is specified in Unix timestamps (seconds). If more data is
|
||||
available beyond the requested range, the result should include a
|
||||
nextTime value for pagination.
|
||||
|
||||
Args:
|
||||
symbol: Symbol identifier
|
||||
resolution: Time resolution (e.g., "1", "5", "60", "1D")
|
||||
from_time: Start time (Unix timestamp in seconds)
|
||||
to_time: End time (Unix timestamp in seconds)
|
||||
countback: Optional limit on number of bars to return
|
||||
|
||||
Returns:
|
||||
HistoryResult with bars, column schema, and pagination info
|
||||
|
||||
Raises:
|
||||
ValueError: If symbol or resolution is not supported
|
||||
"""
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
async def subscribe_bars(
|
||||
self,
|
||||
symbol: str,
|
||||
resolution: str,
|
||||
on_tick: Callable[[dict], None],
|
||||
) -> str:
|
||||
"""
|
||||
Subscribe to real-time bar updates.
|
||||
|
||||
The callback will be invoked with new bar data as it becomes available.
|
||||
The data dict will match the column schema from resolve_symbol().
|
||||
|
||||
Args:
|
||||
symbol: Symbol identifier
|
||||
resolution: Time resolution
|
||||
on_tick: Callback function receiving bar data dict
|
||||
|
||||
Returns:
|
||||
Subscription ID for later unsubscribe
|
||||
|
||||
Raises:
|
||||
ValueError: If symbol or resolution is not supported
|
||||
"""
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
async def unsubscribe_bars(self, subscription_id: str) -> None:
|
||||
"""
|
||||
Unsubscribe from real-time updates.
|
||||
|
||||
Args:
|
||||
subscription_id: ID returned from subscribe_bars()
|
||||
"""
|
||||
pass
|
||||
109
backend/src/datasource/registry.py
Normal file
109
backend/src/datasource/registry.py
Normal file
@@ -0,0 +1,109 @@
|
||||
"""
|
||||
DataSource registry for managing multiple data sources.
|
||||
"""
|
||||
|
||||
from typing import Dict, List, Optional
|
||||
|
||||
from .base import DataSource
|
||||
from .schema import SearchResult, SymbolInfo
|
||||
|
||||
|
||||
class DataSourceRegistry:
|
||||
"""
|
||||
Central registry for managing multiple DataSource instances.
|
||||
|
||||
Allows routing symbol queries to the appropriate data source and
|
||||
aggregating search results across multiple sources.
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
self._sources: Dict[str, DataSource] = {}
|
||||
|
||||
def register(self, name: str, source: DataSource) -> None:
|
||||
"""
|
||||
Register a data source.
|
||||
|
||||
Args:
|
||||
name: Unique name for this data source
|
||||
source: DataSource implementation
|
||||
"""
|
||||
self._sources[name] = source
|
||||
|
||||
def unregister(self, name: str) -> None:
|
||||
"""
|
||||
Unregister a data source.
|
||||
|
||||
Args:
|
||||
name: Name of the data source to remove
|
||||
"""
|
||||
self._sources.pop(name, None)
|
||||
|
||||
def get(self, name: str) -> Optional[DataSource]:
|
||||
"""
|
||||
Get a registered data source by name.
|
||||
|
||||
Args:
|
||||
name: Data source name
|
||||
|
||||
Returns:
|
||||
DataSource instance or None if not found
|
||||
"""
|
||||
return self._sources.get(name)
|
||||
|
||||
def list_sources(self) -> List[str]:
|
||||
"""
|
||||
Get names of all registered data sources.
|
||||
|
||||
Returns:
|
||||
List of data source names
|
||||
"""
|
||||
return list(self._sources.keys())
|
||||
|
||||
async def search_all(
|
||||
self,
|
||||
query: str,
|
||||
type: Optional[str] = None,
|
||||
exchange: Optional[str] = None,
|
||||
limit: int = 30,
|
||||
) -> Dict[str, List[SearchResult]]:
|
||||
"""
|
||||
Search across all registered data sources.
|
||||
|
||||
Args:
|
||||
query: Search query
|
||||
type: Optional instrument type filter
|
||||
exchange: Optional exchange filter
|
||||
limit: Maximum results per source
|
||||
|
||||
Returns:
|
||||
Dict mapping source name to search results
|
||||
"""
|
||||
results = {}
|
||||
for name, source in self._sources.items():
|
||||
try:
|
||||
source_results = await source.search_symbols(query, type, exchange, limit)
|
||||
if source_results:
|
||||
results[name] = source_results
|
||||
except Exception:
|
||||
# Silently skip sources that error during search
|
||||
continue
|
||||
return results
|
||||
|
||||
async def resolve_symbol(self, source_name: str, symbol: str) -> SymbolInfo:
|
||||
"""
|
||||
Resolve a symbol from a specific data source.
|
||||
|
||||
Args:
|
||||
source_name: Name of the data source
|
||||
symbol: Symbol identifier
|
||||
|
||||
Returns:
|
||||
SymbolInfo from the specified source
|
||||
|
||||
Raises:
|
||||
ValueError: If source not found or symbol not found
|
||||
"""
|
||||
source = self.get(source_name)
|
||||
if not source:
|
||||
raise ValueError(f"Data source '{source_name}' not found")
|
||||
return await source.resolve_symbol(symbol)
|
||||
194
backend/src/datasource/schema.py
Normal file
194
backend/src/datasource/schema.py
Normal file
@@ -0,0 +1,194 @@
|
||||
"""
|
||||
Data models for the DataSource interface.
|
||||
|
||||
Inspired by TradingView's Datafeed API but with flexible column schemas
|
||||
for AI-native trading platform needs.
|
||||
"""
|
||||
|
||||
from enum import StrEnum
|
||||
from typing import Any, Dict, List, Literal, Optional
|
||||
|
||||
from pydantic import BaseModel, Field
|
||||
|
||||
|
||||
class Resolution(StrEnum):
|
||||
"""Standard time resolutions for bar data"""
|
||||
|
||||
# Seconds
|
||||
S1 = "1S"
|
||||
S5 = "5S"
|
||||
S15 = "15S"
|
||||
S30 = "30S"
|
||||
|
||||
# Minutes
|
||||
M1 = "1"
|
||||
M5 = "5"
|
||||
M15 = "15"
|
||||
M30 = "30"
|
||||
|
||||
# Hours
|
||||
H1 = "60"
|
||||
H2 = "120"
|
||||
H4 = "240"
|
||||
H6 = "360"
|
||||
H12 = "720"
|
||||
|
||||
# Days
|
||||
D1 = "1D"
|
||||
|
||||
# Weeks
|
||||
W1 = "1W"
|
||||
|
||||
# Months
|
||||
MO1 = "1M"
|
||||
|
||||
|
||||
class ColumnInfo(BaseModel):
|
||||
"""
|
||||
Metadata for a single data column.
|
||||
|
||||
Provides rich, LLM-readable descriptions so AI agents can understand
|
||||
and reason about available data fields.
|
||||
"""
|
||||
|
||||
model_config = {"extra": "forbid"}
|
||||
|
||||
name: str = Field(description="Column name (e.g., 'close', 'volume', 'funding_rate')")
|
||||
type: Literal["float", "int", "bool", "string", "decimal"] = Field(description="Data type")
|
||||
description: str = Field(description="Human and LLM-readable description of what this column represents")
|
||||
unit: Optional[str] = Field(default=None, description="Unit of measurement (e.g., 'USD', 'BTC', '%', 'contracts')")
|
||||
nullable: bool = Field(default=False, description="Whether this column can contain null values")
|
||||
|
||||
|
||||
class SymbolInfo(BaseModel):
|
||||
"""
|
||||
Complete metadata for a tradeable symbol.
|
||||
|
||||
Includes both TradingView-compatible fields and flexible schema definition
|
||||
for arbitrary data columns.
|
||||
"""
|
||||
|
||||
model_config = {"extra": "forbid"}
|
||||
|
||||
# Core identification
|
||||
symbol: str = Field(description="Unique symbol identifier (primary key for data fetching)")
|
||||
ticker: Optional[str] = Field(default=None, description="TradingView ticker (if different from symbol)")
|
||||
name: str = Field(description="Display name")
|
||||
description: str = Field(description="LLM-readable description of the instrument")
|
||||
type: str = Field(description="Instrument type: 'crypto', 'stock', 'forex', 'futures', 'derived', etc.")
|
||||
exchange: str = Field(description="Exchange or data source identifier")
|
||||
|
||||
# Trading session info
|
||||
timezone: str = Field(default="Etc/UTC", description="IANA timezone identifier")
|
||||
session: str = Field(default="24x7", description="Trading session spec (e.g., '0930-1600' or '24x7')")
|
||||
|
||||
# Resolution support
|
||||
supported_resolutions: List[str] = Field(description="List of supported time resolutions")
|
||||
has_intraday: bool = Field(default=True, description="Whether intraday resolutions are supported")
|
||||
has_daily: bool = Field(default=True, description="Whether daily resolution is supported")
|
||||
has_weekly_and_monthly: bool = Field(default=False, description="Whether weekly/monthly resolutions are supported")
|
||||
|
||||
# Flexible schema definition
|
||||
columns: List[ColumnInfo] = Field(description="Available data columns for this symbol")
|
||||
time_column: str = Field(default="time", description="Name of the timestamp column")
|
||||
|
||||
# Convenience flags
|
||||
has_ohlcv: bool = Field(default=False, description="Whether standard OHLCV columns are present")
|
||||
|
||||
# Price display (for OHLCV data)
|
||||
pricescale: int = Field(default=100, description="Price scale factor (e.g., 100 for 2 decimals)")
|
||||
minmov: int = Field(default=1, description="Minimum price movement in pricescale units")
|
||||
|
||||
# Additional metadata
|
||||
base_currency: Optional[str] = Field(default=None, description="Base currency (for crypto/forex)")
|
||||
quote_currency: Optional[str] = Field(default=None, description="Quote currency (for crypto/forex)")
|
||||
|
||||
|
||||
class Bar(BaseModel):
|
||||
"""
|
||||
A single bar/row of time-series data with flexible columns.
|
||||
|
||||
All bars must have a timestamp. Additional columns are stored in the
|
||||
data dict and described by the associated ColumnInfo metadata.
|
||||
"""
|
||||
|
||||
model_config = {"extra": "forbid"}
|
||||
|
||||
time: int = Field(description="Unix timestamp in seconds")
|
||||
data: Dict[str, Any] = Field(description="Column name -> value mapping")
|
||||
|
||||
# Convenience accessors for common OHLCV columns
|
||||
@property
|
||||
def open(self) -> Optional[float]:
|
||||
return self.data.get("open")
|
||||
|
||||
@property
|
||||
def high(self) -> Optional[float]:
|
||||
return self.data.get("high")
|
||||
|
||||
@property
|
||||
def low(self) -> Optional[float]:
|
||||
return self.data.get("low")
|
||||
|
||||
@property
|
||||
def close(self) -> Optional[float]:
|
||||
return self.data.get("close")
|
||||
|
||||
@property
|
||||
def volume(self) -> Optional[float]:
|
||||
return self.data.get("volume")
|
||||
|
||||
|
||||
class HistoryResult(BaseModel):
|
||||
"""
|
||||
Result from a historical data query.
|
||||
|
||||
Includes the bars, schema information, and pagination metadata.
|
||||
"""
|
||||
|
||||
model_config = {"extra": "forbid"}
|
||||
|
||||
symbol: str = Field(description="Symbol identifier")
|
||||
resolution: str = Field(description="Time resolution of the bars")
|
||||
bars: List[Bar] = Field(description="The actual data bars")
|
||||
columns: List[ColumnInfo] = Field(description="Schema describing the bar data columns")
|
||||
nextTime: Optional[int] = Field(default=None, description="Unix timestamp for pagination (if more data available)")
|
||||
|
||||
|
||||
class SearchResult(BaseModel):
|
||||
"""
|
||||
A single result from symbol search.
|
||||
"""
|
||||
|
||||
model_config = {"extra": "forbid"}
|
||||
|
||||
symbol: str = Field(description="Display symbol (e.g., 'BINANCE:ETH/BTC')")
|
||||
ticker: Optional[str] = Field(default=None, description="Backend ticker for data fetching (e.g., 'ETH/BTC')")
|
||||
full_name: str = Field(description="Full display name including exchange")
|
||||
description: str = Field(description="Human-readable description")
|
||||
exchange: str = Field(description="Exchange identifier")
|
||||
type: str = Field(description="Instrument type")
|
||||
|
||||
|
||||
class DatafeedConfig(BaseModel):
|
||||
"""
|
||||
Configuration and capabilities of a DataSource.
|
||||
|
||||
Similar to TradingView's onReady configuration object.
|
||||
"""
|
||||
|
||||
model_config = {"extra": "forbid"}
|
||||
|
||||
# Supported features
|
||||
supported_resolutions: List[str] = Field(description="All resolutions this datafeed supports")
|
||||
supports_search: bool = Field(default=True, description="Whether symbol search is available")
|
||||
supports_time: bool = Field(default=True, description="Whether time-based queries are supported")
|
||||
supports_marks: bool = Field(default=False, description="Whether marks/events are supported")
|
||||
|
||||
# Data characteristics
|
||||
exchanges: List[str] = Field(default_factory=list, description="Available exchanges")
|
||||
symbols_types: List[str] = Field(default_factory=list, description="Available instrument types")
|
||||
|
||||
# Metadata
|
||||
name: str = Field(description="Datafeed name")
|
||||
description: str = Field(description="LLM-readable description of this data source")
|
||||
235
backend/src/datasource/subscription_manager.py
Normal file
235
backend/src/datasource/subscription_manager.py
Normal file
@@ -0,0 +1,235 @@
|
||||
"""
|
||||
Subscription manager for real-time data feeds.
|
||||
|
||||
Manages subscriptions across multiple data sources and routes updates
|
||||
to WebSocket clients.
|
||||
"""
|
||||
|
||||
import asyncio
|
||||
import logging
|
||||
from typing import Callable, Dict, Optional, Set
|
||||
|
||||
from .base import DataSource
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class Subscription:
|
||||
"""Represents a single client subscription"""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
subscription_id: str,
|
||||
client_id: str,
|
||||
source_name: str,
|
||||
symbol: str,
|
||||
resolution: str,
|
||||
callback: Callable[[dict], None],
|
||||
):
|
||||
self.subscription_id = subscription_id
|
||||
self.client_id = client_id
|
||||
self.source_name = source_name
|
||||
self.symbol = symbol
|
||||
self.resolution = resolution
|
||||
self.callback = callback
|
||||
self.source_subscription_id: Optional[str] = None
|
||||
|
||||
|
||||
class SubscriptionManager:
|
||||
"""
|
||||
Manages real-time data subscriptions across multiple data sources.
|
||||
|
||||
Handles:
|
||||
- Subscription lifecycle (subscribe/unsubscribe)
|
||||
- Routing updates from data sources to clients
|
||||
- Multiplexing (multiple clients can subscribe to same symbol/resolution)
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
# Map subscription_id -> Subscription
|
||||
self._subscriptions: Dict[str, Subscription] = {}
|
||||
|
||||
# Map (source_name, symbol, resolution) -> Set[subscription_id]
|
||||
# For tracking which client subscriptions use which source subscriptions
|
||||
self._source_refs: Dict[tuple, Set[str]] = {}
|
||||
|
||||
# Map source_subscription_id -> (source_name, symbol, resolution)
|
||||
self._source_subs: Dict[str, tuple] = {}
|
||||
|
||||
# Available data sources
|
||||
self._sources: Dict[str, DataSource] = {}
|
||||
|
||||
def register_source(self, name: str, source: DataSource) -> None:
|
||||
"""Register a data source"""
|
||||
self._sources[name] = source
|
||||
|
||||
def unregister_source(self, name: str) -> None:
|
||||
"""Unregister a data source"""
|
||||
self._sources.pop(name, None)
|
||||
|
||||
async def subscribe(
|
||||
self,
|
||||
subscription_id: str,
|
||||
client_id: str,
|
||||
source_name: str,
|
||||
symbol: str,
|
||||
resolution: str,
|
||||
callback: Callable[[dict], None],
|
||||
) -> None:
|
||||
"""
|
||||
Subscribe a client to real-time updates.
|
||||
|
||||
Args:
|
||||
subscription_id: Unique ID for this subscription
|
||||
client_id: ID of the subscribing client
|
||||
source_name: Name of the data source
|
||||
symbol: Symbol to subscribe to
|
||||
resolution: Time resolution
|
||||
callback: Function to call with bar updates
|
||||
|
||||
Raises:
|
||||
ValueError: If source not found or subscription fails
|
||||
"""
|
||||
source = self._sources.get(source_name)
|
||||
if not source:
|
||||
raise ValueError(f"Data source '{source_name}' not found")
|
||||
|
||||
# Create subscription record
|
||||
subscription = Subscription(
|
||||
subscription_id=subscription_id,
|
||||
client_id=client_id,
|
||||
source_name=source_name,
|
||||
symbol=symbol,
|
||||
resolution=resolution,
|
||||
callback=callback,
|
||||
)
|
||||
|
||||
# Check if we already have a source subscription for this (source, symbol, resolution)
|
||||
source_key = (source_name, symbol, resolution)
|
||||
if source_key not in self._source_refs:
|
||||
# Need to create a new source subscription
|
||||
try:
|
||||
source_sub_id = await source.subscribe_bars(
|
||||
symbol=symbol,
|
||||
resolution=resolution,
|
||||
on_tick=lambda bar: self._on_source_update(source_key, bar),
|
||||
)
|
||||
subscription.source_subscription_id = source_sub_id
|
||||
self._source_subs[source_sub_id] = source_key
|
||||
self._source_refs[source_key] = set()
|
||||
logger.info(
|
||||
f"Created new source subscription: {source_name}/{symbol}/{resolution} -> {source_sub_id}"
|
||||
)
|
||||
except Exception as e:
|
||||
logger.error(f"Failed to subscribe to source: {e}")
|
||||
raise
|
||||
|
||||
# Add this subscription to the reference set
|
||||
self._source_refs[source_key].add(subscription_id)
|
||||
self._subscriptions[subscription_id] = subscription
|
||||
|
||||
logger.info(
|
||||
f"Client subscription added: {subscription_id} ({client_id}) -> {source_name}/{symbol}/{resolution}"
|
||||
)
|
||||
|
||||
async def unsubscribe(self, subscription_id: str) -> None:
|
||||
"""
|
||||
Unsubscribe a client from updates.
|
||||
|
||||
Args:
|
||||
subscription_id: ID of the subscription to remove
|
||||
"""
|
||||
subscription = self._subscriptions.pop(subscription_id, None)
|
||||
if not subscription:
|
||||
logger.warning(f"Subscription {subscription_id} not found")
|
||||
return
|
||||
|
||||
source_key = (subscription.source_name, subscription.symbol, subscription.resolution)
|
||||
|
||||
# Remove from reference set
|
||||
if source_key in self._source_refs:
|
||||
self._source_refs[source_key].discard(subscription_id)
|
||||
|
||||
# If no more clients need this source subscription, unsubscribe from source
|
||||
if not self._source_refs[source_key]:
|
||||
del self._source_refs[source_key]
|
||||
|
||||
if subscription.source_subscription_id:
|
||||
source = self._sources.get(subscription.source_name)
|
||||
if source:
|
||||
try:
|
||||
await source.unsubscribe_bars(subscription.source_subscription_id)
|
||||
logger.info(
|
||||
f"Unsubscribed from source: {subscription.source_subscription_id}"
|
||||
)
|
||||
except Exception as e:
|
||||
logger.error(f"Error unsubscribing from source: {e}")
|
||||
|
||||
self._source_subs.pop(subscription.source_subscription_id, None)
|
||||
|
||||
logger.info(f"Client subscription removed: {subscription_id}")
|
||||
|
||||
async def unsubscribe_client(self, client_id: str) -> None:
|
||||
"""
|
||||
Unsubscribe all subscriptions for a client.
|
||||
|
||||
Useful when a WebSocket connection closes.
|
||||
|
||||
Args:
|
||||
client_id: ID of the client
|
||||
"""
|
||||
# Find all subscriptions for this client
|
||||
client_subs = [
|
||||
sub_id
|
||||
for sub_id, sub in self._subscriptions.items()
|
||||
if sub.client_id == client_id
|
||||
]
|
||||
|
||||
# Unsubscribe each one
|
||||
for sub_id in client_subs:
|
||||
await self.unsubscribe(sub_id)
|
||||
|
||||
logger.info(f"Unsubscribed all subscriptions for client {client_id}")
|
||||
|
||||
def _on_source_update(self, source_key: tuple, bar: dict) -> None:
|
||||
"""
|
||||
Handle an update from a data source.
|
||||
|
||||
Routes the update to all client subscriptions that need it.
|
||||
|
||||
Args:
|
||||
source_key: (source_name, symbol, resolution) tuple
|
||||
bar: Bar data dict from the source
|
||||
"""
|
||||
subscription_ids = self._source_refs.get(source_key, set())
|
||||
|
||||
for sub_id in subscription_ids:
|
||||
subscription = self._subscriptions.get(sub_id)
|
||||
if subscription:
|
||||
try:
|
||||
subscription.callback(bar)
|
||||
except Exception as e:
|
||||
logger.error(
|
||||
f"Error in subscription callback {sub_id}: {e}", exc_info=True
|
||||
)
|
||||
|
||||
def get_subscription_count(self) -> int:
|
||||
"""Get total number of active client subscriptions"""
|
||||
return len(self._subscriptions)
|
||||
|
||||
def get_source_subscription_count(self) -> int:
|
||||
"""Get total number of active source subscriptions"""
|
||||
return len(self._source_refs)
|
||||
|
||||
def get_client_subscriptions(self, client_id: str) -> list:
|
||||
"""Get all subscriptions for a specific client"""
|
||||
return [
|
||||
{
|
||||
"subscription_id": sub.subscription_id,
|
||||
"source": sub.source_name,
|
||||
"symbol": sub.symbol,
|
||||
"resolution": sub.resolution,
|
||||
}
|
||||
for sub in self._subscriptions.values()
|
||||
if sub.client_id == client_id
|
||||
]
|
||||
347
backend/src/datasource/websocket_handler.py
Normal file
347
backend/src/datasource/websocket_handler.py
Normal file
@@ -0,0 +1,347 @@
|
||||
"""
|
||||
WebSocket handler for TradingView-compatible datafeed API.
|
||||
|
||||
Handles incoming requests for symbol search, metadata, historical data,
|
||||
and real-time subscriptions.
|
||||
"""
|
||||
|
||||
import json
|
||||
import logging
|
||||
from typing import Dict, Optional
|
||||
|
||||
from fastapi import WebSocket
|
||||
|
||||
from .base import DataSource
|
||||
from .registry import DataSourceRegistry
|
||||
from .subscription_manager import SubscriptionManager
|
||||
from .websocket_protocol import (
|
||||
BarUpdateMessage,
|
||||
ErrorResponse,
|
||||
GetBarsRequest,
|
||||
GetBarsResponse,
|
||||
GetConfigRequest,
|
||||
GetConfigResponse,
|
||||
ResolveSymbolRequest,
|
||||
ResolveSymbolResponse,
|
||||
SearchSymbolsRequest,
|
||||
SearchSymbolsResponse,
|
||||
SubscribeBarsRequest,
|
||||
SubscribeBarsResponse,
|
||||
UnsubscribeBarsRequest,
|
||||
UnsubscribeBarsResponse,
|
||||
)
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class DatafeedWebSocketHandler:
|
||||
"""
|
||||
Handles WebSocket connections for TradingView-compatible datafeed API.
|
||||
|
||||
Each handler manages a single WebSocket connection and routes requests
|
||||
to the appropriate data sources via the registry.
|
||||
"""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
websocket: WebSocket,
|
||||
client_id: str,
|
||||
registry: DataSourceRegistry,
|
||||
subscription_manager: SubscriptionManager,
|
||||
default_source: Optional[str] = None,
|
||||
):
|
||||
"""
|
||||
Initialize handler.
|
||||
|
||||
Args:
|
||||
websocket: FastAPI WebSocket connection
|
||||
client_id: Unique identifier for this client
|
||||
registry: DataSource registry for accessing data sources
|
||||
subscription_manager: Shared subscription manager
|
||||
default_source: Default data source name if not specified in requests
|
||||
"""
|
||||
self.websocket = websocket
|
||||
self.client_id = client_id
|
||||
self.registry = registry
|
||||
self.subscription_manager = subscription_manager
|
||||
self.default_source = default_source
|
||||
self._connected = True
|
||||
|
||||
async def handle_connection(self) -> None:
|
||||
"""
|
||||
Main connection handler loop.
|
||||
|
||||
Processes incoming messages until the connection closes.
|
||||
"""
|
||||
try:
|
||||
await self.websocket.accept()
|
||||
logger.info(f"WebSocket connected: client_id={self.client_id}")
|
||||
|
||||
while self._connected:
|
||||
# Receive message
|
||||
try:
|
||||
data = await self.websocket.receive_text()
|
||||
message = json.loads(data)
|
||||
except Exception as e:
|
||||
logger.error(f"Error receiving/parsing message: {e}")
|
||||
break
|
||||
|
||||
# Route to appropriate handler
|
||||
await self._handle_message(message)
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"WebSocket error: {e}", exc_info=True)
|
||||
finally:
|
||||
# Clean up subscriptions when connection closes
|
||||
await self.subscription_manager.unsubscribe_client(self.client_id)
|
||||
self._connected = False
|
||||
logger.info(f"WebSocket disconnected: client_id={self.client_id}")
|
||||
|
||||
async def _handle_message(self, message: dict) -> None:
|
||||
"""Route message to appropriate handler based on type"""
|
||||
msg_type = message.get("type")
|
||||
request_id = message.get("request_id", "unknown")
|
||||
|
||||
try:
|
||||
if msg_type == "search_symbols":
|
||||
await self._handle_search_symbols(SearchSymbolsRequest(**message))
|
||||
elif msg_type == "resolve_symbol":
|
||||
await self._handle_resolve_symbol(ResolveSymbolRequest(**message))
|
||||
elif msg_type == "get_bars":
|
||||
await self._handle_get_bars(GetBarsRequest(**message))
|
||||
elif msg_type == "subscribe_bars":
|
||||
await self._handle_subscribe_bars(SubscribeBarsRequest(**message))
|
||||
elif msg_type == "unsubscribe_bars":
|
||||
await self._handle_unsubscribe_bars(UnsubscribeBarsRequest(**message))
|
||||
elif msg_type == "get_config":
|
||||
await self._handle_get_config(GetConfigRequest(**message))
|
||||
else:
|
||||
await self._send_error(
|
||||
request_id, "UNKNOWN_REQUEST_TYPE", f"Unknown request type: {msg_type}"
|
||||
)
|
||||
except Exception as e:
|
||||
logger.error(f"Error handling {msg_type}: {e}", exc_info=True)
|
||||
await self._send_error(request_id, "INTERNAL_ERROR", str(e))
|
||||
|
||||
async def _handle_search_symbols(self, request: SearchSymbolsRequest) -> None:
|
||||
"""Handle symbol search request"""
|
||||
# Use default source or search all sources
|
||||
if self.default_source:
|
||||
source = self.registry.get(self.default_source)
|
||||
if not source:
|
||||
await self._send_error(
|
||||
request.request_id,
|
||||
"SOURCE_NOT_FOUND",
|
||||
f"Default source '{self.default_source}' not found",
|
||||
)
|
||||
return
|
||||
|
||||
results = await source.search_symbols(
|
||||
query=request.query,
|
||||
type=request.symbol_type,
|
||||
exchange=request.exchange,
|
||||
limit=request.limit,
|
||||
)
|
||||
results_data = [r.model_dump(mode="json") for r in results]
|
||||
else:
|
||||
# Search all sources
|
||||
all_results = await self.registry.search_all(
|
||||
query=request.query,
|
||||
type=request.symbol_type,
|
||||
exchange=request.exchange,
|
||||
limit=request.limit,
|
||||
)
|
||||
# Flatten results from all sources
|
||||
results_data = []
|
||||
for source_results in all_results.values():
|
||||
results_data.extend([r.model_dump(mode="json") for r in source_results])
|
||||
|
||||
response = SearchSymbolsResponse(request_id=request.request_id, results=results_data)
|
||||
await self._send_response(response)
|
||||
|
||||
async def _handle_resolve_symbol(self, request: ResolveSymbolRequest) -> None:
|
||||
"""Handle symbol resolution request"""
|
||||
# Extract source from symbol if present (format: "SOURCE:SYMBOL")
|
||||
if ":" in request.symbol:
|
||||
source_name, symbol = request.symbol.split(":", 1)
|
||||
else:
|
||||
source_name = self.default_source
|
||||
symbol = request.symbol
|
||||
|
||||
if not source_name:
|
||||
await self._send_error(
|
||||
request.request_id,
|
||||
"NO_SOURCE_SPECIFIED",
|
||||
"No data source specified and no default source configured",
|
||||
)
|
||||
return
|
||||
|
||||
try:
|
||||
symbol_info = await self.registry.resolve_symbol(source_name, symbol)
|
||||
response = ResolveSymbolResponse(
|
||||
request_id=request.request_id,
|
||||
symbol_info=symbol_info.model_dump(mode="json"),
|
||||
)
|
||||
await self._send_response(response)
|
||||
except ValueError as e:
|
||||
await self._send_error(request.request_id, "SYMBOL_NOT_FOUND", str(e))
|
||||
|
||||
async def _handle_get_bars(self, request: GetBarsRequest) -> None:
|
||||
"""Handle historical bars request"""
|
||||
# Extract source from symbol
|
||||
if ":" in request.symbol:
|
||||
source_name, symbol = request.symbol.split(":", 1)
|
||||
else:
|
||||
source_name = self.default_source
|
||||
symbol = request.symbol
|
||||
|
||||
if not source_name:
|
||||
await self._send_error(
|
||||
request.request_id, "NO_SOURCE_SPECIFIED", "No data source specified"
|
||||
)
|
||||
return
|
||||
|
||||
source = self.registry.get(source_name)
|
||||
if not source:
|
||||
await self._send_error(
|
||||
request.request_id, "SOURCE_NOT_FOUND", f"Source '{source_name}' not found"
|
||||
)
|
||||
return
|
||||
|
||||
try:
|
||||
history = await source.get_bars(
|
||||
symbol=symbol,
|
||||
resolution=request.resolution,
|
||||
from_time=request.from_time,
|
||||
to_time=request.to_time,
|
||||
countback=request.countback,
|
||||
)
|
||||
response = GetBarsResponse(
|
||||
request_id=request.request_id, history=history.model_dump(mode="json")
|
||||
)
|
||||
await self._send_response(response)
|
||||
except ValueError as e:
|
||||
await self._send_error(request.request_id, "INVALID_REQUEST", str(e))
|
||||
|
||||
async def _handle_subscribe_bars(self, request: SubscribeBarsRequest) -> None:
|
||||
"""Handle real-time subscription request"""
|
||||
# Extract source from symbol
|
||||
if ":" in request.symbol:
|
||||
source_name, symbol = request.symbol.split(":", 1)
|
||||
else:
|
||||
source_name = self.default_source
|
||||
symbol = request.symbol
|
||||
|
||||
if not source_name:
|
||||
await self._send_error(
|
||||
request.request_id, "NO_SOURCE_SPECIFIED", "No data source specified"
|
||||
)
|
||||
return
|
||||
|
||||
try:
|
||||
# Create callback that sends updates to this WebSocket
|
||||
async def send_update(bar: dict):
|
||||
update = BarUpdateMessage(
|
||||
subscription_id=request.subscription_id,
|
||||
symbol=request.symbol,
|
||||
resolution=request.resolution,
|
||||
bar=bar,
|
||||
)
|
||||
await self._send_response(update)
|
||||
|
||||
# Register subscription
|
||||
await self.subscription_manager.subscribe(
|
||||
subscription_id=request.subscription_id,
|
||||
client_id=self.client_id,
|
||||
source_name=source_name,
|
||||
symbol=symbol,
|
||||
resolution=request.resolution,
|
||||
callback=lambda bar: self._queue_update(send_update(bar)),
|
||||
)
|
||||
|
||||
response = SubscribeBarsResponse(
|
||||
request_id=request.request_id,
|
||||
subscription_id=request.subscription_id,
|
||||
success=True,
|
||||
)
|
||||
await self._send_response(response)
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Subscription failed: {e}", exc_info=True)
|
||||
response = SubscribeBarsResponse(
|
||||
request_id=request.request_id,
|
||||
subscription_id=request.subscription_id,
|
||||
success=False,
|
||||
message=str(e),
|
||||
)
|
||||
await self._send_response(response)
|
||||
|
||||
async def _handle_unsubscribe_bars(self, request: UnsubscribeBarsRequest) -> None:
|
||||
"""Handle unsubscribe request"""
|
||||
try:
|
||||
await self.subscription_manager.unsubscribe(request.subscription_id)
|
||||
response = UnsubscribeBarsResponse(
|
||||
request_id=request.request_id,
|
||||
subscription_id=request.subscription_id,
|
||||
success=True,
|
||||
)
|
||||
await self._send_response(response)
|
||||
except Exception as e:
|
||||
logger.error(f"Unsubscribe failed: {e}")
|
||||
response = UnsubscribeBarsResponse(
|
||||
request_id=request.request_id,
|
||||
subscription_id=request.subscription_id,
|
||||
success=False,
|
||||
)
|
||||
await self._send_response(response)
|
||||
|
||||
async def _handle_get_config(self, request: GetConfigRequest) -> None:
|
||||
"""Handle datafeed config request"""
|
||||
if self.default_source:
|
||||
source = self.registry.get(self.default_source)
|
||||
if source:
|
||||
config = await source.get_config()
|
||||
response = GetConfigResponse(
|
||||
request_id=request.request_id, config=config.model_dump(mode="json")
|
||||
)
|
||||
await self._send_response(response)
|
||||
return
|
||||
|
||||
# Return aggregate config from all sources
|
||||
all_sources = self.registry.list_sources()
|
||||
if not all_sources:
|
||||
await self._send_error(
|
||||
request.request_id, "NO_SOURCES", "No data sources available"
|
||||
)
|
||||
return
|
||||
|
||||
# Just use first source's config for now
|
||||
# TODO: Aggregate configs from multiple sources
|
||||
source = self.registry.get(all_sources[0])
|
||||
if source:
|
||||
config = await source.get_config()
|
||||
response = GetConfigResponse(
|
||||
request_id=request.request_id, config=config.model_dump(mode="json")
|
||||
)
|
||||
await self._send_response(response)
|
||||
|
||||
async def _send_response(self, response) -> None:
|
||||
"""Send a response message to the client"""
|
||||
try:
|
||||
await self.websocket.send_json(response.model_dump(mode="json"))
|
||||
except Exception as e:
|
||||
logger.error(f"Error sending response: {e}")
|
||||
self._connected = False
|
||||
|
||||
async def _send_error(self, request_id: str, error_code: str, error_message: str) -> None:
|
||||
"""Send an error response"""
|
||||
error = ErrorResponse(
|
||||
request_id=request_id, error_code=error_code, error_message=error_message
|
||||
)
|
||||
await self._send_response(error)
|
||||
|
||||
def _queue_update(self, coro):
|
||||
"""Queue an async update to be sent (prevents blocking callback)"""
|
||||
import asyncio
|
||||
|
||||
asyncio.create_task(coro)
|
||||
170
backend/src/datasource/websocket_protocol.py
Normal file
170
backend/src/datasource/websocket_protocol.py
Normal file
@@ -0,0 +1,170 @@
|
||||
"""
|
||||
WebSocket protocol messages for TradingView-compatible datafeed API.
|
||||
|
||||
These messages define the wire format for client-server communication
|
||||
over WebSocket for symbol search, historical data, and real-time subscriptions.
|
||||
"""
|
||||
|
||||
from typing import Any, Dict, List, Literal, Optional, Union
|
||||
|
||||
from pydantic import BaseModel, Field
|
||||
|
||||
|
||||
# ============================================================================
|
||||
# Client -> Server Messages
|
||||
# ============================================================================
|
||||
|
||||
|
||||
class SearchSymbolsRequest(BaseModel):
|
||||
"""Request to search for symbols matching a query"""
|
||||
|
||||
type: Literal["search_symbols"] = "search_symbols"
|
||||
request_id: str = Field(description="Client-generated request ID for matching responses")
|
||||
query: str = Field(description="Search query string")
|
||||
symbol_type: Optional[str] = Field(default=None, description="Filter by instrument type")
|
||||
exchange: Optional[str] = Field(default=None, description="Filter by exchange")
|
||||
limit: int = Field(default=30, description="Maximum number of results")
|
||||
|
||||
|
||||
class ResolveSymbolRequest(BaseModel):
|
||||
"""Request full metadata for a specific symbol"""
|
||||
|
||||
type: Literal["resolve_symbol"] = "resolve_symbol"
|
||||
request_id: str
|
||||
symbol: str = Field(description="Symbol identifier to resolve")
|
||||
|
||||
|
||||
class GetBarsRequest(BaseModel):
|
||||
"""Request historical bar data"""
|
||||
|
||||
type: Literal["get_bars"] = "get_bars"
|
||||
request_id: str
|
||||
symbol: str
|
||||
resolution: str = Field(description="Time resolution (e.g., '1', '5', '60', '1D')")
|
||||
from_time: int = Field(description="Start time (Unix timestamp in seconds)")
|
||||
to_time: int = Field(description="End time (Unix timestamp in seconds)")
|
||||
countback: Optional[int] = Field(default=None, description="Maximum number of bars to return")
|
||||
|
||||
|
||||
class SubscribeBarsRequest(BaseModel):
|
||||
"""Subscribe to real-time bar updates"""
|
||||
|
||||
type: Literal["subscribe_bars"] = "subscribe_bars"
|
||||
request_id: str
|
||||
symbol: str
|
||||
resolution: str
|
||||
subscription_id: str = Field(description="Client-generated subscription ID")
|
||||
|
||||
|
||||
class UnsubscribeBarsRequest(BaseModel):
|
||||
"""Unsubscribe from real-time updates"""
|
||||
|
||||
type: Literal["unsubscribe_bars"] = "unsubscribe_bars"
|
||||
request_id: str
|
||||
subscription_id: str
|
||||
|
||||
|
||||
class GetConfigRequest(BaseModel):
|
||||
"""Request datafeed configuration"""
|
||||
|
||||
type: Literal["get_config"] = "get_config"
|
||||
request_id: str
|
||||
|
||||
|
||||
# Union of all client request types
|
||||
ClientRequest = Union[
|
||||
SearchSymbolsRequest,
|
||||
ResolveSymbolRequest,
|
||||
GetBarsRequest,
|
||||
SubscribeBarsRequest,
|
||||
UnsubscribeBarsRequest,
|
||||
GetConfigRequest,
|
||||
]
|
||||
|
||||
|
||||
# ============================================================================
|
||||
# Server -> Client Messages
|
||||
# ============================================================================
|
||||
|
||||
|
||||
class SearchSymbolsResponse(BaseModel):
|
||||
"""Response with search results"""
|
||||
|
||||
type: Literal["search_symbols_response"] = "search_symbols_response"
|
||||
request_id: str
|
||||
results: List[Dict[str, Any]] = Field(description="List of SearchResult objects")
|
||||
|
||||
|
||||
class ResolveSymbolResponse(BaseModel):
|
||||
"""Response with symbol metadata"""
|
||||
|
||||
type: Literal["resolve_symbol_response"] = "resolve_symbol_response"
|
||||
request_id: str
|
||||
symbol_info: Dict[str, Any] = Field(description="SymbolInfo object")
|
||||
|
||||
|
||||
class GetBarsResponse(BaseModel):
|
||||
"""Response with historical bars"""
|
||||
|
||||
type: Literal["get_bars_response"] = "get_bars_response"
|
||||
request_id: str
|
||||
history: Dict[str, Any] = Field(description="HistoryResult object with bars and metadata")
|
||||
|
||||
|
||||
class SubscribeBarsResponse(BaseModel):
|
||||
"""Acknowledgment of subscription"""
|
||||
|
||||
type: Literal["subscribe_bars_response"] = "subscribe_bars_response"
|
||||
request_id: str
|
||||
subscription_id: str
|
||||
success: bool
|
||||
message: Optional[str] = None
|
||||
|
||||
|
||||
class UnsubscribeBarsResponse(BaseModel):
|
||||
"""Acknowledgment of unsubscribe"""
|
||||
|
||||
type: Literal["unsubscribe_bars_response"] = "unsubscribe_bars_response"
|
||||
request_id: str
|
||||
subscription_id: str
|
||||
success: bool
|
||||
|
||||
|
||||
class GetConfigResponse(BaseModel):
|
||||
"""Response with datafeed configuration"""
|
||||
|
||||
type: Literal["get_config_response"] = "get_config_response"
|
||||
request_id: str
|
||||
config: Dict[str, Any] = Field(description="DatafeedConfig object")
|
||||
|
||||
|
||||
class BarUpdateMessage(BaseModel):
|
||||
"""Real-time bar update (server-initiated, no request_id)"""
|
||||
|
||||
type: Literal["bar_update"] = "bar_update"
|
||||
subscription_id: str
|
||||
symbol: str
|
||||
resolution: str
|
||||
bar: Dict[str, Any] = Field(description="Bar data including time and all columns")
|
||||
|
||||
|
||||
class ErrorResponse(BaseModel):
|
||||
"""Error response for any failed request"""
|
||||
|
||||
type: Literal["error"] = "error"
|
||||
request_id: str
|
||||
error_code: str = Field(description="Machine-readable error code")
|
||||
error_message: str = Field(description="Human-readable error description")
|
||||
|
||||
|
||||
# Union of all server response types
|
||||
ServerResponse = Union[
|
||||
SearchSymbolsResponse,
|
||||
ResolveSymbolResponse,
|
||||
GetBarsResponse,
|
||||
SubscribeBarsResponse,
|
||||
UnsubscribeBarsResponse,
|
||||
GetConfigResponse,
|
||||
BarUpdateMessage,
|
||||
ErrorResponse,
|
||||
]
|
||||
4
backend/src/gateway/__init__.py
Normal file
4
backend/src/gateway/__init__.py
Normal file
@@ -0,0 +1,4 @@
|
||||
from gateway.protocol import UserMessage, AgentMessage, ChannelStatus
|
||||
from gateway.hub import Gateway
|
||||
|
||||
__all__ = ["UserMessage", "AgentMessage", "ChannelStatus", "Gateway"]
|
||||
3
backend/src/gateway/channels/__init__.py
Normal file
3
backend/src/gateway/channels/__init__.py
Normal file
@@ -0,0 +1,3 @@
|
||||
from gateway.channels.base import Channel
|
||||
|
||||
__all__ = ["Channel"]
|
||||
73
backend/src/gateway/channels/base.py
Normal file
73
backend/src/gateway/channels/base.py
Normal file
@@ -0,0 +1,73 @@
|
||||
from abc import ABC, abstractmethod
|
||||
from typing import AsyncIterator, Dict, Any
|
||||
|
||||
from gateway.protocol import UserMessage, AgentMessage, ChannelStatus
|
||||
|
||||
|
||||
class Channel(ABC):
|
||||
"""Abstract base class for communication channels.
|
||||
|
||||
Channels are the transport layer between users and the agent system.
|
||||
They handle protocol-specific encoding/decoding and maintain connection state.
|
||||
"""
|
||||
|
||||
def __init__(self, channel_id: str, channel_type: str):
|
||||
self.channel_id = channel_id
|
||||
self.channel_type = channel_type
|
||||
self._connected = False
|
||||
|
||||
@abstractmethod
|
||||
async def send(self, message: AgentMessage) -> None:
|
||||
"""Send a message from the agent to the user through this channel.
|
||||
|
||||
Args:
|
||||
message: AgentMessage to send (may be streaming chunk or complete message)
|
||||
"""
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
async def receive(self) -> AsyncIterator[UserMessage]:
|
||||
"""Receive messages from the user through this channel.
|
||||
|
||||
Yields:
|
||||
UserMessage objects as they arrive
|
||||
"""
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
async def close(self) -> None:
|
||||
"""Close the channel and clean up resources."""
|
||||
pass
|
||||
|
||||
def supports_streaming(self) -> bool:
|
||||
"""Whether this channel supports streaming responses.
|
||||
|
||||
Returns:
|
||||
True if the channel can handle streaming chunks
|
||||
"""
|
||||
return False
|
||||
|
||||
def supports_attachments(self) -> bool:
|
||||
"""Whether this channel supports file attachments.
|
||||
|
||||
Returns:
|
||||
True if the channel can handle attachments
|
||||
"""
|
||||
return False
|
||||
|
||||
def get_status(self) -> ChannelStatus:
|
||||
"""Get current channel status.
|
||||
|
||||
Returns:
|
||||
ChannelStatus object with connection info and capabilities
|
||||
"""
|
||||
return ChannelStatus(
|
||||
channel_id=self.channel_id,
|
||||
channel_type=self.channel_type,
|
||||
connected=self._connected,
|
||||
capabilities={
|
||||
"streaming": self.supports_streaming(),
|
||||
"attachments": self.supports_attachments(),
|
||||
"markdown": True # Most channels support some form of markdown
|
||||
}
|
||||
)
|
||||
99
backend/src/gateway/channels/websocket.py
Normal file
99
backend/src/gateway/channels/websocket.py
Normal file
@@ -0,0 +1,99 @@
|
||||
import asyncio
|
||||
import json
|
||||
import logging
|
||||
from typing import AsyncIterator, Optional
|
||||
from datetime import datetime
|
||||
from fastapi import WebSocket
|
||||
|
||||
from gateway.channels.base import Channel
|
||||
from gateway.protocol import UserMessage, AgentMessage, WebSocketAgentUserMessage, WebSocketAgentChunk
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class WebSocketChannel(Channel):
|
||||
"""WebSocket-based communication channel.
|
||||
|
||||
Integrates with the existing WebSocket endpoint to provide
|
||||
bidirectional agent communication with streaming support.
|
||||
"""
|
||||
|
||||
def __init__(self, channel_id: str, websocket: WebSocket, session_id: str):
|
||||
super().__init__(channel_id, "websocket")
|
||||
self.websocket = websocket
|
||||
self.session_id = session_id
|
||||
self._connected = True
|
||||
self._receive_queue: asyncio.Queue[UserMessage] = asyncio.Queue()
|
||||
self._receive_task: Optional[asyncio.Task] = None
|
||||
|
||||
def supports_streaming(self) -> bool:
|
||||
"""WebSocket supports streaming responses."""
|
||||
return True
|
||||
|
||||
def supports_attachments(self) -> bool:
|
||||
"""WebSocket can support attachments via URLs."""
|
||||
return True
|
||||
|
||||
async def send(self, message: AgentMessage) -> None:
|
||||
"""Send agent message through WebSocket.
|
||||
|
||||
For streaming messages, sends chunks as they arrive.
|
||||
For complete messages, sends as a single chunk.
|
||||
"""
|
||||
if not self._connected:
|
||||
logger.warning(f"Cannot send message, channel {self.channel_id} not connected")
|
||||
return
|
||||
|
||||
try:
|
||||
chunk = WebSocketAgentChunk(
|
||||
session_id=message.session_id,
|
||||
content=message.content,
|
||||
done=message.done,
|
||||
metadata=message.metadata
|
||||
)
|
||||
chunk_data = chunk.model_dump(mode="json")
|
||||
logger.debug(f"Sending WebSocket message: done={message.done}, content_length={len(message.content)}")
|
||||
await self.websocket.send_json(chunk_data)
|
||||
logger.debug(f"WebSocket message sent successfully")
|
||||
except Exception as e:
|
||||
logger.error(f"WebSocket send error: {e}", exc_info=True)
|
||||
self._connected = False
|
||||
|
||||
async def receive(self) -> AsyncIterator[UserMessage]:
|
||||
"""Receive messages from WebSocket.
|
||||
|
||||
Yields:
|
||||
UserMessage objects as they arrive from the client
|
||||
"""
|
||||
try:
|
||||
while self._connected:
|
||||
# Read from WebSocket
|
||||
data = await self.websocket.receive_text()
|
||||
message_json = json.loads(data)
|
||||
|
||||
# Only process agent_user_message types
|
||||
if message_json.get("type") == "agent_user_message":
|
||||
msg = WebSocketAgentUserMessage(**message_json)
|
||||
|
||||
user_msg = UserMessage(
|
||||
session_id=msg.session_id,
|
||||
channel_id=self.channel_id,
|
||||
content=msg.content,
|
||||
attachments=msg.attachments,
|
||||
timestamp=datetime.utcnow()
|
||||
)
|
||||
yield user_msg
|
||||
except Exception as e:
|
||||
print(f"WebSocket receive error: {e}")
|
||||
self._connected = False
|
||||
|
||||
async def close(self) -> None:
|
||||
"""Close the WebSocket connection."""
|
||||
self._connected = False
|
||||
if self._receive_task:
|
||||
self._receive_task.cancel()
|
||||
try:
|
||||
await self._receive_task
|
||||
except asyncio.CancelledError:
|
||||
pass
|
||||
# Note: WebSocket close is handled by the main WebSocket endpoint
|
||||
226
backend/src/gateway/hub.py
Normal file
226
backend/src/gateway/hub.py
Normal file
@@ -0,0 +1,226 @@
|
||||
import asyncio
|
||||
import logging
|
||||
from typing import Dict, Optional, Callable, Awaitable, Any
|
||||
from datetime import datetime
|
||||
|
||||
from gateway.channels.base import Channel
|
||||
from gateway.user_session import UserSession
|
||||
from gateway.protocol import UserMessage, AgentMessage
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class Gateway:
|
||||
"""Central hub for routing messages between users, channels, and the agent.
|
||||
|
||||
The Gateway:
|
||||
- Maintains active channels and user sessions
|
||||
- Routes user messages to the agent
|
||||
- Routes agent responses back to appropriate channels
|
||||
- Handles interruption of in-flight agent tasks
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
self.channels: Dict[str, Channel] = {}
|
||||
self.sessions: Dict[str, UserSession] = {}
|
||||
self.agent_executor: Optional[Callable[[UserSession, UserMessage], Awaitable[AsyncIterator[str]]]] = None
|
||||
|
||||
def set_agent_executor(
|
||||
self,
|
||||
executor: Callable[[UserSession, UserMessage], Awaitable[Any]]
|
||||
) -> None:
|
||||
"""Set the agent executor function.
|
||||
|
||||
Args:
|
||||
executor: Async function that takes (session, message) and returns async iterator of response chunks
|
||||
"""
|
||||
self.agent_executor = executor
|
||||
|
||||
def register_channel(self, channel: Channel) -> None:
|
||||
"""Register a new communication channel.
|
||||
|
||||
Args:
|
||||
channel: Channel instance to register
|
||||
"""
|
||||
self.channels[channel.channel_id] = channel
|
||||
|
||||
def unregister_channel(self, channel_id: str) -> None:
|
||||
"""Unregister a channel.
|
||||
|
||||
Args:
|
||||
channel_id: ID of channel to remove
|
||||
"""
|
||||
if channel_id in self.channels:
|
||||
# Remove channel from any sessions
|
||||
for session in self.sessions.values():
|
||||
session.remove_channel(channel_id)
|
||||
del self.channels[channel_id]
|
||||
|
||||
def get_or_create_session(self, session_id: str, user_id: str) -> UserSession:
|
||||
"""Get existing session or create a new one.
|
||||
|
||||
Args:
|
||||
session_id: Unique session identifier
|
||||
user_id: User identifier
|
||||
|
||||
Returns:
|
||||
UserSession instance
|
||||
"""
|
||||
if session_id not in self.sessions:
|
||||
self.sessions[session_id] = UserSession(session_id, user_id)
|
||||
return self.sessions[session_id]
|
||||
|
||||
async def route_user_message(self, message: UserMessage) -> None:
|
||||
"""Route a user message to the agent.
|
||||
|
||||
If the agent is currently processing a message, it will be interrupted
|
||||
and restarted with the new message appended to the conversation.
|
||||
|
||||
Args:
|
||||
message: UserMessage from a channel
|
||||
"""
|
||||
logger.info(f"route_user_message called - session: {message.session_id}, channel: {message.channel_id}")
|
||||
|
||||
# Get or create session
|
||||
session = self.get_or_create_session(message.session_id, message.session_id)
|
||||
logger.info(f"Session obtained/created: {message.session_id}, channels: {session.active_channels}")
|
||||
|
||||
# Ensure channel is attached to session
|
||||
session.add_channel(message.channel_id)
|
||||
logger.info(f"Channel added to session: {message.channel_id}")
|
||||
|
||||
# If agent is busy, interrupt it
|
||||
if session.is_busy():
|
||||
logger.info(f"Session is busy, interrupting existing task")
|
||||
await session.interrupt()
|
||||
|
||||
# Add user message to history
|
||||
session.add_message("user", message.content, message.channel_id)
|
||||
logger.info(f"User message added to history, history length: {len(session.get_history())}")
|
||||
|
||||
# Start agent task
|
||||
if self.agent_executor:
|
||||
logger.info("Starting agent task execution")
|
||||
task = asyncio.create_task(
|
||||
self._execute_agent_and_stream(session, message)
|
||||
)
|
||||
session.set_task(task)
|
||||
logger.info(f"Agent task created and set on session")
|
||||
else:
|
||||
logger.error("No agent_executor configured! Cannot process message.")
|
||||
# Send error message to user
|
||||
error_msg = AgentMessage(
|
||||
session_id=session.session_id,
|
||||
target_channels=session.active_channels,
|
||||
content="Error: Agent system not initialized. Please check that ANTHROPIC_API_KEY is configured.",
|
||||
done=True
|
||||
)
|
||||
await self._send_to_channels(error_msg)
|
||||
|
||||
async def _execute_agent_and_stream(self, session: UserSession, message: UserMessage) -> None:
|
||||
"""Execute agent and stream responses back to channels.
|
||||
|
||||
Args:
|
||||
session: User session
|
||||
message: Triggering user message
|
||||
"""
|
||||
logger.info(f"_execute_agent_and_stream starting for session {session.session_id}")
|
||||
try:
|
||||
# Execute agent (returns async generator directly)
|
||||
logger.info("Calling agent_executor...")
|
||||
response_stream = self.agent_executor(session, message)
|
||||
logger.info("Agent executor returned response stream")
|
||||
|
||||
# Stream chunks back to active channels
|
||||
full_response = ""
|
||||
chunk_count = 0
|
||||
async for chunk in response_stream:
|
||||
chunk_count += 1
|
||||
full_response += chunk
|
||||
logger.debug(f"Received chunk #{chunk_count}, length: {len(chunk)}")
|
||||
|
||||
# Send chunk to all active channels
|
||||
agent_msg = AgentMessage(
|
||||
session_id=session.session_id,
|
||||
target_channels=session.active_channels,
|
||||
content=chunk,
|
||||
stream_chunk=True,
|
||||
done=False
|
||||
)
|
||||
await self._send_to_channels(agent_msg)
|
||||
|
||||
logger.info(f"Agent streaming completed, total chunks: {chunk_count}, response length: {len(full_response)}")
|
||||
|
||||
# Send final done message
|
||||
agent_msg = AgentMessage(
|
||||
session_id=session.session_id,
|
||||
target_channels=session.active_channels,
|
||||
content="",
|
||||
stream_chunk=True,
|
||||
done=True
|
||||
)
|
||||
await self._send_to_channels(agent_msg)
|
||||
logger.info("Sent final done message to channels")
|
||||
|
||||
# Add to history
|
||||
session.add_message("assistant", full_response)
|
||||
logger.info("Assistant response added to history")
|
||||
|
||||
except asyncio.CancelledError:
|
||||
# Task was interrupted
|
||||
logger.warning(f"Agent task interrupted for session {session.session_id}")
|
||||
raise
|
||||
except Exception as e:
|
||||
logger.error(f"Agent execution error: {e}", exc_info=True)
|
||||
# Send error message
|
||||
error_msg = AgentMessage(
|
||||
session_id=session.session_id,
|
||||
target_channels=session.active_channels,
|
||||
content=f"Error: {str(e)}",
|
||||
done=True
|
||||
)
|
||||
await self._send_to_channels(error_msg)
|
||||
finally:
|
||||
session.set_task(None)
|
||||
logger.info(f"Agent task completed for session {session.session_id}")
|
||||
|
||||
async def _send_to_channels(self, message: AgentMessage) -> None:
|
||||
"""Send message to specified channels.
|
||||
|
||||
Args:
|
||||
message: AgentMessage to send
|
||||
"""
|
||||
logger.debug(f"Sending message to {len(message.target_channels)} channels")
|
||||
for channel_id in message.target_channels:
|
||||
channel = self.channels.get(channel_id)
|
||||
if channel and channel.get_status().connected:
|
||||
try:
|
||||
await channel.send(message)
|
||||
logger.debug(f"Message sent to channel {channel_id}")
|
||||
except Exception as e:
|
||||
logger.error(f"Error sending to channel {channel_id}: {e}", exc_info=True)
|
||||
else:
|
||||
logger.warning(f"Channel {channel_id} not found or not connected")
|
||||
|
||||
def get_session_info(self, session_id: str) -> Optional[Dict[str, Any]]:
|
||||
"""Get session information.
|
||||
|
||||
Args:
|
||||
session_id: Session ID to query
|
||||
|
||||
Returns:
|
||||
Session info dict or None if not found
|
||||
"""
|
||||
session = self.sessions.get(session_id)
|
||||
return session.to_dict() if session else None
|
||||
|
||||
def get_active_sessions(self) -> Dict[str, Dict[str, Any]]:
|
||||
"""Get all active sessions.
|
||||
|
||||
Returns:
|
||||
Dict mapping session_id to session info
|
||||
"""
|
||||
return {
|
||||
sid: session.to_dict()
|
||||
for sid, session in self.sessions.items()
|
||||
}
|
||||
57
backend/src/gateway/protocol.py
Normal file
57
backend/src/gateway/protocol.py
Normal file
@@ -0,0 +1,57 @@
|
||||
from datetime import datetime, timezone
|
||||
from typing import Any, Dict, List, Literal, Optional
|
||||
from pydantic import BaseModel, Field
|
||||
|
||||
|
||||
class UserMessage(BaseModel):
|
||||
"""Message from user to agent through a communication channel."""
|
||||
session_id: str
|
||||
channel_id: str
|
||||
content: str
|
||||
attachments: List[str] = Field(default_factory=list, description="URLs or file paths")
|
||||
timestamp: datetime = Field(default_factory=lambda: datetime.now(timezone.utc))
|
||||
metadata: Dict[str, Any] = Field(default_factory=dict)
|
||||
|
||||
|
||||
class AgentMessage(BaseModel):
|
||||
"""Message from agent to user(s) through one or more channels."""
|
||||
session_id: str
|
||||
target_channels: List[str] = Field(description="List of channel IDs to send to")
|
||||
content: str
|
||||
stream_chunk: bool = Field(default=False, description="True if this is a streaming chunk")
|
||||
done: bool = Field(default=False, description="True if streaming is complete")
|
||||
metadata: Dict[str, Any] = Field(default_factory=dict)
|
||||
|
||||
|
||||
class ChannelStatus(BaseModel):
|
||||
"""Status information about a communication channel."""
|
||||
channel_id: str
|
||||
channel_type: str = Field(description="Type: 'websocket', 'slack', 'telegram', etc.")
|
||||
connected: bool
|
||||
user_id: Optional[str] = None
|
||||
session_id: Optional[str] = None
|
||||
capabilities: Dict[str, bool] = Field(
|
||||
default_factory=lambda: {
|
||||
"streaming": False,
|
||||
"attachments": False,
|
||||
"markdown": False
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
# WebSocket-specific protocol extensions
|
||||
class WebSocketAgentUserMessage(BaseModel):
|
||||
"""WebSocket message: User → Backend (agent chat)"""
|
||||
type: Literal["agent_user_message"] = "agent_user_message"
|
||||
session_id: str
|
||||
content: str
|
||||
attachments: List[str] = Field(default_factory=list)
|
||||
|
||||
|
||||
class WebSocketAgentChunk(BaseModel):
|
||||
"""WebSocket message: Backend → User (streaming agent response)"""
|
||||
type: Literal["agent_chunk"] = "agent_chunk"
|
||||
session_id: str
|
||||
content: str
|
||||
done: bool = False
|
||||
metadata: Dict[str, Any] = Field(default_factory=dict)
|
||||
107
backend/src/gateway/user_session.py
Normal file
107
backend/src/gateway/user_session.py
Normal file
@@ -0,0 +1,107 @@
|
||||
import asyncio
|
||||
from datetime import datetime
|
||||
from typing import Dict, List, Optional, Any
|
||||
from pydantic import BaseModel, Field
|
||||
|
||||
|
||||
class Message(BaseModel):
|
||||
"""A single message in a conversation."""
|
||||
role: str # "user" or "assistant"
|
||||
content: str
|
||||
timestamp: datetime = Field(default_factory=datetime.utcnow)
|
||||
channel_id: Optional[str] = None
|
||||
metadata: Dict[str, Any] = Field(default_factory=dict)
|
||||
|
||||
|
||||
class UserSession:
|
||||
"""Manages a user's conversation session with the agent.
|
||||
|
||||
A session tracks:
|
||||
- Active communication channels
|
||||
- Conversation history
|
||||
- In-flight agent tasks (for interruption)
|
||||
- User metadata
|
||||
"""
|
||||
|
||||
def __init__(self, session_id: str, user_id: str):
|
||||
self.session_id = session_id
|
||||
self.user_id = user_id
|
||||
self.active_channels: List[str] = []
|
||||
self.conversation_history: List[Message] = []
|
||||
self.current_task: Optional[asyncio.Task] = None
|
||||
self.metadata: Dict[str, Any] = {}
|
||||
self.created_at = datetime.utcnow()
|
||||
self.last_activity = datetime.utcnow()
|
||||
|
||||
def add_channel(self, channel_id: str) -> None:
|
||||
"""Attach a channel to this session."""
|
||||
if channel_id not in self.active_channels:
|
||||
self.active_channels.append(channel_id)
|
||||
self.last_activity = datetime.utcnow()
|
||||
|
||||
def remove_channel(self, channel_id: str) -> None:
|
||||
"""Detach a channel from this session."""
|
||||
if channel_id in self.active_channels:
|
||||
self.active_channels.remove(channel_id)
|
||||
self.last_activity = datetime.utcnow()
|
||||
|
||||
def add_message(self, role: str, content: str, channel_id: Optional[str] = None, **kwargs) -> None:
|
||||
"""Add a message to conversation history."""
|
||||
message = Message(
|
||||
role=role,
|
||||
content=content,
|
||||
channel_id=channel_id,
|
||||
metadata=kwargs
|
||||
)
|
||||
self.conversation_history.append(message)
|
||||
self.last_activity = datetime.utcnow()
|
||||
|
||||
def get_history(self, limit: Optional[int] = None) -> List[Message]:
|
||||
"""Get conversation history.
|
||||
|
||||
Args:
|
||||
limit: Maximum number of recent messages to return (None = all)
|
||||
|
||||
Returns:
|
||||
List of Message objects
|
||||
"""
|
||||
if limit:
|
||||
return self.conversation_history[-limit:]
|
||||
return self.conversation_history
|
||||
|
||||
async def interrupt(self) -> bool:
|
||||
"""Interrupt the current agent task if one is running.
|
||||
|
||||
Returns:
|
||||
True if a task was interrupted, False otherwise
|
||||
"""
|
||||
if self.current_task and not self.current_task.done():
|
||||
self.current_task.cancel()
|
||||
try:
|
||||
await self.current_task
|
||||
except asyncio.CancelledError:
|
||||
pass
|
||||
self.current_task = None
|
||||
return True
|
||||
return False
|
||||
|
||||
def set_task(self, task: asyncio.Task) -> None:
|
||||
"""Set the current agent task."""
|
||||
self.current_task = task
|
||||
|
||||
def is_busy(self) -> bool:
|
||||
"""Check if the agent is currently processing a request."""
|
||||
return self.current_task is not None and not self.current_task.done()
|
||||
|
||||
def to_dict(self) -> Dict[str, Any]:
|
||||
"""Serialize session to dict."""
|
||||
return {
|
||||
"session_id": self.session_id,
|
||||
"user_id": self.user_id,
|
||||
"active_channels": self.active_channels,
|
||||
"message_count": len(self.conversation_history),
|
||||
"is_busy": self.is_busy(),
|
||||
"created_at": self.created_at.isoformat(),
|
||||
"last_activity": self.last_activity.isoformat(),
|
||||
"metadata": self.metadata
|
||||
}
|
||||
469
backend/src/main.py
Normal file
469
backend/src/main.py
Normal file
@@ -0,0 +1,469 @@
|
||||
import asyncio
|
||||
import json
|
||||
import logging
|
||||
import os
|
||||
from contextlib import asynccontextmanager
|
||||
from pathlib import Path
|
||||
|
||||
import yaml
|
||||
from dotenv import load_dotenv
|
||||
from fastapi import FastAPI, WebSocket, WebSocketDisconnect, UploadFile, File, HTTPException
|
||||
from fastapi.responses import FileResponse
|
||||
from fastapi.staticfiles import StaticFiles
|
||||
from pydantic import BaseModel
|
||||
import uuid
|
||||
import shutil
|
||||
|
||||
from sync.protocol import HelloMessage, PatchMessage
|
||||
from sync.registry import SyncRegistry
|
||||
from gateway.hub import Gateway
|
||||
from gateway.channels.websocket import WebSocketChannel
|
||||
from gateway.protocol import WebSocketAgentUserMessage
|
||||
from agent.core import create_agent
|
||||
from agent.tools import set_registry, set_datasource_registry
|
||||
from schema.order_spec import SwapOrder
|
||||
from schema.chart_state import ChartState
|
||||
from datasource.registry import DataSourceRegistry
|
||||
from datasource.subscription_manager import SubscriptionManager
|
||||
from datasource.websocket_handler import DatafeedWebSocketHandler
|
||||
|
||||
# Configure logging
|
||||
logging.basicConfig(
|
||||
level=logging.INFO,
|
||||
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
|
||||
)
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
# Load environment variables from .env file (if present)
|
||||
env_path = Path(__file__).parent.parent / ".env"
|
||||
if env_path.exists():
|
||||
load_dotenv(env_path)
|
||||
|
||||
# Load configuration
|
||||
config_path = Path(__file__).parent.parent / "config.yaml"
|
||||
with open(config_path) as f:
|
||||
config = yaml.safe_load(f)
|
||||
|
||||
registry = SyncRegistry()
|
||||
gateway = Gateway()
|
||||
agent_executor = None
|
||||
|
||||
# DataSource infrastructure
|
||||
datasource_registry = DataSourceRegistry()
|
||||
subscription_manager = SubscriptionManager()
|
||||
|
||||
|
||||
@asynccontextmanager
|
||||
async def lifespan(app: FastAPI):
|
||||
"""Initialize agent system and data sources on startup."""
|
||||
global agent_executor
|
||||
|
||||
# Initialize CCXT data sources
|
||||
try:
|
||||
from datasource.adapters.ccxt_adapter import CCXTDataSource
|
||||
|
||||
# Binance
|
||||
try:
|
||||
binance_source = CCXTDataSource(exchange_id="binance", poll_interval=60)
|
||||
datasource_registry.register("binance", binance_source)
|
||||
subscription_manager.register_source("binance", binance_source)
|
||||
logger.info("DataSource: Registered Binance source")
|
||||
except Exception as e:
|
||||
logger.warning(f"Failed to initialize Binance source: {e}")
|
||||
|
||||
logger.info(f"DataSource infrastructure initialized with sources: {datasource_registry.list_sources()}")
|
||||
except ImportError as e:
|
||||
logger.warning(f"CCXT not available: {e}. Only demo source will be available.")
|
||||
logger.info("To use real exchange data, install ccxt: pip install ccxt>=4.0.0")
|
||||
|
||||
# Get API keys from environment
|
||||
anthropic_api_key = os.environ.get("ANTHROPIC_API_KEY")
|
||||
|
||||
if not anthropic_api_key:
|
||||
logger.error("ANTHROPIC_API_KEY not found in environment!")
|
||||
logger.info("Agent system will not be available")
|
||||
else:
|
||||
# Set the registries for agent tools
|
||||
set_registry(registry)
|
||||
set_datasource_registry(datasource_registry)
|
||||
|
||||
# Create and initialize agent
|
||||
agent_executor = create_agent(
|
||||
model_name=config["agent"]["model"],
|
||||
temperature=config["agent"]["temperature"],
|
||||
api_key=anthropic_api_key,
|
||||
checkpoint_db_path=config["memory"]["checkpoint_db"],
|
||||
chroma_db_path=config["memory"]["chroma_db"],
|
||||
embedding_model=config["memory"]["embedding_model"],
|
||||
context_docs_dir=config["agent"]["context_docs_dir"],
|
||||
base_dir=".." # Point to project root from backend/src
|
||||
)
|
||||
|
||||
await agent_executor.initialize()
|
||||
|
||||
# Set agent executor in gateway
|
||||
gateway.set_agent_executor(agent_executor.execute)
|
||||
|
||||
logger.info("Agent system initialized")
|
||||
|
||||
yield
|
||||
|
||||
# Cleanup
|
||||
if agent_executor and agent_executor.memory_manager:
|
||||
await agent_executor.memory_manager.close()
|
||||
logger.info("Agent system shut down")
|
||||
|
||||
|
||||
app = FastAPI(lifespan=lifespan)
|
||||
|
||||
# Create uploads directory
|
||||
UPLOAD_DIR = Path(__file__).parent.parent / "uploads"
|
||||
UPLOAD_DIR.mkdir(exist_ok=True)
|
||||
|
||||
# Mount static files for serving uploads
|
||||
app.mount("/uploads", StaticFiles(directory=str(UPLOAD_DIR)), name="uploads")
|
||||
|
||||
# OrderStore model for synchronization
|
||||
class OrderStore(BaseModel):
|
||||
orders: list[SwapOrder] = []
|
||||
|
||||
# ChartStore model for synchronization
|
||||
class ChartStore(BaseModel):
|
||||
chart_state: ChartState = ChartState()
|
||||
|
||||
# Initialize stores
|
||||
order_store = OrderStore()
|
||||
chart_store = ChartStore()
|
||||
|
||||
# Register with SyncRegistry
|
||||
registry.register(order_store, store_name="OrderStore")
|
||||
registry.register(chart_store, store_name="ChartStore")
|
||||
|
||||
@app.websocket("/ws")
|
||||
async def websocket_endpoint(websocket: WebSocket):
|
||||
await websocket.accept()
|
||||
registry.websocket = websocket
|
||||
|
||||
# Create WebSocket channel for agent communication
|
||||
channel_id = f"ws_{id(websocket)}"
|
||||
client_id = f"client_{id(websocket)}"
|
||||
logger.info(f"WebSocket connected - channel_id: {channel_id}, client_id: {client_id}")
|
||||
ws_channel = WebSocketChannel(channel_id, websocket, session_id="default")
|
||||
gateway.register_channel(ws_channel)
|
||||
|
||||
# Helper function to send responses
|
||||
async def send_response(response):
|
||||
try:
|
||||
await websocket.send_json(response.model_dump(mode="json"))
|
||||
except Exception as e:
|
||||
logger.error(f"Error sending response: {e}")
|
||||
|
||||
try:
|
||||
while True:
|
||||
data = await websocket.receive_text()
|
||||
logger.debug(f"Received WebSocket message: {data[:200]}...") # Log first 200 chars
|
||||
message_json = json.loads(data)
|
||||
|
||||
if "type" not in message_json:
|
||||
logger.warning(f"Message missing 'type' field: {message_json}")
|
||||
continue
|
||||
|
||||
msg_type = message_json["type"]
|
||||
logger.info(f"Processing message type: {msg_type}")
|
||||
|
||||
# Handle sync protocol messages
|
||||
if msg_type == "hello":
|
||||
hello_msg = HelloMessage(**message_json)
|
||||
logger.info(f"Hello message received with seqs: {hello_msg.seqs}")
|
||||
await registry.sync_client(hello_msg.seqs)
|
||||
elif msg_type == "patch":
|
||||
patch_msg = PatchMessage(**message_json)
|
||||
logger.info(f"Patch message received for store: {patch_msg.store}, seq: {patch_msg.seq}")
|
||||
await registry.apply_client_patch(
|
||||
store_name=patch_msg.store,
|
||||
client_base_seq=patch_msg.seq,
|
||||
patch=patch_msg.patch
|
||||
)
|
||||
elif msg_type == "agent_user_message":
|
||||
# Handle agent messages directly here
|
||||
print(f"[DEBUG] Raw message_json: {message_json}")
|
||||
logger.info(f"Raw message_json: {message_json}")
|
||||
msg = WebSocketAgentUserMessage(**message_json)
|
||||
print(f"[DEBUG] Parsed message - session: {msg.session_id}, content: '{msg.content}' (len={len(msg.content)})")
|
||||
logger.info(f"Agent user message received - session: {msg.session_id}, content: '{msg.content}' (len={len(msg.content)})")
|
||||
from gateway.protocol import UserMessage
|
||||
from datetime import datetime, timezone
|
||||
|
||||
user_msg = UserMessage(
|
||||
session_id=msg.session_id,
|
||||
channel_id=channel_id,
|
||||
content=msg.content,
|
||||
attachments=msg.attachments,
|
||||
timestamp=datetime.now(timezone.utc)
|
||||
)
|
||||
logger.info(f"Routing user message to gateway - channel: {channel_id}, session: {msg.session_id}")
|
||||
await gateway.route_user_message(user_msg)
|
||||
logger.info("Message routing completed")
|
||||
|
||||
# Handle datafeed protocol messages
|
||||
elif msg_type in ["get_config", "search_symbols", "resolve_symbol", "get_bars", "subscribe_bars", "unsubscribe_bars"]:
|
||||
from datasource.websocket_protocol import (
|
||||
GetConfigRequest, GetConfigResponse,
|
||||
SearchSymbolsRequest, SearchSymbolsResponse,
|
||||
ResolveSymbolRequest, ResolveSymbolResponse,
|
||||
GetBarsRequest, GetBarsResponse,
|
||||
SubscribeBarsRequest, SubscribeBarsResponse,
|
||||
UnsubscribeBarsRequest, UnsubscribeBarsResponse,
|
||||
ErrorResponse
|
||||
)
|
||||
|
||||
request_id = message_json.get("request_id", "unknown")
|
||||
try:
|
||||
if msg_type == "get_config":
|
||||
req = GetConfigRequest(**message_json)
|
||||
logger.info(f"Getting config, request_id={req.request_id}")
|
||||
sources = datasource_registry.list_sources()
|
||||
logger.info(f"Available sources: {sources}")
|
||||
|
||||
if not sources:
|
||||
error_response = ErrorResponse(request_id=req.request_id, error_code="NO_SOURCES", error_message="No data sources available")
|
||||
await send_response(error_response)
|
||||
else:
|
||||
# Get config from first source (we can enhance this later to aggregate)
|
||||
source = datasource_registry.get(sources[0])
|
||||
if source:
|
||||
try:
|
||||
config = await source.get_config()
|
||||
logger.info(f"Got config from {sources[0]}")
|
||||
# Enhance with all available exchanges
|
||||
all_exchanges = set()
|
||||
for source_name in sources:
|
||||
s = datasource_registry.get(source_name)
|
||||
if s:
|
||||
try:
|
||||
cfg = await asyncio.wait_for(s.get_config(), timeout=5.0)
|
||||
all_exchanges.update(cfg.exchanges)
|
||||
logger.info(f"Added exchanges from {source_name}: {cfg.exchanges}")
|
||||
except asyncio.TimeoutError:
|
||||
logger.warning(f"Timeout getting config from {source_name}")
|
||||
except Exception as e:
|
||||
logger.warning(f"Error getting config from {source_name}: {e}")
|
||||
config_dict = config.model_dump(mode="json")
|
||||
config_dict["exchanges"] = list(all_exchanges)
|
||||
logger.info(f"Sending config with exchanges: {list(all_exchanges)}")
|
||||
response = GetConfigResponse(request_id=req.request_id, config=config_dict)
|
||||
await send_response(response)
|
||||
except Exception as e:
|
||||
logger.error(f"Error getting config: {e}", exc_info=True)
|
||||
error_response = ErrorResponse(request_id=req.request_id, error_code="ERROR", error_message=str(e))
|
||||
await send_response(error_response)
|
||||
else:
|
||||
error_response = ErrorResponse(request_id=req.request_id, error_code="SOURCE_NOT_FOUND", error_message="Data sources not available")
|
||||
await send_response(error_response)
|
||||
|
||||
elif msg_type == "search_symbols":
|
||||
req = SearchSymbolsRequest(**message_json)
|
||||
logger.info(f"Searching symbols: query='{req.query}', request_id={req.request_id}")
|
||||
|
||||
# Search all data sources
|
||||
all_results = []
|
||||
sources = datasource_registry.list_sources()
|
||||
logger.info(f"Available data sources: {sources}")
|
||||
|
||||
for source_name in sources:
|
||||
source = datasource_registry.get(source_name)
|
||||
if source:
|
||||
try:
|
||||
results = await asyncio.wait_for(
|
||||
source.search_symbols(query=req.query, type=req.symbol_type, exchange=req.exchange, limit=req.limit),
|
||||
timeout=5.0
|
||||
)
|
||||
all_results.extend([r.model_dump(mode="json") for r in results])
|
||||
logger.info(f"Source '{source_name}' returned {len(results)} results")
|
||||
except asyncio.TimeoutError:
|
||||
logger.warning(f"Timeout searching source '{source_name}'")
|
||||
except Exception as e:
|
||||
logger.warning(f"Error searching source '{source_name}': {e}")
|
||||
|
||||
logger.info(f"Total search results: {len(all_results)}")
|
||||
response = SearchSymbolsResponse(request_id=req.request_id, results=all_results[:req.limit])
|
||||
await send_response(response)
|
||||
|
||||
elif msg_type == "resolve_symbol":
|
||||
req = ResolveSymbolRequest(**message_json)
|
||||
logger.info(f"Resolving symbol: {req.symbol}")
|
||||
|
||||
# Parse ticker format: "EXCHANGE:SYMBOL" (e.g., "BINANCE:BTC/USDT", "DEMO:BTC/USD")
|
||||
symbol = req.symbol
|
||||
source_name = None
|
||||
symbol_without_exchange = symbol
|
||||
|
||||
# Check if ticker has exchange prefix
|
||||
if ":" in symbol:
|
||||
exchange_prefix, symbol_without_exchange = symbol.split(":", 1)
|
||||
source_name = exchange_prefix.lower()
|
||||
logger.info(f"Parsed ticker: exchange={source_name}, symbol={symbol_without_exchange}")
|
||||
|
||||
# If we identified a source, try it directly
|
||||
if source_name:
|
||||
try:
|
||||
source = datasource_registry.get(source_name)
|
||||
if source:
|
||||
logger.info(f"Trying to resolve '{symbol_without_exchange}' in source '{source_name}'")
|
||||
symbol_info = await asyncio.wait_for(
|
||||
source.resolve_symbol(symbol_without_exchange),
|
||||
timeout=5.0
|
||||
)
|
||||
logger.info(f"Successfully resolved '{symbol_without_exchange}' in source '{source_name}'")
|
||||
response = ResolveSymbolResponse(request_id=req.request_id, symbol_info=symbol_info.model_dump(mode="json"))
|
||||
await send_response(response)
|
||||
else:
|
||||
error_response = ErrorResponse(request_id=req.request_id, error_code="SOURCE_NOT_FOUND", error_message=f"Data source '{source_name}' not found")
|
||||
await send_response(error_response)
|
||||
except asyncio.TimeoutError:
|
||||
logger.warning(f"Timeout resolving '{symbol_without_exchange}' in source '{source_name}'")
|
||||
error_response = ErrorResponse(request_id=req.request_id, error_code="TIMEOUT", error_message=f"Timeout resolving symbol")
|
||||
await send_response(error_response)
|
||||
except Exception as e:
|
||||
logger.warning(f"Error resolving '{symbol_without_exchange}' in source '{source_name}': {e}")
|
||||
error_response = ErrorResponse(request_id=req.request_id, error_code="SYMBOL_NOT_FOUND", error_message=str(e))
|
||||
await send_response(error_response)
|
||||
else:
|
||||
# No exchange prefix, try all sources
|
||||
found = False
|
||||
for src in datasource_registry.list_sources():
|
||||
try:
|
||||
s = datasource_registry.get(src)
|
||||
if s:
|
||||
logger.info(f"Trying to resolve '{symbol}' in source '{src}'")
|
||||
symbol_info = await asyncio.wait_for(s.resolve_symbol(symbol), timeout=5.0)
|
||||
if symbol_info:
|
||||
logger.info(f"Successfully resolved '{symbol}' in source '{src}'")
|
||||
response = ResolveSymbolResponse(request_id=req.request_id, symbol_info=symbol_info.model_dump(mode="json"))
|
||||
await send_response(response)
|
||||
found = True
|
||||
break
|
||||
except asyncio.TimeoutError:
|
||||
logger.warning(f"Timeout resolving '{symbol}' in source '{src}'")
|
||||
except Exception as e:
|
||||
logger.info(f"Symbol '{symbol}' not found in source '{src}': {e}")
|
||||
continue
|
||||
|
||||
if not found:
|
||||
# Symbol not found in any source
|
||||
logger.warning(f"Symbol '{symbol}' not found in any data source")
|
||||
error_response = ErrorResponse(request_id=req.request_id, error_code="SYMBOL_NOT_FOUND", error_message=f"Symbol '{symbol}' not found in any data source")
|
||||
await send_response(error_response)
|
||||
|
||||
elif msg_type == "get_bars":
|
||||
req = GetBarsRequest(**message_json)
|
||||
logger.info(f"Getting bars for symbol: {req.symbol}")
|
||||
|
||||
# Parse ticker format: "EXCHANGE:SYMBOL"
|
||||
symbol = req.symbol
|
||||
source_name = None
|
||||
symbol_without_exchange = symbol
|
||||
|
||||
# Check if ticker has exchange prefix
|
||||
if ":" in symbol:
|
||||
exchange_prefix, symbol_without_exchange = symbol.split(":", 1)
|
||||
source_name = exchange_prefix.lower()
|
||||
logger.info(f"Parsed ticker for bars: exchange={source_name}, symbol={symbol_without_exchange}")
|
||||
|
||||
# If we identified a source, use it directly
|
||||
if source_name:
|
||||
try:
|
||||
source = datasource_registry.get(source_name)
|
||||
if source:
|
||||
logger.info(f"Getting bars for '{symbol_without_exchange}' from source '{source_name}'")
|
||||
history = await asyncio.wait_for(
|
||||
source.get_bars(symbol=symbol_without_exchange, resolution=req.resolution, from_time=req.from_time, to_time=req.to_time, countback=req.countback),
|
||||
timeout=10.0
|
||||
)
|
||||
logger.info(f"Successfully got {len(history.bars)} bars for '{symbol_without_exchange}' from source '{source_name}'")
|
||||
response = GetBarsResponse(request_id=req.request_id, history=history.model_dump(mode="json"))
|
||||
await send_response(response)
|
||||
else:
|
||||
error_response = ErrorResponse(request_id=req.request_id, error_code="SOURCE_NOT_FOUND", error_message=f"Data source '{source_name}' not found")
|
||||
await send_response(error_response)
|
||||
except asyncio.TimeoutError:
|
||||
logger.warning(f"Timeout getting bars for '{symbol_without_exchange}' from source '{source_name}'")
|
||||
error_response = ErrorResponse(request_id=req.request_id, error_code="TIMEOUT", error_message="Timeout fetching bars")
|
||||
await send_response(error_response)
|
||||
except Exception as e:
|
||||
logger.warning(f"Error getting bars for '{symbol_without_exchange}' from source '{source_name}': {e}")
|
||||
error_response = ErrorResponse(request_id=req.request_id, error_code="ERROR", error_message=str(e))
|
||||
await send_response(error_response)
|
||||
else:
|
||||
# No exchange prefix - this shouldn't happen with proper tickers
|
||||
logger.warning(f"Ticker '{symbol}' has no exchange prefix")
|
||||
error_response = ErrorResponse(request_id=req.request_id, error_code="INVALID_TICKER", error_message="Ticker must include exchange prefix (e.g., BINANCE:BTC/USDT)")
|
||||
await send_response(error_response)
|
||||
|
||||
elif msg_type == "subscribe_bars":
|
||||
req = SubscribeBarsRequest(**message_json)
|
||||
# TODO: Implement subscription management
|
||||
response = SubscribeBarsResponse(request_id=req.request_id, subscription_id=req.subscription_id, success=True)
|
||||
await send_response(response)
|
||||
|
||||
elif msg_type == "unsubscribe_bars":
|
||||
req = UnsubscribeBarsRequest(**message_json)
|
||||
response = UnsubscribeBarsResponse(request_id=req.request_id, subscription_id=req.subscription_id, success=True)
|
||||
await send_response(response)
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Error handling {msg_type}: {e}", exc_info=True)
|
||||
error_response = ErrorResponse(request_id=request_id, error_code="INTERNAL_ERROR", error_message=str(e))
|
||||
await send_response(error_response)
|
||||
|
||||
except WebSocketDisconnect:
|
||||
logger.info(f"WebSocket disconnected - channel_id: {channel_id}")
|
||||
registry.websocket = None
|
||||
gateway.unregister_channel(channel_id)
|
||||
except Exception as e:
|
||||
logger.error(f"WebSocket error: {e}", exc_info=True)
|
||||
registry.websocket = None
|
||||
gateway.unregister_channel(channel_id)
|
||||
|
||||
@app.post("/api/upload")
|
||||
async def upload_file(file: UploadFile = File(...)):
|
||||
"""Upload a file and return its URL."""
|
||||
try:
|
||||
# Generate unique filename
|
||||
file_extension = Path(file.filename).suffix if file.filename else ""
|
||||
unique_filename = f"{uuid.uuid4()}{file_extension}"
|
||||
file_path = UPLOAD_DIR / unique_filename
|
||||
|
||||
# Save file
|
||||
with open(file_path, "wb") as buffer:
|
||||
shutil.copyfileobj(file.file, buffer)
|
||||
|
||||
# Return URL (relative to backend)
|
||||
file_url = f"/uploads/{unique_filename}"
|
||||
logger.info(f"File uploaded: {file.filename} -> {file_url}")
|
||||
|
||||
return {
|
||||
"url": file_url,
|
||||
"filename": file.filename,
|
||||
"size": file_path.stat().st_size
|
||||
}
|
||||
except Exception as e:
|
||||
logger.error(f"File upload error: {e}", exc_info=True)
|
||||
raise HTTPException(status_code=500, detail=str(e))
|
||||
|
||||
@app.get("/healthz")
|
||||
async def health():
|
||||
return {"status": "ok"}
|
||||
|
||||
# Background task to simulate backend updates (optional, for demo)
|
||||
async def simulate_backend_updates():
|
||||
while True:
|
||||
await asyncio.sleep(5)
|
||||
if registry.websocket:
|
||||
# Example: could add/modify orders here
|
||||
await registry.push_all()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
import uvicorn
|
||||
uvicorn.run(app, host="0.0.0.0", port=config["www_port"])
|
||||
21
backend/src/schema/chart_state.py
Normal file
21
backend/src/schema/chart_state.py
Normal file
@@ -0,0 +1,21 @@
|
||||
from typing import Optional
|
||||
from pydantic import BaseModel, Field
|
||||
|
||||
|
||||
class ChartState(BaseModel):
|
||||
"""Tracks the user's current chart view state.
|
||||
|
||||
This state is synchronized between the frontend and backend to allow
|
||||
the AI agent to understand what the user is currently viewing.
|
||||
"""
|
||||
|
||||
# Current symbol being viewed (e.g., "BINANCE:BTC/USDT", "BINANCE:ETH/USDT")
|
||||
symbol: str = Field(default="BINANCE:BTC/USDT", description="Current trading pair symbol")
|
||||
|
||||
# Time range currently visible on chart (Unix timestamps in seconds)
|
||||
# These represent the leftmost and rightmost visible candle times
|
||||
start_time: Optional[int] = Field(default=None, description="Start time of visible range (Unix timestamp in seconds)")
|
||||
end_time: Optional[int] = Field(default=None, description="End time of visible range (Unix timestamp in seconds)")
|
||||
|
||||
# Optional: Chart interval/resolution
|
||||
interval: str = Field(default="15", description="Chart interval (e.g., '1', '5', '15', '60', 'D')")
|
||||
140
backend/src/schema/order_spec.py
Normal file
140
backend/src/schema/order_spec.py
Normal file
@@ -0,0 +1,140 @@
|
||||
from enum import StrEnum
|
||||
from typing import Annotated
|
||||
|
||||
from pydantic import BaseModel, Field, BeforeValidator, PlainSerializer
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Scalar coercion helpers
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
def _to_int(v: int | str) -> int:
|
||||
return int(v, 0) if isinstance(v, str) else int(v)
|
||||
|
||||
|
||||
def _to_float(v: float | int | str) -> float:
|
||||
return float(v)
|
||||
|
||||
|
||||
_int_to_str = PlainSerializer(str, return_type=str, when_used="json")
|
||||
_float_to_str = PlainSerializer(str, return_type=str, when_used="json")
|
||||
|
||||
# Always stored as Python int; accepts int or string on input; serialises to string in JSON.
|
||||
type Uint8 = Annotated[int, BeforeValidator(_to_int), _int_to_str]
|
||||
type Uint16 = Annotated[int, BeforeValidator(_to_int), _int_to_str]
|
||||
type Uint24 = Annotated[int, BeforeValidator(_to_int), _int_to_str]
|
||||
type Uint32 = Annotated[int, BeforeValidator(_to_int), _int_to_str]
|
||||
type Uint64 = Annotated[int, BeforeValidator(_to_int), _int_to_str]
|
||||
type Uint256 = Annotated[int, BeforeValidator(_to_int), _int_to_str]
|
||||
type Float = Annotated[float, BeforeValidator(_to_float), _float_to_str]
|
||||
|
||||
ETH_ADDRESS_PATTERN = r"^0x[0-9a-fA-F]{40}$"
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Enums
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
class Exchange(StrEnum):
|
||||
UNISWAP_V2 = "UniswapV2"
|
||||
UNISWAP_V3 = "UniswapV3"
|
||||
|
||||
|
||||
class OcoMode(StrEnum):
|
||||
NO_OCO = "NO_OCO"
|
||||
CANCEL_ON_PARTIAL_FILL = "CANCEL_ON_PARTIAL_FILL"
|
||||
CANCEL_ON_COMPLETION = "CANCEL_ON_COMPLETION"
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Supporting models
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
class Route(BaseModel):
|
||||
model_config = {"extra": "forbid"}
|
||||
|
||||
exchange: Exchange
|
||||
fee: Uint24 = Field(description="Pool fee tier; also used as maxFee on UniswapV3")
|
||||
|
||||
|
||||
class Line(BaseModel):
|
||||
"""Price line: price = intercept + slope * time. Both zero means line is disabled."""
|
||||
|
||||
model_config = {"extra": "forbid"}
|
||||
|
||||
intercept: Float
|
||||
slope: Float
|
||||
|
||||
|
||||
class Tranche(BaseModel):
|
||||
model_config = {"extra": "forbid"}
|
||||
|
||||
fraction: Uint16 = Field(description="Fraction of total order amount; MAX_FRACTION (65535) = 100%")
|
||||
startTimeIsRelative: bool
|
||||
endTimeIsRelative: bool
|
||||
minIsBarrier: bool = Field(description="Not yet supported")
|
||||
maxIsBarrier: bool = Field(description="Not yet supported")
|
||||
marketOrder: bool = Field(
|
||||
description="If true, min/max lines ignored; minLine intercept treated as max slippage"
|
||||
)
|
||||
minIsRatio: bool
|
||||
maxIsRatio: bool
|
||||
rateLimitFraction: Uint16 = Field(description="Max fraction of this tranche's amount per rate-limited execution")
|
||||
rateLimitPeriod: Uint24 = Field(description="Seconds between rate limit resets")
|
||||
startTime: Uint32 = Field(description="Unix timestamp; 0 (DISTANT_PAST) effectively disables")
|
||||
endTime: Uint32 = Field(description="Unix timestamp; 4294967295 (DISTANT_FUTURE) effectively disables")
|
||||
minLine: Line = Field(description="Traditional limit order constraint; can be diagonal")
|
||||
maxLine: Line = Field(description="Upper price boundary (too-good-a-price guard)")
|
||||
|
||||
|
||||
class TrancheStatus(BaseModel):
|
||||
model_config = {"extra": "forbid"}
|
||||
|
||||
filled: Uint256 = Field(description="Amount filled by this tranche")
|
||||
activationTime: Uint32 = Field(description="Earliest time this tranche can execute; 0 = not yet concrete")
|
||||
startTime: Uint32 = Field(description="Concrete start timestamp")
|
||||
endTime: Uint32 = Field(description="Concrete end timestamp")
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Order models
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
class SwapOrder(BaseModel):
|
||||
model_config = {"extra": "forbid"}
|
||||
|
||||
tokenIn: str = Field(pattern=ETH_ADDRESS_PATTERN, description="ERC-20 input token address")
|
||||
tokenOut: str = Field(pattern=ETH_ADDRESS_PATTERN, description="ERC-20 output token address")
|
||||
route: Route
|
||||
amount: Uint256 = Field(description="Maximum quantity to fill")
|
||||
minFillAmount: Uint256 = Field(description="Minimum tranche amount before tranche is considered complete")
|
||||
amountIsInput: bool = Field(description="true = amount is tokenIn quantity; false = tokenOut")
|
||||
outputDirectlyToOwner: bool = Field(description="true = proceeds go to vault owner; false = vault")
|
||||
inverted: bool = Field(description="false = tokenIn/tokenOut price direction (Uniswap natural)")
|
||||
conditionalOrder: Uint64 = Field(
|
||||
description="NO_CONDITIONAL_ORDER = 2^64-1; high bit set = relative index within placement group"
|
||||
)
|
||||
tranches: list[Tranche] = Field(min_length=1)
|
||||
|
||||
|
||||
class OcoGroup(BaseModel):
|
||||
model_config = {"extra": "forbid"}
|
||||
|
||||
mode: OcoMode
|
||||
orders: list[SwapOrder] = Field(min_length=1)
|
||||
|
||||
|
||||
class SwapOrderStatus(BaseModel):
|
||||
model_config = {"extra": "forbid"}
|
||||
|
||||
order: SwapOrder
|
||||
fillFeeHalfBps: Uint8 = Field(description="Fill fee in half-bps (1/20000); max 255 = 1.275%")
|
||||
canceled: bool = Field(description="If true, order is canceled regardless of cancelAllIndex")
|
||||
startTime: Uint32 = Field(description="Earliest block.timestamp at which order may execute")
|
||||
ocoGroup: Uint64 = Field(description="Index into ocoGroups; NO_OCO_INDEX = 2^64-1")
|
||||
originalOrder: Uint64 = Field(description="Index of the original order in the orders array")
|
||||
startPrice: Uint256 = Field(description="Price at order start")
|
||||
filled: Uint256 = Field(description="Total amount filled so far")
|
||||
trancheStatus: list[TrancheStatus]
|
||||
|
||||
|
||||
26
backend/src/sync/protocol.py
Normal file
26
backend/src/sync/protocol.py
Normal file
@@ -0,0 +1,26 @@
|
||||
from typing import Any, Dict, List, Literal, Union
|
||||
|
||||
from pydantic import BaseModel
|
||||
|
||||
|
||||
class SnapshotMessage(BaseModel):
|
||||
type: Literal["snapshot"] = "snapshot"
|
||||
store: str
|
||||
seq: int
|
||||
state: Dict[str, Any]
|
||||
|
||||
class PatchMessage(BaseModel):
|
||||
type: Literal["patch"] = "patch"
|
||||
store: str
|
||||
seq: int
|
||||
patch: List[Dict[str, Any]]
|
||||
|
||||
class HelloMessage(BaseModel):
|
||||
type: Literal["hello"] = "hello"
|
||||
seqs: Dict[str, int]
|
||||
|
||||
# Union type for all messages from backend to frontend
|
||||
BackendMessage = Union[SnapshotMessage, PatchMessage]
|
||||
|
||||
# Union type for all messages from frontend to backend
|
||||
FrontendMessage = Union[HelloMessage, PatchMessage]
|
||||
174
backend/src/sync/registry.py
Normal file
174
backend/src/sync/registry.py
Normal file
@@ -0,0 +1,174 @@
|
||||
from collections import deque
|
||||
from typing import Any, Dict, List, Optional, Tuple, Deque
|
||||
|
||||
import jsonpatch
|
||||
from pydantic import BaseModel
|
||||
|
||||
from sync.protocol import SnapshotMessage, PatchMessage
|
||||
|
||||
|
||||
class SyncEntry:
|
||||
def __init__(self, model: BaseModel, store_name: str, history_size: int = 50):
|
||||
self.model = model
|
||||
self.store_name = store_name
|
||||
self.seq = 0
|
||||
self.last_snapshot = model.model_dump(mode="json")
|
||||
self.history: Deque[Tuple[int, List[Dict[str, Any]]]] = deque(maxlen=history_size)
|
||||
|
||||
def compute_patch(self) -> Optional[List[Dict[str, Any]]]:
|
||||
current_state = self.model.model_dump(mode="json")
|
||||
patch = jsonpatch.make_patch(self.last_snapshot, current_state)
|
||||
if not patch.patch:
|
||||
return None
|
||||
return patch.patch
|
||||
|
||||
def commit_patch(self, patch: List[Dict[str, Any]]):
|
||||
self.seq += 1
|
||||
self.history.append((self.seq, patch))
|
||||
self.last_snapshot = self.model.model_dump(mode="json")
|
||||
|
||||
def catchup_patches(self, since_seq: int) -> Optional[List[Tuple[int, List[Dict[str, Any]]]]]:
|
||||
if since_seq == self.seq:
|
||||
return []
|
||||
|
||||
# Check if all patches from since_seq + 1 to self.seq are in history
|
||||
if not self.history or self.history[0][0] > since_seq + 1:
|
||||
return None
|
||||
|
||||
result = []
|
||||
for seq, patch in self.history:
|
||||
if seq > since_seq:
|
||||
result.append((seq, patch))
|
||||
return result
|
||||
|
||||
class SyncRegistry:
|
||||
def __init__(self):
|
||||
self.entries: Dict[str, SyncEntry] = {}
|
||||
self.websocket: Optional[Any] = None # Expecting a FastAPI WebSocket or similar
|
||||
|
||||
def register(self, model: BaseModel, store_name: str):
|
||||
self.entries[store_name] = SyncEntry(model, store_name)
|
||||
|
||||
async def push_all(self):
|
||||
import logging
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
if not self.websocket:
|
||||
logger.warning("push_all: No websocket connected, cannot push updates")
|
||||
return
|
||||
|
||||
logger.info(f"push_all: Processing {len(self.entries)} store entries")
|
||||
for entry in self.entries.values():
|
||||
patch = entry.compute_patch()
|
||||
if patch:
|
||||
logger.info(f"push_all: Found patch for store '{entry.store_name}': {patch}")
|
||||
entry.commit_patch(patch)
|
||||
msg = PatchMessage(store=entry.store_name, seq=entry.seq, patch=patch)
|
||||
logger.info(f"push_all: Sending patch message for '{entry.store_name}' seq={entry.seq}")
|
||||
await self.websocket.send_json(msg.model_dump(mode="json"))
|
||||
logger.info(f"push_all: Patch sent successfully for '{entry.store_name}'")
|
||||
else:
|
||||
logger.debug(f"push_all: No changes detected for store '{entry.store_name}'")
|
||||
|
||||
async def sync_client(self, client_seqs: Dict[str, int]):
|
||||
if not self.websocket:
|
||||
return
|
||||
|
||||
for store_name, entry in self.entries.items():
|
||||
client_seq = client_seqs.get(store_name, -1)
|
||||
patches = entry.catchup_patches(client_seq)
|
||||
|
||||
if patches is not None:
|
||||
# Replay patches
|
||||
for seq, patch in patches:
|
||||
msg = PatchMessage(store=store_name, seq=seq, patch=patch)
|
||||
await self.websocket.send_json(msg.model_dump(mode="json"))
|
||||
else:
|
||||
# Send full snapshot
|
||||
msg = SnapshotMessage(
|
||||
store=store_name,
|
||||
seq=entry.seq,
|
||||
state=entry.model.model_dump(mode="json")
|
||||
)
|
||||
await self.websocket.send_json(msg.model_dump(mode="json"))
|
||||
|
||||
async def apply_client_patch(self, store_name: str, client_base_seq: int, patch: List[Dict[str, Any]]):
|
||||
import logging
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
logger.info(f"apply_client_patch: store={store_name}, client_base_seq={client_base_seq}, patch={patch}")
|
||||
|
||||
entry = self.entries.get(store_name)
|
||||
if not entry:
|
||||
logger.warning(f"apply_client_patch: Store '{store_name}' not found in registry")
|
||||
return
|
||||
|
||||
logger.info(f"apply_client_patch: Current backend seq={entry.seq}")
|
||||
|
||||
if client_base_seq == entry.seq:
|
||||
# No conflict
|
||||
logger.info("apply_client_patch: No conflict - applying patch directly")
|
||||
current_state = entry.model.model_dump(mode="json")
|
||||
logger.info(f"apply_client_patch: Current state before patch: {current_state}")
|
||||
new_state = jsonpatch.apply_patch(current_state, patch)
|
||||
logger.info(f"apply_client_patch: New state after patch: {new_state}")
|
||||
self._update_model(entry.model, new_state)
|
||||
|
||||
entry.commit_patch(patch)
|
||||
logger.info(f"apply_client_patch: Patch committed, new seq={entry.seq}")
|
||||
# Don't broadcast back to client - they already have this change
|
||||
# Broadcasting would cause an infinite loop
|
||||
logger.info("apply_client_patch: Not broadcasting back to originating client")
|
||||
|
||||
elif client_base_seq < entry.seq:
|
||||
# Conflict! Frontend wins.
|
||||
# 1. Get backend patches since client_base_seq
|
||||
backend_patches = []
|
||||
for seq, p in entry.history:
|
||||
if seq > client_base_seq:
|
||||
backend_patches.append(p)
|
||||
|
||||
# 2. Apply frontend patch first to the state at client_base_seq
|
||||
# But we only have the current authoritative model.
|
||||
# "Apply the frontend patch first to the model (frontend wins)"
|
||||
# "Re-apply the backend deltas that do not overlap the frontend's changed paths on top"
|
||||
|
||||
# Let's get the state as it was at client_base_seq if possible?
|
||||
# No, history only has patches.
|
||||
|
||||
# Alternative: Apply frontend patch to current model.
|
||||
# Then re-apply backend patches, but discard parts that overlap.
|
||||
|
||||
frontend_paths = {p['path'] for p in patch}
|
||||
|
||||
current_state = entry.model.model_dump(mode="json")
|
||||
# Apply frontend patch
|
||||
new_state = jsonpatch.apply_patch(current_state, patch)
|
||||
|
||||
# Re-apply backend patches that don't overlap
|
||||
for b_patch in backend_patches:
|
||||
filtered_b_patch = [op for op in b_patch if op['path'] not in frontend_paths]
|
||||
if filtered_b_patch:
|
||||
new_state = jsonpatch.apply_patch(new_state, filtered_b_patch)
|
||||
|
||||
self._update_model(entry.model, new_state)
|
||||
|
||||
# Commit the result as a single new patch
|
||||
# We need to compute what changed from last_snapshot to new_state
|
||||
final_patch = jsonpatch.make_patch(entry.last_snapshot, new_state).patch
|
||||
if final_patch:
|
||||
entry.commit_patch(final_patch)
|
||||
# Broadcast resolved state as snapshot to converge
|
||||
if self.websocket:
|
||||
msg = SnapshotMessage(
|
||||
store=entry.store_name,
|
||||
seq=entry.seq,
|
||||
state=entry.model.model_dump(mode="json")
|
||||
)
|
||||
await self.websocket.send_json(msg.model_dump(mode="json"))
|
||||
|
||||
def _update_model(self, model: BaseModel, new_data: Dict[str, Any]):
|
||||
# Update model using model_validate for potentially nested models
|
||||
new_model = model.__class__.model_validate(new_data)
|
||||
for field in model.model_fields:
|
||||
setattr(model, field, getattr(new_model, field))
|
||||
0
backend/tests/__init__.py
Normal file
0
backend/tests/__init__.py
Normal file
54
backend/tests/test_websocket.py
Normal file
54
backend/tests/test_websocket.py
Normal file
@@ -0,0 +1,54 @@
|
||||
import asyncio
|
||||
import json
|
||||
import websockets
|
||||
import pytest
|
||||
from pydantic import BaseModel
|
||||
|
||||
async def test_websocket_sync():
|
||||
uri = "ws://localhost:8000/ws"
|
||||
async with websockets.connect(uri) as websocket:
|
||||
# 1. Send hello
|
||||
hello = {
|
||||
"type": "hello",
|
||||
"seqs": {}
|
||||
}
|
||||
await websocket.send(json.dumps(hello))
|
||||
|
||||
# 2. Receive snapshots
|
||||
# Expecting TraderState and StrategyState
|
||||
responses = []
|
||||
for _ in range(2):
|
||||
resp = await websocket.recv()
|
||||
responses.append(json.loads(resp))
|
||||
|
||||
assert any(r["store"] == "TraderState" for r in responses)
|
||||
assert any(r["store"] == "StrategyState" for r in responses)
|
||||
|
||||
# 3. Send a patch for TraderState
|
||||
trader_resp = next(r for r in responses if r["store"] == "TraderState")
|
||||
current_seq = trader_resp["seq"]
|
||||
|
||||
patch_msg = {
|
||||
"type": "patch",
|
||||
"store": "TraderState",
|
||||
"seq": current_seq,
|
||||
"patch": [{"op": "replace", "path": "/status", "value": "busy"}]
|
||||
}
|
||||
await websocket.send(json.dumps(patch_msg))
|
||||
|
||||
# 4. Receive confirmation patch
|
||||
confirm_resp = await websocket.recv()
|
||||
confirm_json = json.loads(confirm_resp)
|
||||
assert confirm_json["type"] == "patch"
|
||||
assert confirm_json["store"] == "TraderState"
|
||||
assert confirm_json["seq"] == current_seq + 1
|
||||
assert confirm_json["patch"][0]["value"] == "busy"
|
||||
|
||||
if __name__ == "__main__":
|
||||
# This script requires the server to be running:
|
||||
# PYTHONPATH=backend/src python3 backend/src/main.py
|
||||
try:
|
||||
asyncio.run(test_websocket_sync())
|
||||
print("Test passed!")
|
||||
except Exception as e:
|
||||
print(f"Test failed: {e}")
|
||||
4
bin/build
Executable file
4
bin/build
Executable file
@@ -0,0 +1,4 @@
|
||||
#!/bin/bash
|
||||
|
||||
docker build -f deploy/Dockerfile -t dexorder-ai:latest .
|
||||
# todo push to archive
|
||||
36
bin/charting_library_update
Executable file
36
bin/charting_library_update
Executable file
@@ -0,0 +1,36 @@
|
||||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
|
||||
REMOTE_NAME="tradingview-charting"
|
||||
REMOTE_URL="git@github.com:tradingview/charting_library.git"
|
||||
PREFIX="web/public/charting_library"
|
||||
BRANCH="master"
|
||||
|
||||
# Detect the default branch if master doesn't exist
|
||||
echo "Adding remote '$REMOTE_NAME'..."
|
||||
if git remote get-url "$REMOTE_NAME" &>/dev/null; then
|
||||
echo "Remote '$REMOTE_NAME' already exists, skipping."
|
||||
else
|
||||
git remote add "$REMOTE_NAME" "$REMOTE_URL"
|
||||
fi
|
||||
|
||||
echo "Fetching from $REMOTE_URL (this may take a moment)..."
|
||||
git fetch "$REMOTE_NAME" "$BRANCH"
|
||||
|
||||
if [ -d "$PREFIX" ]; then
|
||||
echo "'$PREFIX' already exists — pulling latest changes..."
|
||||
git subtree pull \
|
||||
--prefix="$PREFIX" \
|
||||
"$REMOTE_NAME" "$BRANCH" \
|
||||
--squash \
|
||||
-m "chore: update charting_library from tradingview upstream"
|
||||
else
|
||||
echo "Adding '$PREFIX' for the first time..."
|
||||
git subtree add \
|
||||
--prefix="$PREFIX" \
|
||||
"$REMOTE_NAME/$BRANCH":charting_library \
|
||||
--squash \
|
||||
-m "chore: add charting_library from tradingview/charting_library"
|
||||
fi
|
||||
|
||||
echo "Done. Files are at: $PREFIX"
|
||||
3
deploy/Dockerfile-backend
Normal file
3
deploy/Dockerfile-backend
Normal file
@@ -0,0 +1,3 @@
|
||||
FROM python:3.14-alpine
|
||||
|
||||
COPY python/src /app/src
|
||||
0
deploy/Dockerfile-web
Normal file
0
deploy/Dockerfile-web
Normal file
0
deploy/deployment.yaml
Normal file
0
deploy/deployment.yaml
Normal file
21
doc/data.md
Normal file
21
doc/data.md
Normal file
@@ -0,0 +1,21 @@
|
||||
# Data Sources and ETL
|
||||
|
||||
We'll use Pandas and ArcticDB as our data foundation. This gives easy access to numpy and a wide spectrum of Python analysis libraries.
|
||||
|
||||
ArcticDB
|
||||
[ArcticDB](https://arcticdb.com/)
|
||||
We'll use unstructured dynamic schemas for flexibility and ad-hoc adjustment by the assistant.
|
||||
|
||||
## Canonical Formats
|
||||
* OHLCV
|
||||
* columns
|
||||
* open_time high_time etc optional columns
|
||||
* Tick Data (later not now)
|
||||
* Order Book Data (later not now)
|
||||
|
||||
## Symbol Definition
|
||||
Symbols must follow a canonical formatting that provides a unique string identifier:
|
||||
|
||||
type|...(type dependent)...
|
||||
ohlc|exchange:base/quote
|
||||
|
||||
65
doc/design.md
Normal file
65
doc/design.md
Normal file
@@ -0,0 +1,65 @@
|
||||
# AI-Native Trading Platform
|
||||
|
||||
## Summary
|
||||
|
||||
A full-stack, AI-first algorithmic trading platform in which LLMs act as strategy *authors* rather than strategy *executors*. Human traders express intent through natural language, chart drawings, and annotated support/resistance levels via chat or TradingView; an LLM agent interprets this intent and composes a fully self-contained **strategy executable** — a versioned, schema-validated artifact that runs deterministically with zero LLM involvement at runtime or in backtesting.
|
||||
|
||||
The execution architecture is split into two nested kernels. The **strategy kernel** owns the complete mechanics of a strategy: signal DAG evaluation, position state, risk rules, and regime awareness, operating at strategy latency. It drives the **order kernel** — a minimal, fully-specified order state machine designed for deterministic, low-latency execution, in principle deployable to FPGA or kernel-bypass hardware. The two kernels communicate across a hard schema boundary, keeping the hot path free of any high-level logic.
|
||||
|
||||
Data is handled through an abstract **feed specification** that treats historical and realtime, structured and unstructured sources uniformly. All signal computation — including NLP-based sentiment and on-chain analytics — uses local models only; the LLM is strictly a design-time tool.
|
||||
|
||||
The platform is designed to be run **locally by the trader** for execution security, while strategy generation may be cloud-assisted. It leverages the Python data science ecosystem throughout, integrates with TradingView for chart-driven strategy authoring, and exposes multiple interaction surfaces including chat bots and JupyterLab notebooks. The local executable may still have strong dependencies on a centralized data cluster and logging facility.
|
||||
|
||||
## Data
|
||||
|
||||
* **Data source spec** — Abstract interface for historical (bulk/batch) and incremental (realtime) data, supporting both push and pull models, fully async. Sources are typed and versioned; any conforming adapter (REST, WebSocket, FIX, file, queue) plugs in identically.
|
||||
* **ETL pipeline** — Reusable transform/load tooling for normalizing raw source data into platform schemas, and as agent-callable tools for composing bespoke derived series on demand.
|
||||
* **Common schemas** — Canonical normalized forms: OHLCV, tick, order book (L1/L2/L3), trade prints, funding rates, open interest. Unstructured feeds (news, social, on-chain) carry a typed envelope with a payload and a platform-standard timestamp/symbol context.
|
||||
* **Feed registry** — Central catalog of available feeds with their schemas, latency class, and asset coverage. Both the agent layer and the execution kernel subscribe by feed ID, decoupled from transport.
|
||||
|
||||
## Indicators & Signals
|
||||
|
||||
* **Standard indicator library** — Common indicators (moving averages, VWAP, RSI, ATR, Bollinger, volume profile, etc.) implemented against the canonical schema. Stateless functions and stateful streaming variants both available.
|
||||
* **Custom signals in Python** — Arbitrary user/agent-defined signal nodes. Must conform to a standard `SignalNode` interface (inputs, outputs, params, `evaluate()`) so they are composable in the signal DAG and serializable into strategy executables.
|
||||
* **Unstructured signal pipeline** — Adapters that transform unstructured feeds into scalar or categorical signal outputs (e.g. FinBERT sentiment → float, on-chain anomaly detector → bool). Runs local models only; no LLM at signal evaluation time.
|
||||
|
||||
## Strategy Kernel
|
||||
|
||||
The outermost execution layer. Owns the complete mechanics of a strategy: signal DAG evaluation, position and risk state, regime awareness, and re-parameterization of the order kernel. Operates at human/strategy latency (milliseconds to seconds).
|
||||
|
||||
* **Signal DAG** — Directed acyclic graph of signal nodes wired to feed subscriptions. Evaluated incrementally on new data. Nodes are typed, versioned, and serializable.
|
||||
* **Strategy state machine** — Tracks lifecycle: `IDLE → LOOKING → ENTERED → MANAGING → EXITED`. Transitions driven by signal DAG outputs and risk constraints.
|
||||
* **Risk layer** — Position sizing, exposure limits, drawdown circuit breakers, correlation guards. Evaluated before any order is emitted downward to the order kernel.
|
||||
* **Re-parameterization interface** — The strategy kernel may update order kernel parameters (price, size, urgency, validity) in response to new signal outputs without tearing down open orders — a clean boundary between strategic intent and mechanical execution.
|
||||
* **Strategy executable format** — The complete strategy (DAG topology, parameters, risk rules, feed subscriptions) is serialized to a self-contained artifact (YAML + optional Python modules). Generated by the agent layer; runnable with zero LLM dependency.
|
||||
* **Strategy Log** — A structured, append-only log of strategy events, including signal outputs, risk evaluations, and order parameter changes. Facilitates debugging, backtesting, and compliance auditing.
|
||||
|
||||
## Order Kernel
|
||||
|
||||
The innermost execution layer. Represents a single, fully specified order intent and manages its lifecycle mechanically. Designed for deterministic, low-latency operation — in principle implementable in an FPGA or a kernel-bypass network stack.
|
||||
|
||||
* **Order specification** — Fully parameterized: symbol, side, type (market/limit/stop/conditional), price(s), size, time-in-force, validity window, venue routing hint. No ambiguity; all fields resolved before submission.
|
||||
* **Order lifecycle** — State machine: `PENDING → SUBMITTED → PARTIALLY_FILLED → FILLED | CANCELLED | REJECTED`. Transitions driven by exchange acknowledgements and fill reports.
|
||||
* **Timer primitives** — Deadline timers (cancel-on-expire), heartbeat timers (re-quote), and interval timers (TWAP/VWAP slice scheduling). All timers are pure data, evaluatable without process context.
|
||||
* **Venue adapter interface** — Thin, typed interface to exchange connectivity (FIX, REST, WebSocket, on-chain). The order kernel emits a normalized order; the adapter translates to venue wire format.
|
||||
* **FPGA / low-latency boundary** — The order spec and lifecycle state machine are designed with a hard schema so they can be frozen and handed off to a hardware execution path. The strategy kernel communicates to this boundary via a defined message contract, not shared memory or function calls.
|
||||
* **Order Log** — A structured, append-only log of order events, including submission, fill, and cancellation details. Facilitates debugging, backtesting, and compliance auditing.
|
||||
* **Credentials Store** — Secure storage for API keys, wallet keys, secrets, and other sensitive information. Available only to the order kernel and no other layer.
|
||||
|
||||
## Agent Layer
|
||||
|
||||
The LLM-powered strategy authoring environment. Cloud-hosted or local. Produces strategy executables; never participates in live execution or backtesting hot paths.
|
||||
|
||||
* **Tool framework** — Typed, schema-validated tools callable by the LLM: `query_chart`, `compute_indicator`, `detect_sr_levels`, `fetch_news_sentiment`, `annotate_drawing`, `compose_signal_node`, `emit_strategy`. Each tool has a `to_executable_node()` method so its output can be frozen into the strategy artifact.
|
||||
* **TradingView integration** — Drawing/annotation export (trend lines, SR levels, zones, Fibonacci) ingested as structured JSON, interpreted by the agent into signal DAG nodes (e.g. `sr_proximity`, `trendline_cross`).
|
||||
* **Context manager** — Maintains the trader's working session: active symbol, timeframe, chart drawings, prior signal definitions, risk preferences. Persisted across turns; fed as structured context to each LLM call.
|
||||
* **Strategy compiler** — Takes the agent's composed tool outputs and renders a validated, schema-checked strategy executable. Validation errors are reflected back to the agent for self-correction before the artifact is finalized.
|
||||
* **Prompt/strategy versioning** — Every generated strategy artifact is version-controlled (git). The generating prompt, model version, and tool call trace are stored alongside the artifact for full auditability.
|
||||
|
||||
## Interaction Layer
|
||||
|
||||
How traders communicate with the system. Multiple surfaces; all feed the same agent layer.
|
||||
|
||||
* **Chat interface** — Discord, Telegram, or Slack bot. Accepts natural language, images of charts, TradingView drawing exports. Returns chart images, strategy summaries, backtest results. Primary low-friction UI.
|
||||
* **Notebook interface** — JupyterLab environment for power users. Full access to the data layer, indicator library, and agent tools. Chart generation (Plotly/Bokeh) for rich visual feedback, with outputs forwardable to chat channels.
|
||||
* **TradingView plugin** — Embeds into an existing TradingView-based website
|
||||
3
doc/libraries.md
Normal file
3
doc/libraries.md
Normal file
@@ -0,0 +1,3 @@
|
||||
ArcticDB
|
||||
[ArcticDB](https://arcticdb.com/)
|
||||
We'll use unstructured dynamic schemas.
|
||||
32
doc/mvp.md
Normal file
32
doc/mvp.md
Normal file
@@ -0,0 +1,32 @@
|
||||
# Minimum Viable Prototype
|
||||
|
||||
* Chat interface: slack/telegram/whatsapp etc
|
||||
* Agent loop
|
||||
* Memory
|
||||
* RAG
|
||||
* System Prompt
|
||||
* Soul / Mission
|
||||
* Current chart candles
|
||||
* TV Shapes
|
||||
* AI self-prompt
|
||||
* User Prompt
|
||||
* Agent tools
|
||||
* Edit strategy code
|
||||
* Read/Write TradingView shapes
|
||||
* Fetch data
|
||||
* TradingView Snapshot
|
||||
* Plotting
|
||||
* Cron
|
||||
* Docker, never host access
|
||||
* Edit AI self-prompt
|
||||
* One candle data source: Dexorder
|
||||
* Python data science stack with charts
|
||||
* Indicator library
|
||||
* Standard historical backtest
|
||||
* Strategy wrapper / sandbox
|
||||
* One execution engine: Dexorder
|
||||
* Website
|
||||
* TradingView interaction
|
||||
* Authentication
|
||||
* Settings / Prompts
|
||||
* Chat area with image support and zoom
|
||||
39
web/.gitignore
vendored
Normal file
39
web/.gitignore
vendored
Normal file
@@ -0,0 +1,39 @@
|
||||
# Logs
|
||||
logs
|
||||
*.log
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
pnpm-debug.log*
|
||||
lerna-debug.log*
|
||||
|
||||
node_modules
|
||||
.DS_Store
|
||||
dist
|
||||
dist-ssr
|
||||
coverage
|
||||
*.local
|
||||
|
||||
# Editor directories and files
|
||||
.vscode/*
|
||||
!.vscode/extensions.json
|
||||
.idea
|
||||
*.suo
|
||||
*.ntvs*
|
||||
*.njsproj
|
||||
*.sln
|
||||
*.sw?
|
||||
|
||||
*.tsbuildinfo
|
||||
|
||||
.eslintcache
|
||||
|
||||
# Cypress
|
||||
/cypress/videos/
|
||||
/cypress/screenshots/
|
||||
|
||||
# Vitest
|
||||
__screenshots__/
|
||||
|
||||
# Vite
|
||||
*.timestamp-*-*.mjs
|
||||
1
web/env.d.ts
vendored
Normal file
1
web/env.d.ts
vendored
Normal file
@@ -0,0 +1 @@
|
||||
/// <reference types="vite/client" />
|
||||
14
web/index.html
Normal file
14
web/index.html
Normal file
@@ -0,0 +1,14 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="" class="dark">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<link rel="icon" href="/favicon.ico">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Vite App</title>
|
||||
<script type="text/javascript" src="/charting_library/charting_library.standalone.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
<script type="module" src="/src/main.ts"></script>
|
||||
</body>
|
||||
</html>
|
||||
5808
web/package-lock.json
generated
Normal file
5808
web/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
43
web/package.json
Normal file
43
web/package.json
Normal file
@@ -0,0 +1,43 @@
|
||||
{
|
||||
"name": "web",
|
||||
"version": "0.0.0",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
"build": "run-p type-check \"build-only {@}\" --",
|
||||
"preview": "vite preview",
|
||||
"test:unit": "vitest",
|
||||
"build-only": "vite build",
|
||||
"type-check": "vue-tsc --build"
|
||||
},
|
||||
"dependencies": {
|
||||
"@primevue/themes": "^4.5.4",
|
||||
"fast-json-patch": "^3.1.1",
|
||||
"pinia": "^3.0.4",
|
||||
"primeicons": "^7.0.0",
|
||||
"primevue": "^4.5.4",
|
||||
"vue": "^3.5.29",
|
||||
"vue-advanced-chat": "^2.0.4",
|
||||
"vue-router": "^5.0.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@tsconfig/node24": "^24.0.4",
|
||||
"@types/jsdom": "^28.0.0",
|
||||
"@types/node": "^24.10.13",
|
||||
"@vitejs/plugin-vue": "^6.0.4",
|
||||
"@vitejs/plugin-vue-jsx": "^5.1.4",
|
||||
"@vue/test-utils": "^2.4.6",
|
||||
"@vue/tsconfig": "^0.8.1",
|
||||
"jsdom": "^28.1.0",
|
||||
"npm-run-all2": "^8.0.4",
|
||||
"typescript": "~5.9.3",
|
||||
"vite": "^7.3.1",
|
||||
"vite-plugin-vue-devtools": "^8.0.6",
|
||||
"vitest": "^4.0.18",
|
||||
"vue-tsc": "^3.2.5"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^20.19.0 || >=22.12.0"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
.checkbox-WcA5vXoU{align-self:start;font:inherit}.description-CQ7tC6Wp{margin-bottom:16px}
|
||||
@@ -0,0 +1 @@
|
||||
.checkbox-WcA5vXoU{align-self:start;font:inherit}.description-CQ7tC6Wp{margin-bottom:16px}
|
||||
@@ -0,0 +1 @@
|
||||
.button-LkmyTVRc{all:unset;display:flex;position:relative}.button-LkmyTVRc:before{border-radius:4px;content:none;height:100%;left:0;outline:var(--color-tv-blue-500) none 2px;outline-offset:-2px;pointer-events:none;position:absolute;top:0;width:100%}.button-LkmyTVRc:focus-visible:before{content:"";outline-style:solid}.button-LkmyTVRc.active-LkmyTVRc:before{outline-color:var(--color-border-primary-inverse)}.item-zwyEh4hn{align-items:flex-start;font-size:16px;padding-right:20px;white-space:normal}.label-zwyEh4hn{line-height:24px;overflow:visible}.labelRow-zwyEh4hn{margin-bottom:2px;margin-top:2px}.toolbox-zwyEh4hn{margin-top:3px}.wrapper-psOC5oyI{padding:10px 20px}.labelRow-psOC5oyI{line-height:20px;padding:0}.label-psOC5oyI{font-size:16px}.labelHint-psOC5oyI{line-height:17px}.labelOn-psOC5oyI+.labelHint-psOC5oyI{margin-top:0}
|
||||
@@ -0,0 +1 @@
|
||||
.button-LkmyTVRc{all:unset;display:flex;position:relative}.button-LkmyTVRc:before{border-radius:4px;content:none;height:100%;outline:var(--color-tv-blue-500) none 2px;outline-offset:-2px;pointer-events:none;position:absolute;right:0;top:0;width:100%}.button-LkmyTVRc:focus-visible:before{content:"";outline-style:solid}.button-LkmyTVRc.active-LkmyTVRc:before{outline-color:var(--color-border-primary-inverse)}.item-zwyEh4hn{align-items:flex-start;font-size:16px;padding-left:20px;white-space:normal}.label-zwyEh4hn{line-height:24px;overflow:visible}.labelRow-zwyEh4hn{margin-bottom:2px;margin-top:2px}.toolbox-zwyEh4hn{margin-top:3px}.wrapper-psOC5oyI{padding:10px 20px}.labelRow-psOC5oyI{line-height:20px;padding:0}.label-psOC5oyI{font-size:16px}.labelHint-psOC5oyI{line-height:17px}.labelOn-psOC5oyI+.labelHint-psOC5oyI{margin-top:0}
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -0,0 +1 @@
|
||||
[data-theme=light]{--_0-Zt87:var(--color-cold-gray-200)}[data-theme=dark]{--_0-Zt87:var(--color-cold-gray-650)}.wrap-vSb6C0Bj{bottom:0;cursor:default;pointer-events:all;position:absolute;right:0;top:0;width:8px;will-change:height}.wrap--horizontal-vSb6C0Bj{height:8px;left:0;right:0;top:auto;will-change:width}.bar-vSb6C0Bj{align-items:center;display:flex;justify-content:center;left:0;position:absolute;top:0;width:100%;will-change:height,transform}.bar-vSb6C0Bj .barInner-vSb6C0Bj{background-color:var(--_0-Zt87);border-radius:2px;height:calc(100% - 4px);width:4px}.bar-vSb6C0Bj .barInner--horizontal-vSb6C0Bj{height:4px;width:calc(100% - 4px)}.bar--horizontal-vSb6C0Bj{height:100%;left:0;top:0;width:auto;will-change:width,transform}.scrollWrap-FaOvTD2r{pointer-events:none;position:absolute;will-change:visibility}
|
||||
@@ -0,0 +1 @@
|
||||
[data-theme=light]{--_0-Zt87:var(--color-cold-gray-200)}[data-theme=dark]{--_0-Zt87:var(--color-cold-gray-650)}.wrap-vSb6C0Bj{bottom:0;cursor:default;left:0;pointer-events:all;position:absolute;top:0;width:8px;will-change:height}.wrap--horizontal-vSb6C0Bj{height:8px;left:0;right:0;top:auto;will-change:width}.bar-vSb6C0Bj{align-items:center;display:flex;justify-content:center;position:absolute;right:0;top:0;width:100%;will-change:height,transform}.bar-vSb6C0Bj .barInner-vSb6C0Bj{background-color:var(--_0-Zt87);border-radius:2px;height:calc(100% - 4px);width:4px}.bar-vSb6C0Bj .barInner--horizontal-vSb6C0Bj{height:4px;width:calc(100% - 4px)}.bar--horizontal-vSb6C0Bj{height:100%;right:0;top:0;width:auto;will-change:width,transform}.scrollWrap-FaOvTD2r{pointer-events:none;position:absolute;will-change:visibility}
|
||||
@@ -0,0 +1,47 @@
|
||||
"use strict";(self.webpackChunktradingview=self.webpackChunktradingview||[]).push([[1485],{87795:e=>{const t=55296,s=127995,i=127999,r=[776,2359,2359,2367,2367,2984,3007,3021,3633,3635,3648,3657,4352,4449,4520];function n(e){if("string"!=typeof e)throw new Error("string cannot be undefined or null");const t=[];let s=0,i=0;for(;s<e.length;)i+=o(s+i,e),c(e[s+i])&&i++,l(e[s+i])&&i++,h(e[s+i])&&i++,u(e[s+i])?i++:(t.push(e.substring(s,s+i)),s+=i,i=0);return t}function o(e,r){const n=r[e];if(!function(e){return e&&p(e[0].charCodeAt(0),t,56319)}(n)||e===r.length-1)return 1;const o=n+r[e+1];let l=r.substring(e+2,e+5);return a(o)&&a(l)||function(e){return p(d(e),s,i)}(l)?4:2}function a(e){return p(d(e),127462,127487)}function l(e){return"string"==typeof e&&p(e.charCodeAt(0),65024,65039)}function h(e){return"string"==typeof e&&p(e.charCodeAt(0),8400,8447)}function c(e){return"string"==typeof e&&-1!==r.indexOf(e.charCodeAt(0))}function u(e){return"string"==typeof e&&8205===e.charCodeAt(0)}function d(e){return(e.charCodeAt(0)-t<<10)+(e.charCodeAt(1)-56320)+65536}function p(e,t,s){return e>=t&&e<=s}e.exports=n,e.exports.substr=function(e,t,s){const i=n(e);if(void 0===t)return e;if(t>=i.length)return"";const r=i.length-t;let o=t+(void 0===s?r:s);return o>t+r&&(o=void 0),i.slice(t,o).join("")}},63002:(e,t,s)=>{s.d(t,{HHistBasedValuesProvider:()=>f});var i=s(50335),r=s(50151),n=s(49483),o=s(5471),a=s(78861),l=s(56265),h=s(99481),c=s(11946),u=s(53660);function d(e,t="",s=""){return{id:t,index:e,orderIndex:e,title:s,value:"",visible:!1}}const p=n.CheckMobile.any(),_=(0,l.getVolumeFormatter)();class f{constructor(e,t,s=!1){this._emptyValues=[],this._study=e,this._model=t,this._emptyTitles=s,void 0!==this._study.metaInfo().graphics.hhists&&this._emptyValues.push(d(0),d(1),d(2))}getItems(){return this._emptyValues}getValues(e){const t=this._emptyValues.map((e=>({...e})));t.forEach((e=>{e.visible=this._study.isVisible(),e.value=u.notAvailable}));const s=this._study.properties().childs().inputs.childs().volume.value();switch(s){case h.HHistVolumeMode.UpDown:this._emptyTitles||(t[0].title="Up",t[1].title="Down",t[2].title="Total");break;case h.HHistVolumeMode.Total:this._emptyTitles||(t[0].title="Total"),t[1].visible=!1,t[2].visible=!1;break;case h.HHistVolumeMode.Delta:this._emptyTitles||(t[0].title="Delta",t[1].title="Max(Up, Down)",t[2].title="Total")}const n=this._study.priceScale(),a=this._model.timeScale();if(null===n||n.isEmpty()||a.isEmpty()||this._hideValues())return t;if(null===e||!isFinite(e)){const s=this._study.data().last();if(null===s)return t;e=s.index}const l=this._model.crosshairSource(),c=l.price;if(!isFinite(l.y)&&null===(e=function(e,t){const s=e.visibleBarsStrictRange()?.lastBar();if(!s)return null;const i=t.data().search(s,o.PlotRowSearchMode.NearestLeft);return i?i.index:null}(this._model.timeScale(),this._model.mainSeries())))return t;const d=function(e,t,s,i){if(0===e.size)return null;if(!s){const e=(0,r.ensureNotNull)(i.data().valueAt(t));s=i.barFunction()(e)}const n=function(e,t){let s=null
|
||||
;return e.forEach(((e,i)=>{null!==i&&i<=t&&(null===s||i>s)&&(s=i)})),s}(e,t);if(null===n)return null;const o=e.get(n);if(!o||0===o.size)return null;return function(e,t){let s=null;return e.forEach((e=>{e.priceLow<=t&&t<e.priceHigh&&(s=e)})),s}(o,s)}(this._study.graphics().hhistsByTimePointIndex(),e,c,this._model.mainSeries());if(null===d)return t.forEach((e=>{e.value="0"})),t;const p=this._study.metaInfo().graphics.hhists;if(void 0===p)return t;if(void 0===p[d.styleId])return t;const f=this._study.properties().childs().graphics.childs().hhists?.childs()[d.styleId]?.childs(),m=e=>(0,i.isNumber)(e)?_.format(e):"";if(s!==h.HHistVolumeMode.Delta){if(d.rate.forEach(((e,s)=>{t[s].value=m(e),t[s].color=(0,r.ensureDefined)(f).colors[s].value()})),s===h.HHistVolumeMode.UpDown){const e=d.rate[0]+d.rate[1];t[2].value=m(e),t[2].color=(0,r.ensureDefined)(f).valuesColor.value()}}else{const e=d.rate[0]>d.rate[1]?0:1,s=(0,r.ensureDefined)(f).colors[e].value(),i=d.rate[0]+d.rate[1];[2*d.rate[e]-i,d.rate[e],i].forEach(((e,i)=>{t[i].value=m(e),t[i].color=s}))}return t}_hideValues(){return p&&(null===this._model.crosshairSource().pane||(0,c.isLineToolName)(a.tool.value())||null!==this._model.lineBeingEdited())}}},70954:(e,t,s)=>{s.d(t,{StudyBaseWindowView:()=>n});var i=s(40137),r=s(36313);class n extends i.DataWindowView{constructor(e,t){super(),this._invalidated=!0,this._study=e,this._model=t,this._valueProvider=this._createValuesProvider(e,t),this._items=this._valueProvider.getItems().map((e=>new i.DataWindowItem(e.id,e.title,"")))}update(e){"hover-change"!==e.type&&(this._invalidated=!0)}items(){return this._invalidated&&(this._updateImpl(),this._invalidated=!1),this._items}study(){return this._study}_updateImpl(){this._header=this._study.title(r.TitleDisplayTarget.DataWindow),this._title=this._study.title(r.TitleDisplayTarget.DataWindow,!1);const e=this._valueProvider.getValues(this._currentIndex());for(let t=0;t<e.length;++t){const s=e[t],i=this._items[t];i.setValue(s.value),i.setVisible(s.visible),i.setColor(s.color),i.setTitle(s.title)}}_currentIndex(){const e=this._model.crosshairSource().appliedIndex();return isNaN(e)?null:e}}},27909:(e,t,s)=>{s.d(t,{StudyChartFloatingTooltipView:()=>n});var i=s(87465),r=s(36313);class n{constructor(e,t){this._items=[],this._invalidated=!0,this._study=e,this._model=t}destroy(){}items(){return this._invalidated&&(this._updateImpl(),this._invalidated=!1),this._items}update(e){this._invalidated=!0}_updateImpl(){const e=this._study.chartFloatingTooltipValuesProvider(),t=this._model.crosshairSource().appliedIndex(),s=e.getValues(t),n=this._study.titleInParts(r.TitleDisplayTarget.StatusLine),o=n[0];let a="";if(n.length>1){const e=n[1];e.length>0&&(a=e.join(" "))}this._items=s.filter(i.notUndefined).filter((e=>e.visible)).map(((e,t)=>({titleText:0===t?o:"",titleInputs:0===t?a:"",value:e.value,valueColor:e.color})))}}},13212:(e,t,s)=>{s.d(t,{StudyDataWindowView:()=>a});var i=s(70954),r=s(71320),n=s(63002);class o{constructor(e,t){this._study=e,this._model=t,
|
||||
this._hhistBasedStudy=void 0!==e.metaInfo().graphics.hhists,this._valuesProvider=this._createValuesProvider(e,t)}getItems(){return this._valuesProvider.getItems()}getValues(e){const t=this._valuesProvider.getValues(e),s=e=>!!this._hhistBasedStudy||this._study.isPlotVisibleAt(e,2);for(const e of t)e.visible=e.visible&&s(e.id);return t}_createValuesProvider(e,t){return this._hhistBasedStudy?new n.HHistBasedValuesProvider(e,t):new r.StudyValuesProvider(e,t)}}class a extends i.StudyBaseWindowView{canShowItems(){const e=this._model.paneForSource(this._study);return!!e?.maximized().value()||this._model.panes().every((e=>!e.maximized().value()))}_createValuesProvider(e,t){return new o(e,t)}}},12965:(e,t,s)=>{s.d(t,{StudyStatusProvider:()=>n});var i=s(11542),r=(s(86252),s(35990));i.t(null,void 0,s(24077));class n extends r.StudyStatusProviderBase{sourceStatusText(){this._source.status();return super.sourceStatusText()}}},71320:(e,t,s)=>{s.d(t,{StudyValuesProvider:()=>v});var i=s(50335),r=s(49483),n=s(52859),o=s(37103),a=s(5471),l=s(11946),h=s(78861),c=s(4359),u=s(41425),d=s(63903),p=s(50151),_=s(53660),f=s(36313);const m=r.CheckMobile.any(),y=o.enabled("hide_last_na_study_output"),g=o.enabled("always_show_legend_values_on_mobile");class v{constructor(e,t,s,i=!0){this._emptyValues=[],this._colorProviders=new Map,this._study=e,this._model=t,this._searchNearestLeft=i,this._studyMetaInfo=this._study.metaInfo(),this._studyProperties=this._study.properties().childs(),this._isFundamental=!1;const r=this._studyMetaInfo.plots;if(!r)return;let n=0;r.forEach(((e,t)=>{if((0,c.isPlotWithTechnicalValues)(e))return;const i=e.id;this._emptyValues.push(function(e,t,s="",i=""){return{id:s,index:e,orderIndex:t,title:i,value:"",visible:!1}}(t,n++,i,s?"":this._study.guiPlotName(f.TitleDisplayTarget.StatusLine,i)));const r=(0,c.isOhlcPlot)(e)?e.target:i;this._colorProviders.set(r,(0,u.createStudyPlotColorProvider)(this._studyMetaInfo,this._study.properties(),r))}))}getItems(){return this._emptyValues}getPlotColor(e,t){const s=t[e+1];if(!(0,i.isNumber)(s))return"";const r=s>0;let n;const o=this._studyMetaInfo.plots[e];let a=o.id;const l=this._studyProperties;if((0,c.isOhlcPlot)(o))a=o.target||a,n=(0,p.ensureDefined)(l.ohlcPlots.childs()[a].childs().color).value();else if((0,c.isArrowsPlot)(o)){const e=(0,p.ensureDefined)(l.styles.childs()[a]);n=r?e.childs().colorup.value():e.childs().colordown.value()}else n=(0,p.ensureDefined)(l.styles.childs()[a]?.child("color")).value();let h=n;const u=this._colorProviders.get(a),d=u&&u.getPlotPointStyle(t);return d&&((0,c.isArrowsPlot)(o)?(r&&void 0!==d.colors[5]&&(h=d.colors[5]),r||void 0===d.colors[6]||(h=d.colors[6])):void 0!==d.colors[0]&&(h=d.colors[0])),"transparent"===h&&(h=n),h}getValues(e){const t=this._emptyValues.map((e=>({...e})));let s=null;const r=this._study.data().lastIndex(),o=this._studyProperties;if(null!==r){const e=this._searchNearestLeft?a.PlotRowSearchMode.NearestLeft:a.PlotRowSearchMode.Exact;for(const i of t){const t=o.styles.childs()[i.id]?.childs().display.value();if(0===t)continue
|
||||
;const n=this._study.nearestIndex(r,e,i.index+1);if(void 0===n)continue;const a=n+this._study.offset(i.id);s=null!==s?Math.max(a,s):a}}(null===e||null!==s&&e>s)&&(e=s);const l=this._hideValues(),h=this._study.isVisible()&&!l?_.notAvailable:"";for(const e of t)e.value=h;if(l)return t;y&&t.length&&(t[t.length-1].value="");const u=this._study.priceScale();if(!this._study.isVisible()||null===e||null===u||u.isEmpty()||this._model.timeScale().isEmpty())return t;const f={};for(const s of t){const t=s.id,l=(0,d.getPriceValueFormatterForStudy)(this._study,t),h=(0,p.ensureDefined)(o.styles.childs()[t]),u=h.childs().display.value();if(s.visible=0!==u,!s.visible)continue;const _=h.hasChild("plottype")?h.child("plottype")?.value():null,m=this._searchNearestLeft&&this._isFundamental&&(_===c.LineStudyPlotStyle.StepLine||_===c.LineStudyPlotStyle.StepLineWithDiamonds),y=s.index,g=e-this._study.offset(t),v=m||null!==r&&g>r?a.PlotRowSearchMode.NearestLeft:a.PlotRowSearchMode.Exact,S=this._study.nearestIndex(g,v);if(void 0===S)continue;let b=f[t];if(void 0===b&&(b=this._study.getMinFirstBarIndexForPlot(t),Number.isFinite(b)&&(f[t]=b)),b>S)continue;const P=this._study.data().last(),w=this._study.data().valueAt(S)||(null!==P?P.value:null);if(null===w)continue;const I=w[y+1];(0,i.isNumber)(I)&&(s.value=l(I),s.color=(0,n.resetTransparency)(this.getPlotColor(y,w)))}return t}_hideValues(){return g?(0,l.isLineToolName)(h.tool.value())||null!==this._model.lineBeingEdited():m&&(null===this._model.crosshairSource().pane||(0,l.isLineToolName)(h.tool.value())||null!==this._model.lineBeingEdited())}}},11485:(e,t,s)=>{s.r(t),s.d(t,{StudiesChunkName:()=>Yt,Study:()=>us,emptyPrecalculatedAutoscaleInfo:()=>qt,studyFormatter:()=>hs});var i=s(50279),r=s(90054),n=s(16738),o=s(15943);const a=e=>e instanceof Date,l=e=>null!=e&&"object"==typeof e,h=(e,...t)=>Object.prototype.hasOwnProperty.call(e,...t),c=e=>l(e)&&(e=>0===Object.keys(e).length)(e),u=(e,t)=>{if(e===t)return{};if(!l(e)||!l(t))return t;const s=Object.keys(e).reduce(((e,s)=>(h(t,s)||(e[s]=void 0),e)),Object.create(null));return a(e)||a(t)?e.valueOf()==t.valueOf()?{}:t:Object.keys(t).reduce(((s,i)=>{if(!h(e,i))return s[i]=t[i],s;const r=u(e[i],t[i]);return!c(r)||a(r)||!c(e[i])&&c(t[i])?(s[i]=r,s):s}),s)},d=u;var p=s(50151),_=s(87465),f=s(9343),m=s(11542),y=s(12217),g=s(62312);function v(e){const{name:t,group:s}=e;return t.length>0?`${s?`${s}.`:""}${t}`:void 0}var S=s(10341),b=s(22613),P=s(62773),w=s(48096),I=s(52859),x=s(82130),C=s(29806),V=s(67135),M=(s(2088),s(24062)),T=s(72187),A=s(19844),R=s(45530),O=s(5471),D=s(18330),B=s(70954),N=s(40472),F=s(71320),k=s(63002);class E{constructor(e,t,s,i){this._study=e,this._model=t,this._showStudyValues=i??t.properties().childs().paneProperties.childs().legendProperties.childs().showStudyValues,this._hhistBasedStudy=void 0!==e.metaInfo().graphics.hhists,this._valuesProvider=this._createValuesProvider(e,t,s)}getItems(){return this._valuesProvider.getItems()}getValues(e){
|
||||
const t=this._valuesProvider.getValues(e),s=this._study.properties(),i=this._showStudyValues.value()&&s.childs().showLegendValues.value(),r=e=>!!this._hhistBasedStudy||this._study.isPlotVisibleAt(e,8);for(const e of t)e.visible=e.visible&&i&&r(e.id);return t}_createValuesProvider(e,t,s){return this._hhistBasedStudy?new k.HHistBasedValuesProvider(e,t,s):new F.StudyValuesProvider(e,t,s)}}var L=s(4359);class H extends B.StudyBaseWindowView{constructor(e,t){super(e,t),this._showStudyValues=t.properties().childs().paneProperties.childs().legendProperties.childs().showStudyValues,this._showStudyValues.subscribe(this,(()=>this.update((0,N.sourceChangeEvent)(e.id()))));const s=this._study.properties();s.childs().showLegendValues.subscribe(this,(()=>this.update((0,N.sourceChangeEvent)(e.id()))));const i=this._study.metaInfo().plots,r=new Set;i.forEach((t=>{if((0,L.isOhlcPlot)(t)){const i=t.target;if(r.has(i))return;r.add(i),s.childs().ohlcPlots.childs()[i].childs().display.subscribe(this,(()=>this.update((0,N.sourceChangeEvent)(e.id()))))}else(0,L.isPlotSupportDisplay)(t)&&s.childs().styles.childs()[t.id]?.childs().display.subscribe(this,(()=>this.update((0,N.sourceChangeEvent)(e.id()))))}))}areValuesVisible(){return this._showStudyValues.value()}additional(){return null}destroy(){this._showStudyValues.unsubscribeAll(this);const e=this._study.properties();e.childs().showLegendValues.unsubscribeAll(this);const t=this._study.metaInfo().plots,s=new Set;t.forEach((t=>{if((0,L.isOhlcPlot)(t)){const i=t.target;if(s.has(i))return;s.add(i),e.childs().ohlcPlots.childs()[i].childs().display.unsubscribeAll(this)}else(0,L.isPlotSupportDisplay)(t)&&e.childs().styles.childs()[t.id]?.childs().display.unsubscribeAll(this)}))}_createValuesProvider(e,t){return new E(e,t)}}var W=s(78861),z=s(80671),U=s(60911),j=s(87163),G=s(98155),$=s(12965);class K{constructor(e,t,s){this._study=e,this._model=t,this._valuesProvider=new F.StudyValuesProvider(e,t,s)}getItems(){return this._valuesProvider.getItems()}getValues(e){const t=this._valuesProvider.getValues(e),s=e=>this._study.isPlotVisibleAt(e,8)||this._study.isPlotVisibleAt(e,1);for(const e of t)e.visible=e.visible&&s(e.id);return t}}var Y=s(36313),X=s(67455);function q(e,t){return e.studyId.localeCompare(t.studyId)}function J(e){const t=new Set,s=[];return e.forEach((e=>{t.has(e.studyId)||(t.add(e.studyId),s.push(e))})),s}function Z(e){const t=e.model().mainSeries();return{studyId:(0,p.ensureNotNull)(e.sourceId()),turnaround:e.turnaround(),sourceStudies:e.parentSources().filter((e=>e!==t)).map((e=>Z(e)))}}var Q=s(69422),ee=s(37103),te=s(94602),se=s(10307);class ie extends se.BitmapCoordinatesPaneRenderer{constructor(e){super(),this._data=e}hitTest(e){return null}_drawImpl(e){}_drawBackgroundImpl(e){const{context:t,horizontalPixelRatio:s,bitmapSize:i}=e,r=this._data;for(let e=0;e<r.items.length;++e){const n=r.items[e];if(null==n.color)continue;t.fillStyle=n.color;const o=Math.round(n.left*s)+1,a=Math.round(n.right*s);t.fillRect(o,0,a-o+1,i.height)}}}var re=s(41425),ne=s(17631)
|
||||
;class oe extends ne.StudyForceOverlayPlotView{constructor(e,t,s,i){super(t,s,i),this._items=[],this._invalidated=!0,this._isMarkersEnabled=ee.enabled("source_selection_markers"),this._study=e;const r=this._study.metaInfo().plots;for(let e=0;e<r.length;e++){const t=r[e];t.id===this._plotName&&(this._plotIndex=e,(0,p.assert)((0,L.isBgColorerPlot)(t),"Plot '"+this._plotName+"' is not a background colorer!"))}this._colorProvider=(0,re.createStudyPlotColorProvider)(e.metaInfo(),e.properties(),i)}items(){return this._items}update(e){"hover-change"!==e.type&&(this._invalidated=!0)}renderer(){if(1&~(0,p.ensureDefined)(this._study.properties().childs().styles.childs()[this._plotName]).childs().display.value())return null;if(!this._scalesReady())return null;this._invalidated&&(this._updateImpl(),this._invalidated=!1);const e={items:this._items},t=new te.CompositeRenderer;return t.append(new ie(e)),t}_scalesReady(){const e=this._model.timeScale(),t=this._priceScale();return e&&!e.isEmpty()&&null!==t&&!t.isEmpty()}_getTranspValue(){const e=(0,p.ensureDefined)(this._study.properties().childs().styles.childs()[this._plotName]).childs();let t=0;return e.transparency&&(t=e.transparency.value(),t=(0,_.isNumber)(t)?t:40),t}_updateImpl(){this._items=[],(0,p.assert)(this._scalesReady(),"Scales must be ready!");const e=this._model.timeScale().visibleBarsStrictRange();if(null===e)return;const t=this._getTranspValue();let s=(0,p.ensureDefined)(this._series.nearestIndex(e.firstBar(),O.PlotRowSearchMode.NearestRight)),i=(0,p.ensureDefined)(this._series.nearestIndex(e.lastBar(),O.PlotRowSearchMode.NearestLeft));const r=this._study.offset(this._plotName);r>0?(s-=r,i+=r):(s+=r,i-=r);const n=this._study.getMinFirstBarIndexForPlot(this._plotName);if(n>i)return;s=Math.max(n,s);const o=this._study.data();for(const e of o.rangeIterator(s,i)){let s=e.index;const i=e.value;s+=r;const n={timePointIndex:Math.floor(s),left:NaN,center:NaN,right:NaN};let o=(0,_.isNumber)(t)?t:50;o=Math.min(o,100),o=Math.max(o,0);const a=this._colorProvider.getPlotPointStyle(i);void 0!==a.colors[1]&&(n.color=(0,I.generateColor)((0,p.ensureDefined)(a.colors[1]),o)),this._items.push(n)}this._model.timeScale().fillBarBorders(this._items)}}var ae,le=s(89323),he=s(45801),ce=s(51752),ue=s(77914),de=s(13173),pe=s(52746),_e=s(26705),fe=s(10555),me=s(6453),ye=s(50335),ge=s(50605),ve=s(2383),Se=s(45720),be=s(49251),Pe=s(27714),we=s(33350);!function(e){e.Left="left",e.Center="center",e.Right="right"}(ae||(ae={}));const Ie=(0,we.createDisconnectedCanvas)(document,(0,Pe.size)({width:0,height:0}),1);class xe{constructor(e,t,s,i,r,n="center",o=0){this._lines=e.split(/[^\S\r\n]*(?:\r\n|\r|\n)/),this._font=function(e,t,s,i){return(0,be.makeFont)(i,s,`${e?"bold ":""}${t?"italic ":""}`)}(t,s,i,r),this._fontSize=r,this._verticalPadding=~~(r/6),this._textAlign=n,this._lineSpacing=o;const a=(0,p.ensureNotNull)(Ie.getContext("2d"));a.font=this._font,a.textBaseline="top";let l=0;for(let e=0;e<this._lines.length;++e){const t=this._lines[e],s=a.measureText(t).width;l=Math.max(l,s)}
|
||||
this.textImageWidth=l+1,this.textImageHeight=this._lines.length*r+(this._lines.length-1)*this._lineSpacing+this._verticalPadding}paintTo(e,t){const{context:s,horizontalPixelRatio:i,verticalPixelRatio:r}=e;s.save();const n=t.location;s.translate(Math.round(function(e,t,s){let i=e;switch(t){case"left":break;case"right":i-=s;break;case"center":i-=s/2}return Math.round(i)}(n.x,n.horzAlign,this.textImageWidth)*i),Math.round(function(e,t,s){let i=e;switch(t){case"top":break;case"bottom":i-=s;break;case"middle":i-=s/2}return Math.round(i)}(n.y,n.vertAlign,this.textImageHeight)*r));const o=t.style;let a;switch(s.textBaseline="top",s.font=this._font,s.lineJoin="round",s.fillStyle=o.fillStyle,o.strokeStyle&&(s.strokeStyle=o.strokeStyle),o.lineWidth&&(s.lineWidth=o.lineWidth),this._textAlign){case"left":a=0,s.textAlign="left";break;case"right":a=this.textImageWidth-1,s.textAlign="right";break;default:a=this.textImageWidth/2,s.textAlign="center"}let l=this._verticalPadding;(0,we.drawScaled)(s,i,r,(()=>{for(const e of this._lines)o.strokeStyle&&s.strokeText(e,a,l),s.fillText(e,a,l),l+=this._fontSize,l+=this._lineSpacing})),s.restore()}}class Ce extends Se.AbstractMapContainer{constructor(e){super(),this._maxSize=e,this._keysQueue=[]}get(e){const{fontSize:t,text:s,align:i,font:r,bold:n,italic:o,lineSpacing:a=0}=e;if(!s||!t||!i)return null;const l=(0,be.makeFont)(t,r,o?"italic":"",n?"bold":""),h=(0,Se.getDefault3)(this._map,a,i,l,new Map);let c=h.get(s);return void 0!==c||(this._size>=this._maxSize?this._deleteFirstKey():++this._size,this._keysQueue.push([l,i,a,s]),c=new xe(s,n,o,r,t,i,a),h.set(s,c)),c}_deleteFirstKey(){const e=this._keysQueue.shift(),[t,s,i,r]=e,n=(0,p.ensureDefined)(this._map.get(i)),o=(0,p.ensureDefined)(n.get(s)),a=(0,p.ensureDefined)(o.get(t));a.delete(r),0===a.size&&o.delete(t),0===o.size&&n.delete(s),0===n.size&&this._map.delete(i)}}var Ve,Me=s(84617),Te=s(49483);!function(e){e.Transparent="rgba(0, 0, 0, 0)"}(Ve||(Ve={}));class Ae extends se.BitmapCoordinatesPaneRenderer{constructor(e,t={skipRenderingOptimizations:!1}){super(),this._items=[],this._barSpacing=0,this._vertOffset=0,this._textCache=t.textCache||new Ce(5e3),this._drawOperation=t.skipRenderingOptimizations?this._drawWithoutOptimizations.bind(this):this._drawWithOptimizations.bind(this),null!==e&&this.setData(e)}hitTest(e){const t=ve.HitTarget.Regular;let s=null;for(const i of this._items){if(!i)continue;const r=this._calcBoundingBox(i);if(r&&(0,me.pointInBox)(e,r)){const e={tooltip:this._getTooltip(i,r)};s=new ve.HitTestResult(t,e)}}return s}setData(e){if(this._height=void 0!==e.height?e.height:e.width,this._width=void 0!==e.width?e.width:e.height,this._color=e.color,this._borderColor=e.borderColor,this._vertOffset=e.vertOffset||0,e.text&&(this._text=e.text,this._fontSize=e.fontSize,this._lineSpacing=e.lineSpacing,this._textColor=e.textColor,this._textAlign=e.textAlign||"center"),void 0!==e.items&&void 0!==e.barSpacing){const t=e.visibleItemsRange?.startItemIndex??0,s=e.visibleItemsRange?.endItemIndex??e.items.length
|
||||
;this.setItems(s>t?e.items.slice(t,s):[],e.barSpacing)}}setItems(e,t){this._setBaseData(e,t)}_drawImpl(e){this._preDrawInit(),this._drawOperation(e)}_calcBoundingBox(e){const t=e.vertOffset,s=this._getTextCache(e);if(!s)return;const i=s.textImageWidth,r=s.textImageHeight,n=i/2,o=e.y+t+e.textVertOffset,a=t>0?0:-r,l=t>0?r:0,h=new fe.Point(e.center-n,o+a),c=new fe.Point(e.center+n,o+l);return(0,fe.box)(h,c)}_unionBox(e,t){const s=Math.min(e.min.x,t.min.x),i=Math.max(e.max.x,t.max.x),r=Math.min(e.min.y,t.min.y),n=Math.max(e.max.y,t.max.y),o=new fe.Point(s,r),a=new fe.Point(i,n);return(0,fe.box)(o,a)}_getTooltip(e,t){if(e.tooltip)return{content:{type:"text",data:e.tooltip},tooltipDelay:200,extendMargin:!0,rect:{x:t.min.x,y:t.min.y,w:Math.abs(t.max.x-t.min.x),h:Math.abs(t.max.y-t.min.y)}}}_setBaseData(e,t){this._items.length=0,this._barSpacing=t;for(const t of e){if((0,ye.isNaN)(t.y))continue;const e=void 0===t.width?(0,p.ensureDefined)(this._width):t.width,s=void 0===t.height?(0,p.ensureDefined)(this._height):t.height,i=void 0===t.vertOffset?this._vertOffset:t.vertOffset,r=i>0?s:-s;this._items.push({width:e,height:s,vertOffset:i,textVertOffset:r,shapeWidth:0,shapeHeight:0,stepX:0,stepY:0,...t})}}_drawItemText(e,t){const s=this._getTextCache(t);if(null===s)return;const i=t.center,r=t.vertOffset,n=t.y+r+t.textVertOffset;let o;o=t.style&&void 0!==t.style.textColor?t.style.textColor:this._textColor;const a={style:{fillStyle:o},location:{x:i,y:n,horzAlign:ge.HorizontalAlign.Center,vertAlign:r>0?ge.VerticalAlign.Top:ge.VerticalAlign.Bottom}};s.paintTo(e,a)}_drawWithOptimizations(e){let t,s,i=null,r=!1;for(const n of this._items)(0,ye.isNaN)(n.y)||(n.style&&void 0!==n.style.color?(t=n.style.color||"rgba(0, 0, 0, 0)",s=n.style.borderColor||"rgba(0, 0, 0, 0)"):(t=this._color,s=this._borderColor),(i!==t||Te.isSafari)&&(i=t,r&&this._endPath(e),this._startPath(e,t,s)),this._drawItemShape(e,n),r=!0);r&&this._endPath(e);for(const t of this._items)(0,ye.isNaN)(t.y)||this._drawItemText(e,t)}_drawWithoutOptimizations(e){let t,s;for(const i of this._items){if((0,ye.isNaN)(i.y))continue;const r=(0,p.ensureDefined)(i.style);t=r.color||"rgba(0, 0, 0, 0)",s=r.borderColor||"rgba(0, 0, 0, 0)",this._startPath(e,t,s),this._drawItemShape(e,i),this._endPath(e),this._drawItemText(e,i)}}_drawItemShape(e,t){const{context:s,horizontalPixelRatio:i,verticalPixelRatio:r}=e;(0,we.drawScaled)(s,i,r,(()=>this._drawItemShapeUsingCSSPixels(s,t)))}_drawItemShapeUsingCSSPixels(e,t){}_preDrawInit(){}_startPath(e,t,s){}_endPath(e){}_getTextCache(e){const t=e.text||this._text,s=e.fontSize||this._fontSize,i=e.lineSpacing??this._lineSpacing,r=e.textAlign||this._textAlign,n=e.font??Me.CHART_FONT_FAMILY,o=e.bold??!1,a=e.italic??!1;return this._textCache.get({text:t,bold:o,italic:a,font:n,fontSize:s,lineSpacing:i,align:r})}}class Re extends Ae{_startPath(e,t,s){const i=e.context;i.beginPath(),i.lineWidth=this._lineWidth(e),i.lineCap="butt",i.strokeStyle=t}_endPath(e){e.context.stroke()}_lineWidth(e){return Math.max(1,Math.floor(2*e.horizontalPixelRatio))}}
|
||||
class Oe extends Ae{_startPath(e,t,s){const i=e.context;i.beginPath(),i.lineWidth=this._lineWidth(e),i.lineCap="butt",i.fillStyle=t,i.strokeStyle=s}_endPath(e){const t=e.context;t.fill(),t.stroke()}_lineWidth(e){return Math.max(1,Math.floor(e.horizontalPixelRatio))}}class De extends Oe{constructor(){super(...arguments),this._sign=0,this._thinArrow=!1,this._thinArrowLineWidth=0,this._headHeight=0,this._arrowWidth=0}setItems(e,t){this._setBaseData(e,t)}_drawItemShape(e,t){const{context:s,horizontalPixelRatio:i,verticalPixelRatio:r}=e,n=this._lineWidth(e)%2?.5:0,o=this._sign,a=this._arrowWidth,l=this._headHeight,h=Math.abs(t.height),c=Math.round(t.center*i)+n,u=t.vertOffset,d=Math.round((t.y+u+o*h/2)*r)+n,p=(0,ue.ceiledEven)(a*i),_=p/2,f=Math.round(h*r),m=Math.round(l*r);s.translate(c,d),this._thinArrow?(s.moveTo(0,0),s.lineTo(-_,-_*o),s.moveTo(0,0),s.lineTo(_,-_*o),s.moveTo(0,0),s.lineTo(0,-f*o),s.moveTo(-_,-f*o),s.lineTo(_,-f*o)):(s.moveTo(0,0),f<m?(s.lineTo(p,-f*o),s.lineTo(-p,-f*o)):(s.lineTo(p,-m*o),s.lineTo(_,-m*o),s.lineTo(_,-f*o),s.lineTo(-_,-f*o),s.lineTo(-_,-m*o),s.lineTo(-p,-m*o)),s.lineTo(0,0)),s.translate(-c,-d)}_preDrawInit(){const e=this._calculateWidth();this._arrowWidth=e,this._sign=this._isUp()?-1:1,this._thinArrow=e<4,this._thinArrowLineWidth=Math.max(e/2,1),this._headHeight=Math.round(e)}_startPath(e,t,s){const i=e.context;i.beginPath(),i.fillStyle=t,i.strokeStyle=s,i.lineWidth=this._lineWidth(e)}_lineWidth(e){return this._thinArrow?this._thinArrowLineWidth:super._lineWidth(e)}_calcBoundingBox(e){const t=e.vertOffset,s=this._sign,i=this._arrowWidth,r=this._headHeight,n=Math.abs(e.height),o=e.center-i,a=o+2*i,l=e.y+t+s*Math.round(n/2),h=l+(-n-r)*s,c=new fe.Point(o,l),u=new fe.Point(a,h);let d=(0,fe.box)(c,u);const p=super._calcBoundingBox(e);return p&&(d=this._unionBox(d,p)),d}_calculateWidth(){return Math.round(this._barSpacing/4)}}const Be=2*Math.PI;class Ne extends Oe{setItems(e,t){this._setBaseData(e,t);for(const e of this._items){if(e.fontSize){const t=e.fontSize;e.stepX=Math.round(t/1.5),e.stepY=Math.round(t/2)-1}else{const t=e.height;e.stepX=Math.round(t/2*.65)+.5,e.stepY=e.stepX}e.vertOffset=this._calcVertOffset(e);const t=this._getTextCache(e);if(null===t){e.shapeWidth=2*e.stepX,e.shapeHeight=2.5*e.stepY;continue}const s=t.textImageWidth,i=t.textImageHeight;e.shapeWidth=s+2*e.stepX,e.shapeHeight=i+2*e.stepY,e.vertOffset=this._calcVertOffset(e),e.textHorizOffset=this._getHorizontalTextOffset(e),e.textVertOffset=this._getVerticalTextOffset(e)}}_calcVertOffset(e){return e.vertOffset}_drawCorner(e,t,s,i){const{context:r,horizontalPixelRatio:n}=e,o=Math.max(1,Math.floor(2*n));r.lineTo(t-o*i.prevPointSignX,s-o*i.prevPointSignY),r.arcTo(t,s,t+o*i.nextPointSignX,s+o*i.nextPointSignY,o)}_getArrowSize(e){return e.stepX}_getHorizontalTextOffset(e){return 0}_getVerticalTextOffset(e){return 0}_hasText(e){return Boolean(e.text)||Boolean(this._text)}_drawItemText(e,t){const s=this._getTextCache(t);if(null===s)return
|
||||
;const i=t.textHorizOffset||0,r=t.center+i,n=t.vertOffset,o=t.y+n+t.textVertOffset,a=t.style?.textColor||this._textColor,l={style:{fillStyle:(0,p.ensureDefined)(a)},location:{x:r,y:Math.floor(o),horzAlign:ge.HorizontalAlign.Center,vertAlign:ge.VerticalAlign.Middle}};s.paintTo(e,l)}}class Fe{constructor(e,t,s,i){this.prevPointSignX=e,this.prevPointSignY=t,this.nextPointSignX=s,this.nextPointSignY=i}}var ke;!function(e){e.rightUp=new Fe(1,0,0,1),e.rightDown=new Fe(0,1,-1,0),e.leftDown=new Fe(-1,0,0,-1),e.leftUp=new Fe(0,-1,1,0)}(ke||(ke={}));class Ee extends Oe{_calcBoundingBox(e){const t=e.width,s=e.height,i=t/2,r=Math.round(s/3),n=e.center,o=e.vertOffset-2*r,a=e.y+o,l=n-i,h=n+i,c=a,u=a+s,d=new fe.Point(l,c),p=new fe.Point(h,u);let _=(0,fe.box)(d,p);const f=super._calcBoundingBox(e);return f&&(_=this._unionBox(_,f)),_}}var Le=s(41028);const He=new Map;He.set("PaneRendererArrowUp",class extends De{_isUp(){return!0}}),He.set("PaneRendererArrowDown",class extends De{_isUp(){return!1}}),He.set("PaneRendererCircleShape",class extends Oe{_drawItemShapeUsingCSSPixels(e,t){const s=Math.max(t.width,t.height)/2,i=t.center,r=t.vertOffset,n=t.y+r;e.moveTo(i+s,n),e.arc(i,n,s,0,Be,!1)}_calcBoundingBox(e){const t=Math.max(e.width,e.height)/2,s=e.center,i=e.vertOffset,r=e.y+i,n=s-t,o=s+t,a=r-t,l=r+t,h=new fe.Point(n,a),c=new fe.Point(o,l);let u=(0,fe.box)(h,c);const d=super._calcBoundingBox(e);return d&&(u=this._unionBox(u,d)),u}}),He.set("PaneRendererCrossShape",class extends Re{_drawItemShape(e,t){const{context:s,horizontalPixelRatio:i,verticalPixelRatio:r}=e,n=t.width,o=t.height,a=t.center-n/2,l=t.vertOffset,h=t.y-o/2+l,c=this._lineWidth(e),u=c%2?.5:0,d=Math.round(a*i);let p=Math.round((a+n)*i);(p-d)%2!=c%2&&(p+=1);const _=Math.floor((d+p)/2)+u,f=Math.round(h*r);let m=Math.round((h+o)*r);(m-f)%2!=c%2&&(m+=1);const y=Math.floor((f+m)/2)+u;s.moveTo(_,f),s.lineTo(_,m),s.moveTo(d,y),s.lineTo(p,y)}_calcBoundingBox(e){const t=e.width,s=e.height,i=e.center-t/2,r=e.vertOffset,n=e.y-s/2+r,o=i,a=i+t,l=n,h=n+s,c=new fe.Point(o,l),u=new fe.Point(a,h);let d=(0,fe.box)(c,u);const p=super._calcBoundingBox(e);return p&&(d=this._unionBox(d,p)),d}}),He.set("PaneRendererDiamond",class extends Oe{_drawItemShapeUsingCSSPixels(e,t){const s=Math.round(t.height/2),i=t.center,r=t.vertOffset,n=t.y+r;e.moveTo(i,n-s),e.lineTo(i+s,n),e.lineTo(i,n+s),e.lineTo(i-s,n),e.lineTo(i,n-s)}_calcBoundingBox(e){const t=Math.round(e.height/2),s=e.center,i=e.vertOffset,r=e.y+i,n=s-t,o=s+t,a=r-t,l=r+t,h=new fe.Point(n,a),c=new fe.Point(o,l);let u=(0,fe.box)(h,c);const d=super._calcBoundingBox(e);return d&&(u=this._unionBox(u,d)),u}}),He.set("PaneRendererFlagShape",class extends Oe{_drawItemShapeUsingCSSPixels(e,t){const s=t.width,i=t.height,r=i/2,n=(s-3)/3,o=t.center-s/2,a=t.vertOffset,l=t.y-r+a;e.moveTo(o,l),e.lineTo(o+3,l),e.bezierCurveTo(o+n,l-n,o+2*n,l+n,o+s,l),e.lineTo(o+s,l+r),e.bezierCurveTo(o+s-n,l+r+n,o+s-2*n,l+r-n,o+3,l+r),e.lineTo(o+3,l+i),e.lineTo(o,l+i),e.lineTo(o,l)}_calcBoundingBox(e){
|
||||
const t=e.width,s=e.height,i=s/2,r=e.center-t/2,n=e.vertOffset,o=e.y-i+n,a=r,l=r+t,h=o,c=o+s,u=new fe.Point(a,h),d=new fe.Point(l,c);let p=(0,fe.box)(u,d);const _=super._calcBoundingBox(e);return _&&(p=this._unionBox(p,_)),p}}),He.set("PaneRendererLabelUp",class extends Ne{_calcBoundingBox(e){const t=e.center-e.shapeWidth/2,s=e.center+e.shapeWidth/2,i=e.y+e.vertOffset,r=e.y+e.shapeHeight+e.vertOffset,n=new fe.Point(t,i),o=new fe.Point(s,r);return(0,fe.box)(n,o)}_drawItemShape(e,t){const{context:s,horizontalPixelRatio:i,verticalPixelRatio:r}=e,n=this._lineWidth(e)%2?.5:0,o=Math.max(1,Math.floor(i))%2?.5:0,a=this._getArrowSize(t);let l=Math.round(a*i);(o+l)%1!=n%1&&(l+=.5);let h=Math.round(t.shapeWidth/2*i);(o+h)%1!=n%1&&(h+=.5);const c=Math.round(t.center*i)+o,u=Math.round((t.y+t.vertOffset)*r)+n,d=c-l,p=Math.round((t.y+t.vertOffset+a)*r)+n,_=c+l,f=c+h,m=Math.round((t.y+t.vertOffset+a+t.shapeHeight)*r)+n,y=c-h;s.moveTo(d,p),s.lineTo(c,u),s.lineTo(_,p),t.shapeWidth<=2*a?(s.lineTo(f,p),this._drawCorner(e,f,m,ke.rightDown),this._drawCorner(e,y,m,ke.leftDown),s.lineTo(y,p)):(this._drawCorner(e,f,p,ke.rightUp),this._drawCorner(e,f,m,ke.rightDown),this._drawCorner(e,y,m,ke.leftDown),this._drawCorner(e,y,p,ke.leftUp)),s.lineTo(d,p)}_getVerticalTextOffset(e){return e.shapeHeight/2+this._getArrowSize(e)}_calcVertOffset(e){return Math.sign(e.vertOffset)>=0?e.vertOffset:e.vertOffset-e.shapeHeight}}),He.set("PaneRendererLabelDown",class extends Ne{_calcBoundingBox(e){const t=e.center-e.shapeWidth/2,s=e.center+e.shapeWidth/2,i=e.y-e.shapeHeight+e.vertOffset,r=e.y+e.vertOffset,n=new fe.Point(t,i),o=new fe.Point(s,r);return(0,fe.box)(n,o)}_drawItemShape(e,t){const{context:s,horizontalPixelRatio:i,verticalPixelRatio:r}=e,n=this._lineWidth(e)%2?.5:0,o=Math.max(1,Math.floor(i))%2?.5:0,a=this._getArrowSize(t);let l=Math.round(a*i);(o+l)%1!=n%1&&(l+=.5);let h=Math.round(t.shapeWidth/2*i);(o+h)%1!=n%1&&(h+=.5);const c=Math.round(t.center*i)+o,u=Math.round((t.y+t.vertOffset)*r)+n,d=c+l,p=Math.round((t.y+t.vertOffset-a)*r)+n,_=c-l,f=c+h,m=Math.round((t.y+t.vertOffset-t.shapeHeight-a)*r)+n,y=c-h;s.moveTo(d,p),s.lineTo(c,u),s.lineTo(_,p),t.shapeWidth<=2*a?(s.lineTo(y,p),this._drawCorner(e,y,m,ke.leftUp),this._drawCorner(e,f,m,ke.rightUp),s.lineTo(f,p)):(this._drawCorner(e,y,p,ke.leftDown),this._drawCorner(e,y,m,ke.leftUp),this._drawCorner(e,f,m,ke.rightUp),this._drawCorner(e,f,p,ke.rightDown)),s.lineTo(d,p)}_getVerticalTextOffset(e){return-e.shapeHeight/2-this._getArrowSize(e)}_calcVertOffset(e){return Math.sign(e.vertOffset)<=0?e.vertOffset:e.vertOffset+e.shapeHeight}}),He.set("PaneRendererSquare",class extends Oe{_drawItemShape(e,t){const{context:s,horizontalPixelRatio:i,verticalPixelRatio:r}=e,n=Math.max(1,Math.floor(i))%2?.5:0,o=this._lineWidth(e)%2?.5:0;let a=Math.round(t.height/2*r);(n+a)%1!=o%1&&(a+=.5);const l=Math.round(t.center*i)+n,h=Math.round((t.y+t.vertOffset)*r)+n,c=l-a,u=h-a,d=l+a,p=h+a;s.rect(c,u,d-c,p-u)}_calcBoundingBox(e){
|
||||
const t=e.height,s=Math.round(t/2),i=e.center-s,r=e.vertOffset,n=e.y+r-s,o=i,a=i+t,l=n,h=n+t,c=new fe.Point(o,l),u=new fe.Point(a,h);let d=(0,fe.box)(c,u);const p=super._calcBoundingBox(e);return p&&(d=this._unionBox(d,p)),d}}),He.set("PaneRendererTriangleApexUp",class extends Ee{_drawItemShape(e,t){const{context:s,horizontalPixelRatio:i,verticalPixelRatio:r}=e,n=t.width,o=t.height,a=Math.round(o/3),l=t.vertOffset-2*a,h=this._lineWidth(e)%2?.5:0,c=Math.max(1,Math.floor(i)),u=c%2?.5:0;let d=Math.round(n*i);d%2!=c%2&&(d+=1);const p=Math.round(t.center*i)+u,_=Math.round((t.y+l)*r),f=p+d/2,m=Math.round((t.y+l+o)*r)+h,y=p-d/2;s.moveTo(p,_),s.lineTo(f,m),s.lineTo(y,m),s.lineTo(p,_)}}),He.set("PaneRendererTriangleApexDown",class extends Ee{_drawItemShape(e,t){const{context:s,horizontalPixelRatio:i,verticalPixelRatio:r}=e,n=t.width,o=t.height,a=Math.round(o/3),l=t.vertOffset-a,h=this._lineWidth(e)%2?.5:0,c=Math.max(1,Math.floor(i)),u=c%2?.5:0;let d=Math.round(n*i);d%2!=c%2&&(d+=1);const p=Math.round(t.center*i)+u,_=Math.round((t.y+l)*r)+h,f=p+d/2,m=Math.round((t.y+l+o)*r),y=p-d/2;s.moveTo(y,_),s.lineTo(f,_),s.lineTo(p,m),s.lineTo(y,_)}}),He.set("PaneRendererXCross",class extends Re{_drawItemShapeUsingCSSPixels(e,t){const s=t.width,i=t.height,r=t.center-s/2,n=t.vertOffset,o=t.y-i/2+n;e.moveTo(r,o),e.lineTo(r+s,o+i),e.moveTo(r,o+i),e.lineTo(r+s,o)}_calcBoundingBox(e){const t=e.width,s=e.height,i=e.center-t/2,r=e.vertOffset,n=e.y-s/2+r,o=i,a=i+t,l=n,h=n+s,c=new fe.Point(o,l),u=new fe.Point(a,h);let d=(0,fe.box)(c,u);const p=super._calcBoundingBox(e);return p&&(d=this._unionBox(d,p)),d}});class We extends Le.StudyPaneViewInplaceUpdatable{constructor(e,t,s,i){super(t,s,i),this._renderer=null,this._shapesRenderer=null,this._selectionRenderer=null,this._isMarkersEnabled=ee.enabled("source_selection_markers"),this._study=e;const r=e.metaInfo().plots;for(let e=0;e<r.length;e++)if(r[e].id===this._plotName){this._plotIndex=e;break}this._plotStyleInfo=(0,p.ensureDefined)(e.metaInfo().styles?.[this._plotName]),this._colorProvider=(0,re.createStudyPlotColorProvider)(e.metaInfo(),e.properties(),i),this._selectionIndexer=new de.SelectionIndexes(s.timeScale())}items(){return this._items}renderer(){return this._isPlotVisible()&&this._scalesReady()?(this._makeSureRendererIsValid(),this._renderer):null}_isPlotVisible(){return this._study.isPlotVisibleAt(this._plotName,1)}_scalesReady(){const e=this._model.timeScale(),t=this._priceScale();return e&&null!==t&&!e.isEmpty()&&!t.isEmpty()}_updateImplFull(e){if(this._dataInvalidated?.clearData&&(this._items=[],this._renderer=null),!this._scalesReady())return!1;const t=this._model.timeScale(),s=this._priceScale(),i=t.visibleBarsStrictRange();if(null===i||null===s)return!1;const r=this._study.plots().plottableRange(!1);if(0===r.size())return!1;const n=this._study.offset(this._plotName),o=this._study.firstValue(void 0,this.isForceOverlay());if(null===o)return!1;this._updateAdditionalPrices(s,o)
|
||||
;const{hiPlot:a,loPlot:l}=this._hiLoPlots(),h=this._preallocateItems(r,((e,t)=>this._createItem(e,t??null,a,l,n)));let c=this._series.nearestIndex(i.firstBar(),O.PlotRowSearchMode.NearestRight),u=this._series.nearestIndex(i.lastBar(),O.PlotRowSearchMode.NearestLeft);if(void 0===c||void 0===u)return!1;n>0?(c-=n,u+=n):(c+=n,u-=n);const d=this._study.getMinFirstBarIndexForPlot(this._plotName);if(d>u)return!0;c=Math.max(d,c);const _=this._getTranspValue(),f=this._study.properties().childs().styles.childs()[this._plotName].childs(),m=f.color.value(),g=f.textColor?f.textColor.value():void 0,v=m,S=m,b=void 0===g?void 0:g,P=(0,p.ensureNotNull)(this._plotIndex),w=(0,_e.createEmptyStyle)(),I=h??(0,p.ensureNotNull)(r.firstIndex()),x=r.rangeIterator(I,(0,p.ensureNotNull)(r.lastIndex())+1);let C=(0,y.lowerbound)(this._items,I+n,((e,t)=>e.timePointIndex<t));for(const e of x){const t=e.value,s=t[P+1];if(null==s){C++;continue}const i=this._items[C];if(!isNaN(i.origPrices.price)){if(this._colorProvider.isColorDefined()){i.style={color:v,borderColor:S,textColor:b};const e=this._colorProvider.getPlotPointStyle(t,w);this._fillItemWithPointStyle(i,e,_)}}C++}return this._updateImplLight(),!0}_fillItemWithPointStyle(e,t,s){const i=(0,p.ensureDefined)(e.style);if(void 0!==t.colors[0]){i.color=(0,I.generateColor)((0,p.ensureDefined)(t.colors[0]),s);const e=s>9?s-10:0;i.borderColor=(0,I.generateColor)(i.color,e)}void 0!==t.colors[2]&&(i.textColor=(0,I.generateColor)((0,p.ensureDefined)(t.colors[2]),s))}_updateRenderer(e,t){this._makeSureRendererIsValid();const s=this._model.timeScale(),i={},r=this._getTranspValue(),n=s.barSpacing(),o=this._calculateShapeHeight(n),a=this._study.properties().childs().styles.childs()[this._plotName].childs(),l=a.location.value(),h=this._calculateVerticalOffset(l,o+o/2);i.barSpacing=n,i.items=this._items,i.color=(0,I.generateColor)(a.color.value(),r),i.height=o,i.vertOffset=h,i.visibleItemsRange={startItemIndex:e,endItemIndex:t};const c=a.plottype.value(),u=ce.plotShapesData[c],d=new te.CompositeRenderer;u&&(this._shapesRenderer?this._shapesRenderer.setData(i):(this._shapesRenderer=this._createRenderer(u.paneRendererClass,i),d.append(this._shapesRenderer))),this._model.selection().isSelected(this._study)&&this._isMarkersEnabled&&null!==this._selectionData&&(this._selectionData.vertOffset=h,d.append(new he.SelectionRenderer(this._selectionData))),this._renderer=d}_createRenderer(e,t){const s=He.get(e);return new((0,p.ensureDefined)(s))(t)}_getSeriesVal(e,t){const s=(0,pe.barFunction)(e),i=this._series.data().valueAt(t);return null===i?null:s(i)}_getTranspValue(){let e=0;const t=this._study.properties().childs();t.transparency&&(e=t.transparency.value(),e=(0,_.isNumber)(e)?e:50);const s=t.styles.childs()[this._plotName].childs();return s.transparency&&(e=s.transparency.value(),e=(0,_.isNumber)(e)?e:50),(0,ue.clamp)(e,0,100)}_createItem(e,t,s,i,r){const n=this._study.properties().childs().styles.childs()[this._plotName].childs().location.value(),o={origPrices:{price:NaN},timePointIndex:e+r}
|
||||
;if((null===t||0===t)&&n!==D.MarkLocation.Absolute)return o;if(null==t)return o;let a=NaN;switch(n){case D.MarkLocation.AboveBar:{const t=this._getLocationPrice(e,s,r);if(null===t)return o;a=t;break}case D.MarkLocation.BelowBar:{const t=this._getLocationPrice(e,i,r);if(null===t)return o;a=t;break}case D.MarkLocation.Absolute:a=(0,p.ensureNotNull)(t);break;case D.MarkLocation.Top:case D.MarkLocation.Bottom:a=0;break;default:throw new Error("Bad value: "+n)}return{y:NaN,origPrices:{price:a},timePointIndex:e+r}}_dependsOnSeriesData(){const e=this._study.properties().childs().styles.childs()[this._plotName].childs().location.value();return e===D.MarkLocation.AboveBar||e===D.MarkLocation.BelowBar}_getValueForUpdating(e){const t=e.value[this._plotIndex+1];if(null==t)return null;const s=this._study.properties().childs().styles.childs()[this._plotName].childs().location.value();if(0===t&&s!==D.MarkLocation.Absolute)return null;const i=this._study.offset(this._plotName),{hiPlot:r,loPlot:n}=this._hiLoPlots();switch(s){case D.MarkLocation.AboveBar:return this._getLocationPrice(e.index,r,i);case D.MarkLocation.BelowBar:return this._getLocationPrice(e.index,n,i)}return super._getValueForUpdating(e)}_convertItemsToCoordinates(e,t,s,i){for(let e=s;e<i;e++){const t=this._items[e];t.y=t.origPrices.price}this._model.timeScale().fillBarBorders(this._items);const r=this._study.properties().childs().styles.childs()[this._plotName].childs().location.value(),n=e.height()*e.topMargin(),o=e.height()*(1-e.bottomMargin()),a=e.isInverted(),l=a?o:n,h=a?n:o,c=e=>{for(let t=s;t<i;t++)isNaN(this._items[t].y)||(this._items[t].y=e)};switch(r){case D.MarkLocation.Top:c(l);break;case D.MarkLocation.Bottom:c(h);break;default:e.pointsArrayToCoordinates(this._items,t,{startItemIndex:s,endItemIndex:i})}}_calculateVerticalOffset(e,t){let s=0;switch(e){case D.MarkLocation.AboveBar:case D.MarkLocation.Bottom:s=-t;break;case D.MarkLocation.BelowBar:case D.MarkLocation.Top:s=t}return(0,p.ensureNotNull)(this._priceScale()).isInverted()&&(s*=-1),s}_calculateShapeHeight(e,t){let s=e;switch(t){case L.PlotSymbolSize.Tiny:s=.3*e;break;case L.PlotSymbolSize.Small:s=.6*e;break;case L.PlotSymbolSize.Normal:s=e;break;case L.PlotSymbolSize.Large:s=1.5*e;break;case L.PlotSymbolSize.Huge:s=2*e}return"number"==typeof t&&t>0&&(s=t),s}_hiLoPlots(){let e,t;let s=null;switch(this._series.properties().childs().style.value()){case 2:s="lineStyle";break;case 14:s="lineWithMarkersStyle";break;case 15:s="steplineStyle";break;case 3:s="areaStyle"}return s?(e=this._series.properties().childs()[s].childs().priceSource.value(),t=e):(e="high",t="low"),{hiPlot:e,loPlot:t}}_getLocationPrice(e,t,s){const i=Math.min(e+s,(0,p.ensureNotNull)(this._series.data().last()).index);return this._getSeriesVal(t,i)}}class ze extends We{_updateRenderer(e,t){const s=this._study.properties().childs().styles.childs()[this._plotName].childs(),i=this._model.timeScale(),r={},n=this._getTranspValue(),o=i.barSpacing();let a
|
||||
;a=this._plotStyleInfo.size?this._calculateShapeHeight(25,this._plotStyleInfo.size):Math.round(o/2),a=Math.max(a,1);const l=s.location.value(),h=(0,I.generateColor)(s.color.value(),n),c=n>19?n-10:0,u=this._calculateVerticalOffset(l,Math.round(1.5*a));r.barSpacing=o,r.items=this.items(),r.color=h,r.borderColor=(0,I.generateColor)(s.color.value(),c),r.height=a,r.vertOffset=u,r.visibleItemsRange={startItemIndex:e,endItemIndex:t};const d=s.plottype.value(),p=ce.plotShapesData[d],_=this._plotStyleInfo.text;if(void 0!==_&&""!==_.trim()){let e=_.replace(/\\n/gm,"\n");e=(0,le.cleanButAmpersand)(e,!0),r.text=e,r.fontSize=12;const t=s.textColor?s.textColor.value():void 0;r.textColor=t?(0,I.generateColor)(t,n):h}if(this._renderer&&this._shapesRenderer&&this._selectionRenderer)this._shapesRenderer.setData(r),this._model.selection().isSelected(this._study)&&this._isMarkersEnabled&&null!==this._selectionData?(this._selectionData.vertOffset=u,this._selectionRenderer.setData(this._selectionData)):this._selectionRenderer.setData(null);else{const e=new te.CompositeRenderer;this._shapesRenderer=super._createRenderer(p.paneRendererClass,r),e.append(this._shapesRenderer),this._selectionRenderer=new he.SelectionRenderer(this._selectionData??void 0),this._model.selection().isSelected(this._study)&&this._isMarkersEnabled&&null!==this._selectionData?this._selectionData.vertOffset=u:this._selectionRenderer.setData(null),e.append(this._selectionRenderer),this._renderer=e}}}var Ue,je=s(87795),Ge=s.n(je),$e=s(4539),Ke=s(57658);!function(e){e[e.SimplifiedPaintingMaxFontSize=4]="SimplifiedPaintingMaxFontSize"}(Ue||(Ue={}));class Ye extends Ae{constructor(e,t){super(null,t),this._textWidthCache=new Ke.TextWidthCache,this._fontSizeEnsured=0,this._font="",this._ch="",null!==e&&this.setData(e)}setData(e){super.setData(e),this._fontSizeEnsured=(0,p.ensureDefined)(this._height),this._font=(0,be.makeFont)(this._fontSizeEnsured,e.fontFamily||Me.CHART_FONT_FAMILY);const t=e.char.slice(0,40);this._ch=Ge()(t)[0]||" "}hitTest(e){const t=(0,$e.interactionTolerance)().series+this._fontSizeEnsured/2;for(const s of this._items){if(new fe.Point(s.center,s.y+s.vertOffset).subtract(e).length()<=t)return new ve.HitTestResult(ve.HitTarget.Regular)}return null}_drawItemShape(e,t){const s=t.center,i=t.vertOffset>0?1:-1,r=Math.trunc(this._fontSizeEnsured/6),n=t.y+t.vertOffset-i*Math.round(this._fontSizeEnsured/2)+(i>0?r:-this._fontSizeEnsured);let o;o=t.style&&void 0!==t.style.color?t.style.color:this._color;const{context:a,horizontalPixelRatio:l,verticalPixelRatio:h}=e;a.font!==this._font&&(a.font=this._font);const c=this._textWidthCache.measureText(a,this._ch);if(this._fontSizeEnsured<=4/l){a.save();const e=Math.max(1,Math.floor(l));let i=Math.max(1,Math.floor(c*l));i%2!=e%2&&(i+=i>1?-1:1);const r=Math.round(n*h)+(t.vertOffset>=0?0:-i);return a.fillStyle=o,a.fillRect(Math.round(s*l)+(l%2?.5:0)-i/2,r,i,i),void a.restore()}(0,we.drawScaled)(a,l,h,(()=>{a.fillStyle=o,a.textAlign="center",a.textBaseline="top",a.fillText(this._ch,s,n)}))}_startPath(e,t,s){}_endPath(e){}}
|
||||
class Xe extends We{constructor(){super(...arguments),this._charRenderer=new Ye(null)}_updateRenderer(e,t){const s=this._getTranspValue(),i=this._model.timeScale().barSpacing();let r;const n=this._study.properties().childs().styles.childs()[this._plotName].childs();r=this._plotStyleInfo.size?this._calculateShapeHeight(50,this._plotStyleInfo.size):Math.round(i);const o=n.location.value(),a=(0,I.generateColor)(n.color.value(),s),l=this._calculateVerticalOffset(o,r),h={items:this.items(),barSpacing:i,char:(0,p.ensureDefined)(n.char?.value()??this._plotStyleInfo.char),height:r,vertOffset:l,color:a,visibleItemsRange:{startItemIndex:e,endItemIndex:t}},c=this._plotStyleInfo.text;if(void 0!==c&&""!==c.trim()){let e=c.replace(/\\n/gm,"\n");e=(0,le.cleanButAmpersand)(e,!0),h.text=e,h.fontSize=12;const t=n.textColor?n.textColor.value():void 0;h.textColor=t?(0,I.generateColor)(t,s):a}this._charRenderer.setData(h);const u=new te.CompositeRenderer;u.append(this._charRenderer),this._model.selection().isSelected(this._study)&&this._isMarkersEnabled&&null!==this._selectionData&&(this._selectionData.vertOffset=l,u.append(new he.SelectionRenderer(this._selectionData))),this._renderer=u}}var qe=s(24377);class Je{constructor(e,t,s,i,r){this.left=NaN,this.right=NaN,this.height=NaN,this.center=e,this.y=t,this.origHeight=s,this.isUp=i,this.origPrices=r,this.timePointIndex=e,this.style={}}}function Ze(e){return Math.round(e/4)}function Qe(e){return Math.round(e/2)}class et extends se.BitmapCoordinatesPaneRenderer{constructor(e){super(),this._data=e}hitTest(e){const t=this._data,s=Qe(t.barSpacing),i=Math.round(s/2),r=Math.round(s),n=Ze(t.barSpacing),o=t.visibleItemsRange?.startItemIndex??0,a=t.visibleItemsRange?.endItemIndex??t.items.length;if(o>=a)return null;for(const s of t.items.slice(o,a)){if(!s)continue;if(!Number.isFinite(s.center)||!Number.isFinite(s.y))continue;const t=Math.abs(s.height),o=s.isUp?-1:1,a=t+r,l=s.y-o*n,h=l-o*a,c=s.center-i,u=s.center+i;if(c<e.x&&e.x<u&&(s.isUp?l<e.y&&e.y<h:h<e.y&&e.y<l))return new ve.HitTestResult(ve.HitTarget.Regular)}return null}_drawImpl(e){const{horizontalPixelRatio:t,verticalPixelRatio:s,context:i}=e,r=this._data,n=Qe(r.barSpacing),o=Ze(r.barSpacing),a=n<4,l=Math.max(n/2,1),h=(0,ue.ceiledEven)(n*t),c=h/2,u=Math.round(n*s);i.lineCap="butt",i.lineWidth=Math.max(1,Math.floor(t));const d=i.lineWidth%2?.5:0,p=r.visibleItemsRange?.startItemIndex??0,_=r.visibleItemsRange?.endItemIndex??r.items.length;if(!(p>=_))for(const e of r.items.slice(p,_)){if(!Number.isFinite(e.center)||!Number.isFinite(e.y))continue;const n=e.isUp?-1:1,p=Math.round(Math.abs(e.height)*s),_=Math.round(e.center*t)+d,f=Math.round((e.y-n*o)*s)+d;i.beginPath(),i.translate(_,f);const m=(e.style&&e.style.color)??(e.isUp?r.colorup:r.colordown);a?(i.moveTo(0,0),i.lineTo(-c,-c*n),i.moveTo(0,0),i.lineTo(c,-c*n),i.moveTo(0,0),i.lineTo(0,-p*n),i.moveTo(-c,-p*n),i.lineTo(c,-p*n),i.lineWidth=l,i.strokeStyle=m,i.stroke()):(i.moveTo(0,0),p<u?(i.lineTo(h,-p*n),i.lineTo(-h,-p*n)):(i.lineTo(h,-u*n),i.lineTo(c,-u*n),i.lineTo(c,-p*n),i.lineTo(-c,-p*n),
|
||||
i.lineTo(-c,-u*n),i.lineTo(-h,-u*n)),i.lineTo(0,0),i.strokeStyle=e.isUp?r.colorBorderUp:r.colorBorderDown,i.stroke(),i.fillStyle=m,i.fill()),i.translate(-_,-f)}}}class tt extends We{_updateRenderer(e,t){const s=this._study.properties().childs().styles.childs()[this._plotName].childs(),i=(0,ue.clamp)(this._getTranspValue(),0,100),r=this._model.timeScale().barSpacing(),n=(0,I.generateColor)(s.colorup.value(),i),o=(0,I.generateColor)(s.colordown.value(),i),a=(0,qe.parseRgba)(n),l=a?100*(1-a[3]):0,h=(0,qe.parseRgba)(o),c=h?100*(1-h[3]):0,u={items:this._items,barSpacing:r,colorup:n,colordown:o,colorBorderUp:(0,I.generateColor)("#000000",l),colorBorderDown:(0,I.generateColor)("#000000",c),minHeight:this._plotStyleInfo.minHeight,visibleItemsRange:{startItemIndex:e,endItemIndex:t}};this._updateItemsHeights(u);const d=new te.CompositeRenderer;d.append(new et(u)),this._model.selection().isSelected(this._study)&&null!==this._selectionData&&d.append(new he.SelectionRenderer({...this._selectionData,barSpacing:r,withOutline:!1})),this._renderer=d}_fillItemWithPointStyle(e,t,s){const i=(0,p.ensureDefined)(e.style);e.isUp?void 0!==t.colors[5]?i.color=(0,I.generateColor)((0,p.ensureDefined)(t.colors[5]),s):i.color=(0,I.generateColor)(this._study.properties().childs().styles.childs()[this._plotName].childs().colorup.value(),s):void 0!==t.colors[6]?i.color=(0,I.generateColor)((0,p.ensureDefined)(t.colors[6]),s):i.color=(0,I.generateColor)(this._study.properties().childs().styles.childs()[this._plotName].childs().colordown.value(),s)}_getValueForUpdating(e){const t=e.value[this._plotIndex+1];if(!t)return null;const s=e.index,i=t>0,{hiPlot:r,loPlot:n}=this._hiLoPlots(),o=this._study.offset(this._plotName),a=Math.min(s+o,(0,p.ensureNotNull)(this._series.data().last()).index);if(i){const e=this._getSeriesVal(n,a);if(null!==e)return e}else{const e=this._getSeriesVal(r,a);if(null!==e)return e}return null}_updateItem(e,t){const s=this._getValueForUpdating(e),i=e.value[this._plotIndex+1]>0;return this._items[t].origPrices.price=s??NaN,this._items[t].isUp=i,t+1}_createItem(e,t,s,i,r){const n={center:NaN,y:NaN,origPrices:{price:NaN,timePointIndex:NaN},origHeight:NaN,timePointIndex:e+r};if(!t)return n;const o=Math.min(e+r,(0,p.ensureNotNull)(this._series.data().last()).index),a=t>0;let l;if(a){const e=this._getSeriesVal(i,o);if(null===e)return n;l=e}else{const e=this._getSeriesVal(s,o);if(null===e)return n;l=e}return new Je(e+r,l,t,a,{price:l,timePointIndex:e+r})}_dependsOnSeriesData(){return!0}_convertItemsToCoordinates(e,t,s,i){this._convertItemsToCoordinatesImpl(e,t,s,i)}_createSelectionDataPoint(e,t,s,i){const r=this._model.timeScale().barSpacing(),n=Ze(r),o=function(e){return Qe(e)}(r),a=super._createSelectionDataPoint(e,t,s,i),l=this._items[(0,y.lowerbound)(this._items,t,((e,t)=>e.timePointIndex<t))];if(!l)return a;const h=l.isUp?1:-1;return{...a,point:a.point.add((0,fe.point)(0,h*(n+o)))}}_updateItemsHeights(e){const t=this._study.properties().childs().styles.childs();let s=Math.abs((0,
|
||||
p.ensureDefined)(t[this._plotName].childs().minHeight?.value()??this._plotStyleInfo.minHeight)),i=Math.abs((0,p.ensureDefined)(t[this._plotName].childs().maxHeight?.value()??this._plotStyleInfo.maxHeight));if(s>i){const e=s;s=i,i=e}const r=this._items,n=e.visibleItemsRange?.startItemIndex??0,o=(e.visibleItemsRange?.endItemIndex??r.length)-1;let a=0;for(let e=n;e<=o;e++){const t=r[e],s=Math.abs(t.origHeight);s>a&&(a=s)}const l=(i-s)/a;for(let e=n;e<=o;e++){const t=r[e],i=Math.abs(t.origHeight);t.height=i*l+s}}}var st=s(64138);class it extends ne.StudyForceOverlayPlotView{constructor(e,t,s,i){super(t,s,i),this._bars=[],this._invalidated=!1,this._isMarkersEnabled=ee.enabled("source_selection_markers"),this._selectionData=null,this._ohlcPlotIndexes=new Map,this._study=e,this._isMarkersEnabled=ee.enabled("source_selection_markers"),this._colorProvider=(0,re.createStudyPlotColorProvider)(e.metaInfo(),e.properties(),i),this._selectionIndexer=new de.SelectionIndexes(s.timeScale());const r=this._study.metaInfo().plots;for(let e=0;e<r.length;e++){const t=r[e];"target"in t&&(t.target===this._plotName&&((0,L.isOhlcOpenPlot)(t)&&this._ohlcPlotIndexes.set(1,e),(0,L.isOhlcHighPlot)(t)&&this._ohlcPlotIndexes.set(2,e),(0,L.isOhlcLowPlot)(t)&&this._ohlcPlotIndexes.set(3,e),(0,L.isOhlcClosePlot)(t)&&this._ohlcPlotIndexes.set(4,e)))}}update(e){"hover-change"!==e.type&&(this._invalidated=!0)}items(){return this._bars}_updateImpl(){this._bars.length=0;const e=this._priceScale();if(this._model.timeScale().isEmpty()||null===e||e.isEmpty())return;const t=this._model.timeScale().visibleBarsStrictRange();if(null===t)return;let s=this._series.nearestIndex(t.firstBar(),O.PlotRowSearchMode.NearestRight);const i=this._series.nearestIndex(t.lastBar(),O.PlotRowSearchMode.NearestLeft);if(void 0===s||void 0===i)return;const r=this._study.getMinFirstBarIndexForPlot(this._plotName);if(r>i)return;s=Math.max(r,s);const n=this._study.data(),o=this._study.firstValue(void 0,this.isForceOverlay());if(null===o)return;const a=n.rangeIterator(s,i),l=(0,p.ensureDefined)(this._study.properties().childs().ohlcPlots).childs()[this._plotName].childs(),h=new Map,c=(e,t)=>{const s=e+"@"+t;if(!h.has(s)){const i=(0,I.generateColor)(e,t);return h.set(s,i),i}return h.get(s)},u=(0,_e.createEmptyStyle)();for(const e of a){let t=e.index;const s=e.value;t=Math.floor(t);let i=!0;const r=new Map;for(let e=1;e<=4;++e){const t=this._ohlcPlotIndexes.get(e);if(void 0===t){i=!1;break}const n=s[t+1];if(null==n){i=!1;break}r.set(e,n)}if(!i)continue;const n=(0,p.ensureDefined)(r.get(1)),o=(0,p.ensureDefined)(r.get(4)),a=(0,p.ensureDefined)(r.get(2)),h=(0,p.ensureDefined)(r.get(3)),d=Math.max(n,a,h,o),_=Math.min(n,a,h,o);let f=(0,p.ensureDefined)(c(l.color.value(),0));const m=this._colorProvider.getPlotPointStyle(s,u);void 0!==m.colors[0]&&(f=(0,p.ensureDefined)(m.colors[0]));const y={open:n,high:d,low:_,close:o,color:f,wickColor:m.colors[4],borderColor:m.colors[3],hollow:null,center:NaN,left:NaN,right:NaN,timePointIndex:Math.round(t)};this._bars.push(y)}
|
||||
if(e.barPricesToCoordinates(this._bars,o),this._model.timeScale().fillBarBorders(this._bars),this._model.selection().isSelected(this._study)){const t=this._selectionIndexer.indexes();this._selectionData={points:[],hittestResult:ve.HitTarget.Regular,bgColors:[],visible:!0,barSpacing:this._model.timeScale().barSpacing()};const s=(0,p.ensureNotNull)(this._model.paneForSource(this._study)).height(),i=(0,p.ensureDefined)(this._ohlcPlotIndexes.get(4));for(let r=0;r<t.length;r++){const n=t[r],a=this._study.data().valueAt(n);if(null===a)continue;const l=a[i+1];if(null==l)continue;const h=this._model.timeScale().indexToCoordinate(Math.floor(n)),c=e.priceToCoordinate(l,o);this._selectionData.points.push({point:new fe.Point(h,c)}),this._selectionData.bgColors.push(this._model.backgroundColorAtYPercentFromTop(c/s))}}else this._selectionIndexer.clear()}_isOHLCPlotVisible(){return this._study.isPlotVisibleAt(this._plotName,1)}}class rt extends it{renderer(){if(!this._isOHLCPlotVisible())return null;this._invalidated&&(this._updateImpl(),this._invalidated=!1);const e={bars:this._bars,dontDrawOpen:this._series.properties().childs().barStyle.childs().dontDrawOpen.value(),thinBars:this._series.properties().childs().barStyle.childs().thinBars.value()},t=new te.CompositeRenderer;return t.append(new st.PaneRendererBars(e)),this._model.selection().isSelected(this._study)&&this._isMarkersEnabled&&this._selectionData&&t.append(new he.SelectionRenderer(this._selectionData)),t}}var nt=s(48227);class ot extends it{renderer(){if(!this._isOHLCPlotVisible())return null;const e=this._priceScale();if(!e||e.isEmpty())return null;this._invalidated&&(this._updateImpl(),this._invalidated=!1);const t=(0,p.ensureDefined)(this._study.properties().childs().ohlcPlots).childs()[this._plotName].childs(),s=this._model.timeScale().barSpacing(),i={bars:this._bars,barSpacing:s,wickVisible:t.drawWick.value(),bodyVisible:!0,borderVisible:t.drawBorder.value(),barWidth:(0,$e.optimalBarWidth)(s),borderColor:t.borderColor.value(),wickColor:t.wickColor.value(),isPriceScaleInverted:e.isInverted()},r=new te.CompositeRenderer;return r.append(new nt.PaneRendererCandles(i)),this._model.selection().isSelected(this._study)&&this._isMarkersEnabled&&this._selectionData&&r.append(new he.SelectionRenderer(this._selectionData)),r}}var at=s(69555),lt=s(96025),ht=s(40738),ct=s(69558);class ut extends ht.HorizontalLinePaneView{constructor(e,t){super(),this._lineRendererData.linestyle=ct.LINESTYLE_DOTTED,this._study=e,this._plotName=t}_updateImpl(){this._lineRendererData.visible=!1;const e=this._study.properties().childs().styles.childs()[this._plotName].childs();if(!e.trackPrice.value()||!this._study.isPlotVisibleAt(this._plotName,1))return;const t=this._study.lastValueData(this._plotName,!0);t.noData||(this._lineRendererData.visible=!0,this._lineRendererData.y=t.coordinate,this._lineRendererData.color=t.color,this._lineRendererData.linewidth=e.linewidth.value())}}var dt=s(5605),pt=s(13560),_t=s(18348);const ft={type:0,color:"transparent"}
|
||||
;class mt extends _t.AbstractFilledAreaPaneView{constructor(e,t,s,i){super(e,t,s),this._palettesInfo={},this._gradientPropsStateCache=null,this._rgbaFromInteger=(0,pt.rgbaFromIntegerCached)();const r=this._source.metaInfo();this._isRGB=Boolean(r.isRGB),this._isHlineFill="hline_hline"===s.type,(0,p.assert)(this._isHlineFill||"plot_plot"===s.type,"Wrong filledArea type: "+s.type),this._isHlineFill&&this._initBandIndexes(s.objAId,s.objBId),this._fillMetaInfo=s,this._fillStyleProps=i,this._gradientFillType=i.hasChild("fillType")&&"gradient"===i.childs().fillType?.value(),this._gradientStaticState={color1:s.topColor,color2:s.bottomColor,value1:s.topValue,value2:s.bottomValue},this._hasAllGradientRequiredProps=this._gradientFillType&&(void 0!==this._gradientStaticState.color1||i.hasChild("topColor")||void 0!==this._gradientStaticState.color2||i.hasChild("bottomColor"))&&(void 0!==this._gradientStaticState.value1||i.hasChild("topValue"))&&(void 0!==this._gradientStaticState.value2||i.hasChild("bottomValue"));const n=()=>this._colorPlotIndex=this._colorPlotIndex??{type:1};for(let t=0;t<r.plots.length;++t){const i=r.plots[t];if(((0,L.isColorerPlot)(i)||(0,L.isDataPlot)(i))&&i.target===s.id){if((0,L.isColorerPlot)(i)){let s;void 0!==i.targetField?"topColor"===i.targetField?(n().colorIndexOrRgba1=t,s="color1"):"bottomColor"===i.targetField&&(n().colorIndexOrRgba2=t,s="color2"):this._colorPlotIndex={type:0,colorIndexOrRgba:t},(0,L.isPaletteColorerPlot)(i)&&(this._palettesInfo[s??"color"]={map:(0,p.ensureDefined)((0,p.ensureDefined)(r.palettes)[i.palette]?.valToIndex),values:e.properties().palettes[i.palette].colors})}else(0,L.isDataPlot)(i)&&("topValue"===i.targetField?n().valueIndex1=t:"bottomValue"===i.targetField&&(n().valueIndex2=t));if(0===this._colorPlotIndex?.type)break}}}update(e){super.update(e),this._gradientPropsStateCache=null}isForceOverlay(){return!!this._source.metaInfo().isPlotForceOverlay(this._plotAId())}_firstValue(){const e=this.isForceOverlay();return this._source.firstValue(void 0,e)}_minFirstBarIndex(){return this._source.getMinFirstBarIndexForPlot(this._fillMetaInfo.id)}_getColorByPlotValue(e){if(0===e.type){let t;if(null==e.colorIndexOrRgba)return null;if(this._isRGB)t=this._rgbaFromInteger(e.colorIndexOrRgba);else{const s=(0,p.ensureDefined)(this._palettesInfo.color),i=(0,p.ensureDefined)(s.map[e.colorIndexOrRgba]);t=s.values[i]?.childs().color.value()}return{type:0,color:t}}const t=this._gradientColorPropsState();let s,i;if(this._isRGB)null!=e.colorIndexOrRgba1&&(s=this._rgbaFromInteger(e.colorIndexOrRgba1)),null!=e.colorIndexOrRgba2&&(i=this._rgbaFromInteger(e.colorIndexOrRgba2));else{if(null!=e.colorIndexOrRgba1){const t=(0,p.ensureDefined)(this._palettesInfo.color1);s=t.values[(0,p.ensureDefined)(t.map[e.colorIndexOrRgba1])].childs().color.value()}if(null!=e.colorIndexOrRgba2){const t=(0,p.ensureDefined)(this._palettesInfo.color2);i=t.values[(0,p.ensureDefined)(t.map[e.colorIndexOrRgba2])].childs().color.value()}}const r=e.value1??t.value1,n=e.value2??t.value2;return s=s??t.color1,i=i??t.color2,
|
||||
void 0===r||void 0===n||void 0===s&&void 0===i?null:{type:1,color1:s,color2:i,value1:r,value2:n,coordinate1:NaN,coordinate2:NaN}}_plotAId(){return this._fillMetaInfo.objAId}_plotBId(){return this._fillMetaInfo.objBId}_commonColor(){const e=this._fillStyleProps.childs();if(this._gradientFillType){if(!this._hasAllGradientRequiredProps)return ft;const e=this._gradientColorPropsState();return{type:1,color1:e.color1,color2:e.color2,value1:e.value1,value2:e.value2,coordinate1:NaN,coordinate2:NaN}}return{type:0,color:e.color.value()}}_transparency(){return this._fillStyleProps.childs().transparency?.value()??0}_visible(){return this._fillStyleProps.childs().visible.value()}_priceScale(){return this.isForceOverlay()?this._model.mainSeries().priceScale():this._source.priceScale()}_initBandIndexes(e,t){this._bandAKey=null,this._bandBKey=null;const s=this._source.metaInfo().bands;if(void 0!==s)for(let i=0;i<s.length;++i){const r=s[i];null!==this._bandAKey||r.id!==e?null===this._bandBKey&&r.id===t&&(this._bandBKey=i):this._bandAKey=i}}_gradientColorPropsState(){if(null===this._gradientPropsStateCache){const e=this._fillStyleProps.state();this._gradientPropsStateCache={color1:this._gradientStaticState.color1??e.topColor,color2:this._gradientStaticState.color2??e.bottomColor,value1:this._gradientStaticState.value1??e.topValue,value2:this._gradientStaticState.value2??e.bottomValue}}return this._gradientPropsStateCache}}var yt=s(13212),gt=s(27909),vt=s(94119);class St{constructor(e,t){this._invalidated=!0,this._lineRenderer=new vt.HorizontalLineRenderer,this._source=t,this._points=[new fe.Point(-1,-1)],this._invalidated=!0,this._properties=e}update(e){"hover-change"!==e.type&&(this._invalidated=!0)}renderer(){this._invalidated&&(this._updateImpl(),this._invalidated=!1);const e={y:this._points[0].y,color:this._properties.childs().color.value(),linewidth:this._properties.childs().linewidth.value(),linestyle:this._properties.childs().linestyle.value()};return this._lineRenderer.setData(e),this._lineRenderer}_updateImpl(){const e=this._source.priceScale();if(!e||e.isEmpty())return void(this._points[0]=new fe.Point(-1,-1));const t=this._properties.childs().value.value(),s=this._source.firstValue(),i=(0,_.isNumber)(t)&&null!==s?e.priceToCoordinate(t,s):NaN;this._points[0]=new fe.Point(-1,i)}}var bt=s(20820);class Pt extends bt.MediaCoordinatesPaneRenderer{constructor(){super(),this._data=null,this._data=null}setData(e=null){this._data=e}hitTest(){return null}_drawImpl(e){if(null===this._data||0===this._data.points.length)return;const t=e.context,s=e.mediaSize.width;if(this._data.gradient){const e=t.createLinearGradient(0,this._data.coordinate1,0,this._data.coordinate2);e.addColorStop(0,this._data.backColor1??"transparent"),e.addColorStop(1,this._data.backColor2??"transparent"),t.fillStyle=e}else t.fillStyle=this._data.backcolor;const i=Math.min(this._data.points[0],this._data.points[1]),r=Math.max(this._data.points[0],this._data.points[1]);t.fillRect(0,i,s,r-i)}}class wt{constructor(e){this._bandBgRenderer=new Pt,this._invalidated=!0,
|
||||
this._source=e}update(e){"hover-change"!==e.type&&(this._invalidated=!0)}renderer(){return this._invalidated&&(this._updateImpl(),this._invalidated=!1),this._bandBgRenderer}_updateImpl(){this._bandBgRenderer.setData(null);const e=this._source.properties().childs(),t=e.bands;if(t.childCount()<2)return;const s=e.bandsBackground;if(!s?.childs().fillBackground.value())return;const i=t[0].childs(),r=t[1].childs(),n=this._source.priceScale(),o=this._source.firstValue();if(!n||n.isEmpty()||null===o)return;const a=[n.priceToCoordinate(i.value.value(),o),n.priceToCoordinate(r.value.value(),o)],l=(0,p.ensureDefined)(e.bandsBackground).childs(),h=(0,ue.clamp)(l.transparency?.value()??0,0,100);this._bandBgRenderer.setData({gradient:!1,points:a,backcolor:(0,I.generateColor)(l.backgroundColor.value(),h)})}}class It{constructor(e,t,s){this._bandBgRenderer=new Pt,this._bandAKey=null,this._bandBKey=null,this._invalidated=!0,this._source=e,(0,p.assert)("hline_hline"===t.type,"Wrong filledArea type: "+t.type),this._initBandIndexes(t.objAId,t.objBId),this._fillStyleProps=s,this._bandBgRenderer=new Pt,this._gradientFillType=s.hasChild("fillType")&&"gradient"===s.childs().fillType?.value(),this._gradientStaticState={color1:t.topColor,color2:t.bottomColor,value1:t.topValue,value2:t.bottomValue}}update(){this._invalidated=!0}renderer(){return this._invalidated&&(this._updateImpl(),this._invalidated=!1),this._bandBgRenderer}_updateImpl(){if(this._bandBgRenderer.setData(null),!this._fillStyleProps.childs().visible.value())return;if(null===this._bandAKey||null===this._bandBKey)return;const e=(0,p.ensureDefined)(this._source.properties().childs().bands),t=e.childs()[this._bandAKey].childs(),s=e.childs()[this._bandBKey].childs(),i=this._source.priceScale(),r=this._source.firstValue();if(!i||i.isEmpty()||null===r)return;const n=[i.priceToCoordinate(t.value.value(),r),i.priceToCoordinate(s.value.value(),r)],o=(0,ue.clamp)(this._fillStyleProps.childs().transparency?.value()??0,0,100);let a;const l=this._fillStyleProps.childs();if(this._gradientFillType){const e=this._gradientStaticState,t=l,s=e.value1??t.topValue?.value(),h=e.value2??t.bottomValue?.value();if(void 0===s||void 0===h)return;const c=e.color1??t.topColor?.value(),u=e.color2??t.bottomColor?.value();if(void 0===c&&void 0===u)return;a={gradient:!0,points:n,backColor1:c&&(0,I.generateColor)(c,o),backColor2:u&&(0,I.generateColor)(u,o),coordinate1:i.priceToCoordinate(s,r),coordinate2:i.priceToCoordinate(h,r)}}else a={gradient:!1,points:n,backcolor:(0,I.generateColor)(l.color.value(),o)};this._bandBgRenderer.setData(a)}_initBandIndexes(e,t){this._bandAKey=null,this._bandBKey=null;(0,p.ensureDefined)(this._source.metaInfo().bands).forEach(((s,i)=>{null===this._bandAKey&&s.id===e&&(this._bandAKey=i),null===this._bandBKey&&s.id===t&&(this._bandBKey=i)}))}}var xt=s(86252),Ct=s(81922),Vt=s(51304),Mt=s(48943),Tt=s(95059),At=s(91106),Rt=s(63670),Ot=s(30693),Dt=s(28477);class Bt extends Dt.AbstractBarColorer{constructor(e,t){super(),this._rgbaFromInteger=(0,pt.rgbaFromIntegerCached)(),this._study=e,
|
||||
this._plotIndex=t}applyBarStyle(e,t,s,i){if(t)return s;const r=this._study.properties().childs();if(!r.visible.value())return s;const n=this._study.metaInfo(),o=this._study.data();if(!o||0===o.size())return s;const a=n.plots[this._plotIndex],l=this._getOffset();if(this._study.getMinFirstBarIndexForPlot(a.id)>e+l)return s;if(0===r.styles.childs()[a.id].childs().display.value())return s;const h=o.valueAt(e-l);if(null===h)return s;let c=h[this._plotIndex+1];if(null==c)return s;if(c=Math.round(c),n.isRGB)s.barColor=this._rgbaFromInteger(c),s.upColor=s.barColor,s.downColor=s.barColor;else{const e=n.plots[this._plotIndex];if("palette"in e){const t=e.palette,i=r.palettes.childs()[t],o=(0,p.ensureDefined)(n.palettes?.[t]),a=o.valToIndex?(0,p.ensureDefined)(o.valToIndex[c]):c,l=i.childs().colors.childs()[a].childs().color.value();s.barColor=l,s.upColor=l,s.downColor=l}}return s}firstColoredBar(e){let t=e;for(const s of this._backColorers)t=Math.min(t,s.firstColoredBar(e)??1/0);const s=this._getOffset();t=Math.min(t,e+s);const i=this._getBars().firstIndex(),r=Math.max(t,i??-1/0),n=this._study.metaInfo().plots[this._plotIndex];return Math.max(this._study.getMinFirstBarIndexForPlot(n.id),r)}_getBars(){return this._study.series().bars()}_getOffset(){const e=this._study.metaInfo().plots[this._plotIndex];return this._study.offset(e.id)}}var Nt=s(76422),Ft=s(67563),kt=s(64717);class Et extends at.PanePriceAxisView{constructor(e,t,s,i){super(e,t,s),this._dataSource=t,this._isForceOverlay=t.metaInfo().isPlotForceOverlay(i)}_position(){const e=this._isForceOverlay?this._chartModel.mainPane():this._chartModel.paneForSource(this._dataSource);if(null===e)return null;const t=this._isForceOverlay?this._chartModel.mainSeries().priceScale():this._dataSource.priceScale();if(null===t)return null;let s=e.priceScalePosition(t);return"overlay"===s&&(s=e.priceScalePosition(e.defaultPriceScale())),"overlay"===s?null:s}}var Lt=s(56265);class Ht{constructor(e,t){this._study=e,this._valuesProvider=new F.StudyValuesProvider(e,t,!1,!1)}getItems(){const e=this._study.properties().childs(),t=this._valuesProvider.getItems();for(const s of t){const t=s.id,i=(0,p.ensureDefined)(e.styles.childs()[t]).childs().display.value();s.visible=0!==i}return t}getValues(e){const t=this._valuesProvider.getValues(e),s=this._study.plots().lastIndex(),i=this._study.plots().firstIndex();if(null===s||null===i)return null;for(const r of t){const t=e-this._study.offset(r.id);(t>s||t<i)&&(r.value="")}return t}}var Wt=s(76559),zt=s(72207),Ut=s(3618),jt=s(35727);const Gt=(0,f.getLogger)("Chart.Study"),$t=m.t(null,void 0,s(52969)),Kt=!1;var Yt,Xt;function qt(){return{fields:[],useMainSeriesRange:!1,baseValueMinMax:null}}!function(e){e.PaneViews="study-pane-views"}(Yt||(Yt={})),function(e){e[e.DefaultPriceScale=100]="DefaultPriceScale"}(Xt||(Xt={}));const Jt={symbolsForDisplay:!1,symbolsForChartApi:!0,skipHiddenInputs:!1,skipFakeInputs:!1,skipBooleanInputs:ee.enabled("dont_show_boolean_study_arguments"),asObject:!0,skippedGroups:[],skippedInputs:[],noExchanges:!1,noResolution:!1,
|
||||
keepOptionalSymbolsEmpty:!1,skipColorInputs:!1,skipTimeInputs:!1,skipOptionalEmptySymbolInputs:!1,skipTextareaInputs:!1,priceInputsForDisplay:!1},Zt=ee.enabled("study_symbol_ticker_description"),Qt=ee.enabled("hide_main_series_symbol_from_indicator_legend"),es=ee.enabled("datasource_copypaste"),ts=ee.enabled("hide_unresolved_symbols_in_legend");function ss(e,t){const s=e.plots[t];if(!s||!(0,L.isOhlcPlot)(s))return!1;const i=s.target,r=e.defaults.styles&&e.defaults.styles[i],n=e.defaults.ohlcPlots&&e.defaults.ohlcPlots[i],o=e.ohlcPlots&&e.ohlcPlots[i];return r&&(0,L.isOhlcPlotStyleBars)(r)||n&&(0,L.isOhlcPlotStyleBars)(n)||!!o&&(0,L.isOhlcPlotStyleBars)(o)}function is(e,t){const s=e.plots[t];if(!s||!(0,L.isOhlcPlot)(s))return!1;const i=s.target,r=e.defaults.styles&&e.defaults.styles[i],n=e.defaults.ohlcPlots&&e.defaults.ohlcPlots[i],o=e.ohlcPlots&&e.ohlcPlots[i];return r&&(0,L.isOhlcPlotStyleCandles)(r)||n&&(0,L.isOhlcPlotStyleCandles)(n)||!!o&&(0,L.isOhlcPlotStyleCandles)(o)}function rs(e,t){(0,p.assert)(void 0!==e,"zOrder must be defined"),(0,p.assert)(!t.has(e),"zOrder must be unique")}function ns(e,t){return e.plots.some((e=>((0,L.isColorerPlot)(e)||(0,L.isDataPlot)(e))&&e.target===t))}function os(e,t,s){let i=0,r=0;return Math.sign(r)-Math.sign(i)}function as(e){const t=(0,Mt.combine)((e=>e.map((e=>as(e.parentSourcesVW().weakReference())))),e);return(0,Mt.accumulate)(((e,t)=>Array.from(new Set(t.concat(e.flat(20))))),t.ownership(),e).ownership()}function ls(e){return"inherit"===e.type&&(e.type="price"),e}function hs(e,t,s,i){{const t=(0,_.isNumber)(i)?i:void 0,r=jt.customFormatters?.studyFormatterFactory?.(e,s,t)??null;if(null!==r)return r}if(null!==t)switch(e.type){case"inherit":case"price":return new Ft.PriceFormatter({priceScale:t});case"volume":return(0,Lt.getVolumeFormatter)(Math.log10(t));case"percent":return(0,Lt.getPercentageFormatter)(Math.log10(t))}if("inherit"===e.type)return null;const r=(0,_.isNumber)(e.precision)?Math.pow(10,e.precision):void 0;switch(e.type){case"price":return new Ft.PriceFormatter({priceScale:r});case"volume":{let t=e.precision;return void 0===t&&(t=s&&(0,_.isNumber)(s.volume_precision)?s.volume_precision:0),(0,Lt.getVolumeFormatter)(t)}case"percent":return(0,Lt.getPercentageFormatter)(void 0===r?void 0:Math.log10(r));default:return Gt.logWarn(`Unsupported format type: ${e.type}`),null}}const cs=new Set(["first_visible_bar_time","last_visible_bar_time","subscribeRealtime"]);class us extends V.PriceDataSource{constructor(e,t,s,i,r,n,o){super(e),this._onStart=new w.Delegate,this._restarting=!1,this._paneViews=[],this._forceOverlaysPaneViews=[],this._legendView=null,this._floatingTooltipView=null,this._priceAxisViews=[],this._forceOverlayPriceAxisViews=[],this._priceAxisViewsBase=[],this._resolvedSymbols={},this._resolvedSymbolsByInput={},this._priceLinesAxisViews=[],this._labelPaneViews=[],this._forceOverlayLabelPaneViews=[],this._ownFirstValue=null,this._formatter=null,this._defaultFormatter=null,this._dataUpdated=new w.Delegate,this._currencySourceSymbolInputProperty=null,
|
||||
this._pineSourceCodeModel=null,this._alertSourceModel=null,this._onHibernationStateChange=new w.Delegate,this._symbolsResolved=new w.Delegate,this._statusChanged=new w.Delegate,this._inputsAnchorsPaneView=null,this._inputsLinesPaneView=null,this._inputsTimeAxisPaneViews=[],this._inputsPriceAxisPaneViews=[],this._sources=new P.WatchedObject([],y.compareTwoCollectionsByIds),this._status=new b.WatchedValue({type:xt.StudyStatusType.Undefined}),this._compileActiveStatus=new P.WatchedObject(null),this._compileErrorStatus=new P.WatchedObject(null),this._wasCompletedBefore=!1,this._isStarted=!1,this._isSubscribedToSessionId=!1,this._titleStrCache={},this._titleInPartsCache={},this._inputsInPartsCache={},this._children=[],this._graphicsPriceAxisViews=[],this._serverPlotOffsets=new P.WatchedObject({}),this._ongoingDataUpdate=Promise.resolve(),this._studyModified=!1,this._tagsChanged=new w.Delegate,this._turnaround="st0",this._pendingResolveSymbols=new Map,this._onIsActualIntervalChange=new w.Delegate,this._childStudyByRebind=new w.Delegate,this._lastNonEmptyPlotRowCache={},this._startMovingPoint=null,this._processHibernateBound=this.processHibernate.bind(this,1),this._maxOffset=new b.WatchedValue(0),this._currencySourceSymbolInfo=null,this._graphicsPriceRangeGroups=null,this._graphicsViewsReady=!1,this._visibleTimeRangeInputs=null,this._turnaroundCounter=0,this._deferredPinePatchProps=!1,this._propertiesPatched=Promise.resolve(),this._resetPropertiesPatched=Promise.resolve(),this._abortPatchPropsController=new AbortController,this._abortResetPatchPropsController=new AbortController,this._aboutToBeDestroyed=new w.Delegate,this._definitionsViewModel=null,this._plotFormatters=new Map,this._showPineVersionInStatusLine=new b.WatchedValue(!1).spawn(),this._onParentSourcesChanges=new w.Delegate,this._statusChangesSubscriber={},this._calculationTime=new b.WatchedValue(0),this._stateForAlertCache=null,this._idForAlertCache=null,this._idForAlertWV=new b.WatchedValue(""),this._chartApi=e.chartApi(),this._properties=t,this._originalMetaInfo=r,this._metaInfo=new b.WatchedValue(i),this._studyName=(0,Mt.combine)((e=>e.useVersionFromMetaInfo?(0,A.getStudyIdWithVersion)(e):this._getStudyIdWithLatestVersion()),this._metaInfo.weakReference()),this._hideMatches=i.inputs.filter((e=>e.hideWhenPlotsHidden)).map((e=>({id:e.id,plotIds:e.hideWhenPlotsHidden||[]}))),this._series=this._model.mainSeries(),this._series.onIntervalChanged().subscribe(this,this._calcIsActualInterval),this._series.alertCreationAvailable().subscribe(this._updateAlertCreationAvailable.bind(this)),this._showStudyArgumentsProperty=(0,X.combineProperty)(((e,t)=>e&&t),e.properties().childs().paneProperties.childs().legendProperties.childs().showStudyArguments.weakReference(),this._properties.childs().showLegendInputs.weakReference()),this._model.symbolAliasService()?.onAliasChanged().subscribe(this,(()=>{this._onFormatterPropsChanged(),this.invalidateTitleCache()})),e.collapsed().subscribe(this._processHibernateBound),this._sources.setValue(s),
|
||||
A.StudyMetaInfo.setChildStudyMetaInfoPropertiesSourceId(i,s[0]?.id(),t),s.forEach((e=>{e.setChild(this)})),[this._series,...s].forEach((e=>{e.currencyChanged().subscribe(this,this._onSourceCurrencyChanged),e.unitChanged().subscribe(this,this._onSourceUnitChanged),e.priceRangeReadyChanged().subscribe(this,this._onSourcePriceRangeReadyChanged),e.formatterChanged().subscribe(this,this._onSourceFormatterChanged),e.priceStepChanged().subscribe(this,this._onSourcePriceStepChanged)})),Zt&&this._model.mainSeries().properties().childs().statusViewStyle.childs().symbolTextSource.subscribe(this,(()=>{this.invalidateTitleCache(!0)}));const a=this._properties.childs();for(const e of A.StudyMetaInfo.getSourceInputIds(i))a.inputs.childs()[e]?.subscribe(this,this._onSourceInputChanged);this._plotOffsets=(0,Mt.combine)(((e,t,s,i)=>(i.plots??[]).reduce(((i,r)=>{const n=r.id,o=(e[n]??0)+(s?.childs()[n]?.childs().val.value()??0)+(t?.childs().val.value()??0);return i[n]=o,i}),{})),this._serverPlotOffsets.weakReference(),(0,X.createWVFromGetterAndSubscription)((()=>this.properties().childs().offset),this.properties().childs().offset??new w.Delegate).ownership(),(0,X.createWVFromGetterAndSubscription)((()=>this.properties().childs().offsets),this.properties().childs().offsets??new w.Delegate).ownership(),this._metaInfo.weakReference()),this._properties.subscribe(this,this._onPropertiesChanged),a.visible.subscribe(this,this._visibleChanged),a.visible.subscribe(this,(()=>this.processHibernate())),a.intervalsVisibilities.subscribe(this,this._calcIsActualInterval),a.inputs.subscribe(this,this._updateMaxOffsetValue),void 0!==a.offsets&&a.offsets.subscribe(this,this._updateMaxOffsetValue),void 0!==a.offset&&a.offset.subscribe(this,this._updateMaxOffsetValue),this._initializeCurrencySource(),W.hideAllIndicators().subscribe(this,this._visibleChanged);for(let e=0;e<i.plots.length;e++){const t=i.plots[e],s=t.id,r=a.styles.childs()[s],n=(0,L.isBarColorerPlot)(t);r&&!r.hasChild("display")&&r.merge({display:15}),r?.childs().display.subscribe(this,(()=>{this.processHibernate(),this.invalidateTitleCache(),n&&this._series.invalidateBarColorerCache()}))}for(const e of Object.keys(i.graphics))for(const t of Object.keys(i.graphics[e])){const s=a.graphics.childs()[e]?.childs()[t];s&&s.childs().visible&&(0,p.ensureDefined)(s.childs().visible).subscribe(this,(()=>this.processHibernate()))}this._isActualInterval=(0,Ct.isActualInterval)(this._series.intervalObj().value(),a.intervalsVisibilities),this._initializeStudyInputsPaneViews(),this._handler=e=>this._onData(e),this._valuesProvider=new F.StudyValuesProvider(this,e),this._tableViewValuesProvider=new Ht(this,e),this._graphics=new R.LiveStudyGraphics(i.graphics),this._chartApi=e.chartApi(),this._invalidateLastNonEmptyPlotRowCache(),this._data=new T.PlotList((0,kt.studyPlotFunctionMap)(i),kt.studyEmptyPlotValuePredicate),this._createViews(),this._recreatePriceFormattingDependencies(this._series.symbolInfo()),a.precision.subscribe(this,this._onFormatterPropsChanged),
|
||||
this._metaInfo.subscribe((()=>this._onFormatterPropsChanged())),this._showStudyArgumentsProperty.subscribe(this,(()=>this.invalidateTitleCache(!0))),a.inputs.subscribe(this,(()=>this.invalidateTitleCache(!0))),ee.enabled("update_study_formatter_on_symbol_resolve")&&e.mainSeries().dataEvents().symbolResolved().subscribe(this,this._recreatePriceFormattingDependencies),e.mainSeries().dataEvents().symbolResolved().subscribe(this,(()=>this.invalidateTitleCache(!0)));const l=new Set;if(this._simplePlotsCount=i.plots.filter(((e,t)=>{if((0,L.isLinePlot)(e))return!0;if((0,L.isOhlcPlot)(e)){const t=e.target;return!l.has(t)&&(l.add(t),!0)}return!1})).length,this.hasBarColorer()&&a.visible.subscribe(this,(()=>e.mainSeries().invalidateBarStylesCache)),this._definitionsViewModel=null,this._updateMaxOffsetValue(),i.inputs.some((e=>cs.has(e.id)))){this._visibleTimeRangeInputs=e.visibleRangeStudiesInputs().spawn();const t=this._visibleTimeRangeInputs.value();let s=null!==t;this._visibleTimeRangeInputs.subscribe((e=>{const t=()=>{this._onVisibleTimeRangeInputsChanged(e),s!==(null!==e)&&(s=null!==e,!s||this._restarting||this.isStarted()||this.start(!0))};this._statusChanged.unsubscribeAll(this._statusChangesSubscriber),this._status.value().type===xt.StudyStatusType.Loading?this._statusChanged.subscribe(this._statusChangesSubscriber,t,!0):t()})),t&&this._updateVisibleTimeRangeInputs(t,!1)}this._properties.setNameInOwner((0,Wt.propertyPathForSource)(this)),o&&this._pinePatchProps();const h=as(this.parentSourcesVW().weakReference());this._allOwnerSources=(0,Mt.combine)(((e,t)=>{const s=[];for(;null!==t;)s.push(t),t=t.ownerSource();return s}),h,(0,X.createWVFromGetterAndSubscription)((()=>this.ownerSource()),this.ownerSourceChanged()).ownership()),this._symbolSource=(0,Mt.combine)((e=>this._firstSourceOrSeries().symbolSource()),this._allOwnerSources.weakReference())}destroy(){this._signlePerformanceValue?.destroy(),this._aboutToBeDestroyed.fire(),null!==this._definitionsViewModel&&(this._definitionsViewModel.destroy(),this._definitionsViewModel=null),this._showStudyArgumentsProperty.unsubscribeAll(this),this._model.mainSeries().dataEvents().symbolResolved().unsubscribeAll(this),this._model.symbolAliasService()?.onAliasChanged().unsubscribeAll(this);this.parentSources().forEach((e=>{e.currencyChanged().unsubscribeAll(this),e.unitChanged().unsubscribeAll(this),e.priceRangeReadyChanged().unsubscribeAll(this),e.formatterChanged().unsubscribeAll(this),e.priceStepChanged().unsubscribeAll(this)})),this._series.properties().childs().statusViewStyle.childs().symbolTextSource.unsubscribeAll(this),this._series.onIntervalChanged().unsubscribeAll(this),this._series.alertCreationAvailable().unsubscribe(this._updateAlertCreationAvailable),this.formatterChanged().unsubscribe(this,this.invalidateTitleCache),W.hideAllIndicators().unsubscribe(this,this._visibleChanged),this._model.collapsed().unsubscribe(this._processHibernateBound),null!==this._currencySourceSymbolInputProperty&&this._currencySourceSymbolInputProperty.unsubscribeAll(this),
|
||||
this._legendView?.destroy(),this._floatingTooltipView?.destroy(),this._pineSourceCodeModel?.get()?.destroy(),this._visibleTimeRangeInputs?.destroy(),this._showPineVersionInStatusLine.destroy(),this._alertStateVersion?.destroy(),this._metaInfo.destroy(),this._studyName.destroy(),this._allOwnerSources.destroy(),this._sources.destroy(),this._symbolSource.destroy(),this._status.destroy(),this._compileActiveStatus.destroy(),this._compileErrorStatus.destroy(),this._plotOffsets.destroy(),this._serverPlotOffsets.destroy(),this._properties.destroy(),super.destroy()}setId(e){super.setId(e),this._properties.setNameInOwner((0,Wt.propertyPathForSource)(this))}properties(){return this._properties}propertiesPatched(){return this._propertiesPatched}isDraggable(){return!this._metaInfo.value().linkedToSeries}logs(){return null}logLevelMask(){const e=this._properties.childs().inputs.childs().__log_level.value();if(!(0,_.isNumber)(e)||e<0||e>7)throw new Error(`Value of log level is unexpected, current value is ${e}, but expected values from 0 to 7`);return{error:Boolean(1&e),warning:Boolean(2&e),info:Boolean(4&e)}}setLogLevelMask(e){const t=(Number(e.error)&&1)|(Number(e.warning)&&2)|(Number(e.info)&&4);this._properties.childs().inputs.childs().__log_level.setValue(t)}performance(){return new b.WatchedValue(null)}profilingEnabled(){return!!this._properties.childs().inputs.childs().__profile?.value()}enableProfiling(e){this._properties.childs().inputs.childs().__profile?.setValue(e)}onAboutToBeDestroyed(){return this._aboutToBeDestroyed}priceScale(e){return e?this._model.mainSeries().priceScale():super.priceScale()}lastValueData(e,t,s){const i={noData:!0},r=this.metaInfo().isPlotForceOverlay(e),n=r?this._model.mainSeries().priceScale():this.priceScale();if(this._model.timeScale().isEmpty()||null===n||n.isEmpty()||this.data().isEmpty())return i;const o=this._model.timeScale().visibleBarsStrictRange(),a=this.firstValue(!0,r);if(null===o||null===a)return i;if(!this._properties.childs().visible.value())return i;const l=this._properties.childs().styles,h=this._properties.childs().ohlcPlots;let c,u;if(l&&l.childs()[e]&&(c=l.childs()[e]),h&&h.childs()[e]&&(c=h.childs()[e]),!c||0===c.childs().display.value())return i;const d=this.metaInfo().plots;for(u=0;u<d.length;u++){const t=d[u];if(t.id===e||(0,L.isOhlcClosePlot)(t)&&t.target===e)break}const p=u+1,f=this.offset(e),m=this.nearestIndex(o.lastBar()-f,O.PlotRowSearchMode.NearestLeft,p);if(void 0===m)return i;const y=this._lastNonEmptyPlotRow(p),g=null!==y&&o.contains(y.index),v=null!==y?y.value:null,S=t||g?v:this.data().valueAt(m);if(!S||!(0,_.isNumber)(S[p]))return i;const b=S[p],P=this._valuesProvider.getPlotColor(u,S),w=n.priceToCoordinate(b,a),I=this.plotFormatter(e).format(b),x={...n.getFormattedValues(b,a,void 0,I),noData:!1,color:P,floatCoordinate:w,coordinate:w};return s&&(x.price=b),x}isFailed(){return this.status().type===xt.StudyStatusType.Error}isLoading(){return this.status().type===xt.StudyStatusType.Loading}isCompleted(){return this.status().type===xt.StudyStatusType.Completed}
|
||||
isSymbolInvalid(){const e=this._status.value();return e.type===xt.StudyStatusType.Error&&e.errorDescription.error===$t}series(){return this._series}model(){return this._model}state(e,t){const s=(0,p.ensureNotNull)((0,g.getStudyClassName)(this.constructor)),i=this.metaInfo(),r={type:s,id:this.id(),state:this.properties().state(),zorder:this.zorder(),ownFirstValue:this.isVisible()?null:this._ownFirstValue,metaInfo:this._originalMetaInfo.state()},n=d(r.metaInfo,this._metaInfo.value().state());(0,o.default)(n)||(r.metaInfoPatch=n);const a=this._sources.value().map((e=>e.id()));if(a.length&&(r.parentSources=a),e){let e=this.data();const t=this._model.timeScale(),s=this._seriesDataRangeToSave(e);null!==s&&(e=e.range(s.firstBar(),s.lastBar())),r.data=e.state(),r.data.symbols=this._resolvedSymbols,r.data.graphics=(0,R.saveStudyGraphics)(this.graphics(),t.visibleBarsStrictRange()),r.data.plotOffsets=this._serverPlotOffsets.value()}this.ownerSource()&&(r.ownerSource=this.ownerSource()?.id());for(let e=0;e<i.inputs.length;e++)if("bar_time"===i.inputs[e].type){const t=i.inputs[e].id,s=r.state.inputs[t];if(s<0){const e=this._rightOffsetToUnixTime(-s);r.state.inputs[t]=e&&e>=0?e:0}}if(r.state?.inputs){const e=r.metaInfo.inputs.find((e=>"ILScript"===e.name));e&&delete r.state.inputs[e.id],delete r.state.inputs.__log_level,delete r.state.inputs.__profile}const l=this.stateCustomFields();return l&&(r.customFields=l),r}stateCustomFields(){const e=this._compileErrorStatus.value();if(e)return{compileErrorDescription:e.errorDescription}}restoreStateCustomFields(e){const t=e.compileErrorDescription;t&&this.setErrorCompilation([(0,p.ensureDefined)(t.editorError)])}restoreData(e){this._invalidateLastNonEmptyPlotRowCache(),this.data().restoreState(e),this._resolvedSymbols=e.symbols??{},this._graphics=e.graphics?(0,R.loadStudyGraphics)(e.graphics):(0,R.emptyStudyGraphics)(),this._postProcessGraphics(),this._serverPlotOffsets.setValue(e.plotOffsets??{}),this._setStatus({type:xt.StudyStatusType.Completed},!0)}hasStateForAlert(){return!1}stateForAlert(){throw new Error("Not implemented")}async stateForAlertAsync(){throw new Error("Not implemented")}idForAlert(){return super.idForAlert()}hasBarColorer(){return this._metaInfo.value().plots.some(L.isBarColorerPlot)}barColorer(){const e=this._metaInfo.value().plots;let t=null;for(let s=e.length-1;s>=0;s--)if((0,L.isBarColorerPlot)(e[s])){const e=new Bt(this,s);null===t?t=e:t.pushBackBarColorer(e)}return t}isSavedInStudyTemplates(){return this._metaInfo.value().inputs.every((e=>"bar_time"!==e.type))}restart(e){this._restarting=!0,this.clearData(),(e||ee.enabled("stop_study_on_restart"))&&this.stop(),setTimeout(this.start.bind(this),0)}stop(e,t){if(!0===e&&this._children)for(const e of this._children)e.stop(!0);this._stopStudyOnServer(),this.clearData(),this._unsubscribeToSessionId(),this.recalculate()}disconnect(){this._isStarted=!1,this._model.isSnapshot()||(this._resolvedSymbols={},this._resolvedSymbolsByInput={})}sourceId(){return this._id.value()}parentSources(){return this._sources.value()}
|
||||
parentSourcesVW(){return this._sources}symbolSource(){return this._symbolSource.value()}symbolSourceWV(){return this._symbolSource.readonly()}valueAt(e,t){return this.symbolSource().valueAt(e,t)}barsProvider(){return this._firstSourceOrSeries().barsProvider()}ownerSource(){return this.isChildStudy()?this._sources.value()[0]:super.ownerSource()}isChildStudy(){return this._sources.value().length>0}hasChildren(){return this._children.length>0}isStarted(){return this._isStarted}isRestarting(){return this._restarting}isActualInterval(){return this._isActualInterval}onIsActualIntervalChange(){return this._onIsActualIntervalChange}isVisible(){const e=this._properties.childs();if(this._model.collapsed().value()||!e.visible.value()||!this.isActualInterval())return!1;const t=this.metaInfo();if(t.plots.length>0)for(let s=0;s<t.plots.length;s++){const i=t.plots[s].id,r=e.styles.childs()[i];if(void 0===r)continue;if(0!==r.childs().display.value())return!0}if(t.bands)for(let s=0;s<t.bands.length;s++)if(e.bands.childs()[s].childs().visible.value())return!0;for(const s of Object.keys(t.graphics))for(const i of Object.keys(t.graphics[s])){const t=e.graphics.childs()[s]?.childs()[i];if(void 0!==t&&(t.child("visible")?.value()??1))return!0}if(t.filledAreas)for(let s=0;s<t.filledAreas.length;s++)if(e.filledAreasStyle.childs()[t.filledAreas[s].id].childs().visible.value())return!0;return!1}async start(e,t,s){const i=this._model.mainSeries();await i.seriesCreated(),await Promise.all(this._sources.value().filter((e=>e.isHibernated())).map((e=>e.start())));const r=!(this.isHibernationAllowed()&&!this.isVisible())||!0===t;if(this._chartApi&&this._chartApi.isConnected().value()&&r)try{await this._allSymbolsAreResolved(),await this._startAfterSymbolsResolved(e,t)}catch(e){const t=`ERROR: ${this._debugId()} start failed, ${e}`;Gt.logError(t),this._restarting=!1,"TooManyStudies"===e?.cause&&(0,S.showTooManyStudiesNotice)(this._chartApi.getStudyCounter())}r||void 0!==this._inputs||(this._inputs=this._apiInputs())}replaceData(e,t,s){this._invalidateLastNonEmptyPlotRowCache(),this.data().remove(e+1),this.data().addTail(s,t)}inputs(e){const t=(0,n.default)((0,_.clone)(Jt),e||{});t.skipOptionalEmptySymbolInputs&&(t.keepOptionalSymbolsEmpty=!0);return this._buildInputs(t)}data(){return this._data}moveData(e){this._ongoingDataUpdate=this._ongoingDataUpdate.then((()=>{this._invalidateLastNonEmptyPlotRowCache(),this._moveData(e),this.data().isEmpty()||this._onIndexDiffsApplied(e)}))}plots(){return this.data()}metaInfo(){return this._metaInfo.value()}status(){return this._compileActiveStatus.value()??this._compileErrorStatus.value()??this._status.value()}name(e){return e?this.metaInfo().shortDescription||"Study":this.metaInfo().description||"Study"}title(e,t,s,i,r,n){i=void 0===i?!this._showStudyArgumentsProperty.value():i;const o=JSON.stringify([e,t,s,i,r,n]);if(this._titleStrCache[o])return this._titleStrCache[o];if(this._titleInPartsCache[o])return this._joinTitlesParts(this._titleInPartsCache[o]);const a=this._title(e,t,s,i,r,n)
|
||||
;return this._titleStrCache[o]=a,a}titleInParts(e,t,s,i,r){i=void 0===i?!this._showStudyArgumentsProperty.value():i;const n=JSON.stringify([e,t,s,i,r]);if(this._titleInPartsCache[n])return this._titleInPartsCache[n];const o=this._titleInParts(e,t,s,i,r);return this._titleInPartsCache[n]=o,o}inputsInParts(e,t=!0,s,i,r){const n=!this._showStudyArgumentsProperty.value(),o=ee.enabled("always_show_study_symbol_input_values_in_legend"),a=n&&o;if(n&&!o&&e===Y.TitleDisplayTarget.StatusLine)return null;const l=JSON.stringify([e,t,s,i,r]);if(this._inputsInPartsCache[l])return this._inputsInPartsCache[l];const h=[],c=this.metaInfo(),u=this._titleInputs((0,zt.toInputDisplayFlags)(e),i,!0),d=c.inputs.filter((e=>u.hasOwnProperty(e.id)&&(!a||"symbol"===e.type||e?.isAlwaysShownInLegend))).map((e=>{let t=u[e.id];if("symbol"===e.type){const s=this._properties.childs().inputs.child(e.id)?.value();if(s){const e=this._resolvedSymbolsByInput[s];e&&(t=this._model.symbolAliasService()?.getAliasByProName(e.pro_name)?.aliasName??t)}}return{meta:e,value:t}})),f={};if(d.length>0){if(this.isChildStudy())for(let s=0;s<c.inputs.length;++s){const n=c.inputs[s];if(!A.StudyMetaInfo.isSourceInput(n))continue;const o=n.id,a=(0,p.ensureDefined)(this._properties.childs().inputs.child(o)).value();if(a.indexOf("$")>=0){const s=this.parentSourceForInput(a);if(s instanceof us){const n=s.metaInfo(),o=s.title(e,t,{},!0,i,r);if(1===n.plots.length)f[a]=o;else{const e=a.split("$")[1],t=n.plots[parseInt(e)]?.id,s=n.styles&&n.styles[t],i=s&&s.title||t;f[a]=o+": "+i}}}}d.forEach((({meta:e,value:t})=>{let i;i="time"===e.type?new Date(t).toISOString():(0,_.isNumber)(t)?(0,Lt.getNumericFormatter)().format(t):f&&f[t.toString()]||t.toString(),s&&s[i.toString()]&&(i=s[i.toString()]),h.push({title:(0,Ut.getTranslatedInputTitle)(e.name),value:i})}))}return this._inputsInPartsCache[l]=h,h}invalidateTitleCache(e){if(this._titleStrCache={},this._titleInPartsCache={},this._inputsInPartsCache={},!0===e&&this._children)for(let t=0;t<this._children.length;++t)this._children[t].invalidateTitleCache(e)}graphics(){return this._graphics}graphicsInfo(){return this._metaInfo.value().graphics}priceLabelText(e){const t=this._metaInfo.value(),s=t.styles,i=t.ohlcPlots;let r;s&&s[e]&&(r=s[e]),i&&i[e]&&(r=i[e]);const n=(0,p.ensureDefined)(r).title;return 1!==this._simplePlotsCount||(0,L.isPlotTitleDefined)(n)?t.is_price_study&&n!==t.shortDescription?""===n?t.shortDescription:t.shortDescription+":"+n:n:t.shortDescription}setOwnFirstValue(e){this._ownFirstValue=e}firstValue(e,t){if(t)return this._series.firstValue();const s=this._metaInfo.value();if(!this.isChildStudy()&&"Compare@tv-basicstudies"===s.id||!s.is_price_study){const t=this._model.timeScale().visibleBarsStrictRange();if(null===t)return null;const i=this.properties().childs();if(!i.visible.value()||!this.isActualInterval()||null!==this._startMovingPoint)return this._ownFirstValue;const r=t.firstBar(),n=t.lastBar();let o=null;if(null===o){const t=new Set,a=s.filledAreas||[];for(let e=0;e<a.length;e++){const s=a[e]
|
||||
;i.filledAreasStyle.childs()[s.id].childs().visible.value()&&(t.add(s.objAId),t.add(s.objBId))}const l=s.plots||[];for(const a of this.data().rangeIterator(r,n)){const r=a.value;for(let n=0;n<l.length;++n){const a=l[n],h=a.id;if((0,L.isColorerPlot)(a)||s.isPlotForceOverlay(h))continue;const c=r[n+1];if(null==c)continue;if((0!==(0,p.ensureDefined)(i.styles.childs()[h]).childs().display.value()||t.has(h))&&!(e&&Math.abs(c)<1e-10)){o=c;break}}if(null!==o)break}}return this._ownFirstValue=o,null!==o?o:this._bandsFirstValue(e)}if(this.isChildStudy()){const e=this._getNonPriceParent();if(e&&this.priceScale()===e.priceScale())return null!==e._ownFirstValue?e._ownFirstValue:e.firstValue()}return this._series.firstValue()}desiredPriceScalePosition(){if(this.metaInfo().isTVScriptStub)return"overlay";if(this.metaInfo().linkedToSeries)return"as-series";switch(this.metaInfo().priceScale){case 1:return"left";case 0:return"right";case 2:return"overlay";default:return null}}offset(e){return this._plotOffsets.value()?.[e]??0}tags(){const e=this._metaInfo.value();return!e.description||e.isTVScriptStub||e.is_hidden_study||e.isTVScript&&"tv-scripting"===e.productId?[]:[e.description]}copiable(){return es&&!this.isChildStudy()}setPriceScale(e){super.setPriceScale(e),(0,Nt.emit)("study_event",this.id(),"price_scale_changed")}priceRange(e,t,s){let i=null;const r=this._metaInfo.value(),n=this._fillPrecalculatedAutoscaleInfo(e,t,s);let o=this.data().minMaxOnRangeCached(e,t,n.fields);if(o=(0,T.mergeMinMax)(n.baseValueMinMax,o),n.useMainSeriesRange){const s=[{name:"low",offset:0},{name:"high",offset:0}],i=this.series().data().bars().minMaxOnRangeCached(e,t,s);o=(0,T.mergeMinMax)(o,i)}if(null!==o&&(i=new M.PriceRange(o.min,o.max)),r.bands&&s.targetPriceScale===this.priceScale())for(let e=0;e<r.bands.length;e++){const t=(0,p.ensureDefined)(this._properties.childs().bands.childs()[e]).childs();if(t.visible.value()){const e=t.value.value();if(!(0,_.isNumber)(e))continue;i?i.apply(e,e):i=new M.PriceRange(e,e)}}return this._postProcessPriceRange(i,s)}autoScaleInfo(e,t,s){const i=this.priceRange(e,t,s),r=(this.priceScale()===this._series.priceScale()||(this.priceScale(),s.targetPriceScale),{topPixelMargin:0,bottomPixelMargin:0});return{range:i,topPixelMargin:r.topPixelMargin,bottomPixelMargin:r.bottomPixelMargin}}formatter(e){return this._formatter??this._firstSourceOrSeries().formatter(!1)}defaultFormatter(){const e=this._firstSourceOrSeries();return this._defaultFormatter??e.defaultFormatter?.()??e.formatter()}plotFormatter(e){return this._plotFormatters.get(e)??this.formatter()}isMultiPaneAvailable(){return this._metaInfo.value().hasForceOverlayPlots()||(0,x.hasForceOverlayPrimitives)(this._metaInfo.value())}isMultiPaneEnabled(){return this._metaInfo.value().hasForceOverlayPlots()}updateAllViews(e){const t=this._model.paneForSource(this),s=this._model.mainPane(),i="viewport-change"===e.type&&e.pane&&e.pane!==s;"viewport-change"===e.type&&e.pane&&e.pane!==t||(this._paneViews.forEach((t=>t.update(e))),this._labelPaneViews.forEach((t=>t.update(e))),
|
||||
this._dataWindowView?.update(e),this._legendView?.update(e),this._statusView?.update(e),this._floatingTooltipView?.update(e),this._priceAxisViews.forEach((t=>t.update(e))),this._priceLinesAxisViews.forEach((t=>t.update(e))),this._inputsLinesPaneView?.update(e),this._inputsAnchorsPaneView?.update(e),this._inputsTimeAxisPaneViews.forEach((t=>t.update(e))),this._inputsPriceAxisPaneViews.forEach((t=>t.update(e)))),i||(this._forceOverlaysPaneViews.forEach((t=>t.update(e))),this._forceOverlayLabelPaneViews.forEach((t=>t.update(e))),this._forceOverlayPriceAxisViews.forEach((t=>t.update(e)))),"data-source-change"===e.type&&e.sourceId===this.id()&&e.clearData&&this._children.forEach((e=>e.updateAllViews({type:"data-source-change",sourceId:e.id(),clearData:!0})))}removeByRemoveAllStudies(){return!0}studyName(){return this._studyName}nearestIndex(e,t,s){return this.data().search(e,t,s)?.index}getMinFirstBarIndexForPlot(e){const t=this._properties.childs(),s=this._metaInfo,i=t.styles.childs()[e]?.child("showLast")?.value()??t.filledAreasStyle.childs()[e]?.child("showLast")?.value()??s.value().styles?.[e]?.showLast??t.ohlcPlots.childs()[e]?.child("showLast")?.value()??s.value().ohlcPlots?.[e]?.showLast??null;if(null===i)return-1/0;const r=this.data().lastIndex();return null===r?-1/0:r-i+1}guiPlotName(e,t){const s=this._metaInfo.value(),i=s.plots.find((e=>e.id===t));if(void 0!==i){return((0,L.isOhlcPlot)(i)?s.ohlcPlots?.[i.target]?.title:s.styles?.[t]?.title)??this.title(e)}return this.title(e)}childStudyByRebind(){return this._childStudyByRebind}isPine(){return void 0!==this._metaInfo.value().pine}isStandardPine(){return this.isPine()&&A.StudyMetaInfo.isStandardPine(this._metaInfo.value().id)}isLinkedToSeries(){return!0===this._metaInfo.value().linkedToSeries}preferredZOrder(){return!1===this._metaInfo.value().behind_chart?0:null}defaultPlotIdForAlert(){return this._metaInfo.value().plots?.[0]?.id??null}resolvedSymbolInfoBySymbol(e){return this._resolvedSymbols&&e&&this._resolvedSymbols[this._getSymbolForResolve(e)]||null}hasPendingUnresolvedSymbols(){return this._pendingResolveSymbols.size>0}hasSymbolInputs(){return this._metaInfo.value().inputs.some((e=>"symbol"===e.type))}currency(){if(null!==this._currencySourceSymbolInfo)return(0,Tt.symbolCurrency)(this._currencySourceSymbolInfo);const e=this.metaInfo();return Boolean(e)&&e.is_price_study?this._firstSourceOrSeries().currency():null}currencySourceSymbolInfo(){return this._currencySourceSymbolInfo??this.symbolSource()?.symbolInfo()??null}unit(){const e=this.metaInfo();return Boolean(e)&&e.is_price_study?this._firstSourceOrSeries().unit():null}canOverrideMinTick(){return!1}dataWindowView(){return this._dataWindowView}statusView(){return this._statusView}legendView(){return this._legendView}chartFloatingTooltipView(){return this._floatingTooltipView}pineSourceCodeModel(){return Promise.resolve(null)}alertSourceModel(){return this._alertSourceModel}inputsForAlertState(){return this.inputs()}sessionId(){return this._firstSourceOrSeries().sessionId()}sessionIdChanged(){
|
||||
return this._firstSourceOrSeries().sessionIdChanged()}getSymbolString(e){return""===e?"":(0,U.encodeExtendedSymbolOrGetSimpleSymbolString)(this._getSymbolObject(e))}onStatusChanged(){return this._statusChanged}onDataUpdated(){return this._dataUpdated}symbolsResolved(){return this._symbolsResolved}onHibernationStateChange(){return this._onHibernationStateChange}valuesProvider(){return this._valuesProvider}legendValuesProvider(){return new E(this,this.model())}tableViewValuesProvider(){return this._tableViewValuesProvider}statusProvider(e){return new $.StudyStatusProvider(this)}chartFloatingTooltipValuesProvider(){return new K(this,this.model())}correctScaleMargins(e){if("Volume"===this.metaInfo().shortId){const t=this.model().paneForSource(this);return null!==t&&t.isOverlay(this)&&t.containsMainSeries()?{top:.75,bottom:0}:{top:e.top,bottom:0}}return e}canBeHiddenByGlobalFlag(){return!0}isSourceHidden(){return!this.isVisible()||this.canBeHiddenByGlobalFlag()&&W.hideAllIndicators().value()}wasCompletedBefore(){return this._wasCompletedBefore}paneViews(e){const t=this._model.mainPane();if(this.isSourceHidden())return null;if(!e.hasPriceDataSource(this))return e!==t?null:this._forceOverlaysPaneViews;const s=[];return!this._startMovingPoint&&this._wasCompletedBefore&&s.push(...this._paneViews.filter((e=>!e.isForceOverlay?.()))),this._inputsLinesPaneView&&(this._startMovingPoint||this._model.selection().isSelected(this))&&s.push(this._inputsLinesPaneView),this._inputsAnchorsPaneView&&s.push(this._inputsAnchorsPaneView),e===t&&s.push(...this._forceOverlaysPaneViews),s}labelPaneViews(e){const t=this._model.mainPane();if(this.isSourceHidden()||!e.hasPriceDataSource(this))return this._metaInfo.value().hasForceOverlayPlots()?e!==t?null:this._forceOverlayLabelPaneViews:null;const s=[...this._labelPaneViews];return e===t&&s.push(...this._forceOverlayLabelPaneViews),s}timeAxisViews(){return this._model.selection().isSelected(this)?this._inputsTimeAxisPaneViews:null}priceAxisViews(e,t){if(t!==this.priceScale()&&t===this._model.mainSeries().priceScale()&&!e.hasDataSource(this))return this._forceOverlayPriceAxisViews;const s=this._properties.childs().oldShowLastValue;if(s&&!s.value())return null;let i=this._priceAxisViews.slice();return this._model.selection().isSelected(this)&&(i=i.concat(this._inputsPriceAxisPaneViews)),t===this._model.mainSeries().priceScale()&&(i=i.concat(this._forceOverlayPriceAxisViews)),e.findTargetPriceAxisViews(this,t,i,this._priceLinesAxisViews)}movable(){return null!==this._inputsAnchorsPaneView}startMoving(e,t,s,i){this._startMovingPoint=e}move(e,t,s,i){if(void 0!==e.logical&&null!==this._startMovingPoint){if(Array.isArray(t)){const s=t;this._updateInputValue(e.logical,s[0]),this._updateInputValue(e.logical,s[1])}else this._updateInputValue(e.logical,t);this.updateAllViews((0,N.sourceChangeEvent)(this.id()))}}endMoving(e,t){return this._startMovingPoint=null,{indexesChanged:!1,pricesChanged:!1}}clearData(){this._invalidateLastNonEmptyPlotRowCache(),
|
||||
this._ongoingDataUpdate=this._ongoingDataUpdate.then((()=>{this._clearData(),this._graphics instanceof R.LiveStudyGraphics&&this._graphics?.clear(),this._serverPlotOffsets.setValue({})})),this.hasBarColorer()&&this._model.mainSeries().invalidateBarStylesCache(),this.updateAllViews((0,N.sourceChangeEvent)({sourceId:this.id(),clearData:!0}))}convertYCoordinateToPriceForMoving(e,t){const s=this.priceScale();if(!t||!s||s.isEmpty())return null;const i=t.firstValue();return null===i?null:s.coordinateToPrice(e,i)}processHibernate(e){const t=this.isVisible();if(!this.isStarted()&&t&&(this._sources.value().forEach((e=>{e.processHibernate()})),this.start(void 0,void 0,e),this._onHibernationStateChange.fire(!1)),this.isHibernationAllowed()&&this.isStarted()&&!t){for(const e of this._children)e.processHibernate();this.stop(void 0,e),this._onHibernationStateChange.fire(!0)}}isHibernationAllowed(){return!this.metaInfo().historyCalculationMayChange&&(!this.hasChildren()||!!this._model.collapsed().value()&&this._children.every((e=>e.isHibernationAllowed())))}isPlotVisibleAt(e,t){let s;const i=this.metaInfo().plots.find((t=>t.id===e));if(s=void 0!==i?(0,L.isOhlcPlot)(i)?this._properties.childs().ohlcPlots.childs()[i.target]:this._properties.childs().styles.childs()[e]:this._properties.childs().ohlcPlots.childs()[e],void 0===s)throw new Error(`Study does not contain ${e} plot`);const r=s.childs().display.value();return null!==r&&(r&t)===t}recalculate(){const e=this._model.paneForSource(this);this._model.recalculatePane(e,(0,N.sourceChangeEvent)(this.id())),this._model.updateSource(this)}maxOffset(){return this._maxOffset}onStart(){return this._onStart}onParentSourcesChanges(){return this._onParentSourcesChanges}isHibernated(){return!this.isVisible()&&!this.isStarted()}graphicsViewsReady(){return this._graphicsViewsReady}setLoadingCompilationActive(e){0}setErrorCompilation(e){0}hasCompileError(){return null!==this._compileErrorStatus.value()}turnaround(e){if(!e)return this._turnaround;return function(e,t){let s=t.turnaround,i=[t];for(;i.length>0;){let e=[];const t=[];i.forEach((s=>{const i=J(s.sourceStudies).sort(q);if(i.length>0){e=e.concat(i);const s=i.map((e=>e.turnaround)).join("_");t.push(s)}})),t.length&&(s=t.join("_")+"_"+s),i=e}return e+"_"+s}(this._series.seriesSource().turnaround(),Z(this))}canHaveChildren(){return this._canHaveChildren=this._canHaveChildren??A.StudyMetaInfo.canHaveChildren(this._metaInfo.value()),this._canHaveChildren}setChild(e){-1===this._children.indexOf(e)&&this._children.push(e)}unsetChild(e){const t=this._children.indexOf(e);~t&&this._children.splice(t,1)}getAllChildren(){const e=this._children.slice();for(let t=0;t<e.length;++t){const s=e[t].getAllChildren();for(let t=0;t<s.length;++t)~e.indexOf(s[t])||e.push(s[t])}return e}parentSourceForInput(e){if(e.includes("$")){const t=e.split("$")[0];return this._sources.value().find((e=>e.id()===t))??null}return this._series}priceStep(){return this._priceStep||this._firstSourceOrSeries().priceStep(!1)}recreatePriceFormatter(){
|
||||
this._recreatePriceFormattingDependencies()}setOwnerSource(e){super.setOwnerSource(e),this._recreatePriceFormattingDependencies()}onTagsChanged(){return this._tagsChanged}getPropertyDefinitionsViewModel(){return null===this._definitionsViewModel?this._getPropertyDefinitionsViewModelClass().then((e=>null===e||this._isDestroyed?null:(null===this._definitionsViewModel&&(this._definitionsViewModel=new e(this._model.undoModel(),this)),this._definitionsViewModel))):Promise.resolve(this._definitionsViewModel)}calculationTime(){return this._calculationTime.readonly()}contextMenuStatName(){return"IndicatorContextMenu"}metaInfoWV(){return this._metaInfo.readonly()}async patchPropertiesAfterResetDefaults(){throw new Error("Not implemented")}_getPropertyDefinitionsViewModelClass(){return Promise.resolve(null)}_alertMetaInfo(){return this.metaInfo()}_createStudyOnServer(){if(this._isDestroyed)return!1;this._isStarted=!0,this._incrementTurnaround();const e=(0,p.ensureDefined)(this._inputs);let t;return t=this._chartApi.createStudy(this.sourceId(),this._turnaround,this.isChildStudy()?(0,p.ensureNotNull)(this._sources.value()[0].sourceId()):(0,p.ensureNotNull)(this._series.seriesSource().instanceId()),this._studyName.value(),e,this._handler,this._studySpec()),t?(performance.mark(`calculate_study_${this._id.value()}`),!0):(this._isStarted=!1,t)}_stopStudyOnServer(){this._chartApi&&this._chartApi.isConnected().value()&&this.isStarted()&&(this._chartApi.removeStudy(this.sourceId()),this._setStatus({type:xt.StudyStatusType.Undefined})),performance.clearMarks(`calculate_study_${this.sourceId()}`),this._isStarted=!1}_modifyStudyOnServer(e,t){this._chartApi.modifyStudy(this.sourceId(),this._turnaround,e,this._handler,t),performance.mark(`calculate_study_${this.sourceId()}`)}_sendNotifyCommand(e,t){this._chartApi.notifyStudy(this.sourceId(),e,t)}_transformData(e){}_plotsDataRange(){const e=this.plots().firstIndex(),t=this.plots().lastIndex();return null!==e&&null!==t?[e,t]:null}_invalidateLastNonEmptyPlotRowCache(){this._lastNonEmptyPlotRowCache={}}_collectDepsForAlert(){throw new Error("Not implemented")}_allInputsAreValid(){if(null===this._visibleTimeRangeInputs?.value())return!1;for(const e of this._metaInfo.value().inputs)if("bar_time"===e.type){const t=e.id;if(null==this._properties.childs().inputs.childs()[t].value())return!1}return!0}async _startAfterSymbolsResolved(e,t){await Promise.all(this._sources.value().map((e=>!e.isStarted()||e.isRestarting()?new Promise((t=>{e.onStart().subscribe(this,t,!0)})):Promise.resolve()))),this.isStarted()&&!this._restarting||(this._restarting=!1,this._allInputsAreValid()&&!this.metaInfo().isTVScriptStub&&(this._inputs=this._apiInputs(),this._createStudyOnServer()&&(this._subscribeToSessionId(),this._onStart.fire(),!0===e&&this._children&&await this._children.map((e=>e.start(!0,t))))))}async _changeInputsImpl(e,t){const i=this._calcSources(),r=this._metaInfo.value(),n=os(),o=()=>{for(const s of r.inputs){if("source"!==s.type)continue;const i=e[s.id].v,r=t[s.id].v;if(i!==r){(0,
|
||||
p.ensureDefined)(this._properties.childs().inputs.child(s.id)).setValue(r)}}};if(this.isStarted()&&this._chartApi.isConnected().value()&&n>0&&!this._chartApi.canCreateStudy(this._studySpec(!0),!0).success){const e=window.user.pro_plan,t="pro_premium_expert"===e||"pro_premium_expert_trial"===e;return createGoProDialog({feature:"studyOnStudy",hideLimitTable:t,actions:e&&t?[{text:m.t(null,void 0,s(15462)),action:PredefinedAction.Close}]:void 0}),void o()}this._inputs=e;let a=!1;const l=Object.values(Q.RangeDependentStudyInputNames);for(const s of Object.keys(e))if(JSON.stringify(e[s])!==JSON.stringify(t[s])&&!l.includes(s)){a=!0;break}this._incrementTurnaround(),a&&this.disablePriceRangeReady();try{await this._updateParentSources(i,n,!0),this._modifyStudyOnServer(e,n),this._studyModified=!0}catch(e){Gt.logError(`Error applying parent sources: ${e}`),o()}this.invalidateTitleCache()}_createPriceAxisView(e){return new Rt.StudyPriceAxisView(this,{plotIndex:e})}_createPriceLineAxisView(e){return new Ot.StudyPriceLineAxisView(this,e)}_createStudyPlotPaneView(e){return new lt.StudyPlotPaneView(this,this._series,this._model,e)}_createViews(){this._priceAxisViewsBase=[],this._forceOverlayPriceAxisViews=[],this._priceLinesAxisViews=[],this._paneViews=[],this._forceOverlaysPaneViews=[],this._labelPaneViews=[],this._forceOverlayLabelPaneViews=[];const e=new Set,t=this.metaInfo(),s=Boolean(t.usePlotsZOrder),i=new Map,r=this._properties.childs();if(r.filledAreasStyle&&t.filledAreas)for(let e=0;e<t.filledAreas.length;++e){const n=t.filledAreas[e],o=(0,p.ensureDefined)(r.filledAreasStyle.childs()[n.id]),a=ns(t,n.id);let l;if("plot_plot"===n.type||a?l=new mt(this,this.model(),n,o):"hline_hline"===n.type?l=new It(this,n,o):Gt.logWarn("Unsupported filledArea type: "+n.type),void 0!==l){let e=!1;if("plot_plot"===n.type&&(e=t.isPlotForceOverlay(n.objAId)),e)this._forceOverlaysPaneViews.push(l);else{const e=s?(0,p.ensureDefined)(n.zorder):i.size;rs(e,i),i.set(e,{paneViews:[l]})}}}{let r=-1e5;for(let n=0;n<t.plots.length;n++){const o=t.plots[n];let a,l,h,c,u,d=t.isPlotForceOverlay(o.id);if((0,L.isNonVisualPlot)(o))continue;let _=o.id,f=t.styles;const m=(0,L.isBgColorerPlot)(o);if(m)a=new oe(this,this._series,this._model,_);else if((0,L.isShapesPlot)(o))a=new ze(this,this._series,this._model,_);else if((0,L.isCharsPlot)(o))a=new Xe(this,this._series,this._model,_);else if((0,L.isArrowsPlot)(o))a=new tt(this,this._series,this._model,_);else if((0,L.isOhlcPlot)(o)){const s=o.target;if(e.has(s))continue;if(d=t.isPlotForceOverlay(s),e.add(s),ss(t,n))a=new rt(this,this._series,this._model,s);else{if(!is(t,n)){Gt.logError(`plot ${o.id} looks to be invalid`);continue}a=new ot(this,this._series,this._model,s)}c=this._createPriceAxisView(s),h=new at.PanePriceAxisView(c,this,this._model),_=s,f=t.ohlcPlots}else(0,L.isDataPlot)(o)||(c=this._createPriceAxisView(_),u=this._createPriceLineAxisView(_),a=this._createStudyPlotPaneView(_),this._properties.childs().styles.childs()[_]?.child("trackPrice")?.value()&&(l=new ut(this,_)),
|
||||
h=new Et(c,this,this._model,_));const y=s?m?r++:(0,p.ensureDefined)(f?.[_]?.zorder):i.size;if(rs(y,i),d)c&&this._forceOverlayPriceAxisViews.push(c),a&&this._forceOverlaysPaneViews.push(a),h&&this._forceOverlayLabelPaneViews.push(h);else{const e={paneViews:void 0!==a?[a]:[],labelView:h,priceAxisView:c,priceLineAxisView:u};void 0!==l&&e.paneViews.push(l),i.set(y,e)}}}(this._metaInfo.value().bands??[]).forEach(((e,t)=>{const n=r.bands.childs()[t];if(n&&n.childs().visible.value()){const t=new St(n,this),r=s?(0,p.ensureDefined)(e.zorder):i.size;rs(r,i),i.set(r,{paneViews:[t]})}})),r.bandsBackground&&((0,p.assert)(!s,"'usePlotsZOrder' flag does not supported"),i.set(i.size,{paneViews:[new wt(this)]}));const n=this._paneViews,o=this._forceOverlaysPaneViews;this._createGraphicsPaneViews().then((e=>{for(let t=0;t<e.regularPaneViews.length;t++)n.push(e.regularPaneViews[t]);for(let t=0;t<e.forceOverlayPaneViews.length;t++)o.push(e.forceOverlayPaneViews[t]);this._model.lightUpdate(),this._graphicsViewsReady=!0})),r.areaBackground&&((0,p.assert)(!s,"'usePlotsZOrder' flag does not supported"),i.set(i.size,{paneViews:[new dt.AreaBackgroundPaneView(this,this.model())]}));const a=Array.from(i.keys()).sort(((e,t)=>e-t));for(let e=0;e<a.length;e++){const t=(0,p.ensureDefined)(i.get(a[e]));this._paneViews.push(...t.paneViews),t.labelView&&this._labelPaneViews.push(t.labelView),t.priceAxisView&&this._priceAxisViewsBase.push(t.priceAxisView),t.priceLineAxisView&&this._priceLinesAxisViews.push(t.priceLineAxisView)}this._dataWindowView||(this._dataWindowView=new yt.StudyDataWindowView(this,this._model)),this._legendView||(this._legendView=new H(this,this._model)),this._statusView||(this._statusView=new z.StudyStatusView(this)),this._floatingTooltipView||(this._floatingTooltipView=new gt.StudyChartFloatingTooltipView(this,this._model)),this._concatPriceAxisViews()}_onData(e){switch(e.method){case"study_loading":this._onStudyLoading(e.time);break;case"study_error":this._onStudyError(e.params[2]);break;case"study_completed":if(!this._checkTurnaround(e.params[1]))return;this._onStudyCompleted(e.time);break;case"data_update":if(e.params.customId!==this.sourceId()||!this._checkTurnaround(e.params.turnaround))return;(0,p.assert)(!!e.params.nonseries,"data.params.nonseries is missing"),this._onDataUpdate(e.params.plots,(0,p.ensureDefined)(e.params.nonseries),e.params.lastBar);break;case"clear_data":this._checkTurnaround(e.params.turnaround)&&this.clearData()}}_getTelemetryObjectName(){return"study"}_onDataUpdated(e,t,s,i){if(this.hasBarColorer()&&e.length>0){const t=(0,p.ensureNotNull)(this.barColorer()).firstColoredBar(e[0].index);null!==t&&this._model.mainSeries().invalidateBarStylesCache(t)}null!==t&&this._postProcessGraphics();const r=this._model.paneForSource(this);if(this._model.recalculatePane(r,(0,N.sourceChangeEvent)({sourceId:this.id(),firstUpdatedTimePointIndex:i??void 0,nonSeriesOnly:0===e.length})),this._updateSources(),e.length){const t=e[e.length-1].index,s=e[0].index;this._dataRangeUpdated.fire({type:"partial",startIndex:s,
|
||||
endIndex:t})}else this.data().isEmpty()&&this._dataRangeUpdated.fire({type:"full"})}_titleInputs(e,t,s){return this.inputs(this._titleInputsOptions(e,t,s))}_titleInputsOptions(e,t,s){return{symbolsForDisplay:!0,skipHiddenInputs:!0,skipFakeInputs:!1,fakeInputsForDisplay:!0,asObject:!0,skippedGroups:[],skippedInputs:this._skippedTitleInputs(),noExchanges:t,noResolution:s,priceInputsForDisplay:!0,skipOptionalEmptySymbolInputs:Qt,displayMask:e}}_postProcessGraphics(){this._graphicsPriceAxisViews=this._createGraphicsPriceAxisViews(),this._concatPriceAxisViews()}async _createGraphicsPaneViews(){return(0,R.createGraphicsPaneViews)(this,this.model())}_createGraphicsPriceAxisViews(){return(0,R.createGraphicsPriceAxisViews)(this)}_subscribeToSessionId(){!this._isSubscribedToSessionId&&this.hasSymbolInputs()&&(this.sessionIdChanged().subscribe(this,this._onSessionIdChanged),this._isSubscribedToSessionId=!0)}_recreateFormatter(e){let t=e;if(t){const e=this._model.symbolAliasService()?.getAliasByProName(t.pro_name);e&&(t=(0,r.default)(t),(0,n.default)(t,e.formattingOptions??{}))}this._recreatePlotsFormatters(t),this._formatter=this._tryCreateFormatter(t),this._defaultFormatter=this._tryCreateDefaultFormatter(t),this._formatterChanged.fire();const s=this.priceScale();null!==s&&s.updateFormatter(),this.getAllChildren().forEach((e=>{e.recreatePriceFormatter()})),this._model.fullUpdate()}_recreatePriceFormattingDependencies(e){this._recreateFormatter(e),this._recreatePriceStep()}_title(e,t,s,i,r,n){const o=this._titleInParts(e,t,s,i,r,n);return this._joinTitlesParts(o)}_postProcessPriceRange(e,t){if(e&&e.minValue()===e.maxValue()&&!this.metaInfo().is_price_study){const t=.005*e.minValue();e=new M.PriceRange(e.minValue()-t,e.maxValue()+t)}const s=t.targetPriceScale;return s&&s.isLog()&&e?new M.PriceRange(s.priceToLogical(e.minValue()),s.priceToLogical(e.maxValue())):e}_titleInParts(e,t=!0,i,r,n,o){const a=[m.t(this.name(t),{context:"study"},s(83477))];let l=[];if(!r||ee.enabled("always_show_study_symbol_input_values_in_legend")){const s=this._getMTFResolutionInputTitle();null!==s&&s.length>0&&a.push(s);l=(this.inputsInParts(e,t,i,n,o)??[]).map((e=>e.value))}return[a.join(" · "),l]}_seriesDataRangeToSave(e){return this._model.timeScale().visibleExtendedDataRange(e,0)}_getSymbolForResolve(e){return this.getSymbolString(this._getSymbolForApi(e))}_getSymbolForApi(e){return e}_getSymbolObject(e){const t={symbol:e},s=this.currency();return null!==this._currencySourceSymbolInputProperty&&null!==this._currencySourceSymbolInfo&&this._getSymbolForApi(this._currencySourceSymbolInputProperty.value())===e&&(t["currency-id"]=s),t.session=this.sessionId(),t}_onSymbolResolved(e,t,s){this._onCurrencyMayChange()}_onSymbolResolvingStart(e,t){}_onSymbolError(){}_setStatus(e,t){const s=this.isFailed();this._status.setValue(e),e.type===xt.StudyStatusType.Completed?this._wasCompletedBefore=!0:e.type!==xt.StudyStatusType.Error&&e.type!==xt.StudyStatusType.Undefined||(this._wasCompletedBefore=!1),t||(this._statusView?.update((0,
|
||||
N.sourceChangeEvent)(this.id())),this._model.updateSource(this),this._statusChanged.fire(this.status())),s!==this.isFailed()&&this._updateAlertCreationAvailable()}_onPropertiesChanged(){this._restarting||(this._inputs?this._tryChangeInputs():this._chartApi&&this._chartApi.isConnected().value()&&this.restart());this._metaInfo.value();this._recreatePaneViews(),(0,Nt.emit)("study_properties_changed",this._id.value())}_lastNonEmptyPlotRow(e){if(!(0,_.isInteger)(e))return Gt.logDebug("_lastNonEmptyPlotRow: incorrect plotIndex"),null;let t=this._lastNonEmptyPlotRowCache[e]??null;if(null!==t)return t;return t=this.data().findLast(((t,s)=>void 0!==s[e]),1e3),null===t?null:(this._lastNonEmptyPlotRowCache[e]=t,t)}_onCurrencyChanged(){"alwaysOff"!==(0,At.currencyUnitVisibilityProperty)().value()&&this._model.fullUpdate(),this.isStarted()&&this._tryChangeInputs(),this._currencyChanged.fire()}_apiInputs(){return this.inputs({keepOptionalSymbolsEmpty:!0})}async _tryChangeInputs(){const e=this.isStarted()&&this._chartApi.isConnected().value(),t=this._allInputsAreValid(),s=((0,p.ensureDefined)((0,_.clone)(this._inputs)),this._apiInputs()),i=JSON.stringify(s),r=i!==JSON.stringify(this._inputs);if(e&&t)try{if(await this._allSymbolsAreResolved(),i!==JSON.stringify(this._apiInputs()))return this._tryChangeInputs();if(this._isStopped())return void(r&&this.disablePriceRangeReady());r&&await this._changeInputsImpl(s,(0,p.ensureDefined)((0,_.clone)(this._inputs)))}catch(e){Gt.logError(`ERROR: ${this._debugId()} _tryChangeInputs: cannot modify study, ${e}`)}else if(e&&!t&&this.stop(!0),!e&&t&&this.start(!0),r){const e=this._calcSources(),t=os(this._metaInfo.value());this._updateParentSources(e,t,!0),this._inputs=s}this._tagsChanged.fire()}_onCurrencyMayChange(){if(null!==this._currencySourceSymbolInputProperty){const e=this.currency();this._updateCurrencySourceSymbolInfo(),e!==this.currency()&&this._onCurrencyChanged()}}_fillPrecalculatedAutoscaleInfo(e,t,s){const i=this._metaInfo.value(),r=this.properties().childs(),n=new Set,o=i.filledAreas||[];for(let e=0;e<o.length;e++){const t=o[e];r.filledAreasStyle.childs()[t.id].childs().visible.value()&&(n.add(t.objAId),n.add(t.objBId))}return i.plots.filter((e=>!(0,L.isPlotWithTechnicalValues)(e))).filter((e=>i.isPlotForceOverlay(e.id)?s.targetPriceScale===this._model.mainSeries().priceScale():s.targetPriceScale===this.priceScale()&&!s.forceOverlayOnly)).filter((e=>n.has(e.id)||this.isPlotVisibleAt(e.id,1))).reduce(((s,i)=>this._applyPlotToPrecalculatedAutoscaleInfo(e,t,s,i)),{fields:[],useMainSeriesRange:!1,baseValueMinMax:null})}_firstSourceOrSeries(){return this._sources.value()[0]??this._series}_skipHistogramBaseOnAutoScale(){return!1}_tryCreateFormatter(e){const t=void 0===e?this.symbolSource().symbolInfo():e;return hs(this._metaInfo.value().format,this._priceScaleByProperties(),t,this.properties().childs().precision.value())}_tryCreateDefaultFormatter(e){return this._tryCreateFormatter(e)}_mergeData(e){return this._invalidateLastNonEmptyPlotRowCache(),this.data().merge(e)}
|
||||
_skippedTitleInputs(){return this._hideMatches.filter((e=>e.plotIds.every((e=>0===this._getPlotDisplayValue(e))))).map((e=>e.id))}_getPlotDisplayValue(e){return this.properties()?.childs()?.styles?.childs()?.[e]?.childs()?.display?.value()}_onStudyError(e){performance.clearMarks(`calculate_study_${this.sourceId()}`),this._handleStudyError(this._createStudyError(e)),this._enablePriceRangeReady()}_onStudyCompleted(e){if(performance.getEntriesByName(`calculate_study_${this.sourceId()}`).length){try{const e=performance.measure(`measure_study_${this.sourceId()}`,`calculate_study_${this.sourceId()}`);this._calculationTime.setValue(e.duration)}catch(e){Gt.logError("Error during measuring study calculation time")}performance.clearMarks(`calculate_study_${this.sourceId()}`),performance.clearMeasures(`measure_study_${this.sourceId()}`)}this._studyModified&&(this.clearData(),this._studyModified=!1),this._setStatus({type:xt.StudyStatusType.Completed}),this._statusView?.update((0,N.sourceChangeEvent)(this.id()));const t=this._model.paneForSource(this);this._model.recalculatePane(t,(0,N.sourceChangeEvent)(this.id())),this._updateSources();const s=Vt.InvalidationMask.full();null!==this._model.appliedTimeFrame().value()&&s.lockVisibleTimeRangeOnResize(),this._model.invalidate(s)}_clearData(){this._data.clear(),this._dataRangeUpdated.fire({type:"full"})}_moveData(e){this.data().move(e)}_defaultErrorTitle(){return"Runtime error"}_incrementTurnaround(){this._turnaround="st"+ ++this._turnaroundCounter}_checkTurnaround(e){return e===this._turnaround||e===this._model.mainSeries().seriesSource().turnaround()||e===this.turnaround(!0)}_updateMaxOffsetValue(){let e=-1/0;for(const t of this._metaInfo.value().plots)e=Math.max(this.offset(t.id),e);this._maxOffset.setValue(e)}_rightOffsetToUnixTime(e){if(this._series.bars().size()>=e){const t=(0,p.ensureNotNull)(this._series.bars().lastIndex())-e;return(0,p.ensureNotNull)(this._series.bars().valueAt(t))[0]}return null}_concatPriceAxisViews(){this._priceAxisViews=[...this._priceAxisViewsBase,...this._graphicsPriceAxisViews]}_onStudyLoading(e){this._setStatus({type:xt.StudyStatusType.Loading,startTime:Date.now()}),this._statusView?.update((0,N.sourceChangeEvent)(this.id())),this._model.updateSource(this)}_handleStudyError(e){this.clearData(),this._setStatus(e),this._statusView?.update((0,N.sourceChangeEvent)(this.id())),this._model.updateSource(this)}_createStudyError(e){let t;return t=(0,_.isString)(e)?{error:this._getStudyErrorText(e),title:e.includes("study_not_auth")?"Access error":this._defaultErrorTitle()}:{...e,title:e.title??this._defaultErrorTitle()},(0,xt.createStudyError)(t,this.symbolSource().symbolInfo()?.exchange)}_updateSources(){this._model.updateSource(this),this.hasBarColorer()&&this._model.updateSource(this._model.mainSeries())}_unsubscribeToSessionId(){this._isSubscribedToSessionId&&(this.sessionIdChanged().unsubscribe(this,this._onSessionIdChanged),this._isSubscribedToSessionId=!1)}_onSessionIdChanged(){this.restart(!0)}_recreatePriceStep(){let e=null
|
||||
;const t=this._priceScaleByProperties()??this._priceScaleByMetaInfo();null!==t&&(e=1/t),this._priceStep!==e&&(this._priceStep=e,this._priceStepChanged.fire())}_recreatePlotsFormatters(e){this._plotFormatters.clear();const t=this._metaInfo.value(),s=t.format,i=this._priceScaleByProperties(),r=void 0===e?this.symbolSource().symbolInfo():e;for(const[e,n]of Object.entries(t.ohlcPlots??{}))if(n?.format){const t=hs(ls({...s,...n?.format}),i,r,this.properties().childs().precision.value());t&&this._plotFormatters.set(e,t)}for(const[e,n]of Object.entries(t.styles??{}))if(n?.format){const t=hs(ls({...s,...n?.format}),i,r,this.properties().childs().precision.value());t&&this._plotFormatters.set(e,t)}for(const e of t.plots)if((0,L.isOhlcPlot)(e)){const t=this._plotFormatters.get(e.target);t&&this._plotFormatters.set(e.id,t)}}_joinTitlesParts(e){const t=e[1]?e[1].join(", "):"";return e[0]+(t.length>0?" ("+t+")":"")}_getMTFResolutionInputTitle(){const e=this.metaInfo();for(let t=0;t<e.inputs.length;t++){const s=e.inputs[t];if("resolution"===s.type&&s.isMTFResolution)return(0,p.ensureDefined)(this._properties.childs().inputs.child(s.id)).value()}return null}_onDataUpdate(e,t,s){this._studyModified&&(this.clearData(),this._studyModified=!1);const i=(0,C.unpackNonSeriesData)(t.d);return this._ongoingDataUpdate=this._ongoingDataUpdate.then((()=>i),(()=>i)).then(this._onDataUnpacked.bind(this,e,t.indexes,s)),this._ongoingDataUpdate}_allSymbolsAreResolved(){const e=this._inputSymbols(),t=[];let s=!1;for(const i of e){const e=this._getSymbolForResolve(i);if(""!==e)if(this._resolvedSymbols[e])s=!0;else{const s=this._resolveSymbol(e,i);t.push(s)}}if(0===t.length){const e=Promise.resolve();return s?e.then((()=>this._symbolsResolved.fire())):e}return Promise.all(t).catch((e=>(this._inputSymbols().includes(e)&&this.stop(!0),this._setStatus({type:xt.StudyStatusType.Error,errorDescription:{error:$t}}),this._model.updateSource(this),Promise.reject("Invalid symbol, "+e)))).then((()=>{this._symbolsResolved.fire(),this._recheckLineToolsActuality()}))}_resolveSymbol(e,t){if(""===e)return Promise.resolve();let s=this._pendingResolveSymbols.get(e);return void 0!==s||(s=new Promise(((s,i)=>{this._onSymbolResolvingStart(e,t),this._chartApi.resolveSymbol((0,j.makeNextSymbolId)(),e,(r=>{switch(this._pendingResolveSymbols.delete(e),r.method){case"symbol_resolved":{this._setStatus({type:xt.StudyStatusType.Undefined});const i=r.params[1];this._resolvedSymbols[e]=i,this._resolvedSymbolsByInput[t]=i,this.invalidateTitleCache(!0),this._onSymbolResolved(e,t,i),s();break}case"symbol_error":if(this._setStatus({type:xt.StudyStatusType.Error,errorDescription:{error:r.params[1]}}),this._onSymbolError(),r.params[1]===G.permissionDenied&&r.params[2]){if(r.params[2]!==G.SymbolErrorPermissionDeniedReason.Symbol)return void this._resolveSymbol(r.params[2],t).then(s);if(r.params[3])return void this._resolveSymbol(r.params[3],t).then(s)}0,i(t)}}))})),this._pendingResolveSymbols.set(e,s)),s}_recheckLineToolsActuality(){const e=this._model.paneForSource(this)
|
||||
;null!==e&&e.sourcesByGroup().lineSourcesForAllSymbols().forEach((e=>{e.ownerSource()===this&&e.calcIsActualSymbol()}))}_sendTelemetryCounter(e,t){void 0===t&&(t=this._getTelemetryAdditionalData());const s={count:1,additional:t};telemetry.sendChartReport(e,s)}_getTelemetryAdditionalData(){let e="";const t=this._metaInfo.value();return t.pine&&t.pine.version&&t.shortId.indexOf("USER")>=0&&(e="_v"+t.pine.version),{symbol:this.series().actualSymbol(),resolution:this.series().interval(),study:t.shortId+e}}_onSourceFormatterChanged(){null===this._formatter&&(null!==this._priceScale&&this._priceScale.updateFormatter(),this._formatterChanged.fire())}_onSourcePriceStepChanged(){null===this._priceStep&&this._priceStepChanged.fire()}_bandsFirstValue(e){const t=this._metaInfo.value();if(!t.bands)return null;for(let s=0;s<t.bands.length;s++){const t=(0,p.ensureDefined)(this._properties.childs().bands).childs()[s];if(t.childs().visible.value()){const s=t.childs().value.value();if(e&&0===s)continue;if(null!==s)return s}}return null}_prepareInputs(e){(0,p.assert)(!!e,"options not set");const t=this.metaInfo(),s={},i=e.allowedInputTypes?new Set(e.allowedInputTypes):null,r=!(!e.asObject||!e.useNameAndGroupAsKey);for(let n=0;n<t.inputs.length;n++){const o=t.inputs[n];if(null!==i&&!i.has(o.type))continue;if(o.isFake&&e.skipFakeInputs)continue;if(o.isMTFResolution&&e.noResolution)continue;if(void 0!==e.displayMask&&!((0,p.ensureDefined)(o.display)&e.displayMask))continue;if(e.skipHiddenInputs&&(!e.doNotSkipHiddenWithMigrate||!o.migrate)){let t=!1;switch(o.type){case"bool":t=e.skipBooleanInputs;break;case"color":t=e.skipColorInputs;break;case"time":t=e.skipTimeInputs;break;case"text_area":t=e.skipTextareaInputs;break;default:t=Boolean(o.isHidden)}if(t)continue}if(void 0!==o.groupId&&-1!==e.skippedGroups.indexOf(o.groupId))continue;if(-1!==e.skippedInputs.indexOf(o.id))continue;const a=this._prepareInput(o,e);if("symbol"===o.type&&e.skipOptionalEmptySymbolInputs&&""===a)continue;let l;r&&(l=v(o),void 0!==l&&l in s&&(l=void 0)),s[l||o.id]=(0,_.clone)(a)}return s}_prepareInputValue(e,t){const s=e.id,i=this._properties.childs();if(t.valuesAsIsFromProperties)return i.inputs.childs()[s].value();const r=this._metaInfo.value();if("symbol"===e.type){const r=t&&t.symbolsForDisplay,n=i.inputs.childs()[s].value();let o=r?n:this._getSymbolForApi(n),a=this._resolvedSymbols?.[this._getSymbolForResolve(o)]??null;if(""===o&&e.optional){if(t&&t.keepOptionalSymbolsEmpty)return o;o=this._model.mainSeries().symbol(),a=this._model.mainSeries().symbolInfo()}if(r)if(a)if(Zt){switch(this._model.mainSeries().symbolTextSourceProxyProperty().value()){case"description":o=a.description;break;case"ticker-and-description":o=`${a.name}, ${a.description}`;break;case"ticker":o=a.name}}else o=(0,Tt.symbolTitle)(a,t.noExchanges);else ts&&(o="");else a&&(o=a.ticker||a.full_name),!this.isPine()&&t&&t.symbolsForChartApi&&(o=this.getSymbolString(o));return o}if("bar_time"===e.type){let e=i.inputs.childs()[s].value();if(e<0){const t=this._rightOffsetToUnixTime(-e);e=t&&t>=0?t:e}
|
||||
return e}if(r.isTVScript||r.pine){if("text"===s)return r.defaults.inputs?.text??"";if("pineId"===s)return r.scriptIdPart;if("pineVersion"===s)return r.pine?r.pine.version:"-1";if("color"===e.type&&r.isRGB){const e=i.inputs.childs()[s].value();return(0,I.colorToInteger)(e)}if("price"===e.type){const e=i.inputs.childs()[s].value();return t.priceInputsForDisplay?this.formatter().format(e):e}}return i.inputs.childs()[s].value()}_getStudyIdWithLatestVersion(){return A.StudyMetaInfo.getStudyIdWithLatestVersion(this.metaInfo())}_debugId(){const e=[];e.push(this._id.value());const t=this._metaInfo.value();return e.push(t.fullId),e.push(t.description),JSON.stringify({study:e})}_hasAvailableAlertPlots(){return!1}_hasAlertConditions(){return!1}_hasAlertFunction(){return!1}async _updateParentSources(e,t,s){if(this._sources.value().forEach((e=>e.unsetChild(this))),s&&await Promise.all(e.map((e=>e.isStarted()?Promise.resolve():e.start(!1,!0)))),e.forEach((e=>e.setChild(this))),this._setSources(e),this._recreatePriceFormattingDependencies(),0!==t&&this._sources.value().length<=1){const e=this._firstSourceOrSeries(),t=this._priceScale,s=(0,p.ensureNotNull)(e.priceScale());if(t!==s){const t=this._model.paneForSource(this),i=(0,p.ensureNotNull)(this._model.paneForSource(e));t===i&&i.move(this,s,!0)}}}_calcSources(){const e=this._properties.childs().inputs.state();return A.StudyMetaInfo.getSourceIdsByInputs(this._metaInfo.value().inputs,e).map((e=>{if("high"===e||"open"===e||"low"===e||"close"===e||"hl2"===e||"ohl3"===e||"ohlc4"===e)return null;return this._model.allStudies().find((t=>t.canHaveChildren()&&t.id()===e))??null})).filter(_.notNull)}_isStopped(){return!this.isStarted()}_onDataUnpacked(e,t,s,i){if(this._isDestroyed)return;"nochange"!==t&&this._processPlotOffsets(i),this._transformData(e);const r=this._mergeData(e);null!==i&&(i.indexes_replace?((0,p.assert)("nochange"!==t),this._graphics.replaceIndexesTo(t)):("nochange"!==t&&this._graphics.replaceIndexesTo(t),void 0!==i.graphicsCmds&&this._graphics.processCommands(i.graphicsCmds))),this._onDataUpdated(e,i,t,r&&r.index),this.priceRangeReady()||this._enablePriceRangeReady()}_processPlotOffsets(e){if(e&&e.indexes_replace)return;const t=this._serverPlotOffsets.value();this._serverPlotOffsets.setValue(e&&e.offsets||{}),(0,i.default)(t,this._serverPlotOffsets.value())||this.updateAllViews((0,N.sourceChangeEvent)({sourceId:this.id(),clearData:!0})),this._updateMaxOffsetValue()}_applyPlotToPrecalculatedAutoscaleInfo(e,t,s,i){const r=i.id,n=this._properties.childs().styles.childs()[r],o=(0,L.isShapesPlot)(i)||(0,L.isCharsPlot)(i);s.useMainSeriesRange=s.useMainSeriesRange||(0,L.isArrowsPlot)(i);let a=(0,L.isLinePlot)(i)||(0,L.isOhlcPlot)(i);if(o){const e=(0,p.ensureDefined)(n).childs().location.value(),t=[D.MarkLocation.Absolute,D.MarkLocation.Top,D.MarkLocation.Bottom].indexOf(e)<0;s.useMainSeriesRange=s.useMainSeriesRange||o&&t,a=a||e===D.MarkLocation.Absolute}if(!a)return s;const l={name:r,offset:this.offset(r)},h=n.childs().plottype.value()
|
||||
;if(!this._skipHistogramBaseOnAutoScale()&&[L.LineStudyPlotStyle.Histogram,L.LineStudyPlotStyle.Columns,L.LineStudyPlotStyle.Area].indexOf(h)>=0){const i=(this._metaInfo.value().styles??{})?.[r]?.histogramBase;if(void 0===i)return s;const n=this.data().minMaxOnRangeCached(e,t,[l]);return(0,_.isNumber)(i)&&null!==n&&(s.baseValueMinMax=(0,T.mergeMinMax)(s.baseValueMinMax,{min:i,max:i}),s.baseValueMinMax=(0,T.mergeMinMax)(s.baseValueMinMax,n)),s}return s.fields.push(l),s}async _onSourceInputChanged(){if(!this.isStarted()){this._calcSources();Kt}}_buildInputs(e){(0,p.assert)(!!e,"options not set");let t={};try{t=this._prepareInputs(e)}catch(e){Gt.logWarn("Failed to prepare study inputs: "+e)}if(e.asObject){const e={};return Object.keys(t).forEach((s=>{null!=t[s]&&(e[s]=t[s])})),e}{const e=[];return Object.keys(t).forEach((s=>{null!=t[s]&&e.push(t[s])})),e}}_prepareInput(e,t){const s=this._prepareInputValue(e,t);return!e.isFake||t.fakeInputsForDisplay||t.onlyAtomValues?s:{v:s,f:!0,t:e.type}}_plotsForAlert(){return[]}_formatterStateForAlert(){try{const e=this.formatter();return FormattersSerializer.isSerializable(e)?FormattersSerializer.serialize(e):null}catch{return null}}_calcIsActualInterval(){const e=this._isActualInterval;this._isActualInterval=(0,Ct.isActualInterval)(this._series.intervalObj().value(),this._properties.childs().intervalsVisibilities),e!==this._isActualInterval&&(this._onIsActualIntervalChange.fire(),this._visibleChanged(),this.processHibernate())}_visibleChanged(){this._series.invalidateBarColorerCache()}_getNonPriceParent(){const e=this._sources.value();for(const t of e)if(t instanceof us){const e=t.metaInfo();return e.is_price_study&&"Compare@tv-basicstudies"!==e.id?t._getNonPriceParent():t}return null}_updateInputValue(e,t){const s=this._properties.childs().inputs.childs();if(s[t.id])if("price"===t.type)s[t.id].setValue(e.price);else if("time"===t.type){const i=this._model.timeScale().indexToTimePoint(e.index);null!==i&&s[t.id].setValue(1e3*i)}}_initializeStudyInputsPaneViews(){}_updateCurrencySourceSymbolInfo(){null!==this._currencySourceSymbolInputProperty&&(this._currencySourceSymbolInfo=this._resolvedSymbolsByInput[this._currencySourceSymbolInputProperty.value()]??null)}_initializeCurrencySource(){const e=this.metaInfo(),t="symbolInputSymbolSource"===e.symbolSource?.type&&e.symbolSource?.inputId,s=e.inputs.find((e=>e.id===t));if("string"==typeof t&&"symbol"===s?.type&&e.is_price_study){const e=this._properties.childs().inputs.childs()[t];void 0!==e&&(e.subscribe(this,this._onCurrencyMayChange),this._currencySourceSymbolInputProperty=e)}}_recreatePaneViews(){this.hasBarColorer()&&this._model.mainSeries().invalidateBarStylesCache(),this._createViews(),this.recalculate(),this.updateAllViews((0,N.sourceChangeEvent)(this.id()))}async _pinePatchProps(){throw new Error("Not implemented")}_areStudyInputsModified(e){if(0===Object.keys(e).length)return!1;if(void 0===this._oldStudyInputs)return!0;const t=Object.keys(this._oldStudyInputs);(0,
|
||||
p.assert)(t.length===Object.keys(e).length,"keys quantity should be equal");for(const s of t)if((0,p.assert)(e.hasOwnProperty(s),`key '${s}' should exist in study inputs`),(0,p.ensureDefined)(this._oldStudyInputs)[s]!==e[s])return!0;return!1}_onVisibleTimeRangeInputsChanged(e){null!==e?this._updateVisibleTimeRangeInputs(e):this.isStarted()&&this._chartApi.isConnected().value()&&this.stop(!0)}_updateVisibleTimeRangeInputs(e,t=!0){const s={first_visible_bar_time:e.firstVisibleBarTime,last_visible_bar_time:e.lastVisibleBarTime,subscribeRealtime:e.subscribeRealtime},i=this.metaInfo().inputs,r=[];for(const e of i)s.hasOwnProperty(e.id)&&r.push(e.id);const n=this.properties().childs().inputs;for(const e of r)n.childs()[e].setValueSilently(s[e]);t&&r.length>0&&n.fireChanged()}_getStudyErrorText(e){const t=e.split(":",2)[0];return decodeURIComponent(t)}_priceScaleByProperties(){if("default"===this.properties().childs().precision.value())return null;const e=parseInt(this.properties().childs().precision.value());return isFinite(e)?Math.pow(10,e):null}_priceScaleByMetaInfo(){const e=this.metaInfo().format,t="inherit"!==e.type?e.precision:void 0,s=(0,_.isNumber)(t)?Math.pow(10,t):void 0;if("price"===e.type||"percent"===e.type)return s||100;if("volume"===e.type){if(void 0===e.precision){const e=this.series().symbolInfo();if(null!==e&&(0,_.isNumber)(e.volume_precision))return Math.pow(10,e.volume_precision)}return 1}return"inherit"===e.type||Gt.logWarn("Unsupported format type: "+e.type),null}_inputSymbols(){return this.metaInfo().inputs.filter((e=>"symbol"===e.type)).map((e=>(0,p.ensureDefined)(this._properties.childs().inputs.child(e.id)).value()))}_studySpec(e){return{id:this._metaInfo.value().id,child:e??this.isChildStudy(),fundamental:!1}}_onFormatterPropsChanged(){this._recreatePriceFormattingDependencies()}_setSources(e){this.invalidateTitleCache(),this._sources.setValue(e),this._onParentSourcesChanges.fire()}async _awaitForMetaInfo(){const e={resolver:()=>{}},t=()=>e.resolver();try{await Promise.race([new Promise(((e,t)=>{setTimeout((()=>t(new Error("Timeout"))),3e3)})),await new Promise((s=>{e.resolver=s,this.metaInfoWV().subscribe(t)}))])}catch(e){throw e}finally{this.metaInfoWV().unsubscribe(t)}}}},51752:(e,t,s)=>{s.d(t,{plotShapesData:()=>r});var i=s(11542);const r={shape_arrow_down:{guiName:i.t(null,void 0,s(34247)),id:"shape_arrow_down",paneRendererClass:"PaneRendererArrowDown",pineName:"shape.arrowdown",icon:"arrow_down"},shape_arrow_up:{guiName:i.t(null,void 0,s(45523)),id:"shape_arrow_up",paneRendererClass:"PaneRendererArrowUp",pineName:"shape.arrowup",icon:"arrow_up"},shape_circle:{guiName:i.t(null,void 0,s(91944)),id:"shape_circle",paneRendererClass:"PaneRendererCircleShape",pineName:"shape.circle",icon:"circle"},shape_cross:{guiName:i.t(null,void 0,s(6969)),id:"shape_cross",paneRendererClass:"PaneRendererCrossShape",pineName:"shape.cross",icon:"cross"},shape_diamond:{guiName:i.t(null,void 0,s(15179)),id:"shape_diamond",paneRendererClass:"PaneRendererDiamond",pineName:"shape.diamond",icon:"diamond"},shape_flag:{
|
||||
guiName:i.t(null,void 0,s(33885)),id:"shape_flag",paneRendererClass:"PaneRendererFlagShape",pineName:"shape.flag",icon:"flag"},shape_label_down:{guiName:i.t(null,void 0,s(85924)),id:"shape_label_down",paneRendererClass:"PaneRendererLabelDown",pineName:"shape.labeldown",icon:"label_down"},shape_label_up:{guiName:i.t(null,void 0,s(49857)),id:"shape_label_up",paneRendererClass:"PaneRendererLabelUp",pineName:"shape.labelup",icon:"label_up"},shape_square:{guiName:i.t(null,void 0,s(66205)),id:"shape_square",paneRendererClass:"PaneRendererSquare",pineName:"shape.square",icon:"square"},shape_triangle_down:{guiName:i.t(null,void 0,s(76152)),id:"shape_triangle_down",paneRendererClass:"PaneRendererTriangleApexDown",pineName:"shape.triangledown",icon:"triangle_down"},shape_triangle_up:{guiName:i.t(null,void 0,s(21236)),id:"shape_triangle_up",paneRendererClass:"PaneRendererTriangleApexUp",pineName:"shape.triangleup",icon:"triangle_up"},shape_xcross:{guiName:i.t(null,void 0,s(11316)),id:"shape_xcross",paneRendererClass:"PaneRendererXCross",pineName:"shape.xcross",icon:"x_cross"}}}}]);
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -0,0 +1,7 @@
|
||||
(self.webpackChunktradingview=self.webpackChunktradingview||[]).push([[1553],{11553:(t,e,i)=>{var n;!function(r,s,o,a){"use strict";var h,u=["","webkit","Moz","MS","ms","o"],c=s.createElement("div"),l=Math.round,p=Math.abs,f=Date.now;function v(t,e,i){return setTimeout(I(t,i),e)}function d(t,e,i){return!!Array.isArray(t)&&(m(t,i[e],i),!0)}function m(t,e,i){var n;if(t)if(t.forEach)t.forEach(e,i);else if(t.length!==a)for(n=0;n<t.length;)e.call(i,t[n],n,t),n++;else for(n in t)t.hasOwnProperty(n)&&e.call(i,t[n],n,t)}function g(t,e,i){var n="DEPRECATED METHOD: "+e+"\n"+i+" AT \n";return function(){var e=new Error("get-stack-trace"),i=e&&e.stack?e.stack.replace(/^[^\(]+?[\n$]/gm,"").replace(/^\s+at\s+/gm,"").replace(/^Object.<anonymous>\s*\(/gm,"{anonymous}()@"):"Unknown Stack Trace",s=r.console&&(r.console.warn||r.console.log);return s&&s.call(r.console,n,i),t.apply(this,arguments)}}h="function"!=typeof Object.assign?function(t){if(t===a||null===t)throw new TypeError("Cannot convert undefined or null to object");for(var e=Object(t),i=1;i<arguments.length;i++){var n=arguments[i];if(n!==a&&null!==n)for(var r in n)n.hasOwnProperty(r)&&(e[r]=n[r])}return e}:Object.assign;var T=g((function(t,e,i){for(var n=Object.keys(e),r=0;r<n.length;)(!i||i&&t[n[r]]===a)&&(t[n[r]]=e[n[r]]),r++;return t}),"extend","Use `assign`."),y=g((function(t,e){return T(t,e,!0)}),"merge","Use `assign`.");function E(t,e,i){var n,r=e.prototype;(n=t.prototype=Object.create(r)).constructor=t,n._super=r,i&&h(n,i)}function I(t,e){return function(){return t.apply(e,arguments)}}function A(t,e){return"function"==typeof t?t.apply(e&&e[0]||a,e):t}function C(t,e){return t===a?e:t}function b(t,e,i){m(D(e),(function(e){t.addEventListener(e,i,!1)}))}function _(t,e,i){m(D(e),(function(e){t.removeEventListener(e,i,!1)}))}function S(t,e){for(;t;){if(t==e)return!0;t=t.parentNode}return!1}function P(t,e){return t.indexOf(e)>-1}function D(t){return t.trim().split(/\s+/g)}function w(t,e,i){if(t.indexOf&&!i)return t.indexOf(e);for(var n=0;n<t.length;){if(i&&t[n][i]==e||!i&&t[n]===e)return n;n++}return-1}function x(t){return Array.prototype.slice.call(t,0)}function O(t,e,i){for(var n=[],r=[],s=0;s<t.length;){var o=e?t[s][e]:t[s];w(r,o)<0&&n.push(t[s]),r[s]=o,s++}return i&&(n=e?n.sort((function(t,i){return t[e]>i[e]})):n.sort()),n}function R(t,e){for(var i,n,r=e[0].toUpperCase()+e.slice(1),s=0;s<u.length;){if((n=(i=u[s])?i+r:e)in t)return n;s++}return a}var M=1;function z(t){var e=t.ownerDocument||t;return e.defaultView||e.parentWindow||r}var N="ontouchstart"in r,X=R(r,"PointerEvent")!==a,Y=N&&/mobile|tablet|ip(ad|hone|od)|android/i.test(navigator.userAgent),F="touch",k="mouse",W=24,q=["x","y"],L=["clientX","clientY"];function H(t,e){var i=this;this.manager=t,this.callback=e,this.element=t.element,this.target=t.options.inputTarget,this.domHandler=function(e){A(t.options.enable,[t])&&i.handler(e)},this.init()}function U(t,e,i){var n=i.pointers.length,r=i.changedPointers.length,s=1&e&&n-r==0,o=12&e&&n-r==0;i.isFirst=!!s,i.isFinal=!!o,s&&(t.session={}),i.eventType=e,function(t,e){
|
||||
var i=t.session,n=e.pointers,r=n.length;i.firstInput||(i.firstInput=V(e));r>1&&!i.firstMultiple?i.firstMultiple=V(e):1===r&&(i.firstMultiple=!1);var s=i.firstInput,o=i.firstMultiple,h=o?o.center:s.center,u=e.center=j(n);e.timeStamp=f(),e.deltaTime=e.timeStamp-s.timeStamp,e.angle=$(h,u),e.distance=B(h,u),function(t,e){var i=e.center,n=t.offsetDelta||{},r=t.prevDelta||{},s=t.prevInput||{};1!==e.eventType&&4!==s.eventType||(r=t.prevDelta={x:s.deltaX||0,y:s.deltaY||0},n=t.offsetDelta={x:i.x,y:i.y});e.deltaX=r.x+(i.x-n.x),e.deltaY=r.y+(i.y-n.y)}(i,e),e.offsetDirection=Z(e.deltaX,e.deltaY);var c=G(e.deltaTime,e.deltaX,e.deltaY);e.overallVelocityX=c.x,e.overallVelocityY=c.y,e.overallVelocity=p(c.x)>p(c.y)?c.x:c.y,e.scale=o?(l=o.pointers,v=n,B(v[0],v[1],L)/B(l[0],l[1],L)):1,e.rotation=o?function(t,e){return $(e[1],e[0],L)+$(t[1],t[0],L)}(o.pointers,n):0,e.maxPointers=i.prevInput?e.pointers.length>i.prevInput.maxPointers?e.pointers.length:i.prevInput.maxPointers:e.pointers.length,function(t,e){var i,n,r,s,o=t.lastInterval||e,h=e.timeStamp-o.timeStamp;if(8!=e.eventType&&(h>25||o.velocity===a)){var u=e.deltaX-o.deltaX,c=e.deltaY-o.deltaY,l=G(h,u,c);n=l.x,r=l.y,i=p(l.x)>p(l.y)?l.x:l.y,s=Z(u,c),t.lastInterval=e}else i=o.velocity,n=o.velocityX,r=o.velocityY,s=o.direction;e.velocity=i,e.velocityX=n,e.velocityY=r,e.direction=s}(i,e);var l,v;var d=t.element;S(e.srcEvent.target,d)&&(d=e.srcEvent.target);e.target=d}(t,i),t.emit("hammer.input",i),t.recognize(i),t.session.prevInput=i}function V(t){for(var e=[],i=0;i<t.pointers.length;)e[i]={clientX:l(t.pointers[i].clientX),clientY:l(t.pointers[i].clientY)},i++;return{timeStamp:f(),pointers:e,center:j(e),deltaX:t.deltaX,deltaY:t.deltaY}}function j(t){var e=t.length;if(1===e)return{x:l(t[0].clientX),y:l(t[0].clientY)};for(var i=0,n=0,r=0;r<e;)i+=t[r].clientX,n+=t[r].clientY,r++;return{x:l(i/e),y:l(n/e)}}function G(t,e,i){return{x:e/t||0,y:i/t||0}}function Z(t,e){return t===e?1:p(t)>=p(e)?t<0?2:4:e<0?8:16}function B(t,e,i){i||(i=q);var n=e[i[0]]-t[i[0]],r=e[i[1]]-t[i[1]];return Math.sqrt(n*n+r*r)}function $(t,e,i){i||(i=q);var n=e[i[0]]-t[i[0]],r=e[i[1]]-t[i[1]];return 180*Math.atan2(r,n)/Math.PI}H.prototype={handler:function(){},init:function(){this.evEl&&b(this.element,this.evEl,this.domHandler),this.evTarget&&b(this.target,this.evTarget,this.domHandler),this.evWin&&b(z(this.element),this.evWin,this.domHandler)},destroy:function(){this.evEl&&_(this.element,this.evEl,this.domHandler),this.evTarget&&_(this.target,this.evTarget,this.domHandler),this.evWin&&_(z(this.element),this.evWin,this.domHandler)}};var J={mousedown:1,mousemove:2,mouseup:4},K="mousedown",Q="mousemove mouseup";function tt(){this.evEl=K,this.evWin=Q,this.pressed=!1,H.apply(this,arguments)}E(tt,H,{handler:function(t){var e=J[t.type];1&e&&0===t.button&&(this.pressed=!0),2&e&&1!==t.which&&(e=4),this.pressed&&(4&e&&(this.pressed=!1),this.callback(this.manager,e,{pointers:[t],changedPointers:[t],pointerType:k,srcEvent:t}))}});var et={pointerdown:1,pointermove:2,pointerup:4,pointercancel:8,pointerout:8},it={2:F,3:"pen",4:k,
|
||||
5:"kinect"},nt="pointerdown",rt="pointermove pointerup pointercancel";function st(){this.evEl=nt,this.evWin=rt,H.apply(this,arguments),this.store=this.manager.session.pointerEvents=[]}r.MSPointerEvent&&!r.PointerEvent&&(nt="MSPointerDown",rt="MSPointerMove MSPointerUp MSPointerCancel"),E(st,H,{handler:function(t){var e=this.store,i=!1,n=t.type.toLowerCase().replace("ms",""),r=et[n],s=it[t.pointerType]||t.pointerType,o=s==F,a=w(e,t.pointerId,"pointerId");1&r&&(0===t.button||o)?a<0&&(e.push(t),a=e.length-1):12&r&&(i=!0),a<0||(e[a]=t,this.callback(this.manager,r,{pointers:e,changedPointers:[t],pointerType:s,srcEvent:t}),i&&e.splice(a,1))}});var ot={touchstart:1,touchmove:2,touchend:4,touchcancel:8};function at(){this.evTarget="touchstart",this.evWin="touchstart touchmove touchend touchcancel",this.started=!1,H.apply(this,arguments)}function ht(t,e){var i=x(t.touches),n=x(t.changedTouches);return 12&e&&(i=O(i.concat(n),"identifier",!0)),[i,n]}E(at,H,{handler:function(t){var e=ot[t.type];if(1===e&&(this.started=!0),this.started){var i=ht.call(this,t,e);12&e&&i[0].length-i[1].length==0&&(this.started=!1),this.callback(this.manager,e,{pointers:i[0],changedPointers:i[1],pointerType:F,srcEvent:t})}}});var ut={touchstart:1,touchmove:2,touchend:4,touchcancel:8},ct="touchstart touchmove touchend touchcancel";function lt(){this.evTarget=ct,this.targetIds={},H.apply(this,arguments)}function pt(t,e){var i=x(t.touches),n=this.targetIds;if(3&e&&1===i.length)return n[i[0].identifier]=!0,[i,i];var r,s,o=x(t.changedTouches),a=[],h=this.target;if(s=i.filter((function(t){return S(t.target,h)})),1===e)for(r=0;r<s.length;)n[s[r].identifier]=!0,r++;for(r=0;r<o.length;)n[o[r].identifier]&&a.push(o[r]),12&e&&delete n[o[r].identifier],r++;return a.length?[O(s.concat(a),"identifier",!0),a]:void 0}E(lt,H,{handler:function(t){var e=ut[t.type],i=pt.call(this,t,e);i&&this.callback(this.manager,e,{pointers:i[0],changedPointers:i[1],pointerType:F,srcEvent:t})}});function ft(){H.apply(this,arguments);var t=I(this.handler,this);this.touch=new lt(this.manager,t),this.mouse=new tt(this.manager,t),this.primaryTouch=null,this.lastTouches=[]}function vt(t,e){1&t?(this.primaryTouch=e.changedPointers[0].identifier,dt.call(this,e)):12&t&&dt.call(this,e)}function dt(t){var e=t.changedPointers[0];if(e.identifier===this.primaryTouch){var i={x:e.clientX,y:e.clientY};this.lastTouches.push(i);var n=this.lastTouches;setTimeout((function(){var t=n.indexOf(i);t>-1&&n.splice(t,1)}),2500)}}function mt(t){for(var e=t.srcEvent.clientX,i=t.srcEvent.clientY,n=0;n<this.lastTouches.length;n++){var r=this.lastTouches[n],s=Math.abs(e-r.x),o=Math.abs(i-r.y);if(s<=25&&o<=25)return!0}return!1}E(ft,H,{handler:function(t,e,i){var n=i.pointerType==F,r=i.pointerType==k;if(!(r&&i.sourceCapabilities&&i.sourceCapabilities.firesTouchEvents)){if(n)vt.call(this,e,i);else if(r&&mt.call(this,i))return;this.callback(t,e,i)}},destroy:function(){this.touch.destroy(),this.mouse.destroy()}})
|
||||
;var gt=R(c.style,"touchAction"),Tt=gt!==a,yt="compute",Et="auto",It="manipulation",At="none",Ct="pan-x",bt="pan-y",_t=function(){if(!Tt)return!1;var t={},e=r.CSS&&r.CSS.supports;return["auto","manipulation","pan-y","pan-x","pan-x pan-y","none"].forEach((function(i){t[i]=!e||r.CSS.supports("touch-action",i)})),t}();function St(t,e){this.manager=t,this.set(e)}St.prototype={set:function(t){t==yt&&(t=this.compute()),Tt&&this.manager.element.style&&_t[t]&&(this.manager.element.style[gt]=t),this.actions=t.toLowerCase().trim()},update:function(){this.set(this.manager.options.touchAction)},compute:function(){var t=[];return m(this.manager.recognizers,(function(e){A(e.options.enable,[e])&&(t=t.concat(e.getTouchAction()))})),function(t){if(P(t,At))return At;var e=P(t,Ct),i=P(t,bt);if(e&&i)return At;if(e||i)return e?Ct:bt;if(P(t,It))return It;return Et}(t.join(" "))},preventDefaults:function(t){var e=t.srcEvent,i=t.offsetDirection;if(this.manager.session.prevented)e.preventDefault();else{var n=this.actions,r=P(n,At)&&!_t[At],s=P(n,bt)&&!_t[bt],o=P(n,Ct)&&!_t[Ct];if(r){var a=1===t.pointers.length,h=t.distance<2,u=t.deltaTime<250;if(a&&h&&u)return}if(!o||!s)return r||s&&6&i||o&&i&W?this.preventSrc(e):void 0}},preventSrc:function(t){this.manager.session.prevented=!0,t.preventDefault()}};var Pt=32;function Dt(t){this.options=h({},this.defaults,t||{}),this.id=M++,this.manager=null,this.options.enable=C(this.options.enable,!0),this.state=1,this.simultaneous={},this.requireFail=[]}function wt(t){return 16&t?"cancel":8&t?"end":4&t?"move":2&t?"start":""}function xt(t){return 16==t?"down":8==t?"up":2==t?"left":4==t?"right":""}function Ot(t,e){var i=e.manager;return i?i.get(t):t}function Rt(){Dt.apply(this,arguments)}function Mt(){Rt.apply(this,arguments),this.pX=null,this.pY=null}function zt(){Rt.apply(this,arguments)}function Nt(){Dt.apply(this,arguments),this._timer=null,this._input=null}function Xt(){Rt.apply(this,arguments)}function Yt(){Rt.apply(this,arguments)}function Ft(){Dt.apply(this,arguments),this.pTime=!1,this.pCenter=!1,this._timer=null,this._input=null,this.count=0}function kt(t,e){return(e=e||{}).recognizers=C(e.recognizers,kt.defaults.preset),new Wt(t,e)}Dt.prototype={defaults:{},set:function(t){return h(this.options,t),this.manager&&this.manager.touchAction.update(),this},recognizeWith:function(t){if(d(t,"recognizeWith",this))return this;var e=this.simultaneous;return e[(t=Ot(t,this)).id]||(e[t.id]=t,t.recognizeWith(this)),this},dropRecognizeWith:function(t){return d(t,"dropRecognizeWith",this)||(t=Ot(t,this),delete this.simultaneous[t.id]),this},requireFailure:function(t){if(d(t,"requireFailure",this))return this;var e=this.requireFail;return-1===w(e,t=Ot(t,this))&&(e.push(t),t.requireFailure(this)),this},dropRequireFailure:function(t){if(d(t,"dropRequireFailure",this))return this;t=Ot(t,this);var e=w(this.requireFail,t);return e>-1&&this.requireFail.splice(e,1),this},hasRequireFailures:function(){return this.requireFail.length>0},canRecognizeWith:function(t){return!!this.simultaneous[t.id]},emit:function(t){
|
||||
var e=this,i=this.state;function n(i){e.manager.emit(i,t)}i<8&&n(e.options.event+wt(i)),n(e.options.event),t.additionalEvent&&n(t.additionalEvent),i>=8&&n(e.options.event+wt(i))},tryEmit:function(t){if(this.canEmit())return this.emit(t);this.state=Pt},canEmit:function(){for(var t=0;t<this.requireFail.length;){if(!(33&this.requireFail[t].state))return!1;t++}return!0},recognize:function(t){var e=h({},t);if(!A(this.options.enable,[this,e]))return this.reset(),void(this.state=Pt);56&this.state&&(this.state=1),this.state=this.process(e),30&this.state&&this.tryEmit(e)},process:function(t){},getTouchAction:function(){},reset:function(){}},E(Rt,Dt,{defaults:{pointers:1},attrTest:function(t){var e=this.options.pointers;return 0===e||t.pointers.length===e},process:function(t){var e=this.state,i=t.eventType,n=6&e,r=this.attrTest(t);return n&&(8&i||!r)?16|e:n||r?4&i?8|e:2&e?4|e:2:Pt}}),E(Mt,Rt,{defaults:{event:"pan",threshold:10,pointers:1,direction:30},getTouchAction:function(){var t=this.options.direction,e=[];return 6&t&&e.push(bt),t&W&&e.push(Ct),e},directionTest:function(t){var e=this.options,i=!0,n=t.distance,r=t.direction,s=t.deltaX,o=t.deltaY;return r&e.direction||(6&e.direction?(r=0===s?1:s<0?2:4,i=s!=this.pX,n=Math.abs(t.deltaX)):(r=0===o?1:o<0?8:16,i=o!=this.pY,n=Math.abs(t.deltaY))),t.direction=r,i&&n>e.threshold&&r&e.direction},attrTest:function(t){return Rt.prototype.attrTest.call(this,t)&&(2&this.state||!(2&this.state)&&this.directionTest(t))},emit:function(t){this.pX=t.deltaX,this.pY=t.deltaY;var e=xt(t.direction);e&&(t.additionalEvent=this.options.event+e),this._super.emit.call(this,t)}}),E(zt,Rt,{defaults:{event:"pinch",threshold:0,pointers:2},getTouchAction:function(){return[At]},attrTest:function(t){return this._super.attrTest.call(this,t)&&(Math.abs(t.scale-1)>this.options.threshold||2&this.state)},emit:function(t){if(1!==t.scale){var e=t.scale<1?"in":"out";t.additionalEvent=this.options.event+e}this._super.emit.call(this,t)}}),E(Nt,Dt,{defaults:{event:"press",pointers:1,time:251,threshold:9},getTouchAction:function(){return[Et]},process:function(t){var e=this.options,i=t.pointers.length===e.pointers,n=t.distance<e.threshold,r=t.deltaTime>e.time;if(this._input=t,!n||!i||12&t.eventType&&!r)this.reset();else if(1&t.eventType)this.reset(),this._timer=v((function(){this.state=8,this.tryEmit()}),e.time,this);else if(4&t.eventType)return 8;return Pt},reset:function(){clearTimeout(this._timer)},emit:function(t){8===this.state&&(t&&4&t.eventType?this.manager.emit(this.options.event+"up",t):(this._input.timeStamp=f(),this.manager.emit(this.options.event,this._input)))}}),E(Xt,Rt,{defaults:{event:"rotate",threshold:0,pointers:2},getTouchAction:function(){return[At]},attrTest:function(t){return this._super.attrTest.call(this,t)&&(Math.abs(t.rotation)>this.options.threshold||2&this.state)}}),E(Yt,Rt,{defaults:{event:"swipe",threshold:10,velocity:.3,direction:30,pointers:1},getTouchAction:function(){return Mt.prototype.getTouchAction.call(this)},attrTest:function(t){var e,i=this.options.direction
|
||||
;return 30&i?e=t.overallVelocity:6&i?e=t.overallVelocityX:i&W&&(e=t.overallVelocityY),this._super.attrTest.call(this,t)&&i&t.offsetDirection&&t.distance>this.options.threshold&&t.maxPointers==this.options.pointers&&p(e)>this.options.velocity&&4&t.eventType},emit:function(t){var e=xt(t.offsetDirection);e&&this.manager.emit(this.options.event+e,t),this.manager.emit(this.options.event,t)}}),E(Ft,Dt,{defaults:{event:"tap",pointers:1,taps:1,interval:300,time:250,threshold:9,posThreshold:10},getTouchAction:function(){return[It]},process:function(t){var e=this.options,i=t.pointers.length===e.pointers,n=t.distance<e.threshold,r=t.deltaTime<e.time;if(this.reset(),1&t.eventType&&0===this.count)return this.failTimeout();if(n&&r&&i){if(4!=t.eventType)return this.failTimeout();var s=!this.pTime||t.timeStamp-this.pTime<e.interval,o=!this.pCenter||B(this.pCenter,t.center)<e.posThreshold;if(this.pTime=t.timeStamp,this.pCenter=t.center,o&&s?this.count+=1:this.count=1,this._input=t,0===this.count%e.taps)return this.hasRequireFailures()?(this._timer=v((function(){this.state=8,this.tryEmit()}),e.interval,this),2):8}return Pt},failTimeout:function(){return this._timer=v((function(){this.state=Pt}),this.options.interval,this),Pt},reset:function(){clearTimeout(this._timer)},emit:function(){8==this.state&&(this._input.tapCount=this.count,this.manager.emit(this.options.event,this._input))}}),kt.VERSION="2.0.7",kt.defaults={domEvents:!1,touchAction:yt,enable:!0,inputTarget:null,inputClass:null,preset:[[Xt,{enable:!1}],[zt,{enable:!1},["rotate"]],[Yt,{direction:6}],[Mt,{direction:6},["swipe"]],[Ft],[Ft,{event:"doubletap",taps:2},["tap"]],[Nt]],cssProps:{userSelect:"none",touchSelect:"none",touchCallout:"none",contentZooming:"none",userDrag:"none",tapHighlightColor:"rgba(0,0,0,0)"}};function Wt(t,e){var i;this.options=h({},kt.defaults,e||{}),this.options.inputTarget=this.options.inputTarget||t,this.handlers={},this.session={},this.recognizers=[],this.oldCssProps={},this.element=t,this.input=new((i=this).options.inputClass||(X?st:Y?lt:N?ft:tt))(i,U),this.touchAction=new St(this,this.options.touchAction),qt(this,!0),m(this.options.recognizers,(function(t){var e=this.add(new t[0](t[1]));t[2]&&e.recognizeWith(t[2]),t[3]&&e.requireFailure(t[3])}),this)}function qt(t,e){var i,n=t.element;n.style&&(m(t.options.cssProps,(function(r,s){i=R(n.style,s),e?(t.oldCssProps[i]=n.style[i],n.style[i]=r):n.style[i]=t.oldCssProps[i]||""})),e||(t.oldCssProps={}))}Wt.prototype={set:function(t){return h(this.options,t),t.touchAction&&this.touchAction.update(),t.inputTarget&&(this.input.destroy(),this.input.target=t.inputTarget,this.input.init()),this},stop:function(t){this.session.stopped=t?2:1},recognize:function(t){var e=this.session;if(!e.stopped){var i;this.touchAction.preventDefaults(t);var n=this.recognizers,r=e.curRecognizer;(!r||r&&8&r.state)&&(r=e.curRecognizer=null);for(var s=0;s<n.length;)i=n[s],2===e.stopped||r&&i!=r&&!i.canRecognizeWith(r)?i.reset():i.recognize(t),!r&&14&i.state&&(r=e.curRecognizer=i),s++}},get:function(t){if(t instanceof Dt)return t
|
||||
;for(var e=this.recognizers,i=0;i<e.length;i++)if(e[i].options.event==t)return e[i];return null},add:function(t){if(d(t,"add",this))return this;var e=this.get(t.options.event);return e&&this.remove(e),this.recognizers.push(t),t.manager=this,this.touchAction.update(),t},remove:function(t){if(d(t,"remove",this))return this;if(t=this.get(t)){var e=this.recognizers,i=w(e,t);-1!==i&&(e.splice(i,1),this.touchAction.update())}return this},on:function(t,e){if(t!==a&&e!==a){var i=this.handlers;return m(D(t),(function(t){i[t]=i[t]||[],i[t].push(e)})),this}},off:function(t,e){if(t!==a){var i=this.handlers;return m(D(t),(function(t){e?i[t]&&i[t].splice(w(i[t],e),1):delete i[t]})),this}},emit:function(t,e){this.options.domEvents&&function(t,e){var i=s.createEvent("Event");i.initEvent(t,!0,!0),i.gesture=e,e.target.dispatchEvent(i)}(t,e);var i=this.handlers[t]&&this.handlers[t].slice();if(i&&i.length){e.type=t,e.preventDefault=function(){e.srcEvent.preventDefault()};for(var n=0;n<i.length;)i[n](e),n++}},destroy:function(){this.element&&qt(this,!1),this.handlers={},this.session={},this.input.destroy(),this.element=null}},h(kt,{INPUT_START:1,INPUT_MOVE:2,INPUT_END:4,INPUT_CANCEL:8,STATE_POSSIBLE:1,STATE_BEGAN:2,STATE_CHANGED:4,STATE_ENDED:8,STATE_RECOGNIZED:8,STATE_CANCELLED:16,STATE_FAILED:Pt,DIRECTION_NONE:1,DIRECTION_LEFT:2,DIRECTION_RIGHT:4,DIRECTION_UP:8,DIRECTION_DOWN:16,DIRECTION_HORIZONTAL:6,DIRECTION_VERTICAL:W,DIRECTION_ALL:30,Manager:Wt,Input:H,TouchAction:St,TouchInput:lt,MouseInput:tt,PointerEventInput:st,TouchMouseInput:ft,SingleTouchInput:at,Recognizer:Dt,AttrRecognizer:Rt,Tap:Ft,Pan:Mt,Swipe:Yt,Pinch:zt,Rotate:Xt,Press:Nt,on:b,off:_,each:m,merge:y,extend:T,assign:h,inherit:E,bindFn:I,prefixed:R}),(void 0!==r?r:"undefined"!=typeof self?self:{}).Hammer=kt,(n=function(){return kt}.call(e,i,e,t))===a||(t.exports=n)}(window,document)}}]);
|
||||
@@ -0,0 +1 @@
|
||||
[data-theme=light]{--_0-IsoO:var(--color-cold-gray-350);--_1-IsoO:var(--color-cold-gray-100);--_2-IsoO:var(--color-cold-gray-200);--_3-IsoO:var(--color-cold-gray-100);--_4-IsoO:var(--color-cold-gray-300);--_5-IsoO:var(--color-cold-gray-200)}[data-theme=dark]{--_0-IsoO:var(--color-cold-gray-550);--_1-IsoO:var(--color-cold-gray-800);--_2-IsoO:var(--color-cold-gray-650);--_3-IsoO:var(--color-cold-gray-800);--_4-IsoO:var(--color-cold-gray-650);--_5-IsoO:var(--color-cold-gray-650)}.wrapper-VB9J73Gf{align-items:center;border-color:var(--color-control-intent-default);border-radius:6px;border-style:solid;box-sizing:border-box;display:inline-flex;margin:0;position:relative}@media (any-hover:hover){.wrapper-VB9J73Gf:hover{border-color:var(--_0-IsoO)}}.wrapper-VB9J73Gf.focused-VB9J73Gf{border-color:var(--color-control-intent-primary)}.wrapper-VB9J73Gf.readonly-VB9J73Gf{background-color:var(--_1-IsoO);border-color:var(--_2-IsoO)}.wrapper-VB9J73Gf.disabled-VB9J73Gf{background-color:var(--_3-IsoO);border-color:var(--_5-IsoO);color:var(--_4-IsoO)}.wrapper-VB9J73Gf.size-small-VB9J73Gf{height:24px}.wrapper-VB9J73Gf.size-medium-VB9J73Gf{height:34px}.wrapper-VB9J73Gf.size-large-VB9J73Gf{height:48px}.wrapper-VB9J73Gf.font-size-medium-VB9J73Gf,.wrapper-VB9J73Gf.font-size-small-VB9J73Gf{font-size:14px;line-height:20px}.wrapper-VB9J73Gf.font-size-large-VB9J73Gf{font-size:16px;line-height:24px}.wrapper-VB9J73Gf.border-none-VB9J73Gf{border-width:0}.wrapper-VB9J73Gf.border-none-VB9J73Gf .shadow-VB9J73Gf{margin:0}.wrapper-VB9J73Gf.border-thin-VB9J73Gf{border-width:1px}.wrapper-VB9J73Gf.border-thin-VB9J73Gf .shadow-VB9J73Gf{margin:-1px}.wrapper-VB9J73Gf.border-thick-VB9J73Gf{border-width:2px}.wrapper-VB9J73Gf.border-thick-VB9J73Gf .shadow-VB9J73Gf{margin:-2px}.wrapper-VB9J73Gf.intent-default-VB9J73Gf .shadow-VB9J73Gf{border-color:var(--color-control-intent-default)}.wrapper-VB9J73Gf.intent-success-VB9J73Gf,.wrapper-VB9J73Gf.intent-success-VB9J73Gf .shadow-VB9J73Gf{border-color:var(--color-control-intent-success)}.wrapper-VB9J73Gf.intent-warning-VB9J73Gf,.wrapper-VB9J73Gf.intent-warning-VB9J73Gf .shadow-VB9J73Gf{border-color:var(--color-control-intent-warning)}.wrapper-VB9J73Gf.intent-danger-VB9J73Gf,.wrapper-VB9J73Gf.intent-danger-VB9J73Gf .shadow-VB9J73Gf{border-color:var(--color-control-intent-danger)}.wrapper-VB9J73Gf.intent-primary-VB9J73Gf,.wrapper-VB9J73Gf.intent-primary-VB9J73Gf .shadow-VB9J73Gf{border-color:var(--color-control-intent-primary)}.wrapper-VB9J73Gf.corner-top-left-VB9J73Gf{border-top-left-radius:0}.wrapper-VB9J73Gf.corner-top-right-VB9J73Gf{border-top-right-radius:0}.wrapper-VB9J73Gf.corner-bottom-right-VB9J73Gf{border-bottom-right-radius:0}.wrapper-VB9J73Gf.corner-bottom-left-VB9J73Gf{border-bottom-left-radius:0}.shadow-VB9J73Gf{border:2px solid;border-radius:6px;bottom:0;left:0;pointer-events:none;position:absolute;right:0;top:0;z-index:3}.shadow-VB9J73Gf.corner-top-left-VB9J73Gf{border-top-left-radius:0}.shadow-VB9J73Gf.corner-top-right-VB9J73Gf{border-top-right-radius:0}.shadow-VB9J73Gf.corner-bottom-right-VB9J73Gf{border-bottom-right-radius:0}.shadow-VB9J73Gf.corner-bottom-left-VB9J73Gf{border-bottom-left-radius:0}.childrenContainer-VB9J73Gf.disabled-VB9J73Gf{opacity:.5}.buttonWrap-icygBqe7{display:flex}.desktopSize-icygBqe7{width:354px}.drawer-icygBqe7,.menuBox-icygBqe7{padding:0}
|
||||
@@ -0,0 +1 @@
|
||||
[data-theme=light]{--_0-IsoO:var(--color-cold-gray-350);--_1-IsoO:var(--color-cold-gray-100);--_2-IsoO:var(--color-cold-gray-200);--_3-IsoO:var(--color-cold-gray-100);--_4-IsoO:var(--color-cold-gray-300);--_5-IsoO:var(--color-cold-gray-200)}[data-theme=dark]{--_0-IsoO:var(--color-cold-gray-550);--_1-IsoO:var(--color-cold-gray-800);--_2-IsoO:var(--color-cold-gray-650);--_3-IsoO:var(--color-cold-gray-800);--_4-IsoO:var(--color-cold-gray-650);--_5-IsoO:var(--color-cold-gray-650)}.wrapper-VB9J73Gf{align-items:center;border-color:var(--color-control-intent-default);border-radius:6px;border-style:solid;box-sizing:border-box;display:inline-flex;margin:0;position:relative}@media (any-hover:hover){.wrapper-VB9J73Gf:hover{border-color:var(--_0-IsoO)}}.wrapper-VB9J73Gf.focused-VB9J73Gf{border-color:var(--color-control-intent-primary)}.wrapper-VB9J73Gf.readonly-VB9J73Gf{background-color:var(--_1-IsoO);border-color:var(--_2-IsoO)}.wrapper-VB9J73Gf.disabled-VB9J73Gf{background-color:var(--_3-IsoO);border-color:var(--_5-IsoO);color:var(--_4-IsoO)}.wrapper-VB9J73Gf.size-small-VB9J73Gf{height:24px}.wrapper-VB9J73Gf.size-medium-VB9J73Gf{height:34px}.wrapper-VB9J73Gf.size-large-VB9J73Gf{height:48px}.wrapper-VB9J73Gf.font-size-medium-VB9J73Gf,.wrapper-VB9J73Gf.font-size-small-VB9J73Gf{font-size:14px;line-height:20px}.wrapper-VB9J73Gf.font-size-large-VB9J73Gf{font-size:16px;line-height:24px}.wrapper-VB9J73Gf.border-none-VB9J73Gf{border-width:0}.wrapper-VB9J73Gf.border-none-VB9J73Gf .shadow-VB9J73Gf{margin:0}.wrapper-VB9J73Gf.border-thin-VB9J73Gf{border-width:1px}.wrapper-VB9J73Gf.border-thin-VB9J73Gf .shadow-VB9J73Gf{margin:-1px}.wrapper-VB9J73Gf.border-thick-VB9J73Gf{border-width:2px}.wrapper-VB9J73Gf.border-thick-VB9J73Gf .shadow-VB9J73Gf{margin:-2px}.wrapper-VB9J73Gf.intent-default-VB9J73Gf .shadow-VB9J73Gf{border-color:var(--color-control-intent-default)}.wrapper-VB9J73Gf.intent-success-VB9J73Gf,.wrapper-VB9J73Gf.intent-success-VB9J73Gf .shadow-VB9J73Gf{border-color:var(--color-control-intent-success)}.wrapper-VB9J73Gf.intent-warning-VB9J73Gf,.wrapper-VB9J73Gf.intent-warning-VB9J73Gf .shadow-VB9J73Gf{border-color:var(--color-control-intent-warning)}.wrapper-VB9J73Gf.intent-danger-VB9J73Gf,.wrapper-VB9J73Gf.intent-danger-VB9J73Gf .shadow-VB9J73Gf{border-color:var(--color-control-intent-danger)}.wrapper-VB9J73Gf.intent-primary-VB9J73Gf,.wrapper-VB9J73Gf.intent-primary-VB9J73Gf .shadow-VB9J73Gf{border-color:var(--color-control-intent-primary)}.wrapper-VB9J73Gf.corner-top-left-VB9J73Gf{border-top-right-radius:0}.wrapper-VB9J73Gf.corner-top-right-VB9J73Gf{border-top-left-radius:0}.wrapper-VB9J73Gf.corner-bottom-right-VB9J73Gf{border-bottom-left-radius:0}.wrapper-VB9J73Gf.corner-bottom-left-VB9J73Gf{border-bottom-right-radius:0}.shadow-VB9J73Gf{border:2px solid;border-radius:6px;bottom:0;left:0;pointer-events:none;position:absolute;right:0;top:0;z-index:3}.shadow-VB9J73Gf.corner-top-left-VB9J73Gf{border-top-right-radius:0}.shadow-VB9J73Gf.corner-top-right-VB9J73Gf{border-top-left-radius:0}.shadow-VB9J73Gf.corner-bottom-right-VB9J73Gf{border-bottom-left-radius:0}.shadow-VB9J73Gf.corner-bottom-left-VB9J73Gf{border-bottom-right-radius:0}.childrenContainer-VB9J73Gf.disabled-VB9J73Gf{opacity:.5}.buttonWrap-icygBqe7{display:flex}.desktopSize-icygBqe7{width:354px}.drawer-icygBqe7,.menuBox-icygBqe7{padding:0}
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -0,0 +1 @@
|
||||
.menuWrap-Kq3ruQo8{background-color:var(--tv-color-popup-background,var(--color-popup-background));border-radius:6px;box-shadow:0 2px 4px var(--color-shadow-primary-neutral-extra-heavy);box-sizing:border-box;text-align:left;-webkit-user-select:none;user-select:none;z-index:100}.menuWrap-Kq3ruQo8.isMeasuring-Kq3ruQo8{opacity:0;pointer-events:none;position:fixed;visibility:hidden}.menuWrap-Kq3ruQo8:focus{outline:none}.scrollWrap-Kq3ruQo8{height:100%;overflow-x:hidden;overflow-y:auto}.scrollWrap-Kq3ruQo8.momentumBased-Kq3ruQo8{-webkit-overflow-scrolling:touch}.scrollWrap-Kq3ruQo8::-webkit-scrollbar{height:5px;width:5px}.scrollWrap-Kq3ruQo8::-webkit-scrollbar-thumb{background-clip:content-box;background-color:var(--tv-color-scrollbar-thumb-background,var(--color-scroll-bg));border:1px solid #0000;border-radius:3px}.scrollWrap-Kq3ruQo8::-webkit-scrollbar-track{background-color:initial;border-radius:3px}.scrollWrap-Kq3ruQo8::-webkit-scrollbar-corner{display:none}.menuBox-Kq3ruQo8{padding:6px 0}.isHidden-Kq3ruQo8{display:none}
|
||||
@@ -0,0 +1 @@
|
||||
.menuWrap-Kq3ruQo8{background-color:var(--tv-color-popup-background,var(--color-popup-background));border-radius:6px;box-shadow:0 2px 4px var(--color-shadow-primary-neutral-extra-heavy);box-sizing:border-box;text-align:right;-webkit-user-select:none;user-select:none;z-index:100}.menuWrap-Kq3ruQo8.isMeasuring-Kq3ruQo8{opacity:0;pointer-events:none;position:fixed;visibility:hidden}.menuWrap-Kq3ruQo8:focus{outline:none}.scrollWrap-Kq3ruQo8{height:100%;overflow-x:hidden;overflow-y:auto}.scrollWrap-Kq3ruQo8.momentumBased-Kq3ruQo8{-webkit-overflow-scrolling:touch}.scrollWrap-Kq3ruQo8::-webkit-scrollbar{height:5px;width:5px}.scrollWrap-Kq3ruQo8::-webkit-scrollbar-thumb{background-clip:content-box;background-color:var(--tv-color-scrollbar-thumb-background,var(--color-scroll-bg));border:1px solid #0000;border-radius:3px}.scrollWrap-Kq3ruQo8::-webkit-scrollbar-track{background-color:initial;border-radius:3px}.scrollWrap-Kq3ruQo8::-webkit-scrollbar-corner{display:none}.menuBox-Kq3ruQo8{padding:6px 0}.isHidden-Kq3ruQo8{display:none}
|
||||
@@ -0,0 +1 @@
|
||||
[data-theme=light]{--_0-LFvl:var(--color-cold-gray-900);--_1-LFvl:var(--color-cold-gray-150)}[data-theme=dark]{--_0-LFvl:var(--color-cold-gray-350);--_1-LFvl:var(--color-cold-gray-700)}.container-qm7Rg5MB{align-items:center;border-bottom:1px solid;border-top:1px solid;border-color:var(--_1-LFvl);cursor:default;display:flex;flex-shrink:0;position:relative}.container-qm7Rg5MB.mobile-qm7Rg5MB{background-color:var(--color-container-fill-primary-neutral-extra-light);border:none;border-radius:40px;margin:4px 20px 8px}.inputContainer-qm7Rg5MB{height:24px;padding:8px 16px 8px 47px;width:100%}.inputContainer-qm7Rg5MB.mobile-qm7Rg5MB{padding-left:40px}.inputContainer-qm7Rg5MB.withCancel-qm7Rg5MB{padding-right:70px}.input-qm7Rg5MB{background-color:initial;border:none;color:var(--_0-LFvl);font-size:16px;height:100%;margin:0;padding:0;width:100%}.input-qm7Rg5MB.mobile-qm7Rg5MB{color:var(--color-content-primary-neutral-bold)}.input-qm7Rg5MB.mobile-qm7Rg5MB::placeholder{color:var(--color-content-primary-neutral);font-weight:400}.input-qm7Rg5MB::placeholder{color:var(--color-input-placeholder-text);font-weight:400}.icon-qm7Rg5MB{color:var(--color-cold-gray-350);height:28px;left:15px;pointer-events:none;position:absolute;top:calc(50% - 14px)}.icon-qm7Rg5MB.mobile-qm7Rg5MB{color:var(--color-content-primary-neutral);left:8px}.cancel-qm7Rg5MB{color:var(--color-default-gray);position:absolute;right:20px}.cancel-qm7Rg5MB.mobile-qm7Rg5MB{color:var(--color-content-primary-neutral)}.highlighted-cwp8YRo6{color:var(--color-brand)}
|
||||
@@ -0,0 +1 @@
|
||||
[data-theme=light]{--_0-LFvl:var(--color-cold-gray-900);--_1-LFvl:var(--color-cold-gray-150)}[data-theme=dark]{--_0-LFvl:var(--color-cold-gray-350);--_1-LFvl:var(--color-cold-gray-700)}.container-qm7Rg5MB{align-items:center;border-bottom:1px solid;border-top:1px solid;border-color:var(--_1-LFvl);cursor:default;display:flex;flex-shrink:0;position:relative}.container-qm7Rg5MB.mobile-qm7Rg5MB{background-color:var(--color-container-fill-primary-neutral-extra-light);border:none;border-radius:40px;margin:4px 20px 8px}.inputContainer-qm7Rg5MB{height:24px;padding:8px 47px 8px 16px;width:100%}.inputContainer-qm7Rg5MB.mobile-qm7Rg5MB{padding-right:40px}.inputContainer-qm7Rg5MB.withCancel-qm7Rg5MB{padding-left:70px}.input-qm7Rg5MB{background-color:initial;border:none;color:var(--_0-LFvl);font-size:16px;height:100%;margin:0;padding:0;width:100%}.input-qm7Rg5MB.mobile-qm7Rg5MB{color:var(--color-content-primary-neutral-bold)}.input-qm7Rg5MB.mobile-qm7Rg5MB::placeholder{color:var(--color-content-primary-neutral);font-weight:400}.input-qm7Rg5MB::placeholder{color:var(--color-input-placeholder-text);font-weight:400}.icon-qm7Rg5MB{color:var(--color-cold-gray-350);height:28px;pointer-events:none;position:absolute;right:15px;top:calc(50% - 14px)}.icon-qm7Rg5MB.mobile-qm7Rg5MB{color:var(--color-content-primary-neutral);right:8px}.cancel-qm7Rg5MB{color:var(--color-default-gray);left:20px;position:absolute}.cancel-qm7Rg5MB.mobile-qm7Rg5MB{color:var(--color-content-primary-neutral)}.highlighted-cwp8YRo6{color:var(--color-brand)}
|
||||
@@ -0,0 +1,12 @@
|
||||
(self.webpackChunktradingview=self.webpackChunktradingview||[]).push([[1727],{16499:e=>{e.exports={favorite:"favorite-_FRQhM5Y",hovered:"hovered-_FRQhM5Y",disabled:"disabled-_FRQhM5Y",focused:"focused-_FRQhM5Y",active:"active-_FRQhM5Y",checked:"checked-_FRQhM5Y"}},74670:(e,o,l)=>{"use strict";l.d(o,{useActiveDescendant:()=>n});var t=l(50959),i=l(39416);function n(e,o=[]){const[l,n]=(0,t.useState)(!1),a=(0,i.useFunctionalRefObject)(e);return(0,t.useLayoutEffect)((()=>{const e=a.current;if(null===e)return;const o=e=>{switch(e.type){case"active-descendant-focus":n(!0);break;case"active-descendant-blur":n(!1)}};return e.addEventListener("active-descendant-focus",o),e.addEventListener("active-descendant-blur",o),()=>{e.removeEventListener("active-descendant-focus",o),e.removeEventListener("active-descendant-blur",o)}}),o),[a,l]}},71402:(e,o,l)=>{"use strict";l.d(o,{RemoveTitleType:()=>t,removeTitlesMap:()=>n});var t,i=l(11542);!function(e){e.Add="add",e.Remove="remove"}(t||(t={}));const n={[t.Add]:i.t(null,void 0,l(69207)),[t.Remove]:i.t(null,void 0,l(85106))}},36189:(e,o,l)=>{"use strict";l.d(o,{FavoriteButton:()=>d});var t=l(50959),i=l(97754),n=l.n(i),a=l(9745),r=l(71402),s=l(74670),c=l(39146),v=l(48010),h=l(16499);function d(e){const{className:o,isFilled:l,isActive:i,onClick:d,title:m,...u}=e,[g,L]=(0,s.useActiveDescendant)(null),T=m??(l?r.removeTitlesMap[r.RemoveTitleType.Remove]:r.removeTitlesMap[r.RemoveTitleType.Add]);return(0,t.useLayoutEffect)((()=>{const e=g.current;e instanceof HTMLElement&&T&&e.dispatchEvent(new CustomEvent("common-tooltip-update"))}),[T,g]),t.createElement(a.Icon,{...u,className:n()(h.favorite,"apply-common-tooltip",l&&h.checked,i&&h.active,L&&h.focused,o),onClick:d,icon:l?c:v,title:T,ariaLabel:T,ref:g})}},73607:(e,o,l)=>{"use strict";l.d(o,{focusFirstMenuItem:()=>v,handleAccessibleMenuFocus:()=>s,handleAccessibleMenuKeyDown:()=>c,queryMenuElements:()=>m});var t=l(22692),i=l(33647),n=l(68335),a=l(15754);const r=[37,39,38,40];function s(e,o){if(!e.target)return;const l=e.relatedTarget?.getAttribute("aria-activedescendant");if(e.relatedTarget!==o.current){const e=l&&document.getElementById(l);if(!e||e!==o.current)return}v(e.target)}function c(e){if(e.defaultPrevented)return;const o=(0,n.hashFromEvent)(e);if(!r.includes(o))return;const l=document.activeElement;if(!(document.activeElement instanceof HTMLElement))return;const a=m(e.currentTarget).sort(t.navigationOrderComparator);if(0===a.length)return;const s=document.activeElement.closest('[data-role="menuitem"]')||document.activeElement.parentElement?.querySelector('[data-role="menuitem"]');if(!(s instanceof HTMLElement))return;const c=a.indexOf(s);if(-1===c)return;const v=u(s),g=v.indexOf(document.activeElement),L=-1!==g,T=e=>{l&&(0,i.becomeSecondaryElement)(l),(0,i.becomeMainElement)(e),e.focus()};switch((0,t.mapKeyCodeToDirection)(o)){case"inlinePrev":if(!v.length)return;e.preventDefault(),T(0===g?a[c]:L?h(v,g,-1):v[v.length-1]);break;case"inlineNext":if(!v.length)return;e.preventDefault(),g===v.length-1?T(a[c]):T(L?h(v,g,1):v[0]);break
|
||||
;case"blockPrev":{e.preventDefault();const o=h(a,c,-1);if(L){const e=d(o,g);T(e||o);break}T(o);break}case"blockNext":{e.preventDefault();const o=h(a,c,1);if(L){const e=d(o,g);T(e||o);break}T(o)}}}function v(e){const[o]=m(e);o&&((0,i.becomeMainElement)(o),o.focus())}function h(e,o,l){return e[(o+e.length+l)%e.length]}function d(e,o){const l=u(e);return l.length?l[(o+l.length)%l.length]:null}function m(e){return Array.from(e.querySelectorAll('[data-role="menuitem"]:not([disabled]):not([aria-disabled])')).filter((0,a.createScopedVisibleElementFilter)(e))}function u(e){return Array.from(e.querySelectorAll("[tabindex]:not([disabled]):not([aria-disabled])")).filter((0,a.createScopedVisibleElementFilter)(e))}},70173:(e,o,l)=>{"use strict";l.d(o,{drawingToolsIcons:()=>t});const t={SyncDrawing:l(99088),arrow:l(63743),cursor:l(18953),dot:l(72196),demonstration:l(54780),performance:"",drawginmode:l(52459),drawginmodeActive:l(63975),eraser:l(27999),group:l(34059),hideAllDrawings:l(45820),hideAllDrawingsActive:l(84959),hideAllIndicators:l(42321),hideAllIndicatorsActive:l(75895),hideAllDrawingTools:l(93756),hideAllDrawingToolsActive:l(42650),hideAllPositionsTools:l(57313),hideAllPositionsToolsActive:l(65162),lockAllDrawings:l(91244),lockAllDrawingsActive:l(65186),magnet:l(68385),heart:l(10862),smile:l(7636),sticker:l(62567),strongMagnet:l(46049),measure:l(88518),removeAllDrawingTools:l(93544),showObjectsTree:l(36515),zoom:l(6894),"zoom-out":l(45360)}},84902:(e,o,l)=>{"use strict";l.d(o,{isLineTool:()=>d,isLineToolOption:()=>m,isLineToolSwitcherOption:()=>u,isLineToolsGroupWithSections:()=>h,lineTools:()=>v,lineToolsFlat:()=>g});var t=l(11542),i=l(49483),n=l(37103),a=l(57340),r=l(87465);const s=n.enabled("image_drawingtool"),c=!i.CheckMobile.any()&&n.enabled("long_press_floating_tooltip"),v=[{id:"linetool-group-cursors",title:t.t(null,void 0,l(81578)),sections:[{items:[{name:"cursor"},{name:"dot"},{name:"arrow"},{name:"demonstration"},null].filter(r.isExistent)},{items:[{name:"eraser"},c?{type:"switcher",reactKey:"values-tooltip-on-long-press",label:t.t(null,void 0,l(84145)),value:"valuesTooltipOnLongPress",watchedValue:a.chartFloatingTooltipEnabledWV}:null].filter(r.isExistent)}],trackLabel:null},{id:"linetool-group-trend-line",title:t.t(null,void 0,l(48773)),sections:[{title:t.t(null,void 0,l(56982)),items:[{name:"LineToolTrendLine"},{name:"LineToolRay"},{name:"LineToolInfoLine"},{name:"LineToolExtended"},{name:"LineToolTrendAngle"},{name:"LineToolHorzLine"},{name:"LineToolHorzRay"},{name:"LineToolVertLine"},{name:"LineToolCrossLine"}]},{title:t.t(null,void 0,l(59934)),items:[{name:"LineToolParallelChannel"},{name:"LineToolRegressionTrend"},{name:"LineToolFlatBottom"},{name:"LineToolDisjointAngle"}]},{title:t.t(null,void 0,l(36167)),items:[{name:"LineToolPitchfork"},{name:"LineToolSchiffPitchfork2"},{name:"LineToolSchiffPitchfork"},{name:"LineToolInsidePitchfork"}]}],trackLabel:null},{id:"linetool-group-gann-and-fibonacci",title:t.t(null,void 0,l(2654)),sections:[{title:t.t(null,void 0,l(26578)),items:[{
|
||||
name:"LineToolFibRetracement"},{name:"LineToolTrendBasedFibExtension"},{name:"LineToolFibChannel"},{name:"LineToolFibTimeZone"},{name:"LineToolFibSpeedResistanceFan"},{name:"LineToolTrendBasedFibTime"},{name:"LineToolFibCircles"},{name:"LineToolFibSpiral"},{name:"LineToolFibSpeedResistanceArcs"},{name:"LineToolFibWedge"},{name:"LineToolPitchfan"}]},{title:t.t(null,void 0,l(51494)),items:[{name:"LineToolGannSquare"},{name:"LineToolGannFixed"},{name:"LineToolGannComplex"},{name:"LineToolGannFan"}]}],trackLabel:null},{id:"linetool-group-patterns",title:t.t(null,void 0,l(46417)),sections:[{title:t.t(null,void 0,l(46417)),items:[{name:"LineTool5PointsPattern"},{name:"LineToolCypherPattern"},{name:"LineToolHeadAndShoulders"},{name:"LineToolABCD"},{name:"LineToolTrianglePattern"},{name:"LineToolThreeDrivers"}]},{title:t.t(null,void 0,l(44255)),items:[{name:"LineToolElliottImpulse"},{name:"LineToolElliottCorrection"},{name:"LineToolElliottTriangle"},{name:"LineToolElliottDoubleCombo"},{name:"LineToolElliottTripleCombo"}]},{title:t.t(null,void 0,l(77915)),items:[{name:"LineToolCircleLines"},{name:"LineToolTimeCycles"},{name:"LineToolSineLine"}]}],trackLabel:null},{id:"linetool-group-prediction-and-measurement",title:t.t(null,void 0,l(1410)),sections:[{title:t.t(null,void 0,l(75747)),items:[{name:"LineToolRiskRewardLong"},{name:"LineToolRiskRewardShort"},{name:"LineToolPrediction"},{name:"LineToolBarsPattern"},{name:"LineToolGhostFeed"},{name:"LineToolProjection"}].filter(r.isExistent)},{title:t.t(null,void 0,l(69260)),items:[{name:"LineToolAnchoredVWAP"},{name:"LineToolFixedRangeVolumeProfile"},null].filter(r.isExistent)},{title:t.t(null,void 0,l(97050)),items:[{name:"LineToolPriceRange"},{name:"LineToolDateRange"},{name:"LineToolDateAndPriceRange"}]}],trackLabel:null},{id:"linetool-group-geometric-shapes",title:t.t(null,void 0,l(22145)),sections:[{title:t.t(null,void 0,l(65695)),items:[{name:"LineToolBrush"},{name:"LineToolHighlighter"}]},{title:t.t(null,void 0,l(19147)),items:[{name:"LineToolArrowMarker"},{name:"LineToolArrow"},{name:"LineToolArrowMarkUp"},{name:"LineToolArrowMarkDown"},{name:"LineToolArrowMarkLeft"},{name:"LineToolArrowMarkRight"}].filter(r.isExistent)},{title:t.t(null,void 0,l(65781)),items:[{name:"LineToolRectangle"},{name:"LineToolRotatedRectangle"},{name:"LineToolPath"},{name:"LineToolCircle"},{name:"LineToolEllipse"},{name:"LineToolPolyline"},{name:"LineToolTriangle"},{name:"LineToolArc"},{name:"LineToolBezierQuadro"},{name:"LineToolBezierCubic"}]}],trackLabel:null},{id:"linetool-group-annotation",title:t.t(null,void 0,l(32064)),sections:[{title:t.t(null,void 0,l(65831)),items:[{name:"LineToolText"},{name:"LineToolTextAbsolute"},{name:"LineToolTextNote"},{name:"LineToolPriceNote"},{name:"LineToolNote"},{name:"LineToolTable"},{name:"LineToolCallout"},{name:"LineToolComment"},{name:"LineToolPriceLabel"},{name:"LineToolSignpost"},{name:"LineToolFlagMark"}].filter(r.isExistent)},{title:t.t(null,void 0,l(93111)),items:[s?{name:"LineToolImage"}:null,null,null].filter(r.isExistent)}],trackLabel:null}]
|
||||
;function h(e){return"sections"in e}function d(e){return"name"in e}function m(e){return"type"in e}function u(e){return m(e)&&"switcher"===e.type}const g=v.map((function(e){return h(e)?e.sections.map((e=>e.items.filter(d))).flat():e.items.filter(d)})).flat()},18117:(e,o,l)=>{"use strict";l.d(o,{lineToolsInfo:()=>f});var t=l(50151),i=l(11542),n=l(61814),a=(l(40167),l(44341)),r=l(70173);const s={SyncDrawing:i.t(null,void 0,l(59377)),arrow:i.t(null,void 0,l(11858)),cursor:i.t(null,void 0,l(6969)),demonstration:i.t(null,void 0,l(14939)),dot:i.t(null,void 0,l(57157)),performance:i.t(null,void 0,l(35553)),drawginmode:i.t(null,void 0,l(99901)),eraser:i.t(null,void 0,l(8727)),group:i.t(null,void 0,l(3154)),hideAllDrawings:i.t(null,void 0,l(52563)),lockAllDrawings:i.t(null,void 0,l(79451)),magnet:i.t(null,void 0,l(81396)),measure:i.t(null,void 0,l(91563)),removeAllDrawingTools:i.t(null,void 0,l(57118)),showObjectsTree:i.t(null,void 0,l(85786)),zoom:i.t(null,void 0,l(55774)),"zoom-out":i.t(null,void 0,l(37310))};var c=l(56876),v=l(68335),h=l(81360);const d=(0,v.humanReadableModifiers)(v.Modifiers.Shift,!1).trim(),m=(0,v.humanReadableModifiers)(v.Modifiers.Alt,!1).trim(),u=(0,v.humanReadableModifiers)(v.Modifiers.Mod,!1).trim(),g={keys:[d],text:i.t(null,void 0,l(23369))},L={keys:[d],text:i.t(null,void 0,l(13798))},T={keys:[d],text:i.t(null,void 0,l(10539))},w={LineTool5PointsPattern:{},LineToolABCD:{},LineToolArc:{},LineToolArrow:{},LineToolArrowMarkDown:{},LineToolArrowMarkLeft:{},LineToolArrowMarkRight:{},LineToolArrowMarkUp:{},LineToolComment:{},LineToolBarsPattern:{},LineToolBezierCubic:{},LineToolBezierQuadro:{},LineToolBrush:{},LineToolCallout:{},LineToolCircleLines:{},LineToolCypherPattern:{},LineToolDateAndPriceRange:{},LineToolDateRange:{},LineToolDisjointAngle:{hotKey:(0,n.hotKeySerialize)(g)},LineToolElliottCorrection:{},LineToolElliottDoubleCombo:{},LineToolElliottImpulse:{},LineToolElliottTriangle:{},LineToolElliottTripleCombo:{},LineToolEllipse:{hotKey:(0,n.hotKeySerialize)(L)},LineToolExtended:{},LineToolFibChannel:{},LineToolFibCircles:{hotKey:(0,n.hotKeySerialize)(L)},LineToolFibRetracement:{},LineToolFibSpeedResistanceArcs:{},LineToolFibSpeedResistanceFan:{hotKey:(0,n.hotKeySerialize)(T)},LineToolFibSpiral:{},LineToolFibTimeZone:{},LineToolFibWedge:{},LineToolFlagMark:{},LineToolFlatBottom:{hotKey:(0,n.hotKeySerialize)(g)},LineToolAnchoredVWAP:{},LineToolGannComplex:{},LineToolGannFixed:{},LineToolGannFan:{},LineToolGannSquare:{hotKey:(0,n.hotKeySerialize)({keys:[d],text:i.t(null,void 0,l(83042))})},LineToolHeadAndShoulders:{},LineToolHorzLine:{hotKey:(0,n.hotKeySerialize)({keys:[m,"H"],text:"{0} + {1}"})},LineToolHorzRay:{},LineToolIcon:{},LineToolImage:{},LineToolEmoji:{},LineToolSticker:{},LineToolInsidePitchfork:{},LineToolNote:{},LineToolSignpost:{},LineToolParallelChannel:{hotKey:(0,n.hotKeySerialize)(g)},LineToolPitchfan:{},LineToolPitchfork:{},LineToolPolyline:{},LineToolPath:{},LineToolPrediction:{},LineToolPriceLabel:{},LineToolPriceNote:{hotKey:(0,n.hotKeySerialize)(g)},LineToolTextNote:{},
|
||||
LineToolArrowMarker:{},LineToolPriceRange:{},LineToolProjection:{},LineToolRay:{},LineToolRectangle:{hotKey:(0,n.hotKeySerialize)({keys:[d],text:i.t(null,void 0,l(10539))})},LineToolCircle:{},LineToolRegressionTrend:{},LineToolRiskRewardLong:{},LineToolRiskRewardShort:{},LineToolFixedRangeVolumeProfile:{},LineToolRotatedRectangle:{hotKey:(0,n.hotKeySerialize)(g)},LineToolSchiffPitchfork:{},LineToolSchiffPitchfork2:{},LineToolSineLine:{},LineToolText:{},LineToolTextAbsolute:{},LineToolThreeDrivers:{},LineToolTimeCycles:{},LineToolTrendAngle:{hotKey:(0,n.hotKeySerialize)(g)},LineToolTrendBasedFibExtension:{},LineToolTrendBasedFibTime:{},LineToolTrendLine:{hotKey:(0,n.hotKeySerialize)(g)},LineToolInfoLine:{},LineToolTriangle:{},LineToolTrianglePattern:{},LineToolVertLine:{hotKey:(0,n.hotKeySerialize)({keys:[m,"V"],text:"{0} + {1}"})},LineToolCrossLine:{},LineToolHighlighter:{},LineToolGhostFeed:{},LineToolTable:{},SyncDrawing:{iconActive:r.drawingToolsIcons.SyncDrawingActive},arrow:{},cursor:{},dot:{},demonstration:{hotKey:(0,n.hotKeySerialize)({keys:[m],text:i.t(null,void 0,l(42633))})},drawginmode:{iconActive:r.drawingToolsIcons.drawginmodeActive},eraser:{},group:{},hideAllDrawings:{iconActive:r.drawingToolsIcons.hideAllDrawingsActive,hotKey:(0,n.hotKeySerialize)({keys:[u,m,"H"],text:"{0} + {1} + {2}"})},lockAllDrawings:{iconActive:r.drawingToolsIcons.lockAllDrawingsActive},magnet:{hotKey:(0,n.hotKeySerialize)({keys:[u],text:"{0}"})},measure:{hotKey:(0,n.hotKeySerialize)({keys:[d],text:i.t(null,void 0,l(92949))})},removeAllDrawingTools:{},showObjectsTree:{},zoom:{},"zoom-out":{}};const f={};Object.entries(w).map((([e,o])=>{const l=a.lineToolsIcons[e]??r.drawingToolsIcons[e];(0,t.assert)(!!l,`Icon is not defined for drawing "${e}"`);const i=c.lineToolsLocalizedNames[e]??s[e];(0,t.assert)(!!i,`Localized name is not defined for drawing "${e}"`);return{...o,name:e,icon:l,localizedName:i,selectHotkey:h.lineToolsSelectHotkeys[e]}})).forEach((e=>{f[e.name]=e}))},6519:(e,o,l)=>{"use strict";l.d(o,{LinetoolsFavoritesStore:()=>c});var t=l(48096),i=l(87465),n=l(1765);const a=["LineToolBalloon","LineToolNoteAbsolute",null,null].filter(i.isExistent),r=!1;var s,c;!function(e){function o(){e.favorites=[];let o=!1;const t=Boolean(void 0===(0,n.getValue)("chart.favoriteDrawings")),s=(0,n.getJSON)("chart.favoriteDrawings",[]);if(0===s.length&&t&&"undefined"!=typeof window){const e=JSON.parse(window.urlParams?.favorites??"{}").drawingTools;e&&Array.isArray(e)&&s.push(...e)}s.forEach(((t,i)=>{const n=t.tool||t;l(n)?a.includes(n)?o=!0:e.favorites.push(n):r&&r.includes(n)&&e.hiddenToolsPositions.set(n,i)})),o&&i(),e.favoritesSynced.fire()}function l(e){return"string"==typeof e&&""!==e&&!(r&&r.includes(e))}function i(o){const l=e.favorites.slice();e.hiddenToolsPositions.forEach(((e,o)=>{l.splice(e,0,o)})),(0,n.setJSON)("chart.favoriteDrawings",l,o)}e.favorites=[],e.favoritesSynced=new t.Delegate,e.hiddenToolsPositions=new Map,e.favoriteIndex=function(o){return e.favorites.indexOf(o)},e.isValidLineToolName=l,e.saveFavorites=i,o(),
|
||||
n.onSync.subscribe(null,o)}(s||(s={})),function(e){function o(e){return s.isValidLineToolName(e)}function l(){return s.favorites.length}function i(e){return-1!==s.favoriteIndex(e)}e.favoriteAdded=new t.Delegate,e.favoriteRemoved=new t.Delegate,e.favoriteMoved=new t.Delegate,e.favoritesSynced=s.favoritesSynced,e.favorites=function(){return s.favorites.slice()},e.isValidLineToolName=o,e.favoritesCount=l,e.favorite=function(e){return e<0||e>=l()?"":s.favorites[e]},e.addFavorite=function(l,t){return!(i(l)||!o(l)||"performance"===l)&&(s.favorites.push(l),s.saveFavorites(t),e.favoriteAdded.fire(l),!0)},e.removeFavorite=function(o,l){const t=s.favoriteIndex(o);if(-1===t)return!1;s.favorites.splice(t,1);const i=s.hiddenToolsPositions;return i.forEach(((e,o)=>{e>t&&i.set(o,e-1)})),s.saveFavorites(l),e.favoriteRemoved.fire(o),!0},e.isFavorite=i,e.moveFavorite=function(t,i,n){if(i<0||i>=l()||!o(t))return!1;const a=s.favoriteIndex(t);if(-1===a||i===a)return!1;const r=s.hiddenToolsPositions;return r.forEach(((e,o)=>{a<e&&i>e?e--:i<e&&a>e&&e++,r.set(o,e)})),s.favorites.splice(a,1),s.favorites.splice(i,0,t),s.saveFavorites(n),e.favoriteMoved.fire(t,a,i),!0}}(c||(c={}))},54780:e=>{e.exports='<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 28 28" width="28" height="28" fill="currentColor"><path d="m11.26 21 3.65-4.78 6.09-.66L10 8zm3.09-5.71-2.33 3.05-.8-8.3 7.02 4.82z"/><path fill-rule="evenodd" d="M25 14a11 11 0 1 1-22 0 11 11 0 0 1 22 0m-1 0a10 10 0 1 1-20 0 10 10 0 0 1 20 0"/></svg>'},52459:e=>{e.exports='<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 28 28" width="28" height="28"><path fill="currentColor" d="M17.27 4.56a2.5 2.5 0 0 0-3.54 0l-.58.59-9 9-1 1-.15.14V20h4.7l.15-.15 1-1 9-9 .59-.58a2.5 2.5 0 0 0 0-3.54l-1.17-1.17Zm-2.83.7a1.5 1.5 0 0 1 2.12 0l1.17 1.18a1.5 1.5 0 0 1 0 2.12l-.23.23-3.3-3.29.24-.23Zm-.94.95 3.3 3.29-8.3 8.3-3.3-3.3 8.3-8.3Zm-9 9 3.3 3.29-.5.5H4v-3.3l.5-.5Zm16.5.29a1.5 1.5 0 0 0-3 0V18h4.5c.83 0 1.5.67 1.5 1.5v4c0 .83-.67 1.5-1.5 1.5h-6a1.5 1.5 0 0 1-1.5-1.5v-4c0-.83.67-1.5 1.5-1.5h.5v-2.5a2.5 2.5 0 0 1 5 0v.5h-1v-.5ZM16.5 19a.5.5 0 0 0-.5.5v4c0 .28.22.5.5.5h6a.5.5 0 0 0 .5-.5v-4a.5.5 0 0 0-.5-.5h-6Zm2.5 4v-2h1v2h-1Z"/></svg>'},63975:e=>{e.exports='<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 28 28" width="28" height="28"><path fill="currentColor" d="M17.27 4.56a2.5 2.5 0 0 0-3.54 0l-.58.59-9 9-1 1-.15.14V20h4.7l.15-.15 1-1 9-9 .59-.58a2.5 2.5 0 0 0 0-3.54l-1.17-1.17Zm-2.83.7a1.5 1.5 0 0 1 2.12 0l1.17 1.18a1.5 1.5 0 0 1 0 2.12l-.23.23-3.3-3.29.24-.23Zm-.94.95 3.3 3.29-8.3 8.3-3.3-3.3 8.3-8.3Zm-9 9 3.3 3.29-.5.5H4v-3.3l.5-.5Zm16.5.29a1.5 1.5 0 0 0-3 0V18h3v-2.5Zm1 0V18h.5c.83 0 1.5.67 1.5 1.5v4c0 .83-.67 1.5-1.5 1.5h-6a1.5 1.5 0 0 1-1.5-1.5v-4c0-.83.67-1.5 1.5-1.5h.5v-2.5a2.5 2.5 0 0 1 5 0ZM16.5 19a.5.5 0 0 0-.5.5v4c0 .28.22.5.5.5h6a.5.5 0 0 0 .5-.5v-4a.5.5 0 0 0-.5-.5h-6Zm2.5 4v-2h1v2h-1Z"/></svg>'},34059:e=>{
|
||||
e.exports='<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 30 30" width="30" height="30"><path fill="currentColor" d="M5.5 13A2.5 2.5 0 0 0 3 15.5 2.5 2.5 0 0 0 5.5 18 2.5 2.5 0 0 0 8 15.5 2.5 2.5 0 0 0 5.5 13zm9.5 0a2.5 2.5 0 0 0-2.5 2.5A2.5 2.5 0 0 0 15 18a2.5 2.5 0 0 0 2.5-2.5A2.5 2.5 0 0 0 15 13zm9.5 0a2.5 2.5 0 0 0-2.5 2.5 2.5 2.5 0 0 0 2.5 2.5 2.5 2.5 0 0 0 2.5-2.5 2.5 2.5 0 0 0-2.5-2.5z"/></svg>'},63743:e=>{e.exports='<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 28 28" width="28" height="28"><path fill="currentColor" d="M11.682 16.09l3.504 6.068 1.732-1-3.497-6.057 3.595-2.1L8 7.74v10.512l3.682-2.163zm-.362 1.372L7 20V6l12 7-4.216 2.462 3.5 6.062-3.464 2-3.5-6.062z"/></svg>'},18953:e=>{e.exports='<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 28 28" width="28" height="28"><g fill="currentColor"><path d="M18 15h8v-1h-8z"/><path d="M14 18v8h1v-8zM14 3v8h1v-8zM3 15h8v-1h-8z"/></g></svg>'},72196:e=>{e.exports='<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 28 28" width="28" height="28"><circle fill="currentColor" cx="14" cy="14" r="3"/></svg>'},27999:e=>{e.exports='<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 29 31" width="29" height="31"><g fill="currentColor" fill-rule="nonzero"><path d="M15.3 22l8.187-8.187c.394-.394.395-1.028.004-1.418l-4.243-4.243c-.394-.394-1.019-.395-1.407-.006l-11.325 11.325c-.383.383-.383 1.018.007 1.407l1.121 1.121h7.656zm-9.484-.414c-.781-.781-.779-2.049-.007-2.821l11.325-11.325c.777-.777 2.035-.78 2.821.006l4.243 4.243c.781.781.78 2.048-.004 2.832l-8.48 8.48h-8.484l-1.414-1.414z"/><path d="M13.011 22.999h7.999v-1h-7.999zM13.501 11.294l6.717 6.717.707-.707-6.717-6.717z"/></g></svg>'},10862:e=>{e.exports='<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 28 28" width="28" height="28"><path fill="currentColor" fill-rule="evenodd" d="M24.13 14.65a6.2 6.2 0 0 0-.46-9.28c-2.57-2.09-6.39-1.71-8.75.6l-.92.91-.92-.9c-2.36-2.32-6.18-2.7-8.75-.61a6.2 6.2 0 0 0-.46 9.28l9.07 8.92c.58.57 1.53.57 2.12 0l9.07-8.92Zm-9.77 8.2 9.07-8.91a5.2 5.2 0 0 0-.39-7.8c-2.13-1.73-5.38-1.45-7.42.55L14 8.29l-1.62-1.6c-2.03-2-5.29-2.28-7.42-.55a5.2 5.2 0 0 0-.4 7.8l9.08 8.91c.2.2.52.2.72 0Z"/></svg>'},68385:e=>{e.exports='<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 28 28" width="28" height="28"><g fill="currentColor" fill-rule="evenodd"><path fill-rule="nonzero" d="M14 10a2 2 0 0 0-2 2v11H6V12c0-4.416 3.584-8 8-8s8 3.584 8 8v11h-6V12a2 2 0 0 0-2-2zm-3 2a3 3 0 0 1 6 0v10h4V12c0-3.864-3.136-7-7-7s-7 3.136-7 7v10h4V12z"/><path d="M6.5 18h5v1h-5zm10 0h5v1h-5z"/></g></svg>'},88518:e=>{e.exports='<svg xmlns="http://www.w3.org/2000/svg" width="28" height="28"><path fill="currentColor" d="M2 9.75a1.5 1.5 0 0 0-1.5 1.5v5.5a1.5 1.5 0 0 0 1.5 1.5h24a1.5 1.5 0 0 0 1.5-1.5v-5.5a1.5 1.5 0 0 0-1.5-1.5zm0 1h3v2.5h1v-2.5h3.25v3.9h1v-3.9h3.25v2.5h1v-2.5h3.25v3.9h1v-3.9H22v2.5h1v-2.5h3a.5.5 0 0 1 .5.5v5.5a.5.5 0 0 1-.5.5H2a.5.5 0 0 1-.5-.5v-5.5a.5.5 0 0 1 .5-.5z" transform="rotate(-45 14 14)"/></svg>'},36515:e=>{
|
||||
e.exports='<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 28 28" width="28" height="28"><g fill="currentColor"><path fill-rule="nonzero" d="M14 18.634l-.307-.239-7.37-5.73-2.137-1.665 9.814-7.633 9.816 7.634-.509.394-1.639 1.269-7.667 5.969zm7.054-6.759l1.131-.876-8.184-6.366-8.186 6.367 1.123.875 7.063 5.491 7.054-5.492z"/><path d="M7 14.5l-1 .57 8 6.43 8-6.5-1-.5-7 5.5z"/><path d="M7 17.5l-1 .57 8 6.43 8-6.5-1-.5-7 5.5z"/></g></svg>'},7636:e=>{e.exports='<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 28 28" width="28" height="28"><path fill="currentColor" d="M4.05 14a9.95 9.95 0 1 1 19.9 0 9.95 9.95 0 0 1-19.9 0ZM14 3a11 11 0 1 0 0 22 11 11 0 0 0 0-22Zm-3 13.03a.5.5 0 0 1 .64.3 2.5 2.5 0 0 0 4.72 0 .5.5 0 0 1 .94.34 3.5 3.5 0 0 1-6.6 0 .5.5 0 0 1 .3-.64Zm.5-4.53a1 1 0 1 0 0 2 1 1 0 0 0 0-2Zm5 0a1 1 0 1 0 0 2 1 1 0 0 0 0-2Z"/></svg>'},62567:e=>{e.exports='<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 28 28" width="28" height="28"><path fill="currentColor" fill-rule="evenodd" d="M7 4h14a3 3 0 0 1 3 3v11c0 .34-.03.67-.08 1H20.3c-1.28 0-2.31.97-2.31 2.24V24H7a3 3 0 0 1-3-3V7a3 3 0 0 1 3-3Zm12 19.92A6 6 0 0 0 23.66 20H20.3c-.77 0-1.31.48-1.31 1.24v2.68ZM3 7a4 4 0 0 1 4-4h14a4 4 0 0 1 4 4v11a7 7 0 0 1-7 7H7a4 4 0 0 1-4-4V7Zm8 9.03a.5.5 0 0 1 .64.3 2.5 2.5 0 0 0 4.72 0 .5.5 0 0 1 .94.34 3.5 3.5 0 0 1-6.6 0 .5.5 0 0 1 .3-.64Zm.5-4.53a1 1 0 1 0 0 2 1 1 0 0 0 0-2Zm5 0a1 1 0 1 0 0 2 1 1 0 0 0 0-2Z"/></svg>'},46049:e=>{e.exports='<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 28 28" width="28" height="28"><path fill="currentColor" fill-rule="nonzero" d="M14 5a7 7 0 0 0-7 7v3h4v-3a3 3 0 1 1 6 0v3h4v-3a7 7 0 0 0-7-7zm7 11h-4v3h4v-3zm-10 0H7v3h4v-3zm-5-4a8 8 0 1 1 16 0v8h-6v-8a2 2 0 1 0-4 0v8H6v-8zm3.293 11.294l-1.222-2.037.858-.514 1.777 2.963-2 1 1.223 2.037-.858.514-1.778-2.963 2-1zm9.778-2.551l.858.514-1.223 2.037 2 1-1.777 2.963-.858-.514 1.223-2.037-2-1 1.777-2.963z"/></svg>'},99088:e=>{e.exports='<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 28 28" width="28" height="28"><g fill="currentColor"><path fill-rule="nonzero" d="M15.039 5.969l-.019-.019-2.828 2.828.707.707 2.474-2.474c1.367-1.367 3.582-1.367 4.949 0s1.367 3.582 0 4.949l-2.474 2.474.707.707 2.828-2.828-.019-.019c1.415-1.767 1.304-4.352-.334-5.99-1.638-1.638-4.224-1.749-5.99-.334zM5.97 15.038l-.019-.019 2.828-2.828.707.707-2.475 2.475c-1.367 1.367-1.367 3.582 0 4.949s3.582 1.367 4.949 0l2.474-2.474.707.707-2.828 2.828-.019-.019c-1.767 1.415-4.352 1.304-5.99-.334-1.638-1.638-1.749-4.224-.334-5.99z"/><path d="M10.485 16.141l5.656-5.656.707.707-5.656 5.656z"/></g></svg>'},42650:e=>{
|
||||
e.exports='<svg xmlns="http://www.w3.org/2000/svg" width="28" height="28"><path fill="currentColor" fill-rule="evenodd" d="M19.76 6.07l-.7.7a13.4 13.4 0 011.93 2.47c.19.3.33.55.42.72l.03.04-.03.04a15 15 0 01-2.09 2.9c-1.47 1.6-3.6 3.12-6.32 3.12-.98 0-1.88-.2-2.7-.52l-.77.76c1.03.47 2.18.76 3.47.76 3.12 0 5.5-1.75 7.06-3.44a16 16 0 002.38-3.38v-.02h.01L22 10l.45.22.1-.22-.1-.22L22 10l.45-.22-.01-.02a5.1 5.1 0 00-.15-.28 16 16 0 00-2.53-3.41zM6.24 13.93l.7-.7-.27-.29a15 15 0 01-2.08-2.9L4.56 10l.03-.04a15 15 0 012.09-2.9c1.47-1.6 3.6-3.12 6.32-3.12.98 0 1.88.2 2.7.52l.77-.76A8.32 8.32 0 0013 2.94c-3.12 0-5.5 1.75-7.06 3.44a16 16 0 00-2.38 3.38v.02h-.01L4 10l-.45-.22-.1.22.1.22L4 10l-.45.22.01.02a5.5 5.5 0 00.15.28 16 16 0 002.53 3.41zm6.09-.43a3.6 3.6 0 004.24-4.24l-.93.93a2.6 2.6 0 01-2.36 2.36l-.95.95zm-1.97-3.69l-.93.93a3.6 3.6 0 014.24-4.24l-.95.95a2.6 2.6 0 00-2.36 2.36zm11.29 7.84l-.8.79a1.5 1.5 0 000 2.12l.59.59a1.5 1.5 0 002.12 0l1.8-1.8-.71-.7-1.8 1.79a.5.5 0 01-.7 0l-.59-.59a.5.5 0 010-.7l.8-.8-.71-.7zm-5.5 3.5l.35.35-.35-.35.01-.02.02-.02.02-.02a4.68 4.68 0 01.65-.5c.4-.27 1-.59 1.65-.59.66 0 1.28.33 1.73.77.44.45.77 1.07.77 1.73a2.5 2.5 0 01-.77 1.73 2.5 2.5 0 01-1.73.77h-4a.5.5 0 01-.42-.78l1-1.5 1-1.5a.5.5 0 01.07-.07zm.74.67a3.46 3.46 0 01.51-.4c.35-.24.75-.42 1.1-.42.34 0 .72.17 1.02.48.3.3.48.68.48 1.02 0 .34-.17.72-.48 1.02-.3.3-.68.48-1.02.48h-3.07l.49-.72.97-1.46zM21.2 2.5L5.5 18.2l-.7-.7L20.5 1.8l.7.7z"/></svg>'},75895:e=>{e.exports='<svg xmlns="http://www.w3.org/2000/svg" width="28" height="28"><path fill="currentColor" d="M16.47 3.7A8.32 8.32 0 0013 2.94c-3.12 0-5.5 1.75-7.06 3.44a16 16 0 00-2.38 3.38v.02h-.01L4 10l-.45-.22-.1.22.1.22L4 10l-.45.22.01.02a5.5 5.5 0 00.15.28 16 16 0 002.53 3.41l.7-.7-.27-.29a15 15 0 01-2.08-2.9L4.56 10l.03-.04a15 15 0 012.09-2.9c1.47-1.6 3.6-3.12 6.32-3.12.98 0 1.88.2 2.7.52l.77-.76zm-7.04 7.04l.93-.93a2.6 2.6 0 012.36-2.36l.95-.95a3.6 3.6 0 00-4.24 4.24zm.1 5.56c1.03.47 2.18.76 3.47.76 3.12 0 5.5-1.75 7.06-3.44a16 16 0 002.38-3.38v-.02h.01L22 10l.45.22.1-.22-.1-.22L22 10l.45-.22-.01-.02-.02-.03-.01-.03a9.5 9.5 0 00-.57-1 16 16 0 00-2.08-2.63l-.7.7.27.29a15.01 15.01 0 012.08 2.9l.03.04-.03.04a15 15 0 01-2.09 2.9c-1.47 1.6-3.6 3.12-6.32 3.12-.98 0-1.88-.2-2.7-.52l-.77.76zm2.8-2.8a3.6 3.6 0 004.24-4.24l-.93.93a2.6 2.6 0 01-2.36 2.36l-.95.95zm7.9 3.73c-.12.12-.23.35-.23.77v2h1v1h-1v2c0 .58-.14 1.1-.52 1.48-.38.38-.9.52-1.48.52s-1.1-.14-1.48-.52c-.38-.38-.52-.9-.52-1.48h1c0 .42.1.65.23.77.12.12.35.23.77.23.42 0 .65-.1.77-.23.12-.12.23-.35.23-.77v-2h-1v-1h1v-2c0-.58.14-1.1.52-1.48.38-.38.9-.52 1.48-.52s1.1.14 1.48.52c.38.38.52.9.52 1.48h-1c0-.42-.1-.65-.23-.77-.12-.12-.35-.23-.77-.23-.42 0-.65.1-.77.23zm2.56 6.27l-1.14-1.15.7-.7 1.15 1.14 1.15-1.14.7.7-1.14 1.15 1.14 1.15-.7.7-1.15-1.14-1.15 1.14-.7-.7 1.14-1.15zM21.2 2.5L5.5 18.2l-.7-.7L20.5 1.8l.7.7z"/></svg>'},65162:e=>{
|
||||
e.exports='<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 28 28" width="28" height="28"><path fill="currentColor" d="M5.5 18.2L21.2 2.5l-.7-.7L4.8 17.5l.7.7zM19.05 6.78l.71-.7a14.26 14.26 0 0 1 2.08 2.64 14.26 14.26 0 0 1 .6 1.05v.02h.01L22 10l.45.22-.01.02a5.18 5.18 0 0 1-.15.28 16 16 0 0 1-2.23 3.1c-1.56 1.69-3.94 3.44-7.06 3.44-1.29 0-2.44-.3-3.47-.76l.76-.76c.83.32 1.73.52 2.71.52 2.73 0 4.85-1.53 6.33-3.12a15.01 15.01 0 0 0 2.08-2.9l.03-.04-.03-.04a15 15 0 0 0-2.36-3.18zM22 10l.45-.22.1.22-.1.22L22 10zM6.94 13.23l-.7.7a14.24 14.24 0 0 1-2.08-2.64 14.28 14.28 0 0 1-.6-1.05v-.02h-.01L4 10l-.45-.22.01-.02a5.55 5.55 0 0 1 .15-.28 16 16 0 0 1 2.23-3.1C7.5 4.69 9.88 2.94 13 2.94c1.29 0 2.44.3 3.47.76l-.76.76A7.27 7.27 0 0 0 13 3.94c-2.73 0-4.85 1.53-6.33 3.12a15 15 0 0 0-2.08 2.9l-.03.04.03.04a15.01 15.01 0 0 0 2.36 3.18zM4 10l-.45.22-.1-.22.1-.22L4 10zm9 3.56c-.23 0-.46-.02-.67-.06l.95-.95a2.6 2.6 0 0 0 2.36-2.36l.93-.93a3.6 3.6 0 0 1-3.57 4.3zm-3.57-2.82l.93-.93a2.6 2.6 0 0 1 2.36-2.36l.95-.95a3.6 3.6 0 0 0-4.24 4.24zM17.5 21.9l3.28 2.18a.5.5 0 1 1-.56.84L17.5 23.1l-2.72 1.82a.5.5 0 1 1-.56-.84l3.28-2.18zM18.58 19.22a.5.5 0 0 1 .7-.14L22 20.9l2.72-1.82a.5.5 0 0 1 .56.84L22 22.1l-3.28-2.18a.5.5 0 0 1-.14-.7z"/></svg>'},65186:e=>{e.exports='<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 28 28" width="28" height="28"><path fill="currentColor" fill-rule="evenodd" d="M14 6a3 3 0 0 0-3 3v3h6V9a3 3 0 0 0-3-3zm4 6V9a4 4 0 0 0-8 0v3H8.5A2.5 2.5 0 0 0 6 14.5v7A2.5 2.5 0 0 0 8.5 24h11a2.5 2.5 0 0 0 2.5-2.5v-7a2.5 2.5 0 0 0-2.5-2.5H18zm-5 5a1 1 0 1 1 2 0v2a1 1 0 1 1-2 0v-2zm-6-2.5c0-.83.67-1.5 1.5-1.5h11c.83 0 1.5.67 1.5 1.5v7c0 .83-.67 1.5-1.5 1.5h-11A1.5 1.5 0 0 1 7 21.5v-7z"/></svg>'},91244:e=>{e.exports='<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 28 28" width="28" height="28"><path fill="currentColor" fill-rule="evenodd" d="M14 6a3 3 0 0 0-3 3v3h8.5a2.5 2.5 0 0 1 2.5 2.5v7a2.5 2.5 0 0 1-2.5 2.5h-11A2.5 2.5 0 0 1 6 21.5v-7A2.5 2.5 0 0 1 8.5 12H10V9a4 4 0 0 1 8 0h-1a3 3 0 0 0-3-3zm-1 11a1 1 0 1 1 2 0v2a1 1 0 1 1-2 0v-2zm-6-2.5c0-.83.67-1.5 1.5-1.5h11c.83 0 1.5.67 1.5 1.5v7c0 .83-.67 1.5-1.5 1.5h-11A1.5 1.5 0 0 1 7 21.5v-7z"/></svg>'},45820:e=>{e.exports='<svg xmlns="http://www.w3.org/2000/svg" width="28" height="28"><path fill="currentColor" fill-rule="evenodd" d="M4.56 14a10.05 10.05 0 00.52.91c.41.69 1.04 1.6 1.85 2.5C8.58 19.25 10.95 21 14 21c3.05 0 5.42-1.76 7.07-3.58A17.18 17.18 0 0023.44 14a9.47 9.47 0 00-.52-.91c-.41-.69-1.04-1.6-1.85-2.5C19.42 8.75 17.05 7 14 7c-3.05 0-5.42 1.76-7.07 3.58A17.18 17.18 0 004.56 14zM24 14l.45-.21-.01-.03a7.03 7.03 0 00-.16-.32c-.11-.2-.28-.51-.5-.87-.44-.72-1.1-1.69-1.97-2.65C20.08 7.99 17.45 6 14 6c-3.45 0-6.08 2-7.8 3.92a18.18 18.18 0 00-2.64 3.84v.02h-.01L4 14l-.45-.21-.1.21.1.21L4 14l-.45.21.01.03a5.85 5.85 0 00.16.32c.11.2.28.51.5.87.44.72 1.1 1.69 1.97 2.65C7.92 20.01 10.55 22 14 22c3.45 0 6.08-2 7.8-3.92a18.18 18.18 0 002.64-3.84v-.02h.01L24 14zm0 0l.45.21.1-.21-.1-.21L24 14zm-10-3a3 3 0 100 6 3 3 0 000-6zm-4 3a4 4 0 118 0 4 4 0 01-8 0z"/></svg>'},93756:e=>{
|
||||
e.exports='<svg xmlns="http://www.w3.org/2000/svg" width="28" height="28"><path fill="currentColor" fill-rule="evenodd" d="M5 10.76l-.41-.72-.03-.04.03-.04a15 15 0 012.09-2.9c1.47-1.6 3.6-3.12 6.32-3.12 2.73 0 4.85 1.53 6.33 3.12a15.01 15.01 0 012.08 2.9l.03.04-.03.04a15 15 0 01-2.09 2.9c-1.47 1.6-3.6 3.12-6.32 3.12-2.73 0-4.85-1.53-6.33-3.12a15 15 0 01-1.66-2.18zm17.45-.98L22 10l.45.22-.01.02a5.04 5.04 0 01-.15.28 16.01 16.01 0 01-2.23 3.1c-1.56 1.69-3.94 3.44-7.06 3.44-3.12 0-5.5-1.75-7.06-3.44a16 16 0 01-2.38-3.38v-.02h-.01L4 10l-.45-.22.01-.02a5.4 5.4 0 01.15-.28 16 16 0 012.23-3.1C7.5 4.69 9.88 2.94 13 2.94c3.12 0 5.5 1.75 7.06 3.44a16.01 16.01 0 012.38 3.38v.02h.01zM22 10l.45-.22.1.22-.1.22L22 10zM3.55 9.78L4 10l-.45.22-.1-.22.1-.22zm6.8.22A2.6 2.6 0 0113 7.44 2.6 2.6 0 0115.65 10 2.6 2.6 0 0113 12.56 2.6 2.6 0 0110.35 10zM13 6.44A3.6 3.6 0 009.35 10 3.6 3.6 0 0013 13.56c2 0 3.65-1.58 3.65-3.56A3.6 3.6 0 0013 6.44zm7.85 12l.8-.8.7.71-.79.8a.5.5 0 000 .7l.59.59c.2.2.5.2.7 0l1.8-1.8.7.71-1.79 1.8a1.5 1.5 0 01-2.12 0l-.59-.59a1.5 1.5 0 010-2.12zM16.5 21.5l-.35-.35a.5.5 0 00-.07.07l-1 1.5-1 1.5a.5.5 0 00.42.78h4a2.5 2.5 0 001.73-.77A2.5 2.5 0 0021 22.5a2.5 2.5 0 00-.77-1.73A2.5 2.5 0 0018.5 20a3.1 3.1 0 00-1.65.58 5.28 5.28 0 00-.69.55v.01h-.01l.35.36zm.39.32l-.97 1.46-.49.72h3.07c.34 0 .72-.17 1.02-.48.3-.3.48-.68.48-1.02 0-.34-.17-.72-.48-1.02-.3-.3-.68-.48-1.02-.48-.35 0-.75.18-1.1.42a4.27 4.27 0 00-.51.4z"/></svg>'},42321:e=>{e.exports='<svg xmlns="http://www.w3.org/2000/svg" width="28" height="28"><path fill="currentColor" fill-rule="evenodd" d="M5 10.76a13.27 13.27 0 01-.41-.72L4.56 10l.03-.04a15 15 0 012.08-2.9c1.48-1.6 3.6-3.12 6.33-3.12s4.85 1.53 6.33 3.12a15.01 15.01 0 012.08 2.9l.03.04-.03.04a15 15 0 01-2.08 2.9c-1.48 1.6-3.6 3.12-6.33 3.12s-4.85-1.53-6.33-3.12a15 15 0 01-1.66-2.18zm17.45-.98L22 10l.45.22-.01.02a14.3 14.3 0 01-.6 1.05c-.4.64-1 1.48-1.78 2.33-1.56 1.7-3.94 3.44-7.06 3.44s-5.5-1.75-7.06-3.44a16 16 0 01-2.23-3.1 9.39 9.39 0 01-.15-.28v-.02h-.01L4 10l-.45-.22.01-.02a5.59 5.59 0 01.15-.28 16 16 0 012.23-3.1C7.5 4.69 9.87 2.94 13 2.94c3.12 0 5.5 1.75 7.06 3.44a16 16 0 012.23 3.1 9.5 9.5 0 01.15.28v.01l.01.01zM22 10l.45-.22.1.22-.1.22L22 10zM3.55 9.78L4 10l-.45.22-.1-.22.1-.22zm6.8.22A2.6 2.6 0 0113 7.44 2.6 2.6 0 0115.65 10 2.6 2.6 0 0113 12.56 2.6 2.6 0 0110.35 10zM13 6.44A3.6 3.6 0 009.35 10c0 1.98 1.65 3.56 3.65 3.56s3.65-1.58 3.65-3.56A3.6 3.6 0 0013 6.44zM20 18c0-.42.1-.65.23-.77.12-.13.35-.23.77-.23.42 0 .65.1.77.23.13.12.23.35.23.77h1c0-.58-.14-1.1-.52-1.48-.38-.38-.9-.52-1.48-.52s-1.1.14-1.48.52c-.37.38-.52.9-.52 1.48v2h-1v1h1v2c0 .42-.1.65-.23.77-.12.13-.35.23-.77.23-.42 0-.65-.1-.77-.23-.13-.12-.23-.35-.23-.77h-1c0 .58.14 1.1.52 1.48.38.37.9.52 1.48.52s1.1-.14 1.48-.52c.37-.38.52-.9.52-1.48v-2h1v-1h-1v-2zm1.65 4.35l1.14 1.15-1.14 1.15.7.7 1.15-1.14 1.15 1.14.7-.7-1.14-1.15 1.14-1.15-.7-.7-1.15 1.14-1.15-1.14-.7.7z"/></svg>'},57313:e=>{
|
||||
e.exports='<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 28 28" width="28" height="28"><path fill="currentColor" fill-rule="evenodd" d="M4.5 10a8.46 8.46 0 0 0 .46.8c.38.6.94 1.4 1.68 2.19 1.48 1.6 3.62 3.13 6.36 3.13s4.88-1.53 6.36-3.13A15.07 15.07 0 0 0 21.5 10a7.41 7.41 0 0 0-.46-.8c-.38-.6-.94-1.4-1.68-2.19-1.48-1.6-3.62-3.13-6.36-3.13S8.12 5.4 6.64 7A15.07 15.07 0 0 0 4.5 10zM22 10l.41-.19-.4.19zm0 0l.41.19-.4-.19zm.41.19l.09-.19-.09-.19-.01-.02a6.86 6.86 0 0 0-.15-.28c-.1-.18-.25-.45-.45-.76-.4-.64-.99-1.48-1.77-2.32C18.47 4.74 16.11 3 13 3 9.89 3 7.53 4.74 5.97 6.43A15.94 15.94 0 0 0 3.6 9.79v.02h-.01L3.5 10l.09.19.01.02a6.59 6.59 0 0 0 .15.28c.1.18.25.45.45.76.4.64.99 1.48 1.77 2.32C7.53 15.26 9.89 17 13 17c3.11 0 5.47-1.74 7.03-3.43a15.94 15.94 0 0 0 2.37-3.36v-.02h.01zM4 10l-.41-.19.4.19zm9-2.63c-1.5 0-2.7 1.18-2.7 2.63s1.2 2.63 2.7 2.63c1.5 0 2.7-1.18 2.7-2.63S14.5 7.37 13 7.37zM9.4 10C9.4 8.07 11 6.5 13 6.5s3.6 1.57 3.6 3.5S15 13.5 13 13.5A3.55 3.55 0 0 1 9.4 10zm8.1 11.9l3.28 2.18a.5.5 0 1 1-.56.84L17.5 23.1l-2.72 1.82a.5.5 0 1 1-.56-.84l3.28-2.18zm1.78-2.82a.5.5 0 0 0-.56.84L22 22.1l3.28-2.18a.5.5 0 1 0-.56-.84L22 20.9l-2.72-1.82z"/></svg>'},6894:e=>{e.exports='<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 28 28" width="28" height="28" fill="currentColor"><path d="M17.646 18.354l4 4 .708-.708-4-4z"/><path d="M12.5 21a8.5 8.5 0 1 1 0-17 8.5 8.5 0 0 1 0 17zm0-1a7.5 7.5 0 1 0 0-15 7.5 7.5 0 0 0 0 15z"/><path d="M9 13h7v-1H9z"/><path d="M13 16V9h-1v7z"/></svg>'},45360:e=>{e.exports='<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 28 28" width="28" height="28" fill="currentColor"><path d="M17.646 18.354l4 4 .708-.708-4-4z"/><path d="M12.5 21a8.5 8.5 0 1 1 0-17 8.5 8.5 0 0 1 0 17zm0-1a7.5 7.5 0 1 0 0-15 7.5 7.5 0 0 0 0 15z"/><path d="M9 13h7v-1H9z"/></svg>'},14665:e=>{e.exports='<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 10 16" width="10" height="16"><path d="M.6 1.4l1.4-1.4 8 8-8 8-1.4-1.4 6.389-6.532-6.389-6.668z"/></svg>'},39146:e=>{e.exports='<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 18 18" width="18" height="18" fill="none"><path fill="currentColor" d="M9 1l2.35 4.76 5.26.77-3.8 3.7.9 5.24L9 13l-4.7 2.47.9-5.23-3.8-3.71 5.25-.77L9 1z"/></svg>'},48010:e=>{e.exports='<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 18 18" width="18" height="18" fill="none"><path stroke="currentColor" d="M9 2.13l1.903 3.855.116.236.26.038 4.255.618-3.079 3.001-.188.184.044.259.727 4.237-3.805-2L9 12.434l-.233.122-3.805 2.001.727-4.237.044-.26-.188-.183-3.079-3.001 4.255-.618.26-.038.116-.236L9 2.13z"/></svg>'}}]);
|
||||
@@ -0,0 +1 @@
|
||||
[data-theme=dark],[data-theme=light]{--_0-6_wB:#0000}.button-iLKiGOdQ{align-items:center;background-color:var(--tv-list-item-button-background-color);border-radius:4px;color:var(--tv-color-popup-element-toolbox-text,var(--color-popup-element-toolbox-text));display:inline-flex;font-size:0;height:22px;justify-content:center;min-width:22px;width:22px}.button-iLKiGOdQ.hovered-iLKiGOdQ,.button-iLKiGOdQ:active{background-color:var(--tv-color-popup-element-toolbox-background-hover,var(--tv-list-item-button-background-hover-color,var(--color-container-fill-primary-neutral-normal)));color:var(--tv-color-popup-element-toolbox-text-hover,var(--color-popup-element-toolbox-text-hover))}@media (any-hover:hover){.button-iLKiGOdQ:hover{background-color:var(--tv-color-popup-element-toolbox-background-hover,var(--tv-list-item-button-background-hover-color,var(--color-container-fill-primary-neutral-normal)));color:var(--tv-color-popup-element-toolbox-text-hover,var(--color-popup-element-toolbox-text-hover))}}.button-iLKiGOdQ.disabled-iLKiGOdQ,.button-iLKiGOdQ.disabled-iLKiGOdQ:active{background-color:var(--tv-list-item-button-disabled-background-color,var(--_0-6_wB))}@media (any-hover:hover){.button-iLKiGOdQ.disabled-iLKiGOdQ:hover{background-color:var(--tv-list-item-button-disabled-background-color,var(--_0-6_wB))}}.button-iLKiGOdQ{outline:none;overflow:visible;position:relative}.button-iLKiGOdQ:focus{outline:none}.button-iLKiGOdQ:focus-visible{outline:none}.button-iLKiGOdQ:after{border-color:var(--color-focus-outline-color-blue);border-radius:4px;border-style:solid;border-width:2px;box-sizing:border-box;content:"";display:none;height:calc(100% + 4px);left:-2px;pointer-events:none;position:absolute;top:-2px;width:calc(100% + 4px);z-index:1}.button-iLKiGOdQ.focused-iLKiGOdQ:after{display:block}.button-iLKiGOdQ.active-iLKiGOdQ{color:var(--tv-color-popup-element-toolbox-text-active-hover,var(--color-content-secondary-inverse))}.button-iLKiGOdQ.active-iLKiGOdQ.hovered-iLKiGOdQ,.button-iLKiGOdQ.active-iLKiGOdQ:active{background-color:var(--tv-color-popup-element-toolbox-background-active-hover,var(--color-container-fill-primary-neutral-bold))}@media (any-hover:hover){.button-iLKiGOdQ.active-iLKiGOdQ:hover{background-color:var(--tv-color-popup-element-toolbox-background-active-hover,var(--color-container-fill-primary-neutral-bold))}}.hidden-iLKiGOdQ{visibility:hidden}
|
||||
@@ -0,0 +1 @@
|
||||
[data-theme=dark],[data-theme=light]{--_0-6_wB:#0000}.button-iLKiGOdQ{align-items:center;background-color:var(--tv-list-item-button-background-color);border-radius:4px;color:var(--tv-color-popup-element-toolbox-text,var(--color-popup-element-toolbox-text));display:inline-flex;font-size:0;height:22px;justify-content:center;min-width:22px;width:22px}.button-iLKiGOdQ.hovered-iLKiGOdQ,.button-iLKiGOdQ:active{background-color:var(--tv-color-popup-element-toolbox-background-hover,var(--tv-list-item-button-background-hover-color,var(--color-container-fill-primary-neutral-normal)));color:var(--tv-color-popup-element-toolbox-text-hover,var(--color-popup-element-toolbox-text-hover))}@media (any-hover:hover){.button-iLKiGOdQ:hover{background-color:var(--tv-color-popup-element-toolbox-background-hover,var(--tv-list-item-button-background-hover-color,var(--color-container-fill-primary-neutral-normal)));color:var(--tv-color-popup-element-toolbox-text-hover,var(--color-popup-element-toolbox-text-hover))}}.button-iLKiGOdQ.disabled-iLKiGOdQ,.button-iLKiGOdQ.disabled-iLKiGOdQ:active{background-color:var(--tv-list-item-button-disabled-background-color,var(--_0-6_wB))}@media (any-hover:hover){.button-iLKiGOdQ.disabled-iLKiGOdQ:hover{background-color:var(--tv-list-item-button-disabled-background-color,var(--_0-6_wB))}}.button-iLKiGOdQ{outline:none;overflow:visible;position:relative}.button-iLKiGOdQ:focus{outline:none}.button-iLKiGOdQ:focus-visible{outline:none}.button-iLKiGOdQ:after{border-color:var(--color-focus-outline-color-blue);border-radius:4px;border-style:solid;border-width:2px;box-sizing:border-box;content:"";display:none;height:calc(100% + 4px);pointer-events:none;position:absolute;right:-2px;top:-2px;width:calc(100% + 4px);z-index:1}.button-iLKiGOdQ.focused-iLKiGOdQ:after{display:block}.button-iLKiGOdQ.active-iLKiGOdQ{color:var(--tv-color-popup-element-toolbox-text-active-hover,var(--color-content-secondary-inverse))}.button-iLKiGOdQ.active-iLKiGOdQ.hovered-iLKiGOdQ,.button-iLKiGOdQ.active-iLKiGOdQ:active{background-color:var(--tv-color-popup-element-toolbox-background-active-hover,var(--color-container-fill-primary-neutral-bold))}@media (any-hover:hover){.button-iLKiGOdQ.active-iLKiGOdQ:hover{background-color:var(--tv-color-popup-element-toolbox-background-active-hover,var(--color-container-fill-primary-neutral-bold))}}.hidden-iLKiGOdQ{visibility:hidden}
|
||||
@@ -0,0 +1 @@
|
||||
[data-theme=light]{--_0-7Ghp:var(--color-cold-gray-900);--_1-7Ghp:var(--color-white);--_2-7Ghp:var(--color-cold-gray-900);--_3-7Ghp:var(--color-white);--_4-7Ghp:var(--color-cold-gray-150);--_5-7Ghp:var(--color-cold-gray-400);--_6-7Ghp:var(--color-tv-blue-a200);--_7-7Ghp:var(--color-cold-gray-100)}[data-theme=dark]{--_0-7Ghp:var(--color-cold-gray-200);--_1-7Ghp:var(--color-cold-gray-850);--_2-7Ghp:var(--color-cold-gray-200);--_3-7Ghp:var(--color-cold-gray-850);--_4-7Ghp:var(--color-cold-gray-700);--_5-7Ghp:var(--color-cold-gray-300);--_6-7Ghp:var(--color-tv-blue-a200);--_7-7Ghp:var(--color-cold-gray-100)}.wrapper-hPiAkrn3{box-sizing:border-box;display:flex;flex-direction:column;min-width:215px;padding-right:15px;position:relative}.timezone-hPiAkrn3{color:var(--color-default-gray);font-size:11px;line-height:18px;padding-top:4px;text-align:center;width:100%}.largePadding-hPiAkrn3{padding-top:8px}.sessionDayWrapper-hPiAkrn3{display:flex;flex-direction:column;position:relative}.nowWrapper-hPiAkrn3{bottom:0;left:30px;pointer-events:none;position:absolute;right:0;top:0}.nowWrapper-hPiAkrn3 .now-hPiAkrn3{backface-visibility:hidden;background-color:var(--_0-7Ghp);bottom:-1px;outline:1px var(--_1-7Ghp) solid;position:absolute;top:2px;width:1px}.sessionDay-hPiAkrn3{align-items:baseline;display:flex}.sessionDay-hPiAkrn3 .weekDay-hPiAkrn3{color:var(--color-default-gray);font-size:10px;overflow:hidden;padding-top:3px;text-transform:uppercase;width:30px}.sessionDay-hPiAkrn3 .sessionDaySegments-hPiAkrn3,.sessionDay-hPiAkrn3 .timeMarkWrapper-hPiAkrn3{flex:1;position:relative;width:100%}.sessionDay-hPiAkrn3 .timeMarkWrapper-hPiAkrn3{height:16px;margin-top:3px}.sessionDay-hPiAkrn3 .sessionDaySegments-hPiAkrn3{border-radius:4px;height:7px;margin:20px 0 2px}.sessionDay-hPiAkrn3:first-child .sessionDaySegments-hPiAkrn3{margin-top:0}.sessionDay-hPiAkrn3 .timeMarkSegment-hPiAkrn3{content:"";display:flex;justify-content:center;position:absolute}.sessionDay-hPiAkrn3 .timeMarkSegment-hPiAkrn3 .timeMark-hPiAkrn3:first-child{padding-right:4px}.sessionDay-hPiAkrn3 .timeMarkSegment-hPiAkrn3 .timeMark-hPiAkrn3:last-child{padding-left:4px}.sessionDay-hPiAkrn3 .timeMarkSegment-hPiAkrn3.timeMarkSegmentAlignByEnds-hPiAkrn3{justify-content:space-between}.sessionDay-hPiAkrn3 .timeMarkSegment-hPiAkrn3.timeMarkSegmentAlignByEnds-hPiAkrn3 .timeMark-hPiAkrn3{padding:0}.sessionDay-hPiAkrn3 .timeMarkSegment-hPiAkrn3.timeMarkSegmentAlignByEnds-hPiAkrn3 .timeMark-hPiAkrn3:first-child{transform:translateX(-50%)}.sessionDay-hPiAkrn3 .timeMarkSegment-hPiAkrn3.timeMarkSegmentAlignByEnds-hPiAkrn3 .timeMark-hPiAkrn3:last-child{transform:translateX(50%)}.sessionDay-hPiAkrn3 .timeMark-hPiAkrn3{background-color:var(--_3-7Ghp);color:var(--color-default-gray);font-size:11px;line-height:16px}.sessionDay-hPiAkrn3 .segment-hPiAkrn3{box-sizing:border-box;content:"";height:100%;opacity:.3;padding:0 2px;position:absolute}.sessionDay-hPiAkrn3 .segment-hPiAkrn3:first-child{padding-left:0}.sessionDay-hPiAkrn3 .segment-hPiAkrn3:last-child{padding-right:0}.sessionDay-hPiAkrn3 .segment-hPiAkrn3:before{content:"";display:flex;flex:1;height:100%;min-width:1px;z-index:0}.sessionDay-hPiAkrn3 .segment-hPiAkrn3.small-hPiAkrn3{margin-left:-1px;padding:0;z-index:1}.sessionDay-hPiAkrn3 .segment-hPiAkrn3.start-hPiAkrn3:before{border-radius:4px 0 0 4px}.sessionDay-hPiAkrn3 .segment-hPiAkrn3.end-hPiAkrn3:before{border-radius:0 4px 4px 0}.sessionDay-hPiAkrn3 .segment-hPiAkrn3.start-hPiAkrn3.end-hPiAkrn3:before{border-radius:4px}.sessionDay-hPiAkrn3.active-hPiAkrn3 .segment-hPiAkrn3{opacity:1}.sessionDay-hPiAkrn3.active-hPiAkrn3 .weekDay-hPiAkrn3{color:var(--_2-7Ghp)}.green-hPiAkrn3{color:var(--color-minty-green-400)}.green-hPiAkrn3:before{background-color:currentColor}.orange-hPiAkrn3{color:var(--color-tan-orange-500)}.orange-hPiAkrn3:before{background-color:currentColor}.blue-hPiAkrn3{color:var(--color-tv-blue-500)}.blue-hPiAkrn3:before{background-color:currentColor}.gray-hPiAkrn3{color:var(--_4-7Ghp)}.gray-hPiAkrn3:before{background-color:currentColor}.tooltip-hPiAkrn3{white-space:normal}.tooltip-hPiAkrn3 .time-hPiAkrn3{color:var(--_7-7Ghp);margin-left:5px}.tooltip-hPiAkrn3 .gray-hPiAkrn3{color:var(--_5-7Ghp)}.tooltip-hPiAkrn3 .blue-hPiAkrn3{color:var(--_6-7Ghp)}
|
||||
@@ -0,0 +1 @@
|
||||
[data-theme=light]{--_0-7Ghp:var(--color-cold-gray-900);--_1-7Ghp:var(--color-white);--_2-7Ghp:var(--color-cold-gray-900);--_3-7Ghp:var(--color-white);--_4-7Ghp:var(--color-cold-gray-150);--_5-7Ghp:var(--color-cold-gray-400);--_6-7Ghp:var(--color-tv-blue-a200);--_7-7Ghp:var(--color-cold-gray-100)}[data-theme=dark]{--_0-7Ghp:var(--color-cold-gray-200);--_1-7Ghp:var(--color-cold-gray-850);--_2-7Ghp:var(--color-cold-gray-200);--_3-7Ghp:var(--color-cold-gray-850);--_4-7Ghp:var(--color-cold-gray-700);--_5-7Ghp:var(--color-cold-gray-300);--_6-7Ghp:var(--color-tv-blue-a200);--_7-7Ghp:var(--color-cold-gray-100)}.wrapper-hPiAkrn3{box-sizing:border-box;display:flex;flex-direction:column;min-width:215px;padding-left:15px;position:relative}.timezone-hPiAkrn3{color:var(--color-default-gray);font-size:11px;line-height:18px;padding-top:4px;text-align:center;width:100%}.largePadding-hPiAkrn3{padding-top:8px}.sessionDayWrapper-hPiAkrn3{display:flex;flex-direction:column;position:relative}.nowWrapper-hPiAkrn3{bottom:0;left:0;pointer-events:none;position:absolute;right:30px;top:0}.nowWrapper-hPiAkrn3 .now-hPiAkrn3{backface-visibility:hidden;background-color:var(--_0-7Ghp);bottom:-1px;outline:1px var(--_1-7Ghp) solid;position:absolute;top:2px;width:1px}.sessionDay-hPiAkrn3{align-items:baseline;display:flex}.sessionDay-hPiAkrn3 .weekDay-hPiAkrn3{color:var(--color-default-gray);font-size:10px;overflow:hidden;padding-top:3px;text-transform:uppercase;width:30px}.sessionDay-hPiAkrn3 .sessionDaySegments-hPiAkrn3,.sessionDay-hPiAkrn3 .timeMarkWrapper-hPiAkrn3{flex:1;position:relative;width:100%}.sessionDay-hPiAkrn3 .timeMarkWrapper-hPiAkrn3{height:16px;margin-top:3px}.sessionDay-hPiAkrn3 .sessionDaySegments-hPiAkrn3{border-radius:4px;height:7px;margin:20px 0 2px}.sessionDay-hPiAkrn3:first-child .sessionDaySegments-hPiAkrn3{margin-top:0}.sessionDay-hPiAkrn3 .timeMarkSegment-hPiAkrn3{content:"";display:flex;justify-content:center;position:absolute}.sessionDay-hPiAkrn3 .timeMarkSegment-hPiAkrn3 .timeMark-hPiAkrn3:first-child{padding-left:4px}.sessionDay-hPiAkrn3 .timeMarkSegment-hPiAkrn3 .timeMark-hPiAkrn3:last-child{padding-right:4px}.sessionDay-hPiAkrn3 .timeMarkSegment-hPiAkrn3.timeMarkSegmentAlignByEnds-hPiAkrn3{justify-content:space-between}.sessionDay-hPiAkrn3 .timeMarkSegment-hPiAkrn3.timeMarkSegmentAlignByEnds-hPiAkrn3 .timeMark-hPiAkrn3{padding:0}.sessionDay-hPiAkrn3 .timeMarkSegment-hPiAkrn3.timeMarkSegmentAlignByEnds-hPiAkrn3 .timeMark-hPiAkrn3:first-child{transform:translateX(50%)}.sessionDay-hPiAkrn3 .timeMarkSegment-hPiAkrn3.timeMarkSegmentAlignByEnds-hPiAkrn3 .timeMark-hPiAkrn3:last-child{transform:translateX(-50%)}.sessionDay-hPiAkrn3 .timeMark-hPiAkrn3{background-color:var(--_3-7Ghp);color:var(--color-default-gray);font-size:11px;line-height:16px}.sessionDay-hPiAkrn3 .segment-hPiAkrn3{box-sizing:border-box;content:"";height:100%;opacity:.3;padding:0 2px;position:absolute}.sessionDay-hPiAkrn3 .segment-hPiAkrn3:first-child{padding-right:0}.sessionDay-hPiAkrn3 .segment-hPiAkrn3:last-child{padding-left:0}.sessionDay-hPiAkrn3 .segment-hPiAkrn3:before{content:"";display:flex;flex:1;height:100%;min-width:1px;z-index:0}.sessionDay-hPiAkrn3 .segment-hPiAkrn3.small-hPiAkrn3{margin-right:-1px;padding:0;z-index:1}.sessionDay-hPiAkrn3 .segment-hPiAkrn3.start-hPiAkrn3:before{border-radius:0 4px 4px 0}.sessionDay-hPiAkrn3 .segment-hPiAkrn3.end-hPiAkrn3:before{border-radius:4px 0 0 4px}.sessionDay-hPiAkrn3 .segment-hPiAkrn3.start-hPiAkrn3.end-hPiAkrn3:before{border-radius:4px}.sessionDay-hPiAkrn3.active-hPiAkrn3 .segment-hPiAkrn3{opacity:1}.sessionDay-hPiAkrn3.active-hPiAkrn3 .weekDay-hPiAkrn3{color:var(--_2-7Ghp)}.green-hPiAkrn3{color:var(--color-minty-green-400)}.green-hPiAkrn3:before{background-color:currentColor}.orange-hPiAkrn3{color:var(--color-tan-orange-500)}.orange-hPiAkrn3:before{background-color:currentColor}.blue-hPiAkrn3{color:var(--color-tv-blue-500)}.blue-hPiAkrn3:before{background-color:currentColor}.gray-hPiAkrn3{color:var(--_4-7Ghp)}.gray-hPiAkrn3:before{background-color:currentColor}.tooltip-hPiAkrn3{white-space:normal}.tooltip-hPiAkrn3 .time-hPiAkrn3{color:var(--_7-7Ghp);margin-right:5px}.tooltip-hPiAkrn3 .gray-hPiAkrn3{color:var(--_5-7Ghp)}.tooltip-hPiAkrn3 .blue-hPiAkrn3{color:var(--_6-7Ghp)}
|
||||
@@ -0,0 +1,12 @@
|
||||
(self.webpackChunktradingview=self.webpackChunktradingview||[]).push([[2164],{97754:(e,t)=>{var i;!function(){"use strict";var n={}.hasOwnProperty;function r(){for(var e=[],t=0;t<arguments.length;t++){var i=arguments[t];if(i){var s=typeof i;if("string"===s||"number"===s)e.push(i);else if(Array.isArray(i)&&i.length){var o=r.apply(null,i);o&&e.push(o)}else if("object"===s)for(var l in i)n.call(i,l)&&i[l]&&e.push(l)}}return e.join(" ")}e.exports?(r.default=r,e.exports=r):void 0===(i=function(){return r}.apply(t,[]))||(e.exports=i)}()},4237:(e,t,i)=>{"use strict";var n=i(32227);t.createRoot=n.createRoot,n.hydrateRoot},3789:function(e,t,i){e=i.nmd(e),function(){var t,i,n,r,s,o,l,a,u=[].slice,p={}.hasOwnProperty;l=function(){},i=function(){function e(){}return e.prototype.addEventListener=e.prototype.on,e.prototype.on=function(e,t){return this._callbacks=this._callbacks||{},this._callbacks[e]||(this._callbacks[e]=[]),this._callbacks[e].push(t),this},e.prototype.emit=function(){var e,t,i,n,r;if(i=arguments[0],e=2<=arguments.length?u.call(arguments,1):[],this._callbacks=this._callbacks||{},t=this._callbacks[i])for(n=0,r=t.length;n<r;n++)t[n].apply(this,e);return this},e.prototype.removeListener=e.prototype.off,e.prototype.removeAllListeners=e.prototype.off,e.prototype.removeEventListener=e.prototype.off,e.prototype.off=function(e,t){var i,n,r,s;if(!this._callbacks||0===arguments.length)return this._callbacks={},this;if(!(i=this._callbacks[e]))return this;if(1===arguments.length)return delete this._callbacks[e],this;for(n=r=0,s=i.length;r<s;n=++r)if(i[n]===t){i.splice(n,1);break}return this},e}(),t=function(e){var t,n;function r(e,i){var n,s,o;if(this.element=e,this.version=r.version,this.defaultOptions.previewTemplate=this.defaultOptions.previewTemplate.replace(/\n*/g,""),this.clickableElements=[],this.listeners=[],this.files=[],"string"==typeof this.element&&(this.element=document.querySelector(this.element)),!this.element||null==this.element.nodeType)throw new Error("Invalid dropzone element.");if(this.element.dropzone)throw new Error("Dropzone already attached.");if(r.instances.push(this),this.element.dropzone=this,n=null!=(o=r.optionsForElement(this.element))?o:{},this.options=t({},this.defaultOptions,n,null!=i?i:{}),this.options.forceFallback||!r.isBrowserSupported())return this.options.fallback.call(this);if(null==this.options.url&&(this.options.url=this.element.getAttribute("action")),!this.options.url)throw new Error("No URL provided.");if(this.options.acceptedFiles&&this.options.acceptedMimeTypes)throw new Error("You can't provide both 'acceptedFiles' and 'acceptedMimeTypes'. 'acceptedMimeTypes' is deprecated.");this.options.acceptedMimeTypes&&(this.options.acceptedFiles=this.options.acceptedMimeTypes,delete this.options.acceptedMimeTypes),this.options.method=this.options.method.toUpperCase(),(s=this.getExistingFallback())&&s.parentNode&&s.parentNode.removeChild(s),
|
||||
!1!==this.options.previewsContainer&&(this.options.previewsContainer?this.previewsContainer=r.getElement(this.options.previewsContainer,"previewsContainer"):this.previewsContainer=this.element),this.options.clickable&&(!0===this.options.clickable?this.clickableElements=[this.element]:this.clickableElements=r.getElements(this.options.clickable,"clickable")),this.init()}return function(e,t){for(var i in t)p.call(t,i)&&(e[i]=t[i]);function n(){this.constructor=e}n.prototype=t.prototype,e.prototype=new n,e.__super__=t.prototype}(r,e),r.prototype.Emitter=i,r.prototype.events=["drop","dragstart","dragend","dragenter","dragover","dragleave","addedfile","removedfile","thumbnail","error","errormultiple","processing","processingmultiple","uploadprogress","totaluploadprogress","sending","sendingmultiple","success","successmultiple","canceled","canceledmultiple","complete","completemultiple","reset","maxfilesexceeded","maxfilesreached","queuecomplete"],r.prototype.defaultOptions={url:null,method:"post",withCredentials:!1,parallelUploads:2,uploadMultiple:!1,maxFilesize:256,paramName:"file",createImageThumbnails:!0,maxThumbnailFilesize:10,thumbnailWidth:120,thumbnailHeight:120,filesizeBase:1e3,maxFiles:null,filesizeBase:1e3,params:{},clickable:!0,ignoreHiddenFiles:!0,acceptedFiles:null,acceptedMimeTypes:null,autoProcessQueue:!0,autoQueue:!0,addRemoveLinks:!1,previewsContainer:null,capture:null,dictDefaultMessage:"Drop files here to upload",dictFallbackMessage:"Your browser does not support drag'n'drop file uploads.",dictFallbackText:"Please use the fallback form below to upload your files like in the olden days.",dictFileTooBig:"File is too big ({{filesize}}MiB). Max filesize: {{maxFilesize}}MiB.",dictInvalidFileType:"You can't upload files of this type.",dictResponseError:"Server responded with {{statusCode}} code.",dictCancelUpload:"Cancel upload",dictCancelUploadConfirmation:"Are you sure you want to cancel this upload?",dictRemoveFile:"Remove file",dictRemoveFileConfirmation:null,dictMaxFilesExceeded:"You can not upload any more files.",accept:function(e,t){return t()},init:function(){return l},forceFallback:!1,fallback:function(){var e,t,i,n,s,o;for(this.element.className=this.element.className+" dz-browser-not-supported",n=0,s=(o=this.element.getElementsByTagName("div")).length;n<s;n++)e=o[n],/(^| )dz-message($| )/.test(e.className)&&(t=e,e.className="dz-message");return t||(t=r.createElement('<div class="dz-message"><span></span></div>'),this.element.appendChild(t)),(i=t.getElementsByTagName("span")[0])&&(i.textContent=this.options.dictFallbackMessage),this.element.appendChild(this.getFallbackForm())},resize:function(e){var t,i,n;return t={srcX:0,srcY:0,srcWidth:e.width,srcHeight:e.height},i=e.width/e.height,t.optWidth=this.options.thumbnailWidth,t.optHeight=this.options.thumbnailHeight,null==t.optWidth&&null==t.optHeight?(t.optWidth=t.srcWidth,t.optHeight=t.srcHeight):null==t.optWidth?t.optWidth=i*t.optHeight:null==t.optHeight&&(t.optHeight=1/i*t.optWidth),n=t.optWidth/t.optHeight,
|
||||
e.height<t.optHeight||e.width<t.optWidth?(t.trgHeight=t.srcHeight,t.trgWidth=t.srcWidth):i>n?(t.srcHeight=e.height,t.srcWidth=t.srcHeight*n):(t.srcWidth=e.width,t.srcHeight=t.srcWidth/n),t.srcX=(e.width-t.srcWidth)/2,t.srcY=(e.height-t.srcHeight)/2,t},drop:function(e){return this.element.classList.remove("dz-drag-hover")},dragstart:l,dragend:function(e){return this.element.classList.remove("dz-drag-hover")},dragenter:function(e){return this.element.classList.add("dz-drag-hover")},dragover:function(e){return this.element.classList.add("dz-drag-hover")},dragleave:function(e){return this.element.classList.remove("dz-drag-hover")},paste:l,reset:function(){return this.element.classList.remove("dz-started")},addedfile:function(e){var t,i,n,s,o,l,a,u,p,d,c,h,m;if(this.element===this.previewsContainer&&this.element.classList.add("dz-started"),this.previewsContainer){for(e.previewElement=r.createElement(this.options.previewTemplate.trim()),e.previewTemplate=e.previewElement,this.previewsContainer.appendChild(e.previewElement),n=0,l=(p=e.previewElement.querySelectorAll("[data-dz-name]")).length;n<l;n++)p[n].textContent=e.name;for(s=0,a=(d=e.previewElement.querySelectorAll("[data-dz-size]")).length;s<a;s++)d[s].innerHTML=this.filesize(e.size);for(this.options.addRemoveLinks&&(e._removeLink=r.createElement('<a class="dz-remove" href="javascript:undefined;" data-dz-remove>'+this.options.dictRemoveFile+"</a>"),e.previewElement.appendChild(e._removeLink)),m=this,t=function(t){return t.preventDefault(),t.stopPropagation(),e.status===r.UPLOADING?r.confirm(m.options.dictCancelUploadConfirmation,(function(){return m.removeFile(e)})):m.options.dictRemoveFileConfirmation?r.confirm(m.options.dictRemoveFileConfirmation,(function(){return m.removeFile(e)})):m.removeFile(e)},h=[],o=0,u=(c=e.previewElement.querySelectorAll("[data-dz-remove]")).length;o<u;o++)i=c[o],h.push(i.addEventListener("click",t));return h}},removedfile:function(e){var t;return e.previewElement&&null!=(t=e.previewElement)&&t.parentNode.removeChild(e.previewElement),this._updateMaxFilesReachedClass()},thumbnail:function(e,t){var i,n,r,s;if(e.previewElement){for(e.previewElement.classList.remove("dz-file-preview"),n=0,r=(s=e.previewElement.querySelectorAll("[data-dz-thumbnail]")).length;n<r;n++)(i=s[n]).alt=e.name,i.src=t;return setTimeout((function(){return e.previewElement.classList.add("dz-image-preview")}),1)}},error:function(e,t){var i,n,r,s,o;if(e.previewElement){for(e.previewElement.classList.add("dz-error"),"String"!=typeof t&&t.error&&(t=t.error),o=[],n=0,r=(s=e.previewElement.querySelectorAll("[data-dz-errormessage]")).length;n<r;n++)i=s[n],o.push(i.textContent=t);return o}},errormultiple:l,processing:function(e){if(e.previewElement&&(e.previewElement.classList.add("dz-processing"),e._removeLink))return e._removeLink.textContent=this.options.dictCancelUpload},processingmultiple:l,uploadprogress:function(e,t,i){var n,r,s,o,l;if(e.previewElement){for(l=[],r=0,
|
||||
s=(o=e.previewElement.querySelectorAll("[data-dz-uploadprogress]")).length;r<s;r++)"PROGRESS"===(n=o[r]).nodeName?l.push(n.value=t):l.push(n.style.width=t+"%");return l}},totaluploadprogress:l,sending:l,sendingmultiple:l,success:function(e){if(e.previewElement)return e.previewElement.classList.add("dz-success")},successmultiple:l,canceled:function(e){return this.emit("error",e,"Upload canceled.")},canceledmultiple:l,complete:function(e){if(e._removeLink&&(e._removeLink.textContent=this.options.dictRemoveFile),e.previewElement)return e.previewElement.classList.add("dz-complete")},completemultiple:l,maxfilesexceeded:l,maxfilesreached:l,queuecomplete:l,
|
||||
previewTemplate:'<div class="dz-preview dz-file-preview">\n <div class="dz-image"><img data-dz-thumbnail /></div>\n <div class="dz-details">\n <div class="dz-size"><span data-dz-size></span></div>\n <div class="dz-filename"><span data-dz-name></span></div>\n </div>\n <div class="dz-progress"><span class="dz-upload" data-dz-uploadprogress></span></div>\n <div class="dz-error-message"><span data-dz-errormessage></span></div>\n <div class="dz-success-mark">\n <svg width="54px" height="54px" viewBox="0 0 54 54" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sketch="http://www.bohemiancoding.com/sketch/ns">\n <title>Check</title>\n <defs></defs>\n <g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" sketch:type="MSPage">\n <path d="M23.5,31.8431458 L17.5852419,25.9283877 C16.0248253,24.3679711 13.4910294,24.366835 11.9289322,25.9289322 C10.3700136,27.4878508 10.3665912,30.0234455 11.9283877,31.5852419 L20.4147581,40.0716123 C20.5133999,40.1702541 20.6159315,40.2626649 20.7218615,40.3488435 C22.2835669,41.8725651 24.794234,41.8626202 26.3461564,40.3106978 L43.3106978,23.3461564 C44.8771021,21.7797521 44.8758057,19.2483887 43.3137085,17.6862915 C41.7547899,16.1273729 39.2176035,16.1255422 37.6538436,17.6893022 L23.5,31.8431458 Z M27,53 C41.3594035,53 53,41.3594035 53,27 C53,12.6405965 41.3594035,1 27,1 C12.6405965,1 1,12.6405965 1,27 C1,41.3594035 12.6405965,53 27,53 Z" id="Oval-2" stroke-opacity="0.198794158" stroke="#747474" fill-opacity="0.816519475" fill="#FFFFFF" sketch:type="MSShapeGroup"></path>\n </g>\n </svg>\n </div>\n <div class="dz-error-mark">\n <svg width="54px" height="54px" viewBox="0 0 54 54" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sketch="http://www.bohemiancoding.com/sketch/ns">\n <title>Error</title>\n <defs></defs>\n <g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" sketch:type="MSPage">\n <g id="Check-+-Oval-2" sketch:type="MSLayerGroup" stroke="#747474" stroke-opacity="0.198794158" fill="#FFFFFF" fill-opacity="0.816519475">\n <path d="M32.6568542,29 L38.3106978,23.3461564 C39.8771021,21.7797521 39.8758057,19.2483887 38.3137085,17.6862915 C36.7547899,16.1273729 34.2176035,16.1255422 32.6538436,17.6893022 L27,23.3431458 L21.3461564,17.6893022 C19.7823965,16.1255422 17.2452101,16.1273729 15.6862915,17.6862915 C14.1241943,19.2483887 14.1228979,21.7797521 15.6893022,23.3461564 L21.3431458,29 L15.6893022,34.6538436 C14.1228979,36.2202479 14.1241943,38.7516113 15.6862915,40.3137085 C17.2452101,41.8726271 19.7823965,41.8744578 21.3461564,40.3106978 L27,34.6568542 L32.6538436,40.3106978 C34.2176035,41.8744578 36.7547899,41.8726271 38.3137085,40.3137085 C39.8758057,38.7516113 39.8771021,36.2202479 38.3106978,34.6538436 L32.6568542,29 Z M27,53 C41.3594035,53 53,41.3594035 53,27 C53,12.6405965 41.3594035,1 27,1 C12.6405965,1 1,12.6405965 1,27 C1,41.3594035 12.6405965,53 27,53 Z" id="Oval-2" sketch:type="MSShapeGroup"></path>\n </g>\n </g>\n </svg>\n </div>\n</div>'
|
||||
},t=function(){var e,t,i,n,r,s,o;for(n=arguments[0],s=0,o=(i=2<=arguments.length?u.call(arguments,1):[]).length;s<o;s++)for(e in t=i[s])r=t[e],n[e]=r;return n},r.prototype.getAcceptedFiles=function(){var e,t,i,n,r;for(r=[],t=0,i=(n=this.files).length;t<i;t++)(e=n[t]).accepted&&r.push(e);return r},r.prototype.getRejectedFiles=function(){var e,t,i,n,r;for(r=[],t=0,i=(n=this.files).length;t<i;t++)(e=n[t]).accepted||r.push(e);return r},r.prototype.getFilesWithStatus=function(e){var t,i,n,r,s;for(s=[],i=0,n=(r=this.files).length;i<n;i++)(t=r[i]).status===e&&s.push(t);return s},r.prototype.getQueuedFiles=function(){return this.getFilesWithStatus(r.QUEUED)},r.prototype.getUploadingFiles=function(){return this.getFilesWithStatus(r.UPLOADING)},r.prototype.getActiveFiles=function(){var e,t,i,n,s;for(s=[],t=0,i=(n=this.files).length;t<i;t++)(e=n[t]).status!==r.UPLOADING&&e.status!==r.QUEUED||s.push(e);return s},r.prototype.init=function(){var e,t,i,n,s,o,l,a;for("form"===this.element.tagName&&this.element.setAttribute("enctype","multipart/form-data"),this.element.classList.contains("dropzone")&&!this.element.querySelector(".dz-message")&&this.element.appendChild(r.createElement('<div class="dz-default dz-message"><span>'+this.options.dictDefaultMessage+"</span></div>")),this.clickableElements.length&&(a=this,i=function(){return a.hiddenFileInput&&document.body.removeChild(a.hiddenFileInput),a.hiddenFileInput=document.createElement("input"),a.hiddenFileInput.setAttribute("type","file"),(null==a.options.maxFiles||a.options.maxFiles>1)&&a.hiddenFileInput.setAttribute("multiple","multiple"),a.hiddenFileInput.className="dz-hidden-input",null!=a.options.acceptedFiles&&a.hiddenFileInput.setAttribute("accept",a.options.acceptedFiles),null!=a.options.capture&&a.hiddenFileInput.setAttribute("capture",a.options.capture),a.hiddenFileInput.style.visibility="hidden",a.hiddenFileInput.style.position="absolute",a.hiddenFileInput.style.top="0",a.hiddenFileInput.style.left="0",a.hiddenFileInput.style.height="0",a.hiddenFileInput.style.width="0",document.body.appendChild(a.hiddenFileInput),a.hiddenFileInput.addEventListener("change",(function(){var e,t,n,r;if((t=a.hiddenFileInput.files).length)for(n=0,r=t.length;n<r;n++)e=t[n],a.addFile(e);return i()}))},i()),this.URL=null!=(o=window.URL)?o:window.webkitURL,n=0,s=(l=this.events).length;n<s;n++)e=l[n],this.on(e,this.options[e]);return this.on("uploadprogress",function(e){return function(){return e.updateTotalUploadProgress()}}(this)),this.on("removedfile",function(e){return function(){return e.updateTotalUploadProgress()}}(this)),this.on("canceled",function(e){return function(t){return e.emit("complete",t)}}(this)),this.on("complete",function(e){return function(t){if(0===e.getUploadingFiles().length&&0===e.getQueuedFiles().length)return setTimeout((function(){return e.emit("queuecomplete")}),0)}}(this)),t=function(e){return e.stopPropagation(),e.preventDefault?e.preventDefault():e.returnValue=!1},this.listeners=[{element:this.element,events:{dragstart:function(e){return function(t){
|
||||
return e.emit("dragstart",t)}}(this),dragenter:function(e){return function(i){return t(i),e.emit("dragenter",i)}}(this),dragover:function(e){return function(i){var n;try{n=i.dataTransfer.effectAllowed}catch(e){}return i.dataTransfer.dropEffect="move"===n||"linkMove"===n?"move":"copy",t(i),e.emit("dragover",i)}}(this),dragleave:function(e){return function(t){return e.emit("dragleave",t)}}(this),drop:function(e){return function(t){return t.preventDefault?t.preventDefault():t.returnValue=!1,e.drop(t)}}(this),dragend:function(e){return function(t){return e.emit("dragend",t)}}(this)}}],this.clickableElements.forEach(function(e){return function(t){return e.listeners.push({element:t,events:{click:function(i){if(t!==e.element||i.target===e.element||r.elementInside(i.target,e.element.querySelector(".dz-message")))return e.hiddenFileInput.click()}}})}}(this)),this.enable(),this.options.init.call(this)},r.prototype.destroy=function(){var e;return this.disable(),this.removeAllFiles(!0),(null!=(e=this.hiddenFileInput)?e.parentNode:void 0)&&(this.hiddenFileInput.parentNode.removeChild(this.hiddenFileInput),this.hiddenFileInput=null),delete this.element.dropzone,r.instances.splice(r.instances.indexOf(this),1)},r.prototype.updateTotalUploadProgress=function(){var e,t,i,n,r,s,o;if(i=0,t=0,this.getActiveFiles().length){for(r=0,s=(o=this.getActiveFiles()).length;r<s;r++)i+=(e=o[r]).upload.bytesSent,t+=e.upload.total;n=100*i/t}else n=100;return this.emit("totaluploadprogress",n,t,i)},r.prototype._getParamName=function(e){return"function"==typeof this.options.paramName?this.options.paramName(e):this.options.paramName+(this.options.uploadMultiple?"["+e+"]":"")},r.prototype.getFallbackForm=function(){var e,t,i,n;return(e=this.getExistingFallback())?e:(i='<div class="dz-fallback">',this.options.dictFallbackText&&(i+="<p>"+this.options.dictFallbackText+"</p>"),i+='<input type="file" name="'+this._getParamName(0)+'" '+(this.options.uploadMultiple?'multiple="multiple"':void 0)+' /><input type="submit" value="Upload!"></div>',t=r.createElement(i),"FORM"!==this.element.tagName?(n=r.createElement('<form action="'+this.options.url+'" enctype="multipart/form-data" method="'+this.options.method+'"></form>')).appendChild(t):(this.element.setAttribute("enctype","multipart/form-data"),this.element.setAttribute("method",this.options.method)),null!=n?n:t)},r.prototype.getExistingFallback=function(){var e,t,i,n,r,s;for(t=function(e){var t,i,n;for(i=0,n=e.length;i<n;i++)if(t=e[i],/(^| )fallback($| )/.test(t.className))return t},n=0,r=(s=["div","form"]).length;n<r;n++)if(i=s[n],e=t(this.element.getElementsByTagName(i)))return e},r.prototype.setupEventListeners=function(){var e,t,i,n,r,s,o;for(o=[],n=0,r=(s=this.listeners).length;n<r;n++)e=s[n],o.push(function(){var n,r;for(t in r=[],n=e.events)i=n[t],r.push(e.element.addEventListener(t,i,!1));return r}());return o},r.prototype.removeEventListeners=function(){var e,t,i,n,r,s,o;for(o=[],n=0,r=(s=this.listeners).length;n<r;n++)e=s[n],o.push(function(){var n,r;for(t in r=[],n=e.events)i=n[t],
|
||||
r.push(e.element.removeEventListener(t,i,!1));return r}());return o},r.prototype.disable=function(){var e,t,i,n,r;for(this.clickableElements.forEach((function(e){return e.classList.remove("dz-clickable")})),this.removeEventListeners(),r=[],t=0,i=(n=this.files).length;t<i;t++)e=n[t],r.push(this.cancelUpload(e));return r},r.prototype.enable=function(){return this.clickableElements.forEach((function(e){return e.classList.add("dz-clickable")})),this.setupEventListeners()},r.prototype.filesize=function(e){var t,i,n,r,s,o,l;for(i=n=null,t=o=0,l=(s=["TB","GB","MB","KB","b"]).length;o<l;t=++o)if(r=s[t],e>=Math.pow(this.options.filesizeBase,4-t)/10){i=e/Math.pow(this.options.filesizeBase,4-t),n=r;break}return"<strong>"+(i=Math.round(10*i)/10)+"</strong> "+n},r.prototype._updateMaxFilesReachedClass=function(){return null!=this.options.maxFiles&&this.getAcceptedFiles().length>=this.options.maxFiles?(this.getAcceptedFiles().length===this.options.maxFiles&&this.emit("maxfilesreached",this.files),this.element.classList.add("dz-max-files-reached")):this.element.classList.remove("dz-max-files-reached")},r.prototype.drop=function(e){var t,i;e.dataTransfer&&(this.emit("drop",e),(t=e.dataTransfer.files).length&&((i=e.dataTransfer.items)&&i.length&&null!=i[0].webkitGetAsEntry?this._addFilesFromItems(i):this.handleFiles(t)))},r.prototype.paste=function(e){var t,i;if(null!=(null!=e&&null!=(i=e.clipboardData)?i.items:void 0))return this.emit("paste",e),(t=e.clipboardData.items).length?this._addFilesFromItems(t):void 0},r.prototype.handleFiles=function(e){var t,i,n,r;for(r=[],i=0,n=e.length;i<n;i++)t=e[i],r.push(this.addFile(t));return r},r.prototype._addFilesFromItems=function(e){var t,i,n,r,s;for(s=[],n=0,r=e.length;n<r;n++)null!=(i=e[n]).webkitGetAsEntry&&(t=i.webkitGetAsEntry())?t.isFile?s.push(this.addFile(i.getAsFile())):t.isDirectory?s.push(this._addFilesFromDirectory(t,t.name)):s.push(void 0):null!=i.getAsFile&&(null==i.kind||"file"===i.kind)?s.push(this.addFile(i.getAsFile())):s.push(void 0);return s},r.prototype._addFilesFromDirectory=function(e,t){var i,n,r;return i=e.createReader(),r=this,n=function(e){var i,n,s;for(n=0,s=e.length;n<s;n++)(i=e[n]).isFile?i.file((function(e){if(!r.options.ignoreHiddenFiles||"."!==e.name.substring(0,1))return e.fullPath=t+"/"+e.name,r.addFile(e)})):i.isDirectory&&r._addFilesFromDirectory(i,t+"/"+i.name)},i.readEntries(n,(function(e){return"undefined"!=typeof console&&null!==console&&"function"==typeof console.log?console.log(e):void 0}))},r.prototype.accept=function(e,t){return e.size>1024*this.options.maxFilesize*1024?t(this.options.dictFileTooBig.replace("{{filesize}}",Math.round(e.size/1024/10.24)/100).replace("{{maxFilesize}}",this.options.maxFilesize)):r.isValidFile(e,this.options.acceptedFiles)?null!=this.options.maxFiles&&this.getAcceptedFiles().length>=this.options.maxFiles?(t(this.options.dictMaxFilesExceeded.replace("{{maxFiles}}",this.options.maxFiles)),this.emit("maxfilesexceeded",e)):this.options.accept.call(this,e,t):t(this.options.dictInvalidFileType)},
|
||||
r.prototype.addFile=function(e){return e.upload={progress:0,total:e.size,bytesSent:0},this.files.push(e),e.status=r.ADDED,this.emit("addedfile",e),this._enqueueThumbnail(e),this.accept(e,(t=this,function(i){return i?(e.accepted=!1,t._errorProcessing([e],i)):(e.accepted=!0,t.options.autoQueue&&t.enqueueFile(e)),t._updateMaxFilesReachedClass()}));var t},r.prototype.enqueueFiles=function(e){var t,i,n;for(i=0,n=e.length;i<n;i++)t=e[i],this.enqueueFile(t);return null},r.prototype.enqueueFile=function(e){if(e.status!==r.ADDED||!0!==e.accepted)throw new Error("This file can't be queued because it has already been processed or was rejected.");if(e.status=r.QUEUED,this.options.autoProcessQueue)return setTimeout((t=this,function(){return t.processQueue()}),0);var t},r.prototype._thumbnailQueue=[],r.prototype._processingThumbnail=!1,r.prototype._enqueueThumbnail=function(e){if(this.options.createImageThumbnails&&e.type.match(/image.*/)&&e.size<=1024*this.options.maxThumbnailFilesize*1024)return this._thumbnailQueue.push(e),setTimeout((t=this,function(){return t._processThumbnailQueue()}),0);var t},r.prototype._processThumbnailQueue=function(){var e;if(!this._processingThumbnail&&0!==this._thumbnailQueue.length)return this._processingThumbnail=!0,this.createThumbnail(this._thumbnailQueue.shift(),(e=this,function(){return e._processingThumbnail=!1,e._processThumbnailQueue()}))},r.prototype.removeFile=function(e){if(e.status===r.UPLOADING&&this.cancelUpload(e),this.files=a(this.files,e),this.emit("removedfile",e),0===this.files.length)return this.emit("reset")},r.prototype.removeAllFiles=function(e){var t,i,n,s;for(null==e&&(e=!1),i=0,n=(s=this.files.slice()).length;i<n;i++)((t=s[i]).status!==r.UPLOADING||e)&&this.removeFile(t);return null},r.prototype.createThumbnail=function(e,t){var i,n;return(i=new FileReader).onload=(n=this,function(){return"image/svg+xml"===e.type?(n.emit("thumbnail",e,i.result),void(null!=t&&t())):n.createThumbnailFromUrl(e,i.result,t)}),i.readAsDataURL(e)},r.prototype.createThumbnailFromUrl=function(e,t,i){var n,r;return(n=document.createElement("img")).onload=(r=this,function(){var t,s,l,a,u,p,d,c;if(e.width=n.width,e.height=n.height,null==(l=r.options.resize.call(r,e)).trgWidth&&(l.trgWidth=l.optWidth),null==l.trgHeight&&(l.trgHeight=l.optHeight),s=(t=document.createElement("canvas")).getContext("2d"),t.width=l.trgWidth,t.height=l.trgHeight,o(s,n,null!=(u=l.srcX)?u:0,null!=(p=l.srcY)?p:0,l.srcWidth,l.srcHeight,null!=(d=l.trgX)?d:0,null!=(c=l.trgY)?c:0,l.trgWidth,l.trgHeight),a=t.toDataURL("image/png"),r.emit("thumbnail",e,a),null!=i)return i()}),null!=i&&(n.onerror=i),n.src=t},r.prototype.processQueue=function(){var e,t,i,n;if(t=this.options.parallelUploads,e=i=this.getUploadingFiles().length,!(i>=t)&&(n=this.getQueuedFiles()).length>0){if(this.options.uploadMultiple)return this.processFiles(n.slice(0,t-i));for(;e<t;){if(!n.length)return;this.processFile(n.shift()),e++}}},r.prototype.processFile=function(e){return this.processFiles([e])},r.prototype.processFiles=function(e){var t,i,n;for(i=0,
|
||||
n=e.length;i<n;i++)(t=e[i]).processing=!0,t.status=r.UPLOADING,this.emit("processing",t);return this.options.uploadMultiple&&this.emit("processingmultiple",e),this.uploadFiles(e)},r.prototype._getFilesWithXhr=function(e){var t;return function(){var i,n,r,s;for(s=[],i=0,n=(r=this.files).length;i<n;i++)(t=r[i]).xhr===e&&s.push(t);return s}.call(this)},r.prototype.cancelUpload=function(e){var t,i,n,s,o,l,a;if(e.status===r.UPLOADING){for(n=0,o=(i=this._getFilesWithXhr(e.xhr)).length;n<o;n++)(t=i[n]).status=r.CANCELED;for(e.xhr.abort(),s=0,l=i.length;s<l;s++)t=i[s],this.emit("canceled",t);this.options.uploadMultiple&&this.emit("canceledmultiple",i)}else(a=e.status)!==r.ADDED&&a!==r.QUEUED||(e.status=r.CANCELED,this.emit("canceled",e),this.options.uploadMultiple&&this.emit("canceledmultiple",[e]));if(this.options.autoProcessQueue)return this.processQueue()},n=function(){var e,t;return t=arguments[0],e=2<=arguments.length?u.call(arguments,1):[],"function"==typeof t?t.apply(this,e):t},r.prototype.uploadFile=function(e){return this.uploadFiles([e])},r.prototype.uploadFiles=function(e){var i,s,o,l,a,u,p,d,c,h,m,f,g,v,y,F,w,E,b,C,k,z,L,x,A,T,D,S,_,M,U,N,I,R,P;for(b=new XMLHttpRequest,C=0,x=e.length;C<x;C++)(i=e[C]).xhr=b;for(l in f=n(this.options.method,e),w=n(this.options.url,e),b.open(f,w,!0),b.withCredentials=!!this.options.withCredentials,y=null,P=this,o=function(){var t,n,r;for(r=[],t=0,n=e.length;t<n;t++)i=e[t],r.push(P._errorProcessing(e,y||P.options.dictResponseError.replace("{{statusCode}}",b.status),b));return r},F=function(t){return function(n){var r,s,o,l,a,u,p,d,c;if(null!=n)for(s=100*n.loaded/n.total,o=0,u=e.length;o<u;o++)(i=e[o]).upload={progress:s,total:n.total,bytesSent:n.loaded};else{for(r=!0,s=100,l=0,p=e.length;l<p;l++)100===(i=e[l]).upload.progress&&i.upload.bytesSent===i.upload.total||(r=!1),i.upload.progress=s,i.upload.bytesSent=i.upload.total;if(r)return}for(c=[],a=0,d=e.length;a<d;a++)i=e[a],c.push(t.emit("uploadprogress",i,s,i.upload.bytesSent));return c}}(this),b.onload=function(t){return function(i){var n;if(e[0].status!==r.CANCELED&&4===b.readyState){if(y=b.responseText,b.getResponseHeader("content-type")&&~b.getResponseHeader("content-type").indexOf("application/json"))try{y=JSON.parse(y)}catch(e){i=e,y="Invalid JSON response from server."}return F(),200<=(n=b.status)&&n<300?t._finished(e,y,i):o()}}}(this),b.onerror=function(){if(e[0].status!==r.CANCELED)return o()},v=null!=(_=b.upload)?_:b,!1!==this.options.trackProgress&&(v.onprogress=F),u={Accept:"application/json","Cache-Control":"no-cache","X-Requested-With":"XMLHttpRequest"},this.options.headers&&t(u,this.options.headers),u)void 0!==(a=u[l])&&b.setRequestHeader(l,a);if(s=new FormData,this.options.params)for(m in M=this.options.params)E=M[m],s.append(m,E);for(k=0,A=e.length;k<A;k++)i=e[k],this.emit("sending",i,b,s);if(this.options.uploadMultiple&&this.emit("sendingmultiple",e,b,s),"FORM"===this.element.tagName)for(z=0,T=(U=this.element.querySelectorAll("input, textarea, select, button")).length;z<T;z++)if(c=(d=U[z]).getAttribute("name"),
|
||||
h=d.getAttribute("type"),"SELECT"===d.tagName&&d.hasAttribute("multiple"))for(L=0,D=(N=d.options).length;L<D;L++)(g=N[L]).selected&&s.append(c,g.value);else(!h||"checkbox"!==(I=h.toLowerCase())&&"radio"!==I||d.checked)&&s.append(c,d.value);for(p=S=0,R=e.length-1;0<=R?S<=R:S>=R;p=0<=R?++S:--S)s.append(this._getParamName(p),e[p],e[p].name);return b.send(s)},r.prototype._finished=function(e,t,i){var n,s,o;for(s=0,o=e.length;s<o;s++)(n=e[s]).status=r.SUCCESS,this.emit("success",n,t,i),this.emit("complete",n);if(this.options.uploadMultiple&&(this.emit("successmultiple",e,t,i),this.emit("completemultiple",e)),this.options.autoProcessQueue)return this.processQueue()},r.prototype._errorProcessing=function(e,t,i){var n,s,o;for(s=0,o=e.length;s<o;s++)(n=e[s]).status=r.ERROR,this.emit("error",n,t,i),this.emit("complete",n);if(this.options.uploadMultiple&&(this.emit("errormultiple",e,t,i),this.emit("completemultiple",e)),this.options.autoProcessQueue)return this.processQueue()},r}(i),t.version="4.0.1",t.options={},t.optionsForElement=function(e){return e.getAttribute("id")?t.options[n(e.getAttribute("id"))]:void 0},t.instances=[],t.forElement=function(e){if("string"==typeof e&&(e=document.querySelector(e)),null==(null!=e?e.dropzone:void 0))throw new Error("No Dropzone found for given element. This is probably because you're trying to access it before Dropzone had the time to initialize. Use the `init` option to setup any additional observers on your Dropzone.");return e.dropzone},t.autoDiscover=!0,t.discover=function(){var e,i,n,r,s,o;for(document.querySelectorAll?n=document.querySelectorAll(".dropzone"):(n=[],e=function(e){var t,i,r,s;for(s=[],i=0,r=e.length;i<r;i++)t=e[i],/(^| )dropzone($| )/.test(t.className)?s.push(n.push(t)):s.push(void 0);return s},e(document.getElementsByTagName("div")),e(document.getElementsByTagName("form"))),o=[],r=0,s=n.length;r<s;r++)i=n[r],!1!==t.optionsForElement(i)?o.push(new t(i)):o.push(void 0);return o},t.blacklistedBrowsers=[/opera.*Macintosh.*version\/12/i],t.isBrowserSupported=function(){var e,i,n,r;if(e=!0,window.File&&window.FileReader&&window.FileList&&window.Blob&&window.FormData&&document.querySelector)if("classList"in document.createElement("a"))for(i=0,n=(r=t.blacklistedBrowsers).length;i<n;i++)r[i].test(navigator.userAgent)&&(e=!1);else e=!1;else e=!1;return e},a=function(e,t){var i,n,r,s;for(s=[],n=0,r=e.length;n<r;n++)(i=e[n])!==t&&s.push(i);return s},n=function(e){return e.replace(/[\-_](\w)/g,(function(e){return e.charAt(1).toUpperCase()}))},t.createElement=function(e){var t;return(t=document.createElement("div")).innerHTML=e,t.childNodes[0]},t.elementInside=function(e,t){if(e===t)return!0;for(;e=e.parentNode;)if(e===t)return!0;return!1},t.getElement=function(e,t){var i;if("string"==typeof e?i=document.querySelector(e):null!=e.nodeType&&(i=e),null==i)throw new Error("Invalid `"+t+"` option provided. Please provide a CSS selector or a plain HTML element.");return i},t.getElements=function(e,t){var i,n,r,s,o,l,a;if(e instanceof Array){n=[];try{for(r=0,o=e.length;r<o;r++)i=e[r],
|
||||
n.push(this.getElement(i,t))}catch(e){n=null}}else if("string"==typeof e)for(n=[],s=0,l=(a=document.querySelectorAll(e)).length;s<l;s++)i=a[s],n.push(i);else null!=e.nodeType&&(n=[e]);if(null==n||!n.length)throw new Error("Invalid `"+t+"` option provided. Please provide a CSS selector, a plain HTML element or a list of those.");return n},t.confirm=function(e,t,i){return window.confirm(e)?t():null!=i?i():void 0},t.isValidFile=function(e,t){var i,n,r,s,o;if(!t)return!0;for(t=t.split(","),i=(n=e.type).replace(/\/.*$/,""),s=0,o=t.length;s<o;s++)if("."===(r=(r=t[s]).trim()).charAt(0)){if(-1!==e.name.toLowerCase().indexOf(r.toLowerCase(),e.name.length-r.length))return!0}else if(/\/\*$/.test(r)){if(i===r.replace(/\/.*$/,""))return!0}else if(n===r)return!0;return!1},null!==e?e.exports=t:window.Dropzone=t,t.ADDED="added",t.QUEUED="queued",t.ACCEPTED=t.QUEUED,t.UPLOADING="uploading",t.PROCESSING=t.UPLOADING,t.CANCELED="canceled",t.ERROR="error",t.SUCCESS="success",s=function(e){var t,i,n,r,s,o,l,a;for(e.naturalWidth,s=e.naturalHeight,(t=document.createElement("canvas")).width=1,t.height=s,(i=t.getContext("2d")).drawImage(e,0,0),n=i.getImageData(0,0,1,s).data,a=0,r=s,o=s;o>a;)0===n[4*(o-1)+3]?r=o:a=o,o=r+a>>1;return 0===(l=o/s)?1:l},o=function(e,t,i,n,r,o,l,a,u,p){var d;return d=s(t),e.drawImage(t,i,n,r,o,l,a,u,p/d)},r=function(e,t){var i,n,r,s,o,l,a,u,p;if(r=!1,p=!0,n=e.document,u=n.documentElement,i=n.addEventListener?"addEventListener":"attachEvent",a=n.addEventListener?"removeEventListener":"detachEvent",l=n.addEventListener?"":"on",s=function(i){if("readystatechange"!==i.type||"complete"===n.readyState)return("load"===i.type?e:n)[a](l+i.type,s,!1),!r&&(r=!0)?t.call(e,i.type||i):void 0},o=function(){try{u.doScroll("left")}catch(e){return void setTimeout(o,50)}return s("poll")},"complete"!==n.readyState){if(n.createEventObject&&u.doScroll){try{p=!e.frameElement}catch(e){}p&&o()}return n[i](l+"DOMContentLoaded",s,!1),n[i](l+"readystatechange",s,!1),e[i](l+"load",s,!1)}},t._autoDiscoverFunction=function(){if(t.autoDiscover)return t.discover()},r(window,t._autoDiscoverFunction)}.call(this)},25931:(e,t,i)=>{"use strict";i.d(t,{nanoid:()=>n});let n=(e=21)=>crypto.getRandomValues(new Uint8Array(e)).reduce(((e,t)=>e+=(t&=63)<36?t.toString(36):t<62?(t-26).toString(36).toUpperCase():t>62?"-":"_"),"")}}]);
|
||||
@@ -0,0 +1 @@
|
||||
[data-theme=light]{--_0-udjz:var(--color-white);--_1-udjz:var(--color-cold-gray-400)}[data-theme=dark]{--_0-udjz:var(--color-cold-gray-900);--_1-udjz:var(--color-cold-gray-950)}.dialog-aRAWUDhF{background-color:var(--color-bg-primary);box-sizing:border-box;display:flex;flex-direction:column;min-width:280px;text-align:left}.dialog-aRAWUDhF.rounded-aRAWUDhF{border-radius:6px}.dialog-aRAWUDhF.shadowed-aRAWUDhF{box-shadow:0 2px 4px var(--color-shadow-primary-neutral-extra-heavy)}.dialog-aRAWUDhF.fullscreen-aRAWUDhF{bottom:0;height:100%;left:0;max-height:100%;max-width:100%;min-height:100%;position:fixed;right:0;top:0;width:100%}.dialog-aRAWUDhF.darker-aRAWUDhF{background-color:var(--_0-udjz)}.backdrop-aRAWUDhF{background-color:var(--_1-udjz);bottom:0;left:0;opacity:.5;position:fixed;right:0;top:0;transform:translateZ(0);z-index:-1}.dialog-qyCw0PaN{max-width:380px;min-width:280px;position:fixed;width:100%}.dialog-qyCw0PaN [data-dragg-area=true]{cursor:grab}.dialog-qyCw0PaN [data-dragg-area=true].dragging-qyCw0PaN{cursor:grabbing}html.theme-dark .dialog-qyCw0PaN.mobile-qyCw0PaN{background-color:var(--color-black)}html.theme-dark .dialog-qyCw0PaN.mobile-qyCw0PaN:not(.fullscreen-qyCw0PaN){box-shadow:0 4px 16px 0 var(--color-cold-gray-750),0 0 2px 0 var(--color-cold-gray-750)}.dialogAnimatedAppearance-qyCw0PaN{animation-duration:.3s;animation-name:dialogAnimation-qyCw0PaN;transform-origin:0 0}@keyframes dialogAnimation-qyCw0PaN{0%{opacity:0;transform:translate(var(--animationTranslateStartX),var(--animationTranslateStartY)) scale(0)}to{opacity:1;transform:translate(var(--animationTranslateEndX),var(--animationTranslateEndY)) scale(1)}}.dialogTooltip-qyCw0PaN{color:#fff;font-size:14px;left:50%;line-height:21px;max-width:540px;position:absolute;top:-20px;transform:translateX(-50%);width:max-content}@media (max-width:768px){.dialogTooltip-qyCw0PaN{max-width:240px}}
|
||||
@@ -0,0 +1 @@
|
||||
[data-theme=light]{--_0-udjz:var(--color-white);--_1-udjz:var(--color-cold-gray-400)}[data-theme=dark]{--_0-udjz:var(--color-cold-gray-900);--_1-udjz:var(--color-cold-gray-950)}.dialog-aRAWUDhF{background-color:var(--color-bg-primary);box-sizing:border-box;display:flex;flex-direction:column;min-width:280px;text-align:right}.dialog-aRAWUDhF.rounded-aRAWUDhF{border-radius:6px}.dialog-aRAWUDhF.shadowed-aRAWUDhF{box-shadow:0 2px 4px var(--color-shadow-primary-neutral-extra-heavy)}.dialog-aRAWUDhF.fullscreen-aRAWUDhF{bottom:0;height:100%;left:0;max-height:100%;max-width:100%;min-height:100%;position:fixed;right:0;top:0;width:100%}.dialog-aRAWUDhF.darker-aRAWUDhF{background-color:var(--_0-udjz)}.backdrop-aRAWUDhF{background-color:var(--_1-udjz);bottom:0;left:0;opacity:.5;position:fixed;right:0;top:0;transform:translateZ(0);z-index:-1}.dialog-qyCw0PaN{max-width:380px;min-width:280px;position:fixed;width:100%}.dialog-qyCw0PaN [data-dragg-area=true]{cursor:grab}.dialog-qyCw0PaN [data-dragg-area=true].dragging-qyCw0PaN{cursor:grabbing}html.theme-dark .dialog-qyCw0PaN.mobile-qyCw0PaN{background-color:var(--color-black)}html.theme-dark .dialog-qyCw0PaN.mobile-qyCw0PaN:not(.fullscreen-qyCw0PaN){box-shadow:0 4px 16px 0 var(--color-cold-gray-750),0 0 2px 0 var(--color-cold-gray-750)}.dialogAnimatedAppearance-qyCw0PaN{animation-duration:.3s;animation-name:dialogAnimation-qyCw0PaN;transform-origin:100% 0}@keyframes dialogAnimation-qyCw0PaN{0%{opacity:0;transform:translate(var(--animationTranslateStartX),var(--animationTranslateStartY)) scale(0)}to{opacity:1;transform:translate(var(--animationTranslateEndX),var(--animationTranslateEndY)) scale(1)}}.dialogTooltip-qyCw0PaN{color:#fff;font-size:14px;line-height:21px;max-width:540px;position:absolute;right:50%;top:-20px;transform:translateX(50%);width:max-content}@media (max-width:768px){.dialogTooltip-qyCw0PaN{max-width:240px}}
|
||||
@@ -0,0 +1,46 @@
|
||||
"use strict";(self.webpackChunktradingview=self.webpackChunktradingview||[]).push([[2227],{82321:(e,n,t)=>{var r=t(50959),l=t(22962);function a(e){for(var n="https://reactjs.org/docs/error-decoder.html?invariant="+e,t=1;t<arguments.length;t++)n+="&args[]="+encodeURIComponent(arguments[t]);return"Minified React error #"+e+"; visit "+n+" for the full message or use the non-minified dev environment for full errors and additional helpful warnings."}var u=new Set,o={};function i(e,n){s(e,n),s(e+"Capture",n)}function s(e,n){for(o[e]=n,e=0;e<n.length;e++)u.add(n[e])}var c=!("undefined"==typeof window||void 0===window.document||void 0===window.document.createElement),f=Object.prototype.hasOwnProperty,d=/^[:A-Z_a-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD][:A-Z_a-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD\-.0-9\u00B7\u0300-\u036F\u203F-\u2040]*$/,p={},m={};function h(e,n,t,r,l,a,u){this.acceptsBooleans=2===n||3===n||4===n,this.attributeName=r,this.attributeNamespace=l,this.mustUseProperty=t,this.propertyName=e,this.type=n,this.sanitizeURL=a,this.removeEmptyString=u}var g={};"children dangerouslySetInnerHTML defaultValue defaultChecked innerHTML suppressContentEditableWarning suppressHydrationWarning style".split(" ").forEach((function(e){g[e]=new h(e,0,!1,e,null,!1,!1)})),[["acceptCharset","accept-charset"],["className","class"],["htmlFor","for"],["httpEquiv","http-equiv"]].forEach((function(e){var n=e[0];g[n]=new h(n,1,!1,e[1],null,!1,!1)})),["contentEditable","draggable","spellCheck","value"].forEach((function(e){g[e]=new h(e,2,!1,e.toLowerCase(),null,!1,!1)})),["autoReverse","externalResourcesRequired","focusable","preserveAlpha"].forEach((function(e){g[e]=new h(e,2,!1,e,null,!1,!1)})),"allowFullScreen async autoFocus autoPlay controls default defer disabled disablePictureInPicture disableRemotePlayback formNoValidate hidden loop noModule noValidate open playsInline readOnly required reversed scoped seamless itemScope".split(" ").forEach((function(e){g[e]=new h(e,3,!1,e.toLowerCase(),null,!1,!1)})),["checked","multiple","muted","selected"].forEach((function(e){g[e]=new h(e,3,!0,e,null,!1,!1)})),["capture","download"].forEach((function(e){g[e]=new h(e,4,!1,e,null,!1,!1)})),["cols","rows","size","span"].forEach((function(e){g[e]=new h(e,6,!1,e,null,!1,!1)})),["rowSpan","start"].forEach((function(e){g[e]=new h(e,5,!1,e.toLowerCase(),null,!1,!1)}));var v=/[\-:]([a-z])/g;function y(e){return e[1].toUpperCase()}function b(e,n,t,r){var l=g.hasOwnProperty(n)?g[n]:null;(null!==l?0!==l.type:r||!(2<n.length)||"o"!==n[0]&&"O"!==n[0]||"n"!==n[1]&&"N"!==n[1])&&(function(e,n,t,r){if(null==n||function(e,n,t,r){if(null!==t&&0===t.type)return!1;switch(typeof n){case"function":case"symbol":return!0;case"boolean":return!r&&(null!==t?!t.acceptsBooleans:"data-"!==(e=e.toLowerCase().slice(0,5))&&"aria-"!==e);default:return!1}}(e,n,t,r))return!0
|
||||
;if(r)return!1;if(null!==t)switch(t.type){case 3:return!n;case 4:return!1===n;case 5:return isNaN(n);case 6:return isNaN(n)||1>n}return!1}(n,t,l,r)&&(t=null),r||null===l?function(e){return!!f.call(m,e)||!f.call(p,e)&&(d.test(e)?m[e]=!0:(p[e]=!0,!1))}(n)&&(null===t?e.removeAttribute(n):e.setAttribute(n,""+t)):l.mustUseProperty?e[l.propertyName]=null===t?3!==l.type&&"":t:(n=l.attributeName,r=l.attributeNamespace,null===t?e.removeAttribute(n):(t=3===(l=l.type)||4===l&&!0===t?"":""+t,r?e.setAttributeNS(r,n,t):e.setAttribute(n,t))))}"accent-height alignment-baseline arabic-form baseline-shift cap-height clip-path clip-rule color-interpolation color-interpolation-filters color-profile color-rendering dominant-baseline enable-background fill-opacity fill-rule flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight glyph-name glyph-orientation-horizontal glyph-orientation-vertical horiz-adv-x horiz-origin-x image-rendering letter-spacing lighting-color marker-end marker-mid marker-start overline-position overline-thickness paint-order panose-1 pointer-events rendering-intent shape-rendering stop-color stop-opacity strikethrough-position strikethrough-thickness stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width text-anchor text-decoration text-rendering underline-position underline-thickness unicode-bidi unicode-range units-per-em v-alphabetic v-hanging v-ideographic v-mathematical vector-effect vert-adv-y vert-origin-x vert-origin-y word-spacing writing-mode xmlns:xlink x-height".split(" ").forEach((function(e){var n=e.replace(v,y);g[n]=new h(n,1,!1,e,null,!1,!1)})),"xlink:actuate xlink:arcrole xlink:role xlink:show xlink:title xlink:type".split(" ").forEach((function(e){var n=e.replace(v,y);g[n]=new h(n,1,!1,e,"http://www.w3.org/1999/xlink",!1,!1)})),["xml:base","xml:lang","xml:space"].forEach((function(e){var n=e.replace(v,y);g[n]=new h(n,1,!1,e,"http://www.w3.org/XML/1998/namespace",!1,!1)})),["tabIndex","crossOrigin"].forEach((function(e){g[e]=new h(e,1,!1,e.toLowerCase(),null,!1,!1)})),g.xlinkHref=new h("xlinkHref",1,!1,"xlink:href","http://www.w3.org/1999/xlink",!0,!1),["src","href","action","formAction"].forEach((function(e){g[e]=new h(e,1,!1,e.toLowerCase(),null,!0,!0)}));var k=r.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED,w=Symbol.for("react.element"),S=Symbol.for("react.portal"),x=Symbol.for("react.fragment"),E=Symbol.for("react.strict_mode"),C=Symbol.for("react.profiler"),_=Symbol.for("react.provider"),P=Symbol.for("react.context"),N=Symbol.for("react.forward_ref"),z=Symbol.for("react.suspense"),T=Symbol.for("react.suspense_list"),L=Symbol.for("react.memo"),R=Symbol.for("react.lazy");Symbol.for("react.scope"),Symbol.for("react.debug_trace_mode");var M=Symbol.for("react.offscreen");Symbol.for("react.legacy_hidden"),Symbol.for("react.cache"),Symbol.for("react.tracing_marker");var F=Symbol.iterator;function O(e){
|
||||
return null===e||"object"!=typeof e?null:"function"==typeof(e=F&&e[F]||e["@@iterator"])?e:null}var D,I=Object.assign;function U(e){if(void 0===D)try{throw Error()}catch(e){var n=e.stack.trim().match(/\n( *(at )?)/);D=n&&n[1]||""}return"\n"+D+e}var V=!1;function A(e,n){if(!e||V)return"";V=!0;var t=Error.prepareStackTrace;Error.prepareStackTrace=void 0;try{if(n)if(n=function(){throw Error()},Object.defineProperty(n.prototype,"props",{set:function(){throw Error()}}),"object"==typeof Reflect&&Reflect.construct){try{Reflect.construct(n,[])}catch(e){var r=e}Reflect.construct(e,[],n)}else{try{n.call()}catch(e){r=e}e.call(n.prototype)}else{try{throw Error()}catch(e){r=e}e()}}catch(n){if(n&&r&&"string"==typeof n.stack){for(var l=n.stack.split("\n"),a=r.stack.split("\n"),u=l.length-1,o=a.length-1;1<=u&&0<=o&&l[u]!==a[o];)o--;for(;1<=u&&0<=o;u--,o--)if(l[u]!==a[o]){if(1!==u||1!==o)do{if(u--,0>--o||l[u]!==a[o]){var i="\n"+l[u].replace(" at new "," at ");return e.displayName&&i.includes("<anonymous>")&&(i=i.replace("<anonymous>",e.displayName)),i}}while(1<=u&&0<=o);break}}}finally{V=!1,Error.prepareStackTrace=t}return(e=e?e.displayName||e.name:"")?U(e):""}function $(e){switch(e.tag){case 5:return U(e.type);case 16:return U("Lazy");case 13:return U("Suspense");case 19:return U("SuspenseList");case 0:case 2:case 15:return e=A(e.type,!1);case 11:return e=A(e.type.render,!1);case 1:return e=A(e.type,!0);default:return""}}function j(e){if(null==e)return null;if("function"==typeof e)return e.displayName||e.name||null;if("string"==typeof e)return e;switch(e){case x:return"Fragment";case S:return"Portal";case C:return"Profiler";case E:return"StrictMode";case z:return"Suspense";case T:return"SuspenseList"}if("object"==typeof e)switch(e.$$typeof){case P:return(e.displayName||"Context")+".Consumer";case _:return(e._context.displayName||"Context")+".Provider";case N:var n=e.render;return(e=e.displayName)||(e=""!==(e=n.displayName||n.name||"")?"ForwardRef("+e+")":"ForwardRef"),e;case L:return null!==(n=e.displayName||null)?n:j(e.type)||"Memo";case R:n=e._payload,e=e._init;try{return j(e(n))}catch(e){}}return null}function B(e){var n=e.type;switch(e.tag){case 24:return"Cache";case 9:return(n.displayName||"Context")+".Consumer";case 10:return(n._context.displayName||"Context")+".Provider";case 18:return"DehydratedFragment";case 11:return e=(e=n.render).displayName||e.name||"",n.displayName||(""!==e?"ForwardRef("+e+")":"ForwardRef");case 7:return"Fragment";case 5:return n;case 4:return"Portal";case 3:return"Root";case 6:return"Text";case 16:return j(n);case 8:return n===E?"StrictMode":"Mode";case 22:return"Offscreen";case 12:return"Profiler";case 21:return"Scope";case 13:return"Suspense";case 19:return"SuspenseList";case 25:return"TracingMarker";case 1:case 0:case 17:case 2:case 14:case 15:if("function"==typeof n)return n.displayName||n.name||null;if("string"==typeof n)return n}return null}function H(e){switch(typeof e){case"boolean":case"number":case"string":case"undefined":case"object":return e;default:return""}}function W(e){var n=e.type
|
||||
;return(e=e.nodeName)&&"input"===e.toLowerCase()&&("checkbox"===n||"radio"===n)}function Q(e){e._valueTracker||(e._valueTracker=function(e){var n=W(e)?"checked":"value",t=Object.getOwnPropertyDescriptor(e.constructor.prototype,n),r=""+e[n];if(!e.hasOwnProperty(n)&&void 0!==t&&"function"==typeof t.get&&"function"==typeof t.set){var l=t.get,a=t.set;return Object.defineProperty(e,n,{configurable:!0,get:function(){return l.call(this)},set:function(e){r=""+e,a.call(this,e)}}),Object.defineProperty(e,n,{enumerable:t.enumerable}),{getValue:function(){return r},setValue:function(e){r=""+e},stopTracking:function(){e._valueTracker=null,delete e[n]}}}}(e))}function q(e){if(!e)return!1;var n=e._valueTracker;if(!n)return!0;var t=n.getValue(),r="";return e&&(r=W(e)?e.checked?"true":"false":e.value),(e=r)!==t&&(n.setValue(e),!0)}function K(e){if(void 0===(e=e||("undefined"!=typeof document?document:void 0)))return null;try{return e.activeElement||e.body}catch(n){return e.body}}function Y(e,n){var t=n.checked;return I({},n,{defaultChecked:void 0,defaultValue:void 0,value:void 0,checked:null!=t?t:e._wrapperState.initialChecked})}function X(e,n){var t=null==n.defaultValue?"":n.defaultValue,r=null!=n.checked?n.checked:n.defaultChecked;t=H(null!=n.value?n.value:t),e._wrapperState={initialChecked:r,initialValue:t,controlled:"checkbox"===n.type||"radio"===n.type?null!=n.checked:null!=n.value}}function G(e,n){null!=(n=n.checked)&&b(e,"checked",n,!1)}function Z(e,n){G(e,n);var t=H(n.value),r=n.type;if(null!=t)"number"===r?(0===t&&""===e.value||e.value!=t)&&(e.value=""+t):e.value!==""+t&&(e.value=""+t);else if("submit"===r||"reset"===r)return void e.removeAttribute("value");n.hasOwnProperty("value")?ee(e,n.type,t):n.hasOwnProperty("defaultValue")&&ee(e,n.type,H(n.defaultValue)),null==n.checked&&null!=n.defaultChecked&&(e.defaultChecked=!!n.defaultChecked)}function J(e,n,t){if(n.hasOwnProperty("value")||n.hasOwnProperty("defaultValue")){var r=n.type;if(!("submit"!==r&&"reset"!==r||void 0!==n.value&&null!==n.value))return;n=""+e._wrapperState.initialValue,t||n===e.value||(e.value=n),e.defaultValue=n}""!==(t=e.name)&&(e.name=""),e.defaultChecked=!!e._wrapperState.initialChecked,""!==t&&(e.name=t)}function ee(e,n,t){"number"===n&&K(e.ownerDocument)===e||(null==t?e.defaultValue=""+e._wrapperState.initialValue:e.defaultValue!==""+t&&(e.defaultValue=""+t))}var ne=Array.isArray;function te(e,n,t,r){if(e=e.options,n){n={};for(var l=0;l<t.length;l++)n["$"+t[l]]=!0;for(t=0;t<e.length;t++)l=n.hasOwnProperty("$"+e[t].value),e[t].selected!==l&&(e[t].selected=l),l&&r&&(e[t].defaultSelected=!0)}else{for(t=""+H(t),n=null,l=0;l<e.length;l++){if(e[l].value===t)return e[l].selected=!0,void(r&&(e[l].defaultSelected=!0));null!==n||e[l].disabled||(n=e[l])}null!==n&&(n.selected=!0)}}function re(e,n){if(null!=n.dangerouslySetInnerHTML)throw Error(a(91));return I({},n,{value:void 0,defaultValue:void 0,children:""+e._wrapperState.initialValue})}function le(e,n){var t=n.value;if(null==t){if(t=n.children,n=n.defaultValue,null!=t){if(null!=n)throw Error(a(92));if(ne(t)){
|
||||
if(1<t.length)throw Error(a(93));t=t[0]}n=t}null==n&&(n=""),t=n}e._wrapperState={initialValue:H(t)}}function ae(e,n){var t=H(n.value),r=H(n.defaultValue);null!=t&&((t=""+t)!==e.value&&(e.value=t),null==n.defaultValue&&e.defaultValue!==t&&(e.defaultValue=t)),null!=r&&(e.defaultValue=""+r)}function ue(e){var n=e.textContent;n===e._wrapperState.initialValue&&""!==n&&null!==n&&(e.value=n)}function oe(e){switch(e){case"svg":return"http://www.w3.org/2000/svg";case"math":return"http://www.w3.org/1998/Math/MathML";default:return"http://www.w3.org/1999/xhtml"}}function ie(e,n){return null==e||"http://www.w3.org/1999/xhtml"===e?oe(n):"http://www.w3.org/2000/svg"===e&&"foreignObject"===n?"http://www.w3.org/1999/xhtml":e}var se,ce,fe=(ce=function(e,n){if("http://www.w3.org/2000/svg"!==e.namespaceURI||"innerHTML"in e)e.innerHTML=n;else{for((se=se||document.createElement("div")).innerHTML="<svg>"+n.valueOf().toString()+"</svg>",n=se.firstChild;e.firstChild;)e.removeChild(e.firstChild);for(;n.firstChild;)e.appendChild(n.firstChild)}},"undefined"!=typeof MSApp&&MSApp.execUnsafeLocalFunction?function(e,n,t,r){MSApp.execUnsafeLocalFunction((function(){return ce(e,n)}))}:ce);function de(e,n){if(n){var t=e.firstChild;if(t&&t===e.lastChild&&3===t.nodeType)return void(t.nodeValue=n)}e.textContent=n}var pe={animationIterationCount:!0,aspectRatio:!0,borderImageOutset:!0,borderImageSlice:!0,borderImageWidth:!0,boxFlex:!0,boxFlexGroup:!0,boxOrdinalGroup:!0,columnCount:!0,columns:!0,flex:!0,flexGrow:!0,flexPositive:!0,flexShrink:!0,flexNegative:!0,flexOrder:!0,gridArea:!0,gridRow:!0,gridRowEnd:!0,gridRowSpan:!0,gridRowStart:!0,gridColumn:!0,gridColumnEnd:!0,gridColumnSpan:!0,gridColumnStart:!0,fontWeight:!0,lineClamp:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,tabSize:!0,widows:!0,zIndex:!0,zoom:!0,fillOpacity:!0,floodOpacity:!0,stopOpacity:!0,strokeDasharray:!0,strokeDashoffset:!0,strokeMiterlimit:!0,strokeOpacity:!0,strokeWidth:!0},me=["Webkit","ms","Moz","O"];function he(e,n,t){return null==n||"boolean"==typeof n||""===n?"":t||"number"!=typeof n||0===n||pe.hasOwnProperty(e)&&pe[e]?(""+n).trim():n+"px"}function ge(e,n){for(var t in e=e.style,n)if(n.hasOwnProperty(t)){var r=0===t.indexOf("--"),l=he(t,n[t],r);"float"===t&&(t="cssFloat"),r?e.setProperty(t,l):e[t]=l}}Object.keys(pe).forEach((function(e){me.forEach((function(n){n=n+e.charAt(0).toUpperCase()+e.substring(1),pe[n]=pe[e]}))}));var ve=I({menuitem:!0},{area:!0,base:!0,br:!0,col:!0,embed:!0,hr:!0,img:!0,input:!0,keygen:!0,link:!0,meta:!0,param:!0,source:!0,track:!0,wbr:!0});function ye(e,n){if(n){if(ve[e]&&(null!=n.children||null!=n.dangerouslySetInnerHTML))throw Error(a(137,e));if(null!=n.dangerouslySetInnerHTML){if(null!=n.children)throw Error(a(60));if("object"!=typeof n.dangerouslySetInnerHTML||!("__html"in n.dangerouslySetInnerHTML))throw Error(a(61))}if(null!=n.style&&"object"!=typeof n.style)throw Error(a(62))}}function be(e,n){if(-1===e.indexOf("-"))return"string"==typeof n.is;switch(e){case"annotation-xml":case"color-profile":case"font-face":case"font-face-src":
|
||||
case"font-face-uri":case"font-face-format":case"font-face-name":case"missing-glyph":return!1;default:return!0}}var ke=null;function we(e){return(e=e.target||e.srcElement||window).correspondingUseElement&&(e=e.correspondingUseElement),3===e.nodeType?e.parentNode:e}var Se=null,xe=null,Ee=null;function Ce(e){if(e=bl(e)){if("function"!=typeof Se)throw Error(a(280));var n=e.stateNode;n&&(n=wl(n),Se(e.stateNode,e.type,n))}}function _e(e){xe?Ee?Ee.push(e):Ee=[e]:xe=e}function Pe(){if(xe){var e=xe,n=Ee;if(Ee=xe=null,Ce(e),n)for(e=0;e<n.length;e++)Ce(n[e])}}function Ne(e,n){return e(n)}function ze(){}var Te=!1;function Le(e,n,t){if(Te)return e(n,t);Te=!0;try{return Ne(e,n,t)}finally{Te=!1,(null!==xe||null!==Ee)&&(ze(),Pe())}}function Re(e,n){var t=e.stateNode;if(null===t)return null;var r=wl(t);if(null===r)return null;t=r[n];e:switch(n){case"onClick":case"onClickCapture":case"onDoubleClick":case"onDoubleClickCapture":case"onMouseDown":case"onMouseDownCapture":case"onMouseMove":case"onMouseMoveCapture":case"onMouseUp":case"onMouseUpCapture":case"onMouseEnter":(r=!r.disabled)||(r=!("button"===(e=e.type)||"input"===e||"select"===e||"textarea"===e)),e=!r;break e;default:e=!1}if(e)return null;if(t&&"function"!=typeof t)throw Error(a(231,n,typeof t));return t}var Me=!1;if(c)try{var Fe={};Object.defineProperty(Fe,"passive",{get:function(){Me=!0}}),window.addEventListener("test",Fe,Fe),window.removeEventListener("test",Fe,Fe)}catch(ce){Me=!1}function Oe(e,n,t,r,l,a,u,o,i){var s=Array.prototype.slice.call(arguments,3);try{n.apply(t,s)}catch(e){this.onError(e)}}var De=!1,Ie=null,Ue=!1,Ve=null,Ae={onError:function(e){De=!0,Ie=e}};function $e(e,n,t,r,l,a,u,o,i){De=!1,Ie=null,Oe.apply(Ae,arguments)}function je(e){var n=e,t=e;if(e.alternate)for(;n.return;)n=n.return;else{e=n;do{!!(4098&(n=e).flags)&&(t=n.return),e=n.return}while(e)}return 3===n.tag?t:null}function Be(e){if(13===e.tag){var n=e.memoizedState;if(null===n&&(null!==(e=e.alternate)&&(n=e.memoizedState)),null!==n)return n.dehydrated}return null}function He(e){if(je(e)!==e)throw Error(a(188))}function We(e){return null!==(e=function(e){var n=e.alternate;if(!n){if(null===(n=je(e)))throw Error(a(188));return n!==e?null:e}for(var t=e,r=n;;){var l=t.return;if(null===l)break;var u=l.alternate;if(null===u){if(null!==(r=l.return)){t=r;continue}break}if(l.child===u.child){for(u=l.child;u;){if(u===t)return He(l),e;if(u===r)return He(l),n;u=u.sibling}throw Error(a(188))}if(t.return!==r.return)t=l,r=u;else{for(var o=!1,i=l.child;i;){if(i===t){o=!0,t=l,r=u;break}if(i===r){o=!0,r=l,t=u;break}i=i.sibling}if(!o){for(i=u.child;i;){if(i===t){o=!0,t=u,r=l;break}if(i===r){o=!0,r=u,t=l;break}i=i.sibling}if(!o)throw Error(a(189))}}if(t.alternate!==r)throw Error(a(190))}if(3!==t.tag)throw Error(a(188));return t.stateNode.current===t?e:n}(e))?Qe(e):null}function Qe(e){if(5===e.tag||6===e.tag)return e;for(e=e.child;null!==e;){var n=Qe(e);if(null!==n)return n;e=e.sibling}return null}
|
||||
var qe=l.unstable_scheduleCallback,Ke=l.unstable_cancelCallback,Ye=l.unstable_shouldYield,Xe=l.unstable_requestPaint,Ge=l.unstable_now,Ze=l.unstable_getCurrentPriorityLevel,Je=l.unstable_ImmediatePriority,en=l.unstable_UserBlockingPriority,nn=l.unstable_NormalPriority,tn=l.unstable_LowPriority,rn=l.unstable_IdlePriority,ln=null,an=null;var un=Math.clz32?Math.clz32:function(e){return e>>>=0,0===e?32:31-(on(e)/sn|0)|0},on=Math.log,sn=Math.LN2;var cn=64,fn=4194304;function dn(e){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: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 4194240&e;case 4194304:case 8388608:case 16777216:case 33554432:case 67108864:return 130023424&e;case 134217728:return 134217728;case 268435456:return 268435456;case 536870912:return 536870912;case 1073741824:return 1073741824;default:return e}}function pn(e,n){var t=e.pendingLanes;if(0===t)return 0;var r=0,l=e.suspendedLanes,a=e.pingedLanes,u=268435455&t;if(0!==u){var o=u&~l;0!==o?r=dn(o):0!==(a&=u)&&(r=dn(a))}else 0!==(u=t&~l)?r=dn(u):0!==a&&(r=dn(a));if(0===r)return 0;if(0!==n&&n!==r&&!(n&l)&&((l=r&-r)>=(a=n&-n)||16===l&&4194240&a))return n;if(4&r&&(r|=16&t),0!==(n=e.entangledLanes))for(e=e.entanglements,n&=r;0<n;)l=1<<(t=31-un(n)),r|=e[t],n&=~l;return r}function mn(e,n){switch(e){case 1:case 2:case 4:return n+250;case 8:case 16:case 32:case 64: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 n+5e3;default:return-1}}function hn(e){return 0!==(e=-1073741825&e.pendingLanes)?e:1073741824&e?1073741824:0}function gn(){var e=cn;return!(4194240&(cn<<=1))&&(cn=64),e}function vn(e){for(var n=[],t=0;31>t;t++)n.push(e);return n}function yn(e,n,t){e.pendingLanes|=n,536870912!==n&&(e.suspendedLanes=0,e.pingedLanes=0),(e=e.eventTimes)[n=31-un(n)]=t}function bn(e,n){var t=e.entangledLanes|=n;for(e=e.entanglements;t;){var r=31-un(t),l=1<<r;l&n|e[r]&n&&(e[r]|=n),t&=~l}}var kn=0;function wn(e){return 1<(e&=-e)?4<e?268435455&e?16:536870912:4:1}var Sn,xn,En,Cn,_n,Pn=!1,Nn=[],zn=null,Tn=null,Ln=null,Rn=new Map,Mn=new Map,Fn=[],On="mousedown mouseup touchcancel touchend touchstart auxclick dblclick pointercancel pointerdown pointerup dragend dragstart drop compositionend compositionstart keydown keypress keyup input textInput copy cut paste click change contextmenu reset submit".split(" ");function Dn(e,n){switch(e){case"focusin":case"focusout":zn=null;break;case"dragenter":case"dragleave":Tn=null;break;case"mouseover":case"mouseout":Ln=null;break;case"pointerover":case"pointerout":Rn.delete(n.pointerId);break;case"gotpointercapture":case"lostpointercapture":Mn.delete(n.pointerId)}}function In(e,n,t,r,l,a){return null===e||e.nativeEvent!==a?(e={blockedOn:n,domEventName:t,eventSystemFlags:r,nativeEvent:a,targetContainers:[l]},null!==n&&(null!==(n=bl(n))&&xn(n)),
|
||||
e):(e.eventSystemFlags|=r,n=e.targetContainers,null!==l&&-1===n.indexOf(l)&&n.push(l),e)}function Un(e){var n=yl(e.target);if(null!==n){var t=je(n);if(null!==t)if(13===(n=t.tag)){if(null!==(n=Be(t)))return e.blockedOn=n,void _n(e.priority,(function(){En(t)}))}else if(3===n&&t.stateNode.current.memoizedState.isDehydrated)return void(e.blockedOn=3===t.tag?t.stateNode.containerInfo:null)}e.blockedOn=null}function Vn(e){if(null!==e.blockedOn)return!1;for(var n=e.targetContainers;0<n.length;){var t=Xn(e.domEventName,e.eventSystemFlags,n[0],e.nativeEvent);if(null!==t)return null!==(n=bl(t))&&xn(n),e.blockedOn=t,!1;var r=new(t=e.nativeEvent).constructor(t.type,t);ke=r,t.target.dispatchEvent(r),ke=null,n.shift()}return!0}function An(e,n,t){Vn(e)&&t.delete(n)}function $n(){Pn=!1,null!==zn&&Vn(zn)&&(zn=null),null!==Tn&&Vn(Tn)&&(Tn=null),null!==Ln&&Vn(Ln)&&(Ln=null),Rn.forEach(An),Mn.forEach(An)}function jn(e,n){e.blockedOn===n&&(e.blockedOn=null,Pn||(Pn=!0,l.unstable_scheduleCallback(l.unstable_NormalPriority,$n)))}function Bn(e){function n(n){return jn(n,e)}if(0<Nn.length){jn(Nn[0],e);for(var t=1;t<Nn.length;t++){var r=Nn[t];r.blockedOn===e&&(r.blockedOn=null)}}for(null!==zn&&jn(zn,e),null!==Tn&&jn(Tn,e),null!==Ln&&jn(Ln,e),Rn.forEach(n),Mn.forEach(n),t=0;t<Fn.length;t++)(r=Fn[t]).blockedOn===e&&(r.blockedOn=null);for(;0<Fn.length&&null===(t=Fn[0]).blockedOn;)Un(t),null===t.blockedOn&&Fn.shift()}var Hn=k.ReactCurrentBatchConfig,Wn=!0;function Qn(e,n,t,r){var l=kn,a=Hn.transition;Hn.transition=null;try{kn=1,Kn(e,n,t,r)}finally{kn=l,Hn.transition=a}}function qn(e,n,t,r){var l=kn,a=Hn.transition;Hn.transition=null;try{kn=4,Kn(e,n,t,r)}finally{kn=l,Hn.transition=a}}function Kn(e,n,t,r){if(Wn){var l=Xn(e,n,t,r);if(null===l)Hr(e,n,r,Yn,t),Dn(e,r);else if(function(e,n,t,r,l){switch(n){case"focusin":return zn=In(zn,e,n,t,r,l),!0;case"dragenter":return Tn=In(Tn,e,n,t,r,l),!0;case"mouseover":return Ln=In(Ln,e,n,t,r,l),!0;case"pointerover":var a=l.pointerId;return Rn.set(a,In(Rn.get(a)||null,e,n,t,r,l)),!0;case"gotpointercapture":return a=l.pointerId,Mn.set(a,In(Mn.get(a)||null,e,n,t,r,l)),!0}return!1}(l,e,n,t,r))r.stopPropagation();else if(Dn(e,r),4&n&&-1<On.indexOf(e)){for(;null!==l;){var a=bl(l);if(null!==a&&Sn(a),null===(a=Xn(e,n,t,r))&&Hr(e,n,r,Yn,t),a===l)break;l=a}null!==l&&r.stopPropagation()}else Hr(e,n,r,null,t)}}var Yn=null;function Xn(e,n,t,r){if(Yn=null,null!==(e=yl(e=we(r))))if(null===(n=je(e)))e=null;else if(13===(t=n.tag)){if(null!==(e=Be(n)))return e;e=null}else if(3===t){if(n.stateNode.current.memoizedState.isDehydrated)return 3===n.tag?n.stateNode.containerInfo:null;e=null}else n!==e&&(e=null);return Yn=e,null}function Gn(e){switch(e){case"cancel":case"click":case"close":case"contextmenu":case"copy":case"cut":case"auxclick":case"dblclick":case"dragend":case"dragstart":case"drop":case"focusin":case"focusout":case"input":case"invalid":case"keydown":case"keypress":case"keyup":case"mousedown":case"mouseup":case"paste":case"pause":case"play":case"pointercancel":case"pointerdown":case"pointerup":case"ratechange":
|
||||
case"reset":case"resize":case"seeked":case"submit":case"touchcancel":case"touchend":case"touchstart":case"volumechange":case"change":case"selectionchange":case"textInput":case"compositionstart":case"compositionend":case"compositionupdate":case"beforeblur":case"afterblur":case"beforeinput":case"blur":case"fullscreenchange":case"focus":case"hashchange":case"popstate":case"select":case"selectstart":return 1;case"drag":case"dragenter":case"dragexit":case"dragleave":case"dragover":case"mousemove":case"mouseout":case"mouseover":case"pointermove":case"pointerout":case"pointerover":case"scroll":case"toggle":case"touchmove":case"wheel":case"mouseenter":case"mouseleave":case"pointerenter":case"pointerleave":return 4;case"message":switch(Ze()){case Je:return 1;case en:return 4;case nn:case tn:return 16;case rn:return 536870912;default:return 16}default:return 16}}var Zn=null,Jn=null,et=null;function nt(){if(et)return et;var e,n,t=Jn,r=t.length,l="value"in Zn?Zn.value:Zn.textContent,a=l.length;for(e=0;e<r&&t[e]===l[e];e++);var u=r-e;for(n=1;n<=u&&t[r-n]===l[a-n];n++);return et=l.slice(e,1<n?1-n:void 0)}function tt(e){var n=e.keyCode;return"charCode"in e?0===(e=e.charCode)&&13===n&&(e=13):e=n,10===e&&(e=13),32<=e||13===e?e:0}function rt(){return!0}function lt(){return!1}function at(e){function n(n,t,r,l,a){for(var u in this._reactName=n,this._targetInst=r,this.type=t,this.nativeEvent=l,this.target=a,this.currentTarget=null,e)e.hasOwnProperty(u)&&(n=e[u],this[u]=n?n(l):l[u]);return this.isDefaultPrevented=(null!=l.defaultPrevented?l.defaultPrevented:!1===l.returnValue)?rt:lt,this.isPropagationStopped=lt,this}return I(n.prototype,{preventDefault:function(){this.defaultPrevented=!0;var e=this.nativeEvent;e&&(e.preventDefault?e.preventDefault():"unknown"!=typeof e.returnValue&&(e.returnValue=!1),this.isDefaultPrevented=rt)},stopPropagation:function(){var e=this.nativeEvent;e&&(e.stopPropagation?e.stopPropagation():"unknown"!=typeof e.cancelBubble&&(e.cancelBubble=!0),this.isPropagationStopped=rt)},persist:function(){},isPersistent:rt}),n}var ut,ot,it,st={eventPhase:0,bubbles:0,cancelable:0,timeStamp:function(e){return e.timeStamp||Date.now()},defaultPrevented:0,isTrusted:0},ct=at(st),ft=I({},st,{view:0,detail:0}),dt=at(ft),pt=I({},ft,{screenX:0,screenY:0,clientX:0,clientY:0,pageX:0,pageY:0,ctrlKey:0,shiftKey:0,altKey:0,metaKey:0,getModifierState:Ct,button:0,buttons:0,relatedTarget:function(e){return void 0===e.relatedTarget?e.fromElement===e.srcElement?e.toElement:e.fromElement:e.relatedTarget},movementX:function(e){return"movementX"in e?e.movementX:(e!==it&&(it&&"mousemove"===e.type?(ut=e.screenX-it.screenX,ot=e.screenY-it.screenY):ot=ut=0,it=e),ut)},movementY:function(e){return"movementY"in e?e.movementY:ot}}),mt=at(pt),ht=at(I({},pt,{dataTransfer:0})),gt=at(I({},ft,{relatedTarget:0})),vt=at(I({},st,{animationName:0,elapsedTime:0,pseudoElement:0})),yt=I({},st,{clipboardData:function(e){return"clipboardData"in e?e.clipboardData:window.clipboardData}}),bt=at(yt),kt=at(I({},st,{data:0})),wt={Esc:"Escape",Spacebar:" ",Left:"ArrowLeft",
|
||||
Up:"ArrowUp",Right:"ArrowRight",Down:"ArrowDown",Del:"Delete",Win:"OS",Menu:"ContextMenu",Apps:"ContextMenu",Scroll:"ScrollLock",MozPrintableKey:"Unidentified"},St={8:"Backspace",9:"Tab",12:"Clear",13:"Enter",16:"Shift",17:"Control",18:"Alt",19:"Pause",20:"CapsLock",27:"Escape",32:" ",33:"PageUp",34:"PageDown",35:"End",36:"Home",37:"ArrowLeft",38:"ArrowUp",39:"ArrowRight",40:"ArrowDown",45:"Insert",46:"Delete",112:"F1",113:"F2",114:"F3",115:"F4",116:"F5",117:"F6",118:"F7",119:"F8",120:"F9",121:"F10",122:"F11",123:"F12",144:"NumLock",145:"ScrollLock",224:"Meta"},xt={Alt:"altKey",Control:"ctrlKey",Meta:"metaKey",Shift:"shiftKey"};function Et(e){var n=this.nativeEvent;return n.getModifierState?n.getModifierState(e):!!(e=xt[e])&&!!n[e]}function Ct(){return Et}var _t=I({},ft,{key:function(e){if(e.key){var n=wt[e.key]||e.key;if("Unidentified"!==n)return n}return"keypress"===e.type?13===(e=tt(e))?"Enter":String.fromCharCode(e):"keydown"===e.type||"keyup"===e.type?St[e.keyCode]||"Unidentified":""},code:0,location:0,ctrlKey:0,shiftKey:0,altKey:0,metaKey:0,repeat:0,locale:0,getModifierState:Ct,charCode:function(e){return"keypress"===e.type?tt(e):0},keyCode:function(e){return"keydown"===e.type||"keyup"===e.type?e.keyCode:0},which:function(e){return"keypress"===e.type?tt(e):"keydown"===e.type||"keyup"===e.type?e.keyCode:0}}),Pt=at(_t),Nt=at(I({},pt,{pointerId:0,width:0,height:0,pressure:0,tangentialPressure:0,tiltX:0,tiltY:0,twist:0,pointerType:0,isPrimary:0})),zt=at(I({},ft,{touches:0,targetTouches:0,changedTouches:0,altKey:0,metaKey:0,ctrlKey:0,shiftKey:0,getModifierState:Ct})),Tt=at(I({},st,{propertyName:0,elapsedTime:0,pseudoElement:0})),Lt=I({},pt,{deltaX:function(e){return"deltaX"in e?e.deltaX:"wheelDeltaX"in e?-e.wheelDeltaX:0},deltaY:function(e){return"deltaY"in e?e.deltaY:"wheelDeltaY"in e?-e.wheelDeltaY:"wheelDelta"in e?-e.wheelDelta:0},deltaZ:0,deltaMode:0}),Rt=at(Lt),Mt=[9,13,27,32],Ft=c&&"CompositionEvent"in window,Ot=null;c&&"documentMode"in document&&(Ot=document.documentMode);var Dt=c&&"TextEvent"in window&&!Ot,It=c&&(!Ft||Ot&&8<Ot&&11>=Ot),Ut=String.fromCharCode(32),Vt=!1;function At(e,n){switch(e){case"keyup":return-1!==Mt.indexOf(n.keyCode);case"keydown":return 229!==n.keyCode;case"keypress":case"mousedown":case"focusout":return!0;default:return!1}}function $t(e){return"object"==typeof(e=e.detail)&&"data"in e?e.data:null}var jt=!1;var Bt={color:!0,date:!0,datetime:!0,"datetime-local":!0,email:!0,month:!0,number:!0,password:!0,range:!0,search:!0,tel:!0,text:!0,time:!0,url:!0,week:!0};function Ht(e){var n=e&&e.nodeName&&e.nodeName.toLowerCase();return"input"===n?!!Bt[e.type]:"textarea"===n}function Wt(e,n,t,r){_e(r),0<(n=Qr(n,"onChange")).length&&(t=new ct("onChange","change",null,t,r),e.push({event:t,listeners:n}))}var Qt=null,qt=null;function Kt(e){Ur(e,0)}function Yt(e){if(q(kl(e)))return e}function Xt(e,n){if("change"===e)return n}var Gt=!1;if(c){var Zt;if(c){var Jt="oninput"in document;if(!Jt){var er=document.createElement("div");er.setAttribute("oninput","return;"),Jt="function"==typeof er.oninput}Zt=Jt
|
||||
}else Zt=!1;Gt=Zt&&(!document.documentMode||9<document.documentMode)}function nr(){Qt&&(Qt.detachEvent("onpropertychange",tr),qt=Qt=null)}function tr(e){if("value"===e.propertyName&&Yt(qt)){var n=[];Wt(n,qt,e,we(e)),Le(Kt,n)}}function rr(e,n,t){"focusin"===e?(nr(),qt=t,(Qt=n).attachEvent("onpropertychange",tr)):"focusout"===e&&nr()}function lr(e){if("selectionchange"===e||"keyup"===e||"keydown"===e)return Yt(qt)}function ar(e,n){if("click"===e)return Yt(n)}function ur(e,n){if("input"===e||"change"===e)return Yt(n)}var or="function"==typeof Object.is?Object.is:function(e,n){return e===n&&(0!==e||1/e==1/n)||e!=e&&n!=n};function ir(e,n){if(or(e,n))return!0;if("object"!=typeof e||null===e||"object"!=typeof n||null===n)return!1;var t=Object.keys(e),r=Object.keys(n);if(t.length!==r.length)return!1;for(r=0;r<t.length;r++){var l=t[r];if(!f.call(n,l)||!or(e[l],n[l]))return!1}return!0}function sr(e){for(;e&&e.firstChild;)e=e.firstChild;return e}function cr(e,n){var t,r=sr(e);for(e=0;r;){if(3===r.nodeType){if(t=e+r.textContent.length,e<=n&&t>=n)return{node:r,offset:n-e};e=t}e:{for(;r;){if(r.nextSibling){r=r.nextSibling;break e}r=r.parentNode}r=void 0}r=sr(r)}}function fr(e,n){return!(!e||!n)&&(e===n||(!e||3!==e.nodeType)&&(n&&3===n.nodeType?fr(e,n.parentNode):"contains"in e?e.contains(n):!!e.compareDocumentPosition&&!!(16&e.compareDocumentPosition(n))))}function dr(){for(var e=window,n=K();n instanceof e.HTMLIFrameElement;){try{var t="string"==typeof n.contentWindow.location.href}catch(e){t=!1}if(!t)break;n=K((e=n.contentWindow).document)}return n}function pr(e){var n=e&&e.nodeName&&e.nodeName.toLowerCase();return n&&("input"===n&&("text"===e.type||"search"===e.type||"tel"===e.type||"url"===e.type||"password"===e.type)||"textarea"===n||"true"===e.contentEditable)}function mr(e){var n=dr(),t=e.focusedElem,r=e.selectionRange;if(n!==t&&t&&t.ownerDocument&&fr(t.ownerDocument.documentElement,t)){if(null!==r&&pr(t))if(n=r.start,void 0===(e=r.end)&&(e=n),"selectionStart"in t)t.selectionStart=n,t.selectionEnd=Math.min(e,t.value.length);else if((e=(n=t.ownerDocument||document)&&n.defaultView||window).getSelection){e=e.getSelection();var l=t.textContent.length,a=Math.min(r.start,l);r=void 0===r.end?a:Math.min(r.end,l),!e.extend&&a>r&&(l=r,r=a,a=l),l=cr(t,a);var u=cr(t,r);l&&u&&(1!==e.rangeCount||e.anchorNode!==l.node||e.anchorOffset!==l.offset||e.focusNode!==u.node||e.focusOffset!==u.offset)&&((n=n.createRange()).setStart(l.node,l.offset),e.removeAllRanges(),a>r?(e.addRange(n),e.extend(u.node,u.offset)):(n.setEnd(u.node,u.offset),e.addRange(n)))}for(n=[],e=t;e=e.parentNode;)1===e.nodeType&&n.push({element:e,left:e.scrollLeft,top:e.scrollTop});for("function"==typeof t.focus&&t.focus(),t=0;t<n.length;t++)(e=n[t]).element.scrollLeft=e.left,e.element.scrollTop=e.top}}var hr=c&&"documentMode"in document&&11>=document.documentMode,gr=null,vr=null,yr=null,br=!1;function kr(e,n,t){var r=t.window===t?t.document:9===t.nodeType?t:t.ownerDocument;br||null==gr||gr!==K(r)||("selectionStart"in(r=gr)&&pr(r)?r={start:r.selectionStart,end:r.selectionEnd
|
||||
}:r={anchorNode:(r=(r.ownerDocument&&r.ownerDocument.defaultView||window).getSelection()).anchorNode,anchorOffset:r.anchorOffset,focusNode:r.focusNode,focusOffset:r.focusOffset},yr&&ir(yr,r)||(yr=r,0<(r=Qr(vr,"onSelect")).length&&(n=new ct("onSelect","select",null,n,t),e.push({event:n,listeners:r}),n.target=gr)))}function wr(e,n){var t={};return t[e.toLowerCase()]=n.toLowerCase(),t["Webkit"+e]="webkit"+n,t["Moz"+e]="moz"+n,t}var Sr={animationend:wr("Animation","AnimationEnd"),animationiteration:wr("Animation","AnimationIteration"),animationstart:wr("Animation","AnimationStart"),transitionend:wr("Transition","TransitionEnd")},xr={},Er={};function Cr(e){if(xr[e])return xr[e];if(!Sr[e])return e;var n,t=Sr[e];for(n in t)if(t.hasOwnProperty(n)&&n in Er)return xr[e]=t[n];return e}c&&(Er=document.createElement("div").style,"AnimationEvent"in window||(delete Sr.animationend.animation,delete Sr.animationiteration.animation,delete Sr.animationstart.animation),"TransitionEvent"in window||delete Sr.transitionend.transition);var _r=Cr("animationend"),Pr=Cr("animationiteration"),Nr=Cr("animationstart"),zr=Cr("transitionend"),Tr=new Map,Lr="abort auxClick cancel canPlay canPlayThrough click close contextMenu copy cut drag dragEnd dragEnter dragExit dragLeave dragOver dragStart drop durationChange emptied encrypted ended error gotPointerCapture input invalid keyDown keyPress keyUp load loadedData loadedMetadata loadStart lostPointerCapture mouseDown mouseMove mouseOut mouseOver mouseUp paste pause play playing pointerCancel pointerDown pointerMove pointerOut pointerOver pointerUp progress rateChange reset resize seeked seeking stalled submit suspend timeUpdate touchCancel touchEnd touchStart volumeChange scroll toggle touchMove waiting wheel".split(" ");function Rr(e,n){Tr.set(e,n),i(n,[e])}for(var Mr=0;Mr<Lr.length;Mr++){var Fr=Lr[Mr];Rr(Fr.toLowerCase(),"on"+(Fr[0].toUpperCase()+Fr.slice(1)))}Rr(_r,"onAnimationEnd"),Rr(Pr,"onAnimationIteration"),Rr(Nr,"onAnimationStart"),Rr("dblclick","onDoubleClick"),Rr("focusin","onFocus"),Rr("focusout","onBlur"),Rr(zr,"onTransitionEnd"),s("onMouseEnter",["mouseout","mouseover"]),s("onMouseLeave",["mouseout","mouseover"]),s("onPointerEnter",["pointerout","pointerover"]),s("onPointerLeave",["pointerout","pointerover"]),i("onChange","change click focusin focusout input keydown keyup selectionchange".split(" ")),i("onSelect","focusout contextmenu dragend focusin keydown keyup mousedown mouseup selectionchange".split(" ")),i("onBeforeInput",["compositionend","keypress","textInput","paste"]),i("onCompositionEnd","compositionend focusout keydown keypress keyup mousedown".split(" ")),i("onCompositionStart","compositionstart focusout keydown keypress keyup mousedown".split(" ")),i("onCompositionUpdate","compositionupdate focusout keydown keypress keyup mousedown".split(" "))
|
||||
;var Or="abort canplay canplaythrough durationchange emptied encrypted ended error loadeddata loadedmetadata loadstart pause play playing progress ratechange resize seeked seeking stalled suspend timeupdate volumechange waiting".split(" "),Dr=new Set("cancel close invalid load scroll toggle".split(" ").concat(Or));function Ir(e,n,t){var r=e.type||"unknown-event";e.currentTarget=t,function(e,n,t,r,l,u,o,i,s){if($e.apply(this,arguments),De){if(!De)throw Error(a(198));var c=Ie;De=!1,Ie=null,Ue||(Ue=!0,Ve=c)}}(r,n,void 0,e),e.currentTarget=null}function Ur(e,n){n=!!(4&n);for(var t=0;t<e.length;t++){var r=e[t],l=r.event;r=r.listeners;e:{var a=void 0;if(n)for(var u=r.length-1;0<=u;u--){var o=r[u],i=o.instance,s=o.currentTarget;if(o=o.listener,i!==a&&l.isPropagationStopped())break e;Ir(l,o,s),a=i}else for(u=0;u<r.length;u++){if(i=(o=r[u]).instance,s=o.currentTarget,o=o.listener,i!==a&&l.isPropagationStopped())break e;Ir(l,o,s),a=i}}}if(Ue)throw e=Ve,Ue=!1,Ve=null,e}function Vr(e,n){var t=n[hl];void 0===t&&(t=n[hl]=new Set);var r=e+"__bubble";t.has(r)||(Br(n,e,2,!1),t.add(r))}function Ar(e,n,t){var r=0;n&&(r|=4),Br(t,e,r,n)}var $r="_reactListening"+Math.random().toString(36).slice(2);function jr(e){if(!e[$r]){e[$r]=!0,u.forEach((function(n){"selectionchange"!==n&&(Dr.has(n)||Ar(n,!1,e),Ar(n,!0,e))}));var n=9===e.nodeType?e:e.ownerDocument;null===n||n[$r]||(n[$r]=!0,Ar("selectionchange",!1,n))}}function Br(e,n,t,r){switch(Gn(n)){case 1:var l=Qn;break;case 4:l=qn;break;default:l=Kn}t=l.bind(null,n,t,e),l=void 0,!Me||"touchstart"!==n&&"touchmove"!==n&&"wheel"!==n||(l=!0),r?void 0!==l?e.addEventListener(n,t,{capture:!0,passive:l}):e.addEventListener(n,t,!0):void 0!==l?e.addEventListener(n,t,{passive:l}):e.addEventListener(n,t,!1)}function Hr(e,n,t,r,l){var a=r;if(!(1&n||2&n||null===r))e:for(;;){if(null===r)return;var u=r.tag;if(3===u||4===u){var o=r.stateNode.containerInfo;if(o===l||8===o.nodeType&&o.parentNode===l)break;if(4===u)for(u=r.return;null!==u;){var i=u.tag;if((3===i||4===i)&&((i=u.stateNode.containerInfo)===l||8===i.nodeType&&i.parentNode===l))return;u=u.return}for(;null!==o;){if(null===(u=yl(o)))return;if(5===(i=u.tag)||6===i){r=a=u;continue e}o=o.parentNode}}r=r.return}Le((function(){var r=a,l=we(t),u=[];e:{var o=Tr.get(e);if(void 0!==o){var i=ct,s=e;switch(e){case"keypress":if(0===tt(t))break e;case"keydown":case"keyup":i=Pt;break;case"focusin":s="focus",i=gt;break;case"focusout":s="blur",i=gt;break;case"beforeblur":case"afterblur":i=gt;break;case"click":if(2===t.button)break e;case"auxclick":case"dblclick":case"mousedown":case"mousemove":case"mouseup":case"mouseout":case"mouseover":case"contextmenu":i=mt;break;case"drag":case"dragend":case"dragenter":case"dragexit":case"dragleave":case"dragover":case"dragstart":case"drop":i=ht;break;case"touchcancel":case"touchend":case"touchmove":case"touchstart":i=zt;break;case _r:case Pr:case Nr:i=vt;break;case zr:i=Tt;break;case"scroll":i=dt;break;case"wheel":i=Rt;break;case"copy":case"cut":case"paste":i=bt;break;case"gotpointercapture":case"lostpointercapture":
|
||||
case"pointercancel":case"pointerdown":case"pointermove":case"pointerout":case"pointerover":case"pointerup":i=Nt}var c=!!(4&n),f=!c&&"scroll"===e,d=c?null!==o?o+"Capture":null:o;c=[];for(var p,m=r;null!==m;){var h=(p=m).stateNode;if(5===p.tag&&null!==h&&(p=h,null!==d&&(null!=(h=Re(m,d))&&c.push(Wr(m,h,p)))),f)break;m=m.return}0<c.length&&(o=new i(o,s,null,t,l),u.push({event:o,listeners:c}))}}if(!(7&n)){if(i="mouseout"===e||"pointerout"===e,(!(o="mouseover"===e||"pointerover"===e)||t===ke||!(s=t.relatedTarget||t.fromElement)||!yl(s)&&!s[ml])&&(i||o)&&(o=l.window===l?l:(o=l.ownerDocument)?o.defaultView||o.parentWindow:window,i?(i=r,null!==(s=(s=t.relatedTarget||t.toElement)?yl(s):null)&&(s!==(f=je(s))||5!==s.tag&&6!==s.tag)&&(s=null)):(i=null,s=r),i!==s)){if(c=mt,h="onMouseLeave",d="onMouseEnter",m="mouse","pointerout"!==e&&"pointerover"!==e||(c=Nt,h="onPointerLeave",d="onPointerEnter",m="pointer"),f=null==i?o:kl(i),p=null==s?o:kl(s),(o=new c(h,m+"leave",i,t,l)).target=f,o.relatedTarget=p,h=null,yl(l)===r&&((c=new c(d,m+"enter",s,t,l)).target=p,c.relatedTarget=f,h=c),f=h,i&&s)e:{for(d=s,m=0,p=c=i;p;p=qr(p))m++;for(p=0,h=d;h;h=qr(h))p++;for(;0<m-p;)c=qr(c),m--;for(;0<p-m;)d=qr(d),p--;for(;m--;){if(c===d||null!==d&&c===d.alternate)break e;c=qr(c),d=qr(d)}c=null}else c=null;null!==i&&Kr(u,o,i,c,!1),null!==s&&null!==f&&Kr(u,f,s,c,!0)}if("select"===(i=(o=r?kl(r):window).nodeName&&o.nodeName.toLowerCase())||"input"===i&&"file"===o.type)var g=Xt;else if(Ht(o))if(Gt)g=ur;else{g=lr;var v=rr}else(i=o.nodeName)&&"input"===i.toLowerCase()&&("checkbox"===o.type||"radio"===o.type)&&(g=ar);switch(g&&(g=g(e,r))?Wt(u,g,t,l):(v&&v(e,o,r),"focusout"===e&&(v=o._wrapperState)&&v.controlled&&"number"===o.type&&ee(o,"number",o.value)),v=r?kl(r):window,e){case"focusin":(Ht(v)||"true"===v.contentEditable)&&(gr=v,vr=r,yr=null);break;case"focusout":yr=vr=gr=null;break;case"mousedown":br=!0;break;case"contextmenu":case"mouseup":case"dragend":br=!1,kr(u,t,l);break;case"selectionchange":if(hr)break;case"keydown":case"keyup":kr(u,t,l)}var y;if(Ft)e:{switch(e){case"compositionstart":var b="onCompositionStart";break e;case"compositionend":b="onCompositionEnd";break e;case"compositionupdate":b="onCompositionUpdate";break e}b=void 0}else jt?At(e,t)&&(b="onCompositionEnd"):"keydown"===e&&229===t.keyCode&&(b="onCompositionStart");b&&(It&&"ko"!==t.locale&&(jt||"onCompositionStart"!==b?"onCompositionEnd"===b&&jt&&(y=nt()):(Jn="value"in(Zn=l)?Zn.value:Zn.textContent,jt=!0)),0<(v=Qr(r,b)).length&&(b=new kt(b,e,null,t,l),u.push({event:b,listeners:v}),y?b.data=y:null!==(y=$t(t))&&(b.data=y))),(y=Dt?function(e,n){switch(e){case"compositionend":return $t(n);case"keypress":return 32!==n.which?null:(Vt=!0,Ut);case"textInput":return(e=n.data)===Ut&&Vt?null:e;default:return null}}(e,t):function(e,n){if(jt)return"compositionend"===e||!Ft&&At(e,n)?(e=nt(),et=Jn=Zn=null,jt=!1,e):null;switch(e){case"paste":default:return null;case"keypress":if(!(n.ctrlKey||n.altKey||n.metaKey)||n.ctrlKey&&n.altKey){if(n.char&&1<n.char.length)return n.char
|
||||
;if(n.which)return String.fromCharCode(n.which)}return null;case"compositionend":return It&&"ko"!==n.locale?null:n.data}}(e,t))&&(0<(r=Qr(r,"onBeforeInput")).length&&(l=new kt("onBeforeInput","beforeinput",null,t,l),u.push({event:l,listeners:r}),l.data=y))}Ur(u,n)}))}function Wr(e,n,t){return{instance:e,listener:n,currentTarget:t}}function Qr(e,n){for(var t=n+"Capture",r=[];null!==e;){var l=e,a=l.stateNode;5===l.tag&&null!==a&&(l=a,null!=(a=Re(e,t))&&r.unshift(Wr(e,a,l)),null!=(a=Re(e,n))&&r.push(Wr(e,a,l))),e=e.return}return r}function qr(e){if(null===e)return null;do{e=e.return}while(e&&5!==e.tag);return e||null}function Kr(e,n,t,r,l){for(var a=n._reactName,u=[];null!==t&&t!==r;){var o=t,i=o.alternate,s=o.stateNode;if(null!==i&&i===r)break;5===o.tag&&null!==s&&(o=s,l?null!=(i=Re(t,a))&&u.unshift(Wr(t,i,o)):l||null!=(i=Re(t,a))&&u.push(Wr(t,i,o))),t=t.return}0!==u.length&&e.push({event:n,listeners:u})}var Yr=/\r\n?/g,Xr=/\u0000|\uFFFD/g;function Gr(e){return("string"==typeof e?e:""+e).replace(Yr,"\n").replace(Xr,"")}function Zr(e,n,t){if(n=Gr(n),Gr(e)!==n&&t)throw Error(a(425))}function Jr(){}var el=null,nl=null;function tl(e,n){return"textarea"===e||"noscript"===e||"string"==typeof n.children||"number"==typeof n.children||"object"==typeof n.dangerouslySetInnerHTML&&null!==n.dangerouslySetInnerHTML&&null!=n.dangerouslySetInnerHTML.__html}var rl="function"==typeof setTimeout?setTimeout:void 0,ll="function"==typeof clearTimeout?clearTimeout:void 0,al="function"==typeof Promise?Promise:void 0,ul="function"==typeof queueMicrotask?queueMicrotask:void 0!==al?function(e){return al.resolve(null).then(e).catch(ol)}:rl;function ol(e){setTimeout((function(){throw e}))}function il(e,n){var t=n,r=0;do{var l=t.nextSibling;if(e.removeChild(t),l&&8===l.nodeType)if("/$"===(t=l.data)){if(0===r)return e.removeChild(l),void Bn(n);r--}else"$"!==t&&"$?"!==t&&"$!"!==t||r++;t=l}while(t);Bn(n)}function sl(e){for(;null!=e;e=e.nextSibling){var n=e.nodeType;if(1===n||3===n)break;if(8===n){if("$"===(n=e.data)||"$!"===n||"$?"===n)break;if("/$"===n)return null}}return e}function cl(e){e=e.previousSibling;for(var n=0;e;){if(8===e.nodeType){var t=e.data;if("$"===t||"$!"===t||"$?"===t){if(0===n)return e;n--}else"/$"===t&&n++}e=e.previousSibling}return null}var fl=Math.random().toString(36).slice(2),dl="__reactFiber$"+fl,pl="__reactProps$"+fl,ml="__reactContainer$"+fl,hl="__reactEvents$"+fl,gl="__reactListeners$"+fl,vl="__reactHandles$"+fl;function yl(e){var n=e[dl];if(n)return n;for(var t=e.parentNode;t;){if(n=t[ml]||t[dl]){if(t=n.alternate,null!==n.child||null!==t&&null!==t.child)for(e=cl(e);null!==e;){if(t=e[dl])return t;e=cl(e)}return n}t=(e=t).parentNode}return null}function bl(e){return!(e=e[dl]||e[ml])||5!==e.tag&&6!==e.tag&&13!==e.tag&&3!==e.tag?null:e}function kl(e){if(5===e.tag||6===e.tag)return e.stateNode;throw Error(a(33))}function wl(e){return e[pl]||null}var Sl=[],xl=-1;function El(e){return{current:e}}function Cl(e){0>xl||(e.current=Sl[xl],Sl[xl]=null,xl--)}function _l(e,n){xl++,Sl[xl]=e.current,e.current=n}
|
||||
var Pl={},Nl=El(Pl),zl=El(!1),Tl=Pl;function Ll(e,n){var t=e.type.contextTypes;if(!t)return Pl;var r=e.stateNode;if(r&&r.__reactInternalMemoizedUnmaskedChildContext===n)return r.__reactInternalMemoizedMaskedChildContext;var l,a={};for(l in t)a[l]=n[l];return r&&((e=e.stateNode).__reactInternalMemoizedUnmaskedChildContext=n,e.__reactInternalMemoizedMaskedChildContext=a),a}function Rl(e){return null!=(e=e.childContextTypes)}function Ml(){Cl(zl),Cl(Nl)}function Fl(e,n,t){if(Nl.current!==Pl)throw Error(a(168));_l(Nl,n),_l(zl,t)}function Ol(e,n,t){var r=e.stateNode;if(n=n.childContextTypes,"function"!=typeof r.getChildContext)return t;for(var l in r=r.getChildContext())if(!(l in n))throw Error(a(108,B(e)||"Unknown",l));return I({},t,r)}function Dl(e){return e=(e=e.stateNode)&&e.__reactInternalMemoizedMergedChildContext||Pl,Tl=Nl.current,_l(Nl,e),_l(zl,zl.current),!0}function Il(e,n,t){var r=e.stateNode;if(!r)throw Error(a(169));t?(e=Ol(e,n,Tl),r.__reactInternalMemoizedMergedChildContext=e,Cl(zl),Cl(Nl),_l(Nl,e)):Cl(zl),_l(zl,t)}var Ul=null,Vl=!1,Al=!1;function $l(e){null===Ul?Ul=[e]:Ul.push(e)}function jl(){if(!Al&&null!==Ul){Al=!0;var e=0,n=kn;try{var t=Ul;for(kn=1;e<t.length;e++){var r=t[e];do{r=r(!0)}while(null!==r)}Ul=null,Vl=!1}catch(n){throw null!==Ul&&(Ul=Ul.slice(e+1)),qe(Je,jl),n}finally{kn=n,Al=!1}}return null}var Bl=[],Hl=0,Wl=null,Ql=0,ql=[],Kl=0,Yl=null,Xl=1,Gl="";function Zl(e,n){Bl[Hl++]=Ql,Bl[Hl++]=Wl,Wl=e,Ql=n}function Jl(e,n,t){ql[Kl++]=Xl,ql[Kl++]=Gl,ql[Kl++]=Yl,Yl=e;var r=Xl;e=Gl;var l=32-un(r)-1;r&=~(1<<l),t+=1;var a=32-un(n)+l;if(30<a){var u=l-l%5;a=(r&(1<<u)-1).toString(32),r>>=u,l-=u,Xl=1<<32-un(n)+l|t<<l|r,Gl=a+e}else Xl=1<<a|t<<l|r,Gl=e}function ea(e){null!==e.return&&(Zl(e,1),Jl(e,1,0))}function na(e){for(;e===Wl;)Wl=Bl[--Hl],Bl[Hl]=null,Ql=Bl[--Hl],Bl[Hl]=null;for(;e===Yl;)Yl=ql[--Kl],ql[Kl]=null,Gl=ql[--Kl],ql[Kl]=null,Xl=ql[--Kl],ql[Kl]=null}var ta=null,ra=null,la=!1,aa=null;function ua(e,n){var t=Rs(5,null,null,0);t.elementType="DELETED",t.stateNode=n,t.return=e,null===(n=e.deletions)?(e.deletions=[t],e.flags|=16):n.push(t)}function oa(e,n){switch(e.tag){case 5:var t=e.type;return null!==(n=1!==n.nodeType||t.toLowerCase()!==n.nodeName.toLowerCase()?null:n)&&(e.stateNode=n,ta=e,ra=sl(n.firstChild),!0);case 6:return null!==(n=""===e.pendingProps||3!==n.nodeType?null:n)&&(e.stateNode=n,ta=e,ra=null,!0);case 13:return null!==(n=8!==n.nodeType?null:n)&&(t=null!==Yl?{id:Xl,overflow:Gl}:null,e.memoizedState={dehydrated:n,treeContext:t,retryLane:1073741824},(t=Rs(18,null,null,0)).stateNode=n,t.return=e,e.child=t,ta=e,ra=null,!0);default:return!1}}function ia(e){return!(!(1&e.mode)||128&e.flags)}function sa(e){if(la){var n=ra;if(n){var t=n;if(!oa(e,n)){if(ia(e))throw Error(a(418));n=sl(t.nextSibling);var r=ta;n&&oa(e,n)?ua(r,t):(e.flags=-4097&e.flags|2,la=!1,ta=e)}}else{if(ia(e))throw Error(a(418));e.flags=-4097&e.flags|2,la=!1,ta=e}}}function ca(e){for(e=e.return;null!==e&&5!==e.tag&&3!==e.tag&&13!==e.tag;)e=e.return;ta=e}function fa(e){if(e!==ta)return!1;if(!la)return ca(e),la=!0,!1;var n
|
||||
;if((n=3!==e.tag)&&!(n=5!==e.tag)&&(n="head"!==(n=e.type)&&"body"!==n&&!tl(e.type,e.memoizedProps)),n&&(n=ra)){if(ia(e))throw da(),Error(a(418));for(;n;)ua(e,n),n=sl(n.nextSibling)}if(ca(e),13===e.tag){if(!(e=null!==(e=e.memoizedState)?e.dehydrated:null))throw Error(a(317));e:{for(e=e.nextSibling,n=0;e;){if(8===e.nodeType){var t=e.data;if("/$"===t){if(0===n){ra=sl(e.nextSibling);break e}n--}else"$"!==t&&"$!"!==t&&"$?"!==t||n++}e=e.nextSibling}ra=null}}else ra=ta?sl(e.stateNode.nextSibling):null;return!0}function da(){for(var e=ra;e;)e=sl(e.nextSibling)}function pa(){ra=ta=null,la=!1}function ma(e){null===aa?aa=[e]:aa.push(e)}var ha=k.ReactCurrentBatchConfig;function ga(e,n){if(e&&e.defaultProps){for(var t in n=I({},n),e=e.defaultProps)void 0===n[t]&&(n[t]=e[t]);return n}return n}var va=El(null),ya=null,ba=null,ka=null;function wa(){ka=ba=ya=null}function Sa(e){var n=va.current;Cl(va),e._currentValue=n}function xa(e,n,t){for(;null!==e;){var r=e.alternate;if((e.childLanes&n)!==n?(e.childLanes|=n,null!==r&&(r.childLanes|=n)):null!==r&&(r.childLanes&n)!==n&&(r.childLanes|=n),e===t)break;e=e.return}}function Ea(e,n){ya=e,ka=ba=null,null!==(e=e.dependencies)&&null!==e.firstContext&&(!!(e.lanes&n)&&(ko=!0),e.firstContext=null)}function Ca(e){var n=e._currentValue;if(ka!==e)if(e={context:e,memoizedValue:n,next:null},null===ba){if(null===ya)throw Error(a(308));ba=e,ya.dependencies={lanes:0,firstContext:e}}else ba=ba.next=e;return n}var _a=null;function Pa(e){null===_a?_a=[e]:_a.push(e)}function Na(e,n,t,r){var l=n.interleaved;return null===l?(t.next=t,Pa(n)):(t.next=l.next,l.next=t),n.interleaved=t,za(e,r)}function za(e,n){e.lanes|=n;var t=e.alternate;for(null!==t&&(t.lanes|=n),t=e,e=e.return;null!==e;)e.childLanes|=n,null!==(t=e.alternate)&&(t.childLanes|=n),t=e,e=e.return;return 3===t.tag?t.stateNode:null}var Ta=!1;function La(e){e.updateQueue={baseState:e.memoizedState,firstBaseUpdate:null,lastBaseUpdate:null,shared:{pending:null,interleaved:null,lanes:0},effects:null}}function Ra(e,n){e=e.updateQueue,n.updateQueue===e&&(n.updateQueue={baseState:e.baseState,firstBaseUpdate:e.firstBaseUpdate,lastBaseUpdate:e.lastBaseUpdate,shared:e.shared,effects:e.effects})}function Ma(e,n){return{eventTime:e,lane:n,tag:0,payload:null,callback:null,next:null}}function Fa(e,n,t){var r=e.updateQueue;if(null===r)return null;if(r=r.shared,2&zi){var l=r.pending;return null===l?n.next=n:(n.next=l.next,l.next=n),r.pending=n,za(e,t)}return null===(l=r.interleaved)?(n.next=n,Pa(r)):(n.next=l.next,l.next=n),r.interleaved=n,za(e,t)}function Oa(e,n,t){if(null!==(n=n.updateQueue)&&(n=n.shared,4194240&t)){var r=n.lanes;t|=r&=e.pendingLanes,n.lanes=t,bn(e,t)}}function Da(e,n){var t=e.updateQueue,r=e.alternate;if(null!==r&&t===(r=r.updateQueue)){var l=null,a=null;if(null!==(t=t.firstBaseUpdate)){do{var u={eventTime:t.eventTime,lane:t.lane,tag:t.tag,payload:t.payload,callback:t.callback,next:null};null===a?l=a=u:a=a.next=u,t=t.next}while(null!==t);null===a?l=a=n:a=a.next=n}else l=a=n;return t={baseState:r.baseState,firstBaseUpdate:l,lastBaseUpdate:a,
|
||||
shared:r.shared,effects:r.effects},void(e.updateQueue=t)}null===(e=t.lastBaseUpdate)?t.firstBaseUpdate=n:e.next=n,t.lastBaseUpdate=n}function Ia(e,n,t,r){var l=e.updateQueue;Ta=!1;var a=l.firstBaseUpdate,u=l.lastBaseUpdate,o=l.shared.pending;if(null!==o){l.shared.pending=null;var i=o,s=i.next;i.next=null,null===u?a=s:u.next=s,u=i;var c=e.alternate;null!==c&&((o=(c=c.updateQueue).lastBaseUpdate)!==u&&(null===o?c.firstBaseUpdate=s:o.next=s,c.lastBaseUpdate=i))}if(null!==a){var f=l.baseState;for(u=0,c=s=i=null,o=a;;){var d=o.lane,p=o.eventTime;if((r&d)===d){null!==c&&(c=c.next={eventTime:p,lane:0,tag:o.tag,payload:o.payload,callback:o.callback,next:null});e:{var m=e,h=o;switch(d=n,p=t,h.tag){case 1:if("function"==typeof(m=h.payload)){f=m.call(p,f,d);break e}f=m;break e;case 3:m.flags=-65537&m.flags|128;case 0:if(null==(d="function"==typeof(m=h.payload)?m.call(p,f,d):m))break e;f=I({},f,d);break e;case 2:Ta=!0}}null!==o.callback&&0!==o.lane&&(e.flags|=64,null===(d=l.effects)?l.effects=[o]:d.push(o))}else p={eventTime:p,lane:d,tag:o.tag,payload:o.payload,callback:o.callback,next:null},null===c?(s=c=p,i=f):c=c.next=p,u|=d;if(null===(o=o.next)){if(null===(o=l.shared.pending))break;o=(d=o).next,d.next=null,l.lastBaseUpdate=d,l.shared.pending=null}}if(null===c&&(i=f),l.baseState=i,l.firstBaseUpdate=s,l.lastBaseUpdate=c,null!==(n=l.shared.interleaved)){l=n;do{u|=l.lane,l=l.next}while(l!==n)}else null===a&&(l.shared.lanes=0);Ii|=u,e.lanes=u,e.memoizedState=f}}function Ua(e,n,t){if(e=n.effects,n.effects=null,null!==e)for(n=0;n<e.length;n++){var r=e[n],l=r.callback;if(null!==l){if(r.callback=null,r=t,"function"!=typeof l)throw Error(a(191,l));l.call(r)}}}var Va=(new r.Component).refs;function Aa(e,n,t,r){t=null==(t=t(r,n=e.memoizedState))?n:I({},n,t),e.memoizedState=t,0===e.lanes&&(e.updateQueue.baseState=t)}var $a={isMounted:function(e){return!!(e=e._reactInternals)&&je(e)===e},enqueueSetState:function(e,n,t){e=e._reactInternals;var r=ns(),l=ts(e),a=Ma(r,l);a.payload=n,null!=t&&(a.callback=t),null!==(n=Fa(e,a,l))&&(rs(n,e,l,r),Oa(n,e,l))},enqueueReplaceState:function(e,n,t){e=e._reactInternals;var r=ns(),l=ts(e),a=Ma(r,l);a.tag=1,a.payload=n,null!=t&&(a.callback=t),null!==(n=Fa(e,a,l))&&(rs(n,e,l,r),Oa(n,e,l))},enqueueForceUpdate:function(e,n){e=e._reactInternals;var t=ns(),r=ts(e),l=Ma(t,r);l.tag=2,null!=n&&(l.callback=n),null!==(n=Fa(e,l,r))&&(rs(n,e,r,t),Oa(n,e,r))}};function ja(e,n,t,r,l,a,u){return"function"==typeof(e=e.stateNode).shouldComponentUpdate?e.shouldComponentUpdate(r,a,u):!n.prototype||!n.prototype.isPureReactComponent||(!ir(t,r)||!ir(l,a))}function Ba(e,n,t){var r=!1,l=Pl,a=n.contextType;return"object"==typeof a&&null!==a?a=Ca(a):(l=Rl(n)?Tl:Nl.current,a=(r=null!=(r=n.contextTypes))?Ll(e,l):Pl),n=new n(t,a),e.memoizedState=null!==n.state&&void 0!==n.state?n.state:null,n.updater=$a,e.stateNode=n,n._reactInternals=e,r&&((e=e.stateNode).__reactInternalMemoizedUnmaskedChildContext=l,e.__reactInternalMemoizedMaskedChildContext=a),n}function Ha(e,n,t,r){e=n.state,
|
||||
"function"==typeof n.componentWillReceiveProps&&n.componentWillReceiveProps(t,r),"function"==typeof n.UNSAFE_componentWillReceiveProps&&n.UNSAFE_componentWillReceiveProps(t,r),n.state!==e&&$a.enqueueReplaceState(n,n.state,null)}function Wa(e,n,t,r){var l=e.stateNode;l.props=t,l.state=e.memoizedState,l.refs=Va,La(e);var a=n.contextType;"object"==typeof a&&null!==a?l.context=Ca(a):(a=Rl(n)?Tl:Nl.current,l.context=Ll(e,a)),l.state=e.memoizedState,"function"==typeof(a=n.getDerivedStateFromProps)&&(Aa(e,n,a,t),l.state=e.memoizedState),"function"==typeof n.getDerivedStateFromProps||"function"==typeof l.getSnapshotBeforeUpdate||"function"!=typeof l.UNSAFE_componentWillMount&&"function"!=typeof l.componentWillMount||(n=l.state,"function"==typeof l.componentWillMount&&l.componentWillMount(),"function"==typeof l.UNSAFE_componentWillMount&&l.UNSAFE_componentWillMount(),n!==l.state&&$a.enqueueReplaceState(l,l.state,null),Ia(e,t,l,r),l.state=e.memoizedState),"function"==typeof l.componentDidMount&&(e.flags|=4194308)}function Qa(e,n,t){if(null!==(e=t.ref)&&"function"!=typeof e&&"object"!=typeof e){if(t._owner){if(t=t._owner){if(1!==t.tag)throw Error(a(309));var r=t.stateNode}if(!r)throw Error(a(147,e));var l=r,u=""+e;return null!==n&&null!==n.ref&&"function"==typeof n.ref&&n.ref._stringRef===u?n.ref:(n=function(e){var n=l.refs;n===Va&&(n=l.refs={}),null===e?delete n[u]:n[u]=e},n._stringRef=u,n)}if("string"!=typeof e)throw Error(a(284));if(!t._owner)throw Error(a(290,e))}return e}function qa(e,n){throw e=Object.prototype.toString.call(n),Error(a(31,"[object Object]"===e?"object with keys {"+Object.keys(n).join(", ")+"}":e))}function Ka(e){return(0,e._init)(e._payload)}function Ya(e){function n(n,t){if(e){var r=n.deletions;null===r?(n.deletions=[t],n.flags|=16):r.push(t)}}function t(t,r){if(!e)return null;for(;null!==r;)n(t,r),r=r.sibling;return null}function r(e,n){for(e=new Map;null!==n;)null!==n.key?e.set(n.key,n):e.set(n.index,n),n=n.sibling;return e}function l(e,n){return(e=Fs(e,n)).index=0,e.sibling=null,e}function u(n,t,r){return n.index=r,e?null!==(r=n.alternate)?(r=r.index)<t?(n.flags|=2,t):r:(n.flags|=2,t):(n.flags|=1048576,t)}function o(n){return e&&null===n.alternate&&(n.flags|=2),n}function i(e,n,t,r){return null===n||6!==n.tag?((n=Us(t,e.mode,r)).return=e,n):((n=l(n,t)).return=e,n)}function s(e,n,t,r){var a=t.type;return a===x?f(e,n,t.props.children,r,t.key):null!==n&&(n.elementType===a||"object"==typeof a&&null!==a&&a.$$typeof===R&&Ka(a)===n.type)?((r=l(n,t.props)).ref=Qa(e,n,t),r.return=e,r):((r=Os(t.type,t.key,t.props,null,e.mode,r)).ref=Qa(e,n,t),r.return=e,r)}function c(e,n,t,r){return null===n||4!==n.tag||n.stateNode.containerInfo!==t.containerInfo||n.stateNode.implementation!==t.implementation?((n=Vs(t,e.mode,r)).return=e,n):((n=l(n,t.children||[])).return=e,n)}function f(e,n,t,r,a){return null===n||7!==n.tag?((n=Ds(t,e.mode,r,a)).return=e,n):((n=l(n,t)).return=e,n)}function d(e,n,t){if("string"==typeof n&&""!==n||"number"==typeof n)return(n=Us(""+n,e.mode,t)).return=e,n;if("object"==typeof n&&null!==n){
|
||||
switch(n.$$typeof){case w:return(t=Os(n.type,n.key,n.props,null,e.mode,t)).ref=Qa(e,null,n),t.return=e,t;case S:return(n=Vs(n,e.mode,t)).return=e,n;case R:return d(e,(0,n._init)(n._payload),t)}if(ne(n)||O(n))return(n=Ds(n,e.mode,t,null)).return=e,n;qa(e,n)}return null}function p(e,n,t,r){var l=null!==n?n.key:null;if("string"==typeof t&&""!==t||"number"==typeof t)return null!==l?null:i(e,n,""+t,r);if("object"==typeof t&&null!==t){switch(t.$$typeof){case w:return t.key===l?s(e,n,t,r):null;case S:return t.key===l?c(e,n,t,r):null;case R:return p(e,n,(l=t._init)(t._payload),r)}if(ne(t)||O(t))return null!==l?null:f(e,n,t,r,null);qa(e,t)}return null}function m(e,n,t,r,l){if("string"==typeof r&&""!==r||"number"==typeof r)return i(n,e=e.get(t)||null,""+r,l);if("object"==typeof r&&null!==r){switch(r.$$typeof){case w:return s(n,e=e.get(null===r.key?t:r.key)||null,r,l);case S:return c(n,e=e.get(null===r.key?t:r.key)||null,r,l);case R:return m(e,n,t,(0,r._init)(r._payload),l)}if(ne(r)||O(r))return f(n,e=e.get(t)||null,r,l,null);qa(n,r)}return null}function h(l,a,o,i){for(var s=null,c=null,f=a,h=a=0,g=null;null!==f&&h<o.length;h++){f.index>h?(g=f,f=null):g=f.sibling;var v=p(l,f,o[h],i);if(null===v){null===f&&(f=g);break}e&&f&&null===v.alternate&&n(l,f),a=u(v,a,h),null===c?s=v:c.sibling=v,c=v,f=g}if(h===o.length)return t(l,f),la&&Zl(l,h),s;if(null===f){for(;h<o.length;h++)null!==(f=d(l,o[h],i))&&(a=u(f,a,h),null===c?s=f:c.sibling=f,c=f);return la&&Zl(l,h),s}for(f=r(l,f);h<o.length;h++)null!==(g=m(f,l,h,o[h],i))&&(e&&null!==g.alternate&&f.delete(null===g.key?h:g.key),a=u(g,a,h),null===c?s=g:c.sibling=g,c=g);return e&&f.forEach((function(e){return n(l,e)})),la&&Zl(l,h),s}function g(l,o,i,s){var c=O(i);if("function"!=typeof c)throw Error(a(150));if(null==(i=c.call(i)))throw Error(a(151));for(var f=c=null,h=o,g=o=0,v=null,y=i.next();null!==h&&!y.done;g++,y=i.next()){h.index>g?(v=h,h=null):v=h.sibling;var b=p(l,h,y.value,s);if(null===b){null===h&&(h=v);break}e&&h&&null===b.alternate&&n(l,h),o=u(b,o,g),null===f?c=b:f.sibling=b,f=b,h=v}if(y.done)return t(l,h),la&&Zl(l,g),c;if(null===h){for(;!y.done;g++,y=i.next())null!==(y=d(l,y.value,s))&&(o=u(y,o,g),null===f?c=y:f.sibling=y,f=y);return la&&Zl(l,g),c}for(h=r(l,h);!y.done;g++,y=i.next())null!==(y=m(h,l,g,y.value,s))&&(e&&null!==y.alternate&&h.delete(null===y.key?g:y.key),o=u(y,o,g),null===f?c=y:f.sibling=y,f=y);return e&&h.forEach((function(e){return n(l,e)})),la&&Zl(l,g),c}return function e(r,a,u,i){if("object"==typeof u&&null!==u&&u.type===x&&null===u.key&&(u=u.props.children),"object"==typeof u&&null!==u){switch(u.$$typeof){case w:e:{for(var s=u.key,c=a;null!==c;){if(c.key===s){if((s=u.type)===x){if(7===c.tag){t(r,c.sibling),(a=l(c,u.props.children)).return=r,r=a;break e}}else if(c.elementType===s||"object"==typeof s&&null!==s&&s.$$typeof===R&&Ka(s)===c.type){t(r,c.sibling),(a=l(c,u.props)).ref=Qa(r,c,u),a.return=r,r=a;break e}t(r,c);break}n(r,c),c=c.sibling}u.type===x?((a=Ds(u.props.children,r.mode,i,u.key)).return=r,r=a):((i=Os(u.type,u.key,u.props,null,r.mode,i)).ref=Qa(r,a,u),
|
||||
i.return=r,r=i)}return o(r);case S:e:{for(c=u.key;null!==a;){if(a.key===c){if(4===a.tag&&a.stateNode.containerInfo===u.containerInfo&&a.stateNode.implementation===u.implementation){t(r,a.sibling),(a=l(a,u.children||[])).return=r,r=a;break e}t(r,a);break}n(r,a),a=a.sibling}(a=Vs(u,r.mode,i)).return=r,r=a}return o(r);case R:return e(r,a,(c=u._init)(u._payload),i)}if(ne(u))return h(r,a,u,i);if(O(u))return g(r,a,u,i);qa(r,u)}return"string"==typeof u&&""!==u||"number"==typeof u?(u=""+u,null!==a&&6===a.tag?(t(r,a.sibling),(a=l(a,u)).return=r,r=a):(t(r,a),(a=Us(u,r.mode,i)).return=r,r=a),o(r)):t(r,a)}}var Xa=Ya(!0),Ga=Ya(!1),Za={},Ja=El(Za),eu=El(Za),nu=El(Za);function tu(e){if(e===Za)throw Error(a(174));return e}function ru(e,n){switch(_l(nu,n),_l(eu,e),_l(Ja,Za),e=n.nodeType){case 9:case 11:n=(n=n.documentElement)?n.namespaceURI:ie(null,"");break;default:n=ie(n=(e=8===e?n.parentNode:n).namespaceURI||null,e=e.tagName)}Cl(Ja),_l(Ja,n)}function lu(){Cl(Ja),Cl(eu),Cl(nu)}function au(e){tu(nu.current);var n=tu(Ja.current),t=ie(n,e.type);n!==t&&(_l(eu,e),_l(Ja,t))}function uu(e){eu.current===e&&(Cl(Ja),Cl(eu))}var ou=El(0);function iu(e){for(var n=e;null!==n;){if(13===n.tag){var t=n.memoizedState;if(null!==t&&(null===(t=t.dehydrated)||"$?"===t.data||"$!"===t.data))return n}else if(19===n.tag&&void 0!==n.memoizedProps.revealOrder){if(128&n.flags)return n}else if(null!==n.child){n.child.return=n,n=n.child;continue}if(n===e)break;for(;null===n.sibling;){if(null===n.return||n.return===e)return null;n=n.return}n.sibling.return=n.return,n=n.sibling}return null}var su=[];function cu(){for(var e=0;e<su.length;e++)su[e]._workInProgressVersionPrimary=null;su.length=0}var fu=k.ReactCurrentDispatcher,du=k.ReactCurrentBatchConfig,pu=0,mu=null,hu=null,gu=null,vu=!1,yu=!1,bu=0,ku=0;function wu(){throw Error(a(321))}function Su(e,n){if(null===n)return!1;for(var t=0;t<n.length&&t<e.length;t++)if(!or(e[t],n[t]))return!1;return!0}function xu(e,n,t,r,l,u){if(pu=u,mu=n,n.memoizedState=null,n.updateQueue=null,n.lanes=0,fu.current=null===e||null===e.memoizedState?uo:oo,e=t(r,l),yu){u=0;do{if(yu=!1,bu=0,25<=u)throw Error(a(301));u+=1,gu=hu=null,n.updateQueue=null,fu.current=io,e=t(r,l)}while(yu)}if(fu.current=ao,n=null!==hu&&null!==hu.next,pu=0,gu=hu=mu=null,vu=!1,n)throw Error(a(300));return e}function Eu(){var e=0!==bu;return bu=0,e}function Cu(){var e={memoizedState:null,baseState:null,baseQueue:null,queue:null,next:null};return null===gu?mu.memoizedState=gu=e:gu=gu.next=e,gu}function _u(){if(null===hu){var e=mu.alternate;e=null!==e?e.memoizedState:null}else e=hu.next;var n=null===gu?mu.memoizedState:gu.next;if(null!==n)gu=n,hu=e;else{if(null===e)throw Error(a(310));e={memoizedState:(hu=e).memoizedState,baseState:hu.baseState,baseQueue:hu.baseQueue,queue:hu.queue,next:null},null===gu?mu.memoizedState=gu=e:gu=gu.next=e}return gu}function Pu(e,n){return"function"==typeof n?n(e):n}function Nu(e){var n=_u(),t=n.queue;if(null===t)throw Error(a(311));t.lastRenderedReducer=e;var r=hu,l=r.baseQueue,u=t.pending;if(null!==u){if(null!==l){var o=l.next
|
||||
;l.next=u.next,u.next=o}r.baseQueue=l=u,t.pending=null}if(null!==l){u=l.next,r=r.baseState;var i=o=null,s=null,c=u;do{var f=c.lane;if((pu&f)===f)null!==s&&(s=s.next={lane:0,action:c.action,hasEagerState:c.hasEagerState,eagerState:c.eagerState,next:null}),r=c.hasEagerState?c.eagerState:e(r,c.action);else{var d={lane:f,action:c.action,hasEagerState:c.hasEagerState,eagerState:c.eagerState,next:null};null===s?(i=s=d,o=r):s=s.next=d,mu.lanes|=f,Ii|=f}c=c.next}while(null!==c&&c!==u);null===s?o=r:s.next=i,or(r,n.memoizedState)||(ko=!0),n.memoizedState=r,n.baseState=o,n.baseQueue=s,t.lastRenderedState=r}if(null!==(e=t.interleaved)){l=e;do{u=l.lane,mu.lanes|=u,Ii|=u,l=l.next}while(l!==e)}else null===l&&(t.lanes=0);return[n.memoizedState,t.dispatch]}function zu(e){var n=_u(),t=n.queue;if(null===t)throw Error(a(311));t.lastRenderedReducer=e;var r=t.dispatch,l=t.pending,u=n.memoizedState;if(null!==l){t.pending=null;var o=l=l.next;do{u=e(u,o.action),o=o.next}while(o!==l);or(u,n.memoizedState)||(ko=!0),n.memoizedState=u,null===n.baseQueue&&(n.baseState=u),t.lastRenderedState=u}return[u,r]}function Tu(){}function Lu(e,n){var t=mu,r=_u(),l=n(),u=!or(r.memoizedState,l);if(u&&(r.memoizedState=l,ko=!0),r=r.queue,Bu(Fu.bind(null,t,r,e),[e]),r.getSnapshot!==n||u||null!==gu&&1&gu.memoizedState.tag){if(t.flags|=2048,Uu(9,Mu.bind(null,t,r,l,n),void 0,null),null===Ti)throw Error(a(349));30&pu||Ru(t,n,l)}return l}function Ru(e,n,t){e.flags|=16384,e={getSnapshot:n,value:t},null===(n=mu.updateQueue)?(n={lastEffect:null,stores:null},mu.updateQueue=n,n.stores=[e]):null===(t=n.stores)?n.stores=[e]:t.push(e)}function Mu(e,n,t,r){n.value=t,n.getSnapshot=r,Ou(n)&&Du(e)}function Fu(e,n,t){return t((function(){Ou(n)&&Du(e)}))}function Ou(e){var n=e.getSnapshot;e=e.value;try{var t=n();return!or(e,t)}catch(e){return!0}}function Du(e){var n=za(e,1);null!==n&&rs(n,e,1,-1)}function Iu(e){var n=Cu();return"function"==typeof e&&(e=e()),n.memoizedState=n.baseState=e,e={pending:null,interleaved:null,lanes:0,dispatch:null,lastRenderedReducer:Pu,lastRenderedState:e},n.queue=e,e=e.dispatch=no.bind(null,mu,e),[n.memoizedState,e]}function Uu(e,n,t,r){return e={tag:e,create:n,destroy:t,deps:r,next:null},null===(n=mu.updateQueue)?(n={lastEffect:null,stores:null},mu.updateQueue=n,n.lastEffect=e.next=e):null===(t=n.lastEffect)?n.lastEffect=e.next=e:(r=t.next,t.next=e,e.next=r,n.lastEffect=e),e}function Vu(){return _u().memoizedState}function Au(e,n,t,r){var l=Cu();mu.flags|=e,l.memoizedState=Uu(1|n,t,void 0,void 0===r?null:r)}function $u(e,n,t,r){var l=_u();r=void 0===r?null:r;var a=void 0;if(null!==hu){var u=hu.memoizedState;if(a=u.destroy,null!==r&&Su(r,u.deps))return void(l.memoizedState=Uu(n,t,a,r))}mu.flags|=e,l.memoizedState=Uu(1|n,t,a,r)}function ju(e,n){return Au(8390656,8,e,n)}function Bu(e,n){return $u(2048,8,e,n)}function Hu(e,n){return $u(4,2,e,n)}function Wu(e,n){return $u(4,4,e,n)}function Qu(e,n){return"function"==typeof n?(e=e(),n(e),function(){n(null)}):null!=n?(e=e(),n.current=e,function(){n.current=null}):void 0}function qu(e,n,t){
|
||||
return t=null!=t?t.concat([e]):null,$u(4,4,Qu.bind(null,n,e),t)}function Ku(){}function Yu(e,n){var t=_u();n=void 0===n?null:n;var r=t.memoizedState;return null!==r&&null!==n&&Su(n,r[1])?r[0]:(t.memoizedState=[e,n],e)}function Xu(e,n){var t=_u();n=void 0===n?null:n;var r=t.memoizedState;return null!==r&&null!==n&&Su(n,r[1])?r[0]:(e=e(),t.memoizedState=[e,n],e)}function Gu(e,n,t){return 21&pu?(or(t,n)||(t=gn(),mu.lanes|=t,Ii|=t,e.baseState=!0),n):(e.baseState&&(e.baseState=!1,ko=!0),e.memoizedState=t)}function Zu(e,n){var t=kn;kn=0!==t&&4>t?t:4,e(!0);var r=du.transition;du.transition={};try{e(!1),n()}finally{kn=t,du.transition=r}}function Ju(){return _u().memoizedState}function eo(e,n,t){var r=ts(e);if(t={lane:r,action:t,hasEagerState:!1,eagerState:null,next:null},to(e))ro(n,t);else if(null!==(t=Na(e,n,t,r))){rs(t,e,r,ns()),lo(t,n,r)}}function no(e,n,t){var r=ts(e),l={lane:r,action:t,hasEagerState:!1,eagerState:null,next:null};if(to(e))ro(n,l);else{var a=e.alternate;if(0===e.lanes&&(null===a||0===a.lanes)&&null!==(a=n.lastRenderedReducer))try{var u=n.lastRenderedState,o=a(u,t);if(l.hasEagerState=!0,l.eagerState=o,or(o,u)){var i=n.interleaved;return null===i?(l.next=l,Pa(n)):(l.next=i.next,i.next=l),void(n.interleaved=l)}}catch(e){}null!==(t=Na(e,n,l,r))&&(rs(t,e,r,l=ns()),lo(t,n,r))}}function to(e){var n=e.alternate;return e===mu||null!==n&&n===mu}function ro(e,n){yu=vu=!0;var t=e.pending;null===t?n.next=n:(n.next=t.next,t.next=n),e.pending=n}function lo(e,n,t){if(4194240&t){var r=n.lanes;t|=r&=e.pendingLanes,n.lanes=t,bn(e,t)}}var ao={readContext:Ca,useCallback:wu,useContext:wu,useEffect:wu,useImperativeHandle:wu,useInsertionEffect:wu,useLayoutEffect:wu,useMemo:wu,useReducer:wu,useRef:wu,useState:wu,useDebugValue:wu,useDeferredValue:wu,useTransition:wu,useMutableSource:wu,useSyncExternalStore:wu,useId:wu,unstable_isNewReconciler:!1},uo={readContext:Ca,useCallback:function(e,n){return Cu().memoizedState=[e,void 0===n?null:n],e},useContext:Ca,useEffect:ju,useImperativeHandle:function(e,n,t){return t=null!=t?t.concat([e]):null,Au(4194308,4,Qu.bind(null,n,e),t)},useLayoutEffect:function(e,n){return Au(4194308,4,e,n)},useInsertionEffect:function(e,n){return Au(4,2,e,n)},useMemo:function(e,n){var t=Cu();return n=void 0===n?null:n,e=e(),t.memoizedState=[e,n],e},useReducer:function(e,n,t){var r=Cu();return n=void 0!==t?t(n):n,r.memoizedState=r.baseState=n,e={pending:null,interleaved:null,lanes:0,dispatch:null,lastRenderedReducer:e,lastRenderedState:n},r.queue=e,e=e.dispatch=eo.bind(null,mu,e),[r.memoizedState,e]},useRef:function(e){return e={current:e},Cu().memoizedState=e},useState:Iu,useDebugValue:Ku,useDeferredValue:function(e){return Cu().memoizedState=e},useTransition:function(){var e=Iu(!1),n=e[0];return e=Zu.bind(null,e[1]),Cu().memoizedState=e,[n,e]},useMutableSource:function(){},useSyncExternalStore:function(e,n,t){var r=mu,l=Cu();if(la){if(void 0===t)throw Error(a(407));t=t()}else{if(t=n(),null===Ti)throw Error(a(349));30&pu||Ru(r,n,t)}l.memoizedState=t;var u={value:t,getSnapshot:n};return l.queue=u,
|
||||
ju(Fu.bind(null,r,u,e),[e]),r.flags|=2048,Uu(9,Mu.bind(null,r,u,t,n),void 0,null),t},useId:function(){var e=Cu(),n=Ti.identifierPrefix;if(la){var t=Gl;n=":"+n+"R"+(t=(Xl&~(1<<32-un(Xl)-1)).toString(32)+t),0<(t=bu++)&&(n+="H"+t.toString(32)),n+=":"}else n=":"+n+"r"+(t=ku++).toString(32)+":";return e.memoizedState=n},unstable_isNewReconciler:!1},oo={readContext:Ca,useCallback:Yu,useContext:Ca,useEffect:Bu,useImperativeHandle:qu,useInsertionEffect:Hu,useLayoutEffect:Wu,useMemo:Xu,useReducer:Nu,useRef:Vu,useState:function(){return Nu(Pu)},useDebugValue:Ku,useDeferredValue:function(e){return Gu(_u(),hu.memoizedState,e)},useTransition:function(){return[Nu(Pu)[0],_u().memoizedState]},useMutableSource:Tu,useSyncExternalStore:Lu,useId:Ju,unstable_isNewReconciler:!1},io={readContext:Ca,useCallback:Yu,useContext:Ca,useEffect:Bu,useImperativeHandle:qu,useInsertionEffect:Hu,useLayoutEffect:Wu,useMemo:Xu,useReducer:zu,useRef:Vu,useState:function(){return zu(Pu)},useDebugValue:Ku,useDeferredValue:function(e){var n=_u();return null===hu?n.memoizedState=e:Gu(n,hu.memoizedState,e)},useTransition:function(){return[zu(Pu)[0],_u().memoizedState]},useMutableSource:Tu,useSyncExternalStore:Lu,useId:Ju,unstable_isNewReconciler:!1};function so(e,n){try{var t="",r=n;do{t+=$(r),r=r.return}while(r);var l=t}catch(e){l="\nError generating stack: "+e.message+"\n"+e.stack}return{value:e,source:n,stack:l,digest:null}}function co(e,n,t){return{value:e,source:null,stack:null!=t?t:null,digest:null!=n?n:null}}function fo(e,n){try{console.error(n.value)}catch(e){setTimeout((function(){throw e}))}}var po="function"==typeof WeakMap?WeakMap:Map;function mo(e,n,t){(t=Ma(-1,t)).tag=3,t.payload={element:null};var r=n.value;return t.callback=function(){Wi||(Wi=!0,Qi=r),fo(0,n)},t}function ho(e,n,t){(t=Ma(-1,t)).tag=3;var r=e.type.getDerivedStateFromError;if("function"==typeof r){var l=n.value;t.payload=function(){return r(l)},t.callback=function(){fo(0,n)}}var a=e.stateNode;return null!==a&&"function"==typeof a.componentDidCatch&&(t.callback=function(){fo(0,n),"function"!=typeof r&&(null===qi?qi=new Set([this]):qi.add(this));var e=n.stack;this.componentDidCatch(n.value,{componentStack:null!==e?e:""})}),t}function go(e,n,t){var r=e.pingCache;if(null===r){r=e.pingCache=new po;var l=new Set;r.set(n,l)}else void 0===(l=r.get(n))&&(l=new Set,r.set(n,l));l.has(t)||(l.add(t),e=_s.bind(null,e,n,t),n.then(e,e))}function vo(e){do{var n;if((n=13===e.tag)&&(n=null===(n=e.memoizedState)||null!==n.dehydrated),n)return e;e=e.return}while(null!==e);return null}function yo(e,n,t,r,l){return 1&e.mode?(e.flags|=65536,e.lanes=l,e):(e===n?e.flags|=65536:(e.flags|=128,t.flags|=131072,t.flags&=-52805,1===t.tag&&(null===t.alternate?t.tag=17:((n=Ma(-1,1)).tag=2,Fa(t,n,1))),t.lanes|=1),e)}var bo=k.ReactCurrentOwner,ko=!1;function wo(e,n,t,r){n.child=null===e?Ga(n,null,t,r):Xa(n,e.child,t,r)}function So(e,n,t,r,l){t=t.render;var a=n.ref;return Ea(n,l),r=xu(e,n,t,r,a,l),t=Eu(),null===e||ko?(la&&t&&ea(n),n.flags|=1,wo(e,n,r,l),n.child):(n.updateQueue=e.updateQueue,n.flags&=-2053,
|
||||
e.lanes&=~l,Wo(e,n,l))}function xo(e,n,t,r,l){if(null===e){var a=t.type;return"function"!=typeof a||Ms(a)||void 0!==a.defaultProps||null!==t.compare||void 0!==t.defaultProps?((e=Os(t.type,null,r,n,n.mode,l)).ref=n.ref,e.return=n,n.child=e):(n.tag=15,n.type=a,Eo(e,n,a,r,l))}if(a=e.child,!(e.lanes&l)){var u=a.memoizedProps;if((t=null!==(t=t.compare)?t:ir)(u,r)&&e.ref===n.ref)return Wo(e,n,l)}return n.flags|=1,(e=Fs(a,r)).ref=n.ref,e.return=n,n.child=e}function Eo(e,n,t,r,l){if(null!==e){var a=e.memoizedProps;if(ir(a,r)&&e.ref===n.ref){if(ko=!1,n.pendingProps=r=a,!(e.lanes&l))return n.lanes=e.lanes,Wo(e,n,l);131072&e.flags&&(ko=!0)}}return Po(e,n,t,r,l)}function Co(e,n,t){var r=n.pendingProps,l=r.children,a=null!==e?e.memoizedState:null;if("hidden"===r.mode)if(1&n.mode){if(!(1073741824&t))return e=null!==a?a.baseLanes|t:t,n.lanes=n.childLanes=1073741824,n.memoizedState={baseLanes:e,cachePool:null,transitions:null},n.updateQueue=null,_l(Fi,Mi),Mi|=e,null;n.memoizedState={baseLanes:0,cachePool:null,transitions:null},r=null!==a?a.baseLanes:t,_l(Fi,Mi),Mi|=r}else n.memoizedState={baseLanes:0,cachePool:null,transitions:null},_l(Fi,Mi),Mi|=t;else null!==a?(r=a.baseLanes|t,n.memoizedState=null):r=t,_l(Fi,Mi),Mi|=r;return wo(e,n,l,t),n.child}function _o(e,n){var t=n.ref;(null===e&&null!==t||null!==e&&e.ref!==t)&&(n.flags|=512,n.flags|=2097152)}function Po(e,n,t,r,l){var a=Rl(t)?Tl:Nl.current;return a=Ll(n,a),Ea(n,l),t=xu(e,n,t,r,a,l),r=Eu(),null===e||ko?(la&&r&&ea(n),n.flags|=1,wo(e,n,t,l),n.child):(n.updateQueue=e.updateQueue,n.flags&=-2053,e.lanes&=~l,Wo(e,n,l))}function No(e,n,t,r,l){if(Rl(t)){var a=!0;Dl(n)}else a=!1;if(Ea(n,l),null===n.stateNode)Ho(e,n),Ba(n,t,r),Wa(n,t,r,l),r=!0;else if(null===e){var u=n.stateNode,o=n.memoizedProps;u.props=o;var i=u.context,s=t.contextType;"object"==typeof s&&null!==s?s=Ca(s):s=Ll(n,s=Rl(t)?Tl:Nl.current);var c=t.getDerivedStateFromProps,f="function"==typeof c||"function"==typeof u.getSnapshotBeforeUpdate;f||"function"!=typeof u.UNSAFE_componentWillReceiveProps&&"function"!=typeof u.componentWillReceiveProps||(o!==r||i!==s)&&Ha(n,u,r,s),Ta=!1;var d=n.memoizedState;u.state=d,Ia(n,r,u,l),i=n.memoizedState,o!==r||d!==i||zl.current||Ta?("function"==typeof c&&(Aa(n,t,c,r),i=n.memoizedState),(o=Ta||ja(n,t,o,r,d,i,s))?(f||"function"!=typeof u.UNSAFE_componentWillMount&&"function"!=typeof u.componentWillMount||("function"==typeof u.componentWillMount&&u.componentWillMount(),"function"==typeof u.UNSAFE_componentWillMount&&u.UNSAFE_componentWillMount()),"function"==typeof u.componentDidMount&&(n.flags|=4194308)):("function"==typeof u.componentDidMount&&(n.flags|=4194308),n.memoizedProps=r,n.memoizedState=i),u.props=r,u.state=i,u.context=s,r=o):("function"==typeof u.componentDidMount&&(n.flags|=4194308),r=!1)}else{u=n.stateNode,Ra(e,n),o=n.memoizedProps,s=n.type===n.elementType?o:ga(n.type,o),u.props=s,f=n.pendingProps,d=u.context,"object"==typeof(i=t.contextType)&&null!==i?i=Ca(i):i=Ll(n,i=Rl(t)?Tl:Nl.current);var p=t.getDerivedStateFromProps
|
||||
;(c="function"==typeof p||"function"==typeof u.getSnapshotBeforeUpdate)||"function"!=typeof u.UNSAFE_componentWillReceiveProps&&"function"!=typeof u.componentWillReceiveProps||(o!==f||d!==i)&&Ha(n,u,r,i),Ta=!1,d=n.memoizedState,u.state=d,Ia(n,r,u,l);var m=n.memoizedState;o!==f||d!==m||zl.current||Ta?("function"==typeof p&&(Aa(n,t,p,r),m=n.memoizedState),(s=Ta||ja(n,t,s,r,d,m,i)||!1)?(c||"function"!=typeof u.UNSAFE_componentWillUpdate&&"function"!=typeof u.componentWillUpdate||("function"==typeof u.componentWillUpdate&&u.componentWillUpdate(r,m,i),"function"==typeof u.UNSAFE_componentWillUpdate&&u.UNSAFE_componentWillUpdate(r,m,i)),"function"==typeof u.componentDidUpdate&&(n.flags|=4),"function"==typeof u.getSnapshotBeforeUpdate&&(n.flags|=1024)):("function"!=typeof u.componentDidUpdate||o===e.memoizedProps&&d===e.memoizedState||(n.flags|=4),"function"!=typeof u.getSnapshotBeforeUpdate||o===e.memoizedProps&&d===e.memoizedState||(n.flags|=1024),n.memoizedProps=r,n.memoizedState=m),u.props=r,u.state=m,u.context=i,r=s):("function"!=typeof u.componentDidUpdate||o===e.memoizedProps&&d===e.memoizedState||(n.flags|=4),"function"!=typeof u.getSnapshotBeforeUpdate||o===e.memoizedProps&&d===e.memoizedState||(n.flags|=1024),r=!1)}return zo(e,n,t,r,a,l)}function zo(e,n,t,r,l,a){_o(e,n);var u=!!(128&n.flags);if(!r&&!u)return l&&Il(n,t,!1),Wo(e,n,a);r=n.stateNode,bo.current=n;var o=u&&"function"!=typeof t.getDerivedStateFromError?null:r.render();return n.flags|=1,null!==e&&u?(n.child=Xa(n,e.child,null,a),n.child=Xa(n,null,o,a)):wo(e,n,o,a),n.memoizedState=r.state,l&&Il(n,t,!0),n.child}function To(e){var n=e.stateNode;n.pendingContext?Fl(0,n.pendingContext,n.pendingContext!==n.context):n.context&&Fl(0,n.context,!1),ru(e,n.containerInfo)}function Lo(e,n,t,r,l){return pa(),ma(l),n.flags|=256,wo(e,n,t,r),n.child}var Ro,Mo,Fo,Oo,Do={dehydrated:null,treeContext:null,retryLane:0};function Io(e){return{baseLanes:e,cachePool:null,transitions:null}}function Uo(e,n,t){var r,l=n.pendingProps,u=ou.current,o=!1,i=!!(128&n.flags);if((r=i)||(r=(null===e||null!==e.memoizedState)&&!!(2&u)),r?(o=!0,n.flags&=-129):null!==e&&null===e.memoizedState||(u|=1),_l(ou,1&u),null===e)return sa(n),null!==(e=n.memoizedState)&&null!==(e=e.dehydrated)?(1&n.mode?"$!"===e.data?n.lanes=8:n.lanes=1073741824:n.lanes=1,null):(i=l.children,e=l.fallback,o?(l=n.mode,o=n.child,i={mode:"hidden",children:i},1&l||null===o?o=Is(i,l,0,null):(o.childLanes=0,o.pendingProps=i),e=Ds(e,l,t,null),o.return=n,e.return=n,o.sibling=e,n.child=o,n.child.memoizedState=Io(t),n.memoizedState=Do,e):Vo(n,i));if(null!==(u=e.memoizedState)&&null!==(r=u.dehydrated))return function(e,n,t,r,l,u,o){if(t)return 256&n.flags?(n.flags&=-257,Ao(e,n,o,r=co(Error(a(422))))):null!==n.memoizedState?(n.child=e.child,n.flags|=128,null):(u=r.fallback,l=n.mode,r=Is({mode:"visible",children:r.children},l,0,null),(u=Ds(u,l,o,null)).flags|=2,r.return=n,u.return=n,r.sibling=u,n.child=r,1&n.mode&&Xa(n,e.child,null,o),n.child.memoizedState=Io(o),n.memoizedState=Do,u);if(!(1&n.mode))return Ao(e,n,o,null)
|
||||
;if("$!"===l.data){if(r=l.nextSibling&&l.nextSibling.dataset)var i=r.dgst;return r=i,Ao(e,n,o,r=co(u=Error(a(419)),r,void 0))}if(i=!!(o&e.childLanes),ko||i){if(null!==(r=Ti)){switch(o&-o){case 4:l=2;break;case 16:l=8;break;case 64: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:case 4194304:case 8388608:case 16777216:case 33554432:case 67108864:l=32;break;case 536870912:l=268435456;break;default:l=0}0!==(l=l&(r.suspendedLanes|o)?0:l)&&l!==u.retryLane&&(u.retryLane=l,za(e,l),rs(r,e,l,-1))}return gs(),Ao(e,n,o,r=co(Error(a(421))))}return"$?"===l.data?(n.flags|=128,n.child=e.child,n=Ns.bind(null,e),l._reactRetry=n,null):(e=u.treeContext,ra=sl(l.nextSibling),ta=n,la=!0,aa=null,null!==e&&(ql[Kl++]=Xl,ql[Kl++]=Gl,ql[Kl++]=Yl,Xl=e.id,Gl=e.overflow,Yl=n),n=Vo(n,r.children),n.flags|=4096,n)}(e,n,i,l,r,u,t);if(o){o=l.fallback,i=n.mode,r=(u=e.child).sibling;var s={mode:"hidden",children:l.children};return 1&i||n.child===u?(l=Fs(u,s)).subtreeFlags=14680064&u.subtreeFlags:((l=n.child).childLanes=0,l.pendingProps=s,n.deletions=null),null!==r?o=Fs(r,o):(o=Ds(o,i,t,null)).flags|=2,o.return=n,l.return=n,l.sibling=o,n.child=l,l=o,o=n.child,i=null===(i=e.child.memoizedState)?Io(t):{baseLanes:i.baseLanes|t,cachePool:null,transitions:i.transitions},o.memoizedState=i,o.childLanes=e.childLanes&~t,n.memoizedState=Do,l}return e=(o=e.child).sibling,l=Fs(o,{mode:"visible",children:l.children}),!(1&n.mode)&&(l.lanes=t),l.return=n,l.sibling=null,null!==e&&(null===(t=n.deletions)?(n.deletions=[e],n.flags|=16):t.push(e)),n.child=l,n.memoizedState=null,l}function Vo(e,n){return(n=Is({mode:"visible",children:n},e.mode,0,null)).return=e,e.child=n}function Ao(e,n,t,r){return null!==r&&ma(r),Xa(n,e.child,null,t),(e=Vo(n,n.pendingProps.children)).flags|=2,n.memoizedState=null,e}function $o(e,n,t){e.lanes|=n;var r=e.alternate;null!==r&&(r.lanes|=n),xa(e.return,n,t)}function jo(e,n,t,r,l){var a=e.memoizedState;null===a?e.memoizedState={isBackwards:n,rendering:null,renderingStartTime:0,last:r,tail:t,tailMode:l}:(a.isBackwards=n,a.rendering=null,a.renderingStartTime=0,a.last=r,a.tail=t,a.tailMode=l)}function Bo(e,n,t){var r=n.pendingProps,l=r.revealOrder,a=r.tail;if(wo(e,n,r.children,t),2&(r=ou.current))r=1&r|2,n.flags|=128;else{if(null!==e&&128&e.flags)e:for(e=n.child;null!==e;){if(13===e.tag)null!==e.memoizedState&&$o(e,t,n);else if(19===e.tag)$o(e,t,n);else if(null!==e.child){e.child.return=e,e=e.child;continue}if(e===n)break e;for(;null===e.sibling;){if(null===e.return||e.return===n)break e;e=e.return}e.sibling.return=e.return,e=e.sibling}r&=1}if(_l(ou,r),1&n.mode)switch(l){case"forwards":for(t=n.child,l=null;null!==t;)null!==(e=t.alternate)&&null===iu(e)&&(l=t),t=t.sibling;null===(t=l)?(l=n.child,n.child=null):(l=t.sibling,t.sibling=null),jo(n,!1,l,t,a);break;case"backwards":for(t=null,l=n.child,n.child=null;null!==l;){if(null!==(e=l.alternate)&&null===iu(e)){n.child=l;break}e=l.sibling,l.sibling=t,t=l,l=e}jo(n,!0,t,null,a);break
|
||||
;case"together":jo(n,!1,null,null,void 0);break;default:n.memoizedState=null}else n.memoizedState=null;return n.child}function Ho(e,n){!(1&n.mode)&&null!==e&&(e.alternate=null,n.alternate=null,n.flags|=2)}function Wo(e,n,t){if(null!==e&&(n.dependencies=e.dependencies),Ii|=n.lanes,!(t&n.childLanes))return null;if(null!==e&&n.child!==e.child)throw Error(a(153));if(null!==n.child){for(t=Fs(e=n.child,e.pendingProps),n.child=t,t.return=n;null!==e.sibling;)e=e.sibling,(t=t.sibling=Fs(e,e.pendingProps)).return=n;t.sibling=null}return n.child}function Qo(e,n){if(!la)switch(e.tailMode){case"hidden":n=e.tail;for(var t=null;null!==n;)null!==n.alternate&&(t=n),n=n.sibling;null===t?e.tail=null:t.sibling=null;break;case"collapsed":t=e.tail;for(var r=null;null!==t;)null!==t.alternate&&(r=t),t=t.sibling;null===r?n||null===e.tail?e.tail=null:e.tail.sibling=null:r.sibling=null}}function qo(e){var n=null!==e.alternate&&e.alternate.child===e.child,t=0,r=0;if(n)for(var l=e.child;null!==l;)t|=l.lanes|l.childLanes,r|=14680064&l.subtreeFlags,r|=14680064&l.flags,l.return=e,l=l.sibling;else for(l=e.child;null!==l;)t|=l.lanes|l.childLanes,r|=l.subtreeFlags,r|=l.flags,l.return=e,l=l.sibling;return e.subtreeFlags|=r,e.childLanes=t,n}function Ko(e,n,t){var r=n.pendingProps;switch(na(n),n.tag){case 2:case 16:case 15:case 0:case 11:case 7:case 8:case 12:case 9:case 14:return qo(n),null;case 1:case 17:return Rl(n.type)&&Ml(),qo(n),null;case 3:return r=n.stateNode,lu(),Cl(zl),Cl(Nl),cu(),r.pendingContext&&(r.context=r.pendingContext,r.pendingContext=null),null!==e&&null!==e.child||(fa(n)?n.flags|=4:null===e||e.memoizedState.isDehydrated&&!(256&n.flags)||(n.flags|=1024,null!==aa&&(os(aa),aa=null))),Mo(e,n),qo(n),null;case 5:uu(n);var l=tu(nu.current);if(t=n.type,null!==e&&null!=n.stateNode)Fo(e,n,t,r,l),e.ref!==n.ref&&(n.flags|=512,n.flags|=2097152);else{if(!r){if(null===n.stateNode)throw Error(a(166));return qo(n),null}if(e=tu(Ja.current),fa(n)){r=n.stateNode,t=n.type;var u=n.memoizedProps;switch(r[dl]=n,r[pl]=u,e=!!(1&n.mode),t){case"dialog":Vr("cancel",r),Vr("close",r);break;case"iframe":case"object":case"embed":Vr("load",r);break;case"video":case"audio":for(l=0;l<Or.length;l++)Vr(Or[l],r);break;case"source":Vr("error",r);break;case"img":case"image":case"link":Vr("error",r),Vr("load",r);break;case"details":Vr("toggle",r);break;case"input":X(r,u),Vr("invalid",r);break;case"select":r._wrapperState={wasMultiple:!!u.multiple},Vr("invalid",r);break;case"textarea":le(r,u),Vr("invalid",r)}for(var i in ye(t,u),l=null,u)if(u.hasOwnProperty(i)){var s=u[i];"children"===i?"string"==typeof s?r.textContent!==s&&(!0!==u.suppressHydrationWarning&&Zr(r.textContent,s,e),l=["children",s]):"number"==typeof s&&r.textContent!==""+s&&(!0!==u.suppressHydrationWarning&&Zr(r.textContent,s,e),l=["children",""+s]):o.hasOwnProperty(i)&&null!=s&&"onScroll"===i&&Vr("scroll",r)}switch(t){case"input":Q(r),J(r,u,!0);break;case"textarea":Q(r),ue(r);break;case"select":case"option":break;default:"function"==typeof u.onClick&&(r.onclick=Jr)}r=l,n.updateQueue=r,null!==r&&(n.flags|=4)
|
||||
}else{i=9===l.nodeType?l:l.ownerDocument,"http://www.w3.org/1999/xhtml"===e&&(e=oe(t)),"http://www.w3.org/1999/xhtml"===e?"script"===t?((e=i.createElement("div")).innerHTML="<script><\/script>",e=e.removeChild(e.firstChild)):"string"==typeof r.is?e=i.createElement(t,{is:r.is}):(e=i.createElement(t),"select"===t&&(i=e,r.multiple?i.multiple=!0:r.size&&(i.size=r.size))):e=i.createElementNS(e,t),e[dl]=n,e[pl]=r,Ro(e,n,!1,!1),n.stateNode=e;e:{switch(i=be(t,r),t){case"dialog":Vr("cancel",e),Vr("close",e),l=r;break;case"iframe":case"object":case"embed":Vr("load",e),l=r;break;case"video":case"audio":for(l=0;l<Or.length;l++)Vr(Or[l],e);l=r;break;case"source":Vr("error",e),l=r;break;case"img":case"image":case"link":Vr("error",e),Vr("load",e),l=r;break;case"details":Vr("toggle",e),l=r;break;case"input":X(e,r),l=Y(e,r),Vr("invalid",e);break;case"option":default:l=r;break;case"select":e._wrapperState={wasMultiple:!!r.multiple},l=I({},r,{value:void 0}),Vr("invalid",e);break;case"textarea":le(e,r),l=re(e,r),Vr("invalid",e)}for(u in ye(t,l),s=l)if(s.hasOwnProperty(u)){var c=s[u];"style"===u?ge(e,c):"dangerouslySetInnerHTML"===u?null!=(c=c?c.__html:void 0)&&fe(e,c):"children"===u?"string"==typeof c?("textarea"!==t||""!==c)&&de(e,c):"number"==typeof c&&de(e,""+c):"suppressContentEditableWarning"!==u&&"suppressHydrationWarning"!==u&&"autoFocus"!==u&&(o.hasOwnProperty(u)?null!=c&&"onScroll"===u&&Vr("scroll",e):null!=c&&b(e,u,c,i))}switch(t){case"input":Q(e),J(e,r,!1);break;case"textarea":Q(e),ue(e);break;case"option":null!=r.value&&e.setAttribute("value",""+H(r.value));break;case"select":e.multiple=!!r.multiple,null!=(u=r.value)?te(e,!!r.multiple,u,!1):null!=r.defaultValue&&te(e,!!r.multiple,r.defaultValue,!0);break;default:"function"==typeof l.onClick&&(e.onclick=Jr)}switch(t){case"button":case"input":case"select":case"textarea":r=!!r.autoFocus;break e;case"img":r=!0;break e;default:r=!1}}r&&(n.flags|=4)}null!==n.ref&&(n.flags|=512,n.flags|=2097152)}return qo(n),null;case 6:if(e&&null!=n.stateNode)Oo(e,n,e.memoizedProps,r);else{if("string"!=typeof r&&null===n.stateNode)throw Error(a(166));if(t=tu(nu.current),tu(Ja.current),fa(n)){if(r=n.stateNode,t=n.memoizedProps,r[dl]=n,(u=r.nodeValue!==t)&&null!==(e=ta))switch(e.tag){case 3:Zr(r.nodeValue,t,!!(1&e.mode));break;case 5:!0!==e.memoizedProps.suppressHydrationWarning&&Zr(r.nodeValue,t,!!(1&e.mode))}u&&(n.flags|=4)}else(r=(9===t.nodeType?t:t.ownerDocument).createTextNode(r))[dl]=n,n.stateNode=r}return qo(n),null;case 13:if(Cl(ou),r=n.memoizedState,null===e||null!==e.memoizedState&&null!==e.memoizedState.dehydrated){if(la&&null!==ra&&1&n.mode&&!(128&n.flags))da(),pa(),n.flags|=98560,u=!1;else if(u=fa(n),null!==r&&null!==r.dehydrated){if(null===e){if(!u)throw Error(a(318));if(!(u=null!==(u=n.memoizedState)?u.dehydrated:null))throw Error(a(317));u[dl]=n}else pa(),!(128&n.flags)&&(n.memoizedState=null),n.flags|=4;qo(n),u=!1}else null!==aa&&(os(aa),aa=null),u=!0;if(!u)return 65536&n.flags?n:null}return 128&n.flags?(n.lanes=t,
|
||||
n):((r=null!==r)!==(null!==e&&null!==e.memoizedState)&&r&&(n.child.flags|=8192,1&n.mode&&(null===e||1&ou.current?0===Oi&&(Oi=3):gs())),null!==n.updateQueue&&(n.flags|=4),qo(n),null);case 4:return lu(),Mo(e,n),null===e&&jr(n.stateNode.containerInfo),qo(n),null;case 10:return Sa(n.type._context),qo(n),null;case 19:if(Cl(ou),null===(u=n.memoizedState))return qo(n),null;if(r=!!(128&n.flags),null===(i=u.rendering))if(r)Qo(u,!1);else{if(0!==Oi||null!==e&&128&e.flags)for(e=n.child;null!==e;){if(null!==(i=iu(e))){for(n.flags|=128,Qo(u,!1),null!==(r=i.updateQueue)&&(n.updateQueue=r,n.flags|=4),n.subtreeFlags=0,r=t,t=n.child;null!==t;)e=r,(u=t).flags&=14680066,null===(i=u.alternate)?(u.childLanes=0,u.lanes=e,u.child=null,u.subtreeFlags=0,u.memoizedProps=null,u.memoizedState=null,u.updateQueue=null,u.dependencies=null,u.stateNode=null):(u.childLanes=i.childLanes,u.lanes=i.lanes,u.child=i.child,u.subtreeFlags=0,u.deletions=null,u.memoizedProps=i.memoizedProps,u.memoizedState=i.memoizedState,u.updateQueue=i.updateQueue,u.type=i.type,e=i.dependencies,u.dependencies=null===e?null:{lanes:e.lanes,firstContext:e.firstContext}),t=t.sibling;return _l(ou,1&ou.current|2),n.child}e=e.sibling}null!==u.tail&&Ge()>Bi&&(n.flags|=128,r=!0,Qo(u,!1),n.lanes=4194304)}else{if(!r)if(null!==(e=iu(i))){if(n.flags|=128,r=!0,null!==(t=e.updateQueue)&&(n.updateQueue=t,n.flags|=4),Qo(u,!0),null===u.tail&&"hidden"===u.tailMode&&!i.alternate&&!la)return qo(n),null}else 2*Ge()-u.renderingStartTime>Bi&&1073741824!==t&&(n.flags|=128,r=!0,Qo(u,!1),n.lanes=4194304);u.isBackwards?(i.sibling=n.child,n.child=i):(null!==(t=u.last)?t.sibling=i:n.child=i,u.last=i)}return null!==u.tail?(n=u.tail,u.rendering=n,u.tail=n.sibling,u.renderingStartTime=Ge(),n.sibling=null,t=ou.current,_l(ou,r?1&t|2:1&t),n):(qo(n),null);case 22:case 23:return ds(),r=null!==n.memoizedState,null!==e&&null!==e.memoizedState!==r&&(n.flags|=8192),r&&1&n.mode?!!(1073741824&Mi)&&(qo(n),6&n.subtreeFlags&&(n.flags|=8192)):qo(n),null;case 24:case 25:return null}throw Error(a(156,n.tag))}function Yo(e,n){switch(na(n),n.tag){case 1:return Rl(n.type)&&Ml(),65536&(e=n.flags)?(n.flags=-65537&e|128,n):null;case 3:return lu(),Cl(zl),Cl(Nl),cu(),65536&(e=n.flags)&&!(128&e)?(n.flags=-65537&e|128,n):null;case 5:return uu(n),null;case 13:if(Cl(ou),null!==(e=n.memoizedState)&&null!==e.dehydrated){if(null===n.alternate)throw Error(a(340));pa()}return 65536&(e=n.flags)?(n.flags=-65537&e|128,n):null;case 19:return Cl(ou),null;case 4:return lu(),null;case 10:return Sa(n.type._context),null;case 22:case 23:return ds(),null;default:return null}}Ro=function(e,n){for(var t=n.child;null!==t;){if(5===t.tag||6===t.tag)e.appendChild(t.stateNode);else if(4!==t.tag&&null!==t.child){t.child.return=t,t=t.child;continue}if(t===n)break;for(;null===t.sibling;){if(null===t.return||t.return===n)return;t=t.return}t.sibling.return=t.return,t=t.sibling}},Mo=function(){},Fo=function(e,n,t,r){var l=e.memoizedProps;if(l!==r){e=n.stateNode,tu(Ja.current);var a,u=null;switch(t){case"input":l=Y(e,l),r=Y(e,r),u=[];break;case"select":l=I({},l,{
|
||||
value:void 0}),r=I({},r,{value:void 0}),u=[];break;case"textarea":l=re(e,l),r=re(e,r),u=[];break;default:"function"!=typeof l.onClick&&"function"==typeof r.onClick&&(e.onclick=Jr)}for(c in ye(t,r),t=null,l)if(!r.hasOwnProperty(c)&&l.hasOwnProperty(c)&&null!=l[c])if("style"===c){var i=l[c];for(a in i)i.hasOwnProperty(a)&&(t||(t={}),t[a]="")}else"dangerouslySetInnerHTML"!==c&&"children"!==c&&"suppressContentEditableWarning"!==c&&"suppressHydrationWarning"!==c&&"autoFocus"!==c&&(o.hasOwnProperty(c)?u||(u=[]):(u=u||[]).push(c,null));for(c in r){var s=r[c];if(i=null!=l?l[c]:void 0,r.hasOwnProperty(c)&&s!==i&&(null!=s||null!=i))if("style"===c)if(i){for(a in i)!i.hasOwnProperty(a)||s&&s.hasOwnProperty(a)||(t||(t={}),t[a]="");for(a in s)s.hasOwnProperty(a)&&i[a]!==s[a]&&(t||(t={}),t[a]=s[a])}else t||(u||(u=[]),u.push(c,t)),t=s;else"dangerouslySetInnerHTML"===c?(s=s?s.__html:void 0,i=i?i.__html:void 0,null!=s&&i!==s&&(u=u||[]).push(c,s)):"children"===c?"string"!=typeof s&&"number"!=typeof s||(u=u||[]).push(c,""+s):"suppressContentEditableWarning"!==c&&"suppressHydrationWarning"!==c&&(o.hasOwnProperty(c)?(null!=s&&"onScroll"===c&&Vr("scroll",e),u||i===s||(u=[])):(u=u||[]).push(c,s))}t&&(u=u||[]).push("style",t);var c=u;(n.updateQueue=c)&&(n.flags|=4)}},Oo=function(e,n,t,r){t!==r&&(n.flags|=4)};var Xo=!1,Go=!1,Zo="function"==typeof WeakSet?WeakSet:Set,Jo=null;function ei(e,n){var t=e.ref;if(null!==t)if("function"==typeof t)try{t(null)}catch(t){Cs(e,n,t)}else t.current=null}function ni(e,n,t){try{t()}catch(t){Cs(e,n,t)}}var ti=!1;function ri(e,n,t){var r=n.updateQueue;if(null!==(r=null!==r?r.lastEffect:null)){var l=r=r.next;do{if((l.tag&e)===e){var a=l.destroy;l.destroy=void 0,void 0!==a&&ni(n,t,a)}l=l.next}while(l!==r)}}function li(e,n){if(null!==(n=null!==(n=n.updateQueue)?n.lastEffect:null)){var t=n=n.next;do{if((t.tag&e)===e){var r=t.create;t.destroy=r()}t=t.next}while(t!==n)}}function ai(e){var n=e.ref;if(null!==n){var t=e.stateNode;e.tag,e=t,"function"==typeof n?n(e):n.current=e}}function ui(e){var n=e.alternate;null!==n&&(e.alternate=null,ui(n)),e.child=null,e.deletions=null,e.sibling=null,5===e.tag&&(null!==(n=e.stateNode)&&(delete n[dl],delete n[pl],delete n[hl],delete n[gl],delete n[vl])),e.stateNode=null,e.return=null,e.dependencies=null,e.memoizedProps=null,e.memoizedState=null,e.pendingProps=null,e.stateNode=null,e.updateQueue=null}function oi(e){return 5===e.tag||3===e.tag||4===e.tag}function ii(e){e:for(;;){for(;null===e.sibling;){if(null===e.return||oi(e.return))return null;e=e.return}for(e.sibling.return=e.return,e=e.sibling;5!==e.tag&&6!==e.tag&&18!==e.tag;){if(2&e.flags)continue e;if(null===e.child||4===e.tag)continue e;e.child.return=e,e=e.child}if(!(2&e.flags))return e.stateNode}}function si(e,n,t){var r=e.tag;if(5===r||6===r)e=e.stateNode,n?8===t.nodeType?t.parentNode.insertBefore(e,n):t.insertBefore(e,n):(8===t.nodeType?(n=t.parentNode).insertBefore(e,t):(n=t).appendChild(e),null!=(t=t._reactRootContainer)||null!==n.onclick||(n.onclick=Jr));else if(4!==r&&null!==(e=e.child))for(si(e,n,t),
|
||||
e=e.sibling;null!==e;)si(e,n,t),e=e.sibling}function ci(e,n,t){var r=e.tag;if(5===r||6===r)e=e.stateNode,n?t.insertBefore(e,n):t.appendChild(e);else if(4!==r&&null!==(e=e.child))for(ci(e,n,t),e=e.sibling;null!==e;)ci(e,n,t),e=e.sibling}var fi=null,di=!1;function pi(e,n,t){for(t=t.child;null!==t;)mi(e,n,t),t=t.sibling}function mi(e,n,t){if(an&&"function"==typeof an.onCommitFiberUnmount)try{an.onCommitFiberUnmount(ln,t)}catch(e){}switch(t.tag){case 5:Go||ei(t,n);case 6:var r=fi,l=di;fi=null,pi(e,n,t),di=l,null!==(fi=r)&&(di?(e=fi,t=t.stateNode,8===e.nodeType?e.parentNode.removeChild(t):e.removeChild(t)):fi.removeChild(t.stateNode));break;case 18:null!==fi&&(di?(e=fi,t=t.stateNode,8===e.nodeType?il(e.parentNode,t):1===e.nodeType&&il(e,t),Bn(e)):il(fi,t.stateNode));break;case 4:r=fi,l=di,fi=t.stateNode.containerInfo,di=!0,pi(e,n,t),fi=r,di=l;break;case 0:case 11:case 14:case 15:if(!Go&&(null!==(r=t.updateQueue)&&null!==(r=r.lastEffect))){l=r=r.next;do{var a=l,u=a.destroy;a=a.tag,void 0!==u&&(2&a||4&a)&&ni(t,n,u),l=l.next}while(l!==r)}pi(e,n,t);break;case 1:if(!Go&&(ei(t,n),"function"==typeof(r=t.stateNode).componentWillUnmount))try{r.props=t.memoizedProps,r.state=t.memoizedState,r.componentWillUnmount()}catch(e){Cs(t,n,e)}pi(e,n,t);break;case 21:pi(e,n,t);break;case 22:1&t.mode?(Go=(r=Go)||null!==t.memoizedState,pi(e,n,t),Go=r):pi(e,n,t);break;default:pi(e,n,t)}}function hi(e){var n=e.updateQueue;if(null!==n){e.updateQueue=null;var t=e.stateNode;null===t&&(t=e.stateNode=new Zo),n.forEach((function(n){var r=zs.bind(null,e,n);t.has(n)||(t.add(n),n.then(r,r))}))}}function gi(e,n){var t=n.deletions;if(null!==t)for(var r=0;r<t.length;r++){var l=t[r];try{var u=e,o=n,i=o;e:for(;null!==i;){switch(i.tag){case 5:fi=i.stateNode,di=!1;break e;case 3:case 4:fi=i.stateNode.containerInfo,di=!0;break e}i=i.return}if(null===fi)throw Error(a(160));mi(u,o,l),fi=null,di=!1;var s=l.alternate;null!==s&&(s.return=null),l.return=null}catch(e){Cs(l,n,e)}}if(12854&n.subtreeFlags)for(n=n.child;null!==n;)vi(n,e),n=n.sibling}function vi(e,n){var t=e.alternate,r=e.flags;switch(e.tag){case 0:case 11:case 14:case 15:if(gi(n,e),yi(e),4&r){try{ri(3,e,e.return),li(3,e)}catch(n){Cs(e,e.return,n)}try{ri(5,e,e.return)}catch(n){Cs(e,e.return,n)}}break;case 1:gi(n,e),yi(e),512&r&&null!==t&&ei(t,t.return);break;case 5:if(gi(n,e),yi(e),512&r&&null!==t&&ei(t,t.return),32&e.flags){var l=e.stateNode;try{de(l,"")}catch(n){Cs(e,e.return,n)}}if(4&r&&null!=(l=e.stateNode)){var u=e.memoizedProps,o=null!==t?t.memoizedProps:u,i=e.type,s=e.updateQueue;if(e.updateQueue=null,null!==s)try{"input"===i&&"radio"===u.type&&null!=u.name&&G(l,u),be(i,o);var c=be(i,u);for(o=0;o<s.length;o+=2){var f=s[o],d=s[o+1];"style"===f?ge(l,d):"dangerouslySetInnerHTML"===f?fe(l,d):"children"===f?de(l,d):b(l,f,d,c)}switch(i){case"input":Z(l,u);break;case"textarea":ae(l,u);break;case"select":var p=l._wrapperState.wasMultiple;l._wrapperState.wasMultiple=!!u.multiple;var m=u.value
|
||||
;null!=m?te(l,!!u.multiple,m,!1):p!==!!u.multiple&&(null!=u.defaultValue?te(l,!!u.multiple,u.defaultValue,!0):te(l,!!u.multiple,u.multiple?[]:"",!1))}l[pl]=u}catch(n){Cs(e,e.return,n)}}break;case 6:if(gi(n,e),yi(e),4&r){if(null===e.stateNode)throw Error(a(162));l=e.stateNode,u=e.memoizedProps;try{l.nodeValue=u}catch(n){Cs(e,e.return,n)}}break;case 3:if(gi(n,e),yi(e),4&r&&null!==t&&t.memoizedState.isDehydrated)try{Bn(n.containerInfo)}catch(n){Cs(e,e.return,n)}break;case 4:default:gi(n,e),yi(e);break;case 13:gi(n,e),yi(e),8192&(l=e.child).flags&&(u=null!==l.memoizedState,l.stateNode.isHidden=u,!u||null!==l.alternate&&null!==l.alternate.memoizedState||(ji=Ge())),4&r&&hi(e);break;case 22:if(f=null!==t&&null!==t.memoizedState,1&e.mode?(Go=(c=Go)||f,gi(n,e),Go=c):gi(n,e),yi(e),8192&r){if(c=null!==e.memoizedState,(e.stateNode.isHidden=c)&&!f&&1&e.mode)for(Jo=e,f=e.child;null!==f;){for(d=Jo=f;null!==Jo;){switch(m=(p=Jo).child,p.tag){case 0:case 11:case 14:case 15:ri(4,p,p.return);break;case 1:ei(p,p.return);var h=p.stateNode;if("function"==typeof h.componentWillUnmount){r=p,t=p.return;try{n=r,h.props=n.memoizedProps,h.state=n.memoizedState,h.componentWillUnmount()}catch(e){Cs(r,t,e)}}break;case 5:ei(p,p.return);break;case 22:if(null!==p.memoizedState){Si(d);continue}}null!==m?(m.return=p,Jo=m):Si(d)}f=f.sibling}e:for(f=null,d=e;;){if(5===d.tag){if(null===f){f=d;try{l=d.stateNode,c?"function"==typeof(u=l.style).setProperty?u.setProperty("display","none","important"):u.display="none":(i=d.stateNode,o=null!=(s=d.memoizedProps.style)&&s.hasOwnProperty("display")?s.display:null,i.style.display=he("display",o))}catch(n){Cs(e,e.return,n)}}}else if(6===d.tag){if(null===f)try{d.stateNode.nodeValue=c?"":d.memoizedProps}catch(n){Cs(e,e.return,n)}}else if((22!==d.tag&&23!==d.tag||null===d.memoizedState||d===e)&&null!==d.child){d.child.return=d,d=d.child;continue}if(d===e)break e;for(;null===d.sibling;){if(null===d.return||d.return===e)break e;f===d&&(f=null),d=d.return}f===d&&(f=null),d.sibling.return=d.return,d=d.sibling}}break;case 19:gi(n,e),yi(e),4&r&&hi(e);case 21:}}function yi(e){var n=e.flags;if(2&n){try{e:{for(var t=e.return;null!==t;){if(oi(t)){var r=t;break e}t=t.return}throw Error(a(160))}switch(r.tag){case 5:var l=r.stateNode;32&r.flags&&(de(l,""),r.flags&=-33),ci(e,ii(e),l);break;case 3:case 4:var u=r.stateNode.containerInfo;si(e,ii(e),u);break;default:throw Error(a(161))}}catch(n){Cs(e,e.return,n)}e.flags&=-3}4096&n&&(e.flags&=-4097)}function bi(e,n,t){Jo=e,ki(e,n,t)}function ki(e,n,t){for(var r=!!(1&e.mode);null!==Jo;){var l=Jo,a=l.child;if(22===l.tag&&r){var u=null!==l.memoizedState||Xo;if(!u){var o=l.alternate,i=null!==o&&null!==o.memoizedState||Go;o=Xo;var s=Go;if(Xo=u,(Go=i)&&!s)for(Jo=l;null!==Jo;)i=(u=Jo).child,22===u.tag&&null!==u.memoizedState?xi(l):null!==i?(i.return=u,Jo=i):xi(l);for(;null!==a;)Jo=a,ki(a,n,t),a=a.sibling;Jo=l,Xo=o,Go=s}wi(e)}else 8772&l.subtreeFlags&&null!==a?(a.return=l,Jo=a):wi(e)}}function wi(e){for(;null!==Jo;){var n=Jo;if(8772&n.flags){var t=n.alternate;try{if(8772&n.flags)switch(n.tag){
|
||||
case 0:case 11:case 15:Go||li(5,n);break;case 1:var r=n.stateNode;if(4&n.flags&&!Go)if(null===t)r.componentDidMount();else{var l=n.elementType===n.type?t.memoizedProps:ga(n.type,t.memoizedProps);r.componentDidUpdate(l,t.memoizedState,r.__reactInternalSnapshotBeforeUpdate)}var u=n.updateQueue;null!==u&&Ua(n,u,r);break;case 3:var o=n.updateQueue;if(null!==o){if(t=null,null!==n.child)switch(n.child.tag){case 5:case 1:t=n.child.stateNode}Ua(n,o,t)}break;case 5:var i=n.stateNode;if(null===t&&4&n.flags){t=i;var s=n.memoizedProps;switch(n.type){case"button":case"input":case"select":case"textarea":s.autoFocus&&t.focus();break;case"img":s.src&&(t.src=s.src)}}break;case 6:case 4:case 12:case 19:case 17:case 21:case 22:case 23:case 25:break;case 13:if(null===n.memoizedState){var c=n.alternate;if(null!==c){var f=c.memoizedState;if(null!==f){var d=f.dehydrated;null!==d&&Bn(d)}}}break;default:throw Error(a(163))}Go||512&n.flags&&ai(n)}catch(e){Cs(n,n.return,e)}}if(n===e){Jo=null;break}if(null!==(t=n.sibling)){t.return=n.return,Jo=t;break}Jo=n.return}}function Si(e){for(;null!==Jo;){var n=Jo;if(n===e){Jo=null;break}var t=n.sibling;if(null!==t){t.return=n.return,Jo=t;break}Jo=n.return}}function xi(e){for(;null!==Jo;){var n=Jo;try{switch(n.tag){case 0:case 11:case 15:var t=n.return;try{li(4,n)}catch(e){Cs(n,t,e)}break;case 1:var r=n.stateNode;if("function"==typeof r.componentDidMount){var l=n.return;try{r.componentDidMount()}catch(e){Cs(n,l,e)}}var a=n.return;try{ai(n)}catch(e){Cs(n,a,e)}break;case 5:var u=n.return;try{ai(n)}catch(e){Cs(n,u,e)}}}catch(e){Cs(n,n.return,e)}if(n===e){Jo=null;break}var o=n.sibling;if(null!==o){o.return=n.return,Jo=o;break}Jo=n.return}}var Ei,Ci=Math.ceil,_i=k.ReactCurrentDispatcher,Pi=k.ReactCurrentOwner,Ni=k.ReactCurrentBatchConfig,zi=0,Ti=null,Li=null,Ri=0,Mi=0,Fi=El(0),Oi=0,Di=null,Ii=0,Ui=0,Vi=0,Ai=null,$i=null,ji=0,Bi=1/0,Hi=null,Wi=!1,Qi=null,qi=null,Ki=!1,Yi=null,Xi=0,Gi=0,Zi=null,Ji=-1,es=0;function ns(){return 6&zi?Ge():-1!==Ji?Ji:Ji=Ge()}function ts(e){return 1&e.mode?2&zi&&0!==Ri?Ri&-Ri:null!==ha.transition?(0===es&&(es=gn()),es):0!==(e=kn)?e:e=void 0===(e=window.event)?16:Gn(e.type):1}function rs(e,n,t,r){if(50<Gi)throw Gi=0,Zi=null,Error(a(185));yn(e,t,r),2&zi&&e===Ti||(e===Ti&&(!(2&zi)&&(Ui|=t),4===Oi&&is(e,Ri)),ls(e,r),1===t&&0===zi&&!(1&n.mode)&&(Bi=Ge()+500,Vl&&jl()))}function ls(e,n){var t=e.callbackNode;!function(e,n){for(var t=e.suspendedLanes,r=e.pingedLanes,l=e.expirationTimes,a=e.pendingLanes;0<a;){var u=31-un(a),o=1<<u,i=l[u];-1===i?o&t&&!(o&r)||(l[u]=mn(o,n)):i<=n&&(e.expiredLanes|=o),a&=~o}}(e,n);var r=pn(e,e===Ti?Ri:0);if(0===r)null!==t&&Ke(t),e.callbackNode=null,e.callbackPriority=0;else if(n=r&-r,e.callbackPriority!==n){if(null!=t&&Ke(t),1===n)0===e.tag?function(e){Vl=!0,$l(e)}(ss.bind(null,e)):$l(ss.bind(null,e)),ul((function(){!(6&zi)&&jl()})),t=null;else{switch(wn(r)){case 1:t=Je;break;case 4:t=en;break;case 16:default:t=nn;break;case 536870912:t=rn}t=Ts(t,as.bind(null,e))}e.callbackPriority=n,e.callbackNode=t}}function as(e,n){if(Ji=-1,es=0,6&zi)throw Error(a(327))
|
||||
;var t=e.callbackNode;if(xs()&&e.callbackNode!==t)return null;var r=pn(e,e===Ti?Ri:0);if(0===r)return null;if(30&r||r&e.expiredLanes||n)n=vs(e,r);else{n=r;var l=zi;zi|=2;var u=hs();for(Ti===e&&Ri===n||(Hi=null,Bi=Ge()+500,ps(e,n));;)try{bs();break}catch(n){ms(e,n)}wa(),_i.current=u,zi=l,null!==Li?n=0:(Ti=null,Ri=0,n=Oi)}if(0!==n){if(2===n&&(0!==(l=hn(e))&&(r=l,n=us(e,l))),1===n)throw t=Di,ps(e,0),is(e,r),ls(e,Ge()),t;if(6===n)is(e,r);else{if(l=e.current.alternate,!(30&r||function(e){for(var n=e;;){if(16384&n.flags){var t=n.updateQueue;if(null!==t&&null!==(t=t.stores))for(var r=0;r<t.length;r++){var l=t[r],a=l.getSnapshot;l=l.value;try{if(!or(a(),l))return!1}catch(e){return!1}}}if(t=n.child,16384&n.subtreeFlags&&null!==t)t.return=n,n=t;else{if(n===e)break;for(;null===n.sibling;){if(null===n.return||n.return===e)return!0;n=n.return}n.sibling.return=n.return,n=n.sibling}}return!0}(l)||(n=vs(e,r),2===n&&(u=hn(e),0!==u&&(r=u,n=us(e,u))),1!==n)))throw t=Di,ps(e,0),is(e,r),ls(e,Ge()),t;switch(e.finishedWork=l,e.finishedLanes=r,n){case 0:case 1:throw Error(a(345));case 2:case 5:Ss(e,$i,Hi);break;case 3:if(is(e,r),(130023424&r)===r&&10<(n=ji+500-Ge())){if(0!==pn(e,0))break;if(((l=e.suspendedLanes)&r)!==r){ns(),e.pingedLanes|=e.suspendedLanes&l;break}e.timeoutHandle=rl(Ss.bind(null,e,$i,Hi),n);break}Ss(e,$i,Hi);break;case 4:if(is(e,r),(4194240&r)===r)break;for(n=e.eventTimes,l=-1;0<r;){var o=31-un(r);u=1<<o,(o=n[o])>l&&(l=o),r&=~u}if(r=l,10<(r=(120>(r=Ge()-r)?120:480>r?480:1080>r?1080:1920>r?1920:3e3>r?3e3:4320>r?4320:1960*Ci(r/1960))-r)){e.timeoutHandle=rl(Ss.bind(null,e,$i,Hi),r);break}Ss(e,$i,Hi);break;default:throw Error(a(329))}}}return ls(e,Ge()),e.callbackNode===t?as.bind(null,e):null}function us(e,n){var t=Ai;return e.current.memoizedState.isDehydrated&&(ps(e,n).flags|=256),2!==(e=vs(e,n))&&(n=$i,$i=t,null!==n&&os(n)),e}function os(e){null===$i?$i=e:$i.push.apply($i,e)}function is(e,n){for(n&=~Vi,n&=~Ui,e.suspendedLanes|=n,e.pingedLanes&=~n,e=e.expirationTimes;0<n;){var t=31-un(n),r=1<<t;e[t]=-1,n&=~r}}function ss(e){if(6&zi)throw Error(a(327));xs();var n=pn(e,0);if(!(1&n))return ls(e,Ge()),null;var t=vs(e,n);if(0!==e.tag&&2===t){var r=hn(e);0!==r&&(n=r,t=us(e,r))}if(1===t)throw t=Di,ps(e,0),is(e,n),ls(e,Ge()),t;if(6===t)throw Error(a(345));return e.finishedWork=e.current.alternate,e.finishedLanes=n,Ss(e,$i,Hi),ls(e,Ge()),null}function cs(e,n){var t=zi;zi|=1;try{return e(n)}finally{0===(zi=t)&&(Bi=Ge()+500,Vl&&jl())}}function fs(e){null!==Yi&&0===Yi.tag&&!(6&zi)&&xs();var n=zi;zi|=1;var t=Ni.transition,r=kn;try{if(Ni.transition=null,kn=1,e)return e()}finally{kn=r,Ni.transition=t,!(6&(zi=n))&&jl()}}function ds(){Mi=Fi.current,Cl(Fi)}function ps(e,n){e.finishedWork=null,e.finishedLanes=0;var t=e.timeoutHandle;if(-1!==t&&(e.timeoutHandle=-1,ll(t)),null!==Li)for(t=Li.return;null!==t;){var r=t;switch(na(r),r.tag){case 1:null!=(r=r.type.childContextTypes)&&Ml();break;case 3:lu(),Cl(zl),Cl(Nl),cu();break;case 5:uu(r);break;case 4:lu();break;case 13:case 19:Cl(ou);break;case 10:Sa(r.type._context);break;case 22:case 23:ds()}
|
||||
t=t.return}if(Ti=e,Li=e=Fs(e.current,null),Ri=Mi=n,Oi=0,Di=null,Vi=Ui=Ii=0,$i=Ai=null,null!==_a){for(n=0;n<_a.length;n++)if(null!==(r=(t=_a[n]).interleaved)){t.interleaved=null;var l=r.next,a=t.pending;if(null!==a){var u=a.next;a.next=l,r.next=u}t.pending=r}_a=null}return e}function ms(e,n){for(;;){var t=Li;try{if(wa(),fu.current=ao,vu){for(var r=mu.memoizedState;null!==r;){var l=r.queue;null!==l&&(l.pending=null),r=r.next}vu=!1}if(pu=0,gu=hu=mu=null,yu=!1,bu=0,Pi.current=null,null===t||null===t.return){Oi=1,Di=n,Li=null;break}e:{var u=e,o=t.return,i=t,s=n;if(n=Ri,i.flags|=32768,null!==s&&"object"==typeof s&&"function"==typeof s.then){var c=s,f=i,d=f.tag;if(!(1&f.mode||0!==d&&11!==d&&15!==d)){var p=f.alternate;p?(f.updateQueue=p.updateQueue,f.memoizedState=p.memoizedState,f.lanes=p.lanes):(f.updateQueue=null,f.memoizedState=null)}var m=vo(o);if(null!==m){m.flags&=-257,yo(m,o,i,0,n),1&m.mode&&go(u,c,n),s=c;var h=(n=m).updateQueue;if(null===h){var g=new Set;g.add(s),n.updateQueue=g}else h.add(s);break e}if(!(1&n)){go(u,c,n),gs();break e}s=Error(a(426))}else if(la&&1&i.mode){var v=vo(o);if(null!==v){!(65536&v.flags)&&(v.flags|=256),yo(v,o,i,0,n),ma(so(s,i));break e}}u=s=so(s,i),4!==Oi&&(Oi=2),null===Ai?Ai=[u]:Ai.push(u),u=o;do{switch(u.tag){case 3:u.flags|=65536,n&=-n,u.lanes|=n,Da(u,mo(0,s,n));break e;case 1:i=s;var y=u.type,b=u.stateNode;if(!(128&u.flags||"function"!=typeof y.getDerivedStateFromError&&(null===b||"function"!=typeof b.componentDidCatch||null!==qi&&qi.has(b)))){u.flags|=65536,n&=-n,u.lanes|=n,Da(u,ho(u,i,n));break e}}u=u.return}while(null!==u)}ws(t)}catch(e){n=e,Li===t&&null!==t&&(Li=t=t.return);continue}break}}function hs(){var e=_i.current;return _i.current=ao,null===e?ao:e}function gs(){0!==Oi&&3!==Oi&&2!==Oi||(Oi=4),null===Ti||!(268435455&Ii)&&!(268435455&Ui)||is(Ti,Ri)}function vs(e,n){var t=zi;zi|=2;var r=hs();for(Ti===e&&Ri===n||(Hi=null,ps(e,n));;)try{ys();break}catch(n){ms(e,n)}if(wa(),zi=t,_i.current=r,null!==Li)throw Error(a(261));return Ti=null,Ri=0,Oi}function ys(){for(;null!==Li;)ks(Li)}function bs(){for(;null!==Li&&!Ye();)ks(Li)}function ks(e){var n=Ei(e.alternate,e,Mi);e.memoizedProps=e.pendingProps,null===n?ws(e):Li=n,Pi.current=null}function ws(e){var n=e;do{var t=n.alternate;if(e=n.return,32768&n.flags){if(null!==(t=Yo(t,n)))return t.flags&=32767,void(Li=t);if(null===e)return Oi=6,void(Li=null);e.flags|=32768,e.subtreeFlags=0,e.deletions=null}else if(null!==(t=Ko(t,n,Mi)))return void(Li=t);if(null!==(n=n.sibling))return void(Li=n);Li=n=e}while(null!==n);0===Oi&&(Oi=5)}function Ss(e,n,t){var r=kn,l=Ni.transition;try{Ni.transition=null,kn=1,function(e,n,t,r){do{xs()}while(null!==Yi);if(6&zi)throw Error(a(327));t=e.finishedWork;var l=e.finishedLanes;if(null===t)return null;if(e.finishedWork=null,e.finishedLanes=0,t===e.current)throw Error(a(177));e.callbackNode=null,e.callbackPriority=0;var u=t.lanes|t.childLanes;if(function(e,n){var t=e.pendingLanes&~n;e.pendingLanes=n,e.suspendedLanes=0,e.pingedLanes=0,e.expiredLanes&=n,e.mutableReadLanes&=n,e.entangledLanes&=n,n=e.entanglements
|
||||
;var r=e.eventTimes;for(e=e.expirationTimes;0<t;){var l=31-un(t),a=1<<l;n[l]=0,r[l]=-1,e[l]=-1,t&=~a}}(e,u),e===Ti&&(Li=Ti=null,Ri=0),!(2064&t.subtreeFlags)&&!(2064&t.flags)||Ki||(Ki=!0,Ts(nn,(function(){return xs(),null}))),u=!!(15990&t.flags),!!(15990&t.subtreeFlags)||u){u=Ni.transition,Ni.transition=null;var o=kn;kn=1;var i=zi;zi|=4,Pi.current=null,function(e,n){if(el=Wn,pr(e=dr())){if("selectionStart"in e)var t={start:e.selectionStart,end:e.selectionEnd};else e:{var r=(t=(t=e.ownerDocument)&&t.defaultView||window).getSelection&&t.getSelection();if(r&&0!==r.rangeCount){t=r.anchorNode;var l=r.anchorOffset,u=r.focusNode;r=r.focusOffset;try{t.nodeType,u.nodeType}catch(e){t=null;break e}var o=0,i=-1,s=-1,c=0,f=0,d=e,p=null;n:for(;;){for(var m;d!==t||0!==l&&3!==d.nodeType||(i=o+l),d!==u||0!==r&&3!==d.nodeType||(s=o+r),3===d.nodeType&&(o+=d.nodeValue.length),null!==(m=d.firstChild);)p=d,d=m;for(;;){if(d===e)break n;if(p===t&&++c===l&&(i=o),p===u&&++f===r&&(s=o),null!==(m=d.nextSibling))break;p=(d=p).parentNode}d=m}t=-1===i||-1===s?null:{start:i,end:s}}else t=null}t=t||{start:0,end:0}}else t=null;for(nl={focusedElem:e,selectionRange:t},Wn=!1,Jo=n;null!==Jo;)if(e=(n=Jo).child,1028&n.subtreeFlags&&null!==e)e.return=n,Jo=e;else for(;null!==Jo;){n=Jo;try{var h=n.alternate;if(1024&n.flags)switch(n.tag){case 0:case 11:case 15:case 5:case 6:case 4:case 17:break;case 1:if(null!==h){var g=h.memoizedProps,v=h.memoizedState,y=n.stateNode,b=y.getSnapshotBeforeUpdate(n.elementType===n.type?g:ga(n.type,g),v);y.__reactInternalSnapshotBeforeUpdate=b}break;case 3:var k=n.stateNode.containerInfo;1===k.nodeType?k.textContent="":9===k.nodeType&&k.documentElement&&k.removeChild(k.documentElement);break;default:throw Error(a(163))}}catch(e){Cs(n,n.return,e)}if(null!==(e=n.sibling)){e.return=n.return,Jo=e;break}Jo=n.return}h=ti,ti=!1}(e,t),vi(t,e),mr(nl),Wn=!!el,nl=el=null,e.current=t,bi(t,e,l),Xe(),zi=i,kn=o,Ni.transition=u}else e.current=t;if(Ki&&(Ki=!1,Yi=e,Xi=l),u=e.pendingLanes,0===u&&(qi=null),function(e){if(an&&"function"==typeof an.onCommitFiberRoot)try{an.onCommitFiberRoot(ln,e,void 0,!(128&~e.current.flags))}catch(e){}}(t.stateNode),ls(e,Ge()),null!==n)for(r=e.onRecoverableError,t=0;t<n.length;t++)l=n[t],r(l.value,{componentStack:l.stack,digest:l.digest});if(Wi)throw Wi=!1,e=Qi,Qi=null,e;!!(1&Xi)&&0!==e.tag&&xs(),u=e.pendingLanes,1&u?e===Zi?Gi++:(Gi=0,Zi=e):Gi=0,jl()}(e,n,t,r)}finally{Ni.transition=l,kn=r}return null}function xs(){if(null!==Yi){var e=wn(Xi),n=Ni.transition,t=kn;try{if(Ni.transition=null,kn=16>e?16:e,null===Yi)var r=!1;else{if(e=Yi,Yi=null,Xi=0,6&zi)throw Error(a(331));var l=zi;for(zi|=4,Jo=e.current;null!==Jo;){var u=Jo,o=u.child;if(16&Jo.flags){var i=u.deletions;if(null!==i){for(var s=0;s<i.length;s++){var c=i[s];for(Jo=c;null!==Jo;){var f=Jo;switch(f.tag){case 0:case 11:case 15:ri(8,f,u)}var d=f.child;if(null!==d)d.return=f,Jo=d;else for(;null!==Jo;){var p=(f=Jo).sibling,m=f.return;if(ui(f),f===c){Jo=null;break}if(null!==p){p.return=m,Jo=p;break}Jo=m}}}var h=u.alternate;if(null!==h){var g=h.child;if(null!==g){
|
||||
h.child=null;do{var v=g.sibling;g.sibling=null,g=v}while(null!==g)}}Jo=u}}if(2064&u.subtreeFlags&&null!==o)o.return=u,Jo=o;else e:for(;null!==Jo;){if(2048&(u=Jo).flags)switch(u.tag){case 0:case 11:case 15:ri(9,u,u.return)}var y=u.sibling;if(null!==y){y.return=u.return,Jo=y;break e}Jo=u.return}}var b=e.current;for(Jo=b;null!==Jo;){var k=(o=Jo).child;if(2064&o.subtreeFlags&&null!==k)k.return=o,Jo=k;else e:for(o=b;null!==Jo;){if(2048&(i=Jo).flags)try{switch(i.tag){case 0:case 11:case 15:li(9,i)}}catch(e){Cs(i,i.return,e)}if(i===o){Jo=null;break e}var w=i.sibling;if(null!==w){w.return=i.return,Jo=w;break e}Jo=i.return}}if(zi=l,jl(),an&&"function"==typeof an.onPostCommitFiberRoot)try{an.onPostCommitFiberRoot(ln,e)}catch(e){}r=!0}return r}finally{kn=t,Ni.transition=n}}return!1}function Es(e,n,t){e=Fa(e,n=mo(0,n=so(t,n),1),1),n=ns(),null!==e&&(yn(e,1,n),ls(e,n))}function Cs(e,n,t){if(3===e.tag)Es(e,e,t);else for(;null!==n;){if(3===n.tag){Es(n,e,t);break}if(1===n.tag){var r=n.stateNode;if("function"==typeof n.type.getDerivedStateFromError||"function"==typeof r.componentDidCatch&&(null===qi||!qi.has(r))){n=Fa(n,e=ho(n,e=so(t,e),1),1),e=ns(),null!==n&&(yn(n,1,e),ls(n,e));break}}n=n.return}}function _s(e,n,t){var r=e.pingCache;null!==r&&r.delete(n),n=ns(),e.pingedLanes|=e.suspendedLanes&t,Ti===e&&(Ri&t)===t&&(4===Oi||3===Oi&&(130023424&Ri)===Ri&&500>Ge()-ji?ps(e,0):Vi|=t),ls(e,n)}function Ps(e,n){0===n&&(1&e.mode?(n=fn,!(130023424&(fn<<=1))&&(fn=4194304)):n=1);var t=ns();null!==(e=za(e,n))&&(yn(e,n,t),ls(e,t))}function Ns(e){var n=e.memoizedState,t=0;null!==n&&(t=n.retryLane),Ps(e,t)}function zs(e,n){var t=0;switch(e.tag){case 13:var r=e.stateNode,l=e.memoizedState;null!==l&&(t=l.retryLane);break;case 19:r=e.stateNode;break;default:throw Error(a(314))}null!==r&&r.delete(n),Ps(e,t)}function Ts(e,n){return qe(e,n)}function Ls(e,n,t,r){this.tag=e,this.key=t,this.sibling=this.child=this.return=this.stateNode=this.type=this.elementType=null,this.index=0,this.ref=null,this.pendingProps=n,this.dependencies=this.memoizedState=this.updateQueue=this.memoizedProps=null,this.mode=r,this.subtreeFlags=this.flags=0,this.deletions=null,this.childLanes=this.lanes=0,this.alternate=null}function Rs(e,n,t,r){return new Ls(e,n,t,r)}function Ms(e){return!(!(e=e.prototype)||!e.isReactComponent)}function Fs(e,n){var t=e.alternate;return null===t?((t=Rs(e.tag,n,e.key,e.mode)).elementType=e.elementType,t.type=e.type,t.stateNode=e.stateNode,t.alternate=e,e.alternate=t):(t.pendingProps=n,t.type=e.type,t.flags=0,t.subtreeFlags=0,t.deletions=null),t.flags=14680064&e.flags,t.childLanes=e.childLanes,t.lanes=e.lanes,t.child=e.child,t.memoizedProps=e.memoizedProps,t.memoizedState=e.memoizedState,t.updateQueue=e.updateQueue,n=e.dependencies,t.dependencies=null===n?null:{lanes:n.lanes,firstContext:n.firstContext},t.sibling=e.sibling,t.index=e.index,t.ref=e.ref,t}function Os(e,n,t,r,l,u){var o=2;if(r=e,"function"==typeof e)Ms(e)&&(o=1);else if("string"==typeof e)o=5;else e:switch(e){case x:return Ds(t.children,l,u,n);case E:o=8,l|=8;break;case C:
|
||||
return(e=Rs(12,t,n,2|l)).elementType=C,e.lanes=u,e;case z:return(e=Rs(13,t,n,l)).elementType=z,e.lanes=u,e;case T:return(e=Rs(19,t,n,l)).elementType=T,e.lanes=u,e;case M:return Is(t,l,u,n);default:if("object"==typeof e&&null!==e)switch(e.$$typeof){case _:o=10;break e;case P:o=9;break e;case N:o=11;break e;case L:o=14;break e;case R:o=16,r=null;break e}throw Error(a(130,null==e?e:typeof e,""))}return(n=Rs(o,t,n,l)).elementType=e,n.type=r,n.lanes=u,n}function Ds(e,n,t,r){return(e=Rs(7,e,r,n)).lanes=t,e}function Is(e,n,t,r){return(e=Rs(22,e,r,n)).elementType=M,e.lanes=t,e.stateNode={isHidden:!1},e}function Us(e,n,t){return(e=Rs(6,e,null,n)).lanes=t,e}function Vs(e,n,t){return(n=Rs(4,null!==e.children?e.children:[],e.key,n)).lanes=t,n.stateNode={containerInfo:e.containerInfo,pendingChildren:null,implementation:e.implementation},n}function As(e,n,t,r,l){this.tag=n,this.containerInfo=e,this.finishedWork=this.pingCache=this.current=this.pendingChildren=null,this.timeoutHandle=-1,this.callbackNode=this.pendingContext=this.context=null,this.callbackPriority=0,this.eventTimes=vn(0),this.expirationTimes=vn(-1),this.entangledLanes=this.finishedLanes=this.mutableReadLanes=this.expiredLanes=this.pingedLanes=this.suspendedLanes=this.pendingLanes=0,this.entanglements=vn(0),this.identifierPrefix=r,this.onRecoverableError=l,this.mutableSourceEagerHydrationData=null}function $s(e,n,t,r,l,a,u,o,i){return e=new As(e,n,t,o,i),1===n?(n=1,!0===a&&(n|=8)):n=0,a=Rs(3,null,null,n),e.current=a,a.stateNode=e,a.memoizedState={element:r,isDehydrated:t,cache:null,transitions:null,pendingSuspenseBoundaries:null},La(a),e}function js(e){if(!e)return Pl;e:{if(je(e=e._reactInternals)!==e||1!==e.tag)throw Error(a(170));var n=e;do{switch(n.tag){case 3:n=n.stateNode.context;break e;case 1:if(Rl(n.type)){n=n.stateNode.__reactInternalMemoizedMergedChildContext;break e}}n=n.return}while(null!==n);throw Error(a(171))}if(1===e.tag){var t=e.type;if(Rl(t))return Ol(e,t,n)}return n}function Bs(e,n,t,r,l,a,u,o,i){return(e=$s(t,r,!0,e,0,a,0,o,i)).context=js(null),t=e.current,(a=Ma(r=ns(),l=ts(t))).callback=null!=n?n:null,Fa(t,a,l),e.current.lanes=l,yn(e,l,r),ls(e,r),e}function Hs(e,n,t,r){var l=n.current,a=ns(),u=ts(l);return t=js(t),null===n.context?n.context=t:n.pendingContext=t,(n=Ma(a,u)).payload={element:e},null!==(r=void 0===r?null:r)&&(n.callback=r),null!==(e=Fa(l,n,u))&&(rs(e,l,u,a),Oa(e,l,u)),u}function Ws(e){return(e=e.current).child?(e.child.tag,e.child.stateNode):null}function Qs(e,n){if(null!==(e=e.memoizedState)&&null!==e.dehydrated){var t=e.retryLane;e.retryLane=0!==t&&t<n?t:n}}function qs(e,n){Qs(e,n),(e=e.alternate)&&Qs(e,n)}Ei=function(e,n,t){if(null!==e)if(e.memoizedProps!==n.pendingProps||zl.current)ko=!0;else{if(!(e.lanes&t||128&n.flags))return ko=!1,function(e,n,t){switch(n.tag){case 3:To(n),pa();break;case 5:au(n);break;case 1:Rl(n.type)&&Dl(n);break;case 4:ru(n,n.stateNode.containerInfo);break;case 10:var r=n.type._context,l=n.memoizedProps.value;_l(va,r._currentValue),r._currentValue=l;break;case 13:
|
||||
if(null!==(r=n.memoizedState))return null!==r.dehydrated?(_l(ou,1&ou.current),n.flags|=128,null):t&n.child.childLanes?Uo(e,n,t):(_l(ou,1&ou.current),null!==(e=Wo(e,n,t))?e.sibling:null);_l(ou,1&ou.current);break;case 19:if(r=!!(t&n.childLanes),128&e.flags){if(r)return Bo(e,n,t);n.flags|=128}if(null!==(l=n.memoizedState)&&(l.rendering=null,l.tail=null,l.lastEffect=null),_l(ou,ou.current),r)break;return null;case 22:case 23:return n.lanes=0,Co(e,n,t)}return Wo(e,n,t)}(e,n,t);ko=!!(131072&e.flags)}else ko=!1,la&&1048576&n.flags&&Jl(n,Ql,n.index);switch(n.lanes=0,n.tag){case 2:var r=n.type;Ho(e,n),e=n.pendingProps;var l=Ll(n,Nl.current);Ea(n,t),l=xu(null,n,r,e,l,t);var u=Eu();return n.flags|=1,"object"==typeof l&&null!==l&&"function"==typeof l.render&&void 0===l.$$typeof?(n.tag=1,n.memoizedState=null,n.updateQueue=null,Rl(r)?(u=!0,Dl(n)):u=!1,n.memoizedState=null!==l.state&&void 0!==l.state?l.state:null,La(n),l.updater=$a,n.stateNode=l,l._reactInternals=n,Wa(n,r,e,t),n=zo(null,n,r,!0,u,t)):(n.tag=0,la&&u&&ea(n),wo(null,n,l,t),n=n.child),n;case 16:r=n.elementType;e:{switch(Ho(e,n),e=n.pendingProps,r=(l=r._init)(r._payload),n.type=r,l=n.tag=function(e){if("function"==typeof e)return Ms(e)?1:0;if(null!=e){if((e=e.$$typeof)===N)return 11;if(e===L)return 14}return 2}(r),e=ga(r,e),l){case 0:n=Po(null,n,r,e,t);break e;case 1:n=No(null,n,r,e,t);break e;case 11:n=So(null,n,r,e,t);break e;case 14:n=xo(null,n,r,ga(r.type,e),t);break e}throw Error(a(306,r,""))}return n;case 0:return r=n.type,l=n.pendingProps,Po(e,n,r,l=n.elementType===r?l:ga(r,l),t);case 1:return r=n.type,l=n.pendingProps,No(e,n,r,l=n.elementType===r?l:ga(r,l),t);case 3:e:{if(To(n),null===e)throw Error(a(387));r=n.pendingProps,l=(u=n.memoizedState).element,Ra(e,n),Ia(n,r,null,t);var o=n.memoizedState;if(r=o.element,u.isDehydrated){if(u={element:r,isDehydrated:!1,cache:o.cache,pendingSuspenseBoundaries:o.pendingSuspenseBoundaries,transitions:o.transitions},n.updateQueue.baseState=u,n.memoizedState=u,256&n.flags){n=Lo(e,n,r,t,l=so(Error(a(423)),n));break e}if(r!==l){n=Lo(e,n,r,t,l=so(Error(a(424)),n));break e}for(ra=sl(n.stateNode.containerInfo.firstChild),ta=n,la=!0,aa=null,t=Ga(n,null,r,t),n.child=t;t;)t.flags=-3&t.flags|4096,t=t.sibling}else{if(pa(),r===l){n=Wo(e,n,t);break e}wo(e,n,r,t)}n=n.child}return n;case 5:return au(n),null===e&&sa(n),r=n.type,l=n.pendingProps,u=null!==e?e.memoizedProps:null,o=l.children,tl(r,l)?o=null:null!==u&&tl(r,u)&&(n.flags|=32),_o(e,n),wo(e,n,o,t),n.child;case 6:return null===e&&sa(n),null;case 13:return Uo(e,n,t);case 4:return ru(n,n.stateNode.containerInfo),r=n.pendingProps,null===e?n.child=Xa(n,null,r,t):wo(e,n,r,t),n.child;case 11:return r=n.type,l=n.pendingProps,So(e,n,r,l=n.elementType===r?l:ga(r,l),t);case 7:return wo(e,n,n.pendingProps,t),n.child;case 8:case 12:return wo(e,n,n.pendingProps.children,t),n.child;case 10:e:{if(r=n.type._context,l=n.pendingProps,u=n.memoizedProps,o=l.value,_l(va,r._currentValue),r._currentValue=o,null!==u)if(or(u.value,o)){if(u.children===l.children&&!zl.current){n=Wo(e,n,t);break e}
|
||||
}else for(null!==(u=n.child)&&(u.return=n);null!==u;){var i=u.dependencies;if(null!==i){o=u.child;for(var s=i.firstContext;null!==s;){if(s.context===r){if(1===u.tag){(s=Ma(-1,t&-t)).tag=2;var c=u.updateQueue;if(null!==c){var f=(c=c.shared).pending;null===f?s.next=s:(s.next=f.next,f.next=s),c.pending=s}}u.lanes|=t,null!==(s=u.alternate)&&(s.lanes|=t),xa(u.return,t,n),i.lanes|=t;break}s=s.next}}else if(10===u.tag)o=u.type===n.type?null:u.child;else if(18===u.tag){if(null===(o=u.return))throw Error(a(341));o.lanes|=t,null!==(i=o.alternate)&&(i.lanes|=t),xa(o,t,n),o=u.sibling}else o=u.child;if(null!==o)o.return=u;else for(o=u;null!==o;){if(o===n){o=null;break}if(null!==(u=o.sibling)){u.return=o.return,o=u;break}o=o.return}u=o}wo(e,n,l.children,t),n=n.child}return n;case 9:return l=n.type,r=n.pendingProps.children,Ea(n,t),r=r(l=Ca(l)),n.flags|=1,wo(e,n,r,t),n.child;case 14:return l=ga(r=n.type,n.pendingProps),xo(e,n,r,l=ga(r.type,l),t);case 15:return Eo(e,n,n.type,n.pendingProps,t);case 17:return r=n.type,l=n.pendingProps,l=n.elementType===r?l:ga(r,l),Ho(e,n),n.tag=1,Rl(r)?(e=!0,Dl(n)):e=!1,Ea(n,t),Ba(n,r,l),Wa(n,r,l,t),zo(null,n,r,!0,e,t);case 19:return Bo(e,n,t);case 22:return Co(e,n,t)}throw Error(a(156,n.tag))};var Ks="function"==typeof reportError?reportError:function(e){console.error(e)};function Ys(e){this._internalRoot=e}function Xs(e){this._internalRoot=e}function Gs(e){return!(!e||1!==e.nodeType&&9!==e.nodeType&&11!==e.nodeType)}function Zs(e){return!(!e||1!==e.nodeType&&9!==e.nodeType&&11!==e.nodeType&&(8!==e.nodeType||" react-mount-point-unstable "!==e.nodeValue))}function Js(){}function ec(e,n,t,r,l){var a=t._reactRootContainer;if(a){var u=a;if("function"==typeof l){var o=l;l=function(){var e=Ws(u);o.call(e)}}Hs(n,u,e,l)}else u=function(e,n,t,r,l){if(l){if("function"==typeof r){var a=r;r=function(){var e=Ws(u);a.call(e)}}var u=Bs(n,r,e,0,null,!1,0,"",Js);return e._reactRootContainer=u,e[ml]=u.current,jr(8===e.nodeType?e.parentNode:e),fs(),u}for(;l=e.lastChild;)e.removeChild(l);if("function"==typeof r){var o=r;r=function(){var e=Ws(i);o.call(e)}}var i=$s(e,0,!1,null,0,!1,0,"",Js);return e._reactRootContainer=i,e[ml]=i.current,jr(8===e.nodeType?e.parentNode:e),fs((function(){Hs(n,i,t,r)})),i}(t,n,e,l,r);return Ws(u)}Xs.prototype.render=Ys.prototype.render=function(e){var n=this._internalRoot;if(null===n)throw Error(a(409));Hs(e,n,null,null)},Xs.prototype.unmount=Ys.prototype.unmount=function(){var e=this._internalRoot;if(null!==e){this._internalRoot=null;var n=e.containerInfo;fs((function(){Hs(null,e,null,null)})),n[ml]=null}},Xs.prototype.unstable_scheduleHydration=function(e){if(e){var n=Cn();e={blockedOn:null,target:e,priority:n};for(var t=0;t<Fn.length&&0!==n&&n<Fn[t].priority;t++);Fn.splice(t,0,e),0===t&&Un(e)}},Sn=function(e){switch(e.tag){case 3:var n=e.stateNode;if(n.current.memoizedState.isDehydrated){var t=dn(n.pendingLanes);0!==t&&(bn(n,1|t),ls(n,Ge()),!(6&zi)&&(Bi=Ge()+500,jl()))}break;case 13:fs((function(){var n=za(e,1);if(null!==n){var t=ns();rs(n,e,1,t)}})),qs(e,1)}},xn=function(e){
|
||||
if(13===e.tag){var n=za(e,134217728);if(null!==n)rs(n,e,134217728,ns());qs(e,134217728)}},En=function(e){if(13===e.tag){var n=ts(e),t=za(e,n);if(null!==t)rs(t,e,n,ns());qs(e,n)}},Cn=function(){return kn},_n=function(e,n){var t=kn;try{return kn=e,n()}finally{kn=t}},Se=function(e,n,t){switch(n){case"input":if(Z(e,t),n=t.name,"radio"===t.type&&null!=n){for(t=e;t.parentNode;)t=t.parentNode;for(t=t.querySelectorAll("input[name="+JSON.stringify(""+n)+'][type="radio"]'),n=0;n<t.length;n++){var r=t[n];if(r!==e&&r.form===e.form){var l=wl(r);if(!l)throw Error(a(90));q(r),Z(r,l)}}}break;case"textarea":ae(e,t);break;case"select":null!=(n=t.value)&&te(e,!!t.multiple,n,!1)}},Ne=cs,ze=fs;var nc={usingClientEntryPoint:!1,Events:[bl,kl,wl,_e,Pe,cs]},tc={findFiberByHostInstance:yl,bundleType:0,version:"18.2.0",rendererPackageName:"react-dom"},rc={bundleType:tc.bundleType,version:tc.version,rendererPackageName:tc.rendererPackageName,rendererConfig:tc.rendererConfig,overrideHookState:null,overrideHookStateDeletePath:null,overrideHookStateRenamePath:null,overrideProps:null,overridePropsDeletePath:null,overridePropsRenamePath:null,setErrorHandler:null,setSuspenseHandler:null,scheduleUpdate:null,currentDispatcherRef:k.ReactCurrentDispatcher,findHostInstanceByFiber:function(e){return null===(e=We(e))?null:e.stateNode},findFiberByHostInstance:tc.findFiberByHostInstance||function(){return null},findHostInstancesForRefresh:null,scheduleRefresh:null,scheduleRoot:null,setRefreshHandler:null,getCurrentFiber:null,reconcilerVersion:"18.2.0-next-9e3b772b8-20220608"};if("undefined"!=typeof __REACT_DEVTOOLS_GLOBAL_HOOK__){var lc=__REACT_DEVTOOLS_GLOBAL_HOOK__;if(!lc.isDisabled&&lc.supportsFiber)try{ln=lc.inject(rc),an=lc}catch(ce){}}n.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED=nc,n.createPortal=function(e,n){var t=2<arguments.length&&void 0!==arguments[2]?arguments[2]:null;if(!Gs(n))throw Error(a(200));return function(e,n,t){var r=3<arguments.length&&void 0!==arguments[3]?arguments[3]:null;return{$$typeof:S,key:null==r?null:""+r,children:e,containerInfo:n,implementation:t}}(e,n,null,t)},n.createRoot=function(e,n){if(!Gs(e))throw Error(a(299));var t=!1,r="",l=Ks;return null!=n&&(!0===n.unstable_strictMode&&(t=!0),void 0!==n.identifierPrefix&&(r=n.identifierPrefix),void 0!==n.onRecoverableError&&(l=n.onRecoverableError)),n=$s(e,1,!1,null,0,t,0,r,l),e[ml]=n.current,jr(8===e.nodeType?e.parentNode:e),new Ys(n)},n.findDOMNode=function(e){if(null==e)return null;if(1===e.nodeType)return e;var n=e._reactInternals;if(void 0===n){if("function"==typeof e.render)throw Error(a(188));throw e=Object.keys(e).join(","),Error(a(268,e))}return e=null===(e=We(n))?null:e.stateNode},n.flushSync=function(e){return fs(e)},n.hydrate=function(e,n,t){if(!Zs(n))throw Error(a(200));return ec(null,e,n,!0,t)},n.hydrateRoot=function(e,n,t){if(!Gs(e))throw Error(a(405));var r=null!=t&&t.hydratedSources||null,l=!1,u="",o=Ks;if(null!=t&&(!0===t.unstable_strictMode&&(l=!0),void 0!==t.identifierPrefix&&(u=t.identifierPrefix),
|
||||
void 0!==t.onRecoverableError&&(o=t.onRecoverableError)),n=Bs(n,null,e,1,null!=t?t:null,l,0,u,o),e[ml]=n.current,jr(e),r)for(e=0;e<r.length;e++)l=(l=(t=r[e])._getVersion)(t._source),null==n.mutableSourceEagerHydrationData?n.mutableSourceEagerHydrationData=[t,l]:n.mutableSourceEagerHydrationData.push(t,l);return new Xs(n)},n.render=function(e,n,t){if(!Zs(n))throw Error(a(200));return ec(null,e,n,!1,t)},n.unmountComponentAtNode=function(e){if(!Zs(e))throw Error(a(40));return!!e._reactRootContainer&&(fs((function(){ec(null,null,e,!1,(function(){e._reactRootContainer=null,e[ml]=null}))})),!0)},n.unstable_batchedUpdates=cs,n.unstable_renderSubtreeIntoContainer=function(e,n,t,r){if(!Zs(t))throw Error(a(200));if(null==e||void 0===e._reactInternals)throw Error(a(38));return ec(e,n,t,!1,r)},n.version="18.2.0-next-9e3b772b8-20220608"},32227:(e,n,t)=>{!function e(){if("undefined"!=typeof __REACT_DEVTOOLS_GLOBAL_HOOK__&&"function"==typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE)try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(e)}catch(e){console.error(e)}}(),e.exports=t(82321)},95257:(e,n)=>{var t=Symbol.for("react.element"),r=Symbol.for("react.portal"),l=Symbol.for("react.fragment"),a=Symbol.for("react.strict_mode"),u=Symbol.for("react.profiler"),o=Symbol.for("react.provider"),i=Symbol.for("react.context"),s=Symbol.for("react.forward_ref"),c=Symbol.for("react.suspense"),f=Symbol.for("react.memo"),d=Symbol.for("react.lazy"),p=Symbol.iterator;var m={isMounted:function(){return!1},enqueueForceUpdate:function(){},enqueueReplaceState:function(){},enqueueSetState:function(){}},h=Object.assign,g={};function v(e,n,t){this.props=e,this.context=n,this.refs=g,this.updater=t||m}function y(){}function b(e,n,t){this.props=e,this.context=n,this.refs=g,this.updater=t||m}v.prototype.isReactComponent={},v.prototype.setState=function(e,n){if("object"!=typeof e&&"function"!=typeof e&&null!=e)throw Error("setState(...): takes an object of state variables to update or a function which returns an object of state variables.");this.updater.enqueueSetState(this,e,n,"setState")},v.prototype.forceUpdate=function(e){this.updater.enqueueForceUpdate(this,e,"forceUpdate")},y.prototype=v.prototype;var k=b.prototype=new y;k.constructor=b,h(k,v.prototype),k.isPureReactComponent=!0;var w=Array.isArray,S=Object.prototype.hasOwnProperty,x={current:null},E={key:!0,ref:!0,__self:!0,__source:!0};function C(e,n,r){var l,a={},u=null,o=null;if(null!=n)for(l in void 0!==n.ref&&(o=n.ref),void 0!==n.key&&(u=""+n.key),n)S.call(n,l)&&!E.hasOwnProperty(l)&&(a[l]=n[l]);var i=arguments.length-2;if(1===i)a.children=r;else if(1<i){for(var s=Array(i),c=0;c<i;c++)s[c]=arguments[c+2];a.children=s}if(e&&e.defaultProps)for(l in i=e.defaultProps)void 0===a[l]&&(a[l]=i[l]);return{$$typeof:t,type:e,key:u,ref:o,props:a,_owner:x.current}}function _(e){return"object"==typeof e&&null!==e&&e.$$typeof===t}var P=/\/+/g;function N(e,n){return"object"==typeof e&&null!==e&&null!=e.key?function(e){var n={"=":"=0",":":"=2"};return"$"+e.replace(/[=:]/g,(function(e){return n[e]}))}(""+e.key):n.toString(36)}
|
||||
function z(e,n,l,a,u){var o=typeof e;"undefined"!==o&&"boolean"!==o||(e=null);var i=!1;if(null===e)i=!0;else switch(o){case"string":case"number":i=!0;break;case"object":switch(e.$$typeof){case t:case r:i=!0}}if(i)return u=u(i=e),e=""===a?"."+N(i,0):a,w(u)?(l="",null!=e&&(l=e.replace(P,"$&/")+"/"),z(u,n,l,"",(function(e){return e}))):null!=u&&(_(u)&&(u=function(e,n){return{$$typeof:t,type:e.type,key:n,ref:e.ref,props:e.props,_owner:e._owner}}(u,l+(!u.key||i&&i.key===u.key?"":(""+u.key).replace(P,"$&/")+"/")+e)),n.push(u)),1;if(i=0,a=""===a?".":a+":",w(e))for(var s=0;s<e.length;s++){var c=a+N(o=e[s],s);i+=z(o,n,l,c,u)}else if(c=function(e){return null===e||"object"!=typeof e?null:"function"==typeof(e=p&&e[p]||e["@@iterator"])?e:null}(e),"function"==typeof c)for(e=c.call(e),s=0;!(o=e.next()).done;)i+=z(o=o.value,n,l,c=a+N(o,s++),u);else if("object"===o)throw n=String(e),Error("Objects are not valid as a React child (found: "+("[object Object]"===n?"object with keys {"+Object.keys(e).join(", ")+"}":n)+"). If you meant to render a collection of children, use an array instead.");return i}function T(e,n,t){if(null==e)return e;var r=[],l=0;return z(e,r,"","",(function(e){return n.call(t,e,l++)})),r}function L(e){if(-1===e._status){var n=e._result;(n=n()).then((function(n){0!==e._status&&-1!==e._status||(e._status=1,e._result=n)}),(function(n){0!==e._status&&-1!==e._status||(e._status=2,e._result=n)})),-1===e._status&&(e._status=0,e._result=n)}if(1===e._status)return e._result.default;throw e._result}var R={current:null},M={transition:null},F={ReactCurrentDispatcher:R,ReactCurrentBatchConfig:M,ReactCurrentOwner:x};n.Children={map:T,forEach:function(e,n,t){T(e,(function(){n.apply(this,arguments)}),t)},count:function(e){var n=0;return T(e,(function(){n++})),n},toArray:function(e){return T(e,(function(e){return e}))||[]},only:function(e){if(!_(e))throw Error("React.Children.only expected to receive a single React element child.");return e}},n.Component=v,n.Fragment=l,n.Profiler=u,n.PureComponent=b,n.StrictMode=a,n.Suspense=c,n.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED=F,n.cloneElement=function(e,n,r){if(null==e)throw Error("React.cloneElement(...): The argument must be a React element, but you passed "+e+".");var l=h({},e.props),a=e.key,u=e.ref,o=e._owner;if(null!=n){if(void 0!==n.ref&&(u=n.ref,o=x.current),void 0!==n.key&&(a=""+n.key),e.type&&e.type.defaultProps)var i=e.type.defaultProps;for(s in n)S.call(n,s)&&!E.hasOwnProperty(s)&&(l[s]=void 0===n[s]&&void 0!==i?i[s]:n[s])}var s=arguments.length-2;if(1===s)l.children=r;else if(1<s){i=Array(s);for(var c=0;c<s;c++)i[c]=arguments[c+2];l.children=i}return{$$typeof:t,type:e.type,key:a,ref:u,props:l,_owner:o}},n.createContext=function(e){return(e={$$typeof:i,_currentValue:e,_currentValue2:e,_threadCount:0,Provider:null,Consumer:null,_defaultValue:null,_globalName:null}).Provider={$$typeof:o,_context:e},e.Consumer=e},n.createElement=C,n.createFactory=function(e){var n=C.bind(null,e);return n.type=e,n},n.createRef=function(){return{current:null}},n.forwardRef=function(e){
|
||||
return{$$typeof:s,render:e}},n.isValidElement=_,n.lazy=function(e){return{$$typeof:d,_payload:{_status:-1,_result:e},_init:L}},n.memo=function(e,n){return{$$typeof:f,type:e,compare:void 0===n?null:n}},n.startTransition=function(e){var n=M.transition;M.transition={};try{e()}finally{M.transition=n}},n.unstable_act=function(){throw Error("act(...) is not supported in production builds of React.")},n.useCallback=function(e,n){return R.current.useCallback(e,n)},n.useContext=function(e){return R.current.useContext(e)},n.useDebugValue=function(){},n.useDeferredValue=function(e){return R.current.useDeferredValue(e)},n.useEffect=function(e,n){return R.current.useEffect(e,n)},n.useId=function(){return R.current.useId()},n.useImperativeHandle=function(e,n,t){return R.current.useImperativeHandle(e,n,t)},n.useInsertionEffect=function(e,n){return R.current.useInsertionEffect(e,n)},n.useLayoutEffect=function(e,n){return R.current.useLayoutEffect(e,n)},n.useMemo=function(e,n){return R.current.useMemo(e,n)},n.useReducer=function(e,n,t){return R.current.useReducer(e,n,t)},n.useRef=function(e){return R.current.useRef(e)},n.useState=function(e){return R.current.useState(e)},n.useSyncExternalStore=function(e,n,t){return R.current.useSyncExternalStore(e,n,t)},n.useTransition=function(){return R.current.useTransition()},n.version="18.2.0"},50959:(e,n,t)=>{e.exports=t(95257)},85568:(e,n)=>{function t(e,n){var t=e.length;e.push(n);e:for(;0<t;){var r=t-1>>>1,l=e[r];if(!(0<a(l,n)))break e;e[r]=n,e[t]=l,t=r}}function r(e){return 0===e.length?null:e[0]}function l(e){if(0===e.length)return null;var n=e[0],t=e.pop();if(t!==n){e[0]=t;e:for(var r=0,l=e.length,u=l>>>1;r<u;){var o=2*(r+1)-1,i=e[o],s=o+1,c=e[s];if(0>a(i,t))s<l&&0>a(c,i)?(e[r]=c,e[s]=t,r=s):(e[r]=i,e[o]=t,r=o);else{if(!(s<l&&0>a(c,t)))break e;e[r]=c,e[s]=t,r=s}}}return n}function a(e,n){var t=e.sortIndex-n.sortIndex;return 0!==t?t:e.id-n.id}if("object"==typeof performance&&"function"==typeof performance.now){var u=performance;n.unstable_now=function(){return u.now()}}else{var o=Date,i=o.now();n.unstable_now=function(){return o.now()-i}}var s=[],c=[],f=1,d=null,p=3,m=!1,h=!1,g=!1,v="function"==typeof setTimeout?setTimeout:null,y="function"==typeof clearTimeout?clearTimeout:null,b="undefined"!=typeof setImmediate?setImmediate:null;function k(e){for(var n=r(c);null!==n;){if(null===n.callback)l(c);else{if(!(n.startTime<=e))break;l(c),n.sortIndex=n.expirationTime,t(s,n)}n=r(c)}}function w(e){if(g=!1,k(e),!h)if(null!==r(s))h=!0,M(S);else{var n=r(c);null!==n&&F(w,n.startTime-e)}}function S(e,t){h=!1,g&&(g=!1,y(_),_=-1),m=!0;var a=p;try{for(k(t),d=r(s);null!==d&&(!(d.expirationTime>t)||e&&!z());){var u=d.callback;if("function"==typeof u){d.callback=null,p=d.priorityLevel;var o=u(d.expirationTime<=t);t=n.unstable_now(),"function"==typeof o?d.callback=o:d===r(s)&&l(s),k(t)}else l(s);d=r(s)}if(null!==d)var i=!0;else{var f=r(c);null!==f&&F(w,f.startTime-t),i=!1}return i}finally{d=null,p=a,m=!1}}
|
||||
"undefined"!=typeof navigator&&void 0!==navigator.scheduling&&void 0!==navigator.scheduling.isInputPending&&navigator.scheduling.isInputPending.bind(navigator.scheduling);var x,E=!1,C=null,_=-1,P=5,N=-1;function z(){return!(n.unstable_now()-N<P)}function T(){if(null!==C){var e=n.unstable_now();N=e;var t=!0;try{t=C(!0,e)}finally{t?x():(E=!1,C=null)}}else E=!1}if("function"==typeof b)x=function(){b(T)};else if("undefined"!=typeof MessageChannel){var L=new MessageChannel,R=L.port2;L.port1.onmessage=T,x=function(){R.postMessage(null)}}else x=function(){v(T,0)};function M(e){C=e,E||(E=!0,x())}function F(e,t){_=v((function(){e(n.unstable_now())}),t)}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(e){e.callback=null},n.unstable_continueExecution=function(){h||m||(h=!0,M(S))},n.unstable_forceFrameRate=function(e){0>e||125<e?console.error("forceFrameRate takes a positive int between 0 and 125, forcing frame rates higher than 125 fps is not supported"):P=0<e?Math.floor(1e3/e):5},n.unstable_getCurrentPriorityLevel=function(){return p},n.unstable_getFirstCallbackNode=function(){return r(s)},n.unstable_next=function(e){switch(p){case 1:case 2:case 3:var n=3;break;default:n=p}var t=p;p=n;try{return e()}finally{p=t}},n.unstable_pauseExecution=function(){},n.unstable_requestPaint=function(){},n.unstable_runWithPriority=function(e,n){switch(e){case 1:case 2:case 3:case 4:case 5:break;default:e=3}var t=p;p=e;try{return n()}finally{p=t}},n.unstable_scheduleCallback=function(e,l,a){var u=n.unstable_now();switch("object"==typeof a&&null!==a?a="number"==typeof(a=a.delay)&&0<a?u+a:u:a=u,e){case 1:var o=-1;break;case 2:o=250;break;case 5:o=1073741823;break;case 4:o=1e4;break;default:o=5e3}return e={id:f++,callback:l,priorityLevel:e,startTime:a,expirationTime:o=a+o,sortIndex:-1},a>u?(e.sortIndex=a,t(c,e),null===r(s)&&e===r(c)&&(g?(y(_),_=-1):g=!0,F(w,a-u))):(e.sortIndex=o,t(s,e),h||m||(h=!0,M(S))),e},n.unstable_shouldYield=z,n.unstable_wrapCallback=function(e){var n=p;return function(){var t=p;p=n;try{return e.apply(this,arguments)}finally{p=t}}}},22962:(e,n,t)=>{e.exports=t(85568)}}]);
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -0,0 +1 @@
|
||||
.priceScaleModeButton-okRV4Kjm{--priceScaleModeButtons-color:var(--color-content-primary-neutral-bold);--priceScaleModeButtons-background-hover:var(--color-container-fill-primary-neutral-extra-light);--priceScaleModeButtons-background-active:var(--color-container-fill-primary-neutral-light);--priceScaleModeButtons-border:var(--color-border-primary-neutral-light);--priceScaleModeButtons-activated-color:var(--color-content-secondary-inverse);--priceScaleModeButtons-activated-background:var(--color-container-fill-primary-neutral-extra-bold);--priceScaleModeButtons-activated-border:var(--color-container-fill-primary-neutral-extra-bold);--priceScaleModeButtons-activated-border-hover:var(--color-container-fill-primary-neutral-bold);--priceScaleModeButtons-activated-background-hover:var(--color-container-fill-primary-neutral-bold);font-family:-apple-system,BlinkMacSystemFont,Trebuchet MS,Roboto,Ubuntu,sans-serif;font-feature-settings:"tnum" on,"lnum" on;font-style:normal;--ui-lib-typography-font-size:14px;font-size:var(--ui-lib-typography-font-size);font-weight:400;--ui-lib-typography-line-height:18px;background-color:initial;border:1px solid var(--priceScaleModeButtons-border);border-radius:4px;color:var(--priceScaleModeButtons-color);display:flex;justify-content:center;line-height:var(--ui-lib-typography-line-height);padding:1px 0;width:20px}@media (any-hover:hover){.priceScaleModeButton-okRV4Kjm:hover{background-color:var(--priceScaleModeButtons-background-hover)}}.priceScaleModeButton-okRV4Kjm:active{background-color:var(--priceScaleModeButtons-background-active)}.priceScaleModeButton_activated-okRV4Kjm{background-color:var(--priceScaleModeButtons-activated-background);border-color:var(--priceScaleModeButtons-activated-border);color:var(--priceScaleModeButtons-activated-color)}@media (any-hover:hover){.priceScaleModeButton_activated-okRV4Kjm:hover{background-color:var(--priceScaleModeButtons-activated-background-hover);border-color:var(--priceScaleModeButtons-activated-border-hover)}}.priceScaleModeButtons-PEm49B2T{box-sizing:border-box;display:flex;justify-content:center;width:100%}.priceScaleModeButtons__buttonWrapper-PEm49B2T{display:flex;flex:1 1;padding:4px}.priceScaleModeButtons__buttonWrapper-PEm49B2T:first-child{justify-content:flex-end;padding-right:2px}.priceScaleModeButtons__buttonWrapper-PEm49B2T:last-child{justify-content:flex-start;padding-left:2px}.chart-widget__bottom--themed-light .priceScaleModeButtons__button-PEm49B2T{--priceScaleModeButtons-color:var(--color-cold-gray-900);--priceScaleModeButtons-background-hover:var(--color-cold-gray-100);--priceScaleModeButtons-background-active:var(--color-cold-gray-150);--priceScaleModeButtons-border:var(--color-cold-gray-150);--priceScaleModeButtons-activated-color:var(--color-white);--priceScaleModeButtons-activated-background:var(--color-cold-gray-800);--priceScaleModeButtons-activated-border:var(--color-cold-gray-800);--priceScaleModeButtons-activated-border-hover:var(--color-cold-gray-700);--priceScaleModeButtons-activated-background-hover:var(--color-cold-gray-700)}.chart-widget__bottom--themed-dark .priceScaleModeButtons__button-PEm49B2T{--priceScaleModeButtons-color:var(--color-cold-gray-200);--priceScaleModeButtons-background-hover:var(--color-cold-gray-800);--priceScaleModeButtons-background-active:var(--color-cold-gray-750);--priceScaleModeButtons-border:var(--color-cold-gray-700);--priceScaleModeButtons-activated-color:var(--color-cold-gray-900);--priceScaleModeButtons-activated-background:var(--color-cold-gray-100);--priceScaleModeButtons-activated-border:var(--color-cold-gray-100);--priceScaleModeButtons-activated-border-hover:var(--color-cold-gray-200);--priceScaleModeButtons-activated-background-hover:var(--color-cold-gray-200)}
|
||||
@@ -0,0 +1 @@
|
||||
.priceScaleModeButton-okRV4Kjm{--priceScaleModeButtons-color:var(--color-content-primary-neutral-bold);--priceScaleModeButtons-background-hover:var(--color-container-fill-primary-neutral-extra-light);--priceScaleModeButtons-background-active:var(--color-container-fill-primary-neutral-light);--priceScaleModeButtons-border:var(--color-border-primary-neutral-light);--priceScaleModeButtons-activated-color:var(--color-content-secondary-inverse);--priceScaleModeButtons-activated-background:var(--color-container-fill-primary-neutral-extra-bold);--priceScaleModeButtons-activated-border:var(--color-container-fill-primary-neutral-extra-bold);--priceScaleModeButtons-activated-border-hover:var(--color-container-fill-primary-neutral-bold);--priceScaleModeButtons-activated-background-hover:var(--color-container-fill-primary-neutral-bold);font-family:-apple-system,BlinkMacSystemFont,Trebuchet MS,Roboto,Ubuntu,sans-serif;font-feature-settings:"tnum" on,"lnum" on;font-style:normal;--ui-lib-typography-font-size:14px;font-size:var(--ui-lib-typography-font-size);font-weight:400;--ui-lib-typography-line-height:18px;background-color:initial;border:1px solid var(--priceScaleModeButtons-border);border-radius:4px;color:var(--priceScaleModeButtons-color);display:flex;justify-content:center;line-height:var(--ui-lib-typography-line-height);padding:1px 0;width:20px}@media (any-hover:hover){.priceScaleModeButton-okRV4Kjm:hover{background-color:var(--priceScaleModeButtons-background-hover)}}.priceScaleModeButton-okRV4Kjm:active{background-color:var(--priceScaleModeButtons-background-active)}.priceScaleModeButton_activated-okRV4Kjm{background-color:var(--priceScaleModeButtons-activated-background);border-color:var(--priceScaleModeButtons-activated-border);color:var(--priceScaleModeButtons-activated-color)}@media (any-hover:hover){.priceScaleModeButton_activated-okRV4Kjm:hover{background-color:var(--priceScaleModeButtons-activated-background-hover);border-color:var(--priceScaleModeButtons-activated-border-hover)}}.priceScaleModeButtons-PEm49B2T{box-sizing:border-box;display:flex;justify-content:center;width:100%}.priceScaleModeButtons__buttonWrapper-PEm49B2T{display:flex;flex:1 1;padding:4px}.priceScaleModeButtons__buttonWrapper-PEm49B2T:first-child{justify-content:flex-end;padding-left:2px}.priceScaleModeButtons__buttonWrapper-PEm49B2T:last-child{justify-content:flex-start;padding-right:2px}.chart-widget__bottom--themed-light .priceScaleModeButtons__button-PEm49B2T{--priceScaleModeButtons-color:var(--color-cold-gray-900);--priceScaleModeButtons-background-hover:var(--color-cold-gray-100);--priceScaleModeButtons-background-active:var(--color-cold-gray-150);--priceScaleModeButtons-border:var(--color-cold-gray-150);--priceScaleModeButtons-activated-color:var(--color-white);--priceScaleModeButtons-activated-background:var(--color-cold-gray-800);--priceScaleModeButtons-activated-border:var(--color-cold-gray-800);--priceScaleModeButtons-activated-border-hover:var(--color-cold-gray-700);--priceScaleModeButtons-activated-background-hover:var(--color-cold-gray-700)}.chart-widget__bottom--themed-dark .priceScaleModeButtons__button-PEm49B2T{--priceScaleModeButtons-color:var(--color-cold-gray-200);--priceScaleModeButtons-background-hover:var(--color-cold-gray-800);--priceScaleModeButtons-background-active:var(--color-cold-gray-750);--priceScaleModeButtons-border:var(--color-cold-gray-700);--priceScaleModeButtons-activated-color:var(--color-cold-gray-900);--priceScaleModeButtons-activated-background:var(--color-cold-gray-100);--priceScaleModeButtons-activated-border:var(--color-cold-gray-100);--priceScaleModeButtons-activated-border-hover:var(--color-cold-gray-200);--priceScaleModeButtons-activated-background-hover:var(--color-cold-gray-200)}
|
||||
@@ -0,0 +1,7 @@
|
||||
(self.webpackChunktradingview=self.webpackChunktradingview||[]).push([[2477],{97754:(e,t)=>{var n;!function(){"use strict";var s={}.hasOwnProperty;function r(){for(var e=[],t=0;t<arguments.length;t++){var n=arguments[t];if(n){var i=typeof n;if("string"===i||"number"===i)e.push(n);else if(Array.isArray(n)&&n.length){var o=r.apply(null,n);o&&e.push(o)}else if("object"===i)for(var a in n)s.call(n,a)&&n[a]&&e.push(a)}}return e.join(" ")}e.exports?(r.default=r,e.exports=r):void 0===(n=function(){return r}.apply(t,[]))||(e.exports=n)}()},17946:(e,t,n)=>{"use strict";n.d(t,{CustomBehaviourContext:()=>s});const s=(0,n(50959).createContext)({enableActiveStateStyles:!0});s.displayName="CustomBehaviourContext"},43010:(e,t,n)=>{"use strict";n.d(t,{useIsomorphicLayoutEffect:()=>r});var s=n(50959);function r(e,t){("undefined"==typeof window?s.useEffect:s.useLayoutEffect)(e,t)}},27267:(e,t,n)=>{"use strict";function s(e,t,n,s,r){function i(r){if(e>r.timeStamp)return;const i=r.target;void 0!==n&&null!==t&&null!==i&&i.ownerDocument===s&&(t.contains(i)||n(r))}return r.click&&s.addEventListener("click",i,!1),r.mouseDown&&s.addEventListener("mousedown",i,!1),r.touchEnd&&s.addEventListener("touchend",i,!1),r.touchStart&&s.addEventListener("touchstart",i,!1),()=>{s.removeEventListener("click",i,!1),s.removeEventListener("mousedown",i,!1),s.removeEventListener("touchend",i,!1),s.removeEventListener("touchstart",i,!1)}}n.d(t,{addOutsideEventListener:()=>s})},9745:(e,t,n)=>{"use strict";n.d(t,{Icon:()=>r});var s=n(50959);const r=s.forwardRef(((e,t)=>{const{icon:n="",title:r,ariaLabel:i,ariaLabelledby:o,ariaHidden:a,...l}=e,u=!!(r||i||o);return s.createElement("span",{role:"img",...l,ref:t,"aria-label":i,"aria-labelledby":o,"aria-hidden":a||!u,title:r,dangerouslySetInnerHTML:{__html:n}})}))},19250:(e,t,n)=>{"use strict";n.d(t,{Portal:()=>u,PortalContext:()=>d});var s=n(50959),r=n(32227),i=n(25931),o=n(67961),a=n(34811),l=n(99663);class u extends s.PureComponent{constructor(){super(...arguments),this._uuid=(0,i.nanoid)()}componentWillUnmount(){this._manager().removeWindow(this._uuid)}render(){const e=this._manager().ensureWindow(this._uuid,this.props.layerOptions);e.style.top=this.props.top||"",e.style.bottom=this.props.bottom||"",e.style.left=this.props.left||"",e.style.right=this.props.right||"",e.style.pointerEvents=this.props.pointerEvents||"";const t=this.props.className;return t&&("string"==typeof t?e.classList.add(t):e.classList.add(...t)),this.props.shouldTrapFocus&&!e.hasAttribute(a.FOCUS_TRAP_DATA_ATTRIBUTE)&&e.setAttribute(a.FOCUS_TRAP_DATA_ATTRIBUTE,"true"),this.props["aria-hidden"]&&e.setAttribute("aria-hidden","true"),r.createPortal(s.createElement(d.Provider,{value:this},this.props.children),e)}moveToTop(){this._manager().moveToTop(this._uuid)}_manager(){return null===this.context?(0,o.getRootOverlapManager)():this.context}}u.contextType=l.SlotContext;const d=s.createContext(null)},99663:(e,t,n)=>{"use strict";n.d(t,{Slot:()=>r,SlotContext:()=>i});var s=n(50959);class r extends s.Component{shouldComponentUpdate(){return!1}
|
||||
render(){return s.createElement("div",{style:{position:"fixed",zIndex:150,left:0,top:0},ref:this.props.reference})}}const i=s.createContext(null)},90186:(e,t,n)=>{"use strict";function s(e){return i(e,o)}function r(e){return i(e,a)}function i(e,t){const n=Object.entries(e).filter(t),s={};for(const[e,t]of n)s[e]=t;return s}function o(e){const[t,n]=e;return 0===t.indexOf("data-")&&"string"==typeof n}function a(e){return 0===e[0].indexOf("aria-")}n.d(t,{filterAriaProps:()=>r,filterDataProps:()=>s,filterProps:()=>i,isAriaAttribute:()=>a,isDataAttribute:()=>o})},67961:(e,t,n)=>{"use strict";n.d(t,{OverlapManager:()=>o,getRootOverlapManager:()=>l});var s=n(50151),r=n(34811);class i{constructor(){this._storage=[]}add(e){this._storage.push(e)}remove(e){this._storage=this._storage.filter((t=>e!==t))}has(e){return this._storage.includes(e)}getItems(){return this._storage}}class o{constructor(e=document){this._storage=new i,this._windows=new Map,this._index=0,this._document=e,this._container=e.createDocumentFragment()}setContainer(e){const t=this._container,n=null===e?this._document.createDocumentFragment():e;!function(e,t){Array.from(e.childNodes).forEach((e=>{e.nodeType===Node.ELEMENT_NODE&&t.appendChild(e)}))}(t,n),this._container=n}registerWindow(e){this._storage.has(e)||this._storage.add(e)}ensureWindow(e,t={position:"fixed",direction:"normal"}){const n=this._windows.get(e);if(void 0!==n)return n;this.registerWindow(e);const s=this._document.createElement("div");if(s.style.position=t.position,s.style.zIndex=this._index.toString(),s.dataset.id=e,void 0!==t.index){const e=this._container.childNodes.length;if(t.index>=e)this._container.appendChild(s);else if(t.index<=0)this._container.insertBefore(s,this._container.firstChild);else{const e=this._container.childNodes[t.index];this._container.insertBefore(s,e)}}else"reverse"===t.direction?this._container.insertBefore(s,this._container.firstChild):this._container.appendChild(s);return this._windows.set(e,s),++this._index,s}unregisterWindow(e){this._storage.remove(e);const t=this._windows.get(e);void 0!==t&&(null!==t.parentElement&&t.parentElement.removeChild(t),this._windows.delete(e))}getZindex(e){const t=this.ensureWindow(e);return parseInt(t.style.zIndex||"0")}moveLastWindowToTop(){const e=this._storage.getItems(),t=e[e.length-1];t&&this.moveToTop(t)}moveToTop(e){if(this.getZindex(e)!==this._index){const t=this.ensureWindow(e);this._windows.forEach(((e,n)=>{e.hasAttribute(r.FOCUS_TRAP_DATA_ATTRIBUTE)&&e.setAttribute(r.FOCUS_TRAP_DATA_ATTRIBUTE,e===t?"true":"false")})),t.style.zIndex=(++this._index).toString()}}removeWindow(e){this.unregisterWindow(e)}}const a=new WeakMap;function l(e=document){const t=e.getElementById("overlap-manager-root");if(null!==t)return(0,s.ensureDefined)(a.get(t));{const t=new o(e),n=function(e){const t=e.createElement("div");return t.style.position="absolute",t.style.zIndex=150..toString(),t.style.top="0px",t.style.left="0px",t.id="overlap-manager-root",t.dataset.qaId="overlap-manager-root",t}(e);return a.set(n,t),t.setContainer(n),
|
||||
e.body.appendChild(n),t}}var u;!function(e){e[e.BaseZindex=150]="BaseZindex"}(u||(u={}))},36279:(e,t,n)=>{"use strict";var s;n.d(t,{LogoSize:()=>s,getLogoUrlResolver:()=>o}),function(e){e[e.Medium=0]="Medium",e[e.Large=1]="Large"}(s||(s={}));class r{getSymbolLogoUrl(e){return e}collectSymbolLogoUrls(e,t){return[]}getCountryFlagUrl(){return""}getCryptoLogoUrl(e){return e}getProviderLogoUrl(e){return e}getSourceLogoUrl(e){return e}getBlockchainContractLogoUrl(e){return e}}let i;function o(){return i||(i=new r),i}},77975:(e,t,n)=>{"use strict";n.d(t,{useWatchedValueReadonly:()=>r});var s=n(50959);const r=(e,t=!1,n=[])=>{const r="watchedValue"in e?e.watchedValue:void 0,i="defaultValue"in e?e.defaultValue:e.watchedValue.value(),[o,a]=(0,s.useState)(r?r.value():i);return(t?s.useLayoutEffect:s.useEffect)((()=>{if(r){a(r.value());const e=e=>a(e);return r.subscribe(e),()=>r.unsubscribe(e)}return()=>{}}),[r,...n]),o}},4237:(e,t,n)=>{"use strict";var s=n(32227);t.createRoot=s.createRoot,s.hydrateRoot},47596:e=>{e.exports={wrapper:"wrapper-hPiAkrn3",timezone:"timezone-hPiAkrn3",largePadding:"largePadding-hPiAkrn3",sessionDayWrapper:"sessionDayWrapper-hPiAkrn3",nowWrapper:"nowWrapper-hPiAkrn3",now:"now-hPiAkrn3",sessionDay:"sessionDay-hPiAkrn3",weekDay:"weekDay-hPiAkrn3",sessionDaySegments:"sessionDaySegments-hPiAkrn3",timeMarkWrapper:"timeMarkWrapper-hPiAkrn3",timeMarkSegment:"timeMarkSegment-hPiAkrn3",timeMark:"timeMark-hPiAkrn3",timeMarkSegmentAlignByEnds:"timeMarkSegmentAlignByEnds-hPiAkrn3",segment:"segment-hPiAkrn3",small:"small-hPiAkrn3",start:"start-hPiAkrn3",end:"end-hPiAkrn3",active:"active-hPiAkrn3",green:"green-hPiAkrn3",orange:"orange-hPiAkrn3",blue:"blue-hPiAkrn3",gray:"gray-hPiAkrn3",tooltip:"tooltip-hPiAkrn3",time:"time-hPiAkrn3"}},1445:(e,t,n)=>{"use strict";n.d(t,{FullSessionScheduleRenderer:()=>A});var s=n(50959),r=n(97754),i=n(50151),o=n(11542),a=n(77975),l=n(4226),u=n(47596);const d=new WeakMap;function c(e){return d.has(e)||d.set(e,(0,l.randomHash)()),(0,i.ensureDefined)(d.get(e))}const m=new Map([[0,u.green],[1,u.orange],[2,u.blue],[3,u.gray]]),h=new Map([[0,o.t(null,void 0,n(80086))],[1,o.t(null,void 0,n(36018))],[2,o.t(null,void 0,n(73897))],[3,o.t(null,void 0,n(62464))]]),v=o.t(null,void 0,n(63538));var p;function f(e){const{segment:t,forceStart:n,forceEnd:i}=e,o=t.end.value-t.start.value,a=o<.03,l={left:100*t.start.value+"%",width:`calc(${100*o}% + ${a?2:0}px)`},d=r(u.segment,m.get(t.type),(n||t.start.isFirstOrLastPoint)&&u.start,(i||t.end.isFirstOrLastPoint)&&u.end,a&&u.small,"common-tooltip-html","apply-common-tooltip"),c=function(e,t){return`<div class="${u.tooltip}">\n\t\t<span class="${m.get(t)}">${h.get(t)}</span>\n\t\t<span class="${u.time}">${e}</span>\n\t</div>`}(t.tooltip,t.type);return s.createElement("div",{className:d,style:l,"data-tooltip":c})}function y(e){const{sessionDay:t}=e,n=t.entries.map(((e,n)=>s.createElement(f,{key:`${c(e)}Segment`,segment:e,forceStart:0===n&&3===e.type,forceEnd:n===t.entries.length-1&&3===e.type}))),i=r(u.sessionDay,t.isActive&&u.active)
|
||||
;return s.createElement("div",{className:i},s.createElement("div",{className:u.weekDay},t.title),s.createElement("div",{className:u.sessionDaySegments},n))}function g(e){const{sessionDays:t,currentTimeMark:n}=e,i=[],o=parseInt(Object.keys(t).filter((e=>t[parseInt(e)].isActive))[0]),a=t[o].entries.filter((e=>e.start.value<=n&&e.end.value>=n))[0];if((a.start.isFirstOrLastPoint||3===a.type)&&i.push(a.start),(a.end.isFirstOrLastPoint||3===a.type)&&i.push(a.end),0===i.length)return null;i.sort(((e,t)=>e.value-t.value));const l=i.map((e=>s.createElement("div",{key:c(e),className:u.timeMark},e.title))),d=100*(2===i.length?i[1].value-i[0].value:0),m=r(d>12&&u.timeMarkSegmentAlignByEnds,u.timeMarkSegment);return s.createElement("div",{className:u.sessionDay},s.createElement("div",{className:u.weekDay}),s.createElement("div",{className:u.timeMarkWrapper},s.createElement("div",{className:m,style:{left:100*i[0].value+"%",width:`${d}%`}},l)))}function A(e){const{className:t,timezone:n,showAllDays:i,timeZoneClassName:o}=e,l=(0,a.useWatchedValueReadonly)({watchedValue:e.sessionDays}),d=(0,a.useWatchedValueReadonly)({watchedValue:e.now}),c=Object.values(l).filter((e=>e.isActive))[0],m=r(t,u.wrapper);return s.createElement("div",{className:m},s.createElement("div",{className:u.sessionDayWrapper},i?s.createElement(s.Fragment,null,Object.values(l).map(((e,t)=>s.createElement(y,{key:t,sessionDay:e})))):s.createElement(y,{sessionDay:c}),s.createElement("div",{className:u.nowWrapper},s.createElement("div",{className:u.now,style:{left:100*d+"%"}}))),s.createElement(g,{sessionDays:l,currentTimeMark:d}),s.createElement("div",{className:r(u.timezone,o,i&&u.largePadding)},`${v}: ${n}`))}!function(e){e[e.MinSegmentWidth=12]="MinSegmentWidth",e[e.SmallWidth=.03]="SmallWidth"}(p||(p={}))},22166:(e,t,n)=>{"use strict";n.d(t,{FullSessionScheduleViewModel:()=>G});var s=n(10845),r=n(87465),i=n(37236),o=n(22613),a=n(95059);function l(e){return e/i.minutesPerDay}function u(e){return Math.round(e*i.minutesPerDay)}var d,c,m=n(50151),h=n(58043);!function(e){e[e.SUNDAY=1]="SUNDAY",e[e.MONDAY=2]="MONDAY",e[e.TUESDAY=3]="TUESDAY",e[e.WEDNESDAY=4]="WEDNESDAY",e[e.THURSDAY=5]="THURSDAY",e[e.FRIDAY=6]="FRIDAY",e[e.SATURDAY=7]="SATURDAY"}(d||(d={})),function(e){e[e.JANUARY=0]="JANUARY",e[e.FEBRUARY=1]="FEBRUARY",e[e.MARCH=2]="MARCH",e[e.APRIL=3]="APRIL",e[e.MAY=4]="MAY",e[e.JUNE=5]="JUNE",e[e.JULY=6]="JULY",e[e.AUGUST=7]="AUGUST",e[e.SEPTEMBER=8]="SEPTEMBER",e[e.OCTOBER=9]="OCTOBER",e[e.NOVEMBER=10]="NOVEMBER",e[e.DECEMBER=11]="DECEMBER"}(c||(c={}));const v=[d.SUNDAY,d.MONDAY,d.TUESDAY,d.WEDNESDAY,d.THURSDAY,d.FRIDAY,d.SATURDAY];function p(e){return t=>function(e,t){return(e+t+6)%7+1}(t,e)}const f=p(-1),y=p(1);const g=function(e){return e&&e.length?e[0]:void 0};var A=n(82593),E=n(11542);c.JANUARY,E.t(null,void 0,n(200)),c.FEBRUARY,E.t(null,void 0,n(81069)),c.MARCH,E.t(null,void 0,n(93878)),c.APRIL,E.t(null,void 0,n(28896)),c.MAY,E.t(null,void 0,n(25734)),c.JUNE,E.t(null,void 0,n(61487)),c.JULY,E.t(null,void 0,n(6608)),c.AUGUST,E.t(null,void 0,n(11081)),
|
||||
c.SEPTEMBER,E.t(null,void 0,n(32179)),c.OCTOBER,E.t(null,void 0,n(37997)),c.NOVEMBER,E.t(null,void 0,n(4607)),c.DECEMBER,E.t(null,void 0,n(90082)),c.JANUARY,E.t(null,void 0,n(62310)),c.FEBRUARY,E.t(null,void 0,n(2507)),c.MARCH,E.t(null,void 0,n(92767)),c.APRIL,E.t(null,void 0,n(27072)),c.MAY,E.t(null,{context:"short"},n(13132)),c.JUNE,E.t(null,void 0,n(429)),c.JULY,E.t(null,void 0,n(53786)),c.AUGUST,E.t(null,void 0,n(46450)),c.SEPTEMBER,E.t(null,void 0,n(6816)),c.OCTOBER,E.t(null,void 0,n(12179)),c.NOVEMBER,E.t(null,void 0,n(26899)),c.DECEMBER,E.t(null,void 0,n(32084)),d.SUNDAY,E.t(null,void 0,n(61480)),d.MONDAY,E.t(null,void 0,n(19573)),d.TUESDAY,E.t(null,void 0,n(82160)),d.WEDNESDAY,E.t(null,void 0,n(94226)),d.THURSDAY,E.t(null,void 0,n(79137)),d.FRIDAY,E.t(null,void 0,n(3570)),d.SATURDAY,E.t(null,void 0,n(30348));const _={[d.SUNDAY]:E.t(null,void 0,n(77493)),[d.MONDAY]:E.t(null,void 0,n(50872)),[d.TUESDAY]:E.t(null,void 0,n(11916)),[d.WEDNESDAY]:E.t(null,void 0,n(11532)),[d.THURSDAY]:E.t(null,void 0,n(71388)),[d.FRIDAY]:E.t(null,void 0,n(22928)),[d.SATURDAY]:E.t(null,void 0,n(32273))};d.SUNDAY,E.t(null,{context:"day_of_week"},n(75005)),d.MONDAY,E.t(null,{context:"day_of_week"},n(30961)),d.TUESDAY,E.t(null,{context:"day_of_week"},n(9135)),d.WEDNESDAY,E.t(null,{context:"day_of_week"},n(92578)),d.THURSDAY,E.t(null,{context:"day_of_week"},n(8765)),d.FRIDAY,E.t(null,{context:"day_of_week"},n(23230)),d.SATURDAY,E.t(null,{context:"day_of_week"},n(94748));var D=n(95322);function w(e){for((0,m.assert)(Number.isInteger(e),"timeMinutes expected to be integer number");e>i.minutesPerDay;)e-=i.minutesPerDay;const t=e%60,n=(e-t)/60;return(0,D.numberToStringWithLeadingZero)(n,2)+":"+(0,D.numberToStringWithLeadingZero)(t,2)}function S(e,t){return`${e} — ${t}`}function T(e,t){return`${_[e]} ${w(t)}`}function x(e,t,n,s){(0,m.assert)(t!==i.minutesPerDay,"Start time expected to be normalized (24:00 as range start is not allowed)"),(0,m.assert)(0!==s,"End time expected to be normalized (00:00 as range end is not allowed)");const r=function(e,t,n,s){const r=e*i.minutesPerDay+t;let o=n*i.minutesPerDay+s;return o<r&&(o+=7*i.minutesPerDay),o-r}(e,t,n,s);return r<i.minutesPerDay||r===i.minutesPerDay&&0===t?function(e,t){return S(w(e),w(t))}(t,s):function(e,t,n,s){return S(T(e,t),T(n,s))}(e,t,n,s)}function R(e,t){return{value:e,title:w(u(e)),isFirstOrLastPoint:t}}function k(e){return 3!==e.type}function U(e,t){return{dayIndex:e,entries:t.filter(k)}}function P(e,t,n,s=t){const r=n(t),i=e[r];return r!==s&&0===i.entries.length?P(e,r,n,s):U(r,e[r].entries)}function M(e){return(t,n)=>P(t,n,e)}const b=M(f),I=M(y);function N(e,t,n,s){return(r,i,o)=>void 0===r?[s,o]:r===e?[t,n(i)]:[r,i]}const Y=N(1,0,y,0),C=N(0,1,f,1);function L(e,t,n,s,r){const[i,o]=Y(e,t,r),[a,l]=C(n,s,r);(0,m.assert)(t!==n||i<a,`Days are same (${t}) but prev entry time (${i}) >= next entry time (${a})`);const d=u(i),c=u(a);return h=R(o!==r?0:i,o===r),v=R(l!==r?1:a,l===r),p=3,f=x(o,d,l,c),{start:h,end:v,type:p,tooltip:f};var h,v,p,f}function W(e,t,n,s,r){
|
||||
return L(e?.end?.value,t,n?.start?.value,s,r)}function O(e){const t=[...e.entries];for(let n=1;n<e.entries.length;n++){const s=e.entries[n-1],r=e.entries[n];if(r.start.value!==s.end.value){const n=W(s,e.dayIndex,r,e.dayIndex,e.dayIndex);t.push(n)}}return t.sort(((e,t)=>e.start.value-t.start.value)),t}function B(e,t){const n=(0,A.default)(t.entries),s=t.dayIndex,r=(0,m.ensureDefined)(g(e.entries));return 0===r.start.value?[]:[W(n,s,r,e.dayIndex,e.dayIndex)]}function F(e,t){const n=g(t.entries),s=t.dayIndex,r=(0,m.ensureDefined)((0,A.default)(e.entries));return 1===r.end.value?[]:[W(r,e.dayIndex,n,s,e.dayIndex)]}function V(e,t){const n={thisDay:U(e,t[e].entries),prevDay:b(t,e),nextDay:I(t,e)};return function({thisDay:e,prevDay:t,nextDay:n}){if(0===e.entries.length)return[W((0,A.default)(t.entries),t.dayIndex,g(n.entries),n.dayIndex,e.dayIndex)]}(n)??function({thisDay:e,prevDay:t,nextDay:n}){const s=e.dayIndex;if(t.dayIndex!==s||n.dayIndex!==s)return;const i=e.entries,o=(0,m.ensureDefined)(g(i)),a=(0,m.ensureDefined)((0,A.default)(i));return[0!==o.start.value?L(0,s,o.start.value,s,s):void 0,...O(e),1!==a.end.value?L(a.end.value,s,1,s,s):void 0].filter(r.isExistent)}(n)??function(e){return[...B(e.thisDay,e.prevDay),...O(e.thisDay),...F(e.thisDay,e.nextDay)]}(n)}var z=n(16329);const $=function(e){for(var t=-1,n=null==e?0:e.length,s={};++t<n;){var r=e[t];s[r[0]]=r[1]}return s}(v.map((e=>[e,{title:_[e],isActive:!1,entries:[]}])));function H(e,t,n){const s=e[n].entries;s.push(t),s.sort(((e,t)=>e.start.value-t.start.value))}function J(e,t){const n=function(e){if(null===e)return new Map;if(void 0===e.subsessions)return new Map([[0,new z.SessionsSpec(e.timezone,e.session_display??e.session,e.session_holidays,e.corrections)]]);const t="regular",n="premarket",s="postmarket",r=[t,n,s],i=new Map;for(const o of r){let r=null;switch(o){case t:r=0;break;case n:r=1;break;case s:r=2}if(null!==r){const t=e.subsessions.find((e=>e.id===o));void 0!==t&&i.set(r,new z.SessionsSpec(e.timezone,t["session-display"]||t.session,e.session_holidays,t["session-correction"]))}}return i}(e),s=t??(0,i.utc_to_cal)((0,i.get_timezone)(e?.timezone??"Etc/UTC"),Date.now()),r=(t?.getUTCDay()??(new Date).getDay())%7+1;const o=(0,h.deepCopy)($);o[r].isActive=!0;for(const e of Array.from(n.keys())){const t=(0,m.ensureDefined)(n.get(e)),r=(0,i.get_day_of_week)(s),a=(0,i.clone)(s);(0,i.add_date)(a,-r),(0,i.set_hms)(a,0,0,0,0);const u=(0,i.clone)(a);(0,i.add_date)(u,7);let d=t.alignToNearestSessionStart(a,t.inSession(a)?-1:1);for(;d.getTime()<u.getTime();){const n=t.alignToNearestSessionEnd(d,1),s=(0,i.get_day_of_week)(d),r=(0,i.get_day_of_week)(n),c=(0,i.get_minutes_from_midnight)(d),m=(0,i.get_minutes_from_midnight)(n)+1,h=l(c),v=l(m),p=x(s,c,r,m);s===r?H(o,{start:R(h,!0),end:R(v,!0),type:e,tooltip:p},s):(d.getTime()>a.getTime()&&H(o,{start:R(h,!0),end:R(1,!1),type:e,tooltip:p},s),n.getTime()<u.getTime()&&H(o,{start:R(0,!1),end:R(v,!0),type:e,tooltip:p},r)),(0,i.add_minutes)(n,1),d=t.alignToNearestSessionStart(n,1)}}return function(e){const t=new Map
|
||||
;for(const n of v)t.set(n,V(n,e));for(const n of v)e[n].entries=(0,m.ensureDefined)(t.get(n))}(o),{newSessionsDays:o,newTodaySession:o[r]}}var Z;function j(e){return(0,i.get_cal_from_unix_timestamp_ms)((0,i.get_timezone)(e.timezone),window.ChartApiInstance.serverTime()-1e3*(0,a.getSymbolDelaySeconds)(e))}!function(e){e[e.Regular=0]="Regular",e[e.Pre=1]="Pre",e[e.Post=2]="Post",e[e.Close=3]="Close"}(Z||(Z={}));class G{constructor(e){this.sessionsDays=new o.WatchedValue((0,r.clone)($)),this.todaySession=new o.WatchedValue((0,r.clone)({entries:[]})),this._currentTime=new o.WatchedValue(-1),this._symbolInfo=e.symbolInfo().spawn(),this._symbolInfo.subscribe(this._updateEntriesBySubSessions.bind(this),{callWithLast:!0}),this._timeIntervalId=setInterval(this._updateTodayWithOffsets.bind(this),6e4)}destroy(){this._symbolInfo.destroy(),clearInterval(this._timeIntervalId)}currentTimeValue(){return this._currentTime.readonly()}timezone(){const e=this._symbolInfo.value();return null===e?"":(0,s.timezoneTitle)(e.timezone)}_updateEntriesBySubSessions(e){this._updateTodayWithOffsets();const{newSessionsDays:t,newTodaySession:n}=J(e,null===e?null:j(e));this.sessionsDays.setValue(t),this.todaySession.setValue(n)}_updateTodayWithOffsets(){const e=this._symbolInfo.value();if(null===e)return void this._currentTime.setValue(-1);const t=this._currentTime.value(),n=l((0,i.get_minutes_from_midnight)(j(e)));this._currentTime.setValue(n),n<t&&this._updateEntriesBySubSessions(e)}}},2948:e=>{e.exports='<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 18 18" width="18" height="18"><path fill="currentColor" d="M3.92 7.83 9 12.29l5.08-4.46-1-1.13L9 10.29l-4.09-3.6-.99 1.14Z"/></svg>'},92315:e=>{e.exports='<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 18 18" width="18" height="18"><path fill="currentColor" d="M9 14A5 5 0 1 0 9 4a5 5 0 0 0 0 10Zm3-4H6V8h6v2Z"/></svg>'},25931:(e,t,n)=>{"use strict";n.d(t,{nanoid:()=>s});let s=(e=21)=>crypto.getRandomValues(new Uint8Array(e)).reduce(((e,t)=>e+=(t&=63)<36?t.toString(36):t<62?(t-26).toString(36).toUpperCase():t>62?"-":"_"),"")}}]);
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -0,0 +1 @@
|
||||
.lollipopTooltipTitle-jFagU3Qi{align-items:center;column-gap:8px;display:flex;justify-content:flex-start;padding:4px 0}.lollipopTooltipTitle_minimal-jFagU3Qi .lollipopTooltipTitle__title-jFagU3Qi{font-size:16px;line-height:22px}.lollipopTooltipTitle_mobile-jFagU3Qi{padding:0}.lollipopTooltipTitle_mobile-jFagU3Qi .lollipopTooltipTitle__title-jFagU3Qi{font-size:20px;line-height:24px}.lollipopTooltipTitle__icon-jFagU3Qi{color:currentColor;display:flex}.lollipopTooltipTitle__title-jFagU3Qi{font-family:-apple-system,BlinkMacSystemFont,Trebuchet MS,Roboto,Ubuntu,sans-serif;font-feature-settings:"tnum" on,"lnum" on;font-style:normal;--ui-lib-typography-font-size:18px;font-size:var(--ui-lib-typography-font-size);font-weight:600;--ui-lib-typography-line-height:24px;line-height:var(--ui-lib-typography-line-height)}[data-theme=dark],[data-theme=light]{--_0--48T:var(--color-tan-orange-600);--_1--48T:var(--color-tan-orange-400);--_2--48T:var(--color-tv-blue-500);--_3--48T:var(--color-tv-blue-400)}.subtitle-cEWFvaCX{font-size:14px;line-height:21px}.subtitle-cEWFvaCX .text-cEWFvaCX{flex:1 0 0;overflow:hidden;text-overflow:ellipsis}.group-cEWFvaCX{padding-top:12px}.groupIcon-cEWFvaCX{border-radius:9px;display:inline-block;height:18px;margin-left:7px;vertical-align:top;width:18px}.groupIcon-cEWFvaCX.beforeMarketOpen-cEWFvaCX{background-color:var(--color-overlay-warning-1-light);color:var(--_0--48T)}@media (any-hover:hover){.groupIcon-cEWFvaCX.beforeMarketOpen-cEWFvaCX:hover{background-color:var(--color-overlay-warning-1-normal)}}.groupIcon-cEWFvaCX.afterMarketClose-cEWFvaCX{background-color:var(--color-overlay-accent-1-light);color:var(--_2--48T)}@media (any-hover:hover){.groupIcon-cEWFvaCX.afterMarketClose-cEWFvaCX:hover{background-color:var(--color-overlay-accent-1-normal)}}.groupTitle-cEWFvaCX{color:var(--color-default-gray);font-size:11px;font-weight:400;letter-spacing:.4px;line-height:16px;text-transform:uppercase}.groupRow-cEWFvaCX{display:flex;flex-direction:row}.groupCell-cEWFvaCX{flex:1 0 0}.group-cEWFvaCX .text-cEWFvaCX{font-size:14px;line-height:22px;overflow:hidden;text-overflow:ellipsis}[data-theme=light]{--_0-UeVb:var(--color-white);--_1-UeVb:var(--color-white)}[data-theme=dark]{--_0-UeVb:var(--color-cold-gray-850);--_1-UeVb:var(--color-cold-gray-850)}.wrap-GPY6iGF_{background:var(--tv-color-popup-background,var(--_1-UeVb))}.title-GPY6iGF_{margin-bottom:12px}.content-GPY6iGF_ a,.content-GPY6iGF_ span{cursor:default}.content-GPY6iGF_.mob-GPY6iGF_ .group-GPY6iGF_ .text-GPY6iGF_,.content-GPY6iGF_.mob-GPY6iGF_ .subtitle-GPY6iGF_{font-size:16px;line-height:24px}.content-GPY6iGF_.mini-GPY6iGF_ .subtitle-GPY6iGF_{font-size:13px;line-height:19px}.anchor-GPY6iGF_{margin-top:12px}[data-theme=light]{--_0-2jh4:var(--color-cold-gray-900);--_1-2jh4:#0000;--_2-2jh4:var(--color-white)}[data-theme=dark]{--_0-2jh4:var(--color-cold-gray-200);--_1-2jh4:#0000;--_2-2jh4:var(--color-cold-gray-900)}.drawer-KpYsc6dH{padding:0}.drawer-KpYsc6dH>:not(:last-child){border-bottom:1px solid var(--color-cold-gray-150)}.drawerItem-KpYsc6dH{color:var(--_0-2jh4);padding:16px}.menuWrap-KpYsc6dH{background:var(--_1-2jh4);box-shadow:0 0 var(--_1-2jh4)}.menuWrap-KpYsc6dH .scrollWrap-KpYsc6dH{overflow-y:hidden!important}.menuWrap-KpYsc6dH .menuBox-KpYsc6dH{margin:2px 4px 4px;padding:0}.card-KpYsc6dH{border-left:4px solid;border-radius:4px;box-shadow:0 2px 4px 0 var(--color-other-shadow-primary-neutral-extra-heavy);box-sizing:border-box;color:var(--_0-2jh4);padding:12px 12px 16px;width:300px}.card-KpYsc6dH:not(:first-child){margin-top:8px}.fadeTop-KpYsc6dH{background:linear-gradient(180deg,#fff,#fff0);height:10px;position:absolute;top:0}html.theme-dark .fadeTop-KpYsc6dH{background:linear-gradient(180deg,#0f0f0f,#0f0f0f00)}.fadeBottom-KpYsc6dH{background:linear-gradient(0deg,#fff,#fff0);bottom:0;height:10px;position:absolute}html.theme-dark .fadeBottom-KpYsc6dH{background:linear-gradient(0deg,#0f0f0f,#0f0f0f00)}
|
||||
@@ -0,0 +1 @@
|
||||
.lollipopTooltipTitle-jFagU3Qi{align-items:center;column-gap:8px;display:flex;justify-content:flex-start;padding:4px 0}.lollipopTooltipTitle_minimal-jFagU3Qi .lollipopTooltipTitle__title-jFagU3Qi{font-size:16px;line-height:22px}.lollipopTooltipTitle_mobile-jFagU3Qi{padding:0}.lollipopTooltipTitle_mobile-jFagU3Qi .lollipopTooltipTitle__title-jFagU3Qi{font-size:20px;line-height:24px}.lollipopTooltipTitle__icon-jFagU3Qi{color:currentColor;display:flex}.lollipopTooltipTitle__title-jFagU3Qi{font-family:-apple-system,BlinkMacSystemFont,Trebuchet MS,Roboto,Ubuntu,sans-serif;font-feature-settings:"tnum" on,"lnum" on;font-style:normal;--ui-lib-typography-font-size:18px;font-size:var(--ui-lib-typography-font-size);font-weight:600;--ui-lib-typography-line-height:24px;line-height:var(--ui-lib-typography-line-height)}[data-theme=dark],[data-theme=light]{--_0--48T:var(--color-tan-orange-600);--_1--48T:var(--color-tan-orange-400);--_2--48T:var(--color-tv-blue-500);--_3--48T:var(--color-tv-blue-400)}.subtitle-cEWFvaCX{font-size:14px;line-height:21px}.subtitle-cEWFvaCX .text-cEWFvaCX{flex:1 0 0;overflow:hidden;text-overflow:ellipsis}.group-cEWFvaCX{padding-top:12px}.groupIcon-cEWFvaCX{border-radius:9px;display:inline-block;height:18px;margin-right:7px;vertical-align:top;width:18px}.groupIcon-cEWFvaCX.beforeMarketOpen-cEWFvaCX{background-color:var(--color-overlay-warning-1-light);color:var(--_0--48T)}@media (any-hover:hover){.groupIcon-cEWFvaCX.beforeMarketOpen-cEWFvaCX:hover{background-color:var(--color-overlay-warning-1-normal)}}.groupIcon-cEWFvaCX.afterMarketClose-cEWFvaCX{background-color:var(--color-overlay-accent-1-light);color:var(--_2--48T)}@media (any-hover:hover){.groupIcon-cEWFvaCX.afterMarketClose-cEWFvaCX:hover{background-color:var(--color-overlay-accent-1-normal)}}.groupTitle-cEWFvaCX{color:var(--color-default-gray);font-size:11px;font-weight:400;letter-spacing:.4px;line-height:16px;text-transform:uppercase}.groupRow-cEWFvaCX{display:flex;flex-direction:row}.groupCell-cEWFvaCX{flex:1 0 0}.group-cEWFvaCX .text-cEWFvaCX{font-size:14px;line-height:22px;overflow:hidden;text-overflow:ellipsis}[data-theme=light]{--_0-UeVb:var(--color-white);--_1-UeVb:var(--color-white)}[data-theme=dark]{--_0-UeVb:var(--color-cold-gray-850);--_1-UeVb:var(--color-cold-gray-850)}.wrap-GPY6iGF_{background:var(--tv-color-popup-background,var(--_1-UeVb))}.title-GPY6iGF_{margin-bottom:12px}.content-GPY6iGF_ a,.content-GPY6iGF_ span{cursor:default}.content-GPY6iGF_.mob-GPY6iGF_ .group-GPY6iGF_ .text-GPY6iGF_,.content-GPY6iGF_.mob-GPY6iGF_ .subtitle-GPY6iGF_{font-size:16px;line-height:24px}.content-GPY6iGF_.mini-GPY6iGF_ .subtitle-GPY6iGF_{font-size:13px;line-height:19px}.anchor-GPY6iGF_{margin-top:12px}[data-theme=light]{--_0-2jh4:var(--color-cold-gray-900);--_1-2jh4:#0000;--_2-2jh4:var(--color-white)}[data-theme=dark]{--_0-2jh4:var(--color-cold-gray-200);--_1-2jh4:#0000;--_2-2jh4:var(--color-cold-gray-900)}.drawer-KpYsc6dH{padding:0}.drawer-KpYsc6dH>:not(:last-child){border-bottom:1px solid var(--color-cold-gray-150)}.drawerItem-KpYsc6dH{color:var(--_0-2jh4);padding:16px}.menuWrap-KpYsc6dH{background:var(--_1-2jh4);box-shadow:0 0 var(--_1-2jh4)}.menuWrap-KpYsc6dH .scrollWrap-KpYsc6dH{overflow-y:hidden!important}.menuWrap-KpYsc6dH .menuBox-KpYsc6dH{margin:2px 4px 4px;padding:0}.card-KpYsc6dH{border-radius:4px;border-right:4px solid;box-shadow:0 2px 4px 0 var(--color-other-shadow-primary-neutral-extra-heavy);box-sizing:border-box;color:var(--_0-2jh4);padding:12px 12px 16px;width:300px}.card-KpYsc6dH:not(:first-child){margin-top:8px}.fadeTop-KpYsc6dH{background:linear-gradient(-180deg,#fff,#fff0);height:10px;position:absolute;top:0}html.theme-dark .fadeTop-KpYsc6dH{background:linear-gradient(-180deg,#0f0f0f,#0f0f0f00)}.fadeBottom-KpYsc6dH{background:linear-gradient(0deg,#fff,#fff0);bottom:0;height:10px;position:absolute}html.theme-dark .fadeBottom-KpYsc6dH{background:linear-gradient(0deg,#0f0f0f,#0f0f0f00)}
|
||||
@@ -0,0 +1 @@
|
||||
.container-BZKENkhT{align-items:center;cursor:default;display:flex;flex:0 0 auto;padding:0 20px}.unsetAlign-BZKENkhT{align-items:stretch}.title-BZKENkhT{color:var(--tv-color-dialog-header-text,var(--color-text-primary));flex-grow:1;font-size:20px;font-weight:600;line-height:28px;min-width:0;padding:17px 0}@media (max-height:360px){.title-BZKENkhT{padding:10px 0}}.subtitle-BZKENkhT{font-size:16px;font-weight:400;line-height:24px;margin:8px 0 3px}.textWrap-BZKENkhT{display:-webkit-box;overflow:hidden;-webkit-line-clamp:2;-webkit-box-orient:vertical;line-height:28px;max-height:56px}.ellipsis-BZKENkhT{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.close-BZKENkhT{color:var(--tv-color-dialog-header-text,var(--color-text-primary));margin:17px -3px 17px 0}@media (max-height:360px){.close-BZKENkhT{margin-bottom:10px;margin-top:10px}}.icon-BZKENkhT{height:17px}.dialog-b8SxMnzX{display:block;max-width:550px;min-width:380px;width:auto}@media (max-width:379px){.dialog-b8SxMnzX{min-height:auto;min-width:100%}}.wrapper-b8SxMnzX{display:flex;flex-direction:column;height:100%}.dialog-b8SxMnzX .separator-b8SxMnzX{flex:none;margin:0 0 2px}.separator-b8SxMnzX{background-color:var(--tv-color-dialog-header-separator,var(--color-divider))}.bounded-b8SxMnzX{box-shadow:0 0 0 1px var(--color-divider)}
|
||||
@@ -0,0 +1 @@
|
||||
.container-BZKENkhT{align-items:center;cursor:default;display:flex;flex:0 0 auto;padding:0 20px}.unsetAlign-BZKENkhT{align-items:stretch}.title-BZKENkhT{color:var(--tv-color-dialog-header-text,var(--color-text-primary));flex-grow:1;font-size:20px;font-weight:600;line-height:28px;min-width:0;padding:17px 0}@media (max-height:360px){.title-BZKENkhT{padding:10px 0}}.subtitle-BZKENkhT{font-size:16px;font-weight:400;line-height:24px;margin:8px 0 3px}.textWrap-BZKENkhT{display:-webkit-box;overflow:hidden;-webkit-line-clamp:2;-webkit-box-orient:vertical;line-height:28px;max-height:56px}.ellipsis-BZKENkhT{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.close-BZKENkhT{color:var(--tv-color-dialog-header-text,var(--color-text-primary));margin:17px 0 17px -3px}@media (max-height:360px){.close-BZKENkhT{margin-bottom:10px;margin-top:10px}}.icon-BZKENkhT{height:17px}.dialog-b8SxMnzX{display:block;max-width:550px;min-width:380px;width:auto}@media (max-width:379px){.dialog-b8SxMnzX{min-height:auto;min-width:100%}}.wrapper-b8SxMnzX{display:flex;flex-direction:column;height:100%}.dialog-b8SxMnzX .separator-b8SxMnzX{flex:none;margin:0 0 2px}.separator-b8SxMnzX{background-color:var(--tv-color-dialog-header-separator,var(--color-divider))}.bounded-b8SxMnzX{box-shadow:0 0 0 1px var(--color-divider)}
|
||||
@@ -0,0 +1,5 @@
|
||||
"use strict";(self.webpackChunktradingview=self.webpackChunktradingview||[]).push([[2745],{97578:(e,t,n)=>{n.r(t),n.d(t,{getCoordinateXMetaInfo:()=>g,getCoordinateYMetaInfo:()=>P,getCoordinatesPropertiesDefinitions:()=>T,getSelectionCoordinatesPropertyDefinition:()=>C});var i=n(50151),o=n(77914),r=n(11542),l=n(95804),s=n(40472),a=n(72270);class d extends a.UndoCommand{constructor({lineToolId:e,chartModel:t,newPositionPoints:n}){super(null),this._pointState=null,this._lineToolId=e,this._model=t,this._newPositionPoints=n}redo(){const e=(0,i.ensureNotNull)(this._model.dataSourceForId(this._lineToolId));this._pointState=[e.normalizedPoints(),e.points()],e.startChanging(),e.moveLineTool(this._newPositionPoints),this._model.updateSource(e),e.updateAllViews((0,s.sourceChangeEvent)(e.id())),e.syncMultichartState(e.endChanging(!0,!1))}undo(){if(this._pointState){const e=(0,i.ensureNotNull)(this._model.dataSourceForId(this._lineToolId));e.startChanging(),e.restorePoints(...this._pointState),this._model.updateSource(e),e.updateAllViews((0,s.sourceChangeEvent)(e.id())),e.syncMultichartState(e.endChanging(!0,!1))}}}var c=n(95338),p=n(22613),u=n(43337),h=n(91682);const y=-5e4,m=15e3,w=new l.TranslatedString("change price Y coordinate",r.t(null,void 0,n(11737))),f=new l.TranslatedString("change bar X coordinate",r.t(null,void 0,n(2066))),v=new l.TranslatedString("move drawings",r.t(null,void 0,n(76261)));function P(e,t,n){return{property:(0,c.convertToDefinitionProperty)(e,t.price,w),info:{typeY:1,stepY:n}}}function g(e,t){return{property:(0,c.convertToDefinitionProperty)(e,t.bar,null,void 0,(n=>{n!==t.bar.value()&&e.setProperty(t.bar,(0,o.clamp)(n,y,m),f)})),info:{typeX:0,stepX:new p.WatchedValue(1)}}}function T(e,t,n,i,o,r){const l=g(e,t),s=P(e,t,i);return(0,c.createCoordinatesPropertyDefinition)({x:l.property,y:s.property},{id:(0,h.removeSpaces)(`${r}Coordinates${o}`),title:o,...l.info,...s.info})}const b=/^([+*\-\/]?)((?:\d*)|(?:\d+\.\d*))$/;function S(e,t,n){const o=new u.Property(""),r=(0,c.makeProxyDefinitionProperty)(o.weakReference());return r.setValue=r=>{try{const o=r.match(b);if(!o)return;const[,l,s]=o;if(!s.length)return;const a=n(parseFloat(s));if("/"===l&&(0===a.price||0===a.index))return;t.withMacro(v,(()=>{e.filter((e=>!e.isSourceHidden())).forEach((e=>{const n=e.points();let o;switch(l){case"":{const e=(0,i.ensureDefined)(n[0]);let{index:t=e.index,price:r=e.price}=a;r-=e.price,t-=e.index,o=n.map((e=>({...e,index:e.index+t,price:e.price+r})));break}case"-":case"+":{let{index:e=0,price:t=0}=a;"-"===l&&(e*=-1,t*=-1),o=n.map((n=>({...n,index:n.index+e,price:n.price+t})));break}case"*":{const{index:e=1,price:t=1}=a;o=n.map((n=>({...n,index:n.index*e,price:n.price*t})));break}case"/":{const{index:e=1,price:t=1}=a;o=n.map((n=>({...n,index:n.index/e,price:n.price/t})));break}}t.undoHistory().pushUndoCommand(new d({lineToolId:e.id(),chartModel:t.model(),newPositionPoints:o}))}))}))}finally{o.setValue("",!0)}},r}function C(e,t){const i=S(e,t,(e=>({index:e}))),o=S(e,t,(e=>({price:e})));return(0,
|
||||
c.createSelectionCoordinatesPropertyDefinition)({x:i,y:o},{id:"SourcesCoordinates",title:r.t(null,void 0,n(44272)),mathOperationsX:"+",mathOperationsY:"+/*",modeX:"integer",modeY:"float"})}},73863:(e,t,n)=>{n.r(t),n.d(t,{getIntervalsVisibilitiesPropertiesDefinitions:()=>ae,getSelectionIntervalsVisibilitiesPropertiesDefinition:()=>de});var i=n(11542),o=n(95804),r=n(95338),l=n(22613),s=n(87296),a=n(15574),d=n(65045),c=n(66567);const p=new o.TranslatedString("change {title} visibility on ticks",i.t(null,void 0,n(98596))),u=new o.TranslatedString("change {title} visibility on seconds",i.t(null,void 0,n(41315))),h=new o.TranslatedString("change {title} seconds from",i.t(null,void 0,n(86780))),y=new o.TranslatedString("change {title} seconds to",i.t(null,void 0,n(6573))),m=new o.TranslatedString("change {title} visibility on minutes",i.t(null,void 0,n(78219))),w=new o.TranslatedString("change {title} minutes from",i.t(null,void 0,n(59820))),f=new o.TranslatedString("change {title} minutes to",i.t(null,void 0,n(38011))),v=new o.TranslatedString("change {title} visibility on hours",i.t(null,void 0,n(68715))),P=new o.TranslatedString("change {title} hours from",i.t(null,void 0,n(8306))),g=new o.TranslatedString("change {title} hours to",i.t(null,void 0,n(67233))),T=new o.TranslatedString("change {title} visibility on days",i.t(null,void 0,n(56402))),b=new o.TranslatedString("change {title} days from",i.t(null,void 0,n(91201))),S=new o.TranslatedString("change {title} days to",i.t(null,void 0,n(96135))),C=new o.TranslatedString("change {title} visibility on weeks",i.t(null,void 0,n(71084))),k=new o.TranslatedString("change {title} weeks from",i.t(null,void 0,n(32481))),V=new o.TranslatedString("change {title} weeks to",i.t(null,void 0,n(18678))),W=new o.TranslatedString("change {title} visibility on months",i.t(null,void 0,n(67583))),D=new o.TranslatedString("change {title} months from",i.t(null,void 0,n(99122))),_=new o.TranslatedString("change {title} months to",i.t(null,void 0,n(10518))),x=(new o.TranslatedString("change {title} visibility on ranges",i.t(null,{replace:{ranges:"ranges"}},n(55616))),
|
||||
i.t(null,void 0,n(24821))),U=i.t(null,void 0,n(65188)),I=i.t(null,void 0,n(42562)),M=i.t(null,void 0,n(56796)),L=i.t(null,void 0,n(72942)),F=i.t(null,void 0,n(835)),A=i.t(null,void 0,n(43154)),R=new o.TranslatedString("ticks",i.t(null,void 0,n(3539))),N=new o.TranslatedString("seconds",i.t(null,void 0,n(751))),E=new o.TranslatedString("seconds from",i.t(null,void 0,n(35801))),X=new o.TranslatedString("seconds to",i.t(null,void 0,n(73419))),Y=new o.TranslatedString("minutes",i.t(null,void 0,n(18726))),H=new o.TranslatedString("minutes from",i.t(null,void 0,n(22476))),j=new o.TranslatedString("minutes to",i.t(null,void 0,n(67649))),$=new o.TranslatedString("hours",i.t(null,void 0,n(2359))),O=new o.TranslatedString("hours from",i.t(null,void 0,n(82267))),z=new o.TranslatedString("hours to",i.t(null,void 0,n(15600))),q=new o.TranslatedString("days",i.t(null,void 0,n(35813))),B=new o.TranslatedString("days from",i.t(null,void 0,n(59215))),G=new o.TranslatedString("days to",i.t(null,void 0,n(89919))),J=new o.TranslatedString("weeks",i.t(null,void 0,n(45537))),K=new o.TranslatedString("weeks from",i.t(null,void 0,n(92859))),Q=new o.TranslatedString("weeks to",i.t(null,void 0,n(44127))),Z=new o.TranslatedString("months",i.t(null,void 0,n(95300))),ee=new o.TranslatedString("months from",i.t(null,void 0,n(17250))),te=new o.TranslatedString("months to",i.t(null,void 0,n(2828))),ne=(new o.TranslatedString("ranges","ranges"),[1,59]),ie=[1,59],oe=[1,24],re=[1,366],le=[1,52],se=[1,12];function ae(e,t,n){const i=[];if((0,a.isTicksEnabled)()){const o=(0,r.createCheckablePropertyDefinition)({checked:(0,r.convertToDefinitionProperty)(e,t.ticks,p.format({title:n}))},{id:"IntervalsVisibilitiesTicks",title:x});i.push(o)}if((0,s.isSecondsEnabled)()){const o=(0,r.createRangePropertyDefinition)({checked:(0,r.convertToDefinitionProperty)(e,t.seconds,u.format({title:n})),from:(0,r.convertToDefinitionProperty)(e,t.secondsFrom,h.format({title:n})),to:(0,r.convertToDefinitionProperty)(e,t.secondsTo,y.format({title:n}))},{id:"IntervalsVisibilitiesSecond",title:U,min:new l.WatchedValue(ne[0]),max:new l.WatchedValue(ne[1])});i.push(o)}const o=(0,r.createRangePropertyDefinition)({checked:(0,r.convertToDefinitionProperty)(e,t.minutes,m.format({title:n})),from:(0,r.convertToDefinitionProperty)(e,t.minutesFrom,w.format({title:n})),to:(0,r.convertToDefinitionProperty)(e,t.minutesTo,f.format({title:n}))},{id:"IntervalsVisibilitiesMinutes",title:I,min:new l.WatchedValue(ie[0]),max:new l.WatchedValue(ie[1])}),d=(0,r.createRangePropertyDefinition)({checked:(0,r.convertToDefinitionProperty)(e,t.hours,v.format({title:n})),from:(0,r.convertToDefinitionProperty)(e,t.hoursFrom,P.format({title:n})),to:(0,r.convertToDefinitionProperty)(e,t.hoursTo,g.format({title:n}))},{id:"IntervalsVisibilitiesHours",title:M,min:new l.WatchedValue(oe[0]),max:new l.WatchedValue(oe[1])}),c=(0,r.createRangePropertyDefinition)({checked:(0,r.convertToDefinitionProperty)(e,t.days,T.format({title:n})),from:(0,r.convertToDefinitionProperty)(e,t.daysFrom,b.format({title:n})),to:(0,
|
||||
r.convertToDefinitionProperty)(e,t.daysTo,S.format({title:n}))},{id:"IntervalsVisibilitiesDays",title:L,min:new l.WatchedValue(re[0]),max:new l.WatchedValue(re[1])});i.push(o,d,c);const R=(0,r.createRangePropertyDefinition)({checked:(0,r.convertToDefinitionProperty)(e,t.weeks,C.format({title:n})),from:(0,r.convertToDefinitionProperty)(e,t.weeksFrom,k.format({title:n})),to:(0,r.convertToDefinitionProperty)(e,t.weeksTo,V.format({title:n}))},{id:"IntervalsVisibilitiesWeeks",title:F,min:new l.WatchedValue(le[0]),max:new l.WatchedValue(le[1])}),N=(0,r.createRangePropertyDefinition)({checked:(0,r.convertToDefinitionProperty)(e,t.months,W.format({title:n})),from:(0,r.convertToDefinitionProperty)(e,t.monthsFrom,D.format({title:n})),to:(0,r.convertToDefinitionProperty)(e,t.monthsTo,_.format({title:n}))},{id:"IntervalsVisibilitiesMonths",title:A,min:new l.WatchedValue(se[0]),max:new l.WatchedValue(se[1])});return i.push(R,N),{definitions:i}}function de(e,t){const n=[];if((0,a.isTicksEnabled)()){const i=(0,r.createCheckablePropertyDefinition)({checked:new c.CollectiblePropertyUndoWrapper(new d.LineToolCollectedProperty(e.ticks),R,t)},{id:"IntervalsVisibilitiesTicks",title:x});n.push(i)}if((0,s.isSecondsEnabled)()){const i=(0,r.createRangePropertyDefinition)({checked:new c.CollectiblePropertyUndoWrapper(new d.LineToolCollectedProperty(e.seconds),N,t),from:new c.CollectiblePropertyUndoWrapper(new d.LineToolCollectedProperty(e.secondsFrom),E,t),to:new c.CollectiblePropertyUndoWrapper(new d.LineToolCollectedProperty(e.secondsTo),X,t)},{id:"IntervalsVisibilitiesSecond",title:U,min:new l.WatchedValue(ne[0]),max:new l.WatchedValue(ne[1])});n.push(i)}const i=(0,r.createRangePropertyDefinition)({checked:new c.CollectiblePropertyUndoWrapper(new d.LineToolCollectedProperty(e.minutes),Y,t),from:new c.CollectiblePropertyUndoWrapper(new d.LineToolCollectedProperty(e.minutesFrom),H,t),to:new c.CollectiblePropertyUndoWrapper(new d.LineToolCollectedProperty(e.minutesTo),j,t)},{id:"IntervalsVisibilitiesMinutes",title:I,min:new l.WatchedValue(ie[0]),max:new l.WatchedValue(ie[1])}),o=(0,r.createRangePropertyDefinition)({checked:new c.CollectiblePropertyUndoWrapper(new d.LineToolCollectedProperty(e.hours),$,t),from:new c.CollectiblePropertyUndoWrapper(new d.LineToolCollectedProperty(e.hoursFrom),O,t),to:new c.CollectiblePropertyUndoWrapper(new d.LineToolCollectedProperty(e.hoursTo),z,t)},{id:"IntervalsVisibilitiesHours",title:M,min:new l.WatchedValue(oe[0]),max:new l.WatchedValue(oe[1])}),p=(0,r.createRangePropertyDefinition)({checked:new c.CollectiblePropertyUndoWrapper(new d.LineToolCollectedProperty(e.days),q,t),from:new c.CollectiblePropertyUndoWrapper(new d.LineToolCollectedProperty(e.daysFrom),B,t),to:new c.CollectiblePropertyUndoWrapper(new d.LineToolCollectedProperty(e.daysTo),G,t)},{id:"IntervalsVisibilitiesDays",title:L,min:new l.WatchedValue(re[0]),max:new l.WatchedValue(re[1])});n.push(i,o,p);const u=(0,r.createRangePropertyDefinition)({checked:new c.CollectiblePropertyUndoWrapper(new d.LineToolCollectedProperty(e.weeks),J,t),
|
||||
from:new c.CollectiblePropertyUndoWrapper(new d.LineToolCollectedProperty(e.weeksFrom),K,t),to:new c.CollectiblePropertyUndoWrapper(new d.LineToolCollectedProperty(e.weeksTo),Q,t)},{id:"IntervalsVisibilitiesWeeks",title:F,min:new l.WatchedValue(le[0]),max:new l.WatchedValue(le[1])}),h=(0,r.createRangePropertyDefinition)({checked:new c.CollectiblePropertyUndoWrapper(new d.LineToolCollectedProperty(e.months),Z,t),from:new c.CollectiblePropertyUndoWrapper(new d.LineToolCollectedProperty(e.monthsFrom),ee,t),to:new c.CollectiblePropertyUndoWrapper(new d.LineToolCollectedProperty(e.monthsTo),te,t)},{id:"IntervalsVisibilitiesMonths",title:A,min:new l.WatchedValue(se[0]),max:new l.WatchedValue(se[1])});return n.push(u,h),{definitions:n}}},66567:(e,t,n)=>{n.d(t,{CollectiblePropertyUndoWrapper:()=>a});var i=n(50151),o=n(11542),r=n(95804),l=n(43337);const s=new r.TranslatedString("change {propertyName} property",o.t(null,void 0,n(25167)));class a extends l.Property{constructor(e,t,n){super(),this._isProcess=!1,this._listenersMappers=[],this._valueApplier={applyValue:(e,t)=>{this._propertyApplier.setProperty(e,t,s)}},this._baseProperty=e,this._propertyApplier=n,this._propertyName=t}destroy(){this._baseProperty.destroy(),super.destroy()}value(){return this._baseProperty.value()}setValue(e,t){this._propertyApplier.beginUndoMacro(s.format({propertyName:this._propertyName})),this._isProcess=!0,this._baseProperty.setValue(e,void 0,this._valueApplier),this._isProcess=!1,this._propertyApplier.endUndoMacro(),this._listenersMappers.forEach((e=>{e.method.call(e.obj,this,"")}))}subscribe(e,t){const n=()=>{this._isProcess||t.call(e,this,"")};this._listenersMappers.push({obj:e,method:t,callback:n}),this._baseProperty.subscribe(e,n)}unsubscribe(e,t){const n=(0,i.ensureDefined)(this._listenersMappers.find((n=>n.obj===e&&n.method===t))?.callback);this._baseProperty.unsubscribe(e,n)}unsubscribeAll(e){this._baseProperty.unsubscribeAll(e)}}},81634:(e,t,n)=>{n.d(t,{PropertyApplierWithoutSavingChart:()=>o});var i=n(13896);class o{constructor(e){this._undoModelSupplier=e}setProperty(e,t,n){this._undoModelSupplier().setProperty(e,t,n,i.lineToolsDoNotAffectChartInvalidation)}beginUndoMacro(e){return this._undoModelSupplier().beginUndoMacro(e)}endUndoMacro(){this._undoModelSupplier().endUndoMacro()}setWatchedValue(e,t,n){this._undoModelSupplier().undoHistory().setWatchedValue(e,t,n,i.lineToolsDoNotAffectChartInvalidation)}}}}]);
|
||||
@@ -0,0 +1,5 @@
|
||||
"use strict";(self.webpackChunktradingview=self.webpackChunktradingview||[]).push([[2891],{91445:(e,t,o)=>{o.d(t,{createTextStyleDefinition:()=>w});var i=o(11542),r=o(95804),n=o(95338),s=o(91682);const a=new r.TranslatedString("change {toolName} text visibility",i.t(null,void 0,o(56634))),l=new r.TranslatedString("change {toolName} text color",i.t(null,void 0,o(64500))),d=new r.TranslatedString("change {toolName} text font size",i.t(null,void 0,o(21781))),c=new r.TranslatedString("change {toolName} text font bold",i.t(null,void 0,o(24701))),u=new r.TranslatedString("change {toolName} text font italic",i.t(null,void 0,o(42694))),p=new r.TranslatedString("change {toolName} text",i.t(null,void 0,o(66668))),h=new r.TranslatedString("change {toolName} labels alignment vertical",i.t(null,void 0,o(31689))),g=new r.TranslatedString("change {toolName} labels alignment horizontal",i.t(null,void 0,o(88277))),_=new r.TranslatedString("change {toolName} labels direction",i.t(null,void 0,o(61160))),y=new r.TranslatedString("change {toolName} text background visibility",i.t(null,void 0,o(31133))),b=new r.TranslatedString("change {toolName} text background color",i.t(null,void 0,o(22231))),m=new r.TranslatedString("change {toolName} text border visibility",i.t(null,void 0,o(58704))),f=new r.TranslatedString("change {toolName} text border width",i.t(null,void 0,o(35423))),P=new r.TranslatedString("change {toolName} text border color",i.t(null,void 0,o(36666))),v=new r.TranslatedString("change {toolName} text wrap",i.t(null,void 0,o(39587))),T=i.t(null,void 0,o(79468)),C=i.t(null,void 0,o(38408)),x=i.t(null,void 0,o(7560)),S=i.t(null,void 0,o(6060));function w(e,t,o,i){const r={},w={id:`${(0,s.removeSpaces)(o.originalText())}Text`,title:i.customTitles&&i.customTitles.text||"",placeholder:i.placeholder??S};if(void 0===t.showText||i.hideTextCheckbox||(r.checked=(0,n.convertToDefinitionProperty)(e,t.showText,a.format({toolName:o}))),void 0!==t.textColor&&(r.color=(0,n.getColorDefinitionProperty)(e,t.textColor,t.transparency||null,l.format({toolName:o}))),void 0!==t.fontSize&&(r.size=(0,n.convertToDefinitionProperty)(e,t.fontSize,d.format({toolName:o}))),void 0!==t.bold&&(r.bold=(0,n.convertToDefinitionProperty)(e,t.bold,c.format({toolName:o}))),void 0!==t.italic&&(r.italic=(0,n.convertToDefinitionProperty)(e,t.italic,u.format({toolName:o}))),void 0!==t.text){const s=p.format({toolName:o});r.text=(0,n.convertToDefinitionProperty)(e,t.text,s,void 0),w.isEditable=Boolean(i.isEditable),w.isMultiLine=Boolean(i.isMultiLine)}if(void 0!==t.vertLabelsAlign&&(r.alignmentVertical=(0,n.convertToDefinitionProperty)(e,t.vertLabelsAlign,h.format({toolName:o})),w.alignmentVerticalItems=i.alignmentVerticalItems),void 0!==t.horzLabelsAlign&&(r.alignmentHorizontal=(0,n.convertToDefinitionProperty)(e,t.horzLabelsAlign,g.format({toolName:o})),w.alignmentHorizontalItems=i.alignmentHorizontalItems),void 0!==t.textOrientation&&(r.orientation=(0,n.convertToDefinitionProperty)(e,t.textOrientation,_.format({toolName:o}))),
|
||||
void 0!==t.backgroundVisible&&(r.backgroundVisible=(0,n.convertToDefinitionProperty)(e,t.backgroundVisible,y.format({toolName:o}))),void 0!==t.backgroundColor){let i=null;void 0!==t.backgroundTransparency&&(i=t.backgroundTransparency),r.backgroundColor=(0,n.getColorDefinitionProperty)(e,t.backgroundColor,i,b.format({toolName:o}))}return void 0===t.backgroundVisible&&void 0===t.backgroundColor||(w.backgroundTitle=i.customTitles&&i.customTitles.backgroundTitle||T),void 0!==t.borderVisible&&(r.borderVisible=(0,n.convertToDefinitionProperty)(e,t.borderVisible,m.format({toolName:o}))),void 0!==t.borderWidth&&(r.borderWidth=(0,n.convertToDefinitionProperty)(e,t.borderWidth,f.format({toolName:o}))),void 0!==t.borderColor&&(r.borderColor=(0,n.getColorDefinitionProperty)(e,t.borderColor,null,P.format({toolName:o}))),void 0===t.borderVisible&&void 0===t.borderColor&&void 0===t.borderWidth||(w.borderTitle=i.customTitles&&i.customTitles.borderTitle||C),void 0!==t.wrap&&(r.wrap=(0,n.convertToDefinitionProperty)(e,t.wrap,v.format({toolName:o})),w.wrapTitle=i.customTitles&&i.customTitles.wrapTitle||x),(0,n.createTextPropertyDefinition)(r,w)}},14472:(e,t,o)=>{o.r(t),o.d(t,{LineDataSourceDefinitionsViewModel:()=>P,LineDataSourceTabTypes:()=>i,pointPriceBarTitle:()=>f});var i,r=o(50151),n=o(11542),s=o(95804),a=(o(40167),o(95338)),l=o(60567),d=o(22613),c=o(73863),u=o(97578),p=o(81634),h=o(36313);!function(e){e.Visibility="visibility",e.Coordinates="coordinates",e.Style="style",e.Text="text",e.Inputs="inputs"}(i||(i={}));const g=n.t(null,void 0,o(40091)),_=n.t(null,void 0,o(78930)),y=n.t(null,void 0,o(92516)),b=n.t(null,void 0,o(70320)),m=n.t(null,void 0,o(21429)),f=n.t(null,{context:"linetool point"},o(80166));class P{constructor(e,t){this._yCoordinateStepWV=null,this._propertyPages=[],this._source=t,this._undoModel=e,this._ownerSource=(0,r.ensureNotNull)(this._source.ownerSource()),this._propertyApplier=new p.PropertyApplierWithoutSavingChart((()=>e)),this._createPropertyRages()}destroy(){null!==this._yCoordinateStepWV&&(this._source.ownerSourceChanged().unsubscribeAll(this),this._ownerSource.priceStepChanged().unsubscribeAll(this)),this._source.pointAdded().unsubscribeAll(this),this._propertyPages.forEach((e=>{(0,a.destroyDefinitions)(e.definitions.value())}))}propertyPages(){return Promise.resolve(this._propertyPages)}_createPropertyRages(){this._propertyPages=[];const e=this._createInputsPropertyPage();null!==e&&this._propertyPages.push(e);const t=this._createStylePropertyPage();null!==t&&this._propertyPages.push(t);const o=this._createTextPropertyPage();null!==o&&this._propertyPages.push(o);const i=this._createCoordinatesPropertyPage();null!==i&&(i.visible=this._source.hasEditableCoordinates(),this._propertyPages.push(i));const r=this._createVisibilitiesPropertyPage();this._propertyPages.push(r)}_createVisibilitiesPropertyPage(){const e=this._source.properties().childs().intervalsVisibilities.childs();return(0,l.createPropertyPage)((0,
|
||||
c.getIntervalsVisibilitiesPropertiesDefinitions)(this._propertyApplier,e,new s.TranslatedString(this._source.name(),this._source.title(h.TitleDisplayTarget.StatusLine,!0))),"visibility",g)}_createCoordinatesPropertyPage(){const e=this._coordinatesPropertyDefinitions();return null!==e?(e.definitions.length<this._source.pointsCount()&&this._source.pointAdded().subscribe(this,this._updateCoordinatesPropertyDefinitons),(0,l.createPropertyPage)(e,"coordinates",_)):null}_getYCoordinateStepWV(){return null===this._yCoordinateStepWV&&(this._yCoordinateStepWV=new d.WatchedValue(function(e){if(null!==e){const t=e.priceStep();if(null!==t)return t}return 1}(this._source.ownerSource())),this._ownerSource.priceStepChanged().subscribe(this,(()=>this._updateYCoordinateStep())),this._source.ownerSourceChanged().subscribe(this,(()=>{this._ownerSource.priceStepChanged().unsubscribeAll(this),this._ownerSource=(0,r.ensureNotNull)(this._source.ownerSource()),this._ownerSource.priceStepChanged().subscribe(this,(()=>this._updateYCoordinateStep()))}))),this._yCoordinateStepWV}_coordinatesPropertyDefinitions(){const e=this._source.points(),t=this._source.pointsProperty().childs().points,o=[],i=this._getYCoordinateStepWV();return e.forEach(((e,r)=>{const n=t[r].childs();n&&o.push((0,u.getCoordinatesPropertiesDefinitions)(this._propertyApplier,n,e,i,f.format({count:(r+1).toString()}),this._source.name()))})),{definitions:o}}_createStylePropertyPage(){const e=this._stylePropertyDefinitions();return null!==e?(0,l.createPropertyPage)(e,"style",y):null}_stylePropertyDefinitions(){return null}_createTextPropertyPage(){const e=this._textPropertyDefinitions();return null!==e?(0,l.createPropertyPage)(e,"text",b):null}_textPropertyDefinitions(){return null}_createInputsPropertyPage(){const e=this._inputsPropertyDefinitions();return null!==e?(0,l.createPropertyPage)(e,"inputs",m):null}_inputsPropertyDefinitions(){return null}_updateYCoordinateStep(){const e=this._ownerSource.priceStep();this._getYCoordinateStepWV().setValue(e||1)}_updateCoordinatesPropertyDefinitons(){const e=this._coordinatesPropertyDefinitions();if(null!==e){(0,r.ensureDefined)(this._propertyPages.find((e=>"coordinates"===e.id))).definitions.setValue(e.definitions),this._source.points().length===this._source.pointsCount()&&this._source.pointAdded().unsubscribeAll(this)}}}},12891:(e,t,o)=>{o.r(t),o.d(t,{LineToolBalloon:()=>A});var i=o(50151),r=o(11542),n=o(78176),s=o(63117),a=o(43337),l=o(65045),d=o(95804),c=o(91445),u=o(14472);const p=r.t(null,void 0,o(70320));class h extends u.LineDataSourceDefinitionsViewModel{_textPropertyDefinitions(){const e=this._source.properties().childs();return{definitions:[(0,c.createTextStyleDefinition)(this._propertyApplier,{textColor:e.color,fontSize:e.fontsize,text:e.text,backgroundColor:e.backgroundColor,backgroundTransparency:e.transparency,borderColor:e.borderColor},new d.TranslatedString(this._source.name(),this._source.translatedType()),{isEditable:!0,isMultiLine:!0,customTitles:{text:p}})]}}}
|
||||
var g,_=o(52859),y=o(49251),b=o(84617),m=o(54707),f=o(73914),P=o(94602),v=o(45801),T=o(2383),C=o(10555),x=o(6453),S=o(24640),w=o(33350),D=o(20820);!function(e){e[e.Radius=15]="Radius",e[e.TailApexXOffsetFromTextStart=20]="TailApexXOffsetFromTextStart",e[e.TailHeight=9]="TailHeight"}(g||(g={}));class N extends D.MediaCoordinatesPaneRenderer{constructor(){super(...arguments),this._geometryCache={innerHeight:NaN,textHorizontalPadding:NaN,innerWidth:NaN,paddingLeft:NaN},this._geomertryCacheInvalidated=!0,this._data=null}setData(e){this._data=e,this._geomertryCacheInvalidated=!0}hitTest(e){if(null===this._data||0===this._data.points.length)return null;const t=this._data.points[0].x-(this._geometryCache.paddingLeft+20),o=this._data.points[0].y-(this._geometryCache.innerHeight+9),i=(0,C.box)(new C.Point(t,o),new C.Point(t+this._geometryCache.innerWidth,o+this._geometryCache.innerHeight));return(0,x.pointInBox)(e,i)?new T.HitTestResult(T.HitTarget.MovePoint,{areaName:T.AreaName.Text}):null}_drawImpl(e){if(null===this._data||0===this._data.points.length)return;const t=e.context;t.font=this._data.font;const o=this._measureInfo(t,this._data.label,this._data.fontSize),{paddingLeft:i,innerHeight:r,innerWidth:n,textHorizontalPadding:s}=o;t.textAlign=(0,S.isRtl)()?"right":"left";const a=this._data.points[0].x-(i+20),l=this._data.points[0].y-(r+9);t.translate(a,l),t.beginPath(),t.moveTo(24,r),t.lineTo(15,r),t.arcTo(-1e3,0,1e3,0,r/2),t.lineTo(n-15,0),t.arcTo(1e3,r,-1e3,r,r/2),t.lineTo(33,r),t.quadraticCurveTo(33,r+4,35,r+9),t.quadraticCurveTo(27,r+6,24,r),t.fillStyle=this._data.backgroundColor,t.fill(),t.strokeStyle=this._data.borderColor,t.lineWidth=2,t.stroke(),t.closePath(),t.textBaseline="middle",t.fillStyle=this._data.color,t.fillText(this._data.label,i+s,r/2)}_measureInfo(e,t,o){if(this._geomertryCacheInvalidated){const i=e.measureText(t),r=o,n=15,s=Math.round(r/1.3),a=i.width+2*n,l=r+2*s,d=(0,w.calcTextHorizontalShift)(e,i.width);this._geometryCache={paddingLeft:n,innerWidth:a,innerHeight:l,textHorizontalPadding:d},this._geomertryCacheInvalidated=!1}return this._geometryCache}}class V extends m.LineSourcePaneView{constructor(e,t){super(e,t),this._balloonRenderer=new N,this._renderer=null}renderer(e){return this._invalidated&&this._updateImpl(e),this._renderer}_updateImpl(e){super._updateImpl(e);const t=this._source.properties().childs(),o={points:this._points,color:t.color.value(),borderColor:t.borderColor.value(),backgroundColor:(0,_.generateColor)(t.backgroundColor.value(),t.transparency.value()),font:(0,y.makeFont)(t.fontsize.value(),b.CHART_FONT_FAMILY),fontSize:t.fontsize.value(),label:t.text.value()};if(this._balloonRenderer.setData(o),1===o.points.length){const e=new P.CompositeRenderer;return e.append(this._balloonRenderer),e.append(new v.SelectionRenderer({points:o.points.map(f.mapLineSourcePaneViewPointToLineAnchorPoint),bgColors:this._lineAnchorColors(o.points),visible:this.areAnchorsVisible(),barSpacing:this._model.timeScale().barSpacing(),hittestResult:T.HitTarget.MovePoint})),void(this._renderer=e)}
|
||||
this._renderer=this._balloonRenderer}}const k=r.t(null,void 0,o(9818));class A extends s.InplaceTextLineDataSource{constructor(e,t,o,i){super(e,t??A.createProperties(e.backgroundTheme().spawnOwnership()),o,i),this._createPaneView()}pointsCount(){return 1}name(){return"Balloon"}template(){const e=super.template();return e.text=this.properties().childs().text.value(),e}shouldBeRemovedOnDeselect(){return""===this._properties.childs().text.value().trim()}editableTextProperties(){(0,i.assert)(!1,"unexpected method call")}static createProperties(e,t){const o=new n.DefaultProperty({defaultName:"linetoolballoon",state:t,theme:e});return this._configureProperties(o),o}_applyTemplateImpl(e){super._applyTemplateImpl(e),this.properties().childs().text.setValue(e.text)}async _getPropertyDefinitionsViewModelClass(){return h}_createPaneView(){this._setPaneViews([new V(this,this._model)])}static _configureProperties(e){super._configureProperties(e),e.hasChild("text")||e.addChild("text",new a.Property(this._defaultText)),e.addExcludedKey("text",1),e.addChild("linesColors",new l.LineToolColorsProperty([e.childs().borderColor])),e.addChild("textsColors",new l.LineToolColorsProperty([e.childs().color]))}}A._defaultText=k}}]);
|
||||
@@ -0,0 +1 @@
|
||||
.button-Y1TCZogJ{all:unset;display:flex;position:relative}.button-Y1TCZogJ:before{border-radius:4px;content:none;height:100%;left:0;outline:var(--color-tv-blue-500) none 2px;outline-offset:-2px;position:absolute;top:0;width:100%}.button-Y1TCZogJ:focus-visible:before{content:"";outline-style:solid}.button-Y1TCZogJ.active-Y1TCZogJ:before{outline-color:var(--color-white)}
|
||||
@@ -0,0 +1 @@
|
||||
.button-Y1TCZogJ{all:unset;display:flex;position:relative}.button-Y1TCZogJ:before{border-radius:4px;content:none;height:100%;outline:var(--color-tv-blue-500) none 2px;outline-offset:-2px;position:absolute;right:0;top:0;width:100%}.button-Y1TCZogJ:focus-visible:before{content:"";outline-style:solid}.button-Y1TCZogJ.active-Y1TCZogJ:before{outline-color:var(--color-white)}
|
||||
@@ -0,0 +1,6 @@
|
||||
(self.webpackChunktradingview=self.webpackChunktradingview||[]).push([[3179],{5808:e=>{e.exports={menuWrap:"menuWrap-Kq3ruQo8",isMeasuring:"isMeasuring-Kq3ruQo8",scrollWrap:"scrollWrap-Kq3ruQo8",momentumBased:"momentumBased-Kq3ruQo8",menuBox:"menuBox-Kq3ruQo8",isHidden:"isHidden-Kq3ruQo8"}},43010:(e,t,n)=>{"use strict";n.d(t,{useIsomorphicLayoutEffect:()=>i});var s=n(50959);function i(e,t){("undefined"==typeof window?s.useEffect:s.useLayoutEffect)(e,t)}},27267:(e,t,n)=>{"use strict";function s(e,t,n,s,i){function o(i){if(e>i.timeStamp)return;const o=i.target;void 0!==n&&null!==t&&null!==o&&o.ownerDocument===s&&(t.contains(o)||n(i))}return i.click&&s.addEventListener("click",o,!1),i.mouseDown&&s.addEventListener("mousedown",o,!1),i.touchEnd&&s.addEventListener("touchend",o,!1),i.touchStart&&s.addEventListener("touchstart",o,!1),()=>{s.removeEventListener("click",o,!1),s.removeEventListener("mousedown",o,!1),s.removeEventListener("touchend",o,!1),s.removeEventListener("touchstart",o,!1)}}n.d(t,{addOutsideEventListener:()=>s})},36383:(e,t,n)=>{"use strict";n.d(t,{useOutsideEvent:()=>r});var s=n(50959),i=n(43010),o=n(27267);function r(e){const{click:t,mouseDown:n,touchEnd:r,touchStart:a,handler:l,reference:u}=e,c=(0,s.useRef)(null),d=(0,s.useRef)("undefined"==typeof window?0:new window.CustomEvent("timestamp").timeStamp);return(0,i.useIsomorphicLayoutEffect)((()=>{const e={click:t,mouseDown:n,touchEnd:r,touchStart:a},s=u?u.current:c.current;return(0,o.addOutsideEventListener)(d.current,s,l,document,e)}),[t,n,r,a,l]),u||c}},9745:(e,t,n)=>{"use strict";n.d(t,{Icon:()=>i});var s=n(50959);const i=s.forwardRef(((e,t)=>{const{icon:n="",title:i,ariaLabel:o,ariaLabelledby:r,ariaHidden:a,...l}=e,u=!!(i||o||r);return s.createElement("span",{role:"img",...l,ref:t,"aria-label":o,"aria-labelledby":r,"aria-hidden":a||!u,title:i,dangerouslySetInnerHTML:{__html:n}})}))},83021:(e,t,n)=>{"use strict";n.d(t,{SubmenuContext:()=>i,SubmenuHandler:()=>o});var s=n(50959);const i=s.createContext(null);function o(e){const[t,n]=(0,s.useState)(null),o=(0,s.useRef)(null),r=(0,s.useRef)(new Map);return(0,s.useEffect)((()=>()=>{null!==o.current&&clearTimeout(o.current)}),[]),s.createElement(i.Provider,{value:{current:t,setCurrent:function(e){null!==o.current&&(clearTimeout(o.current),o.current=null);null===t?n(e):o.current=setTimeout((()=>{o.current=null,n(e)}),100)},registerSubmenu:function(e,t){return r.current.set(e,t),()=>{r.current.delete(e)}},isSubmenuNode:function(e){return Array.from(r.current.values()).some((t=>t(e)))}}},e.children)}},19250:(e,t,n)=>{"use strict";n.d(t,{Portal:()=>u,PortalContext:()=>c});var s=n(50959),i=n(32227),o=n(25931),r=n(67961),a=n(34811),l=n(99663);class u extends s.PureComponent{constructor(){super(...arguments),this._uuid=(0,o.nanoid)()}componentWillUnmount(){this._manager().removeWindow(this._uuid)}render(){const e=this._manager().ensureWindow(this._uuid,this.props.layerOptions);e.style.top=this.props.top||"",e.style.bottom=this.props.bottom||"",e.style.left=this.props.left||"",e.style.right=this.props.right||"",
|
||||
e.style.pointerEvents=this.props.pointerEvents||"";const t=this.props.className;return t&&("string"==typeof t?e.classList.add(t):e.classList.add(...t)),this.props.shouldTrapFocus&&!e.hasAttribute(a.FOCUS_TRAP_DATA_ATTRIBUTE)&&e.setAttribute(a.FOCUS_TRAP_DATA_ATTRIBUTE,"true"),this.props["aria-hidden"]&&e.setAttribute("aria-hidden","true"),i.createPortal(s.createElement(c.Provider,{value:this},this.props.children),e)}moveToTop(){this._manager().moveToTop(this._uuid)}_manager(){return null===this.context?(0,r.getRootOverlapManager)():this.context}}u.contextType=l.SlotContext;const c=s.createContext(null)},99663:(e,t,n)=>{"use strict";n.d(t,{Slot:()=>i,SlotContext:()=>o});var s=n(50959);class i extends s.Component{shouldComponentUpdate(){return!1}render(){return s.createElement("div",{style:{position:"fixed",zIndex:150,left:0,top:0},ref:this.props.reference})}}const o=s.createContext(null)},67961:(e,t,n)=>{"use strict";n.d(t,{OverlapManager:()=>r,getRootOverlapManager:()=>l});var s=n(50151),i=n(34811);class o{constructor(){this._storage=[]}add(e){this._storage.push(e)}remove(e){this._storage=this._storage.filter((t=>e!==t))}has(e){return this._storage.includes(e)}getItems(){return this._storage}}class r{constructor(e=document){this._storage=new o,this._windows=new Map,this._index=0,this._document=e,this._container=e.createDocumentFragment()}setContainer(e){const t=this._container,n=null===e?this._document.createDocumentFragment():e;!function(e,t){Array.from(e.childNodes).forEach((e=>{e.nodeType===Node.ELEMENT_NODE&&t.appendChild(e)}))}(t,n),this._container=n}registerWindow(e){this._storage.has(e)||this._storage.add(e)}ensureWindow(e,t={position:"fixed",direction:"normal"}){const n=this._windows.get(e);if(void 0!==n)return n;this.registerWindow(e);const s=this._document.createElement("div");if(s.style.position=t.position,s.style.zIndex=this._index.toString(),s.dataset.id=e,void 0!==t.index){const e=this._container.childNodes.length;if(t.index>=e)this._container.appendChild(s);else if(t.index<=0)this._container.insertBefore(s,this._container.firstChild);else{const e=this._container.childNodes[t.index];this._container.insertBefore(s,e)}}else"reverse"===t.direction?this._container.insertBefore(s,this._container.firstChild):this._container.appendChild(s);return this._windows.set(e,s),++this._index,s}unregisterWindow(e){this._storage.remove(e);const t=this._windows.get(e);void 0!==t&&(null!==t.parentElement&&t.parentElement.removeChild(t),this._windows.delete(e))}getZindex(e){const t=this.ensureWindow(e);return parseInt(t.style.zIndex||"0")}moveLastWindowToTop(){const e=this._storage.getItems(),t=e[e.length-1];t&&this.moveToTop(t)}moveToTop(e){if(this.getZindex(e)!==this._index){const t=this.ensureWindow(e);this._windows.forEach(((e,n)=>{e.hasAttribute(i.FOCUS_TRAP_DATA_ATTRIBUTE)&&e.setAttribute(i.FOCUS_TRAP_DATA_ATTRIBUTE,e===t?"true":"false")})),t.style.zIndex=(++this._index).toString()}}removeWindow(e){this.unregisterWindow(e)}}const a=new WeakMap;function l(e=document){const t=e.getElementById("overlap-manager-root")
|
||||
;if(null!==t)return(0,s.ensureDefined)(a.get(t));{const t=new r(e),n=function(e){const t=e.createElement("div");return t.style.position="absolute",t.style.zIndex=150..toString(),t.style.top="0px",t.style.left="0px",t.id="overlap-manager-root",t.dataset.qaId="overlap-manager-root",t}(e);return a.set(n,t),t.setContainer(n),e.body.appendChild(n),t}}var u;!function(e){e[e.BaseZindex=150]="BaseZindex"}(u||(u={}))},99054:(e,t,n)=>{"use strict";n.d(t,{setFixedBodyState:()=>u});const s=(()=>{let e;return()=>{if(void 0===e){const t=document.createElement("div"),n=t.style;n.visibility="hidden",n.width="100px",n.msOverflowStyle="scrollbar",document.body.appendChild(t);const s=t.offsetWidth;t.style.overflow="scroll";const i=document.createElement("div");i.style.width="100%",t.appendChild(i);const o=i.offsetWidth;t.parentNode?.removeChild(t),e=s-o}return e}})();function i(e,t,n){null!==e&&e.style.setProperty(t,n)}function o(e,t){return getComputedStyle(e,null).getPropertyValue(t)}function r(e,t){return parseInt(o(e,t))}let a=0,l=!1;function u(e){const{body:t}=document,n=t.querySelector(".widgetbar-wrap");if(e&&1==++a){const e=o(t,"overflow"),a=r(t,"padding-right");"hidden"!==e.toLowerCase()&&t.scrollHeight>t.offsetHeight&&(i(n,"right",`${s()}px`),t.style.paddingRight=`${a+s()}px`,l=!0),t.classList.add("i-no-scroll")}else if(!e&&a>0&&0==--a&&(t.classList.remove("i-no-scroll"),l)){i(n,"right","0px");let e=0;0,t.scrollHeight<=t.clientHeight&&(e-=s()),t.style.paddingRight=(e<0?0:e)+"px",l=!1}}},90692:(e,t,n)=>{"use strict";n.d(t,{MatchMedia:()=>i});var s=n(50959);class i extends s.PureComponent{constructor(e){super(e),this._handleChange=()=>{this.forceUpdate()},this.state={query:window.matchMedia(this.props.rule)}}componentDidMount(){this._subscribe(this.state.query)}componentDidUpdate(e,t){this.state.query!==t.query&&(this._unsubscribe(t.query),this._subscribe(this.state.query))}componentWillUnmount(){this._unsubscribe(this.state.query)}render(){return this.props.children(this.state.query.matches)}static getDerivedStateFromProps(e,t){return e.rule!==t.query.media?{query:window.matchMedia(e.rule)}:null}_subscribe(e){e.addEventListener("change",this._handleChange)}_unsubscribe(e){e.removeEventListener("change",this._handleChange)}}},64706:(e,t,n)=>{"use strict";n.d(t,{MenuContext:()=>s});const s=n(50959).createContext(null)},27317:(e,t,n)=>{"use strict";n.d(t,{DEFAULT_MENU_THEME:()=>_,Menu:()=>v});var s=n(50959),i=n(97754),o=n.n(i),r=n(50151),a=n(77914),l=n(26867),u=n(50655),c=n(87713),d=n(67961),h=n(26709),p=n(83021),m=n(64706),f=n(5808);const _=f;var g;!function(e){e[e.IndentFromWindow=0]="IndentFromWindow"}(g||(g={}));class v extends s.PureComponent{constructor(e){super(e),this._containerRef=null,this._scrollWrapRef=null,this._raf=null,this._scrollRaf=null,this._scrollTimeout=void 0,this._manager=new d.OverlapManager,this._hotkeys=null,this._scroll=0,this._handleContainerRef=e=>{this._containerRef=e,this.props.reference&&("function"==typeof this.props.reference&&this.props.reference(e),
|
||||
"object"==typeof this.props.reference&&(this.props.reference.current=e))},this._handleScrollWrapRef=e=>{this._scrollWrapRef=e,"function"==typeof this.props.scrollWrapReference&&this.props.scrollWrapReference(e),"object"==typeof this.props.scrollWrapReference&&(this.props.scrollWrapReference.current=e)},this._handleCustomRemeasureDelegate=()=>{this._resizeForced(),this._handleMeasure()},this._handleMeasure=({callback:e,forceRecalcPosition:t}={})=>{if(this.state.isMeasureValid&&!t)return;const{position:n}=this.props,s=(0,r.ensureNotNull)(this._containerRef);let i=s.getBoundingClientRect();const o=document.documentElement.clientHeight,l=document.documentElement.clientWidth,u=this.props.closeOnScrollOutsideOffset??0;let c=o-0-u;const d=i.height>c;if(d){(0,r.ensureNotNull)(this._scrollWrapRef).style.overflowY="scroll",i=s.getBoundingClientRect()}const{width:h,height:p}=i,m="function"==typeof n?n({contentWidth:h,contentHeight:p,availableWidth:l,availableHeight:o}):n,f=m?.indentFromWindow?.left??0,_=l-(m.overrideWidth??h)-(m?.indentFromWindow?.right??0),g=(0,a.clamp)(m.x,f,Math.max(f,_)),v=(m?.indentFromWindow?.top??0)+u,y=o-(m.overrideHeight??p)-(m?.indentFromWindow?.bottom??0);let w=(0,a.clamp)(m.y,v,Math.max(v,y));if(m.forbidCorrectYCoord&&w<m.y&&(c-=m.y-w,w=m.y),t&&void 0!==this.props.closeOnScrollOutsideOffset&&m.y<=this.props.closeOnScrollOutsideOffset)return void this._handleGlobalClose(!0);const b=m.overrideHeight??(d?c:void 0);this.setState({appearingMenuHeight:t?this.state.appearingMenuHeight:b,appearingMenuWidth:t?this.state.appearingMenuWidth:m.overrideWidth,appearingPosition:{x:g,y:w},isMeasureValid:!0},(()=>{this.props.doNotRestorePosition||this._restoreScrollPosition(),e&&e()}))},this._restoreScrollPosition=()=>{const e=document.activeElement,t=(0,r.ensureNotNull)(this._containerRef);if(null!==e&&t.contains(e))try{e.scrollIntoView()}catch(e){}else(0,r.ensureNotNull)(this._scrollWrapRef).scrollTop=this._scroll},this._resizeForced=()=>{this.setState({appearingMenuHeight:void 0,appearingMenuWidth:void 0,appearingPosition:void 0,isMeasureValid:void 0})},this._resize=()=>{null===this._raf&&(this._raf=requestAnimationFrame((()=>{this.setState({appearingMenuHeight:void 0,appearingMenuWidth:void 0,appearingPosition:void 0,isMeasureValid:void 0}),this._raf=null})))},this._handleGlobalClose=e=>{this.props.onClose(e)},this._handleSlot=e=>{this._manager.setContainer(e)},this._handleScroll=()=>{this._scroll=(0,r.ensureNotNull)(this._scrollWrapRef).scrollTop},this._handleScrollOutsideEnd=()=>{clearTimeout(this._scrollTimeout),this._scrollTimeout=setTimeout((()=>{this._handleMeasure({forceRecalcPosition:!0})}),80)},this._handleScrollOutside=e=>{e.target!==this._scrollWrapRef&&(this._handleScrollOutsideEnd(),null===this._scrollRaf&&(this._scrollRaf=requestAnimationFrame((()=>{this._handleMeasure({forceRecalcPosition:!0}),this._scrollRaf=null}))))},this.state={}}componentDidMount(){this._handleMeasure({callback:this.props.onOpen});const{customCloseDelegate:e=c.globalCloseDelegate,customRemeasureDelegate:t}=this.props
|
||||
;e.subscribe(this,this._handleGlobalClose),t?.subscribe(null,this._handleCustomRemeasureDelegate),window.addEventListener("resize",this._resize);const n=null!==this.context;this._hotkeys||n||(this._hotkeys=h.createGroup({desc:"Popup menu"}),this._hotkeys.add({desc:"Close",hotkey:27,handler:()=>{this.props.onKeyboardClose&&this.props.onKeyboardClose(),this._handleGlobalClose()}})),this.props.repositionOnScroll&&window.addEventListener("scroll",this._handleScrollOutside,{capture:!0})}componentDidUpdate(){this._handleMeasure()}componentWillUnmount(){const{customCloseDelegate:e=c.globalCloseDelegate,customRemeasureDelegate:t}=this.props;e.unsubscribe(this,this._handleGlobalClose),t?.unsubscribe(null,this._handleCustomRemeasureDelegate),window.removeEventListener("resize",this._resize),window.removeEventListener("scroll",this._handleScrollOutside,{capture:!0}),this._hotkeys&&(this._hotkeys.destroy(),this._hotkeys=null),null!==this._raf&&(cancelAnimationFrame(this._raf),this._raf=null),null!==this._scrollRaf&&(cancelAnimationFrame(this._scrollRaf),this._scrollRaf=null),this._scrollTimeout&&clearTimeout(this._scrollTimeout)}render(){const{id:e,role:t,"aria-label":n,"aria-labelledby":i,"aria-activedescendant":r,"aria-hidden":a,"aria-describedby":c,"aria-invalid":d,children:h,minWidth:_,theme:g=f,className:v,maxHeight:w,onMouseOver:b,onMouseOut:x,onKeyDown:C,onFocus:E,onBlur:S}=this.props,{appearingMenuHeight:R,appearingMenuWidth:M,appearingPosition:W,isMeasureValid:T}=this.state,O={"--ui-kit-menu-max-width":`${W&&W.x}px`,maxWidth:"calc(100vw - var(--ui-kit-menu-max-width) - 6px)"};return s.createElement(m.MenuContext.Provider,{value:this},s.createElement(p.SubmenuHandler,null,s.createElement(u.SlotContext.Provider,{value:this._manager},s.createElement("div",{id:e,role:t,"aria-label":n,"aria-labelledby":i,"aria-activedescendant":r,"aria-hidden":a,"aria-describedby":c,"aria-invalid":d,className:o()(v,g.menuWrap,!T&&g.isMeasuring),style:{height:R,left:W&&W.x,minWidth:_,position:"fixed",top:W&&W.y,width:M,...this.props.limitMaxWidth&&O},"data-name":this.props["data-name"],"data-qa-id":this.props.dataQaId,"data-tooltip-show-on-focus":this.props["data-tooltip-show-on-focus"],ref:this._handleContainerRef,onScrollCapture:this.props.onScroll,onContextMenu:l.preventDefaultForContextMenu,tabIndex:this.props.tabIndex,onMouseOver:b,onMouseOut:x,onKeyDown:C,onFocus:E,onBlur:S},s.createElement("div",{className:o()(g.scrollWrap,!this.props.noMomentumBasedScroll&&g.momentumBased),style:{overflowY:void 0!==R?"scroll":"auto",maxHeight:w},onScrollCapture:this._handleScroll,ref:this._handleScrollWrapRef},s.createElement(y,{className:g.menuBox},h)))),s.createElement(u.Slot,{reference:this._handleSlot})))}update(e){e?this._resizeForced():this._resize()}focus(e){this._containerRef?.focus(e)}blur(){this._containerRef?.blur()}}function y(e){const t=(0,r.ensureNotNull)((0,s.useContext)(p.SubmenuContext)),n=s.useRef(null);return s.createElement("div",{ref:n,className:e.className,onMouseOver:function(e){
|
||||
if(!(null!==t.current&&e.target instanceof Node&&(s=e.target,n.current?.contains(s))))return;var s;t.isSubmenuNode(e.target)||t.setCurrent(null)},"data-name":"menu-inner","data-qa-id":"menu-inner"},e.children)}v.contextType=p.SubmenuContext},29197:(e,t,n)=>{"use strict";n.d(t,{CloseDelegateContext:()=>o});var s=n(50959),i=n(87713);const o=s.createContext(i.globalCloseDelegate)},65718:(e,t,n)=>{"use strict";n.d(t,{Portal:()=>s.Portal,PortalContext:()=>s.PortalContext});var s=n(19250)},50655:(e,t,n)=>{"use strict";n.d(t,{Slot:()=>s.Slot,SlotContext:()=>s.SlotContext});var s=n(99663)}}]);
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user