mirror of
https://github.com/exchanges-lab/view.git
synced 2026-08-04 21:31:22 +08:00
Upload files.
This commit is contained in:
+12
@@ -0,0 +1,12 @@
|
||||
binance_rust
|
||||
|
||||
/kiro.json
|
||||
|
||||
.claude
|
||||
.devcontainer
|
||||
storage
|
||||
tradingview-demo
|
||||
|
||||
backend/.env
|
||||
|
||||
/frontend/.env
|
||||
@@ -0,0 +1,401 @@
|
||||
# 📊 View — Crypto chart Platform
|
||||
|
||||
[🇨🇳 中文版 README](README_CN.md)
|
||||
A self-hosted, real-time cryptocurrency data collection and visualization platform for **Binance USDS-M Futures**. Combines a high-performance Rust backend with a professional charting frontend to deliver institutional-grade market data tooling.
|
||||
|
||||
This project is primarily built for my own use, and I don't have much bandwidth to maintain it. I'm also not a frontend developer, so the frontend code may not follow best practices. That said, pull requests and issues are very welcome — feel free to open an Issue or submit a Pull Request!
|
||||
|
||||
As you can see, this is not a simple one-click-to-deploy project, nor is it a beginner-friendly toy. I simply don't have the time or ability to simplify it further. The easiest way to deploy is to let **Claude Opus 4.6** study the entire project and have it guide you through the setup.
|
||||
|
||||
If deploying the backend is too difficult, you can temporarily use my public backend API endpoint: `api-view.cathiefish.org`. This way you only need to deploy the frontend to Cloudflare Pages. Note that this endpoint only guarantees data for **BTCUSDT, ETHUSDT, SOLUSDT, BNBUSDT, XRPUSDT, SUIUSDT**. See the [Deployment](#-deployment) section for how to configure this.
|
||||
|
||||

|
||||

|
||||

|
||||
|
||||
## ✨ Features
|
||||
|
||||
### Data Collection & Storage
|
||||
- [x] **Real-time WebSocket streaming** — Live 1-minute K-line data from Binance combined streams, with auto-reconnect and gap backfill
|
||||
- [x] **3-tier historical sync** — Monthly ZIP → Daily ZIP → REST API, for fastest possible backfill from [Binance Data Archive](https://data.binance.vision/)
|
||||
- [x] **TimescaleDB time-series storage** — Hypertable-optimized with `time_bucket` aggregation across 8 timeframes (1m, 5m, 15m, 1h, 4h, 1D, 1W, 1M)
|
||||
- [x] **Proxy pool support** — Up to 100 concurrent proxy clients for high-throughput parallel downloads
|
||||
- [ ] **Binance Spot support** — Spot market data collection, using `.P` suffix to distinguish Futures from Spot symbols
|
||||
- [ ] **MCP support** — Model Context Protocol integration
|
||||
|
||||
### Charting & Visualization
|
||||
- [x] **Professional charting engine** — Full indicator and drawing tool support
|
||||
- [x] **Custom indicators** — Net Volume (NV-C) and Cumulative Volume Delta (CVD-C)
|
||||
- [x] **Multi-chart layouts** — Single, vertical split, horizontal split, and 1L+2R layouts with draggable dividers
|
||||
- [x] **Canvas persistence** — Named drawing canvases per symbol, with auto-save every 5 minutes
|
||||
- [x] **Dark & Light themes** — Full theme toggle synced across widget and UI
|
||||
|
||||
### Watchlist & Interaction
|
||||
- [x] **Live watchlist sidebar** — Real-time price, 24h change tracking, drag-and-drop reordering
|
||||
- [x] **Multiple custom lists** — Create and manage separate watchlists
|
||||
- [ ] **Frontend symbol management** — Add/remove tracked symbols from the frontend UI (currently `TRACKED_SYMBOL` is only controlled via the backend `.env` file)
|
||||
|
||||
### Security & Deployment
|
||||
- [x] **Google OAuth protection** — Email whitelist access control with 144-hour session persistence
|
||||
- [x] **Docker ready** — Multi-stage builds, Docker Compose with shared network
|
||||
- [ ] **Google Firebase integration** — Connect backend API via Firebase for managed authentication and hosting
|
||||
|
||||
## 📁 Project Structure
|
||||
|
||||
```
|
||||
view/
|
||||
├── backend/ # Rust data engine & API server
|
||||
│ ├── src/
|
||||
│ │ ├── main.rs # Axum HTTP server bootstrap
|
||||
│ │ ├── binance_collector.rs # WebSocket real-time collection + REST sync
|
||||
│ │ ├── historical_downloader.rs # Binance data archive (ZIP) downloader
|
||||
│ │ ├── database.rs # TimescaleDB operations & aggregation
|
||||
│ │ ├── scheduler.rs # Task coordination & collector lifecycle
|
||||
│ │ ├── klinechart.rs # KlineChart REST API handlers
|
||||
│ │ ├── tradingview.rs # TradingView UDF API + WebSocket + Canvas
|
||||
│ │ ├── structs.rs # Data types (CandleData, Interval, WsMessage…)
|
||||
│ │ ├── error.rs # Custom error types
|
||||
│ │ └── lib.rs # Public module exports
|
||||
│ ├── tests/
|
||||
│ │ ├── connection_test.rs # Database connection tests
|
||||
│ │ ├── database_test.rs # CRUD & query tests
|
||||
│ │ ├── scheduler_test.rs # Scheduler command & lifecycle tests
|
||||
│ │ ├── sync_test.rs # Single symbol sync tests
|
||||
│ │ └── sync_full_history_test.rs
|
||||
│ ├── examples/
|
||||
│ │ ├── sync_all.rs # Sync all symbols (standard)
|
||||
│ │ ├── sync_all_fast.rs # Sync all symbols (parallel with proxy pool)
|
||||
│ │ └── sql.txt # Reference SQL for TimescaleDB setup
|
||||
│ ├── Dockerfile
|
||||
│ └── docker-compose.yml
|
||||
│
|
||||
├── frontend/ # Charting Library frontend
|
||||
│ ├── index.html # Main app (widget + watchlist + layouts)
|
||||
│ ├── login.html # Google OAuth login page
|
||||
│ ├── auth.js # AuthGuard — session management
|
||||
│ ├── auth-config.js # OAuth & API configuration
|
||||
│ ├── charting_library/ # Charting Library assets
|
||||
│ ├── datafeeds/ # UDF datafeed adapter
|
||||
│ ├── Dockerfile
|
||||
│ └── docker-compose.yml
|
||||
│
|
||||
└── references/ # Git submodules
|
||||
├── binance-rust/ # Binance connector SDK
|
||||
└── library/ # Charting Library source
|
||||
```
|
||||
|
||||
## 🛠️ Tech Stack
|
||||
|
||||
| Layer | Technology |
|
||||
|-------|-----------|
|
||||
| **Backend** | Rust, Axum, sqlx, tokio, tokio-tungstenite |
|
||||
| **Database** | PostgreSQL + TimescaleDB |
|
||||
| **Frontend** | Charting Library v29.4, Vanilla JS |
|
||||
| **Auth** | Google Identity Services (OAuth) |
|
||||
| **Deployment** | Docker, Nginx, Docker Compose |
|
||||
|
||||
## 🚀 Deployment
|
||||
|
||||
For first-time users of Nginx Proxy Manager, TimescaleDB, PgAdmin, Docker, or Cloudflare — the easiest way to deploy is to let **Claude Opus 4.6** study this project and guide you through each step. If you encounter persistent issues, please open an Issue on this repository.
|
||||
|
||||
### Option 1: Full Self-Hosted Deployment
|
||||
|
||||
Deploy the entire stack on your own server with Docker and Nginx Proxy Manager as the reverse proxy.
|
||||
|
||||
> [!NOTE]
|
||||
> If you are unsure about any of the steps below, ask **Claude Opus 4.6** for guidance — it can walk you through each step in detail.
|
||||
|
||||
#### Network Architecture
|
||||
|
||||
```
|
||||
┌─────────────────── Docker Network: cycle ───────────────────┐
|
||||
│ │
|
||||
│ ┌──────────────────┐ ┌──────────────┐ │
|
||||
│ │ Nginx Proxy Mgr │ │ TimescaleDB │ │
|
||||
│ │ :80 / :443 │ │ :5432 │ │
|
||||
│ └────────┬─────────┘ └──────┬───────┘ │
|
||||
│ │ │ │
|
||||
│ │ │ │
|
||||
│ ┌────────▼──┐ ┌───────────┐ │ │
|
||||
│ │ Frontend │ │ Backend │───┘ │
|
||||
│ │ :80 │ │ :3000 │ │
|
||||
│ │ (nginx) │ │ (axum) │ │
|
||||
│ └───────────┘ └───────────┘ │
|
||||
│ │
|
||||
└─────────────────────────────────────────────────────────────┘
|
||||
▲
|
||||
Public domain
|
||||
view.yourdomain.com
|
||||
```
|
||||
|
||||
All containers **must** run on the same Docker network `cycle` so they can communicate by container name. Only the **frontend** needs to be exposed to the public via Nginx Proxy Manager — the backend (port `3000`) is accessed internally by the frontend container through Docker DNS.
|
||||
|
||||
---
|
||||
|
||||
#### Step 1: Create Docker Network
|
||||
|
||||
```bash
|
||||
docker network create cycle
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
#### Step 2: Database Setup (TimescaleDB)
|
||||
|
||||
Create a `docker-compose.yml` for TimescaleDB on the `cycle` network:
|
||||
|
||||
```yaml
|
||||
# database/docker-compose.yml
|
||||
services:
|
||||
timescaledb:
|
||||
image: timescale/timescaledb:latest-pg16
|
||||
container_name: timescaledb
|
||||
networks:
|
||||
- cycle
|
||||
environment:
|
||||
- POSTGRES_USER=quant
|
||||
- POSTGRES_PASSWORD=your_secure_password
|
||||
- POSTGRES_DB=crypto_database
|
||||
volumes:
|
||||
- timescaledb_data:/var/lib/postgresql/data
|
||||
restart: unless-stopped
|
||||
|
||||
volumes:
|
||||
timescaledb_data:
|
||||
|
||||
networks:
|
||||
cycle:
|
||||
external: true
|
||||
```
|
||||
|
||||
```bash
|
||||
docker compose up -d
|
||||
```
|
||||
|
||||
Then initialize the schema using the SQL in [backend/examples/sql.txt](backend/examples/sql.txt):
|
||||
|
||||
```bash
|
||||
docker exec -i timescaledb psql -U quant -d crypto_database < backend/examples/sql.txt
|
||||
```
|
||||
|
||||
> [!TIP]
|
||||
> For database management, consider deploying **PgAdmin** alongside TimescaleDB. See [this guide](https://n8n.cathiefish.art/n8n-instances-twitter-ai-%E5%88%86%E6%9E%90%E7%9B%91%E6%8E%A7-5b706bb444d7) for PgAdmin setup instructions. For beginners, ask **Claude Opus 4.6** to walk you through it.
|
||||
|
||||
#### Step 3: Deploy Backend
|
||||
|
||||
**1. Configure `.env`**
|
||||
|
||||
```bash
|
||||
cd backend
|
||||
cp .env.example .env
|
||||
```
|
||||
|
||||
Edit `backend/.env`:
|
||||
|
||||
```env
|
||||
RUST_LOG="INFO,binance_sdk::common::utils=off,binance_sdk::common::websocket=off"
|
||||
|
||||
DATABASE_URL="postgres://quant:your_secure_password@timescaledb:5432/crypto_database"
|
||||
|
||||
TRACKED_SYMBOL=[BTCUSDT,ETHUSDT,BNBUSDT,SOLUSDT,XRPUSDT]
|
||||
|
||||
# Proxy settings (optional — leave empty for direct connection)
|
||||
PROXY_HOST=dc.your-proxy-provider.com
|
||||
PROXY_USERNAME=your_username
|
||||
PROXY_PASSWORD=your_password
|
||||
PROXY_PROTOCOL=https/http/socks5
|
||||
PROXY_PORT_START=10000
|
||||
PROXY_PORT_END=10099
|
||||
```
|
||||
|
||||
> [!NOTE]
|
||||
> `DATABASE_URL` uses the container name `timescaledb` as the hostname — this works because both containers are on the `cycle` network. You can also use the database container's absolute IP (find it with `docker inspect timescaledb --format '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}'`). Make sure the database container is also on the `cycle` network. `TRACKED_SYMBOL` currently only supports **USDS-M Futures (Swap)**, not Spot.
|
||||
|
||||
> [!WARNING]
|
||||
> **Proxy is strongly recommended.** Historical data sync downloads from [Binance Data Archive](https://data.binance.vision/) for all tracked symbols. With a multi-port proxy pool (e.g. 100 concurrent connections), a full sync completes in hours. **Without a proxy, syncing may take several days.** If `PROXY_HOST` is left empty, the backend falls back to a single direct connection.
|
||||
|
||||
**2. Build & Run**
|
||||
|
||||
```bash
|
||||
docker build -t backend .
|
||||
docker compose up -d
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
#### Step 4: Deploy Frontend
|
||||
|
||||
Before building the frontend container, you need to configure authentication and API connection.
|
||||
|
||||
**1. Configure Google OAuth — `auth-config.js`**
|
||||
|
||||
Since the frontend runs inside the Docker network, it accesses the backend via the **container name**:
|
||||
|
||||
```js
|
||||
// Use the backend container name as the hostname (internal Docker DNS)
|
||||
window.API_CONFIG = { baseUrl: 'http://backend:3000' };
|
||||
|
||||
const AUTH_CONFIG = {
|
||||
// Replace with your Google OAuth Client ID from GCP Console
|
||||
clientId: 'YOUR_CLIENT_ID.apps.googleusercontent.com',
|
||||
onSuccess: (user) => { console.log('Auth successful:', user.email); },
|
||||
onError: (error) => { console.error('Auth error:', error); }
|
||||
};
|
||||
window.AUTH_CONFIG = AUTH_CONFIG;
|
||||
```
|
||||
|
||||
To find the backend container IP (useful for debugging):
|
||||
|
||||
```bash
|
||||
$ docker inspect backend --format '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}'
|
||||
172.18.0.3
|
||||
```
|
||||
|
||||
**2. Configure Email Whitelist — `login.html`**
|
||||
|
||||
Add your Google account email to the whitelist:
|
||||
|
||||
```js
|
||||
const allowedEmails = ['your-email@gmail.com'];
|
||||
```
|
||||
|
||||
> [!IMPORTANT]
|
||||
> Google OAuth requires a Client ID from GCP Console. Tutorial placeholder — to be added.
|
||||
|
||||
**3. Build & Run**
|
||||
|
||||
```bash
|
||||
cd frontend
|
||||
docker build -t frontend .
|
||||
docker compose up -d
|
||||
```
|
||||
|
||||
> [!WARNING]
|
||||
> The frontend and backend containers **must** be on the same Docker network (`cycle`). This is already configured in both `docker-compose.yml` files via `networks: cycle: external: true`.
|
||||
|
||||
---
|
||||
|
||||
#### Step 5: Nginx Proxy Manager
|
||||
|
||||
Nginx Proxy Manager must also run on the `cycle` network. Create a `docker-compose.yml`:
|
||||
|
||||
```yaml
|
||||
# npm/docker-compose.yml
|
||||
services:
|
||||
nginx-proxy-manager:
|
||||
image: jc21/nginx-proxy-manager:latest
|
||||
container_name: nginx-proxy-manager
|
||||
networks:
|
||||
- cycle
|
||||
ports:
|
||||
- "80:80"
|
||||
- "443:443"
|
||||
- "81:81"
|
||||
volumes:
|
||||
- npm_data:/data
|
||||
- npm_letsencrypt:/etc/letsencrypt
|
||||
restart: unless-stopped
|
||||
|
||||
volumes:
|
||||
npm_data:
|
||||
npm_letsencrypt:
|
||||
|
||||
networks:
|
||||
cycle:
|
||||
external: true
|
||||
```
|
||||
|
||||
```bash
|
||||
docker compose up -d
|
||||
```
|
||||
|
||||
> [!TIP]
|
||||
> For detailed Nginx Proxy Manager setup and Docker deployment best practices, see [this guide](https://n8n.cathiefish.art/rsshub-install-f5ad036a4dd9). For beginners, ask **Claude Opus 4.6** to walk you through it.
|
||||
|
||||
Access the admin panel at `http://your-server-ip:81` (default: `admin@example.com` / `changeme`).
|
||||
|
||||
**Create a Proxy Host for the frontend:**
|
||||
|
||||
| Domain | Forward Hostname | Forward Port | SSL |
|
||||
|--------|-----------------|--------------|-----|
|
||||
| `view.yourdomain.com` | `frontend_tv` | `80` | ✅ Let's Encrypt |
|
||||
|
||||
> [!TIP]
|
||||
> The "Forward Hostname" uses the **container name** (not IP), which works because all containers share the `cycle` network. The backend does **not** need a public proxy — the frontend accesses it internally via Docker DNS (`http://backend:3000`).
|
||||
|
||||
After setup, your platform will be accessible at `https://view.yourdomain.com`.
|
||||
|
||||
---
|
||||
|
||||
### Option 2: Backend Self-Hosted + Frontend on Cloudflare Pages
|
||||
|
||||
Build on top of **Option 1** — keep the same server-side setup (Docker network, TimescaleDB, backend), but additionally expose the backend API to the public internet and deploy the frontend to Cloudflare Pages instead of self-hosting it.
|
||||
|
||||
> [!NOTE]
|
||||
> If you are unsure about any of these steps, ask **Claude Opus 4.6** — this is a straightforward process.
|
||||
|
||||
> [!CAUTION]
|
||||
> **Do NOT** include "tradingview" in your Cloudflare Pages project name or custom domain. TradingView actively enforces their trademark and your deployment **will be taken down**. Use a neutral name like `view`, `chart`, or `crypto-dash`.
|
||||
|
||||
#### Step 1: Backend + Database
|
||||
|
||||
Complete **Option 1 Steps 1–3** (create `cycle` network, deploy TimescaleDB, deploy backend).
|
||||
|
||||
#### Step 2: Expose Backend API via Nginx Proxy Manager
|
||||
|
||||
Since the frontend will be served from Cloudflare (outside your Docker network), the backend API must be publicly accessible. Add a **second Proxy Host** in Nginx Proxy Manager:
|
||||
|
||||
| Domain | Forward Hostname | Forward Port | SSL |
|
||||
|--------|-----------------|--------------|-----|
|
||||
| `api.yourdomain.com` | `backend` | `3000` | ✅ Let's Encrypt |
|
||||
|
||||
> [!IMPORTANT]
|
||||
> Enable **Websockets Support** for this proxy host — required for real-time candle streaming.
|
||||
|
||||
#### Step 3: Configure Frontend
|
||||
|
||||
Before deploying to Cloudflare, update the config files:
|
||||
|
||||
**`auth-config.js`** — point `baseUrl` to the **public backend domain** from Step 2:
|
||||
|
||||
```js
|
||||
window.API_CONFIG = { baseUrl: 'https://api.yourdomain.com' };
|
||||
|
||||
const AUTH_CONFIG = {
|
||||
clientId: 'YOUR_CLIENT_ID.apps.googleusercontent.com',
|
||||
// ...
|
||||
};
|
||||
```
|
||||
|
||||
**`login.html`** — add your email to the whitelist:
|
||||
|
||||
```js
|
||||
const allowedEmails = ['your-email@gmail.com'];
|
||||
```
|
||||
|
||||
#### Step 4: Deploy to Cloudflare Pages
|
||||
|
||||
1. Fork or clone this repository to your own GitHub account
|
||||
2. Go to [Cloudflare Dashboard](https://dash.cloudflare.com/) → **Workers & Pages** → **Create**
|
||||
3. Select **Pages** → **Connect to Git**
|
||||
4. Authorize Cloudflare to access your GitHub account and select the repository
|
||||
5. Configure the build settings:
|
||||
|
||||
| Setting | Value |
|
||||
|---------|-------|
|
||||
| Production branch | `main` |
|
||||
| Build command | *(leave empty)* |
|
||||
| Build output directory | `frontend` |
|
||||
|
||||
6. Click **Save and Deploy**
|
||||
|
||||
Cloudflare will assign a `*.pages.dev` domain. You can add a custom domain in **Pages** → **Custom domains**.
|
||||
|
||||
---
|
||||
|
||||
## 📜 License
|
||||
|
||||
MIT
|
||||
|
||||
|
||||
Generated By Claude Opus 4.6
|
||||
+400
@@ -0,0 +1,400 @@
|
||||
# 📊 View — 加密货币图表平台
|
||||
|
||||
自建的实时加密货币数据采集与可视化平台,适用于 **Binance USDS-M 永续合约**。结合高性能 Rust 后端与专业图表前端,提供机构级市场数据工具。
|
||||
|
||||
这个项目主要是我自用的,实在没太多精力维护。我也不擅长前端,前端代码可能不太规范。欢迎大家发起 Pull Request 和 Issue!
|
||||
|
||||
如您所见,这并不是一个简单的一键启动的傻瓜工程,也不是面向小白的玩具项目。请原谅我没有时间也没有能力将其简单化。最简单的部署方式就是让 **Claude Opus 4.6** 研究完整个项目,然后让它来指导你启动。
|
||||
|
||||
如果后端部署实在太过困难,您可以暂时直接使用我的公开后端 API 端口:`api-view.cathiefish.org`,这样您只需将前端部署到 Cloudflare Pages 即可。注意该端口仅保证提供 **BTCUSDT, ETHUSDT, SOLUSDT, BNBUSDT, XRPUSDT, SUIUSDT** 的数据。请参阅下方[部署](#-部署)章节了解如何配置。
|
||||
|
||||

|
||||

|
||||

|
||||
|
||||
## ✨ 功能
|
||||
|
||||
### 数据采集与存储
|
||||
- [x] **实时 WebSocket 推流** — 从 Binance 合并流实时接收 1 分钟 K 线数据,支持自动重连和缺口回补
|
||||
- [x] **三级历史数据同步** — 月度 ZIP → 每日 ZIP → REST API,从 [Binance 数据归档](https://data.binance.vision/) 尽可能快速回补
|
||||
- [x] **TimescaleDB 时序存储** — Hypertable 优化,支持 `time_bucket` 聚合,覆盖 8 个时间周期(1m, 5m, 15m, 1h, 4h, 1D, 1W, 1M)
|
||||
- [x] **代理池支持** — 最多 100 个并发代理客户端,用于高吞吐量并行下载
|
||||
- [ ] **Binance 现货支持** — 现货市场数据采集,使用 `.P` 后缀区分合约与现货
|
||||
- [ ] **MCP 支持** — Model Context Protocol 集成
|
||||
|
||||
### 图表与可视化
|
||||
- [x] **专业图表引擎** — 完整的指标和画图工具支持
|
||||
- [x] **自定义指标** — 净成交量(NV-C)和累积成交量差(CVD-C)
|
||||
- [x] **多图表布局** — 单图、垂直分割、水平分割、1 左 + 2 右布局,分隔线可拖动
|
||||
- [x] **画布持久化** — 按品种保存命名画布,每 5 分钟自动保存
|
||||
- [x] **深色/浅色主题** — 主题切换同步到图表组件和 UI
|
||||
|
||||
### 自选列表与交互
|
||||
- [x] **实时自选列表侧栏** — 实时价格、24 小时涨跌幅、拖拽排序
|
||||
- [x] **多自定义列表** — 创建和管理多个自选列表
|
||||
- [ ] **前端品种管理** — 从前端 UI 添加/移除追踪品种(目前 `TRACKED_SYMBOL` 仅通过后端 `.env` 文件控制)
|
||||
|
||||
### 安全与部署
|
||||
- [x] **Google OAuth 保护** — 邮箱白名单访问控制,144 小时会话持久化
|
||||
- [x] **Docker 就绪** — 多阶段构建,Docker Compose 共享网络
|
||||
- [ ] **Google Firebase 集成** — 通过 Firebase 连接后端 API,实现托管认证与托管部署
|
||||
|
||||
## 📁 项目结构
|
||||
|
||||
```
|
||||
view/
|
||||
├── backend/ # Rust 数据引擎 & API 服务
|
||||
│ ├── src/
|
||||
│ │ ├── main.rs # Axum HTTP 服务启动
|
||||
│ │ ├── binance_collector.rs # WebSocket 实时采集 + REST 同步
|
||||
│ │ ├── historical_downloader.rs # Binance 数据归档 (ZIP) 下载器
|
||||
│ │ ├── database.rs # TimescaleDB 操作与聚合
|
||||
│ │ ├── scheduler.rs # 任务调度与采集器生命周期
|
||||
│ │ ├── klinechart.rs # KlineChart REST API 处理
|
||||
│ │ ├── tradingview.rs # TradingView UDF API + WebSocket + Canvas
|
||||
│ │ ├── structs.rs # 数据类型(CandleData, Interval, WsMessage…)
|
||||
│ │ ├── error.rs # 自定义错误类型
|
||||
│ │ └── lib.rs # 公开模块导出
|
||||
│ ├── tests/
|
||||
│ │ ├── connection_test.rs # 数据库连接测试
|
||||
│ │ ├── database_test.rs # CRUD 与查询测试
|
||||
│ │ ├── scheduler_test.rs # 调度器命令与生命周期测试
|
||||
│ │ ├── sync_test.rs # 单品种同步测试
|
||||
│ │ └── sync_full_history_test.rs
|
||||
│ ├── examples/
|
||||
│ │ ├── sync_all.rs # 同步所有品种(标准模式)
|
||||
│ │ ├── sync_all_fast.rs # 同步所有品种(代理池并行)
|
||||
│ │ └── sql.txt # TimescaleDB 建表 SQL
|
||||
│ ├── Dockerfile
|
||||
│ └── docker-compose.yml
|
||||
│
|
||||
├── frontend/ # 图表库前端
|
||||
│ ├── index.html # 主应用(图表 + 自选列表 + 布局)
|
||||
│ ├── login.html # Google OAuth 登录页
|
||||
│ ├── auth.js # AuthGuard — 会话管理
|
||||
│ ├── auth-config.js # OAuth 与 API 配置
|
||||
│ ├── charting_library/ # 图表库资源
|
||||
│ ├── datafeeds/ # UDF 数据源适配器
|
||||
│ ├── Dockerfile
|
||||
│ └── docker-compose.yml
|
||||
│
|
||||
└── references/ # Git 子模块
|
||||
├── binance-rust/ # Binance 连接器 SDK
|
||||
└── library/ # 图表库源码
|
||||
```
|
||||
|
||||
## 🛠️ 技术栈
|
||||
|
||||
| 层级 | 技术 |
|
||||
|------|------|
|
||||
| **后端** | Rust, Axum, sqlx, tokio, tokio-tungstenite |
|
||||
| **数据库** | PostgreSQL + TimescaleDB |
|
||||
| **前端** | Charting Library v29.4, Vanilla JS |
|
||||
| **认证** | Google Identity Services (OAuth) |
|
||||
| **部署** | Docker, Nginx, Docker Compose |
|
||||
|
||||
## 🚀 部署
|
||||
|
||||
对于第一次接触 Nginx Proxy Manager、TimescaleDB、PgAdmin、Docker 或 Cloudflare 的用户,最简单的部署方式就是让 **Claude Opus 4.6** 研究这个项目,然后让它一步步指导你部署。如果持续失败,请在本仓库提交 Issue。
|
||||
|
||||
### 方案一:完全自建部署
|
||||
|
||||
在自己的服务器上部署全套服务,使用 Docker 和 Nginx Proxy Manager 作为反向代理。
|
||||
|
||||
> [!NOTE]
|
||||
> 如果不清楚以下任何步骤,请咨询 **Claude Opus 4.6**,它可以详细指导你完成每一步。
|
||||
|
||||
#### 网络架构
|
||||
|
||||
```
|
||||
┌─────────────────── Docker 网络: cycle ──────────────────────┐
|
||||
│ │
|
||||
│ ┌──────────────────┐ ┌──────────────┐ │
|
||||
│ │ Nginx Proxy Mgr │ │ TimescaleDB │ │
|
||||
│ │ :80 / :443 │ │ :5432 │ │
|
||||
│ └────────┬─────────┘ └──────┬───────┘ │
|
||||
│ │ │ │
|
||||
│ │ │ │
|
||||
│ ┌────────▼──┐ ┌───────────┐ │ │
|
||||
│ │ Frontend │ │ Backend │───┘ │
|
||||
│ │ :80 │ │ :3000 │ │
|
||||
│ │ (nginx) │ │ (axum) │ │
|
||||
│ └───────────┘ └───────────┘ │
|
||||
│ │
|
||||
└─────────────────────────────────────────────────────────────┘
|
||||
▲
|
||||
公网域名
|
||||
view.yourdomain.com
|
||||
```
|
||||
|
||||
所有容器**必须**在同一个 Docker 网络 `cycle` 中运行,这样才能通过容器名互相通信。只有**前端**需要通过 Nginx Proxy Manager 暴露到公网 —— 后端(端口 `3000`)由前端容器通过 Docker 内部 DNS 访问。
|
||||
|
||||
---
|
||||
|
||||
#### 第一步:创建 Docker 网络
|
||||
|
||||
```bash
|
||||
docker network create cycle
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
#### 第二步:数据库部署(TimescaleDB)
|
||||
|
||||
为 TimescaleDB 创建 `docker-compose.yml`,加入 `cycle` 网络:
|
||||
|
||||
```yaml
|
||||
# database/docker-compose.yml
|
||||
services:
|
||||
timescaledb:
|
||||
image: timescale/timescaledb:latest-pg16
|
||||
container_name: timescaledb
|
||||
networks:
|
||||
- cycle
|
||||
environment:
|
||||
- POSTGRES_USER=quant
|
||||
- POSTGRES_PASSWORD=your_secure_password
|
||||
- POSTGRES_DB=crypto_database
|
||||
volumes:
|
||||
- timescaledb_data:/var/lib/postgresql/data
|
||||
restart: unless-stopped
|
||||
|
||||
volumes:
|
||||
timescaledb_data:
|
||||
|
||||
networks:
|
||||
cycle:
|
||||
external: true
|
||||
```
|
||||
|
||||
```bash
|
||||
docker compose up -d
|
||||
```
|
||||
|
||||
然后使用 [backend/examples/sql.txt](backend/examples/sql.txt) 中的 SQL 初始化数据库:
|
||||
|
||||
```bash
|
||||
docker exec -i timescaledb psql -U quant -d crypto_database < backend/examples/sql.txt
|
||||
```
|
||||
|
||||
> [!TIP]
|
||||
> 建议同时部署 **PgAdmin** 用于数据库管理。详见[这篇教程](https://n8n.cathiefish.art/n8n-instances-twitter-ai-%E5%88%86%E6%9E%90%E7%9B%91%E6%8E%A7-5b706bb444d7)。新手建议直接让 **Claude Opus 4.6** 来指导。
|
||||
|
||||
#### 第三步:部署后端
|
||||
|
||||
**1. 配置 `.env`**
|
||||
|
||||
```bash
|
||||
cd backend
|
||||
cp .env.example .env
|
||||
```
|
||||
|
||||
编辑 `backend/.env`:
|
||||
|
||||
```env
|
||||
RUST_LOG="INFO,binance_sdk::common::utils=off,binance_sdk::common::websocket=off"
|
||||
|
||||
DATABASE_URL="postgres://quant:your_secure_password@timescaledb:5432/crypto_database"
|
||||
|
||||
TRACKED_SYMBOL=[BTCUSDT,ETHUSDT,BNBUSDT,SOLUSDT,XRPUSDT]
|
||||
|
||||
# 代理设置(可选 — 留空则直连)
|
||||
PROXY_HOST=dc.your-proxy-provider.com
|
||||
PROXY_USERNAME=your_username
|
||||
PROXY_PASSWORD=your_password
|
||||
PROXY_PROTOCOL=https
|
||||
PROXY_PORT_START=10000
|
||||
PROXY_PORT_END=10099
|
||||
```
|
||||
|
||||
> [!NOTE]
|
||||
> `DATABASE_URL` 使用容器名 `timescaledb` 作为主机名 —— 因为两个容器都在 `cycle` 网络中。也可以使用数据库容器的绝对 IP(通过 `docker inspect timescaledb --format '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}'` 查询)。确保数据库容器也在 `cycle` 网络中。`TRACKED_SYMBOL` 目前仅支持 **USDS-M 永续合约(Swap)**,不支持现货。
|
||||
|
||||
> [!WARNING]
|
||||
> **强烈建议配置代理。** 后端需要从 [Binance 数据归档](https://data.binance.vision/) 下载所有追踪品种的历史数据。使用多端口代理池(如 100 个并发连接)。**不使用代理的话,同步可能需要几天时间。** 如果 `PROXY_HOST` 留空,后端将使用单一直连。
|
||||
|
||||
**2. 构建并运行**
|
||||
|
||||
```bash
|
||||
docker build -t backend .
|
||||
docker compose up -d
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
#### 第四步:部署前端
|
||||
|
||||
构建前端容器之前,需要先配置认证和 API 连接。
|
||||
|
||||
**1. 配置 Google OAuth — `auth-config.js`**
|
||||
|
||||
前端在 Docker 网络内部运行,通过**容器名**访问后端:
|
||||
|
||||
```js
|
||||
// 使用后端容器名作为主机名(Docker 内部 DNS)
|
||||
window.API_CONFIG = { baseUrl: 'http://backend:3000' };
|
||||
|
||||
const AUTH_CONFIG = {
|
||||
// 替换为你从 GCP Console 获取的 Google OAuth Client ID
|
||||
clientId: 'YOUR_CLIENT_ID.apps.googleusercontent.com',
|
||||
onSuccess: (user) => { console.log('Auth successful:', user.email); },
|
||||
onError: (error) => { console.error('Auth error:', error); }
|
||||
};
|
||||
window.AUTH_CONFIG = AUTH_CONFIG;
|
||||
```
|
||||
|
||||
查询后端容器 IP(调试用):
|
||||
|
||||
```bash
|
||||
$ docker inspect backend --format '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}'
|
||||
172.18.0.3
|
||||
```
|
||||
|
||||
**2. 配置邮箱白名单 — `login.html`**
|
||||
|
||||
将你的 Google 邮箱添加到白名单:
|
||||
|
||||
```js
|
||||
const allowedEmails = ['your-email@gmail.com'];
|
||||
```
|
||||
|
||||
> [!IMPORTANT]
|
||||
> Google OAuth 需要从 GCP Console 获取 Client ID。教程待补充。
|
||||
|
||||
**3. 构建并运行**
|
||||
|
||||
```bash
|
||||
cd frontend
|
||||
docker build -t frontend .
|
||||
docker compose up -d
|
||||
```
|
||||
|
||||
> [!WARNING]
|
||||
> 前端和后端容器**必须**在同一个 Docker 网络(`cycle`)中。两个 `docker-compose.yml` 文件已通过 `networks: cycle: external: true` 配置好。
|
||||
|
||||
---
|
||||
|
||||
#### 第五步:Nginx Proxy Manager
|
||||
|
||||
Nginx Proxy Manager 也必须在 `cycle` 网络中运行。创建 `docker-compose.yml`:
|
||||
|
||||
```yaml
|
||||
# npm/docker-compose.yml
|
||||
services:
|
||||
nginx-proxy-manager:
|
||||
image: jc21/nginx-proxy-manager:latest
|
||||
container_name: nginx-proxy-manager
|
||||
networks:
|
||||
- cycle
|
||||
ports:
|
||||
- "80:80"
|
||||
- "443:443"
|
||||
- "81:81"
|
||||
volumes:
|
||||
- npm_data:/data
|
||||
- npm_letsencrypt:/etc/letsencrypt
|
||||
restart: unless-stopped
|
||||
|
||||
volumes:
|
||||
npm_data:
|
||||
npm_letsencrypt:
|
||||
|
||||
networks:
|
||||
cycle:
|
||||
external: true
|
||||
```
|
||||
|
||||
```bash
|
||||
docker compose up -d
|
||||
```
|
||||
|
||||
> [!TIP]
|
||||
> Nginx Proxy Manager 的详细部署和 Docker 最佳实践,请参阅[这篇教程](https://n8n.cathiefish.art/rsshub-install-f5ad036a4dd9)。新手建议直接让 **Claude Opus 4.6** 来指导。
|
||||
|
||||
访问管理面板 `http://你的服务器IP:81`(默认账号:`admin@example.com` / `changeme`)。
|
||||
|
||||
**为前端创建 Proxy Host:**
|
||||
|
||||
| 域名 | 转发主机名 | 转发端口 | SSL |
|
||||
|------|-----------|---------|-----|
|
||||
| `view.yourdomain.com` | `frontend_tv` | `80` | ✅ Let's Encrypt |
|
||||
|
||||
> [!TIP]
|
||||
> "转发主机名"使用的是**容器名**(不是 IP),因为所有容器共享 `cycle` 网络。后端**不需要**公网代理 —— 前端通过 Docker 内部 DNS(`http://backend:3000`)访问。
|
||||
|
||||
部署完成后,即可通过 `https://view.yourdomain.com` 访问。
|
||||
|
||||
---
|
||||
|
||||
### 方案二:后端自建 + 前端部署到 Cloudflare Pages
|
||||
|
||||
在**方案一**的基础上,额外将后端 API 暴露到公网,并将前端部署到 Cloudflare Pages,而不是自建托管。
|
||||
|
||||
> [!NOTE]
|
||||
> 如果不清楚以下步骤,请咨询 **Claude Opus 4.6** —— 这是很简单的操作。
|
||||
|
||||
> [!CAUTION]
|
||||
> Cloudflare Pages 项目名和自定义域名中**不要**包含 "tradingview"。TradingView 会主动维权,你的部署**会被下架**。使用中性名称如 `view`、`chart`、`crypto-dash`。
|
||||
|
||||
#### 第一步:后端 + 数据库
|
||||
|
||||
完成**方案一的第一至三步**(创建 `cycle` 网络、部署 TimescaleDB、部署后端)。
|
||||
|
||||
#### 第二步:通过 Nginx Proxy Manager 暴露后端 API
|
||||
|
||||
由于前端将从 Cloudflare 提供服务(在 Docker 网络外部),后端 API 必须可以从公网访问。在 Nginx Proxy Manager 中添加一个 **Proxy Host**:
|
||||
|
||||
| 域名 | 转发主机名 | 转发端口 | SSL |
|
||||
|------|-----------|---------|-----|
|
||||
| `api.yourdomain.com` | `backend` | `3000` | ✅ Let's Encrypt |
|
||||
|
||||
> [!IMPORTANT]
|
||||
> 为此 Proxy Host 启用 **Websockets Support** —— 实时 K 线推送需要 WebSocket。
|
||||
|
||||
#### 第三步:配置前端
|
||||
|
||||
部署到 Cloudflare 之前,更新配置文件:
|
||||
|
||||
**`auth-config.js`** —— 将 `baseUrl` 指向第二步的**公网后端域名**:
|
||||
|
||||
```js
|
||||
window.API_CONFIG = { baseUrl: 'https://api.yourdomain.com' };
|
||||
|
||||
const AUTH_CONFIG = {
|
||||
clientId: 'YOUR_CLIENT_ID.apps.googleusercontent.com',
|
||||
// ...
|
||||
};
|
||||
```
|
||||
|
||||
**`login.html`** —— 添加你的邮箱到白名单:
|
||||
|
||||
```js
|
||||
const allowedEmails = ['your-email@gmail.com'];
|
||||
```
|
||||
|
||||
#### 第四步:部署到 Cloudflare Pages
|
||||
|
||||
1. Fork 或 Clone 本仓库到你自己的 GitHub 账号
|
||||
2. 进入 [Cloudflare 控制台](https://dash.cloudflare.com/) → **Workers & Pages** → **创建**
|
||||
3. 选择 **Pages** → **连接到 Git**
|
||||
4. 授权 Cloudflare 访问你的 GitHub 账号,选择仓库
|
||||
5. 配置构建设置:
|
||||
|
||||
| 设置 | 值 |
|
||||
|------|---|
|
||||
| 生产分支 | `main` |
|
||||
| 构建命令 | *(留空)* |
|
||||
| 构建输出目录 | `frontend` |
|
||||
|
||||
6. 点击 **保存并部署**
|
||||
|
||||
Cloudflare 会分配一个 `*.pages.dev` 域名。你可以在 **Pages** → **自定义域** 中添加自定义域名。
|
||||
|
||||
---
|
||||
|
||||
## 📜 许可证
|
||||
|
||||
MIT
|
||||
|
||||
|
||||
Generated By Claude Opus 4.6
|
||||
@@ -0,0 +1,14 @@
|
||||
RUST_LOG="INFO,binance_sdk::common::utils=off,binance_sdk::common::websocket=off"
|
||||
|
||||
DATABASE_URL="postgres://xxx:xxxxxxx"
|
||||
|
||||
TRACKED_SYMBOL=[BTCUSDT,XRPUSDT,BNBUSDT,SOLUSDT,ETHUSDT]
|
||||
|
||||
# Proxy settings (optional — leave empty or remove for direct connection)
|
||||
# Required for fast multi-proxy parallel downloads from Binance Data Archive
|
||||
PROXY_HOST=
|
||||
PROXY_USERNAME=
|
||||
PROXY_PASSWORD=
|
||||
PROXY_PROTOCOL=https
|
||||
PROXY_PORT_START=10000
|
||||
PROXY_PORT_END=10099
|
||||
@@ -0,0 +1,2 @@
|
||||
/target
|
||||
|
||||
Generated
+3981
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,28 @@
|
||||
[package]
|
||||
name = "backend"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
|
||||
binance-sdk = { version = "35.0.0", features = ["derivatives_trading_usds_futures", "spot"] }
|
||||
rand = "0.9"
|
||||
sqlx = { version = "0.8", features = ["runtime-tokio", "postgres"] }
|
||||
|
||||
axum = { version = "0.8", features = ["ws"] }
|
||||
tower-http = { version = "0.6", features = ["cors"] }
|
||||
|
||||
dotenv = "0.15.0"
|
||||
json = "0.12.4"
|
||||
log = "0.4.29"
|
||||
serde = { version = "1.0.228", features = ["derive"] }
|
||||
serde_json = "1.0.145"
|
||||
thiserror = "2.0.17"
|
||||
tokio = {version = "1.48.0", features = ["full"] }
|
||||
env_logger = "0.11"
|
||||
reqwest = { version = "0.12", features = ["stream"] }
|
||||
zip = "2.2"
|
||||
chrono = "0.4"
|
||||
csv = "1.3"
|
||||
futures = "0.3"
|
||||
tokio-tungstenite = { version = "0.26", features = ["native-tls"] }
|
||||
@@ -0,0 +1,14 @@
|
||||
# Build stage
|
||||
FROM rust:1.89-slim-bookworm AS builder
|
||||
WORKDIR /app
|
||||
RUN apt-get update && apt-get install -y pkg-config libssl-dev && rm -rf /var/lib/apt/lists/*
|
||||
COPY Cargo.toml Cargo.lock ./
|
||||
COPY src ./src
|
||||
RUN cargo build --release
|
||||
|
||||
# Runtime stage
|
||||
FROM debian:bookworm-slim
|
||||
RUN apt-get update && apt-get install -y ca-certificates libssl3 && rm -rf /var/lib/apt/lists/*
|
||||
COPY --from=builder /app/target/release/backend /usr/local/bin/backend
|
||||
EXPOSE 3000
|
||||
CMD ["backend"]
|
||||
@@ -0,0 +1,296 @@
|
||||
# 📊 Binance USDS Futures — Data Collection & API Backend
|
||||
|
||||
A high-performance Rust backend that collects, stores, and serves Binance USDS-M Futures K-line data in real-time. Designed as the data engine for custom charting frontends — supports both [KlineChart](https://klinecharts.com/) and [TradingView](https://www.tradingview.com/charting-library-docs/) out of the box.
|
||||
|
||||
## ✨ Features
|
||||
|
||||
- **Real-time WebSocket streaming** — Subscribe to 1-minute K-line updates via Binance combined streams, with auto-reconnect and backfill on disconnect
|
||||
- **Multi-strategy historical sync** — Monthly ZIP → Daily ZIP → REST API fallback for fastest possible backfill
|
||||
- **TimescaleDB-powered storage** — Hypertable-optimized with `time_bucket` aggregation for 8 timeframes (1m, 5m, 15m, 1h, 4h, 1D, 1W, 1M)
|
||||
- **Dual API interface** — KlineChart REST API + TradingView UDF-compatible datafeed
|
||||
- **Live WebSocket broadcast** — Push real-time candle updates to connected frontend clients
|
||||
- **Canvas persistence** — Save/load chart drawings per symbol to local filesystem
|
||||
- **Net Volume & Taker Buy Volume** — Custom indicators included in every response
|
||||
- **Proxy pool support** — Up to 100 proxy clients (port 10000–10099) for high-throughput parallel downloads
|
||||
- **Docker ready** — Multi-stage build with minimal runtime image
|
||||
|
||||
## 🏗️ Architecture
|
||||
|
||||
```
|
||||
┌──────────────────────────────────────────────────────────────────┐
|
||||
│ Axum HTTP Server (:3000) │
|
||||
│ │
|
||||
│ ┌─────────────────────┐ ┌──────────────────────────┐ │
|
||||
│ │ KlineChart API │ │ TradingView UDF API │ │
|
||||
│ │ /api/klines │ │ /config /history /ws │ │
|
||||
│ │ /api/symbols │ │ /symbols /search │ │
|
||||
│ │ /api/status │ │ /canvas/* │ │
|
||||
│ └────────┬────────────┘ └────────────┬─────────────┘ │
|
||||
│ │ │ │
|
||||
│ └──────────┬──────────────────────┘ │
|
||||
│ ▼ │
|
||||
│ ┌────────────────┐ │
|
||||
│ │ Scheduler │ │
|
||||
│ │ (Command Bus) │ │
|
||||
│ └───┬────────┬───┘ │
|
||||
│ │ │ │
|
||||
│ ┌──────────▼──┐ ┌──▼──────────────────────┐ │
|
||||
│ │ Binance │ │ Historical Downloader │ │
|
||||
│ │ Collector │ │ (ZIP + REST backfill) │ │
|
||||
│ │ (WebSocket)│ └─────────────────────────┘ │
|
||||
│ └─────────────┘ │
|
||||
│ │
|
||||
│ ┌─────────────────────────┐ │
|
||||
│ │ DatabaseHandler │ │
|
||||
│ │ (TimescaleDB + batch) │ │
|
||||
│ └─────────────────────────┘ │
|
||||
└──────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
## 📁 Project Structure
|
||||
|
||||
```
|
||||
src/
|
||||
├── main.rs # Axum server bootstrap & route composition
|
||||
├── binance_collector.rs # WebSocket real-time collection + REST sync
|
||||
├── historical_downloader.rs # Binance data archive (ZIP) downloader
|
||||
├── database.rs # TimescaleDB operations, batch insert, aggregation
|
||||
├── scheduler.rs # Task coordination & collector lifecycle
|
||||
├── klinechart.rs # KlineChart REST API handlers
|
||||
├── tradingview.rs # TradingView UDF API + WebSocket + Canvas
|
||||
├── structs.rs # Data types (CandleData, Interval, WsMessage…)
|
||||
├── error.rs # Custom error types (CollectorError, SchedulerError)
|
||||
└── lib.rs # Public module exports
|
||||
|
||||
tests/
|
||||
├── connection_test.rs # Database connection tests
|
||||
├── database_test.rs # CRUD & query tests
|
||||
├── scheduler_test.rs # Scheduler command & lifecycle tests
|
||||
├── sync_test.rs # Single symbol sync tests
|
||||
└── sync_full_history_test.rs # Full historical backfill tests
|
||||
|
||||
examples/
|
||||
├── sync_all.rs # Sync all symbols (standard)
|
||||
├── sync_all_fast.rs # Sync all symbols (parallel with proxy pool)
|
||||
└── sql.txt # Reference SQL for TimescaleDB setup
|
||||
```
|
||||
|
||||
## 🚀 Quick Start
|
||||
|
||||
### Prerequisites
|
||||
|
||||
- **Rust** 1.70+ (edition 2021)
|
||||
- **PostgreSQL** with [TimescaleDB](https://docs.timescale.com/) extension
|
||||
- (Recommended) Third-party rotating proxy with multi-port support for parallel downloads
|
||||
|
||||
### Environment Setup
|
||||
|
||||
```bash
|
||||
cp .env.example .env
|
||||
# Edit .env with your values
|
||||
```
|
||||
|
||||
`.env.example`:
|
||||
```env
|
||||
RUST_LOG="INFO,binance_sdk::common::utils=off,binance_sdk::common::websocket=off"
|
||||
DATABASE_URL="postgres://user:password@host:5432/crypto_database"
|
||||
TRACKED_SYMBOL=[BTCUSDT,XRPUSDT,BNBUSDT,SOLUSDT,ETHUSDT]
|
||||
|
||||
# Proxy settings (optional — leave empty for direct connection)
|
||||
PROXY_HOST=dc.your-proxy-provider.com
|
||||
PROXY_USERNAME=your_username
|
||||
PROXY_PASSWORD=your_password
|
||||
PROXY_PROTOCOL=https
|
||||
PROXY_PORT_START=10000
|
||||
PROXY_PORT_END=10099
|
||||
```
|
||||
|
||||
> [!WARNING]
|
||||
> **Proxy is strongly recommended.** The backend downloads historical data from [Binance Data Archive](https://data.binance.vision/) for all tracked symbols. With a multi-port proxy pool (e.g. 100 concurrent connections), a full sync completes in minutes. **Without a proxy, syncing may take several days** due to single-connection rate limits. If `PROXY_HOST` is left empty, the backend falls back to a single direct connection.
|
||||
|
||||
### Run
|
||||
|
||||
```bash
|
||||
# Development
|
||||
cargo run
|
||||
|
||||
# Release build
|
||||
cargo build --release
|
||||
./target/release/backend
|
||||
|
||||
# Run tests
|
||||
cargo test
|
||||
```
|
||||
|
||||
### Docker
|
||||
|
||||
```bash
|
||||
# Build image
|
||||
docker build -t backend .
|
||||
|
||||
# Using docker-compose (connects to existing `cycle` network)
|
||||
docker compose up -d
|
||||
```
|
||||
|
||||
## 📡 API Reference
|
||||
|
||||
### KlineChart API
|
||||
|
||||
| Method | Endpoint | Description |
|
||||
|--------|----------|-------------|
|
||||
| **GET** | `/api/klines/{symbol}` | Query K-line data |
|
||||
| **GET** | `/api/symbols` | List all tracked symbols |
|
||||
| **POST** | `/api/symbols` | Add symbol to tracking (triggers backfill) |
|
||||
| **DELETE** | `/api/symbols/{symbol}` | Remove symbol from tracking |
|
||||
| **GET** | `/api/status` | Get scheduler status |
|
||||
|
||||
**Query Parameters** for `/api/klines/{symbol}`:
|
||||
|
||||
| Param | Type | Default | Description |
|
||||
|-------|------|---------|-------------|
|
||||
| `limit` | `i64` | `800` | Number of candles to return |
|
||||
| `interval` | `string` | `1m` | Timeframe: `1m`, `5m`, `15m`, `1h`, `4h`, `1d`, `1w`, `1M` |
|
||||
| `end_time` | `i64` | *now* | Unix timestamp (ms) upper bound |
|
||||
|
||||
<details>
|
||||
<summary>📄 Response Example</summary>
|
||||
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"data": [
|
||||
{
|
||||
"symbol": "BTCUSDT",
|
||||
"timestamp": 1704067200000,
|
||||
"open": 42000.0,
|
||||
"high": 42100.0,
|
||||
"low": 41900.0,
|
||||
"close": 42050.0,
|
||||
"volume": 1000.5,
|
||||
"taker_buy_volume": 600.3,
|
||||
"net_volume": 200.1,
|
||||
"is_closed": true
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
---
|
||||
|
||||
### TradingView UDF API
|
||||
|
||||
Fully compatible with the [TradingView UDF Datafeed API](https://www.tradingview.com/charting-library-docs/latest/connecting_data/UDF/).
|
||||
|
||||
| Method | Endpoint | Description |
|
||||
|--------|----------|-------------|
|
||||
| **GET** | `/config` | Datafeed configuration |
|
||||
| **GET** | `/time` | Server time (seconds) |
|
||||
| **GET** | `/symbols` | Resolve symbol info |
|
||||
| **GET** | `/search` | Search symbols |
|
||||
| **GET** | `/history` | Historical OHLCV data (includes `nv` and `tbv`) |
|
||||
| **GET** | `/tracked-symbols` | List configured symbols |
|
||||
| **GET** | `/daily-opens` | Daily open prices for all symbols |
|
||||
| **WS** | `/ws` | Real-time K-line push via WebSocket |
|
||||
|
||||
<details>
|
||||
<summary>📄 History Response Example</summary>
|
||||
|
||||
```json
|
||||
{
|
||||
"s": "ok",
|
||||
"t": [1704067200, 1704153600],
|
||||
"o": [42000.0, 42050.0],
|
||||
"h": [42100.0, 42200.0],
|
||||
"l": [41900.0, 41950.0],
|
||||
"c": [42050.0, 42150.0],
|
||||
"v": [1000.5, 1200.3],
|
||||
"nv": [200.1, -150.5],
|
||||
"tbv": [600.3, 525.4]
|
||||
}
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary>📄 WebSocket Protocol</summary>
|
||||
|
||||
**Subscribe:**
|
||||
```json
|
||||
{ "type": "subscribe", "data": { "symbols": ["BTCUSDT", "ETHUSDT"] } }
|
||||
```
|
||||
|
||||
**Kline Update (server → client):**
|
||||
```json
|
||||
{ "type": "kline", "data": { "symbol": "BTCUSDT", "timestamp": 1704067200000, "open": 42000.0, "high": 42100.0, "low": 41900.0, "close": 42050.0, "volume": 1000.5, "taker_buy_volume": 600.3, "net_volume": 200.1, "is_closed": false } }
|
||||
```
|
||||
|
||||
**Keepalive:** `ping` / `pong`
|
||||
|
||||
</details>
|
||||
|
||||
---
|
||||
|
||||
### Canvas API (Drawing Persistence)
|
||||
|
||||
Save and load chart drawings per symbol to the local filesystem.
|
||||
|
||||
| Method | Endpoint | Description |
|
||||
|--------|----------|-------------|
|
||||
| **GET** | `/canvas/list` | List saved canvases for a symbol |
|
||||
| **GET** | `/canvas/load` | Load canvas drawings |
|
||||
| **POST** | `/canvas/save` | Save canvas drawings |
|
||||
| **DELETE** | `/canvas/delete` | Delete a canvas |
|
||||
|
||||
## ⚙️ Core Components
|
||||
|
||||
### BinanceCollector
|
||||
- Connects to Binance WebSocket combined streams for real-time 1m K-line data
|
||||
- Supports up to **50 symbols per connection** (Binance limit); auto-splits into multiple connections
|
||||
- **Auto-reconnect** with gap detection — backfills missed data on disconnect
|
||||
- REST API sync with rate limiting (150ms interval, ~480 req/min)
|
||||
|
||||
### HistoricalDownloader
|
||||
- **3-tier download strategy**: Monthly ZIP → Daily ZIP → REST API (fastest to slowest)
|
||||
- Downloads from [Binance Data Archive](https://data.binance.vision/) for bulk historical data
|
||||
- Concurrent downloads across proxy pool for maximum throughput
|
||||
- CSV parsing from ZIP archives
|
||||
|
||||
### DatabaseHandler
|
||||
- **TimescaleDB** hypertable for time-series optimization
|
||||
- **Batch insert**: 100 candles or 5-second flush timeout
|
||||
- `time_bucket` aggregation for multi-timeframe queries (1m → 1M)
|
||||
- Gap detection and data integrity checks
|
||||
- Data cutoff: only syncs data from **2024-01-01 UTC** onwards
|
||||
|
||||
### Scheduler
|
||||
- Command-based control via `mpsc` channels:
|
||||
- `AddSymbol` — backfill + restart collector
|
||||
- `RemoveSymbol` — deactivate + restart collector
|
||||
- `RestartCollector` / `GetStatus` / `Shutdown`
|
||||
- Manages full lifecycle: symbol tracking → historical backfill → real-time streaming
|
||||
|
||||
## 📦 Dependencies
|
||||
|
||||
| Crate | Purpose |
|
||||
|-------|---------|
|
||||
| `axum` | Web framework with WebSocket support |
|
||||
| `sqlx` | Async PostgreSQL / TimescaleDB driver |
|
||||
| `tokio` | Async runtime |
|
||||
| `binance-sdk` | Official Binance connector (USDS futures + spot) |
|
||||
| `tokio-tungstenite` | WebSocket client for Binance streams |
|
||||
| `reqwest` | HTTP client for REST API & archive downloads |
|
||||
| `tower-http` | CORS middleware |
|
||||
| `serde` / `serde_json` | Serialization |
|
||||
| `chrono` | Date/time handling |
|
||||
| `csv` / `zip` | Historical data archive parsing |
|
||||
| `thiserror` | Custom error types |
|
||||
| `env_logger` | Logging |
|
||||
|
||||
## 📜 License
|
||||
|
||||
MIT
|
||||
|
||||
|
||||
Generated By Claude Opus 4.6
|
||||
@@ -0,0 +1,17 @@
|
||||
services:
|
||||
backend:
|
||||
image: ghcr.io/exchanges-lab/statistic/backend:v1.2
|
||||
container_name: backend
|
||||
networks:
|
||||
- cycle
|
||||
#ports:
|
||||
# - "3000:3000"
|
||||
env_file:
|
||||
- .env
|
||||
volumes:
|
||||
- ./storage:/storage
|
||||
restart: unless-stopped
|
||||
|
||||
networks:
|
||||
cycle:
|
||||
external: true
|
||||
@@ -0,0 +1,47 @@
|
||||
-- Create klines table for 1-minute candlestick data
|
||||
CREATE TABLE IF NOT EXISTS klines_1m (
|
||||
symbol VARCHAR(20) NOT NULL,
|
||||
timestamp BIGINT NOT NULL,
|
||||
open DOUBLE PRECISION NOT NULL,
|
||||
high DOUBLE PRECISION NOT NULL,
|
||||
low DOUBLE PRECISION NOT NULL,
|
||||
close DOUBLE PRECISION NOT NULL,
|
||||
volume DOUBLE PRECISION NOT NULL,
|
||||
taker_buy_volume DOUBLE PRECISION NOT NULL,
|
||||
net_volume DOUBLE PRECISION NOT NULL,
|
||||
PRIMARY KEY (symbol, timestamp)
|
||||
);
|
||||
|
||||
-- Convert to TimescaleDB hypertable for better time-series performance
|
||||
-- chunk_time_interval = 7 days (in milliseconds: 7 * 24 * 60 * 60 * 1000 = 604800000)
|
||||
SELECT create_hypertable('klines_1m', 'timestamp',
|
||||
chunk_time_interval => 604800000,
|
||||
if_not_exists => TRUE
|
||||
);
|
||||
|
||||
-- Create index for faster queries by symbol
|
||||
CREATE INDEX IF NOT EXISTS idx_klines_1m_symbol ON klines_1m (symbol, timestamp DESC);
|
||||
|
||||
-- Table for tracking active symbols
|
||||
CREATE TABLE IF NOT EXISTS tracked_symbols (
|
||||
symbol VARCHAR(20) PRIMARY KEY,
|
||||
added_at TIMESTAMP DEFAULT NOW(),
|
||||
is_active BOOLEAN DEFAULT TRUE
|
||||
);
|
||||
|
||||
-- Insert some default symbols
|
||||
INSERT INTO tracked_symbols (symbol) VALUES
|
||||
('btcusdt'),
|
||||
('ethusdt')
|
||||
ON CONFLICT (symbol) DO NOTHING;
|
||||
|
||||
-- Useful queries:
|
||||
|
||||
-- Get latest timestamp for a symbol
|
||||
-- SELECT MAX(timestamp) FROM klines_1m WHERE symbol = 'BTCUSDT';
|
||||
|
||||
-- Get latest N candles for a symbol
|
||||
-- SELECT * FROM klines_1m WHERE symbol = 'BTCUSDT' ORDER BY timestamp DESC LIMIT 100;
|
||||
|
||||
-- Get all active symbols
|
||||
-- SELECT symbol FROM tracked_symbols WHERE is_active = TRUE;
|
||||
@@ -0,0 +1,137 @@
|
||||
use backend::{BinanceCollector, CandleData, DatabaseHandler};
|
||||
|
||||
use log::{info, error};
|
||||
use dotenv::dotenv;
|
||||
use tokio::sync::mpsc;
|
||||
use std::sync::Arc;
|
||||
use std::sync::atomic::{AtomicU64, Ordering};
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() {
|
||||
dotenv().ok();
|
||||
env_logger::init();
|
||||
|
||||
// 1. Connect to database
|
||||
let database_url = std::env::var("DATABASE_URL")
|
||||
.expect("DATABASE_URL must be set");
|
||||
|
||||
info!("Connecting to database...");
|
||||
let db = Arc::new(
|
||||
DatabaseHandler::new(&database_url)
|
||||
.await
|
||||
.expect("Failed to connect to database")
|
||||
);
|
||||
|
||||
// 2. Get all symbols (filter USDT pairs only)
|
||||
info!("Fetching all symbols from Binance...");
|
||||
let all_symbols = BinanceCollector::get_symbol().await.unwrap();
|
||||
let symbols: Vec<_> = all_symbols
|
||||
.into_iter()
|
||||
.filter(|s| s.symbol.ends_with("USDT"))
|
||||
.collect();
|
||||
info!("Got {} USDT symbols to sync", symbols.len());
|
||||
|
||||
// 3. Build clients
|
||||
info!("Building clients...");
|
||||
let clients = BinanceCollector::build_clients().await;
|
||||
info!("Built {} working clients", clients.len());
|
||||
|
||||
if clients.is_empty() {
|
||||
error!("No working clients, exiting");
|
||||
return;
|
||||
}
|
||||
|
||||
// 4. Sync each symbol one by one
|
||||
let total_symbols = symbols.len();
|
||||
|
||||
for (i, symbol) in symbols.into_iter().enumerate() {
|
||||
let now = std::time::SystemTime::now()
|
||||
.duration_since(std::time::UNIX_EPOCH)
|
||||
.unwrap()
|
||||
.as_millis() as i64;
|
||||
|
||||
let start_time = symbol.start_timestamp;
|
||||
let total_range_ms = now - start_time;
|
||||
// Estimate total candles (1 candle per minute)
|
||||
let estimated_total = (total_range_ms / 60000) as u64;
|
||||
|
||||
info!("[{}/{}] Starting sync for {} (estimated {} candles)",
|
||||
i + 1, total_symbols, symbol.symbol, estimated_total);
|
||||
|
||||
// Create channels
|
||||
let (tx, rx) = mpsc::channel::<CandleData>(100000);
|
||||
let (db_tx, db_rx) = mpsc::channel::<CandleData>(100000);
|
||||
|
||||
// Progress tracking
|
||||
let candle_count = Arc::new(AtomicU64::new(0));
|
||||
let last_progress = Arc::new(AtomicU64::new(0));
|
||||
|
||||
// Progress monitor and forward task
|
||||
let symbol_name = symbol.symbol.clone();
|
||||
let candle_count_clone = candle_count.clone();
|
||||
let last_progress_clone = last_progress.clone();
|
||||
let idx = i + 1;
|
||||
|
||||
let progress_handle = tokio::spawn(async move {
|
||||
let mut rx = rx;
|
||||
while let Some(candle) = rx.recv().await {
|
||||
let count = candle_count_clone.fetch_add(1, Ordering::Relaxed) + 1;
|
||||
|
||||
// Calculate progress based on received candles vs estimated total
|
||||
let progress = if estimated_total > 0 {
|
||||
((count as f64 / estimated_total as f64) * 100.0).min(100.0) as u64
|
||||
} else {
|
||||
100
|
||||
};
|
||||
|
||||
// Report every 20%
|
||||
let last = last_progress_clone.load(Ordering::Relaxed);
|
||||
let milestone = (progress / 20) * 20;
|
||||
if milestone > last && milestone <= 100 {
|
||||
if last_progress_clone.compare_exchange(
|
||||
last, milestone, Ordering::Relaxed, Ordering::Relaxed
|
||||
).is_ok() {
|
||||
info!("[{}/{}] {} progress: {}% ({}/{} candles)",
|
||||
idx, total_symbols, symbol_name, milestone, count, estimated_total);
|
||||
}
|
||||
}
|
||||
|
||||
// Forward to database
|
||||
let _ = db_tx.send(candle).await;
|
||||
}
|
||||
});
|
||||
|
||||
// Database consumer
|
||||
let db_clone = db.clone();
|
||||
let consumer_handle = tokio::spawn(async move {
|
||||
db_clone.start_consumer(db_rx).await;
|
||||
});
|
||||
|
||||
// Sync this symbol
|
||||
let result = BinanceCollector::sync_from_scratch(
|
||||
symbol.symbol.clone(),
|
||||
symbol.start_timestamp,
|
||||
clients.clone(),
|
||||
tx,
|
||||
).await;
|
||||
|
||||
// Wait for tasks to finish
|
||||
let _ = progress_handle.await;
|
||||
let _ = consumer_handle.await;
|
||||
|
||||
let final_count = candle_count.load(Ordering::Relaxed);
|
||||
|
||||
match result {
|
||||
Ok(count) => {
|
||||
info!("[{}/{}] {} completed: {} candles",
|
||||
i + 1, total_symbols, symbol.symbol, count);
|
||||
}
|
||||
Err(e) => {
|
||||
error!("[{}/{}] {} failed: {} (received: {} candles)",
|
||||
i + 1, total_symbols, symbol.symbol, e, final_count);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
info!("All symbols synced!");
|
||||
}
|
||||
@@ -0,0 +1,162 @@
|
||||
use backend::{BinanceCollector, CandleData, DatabaseHandler, HistoricalDownloader};
|
||||
|
||||
use log::{info, error};
|
||||
use dotenv::dotenv;
|
||||
use tokio::sync::mpsc;
|
||||
use std::sync::Arc;
|
||||
use std::sync::atomic::{AtomicU64, Ordering};
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() {
|
||||
dotenv().ok();
|
||||
env_logger::init();
|
||||
|
||||
// 1. Connect to database
|
||||
let database_url = std::env::var("DATABASE_URL")
|
||||
.expect("DATABASE_URL must be set");
|
||||
|
||||
info!("Connecting to database...");
|
||||
let db = Arc::new(
|
||||
DatabaseHandler::new(&database_url)
|
||||
.await
|
||||
.expect("Failed to connect to database")
|
||||
);
|
||||
|
||||
// 2. Get all USDT symbols
|
||||
info!("Fetching all symbols from Binance...");
|
||||
let all_symbols = BinanceCollector::get_symbol().await.unwrap();
|
||||
let symbols: Vec<_> = all_symbols
|
||||
.into_iter()
|
||||
.filter(|s| s.symbol.ends_with("USDT"))
|
||||
.collect();
|
||||
info!("Got {} USDT symbols to sync", symbols.len());
|
||||
|
||||
// 3. Build clients
|
||||
info!("Building download clients (with proxies)...");
|
||||
let download_clients = HistoricalDownloader::build_clients().await;
|
||||
|
||||
info!("Building API clients (for recent data)...");
|
||||
let api_clients = BinanceCollector::build_clients().await;
|
||||
info!("Built {} download clients, {} API clients", download_clients.len(), api_clients.len());
|
||||
|
||||
// Get last complete month timestamp
|
||||
let archive_end = HistoricalDownloader::last_complete_month_end();
|
||||
info!("Archive data available until: {}", archive_end);
|
||||
|
||||
// Use the global cutoff timestamp
|
||||
info!("Data cutoff: 2024-01-01 00:00:00 UTC (timestamp: {})", backend::DATA_CUTOFF_TIMESTAMP);
|
||||
|
||||
// 4. Sync each symbol
|
||||
let total_symbols = symbols.len();
|
||||
|
||||
for (i, symbol) in symbols.into_iter().enumerate() {
|
||||
info!("========================================");
|
||||
info!("[{}/{}] {} - Starting fast sync", i + 1, total_symbols, symbol.symbol);
|
||||
|
||||
// Check if we have data already
|
||||
let latest_ts = db.get_latest_timestamp(&symbol.symbol).await.ok().flatten();
|
||||
|
||||
let start_time = match latest_ts {
|
||||
Some(ts) => {
|
||||
info!("[{}/{}] {} - Has data until {}, continuing from there",
|
||||
i + 1, total_symbols, symbol.symbol, ts);
|
||||
ts + 60000
|
||||
}
|
||||
None => {
|
||||
// No existing data, use the later of symbol start or cutoff
|
||||
let actual_start = symbol.start_timestamp.max(backend::DATA_CUTOFF_TIMESTAMP);
|
||||
if symbol.start_timestamp < backend::DATA_CUTOFF_TIMESTAMP {
|
||||
info!("[{}/{}] {} - Original start is before 2024-01-01, starting from cutoff instead",
|
||||
i + 1, total_symbols, symbol.symbol);
|
||||
}
|
||||
actual_start
|
||||
}
|
||||
};
|
||||
|
||||
// Create channels
|
||||
let (tx, rx) = mpsc::channel::<CandleData>(500000);
|
||||
let (db_tx, db_rx) = mpsc::channel::<CandleData>(500000);
|
||||
|
||||
// Progress tracking
|
||||
let candle_count = Arc::new(AtomicU64::new(0));
|
||||
let candle_count_clone = candle_count.clone();
|
||||
let symbol_name = symbol.symbol.clone();
|
||||
let idx = i + 1;
|
||||
|
||||
// Progress forwarder
|
||||
let progress_handle = tokio::spawn(async move {
|
||||
let mut rx = rx;
|
||||
let mut last_report = 0u64;
|
||||
|
||||
while let Some(candle) = rx.recv().await {
|
||||
let count = candle_count_clone.fetch_add(1, Ordering::Relaxed) + 1;
|
||||
|
||||
if count - last_report >= 500000 {
|
||||
info!("[{}/{}] {} - Progress: {} candles", idx, total_symbols, symbol_name, count);
|
||||
last_report = count;
|
||||
}
|
||||
|
||||
let _ = db_tx.send(candle).await;
|
||||
}
|
||||
});
|
||||
|
||||
// DB consumer (batch insert)
|
||||
let db_clone = db.clone();
|
||||
let consumer_handle = tokio::spawn(async move {
|
||||
db_clone.start_consumer(db_rx).await;
|
||||
});
|
||||
|
||||
// STEP 1: Download historical data from archive (with proxies)
|
||||
if start_time < archive_end && !download_clients.is_empty() {
|
||||
info!("[{}/{}] {} - Downloading from archive with {} proxies...",
|
||||
i + 1, total_symbols, symbol.symbol, download_clients.len());
|
||||
|
||||
match HistoricalDownloader::download_symbol_with_clients(
|
||||
&symbol.symbol,
|
||||
start_time,
|
||||
&download_clients,
|
||||
tx.clone(),
|
||||
).await {
|
||||
Ok(count) => info!("[{}/{}] {} - Archive download: {} candles",
|
||||
i + 1, total_symbols, symbol.symbol, count),
|
||||
Err(e) => error!("[{}/{}] {} - Archive download failed: {}",
|
||||
i + 1, total_symbols, symbol.symbol, e),
|
||||
}
|
||||
}
|
||||
|
||||
// STEP 2: Sync recent data via API
|
||||
let api_start = archive_end.max(start_time);
|
||||
let now = std::time::SystemTime::now()
|
||||
.duration_since(std::time::UNIX_EPOCH)
|
||||
.unwrap()
|
||||
.as_millis() as i64;
|
||||
|
||||
if now - api_start > 60000 && !api_clients.is_empty() {
|
||||
info!("[{}/{}] {} - Syncing recent data via API...", i + 1, total_symbols, symbol.symbol);
|
||||
|
||||
match BinanceCollector::sync_from_scratch(
|
||||
symbol.symbol.clone(),
|
||||
api_start,
|
||||
api_clients.clone(),
|
||||
tx.clone(),
|
||||
).await {
|
||||
Ok(count) => info!("[{}/{}] {} - API sync: {} candles",
|
||||
i + 1, total_symbols, symbol.symbol, count),
|
||||
Err(e) => error!("[{}/{}] {} - API sync failed: {}",
|
||||
i + 1, total_symbols, symbol.symbol, e),
|
||||
}
|
||||
}
|
||||
|
||||
// Close channel and wait
|
||||
drop(tx);
|
||||
let _ = progress_handle.await;
|
||||
let _ = consumer_handle.await;
|
||||
|
||||
let final_count = candle_count.load(Ordering::Relaxed);
|
||||
info!("[{}/{}] {} - Complete: {} total candles",
|
||||
i + 1, total_symbols, symbol.symbol, final_count);
|
||||
}
|
||||
|
||||
info!("========================================");
|
||||
info!("All symbols synced!");
|
||||
}
|
||||
@@ -0,0 +1,709 @@
|
||||
use crate::error::*;
|
||||
use crate::structs::*;
|
||||
use crate::historical_downloader::HistoricalDownloader;
|
||||
|
||||
use binance_sdk::{
|
||||
config::{ConfigurationRestApi, ProxyConfig, ProxyAuth},
|
||||
derivatives_trading_usds_futures::{
|
||||
DerivativesTradingUsdsFuturesRestApi,
|
||||
rest_api::{
|
||||
RestApi,
|
||||
KlineCandlestickDataIntervalEnum, KlineCandlestickDataParams, KlineCandlestickDataResponseItemInner,
|
||||
},
|
||||
websocket_streams::KlineCandlestickStreamsResponseK,
|
||||
},
|
||||
};
|
||||
|
||||
use futures::StreamExt;
|
||||
use log::{debug, error, info, warn};
|
||||
use std::collections::HashMap;
|
||||
use std::sync::Arc;
|
||||
use tokio::sync::{mpsc, RwLock};
|
||||
use reqwest::Client;
|
||||
use tokio_tungstenite::{connect_async, tungstenite::Message};
|
||||
use rand::Rng;
|
||||
use serde::Deserialize;
|
||||
|
||||
/// Read proxy configuration from environment variables.
|
||||
/// Returns None if PROXY_HOST is not set (direct connection).
|
||||
fn proxy_config_from_env(port: u16) -> Option<ProxyConfig> {
|
||||
let host = std::env::var("PROXY_HOST").ok()?;
|
||||
if host.is_empty() {
|
||||
return None;
|
||||
}
|
||||
let username = std::env::var("PROXY_USERNAME").unwrap_or_default();
|
||||
let password = std::env::var("PROXY_PASSWORD").unwrap_or_default();
|
||||
let protocol = std::env::var("PROXY_PROTOCOL").unwrap_or_else(|_| "https".to_string());
|
||||
|
||||
let auth = if username.is_empty() {
|
||||
None
|
||||
} else {
|
||||
Some(ProxyAuth {
|
||||
username,
|
||||
password,
|
||||
})
|
||||
};
|
||||
|
||||
Some(ProxyConfig {
|
||||
host,
|
||||
port,
|
||||
protocol: Some(protocol),
|
||||
auth,
|
||||
})
|
||||
}
|
||||
|
||||
// Combined stream response wrapper
|
||||
#[derive(Debug, Deserialize)]
|
||||
struct CombinedStreamWrapper {
|
||||
#[allow(dead_code)]
|
||||
stream: String,
|
||||
data: CombinedStreamData,
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
struct CombinedStreamData {
|
||||
s: Option<String>,
|
||||
k: Option<KlineCandlestickStreamsResponseK>,
|
||||
}
|
||||
|
||||
const BATCH_SIZE: i64 = 1000;
|
||||
const ONE_MINUTE_MS: i64 = 60_000;
|
||||
const MAX_SYMBOLS_PER_WS: usize = 50; // Binance limit per WebSocket connection
|
||||
// Rate limit: 2400 weight/min, limit=1000 costs 5 weight
|
||||
// 2400/5 = 480 requests/min = 8 req/sec = 125ms interval
|
||||
// Use 150ms for safety margin
|
||||
const REQUEST_INTERVAL_MS: u64 = 150;
|
||||
|
||||
pub struct BinanceCollector {
|
||||
pub symbols: Vec<String>,
|
||||
rest_client: RestApi,
|
||||
last_closed_timestamps: Arc<RwLock<HashMap<String, i64>>>,
|
||||
}
|
||||
|
||||
impl BinanceCollector {
|
||||
pub fn new(symbols: Vec<String>) -> Self {
|
||||
assert!(!symbols.is_empty(), "symbols cannot be empty");
|
||||
|
||||
let symbols: Vec<String> = symbols.into_iter().map(|s| s.to_lowercase()).collect();
|
||||
|
||||
let port: u16 = rand::rng().random_range(10036..=10066);
|
||||
|
||||
let mut config_builder = ConfigurationRestApi::builder()
|
||||
.timeout(10000);
|
||||
|
||||
if let Some(proxy) = proxy_config_from_env(port) {
|
||||
config_builder = config_builder.proxy(proxy);
|
||||
}
|
||||
|
||||
let rest_client_config = config_builder
|
||||
.build()
|
||||
.expect("Failed to initialize the rest api client");
|
||||
|
||||
let rest_client = DerivativesTradingUsdsFuturesRestApi::production(rest_client_config);
|
||||
|
||||
Self {
|
||||
symbols,
|
||||
rest_client,
|
||||
last_closed_timestamps: Arc::new(RwLock::new(HashMap::new())),
|
||||
}
|
||||
}
|
||||
|
||||
/// Backfill K-line data for a specific symbol from start_time to end_time.
|
||||
/// Uses limit=1000 per request (weight=5, ~480 requests/min allowed).
|
||||
/// Returns total number of candles fetched.
|
||||
pub async fn backfill(
|
||||
&self,
|
||||
symbol: &str,
|
||||
start_time: i64,
|
||||
end_time: i64,
|
||||
candle_tx: &mpsc::Sender<CandleData>,
|
||||
) -> Result<u64, CollectorError> {
|
||||
let symbol_upper = symbol.to_uppercase();
|
||||
let symbol_lower = symbol.to_lowercase();
|
||||
let mut current_start = start_time;
|
||||
let mut total_count: u64 = 0;
|
||||
|
||||
info!(
|
||||
"Starting backfill for {} from {} to {}",
|
||||
symbol_upper, start_time, end_time
|
||||
);
|
||||
|
||||
while current_start < end_time {
|
||||
let params = KlineCandlestickDataParams::builder(
|
||||
symbol_upper.clone(),
|
||||
KlineCandlestickDataIntervalEnum::Interval1m,
|
||||
)
|
||||
.start_time(Some(current_start))
|
||||
.end_time(Some(end_time))
|
||||
.limit(Some(BATCH_SIZE))
|
||||
.build()
|
||||
.map_err(|e| CollectorError::RestApiError(e.to_string()))?;
|
||||
|
||||
let response = self.rest_client
|
||||
.kline_candlestick_data(params)
|
||||
.await
|
||||
.map_err(|e| CollectorError::RestApiError(e.to_string()))?;
|
||||
|
||||
let klines = response.data().await
|
||||
.map_err(|e| CollectorError::RestApiError(e.to_string()))?;
|
||||
|
||||
let batch_count = klines.len();
|
||||
if batch_count == 0 {
|
||||
break;
|
||||
}
|
||||
|
||||
let mut last_timestamp = current_start;
|
||||
|
||||
for kline in &klines {
|
||||
if let Some(candle) = Self::parse_rest_kline(&symbol_upper, kline) {
|
||||
last_timestamp = candle.timestamp;
|
||||
|
||||
if let Err(e) = candle_tx.send(candle).await {
|
||||
warn!("Failed to send candle: {}", e);
|
||||
}
|
||||
|
||||
total_count += 1;
|
||||
}
|
||||
}
|
||||
|
||||
// Update last_closed_timestamp for this symbol
|
||||
{
|
||||
let mut timestamps = self.last_closed_timestamps.write().await;
|
||||
timestamps.insert(symbol_lower.clone(), last_timestamp);
|
||||
}
|
||||
|
||||
debug!(
|
||||
"Fetched {} klines for {}, total: {}, last_ts: {}",
|
||||
batch_count, symbol_upper, total_count, last_timestamp
|
||||
);
|
||||
|
||||
current_start = last_timestamp + ONE_MINUTE_MS;
|
||||
|
||||
if batch_count < BATCH_SIZE as usize {
|
||||
break;
|
||||
}
|
||||
|
||||
tokio::time::sleep(tokio::time::Duration::from_millis(REQUEST_INTERVAL_MS)).await;
|
||||
}
|
||||
|
||||
info!(
|
||||
"Backfill completed for {}: {} candles",
|
||||
symbol_upper, total_count
|
||||
);
|
||||
|
||||
Ok(total_count)
|
||||
}
|
||||
|
||||
/// Backfill all symbols in the collector.
|
||||
pub async fn backfill_all(
|
||||
&self,
|
||||
start_time: i64,
|
||||
end_time: i64,
|
||||
candle_tx: &mpsc::Sender<CandleData>,
|
||||
) -> Result<u64, CollectorError> {
|
||||
let mut total_count: u64 = 0;
|
||||
|
||||
for symbol in &self.symbols.clone() {
|
||||
let count = self.backfill(symbol, start_time, end_time, candle_tx).await?;
|
||||
total_count += count;
|
||||
}
|
||||
|
||||
Ok(total_count)
|
||||
}
|
||||
|
||||
/// Start WebSocket streams for real-time K-line data on all symbols.
|
||||
/// Creates multiple connections if symbols > MAX_SYMBOLS_PER_WS.
|
||||
/// Automatically reconnects and backfills missed data on disconnect.
|
||||
pub async fn start_stream(
|
||||
&self,
|
||||
candle_tx: mpsc::Sender<CandleData>,
|
||||
) -> Result<(), CollectorError> {
|
||||
let total_symbols = self.symbols.len();
|
||||
let num_connections = (total_symbols + MAX_SYMBOLS_PER_WS - 1) / MAX_SYMBOLS_PER_WS;
|
||||
|
||||
info!(
|
||||
"Starting {} WebSocket connections for {} symbols",
|
||||
num_connections, total_symbols
|
||||
);
|
||||
|
||||
// Split symbols into batches
|
||||
let batches: Vec<Vec<String>> = self.symbols
|
||||
.chunks(MAX_SYMBOLS_PER_WS)
|
||||
.map(|chunk| chunk.to_vec())
|
||||
.collect();
|
||||
|
||||
loop {
|
||||
// Start all WebSocket connections in parallel
|
||||
let mut handles = Vec::new();
|
||||
|
||||
for (i, batch) in batches.iter().enumerate() {
|
||||
let batch_symbols = batch.clone();
|
||||
let tx = candle_tx.clone();
|
||||
let last_ts = self.last_closed_timestamps.clone();
|
||||
|
||||
let handle = tokio::spawn(async move {
|
||||
Self::run_single_ws_connection(i, batch_symbols, tx, last_ts).await
|
||||
});
|
||||
handles.push(handle);
|
||||
}
|
||||
|
||||
// Wait for any connection to fail
|
||||
let mut all_ok = true;
|
||||
for (i, handle) in handles.into_iter().enumerate() {
|
||||
match handle.await {
|
||||
Ok(Ok(())) => info!("WS connection {} ended normally", i),
|
||||
Ok(Err(e)) => {
|
||||
error!("WS connection {} error: {}", i, e);
|
||||
all_ok = false;
|
||||
}
|
||||
Err(e) => {
|
||||
error!("WS connection {} join error: {}", i, e);
|
||||
all_ok = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if all_ok {
|
||||
break;
|
||||
}
|
||||
|
||||
// Reconnect after error
|
||||
error!("WebSocket error. Reconnecting in 5 seconds...");
|
||||
tokio::time::sleep(tokio::time::Duration::from_secs(5)).await;
|
||||
|
||||
// Backfill missed data
|
||||
let now = std::time::SystemTime::now()
|
||||
.duration_since(std::time::UNIX_EPOCH)
|
||||
.unwrap()
|
||||
.as_millis() as i64;
|
||||
|
||||
let timestamps = self.last_closed_timestamps.read().await.clone();
|
||||
|
||||
for symbol in &self.symbols {
|
||||
if let Some(&last_ts) = timestamps.get(symbol) {
|
||||
if now - last_ts > ONE_MINUTE_MS {
|
||||
info!("Backfilling missed data for {} from {}", symbol, last_ts);
|
||||
if let Err(e) = self.backfill(symbol, last_ts, now, &candle_tx).await {
|
||||
warn!("Backfill failed for {}: {}", symbol, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Run a single WebSocket connection for a batch of symbols (combined streams)
|
||||
async fn run_single_ws_connection(
|
||||
connection_id: usize,
|
||||
symbols: Vec<String>,
|
||||
candle_tx: mpsc::Sender<CandleData>,
|
||||
last_closed_timestamps: Arc<RwLock<HashMap<String, i64>>>,
|
||||
) -> Result<(), CollectorError> {
|
||||
// Build combined stream URL: wss://fstream.binance.com/stream?streams=symbol1@kline_1m/symbol2@kline_1m
|
||||
let streams: Vec<String> = symbols.iter()
|
||||
.map(|s| format!("{}@kline_1m", s.to_lowercase()))
|
||||
.collect();
|
||||
let url = format!("wss://fstream.binance.com/stream?streams={}", streams.join("/"));
|
||||
|
||||
let (ws_stream, _) = connect_async(&url)
|
||||
.await
|
||||
.map_err(|e| CollectorError::ConnectionFailed(e.to_string()))?;
|
||||
|
||||
info!("WS {} connected with {} symbols (combined stream)", connection_id, symbols.len());
|
||||
|
||||
let (_, mut read) = ws_stream.split();
|
||||
|
||||
// Process incoming messages
|
||||
while let Some(msg_result) = read.next().await {
|
||||
match msg_result {
|
||||
Ok(Message::Text(text)) => {
|
||||
// Combined stream format: {"stream":"btcusdt@kline_1m","data":{...}}
|
||||
if let Ok(wrapper) = serde_json::from_str::<CombinedStreamWrapper>(&text) {
|
||||
if let Some(k) = wrapper.data.k {
|
||||
let symbol = wrapper.data.s.unwrap_or_default();
|
||||
let candle = Self::parse_ws_kline(&symbol, &k);
|
||||
|
||||
if let Err(e) = candle_tx.send(candle.clone()).await {
|
||||
warn!("Failed to send candle: {}", e);
|
||||
}
|
||||
|
||||
if candle.is_closed {
|
||||
let mut timestamps = last_closed_timestamps.write().await;
|
||||
timestamps.insert(candle.symbol.to_lowercase(), candle.timestamp);
|
||||
|
||||
debug!(
|
||||
"Kline closed: {} ts={} c={:.2} net_vol={:.4}",
|
||||
candle.symbol, candle.timestamp, candle.close, candle.net_volume
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(Message::Ping(data)) => {
|
||||
debug!("WS {} received ping", connection_id);
|
||||
// tungstenite auto-responds to pings
|
||||
let _ = data;
|
||||
}
|
||||
Ok(Message::Close(_)) => {
|
||||
info!("WS {} received close", connection_id);
|
||||
break;
|
||||
}
|
||||
Ok(_) => {}
|
||||
Err(e) => {
|
||||
error!("WS {} error: {}", connection_id, e);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Err(CollectorError::ConnectionFailed("Disconnected".to_string()))
|
||||
}
|
||||
|
||||
fn parse_rest_kline(symbol: &str, kline: &Vec<KlineCandlestickDataResponseItemInner>) -> Option<CandleData> {
|
||||
if kline.len() < 12 {
|
||||
return None;
|
||||
}
|
||||
|
||||
let timestamp = match &kline[0] {
|
||||
KlineCandlestickDataResponseItemInner::Integer(v) => *v,
|
||||
_ => return None,
|
||||
};
|
||||
|
||||
let open = Self::parse_string_field(&kline[1])?;
|
||||
let high = Self::parse_string_field(&kline[2])?;
|
||||
let low = Self::parse_string_field(&kline[3])?;
|
||||
let close = Self::parse_string_field(&kline[4])?;
|
||||
let volume = Self::parse_string_field(&kline[5])?;
|
||||
let taker_buy_volume = Self::parse_string_field(&kline[9])?;
|
||||
|
||||
let net_volume = CandleData::calculate_net_volume(volume, taker_buy_volume);
|
||||
|
||||
Some(CandleData {
|
||||
symbol: symbol.to_uppercase(),
|
||||
timestamp,
|
||||
open,
|
||||
high,
|
||||
low,
|
||||
close,
|
||||
volume,
|
||||
taker_buy_volume,
|
||||
net_volume,
|
||||
is_closed: true,
|
||||
})
|
||||
}
|
||||
|
||||
fn parse_string_field(item: &KlineCandlestickDataResponseItemInner) -> Option<f64> {
|
||||
match item {
|
||||
KlineCandlestickDataResponseItemInner::String(s) => s.parse().ok(),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_ws_kline(symbol: &str, k: &KlineCandlestickStreamsResponseK) -> CandleData {
|
||||
let timestamp = k.t.unwrap_or(0);
|
||||
let open = k.o.as_ref().and_then(|s| s.parse().ok()).unwrap_or(0.0);
|
||||
let high = k.h.as_ref().and_then(|s| s.parse().ok()).unwrap_or(0.0);
|
||||
let low = k.l.as_ref().and_then(|s| s.parse().ok()).unwrap_or(0.0);
|
||||
let close = k.c.as_ref().and_then(|s| s.parse().ok()).unwrap_or(0.0);
|
||||
let volume = k.v.as_ref().and_then(|s| s.parse().ok()).unwrap_or(0.0);
|
||||
let taker_buy_volume = k.v_uppercase.as_ref().and_then(|s| s.parse().ok()).unwrap_or(0.0);
|
||||
let is_closed = k.x.unwrap_or(false);
|
||||
|
||||
let net_volume = CandleData::calculate_net_volume(volume, taker_buy_volume);
|
||||
|
||||
CandleData {
|
||||
symbol: symbol.to_uppercase(),
|
||||
timestamp,
|
||||
open,
|
||||
high,
|
||||
low,
|
||||
close,
|
||||
volume,
|
||||
taker_buy_volume,
|
||||
net_volume,
|
||||
is_closed,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// Get all tradable symbol in current market
|
||||
pub async fn get_symbol() -> Result<Vec<Symbol>, CollectorError> {
|
||||
|
||||
let port: u16 = rand::rng().random_range(10036..=10066);
|
||||
|
||||
let mut config_builder = ConfigurationRestApi::builder()
|
||||
.timeout(10000);
|
||||
|
||||
if let Some(proxy) = proxy_config_from_env(port) {
|
||||
config_builder = config_builder.proxy(proxy);
|
||||
}
|
||||
|
||||
let rest_client_config = config_builder
|
||||
.build()
|
||||
.expect("Failed to initialize the rest api client");
|
||||
|
||||
let rest_client = DerivativesTradingUsdsFuturesRestApi::production(rest_client_config);
|
||||
|
||||
let mut symbol_list = Vec::new();
|
||||
|
||||
let response = rest_client
|
||||
.exchange_information()
|
||||
.await
|
||||
.map_err(|e| CollectorError::GetSymbolError(e.to_string()))?;
|
||||
|
||||
let data = response.data().await.unwrap();
|
||||
|
||||
let symbol_vec = data.symbols.unwrap();
|
||||
|
||||
for item in symbol_vec {
|
||||
|
||||
if item.contract_type.unwrap() == "PERPETUAL" {
|
||||
|
||||
let symbol = Symbol {
|
||||
|
||||
symbol: item.symbol.unwrap(),
|
||||
start_timestamp: item.onboard_date.unwrap(),
|
||||
};
|
||||
|
||||
symbol_list.push(symbol);
|
||||
}
|
||||
}
|
||||
|
||||
Ok(symbol_list)
|
||||
}
|
||||
|
||||
|
||||
/// Build proxy list (port 10000-10099) and create clients
|
||||
pub async fn build_clients() -> Vec<Arc<RestApi>> {
|
||||
let mut handles = Vec::new();
|
||||
|
||||
let port_start: u16 = std::env::var("PROXY_PORT_START")
|
||||
.ok().and_then(|v| v.parse().ok()).unwrap_or(10000);
|
||||
let port_end: u16 = std::env::var("PROXY_PORT_END")
|
||||
.ok().and_then(|v| v.parse().ok()).unwrap_or(10099);
|
||||
|
||||
for port in port_start..=port_end {
|
||||
let handle = tokio::spawn(async move {
|
||||
let mut config_builder = ConfigurationRestApi::builder()
|
||||
.timeout(5000);
|
||||
|
||||
if let Some(proxy) = proxy_config_from_env(port) {
|
||||
config_builder = config_builder.proxy(proxy);
|
||||
}
|
||||
|
||||
let config = config_builder
|
||||
.build()
|
||||
.ok()?;
|
||||
|
||||
let client = DerivativesTradingUsdsFuturesRestApi::production(config);
|
||||
|
||||
// Test connection
|
||||
if client.check_server_time().await.ok()?.data().await.is_ok() {
|
||||
Some(Arc::new(client))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
});
|
||||
handles.push(handle);
|
||||
}
|
||||
|
||||
let mut clients = Vec::new();
|
||||
for handle in handles {
|
||||
if let Ok(Some(client)) = handle.await {
|
||||
clients.push(client);
|
||||
}
|
||||
}
|
||||
|
||||
info!("Built {} working clients", clients.len());
|
||||
clients
|
||||
}
|
||||
|
||||
/// Comprehensive sync: Monthly ZIP → Daily ZIP → API (fastest to slowest)
|
||||
pub async fn sync_comprehensive(
|
||||
symbol: String,
|
||||
start_time: i64,
|
||||
api_clients: Vec<Arc<RestApi>>,
|
||||
http_clients: &[Arc<Client>],
|
||||
candle_tx: mpsc::Sender<CandleData>,
|
||||
) -> Result<u64, CollectorError> {
|
||||
let mut total = 0u64;
|
||||
let mut current_start = start_time;
|
||||
|
||||
// Phase 1: Monthly ZIP download (complete months only)
|
||||
let month_end = HistoricalDownloader::last_complete_month_end();
|
||||
if current_start < month_end && !http_clients.is_empty() {
|
||||
info!("{}: Phase 1 - Monthly ZIP download", symbol);
|
||||
match HistoricalDownloader::download_symbol_with_clients(
|
||||
&symbol,
|
||||
current_start,
|
||||
http_clients,
|
||||
candle_tx.clone(),
|
||||
).await {
|
||||
Ok(count) => {
|
||||
total += count;
|
||||
if count > 0 {
|
||||
current_start = month_end;
|
||||
info!("{}: Monthly ZIP done, {} candles", symbol, count);
|
||||
}
|
||||
}
|
||||
Err(e) => warn!("{}: Monthly ZIP failed: {}", symbol, e),
|
||||
}
|
||||
}
|
||||
|
||||
// Phase 2: Daily ZIP download (current month's completed days)
|
||||
let now = std::time::SystemTime::now()
|
||||
.duration_since(std::time::UNIX_EPOCH)
|
||||
.unwrap()
|
||||
.as_millis() as i64;
|
||||
let today_start = (now / (24 * 60 * 60 * 1000)) * (24 * 60 * 60 * 1000);
|
||||
|
||||
if current_start < today_start && !http_clients.is_empty() {
|
||||
info!("{}: Phase 2 - Daily ZIP download", symbol);
|
||||
match HistoricalDownloader::download_days_with_clients(
|
||||
&symbol,
|
||||
current_start,
|
||||
http_clients,
|
||||
candle_tx.clone(),
|
||||
).await {
|
||||
Ok(count) => {
|
||||
total += count;
|
||||
if count > 0 {
|
||||
current_start = today_start;
|
||||
info!("{}: Daily ZIP done, {} candles", symbol, count);
|
||||
}
|
||||
}
|
||||
Err(e) => warn!("{}: Daily ZIP failed: {}", symbol, e),
|
||||
}
|
||||
}
|
||||
|
||||
// Phase 3: API for remaining (today's data)
|
||||
if current_start < now && !api_clients.is_empty() {
|
||||
info!("{}: Phase 3 - API sync for today", symbol);
|
||||
match Self::sync_from_scratch(
|
||||
symbol.clone(),
|
||||
current_start,
|
||||
api_clients,
|
||||
candle_tx,
|
||||
).await {
|
||||
Ok(count) => {
|
||||
total += count;
|
||||
info!("{}: API sync done, {} candles", symbol, count);
|
||||
}
|
||||
Err(e) => warn!("{}: API sync failed: {}", symbol, e),
|
||||
}
|
||||
}
|
||||
|
||||
info!("{}: Comprehensive sync complete, total {} candles", symbol, total);
|
||||
Ok(total)
|
||||
}
|
||||
|
||||
/// Sync single symbol using ALL clients in parallel (each client handles a time segment)
|
||||
pub async fn sync_from_scratch(
|
||||
symbol: String,
|
||||
start_time: i64,
|
||||
clients: Vec<Arc<RestApi>>,
|
||||
candle_tx: mpsc::Sender<CandleData>,
|
||||
) -> Result<u64, CollectorError> {
|
||||
let now = std::time::SystemTime::now()
|
||||
.duration_since(std::time::UNIX_EPOCH)
|
||||
.unwrap()
|
||||
.as_millis() as i64;
|
||||
|
||||
let num_clients = clients.len();
|
||||
if num_clients == 0 {
|
||||
return Err(CollectorError::RestApiError("No clients".to_string()));
|
||||
}
|
||||
|
||||
let total_duration = now - start_time;
|
||||
let segment_size = total_duration / num_clients as i64;
|
||||
|
||||
info!(
|
||||
"Syncing {} with {} clients, {} -> {} ({} ms per segment)",
|
||||
symbol, num_clients, start_time, now, segment_size
|
||||
);
|
||||
|
||||
// Each client gets a time segment
|
||||
let mut handles = Vec::new();
|
||||
|
||||
for (i, client) in clients.into_iter().enumerate() {
|
||||
let seg_start = start_time + (i as i64 * segment_size);
|
||||
let seg_end = if i == num_clients - 1 {
|
||||
now // Last segment goes to now
|
||||
} else {
|
||||
start_time + ((i + 1) as i64 * segment_size)
|
||||
};
|
||||
|
||||
let sym = symbol.clone();
|
||||
let tx = candle_tx.clone();
|
||||
|
||||
handles.push(tokio::spawn(async move {
|
||||
Self::sync_segment(sym, seg_start, seg_end, client, tx).await
|
||||
}));
|
||||
}
|
||||
|
||||
// Wait and sum results
|
||||
let mut total = 0u64;
|
||||
for (i, h) in handles.into_iter().enumerate() {
|
||||
match h.await {
|
||||
Ok(Ok(count)) => {
|
||||
total += count;
|
||||
debug!("Client {} done: {} candles", i, count);
|
||||
}
|
||||
Ok(Err(e)) => error!("Client {} error: {}", i, e),
|
||||
Err(e) => error!("Client {} join error: {}", i, e),
|
||||
}
|
||||
}
|
||||
|
||||
info!("{} sync complete: {} candles", symbol, total);
|
||||
Ok(total)
|
||||
}
|
||||
|
||||
/// Sync a specific time segment
|
||||
async fn sync_segment(
|
||||
symbol: String,
|
||||
start_time: i64,
|
||||
end_time: i64,
|
||||
client: Arc<RestApi>,
|
||||
candle_tx: mpsc::Sender<CandleData>,
|
||||
) -> Result<u64, CollectorError> {
|
||||
let mut current = start_time;
|
||||
let mut count = 0u64;
|
||||
|
||||
while current < end_time {
|
||||
let params = KlineCandlestickDataParams::builder(
|
||||
symbol.clone(),
|
||||
KlineCandlestickDataIntervalEnum::Interval1m,
|
||||
)
|
||||
.start_time(Some(current))
|
||||
.end_time(Some(end_time))
|
||||
.limit(Some(BATCH_SIZE))
|
||||
.build()
|
||||
.map_err(|e| CollectorError::RestApiError(e.to_string()))?;
|
||||
|
||||
let res = client
|
||||
.kline_candlestick_data(params)
|
||||
.await
|
||||
.map_err(|e| CollectorError::RestApiError(e.to_string()))?;
|
||||
|
||||
let klines = res.data().await
|
||||
.map_err(|e| CollectorError::RestApiError(e.to_string()))?;
|
||||
|
||||
if klines.is_empty() { break; }
|
||||
|
||||
let batch_len = klines.len();
|
||||
for kline in &klines {
|
||||
if let Some(candle) = Self::parse_rest_kline(&symbol, kline) {
|
||||
current = candle.timestamp + ONE_MINUTE_MS;
|
||||
let _ = candle_tx.send(candle).await;
|
||||
count += 1;
|
||||
}
|
||||
}
|
||||
|
||||
if batch_len < BATCH_SIZE as usize { break; }
|
||||
tokio::time::sleep(tokio::time::Duration::from_millis(REQUEST_INTERVAL_MS)).await;
|
||||
}
|
||||
|
||||
Ok(count)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,479 @@
|
||||
use crate::structs::*;
|
||||
|
||||
use log::{debug, error, info};
|
||||
use sqlx::{PgPool, postgres::PgPoolOptions};
|
||||
use tokio::sync::mpsc;
|
||||
use tokio::time::{Duration, interval};
|
||||
|
||||
const BUFFER_SIZE: usize = 100;
|
||||
const FLUSH_INTERVAL_SECS: u64 = 5;
|
||||
|
||||
pub struct DatabaseHandler {
|
||||
pool: PgPool,
|
||||
}
|
||||
|
||||
impl DatabaseHandler {
|
||||
pub async fn new(database_url: &str) -> Result<Self, sqlx::Error> {
|
||||
let pool = PgPoolOptions::new()
|
||||
.max_connections(20)
|
||||
.min_connections(5)
|
||||
.connect(database_url)
|
||||
.await?;
|
||||
|
||||
info!("Database connected (pool: 5-20 connections)");
|
||||
|
||||
Ok(Self { pool })
|
||||
}
|
||||
|
||||
/// Start consuming from rx and batch insert into database
|
||||
pub async fn start_consumer(&self, mut rx: mpsc::Receiver<CandleData>) {
|
||||
let mut buffer: Vec<CandleData> = Vec::with_capacity(BUFFER_SIZE);
|
||||
let mut flush_timer = interval(Duration::from_secs(FLUSH_INTERVAL_SECS));
|
||||
|
||||
info!("Database consumer started");
|
||||
|
||||
loop {
|
||||
tokio::select! {
|
||||
// Receive candle data
|
||||
candle = rx.recv() => {
|
||||
match candle {
|
||||
Some(c) => {
|
||||
buffer.push(c);
|
||||
if buffer.len() >= BUFFER_SIZE {
|
||||
self.flush_buffer(&mut buffer).await;
|
||||
}
|
||||
}
|
||||
None => {
|
||||
// Channel closed, flush remaining and exit
|
||||
if !buffer.is_empty() {
|
||||
self.flush_buffer(&mut buffer).await;
|
||||
}
|
||||
info!("Database consumer stopped (channel closed)");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Flush on timer
|
||||
_ = flush_timer.tick() => {
|
||||
if !buffer.is_empty() {
|
||||
self.flush_buffer(&mut buffer).await;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async fn flush_buffer(&self, buffer: &mut Vec<CandleData>) {
|
||||
if buffer.is_empty() {
|
||||
return;
|
||||
}
|
||||
|
||||
let count = buffer.len();
|
||||
|
||||
match self.batch_insert(buffer).await {
|
||||
Ok(_) => {
|
||||
debug!("Inserted {} candles", count);
|
||||
}
|
||||
Err(e) => {
|
||||
error!("Failed to insert {} candles: {}", count, e);
|
||||
}
|
||||
}
|
||||
|
||||
buffer.clear();
|
||||
}
|
||||
|
||||
async fn batch_insert(&self, candles: &[CandleData]) -> Result<(), sqlx::Error> {
|
||||
if candles.is_empty() {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
// Deduplicate by (symbol, timestamp) - keep last occurrence
|
||||
use std::collections::HashMap;
|
||||
let mut dedup_map: HashMap<(String, i64), &CandleData> = HashMap::new();
|
||||
for c in candles {
|
||||
dedup_map.insert((c.symbol.clone(), c.timestamp), c);
|
||||
}
|
||||
let unique_candles: Vec<&CandleData> = dedup_map.into_values().collect();
|
||||
|
||||
if unique_candles.is_empty() {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
// Build batch insert query
|
||||
let mut query = String::from(
|
||||
"INSERT INTO klines_1m (symbol, timestamp, open, high, low, close, volume, taker_buy_volume, net_volume) VALUES "
|
||||
);
|
||||
|
||||
let mut values: Vec<String> = Vec::with_capacity(unique_candles.len());
|
||||
|
||||
for (i, _) in unique_candles.iter().enumerate() {
|
||||
let idx = i * 9;
|
||||
values.push(format!(
|
||||
"(${}, ${}, ${}, ${}, ${}, ${}, ${}, ${}, ${})",
|
||||
idx + 1, idx + 2, idx + 3, idx + 4, idx + 5, idx + 6, idx + 7, idx + 8, idx + 9
|
||||
));
|
||||
}
|
||||
|
||||
query.push_str(&values.join(", "));
|
||||
query.push_str(" ON CONFLICT (symbol, timestamp) DO UPDATE SET open = EXCLUDED.open, high = EXCLUDED.high, low = EXCLUDED.low, close = EXCLUDED.close, volume = EXCLUDED.volume, taker_buy_volume = EXCLUDED.taker_buy_volume, net_volume = EXCLUDED.net_volume");
|
||||
|
||||
let mut query_builder = sqlx::query(&query);
|
||||
|
||||
for c in unique_candles {
|
||||
query_builder = query_builder
|
||||
.bind(&c.symbol)
|
||||
.bind(c.timestamp)
|
||||
.bind(c.open)
|
||||
.bind(c.high)
|
||||
.bind(c.low)
|
||||
.bind(c.close)
|
||||
.bind(c.volume)
|
||||
.bind(c.taker_buy_volume)
|
||||
.bind(c.net_volume);
|
||||
}
|
||||
|
||||
query_builder.execute(&self.pool).await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Get latest timestamp for a symbol
|
||||
pub async fn get_latest_timestamp(&self, symbol: &str) -> Result<Option<i64>, sqlx::Error> {
|
||||
let row: Option<(Option<i64>,)> = sqlx::query_as(
|
||||
"SELECT MAX(timestamp) FROM klines_1m WHERE symbol = $1"
|
||||
)
|
||||
.bind(symbol.to_uppercase())
|
||||
.fetch_optional(&self.pool)
|
||||
.await?;
|
||||
|
||||
Ok(row.and_then(|r| r.0))
|
||||
}
|
||||
|
||||
/// Get today's UTC 00:00 open price for all tracked symbols
|
||||
pub async fn get_daily_opens(&self) -> Result<std::collections::HashMap<String, f64>, sqlx::Error> {
|
||||
use chrono::Utc;
|
||||
let now = Utc::now();
|
||||
let today_start = now.date_naive().and_hms_opt(0, 0, 0).unwrap().and_utc().timestamp_millis();
|
||||
|
||||
let rows: Vec<(String, f64)> = sqlx::query_as(
|
||||
"SELECT symbol, open FROM klines_1m WHERE timestamp = $1"
|
||||
)
|
||||
.bind(today_start)
|
||||
.fetch_all(&self.pool)
|
||||
.await?;
|
||||
|
||||
Ok(rows.into_iter().collect())
|
||||
}
|
||||
|
||||
/// Get all active symbols from tracked_symbols table
|
||||
pub async fn get_active_symbols(&self) -> Result<Vec<String>, sqlx::Error> {
|
||||
let rows: Vec<(String,)> = sqlx::query_as(
|
||||
"SELECT symbol FROM tracked_symbols WHERE is_active = TRUE"
|
||||
)
|
||||
.fetch_all(&self.pool)
|
||||
.await?;
|
||||
|
||||
Ok(rows.into_iter().map(|r| r.0).collect())
|
||||
}
|
||||
|
||||
/// Get tracked symbols from TRACKED_SYMBOL env variable
|
||||
/// Format: TRACKED_SYMBOL=[BTCUSDT,ETHUSDT,BNBUSDT]
|
||||
pub fn get_symbols_from_env() -> Vec<String> {
|
||||
std::env::var("TRACKED_SYMBOL")
|
||||
.unwrap_or_default()
|
||||
.trim_start_matches('[')
|
||||
.trim_end_matches(']')
|
||||
.split(',')
|
||||
.map(|s| s.trim().to_uppercase())
|
||||
.filter(|s| !s.is_empty())
|
||||
.collect()
|
||||
}
|
||||
|
||||
/// Insert candle directly (for single inserts)
|
||||
pub async fn insert_candle(&self, candle: &CandleData) -> Result<(), sqlx::Error> {
|
||||
sqlx::query(
|
||||
"INSERT INTO klines_1m (symbol, timestamp, open, high, low, close, volume, taker_buy_volume, net_volume)
|
||||
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)
|
||||
ON CONFLICT (symbol, timestamp) DO UPDATE SET
|
||||
open = EXCLUDED.open, high = EXCLUDED.high, low = EXCLUDED.low,
|
||||
close = EXCLUDED.close, volume = EXCLUDED.volume,
|
||||
taker_buy_volume = EXCLUDED.taker_buy_volume, net_volume = EXCLUDED.net_volume"
|
||||
)
|
||||
.bind(&candle.symbol)
|
||||
.bind(candle.timestamp)
|
||||
.bind(candle.open)
|
||||
.bind(candle.high)
|
||||
.bind(candle.low)
|
||||
.bind(candle.close)
|
||||
.bind(candle.volume)
|
||||
.bind(candle.taker_buy_volume)
|
||||
.bind(candle.net_volume)
|
||||
.execute(&self.pool)
|
||||
.await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Add a new symbol to tracked_symbols
|
||||
pub async fn add_symbol(&self, symbol: &str) -> Result<(), sqlx::Error> {
|
||||
let symbol_lower = symbol.to_lowercase();
|
||||
|
||||
sqlx::query(
|
||||
"INSERT INTO tracked_symbols (symbol, is_active)
|
||||
VALUES ($1, TRUE)
|
||||
ON CONFLICT (symbol) DO UPDATE SET is_active = TRUE"
|
||||
)
|
||||
.bind(&symbol_lower)
|
||||
.execute(&self.pool)
|
||||
.await?;
|
||||
|
||||
info!("Added symbol to tracking: {}", symbol_lower);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Remove (deactivate) a symbol from tracking
|
||||
pub async fn remove_symbol(&self, symbol: &str) -> Result<(), sqlx::Error> {
|
||||
let symbol_lower = symbol.to_lowercase();
|
||||
|
||||
sqlx::query(
|
||||
"UPDATE tracked_symbols SET is_active = FALSE WHERE symbol = $1"
|
||||
)
|
||||
.bind(&symbol_lower)
|
||||
.execute(&self.pool)
|
||||
.await?;
|
||||
|
||||
info!("Removed symbol from tracking: {}", symbol_lower);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Check if a symbol is currently being tracked
|
||||
pub async fn is_symbol_tracked(&self, symbol: &str) -> Result<bool, sqlx::Error> {
|
||||
let symbol_lower = symbol.to_lowercase();
|
||||
|
||||
let row: Option<(bool,)> = sqlx::query_as(
|
||||
"SELECT is_active FROM tracked_symbols WHERE symbol = $1"
|
||||
)
|
||||
.bind(&symbol_lower)
|
||||
.fetch_optional(&self.pool)
|
||||
.await?;
|
||||
|
||||
Ok(row.map(|r| r.0).unwrap_or(false))
|
||||
}
|
||||
|
||||
/// Delete all kline data for a symbol (use with caution)
|
||||
pub async fn delete_symbol_data(&self, symbol: &str) -> Result<u64, sqlx::Error> {
|
||||
let symbol_upper = symbol.to_uppercase();
|
||||
|
||||
let result = sqlx::query(
|
||||
"DELETE FROM klines_1m WHERE symbol = $1"
|
||||
)
|
||||
.bind(&symbol_upper)
|
||||
.execute(&self.pool)
|
||||
.await?;
|
||||
|
||||
let deleted = result.rows_affected();
|
||||
info!("Deleted {} candles for symbol: {}", deleted, symbol_upper);
|
||||
Ok(deleted)
|
||||
}
|
||||
|
||||
/// Get klines for a symbol with limit and optional end_time
|
||||
pub async fn get_klines(&self, symbol: &str, limit: i64, end_time: Option<i64>) -> Result<Vec<CandleData>, sqlx::Error> {
|
||||
let symbol_upper = symbol.to_uppercase();
|
||||
|
||||
let rows: Vec<(String, i64, f64, f64, f64, f64, f64, f64, f64)> = if let Some(et) = end_time {
|
||||
sqlx::query_as(
|
||||
"SELECT symbol, timestamp, open, high, low, close, volume, taker_buy_volume, net_volume
|
||||
FROM klines_1m
|
||||
WHERE symbol = $1 AND timestamp <= $3
|
||||
ORDER BY timestamp DESC
|
||||
LIMIT $2"
|
||||
)
|
||||
.bind(&symbol_upper)
|
||||
.bind(limit)
|
||||
.bind(et)
|
||||
.fetch_all(&self.pool)
|
||||
.await?
|
||||
} else {
|
||||
sqlx::query_as(
|
||||
"SELECT symbol, timestamp, open, high, low, close, volume, taker_buy_volume, net_volume
|
||||
FROM klines_1m
|
||||
WHERE symbol = $1
|
||||
ORDER BY timestamp DESC
|
||||
LIMIT $2"
|
||||
)
|
||||
.bind(&symbol_upper)
|
||||
.bind(limit)
|
||||
.fetch_all(&self.pool)
|
||||
.await?
|
||||
};
|
||||
|
||||
let mut candles: Vec<CandleData> = rows.into_iter().map(|r| CandleData {
|
||||
symbol: r.0,
|
||||
timestamp: r.1,
|
||||
open: r.2,
|
||||
high: r.3,
|
||||
low: r.4,
|
||||
close: r.5,
|
||||
volume: r.6,
|
||||
taker_buy_volume: r.7,
|
||||
net_volume: r.8,
|
||||
is_closed: true,
|
||||
}).collect();
|
||||
|
||||
// Reverse to chronological order (oldest first)
|
||||
candles.reverse();
|
||||
|
||||
Ok(candles)
|
||||
}
|
||||
|
||||
/// Get klines aggregated to a specific interval using TimescaleDB time_bucket
|
||||
pub async fn get_klines_aggregated(
|
||||
&self,
|
||||
symbol: &str,
|
||||
interval: crate::Interval,
|
||||
limit: i64,
|
||||
end_time: Option<i64>
|
||||
) -> Result<Vec<CandleData>, sqlx::Error> {
|
||||
use crate::Interval;
|
||||
|
||||
// For 1m interval, just return raw data
|
||||
if interval == Interval::Min1 {
|
||||
return self.get_klines(symbol, limit, end_time).await;
|
||||
}
|
||||
|
||||
let symbol_upper = symbol.to_uppercase();
|
||||
|
||||
// Calculate interval in milliseconds for time range filtering
|
||||
let interval_ms: i64 = match interval {
|
||||
Interval::Min1 => 60_000,
|
||||
Interval::Min5 => 5 * 60_000,
|
||||
Interval::Min15 => 15 * 60_000,
|
||||
Interval::Hour1 => 60 * 60_000,
|
||||
Interval::Hour4 => 4 * 60 * 60_000,
|
||||
Interval::Day1 => 24 * 60 * 60_000,
|
||||
Interval::Week1 => 7 * 24 * 60 * 60_000,
|
||||
Interval::Month1 => 30 * 24 * 60 * 60_000,
|
||||
};
|
||||
|
||||
// Convert interval to PostgreSQL interval string
|
||||
let interval_str = match interval {
|
||||
Interval::Min1 => "1 minute",
|
||||
Interval::Min5 => "5 minutes",
|
||||
Interval::Min15 => "15 minutes",
|
||||
Interval::Hour1 => "1 hour",
|
||||
Interval::Hour4 => "4 hours",
|
||||
Interval::Day1 => "1 day",
|
||||
Interval::Week1 => "1 week",
|
||||
Interval::Month1 => "1 month",
|
||||
};
|
||||
|
||||
// Calculate time range to limit scan (add 10% buffer)
|
||||
let et = end_time.unwrap_or_else(|| chrono::Utc::now().timestamp_millis());
|
||||
let time_range_needed = interval_ms * limit * 11 / 10;
|
||||
let start_time = et - time_range_needed;
|
||||
|
||||
// Use TimescaleDB time_bucket for efficient aggregation with time range filter
|
||||
let query = format!(
|
||||
r#"
|
||||
SELECT
|
||||
$1 as symbol,
|
||||
(EXTRACT(EPOCH FROM time_bucket('{interval}', to_timestamp(timestamp/1000.0))) * 1000)::bigint as bucket_ts,
|
||||
(array_agg(open ORDER BY timestamp ASC))[1] as open,
|
||||
max(high) as high,
|
||||
min(low) as low,
|
||||
(array_agg(close ORDER BY timestamp DESC))[1] as close,
|
||||
sum(volume) as volume,
|
||||
sum(taker_buy_volume) as taker_buy_volume,
|
||||
sum(net_volume) as net_volume
|
||||
FROM klines_1m
|
||||
WHERE symbol = $1 AND timestamp >= $3 AND timestamp <= $4
|
||||
GROUP BY bucket_ts
|
||||
ORDER BY bucket_ts DESC
|
||||
LIMIT $2
|
||||
"#,
|
||||
interval = interval_str,
|
||||
);
|
||||
|
||||
let rows: Vec<(String, i64, f64, f64, f64, f64, f64, f64, f64)> = sqlx::query_as(&query)
|
||||
.bind(&symbol_upper)
|
||||
.bind(limit)
|
||||
.bind(start_time)
|
||||
.bind(et)
|
||||
.fetch_all(&self.pool)
|
||||
.await?;
|
||||
|
||||
let mut candles: Vec<CandleData> = rows.into_iter().map(|r| CandleData {
|
||||
symbol: r.0,
|
||||
timestamp: r.1,
|
||||
open: r.2,
|
||||
high: r.3,
|
||||
low: r.4,
|
||||
close: r.5,
|
||||
volume: r.6,
|
||||
taker_buy_volume: r.7,
|
||||
net_volume: r.8,
|
||||
is_closed: true,
|
||||
}).collect();
|
||||
|
||||
// Reverse to chronological order (oldest first)
|
||||
candles.reverse();
|
||||
|
||||
Ok(candles)
|
||||
}
|
||||
|
||||
/// Find gaps in 1-minute kline data for a symbol.
|
||||
/// Returns a list of (start_timestamp, end_timestamp) pairs representing gaps.
|
||||
/// Each gap represents missing data from start_timestamp to end_timestamp (exclusive).
|
||||
/// Only considers data after DATA_CUTOFF_TIMESTAMP (2024-01-01).
|
||||
pub async fn find_gaps(&self, symbol: &str, cutoff_timestamp: i64) -> Result<Vec<(i64, i64)>, sqlx::Error> {
|
||||
let symbol_upper = symbol.to_uppercase();
|
||||
|
||||
// Query to find gaps using window function
|
||||
// We look for cases where the next timestamp is more than 1 minute away
|
||||
// Only consider data after cutoff_timestamp
|
||||
let rows: Vec<(i64, i64)> = sqlx::query_as(
|
||||
r#"
|
||||
WITH ordered_klines AS (
|
||||
SELECT timestamp,
|
||||
LEAD(timestamp) OVER (ORDER BY timestamp) as next_timestamp
|
||||
FROM klines_1m
|
||||
WHERE symbol = $1 AND timestamp >= $2
|
||||
)
|
||||
SELECT timestamp + 60000 as gap_start, next_timestamp as gap_end
|
||||
FROM ordered_klines
|
||||
WHERE next_timestamp - timestamp > 60000
|
||||
ORDER BY timestamp
|
||||
"#
|
||||
)
|
||||
.bind(&symbol_upper)
|
||||
.bind(cutoff_timestamp)
|
||||
.fetch_all(&self.pool)
|
||||
.await?;
|
||||
|
||||
Ok(rows)
|
||||
}
|
||||
|
||||
/// Get the earliest timestamp for a symbol
|
||||
pub async fn get_earliest_timestamp(&self, symbol: &str) -> Result<Option<i64>, sqlx::Error> {
|
||||
let row: Option<(Option<i64>,)> = sqlx::query_as(
|
||||
"SELECT MIN(timestamp) FROM klines_1m WHERE symbol = $1"
|
||||
)
|
||||
.bind(symbol.to_uppercase())
|
||||
.fetch_optional(&self.pool)
|
||||
.await?;
|
||||
|
||||
Ok(row.and_then(|r| r.0))
|
||||
}
|
||||
|
||||
/// Get count of klines for a symbol
|
||||
pub async fn get_kline_count(&self, symbol: &str) -> Result<i64, sqlx::Error> {
|
||||
let row: (i64,) = sqlx::query_as(
|
||||
"SELECT COUNT(*) FROM klines_1m WHERE symbol = $1"
|
||||
)
|
||||
.bind(symbol.to_uppercase())
|
||||
.fetch_one(&self.pool)
|
||||
.await?;
|
||||
|
||||
Ok(row.0)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
use thiserror::Error;
|
||||
|
||||
#[derive(Error, Debug)]
|
||||
pub enum CollectorError {
|
||||
#[error("WebSocket connection failed: {0}")]
|
||||
ConnectionFailed(String),
|
||||
|
||||
#[error("REST API request failed: {0}")]
|
||||
RestApiError(String),
|
||||
|
||||
#[error("Data parsing error: {0}")]
|
||||
ParseError(String),
|
||||
|
||||
#[error("Invalid kline data: {0}")]
|
||||
InvalidKlineData(String),
|
||||
|
||||
#[error("Failed to get opened symbol, with error {0}")]
|
||||
GetSymbolError(String),
|
||||
|
||||
}
|
||||
|
||||
#[derive(Error, Debug)]
|
||||
pub enum SchedulerError {
|
||||
#[error("Database error: {0}")]
|
||||
DatabaseError(String),
|
||||
|
||||
#[error("Collector error: {0}")]
|
||||
CollectorError(String),
|
||||
|
||||
#[error("Backfill error: {0}")]
|
||||
BackfillError(String),
|
||||
|
||||
#[error("No active symbols")]
|
||||
NoActiveSymbols,
|
||||
}
|
||||
|
||||
impl From<sqlx::Error> for SchedulerError {
|
||||
fn from(err: sqlx::Error) -> Self {
|
||||
SchedulerError::DatabaseError(err.to_string())
|
||||
}
|
||||
}
|
||||
|
||||
impl From<CollectorError> for SchedulerError {
|
||||
fn from(err: CollectorError) -> Self {
|
||||
SchedulerError::CollectorError(err.to_string())
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,522 @@
|
||||
use crate::structs::CandleData;
|
||||
use crate::error::CollectorError;
|
||||
|
||||
use chrono::{Datelike, NaiveDate, Utc};
|
||||
use log::{info, warn};
|
||||
use std::io::{Cursor, Read};
|
||||
use std::sync::Arc;
|
||||
use tokio::sync::mpsc;
|
||||
use futures::future::join_all;
|
||||
use reqwest::Client;
|
||||
|
||||
const BASE_URL: &str = "https://data.binance.vision/data/futures/um/monthly/klines";
|
||||
const DAILY_BASE_URL: &str = "https://data.binance.vision/data/futures/um/daily/klines";
|
||||
|
||||
/// Download historical klines from Binance data archive
|
||||
pub struct HistoricalDownloader;
|
||||
|
||||
impl HistoricalDownloader {
|
||||
/// Build proxy clients from env vars (PROXY_HOST, PROXY_USERNAME, PROXY_PASSWORD, PROXY_PROTOCOL)
|
||||
/// Port range defaults to PROXY_PORT_START..PROXY_PORT_END (default 10000..10099)
|
||||
/// Returns direct (no-proxy) clients if PROXY_HOST is not set.
|
||||
pub async fn build_clients() -> Vec<Arc<Client>> {
|
||||
let mut handles = Vec::new();
|
||||
|
||||
let proxy_host = std::env::var("PROXY_HOST").unwrap_or_default();
|
||||
let proxy_username = std::env::var("PROXY_USERNAME").unwrap_or_default();
|
||||
let proxy_password = std::env::var("PROXY_PASSWORD").unwrap_or_default();
|
||||
let proxy_protocol = std::env::var("PROXY_PROTOCOL").unwrap_or_else(|_| "https".to_string());
|
||||
let port_start: u16 = std::env::var("PROXY_PORT_START")
|
||||
.ok().and_then(|v| v.parse().ok()).unwrap_or(10000);
|
||||
let port_end: u16 = std::env::var("PROXY_PORT_END")
|
||||
.ok().and_then(|v| v.parse().ok()).unwrap_or(10099);
|
||||
|
||||
if proxy_host.is_empty() {
|
||||
// No proxy configured — return a single direct client
|
||||
info!("No proxy configured (PROXY_HOST not set), using direct connection");
|
||||
if let Ok(client) = Client::builder()
|
||||
.timeout(std::time::Duration::from_secs(60))
|
||||
.build()
|
||||
{
|
||||
return vec![Arc::new(client)];
|
||||
}
|
||||
return vec![];
|
||||
}
|
||||
|
||||
for port in port_start..=port_end {
|
||||
let host = proxy_host.clone();
|
||||
let user = proxy_username.clone();
|
||||
let pass = proxy_password.clone();
|
||||
let proto = proxy_protocol.clone();
|
||||
|
||||
handles.push(tokio::spawn(async move {
|
||||
let proxy_url = if user.is_empty() {
|
||||
format!("{}://{}:{}", proto, host, port)
|
||||
} else {
|
||||
format!("{}://{}:{}@{}:{}", proto, user, pass, host, port)
|
||||
};
|
||||
|
||||
match reqwest::Proxy::all(&proxy_url) {
|
||||
Ok(proxy) => {
|
||||
match Client::builder()
|
||||
.proxy(proxy)
|
||||
.timeout(std::time::Duration::from_secs(60))
|
||||
.build()
|
||||
{
|
||||
Ok(client) => Some(Arc::new(client)),
|
||||
Err(_) => None,
|
||||
}
|
||||
}
|
||||
Err(_) => None,
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
let mut clients = Vec::new();
|
||||
for handle in handles {
|
||||
if let Ok(Some(client)) = handle.await {
|
||||
clients.push(client);
|
||||
}
|
||||
}
|
||||
|
||||
info!("Built {} download clients with proxies", clients.len());
|
||||
clients
|
||||
}
|
||||
|
||||
/// Download all monthly klines for a symbol using proxy clients
|
||||
pub async fn download_symbol_with_clients(
|
||||
symbol: &str,
|
||||
start_timestamp: i64,
|
||||
clients: &[Arc<Client>],
|
||||
candle_tx: mpsc::Sender<CandleData>,
|
||||
) -> Result<u64, CollectorError> {
|
||||
let symbol_upper = symbol.to_uppercase();
|
||||
|
||||
if clients.is_empty() {
|
||||
return Err(CollectorError::RestApiError("No clients available".to_string()));
|
||||
}
|
||||
|
||||
// Calculate start and end months
|
||||
let start_date = Self::timestamp_to_date(start_timestamp);
|
||||
let now = Utc::now().naive_utc().date();
|
||||
|
||||
// Generate list of months to download (exclude current month - incomplete)
|
||||
let months = Self::generate_months(start_date, now);
|
||||
|
||||
if months.is_empty() {
|
||||
info!("{}: No complete months to download", symbol_upper);
|
||||
return Ok(0);
|
||||
}
|
||||
|
||||
info!(
|
||||
"{}: Downloading {} months ({}-{:02} to {}-{:02}) with {} clients",
|
||||
symbol_upper,
|
||||
months.len(),
|
||||
months.first().unwrap().0, months.first().unwrap().1,
|
||||
months.last().unwrap().0, months.last().unwrap().1,
|
||||
clients.len()
|
||||
);
|
||||
|
||||
// Download all months in parallel using all clients
|
||||
let mut handles = Vec::new();
|
||||
|
||||
for (i, &(year, month)) in months.iter().enumerate() {
|
||||
let client = clients[i % clients.len()].clone();
|
||||
let sym = symbol_upper.clone();
|
||||
let tx = candle_tx.clone();
|
||||
|
||||
handles.push(tokio::spawn(async move {
|
||||
Self::download_month_with_client(&sym, year, month, &client, tx).await
|
||||
}));
|
||||
}
|
||||
|
||||
// Wait for all downloads
|
||||
let results = join_all(handles).await;
|
||||
|
||||
let mut total_candles = 0u64;
|
||||
for result in results {
|
||||
match result {
|
||||
Ok(Ok(count)) => total_candles += count,
|
||||
Ok(Err(e)) => warn!("Download error: {}", e),
|
||||
Err(e) => warn!("Join error: {}", e),
|
||||
}
|
||||
}
|
||||
|
||||
info!("{}: Downloaded {} candles from archive", symbol_upper, total_candles);
|
||||
Ok(total_candles)
|
||||
}
|
||||
|
||||
/// Download a single month's klines using a specific client
|
||||
async fn download_month_with_client(
|
||||
symbol: &str,
|
||||
year: i32,
|
||||
month: u32,
|
||||
client: &Client,
|
||||
candle_tx: mpsc::Sender<CandleData>,
|
||||
) -> Result<u64, CollectorError> {
|
||||
let url = format!(
|
||||
"{}/{}/1m/{}-1m-{}-{:02}.zip",
|
||||
BASE_URL, symbol, symbol, year, month
|
||||
);
|
||||
|
||||
// Download ZIP file with proxy client
|
||||
let response = client.get(&url)
|
||||
.send()
|
||||
.await
|
||||
.map_err(|e| CollectorError::RestApiError(format!("Download failed: {}", e)))?;
|
||||
|
||||
if !response.status().is_success() {
|
||||
return Err(CollectorError::RestApiError(
|
||||
format!("HTTP {}: {}", response.status(), url)
|
||||
));
|
||||
}
|
||||
|
||||
let bytes = response.bytes()
|
||||
.await
|
||||
.map_err(|e| CollectorError::RestApiError(format!("Read bytes failed: {}", e)))?;
|
||||
|
||||
// Extract CSV from ZIP
|
||||
let cursor = Cursor::new(bytes);
|
||||
let mut archive = zip::ZipArchive::new(cursor)
|
||||
.map_err(|e| CollectorError::RestApiError(format!("ZIP error: {}", e)))?;
|
||||
|
||||
let mut csv_content = String::new();
|
||||
{
|
||||
let mut file = archive.by_index(0)
|
||||
.map_err(|e| CollectorError::RestApiError(format!("ZIP file error: {}", e)))?;
|
||||
file.read_to_string(&mut csv_content)
|
||||
.map_err(|e| CollectorError::RestApiError(format!("Read CSV error: {}", e)))?;
|
||||
}
|
||||
|
||||
// Parse CSV and send candles
|
||||
let count = Self::parse_csv(symbol, &csv_content, &candle_tx).await?;
|
||||
|
||||
info!("{} {}-{:02}: {} candles", symbol, year, month, count);
|
||||
Ok(count)
|
||||
}
|
||||
|
||||
/// Download all monthly klines (without proxy - original method)
|
||||
pub async fn download_symbol(
|
||||
symbol: &str,
|
||||
start_timestamp: i64,
|
||||
candle_tx: mpsc::Sender<CandleData>,
|
||||
max_parallel: usize,
|
||||
) -> Result<u64, CollectorError> {
|
||||
let symbol_upper = symbol.to_uppercase();
|
||||
|
||||
let start_date = Self::timestamp_to_date(start_timestamp);
|
||||
let now = Utc::now().naive_utc().date();
|
||||
let months = Self::generate_months(start_date, now);
|
||||
|
||||
if months.is_empty() {
|
||||
info!("{}: No complete months to download", symbol_upper);
|
||||
return Ok(0);
|
||||
}
|
||||
|
||||
info!(
|
||||
"{}: Downloading {} months from {}-{:02} to {}-{:02}",
|
||||
symbol_upper,
|
||||
months.len(),
|
||||
months.first().unwrap().0, months.first().unwrap().1,
|
||||
months.last().unwrap().0, months.last().unwrap().1
|
||||
);
|
||||
|
||||
let mut total_candles = 0u64;
|
||||
|
||||
for chunk in months.chunks(max_parallel) {
|
||||
let mut handles = Vec::new();
|
||||
|
||||
for &(year, month) in chunk {
|
||||
let sym = symbol_upper.clone();
|
||||
let tx = candle_tx.clone();
|
||||
|
||||
handles.push(tokio::spawn(async move {
|
||||
Self::download_month(&sym, year, month, tx).await
|
||||
}));
|
||||
}
|
||||
|
||||
let results = join_all(handles).await;
|
||||
|
||||
for result in results {
|
||||
match result {
|
||||
Ok(Ok(count)) => total_candles += count,
|
||||
Ok(Err(e)) => warn!("Download error: {}", e),
|
||||
Err(e) => warn!("Join error: {}", e),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
info!("{}: Downloaded {} candles from archive", symbol_upper, total_candles);
|
||||
Ok(total_candles)
|
||||
}
|
||||
|
||||
/// Download a single month (without proxy)
|
||||
async fn download_month(
|
||||
symbol: &str,
|
||||
year: i32,
|
||||
month: u32,
|
||||
candle_tx: mpsc::Sender<CandleData>,
|
||||
) -> Result<u64, CollectorError> {
|
||||
let url = format!(
|
||||
"{}/{}/1m/{}-1m-{}-{:02}.zip",
|
||||
BASE_URL, symbol, symbol, year, month
|
||||
);
|
||||
|
||||
let response = reqwest::get(&url)
|
||||
.await
|
||||
.map_err(|e| CollectorError::RestApiError(format!("Download failed: {}", e)))?;
|
||||
|
||||
if !response.status().is_success() {
|
||||
return Err(CollectorError::RestApiError(
|
||||
format!("HTTP {}: {}", response.status(), url)
|
||||
));
|
||||
}
|
||||
|
||||
let bytes = response.bytes()
|
||||
.await
|
||||
.map_err(|e| CollectorError::RestApiError(format!("Read bytes failed: {}", e)))?;
|
||||
|
||||
let cursor = Cursor::new(bytes);
|
||||
let mut archive = zip::ZipArchive::new(cursor)
|
||||
.map_err(|e| CollectorError::RestApiError(format!("ZIP error: {}", e)))?;
|
||||
|
||||
let mut csv_content = String::new();
|
||||
{
|
||||
let mut file = archive.by_index(0)
|
||||
.map_err(|e| CollectorError::RestApiError(format!("ZIP file error: {}", e)))?;
|
||||
file.read_to_string(&mut csv_content)
|
||||
.map_err(|e| CollectorError::RestApiError(format!("Read CSV error: {}", e)))?;
|
||||
}
|
||||
|
||||
let count = Self::parse_csv(symbol, &csv_content, &candle_tx).await?;
|
||||
|
||||
info!("{} {}-{:02}: {} candles", symbol, year, month, count);
|
||||
Ok(count)
|
||||
}
|
||||
|
||||
/// Parse CSV content and send candles through channel
|
||||
async fn parse_csv(
|
||||
symbol: &str,
|
||||
csv_content: &str,
|
||||
candle_tx: &mpsc::Sender<CandleData>,
|
||||
) -> Result<u64, CollectorError> {
|
||||
let mut reader = csv::ReaderBuilder::new()
|
||||
.has_headers(true)
|
||||
.from_reader(csv_content.as_bytes());
|
||||
|
||||
let mut count = 0u64;
|
||||
|
||||
for result in reader.records() {
|
||||
let record = match result {
|
||||
Ok(r) => r,
|
||||
Err(_) => continue,
|
||||
};
|
||||
|
||||
if record.len() < 11 {
|
||||
continue;
|
||||
}
|
||||
|
||||
let timestamp: i64 = record[0].parse().unwrap_or(0);
|
||||
let open: f64 = record[1].parse().unwrap_or(0.0);
|
||||
let high: f64 = record[2].parse().unwrap_or(0.0);
|
||||
let low: f64 = record[3].parse().unwrap_or(0.0);
|
||||
let close: f64 = record[4].parse().unwrap_or(0.0);
|
||||
let volume: f64 = record[5].parse().unwrap_or(0.0);
|
||||
let taker_buy_volume: f64 = record[9].parse().unwrap_or(0.0);
|
||||
|
||||
let net_volume = taker_buy_volume * 2.0 - volume;
|
||||
|
||||
let candle = CandleData {
|
||||
symbol: symbol.to_string(),
|
||||
timestamp,
|
||||
open,
|
||||
high,
|
||||
low,
|
||||
close,
|
||||
volume,
|
||||
taker_buy_volume,
|
||||
net_volume,
|
||||
is_closed: true,
|
||||
};
|
||||
|
||||
if candle_tx.send(candle).await.is_err() {
|
||||
break;
|
||||
}
|
||||
count += 1;
|
||||
}
|
||||
|
||||
Ok(count)
|
||||
}
|
||||
|
||||
fn timestamp_to_date(ts: i64) -> NaiveDate {
|
||||
let secs = ts / 1000;
|
||||
chrono::DateTime::from_timestamp(secs, 0)
|
||||
.unwrap_or_else(|| Utc::now())
|
||||
.naive_utc()
|
||||
.date()
|
||||
}
|
||||
|
||||
fn generate_months(start: NaiveDate, end: NaiveDate) -> Vec<(i32, u32)> {
|
||||
let mut months = Vec::new();
|
||||
|
||||
let mut year = start.year();
|
||||
let mut month = start.month();
|
||||
|
||||
let end_year = if end.month() == 1 { end.year() - 1 } else { end.year() };
|
||||
let end_month = if end.month() == 1 { 12 } else { end.month() - 1 };
|
||||
|
||||
loop {
|
||||
if year > end_year || (year == end_year && month > end_month) {
|
||||
break;
|
||||
}
|
||||
|
||||
months.push((year, month));
|
||||
|
||||
month += 1;
|
||||
if month > 12 {
|
||||
month = 1;
|
||||
year += 1;
|
||||
}
|
||||
}
|
||||
|
||||
months
|
||||
}
|
||||
|
||||
pub fn last_complete_month_end() -> i64 {
|
||||
let now = Utc::now().naive_utc();
|
||||
let first_of_this_month = NaiveDate::from_ymd_opt(now.year(), now.month(), 1)
|
||||
.unwrap()
|
||||
.and_hms_opt(0, 0, 0)
|
||||
.unwrap();
|
||||
first_of_this_month.and_utc().timestamp_millis()
|
||||
}
|
||||
|
||||
/// Download daily klines for a symbol (for current incomplete month)
|
||||
pub async fn download_days_with_clients(
|
||||
symbol: &str,
|
||||
start_timestamp: i64,
|
||||
clients: &[Arc<Client>],
|
||||
candle_tx: mpsc::Sender<CandleData>,
|
||||
) -> Result<u64, CollectorError> {
|
||||
let symbol_upper = symbol.to_uppercase();
|
||||
|
||||
if clients.is_empty() {
|
||||
return Err(CollectorError::RestApiError("No clients available".to_string()));
|
||||
}
|
||||
|
||||
let start_date = Self::timestamp_to_date(start_timestamp);
|
||||
let yesterday = Utc::now().naive_utc().date().pred_opt().unwrap_or(start_date);
|
||||
|
||||
let days = Self::generate_days(start_date, yesterday);
|
||||
|
||||
if days.is_empty() {
|
||||
info!("{}: No days to download", symbol_upper);
|
||||
return Ok(0);
|
||||
}
|
||||
|
||||
info!(
|
||||
"{}: Downloading {} days ({} to {}) with {} clients",
|
||||
symbol_upper, days.len(),
|
||||
days.first().unwrap(), days.last().unwrap(),
|
||||
clients.len()
|
||||
);
|
||||
|
||||
let mut handles = Vec::new();
|
||||
|
||||
for (i, date) in days.iter().enumerate() {
|
||||
let client = clients[i % clients.len()].clone();
|
||||
let sym = symbol_upper.clone();
|
||||
let tx = candle_tx.clone();
|
||||
let d = *date;
|
||||
|
||||
handles.push(tokio::spawn(async move {
|
||||
Self::download_day_with_client(&sym, d, &client, tx).await
|
||||
}));
|
||||
}
|
||||
|
||||
let results = join_all(handles).await;
|
||||
|
||||
let mut total_candles = 0u64;
|
||||
for result in results {
|
||||
match result {
|
||||
Ok(Ok(count)) => total_candles += count,
|
||||
Ok(Err(e)) => warn!("Daily download error: {}", e),
|
||||
Err(e) => warn!("Join error: {}", e),
|
||||
}
|
||||
}
|
||||
|
||||
info!("{}: Downloaded {} candles from daily archive", symbol_upper, total_candles);
|
||||
Ok(total_candles)
|
||||
}
|
||||
|
||||
/// Download a single day's klines
|
||||
async fn download_day_with_client(
|
||||
symbol: &str,
|
||||
date: NaiveDate,
|
||||
client: &Client,
|
||||
candle_tx: mpsc::Sender<CandleData>,
|
||||
) -> Result<u64, CollectorError> {
|
||||
let url = format!(
|
||||
"{}/{}/1m/{}-1m-{}.zip",
|
||||
DAILY_BASE_URL, symbol, symbol, date.format("%Y-%m-%d")
|
||||
);
|
||||
|
||||
let response = client.get(&url)
|
||||
.send()
|
||||
.await
|
||||
.map_err(|e| CollectorError::RestApiError(format!("Download failed: {}", e)))?;
|
||||
|
||||
if !response.status().is_success() {
|
||||
return Err(CollectorError::RestApiError(
|
||||
format!("HTTP {}: {}", response.status(), url)
|
||||
));
|
||||
}
|
||||
|
||||
let bytes = response.bytes()
|
||||
.await
|
||||
.map_err(|e| CollectorError::RestApiError(format!("Read bytes failed: {}", e)))?;
|
||||
|
||||
let cursor = Cursor::new(bytes);
|
||||
let mut archive = zip::ZipArchive::new(cursor)
|
||||
.map_err(|e| CollectorError::RestApiError(format!("ZIP error: {}", e)))?;
|
||||
|
||||
let mut csv_content = String::new();
|
||||
{
|
||||
let mut file = archive.by_index(0)
|
||||
.map_err(|e| CollectorError::RestApiError(format!("ZIP file error: {}", e)))?;
|
||||
file.read_to_string(&mut csv_content)
|
||||
.map_err(|e| CollectorError::RestApiError(format!("Read CSV error: {}", e)))?;
|
||||
}
|
||||
|
||||
let count = Self::parse_csv(symbol, &csv_content, &candle_tx).await?;
|
||||
|
||||
info!("{} {}: {} candles", symbol, date, count);
|
||||
Ok(count)
|
||||
}
|
||||
|
||||
/// Generate list of days between start and end (inclusive)
|
||||
fn generate_days(start: NaiveDate, end: NaiveDate) -> Vec<NaiveDate> {
|
||||
let mut days = Vec::new();
|
||||
let mut current = start;
|
||||
|
||||
while current <= end {
|
||||
days.push(current);
|
||||
current = current.succ_opt().unwrap_or(end);
|
||||
if current == end && days.last() == Some(&end) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
days
|
||||
}
|
||||
|
||||
/// Get timestamp for start of current month (for daily download start point)
|
||||
pub fn current_month_start() -> i64 {
|
||||
let now = Utc::now().naive_utc();
|
||||
let first_of_this_month = NaiveDate::from_ymd_opt(now.year(), now.month(), 1)
|
||||
.unwrap()
|
||||
.and_hms_opt(0, 0, 0)
|
||||
.unwrap();
|
||||
first_of_this_month.and_utc().timestamp_millis()
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
use crate::{
|
||||
DatabaseHandler, SchedulerCommand,
|
||||
CandleData, KlineQuery, ApiResponse, AddSymbolRequest, SchedulerStatus,
|
||||
};
|
||||
|
||||
use axum::{
|
||||
Router,
|
||||
routing::{get, post, delete},
|
||||
extract::{Path, Query, State},
|
||||
response::Json,
|
||||
http::StatusCode,
|
||||
};
|
||||
use std::sync::Arc;
|
||||
use tokio::sync::{mpsc, oneshot};
|
||||
|
||||
pub struct KlineChartState {
|
||||
pub db: Arc<DatabaseHandler>,
|
||||
pub command_tx: mpsc::Sender<SchedulerCommand>,
|
||||
}
|
||||
|
||||
pub fn klinechart_routes() -> Router<Arc<KlineChartState>> {
|
||||
Router::new()
|
||||
.route("/api/klines/{symbol}", get(get_klines))
|
||||
.route("/api/symbols", get(get_symbols))
|
||||
.route("/api/symbols", post(add_symbol))
|
||||
.route("/api/symbols/{symbol}", delete(remove_symbol))
|
||||
.route("/api/status", get(get_status))
|
||||
}
|
||||
|
||||
// GET /api/klines/{symbol}?limit=800&interval=1m&end_time=...
|
||||
async fn get_klines(
|
||||
State(state): State<Arc<KlineChartState>>,
|
||||
Path(symbol): Path<String>,
|
||||
Query(query): Query<KlineQuery>,
|
||||
) -> Json<ApiResponse<Vec<CandleData>>> {
|
||||
let limit = query.limit.unwrap_or(800);
|
||||
let interval = query.interval.unwrap_or_default();
|
||||
let end_time = query.end_time;
|
||||
|
||||
match state.db.get_klines_aggregated(&symbol, interval, limit, end_time).await {
|
||||
Ok(candles) => Json(ApiResponse::ok(candles)),
|
||||
Err(e) => Json(ApiResponse::err(&e.to_string())),
|
||||
}
|
||||
}
|
||||
|
||||
// GET /api/symbols
|
||||
async fn get_symbols(
|
||||
State(state): State<Arc<KlineChartState>>,
|
||||
) -> Json<ApiResponse<Vec<String>>> {
|
||||
match state.db.get_active_symbols().await {
|
||||
Ok(symbols) => Json(ApiResponse::ok(symbols)),
|
||||
Err(e) => Json(ApiResponse::err(&e.to_string())),
|
||||
}
|
||||
}
|
||||
|
||||
// POST /api/symbols
|
||||
async fn add_symbol(
|
||||
State(state): State<Arc<KlineChartState>>,
|
||||
Json(req): Json<AddSymbolRequest>,
|
||||
) -> (StatusCode, Json<ApiResponse<String>>) {
|
||||
let result = state.command_tx.send(SchedulerCommand::AddSymbol {
|
||||
symbol: req.symbol.clone(),
|
||||
backfill_from: req.backfill_from,
|
||||
}).await;
|
||||
|
||||
match result {
|
||||
Ok(_) => (StatusCode::OK, Json(ApiResponse::ok(format!("Adding symbol: {}", req.symbol)))),
|
||||
Err(e) => (StatusCode::INTERNAL_SERVER_ERROR, Json(ApiResponse::err(&e.to_string()))),
|
||||
}
|
||||
}
|
||||
|
||||
// DELETE /api/symbols/{symbol}
|
||||
async fn remove_symbol(
|
||||
State(state): State<Arc<KlineChartState>>,
|
||||
Path(symbol): Path<String>,
|
||||
) -> (StatusCode, Json<ApiResponse<String>>) {
|
||||
let result = state.command_tx.send(SchedulerCommand::RemoveSymbol {
|
||||
symbol: symbol.clone(),
|
||||
}).await;
|
||||
|
||||
match result {
|
||||
Ok(_) => (StatusCode::OK, Json(ApiResponse::ok(format!("Removing symbol: {}", symbol)))),
|
||||
Err(e) => (StatusCode::INTERNAL_SERVER_ERROR, Json(ApiResponse::err(&e.to_string()))),
|
||||
}
|
||||
}
|
||||
|
||||
// GET /api/status
|
||||
async fn get_status(
|
||||
State(state): State<Arc<KlineChartState>>,
|
||||
) -> Json<ApiResponse<SchedulerStatus>> {
|
||||
let (reply_tx, reply_rx) = oneshot::channel();
|
||||
|
||||
let send_result = state.command_tx.send(SchedulerCommand::GetStatus { reply: reply_tx }).await;
|
||||
|
||||
if send_result.is_err() {
|
||||
return Json(ApiResponse::err("Failed to send status request"));
|
||||
}
|
||||
|
||||
match reply_rx.await {
|
||||
Ok(status) => Json(ApiResponse::ok(status)),
|
||||
Err(_) => Json(ApiResponse::err("Failed to receive status")),
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
pub mod structs;
|
||||
pub use structs::*;
|
||||
|
||||
pub mod error;
|
||||
pub use error::*;
|
||||
|
||||
pub mod binance_collector;
|
||||
pub use binance_collector::*;
|
||||
|
||||
pub mod database;
|
||||
pub use database::*;
|
||||
|
||||
pub mod scheduler;
|
||||
pub use scheduler::*;
|
||||
|
||||
pub mod klinechart;
|
||||
pub use klinechart::*;
|
||||
|
||||
pub mod tradingview;
|
||||
pub use tradingview::*;
|
||||
|
||||
pub mod historical_downloader;
|
||||
pub use historical_downloader::*;
|
||||
@@ -0,0 +1,83 @@
|
||||
use backend::{
|
||||
DatabaseHandler, Scheduler, create_command_channel,
|
||||
KlineChartState, klinechart_routes,
|
||||
TradingViewState, tradingview_routes,
|
||||
CandleData,
|
||||
};
|
||||
|
||||
use axum::Router;
|
||||
use tower_http::cors::{CorsLayer, Any};
|
||||
use axum::http::Method;
|
||||
use std::sync::Arc;
|
||||
use log::info;
|
||||
use dotenv::*;
|
||||
use tokio::sync::mpsc;
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() {
|
||||
|
||||
dotenv().ok();
|
||||
env_logger::init();
|
||||
|
||||
info!("Current Version 1.4");
|
||||
|
||||
let database_url = std::env::var("DATABASE_URL")
|
||||
.unwrap_or_else(|_| "postgres://quant:2Nr!Ya&oVvY5pp@172.18.0.2:5432/crypto_database".to_string());
|
||||
|
||||
info!("Connecting to database...");
|
||||
let db = Arc::new(
|
||||
DatabaseHandler::new(&database_url)
|
||||
.await
|
||||
.expect("Failed to connect to database")
|
||||
);
|
||||
|
||||
let (command_tx, command_rx) = create_command_channel();
|
||||
|
||||
// Create TradingView state with broadcast channel
|
||||
let (tradingview_state, _) = TradingViewState::new(db.clone());
|
||||
let tradingview_state = Arc::new(tradingview_state);
|
||||
|
||||
// Create channel for WebSocket broadcasts
|
||||
let (ws_broadcast_tx, mut ws_broadcast_rx) = mpsc::channel::<CandleData>(10000);
|
||||
|
||||
// Forward candles to TradingView broadcast
|
||||
let tv_state_clone = tradingview_state.clone();
|
||||
tokio::spawn(async move {
|
||||
while let Some(candle) = ws_broadcast_rx.recv().await {
|
||||
tv_state_clone.broadcast_candle(candle);
|
||||
}
|
||||
});
|
||||
|
||||
// Start scheduler in background with ws_broadcast_tx
|
||||
let scheduler_db = db.clone();
|
||||
tokio::spawn(async move {
|
||||
let mut scheduler = Scheduler::new(scheduler_db, command_rx, Some(ws_broadcast_tx));
|
||||
scheduler.run().await;
|
||||
});
|
||||
|
||||
// KlineChart state (for klinechart frontend)
|
||||
let klinechart_state = Arc::new(KlineChartState {
|
||||
db: db.clone(),
|
||||
command_tx,
|
||||
});
|
||||
|
||||
// CORS for frontend
|
||||
let cors = CorsLayer::new()
|
||||
.allow_origin(Any)
|
||||
.allow_methods([Method::GET, Method::POST, Method::DELETE, Method::OPTIONS])
|
||||
.allow_headers(Any);
|
||||
|
||||
// Merge routes from both modules
|
||||
let app = Router::new()
|
||||
.merge(klinechart_routes().with_state(klinechart_state))
|
||||
.merge(tradingview_routes().with_state(tradingview_state))
|
||||
.layer(cors);
|
||||
|
||||
let addr = "0.0.0.0:3000";
|
||||
info!("Starting API server on {}", addr);
|
||||
info!("KlineChart API: /api/klines, /api/symbols, /api/status");
|
||||
info!("TradingView UDF: /config, /symbols, /search, /history, /time");
|
||||
|
||||
let listener = tokio::net::TcpListener::bind(addr).await.unwrap();
|
||||
axum::serve(listener, app).await.unwrap();
|
||||
}
|
||||
@@ -0,0 +1,320 @@
|
||||
use crate::database::DatabaseHandler;
|
||||
use crate::binance_collector::BinanceCollector;
|
||||
use crate::historical_downloader::HistoricalDownloader;
|
||||
use crate::error::SchedulerError;
|
||||
use crate::structs::*;
|
||||
use crate::DATA_CUTOFF_TIMESTAMP;
|
||||
|
||||
use log::{info, error, warn};
|
||||
use std::sync::Arc;
|
||||
use tokio::sync::{mpsc, RwLock};
|
||||
use tokio::task::JoinHandle;
|
||||
|
||||
const ONE_MINUTE_MS: i64 = 60_000;
|
||||
|
||||
pub struct Scheduler {
|
||||
db: Arc<DatabaseHandler>,
|
||||
command_rx: mpsc::Receiver<SchedulerCommand>,
|
||||
collector_handle: Option<JoinHandle<()>>,
|
||||
is_running: Arc<RwLock<bool>>,
|
||||
active_symbols: Arc<RwLock<Vec<String>>>,
|
||||
ws_broadcast_tx: Option<mpsc::Sender<CandleData>>,
|
||||
}
|
||||
|
||||
impl Scheduler {
|
||||
pub fn new(
|
||||
db: Arc<DatabaseHandler>,
|
||||
command_rx: mpsc::Receiver<SchedulerCommand>,
|
||||
ws_broadcast_tx: Option<mpsc::Sender<CandleData>>,
|
||||
) -> Self {
|
||||
Self {
|
||||
db,
|
||||
command_rx,
|
||||
collector_handle: None,
|
||||
is_running: Arc::new(RwLock::new(false)),
|
||||
active_symbols: Arc::new(RwLock::new(Vec::new())),
|
||||
ws_broadcast_tx,
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn run(&mut self) {
|
||||
info!("Scheduler started");
|
||||
|
||||
// Initial startup
|
||||
if let Err(e) = self.start_collector().await {
|
||||
error!("Failed to start collector on init: {}", e);
|
||||
}
|
||||
|
||||
// Command processing loop
|
||||
while let Some(cmd) = self.command_rx.recv().await {
|
||||
match cmd {
|
||||
SchedulerCommand::AddSymbol { symbol, backfill_from: _ } => {
|
||||
info!("AddSymbol command ignored - symbols managed by get_symbol()");
|
||||
let _ = self.db.add_symbol(&symbol).await;
|
||||
}
|
||||
SchedulerCommand::RemoveSymbol { symbol } => {
|
||||
info!("RemoveSymbol: {}", symbol);
|
||||
let _ = self.db.remove_symbol(&symbol).await;
|
||||
}
|
||||
SchedulerCommand::RestartCollector => {
|
||||
self.handle_restart_collector().await;
|
||||
}
|
||||
SchedulerCommand::GetStatus { reply } => {
|
||||
self.handle_get_status(reply).await;
|
||||
}
|
||||
SchedulerCommand::Shutdown => {
|
||||
info!("Shutdown command received");
|
||||
self.stop_collector().await;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
info!("Scheduler stopped");
|
||||
}
|
||||
|
||||
async fn handle_restart_collector(&mut self) {
|
||||
info!("Restarting collector...");
|
||||
self.stop_collector().await;
|
||||
if let Err(e) = self.start_collector().await {
|
||||
error!("Failed to restart collector: {}", e);
|
||||
}
|
||||
}
|
||||
|
||||
async fn handle_get_status(&self, reply: tokio::sync::oneshot::Sender<SchedulerStatus>) {
|
||||
let is_running = *self.is_running.read().await;
|
||||
let active_symbols = self.active_symbols.read().await.clone();
|
||||
let collector_connected = self.collector_handle.is_some() && is_running;
|
||||
|
||||
let _ = reply.send(SchedulerStatus {
|
||||
is_running,
|
||||
active_symbols,
|
||||
collector_connected,
|
||||
});
|
||||
}
|
||||
|
||||
async fn start_collector(&mut self) -> Result<(), SchedulerError> {
|
||||
// STEP 1: Get symbols from TRACKED_SYMBOLS env variable
|
||||
let symbol_names = DatabaseHandler::get_symbols_from_env();
|
||||
|
||||
if symbol_names.is_empty() {
|
||||
warn!("No symbols in TRACKED_SYMBOLS env variable. Set TRACKED_SYMBOLS=BTCUSDT,ETHUSDT,...");
|
||||
return Ok(());
|
||||
}
|
||||
info!("Tracking {} symbols from env: {:?}", symbol_names.len(), symbol_names);
|
||||
|
||||
// Update active symbols
|
||||
{
|
||||
let mut active = self.active_symbols.write().await;
|
||||
*active = symbol_names.clone();
|
||||
}
|
||||
|
||||
// STEP 2: Start WebSocket FIRST to capture real-time data immediately
|
||||
info!("Starting WebSocket collector FIRST (priority: real-time data)...");
|
||||
let collector = BinanceCollector::new(symbol_names.clone());
|
||||
|
||||
let (candle_tx, mut candle_rx) = mpsc::channel::<CandleData>(10000);
|
||||
|
||||
// Consumer that both saves to DB and broadcasts to WebSocket clients
|
||||
let db = self.db.clone();
|
||||
let ws_tx = self.ws_broadcast_tx.clone();
|
||||
tokio::spawn(async move {
|
||||
while let Some(candle) = candle_rx.recv().await {
|
||||
// Broadcast to WebSocket clients immediately (all updates for real-time charts)
|
||||
if let Some(ref tx) = ws_tx {
|
||||
let _ = tx.send(candle.clone()).await;
|
||||
}
|
||||
|
||||
// Only save closed candles to database
|
||||
if candle.is_closed {
|
||||
if let Err(e) = db.insert_candle(&candle).await {
|
||||
error!("Failed to insert realtime candle: {}", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
let is_running = self.is_running.clone();
|
||||
let handle = tokio::spawn(async move {
|
||||
{
|
||||
let mut running = is_running.write().await;
|
||||
*running = true;
|
||||
}
|
||||
|
||||
if let Err(e) = collector.start_stream(candle_tx).await {
|
||||
error!("Collector error: {}", e);
|
||||
}
|
||||
|
||||
{
|
||||
let mut running = is_running.write().await;
|
||||
*running = false;
|
||||
}
|
||||
});
|
||||
|
||||
self.collector_handle = Some(handle);
|
||||
info!("WebSocket collector started! Real-time data is now being captured.");
|
||||
|
||||
// STEP 3: Background sync - runs in parallel with WebSocket
|
||||
// This fills in historical data without blocking real-time updates
|
||||
let db_for_sync = self.db.clone();
|
||||
let symbols_for_sync = symbol_names.clone();
|
||||
|
||||
tokio::spawn(async move {
|
||||
info!("Starting background historical sync...");
|
||||
|
||||
// Build API clients for parallel sync
|
||||
let api_clients = BinanceCollector::build_clients().await;
|
||||
if api_clients.is_empty() {
|
||||
error!("No working API clients available for background sync");
|
||||
return;
|
||||
}
|
||||
info!("Built {} API clients for background sync", api_clients.len());
|
||||
|
||||
// Build HTTP clients for ZIP downloads
|
||||
let http_clients = HistoricalDownloader::build_clients().await;
|
||||
info!("Built {} HTTP clients for ZIP downloads", http_clients.len());
|
||||
|
||||
// Create channel for background sync (lower priority, uses batching)
|
||||
let (sync_tx, sync_rx) = mpsc::channel::<CandleData>(100000);
|
||||
|
||||
let db_consumer = db_for_sync.clone();
|
||||
let consumer_handle = tokio::spawn(async move {
|
||||
db_consumer.start_consumer(sync_rx).await;
|
||||
});
|
||||
|
||||
// Sync symbols that need updates
|
||||
let mut synced_count = 0;
|
||||
let total_symbols = symbols_for_sync.len();
|
||||
|
||||
for symbol in &symbols_for_sync {
|
||||
let latest_ts = db_for_sync.get_latest_timestamp(symbol).await.ok().flatten();
|
||||
|
||||
let start_time = match latest_ts {
|
||||
Some(ts) => ts + ONE_MINUTE_MS,
|
||||
None => DATA_CUTOFF_TIMESTAMP,
|
||||
};
|
||||
|
||||
let now = std::time::SystemTime::now()
|
||||
.duration_since(std::time::UNIX_EPOCH)
|
||||
.unwrap()
|
||||
.as_millis() as i64;
|
||||
|
||||
// Skip if less than 2 minutes behind (WebSocket will catch up)
|
||||
if now - start_time < ONE_MINUTE_MS * 2 {
|
||||
synced_count += 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
let behind_mins = (now - start_time) / ONE_MINUTE_MS;
|
||||
info!("[{}/{}] Syncing {} ({} minutes behind)...",
|
||||
synced_count + 1, total_symbols, symbol, behind_mins);
|
||||
|
||||
// Use comprehensive sync: Monthly ZIP → Daily ZIP → API
|
||||
match BinanceCollector::sync_comprehensive(
|
||||
symbol.clone(),
|
||||
start_time,
|
||||
api_clients.clone(),
|
||||
&http_clients,
|
||||
sync_tx.clone(),
|
||||
).await {
|
||||
Ok(count) => {
|
||||
synced_count += 1;
|
||||
if count > 0 {
|
||||
info!("[{}/{}] {} synced: {} candles", synced_count, total_symbols, symbol, count);
|
||||
}
|
||||
}
|
||||
Err(e) => {
|
||||
synced_count += 1;
|
||||
error!("{} sync failed: {}", symbol, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Close sync channel
|
||||
drop(sync_tx);
|
||||
let _ = consumer_handle.await;
|
||||
info!("Background historical sync complete! Synced {} symbols", synced_count);
|
||||
|
||||
// STEP 4: Gap detection and repair (also in background)
|
||||
info!("Starting background gap detection and repair...");
|
||||
let (gap_tx, gap_rx) = mpsc::channel::<CandleData>(100000);
|
||||
|
||||
let db_gap = db_for_sync.clone();
|
||||
let gap_consumer_handle = tokio::spawn(async move {
|
||||
db_gap.start_consumer(gap_rx).await;
|
||||
});
|
||||
|
||||
// Rebuild clients for gap repair
|
||||
let clients = BinanceCollector::build_clients().await;
|
||||
let mut total_gaps_repaired = 0u64;
|
||||
let mut symbols_with_gaps = 0;
|
||||
|
||||
for symbol in &symbols_for_sync {
|
||||
match db_for_sync.find_gaps(symbol, DATA_CUTOFF_TIMESTAMP).await {
|
||||
Ok(gaps) => {
|
||||
if gaps.is_empty() {
|
||||
continue;
|
||||
}
|
||||
|
||||
symbols_with_gaps += 1;
|
||||
info!("{} - Found {} gaps to repair", symbol, gaps.len());
|
||||
|
||||
for (gap_start, gap_end) in gaps {
|
||||
let gap_duration_mins = (gap_end - gap_start) / ONE_MINUTE_MS;
|
||||
|
||||
// Skip very small gaps (less than 2 minutes)
|
||||
if gap_duration_mins < 2 {
|
||||
continue;
|
||||
}
|
||||
|
||||
info!(
|
||||
"{} - Repairing gap: {} minutes",
|
||||
symbol, gap_duration_mins
|
||||
);
|
||||
|
||||
match BinanceCollector::sync_from_scratch(
|
||||
symbol.clone(),
|
||||
gap_start,
|
||||
clients.clone(),
|
||||
gap_tx.clone(),
|
||||
).await {
|
||||
Ok(count) => {
|
||||
total_gaps_repaired += count;
|
||||
}
|
||||
Err(e) => {
|
||||
error!("{} - Gap repair failed: {}", symbol, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Err(e) => {
|
||||
warn!("{} - Failed to check gaps: {}", symbol, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Close gap repair channel
|
||||
drop(gap_tx);
|
||||
let _ = gap_consumer_handle.await;
|
||||
info!("Gap detection complete! {} symbols had gaps, repaired {} candles total",
|
||||
symbols_with_gaps, total_gaps_repaired);
|
||||
});
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn stop_collector(&mut self) {
|
||||
if let Some(handle) = self.collector_handle.take() {
|
||||
info!("Stopping collector...");
|
||||
handle.abort();
|
||||
let _ = handle.await;
|
||||
|
||||
let mut running = self.is_running.write().await;
|
||||
*running = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn create_command_channel() -> (mpsc::Sender<SchedulerCommand>, mpsc::Receiver<SchedulerCommand>) {
|
||||
mpsc::channel(100)
|
||||
}
|
||||
@@ -0,0 +1,159 @@
|
||||
use serde::{Serialize, Deserialize};
|
||||
use tokio::sync::oneshot;
|
||||
|
||||
/// Data cutoff timestamp: 2024-01-01 00:00:00 UTC
|
||||
/// Data before this timestamp will not be synced
|
||||
pub const DATA_CUTOFF_TIMESTAMP: i64 = 1704067200000;
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct CandleData {
|
||||
pub symbol: String,
|
||||
pub timestamp: i64,
|
||||
pub open: f64,
|
||||
pub high: f64,
|
||||
pub low: f64,
|
||||
pub close: f64,
|
||||
pub volume: f64,
|
||||
pub taker_buy_volume: f64,
|
||||
pub net_volume: f64,
|
||||
pub is_closed: bool,
|
||||
}
|
||||
|
||||
impl CandleData {
|
||||
pub fn calculate_net_volume(total_volume: f64, taker_buy_volume: f64) -> f64 {
|
||||
2.0 * taker_buy_volume - total_volume
|
||||
}
|
||||
}
|
||||
|
||||
/// Commands for controlling the Scheduler
|
||||
pub enum SchedulerCommand {
|
||||
/// Add a new symbol to track. Triggers backfill then collector restart.
|
||||
AddSymbol {
|
||||
symbol: String,
|
||||
backfill_from: Option<i64>, // None = use EARLIEST_TIME
|
||||
},
|
||||
|
||||
/// Remove a symbol from tracking. Triggers collector restart.
|
||||
RemoveSymbol { symbol: String },
|
||||
|
||||
/// Restart the collector with current active symbols from database
|
||||
RestartCollector,
|
||||
|
||||
/// Get current scheduler status
|
||||
GetStatus { reply: oneshot::Sender<SchedulerStatus> },
|
||||
|
||||
/// Graceful shutdown
|
||||
Shutdown,
|
||||
}
|
||||
|
||||
/// Scheduler status for API responses
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct SchedulerStatus {
|
||||
pub is_running: bool,
|
||||
pub active_symbols: Vec<String>,
|
||||
pub collector_connected: bool,
|
||||
}
|
||||
|
||||
// API Request/Response structs
|
||||
|
||||
#[derive(Debug, Clone, Copy, Deserialize, PartialEq)]
|
||||
#[serde(rename_all = "lowercase")]
|
||||
pub enum Interval {
|
||||
#[serde(rename = "1m")]
|
||||
Min1,
|
||||
#[serde(rename = "5m")]
|
||||
Min5,
|
||||
#[serde(rename = "15m")]
|
||||
Min15,
|
||||
#[serde(rename = "1h")]
|
||||
Hour1,
|
||||
#[serde(rename = "4h")]
|
||||
Hour4,
|
||||
#[serde(rename = "1d")]
|
||||
Day1,
|
||||
#[serde(rename = "1w")]
|
||||
Week1,
|
||||
#[serde(rename = "1M")]
|
||||
Month1,
|
||||
}
|
||||
|
||||
impl Default for Interval {
|
||||
fn default() -> Self {
|
||||
Interval::Min1
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
pub struct KlineQuery {
|
||||
pub limit: Option<i64>,
|
||||
pub interval: Option<Interval>,
|
||||
pub end_time: Option<i64>,
|
||||
}
|
||||
|
||||
#[derive(Serialize)]
|
||||
pub struct ApiResponse<T> {
|
||||
pub success: bool,
|
||||
pub data: Option<T>,
|
||||
pub error: Option<String>,
|
||||
}
|
||||
|
||||
impl<T> ApiResponse<T> {
|
||||
pub fn ok(data: T) -> Self {
|
||||
Self { success: true, data: Some(data), error: None }
|
||||
}
|
||||
|
||||
pub fn err(msg: &str) -> Self {
|
||||
Self { success: false, data: None, error: Some(msg.to_string()) }
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
pub struct AddSymbolRequest {
|
||||
pub symbol: String,
|
||||
pub backfill_from: Option<i64>,
|
||||
}
|
||||
|
||||
#[derive(Serialize,Deserialize,Debug,Clone)]
|
||||
pub struct Symbol{
|
||||
|
||||
pub symbol: String,
|
||||
pub start_timestamp: i64,
|
||||
}
|
||||
|
||||
// WebSocket message types
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
#[serde(tag = "type", content = "data")]
|
||||
pub enum WsMessage {
|
||||
/// Kline update for a symbol
|
||||
#[serde(rename = "kline")]
|
||||
Kline(CandleData),
|
||||
|
||||
/// Ticker update with price info for watchlist
|
||||
#[serde(rename = "ticker")]
|
||||
Ticker(TickerUpdate),
|
||||
|
||||
/// Subscribe to symbols
|
||||
#[serde(rename = "subscribe")]
|
||||
Subscribe { symbols: Vec<String> },
|
||||
|
||||
/// Unsubscribe from symbols
|
||||
#[serde(rename = "unsubscribe")]
|
||||
Unsubscribe { symbols: Vec<String> },
|
||||
|
||||
/// Ping/Pong for keepalive
|
||||
#[serde(rename = "ping")]
|
||||
Ping,
|
||||
|
||||
#[serde(rename = "pong")]
|
||||
Pong,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct TickerUpdate {
|
||||
pub symbol: String,
|
||||
pub price: f64,
|
||||
pub change_24h: f64,
|
||||
pub change_percent_24h: f64,
|
||||
pub volume_24h: f64,
|
||||
pub timestamp: i64,
|
||||
}
|
||||
@@ -0,0 +1,559 @@
|
||||
use crate::{DatabaseHandler, Interval, CandleData, WsMessage};
|
||||
|
||||
use axum::{
|
||||
Router,
|
||||
routing::{get, post, delete},
|
||||
extract::{Query, State, WebSocketUpgrade, ws::{Message, WebSocket}},
|
||||
response::{Json, IntoResponse},
|
||||
http::StatusCode,
|
||||
};
|
||||
use futures::{StreamExt, SinkExt};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::collections::HashSet;
|
||||
use std::sync::Arc;
|
||||
use std::time::{SystemTime, UNIX_EPOCH};
|
||||
use std::path::PathBuf;
|
||||
use tokio::sync::{broadcast, RwLock};
|
||||
use tokio::fs;
|
||||
use log::{info, warn, debug, error};
|
||||
|
||||
pub struct TradingViewState {
|
||||
pub db: Arc<DatabaseHandler>,
|
||||
pub candle_tx: broadcast::Sender<CandleData>,
|
||||
}
|
||||
|
||||
impl TradingViewState {
|
||||
pub fn new(db: Arc<DatabaseHandler>) -> (Self, broadcast::Receiver<CandleData>) {
|
||||
let (candle_tx, candle_rx) = broadcast::channel(10000);
|
||||
(Self { db, candle_tx }, candle_rx)
|
||||
}
|
||||
|
||||
/// Send a candle update to all connected WebSocket clients
|
||||
pub fn broadcast_candle(&self, candle: CandleData) {
|
||||
// Ignore errors (no subscribers)
|
||||
let _ = self.candle_tx.send(candle);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn tradingview_routes() -> Router<Arc<TradingViewState>> {
|
||||
Router::new()
|
||||
.route("/config", get(get_config))
|
||||
.route("/time", get(get_time))
|
||||
.route("/symbols", get(get_symbol_info))
|
||||
.route("/search", get(search_symbols))
|
||||
.route("/tracked-symbols", get(get_tracked_symbols))
|
||||
.route("/daily-opens", get(get_daily_opens))
|
||||
.route("/history", get(get_history))
|
||||
.route("/ws", get(ws_handler))
|
||||
// Canvas API
|
||||
.route("/canvas/list", get(canvas_list))
|
||||
.route("/canvas/load", get(canvas_load))
|
||||
.route("/canvas/save", post(canvas_save))
|
||||
.route("/canvas/delete", delete(canvas_delete))
|
||||
}
|
||||
|
||||
// ============ UDF Response Types ============
|
||||
|
||||
#[derive(Serialize)]
|
||||
struct UdfConfig {
|
||||
supported_resolutions: Vec<&'static str>,
|
||||
supports_group_request: bool,
|
||||
supports_marks: bool,
|
||||
supports_search: bool,
|
||||
supports_timescale_marks: bool,
|
||||
}
|
||||
|
||||
#[derive(Serialize)]
|
||||
struct UdfSymbolInfo {
|
||||
symbol: String,
|
||||
ticker: String,
|
||||
name: String,
|
||||
full_name: String,
|
||||
description: String,
|
||||
exchange: String,
|
||||
listed_exchange: String,
|
||||
#[serde(rename = "type")]
|
||||
symbol_type: String,
|
||||
currency_code: String,
|
||||
session: String,
|
||||
timezone: String,
|
||||
minmovement: i32,
|
||||
minmov: i32,
|
||||
minmovement2: i32,
|
||||
minmov2: i32,
|
||||
pricescale: i64,
|
||||
supported_resolutions: Vec<&'static str>,
|
||||
has_intraday: bool,
|
||||
has_daily: bool,
|
||||
has_weekly_and_monthly: bool,
|
||||
data_status: String,
|
||||
}
|
||||
|
||||
#[derive(Serialize)]
|
||||
struct UdfSearchResult {
|
||||
symbol: String,
|
||||
full_name: String,
|
||||
description: String,
|
||||
exchange: String,
|
||||
ticker: String,
|
||||
#[serde(rename = "type")]
|
||||
symbol_type: String,
|
||||
}
|
||||
|
||||
#[derive(Serialize)]
|
||||
#[serde(untagged)]
|
||||
enum UdfHistoryResponse {
|
||||
Ok {
|
||||
s: String, // "ok"
|
||||
t: Vec<i64>, // timestamps (seconds)
|
||||
o: Vec<f64>, // open
|
||||
h: Vec<f64>, // high
|
||||
l: Vec<f64>, // low
|
||||
c: Vec<f64>, // close
|
||||
v: Vec<f64>, // volume
|
||||
nv: Vec<f64>, // net volume (custom)
|
||||
tbv: Vec<f64>, // taker buy volume (custom)
|
||||
},
|
||||
NoData {
|
||||
s: String, // "no_data"
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
#[serde(rename = "nextTime")]
|
||||
next_time: Option<i64>,
|
||||
},
|
||||
Error {
|
||||
s: String, // "error"
|
||||
errmsg: String,
|
||||
},
|
||||
}
|
||||
|
||||
// ============ Query Parameters ============
|
||||
|
||||
#[derive(Deserialize)]
|
||||
struct SymbolQuery {
|
||||
symbol: String,
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
#[derive(Deserialize)]
|
||||
struct SearchQuery {
|
||||
query: Option<String>,
|
||||
#[serde(rename = "type")]
|
||||
symbol_type: Option<String>,
|
||||
exchange: Option<String>,
|
||||
limit: Option<i32>,
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
struct HistoryQuery {
|
||||
symbol: String,
|
||||
resolution: String,
|
||||
from: i64, // unix timestamp (seconds)
|
||||
to: i64, // unix timestamp (seconds)
|
||||
countback: Option<i64>,
|
||||
}
|
||||
|
||||
// ============ Handlers ============
|
||||
|
||||
// GET /config
|
||||
async fn get_config() -> Json<UdfConfig> {
|
||||
Json(UdfConfig {
|
||||
supported_resolutions: vec!["1", "5", "15", "60", "240", "1D", "1W", "1M"],
|
||||
supports_group_request: false,
|
||||
supports_marks: false,
|
||||
supports_search: true,
|
||||
supports_timescale_marks: false,
|
||||
})
|
||||
}
|
||||
|
||||
// GET /time
|
||||
async fn get_time() -> String {
|
||||
let now = SystemTime::now()
|
||||
.duration_since(UNIX_EPOCH)
|
||||
.unwrap()
|
||||
.as_secs();
|
||||
now.to_string()
|
||||
}
|
||||
|
||||
// GET /symbols?symbol=BTCUSDT
|
||||
async fn get_symbol_info(
|
||||
Query(query): Query<SymbolQuery>,
|
||||
) -> Json<UdfSymbolInfo> {
|
||||
let symbol = query.symbol.to_uppercase();
|
||||
|
||||
Json(UdfSymbolInfo {
|
||||
symbol: symbol.clone(),
|
||||
ticker: symbol.clone(),
|
||||
name: symbol.clone(),
|
||||
full_name: format!("BINANCE:{}", symbol),
|
||||
description: symbol.clone(),
|
||||
exchange: "BINANCE".to_string(),
|
||||
listed_exchange: "BINANCE".to_string(),
|
||||
symbol_type: "crypto".to_string(),
|
||||
currency_code: "USDT".to_string(),
|
||||
session: "24x7".to_string(),
|
||||
timezone: "Etc/UTC".to_string(),
|
||||
minmovement: 1,
|
||||
minmov: 1,
|
||||
minmovement2: 0,
|
||||
minmov2: 0,
|
||||
pricescale: 100000000, // 8 decimal places for crypto
|
||||
supported_resolutions: vec!["1", "5", "15", "60", "240", "1D", "1W", "1M"],
|
||||
has_intraday: true,
|
||||
has_daily: true,
|
||||
has_weekly_and_monthly: true,
|
||||
data_status: "streaming".to_string(),
|
||||
})
|
||||
}
|
||||
|
||||
// GET /tracked-symbols - 返回 TRACKED_SYMBOL 环境变量中配置的 symbols
|
||||
async fn get_tracked_symbols() -> Json<Vec<String>> {
|
||||
Json(crate::DatabaseHandler::get_symbols_from_env())
|
||||
}
|
||||
|
||||
// GET /daily-opens - 返回所有 symbol 当天 UTC 00:00 的开盘价
|
||||
async fn get_daily_opens(
|
||||
State(state): State<Arc<TradingViewState>>,
|
||||
) -> Json<std::collections::HashMap<String, f64>> {
|
||||
match state.db.get_daily_opens().await {
|
||||
Ok(opens) => Json(opens),
|
||||
Err(_) => Json(std::collections::HashMap::new()),
|
||||
}
|
||||
}
|
||||
|
||||
// GET /search?query=BTC&limit=10
|
||||
async fn search_symbols(
|
||||
State(state): State<Arc<TradingViewState>>,
|
||||
Query(query): Query<SearchQuery>,
|
||||
) -> Json<Vec<UdfSearchResult>> {
|
||||
let search_term = query.query.unwrap_or_default().to_uppercase();
|
||||
let limit = query.limit.unwrap_or(30) as usize;
|
||||
|
||||
let symbols = match state.db.get_active_symbols().await {
|
||||
Ok(s) => s,
|
||||
Err(_) => return Json(vec![]),
|
||||
};
|
||||
|
||||
let results: Vec<UdfSearchResult> = symbols
|
||||
.into_iter()
|
||||
.filter(|s| search_term.is_empty() || s.to_uppercase().contains(&search_term))
|
||||
.take(limit)
|
||||
.map(|s| {
|
||||
let upper = s.to_uppercase();
|
||||
UdfSearchResult {
|
||||
symbol: upper.clone(),
|
||||
full_name: format!("BINANCE:{}", upper),
|
||||
description: upper.clone(),
|
||||
exchange: "BINANCE".to_string(),
|
||||
ticker: upper,
|
||||
symbol_type: "crypto".to_string(),
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
|
||||
Json(results)
|
||||
}
|
||||
|
||||
// GET /history?symbol=BTCUSDT&resolution=1&from=...&to=...
|
||||
async fn get_history(
|
||||
State(state): State<Arc<TradingViewState>>,
|
||||
Query(query): Query<HistoryQuery>,
|
||||
) -> Json<UdfHistoryResponse> {
|
||||
let symbol = query.symbol.to_uppercase();
|
||||
|
||||
// Convert resolution string to Interval enum
|
||||
let interval = match query.resolution.as_str() {
|
||||
"1" => Interval::Min1,
|
||||
"5" => Interval::Min5,
|
||||
"15" => Interval::Min15,
|
||||
"60" => Interval::Hour1,
|
||||
"240" => Interval::Hour4,
|
||||
"D" | "1D" => Interval::Day1,
|
||||
"W" | "1W" => Interval::Week1,
|
||||
"M" | "1M" => Interval::Month1,
|
||||
_ => Interval::Min1,
|
||||
};
|
||||
|
||||
// Convert from/to (seconds) to milliseconds for database query
|
||||
let from_ms = query.from * 1000;
|
||||
let to_ms = query.to * 1000;
|
||||
|
||||
// Calculate limit based on countback or time range
|
||||
let limit = query.countback.unwrap_or(1000);
|
||||
|
||||
match state.db.get_klines_aggregated(&symbol, interval, limit, Some(to_ms)).await {
|
||||
Ok(candles) => {
|
||||
// Filter by from_ms and convert to UDF format
|
||||
let filtered: Vec<_> = candles
|
||||
.into_iter()
|
||||
.filter(|c| c.timestamp >= from_ms && c.timestamp <= to_ms)
|
||||
.collect();
|
||||
|
||||
if filtered.is_empty() {
|
||||
return Json(UdfHistoryResponse::NoData {
|
||||
s: "no_data".to_string(),
|
||||
next_time: None,
|
||||
});
|
||||
}
|
||||
|
||||
let t: Vec<i64> = filtered.iter().map(|c| c.timestamp / 1000).collect();
|
||||
let o: Vec<f64> = filtered.iter().map(|c| c.open).collect();
|
||||
let h: Vec<f64> = filtered.iter().map(|c| c.high).collect();
|
||||
let l: Vec<f64> = filtered.iter().map(|c| c.low).collect();
|
||||
let c: Vec<f64> = filtered.iter().map(|c| c.close).collect();
|
||||
let v: Vec<f64> = filtered.iter().map(|c| c.volume).collect();
|
||||
let nv: Vec<f64> = filtered.iter().map(|c| c.net_volume).collect();
|
||||
let tbv: Vec<f64> = filtered.iter().map(|c| c.taker_buy_volume).collect();
|
||||
|
||||
Json(UdfHistoryResponse::Ok {
|
||||
s: "ok".to_string(),
|
||||
t, o, h, l, c, v, nv, tbv,
|
||||
})
|
||||
}
|
||||
Err(e) => Json(UdfHistoryResponse::Error {
|
||||
s: "error".to_string(),
|
||||
errmsg: e.to_string(),
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
||||
// ============ WebSocket Handler ============
|
||||
|
||||
async fn ws_handler(
|
||||
ws: WebSocketUpgrade,
|
||||
State(state): State<Arc<TradingViewState>>,
|
||||
) -> impl IntoResponse {
|
||||
ws.on_upgrade(move |socket| handle_ws_connection(socket, state))
|
||||
}
|
||||
|
||||
async fn handle_ws_connection(socket: WebSocket, state: Arc<TradingViewState>) {
|
||||
let (mut sender, mut receiver) = socket.split();
|
||||
|
||||
// Subscribe to broadcast channel
|
||||
let mut candle_rx = state.candle_tx.subscribe();
|
||||
|
||||
// Subscribed symbols for this client
|
||||
let subscribed_symbols: Arc<RwLock<HashSet<String>>> = Arc::new(RwLock::new(HashSet::new()));
|
||||
let subscribed_symbols_clone = subscribed_symbols.clone();
|
||||
|
||||
info!("WebSocket client connected");
|
||||
|
||||
// Task to receive messages from client
|
||||
let recv_task = tokio::spawn(async move {
|
||||
while let Some(msg) = receiver.next().await {
|
||||
match msg {
|
||||
Ok(Message::Text(text)) => {
|
||||
// Parse incoming message
|
||||
if let Ok(ws_msg) = serde_json::from_str::<WsMessage>(&text) {
|
||||
match ws_msg {
|
||||
WsMessage::Subscribe { symbols } => {
|
||||
let mut subs = subscribed_symbols_clone.write().await;
|
||||
for s in symbols {
|
||||
subs.insert(s.to_uppercase());
|
||||
}
|
||||
debug!("Client subscribed to {} symbols", subs.len());
|
||||
}
|
||||
WsMessage::Unsubscribe { symbols } => {
|
||||
let mut subs = subscribed_symbols_clone.write().await;
|
||||
for s in symbols {
|
||||
subs.remove(&s.to_uppercase());
|
||||
}
|
||||
}
|
||||
WsMessage::Ping => {
|
||||
// Pong is handled by the send task
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(Message::Close(_)) => {
|
||||
info!("WebSocket client disconnected");
|
||||
break;
|
||||
}
|
||||
Err(e) => {
|
||||
warn!("WebSocket receive error: {}", e);
|
||||
break;
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Task to send messages to client
|
||||
let send_task = tokio::spawn(async move {
|
||||
loop {
|
||||
tokio::select! {
|
||||
// Forward candle updates to client
|
||||
result = candle_rx.recv() => {
|
||||
match result {
|
||||
Ok(candle) => {
|
||||
let subs = subscribed_symbols.read().await;
|
||||
// Send to client if subscribed or if subscribed to all (empty set means all)
|
||||
if subs.is_empty() || subs.contains(&candle.symbol.to_uppercase()) {
|
||||
let msg = WsMessage::Kline(candle);
|
||||
if let Ok(json) = serde_json::to_string(&msg) {
|
||||
if sender.send(Message::Text(json.into())).await.is_err() {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Err(broadcast::error::RecvError::Lagged(n)) => {
|
||||
warn!("WebSocket client lagged {} messages", n);
|
||||
}
|
||||
Err(broadcast::error::RecvError::Closed) => {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Wait for either task to finish
|
||||
tokio::select! {
|
||||
_ = recv_task => {}
|
||||
_ = send_task => {}
|
||||
}
|
||||
|
||||
info!("WebSocket connection closed");
|
||||
}
|
||||
|
||||
// ============ Canvas API ============
|
||||
|
||||
const STORAGE_DIR: &str = "storage";
|
||||
const DEFAULT_USER: &str = "default";
|
||||
|
||||
#[derive(Deserialize)]
|
||||
struct CanvasListQuery {
|
||||
symbol: String,
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
struct CanvasLoadQuery {
|
||||
symbol: String,
|
||||
name: String,
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
struct CanvasSaveBody {
|
||||
symbol: String,
|
||||
name: String,
|
||||
data: serde_json::Value,
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
struct CanvasDeleteQuery {
|
||||
symbol: String,
|
||||
name: String,
|
||||
}
|
||||
|
||||
#[derive(Serialize)]
|
||||
struct CanvasListResponse {
|
||||
canvases: Vec<String>,
|
||||
}
|
||||
|
||||
fn get_user_id(headers: &axum::http::HeaderMap) -> String {
|
||||
headers.get("X-User-Id")
|
||||
.and_then(|v| v.to_str().ok())
|
||||
.filter(|s| !s.is_empty())
|
||||
.unwrap_or(DEFAULT_USER)
|
||||
.to_string()
|
||||
}
|
||||
|
||||
fn get_canvas_dir(user_id: &str, symbol: &str) -> PathBuf {
|
||||
PathBuf::from(STORAGE_DIR)
|
||||
.join(user_id)
|
||||
.join(symbol.to_uppercase())
|
||||
}
|
||||
|
||||
fn get_canvas_path(user_id: &str, symbol: &str, name: &str) -> PathBuf {
|
||||
get_canvas_dir(user_id, symbol).join(format!("{}.json", name))
|
||||
}
|
||||
|
||||
// GET /canvas/list?symbol=BTCUSDT
|
||||
async fn canvas_list(headers: axum::http::HeaderMap, Query(query): Query<CanvasListQuery>) -> Json<CanvasListResponse> {
|
||||
let user_id = get_user_id(&headers);
|
||||
let dir = get_canvas_dir(&user_id, &query.symbol);
|
||||
let mut canvases = Vec::new();
|
||||
|
||||
if let Ok(mut entries) = fs::read_dir(&dir).await {
|
||||
while let Ok(Some(entry)) = entries.next_entry().await {
|
||||
if let Some(name) = entry.file_name().to_str() {
|
||||
if name.ends_with(".json") {
|
||||
canvases.push(name.trim_end_matches(".json").to_string());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
canvases.sort();
|
||||
Json(CanvasListResponse { canvases })
|
||||
}
|
||||
|
||||
// GET /canvas/load?symbol=BTCUSDT&name=default
|
||||
async fn canvas_load(
|
||||
headers: axum::http::HeaderMap,
|
||||
Query(query): Query<CanvasLoadQuery>,
|
||||
) -> Result<Json<serde_json::Value>, StatusCode> {
|
||||
let user_id = get_user_id(&headers);
|
||||
let path = get_canvas_path(&user_id, &query.symbol, &query.name);
|
||||
|
||||
match fs::read_to_string(&path).await {
|
||||
Ok(content) => {
|
||||
match serde_json::from_str(&content) {
|
||||
Ok(data) => Ok(Json(data)),
|
||||
Err(e) => {
|
||||
error!("Failed to parse canvas {}: {}", path.display(), e);
|
||||
Err(StatusCode::INTERNAL_SERVER_ERROR)
|
||||
}
|
||||
}
|
||||
}
|
||||
Err(_) => Err(StatusCode::NOT_FOUND),
|
||||
}
|
||||
}
|
||||
|
||||
// POST /canvas/save
|
||||
async fn canvas_save(
|
||||
headers: axum::http::HeaderMap,
|
||||
Json(body): Json<CanvasSaveBody>,
|
||||
) -> Result<StatusCode, StatusCode> {
|
||||
let user_id = get_user_id(&headers);
|
||||
let dir = get_canvas_dir(&user_id, &body.symbol);
|
||||
let path = get_canvas_path(&user_id, &body.symbol, &body.name);
|
||||
|
||||
// Create directory if not exists
|
||||
if let Err(e) = fs::create_dir_all(&dir).await {
|
||||
error!("Failed to create dir {}: {}", dir.display(), e);
|
||||
return Err(StatusCode::INTERNAL_SERVER_ERROR);
|
||||
}
|
||||
|
||||
// Write canvas data
|
||||
let content = serde_json::to_string_pretty(&body.data)
|
||||
.map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?;
|
||||
|
||||
fs::write(&path, content).await
|
||||
.map_err(|e| {
|
||||
error!("Failed to write canvas {}: {}", path.display(), e);
|
||||
StatusCode::INTERNAL_SERVER_ERROR
|
||||
})?;
|
||||
|
||||
info!("Saved canvas: {}", path.display());
|
||||
Ok(StatusCode::OK)
|
||||
}
|
||||
|
||||
// DELETE /canvas/delete?symbol=BTCUSDT&name=default
|
||||
async fn canvas_delete(
|
||||
headers: axum::http::HeaderMap,
|
||||
Query(query): Query<CanvasDeleteQuery>,
|
||||
) -> StatusCode {
|
||||
let user_id = get_user_id(&headers);
|
||||
let path = get_canvas_path(&user_id, &query.symbol, &query.name);
|
||||
|
||||
match fs::remove_file(&path).await {
|
||||
Ok(_) => {
|
||||
info!("Deleted canvas: {}", path.display());
|
||||
StatusCode::OK
|
||||
}
|
||||
Err(_) => StatusCode::NOT_FOUND,
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
use backend::{BinanceCollector, CandleData};
|
||||
use tokio::sync::mpsc;
|
||||
use tokio::time::{timeout, Duration};
|
||||
use dotenv::dotenv;
|
||||
use log::{info,error,debug};
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_backfill_and_stream() {
|
||||
|
||||
dotenv().ok();
|
||||
env_logger::init();
|
||||
|
||||
let collector = BinanceCollector::new(vec!["btcusdt".to_string(), "ethusdt".to_string()]);
|
||||
let (tx, mut rx) = mpsc::channel::<CandleData>(1000);
|
||||
|
||||
// Calculate time range: last 10 minutes
|
||||
let now = std::time::SystemTime::now()
|
||||
.duration_since(std::time::UNIX_EPOCH)
|
||||
.unwrap()
|
||||
.as_millis() as i64;
|
||||
let start_time = now - (10 * 60 * 1000); // 10 minutes ago
|
||||
|
||||
// First, backfill recent data for btcusdt
|
||||
info!("Starting backfill...");
|
||||
let backfill_count = collector.backfill("btcusdt", start_time, now, &tx).await.unwrap();
|
||||
info!("Backfill completed: {} candles", backfill_count);
|
||||
|
||||
// Then start WebSocket stream
|
||||
let collector_handle = tokio::spawn(async move {
|
||||
collector.start_stream(tx).await
|
||||
});
|
||||
|
||||
let mut received_count = 0;
|
||||
|
||||
// Drain backfill data first
|
||||
while let Ok(Some(candle)) = timeout(Duration::from_millis(100), rx.recv()).await {
|
||||
info!(
|
||||
"[BACKFILL] {} ts={} c={:.2} net_vol={:.4}",
|
||||
candle.symbol, candle.timestamp, candle.close, candle.net_volume
|
||||
);
|
||||
received_count += 1;
|
||||
}
|
||||
info!("Received {} backfill candles from channel", received_count);
|
||||
|
||||
// Wait for WebSocket data (up to 90 seconds for at least 1 closed candle)
|
||||
let mut ws_count = 0;
|
||||
let ws_result = timeout(Duration::from_secs(90), async {
|
||||
while let Some(candle) = rx.recv().await {
|
||||
info!(
|
||||
"[WEBSOCKET] {} ts={} c={:.2} net_vol={:.4}",
|
||||
candle.symbol, candle.timestamp, candle.close, candle.net_volume
|
||||
);
|
||||
ws_count += 1;
|
||||
if ws_count >= 1 {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
false
|
||||
}).await;
|
||||
|
||||
collector_handle.abort();
|
||||
|
||||
info!("\nFinal: Backfill={}, WebSocket={}", backfill_count, ws_count);
|
||||
|
||||
assert!(backfill_count >= 5, "Expected at least 5 backfill candles, got {}", backfill_count);
|
||||
|
||||
match ws_result {
|
||||
Ok(true) => info!("Test completed successfully!"),
|
||||
Ok(false) => info!("WebSocket closed before receiving data"),
|
||||
Err(_) => info!("WebSocket timed out (normal if test runs mid-minute)"),
|
||||
}
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
|
||||
async fn test_get_symbol() {
|
||||
|
||||
dotenv().ok();
|
||||
env_logger::init();
|
||||
|
||||
let collector = BinanceCollector::new(vec!["btcusdt".to_string(), "ethusdt".to_string()]);
|
||||
|
||||
let result = BinanceCollector::get_symbol().await.unwrap();
|
||||
|
||||
info!("Result = {:?}",result);
|
||||
}
|
||||
@@ -0,0 +1,128 @@
|
||||
use backend::{DatabaseHandler, CandleData};
|
||||
use tokio::sync::mpsc;
|
||||
use dotenv::dotenv;
|
||||
use log::info;
|
||||
use std::env;
|
||||
|
||||
fn get_database_url() -> String {
|
||||
|
||||
dotenv().ok();
|
||||
env::var("DATABASE_URL").unwrap_or_else(|_| {
|
||||
"postgres://quant:2Nr!Ya&oVvY5pp@172.18.0.10:5432/crypto_database".to_string()
|
||||
})
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_database_connection() {
|
||||
|
||||
dotenv().ok();
|
||||
env_logger::init();
|
||||
|
||||
let db_url = get_database_url();
|
||||
info!("Connecting to database...");
|
||||
|
||||
let db = DatabaseHandler::new(&db_url).await;
|
||||
assert!(db.is_ok(), "Failed to connect to database: {:?}", db.err());
|
||||
|
||||
info!("Database connection successful!");
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_get_active_symbols() {
|
||||
|
||||
dotenv().ok();
|
||||
env_logger::init();
|
||||
|
||||
let db_url = get_database_url();
|
||||
let db = DatabaseHandler::new(&db_url).await.expect("Failed to connect");
|
||||
|
||||
let symbols = db.get_active_symbols().await;
|
||||
info!("Active symbols: {:?}", symbols);
|
||||
|
||||
assert!(symbols.is_ok(), "Failed to get active symbols: {:?}", symbols.err());
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_insert_and_query() {
|
||||
|
||||
dotenv().ok();
|
||||
env_logger::init();
|
||||
|
||||
let db_url = get_database_url();
|
||||
let db = DatabaseHandler::new(&db_url).await.expect("Failed to connect");
|
||||
|
||||
// Create test candle
|
||||
let test_candle = CandleData {
|
||||
symbol: "TESTUSDT".to_string(),
|
||||
timestamp: 1700000000000, // Fixed test timestamp
|
||||
open: 100.0,
|
||||
high: 105.0,
|
||||
low: 99.0,
|
||||
close: 102.0,
|
||||
volume: 1000.0,
|
||||
taker_buy_volume: 600.0,
|
||||
net_volume: 200.0,
|
||||
is_closed: true,
|
||||
};
|
||||
|
||||
// Insert
|
||||
let result = db.insert_candle(&test_candle).await;
|
||||
assert!(result.is_ok(), "Failed to insert candle: {:?}", result.err());
|
||||
info!("Inserted test candle");
|
||||
|
||||
// Query latest timestamp
|
||||
let latest = db.get_latest_timestamp("TESTUSDT").await;
|
||||
assert!(latest.is_ok(), "Failed to get latest timestamp: {:?}", latest.err());
|
||||
|
||||
let ts = latest.unwrap();
|
||||
assert!(ts.is_some(), "No timestamp found for TESTUSDT");
|
||||
assert_eq!(ts.unwrap(), 1700000000000, "Timestamp mismatch");
|
||||
|
||||
info!("Latest timestamp for TESTUSDT: {:?}", ts);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_batch_consumer() {
|
||||
|
||||
dotenv().ok();
|
||||
env_logger::init();
|
||||
|
||||
let db_url = get_database_url();
|
||||
let db = DatabaseHandler::new(&db_url).await.expect("Failed to connect");
|
||||
|
||||
let (tx, rx) = mpsc::channel::<CandleData>(100);
|
||||
|
||||
// Spawn consumer
|
||||
let db_handle = tokio::spawn(async move {
|
||||
db.start_consumer(rx).await;
|
||||
});
|
||||
|
||||
// Send test candles
|
||||
let base_ts = 1700000100000i64;
|
||||
for i in 0..10 {
|
||||
let candle = CandleData {
|
||||
symbol: "BATCHTEST".to_string(),
|
||||
timestamp: base_ts + (i * 60000),
|
||||
open: 100.0 + i as f64,
|
||||
high: 105.0 + i as f64,
|
||||
low: 99.0 + i as f64,
|
||||
close: 102.0 + i as f64,
|
||||
volume: 1000.0,
|
||||
taker_buy_volume: 600.0,
|
||||
net_volume: 200.0,
|
||||
is_closed: true,
|
||||
};
|
||||
tx.send(candle).await.unwrap();
|
||||
}
|
||||
|
||||
// Close channel to trigger flush
|
||||
drop(tx);
|
||||
|
||||
// Wait for consumer to finish
|
||||
let _ = tokio::time::timeout(
|
||||
tokio::time::Duration::from_secs(10),
|
||||
db_handle
|
||||
).await;
|
||||
|
||||
info!("Batch insert test completed");
|
||||
}
|
||||
@@ -0,0 +1,322 @@
|
||||
use backend::{
|
||||
Scheduler, DatabaseHandler, SchedulerCommand,
|
||||
create_command_channel,
|
||||
};
|
||||
use std::sync::Arc;
|
||||
use tokio::sync::oneshot;
|
||||
use tokio::time::{timeout, Duration};
|
||||
use dotenv::dotenv;
|
||||
use log::info;
|
||||
use std::env;
|
||||
|
||||
fn get_database_url() -> String {
|
||||
dotenv().ok();
|
||||
env::var("DATABASE_URL").unwrap_or_else(|_| {
|
||||
"postgres://quant:2Nr!Ya&oVvY5pp@172.18.0.2:5432/crypto_database".to_string()
|
||||
})
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_scheduler_startup_and_shutdown() {
|
||||
|
||||
dotenv().ok();
|
||||
env_logger::try_init().ok();
|
||||
|
||||
let db_url = get_database_url();
|
||||
let db = Arc::new(DatabaseHandler::new(&db_url).await.expect("Failed to connect to database"));
|
||||
|
||||
let (command_tx, command_rx) = create_command_channel();
|
||||
let mut scheduler = Scheduler::new(db.clone(), command_rx, None);
|
||||
|
||||
// Start scheduler in background
|
||||
let scheduler_handle = tokio::spawn(async move {
|
||||
scheduler.run().await;
|
||||
});
|
||||
|
||||
// Give it time to start
|
||||
tokio::time::sleep(Duration::from_secs(2)).await;
|
||||
|
||||
// Send shutdown command
|
||||
command_tx.send(SchedulerCommand::Shutdown).await.expect("Failed to send shutdown");
|
||||
|
||||
// Wait for scheduler to stop
|
||||
let result = timeout(Duration::from_secs(10), scheduler_handle).await;
|
||||
assert!(result.is_ok(), "Scheduler did not shutdown in time");
|
||||
|
||||
info!("Scheduler startup and shutdown test passed");
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_get_status() {
|
||||
|
||||
dotenv().ok();
|
||||
env_logger::try_init().ok();
|
||||
|
||||
let db_url = get_database_url();
|
||||
let db = Arc::new(DatabaseHandler::new(&db_url).await.expect("Failed to connect to database"));
|
||||
|
||||
let (command_tx, command_rx) = create_command_channel();
|
||||
let mut scheduler = Scheduler::new(db.clone(), command_rx, None);
|
||||
|
||||
// Start scheduler
|
||||
let scheduler_handle = tokio::spawn(async move {
|
||||
scheduler.run().await;
|
||||
});
|
||||
|
||||
// Give it time to start
|
||||
tokio::time::sleep(Duration::from_secs(2)).await;
|
||||
|
||||
// Request status
|
||||
let (reply_tx, reply_rx) = oneshot::channel();
|
||||
command_tx.send(SchedulerCommand::GetStatus { reply: reply_tx }).await.expect("Failed to send GetStatus");
|
||||
|
||||
let status = timeout(Duration::from_secs(5), reply_rx).await
|
||||
.expect("Timeout waiting for status")
|
||||
.expect("Failed to receive status");
|
||||
|
||||
info!("Scheduler status: {:?}", status);
|
||||
assert!(status.is_running || status.active_symbols.is_empty(), "Scheduler should be running or have no symbols");
|
||||
|
||||
// Shutdown
|
||||
command_tx.send(SchedulerCommand::Shutdown).await.expect("Failed to send shutdown");
|
||||
let _ = timeout(Duration::from_secs(10), scheduler_handle).await;
|
||||
|
||||
info!("GetStatus test passed");
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_add_and_remove_symbol() {
|
||||
|
||||
dotenv().ok();
|
||||
env_logger::try_init().ok();
|
||||
|
||||
let db_url = get_database_url();
|
||||
let db = Arc::new(DatabaseHandler::new(&db_url).await.expect("Failed to connect to database"));
|
||||
|
||||
let test_symbol = "testscheduler";
|
||||
|
||||
// Clean up first - remove test symbol if exists
|
||||
let _ = db.remove_symbol(test_symbol).await;
|
||||
|
||||
let (command_tx, command_rx) = create_command_channel();
|
||||
let mut scheduler = Scheduler::new(db.clone(), command_rx, None);
|
||||
|
||||
// Start scheduler
|
||||
let scheduler_handle = tokio::spawn(async move {
|
||||
scheduler.run().await;
|
||||
});
|
||||
|
||||
// Give it time to start
|
||||
tokio::time::sleep(Duration::from_secs(2)).await;
|
||||
|
||||
// Add symbol (with recent backfill_from to avoid long backfill)
|
||||
let now = std::time::SystemTime::now()
|
||||
.duration_since(std::time::UNIX_EPOCH)
|
||||
.unwrap()
|
||||
.as_millis() as i64;
|
||||
let recent_time = now - (5 * 60 * 1000); // 5 minutes ago
|
||||
|
||||
info!("Adding test symbol: {}", test_symbol);
|
||||
command_tx.send(SchedulerCommand::AddSymbol {
|
||||
symbol: test_symbol.to_string(),
|
||||
backfill_from: Some(recent_time),
|
||||
}).await.expect("Failed to send AddSymbol");
|
||||
|
||||
// Wait for processing
|
||||
tokio::time::sleep(Duration::from_secs(5)).await;
|
||||
|
||||
// Check status
|
||||
let (reply_tx, reply_rx) = oneshot::channel();
|
||||
command_tx.send(SchedulerCommand::GetStatus { reply: reply_tx }).await.expect("Failed to send GetStatus");
|
||||
|
||||
let status = timeout(Duration::from_secs(5), reply_rx).await
|
||||
.expect("Timeout")
|
||||
.expect("Failed to receive");
|
||||
|
||||
info!("Status after add: {:?}", status);
|
||||
|
||||
// Verify symbol was added
|
||||
let is_tracked = db.is_symbol_tracked(test_symbol).await.expect("Failed to check tracking");
|
||||
assert!(is_tracked, "Symbol should be tracked after AddSymbol");
|
||||
|
||||
// Remove symbol
|
||||
info!("Removing test symbol: {}", test_symbol);
|
||||
command_tx.send(SchedulerCommand::RemoveSymbol {
|
||||
symbol: test_symbol.to_string(),
|
||||
}).await.expect("Failed to send RemoveSymbol");
|
||||
|
||||
// Wait for processing
|
||||
tokio::time::sleep(Duration::from_secs(3)).await;
|
||||
|
||||
// Verify symbol was removed
|
||||
let is_tracked = db.is_symbol_tracked(test_symbol).await.expect("Failed to check tracking");
|
||||
assert!(!is_tracked, "Symbol should not be tracked after RemoveSymbol");
|
||||
|
||||
// Shutdown
|
||||
command_tx.send(SchedulerCommand::Shutdown).await.expect("Failed to send shutdown");
|
||||
let _ = timeout(Duration::from_secs(10), scheduler_handle).await;
|
||||
|
||||
info!("Add and remove symbol test passed");
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_restart_collector() {
|
||||
|
||||
dotenv().ok();
|
||||
env_logger::try_init().ok();
|
||||
|
||||
let db_url = get_database_url();
|
||||
let db = Arc::new(DatabaseHandler::new(&db_url).await.expect("Failed to connect to database"));
|
||||
|
||||
let (command_tx, command_rx) = create_command_channel();
|
||||
let mut scheduler = Scheduler::new(db.clone(), command_rx, None);
|
||||
|
||||
// Start scheduler
|
||||
let scheduler_handle = tokio::spawn(async move {
|
||||
scheduler.run().await;
|
||||
});
|
||||
|
||||
// Give it time to start
|
||||
tokio::time::sleep(Duration::from_secs(2)).await;
|
||||
|
||||
// Get initial status
|
||||
let (reply_tx, reply_rx) = oneshot::channel();
|
||||
command_tx.send(SchedulerCommand::GetStatus { reply: reply_tx }).await.unwrap();
|
||||
let status_before = reply_rx.await.unwrap();
|
||||
info!("Status before restart: {:?}", status_before);
|
||||
|
||||
// Send restart command
|
||||
info!("Sending RestartCollector command");
|
||||
command_tx.send(SchedulerCommand::RestartCollector).await.expect("Failed to send RestartCollector");
|
||||
|
||||
// Wait for restart
|
||||
tokio::time::sleep(Duration::from_secs(5)).await;
|
||||
|
||||
// Get status after restart
|
||||
let (reply_tx, reply_rx) = oneshot::channel();
|
||||
command_tx.send(SchedulerCommand::GetStatus { reply: reply_tx }).await.unwrap();
|
||||
let status_after = reply_rx.await.unwrap();
|
||||
info!("Status after restart: {:?}", status_after);
|
||||
|
||||
// Shutdown
|
||||
command_tx.send(SchedulerCommand::Shutdown).await.expect("Failed to send shutdown");
|
||||
let _ = timeout(Duration::from_secs(10), scheduler_handle).await;
|
||||
|
||||
info!("Restart collector test passed");
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_multiple_commands() {
|
||||
|
||||
dotenv().ok();
|
||||
env_logger::try_init().ok();
|
||||
|
||||
let db_url = get_database_url();
|
||||
let db = Arc::new(DatabaseHandler::new(&db_url).await.expect("Failed to connect to database"));
|
||||
|
||||
let (command_tx, command_rx) = create_command_channel();
|
||||
let mut scheduler = Scheduler::new(db.clone(), command_rx, None);
|
||||
|
||||
// Start scheduler
|
||||
let scheduler_handle = tokio::spawn(async move {
|
||||
scheduler.run().await;
|
||||
});
|
||||
|
||||
tokio::time::sleep(Duration::from_secs(2)).await;
|
||||
|
||||
// Send multiple status requests rapidly
|
||||
for i in 0..5 {
|
||||
let (reply_tx, reply_rx) = oneshot::channel();
|
||||
command_tx.send(SchedulerCommand::GetStatus { reply: reply_tx }).await.unwrap();
|
||||
let status = reply_rx.await.unwrap();
|
||||
info!("Status request {}: {:?}", i, status);
|
||||
}
|
||||
|
||||
// Shutdown
|
||||
command_tx.send(SchedulerCommand::Shutdown).await.expect("Failed to send shutdown");
|
||||
let _ = timeout(Duration::from_secs(10), scheduler_handle).await;
|
||||
|
||||
info!("Multiple commands test passed");
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_real_btcusdt_collection() {
|
||||
|
||||
dotenv().ok();
|
||||
env_logger::try_init().ok();
|
||||
|
||||
let db_url = get_database_url();
|
||||
let db = Arc::new(DatabaseHandler::new(&db_url).await.expect("Failed to connect to database"));
|
||||
|
||||
let symbol = "btcusdt";
|
||||
|
||||
// Clean up - remove from tracking first
|
||||
let _ = db.remove_symbol(symbol).await;
|
||||
|
||||
let (command_tx, command_rx) = create_command_channel();
|
||||
let mut scheduler = Scheduler::new(db.clone(), command_rx, None);
|
||||
|
||||
// Start scheduler
|
||||
let scheduler_handle = tokio::spawn(async move {
|
||||
scheduler.run().await;
|
||||
});
|
||||
|
||||
tokio::time::sleep(Duration::from_secs(2)).await;
|
||||
|
||||
// Calculate start time: 5 minutes ago
|
||||
let now = std::time::SystemTime::now()
|
||||
.duration_since(std::time::UNIX_EPOCH)
|
||||
.unwrap()
|
||||
.as_millis() as i64;
|
||||
let five_min_ago = now - (5 * 60 * 1000);
|
||||
|
||||
info!("Adding BTCUSDT, backfill from {} (5 min ago)", five_min_ago);
|
||||
|
||||
// Add BTCUSDT with backfill from 5 minutes ago
|
||||
command_tx.send(SchedulerCommand::AddSymbol {
|
||||
symbol: symbol.to_string(),
|
||||
backfill_from: Some(five_min_ago),
|
||||
}).await.expect("Failed to send AddSymbol");
|
||||
|
||||
// Wait for backfill to complete
|
||||
info!("Waiting for backfill...");
|
||||
tokio::time::sleep(Duration::from_secs(10)).await;
|
||||
|
||||
// Check latest timestamp in database
|
||||
let latest_ts = db.get_latest_timestamp(symbol).await.expect("Failed to get timestamp");
|
||||
info!("Latest BTCUSDT timestamp in DB: {:?}", latest_ts);
|
||||
|
||||
assert!(latest_ts.is_some(), "Should have BTCUSDT data in database");
|
||||
|
||||
// Wait for 2 more candles (about 2 minutes + buffer)
|
||||
info!("Waiting for 2 live candles (~2.5 minutes)...");
|
||||
tokio::time::sleep(Duration::from_secs(150)).await;
|
||||
|
||||
// Check new latest timestamp
|
||||
let new_latest_ts = db.get_latest_timestamp(symbol).await.expect("Failed to get timestamp");
|
||||
info!("New latest BTCUSDT timestamp: {:?}", new_latest_ts);
|
||||
|
||||
assert!(new_latest_ts.unwrap() > latest_ts.unwrap(), "Should have received new candles");
|
||||
|
||||
// Get status
|
||||
let (reply_tx, reply_rx) = oneshot::channel();
|
||||
command_tx.send(SchedulerCommand::GetStatus { reply: reply_tx }).await.unwrap();
|
||||
let status = reply_rx.await.unwrap();
|
||||
info!("Final status: {:?}", status);
|
||||
|
||||
assert!(status.active_symbols.contains(&symbol.to_string()), "BTCUSDT should be in active symbols");
|
||||
|
||||
// Clean up - remove symbol
|
||||
command_tx.send(SchedulerCommand::RemoveSymbol {
|
||||
symbol: symbol.to_string(),
|
||||
}).await.expect("Failed to remove symbol");
|
||||
|
||||
tokio::time::sleep(Duration::from_secs(2)).await;
|
||||
|
||||
// Shutdown
|
||||
command_tx.send(SchedulerCommand::Shutdown).await.expect("Failed to send shutdown");
|
||||
let _ = timeout(Duration::from_secs(10), scheduler_handle).await;
|
||||
|
||||
info!("Real BTCUSDT collection test passed!");
|
||||
info!("Check database: SELECT * FROM klines_1m WHERE symbol = 'BTCUSDT' ORDER BY timestamp DESC LIMIT 10;");
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
use backend::{BinanceCollector, CandleData};
|
||||
use tokio::sync::mpsc;
|
||||
use dotenv::dotenv;
|
||||
use log::info;
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_sync_full_history_single_symbol() {
|
||||
dotenv().ok();
|
||||
env_logger::init();
|
||||
|
||||
// 1. Get all symbols
|
||||
let symbol_vec = BinanceCollector::get_symbol().await.unwrap();
|
||||
info!("Got {} symbols", symbol_vec.len());
|
||||
|
||||
// 2. Find ETHUSDT start time
|
||||
let test_symbol = "ETHUSDT";
|
||||
let test_start_time = symbol_vec
|
||||
.iter()
|
||||
.find(|item| item.symbol == test_symbol)
|
||||
.map(|item| item.start_timestamp)
|
||||
.expect("ETHUSDT not found");
|
||||
|
||||
info!("{} start_timestamp: {}", test_symbol, test_start_time);
|
||||
|
||||
// 3. Build clients (all clients work together on this symbol)
|
||||
let clients = BinanceCollector::build_clients().await;
|
||||
info!("Built {} clients", clients.len());
|
||||
assert!(!clients.is_empty(), "Need at least 1 client");
|
||||
|
||||
// 4. Create channel
|
||||
let (tx, mut rx) = mpsc::channel::<CandleData>(100000);
|
||||
|
||||
// 5. Sync from scratch (all clients work in parallel on different time segments)
|
||||
info!("Starting full history sync for {} with {} clients...", test_symbol, clients.len());
|
||||
|
||||
let sync_handle = tokio::spawn(async move {
|
||||
BinanceCollector::sync_from_scratch(
|
||||
test_symbol.to_string(),
|
||||
test_start_time,
|
||||
clients, // Pass all clients
|
||||
tx,
|
||||
).await
|
||||
});
|
||||
|
||||
// 6. Consume and count
|
||||
let mut count = 0u64;
|
||||
let mut last_ts = 0i64;
|
||||
|
||||
while let Some(candle) = rx.recv().await {
|
||||
count += 1;
|
||||
last_ts = candle.timestamp;
|
||||
|
||||
if count % 100000 == 0 {
|
||||
info!("Progress: {} candles, last_ts: {}", count, last_ts);
|
||||
}
|
||||
}
|
||||
|
||||
let result = sync_handle.await.unwrap();
|
||||
|
||||
info!("Sync result: {:?}", result);
|
||||
info!("Total received: {} candles", count);
|
||||
info!("Last timestamp: {}", last_ts);
|
||||
|
||||
assert!(count > 0, "Should have synced some candles");
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
use backend::{BinanceCollector, CandleData};
|
||||
use tokio::sync::mpsc;
|
||||
use dotenv::dotenv;
|
||||
use log::info;
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_build_clients() {
|
||||
dotenv().ok();
|
||||
env_logger::init();
|
||||
|
||||
info!("Testing build_clients...");
|
||||
|
||||
let clients = BinanceCollector::build_clients().await;
|
||||
|
||||
info!("Built {} working clients", clients.len());
|
||||
assert!(clients.len() > 0, "Should have at least 1 working client");
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_sync_single_symbol() {
|
||||
dotenv().ok();
|
||||
let _ = env_logger::try_init();
|
||||
|
||||
info!("Testing sync_from_scratch for single symbol...");
|
||||
|
||||
// Build clients (all work together)
|
||||
let clients = BinanceCollector::build_clients().await;
|
||||
assert!(!clients.is_empty(), "Need at least 1 client");
|
||||
info!("Built {} clients", clients.len());
|
||||
|
||||
// Create channel
|
||||
let (tx, mut rx) = mpsc::channel::<CandleData>(10000);
|
||||
|
||||
// Sync last 5 minutes of BTCUSDT
|
||||
let now = std::time::SystemTime::now()
|
||||
.duration_since(std::time::UNIX_EPOCH)
|
||||
.unwrap()
|
||||
.as_millis() as i64;
|
||||
let start_time = now - (5 * 60 * 1000); // 5 minutes ago
|
||||
|
||||
info!("Syncing BTCUSDT from {} to {}", start_time, now);
|
||||
|
||||
let count = BinanceCollector::sync_from_scratch(
|
||||
"BTCUSDT".to_string(),
|
||||
start_time,
|
||||
clients, // All clients work together
|
||||
tx,
|
||||
).await.unwrap();
|
||||
|
||||
info!("Sync returned {} candles", count);
|
||||
|
||||
// Drain channel
|
||||
let mut received = 0;
|
||||
while let Ok(candle) = rx.try_recv() {
|
||||
info!(
|
||||
"Candle: {} ts={} o={:.2} h={:.2} l={:.2} c={:.2} nv={:.4}",
|
||||
candle.symbol, candle.timestamp,
|
||||
candle.open, candle.high, candle.low, candle.close,
|
||||
candle.net_volume
|
||||
);
|
||||
received += 1;
|
||||
}
|
||||
|
||||
info!("Received {} candles from channel", received);
|
||||
assert!(count >= 3, "Expected at least 3 candles for 5 min, got {}", count);
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
API_BASE_URL=https://api.yourdomain.com
|
||||
+59
@@ -0,0 +1,59 @@
|
||||
---
|
||||
name: Bug report
|
||||
about: Create a report to help us improve
|
||||
title: ''
|
||||
labels: ''
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
# Bug Report
|
||||
|
||||
**Charting Library Version**
|
||||
|
||||
Execute `TradingView.version()` in the browser console.
|
||||
|
||||
**Desktop (please complete the following information):**
|
||||
|
||||
- OS: [e.g. Windows 11]
|
||||
- Browser [e.g. chrome, safari]
|
||||
- Browser version [e.g. 22]
|
||||
|
||||
**Smartphone (please complete the following information):**
|
||||
|
||||
- Device: [e.g. iPhone 13]
|
||||
- OS: [e.g. iOS 14.1]
|
||||
- Browser [e.g. stock browser, safari]
|
||||
- Browser version [e.g. 22]
|
||||
|
||||
**JSFiddle**
|
||||
|
||||
If possible, please provide an example in JSFiddle which demonstrates the bug. Please see this guide on how to create a JSFiddle: [Using the library with online code playgrounds](https://github.com/tradingview/charting_library/wiki/Online-Editors)
|
||||
|
||||
**To Reproduce**
|
||||
|
||||
Steps to reproduce the behavior:
|
||||
1. Go to '...'
|
||||
2. Click on '....'
|
||||
3. Scroll down to '....'
|
||||
4. See error
|
||||
|
||||
**Describe the bug**
|
||||
|
||||
A clear and concise description of what the bug is.
|
||||
|
||||
**Expected behavior**
|
||||
|
||||
A clear and concise description of what you expected to happen.
|
||||
|
||||
**Screenshots**
|
||||
|
||||
If applicable, add screenshots, or videos, to help explain your problem.
|
||||
|
||||
**Debug Console Log**
|
||||
|
||||
Please provide the entire console log produced when [`debug:true`](https://github.com/tradingview/charting_library/wiki/Widget-Constructor#debug) is set within the widget constructor options, or evoke the following command in the console: [`widget.setDebugMode(true)`](https://github.com/tradingview/charting_library/wiki/Widget-Methods#setdebugmodeenabled).
|
||||
|
||||
**Additional context**
|
||||
|
||||
Add any other context about the problem here.
|
||||
@@ -0,0 +1,27 @@
|
||||
---
|
||||
name: Data Question
|
||||
about: Ask a question if you have a problem with connecting your data
|
||||
title: ''
|
||||
labels: status/conversation
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
# Data Question
|
||||
|
||||
<!-- PLEASE MAKE SURE THAT YOU HAVE READ FAQ -->
|
||||
<!-- https://github.com/tradingview/charting_library/wiki/Frequently-Asked-Questions -->
|
||||
|
||||
- [ ] I have read FAQ <!-- replace the space in the brackets with `x` -->
|
||||
|
||||
**Describe the problem**
|
||||
|
||||
A clear and concise description of what the problem is.
|
||||
|
||||
**Console logs**
|
||||
|
||||
Uncomment `debug: true` in the widget constructor and post here all console logs. ```Use a triple backtick in front and behind the logs.```
|
||||
|
||||
**Symbol**
|
||||
|
||||
What symbol(instrument) your problem is related to.
|
||||
@@ -0,0 +1,26 @@
|
||||
---
|
||||
name: Feature request
|
||||
about: Suggest an idea for this project
|
||||
title: ''
|
||||
labels: ''
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
# Feature Request
|
||||
|
||||
**Is your feature request related to a problem? Please describe.**
|
||||
|
||||
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
|
||||
|
||||
**Describe the solution you'd like**
|
||||
|
||||
A clear and concise description of what you want to happen.
|
||||
|
||||
**Describe alternatives you've considered**
|
||||
|
||||
A clear and concise description of any alternative solutions or features you've considered.
|
||||
|
||||
**Additional context**
|
||||
|
||||
Add any other context or screenshots about the feature request here.
|
||||
@@ -0,0 +1,19 @@
|
||||
---
|
||||
name: General Question
|
||||
about: Ask a question if you cannot find an answer in the documentation
|
||||
title: ''
|
||||
labels: status/conversation
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
# General Question
|
||||
|
||||
<!-- PLEASE MAKE SURE THAT YOU HAVE READ FAQ -->
|
||||
<!-- https://github.com/tradingview/charting_library/wiki/Frequently-Asked-Questions -->
|
||||
|
||||
- [ ] I have read FAQ <!-- replace the space in the brackets with `x` -->
|
||||
|
||||
**Ask your question with the greatest possible detail**
|
||||
|
||||
<!-- Write your question right here... -->
|
||||
@@ -0,0 +1 @@
|
||||
img
|
||||
@@ -0,0 +1,3 @@
|
||||
FROM nginx:alpine
|
||||
COPY . /usr/share/nginx/html/
|
||||
EXPOSE 80
|
||||
@@ -0,0 +1,143 @@
|
||||
# 📈 View Charting Frontend
|
||||
|
||||
A self-hosted [View Charting Library](https://www.tradingview.com/charting-library-docs/) frontend for Binance USDS-M Futures. Features real-time WebSocket streaming, multi-chart layouts, persistent drawing canvases, and a watchlist sidebar — all protected behind Google OAuth.
|
||||
|
||||
## ✨ Features
|
||||
|
||||
- **View Charting Library v29.4** — Professional-grade charting with full indicator and drawing tool support
|
||||
- **Real-time Data** — Live candle updates via WebSocket from the backend API
|
||||
- **Multi-chart Layouts** — Single, vertical split, horizontal split, and 1-left / 2-right layouts with resizable dividers
|
||||
- **Watchlist Sidebar** — Drag-and-drop reordering, live price & change tracking, multiple custom lists
|
||||
- **Canvas Persistence** — Save/load named drawing canvases per symbol, with auto-save every 5 minutes
|
||||
- **Dark & Light Theme** — Full theme support synced with View widget
|
||||
- **Google OAuth Protection** — Access restricted to authorized Google accounts with 144-hour session persistence
|
||||
- **Responsive Login Page** — Adaptive background images for mobile / tablet / desktop
|
||||
- **Docker Ready** — Nginx-based container, single-file deployment
|
||||
|
||||
## 📁 Project Structure
|
||||
|
||||
```
|
||||
├── index.html # Main application (View widget + watchlist + layouts)
|
||||
├── login.html # Standalone login page with Google Sign-In
|
||||
├── auth.js # AuthGuard class — session management & login UI
|
||||
├── auth-config.js # Google OAuth Client ID & API base URL configuration
|
||||
├── .env.example # Environment variable template
|
||||
├── Dockerfile # Nginx Alpine container
|
||||
├── docker-compose.yml # Docker Compose service definition
|
||||
├── serve.py # Python dev server with CORS support
|
||||
├── package.json # Charting Library package metadata (v29.4.0)
|
||||
├── charting_library/ # View Charting Library assets
|
||||
└── datafeeds/ # View UDF datafeed adapter
|
||||
```
|
||||
|
||||
## 🚀 Quick Start
|
||||
|
||||
### Prerequisites
|
||||
|
||||
- A running [backend service](../backend/) providing the API
|
||||
- (Optional) Google OAuth Client ID from [GCP Console](https://console.cloud.google.com/apis/credentials) for authentication
|
||||
|
||||
### Environment Setup
|
||||
|
||||
```bash
|
||||
cp .env.example .env
|
||||
# Edit .env with your backend API URL
|
||||
```
|
||||
|
||||
`.env.example`:
|
||||
```env
|
||||
API_BASE_URL=https://api.yourdomain.com
|
||||
```
|
||||
|
||||
### Configuration
|
||||
|
||||
Edit `auth-config.js` to set your API base URL and Google OAuth Client ID:
|
||||
|
||||
```js
|
||||
window.API_CONFIG = { baseUrl: 'https://api.yourdomain.com' };
|
||||
|
||||
const AUTH_CONFIG = {
|
||||
clientId: 'YOUR_GOOGLE_CLIENT_ID.apps.googleusercontent.com',
|
||||
onSuccess: (user) => { /* ... */ },
|
||||
onError: (error) => { /* ... */ }
|
||||
};
|
||||
```
|
||||
|
||||
### Development
|
||||
|
||||
```bash
|
||||
# Using Python dev server (with CORS headers)
|
||||
python3 serve.py
|
||||
# → http://localhost:8080
|
||||
|
||||
# Or any static file server
|
||||
npx serve .
|
||||
```
|
||||
|
||||
### Docker
|
||||
|
||||
```bash
|
||||
# Build image
|
||||
docker build -t frontend .
|
||||
|
||||
# Using docker-compose (connects to existing `cycle` network)
|
||||
docker compose up -d
|
||||
```
|
||||
|
||||
## 🔐 Authentication Flow
|
||||
|
||||
```
|
||||
login.html index.html
|
||||
│ │
|
||||
├─ Google Sign-In ──────┐ │
|
||||
│ ▼ │
|
||||
│ JWT validation │
|
||||
│ + email whitelist │
|
||||
│ │
|
||||
│ localStorage ───────┤
|
||||
│ (auth_user, │
|
||||
│ auth_token, │
|
||||
│ auth_login_time) │
|
||||
│ │
|
||||
│ redirect ───────────▶ Session check (144h max) │
|
||||
│ │
|
||||
│ ├─ Valid → Load app │
|
||||
│ └─ Expired → Redirect to login.html
|
||||
```
|
||||
|
||||
### Email Whitelist
|
||||
|
||||
Access is restricted at the client level via an email whitelist in `login.html`. Only emails in the `allowedEmails` array can log in — all others receive an "Access denied" error:
|
||||
|
||||
```js
|
||||
const allowedEmails = ['your-email@gmail.com'];
|
||||
```
|
||||
|
||||
> [!IMPORTANT]
|
||||
> Update this whitelist with your authorized email addresses before deploying. This is a **client-side** check; for production use, combine with GCP Console's OAuth test user list for server-side enforcement.
|
||||
|
||||
## 🖥️ Multi-Chart Layouts
|
||||
|
||||
| Layout | Description |
|
||||
|--------|-------------|
|
||||
| **Single** | One full-screen chart |
|
||||
| **Vertical** | Two charts stacked vertically |
|
||||
| **Horizontal** | Two charts side by side |
|
||||
| **1L + 2R** | One large chart on left, two stacked on right |
|
||||
|
||||
All dividers are draggable for custom sizing.
|
||||
|
||||
## 📦 Dependencies
|
||||
|
||||
| Dependency | Purpose |
|
||||
|------------|---------|
|
||||
| [View Charting Library](https://www.tradingview.com/charting-library-docs/) v29.4 | Charting engine |
|
||||
| [Google Identity Services](https://developers.google.com/identity/gsi/web) | OAuth authentication |
|
||||
| Nginx Alpine | Production static file serving |
|
||||
|
||||
## 📜 License
|
||||
|
||||
MIT
|
||||
|
||||
|
||||
Generated By Claude Opus 4.6
|
||||
@@ -0,0 +1,28 @@
|
||||
window.API_CONFIG = { baseUrl: 'https://xxx.xxx.com' };
|
||||
|
||||
/**
|
||||
* Google OAuth Configuration
|
||||
* Configure your Google OAuth Client ID here
|
||||
* Access control is managed via the test users list in GCP Console
|
||||
*/
|
||||
|
||||
const AUTH_CONFIG = {
|
||||
// Client ID obtained from GCP Console
|
||||
// Replace with your actual Client ID
|
||||
clientId: 'xxxxxxxxxxxxxxxxxxxxxxxxxx.apps.googleusercontent.com',
|
||||
|
||||
// Authentication success callback
|
||||
onSuccess: (user) => {
|
||||
console.log('Authentication successful:', user.email);
|
||||
// Additional logic can be added here, e.g. logging
|
||||
},
|
||||
|
||||
// Authentication failure callback
|
||||
onError: (error) => {
|
||||
console.error('Authentication error:', error);
|
||||
// Error handling logic can be added here
|
||||
}
|
||||
};
|
||||
|
||||
// Export configuration
|
||||
window.AUTH_CONFIG = AUTH_CONFIG;
|
||||
@@ -0,0 +1,278 @@
|
||||
/**
|
||||
* Google OAuth Login Guard
|
||||
* Only authorized Google accounts can access the application
|
||||
*/
|
||||
|
||||
class AuthGuard {
|
||||
constructor(config) {
|
||||
this.clientId = config.clientId;
|
||||
this.onSuccess = config.onSuccess || (() => { });
|
||||
this.onError = config.onError || ((error) => console.error(error));
|
||||
|
||||
this.user = null;
|
||||
this.isAuthenticated = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize Google Sign-In
|
||||
*/
|
||||
init() {
|
||||
return new Promise((resolve, reject) => {
|
||||
// Load Google Identity Services
|
||||
const script = document.createElement('script');
|
||||
script.src = 'https://accounts.google.com/gsi/client';
|
||||
script.async = true;
|
||||
script.defer = true;
|
||||
|
||||
script.onload = () => {
|
||||
this.initializeGoogleAuth();
|
||||
resolve();
|
||||
};
|
||||
|
||||
script.onerror = () => {
|
||||
reject(new Error('Failed to load Google Identity Services'));
|
||||
};
|
||||
|
||||
document.head.appendChild(script);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize Google OAuth
|
||||
*/
|
||||
initializeGoogleAuth() {
|
||||
google.accounts.id.initialize({
|
||||
client_id: this.clientId,
|
||||
callback: this.handleCredentialResponse.bind(this),
|
||||
auto_select: true,
|
||||
cancel_on_tap_outside: false
|
||||
});
|
||||
|
||||
// Check if already logged in
|
||||
this.checkExistingSession();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check locally stored session
|
||||
*/
|
||||
checkExistingSession() {
|
||||
const savedUser = localStorage.getItem('auth_user');
|
||||
const savedToken = localStorage.getItem('auth_token');
|
||||
|
||||
if (savedUser && savedToken) {
|
||||
try {
|
||||
const user = JSON.parse(savedUser);
|
||||
// Verify if token is expired
|
||||
const tokenData = this.parseJwt(savedToken);
|
||||
if (tokenData.exp * 1000 > Date.now()) {
|
||||
this.user = user;
|
||||
this.isAuthenticated = true;
|
||||
this.onSuccess(user);
|
||||
this.hideLoginUI();
|
||||
return;
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('Invalid session data:', e);
|
||||
}
|
||||
}
|
||||
|
||||
// No valid session, show login UI
|
||||
this.showLoginUI();
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle Google login response
|
||||
*/
|
||||
handleCredentialResponse(response) {
|
||||
try {
|
||||
const credential = response.credential;
|
||||
const userData = this.parseJwt(credential);
|
||||
|
||||
// Save user info and token
|
||||
this.user = {
|
||||
email: userData.email,
|
||||
name: userData.name,
|
||||
picture: userData.picture,
|
||||
sub: userData.sub
|
||||
};
|
||||
this.isAuthenticated = true;
|
||||
|
||||
localStorage.setItem('auth_user', JSON.stringify(this.user));
|
||||
localStorage.setItem('auth_token', credential);
|
||||
|
||||
this.hideLoginUI();
|
||||
this.onSuccess(this.user);
|
||||
|
||||
// Reload page to initialize the application
|
||||
location.reload();
|
||||
|
||||
} catch (error) {
|
||||
this.onError({
|
||||
type: 'AUTH_ERROR',
|
||||
message: 'Authentication failed',
|
||||
error
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Show login UI
|
||||
*/
|
||||
showLoginUI() {
|
||||
const loginContainer = document.createElement('div');
|
||||
loginContainer.id = 'auth-container';
|
||||
loginContainer.innerHTML = `
|
||||
<style>
|
||||
@media (max-width: 768px) {
|
||||
#auth-background {
|
||||
background-image: url('https://img.cathiefish.art/tradingview/small.jpg') !important;
|
||||
}
|
||||
#auth-card {
|
||||
padding: 30px 20px !important;
|
||||
max-width: 90% !important;
|
||||
margin: 0 20px !important;
|
||||
}
|
||||
#auth-title {
|
||||
font-size: 20px !important;
|
||||
}
|
||||
}
|
||||
@media (min-width: 769px) and (max-width: 1200px) {
|
||||
#auth-background {
|
||||
background-image: url('https://img.cathiefish.art/tradingview/medium.jpg') !important;
|
||||
}
|
||||
}
|
||||
@media (min-width: 1201px) {
|
||||
#auth-background {
|
||||
background-image: url('https://img.cathiefish.art/tradingview/large.jpg') !important;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<div id="auth-background" style="
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-image: url('https://img.cathiefish.art/tradingview/large.jpg');
|
||||
background-size: cover;
|
||||
background-position: center;
|
||||
background-repeat: no-repeat;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
z-index: 10000;
|
||||
">
|
||||
<!-- Semi-transparent overlay -->
|
||||
<div style="
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: rgba(15, 15, 15, 0.05);
|
||||
"></div>
|
||||
|
||||
<!-- Login card -->
|
||||
<div id="auth-card" style="
|
||||
position: relative;
|
||||
background: rgba(250, 248, 245, 0.95);
|
||||
padding: 50px 40px;
|
||||
border-radius: 16px;
|
||||
box-shadow: 0 16px 48px rgba(0,0,0,0.6);
|
||||
text-align: center;
|
||||
max-width: 420px;
|
||||
border: 1px solid rgba(255, 255, 255, 0.3);
|
||||
backdrop-filter: blur(10px);
|
||||
-webkit-backdrop-filter: blur(10px);
|
||||
">
|
||||
<h1 id="auth-title" style="
|
||||
color: #2c3e50;
|
||||
margin-bottom: 12px;
|
||||
font-size: 28px;
|
||||
font-weight: 600;
|
||||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
||||
letter-spacing: -0.5px;
|
||||
">Tradingview</h1>
|
||||
<p style="
|
||||
color: #5a6c7d;
|
||||
margin-bottom: 35px;
|
||||
font-size: 15px;
|
||||
line-height: 1.5;
|
||||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
||||
">Sign in with your authorized Google account to continue</p>
|
||||
<div id="google-signin-button"></div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
document.body.appendChild(loginContainer);
|
||||
|
||||
// Render Google Sign-In button
|
||||
google.accounts.id.renderButton(
|
||||
document.getElementById('google-signin-button'),
|
||||
{
|
||||
theme: 'filled_blue',
|
||||
size: 'large',
|
||||
text: 'signin_with',
|
||||
shape: 'rectangular',
|
||||
width: 300
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Hide login UI
|
||||
*/
|
||||
hideLoginUI() {
|
||||
const container = document.getElementById('auth-container');
|
||||
if (container) {
|
||||
container.remove();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Logout
|
||||
*/
|
||||
logout() {
|
||||
this.user = null;
|
||||
this.isAuthenticated = false;
|
||||
localStorage.removeItem('auth_user');
|
||||
localStorage.removeItem('auth_token');
|
||||
|
||||
// Clear Google session
|
||||
google.accounts.id.disableAutoSelect();
|
||||
|
||||
// Reload page
|
||||
location.reload();
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse JWT token
|
||||
*/
|
||||
parseJwt(token) {
|
||||
const base64Url = token.split('.')[1];
|
||||
const base64 = base64Url.replace(/-/g, '+').replace(/_/g, '/');
|
||||
const jsonPayload = decodeURIComponent(atob(base64).split('').map(function (c) {
|
||||
return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2);
|
||||
}).join(''));
|
||||
return JSON.parse(jsonPayload);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get current user
|
||||
*/
|
||||
getUser() {
|
||||
return this.user;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if user is authenticated
|
||||
*/
|
||||
isUserAuthenticated() {
|
||||
return this.isAuthenticated;
|
||||
}
|
||||
}
|
||||
|
||||
// Export to global scope
|
||||
window.AuthGuard = AuthGuard;
|
||||
Vendored
+5
@@ -0,0 +1,5 @@
|
||||
export * from './charting_library/charting_library';
|
||||
declare module 'charting_library/datafeeds/udf/dist/bundle' {
|
||||
const UDFCompatibleDatafeed: typeof import('./datafeeds/udf/src/udf-compatible-datafeed').UDFCompatibleDatafeed;
|
||||
export { UDFCompatibleDatafeed };
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
.container-qm7Rg5MB{align-items:center;border-bottom:1px solid;border-top:1px solid;border-color:var(--themed-color-search-border,#ebebeb);cursor:default;display:flex;flex-shrink:0;position:relative}html.theme-dark .container-qm7Rg5MB{border-color:var(--themed-color-search-border,#4a4a4a)}.container-qm7Rg5MB.mobile-qm7Rg5MB{background-color:var(--themed-color-container-fill-primary-neutral-extra-light,#f2f2f2);border:none;border-radius:40px;margin:4px 20px 8px}html.theme-dark .container-qm7Rg5MB.mobile-qm7Rg5MB{background-color:var(--themed-color-container-fill-primary-neutral-extra-light,#303030)}.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(--themed-color-load-chart-dialog-text,#1a1a1a);font-size:16px;height:100%;margin:0;padding:0;width:100%}html.theme-dark .input-qm7Rg5MB{color:var(--themed-color-load-chart-dialog-text,#a8a8a8)}.input-qm7Rg5MB.mobile-qm7Rg5MB{color:var(--themed-color-content-primary-neutral-bold,#1a1a1a)}html.theme-dark .input-qm7Rg5MB.mobile-qm7Rg5MB{color:var(--themed-color-content-primary-neutral-bold,#dbdbdb)}.input-qm7Rg5MB.mobile-qm7Rg5MB::placeholder{color:var(--themed-color-content-primary-neutral,#707070);font-weight:400}html.theme-dark .input-qm7Rg5MB.mobile-qm7Rg5MB::placeholder{color:var(--themed-color-content-primary-neutral,#8c8c8c)}.input-qm7Rg5MB::placeholder{color:var(--themed-color-input-placeholder-text,#a8a8a8);font-weight:400}html.theme-dark .input-qm7Rg5MB::placeholder{color:var(--themed-color-input-placeholder-text,#4a4a4a)}.icon-qm7Rg5MB{color:#a8a8a8;height:28px;left:15px;pointer-events:none;position:absolute;top:calc(50% - 14px)}.icon-qm7Rg5MB.mobile-qm7Rg5MB{color:var(--themed-color-content-primary-neutral,#707070);left:8px}html.theme-dark .icon-qm7Rg5MB.mobile-qm7Rg5MB{color:var(--themed-color-content-primary-neutral,#8c8c8c)}.cancel-qm7Rg5MB{color:var(--themed-color-default-gray,#707070);position:absolute;right:20px}html.theme-dark .cancel-qm7Rg5MB{color:var(--themed-color-default-gray,#8c8c8c)}.cancel-qm7Rg5MB.mobile-qm7Rg5MB{color:var(--themed-color-content-primary-neutral,#707070)}html.theme-dark .cancel-qm7Rg5MB.mobile-qm7Rg5MB{color:var(--themed-color-content-primary-neutral,#8c8c8c)}.highlighted-cwp8YRo6,html.theme-dark .highlighted-cwp8YRo6{color:var(--themed-color-brand,#2962ff)}
|
||||
@@ -0,0 +1 @@
|
||||
.container-qm7Rg5MB{align-items:center;border-bottom:1px solid;border-top:1px solid;border-color:var(--themed-color-search-border,#ebebeb);cursor:default;display:flex;flex-shrink:0;position:relative}html.theme-dark .container-qm7Rg5MB{border-color:var(--themed-color-search-border,#4a4a4a)}.container-qm7Rg5MB.mobile-qm7Rg5MB{background-color:var(--themed-color-container-fill-primary-neutral-extra-light,#f2f2f2);border:none;border-radius:40px;margin:4px 20px 8px}html.theme-dark .container-qm7Rg5MB.mobile-qm7Rg5MB{background-color:var(--themed-color-container-fill-primary-neutral-extra-light,#303030)}.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(--themed-color-load-chart-dialog-text,#1a1a1a);font-size:16px;height:100%;margin:0;padding:0;width:100%}html.theme-dark .input-qm7Rg5MB{color:var(--themed-color-load-chart-dialog-text,#a8a8a8)}.input-qm7Rg5MB.mobile-qm7Rg5MB{color:var(--themed-color-content-primary-neutral-bold,#1a1a1a)}html.theme-dark .input-qm7Rg5MB.mobile-qm7Rg5MB{color:var(--themed-color-content-primary-neutral-bold,#dbdbdb)}.input-qm7Rg5MB.mobile-qm7Rg5MB::placeholder{color:var(--themed-color-content-primary-neutral,#707070);font-weight:400}html.theme-dark .input-qm7Rg5MB.mobile-qm7Rg5MB::placeholder{color:var(--themed-color-content-primary-neutral,#8c8c8c)}.input-qm7Rg5MB::placeholder{color:var(--themed-color-input-placeholder-text,#a8a8a8);font-weight:400}html.theme-dark .input-qm7Rg5MB::placeholder{color:var(--themed-color-input-placeholder-text,#4a4a4a)}.icon-qm7Rg5MB{color:#a8a8a8;height:28px;pointer-events:none;position:absolute;right:15px;top:calc(50% - 14px)}.icon-qm7Rg5MB.mobile-qm7Rg5MB{color:var(--themed-color-content-primary-neutral,#707070);right:8px}html.theme-dark .icon-qm7Rg5MB.mobile-qm7Rg5MB{color:var(--themed-color-content-primary-neutral,#8c8c8c)}.cancel-qm7Rg5MB{color:var(--themed-color-default-gray,#707070);left:20px;position:absolute}html.theme-dark .cancel-qm7Rg5MB{color:var(--themed-color-default-gray,#8c8c8c)}.cancel-qm7Rg5MB.mobile-qm7Rg5MB{color:var(--themed-color-content-primary-neutral,#707070)}html.theme-dark .cancel-qm7Rg5MB.mobile-qm7Rg5MB{color:var(--themed-color-content-primary-neutral,#8c8c8c)}.highlighted-cwp8YRo6,html.theme-dark .highlighted-cwp8YRo6{color:var(--themed-color-brand,#2962ff)}
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
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 @@
|
||||
.dialog-UGdC69sw{min-width:254px;padding:40px;width:auto}.dialogInner-UGdC69sw{align-items:center;display:flex;flex-direction:column}.titleWrapper-UGdC69sw{align-items:center;display:flex;justify-content:center;margin-bottom:16px;max-width:100%}.title-UGdC69sw{color:var(--themed-color-primary-text,#1a1a1a);cursor:default;font-size:20px;font-weight:700;line-height:28px;overflow:hidden;white-space:nowrap}html.theme-dark .title-UGdC69sw{color:var(--themed-color-primary-text,#dbdbdb)}.infoHint-UGdC69sw{color:var(--themed-color-default-gray,#707070);height:18px;margin-left:8px;width:18px}html.theme-dark .infoHint-UGdC69sw{color:var(--themed-color-default-gray,#8c8c8c)}.form-UGdC69sw{display:flex;max-width:200px;width:100%}.inputWrapper-UGdC69sw{flex-grow:1}.input-UGdC69sw{font-size:24px;text-align:center}.hint-UGdC69sw{color:var(--themed-color-default-gray,#707070);cursor:default;font-size:12px;line-height:18px;margin-top:3px;max-width:100%;overflow:hidden;white-space:nowrap}html.theme-dark .hint-UGdC69sw{color:var(--themed-color-default-gray,#8c8c8c)}.error-UGdC69sw{color:#f23645}
|
||||
@@ -0,0 +1 @@
|
||||
.dialog-UGdC69sw{min-width:254px;padding:40px;width:auto}.dialogInner-UGdC69sw{align-items:center;display:flex;flex-direction:column}.titleWrapper-UGdC69sw{align-items:center;display:flex;justify-content:center;margin-bottom:16px;max-width:100%}.title-UGdC69sw{color:var(--themed-color-primary-text,#1a1a1a);cursor:default;font-size:20px;font-weight:700;line-height:28px;overflow:hidden;white-space:nowrap}html.theme-dark .title-UGdC69sw{color:var(--themed-color-primary-text,#dbdbdb)}.infoHint-UGdC69sw{color:var(--themed-color-default-gray,#707070);height:18px;margin-right:8px;width:18px}html.theme-dark .infoHint-UGdC69sw{color:var(--themed-color-default-gray,#8c8c8c)}.form-UGdC69sw{display:flex;max-width:200px;width:100%}.inputWrapper-UGdC69sw{flex-grow:1}.input-UGdC69sw{font-size:24px;text-align:center}.hint-UGdC69sw{color:var(--themed-color-default-gray,#707070);cursor:default;font-size:12px;line-height:18px;margin-top:3px;max-width:100%;overflow:hidden;white-space:nowrap}html.theme-dark .hint-UGdC69sw{color:var(--themed-color-default-gray,#8c8c8c)}.error-UGdC69sw{color:#f23645}
|
||||
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,7 @@
|
||||
"use strict";(self.webpackChunktradingview=self.webpackChunktradingview||[]).push([[1667],{11667:(e,t,i)=>{i.d(t,{LineToolRiskRewardBase:()=>N,registerReversibleTool:()=>E,roundValue:()=>M});var s=i(50279),r=i(50151),n=i(11542),o=i(8025),c=i(93280),a=i(74079),l=i(29875),u=i(76386),h=i(76050),d=i(98558),p=i(19063);class _ extends d.PriceAxisView{constructor(e,t){super(),this._source=e,this._data=t}_updateRendererData(e,t,i){if(e.visible=!1,!this._showAxisLabel())return;const s=this._source.priceScale();if(0===this._source.points().length||null===s||s.isEmpty())return;const r=this._source.ownerSource(),n=null!==r?r.firstValue():null;if(null===n)return;const o=this._data.priceProperty.value(),c=(0,p.resetTransparency)(this._data.colorProperty.value());i.background=c,i.textColor=this.generateTextColor(c),i.coordinate=s.priceToCoordinate(o,n),e.text=s.formatPrice(o,n),e.visible=!0}_showAxisLabel(){return this._source.properties().childs().showPriceLabels.value()||this._source.model().selection().isSelected(this._source)}}var y=i(12988);class P extends y.Property{constructor(e,t){super(),this._lineSource=e,this._pointIndex=t}value(){const e=this._lineSource.points(),t=e[this._pointIndex]?e[this._pointIndex].price:this._lineSource.normalizedPoints()[this._pointIndex].price;return this._formatAndParsePrice(t)}state(){return this.value()}merge(e,t){return this.setValue(e),t?[]:null}_formatAndParsePrice(e){const t=(0,r.ensureNotNull)(this._lineSource.ownerSource()),i=t.defaultFormatter?.()||t.formatter();if(i.parse){const t=i.format(e),s=i.parse(t);return s.res?s.value:e}return e}}class S extends P{constructor(e){super(e,0)}setValue(e){if(this._lineSource.isSourceHidden()){const t=this._lineSource.normalizedPoints();return t[this._pointIndex].price=parseFloat(e.toString()),void this._lineSource.restorePoints(t,[])}const t=this._lineSource.points()[this._pointIndex];this._lineSource.startChanging(this._pointIndex,t),t.price=parseFloat(e.toString()),this._lineSource.setPoint(this._pointIndex,t),this._lineSource.recalculate(),this._lineSource.model().updateSource(this._lineSource),this._listeners.fire(this,""),this._lineSource.endChanging(!1,!1),this._lineSource.syncPriceLevels()}}class v extends P{constructor(e){super(e,1)}value(){const e=this._lineSource.stopPrice();return this._formatAndParsePrice(e)}setValue(e){const t=Math.round(Math.abs(e-this._lineSource.entryPrice())*this._lineSource.ownerSourceBase());this._lineSource.properties().childs().stopLevel.setValue(t),this._lineSource.syncPriceLevels()}}class m extends P{constructor(e){super(e,2)}value(){const e=this._lineSource.profitPrice();return this._formatAndParsePrice(e)}setValue(e){const t=Math.round(Math.abs(e-this._lineSource.entryPrice())*this._lineSource.ownerSourceBase());this._lineSource.properties().childs().profitLevel.setValue(t),this._lineSource.syncPriceLevels()}}var f,g=i(37265),b=i(928),x=i(44672),w=i(77148),C=i(29023),k=i(45126),R=i(64147),L=i(92184),V=i(29137),A=i(19466);function M(e){return parseFloat(e.toFixed(2))}!function(e){
|
||||
e[e.InitialVersion=1]="InitialVersion",e[e.CurrentVersion=2]="CurrentVersion"}(f||(f={}));const I=new Map;function E(e,t){I.set(e,t)}const z=new k.TranslatedString("reverse {tool}",n.t(null,void 0,i(66643)));class N extends l.LineDataSource{constructor(e,t,s,n){super(e,t,s,n),this._hasEditableCoordinates=new R.WatchedValue(!1),this._studySource=null,this._metaInfo=null,this._riskInChange=!1,this._syncStateExclusions.push("points","entryPrice","stopPrice","targetPrice","stopLevel","profitLevel","riskSize","qty","amountTarget","amountStop");const o=this._metaInfo?.inputs.find((e=>"account_currency"===e.id)),a=t.childs().currency.value();o&&!o.options.includes(a)&&t.childs().currency.setValue(o.defval),o&&t.childs().currency.subscribe(this,this._updateStudySource),this.version=2,t.hasChild("stopLevel")||t.hasChild("profitLevel")||(t.addProperty("stopLevel",0),t.addProperty("profitLevel",0),this.ownerSourceChanged().subscribe(this,(()=>{const i=(0,r.ensureNotNull)(e.timeScale().visibleBarsStrictRange()),s=i.firstBar(),n=i.lastBar(),o=(0,r.ensureNotNull)(this.ownerSource()),a=o.priceScale();if(a){let e=(0,r.ensureNotNull)(o.priceRange(s,n,{targetPriceScale:a,scaleSeriesOnly:a?.isScaleSeriesOnly()}));if(a.isLog()){const t=a.logicalToPrice(e.minValue()),i=a.logicalToPrice(e.maxValue());e=new c.PriceRange(t,i)}if(e&&!e.isEmpty()){const i=Math.round(.2*e.length()*this.ownerSourceBase());t.merge({stopLevel:i,profitLevel:i})}}}),!0)),t.hasChild("entryPointCurrencyRate")||t.addProperty("entryPointCurrencyRate",1),t.hasChild("closePointCurrencyRate")||t.addProperty("closePointCurrencyRate",1);const l=t.childs();l.stopLevel.subscribe(this,this.recalculate),l.stopLevel.subscribe(null,(()=>{this.properties().childs().stopPrice.fireChanged()})),l.profitLevel.subscribe(this,this.recalculate),l.profitLevel.subscribe(null,(()=>{this.properties().childs().targetPrice.fireChanged()})),t.addChild("entryPrice",new S(this)),t.addChild("stopPrice",new v(this)),t.addChild("targetPrice",new m(this)),t.hasChild("riskSize")||t.addProperty("riskSize",0),t.hasChild("qty")||t.addProperty("qty",0),t.hasChild("amountTarget")||t.addProperty("amountTarget",l.accountSize.value()),t.hasChild("amountStop")||t.addProperty("amountStop",l.accountSize.value()),["riskSize","qty","amountTarget","amountStop","currency","entryPointCurrencyRate","closePointCurrencyRate"].forEach((e=>{t.addExcludedKey(e,1)})),["qty","amountTarget","amountStop","currency","entryPointCurrencyRate","closePointCurrencyRate"].forEach((e=>{t.addExcludedKey(e,4)})),l.risk.subscribe(this,this._recalculateRiskSize),l.accountSize.subscribe(this,this._recalculateRiskSize),l.riskDisplayMode.subscribe(this,this._recalculateRisk),l.riskDisplayMode.subscribe(this,this._recalculateRiskSize),l.entryPrice.subscribe(this,this._recalculateRiskSize),l.stopPrice.subscribe(this,this._recalculateRiskSize),l.profitLevel.subscribe(this,this._recalculateRiskSize),l.profitLevel.subscribe(this,this.syncPriceLevels.bind(this)),l.stopLevel.subscribe(this,this._recalculateRiskSize),
|
||||
l.stopLevel.subscribe(this,this.syncPriceLevels.bind(this)),l.qty.subscribe(this,this._recalculateRiskSize),this.ownerSourceChanged().subscribe(null,((e,t)=>{e&&e.barsProvider().dataUpdated().unsubscribeAll(this),t&&t.barsProvider().dataUpdated().subscribe(this,this._onSeriesUpdated)})),this.pointAdded().subscribe(this,(e=>{switch(e){case h.RiskRewardPointIndex.Entry:case h.RiskRewardPointIndex.Close:this._recalculateRiskSize(),this._recalculateQty()}this._updateStudySource()})),this.pointChanged().subscribe(this,(e=>{switch(e){case h.RiskRewardPointIndex.Entry:case h.RiskRewardPointIndex.Close:this._recalculateRiskSize(),this._recalculateQty()}this._updateStudySource()})),l.riskDisplayMode.value()===u.RiskDisplayMode.Percentage&&l.risk.value()>100&&l.riskDisplayMode.setValueSilently(u.RiskDisplayMode.Money),l.entryPrice.subscribe(this,this._recalculateQty),l.stopPrice.subscribe(this,this._recalculateQty),l.riskSize.subscribe(this,this._recalculateQty),l.entryPrice.subscribe(this,this._recalculateAmount),l.profitLevel.subscribe(this,this._recalculateAmount),l.stopLevel.subscribe(this,this._recalculateAmount),l.accountSize.subscribe(this,this._recalculateAmount),l.riskSize.subscribe(this,this._recalculateAmount),l.qty.subscribe(this,this._recalculateAmount),this._entryPriceAxisView=new _(this,{colorProperty:l.linecolor,priceProperty:l.entryPrice}),this._stopPriceAxisView=new _(this,{colorProperty:l.stopBackground,priceProperty:l.stopPrice}),this._profitPriceAxisView=new _(this,{colorProperty:l.profitBackground,priceProperty:l.targetPrice}),[l.entryPointCurrencyRate,l.closePointCurrencyRate].forEach((e=>{e.subscribe(this,(()=>{this._recalculateAmount(),this._recalculateRiskSize(),this._recalculateQty()}))})),Promise.all([i.e(6290),i.e(9116),i.e(1200),i.e(1583)]).then(i.bind(i,1971)).then((({RiskRewardPaneView:t})=>{const i=[new t(this,e)];this._setPaneViews(i)}))}destroy(){this.ownerSource()?.barsProvider().dataUpdated().unsubscribeAll(this),this.ownerSourceChanged().unsubscribeAll(this),this._studySource?.destroy(),super.destroy()}availableCurrencies(){const e=(0,r.ensureDefined)(this._metaInfo?.inputs.find((e=>"account_currency"===e.id)));return(0,r.ensureDefined)(e.options)}setOwnerSource(e){super.setOwnerSource(e);const t=this.ownerSource();t&&t.symbolSource().symbolInfo()&&(this._recalculateAmount(),this._recalculateRiskSize(),this._recalculateQty())}pointsCount(){return 2}priceAxisPoints(){if(!this._points.length)return[];const e=this._points[0],t=this._properties.childs();return[{...e,price:t.stopPrice.value()},{...e,price:t.entryPrice.value()},{...e,price:t.targetPrice.value()}]}priceAxisViews(e,t){return this.isSourceHidden()||t!==this.priceScale()||this._model.paneForSource(this)!==e?null:[this._entryPriceAxisView,this._stopPriceAxisView,this._profitPriceAxisView]}updateAllViews(e){this.isActualSymbol()&&this.properties().childs().visible.value()&&((0,b.hideAllDrawings)().value()&&this.userEditEnabled()||(super.updateAllViews(e),this._entryPriceAxisView.update(e),this._stopPriceAxisView.update(e),
|
||||
this._profitPriceAxisView.update(e)))}migrateVersion(e,t,i){if(1===e&&this._points.length>=1){const e=[];e.push(this._points[0]);let t=this._points[0];if(t={price:t.price,index:this._getClosePointIndex(t.index),interval:this._properties.childs().interval.value()},e.push(t),this._points[1]&&e.push(this._points[1]),this._points[2]&&e.push(this._points[2]),this._points=e,this._timePoint.length>=1){const t=[],i=this._timePoint[0];t.push(i);const s={price:i.price,time_t:i.time_t,offset:this._getClosePointIndex(i.offset)};t.push(s),this._timePoint[1]&&e.push(this._points[1]),this._timePoint[2]&&e.push(this._points[2]),this._timePoint=t}}}restoreExternalState(e){if(!(0,g.isNumber)(e.entryPrice))return void super.restoreExternalState(e);let t;if(this.isActualSymbol())t=e;else{const{entryPrice:i,...s}=e,[r]=this._timePoint;r.price=i,t=s}this.properties().merge(t)}addPoint(e,t,i){e.price=this._roundPrice(e.price),super.addPoint(e,void 0,!0);const s={price:e.price,index:this._getClosePointIndex(e.index)};super._addPointIntenal(s,void 0,!0);const r=this._calculateActualEntry(e,s);if(r){super._addPointIntenal(r,void 0,!0);const e=this._findClosePoint(r,s);e&&super._addPointIntenal(e,void 0,!0)}return this._lastPoint=null,this._normalizePoints(),this.createServerPoints(),!0}setPoint(e,t,i,s){if(this.isSourceHidden())return;const r=this.properties().childs();switch(this._muteSyncLineStyle(),e){case 0:this._changeEntryPoint({...t,interval:this._model.mainSeries().interval()});break;case 2:r.stopPrice.setValue(this.prepareStopPrice(t.price));break;case 3:r.targetPrice.setValue(this.prepareProfitPrice(t.price));break;case 1:t.price=this._points[0].price,super.setPoint(1,t),this.recalculate()}this._unmuteSyncLineStyleWithoutApplyingChanges(),s||this.syncPriceLevels()}getPoint(e){if(this.isSourceHidden())return null;switch(e){case 0:return this._points[0];case 1:return{index:this._points[1].index,price:this._points[0].price};case 2:return{index:this._points[0].index,price:this.stopPrice()};case 3:return{index:this._points[0].index,price:this.profitPrice()}}return null}setPoints(e){this.isSourceHidden()||(this._muteSyncLineStyle(),super.setPoints(e),this.recalculate(),this._unmuteSyncLineStyleWithoutApplyingChanges(),this.syncPriceLevels())}start(){super.start(),this.recalculate()}startMoving(e,t,i,s){const n=(0,r.ensureDefined)(e.logical);n.price=this._roundPrice(n.price),super.startMoving(e,t,i)}move(e,t,i,s){const n=(0,r.ensureDefined)(e.logical);n.price=this._roundPrice(n.price),super.move(e,t,i),this.recalculate(),this._entryPriceAxisView.update((0,x.sourceChangeEvent)(this.id()))}axisPoints(){if(!this._points[h.RiskRewardPointIndex.ActualEntry])return[];const e=this._points[h.RiskRewardPointIndex.ActualEntry];let t=null;if(4===this._points.length)t=this._points[h.RiskRewardPointIndex.ActualClose];else{const e=this.lastBarData();if(!e)return[];t={index:e.index,price:e.closePrice}}return[e,t]}recalculateStateByData(){this.recalculate()}recalculate(){if(0===this.points().length)return
|
||||
;const e=this.properties().childs(),t=e.targetPrice.value(),i=e.stopPrice.value(),s=[this._points[0],this._points[1]],r=this._calculateActualEntry(this.points()[0],this.points()[1]),n=this._model.mainSeries().interval();if(r){s.push({...r,interval:n});const e=this._findClosePoint(r,this.points()[1]);e&&s.push({...e,interval:n})}this._points=s,t!==e.targetPrice.value()&&e.targetPrice.fireChanged(),i!==e.stopPrice.value()&&e.stopPrice.fireChanged()}syncPriceLevels(){const e=this.linkKey().value();if(e){const t=this.properties().childs();this._syncLineStyleChanges(e,{entryPrice:t.entryPrice.value(),stopLevel:t.stopLevel.value(),profitLevel:t.profitLevel.value()})}}entryPrice(){const e=this.points();return 0===e.length?this._timePoint[0].price:e[0].price}lastBarData(){const e=this.ownerSource()?.barsProvider();if(!e)return null;const t=e.bars().firstIndex(),i=e.bars().lastIndex();if(null===t||null===i||isNaN(t)||isNaN(i))return null;const s=this.points();if(4===s.length){const e=s[h.RiskRewardPointIndex.ActualClose];return e.index<t?null:{closePrice:e.price,index:Math.min(i,e.index)}}const n=s[h.RiskRewardPointIndex.Close];if(n.index<t)return null;const c=Math.min(i,n.index),a=e.bars().search(c,o.PlotRowSearchMode.NearestLeft);return null===a?null:{closePrice:(0,r.ensure)(a.value[4]),index:a.index}}ownerSourceBase(){const e=this.ownerSource()?.symbolSource().symbolInfo();return e?e.pricescale/e.minmov:100}getOrderTemplate(){return null}template(){const e=this.properties().childs(),t=super.template();return t.stopLevel=e.stopLevel.value(),t.profitLevel=e.profitLevel.value(),t}async additionalActions(e){return{actions:[new C.Action({actionId:"Chart.LineTool.RiskReward.Reverse",options:{checkable:!1,label:n.t(null,void 0,i(64489)),onExecute:()=>{const t=z.format({tool:(0,V.getTranslatedStringForSource)(A.TitleDisplayTarget.StatusLine,this)});e.beginUndoMacro(t);const i=function(e,t){const i=e.points(),s=e.zorder(),n=(0,r.ensureNotNull)(t.model().paneForSource(e)),o=(0,r.ensureNotNull)(e.ownerSource()),c=(0,r.ensureDefined)(I.get(e.toolname)),a=c.propertiesFactory(t.model().backgroundTheme().spawnOwnership(),e.properties().state()),l=e.linkKey().value(),u=l?w.CreateLineToolSyncMode.ForceOn:w.CreateLineToolSyncMode.ForceOff,h=t.createLineTool({pane:n,point:i[0],linkKey:l?(0,L.randomHash)():void 0,linetool:c.targetToolName,properties:a,ownerSource:o,synchronizationMode:u,sharingMode:e.sharingMode().value()});return h&&(t.startChangingLinetool(h,h.points()[1],1),t.changeLinePoint(i[1]),t.endChangingLinetool(!1),t.insertBefore([h],e),h.setZorder(s)),t.removeSource(e,!1),h}(this,e);e.endUndoMacro(),i&&e.model().selectionMacro((e=>{e.addSourceToSelection(i,null)}))}}})],placement:"CustomAction"}}_entryPointCurrencyRate(){return this.properties().childs().entryPointCurrencyRate.value()}_closePointCurrencyRate(){return this.properties().childs().closePointCurrencyRate.value()}_ignoreSourceEvent(e){return super._ignoreSourceEvent(e)&&e.sourceId!==this._model.mainSeries().id()}_applyTemplateImpl(e){
|
||||
const{targetPrice:t,stopPrice:i,entryPrice:s,...r}=e;super._applyTemplateImpl(r);const n=this.properties().childs();void 0!==e.stopLevel&&n.stopLevel.setValue(e.stopLevel),void 0!==e.profitLevel&&n.profitLevel.setValue(e.profitLevel)}_propertiesStateExclusions(){return[...super._propertiesStateExclusions(),"entryPrice","stopPrice","targetPrice"]}_correctPoints(e,t){if(!this.isActualSymbol())return!1;const i=super._correctPoints(e.slice(0,this.pointsCount()),t);for(let t=0;t<e.length;t++){const i=e[t];i.price=this._roundPrice(i.price)}return i}async _getPropertyDefinitionsViewModelClass(){return(await Promise.all([i.e(6406),i.e(3889),i.e(8009),i.e(8056),i.e(8537)]).then(i.bind(i,2243))).RiskRewardDefinitionsViewModel}_recalculateRiskSize(){if(this._riskInChange)return;const e=this.properties().childs(),t=e.risk.value(),i=e.riskDisplayMode.value(),s=e.accountSize.value();i===u.RiskDisplayMode.Percentage?e.riskSize.setValue(t/100*s):t>s?(e.risk.setValue(s),e.riskSize.setValue(s)):e.riskSize.setValue(t)}_roundPrice(e){const t=this.ownerSourceBase();return Math.round(e*t)/t}_ownerSourcePointValue(){return this.ownerSource()?.symbolSource().symbolInfo()?.pointvalue??1}_onSourceHiddenMayChange(){super._onSourceHiddenMayChange(),this._updateStudySource()}static _configureProperties(e){l.LineDataSource._configureProperties(e),e.addExcludedKey("stopLevel",1),e.addExcludedKey("profitLevel",1),e.addExcludedKey("stopPrice",1),e.addExcludedKey("targetPrice",1),e.addExcludedKey("entryPrice",1)}_onSeriesUpdated(e,t,i){this.isSourceHidden()||this._points.length<2||null!==i&&i.index>Math.max(this._points[0].index,this._points[1].index)||this.recalculateStateByData()}_recalculateRisk(){const e=this.properties().childs(),t=e.riskDisplayMode.value(),i=e.riskSize.value(),s=e.accountSize.value();let r=e.risk.value();r=t===u.RiskDisplayMode.Percentage?M(i/s*100):M(s/100*r),this._riskInChange=!0,e.risk.setValue(parseFloat(this._riskFormatter(t).format(r,{ignoreLocaleNumberFormat:!0}))),this._riskInChange=!1}_recalculateAmount(){if(0===this.points().length)return;const e=this.properties().childs(),t=e.accountSize.value(),i=e.entryPrice.value(),s=e.qty.value(),r=e.stopPrice.value(),n=e.targetPrice.value(),o=this._ownerSourcePointValue();e.amountTarget.setValue(this._amountTarget(t,n,i,s,o)),e.amountStop.setValue(this._amountStop(t,r,i,s,o))}_recalculateQty(){if(0===this.points().length)return;const e=this.properties().childs(),t=e.entryPrice.value(),i=e.stopPrice.value(),s=e.riskSize.value(),r=this._entryPointCurrencyRate(),n=null===r?NaN:s/(Math.abs(t-i)*this._ownerSourcePointValue()*r);e.qty.setValue(n)}_calculateActualEntry(e,t){const i=this.ownerSource();if(!i)return null;const s=i.barsProvider().bars();if(s.isEmpty())return null;const n=(0,r.ensureNotNull)(s.firstIndex()),o=Math.max(e.index,n),c=e.price,a=(0,r.ensureNotNull)(s.lastIndex()),l=Math.min(a,t.index-1);for(const e of s.rangeIterator(o,l+1)){const t=e.value;if(null!==t&&(0,r.ensure)(t[2])>=c&&(0,r.ensure)(t[3])<=c)return{index:e.index,price:c}}return null}_riskFormatter(e){
|
||||
return e===u.RiskDisplayMode.Percentage?(0,a.getNumericFormatter)(2):(0,a.getNumericFormatter)()}_getClosePointIndex(e){const t=this._model.timeScale(),i=Math.round(t.width()/t.barSpacing());return e+Math.max(3,Math.round(.15*i))}_findClosePoint(e,t){const i=this.ownerSource();if(!i)return null;const s=i.barsProvider().bars(),n=(0,r.ensureNotNull)(s.firstIndex()),o=Math.max(e.index,n),c=(0,r.ensureNotNull)(s.lastIndex()),a=Math.min(c,t.index-1);for(const e of s.rangeIterator(o,a+1)){const t=e.value;if(null===t)continue;const i=this._checkStopPrice(t);if(null!=i)return{index:e.index,price:i}}return null}_changeEntryPoint(e){const t=this.properties().childs(),i=t.stopPrice.value(),s=t.targetPrice.value(),r=1/this.ownerSourceBase(),n=Math.min(i,s)+r,o=Math.max(i,s)-r;e.price=Math.max(n,Math.min(o,this._roundPrice(e.price))),this.setPoints([e,{...this._points[1],price:e.price}]),t.stopPrice.setValue(i),t.targetPrice.setValue(s)}_updateStudySource(){if(!this._metaInfo||this._isDestroyed)return;const e=this._properties.childs().currency.value(),t=this._model.mainSeries(),i="NONE"!==e&&e!==t.currency()&&!this.isSourceHidden();if(!i&&this._studySource?(this._studySource.destroy(),this._studySource=null,this._properties.childs().entryPointCurrencyRate.setValue(1),this._properties.childs().closePointCurrencyRate.setValue(1)):i&&!this._studySource&&(this._studySource=new RiskRewardStudyDataSource(this._model.chartApi(),t.seriesSource()),this._studySource.nonSeriesData().subscribe((e=>{e&&(this._properties.childs().entryPointCurrencyRate.setValue(e.currency_ratio[0]),this._properties.childs().closePointCurrencyRate.setValue(e.currency_ratio[1]??e.currency_ratio[0]))}))),this._studySource&&this._points.length>=2){const i=this._model.timeScale(),r=t.data().bars().firstIndex(),n=t.data().bars().lastIndex();if(null===r||null===n)return;const o=Math.min(n,Math.max(r,this._points[0].index)),c=Math.min(n,Math.max(r,this._points[1].index)),a=i.indexToTimePoint(o),l=i.indexToTimePoint(c);if(null!==a&&null!==l){const t={...this._studySource.inputs(),start_time:1e3*a,end_time:1e3*l,entry_price:this.entryPrice(),target_price:this.profitPrice(),stop_price:this.stopPrice(),account_currency:e};(0,s.default)(t,this._studySource.inputs())||this._studySource.setInputs(t),this._studySource.isStarted()||this._studySource.start()}}}}},76386:(e,t,i)=>{var s;i.d(t,{RiskDisplayMode:()=>s}),function(e){e.Percentage="percents",e.Money="money"}(s||(s={}))},76050:(e,t,i)=>{var s;i.d(t,{RiskRewardPointIndex:()=>s}),function(e){e[e.Entry=0]="Entry",e[e.Close=1]="Close",e[e.ActualEntry=2]="ActualEntry",e[e.ActualClose=3]="ActualClose"}(s||(s={}))}}]);
|
||||
@@ -0,0 +1 @@
|
||||
.container-zLVm6B4t{align-items:flex-start;border-radius:4px;cursor:default;display:flex;overflow:auto;padding:8px}.container-zLVm6B4t,html.theme-dark .container-zLVm6B4t{background:var(--themed-color-tooltip-wizard-bg,#2962ff)}.content-zLVm6B4t{padding:4px 8px}.arrowHolder-zLVm6B4t{position:absolute}.arrowHolder-zLVm6B4t:after{border:0 solid;box-sizing:border-box;content:"";display:block;height:0;position:absolute;width:0}.arrowHolder-zLVm6B4t:after,html.theme-dark .arrowHolder-zLVm6B4t:after{border-color:var(--themed-color-tooltip-wizard-bg,#2962ff)}.arrowHolder--above-zLVm6B4t:after,.arrowHolder--below-zLVm6B4t:after{border-left:6px solid;border-left-color:var(--themed-color-tooltip-force-transparent,#0000);border-right:6px solid;left:50%;margin-left:-6px}.arrowHolder--above-zLVm6B4t:after,.arrowHolder--below-zLVm6B4t:after,html.theme-dark .arrowHolder--above-zLVm6B4t:after,html.theme-dark .arrowHolder--below-zLVm6B4t:after{border-right-color:var(--themed-color-tooltip-force-transparent,#0000)}html.theme-dark .arrowHolder--above-zLVm6B4t:after,html.theme-dark .arrowHolder--below-zLVm6B4t:after{border-left-color:var(--themed-color-tooltip-force-transparent,#0000)}.arrowHolder--below-zLVm6B4t:after{border-bottom-width:4px;bottom:100%}.arrowHolder--above-zLVm6B4t:after{border-top-width:4px;top:100%}.arrowHolder--after-zLVm6B4t:after,.arrowHolder--before-zLVm6B4t:after{border-bottom:6px solid;border-top:6px solid;border-top-color:var(--themed-color-tooltip-force-transparent,#0000);margin-top:-6px;top:50%}.arrowHolder--after-zLVm6B4t:after,.arrowHolder--before-zLVm6B4t:after,html.theme-dark .arrowHolder--after-zLVm6B4t:after,html.theme-dark .arrowHolder--before-zLVm6B4t:after{border-bottom-color:var(--themed-color-tooltip-force-transparent,#0000)}html.theme-dark .arrowHolder--after-zLVm6B4t:after,html.theme-dark .arrowHolder--before-zLVm6B4t:after{border-top-color:var(--themed-color-tooltip-force-transparent,#0000)}.arrowHolder--before-zLVm6B4t:after{border-right-width:4px;right:100%}.arrowHolder--after-zLVm6B4t:after{border-left-width:4px;left:100%}.arrowHolder--above-fix-zLVm6B4t{bottom:0}.arrowHolder--after-ltr-fix-zLVm6B4t{right:0}.label-zLVm6B4t{display:flex;flex:1 1 auto;margin-right:24px}.closeButton-zLVm6B4t{color:#fff}.container-kfvcmk8t{display:flex;justify-content:center;left:10px;pointer-events:none;position:absolute;right:10px}.centerElement-kfvcmk8t{pointer-events:auto;z-index:1}.text-kfvcmk8t{color:#fff;font-size:14px;line-height:21px;margin-bottom:auto;word-wrap:break-word}
|
||||
@@ -0,0 +1 @@
|
||||
.container-zLVm6B4t{align-items:flex-start;border-radius:4px;cursor:default;display:flex;overflow:auto;padding:8px}.container-zLVm6B4t,html.theme-dark .container-zLVm6B4t{background:var(--themed-color-tooltip-wizard-bg,#2962ff)}.content-zLVm6B4t{padding:4px 8px}.arrowHolder-zLVm6B4t{position:absolute}.arrowHolder-zLVm6B4t:after{border:0 solid;box-sizing:border-box;content:"";display:block;height:0;position:absolute;width:0}.arrowHolder-zLVm6B4t:after,html.theme-dark .arrowHolder-zLVm6B4t:after{border-color:var(--themed-color-tooltip-wizard-bg,#2962ff)}.arrowHolder--above-zLVm6B4t:after,.arrowHolder--below-zLVm6B4t:after{border-left:6px solid;border-left-color:var(--themed-color-tooltip-force-transparent,#0000);border-right:6px solid;border-right-color:var(--themed-color-tooltip-force-transparent,#0000);left:50%;margin-left:-6px}html.theme-dark .arrowHolder--above-zLVm6B4t:after,html.theme-dark .arrowHolder--below-zLVm6B4t:after{border-left-color:var(--themed-color-tooltip-force-transparent,#0000);border-right-color:var(--themed-color-tooltip-force-transparent,#0000)}.arrowHolder--below-zLVm6B4t:after{border-bottom-width:4px;bottom:100%}.arrowHolder--above-zLVm6B4t:after{border-top-width:4px;top:100%}.arrowHolder--after-zLVm6B4t:after,.arrowHolder--before-zLVm6B4t:after{border-bottom:6px solid;border-top:6px solid;border-top-color:var(--themed-color-tooltip-force-transparent,#0000);margin-top:-6px;top:50%}.arrowHolder--after-zLVm6B4t:after,.arrowHolder--before-zLVm6B4t:after,html.theme-dark .arrowHolder--after-zLVm6B4t:after,html.theme-dark .arrowHolder--before-zLVm6B4t:after{border-bottom-color:var(--themed-color-tooltip-force-transparent,#0000)}html.theme-dark .arrowHolder--after-zLVm6B4t:after,html.theme-dark .arrowHolder--before-zLVm6B4t:after{border-top-color:var(--themed-color-tooltip-force-transparent,#0000)}.arrowHolder--before-zLVm6B4t:after{border-right-width:4px;right:100%}.arrowHolder--after-zLVm6B4t:after{border-left-width:4px;left:100%}.arrowHolder--above-fix-zLVm6B4t{bottom:0}.arrowHolder--before-rtl-fix-zLVm6B4t{left:0}.arrowHolder--after-ltr-fix-zLVm6B4t{right:0}.label-zLVm6B4t{display:flex;flex:1 1 auto;margin-left:24px}.closeButton-zLVm6B4t{color:#fff}.container-kfvcmk8t{display:flex;justify-content:center;left:10px;pointer-events:none;position:absolute;right:10px}.centerElement-kfvcmk8t{pointer-events:auto;z-index:1}.text-kfvcmk8t{color:#fff;font-size:14px;line-height:21px;margin-bottom:auto;word-wrap:break-word}
|
||||
@@ -0,0 +1 @@
|
||||
.titleWrap-e3jFxbHm{align-items:center;display:flex}.ellipsis-e3jFxbHm{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.hideInput-e3jFxbHm,.hideText-e3jFxbHm{height:0;visibility:hidden}.empty-e3jFxbHm{height:34px;margin-right:-3px;width:34px}.hideEmpty-e3jFxbHm{margin:0;width:0}.editIcon-e3jFxbHm{align-items:center;border-radius:2px;color:var(--themed-color-toolbar-interactive-element-text-normal,#1a1a1a);cursor:default;display:flex;flex-shrink:0;height:34px;justify-content:center;margin-left:5px;width:34px}html.theme-dark .editIcon-e3jFxbHm{color:var(--themed-color-toolbar-interactive-element-text-normal,#dbdbdb)}@media (any-hover:hover){.editIcon-e3jFxbHm:hover{background-color:var(--themed-color-bg-primary-hover,#f2f2f2)}html.theme-dark .editIcon-e3jFxbHm:hover{background-color:var(--themed-color-bg-primary-hover,#303030)}}.scrollable-Ycj0dUGE{flex:1 1 auto;min-height:145px;overflow-x:hidden;overflow-y:auto;-webkit-overflow-scrolling:touch}@media (max-height:290px){.scrollable-Ycj0dUGE{min-height:auto}}@supports (-moz-appearance:none){.scrollable-Ycj0dUGE{scrollbar-color:var(--themed-color-scroll-bg,#9c9c9c) #0000;scrollbar-width:thin}html.theme-dark .scrollable-Ycj0dUGE{scrollbar-color:var(--themed-color-scroll-bg,#3d3d3d) #0000}}.scrollable-Ycj0dUGE::-webkit-scrollbar{height:5px;width:5px}.scrollable-Ycj0dUGE::-webkit-scrollbar-thumb{background-clip:content-box;background-color:var(--tv-color-scrollbar-thumb-background,var(--themed-color-scroll-bg,#9c9c9c));border:1px solid #0000;border-radius:3px}html.theme-dark .scrollable-Ycj0dUGE::-webkit-scrollbar-thumb{background-color:var(--tv-color-scrollbar-thumb-background,var(--themed-color-scroll-bg,#3d3d3d))}.scrollable-Ycj0dUGE::-webkit-scrollbar-track{background-color:initial;border-radius:3px}.scrollable-Ycj0dUGE::-webkit-scrollbar-corner{display:none}.tabs-Ycj0dUGE,.tabs-xNPrJ8dY{--ui-lib-underline-tabs-hor-padding:20px;padding:0 var(--ui-lib-underline-tabs-hor-padding)}
|
||||
@@ -0,0 +1 @@
|
||||
.titleWrap-e3jFxbHm{align-items:center;display:flex}.ellipsis-e3jFxbHm{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.hideInput-e3jFxbHm,.hideText-e3jFxbHm{height:0;visibility:hidden}.empty-e3jFxbHm{height:34px;margin-left:-3px;width:34px}.hideEmpty-e3jFxbHm{margin:0;width:0}.editIcon-e3jFxbHm{align-items:center;border-radius:2px;color:var(--themed-color-toolbar-interactive-element-text-normal,#1a1a1a);cursor:default;display:flex;flex-shrink:0;height:34px;justify-content:center;margin-right:5px;width:34px}html.theme-dark .editIcon-e3jFxbHm{color:var(--themed-color-toolbar-interactive-element-text-normal,#dbdbdb)}@media (any-hover:hover){.editIcon-e3jFxbHm:hover{background-color:var(--themed-color-bg-primary-hover,#f2f2f2)}html.theme-dark .editIcon-e3jFxbHm:hover{background-color:var(--themed-color-bg-primary-hover,#303030)}}.scrollable-Ycj0dUGE{flex:1 1 auto;min-height:145px;overflow-x:hidden;overflow-y:auto;-webkit-overflow-scrolling:touch}@media (max-height:290px){.scrollable-Ycj0dUGE{min-height:auto}}@supports (-moz-appearance:none){.scrollable-Ycj0dUGE{scrollbar-color:var(--themed-color-scroll-bg,#9c9c9c) #0000;scrollbar-width:thin}html.theme-dark .scrollable-Ycj0dUGE{scrollbar-color:var(--themed-color-scroll-bg,#3d3d3d) #0000}}.scrollable-Ycj0dUGE::-webkit-scrollbar{height:5px;width:5px}.scrollable-Ycj0dUGE::-webkit-scrollbar-thumb{background-clip:content-box;background-color:var(--tv-color-scrollbar-thumb-background,var(--themed-color-scroll-bg,#9c9c9c));border:1px solid #0000;border-radius:3px}html.theme-dark .scrollable-Ycj0dUGE::-webkit-scrollbar-thumb{background-color:var(--tv-color-scrollbar-thumb-background,var(--themed-color-scroll-bg,#3d3d3d))}.scrollable-Ycj0dUGE::-webkit-scrollbar-track{background-color:initial;border-radius:3px}.scrollable-Ycj0dUGE::-webkit-scrollbar-corner{display:none}.tabs-Ycj0dUGE,.tabs-xNPrJ8dY{--ui-lib-underline-tabs-hor-padding:20px;padding:0 var(--ui-lib-underline-tabs-hor-padding)}
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
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,11 @@
|
||||
(self.webpackChunktradingview=self.webpackChunktradingview||[]).push([[2157],{59142:function(e,t){var n,o,s;o=[t],n=function(e){"use strict";function t(e){if(Array.isArray(e)){for(var t=0,n=Array(e.length);t<e.length;t++)n[t]=e[t];return n}return Array.from(e)}Object.defineProperty(e,"__esModule",{value:!0});var n=!1;if("undefined"!=typeof window){var o={get passive(){n=!0}};window.addEventListener("testPassive",null,o),window.removeEventListener("testPassive",null,o)}var s="undefined"!=typeof window&&window.navigator&&window.navigator.platform&&/iP(ad|hone|od)/.test(window.navigator.platform),r=[],a=!1,i=-1,l=void 0,c=void 0,u=function(e){return r.some((function(t){return!(!t.options.allowTouchMove||!t.options.allowTouchMove(e))}))},d=function(e){var t=e||window.event;return!!u(t.target)||1<t.touches.length||(t.preventDefault&&t.preventDefault(),!1)},h=function(){setTimeout((function(){void 0!==c&&(document.body.style.paddingRight=c,c=void 0),void 0!==l&&(document.body.style.overflow=l,l=void 0)}))};e.disableBodyScroll=function(e,o){if(s){if(!e)return void console.error("disableBodyScroll unsuccessful - targetElement must be provided when calling disableBodyScroll on IOS devices.");if(e&&!r.some((function(t){return t.targetElement===e}))){var h={targetElement:e,options:o||{}};r=[].concat(t(r),[h]),e.ontouchstart=function(e){1===e.targetTouches.length&&(i=e.targetTouches[0].clientY)},e.ontouchmove=function(t){var n,o,s,r;1===t.targetTouches.length&&(o=e,r=(n=t).targetTouches[0].clientY-i,!u(n.target)&&(o&&0===o.scrollTop&&0<r||(s=o)&&s.scrollHeight-s.scrollTop<=s.clientHeight&&r<0?d(n):n.stopPropagation()))},a||(document.addEventListener("touchmove",d,n?{passive:!1}:void 0),a=!0)}}else{p=o,setTimeout((function(){if(void 0===c){var e=!!p&&!0===p.reserveScrollBarGap,t=window.innerWidth-document.documentElement.clientWidth;e&&0<t&&(c=document.body.style.paddingRight,document.body.style.paddingRight=t+"px")}void 0===l&&(l=document.body.style.overflow,document.body.style.overflow="hidden")}));var m={targetElement:e,options:o||{}};r=[].concat(t(r),[m])}var p},e.clearAllBodyScrollLocks=function(){s?(r.forEach((function(e){e.targetElement.ontouchstart=null,e.targetElement.ontouchmove=null})),a&&(document.removeEventListener("touchmove",d,n?{passive:!1}:void 0),a=!1),r=[],i=-1):(h(),r=[])},e.enableBodyScroll=function(e){if(s){if(!e)return void console.error("enableBodyScroll unsuccessful - targetElement must be provided when calling enableBodyScroll on IOS devices.");e.ontouchstart=null,e.ontouchmove=null,r=r.filter((function(t){return t.targetElement!==e})),a&&0===r.length&&(document.removeEventListener("touchmove",d,n?{passive:!1}:void 0),a=!1)}else 1===r.length&&r[0].targetElement===e?(h(),r=[]):r=r.filter((function(t){return t.targetElement!==e}))}},void 0===(s="function"==typeof n?n.apply(t,o):n)||(e.exports=s)},11362:e=>{e.exports={wrapper:"wrapper-GZajBGIm",input:"input-GZajBGIm",view:"view-GZajBGIm",danger:"danger-GZajBGIm"}},4052:e=>{e.exports={box:"box-ywH2tsV_",noOutline:"noOutline-ywH2tsV_",
|
||||
disabled:"disabled-ywH2tsV_","intent-danger":"intent-danger-ywH2tsV_",checked:"checked-ywH2tsV_",check:"check-ywH2tsV_",icon:"icon-ywH2tsV_",dot:"dot-ywH2tsV_",disableActiveStyles:"disableActiveStyles-ywH2tsV_"}},4665:e=>{e.exports={loader:"loader-UL6iwcBa",static:"static-UL6iwcBa",item:"item-UL6iwcBa","tv-button-loader":"tv-button-loader-UL6iwcBa",medium:"medium-UL6iwcBa",small:"small-UL6iwcBa",black:"black-UL6iwcBa",white:"white-UL6iwcBa",gray:"gray-UL6iwcBa",primary:"primary-UL6iwcBa"}},36110:e=>{e.exports={accessible:"accessible-rm8yeqY4"}},22846:e=>{e.exports={loaderWrap:"loaderWrap-jGEARQlM",big:"big-jGEARQlM",loader:"loader-jGEARQlM"}},31668:e=>{e.exports={item:"item-GJX1EXhk",interactive:"interactive-GJX1EXhk",hovered:"hovered-GJX1EXhk",disabled:"disabled-GJX1EXhk",active:"active-GJX1EXhk",shortcut:"shortcut-GJX1EXhk",normal:"normal-GJX1EXhk",big:"big-GJX1EXhk",iconCell:"iconCell-GJX1EXhk",icon:"icon-GJX1EXhk",content:"content-GJX1EXhk",label:"label-GJX1EXhk",checked:"checked-GJX1EXhk",toolbox:"toolbox-GJX1EXhk",showToolboxOnHover:"showToolboxOnHover-GJX1EXhk",arrowIcon:"arrowIcon-GJX1EXhk",subMenu:"subMenu-GJX1EXhk",invisibleHotkey:"invisibleHotkey-GJX1EXhk"}},21320:e=>{e.exports={row:"row-DFIg7eOh",line:"line-DFIg7eOh",hint:"hint-DFIg7eOh"}},37399:e=>{e.exports={menu:"menu-Tx5xMZww"}},70159:e=>{e.exports={item:"item-WJDah4zD",emptyIcons:"emptyIcons-WJDah4zD",loading:"loading-WJDah4zD",disabled:"disabled-WJDah4zD",interactive:"interactive-WJDah4zD",hovered:"hovered-WJDah4zD",normal:"normal-WJDah4zD",big:"big-WJDah4zD",icon:"icon-WJDah4zD",label:"label-WJDah4zD",title:"title-WJDah4zD",nested:"nested-WJDah4zD",shortcut:"shortcut-WJDah4zD",remove:"remove-WJDah4zD"}},20669:e=>{e.exports={separator:"separator-Ymxd0dt_"}},36718:e=>{e.exports={"default-drawer-min-top-distance":"100px",wrap:"wrap-_HnK0UIN",positionBottom:"positionBottom-_HnK0UIN",backdrop:"backdrop-_HnK0UIN",drawer:"drawer-_HnK0UIN",positionLeft:"positionLeft-_HnK0UIN"}},22413:e=>{e.exports={favorite:"favorite-_FRQhM5Y",hovered:"hovered-_FRQhM5Y",disabled:"disabled-_FRQhM5Y",focused:"focused-_FRQhM5Y",active:"active-_FRQhM5Y",checked:"checked-_FRQhM5Y"}},35990:e=>{e.exports={button:"button-iLKiGOdQ",hovered:"hovered-iLKiGOdQ",disabled:"disabled-iLKiGOdQ",focused:"focused-iLKiGOdQ",active:"active-iLKiGOdQ",hidden:"hidden-iLKiGOdQ"}},70673:(e,t,n)=>{"use strict";n.d(t,{CheckboxInput:()=>c});var o=n(50959),s=n(97754),r=n(90186),a=n(5811),i=n(11362),l=n.n(i);function c(e){const t=s(l().wrapper,e.className);return o.createElement("span",{className:t,title:e.title,style:e.style},o.createElement("input",{id:e.id,tabIndex:e.tabIndex,className:s(e.intent&&l()[e.intent],l().input),type:"checkbox",name:e.name,checked:e.checked,disabled:e.disabled,value:e.value,autoFocus:e.autoFocus,role:e.role,onChange:function(){e.onChange?.(e.value)},ref:e.reference,"aria-required":e["aria-required"],"aria-describedby":e["aria-describedby"],"aria-invalid":e["aria-invalid"],...(0,r.filterDataProps)(e)}),o.createElement(a.CheckboxView,{className:l().view,
|
||||
indeterminate:e.indeterminate,checked:e.checked,disabled:e.disabled,intent:e.intent,tabIndex:e.tabIndex}))}},5811:(e,t,n)=>{"use strict";n.d(t,{CheckboxView:()=>c});var o=n(50959),s=n(97754),r=n(9745),a=n(65890),i=n(4052),l=n.n(i);function c(e){const{indeterminate:t,checked:n,tabIndex:i,className:c,disabled:u,disableActiveStyles:d,intent:h,hideIcon:m,...p}=e,v=t||!n||m?"":a,b=s(l().box,l()[`intent-${h}`],!t&&l().check,!!t&&l().dot,-1===i&&l().noOutline,c,n&&l().checked,u&&l().disabled,d&&l().disableActiveStyles);return o.createElement("span",{className:b,...p},o.createElement(r.Icon,{icon:v,className:l().icon}))}},26996:(e,t,n)=>{"use strict";n.d(t,{Loader:()=>l});var o,s=n(50959),r=n(97754),a=n(4665),i=n.n(a);function l(e){const{className:t,size:n="medium",staticPosition:o,color:a="black"}=e,l=r(i().item,i()[a],i()[n]);return s.createElement("span",{className:r(i().loader,o&&i().static,t)},s.createElement("span",{className:l}),s.createElement("span",{className:l}),s.createElement("span",{className:l}))}!function(e){e.Medium="medium",e.Small="small"}(o||(o={}))},74670:(e,t,n)=>{"use strict";n.d(t,{useActiveDescendant:()=>r});var o=n(50959),s=n(39416);function r(e,t=[]){const[n,r]=(0,o.useState)(!1),a=(0,s.useFunctionalRefObject)(e);return(0,o.useLayoutEffect)((()=>{const e=a.current;if(null===e)return;const t=e=>{switch(e.type){case"active-descendant-focus":r(!0);break;case"active-descendant-blur":r(!1)}};return e.addEventListener("active-descendant-focus",t),e.addEventListener("active-descendant-blur",t),()=>{e.removeEventListener("active-descendant-focus",t),e.removeEventListener("active-descendant-blur",t)}}),t),[a,n]}},50238:(e,t,n)=>{"use strict";n.d(t,{useRovingTabindexElement:()=>r});var o=n(50959),s=n(39416);function r(e,t=[]){const[n,r]=(0,o.useState)(!1),a=(0,s.useFunctionalRefObject)(e);return(0,o.useLayoutEffect)((()=>{const e=a.current;if(null===e)return;const t=e=>{switch(e.type){case"roving-tabindex:main-element":r(!0);break;case"roving-tabindex:secondary-element":r(!1)}};return e.addEventListener("roving-tabindex:main-element",t),e.addEventListener("roving-tabindex:secondary-element",t),()=>{e.removeEventListener("roving-tabindex:main-element",t),e.removeEventListener("roving-tabindex:secondary-element",t)}}),t),[a,n?0:-1]}},10772:(e,t,n)=>{"use strict";n.d(t,{ContextMenuAction:()=>x});var o=n(50959),s=n(50151),r=n(91561),a=n(59064),i=n(51768),l=n(63273);var c=n(83021),u=n(97754),d=n.n(u),h=n(26996),m=n(5304),p=n(22846);function v(e){const{size:t="normal"}=e;return o.createElement(m.ContextMenuItem,{size:t,jsxLabel:o.createElement("div",{className:d()(p.loaderWrap,p[t])},o.createElement(h.Loader,{className:p.loader})),noInteractive:!0,onMouseOver:e.onMouseOver})}var b=n(3343),f=n(50238),E=n(36110);const g=(0,o.forwardRef)((function(e,t){const{className:n,...s}=e,[r,a]=(0,f.useRovingTabindexElement)(t);return o.createElement(m.ContextMenuItem,{...s,className:d()(E.accessible,n),reference:r,tabIndex:a,onKeyDown:function(e){if(e.target!==e.currentTarget)return;const t=(0,b.hashFromEvent)(e)
|
||||
;13!==t&&32!==t||(e.preventDefault(),r.current instanceof HTMLElement&&r.current.click())},"data-role":"menuitem","aria-disabled":e.disabled||void 0})}));var w=n(90186);class x extends o.PureComponent{constructor(e){super(e),this._itemRef=null,this._menuElementRef=o.createRef(),this._menuRef=null,this._handleClick=e=>{e.isDefaultPrevented()||this.state.disabled||(this._hasSubItems()?this._showSubMenu():(this.state.doNotCloseOnClick||(0,a.globalCloseMenu)(),this.props.action.execute(),this._trackEvent(),this.props.onExecute&&this.props.onExecute(this.props.action)))},this._handleClickToolbox=()=>{(0,a.globalCloseMenu)()},this._handleItemMouseOver=()=>{this._showSubMenu(),this._setCurrentContextValue()},this._handleMenuMouseOver=()=>{this._setCurrentContextValue()},this._showSubMenu=()=>{this.props.onShowSubMenu(this.props.action)},this._calcSubMenuPos=e=>function(e,t,n={x:0,y:10}){if(t){const{left:n,right:o,top:s}=t.getBoundingClientRect(),r=document.documentElement.clientWidth,a={x:n-e,y:s},i={x:o,y:s};return(0,l.isRtl)()?n<=e?i:a:r-o>=e?i:a}return n}(e.contentWidth,this._itemRef),this._updateState=e=>{this.setState(e.getState())},this._setItemRef=e=>{this._itemRef=e},this._handleMenuRef=e=>{this._menuRef=e},this._registerSubmenu=()=>this.context?.registerSubmenu(this.props.action.id,(e=>(0,s.ensureNotNull)(this._itemRef).contains(e)||null!==this._menuElementRef.current&&this._menuElementRef.current.contains(e))),this.state={...this.props.action.getState()}}componentDidMount(){this.props.action.onUpdate().subscribe(this,this._updateState),this.state.subItems.length&&(this._unsubscribe=this._registerSubmenu()),this.props.reference&&(this._itemRef=this.props.reference.current)}componentDidUpdate(e,t){t.loading!==this.state.loading&&this.props.onRequestUpdate?.(),0===t.subItems.length&&this.state.subItems.length>0&&(this._unsubscribe=this._registerSubmenu()),t.subItems.length>0&&0===this.state.subItems.length&&this._unsubscribe?.(),t.subItems!==this.state.subItems&&null!==this._menuRef&&this._menuRef.update()}componentWillUnmount(){this.props.action.onUpdate().unsubscribe(this,this._updateState),this._unsubscribe&&this._unsubscribe()}render(){const e=this.context?.current?this.context.current===this.props.action.id:this.props.isSubMenuOpened;return this.state.loading?o.createElement(v,{size:this.state.size}):o.createElement(g,{...(0,w.filterDataProps)(this.props),theme:this.props.theme,ref:this.props.reference??this._setItemRef,onClick:this._handleClick,onClickToolbox:this._handleClickToolbox,onMouseOver:this._handleItemMouseOver,hovered:e,hasSubItems:this._hasSubItems(),actionName:this.state.name,checkboxInput:this.props.checkboxInput,selected:this.props.selected,className:this.props.className,...this.state},o.createElement(r.ContextMenu,{isOpened:e,items:this.state.subItems,position:this._calcSubMenuPos,menuStatName:this.props.menuStatName,parentStatName:this._getStatName(),menuElementReference:this._menuElementRef,onMouseOver:this.state.subItems.length?this._handleMenuMouseOver:void 0,ref:this._handleMenuRef}))}
|
||||
_setCurrentContextValue(){this.state.subItems.length&&this.context?.setCurrent(this.props.action.id)}_hasSubItems(){return this.state.subItems.length>0}_trackEvent(){const e=this._getStatName();(0,i.trackEvent)("ContextMenuClick",this.props.menuStatName||"",e)}_getStatName(){return[this.props.parentStatName,this.state.statName].filter((e=>Boolean(e))).join(".")}}x.contextType=c.SubmenuContext},5304:(e,t,n)=>{"use strict";n.d(t,{ContextMenuItem:()=>w,DEFAUL_CONTEXT_MENU_ITEM_THEME:()=>E});var o=n(50959),s=n(97754),r=n(70673),a=n(49483),i=n(71382),l=n(96040),c=n(36189),u=n(99025),d=n(25812),h=n(56570),m=n(90186),p=n(60925),v=n(60004),b=n(14665),f=n(31668);const E=f,g=h.enabled("items_favoriting");class w extends o.PureComponent{constructor(){super(...arguments),this._handleMouseOver=e=>{(0,i.isTouchEvent)(e.nativeEvent)||this.props.onMouseOver&&this.props.onMouseOver()},this._handleClickToolbox=e=>{e.stopPropagation(),this.props.onClickToolbox&&this.props.onClickToolbox()}}render(){const{hasSubItems:e,shortcutHint:t,hint:n,invisibleHotkey:r,favourite:i,theme:l=f,size:d="normal",onKeyDown:h,label:p,jsxLabel:v,styledLabel:E}=this.props,w=this.props.checkable&&this.props.checkboxInput?"label":"div";return o.createElement(o.Fragment,null,o.createElement("tr",{...(0,m.filterDataProps)(this.props),...(0,m.filterAriaProps)(this.props),id:this.props.id,className:s(this.props.className,l.item,!this.props.noInteractive&&l.interactive,this.props.hovered&&l.hovered,this.props.disabled&&l.disabled,this.props.active&&l.active,this.props.selected&&l.selected,l[d]),onClick:this.props.onClick,onMouseOver:this._handleMouseOver,ref:this.props.reference,"data-action-name":this.props.actionName,tabIndex:this.props.tabIndex,onKeyDown:h},g&&void 0!==i&&o.createElement("td",{className:l.favoriteActionCell},o.createElement(c.FavoriteButton,{id:`${this.props.id}-favorite`,className:l.favourite,isFilled:i,onClick:this.props.onFavouriteClick,"data-role":"list-item-action"})),o.createElement("td",{className:s(l.iconCell),"data-icon-cell":!0},this._icon(l)),o.createElement("td",{className:l.contentCell},o.createElement(w,{className:l.content},o.createElement("span",{className:s(l.label,this.props.checked&&l.checked),"data-label":!0},!v&&E?E.map((({text:e,...t},n)=>o.createElement("span",{key:n,style:t},e))):v??p),this._toolbox(l),e&&o.createElement("span",{className:l.arrowIcon,dangerouslySetInnerHTML:{__html:b},"data-submenu-arrow":!0}),!e&&t&&!a.CheckMobile.any()&&o.createElement(u.Hint,{className:s(r&&l.invisibleHotkey),text:t}),!e&&!t&&n&&o.createElement(u.Hint,{text:n})))),o.createElement("tr",{className:l.subMenu},o.createElement("td",null,this.props.children)))}_icon(e){if(this.props.checkable){if(this.props.checkboxInput)return o.createElement(r.CheckboxInput,{className:s(e.icon,e.checkboxInput),checked:this.props.checked});if(this.props.checked){const t=!this.props.icon&&!this.props.iconChecked,n=this.props.iconChecked||this.props.icon||v;return o.createElement("span",{className:e.icon,dangerouslySetInnerHTML:{__html:n},
|
||||
"data-icon-checkmark":t})}return this.props.icon?o.createElement("span",{className:e.icon,dangerouslySetInnerHTML:{__html:this.props.icon}}):o.createElement("span",{className:e.icon})}return this.props.icon?o.createElement("span",{className:e.icon,dangerouslySetInnerHTML:{__html:this.props.icon}}):null}_toolbox(e){return this.props.toolbox?o.createElement("span",{className:s(e.toolbox,this.props.showToolboxOnHover&&e.showToolboxOnHover),onClick:this._handleClickToolbox,"data-toolbox":!0},this._renderToolboxContent()):null}_renderToolboxContent(){return this.props.toolbox&&this.props.toolbox.type===d.ToolboxType.Delete?o.createElement(l.RemoveButton,{icon:p,onClick:this.props.toolbox.action}):null}}},91561:(e,t,n)=>{"use strict";n.d(t,{ContextMenu:()=>_,OverlapContextMenu:()=>M});var o=n(50959),s=n(97754),r=n.n(s),a=n(86431),i=n(27317),l=n(52778);class c extends o.PureComponent{constructor(){super(...arguments),this._handleKeyDown=e=>{e.keyCode===this.props.keyCode&&this.props.handler(e)}}componentDidMount(){document.addEventListener(this.props.eventType||"keydown",this._handleKeyDown,!1)}componentWillUnmount(){document.removeEventListener(this.props.eventType||"keydown",this._handleKeyDown,!1)}render(){return null}}var u=n(75535),d=n(37558),h=n(90692),m=n(20669);function p(e){return o.createElement("li",{className:m.separator})}var v=n(23829),b=n(41590),f=n(59064);function E(e){const t=e.action.custom()??e.action,[n,s]=(0,o.useState)((()=>t.getState())),[r,a]=(0,o.useState)(!1),i=!!n.subItems.length,l=i&&r;return(0,o.useEffect)((()=>{const e=()=>s(t.getState());return t.onUpdate().subscribe(null,e),()=>{t.onUpdate().unsubscribe(null,e)}}),[]),o.createElement(v.ContextMenuItem,{...n,onClick:function(e){if(n.disabled||e.defaultPrevented)return;if(i)return void a(!0);n.doNotCloseOnClick||(0,f.globalCloseMenu)();t.execute()},isLoading:n.loading,isHovered:l},l&&o.createElement(b.Drawer,{onClose:c},o.createElement(x,{items:n.subItems,parentAction:t,closeNested:c})));function c(e){e&&e.preventDefault(),a(!1)}}var g=n(54627),w=n(66493);function x(e){const{items:t,parentAction:n,closeNested:s}=e,r=!Boolean(n)&&t.every((e=>!Boolean("separator"!==e.type&&(e.getState().icon||e.getState().checkable))));return o.createElement(g.EmptyIconsContext.Provider,{value:r},o.createElement("ul",null,n&&o.createElement(o.Fragment,null,o.createElement(v.ContextMenuItem,{label:n.getState().label,isTitle:!0,active:!1,disabled:!1,subItems:[],checkable:!1,checked:!1,doNotCloseOnClick:!1,icon:w,onClick:s}),o.createElement(p,null)),t.map((e=>{switch(e.type){case"action":return o.createElement(E,{key:e.id,action:e});case"separator":return o.createElement(p,{key:e.id})}}))))}const k=o.createContext(null);var y=n(20243),C=n(37399);class _ extends o.PureComponent{constructor(e){super(e),this._menuRef=o.createRef(),this._handleRequestUpdate=()=>{this.update()},this._handleClose=()=>{this.props.onClose&&this.props.onClose()},this._handleOutsideClickClose=e=>{const{doNotCloseOn:t,onClose:n}=this.props;!n||void 0!==t&&t.contains(e.target)||n()},
|
||||
this._handleFocusOnOpen=()=>{this.props.menuElementReference?.current&&this.props.takeFocus&&this.props.menuElementReference?.current.focus({preventScroll:!0})},this._handleFocus=e=>{this.props.isKeyboardEvent&&e.target&&(0,y.focusFirstMenuItem)(e.target)},this.state={}}render(){const{isOpened:e,onClose:t,items:n,doNotCloseOn:s,menuStatName:a,parentStatName:m,takeFocus:p,...v}=this.props;return e&&n.length>0?o.createElement(d.DrawerManager,null,o.createElement(c,{keyCode:27,eventType:"keyup",handler:this._handleClose}),o.createElement(h.MatchMedia,{rule:"(max-width: 440px)"},(t=>this._isDrawer(t)?o.createElement(k.Provider,{value:{type:"drawer"}},o.createElement(b.Drawer,{onClose:this._handleClose,position:"Bottom","data-name":v["data-name"]},o.createElement(x,{items:n}))):o.createElement(k.Provider,{value:{type:"menu"}},o.createElement(l.OutsideEvent,{handler:this._handleOutsideClickClose,mouseDown:!0,touchStart:!0,reference:this.props.menuElementReference},(t=>o.createElement(i.Menu,{...v,reference:t,className:r()(C.menu,"context-menu"),onClose:this._handleClose,noMomentumBasedScroll:!0,ref:this._menuRef,tabIndex:p?-1:void 0,onOpen:this._handleFocusOnOpen,onFocus:this._handleFocus,onKeyDown:y.handleAccessibleMenuKeyDown},o.createElement(u.ActionsTable,{items:n,menuStatName:a,parentStatName:m,parentIsOpened:e,onRequestUpdate:this._handleRequestUpdate})))))))):null}update(){this._menuRef.current&&this._menuRef.current.update(),this.props.isKeyboardEvent&&this.props.menuElementReference?.current&&document.activeElement===this.props.menuElementReference.current&&(0,y.focusFirstMenuItem)(this.props.menuElementReference.current)}_isDrawer(e){return void 0===this.props.mode?e:"drawer"===this.props.mode}}const M=(0,a.makeOverlapable)(_)},99025:(e,t,n)=>{"use strict";n.d(t,{Hint:()=>i});var o=n(50959),s=n(97754),r=n.n(s),a=n(31668);function i(e){const{text:t="",className:n}=e;return o.createElement("span",{className:r()(a.shortcut,n)},t)}},23829:(e,t,n)=>{"use strict";n.d(t,{ContextMenuItem:()=>p});var o=n(50959),s=n(97754),r=n.n(s),a=n(9745),i=n(26996),l=n(54627),c=n(99025),u=n(39750),d=n(79978),h=n(60925),m=n(70159);function p(e){const{className:t,isTitle:n,isLoading:s,isHovered:p,active:v,checkable:b,disabled:f,checked:E,icon:g,iconChecked:w,hint:x,subItems:k,label:y,styledLabel:C,onClick:_,children:M,toolbox:S,jsxLabel:N,size:I="normal"}=e,D=(0,o.useContext)(l.EmptyIconsContext),L=!!k.length;return s?o.createElement("li",{className:r()(t,m.item,m.loading,m[I])},o.createElement(i.Loader,null)):o.createElement("li",{className:r()(t,m.item,m.interactive,n&&m.title,f&&m.disabled,p&&m.hovered,v&&m.active,D&&m.emptyIcons,m[I]),onClick:_},o.createElement(a.Icon,{className:r()(m.icon),icon:function(){if(b&&E)return w||g||u;return g}()}),o.createElement("span",{className:r()(m.label)},!N&&C?C.map((({text:e,...t},n)=>o.createElement("span",{key:n,style:t},e))):N??y),!!S&&o.createElement(a.Icon,{onClick:function(){S&&S.action()},className:m.remove,icon:h}),!L&&x&&o.createElement(c.Hint,{className:m.shortcut,text:x
|
||||
}),L&&o.createElement(a.Icon,{className:m.nested,icon:d}),M)}},54627:(e,t,n)=>{"use strict";n.d(t,{EmptyIconsContext:()=>o});const o=n(50959).createContext(!1)},37558:(e,t,n)=>{"use strict";n.d(t,{DrawerContext:()=>a,DrawerManager:()=>r});var o=n(50959),s=n(99054);class r extends o.PureComponent{constructor(e){super(e),this._isBodyFixed=!1,this._addDrawer=e=>{this.setState((t=>({stack:[...t.stack,e]})))},this._removeDrawer=e=>{this.setState((t=>({stack:t.stack.filter((t=>t!==e))})))},this.state={stack:[]}}componentDidUpdate(e,t){!t.stack.length&&this.state.stack.length&&((0,s.setFixedBodyState)(!0),this._isBodyFixed=!0),t.stack.length&&!this.state.stack.length&&this._isBodyFixed&&((0,s.setFixedBodyState)(!1),this._isBodyFixed=!1)}componentWillUnmount(){this.state.stack.length&&this._isBodyFixed&&(0,s.setFixedBodyState)(!1)}render(){return o.createElement(a.Provider,{value:{addDrawer:this._addDrawer,removeDrawer:this._removeDrawer,currentDrawer:this.state.stack.length?this.state.stack[this.state.stack.length-1]:null}},this.props.children)}}const a=o.createContext(null)},41590:(e,t,n)=>{"use strict";n.d(t,{Drawer:()=>m});var o=n(50959),s=n(50151),r=n(97754),a=n(92184),i=n(42842),l=n(37558),c=n(29197),u=n(86656),d=n(36718);var h;function m(e){const{position:t="Bottom",onClose:n,children:u,reference:h,className:m,theme:v=d}=e,b=(0,s.ensureNotNull)((0,o.useContext)(l.DrawerContext)),[f]=(0,o.useState)((()=>(0,a.randomHash)())),E=(0,o.useRef)(null),g=(0,o.useContext)(c.CloseDelegateContext);return(0,o.useLayoutEffect)((()=>((0,s.ensureNotNull)(E.current).focus({preventScroll:!0}),g.subscribe(b,n),b.addDrawer(f),()=>{b.removeDrawer(f),g.unsubscribe(b,n)})),[]),o.createElement(i.Portal,null,o.createElement("div",{ref:h,className:r(d.wrap,d[`position${t}`])},f===b.currentDrawer&&o.createElement("div",{className:d.backdrop,onClick:n}),o.createElement(p,{className:r(v.drawer,d[`position${t}`],m),ref:E,"data-name":e["data-name"]},u)))}!function(e){e.Left="Left",e.Bottom="Bottom"}(h||(h={}));const p=(0,o.forwardRef)(((e,t)=>{const{className:n,...s}=e;return o.createElement(u.TouchScrollContainer,{className:r(d.drawer,n),tabIndex:-1,ref:t,...s})}))},71402:(e,t,n)=>{"use strict";n.d(t,{RemoveTitleType:()=>o,removeTitlesMap:()=>r});var o,s=n(11542);!function(e){e.Add="add",e.Remove="remove"}(o||(o={}));const r={[o.Add]:s.t(null,void 0,n(69207)),[o.Remove]:s.t(null,void 0,n(85106))}},36189:(e,t,n)=>{"use strict";n.d(t,{FavoriteButton:()=>h});var o=n(50959),s=n(97754),r=n.n(s),a=n(9745),i=n(71402),l=n(74670),c=n(39146),u=n(48010),d=n(22413);function h(e){const{className:t,isFilled:n,isActive:s,onClick:h,title:m,...p}=e,[v,b]=(0,l.useActiveDescendant)(null),f=m??(n?i.removeTitlesMap[i.RemoveTitleType.Remove]:i.removeTitlesMap[i.RemoveTitleType.Add]);return(0,o.useLayoutEffect)((()=>{const e=v.current;e instanceof HTMLElement&&f&&e.dispatchEvent(new CustomEvent("common-tooltip-update"))}),[f,v]),o.createElement(a.Icon,{...p,className:r()(d.favorite,"apply-common-tooltip",n&&d.checked,s&&d.active,b&&d.focused,t),onClick:h,icon:n?c:u,
|
||||
title:f,ariaLabel:f,ref:v})}},96040:(e,t,n)=>{"use strict";n.d(t,{RemoveButton:()=>d});var o=n(11542),s=n(50959),r=n(97754),a=n.n(r),i=n(9745),l=n(74670),c=n(33765),u=n(35990);function d(e){const{className:t,isActive:r,onClick:d,onMouseDown:h,title:m,hidden:p,"data-name":v="remove-button",icon:b,...f}=e,[E,g]=(0,l.useActiveDescendant)(null);return s.createElement(i.Icon,{...f,"data-name":v,className:a()(u.button,"apply-common-tooltip",r&&u.active,p&&u.hidden,g&&u.focused,t),icon:b||c,onClick:d,onMouseDown:h,title:m??o.t(null,void 0,n(67410)),ariaLabel:m??o.t(null,void 0,n(67410)),ref:E})}},86656:(e,t,n)=>{"use strict";n.d(t,{TouchScrollContainer:()=>c});var o=n(50959),s=n(59142),r=n(50151),a=n(49483);const i=CSS.supports("overscroll-behavior","none");let l=0;const c=(0,o.forwardRef)(((e,t)=>{const{children:n,...r}=e,c=(0,o.useRef)(null);return(0,o.useImperativeHandle)(t,(()=>c.current)),(0,o.useLayoutEffect)((()=>{if(a.CheckMobile.iOS())return l++,null!==c.current&&(i?1===l&&(document.body.style.overscrollBehavior="none"):(0,s.disableBodyScroll)(c.current,{allowTouchMove:u(c)})),()=>{l--,null!==c.current&&(i?0===l&&(document.body.style.overscrollBehavior=""):(0,s.enableBodyScroll)(c.current))}}),[]),o.createElement("div",{ref:c,...r},n)}));function u(e){return t=>{const n=(0,r.ensureNotNull)(e.current),o=document.activeElement;return!n.contains(t)||null!==o&&n.contains(o)&&o.contains(t)}}},20243:(e,t,n)=>{"use strict";n.d(t,{focusFirstMenuItem:()=>u,handleAccessibleMenuFocus:()=>l,handleAccessibleMenuKeyDown:()=>c,queryMenuElements:()=>m});var o=n(19291),s=n(57177),r=n(68335),a=n(15754);const i=[37,39,38,40];function l(e,t){if(!e.target)return;const n=e.relatedTarget?.getAttribute("aria-activedescendant");if(e.relatedTarget!==t.current){const e=n&&document.getElementById(n);if(!e||e!==t.current)return}u(e.target)}function c(e){if(e.defaultPrevented)return;const t=(0,r.hashFromEvent)(e);if(!i.includes(t))return;const n=document.activeElement;if(!(document.activeElement instanceof HTMLElement))return;const a=m(e.currentTarget).sort(o.navigationOrderComparator);if(0===a.length)return;const l=document.activeElement.closest('[data-role="menuitem"]')||document.activeElement.parentElement?.querySelector('[data-role="menuitem"]');if(!(l instanceof HTMLElement))return;const c=a.indexOf(l);if(-1===c)return;const u=p(l),v=u.indexOf(document.activeElement),b=-1!==v,f=e=>{n&&(0,s.becomeSecondaryElement)(n),(0,s.becomeMainElement)(e),e.focus()};switch((0,o.mapKeyCodeToDirection)(t)){case"inlinePrev":if(!u.length)return;e.preventDefault(),f(0===v?a[c]:b?d(u,v,-1):u[u.length-1]);break;case"inlineNext":if(!u.length)return;e.preventDefault(),v===u.length-1?f(a[c]):f(b?d(u,v,1):u[0]);break;case"blockPrev":{e.preventDefault();const t=d(a,c,-1);if(b){const e=h(t,v);f(e||t);break}f(t);break}case"blockNext":{e.preventDefault();const t=d(a,c,1);if(b){const e=h(t,v);f(e||t);break}f(t)}}}function u(e){const[t]=m(e);t&&((0,s.becomeMainElement)(t),t.focus())}function d(e,t,n){return e[(t+e.length+n)%e.length]}function h(e,t){const n=p(e)
|
||||
;return n.length?n[(t+n.length)%n.length]:null}function m(e){return Array.from(e.querySelectorAll('[data-role="menuitem"]:not([disabled]):not([aria-disabled])')).filter((0,a.createScopedVisibleElementFilter)(e))}function p(e){return Array.from(e.querySelectorAll("[tabindex]:not([disabled]):not([aria-disabled])")).filter((0,a.createScopedVisibleElementFilter)(e))}},57177:(e,t,n)=>{"use strict";var o;function s(e){e.dispatchEvent(new CustomEvent("roving-tabindex:main-element"))}function r(e){e.dispatchEvent(new CustomEvent("roving-tabindex:secondary-element"))}n.d(t,{becomeMainElement:()=>s,becomeSecondaryElement:()=>r}),function(e){e.MainElement="roving-tabindex:main-element",e.SecondaryElement="roving-tabindex:secondary-element"}(o||(o={}))},75535:(e,t,n)=>{"use strict";n.d(t,{ActionsTable:()=>i});var o=n(50959),s=n(21320);function r(e){return o.createElement("tr",{className:s.row},o.createElement("td",null,o.createElement("div",{className:s.line})),o.createElement("td",null,o.createElement("div",{className:s.line}),e.hint?o.createElement("div",{className:s.hint},e.hint):null))}var a=n(10772);class i extends o.PureComponent{constructor(e){super(e),this._handleShowSubMenu=e=>{const t=e.getState();this.setState({showSubMenuOf:t.subItems.length?e:void 0})},this.state={}}render(){return o.createElement("table",null,o.createElement("tbody",null,this.props.items.map((e=>this._item(e)))))}static getDerivedStateFromProps(e,t){return!e.parentIsOpened&&t.showSubMenuOf?{showSubMenuOf:void 0}:null}_item(e){switch(e.type){case"separator":return o.createElement(r,{key:e.id,hint:e.getHint()});case"action":const t=e.custom()??e;return o.createElement(a.ContextMenuAction,{key:t.id,action:t,onShowSubMenu:this._handleShowSubMenu,isSubMenuOpened:this.state.showSubMenuOf===t,menuStatName:this.props.menuStatName,parentStatName:this.props.parentStatName,onRequestUpdate:this.props.onRequestUpdate})}}}},60925:e=>{e.exports='<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 18 18" width="18" height="18"><path fill="currentColor" d="M12 4h3v1h-1.04l-.88 9.64a1.5 1.5 0 0 1-1.5 1.36H6.42a1.5 1.5 0 0 1-1.5-1.36L4.05 5H3V4h3v-.5C6 2.67 6.67 2 7.5 2h3c.83 0 1.5.67 1.5 1.5V4ZM7.5 3a.5.5 0 0 0-.5.5V4h4v-.5a.5.5 0 0 0-.5-.5h-3ZM5.05 5l.87 9.55a.5.5 0 0 0 .5.45h5.17a.5.5 0 0 0 .5-.45L12.94 5h-7.9Z"/></svg>'},60004:e=>{e.exports='<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 28 28" width="28" height="28"><path fill="currentColor" d="M22 9.06 11 20 6 14.7l1.09-1.02 3.94 4.16L20.94 8 22 9.06Z"/></svg>'},65890:e=>{e.exports='<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 11 9" width="11" height="9" fill="none"><path stroke="currentColor" stroke-width="2" d="M0.999878 4L3.99988 7L9.99988 1"/></svg>'},66493:e=>{e.exports='<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 28 28" width="28" height="28" fill="none"><path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M16.5 20L11 14.5 16.5 9"/></svg>'},79978: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="M8 5l3.5 3.5L8 12"/></svg>'},39750:e=>{e.exports='<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 28 28" width="28" height="28" fill="none"><path stroke="currentColor" stroke-linecap="round" stroke-width="1.5" d="M7 15l5 5L23 9"/></svg>'},33765:e=>{e.exports='<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18"><path fill="currentColor" d="M9.707 9l4.647-4.646-.707-.708L9 8.293 4.354 3.646l-.708.708L8.293 9l-4.647 4.646.708.708L9 9.707l4.646 4.647.708-.707L9.707 9z"/></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 @@
|
||||
.title-u3QJgF_p{cursor:default;font-size:11px;letter-spacing:.4px;line-height:16px;margin:6px 0;padding:0 12px;text-transform:uppercase}.title-u3QJgF_p,html.theme-dark .title-u3QJgF_p{color:var(--tv-color-popup-element-secondary-text,var(--themed-color-popup-element-secondary-text,grey))}
|
||||
@@ -0,0 +1 @@
|
||||
.title-u3QJgF_p{cursor:default;font-size:11px;letter-spacing:.4px;line-height:16px;margin:6px 0;padding:0 12px;text-transform:uppercase}.title-u3QJgF_p,html.theme-dark .title-u3QJgF_p{color:var(--tv-color-popup-element-secondary-text,var(--themed-color-popup-element-secondary-text,grey))}
|
||||
@@ -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)}}]);
|
||||
@@ -0,0 +1 @@
|
||||
.actionButton-k53vexPa{margin:0 6px}.actionButton-k53vexPa:first-child{margin-right:0}.actionButton-k53vexPa:last-child{margin-left:0}.actionButton-k53vexPa.small-k53vexPa{margin:6px 0}.actionButton-k53vexPa.small-k53vexPa:first-child{margin-top:0}.actionButton-k53vexPa.small-k53vexPa:last-child{margin-bottom:0}.hiddenTitle-k53vexPa{visibility:hidden}.popupDialog-B02UUUN3{max-height:calc(100% - 20px);max-width:480px;width:calc(100% - 20px)}.wrap-B02UUUN3{cursor:default;display:flex;overflow:hidden}.main-B02UUUN3{color:var(--themed-color-toolbar-interactive-element-text-normal,#1a1a1a);display:flex;flex:1 1 auto;flex-direction:column;margin:40px 0 40px 40px}html.theme-dark .main-B02UUUN3{color:var(--themed-color-toolbar-interactive-element-text-normal,#dbdbdb)}.main-B02UUUN3.small-B02UUUN3{margin:20px 0 20px 20px}.title-B02UUUN3{--ui-lib-typography-line-height:28px;line-height:var(--ui-lib-typography-line-height);--ui-lib-typography-font-size:20px;align-items:center;display:flex;flex:none;font-size:var(--ui-lib-typography-font-size);font-style:normal;font-weight:600;margin-bottom:8px;width:calc(100% - 9px);word-break:break-word}.title-B02UUUN3.small-B02UUUN3{width:calc(100% - 29px)}.content-B02UUUN3{--ui-lib-typography-line-height:24px;line-height:var(--ui-lib-typography-line-height);--ui-lib-typography-font-size:16px;display:flex;flex:1 1 auto;flex-direction:column;font-size:var(--ui-lib-typography-font-size);font-style:normal;font-weight:400;min-height:145px;overflow-x:hidden;overflow-y:auto;white-space:pre-wrap;word-break:break-word;-webkit-overflow-scrolling:touch;margin:0 -40px;min-height:0;padding:8px 40px}@media (max-height:290px){.content-B02UUUN3{min-height:auto}}@supports (-moz-appearance:none){.content-B02UUUN3{scrollbar-color:var(--themed-color-scroll-bg,#9c9c9c) #0000;scrollbar-width:thin}html.theme-dark .content-B02UUUN3{scrollbar-color:var(--themed-color-scroll-bg,#3d3d3d) #0000}}.content-B02UUUN3::-webkit-scrollbar{height:5px;width:5px}.content-B02UUUN3::-webkit-scrollbar-thumb{background-clip:content-box;background-color:var(--tv-color-scrollbar-thumb-background,var(--themed-color-scroll-bg,#9c9c9c));border:1px solid #0000;border-radius:3px}html.theme-dark .content-B02UUUN3::-webkit-scrollbar-thumb{background-color:var(--tv-color-scrollbar-thumb-background,var(--themed-color-scroll-bg,#3d3d3d))}.content-B02UUUN3::-webkit-scrollbar-track{background-color:initial;border-radius:3px}.content-B02UUUN3::-webkit-scrollbar-corner{display:none}.content-B02UUUN3.small-B02UUUN3{margin:0 -20px;padding:8px 20px}.content-B02UUUN3.html-B02UUUN3{display:block}.content-B02UUUN3 a,html.theme-dark .content-B02UUUN3 a{color:var(--themed-color-link,#2962ff)}.footer-B02UUUN3{display:flex;flex:none;flex-direction:row-reverse;justify-content:flex-start;margin-top:16px}.footer-B02UUUN3.small-B02UUUN3{flex-direction:column}.close-B02UUUN3{align-items:center;border-radius:2px;color:var(--themed-color-toolbar-interactive-element-text-normal,#1a1a1a);cursor:default;display:flex;flex:none;justify-content:center;margin:8px 8px 0 -2px}html.theme-dark .close-B02UUUN3{color:var(--themed-color-toolbar-interactive-element-text-normal,#dbdbdb)}@media (any-hover:hover){.close-B02UUUN3:hover{background-color:var(--themed-color-bg-primary-hover,#f2f2f2)}html.theme-dark .close-B02UUUN3:hover{background-color:var(--themed-color-bg-primary-hover,#303030)}}.close-B02UUUN3.small-B02UUUN3{margin-left:-22px}.marginWithoutCloseButton-B02UUUN3{margin-right:40px}.marginWithoutCloseButton-B02UUUN3.small-B02UUUN3{margin-right:20px}.label-nb7ji1l2{color:var(--themed-color-default-gray,#707070);font-size:14px;line-height:21px}html.theme-dark .label-nb7ji1l2{color:var(--themed-color-default-gray,#8c8c8c)}
|
||||
@@ -0,0 +1 @@
|
||||
.actionButton-k53vexPa{margin:0 6px}.actionButton-k53vexPa:first-child{margin-left:0}.actionButton-k53vexPa:last-child{margin-right:0}.actionButton-k53vexPa.small-k53vexPa{margin:6px 0}.actionButton-k53vexPa.small-k53vexPa:first-child{margin-top:0}.actionButton-k53vexPa.small-k53vexPa:last-child{margin-bottom:0}.hiddenTitle-k53vexPa{visibility:hidden}.popupDialog-B02UUUN3{max-height:calc(100% - 20px);max-width:480px;width:calc(100% - 20px)}.wrap-B02UUUN3{cursor:default;display:flex;overflow:hidden}.main-B02UUUN3{color:var(--themed-color-toolbar-interactive-element-text-normal,#1a1a1a);display:flex;flex:1 1 auto;flex-direction:column;margin:40px 40px 40px 0}html.theme-dark .main-B02UUUN3{color:var(--themed-color-toolbar-interactive-element-text-normal,#dbdbdb)}.main-B02UUUN3.small-B02UUUN3{margin:20px 20px 20px 0}.title-B02UUUN3{--ui-lib-typography-line-height:28px;line-height:var(--ui-lib-typography-line-height);--ui-lib-typography-font-size:20px;align-items:center;display:flex;flex:none;font-size:var(--ui-lib-typography-font-size);font-style:normal;font-weight:600;margin-bottom:8px;width:calc(100% - 9px);word-break:break-word}.title-B02UUUN3.small-B02UUUN3{width:calc(100% - 29px)}.content-B02UUUN3{--ui-lib-typography-line-height:24px;line-height:var(--ui-lib-typography-line-height);--ui-lib-typography-font-size:16px;display:flex;flex:1 1 auto;flex-direction:column;font-size:var(--ui-lib-typography-font-size);font-style:normal;font-weight:400;min-height:145px;overflow-x:hidden;overflow-y:auto;white-space:pre-wrap;word-break:break-word;-webkit-overflow-scrolling:touch;margin:0 -40px;min-height:0;padding:8px 40px}@media (max-height:290px){.content-B02UUUN3{min-height:auto}}@supports (-moz-appearance:none){.content-B02UUUN3{scrollbar-color:var(--themed-color-scroll-bg,#9c9c9c) #0000;scrollbar-width:thin}html.theme-dark .content-B02UUUN3{scrollbar-color:var(--themed-color-scroll-bg,#3d3d3d) #0000}}.content-B02UUUN3::-webkit-scrollbar{height:5px;width:5px}.content-B02UUUN3::-webkit-scrollbar-thumb{background-clip:content-box;background-color:var(--tv-color-scrollbar-thumb-background,var(--themed-color-scroll-bg,#9c9c9c));border:1px solid #0000;border-radius:3px}html.theme-dark .content-B02UUUN3::-webkit-scrollbar-thumb{background-color:var(--tv-color-scrollbar-thumb-background,var(--themed-color-scroll-bg,#3d3d3d))}.content-B02UUUN3::-webkit-scrollbar-track{background-color:initial;border-radius:3px}.content-B02UUUN3::-webkit-scrollbar-corner{display:none}.content-B02UUUN3.small-B02UUUN3{margin:0 -20px;padding:8px 20px}.content-B02UUUN3.html-B02UUUN3{display:block}.content-B02UUUN3 a,html.theme-dark .content-B02UUUN3 a{color:var(--themed-color-link,#2962ff)}.footer-B02UUUN3{display:flex;flex:none;flex-direction:row-reverse;justify-content:flex-start;margin-top:16px}.footer-B02UUUN3.small-B02UUUN3{flex-direction:column}.close-B02UUUN3{align-items:center;border-radius:2px;color:var(--themed-color-toolbar-interactive-element-text-normal,#1a1a1a);cursor:default;display:flex;flex:none;justify-content:center;margin:8px -2px 0 8px}html.theme-dark .close-B02UUUN3{color:var(--themed-color-toolbar-interactive-element-text-normal,#dbdbdb)}@media (any-hover:hover){.close-B02UUUN3:hover{background-color:var(--themed-color-bg-primary-hover,#f2f2f2)}html.theme-dark .close-B02UUUN3:hover{background-color:var(--themed-color-bg-primary-hover,#303030)}}.close-B02UUUN3.small-B02UUUN3{margin-right:-22px}.marginWithoutCloseButton-B02UUUN3{margin-left:40px}.marginWithoutCloseButton-B02UUUN3.small-B02UUUN3{margin-left:20px}.label-nb7ji1l2{color:var(--themed-color-default-gray,#707070);font-size:14px;line-height:21px}html.theme-dark .label-nb7ji1l2{color:var(--themed-color-default-gray,#8c8c8c)}
|
||||
@@ -0,0 +1 @@
|
||||
.opacity-EnWts7Xu{align-items:center;display:flex}.opacitySlider-EnWts7Xu{background-color:var(--themed-color-opacity-bg,#fff);background-image:url(opacity-pattern.4d8fbb552dde3db26f4a.svg);background-position:1px;border-radius:5px;flex:1 0 auto;height:10px;position:relative}html.theme-dark .opacitySlider-EnWts7Xu{background-color:var(--themed-color-opacity-bg,#000)}.opacitySliderGradient-EnWts7Xu{background-color:initial;background-image:linear-gradient(90deg,#0000,currentColor);border:1px solid;border-radius:4px;box-sizing:border-box;color:inherit;display:block;height:100%;width:100%}.pointer-EnWts7Xu{background-color:initial;background-color:var(--themed-color-container-fill-primary-inverse,#fff);border:2px solid var(--themed-color-border-primary-neutral-extra-heavy,#000);border-radius:50%;box-shadow:0 1px 2px #00000080;box-sizing:border-box;height:12px;margin:-1px 0 0;position:absolute;transition:left .1s,top .1s;width:12px}html.theme-dark .pointer-EnWts7Xu{background-color:var(--themed-color-container-fill-primary-inverse,#000);border:2px solid var(--themed-color-border-primary-neutral-extra-heavy,#fff)}.pointer-EnWts7Xu.dragged-EnWts7Xu{transition:left 0s}.opacityPointerWrap-EnWts7Xu{left:0;position:absolute;top:0;width:calc(100% - 12px)}.opacityInputWrap-EnWts7Xu{align-items:center;color:var(--themed-color-input-text,#1a1a1a);display:flex;position:relative}html.theme-dark .opacityInputWrap-EnWts7Xu{color:var(--themed-color-input-text,#dbdbdb)}.opacityInput-EnWts7Xu{background-color:initial;border:1px solid var(--themed-color-input-border,#dbdbdb);border-radius:4px;box-sizing:border-box;display:flex;height:26px;line-height:24px;margin-left:8px;padding:0 14px 0 5px;text-align:right;width:47px}html.theme-dark .opacityInput-EnWts7Xu{border:1px solid var(--themed-color-input-border,#575757)}.opacityInput-EnWts7Xu:focus,html.theme-dark .opacityInput-EnWts7Xu:focus{border-color:var(--themed-color-brand,#2962ff)}.opacityInputPercent-EnWts7Xu{left:40px;pointer-events:none;position:absolute;text-align:right;top:5px}.accessible-EnWts7Xu{outline:none;overflow:visible;position:relative}.accessible-EnWts7Xu:focus{outline:none}.accessible-EnWts7Xu:focus-visible{outline:none}.accessible-EnWts7Xu:after{border-style:solid;border-width:2px;box-sizing:border-box;content:"";display:none;height:calc(100% + 8px);left:-4px;pointer-events:none;position:absolute;top:-4px;width:calc(100% + 8px);z-index:1}.accessible-EnWts7Xu:focus:after{display:block}.accessible-EnWts7Xu:focus-visible:after{display:block}.accessible-EnWts7Xu:focus:not(:focus-visible):after{display:none}.accessible-EnWts7Xu:after{border-color:#2962ff;border-radius:6px}
|
||||
@@ -0,0 +1 @@
|
||||
.opacity-EnWts7Xu{align-items:center;display:flex}.opacitySlider-EnWts7Xu{background-color:var(--themed-color-opacity-bg,#fff);background-image:url(opacity-pattern.4d8fbb552dde3db26f4a.svg);background-position:1px;border-radius:5px;flex:1 0 auto;height:10px;position:relative}html.theme-dark .opacitySlider-EnWts7Xu{background-color:var(--themed-color-opacity-bg,#000)}.opacitySliderGradient-EnWts7Xu{background-color:initial;background-image:linear-gradient(270deg,#0000,currentColor);border:1px solid;border-radius:4px;box-sizing:border-box;color:inherit;display:block;height:100%;width:100%}.pointer-EnWts7Xu{background-color:initial;background-color:var(--themed-color-container-fill-primary-inverse,#fff);border:2px solid var(--themed-color-border-primary-neutral-extra-heavy,#000);border-radius:50%;box-shadow:0 1px 2px #00000080;box-sizing:border-box;height:12px;margin:-1px 0 0;position:absolute;transition:right .1s,top .1s;width:12px}html.theme-dark .pointer-EnWts7Xu{background-color:var(--themed-color-container-fill-primary-inverse,#000);border:2px solid var(--themed-color-border-primary-neutral-extra-heavy,#fff)}.pointer-EnWts7Xu.dragged-EnWts7Xu{transition:right 0s}.opacityPointerWrap-EnWts7Xu{left:0;position:absolute;top:0;width:calc(100% - 12px)}.opacityInputWrap-EnWts7Xu{align-items:center;color:var(--themed-color-input-text,#1a1a1a);display:flex;position:relative}html.theme-dark .opacityInputWrap-EnWts7Xu{color:var(--themed-color-input-text,#dbdbdb)}.opacityInput-EnWts7Xu{background-color:initial;border:1px solid var(--themed-color-input-border,#dbdbdb);border-radius:4px;box-sizing:border-box;display:flex;height:26px;line-height:24px;margin-right:8px;padding:0 5px 0 14px;text-align:left;width:47px}html.theme-dark .opacityInput-EnWts7Xu{border:1px solid var(--themed-color-input-border,#575757)}.opacityInput-EnWts7Xu:focus,html.theme-dark .opacityInput-EnWts7Xu:focus{border-color:var(--themed-color-brand,#2962ff)}.opacityInputPercent-EnWts7Xu{pointer-events:none;position:absolute;right:40px;text-align:left;top:5px}.accessible-EnWts7Xu{outline:none;overflow:visible;position:relative}.accessible-EnWts7Xu:focus{outline:none}.accessible-EnWts7Xu:focus-visible{outline:none}.accessible-EnWts7Xu:after{border-style:solid;border-width:2px;box-sizing:border-box;content:"";display:none;height:calc(100% + 8px);pointer-events:none;position:absolute;right:-4px;top:-4px;width:calc(100% + 8px);z-index:1}.accessible-EnWts7Xu:focus:after{display:block}.accessible-EnWts7Xu:focus-visible:after{display:block}.accessible-EnWts7Xu:focus:not(:focus-visible):after{display:none}.accessible-EnWts7Xu:after{border-color:#2962ff;border-radius:6px}
|
||||
@@ -0,0 +1 @@
|
||||
.footer-dwINHZFL{align-items:center;background-color:var(--themed-color-bg,#f9f9f9);border-radius:0 0 6px 6px;box-sizing:border-box;color:var(--themed-color-default-gray,#707070);cursor:default;display:flex;flex:0 0 auto;font-size:13px;justify-content:center;line-height:17px;max-height:65px;min-height:40px;padding:9px 20px;text-align:center}html.theme-dark .footer-dwINHZFL{background-color:var(--themed-color-bg,#303030);color:var(--themed-color-default-gray,#8c8c8c)}
|
||||
@@ -0,0 +1 @@
|
||||
.footer-dwINHZFL{align-items:center;background-color:var(--themed-color-bg,#f9f9f9);border-radius:0 0 6px 6px;box-sizing:border-box;color:var(--themed-color-default-gray,#707070);cursor:default;display:flex;flex:0 0 auto;font-size:13px;justify-content:center;line-height:17px;max-height:65px;min-height:40px;padding:9px 20px;text-align:center}html.theme-dark .footer-dwINHZFL{background-color:var(--themed-color-bg,#303030);color:var(--themed-color-default-gray,#8c8c8c)}
|
||||
@@ -0,0 +1,5 @@
|
||||
(self.webpackChunktradingview=self.webpackChunktradingview||[]).push([[2544],{67797:e=>{e.exports={menuWrap:"menuWrap-Kq3ruQo8",isMeasuring:"isMeasuring-Kq3ruQo8",scrollWrap:"scrollWrap-Kq3ruQo8",momentumBased:"momentumBased-Kq3ruQo8",menuBox:"menuBox-Kq3ruQo8",isHidden:"isHidden-Kq3ruQo8"}},43010:(e,t,s)=>{"use strict";s.d(t,{useIsomorphicLayoutEffect:()=>i});var n=s(50959);function i(e,t){("undefined"==typeof window?n.useEffect:n.useLayoutEffect)(e,t)}},36383:(e,t,s)=>{"use strict";s.d(t,{useOutsideEvent:()=>r});var n=s(50959),i=s(43010),o=s(27267);function r(e){const{click:t,mouseDown:s,touchEnd:r,touchStart:l,handler:a,reference:u}=e,c=(0,n.useRef)(null),d=(0,n.useRef)("undefined"==typeof window?0:new window.CustomEvent("timestamp").timeStamp);return(0,i.useIsomorphicLayoutEffect)((()=>{const e={click:t,mouseDown:s,touchEnd:r,touchStart:l},n=u?u.current:c.current;return(0,o.addOutsideEventListener)(d.current,n,a,document,e)}),[t,s,r,l,a]),u||c}},9745:(e,t,s)=>{"use strict";s.d(t,{Icon:()=>i});var n=s(50959);const i=n.forwardRef(((e,t)=>{const{icon:s="",title:i,ariaLabel:o,ariaLabelledby:r,ariaHidden:l,...a}=e,u=!!(i||o||r);return n.createElement("span",{role:"img",...a,ref:t,"aria-label":o,"aria-labelledby":r,"aria-hidden":l||!u,title:i,dangerouslySetInnerHTML:{__html:s}})}))},83021:(e,t,s)=>{"use strict";s.d(t,{SubmenuContext:()=>i,SubmenuHandler:()=>o});var n=s(50959);const i=n.createContext(null);function o(e){const[t,s]=(0,n.useState)(null),o=(0,n.useRef)(null),r=(0,n.useRef)(new Map);return(0,n.useEffect)((()=>()=>{null!==o.current&&clearTimeout(o.current)}),[]),n.createElement(i.Provider,{value:{current:t,setCurrent:function(e){null!==o.current&&(clearTimeout(o.current),o.current=null);null===t?s(e):o.current=setTimeout((()=>{o.current=null,s(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)}},99663:(e,t,s)=>{"use strict";s.d(t,{Slot:()=>i,SlotContext:()=>o});var n=s(50959);class i extends n.Component{shouldComponentUpdate(){return!1}render(){return n.createElement("div",{style:{position:"fixed",zIndex:150,left:0,top:0},ref:this.props.reference})}}const o=n.createContext(null)},67961:(e,t,s)=>{"use strict";s.d(t,{OverlapManager:()=>r,getRootOverlapManager:()=>a});var n=s(50151),i=s(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,s=null===e?this._document.createDocumentFragment():e;!function(e,t){Array.from(e.childNodes).forEach((e=>{e.nodeType===Node.ELEMENT_NODE&&t.appendChild(e)}))}(t,s),this._container=s}registerWindow(e){this._storage.has(e)||this._storage.add(e)}ensureWindow(e,t={position:"fixed",direction:"normal"}){
|
||||
const s=this._windows.get(e);if(void 0!==s)return s;this.registerWindow(e);const n=this._document.createElement("div");if(n.style.position=t.position,n.style.zIndex=this._index.toString(),n.dataset.id=e,void 0!==t.index){const e=this._container.childNodes.length;if(t.index>=e)this._container.appendChild(n);else if(t.index<=0)this._container.insertBefore(n,this._container.firstChild);else{const e=this._container.childNodes[t.index];this._container.insertBefore(n,e)}}else"reverse"===t.direction?this._container.insertBefore(n,this._container.firstChild):this._container.appendChild(n);return this._windows.set(e,n),++this._index,n}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,s)=>{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 l=new WeakMap;function a(e=document){const t=e.getElementById("overlap-manager-root");if(null!==t)return(0,n.ensureDefined)(l.get(t));{const t=new r(e),s=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}(e);return l.set(s,t),t.setContainer(s),e.body.appendChild(s),t}}var u;!function(e){e[e.BaseZindex=150]="BaseZindex"}(u||(u={}))},99054:(e,t,s)=>{"use strict";s.d(t,{setFixedBodyState:()=>u});const n=(()=>{let e;return()=>{if(void 0===e){const t=document.createElement("div"),s=t.style;s.visibility="hidden",s.width="100px",s.msOverflowStyle="scrollbar",document.body.appendChild(t);const n=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=n-o}return e}})();function i(e,t,s){null!==e&&e.style.setProperty(t,s)}function o(e,t){return getComputedStyle(e,null).getPropertyValue(t)}function r(e,t){return parseInt(o(e,t))}let l=0,a=!1;function u(e){const{body:t}=document,s=t.querySelector(".widgetbar-wrap");if(e&&1==++l){const e=o(t,"overflow"),l=r(t,"padding-right");"hidden"!==e.toLowerCase()&&t.scrollHeight>t.offsetHeight&&(i(s,"right",`${n()}px`),t.style.paddingRight=`${l+n()}px`,a=!0),t.classList.add("i-no-scroll")}else if(!e&&l>0&&0==--l&&(t.classList.remove("i-no-scroll"),a)){i(s,"right","0px");let e=0;0,t.scrollHeight<=t.clientHeight&&(e-=n()),t.style.paddingRight=(e<0?0:e)+"px",a=!1}}},90692:(e,t,s)=>{"use strict";s.d(t,{MatchMedia:()=>i});var n=s(50959);class i extends n.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,s)=>{"use strict";s.d(t,{MenuContext:()=>n});const n=s(50959).createContext(null)},27317:(e,t,s)=>{"use strict";s.d(t,{DEFAULT_MENU_THEME:()=>_,Menu:()=>v});var n=s(50959),i=s(97754),o=s.n(i),r=s(50151),l=s(9859),a=s(14729),u=s(50655),c=s(59064),d=s(67961),h=s(26709),p=s(83021),m=s(64706),f=s(67797);const _=f;var g;!function(e){e[e.IndentFromWindow=0]="IndentFromWindow"}(g||(g={}));class v extends n.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:s}=this.props,n=(0,r.ensureNotNull)(this._containerRef);let i=n.getBoundingClientRect();const o=document.documentElement.clientHeight,a=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=n.getBoundingClientRect()}const{width:h,height:p}=i,m="function"==typeof s?s({contentWidth:h,contentHeight:p,availableWidth:a,availableHeight:o}):s,f=m?.indentFromWindow?.left??0,_=a-(m.overrideWidth??h)-(m?.indentFromWindow?.right??0),g=(0,l.clamp)(m.x,f,Math.max(f,_)),v=(m?.indentFromWindow?.top??0)+u,y=o-(m.overrideHeight??p)-(m?.indentFromWindow?.bottom??0);let b=(0,l.clamp)(m.y,v,Math.max(v,y));if(m.forbidCorrectYCoord&&b<m.y&&(c-=m.y-b,b=m.y),t&&void 0!==this.props.closeOnScrollOutsideOffset&&m.y<=this.props.closeOnScrollOutsideOffset)return void this._handleGlobalClose(!0);const w=m.overrideHeight??(d?c:void 0);this.setState({appearingMenuHeight:t?this.state.appearingMenuHeight:w,appearingMenuWidth:t?this.state.appearingMenuWidth:m.overrideWidth,appearingPosition:{x:g,y:b},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 s=null!==this.context;this._hotkeys||s||(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":s,"aria-labelledby":i,"aria-activedescendant":r,"aria-hidden":l,"aria-describedby":c,"aria-invalid":d,children:h,minWidth:_,theme:g=f,className:v,maxHeight:b,onMouseOver:w,onMouseOut:x,onKeyDown:C,onFocus:S,onBlur:E}=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 n.createElement(m.MenuContext.Provider,{value:this},n.createElement(p.SubmenuHandler,null,n.createElement(u.SlotContext.Provider,{value:this._manager
|
||||
},n.createElement("div",{id:e,role:t,"aria-label":s,"aria-labelledby":i,"aria-activedescendant":r,"aria-hidden":l,"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-tooltip-show-on-focus":this.props["data-tooltip-show-on-focus"],ref:this._handleContainerRef,onScrollCapture:this.props.onScroll,onContextMenu:a.preventDefaultForContextMenu,tabIndex:this.props.tabIndex,onMouseOver:w,onMouseOut:x,onKeyDown:C,onFocus:S,onBlur:E},n.createElement("div",{className:o()(g.scrollWrap,!this.props.noMomentumBasedScroll&&g.momentumBased),style:{overflowY:void 0!==R?"scroll":"auto",maxHeight:b},onScrollCapture:this._handleScroll,ref:this._handleScrollWrapRef},n.createElement(y,{className:g.menuBox},h)))),n.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,n.useContext)(p.SubmenuContext)),s=n.useRef(null);return n.createElement("div",{ref:s,className:e.className,onMouseOver:function(e){if(!(null!==t.current&&e.target instanceof Node&&(n=e.target,s.current?.contains(n))))return;var n;t.isSubmenuNode(e.target)||t.setCurrent(null)},"data-name":"menu-inner"},e.children)}v.contextType=p.SubmenuContext},29197:(e,t,s)=>{"use strict";s.d(t,{CloseDelegateContext:()=>o});var n=s(50959),i=s(59064);const o=n.createContext(i.globalCloseDelegate)},42842:(e,t,s)=>{"use strict";s.d(t,{Portal:()=>u,PortalContext:()=>c});var n=s(50959),i=s(32227),o=s(55698),r=s(67961),l=s(34811),a=s(99663);class u extends n.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(l.FOCUS_TRAP_DATA_ATTRIBUTE)&&e.setAttribute(l.FOCUS_TRAP_DATA_ATTRIBUTE,"true"),this.props["aria-hidden"]&&e.setAttribute("aria-hidden","true"),i.createPortal(n.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=a.SlotContext;const c=n.createContext(null)},50655:(e,t,s)=>{"use strict";s.d(t,{Slot:()=>n.Slot,SlotContext:()=>n.SlotContext});var n=s(99663)}}]);
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
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 @@
|
||||
.favorite-_FRQhM5Y{align-items:center;background-color:var(--tv-list-item-button-background-color);border-radius:4px;color:var(--tv-color-popup-element-toolbox-text,grey);display:inline-flex;font-size:0;height:22px;justify-content:center;min-width:22px;width:22px}.favorite-_FRQhM5Y.hovered-_FRQhM5Y,.favorite-_FRQhM5Y:active{background-color:var(--tv-color-popup-element-toolbox-background-hover,var(--tv-list-item-button-background-hover-color,var(--themed-color-container-fill-primary-neutral-normal,#dbdbdb)));color:var(--tv-color-popup-element-toolbox-text-hover,var(--themed-color-popup-element-toolbox-text-hover,#1a1a1a))}@media (any-hover:hover){.favorite-_FRQhM5Y:hover{background-color:var(--tv-color-popup-element-toolbox-background-hover,var(--tv-list-item-button-background-hover-color,var(--themed-color-container-fill-primary-neutral-normal,#dbdbdb)));color:var(--tv-color-popup-element-toolbox-text-hover,var(--themed-color-popup-element-toolbox-text-hover,#1a1a1a))}}html.theme-dark .favorite-_FRQhM5Y.hovered-_FRQhM5Y,html.theme-dark .favorite-_FRQhM5Y:active{background-color:var(--tv-color-popup-element-toolbox-background-hover,var(--tv-list-item-button-background-hover-color,var(--themed-color-container-fill-primary-neutral-normal,#4a4a4a)))}@media (any-hover:hover){html.theme-dark .favorite-_FRQhM5Y:hover{background-color:var(--tv-color-popup-element-toolbox-background-hover,var(--tv-list-item-button-background-hover-color,var(--themed-color-container-fill-primary-neutral-normal,#4a4a4a)))}}html.theme-dark .favorite-_FRQhM5Y.hovered-_FRQhM5Y,html.theme-dark .favorite-_FRQhM5Y:active{color:var(--tv-color-popup-element-toolbox-text-hover,var(--themed-color-popup-element-toolbox-text-hover,#dbdbdb))}@media (any-hover:hover){html.theme-dark .favorite-_FRQhM5Y:hover{color:var(--tv-color-popup-element-toolbox-text-hover,var(--themed-color-popup-element-toolbox-text-hover,#dbdbdb))}}.favorite-_FRQhM5Y.disabled-_FRQhM5Y,.favorite-_FRQhM5Y.disabled-_FRQhM5Y:active{background-color:var(--tv-list-item-button-disabled-background-color,var(--themed-color-force-transparent,#0000))}@media (any-hover:hover){.favorite-_FRQhM5Y.disabled-_FRQhM5Y:hover{background-color:var(--tv-list-item-button-disabled-background-color,var(--themed-color-force-transparent,#0000))}}html.theme-dark .favorite-_FRQhM5Y.disabled-_FRQhM5Y,html.theme-dark .favorite-_FRQhM5Y.disabled-_FRQhM5Y:active{background-color:var(--tv-list-item-button-disabled-background-color,var(--themed-color-force-transparent,#0000))}@media (any-hover:hover){html.theme-dark .favorite-_FRQhM5Y.disabled-_FRQhM5Y:hover{background-color:var(--tv-list-item-button-disabled-background-color,var(--themed-color-force-transparent,#0000))}}.favorite-_FRQhM5Y{outline:none;overflow:visible;position:relative}.favorite-_FRQhM5Y:focus{outline:none}.favorite-_FRQhM5Y:focus-visible{outline:none}.favorite-_FRQhM5Y:after{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}.favorite-_FRQhM5Y:after,html.theme-dark .favorite-_FRQhM5Y:after{border-color:var(--themed-color-focus-outline-color-blue,#2962ff)}.favorite-_FRQhM5Y:after{border-radius:4px}.favorite-_FRQhM5Y.focused-_FRQhM5Y:after{display:block}.favorite-_FRQhM5Y.active-_FRQhM5Y{color:var(--tv-color-popup-element-toolbox-text-active-hover,var(--themed-color-content-secondary-inverse,#fff))}html.theme-dark .favorite-_FRQhM5Y.active-_FRQhM5Y{color:var(--tv-color-popup-element-toolbox-text-active-hover,var(--themed-color-content-secondary-inverse,#1a1a1a))}.favorite-_FRQhM5Y.active-_FRQhM5Y.hovered-_FRQhM5Y,.favorite-_FRQhM5Y.active-_FRQhM5Y:active{background-color:var(--tv-color-popup-element-toolbox-background-active-hover,var(--themed-color-overlay-neutral-1-bold,#63636366))}@media (any-hover:hover){.favorite-_FRQhM5Y.active-_FRQhM5Y:hover{background-color:var(--tv-color-popup-element-toolbox-background-active-hover,var(--themed-color-overlay-neutral-1-bold,#63636366))}}html.theme-dark .favorite-_FRQhM5Y.active-_FRQhM5Y.hovered-_FRQhM5Y,html.theme-dark .favorite-_FRQhM5Y.active-_FRQhM5Y:active{background-color:var(--tv-color-popup-element-toolbox-background-active-hover,var(--themed-color-overlay-neutral-1-bold,#b8b8b866))}@media (any-hover:hover){html.theme-dark .favorite-_FRQhM5Y.active-_FRQhM5Y:hover{background-color:var(--tv-color-popup-element-toolbox-background-active-hover,var(--themed-color-overlay-neutral-1-bold,#b8b8b866))}}.favorite-_FRQhM5Y.checked-_FRQhM5Y{color:var(--themed-color-favorite-checked,#fbc02d)}html.theme-dark .favorite-_FRQhM5Y.checked-_FRQhM5Y{color:var(--themed-color-favorite-checked,#f9a825)}
|
||||
@@ -0,0 +1 @@
|
||||
.favorite-_FRQhM5Y{align-items:center;background-color:var(--tv-list-item-button-background-color);border-radius:4px;color:var(--tv-color-popup-element-toolbox-text,grey);display:inline-flex;font-size:0;height:22px;justify-content:center;min-width:22px;width:22px}.favorite-_FRQhM5Y.hovered-_FRQhM5Y,.favorite-_FRQhM5Y:active{background-color:var(--tv-color-popup-element-toolbox-background-hover,var(--tv-list-item-button-background-hover-color,var(--themed-color-container-fill-primary-neutral-normal,#dbdbdb)));color:var(--tv-color-popup-element-toolbox-text-hover,var(--themed-color-popup-element-toolbox-text-hover,#1a1a1a))}@media (any-hover:hover){.favorite-_FRQhM5Y:hover{background-color:var(--tv-color-popup-element-toolbox-background-hover,var(--tv-list-item-button-background-hover-color,var(--themed-color-container-fill-primary-neutral-normal,#dbdbdb)));color:var(--tv-color-popup-element-toolbox-text-hover,var(--themed-color-popup-element-toolbox-text-hover,#1a1a1a))}}html.theme-dark .favorite-_FRQhM5Y.hovered-_FRQhM5Y,html.theme-dark .favorite-_FRQhM5Y:active{background-color:var(--tv-color-popup-element-toolbox-background-hover,var(--tv-list-item-button-background-hover-color,var(--themed-color-container-fill-primary-neutral-normal,#4a4a4a)))}@media (any-hover:hover){html.theme-dark .favorite-_FRQhM5Y:hover{background-color:var(--tv-color-popup-element-toolbox-background-hover,var(--tv-list-item-button-background-hover-color,var(--themed-color-container-fill-primary-neutral-normal,#4a4a4a)))}}html.theme-dark .favorite-_FRQhM5Y.hovered-_FRQhM5Y,html.theme-dark .favorite-_FRQhM5Y:active{color:var(--tv-color-popup-element-toolbox-text-hover,var(--themed-color-popup-element-toolbox-text-hover,#dbdbdb))}@media (any-hover:hover){html.theme-dark .favorite-_FRQhM5Y:hover{color:var(--tv-color-popup-element-toolbox-text-hover,var(--themed-color-popup-element-toolbox-text-hover,#dbdbdb))}}.favorite-_FRQhM5Y.disabled-_FRQhM5Y,.favorite-_FRQhM5Y.disabled-_FRQhM5Y:active{background-color:var(--tv-list-item-button-disabled-background-color,var(--themed-color-force-transparent,#0000))}@media (any-hover:hover){.favorite-_FRQhM5Y.disabled-_FRQhM5Y:hover{background-color:var(--tv-list-item-button-disabled-background-color,var(--themed-color-force-transparent,#0000))}}html.theme-dark .favorite-_FRQhM5Y.disabled-_FRQhM5Y,html.theme-dark .favorite-_FRQhM5Y.disabled-_FRQhM5Y:active{background-color:var(--tv-list-item-button-disabled-background-color,var(--themed-color-force-transparent,#0000))}@media (any-hover:hover){html.theme-dark .favorite-_FRQhM5Y.disabled-_FRQhM5Y:hover{background-color:var(--tv-list-item-button-disabled-background-color,var(--themed-color-force-transparent,#0000))}}.favorite-_FRQhM5Y{outline:none;overflow:visible;position:relative}.favorite-_FRQhM5Y:focus{outline:none}.favorite-_FRQhM5Y:focus-visible{outline:none}.favorite-_FRQhM5Y:after{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}.favorite-_FRQhM5Y:after,html.theme-dark .favorite-_FRQhM5Y:after{border-color:var(--themed-color-focus-outline-color-blue,#2962ff)}.favorite-_FRQhM5Y:after{border-radius:4px}.favorite-_FRQhM5Y.focused-_FRQhM5Y:after{display:block}.favorite-_FRQhM5Y.active-_FRQhM5Y{color:var(--tv-color-popup-element-toolbox-text-active-hover,var(--themed-color-content-secondary-inverse,#fff))}html.theme-dark .favorite-_FRQhM5Y.active-_FRQhM5Y{color:var(--tv-color-popup-element-toolbox-text-active-hover,var(--themed-color-content-secondary-inverse,#1a1a1a))}.favorite-_FRQhM5Y.active-_FRQhM5Y.hovered-_FRQhM5Y,.favorite-_FRQhM5Y.active-_FRQhM5Y:active{background-color:var(--tv-color-popup-element-toolbox-background-active-hover,var(--themed-color-overlay-neutral-1-bold,#63636366))}@media (any-hover:hover){.favorite-_FRQhM5Y.active-_FRQhM5Y:hover{background-color:var(--tv-color-popup-element-toolbox-background-active-hover,var(--themed-color-overlay-neutral-1-bold,#63636366))}}html.theme-dark .favorite-_FRQhM5Y.active-_FRQhM5Y.hovered-_FRQhM5Y,html.theme-dark .favorite-_FRQhM5Y.active-_FRQhM5Y:active{background-color:var(--tv-color-popup-element-toolbox-background-active-hover,var(--themed-color-overlay-neutral-1-bold,#b8b8b866))}@media (any-hover:hover){html.theme-dark .favorite-_FRQhM5Y.active-_FRQhM5Y:hover{background-color:var(--tv-color-popup-element-toolbox-background-active-hover,var(--themed-color-overlay-neutral-1-bold,#b8b8b866))}}.favorite-_FRQhM5Y.checked-_FRQhM5Y{color:var(--themed-color-favorite-checked,#fbc02d)}html.theme-dark .favorite-_FRQhM5Y.checked-_FRQhM5Y{color:var(--themed-color-favorite-checked,#f9a825)}
|
||||
@@ -0,0 +1,32 @@
|
||||
(self.webpackChunktradingview=self.webpackChunktradingview||[]).push([[2751],{66783:e=>{"use strict";var t=Object.prototype.hasOwnProperty;function r(e,t){return e===t?0!==e||0!==t||1/e==1/t:e!=e&&t!=t}e.exports=function(e,n){if(r(e,n))return!0;if("object"!=typeof e||null===e||"object"!=typeof n||null===n)return!1;var o=Object.keys(e),a=Object.keys(n);if(o.length!==a.length)return!1;for(var s=0;s<o.length;s++)if(!t.call(n,o[s])||!r(e[o[s]],n[o[s]]))return!1;return!0}},88317:e=>{e.exports={pills:"pills-PVWoXu5j",primary:"primary-PVWoXu5j",gray:"gray-PVWoXu5j",selected:"selected-PVWoXu5j",grouped:"grouped-PVWoXu5j",active:"active-PVWoXu5j",disableActiveOnTouch:"disableActiveOnTouch-PVWoXu5j",disableActiveStateStyles:"disableActiveStateStyles-PVWoXu5j",withGrouped:"withGrouped-PVWoXu5j","quiet-primary":"quiet-primary-PVWoXu5j",green:"green-PVWoXu5j",red:"red-PVWoXu5j",blue:"blue-PVWoXu5j",secondary:"secondary-PVWoXu5j",ghost:"ghost-PVWoXu5j"}},1538:e=>{e.exports={lightButton:"lightButton-bYDQcOkp",link:"link-bYDQcOkp",ltr:"ltr-bYDQcOkp",rtl:"rtl-bYDQcOkp","typography-regular16px":"typography-regular16px-bYDQcOkp","typography-medium16px":"typography-medium16px-bYDQcOkp","typography-regular14px":"typography-regular14px-bYDQcOkp","typography-semibold14px":"typography-semibold14px-bYDQcOkp","typography-semibold16px":"typography-semibold16px-bYDQcOkp",content:"content-bYDQcOkp",visuallyHidden:"visuallyHidden-bYDQcOkp",nowrap:"nowrap-bYDQcOkp",ellipsisContainer:"ellipsisContainer-bYDQcOkp",textWrapContainer:"textWrapContainer-bYDQcOkp",textWrapWithEllipsis:"textWrapWithEllipsis-bYDQcOkp",slot:"slot-bYDQcOkp",caret:"caret-bYDQcOkp",activeCaret:"activeCaret-bYDQcOkp",xsmall:"xsmall-bYDQcOkp",withStartSlot:"withStartSlot-bYDQcOkp",withEndSlot:"withEndSlot-bYDQcOkp",noContent:"noContent-bYDQcOkp",wrap:"wrap-bYDQcOkp",small:"small-bYDQcOkp",medium:"medium-bYDQcOkp"}},78217:e=>{e.exports={pair:"pair-ocURKVwI",xxceptionallysmalldonotusebrv1023:"xxceptionallysmalldonotusebrv1023-ocURKVwI",xxxxsmall:"xxxxsmall-ocURKVwI",xxxsmall:"xxxsmall-ocURKVwI",xxsmall:"xxsmall-ocURKVwI",xsmall:"xsmall-ocURKVwI",small:"small-ocURKVwI",medium:"medium-ocURKVwI",large:"large-ocURKVwI",xlarge:"xlarge-ocURKVwI",xxlarge:"xxlarge-ocURKVwI",xxxlarge:"xxxlarge-ocURKVwI",logo:"logo-ocURKVwI",skeleton:"skeleton-ocURKVwI",empty:"empty-ocURKVwI"}},34869:e=>{e.exports={hidden:"hidden-DgcIT6Uz",fadeInWrapper:"fadeInWrapper-DgcIT6Uz"}},85862:e=>{e.exports={disableSelfPositioning:"disableSelfPositioning-dYiqkKAE"}},79566:e=>{e.exports={container:"container-M1mz4quA",pairContainer:"pairContainer-M1mz4quA",logo:"logo-M1mz4quA",hidden:"hidden-M1mz4quA"}},92335:e=>{e.exports={container:"container-qm7Rg5MB",mobile:"mobile-qm7Rg5MB",inputContainer:"inputContainer-qm7Rg5MB",withCancel:"withCancel-qm7Rg5MB",input:"input-qm7Rg5MB",icon:"icon-qm7Rg5MB",cancel:"cancel-qm7Rg5MB"}},10070:e=>{e.exports={actions:"actions-rarsm4ka",actionButton:"actionButton-rarsm4ka"}},94869:e=>{e.exports={logo:"logo-d0vVmGvT"}},92069:e=>{e.exports={
|
||||
"tablet-small-breakpoint":"(max-width: 440px)",itemRow:"itemRow-oRSs8UQo",multiLine:"multiLine-oRSs8UQo",cell:"cell-oRSs8UQo",itemInfoCell:"itemInfoCell-oRSs8UQo",description:"description-oRSs8UQo",symbolDescription:"symbolDescription-oRSs8UQo",flag:"flag-oRSs8UQo",exchangeDescription:"exchangeDescription-oRSs8UQo",marketType:"marketType-oRSs8UQo",exchangeName:"exchangeName-oRSs8UQo",actionHandleWrap:"actionHandleWrap-oRSs8UQo",source:"source-oRSs8UQo",hover:"hover-oRSs8UQo",selected:"selected-oRSs8UQo",active:"active-oRSs8UQo",highlighted:"highlighted-oRSs8UQo",light:"light-oRSs8UQo","highlight-animation-theme-light":"highlight-animation-theme-light-oRSs8UQo",dark:"dark-oRSs8UQo","highlight-animation-theme-dark":"highlight-animation-theme-dark-oRSs8UQo",markedFlag:"markedFlag-oRSs8UQo",offset:"offset-oRSs8UQo",descriptionCell:"descriptionCell-oRSs8UQo",addition:"addition-oRSs8UQo",exchangeCell:"exchangeCell-oRSs8UQo",fixedWidth:"fixedWidth-oRSs8UQo",expandHandle:"expandHandle-oRSs8UQo",expanded:"expanded-oRSs8UQo",symbolTitle:"symbolTitle-oRSs8UQo",invalid:"invalid-oRSs8UQo",noDescription:"noDescription-oRSs8UQo",highlightedText:"highlightedText-oRSs8UQo",icon:"icon-oRSs8UQo",narrow:"narrow-oRSs8UQo",wide:"wide-oRSs8UQo",dataMode:"dataMode-oRSs8UQo",actionsCell:"actionsCell-oRSs8UQo",action:"action-oRSs8UQo",targetAction:"targetAction-oRSs8UQo",removeAction:"removeAction-oRSs8UQo",addAction:"addAction-oRSs8UQo",markedFlagWrap:"markedFlagWrap-oRSs8UQo",markedFlagMobile:"markedFlagMobile-oRSs8UQo",logo:"logo-oRSs8UQo",isExpandable:"isExpandable-oRSs8UQo",primaryIcon:"primaryIcon-oRSs8UQo"}},6963:e=>{e.exports={icon:"icon-OJpk_CAQ"}},6109:e=>{e.exports={wrap:"wrap-IxKZEhmO",libAllSelected:"libAllSelected-IxKZEhmO",container:"container-IxKZEhmO",iconWrap:"iconWrap-IxKZEhmO",icon:"icon-IxKZEhmO",title:"title-IxKZEhmO",highlighted:"highlighted-IxKZEhmO",description:"description-IxKZEhmO",mobile:"mobile-IxKZEhmO",allSelected:"allSelected-IxKZEhmO",desktop:"desktop-IxKZEhmO",allSelectedIcon:"allSelectedIcon-IxKZEhmO",selected:"selected-IxKZEhmO",focused:"focused-IxKZEhmO",titleWithoutDesc:"titleWithoutDesc-IxKZEhmO",textBlock:"textBlock-IxKZEhmO",bordered:"bordered-IxKZEhmO"}},96137:e=>{e.exports={container:"container-dfKL9A7t",contentList:"contentList-dfKL9A7t",contentListDesktop:"contentListDesktop-dfKL9A7t",searchSourceItemsContainer:"searchSourceItemsContainer-dfKL9A7t",oneColumn:"oneColumn-dfKL9A7t",searchSourceItemsContainerDesktop:"searchSourceItemsContainerDesktop-dfKL9A7t",groupTitleDesktop:"groupTitleDesktop-dfKL9A7t",column:"column-dfKL9A7t",emptyText:"emptyText-dfKL9A7t",emptyIcon:"emptyIcon-dfKL9A7t",noResultsDesktop:"noResultsDesktop-dfKL9A7t"}},6591:e=>{e.exports={wrap:"wrap-gjrLBBL3",item:"item-gjrLBBL3",small:"small-gjrLBBL3",newStyles:"newStyles-gjrLBBL3",mobile:"mobile-gjrLBBL3",text:"text-gjrLBBL3",exchange:"exchange-gjrLBBL3",filterItem:"filterItem-gjrLBBL3",brokerWrap:"brokerWrap-gjrLBBL3"}},44458:e=>{e.exports={wrap:"wrap-dlewR1s1",watchlist:"watchlist-dlewR1s1",noFeed:"noFeed-dlewR1s1",
|
||||
newStyles:"newStyles-dlewR1s1",scrollContainer:"scrollContainer-dlewR1s1",listContainer:"listContainer-dlewR1s1",multiLineItemsContainer:"multiLineItemsContainer-dlewR1s1",withSpinner:"withSpinner-dlewR1s1",spinnerContainer:"spinnerContainer-dlewR1s1",largeSpinner:"largeSpinner-dlewR1s1"}},76717:e=>{e.exports={search:"search-ZXzPWcCf",upperCase:"upperCase-ZXzPWcCf",bubblesContainer:"bubblesContainer-ZXzPWcCf",mobile:"mobile-ZXzPWcCf",bubbles:"bubbles-ZXzPWcCf",withFilters:"withFilters-ZXzPWcCf",spinnerWrap:"spinnerWrap-ZXzPWcCf",emptyText:"emptyText-ZXzPWcCf",emptyIcon:"emptyIcon-ZXzPWcCf",noResultsDesktop:"noResultsDesktop-ZXzPWcCf",brokerButtonWrap:"brokerButtonWrap-ZXzPWcCf"}},92244:e=>{e.exports={flagWrap:"flagWrap-QKnxaZOG",icon:"icon-QKnxaZOG",caret:"caret-QKnxaZOG",title:"title-QKnxaZOG",button:"button-QKnxaZOG",withFlag:"withFlag-QKnxaZOG",buttonContent:"buttonContent-QKnxaZOG"}},63748:e=>{e.exports={dialog:"dialog-u2dP3kv1",tabletDialog:"tabletDialog-u2dP3kv1",desktopDialog:"desktopDialog-u2dP3kv1",backButton:"backButton-u2dP3kv1"}},24517:e=>{e.exports={childrenWrapper:"childrenWrapper-_RhDhmVQ",container:"container-_RhDhmVQ"}},95059:e=>{e.exports={highlighted:"highlighted-cwp8YRo6"}},93524:e=>{e.exports={linkItem:"linkItem-zMVwkifW"}},90854:e=>{e.exports={roundTabButton:"roundTabButton-JbssaNvk",disableFocusOutline:"disableFocusOutline-JbssaNvk",enableCursorPointer:"enableCursorPointer-JbssaNvk",large:"large-JbssaNvk",withStartIcon:"withStartIcon-JbssaNvk",iconOnly:"iconOnly-JbssaNvk",withEndIcon:"withEndIcon-JbssaNvk",startIconWrap:"startIconWrap-JbssaNvk",endIconWrap:"endIconWrap-JbssaNvk",small:"small-JbssaNvk",xsmall:"xsmall-JbssaNvk",primary:"primary-JbssaNvk",selected:"selected-JbssaNvk",disableActiveStateStyles:"disableActiveStateStyles-JbssaNvk",ghost:"ghost-JbssaNvk",fake:"fake-JbssaNvk",caret:"caret-JbssaNvk",visuallyHidden:"visuallyHidden-JbssaNvk"}},76912:e=>{e.exports={scrollWrap:"scrollWrap-vgCB17hK",overflowScroll:"overflowScroll-vgCB17hK",roundTabs:"roundTabs-vgCB17hK",center:"center-vgCB17hK",overflowWrap:"overflowWrap-vgCB17hK",start:"start-vgCB17hK"}},49128:e=>{e.exports={icon:"icon-WB2y0EnP",dropped:"dropped-WB2y0EnP"}},18429:(e,t,r)=>{"use strict";r.d(t,{SEPARATOR_PREFIX:()=>n,isSeparatorItem:()=>o});const n="###";function o(e){return e.startsWith(n)}},48199:(e,t,r)=>{"use strict";r.d(t,{BackButton:()=>v});var n,o=r(50959),a=r(64388),s=r(95694),l=r(49498),i=r(60176),c=r(35369),u=r(58478),d=r(73063),m=r(14127),p=r(18073),h=r(99243),g=r(42576);function f(e="large",t="1.2"){switch(e){case"large":return"1.2"===t?s:d;case"medium":return"1.2"===t?l:m;case"small":return"1.2"===t?i:p;case"xsmall":return"1.2"===t?c:h;case"xxsmall":return"1.2"===t?u:g;default:return l}}!function(e){e.Thin="1.2",e.Medium="1.5"}(n||(n={}));const v=o.forwardRef(((e,t)=>{const{"aria-label":r,flipIconOnRtl:n,...s}=e;return o.createElement(a.NavButton,{...s,"aria-label":r,ref:t,icon:f(e.size,e.iconStrokeWidth),flipIconOnRtl:n})}))},27011:(e,t,r)=>{"use strict";function n(e,t){
|
||||
return t||null==e||("string"==typeof e||Array.isArray(e))&&0===e.length}r.d(t,{isIconOnly:()=>n})},14543:(e,t,r)=>{"use strict";r.d(t,{LightButton:()=>n.LightButton});r(9038);var n=r(15893);r(50959),r(21593),r(66860),r(1538),r(88317);r(49406)},9038:(e,t,r)=>{"use strict";r.d(t,{useLightButtonClasses:()=>c});var n=r(50959),o=r(97754),a=r(17946),s=r(27011),l=r(86332);const i=n.createContext({isInButtonGroup:!1,isGroupPrimary:!1}),c=(e,t,r)=>{const c=(0,n.useContext)(a.CustomBehaviourContext),{className:u,isSelected:d,children:m,showCaret:p,forceDirection:h,iconOnly:g,color:f="gray",variant:v="primary",size:b="medium",enableActiveStateStyles:y=c.enableActiveStateStyles,typography:S,isLink:x=!1,textWrap:w,isPills:k,isActive:C,startSlot:E,endSlot:I}=t,R=e[`typography-${((e,t,r)=>{if(r){const e=r.replace(/^\D+/g,"");return t?`semibold${e}`:r}switch(e){case"xsmall":return t?"semibold14px":"regular14px";case"small":case"medium":return t?"semibold16px":"regular16px";default:return""}})(b,d||k,S||void 0)}`],L=(0,n.useContext)(l.ControlGroupContext),{isInButtonGroup:T,isGroupPrimary:B}=(0,n.useContext)(i);return o(u,e.lightButton,x&&e.link,C&&e.active,d&&e.selected,(0,s.isIconOnly)(m,g)&&e.noContent,!!E&&e.withStartSlot,(p||!!I)&&e.withEndSlot,r&&e.withGrouped,h&&e[h],e[B?"primary":v],e[B?"gray":f],e[b],R,!y&&e.disableActiveStateStyles,L.isGrouped&&e.grouped,w&&e.wrap,T&&e.disableActiveOnTouch,k&&e.pills)}},66860:(e,t,r)=>{"use strict";r.d(t,{LightButtonContent:()=>m});var n=r(50959),o=r(97754),a=r(34094),s=r(27011),l=r(9745),i=r(2948),c=r(1538),u=r.n(c);const d=e=>n.createElement(l.Icon,{className:o(u().caret,e&&u().activeCaret),icon:i});function m(e){const{showCaret:t,iconOnly:r,ellipsis:l=!0,textWrap:i,tooltipText:c,children:m,endSlot:p,startSlot:h,isActiveCaret:g}=e;[p,t].filter((e=>!!e));return n.createElement(n.Fragment,null,h&&n.createElement("span",{className:o(u().slot,u().startSlot)},h),!(0,s.isIconOnly)(m,r)&&n.createElement("span",{className:o(u().content,!i&&u().nowrap,"apply-overflow-tooltip","apply-overflow-tooltip--check-children-recursively","apply-overflow-tooltip--allow-text"),"data-overflow-tooltip-text":c??(0,a.getTextForTooltip)(m)},i||l?n.createElement(n.Fragment,null,n.createElement("span",{className:o(!i&&l&&u().ellipsisContainer,i&&u().textWrapContainer,i&&l&&u().textWrapWithEllipsis)},m),n.createElement("span",{className:u().visuallyHidden,"aria-hidden":!0},m)):n.createElement(n.Fragment,null,m,n.createElement("span",{className:u().visuallyHidden,"aria-hidden":!0},m))),p&&n.createElement("span",{className:o(u().slot,u().endSlot)},p),t&&d(g))}},15893:(e,t,r)=>{"use strict";r.d(t,{LightButton:()=>d});var n=r(50959),o=r(86332),a=r(9038),s=r(66860),l=r(1538),i=r.n(l),c=r(88317),u=r.n(c);function d(e){
|
||||
const{isGrouped:t}=n.useContext(o.ControlGroupContext),{reference:r,className:l,isSelected:c,children:d,iconOnly:m,ellipsis:p,showCaret:h,forceDirection:g,endSlot:f,startSlot:v,color:b,variant:y,size:S,enableActiveStateStyles:x,typography:w,textWrap:k=!1,maxLines:C,style:E={},isPills:I,isActive:R,tooltipText:L,role:T,...B}=e,N=k?C??2:1,M=N>0?{...E,"--ui-lib-light-button-content-max-lines":N}:E;return n.createElement("button",{...B,className:(0,a.useLightButtonClasses)({...u(),...i()},{className:l,isSelected:c,children:d,iconOnly:m,showCaret:h,forceDirection:g,endSlot:f,startSlot:v,color:b,variant:y,size:S,enableActiveStateStyles:x,typography:w,textWrap:k,isPills:I,isActive:R},t),ref:r,style:M,role:T},n.createElement(s.LightButtonContent,{showCaret:h,isActiveCaret:h&&(I||R||c),iconOnly:m,ellipsis:p,textWrap:k,tooltipText:L,endSlot:f,startSlot:v},d))}},125:(e,t,r)=>{"use strict";r.d(t,{useForceUpdate:()=>o});var n=r(50959);const o=()=>{const[,e]=(0,n.useReducer)((e=>e+1),0);return e}},34094:(e,t,r)=>{"use strict";r.d(t,{getTextForTooltip:()=>s});var n=r(50959);const o=e=>(0,n.isValidElement)(e)&&Boolean(e.props.children),a=e=>null==e||"boolean"==typeof e||"{}"===JSON.stringify(e)?"":e.toString()+" ",s=e=>Array.isArray(e)||(0,n.isValidElement)(e)?n.Children.toArray(e).reduce(((e,t)=>{let r="";return r=(0,n.isValidElement)(t)&&o(t)?s(t.props.children):(0,n.isValidElement)(t)&&!o(t)?"":a(t),e.concat(r)}),"").trim():a(e)},3685:(e,t,r)=>{"use strict";function n(){return window.configurationData?.exchanges?.map((e=>({...e,country:"",providerId:"",flag:""})))??[]}r.d(t,{getExchanges:()=>n})},36279:(e,t,r)=>{"use strict";var n;r.d(t,{LogoSize:()=>n,getLogoUrlResolver:()=>s}),function(e){e[e.Medium=0]="Medium",e[e.Large=1]="Large"}(n||(n={}));class o{getSymbolLogoUrl(e){return e}getCountryFlagUrl(){return""}getCryptoLogoUrl(e){return e}getProviderLogoUrl(e){return e}getSourceLogoUrl(e){return e}getBlockchainContractLogoUrl(e){return e}}let a;function s(){return a||(a=new o),a}},69654:(e,t,r)=>{"use strict";r.d(t,{DialogSearch:()=>d});var n=r(50959),o=r(97754),a=r.n(o),s=r(11542),l=r(9745),i=r(6347),c=r(54313),u=r(92335);function d(e){const{children:t,isMobile:o,renderInput:d,onCancel:p,containerClassName:h,inputContainerClassName:g,iconClassName:f,cancelTitle:v=s.t(null,void 0,r(4543)),...b}=e;return n.createElement("div",{className:a()(u.container,o&&u.mobile,h)},n.createElement("div",{className:a()(u.inputContainer,o&&u.mobile,g,p&&u.withCancel)},d||n.createElement(m,{isMobile:o,...b})),t,n.createElement(l.Icon,{className:a()(u.icon,o&&u.mobile,f),icon:o?c:i}),p&&(!o||""!==b.value)&&n.createElement("div",{className:a()(u.cancel,o&&u.mobile),onClick:p},v))}function m(e){const{className:t,reference:r,isMobile:o,value:s,onChange:l,onFocus:i,onBlur:c,onKeyDown:d,onSelect:m,placeholder:p,activeDescendant:h,...g}=e;return n.createElement("input",{...g,ref:r,type:"text",className:a()(t,u.input,o&&u.mobile),autoComplete:"off",role:"searchbox","data-role":"search",placeholder:p,value:s,onChange:l,onFocus:i,onBlur:c,onSelect:m,
|
||||
onKeyDown:d,"aria-activedescendant":h})}},96967:(e,t,r)=>{"use strict";r.d(t,{SymbolSearchDialogContentItem:()=>D});var n=r(50959),o=r(97754),a=r.n(o),s=(r(11542),r(50151)),l=r(9745),i=r(56570),c=r(24637),u=r(97006),d=r(84524),m=r(24633),p=r(77975),h=r(45345),g=r(32563),f=r(91682),v=r(618),b=r(36279),y=r(59695),S=r(58492),x=r(39330),w=r(19938),k=r(43010),C=r(79566);function E(e){const{className:t,placeholderLetter:r,url1:o,url2:s,size:l="xxxsmall"}=e,i=(0,n.useRef)(null),c=(0,n.useRef)(null),u=(0,n.useRef)(null),d=(0,n.useRef)(null),m=(0,n.useRef)(null),p=(0,n.useRef)(null);return(0,k.useIsomorphicLayoutEffect)((()=>{const e=void 0===o?[]:void 0===s?[o]:[o,s],t=p.current=(r=e,Promise.all(r.map((e=>(0,w.getImage)(`symbol_logo_${e}`,e,R).then((e=>e.cloneNode()))))));var r;t.catch((()=>[])).then((e=>{if(t===p.current)switch(e.length){case 0:u.current?.classList.add(C.hidden),c.current?.classList.add(y.hiddenCircleLogoClass),i.current?.classList.remove(y.hiddenCircleLogoClass);break;case 1:I(c.current,e[0]),u.current?.classList.add(C.hidden),c.current?.classList.remove(y.hiddenCircleLogoClass),i.current?.classList.add(y.hiddenCircleLogoClass);break;case 2:I(d.current,e[0]),I(m.current,e[1]),u.current?.classList.remove(C.hidden),c.current?.classList.add(y.hiddenCircleLogoClass),i.current?.classList.add(y.hiddenCircleLogoClass)}}))}),[o,s]),n.createElement("span",{className:a()(t,C.container)},n.createElement("span",{ref:u,className:a()(C.pairContainer,C.hidden)},n.createElement("span",{className:(0,x.getBlockStyleClasses)(l)},n.createElement("span",{ref:m,className:a()(C.logo,(0,x.getLogoStyleClasses)(l))}),n.createElement("span",{ref:d,className:a()(C.logo,(0,x.getLogoStyleClasses)(l))}))),n.createElement("span",{ref:c,className:a()(C.logo,y.hiddenCircleLogoClass,(0,S.getStyleClasses)(l))}),n.createElement("span",{ref:i,className:a()(C.logo,(0,S.getStyleClasses)(l))},n.createElement(y.CircleLogo,{size:l,placeholderLetter:r})))}function I(e,t){e&&(e.innerHTML="",e.appendChild(t))}function R(e){e.crossOrigin="",e.decoding="async"}var L=r(94869);function T(e){const{logoId:t,baseCurrencyLogoId:r,currencyLogoId:o,placeholder:s,className:l,size:i="xsmall"}=e,c=(0,n.useMemo)((()=>{const e={logoid:t,"currency-logoid":o,"base-currency-logoid":r};return(0,v.removeUsdFromCryptoPairLogos)((0,v.resolveLogoUrls)(e,b.LogoSize.Medium))}),[t,o,r]);return n.createElement(E,{key:i,className:a()(L.logo,l),url1:c[0],url2:c[1],placeholderLetter:s,size:i})}var B=r(29562),N=r(69533),M=r(92069);function D(e){
|
||||
const{dangerousTitleHTML:t,title:r,dangerousDescriptionHTML:o,description:v,searchToken:b,exchangeName:y,marketType:S,onClick:x,isSelected:w,isEod:k=!1,isActive:C=!1,isOffset:E=!1,invalid:I=!1,isHighlighted:R=!1,hideExchange:L=!1,hideMarkedListFlag:D=!1,onExpandClick:O,isExpanded:A,hoverComponent:P,country:_,providerId:F,source:W,source2:Q,type:U,flag:V,itemRef:K,onMouseOut:z,onMouseOver:H,className:Z,actions:G,reference:q,fullSymbolName:j,logoId:$,currencyLogoId:Y,baseCurrencyLogoId:X,shortName:J,hideLogo:ee=!1,exchangeTooltip:te,hideMarketType:re,isPrimary:ne}=e,{isSmallWidth:oe,isMobile:ae}=(0,s.ensureNotNull)((0,n.useContext)(d.SymbolSearchItemsDialogContext)),se=Boolean(P),le=!I&&!L&&(ae||!se),ie=(0,p.useWatchedValueReadonly)({watchedValue:h.watchedTheme})===m.StdTheme.Dark?M.dark:M.light,ce=P,ue=i.enabled("show_symbol_logos"),de=i.enabled("show_exchange_logos"),me=ue||!1,pe=Q?.description??W,he=Q?.name??W;return n.createElement("div",{className:a()(M.itemRow,oe&&M.multiLine,R&&M.highlighted,R&&ie,w&&M.selected,C&&M.active,I&&M.invalid,!ae&&g.mobiletouch&&se&&M.hover,Z),onClick:function(e){if(!x||e.defaultPrevented)return;e.preventDefault(),x(e)},"data-role":e["data-role"]||"list-item","data-active":C,"data-type":S,"data-name":"symbol-search-dialog-content-item",onMouseOut:z,onMouseOver:H,ref:q},n.createElement("div",{ref:K,className:a()(M.itemInfoCell,M.cell,E&&M.offset)},n.createElement("div",{className:a()(M.actionHandleWrap,!me&&M.fixedWidth)},n.createElement(n.Fragment,null,!1,O&&n.createElement("div",{onClick:function(e){if(!O||e.defaultPrevented)return;e.preventDefault(),O(e)}},n.createElement(l.Icon,{className:a()(M.expandHandle,A&&M.expanded,w&&M.selected),icon:N})),me&&!E&&n.createElement("div",{className:a()(M.logo,Boolean(O)&&M.isExpandable)},n.createElement(T,{key:j,logoId:$,currencyLogoId:Y,baseCurrencyLogoId:X,placeholder:J?J[0]:void 0})))),n.createElement("div",{className:a()(M.description,me&&E&&M.offset)},r&&n.createElement("div",{className:a()(M.symbolTitle,C&&M.active,I&&M.invalid,!Boolean(o)&&M.noDescription,!g.mobiletouch&&"apply-overflow-tooltip"),"data-overflow-tooltip-text":r,"data-name":"list-item-title"},"string"==typeof r&&b?n.createElement(c.HighlightedText,{className:M.highlightedText,text:r,queryString:b,rules:(0,u.createRegExpList)(b)}):r,k&&n.createElement("span",{className:M.dataMode},"E")),!r&&t&&n.createElement("div",{className:a()(M.symbolTitle,C&&M.active,I&&M.invalid,!g.mobiletouch&&"apply-overflow-tooltip"),"data-name":"list-item-title","data-overflow-tooltip-text":(0,f.removeTags)(t)},n.createElement("span",{dangerouslySetInnerHTML:{__html:t}}),k&&n.createElement("span",{className:M.dataMode},"E")),oe&&ge())),!oe&&n.createElement("div",{className:a()(M.cell,M.descriptionCell,Boolean(ce)&&M.addition)},ge(),ce?n.createElement(ce,{...e,className:M.actions,onMouseOver:void 0,onMouseOut:void 0}):null),oe&&ce?n.createElement(ce,{...e,className:M.cell,onMouseOver:void 0,onMouseOut:void 0}):null,le&&n.createElement("div",{className:a()(M.exchangeCell,M.cell)
|
||||
},n.createElement("div",{className:a()(M.exchangeDescription)},!re&&n.createElement("div",{className:a()(M.marketType,C&&M.active)},S),n.createElement("div",{className:M.source},!1,"economic"===U&&pe&&he?n.createElement("div",{className:a()(M.exchangeName,C&&M.active,"apply-common-tooltip",M.narrow,re&&M.wide),title:pe},he):n.createElement("div",{className:a()(M.exchangeName,C&&M.active,te&&"apply-common-tooltip"),title:te},y))),de&&n.createElement("div",{className:M.flag},n.createElement(B.SymbolSearchFlag,{key:de?`${j}_exchange`:`${_}_${F}_${Q?.id}_${U}_${V}`,className:M.icon,country:_,providerId:F,sourceId:"economic"===U&&Q?Q.id:void 0}))),n.createElement("div",{className:a()(M.cell,Boolean(G)&&M.actionsCell)},G));function ge(){if(I)return null;const e=a()(M.symbolDescription,C&&M.active,!g.mobiletouch&&"apply-overflow-tooltip apply-overflow-tooltip--allow-text");return v?n.createElement("div",{className:e},b?n.createElement(c.HighlightedText,{className:M.highlightedText,text:v,queryString:b,rules:(0,u.createRegExpList)(b)}):v):o?n.createElement("div",{"data-overflow-tooltip-text":(0,f.removeTags)(o),className:e,dangerouslySetInnerHTML:{__html:o}}):null}}},29562:(e,t,r)=>{"use strict";r.d(t,{SymbolSearchFlag:()=>f});var n=r(50959),o=r(97754),a=r.n(o),s=r(24633),l=r(36279);const i=r.p+"mock-dark.16b5f3a431f502b03ae3.svg",c=r.p+"mock-light.d201313017eb2c1b989f.svg";function u(e){return e===s.StdTheme.Dark?i:c}var d=r(77975),m=r(45345),p=r(50151);const h=l.LogoSize.Medium;var g=r(6963);function f(e){const{country:t,tooltip:r,providerId:o,sourceId:s,className:i}=e,c=(0,d.useWatchedValueReadonly)({watchedValue:m.watchedTheme}),[f,v]=(0,n.useState)(function({country:e,providerId:t,sourceId:r}){const n=(0,l.getLogoUrlResolver)();return o=>{const a=e=>n.getProviderLogoUrl(e,h),s=[{value:r,resolve:a},{value:e,resolve:e=>n.getCountryFlagUrl(e.toUpperCase(),h)},{value:t,resolve:a}].find((({value:e})=>void 0!==e&&e.length>0));return void 0!==s?s.resolve((0,p.ensureDefined)(s.value)):u(o)}}({country:t,providerId:o,sourceId:s})(c));return n.createElement("img",{className:a()(i,"apply-common-tooltip",g.icon),crossOrigin:"","data-tooltip":r,src:f,onError:function(){v(u(c))}})}},58442:(e,t,r)=>{"use strict";r.d(t,{QualifiedSources:()=>n,qualifyProName:()=>s});var n,o=r(50151),a=r(56570);r(81319);function s(e){return e}!function(e){function t(e){return e.pro_name}function r(e){{const t=a.enabled("pay_attention_to_ticker_not_symbol")?e.ticker:e.name;return(0,o.ensureDefined)(t)}}e.fromQuotesSnapshot=function(e){return"error"===e.status?e.symbolname:e.values.pro_name},e.fromQuotesResponse=function(e){const{values:r,symbolname:n,status:o}=e;return"error"===o&&n?n:t(r)},e.fromQuotes=t,e.fromSymbolSearchResult=function(e,t){{const{ticker:r,symbol:n}=t??e;return a.enabled("pay_attention_to_ticker_not_symbol")?(0,o.ensureDefined)(r??n):(0,o.ensureDefined)(n)}},e.fromSymbolInfo=r,e.fromSymbolMessage=function(e,t){return"symbol_resolved"===t.method?r(t.params[1]):e}}(n||(n={}))},20882:(e,t,r)=>{"use strict";r.d(t,{createSearchSources:()=>l,
|
||||
filterSearchSources:()=>a,isAllSearchSourcesSelected:()=>o,splitSearchSourcesByGroup:()=>s});const n=[];function o(e){return""===e.value()}function a(e,t){return e.filter((e=>e.includes(t)))}function s(e){const t=new Map;e.forEach((e=>{t.has(e.group())?t.get(e.group()).push(e):t.set(e.group(),[e])}));for(const e of t.values()){e[0].group()!==ExchangeGroup.NorthAmerica&&e.sort(((e,t)=>e.name().toLowerCase()>t.name().toLowerCase()?1:-1))}return new Map([...t.entries()].sort((([e],[t])=>n.indexOf(e)-n.indexOf(t))))}function l(e,t){return t.map((t=>new e(t)))}},70613:(e,t,r)=>{"use strict";r.d(t,{SymbolSearchDialogBodyContext:()=>n});const n=r(50959).createContext(null)},84524:(e,t,r)=>{"use strict";r.d(t,{SymbolSearchItemsDialogContext:()=>n});const n=r(50959).createContext(null)},73280:(e,t,r)=>{"use strict";r.d(t,{SymbolSearchItemsDialog:()=>et});var n,o,a,s=r(50959),l=r(97754),i=r.n(l),c=r(11542),u=r(56570),d=r(44254),m=r(81319);function p(e){const t=function(e){let t,r=0,n=0;for(let o=0;o<e.length;o++){const a=e[o];if("whitespace"!==a.type)switch(r){case 0:if("number"!==a.type||1!=+a.value)return[];r=1;break;case 1:if(1!==r||"divide"!==a.type)return[];r=2,t=o+1;break;case 2:if("openBrace"===a.type)r=3,n=1;else if((0,d.isBinaryOperator)(a.type))return[];break;case 3:"openBrace"===a.type?n++:"closeBrace"===a.type&&(n--,n<=0&&(r=2))}}return e.slice(t)}(e);return t.length?(0,d.factorOutBraces)(t):(0,d.factorOutBraces)((0,d.tokenize)("1/("+h(e)+")"))}function h(e){return e.reduce(((e,t)=>"symbol"===t.type&&d.symbolTokenEscapeRe.test(t.value)?e+`'${t.value}'`:e+t.value),"")}function g(e){const t=function(e){const t=(0,d.tokenize)(e),r=[];return t.forEach((e=>{if("symbol"!==e.type)return;const[t]=(0,d.parseToken)(e);t&&r.push(t)})),r}(e);if(1===t.length)return t[0]}function f(e,t,r){const n=e.value,[o,a]=v(e,r),s=(0,m.getSymbolFullName)(t),l=d.symbolTokenEscapeRe.test(s)?`'${s}'`:s;return[n.substring(0,a)+l+n.substring(a+o.length),a+l.length]}function v(e,t){const{value:r,selectionStart:n}=e,o=(0,d.tokenize)(t?r.toUpperCase():r),a=(0,d.getTokenAtPos)(o,n||0);return[a?.value||"",a?a.offset:r.length,o]}!function(e){e.Init="init",e.Var="var",e.Operator="operator"}(n||(n={})),function(e){e[e.Init=0]="Init",e[e.Div=1]="Div",e[e.Expression=2]="Expression",e[e.BracedExpression=3]="BracedExpression"}(o||(o={})),function(e){e.Stocks="stocks",e.Futures="futures",e.Funds="funds",e.Forex="forex",e.Crypto="bitcoin,crypto",e.Index="index",e.Bond="bond",e.Economic="economic",e.Options="options"}(a||(a={}));const b=["futures","forex","bond","economic","options"];var y=r(84877),S=r(24437),x=r(79418),w=r(9745),k=r(86240),C=r(86781),E=r(84524),I=r(69654),R=r(3343),L=r(19291);function T(e,t,r){return`source-item-${e}-${t}-${r}`}var B=r(20882),N=r(24517);function M(e){const{children:t,className:r}=e;return s.createElement("div",{className:i()(N.container,r)},s.createElement("div",{className:N.childrenWrapper},t))}var D=r(50151),O=r(78036),A=r(24637),P=r(97006),_=r(91540),F=r(6109);function W(e){
|
||||
const{searchSource:t,onClick:r,queryString:n,isFocused:o,id:a}=e,{symbolSearchContent:l,isAllSearchSourcesSelected:c,allSearchSourcesTitle:u,isMobile:d}=(0,O.useEnsuredContext)(E.SymbolSearchItemsDialogContext),p=l.currentSelectedSearchSource,h=(0,D.ensureNotNull)(p).value(),g=c(t),f=t.value()===h,v=(0,s.useMemo)((()=>(0,P.createRegExpList)(n)),[n]),b=t.description(),y=b&&!g,S=m.isSeparateSymbolSearchTabs&&g&&u?u:t.name(),x=i()(F.container,d?F.mobile:F.desktop,f&&F.selected,o&&F.focused,g&&F.allSelected,g&&F.libAllSelected,!g&&d&&F.bordered);return s.createElement("div",{className:i()(!d&&F.wrap,g&&F.libAllSelected),onClick:r,id:a},s.createElement("div",{className:x},s.createElement("div",{className:F.iconWrap},!!g&&s.createElement(w.Icon,{className:i()(F.icon,F.allSelectedIcon),icon:_})),s.createElement("div",{className:F.textBlock},s.createElement("div",{className:i()(F.title,!y&&!d&&F.titleWithoutDesc)},s.createElement(A.HighlightedText,{className:i()(f&&F.highlighted),queryString:n,text:S,rules:v})),y&&s.createElement("div",{className:i()(F.description,"apply-overflow-tooltip")},s.createElement(A.HighlightedText,{className:F.highlighted,queryString:n,rules:v,text:b})))))}var Q=r(77975),U=r(45345),V=r(24633),K=r(70613),z=r(66619),H=r(67562),Z=r(96137);const G={emptyTextClassName:Z.emptyText};function q(e){const{searchSources:t}=e,{setSelectedIndex:n,setSelectedSearchSource:o,setMode:a,isMobile:l,emptyState:u,autofocus:d}=(0,O.useEnsuredContext)(E.SymbolSearchItemsDialogContext),p=(0,Q.useWatchedValueReadonly)({watchedValue:U.watchedTheme})===V.StdTheme.Dark?z:H,h=(0,C.useMatchMedia)(k["media-phone-vertical"]),[g,f]=(0,s.useState)(""),v=(0,s.useMemo)((()=>[{group:null,sources:(0,m.createGroupColumns)((0,B.filterSearchSources)(t,g),h?1:2)}]),[t,g,h]),b=((0,s.useMemo)((()=>({})),[]),(0,s.useRef)(null)),y=(0,s.useRef)(null),{focusedItem:S,activeDescendant:x,handleKeyDown:N,resetFocusedItem:D}=function(e,t,r){const[n,o]=(0,s.useState)(null),[a,l]=(0,s.useState)("");function i(t){const r=e[t.groupIndex].sources[t.col].length-1;if(t.row===r){const e=d(t.groupIndex+1);if(null===e)return;return t.col>0&&!u({...t,groupIndex:e,row:0})?void o({groupIndex:e,col:0,row:0}):void o({...t,groupIndex:e,row:0})}o({...t,row:t.row+1})}function c(t){if(0===t.row){const r=d(t.groupIndex-1,-1);if(null===r)return;const n=e[r].sources[t.col]?.length??0;return 0===n?void o({groupIndex:r,col:0,row:0}):void o({...t,groupIndex:r,row:n-1})}o({...t,row:t.row-1})}function u(t){return Boolean(e[t.groupIndex]?.sources[t.col]?.[t.row])}function d(t=0,r=1){const n=e.length;let o=(t+n)%n;for(;!u({groupIndex:o,col:0,row:0});)if(o=(o+r+n)%n,o===t)return null;return o}return(0,s.useEffect)((()=>{if(!r.current)return;if(!n)return void l("");const e=T(n.groupIndex,n.col,n.row),t=r.current.querySelector(`#${e}`);t?.scrollIntoView({block:"nearest"}),l(e)}),[n]),(0,s.useEffect)((()=>{o(null)}),[t]),{focusedItem:n,activeDescendant:a,handleKeyDown:function(a){if(!r.current)return;const s=(0,R.hashFromEvent)(a);if(32!==s&&13!==s)switch((0,
|
||||
L.mapKeyCodeToDirection)(s)){case"blockNext":if(a.preventDefault(),!n){const e=d();if(null===e)break;o({groupIndex:e,col:0,row:0});break}i(n);break;case"blockPrev":if(a.preventDefault(),!n)break;c(n);break;case"inlineNext":{if(!n||t)break;a.preventDefault();const r=e[n.groupIndex].sources.length;if(n.col===r-1||!u({...n,col:n.col+1})){i({...n,col:0});break}o({...n,col:n.col+1});break}case"inlinePrev":{if(!n||t)break;a.preventDefault();const r=e[n.groupIndex].sources.length;if(0===n.col){if(0!==n.row){c({...n,col:r-1});break}const t=d(n.groupIndex-1,-1);if(null===t)break;const a=e[t].sources.length,s=e[t].sources[0].length;if(!u({groupIndex:t,col:a-1,row:s-1})){c(n);break}o({groupIndex:t,col:a-1,row:s-1});break}o({...n,col:n.col-1});break}}else{if(!n)return;a.preventDefault();const e=r.current.querySelector(`#${T(n.groupIndex,n.col,n.row)}`);e instanceof HTMLElement&&e.click()}},resetFocusedItem:()=>o(null)}}(v,h,y);(0,s.useLayoutEffect)((()=>{d&&b?.current?.focus()}),[]);const A=u?s.createElement(u,null):s.createElement(M,{className:Z.noResultsDesktop},s.createElement(w.Icon,{icon:p,className:Z.emptyIcon}),s.createElement("div",{className:Z.emptyText},c.t(null,void 0,r(53182)))),P=!(v.length&&v.every((e=>0===e.sources.length)));return s.createElement(K.SymbolSearchDialogBodyContext.Provider,{value:G},s.createElement(I.DialogSearch,{placeholder:c.t(null,void 0,r(8573)),onChange:function(e){D(),f(e.target.value),y&&y.current&&(y.current.scrollTop=0)},reference:b,onKeyDown:N,onBlur:D,"aria-activedescendant":x}),P?s.createElement("div",{ref:y,className:i()(Z.contentList,!l&&Z.contentListDesktop),onTouchStart:function(){b.current?.blur()}},v.map(((e,t)=>{const{group:r,sources:n}=e;return 0===n.length?s.createElement(s.Fragment,{key:r}):s.createElement(s.Fragment,{key:r},!1,s.createElement("div",{className:i()(Z.searchSourceItemsContainer,!l&&Z.searchSourceItemsContainerDesktop,h&&Z.oneColumn)},n.map(((e,r)=>s.createElement("div",{key:`${t}-${r}`,className:Z.column},e.map(((e,n)=>s.createElement(W,{id:T(t,r,n),isFocused:!!S&&(S.groupIndex===t&&S.col===r&&S.row===n),key:e.value(),searchSource:e,queryString:g,onClick:_.bind(null,e)}))))))))}))):A);function _(e){o(e),a("symbolSearch"),n(-1)}}var j,$,Y,X,J=r(32227),ee=r(14051);r(84906);function te(e){return e.hasOwnProperty("exchange")}async function re(e){{const t=await async function(e){return new Promise((t=>{window.ChartApiInstance.searchSymbols(e.text||"",e.exchange||"",e.type||"",(e=>{t(e)}),e.searchInitiationPoint??"symbolSearch")}))}(e);return{symbols:t,symbols_remaining:0}}}!function(e){e.SourceId="source_id",e.EconomicCategory="economic_category",e.SearchType="search_type",e.Sector="sector",e.Product="product",e.Centralization="centralization",e.OnlyHasOptions="only_has_options"}(j||(j={})),function(e){e.SymbolSearch="symbolSearch",e.Watchlist="watchlist",e.Compare="compare",e.IndicatorInputs="indicatorInputs"}($||($={})),function(e){e[e.Prod=0]="Prod",e[e.Local=1]="Local"}(Y||(Y={})),function(e){e[e.Paginated=0]="Paginated",e[e.NoLimit=1]="NoLimit"}(X||(X={}))
|
||||
;new Map([].map((({value:e,search_type:t})=>[e,t])));var ne=r(78136),oe=r(51768),ae=r(68335),se=r(81348),le=r(486),ie=r(81574),ce=r(35119),ue=r(32617),de=r(69135),me=r(63861),pe=r(10070);function he(e){const{state:t,update:r}=e,{searchRef:n,forceUpdate:o,upperCaseEnabled:a}=(0,D.ensureNotNull)((0,s.useContext)(E.SymbolSearchItemsDialogContext)),l=(0,d.tokenize)(n.current?.value),i=function(e){const t={braceBalance:0,currentState:"var",warnings:[],errors:[]};if(!u.enabled("show_spread_operators"))return t;let r="init";const n=[];for(let o=0;o<e.length;o++){const a=e[o];if("whitespace"!==a.type){if("incompleteSymbol"===a.type||"incompleteNumber"===a.type){const r=o!==e.length-1,n={status:r?"error":"incomplete",reason:"incomplete_token",offset:a.offset,token:a};if(r?t.errors.push(n):t.warnings.push(n),r)continue}switch(a.type){case"symbol":case"number":if("var"===r){t.errors.push({status:"error",reason:"unexpected_token",offset:a.offset,token:a});continue}r="var";break;case"plus":case"minus":case"multiply":case"divide":case"power":if("var"!==r){t.errors.push({status:"error",reason:"unexpected_token",offset:a.offset,token:a});continue}r="operator";break;case"openBrace":if("var"===r){t.errors.push({status:"error",reason:"unexpected_token",offset:a.offset,token:a});continue}n.push(a),r="init";break;case"closeBrace":if("var"!==r){t.errors.push({status:"error",reason:"unexpected_token",offset:a.offset,token:a});continue}n.pop()||t.errors.push({status:"error",reason:"unbalanced_brace",offset:a.offset,token:a}),r="var";break;case"unparsed":t.errors.push({status:"error",reason:"unparsed_entity",offset:a.offset,token:a})}}}for(t.braceBalance=n.length,"var"!==r&&t.warnings.push({status:"incomplete",token:e[e.length-1]});n.length;){const e=n.pop();e&&t.warnings.push({status:"incomplete",reason:"unbalanced_brace",offset:e.offset,token:e})}return t.currentState=r,t}(l);let c=[{icon:le,insert:"/",type:"binaryOp",name:"division"},{icon:ie,insert:"-",type:"binaryOp",name:"subtraction"},{icon:ce,insert:"+",type:"binaryOp",name:"addition"},{icon:ue,insert:"*",type:"binaryOp",name:"multiplication"}];return u.enabled("hide_exponentiation_spread_operator")||(c=c.concat([{icon:de,insert:"^",type:"binaryOp",name:"exponentiation"}])),u.enabled("hide_reciprocal_spread_operator")||(c=c.concat([{icon:me,type:"complete",name:"1/x",callback:()=>{!n.current||i.errors.length||i.warnings.length||(n.current.value=h(p(l)),o())}}])),s.createElement("div",{className:pe.actions},c.map((e=>s.createElement(se.ToolWidgetButton,{className:pe.actionButton,icon:e.icon,key:e.name,isDisabled:ge(e,i),onClick:()=>function(e){if(!ge(e,i)){if(e.insert&&n.current){const s=n.current.value+e.insert;n.current.value=s,n.current.setSelectionRange(s.length,s.length);const[l,,i]=v(n.current,a);t.current&&(t.current.selectedIndexValue=-1,t.current.searchSpreadsValue=(0,d.isSpread)(i),t.current.searchTokenValue=l),o(),r()}e.callback&&e.callback(),n.current?.focus(),(0,oe.trackEvent)("GUI","SS",e.name)}}(e)}))))}function ge(e,t){let r=!1;if(!t.errors.length)switch(e.type){
|
||||
case"binaryOp":r="var"===t.currentState;break;case"openBrace":r="var"!==t.currentState;break;case"closeBrace":r="var"===t.currentState&&t.braceBalance>0;break;case"complete":r=!t.errors.length&&!t.warnings.length}return!r}var fe=r(63932),ve=r(84952),be=r(29006),ye=r(14543),Se=r(10381),xe=r(52019),we=r(92244);const ke=(0,m.getDefaultSearchSource)();function Ce(e){const{mode:t,setMode:n,searchRef:o,cachedInputValue:a,setSelectedIndex:l,setSelectedSearchSource:u,isAllSearchSourcesSelected:d,allSearchSourcesTitle:p,upperCaseEnabled:h,symbolSearchContent:g}=(0,O.useEnsuredContext)(E.SymbolSearchItemsDialogContext),f=g.currentSelectedSearchSource,v=(0,D.ensureNotNull)(f),b="symbolSearch"===t,y=d(v),S=m.isSeparateSymbolSearchTabs&&y&&p?p:v.name(),x=(0,s.useCallback)((()=>{if(m.isSeparateSymbolSearchTabs&&!y&&ke)return u(ke),l(-1),void o.current?.focus();o.current&&(a.current=h?o.current.value.toUpperCase():o.current.value),n("exchange")}),[y,o,h,n,u]);return m.isSeparateSymbolSearchTabs?b?s.createElement(ye.LightButton,{onClick:x,isPills:!y,size:"xsmall",variant:y?"ghost":"quiet-primary",showCaret:y,endSlot:y?void 0:s.createElement(w.Icon,{icon:xe}),enableActiveStateStyles:!1,className:i()(we.button,!y&&we.withFlag),tabIndex:-1,"data-name":"sources-button"},s.createElement("div",{className:we.buttonContent},null,s.createElement("span",null,S))):null:b?s.createElement("div",{className:i()(we.flagWrap,"apply-common-tooltip",!y&&we.withFlag),title:c.t(null,void 0,r(57640)),onClick:x,"data-name":"sources-button"},y&&s.createElement(w.Icon,{className:we.icon,icon:_}),null,s.createElement("div",{className:i()(we.title)},S),s.createElement(Se.ToolWidgetCaret,{className:we.caret,dropped:!1})):null}var Ee=r(6591);function Ie(e){const{brokerButton:t=null}=e,{isSmallWidth:n,selectedFilterValues:o,setSelectedFilterValues:a,setSelectedIndex:l,isMobile:u,searchRef:d,symbolSearchContent:p}=(0,O.useEnsuredContext)(E.SymbolSearchItemsDialogContext),h=p.tabSelectFilters;return m.isSeparateSymbolSearchTabs?s.createElement("div",{className:i()(Ee.wrap,Ee.small,Ee.newStyles,u&&Ee.mobile)},t&&s.createElement("div",{className:Ee.brokerWrap},t),p.canChangeExchange&&s.createElement("div",{className:Ee.filterItem},s.createElement(Ce,null)),h&&h.map((e=>{const{id:t,options:r,label:n}=e,i=r.find((e=>e.value===FILTER_DEFAULT_VALUE));if(!i)throw new Error("There must be default filter value in filter definition");const c=r.find((e=>e.value===o[p.currentSymbolType]?.[t]))||i;return s.createElement("div",{key:t,className:Ee.filterItem},s.createElement(SymbolSearchSelectFilter,{selectedOption:c,defaultOption:i,options:r,onSelect:e=>{a(p.currentSymbolType,{[t]:e.value}),trackEvent("New SS",p.currentSymbolType,null===e.value?e.analyticsLabel:e.value),l(-1),d.current?.focus()},label:n,isMobile:u,"data-name":t}))}))):s.createElement("div",{className:i()(Ee.wrap,n&&Ee.small)},s.createElement("div",{className:Ee.item},s.createElement("div",{className:Ee.text},n?c.t(null,void 0,r(74007)):c.t(null,void 0,r(95481)))),s.createElement("div",{className:Ee.item
|
||||
},!n&&s.createElement("div",{className:Ee.text},c.t(null,void 0,r(78734))),p.canChangeExchange&&s.createElement("div",{className:Ee.exchange},s.createElement(Ce,null))))}var Re=r(63273),Le=r(44458);function Te(e){const{onTouchMove:t,listRef:r,className:n,listWrapRef:o,virtualListKey:a,items:l,getItemSize:c,hideFeed:u,canLoadMore:d,onLoadMoreSymbols:p}=e,{mode:h,isSmallWidth:g,handleListWidth:f}=(0,O.useEnsuredContext)(E.SymbolSearchItemsDialogContext),[v,b]=(0,s.useState)(null),y=(0,be.useResizeObserver)((function([e]){b(e.contentRect.height),f(e.contentRect.width)})),S=(0,s.useCallback)((e=>{const{index:t,style:r}=e;return s.createElement("div",{style:r},l[t])}),[l]),x=(0,s.useCallback)((e=>(0,D.ensure)(l[e].key)),[l]),w="watchlist"===h&&null!==v;return s.createElement("div",{className:i()(Le.wrap,w&&Le.watchlist,u&&Le.noFeed,u&&m.isSeparateSymbolSearchTabs&&Le.newStyles,n),onTouchMove:t,ref:y},s.createElement("div",{ref:o,className:i()(Le.scrollContainer,u&&Le.noFeed)},w?s.createElement(ve.VariableSizeList,{key:a,ref:r,className:Le.listContainer,width:"100%",height:(0,D.ensureNotNull)(v),itemCount:l.length,itemSize:c,children:S,itemKey:x,overscanCount:20,direction:(0,Re.isRtl)()?"rtl":"ltr"}):s.createElement(s.Fragment,null,s.createElement("div",{className:i()(Le.listContainer,g&&Le.multiLineItemsContainer)},!m.isSeparateSymbolSearchTabs&&s.createElement(Ie,null),...l,!1))))}var Be=r(96967),Ne=r(47308),Me=r(76717);const De=u.enabled("hide_image_invalid_symbol");function Oe(e){const{otherSymbolsCount:t,onChangeSymbolTypeFilter:r,onResetFilters:n,onListTouchMove:o,brokerTitle:a,brokerLogoInfo:i,isBrokerActive:c,onBrokerToggle:u,listRef:d,listWrapRef:p,onLoadMoreSymbols:h,canLoadMore:g}=e,{mode:f,isMobile:v,selectedSymbolType:b,symbolTypes:y,feedItems:S,contentItem:x,emptyState:w=Ae,symbolSearchContent:k,symbolSearchState:C}=(0,O.useEnsuredContext)(E.SymbolSearchItemsDialogContext),I=a?s.createElement(BrokerButton,{brokerTitle:a,isActive:c,onToggle:u,onKeyDown:e=>{const t=(0,R.hashFromEvent)(e);t!==9+R.Modifiers.Shift&&9!==t&&e.stopPropagation()},logoInfo:i}):null,L=y.map((e=>({id:e.value,children:e.name}))),T="symbolSearch"===f&&["good","loadingWithPaginated"].includes(C),B=x??Be.SymbolSearchDialogContentItem,N=(0,s.useMemo)((()=>S.map((e=>s.createElement(B,{...e,searchToken:k.token})))),[S]);return s.createElement(s.Fragment,null,"symbolSearch"===f&&s.createElement(s.Fragment,null,s.createElement("div",{className:l(Me.bubblesContainer,!v&&I&&Me.withButton,v&&Me.mobile)},y.length>0&&s.createElement(Ne.RoundButtonTabs,{id:"symbol-search-tabs",isActive:e=>e.id===b,onActivate:r,overflowBehaviour:v?"scroll":"wrap",className:l(Me.bubbles,v&&Me.mobile,m.isSeparateSymbolSearchTabs&&(k.withFilters||I)&&!v&&Me.withFilters),items:L},v?null:s.createElement("div",null,I)),!m.isSeparateSymbolSearchTabs&&v&&y.length>0&&a&&s.createElement("div",{className:Me.brokerButtonWrap},I)),m.isSeparateSymbolSearchTabs&&s.createElement(Ie,{brokerButton:v?I:void 0})),s.createElement(Te,{listRef:d,listWrapRef:p,onTouchMove:o,items:N,
|
||||
getItemSize:()=>_e,onLoadMoreSymbols:h,canLoadMore:g,hideFeed:!T}),"loading"===C&&s.createElement("div",{className:Me.spinnerWrap},s.createElement(fe.Spinner,null)),"symbolSearch"===f&&s.createElement(s.Fragment,null,!1,"empty"===C&&s.createElement(w,null)))}function Ae(e){const t=(0,Q.useWatchedValueReadonly)({watchedValue:U.watchedTheme})===V.StdTheme.Dark?z:H;return s.createElement(M,{className:Me.noResultsDesktop},!De&&s.createElement(w.Icon,{icon:t,className:Me.emptyIcon}),s.createElement("div",{className:Me.emptyText},c.t(null,void 0,r(76822))))}const Pe=(0,m.getDefaultSearchSource)(),_e=52;function Fe(e){const{mode:t,setMode:n,setSelectedIndex:o,isMobile:a,selectedSearchSource:l,setSelectedSearchSource:p,isAllSearchSourcesSelected:h,selectedSymbolType:b,setSelectedSymbolType:y,symbolSearchContent:S,setSymbolSearchContent:x,searchRef:w,setSearchSpreads:k,showSpreadActions:C,selectedItem:R,forceUpdate:L,placeholder:T,initialScreen:B,footer:N,searchInput:M,upperCaseEnabled:D,externalInput:A,handleKeyDown:P,customSearchSymbols:_,filterDefinitions:F,filterQueryParams:W,searchSources:Q,symbolSearchState:U,setSymbolSearchState:V,onEmptyResults:z,searchInitiationPoint:H}=(0,O.useEnsuredContext)(E.SymbolSearchItemsDialogContext),Z=_??re,G=(0,s.useRef)(t);G.current=t;const q=(0,s.useRef)(new AbortController),[j,$]=(0,s.useState)(0),Y=(0,s.useRef)(0),[X,se]=(0,s.useState)(S.token),le=(0,s.useRef)(null),ie=(0,s.useRef)(null),ce=(0,s.useRef)({selectedIndexValue:-1,searchTokenValue:"",searchSpreadsValue:!0}),ue=(0,s.useRef)(null),de=(0,s.useRef)(null),me=(0,s.useRef)(null),{broker:pe=null,brokerId:ge,brokerTitle:fe,brokerLogoInfo:ve,isBrokerChecked:be=!1,setIsBrokerChecked:ye=()=>{},unhideSymbolSearchGroups:Se=""}={brokerId:void 0,brokerTitle:void 0,brokerLogoInfo:void 0};(0,s.useEffect)((()=>()=>{q.current.abort(),Fe(),We()}),[]),(0,s.useEffect)((()=>{w?.current&&se(w.current.value)}),[]),(0,s.useEffect)((()=>{const e=w.current;if(e)return e.addEventListener("input",Re),e.addEventListener("focus",Ae),e.addEventListener("select",Ie),e.addEventListener("click",Ie),e.addEventListener("keyup",_e),A&&P&&e.addEventListener("keydown",P),()=>{e&&(e.removeEventListener("input",Re),e.removeEventListener("focus",Ae),e.removeEventListener("select",Ie),e.removeEventListener("click",Ie),e.removeEventListener("keyup",_e),A&&P&&e.removeEventListener("keydown",P))}}),[P]),(0,s.useEffect)((()=>{Boolean(B)&&""===X.trim()?x((e=>{const t=Boolean(l&&Q.length>1&&!(0,m.exchangeSelectDisabled)(b)),r=F?.[b];return{...e,tabSelectFilters:r,currentSymbolType:b,canChangeExchange:t,withFilters:Boolean(t||r?.length),token:X,currentTabAvailableSearchSources:Q,currentSelectedSearchSource:l}})):(x((e=>({...e,symbolStartIndex:0}))),Te(X,b,l).then((()=>{le.current&&(le.current.scrollTop=0)})))}),[X,b,l,be,B,W]),(0,s.useEffect)((()=>{if(!R||!w.current)return;if(!u.enabled("show_spread_operators"))return w.current.value=R.symbol,void L();const e=te(R)?R.exchange:R.parent.exchange;let t;t="contracts"in R&&R.contracts?.length?R.contracts[0]:R;const r={
|
||||
name:t.symbol,exchange:e,prefix:t.prefix,fullName:t.full_name},[n,o]=f(w.current,r,D);w.current.value=n,w.current.setSelectionRange(o,o),L()}),[R]);const xe=B??"div",we=Boolean(B)&&"symbolSearch"!==t,ke=M??I.DialogSearch,Ce=(0,s.useMemo)((()=>({listRef:ie,resetRecommends:De,updateRecommends:Te,searchToken:X,emptyTextClassName:Me.emptyText,isBrokerChecked:be,symbolSearchState:U,currentMode:G})),[ie,X,be,U,G,W]);return s.createElement(K.SymbolSearchDialogBodyContext.Provider,{value:Ce},!(A&&"symbolSearch"===t)&&s.createElement(ke,{reference:w,className:i()(Me.search,D&&Me.upperCase),placeholder:T||c.t(null,void 0,r(8573))},C&&s.createElement(he,{state:ce,update:Le})),we?s.createElement(xe,null):s.createElement(Oe,{otherSymbolsCount:j,onListTouchMove:function(){w.current?.blur()},onChangeSymbolTypeFilter:function(e){const{id:t}=e;y(t),o(-1)},onResetFilters:function(){m.isSeparateSymbolSearchTabs?"resetFilter"===U?y((0,m.getAllSymbolTypesValue)()):Pe&&p(Pe):(y((0,m.getAllSymbolTypesValue)()),Pe&&p(Pe));ye(!1),a||w.current?.focus()},brokerTitle:fe,brokerLogoInfo:ve,isBrokerActive:be,onBrokerToggle:ye,listRef:ie,listWrapRef:le,onLoadMoreSymbols:void 0,canLoadMore:void 0}),N);function Ee(){if(!w.current)return;const[e,t,r]=v(w.current,D);Y.current=t,ce.current={selectedIndexValue:-1,searchSpreadsValue:(0,d.isSpread)(r),searchTokenValue:e},ue.current||(ue.current=setTimeout(Le,0))}function Ie(){if(!w.current)return;const[,e]=v(w.current,D);e!==Y.current&&Ee()}function Re(){u.enabled("show_spread_operators")?Ee():w.current&&(ce.current={selectedIndexValue:-1,searchSpreadsValue:!1,searchTokenValue:w.current.value},ue.current||(ue.current=setTimeout(Le,0)))}function Le(){const{selectedIndexValue:e,searchTokenValue:t,searchSpreadsValue:r}=ce.current;ue.current=null,(0,J.unstable_batchedUpdates)((()=>{k(r),o(e),se(D?t.toUpperCase():t)}))}async function Te(e,t,r,n){try{"noop"===U?V("loading"):n?V("loadingWithPaginated"):(Fe(),We(),de.current=setTimeout((()=>{const r=Boolean(l&&Q.length>1&&!(0,m.exchangeSelectDisabled)(t)),n=F?.[t];x({token:e,canChangeExchange:r,tabSelectFilters:n,withFilters:Boolean(r||n?.length),currentSymbolType:t,currentSelectedSearchSource:l,currentTabAvailableSearchSources:Q,renderSymbolSearchList:[],symbolsRemaining:0,symbolStartIndex:0}),V("loading")}),500)),Qe();(0,m.getAllSymbolTypesValue)();const o=!1;let a;if(be&&pe){a=(await(0,ee.respectAbort)(q.current.signal,pe.accountMetainfo())).prefix}const s=u.enabled("show_spread_operators")?g(e)??a??r?.getRequestExchangeValue():l?.getRequestExchangeValue(),i=g(e)?void 0:(r||l)?.getRequestCountryValue(),[c,d]=await Promise.all([Ne(q.current.signal,e,t,r,s,i,n),o&&!n?getRecent():Promise.resolve([])]),p=d.filter((e=>s?e.exchange?.toLowerCase()===s.toLowerCase():!i||e.country?.toLowerCase()===i.toLowerCase())),h=new Set(p.map((e=>`${e.exchange}_${e.symbol}`))),f=c.symbols.filter((e=>!h.has(`${e.exchange}_${e.symbol}`)));let v=function(e,t=window.ChartApiInstance.symbolsGrouping()){const r={},n=[];for(let o=0;o<e.length;++o){const a=e[o]
|
||||
;if(a.prefix||Array.isArray(a.contracts))return e;const s=t[a.type];if(void 0===s){n.push(a);continue}const l=s.exec(a.symbol);if(l){const e=l[1];let t;r.hasOwnProperty(e)?t=r[e]:(t=n.length,r[e]=t,n.push({type:a.type,symbol:e,exchange:a.exchange,description:a.description,full_name:a.exchange+":"+e,contracts:[]})),n[t].contracts?.push(a)}else n.push(a)}return n}([...p,...f]);if(n&&(v=[...S.renderSymbolSearchList,...v]),!v.length)return x((r=>{const n=Boolean(l&&Q.length>1&&!(0,m.exchangeSelectDisabled)(t)),o=F?.[t];return{...r,canChangeExchange:n,tabSelectFilters:o,token:e,symbolsRemaining:0,withFilters:Boolean(n||o?.length),currentSymbolType:t,currentSelectedSearchSource:l,currentTabAvailableSearchSources:Q}})),Fe(),V("empty"),void Be();Fe(),x((r=>{const n=Boolean(l&&Q.length>1&&!(0,m.exchangeSelectDisabled)(t)),o=F?.[t];return{...r,canChangeExchange:n,tabSelectFilters:o,renderSymbolSearchList:v,token:e,symbolsRemaining:c.symbols_remaining,withFilters:Boolean(n||o?.length),currentSymbolType:t,currentSelectedSearchSource:l,currentTabAvailableSearchSources:Q,symbolStartIndex:r.symbolStartIndex+c.symbols.length}})),V("good")}catch(e){(0,ee.skipAbortError)(e)}}function Be(){z&&(me.current=setTimeout((()=>z()),1e3))}async function Ne(e,t,r,n,o,a,s){const l={serverHighlight:!1,text:u.enabled("show_spread_operators")?(0,d.shortName)(t):w.current?.value,exchange:o,country:a,type:r,lang:window.language||"",sortByCountry:void 0,brokerId:ge,onlyTradable:Boolean(ge)&&be,unhideSymbolSearchGroups:Se,signal:e,start:s,filterQueryParams:W,searchInitiationPoint:H},i=(0,ne.getSearchRequestDelay)();return void 0!==i&&await(0,ee.delay)(e,i),Z(l)}function De(){Qe(),V("empty"),se(""),k(!1),x((e=>({...e,symbolStartIndex:0}))),Fe()}function Ae(){"watchlist"===G.current&&(n("symbolSearch"),(0,oe.trackEvent)("Watchlist","Mobile SS","Go to SS page"))}function _e(e){switch((0,ae.hashFromEvent)(e)){case 37:case 39:Ie()}}function Fe(){de.current&&clearTimeout(de.current)}function We(){me.current&&clearTimeout(me.current)}function Qe(){q.current.abort(),q.current=new AbortController}}var We=r(48199),Qe=r(74395),Ue=r(58442),Ve=r(56840);function Ke(e){const[t,r]=(0,s.useState)((()=>{const{defaultSearchSource:t,searchSources:r}=e,n=Ve.getValue("symboledit.exchangefilter","");return r.find((e=>e.value()===n))||t}));return[t,(0,s.useCallback)((e=>{var t;r(e),t=e,Ve.setValue("symboledit.exchangefilter",t.value())}),[])]}function ze(e){const[t,r]=(0,s.useState)((()=>{if(1===e.types.length)return e.types[0].value;const t=Ve.getValue("symboledit.filter",(0,m.getAllSymbolTypesValue)());return e.types.find((e=>e.value===t))?t:(0,m.getAllSymbolTypesValue)()}));return[t,(0,s.useCallback)((e=>{var t;r(e),t=e,Ve.setValue("symboledit.filter",t)}),[])]}var He=r(36947),Ze=r(82708),Ge=r(88145),qe=r(76460),je=r(63748);const $e=!1,Ye=(0,m.getAvailableSearchSources)(),Xe=(0,m.getDefaultSearchSource)(),Je=u.enabled("uppercase_instrument_names");function et(e){
|
||||
const{onClose:t,symbolTypeFilter:n,initialMode:o,defaultValue:a="",showSpreadActions:l,hideMarkedListFlag:i,selectSearchOnInit:d=!0,onSearchComplete:p,dialogTitle:h=c.t(null,void 0,r(51165)),placeholder:g,fullscreen:v,initialScreen:x,wrapper:w,dialog:k,contentItem:C,footer:I,searchInput:R,emptyState:T,autofocus:N,dialogWidth:M,onKeyDown:D,searchSourcesScreen:O,customSearchSymbols:A,isDisableFiltering:P,disableRecents:_,shouldReturnFocus:F,onSymbolFiltersParamsChange:W,onEmptyResults:Q,enableOptionsChain:U,searchInitiationPoint:V="symbolSearch"}=e,K=(0,s.useMemo)((()=>{if(P)return[];const t=e.symbolTypes??(0,m.getAvailableSymbolTypes)();return n?n(t):t}),[]),z=void 0!==e.input,H=P?[]:Ye,[Z,G]=(0,s.useState)((()=>st(a,U)?"options":o)),[j,$]=(0,s.useState)((()=>st(a,U))),[Y,X]=(0,s.useState)((()=>null)),J=(0,s.useRef)(function(e,t){const r=st(e,t);return(0,m.isOptionDefaultValue)(e)?r??e.value:e}(a,U)),[ee,ne]=Ke({searchSources:H,defaultSearchSource:Xe}),[oe,se]=[],[le,ie]=ze({types:K}),[ce,ue]=[{},()=>{}],[de,me]=(0,s.useState)(!1),[pe,he]=(0,s.useState)(-1),[ge,fe]=(0,s.useState)("noop"),ve=m.isSeparateSymbolSearchTabs?TAB_SELECT_FILTER_MAP:void 0,be=m.isSeparateSymbolSearchTabs?oe?.[le]||Xe:ee,ye=(0,s.useMemo)((()=>{if(!m.isSeparateSymbolSearchTabs)return H;return H.filter((e=>{const t=TAB_SOURCE_FILTER_MAP[le];if(!t)return!1;if(!le)return!0;const r=e.group();return r===ExchangeGroup.AllExchanges||r&&t.value.includes(r)}))}),[H,le]),[Se,xe]=(0,s.useState)((()=>{const e=Boolean(ee&&Ye.length>1&&!(0,m.exchangeSelectDisabled)(le)),t=ve?.[le];return{canChangeExchange:e,tabSelectFilters:t,withFilters:Boolean(e||t?.length),renderSymbolSearchList:[],token:J.current,symbolsRemaining:0,currentSymbolType:le,currentSelectedSearchSource:be,currentTabAvailableSearchSources:ye,symbolStartIndex:0}})),we=(0,s.useCallback)((e=>{trackEvent("New SS",le,"Change sources"),se?.(le,e),xe((t=>({...t,currentSelectedSearchSource:e})))}),[le,xe]),ke=(0,s.useRef)(e.input??null),[Ce,Ee]=(0,s.useState)(!1),Ie=(0,He.useForceUpdate)(),[Le,Te]=(0,s.useState)(new Set),{broker:Be=null,brokerId:Ne,unhideSymbolSearchGroups:Me="",displayBrokerSymbol:De=!1}={brokerId:void 0};(0,s.useLayoutEffect)((()=>{!ke?.current||!z&&Boolean(ke.current?.value)||(z||"compare"===Z||(ke.current.value=J.current),!N||z&&"symbolSearch"!==Z||ke.current.focus())}),[Z]),(0,s.useEffect)((()=>{ke?.current&&d&&N&&ke.current.select()}),[]);const Oe=(0,s.useMemo)((()=>Se.renderSymbolSearchList.reduce(((e,t)=>{const r=nt(t),n=Le.has(r);return e.push(t),n&&t.contracts&&e.push(...t.contracts.map((e=>({...e,parent:t})))),e}),[])),[Se.renderSymbolSearchList,Le]),Ae=(0,s.useRef)(null);(0,s.useEffect)((()=>{-1!==pe&&Ae.current?.scrollIntoView({block:"nearest"})}),[pe,Ae]);const Pe=b.includes(le),_e=(0,s.useMemo)((()=>Oe.map(((e,t)=>{if(te(e)){const r=nt(e),n=e.contracts?Le.has(r):void 0,o=t===pe,a=Se.renderSymbolSearchList.findIndex((t=>t.symbol===e.symbol&&t.exchange===e.exchange))+1;return{key:t,numberInList:a,id:r,title:rt(e,De),description:e.description,isOffset:!1,
|
||||
onClick:pt.bind(null,e,a),providerId:e.provider_id,source:e.source,source2:e.source2,country:e.country?.toLocaleLowerCase(),type:e.type,exchangeName:null===e.exchange?void 0:e.exchange,exchangeTooltip:"",prefix:e.prefix||void 0,marketType:(0,Qe.marketType)(e.type,e.typespecs,!1),hideMarketType:Pe,isEod:e.params?.includes("eod")&&"economic"!==e.type,isYield:(0,Ge.isYield)(e),isExpanded:n,onExpandClick:e.contracts?ht.bind(null,r):void 0,fullSymbolName:e.contracts?Ue.QualifiedSources.fromSymbolSearchResult(e,e.contracts[0]):Ue.QualifiedSources.fromSymbolSearchResult(e),itemRef:o?Ae:void 0,isSelected:t===pe,hideMarkedListFlag:i,item:e,logoId:e.logoid,currencyLogoId:e["currency-logoid"],baseCurrencyLogoId:e["base-currency-logoid"],shortName:(0,Ze.safeShortName)(Ue.QualifiedSources.fromSymbolSearchResult(e)),currencyCode:e.currency_code,isPrimary:e.is_primary_listing}}{const{parent:r}=e,n=nt(r),o=t===pe,a=Se.renderSymbolSearchList.findIndex((e=>e.symbol===r.symbol&&e.exchange===r.exchange))+1;return{key:t,numberInList:a,id:n+e.symbol,dangerousTitleHTML:rt(e,De),dangerousDescriptionHTML:`${r.description}`+(e.description?` (${e.description})`:""),isOffset:!0,isEod:e.params?.includes("eod"),isYield:(0,Ge.isYield)(e),onClick:gt.bind(null,e.parent,e,a),providerId:r.provider_id,country:r.country?.toLowerCase(),type:r.type,exchangeName:null===r.exchange?void 0:r.exchange,exchangeTooltip:"",marketType:(0,Qe.marketType)(r.type,e.typespecs,!1),hideMarketType:Pe,fullSymbolName:Ue.QualifiedSources.fromSymbolSearchResult(e.parent,e),itemRef:o?Ae:void 0,isSelected:o,hideMarkedListFlag:i,item:e}}}))),[Se.renderSymbolSearchList,Le,Z,pe,D]),Ve=(0,s.useMemo)((()=>function(e,t,r){const n=t?.[e],o=new Map(n?.map((e=>[e.id,e.urlParam]))),a=r[e];let s;if(a){s={};for(const[e,t]of Object.entries(a)){const r=o.get(e);r&&(s[r]=t)}}return s}(le,ve,ce)),[le,ve,ce]),et=(0,s.useMemo)((()=>Se.renderSymbolSearchList.slice(0,20).map((e=>e.contracts?Ue.QualifiedSources.fromSymbolSearchResult(e,e.contracts[0]):Ue.QualifiedSources.fromSymbolSearchResult(e)))),[Se.renderSymbolSearchList]);(0,s.useEffect)((()=>{if(!W)return;const e=["resetFilter","resetTabFilter","empty"].includes(ge)?[]:et,t={...Ve,result_list:e};if(t.search_type||(t.search_type="bitcoin,crypto"===le?"crypto":le),!m.isSeparateSymbolSearchTabs)return t.exchange=be?.getRequestCountryValue()??null,void W(t);if(le){const e=be?.getRequestCountryValue()??null;e&&(t.country=e);const r=be?.getRequestExchangeValue()??null;r&&(t.exchange=r)}W(t)}),[le,Ve,et,be,ge]);const lt=(0,s.useMemo)((()=>{if(A)return A}),[le,A,Ve,U]),it=k??at,ct=it!==at&&!z,ut=(e,r)=>({mode:Z,setMode:G,selectedSearchSource:be,setSelectedSearchSource:m.isSeparateSymbolSearchTabs?we:ne,isAllSearchSourcesSelected:B.isAllSearchSourcesSelected,allSearchSourcesTitle:m.isSeparateSymbolSearchTabs?TAB_SOURCE_FILTER_MAP[Se.currentSymbolType]?.allSearchSourcesTitle:void 0,selectedSymbolType:le,setSelectedSymbolType:ie,selectedIndex:pe,setSelectedIndex:he,onClose:t,setSymbolSearchContent:xe,symbolSearchContent:Se,searchRef:ke,
|
||||
cachedInputValue:J,searchSpreads:de,setSearchSpreads:me,handleListWidth:ft,isSmallWidth:Ce,feedItems:_e,isMobile:e,showSpreadActions:l,selectSearchOnInit:d,isTablet:r,selectedItem:Oe[pe],forceUpdate:Ie,placeholder:g,initialScreen:x,toggleExpand:ht,openedItems:Le,onSubmit:yt,onSearchComplete:p,footer:I,symbolTypes:K,contentItem:C,searchInput:R,emptyState:T,autofocus:N,upperCaseEnabled:Je,externalInput:z,handleKeyDown:ct?void 0:bt,customSearchSymbols:lt,searchSources:ye,filterDefinitions:ve,selectedFilterValues:ce,setSelectedFilterValues:ue,filterQueryParams:Ve,symbolSearchState:ge,setSymbolSearchState:fe,onEmptyResults:void 0,searchInitiationPoint:V}),dt=O??q,mt=w??"div";return s.createElement(mt,null,s.createElement(y.MatchMediaMap,{rules:S.DialogBreakpoints},(({TabletSmall:e,TabletNormal:n})=>s.createElement(E.SymbolSearchItemsDialogContext.Provider,{value:ut(e,n)},s.createElement(it,{..."exchange"===Z?{title:c.t(null,void 0,r(28628)),dataName:"exchanges-search",render:()=>s.createElement(dt,{searchSources:Se.currentTabAvailableSearchSources}),additionalHeaderElement:s.createElement(We.BackButton,{onClick:()=>G("symbolSearch"),className:je.backButton,size:"medium","aria-label":c.t(null,{context:"input"},r(41256)),preservePaddings:!0,flipIconOnRtl:(0,Re.isRtl)()}),additionalElementPos:"before"}:{title:h,dataName:"symbol-search-items-dialog",render:()=>s.createElement(Fe,null),additionalElementPos:"after"},shouldReturnFocus:F,fullScreen:v,onClose:t,onClickOutside:t,onKeyDown:ct?void 0:bt,isOpened:!0})))));function pt(e,t,r){if(e.contracts)return e.contracts.length?void gt(e,e.contracts[0],t,r):void ht(nt(e));gt(e,void 0,t,r)}function ht(e){const t=new Set(Le);t.has(e)?t.delete(e):t.add(e),Te(t)}function gt(e,r,n,o){const a=r||e,{exchange:s}=e;if(u.enabled("show_spread_operators")){const e={name:a.symbol,exchange:s,prefix:a.prefix,fullName:a.full_name};if(de)return vt(e),void Ie();if(ke.current&&ke.current.value.includes(","))return void vt(e)}St([{resolved:!0,symbol:Ue.QualifiedSources.fromSymbolSearchResult(e,r),result:a}],n,o),t()}function ft(e){Ee("fixed"===M||e<=640)}function vt(e){if(!ke.current)return;const[t,r]=f(ke.current,e,Je);ke.current.value=t,ke.current.setSelectionRange(r,r),ke.current.focus()}function bt(e){if(e.target&&e.target!==ke.current)return;const r=(0,ae.hashFromEvent)(e);switch(r){case 13:e.preventDefault(),yt(!0);break;case 27:if(e.preventDefault(),"exchange"===Z)return void G("symbolSearch");if("options"===Z)return G("symbolSearch"),$(null),void X(null);t()}switch((0,L.mapKeyCodeToDirection)(r)){case"blockPrev":if(e.preventDefault(),0===pe||"good"!==ge)return;if(-1===pe)return void he(0);he(pe-1);break;case"blockNext":if(e.preventDefault(),pe===_e.length-1||"good"!==ge)return;he(pe+1);break;case"inlinePrev":{if(-1===pe)return;const t=_e[pe],{id:r,isOffset:n,onExpandClick:o}=t;if(!n&&r&&Le.has(r)&&Boolean(o)&&!Boolean(D)&&(e.preventDefault(),ht(r)),o)return void D?.(e,!0);break}case"inlineNext":{if(-1===pe)return;const t=_e[pe],{id:r,isOffset:n,onExpandClick:o}=t
|
||||
;if(n||!r||Le.has(r)||!Boolean(o)||Boolean(D)||(e.preventDefault(),ht(r)),o)return void D?.(e,!0);break}}D?.(e)}function yt(e){if(!ke.current)return;let r=ke.current.value;if(u.enabled("show_spread_operators")&&de&&r){const n=_e[pe];if(n&&void 0!==n.isExpanded&&(n.onClick(),r=ke.current.value),r.includes(",")){return St(ot(r).map(tt),null),void(e&&t())}return St([{symbol:Je?r.toUpperCase():r,resolved:!1}],null),void(e&&t())}if(r.includes(","))return St(ot(r).map(tt),null),void(e&&t());if(-1!==pe){_e[pe].onClick()}else if(u.enabled("allow_arbitrary_symbol_search_input")){const n=Je?r.toUpperCase():r;if(n&&""!==n.trim()){const e=ot(n);if($e||void 0===Ne||-1!==n.indexOf(":")){St(e.map(tt),null)}else(function(e){let t=!1;return Promise.all(e.map((e=>-1!==e.indexOf(":")||t?Promise.resolve({symbol:e,resolved:!1}):(t=!0,async function(e){await(Be?.accountMetainfo());const t=void 0,r=await re({strictMatch:!0,serverHighlight:!1,text:e,lang:window.language||"",brokerId:Ne,onlyTradable:!0,unhideSymbolSearchGroups:Me,exchange:t});if(0!==r.symbols.length){const e=r.symbols[0],{contracts:t}=e,n=t&&t.length>0?t[0]:void 0,o=e.prefix||e.exchange,a=n?n.symbol:e.symbol;if(o&&a)return{symbol:Ue.QualifiedSources.fromSymbolSearchResult(e,n),resolved:!0,result:e}}return{symbol:e,resolved:!1}}(e)))))})(e).then((e=>St(e,null)))}e&&t()}else if("empty"!==ge&&_e.length>0){_e[0].onClick()}}async function St(e,t,r){const[{result:n,symbol:o,resolved:a}]=e,s=ke.current?.value,l=!r||(0,qe.isKeyboardClick)(r);let i=de;void 0!==n&&te(n)&&(i="spread"===n.type),p(e,{symbolType:le,isKeyboardEvent:l,numberInList:t,inputValue:s,isSpread:i})}}function tt(e){return{symbol:Je?e.toUpperCase():e,resolved:!1}}function rt(e,t){const{broker_symbol:r,symbol:n,description:o}=e;return`${"spread"===e.type?o:n}${t&&r?` (${r})`:""}`}function nt(e){return e.symbol+e.exchange+e.description}function ot(e){return e.split(",").map((e=>e.trim())).filter((e=>""!==e))}function at(e){const{isMobile:t,isTablet:r}=(0,O.useEnsuredContext)(E.SymbolSearchItemsDialogContext);return s.createElement(x.AdaptivePopupDialog,{...e,className:i()(je.dialog,!t&&(r?je.tabletDialog:je.desktopDialog)),backdrop:!0,draggable:!1})}function st(e,t){return null}},81319:(e,t,r)=>{"use strict";r.d(t,{createGroupColumns:()=>p,exchangeSelectDisabled:()=>m,getAllSymbolTypesValue:()=>d,getAvailableSearchSources:()=>c,getAvailableSymbolTypes:()=>u,getDefaultSearchSource:()=>i,getSymbolFullName:()=>l,isOptionDefaultValue:()=>g,isSeparateSymbolSearchTabs:()=>h});var n=r(11542),o=r(20882);class a{constructor(e){this._exchange=e}value(){return this._exchange.value}name(){return(0,o.isAllSearchSourcesSelected)(this)?n.t(null,void 0,r(34040)):this._exchange.name}description(){return this._exchange.desc}country(){return this._exchange.country}providerId(){return this._exchange.providerId}group(){return this._exchange.group}includes(e){return function(e,t){const r=t.toLowerCase(),{name:n,desc:o,searchTerms:a}=e
|
||||
;return n.toLowerCase().includes(r)||o.toLowerCase().includes(r)||void 0!==a&&a.some((e=>e.toLowerCase().includes(r)))}(this._exchange,e)}getRequestExchangeValue(){return this._exchange.value}getRequestCountryValue(){}}var s=r(3685);function l(e){if(e.fullName)return e.fullName;let t;return t=e.prefix||e.exchange?(e.prefix||e.exchange)+":"+e.name:e.name,t.replace(/<\/?[^>]+(>|$)/g,"")}function i(){const e=c();return e.find(o.isAllSearchSourcesSelected)||e[0]||null}function c(){return(0,o.createSearchSources)(a,(0,s.getExchanges)())}function u(){return window.ChartApiInstance.supportedSymbolsTypes()}function d(){return""}function m(e){return!!h&&!TAB_SOURCE_FILTER_MAP[e]}function p(e,t=2){if(0===e.length)return[];if(1===t)return[e];const r=Math.floor(e.length/2)+e.length%2;return[e.slice(0,r),e.slice(r)].filter((e=>e.length>0))}const h=!1;function g(e){return"string"!=typeof e}},82708:(e,t,r)=>{"use strict";r.d(t,{safeShortName:()=>o});var n=r(13665);function o(e){try{return(0,n.shortName)(e)}catch(t){return e}}},44254:(e,t,r)=>{"use strict";r.d(t,{factorOutBraces:()=>m,getTokenAtPos:()=>d,isBinaryOperator:()=>c,isSpread:()=>u,parseToken:()=>h,shortName:()=>p,symbolTokenEscapeRe:()=>a,tokenize:()=>i});var n,o=r(18429);!function(e){e.Symbol="symbol",e.IncompleteSymbol="incompleteSymbol",e.Number="number",e.IncompleteNumber="incompleteNumber",e.SeparatorPrefix="separatorPrefix",e.OpenBrace="openBrace",e.CloseBrace="closeBrace",e.Plus="plus",e.Minus="minus",e.Multiply="multiply",e.Divide="divide",e.Power="power",e.Whitespace="whitespace",e.Unparsed="unparsed"}(n||(n={}));const a=/[+\-/*]/,s={number:/\d+(?:\.\d*|(?![a-zA-Z0-9_!:.&]))|\.\d+/,incompleteNumber:/\./,symbol:/(?:[^-+\/*^\s]'|[a-zA-Z0-9_\u0370-\u1FFF_\u2E80-\uFFFF^])(?:[^-+\/*^\s]'|[a-zA-Z0-9_\u0020\u0370-\u1FFF_\u2E80-\uFFFF_!:.&])*|'.+?'/,incompleteSymbol:/'[^']*/,separatorPrefix:o.SEPARATOR_PREFIX,openBrace:"(",closeBrace:")",plus:"+",minus:"-",multiply:"*",divide:"/",power:"^",whitespace:/[\0-\x20\s]+/,unparsed:null},l=new RegExp(Object.values(s).map((e=>{return null===e?"":`(${"string"==typeof e?(t=e,t.replace(/[\^$()[\]{}*+?|\\]/g,"\\$&")):e.source})`;var t})).filter((e=>""!==e)).concat(".").join("|"),"g");function i(e){if(!e)return[];const t=[],r=Object.keys(s);let n;for(;n=l.exec(e);){let e=!1;for(let o=r.length;o--;)if(n[o+1]){r[o]&&t.push({value:n[o+1],type:r[o],precedence:0,offset:n.index}),e=!0;break}e||t.push({value:n[0],type:"unparsed",precedence:0,offset:n.index})}return t}function c(e){return"plus"===e||"minus"===e||"multiply"===e||"divide"===e||"power"===e}function u(e){return e.length>1&&e.some((e=>c(e.type)))}function d(e,t){for(let r=0;r<e.length;r++){const n=e[r],o="symbol"===n.type||"incompleteSymbol"===n.type||"number"===n.type;if(n.offset<=t&&t<=n.offset+n.value.length&&o)return n}return null}function m(e){e=function(e){const t=[];for(const r of e)"whitespace"!==r.type&&t.push(r);return t}(e);const t=[],r=[];let n;for(let o=0;o<e.length;o++){const a=e[o];switch(a.type){case"plus":case"minus":case"multiply":case"divide":case"power":
|
||||
r.length&&r[r.length-1].minPrecedence>a.precedence&&(r[r.length-1].minPrecedence=a.precedence);break;case"openBrace":n={minPrecedence:1/0,openBraceIndex:o},r.push(n);break;case"closeBrace":{if(n=r.pop(),!n)break;const a=e[n.openBraceIndex-1],s=e[o+1],l=a&&("plus"===a.type||"multiply"===a.type);(!c(s?.type)||s?.precedence<=n.minPrecedence)&&(!c(a?.type)||a?.precedence<n?.minPrecedence||a?.precedence===n?.minPrecedence&&l)&&(t.unshift(n.openBraceIndex),t.push(o),r.length&&r[r.length-1].minPrecedence>n.minPrecedence&&(r[r.length-1].minPrecedence=n.minPrecedence))}}}for(let r=t.length;r--;)e.splice(t[r],1);return e}function p(e){return m(i(e)).reduce(((e,t)=>{if("symbol"!==t.type)return e+t.value;const[,r]=h(t);return r?e+r:e}),"")}function h(e){const t=/^'?(?:([A-Z0-9_]+):)?(.*?)'?$/i.exec(e.value);return null===t?[void 0,void 0]:[t[1],t[2]]}},618:(e,t,r)=>{"use strict";r.d(t,{removeUsdFromCryptoPairLogos:()=>s,resolveLogoUrls:()=>a});var n=r(36279);const o=(0,n.getLogoUrlResolver)();function a(e,t=n.LogoSize.Medium){const r=e.logoid,a=e["base-currency-logoid"],s=e["currency-logoid"],l=r&&o.getSymbolLogoUrl(r,t);if(l)return[l];const i=a&&o.getSymbolLogoUrl(a,t),c=s&&o.getSymbolLogoUrl(s,t);return i&&c?[i,c]:i?[i]:c?[c]:[]}function s(e){return 2!==e.length?e:function(e){return e.some((e=>l(e)))}(e)&&!function(e){return e.some((e=>e.includes("country")&&!l(e)))}(e)?e.filter((e=>!l(e))):e}function l(e){return!1}},39330:(e,t,r)=>{"use strict";r.d(t,{getBlockStyleClasses:()=>l,getLogoStyleClasses:()=>i});var n=r(97754),o=r(52292),a=r(78217),s=r.n(a);function l(e,t){return n(s().pair,s()[e],t)}function i(e,t=2,r=!0){return n(s().logo,s()[e],s().skeleton,o.skeletonTheme.wrapper,!r&&s().empty,1===t&&n(o.skeletonTheme.animated))}},58492:(e,t,r)=>{"use strict";r.d(t,{getStyleClasses:()=>n.getStyleClasses});var n=r(53885)},97006:(e,t,r)=>{"use strict";r.d(t,{createRegExpList:()=>l,getHighlightedChars:()=>i,rankedSearch:()=>s});var n=r(37265);function o(e){return e.replace(/[!-/[-^{-}?]/g,"\\$&")}var a;function s(e){const{data:t,rules:r,queryString:o,isPreventedFromFiltering:a,primaryKey:s,secondaryKey:l=s,optionalPrimaryKey:i,tertiaryKey:c}=e;return t.map((e=>{const t=i&&e[i]?e[i]:e[s],a=e[l],u=c&&e[c];let d,m=0;return r.forEach((e=>{const{re:r,fullMatch:s}=e;if(r.lastIndex=0,(0,n.isString)(t)&&t&&t.toLowerCase()===o.toLowerCase())return m=4,void(d=t.match(s)?.index);if((0,n.isString)(t)&&s.test(t))return m=3,void(d=t.match(s)?.index);if((0,n.isString)(a)&&s.test(a))return m=2,void(d=a.match(s)?.index);if((0,n.isString)(a)&&r.test(a))return m=2,void(d=a.match(r)?.index);if(Array.isArray(u))for(const e of u)if(s.test(e))return m=1,void(d=e.match(s)?.index)})),{matchPriority:m,matchIndex:d,item:e}})).filter((e=>a||e.matchPriority)).sort(((e,t)=>{if(e.matchPriority<t.matchPriority)return 1;if(e.matchPriority>t.matchPriority)return-1;if(e.matchPriority===t.matchPriority){if(void 0===e.matchIndex||void 0===t.matchIndex)return 0;if(e.matchIndex>t.matchIndex)return 1;if(e.matchIndex<t.matchIndex)return-1}return 0})).map((({item:e})=>e))}
|
||||
function l(e,t){const r=[],n=e.toLowerCase(),a=e.split("").map(((e,t)=>`(${0!==t?`[/\\s-]${o(e)}`:o(e)})`)).join("(.*?)")+"(.*)";return r.push({fullMatch:new RegExp(`(${o(e)})`,"i"),re:new RegExp(`^${a}`,"i"),reserveRe:new RegExp(a,"i"),fuzzyHighlight:!0}),t&&t.hasOwnProperty(n)&&r.push({fullMatch:t[n],re:t[n],fuzzyHighlight:!1}),r}function i(e,t,r){const n=[];return e&&r?(r.forEach((e=>{const{fullMatch:r,re:o,reserveRe:a}=e;r.lastIndex=0,o.lastIndex=0;const s=r.exec(t),l=s||o.exec(t)||a&&a.exec(t);if(e.fuzzyHighlight=!s,l)if(e.fuzzyHighlight){let e=l.index;for(let t=1;t<l.length;t++){const r=l[t],o=l[t].length;if(t%2){const t=r.startsWith(" ")||r.startsWith("/")||r.startsWith("-");n[t?e+1:e]=!0}e+=o}}else for(let e=0;e<l[0].length;e++)n[l.index+e]=!0})),n):n}!function(e){e[e.Low=0]="Low",e[e.MediumLow=1]="MediumLow",e[e.Medium=2]="Medium",e[e.High=3]="High",e[e.Highest=4]="Highest"}(a||(a={}))},24637:(e,t,r)=>{"use strict";r.d(t,{HighlightedText:()=>l});var n=r(50959),o=r(97754),a=r(97006),s=r(95059);function l(e){const{queryString:t,rules:r,text:l,className:i}=e,c=(0,n.useMemo)((()=>(0,a.getHighlightedChars)(t,l,r)),[t,r,l]);return n.createElement(n.Fragment,null,c.length?l.split("").map(((e,t)=>n.createElement(n.Fragment,{key:t},c[t]?n.createElement("span",{className:o(s.highlighted,i)},e):n.createElement("span",null,e)))):l)}},78036:(e,t,r)=>{"use strict";r.d(t,{useEnsuredContext:()=>a});var n=r(50959),o=r(50151);function a(e){return(0,o.ensureNotNull)((0,n.useContext)(e))}},36947:(e,t,r)=>{"use strict";r.d(t,{useForceUpdate:()=>n.useForceUpdate});var n=r(125)},29006:(e,t,r)=>{"use strict";r.d(t,{useResizeObserver:()=>n.useResizeObserver});var n=r(67842)},77975:(e,t,r)=>{"use strict";r.d(t,{useWatchedValueReadonly:()=>o});var n=r(50959);const o=(e,t=!1,r=[])=>{const o="watchedValue"in e?e.watchedValue:void 0,a="defaultValue"in e?e.defaultValue:e.watchedValue.value(),[s,l]=(0,n.useState)(o?o.value():a);return(t?n.useLayoutEffect:n.useEffect)((()=>{if(o){l(o.value());const e=e=>l(e);return o.subscribe(e),()=>o.unsubscribe(e)}return()=>{}}),[o,...r]),s}},84877:(e,t,r)=>{"use strict";r.d(t,{MatchMediaMap:()=>s});var n=r(50959),o=r(66783),a=r.n(o);class s extends n.Component{constructor(e){super(e),this._handleMediaChange=()=>{const e=i(this.state.queries,((e,t)=>t.matches));let t=!1;for(const r in e)if(e.hasOwnProperty(r)&&this.state.matches[r]!==e[r]){t=!0;break}t&&this.setState({matches:e})};const{rules:t}=this.props;this.state=l(t)}shouldComponentUpdate(e,t){return!a()(e,this.props)||(!a()(t.rules,this.state.rules)||!a()(t.matches,this.state.matches))}componentDidMount(){this._migrate(null,this.state.queries)}componentDidUpdate(e,t){a()(e.rules,this.props.rules)||this._migrate(t.queries,this.state.queries)}componentWillUnmount(){this._migrate(this.state.queries,null)}render(){return this.props.children(this.state.matches)}static getDerivedStateFromProps(e,t){if(a()(e.rules,t.rules))return null;const{rules:r}=e;return l(r)}_migrate(e,t){null!==e&&i(e,((e,t)=>{t.removeEventListener("change",this._handleMediaChange)
|
||||
})),null!==t&&i(t,((e,t)=>{t.addEventListener("change",this._handleMediaChange)}))}}function l(e){const t=i(e,((e,t)=>window.matchMedia(t)));return{queries:t,matches:i(t,((e,t)=>t.matches)),rules:{...e}}}function i(e,t){const r={};for(const n in e)e.hasOwnProperty(n)&&(r[n]=t(n,e[n]));return r}},47308:(e,t,r)=>{"use strict";r.d(t,{RoundButtonTabs:()=>$});var n=r(50959),o=r(97754),a=r(11542),s=r(63273),l=r(47201),i=r(35020),c=r(86240),u=r(86781);var d=r(95854),m=r(36966),p=r(7953),h=r(38528),g=r(66686);r(34869);const f=n.createContext({children:{},setIsReady:()=>{}});function v(){return!function(){const[e,t]=(0,n.useState)(!0);return(0,n.useEffect)((()=>{t(!1)}),[]),e}()}var b=r(67842);function y(e,t,r){const{id:o,items:a,activationType:s,orientation:y,disabled:S,onActivate:x,isActive:w,overflowBehaviour:k,enableActiveStateStyles:C,tablistLabelId:E,tablistLabel:I,preventDefaultIfKeyboardActionHandled:R,stopPropagationIfKeyboardActionHandled:L,keyboardNavigationLoop:T,defaultKeyboardFocus:B,focusableItemAttributes:N}=t,M=(0,i.useMobileTouchState)(),D=function(e){const t=(0,u.useSafeMatchMedia)(c["media-mf-phone-landscape"],!0),r=(0,i.useMobileTouchState)();return e??(r||!t?"scroll":"collapse")}(k),O=(0,n.useRef)(!1),A=(0,n.useCallback)((e=>e.id),[]),P=C??!M,_=function(){const{setIsReady:e,children:t}=(0,n.useContext)(f),r=(0,n.useRef)((0,n.useId)());return t[r.current]||(t[r.current]={isReady:!1}),(0,n.useCallback)((()=>{t[r.current].isReady=!0,e(Object.values(t).every((e=>e.isReady)))}),[t,e])}(),{visibleItems:F,hiddenItems:W,containerRefCallback:Q,innerContainerRefCallback:U,moreButtonRef:V,setItemRef:K,itemsMeasurements:z}=(0,d.useCollapsible)(a,A,w),H=function(e){const t=(0,n.useRef)(null);return(0,n.useEffect)((()=>{t.current=e}),[e]),t.current}(z.current?.containerWidth)??0,Z=v(),G=z.current?.containerWidth??0;let q=!1;z.current&&Z&&(q=function(e,t,r,n,o){if("collapse"!==n)return!0;const a=function(e,t,r){const n=e.filter((e=>t.find((t=>t.id===e[0]))));return t.length>0?n[0][1]+r:0}(Array.from(e.widthsMap.entries()),t,o),s=e.moreButtonWidth??0;let l=function(e,t){return e.reduce(((e,r)=>e+(t.get(r.id)??0)),0)}(r,e.widthsMap);return l+=t.length>0?s:0,function(e,t,r,n){return 0!==e?t-r<e&&t-r>n:r<t}(a,e.containerWidth,l,o)}(z.current,W,F,D,r.gap??0)||0===G);const j=(0,b.useResizeObserver)((([e])=>{const t=Z&&0===H&&0===W.length;(q&&e.contentRect.width===H||t)&&_()})),$="collapse"===D?F:a,Y=(0,n.useMemo)((()=>"collapse"===D?W:[]),[D,W]),X=(0,n.useCallback)((e=>Y.includes(e)),[Y]),{isOpened:J,open:ee,close:te,onButtonClick:re}=(0,p.useDisclosure)({id:o,disabled:S}),{tabsBindings:ne,tablistBinding:oe,scrollWrapBinding:ae,onActivate:se,onHighlight:le,isHighlighted:ie}=(0,m.useTabs)({id:o,items:[...$,...Y],activationType:s,orientation:y,disabled:S,tablistLabelId:E,tablistLabel:I,preventDefaultIfKeyboardActionHandled:R,scrollIntoViewOptions:r.scrollIntoViewOptions,onActivate:x,isActive:w,isCollapsed:X,isRtl:r.isRtl,isDisclosureOpened:J,isRadioGroup:r.isRadioGroup,stopPropagationIfKeyboardActionHandled:L,
|
||||
keyboardNavigationLoop:T,defaultKeyboardFocus:B,focusableItemAttributes:N}),ce=Y.find(ie),ue=(0,n.useCallback)((()=>{const e=a.find(w);e&&le(e)}),[le,w,a]),de=(0,n.useCallback)((e=>ne.find((t=>t.id===e.id))),[ne]),me=(0,n.useCallback)((()=>{te(),ue(),O.current=!0}),[te,ue]),pe=(0,n.useCallback)((()=>{ce&&(se(ce),le(ce,250))}),[se,le,ce]);ae.ref=(0,h.useMergedRefs)([j,ae.ref,Q]),oe.ref=(0,h.useMergedRefs)([oe.ref,U]),oe.onKeyDown=(0,l.createSafeMulticastEventHandler)((0,g.useKeyboardEventHandler)([(0,g.useKeyboardClose)(J,me),(0,g.useKeyboardActionHandler)([13,32],pe,(0,n.useCallback)((()=>Boolean(ce)),[ce]))],R),oe.onKeyDown);const he=(0,n.useCallback)((e=>{O.current=!0,re(e)}),[O,re]),ge=(0,n.useCallback)((e=>{e&&se(e)}),[se]);return(0,n.useEffect)((()=>{O.current?O.current=!1:(ce&&!J&&ee(),!ce&&J&&te())}),[ce,J,ee,te]),{enableActiveStateStyles:P,moreButtonRef:V,setItemRef:K,getBindings:de,handleMoreButtonClick:he,handleCollapsedItemClick:ge,scrollWrapBinding:ae,overflowBehaviour:D,tablistBinding:oe,visibleTabs:$,hiddenTabs:Y,handleActivate:se,isMobileTouch:M,getItemId:A,isDisclosureOpened:J,isHighlighted:ie,closeDisclosure:te}}var S=r(8304),x=r(53017),w=r(17946),k=r(9745),C=r(2948),E=r(90854);const I="xsmall",R="primary";function L(e){const t=(0,n.useContext)(w.CustomBehaviourContext),{size:r="xsmall",variant:a="primary",active:s,fake:l,startIcon:i,endIcon:c,showCaret:u,iconOnly:d,anchor:m,enableActiveStateStyles:p=t.enableActiveStateStyles,disableFocusOutline:h=!1,tooltip:g}=e;return o(E.roundTabButton,E[r],E[a],i&&E.withStartIcon,(c||u)&&E.withEndIcon,d&&E.iconOnly,s&&E.selected,l&&E.fake,m&&E.enableCursorPointer,!p&&E.disableActiveStateStyles,h&&E.disableFocusOutline,g&&"apply-common-tooltip")}function T(e){const{startIcon:t,endIcon:r,showCaret:a,iconOnly:s,children:l}=e;return n.createElement(n.Fragment,null,t&&n.createElement(k.Icon,{icon:t,className:E.startIconWrap,"aria-hidden":!0}),l&&n.createElement("span",{className:o(E.content,s&&E.visuallyHidden)},l),(!s&&r||a)&&n.createElement(B,{icon:r,showCaret:a}))}function B(e){const{icon:t,showCaret:r}=e;return n.createElement(k.Icon,{className:o(E.endIconWrap,r&&E.caret),icon:r?C:t,"aria-hidden":!0})}const N=(0,n.forwardRef)(((e,t)=>{const{id:r,size:o,variant:a,active:s,fake:l,startIcon:i,endIcon:c,showCaret:u,iconOnly:d,children:m,enableActiveStateStyles:p,disableFocusOutline:h,tooltip:g,...f}=e;return n.createElement("button",{...f,id:r,ref:t,"data-tooltip":g,className:L({size:o,variant:a,active:s,fake:l,startIcon:i,endIcon:c,showCaret:u,iconOnly:d,enableActiveStateStyles:p,disableFocusOutline:h,tooltip:g})},n.createElement(T,{startIcon:i,endIcon:c,showCaret:u,iconOnly:d},m))}));N.displayName="RoundTabsBaseButton";const M=(0,n.createContext)({size:"small",variant:"primary",isHighlighted:!1,isCollapsed:!1,disabled:!1});function D(e){const{item:t,highlighted:r,handleItemRef:o,reference:a,onClick:s,"aria-disabled":l,...i}=e,c=(0,n.useCallback)((e=>{i.disabled&&e.preventDefault(),s&&s(t)}),[s,t,i.disabled]),u=(0,n.useCallback)((e=>{o&&o(t,e),(0,
|
||||
x.isomorphicRef)(a)(e)}),[t,o]),d={size:i.size??I,variant:i.variant??R,isHighlighted:Boolean(i.active),isCollapsed:!1,disabled:i.disabled??!1};return n.createElement(N,{...i,id:t.id,onClick:c,ref:u,startIcon:t.startIcon,endIcon:t.endIcon,tooltip:t.tooltip,"aria-label":"radio"===i.role?t.children:void 0},n.createElement(M.Provider,{value:d},t.children))}var O=r(16396),A=r(4523),P=r(16829),_=r(89882),F=r(2057),W=r(93524);function Q(e){const{disabled:t,isOpened:r,enableActiveStateStyles:o,disableFocusOutline:a,fake:s,items:l,buttonText:i,buttonPreset:c="text",buttonRef:u,size:d,variant:m,isAnchorTabs:p,isHighlighted:g,onButtonClick:f,onItemClick:v,onClose:b}=e,y=(0,n.useRef)(null),S=(0,h.useMergedRefs)([u,y]),x="text"===c?void 0:"xsmall"===d?_:F;return n.createElement(A.PopupMenuDisclosureView,{buttonRef:y,listboxTabIndex:-1,isOpened:r,onClose:b,listboxAria:{"aria-hidden":!0},button:n.createElement(N,{"aria-hidden":!0,disabled:t,active:r,onClick:f,ref:S,tabIndex:-1,size:d,variant:m,startIcon:x,showCaret:"text"===c,iconOnly:"meatballs"===c,enableActiveStateStyles:o,disableFocusOutline:a,fake:s},i),popupChildren:n.createElement(n.Fragment,null,"meatballs"===c&&n.createElement(P.ToolWidgetMenuSummary,null,i),l.map((e=>n.createElement(O.PopupMenuItem,{key:e.id,className:p?W.linkItem:void 0,onClick:v,onClickArg:e,isActive:g(e),label:n.createElement(U,{isHighlighted:g(e),size:d,variant:m,disabled:e.disabled},e.children),isDisabled:e.disabled,link:"href"in e?e.href:void 0,rel:"rel"in e?e.rel:void 0,target:"target"in e?e.target:void 0,icon:e.startIcon,toolbox:e.endIcon&&n.createElement(k.Icon,{icon:e.endIcon}),renderComponent:"renderComponent"in e?e.renderComponent:void 0,dontClosePopup:!0}))))})}function U(e){const{isHighlighted:t,size:r,variant:o,children:a,disabled:s}=e,l={size:r??I,variant:o??R,isHighlighted:t,isCollapsed:!0,disabled:s??!1};return n.createElement(M.Provider,{value:l},a)}var V,K,z,H,Z=r(76912);function G(e){const{overflowBehaviour:t}=e;return o(Z.scrollWrap,"scroll"===t&&Z.overflowScroll,"wrap"===t&&Z.overflowWrap)}function q(e){const{align:t="start"}=e;return o(Z.roundTabs,Z[t])}function j(e){const{children:t,disabled:l,moreButtonText:i=a.t(null,void 0,r(37117)),moreButtonPreset:c,className:u,size:d,variant:m,align:p,style:h={},"data-name":g,isRadioGroup:f,"aria-controls":v}=e,b=function(e="xsmall"){switch(e){case"small":return 8;case"xsmall":return 4;default:return 16}}(d),{enableActiveStateStyles:x,moreButtonRef:w,setItemRef:k,getBindings:C,handleMoreButtonClick:E,handleCollapsedItemClick:I,scrollWrapBinding:R,overflowBehaviour:L,tablistBinding:T,visibleTabs:B,hiddenTabs:N,handleActivate:M,isMobileTouch:O,getItemId:A,isDisclosureOpened:P,isHighlighted:_,closeDisclosure:F}=y(S.TabNames.RoundButtonTabs,e,{isRtl:s.isRtl,scrollIntoViewOptions:{additionalScroll:b},isRadioGroup:f,gap:b});return n.createElement("div",{...R,className:o(G({overflowBehaviour:L}),u),style:{...h,"--ui-lib-round-tabs-gap":`${b}px`},"data-name":g},n.createElement("div",{...T,className:q({align:p,overflowBehaviour:L})
|
||||
},B.map((e=>n.createElement(D,{...C(e),key:e.id,item:e,onClick:()=>M(e),variant:m,size:d,enableActiveStateStyles:x,disableFocusOutline:O,reference:k(A(e)),...e.dataId&&{"data-id":e.dataId},"aria-controls":v}))),N.map((e=>n.createElement(D,{...C(e),key:e.id,item:e,variant:m,size:d,reference:k(A(e)),"aria-controls":v,fake:!0}))),n.createElement(Q,{disabled:l,isOpened:P,items:N,buttonText:i,buttonPreset:c,buttonRef:w,isHighlighted:_,onButtonClick:E,onItemClick:I,onClose:F,variant:m,size:d,enableActiveStateStyles:x,disableFocusOutline:O,fake:0===N.length}),t))}function $(e){const{"data-name":t="round-tabs-buttons",...r}=e;return n.createElement(j,{...r,"data-name":t})}!function(e){e.Primary="primary",e.Ghost="ghost"}(V||(V={})),function(e){e.XSmall="xsmall",e.Small="small",e.Large="large"}(K||(K={})),function(e){e.Start="start",e.Center="center"}(z||(z={})),function(e){e.Text="text",e.Meatballs="meatballs"}(H||(H={}));r(21593)},63932:(e,t,r)=>{"use strict";r.d(t,{Spinner:()=>i});var n=r(50959),o=r(97754),a=r(58096),s=(r(15216),r(85862)),l=r.n(s);function i(e){const{ariaLabel:t,ariaLabelledby:r,className:s,style:i,size:c,id:u,disableSelfPositioning:d}=e;return n.createElement("div",{className:o(s,"tv-spinner","tv-spinner--shown",`tv-spinner--size_${a.spinnerSizeMap[c||a.DEFAULT_SIZE]}`,d&&l().disableSelfPositioning),style:i,role:"progressbar",id:u,"aria-label":t,"aria-labelledby":r})}},10381:(e,t,r)=>{"use strict";r.d(t,{ToolWidgetCaret:()=>i});var n=r(50959),o=r(97754),a=r(9745),s=r(49128),l=r(578);function i(e){const{dropped:t,className:r}=e;return n.createElement(a.Icon,{className:o(r,s.icon,{[s.dropped]:t}),icon:l})}},4237:(e,t,r)=>{"use strict";var n=r(32227);t.createRoot=n.createRoot,n.hydrateRoot},38576:e=>{e.exports={button:"button-GwQQdU8S",hover:"hover-GwQQdU8S",clicked:"clicked-GwQQdU8S",isInteractive:"isInteractive-GwQQdU8S",accessible:"accessible-GwQQdU8S",isGrouped:"isGrouped-GwQQdU8S",isActive:"isActive-GwQQdU8S",isOpened:"isOpened-GwQQdU8S",isDisabled:"isDisabled-GwQQdU8S",text:"text-GwQQdU8S",icon:"icon-GwQQdU8S",endIcon:"endIcon-GwQQdU8S"}},55973:e=>{e.exports={title:"title-u3QJgF_p"}},81348:(e,t,r)=>{"use strict";r.d(t,{DEFAULT_TOOL_WIDGET_BUTTON_THEME:()=>l,ToolWidgetButton:()=>i});var n=r(50959),o=r(97754),a=r(9745),s=r(38576);const l=s,i=n.forwardRef(((e,t)=>{const{tag:r="div",icon:l,endIcon:i,isActive:c,isOpened:u,isDisabled:d,isGrouped:m,isHovered:p,isClicked:h,onClick:g,text:f,textBeforeIcon:v,title:b,theme:y=s,className:S,forceInteractive:x,inactive:w,"data-name":k,"data-tooltip":C,...E}=e,I=o(S,y.button,(b||C)&&"apply-common-tooltip",{[y.isActive]:c,[y.isOpened]:u,[y.isInteractive]:(x||Boolean(g))&&!d&&!w,[y.isDisabled]:Boolean(d||w),[y.isGrouped]:m,[y.hover]:p,[y.clicked]:h}),R=l&&("string"==typeof l?n.createElement(a.Icon,{className:y.icon,icon:l}):n.cloneElement(l,{className:o(y.icon,l.props.className)}));return"button"===r?n.createElement("button",{...E,ref:t,type:"button",className:o(I,y.accessible),disabled:d&&!w,onClick:g,title:b,"data-name":k,"data-tooltip":C
|
||||
},v&&f&&n.createElement("div",{className:o("js-button-text",y.text)},f),R,!v&&f&&n.createElement("div",{className:o("js-button-text",y.text)},f)):n.createElement("div",{...E,ref:t,"data-role":"button",className:I,onClick:d?void 0:g,title:b,"data-name":k,"data-tooltip":C},v&&f&&n.createElement("div",{className:o("js-button-text",y.text)},f),R,!v&&f&&n.createElement("div",{className:o("js-button-text",y.text)},f),i&&n.createElement(a.Icon,{icon:i,className:s.endIcon}))}))},16829:(e,t,r)=>{"use strict";r.d(t,{ToolWidgetMenuSummary:()=>s});var n=r(50959),o=r(97754),a=r(55973);function s(e){return n.createElement("div",{className:o(e.className,a.title)},e.children)}},74395:(e,t,r)=>{"use strict";r.d(t,{VISIBLE_TYPESPECS:()=>s,marketType:()=>l});var n=r(11542);const o=new Map([["cfd",n.t(null,void 0,r(79599))],["dr",n.t(null,void 0,r(47268))],["index",n.t(null,void 0,r(87464))],["forex",n.t(null,void 0,r(17770))],["right",n.t(null,{context:"symbol_type"},r(53174))],["bond",n.t(null,void 0,r(42358))],["bitcoin",n.t(null,void 0,r(46128))],["crypto",n.t(null,void 0,r(46128))],["economic",n.t(null,void 0,r(54094))],["indices",n.t(null,void 0,r(90250))],["futures",n.t(null,void 0,r(4723))],["stock",n.t(null,void 0,r(76752))],["commodity",n.t(null,void 0,r(70932))]]);r(21251);const a=new Map,s=new Set(["cfd","spreadbet","defi","yield","government","corporate","mutual","money","etf","unit","trust","reit","etn","convertible","closedend","crypto","oracle"]);function l(e,t=[],r=!0){const n=t.filter((e=>s.has(e))),l=`${e}_${n.sort().join("_")}`,i=a.get(l);if(void 0!==i)return i;const c=r?function(e){return o.get(e)||e}(e):e,u=Boolean(t.length)?[c,...n].join(" "):c;return a.set(l,u),u}},52019:e=>{e.exports='<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 18 18" width="18" height="18"><path fill="currentColor" d="M13.35 5.35a.5.5 0 0 0-.7-.7L9 8.29 5.35 4.65a.5.5 0 1 0-.7.7L8.29 9l-3.64 3.65a.5.5 0 0 0 .7.7L9 9.71l3.65 3.64a.5.5 0 0 0 .7-.7L9.71 9l3.64-3.65z"/></svg>'},89882:e=>{e.exports='<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 18 18" width="18" height="18"><path fill="currentColor" d="M5 9a2 2 0 1 1-4 0 2 2 0 0 1 4 0zm6 0a2 2 0 1 1-4 0 2 2 0 0 1 4 0zm4 2a2 2 0 1 0 0-4 2 2 0 0 0 0 4z"/></svg>'},2057:e=>{e.exports='<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 28 28" width="28" height="28"><path fill="currentColor" d="M9 14a3 3 0 1 1-6 0 3 3 0 0 1 6 0zm8 0a3 3 0 1 1-6 0 3 3 0 0 1 6 0zm5 3a3 3 0 1 0 0-6 3 3 0 0 0 0 6z"/></svg>'},95694:e=>{e.exports='<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24" fill="none"><path stroke="currentColor" stroke-linecap="round" stroke-width="1.2" d="M17 22.5 6.85 12.35a.5.5 0 0 1 0-.7L17 1.5"/></svg>'},49498: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" stroke-linecap="round" stroke-width="1.2" d="M12 16.5 4.85 9.35a.5.5 0 0 1 0-.7L12 1.5"/></svg>'},60176:e=>{
|
||||
e.exports='<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 14 14" width="14" height="14" fill="none"><path stroke="currentColor" stroke-linecap="round" stroke-width="1.2" d="M9.5 12.5 3.9 7.37a.5.5 0 0 1 0-.74L9.5 1.5"/></svg>'},35369:e=>{e.exports='<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 12 12" width="12" height="12" fill="none"><path stroke="currentColor" stroke-linecap="round" stroke-width="1.2" d="M8 10.5 3.85 6.35a.5.5 0 0 1 0-.7L8 1.5"/></svg>'},58478:e=>{e.exports='<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 10 10" width="10" height="10" fill="none"><path stroke="currentColor" stroke-linecap="round" stroke-width="1.2" d="M7 8.5 3.85 5.35a.5.5 0 0 1 0-.7L7 1.5"/></svg>'},73063:e=>{e.exports='<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24" fill="none"><path stroke="currentColor" stroke-linecap="round" stroke-width="1.5" d="M17 22.5 6.85 12.35a.5.5 0 0 1 0-.7L17 1.5"/></svg>'},14127: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" stroke-linecap="round" stroke-width="1.5" d="M12 16.5 4.85 9.35a.5.5 0 0 1 0-.7L12 1.5"/></svg>'},18073:e=>{e.exports='<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 14 14" width="14" height="14" fill="none"><path stroke="currentColor" stroke-linecap="round" stroke-width="1.5" d="M9.5 12.5 3.9 7.37a.5.5 0 0 1 0-.74L9.5 1.5"/></svg>'},99243:e=>{e.exports='<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 12 12" width="12" height="12" fill="none"><path stroke="currentColor" stroke-linecap="round" stroke-width="1.5" d="M8 10.5 3.85 6.35a.5.5 0 0 1 0-.7L8 1.5"/></svg>'},42576:e=>{e.exports='<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 10 10" width="10" height="10" fill="none"><path stroke="currentColor" stroke-linecap="round" stroke-width="1.5" d="M7 8.5 3.85 5.35a.5.5 0 0 1 0-.7L7 1.5"/></svg>'},578:e=>{e.exports='<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 8" width="16" height="8"><path fill="currentColor" d="M0 1.475l7.396 6.04.596.485.593-.49L16 1.39 14.807 0 7.393 6.122 8.58 6.12 1.186.08z"/></svg>'},91540: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="M2.5 14.5c1.68-1.26 3.7-2 6.5-2s4.91.74 6.5 2m-13-11c1.68 1.26 3.7 2 6.5 2s4.91-.74 6.5-2"/><circle stroke="currentColor" cx="9" cy="9" r="8.5"/><path stroke="currentColor" d="M13.5 9c0 2.42-.55 4.58-1.4 6.12-.87 1.56-1.98 2.38-3.1 2.38s-2.23-.82-3.1-2.38c-.85-1.54-1.4-3.7-1.4-6.12s.55-4.58 1.4-6.12C6.77 1.32 7.88.5 9 .5s2.23.82 3.1 2.38c.85 1.54 1.4 3.7 1.4 6.12z"/></svg>'},66619:e=>{
|
||||
e.exports='<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 120 120" width="120" height="120"><path fill="#B2B5BE" fill-rule="evenodd" d="M23 39a36 36 0 0 1 72 0v13.15l15.1 8.44 2.16 1.2-1.64 1.86-12.85 14.59 3.73 4.03L98.57 85 95 81.13V117H77v-12H67v9H50V95H40v22H23V81.28l-3.8 3.61-2.76-2.9 4.05-3.84-12.77-14.5-1.64-1.86 2.16-1.2L23 52.34V39Zm72 36.33 10.98-12.46L95 56.73v18.6ZM23 56.92v18.03L12.35 62.87 23 56.92ZM59 7a32 32 0 0 0-32 32v74h9V91h18v19h9v-9h18v12h10V39A32 32 0 0 0 59 7Zm-7 36a3 3 0 1 1-6 0 3 3 0 0 1 6 0Zm19 3a3 3 0 1 0 0-6 3 3 0 0 0 0 6Z"/></svg>'},67562:e=>{e.exports='<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 120 120" width="120" height="120"><path fill="#131722" fill-rule="evenodd" d="M23 39a36 36 0 0 1 72 0v13.15l15.1 8.44 2.16 1.2-1.64 1.86-12.85 14.59 3.73 4.03L98.57 85 95 81.13V117H77v-12H67v9H50V95H40v22H23V81.28l-3.8 3.61-2.76-2.9 4.05-3.84-12.77-14.5-1.64-1.86 2.16-1.2L23 52.34V39Zm72 36.33 10.98-12.46L95 56.73v18.6ZM23 56.92v18.03L12.35 62.87 23 56.92ZM59 7a32 32 0 0 0-32 32v74h9V91h18v19h9v-9h18v12h10V39A32 32 0 0 0 59 7Zm-7 36a3 3 0 1 1-6 0 3 3 0 0 1 6 0Zm19 3a3 3 0 1 0 0-6 3 3 0 0 0 0 6Z"/></svg>'},69533:e=>{e.exports='<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" fill="none"><path stroke="currentColor" d="M8 5l3.5 3.5L8 12"/></svg>'},486:e=>{e.exports='<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 13 13" width="13" height="13"><path fill="none" stroke="currentColor" stroke-linecap="square" d="M2.5 6.5h9"/><circle fill="currentColor" cx="7" cy="3" r="1"/><circle fill="currentColor" cx="7" cy="10" r="1"/></svg>'},63861:e=>{e.exports='<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 13 13" width="13" height="13"><g fill="none" fill-rule="evenodd" stroke="currentColor"><path stroke-linecap="square" stroke-linejoin="round" d="M3.5 10V2.5L1 5"/><path stroke-linecap="square" d="M1.5 10.5h4"/><path d="M8 12l3-11"/></g></svg>'},81574:e=>{e.exports='<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 13 13" width="13" height="13"><path fill="none" stroke="currentColor" stroke-linecap="square" d="M2.5 6.5h8"/></svg>'},32617:e=>{e.exports='<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 13 13" width="13" height="13"><path fill="none" stroke="currentColor" stroke-linecap="square" d="M3 10l7-7M3 3l7 7"/></svg>'},35119:e=>{e.exports='<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 13 13" width="13" height="13"><path fill="none" stroke="currentColor" stroke-linecap="square" d="M2.5 6.5h8m-4-4v8"/></svg>'},69135:e=>{e.exports='<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 13 13" width="13" height="13"><path fill="none" stroke="currentColor" stroke-linecap="square" d="M3 7l3.5-3.5L10 7"/></svg>'},54313: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="M18.5 12.5a6 6 0 1 1-12 0 6 6 0 0 1 12 0Zm-1.25 5.8a7.5 7.5 0 1 1 1.06-1.06l4.22 4.23.53.53L22 23.06l-.53-.53-4.22-4.22Z"/></svg>'},6347:e=>{
|
||||
e.exports='<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 28 28" width="28" height="28" fill="none"><path stroke="currentColor" d="M17.4 17.5a7 7 0 1 0-4.9 2c1.9 0 3.64-.76 4.9-2zm0 0l5.1 5"/></svg>'}}]);
|
||||
@@ -0,0 +1 @@
|
||||
.scrollable-vwgPOHG8{flex:1 1 auto;min-height:145px;overflow-x:hidden;overflow-y:auto;-webkit-overflow-scrolling:touch}@media (max-height:290px){.scrollable-vwgPOHG8{min-height:auto}}@supports (-moz-appearance:none){.scrollable-vwgPOHG8{scrollbar-color:var(--themed-color-scroll-bg,#9c9c9c) #0000;scrollbar-width:thin}html.theme-dark .scrollable-vwgPOHG8{scrollbar-color:var(--themed-color-scroll-bg,#3d3d3d) #0000}}.scrollable-vwgPOHG8::-webkit-scrollbar{height:5px;width:5px}.scrollable-vwgPOHG8::-webkit-scrollbar-thumb{background-clip:content-box;background-color:var(--tv-color-scrollbar-thumb-background,var(--themed-color-scroll-bg,#9c9c9c));border:1px solid #0000;border-radius:3px}html.theme-dark .scrollable-vwgPOHG8::-webkit-scrollbar-thumb{background-color:var(--tv-color-scrollbar-thumb-background,var(--themed-color-scroll-bg,#3d3d3d))}.scrollable-vwgPOHG8::-webkit-scrollbar-track{background-color:initial;border-radius:3px}.scrollable-vwgPOHG8::-webkit-scrollbar-corner{display:none}.tabs-vwgPOHG8{--ui-lib-underline-tabs-hor-padding:20px;padding:0 var(--ui-lib-underline-tabs-hor-padding)}.smallStyleControl-l5f4IL9k{margin-left:8px;width:34px}.smallStyleControl-l5f4IL9k:first-child{margin-left:0}.additionalSelect-l5f4IL9k{margin-left:8px}.childRowContainer-l5f4IL9k{cursor:default;margin-left:26px}.defaultSelect-l5f4IL9k{cursor:default;width:100px}.defaultSelectItem-l5f4IL9k{box-sizing:border-box;min-width:100px}.block-l5f4IL9k{display:flex}@media (max-width:379px){.block-l5f4IL9k{display:block}}.group-l5f4IL9k{display:flex}@media (max-width:379px){.wrapGroup-l5f4IL9k{margin-left:0;margin-top:8px}}.textMarkGraphicBlock-l5f4IL9k{display:flex}@media (max-width:550px){.textMarkGraphicBlock-l5f4IL9k{display:block}}.textMarkGraphicWrapGroup-l5f4IL9k{display:flex}@media (max-width:550px){.textMarkGraphicWrapGroup-l5f4IL9k{margin-left:0;margin-top:8px}}.transparency-l5f4IL9k{height:16px}.color-l5f4IL9k:not(:first-child){margin-left:8px}
|
||||
@@ -0,0 +1 @@
|
||||
.scrollable-vwgPOHG8{flex:1 1 auto;min-height:145px;overflow-x:hidden;overflow-y:auto;-webkit-overflow-scrolling:touch}@media (max-height:290px){.scrollable-vwgPOHG8{min-height:auto}}@supports (-moz-appearance:none){.scrollable-vwgPOHG8{scrollbar-color:var(--themed-color-scroll-bg,#9c9c9c) #0000;scrollbar-width:thin}html.theme-dark .scrollable-vwgPOHG8{scrollbar-color:var(--themed-color-scroll-bg,#3d3d3d) #0000}}.scrollable-vwgPOHG8::-webkit-scrollbar{height:5px;width:5px}.scrollable-vwgPOHG8::-webkit-scrollbar-thumb{background-clip:content-box;background-color:var(--tv-color-scrollbar-thumb-background,var(--themed-color-scroll-bg,#9c9c9c));border:1px solid #0000;border-radius:3px}html.theme-dark .scrollable-vwgPOHG8::-webkit-scrollbar-thumb{background-color:var(--tv-color-scrollbar-thumb-background,var(--themed-color-scroll-bg,#3d3d3d))}.scrollable-vwgPOHG8::-webkit-scrollbar-track{background-color:initial;border-radius:3px}.scrollable-vwgPOHG8::-webkit-scrollbar-corner{display:none}.tabs-vwgPOHG8{--ui-lib-underline-tabs-hor-padding:20px;padding:0 var(--ui-lib-underline-tabs-hor-padding)}.smallStyleControl-l5f4IL9k{margin-right:8px;width:34px}.smallStyleControl-l5f4IL9k:first-child{margin-right:0}.additionalSelect-l5f4IL9k{margin-right:8px}.childRowContainer-l5f4IL9k{cursor:default;margin-right:26px}.defaultSelect-l5f4IL9k{cursor:default;width:100px}.defaultSelectItem-l5f4IL9k{box-sizing:border-box;min-width:100px}.block-l5f4IL9k{display:flex}@media (max-width:379px){.block-l5f4IL9k{display:block}}.group-l5f4IL9k{display:flex}@media (max-width:379px){.wrapGroup-l5f4IL9k{margin-right:0;margin-top:8px}}.textMarkGraphicBlock-l5f4IL9k{display:flex}@media (max-width:550px){.textMarkGraphicBlock-l5f4IL9k{display:block}}.textMarkGraphicWrapGroup-l5f4IL9k{display:flex}@media (max-width:550px){.textMarkGraphicWrapGroup-l5f4IL9k{margin-right:0;margin-top:8px}}.transparency-l5f4IL9k{height:16px}.color-l5f4IL9k:not(:first-child){margin-right:8px}
|
||||
@@ -0,0 +1,10 @@
|
||||
(self.webpackChunktradingview=self.webpackChunktradingview||[]).push([[3202],{56057:e=>{e.exports={logo:"logo-PsAlMQQF",hidden:"hidden-PsAlMQQF",xxceptionallysmalldonotusebrv1023:"xxceptionallysmalldonotusebrv1023-PsAlMQQF",xxxsmall:"xxxsmall-PsAlMQQF",xxsmall:"xxsmall-PsAlMQQF",xsmall:"xsmall-PsAlMQQF",small:"small-PsAlMQQF",medium:"medium-PsAlMQQF",large:"large-PsAlMQQF",xlarge:"xlarge-PsAlMQQF",xxlarge:"xxlarge-PsAlMQQF",xxxlarge:"xxxlarge-PsAlMQQF",skeleton:"skeleton-PsAlMQQF",letter:"letter-PsAlMQQF"}},55679:e=>{e.exports={wrapper:"wrapper-TJ9ObuLF",animated:"animated-TJ9ObuLF",pulsation:"pulsation-TJ9ObuLF"}},96108:e=>{e.exports={"tablet-normal-breakpoint":"(max-width: 768px)","small-height-breakpoint":"(max-height: 360px)","tablet-small-breakpoint":"(max-width: 440px)"}},9059:e=>{e.exports={"tablet-small-breakpoint":"(max-width: 440px)",item:"item-jFqVJoPk",hovered:"hovered-jFqVJoPk",isDisabled:"isDisabled-jFqVJoPk",isActive:"isActive-jFqVJoPk",shortcut:"shortcut-jFqVJoPk",toolbox:"toolbox-jFqVJoPk",withIcon:"withIcon-jFqVJoPk","round-icon":"round-icon-jFqVJoPk",icon:"icon-jFqVJoPk",labelRow:"labelRow-jFqVJoPk",label:"label-jFqVJoPk",showOnHover:"showOnHover-jFqVJoPk","disclosure-item-circle-logo":"disclosure-item-circle-logo-jFqVJoPk",showOnFocus:"showOnFocus-jFqVJoPk"}},53885:(e,t,n)=>{"use strict";n.d(t,{getStyleClasses:()=>s,isCircleLogoWithUrlProps:()=>a});var o=n(97754),r=n(52292),i=n(56057),l=n.n(i);function s(e,t=2,n){return o(l().logo,l()[e],n,0===t||1===t?o(r.skeletonTheme.wrapper,l().skeleton):l().letter,1===t&&r.skeletonTheme.animated)}function a(e){return"logoUrl"in e&&null!==e.logoUrl&&void 0!==e.logoUrl&&0!==e.logoUrl.length}},86332:(e,t,n)=>{"use strict";n.d(t,{ControlGroupContext:()=>o});const o=n(50959).createContext({isGrouped:!1,cellState:{isTop:!0,isRight:!0,isBottom:!0,isLeft:!0}})},17946:(e,t,n)=>{"use strict";n.d(t,{CustomBehaviourContext:()=>o});const o=(0,n(50959).createContext)({enableActiveStateStyles:!0});o.displayName="CustomBehaviourContext"},95854:(e,t,n)=>{"use strict";var o;n.d(t,{useCollapsible:()=>f}),function(e){e.StartFirst="start-first",e.EndFirst="end-first"}(o||(o={}));var r=n(50959),i=n(67842),l=n(56073),s=n(78869),a=n(43010),c=n(53017);function u(e){const{itemsList:t,getItemId:n,calcVisibleAndHiddenItems:o,shouldKeepItemVisible:u,onMeasureCallback:f,forceUpdate:h=!1}=e,[b,m]=(0,s.useRefsMap)(),p=(0,r.useRef)(null),g=(0,r.useRef)({widthsMap:new Map,containerWidth:0,moreButtonWidth:0}),[v,x]=(0,r.useState)({visible:t,hidden:[]}),C=(0,r.useMemo)((()=>t.reduce(((e,t,n)=>(u(t)&&e.push(n),e)),[])),[t,u]),k=(0,r.useCallback)((()=>{if(g.current.containerWidth){const e=o(g.current,C);(function(e,t){return!d(e.visible,t.visible)||!d(e.hidden,t.hidden)})(v,e)&&x(e)}}),[g,x,v,C,o]),E=(0,r.useCallback)((()=>{g.current.moreButtonWidth=p.current?(0,l.outerWidth)(p.current,!0):0;const e=new Map(g.current.widthsMap);for(const o of t){const t=n(o),r=b.current.get(t);if(r){const n=(0,l.outerWidth)(r,!0);e.set(t,n)}}g.current.widthsMap=e,f&&f()}),[g,t,n,b,f]),M=(0,r.useRef)(null),w=(0,
|
||||
r.useCallback)((([e])=>{e.contentRect.width!==g.current.containerWidth&&(M.current&&cancelAnimationFrame(M.current),g.current.containerWidth=e.contentRect.width,M.current=requestAnimationFrame((()=>{k()})))}),[g,k]),y=(0,r.useRef)(null),R=(0,r.useCallback)((([e])=>{y.current&&cancelAnimationFrame(y.current),E(),y.current=requestAnimationFrame((()=>{k()}))}),[E,k]),S=(0,i.useResizeObserver)(R),I=(0,i.useResizeObserver)(w),F=(0,r.useRef)(null),A=(0,c.mergeRefs)([I,F]),O=(0,r.useRef)(t),P=(0,r.useRef)(!0),T=(0,r.useRef)([]);return(0,a.useIsomorphicLayoutEffect)((()=>{!h&&!P.current&&d(O.current,t)&&d(C,T.current)||(k(),P.current=!1,O.current=t,T.current=C)}),[t,k,C,h]),{containerRefCallback:A,moreButtonRef:p,innerContainerRefCallback:S,itemsRefs:b,setItemRef:m,hiddenItems:v.hidden,visibleItems:v.visible,itemsMeasurements:g}}function d(e,t){return e.length===t.length&&e.reduce(((e,n,o)=>e&&n===t[o]),!0)}function f(e,t,n,i=o.EndFirst){const l=(0,r.useCallback)(((n,r)=>{const l=e.map((e=>n.widthsMap.get(t(e))??0));return function({items:e,containerWidth:t,elementsWidths:n,menuItemWidth:r,keepVisible:i,direction:l}){const s=[...e],a=[],c=[];let u=0;for(const e of n)u+=e;if(u<=t)return{visible:s,hidden:c};const d=[...n];if(u=i.map((e=>d[e])).reduce(((e,t)=>e+t),0)+r,l===o.EndFirst)for(let e=0;e<s.length;e++)i.includes(e)?a.push(s[e]):(u+=d[e],u<=t?a.push(s[e]):c.push(s[e]));else for(let e=s.length-1;e>=0;e--)i.includes(e)?a.unshift(s[e]):(u+=d[e],u<=t?a.unshift(s[e]):c.unshift(s[e]));return{visible:a,hidden:c}}({items:e,containerWidth:n.containerWidth,elementsWidths:l,menuItemWidth:n.moreButtonWidth,keepVisible:r,direction:i})}),[e]);return u({itemsList:e,getItemId:t,calcVisibleAndHiddenItems:l,shouldKeepItemVisible:n})}},66686:(e,t,n)=>{"use strict";n.d(t,{useComposedKeyboardActionHandlers:()=>s,useKeyboardActionHandler:()=>l,useKeyboardClose:()=>u,useKeyboardEventHandler:()=>a,useKeyboardOpen:()=>d,useKeyboardToggle:()=>c});var o=n(50959),r=n(3343);const i=()=>!0;function l(e,t,n=i,r){return(0,o.useCallback)((o=>{if(r){if("horizontal"===r&&(40===o||38===o))return;if("vertical"===r&&(37===o||39===o))return}const i=e.map((e=>"function"==typeof e?e():e));return!(!n(o)||!i.includes(o))&&(t(o),!0)}),[...e,t,n])}function s(...e){return(0,o.useCallback)((t=>{for(const n of e)if(n(t))return!0;return!1}),[...e])}function a(e,t=!0,n=!1){const i=s(...e);return(0,o.useCallback)((e=>{const o=i((0,r.hashFromEvent)(e));o&&t&&e.preventDefault(),o&&n&&e.stopPropagation()}),[i])}function c(e,t=!0){return l([13,32],e,(function(e){if(13===e)return t;return!0}))}function u(e,t){return l([9,(0,o.useCallback)((()=>r.Modifiers.Shift+9),[]),27],t,(0,o.useCallback)((()=>e),[e]))}function d(e,t){return l([40,38],t,(0,o.useCallback)((()=>!e),[e]))}},7953:(e,t,n)=>{"use strict";n.d(t,{useDisclosure:()=>c});var o=n(50959),r=n(50151),i=n(54717),l=n(29202),s=n(47201),a=n(22064);function c(e){const{id:t,listboxId:n,disabled:c,buttonTabIndex:u=0,onFocus:d,onBlur:f,onClick:h}=e,[b,m]=(0,o.useState)(!1),[p,g]=(0,l.useFocus)(),v=p||b,x=n??void 0!==t?(0,
|
||||
a.createDomId)(t,"listbox"):void 0,C=(0,o.useRef)(null),k=(0,o.useCallback)((e=>C.current?.focus(e)),[C]),E=(0,o.useRef)(null),M=(0,o.useCallback)((()=>(0,r.ensureNotNull)(E.current).focus()),[E]),w=(0,o.useCallback)((()=>m(!0)),[m]),y=(0,o.useCallback)(((e=!1,t=!1)=>{m(!1);const{activeElement:n}=document;n&&(0,i.isTextEditingField)(n)||t||k({preventScroll:e})}),[m,k]),R=(0,o.useCallback)((()=>{b?y():w()}),[b,y,w]),S=c?[]:[d,g.onFocus],I=c?[]:[f,g.onBlur],F=c?[]:[h,R],A=(0,s.createSafeMulticastEventHandler)(...S),O=(0,s.createSafeMulticastEventHandler)(...I),P=(0,s.createSafeMulticastEventHandler)(...F);return{listboxId:x,isOpened:b,isFocused:v,buttonTabIndex:c?-1:u,listboxTabIndex:-1,open:w,close:y,toggle:R,onOpen:M,buttonFocusBindings:{onFocus:A,onBlur:O},onButtonClick:P,buttonRef:C,listboxRef:E,buttonAria:{"aria-controls":b?x:void 0,"aria-expanded":b,"aria-disabled":c}}}},29202:(e,t,n)=>{"use strict";n.d(t,{useFocus:()=>r});var o=n(50959);function r(e,t){const[n,r]=(0,o.useState)(!1);(0,o.useEffect)((()=>{t&&n&&r(!1)}),[t,n]);const i={onFocus:(0,o.useCallback)((function(t){void 0!==e&&e.current!==t.target||r(!0)}),[e]),onBlur:(0,o.useCallback)((function(t){void 0!==e&&e.current!==t.target||r(!1)}),[e])};return[n,i]}},39416:(e,t,n)=>{"use strict";n.d(t,{useFunctionalRefObject:()=>i});var o=n(50959),r=n(43010);function i(e){const t=(0,o.useMemo)((()=>function(e){const t=n=>{e(n),t.current=n};return t.current=null,t}((e=>{s.current(e)}))),[]),n=(0,o.useRef)(null),i=t=>{if(null===t)return l(n.current,t),void(n.current=null);n.current!==e&&(n.current=e,l(n.current,t))},s=(0,o.useRef)(i);return s.current=i,(0,r.useIsomorphicLayoutEffect)((()=>{if(null!==t.current)return s.current(t.current),()=>s.current(null)}),[e]),t}function l(e,t){null!==e&&("function"==typeof e?e(t):e.current=t)}},36762:(e,t,n)=>{"use strict";n.d(t,{useItemsKeyboardNavigation:()=>a});var o,r=n(50959),i=n(66686);function l(e,t){return e>=0?e%t:(t-Math.abs(e)%t)%t}!function(e){e.Next="next",e.Previous="previous",e.First="first",e.Last="last"}(o||(o={}));const s=e=>({next:[40,()=>e()?37:39],previous:[38,()=>e()?39:37],first:[33,()=>e()?35:36],last:[34,()=>e()?36:35]});function a(e,t,n,o,a,c,u={},d,f){const h=(0,r.useCallback)((e=>{const t=n.findIndex(o);if(t===n.length-1&&!c)return void(d?.onFailNext&&d.onFailNext(e));const r=l(t+1,n.length);a&&a(n[r],"next")}),[n,o,a,c]),b=(0,r.useCallback)((e=>{const t=n.findIndex(o);if(0===t&&!c)return void(d?.onFailPrev&&d.onFailPrev(e));const r=l(t-1,n.length);a&&a(n[r],"previous")}),[n,o,a,c]),m=(0,r.useCallback)((()=>{a&&a(n[0],"first")}),[a,n]),p=(0,r.useCallback)((()=>{a&&a(n[n.length-1],"last")}),[a,n]),g=(0,r.useMemo)((()=>s(t)),[t]),{next:v=g.next,previous:x=g.previous,first:C=g.first,last:k=g.last}=u;return(0,i.useComposedKeyboardActionHandlers)((0,i.useKeyboardActionHandler)(v,h,f?.next??(()=>!0),e),(0,i.useKeyboardActionHandler)(x,b,f?.previous??(()=>!0),e),(0,i.useKeyboardActionHandler)(C,m,(()=>!0),e),(0,i.useKeyboardActionHandler)(k,p,(()=>!0),e))}},16921:(e,t,n)=>{"use strict";n.d(t,{
|
||||
useKeepActiveItemIntoView:()=>d});var o=n(50959),r=n(50151),i=n(74991);const l={duration:200,additionalScroll:0},s={vertical:{scrollSize:"scrollHeight",clientSize:"clientHeight",start:"top",end:"bottom",size:"height"},horizontal:{scrollSize:"scrollWidth",clientSize:"clientWidth",start:"left",end:"right",size:"width"}};function a(e,t){const n=s[e];return t[n.scrollSize]>t[n.clientSize]}function c(e,t,n,o,r,l){const a=function(e,t,n,o=0){const r=s[e];return{start:-1*o,middle:-1*(Math.floor(n[r.size]/2)-Math.floor(t[r.size]/2)),end:-1*(n[r.size]-t[r.size])+o}}(e,o,r,l.additionalScroll);let c=0;if(l.snapToMiddle||function(e,t,n){const o=s[e];return t[o.start]<n[o.start]-n[o.size]/2||t[o.end]>n[o.end]+n[o.size]/2}(e,o,r))c=a.middle;else{const t=function(e,t,n,o=0){const r=s[e],i=t[r.start]+Math.floor(t[r.size]/2),l=n[r.start]+Math.floor(n[r.size]/2);return{start:t[r.start]-n[r.start]-o,middle:i-l,end:t[r.end]-n[r.end]+o}}(e,o,r,l.additionalScroll),n=function(e){const{start:t,middle:n,end:o}=e,r=new Map([[Math.abs(t),{key:"start",value:Math.sign(t)}],[Math.abs(n),{key:"middle",value:Math.sign(n)}],[Math.abs(o),{key:"end",value:Math.sign(o)}]]),i=Math.min(...r.keys());return r.get(i)}(t);c=void 0!==n?a[n.key]:0}return l.align&&(c=a[l.align]),function(e){const{additionalScroll:t=0,duration:n=i.dur,func:o=i.easingFunc.easeInOutCubic,onScrollEnd:r,target:l,wrap:s,direction:a="vertical"}=e;let{targetRect:c,wrapRect:u}=e;c=c??l.getBoundingClientRect(),u=u??s.getBoundingClientRect();const d=("vertical"===a?c.top-u.top:c.left-u.left)+t,f="vertical"===a?"scrollTop":"scrollLeft",h=s?s[f]:0;let b,m=0;return m=window.requestAnimationFrame((function e(t){let i;if(b?i=t-b:(i=0,b=t),i>=n)return s[f]=h+d,void(r&&r());const l=h+d*o(i/n);s[f]=Math.floor(l),m=window.requestAnimationFrame(e)})),function(){window.cancelAnimationFrame(m),r&&r()}}({...l,target:t,targetRect:o,wrap:n,wrapRect:r,additionalScroll:c,direction:e})}class u{constructor(e=null){this._container=null,this._lastScrolledElement=null,this._stopVerticalScroll=null,this._stopHorizontalScroll=null,this._container=e}scrollTo(e,t=l){if(null!==this._container&&null!==e&&!function(e,t,n=0){const o=e.getBoundingClientRect(),r=t.getBoundingClientRect();return o.top-r.top>=0&&r.bottom-o.bottom>=0&&o.left-r.left>=n&&r.right-o.right>=n}(e,this._container,t.visibilityDetectionOffsetInline)){const n=e.getBoundingClientRect(),o=this._container.getBoundingClientRect();this.stopScroll(),a("vertical",this._container)&&(this._stopVerticalScroll=c("vertical",e,this._container,n,o,this._modifyOptions("vertical",t))),a("horizontal",this._container)&&(this._stopHorizontalScroll=c("horizontal",e,this._container,n,o,this._modifyOptions("horizontal",t)))}this._lastScrolledElement=e}scrollToLastElement(e){this.scrollTo(this._lastScrolledElement,e)}stopScroll(){null!==this._stopVerticalScroll&&this._stopVerticalScroll(),null!==this._stopHorizontalScroll&&this._stopHorizontalScroll()}getContainer(){return this._container}setContainer(e){this._container=e,
|
||||
this._container?.contains(this._lastScrolledElement)||(this._lastScrolledElement=null)}destroy(){this.stopScroll(),this._container=null,this._lastScrolledElement=null}_handleScrollEnd(e){"vertical"===e?this._stopVerticalScroll=null:this._stopHorizontalScroll=null}_modifyOptions(e,t){return Object.assign({},t,{onScrollEnd:()=>{this._handleScrollEnd(e),void 0!==t.onScrollEnd&&t.onScrollEnd()}})}}function d(e={}){const{activeItem:t,getKey:n,...i}=e,l=(0,o.useRef)(null),s=(0,o.useRef)(new Map),a=function(e){const t=(0,o.useRef)(null);return(0,o.useEffect)((()=>(t.current=new u(e),()=>(0,r.ensureNotNull)(t.current).destroy())),[]),t}(l.current),c=(0,o.useCallback)((()=>{null!==a.current&&null!==l.current&&a.current.getContainer()!==l.current&&a.current.setContainer(l.current)}),[a,l]),d=(0,o.useCallback)((e=>{l.current=e}),[l]),f=(0,o.useCallback)(((e,t)=>{const o=n?n(e):e;t?s.current.set(o,t):s.current.delete(o)}),[s,n]),h=(0,o.useCallback)(((e,t)=>{if(!e)return;const o=n?n(e):e,i=s.current.get(o);i&&(c(),(0,r.ensureNotNull)(a.current).scrollTo(i,t))}),[s,a,n]);return(0,o.useEffect)((()=>h(t,i)),[h,t]),[d,f,h]}},86781:(e,t,n)=>{"use strict";n.d(t,{useMatchMedia:()=>i,useSafeMatchMedia:()=>r});var o=n(50959);function r(e,t=!1){const[n,r]=(0,o.useState)(t);return(0,o.useEffect)((()=>{const t=window.matchMedia(e);function n(){r(t.matches)}return n(),t.addEventListener("change",n),()=>{t.removeEventListener("change",n)}}),[e]),n}function i(e){const t=(0,o.useMemo)((()=>window.matchMedia(e).matches),[]);return r(e,t)}},38528:(e,t,n)=>{"use strict";n.d(t,{useMergedRefs:()=>i});var o=n(50959),r=n(53017);function i(e){return(0,o.useCallback)((0,r.mergeRefs)(e),e)}},35020:(e,t,n)=>{"use strict";n.d(t,{useMobileTouchState:()=>i});var o=n(50959),r=n(75774);function i(){const[e,t]=(0,o.useState)(!1);return(0,o.useEffect)((()=>{t(r.mobiletouch)}),[]),e}},27267:(e,t,n)=>{"use strict";function o(e,t,n,o,r){function i(r){if(e>r.timeStamp)return;const i=r.target;void 0!==n&&null!==t&&null!==i&&i.ownerDocument===o&&(t.contains(i)||n(r))}return r.click&&o.addEventListener("click",i,!1),r.mouseDown&&o.addEventListener("mousedown",i,!1),r.touchEnd&&o.addEventListener("touchend",i,!1),r.touchStart&&o.addEventListener("touchstart",i,!1),()=>{o.removeEventListener("click",i,!1),o.removeEventListener("mousedown",i,!1),o.removeEventListener("touchend",i,!1),o.removeEventListener("touchstart",i,!1)}}n.d(t,{addOutsideEventListener:()=>o})},78869:(e,t,n)=>{"use strict";n.d(t,{useRefsMap:()=>r});var o=n(50959);function r(){const e=(0,o.useRef)(new Map),t=(0,o.useCallback)((t=>n=>{null!==n?e.current.set(t,n):e.current.delete(t)}),[e]);return[e,t]}},67842:(e,t,n)=>{"use strict";n.d(t,{useResizeObserver:()=>l});var o=n(50959),r=n(43010),i=n(39416);function l(e,t=[]){const{callback:n,ref:l=null}=function(e){return"function"==typeof e?{callback:e}:e}(e),s=(0,o.useRef)(null),a=(0,o.useRef)(n);a.current=n;const c=(0,i.useFunctionalRefObject)(l),u=(0,o.useCallback)((e=>{c(e),null!==s.current&&(s.current.disconnect(),null!==e&&s.current.observe(e))}),[c,s])
|
||||
;return(0,r.useIsomorphicLayoutEffect)((()=>(s.current=new ResizeObserver(((e,t)=>{a.current(e,t)})),c.current&&u(c.current),()=>{s.current?.disconnect()})),[c,...t]),u}},36966:(e,t,n)=>{"use strict";n.d(t,{useTabs:()=>p});var o=n(50959),r=n(8304),i=n(47201),l=n(29202),s=n(16921),a=n(50151),c=n(66686),u=n(36762);function d(){return!1}function f(e,t){return{next:()=>t!==e.length-1,previous:()=>0!==t}}function h(e){const{activationType:t="manual"}=e,n=(0,o.useMemo)((()=>t),[]);return(0,a.assert)(t===n,"Activation type must be invariant."),"automatic"===t?function(e){const{isRtl:t,items:n,preventDefaultIfHandled:r=!0,stopPropagationIfHandled:i=!1,loop:l=!0,isHighlighted:s,onHighlight:a,onActivate:h,isCollapsed:b=d,orientation:m}=e,p=(0,o.useCallback)((e=>{a(e),b(e)||h(e)}),[a,h,b]),g=!l&&i?f(n,n.findIndex(s)):void 0;return(0,c.useKeyboardEventHandler)([(0,u.useItemsKeyboardNavigation)(m,t,n,s,p,l,{},void 0,g)],r,i)}(e):function(e){const{isRtl:t,items:n,preventDefaultIfHandled:r=!0,stopPropagationIfHandled:i=!1,loop:l=!0,isHighlighted:s,onHighlight:a,onActivate:d,orientation:h}=e,b=n.findIndex(s),m=n[b],p=(0,o.useCallback)((()=>{void 0!==m&&d(m)}),[m,d]),g=!l&&i?f(n,b):void 0,v=(0,o.useCallback)((e=>a(e)),[a]),x=(0,u.useItemsKeyboardNavigation)(h,t,n,s,v,l,{},void 0,g),C=(0,c.useKeyboardActionHandler)([13,32],p);return(0,c.useKeyboardEventHandler)([x,C],r,i)}(e)}var b=n(35020);const m=24;function p(e){const{id:t,items:n,orientation:a,activationType:c="manual",disabled:u,tablistLabelId:d,tablistLabel:f,focusOnHighlight:p=!0,preventDefaultIfKeyboardActionHandled:g=!0,stopPropagationIfKeyboardActionHandled:v=!1,keyboardNavigationLoop:x=!0,scrollIntoViewOptions:C,isActive:k,onActivate:E,isCollapsed:M,isRtl:w,isDisclosureOpened:y,isRadioGroup:R,defaultKeyboardFocus:S,focusableItemAttributes:I={}}=e,F=(0,b.useMobileTouchState)(),A=y?null:a||"horizontal",O=(0,o.useRef)(e.itemsRefs?.current??new Map),[P,T]=(0,o.useState)(),[H,L]=(0,l.useFocus)(),N=n.find(k),_=(0,o.useCallback)((e=>!u&&!e.disabled&&e===P),[u,P]),z=(0,o.useCallback)((e=>{const t=O.current.get(e);p&&void 0!==t&&t!==document.activeElement&&t.focus()}),[p]),B=(0,o.useRef)(),W=(0,o.useCallback)(((e,t)=>{u||e.disabled||(T(e),"number"==typeof t?(clearTimeout(B.current),B.current=setTimeout((()=>z(e)),t)):z(e))}),[u,T,z,y]),D=(0,o.useCallback)((e=>{u||e.disabled||(E(e),_(e)||W(e))}),[u,E,_,W]),K=h({isRtl:w,items:(0,o.useMemo)((()=>n.filter((e=>!u&&!e.disabled))),[n,u]),activationType:c,preventDefaultIfHandled:g,stopPropagationIfHandled:v,loop:x,onActivate:D,isHighlighted:_,onHighlight:W,isCollapsed:M,orientation:A}),V=(0,o.useCallback)((e=>{let t=null;for(const[n,o]of O.current.entries())if(e.target===o){t=n;break}t&&!_(t)&&("automatic"===c&&M&&!M(t)?D(t):W(t))}),[c,_,W,D,M]);(0,o.useEffect)((()=>{F||void 0!==N&&T(N)}),[N,F]),(0,o.useEffect)((()=>{H||T(void 0)}),[H]),(0,o.useEffect)((()=>()=>clearTimeout(B.current)),[]);const Q=C?.additionalScroll??0,[j,q]=(0,s.useKeepActiveItemIntoView)({...C,visibilityDetectionOffsetInline:Q+m,snapToMiddle:!0,activeItem:P??N,getKey:(0,
|
||||
o.useCallback)((e=>e.id),[])}),J=(0,o.useCallback)(((e,t)=>{q(e,t),null!==t?O.current.set(e,t):O.current.delete(e)}),[q]),{firstEdgeItemIndex:U,lastEdgeItemIndex:G}=(0,r.findEdgesTab)(n,M);return{tabsBindings:n.map(((e,t)=>{const n=_(e),o=k(e),i=e.disabled??u??!1,l=1===S?H?n:t===U||t===G:!i&&(H?n:o);return{...(0,r.getTabAttributes)(e.id,l,o,e.tabpanelId,i,R,"",I),highlighted:n,active:o,handleItemRef:J}})),tablistBinding:{...(0,r.getTabListAttributes)(t,a,u,d,f,R),onBlur:L.onBlur,onFocus:(0,i.createSafeMulticastEventHandler)(L.onFocus,V),onKeyDown:K},scrollWrapBinding:{ref:j},onActivate:D,onHighlight:W,isHighlighted:_}}},52292:(e,t,n)=>{"use strict";n.d(t,{skeletonTheme:()=>r});var o=n(55679);const r=o},8304:(e,t,n)=>{"use strict";function o(e,t="horizontal",n,o,r,i){return{id:e,role:i?"radiogroup":"tablist","aria-orientation":t,"aria-label":r,"aria-labelledby":o,"aria-disabled":n}}function r(e,t,n,o,r,i,l,s){return{id:e,role:i?"radio":"tab",tabIndex:t?s?.tabIndex??0:-1,disabled:r,"aria-selected":i?void 0:n,"aria-checked":i?n:void 0,"aria-controls":o,"aria-disabled":r,"aria-label":l,"data-focus-manager":void 0!==s?s["data-focus-manager"]:void 0}}function i(e,t){let n,o;for(let r=0;r<e.length;r++){const i=e.length-(r+1),l=void 0!==t&&t(e[i]);if(!e[r].disabled&&void 0===n&&(n=r),!e[i].disabled&&!l&&void 0===o&&(o=i),void 0!==n&&void 0!==o)break}return{firstEdgeItemIndex:n,lastEdgeItemIndex:o}}var l,s,a,c,u;n.d(t,{TabNames:()=>u,findEdgesTab:()=>i,getTabAttributes:()=>r,getTabListAttributes:()=>o}),function(e){e[e.Active=0]="Active",e[e.Edges=1]="Edges"}(l||(l={})),function(e){e.Horizontal="horizontal",e.Vertical="vertical"}(s||(s={})),function(e){e.Automatic="automatic",e.Manual="manual"}(a||(a={})),function(e){e.Collapse="collapse",e.Scroll="scroll",e.Wrap="wrap",e.None="none"}(c||(c={})),function(e){e.SquareButtonTabs="square-button-tabs",e.UnderlineButtonTabs="underline-button-tabs",e.UnderlineAnchorTabs="underline-anchor-tabs",e.RoundAnchorTabs="round-anchor-tabs",e.RoundButtonTabs="round-button-tabs",e.LightButtonTabs="light-button-tabs"}(u||(u={}))},90186:(e,t,n)=>{"use strict";function o(e){return i(e,l)}function r(e){return i(e,s)}function i(e,t){const n=Object.entries(e).filter(t),o={};for(const[e,t]of n)o[e]=t;return o}function l(e){const[t,n]=e;return 0===t.indexOf("data-")&&"string"==typeof n}function s(e){return 0===e[0].indexOf("aria-")}n.d(t,{filterAriaProps:()=>r,filterDataProps:()=>o,filterProps:()=>i,isAriaAttribute:()=>s,isDataAttribute:()=>l})},22064:(e,t,n)=>{"use strict";n.d(t,{createDomId:()=>f,joinDomIds:()=>h});const o="id",r=/\s/g,i="-",l="_",s=" ";function a(e){return"string"==typeof e}function c(e){switch(typeof e){case"string":return e;case"number":case"bigint":return e.toString(10);case"boolean":case"symbol":return e.toString();default:return null}}function u(e){return e.trim().length>0}function d(e){return e.replace(r,i)}function f(...e){const t=e.map(c).filter(a).filter(u).map(d);return(t.length>0&&t[0].startsWith(o+l)?t:[o,...t]).join(l)}function h(...e){
|
||||
return e.map(c).filter(a).filter(u).join(s)}},56073:(e,t,n)=>{"use strict";function o(e,t=!1){const n=getComputedStyle(e),o=[n.height];return"border-box"!==n.boxSizing&&o.push(n.paddingTop,n.paddingBottom,n.borderTopWidth,n.borderBottomWidth),t&&o.push(n.marginTop,n.marginBottom),o.reduce(((e,t)=>e+(parseFloat(t)||0)),0)}function r(e,t=!1){const n=getComputedStyle(e),o=[n.width];return"border-box"!==n.boxSizing&&o.push(n.paddingLeft,n.paddingRight,n.borderLeftWidth,n.borderRightWidth),t&&o.push(n.marginLeft,n.marginRight),o.reduce(((e,t)=>e+(parseFloat(t)||0)),0)}n.d(t,{outerHeight:()=>o,outerWidth:()=>r})},47201:(e,t,n)=>{"use strict";function o(...e){return t=>{for(const n of e)void 0!==n&&n(t)}}n.d(t,{createSafeMulticastEventHandler:()=>o})},87896:(e,t,n)=>{"use strict";n.d(t,{createReactRoot:()=>d});var o=n(50959),r=n(32227),i=n(4237);const l=(0,o.createContext)({isOnMobileAppPage:()=>!1,isRtl:!1,locale:"en"});var s=n(84015),a=n(63273);const c={iOs:"old",android:"new",old:"old",new:"new",any:"any"};function u(e){const[t]=(0,o.useState)({isOnMobileAppPage:e=>(0,s.isOnMobileAppPage)(c[e]),isRtl:(0,a.isRtl)(),locale:window.locale});return o.createElement(l.Provider,{value:t},e.children)}function d(e,t,n="legacy"){const l=o.createElement(u,null,e);if("modern"===n){const e=(0,i.createRoot)(t);return e.render(l),{render(t){e.render(o.createElement(u,null,t))},unmount(){e.unmount()}}}return r.render(l,t),{render(e){r.render(o.createElement(u,null,e),t)},unmount(){r.unmountComponentAtNode(t)}}}},24437:(e,t,n)=>{"use strict";n.d(t,{DialogBreakpoints:()=>r});var o=n(96108);const r={SmallHeight:o["small-height-breakpoint"],TabletSmall:o["tablet-small-breakpoint"],TabletNormal:o["tablet-normal-breakpoint"]}},59695:(e,t,n)=>{"use strict";n.d(t,{CircleLogo:()=>s,hiddenCircleLogoClass:()=>l});var o=n(50959),r=n(53885),i=n(56057);const l=n.n(i)().hidden;function s(e){const t=(0,r.isCircleLogoWithUrlProps)(e),[n,i]=(0,o.useState)(0),l=(0,o.useRef)(null),s=(0,r.getStyleClasses)(e.size,n,e.className),a=e.alt??e.title??"",c=t?a[0]:e.placeholderLetter;return(0,o.useEffect)((()=>i(l.current?.complete??!t?2:1)),[t]),t&&3!==n?o.createElement("img",{ref:l,className:s,crossOrigin:"",src:e.logoUrl,alt:a,title:e.title,loading:e.loading,onLoad:()=>i(2),onError:()=>i(3),"aria-label":e["aria-label"],"aria-hidden":e["aria-hidden"]}):o.createElement("span",{className:s,title:e.title,"aria-label":e["aria-label"],"aria-hidden":e["aria-hidden"]},c)}},4523:(e,t,n)=>{"use strict";n.d(t,{PopupMenuDisclosureView:()=>u});var o=n(50959),r=n(20520),i=n(50151);const l={x:0,y:0};function s(e,t,n){return(0,o.useCallback)((()=>function(e,t,{x:n=l.x,y:o=l.y}=l){const r=(0,i.ensureNotNull)(e).getBoundingClientRect(),s={x:r.left+n,y:r.top+r.height+o,indentFromWindow:{top:4,bottom:4,left:4,right:4}};return t&&(s.overrideWidth=r.width),s}(e.current,t,n)),[e,t])}var a=n(86240);const c=parseInt(a["size-header-height"]);function u(e){
|
||||
const{button:t,popupChildren:n,buttonRef:i,listboxId:l,listboxClassName:a,listboxTabIndex:u,matchButtonAndListboxWidths:d,isOpened:f,scrollWrapReference:h,listboxReference:b,onClose:m,onOpen:p,onListboxFocus:g,onListboxBlur:v,onListboxKeyDown:x,listboxAria:C,repositionOnScroll:k=!0,closeOnHeaderOverlap:E=!1,popupPositionCorrection:M={x:0,y:0},popupPosition:w}=e,y=s(i,d,M),R=E?c:0;return o.createElement(o.Fragment,null,t,o.createElement(r.PopupMenu,{...C,id:l,className:a,tabIndex:u,isOpened:f,position:w||y,repositionOnScroll:k,onClose:m,onOpen:p,doNotCloseOn:i.current,reference:b,scrollWrapReference:h,onFocus:g,onBlur:v,onKeyDown:x,closeOnScrollOutsideOffset:R},n))}},16396:(e,t,n)=>{"use strict";n.d(t,{DEFAULT_POPUP_MENU_ITEM_THEME:()=>u,PopupMenuItem:()=>f});var o=n(50959),r=n(97754),i=n(51768),l=n(59064),s=n(59695),a=n(76460),c=n(9059);const u=c;function d(e){e.stopPropagation()}function f(e){const{id:t,role:n,className:u,title:f,labelRowClassName:h,labelClassName:b,toolboxClassName:m,shortcut:p,forceShowShortcuts:g,icon:v,iconClassname:x,isActive:C,isDisabled:k,isHovered:E,appearAsDisabled:M,label:w,link:y,showToolboxOnHover:R,showToolboxOnFocus:S,target:I,rel:F,toolbox:A,toolboxRole:O,reference:P,onMouseOut:T,onMouseOver:H,onKeyDown:L,suppressToolboxClick:N=!0,theme:_=c,tabIndex:z,tagName:B,renderComponent:W,roundedIcon:D,iconAriaProps:K,circleLogo:V,dontClosePopup:Q,onClick:j,onClickArg:q,trackEventObject:J,trackMouseWheelClick:U,trackRightClick:G,...$}=e,Z=(0,o.useRef)(null),X=(0,o.useMemo)((()=>function(e){function t(t){const{reference:n,...r}=t,i=e??(r.href?"a":"div"),l="a"===i?r:function(e){const{download:t,href:n,hrefLang:o,media:r,ping:i,rel:l,target:s,type:a,referrerPolicy:c,...u}=e;return u}(r);return o.createElement(i,{...l,ref:n})}return t.displayName=`DefaultComponent(${e})`,t}(B)),[B]),Y=W??X;return o.createElement(Y,{...$,id:t,role:n,className:r(u,_.item,v&&_.withIcon,{[_.isActive]:C,[_.isDisabled]:k||M,[_.hovered]:E}),title:f,href:y,target:I,rel:F,reference:function(e){Z.current=e,"function"==typeof P&&P(e);"object"==typeof P&&(P.current=e)},onClick:function(e){if(k)return;J&&(0,i.trackEvent)(J.category,J.event,J.label);j&&j(q,e);Q||(e.currentTarget.dispatchEvent(new CustomEvent("popup-menu-close-event",{bubbles:!0,detail:{clickType:(0,a.isKeyboardClick)(e)?"keyboard":"mouse"}})),(0,l.globalCloseMenu)())},onContextMenu:function(e){J&&G&&(0,i.trackEvent)(J.category,J.event,`${J.label}_rightClick`)},onMouseUp:function(e){if(1===e.button&&y&&J){let e=J.label;U&&(e+="_mouseWheelClick"),(0,i.trackEvent)(J.category,J.event,e)}},onMouseOver:H,onMouseOut:T,onKeyDown:L,tabIndex:z},V&&o.createElement(s.CircleLogo,{...K,className:c["disclosure-item-circle-logo"],size:"xxxsmall",logoUrl:V.logoUrl,placeholderLetter:"placeholderLetter"in V?V.placeholderLetter:void 0}),v&&o.createElement("span",{"aria-label":K&&K["aria-label"],"aria-hidden":K&&Boolean(K["aria-hidden"]),className:r(_.icon,D&&c["round-icon"],x),dangerouslySetInnerHTML:{__html:v}}),o.createElement("span",{className:r(_.labelRow,h)
|
||||
},o.createElement("span",{className:r(_.label,b)},w)),(void 0!==p||g)&&o.createElement("span",{className:_.shortcut},(ee=p)&&ee.split("+").join(" + ")),void 0!==A&&o.createElement("span",{role:O,onClick:N?d:void 0,className:r(m,_.toolbox,{[_.showOnHover]:R,[_.showOnFocus]:S})},A));var ee}},20520:(e,t,n)=>{"use strict";n.d(t,{PopupMenu:()=>f});var o=n(50959),r=n(32227),i=n(88987),l=n(42842),s=n(27317),a=n(29197);const c=o.createContext(void 0);var u=n(36383);const d=o.createContext({setMenuMaxWidth:!1});function f(e){const{controller:t,children:n,isOpened:f,closeOnClickOutside:h=!0,doNotCloseOn:b,onClickOutside:m,onClose:p,onKeyboardClose:g,"data-name":v="popup-menu-container",...x}=e,C=(0,o.useContext)(a.CloseDelegateContext),k=o.useContext(d),E=(0,o.useContext)(c),M=(0,u.useOutsideEvent)({handler:function(e){m&&m(e);if(!h)return;const t=(0,i.default)(b)?b():null==b?[]:[b];if(t.length>0&&e.target instanceof Node)for(const n of t){const t=r.findDOMNode(n);if(t instanceof Node&&t.contains(e.target))return}p()},mouseDown:!0,touchStart:!0});return f?o.createElement(l.Portal,{top:"0",left:"0",right:"0",bottom:"0",pointerEvents:"none"},o.createElement("span",{ref:M,style:{pointerEvents:"auto"}},o.createElement(s.Menu,{...x,onClose:p,onKeyboardClose:g,onScroll:function(t){const{onScroll:n}=e;n&&n(t)},customCloseDelegate:C,customRemeasureDelegate:E,ref:t,"data-name":v,limitMaxWidth:k.setMenuMaxWidth,"data-tooltip-show-on-focus":"true"},n))):null}},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>'},86240:e=>{"use strict";e.exports=JSON.parse('{"size-header-height":"64px","media-phone-vertical":"all and (max-width: 479px)","media-mf-phone-landscape":"all and (min-width: 568px)"}')}}]);
|
||||
@@ -0,0 +1 @@
|
||||
.separator-QjUlCDId{background-color:var(--tv-color-popup-element-divider-background,var(--themed-color-popup-menu-separator,#ebebeb));flex-shrink:0;height:1px;margin:6px 0}html.theme-dark .separator-QjUlCDId{background-color:var(--tv-color-popup-element-divider-background,var(--themed-color-popup-menu-separator,#4a4a4a))}.small-QjUlCDId{margin-bottom:4px;margin-top:4px}.normal-QjUlCDId{margin-bottom:6px;margin-top:6px}.large-QjUlCDId{margin-bottom:8px;margin-top:8px}
|
||||
@@ -0,0 +1 @@
|
||||
.separator-QjUlCDId{background-color:var(--tv-color-popup-element-divider-background,var(--themed-color-popup-menu-separator,#ebebeb));flex-shrink:0;height:1px;margin:6px 0}html.theme-dark .separator-QjUlCDId{background-color:var(--tv-color-popup-element-divider-background,var(--themed-color-popup-menu-separator,#4a4a4a))}.small-QjUlCDId{margin-bottom:4px;margin-top:4px}.normal-QjUlCDId{margin-bottom:6px;margin-top:6px}.large-QjUlCDId{margin-bottom:8px;margin-top:8px}
|
||||
@@ -0,0 +1,25 @@
|
||||
(self.webpackChunktradingview=self.webpackChunktradingview||[]).push([[3489],{10555:e=>{e.exports={wrapper:"wrapper-VB9J73Gf",focused:"focused-VB9J73Gf",readonly:"readonly-VB9J73Gf",disabled:"disabled-VB9J73Gf","size-small":"size-small-VB9J73Gf","size-medium":"size-medium-VB9J73Gf","size-large":"size-large-VB9J73Gf","font-size-small":"font-size-small-VB9J73Gf","font-size-medium":"font-size-medium-VB9J73Gf","font-size-large":"font-size-large-VB9J73Gf","border-none":"border-none-VB9J73Gf",shadow:"shadow-VB9J73Gf","border-thin":"border-thin-VB9J73Gf","border-thick":"border-thick-VB9J73Gf","intent-default":"intent-default-VB9J73Gf","intent-success":"intent-success-VB9J73Gf","intent-warning":"intent-warning-VB9J73Gf","intent-danger":"intent-danger-VB9J73Gf","intent-primary":"intent-primary-VB9J73Gf","corner-top-left":"corner-top-left-VB9J73Gf","corner-top-right":"corner-top-right-VB9J73Gf","corner-bottom-right":"corner-bottom-right-VB9J73Gf","corner-bottom-left":"corner-bottom-left-VB9J73Gf",childrenContainer:"childrenContainer-VB9J73Gf"}},61425:e=>{e.exports={defaultSelect:"defaultSelect-OM7V5ndi"}},14272:e=>{e.exports={itemWrap:"itemWrap-srH7jxJB",item:"item-srH7jxJB",icon:"icon-srH7jxJB",selected:"selected-srH7jxJB",label:"label-srH7jxJB"}},54159:e=>{e.exports={lineEndSelect:"lineEndSelect-gw7ESiZg",right:"right-gw7ESiZg"}},69552:e=>{e.exports={lineStyleSelect:"lineStyleSelect-GcXENVb4",multipleStyles:"multipleStyles-GcXENVb4"}},27391:e=>{e.exports={lineWidthSelect:"lineWidthSelect-EUDB1YgB",bar:"bar-EUDB1YgB",isActive:"isActive-EUDB1YgB",item:"item-EUDB1YgB"}},46558:e=>{e.exports={container:"container-dhpv13DH",active:"active-dhpv13DH",disabled:"disabled-dhpv13DH",icon:"icon-dhpv13DH"}},50219:e=>{e.exports={wrap:"wrap-b6_0ORMg",disabled:"disabled-b6_0ORMg"}},97546:e=>{e.exports={dropdown:"dropdown-gZlS9p6t",dropdownMenu:"dropdownMenu-gZlS9p6t",gradientColor:"gradientColor-gZlS9p6t",lineWidthSelect:"lineWidthSelect-gZlS9p6t"}},84001:e=>{e.exports={row:"row-nGXZ4vJz",empty:"empty-nGXZ4vJz",noMargins:"noMargins-nGXZ4vJz",wrap:"wrap-nGXZ4vJz",breakpointNormal:"breakpointNormal-nGXZ4vJz",breakpointMedium:"breakpointMedium-nGXZ4vJz",breakpointSmall:"breakpointSmall-nGXZ4vJz"}},46741:e=>{e.exports={coordinates:"coordinates-mb1bDWNb",input:"input-mb1bDWNb",selectionCoordinates:"selectionCoordinates-mb1bDWNb",selectionCoordinates__inputs:"selectionCoordinates__inputs-mb1bDWNb",selectionCoordinates__description:"selectionCoordinates__description-mb1bDWNb",hintButton:"hintButton-mb1bDWNb"}},79965:e=>{e.exports={wrapper:"wrapper-NVcHMTVy",checkbox:"checkbox-NVcHMTVy",colorSelect:"colorSelect-NVcHMTVy",hintButton:"hintButton-NVcHMTVy"}},97995:e=>{e.exports={withoutPadding:"withoutPadding-KtEcG0Q0"}},80509:e=>{e.exports={input:"input-mIsHGNhw",control:"control-mIsHGNhw",item:"item-mIsHGNhw",cell:"cell-mIsHGNhw",fragmentCell:"fragmentCell-mIsHGNhw",largeWidth:"largeWidth-mIsHGNhw",withTitle:"withTitle-mIsHGNhw",title:"title-mIsHGNhw",hidden:"hidden-mIsHGNhw"}},37458:e=>{e.exports={line:"line-j5rMaiWF",control:"control-j5rMaiWF",
|
||||
valueInput:"valueInput-j5rMaiWF",valueUnit:"valueUnit-j5rMaiWF",input:"input-j5rMaiWF"}},6289:e=>{e.exports={unit:"unit-ZtRdVxiD",input:"input-ZtRdVxiD",normal:"normal-ZtRdVxiD",big:"big-ZtRdVxiD",dropdown:"dropdown-ZtRdVxiD",dropdownMenu:"dropdownMenu-ZtRdVxiD"}},69982:e=>{e.exports={optionalTwoColors:"optionalTwoColors-LDRcAXEV",colorPicker:"colorPicker-LDRcAXEV",dropdown:"dropdown-LDRcAXEV",dropdownMenu:"dropdownMenu-LDRcAXEV"}},11131:e=>{e.exports={dropdown:"dropdown-RxdEkbF0",normal:"normal-RxdEkbF0",big:"big-RxdEkbF0",dropdownMenu:"dropdownMenu-RxdEkbF0"}},35498:e=>{e.exports={range:"range-GLEBGed4",valueInput:"valueInput-GLEBGed4",rangeSlider:"rangeSlider-GLEBGed4",rangeSlider_mixed:"rangeSlider_mixed-GLEBGed4",input:"input-GLEBGed4",hintButton:"hintButton-GLEBGed4"}},74782:e=>{e.exports={select:"select-hJtsYZ3G",preContent:"preContent-hJtsYZ3G",wrap:"wrap-hJtsYZ3G",colorsWrap:"colorsWrap-hJtsYZ3G"}},63907:e=>{e.exports={colorPicker:"colorPicker-VK3h8amb",fontStyleButton:"fontStyleButton-VK3h8amb",dropdown:"dropdown-VK3h8amb",dropdownMenu:"dropdownMenu-VK3h8amb",hintButton:"hintButton-VK3h8amb",title:"title-VK3h8amb"}},95442:e=>{e.exports={twoColors:"twoColors-C2hZXnYv",colorPicker:"colorPicker-C2hZXnYv"}},26302:e=>{e.exports={dropdown:"dropdown-eLkGg0Ft",menu:"menu-eLkGg0Ft"}},27061:e=>{e.exports={buttonWrap:"buttonWrap-icygBqe7",desktopSize:"desktopSize-icygBqe7",drawer:"drawer-icygBqe7",menuBox:"menuBox-icygBqe7"}},1774:e=>{e.exports={btnContent:"btnContent-ivexqeZZ",contentPart:"contentPart-ivexqeZZ"}},40638:e=>{e.exports={checkbox:"checkbox-aOSYFxuH"}},73188:e=>{e.exports={range:"range-mFgGeMmT",disabled:"disabled-mFgGeMmT",rangeSlider:"rangeSlider-mFgGeMmT",rangeSliderMiddleWrap:"rangeSliderMiddleWrap-mFgGeMmT",rangeSliderMiddle:"rangeSliderMiddle-mFgGeMmT",dragged:"dragged-mFgGeMmT",pointer:"pointer-mFgGeMmT",rangePointerWrap:"rangePointerWrap-mFgGeMmT"}},35990:e=>{e.exports={button:"button-iLKiGOdQ",hovered:"hovered-iLKiGOdQ",disabled:"disabled-iLKiGOdQ",focused:"focused-iLKiGOdQ",active:"active-iLKiGOdQ",hidden:"hidden-iLKiGOdQ"}},66045:(e,t,n)=>{"use strict";n.d(t,{FontSizeSelect:()=>c});var o=n(50959),i=n(97754),r=n.n(i),a=n(90405),l=n(90186),s=n(61425);function c(e){const{id:t,fontSize:n,fontSizes:i=[],className:c,disabled:d,fontSizeChange:u}=e;return o.createElement(a.Select,{id:t,disabled:d,className:r()(c,s.defaultSelect),menuClassName:s.defaultSelect,items:(p=i,p.map((e=>({value:e.value,content:e.title})))),value:n,onChange:u,...(0,l.filterDataProps)(e)});var p}},94697:(e,t,n)=>{"use strict";n.d(t,{DisplayItem:()=>d,DropItem:()=>u,IconDropdown:()=>c});var o=n(50959),i=n(97754),r=n.n(i),a=n(90405),l=n(9745),s=n(14272);function c(e){const{menuItemClassName:t,...n}=e;return o.createElement(a.Select,{...n,menuItemClassName:r()(t,s.itemWrap)})}function d(e){return o.createElement("div",{className:r()(s.item,s.selected,e.className)},o.createElement(l.Icon,{className:s.icon,icon:e.icon}))}function u(e){return o.createElement("div",{className:s.item},o.createElement(l.Icon,{
|
||||
className:r()(s.icon,e.iconClassName),icon:e.icon}),o.createElement("div",{className:s.label},e.label))}},53598:(e,t,n)=>{"use strict";n.d(t,{LineStyleSelect:()=>d});var o=n(50959),i=n(97754),r=n.n(i),a=n(94697),l=n(6245),s=n(80427),c=n(69552);class d extends o.PureComponent{render(){const{id:e,lineStyle:t,className:n,lineStyleChange:i,disabled:d,additionalItems:u,allowedLineStyles:p}=this.props;let m=function(e){let t=[...l.lineStyleItemValues];return void 0!==e&&(t=t.filter((t=>e.includes(t.type)))),t.map((e=>({value:e.type,selectedContent:o.createElement(a.DisplayItem,{icon:e.icon}),content:o.createElement(a.DropItem,{icon:e.icon,label:e.label})})))}(p);return u&&(m=[{readonly:!0,content:u},...m]),o.createElement(a.IconDropdown,{id:e,disabled:d,className:r()(c.lineStyleSelect,n),hideArrowButton:!0,items:m,value:t,onChange:i,"data-name":"line-style-select",addPlaceholderToItems:!1,placeholder:o.createElement(a.DisplayItem,{icon:s,className:c.multipleStyles})})}}},88601:(e,t,n)=>{"use strict";n.d(t,{Transparency:()=>s});var o=n(50959),i=n(97754),r=n(54368),a=n(19625),l=n(50219);function s(e){const{value:t,disabled:n,onChange:s,className:c}=e;return o.createElement("div",{className:i(l.wrap,c,{[l.disabled]:n})},o.createElement(r.Opacity,{hideInput:!0,color:a.colorsPalette["color-tv-blue-500"],opacity:1-t/100,onChange:function(e){n||s(100-100*e)},disabled:n}))}},74670:(e,t,n)=>{"use strict";n.d(t,{useActiveDescendant:()=>r});var o=n(50959),i=n(39416);function r(e,t=[]){const[n,r]=(0,o.useState)(!1),a=(0,i.useFunctionalRefObject)(e);return(0,o.useLayoutEffect)((()=>{const e=a.current;if(null===e)return;const t=e=>{switch(e.type){case"active-descendant-focus":r(!0);break;case"active-descendant-blur":r(!1)}};return e.addEventListener("active-descendant-focus",t),e.addEventListener("active-descendant-blur",t),()=>{e.removeEventListener("active-descendant-focus",t),e.removeEventListener("active-descendant-blur",t)}}),t),[a,n]}},50890:(e,t,n)=>{"use strict";n.d(t,{LineWidthSelect:()=>d});var o=n(50959),i=n(97754),r=n(90405),a=n(27391);const l=[1,2,3,4];function s(e){const{id:t,value:n,items:s=l,disabled:c,onChange:d,className:u}=e;return o.createElement(r.Select,{id:t,disabled:c,hideArrowButton:!0,className:i(a.lineWidthSelect,u),items:(p=s,p.map((e=>({value:e,selectedContent:m(e,!0),content:m(e)})))),value:n,onChange:d,"data-name":"line-width-select"});var p;function m(e,t){const r={borderTopWidth:e};return o.createElement("div",{className:a.item},o.createElement("div",{className:i(a.bar,{[a.isActive]:e===n&&!t}),style:r}," "))}}var c=n(45560);function d(e){const{property:t}=e,[n,i]=(0,c.useDefinitionProperty)({property:t});return o.createElement(s,{...e,value:n,onChange:i})}},66849:(e,t,n)=>{"use strict";n.d(t,{ControlCustomHeightContext:()=>l,ControlCustomWidthContext:()=>r});var o,i=n(50959);!function(e){e.Small="small",e.Normal="normal",e.Big="big"}(o||(o={}));const r=i.createContext({});var a;!function(e){e.Normal="normal",e.Big="big"}(a||(a={}));const l=i.createContext({})},68215:(e,t,n)=>{"use strict";n.d(t,{
|
||||
Section:()=>Ot});var o=n(50959),i=n(32097),r=n(48897),a=n(45560),l=n(31356);function s(e){const{definition:{id:t,properties:{checked:n,disabled:i,visible:r},title:s,solutionId:c,infoTooltip:d},offset:u}=e,[p]=(0,a.useDefinitionProperty)({property:i,defaultValue:!1}),[m]=(0,a.useDefinitionProperty)({property:r,defaultValue:!0});return m?o.createElement(l.CommonSection,{id:t,offset:u,checked:n,title:s,solutionId:c,infoTooltip:d,disabled:e.disabled||p}):null}var c=n(97754),d=n.n(c),u=n(22064),p=n(53598);function m(e){const{property:t}=e,[n,i]=(0,a.useDefinitionProperty)({property:t});return o.createElement(p.LineStyleSelect,{...e,lineStyle:n,lineStyleChange:i})}var f=n(50890),h=n(60521),b=n(50151);function v(e){return"mixed"===e}function y(e,t,n){const[i,r]=(0,o.useState)(e),a=(0,o.useRef)(i);return(0,o.useEffect)((()=>{r(e)}),[e,n]),[i,function(e){a.current=e,r(e)},function(){t(a.current)},function(){a.current=e,r(e)}]}var g,E=n(68335),w=n(92399),C=n(9859),D=n(59623),S=n(49483);function V(e){const{property:t,...n}=e,[i,r]=(0,o.useState)(performance.now()),[l,s]=(0,a.useDefinitionProperty)({property:t,handler:()=>r(performance.now())}),c=y(l,s,i);return o.createElement(P,{...n,valueHash:i,sharedBuffer:c})}function P(e){const{sharedBuffer:t,min:n,max:i,step:r,...a}=e,[l,s,c,d]=t,u=(0,o.useRef)(null),p=(0,o.useRef)(null),m={flushed:!1};return o.createElement(k,{...a,ref:p,onValueChange:function(e,t){s(e),"step"!==t||m.flushed||(c(),m.flushed=!0)},onKeyDown:function(e){if(e.defaultPrevented||m.flushed)return;switch((0,E.hashFromEvent)(e.nativeEvent)){case 27:d(),m.flushed=!0;break;case 13:e.preventDefault();const t=(0,b.ensureNotNull)(p.current).getClampedValue();null!==t&&(s(t),c(),m.flushed=!0)}},onBlur:function(e){const t=(0,b.ensureNotNull)(u.current);if(!t.contains(document.activeElement)&&!t.contains(e.relatedTarget)){const e=(0,b.ensureNotNull)(p.current).getClampedValue();null===e||m.flushed||(s(e),c(),m.flushed=!0)}},value:l,roundByStep:!1,containerReference:function(e){u.current=e},inputMode:S.CheckMobile.iOS()?void 0:"numeric",min:n,max:i,step:r,stretch:!1})}!function(e){e.Input="input",e.Step="step"}(g||(g={}));const N={mode:"float",min:-Number.MAX_VALUE,max:Number.MAX_VALUE,step:1,precision:0,inheritPrecisionFromStep:!0};class k extends o.PureComponent{constructor(e){super(e),this._selection=null,this._restoreSelection=!1,this._input=null,this._handleSelectionChange=()=>{this._restoreSelection||document.activeElement!==(0,b.ensureNotNull)(this._input)||this._saveSelection((0,b.ensureNotNull)(this._input))},this._handleInputReference=e=>{this._input=e,this.props.inputReference&&this.props.inputReference(e)},this._onFocus=e=>{this._saveSelection((0,b.ensureNotNull)(this._input)),this.setState({focused:!0}),this.props.onFocus&&this.props.onFocus(e)},this._onBlur=e=>{this._selection=null,this.setState({displayValue:M(this.props,this.props.value,_(this.props)),focused:!1}),this.props.onBlur&&this.props.onBlur(e)},this._onValueChange=e=>{const t=e.currentTarget,n=t.value,o=function(e,t,n){switch(n){case"integer":
|
||||
return x.test(t)?t:e;case"float":return t=t.replace(/,/g,"."),T.test(t)?t:e;case"fractional":return I.test(t)?t:e}}(this.state.displayValue,n,this.props.mode),i=L(o),r=this._checkValueBoundaries(i);var a,l;this.setState({displayValue:o}),o!==n&&(a=this.state.displayValue,l=(l=o).replace(/,/g,"."),(a=a.replace(/,/g,".")).includes(".")||!l.includes("."))?(this._restoreSelection=!0,this.forceUpdate()):this._saveSelection(t),r.value&&M(this.props,i)===o&&this.props.onValueChange(i,"input")},this._onValueByStepChange=e=>{const{roundByStep:t=!0,step:n=1}=this.props,o=L(this.state.displayValue);let i;if(isNaN(o)){const{defaultValue:e}=this.props;if(void 0===e)return;i=e}else{const r=new h.Big(o),a=new h.Big(n),l=r.mod(a);let s=r.plus(e*n);!l.eq(0)&&t&&(s=s.plus((e>0?0:1)*n).minus(l)),i=s.toNumber()}this._checkValueBoundaries(i).value&&(this.setState({displayValue:M(this.props,i,_(this.props))}),this.props.onValueChange(i,"step"))},this.state={value:R(this.props.value),displayValue:M(this.props,this.props.value,_(this.props)),focused:!1,valueHash:this.props.valueHash}}componentDidMount(){document.addEventListener("selectionchange",this._handleSelectionChange)}componentWillUnmount(){document.removeEventListener("selectionchange",this._handleSelectionChange)}componentDidUpdate(){const e=(0,b.ensureNotNull)(this._input),t=this._selection;if(null!==t&&this._restoreSelection&&document.activeElement===e){const{start:n,end:o,direction:i}=t;e.setSelectionRange(n,o,i)}this._restoreSelection=!1}render(){return o.createElement(w.NumberInputView,{type:"text",inputMode:this.props.inputMode,name:this.props.name,fontSizeStyle:"medium",value:this.state.displayValue,className:this.props.className,placeholder:this.props.placeholder,forceShowControls:this.props.forceShowControls,disabled:this.props.disabled,stretch:this.props.stretch,error:Boolean(this.props.error),errorMessage:this.props.error,onValueChange:this._onValueChange,onValueByStepChange:this._onValueByStepChange,containerReference:this.props.containerReference,inputReference:this._handleInputReference,onClick:this.props.onClick,onFocus:this._onFocus,onBlur:this._onBlur,onKeyDown:this.props.onKeyDown,autoSelectOnFocus:!0,"data-name":this.props["data-name"],highlight:this.props.highlight})}getClampedValue(){const{min:e,max:t}=this.props,n=L(this.state.displayValue);return isNaN(n)?null:(0,C.clamp)(n,e,t)}static getDerivedStateFromProps(e,t){const{valueHash:n}=e,o=R(e.value);if(t.value!==o||t.valueHash!==n){return{value:o,valueHash:n,displayValue:M(e,o,t.focused&&t.valueHash===n?void 0:_(e))}}return null}_saveSelection(e){const{selectionStart:t,selectionEnd:n,selectionDirection:o}=e;null!==t&&null!==n&&null!==o&&(this._selection={start:t,end:n,direction:o})}_checkValueBoundaries(e){const{min:t,max:n}=this.props,o=function(e,t,n){const o=e>=t,i=e<=n;return{passMin:o,passMax:i,pass:o&&i,clamped:(0,C.clamp)(e,t,n)}}(e,t,n);return{value:o.pass}}}k.defaultProps=N;const x=/^-?[0-9]*$/,T=/^(-?([0-9]+\.?[0-9]*)|(-?[0-9]*))$/,I=/^(-?([0-9]+'?[0-9]*([0-9]+'?)[0-9]*)|(-?[0-9]*))$/
|
||||
;function M(e,t,n){return v(t=R(t))?"—":(null!==t&&void 0!==n&&(n=Math.max(B(t),n)),function(e,t){if(null===e)return"";return new D.NumericFormatter({precision:t}).format(e,{ignoreLocaleNumberFormat:!0})}(t,n))}function _(e){let t=0;return e.inheritPrecisionFromStep&&e.step<=1&&(t=B(e.step)),Math.max(e.precision,t)||void 0}function B(e){const t=Math.trunc(e).toString();return(0,C.clamp)(D.NumericFormatter.formatNoE(e).length-t.length-1,0,15)}function L(e,t){const n=new D.NumericFormatter({precision:t}).parse(e,{ignoreLocaleNumberFormat:!0});return n.res?n.value:NaN}function R(e){return"number"==typeof e&&Number.isFinite(e)||v(e)?e:null}var A=n(24377),F=n(26540),W=n(19063),z=n(6245);function G(e){const{color:t,thickness:n,thicknessItems:i,noAlpha:r,lineStyle:l,allowedLineStyles:s}=e,[c,d]=(0,a.useDefinitionProperty)({property:t}),[u,p]=(0,a.useDefinitionProperty)(n?{property:n}:{defaultValue:void 0}),[m,f]=(0,a.useDefinitionProperty)(l?{property:l}:{defaultValue:void 0}),h=(0,o.useMemo)((()=>s?z.defaultLineStyleItems.filter((e=>s.includes(e))):z.defaultLineStyleItems),[s]);return o.createElement(F.ColorSelect,{...e,color:function(){if(!c)return null;if("mixed"===c)return"mixed";return(0,A.rgbToHexString)((0,A.parseRgb)(c))}(),onColorChange:function(e){const t=c&&"mixed"!==c?(0,W.alphaToTransparency)((0,A.parseRgba)(c)[3]):0;d((0,W.generateColor)(String(e),t,!0))},thickness:u,lineStyle:m,thicknessItems:i,lineStyleItems:h,onThicknessChange:p,onLineStyleChange:f,opacity:r?void 0:c&&"mixed"!==c?(0,A.parseRgba)(c)[3]:void 0,onOpacityChange:r?void 0:function(e){d((0,W.generateColor)(c,(0,W.alphaToTransparency)(e),!0))}})}var O=n(11542),H=n(49857),J=n(94697),Z=n(90186),j=n(43382),K=n(98853),U=n(54159);const X=[{type:H.LineEnd.Normal,icon:j,label:O.t(null,void 0,n(65353))},{type:H.LineEnd.Arrow,icon:K,label:O.t(null,void 0,n(11858))}];class Y extends o.PureComponent{constructor(e){super(e),this._items=[],this._items=X.map((t=>({value:t.type,selectedContent:o.createElement(J.DisplayItem,{icon:t.icon}),content:o.createElement(J.DropItem,{icon:t.icon,iconClassName:d()(e.isRight&&U.right),label:t.label})})))}render(){const{id:e,lineEnd:t,className:n,lineEndChange:i,isRight:r,disabled:a}=this.props;return o.createElement(J.IconDropdown,{id:e,disabled:a,className:d()(U.lineEndSelect,r&&U.right,n),items:this._items,value:t,onChange:i,hideArrowButton:!0,...(0,Z.filterDataProps)(this.props)})}}function $(e){const{property:t}=e,[n,i]=(0,a.useDefinitionProperty)({property:t});return o.createElement(Y,{...e,lineEnd:n,lineEndChange:i})}var q,Q=n(78260),ee=n(84001);function te(e){const{children:t,className:n,breakPoint:i="Normal"}=e;return o.createElement(Q.CellWrap,{className:c(ee.wrap,n,ee[`breakpoint${i}`])},o.Children.map(t,(e=>o.isValidElement(e)?o.createElement("span",{key:null===e.key?void 0:e.key,className:c(ee.row,r(e)&&ee.empty,a(e)&&ee.noMargins)},e):e)));function r(e){return!(!o.isValidElement(e)||e.type!==o.Fragment||!Array.isArray(e.props.children))&&e.props.children.every((e=>null===e))}function a(e){
|
||||
return o.isValidElement(e)&&Boolean(e.props?.["data-no-margins"])}}!function(e){e.MobileNormal="Normal",e.MobileMedium="Medium",e.MobileSmall="Small"}(q||(q={}));const ne={1:"float",0:"integer"};var oe=n(77975),ie=n(37458);function re(e){const{definition:{id:t,properties:{checked:n,disabled:i,visible:r,leftEnd:s,rightEnd:d,value:p,extendLeft:h,extendRight:b,style:v,width:y,color:g},title:E,valueMin:w,valueMax:C,valueStep:D,valueUnit:S,extendLeftTitle:P,extendRightTitle:N,solutionId:k,widthValues:x},offset:T}=e,[I]=(0,a.useDefinitionProperty)({property:n,defaultValue:!0}),[M]=(0,a.useDefinitionProperty)({property:i,defaultValue:!1}),[_]=(0,a.useDefinitionProperty)({property:r,defaultValue:!0}),B=(0,oe.useWatchedValueReadonly)({watchedValue:w,defaultValue:void 0}),L=(0,oe.useWatchedValueReadonly)({watchedValue:C,defaultValue:void 0}),R=(0,oe.useWatchedValueReadonly)({watchedValue:D,defaultValue:void 0}),A=(0,oe.useWatchedValueReadonly)({watchedValue:S,defaultValue:void 0}),F=e.disabled||!I;return _?o.createElement(o.Fragment,null,o.createElement(l.CommonSection,{id:t,offset:T,checked:n,title:E,solutionId:k,disabled:e.disabled||M},o.createElement(te,{className:ie.line,breakPoint:"Small"},g&&o.createElement("span",{className:ie.control},o.createElement(G,{color:g,thickness:y,disabled:F,thicknessItems:x,lineStyle:v})),!g&&y&&o.createElement("span",{className:ie.control},o.createElement(f.LineWidthSelect,{id:(0,u.createDomId)(t,"line-width-select"),items:x,property:y,disabled:F})),!g&&v&&o.createElement("span",{className:ie.control},o.createElement(m,{id:(0,u.createDomId)(t,"line-style-select"),property:v,disabled:F})),(s||d||p)&&o.createElement(o.Fragment,null,o.createElement(o.Fragment,null,s&&o.createElement($,{id:(0,u.createDomId)(t,"left-end-select"),"data-name":"left-end-select",className:ie.control,property:s,disabled:F}),d&&o.createElement($,{id:(0,u.createDomId)(t,"right-end-select"),"data-name":"right-end-select",className:ie.control,property:d,disabled:F,isRight:!0})),function(){const{definition:{valueType:t}}=e;return p&&o.createElement("span",{className:c(ie.valueInput,ie.control)},o.createElement(V,{className:ie.input,property:p,min:B,max:L,step:R,disabled:F,mode:void 0!==t?ne[t]:void 0,name:"line-value-input"}),o.createElement("span",{className:ie.valueUnit},A))}()))),h&&o.createElement(l.CommonSection,{id:`${t}ExtendLeft`,offset:T,checked:h,title:P,disabled:e.disabled||M}),b&&o.createElement(l.CommonSection,{id:`${t}ExtendRight`,offset:T,checked:b,title:N,disabled:e.disabled||M})):null}function ae(e){return o.createElement(G,{...e})}var le=n(46088),se=n(90405),ce=n(36947);function de(e){const{property:t,options:n,...i}=e,[r,l]=(0,a.useDefinitionProperty)({property:t}),s=(0,ce.useForceUpdate)();return(0,o.useEffect)((()=>{const e=()=>s();return Array.isArray(n)||n.subscribe(e),()=>{Array.isArray(n)||n.unsubscribe(e)}}),[]),o.createElement(se.Select,{...i,onChange:l,value:r,items:(Array.isArray(n)?n:n.value()).map((e=>e.readonly?{content:e.title,readonly:e.readonly}:{content:e.title,value:e.value,
|
||||
disabled:e.disabled,id:e.id}))})}var ue=n(97546);const pe=[{title:O.t(null,void 0,n(88686)),value:le.ColorType.Solid},{title:O.t(null,void 0,n(68043)),value:le.ColorType.Gradient}],me=[1,2,3,4];function fe(e){const{id:t,disabled:n,noAlpha:i,properties:r}=e,{color:l,gradientColor1:s,gradientColor2:c,type:d,width:p}=r,[m]=(0,a.useDefinitionProperty)({property:d,defaultValue:le.ColorType.Solid});return o.createElement(te,null,d&&o.createElement(de,{id:(0,u.createDomId)(t,"background-type-options-dropdown"),"data-name":"background-type-options-dropdown",className:ue.dropdown,menuClassName:ue.dropdownMenu,disabled:n,property:d,options:pe}),m!==le.ColorType.Solid&&m&&s&&c?o.createElement("div",{className:ue.gradientColor},o.createElement(ae,{color:s,disabled:n,noAlpha:i}),o.createElement(ae,{color:c,disabled:n,noAlpha:i}),p&&o.createElement(f.LineWidthSelect,{className:ue.lineWidthSelect,property:p,items:me,disabled:!!n})):o.createElement(G,{color:l,disabled:n,noAlpha:i,thickness:p,thicknessItems:me}))}function he(e){const{definition:{id:t,properties:n,title:i,noAlpha:r,solutionId:s},offset:c}=e,{color:d,checked:u,disabled:p,visible:m}=n,[f]=(0,a.useDefinitionProperty)({property:u,defaultValue:!0}),[h]=(0,a.useDefinitionProperty)({property:p,defaultValue:!1}),[b]=(0,a.useDefinitionProperty)({property:m,defaultValue:!0}),v=e.disabled||!f;return b?o.createElement(l.CommonSection,{id:t,offset:c,checked:u,title:i,solutionId:s,disabled:e.disabled||h},o.createElement(Q.CellWrap,null,n.hasOwnProperty("type")?o.createElement(fe,{id:t,properties:n,disabled:v,noAlpha:r}):o.createElement(ae,{color:d,disabled:v,noAlpha:r}))):null}var be=n(88601);function ve(e){const{property:t,...n}=e,[i,r]=(0,a.useDefinitionProperty)({property:t});return o.createElement(be.Transparency,{...n,value:i,onChange:r})}function ye(e){const{definition:{id:t,properties:{transparency:n,checked:i,disabled:r,visible:s},title:c,solutionId:d},offset:u}=e,[p]=(0,a.useDefinitionProperty)({property:i,defaultValue:!0}),[m]=(0,a.useDefinitionProperty)({property:r,defaultValue:!1}),[f]=(0,a.useDefinitionProperty)({property:s,defaultValue:!0}),h=e.disabled||!p;return f?o.createElement(l.CommonSection,{id:t,offset:u,checked:i,title:c,solutionId:d,disabled:e.disabled||m},o.createElement(Q.CellWrap,null,o.createElement(ve,{property:n,disabled:h}))):null}var ge=n(95442);function Ee(e){const{definition:{id:t,properties:{color1:n,color2:i,checked:r,disabled:s,visible:c},title:d,noAlpha1:u,noAlpha2:p,solutionId:m},offset:f}=e,[h]=(0,a.useDefinitionProperty)({property:r,defaultValue:!0}),[b]=(0,a.useDefinitionProperty)({property:s,defaultValue:!1}),[v]=(0,a.useDefinitionProperty)({property:c,defaultValue:!0}),y=e.disabled||!h||b;return v?o.createElement(l.CommonSection,{id:t,offset:f,checked:r,solutionId:m,title:d,disabled:e.disabled||b},o.createElement(Q.CellWrap,{className:ge.twoColors},g(n,u),g(i,p))):null;function g(e,t){return o.createElement("span",{className:ge.colorPicker},o.createElement(ae,{color:e,disabled:y,noAlpha:t}))}}var we=n(66849),Ce=n(6289);function De(e){
|
||||
const{definition:{id:t,properties:{checked:n,value:i,unitOptionsValue:r,disabled:s,visible:d},min:p,max:m,step:f,title:h,unit:v,unitOptions:y,type:g,solutionId:E},offset:w}=e,[C]=(0,a.useDefinitionProperty)({property:n,defaultValue:!0}),[D]=(0,a.useDefinitionProperty)({property:s,defaultValue:!1}),[S]=(0,a.useDefinitionProperty)({property:d,defaultValue:!0}),P=(0,oe.useWatchedValueReadonly)({watchedValue:p,defaultValue:void 0}),N=(0,oe.useWatchedValueReadonly)({watchedValue:m,defaultValue:void 0}),k=(0,oe.useWatchedValueReadonly)({watchedValue:f,defaultValue:void 0}),x=(0,oe.useWatchedValueReadonly)({watchedValue:v,defaultValue:void 0}),T=(0,o.useContext)(we.ControlCustomWidthContext),I=D||e.disabled||!C;return S?o.createElement(l.CommonSection,{id:t,offset:w,checked:n,title:h,solutionId:E,disabled:e.disabled||D},o.createElement(Q.CellWrap,null,o.createElement(te,null,o.createElement(V,{className:c(Ce.input,T[t]&&Ce[T[t]]),property:i,min:P,max:N,step:k,disabled:I,mode:ne[g],name:"number-input","data-name":t}),r&&o.createElement(de,{id:(0,u.createDomId)(t,"unit-options-dropdown"),"data-name":"unit-options-dropdown",className:Ce.dropdown,menuClassName:Ce.dropdownMenu,disabled:I,property:r,options:(0,b.ensureDefined)(y)})),x&&o.createElement("span",{className:Ce.unit},x))):null}function Se(e){const{definition:{id:t,properties:{checked:n,disabled:i,visible:r},childrenDefinitions:s,title:c},offset:d}=e,[u]=(0,a.useDefinitionProperty)({property:n,defaultValue:!0}),[p]=(0,a.useDefinitionProperty)({property:i,defaultValue:!1}),[m]=(0,a.useDefinitionProperty)({property:r,defaultValue:!0}),f=e.disabled||!u;return m?o.createElement(o.Fragment,null,o.createElement(l.CommonSection,{id:t,offset:d,checked:n,title:c,disabled:e.disabled||p}),s.map((e=>o.createElement(Ot,{key:e.id,disabled:f,definition:e,offset:!0})))):null}var Ve=n(66045);function Pe(e){const{property:t}=e,[n,i]=(0,a.useDefinitionProperty)({property:t});return o.createElement(Ve.FontSizeSelect,{...e,fontSize:n,fontSizeChange:i,"data-name":"font-size-select"})}var Ne=n(9745),ke=n(46558);function xe(e){const{className:t,checked:n,icon:i,disabled:r,onClick:a}=e;return o.createElement("div",{className:d()(t,ke.container,n&&!r&&ke.active,r&&ke.disabled),onClick:r?void 0:a,"data-role":"button",...(0,Z.filterDataProps)(e)},o.createElement(Ne.Icon,{className:ke.icon,icon:i}))}function Te(e){const{icon:t,className:n,property:i,disabled:r}=e,[l,s]=(0,a.useDefinitionProperty)({property:i});return o.createElement(xe,{className:n,icon:t,checked:l,onClick:function(){s(!l)},disabled:r,...(0,Z.filterDataProps)(e)})}var Ie=n(67029),Me=n(71891),_e=n(2568);function Be(e){const{property:t,...n}=e,[i,r]=(0,a.useDefinitionProperty)({property:t}),l=(0,o.useCallback)((e=>r(e.target.value)),[r]);return o.createElement(_e.Textarea,{...n,value:i,onChange:l})}var Le=n(8295),Re=n(29285),Ae=n(63907);const Fe=e=>({content:e.title,title:e.title,value:e.value,id:e.id}),We=e=>({content:e.title,title:e.title,value:e.value,id:e.id});function ze(e){
|
||||
const{definition:{id:t,properties:{color:n,size:i,checked:r,disabled:s,bold:c,italic:d,text:p,alignmentHorizontal:m,alignmentVertical:f,orientation:h,backgroundVisible:b,backgroundColor:v,borderVisible:y,borderColor:g,borderWidth:E,wrap:w},title:C,solutionId:D,sizeItems:S,alignmentTitle:V,alignmentHorizontalItems:P,alignmentVerticalItems:N,orientationTitle:k,orientationItems:x,backgroundTitle:T,borderTitle:I,borderWidthItems:M,wrapTitle:_},offset:B}=e,L=(0,o.useContext)(we.ControlCustomHeightContext),[R]=(0,a.useDefinitionProperty)({property:r,defaultValue:!0}),[A]=(0,a.useDefinitionProperty)({property:s,defaultValue:!1}),[F,W]=(0,a.useDefinitionProperty)({property:f,defaultValue:void 0}),[z,O]=(0,a.useDefinitionProperty)({property:h,defaultValue:"horizontal"}),[H,J]=(0,a.useDefinitionProperty)({property:m,defaultValue:void 0}),[Z]=(0,a.useDefinitionProperty)({property:b,defaultValue:!1}),[j]=(0,a.useDefinitionProperty)({property:y,defaultValue:!1}),K=e.disabled||!R;return o.createElement(o.Fragment,null,function(){if(C)return o.createElement(l.CommonSection,{id:t,offset:B,checked:r,title:C,solutionId:D,disabled:e.disabled||A},o.createElement(te,{breakPoint:"Small"},Y(),$()));return o.createElement(Me.PropertyTable.Row,null,o.createElement(Me.PropertyTable.Cell,{placement:"first",colSpan:2,offset:B,"data-section-name":t},Y(),$(),D&&!1))}(),p&&o.createElement(Me.PropertyTable.Row,null,o.createElement(Me.PropertyTable.Cell,{placement:"first",colSpan:2,offset:B,"data-section-name":t},o.createElement(Be,{className:Ie.InputClasses.FontSizeMedium,rows:(U=L[t],"big"===U?9:5),stretch:!0,property:p,disabled:K,onFocus:function(e){e.target.select()},name:"text-input"}))),(m||f)&&o.createElement(Me.PropertyTable.Row,null,o.createElement(Me.PropertyTable.Cell,{placement:"first",verticalAlign:"adaptive",offset:B,"data-section-name":t},o.createElement(Q.CellWrap,null,o.createElement("span",{className:Ae.title},V))),o.createElement(Me.PropertyTable.Cell,{placement:"last",verticalAlign:"adaptive","data-section-name":t},o.createElement(te,{breakPoint:"Small"},void 0!==F&&void 0!==N&&o.createElement(se.Select,{id:(0,u.createDomId)(t,"alignment-vertical-select"),"data-name":"alignment-vertical-select",className:Ae.dropdown,menuClassName:Ae.dropdownMenu,disabled:K,value:F,items:N.map(Fe),onChange:W}),void 0!==H&&void 0!==P&&o.createElement(se.Select,{id:(0,u.createDomId)(t,"alignment-horizontal-select"),"data-name":"alignment-horizontal-select",className:Ae.dropdown,menuClassName:Ae.dropdownMenu,disabled:K,value:H,items:P.map(Fe),onChange:J})))),void 0!==h&&void 0!==x&&o.createElement(Me.PropertyTable.Row,null,o.createElement(Me.PropertyTable.Cell,{placement:"first",verticalAlign:"adaptive",offset:B,"data-section-name":t},o.createElement(Q.CellWrap,null,o.createElement("span",{className:Ae.title},k))),o.createElement(Me.PropertyTable.Cell,{placement:"last",verticalAlign:"adaptive","data-section-name":t},o.createElement(te,{breakPoint:"Small"},o.createElement(se.Select,{id:(0,u.createDomId)(t,"orientation-select"),
|
||||
"data-name":"orientation-select",className:Ae.dropdown,menuClassName:Ae.dropdownMenu,disabled:K,value:z,items:x.map(We),onChange:O})))),q(T,b,v,!!b&&!Z),q(I,y,g,!!y&&!j,E,M),w&&o.createElement(l.CommonSection,{id:`${t}Wrap`,offset:B,checked:w,title:_,disabled:e.disabled||A}));var U;function X(e,t,n){return e?o.createElement(Te,{className:Ae.fontStyleButton,icon:t,property:e,disabled:K,"data-name":n}):null}function Y(){return o.createElement(o.Fragment,null,n&&o.createElement("div",{className:Ae.colorPicker},o.createElement(ae,{color:n,disabled:K})),i&&S&&o.createElement(Pe,{id:(0,u.createDomId)(t,"font-size-select"),property:i,fontSizes:S,disabled:K}))}function $(){return o.createElement(o.Fragment,null,X(c,Le,"toggle-bold"),X(d,Re,"toggle-italic"))}function q(e,n,i,r,a,s){return i||n?o.createElement(l.CommonSection,{id:`${t}ColorSelect`,offset:B,checked:n,title:e,disabled:K},i&&o.createElement(G,{color:i,thickness:a,thicknessItems:s,disabled:K||r})):null}}var Ge=n(86623),Oe=n(37265);function He(e){const{property:t,mathOperations:n="+/*",mode:i="float",disabled:r,...l}=e,[s,c]=(0,o.useState)(performance.now()),[d,u]=(0,a.useDefinitionProperty)({property:t,handler:()=>c(performance.now())}),[p,m,f,h]=y(d,u,s),b=(0,o.useMemo)((()=>{const e=new RegExp(`^[${n.split("").join("\\")}-]?(${"float"===i?"(\\d+\\.\\d*)|":""}(\\d*))$`);return t=>(0,Oe.isString)(t)&&e.test(t)}),[n,i]);return o.createElement(Ge.FormInput,{...l,type:"text",value:p,onChange:function(e){const{value:t}=e.currentTarget;m(b(t)?t:p)},onKeyDown:function(e){if(e.defaultPrevented)return;switch((0,E.hashFromEvent)(e.nativeEvent)){case 27:h();break;case 13:v()}},onBlur:function(){v()},disabled:r,stretch:!1,autoSelectOnFocus:!0});function v(){p.length&&f()}}var Je=n(46741);function Ze(e){const{definition:{properties:{x:t,y:n,disabled:i},id:r,title:a,solutionId:l},definition:s,offset:c}=e,d=i&&i.value()||e.disabled;return o.createElement(Me.PropertyTable.Row,null,o.createElement(Me.PropertyTable.Cell,{verticalAlign:"top",placement:"first",offset:c,"data-section-name":r},o.createElement("span",{className:Je.coordinates},a)),(t||n)&&o.createElement(Me.PropertyTable.Cell,{placement:"last",offset:c,"data-section-name":r},o.createElement(te,{breakPoint:"Medium"},"coordinates"===s.propType?o.createElement(je,{definition:s,disabled:d}):o.createElement(Ke,{definition:s,disabled:d})),l&&!1))}function je(e){const{definition:{properties:{x:t,y:n},minX:i,maxX:r,stepX:a,minY:l,maxY:s,stepY:c,typeX:d,typeY:u},disabled:p}=e,m=(0,oe.useWatchedValueReadonly)({watchedValue:i,defaultValue:void 0}),f=(0,oe.useWatchedValueReadonly)({watchedValue:r,defaultValue:void 0}),h=(0,oe.useWatchedValueReadonly)({watchedValue:a,defaultValue:void 0}),b=(0,oe.useWatchedValueReadonly)({watchedValue:l,defaultValue:void 0}),v=(0,oe.useWatchedValueReadonly)({watchedValue:s,defaultValue:void 0}),y=(0,oe.useWatchedValueReadonly)({watchedValue:c,defaultValue:void 0});return o.createElement(o.Fragment,null,n&&o.createElement(V,{className:Je.input,property:n,min:b,max:v,step:y,disabled:p,name:"y-input",
|
||||
mode:void 0!==u?ne[u]:"integer"}),t&&o.createElement(V,{className:Je.input,property:t,min:m,max:f,step:h,disabled:p,name:"x-input",mode:void 0!==d?ne[d]:"integer"}))}function Ke(e){const{definition:{properties:{x:t,y:i},mathOperationsX:r,mathOperationsY:a,modeX:l,modeY:s},disabled:c}=e;return o.createElement("div",{className:Je.selectionCoordinates},o.createElement("div",{className:Je.selectionCoordinates__inputs},i&&o.createElement(He,{property:i,mathOperations:a,mode:s,disabled:c,className:Je.input,placeholder:O.t(null,void 0,n(49957))}),t&&o.createElement(He,{property:t,mathOperations:r,mode:l,disabled:c,className:Je.input,placeholder:O.t(null,void 0,n(406))})),o.createElement("div",{className:Je.selectionCoordinates__description},O.t(null,void 0,n(13748))))}var Ue=n(11131);function Xe(e){const{definition:{id:t,properties:{checked:n,option:i,disabled:r,visible:s,color:c},title:p,solutionId:m,options:f,infoTooltip:h},offset:b}=e,[v]=(0,a.useDefinitionProperty)({property:n,defaultValue:!0}),[y]=(0,a.useDefinitionProperty)({property:r,defaultValue:!1}),[g]=(0,a.useDefinitionProperty)({property:s,defaultValue:!0}),E=(0,o.useContext)(we.ControlCustomWidthContext),w=e.disabled||!v;return g?o.createElement(l.CommonSection,{id:t,offset:b,checked:n,title:p,solutionId:m,disabled:e.disabled||y,infoTooltip:h},o.createElement(Q.CellWrap,null,o.createElement(te,null,o.createElement(de,{id:(0,u.createDomId)(t,"options-dropdown"),"data-name":"options-dropdown",className:d()(Ue.dropdown,E[t]&&Ue[E[t]]),menuClassName:d()(Ue.dropdownMenu,E[t]&&Ue[E[t]]),disabled:w||y,property:i,options:f}),c&&o.createElement(ae,{color:c,disabled:w})))):null}var Ye=n(71953);var $e,qe=n(63273),Qe=n(73188);!function(e){e[e.None=0]="None",e[e.From=1]="From",e[e.To=2]="To"}($e||($e={}));class et extends o.PureComponent{constructor(e){super(e),this._container=null,this._pointer=null,this._rafPosition=null,this._rafDragStop=null,this._refContainer=e=>{this._container=e},this._refPointer=e=>{this._pointer=e},this._handlePosition=e=>{null!==this._rafPosition||this.props.disabled||(this._rafPosition=requestAnimationFrame((()=>{const{from:t,to:n,min:o,max:i}=this.props,r=this._getNewPosition(e),a=1===this._detectPointerMode(e),l=a?(0,C.clamp)(r,o,n):t,s=a?n:(0,C.clamp)(r,t,i);l<=s&&this._handleChange(l,s),this._rafPosition=null})))},this._handleDragStop=()=>{null!==this._rafDragStop||this.props.disabled||(this._rafDragStop=requestAnimationFrame((()=>{this.setState({pointerDragMode:0}),this._rafDragStop=null,this.props.onCommit()})))},this._onSliderClick=e=>{S.CheckMobile.any()||(this._handlePosition(e.nativeEvent),this._dragSubscribe())},this._mouseUp=e=>{this._dragUnsubscribe(),this._handlePosition(e),this._handleDragStop()},this._mouseMove=e=>{this._handlePosition(e)},this._onTouchStart=e=>{this._handlePosition(e.nativeEvent.touches[0])},this._handleTouch=e=>{this._handlePosition(e.nativeEvent.touches[0])},this._handleTouchEnd=()=>{this._handleDragStop()},this.state={pointerDragMode:0}}componentWillUnmount(){
|
||||
null!==this._rafPosition&&(cancelAnimationFrame(this._rafPosition),this._rafPosition=null),null!==this._rafDragStop&&(cancelAnimationFrame(this._rafDragStop),this._rafDragStop=null),this._dragUnsubscribe()}render(){const{className:e,disabled:t,from:n,to:i,min:r,max:a}=this.props,{pointerDragMode:l}=this.state,s=0!==l,d=a-r,u=0===d?r:(n-r)/d,p=0===d?a:(i-r)/d,m=(0,qe.isRtl)()?"right":"left";return o.createElement("div",{className:c(e,Qe.range,t&&Qe.disabled)},o.createElement("div",{className:Qe.rangeSlider,ref:this._refContainer,onMouseDown:this._onSliderClick,onTouchStart:this._onTouchStart,onTouchMove:this._handleTouch,onTouchEnd:this._handleTouchEnd},o.createElement("div",{className:Qe.rangeSliderMiddleWrap},o.createElement("div",{className:c(Qe.rangeSliderMiddle,s&&Qe.dragged),style:{[m]:100*u+"%",width:100*(p-u)+"%"}})),o.createElement("div",{className:Qe.rangePointerWrap},o.createElement("div",{className:c(Qe.pointer,s&&Qe.dragged),style:{[m]:100*u+"%"},ref:this._refPointer})),o.createElement("div",{className:Qe.rangePointerWrap},o.createElement("div",{className:c(Qe.pointer,s&&Qe.dragged),style:{[m]:100*p+"%"}}))))}_dragSubscribe(){const e=(0,b.ensureNotNull)(this._container).ownerDocument;e&&(e.addEventListener("mouseup",this._mouseUp),e.addEventListener("mousemove",this._mouseMove))}_dragUnsubscribe(){const e=(0,b.ensureNotNull)(this._container).ownerDocument;e&&(e.removeEventListener("mousemove",this._mouseMove),e.removeEventListener("mouseup",this._mouseUp))}_getNewPosition(e){const{min:t,max:n}=this.props,o=n-t,i=(0,b.ensureNotNull)(this._container),r=(0,b.ensureNotNull)(this._pointer),a=i.getBoundingClientRect(),l=r.offsetWidth;let s=e.clientX-l/2-a.left;return(0,qe.isRtl)()&&(s=a.width-s-l),(0,C.clamp)(s/(a.width-l),0,1)*o+t}_detectPointerMode(e){const{from:t,to:n}=this.props,{pointerDragMode:o}=this.state;if(0!==o)return o;const i=this._getNewPosition(e),r=Math.abs(t-i),a=Math.abs(n-i),l=r===a?i<t?1:2:r<a?1:2;return this.setState({pointerDragMode:l}),l}_handleChange(e,t){const{from:n,to:o,onChange:i}=this.props;e===n&&t===o||i(e,t)}}var tt=n(90692),nt=n(35498);function ot(e){const{definition:{id:t,properties:{checked:n,disabled:i,from:r,to:s},title:c,solutionId:u,max:p,min:m},offset:f,disabled:h}=e,[b]=(0,a.useDefinitionProperty)({property:n,defaultValue:!0}),[g]=(0,a.useDefinitionProperty)({property:i,defaultValue:!1}),E=(0,oe.useWatchedValueReadonly)({watchedValue:m,defaultValue:void 0}),w=(0,oe.useWatchedValueReadonly)({watchedValue:p,defaultValue:void 0}),[C,D]=(0,a.useDefinitionProperty)({property:r}),[S,V]=(0,a.useDefinitionProperty)({property:s}),N=v(C)||v(S),k=y(N?"mixed":C,(function(e){if(D(e),v(_)){const e=w||100;B(e),V(e)}})),[x,T,I]=k,M=y(N?"mixed":S,(function(e){if(V(e),v(x)){const e=E||0;T(e),D(e)}})),[_,B,L]=M,R=v(x)||v(_),A=h||v(b)||!b,F={flushed:!1};return o.createElement(l.CommonSection,{id:t,offset:f,checked:n,title:c,disabled:h||g},o.createElement(Q.CellWrap,{className:nt.range},function(){if(!E||!w)return null;return o.createElement(tt.MatchMedia,{rule:"(max-width: 460px)"
|
||||
},(e=>o.createElement(te,{breakPoint:"Medium"},o.createElement(o.Fragment,null,o.createElement("span",{className:nt.valueInput},o.createElement(P,{className:nt.input,sharedBuffer:k,min:E,max:v(_)?w:_,step:1,disabled:A,name:"from-input",mode:"integer",defaultValue:E}),e?o.createElement("span",{className:nt.rangeSlider},"—"):o.createElement(et,{className:d()(nt.rangeSlider,R&&nt.rangeSlider_mixed),from:R?E:x,to:R?w:_,min:E,max:w,onChange:W,onCommit:z,disabled:A}))),o.createElement(o.Fragment,null,o.createElement("span",{className:nt.valueInput},o.createElement(P,{className:nt.input,sharedBuffer:M,min:v(x)?E:x,max:w,step:1,disabled:A,name:"to-input",mode:"integer",defaultValue:w}),u&&!1)))))}()));function W(e,t){T(Math.round(e)),B(Math.round(t))}function z(){F.flushed||(I(),L(),F.flushed=!0)}}var it=n(86067),rt=n(53424),at=n(80509);function lt(e){const{definitions:t,name:n,offset:i}=e,r=d()(at.cell,at.fragmentCell,t.some((e=>void 0!==e.solutionId))&&at.largeWidth);return o.createElement(Me.PropertyTable.Row,null,o.createElement(Me.PropertyTable.Cell,{className:r,offset:i,placement:"first",verticalAlign:"adaptive",colSpan:2,"data-section-name":n,checkableTitle:!0},t.map((e=>o.createElement("div",{className:at.item,key:e.id,"data-section-name":e.id},o.createElement(ct,{definition:e}))))))}function st(e){const{definition:t,offset:n}=e;return o.createElement(Me.PropertyTable.Row,null,o.createElement(Me.PropertyTable.Cell,{className:at.cell,offset:n,placement:"first",verticalAlign:"adaptive",colSpan:2,checkableTitle:!0},o.createElement(ct,{definition:t})))}function ct(e){const{definition:{id:t,properties:{disabled:n,checked:i,color:r,level:l,width:s,style:c},solutionId:p,title:f,widthValues:h,styleValues:b,locked:v}}=e,[y]=(0,a.useDefinitionProperty)({property:i,defaultValue:!0}),[g]=(0,a.useDefinitionProperty)({property:n,defaultValue:!1}),E=g||!y;return o.createElement(o.Fragment,null,o.createElement(rt.CheckableTitle,{name:`is-enabled-${t}`,className:d()(f&&at.withTitle,v&&at.hidden),title:f&&o.createElement("span",{className:at.title},f),property:i,disabled:g}),l&&o.createElement(V,{className:d()(at.input,at.control),property:l,disabled:E}),r&&o.createElement(G,{className:at.control,disabled:E,color:r,thickness:s,thicknessItems:h,lineStyle:c,allowedLineStyles:b}),!r&&c&&o.createElement(m,{id:(0,u.createDomId)(t,"leveled-line-style-select"),className:at.control,property:c,disabled:E,allowedLineStyles:b}),p&&!1)}var dt=n(26302);function ut(e){const{definition:{id:t,properties:{option1:n,option2:i,checked:r,disabled:s},title:c,solutionId:d,optionsItems1:p,optionsItems2:m},offset:f}=e,[h]=(0,a.useDefinitionProperty)({property:r,defaultValue:!0}),[b]=(0,a.useDefinitionProperty)({property:s,defaultValue:!1}),v=e.disabled||!h;return o.createElement(l.CommonSection,{id:t,offset:f,checked:r,title:c,solutionId:d,disabled:e.disabled||b},o.createElement(te,{className:dt.twoOptions},o.createElement(de,{id:(0,u.createDomId)(t,"two-options-dropdown-1"),"data-name":"two-options-dropdown-1",className:dt.dropdown,menuClassName:dt.menu,
|
||||
property:n,disabled:v,options:p}),o.createElement(de,{id:(0,u.createDomId)(t,"two-options-dropdown-2"),"data-name":"two-options-dropdown-2",className:dt.dropdown,menuClassName:dt.menu,property:i,disabled:v,options:m})))}var pt=n(69982);function mt(e){const{definition:{id:t,properties:{color1:n,color2:i,option:r},options:a,color1Visible:s,color2Visible:c,title:p,noAlpha1:m,noAlpha2:f,solutionId:h},offset:b}=e,v=(0,oe.useWatchedValueReadonly)({watchedValue:s,defaultValue:!1}),y=(0,oe.useWatchedValueReadonly)({watchedValue:c,defaultValue:!1}),g=(0,o.useContext)(we.ControlCustomWidthContext);return o.createElement(l.CommonSection,{id:t,offset:b,solutionId:h,title:p},o.createElement(Q.CellWrap,{className:pt.optionalTwoColors},o.createElement(te,null,o.createElement(de,{id:(0,u.createDomId)(t,"options-dropdown"),"data-name":"options-dropdown",className:d()(pt.dropdown,g[t]&&pt[g[t]]),menuClassName:d()(pt.dropdownMenu,g[t]&&pt[g[t]]),property:r,options:a}),o.createElement(o.Fragment,null,v&&E(n,m),y&&E(i,f)))));function E(e,t){return o.createElement("span",{className:pt.colorPicker},o.createElement(ae,{color:e,noAlpha:t}))}}var ft=n(33900),ht=n(97995);function bt(e){const{source:t,inputs:n,model:i,inputsTabProperty:r,studyMetaInfo:a}=e.definition;return o.createElement(ft.InputsTabContent,{className:ht.withoutPadding,property:r,model:i,study:t,studyMetaInfo:a,inputs:n})}var vt=n(19625),yt=n(82930),gt=n(79965);function Et(e){const{definition:{id:t,title:n,properties:i,solutionId:r},offset:s}=e,{checked:c,emoji:d,backgroundColor:u}=i,[p]=(0,a.useDefinitionProperty)({property:c,defaultValue:!1}),[m,f]=(0,a.useDefinitionProperty)({property:d,defaultValue:"🙂"}),[h,b]=(0,a.useDefinitionProperty)({property:u,defaultValue:vt.colorsPalette["color-tv-blue-a600"]}),[v]=(0,a.useDefinitionProperty)({property:i.disabled,defaultValue:!1}),y=e.disabled||!p;return o.createElement(l.CommonSection,{id:t,offset:s,checked:c,title:n,solutionId:r,disabled:e.disabled||v},o.createElement(yt.EmojiPicker,{value:m,disabled:y,onSelect:f}),o.createElement(F.ColorSelect,{className:gt.colorSelect,disabled:y,color:function(){if("mixed"===h)return h;return(0,A.rgbToHexString)((0,A.parseRgb)(h))}(),opacity:h&&"mixed"!==h?(0,A.parseRgba)(h)[3]:void 0,onColorChange:function(e){const t=h&&"mixed"!==h?(0,W.alphaToTransparency)((0,A.parseRgba)(h)[3]):0;b((0,W.generateColor)(String(e),t,!0))},onOpacityChange:function(e){b((0,W.generateColor)(h,(0,W.alphaToTransparency)(e),!0))}}))}function wt(e){const{definition:{id:t,properties:{disabled:n,visible:i},childrenDefinitions:r,title:s},offset:c}=e,[d]=(0,a.useDefinitionProperty)({property:n,defaultValue:!1}),[u]=(0,a.useDefinitionProperty)({property:i,defaultValue:!0}),p=e.disabled;return u?o.createElement(o.Fragment,null,s&&o.createElement(l.CommonSection,{id:t,offset:c,title:s,disabled:e.disabled||d}),r.map((e=>o.createElement(Ot,{key:e.id,disabled:p,definition:e,offset:e.offset??Boolean(s)})))):null}var Ct=n(38528),Dt=n(36104),St=n(3343),Vt=n(26597),Pt=n(59054),Nt=n(50238),kt=n(16396),xt=n(15294),Tt=n(40638)
|
||||
;function It(e){const{isDisabled:t,hint:n,label:i,isChecked:r,checkboxClassName:a,labelClassName:l,indeterminate:s,isActive:d,checkboxTabIndex:u,checkboxReference:p,checkboxDataRole:m,checkboxDataName:f,...h}=e;return o.createElement(kt.PopupMenuItem,{...h,isDisabled:t,shortcut:n,dontClosePopup:!0,labelRowClassName:l,label:o.createElement(xt.Checkbox,{reference:p,disabled:t,label:i,checked:r,indeterminate:s,className:c(Tt.checkbox,a),tabIndex:u,"data-role":m,"data-name":f})})}var Mt=n(13631);function _t(e){const[t,n]=(0,Nt.useRovingTabindexElement)(null);return o.createElement(It,{...e,className:Mt.item,checkboxClassName:Mt.checkbox,checkboxReference:t,checkboxTabIndex:n,checkboxDataRole:"menuitem",onKeyDown:function(e){const n=(0,St.hashFromEvent)(e);13!==n&&32!==n||(e.preventDefault(),t.current instanceof HTMLElement&&t.current.click())},"aria-disabled":e.isDisabled||void 0})}var Bt=n(20243),Lt=n(1774);function Rt(e){return!e.readonly&&!e.disabled}function At(e){const{selectedItems:t,placeholder:n}=e;if(!t.length)return o.createElement("span",null,n);const i=t.map((e=>e.selectedContent??e.content??e.value?.toString())).reduce(((e,t,n)=>t?(e.push(o.createElement("span",{key:n,className:Lt.contentPart},t)),e.push(o.createElement("span",{key:`separator_${n}`},","," ")),e):e),[]);return i.length&&i.splice(-1),o.createElement("span",{className:Lt.btnContent},i)}function Ft(e,t){const{id:n,items:i,menuClassName:r,menuItemClassName:a,tabIndex:l,disabled:s,highlight:c,intent:d,hideArrowButton:p,placeholder:m,value:f,"aria-labelledby":h,onFocus:b,onBlur:v,onClick:y,onChange:g,onKeyDown:E,openMenuOnEnter:w=!0,"aria-describedby":C,"aria-invalid":D,...S}=e,{listboxId:V,isOpened:P,isFocused:N,buttonTabIndex:k,highlight:x,intent:T,open:I,onOpen:M,close:_,toggle:B,buttonFocusBindings:L,onButtonClick:R,buttonRef:A,listboxRef:F,listboxTabIndex:W,buttonAria:z}=(0,Dt.useControlDisclosure)({id:n,disabled:s,buttonTabIndex:l,intent:d,highlight:c,onFocus:b,onBlur:v,onClick:y}),G=i.filter(Rt).filter((e=>f.some((t=>e.value===t)))),O=(0,u.joinDomIds)(h,n),H=O.length>0?O:void 0,J=(0,o.useMemo)((()=>({role:"listbox","aria-labelledby":h})),[h]),Z=(0,Vt.useKeyboardToggle)(B,P||w),j=(0,Vt.useKeyboardOpen)(P,I),K=(0,Vt.useKeyboardEventHandler)([Z,j]),U=(0,Ct.useMergedRefs)([A,t]);return o.createElement(Pt.ControlDisclosureView,{...S,...z,...L,id:n,role:"button",tabIndex:k,"aria-owns":z["aria-controls"],"aria-haspopup":"listbox","aria-labelledby":H,disabled:s,hideArrowButton:p,isFocused:N,isOpened:P,highlight:x,intent:T,ref:U,onClick:R,onClose:_,onKeyDown:K,onOpen:M,listboxTabIndex:W,listboxId:V,listboxClassName:r,listboxAria:J,"aria-describedby":C,"aria-invalid":D,listboxReference:F,onListboxKeyDown:function(e){switch((0,St.hashFromEvent)(e)){case 27:case 9:return void(P&&(e.preventDefault(),_()))}(0,Bt.handleAccessibleMenuKeyDown)(e)},onListboxFocus:e=>(0,Bt.handleAccessibleMenuFocus)(e,A),buttonChildren:o.createElement(At,{selectedItems:G??null,placeholder:m})},i.map(((e,t)=>{if(e.readonly)return o.createElement(o.Fragment,{
|
||||
key:`readonly_item_${t}`},e.content);const i=function(e,t){return t?.id??(0,u.createDomId)(e,"item",t?.value)}(n,e);return o.createElement(_t,{key:i,id:i,className:a,"aria-selected":f===e.value,isChecked:f.includes(e.value),label:e.content??e.value?.toString()??"",onClick:()=>function(e){const t=new Set(f);t.has(e)?t.delete(e):t.add(e);g(Array.from(t))}(e.value),isDisabled:e.disabled})})))}Ft.displayName="Multiselect";const Wt=o.forwardRef(Ft);var zt=n(74782);function Gt(e){const{definition:t}=e,{checked:r,checkableListOptions:l,definitions:s}=t,[c,d]=(0,o.useState)(y()),[u]=(0,a.useDefinitionProperty)({property:r,defaultValue:!0});(0,o.useEffect)((()=>{const e={},t=()=>{const e=y();d(e)};return t(),l.forEach((n=>{n.properties.checked&&n.properties.checked?.subscribe(e,t)})),()=>{l.forEach((n=>{n.properties.checked&&n.properties.checked?.unsubscribe(e,t)}))}}),[t]);const p=[],m=[],f=[],h=[];s.value().forEach((e=>{(0,i.isPropertyDefinition)(e)&&((0,i.isColorDefinition)(e)?p.push(e):(0,i.isTwoColorDefinition)(e)?m.push(e):(0,i.isLineDefinition)(e)?f.push(e):(0,i.isOptionsDefinition)(e)&&h.push(e))}));const v=!u||0===c.length;return o.createElement(o.Fragment,null,o.createElement(Me.PropertyTable.Row,null,o.createElement(rt.CheckableTitle,{name:`is-enabled-${t.id}`,title:t.title,property:r}),o.createElement(Me.PropertyTable.Cell,{placement:"last"},o.createElement("div",{className:zt.wrap},o.createElement(Wt,{className:zt.select,placeholder:O.t(null,void 0,n(8854)),disabled:!u,onChange:function(e){const t=new Set(e);l.forEach((e=>{!t.has(e.id)||e.properties.checked?.value()?!t.has(e.id)&&e.properties.checked?.value()&&e.properties.checked.setValue(!1):(0,b.ensureDefined)(e.properties.checked).setValue(!0)}))},value:c,matchButtonAndListboxWidths:!0,items:l.map((e=>({id:e.id,content:e.notFormatedTitle?o.createElement("span",{className:zt.preContent},(0,b.ensureDefined)(e.title)):(0,b.ensureDefined)(e.title),value:e.id})))}),p.length||f.length?o.createElement("div",{className:zt.colorsWrap},f.map((e=>o.createElement(G,{key:e.id,color:(0,b.ensureDefined)(e.properties.color),thickness:e.properties.width,thicknessItems:e.widthValues,disabled:v}))),p.map((e=>o.createElement(ae,{key:e.id,color:e.properties.color,disabled:v})))):null,m.length?m.map((e=>o.createElement("div",{key:e.id,className:zt.colorsWrap},o.createElement(ae,{color:e.properties.color1,disabled:v,noAlpha:e.noAlpha1}),o.createElement(ae,{color:e.properties.color2,disabled:v,noAlpha:e.noAlpha2})))):null))),h.map((e=>o.createElement(Me.PropertyTable.Row,{key:e.id},o.createElement(Me.PropertyTable.Cell,{placement:"first"}),o.createElement(Me.PropertyTable.Cell,{placement:"last"},o.createElement(de,{className:zt.select,property:e.properties.option,options:e.options,disabled:v}))))));function y(){return l.filter((e=>(0,b.ensureDefined)(e.properties?.checked).value())).map((e=>e.id))}}function Ot(e){const{definition:t,offset:n,disabled:a}=e;if(function(e){(0,o.useEffect)((()=>{if(void 0===e)return;const t={...e.properties};return Object.entries(t).forEach((([n,o])=>{
|
||||
void 0!==o&&o.subscribe(t,(()=>Ye.logger.logNormal(`Property "${n}" in definition "${e.id}" was updated to value "${o.value()}"`)))})),()=>{Object.entries(t).forEach((([,e])=>{e?.unsubscribeAll(t)}))}}),[e])}((0,i.isPropertyDefinitionsGroup)(t)?void 0:t),(0,i.isPropertyDefinitionsGroup)(t))return o.createElement(Ht,{definition:t,offset:n,disabled:a});switch(t.propType){case"line":return o.createElement(re,{...e,definition:t});case"checkable":return o.createElement(s,{...e,definition:t});case"color":return o.createElement(he,{...e,definition:t});case"transparency":return o.createElement(ye,{...e,definition:t});case"twoColors":return o.createElement(Ee,{...e,definition:t});case"optionalTwoColors":return o.createElement(mt,{...e,definition:t});case"fourColors":case"session":case"soundSelect":case"soundVolume":case"image":default:return null;case"number":return o.createElement(De,{...e,definition:t});case"symbol":return o.createElement(r.SymbolInputsButton,{...e,definition:t});case"text":return o.createElement(ze,{...e,definition:t});case"checkableSet":return o.createElement(Se,{...e,definition:t});case"set":return o.createElement(wt,{...e,definition:t});case"options":return o.createElement(Xe,{...e,definition:t});case"range":return o.createElement(ot,{...e,definition:t});case"coordinates":case"selectionCoordinates":return o.createElement(Ze,{...e,definition:t});case"twoOptions":return o.createElement(ut,{...e,definition:t});case"leveledLine":return o.createElement(st,{...e,definition:t});case"emoji":return o.createElement(Et,{...e,definition:t});case"studyInputs":return o.createElement(bt,{...e,definition:t})}}function Ht(e){const{definition:t}=e,n=(0,oe.useWatchedValueReadonly)({watchedValue:t.definitions});return(0,oe.useWatchedValueReadonly)({watchedValue:t.visible,defaultValue:!0})?(0,i.isCheckableListOptionsDefinition)(t)?o.createElement(Gt,{definition:t}):o.createElement(o.Fragment,null,t.title&&o.createElement(it.GroupTitleSection,{title:t.title,name:t.id}),n&&function(e){const t=[];return e.reduce(((e,t)=>{if((0,i.isPropertyDefinitionsGroup)(t)||"leveledLine"!==t.propType)e.push(t);else{const n=e[e.length-1];Array.isArray(n)?n.push(t):e.push([t])}return e}),t)}(n).map((n=>Array.isArray(n)?o.createElement(lt,{key:n[0].id,name:t.id,definitions:n}):o.createElement(Ot,{key:n.id,...e,definition:n}))),"general"===t.groupType&&o.createElement(Me.PropertyTable.GroupSeparator,{size:1})):null}},95276:(e,t,n)=>{"use strict";n.d(t,{ControlDisclosure:()=>d});var o=n(50959),i=n(38528),r=n(26597),a=n(59054),l=n(36104),s=n(68335),c=n(99505);const d=o.forwardRef(((e,t)=>{const{id:n,tabIndex:d,disabled:u,highlight:p,intent:m,children:f,onClick:h,onFocus:b,onBlur:v,listboxAria:y,onListboxKeyDown:g,...E}=e,w=(0,o.useRef)({"aria-labelledby":n}),{listboxId:C,isOpened:D,isFocused:S,buttonTabIndex:V,listboxTabIndex:P,highlight:N,intent:k,onOpen:x,close:T,toggle:I,buttonFocusBindings:M,onButtonClick:_,buttonRef:B,listboxRef:L,buttonAria:R}=(0,l.useControlDisclosure)({id:n,disabled:u,buttonTabIndex:d,intent:m,highlight:p,onFocus:b,
|
||||
onBlur:v,onClick:h}),A=(0,r.useKeyboardToggle)(I),F=(0,r.useKeyboardClose)(D,T),W=(0,r.useKeyboardEventHandler)([A,F]);return o.createElement(a.ControlDisclosureView,{...E,...M,...R,id:n,role:"button",tabIndex:V,disabled:u,isOpened:D,isFocused:S,ref:(0,i.useMergedRefs)([B,t]),highlight:N,intent:k,onClose:T,onOpen:x,onClick:_,onKeyDown:W,listboxId:C,listboxTabIndex:P,listboxReference:L,listboxAria:y??w.current,onListboxKeyDown:function(e){if(27===(0,s.hashFromEvent)(e))return e.preventDefault(),void T();g?.(e)}},f,o.createElement("span",{className:c.invisibleFocusHandler,tabIndex:0,"aria-hidden":!0,onFocus:()=>T()}))}));d.displayName="ControlDisclosure"},82930:(e,t,n)=>{"use strict";n.d(t,{EmojiPicker:()=>x});var o=n(50959),i=n(56840),r=n(38297),a=n(43790),l=n(173);var s=n(20520),c=n(37558),d=n(41590),u=n(27317),p=n(3343),m=n(40173),f=n(90692);function h(e){!function(e,t){(0,o.useEffect)((()=>{const n=t||document;return n.addEventListener("scroll",e),()=>n.removeEventListener("scroll",e)}),[e])}(e,document)}var b=n(78135),v=n(24437),y=n(97754),g=n.n(y),E=n(10555);function w(e){const{children:t,highlight:n,disabled:i,reference:r,...a}=e,l=n?"primary":"default";return o.createElement("div",{...a,ref:r,className:g()(E.wrapper,E[`intent-${l}`],E["border-thin"],E["size-medium"],n&&E.highlight,n&&E.focused,i&&E.disabled),"data-role":"button"},o.createElement("div",{className:g()(E.childrenContainer,i&&E.disabled)},t),n&&o.createElement("span",{className:E.shadow}))}var C=n(88160),D=n(27061);const S=()=>null,V=(0,m.mergeThemes)(u.DEFAULT_MENU_THEME,{menuBox:D.menuBox}),P=378,N=18,k=200;function x(e){const{value:t,disabled:n,onSelect:a,onClose:u,canBeEmpty:m,renderButton:y=T}=e,g=(0,o.useRef)(null),{current:E}=(0,o.useRef)((w=t,i.getJSON("RecentlyUsedEmojis",[w]).filter((e=>e!==C.EMPTY_EMOJI))));var w;const x=(0,o.useRef)(null),[I,M]=(0,o.useState)(E),[_,B]=(0,o.useState)(!1),L=(0,o.useCallback)((()=>{B(!1),u?.()}),[u]),R=(0,o.useRef)(0);h((0,o.useCallback)((()=>{Date.now()-R.current<k||L()}),[L]));const A=(0,o.useCallback)((e=>{if(e!==C.EMPTY_EMOJI){const t=Array.from(new Set([e,...I])).slice(0,N);i.setJSON("RecentlyUsedEmojis",t),M(t)}a(e),L()}),[I,a]),F=(0,o.useMemo)((()=>m?[C.EMPTY_EMOJI,...I].slice(0,N):I),[I,m]),W=(z=F,(0,o.useMemo)((()=>{const e=(0,l.emojiGroups)();return e[0].emojis=z,e}),[z]));var z;return o.createElement(o.Fragment,null,o.createElement("div",{ref:g,className:D.buttonWrap},y({emoji:t,isOpened:_,disabled:n,onClick:function(){if(_)return void L();n||(B(!0),R.current=Date.now())}})),o.createElement(f.MatchMedia,{rule:v.DialogBreakpoints.TabletSmall},(e=>_&&o.createElement(c.DrawerManager,null,e?o.createElement(d.Drawer,{className:D.drawer,position:"Bottom",onClose:L},o.createElement(r.EmojiList,{emojis:W,onSelect:A,height:P})):o.createElement(s.PopupMenu,{theme:V,onKeyDown:O,isOpened:!0,position:(0,b.getPopupPositioner)(g.current,{horizontalDropDirection:b.HorizontalDropDirection.FromLeftToRight,horizontalAttachEdge:b.HorizontalAttachEdge.Left}),closeOnClickOutside:!1,onClickOutside:H,onClose:S,
|
||||
controller:x,onOpen:G,tabIndex:-1},o.createElement(r.EmojiList,{className:D.desktopSize,emojis:W,onSelect:A,height:P}))))));function G(){x.current?.focus()}function O(e){27===(0,p.hashFromEvent)(e)&&(e.preventDefault(),e.stopPropagation(),L())}function H(e){const t=e.target;t instanceof Node&&g.current?.contains(t)||L()}}function T(e){const{emoji:t,isOpened:n,disabled:i,onClick:r}=e;return o.createElement(w,{highlight:n,disabled:i,"data-name":"emoji-picker"},o.createElement(a.EmojiWrap,{emoji:t,onClick:r}))}},96040:(e,t,n)=>{"use strict";n.d(t,{RemoveButton:()=>u});var o=n(11542),i=n(50959),r=n(97754),a=n.n(r),l=n(9745),s=n(74670),c=n(33765),d=n(35990);function u(e){const{className:t,isActive:r,onClick:u,onMouseDown:p,title:m,hidden:f,"data-name":h="remove-button",icon:b,...v}=e,[y,g]=(0,s.useActiveDescendant)(null);return i.createElement(l.Icon,{...v,"data-name":h,className:a()(d.button,"apply-common-tooltip",r&&d.active,f&&d.hidden,g&&d.focused,t),icon:b||c,onClick:u,onMouseDown:p,title:m??o.t(null,void 0,n(67410)),ariaLabel:m??o.t(null,void 0,n(67410)),ref:y})}},13631:e=>{e.exports={checkbox:"checkbox-hcyAOCXc",item:"item-hcyAOCXc"}},20243:(e,t,n)=>{"use strict";n.d(t,{focusFirstMenuItem:()=>d,handleAccessibleMenuFocus:()=>s,handleAccessibleMenuKeyDown:()=>c,queryMenuElements:()=>m});var o=n(19291),i=n(57177),r=n(68335),a=n(15754);const l=[37,39,38,40];function s(e,t){if(!e.target)return;const n=e.relatedTarget?.getAttribute("aria-activedescendant");if(e.relatedTarget!==t.current){const e=n&&document.getElementById(n);if(!e||e!==t.current)return}d(e.target)}function c(e){if(e.defaultPrevented)return;const t=(0,r.hashFromEvent)(e);if(!l.includes(t))return;const n=document.activeElement;if(!(document.activeElement instanceof HTMLElement))return;const a=m(e.currentTarget).sort(o.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 d=f(s),h=d.indexOf(document.activeElement),b=-1!==h,v=e=>{n&&(0,i.becomeSecondaryElement)(n),(0,i.becomeMainElement)(e),e.focus()};switch((0,o.mapKeyCodeToDirection)(t)){case"inlinePrev":if(!d.length)return;e.preventDefault(),v(0===h?a[c]:b?u(d,h,-1):d[d.length-1]);break;case"inlineNext":if(!d.length)return;e.preventDefault(),h===d.length-1?v(a[c]):v(b?u(d,h,1):d[0]);break;case"blockPrev":{e.preventDefault();const t=u(a,c,-1);if(b){const e=p(t,h);v(e||t);break}v(t);break}case"blockNext":{e.preventDefault();const t=u(a,c,1);if(b){const e=p(t,h);v(e||t);break}v(t)}}}function d(e){const[t]=m(e);t&&((0,i.becomeMainElement)(t),t.focus())}function u(e,t,n){return e[(t+e.length+n)%e.length]}function p(e,t){const n=f(e);return n.length?n[(t+n.length)%n.length]:null}function m(e){return Array.from(e.querySelectorAll('[data-role="menuitem"]:not([disabled]):not([aria-disabled])')).filter((0,a.createScopedVisibleElementFilter)(e))}function f(e){
|
||||
return Array.from(e.querySelectorAll("[tabindex]:not([disabled]):not([aria-disabled])")).filter((0,a.createScopedVisibleElementFilter)(e))}},78135:(e,t,n)=>{"use strict";n.d(t,{HorizontalAttachEdge:()=>i,HorizontalDropDirection:()=>a,VerticalAttachEdge:()=>o,VerticalDropDirection:()=>r,getPopupPositioner:()=>c});var o,i,r,a,l=n(50151);!function(e){e[e.Top=0]="Top",e[e.Bottom=1]="Bottom",e[e.AutoStrict=2]="AutoStrict"}(o||(o={})),function(e){e[e.Left=0]="Left",e[e.Right=1]="Right"}(i||(i={})),function(e){e[e.FromTopToBottom=0]="FromTopToBottom",e[e.FromBottomToTop=1]="FromBottomToTop"}(r||(r={})),function(e){e[e.FromLeftToRight=0]="FromLeftToRight",e[e.FromRightToLeft=1]="FromRightToLeft"}(a||(a={}));const s={verticalAttachEdge:o.Bottom,horizontalAttachEdge:i.Left,verticalDropDirection:r.FromTopToBottom,horizontalDropDirection:a.FromLeftToRight,verticalMargin:0,horizontalMargin:0,matchButtonAndListboxWidths:!1};function c(e,t){return n=>{const{contentWidth:c,contentHeight:d,availableHeight:u}=n,p=(0,l.ensureNotNull)(e).getBoundingClientRect(),{horizontalAttachEdge:m=s.horizontalAttachEdge,horizontalDropDirection:f=s.horizontalDropDirection,horizontalMargin:h=s.horizontalMargin,verticalMargin:b=s.verticalMargin,matchButtonAndListboxWidths:v=s.matchButtonAndListboxWidths}=t;let y=t.verticalAttachEdge??s.verticalAttachEdge,g=t.verticalDropDirection??s.verticalDropDirection;y===o.AutoStrict&&(u<p.y+p.height+b+d?(y=o.Top,g=r.FromBottomToTop):(y=o.Bottom,g=r.FromTopToBottom));const E=y===o.Top?-1*b:b,w=m===i.Right?p.right:p.left,C=y===o.Top?p.top:p.bottom,D={x:w-(f===a.FromRightToLeft?c:0)+h,y:C-(g===r.FromBottomToTop?d:0)+E};return v&&(D.overrideWidth=p.width),D}}},23351:(e,t,n)=>{"use strict";n.d(t,{convertToDefinitionProperty:()=>r,makeProxyDefinitionProperty:()=>i});var o=n(51768);function i(e,t,n){const o=new Map,i=void 0!==t?t[0]:e=>e,r=void 0!==t?void 0!==t[1]?t[1]:t[0]:e=>e,a={value:()=>i(e.value()),setValue:t=>{e.setValue(r(t))},subscribe:(t,n)=>{const i=e=>{n(a)};o.set(n,i),e.subscribe(t,i)},unsubscribe:(t,n)=>{const i=o.get(n);i&&(e.unsubscribe(t,i),o.delete(n))},unsubscribeAll:t=>{e.unsubscribeAll(t),o.clear()},destroy:()=>{e.release(),n?.()}};return a}function r(e,t,n,r,a,l,s){const c=i(t.weakReference(),r,l),d=void 0!==r?void 0!==r[1]?r[1]:r[0]:e=>e,u=a??(o=>e.setProperty(t,d(o),n));return c.setValue=e=>{s&&(0,o.trackEvent)(s.category,s.event,s.label?.(e)),u(e)},c}},59411:(e,t,n)=>{"use strict";n.d(t,{createLinePropertyDefinition:()=>s});var o=n(49857),i=n(51056);const r=[i.LINESTYLE_SOLID,i.LINESTYLE_DOTTED,i.LINESTYLE_DASHED],a=[1,2,3,4],l=[o.LineEnd.Normal,o.LineEnd.Arrow];function s(e,t){const n={propType:"line",properties:e,...t};return void 0!==n.properties.style&&(n.styleValues=r),void 0!==n.properties.width&&(n.widthValues=a),void 0===n.properties.leftEnd&&void 0===n.properties.rightEnd||void 0!==n.endsValues||(n.endsValues=l),void 0!==n.properties.value&&void 0===n.valueType&&(n.valueType=1),n}},14608:(e,t,n)=>{"use strict";var o;function i(e,t){return{propType:"number",properties:e,type:1,...t}}
|
||||
n.d(t,{createNumberPropertyDefinition:()=>i}),function(e){e[e.Integer=0]="Integer",e[e.Float=1]="Float"}(o||(o={}))},14139:(e,t,n)=>{"use strict";function o(e,t){return{propType:"options",properties:e,...t}}n.d(t,{createOptionsPropertyDefinition:()=>o})},32097:(e,t,n)=>{"use strict";function o(e,t){return{propType:"checkable",properties:e,notFormatedTitle:!1,...t}}function i(e,t,n){return{propType:"checkableSet",properties:e,childrenDefinitions:n,...t}}function r(e,t){return{propType:"color",properties:e,noAlpha:!1,...t}}n.d(t,{convertFromReadonlyWVToDefinitionProperty:()=>H,convertFromWVToDefinitionProperty:()=>O,convertToDefinitionProperty:()=>z.convertToDefinitionProperty,createCheckablePropertyDefinition:()=>o,createCheckableSetPropertyDefinition:()=>i,createColorPropertyDefinition:()=>r,createCoordinatesPropertyDefinition:()=>N,createEmojiPropertyDefinition:()=>B,createImagePropertyDefinition:()=>_,createLeveledLinePropertyDefinition:()=>d,createLinePropertyDefinition:()=>a.createLinePropertyDefinition,createNumberPropertyDefinition:()=>u.createNumberPropertyDefinition,createOptionalTwoColorsPropertyDefinition:()=>P,createOptionsPropertyDefinition:()=>p.createOptionsPropertyDefinition,createPropertyDefinitionsCheckableListOptionsGroup:()=>F,createPropertyDefinitionsGeneralGroup:()=>A,createPropertyDefinitionsLeveledLinesGroup:()=>W,createRangePropertyDefinition:()=>x,createSelectionCoordinatesPropertyDefinition:()=>k,createSessionPropertyDefinition:()=>M,createStudyInputsPropertyDefinition:()=>L,createSymbolPropertyDefinition:()=>I,createTextPropertyDefinition:()=>S,createTransparencyPropertyDefinition:()=>T,createTwoColorsPropertyDefinition:()=>V,createTwoOptionsPropertyDefinition:()=>m,destroyDefinitions:()=>ae,getColorDefinitionProperty:()=>$,getLockPriceScaleDefinitionProperty:()=>Z,getPriceScaleSelectionStrategyDefinitionProperty:()=>J,getScaleRatioDefinitionProperty:()=>j,getSymbolDefinitionProperty:()=>q,isCheckableListOptionsDefinition:()=>re,isColorDefinition:()=>ne,isLineDefinition:()=>te,isOptionsDefinition:()=>ie,isPropertyDefinition:()=>Q,isPropertyDefinitionsGroup:()=>ee,isTwoColorDefinition:()=>oe,makeProxyDefinitionProperty:()=>z.makeProxyDefinitionProperty});var a=n(59411),l=n(51056);const s=[l.LINESTYLE_SOLID,l.LINESTYLE_DOTTED,l.LINESTYLE_DASHED],c=[1,2,3,4];function d(e,t){const n={propType:"leveledLine",properties:e,...t};return void 0!==n.properties.style&&(n.styleValues=s),void 0!==n.properties.width&&(n.widthValues=c),n}var u=n(14608),p=n(14139);function m(e,t){return{propType:"twoOptions",properties:e,...t}}var f,h=n(11542),b=n(30699);!function(e){e.Horizontal="horizontal",e.Vertical="vertical"}(f||(f={}));const v=[{id:b.VerticalAlign.Top,value:b.VerticalAlign.Bottom,title:h.t(null,void 0,n(97118))},{id:b.VerticalAlign.Middle,value:b.VerticalAlign.Middle,title:h.t(null,void 0,n(68833))},{id:b.VerticalAlign.Bottom,value:b.VerticalAlign.Top,title:h.t(null,void 0,n(27567))}],y=[{id:b.HorizontalAlign.Left,value:b.HorizontalAlign.Left,title:h.t(null,void 0,n(11626))},{
|
||||
id:b.HorizontalAlign.Center,value:b.HorizontalAlign.Center,title:h.t(null,void 0,n(24197))},{id:b.HorizontalAlign.Right,value:b.HorizontalAlign.Right,title:h.t(null,void 0,n(50421))}],g=[{id:"horizontal",value:"horizontal",title:h.t(null,void 0,n(95406))},{id:"vertical",value:"vertical",title:h.t(null,void 0,n(69526))}],E=[8,10,11,12,14,16,18,20,22,24,28,32,40].map((e=>({title:String(e),value:e}))),w=[1,2,3,4],C=h.t(null,void 0,n(25485)),D=h.t(null,void 0,n(67781));function S(e,t){const n={propType:"text",properties:e,...t,isEditable:t.isEditable||!1};return void 0!==n.properties.size&&void 0===n.sizeItems&&(n.sizeItems=E),void 0!==n.properties.alignmentVertical&&void 0===n.alignmentVerticalItems&&(n.alignmentVerticalItems=v),void 0!==n.properties.alignmentHorizontal&&void 0===n.alignmentHorizontalItems&&(n.alignmentHorizontalItems=y),(n.alignmentVerticalItems||n.alignmentHorizontalItems)&&void 0===n.alignmentTitle&&(n.alignmentTitle=C),void 0!==n.properties.orientation&&(void 0===n.orientationItems&&(n.orientationItems=g),void 0===n.orientationTitle&&(n.orientationTitle=D)),void 0!==n.properties.borderWidth&&void 0===n.borderWidthItems&&(n.borderWidthItems=w),n}function V(e,t){return{propType:"twoColors",properties:e,noAlpha1:!1,noAlpha2:!1,...t}}function P(e,t){return{propType:"optionalTwoColors",properties:e,noAlpha1:!1,noAlpha2:!1,...t}}function N(e,t){return{propType:"coordinates",properties:e,...t}}function k(e,t){return{propType:"selectionCoordinates",properties:e,...t}}function x(e,t){return{propType:"range",properties:e,...t}}function T(e,t){return{propType:"transparency",properties:e,...t}}function I(e,t){return{propType:"symbol",properties:e,...t}}function M(e,t){return{propType:"session",properties:e,...t}}function _(e,t){return{propType:"image",properties:e,...t}}function B(e,t){return{propType:"emoji",properties:e,...t}}function L(e,t){return{propType:"studyInputs",properties:e,...t}}var R=n(64147);function A(e,t,n,o){return{id:t,title:n,visible:o,groupType:"general",definitions:new R.WatchedValue(e)}}function F(e,t,n,o,i,r){return{id:o,title:i,visible:r,groupType:"checkableListOptions",checked:t,definitions:new R.WatchedValue(n),checkableListOptions:e}}function W(e,t,n){return{id:t,title:n,groupType:"leveledLines",definitions:new R.WatchedValue(e)}}var z=n(23351);function G(e,t,n){const o=new Map,i=void 0!==t?t[0]:e=>e,r=void 0!==t?void 0!==t[1]?t[1]:t[0]:e=>e,a={value:()=>i(e.value()),setValue:t=>{e.setValue?.(r(t))},subscribe:(t,n)=>{const i=()=>{n(a)};let r=o.get(t);void 0===r?(r=new Map,r.set(n,i),o.set(t,r)):r.set(n,i),e.subscribe(i)},unsubscribe:(t,n)=>{const i=o.get(t);if(void 0!==i){const t=i.get(n);void 0!==t&&(e.unsubscribe(t),i.delete(n))}},unsubscribeAll:t=>{const n=o.get(t);void 0!==n&&(n.forEach(((t,n)=>{e.unsubscribe(t)})),n.clear())}};return n&&(a.destroy=()=>n()),a}function O(e,t,n,o){const i=G(t,o),r=void 0!==o?void 0!==o[1]?o[1]:o[0]:e=>e;return i.setValue=o=>e.setWatchedValue(t,r(o),n),i}function H(e,t){return function(e,t,n,o){const i=new Map,r={subscribe:(n,o)=>{const r=e=>n(t(e))
|
||||
;i.set(n,r),e.subscribe(r,o)},unsubscribe:t=>{if(t){const n=i.get(t);n&&(e.unsubscribe(n),i.delete(t))}else i.clear(),e.unsubscribe()},value:()=>t(e.value())};return G(r,n,o)}(e,(e=>e),t,(()=>e.release()))}function J(e,t){const n=(0,z.makeProxyDefinitionProperty)(t.weakReference());return n.setValue=t=>e.setPriceScaleSelectionStrategy(t),n}function Z(e,t,n,o){const i=(0,z.makeProxyDefinitionProperty)(t.weakReference());return i.setValue=t=>{const i={lockScale:t};e.setPriceScaleMode(i,n,o)},i}function j(e,t,n,o){const i=(0,z.makeProxyDefinitionProperty)(t.weakReference(),o);return i.setValue=o=>{e.setScaleRatioProperty(t,o,n)},i}var K=n(24377),U=n(19063),X=n(84425);function Y(e,t){if((0,U.isHexColor)(e)){const n=(0,K.parseRgb)(e);return(0,K.rgbaToString)((0,K.rgba)(n,(100-t)/100))}return e}function $(e,t,n,o,i){let r;if(null!==n){const e=(0,X.combineProperty)(Y,t.weakReference(),n.weakReference());r=(0,z.makeProxyDefinitionProperty)(e.ownership())}else r=(0,z.makeProxyDefinitionProperty)(t.weakReference(),[()=>Y(t.value(),0),e=>e]);return r.setValue=n=>{i&&e.beginUndoMacro(o),e.setProperty(t,n,o),i&&e.endUndoMacro()},r}function q(e,t,n,o,i,r){const a=[(l=n,s=t,e=>{const t=l(s);if(e===s.value()&&null!==t){const e=t.ticker||t.full_name;if(e)return e}return e}),e=>e];var l,s;const c=(0,z.convertToDefinitionProperty)(e,t,i,a);r&&(c.setValue=r);const d=new Map;c.subscribe=(e,n)=>{const o=e=>{n(c)};d.set(n,o),t.subscribe(e,o)},c.unsubscribe=(e,n)=>{const o=d.get(n);o&&(t.unsubscribe(e,o),d.delete(n))};const u={};return o.subscribe(u,(()=>{d.forEach(((e,t)=>{t(c)}))})),c.destroy=()=>{o.unsubscribeAll(u),d.clear()},c}function Q(e){return e.hasOwnProperty("propType")}function ee(e){return e.hasOwnProperty("groupType")}function te(e){return"line"===e.propType}function ne(e){return"color"===e.propType}function oe(e){return"twoColors"===e.propType}function ie(e){return"options"===e.propType}function re(e){return"checkableListOptions"===e.groupType}function ae(e){e.forEach((e=>{if(Q(e)){Object.keys(e.properties).forEach((t=>{const n=e.properties[t];void 0!==n&&void 0!==n.destroy&&n.destroy()}))}else ae(e.definitions.value()),e.visible?.destroy()}))}},60925:e=>{e.exports='<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 18 18" width="18" height="18"><path fill="currentColor" d="M12 4h3v1h-1.04l-.88 9.64a1.5 1.5 0 0 1-1.5 1.36H6.42a1.5 1.5 0 0 1-1.5-1.36L4.05 5H3V4h3v-.5C6 2.67 6.67 2 7.5 2h3c.83 0 1.5.67 1.5 1.5V4ZM7.5 3a.5.5 0 0 0-.5.5V4h4v-.5a.5.5 0 0 0-.5-.5h-3ZM5.05 5l.87 9.55a.5.5 0 0 0 .5.45h5.17a.5.5 0 0 0 .5-.45L12.94 5h-7.9Z"/></svg>'},44996:e=>{e.exports='<svg xmlns="http://www.w3.org/2000/svg" width="28" height="28" fill="none"><path fill="currentColor" fillRule="evenodd" clipRule="evenodd" d="M7.5 13a1.5 1.5 0 1 0 0 3 1.5 1.5 0 0 0 0-3zM5 14.5a2.5 2.5 0 1 1 5 0 2.5 2.5 0 0 1-5 0zm9.5-1.5a1.5 1.5 0 1 0 0 3 1.5 1.5 0 0 0 0-3zM12 14.5a2.5 2.5 0 1 1 5 0 2.5 2.5 0 0 1-5 0zm9.5-1.5a1.5 1.5 0 1 0 0 3 1.5 1.5 0 0 0 0-3zM19 14.5a2.5 2.5 0 1 1 5 0 2.5 2.5 0 0 1-5 0z"/></svg>'},33765:e=>{
|
||||
e.exports='<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18"><path fill="currentColor" d="M9.707 9l4.647-4.646-.707-.708L9 8.293 4.354 3.646l-.708.708L8.293 9l-4.647 4.646.708.708L9 9.707l4.646 4.647.708-.707L9.707 9z"/></svg>'},80427:e=>{e.exports='<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 28 28" width="28" height="28"><path fill="currentColor" d="M23 8H5V7h18v1ZM9 14H5v-1h4v1Zm3 0h4v-1h-4v1Zm11 0h-4v-1h4v1ZM7 19H5v2h2v-2Zm2 0h2v2H9v-2Zm6 0h-2v2h2v-2Zm2 0h2v2h-2v-2Zm6 0h-2v2h2v-2Z"/></svg>'},98853:e=>{e.exports='<svg xmlns="http://www.w3.org/2000/svg" width="28" height="28" fill="none"><path stroke="currentColor" d="M4.5 13.5H24m-19.5 0L8 17m-3.5-3.5L8 10"/></svg>'},43382:e=>{e.exports='<svg xmlns="http://www.w3.org/2000/svg" width="28" height="28" fill="none"><path stroke="currentColor" d="M8.5 13.5a2 2 0 1 1-4 0 2 2 0 0 1 4 0zm0 0H24"/></svg>'},8295:e=>{e.exports='<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 28 28" width="28" height="28"><path fill="currentColor" d="M14 21h-3a1 1 0 0 1-1-1V8a1 1 0 0 1 1-1h3c2 0 4 1 4 3 0 1 0 2-1.5 3 1.5.5 2.5 2 2.5 4 0 2.75-2.638 4-5 4zM12 9l.004 3c.39.026.82 0 1.25 0C14.908 12 16 11.743 16 10.5c0-1.1-.996-1.5-2.5-1.5-.397 0-.927-.033-1.5 0zm0 5v5h1.5c1.5 0 3.5-.5 3.5-2.5S15 14 13.5 14c-.5 0-.895-.02-1.5 0z"/></svg>'},29285:e=>{e.exports='<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 28 28" width="28" height="28"><path fill="currentColor" d="M12.143 20l1.714-12H12V7h5v1h-2.143l-1.714 12H15v1h-5v-1h2.143z"/></svg>'}}]);
|
||||
@@ -0,0 +1 @@
|
||||
.title-QPktCwTY{color:var(--themed-color-default-gray,#707070);cursor:default;font-size:11px;letter-spacing:.4px;line-height:16px;padding:10px 20px 8px;text-transform:uppercase}html.theme-dark .title-QPktCwTY{color:var(--themed-color-default-gray,#8c8c8c)}.container-QPktCwTY{padding:12px 20px;--ui-lib-round-tabs-hor-padding:0}.mobile-QPktCwTY{--ui-lib-round-tabs-hor-padding:20px}.empty-QPktCwTY{align-items:center;color:var(--themed-color-empty-state-text,#1a1a1a);cursor:default;display:flex;flex:1 1;flex-direction:column;font-size:16px;justify-content:center;line-height:24px}html.theme-dark .empty-QPktCwTY{color:var(--themed-color-empty-state-text,#dbdbdb)}.empty-QPktCwTY .image-QPktCwTY{height:72px;margin-bottom:8px;width:72px}.spinner-QPktCwTY{margin-top:-12px}.contentList-QPktCwTY{min-width:100%}@media (min-width:480px){.contentList-QPktCwTY{width:380px}}.item-QPktCwTY{flex-shrink:0}
|
||||
@@ -0,0 +1 @@
|
||||
.title-QPktCwTY{color:var(--themed-color-default-gray,#707070);cursor:default;font-size:11px;letter-spacing:.4px;line-height:16px;padding:10px 20px 8px;text-transform:uppercase}html.theme-dark .title-QPktCwTY{color:var(--themed-color-default-gray,#8c8c8c)}.container-QPktCwTY{padding:12px 20px;--ui-lib-round-tabs-hor-padding:0}.mobile-QPktCwTY{--ui-lib-round-tabs-hor-padding:20px}.empty-QPktCwTY{align-items:center;color:var(--themed-color-empty-state-text,#1a1a1a);cursor:default;display:flex;flex:1 1;flex-direction:column;font-size:16px;justify-content:center;line-height:24px}html.theme-dark .empty-QPktCwTY{color:var(--themed-color-empty-state-text,#dbdbdb)}.empty-QPktCwTY .image-QPktCwTY{height:72px;margin-bottom:8px;width:72px}.spinner-QPktCwTY{margin-top:-12px}.contentList-QPktCwTY{min-width:100%}@media (min-width:480px){.contentList-QPktCwTY{width:380px}}.item-QPktCwTY{flex-shrink: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,12 @@
|
||||
(self.webpackChunktradingview=self.webpackChunktradingview||[]).push([[3746],{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},33849: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)},55698:(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?"-":"_"),"")}}]);
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
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,4 @@
|
||||
"use strict";(self.webpackChunktradingview=self.webpackChunktradingview||[]).push([[3889],{57717:(e,t,i)=>{i.r(t),i.d(t,{createPropertyPage:()=>o});var r=i(64147);function o(e,t,i,o=null){const n={id:t,title:i,definitions:new r.WatchedValue(e.definitions),visible:e.visible??new r.WatchedValue(!0).readonly()};return null!==o&&(n.icon=o),n}},23351:(e,t,i)=>{i.d(t,{convertToDefinitionProperty:()=>n,makeProxyDefinitionProperty:()=>o});var r=i(51768);function o(e,t,i){const r=new Map,o=void 0!==t?t[0]:e=>e,n=void 0!==t?void 0!==t[1]?t[1]:t[0]:e=>e,s={value:()=>o(e.value()),setValue:t=>{e.setValue(n(t))},subscribe:(t,i)=>{const o=e=>{i(s)};r.set(i,o),e.subscribe(t,o)},unsubscribe:(t,i)=>{const o=r.get(i);o&&(e.unsubscribe(t,o),r.delete(i))},unsubscribeAll:t=>{e.unsubscribeAll(t),r.clear()},destroy:()=>{e.release(),i?.()}};return s}function n(e,t,i,n,s,p,l){const a=o(t.weakReference(),n,p),c=void 0!==n?void 0!==n[1]?n[1]:n[0]:e=>e,u=s??(r=>e.setProperty(t,c(r),i));return a.setValue=e=>{l&&(0,r.trackEvent)(l.category,l.event,l.label?.(e)),u(e)},a}},59411:(e,t,i)=>{i.d(t,{createLinePropertyDefinition:()=>l});var r=i(49857),o=i(51056);const n=[o.LINESTYLE_SOLID,o.LINESTYLE_DOTTED,o.LINESTYLE_DASHED],s=[1,2,3,4],p=[r.LineEnd.Normal,r.LineEnd.Arrow];function l(e,t){const i={propType:"line",properties:e,...t};return void 0!==i.properties.style&&(i.styleValues=n),void 0!==i.properties.width&&(i.widthValues=s),void 0===i.properties.leftEnd&&void 0===i.properties.rightEnd||void 0!==i.endsValues||(i.endsValues=p),void 0!==i.properties.value&&void 0===i.valueType&&(i.valueType=1),i}},14608:(e,t,i)=>{var r;function o(e,t){return{propType:"number",properties:e,type:1,...t}}i.d(t,{createNumberPropertyDefinition:()=>o}),function(e){e[e.Integer=0]="Integer",e[e.Float=1]="Float"}(r||(r={}))},14139:(e,t,i)=>{function r(e,t){return{propType:"options",properties:e,...t}}i.d(t,{createOptionsPropertyDefinition:()=>r})},32097:(e,t,i)=>{function r(e,t){return{propType:"checkable",properties:e,notFormatedTitle:!1,...t}}function o(e,t,i){return{propType:"checkableSet",properties:e,childrenDefinitions:i,...t}}function n(e,t){return{propType:"color",properties:e,noAlpha:!1,...t}}i.d(t,{convertFromReadonlyWVToDefinitionProperty:()=>G,convertFromWVToDefinitionProperty:()=>F,convertToDefinitionProperty:()=>_.convertToDefinitionProperty,createCheckablePropertyDefinition:()=>r,createCheckableSetPropertyDefinition:()=>o,createColorPropertyDefinition:()=>n,createCoordinatesPropertyDefinition:()=>S,createEmojiPropertyDefinition:()=>H,createImagePropertyDefinition:()=>z,createLeveledLinePropertyDefinition:()=>c,createLinePropertyDefinition:()=>s.createLinePropertyDefinition,createNumberPropertyDefinition:()=>u.createNumberPropertyDefinition,createOptionalTwoColorsPropertyDefinition:()=>L,createOptionsPropertyDefinition:()=>f.createOptionsPropertyDefinition,createPropertyDefinitionsCheckableListOptionsGroup:()=>M,createPropertyDefinitionsGeneralGroup:()=>W,createPropertyDefinitionsLeveledLinesGroup:()=>N,createRangePropertyDefinition:()=>I,
|
||||
createSelectionCoordinatesPropertyDefinition:()=>E,createSessionPropertyDefinition:()=>O,createStudyInputsPropertyDefinition:()=>R,createSymbolPropertyDefinition:()=>C,createTextPropertyDefinition:()=>V,createTransparencyPropertyDefinition:()=>A,createTwoColorsPropertyDefinition:()=>k,createTwoOptionsPropertyDefinition:()=>d,destroyDefinitions:()=>se,getColorDefinitionProperty:()=>X,getLockPriceScaleDefinitionProperty:()=>B,getPriceScaleSelectionStrategyDefinitionProperty:()=>j,getScaleRatioDefinitionProperty:()=>U,getSymbolDefinitionProperty:()=>Z,isCheckableListOptionsDefinition:()=>ne,isColorDefinition:()=>ie,isLineDefinition:()=>te,isOptionsDefinition:()=>oe,isPropertyDefinition:()=>$,isPropertyDefinitionsGroup:()=>ee,isTwoColorDefinition:()=>re,makeProxyDefinitionProperty:()=>_.makeProxyDefinitionProperty});var s=i(59411),p=i(51056);const l=[p.LINESTYLE_SOLID,p.LINESTYLE_DOTTED,p.LINESTYLE_DASHED],a=[1,2,3,4];function c(e,t){const i={propType:"leveledLine",properties:e,...t};return void 0!==i.properties.style&&(i.styleValues=l),void 0!==i.properties.width&&(i.widthValues=a),i}var u=i(14608),f=i(14139);function d(e,t){return{propType:"twoOptions",properties:e,...t}}var y,v=i(11542),b=i(30699);!function(e){e.Horizontal="horizontal",e.Vertical="vertical"}(y||(y={}));const P=[{id:b.VerticalAlign.Top,value:b.VerticalAlign.Bottom,title:v.t(null,void 0,i(97118))},{id:b.VerticalAlign.Middle,value:b.VerticalAlign.Middle,title:v.t(null,void 0,i(68833))},{id:b.VerticalAlign.Bottom,value:b.VerticalAlign.Top,title:v.t(null,void 0,i(27567))}],D=[{id:b.HorizontalAlign.Left,value:b.HorizontalAlign.Left,title:v.t(null,void 0,i(11626))},{id:b.HorizontalAlign.Center,value:b.HorizontalAlign.Center,title:v.t(null,void 0,i(24197))},{id:b.HorizontalAlign.Right,value:b.HorizontalAlign.Right,title:v.t(null,void 0,i(50421))}],T=[{id:"horizontal",value:"horizontal",title:v.t(null,void 0,i(95406))},{id:"vertical",value:"vertical",title:v.t(null,void 0,i(69526))}],g=[8,10,11,12,14,16,18,20,22,24,28,32,40].map((e=>({title:String(e),value:e}))),m=[1,2,3,4],h=v.t(null,void 0,i(25485)),w=v.t(null,void 0,i(67781));function V(e,t){const i={propType:"text",properties:e,...t,isEditable:t.isEditable||!1};return void 0!==i.properties.size&&void 0===i.sizeItems&&(i.sizeItems=g),void 0!==i.properties.alignmentVertical&&void 0===i.alignmentVerticalItems&&(i.alignmentVerticalItems=P),void 0!==i.properties.alignmentHorizontal&&void 0===i.alignmentHorizontalItems&&(i.alignmentHorizontalItems=D),(i.alignmentVerticalItems||i.alignmentHorizontalItems)&&void 0===i.alignmentTitle&&(i.alignmentTitle=h),void 0!==i.properties.orientation&&(void 0===i.orientationItems&&(i.orientationItems=T),void 0===i.orientationTitle&&(i.orientationTitle=w)),void 0!==i.properties.borderWidth&&void 0===i.borderWidthItems&&(i.borderWidthItems=m),i}function k(e,t){return{propType:"twoColors",properties:e,noAlpha1:!1,noAlpha2:!1,...t}}function L(e,t){return{propType:"optionalTwoColors",properties:e,noAlpha1:!1,noAlpha2:!1,...t}}function S(e,t){return{propType:"coordinates",
|
||||
properties:e,...t}}function E(e,t){return{propType:"selectionCoordinates",properties:e,...t}}function I(e,t){return{propType:"range",properties:e,...t}}function A(e,t){return{propType:"transparency",properties:e,...t}}function C(e,t){return{propType:"symbol",properties:e,...t}}function O(e,t){return{propType:"session",properties:e,...t}}function z(e,t){return{propType:"image",properties:e,...t}}function H(e,t){return{propType:"emoji",properties:e,...t}}function R(e,t){return{propType:"studyInputs",properties:e,...t}}var x=i(64147);function W(e,t,i,r){return{id:t,title:i,visible:r,groupType:"general",definitions:new x.WatchedValue(e)}}function M(e,t,i,r,o,n){return{id:r,title:o,visible:n,groupType:"checkableListOptions",checked:t,definitions:new x.WatchedValue(i),checkableListOptions:e}}function N(e,t,i){return{id:t,title:i,groupType:"leveledLines",definitions:new x.WatchedValue(e)}}var _=i(23351);function Y(e,t,i){const r=new Map,o=void 0!==t?t[0]:e=>e,n=void 0!==t?void 0!==t[1]?t[1]:t[0]:e=>e,s={value:()=>o(e.value()),setValue:t=>{e.setValue?.(n(t))},subscribe:(t,i)=>{const o=()=>{i(s)};let n=r.get(t);void 0===n?(n=new Map,n.set(i,o),r.set(t,n)):n.set(i,o),e.subscribe(o)},unsubscribe:(t,i)=>{const o=r.get(t);if(void 0!==o){const t=o.get(i);void 0!==t&&(e.unsubscribe(t),o.delete(i))}},unsubscribeAll:t=>{const i=r.get(t);void 0!==i&&(i.forEach(((t,i)=>{e.unsubscribe(t)})),i.clear())}};return i&&(s.destroy=()=>i()),s}function F(e,t,i,r){const o=Y(t,r),n=void 0!==r?void 0!==r[1]?r[1]:r[0]:e=>e;return o.setValue=r=>e.setWatchedValue(t,n(r),i),o}function G(e,t){return function(e,t,i,r){const o=new Map,n={subscribe:(i,r)=>{const n=e=>i(t(e));o.set(i,n),e.subscribe(n,r)},unsubscribe:t=>{if(t){const i=o.get(t);i&&(e.unsubscribe(i),o.delete(t))}else o.clear(),e.unsubscribe()},value:()=>t(e.value())};return Y(n,i,r)}(e,(e=>e),t,(()=>e.release()))}function j(e,t){const i=(0,_.makeProxyDefinitionProperty)(t.weakReference());return i.setValue=t=>e.setPriceScaleSelectionStrategy(t),i}function B(e,t,i,r){const o=(0,_.makeProxyDefinitionProperty)(t.weakReference());return o.setValue=t=>{const o={lockScale:t};e.setPriceScaleMode(o,i,r)},o}function U(e,t,i,r){const o=(0,_.makeProxyDefinitionProperty)(t.weakReference(),r);return o.setValue=r=>{e.setScaleRatioProperty(t,r,i)},o}var q=i(24377),J=i(19063),K=i(84425);function Q(e,t){if((0,J.isHexColor)(e)){const i=(0,q.parseRgb)(e);return(0,q.rgbaToString)((0,q.rgba)(i,(100-t)/100))}return e}function X(e,t,i,r,o){let n;if(null!==i){const e=(0,K.combineProperty)(Q,t.weakReference(),i.weakReference());n=(0,_.makeProxyDefinitionProperty)(e.ownership())}else n=(0,_.makeProxyDefinitionProperty)(t.weakReference(),[()=>Q(t.value(),0),e=>e]);return n.setValue=i=>{o&&e.beginUndoMacro(r),e.setProperty(t,i,r),o&&e.endUndoMacro()},n}function Z(e,t,i,r,o,n){const s=[(p=i,l=t,e=>{const t=p(l);if(e===l.value()&&null!==t){const e=t.ticker||t.full_name;if(e)return e}return e}),e=>e];var p,l;const a=(0,_.convertToDefinitionProperty)(e,t,o,s);n&&(a.setValue=n);const c=new Map;a.subscribe=(e,i)=>{const r=e=>{
|
||||
i(a)};c.set(i,r),t.subscribe(e,r)},a.unsubscribe=(e,i)=>{const r=c.get(i);r&&(t.unsubscribe(e,r),c.delete(i))};const u={};return r.subscribe(u,(()=>{c.forEach(((e,t)=>{t(a)}))})),a.destroy=()=>{r.unsubscribeAll(u),c.clear()},a}function $(e){return e.hasOwnProperty("propType")}function ee(e){return e.hasOwnProperty("groupType")}function te(e){return"line"===e.propType}function ie(e){return"color"===e.propType}function re(e){return"twoColors"===e.propType}function oe(e){return"options"===e.propType}function ne(e){return"checkableListOptions"===e.groupType}function se(e){e.forEach((e=>{if($(e)){Object.keys(e.properties).forEach((t=>{const i=e.properties[t];void 0!==i&&void 0!==i.destroy&&i.destroy()}))}else se(e.definitions.value()),e.visible?.destroy()}))}}}]);
|
||||
@@ -0,0 +1 @@
|
||||
.menuWrap-Kq3ruQo8{background-color:var(--tv-color-popup-background,var(--themed-color-popup-background,#fff));border-radius:6px;box-shadow:0 2px 4px var(--themed-color-shadow-primary-neutral-extra-heavy,#0003);box-sizing:border-box;text-align:left;-webkit-user-select:none;user-select:none;z-index:100}html.theme-dark .menuWrap-Kq3ruQo8{background-color:var(--tv-color-popup-background,var(--themed-color-popup-background,#262626));box-shadow:0 2px 4px var(--themed-color-shadow-primary-neutral-extra-heavy,#0006)}.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(--themed-color-scroll-bg,#9c9c9c));border:1px solid #0000;border-radius:3px}html.theme-dark .scrollWrap-Kq3ruQo8::-webkit-scrollbar-thumb{background-color:var(--tv-color-scrollbar-thumb-background,var(--themed-color-scroll-bg,#3d3d3d))}.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}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user