diff --git a/README.md b/README.md index 58c1e90..b1209c6 100644 --- a/README.md +++ b/README.md @@ -22,12 +22,12 @@ ___ ## Features 1. Streamlined for live data, with methods for updating directly from tick data. 2. Multi-pane charts using [Subcharts](https://lightweight-charts-python.readthedocs.io/en/latest/reference/abstract_chart.html#AbstractChart.create_subchart). -3. The [Toolbox](https://lightweight-charts-python.readthedocs.io/en/latest/reference/toolbox.html), allowing for trendlines, rays and horizontal lines to be drawn directly onto charts. +3. The [Toolbox](https://lightweight-charts-python.readthedocs.io/en/latest/reference/toolbox.html), allowing for trendlines, rectangles, rays and horizontal lines to be drawn directly onto charts. 4. [Events](https://lightweight-charts-python.readthedocs.io/en/latest/tutorials/events.html) allowing for timeframe selectors (1min, 5min, 30min etc.), searching, hotkeys, and more. 5. [Tables](https://lightweight-charts-python.readthedocs.io/en/latest/reference/tables.html) for watchlists, order entry, and trade management. 6. Direct integration of market data through [Polygon.io's](https://polygon.io/?utm_source=affiliate&utm_campaign=pythonlwcharts) market data API. -__Supports:__ Jupyter Notebooks, PyQt5, PySide6, wxPython, Streamlit, and asyncio. +__Supports:__ Jupyter Notebooks, PyQt6, PyQt5, PySide6, wxPython, Streamlit, and asyncio. PartTimeLarry: [Interactive Brokers API and TradingView Charts in Python](https://www.youtube.com/watch?v=TlhDI3PforA) ___ diff --git a/build.sh b/build.sh new file mode 100755 index 0000000..ea049c0 --- /dev/null +++ b/build.sh @@ -0,0 +1,34 @@ +#!/usr/bin/env bash + +GREEN='\033[0;32m' +RED='\033[0;31m' +YELLOW='\033[0;33m' +CYAN='\033[0;36m' +NC='\033[0m' + +ERROR="${RED}[ERROR]${NC} " +INFO="${CYAN}[INFO]${NC} " +WARNING="${WARNING}[WARNING]${NC} " + +rm -rf dist/bundle.js dist/typings/ + +if [[ $? -eq 0 ]]; then + echo -e "${INFO}deleted bundle.js and typings.." +else + echo -e "${WARNING}could not delete old dist files, continuing.." +fi + +npx rollup -c rollup.config.js +if [[ $? -ne 0 ]]; then + exit 1 +fi + +cp dist/bundle.js src/general/styles.css lightweight_charts/js +if [[ $? -eq 0 ]]; then + echo -e "${INFO}copied bundle.js, style.css into python package" +else + echo -e "${ERROR}could not copy dist into python package ?" + exit 1 +fi +echo -e "\n${GREEN}[BUILD SUCCESS]${NC}" + diff --git a/docs/source/examples/gui_examples.md b/docs/source/examples/gui_examples.md index 0678068..b5eaf7c 100644 --- a/docs/source/examples/gui_examples.md +++ b/docs/source/examples/gui_examples.md @@ -1,7 +1,7 @@ # Alternative GUI's -## PyQt5 / PySide6 +## PyQt6 / PyQt5 / PySide6 ```python import pandas as pd diff --git a/docs/source/examples/toolbox.md b/docs/source/examples/toolbox.md index 8c1a3e6..ae6c901 100644 --- a/docs/source/examples/toolbox.md +++ b/docs/source/examples/toolbox.md @@ -36,7 +36,7 @@ def on_timeframe_selection(chart): if new_data.empty: return # The symbol has not changed, so we want to re-render the drawings. - chart.set(new_data, render_drawings=True) + chart.set(new_data, keep_drawings=True) if __name__ == '__main__': diff --git a/docs/source/polygon.md b/docs/source/polygon.md index c82c9a1..949d080 100644 --- a/docs/source/polygon.md +++ b/docs/source/polygon.md @@ -22,7 +22,7 @@ The `websockets` library is required when using live data. ```{important} When using live data and the standard `show` method, the `block` parameter __must__ be set to `True` in order for the data to congregate on the chart (`chart.show(block=True)`). -If `show_async` is used with live data, `block` can be either value. +`show_async` can also be used with live data. ``` diff --git a/docs/source/reference/abstract_chart.md b/docs/source/reference/abstract_chart.md index fdc6c79..10981bc 100644 --- a/docs/source/reference/abstract_chart.md +++ b/docs/source/reference/abstract_chart.md @@ -8,7 +8,7 @@ ___ -```{py:method} set(data: pd.DataFrame, render_drawings: bool = False) +```{py:method} set(data: pd.DataFrame, keep_drawings: bool = False) Sets the initial data for the chart. @@ -17,9 +17,11 @@ Columns should be named: Time can be given in the index rather than a column, and volume can be omitted if volume is not used. Column names are not case sensitive. -If `render_drawings` is `True`, any drawings made using the `toolbox` will be redrawn with the new data. This is designed to be used when switching to a different timeframe of the same symbol. +If `keep_drawings` is `True`, any drawings made using the `toolbox` will be redrawn with the new data. This is designed to be used when switching to a different timeframe of the same symbol. `None` can also be given, which will erase all candle and volume data displayed on the chart. + +You can also add columns to color the candles (https://tradingview.github.io/lightweight-charts/tutorials/customization/data-points) ``` @@ -27,7 +29,7 @@ ___ -```{py:method} update(series: pd.Series, render_drawings: bool = False) +```{py:method} update(series: pd.Series, keep_drawings: bool = False) Updates the chart data from a bar. Series labels should be akin to [`set`](#AbstractChart.set). diff --git a/docs/source/reference/charts.md b/docs/source/reference/charts.md index a0480c5..44ec256 100644 --- a/docs/source/reference/charts.md +++ b/docs/source/reference/charts.md @@ -45,7 +45,7 @@ ___ -```{py:method} show_async(block: bool) +```{py:method} show_async() :async: Show the chart asynchronously. @@ -85,7 +85,7 @@ ___ The `QtChart` object allows the use of charts within a `QMainWindow` object, and has similar functionality to the `Chart` object for manipulating data, configuring and styling. -Either the `PyQt5` or `PySide6` libraries will work with this chart. +Either the `PyQt5`, `PyQt6` or `PySide6` libraries will work with this chart. Callbacks can be received through the Qt event loop. ___ diff --git a/docs/source/reference/events.md b/docs/source/reference/events.md index 83a785a..63ee6e9 100644 --- a/docs/source/reference/events.md +++ b/docs/source/reference/events.md @@ -22,6 +22,11 @@ Fires when the range (visibleLogicalRange) changes. ``` +```{py:method} click -> (chart: Chart, time: NUM, price: NUM) +Fires when the mouse is clicked, returning the time and price of the clicked location. + +``` + ```` Tutorial: [Topbar & Events](../tutorials/events.md) diff --git a/docs/source/tutorials/events.md b/docs/source/tutorials/events.md index ac91c20..0e4c527 100644 --- a/docs/source/tutorials/events.md +++ b/docs/source/tutorials/events.md @@ -101,7 +101,7 @@ async def update_clock(chart): async def main(): chart = Chart() chart.topbar.textbox('clock') - await asyncio.gather(chart.show_async(block=True), update_clock(chart)) + await asyncio.gather(chart.show_async(), update_clock(chart)) if __name__ == '__main__': @@ -130,7 +130,6 @@ async def data_loop(chart): return chart.update_from_tick(ticks.iloc[i]) await asyncio.sleep(0.03) - i += 1 def on_new_bar(chart): @@ -150,7 +149,7 @@ async def main(): df = pd.read_csv('ohlc.csv') chart.set(df) - await asyncio.gather(chart.show_async(block=True), data_loop(chart)) + await asyncio.gather(chart.show_async(), data_loop(chart)) if __name__ == '__main__': diff --git a/index.html b/index.html new file mode 100644 index 0000000..95184b7 --- /dev/null +++ b/index.html @@ -0,0 +1,7 @@ + + + + + + + diff --git a/lightweight_charts/abstract.py b/lightweight_charts/abstract.py index b3382c2..9bd9638 100644 --- a/lightweight_charts/abstract.py +++ b/lightweight_charts/abstract.py @@ -1,67 +1,40 @@ import asyncio +import json import os from base64 import b64decode from datetime import datetime -from typing import Union, Literal, List, Optional +from typing import Callable, Union, Literal, List, Optional import pandas as pd from .table import Table from .toolbox import ToolBox +from .drawings import Box, HorizontalLine, RayLine, TrendLine, TwoPointDrawing, VerticalLine, VerticalSpan from .topbar import TopBar from .util import ( - IDGen, jbool, Pane, Events, TIME, NUM, FLOAT, - LINE_STYLE, MARKER_POSITION, MARKER_SHAPE, CROSSHAIR_MODE, PRICE_SCALE_MODE, - line_style, marker_position, marker_shape, crosshair_mode, price_scale_mode, js_data, + BulkRunScript, Pane, Events, IDGen, as_enum, jbool, js_json, TIME, NUM, FLOAT, + LINE_STYLE, MARKER_POSITION, MARKER_SHAPE, CROSSHAIR_MODE, + PRICE_SCALE_MODE, marker_position, marker_shape, js_data, ) -JS = {} current_dir = os.path.dirname(os.path.abspath(__file__)) -for file in ('pkg', 'funcs', 'callback', 'toolbox', 'table'): - with open(os.path.join(current_dir, 'js', f'{file}.js'), 'r', encoding='utf-8') as f: - JS[file] = f.read() - -TEMPLATE = f""" - - - - lightweight-charts-python - - - - - -
- - - -""" +INDEX = os.path.join(current_dir, 'js', 'test.html') class Window: _id_gen = IDGen() handlers = {} - def __init__(self, script_func: callable = None, js_api_code: str = None, run_script: callable = None): + def __init__( + self, + script_func: Optional[Callable] = None, + js_api_code: Optional[str] = None, + run_script: Optional[Callable] = None + ): self.loaded = False self.script_func = script_func self.scripts = [] self.final_scripts = [] + self.bulk_run = BulkRunScript(script_func) if run_script: self.run_script = run_script @@ -73,65 +46,101 @@ def on_js_load(self): if self.loaded: return self.loaded = True - [self.run_script(script) for script in self.scripts] - [self.run_script(script) for script in self.final_scripts] + + if hasattr(self, '_return_q'): + while not self.run_script_and_get('document.readyState == "complete"'): + continue # scary, but works + + initial_script = '' + self.scripts.extend(self.final_scripts) + for script in self.scripts: + initial_script += f'\n{script}' + self.script_func(initial_script) def run_script(self, script: str, run_last: bool = False): """ For advanced users; evaluates JavaScript within the Webview. """ + if self.script_func is None: + raise AttributeError("script_func has not been set") if self.loaded: - self.script_func(script) - return - self.scripts.append(script) if not run_last else self.final_scripts.append(script) + if self.bulk_run.enabled: + self.bulk_run.add_script(script) + else: + self.script_func(script) + elif run_last: + self.final_scripts.append(script) + else: + self.scripts.append(script) + + def run_script_and_get(self, script: str): + self.run_script(f'_~_~RETURN~_~_{script}') + return self._return_q.get() def create_table( - self, width: NUM, height: NUM, headings: tuple, widths: tuple = None, - alignments: tuple = None, position: FLOAT = 'left', draggable: bool = False, - background_color: str = '#121417', border_color: str = 'rgb(70, 70, 70)', - border_width: int = 1, heading_text_colors: tuple = None, - heading_background_colors: tuple = None, return_clicked_cells: bool = False, - func: callable = None + self, + width: NUM, + height: NUM, + headings: tuple, + widths: Optional[tuple] = None, + alignments: Optional[tuple] = None, + position: FLOAT = 'left', + draggable: bool = False, + background_color: str = '#121417', + border_color: str = 'rgb(70, 70, 70)', + border_width: int = 1, + heading_text_colors: Optional[tuple] = None, + heading_background_colors: Optional[tuple] = None, + return_clicked_cells: bool = False, + func: Optional[Callable] = None ) -> 'Table': - return Table(self, width, height, headings, widths, alignments, position, draggable, - background_color, border_color, border_width, heading_text_colors, - heading_background_colors, return_clicked_cells, func) - - def create_subchart(self, position: FLOAT = 'left', width: float = 0.5, height: float = 0.5, - sync_id: str = None, scale_candles_only: bool = False, - sync_crosshairs_only: bool = False, toolbox: bool = False - ) -> 'AbstractChart': - subchart = AbstractChart(self, width, height, scale_candles_only, toolbox, position=position) + return Table(*locals().values()) + + def create_subchart( + self, + position: FLOAT = 'left', + width: float = 0.5, + height: float = 0.5, + sync_id: Optional[str] = None, + scale_candles_only: bool = False, + sync_crosshairs_only: bool = False, + toolbox: bool = False + ) -> 'AbstractChart': + subchart = AbstractChart( + self, + width, + height, + scale_candles_only, + toolbox, + position=position + ) if not sync_id: return subchart self.run_script(f''' - syncCharts({subchart.id}, {sync_id}, {jbool(sync_crosshairs_only)}) - {subchart.id}.chart.timeScale().setVisibleLogicalRange( - {sync_id}.chart.timeScale().getVisibleLogicalRange() - ) + Lib.Handler.syncCharts( + {subchart.id}, + {sync_id}, + {jbool(sync_crosshairs_only)} + ) ''', run_last=True) return subchart - def style(self, background_color: str = '#0c0d0f', hover_background_color: str = '#3c434c', - click_background_color: str = '#50565E', - active_background_color: str = 'rgba(0, 122, 255, 0.7)', - muted_background_color: str = 'rgba(0, 122, 255, 0.3)', - border_color: str = '#3C434C', color: str = '#d8d9db', active_color: str = '#ececed'): - self.run_script(f''' - window.pane = {{ - backgroundColor: '{background_color}', - hoverBackgroundColor: '{hover_background_color}', - clickBackgroundColor: '{click_background_color}', - activeBackgroundColor: '{active_background_color}', - mutedBackgroundColor: '{muted_background_color}', - borderColor: '{border_color}', - color: '{color}', - activeColor: '{active_color}', - }}''') + def style( + self, + background_color: str = '#0c0d0f', + hover_background_color: str = '#3c434c', + click_background_color: str = '#50565E', + active_background_color: str = 'rgba(0, 122, 255, 0.7)', + muted_background_color: str = 'rgba(0, 122, 255, 0.3)', + border_color: str = '#3C434C', + color: str = '#d8d9db', + active_color: str = '#ececed' + ): + self.run_script(f'Lib.Handler.setRootStyles({js_json(locals())});') class SeriesCommon(Pane): - def __init__(self, chart: 'AbstractChart', name: str = None): + def __init__(self, chart: 'AbstractChart', name: str = ''): super().__init__(chart.win) self._chart = chart if hasattr(chart, '_interval'): @@ -143,6 +152,7 @@ def __init__(self, chart: 'AbstractChart', name: str = None): self.num_decimals = 2 self.offset = 0 self.data = pd.DataFrame() + self.markers = {} def _set_interval(self, df: pd.DataFrame): if not pd.api.types.is_datetime64_any_dtype(df['time']): @@ -169,16 +179,6 @@ def _set_interval(self, df: pd.DataFrame): self.offset = value break - self.run_script( - f'if ({self.id}.toolBox) {self.id}.interval = {self._interval}' - ) - - def _push_to_legend(self): - self.run_script(f''' - {self._chart.id}.lines.push({self.id}) - {self._chart.id}.legend.lines.push({self._chart.id}.legend.makeLineRow({self.id})) - ''') - @staticmethod def _format_labels(data, labels, index, exclude_lowercase): def rename(la, mapper): @@ -209,7 +209,7 @@ def _series_datetime_format(self, series: pd.Series, exclude_lowercase=None): series['time'] = self._single_datetime_format(series['time']) return series - def _single_datetime_format(self, arg): + def _single_datetime_format(self, arg) -> float: if isinstance(arg, (str, int, float)) or not pd.api.types.is_datetime64_any_dtype(arg): try: arg = pd.to_datetime(arg, unit='ms') @@ -218,7 +218,7 @@ def _single_datetime_format(self, arg): arg = self._interval * (arg.timestamp() // self._interval)+self.offset return arg - def set(self, df: pd.DataFrame = None, format_cols: bool = True): + def set(self, df: Optional[pd.DataFrame] = None, format_cols: bool = True): if df is None or df.empty: self.run_script(f'{self.id}.series.setData([])') self.data = pd.DataFrame() @@ -231,7 +231,7 @@ def set(self, df: pd.DataFrame = None, format_cols: bool = True): df = df.rename(columns={self.name: 'value'}) self.data = df.copy() self._last_bar = df.iloc[-1] - self.run_script(f'{self.id}.data = {js_data(df)}; {self.id}.series.setData({self.id}.data); ') + self.run_script(f'{self.id}.series.setData({js_data(df)}); ') def update(self, series: pd.Series): series = self._series_datetime_format(series, exclude_lowercase=self.name) @@ -241,16 +241,11 @@ def update(self, series: pd.Series): self.data.loc[self.data.index[-1]] = self._last_bar self.data = pd.concat([self.data, series.to_frame().T], ignore_index=True) self._last_bar = series - bar = js_data(series) - self.run_script(f''' - if (stampToDate(lastBar({self.id}.data).time).getTime() === stampToDate({series['time']}).getTime()) {{ - {self.id}.data[{self.id}.data.length-1] = {bar} - }} - else {self.id}.data.push({bar}) - {self.id}.series.update({bar}) - ''') self.run_script(f'{self.id}.series.update({js_data(series)})') + def _update_markers(self): + self.run_script(f'{self.id}.series.setMarkers({json.dumps(list(self.markers.values()))})') + def marker_list(self, markers: list): """ Creates multiple markers.\n @@ -264,19 +259,20 @@ def marker_list(self, markers: list): """ markers = markers.copy() marker_ids = [] - for i, marker in enumerate(markers): - markers[i]['time'] = self._single_datetime_format(markers[i]['time']) - markers[i]['position'] = marker_position(markers[i]['position']) - markers[i]['shape'] = marker_shape(markers[i]['shape']) - markers[i]['id'] = self.win._id_gen.generate() - marker_ids.append(markers[i]['id']) - self.run_script(f""" - {self.id}.markers.push(...{markers}) - {self.id}.series.setMarkers({self.id}.markers) - """) + for marker in markers: + marker_id = self.win._id_gen.generate() + self.markers[marker_id] = { + "time": self._single_datetime_format(marker['time']), + "position": marker_position(marker['position']), + "color": marker['color'], + "shape": marker_shape(marker['shape']), + "text": marker['text'], + } + marker_ids.append(marker_id) + self._update_markers() return marker_ids - def marker(self, time: datetime = None, position: MARKER_POSITION = 'below', + def marker(self, time: Optional[datetime] = None, position: MARKER_POSITION = 'below', shape: MARKER_SHAPE = 'arrow_up', color: str = '#2196F3', text: str = '' ) -> str: """ @@ -289,66 +285,93 @@ def marker(self, time: datetime = None, position: MARKER_POSITION = 'below', :return: The id of the marker placed. """ try: - time = self._last_bar['time'] if not time else self._single_datetime_format(time) + formatted_time = self._last_bar['time'] if not time else self._single_datetime_format(time) except TypeError: raise TypeError('Chart marker created before data was set.') marker_id = self.win._id_gen.generate() - self.run_script(f""" - {self.id}.markers.push({{ - time: {time if isinstance(time, float) else f"'{time}'"}, - position: '{marker_position(position)}', - color: '{color}', - shape: '{marker_shape(shape)}', - text: '{text}', - id: '{marker_id}' - }}); - {self.id}.series.setMarkers({self.id}.markers)""") + + self.markers[marker_id] = { + "time": formatted_time, + "position": marker_position(position), + "color": color, + "shape": marker_shape(shape), + "text": text, + } + self._update_markers() return marker_id def remove_marker(self, marker_id: str): """ Removes the marker with the given id.\n """ - self.run_script(f''' - {self.id}.markers.forEach(function (marker) {{ - if ('{marker_id}' === marker.id) {{ - {self.id}.markers.splice({self.id}.markers.indexOf(marker), 1) - {self.id}.series.setMarkers({self.id}.markers) - }} - }});''') + self.markers.pop(marker_id) + self._update_markers() def horizontal_line(self, price: NUM, color: str = 'rgb(122, 146, 202)', width: int = 2, style: LINE_STYLE = 'solid', text: str = '', axis_label_visible: bool = True, - func: callable = None + func: Optional[Callable] = None ) -> 'HorizontalLine': """ Creates a horizontal line at the given price. """ return HorizontalLine(self, price, color, width, style, text, axis_label_visible, func) - def remove_horizontal_line(self, price: NUM = None): - """ - Removes a horizontal line at the given price. - """ - self.run_script(f''' - {self.id}.horizontal_lines.forEach(function (line) {{ - if ({price} === line.price) line.deleteLine() - }})''') + def trend_line( + self, + start_time: TIME, + start_value: NUM, + end_time: TIME, + end_value: NUM, + round: bool = False, + line_color: str = '#1E80F0', + width: int = 2, + style: LINE_STYLE = 'solid', + ) -> TwoPointDrawing: + return TrendLine(*locals().values()) + + def box( + self, + start_time: TIME, + start_value: NUM, + end_time: TIME, + end_value: NUM, + round: bool = False, + color: str = '#1E80F0', + fill_color: str = 'rgba(255, 255, 255, 0.2)', + width: int = 2, + style: LINE_STYLE = 'solid', + ) -> TwoPointDrawing: + return Box(*locals().values()) + + def ray_line( + self, + start_time: TIME, + value: NUM, + round: bool = False, + color: str = '#1E80F0', + width: int = 2, + style: LINE_STYLE = 'solid', + text: str = '' + ) -> RayLine: + # TODO + return RayLine(*locals().values()) + + def vertical_line( + self, + time: TIME, + color: str = '#1E80F0', + width: int = 2, + style: LINE_STYLE ='solid', + text: str = '' + ) -> VerticalLine: + return VerticalLine(*locals().values()) def clear_markers(self): """ Clears the markers displayed on the data.\n """ - self.run_script(f'''{self.id}.markers = []; {self.id}.series.setMarkers([])''') - - def clear_horizontal_lines(self): - """ - Clears the horizontal lines displayed on the data.\n - """ - self.run_script(f''' - {self.id}.horizontal_lines.forEach(function (line) {{{self.id}.series.removePriceLine(line.line);}}); - {self.id}.horizontal_lines = []; - ''') + self.markers.clear() + self._update_markers() def price_line(self, label_visible: bool = True, line_visible: bool = True, title: str = ''): self.run_script(f''' @@ -363,10 +386,10 @@ def precision(self, precision: int): Sets the precision and minMove.\n :param precision: The number of decimal places. """ + min_move = 1 / (10**precision) self.run_script(f''' - {self.id}.precision = {precision} {self.id}.series.applyOptions({{ - priceFormat: {{precision: {precision}, minMove: {1 / (10 ** precision)}}} + priceFormat: {{precision: {precision}, minMove: {min_move}}} }})''') self.num_decimals = precision @@ -382,8 +405,13 @@ def _toggle_data(self, arg): if ('volumeSeries' in {self.id}) {self.id}.volumeSeries.applyOptions({{visible: {jbool(arg)}}}) ''') - def vertical_span(self, start_time: Union[TIME, tuple, list], end_time: TIME = None, - color: str = 'rgba(252, 219, 3, 0.2)', round: bool = False): + def vertical_span( + self, + start_time: Union[TIME, tuple, list], + end_time: Optional[TIME] = None, + color: str = 'rgba(252, 219, 3, 0.2)', + round: bool = False + ): """ Creates a vertical line or span across the chart.\n Start time and end time can be used together, or end_time can be @@ -395,127 +423,47 @@ def vertical_span(self, start_time: Union[TIME, tuple, list], end_time: TIME = N return VerticalSpan(self, start_time, end_time, color) -class HorizontalLine(Pane): - def __init__(self, chart, price, color, width, style, text, axis_label_visible, func): - super().__init__(chart.win) - self.price = price - self.run_script(f''' - {self.id} = new HorizontalLine( - {chart.id}, '{self.id}', {price}, '{color}', {width}, - {line_style(style)}, {jbool(axis_label_visible)}, '{text}' - )''') - if not func: - return - - def wrapper(p): - self.price = float(p) - func(chart, self) - - async def wrapper_async(p): - self.price = float(p) - await func(chart, self) - - self.win.handlers[self.id] = wrapper_async if asyncio.iscoroutinefunction(func) else wrapper - self.run_script(f'if ("toolBox" in {chart.id}) {chart.id}.toolBox.drawings.push({self.id})') - - def update(self, price): - """ - Moves the horizontal line to the given price. - """ - self.run_script(f'{self.id}.updatePrice({price})') - self.price = price - - def label(self, text: str): - self.run_script(f'{self.id}.updateLabel("{text}")') - - def delete(self): - """ - Irreversibly deletes the horizontal line. - """ - self.run_script(f'{self.id}.deleteLine()') - del self - - -class VerticalSpan(Pane): - def __init__(self, series: 'SeriesCommon', start_time: Union[TIME, tuple, list], end_time: TIME = None, - color: str = 'rgba(252, 219, 3, 0.2)'): - self._chart = series._chart - super().__init__(self._chart.win) - start_time, end_time = pd.to_datetime(start_time), pd.to_datetime(end_time) - self.run_script(f''' - {self.id} = {self._chart.id}.chart.addHistogramSeries({{ - color: '{color}', - priceFormat: {{type: 'volume'}}, - priceScaleId: 'vertical_line', - lastValueVisible: false, - priceLineVisible: false, - }}) - {self.id}.priceScale('').applyOptions({{ - scaleMargins: {{top: 0, bottom: 0}} - }}) - ''') - if end_time is None: - if isinstance(start_time, pd.DatetimeIndex): - data = [{'time': time.timestamp(), 'value': 1} for time in start_time] - else: - data = [{'time': start_time.timestamp(), 'value': 1}] - self.run_script(f'{self.id}.setData({data})') - else: - self.run_script(f''' - {self.id}.setData(calculateTrendLine( - {start_time.timestamp()}, 1, {end_time.timestamp()}, 1, {series.id})) - ''') - - def delete(self): - """ - Irreversibly deletes the vertical span. - """ - self.run_script(f'{self._chart.id}.chart.removeSeries({self.id})') - - class Line(SeriesCommon): def __init__(self, chart, name, color, style, width, price_line, price_label, crosshair_marker=True): + super().__init__(chart, name) self.color = color + self.run_script(f''' - {self.id} = {{ - type: "line", - series: {chart.id}.chart.addLineSeries({{ - color: '{color}', - lineStyle: {line_style(style)}, - lineWidth: {width}, - lastValueVisible: {jbool(price_label)}, - priceLineVisible: {jbool(price_line)}, - crosshairMarkerVisible: {jbool(crosshair_marker)}, - {"""autoscaleInfoProvider: () => ({ - priceRange: { - minValue: 1_000_000_000, - maxValue: 0, - }, - }),""" if chart._scale_candles_only else ''} - }}), - markers: [], - horizontal_lines: [], - name: '{name}', - color: '{color}', - precision: 2, - }} + {self.id} = {self._chart.id}.createLineSeries( + "{name}", + {{ + color: '{color}', + lineStyle: {as_enum(style, LINE_STYLE)}, + lineWidth: {width}, + lastValueVisible: {jbool(price_label)}, + priceLineVisible: {jbool(price_line)}, + crosshairMarkerVisible: {jbool(crosshair_marker)}, + {"""autoscaleInfoProvider: () => ({ + priceRange: { + minValue: 1_000_000_000, + maxValue: 0, + }, + }), + """ if chart._scale_candles_only else ''} + }} + ) null''') - def _set_trend(self, start_time, start_value, end_time, end_value, ray=False, round=False): - if round: - start_time = self._single_datetime_format(start_time) - end_time = self._single_datetime_format(end_time) - else: - start_time, end_time = pd.to_datetime((start_time, end_time)).astype('int64') // 10 ** 9 - - self.run_script(f''' - {self._chart.id}.chart.timeScale().applyOptions({{shiftVisibleRangeOnNewBar: false}}) - {self.id}.series.setData( - calculateTrendLine({start_time}, {start_value}, {end_time}, {end_value}, - {self._chart.id}, {jbool(ray)})) - {self._chart.id}.chart.timeScale().applyOptions({{shiftVisibleRangeOnNewBar: true}}) - ''') + # def _set_trend(self, start_time, start_value, end_time, end_value, ray=False, round=False): + # if round: + # start_time = self._single_datetime_format(start_time) + # end_time = self._single_datetime_format(end_time) + # else: + # start_time, end_time = pd.to_datetime((start_time, end_time)).astype('int64') // 10 ** 9 + + # self.run_script(f''' + # {self._chart.id}.chart.timeScale().applyOptions({{shiftVisibleRangeOnNewBar: false}}) + # {self.id}.series.setData( + # calculateTrendLine({start_time}, {start_value}, {end_time}, {end_value}, + # {self._chart.id}, {jbool(ray)})) + # {self._chart.id}.chart.timeScale().applyOptions({{shiftVisibleRangeOnNewBar: true}}) + # ''') def delete(self): """ @@ -545,8 +493,6 @@ def __init__(self, chart, name, color, price_line, price_label, scale_margin_top priceScaleId: '{self.id}', priceFormat: {{type: "volume"}}, }}), - markers: [], - horizontal_lines: [], name: '{name}', color: '{color}', precision: 2, @@ -582,13 +528,13 @@ def __init__(self, chart: 'AbstractChart'): self.candle_data = pd.DataFrame() - self.run_script(f'{self.id}.makeCandlestickSeries()') + # self.run_script(f'{self.id}.makeCandlestickSeries()') - def set(self, df: pd.DataFrame = None, render_drawings=False): + def set(self, df: Optional[pd.DataFrame] = None, keep_drawings=False): """ Sets the initial data for the chart.\n :param df: columns: date/time, open, high, low, close, volume (if volume enabled). - :param render_drawings: Re-renders any drawings made through the toolbox. Otherwise, they will be deleted. + :param keep_drawings: keeps any drawings made through the toolbox. Otherwise, they will be deleted. """ if df is None or df.empty: self.run_script(f'{self.id}.series.setData([])') @@ -598,10 +544,8 @@ def set(self, df: pd.DataFrame = None, render_drawings=False): df = self._df_datetime_format(df) self.candle_data = df.copy() self._last_bar = df.iloc[-1] + self.run_script(f'{self.id}.series.setData({js_data(df)})') - self.run_script(f'{self.id}.data = {js_data(df)}; {self.id}.series.setData({self.id}.data)') - toolbox_action = 'clearDrawings' if not render_drawings else 'renderDrawings' - self.run_script(f"if ('toolBox' in {self._chart.id}) {self._chart.id}.toolBox.{toolbox_action}()") if 'volume' not in df: return volume = df.drop(columns=['open', 'high', 'low', 'close']).rename(columns={'volume': 'value'}) @@ -618,8 +562,13 @@ def set(self, df: pd.DataFrame = None, render_drawings=False): if (!{self.id}.chart.priceScale("right").options.autoScale) {self.id}.chart.priceScale("right").applyOptions({{autoScale: true}}) ''') + # TODO keep drawings doesn't work consistenly w + if keep_drawings: + self.run_script(f'{self._chart.id}.toolBox?._drawingTool.repositionOnTime()') + else: + self.run_script(f"{self._chart.id}.toolBox?.clearDrawings()") - def update(self, series: pd.Series, render_drawings=False, _from_tick=False): + def update(self, series: pd.Series, _from_tick=False): """ Updates the data from a bar; if series['time'] is the same time as the last bar, the last bar will be overwritten.\n @@ -630,18 +579,9 @@ def update(self, series: pd.Series, render_drawings=False, _from_tick=False): self.candle_data.loc[self.candle_data.index[-1]] = self._last_bar self.candle_data = pd.concat([self.candle_data, series.to_frame().T], ignore_index=True) self._chart.events.new_bar._emit(self) + self._last_bar = series - bar = js_data(series) - self.run_script(f''' - if (stampToDate(lastBar({self.id}.data).time).getTime() === stampToDate({series['time']}).getTime()) {{ - {self.id}.data[{self.id}.data.length-1] = {bar} - }} - else {{ - {self.id}.data.push({bar}) - {f'{self.id}.toolBox.renderDrawings()' if render_drawings else ''} - }} - {self.id}.series.update({bar}) - ''') + self.run_script(f'{self.id}.series.update({js_data(series)})') if 'volume' not in series: return volume = series.drop(['open', 'high', 'low', 'close']).rename({'volume': 'value'}) @@ -656,10 +596,7 @@ def update_from_tick(self, series: pd.Series, cumulative_volume: bool = False): """ series = self._series_datetime_format(series) if series['time'] < self._last_bar['time']: - raise ValueError( - f'Trying to update tick of time "{pd.to_datetime(series["time"])}", ' - f'which occurs before the last bar time of ' - f'"{pd.to_datetime(self._last_bar["time"])}".') + raise ValueError(f'Trying to update tick of time "{pd.to_datetime(series["time"])}", which occurs before the last bar time of "{pd.to_datetime(self._last_bar["time"])}".') bar = pd.Series(dtype='float64') if series['time'] == self._last_bar['time']: bar = self._last_bar @@ -680,15 +617,25 @@ def update_from_tick(self, series: pd.Series, cumulative_volume: bool = False): self.update(bar, _from_tick=True) def price_scale( - self, auto_scale: bool = True, mode: PRICE_SCALE_MODE = 'normal', invert_scale: bool = False, - align_labels: bool = True, scale_margin_top: float = 0.2, scale_margin_bottom: float = 0.2, - border_visible: bool = False, border_color: Optional[str] = None, text_color: Optional[str] = None, - entire_text_only: bool = False, visible: bool = True, ticks_visible: bool = False, minimum_width: int = 0 - ): + self, + auto_scale: bool = True, + mode: PRICE_SCALE_MODE = 'normal', + invert_scale: bool = False, + align_labels: bool = True, + scale_margin_top: float = 0.2, + scale_margin_bottom: float = 0.2, + border_visible: bool = False, + border_color: Optional[str] = None, + text_color: Optional[str] = None, + entire_text_only: bool = False, + visible: bool = True, + ticks_visible: bool = False, + minimum_width: int = 0 + ): self.run_script(f''' {self.id}.series.priceScale().applyOptions({{ autoScale: {jbool(auto_scale)}, - mode: {price_scale_mode(mode)}, + mode: {as_enum(mode, PRICE_SCALE_MODE)}, invertScale: {jbool(invert_scale)}, alignLabels: {jbool(align_labels)}, scaleMargins: {{top: {scale_margin_top}, bottom: {scale_margin_bottom}}}, @@ -703,29 +650,17 @@ def price_scale( def candle_style( self, up_color: str = 'rgba(39, 157, 130, 100)', down_color: str = 'rgba(200, 97, 100, 100)', - wick_enabled: bool = True, border_enabled: bool = True, border_up_color: str = '', + wick_visible: bool = True, border_visible: bool = True, border_up_color: str = '', border_down_color: str = '', wick_up_color: str = '', wick_down_color: str = ''): """ Candle styling for each of its parts.\n If only `up_color` and `down_color` are passed, they will color all parts of the candle. """ - if border_enabled: - border_up_color = border_up_color if border_up_color else up_color - border_down_color = border_down_color if border_down_color else down_color - if wick_enabled: - wick_up_color = wick_up_color if wick_up_color else up_color - wick_down_color = wick_down_color if wick_down_color else down_color - self.run_script(f""" - {self.id}.series.applyOptions({{ - upColor: "{up_color}", - downColor: "{down_color}", - wickVisible: {jbool(wick_enabled)}, - borderVisible: {jbool(border_enabled)}, - {f'borderUpColor: "{border_up_color}",' if border_enabled else ''} - {f'borderDownColor: "{border_down_color}",' if border_enabled else ''} - {f'wickUpColor: "{wick_up_color}",' if wick_enabled else ''} - {f'wickDownColor: "{wick_down_color}",' if wick_enabled else ''} - }})""") + border_up_color = border_up_color if border_up_color else up_color + border_down_color = border_down_color if border_down_color else down_color + wick_up_color = wick_up_color if wick_up_color else up_color + wick_down_color = wick_down_color if wick_down_color else down_color + self.run_script(f"{self.id}.series.applyOptions({js_json(locals())})") def volume_config(self, scale_margin_top: float = 0.8, scale_margin_bottom: float = 0.0, up_color='rgba(83,141,131,0.8)', down_color='rgba(200,127,130,0.8)'): @@ -761,7 +696,7 @@ def __init__(self, window: Window, width: float = 1.0, height: float = 1.0, self.polygon: PolygonAPI = PolygonAPI(self) self.run_script( - f'{self.id} = new Chart("{self.id}", {width}, {height}, "{position}", {jbool(autosize)})') + f'{self.id} = new Lib.Handler("{self.id}", {width}, {height}, "{position}", {jbool(autosize)})') Candlestick.__init__(self, self) @@ -784,7 +719,6 @@ def create_line( Creates and returns a Line object. """ self._lines.append(Line(self, name, color, style, width, price_line, price_label)) - self._lines[-1]._push_to_legend() return self._lines[-1] def create_histogram( @@ -795,11 +729,9 @@ def create_histogram( """ Creates and returns a Histogram object. """ - histogram = Histogram( + return Histogram( self, name, color, price_line, price_label, scale_margin_top, scale_margin_bottom) - histogram._push_to_legend() - return histogram def lines(self) -> List[Line]: """ @@ -807,22 +739,6 @@ def lines(self) -> List[Line]: """ return self._lines.copy() - def trend_line(self, start_time: TIME, start_value: NUM, end_time: TIME, end_value: NUM, - round: bool = False, color: str = '#1E80F0', width: int = 2, - style: LINE_STYLE = 'solid', - ) -> Line: - line = Line(self, '', color, style, width, False, False, False) - line._set_trend(start_time, start_value, end_time, end_value, round=round) - return line - - def ray_line(self, start_time: TIME, value: NUM, round: bool = False, - color: str = '#1E80F0', width: int = 2, - style: LINE_STYLE = 'solid' - ) -> Line: - line = Line(self, '', color, style, width, False, False, False) - line._set_trend(start_time, value, start_time, value, ray=True, round=round) - return line - def set_visible_range(self, start_time: TIME, end_time: TIME): self.run_script(f''' {self.id}.chart.timeScale().setVisibleRange({{ @@ -831,7 +747,7 @@ def set_visible_range(self, start_time: TIME, end_time: TIME): }}) ''') - def resize(self, width: float = None, height: float = None): + def resize(self, width: Optional[float] = None, height: Optional[float] = None): """ Resizes the chart within the window. Dimensions should be given as a float between 0 and 1. @@ -846,37 +762,26 @@ def resize(self, width: float = None, height: float = None): def time_scale(self, right_offset: int = 0, min_bar_spacing: float = 0.5, visible: bool = True, time_visible: bool = True, seconds_visible: bool = False, - border_visible: bool = True, border_color: str = None): + border_visible: bool = True, border_color: Optional[str] = None): """ Options for the timescale of the chart. """ - self.run_script(f''' - {self.id}.chart.applyOptions({{ - timeScale: {{ - rightOffset: {right_offset}, - minBarSpacing: {min_bar_spacing}, - visible: {jbool(visible)}, - timeVisible: {jbool(time_visible)}, - secondsVisible: {jbool(seconds_visible)}, - borderVisible: {jbool(border_visible)}, - {f'borderColor: "{border_color}",' if border_color else ''} - }} - }})''') - - def layout(self, background_color: str = '#000000', text_color: str = None, - font_size: int = None, font_family: str = None): + self.run_script(f'''{self.id}.chart.applyOptions({{timeScale: {js_json(locals())}}})''') + + def layout(self, background_color: str = '#000000', text_color: Optional[str] = None, + font_size: Optional[int] = None, font_family: Optional[str] = None): """ Global layout options for the chart. """ self.run_script(f""" - document.getElementById('wrapper').style.backgroundColor = '{background_color}' - {self.id}.chart.applyOptions({{ - layout: {{ - background: {{color: "{background_color}"}}, - {f'textColor: "{text_color}",' if text_color else ''} - {f'fontSize: {font_size},' if font_size else ''} - {f'fontFamily: "{font_family}",' if font_family else ''} - }}}})""") + document.getElementById('container').style.backgroundColor = '{background_color}' + {self.id}.chart.applyOptions({{ + layout: {{ + background: {{color: "{background_color}"}}, + {f'textColor: "{text_color}",' if text_color else ''} + {f'fontSize: {font_size},' if font_size else ''} + {f'fontFamily: "{font_family}",' if font_family else ''} + }}}})""") def grid(self, vert_enabled: bool = True, horz_enabled: bool = True, color: str = 'rgba(29, 30, 38, 5)', style: LINE_STYLE = 'solid'): @@ -889,43 +794,53 @@ def grid(self, vert_enabled: bool = True, horz_enabled: bool = True, vertLines: {{ visible: {jbool(vert_enabled)}, color: "{color}", - style: {line_style(style)}, + style: {as_enum(style, LINE_STYLE)}, }}, horzLines: {{ visible: {jbool(horz_enabled)}, color: "{color}", - style: {line_style(style)}, + style: {as_enum(style, LINE_STYLE)}, }}, }} }})""") - def crosshair(self, mode: CROSSHAIR_MODE = 'normal', vert_visible: bool = True, - vert_width: int = 1, vert_color: str = None, vert_style: LINE_STYLE = 'large_dashed', - vert_label_background_color: str = 'rgb(46, 46, 46)', horz_visible: bool = True, - horz_width: int = 1, horz_color: str = None, horz_style: LINE_STYLE = 'large_dashed', - horz_label_background_color: str = 'rgb(55, 55, 55)'): + def crosshair( + self, + mode: CROSSHAIR_MODE = 'normal', + vert_visible: bool = True, + vert_width: int = 1, + vert_color: Optional[str] = None, + vert_style: LINE_STYLE = 'large_dashed', + vert_label_background_color: str = 'rgb(46, 46, 46)', + horz_visible: bool = True, + horz_width: int = 1, + horz_color: Optional[str] = None, + horz_style: LINE_STYLE = 'large_dashed', + horz_label_background_color: str = 'rgb(55, 55, 55)' + ): """ Crosshair formatting for its vertical and horizontal axes. """ self.run_script(f''' {self.id}.chart.applyOptions({{ crosshair: {{ - mode: {crosshair_mode(mode)}, + mode: {as_enum(mode, CROSSHAIR_MODE)}, vertLine: {{ visible: {jbool(vert_visible)}, width: {vert_width}, {f'color: "{vert_color}",' if vert_color else ''} - style: {line_style(vert_style)}, + style: {as_enum(vert_style, LINE_STYLE)}, labelBackgroundColor: "{vert_label_background_color}" }}, horzLine: {{ visible: {jbool(horz_visible)}, width: {horz_width}, {f'color: "{horz_color}",' if horz_color else ''} - style: {line_style(horz_style)}, + style: {as_enum(horz_style, LINE_STYLE)}, labelBackgroundColor: "{horz_label_background_color}" }} - }}}})''') + }} + }})''') def watermark(self, text: str, font_size: int = 44, color: str = 'rgba(180, 180, 200, 0.5)'): """ @@ -935,11 +850,9 @@ def watermark(self, text: str, font_size: int = 44, color: str = 'rgba(180, 180, {self.id}.chart.applyOptions({{ watermark: {{ visible: true, - fontSize: {font_size}, horzAlign: 'center', vertAlign: 'center', - color: '{color}', - text: '{text}', + ...{js_json(locals())} }} }})''') @@ -975,7 +888,7 @@ def spinner(self, visible): self.run_script(f"{self.id}.spinner.style.display = '{'block' if visible else 'none'}'") def hotkey(self, modifier_key: Literal['ctrl', 'alt', 'shift', 'meta', None], - keys: Union[str, tuple, int], func: callable): + keys: Union[str, tuple, int], func: Callable): if not isinstance(keys, tuple): keys = (keys,) for key in keys: @@ -1000,31 +913,40 @@ def hotkey(self, modifier_key: Literal['ctrl', 'alt', 'shift', 'meta', None], self.win.handlers[f'{modifier_key, keys}'] = func def create_table( - self, width: NUM, height: NUM, headings: tuple, widths: tuple = None, - alignments: tuple = None, position: FLOAT = 'left', draggable: bool = False, - background_color: str = '#121417', border_color: str = 'rgb(70, 70, 70)', - border_width: int = 1, heading_text_colors: tuple = None, - heading_background_colors: tuple = None, return_clicked_cells: bool = False, - func: callable = None + self, + width: NUM, + height: NUM, + headings: tuple, + widths: Optional[tuple] = None, + alignments: Optional[tuple] = None, + position: FLOAT = 'left', + draggable: bool = False, + background_color: str = '#121417', + border_color: str = 'rgb(70, 70, 70)', + border_width: int = 1, + heading_text_colors: Optional[tuple] = None, + heading_background_colors: Optional[tuple] = None, + return_clicked_cells: bool = False, + func: Optional[Callable] = None ) -> Table: - return self.win.create_table(width, height, headings, widths, alignments, position, draggable, - background_color, border_color, border_width, heading_text_colors, - heading_background_colors, return_clicked_cells, func) + args = locals() + del args['self'] + return self.win.create_table(*args.values()) def screenshot(self) -> bytes: """ Takes a screenshot. This method can only be used after the chart window is visible. :return: a bytes object containing a screenshot of the chart. """ - self.run_script(f'_~_~RETURN~_~_{self.id}.chart.takeScreenshot().toDataURL()') - serial_data = self.win._return_q.get() + serial_data = self.win.run_script_and_get(f'{self.id}.chart.takeScreenshot().toDataURL()') return b64decode(serial_data.split(',')[1]) def create_subchart(self, position: FLOAT = 'left', width: float = 0.5, height: float = 0.5, - sync: Union[str, bool] = None, scale_candles_only: bool = False, + sync: Optional[Union[str, bool]] = None, scale_candles_only: bool = False, sync_crosshairs_only: bool = False, toolbox: bool = False) -> 'AbstractChart': if sync is True: sync = self.id - return self.win.create_subchart(position, width, height, sync, - scale_candles_only, sync_crosshairs_only, toolbox) + args = locals() + del args['self'] + return self.win.create_subchart(*args.values()) diff --git a/lightweight_charts/chart.py b/lightweight_charts/chart.py index 855ada2..305534c 100644 --- a/lightweight_charts/chart.py +++ b/lightweight_charts/chart.py @@ -1,43 +1,43 @@ import asyncio +import json import multiprocessing as mp +import typing import webview - -# temporary until we fix to pywebview v5 -try: - from webview.errors import JavascriptException -except ModuleNotFoundError: - JavascriptException = Exception +from webview.errors import JavascriptException from lightweight_charts import abstract from .util import parse_event_message, FLOAT +import os +import threading + class CallbackAPI: def __init__(self, emit_queue): - self.emit_q = emit_queue + self.emit_queue = emit_queue def callback(self, message: str): - self.emit_q.put(message) + self.emit_queue.put(message) class PyWV: - def __init__(self, q, start_ev, exit_ev, loaded, emit_queue, return_queue, html, debug, - width, height, x, y, screen, on_top, maximize, title): + def __init__(self, q, emit_q, return_q, loaded_event): self.queue = q - self.return_queue = return_queue - self.exit = exit_ev - self.callback_api = CallbackAPI(emit_queue) - self.loaded: list = loaded - self.html = html + self.return_queue = return_q + self.emit_queue = emit_q + self.loaded_event = loaded_event + + self.is_alive = True - self.windows = [] - self.create_window(width, height, x, y, screen, on_top, maximize, title) + self.callback_api = CallbackAPI(emit_q) + self.windows: typing.List[webview.Window] = [] + self.loop() - start_ev.wait() - webview.start(debug=debug) - self.exit.set() - def create_window(self, width, height, x, y, screen=None, on_top=False, maximize=False, title=''): + def create_window( + self, width, height, x, y, screen=None, on_top=False, + maximize=False, title='' + ): screen = webview.screens[screen] if screen is not None else None if maximize: if screen is None: @@ -45,68 +45,148 @@ def create_window(self, width, height, x, y, screen=None, on_top=False, maximize width, height = active_screen.width, active_screen.height else: width, height = screen.width, screen.height + self.windows.append(webview.create_window( - title, html=self.html, js_api=self.callback_api, - width=width, height=height, x=x, y=y, screen=screen, - on_top=on_top, background_color='#000000')) - self.windows[-1].events.loaded += lambda: self.loop(self.loaded[len(self.windows)-1]) - - def loop(self, loaded): - loaded.set() - while 1: + title, + url=abstract.INDEX, + js_api=self.callback_api, + width=width, + height=height, + x=x, + y=y, + screen=screen, + on_top=on_top, + background_color='#000000') + ) + + self.windows[-1].events.loaded += lambda: self.loaded_event.set() + + + def loop(self): + # self.loaded_event.set() + while self.is_alive: i, arg = self.queue.get() + + if i == 'start': + webview.start(debug=arg, func=self.loop) + self.is_alive = False + self.emit_queue.put('exit') + return if i == 'create_window': self.create_window(*arg) - elif arg in ('show', 'hide'): - getattr(self.windows[i], arg)() - elif arg == 'exit': - self.exit.set() + continue + + window = self.windows[i] + if arg == 'show': + window.show() + elif arg == 'hide': + window.hide() else: try: if '_~_~RETURN~_~_' in arg: - self.return_queue.put(self.windows[i].evaluate_js(arg[14:])) + self.return_queue.put(window.evaluate_js(arg[14:])) else: - self.windows[i].evaluate_js(arg) + window.evaluate_js(arg) except KeyError as e: return except JavascriptException as e: - pass - # msg = eval(str(e)) - # raise JavascriptException(f"\n\nscript -> '{arg}',\nerror -> {msg['name']}[{msg['line']}:{msg['column']}]\n{msg['message']}") + msg = eval(str(e)) + raise JavascriptException(f"\n\nscript -> '{arg}',\nerror -> {msg['name']}[{msg['line']}:{msg['column']}]\n{msg['message']}") + + +class WebviewHandler(): + def __init__(self) -> None: + self._reset() + self.debug = False + + def _reset(self): + self.loaded_event = mp.Event() + self.return_queue = mp.Queue() + self.function_call_queue = mp.Queue() + self.emit_queue = mp.Queue() + self.wv_process = mp.Process( + target=PyWV, args=( + self.function_call_queue, self.emit_queue, + self.return_queue, self.loaded_event + ), + daemon=True + ) + self.max_window_num = -1 + + def create_window( + self, width, height, x, y, screen=None, on_top=False, + maximize=False, title='' + ): + self.function_call_queue.put(( + 'create_window', + (width, height, x, y, screen, on_top, maximize, title) + )) + self.max_window_num += 1 + return self.max_window_num + + def start(self): + self.loaded_event.clear() + self.wv_process.start() + self.function_call_queue.put(('start', self.debug)) + self.loaded_event.wait() + + def show(self, window_num): + self.function_call_queue.put((window_num, 'show')) + + def hide(self, window_num): + self.function_call_queue.put((window_num, 'hide')) + + def evaluate_js(self, window_num, script): + self.function_call_queue.put((window_num, script)) + + def exit(self): + if self.wv_process.is_alive(): + self.wv_process.terminate() + self.wv_process.join() + self._reset() class Chart(abstract.AbstractChart): - MAX_WINDOWS = 10 - _window_num = 0 _main_window_handlers = None - _exit, _start = (mp.Event() for _ in range(2)) - _q, _emit_q, _return_q = (mp.Queue() for _ in range(3)) - _loaded_list = [mp.Event() for _ in range(MAX_WINDOWS)] - - def __init__(self, width: int = 800, height: int = 600, x: int = None, y: int = None, title: str = '', - screen: int = None, on_top: bool = False, maximize: bool = False, debug: bool = False, - toolbox: bool = False, inner_width: float = 1.0, inner_height: float = 1.0, - scale_candles_only: bool = False, position: FLOAT = 'left'): - self._i = Chart._window_num - self._loaded = Chart._loaded_list[self._i] - abstract.Window._return_q = Chart._return_q - Chart._window_num += 1 + WV: WebviewHandler = WebviewHandler() + + def __init__( + self, + width: int = 800, + height: int = 600, + x: int = None, + y: int = None, + title: str = '', + screen: int = None, + on_top: bool = False, + maximize: bool = False, + debug: bool = False, + toolbox: bool = False, + inner_width: float = 1.0, + inner_height: float = 1.0, + scale_candles_only: bool = False, + position: FLOAT = 'left' + ): + Chart.WV.debug = debug + self._i = Chart.WV.create_window( + width, height, x, y, screen, on_top, maximize, title + ) + + window = abstract.Window( + script_func=lambda s: Chart.WV.evaluate_js(self._i, s), + js_api_code='pywebview.api.callback' + ) + + abstract.Window._return_q = Chart.WV.return_queue + self.is_alive = True - window = abstract.Window(lambda s: self._q.put((self._i, s)), 'pywebview.api.callback') - if self._i == 0: + if Chart._main_window_handlers is None: super().__init__(window, inner_width, inner_height, scale_candles_only, toolbox, position=position) Chart._main_window_handlers = self.win.handlers - self._process = mp.Process(target=PyWV, args=( - self._q, self._start, self._exit, Chart._loaded_list, - self._emit_q, self._return_q, abstract.TEMPLATE, debug, - width, height, x, y, screen, on_top, maximize, title - ), daemon=True) - self._process.start() else: window.handlers = Chart._main_window_handlers super().__init__(window, inner_width, inner_height, scale_candles_only, toolbox, position=position) - self._q.put(('create_window', (width, height, x, y, screen, on_top, maximize, title))) def show(self, block: bool = False): """ @@ -114,34 +194,31 @@ def show(self, block: bool = False): :param block: blocks execution until the chart is closed. """ if not self.win.loaded: - self._start.set() - self._loaded.wait() + Chart.WV.start() self.win.on_js_load() else: - self._q.put((self._i, 'show')) + Chart.WV.show(self._i) if block: - asyncio.run(self.show_async(block=True)) + asyncio.run(self.show_async()) - async def show_async(self, block=False): + async def show_async(self): self.show(block=False) - if not block: - asyncio.create_task(self.show_async(block=True)) - return try: from lightweight_charts import polygon [asyncio.create_task(self.polygon.async_set(*args)) for args in polygon._set_on_load] while 1: - while self._emit_q.empty() and not self._exit.is_set(): + while Chart.WV.emit_queue.empty() and self.is_alive: await asyncio.sleep(0.05) - if self._exit.is_set(): - self._exit.clear() + if not self.is_alive: + return + response = Chart.WV.emit_queue.get() + if response == 'exit': + Chart.WV.exit() self.is_alive = False - self.exit() return - elif not self._emit_q.empty(): - func, args = parse_event_message(self.win, self._emit_q.get()) + else: + func, args = parse_event_message(self.win, response) await func(*args) if asyncio.iscoroutinefunction(func) else func(*args) - continue except KeyboardInterrupt: return @@ -155,12 +232,5 @@ def exit(self): """ Exits and destroys the chart window.\n """ - self._q.put((self._i, 'exit')) - self._exit.wait() if self.win.loaded else None - self._process.terminate() - - Chart._main_window_handlers = None - Chart._window_num = 0 - Chart._q = mp.Queue() - Chart._exit.clear(), Chart._start.clear() + Chart.WV.exit() self.is_alive = False diff --git a/lightweight_charts/drawings.py b/lightweight_charts/drawings.py new file mode 100644 index 0000000..d00d0ba --- /dev/null +++ b/lightweight_charts/drawings.py @@ -0,0 +1,276 @@ +import asyncio +import json +import pandas as pd + +from typing import Union, Optional + +from lightweight_charts.util import js_json + +from .util import NUM, Pane, as_enum, LINE_STYLE, TIME, snake_to_camel + + +class Drawing(Pane): + def __init__(self, chart, func=None): + super().__init__(chart.win) + self.chart = chart + + def update(self, *points): + js_json_string = f'JSON.parse({json.dumps(points)})' + self.run_script(f'{self.id}.updatePoints(...{js_json_string})') + + def delete(self): + """ + Irreversibly deletes the drawing. + """ + self.run_script(f'{self.id}.detach()') + + def options(self, color='#1E80F0', style='solid', width=4): + self.run_script(f'''{self.id}.applyOptions({{ + lineColor: '{color}', + lineStyle: {as_enum(style, LINE_STYLE)}, + width: {width}, + }})''') + +class TwoPointDrawing(Drawing): + def __init__( + self, + drawing_type, + chart, + start_time: TIME, + start_value: NUM, + end_time: TIME, + end_value: NUM, + round: bool, + options: dict, + func=None + ): + super().__init__(chart, func) + + def make_js_point(time, price): + formatted_time = self.chart._single_datetime_format(time) + return f'''{{ + "time": {formatted_time}, + "logical": {self.chart.id}.chart.timeScale() + .coordinateToLogical( + {self.chart.id}.chart.timeScale() + .timeToCoordinate({formatted_time}) + ), + "price": {price} + }}''' + + options_string = '\n'.join(f'{key}: {val},' for key, val in options.items()) + + self.run_script(f''' + {self.id} = new Lib.{drawing_type}( + {make_js_point(start_time, start_value)}, + {make_js_point(end_time, end_value)}, + {{ + {options_string} + }} + ) + {chart.id}.series.attachPrimitive({self.id}) + ''') + + +class HorizontalLine(Drawing): + def __init__(self, chart, price, color, width, style, text, axis_label_visible, func): + super().__init__(chart, func) + self.price = price + self.run_script(f''' + + {self.id} = new Lib.HorizontalLine( + {{price: {price}}}, + {{ + lineColor: '{color}', + lineStyle: {as_enum(style, LINE_STYLE)}, + width: {width}, + text: `{text}`, + }}, + callbackName={f"'{self.id}'" if func else 'null'} + ) + {chart.id}.series.attachPrimitive({self.id}) + ''') + if not func: + return + + def wrapper(p): + self.price = float(p) + func(chart, self) + + async def wrapper_async(p): + self.price = float(p) + await func(chart, self) + + self.win.handlers[self.id] = wrapper_async if asyncio.iscoroutinefunction(func) else wrapper + self.run_script(f'{chart.id}.toolBox?.addNewDrawing({self.id})') + + def update(self, price: float): + """ + Moves the horizontal line to the given price. + """ + self.run_script(f'{self.id}.updatePoints({{price: {price}}})') + # self.run_script(f'{self.id}.updatePrice({price})') + self.price = price + + def options(self, color='#1E80F0', style='solid', width=4, text=''): + super().options(color, style, width) + self.run_script(f'{self.id}.applyOptions({{text: `{text}`}})') + + + +class VerticalLine(Drawing): + def __init__(self, chart, time, color, width, style, text, func=None): + super().__init__(chart, func) + self.time = time + self.run_script(f''' + + {self.id} = new Lib.VerticalLine( + {{time: {self.chart._single_datetime_format(time)}}}, + {{ + lineColor: '{color}', + lineStyle: {as_enum(style, LINE_STYLE)}, + width: {width}, + text: `{text}`, + }}, + callbackName={f"'{self.id}'" if func else 'null'} + ) + {chart.id}.series.attachPrimitive({self.id}) + ''') + + def update(self, time: TIME): + self.run_script(f'{self.id}.updatePoints({{time: {time}}})') + # self.run_script(f'{self.id}.updatePrice({price})') + self.price = price + + def options(self, color='#1E80F0', style='solid', width=4, text=''): + super().options(color, style, width) + self.run_script(f'{self.id}.applyOptions({{text: `{text}`}})') + + +class RayLine(Drawing): + def __init__(self, + chart, + start_time: TIME, + value: NUM, + round: bool = False, + color: str = '#1E80F0', + width: int = 2, + style: LINE_STYLE = 'solid', + text: str = '', + func = None, + ): + super().__init__(chart, func) + self.run_script(f''' + {self.id} = new Lib.RayLine( + {{time: {self.chart._single_datetime_format(start_time)}, price: {value}}}, + {{ + lineColor: '{color}', + lineStyle: {as_enum(style, LINE_STYLE)}, + width: {width}, + text: `{text}`, + }}, + callbackName={f"'{self.id}'" if func else 'null'} + ) + {chart.id}.series.attachPrimitive({self.id}) + ''') + + + + +class Box(TwoPointDrawing): + def __init__(self, + chart, + start_time: TIME, + start_value: NUM, + end_time: TIME, + end_value: NUM, + round: bool, + line_color: str, + fill_color: str, + width: int, + style: LINE_STYLE, + func=None): + + super().__init__( + "Box", + chart, + start_time, + start_value, + end_time, + end_value, + round, + { + "lineColor": f'"{line_color}"', + "fillColor": f'"{fill_color}"', + "width": width, + "lineStyle": as_enum(style, LINE_STYLE) + }, + func + ) + + +class TrendLine(TwoPointDrawing): + def __init__(self, + chart, + start_time: TIME, + start_value: NUM, + end_time: TIME, + end_value: NUM, + round: bool, + line_color: str, + width: int, + style: LINE_STYLE, + func=None): + + super().__init__( + "TrendLine", + chart, + start_time, + start_value, + end_time, + end_value, + round, + { + "lineColor": f'"{line_color}"', + "width": width, + "lineStyle": as_enum(style, LINE_STYLE) + }, + func + ) + +# TODO reimplement/fix +class VerticalSpan(Pane): + def __init__(self, series: 'SeriesCommon', start_time: Union[TIME, tuple, list], end_time: Optional[TIME] = None, + color: str = 'rgba(252, 219, 3, 0.2)'): + self._chart = series._chart + super().__init__(self._chart.win) + start_time, end_time = pd.to_datetime(start_time), pd.to_datetime(end_time) + self.run_script(f''' + {self.id} = {self._chart.id}.chart.addHistogramSeries({{ + color: '{color}', + priceFormat: {{type: 'volume'}}, + priceScaleId: 'vertical_line', + lastValueVisible: false, + priceLineVisible: false, + }}) + {self.id}.priceScale('').applyOptions({{ + scaleMargins: {{top: 0, bottom: 0}} + }}) + ''') + if end_time is None: + if isinstance(start_time, pd.DatetimeIndex): + data = [{'time': time.timestamp(), 'value': 1} for time in start_time] + else: + data = [{'time': start_time.timestamp(), 'value': 1}] + self.run_script(f'{self.id}.setData({data})') + else: + self.run_script(f''' + {self.id}.setData(calculateTrendLine( + {start_time.timestamp()}, 1, {end_time.timestamp()}, 1, {series.id})) + ''') + + def delete(self): + """ + Irreversibly deletes the vertical span. + """ + self.run_script(f'{self._chart.id}.chart.removeSeries({self.id})') diff --git a/lightweight_charts/js/bundle.js b/lightweight_charts/js/bundle.js new file mode 100644 index 0000000..2faa61a --- /dev/null +++ b/lightweight_charts/js/bundle.js @@ -0,0 +1 @@ +var Lib=function(t,e){"use strict";const i={backgroundColor:"#0c0d0f",hoverBackgroundColor:"#3c434c",clickBackgroundColor:"#50565E",activeBackgroundColor:"rgba(0, 122, 255, 0.7)",mutedBackgroundColor:"rgba(0, 122, 255, 0.3)",borderColor:"#3C434C",color:"#d8d9db",activeColor:"#ececed"};function s(){window.pane={...i},window.containerDiv=document.getElementById("container")||document.createElement("div"),window.setCursor=t=>{t&&(window.cursor=t),document.body.style.cursor=window.cursor},window.cursor="default"}class o{handler;div;ohlcEnabled=!1;percentEnabled=!1;linesEnabled=!1;colorBasedOnCandle=!1;text;candle;_lines=[];constructor(t){this.legendHandler=this.legendHandler.bind(this),this.handler=t,this.ohlcEnabled=!1,this.percentEnabled=!1,this.linesEnabled=!1,this.colorBasedOnCandle=!1,this.div=document.createElement("div"),this.div.classList.add("legend"),this.div.style.maxWidth=100*t.scale.width-8+"vw",this.div.style.display="none",this.text=document.createElement("span"),this.text.style.lineHeight="1.8",this.candle=document.createElement("div"),this.div.appendChild(this.text),this.div.appendChild(this.candle),t.div.appendChild(this.div),t.chart.subscribeCrosshairMove(this.legendHandler)}toJSON(){const{_lines:t,handler:e,...i}=this;return i}makeSeriesRow(t,e){const i="#FFF";let s=`\n \n \`\n `,o=`\n \n `,n=document.createElement("div");n.style.display="flex",n.style.alignItems="center";let r=document.createElement("div"),a=document.createElement("div");a.classList.add("legend-toggle-switch");let l=document.createElementNS("http://www.w3.org/2000/svg","svg");l.setAttribute("width","22"),l.setAttribute("height","16");let h=document.createElementNS("http://www.w3.org/2000/svg","g");h.innerHTML=s;let d=!0;a.addEventListener("click",(()=>{d?(d=!1,h.innerHTML=o,e.applyOptions({visible:!1})):(d=!0,e.applyOptions({visible:!0}),h.innerHTML=s)})),l.appendChild(h),a.appendChild(l),n.appendChild(r),n.appendChild(a),this.div.appendChild(n);const c=e.options().baseLineColor;this._lines.push({name:t,div:r,row:n,toggle:a,series:e,solid:c.startsWith("rgba")?c.replace(/[^,]+(?=\))/,"1"):c})}legendItemFormat(t,e){return t.toFixed(e).toString().padStart(8," ")}shorthandFormat(t){const e=Math.abs(t);return e>=1e6?(t/1e6).toFixed(1)+"M":e>=1e3?(t/1e3).toFixed(1)+"K":t.toString().padStart(8," ")}legendHandler(t,e=!1){if(!this.ohlcEnabled&&!this.linesEnabled&&!this.percentEnabled)return;const i=this.handler.series.options();if(!t.time)return this.candle.style.color="transparent",void(this.candle.innerHTML=this.candle.innerHTML.replace(i.upColor,"").replace(i.downColor,""));let s,o=null;if(e){const e=this.handler.chart.timeScale();let i=e.timeToCoordinate(t.time);i&&(o=e.coordinateToLogical(i.valueOf())),o&&(s=this.handler.series.dataByIndex(o.valueOf()))}else s=t.seriesData.get(this.handler.series);this.candle.style.color="";let n='';if(s){if(this.ohlcEnabled&&(n+=`O ${this.legendItemFormat(s.open,this.handler.precision)} `,n+=`| H ${this.legendItemFormat(s.high,this.handler.precision)} `,n+=`| L ${this.legendItemFormat(s.low,this.handler.precision)} `,n+=`| C ${this.legendItemFormat(s.close,this.handler.precision)} `),this.percentEnabled){let t=(s.close-s.open)/s.open*100,e=t>0?i.upColor:i.downColor,o=`${t>=0?"+":""}${t.toFixed(2)} %`;this.colorBasedOnCandle?n+=`| ${o}`:n+="| "+o}if(this.handler.volumeSeries){let e;e=o?this.handler.volumeSeries.dataByIndex(o):t.seriesData.get(this.handler.volumeSeries),e&&(n+=this.ohlcEnabled?`
V ${this.shorthandFormat(e.value)}`:"")}}this.candle.innerHTML=n+"
",this._lines.forEach((i=>{if(!this.linesEnabled)return void(i.row.style.display="none");let s,n;if(i.row.style.display="flex",s=e&&o?i.series.dataByIndex(o):t.seriesData.get(i.series),"Histogram"==i.series.seriesType())n=this.shorthandFormat(s.value);else{const t=i.series.options().priceFormat;n=this.legendItemFormat(s.value,t.precision)}i.div.innerHTML=`▨ ${i.name} : ${n}`}))}}function n(t){if(void 0===t)throw new Error("Value is undefined");return t}class r{_chart=void 0;_series=void 0;requestUpdate(){this._requestUpdate&&this._requestUpdate()}_requestUpdate;attached({chart:t,series:e,requestUpdate:i}){this._chart=t,this._series=e,this._series.subscribeDataChanged(this._fireDataUpdated),this._requestUpdate=i,this.requestUpdate()}detached(){this._chart=void 0,this._series=void 0,this._requestUpdate=void 0}get chart(){return n(this._chart)}get series(){return n(this._series)}_fireDataUpdated(t){this.dataUpdated&&this.dataUpdated(t)}}const a={lineColor:"#1E80F0",lineStyle:e.LineStyle.Solid,width:4};var l;!function(t){t[t.NONE=0]="NONE",t[t.HOVERING=1]="HOVERING",t[t.DRAGGING=2]="DRAGGING",t[t.DRAGGINGP1=3]="DRAGGINGP1",t[t.DRAGGINGP2=4]="DRAGGINGP2",t[t.DRAGGINGP3=5]="DRAGGINGP3",t[t.DRAGGINGP4=6]="DRAGGINGP4"}(l||(l={}));class h extends r{_paneViews=[];_options;_points=[];_state=l.NONE;_startDragPoint=null;_latestHoverPoint=null;static _mouseIsDown=!1;static hoveredObject=null;static lastHoveredObject=null;_listeners=[];constructor(t){super(),this._options={...a,...t}}updateAllViews(){this._paneViews.forEach((t=>t.update()))}paneViews(){return this._paneViews}applyOptions(t){this._options={...this._options,...t},this.requestUpdate()}updatePoints(...t){for(let e=0;ei.name===t&&i.listener===e));this._listeners.splice(this._listeners.indexOf(i),1)}_handleHoverInteraction(t){if(this._latestHoverPoint=t.point,h._mouseIsDown)this._handleDragInteraction(t);else if(this._mouseIsOverDrawing(t)){if(this._state!=l.NONE)return;this._moveToState(l.HOVERING),h.hoveredObject=h.lastHoveredObject=this}else{if(this._state==l.NONE)return;this._moveToState(l.NONE),h.hoveredObject===this&&(h.hoveredObject=null)}}static _eventToPoint(t,e){if(!e||!t.point||!t.logical)return null;const i=e.coordinateToPrice(t.point.y);return null==i?null:{time:t.time||null,logical:t.logical,price:i.valueOf()}}static _getDiff(t,e){return{logical:t.logical-e.logical,price:t.price-e.price}}_addDiffToPoint(t,e,i){t&&(t.logical=t.logical+e,t.price=t.price+i,t.time=this.series.dataByIndex(t.logical)?.time||null)}_handleMouseDownInteraction=()=>{h._mouseIsDown=!0,this._onMouseDown()};_handleMouseUpInteraction=()=>{h._mouseIsDown=!1,this._moveToState(l.HOVERING)};_handleDragInteraction(t){if(this._state!=l.DRAGGING&&this._state!=l.DRAGGINGP1&&this._state!=l.DRAGGINGP2&&this._state!=l.DRAGGINGP3&&this._state!=l.DRAGGINGP4)return;const e=h._eventToPoint(t,this.series);if(!e)return;this._startDragPoint=this._startDragPoint||e;const i=h._getDiff(e,this._startDragPoint);this._onDrag(i),this.requestUpdate(),this._startDragPoint=e}}class d{_options;constructor(t){this._options=t}}class c extends d{_p1;_p2;_hovered;constructor(t,e,i,s){super(i),this._p1=t,this._p2=e,this._hovered=s}_getScaledCoordinates(t){return null===this._p1.x||null===this._p1.y||null===this._p2.x||null===this._p2.y?null:{x1:Math.round(this._p1.x*t.horizontalPixelRatio),y1:Math.round(this._p1.y*t.verticalPixelRatio),x2:Math.round(this._p2.x*t.horizontalPixelRatio),y2:Math.round(this._p2.y*t.verticalPixelRatio)}}_drawEndCircle(t,e,i){t.context.fillStyle="#000",t.context.beginPath(),t.context.arc(e,i,9,0,2*Math.PI),t.context.stroke(),t.context.fill()}}function p(t,i){const s={[e.LineStyle.Solid]:[],[e.LineStyle.Dotted]:[t.lineWidth,t.lineWidth],[e.LineStyle.Dashed]:[2*t.lineWidth,2*t.lineWidth],[e.LineStyle.LargeDashed]:[6*t.lineWidth,6*t.lineWidth],[e.LineStyle.SparseDotted]:[t.lineWidth,4*t.lineWidth]}[i];t.setLineDash(s)}class u extends d{_point={x:null,y:null};constructor(t,e){super(e),this._point=t}draw(t){t.useBitmapCoordinateSpace((t=>{if(null==this._point.y)return;const e=t.context,i=Math.round(this._point.y*t.verticalPixelRatio),s=this._point.x?this._point.x*t.horizontalPixelRatio:0;e.lineWidth=this._options.width,e.strokeStyle=this._options.lineColor,p(e,this._options.lineStyle),e.beginPath(),e.moveTo(s,i),e.lineTo(t.bitmapSize.width,i),e.stroke()}))}}class _{_source;constructor(t){this._source=t}}class m extends _{_p1={x:null,y:null};_p2={x:null,y:null};_source;constructor(t){super(t),this._source=t}update(){if(!this._source.p1||!this._source.p2)return;const t=this._source.series,e=t.priceToCoordinate(this._source.p1.price),i=t.priceToCoordinate(this._source.p2.price),s=this._getX(this._source.p1),o=this._getX(this._source.p2);this._p1={x:s,y:e},this._p2={x:o,y:i}}_getX(t){return this._source.chart.timeScale().logicalToCoordinate(t.logical)}}class v extends _{_source;_point={x:null,y:null};constructor(t){super(t),this._source=t}update(){const t=this._source._point,e=this._source.chart.timeScale(),i=this._source.series;"RayLine"==this._source._type&&(this._point.x=t.time?e.timeToCoordinate(t.time):e.logicalToCoordinate(t.logical)),this._point.y=i.priceToCoordinate(t.price)}renderer(){return new u(this._point,this._source._options)}}class g{_source;_y=null;_price=null;constructor(t){this._source=t}update(){if(!this._source.series||!this._source._point)return;this._y=this._source.series.priceToCoordinate(this._source._point.price);const t=this._source.series.options().priceFormat.precision;this._price=this._source._point.price.toFixed(t).toString()}visible(){return!0}tickVisible(){return!0}coordinate(){return this._y??0}text(){return this._source._options.text||this._price||""}textColor(){return"white"}backColor(){return this._source._options.lineColor}}class w extends h{_type="HorizontalLine";_paneViews;_point;_callbackName;_priceAxisViews;_startDragPoint=null;constructor(t,e,i=null){super(e),this._point=t,this._point.time=null,this._paneViews=[new v(this)],this._priceAxisViews=[new g(this)],this._callbackName=i}get points(){return[this._point]}updatePoints(...t){for(const e of t)e&&(this._point.price=e.price);this.requestUpdate()}updateAllViews(){this._paneViews.forEach((t=>t.update())),this._priceAxisViews.forEach((t=>t.update()))}priceAxisViews(){return this._priceAxisViews}_moveToState(t){switch(t){case l.NONE:document.body.style.cursor="default",this._unsubscribe("mousedown",this._handleMouseDownInteraction);break;case l.HOVERING:document.body.style.cursor="pointer",this._unsubscribe("mouseup",this._childHandleMouseUpInteraction),this._subscribe("mousedown",this._handleMouseDownInteraction),this.chart.applyOptions({handleScroll:!0});break;case l.DRAGGING:document.body.style.cursor="grabbing",this._subscribe("mouseup",this._childHandleMouseUpInteraction),this.chart.applyOptions({handleScroll:!1})}this._state=t}_onDrag(t){this._addDiffToPoint(this._point,0,t.price),this.requestUpdate()}_mouseIsOverDrawing(t,e=4){if(!t.point)return!1;const i=this.series.priceToCoordinate(this._point.price);return!!i&&Math.abs(i-t.point.y){this._handleMouseUpInteraction(),this._callbackName&&window.callbackFunction(`${this._callbackName}_~_${this._point.price.toFixed(8)}`)}}class y{_chart;_series;_finishDrawingCallback=null;_drawings=[];_activeDrawing=null;_isDrawing=!1;_drawingType=null;constructor(t,e,i=null){this._chart=t,this._series=e,this._finishDrawingCallback=i,this._chart.subscribeClick(this._clickHandler),this._chart.subscribeCrosshairMove(this._moveHandler)}_clickHandler=t=>this._onClick(t);_moveHandler=t=>this._onMouseMove(t);beginDrawing(t){this._drawingType=t,this._isDrawing=!0}stopDrawing(){this._isDrawing=!1,this._activeDrawing=null}get drawings(){return this._drawings}addNewDrawing(t){this._series.attachPrimitive(t),this._drawings.push(t)}delete(t){if(null==t)return;const e=this._drawings.indexOf(t);-1!=e&&(this._drawings.splice(e,1),t.detach())}clearDrawings(){for(const t of this._drawings)t.detach();this._drawings=[]}repositionOnTime(){for(const t of this.drawings){const e=[];for(const i of t.points){if(!i){e.push(i);continue}const t=i.time?this._chart.timeScale().coordinateToLogical(this._chart.timeScale().timeToCoordinate(i.time)||0):i.logical;e.push({time:i.time,logical:t,price:i.price})}t.updatePoints(...e)}}_onClick(t){if(!this._isDrawing)return;const e=h._eventToPoint(t,this._series);if(e)if(null==this._activeDrawing){if(null==this._drawingType)return;this._activeDrawing=new this._drawingType(e,e),this._series.attachPrimitive(this._activeDrawing),this._drawingType==w&&this._onClick(t)}else{if(this._drawings.push(this._activeDrawing),this.stopDrawing(),!this._finishDrawingCallback)return;this._finishDrawingCallback()}}_onMouseMove(t){if(!t)return;for(const e of this._drawings)e._handleHoverInteraction(t);if(!this._isDrawing||!this._activeDrawing)return;const e=h._eventToPoint(t,this._series);e&&this._activeDrawing.updatePoints(null,e)}}class b extends c{constructor(t,e,i,s){super(t,e,i,s)}draw(t){t.useBitmapCoordinateSpace((t=>{if(null===this._p1.x||null===this._p1.y||null===this._p2.x||null===this._p2.y)return;const e=t.context,i=this._getScaledCoordinates(t);i&&(e.lineWidth=this._options.width,e.strokeStyle=this._options.lineColor,p(e,this._options.lineStyle),e.beginPath(),e.moveTo(i.x1,i.y1),e.lineTo(i.x2,i.y2),e.stroke(),this._hovered&&(this._drawEndCircle(t,i.x1,i.y1),this._drawEndCircle(t,i.x2,i.y2)))}))}}class x extends m{constructor(t){super(t)}renderer(){return new b(this._p1,this._p2,this._source._options,this._source.hovered)}}class C extends h{_paneViews=[];_hovered=!1;constructor(t,e,i){super(),this.points.push(t),this.points.push(e),this._options={...a,...i}}setFirstPoint(t){this.updatePoints(t)}setSecondPoint(t){this.updatePoints(null,t)}get p1(){return this.points[0]}get p2(){return this.points[1]}get hovered(){return this._hovered}}class f extends C{_type="TrendLine";constructor(t,e,i){super(t,e,i),this._paneViews=[new x(this)]}_moveToState(t){switch(t){case l.NONE:document.body.style.cursor="default",this._hovered=!1,this.requestUpdate(),this._unsubscribe("mousedown",this._handleMouseDownInteraction);break;case l.HOVERING:document.body.style.cursor="pointer",this._hovered=!0,this.requestUpdate(),this._subscribe("mousedown",this._handleMouseDownInteraction),this._unsubscribe("mouseup",this._handleMouseDownInteraction),this.chart.applyOptions({handleScroll:!0});break;case l.DRAGGINGP1:case l.DRAGGINGP2:case l.DRAGGING:document.body.style.cursor="grabbing",this._subscribe("mouseup",this._handleMouseUpInteraction),this.chart.applyOptions({handleScroll:!1})}this._state=t}_onDrag(t){this._state!=l.DRAGGING&&this._state!=l.DRAGGINGP1||this._addDiffToPoint(this.p1,t.logical,t.price),this._state!=l.DRAGGING&&this._state!=l.DRAGGINGP2||this._addDiffToPoint(this.p2,t.logical,t.price)}_onMouseDown(){this._startDragPoint=null;const t=this._latestHoverPoint;if(!t)return;const e=this._paneViews[0]._p1,i=this._paneViews[0]._p2;if(!(e.x&&i.x&&e.y&&i.y))return this._moveToState(l.DRAGGING);Math.abs(t.x-e.x)<10&&Math.abs(t.y-e.y)<10?this._moveToState(l.DRAGGINGP1):Math.abs(t.x-i.x)<10&&Math.abs(t.y-i.y)<10?this._moveToState(l.DRAGGINGP2):this._moveToState(l.DRAGGING)}_mouseIsOverDrawing(t,e=4){if(!t.point)return!1;const i=this._paneViews[0]._p1.x,s=this._paneViews[0]._p1.y,o=this._paneViews[0]._p2.x,n=this._paneViews[0]._p2.y;if(!(i&&o&&s&&n))return!1;const r=t.point.x,a=t.point.y;if(r<=Math.min(i,o)-e||r>=Math.max(i,o)+e)return!1;return Math.abs((n-s)*r-(o-i)*a+o*s-n*i)/Math.sqrt((n-s)**2+(o-i)**2)<=e}}class D extends c{constructor(t,e,i,s){super(t,e,i,s)}draw(t){t.useBitmapCoordinateSpace((t=>{const e=t.context,i=this._getScaledCoordinates(t);if(!i)return;e.lineWidth=this._options.width,e.strokeStyle=this._options.lineColor,p(e,this._options.lineStyle),e.fillStyle=this._options.fillColor;const s=Math.min(i.x1,i.x2),o=Math.min(i.y1,i.y2),n=Math.abs(i.x1-i.x2),r=Math.abs(i.y1-i.y2);e.strokeRect(s,o,n,r),e.fillRect(s,o,n,r),this._hovered&&(this._drawEndCircle(t,s,o),this._drawEndCircle(t,s+n,o),this._drawEndCircle(t,s+n,o+r),this._drawEndCircle(t,s,o+r))}))}}class k extends m{constructor(t){super(t)}renderer(){return new D(this._p1,this._p2,this._source._options,this._source.hovered)}}const E={fillEnabled:!0,fillColor:"rgba(255, 255, 255, 0.2)",...a};class L extends C{_type="Box";constructor(t,e,i){super(t,e,i),this._options={...E,...i},this._paneViews=[new k(this)]}_moveToState(t){switch(t){case l.NONE:document.body.style.cursor="default",this._hovered=!1,this._unsubscribe("mousedown",this._handleMouseDownInteraction);break;case l.HOVERING:document.body.style.cursor="pointer",this._hovered=!0,this._unsubscribe("mouseup",this._handleMouseUpInteraction),this._subscribe("mousedown",this._handleMouseDownInteraction),this.chart.applyOptions({handleScroll:!0});break;case l.DRAGGINGP1:case l.DRAGGINGP2:case l.DRAGGINGP3:case l.DRAGGINGP4:case l.DRAGGING:document.body.style.cursor="grabbing",document.body.addEventListener("mouseup",this._handleMouseUpInteraction),this._subscribe("mouseup",this._handleMouseUpInteraction),this.chart.applyOptions({handleScroll:!1})}this._state=t}_onDrag(t){this._state!=l.DRAGGING&&this._state!=l.DRAGGINGP1||this._addDiffToPoint(this.p1,t.logical,t.price),this._state!=l.DRAGGING&&this._state!=l.DRAGGINGP2||this._addDiffToPoint(this.p2,t.logical,t.price),this._state!=l.DRAGGING&&(this._state==l.DRAGGINGP3&&(this._addDiffToPoint(this.p1,t.logical,0),this._addDiffToPoint(this.p2,0,t.price)),this._state==l.DRAGGINGP4&&(this._addDiffToPoint(this.p1,0,t.price),this._addDiffToPoint(this.p2,t.logical,0)))}_onMouseDown(){this._startDragPoint=null;const t=this._latestHoverPoint,e=this._paneViews[0]._p1,i=this._paneViews[0]._p2;if(!(e.x&&i.x&&e.y&&i.y))return this._moveToState(l.DRAGGING);const s=10;Math.abs(t.x-e.x)l-p&&rh-p&&ai.appendChild(this.makeColorBox(t))));let s=document.createElement("div");s.style.backgroundColor=window.pane.borderColor,s.style.height="1px",s.style.width="130px";let o=document.createElement("div");o.style.margin="10px";let n=document.createElement("div");n.style.color="lightgray",n.style.fontSize="12px",n.innerText="Opacity",this._opacityLabel=document.createElement("div"),this._opacityLabel.style.color="lightgray",this._opacityLabel.style.fontSize="12px",this._opacitySlider=document.createElement("input"),this._opacitySlider.type="range",this._opacitySlider.value=(100*this.opacity).toString(),this._opacityLabel.innerText=this._opacitySlider.value+"%",this._opacitySlider.oninput=()=>{this._opacityLabel.innerText=this._opacitySlider.value+"%",this.opacity=parseInt(this._opacitySlider.value)/100,this.updateColor()},o.appendChild(n),o.appendChild(this._opacitySlider),o.appendChild(this._opacityLabel),this._div.appendChild(i),this._div.appendChild(s),this._div.appendChild(o),window.containerDiv.appendChild(this._div)}_updateOpacitySlider(){this._opacitySlider.value=(100*this.opacity).toString(),this._opacityLabel.innerText=this._opacitySlider.value+"%"}makeColorBox(t){const e=document.createElement("div");e.style.width="18px",e.style.height="18px",e.style.borderRadius="3px",e.style.margin="3px",e.style.boxSizing="border-box",e.style.backgroundColor=t,e.addEventListener("mouseover",(()=>e.style.border="2px solid lightgray")),e.addEventListener("mouseout",(()=>e.style.border="none"));const i=S.extractRGBA(t);return e.addEventListener("click",(()=>{this.rgba=i,this.updateColor()})),e}static extractRGBA(t){const e=document.createElement("div");e.style.color=t,document.body.appendChild(e);const i=getComputedStyle(e).color;document.body.removeChild(e);const s=i.match(/\d+/g)?.map(Number);if(!s)return[];let o=i.includes("rgba")?parseFloat(i.split(",")[3]):1;return[s[0],s[1],s[2],o]}updateColor(){if(!h.lastHoveredObject||!this.rgba)return;const t=`rgba(${this.rgba[0]}, ${this.rgba[1]}, ${this.rgba[2]}, ${this.opacity})`;h.lastHoveredObject.applyOptions({[this.colorOption]:t}),this.saveDrawings()}openMenu(t){h.lastHoveredObject&&(this.rgba=S.extractRGBA(h.lastHoveredObject._options[this.colorOption]),this.opacity=this.rgba[3],this._updateOpacitySlider(),this._div.style.top=t.top-30+"px",this._div.style.left=t.right+"px",this._div.style.display="flex",setTimeout((()=>document.addEventListener("mousedown",(t=>{this._div.contains(t.target)||this.closeMenu()}))),10))}closeMenu(){document.body.removeEventListener("click",this.closeMenu),this._div.style.display="none"}}class G{static _styles=[{name:"Solid",var:e.LineStyle.Solid},{name:"Dotted",var:e.LineStyle.Dotted},{name:"Dashed",var:e.LineStyle.Dashed},{name:"Large Dashed",var:e.LineStyle.LargeDashed},{name:"Sparse Dotted",var:e.LineStyle.SparseDotted}];_div;_saveDrawings;constructor(t){this._saveDrawings=t,this._div=document.createElement("div"),this._div.classList.add("context-menu"),G._styles.forEach((t=>{this._div.appendChild(this._makeTextBox(t.name,t.var))})),window.containerDiv.appendChild(this._div)}_makeTextBox(t,e){const i=document.createElement("span");return i.classList.add("context-menu-item"),i.innerText=t,i.addEventListener("click",(()=>{h.lastHoveredObject?.applyOptions({lineStyle:e}),this._saveDrawings()})),i}openMenu(t){this._div.style.top=t.top-30+"px",this._div.style.left=t.right+"px",this._div.style.display="block",setTimeout((()=>document.addEventListener("mousedown",(t=>{this._div.contains(t.target)||this.closeMenu()}))),10)}closeMenu(){document.removeEventListener("click",this.closeMenu),this._div.style.display="none"}}function T(t){const e=[];for(const i of t)0==e.length?e.push(i.toUpperCase()):i==i.toUpperCase()?e.push(" "+i):e.push(i);return e.join("")}class I{saveDrawings;drawingTool;div;hoverItem;items=[];constructor(t,e){this.saveDrawings=t,this.drawingTool=e,this._onRightClick=this._onRightClick.bind(this),this.div=document.createElement("div"),this.div.classList.add("context-menu"),document.body.appendChild(this.div),this.hoverItem=null,document.body.addEventListener("contextmenu",this._onRightClick)}_handleClick=t=>this._onClick(t);_onClick(t){t.target&&(this.div.contains(t.target)||(this.div.style.display="none",document.body.removeEventListener("click",this._handleClick)))}_onRightClick(t){if(!h.hoveredObject)return;for(const t of this.items)this.div.removeChild(t);this.items=[];for(const t of Object.keys(h.hoveredObject._options)){let e;if(t.toLowerCase().includes("color"))e=new S(this.saveDrawings,t);else{if("lineStyle"!==t)continue;e=new G(this.saveDrawings)}let i=t=>e.openMenu(t);this.menuItem(T(t),i,(()=>{document.removeEventListener("click",e.closeMenu),e._div.style.display="none"}))}this.separator(),this.menuItem("Delete Drawing",(()=>this.drawingTool.delete(h.lastHoveredObject))),t.preventDefault(),this.div.style.left=t.clientX+"px",this.div.style.top=t.clientY+"px",this.div.style.display="block",document.body.addEventListener("click",this._handleClick)}menuItem(t,e,i=null){const s=document.createElement("span");s.classList.add("context-menu-item"),this.div.appendChild(s);const o=document.createElement("span");if(o.innerText=t,o.style.pointerEvents="none",s.appendChild(o),i){let t=document.createElement("span");t.innerText="►",t.style.fontSize="8px",t.style.pointerEvents="none",s.appendChild(t)}if(s.addEventListener("mouseover",(()=>{this.hoverItem&&this.hoverItem.closeAction&&this.hoverItem.closeAction(),this.hoverItem={elem:o,action:e,closeAction:i}})),i){let t;s.addEventListener("mouseover",(()=>t=setTimeout((()=>e(s.getBoundingClientRect())),100))),s.addEventListener("mouseout",(()=>clearTimeout(t)))}else s.addEventListener("click",(t=>{e(t),this.div.style.display="none"}));this.items.push(s)}separator(){const t=document.createElement("div");t.style.width="90%",t.style.height="1px",t.style.margin="3px 0px",t.style.backgroundColor=window.pane.borderColor,this.div.appendChild(t),this.items.push(t)}}class M extends w{_type="RayLine";constructor(t,e){super({...t},e),this._point.time=t.time}updatePoints(...t){for(const e of t)e&&(this._point=e);this.requestUpdate()}_onDrag(t){this._addDiffToPoint(this._point,t.logical,t.price),this.requestUpdate()}_mouseIsOverDrawing(t,e=4){if(!t.point)return!1;const i=this.series.priceToCoordinate(this._point.price),s=this._point.time?this.chart.timeScale().timeToCoordinate(this._point.time):null;return!(!i||!s)&&(Math.abs(i-t.point.y)s-e)}}class N extends d{_point={x:null,y:null};constructor(t,e){super(e),this._point=t}draw(t){t.useBitmapCoordinateSpace((t=>{if(null==this._point.x)return;const e=t.context,i=this._point.x*t.horizontalPixelRatio;e.lineWidth=this._options.width,e.strokeStyle=this._options.lineColor,p(e,this._options.lineStyle),e.beginPath(),e.moveTo(i,0),e.lineTo(i,t.bitmapSize.height),e.stroke()}))}}class R extends _{_source;_point={x:null,y:null};constructor(t){super(t),this._source=t}update(){const t=this._source._point,e=this._source.chart.timeScale(),i=this._source.series;this._point.x=t.time?e.timeToCoordinate(t.time):e.logicalToCoordinate(t.logical),this._point.y=i.priceToCoordinate(t.price)}renderer(){return new N(this._point,this._source._options)}}class A{_source;_x=null;constructor(t){this._source=t}update(){if(!this._source.chart||!this._source._point)return;const t=this._source._point,e=this._source.chart.timeScale();this._x=t.time?e.timeToCoordinate(t.time):e.logicalToCoordinate(t.logical)}visible(){return!!this._source._options.text}tickVisible(){return!0}coordinate(){return this._x??0}text(){return this._source._options.text||""}textColor(){return"white"}backColor(){return this._source._options.lineColor}}class P extends h{_type="VerticalLine";_paneViews;_timeAxisViews;_point;_callbackName;_startDragPoint=null;constructor(t,e,i=null){super(e),this._point=t,this._paneViews=[new R(this)],this._callbackName=i,this._timeAxisViews=[new A(this)]}updateAllViews(){this._paneViews.forEach((t=>t.update())),this._timeAxisViews.forEach((t=>t.update()))}timeAxisViews(){return this._timeAxisViews}updatePoints(...t){for(const e of t)e&&(!e.time&&e.logical&&(e.time=this.series.dataByIndex(e.logical)?.time||null),this._point=e);this.requestUpdate()}get points(){return[this._point]}_moveToState(t){switch(t){case l.NONE:document.body.style.cursor="default",this._unsubscribe("mousedown",this._handleMouseDownInteraction);break;case l.HOVERING:document.body.style.cursor="pointer",this._unsubscribe("mouseup",this._childHandleMouseUpInteraction),this._subscribe("mousedown",this._handleMouseDownInteraction),this.chart.applyOptions({handleScroll:!0});break;case l.DRAGGING:document.body.style.cursor="grabbing",this._subscribe("mouseup",this._childHandleMouseUpInteraction),this.chart.applyOptions({handleScroll:!1})}this._state=t}_onDrag(t){this._addDiffToPoint(this._point,t.logical,0),this.requestUpdate()}_mouseIsOverDrawing(t,e=4){if(!t.point)return!1;const i=this.chart.timeScale();let s;return s=this._point.time?i.timeToCoordinate(this._point.time):i.logicalToCoordinate(this._point.logical),!!s&&Math.abs(s-t.point.x){this._handleMouseUpInteraction(),this._callbackName&&window.callbackFunction(`${this._callbackName}_~_${this._point.price.toFixed(8)}`)}}class B{static TREND_SVG='';static HORZ_SVG='';static RAY_SVG='';static BOX_SVG='';static VERT_SVG=B.RAY_SVG;div;activeIcon=null;buttons=[];_commandFunctions;_handlerID;_drawingTool;constructor(t,e,i,s){this._handlerID=t,this._commandFunctions=s,this._drawingTool=new y(e,i,(()=>this.removeActiveAndSave())),this.div=this._makeToolBox(),new I(this.saveDrawings,this._drawingTool),s.push((t=>{if((t.metaKey||t.ctrlKey)&&"KeyZ"===t.code){const t=this._drawingTool.drawings.pop();return t&&this._drawingTool.delete(t),!0}return!1}))}toJSON(){const{...t}=this;return t}_makeToolBox(){let t=document.createElement("div");t.classList.add("toolbox"),this.buttons.push(this._makeToolBoxElement(f,"KeyT",B.TREND_SVG)),this.buttons.push(this._makeToolBoxElement(w,"KeyH",B.HORZ_SVG)),this.buttons.push(this._makeToolBoxElement(M,"KeyR",B.RAY_SVG)),this.buttons.push(this._makeToolBoxElement(L,"KeyB",B.BOX_SVG)),this.buttons.push(this._makeToolBoxElement(P,"KeyV",B.VERT_SVG,!0));for(const e of this.buttons)t.appendChild(e);return t}_makeToolBoxElement(t,e,i,s=!1){const o=document.createElement("div");o.classList.add("toolbox-button");const n=document.createElementNS("http://www.w3.org/2000/svg","svg");n.setAttribute("width","29"),n.setAttribute("height","29");const r=document.createElementNS("http://www.w3.org/2000/svg","g");r.innerHTML=i,r.setAttribute("fill",window.pane.color),n.appendChild(r),o.appendChild(n);const a={div:o,group:r,type:t};return o.addEventListener("click",(()=>this._onIconClick(a))),this._commandFunctions.push((t=>this._handlerID===window.handlerInFocus&&(!(!t.altKey||t.code!==e)&&(t.preventDefault(),this._onIconClick(a),!0)))),1==s&&(n.style.transform="rotate(90deg)",n.style.transformBox="fill-box",n.style.transformOrigin="center"),o}_onIconClick(t){this.activeIcon&&(this.activeIcon.div.classList.remove("active-toolbox-button"),window.setCursor("crosshair"),this._drawingTool?.stopDrawing(),this.activeIcon===t)?this.activeIcon=null:(this.activeIcon=t,this.activeIcon.div.classList.add("active-toolbox-button"),window.setCursor("crosshair"),this._drawingTool?.beginDrawing(this.activeIcon.type))}removeActiveAndSave=()=>{window.setCursor("default"),this.activeIcon&&this.activeIcon.div.classList.remove("active-toolbox-button"),this.activeIcon=null,this.saveDrawings()};addNewDrawing(t){this._drawingTool.addNewDrawing(t)}clearDrawings(){this._drawingTool.clearDrawings()}saveDrawings=()=>{const t=[];for(const e of this._drawingTool.drawings)t.push({type:e._type,points:e.points,options:e._options});const e=JSON.stringify(t);window.callbackFunction(`save_drawings${this._handlerID}_~_${e}`)};loadDrawings(t){t.forEach((t=>{switch(t.type){case"Box":this._drawingTool.addNewDrawing(new L(t.points[0],t.points[1],t.options));break;case"TrendLine":this._drawingTool.addNewDrawing(new f(t.points[0],t.points[1],t.options));break;case"HorizontalLine":this._drawingTool.addNewDrawing(new w(t.points[0],t.options));break;case"RayLine":this._drawingTool.addNewDrawing(new M(t.points[0],t.options));break;case"VerticalLine":this._drawingTool.addNewDrawing(new P(t.points[0],t.options))}}))}}class O{makeButton;callbackName;div;isOpen=!1;widget;constructor(t,e,i,s,o,n){this.makeButton=t,this.callbackName=e,this.div=document.createElement("div"),this.div.classList.add("topbar-menu"),this.widget=this.makeButton(s+" ↓",null,o,!0,n),this.updateMenuItems(i),this.widget.elem.addEventListener("click",(()=>{if(this.isOpen=!this.isOpen,!this.isOpen)return void(this.div.style.display="none");let t=this.widget.elem.getBoundingClientRect();this.div.style.display="flex",this.div.style.flexDirection="column";let e=t.x+t.width/2;this.div.style.left=e-this.div.clientWidth/2+"px",this.div.style.top=t.y+t.height+"px"})),document.body.appendChild(this.div)}updateMenuItems(t){this.div.innerHTML="",t.forEach((t=>{let e=this.makeButton(t,null,!1,!1);e.elem.addEventListener("click",(()=>{this.widget.elem.innerText=e.elem.innerText+" ↓",window.callbackFunction(`${this.callbackName}_~_${e.elem.innerText}`),this.div.style.display="none",this.isOpen=!1})),e.elem.style.margin="4px 4px",e.elem.style.padding="2px 2px",this.div.appendChild(e.elem)})),this.widget.elem.innerText=t[0]+" ↓"}}class V{_handler;_div;left;right;constructor(t){this._handler=t,this._div=document.createElement("div"),this._div.classList.add("topbar");const e=t=>{const e=document.createElement("div");return e.classList.add("topbar-container"),e.style.justifyContent=t,this._div.appendChild(e),e};this.left=e("flex-start"),this.right=e("flex-end")}makeSwitcher(t,e,i,s="left"){const o=document.createElement("div");let n;o.style.margin="4px 12px";const r={elem:o,callbackName:i,intervalElements:t.map((t=>{const i=document.createElement("button");i.classList.add("topbar-button"),i.classList.add("switcher-button"),i.style.margin="0px 2px",i.innerText=t,t==e&&(n=i,i.classList.add("active-switcher-button"));const s=V.getClientWidth(i);return i.style.minWidth=s+1+"px",i.addEventListener("click",(()=>r.onItemClicked(i))),o.appendChild(i),i})),onItemClicked:t=>{t!=n&&(n.classList.remove("active-switcher-button"),t.classList.add("active-switcher-button"),n=t,window.callbackFunction(`${r.callbackName}_~_${t.innerText}`))}};return this.appendWidget(o,s,!0),r}makeTextBoxWidget(t,e="left",i=null){if(i){const s=document.createElement("input");return s.classList.add("topbar-textbox-input"),s.value=t,s.style.width=`${s.value.length+2}ch`,s.addEventListener("input",(t=>{s.style.width=`${s.value.length+2}ch`})),s.addEventListener("keydown",(t=>{"Enter"==t.key&&(t.preventDefault(),s.blur())})),s.addEventListener("blur",(()=>{window.callbackFunction(`${i}_~_${s.value}`)})),this.appendWidget(s,e,!0),s}{const i=document.createElement("div");return i.classList.add("topbar-textbox"),i.innerText=t,this.appendWidget(i,e,!0),i}}makeMenu(t,e,i,s,o){return new O(this.makeButton.bind(this),s,t,e,i,o)}makeButton(t,e,i,s=!0,o="left",n=!1){let r=document.createElement("button");r.classList.add("topbar-button"),r.innerText=t,document.body.appendChild(r),r.style.minWidth=r.clientWidth+1+"px",document.body.removeChild(r);let a={elem:r,callbackName:e};if(e){let t;if(n){let e=!1;t=()=>{e=!e,window.callbackFunction(`${a.callbackName}_~_${e}`),r.style.backgroundColor=e?"var(--active-bg-color)":"",r.style.color=e?"var(--active-color)":""}}else t=()=>window.callbackFunction(`${a.callbackName}_~_${r.innerText}`);r.addEventListener("click",t)}return s&&this.appendWidget(r,o,i),a}makeSeparator(t="left"){const e=document.createElement("div");e.classList.add("topbar-seperator");("left"==t?this.left:this.right).appendChild(e)}appendWidget(t,e,i){const s="left"==e?this.left:this.right;i?("left"==e&&s.appendChild(t),this.makeSeparator(e),"right"==e&&s.appendChild(t)):s.appendChild(t),this._handler.reSize()}static getClientWidth(t){document.body.appendChild(t);const e=t.clientWidth;return document.body.removeChild(t),e}}s();return t.Box=L,t.Handler=class{id;commandFunctions=[];wrapper;div;chart;scale;precision=2;series;volumeSeries;legend;_topBar;toolBox;spinner;_seriesList=[];constructor(t,e,i,s,n){this.reSize=this.reSize.bind(this),this.id=t,this.scale={width:e,height:i},this.wrapper=document.createElement("div"),this.wrapper.classList.add("handler"),this.wrapper.style.float=s,this.div=document.createElement("div"),this.div.style.position="relative",this.wrapper.appendChild(this.div),window.containerDiv.append(this.wrapper),this.chart=this._createChart(),this.series=this.createCandlestickSeries(),this.volumeSeries=this.createVolumeSeries(),this.legend=new o(this),document.addEventListener("keydown",(t=>{for(let e=0;ewindow.handlerInFocus=this.id)),this.reSize(),n&&window.addEventListener("resize",(()=>this.reSize()))}reSize(){let t=0!==this.scale.height&&this._topBar?._div.offsetHeight||0;this.chart.resize(window.innerWidth*this.scale.width,window.innerHeight*this.scale.height-t),this.wrapper.style.width=100*this.scale.width+"%",this.wrapper.style.height=100*this.scale.height+"%",0===this.scale.height||0===this.scale.width?this.toolBox&&(this.toolBox.div.style.display="none"):this.toolBox&&(this.toolBox.div.style.display="flex")}_createChart(){return e.createChart(this.div,{width:window.innerWidth*this.scale.width,height:window.innerHeight*this.scale.height,layout:{textColor:window.pane.color,background:{color:"#000000",type:e.ColorType.Solid},fontSize:12},rightPriceScale:{scaleMargins:{top:.3,bottom:.25}},timeScale:{timeVisible:!0,secondsVisible:!1},crosshair:{mode:e.CrosshairMode.Normal,vertLine:{labelBackgroundColor:"rgb(46, 46, 46)"},horzLine:{labelBackgroundColor:"rgb(55, 55, 55)"}},grid:{vertLines:{color:"rgba(29, 30, 38, 5)"},horzLines:{color:"rgba(29, 30, 58, 5)"}},handleScroll:{vertTouchDrag:!0}})}createCandlestickSeries(){const t="rgba(39, 157, 130, 100)",e="rgba(200, 97, 100, 100)",i=this.chart.addCandlestickSeries({upColor:t,borderUpColor:t,wickUpColor:t,downColor:e,borderDownColor:e,wickDownColor:e});return i.priceScale().applyOptions({scaleMargins:{top:.2,bottom:.2}}),i}createVolumeSeries(){const t=this.chart.addHistogramSeries({color:"#26a69a",priceFormat:{type:"volume"},priceScaleId:"volume_scale"});return t.priceScale().applyOptions({scaleMargins:{top:.8,bottom:0}}),t}createLineSeries(t,e){const i=this.chart.addLineSeries({...e});return this._seriesList.push(i),this.legend.makeSeriesRow(t,i),{name:t,series:i}}createHistogramSeries(t,e){const i=this.chart.addHistogramSeries({...e});return this._seriesList.push(i),this.legend.makeSeriesRow(t,i),{name:t,series:i}}createToolBox(){this.toolBox=new B(this.id,this.chart,this.series,this.commandFunctions),this.div.appendChild(this.toolBox.div)}createTopBar(){return this._topBar=new V(this),this.wrapper.prepend(this._topBar._div),this._topBar}toJSON(){const{chart:t,...e}=this;return e}static syncCharts(t,e,i=!1){function s(t,e){e?(t.chart.setCrosshairPosition(e.value||e.close,e.time,t.series),t.legend.legendHandler(e,!0)):t.chart.clearCrosshairPosition()}function o(t,e){return e.time&&e.seriesData.get(t)||null}const n=t.chart.timeScale(),r=e.chart.timeScale(),a=t=>{t&&n.setVisibleLogicalRange(t)},l=t=>{t&&r.setVisibleLogicalRange(t)},h=i=>{s(e,o(t.series,i))},d=i=>{s(t,o(e.series,i))};let c=e;function p(t,e,s,o,n,r){t.wrapper.addEventListener("mouseover",(()=>{c!==t&&(c=t,e.chart.unsubscribeCrosshairMove(s),t.chart.subscribeCrosshairMove(o),i||(e.chart.timeScale().unsubscribeVisibleLogicalRangeChange(n),t.chart.timeScale().subscribeVisibleLogicalRangeChange(r)))}))}p(e,t,h,d,l,a),p(t,e,d,h,a,l),e.chart.subscribeCrosshairMove(d);const u=r.getVisibleLogicalRange();u&&n.setVisibleLogicalRange(u),i||e.chart.timeScale().subscribeVisibleLogicalRangeChange(a)}static makeSearchBox(t){const e=document.createElement("div");e.classList.add("searchbox"),e.style.display="none";const i=document.createElement("div");i.innerHTML='';const s=document.createElement("input");return s.type="text",e.appendChild(i),e.appendChild(s),t.div.appendChild(e),t.commandFunctions.push((i=>window.handlerInFocus===t.id&&("none"===e.style.display?!!/^[a-zA-Z0-9]$/.test(i.key)&&(e.style.display="flex",s.focus(),!0):("Enter"===i.key||"Escape"===i.key)&&("Enter"===i.key&&window.callbackFunction(`search${t.id}_~_${s.value}`),e.style.display="none",s.value="",!0)))),s.addEventListener("input",(()=>s.value=s.value.toUpperCase())),{window:e,box:s}}static makeSpinner(t){t.spinner=document.createElement("div"),t.spinner.classList.add("spinner"),t.wrapper.appendChild(t.spinner);let e=0;!function i(){t.spinner&&(e+=10,t.spinner.style.transform=`translate(-50%, -50%) rotate(${e}deg)`,requestAnimationFrame(i))}()}static _styleMap={"--bg-color":"backgroundColor","--hover-bg-color":"hoverBackgroundColor","--click-bg-color":"clickBackgroundColor","--active-bg-color":"activeBackgroundColor","--muted-bg-color":"mutedBackgroundColor","--border-color":"borderColor","--color":"color","--active-color":"activeColor"};static setRootStyles(t){const e=document.documentElement.style;for(const[i,s]of Object.entries(this._styleMap))e.setProperty(i,t[s])}},t.HorizontalLine=w,t.Legend=o,t.RayLine=M,t.Table=class{_div;callbackName;borderColor;borderWidth;table;rows={};headings;widths;alignments;footer;header;constructor(t,e,i,s,o,n,r=!1,a,l,h,d,c){this._div=document.createElement("div"),this.callbackName=null,this.borderColor=l,this.borderWidth=h,r?(this._div.style.position="absolute",this._div.style.cursor="move"):(this._div.style.position="relative",this._div.style.float=n),this._div.style.zIndex="2000",this.reSize(t,e),this._div.style.display="flex",this._div.style.flexDirection="column",this._div.style.borderRadius="5px",this._div.style.color="white",this._div.style.fontSize="12px",this._div.style.fontVariantNumeric="tabular-nums",this.table=document.createElement("table"),this.table.style.width="100%",this.table.style.borderCollapse="collapse",this._div.style.overflow="hidden",this.headings=i,this.widths=s.map((t=>100*t+"%")),this.alignments=o;let p=this.table.createTHead().insertRow();for(let t=0;t0?c[t]:a,e.style.color=d[t],p.appendChild(e)}let u,_,m=document.createElement("div");if(m.style.overflowY="auto",m.style.overflowX="hidden",m.style.backgroundColor=a,m.appendChild(this.table),this._div.appendChild(m),window.containerDiv.appendChild(this._div),!r)return;let v=t=>{this._div.style.left=t.clientX-u+"px",this._div.style.top=t.clientY-_+"px"},g=()=>{document.removeEventListener("mousemove",v),document.removeEventListener("mouseup",g)};this._div.addEventListener("mousedown",(t=>{u=t.clientX-this._div.offsetLeft,_=t.clientY-this._div.offsetTop,document.addEventListener("mousemove",v),document.addEventListener("mouseup",g)}))}divToButton(t,e){t.addEventListener("mouseover",(()=>t.style.backgroundColor="rgba(60, 60, 60, 0.6)")),t.addEventListener("mouseout",(()=>t.style.backgroundColor="transparent")),t.addEventListener("mousedown",(()=>t.style.backgroundColor="rgba(60, 60, 60)")),t.addEventListener("click",(()=>window.callbackFunction(e))),t.addEventListener("mouseup",(()=>t.style.backgroundColor="rgba(60, 60, 60, 0.6)"))}newRow(t,e=!1){let i=this.table.insertRow();i.style.cursor="default";for(let s=0;s{t&&(window.cursor=t),document.body.style.cursor=window.cursor},t}({},LightweightCharts); diff --git a/lightweight_charts/js/callback.js b/lightweight_charts/js/callback.js deleted file mode 100644 index 5d1cde3..0000000 --- a/lightweight_charts/js/callback.js +++ /dev/null @@ -1,277 +0,0 @@ -if (!window.TopBar) { - class TopBar { - constructor(chart) { - this.makeSwitcher = this.makeSwitcher.bind(this) - this.topBar = document.createElement('div') - this.topBar.style.backgroundColor = pane.backgroundColor - this.topBar.style.borderBottom = '2px solid '+pane.borderColor - this.topBar.style.display = 'flex' - this.topBar.style.alignItems = 'center' - - let createTopBarContainer = (justification) => { - let div = document.createElement('div') - div.style.display = 'flex' - div.style.alignItems = 'center' - div.style.justifyContent = justification - div.style.flexGrow = '1' - this.topBar.appendChild(div) - return div - } - this.left = createTopBarContainer('flex-start') - this.right = createTopBarContainer('flex-end') - - chart.wrapper.prepend(this.topBar) - chart.topBar = this.topBar - this.reSize = () => chart.reSize() - this.reSize() - } - makeSwitcher(items, activeItem, callbackName, align='left') { - let switcherElement = document.createElement('div'); - switcherElement.style.margin = '4px 12px' - let widget = { - elem: switcherElement, - callbackName: callbackName, - intervalElements: null, - onItemClicked: null, - } - widget.intervalElements = items.map((item)=> { - let itemEl = document.createElement('button'); - itemEl.style.border = 'none' - itemEl.style.padding = '2px 5px' - itemEl.style.margin = '0px 2px' - itemEl.style.fontSize = '13px' - itemEl.style.borderRadius = '4px' - itemEl.style.backgroundColor = item === activeItem ? pane.activeBackgroundColor : 'transparent' - itemEl.style.color = item === activeItem ? pane.activeColor : pane.color - itemEl.innerText = item; - document.body.appendChild(itemEl) - itemEl.style.minWidth = itemEl.clientWidth + 1 + 'px' - document.body.removeChild(itemEl) - - itemEl.addEventListener('mouseenter', () => itemEl.style.backgroundColor = item === activeItem ? pane.activeBackgroundColor : pane.hoverBackgroundColor) - itemEl.addEventListener('mouseleave', () => itemEl.style.backgroundColor = item === activeItem ? pane.activeBackgroundColor : 'transparent') - itemEl.addEventListener('mousedown', () => itemEl.style.backgroundColor = item === activeItem ? pane.activeBackgroundColor : pane.clickBackgroundColor) - itemEl.addEventListener('mouseup', () => itemEl.style.backgroundColor = item === activeItem ? pane.activeBackgroundColor : pane.hoverBackgroundColor) - itemEl.addEventListener('click', () => widget.onItemClicked(item)) - - switcherElement.appendChild(itemEl); - return itemEl; - }); - widget.onItemClicked = (item)=> { - if (item === activeItem) return - widget.intervalElements.forEach((element, index) => { - element.style.backgroundColor = items[index] === item ? pane.activeBackgroundColor : 'transparent' - element.style.color = items[index] === item ? pane.activeColor : pane.color - element.style.fontWeight = items[index] === item ? '500' : 'normal' - }) - activeItem = item; - window.callbackFunction(`${widget.callbackName}_~_${item}`); - } - this.appendWidget(switcherElement, align, true) - return widget - } - makeTextBoxWidget(text, align='left') { - let textBox = document.createElement('div') - textBox.style.margin = '0px 18px' - textBox.style.fontSize = '16px' - textBox.style.color = pane.color - textBox.innerText = text - this.appendWidget(textBox, align, true) - return textBox - } - - makeMenu(items, activeItem, separator, callbackName, align='right') { - let menu = document.createElement('div') - menu.style.position = 'absolute' - menu.style.display = 'none' - menu.style.zIndex = '100000' - menu.style.backgroundColor = pane.backgroundColor - menu.style.borderRadius = '2px' - menu.style.border = '2px solid '+pane.borderColor - menu.style.borderTop = 'none' - menu.style.alignItems = 'flex-start' - menu.style.maxHeight = '80%' - menu.style.overflowY = 'auto' - menu.style.scrollbar - - let menuOpen = false - items.forEach(text => { - let button = this.makeButton(text, null, false, false) - button.elem.addEventListener('click', () => { - widget.elem.innerText = button.elem.innerText+' ↓' - window.callbackFunction(`${callbackName}_~_${button.elem.innerText}`) - menu.style.display = 'none' - menuOpen = false - }); - button.elem.style.margin = '4px 4px' - button.elem.style.padding = '2px 2px' - menu.appendChild(button.elem) - }) - let widget = - this.makeButton(activeItem+' ↓', null, separator, true, align) - - widget.elem.addEventListener('click', () => { - menuOpen = !menuOpen - if (!menuOpen) return menu.style.display = 'none' - let rect = widget.elem.getBoundingClientRect() - menu.style.display = 'flex' - menu.style.flexDirection = 'column' - - let center = rect.x+(rect.width/2) - menu.style.left = center-(menu.clientWidth/2)+'px' - menu.style.top = rect.y+rect.height+'px' - }) - document.body.appendChild(menu) - } - - makeButton(defaultText, callbackName, separator, append=true, align='left') { - let button = document.createElement('button') - button.style.border = 'none' - button.style.padding = '2px 5px' - button.style.margin = '4px 10px' - button.style.fontSize = '13px' - button.style.backgroundColor = 'transparent' - button.style.color = pane.color - button.style.borderRadius = '4px' - button.innerText = defaultText; - document.body.appendChild(button) - button.style.minWidth = button.clientWidth+1+'px' - document.body.removeChild(button) - - let widget = { - elem: button, - callbackName: callbackName - } - - button.addEventListener('mouseenter', () => button.style.backgroundColor = pane.hoverBackgroundColor) - button.addEventListener('mouseleave', () => button.style.backgroundColor = 'transparent') - if (callbackName) { - button.addEventListener('click', () => window.callbackFunction(`${widget.callbackName}_~_${button.innerText}`)); - } - button.addEventListener('mousedown', () => { - button.style.backgroundColor = pane.activeBackgroundColor - button.style.color = pane.activeColor - button.style.fontWeight = '500' - }) - button.addEventListener('mouseup', () => { - button.style.backgroundColor = pane.hoverBackgroundColor - button.style.color = pane.color - button.style.fontWeight = 'normal' - }) - if (append) this.appendWidget(button, align, separator) - return widget - } - - makeSeparator(align='left') { - let seperator = document.createElement('div') - seperator.style.width = '1px' - seperator.style.height = '20px' - seperator.style.backgroundColor = pane.borderColor - let div = align === 'left' ? this.left : this.right - div.appendChild(seperator) - } - - appendWidget(widget, align, separator) { - let div = align === 'left' ? this.left : this.right - if (separator) { - if (align === 'left') div.appendChild(widget) - this.makeSeparator(align) - if (align === 'right') div.appendChild(widget) - } else div.appendChild(widget) - this.reSize() - } - } - window.TopBar = TopBar -} - -function makeSearchBox(chart) { - let searchWindow = document.createElement('div') - searchWindow.style.position = 'absolute' - searchWindow.style.top = '0' - searchWindow.style.bottom = '200px' - searchWindow.style.left = '0' - searchWindow.style.right = '0' - searchWindow.style.margin = 'auto' - searchWindow.style.width = '150px' - searchWindow.style.height = '30px' - searchWindow.style.padding = '5px' - searchWindow.style.zIndex = '1000' - searchWindow.style.alignItems = 'center' - searchWindow.style.backgroundColor = 'rgba(30, 30, 30, 0.9)' - searchWindow.style.border = '2px solid '+pane.borderColor - searchWindow.style.borderRadius = '5px' - searchWindow.style.display = 'none' - - let magnifyingGlass = document.createElement('div'); - magnifyingGlass.innerHTML = `` - - let sBox = document.createElement('input'); - sBox.type = 'text'; - sBox.style.textAlign = 'center' - sBox.style.width = '100px' - sBox.style.marginLeft = '10px' - sBox.style.backgroundColor = pane.mutedBackgroundColor - sBox.style.color = pane.activeColor - sBox.style.fontSize = '20px' - sBox.style.border = 'none' - sBox.style.outline = 'none' - sBox.style.borderRadius = '2px' - - searchWindow.appendChild(magnifyingGlass) - searchWindow.appendChild(sBox) - chart.div.appendChild(searchWindow); - - let yPrice = null - chart.chart.subscribeCrosshairMove((param) => { - if (param.point) yPrice = param.point.y; - }) - chart.commandFunctions.push((event) => { - if (selectedChart !== chart) return false - if (searchWindow.style.display === 'none') { - if (/^[a-zA-Z0-9]$/.test(event.key)) { - searchWindow.style.display = 'flex'; - sBox.focus(); - return true - } - else return false - } - else if (event.key === 'Enter' || event.key === 'Escape') { - if (event.key === 'Enter') window.callbackFunction(`search${chart.id}_~_${sBox.value}`) - searchWindow.style.display = 'none' - sBox.value = '' - return true - } - else return false - }) - sBox.addEventListener('input', () => sBox.value = sBox.value.toUpperCase()) - return { - window: searchWindow, - box: sBox, - } -} - -function makeSpinner(chart) { - chart.spinner = document.createElement('div') - chart.spinner.style.width = '30px' - chart.spinner.style.height = '30px' - chart.spinner.style.border = '4px solid rgba(255, 255, 255, 0.6)' - chart.spinner.style.borderTop = '4px solid '+pane.activeBackgroundColor - chart.spinner.style.borderRadius = '50%' - chart.spinner.style.position = 'absolute' - chart.spinner.style.top = '50%' - chart.spinner.style.left = '50%' - chart.spinner.style.zIndex = '1000' - chart.spinner.style.transform = 'translate(-50%, -50%)' - chart.spinner.style.display = 'none' - chart.wrapper.appendChild(chart.spinner) - let rotation = 0; - const speed = 10; - function animateSpinner() { - rotation += speed - chart.spinner.style.transform = `translate(-50%, -50%) rotate(${rotation}deg)` - requestAnimationFrame(animateSpinner) - } - animateSpinner(); -} - - diff --git a/lightweight_charts/js/funcs.js b/lightweight_charts/js/funcs.js deleted file mode 100644 index 0e4a396..0000000 --- a/lightweight_charts/js/funcs.js +++ /dev/null @@ -1,595 +0,0 @@ -if (!window.Chart) { - window.pane = { - backgroundColor: '#0c0d0f', - hoverBackgroundColor: '#3c434c', - clickBackgroundColor: '#50565E', - activeBackgroundColor: 'rgba(0, 122, 255, 0.7)', - mutedBackgroundColor: 'rgba(0, 122, 255, 0.3)', - borderColor: '#3C434C', - color: '#d8d9db', - activeColor: '#ececed', - } - - class Chart { - constructor(chartId, innerWidth, innerHeight, position, autoSize) { - this.makeCandlestickSeries = this.makeCandlestickSeries.bind(this) - this.reSize = this.reSize.bind(this) - this.id = chartId - this.lines = [] - this.interval = null - this.wrapper = document.createElement('div') - this.div = document.createElement('div') - this.scale = { - width: innerWidth, - height: innerHeight, - } - this.commandFunctions = [] - this.chart = LightweightCharts.createChart(this.div, { - width: window.innerWidth * innerWidth, - height: window.innerHeight * innerHeight, - layout: { - textColor: pane.color, - background: { - color: '#000000', - type: LightweightCharts.ColorType.Solid, - }, - fontSize: 12 - }, - rightPriceScale: { - scaleMargins: {top: 0.3, bottom: 0.25}, - }, - timeScale: {timeVisible: true, secondsVisible: false}, - crosshair: { - mode: LightweightCharts.CrosshairMode.Normal, - vertLine: { - labelBackgroundColor: 'rgb(46, 46, 46)' - }, - horzLine: { - labelBackgroundColor: 'rgb(55, 55, 55)' - } - }, - grid: { - vertLines: {color: 'rgba(29, 30, 38, 5)'}, - horzLines: {color: 'rgba(29, 30, 58, 5)'}, - }, - handleScroll: {vertTouchDrag: true}, - }) - this.legend = new Legend(this) - this.wrapper.style.display = 'flex' - this.wrapper.style.flexDirection = 'column' - this.wrapper.style.position = 'relative' - this.wrapper.style.float = position - this.div.style.position = 'relative' - // this.div.style.display = 'flex' - this.reSize() - this.wrapper.appendChild(this.div) - document.getElementById('wrapper').append(this.wrapper) - - document.addEventListener('keydown', (event) => { - for (let i = 0; i < this.commandFunctions.length; i++) { - if (this.commandFunctions[i](event)) break - } - }) - - window.selectedChart = this - this.wrapper.addEventListener('mouseover', (e) => window.selectedChart = this) - - if (!autoSize) return - window.addEventListener('resize', () => this.reSize()) - } - reSize() { - let topBarOffset = 'topBar' in this && this.scale.height !== 0 ? this.topBar.offsetHeight : 0 - this.chart.resize(window.innerWidth * this.scale.width, (window.innerHeight * this.scale.height) - topBarOffset) - this.wrapper.style.width = `${100 * this.scale.width}%` - this.wrapper.style.height = `${100 * this.scale.height}%` - - if (this.scale.height === 0 || this.scale.width === 0) { - this.legend.div.style.display = 'none' - if (this.toolBox) { - this.toolBox.elem.style.display = 'none' - } - } - else { - this.legend.div.style.display = 'flex' - if (this.toolBox) { - this.toolBox.elem.style.display = 'flex' - } - } - - - } - makeCandlestickSeries() { - this.markers = [] - this.horizontal_lines = [] - this.data = [] - this.precision = 2 - let up = 'rgba(39, 157, 130, 100)' - let down = 'rgba(200, 97, 100, 100)' - this.series = this.chart.addCandlestickSeries({ - color: 'rgb(0, 120, 255)', upColor: up, borderUpColor: up, wickUpColor: up, - downColor: down, borderDownColor: down, wickDownColor: down, lineWidth: 2, - }) - this.volumeSeries = this.chart.addHistogramSeries({ - color: '#26a69a', - priceFormat: {type: 'volume'}, - priceScaleId: 'volume_scale', - }) - this.series.priceScale().applyOptions({ - scaleMargins: {top: 0.2, bottom: 0.2}, - }); - this.volumeSeries.priceScale().applyOptions({ - scaleMargins: {top: 0.8, bottom: 0}, - }); - } - toJSON() { - // Exclude the chart attribute from serialization - const {chart, ...serialized} = this; - return serialized; - } - } - window.Chart = Chart - - class HorizontalLine { - constructor(chart, lineId, price, color, width, style, axisLabelVisible, text) { - this.updatePrice = this.updatePrice.bind(this) - this.deleteLine = this.deleteLine.bind(this) - this.chart = chart - this.price = price - this.color = color - this.id = lineId - this.priceLine = { - price: this.price, - color: this.color, - lineWidth: width, - lineStyle: style, - axisLabelVisible: axisLabelVisible, - title: text, - } - this.line = this.chart.series.createPriceLine(this.priceLine) - this.chart.horizontal_lines.push(this) - } - - toJSON() { - // Exclude the chart attribute from serialization - const {chart, line, ...serialized} = this; - return serialized; - } - - updatePrice(price) { - this.chart.series.removePriceLine(this.line) - this.price = price - this.priceLine.price = this.price - this.line = this.chart.series.createPriceLine(this.priceLine) - } - - updateLabel(text) { - this.chart.series.removePriceLine(this.line) - this.priceLine.title = text - this.line = this.chart.series.createPriceLine(this.priceLine) - } - - updateColor(color) { - this.chart.series.removePriceLine(this.line) - this.color = color - this.priceLine.color = this.color - this.line = this.chart.series.createPriceLine(this.priceLine) - } - - updateStyle(style) { - this.chart.series.removePriceLine(this.line) - this.priceLine.lineStyle = style - this.line = this.chart.series.createPriceLine(this.priceLine) - } - - deleteLine() { - this.chart.series.removePriceLine(this.line) - this.chart.horizontal_lines.splice(this.chart.horizontal_lines.indexOf(this)) - delete this - } - } - - window.HorizontalLine = HorizontalLine - - class Legend { - constructor(chart) { - this.legendHandler = this.legendHandler.bind(this) - - this.chart = chart - this.ohlcEnabled = false - this.percentEnabled = false - this.linesEnabled = false - this.colorBasedOnCandle = false - - this.div = document.createElement('div') - this.div.style.position = 'absolute' - this.div.style.zIndex = '3000' - this.div.style.pointerEvents = 'none' - this.div.style.top = '10px' - this.div.style.left = '10px' - this.div.style.display = 'flex' - this.div.style.flexDirection = 'column' - this.div.style.maxWidth = `${(chart.scale.width * 100) - 8}vw` - - this.text = document.createElement('span') - this.text.style.lineHeight = '1.8' - this.candle = document.createElement('div') - - this.div.appendChild(this.text) - this.div.appendChild(this.candle) - chart.div.appendChild(this.div) - - this.makeLines(chart) - - chart.chart.subscribeCrosshairMove(this.legendHandler) - } - - toJSON() { - // Exclude the chart attribute from serialization - const {lines, chart, ...serialized} = this; - return serialized; - } - - makeLines(chart) { - this.lines = [] - if (this.linesEnabled) chart.lines.forEach(line => this.lines.push(this.makeLineRow(line))) - } - - makeLineRow(line) { - let openEye = ` - - \` - ` - let closedEye = ` - - ` - - let row = document.createElement('div') - row.style.display = 'flex' - row.style.alignItems = 'center' - let div = document.createElement('div') - let toggle = document.createElement('div') - toggle.style.borderRadius = '4px' - toggle.style.marginLeft = '10px' - toggle.style.pointerEvents = 'auto' - - - let svg = document.createElementNS("http://www.w3.org/2000/svg", "svg"); - svg.setAttribute("width", "22"); - svg.setAttribute("height", "16"); - - let group = document.createElementNS("http://www.w3.org/2000/svg", "g"); - group.innerHTML = openEye - - let on = true - toggle.addEventListener('click', (event) => { - if (on) { - on = false - group.innerHTML = closedEye - line.series.applyOptions({ - visible: false - }) - } else { - on = true - line.series.applyOptions({ - visible: true - }) - group.innerHTML = openEye - } - }) - toggle.addEventListener('mouseover', (event) => { - document.body.style.cursor = 'pointer' - toggle.style.backgroundColor = 'rgba(50, 50, 50, 0.5)' - }) - toggle.addEventListener('mouseleave', (event) => { - document.body.style.cursor = 'default' - toggle.style.backgroundColor = 'transparent' - }) - svg.appendChild(group) - toggle.appendChild(svg); - row.appendChild(div) - row.appendChild(toggle) - this.div.appendChild(row) - return { - div: div, - row: row, - toggle: toggle, - line: line, - solid: line.color.startsWith('rgba') ? line.color.replace(/[^,]+(?=\))/, '1') : line.color - } - } - - legendItemFormat(num, decimal) { return num.toFixed(decimal).toString().padStart(8, ' ') } - - shorthandFormat(num) { - const absNum = Math.abs(num) - if (absNum >= 1000000) { - return (num / 1000000).toFixed(1) + 'M'; - } else if (absNum >= 1000) { - return (num / 1000).toFixed(1) + 'K'; - } - return num.toString().padStart(8, ' '); - } - - legendHandler(param, usingPoint= false) { - let options = this.chart.series.options() - - if (!param.time) { - this.candle.style.color = 'transparent' - this.candle.innerHTML = this.candle.innerHTML.replace(options['upColor'], '').replace(options['downColor'], '') - return - } - - let data, logical - - if (usingPoint) { - let coordinate = this.chart.chart.timeScale().timeToCoordinate(param.time) - logical = this.chart.chart.timeScale().coordinateToLogical(coordinate) - data = this.chart.series.dataByIndex(logical) - } - else { - data = param.seriesData.get(this.chart.series); - } - - this.candle.style.color = '' - let str = '' - if (data) { - if (this.ohlcEnabled) { - str += `O ${this.legendItemFormat(data.open, this.chart.precision)} ` - str += `| H ${this.legendItemFormat(data.high, this.chart.precision)} ` - str += `| L ${this.legendItemFormat(data.low, this.chart.precision)} ` - str += `| C ${this.legendItemFormat(data.close, this.chart.precision)} ` - } - - if (this.percentEnabled) { - let percentMove = ((data.close - data.open) / data.open) * 100 - let color = percentMove > 0 ? options['upColor'] : options['downColor'] - let percentStr = `${percentMove >= 0 ? '+' : ''}${percentMove.toFixed(2)} %` - - if (this.colorBasedOnCandle) { - str += `| ${percentStr}` - } else { - str += '| ' + percentStr - } - } - - let volumeData; - if (usingPoint) { - volumeData = this.chart.volumeSeries.dataByIndex(logical) - } - else { - volumeData = param.seriesData.get(this.chart.volumeSeries) - } - if (volumeData) { - str += this.ohlcEnabled ? `
V ${this.shorthandFormat(volumeData.value)}` : '' - } - } - this.candle.innerHTML = str + '
' - - this.lines.forEach((line) => { - if (!this.linesEnabled) { - line.row.style.display = 'none' - return - } - line.row.style.display = 'flex' - - let price - if (usingPoint) { - price = line.line.series.dataByIndex(logical) - } - else { - price = param.seriesData.get(line.line.series) - } - if (!price) return - else price = price.value - - if (line.line.type === 'histogram') { - price = this.shorthandFormat(price) - } else { - price = this.legendItemFormat(price, line.line.precision) - } - line.div.innerHTML = `▨ ${line.line.name} : ${price}` - }) - } - } - - window.Legend = Legend -} - -function syncCharts(childChart, parentChart, crosshairOnly= false) { - - function crosshairHandler(chart, point) { - if (!point) { - chart.chart.clearCrosshairPosition() - return - } - chart.chart.setCrosshairPosition(point.value || point.close, point.time, chart.series); - chart.legend.legendHandler(point, true) - } - - function getPoint(series, param) { - if (!param.time) return null; - return param.seriesData.get(series) || null; - } - - let setChildRange, setParentRange; - if (crosshairOnly) { - setChildRange = (timeRange) => { } - setParentRange = (timeRange) => { } - } - else { - setChildRange = (timeRange) => childChart.chart.timeScale().setVisibleLogicalRange(timeRange) - setParentRange = (timeRange) => parentChart.chart.timeScale().setVisibleLogicalRange(timeRange) - } - - let setParentCrosshair = (param) => { - crosshairHandler(parentChart, getPoint(childChart.series, param)) - } - let setChildCrosshair = (param) => { - crosshairHandler(childChart, getPoint(parentChart.series, param)) - } - - let selected = parentChart - function addMouseOverListener(thisChart, otherChart, thisCrosshair, otherCrosshair, thisRange, otherRange) { - thisChart.wrapper.addEventListener('mouseover', (event) => { - if (selected === thisChart) return - selected = thisChart - otherChart.chart.timeScale().unsubscribeVisibleLogicalRangeChange(thisRange) - otherChart.chart.unsubscribeCrosshairMove(thisCrosshair) - thisChart.chart.timeScale().subscribeVisibleLogicalRangeChange(otherRange) - thisChart.chart.subscribeCrosshairMove(otherCrosshair) - }) - } - addMouseOverListener(parentChart, childChart, setParentCrosshair, setChildCrosshair, setParentRange, setChildRange) - addMouseOverListener(childChart, parentChart, setChildCrosshair, setParentCrosshair, setChildRange, setParentRange) - - parentChart.chart.timeScale().subscribeVisibleLogicalRangeChange(setChildRange) - parentChart.chart.subscribeCrosshairMove(setChildCrosshair) -} - -function stampToDate(stampOrBusiness) { - return new Date(stampOrBusiness*1000) -} -function dateToStamp(date) { - return Math.floor(date.getTime()/1000) -} - -function lastBar(obj) { - return obj[obj.length-1] -} - -function calculateTrendLine(startDate, startValue, endDate, endValue, chart, ray=false) { - let reversed = false - if (stampToDate(endDate).getTime() < stampToDate(startDate).getTime()) { - reversed = true; - [startDate, endDate] = [endDate, startDate]; - } - let startIndex - if (stampToDate(startDate).getTime() < stampToDate(chart.data[0].time).getTime()) { - startIndex = 0 - } - else { - startIndex = chart.data.findIndex(item => stampToDate(item.time).getTime() === stampToDate(startDate).getTime()) - } - - if (startIndex === -1) { - throw new Error(`Could not calculate start index from time ${stampToDate(startDate)}.`) - } - let endIndex - if (ray) { - endIndex = chart.data.length+1000 - startValue = endValue - } - else { - endIndex = chart.data.findIndex(item => stampToDate(item.time).getTime() === stampToDate(endDate).getTime()) - if (endIndex === -1) { - let barsBetween = (endDate-lastBar(chart.data).time)/chart.interval - endIndex = chart.data.length-1+barsBetween - } - } - - let numBars = endIndex-startIndex - const rate_of_change = (endValue - startValue) / numBars; - const trendData = []; - let currentDate = null - let iPastData = 0 - for (let i = 0; i <= numBars; i++) { - if (chart.data[startIndex+i]) { - currentDate = chart.data[startIndex+i].time - } - else { - iPastData ++ - currentDate = lastBar(chart.data).time+(iPastData*chart.interval) - } - - const currentValue = reversed ? startValue + rate_of_change * (numBars - i) : startValue + rate_of_change * i; - trendData.push({ time: currentDate, value: currentValue }); - } - return trendData; -} - - -if (!window.ContextMenu) { - class ContextMenu { - constructor() { - this.menu = document.createElement('div') - this.menu.style.position = 'absolute' - this.menu.style.zIndex = '10000' - this.menu.style.background = 'rgb(50, 50, 50)' - this.menu.style.color = pane.activeColor - this.menu.style.display = 'none' - this.menu.style.borderRadius = '5px' - this.menu.style.padding = '3px 3px' - this.menu.style.fontSize = '13px' - this.menu.style.cursor = 'default' - document.body.appendChild(this.menu) - this.hoverItem = null - - let closeMenu = (event) => { - if (!this.menu.contains(event.target)) { - this.menu.style.display = 'none'; - this.listen(false) - } - } - - this.onRightClick = (event) => { - event.preventDefault(); - this.menu.style.left = event.clientX + 'px'; - this.menu.style.top = event.clientY + 'px'; - this.menu.style.display = 'block'; - document.removeEventListener('click', closeMenu) - document.addEventListener('click', closeMenu) - } - } - listen(active) { - active ? document.addEventListener('contextmenu', this.onRightClick) : document.removeEventListener('contextmenu', this.onRightClick) - } - menuItem(text, action, hover=false) { - let item = document.createElement('span') - item.style.display = 'flex' - item.style.alignItems = 'center' - item.style.justifyContent = 'space-between' - item.style.padding = '2px 10px' - item.style.margin = '1px 0px' - item.style.borderRadius = '3px' - this.menu.appendChild(item) - - let elem = document.createElement('span') - elem.innerText = text - elem.style.pointerEvents = 'none' - item.appendChild(elem) - - if (hover) { - let arrow = document.createElement('span') - arrow.innerText = `►` - arrow.style.fontSize = '8px' - arrow.style.pointerEvents = 'none' - item.appendChild(arrow) - } - - item.addEventListener('mouseover', (event) => { - item.style.backgroundColor = 'rgba(0, 122, 255, 0.3)' - if (this.hoverItem && this.hoverItem.closeAction) this.hoverItem.closeAction() - this.hoverItem = {elem: elem, action: action, closeAction: hover} - }) - item.addEventListener('mouseout', (event) => item.style.backgroundColor = 'transparent') - if (!hover) item.addEventListener('click', (event) => {action(event); this.menu.style.display = 'none'}) - else { - let timeout - item.addEventListener('mouseover', () => timeout = setTimeout(() => action(item.getBoundingClientRect()), 100)) - item.addEventListener('mouseout', () => clearTimeout(timeout)) - } - } - separator() { - let separator = document.createElement('div') - separator.style.width = '90%' - separator.style.height = '1px' - separator.style.margin = '3px 0px' - separator.style.backgroundColor = pane.borderColor - this.menu.appendChild(separator) - } - - } - window.ContextMenu = ContextMenu -} - -window.callbackFunction = () => undefined; \ No newline at end of file diff --git a/lightweight_charts/js/lightweight-charts.js b/lightweight_charts/js/lightweight-charts.js new file mode 100644 index 0000000..69033f3 --- /dev/null +++ b/lightweight_charts/js/lightweight-charts.js @@ -0,0 +1,7 @@ +/*! + * @license + * TradingView Lightweight Charts™ v4.1.3 + * Copyright (c) 2024 TradingView, Inc. + * Licensed under Apache License 2.0 https://www.apache.org/licenses/LICENSE-2.0 + */ +!function(){"use strict";const t={upColor:"#26a69a",downColor:"#ef5350",wickVisible:!0,borderVisible:!0,borderColor:"#378658",borderUpColor:"#26a69a",borderDownColor:"#ef5350",wickColor:"#737375",wickUpColor:"#26a69a",wickDownColor:"#ef5350"},i={upColor:"#26a69a",downColor:"#ef5350",openVisible:!0,thinBars:!0},n={color:"#2196f3",lineStyle:0,lineWidth:3,lineType:0,lineVisible:!0,crosshairMarkerVisible:!0,crosshairMarkerRadius:4,crosshairMarkerBorderColor:"",crosshairMarkerBorderWidth:2,crosshairMarkerBackgroundColor:"",lastPriceAnimation:0,pointMarkersVisible:!1},s={topColor:"rgba( 46, 220, 135, 0.4)",bottomColor:"rgba( 40, 221, 100, 0)",invertFilledArea:!1,lineColor:"#33D778",lineStyle:0,lineWidth:3,lineType:0,lineVisible:!0,crosshairMarkerVisible:!0,crosshairMarkerRadius:4,crosshairMarkerBorderColor:"",crosshairMarkerBorderWidth:2,crosshairMarkerBackgroundColor:"",lastPriceAnimation:0,pointMarkersVisible:!1},e={baseValue:{type:"price",price:0},topFillColor1:"rgba(38, 166, 154, 0.28)",topFillColor2:"rgba(38, 166, 154, 0.05)",topLineColor:"rgba(38, 166, 154, 1)",bottomFillColor1:"rgba(239, 83, 80, 0.05)",bottomFillColor2:"rgba(239, 83, 80, 0.28)",bottomLineColor:"rgba(239, 83, 80, 1)",lineWidth:3,lineStyle:0,lineType:0,lineVisible:!0,crosshairMarkerVisible:!0,crosshairMarkerRadius:4,crosshairMarkerBorderColor:"",crosshairMarkerBorderWidth:2,crosshairMarkerBackgroundColor:"",lastPriceAnimation:0,pointMarkersVisible:!1},r={color:"#26a69a",base:0},h={color:"#2196f3"},l={title:"",visible:!0,lastValueVisible:!0,priceLineVisible:!0,priceLineSource:0,priceLineWidth:1,priceLineColor:"",priceLineStyle:2,baseLineVisible:!0,baseLineWidth:1,baseLineColor:"#B2B5BE",baseLineStyle:0,priceFormat:{type:"price",precision:2,minMove:.01}};var a,o;function _(t,i){const n={0:[],1:[t.lineWidth,t.lineWidth],2:[2*t.lineWidth,2*t.lineWidth],3:[6*t.lineWidth,6*t.lineWidth],4:[t.lineWidth,4*t.lineWidth]}[i];t.setLineDash(n)}function u(t,i,n,s){t.beginPath();const e=t.lineWidth%2?.5:0;t.moveTo(n,i+e),t.lineTo(s,i+e),t.stroke()}function c(t,i){if(!t)throw new Error("Assertion failed"+(i?": "+i:""))}function d(t){if(void 0===t)throw new Error("Value is undefined");return t}function f(t){if(null===t)throw new Error("Value is null");return t}function v(t){return f(d(t))}!function(t){t[t.Simple=0]="Simple",t[t.WithSteps=1]="WithSteps",t[t.Curved=2]="Curved"}(a||(a={})),function(t){t[t.Solid=0]="Solid",t[t.Dotted=1]="Dotted",t[t.Dashed=2]="Dashed",t[t.LargeDashed=3]="LargeDashed",t[t.SparseDotted=4]="SparseDotted"}(o||(o={}));const p={khaki:"#f0e68c",azure:"#f0ffff",aliceblue:"#f0f8ff",ghostwhite:"#f8f8ff",gold:"#ffd700",goldenrod:"#daa520",gainsboro:"#dcdcdc",gray:"#808080",green:"#008000",honeydew:"#f0fff0",floralwhite:"#fffaf0",lightblue:"#add8e6",lightcoral:"#f08080",lemonchiffon:"#fffacd",hotpink:"#ff69b4",lightyellow:"#ffffe0",greenyellow:"#adff2f",lightgoldenrodyellow:"#fafad2",limegreen:"#32cd32",linen:"#faf0e6",lightcyan:"#e0ffff",magenta:"#f0f",maroon:"#800000",olive:"#808000",orange:"#ffa500",oldlace:"#fdf5e6",mediumblue:"#0000cd",transparent:"#0000",lime:"#0f0",lightpink:"#ffb6c1",mistyrose:"#ffe4e1",moccasin:"#ffe4b5",midnightblue:"#191970",orchid:"#da70d6",mediumorchid:"#ba55d3",mediumturquoise:"#48d1cc",orangered:"#ff4500",royalblue:"#4169e1",powderblue:"#b0e0e6",red:"#f00",coral:"#ff7f50",turquoise:"#40e0d0",white:"#fff",whitesmoke:"#f5f5f5",wheat:"#f5deb3",teal:"#008080",steelblue:"#4682b4",bisque:"#ffe4c4",aquamarine:"#7fffd4",aqua:"#0ff",sienna:"#a0522d",silver:"#c0c0c0",springgreen:"#00ff7f",antiquewhite:"#faebd7",burlywood:"#deb887",brown:"#a52a2a",beige:"#f5f5dc",chocolate:"#d2691e",chartreuse:"#7fff00",cornflowerblue:"#6495ed",cornsilk:"#fff8dc",crimson:"#dc143c",cadetblue:"#5f9ea0",tomato:"#ff6347",fuchsia:"#f0f",blue:"#00f",salmon:"#fa8072",blanchedalmond:"#ffebcd",slateblue:"#6a5acd",slategray:"#708090",thistle:"#d8bfd8",tan:"#d2b48c",cyan:"#0ff",darkblue:"#00008b",darkcyan:"#008b8b",darkgoldenrod:"#b8860b",darkgray:"#a9a9a9",blueviolet:"#8a2be2",black:"#000",darkmagenta:"#8b008b",darkslateblue:"#483d8b",darkkhaki:"#bdb76b",darkorchid:"#9932cc",darkorange:"#ff8c00",darkgreen:"#006400",darkred:"#8b0000",dodgerblue:"#1e90ff",darkslategray:"#2f4f4f",dimgray:"#696969",deepskyblue:"#00bfff",firebrick:"#b22222",forestgreen:"#228b22",indigo:"#4b0082",ivory:"#fffff0",lavenderblush:"#fff0f5",feldspar:"#d19275",indianred:"#cd5c5c",lightgreen:"#90ee90",lightgrey:"#d3d3d3",lightskyblue:"#87cefa",lightslategray:"#789",lightslateblue:"#8470ff",snow:"#fffafa",lightseagreen:"#20b2aa",lightsalmon:"#ffa07a",darksalmon:"#e9967a",darkviolet:"#9400d3",mediumpurple:"#9370d8",mediumaquamarine:"#66cdaa",skyblue:"#87ceeb",lavender:"#e6e6fa",lightsteelblue:"#b0c4de",mediumvioletred:"#c71585",mintcream:"#f5fffa",navajowhite:"#ffdead",navy:"#000080",olivedrab:"#6b8e23",palevioletred:"#d87093",violetred:"#d02090",yellow:"#ff0",yellowgreen:"#9acd32",lawngreen:"#7cfc00",pink:"#ffc0cb",paleturquoise:"#afeeee",palegoldenrod:"#eee8aa",darkolivegreen:"#556b2f",darkseagreen:"#8fbc8f",darkturquoise:"#00ced1",peachpuff:"#ffdab9",deeppink:"#ff1493",violet:"#ee82ee",palegreen:"#98fb98",mediumseagreen:"#3cb371",peru:"#cd853f",saddlebrown:"#8b4513",sandybrown:"#f4a460",rosybrown:"#bc8f8f",purple:"#800080",seagreen:"#2e8b57",seashell:"#fff5ee",papayawhip:"#ffefd5",mediumslateblue:"#7b68ee",plum:"#dda0dd",mediumspringgreen:"#00fa9a"};function m(t){return t<0?0:t>255?255:Math.round(t)||0}function b(t){return t<=0||t>0?t<0?0:t>1?1:Math.round(1e4*t)/1e4:0}const w=/^#([0-9a-f])([0-9a-f])([0-9a-f])([0-9a-f])?$/i,g=/^#([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})?$/i,M=/^rgb\(\s*(-?\d{1,10})\s*,\s*(-?\d{1,10})\s*,\s*(-?\d{1,10})\s*\)$/,x=/^rgba\(\s*(-?\d{1,10})\s*,\s*(-?\d{1,10})\s*,\s*(-?\d{1,10})\s*,\s*(-?[\d]{0,10}(?:\.\d+)?)\s*\)$/;function S(t){(t=t.toLowerCase())in p&&(t=p[t]);{const i=x.exec(t)||M.exec(t);if(i)return[m(parseInt(i[1],10)),m(parseInt(i[2],10)),m(parseInt(i[3],10)),b(i.length<5?1:parseFloat(i[4]))]}{const i=g.exec(t);if(i)return[m(parseInt(i[1],16)),m(parseInt(i[2],16)),m(parseInt(i[3],16)),1]}{const i=w.exec(t);if(i)return[m(17*parseInt(i[1],16)),m(17*parseInt(i[2],16)),m(17*parseInt(i[3],16)),1]}throw new Error(`Cannot parse color: ${t}`)}function y(t){const i=S(t);return{t:`rgb(${i[0]}, ${i[1]}, ${i[2]})`,i:(n=i,.199*n[0]+.687*n[1]+.114*n[2]>160?"black":"white")};var n}class k{constructor(){this.h=[]}l(t,i,n){const s={o:t,_:i,u:!0===n};this.h.push(s)}v(t){const i=this.h.findIndex((i=>t===i.o));i>-1&&this.h.splice(i,1)}p(t){this.h=this.h.filter((i=>i._!==t))}m(t,i,n){const s=[...this.h];this.h=this.h.filter((t=>!t.u)),s.forEach((s=>s.o(t,i,n)))}M(){return this.h.length>0}S(){this.h=[]}}function C(t,...i){for(const n of i)for(const i in n)void 0!==n[i]&&("object"!=typeof n[i]||void 0===t[i]||Array.isArray(n[i])?t[i]=n[i]:C(t[i],n[i]));return t}function T(t){return"number"==typeof t&&isFinite(t)}function P(t){return"number"==typeof t&&t%1==0}function R(t){return"string"==typeof t}function D(t){return"boolean"==typeof t}function O(t){const i=t;if(!i||"object"!=typeof i)return i;let n,s,e;for(s in n=Array.isArray(i)?[]:{},i)i.hasOwnProperty(s)&&(e=i[s],n[s]=e&&"object"==typeof e?O(e):e);return n}function A(t){return null!==t}function B(t){return null===t?void 0:t}const V="-apple-system, BlinkMacSystemFont, 'Trebuchet MS', Roboto, Ubuntu, sans-serif";function z(t,i,n){return void 0===i&&(i=V),`${n=void 0!==n?`${n} `:""}${t}px ${i}`}class E{constructor(t){this.k={C:1,T:5,P:NaN,R:"",D:"",O:"",A:"",B:0,V:0,I:0,L:0,N:0},this.F=t}W(){const t=this.k,i=this.j(),n=this.H();return t.P===i&&t.D===n||(t.P=i,t.D=n,t.R=z(i,n),t.L=2.5/12*i,t.B=t.L,t.V=i/12*t.T,t.I=i/12*t.T,t.N=0),t.O=this.$(),t.A=this.U(),this.k}$(){return this.F.W().layout.textColor}U(){return this.F.q()}j(){return this.F.W().layout.fontSize}H(){return this.F.W().layout.fontFamily}}class I{constructor(){this.Y=[]}X(t){this.Y=t}K(t,i,n){this.Y.forEach((s=>{s.K(t,i,n)}))}}class L{K(t,i,n){t.useBitmapCoordinateSpace((t=>this.Z(t,i,n)))}}class N extends L{constructor(){super(...arguments),this.G=null}J(t){this.G=t}Z({context:t,horizontalPixelRatio:i,verticalPixelRatio:n}){if(null===this.G||null===this.G.tt)return;const s=this.G.tt,e=this.G,r=Math.max(1,Math.floor(i))%2/2,h=h=>{t.beginPath();for(let l=s.to-1;l>=s.from;--l){const s=e.it[l],a=Math.round(s.nt*i)+r,o=s.st*n,_=h*n+r;t.moveTo(a,o),t.arc(a,o,_,0,2*Math.PI)}t.fill()};e.et>0&&(t.fillStyle=e.rt,h(e.ht+e.et)),t.fillStyle=e.lt,h(e.ht)}}function F(){return{it:[{nt:0,st:0,ot:0,_t:0}],lt:"",rt:"",ht:0,et:0,tt:null}}const W={from:0,to:1};class j{constructor(t,i){this.ut=new I,this.ct=[],this.dt=[],this.ft=!0,this.F=t,this.vt=i,this.ut.X(this.ct)}bt(t){const i=this.F.wt();i.length!==this.ct.length&&(this.dt=i.map(F),this.ct=this.dt.map((t=>{const i=new N;return i.J(t),i})),this.ut.X(this.ct)),this.ft=!0}gt(){return this.ft&&(this.Mt(),this.ft=!1),this.ut}Mt(){const t=2===this.vt.W().mode,i=this.F.wt(),n=this.vt.xt(),s=this.F.St();i.forEach(((i,e)=>{var r;const h=this.dt[e],l=i.yt(n);if(t||null===l||!i.kt())return void(h.tt=null);const a=f(i.Ct());h.lt=l.Tt,h.ht=l.ht,h.et=l.Pt,h.it[0]._t=l._t,h.it[0].st=i.Dt().Rt(l._t,a.Ot),h.rt=null!==(r=l.At)&&void 0!==r?r:this.F.Bt(h.it[0].st/i.Dt().Vt()),h.it[0].ot=n,h.it[0].nt=s.zt(n),h.tt=W}))}}class H extends L{constructor(t){super(),this.Et=t}Z({context:t,bitmapSize:i,horizontalPixelRatio:n,verticalPixelRatio:s}){if(null===this.Et)return;const e=this.Et.It.kt,r=this.Et.Lt.kt;if(!e&&!r)return;const h=Math.round(this.Et.nt*n),l=Math.round(this.Et.st*s);t.lineCap="butt",e&&h>=0&&(t.lineWidth=Math.floor(this.Et.It.et*n),t.strokeStyle=this.Et.It.O,t.fillStyle=this.Et.It.O,_(t,this.Et.It.Nt),function(t,i,n,s){t.beginPath();const e=t.lineWidth%2?.5:0;t.moveTo(i+e,n),t.lineTo(i+e,s),t.stroke()}(t,h,0,i.height)),r&&l>=0&&(t.lineWidth=Math.floor(this.Et.Lt.et*s),t.strokeStyle=this.Et.Lt.O,t.fillStyle=this.Et.Lt.O,_(t,this.Et.Lt.Nt),u(t,l,0,i.width))}}class ${constructor(t){this.ft=!0,this.Ft={It:{et:1,Nt:0,O:"",kt:!1},Lt:{et:1,Nt:0,O:"",kt:!1},nt:0,st:0},this.Wt=new H(this.Ft),this.jt=t}bt(){this.ft=!0}gt(){return this.ft&&(this.Mt(),this.ft=!1),this.Wt}Mt(){const t=this.jt.kt(),i=f(this.jt.Ht()),n=i.$t().W().crosshair,s=this.Ft;if(2===n.mode)return s.Lt.kt=!1,void(s.It.kt=!1);s.Lt.kt=t&&this.jt.Ut(i),s.It.kt=t&&this.jt.qt(),s.Lt.et=n.horzLine.width,s.Lt.Nt=n.horzLine.style,s.Lt.O=n.horzLine.color,s.It.et=n.vertLine.width,s.It.Nt=n.vertLine.style,s.It.O=n.vertLine.color,s.nt=this.jt.Yt(),s.st=this.jt.Xt()}}function U(t,i,n,s,e,r){t.fillRect(i+r,n,s-2*r,r),t.fillRect(i+r,n+e-r,s-2*r,r),t.fillRect(i,n,r,e),t.fillRect(i+s-r,n,r,e)}function q(t,i,n,s,e,r){t.save(),t.globalCompositeOperation="copy",t.fillStyle=r,t.fillRect(i,n,s,e),t.restore()}function Y(t,i){return t.map((t=>0===t?t:t+i))}function X(t,i,n,s,e,r){t.beginPath(),t.lineTo(i+s-r[1],n),0!==r[1]&&t.arcTo(i+s,n,i+s,n+r[1],r[1]),t.lineTo(i+s,n+e-r[2]),0!==r[2]&&t.arcTo(i+s,n+e,i+s-r[2],n+e,r[2]),t.lineTo(i+r[3],n+e),0!==r[3]&&t.arcTo(i,n+e,i,n+e-r[3],r[3]),t.lineTo(i,n+r[0]),0!==r[0]&&t.arcTo(i,n,i+r[0],n,r[0])}function K(t,i,n,s,e,r,h=0,l=[0,0,0,0],a=""){if(t.save(),!h||!a||a===r)return X(t,i,n,s,e,l),t.fillStyle=r,t.fill(),void t.restore();const o=h/2;if("transparent"!==r){X(t,i+h,n+h,s-2*h,e-2*h,Y(l,-h)),t.fillStyle=r,t.fill()}if("transparent"!==a){X(t,i+o,n+o,s-h,e-h,Y(l,-o)),t.lineWidth=h,t.strokeStyle=a,t.closePath(),t.stroke()}t.restore()}function Z(t,i,n,s,e,r,h){t.save(),t.globalCompositeOperation="copy";const l=t.createLinearGradient(0,0,0,e);l.addColorStop(0,r),l.addColorStop(1,h),t.fillStyle=l,t.fillRect(i,n,s,e),t.restore()}class G{constructor(t,i){this.J(t,i)}J(t,i){this.Et=t,this.Kt=i}Vt(t,i){return this.Et.kt?t.P+t.L+t.B:0}K(t,i,n,s){if(!this.Et.kt||0===this.Et.Zt.length)return;const e=this.Et.O,r=this.Kt.t,h=t.useBitmapCoordinateSpace((t=>{const h=t.context;h.font=i.R;const l=this.Gt(t,i,n,s),a=l.Jt,o=(t,i)=>{l.Qt?K(h,a.ti,a.ii,a.ni,a.si,t,a.ei,[a.ht,0,0,a.ht],i):K(h,a.ri,a.ii,a.ni,a.si,t,a.ei,[0,a.ht,a.ht,0],i)};return o(r,"transparent"),this.Et.hi&&(h.fillStyle=e,h.fillRect(a.ri,a.li,a.ai-a.ri,a.oi)),o("transparent",r),this.Et._i&&(h.fillStyle=i.A,h.fillRect(l.Qt?a.ui-a.ei:0,a.ii,a.ei,a.ci-a.ii)),l}));t.useMediaCoordinateSpace((({context:t})=>{const n=h.di;t.font=i.R,t.textAlign=h.Qt?"right":"left",t.textBaseline="middle",t.fillStyle=e,t.fillText(this.Et.Zt,n.fi,(n.ii+n.ci)/2+n.vi)}))}Gt(t,i,n,s){var e;const{context:r,bitmapSize:h,mediaSize:l,horizontalPixelRatio:a,verticalPixelRatio:o}=t,_=this.Et.hi||!this.Et.pi?i.T:0,u=this.Et.mi?i.C:0,c=i.L+this.Kt.bi,d=i.B+this.Kt.wi,f=i.V,v=i.I,p=this.Et.Zt,m=i.P,b=n.gi(r,p),w=Math.ceil(n.Mi(r,p)),g=m+c+d,M=i.C+f+v+w+_,x=Math.max(1,Math.floor(o));let S=Math.round(g*o);S%2!=x%2&&(S+=1);const y=u>0?Math.max(1,Math.floor(u*a)):0,k=Math.round(M*a),C=Math.round(_*a),T=null!==(e=this.Kt.xi)&&void 0!==e?e:this.Kt.Si,P=Math.round(T*o)-Math.floor(.5*o),R=Math.floor(P+x/2-S/2),D=R+S,O="right"===s,A=O?l.width-u:u,B=O?h.width-y:y;let V,z,E;return O?(V=B-k,z=B-C,E=A-_-f-u):(V=B+k,z=B+C,E=A+_+f),{Qt:O,Jt:{ii:R,li:P,ci:D,ni:k,si:S,ht:2*a,ei:y,ti:V,ri:B,ai:z,oi:x,ui:h.width},di:{ii:R/o,ci:D/o,fi:E,vi:b}}}}class J{constructor(t){this.yi={Si:0,t:"#000",wi:0,bi:0},this.ki={Zt:"",kt:!1,hi:!0,pi:!1,At:"",O:"#FFF",_i:!1,mi:!1},this.Ci={Zt:"",kt:!1,hi:!1,pi:!0,At:"",O:"#FFF",_i:!0,mi:!0},this.ft=!0,this.Ti=new(t||G)(this.ki,this.yi),this.Pi=new(t||G)(this.Ci,this.yi)}Zt(){return this.Ri(),this.ki.Zt}Si(){return this.Ri(),this.yi.Si}bt(){this.ft=!0}Vt(t,i=!1){return Math.max(this.Ti.Vt(t,i),this.Pi.Vt(t,i))}Di(){return this.yi.xi||0}Oi(t){this.yi.xi=t}Ai(){return this.Ri(),this.ki.kt||this.Ci.kt}Bi(){return this.Ri(),this.ki.kt}gt(t){return this.Ri(),this.ki.hi=this.ki.hi&&t.W().ticksVisible,this.Ci.hi=this.Ci.hi&&t.W().ticksVisible,this.Ti.J(this.ki,this.yi),this.Pi.J(this.Ci,this.yi),this.Ti}Vi(){return this.Ri(),this.Ti.J(this.ki,this.yi),this.Pi.J(this.Ci,this.yi),this.Pi}Ri(){this.ft&&(this.ki.hi=!0,this.Ci.hi=!1,this.zi(this.ki,this.Ci,this.yi))}}class Q extends J{constructor(t,i,n){super(),this.jt=t,this.Ei=i,this.Ii=n}zi(t,i,n){if(t.kt=!1,2===this.jt.W().mode)return;const s=this.jt.W().horzLine;if(!s.labelVisible)return;const e=this.Ei.Ct();if(!this.jt.kt()||this.Ei.Li()||null===e)return;const r=y(s.labelBackgroundColor);n.t=r.t,t.O=r.i;const h=2/12*this.Ei.P();n.bi=h,n.wi=h;const l=this.Ii(this.Ei);n.Si=l.Si,t.Zt=this.Ei.Ni(l._t,e),t.kt=!0}}const tt=/[1-9]/g;class it{constructor(){this.Et=null}J(t){this.Et=t}K(t,i){if(null===this.Et||!1===this.Et.kt||0===this.Et.Zt.length)return;const n=t.useMediaCoordinateSpace((({context:t})=>(t.font=i.R,Math.round(i.Fi.Mi(t,f(this.Et).Zt,tt)))));if(n<=0)return;const s=i.Wi,e=n+2*s,r=e/2,h=this.Et.ji;let l=this.Et.Si,a=Math.floor(l-r)+.5;a<0?(l+=Math.abs(0-a),a=Math.floor(l-r)+.5):a+e>h&&(l-=Math.abs(h-(a+e)),a=Math.floor(l-r)+.5);const o=a+e,_=Math.ceil(0+i.C+i.T+i.L+i.P+i.B);t.useBitmapCoordinateSpace((({context:t,horizontalPixelRatio:n,verticalPixelRatio:s})=>{const e=f(this.Et);t.fillStyle=e.t;const r=Math.round(a*n),h=Math.round(0*s),l=Math.round(o*n),u=Math.round(_*s),c=Math.round(2*n);if(t.beginPath(),t.moveTo(r,h),t.lineTo(r,u-c),t.arcTo(r,u,r+c,u,c),t.lineTo(l-c,u),t.arcTo(l,u,l,u-c,c),t.lineTo(l,h),t.fill(),e.hi){const r=Math.round(e.Si*n),l=h,a=Math.round((l+i.T)*s);t.fillStyle=e.O;const o=Math.max(1,Math.floor(n)),_=Math.floor(.5*n);t.fillRect(r-_,l,o,a-l)}})),t.useMediaCoordinateSpace((({context:t})=>{const n=f(this.Et),e=0+i.C+i.T+i.L+i.P/2;t.font=i.R,t.textAlign="left",t.textBaseline="middle",t.fillStyle=n.O;const r=i.Fi.gi(t,"Apr0");t.translate(a+s,e+r),t.fillText(n.Zt,0,0)}))}}class nt{constructor(t,i,n){this.ft=!0,this.Wt=new it,this.Ft={kt:!1,t:"#4c525e",O:"white",Zt:"",ji:0,Si:NaN,hi:!0},this.vt=t,this.Hi=i,this.Ii=n}bt(){this.ft=!0}gt(){return this.ft&&(this.Mt(),this.ft=!1),this.Wt.J(this.Ft),this.Wt}Mt(){const t=this.Ft;if(t.kt=!1,2===this.vt.W().mode)return;const i=this.vt.W().vertLine;if(!i.labelVisible)return;const n=this.Hi.St();if(n.Li())return;t.ji=n.ji();const s=this.Ii();if(null===s)return;t.Si=s.Si;const e=n.$i(this.vt.xt());t.Zt=n.Ui(f(e)),t.kt=!0;const r=y(i.labelBackgroundColor);t.t=r.t,t.O=r.i,t.hi=n.W().ticksVisible}}class st{constructor(){this.qi=null,this.Yi=0}Xi(){return this.Yi}Ki(t){this.Yi=t}Dt(){return this.qi}Zi(t){this.qi=t}Gi(t){return[]}Ji(){return[]}kt(){return!0}}var et;!function(t){t[t.Normal=0]="Normal",t[t.Magnet=1]="Magnet",t[t.Hidden=2]="Hidden"}(et||(et={}));class rt extends st{constructor(t,i){super(),this.Qi=null,this.tn=NaN,this.nn=0,this.sn=!0,this.en=new Map,this.rn=!1,this.hn=NaN,this.ln=NaN,this.an=NaN,this.on=NaN,this.Hi=t,this._n=i,this.un=new j(t,this);this.cn=((t,i)=>n=>{const s=i(),e=t();if(n===f(this.Qi).dn())return{_t:e,Si:s};{const t=f(n.Ct());return{_t:n.fn(s,t),Si:s}}})((()=>this.tn),(()=>this.ln));const n=((t,i)=>()=>{const n=this.Hi.St().vn(t()),s=i();return n&&Number.isFinite(s)?{ot:n,Si:s}:null})((()=>this.nn),(()=>this.Yt()));this.pn=new nt(this,t,n),this.mn=new $(this)}W(){return this._n}bn(t,i){this.an=t,this.on=i}wn(){this.an=NaN,this.on=NaN}gn(){return this.an}Mn(){return this.on}xn(t,i,n){this.rn||(this.rn=!0),this.sn=!0,this.Sn(t,i,n)}xt(){return this.nn}Yt(){return this.hn}Xt(){return this.ln}kt(){return this.sn}yn(){this.sn=!1,this.kn(),this.tn=NaN,this.hn=NaN,this.ln=NaN,this.Qi=null,this.wn()}Cn(t){return null!==this.Qi?[this.mn,this.un]:[]}Ut(t){return t===this.Qi&&this._n.horzLine.visible}qt(){return this._n.vertLine.visible}Tn(t,i){this.sn&&this.Qi===t||this.en.clear();const n=[];return this.Qi===t&&n.push(this.Pn(this.en,i,this.cn)),n}Ji(){return this.sn?[this.pn]:[]}Ht(){return this.Qi}Rn(){this.mn.bt(),this.en.forEach((t=>t.bt())),this.pn.bt(),this.un.bt()}Dn(t){return t&&!t.dn().Li()?t.dn():null}Sn(t,i,n){this.On(t,i,n)&&this.Rn()}On(t,i,n){const s=this.hn,e=this.ln,r=this.tn,h=this.nn,l=this.Qi,a=this.Dn(n);this.nn=t,this.hn=isNaN(t)?NaN:this.Hi.St().zt(t),this.Qi=n;const o=null!==a?a.Ct():null;return null!==a&&null!==o?(this.tn=i,this.ln=a.Rt(i,o)):(this.tn=NaN,this.ln=NaN),s!==this.hn||e!==this.ln||h!==this.nn||r!==this.tn||l!==this.Qi}kn(){const t=this.Hi.wt().map((t=>t.Bn().An())).filter(A),i=0===t.length?null:Math.max(...t);this.nn=null!==i?i:NaN}Pn(t,i,n){let s=t.get(i);return void 0===s&&(s=new Q(this,i,n),t.set(i,s)),s}}function ht(t){return"left"===t||"right"===t}class lt{constructor(t){this.Vn=new Map,this.zn=[],this.En=t}In(t,i){const n=function(t,i){return void 0===t?i:{Ln:Math.max(t.Ln,i.Ln),Nn:t.Nn||i.Nn}}(this.Vn.get(t),i);this.Vn.set(t,n)}Fn(){return this.En}Wn(t){const i=this.Vn.get(t);return void 0===i?{Ln:this.En}:{Ln:Math.max(this.En,i.Ln),Nn:i.Nn}}jn(){this.Hn(),this.zn=[{$n:0}]}Un(t){this.Hn(),this.zn=[{$n:1,Ot:t}]}qn(t){this.Yn(),this.zn.push({$n:5,Ot:t})}Hn(){this.Yn(),this.zn.push({$n:6})}Xn(){this.Hn(),this.zn=[{$n:4}]}Kn(t){this.Hn(),this.zn.push({$n:2,Ot:t})}Zn(t){this.Hn(),this.zn.push({$n:3,Ot:t})}Gn(){return this.zn}Jn(t){for(const i of t.zn)this.Qn(i);this.En=Math.max(this.En,t.En),t.Vn.forEach(((t,i)=>{this.In(i,t)}))}static ts(){return new lt(2)}static ns(){return new lt(3)}Qn(t){switch(t.$n){case 0:this.jn();break;case 1:this.Un(t.Ot);break;case 2:this.Kn(t.Ot);break;case 3:this.Zn(t.Ot);break;case 4:this.Xn();break;case 5:this.qn(t.Ot);break;case 6:this.Yn()}}Yn(){const t=this.zn.findIndex((t=>5===t.$n));-1!==t&&this.zn.splice(t,1)}}const at=".";function ot(t,i){if(!T(t))return"n/a";if(!P(i))throw new TypeError("invalid length");if(i<0||i>16)throw new TypeError("invalid length");if(0===i)return t.toString();return("0000000000000000"+t.toString()).slice(-i)}class _t{constructor(t,i){if(i||(i=1),T(t)&&P(t)||(t=100),t<0)throw new TypeError("invalid base");this.Ei=t,this.ss=i,this.es()}format(t){const i=t<0?"−":"";return t=Math.abs(t),i+this.rs(t)}es(){if(this.hs=0,this.Ei>0&&this.ss>0){let t=this.Ei;for(;t>1;)t/=10,this.hs++}}rs(t){const i=this.Ei/this.ss;let n=Math.floor(t),s="";const e=void 0!==this.hs?this.hs:NaN;if(i>1){let r=+(Math.round(t*i)-n*i).toFixed(this.hs);r>=i&&(r-=i,n+=1),s=at+ot(+r.toFixed(this.hs)*this.ss,e)}else n=Math.round(n*i)/i,e>0&&(s=at+ot(0,e));return n.toFixed(0)+s}}class ut extends _t{constructor(t=100){super(t)}format(t){return`${super.format(t)}%`}}class ct{constructor(t){this.ls=t}format(t){let i="";return t<0&&(i="-",t=-t),t<995?i+this.os(t):t<999995?i+this.os(t/1e3)+"K":t<999999995?(t=1e3*Math.round(t/1e3),i+this.os(t/1e6)+"M"):(t=1e6*Math.round(t/1e6),i+this.os(t/1e9)+"B")}os(t){let i;const n=Math.pow(10,this.ls);return i=(t=Math.round(t*n)/n)>=1e-15&&t<1?t.toFixed(this.ls).replace(/\.?0+$/,""):String(t),i.replace(/(\.[1-9]*)0+$/,((t,i)=>i))}}function dt(t,i,n,s,e,r,h){if(0===i.length||s.from>=i.length||s.to<=0)return;const{context:l,horizontalPixelRatio:a,verticalPixelRatio:o}=t,_=i[s.from];let u=r(t,_),c=_;if(s.to-s.from<2){const i=e/2;l.beginPath();const n={nt:_.nt-i,st:_.st},s={nt:_.nt+i,st:_.st};l.moveTo(n.nt*a,n.st*o),l.lineTo(s.nt*a,s.st*o),h(t,u,n,s)}else{const e=(i,n)=>{h(t,u,c,n),l.beginPath(),u=i,c=n};let d=c;l.beginPath(),l.moveTo(_.nt*a,_.st*o);for(let h=s.from+1;h=s.from;--n){const s=i[n];if(s){const i=e(t,s);i!==a&&(l.beginPath(),null!==a&&l.fill(),l.fillStyle=i,a=i);const n=Math.round(s.nt*r)+o,u=s.st*h;l.moveTo(n,u),l.arc(n,u,_,0,2*Math.PI)}}l.fill()}(t,i,l,n,o)}}class Tt extends Ct{Ps(t,i){return i.lt}}function Pt(t,i,n,s,e=0,r=i.length){let h=r-e;for(;0>1,l=e+r;s(i[l],n)===t?(e=l+1,h-=r+1):h=r}return e}const Rt=Pt.bind(null,!0),Dt=Pt.bind(null,!1);function Ot(t,i){return t.ot0&&r=s&&(l=r-1),h>0&&hObject.assign(Object.assign({},t),this.zs.js().Ws(t.ot))))}Hs(){this.Vs=null}Ls(){this.Os&&(this.$s(),this.Os=!1),this.As&&(this.Fs(),this.As=!1),this.Ds&&(this.Us(),this.Ds=!1)}Us(){const t=this.zs.Dt(),i=this.Es.St();if(this.Hs(),i.Li()||t.Li())return;const n=i.qs();if(null===n)return;if(0===this.zs.Bn().Ys())return;const s=this.zs.Ct();null!==s&&(this.Vs=Bt(this.Bs,n,this.Is),this.Xs(t,i,s.Ot),this.Ks())}}class zt extends Vt{constructor(t,i){super(t,i,!0)}Xs(t,i,n){i.Zs(this.Bs,B(this.Vs)),t.Gs(this.Bs,n,B(this.Vs))}Js(t,i){return{ot:t,_t:i,nt:NaN,st:NaN}}$s(){const t=this.zs.js();this.Bs=this.zs.Bn().Qs().map((i=>{const n=i.Ot[3];return this.te(i.ie,n,t)}))}}class Et extends zt{constructor(t,i){super(t,i),this.Ns=new I,this.ne=new yt,this.se=new Tt,this.Ns.X([this.ne,this.se])}te(t,i,n){return Object.assign(Object.assign({},this.Js(t,i)),n.Ws(t))}Ks(){const t=this.zs.W();this.ne.J({us:t.lineType,it:this.Bs,Nt:t.lineStyle,et:t.lineWidth,cs:null,ds:t.invertFilledArea,tt:this.Vs,_s:this.Es.St().ee()}),this.se.J({us:t.lineVisible?t.lineType:void 0,it:this.Bs,Nt:t.lineStyle,et:t.lineWidth,tt:this.Vs,_s:this.Es.St().ee(),Ts:t.pointMarkersVisible?t.pointMarkersRadius||t.lineWidth/2+2:void 0})}}class It extends L{constructor(){super(...arguments),this.Et=null,this.re=0,this.he=0}J(t){this.Et=t}Z({context:t,horizontalPixelRatio:i,verticalPixelRatio:n}){if(null===this.Et||0===this.Et.Bn.length||null===this.Et.tt)return;if(this.re=this.le(i),this.re>=2){Math.max(1,Math.floor(i))%2!=this.re%2&&this.re--}this.he=this.Et.ae?Math.min(this.re,Math.floor(i)):this.re;let s=null;const e=this.he<=this.re&&this.Et.ee>=Math.floor(1.5*i);for(let r=this.Et.tt.from;rf+p-1&&(e=f+p-1,s=e-_+1),t.fillRect(i,s,o-i,e-s+1)}const i=a+m;let s=Math.max(f,Math.round(h.fe*n)-l),e=s+_-1;e>f+p-1&&(e=f+p-1,s=e-_+1),t.fillRect(u+1,s,i-u,e-s+1)}}}le(t){const i=Math.floor(t);return Math.max(i,Math.floor(function(t,i){return Math.floor(.3*t*i)}(f(this.Et).ee,t)))}}class Lt extends Vt{constructor(t,i){super(t,i,!1)}Xs(t,i,n){i.Zs(this.Bs,B(this.Vs)),t.ve(this.Bs,n,B(this.Vs))}pe(t,i,n){return{ot:t,me:i.Ot[0],be:i.Ot[1],we:i.Ot[2],ge:i.Ot[3],nt:NaN,de:NaN,_e:NaN,ue:NaN,fe:NaN}}$s(){const t=this.zs.js();this.Bs=this.zs.Bn().Qs().map((i=>this.te(i.ie,i,t)))}}class Nt extends Lt{constructor(){super(...arguments),this.Ns=new It}te(t,i,n){return Object.assign(Object.assign({},this.pe(t,i,n)),n.Ws(t))}Ks(){const t=this.zs.W();this.Ns.J({Bn:this.Bs,ee:this.Es.St().ee(),ce:t.openVisible,ae:t.thinBars,tt:this.Vs})}}class Ft extends wt{constructor(){super(...arguments),this.ys=new St}fs(t,i){const n=this.G;return this.ys.vs(t,{bs:i.Me,ws:i.xe,gs:i.Se,Ms:i.ye,xs:t.bitmapSize.height,cs:n.cs})}}class Wt extends Ct{constructor(){super(...arguments),this.ke=new St}Ps(t,i){const n=this.G;return this.ke.vs(t,{bs:i.Ce,ws:i.Ce,gs:i.Te,Ms:i.Te,xs:t.bitmapSize.height,cs:n.cs})}}class jt extends zt{constructor(t,i){super(t,i),this.Ns=new I,this.Pe=new Ft,this.Re=new Wt,this.Ns.X([this.Pe,this.Re])}te(t,i,n){return Object.assign(Object.assign({},this.Js(t,i)),n.Ws(t))}Ks(){const t=this.zs.Ct();if(null===t)return;const i=this.zs.W(),n=this.zs.Dt().Rt(i.baseValue.price,t.Ot),s=this.Es.St().ee();this.Pe.J({it:this.Bs,et:i.lineWidth,Nt:i.lineStyle,us:i.lineType,cs:n,ds:!1,tt:this.Vs,_s:s}),this.Re.J({it:this.Bs,et:i.lineWidth,Nt:i.lineStyle,us:i.lineVisible?i.lineType:void 0,Ts:i.pointMarkersVisible?i.pointMarkersRadius||i.lineWidth/2+2:void 0,cs:n,tt:this.Vs,_s:s})}}class Ht extends L{constructor(){super(...arguments),this.Et=null,this.re=0}J(t){this.Et=t}Z(t){if(null===this.Et||0===this.Et.Bn.length||null===this.Et.tt)return;const{horizontalPixelRatio:i}=t;if(this.re=function(t,i){if(t>=2.5&&t<=4)return Math.floor(3*i);const n=1-.2*Math.atan(Math.max(4,t)-4)/(.5*Math.PI),s=Math.floor(t*n*i),e=Math.floor(t*i),r=Math.min(s,e);return Math.max(Math.floor(i),r)}(this.Et.ee,i),this.re>=2){Math.floor(i)%2!=this.re%2&&this.re--}const n=this.Et.Bn;this.Et.De&&this.Oe(t,n,this.Et.tt),this.Et._i&&this.Ae(t,n,this.Et.tt);const s=this.Be(i);(!this.Et._i||this.re>2*s)&&this.Ve(t,n,this.Et.tt)}Oe(t,i,n){if(null===this.Et)return;const{context:s,horizontalPixelRatio:e,verticalPixelRatio:r}=t;let h="",l=Math.min(Math.floor(e),Math.floor(this.Et.ee*e));l=Math.max(Math.floor(e),Math.min(l,this.re));const a=Math.floor(.5*l);let o=null;for(let t=n.from;t2*l)U(s,o,u,_-o+1,c-u+1,l);else{const t=_-o+1;s.fillRect(o,u,t,c-u+1)}a=_}}Ve(t,i,n){if(null===this.Et)return;const{context:s,horizontalPixelRatio:e,verticalPixelRatio:r}=t;let h="";const l=this.Be(e);for(let t=n.from;to||s.fillRect(_,a,u-_+1,o-a+1)}}}class $t extends Lt{constructor(){super(...arguments),this.Ns=new Ht}te(t,i,n){return Object.assign(Object.assign({},this.pe(t,i,n)),n.Ws(t))}Ks(){const t=this.zs.W();this.Ns.J({Bn:this.Bs,ee:this.Es.St().ee(),De:t.wickVisible,_i:t.borderVisible,tt:this.Vs})}}class Ut{constructor(t,i){this.Ie=t,this.Ei=i}K(t,i,n){this.Ie.draw(t,this.Ei,i,n)}}class qt extends Vt{constructor(t,i,n){super(t,i,!1),this.mn=n,this.Ns=new Ut(this.mn.renderer(),(i=>{const n=t.Ct();return null===n?null:t.Dt().Rt(i,n.Ot)}))}Le(t){return this.mn.priceValueBuilder(t)}Ne(t){return this.mn.isWhitespace(t)}$s(){const t=this.zs.js();this.Bs=this.zs.Bn().Qs().map((i=>Object.assign(Object.assign({ot:i.ie,nt:NaN},t.Ws(i.ie)),{Fe:i.We})))}Xs(t,i){i.Zs(this.Bs,B(this.Vs))}Ks(){this.mn.update({bars:this.Bs.map(Yt),barSpacing:this.Es.St().ee(),visibleRange:this.Vs},this.zs.W())}}function Yt(t){return{x:t.nt,time:t.ot,originalData:t.Fe,barColor:t.oe}}class Xt extends L{constructor(){super(...arguments),this.Et=null,this.je=[]}J(t){this.Et=t,this.je=[]}Z({context:t,horizontalPixelRatio:i,verticalPixelRatio:n}){if(null===this.Et||0===this.Et.it.length||null===this.Et.tt)return;this.je.length||this.He(i);const s=Math.max(1,Math.floor(n)),e=Math.round(this.Et.$e*n)-Math.floor(s/2),r=e+s;for(let i=this.Et.tt.from;is.qe?s.ui=n.Rs-i-1:n.Rs=s.ui+i+1))}let s=Math.ceil(this.Et.ee*t);for(let t=this.Et.tt.from;t0&&s<4)for(let t=this.Et.tt.from;ts&&(i.Ue>i.qe?i.ui-=1:i.Rs+=1)}}}class Kt extends zt{constructor(){super(...arguments),this.Ns=new Xt}te(t,i,n){return Object.assign(Object.assign({},this.Js(t,i)),n.Ws(t))}Ks(){const t={it:this.Bs,ee:this.Es.St().ee(),tt:this.Vs,$e:this.zs.Dt().Rt(this.zs.W().base,f(this.zs.Ct()).Ot)};this.Ns.J(t)}}class Zt extends zt{constructor(){super(...arguments),this.Ns=new Tt}te(t,i,n){return Object.assign(Object.assign({},this.Js(t,i)),n.Ws(t))}Ks(){const t=this.zs.W(),i={it:this.Bs,Nt:t.lineStyle,us:t.lineVisible?t.lineType:void 0,et:t.lineWidth,Ts:t.pointMarkersVisible?t.pointMarkersRadius||t.lineWidth/2+2:void 0,tt:this.Vs,_s:this.Es.St().ee()};this.Ns.J(i)}}const Gt=/[2-9]/g;class Jt{constructor(t=50){this.Ye=0,this.Xe=1,this.Ke=1,this.Ze={},this.Ge=new Map,this.Je=t}Qe(){this.Ye=0,this.Ge.clear(),this.Xe=1,this.Ke=1,this.Ze={}}Mi(t,i,n){return this.tr(t,i,n).width}gi(t,i,n){const s=this.tr(t,i,n);return((s.actualBoundingBoxAscent||0)-(s.actualBoundingBoxDescent||0))/2}tr(t,i,n){const s=n||Gt,e=String(i).replace(s,"0");if(this.Ge.has(e))return d(this.Ge.get(e)).ir;if(this.Ye===this.Je){const t=this.Ze[this.Ke];delete this.Ze[this.Ke],this.Ge.delete(t),this.Ke++,this.Ye--}t.save(),t.textBaseline="middle";const r=t.measureText(e);return t.restore(),0===r.width&&i.length||(this.Ge.set(e,{ir:r,nr:this.Xe}),this.Ze[this.Xe]=e,this.Ye++,this.Xe++),r}}class Qt{constructor(t){this.sr=null,this.k=null,this.er="right",this.rr=t}hr(t,i,n){this.sr=t,this.k=i,this.er=n}K(t){null!==this.k&&null!==this.sr&&this.sr.K(t,this.k,this.rr,this.er)}}class ti{constructor(t,i,n){this.lr=t,this.rr=new Jt(50),this.ar=i,this.F=n,this.j=-1,this.Wt=new Qt(this.rr)}gt(){const t=this.F._r(this.ar);if(null===t)return null;const i=t.ur(this.ar)?t.cr():this.ar.Dt();if(null===i)return null;const n=t.dr(i);if("overlay"===n)return null;const s=this.F.vr();return s.P!==this.j&&(this.j=s.P,this.rr.Qe()),this.Wt.hr(this.lr.Vi(),s,n),this.Wt}}class ii extends L{constructor(){super(...arguments),this.Et=null}J(t){this.Et=t}pr(t,i){var n;if(!(null===(n=this.Et)||void 0===n?void 0:n.kt))return null;const{st:s,et:e,mr:r}=this.Et;return i>=s-e-7&&i<=s+e+7?{br:this.Et,mr:r}:null}Z({context:t,bitmapSize:i,horizontalPixelRatio:n,verticalPixelRatio:s}){if(null===this.Et)return;if(!1===this.Et.kt)return;const e=Math.round(this.Et.st*s);e<0||e>i.height||(t.lineCap="butt",t.strokeStyle=this.Et.O,t.lineWidth=Math.floor(this.Et.et*n),_(t,this.Et.Nt),u(t,e,0,i.width))}}class ni{constructor(t){this.wr={st:0,O:"rgba(0, 0, 0, 0)",et:1,Nt:0,kt:!1},this.gr=new ii,this.ft=!0,this.zs=t,this.Es=t.$t(),this.gr.J(this.wr)}bt(){this.ft=!0}gt(){return this.zs.kt()?(this.ft&&(this.Mr(),this.ft=!1),this.gr):null}}class si extends ni{constructor(t){super(t)}Mr(){this.wr.kt=!1;const t=this.zs.Dt(),i=t.Sr().Sr;if(2!==i&&3!==i)return;const n=this.zs.W();if(!n.baseLineVisible||!this.zs.kt())return;const s=this.zs.Ct();null!==s&&(this.wr.kt=!0,this.wr.st=t.Rt(s.Ot,s.Ot),this.wr.O=n.baseLineColor,this.wr.et=n.baseLineWidth,this.wr.Nt=n.baseLineStyle)}}class ei extends L{constructor(){super(...arguments),this.Et=null}J(t){this.Et=t}We(){return this.Et}Z({context:t,horizontalPixelRatio:i,verticalPixelRatio:n}){const s=this.Et;if(null===s)return;const e=Math.max(1,Math.floor(i)),r=e%2/2,h=Math.round(s.qe.x*i)+r,l=s.qe.y*n;t.fillStyle=s.yr,t.beginPath();const a=Math.max(2,1.5*s.kr)*i;t.arc(h,l,a,0,2*Math.PI,!1),t.fill(),t.fillStyle=s.Cr,t.beginPath(),t.arc(h,l,s.ht*i,0,2*Math.PI,!1),t.fill(),t.lineWidth=e,t.strokeStyle=s.Tr,t.beginPath(),t.arc(h,l,s.ht*i+e/2,0,2*Math.PI,!1),t.stroke()}}const ri=[{Pr:0,Rr:.25,Dr:4,Or:10,Ar:.25,Br:0,Vr:.4,zr:.8},{Pr:.25,Rr:.525,Dr:10,Or:14,Ar:0,Br:0,Vr:.8,zr:0},{Pr:.525,Rr:1,Dr:14,Or:14,Ar:0,Br:0,Vr:0,zr:0}];function hi(t,i,n,s){return function(t,i){if("transparent"===t)return t;const n=S(t),s=n[3];return`rgba(${n[0]}, ${n[1]}, ${n[2]}, ${i*s})`}(t,n+(s-n)*i)}function li(t,i){const n=t%2600/2600;let s;for(const t of ri)if(n>=t.Pr&&n<=t.Rr){s=t;break}c(void 0!==s,"Last price animation internal logic error");const e=(n-s.Pr)/(s.Rr-s.Pr);return{Cr:hi(i,e,s.Ar,s.Br),Tr:hi(i,e,s.Vr,s.zr),ht:(r=e,h=s.Dr,l=s.Or,h+(l-h)*r)};var r,h,l}class ai{constructor(t){this.Wt=new ei,this.ft=!0,this.Er=!0,this.Ir=performance.now(),this.Lr=this.Ir-1,this.Nr=t}Fr(){this.Lr=this.Ir-1,this.bt()}Wr(){if(this.bt(),2===this.Nr.W().lastPriceAnimation){const t=performance.now(),i=this.Lr-t;if(i>0)return void(i<650&&(this.Lr+=2600));this.Ir=t,this.Lr=t+2600}}bt(){this.ft=!0}jr(){this.Er=!0}kt(){return 0!==this.Nr.W().lastPriceAnimation}Hr(){switch(this.Nr.W().lastPriceAnimation){case 0:return!1;case 1:return!0;case 2:return performance.now()<=this.Lr}}gt(){return this.ft?(this.Mt(),this.ft=!1,this.Er=!1):this.Er&&(this.$r(),this.Er=!1),this.Wt}Mt(){this.Wt.J(null);const t=this.Nr.$t().St(),i=t.qs(),n=this.Nr.Ct();if(null===i||null===n)return;const s=this.Nr.Ur(!0);if(s.qr||!i.Yr(s.ie))return;const e={x:t.zt(s.ie),y:this.Nr.Dt().Rt(s._t,n.Ot)},r=s.O,h=this.Nr.W().lineWidth,l=li(this.Xr(),r);this.Wt.J({yr:r,kr:h,Cr:l.Cr,Tr:l.Tr,ht:l.ht,qe:e})}$r(){const t=this.Wt.We();if(null!==t){const i=li(this.Xr(),t.yr);t.Cr=i.Cr,t.Tr=i.Tr,t.ht=i.ht}}Xr(){return this.Hr()?performance.now()-this.Ir:2599}}function oi(t,i){return xt(Math.min(Math.max(t,12),30)*i)}function _i(t,i){switch(t){case"arrowDown":case"arrowUp":return oi(i,1);case"circle":return oi(i,.8);case"square":return oi(i,.7)}}function ui(t){return function(t){const i=Math.ceil(t);return i%2!=0?i-1:i}(oi(t,1))}function ci(t){return Math.max(oi(t,.1),3)}function di(t,i,n,s,e){const r=_i("square",n),h=(r-1)/2,l=t-h,a=i-h;return s>=l&&s<=l+r&&e>=a&&e<=a+r}function fi(t,i,n,s){const e=(_i("arrowUp",s)-1)/2*n.Kr,r=(xt(s/2)-1)/2*n.Kr;i.beginPath(),t?(i.moveTo(n.nt-e,n.st),i.lineTo(n.nt,n.st-e),i.lineTo(n.nt+e,n.st),i.lineTo(n.nt+r,n.st),i.lineTo(n.nt+r,n.st+e),i.lineTo(n.nt-r,n.st+e),i.lineTo(n.nt-r,n.st)):(i.moveTo(n.nt-e,n.st),i.lineTo(n.nt,n.st+e),i.lineTo(n.nt+e,n.st),i.lineTo(n.nt+r,n.st),i.lineTo(n.nt+r,n.st-e),i.lineTo(n.nt-r,n.st-e),i.lineTo(n.nt-r,n.st)),i.fill()}function vi(t,i,n,s,e,r){return di(i,n,s,e,r)}class pi extends L{constructor(){super(...arguments),this.Et=null,this.rr=new Jt,this.j=-1,this.H="",this.Zr=""}J(t){this.Et=t}hr(t,i){this.j===t&&this.H===i||(this.j=t,this.H=i,this.Zr=z(t,i),this.rr.Qe())}pr(t,i){if(null===this.Et||null===this.Et.tt)return null;for(let n=this.Et.tt.from;n=t&&e<=t+n&&r>=i-h&&r<=i+h}(t.Zt.nt,t.Zt.st,t.Zt.ji,t.Zt.Vt,i,n))||function(t,i,n){if(0===t.Ys)return!1;switch(t.Qr){case"arrowDown":case"arrowUp":return vi(0,t.nt,t.st,t.Ys,i,n);case"circle":return function(t,i,n,s,e){const r=2+_i("circle",n)/2,h=t-s,l=i-e;return Math.sqrt(h*h+l*l)<=r}(t.nt,t.st,t.Ys,i,n);case"square":return di(t.nt,t.st,t.Ys,i,n)}}(t,i,n)}function wi(t,i,n,s,e,r,h,l,a){const o=T(n)?n:n.ge,_=T(n)?n:n.be,u=T(n)?n:n.we,c=T(i.size)?Math.max(i.size,0):1,d=ui(l.ee())*c,f=d/2;switch(t.Ys=d,i.position){case"inBar":return t.st=h.Rt(o,a),void(void 0!==t.Zt&&(t.Zt.st=t.st+f+r+.6*e));case"aboveBar":return t.st=h.Rt(_,a)-f-s.th,void 0!==t.Zt&&(t.Zt.st=t.st-f-.6*e,s.th+=1.2*e),void(s.th+=d+r);case"belowBar":return t.st=h.Rt(u,a)+f+s.ih,void 0!==t.Zt&&(t.Zt.st=t.st+f+r+.6*e,s.ih+=1.2*e),void(s.ih+=d+r)}i.position}class gi{constructor(t,i){this.ft=!0,this.nh=!0,this.sh=!0,this.eh=null,this.Wt=new pi,this.Nr=t,this.Hi=i,this.Et={it:[],tt:null}}bt(t){this.ft=!0,this.sh=!0,"data"===t&&(this.nh=!0)}gt(t){if(!this.Nr.kt())return null;this.ft&&this.rh();const i=this.Hi.W().layout;return this.Wt.hr(i.fontSize,i.fontFamily),this.Wt.J(this.Et),this.Wt}hh(){if(this.sh){if(this.Nr.lh().length>0){const t=this.Hi.St().ee(),i=ci(t),n=1.5*ui(t)+2*i;this.eh={above:n,below:n}}else this.eh=null;this.sh=!1}return this.eh}rh(){const t=this.Nr.Dt(),i=this.Hi.St(),n=this.Nr.lh();this.nh&&(this.Et.it=n.map((t=>({ot:t.time,nt:0,st:0,Ys:0,Qr:t.shape,O:t.color,Gr:t.Gr,mr:t.id,Zt:void 0}))),this.nh=!1);const s=this.Hi.W().layout;this.Et.tt=null;const e=i.qs();if(null===e)return;const r=this.Nr.Ct();if(null===r)return;if(0===this.Et.it.length)return;let h=NaN;const l=ci(i.ee()),a={th:l,ih:l};this.Et.tt=Bt(this.Et.it,e,!0);for(let e=this.Et.tt.from;e0&&(_.Zt={Jr:o.text,nt:0,st:0,ji:0,Vt:0});const u=this.Nr.ah(o.time);null!==u&&wi(_,o,u,a,s.fontSize,l,t,i,r.Ot)}this.ft=!1}}class Mi extends ni{constructor(t){super(t)}Mr(){const t=this.wr;t.kt=!1;const i=this.zs.W();if(!i.priceLineVisible||!this.zs.kt())return;const n=this.zs.Ur(0===i.priceLineSource);n.qr||(t.kt=!0,t.st=n.Si,t.O=this.zs.oh(n.O),t.et=i.priceLineWidth,t.Nt=i.priceLineStyle)}}class xi extends J{constructor(t){super(),this.jt=t}zi(t,i,n){t.kt=!1,i.kt=!1;const s=this.jt;if(!s.kt())return;const e=s.W(),r=e.lastValueVisible,h=""!==s._h(),l=0===e.seriesLastValueMode,a=s.Ur(!1);if(a.qr)return;r&&(t.Zt=this.uh(a,r,l),t.kt=0!==t.Zt.length),(h||l)&&(i.Zt=this.dh(a,r,h,l),i.kt=i.Zt.length>0);const o=s.oh(a.O),_=y(o);n.t=_.t,n.Si=a.Si,i.At=s.$t().Bt(a.Si/s.Dt().Vt()),t.At=o,t.O=_.i,i.O=_.i}dh(t,i,n,s){let e="";const r=this.jt._h();return n&&0!==r.length&&(e+=`${r} `),i&&s&&(e+=this.jt.Dt().fh()?t.ph:t.mh),e.trim()}uh(t,i,n){return i?n?this.jt.Dt().fh()?t.mh:t.ph:t.Zt:""}}function Si(t,i,n,s){const e=Number.isFinite(i),r=Number.isFinite(n);return e&&r?t(i,n):e||r?e?i:n:s}class yi{constructor(t,i){this.bh=t,this.wh=i}gh(t){return null!==t&&(this.bh===t.bh&&this.wh===t.wh)}Mh(){return new yi(this.bh,this.wh)}xh(){return this.bh}Sh(){return this.wh}yh(){return this.wh-this.bh}Li(){return this.wh===this.bh||Number.isNaN(this.wh)||Number.isNaN(this.bh)}Jn(t){return null===t?this:new yi(Si(Math.min,this.xh(),t.xh(),-1/0),Si(Math.max,this.Sh(),t.Sh(),1/0))}kh(t){if(!T(t))return;if(0===this.wh-this.bh)return;const i=.5*(this.wh+this.bh);let n=this.wh-i,s=this.bh-i;n*=t,s*=t,this.wh=i+n,this.bh=i+s}Ch(t){T(t)&&(this.wh+=t,this.bh+=t)}Th(){return{minValue:this.bh,maxValue:this.wh}}static Ph(t){return null===t?null:new yi(t.minValue,t.maxValue)}}class ki{constructor(t,i){this.Rh=t,this.Dh=i||null}Oh(){return this.Rh}Ah(){return this.Dh}Th(){return null===this.Rh?null:{priceRange:this.Rh.Th(),margins:this.Dh||void 0}}static Ph(t){return null===t?null:new ki(yi.Ph(t.priceRange),t.margins)}}class Ci extends ni{constructor(t,i){super(t),this.Bh=i}Mr(){const t=this.wr;t.kt=!1;const i=this.Bh.W();if(!this.zs.kt()||!i.lineVisible)return;const n=this.Bh.Vh();null!==n&&(t.kt=!0,t.st=n,t.O=i.color,t.et=i.lineWidth,t.Nt=i.lineStyle,t.mr=this.Bh.W().id)}}class Ti extends J{constructor(t,i){super(),this.Nr=t,this.Bh=i}zi(t,i,n){t.kt=!1,i.kt=!1;const s=this.Bh.W(),e=s.axisLabelVisible,r=""!==s.title,h=this.Nr;if(!e||!h.kt())return;const l=this.Bh.Vh();if(null===l)return;r&&(i.Zt=s.title,i.kt=!0),i.At=h.$t().Bt(l/h.Dt().Vt()),t.Zt=this.zh(s.price),t.kt=!0;const a=y(s.axisLabelColor||s.color);n.t=a.t;const o=s.axisLabelTextColor||a.i;t.O=o,i.O=o,n.Si=l}zh(t){const i=this.Nr.Ct();return null===i?"":this.Nr.Dt().Ni(t,i.Ot)}}class Pi{constructor(t,i){this.Nr=t,this._n=i,this.Eh=new Ci(t,this),this.lr=new Ti(t,this),this.Ih=new ti(this.lr,t,t.$t())}Lh(t){C(this._n,t),this.bt(),this.Nr.$t().Nh()}W(){return this._n}Fh(){return this.Eh}Wh(){return this.Ih}jh(){return this.lr}bt(){this.Eh.bt(),this.lr.bt()}Vh(){const t=this.Nr,i=t.Dt();if(t.$t().St().Li()||i.Li())return null;const n=t.Ct();return null===n?null:i.Rt(this._n.price,n.Ot)}}class Ri extends st{constructor(t){super(),this.Hi=t}$t(){return this.Hi}}const Di={Bar:(t,i,n,s)=>{var e;const r=i.upColor,h=i.downColor,l=f(t(n,s)),a=v(l.Ot[0])<=v(l.Ot[3]);return{oe:null!==(e=l.O)&&void 0!==e?e:a?r:h}},Candlestick:(t,i,n,s)=>{var e,r,h;const l=i.upColor,a=i.downColor,o=i.borderUpColor,_=i.borderDownColor,u=i.wickUpColor,c=i.wickDownColor,d=f(t(n,s)),p=v(d.Ot[0])<=v(d.Ot[3]);return{oe:null!==(e=d.O)&&void 0!==e?e:p?l:a,Ee:null!==(r=d.At)&&void 0!==r?r:p?o:_,ze:null!==(h=d.Hh)&&void 0!==h?h:p?u:c}},Custom:(t,i,n,s)=>{var e;return{oe:null!==(e=f(t(n,s)).O)&&void 0!==e?e:i.color}},Area:(t,i,n,s)=>{var e,r,h,l;const a=f(t(n,s));return{oe:null!==(e=a.lt)&&void 0!==e?e:i.lineColor,lt:null!==(r=a.lt)&&void 0!==r?r:i.lineColor,ks:null!==(h=a.ks)&&void 0!==h?h:i.topColor,Cs:null!==(l=a.Cs)&&void 0!==l?l:i.bottomColor}},Baseline:(t,i,n,s)=>{var e,r,h,l,a,o;const _=f(t(n,s));return{oe:_.Ot[3]>=i.baseValue.price?i.topLineColor:i.bottomLineColor,Ce:null!==(e=_.Ce)&&void 0!==e?e:i.topLineColor,Te:null!==(r=_.Te)&&void 0!==r?r:i.bottomLineColor,Me:null!==(h=_.Me)&&void 0!==h?h:i.topFillColor1,xe:null!==(l=_.xe)&&void 0!==l?l:i.topFillColor2,Se:null!==(a=_.Se)&&void 0!==a?a:i.bottomFillColor1,ye:null!==(o=_.ye)&&void 0!==o?o:i.bottomFillColor2}},Line:(t,i,n,s)=>{var e,r;const h=f(t(n,s));return{oe:null!==(e=h.O)&&void 0!==e?e:i.color,lt:null!==(r=h.O)&&void 0!==r?r:i.color}},Histogram:(t,i,n,s)=>{var e;return{oe:null!==(e=f(t(n,s)).O)&&void 0!==e?e:i.color}}};class Oi{constructor(t){this.$h=(t,i)=>void 0!==i?i.Ot:this.Nr.Bn().Uh(t),this.Nr=t,this.qh=Di[t.Yh()]}Ws(t,i){return this.qh(this.$h,this.Nr.W(),t,i)}}var Ai;!function(t){t[t.NearestLeft=-1]="NearestLeft",t[t.None=0]="None",t[t.NearestRight=1]="NearestRight"}(Ai||(Ai={}));const Bi=30;class Vi{constructor(){this.Xh=[],this.Kh=new Map,this.Zh=new Map}Gh(){return this.Ys()>0?this.Xh[this.Xh.length-1]:null}Jh(){return this.Ys()>0?this.Qh(0):null}An(){return this.Ys()>0?this.Qh(this.Xh.length-1):null}Ys(){return this.Xh.length}Li(){return 0===this.Ys()}Yr(t){return null!==this.tl(t,0)}Uh(t){return this.il(t)}il(t,i=0){const n=this.tl(t,i);return null===n?null:Object.assign(Object.assign({},this.nl(n)),{ie:this.Qh(n)})}Qs(){return this.Xh}sl(t,i,n){if(this.Li())return null;let s=null;for(const e of n){s=zi(s,this.el(t,i,e))}return s}J(t){this.Zh.clear(),this.Kh.clear(),this.Xh=t}Qh(t){return this.Xh[t].ie}nl(t){return this.Xh[t]}tl(t,i){const n=this.rl(t);if(null===n&&0!==i)switch(i){case-1:return this.hl(t);case 1:return this.ll(t);default:throw new TypeError("Unknown search mode")}return n}hl(t){let i=this.al(t);return i>0&&(i-=1),i!==this.Xh.length&&this.Qh(i)t.iet.ie>i))}_l(t,i,n){let s=null;for(let e=t;es.cl&&(s.cl=t)))}return s}el(t,i,n){if(this.Li())return null;let s=null;const e=f(this.Jh()),r=f(this.An()),h=Math.max(t,e),l=Math.min(i,r),a=Math.ceil(h/Bi)*Bi,o=Math.max(a,Math.floor(l/Bi)*Bi);{const t=this.al(h),e=this.ol(Math.min(l,a,i));s=zi(s,this._l(t,e,n))}let _=this.Kh.get(n);void 0===_&&(_=new Map,this.Kh.set(n,_));for(let t=Math.max(a+1,h);tnew Ii(t)));return this.gl={vl:e,pl:r},r}Ji(){var t,i,n,s;const e=null!==(n=null===(i=(t=this.kl).timeAxisViews)||void 0===i?void 0:i.call(t))&&void 0!==n?n:[];if((null===(s=this.Ml)||void 0===s?void 0:s.vl)===e)return this.Ml.pl;const r=this.Nr.$t().St(),h=e.map((t=>new Ni(t,r)));return this.Ml={vl:e,pl:h},h}Tn(){var t,i,n,s;const e=null!==(n=null===(i=(t=this.kl).priceAxisViews)||void 0===i?void 0:i.call(t))&&void 0!==n?n:[];if((null===(s=this.xl)||void 0===s?void 0:s.vl)===e)return this.xl.pl;const r=this.Nr.Dt(),h=e.map((t=>new Fi(t,r)));return this.xl={vl:e,pl:h},h}Tl(){var t,i,n,s;const e=null!==(n=null===(i=(t=this.kl).priceAxisPaneViews)||void 0===i?void 0:i.call(t))&&void 0!==n?n:[];if((null===(s=this.Sl)||void 0===s?void 0:s.vl)===e)return this.Sl.pl;const r=e.map((t=>new Ii(t)));return this.Sl={vl:e,pl:r},r}Pl(){var t,i,n,s;const e=null!==(n=null===(i=(t=this.kl).timeAxisPaneViews)||void 0===i?void 0:i.call(t))&&void 0!==n?n:[];if((null===(s=this.yl)||void 0===s?void 0:s.vl)===e)return this.yl.pl;const r=e.map((t=>new Ii(t)));return this.yl={vl:e,pl:r},r}Rl(t,i){var n,s,e;return null!==(e=null===(s=(n=this.kl).autoscaleInfo)||void 0===s?void 0:s.call(n,t,i))&&void 0!==e?e:null}pr(t,i){var n,s,e;return null!==(e=null===(s=(n=this.kl).hitTest)||void 0===s?void 0:s.call(n,t,i))&&void 0!==e?e:null}}function ji(t,i,n,s){t.forEach((t=>{i(t).forEach((t=>{t.ml()===n&&s.push(t)}))}))}function Hi(t){return t.Cn()}function $i(t){return t.Tl()}function Ui(t){return t.Pl()}class qi extends Ri{constructor(t,i,n,s,e){super(t),this.Et=new Vi,this.Eh=new Mi(this),this.Dl=[],this.Ol=new si(this),this.Al=null,this.Bl=null,this.Vl=[],this.zl=[],this.El=null,this.Il=[],this._n=i,this.Ll=n;const r=new xi(this);this.en=[r],this.Ih=new ti(r,this,t),"Area"!==n&&"Line"!==n&&"Baseline"!==n||(this.Al=new ai(this)),this.Nl(),this.Fl(e)}S(){null!==this.El&&clearTimeout(this.El)}oh(t){return this._n.priceLineColor||t}Ur(t){const i={qr:!0},n=this.Dt();if(this.$t().St().Li()||n.Li()||this.Et.Li())return i;const s=this.$t().St().qs(),e=this.Ct();if(null===s||null===e)return i;let r,h;if(t){const t=this.Et.Gh();if(null===t)return i;r=t,h=t.ie}else{const t=this.Et.il(s.ui(),-1);if(null===t)return i;if(r=this.Et.Uh(t.ie),null===r)return i;h=t.ie}const l=r.Ot[3],a=this.js().Ws(h,{Ot:r}),o=n.Rt(l,e.Ot);return{qr:!1,_t:l,Zt:n.Ni(l,e.Ot),ph:n.Wl(l),mh:n.jl(l,e.Ot),O:a.oe,Si:o,ie:h}}js(){return null!==this.Bl||(this.Bl=new Oi(this)),this.Bl}W(){return this._n}Lh(t){const i=t.priceScaleId;void 0!==i&&i!==this._n.priceScaleId&&this.$t().Hl(this,i),C(this._n,t),void 0!==t.priceFormat&&(this.Nl(),this.$t().$l()),this.$t().Ul(this),this.$t().ql(),this.mn.bt("options")}J(t,i){this.Et.J(t),this.Yl(),this.mn.bt("data"),this.un.bt("data"),null!==this.Al&&(i&&i.Xl?this.Al.Wr():0===t.length&&this.Al.Fr());const n=this.$t()._r(this);this.$t().Kl(n),this.$t().Ul(this),this.$t().ql(),this.$t().Nh()}Zl(t){this.Vl=t,this.Yl();const i=this.$t()._r(this);this.un.bt("data"),this.$t().Kl(i),this.$t().Ul(this),this.$t().ql(),this.$t().Nh()}Gl(){return this.Vl}lh(){return this.zl}Jl(t){const i=new Pi(this,t);return this.Dl.push(i),this.$t().Ul(this),i}Ql(t){const i=this.Dl.indexOf(t);-1!==i&&this.Dl.splice(i,1),this.$t().Ul(this)}Yh(){return this.Ll}Ct(){const t=this.ta();return null===t?null:{Ot:t.Ot[3],ia:t.ot}}ta(){const t=this.$t().St().qs();if(null===t)return null;const i=t.Rs();return this.Et.il(i,1)}Bn(){return this.Et}ah(t){const i=this.Et.Uh(t);return null===i?null:"Bar"===this.Ll||"Candlestick"===this.Ll||"Custom"===this.Ll?{me:i.Ot[0],be:i.Ot[1],we:i.Ot[2],ge:i.Ot[3]}:i.Ot[3]}na(t){const i=[];ji(this.Il,Hi,"top",i);const n=this.Al;return null!==n&&n.kt()?(null===this.El&&n.Hr()&&(this.El=setTimeout((()=>{this.El=null,this.$t().sa()}),0)),n.jr(),i.push(n),i):i}Cn(){const t=[];this.ea()||t.push(this.Ol),t.push(this.mn,this.Eh,this.un);const i=this.Dl.map((t=>t.Fh()));return t.push(...i),ji(this.Il,Hi,"normal",t),t}ra(){return this.ha(Hi,"bottom")}la(t){return this.ha($i,t)}aa(t){return this.ha(Ui,t)}oa(t,i){return this.Il.map((n=>n.pr(t,i))).filter((t=>null!==t))}Gi(t){return[this.Ih,...this.Dl.map((t=>t.Wh()))]}Tn(t,i){if(i!==this.qi&&!this.ea())return[];const n=[...this.en];for(const t of this.Dl)n.push(t.jh());return this.Il.forEach((t=>{n.push(...t.Tn())})),n}Ji(){const t=[];return this.Il.forEach((i=>{t.push(...i.Ji())})),t}Rl(t,i){if(void 0!==this._n.autoscaleInfoProvider){const n=this._n.autoscaleInfoProvider((()=>{const n=this._a(t,i);return null===n?null:n.Th()}));return ki.Ph(n)}return this._a(t,i)}ua(){return this._n.priceFormat.minMove}ca(){return this.da}Rn(){var t;this.mn.bt(),this.un.bt();for(const t of this.en)t.bt();for(const t of this.Dl)t.bt();this.Eh.bt(),this.Ol.bt(),null===(t=this.Al)||void 0===t||t.bt(),this.Il.forEach((t=>t.Rn()))}Dt(){return f(super.Dt())}yt(t){if(!(("Line"===this.Ll||"Area"===this.Ll||"Baseline"===this.Ll)&&this._n.crosshairMarkerVisible))return null;const i=this.Et.Uh(t);if(null===i)return null;return{_t:i.Ot[3],ht:this.fa(),At:this.va(),Pt:this.pa(),Tt:this.ma(t)}}_h(){return this._n.title}kt(){return this._n.visible}ba(t){this.Il.push(new Wi(t,this))}wa(t){this.Il=this.Il.filter((i=>i.Cl()!==t))}ga(){if(this.mn instanceof qt!=!1)return t=>this.mn.Le(t)}Ma(){if(this.mn instanceof qt!=!1)return t=>this.mn.Ne(t)}ea(){return!ht(this.Dt().xa())}_a(t,i){if(!P(t)||!P(i)||this.Et.Li())return null;const n="Line"===this.Ll||"Area"===this.Ll||"Baseline"===this.Ll||"Histogram"===this.Ll?[3]:[2,1],s=this.Et.sl(t,i,n);let e=null!==s?new yi(s.ul,s.cl):null;if("Histogram"===this.Yh()){const t=this._n.base,i=new yi(t,t);e=null!==e?e.Jn(i):i}let r=this.un.hh();return this.Il.forEach((n=>{const s=n.Rl(t,i);if(null==s?void 0:s.priceRange){const t=new yi(s.priceRange.minValue,s.priceRange.maxValue);e=null!==e?e.Jn(t):t}var h,l,a,o;(null==s?void 0:s.margins)&&(h=r,l=s.margins,r={above:Math.max(null!==(a=null==h?void 0:h.above)&&void 0!==a?a:0,l.above),below:Math.max(null!==(o=null==h?void 0:h.below)&&void 0!==o?o:0,l.below)})})),new ki(e,r)}fa(){switch(this.Ll){case"Line":case"Area":case"Baseline":return this._n.crosshairMarkerRadius}return 0}va(){switch(this.Ll){case"Line":case"Area":case"Baseline":{const t=this._n.crosshairMarkerBorderColor;if(0!==t.length)return t}}return null}pa(){switch(this.Ll){case"Line":case"Area":case"Baseline":return this._n.crosshairMarkerBorderWidth}return 0}ma(t){switch(this.Ll){case"Line":case"Area":case"Baseline":{const t=this._n.crosshairMarkerBackgroundColor;if(0!==t.length)return t}}return this.js().Ws(t).oe}Nl(){switch(this._n.priceFormat.type){case"custom":this.da={format:this._n.priceFormat.formatter};break;case"volume":this.da=new ct(this._n.priceFormat.precision);break;case"percent":this.da=new ut(this._n.priceFormat.precision);break;default:{const t=Math.pow(10,this._n.priceFormat.precision);this.da=new _t(t,this._n.priceFormat.minMove*t)}}null!==this.qi&&this.qi.Sa()}Yl(){const t=this.$t().St();if(!t.ya()||this.Et.Li())return void(this.zl=[]);const i=f(this.Et.Jh());this.zl=this.Vl.map(((n,s)=>{const e=f(t.ka(n.time,!0)),r=et instanceof qi)).reduce(((t,s)=>{if(n.ur(s)||!s.kt())return t;const e=s.Dt(),r=s.Bn();if(e.Li()||!r.Yr(i))return t;const h=r.Uh(i);if(null===h)return t;const l=v(s.Ct());return t.concat([e.Rt(h.Ot[3],l.Ot)])}),[]);if(0===l.length)return s;l.sort(((t,i)=>Math.abs(t-h)-Math.abs(i-h)));const a=l[0];return s=e.fn(a,r),s}}class Xi extends L{constructor(){super(...arguments),this.Et=null}J(t){this.Et=t}Z({context:t,bitmapSize:i,horizontalPixelRatio:n,verticalPixelRatio:s}){if(null===this.Et)return;const e=Math.max(1,Math.floor(n));t.lineWidth=e,function(t,i){t.save(),t.lineWidth%2&&t.translate(.5,.5),i(),t.restore()}(t,(()=>{const r=f(this.Et);if(r.Pa){t.strokeStyle=r.Ra,_(t,r.Da),t.beginPath();for(const s of r.Oa){const r=Math.round(s.Aa*n);t.moveTo(r,-e),t.lineTo(r,i.height+e)}t.stroke()}if(r.Ba){t.strokeStyle=r.Va,_(t,r.za),t.beginPath();for(const n of r.Ea){const r=Math.round(n.Aa*s);t.moveTo(-e,r),t.lineTo(i.width+e,r)}t.stroke()}}))}}class Ki{constructor(t){this.Wt=new Xi,this.ft=!0,this.Qi=t}bt(){this.ft=!0}gt(){if(this.ft){const t=this.Qi.$t().W().grid,i={Ba:t.horzLines.visible,Pa:t.vertLines.visible,Va:t.horzLines.color,Ra:t.vertLines.color,za:t.horzLines.style,Da:t.vertLines.style,Ea:this.Qi.dn().Ia(),Oa:(this.Qi.$t().St().Ia()||[]).map((t=>({Aa:t.coord})))};this.Wt.J(i),this.ft=!1}return this.Wt}}class Zi{constructor(t){this.mn=new Ki(t)}Fh(){return this.mn}}const Gi={La:4,Na:1e-4};function Ji(t,i){const n=100*(t-i)/i;return i<0?-n:n}function Qi(t,i){const n=Ji(t.xh(),i),s=Ji(t.Sh(),i);return new yi(n,s)}function tn(t,i){const n=100*(t-i)/i+100;return i<0?-n:n}function nn(t,i){const n=tn(t.xh(),i),s=tn(t.Sh(),i);return new yi(n,s)}function sn(t,i){const n=Math.abs(t);if(n<1e-15)return 0;const s=Math.log10(n+i.Na)+i.La;return t<0?-s:s}function en(t,i){const n=Math.abs(t);if(n<1e-15)return 0;const s=Math.pow(10,n-i.La)-i.Na;return t<0?-s:s}function rn(t,i){if(null===t)return null;const n=sn(t.xh(),i),s=sn(t.Sh(),i);return new yi(n,s)}function hn(t,i){if(null===t)return null;const n=en(t.xh(),i),s=en(t.Sh(),i);return new yi(n,s)}function ln(t){if(null===t)return Gi;const i=Math.abs(t.Sh()-t.xh());if(i>=1||i<1e-15)return Gi;const n=Math.ceil(Math.abs(Math.log10(i))),s=Gi.La+n;return{La:s,Na:1/Math.pow(10,s)}}class an{constructor(t,i){if(this.Fa=t,this.Wa=i,function(t){if(t<0)return!1;for(let i=t;i>1;i/=10)if(i%10!=0)return!1;return!0}(this.Fa))this.ja=[2,2.5,2];else{this.ja=[];for(let t=this.Fa;1!==t;){if(t%2==0)this.ja.push(2),t/=2;else{if(t%5!=0)throw new Error("unexpected base");this.ja.push(2,2.5),t/=5}if(this.ja.length>100)throw new Error("something wrong with base")}}}Ha(t,i,n){const s=0===this.Fa?0:1/this.Fa;let e=Math.pow(10,Math.max(0,Math.ceil(Math.log10(t-i)))),r=0,h=this.Wa[0];for(;;){const t=Mt(e,s,1e-14)&&e>s+1e-14,i=Mt(e,n*h,1e-14),l=Mt(e,1,1e-14);if(!(t&&i&&l))break;e/=h,h=this.Wa[++r%this.Wa.length]}if(e<=s+1e-14&&(e=s),e=Math.max(1,e),this.ja.length>0&&(l=e,a=1,o=1e-14,Math.abs(l-a)s+1e-14;)e/=h,h=this.ja[++r%this.ja.length];var l,a,o;return e}}class on{constructor(t,i,n,s){this.$a=[],this.Ei=t,this.Fa=i,this.Ua=n,this.qa=s}Ha(t,i){if(t=o?1:-1;let d=null,f=0;for(let n=a-u;n>o;n-=_){const s=this.qa(n,i,!0);null!==d&&Math.abs(s-d)l||(ff(t.Xi())-f(i.Xi())))}var un;!function(t){t[t.Normal=0]="Normal",t[t.Logarithmic=1]="Logarithmic",t[t.Percentage=2]="Percentage",t[t.IndexedTo100=3]="IndexedTo100"}(un||(un={}));const cn=new ut,dn=new _t(100,1);class fn{constructor(t,i,n,s){this.Qa=0,this.io=null,this.Rh=null,this.no=null,this.so={eo:!1,ro:null},this.ho=0,this.lo=0,this.ao=new k,this.oo=new k,this._o=[],this.uo=null,this.co=null,this.do=null,this.fo=null,this.da=dn,this.vo=ln(null),this.po=t,this._n=i,this.mo=n,this.bo=s,this.wo=new on(this,100,this.Mo.bind(this),this.xo.bind(this))}xa(){return this.po}W(){return this._n}Lh(t){if(C(this._n,t),this.Sa(),void 0!==t.mode&&this.So({Sr:t.mode}),void 0!==t.scaleMargins){const i=d(t.scaleMargins.top),n=d(t.scaleMargins.bottom);if(i<0||i>1)throw new Error(`Invalid top margin - expect value between 0 and 1, given=${i}`);if(n<0||n>1)throw new Error(`Invalid bottom margin - expect value between 0 and 1, given=${n}`);if(i+n>1)throw new Error(`Invalid margins - sum of margins must be less than 1, given=${i+n}`);this.yo(),this.co=null}}ko(){return this._n.autoScale}Ja(){return 1===this._n.mode}fh(){return 2===this._n.mode}Co(){return 3===this._n.mode}Sr(){return{Nn:this._n.autoScale,To:this._n.invertScale,Sr:this._n.mode}}So(t){const i=this.Sr();let n=null;void 0!==t.Nn&&(this._n.autoScale=t.Nn),void 0!==t.Sr&&(this._n.mode=t.Sr,2!==t.Sr&&3!==t.Sr||(this._n.autoScale=!0),this.so.eo=!1),1===i.Sr&&t.Sr!==i.Sr&&(!function(t,i){if(null===t)return!1;const n=en(t.xh(),i),s=en(t.Sh(),i);return isFinite(n)&&isFinite(s)}(this.Rh,this.vo)?this._n.autoScale=!0:(n=hn(this.Rh,this.vo),null!==n&&this.Po(n))),1===t.Sr&&t.Sr!==i.Sr&&(n=rn(this.Rh,this.vo),null!==n&&this.Po(n));const s=i.Sr!==this._n.mode;s&&(2===i.Sr||this.fh())&&this.Sa(),s&&(3===i.Sr||this.Co())&&this.Sa(),void 0!==t.To&&i.To!==t.To&&(this._n.invertScale=t.To,this.Ro()),this.oo.m(i,this.Sr())}Do(){return this.oo}P(){return this.mo.fontSize}Vt(){return this.Qa}Oo(t){this.Qa!==t&&(this.Qa=t,this.yo(),this.co=null)}Ao(){if(this.io)return this.io;const t=this.Vt()-this.Bo()-this.Vo();return this.io=t,t}Oh(){return this.zo(),this.Rh}Po(t,i){const n=this.Rh;(i||null===n&&null!==t||null!==n&&!n.gh(t))&&(this.co=null,this.Rh=t)}Li(){return this.zo(),0===this.Qa||!this.Rh||this.Rh.Li()}Eo(t){return this.To()?t:this.Vt()-1-t}Rt(t,i){return this.fh()?t=Ji(t,i):this.Co()&&(t=tn(t,i)),this.xo(t,i)}Gs(t,i,n){this.zo();const s=this.Vo(),e=f(this.Oh()),r=e.xh(),h=e.Sh(),l=this.Ao()-1,a=this.To(),o=l/(h-r),_=void 0===n?0:n.from,u=void 0===n?t.length:n.to,c=this.Io();for(let n=_;nt.Rn()))}Sa(){this.co=null;const t=this.Jo();let i=100;null!==t&&(i=Math.round(1/t.ua())),this.da=dn,this.fh()?(this.da=cn,i=100):this.Co()?(this.da=new _t(100,1),i=100):null!==t&&(this.da=t.ca()),this.wo=new on(this,i,this.Mo.bind(this),this.xo.bind(this)),this.wo.Xa()}Wo(){this.uo=null}Jo(){return this._o[0]||null}Bo(){return this.To()?this._n.scaleMargins.bottom*this.Vt()+this.lo:this._n.scaleMargins.top*this.Vt()+this.ho}Vo(){return this.To()?this._n.scaleMargins.top*this.Vt()+this.ho:this._n.scaleMargins.bottom*this.Vt()+this.lo}zo(){this.so.eo||(this.so.eo=!0,this.i_())}yo(){this.io=null}xo(t,i){if(this.zo(),this.Li())return 0;t=this.Ja()&&t?sn(t,this.vo):t;const n=f(this.Oh()),s=this.Vo()+(this.Ao()-1)*(t-n.xh())/n.yh();return this.Eo(s)}Mo(t,i){if(this.zo(),this.Li())return 0;const n=this.Eo(t),s=f(this.Oh()),e=s.xh()+s.yh()*((n-this.Vo())/(this.Ao()-1));return this.Ja()?en(e,this.vo):e}Ro(){this.co=null,this.wo.Xa()}i_(){const t=this.so.ro;if(null===t)return;let i=null;const n=this.Qo();let s=0,e=0;for(const r of n){if(!r.kt())continue;const n=r.Ct();if(null===n)continue;const h=r.Rl(t.Rs(),t.ui());let l=h&&h.Oh();if(null!==l){switch(this._n.mode){case 1:l=rn(l,this.vo);break;case 2:l=Qi(l,n.Ot);break;case 3:l=nn(l,n.Ot)}if(i=null===i?l:i.Jn(f(l)),null!==h){const t=h.Ah();null!==t&&(s=Math.max(s,t.above),e=Math.max(s,t.below))}}}if(s===this.ho&&e===this.lo||(this.ho=s,this.lo=e,this.co=null,this.yo()),null!==i){if(i.xh()===i.Sh()){const t=this.Jo(),n=5*(null===t||this.fh()||this.Co()?1:t.ua());this.Ja()&&(i=hn(i,this.vo)),i=new yi(i.xh()-n,i.Sh()+n),this.Ja()&&(i=rn(i,this.vo))}if(this.Ja()){const t=hn(i,this.vo),n=ln(t);if(r=n,h=this.vo,r.La!==h.La||r.Na!==h.Na){const s=null!==this.no?hn(this.no,this.vo):null;this.vo=n,i=rn(t,n),null!==s&&(this.no=rn(s,n))}}this.Po(i)}else null===this.Rh&&(this.Po(new yi(-.5,.5)),this.vo=ln(null));var r,h;this.so.eo=!0}Io(){return this.fh()?Ji:this.Co()?tn:this.Ja()?t=>sn(t,this.vo):null}n_(t,i,n){return void 0===i?(void 0===n&&(n=this.ca()),n.format(t)):i(t)}zh(t,i){return this.n_(t,this.bo.priceFormatter,i)}Go(t,i){return this.n_(t,this.bo.percentageFormatter,i)}}class vn{constructor(t,i){this._o=[],this.s_=new Map,this.Qa=0,this.e_=0,this.r_=1e3,this.uo=null,this.h_=new k,this.wl=t,this.Hi=i,this.l_=new Zi(this);const n=i.W();this.a_=this.o_("left",n.leftPriceScale),this.__=this.o_("right",n.rightPriceScale),this.a_.Do().l(this.u_.bind(this,this.a_),this),this.__.Do().l(this.u_.bind(this,this.__),this),this.c_(n)}c_(t){if(t.leftPriceScale&&this.a_.Lh(t.leftPriceScale),t.rightPriceScale&&this.__.Lh(t.rightPriceScale),t.localization&&(this.a_.Sa(),this.__.Sa()),t.overlayPriceScales){const i=Array.from(this.s_.values());for(const n of i){const i=f(n[0].Dt());i.Lh(t.overlayPriceScales),t.localization&&i.Sa()}}}d_(t){switch(t){case"left":return this.a_;case"right":return this.__}return this.s_.has(t)?d(this.s_.get(t))[0].Dt():null}S(){this.$t().f_().p(this),this.a_.Do().p(this),this.__.Do().p(this),this._o.forEach((t=>{t.S&&t.S()})),this.h_.m()}v_(){return this.r_}p_(t){this.r_=t}$t(){return this.Hi}ji(){return this.e_}Vt(){return this.Qa}m_(t){this.e_=t,this.b_()}Oo(t){this.Qa=t,this.a_.Oo(t),this.__.Oo(t),this._o.forEach((i=>{if(this.ur(i)){const n=i.Dt();null!==n&&n.Oo(t)}})),this.b_()}Ta(){return this._o}ur(t){const i=t.Dt();return null===i||this.a_!==i&&this.__!==i}Fo(t,i,n){const s=void 0!==n?n:this.g_().w_+1;this.M_(t,i,s)}jo(t){const i=this._o.indexOf(t);c(-1!==i,"removeDataSource: invalid data source"),this._o.splice(i,1);const n=f(t.Dt()).xa();if(this.s_.has(n)){const i=d(this.s_.get(n)),s=i.indexOf(t);-1!==s&&(i.splice(s,1),0===i.length&&this.s_.delete(n))}const s=t.Dt();s&&s.Ta().indexOf(t)>=0&&s.jo(t),null!==s&&(s.Wo(),this.x_(s)),this.uo=null}dr(t){return t===this.a_?"left":t===this.__?"right":"overlay"}S_(){return this.a_}y_(){return this.__}k_(t,i){t.Uo(i)}C_(t,i){t.qo(i),this.b_()}T_(t){t.Yo()}P_(t,i){t.Xo(i)}R_(t,i){t.Ko(i),this.b_()}D_(t){t.Zo()}b_(){this._o.forEach((t=>{t.Rn()}))}dn(){let t=null;return this.Hi.W().rightPriceScale.visible&&0!==this.__.Ta().length?t=this.__:this.Hi.W().leftPriceScale.visible&&0!==this.a_.Ta().length?t=this.a_:0!==this._o.length&&(t=this._o[0].Dt()),null===t&&(t=this.__),t}cr(){let t=null;return this.Hi.W().rightPriceScale.visible?t=this.__:this.Hi.W().leftPriceScale.visible&&(t=this.a_),t}x_(t){null!==t&&t.ko()&&this.O_(t)}A_(t){const i=this.wl.qs();t.So({Nn:!0}),null!==i&&t.t_(i),this.b_()}B_(){this.O_(this.a_),this.O_(this.__)}V_(){this.x_(this.a_),this.x_(this.__),this._o.forEach((t=>{this.ur(t)&&this.x_(t.Dt())})),this.b_(),this.Hi.Nh()}No(){return null===this.uo&&(this.uo=_n(this._o)),this.uo}z_(){return this.h_}E_(){return this.l_}O_(t){const i=t.Qo();if(i&&i.length>0&&!this.wl.Li()){const i=this.wl.qs();null!==i&&t.t_(i)}t.Rn()}g_(){const t=this.No();if(0===t.length)return{I_:0,w_:0};let i=0,n=0;for(let s=0;sn&&(n=e))}return{I_:i,w_:n}}M_(t,i,n){let s=this.d_(i);if(null===s&&(s=this.o_(i,this.Hi.W().overlayPriceScales)),this._o.push(t),!ht(i)){const n=this.s_.get(i)||[];n.push(t),this.s_.set(i,n)}s.Fo(t),t.Zi(s),t.Ki(n),this.x_(s),this.uo=null}u_(t,i,n){i.Sr!==n.Sr&&this.O_(t)}o_(t,i){const n=Object.assign({visible:!0,autoScale:!0},O(i)),s=new fn(t,n,this.Hi.W().layout,this.Hi.W().localization);return s.Oo(this.Vt()),s}}class pn{constructor(t,i,n=50){this.Ye=0,this.Xe=1,this.Ke=1,this.Ge=new Map,this.Ze=new Map,this.L_=t,this.N_=i,this.Je=n}F_(t){const i=t.time,n=this.N_.cacheKey(i),s=this.Ge.get(n);if(void 0!==s)return s.W_;if(this.Ye===this.Je){const t=this.Ze.get(this.Ke);this.Ze.delete(this.Ke),this.Ge.delete(d(t)),this.Ke++,this.Ye--}const e=this.L_(t);return this.Ge.set(n,{W_:e,nr:this.Xe}),this.Ze.set(this.Xe,n),this.Ye++,this.Xe++,e}}class mn{constructor(t,i){c(t<=i,"right should be >= left"),this.j_=t,this.H_=i}Rs(){return this.j_}ui(){return this.H_}U_(){return this.H_-this.j_+1}Yr(t){return this.j_<=t&&t<=this.H_}gh(t){return this.j_===t.Rs()&&this.H_===t.ui()}}function bn(t,i){return null===t||null===i?t===i:t.gh(i)}class wn{constructor(){this.q_=new Map,this.Ge=null,this.Y_=!1}X_(t){this.Y_=t,this.Ge=null}K_(t,i){this.Z_(i),this.Ge=null;for(let n=i;n{t<=n[0].index?i.push(s):n.splice(Rt(n,t,(i=>i.indexi-t))){if(!this.q_.get(n))continue;const s=i;i=[];const e=s.length;let r=0;const h=d(this.q_.get(n)),l=h.length;let a=1/0,o=-1/0;for(let n=0;n=t&&_-o>=t)i.push(l),o=_;else if(this.Y_)return s}for(;ri.weight?t:i}class xn{constructor(t,i,n,s){this.e_=0,this.eu=null,this.ru=[],this.fo=null,this.do=null,this.hu=new wn,this.lu=new Map,this.au=gn.su(),this.ou=!0,this._u=new k,this.uu=new k,this.cu=new k,this.du=null,this.fu=null,this.vu=[],this._n=i,this.bo=n,this.pu=i.rightOffset,this.mu=i.barSpacing,this.Hi=t,this.N_=s,this.bu(),this.hu.X_(i.uniformDistribution)}W(){return this._n}wu(t){C(this.bo,t),this.gu(),this.bu()}Lh(t,i){var n;C(this._n,t),this._n.fixLeftEdge&&this.Mu(),this._n.fixRightEdge&&this.xu(),void 0!==t.barSpacing&&this.Hi.Kn(t.barSpacing),void 0!==t.rightOffset&&this.Hi.Zn(t.rightOffset),void 0!==t.minBarSpacing&&this.Hi.Kn(null!==(n=t.barSpacing)&&void 0!==n?n:this.mu),this.gu(),this.bu(),this.cu.m()}vn(t){var i,n;return null!==(n=null===(i=this.ru[t])||void 0===i?void 0:i.time)&&void 0!==n?n:null}$i(t){var i;return null!==(i=this.ru[t])&&void 0!==i?i:null}ka(t,i){if(this.ru.length<1)return null;if(this.N_.key(t)>this.N_.key(this.ru[this.ru.length-1].time))return i?this.ru.length-1:null;const n=Rt(this.ru,this.N_.key(t),((t,i)=>this.N_.key(t.time)0}qs(){return this.Su(),this.au.iu()}yu(){return this.Su(),this.au.nu()}ku(){const t=this.qs();if(null===t)return null;const i={from:t.Rs(),to:t.ui()};return this.Cu(i)}Cu(t){const i=Math.round(t.from),n=Math.round(t.to),s=f(this.Tu()),e=f(this.Pu());return{from:f(this.$i(Math.max(s,i))),to:f(this.$i(Math.min(e,n)))}}Ru(t){return{from:f(this.ka(t.from,!0)),to:f(this.ka(t.to,!0))}}ji(){return this.e_}m_(t){if(!isFinite(t)||t<=0)return;if(this.e_===t)return;const i=this.yu(),n=this.e_;if(this.e_=t,this.ou=!0,this._n.lockVisibleTimeRangeOnResize&&0!==n){const i=this.mu*t/n;this.mu=i}if(this._n.fixLeftEdge&&null!==i&&i.Rs()<=0){const i=n-t;this.pu-=Math.round(i/this.mu)+1,this.ou=!0}this.Du(),this.Ou()}zt(t){if(this.Li()||!P(t))return 0;const i=this.Au()+this.pu-t;return this.e_-(i+.5)*this.mu-1}Zs(t,i){const n=this.Au(),s=void 0===i?0:i.from,e=void 0===i?t.length:i.to;for(let i=s;ii/2&&!o?n.needAlignCoordinate=!1:n.needAlignCoordinate=_&&t.index<=l||u&&t.index>=a,c++}return this.vu.length=c,this.fu=this.vu,this.vu}Fu(){this.ou=!0,this.Kn(this._n.barSpacing),this.Zn(this._n.rightOffset)}Wu(t){this.ou=!0,this.eu=t,this.Ou(),this.Mu()}ju(t,i){const n=this.Vu(t),s=this.ee(),e=s+i*(s/10);this.Kn(e),this._n.rightBarStaysOnScroll||this.Zn(this.Iu()+(n-this.Vu(t)))}Uo(t){this.fo&&this.Zo(),null===this.do&&null===this.du&&(this.Li()||(this.do=t,this.Hu()))}qo(t){if(null===this.du)return;const i=gt(this.e_-t,0,this.e_),n=gt(this.e_-f(this.do),0,this.e_);0!==i&&0!==n&&this.Kn(this.du.ee*i/n)}Yo(){null!==this.do&&(this.do=null,this.$u())}Xo(t){null===this.fo&&null===this.du&&(this.Li()||(this.fo=t,this.Hu()))}Ko(t){if(null===this.fo)return;const i=(this.fo-t)/this.ee();this.pu=f(this.du).Iu+i,this.ou=!0,this.Ou()}Zo(){null!==this.fo&&(this.fo=null,this.$u())}Uu(){this.qu(this._n.rightOffset)}qu(t,i=400){if(!isFinite(t))throw new RangeError("offset is required and must be finite number");if(!isFinite(i)||i<=0)throw new RangeError("animationDuration (optional) must be finite positive number");const n=this.pu,s=performance.now();this.Hi.qn({Yu:t=>(t-s)/i>=1,Xu:e=>{const r=(e-s)/i;return r>=1?t:n+(t-n)*r}})}bt(t,i){this.ou=!0,this.ru=t,this.hu.K_(t,i),this.Ou()}Ku(){return this._u}Zu(){return this.uu}Gu(){return this.cu}Au(){return this.eu||0}Ju(t){const i=t.U_();this.Eu(this.e_/i),this.pu=t.ui()-this.Au(),this.Ou(),this.ou=!0,this.Hi.zu(),this.Hi.Nh()}Qu(){const t=this.Tu(),i=this.Pu();null!==t&&null!==i&&this.Ju(new mn(t,i+this._n.rightOffset))}tc(t){const i=new mn(t.from,t.to);this.Ju(i)}Ui(t){return void 0!==this.bo.timeFormatter?this.bo.timeFormatter(t.originalTime):this.N_.formatHorzItem(t.time)}Lu(){const{handleScroll:t,handleScale:i}=this.Hi.W();return!(t.horzTouchDrag||t.mouseWheel||t.pressedMouseMove||t.vertTouchDrag||i.axisDoubleClickReset.time||i.axisPressedMouseMove.time||i.mouseWheel||i.pinch)}Tu(){return 0===this.ru.length?null:0}Pu(){return 0===this.ru.length?null:this.ru.length-1}ic(t){return(this.e_-1-t)/this.mu}Vu(t){const i=this.ic(t),n=this.Au()+this.pu-i;return Math.round(1e6*n)/1e6}Eu(t){const i=this.mu;this.mu=t,this.Du(),i!==this.mu&&(this.ou=!0,this.nc())}Su(){if(!this.ou)return;if(this.ou=!1,this.Li())return void this.sc(gn.su());const t=this.Au(),i=this.e_/this.mu,n=this.pu+t,s=new mn(n-i+1,n);this.sc(new gn(s))}Du(){const t=this.ec();if(this.mut&&(this.mu=t,this.ou=!0)}}ec(){return this._n.fixLeftEdge&&this._n.fixRightEdge&&0!==this.ru.length?this.e_/this.ru.length:this._n.minBarSpacing}Ou(){const t=this.rc();this.pu>t&&(this.pu=t,this.ou=!0);const i=this.hc();null!==i&&this.puthis.lc(t)),this.N_),this.lu.set(t.weight,i)),i.F_(t)}lc(t){return this.N_.formatTickmark(t,this.bo)}sc(t){const i=this.au;this.au=t,bn(i.iu(),this.au.iu())||this._u.m(),bn(i.nu(),this.au.nu())||this.uu.m(),this.nc()}nc(){this.fu=null}gu(){this.nc(),this.lu.clear()}bu(){this.N_.updateFormatter(this.bo)}Mu(){if(!this._n.fixLeftEdge)return;const t=this.Tu();if(null===t)return;const i=this.qs();if(null===i)return;const n=i.Rs()-t;if(n<0){const t=this.pu-n-1;this.Zn(t)}this.Du()}xu(){this.Ou(),this.Du()}}class Sn{K(t,i,n){t.useMediaCoordinateSpace((t=>this.Z(t,i,n)))}fl(t,i,n){t.useMediaCoordinateSpace((t=>this.ac(t,i,n)))}ac(t,i,n){}}class yn extends Sn{constructor(t){super(),this.oc=new Map,this.Et=t}Z(t){}ac(t){if(!this.Et.kt)return;const{context:i,mediaSize:n}=t;let s=0;for(const t of this.Et._c){if(0===t.Zt.length)continue;i.font=t.R;const e=this.uc(i,t.Zt);e>n.width?t.ju=n.width/e:t.ju=1,s+=t.cc*t.ju}let e=0;switch(this.Et.dc){case"top":e=0;break;case"center":e=Math.max((n.height-s)/2,0);break;case"bottom":e=Math.max(n.height-s,0)}i.fillStyle=this.Et.O;for(const t of this.Et._c){i.save();let s=0;switch(this.Et.fc){case"left":i.textAlign="left",s=t.cc/2;break;case"center":i.textAlign="center",s=n.width/2;break;case"right":i.textAlign="right",s=n.width-1-t.cc/2}i.translate(s,e),i.textBaseline="top",i.font=t.R,i.scale(t.ju,t.ju),i.fillText(t.Zt,0,t.vc),i.restore(),e+=t.cc*t.ju}}uc(t,i){const n=this.mc(t.font);let s=n.get(i);return void 0===s&&(s=t.measureText(i).width,n.set(i,s)),s}mc(t){let i=this.oc.get(t);return void 0===i&&(i=new Map,this.oc.set(t,i)),i}}class kn{constructor(t){this.ft=!0,this.Ft={kt:!1,O:"",_c:[],dc:"center",fc:"center"},this.Wt=new yn(this.Ft),this.jt=t}bt(){this.ft=!0}gt(){return this.ft&&(this.Mt(),this.ft=!1),this.Wt}Mt(){const t=this.jt.W(),i=this.Ft;i.kt=t.visible,i.kt&&(i.O=t.color,i.fc=t.horzAlign,i.dc=t.vertAlign,i._c=[{Zt:t.text,R:z(t.fontSize,t.fontFamily,t.fontStyle),cc:1.2*t.fontSize,vc:0,ju:0}])}}class Cn extends st{constructor(t,i){super(),this._n=i,this.mn=new kn(this)}Tn(){return[]}Cn(){return[this.mn]}W(){return this._n}Rn(){this.mn.bt()}}var Tn,Pn,Rn,Dn,On;!function(t){t[t.OnTouchEnd=0]="OnTouchEnd",t[t.OnNextTap=1]="OnNextTap"}(Tn||(Tn={}));class An{constructor(t,i,n){this.bc=[],this.wc=[],this.e_=0,this.gc=null,this.Mc=new k,this.xc=new k,this.Sc=null,this.yc=t,this._n=i,this.N_=n,this.kc=new E(this),this.wl=new xn(this,i.timeScale,this._n.localization,n),this.vt=new rt(this,i.crosshair),this.Cc=new Yi(i.crosshair),this.Tc=new Cn(this,i.watermark),this.Pc(),this.bc[0].p_(2e3),this.Rc=this.Dc(0),this.Oc=this.Dc(1)}$l(){this.Ac(lt.ns())}Nh(){this.Ac(lt.ts())}sa(){this.Ac(new lt(1))}Ul(t){const i=this.Bc(t);this.Ac(i)}Vc(){return this.gc}zc(t){const i=this.gc;this.gc=t,null!==i&&this.Ul(i.Ec),null!==t&&this.Ul(t.Ec)}W(){return this._n}Lh(t){C(this._n,t),this.bc.forEach((i=>i.c_(t))),void 0!==t.timeScale&&this.wl.Lh(t.timeScale),void 0!==t.localization&&this.wl.wu(t.localization),(t.leftPriceScale||t.rightPriceScale)&&this.Mc.m(),this.Rc=this.Dc(0),this.Oc=this.Dc(1),this.$l()}Ic(t,i){if("left"===t)return void this.Lh({leftPriceScale:i});if("right"===t)return void this.Lh({rightPriceScale:i});const n=this.Lc(t);null!==n&&(n.Dt.Lh(i),this.Mc.m())}Lc(t){for(const i of this.bc){const n=i.d_(t);if(null!==n)return{Ht:i,Dt:n}}return null}St(){return this.wl}Nc(){return this.bc}Fc(){return this.Tc}Wc(){return this.vt}jc(){return this.xc}Hc(t,i){t.Oo(i),this.zu()}m_(t){this.e_=t,this.wl.m_(this.e_),this.bc.forEach((i=>i.m_(t))),this.zu()}Pc(t){const i=new vn(this.wl,this);void 0!==t?this.bc.splice(t,0,i):this.bc.push(i);const n=void 0===t?this.bc.length-1:t,s=lt.ns();return s.In(n,{Ln:0,Nn:!0}),this.Ac(s),i}k_(t,i,n){t.k_(i,n)}C_(t,i,n){t.C_(i,n),this.ql(),this.Ac(this.$c(t,2))}T_(t,i){t.T_(i),this.Ac(this.$c(t,2))}P_(t,i,n){i.ko()||t.P_(i,n)}R_(t,i,n){i.ko()||(t.R_(i,n),this.ql(),this.Ac(this.$c(t,2)))}D_(t,i){i.ko()||(t.D_(i),this.Ac(this.$c(t,2)))}A_(t,i){t.A_(i),this.Ac(this.$c(t,2))}Uc(t){this.wl.Uo(t)}qc(t,i){const n=this.St();if(n.Li()||0===i)return;const s=n.ji();t=Math.max(1,Math.min(t,s)),n.ju(t,i),this.zu()}Yc(t){this.Xc(0),this.Kc(t),this.Zc()}Gc(t){this.wl.qo(t),this.zu()}Jc(){this.wl.Yo(),this.Nh()}Xc(t){this.wl.Xo(t)}Kc(t){this.wl.Ko(t),this.zu()}Zc(){this.wl.Zo(),this.Nh()}wt(){return this.wc}Qc(t,i,n,s,e){this.vt.bn(t,i);let r=NaN,h=this.wl.Bu(t);const l=this.wl.qs();null!==l&&(h=Math.min(Math.max(l.Rs(),h),l.ui()));const a=s.dn(),o=a.Ct();null!==o&&(r=a.fn(i,o)),r=this.Cc.Ca(r,h,s),this.vt.xn(h,r,s),this.sa(),e||this.xc.m(this.vt.xt(),{x:t,y:i},n)}td(t,i,n){const s=n.dn(),e=s.Ct(),r=s.Rt(t,f(e)),h=this.wl.ka(i,!0),l=this.wl.zt(f(h));this.Qc(l,r,null,n,!0)}nd(t){this.Wc().yn(),this.sa(),t||this.xc.m(null,null,null)}ql(){const t=this.vt.Ht();if(null!==t){const i=this.vt.gn(),n=this.vt.Mn();this.Qc(i,n,null,t)}this.vt.Rn()}sd(t,i,n){const s=this.wl.vn(0);void 0!==i&&void 0!==n&&this.wl.bt(i,n);const e=this.wl.vn(0),r=this.wl.Au(),h=this.wl.qs();if(null!==h&&null!==s&&null!==e){const i=h.Yr(r),l=this.N_.key(s)>this.N_.key(e),a=null!==t&&t>r&&!l,o=this.wl.W().allowShiftVisibleRangeOnWhitespaceReplacement,_=i&&(!(void 0===n)||o)&&this.wl.W().shiftVisibleRangeOnNewBar;if(a&&!_){const i=t-r;this.wl.Zn(this.wl.Iu()-i)}}this.wl.Wu(t)}Kl(t){null!==t&&t.V_()}_r(t){const i=this.bc.find((i=>i.No().includes(t)));return void 0===i?null:i}zu(){this.Tc.Rn(),this.bc.forEach((t=>t.V_())),this.ql()}S(){this.bc.forEach((t=>t.S())),this.bc.length=0,this._n.localization.priceFormatter=void 0,this._n.localization.percentageFormatter=void 0,this._n.localization.timeFormatter=void 0}ed(){return this.kc}vr(){return this.kc.W()}f_(){return this.Mc}rd(t,i,n){const s=this.bc[0],e=this.hd(i,t,s,n);return this.wc.push(e),1===this.wc.length?this.$l():this.Nh(),e}ld(t){const i=this._r(t),n=this.wc.indexOf(t);c(-1!==n,"Series not found"),this.wc.splice(n,1),f(i).jo(t),t.S&&t.S()}Hl(t,i){const n=f(this._r(t));n.jo(t);const s=this.Lc(i);if(null===s){const s=t.Xi();n.Fo(t,i,s)}else{const e=s.Ht===n?t.Xi():void 0;s.Ht.Fo(t,i,e)}}Qu(){const t=lt.ts();t.jn(),this.Ac(t)}ad(t){const i=lt.ts();i.Un(t),this.Ac(i)}Xn(){const t=lt.ts();t.Xn(),this.Ac(t)}Kn(t){const i=lt.ts();i.Kn(t),this.Ac(i)}Zn(t){const i=lt.ts();i.Zn(t),this.Ac(i)}qn(t){const i=lt.ts();i.qn(t),this.Ac(i)}Hn(){const t=lt.ts();t.Hn(),this.Ac(t)}od(){return this._n.rightPriceScale.visible?"right":"left"}_d(){return this.Oc}q(){return this.Rc}Bt(t){const i=this.Oc,n=this.Rc;if(i===n)return i;if(t=Math.max(0,Math.min(100,Math.round(100*t))),null===this.Sc||this.Sc.ks!==n||this.Sc.Cs!==i)this.Sc={ks:n,Cs:i,ud:new Map};else{const i=this.Sc.ud.get(t);if(void 0!==i)return i}const s=function(t,i,n){const[s,e,r,h]=S(t),[l,a,o,_]=S(i),u=[m(s+n*(l-s)),m(e+n*(a-e)),m(r+n*(o-r)),b(h+n*(_-h))];return`rgba(${u[0]}, ${u[1]}, ${u[2]}, ${u[3]})`}(n,i,t/100);return this.Sc.ud.set(t,s),s}$c(t,i){const n=new lt(i);if(null!==t){const s=this.bc.indexOf(t);n.In(s,{Ln:i})}return n}Bc(t,i){return void 0===i&&(i=2),this.$c(this._r(t),i)}Ac(t){this.yc&&this.yc(t),this.bc.forEach((t=>t.E_().Fh().bt()))}hd(t,i,n,s){const e=new qi(this,t,i,n,s),r=void 0!==t.priceScaleId?t.priceScaleId:this.od();return n.Fo(e,r),ht(r)||e.Lh(t),e}Dc(t){const i=this._n.layout;return"gradient"===i.background.type?0===t?i.background.topColor:i.background.bottomColor:i.background.color}}function Bn(t){return!T(t)&&!R(t)}function Vn(t){return T(t)}!function(t){t[t.Disabled=0]="Disabled",t[t.Continuous=1]="Continuous",t[t.OnDataUpdate=2]="OnDataUpdate"}(Pn||(Pn={})),function(t){t[t.LastBar=0]="LastBar",t[t.LastVisible=1]="LastVisible"}(Rn||(Rn={})),function(t){t.Solid="solid",t.VerticalGradient="gradient"}(Dn||(Dn={})),function(t){t[t.Year=0]="Year",t[t.Month=1]="Month",t[t.DayOfMonth=2]="DayOfMonth",t[t.Time=3]="Time",t[t.TimeWithSeconds=4]="TimeWithSeconds"}(On||(On={}));const zn=t=>t.getUTCFullYear();function En(t,i,n){return i.replace(/yyyy/g,(t=>ot(zn(t),4))(t)).replace(/yy/g,(t=>ot(zn(t)%100,2))(t)).replace(/MMMM/g,((t,i)=>new Date(t.getUTCFullYear(),t.getUTCMonth(),1).toLocaleString(i,{month:"long"}))(t,n)).replace(/MMM/g,((t,i)=>new Date(t.getUTCFullYear(),t.getUTCMonth(),1).toLocaleString(i,{month:"short"}))(t,n)).replace(/MM/g,(t=>ot((t=>t.getUTCMonth()+1)(t),2))(t)).replace(/dd/g,(t=>ot((t=>t.getUTCDate())(t),2))(t))}class In{constructor(t="yyyy-MM-dd",i="default"){this.dd=t,this.fd=i}F_(t){return En(t,this.dd,this.fd)}}class Ln{constructor(t){this.vd=t||"%h:%m:%s"}F_(t){return this.vd.replace("%h",ot(t.getUTCHours(),2)).replace("%m",ot(t.getUTCMinutes(),2)).replace("%s",ot(t.getUTCSeconds(),2))}}const Nn={pd:"yyyy-MM-dd",md:"%h:%m:%s",bd:" ",wd:"default"};class Fn{constructor(t={}){const i=Object.assign(Object.assign({},Nn),t);this.gd=new In(i.pd,i.wd),this.Md=new Ln(i.md),this.xd=i.bd}F_(t){return`${this.gd.F_(t)}${this.xd}${this.Md.F_(t)}`}}function Wn(t){return 60*t*60*1e3}function jn(t){return 60*t*1e3}const Hn=[{Sd:($n=1,1e3*$n),yd:10},{Sd:jn(1),yd:20},{Sd:jn(5),yd:21},{Sd:jn(30),yd:22},{Sd:Wn(1),yd:30},{Sd:Wn(3),yd:31},{Sd:Wn(6),yd:32},{Sd:Wn(12),yd:33}];var $n;function Un(t,i){if(t.getUTCFullYear()!==i.getUTCFullYear())return 70;if(t.getUTCMonth()!==i.getUTCMonth())return 60;if(t.getUTCDate()!==i.getUTCDate())return 50;for(let n=Hn.length-1;n>=0;--n)if(Math.floor(i.getTime()/Hn[n].Sd)!==Math.floor(t.getTime()/Hn[n].Sd))return Hn[n].yd;return 0}function qn(t){let i=t;if(R(t)&&(i=Xn(t)),!Bn(i))throw new Error("time must be of type BusinessDay");const n=new Date(Date.UTC(i.year,i.month-1,i.day,0,0,0,0));return{kd:Math.round(n.getTime()/1e3),Cd:i}}function Yn(t){if(!Vn(t))throw new Error("time must be of type isUTCTimestamp");return{kd:t}}function Xn(t){const i=new Date(t);if(isNaN(i.getTime()))throw new Error(`Invalid date string=${t}, expected format=yyyy-mm-dd`);return{day:i.getUTCDate(),month:i.getUTCMonth()+1,year:i.getUTCFullYear()}}function Kn(t){R(t.time)&&(t.time=Xn(t.time))}class Zn{options(){return this._n}setOptions(t){this._n=t,this.updateFormatter(t.localization)}preprocessData(t){Array.isArray(t)?function(t){t.forEach(Kn)}(t):Kn(t)}createConverterToInternalObj(t){return f(function(t){return 0===t.length?null:Bn(t[0].time)||R(t[0].time)?qn:Yn}(t))}key(t){return"object"==typeof t&&"kd"in t?t.kd:this.key(this.convertHorzItemToInternal(t))}cacheKey(t){const i=t;return void 0===i.Cd?new Date(1e3*i.kd).getTime():new Date(Date.UTC(i.Cd.year,i.Cd.month-1,i.Cd.day)).getTime()}convertHorzItemToInternal(t){return Vn(i=t)?Yn(i):Bn(i)?qn(i):qn(Xn(i));var i}updateFormatter(t){if(!this._n)return;const i=t.dateFormat;this._n.timeScale.timeVisible?this.Td=new Fn({pd:i,md:this._n.timeScale.secondsVisible?"%h:%m:%s":"%h:%m",bd:" ",wd:t.locale}):this.Td=new In(i,t.locale)}formatHorzItem(t){const i=t;return this.Td.F_(new Date(1e3*i.kd))}formatTickmark(t,i){const n=function(t,i,n){switch(t){case 0:case 10:return i?n?4:3:2;case 20:case 21:case 22:case 30:case 31:case 32:case 33:return i?3:2;case 50:return 2;case 60:return 1;case 70:return 0}}(t.weight,this._n.timeScale.timeVisible,this._n.timeScale.secondsVisible),s=this._n.timeScale;if(void 0!==s.tickMarkFormatter){const e=s.tickMarkFormatter(t.originalTime,n,i.locale);if(null!==e)return e}return function(t,i,n){const s={};switch(i){case 0:s.year="numeric";break;case 1:s.month="short";break;case 2:s.day="numeric";break;case 3:s.hour12=!1,s.hour="2-digit",s.minute="2-digit";break;case 4:s.hour12=!1,s.hour="2-digit",s.minute="2-digit",s.second="2-digit"}const e=void 0===t.Cd?new Date(1e3*t.kd):new Date(Date.UTC(t.Cd.year,t.Cd.month-1,t.Cd.day));return new Date(e.getUTCFullYear(),e.getUTCMonth(),e.getUTCDate(),e.getUTCHours(),e.getUTCMinutes(),e.getUTCSeconds(),e.getUTCMilliseconds()).toLocaleString(n,s)}(t.time,n,i.locale)}maxTickMarkWeight(t){let i=t.reduce(Mn,t[0]).weight;return i>30&&i<50&&(i=30),i}fillWeightsForPoints(t,i){!function(t,i=0){if(0===t.length)return;let n=0===i?null:t[i-1].time.kd,s=null!==n?new Date(1e3*n):null,e=0;for(let r=i;r1){const i=Math.ceil(e/(t.length-1)),n=new Date(1e3*(t[0].time.kd-i));t[0].timeWeight=Un(new Date(1e3*t[0].time.kd),n)}}(t,i)}static Pd(t){return C({localization:{dateFormat:"dd MMM 'yy"}},null!=t?t:{})}}function Gn(t){var i=t.width,n=t.height;if(i<0)throw new Error("Negative width is not allowed for Size");if(n<0)throw new Error("Negative height is not allowed for Size");return{width:i,height:n}}function Jn(t,i){return t.width===i.width&&t.height===i.height}var Qn=function(){function t(t){var i=this;this._resolutionListener=function(){return i._onResolutionChanged()},this._resolutionMediaQueryList=null,this._observers=[],this._window=t,this._installResolutionListener()}return t.prototype.dispose=function(){this._uninstallResolutionListener(),this._window=null},Object.defineProperty(t.prototype,"value",{get:function(){return this._window.devicePixelRatio},enumerable:!1,configurable:!0}),t.prototype.subscribe=function(t){var i=this,n={next:t};return this._observers.push(n),{unsubscribe:function(){i._observers=i._observers.filter((function(t){return t!==n}))}}},t.prototype._installResolutionListener=function(){if(null!==this._resolutionMediaQueryList)throw new Error("Resolution listener is already installed");var t=this._window.devicePixelRatio;this._resolutionMediaQueryList=this._window.matchMedia("all and (resolution: ".concat(t,"dppx)")),this._resolutionMediaQueryList.addListener(this._resolutionListener)},t.prototype._uninstallResolutionListener=function(){null!==this._resolutionMediaQueryList&&(this._resolutionMediaQueryList.removeListener(this._resolutionListener),this._resolutionMediaQueryList=null)},t.prototype._reinstallResolutionListener=function(){this._uninstallResolutionListener(),this._installResolutionListener()},t.prototype._onResolutionChanged=function(){var t=this;this._observers.forEach((function(i){return i.next(t._window.devicePixelRatio)})),this._reinstallResolutionListener()},t}();var ts=function(){function t(t,i,n){var s;this._canvasElement=null,this._bitmapSizeChangedListeners=[],this._suggestedBitmapSize=null,this._suggestedBitmapSizeChangedListeners=[],this._devicePixelRatioObservable=null,this._canvasElementResizeObserver=null,this._canvasElement=t,this._canvasElementClientSize=Gn({width:this._canvasElement.clientWidth,height:this._canvasElement.clientHeight}),this._transformBitmapSize=null!=i?i:function(t){return t},this._allowResizeObserver=null===(s=null==n?void 0:n.allowResizeObserver)||void 0===s||s,this._chooseAndInitObserver()}return t.prototype.dispose=function(){var t,i;if(null===this._canvasElement)throw new Error("Object is disposed");null===(t=this._canvasElementResizeObserver)||void 0===t||t.disconnect(),this._canvasElementResizeObserver=null,null===(i=this._devicePixelRatioObservable)||void 0===i||i.dispose(),this._devicePixelRatioObservable=null,this._suggestedBitmapSizeChangedListeners.length=0,this._bitmapSizeChangedListeners.length=0,this._canvasElement=null},Object.defineProperty(t.prototype,"canvasElement",{get:function(){if(null===this._canvasElement)throw new Error("Object is disposed");return this._canvasElement},enumerable:!1,configurable:!0}),Object.defineProperty(t.prototype,"canvasElementClientSize",{get:function(){return this._canvasElementClientSize},enumerable:!1,configurable:!0}),Object.defineProperty(t.prototype,"bitmapSize",{get:function(){return Gn({width:this.canvasElement.width,height:this.canvasElement.height})},enumerable:!1,configurable:!0}),t.prototype.resizeCanvasElement=function(t){this._canvasElementClientSize=Gn(t),this.canvasElement.style.width="".concat(this._canvasElementClientSize.width,"px"),this.canvasElement.style.height="".concat(this._canvasElementClientSize.height,"px"),this._invalidateBitmapSize()},t.prototype.subscribeBitmapSizeChanged=function(t){this._bitmapSizeChangedListeners.push(t)},t.prototype.unsubscribeBitmapSizeChanged=function(t){this._bitmapSizeChangedListeners=this._bitmapSizeChangedListeners.filter((function(i){return i!==t}))},Object.defineProperty(t.prototype,"suggestedBitmapSize",{get:function(){return this._suggestedBitmapSize},enumerable:!1,configurable:!0}),t.prototype.subscribeSuggestedBitmapSizeChanged=function(t){this._suggestedBitmapSizeChangedListeners.push(t)},t.prototype.unsubscribeSuggestedBitmapSizeChanged=function(t){this._suggestedBitmapSizeChangedListeners=this._suggestedBitmapSizeChangedListeners.filter((function(i){return i!==t}))},t.prototype.applySuggestedBitmapSize=function(){if(null!==this._suggestedBitmapSize){var t=this._suggestedBitmapSize;this._suggestedBitmapSize=null,this._resizeBitmap(t),this._emitSuggestedBitmapSizeChanged(t,this._suggestedBitmapSize)}},t.prototype._resizeBitmap=function(t){var i=this.bitmapSize;Jn(i,t)||(this.canvasElement.width=t.width,this.canvasElement.height=t.height,this._emitBitmapSizeChanged(i,t))},t.prototype._emitBitmapSizeChanged=function(t,i){var n=this;this._bitmapSizeChangedListeners.forEach((function(s){return s.call(n,t,i)}))},t.prototype._suggestNewBitmapSize=function(t){var i=this._suggestedBitmapSize,n=Gn(this._transformBitmapSize(t,this._canvasElementClientSize)),s=Jn(this.bitmapSize,n)?null:n;null===i&&null===s||null!==i&&null!==s&&Jn(i,s)||(this._suggestedBitmapSize=s,this._emitSuggestedBitmapSizeChanged(i,s))},t.prototype._emitSuggestedBitmapSizeChanged=function(t,i){var n=this;this._suggestedBitmapSizeChangedListeners.forEach((function(s){return s.call(n,t,i)}))},t.prototype._chooseAndInitObserver=function(){var t=this;this._allowResizeObserver?new Promise((function(t){var i=new ResizeObserver((function(n){t(n.every((function(t){return"devicePixelContentBoxSize"in t}))),i.disconnect()}));i.observe(document.body,{box:"device-pixel-content-box"})})).catch((function(){return!1})).then((function(i){return i?t._initResizeObserver():t._initDevicePixelRatioObservable()})):this._initDevicePixelRatioObservable()},t.prototype._initDevicePixelRatioObservable=function(){var t=this;if(null!==this._canvasElement){var i=is(this._canvasElement);if(null===i)throw new Error("No window is associated with the canvas");this._devicePixelRatioObservable=function(t){return new Qn(t)}(i),this._devicePixelRatioObservable.subscribe((function(){return t._invalidateBitmapSize()})),this._invalidateBitmapSize()}},t.prototype._invalidateBitmapSize=function(){var t,i;if(null!==this._canvasElement){var n=is(this._canvasElement);if(null!==n){var s=null!==(i=null===(t=this._devicePixelRatioObservable)||void 0===t?void 0:t.value)&&void 0!==i?i:n.devicePixelRatio,e=this._canvasElement.getClientRects(),r=void 0!==e[0]?function(t,i){return Gn({width:Math.round(t.left*i+t.width*i)-Math.round(t.left*i),height:Math.round(t.top*i+t.height*i)-Math.round(t.top*i)})}(e[0],s):Gn({width:this._canvasElementClientSize.width*s,height:this._canvasElementClientSize.height*s});this._suggestNewBitmapSize(r)}}},t.prototype._initResizeObserver=function(){var t=this;null!==this._canvasElement&&(this._canvasElementResizeObserver=new ResizeObserver((function(i){var n=i.find((function(i){return i.target===t._canvasElement}));if(n&&n.devicePixelContentBoxSize&&n.devicePixelContentBoxSize[0]){var s=n.devicePixelContentBoxSize[0],e=Gn({width:s.inlineSize,height:s.blockSize});t._suggestNewBitmapSize(e)}})),this._canvasElementResizeObserver.observe(this._canvasElement,{box:"device-pixel-content-box"}))},t}();function is(t){return t.ownerDocument.defaultView}var ns=function(){function t(t,i,n){if(0===i.width||0===i.height)throw new TypeError("Rendering target could only be created on a media with positive width and height");if(this._mediaSize=i,0===n.width||0===n.height)throw new TypeError("Rendering target could only be created using a bitmap with positive integer width and height");this._bitmapSize=n,this._context=t}return t.prototype.useMediaCoordinateSpace=function(t){try{return this._context.save(),this._context.setTransform(1,0,0,1,0,0),this._context.scale(this._horizontalPixelRatio,this._verticalPixelRatio),t({context:this._context,mediaSize:this._mediaSize})}finally{this._context.restore()}},t.prototype.useBitmapCoordinateSpace=function(t){try{return this._context.save(),this._context.setTransform(1,0,0,1,0,0),t({context:this._context,mediaSize:this._mediaSize,bitmapSize:this._bitmapSize,horizontalPixelRatio:this._horizontalPixelRatio,verticalPixelRatio:this._verticalPixelRatio})}finally{this._context.restore()}},Object.defineProperty(t.prototype,"_horizontalPixelRatio",{get:function(){return this._bitmapSize.width/this._mediaSize.width},enumerable:!1,configurable:!0}),Object.defineProperty(t.prototype,"_verticalPixelRatio",{get:function(){return this._bitmapSize.height/this._mediaSize.height},enumerable:!1,configurable:!0}),t}();function ss(t,i){var n=t.canvasElementClientSize;if(0===n.width||0===n.height)return null;var s=t.bitmapSize;if(0===s.width||0===s.height)return null;var e=t.canvasElement.getContext("2d",i);return null===e?null:new ns(e,n,s)}const es="undefined"!=typeof window;function rs(){return!!es&&window.navigator.userAgent.toLowerCase().indexOf("firefox")>-1}function hs(){return!!es&&/iPhone|iPad|iPod/.test(window.navigator.platform)}function ls(t){return t+t%2}function as(t,i){return t.Rd-i.Rd}function os(t,i,n){const s=(t.Rd-i.Rd)/(t.ot-i.ot);return Math.sign(s)*Math.min(Math.abs(s),n)}class _s{constructor(t,i,n,s){this.Dd=null,this.Od=null,this.Ad=null,this.Bd=null,this.Vd=null,this.zd=0,this.Ed=0,this.Id=t,this.Ld=i,this.Nd=n,this.ss=s}Fd(t,i){if(null!==this.Dd){if(this.Dd.ot===i)return void(this.Dd.Rd=t);if(Math.abs(this.Dd.Rd-t)50)return;let n=0;const s=os(this.Dd,this.Od,this.Ld),e=as(this.Dd,this.Od),r=[s],h=[e];if(n+=e,null!==this.Ad){const t=os(this.Od,this.Ad,this.Ld);if(Math.sign(t)===Math.sign(s)){const i=as(this.Od,this.Ad);if(r.push(t),h.push(i),n+=i,null!==this.Bd){const t=os(this.Ad,this.Bd,this.Ld);if(Math.sign(t)===Math.sign(s)){const i=as(this.Ad,this.Bd);r.push(t),h.push(i),n+=i}}}}let l=0;for(let t=0;t({width:Math.max(t.width,i.width),height:Math.max(t.height,i.height)})});return s.resizeCanvasElement(i),s}function cs(t){var i;t.width=1,t.height=1,null===(i=t.getContext("2d"))||void 0===i||i.clearRect(0,0,1,1)}function ds(t,i,n,s){t.fl&&t.fl(i,n,s)}function fs(t,i,n,s){t.K(i,n,s)}function vs(t,i,n,s){const e=t(n,s);for(const t of e){const n=t.gt();null!==n&&i(n)}}function ps(t){es&&void 0!==window.chrome&&t.addEventListener("mousedown",(t=>{if(1===t.button)return t.preventDefault(),!1}))}class ms{constructor(t,i,n){this.jd=0,this.Hd=null,this.$d={nt:Number.NEGATIVE_INFINITY,st:Number.POSITIVE_INFINITY},this.Ud=0,this.qd=null,this.Yd={nt:Number.NEGATIVE_INFINITY,st:Number.POSITIVE_INFINITY},this.Xd=null,this.Kd=!1,this.Zd=null,this.Gd=null,this.Jd=!1,this.Qd=!1,this.tf=!1,this.if=null,this.nf=null,this.sf=null,this.ef=null,this.rf=null,this.hf=null,this.lf=null,this.af=0,this._f=!1,this.uf=!1,this.cf=!1,this.df=0,this.ff=null,this.vf=!hs(),this.pf=t=>{this.mf(t)},this.bf=t=>{if(this.wf(t)){const i=this.gf(t);if(++this.Ud,this.qd&&this.Ud>1){const{Mf:n}=this.xf(gs(t),this.Yd);n<30&&!this.tf&&this.Sf(i,this.kf.yf),this.Cf()}}else{const i=this.gf(t);if(++this.jd,this.Hd&&this.jd>1){const{Mf:n}=this.xf(gs(t),this.$d);n<5&&!this.Qd&&this.Tf(i,this.kf.Pf),this.Rf()}}},this.Df=t,this.kf=i,this._n=n,this.Of()}S(){null!==this.if&&(this.if(),this.if=null),null!==this.nf&&(this.nf(),this.nf=null),null!==this.ef&&(this.ef(),this.ef=null),null!==this.rf&&(this.rf(),this.rf=null),null!==this.hf&&(this.hf(),this.hf=null),null!==this.sf&&(this.sf(),this.sf=null),this.Af(),this.Rf()}Bf(t){this.ef&&this.ef();const i=this.Vf.bind(this);if(this.ef=()=>{this.Df.removeEventListener("mousemove",i)},this.Df.addEventListener("mousemove",i),this.wf(t))return;const n=this.gf(t);this.Tf(n,this.kf.zf),this.vf=!0}Rf(){null!==this.Hd&&clearTimeout(this.Hd),this.jd=0,this.Hd=null,this.$d={nt:Number.NEGATIVE_INFINITY,st:Number.POSITIVE_INFINITY}}Cf(){null!==this.qd&&clearTimeout(this.qd),this.Ud=0,this.qd=null,this.Yd={nt:Number.NEGATIVE_INFINITY,st:Number.POSITIVE_INFINITY}}Vf(t){if(this.cf||null!==this.Gd)return;if(this.wf(t))return;const i=this.gf(t);this.Tf(i,this.kf.Ef),this.vf=!0}If(t){const i=xs(t.changedTouches,f(this.ff));if(null===i)return;if(this.df=Ms(t),null!==this.lf)return;if(this.uf)return;this._f=!0;const n=this.xf(gs(i),f(this.Gd)),{Lf:s,Nf:e,Mf:r}=n;if(this.Jd||!(r<5)){if(!this.Jd){const t=.5*s,i=e>=t&&!this._n.Ff(),n=t>e&&!this._n.Wf();i||n||(this.uf=!0),this.Jd=!0,this.tf=!0,this.Af(),this.Cf()}if(!this.uf){const n=this.gf(t,i);this.Sf(n,this.kf.jf),ws(t)}}}Hf(t){if(0!==t.button)return;const i=this.xf(gs(t),f(this.Zd)),{Mf:n}=i;if(n>=5&&(this.Qd=!0,this.Rf()),this.Qd){const i=this.gf(t);this.Tf(i,this.kf.$f)}}xf(t,i){const n=Math.abs(i.nt-t.nt),s=Math.abs(i.st-t.st);return{Lf:n,Nf:s,Mf:n+s}}Uf(t){let i=xs(t.changedTouches,f(this.ff));if(null===i&&0===t.touches.length&&(i=t.changedTouches[0]),null===i)return;this.ff=null,this.df=Ms(t),this.Af(),this.Gd=null,this.hf&&(this.hf(),this.hf=null);const n=this.gf(t,i);if(this.Sf(n,this.kf.qf),++this.Ud,this.qd&&this.Ud>1){const{Mf:t}=this.xf(gs(i),this.Yd);t<30&&!this.tf&&this.Sf(n,this.kf.yf),this.Cf()}else this.tf||(this.Sf(n,this.kf.Yf),this.kf.Yf&&ws(t));0===this.Ud&&ws(t),0===t.touches.length&&this.Kd&&(this.Kd=!1,ws(t))}mf(t){if(0!==t.button)return;const i=this.gf(t);if(this.Zd=null,this.cf=!1,this.rf&&(this.rf(),this.rf=null),rs()){this.Df.ownerDocument.documentElement.removeEventListener("mouseleave",this.pf)}if(!this.wf(t))if(this.Tf(i,this.kf.Xf),++this.jd,this.Hd&&this.jd>1){const{Mf:n}=this.xf(gs(t),this.$d);n<5&&!this.Qd&&this.Tf(i,this.kf.Pf),this.Rf()}else this.Qd||this.Tf(i,this.kf.Kf)}Af(){null!==this.Xd&&(clearTimeout(this.Xd),this.Xd=null)}Zf(t){if(null!==this.ff)return;const i=t.changedTouches[0];this.ff=i.identifier,this.df=Ms(t);const n=this.Df.ownerDocument.documentElement;this.tf=!1,this.Jd=!1,this.uf=!1,this.Gd=gs(i),this.hf&&(this.hf(),this.hf=null);{const i=this.If.bind(this),s=this.Uf.bind(this);this.hf=()=>{n.removeEventListener("touchmove",i),n.removeEventListener("touchend",s)},n.addEventListener("touchmove",i,{passive:!1}),n.addEventListener("touchend",s,{passive:!1}),this.Af(),this.Xd=setTimeout(this.Gf.bind(this,t),240)}const s=this.gf(t,i);this.Sf(s,this.kf.Jf),this.qd||(this.Ud=0,this.qd=setTimeout(this.Cf.bind(this),500),this.Yd=gs(i))}Qf(t){if(0!==t.button)return;const i=this.Df.ownerDocument.documentElement;rs()&&i.addEventListener("mouseleave",this.pf),this.Qd=!1,this.Zd=gs(t),this.rf&&(this.rf(),this.rf=null);{const t=this.Hf.bind(this),n=this.mf.bind(this);this.rf=()=>{i.removeEventListener("mousemove",t),i.removeEventListener("mouseup",n)},i.addEventListener("mousemove",t),i.addEventListener("mouseup",n)}if(this.cf=!0,this.wf(t))return;const n=this.gf(t);this.Tf(n,this.kf.tv),this.Hd||(this.jd=0,this.Hd=setTimeout(this.Rf.bind(this),500),this.$d=gs(t))}Of(){this.Df.addEventListener("mouseenter",this.Bf.bind(this)),this.Df.addEventListener("touchcancel",this.Af.bind(this));{const t=this.Df.ownerDocument,i=t=>{this.kf.iv&&(t.composed&&this.Df.contains(t.composedPath()[0])||t.target&&this.Df.contains(t.target)||this.kf.iv())};this.nf=()=>{t.removeEventListener("touchstart",i)},this.if=()=>{t.removeEventListener("mousedown",i)},t.addEventListener("mousedown",i),t.addEventListener("touchstart",i,{passive:!0})}hs()&&(this.sf=()=>{this.Df.removeEventListener("dblclick",this.bf)},this.Df.addEventListener("dblclick",this.bf)),this.Df.addEventListener("mouseleave",this.nv.bind(this)),this.Df.addEventListener("touchstart",this.Zf.bind(this),{passive:!0}),ps(this.Df),this.Df.addEventListener("mousedown",this.Qf.bind(this)),this.sv(),this.Df.addEventListener("touchmove",(()=>{}),{passive:!1})}sv(){void 0===this.kf.ev&&void 0===this.kf.rv&&void 0===this.kf.hv||(this.Df.addEventListener("touchstart",(t=>this.lv(t.touches)),{passive:!0}),this.Df.addEventListener("touchmove",(t=>{if(2===t.touches.length&&null!==this.lf&&void 0!==this.kf.rv){const i=bs(t.touches[0],t.touches[1])/this.af;this.kf.rv(this.lf,i),ws(t)}}),{passive:!1}),this.Df.addEventListener("touchend",(t=>{this.lv(t.touches)})))}lv(t){1===t.length&&(this._f=!1),2!==t.length||this._f||this.Kd?this.av():this.ov(t)}ov(t){const i=this.Df.getBoundingClientRect()||{left:0,top:0};this.lf={nt:(t[0].clientX-i.left+(t[1].clientX-i.left))/2,st:(t[0].clientY-i.top+(t[1].clientY-i.top))/2},this.af=bs(t[0],t[1]),void 0!==this.kf.ev&&this.kf.ev(),this.Af()}av(){null!==this.lf&&(this.lf=null,void 0!==this.kf.hv&&this.kf.hv())}nv(t){if(this.ef&&this.ef(),this.wf(t))return;if(!this.vf)return;const i=this.gf(t);this.Tf(i,this.kf._v),this.vf=!hs()}Gf(t){const i=xs(t.touches,f(this.ff));if(null===i)return;const n=this.gf(t,i);this.Sf(n,this.kf.uv),this.tf=!0,this.Kd=!0}wf(t){return t.sourceCapabilities&&void 0!==t.sourceCapabilities.firesTouchEvents?t.sourceCapabilities.firesTouchEvents:Ms(t){"touchstart"!==t.type&&ws(t)}}}}function bs(t,i){const n=t.clientX-i.clientX,s=t.clientY-i.clientY;return Math.sqrt(n*n+s*s)}function ws(t){t.cancelable&&t.preventDefault()}function gs(t){return{nt:t.pageX,st:t.pageY}}function Ms(t){return t.timeStamp||performance.now()}function xs(t,i){for(let n=0;n{var s,e,r,h;return(null!==(e=null===(s=n.Dt())||void 0===s?void 0:s.xa())&&void 0!==e?e:"")!==i?[]:null!==(h=null===(r=n.la)||void 0===r?void 0:r.call(n,t))&&void 0!==h?h:[]}}class Cs{constructor(t,i,n,s){this.Ei=null,this.gv=null,this.Mv=!1,this.xv=new Jt(200),this.Zr=null,this.Sv=0,this.yv=!1,this.kv=()=>{this.yv||this.Qi.Cv().$t().Nh()},this.Tv=()=>{this.yv||this.Qi.Cv().$t().Nh()},this.Qi=t,this._n=i,this.mo=i.layout,this.kc=n,this.Pv="left"===s,this.Rv=ks("normal",s),this.Dv=ks("top",s),this.Ov=ks("bottom",s),this.Av=document.createElement("div"),this.Av.style.height="100%",this.Av.style.overflow="hidden",this.Av.style.width="25px",this.Av.style.left="0",this.Av.style.position="relative",this.Bv=us(this.Av,Gn({width:16,height:16})),this.Bv.subscribeSuggestedBitmapSizeChanged(this.kv);const e=this.Bv.canvasElement;e.style.position="absolute",e.style.zIndex="1",e.style.left="0",e.style.top="0",this.Vv=us(this.Av,Gn({width:16,height:16})),this.Vv.subscribeSuggestedBitmapSizeChanged(this.Tv);const r=this.Vv.canvasElement;r.style.position="absolute",r.style.zIndex="2",r.style.left="0",r.style.top="0";const h={tv:this.zv.bind(this),Jf:this.zv.bind(this),$f:this.Ev.bind(this),jf:this.Ev.bind(this),iv:this.Iv.bind(this),Xf:this.Lv.bind(this),qf:this.Lv.bind(this),Pf:this.Nv.bind(this),yf:this.Nv.bind(this),zf:this.Fv.bind(this),_v:this.Wv.bind(this)};this.jv=new ms(this.Vv.canvasElement,h,{Ff:()=>!this._n.handleScroll.vertTouchDrag,Wf:()=>!0})}S(){this.jv.S(),this.Vv.unsubscribeSuggestedBitmapSizeChanged(this.Tv),cs(this.Vv.canvasElement),this.Vv.dispose(),this.Bv.unsubscribeSuggestedBitmapSizeChanged(this.kv),cs(this.Bv.canvasElement),this.Bv.dispose(),null!==this.Ei&&this.Ei.$o().p(this),this.Ei=null}Hv(){return this.Av}P(){return this.mo.fontSize}$v(){const t=this.kc.W();return this.Zr!==t.R&&(this.xv.Qe(),this.Zr=t.R),t}Uv(){if(null===this.Ei)return 0;let t=0;const i=this.$v(),n=f(this.Bv.canvasElement.getContext("2d"));n.save();const s=this.Ei.Ia();n.font=this.qv(),s.length>0&&(t=Math.max(this.xv.Mi(n,s[0].Za),this.xv.Mi(n,s[s.length-1].Za)));const e=this.Yv();for(let i=e.length;i--;){const s=this.xv.Mi(n,e[i].Zt());s>t&&(t=s)}const r=this.Ei.Ct();if(null!==r&&null!==this.gv){const i=this.Ei.fn(1,r),s=this.Ei.fn(this.gv.height-2,r);t=Math.max(t,this.xv.Mi(n,this.Ei.Ni(Math.floor(Math.min(i,s))+.11111111111111,r)),this.xv.Mi(n,this.Ei.Ni(Math.ceil(Math.max(i,s))-.11111111111111,r)))}n.restore();const h=t||34;return ls(Math.ceil(i.C+i.T+i.V+i.I+5+h))}Xv(t){null!==this.gv&&Jn(this.gv,t)||(this.gv=t,this.yv=!0,this.Bv.resizeCanvasElement(t),this.Vv.resizeCanvasElement(t),this.yv=!1,this.Av.style.width=`${t.width}px`,this.Av.style.height=`${t.height}px`)}Kv(){return f(this.gv).width}Zi(t){this.Ei!==t&&(null!==this.Ei&&this.Ei.$o().p(this),this.Ei=t,t.$o().l(this.ao.bind(this),this))}Dt(){return this.Ei}Qe(){const t=this.Qi.Zv();this.Qi.Cv().$t().A_(t,f(this.Dt()))}Gv(t){if(null===this.gv)return;if(1!==t){this.Jv(),this.Bv.applySuggestedBitmapSize();const t=ss(this.Bv);null!==t&&(t.useBitmapCoordinateSpace((t=>{this.Qv(t),this.Ae(t)})),this.Qi.tp(t,this.Ov),this.ip(t),this.Qi.tp(t,this.Rv),this.np(t))}this.Vv.applySuggestedBitmapSize();const i=ss(this.Vv);null!==i&&(i.useBitmapCoordinateSpace((({context:t,bitmapSize:i})=>{t.clearRect(0,0,i.width,i.height)})),this.sp(i),this.Qi.tp(i,this.Dv))}ep(){return this.Bv.bitmapSize}rp(t,i,n){const s=this.ep();s.width>0&&s.height>0&&t.drawImage(this.Bv.canvasElement,i,n)}bt(){var t;null===(t=this.Ei)||void 0===t||t.Ia()}zv(t){if(null===this.Ei||this.Ei.Li()||!this._n.handleScale.axisPressedMouseMove.price)return;const i=this.Qi.Cv().$t(),n=this.Qi.Zv();this.Mv=!0,i.k_(n,this.Ei,t.localY)}Ev(t){if(null===this.Ei||!this._n.handleScale.axisPressedMouseMove.price)return;const i=this.Qi.Cv().$t(),n=this.Qi.Zv(),s=this.Ei;i.C_(n,s,t.localY)}Iv(){if(null===this.Ei||!this._n.handleScale.axisPressedMouseMove.price)return;const t=this.Qi.Cv().$t(),i=this.Qi.Zv(),n=this.Ei;this.Mv&&(this.Mv=!1,t.T_(i,n))}Lv(t){if(null===this.Ei||!this._n.handleScale.axisPressedMouseMove.price)return;const i=this.Qi.Cv().$t(),n=this.Qi.Zv();this.Mv=!1,i.T_(n,this.Ei)}Nv(t){this._n.handleScale.axisDoubleClickReset.price&&this.Qe()}Fv(t){if(null===this.Ei)return;!this.Qi.Cv().$t().W().handleScale.axisPressedMouseMove.price||this.Ei.fh()||this.Ei.Co()||this.hp(1)}Wv(t){this.hp(0)}Yv(){const t=[],i=null===this.Ei?void 0:this.Ei;return(n=>{for(let s=0;s{t.fillStyle=n.borderColor;const l=Math.max(1,Math.floor(h)),a=Math.floor(.5*h),o=Math.round(s.T*r);t.beginPath();for(const n of i)t.rect(Math.floor(e*r),Math.round(n.Aa*h)-a,o,l);t.fill()})),t.useMediaCoordinateSpace((({context:t})=>{var r;t.font=this.qv(),t.fillStyle=null!==(r=n.textColor)&&void 0!==r?r:this.mo.textColor,t.textAlign=this.Pv?"right":"left",t.textBaseline="middle";const h=this.Pv?Math.round(e-s.V):Math.round(e+s.T+s.V),l=i.map((i=>this.xv.gi(t,i.Za)));for(let n=i.length;n--;){const s=i[n];t.fillText(s.Za,h,s.Aa+l[n])}}))}Jv(){if(null===this.gv||null===this.Ei)return;let t=this.gv.height/2;const i=[],n=this.Ei.No().slice(),s=this.Qi.Zv(),e=this.$v();this.Ei===s.cr()&&this.Qi.Zv().No().forEach((t=>{s.ur(t)&&n.push(t)}));const r=this.Ei.Ta()[0],h=this.Ei;n.forEach((n=>{const e=n.Tn(s,h);e.forEach((t=>{t.Oi(null),t.Ai()&&i.push(t)})),r===n&&e.length>0&&(t=e[0].Si())})),i.forEach((t=>t.Oi(t.Si())));this.Ei.W().alignLabels&&this.lp(i,e,t)}lp(t,i,n){if(null===this.gv)return;const s=t.filter((t=>t.Si()<=n)),e=t.filter((t=>t.Si()>n));s.sort(((t,i)=>i.Si()-t.Si())),s.length&&e.length&&e.push(s[0]),e.sort(((t,i)=>t.Si()-i.Si()));for(const n of t){const t=Math.floor(n.Vt(i)/2),s=n.Si();s>-t&&sthis.gv.height-t&&sl-r&&n.Oi(l-r)}for(let t=1;t{if(i.Bi()){i.gt(f(this.Ei)).K(t,n,this.xv,s)}}))}sp(t){if(null===this.gv||null===this.Ei)return;const i=this.Qi.Cv().$t(),n=[],s=this.Qi.Zv(),e=i.Wc().Tn(s,this.Ei);e.length&&n.push(e);const r=this.$v(),h=this.Pv?"right":"left";n.forEach((i=>{i.forEach((i=>{i.gt(f(this.Ei)).K(t,r,this.xv,h)}))}))}hp(t){this.Av.style.cursor=1===t?"ns-resize":"default"}ao(){const t=this.Uv();this.Sv{this.yv||null===this.gp||this.Hi().Nh()},this.Tv=()=>{this.yv||null===this.gp||this.Hi().Nh()},this.Mp=t,this.gp=i,this.gp.z_().l(this.xp.bind(this),this,!0),this.Sp=document.createElement("td"),this.Sp.style.padding="0",this.Sp.style.position="relative";const n=document.createElement("div");n.style.width="100%",n.style.height="100%",n.style.position="relative",n.style.overflow="hidden",this.yp=document.createElement("td"),this.yp.style.padding="0",this.kp=document.createElement("td"),this.kp.style.padding="0",this.Sp.appendChild(n),this.Bv=us(n,Gn({width:16,height:16})),this.Bv.subscribeSuggestedBitmapSizeChanged(this.kv);const s=this.Bv.canvasElement;s.style.position="absolute",s.style.zIndex="1",s.style.left="0",s.style.top="0",this.Vv=us(n,Gn({width:16,height:16})),this.Vv.subscribeSuggestedBitmapSizeChanged(this.Tv);const e=this.Vv.canvasElement;e.style.position="absolute",e.style.zIndex="2",e.style.left="0",e.style.top="0",this.Cp=document.createElement("tr"),this.Cp.appendChild(this.yp),this.Cp.appendChild(this.Sp),this.Cp.appendChild(this.kp),this.Tp(),this.jv=new ms(this.Vv.canvasElement,this,{Ff:()=>null===this.pp&&!this.Mp.W().handleScroll.vertTouchDrag,Wf:()=>null===this.pp&&!this.Mp.W().handleScroll.horzTouchDrag})}S(){null!==this.ap&&this.ap.S(),null!==this.op&&this.op.S(),this.Vv.unsubscribeSuggestedBitmapSizeChanged(this.Tv),cs(this.Vv.canvasElement),this.Vv.dispose(),this.Bv.unsubscribeSuggestedBitmapSizeChanged(this.kv),cs(this.Bv.canvasElement),this.Bv.dispose(),null!==this.gp&&this.gp.z_().p(this),this.jv.S()}Zv(){return f(this.gp)}Pp(t){null!==this.gp&&this.gp.z_().p(this),this.gp=t,null!==this.gp&&this.gp.z_().l(Os.prototype.xp.bind(this),this,!0),this.Tp()}Cv(){return this.Mp}Hv(){return this.Cp}Tp(){if(null!==this.gp&&(this.Rp(),0!==this.Hi().wt().length)){if(null!==this.ap){const t=this.gp.S_();this.ap.Zi(f(t))}if(null!==this.op){const t=this.gp.y_();this.op.Zi(f(t))}}}Dp(){null!==this.ap&&this.ap.bt(),null!==this.op&&this.op.bt()}v_(){return null!==this.gp?this.gp.v_():0}p_(t){this.gp&&this.gp.p_(t)}zf(t){if(!this.gp)return;this.Op();const i=t.localX,n=t.localY;this.Ap(i,n,t)}tv(t){this.Op(),this.Bp(),this.Ap(t.localX,t.localY,t)}Ef(t){var i;if(!this.gp)return;this.Op();const n=t.localX,s=t.localY;this.Ap(n,s,t);const e=this.pr(n,s);this.Mp.Vp(null!==(i=null==e?void 0:e.wv)&&void 0!==i?i:null),this.Hi().zc(e&&{Ec:e.Ec,mv:e.mv})}Kf(t){null!==this.gp&&(this.Op(),this.zp(t))}Pf(t){null!==this.gp&&this.Ep(this.dp,t)}yf(t){this.Pf(t)}$f(t){this.Op(),this.Ip(t),this.Ap(t.localX,t.localY,t)}Xf(t){null!==this.gp&&(this.Op(),this.vp=!1,this.Lp(t))}Yf(t){null!==this.gp&&this.zp(t)}uv(t){if(this.vp=!0,null===this.pp){const i={x:t.localX,y:t.localY};this.Np(i,i,t)}}_v(t){null!==this.gp&&(this.Op(),this.gp.$t().zc(null),this.Fp())}Wp(){return this.cp}jp(){return this.dp}ev(){this.fp=1,this.Hi().Hn()}rv(t,i){if(!this.Mp.W().handleScale.pinch)return;const n=5*(i-this.fp);this.fp=i,this.Hi().qc(t.nt,n)}Jf(t){this.vp=!1,this.mp=null!==this.pp,this.Bp();const i=this.Hi().Wc();null!==this.pp&&i.kt()&&(this.bp={x:i.Yt(),y:i.Xt()},this.pp={x:t.localX,y:t.localY})}jf(t){if(null===this.gp)return;const i=t.localX,n=t.localY;if(null===this.pp)this.Ip(t);else{this.mp=!1;const s=f(this.bp),e=s.x+(i-this.pp.x),r=s.y+(n-this.pp.y);this.Ap(e,r,t)}}qf(t){0===this.Cv().W().trackingMode.exitMode&&(this.mp=!0),this.Hp(),this.Lp(t)}pr(t,i){const n=this.gp;return null===n?null:function(t,i,n){const s=t.No(),e=function(t,i,n){var s,e;let r,h;for(const o of t){const t=null!==(e=null===(s=o.oa)||void 0===s?void 0:s.call(o,i,n))&&void 0!==e?e:[];for(const i of t)l=i.zOrder,(!(a=null==r?void 0:r.zOrder)||"top"===l&&"top"!==a||"normal"===l&&"bottom"===a)&&(r=i,h=o)}var l,a;return r&&h?{bv:r,Ec:h}:null}(s,i,n);if("top"===(null==e?void 0:e.bv.zOrder))return Ss(e);for(const r of s){if(e&&e.Ec===r&&"bottom"!==e.bv.zOrder&&!e.bv.isBackground)return Ss(e);const s=ys(r.Cn(t),i,n);if(null!==s)return{Ec:r,vv:s.vv,mv:s.mv};if(e&&e.Ec===r&&"bottom"!==e.bv.zOrder&&e.bv.isBackground)return Ss(e)}return(null==e?void 0:e.bv)?Ss(e):null}(n,t,i)}$p(t,i){f("left"===i?this.ap:this.op).Xv(Gn({width:t,height:this.gv.height}))}Up(){return this.gv}Xv(t){Jn(this.gv,t)||(this.gv=t,this.yv=!0,this.Bv.resizeCanvasElement(t),this.Vv.resizeCanvasElement(t),this.yv=!1,this.Sp.style.width=t.width+"px",this.Sp.style.height=t.height+"px")}qp(){const t=f(this.gp);t.x_(t.S_()),t.x_(t.y_());for(const i of t.Ta())if(t.ur(i)){const n=i.Dt();null!==n&&t.x_(n),i.Rn()}}ep(){return this.Bv.bitmapSize}rp(t,i,n){const s=this.ep();s.width>0&&s.height>0&&t.drawImage(this.Bv.canvasElement,i,n)}Gv(t){if(0===t)return;if(null===this.gp)return;if(t>1&&this.qp(),null!==this.ap&&this.ap.Gv(t),null!==this.op&&this.op.Gv(t),1!==t){this.Bv.applySuggestedBitmapSize();const t=ss(this.Bv);null!==t&&(t.useBitmapCoordinateSpace((t=>{this.Qv(t)})),this.gp&&(this.Yp(t,Ts),this.Xp(t),this.Kp(t),this.Yp(t,Ps),this.Yp(t,Rs)))}this.Vv.applySuggestedBitmapSize();const i=ss(this.Vv);null!==i&&(i.useBitmapCoordinateSpace((({context:t,bitmapSize:i})=>{t.clearRect(0,0,i.width,i.height)})),this.Zp(i),this.Yp(i,Ds))}Gp(){return this.ap}Jp(){return this.op}tp(t,i){this.Yp(t,i)}xp(){null!==this.gp&&this.gp.z_().p(this),this.gp=null}zp(t){this.Ep(this.cp,t)}Ep(t,i){const n=i.localX,s=i.localY;t.M()&&t.m(this.Hi().St().Bu(n),{x:n,y:s},i)}Qv({context:t,bitmapSize:i}){const{width:n,height:s}=i,e=this.Hi(),r=e.q(),h=e._d();r===h?q(t,0,0,n,s,h):Z(t,0,0,n,s,r,h)}Xp(t){const i=f(this.gp).E_().Fh().gt();null!==i&&i.K(t,!1)}Kp(t){const i=this.Hi().Fc();this.Qp(t,Ps,ds,i),this.Qp(t,Ps,fs,i)}Zp(t){this.Qp(t,Ps,fs,this.Hi().Wc())}Yp(t,i){const n=f(this.gp).No();for(const s of n)this.Qp(t,i,ds,s);for(const s of n)this.Qp(t,i,fs,s)}Qp(t,i,n,s){const e=f(this.gp),r=e.$t().Vc(),h=null!==r&&r.Ec===s,l=null!==r&&h&&void 0!==r.mv?r.mv.br:void 0;vs(i,(i=>n(i,t,h,l)),s,e)}Rp(){if(null===this.gp)return;const t=this.Mp,i=this.gp.S_().W().visible,n=this.gp.y_().W().visible;i||null===this.ap||(this.yp.removeChild(this.ap.Hv()),this.ap.S(),this.ap=null),n||null===this.op||(this.kp.removeChild(this.op.Hv()),this.op.S(),this.op=null);const s=t.$t().ed();i&&null===this.ap&&(this.ap=new Cs(this,t.W(),s,"left"),this.yp.appendChild(this.ap.Hv())),n&&null===this.op&&(this.op=new Cs(this,t.W(),s,"right"),this.kp.appendChild(this.op.Hv()))}tm(t){return t.cv&&this.vp||null!==this.pp}im(t){return Math.max(0,Math.min(t,this.gv.width-1))}nm(t){return Math.max(0,Math.min(t,this.gv.height-1))}Ap(t,i,n){this.Hi().Qc(this.im(t),this.nm(i),n,f(this.gp))}Fp(){this.Hi().nd()}Hp(){this.mp&&(this.pp=null,this.Fp())}Np(t,i,n){this.pp=t,this.mp=!1,this.Ap(i.x,i.y,n);const s=this.Hi().Wc();this.bp={x:s.Yt(),y:s.Xt()}}Hi(){return this.Mp.$t()}Lp(t){if(!this.up)return;const i=this.Hi(),n=this.Zv();if(i.D_(n,n.dn()),this._p=null,this.up=!1,i.Zc(),null!==this.wp){const t=performance.now(),n=i.St();this.wp.Pr(n.Iu(),t),this.wp.Yu(t)||i.qn(this.wp)}}Op(){this.pp=null}Bp(){if(!this.gp)return;if(this.Hi().Hn(),document.activeElement!==document.body&&document.activeElement!==document.documentElement)f(document.activeElement).blur();else{const t=document.getSelection();null!==t&&t.removeAllRanges()}!this.gp.dn().Li()&&this.Hi().St().Li()}Ip(t){if(null===this.gp)return;const i=this.Hi(),n=i.St();if(n.Li())return;const s=this.Mp.W(),e=s.handleScroll,r=s.kineticScroll;if((!e.pressedMouseMove||t.cv)&&(!e.horzTouchDrag&&!e.vertTouchDrag||!t.cv))return;const h=this.gp.dn(),l=performance.now();if(null!==this._p||this.tm(t)||(this._p={x:t.clientX,y:t.clientY,kd:l,sm:t.localX,rm:t.localY}),null!==this._p&&!this.up&&(this._p.x!==t.clientX||this._p.y!==t.clientY)){if(t.cv&&r.touch||!t.cv&&r.mouse){const t=n.ee();this.wp=new _s(.2/t,7/t,.997,15/t),this.wp.Fd(n.Iu(),this._p.kd)}else this.wp=null;h.Li()||i.P_(this.gp,h,t.localY),i.Xc(t.localX),this.up=!0}this.up&&(h.Li()||i.R_(this.gp,h,t.localY),i.Kc(t.localX),null!==this.wp&&this.wp.Fd(n.Iu(),l))}}class As{constructor(t,i,n,s,e){this.ft=!0,this.gv=Gn({width:0,height:0}),this.kv=()=>this.Gv(3),this.Pv="left"===t,this.kc=n.ed,this._n=i,this.hm=s,this.lm=e,this.Av=document.createElement("div"),this.Av.style.width="25px",this.Av.style.height="100%",this.Av.style.overflow="hidden",this.Bv=us(this.Av,Gn({width:16,height:16})),this.Bv.subscribeSuggestedBitmapSizeChanged(this.kv)}S(){this.Bv.unsubscribeSuggestedBitmapSizeChanged(this.kv),cs(this.Bv.canvasElement),this.Bv.dispose()}Hv(){return this.Av}Up(){return this.gv}Xv(t){Jn(this.gv,t)||(this.gv=t,this.Bv.resizeCanvasElement(t),this.Av.style.width=`${t.width}px`,this.Av.style.height=`${t.height}px`,this.ft=!0)}Gv(t){if(t<3&&!this.ft)return;if(0===this.gv.width||0===this.gv.height)return;this.ft=!1,this.Bv.applySuggestedBitmapSize();const i=ss(this.Bv);null!==i&&i.useBitmapCoordinateSpace((t=>{this.Qv(t),this.Ae(t)}))}ep(){return this.Bv.bitmapSize}rp(t,i,n){const s=this.ep();s.width>0&&s.height>0&&t.drawImage(this.Bv.canvasElement,i,n)}Ae({context:t,bitmapSize:i,horizontalPixelRatio:n,verticalPixelRatio:s}){if(!this.hm())return;t.fillStyle=this._n.timeScale.borderColor;const e=Math.floor(this.kc.W().C*n),r=Math.floor(this.kc.W().C*s),h=this.Pv?i.width-e:0;t.fillRect(h,0,e,r)}Qv({context:t,bitmapSize:i}){q(t,0,0,i.width,i.height,this.lm())}}function Bs(t){return i=>{var n,s;return null!==(s=null===(n=i.aa)||void 0===n?void 0:n.call(i,t))&&void 0!==s?s:[]}}const Vs=Bs("normal"),zs=Bs("top"),Es=Bs("bottom");class Is{constructor(t,i){this.am=null,this.om=null,this.k=null,this._m=!1,this.gv=Gn({width:0,height:0}),this.um=new k,this.xv=new Jt(5),this.yv=!1,this.kv=()=>{this.yv||this.Mp.$t().Nh()},this.Tv=()=>{this.yv||this.Mp.$t().Nh()},this.Mp=t,this.N_=i,this._n=t.W().layout,this.dm=document.createElement("tr"),this.fm=document.createElement("td"),this.fm.style.padding="0",this.vm=document.createElement("td"),this.vm.style.padding="0",this.Av=document.createElement("td"),this.Av.style.height="25px",this.Av.style.padding="0",this.pm=document.createElement("div"),this.pm.style.width="100%",this.pm.style.height="100%",this.pm.style.position="relative",this.pm.style.overflow="hidden",this.Av.appendChild(this.pm),this.Bv=us(this.pm,Gn({width:16,height:16})),this.Bv.subscribeSuggestedBitmapSizeChanged(this.kv);const n=this.Bv.canvasElement;n.style.position="absolute",n.style.zIndex="1",n.style.left="0",n.style.top="0",this.Vv=us(this.pm,Gn({width:16,height:16})),this.Vv.subscribeSuggestedBitmapSizeChanged(this.Tv);const s=this.Vv.canvasElement;s.style.position="absolute",s.style.zIndex="2",s.style.left="0",s.style.top="0",this.dm.appendChild(this.fm),this.dm.appendChild(this.Av),this.dm.appendChild(this.vm),this.bm(),this.Mp.$t().f_().l(this.bm.bind(this),this),this.jv=new ms(this.Vv.canvasElement,this,{Ff:()=>!0,Wf:()=>!this.Mp.W().handleScroll.horzTouchDrag})}S(){this.jv.S(),null!==this.am&&this.am.S(),null!==this.om&&this.om.S(),this.Vv.unsubscribeSuggestedBitmapSizeChanged(this.Tv),cs(this.Vv.canvasElement),this.Vv.dispose(),this.Bv.unsubscribeSuggestedBitmapSizeChanged(this.kv),cs(this.Bv.canvasElement),this.Bv.dispose()}Hv(){return this.dm}wm(){return this.am}gm(){return this.om}tv(t){if(this._m)return;this._m=!0;const i=this.Mp.$t();!i.St().Li()&&this.Mp.W().handleScale.axisPressedMouseMove.time&&i.Uc(t.localX)}Jf(t){this.tv(t)}iv(){const t=this.Mp.$t();!t.St().Li()&&this._m&&(this._m=!1,this.Mp.W().handleScale.axisPressedMouseMove.time&&t.Jc())}$f(t){const i=this.Mp.$t();!i.St().Li()&&this.Mp.W().handleScale.axisPressedMouseMove.time&&i.Gc(t.localX)}jf(t){this.$f(t)}Xf(){this._m=!1;const t=this.Mp.$t();t.St().Li()&&!this.Mp.W().handleScale.axisPressedMouseMove.time||t.Jc()}qf(){this.Xf()}Pf(){this.Mp.W().handleScale.axisDoubleClickReset.time&&this.Mp.$t().Xn()}yf(){this.Pf()}zf(){this.Mp.$t().W().handleScale.axisPressedMouseMove.time&&this.hp(1)}_v(){this.hp(0)}Up(){return this.gv}Mm(){return this.um}xm(t,i,n){Jn(this.gv,t)||(this.gv=t,this.yv=!0,this.Bv.resizeCanvasElement(t),this.Vv.resizeCanvasElement(t),this.yv=!1,this.Av.style.width=`${t.width}px`,this.Av.style.height=`${t.height}px`,this.um.m(t)),null!==this.am&&this.am.Xv(Gn({width:i,height:t.height})),null!==this.om&&this.om.Xv(Gn({width:n,height:t.height}))}Sm(){const t=this.ym();return Math.ceil(t.C+t.T+t.P+t.L+t.B+t.km)}bt(){this.Mp.$t().St().Ia()}ep(){return this.Bv.bitmapSize}rp(t,i,n){const s=this.ep();s.width>0&&s.height>0&&t.drawImage(this.Bv.canvasElement,i,n)}Gv(t){if(0===t)return;if(1!==t){this.Bv.applySuggestedBitmapSize();const i=ss(this.Bv);null!==i&&(i.useBitmapCoordinateSpace((t=>{this.Qv(t),this.Ae(t),this.Cm(i,Es)})),this.ip(i),this.Cm(i,Vs)),null!==this.am&&this.am.Gv(t),null!==this.om&&this.om.Gv(t)}this.Vv.applySuggestedBitmapSize();const i=ss(this.Vv);null!==i&&(i.useBitmapCoordinateSpace((({context:t,bitmapSize:i})=>{t.clearRect(0,0,i.width,i.height)})),this.Tm([...this.Mp.$t().wt(),this.Mp.$t().Wc()],i),this.Cm(i,zs))}Cm(t,i){const n=this.Mp.$t().wt();for(const s of n)vs(i,(i=>ds(i,t,!1,void 0)),s,void 0);for(const s of n)vs(i,(i=>fs(i,t,!1,void 0)),s,void 0)}Qv({context:t,bitmapSize:i}){q(t,0,0,i.width,i.height,this.Mp.$t()._d())}Ae({context:t,bitmapSize:i,verticalPixelRatio:n}){if(this.Mp.W().timeScale.borderVisible){t.fillStyle=this.Pm();const s=Math.max(1,Math.floor(this.ym().C*n));t.fillRect(0,0,i.width,s)}}ip(t){const i=this.Mp.$t().St(),n=i.Ia();if(!n||0===n.length)return;const s=this.N_.maxTickMarkWeight(n),e=this.ym(),r=i.W();r.borderVisible&&r.ticksVisible&&t.useBitmapCoordinateSpace((({context:t,horizontalPixelRatio:i,verticalPixelRatio:s})=>{t.strokeStyle=this.Pm(),t.fillStyle=this.Pm();const r=Math.max(1,Math.floor(i)),h=Math.floor(.5*i);t.beginPath();const l=Math.round(e.T*s);for(let s=n.length;s--;){const e=Math.round(n[s].coord*i);t.rect(e-h,0,r,l)}t.fill()})),t.useMediaCoordinateSpace((({context:t})=>{const i=e.C+e.T+e.L+e.P/2;t.textAlign="center",t.textBaseline="middle",t.fillStyle=this.$(),t.font=this.qv();for(const e of n)if(e.weight=s){const n=e.needAlignCoordinate?this.Rm(t,e.coord,e.label):e.coord;t.fillText(e.label,n,i)}}))}Rm(t,i,n){const s=this.xv.Mi(t,n),e=s/2,r=Math.floor(i-e)+.5;return r<0?i+=Math.abs(0-r):r+s>this.gv.width&&(i-=Math.abs(this.gv.width-(r+s))),i}Tm(t,i){const n=this.ym();for(const s of t)for(const t of s.Ji())t.gt().K(i,n)}Pm(){return this.Mp.W().timeScale.borderColor}$(){return this._n.textColor}j(){return this._n.fontSize}qv(){return z(this.j(),this._n.fontFamily)}Dm(){return z(this.j(),this._n.fontFamily,"bold")}ym(){null===this.k&&(this.k={C:1,N:NaN,L:NaN,B:NaN,Wi:NaN,T:5,P:NaN,R:"",Fi:new Jt,km:0});const t=this.k,i=this.qv();if(t.R!==i){const n=this.j();t.P=n,t.R=i,t.L=3*n/12,t.B=3*n/12,t.Wi=9*n/12,t.N=0,t.km=4*n/12,t.Fi.Qe()}return this.k}hp(t){this.Av.style.cursor=1===t?"ew-resize":"default"}bm(){const t=this.Mp.$t(),i=t.W();i.leftPriceScale.visible||null===this.am||(this.fm.removeChild(this.am.Hv()),this.am.S(),this.am=null),i.rightPriceScale.visible||null===this.om||(this.vm.removeChild(this.om.Hv()),this.om.S(),this.om=null);const n={ed:this.Mp.$t().ed()},s=()=>i.leftPriceScale.borderVisible&&t.St().W().borderVisible,e=()=>t._d();i.leftPriceScale.visible&&null===this.am&&(this.am=new As("left",i,n,s,e),this.fm.appendChild(this.am.Hv())),i.rightPriceScale.visible&&null===this.om&&(this.om=new As("right",i,n,s,e),this.vm.appendChild(this.om.Hv()))}}const Ls=!!es&&!!navigator.userAgentData&&navigator.userAgentData.brands.some((t=>t.brand.includes("Chromium")))&&!!es&&((null===(Ns=null===navigator||void 0===navigator?void 0:navigator.userAgentData)||void 0===Ns?void 0:Ns.platform)?"Windows"===navigator.userAgentData.platform:navigator.userAgent.toLowerCase().indexOf("win")>=0);var Ns;class Fs{constructor(t,i,n){var s;this.Om=[],this.Am=0,this.Qa=0,this.e_=0,this.Bm=0,this.Vm=0,this.zm=null,this.Em=!1,this.cp=new k,this.dp=new k,this.xc=new k,this.Im=null,this.Lm=null,this.Nm=t,this._n=i,this.N_=n,this.dm=document.createElement("div"),this.dm.classList.add("tv-lightweight-charts"),this.dm.style.overflow="hidden",this.dm.style.direction="ltr",this.dm.style.width="100%",this.dm.style.height="100%",(s=this.dm).style.userSelect="none",s.style.webkitUserSelect="none",s.style.msUserSelect="none",s.style.MozUserSelect="none",s.style.webkitTapHighlightColor="transparent",this.Fm=document.createElement("table"),this.Fm.setAttribute("cellspacing","0"),this.dm.appendChild(this.Fm),this.Wm=this.jm.bind(this),Ws(this._n)&&this.Hm(!0),this.Hi=new An(this.yc.bind(this),this._n,n),this.$t().jc().l(this.$m.bind(this),this),this.Um=new Is(this,this.N_),this.Fm.appendChild(this.Um.Hv());const e=i.autoSize&&this.qm();let r=this._n.width,h=this._n.height;if(e||0===r||0===h){const i=t.getBoundingClientRect();r=r||i.width,h=h||i.height}this.Ym(r,h),this.Xm(),t.appendChild(this.dm),this.Km(),this.Hi.St().Gu().l(this.Hi.$l.bind(this.Hi),this),this.Hi.f_().l(this.Hi.$l.bind(this.Hi),this)}$t(){return this.Hi}W(){return this._n}Zm(){return this.Om}Gm(){return this.Um}S(){this.Hm(!1),0!==this.Am&&window.cancelAnimationFrame(this.Am),this.Hi.jc().p(this),this.Hi.St().Gu().p(this),this.Hi.f_().p(this),this.Hi.S();for(const t of this.Om)this.Fm.removeChild(t.Hv()),t.Wp().p(this),t.jp().p(this),t.S();this.Om=[],f(this.Um).S(),null!==this.dm.parentElement&&this.dm.parentElement.removeChild(this.dm),this.xc.S(),this.cp.S(),this.dp.S(),this.Jm()}Ym(t,i,n=!1){if(this.Qa===i&&this.e_===t)return;const s=function(t){const i=Math.floor(t.width),n=Math.floor(t.height);return Gn({width:i-i%2,height:n-n%2})}(Gn({width:t,height:i}));this.Qa=s.height,this.e_=s.width;const e=this.Qa+"px",r=this.e_+"px";f(this.dm).style.height=e,f(this.dm).style.width=r,this.Fm.style.height=e,this.Fm.style.width=r,n?this.Qm(lt.ns(),performance.now()):this.Hi.$l()}Gv(t){void 0===t&&(t=lt.ns());for(let i=0;i{let s=0;for(let e=0;e{f("left"===i?this.Um.wm():this.Um.gm()).rp(f(t),n,s)};if(this._n.timeScale.visible){const i=this.Um.ep();if(null!==t){let e=0;this.eb()&&(r("left",e,n),e=f(s.Gp()).ep().width),this.Um.rp(t,e,n),e+=i.width,this.rb()&&r("right",e,n)}n+=i.height}return Gn({width:i,height:n})}_b(){let t=0,i=0,n=0;for(const s of this.Om)this.eb()&&(i=Math.max(i,f(s.Gp()).Uv(),this._n.leftPriceScale.minimumWidth)),this.rb()&&(n=Math.max(n,f(s.Jp()).Uv(),this._n.rightPriceScale.minimumWidth)),t+=s.v_();i=ls(i),n=ls(n);const s=this.e_,e=this.Qa,r=Math.max(s-i-n,0),h=this._n.timeScale.visible;let l=h?Math.max(this.Um.Sm(),this._n.timeScale.minimumHeight):0;var a;l=(a=l)+a%2;const o=0+l,_=e{t.Dp()})),3===(null===(n=this.zm)||void 0===n?void 0:n.Fn())&&(this.zm.Jn(t),this.cb(),this.fb(this.zm),this.vb(this.zm,i),t=this.zm,this.zm=null)),this.Gv(t)}vb(t,i){for(const n of t.Gn())this.Qn(n,i)}fb(t){const i=this.Hi.Nc();for(let n=0;n{if(this.Em=!1,this.Am=0,null!==this.zm){const i=this.zm;this.zm=null,this.Qm(i,t);for(const n of i.Gn())if(5===n.$n&&!n.Ot.Yu(t)){this.$t().qn(n.Ot);break}}})))}cb(){this.Xm()}Xm(){const t=this.Hi.Nc(),i=t.length,n=this.Om.length;for(let t=i;t{const n=i.Bn().il(t);null!==n&&e.set(i,n)}))}let r;if(null!==t){const i=null===(s=this.Hi.St().$i(t))||void 0===s?void 0:s.originalTime;void 0!==i&&(r=i)}const h=this.$t().Vc(),l=null!==h&&h.Ec instanceof qi?h.Ec:void 0,a=null!==h&&void 0!==h.mv?h.mv.mr:void 0;return{wb:r,ie:null!=t?t:void 0,gb:null!=i?i:void 0,Mb:l,xb:e,Sb:a,yb:null!=n?n:void 0}}pb(t,i,n){this.cp.m((()=>this.bb(t,i,n)))}mb(t,i,n){this.dp.m((()=>this.bb(t,i,n)))}$m(t,i,n){this.xc.m((()=>this.bb(t,i,n)))}Km(){const t=this._n.timeScale.visible?"":"none";this.Um.Hv().style.display=t}eb(){return this.Om[0].Zv().S_().W().visible}rb(){return this.Om[0].Zv().y_().W().visible}qm(){return"ResizeObserver"in window&&(this.Im=new ResizeObserver((t=>{const i=t.find((t=>t.target===this.Nm));i&&this.Ym(i.contentRect.width,i.contentRect.height)})),this.Im.observe(this.Nm,{box:"border-box"}),!0)}Jm(){null!==this.Im&&this.Im.disconnect(),this.Im=null}}function Ws(t){return Boolean(t.handleScroll.mouseWheel||t.handleScale.mouseWheel)}function js(t,i){var n={};for(var s in t)Object.prototype.hasOwnProperty.call(t,s)&&i.indexOf(s)<0&&(n[s]=t[s]);if(null!=t&&"function"==typeof Object.getOwnPropertySymbols){var e=0;for(s=Object.getOwnPropertySymbols(t);efunction(t,i){return i?i(t):void 0===(n=t).open&&void 0===n.value;var n}(s,h)?Zs({ot:i,ie:n,wb:e},s):Zs(t(i,n,s,e,r),s)}function Js(t){return{Candlestick:Gs(Ys),Bar:Gs(qs),Area:Gs($s),Baseline:Gs(Us),Histogram:Gs(Hs),Line:Gs(Hs),Custom:Gs(Xs)}[t]}function Qs(t){return{ie:0,Cb:new Map,ia:t}}function te(t,i){if(void 0!==t&&0!==t.length)return{Tb:i.key(t[0].ot),Pb:i.key(t[t.length-1].ot)}}function ie(t){let i;return t.forEach((t=>{void 0===i&&(i=t.wb)})),d(i)}class ne{constructor(t){this.Rb=new Map,this.Db=new Map,this.Ob=new Map,this.Ab=[],this.N_=t}S(){this.Rb.clear(),this.Db.clear(),this.Ob.clear(),this.Ab=[]}Bb(t,i){let n=0!==this.Rb.size,s=!1;const e=this.Db.get(t);if(void 0!==e)if(1===this.Db.size)n=!1,s=!0,this.Rb.clear();else for(const i of this.Ab)i.pointData.Cb.delete(t)&&(s=!0);let r=[];if(0!==i.length){const n=i.map((t=>t.time)),e=this.N_.createConverterToInternalObj(i),h=Js(t.Yh()),l=t.ga(),a=t.Ma();r=i.map(((i,r)=>{const o=e(i.time),_=this.N_.key(o);let u=this.Rb.get(_);void 0===u&&(u=Qs(o),this.Rb.set(_,u),s=!0);const c=h(o,u.ie,i,n[r],l,a);return u.Cb.set(t,c),c}))}n&&this.Vb(),this.zb(t,r);let h=-1;if(s){const t=[];this.Rb.forEach((i=>{t.push({timeWeight:0,time:i.ia,pointData:i,originalTime:ie(i.Cb)})})),t.sort(((t,i)=>this.N_.key(t.time)-this.N_.key(i.time))),h=this.Eb(t)}return this.Ib(t,h,function(t,i,n){const s=te(t,n),e=te(i,n);if(void 0!==s&&void 0!==e)return{Xl:s.Pb>=e.Pb&&s.Tb>=e.Tb}}(this.Db.get(t),e,this.N_))}ld(t){return this.Bb(t,[])}Lb(t,i){const n=i;!function(t){void 0===t.wb&&(t.wb=t.time)}(n),this.N_.preprocessData(i);const s=this.N_.createConverterToInternalObj([i])(i.time),e=this.Ob.get(t);if(void 0!==e&&this.N_.key(s)this.N_.key(t.time)this.N_.key(s.ot)?Ks(i)&&n.push(i):Ks(i)?n[n.length-1]=i:n.splice(-1,1),this.Ob.set(t,i.ot)}zb(t,i){0!==i.length?(this.Db.set(t,i.filter(Ks)),this.Ob.set(t,i[i.length-1].ot)):(this.Db.delete(t),this.Ob.delete(t))}Vb(){for(const t of this.Ab)0===t.pointData.Cb.size&&this.Rb.delete(this.N_.key(t.time))}Eb(t){let i=-1;for(let n=0;n{0!==i.length&&(t=Math.max(t,i[i.length-1].ie))})),t}Ib(t,i,n){const s={Wb:new Map,St:{Au:this.Fb()}};if(-1!==i)this.Db.forEach(((i,e)=>{s.Wb.set(e,{We:i,jb:e===t?n:void 0})})),this.Db.has(t)||s.Wb.set(t,{We:[],jb:n}),s.St.Hb=this.Ab,s.St.$b=i;else{const i=this.Db.get(t);s.Wb.set(t,{We:i||[],jb:n})}return s}}function se(t,i){t.ie=i,t.Cb.forEach((t=>{t.ie=i}))}function ee(t){const i={value:t.Ot[3],time:t.wb};return void 0!==t.kb&&(i.customValues=t.kb),i}function re(t){const i=ee(t);return void 0!==t.O&&(i.color=t.O),i}function he(t){const i=ee(t);return void 0!==t.lt&&(i.lineColor=t.lt),void 0!==t.ks&&(i.topColor=t.ks),void 0!==t.Cs&&(i.bottomColor=t.Cs),i}function le(t){const i=ee(t);return void 0!==t.Ce&&(i.topLineColor=t.Ce),void 0!==t.Te&&(i.bottomLineColor=t.Te),void 0!==t.Me&&(i.topFillColor1=t.Me),void 0!==t.xe&&(i.topFillColor2=t.xe),void 0!==t.Se&&(i.bottomFillColor1=t.Se),void 0!==t.ye&&(i.bottomFillColor2=t.ye),i}function ae(t){const i={open:t.Ot[0],high:t.Ot[1],low:t.Ot[2],close:t.Ot[3],time:t.wb};return void 0!==t.kb&&(i.customValues=t.kb),i}function oe(t){const i=ae(t);return void 0!==t.O&&(i.color=t.O),i}function _e(t){const i=ae(t),{O:n,At:s,Hh:e}=t;return void 0!==n&&(i.color=n),void 0!==s&&(i.borderColor=s),void 0!==e&&(i.wickColor=e),i}function ue(t){return{Area:he,Line:re,Baseline:le,Histogram:re,Bar:oe,Candlestick:_e,Custom:ce}[t]}function ce(t){const i=t.wb;return Object.assign(Object.assign({},t.We),{time:i})}const de={vertLine:{color:"#9598A1",width:1,style:3,visible:!0,labelVisible:!0,labelBackgroundColor:"#131722"},horzLine:{color:"#9598A1",width:1,style:3,visible:!0,labelVisible:!0,labelBackgroundColor:"#131722"},mode:1},fe={vertLines:{color:"#D6DCDE",style:0,visible:!0},horzLines:{color:"#D6DCDE",style:0,visible:!0}},ve={background:{type:"solid",color:"#FFFFFF"},textColor:"#191919",fontSize:12,fontFamily:V},pe={autoScale:!0,mode:0,invertScale:!1,alignLabels:!0,borderVisible:!0,borderColor:"#2B2B43",entireTextOnly:!1,visible:!1,ticksVisible:!1,scaleMargins:{bottom:.1,top:.2},minimumWidth:0},me={rightOffset:0,barSpacing:6,minBarSpacing:.5,fixLeftEdge:!1,fixRightEdge:!1,lockVisibleTimeRangeOnResize:!1,rightBarStaysOnScroll:!1,borderVisible:!0,borderColor:"#2B2B43",visible:!0,timeVisible:!1,secondsVisible:!0,shiftVisibleRangeOnNewBar:!0,allowShiftVisibleRangeOnWhitespaceReplacement:!1,ticksVisible:!1,uniformDistribution:!1,minimumHeight:0,allowBoldLabels:!0},be={color:"rgba(0, 0, 0, 0)",visible:!1,fontSize:48,fontFamily:V,fontStyle:"",text:"",horzAlign:"center",vertAlign:"center"};function we(){return{width:0,height:0,autoSize:!1,layout:ve,crosshair:de,grid:fe,overlayPriceScales:Object.assign({},pe),leftPriceScale:Object.assign(Object.assign({},pe),{visible:!1}),rightPriceScale:Object.assign(Object.assign({},pe),{visible:!0}),timeScale:me,watermark:be,localization:{locale:es?navigator.language:"",dateFormat:"dd MMM 'yy"},handleScroll:{mouseWheel:!0,pressedMouseMove:!0,horzTouchDrag:!0,vertTouchDrag:!0},handleScale:{axisPressedMouseMove:{time:!0,price:!0},axisDoubleClickReset:{time:!0,price:!0},mouseWheel:!0,pinch:!0},kineticScroll:{mouse:!1,touch:!0},trackingMode:{exitMode:1}}}class ge{constructor(t,i){this.Ub=t,this.qb=i}applyOptions(t){this.Ub.$t().Ic(this.qb,t)}options(){return this.Ei().W()}width(){return ht(this.qb)?this.Ub.sb(this.qb):0}Ei(){return f(this.Ub.$t().Lc(this.qb)).Dt}}function Me(t,i,n){const s=js(t,["time","originalTime"]),e=Object.assign({time:i},s);return void 0!==n&&(e.originalTime=n),e}const xe={color:"#FF0000",price:0,lineStyle:2,lineWidth:1,lineVisible:!0,axisLabelVisible:!0,title:"",axisLabelColor:"",axisLabelTextColor:""};class Se{constructor(t){this.Bh=t}applyOptions(t){this.Bh.Lh(t)}options(){return this.Bh.W()}Yb(){return this.Bh}}class ye{constructor(t,i,n,s,e){this.Xb=new k,this.zs=t,this.Kb=i,this.Zb=n,this.N_=e,this.Gb=s}S(){this.Xb.S()}priceFormatter(){return this.zs.ca()}priceToCoordinate(t){const i=this.zs.Ct();return null===i?null:this.zs.Dt().Rt(t,i.Ot)}coordinateToPrice(t){const i=this.zs.Ct();return null===i?null:this.zs.Dt().fn(t,i.Ot)}barsInLogicalRange(t){if(null===t)return null;const i=new gn(new mn(t.from,t.to)).iu(),n=this.zs.Bn();if(n.Li())return null;const s=n.il(i.Rs(),1),e=n.il(i.ui(),-1),r=f(n.Jh()),h=f(n.An());if(null!==s&&null!==e&&s.ie>e.ie)return{barsBefore:t.from-r,barsAfter:h-t.to};const l={barsBefore:null===s||s.ie===r?t.from-r:s.ie-r,barsAfter:null===e||e.ie===h?h-t.to:h-e.ie};return null!==s&&null!==e&&(l.from=s.wb,l.to=e.wb),l}setData(t){this.N_,this.zs.Yh(),this.Kb.Jb(this.zs,t),this.Qb("full")}update(t){this.zs.Yh(),this.Kb.tw(this.zs,t),this.Qb("update")}dataByIndex(t,i){const n=this.zs.Bn().il(t,i);if(null===n)return null;return ue(this.seriesType())(n)}data(){const t=ue(this.seriesType());return this.zs.Bn().Qs().map((i=>t(i)))}subscribeDataChanged(t){this.Xb.l(t)}unsubscribeDataChanged(t){this.Xb.v(t)}setMarkers(t){this.N_;const i=t.map((t=>Me(t,this.N_.convertHorzItemToInternal(t.time),t.time)));this.zs.Zl(i)}markers(){return this.zs.Gl().map((t=>Me(t,t.originalTime,void 0)))}applyOptions(t){this.zs.Lh(t)}options(){return O(this.zs.W())}priceScale(){return this.Zb.priceScale(this.zs.Dt().xa())}createPriceLine(t){const i=C(O(xe),t),n=this.zs.Jl(i);return new Se(n)}removePriceLine(t){this.zs.Ql(t.Yb())}seriesType(){return this.zs.Yh()}attachPrimitive(t){this.zs.ba(t),t.attached&&t.attached({chart:this.Gb,series:this,requestUpdate:()=>this.zs.$t().$l()})}detachPrimitive(t){this.zs.wa(t),t.detached&&t.detached()}Qb(t){this.Xb.M()&&this.Xb.m(t)}}class ke{constructor(t,i,n){this.iw=new k,this.uu=new k,this.um=new k,this.Hi=t,this.wl=t.St(),this.Um=i,this.wl.Ku().l(this.nw.bind(this)),this.wl.Zu().l(this.sw.bind(this)),this.Um.Mm().l(this.ew.bind(this)),this.N_=n}S(){this.wl.Ku().p(this),this.wl.Zu().p(this),this.Um.Mm().p(this),this.iw.S(),this.uu.S(),this.um.S()}scrollPosition(){return this.wl.Iu()}scrollToPosition(t,i){i?this.wl.qu(t,1e3):this.Hi.Zn(t)}scrollToRealTime(){this.wl.Uu()}getVisibleRange(){const t=this.wl.ku();return null===t?null:{from:t.from.originalTime,to:t.to.originalTime}}setVisibleRange(t){const i={from:this.N_.convertHorzItemToInternal(t.from),to:this.N_.convertHorzItemToInternal(t.to)},n=this.wl.Ru(i);this.Hi.ad(n)}getVisibleLogicalRange(){const t=this.wl.yu();return null===t?null:{from:t.Rs(),to:t.ui()}}setVisibleLogicalRange(t){c(t.from<=t.to,"The from index cannot be after the to index."),this.Hi.ad(t)}resetTimeScale(){this.Hi.Xn()}fitContent(){this.Hi.Qu()}logicalToCoordinate(t){const i=this.Hi.St();return i.Li()?null:i.zt(t)}coordinateToLogical(t){return this.wl.Li()?null:this.wl.Bu(t)}timeToCoordinate(t){const i=this.N_.convertHorzItemToInternal(t),n=this.wl.ka(i,!1);return null===n?null:this.wl.zt(n)}coordinateToTime(t){const i=this.Hi.St(),n=i.Bu(t),s=i.$i(n);return null===s?null:s.originalTime}width(){return this.Um.Up().width}height(){return this.Um.Up().height}subscribeVisibleTimeRangeChange(t){this.iw.l(t)}unsubscribeVisibleTimeRangeChange(t){this.iw.v(t)}subscribeVisibleLogicalRangeChange(t){this.uu.l(t)}unsubscribeVisibleLogicalRangeChange(t){this.uu.v(t)}subscribeSizeChange(t){this.um.l(t)}unsubscribeSizeChange(t){this.um.v(t)}applyOptions(t){this.wl.Lh(t)}options(){return Object.assign(Object.assign({},O(this.wl.W())),{barSpacing:this.wl.ee()})}nw(){this.iw.M()&&this.iw.m(this.getVisibleRange())}sw(){this.uu.M()&&this.uu.m(this.getVisibleLogicalRange())}ew(t){this.um.m(t.width,t.height)}}function Ce(t){if(void 0===t||"custom"===t.type)return;const i=t;void 0!==i.minMove&&void 0===i.precision&&(i.precision=function(t){if(t>=1)return 0;let i=0;for(;i<8;i++){const n=Math.round(t);if(Math.abs(n-t)<1e-8)return i;t*=10}return i}(i.minMove))}function Te(t){return function(t){if(D(t.handleScale)){const i=t.handleScale;t.handleScale={axisDoubleClickReset:{time:i,price:i},axisPressedMouseMove:{time:i,price:i},mouseWheel:i,pinch:i}}else if(void 0!==t.handleScale){const{axisPressedMouseMove:i,axisDoubleClickReset:n}=t.handleScale;D(i)&&(t.handleScale.axisPressedMouseMove={time:i,price:i}),D(n)&&(t.handleScale.axisDoubleClickReset={time:n,price:n})}const i=t.handleScroll;D(i)&&(t.handleScroll={horzTouchDrag:i,vertTouchDrag:i,mouseWheel:i,pressedMouseMove:i})}(t),t}class Pe{constructor(t,i,n){this.rw=new Map,this.hw=new Map,this.lw=new k,this.aw=new k,this.ow=new k,this._w=new ne(i);const s=void 0===n?O(we()):C(O(we()),Te(n));this.N_=i,this.Ub=new Fs(t,s,i),this.Ub.Wp().l((t=>{this.lw.M()&&this.lw.m(this.uw(t()))}),this),this.Ub.jp().l((t=>{this.aw.M()&&this.aw.m(this.uw(t()))}),this),this.Ub.jc().l((t=>{this.ow.M()&&this.ow.m(this.uw(t()))}),this);const e=this.Ub.$t();this.cw=new ke(e,this.Ub.Gm(),this.N_)}remove(){this.Ub.Wp().p(this),this.Ub.jp().p(this),this.Ub.jc().p(this),this.cw.S(),this.Ub.S(),this.rw.clear(),this.hw.clear(),this.lw.S(),this.aw.S(),this.ow.S(),this._w.S()}resize(t,i,n){this.autoSizeActive()||this.Ub.Ym(t,i,n)}addCustomSeries(t,i){const n=v(t),s=Object.assign(Object.assign({},h),n.defaultOptions());return this.dw("Custom",s,i,n)}addAreaSeries(t){return this.dw("Area",s,t)}addBaselineSeries(t){return this.dw("Baseline",e,t)}addBarSeries(t){return this.dw("Bar",i,t)}addCandlestickSeries(i={}){return function(t){void 0!==t.borderColor&&(t.borderUpColor=t.borderColor,t.borderDownColor=t.borderColor),void 0!==t.wickColor&&(t.wickUpColor=t.wickColor,t.wickDownColor=t.wickColor)}(i),this.dw("Candlestick",t,i)}addHistogramSeries(t){return this.dw("Histogram",r,t)}addLineSeries(t){return this.dw("Line",n,t)}removeSeries(t){const i=d(this.rw.get(t)),n=this._w.ld(i);this.Ub.$t().ld(i),this.fw(n),this.rw.delete(t),this.hw.delete(i)}Jb(t,i){this.fw(this._w.Bb(t,i))}tw(t,i){this.fw(this._w.Lb(t,i))}subscribeClick(t){this.lw.l(t)}unsubscribeClick(t){this.lw.v(t)}subscribeCrosshairMove(t){this.ow.l(t)}unsubscribeCrosshairMove(t){this.ow.v(t)}subscribeDblClick(t){this.aw.l(t)}unsubscribeDblClick(t){this.aw.v(t)}priceScale(t){return new ge(this.Ub,t)}timeScale(){return this.cw}applyOptions(t){this.Ub.Lh(Te(t))}options(){return this.Ub.W()}takeScreenshot(){return this.Ub.ib()}autoSizeActive(){return this.Ub.hb()}chartElement(){return this.Ub.lb()}paneSize(){const t=this.Ub.ob();return{height:t.height,width:t.width}}setCrosshairPosition(t,i,n){const s=this.rw.get(n);if(void 0===s)return;const e=this.Ub.$t()._r(s);null!==e&&this.Ub.$t().td(t,i,e)}clearCrosshairPosition(){this.Ub.$t().nd(!0)}dw(t,i,n={},s){Ce(n.priceFormat);const e=C(O(l),O(i),n),r=this.Ub.$t().rd(t,e,s),h=new ye(r,this,this,this,this.N_);return this.rw.set(h,r),this.hw.set(r,h),h}fw(t){const i=this.Ub.$t();i.sd(t.St.Au,t.St.Hb,t.St.$b),t.Wb.forEach(((t,i)=>i.J(t.We,t.jb))),i.zu()}pw(t){return d(this.hw.get(t))}uw(t){const i=new Map;t.xb.forEach(((t,n)=>{const s=n.Yh(),e=ue(s)(t);if("Custom"!==s)c(function(t){return void 0!==t.open||void 0!==t.value}(e));else{const t=n.Ma();c(!t||!1===t(e))}i.set(this.pw(n),e)}));const n=void 0===t.Mb?void 0:this.pw(t.Mb);return{time:t.wb,logical:t.ie,point:t.gb,hoveredSeries:n,hoveredObjectId:t.Sb,seriesData:i,sourceEvent:t.yb}}}function Re(t,i,n){let s;if(R(t)){const i=document.getElementById(t);c(null!==i,`Cannot find element in DOM with id=${t}`),s=i}else s=t;const e=new Pe(s,i,n);return i.setOptions(e.options()),e}const De=Object.assign(Object.assign({},l),h);var Oe=Object.freeze({__proto__:null,get ColorType(){return Dn},get CrosshairMode(){return et},get LastPriceAnimationMode(){return Pn},get LineStyle(){return o},get LineType(){return a},get MismatchDirection(){return Ai},get PriceLineSource(){return Rn},get PriceScaleMode(){return un},get TickMarkType(){return On},get TrackingModeExitMode(){return Tn},createChart:function(t,i){return Re(t,new Zn,Zn.Pd(i))},createChartEx:Re,customSeriesDefaultOptions:De,isBusinessDay:Bn,isUTCTimestamp:Vn,version:function(){return"4.1.3"}});window.LightweightCharts=Oe}(); \ No newline at end of file diff --git a/lightweight_charts/js/pkg.js b/lightweight_charts/js/pkg.js deleted file mode 100644 index d759172..0000000 --- a/lightweight_charts/js/pkg.js +++ /dev/null @@ -1,7 +0,0 @@ -/*! - * @license - * TradingView Lightweight Charts™ v4.2.0-dev+202310302149 - * Copyright (c) 2023 TradingView, Inc. - * Licensed under Apache License 2.0 https://www.apache.org/licenses/LICENSE-2.0 - */ -!function(){"use strict";const t={upColor:"#26a69a",downColor:"#ef5350",wickVisible:!0,borderVisible:!0,borderColor:"#378658",borderUpColor:"#26a69a",borderDownColor:"#ef5350",wickColor:"#737375",wickUpColor:"#26a69a",wickDownColor:"#ef5350"},i={upColor:"#26a69a",downColor:"#ef5350",openVisible:!0,thinBars:!0},n={color:"#2196f3",lineStyle:0,lineWidth:3,lineType:0,lineVisible:!0,crosshairMarkerVisible:!0,crosshairMarkerRadius:4,crosshairMarkerBorderColor:"",crosshairMarkerBorderWidth:2,crosshairMarkerBackgroundColor:"",lastPriceAnimation:0,pointMarkersVisible:!1},s={topColor:"rgba( 46, 220, 135, 0.4)",bottomColor:"rgba( 40, 221, 100, 0)",invertFilledArea:!1,lineColor:"#33D778",lineStyle:0,lineWidth:3,lineType:0,lineVisible:!0,crosshairMarkerVisible:!0,crosshairMarkerRadius:4,crosshairMarkerBorderColor:"",crosshairMarkerBorderWidth:2,crosshairMarkerBackgroundColor:"",lastPriceAnimation:0,pointMarkersVisible:!1},e={baseValue:{type:"price",price:0},topFillColor1:"rgba(38, 166, 154, 0.28)",topFillColor2:"rgba(38, 166, 154, 0.05)",topLineColor:"rgba(38, 166, 154, 1)",bottomFillColor1:"rgba(239, 83, 80, 0.05)",bottomFillColor2:"rgba(239, 83, 80, 0.28)",bottomLineColor:"rgba(239, 83, 80, 1)",lineWidth:3,lineStyle:0,lineType:0,lineVisible:!0,crosshairMarkerVisible:!0,crosshairMarkerRadius:4,crosshairMarkerBorderColor:"",crosshairMarkerBorderWidth:2,crosshairMarkerBackgroundColor:"",lastPriceAnimation:0,pointMarkersVisible:!1},r={color:"#26a69a",base:0},h={color:"#2196f3"},l={title:"",visible:!0,lastValueVisible:!0,priceLineVisible:!0,priceLineSource:0,priceLineWidth:1,priceLineColor:"",priceLineStyle:2,baseLineVisible:!0,baseLineWidth:1,baseLineColor:"#B2B5BE",baseLineStyle:0,priceFormat:{type:"price",precision:2,minMove:.01}};var a,o;function _(t,i){const n={0:[],1:[t.lineWidth,t.lineWidth],2:[2*t.lineWidth,2*t.lineWidth],3:[6*t.lineWidth,6*t.lineWidth],4:[t.lineWidth,4*t.lineWidth]}[i];t.setLineDash(n)}function u(t,i,n,s){t.beginPath();const e=t.lineWidth%2?.5:0;t.moveTo(n,i+e),t.lineTo(s,i+e),t.stroke()}function c(t,i){if(!t)throw new Error("Assertion failed"+(i?": "+i:""))}function d(t){if(void 0===t)throw new Error("Value is undefined");return t}function f(t){if(null===t)throw new Error("Value is null");return t}function v(t){return f(d(t))}!function(t){t[t.Simple=0]="Simple",t[t.WithSteps=1]="WithSteps",t[t.Curved=2]="Curved"}(a||(a={})),function(t){t[t.Solid=0]="Solid",t[t.Dotted=1]="Dotted",t[t.Dashed=2]="Dashed",t[t.LargeDashed=3]="LargeDashed",t[t.SparseDotted=4]="SparseDotted"}(o||(o={}));const p={khaki:"#f0e68c",azure:"#f0ffff",aliceblue:"#f0f8ff",ghostwhite:"#f8f8ff",gold:"#ffd700",goldenrod:"#daa520",gainsboro:"#dcdcdc",gray:"#808080",green:"#008000",honeydew:"#f0fff0",floralwhite:"#fffaf0",lightblue:"#add8e6",lightcoral:"#f08080",lemonchiffon:"#fffacd",hotpink:"#ff69b4",lightyellow:"#ffffe0",greenyellow:"#adff2f",lightgoldenrodyellow:"#fafad2",limegreen:"#32cd32",linen:"#faf0e6",lightcyan:"#e0ffff",magenta:"#f0f",maroon:"#800000",olive:"#808000",orange:"#ffa500",oldlace:"#fdf5e6",mediumblue:"#0000cd",transparent:"#0000",lime:"#0f0",lightpink:"#ffb6c1",mistyrose:"#ffe4e1",moccasin:"#ffe4b5",midnightblue:"#191970",orchid:"#da70d6",mediumorchid:"#ba55d3",mediumturquoise:"#48d1cc",orangered:"#ff4500",royalblue:"#4169e1",powderblue:"#b0e0e6",red:"#f00",coral:"#ff7f50",turquoise:"#40e0d0",white:"#fff",whitesmoke:"#f5f5f5",wheat:"#f5deb3",teal:"#008080",steelblue:"#4682b4",bisque:"#ffe4c4",aquamarine:"#7fffd4",aqua:"#0ff",sienna:"#a0522d",silver:"#c0c0c0",springgreen:"#00ff7f",antiquewhite:"#faebd7",burlywood:"#deb887",brown:"#a52a2a",beige:"#f5f5dc",chocolate:"#d2691e",chartreuse:"#7fff00",cornflowerblue:"#6495ed",cornsilk:"#fff8dc",crimson:"#dc143c",cadetblue:"#5f9ea0",tomato:"#ff6347",fuchsia:"#f0f",blue:"#00f",salmon:"#fa8072",blanchedalmond:"#ffebcd",slateblue:"#6a5acd",slategray:"#708090",thistle:"#d8bfd8",tan:"#d2b48c",cyan:"#0ff",darkblue:"#00008b",darkcyan:"#008b8b",darkgoldenrod:"#b8860b",darkgray:"#a9a9a9",blueviolet:"#8a2be2",black:"#000",darkmagenta:"#8b008b",darkslateblue:"#483d8b",darkkhaki:"#bdb76b",darkorchid:"#9932cc",darkorange:"#ff8c00",darkgreen:"#006400",darkred:"#8b0000",dodgerblue:"#1e90ff",darkslategray:"#2f4f4f",dimgray:"#696969",deepskyblue:"#00bfff",firebrick:"#b22222",forestgreen:"#228b22",indigo:"#4b0082",ivory:"#fffff0",lavenderblush:"#fff0f5",feldspar:"#d19275",indianred:"#cd5c5c",lightgreen:"#90ee90",lightgrey:"#d3d3d3",lightskyblue:"#87cefa",lightslategray:"#789",lightslateblue:"#8470ff",snow:"#fffafa",lightseagreen:"#20b2aa",lightsalmon:"#ffa07a",darksalmon:"#e9967a",darkviolet:"#9400d3",mediumpurple:"#9370d8",mediumaquamarine:"#66cdaa",skyblue:"#87ceeb",lavender:"#e6e6fa",lightsteelblue:"#b0c4de",mediumvioletred:"#c71585",mintcream:"#f5fffa",navajowhite:"#ffdead",navy:"#000080",olivedrab:"#6b8e23",palevioletred:"#d87093",violetred:"#d02090",yellow:"#ff0",yellowgreen:"#9acd32",lawngreen:"#7cfc00",pink:"#ffc0cb",paleturquoise:"#afeeee",palegoldenrod:"#eee8aa",darkolivegreen:"#556b2f",darkseagreen:"#8fbc8f",darkturquoise:"#00ced1",peachpuff:"#ffdab9",deeppink:"#ff1493",violet:"#ee82ee",palegreen:"#98fb98",mediumseagreen:"#3cb371",peru:"#cd853f",saddlebrown:"#8b4513",sandybrown:"#f4a460",rosybrown:"#bc8f8f",purple:"#800080",seagreen:"#2e8b57",seashell:"#fff5ee",papayawhip:"#ffefd5",mediumslateblue:"#7b68ee",plum:"#dda0dd",mediumspringgreen:"#00fa9a"};function m(t){return t<0?0:t>255?255:Math.round(t)||0}function b(t){return t<=0||t>0?t<0?0:t>1?1:Math.round(1e4*t)/1e4:0}const w=/^#([0-9a-f])([0-9a-f])([0-9a-f])([0-9a-f])?$/i,g=/^#([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})?$/i,M=/^rgb\(\s*(-?\d{1,10})\s*,\s*(-?\d{1,10})\s*,\s*(-?\d{1,10})\s*\)$/,x=/^rgba\(\s*(-?\d{1,10})\s*,\s*(-?\d{1,10})\s*,\s*(-?\d{1,10})\s*,\s*(-?[\d]{0,10}(?:\.\d+)?)\s*\)$/;function S(t){(t=t.toLowerCase())in p&&(t=p[t]);{const i=x.exec(t)||M.exec(t);if(i)return[m(parseInt(i[1],10)),m(parseInt(i[2],10)),m(parseInt(i[3],10)),b(i.length<5?1:parseFloat(i[4]))]}{const i=g.exec(t);if(i)return[m(parseInt(i[1],16)),m(parseInt(i[2],16)),m(parseInt(i[3],16)),1]}{const i=w.exec(t);if(i)return[m(17*parseInt(i[1],16)),m(17*parseInt(i[2],16)),m(17*parseInt(i[3],16)),1]}throw new Error(`Cannot parse color: ${t}`)}function y(t){const i=S(t);return{t:`rgb(${i[0]}, ${i[1]}, ${i[2]})`,i:(n=i,.199*n[0]+.687*n[1]+.114*n[2]>160?"black":"white")};var n}class k{constructor(){this.h=[]}l(t,i,n){const s={o:t,_:i,u:!0===n};this.h.push(s)}v(t){const i=this.h.findIndex((i=>t===i.o));i>-1&&this.h.splice(i,1)}p(t){this.h=this.h.filter((i=>i._!==t))}m(t,i,n){const s=[...this.h];this.h=this.h.filter((t=>!t.u)),s.forEach((s=>s.o(t,i,n)))}M(){return this.h.length>0}S(){this.h=[]}}function C(t,...i){for(const n of i)for(const i in n)void 0!==n[i]&&("object"!=typeof n[i]||void 0===t[i]||Array.isArray(n[i])?t[i]=n[i]:C(t[i],n[i]));return t}function T(t){return"number"==typeof t&&isFinite(t)}function P(t){return"number"==typeof t&&t%1==0}function R(t){return"string"==typeof t}function D(t){return"boolean"==typeof t}function O(t){const i=t;if(!i||"object"!=typeof i)return i;let n,s,e;for(s in n=Array.isArray(i)?[]:{},i)i.hasOwnProperty(s)&&(e=i[s],n[s]=e&&"object"==typeof e?O(e):e);return n}function A(t){return null!==t}function B(t){return null===t?void 0:t}const V="-apple-system, BlinkMacSystemFont, 'Trebuchet MS', Roboto, Ubuntu, sans-serif";function z(t,i,n){return void 0===i&&(i=V),`${n=void 0!==n?`${n} `:""}${t}px ${i}`}class E{constructor(t){this.k={C:1,T:5,P:NaN,R:"",D:"",O:"",A:"",B:0,V:0,I:0,L:0,N:0},this.F=t}W(){const t=this.k,i=this.j(),n=this.H();return t.P===i&&t.D===n||(t.P=i,t.D=n,t.R=z(i,n),t.L=2.5/12*i,t.B=t.L,t.V=i/12*t.T,t.I=i/12*t.T,t.N=0),t.O=this.$(),t.A=this.U(),this.k}$(){return this.F.W().layout.textColor}U(){return this.F.q()}j(){return this.F.W().layout.fontSize}H(){return this.F.W().layout.fontFamily}}class I{constructor(){this.Y=[]}X(t){this.Y=t}K(t,i,n){this.Y.forEach((s=>{s.K(t,i,n)}))}}class L{K(t,i,n){t.useMediaCoordinateSpace((t=>this.Z(t,i,n)))}G(t,i,n){t.useMediaCoordinateSpace((t=>this.J(t,i,n)))}J(t,i,n){}}class N extends L{constructor(){super(...arguments),this.tt=null}it(t){this.tt=t}Z({context:t}){if(null===this.tt||null===this.tt.nt)return;const i=this.tt.nt,n=this.tt,s=s=>{t.beginPath();for(let e=i.to-1;e>=i.from;--e){const i=n.st[e];t.moveTo(i.et,i.rt),t.arc(i.et,i.rt,s,0,2*Math.PI)}t.fill()};n.ht>0&&(t.fillStyle=n.lt,s(n.ot+n.ht)),t.fillStyle=n._t,s(n.ot)}}function F(){return{st:[{et:0,rt:0,ut:0,ct:0}],_t:"",lt:"",ot:0,ht:0,nt:null}}const W={from:0,to:1};class j{constructor(t,i){this.dt=new I,this.ft=[],this.vt=[],this.bt=!0,this.F=t,this.wt=i,this.dt.X(this.ft)}gt(t){const i=this.F.Mt();i.length!==this.ft.length&&(this.vt=i.map(F),this.ft=this.vt.map((t=>{const i=new N;return i.it(t),i})),this.dt.X(this.ft)),this.bt=!0}xt(){return this.bt&&(this.St(),this.bt=!1),this.dt}St(){const t=2===this.wt.W().mode,i=this.F.Mt(),n=this.wt.yt(),s=this.F.kt();i.forEach(((i,e)=>{var r;const h=this.vt[e],l=i.Ct(n);if(t||null===l||!i.Tt())return void(h.nt=null);const a=f(i.Pt());h._t=l.Rt,h.ot=l.ot,h.ht=l.Dt,h.st[0].ct=l.ct,h.st[0].rt=i.At().Ot(l.ct,a.Bt),h.lt=null!==(r=l.Vt)&&void 0!==r?r:this.F.zt(h.st[0].rt/i.At().Et()),h.st[0].ut=n,h.st[0].et=s.It(n),h.nt=W}))}}class H{K(t,i,n){t.useBitmapCoordinateSpace((t=>this.Z(t,i,n)))}}class $ extends H{constructor(t){super(),this.Lt=t}Z({context:t,bitmapSize:i,horizontalPixelRatio:n,verticalPixelRatio:s}){if(null===this.Lt)return;const e=this.Lt.Nt.Tt,r=this.Lt.Ft.Tt;if(!e&&!r)return;const h=Math.round(this.Lt.et*n),l=Math.round(this.Lt.rt*s);t.lineCap="butt",e&&h>=0&&(t.lineWidth=Math.floor(this.Lt.Nt.ht*n),t.strokeStyle=this.Lt.Nt.O,t.fillStyle=this.Lt.Nt.O,_(t,this.Lt.Nt.Wt),function(t,i,n,s){t.beginPath();const e=t.lineWidth%2?.5:0;t.moveTo(i+e,n),t.lineTo(i+e,s),t.stroke()}(t,h,0,i.height)),r&&l>=0&&(t.lineWidth=Math.floor(this.Lt.Ft.ht*s),t.strokeStyle=this.Lt.Ft.O,t.fillStyle=this.Lt.Ft.O,_(t,this.Lt.Ft.Wt),u(t,l,0,i.width))}}class U{constructor(t){this.bt=!0,this.jt={Nt:{ht:1,Wt:0,O:"",Tt:!1},Ft:{ht:1,Wt:0,O:"",Tt:!1},et:0,rt:0},this.Ht=new $(this.jt),this.$t=t}gt(){this.bt=!0}xt(){return this.bt&&(this.St(),this.bt=!1),this.Ht}St(){const t=this.$t.Tt(),i=f(this.$t.Ut()),n=i.qt().W().crosshair,s=this.jt;if(2===n.mode)return s.Ft.Tt=!1,void(s.Nt.Tt=!1);s.Ft.Tt=t&&this.$t.Yt(i),s.Nt.Tt=t&&this.$t.Xt(),s.Ft.ht=n.horzLine.width,s.Ft.Wt=n.horzLine.style,s.Ft.O=n.horzLine.color,s.Nt.ht=n.vertLine.width,s.Nt.Wt=n.vertLine.style,s.Nt.O=n.vertLine.color,s.et=this.$t.Kt(),s.rt=this.$t.Zt()}}function q(t,i,n,s,e,r){t.fillRect(i+r,n,s-2*r,r),t.fillRect(i+r,n+e-r,s-2*r,r),t.fillRect(i,n,r,e),t.fillRect(i+s-r,n,r,e)}function Y(t,i,n,s,e,r){t.save(),t.globalCompositeOperation="copy",t.fillStyle=r,t.fillRect(i,n,s,e),t.restore()}function X(t,i){return t.map((t=>0===t?t:t+i))}function K(t,i,n,s,e,r){t.beginPath(),t.lineTo(i+s-r[1],n),0!==r[1]&&t.arcTo(i+s,n,i+s,n+r[1],r[1]),t.lineTo(i+s,n+e-r[2]),0!==r[2]&&t.arcTo(i+s,n+e,i+s-r[2],n+e,r[2]),t.lineTo(i+r[3],n+e),0!==r[3]&&t.arcTo(i,n+e,i,n+e-r[3],r[3]),t.lineTo(i,n+r[0]),0!==r[0]&&t.arcTo(i,n,i+r[0],n,r[0])}function Z(t,i,n,s,e,r,h=0,l=[0,0,0,0],a=""){if(t.save(),!h||!a||a===r)return K(t,i,n,s,e,l),t.fillStyle=r,t.fill(),void t.restore();const o=h/2;if("transparent"!==r){K(t,i+h,n+h,s-2*h,e-2*h,X(l,-h)),t.fillStyle=r,t.fill()}if("transparent"!==a){K(t,i+o,n+o,s-h,e-h,X(l,-o)),t.lineWidth=h,t.strokeStyle=a,t.closePath(),t.stroke()}t.restore()}function G(t,i,n,s,e,r,h){t.save(),t.globalCompositeOperation="copy";const l=t.createLinearGradient(0,0,0,e);l.addColorStop(0,r),l.addColorStop(1,h),t.fillStyle=l,t.fillRect(i,n,s,e),t.restore()}class J{constructor(t,i){this.it(t,i)}it(t,i){this.Lt=t,this.Gt=i}Et(t,i){return this.Lt.Tt?t.P+t.L+t.B:0}K(t,i,n,s){if(!this.Lt.Tt||0===this.Lt.Jt.length)return;const e=this.Lt.O,r=this.Gt.t,h=t.useBitmapCoordinateSpace((t=>{const h=t.context;h.font=i.R;const l=this.Qt(t,i,n,s),a=l.ti,o=(t,i)=>{l.ii?Z(h,a.ni,a.si,a.ei,a.ri,t,a.hi,[a.ot,0,0,a.ot],i):Z(h,a.li,a.si,a.ei,a.ri,t,a.hi,[0,a.ot,a.ot,0],i)};return o(r,"transparent"),this.Lt.ai&&(h.fillStyle=e,h.fillRect(a.li,a.oi,a._i-a.li,a.ui)),o("transparent",r),this.Lt.ci&&(h.fillStyle=i.A,h.fillRect(l.ii?a.di-a.hi:0,a.si,a.hi,a.fi-a.si)),l}));t.useMediaCoordinateSpace((({context:t})=>{const n=h.vi;t.font=i.R,t.textAlign=h.ii?"right":"left",t.textBaseline="middle",t.fillStyle=e,t.fillText(this.Lt.Jt,n.pi,(n.si+n.fi)/2+n.mi)}))}Qt(t,i,n,s){var e;const{context:r,bitmapSize:h,mediaSize:l,horizontalPixelRatio:a,verticalPixelRatio:o}=t,_=this.Lt.ai||!this.Lt.bi?i.T:0,u=this.Lt.wi?i.C:0,c=i.L+this.Gt.gi,d=i.B+this.Gt.Mi,f=i.V,v=i.I,p=this.Lt.Jt,m=i.P,b=n.xi(r,p),w=Math.ceil(n.Si(r,p)),g=m+c+d,M=i.C+f+v+w+_,x=Math.max(1,Math.floor(o));let S=Math.round(g*o);S%2!=x%2&&(S+=1);const y=u>0?Math.max(1,Math.floor(u*a)):0,k=Math.round(M*a),C=Math.round(_*a),T=null!==(e=this.Gt.yi)&&void 0!==e?e:this.Gt.ki,P=Math.round(T*o)-Math.floor(.5*o),R=Math.floor(P+x/2-S/2),D=R+S,O="right"===s,A=O?l.width-u:u,B=O?h.width-y:y;let V,z,E;return O?(V=B-k,z=B-C,E=A-_-f-u):(V=B+k,z=B+C,E=A+_+f),{ii:O,ti:{si:R,oi:P,fi:D,ei:k,ri:S,ot:2*a,hi:y,ni:V,li:B,_i:z,ui:x,di:h.width},vi:{si:R/o,fi:D/o,pi:E,mi:b}}}}class Q{constructor(t){this.Ci={ki:0,t:"#000",Mi:0,gi:0},this.Ti={Jt:"",Tt:!1,ai:!0,bi:!1,Vt:"",O:"#FFF",ci:!1,wi:!1},this.Pi={Jt:"",Tt:!1,ai:!1,bi:!0,Vt:"",O:"#FFF",ci:!0,wi:!0},this.bt=!0,this.Ri=new(t||J)(this.Ti,this.Ci),this.Di=new(t||J)(this.Pi,this.Ci)}Jt(){return this.Oi(),this.Ti.Jt}ki(){return this.Oi(),this.Ci.ki}gt(){this.bt=!0}Et(t,i=!1){return Math.max(this.Ri.Et(t,i),this.Di.Et(t,i))}Ai(){return this.Ci.yi||0}Bi(t){this.Ci.yi=t}Vi(){return this.Oi(),this.Ti.Tt||this.Pi.Tt}zi(){return this.Oi(),this.Ti.Tt}xt(t){return this.Oi(),this.Ti.ai=this.Ti.ai&&t.W().ticksVisible,this.Pi.ai=this.Pi.ai&&t.W().ticksVisible,this.Ri.it(this.Ti,this.Ci),this.Di.it(this.Pi,this.Ci),this.Ri}Ei(){return this.Oi(),this.Ri.it(this.Ti,this.Ci),this.Di.it(this.Pi,this.Ci),this.Di}Oi(){this.bt&&(this.Ti.ai=!0,this.Pi.ai=!1,this.Ii(this.Ti,this.Pi,this.Ci))}}class tt extends Q{constructor(t,i,n){super(),this.$t=t,this.Li=i,this.Ni=n}Ii(t,i,n){if(t.Tt=!1,2===this.$t.W().mode)return;const s=this.$t.W().horzLine;if(!s.labelVisible)return;const e=this.Li.Pt();if(!this.$t.Tt()||this.Li.Fi()||null===e)return;const r=y(s.labelBackgroundColor);n.t=r.t,t.O=r.i;const h=2/12*this.Li.P();n.gi=h,n.Mi=h;const l=this.Ni(this.Li);n.ki=l.ki,t.Jt=this.Li.Wi(l.ct,e),t.Tt=!0}}const it=/[1-9]/g;class nt{constructor(){this.Lt=null}it(t){this.Lt=t}K(t,i){if(null===this.Lt||!1===this.Lt.Tt||0===this.Lt.Jt.length)return;const n=t.useMediaCoordinateSpace((({context:t})=>(t.font=i.R,Math.round(i.ji.Si(t,f(this.Lt).Jt,it)))));if(n<=0)return;const s=i.Hi,e=n+2*s,r=e/2,h=this.Lt.$i;let l=this.Lt.ki,a=Math.floor(l-r)+.5;a<0?(l+=Math.abs(0-a),a=Math.floor(l-r)+.5):a+e>h&&(l-=Math.abs(h-(a+e)),a=Math.floor(l-r)+.5);const o=a+e,_=Math.ceil(0+i.C+i.T+i.L+i.P+i.B);t.useBitmapCoordinateSpace((({context:t,horizontalPixelRatio:n,verticalPixelRatio:s})=>{const e=f(this.Lt);t.fillStyle=e.t;const r=Math.round(a*n),h=Math.round(0*s),l=Math.round(o*n),u=Math.round(_*s),c=Math.round(2*n);if(t.beginPath(),t.moveTo(r,h),t.lineTo(r,u-c),t.arcTo(r,u,r+c,u,c),t.lineTo(l-c,u),t.arcTo(l,u,l,u-c,c),t.lineTo(l,h),t.fill(),e.ai){const r=Math.round(e.ki*n),l=h,a=Math.round((l+i.T)*s);t.fillStyle=e.O;const o=Math.max(1,Math.floor(n)),_=Math.floor(.5*n);t.fillRect(r-_,l,o,a-l)}})),t.useMediaCoordinateSpace((({context:t})=>{const n=f(this.Lt),e=0+i.C+i.T+i.L+i.P/2;t.font=i.R,t.textAlign="left",t.textBaseline="middle",t.fillStyle=n.O;const r=i.ji.xi(t,"Apr0");t.translate(a+s,e+r),t.fillText(n.Jt,0,0)}))}}class st{constructor(t,i,n){this.bt=!0,this.Ht=new nt,this.jt={Tt:!1,t:"#4c525e",O:"white",Jt:"",$i:0,ki:NaN,ai:!0},this.wt=t,this.Ui=i,this.Ni=n}gt(){this.bt=!0}xt(){return this.bt&&(this.St(),this.bt=!1),this.Ht.it(this.jt),this.Ht}St(){const t=this.jt;if(t.Tt=!1,2===this.wt.W().mode)return;const i=this.wt.W().vertLine;if(!i.labelVisible)return;const n=this.Ui.kt();if(n.Fi())return;t.$i=n.$i();const s=this.Ni();if(null===s)return;t.ki=s.ki;const e=n.qi(this.wt.yt());t.Jt=n.Yi(f(e)),t.Tt=!0;const r=y(i.labelBackgroundColor);t.t=r.t,t.O=r.i,t.ai=n.W().ticksVisible}}class et{constructor(){this.Xi=null,this.Ki=0}Zi(){return this.Ki}Gi(t){this.Ki=t}At(){return this.Xi}Ji(t){this.Xi=t}Qi(t){return[]}tn(){return[]}Tt(){return!0}}var rt;!function(t){t[t.Normal=0]="Normal",t[t.Magnet=1]="Magnet",t[t.Hidden=2]="Hidden"}(rt||(rt={}));class ht extends et{constructor(t,i){super(),this.nn=null,this.sn=NaN,this.en=0,this.rn=!0,this.hn=new Map,this.ln=!1,this.an=NaN,this.on=NaN,this._n=NaN,this.un=NaN,this.Ui=t,this.cn=i,this.dn=new j(t,this);this.fn=((t,i)=>n=>{const s=i(),e=t();if(n===f(this.nn).vn())return{ct:e,ki:s};{const t=f(n.Pt());return{ct:n.pn(s,t),ki:s}}})((()=>this.sn),(()=>this.on));const n=((t,i)=>()=>{const n=this.Ui.kt().mn(t()),s=i();return n&&Number.isFinite(s)?{ut:n,ki:s}:null})((()=>this.en),(()=>this.Kt()));this.bn=new st(this,t,n),this.wn=new U(this)}W(){return this.cn}gn(t,i){this._n=t,this.un=i}Mn(){this._n=NaN,this.un=NaN}xn(){return this._n}Sn(){return this.un}yn(t,i,n){this.ln||(this.ln=!0),this.rn=!0,this.kn(t,i,n)}yt(){return this.en}Kt(){return this.an}Zt(){return this.on}Tt(){return this.rn}Cn(){this.rn=!1,this.Tn(),this.sn=NaN,this.an=NaN,this.on=NaN,this.nn=null,this.Mn()}Pn(t){return null!==this.nn?[this.wn,this.dn]:[]}Yt(t){return t===this.nn&&this.cn.horzLine.visible}Xt(){return this.cn.vertLine.visible}Rn(t,i){this.rn&&this.nn===t||this.hn.clear();const n=[];return this.nn===t&&n.push(this.Dn(this.hn,i,this.fn)),n}tn(){return this.rn?[this.bn]:[]}Ut(){return this.nn}On(){this.wn.gt(),this.hn.forEach((t=>t.gt())),this.bn.gt(),this.dn.gt()}An(t){return t&&!t.vn().Fi()?t.vn():null}kn(t,i,n){this.Bn(t,i,n)&&this.On()}Bn(t,i,n){const s=this.an,e=this.on,r=this.sn,h=this.en,l=this.nn,a=this.An(n);this.en=t,this.an=isNaN(t)?NaN:this.Ui.kt().It(t),this.nn=n;const o=null!==a?a.Pt():null;return null!==a&&null!==o?(this.sn=i,this.on=a.Ot(i,o)):(this.sn=NaN,this.on=NaN),s!==this.an||e!==this.on||h!==this.en||r!==this.sn||l!==this.nn}Tn(){const t=this.Ui.Mt().map((t=>t.zn().Vn())).filter(A),i=0===t.length?null:Math.max(...t);this.en=null!==i?i:NaN}Dn(t,i,n){let s=t.get(i);return void 0===s&&(s=new tt(this,i,n),t.set(i,s)),s}}function lt(t){return"left"===t||"right"===t}class at{constructor(t){this.En=new Map,this.In=[],this.Ln=t}Nn(t,i){const n=function(t,i){return void 0===t?i:{Fn:Math.max(t.Fn,i.Fn),Wn:t.Wn||i.Wn}}(this.En.get(t),i);this.En.set(t,n)}jn(){return this.Ln}Hn(t){const i=this.En.get(t);return void 0===i?{Fn:this.Ln}:{Fn:Math.max(this.Ln,i.Fn),Wn:i.Wn}}$n(){this.Un(),this.In=[{qn:0}]}Yn(t){this.Un(),this.In=[{qn:1,Bt:t}]}Xn(t){this.Kn(),this.In.push({qn:5,Bt:t})}Un(){this.Kn(),this.In.push({qn:6})}Zn(){this.Un(),this.In=[{qn:4}]}Gn(t){this.Un(),this.In.push({qn:2,Bt:t})}Jn(t){this.Un(),this.In.push({qn:3,Bt:t})}Qn(){return this.In}ts(t){for(const i of t.In)this.ns(i);this.Ln=Math.max(this.Ln,t.Ln),t.En.forEach(((t,i)=>{this.Nn(i,t)}))}static ss(){return new at(2)}static es(){return new at(3)}ns(t){switch(t.qn){case 0:this.$n();break;case 1:this.Yn(t.Bt);break;case 2:this.Gn(t.Bt);break;case 3:this.Jn(t.Bt);break;case 4:this.Zn();break;case 5:this.Xn(t.Bt);break;case 6:this.Kn()}}Kn(){const t=this.In.findIndex((t=>5===t.qn));-1!==t&&this.In.splice(t,1)}}const ot=".";function _t(t,i){if(!T(t))return"n/a";if(!P(i))throw new TypeError("invalid length");if(i<0||i>16)throw new TypeError("invalid length");if(0===i)return t.toString();return("0000000000000000"+t.toString()).slice(-i)}class ut{constructor(t,i){if(i||(i=1),T(t)&&P(t)||(t=100),t<0)throw new TypeError("invalid base");this.Li=t,this.rs=i,this.hs()}format(t){const i=t<0?"−":"";return t=Math.abs(t),i+this.ls(t)}hs(){if(this.os=0,this.Li>0&&this.rs>0){let t=this.Li;for(;t>1;)t/=10,this.os++}}ls(t){const i=this.Li/this.rs;let n=Math.floor(t),s="";const e=void 0!==this.os?this.os:NaN;if(i>1){let r=+(Math.round(t*i)-n*i).toFixed(this.os);r>=i&&(r-=i,n+=1),s=ot+_t(+r.toFixed(this.os)*this.rs,e)}else n=Math.round(n*i)/i,e>0&&(s=ot+_t(0,e));return n.toFixed(0)+s}}class ct extends ut{constructor(t=100){super(t)}format(t){return`${super.format(t)}%`}}class dt{constructor(t){this._s=t}format(t){let i="";return t<0&&(i="-",t=-t),t<995?i+this.us(t):t<999995?i+this.us(t/1e3)+"K":t<999999995?(t=1e3*Math.round(t/1e3),i+this.us(t/1e6)+"M"):(t=1e6*Math.round(t/1e6),i+this.us(t/1e9)+"B")}us(t){let i;const n=Math.pow(10,this._s);return i=(t=Math.round(t*n)/n)>=1e-15&&t<1?t.toFixed(this._s).replace(/\.?0+$/,""):String(t),i.replace(/(\.[1-9]*)0+$/,((t,i)=>i))}}function ft(t,i,n,s,e,r,h){if(0===i.length||s.from>=i.length||s.to<=0)return;const{context:l,horizontalPixelRatio:a,verticalPixelRatio:o}=t,_=i[s.from];let u=r(t,_),c=_;if(s.to-s.from<2){const i=e/2;l.beginPath();const n={et:_.et-i,rt:_.rt},s={et:_.et+i,rt:_.rt};l.moveTo(n.et*a,n.rt*o),l.lineTo(s.et*a,s.rt*o),h(t,u,n,s)}else{const e=(i,n)=>{h(t,u,c,n),l.beginPath(),u=i,c=n};let d=c;l.beginPath(),l.moveTo(_.et*a,_.rt*o);for(let h=s.from+1;h=s.from;--n){const s=i[n];if(s){const i=e(t,s);i!==a&&(l.beginPath(),null!==a&&l.fill(),l.fillStyle=i,a=i);const n=Math.round(s.et*r)+o,u=s.rt*h;l.moveTo(n,u),l.arc(n,u,_,0,2*Math.PI)}}l.fill()}(t,i,l,n,o)}}class Pt extends Tt{Ds(t,i){return i._t}}function Rt(t,i,n,s,e=0,r=i.length){let h=r-e;for(;0>1,l=e+r;s(i[l],n)===t?(e=l+1,h-=r+1):h=r}return e}const Dt=Rt.bind(null,!0),Ot=Rt.bind(null,!1);function At(t,i){return t.ut0&&r=s&&(l=r-1),h>0&&hObject.assign(Object.assign({},t),this.Is.$s().Hs(t.ut))))}Us(){this.Es=null}Fs(){this.Bs&&(this.qs(),this.Bs=!1),this.Vs&&(this.js(),this.Vs=!1),this.As&&(this.Ys(),this.As=!1)}Ys(){const t=this.Is.At(),i=this.Ls.kt();if(this.Us(),i.Fi()||t.Fi())return;const n=i.Xs();if(null===n)return;if(0===this.Is.zn().Ks())return;const s=this.Is.Pt();null!==s&&(this.Es=Vt(this.zs,n,this.Ns),this.Zs(t,i,s.Bt),this.Gs())}}class Et extends zt{constructor(t,i){super(t,i,!0)}Zs(t,i,n){i.Js(this.zs,B(this.Es)),t.Qs(this.zs,n,B(this.Es))}te(t,i){return{ut:t,ct:i,et:NaN,rt:NaN}}qs(){const t=this.Is.$s();this.zs=this.Is.zn().ie().map((i=>{const n=i.Bt[3];return this.ne(i.se,n,t)}))}}class It extends Et{constructor(t,i){super(t,i),this.Ws=new I,this.ee=new kt,this.re=new Pt,this.Ws.X([this.ee,this.re])}ne(t,i,n){return Object.assign(Object.assign({},this.te(t,i)),n.Hs(t))}Gs(){const t=this.Is.W();this.ee.it({ds:t.lineType,st:this.zs,Wt:t.lineStyle,ht:t.lineWidth,fs:null,vs:t.invertFilledArea,nt:this.Es,cs:this.Ls.kt().he()}),this.re.it({ds:t.lineVisible?t.lineType:void 0,st:this.zs,Wt:t.lineStyle,ht:t.lineWidth,nt:this.Es,cs:this.Ls.kt().he(),Rs:t.pointMarkersVisible?t.pointMarkersRadius||t.lineWidth/2+2:void 0})}}class Lt extends H{constructor(){super(...arguments),this.Lt=null,this.le=0,this.ae=0}it(t){this.Lt=t}Z({context:t,horizontalPixelRatio:i,verticalPixelRatio:n}){if(null===this.Lt||0===this.Lt.zn.length||null===this.Lt.nt)return;if(this.le=this.oe(i),this.le>=2){Math.max(1,Math.floor(i))%2!=this.le%2&&this.le--}this.ae=this.Lt._e?Math.min(this.le,Math.floor(i)):this.le;let s=null;const e=this.ae<=this.le&&this.Lt.he>=Math.floor(1.5*i);for(let r=this.Lt.nt.from;rf+p-1&&(e=f+p-1,s=e-_+1),t.fillRect(i,s,o-i,e-s+1)}const i=a+m;let s=Math.max(f,Math.round(h.pe*n)-l),e=s+_-1;e>f+p-1&&(e=f+p-1,s=e-_+1),t.fillRect(u+1,s,i-u,e-s+1)}}}oe(t){const i=Math.floor(t);return Math.max(i,Math.floor(function(t,i){return Math.floor(.3*t*i)}(f(this.Lt).he,t)))}}class Nt extends zt{constructor(t,i){super(t,i,!1)}Zs(t,i,n){i.Js(this.zs,B(this.Es)),t.me(this.zs,n,B(this.Es))}be(t,i,n){return{ut:t,we:i.Bt[0],ge:i.Bt[1],Me:i.Bt[2],xe:i.Bt[3],et:NaN,ve:NaN,ce:NaN,de:NaN,pe:NaN}}qs(){const t=this.Is.$s();this.zs=this.Is.zn().ie().map((i=>this.ne(i.se,i,t)))}}class Ft extends Nt{constructor(){super(...arguments),this.Ws=new Lt}ne(t,i,n){return Object.assign(Object.assign({},this.be(t,i,n)),n.Hs(t))}Gs(){const t=this.Is.W();this.Ws.it({zn:this.zs,he:this.Ls.kt().he(),fe:t.openVisible,_e:t.thinBars,nt:this.Es})}}class Wt extends gt{constructor(){super(...arguments),this.Cs=new yt}ps(t,i){const n=this.tt;return this.Cs.bs(t,{gs:i.Se,Ms:i.ye,xs:i.ke,Ss:i.Ce,ys:t.bitmapSize.height,fs:n.fs})}}class jt extends Tt{constructor(){super(...arguments),this.Te=new yt}Ds(t,i){const n=this.tt;return this.Te.bs(t,{gs:i.Pe,Ms:i.Pe,xs:i.Re,Ss:i.Re,ys:t.bitmapSize.height,fs:n.fs})}}class Ht extends Et{constructor(t,i){super(t,i),this.Ws=new I,this.De=new Wt,this.Oe=new jt,this.Ws.X([this.De,this.Oe])}ne(t,i,n){return Object.assign(Object.assign({},this.te(t,i)),n.Hs(t))}Gs(){const t=this.Is.Pt();if(null===t)return;const i=this.Is.W(),n=this.Is.At().Ot(i.baseValue.price,t.Bt),s=this.Ls.kt().he();this.De.it({st:this.zs,ht:i.lineWidth,Wt:i.lineStyle,ds:i.lineType,fs:n,vs:!1,nt:this.Es,cs:s}),this.Oe.it({st:this.zs,ht:i.lineWidth,Wt:i.lineStyle,ds:i.lineVisible?i.lineType:void 0,Rs:i.pointMarkersVisible?i.pointMarkersRadius||i.lineWidth/2+2:void 0,fs:n,nt:this.Es,cs:s})}}class $t extends H{constructor(){super(...arguments),this.Lt=null,this.le=0}it(t){this.Lt=t}Z(t){if(null===this.Lt||0===this.Lt.zn.length||null===this.Lt.nt)return;const{horizontalPixelRatio:i}=t;if(this.le=function(t,i){if(t>=2.5&&t<=4)return Math.floor(3*i);const n=1-.2*Math.atan(Math.max(4,t)-4)/(.5*Math.PI),s=Math.floor(t*n*i),e=Math.floor(t*i),r=Math.min(s,e);return Math.max(Math.floor(i),r)}(this.Lt.he,i),this.le>=2){Math.floor(i)%2!=this.le%2&&this.le--}const n=this.Lt.zn;this.Lt.Ae&&this.Be(t,n,this.Lt.nt),this.Lt.ci&&this.Ve(t,n,this.Lt.nt);const s=this.ze(i);(!this.Lt.ci||this.le>2*s)&&this.Ee(t,n,this.Lt.nt)}Be(t,i,n){if(null===this.Lt)return;const{context:s,horizontalPixelRatio:e,verticalPixelRatio:r}=t;let h="",l=Math.min(Math.floor(e),Math.floor(this.Lt.he*e));l=Math.max(Math.floor(e),Math.min(l,this.le));const a=Math.floor(.5*l);let o=null;for(let t=n.from;t2*l)q(s,o,u,_-o+1,c-u+1,l);else{const t=_-o+1;s.fillRect(o,u,t,c-u+1)}a=_}}Ee(t,i,n){if(null===this.Lt)return;const{context:s,horizontalPixelRatio:e,verticalPixelRatio:r}=t;let h="";const l=this.ze(e);for(let t=n.from;to||s.fillRect(_,a,u-_+1,o-a+1)}}}class Ut extends Nt{constructor(){super(...arguments),this.Ws=new $t}ne(t,i,n){return Object.assign(Object.assign({},this.be(t,i,n)),n.Hs(t))}Gs(){const t=this.Is.W();this.Ws.it({zn:this.zs,he:this.Ls.kt().he(),Ae:t.wickVisible,ci:t.borderVisible,nt:this.Es})}}class qt{constructor(t,i){this.Ne=t,this.Li=i}K(t,i,n){this.Ne.draw(t,this.Li,i,n)}}class Yt extends zt{constructor(t,i,n){super(t,i,!1),this.wn=n,this.Ws=new qt(this.wn.renderer(),(i=>{const n=t.Pt();return null===n?null:t.At().Ot(i,n.Bt)}))}Fe(t){return this.wn.priceValueBuilder(t)}We(t){return this.wn.isWhitespace(t)}qs(){const t=this.Is.$s();this.zs=this.Is.zn().ie().map((i=>Object.assign(Object.assign({ut:i.se,et:NaN},t.Hs(i.se)),{je:i.He})))}Zs(t,i){i.Js(this.zs,B(this.Es))}Gs(){this.wn.update({bars:this.zs.map(Xt),barSpacing:this.Ls.kt().he(),visibleRange:this.Es},this.Is.W())}}function Xt(t){return{x:t.et,time:t.ut,originalData:t.je,barColor:t.ue}}class Kt extends H{constructor(){super(...arguments),this.Lt=null,this.$e=[]}it(t){this.Lt=t,this.$e=[]}Z({context:t,horizontalPixelRatio:i,verticalPixelRatio:n}){if(null===this.Lt||0===this.Lt.st.length||null===this.Lt.nt)return;this.$e.length||this.Ue(i);const s=Math.max(1,Math.floor(n)),e=Math.round(this.Lt.qe*n)-Math.floor(s/2),r=e+s;for(let i=this.Lt.nt.from;is.Xe?s.di=n.Os-i-1:n.Os=s.di+i+1))}let s=Math.ceil(this.Lt.he*t);for(let t=this.Lt.nt.from;t0&&s<4)for(let t=this.Lt.nt.from;ts&&(i.Ye>i.Xe?i.di-=1:i.Os+=1)}}}class Zt extends Et{constructor(){super(...arguments),this.Ws=new Kt}ne(t,i,n){return Object.assign(Object.assign({},this.te(t,i)),n.Hs(t))}Gs(){const t={st:this.zs,he:this.Ls.kt().he(),nt:this.Es,qe:this.Is.At().Ot(this.Is.W().base,f(this.Is.Pt()).Bt)};this.Ws.it(t)}}class Gt extends Et{constructor(){super(...arguments),this.Ws=new Pt}ne(t,i,n){return Object.assign(Object.assign({},this.te(t,i)),n.Hs(t))}Gs(){const t=this.Is.W(),i={st:this.zs,Wt:t.lineStyle,ds:t.lineVisible?t.lineType:void 0,ht:t.lineWidth,Rs:t.pointMarkersVisible?t.pointMarkersRadius||t.lineWidth/2+2:void 0,nt:this.Es,cs:this.Ls.kt().he()};this.Ws.it(i)}}const Jt=/[2-9]/g;class Qt{constructor(t=50){this.Ke=0,this.Ze=1,this.Ge=1,this.Je={},this.Qe=new Map,this.tr=t}ir(){this.Ke=0,this.Qe.clear(),this.Ze=1,this.Ge=1,this.Je={}}Si(t,i,n){return this.nr(t,i,n).width}xi(t,i,n){const s=this.nr(t,i,n);return((s.actualBoundingBoxAscent||0)-(s.actualBoundingBoxDescent||0))/2}nr(t,i,n){const s=n||Jt,e=String(i).replace(s,"0");if(this.Qe.has(e))return d(this.Qe.get(e)).sr;if(this.Ke===this.tr){const t=this.Je[this.Ge];delete this.Je[this.Ge],this.Qe.delete(t),this.Ge++,this.Ke--}t.save(),t.textBaseline="middle";const r=t.measureText(e);return t.restore(),0===r.width&&i.length||(this.Qe.set(e,{sr:r,er:this.Ze}),this.Je[this.Ze]=e,this.Ke++,this.Ze++),r}}class ti{constructor(t){this.rr=null,this.k=null,this.hr="right",this.lr=t}ar(t,i,n){this.rr=t,this.k=i,this.hr=n}K(t){null!==this.k&&null!==this.rr&&this.rr.K(t,this.k,this.lr,this.hr)}}class ii{constructor(t,i,n){this._r=t,this.lr=new Qt(50),this.ur=i,this.F=n,this.j=-1,this.Ht=new ti(this.lr)}xt(){const t=this.F.cr(this.ur);if(null===t)return null;const i=t.dr(this.ur)?t.vr():this.ur.At();if(null===i)return null;const n=t.pr(i);if("overlay"===n)return null;const s=this.F.mr();return s.P!==this.j&&(this.j=s.P,this.lr.ir()),this.Ht.ar(this._r.Ei(),s,n),this.Ht}}class ni extends H{constructor(){super(...arguments),this.Lt=null}it(t){this.Lt=t}br(t,i){var n;if(!(null===(n=this.Lt)||void 0===n?void 0:n.Tt))return null;const{rt:s,ht:e,wr:r}=this.Lt;return i>=s-e-7&&i<=s+e+7?{gr:this.Lt,wr:r}:null}Z({context:t,bitmapSize:i,horizontalPixelRatio:n,verticalPixelRatio:s}){if(null===this.Lt)return;if(!1===this.Lt.Tt)return;const e=Math.round(this.Lt.rt*s);e<0||e>i.height||(t.lineCap="butt",t.strokeStyle=this.Lt.O,t.lineWidth=Math.floor(this.Lt.ht*n),_(t,this.Lt.Wt),u(t,e,0,i.width))}}class si{constructor(t){this.Mr={rt:0,O:"rgba(0, 0, 0, 0)",ht:1,Wt:0,Tt:!1},this.Sr=new ni,this.bt=!0,this.Is=t,this.Ls=t.qt(),this.Sr.it(this.Mr)}gt(){this.bt=!0}xt(){return this.Is.Tt()?(this.bt&&(this.yr(),this.bt=!1),this.Sr):null}}class ei extends si{constructor(t){super(t)}yr(){this.Mr.Tt=!1;const t=this.Is.At(),i=t.kr().kr;if(2!==i&&3!==i)return;const n=this.Is.W();if(!n.baseLineVisible||!this.Is.Tt())return;const s=this.Is.Pt();null!==s&&(this.Mr.Tt=!0,this.Mr.rt=t.Ot(s.Bt,s.Bt),this.Mr.O=n.baseLineColor,this.Mr.ht=n.baseLineWidth,this.Mr.Wt=n.baseLineStyle)}}class ri extends H{constructor(){super(...arguments),this.Lt=null}it(t){this.Lt=t}He(){return this.Lt}Z({context:t,horizontalPixelRatio:i,verticalPixelRatio:n}){const s=this.Lt;if(null===s)return;const e=Math.max(1,Math.floor(i)),r=e%2/2,h=Math.round(s.Xe.x*i)+r,l=s.Xe.y*n;t.fillStyle=s.Cr,t.beginPath();const a=Math.max(2,1.5*s.Tr)*i;t.arc(h,l,a,0,2*Math.PI,!1),t.fill(),t.fillStyle=s.Pr,t.beginPath(),t.arc(h,l,s.ot*i,0,2*Math.PI,!1),t.fill(),t.lineWidth=e,t.strokeStyle=s.Rr,t.beginPath(),t.arc(h,l,s.ot*i+e/2,0,2*Math.PI,!1),t.stroke()}}const hi=[{Dr:0,Or:.25,Ar:4,Br:10,Vr:.25,zr:0,Er:.4,Ir:.8},{Dr:.25,Or:.525,Ar:10,Br:14,Vr:0,zr:0,Er:.8,Ir:0},{Dr:.525,Or:1,Ar:14,Br:14,Vr:0,zr:0,Er:0,Ir:0}];function li(t,i,n,s){return function(t,i){if("transparent"===t)return t;const n=S(t),s=n[3];return`rgba(${n[0]}, ${n[1]}, ${n[2]}, ${i*s})`}(t,n+(s-n)*i)}function ai(t,i){const n=t%2600/2600;let s;for(const t of hi)if(n>=t.Dr&&n<=t.Or){s=t;break}c(void 0!==s,"Last price animation internal logic error");const e=(n-s.Dr)/(s.Or-s.Dr);return{Pr:li(i,e,s.Vr,s.zr),Rr:li(i,e,s.Er,s.Ir),ot:(r=e,h=s.Ar,l=s.Br,h+(l-h)*r)};var r,h,l}class oi{constructor(t){this.Ht=new ri,this.bt=!0,this.Lr=!0,this.Nr=performance.now(),this.Fr=this.Nr-1,this.Wr=t}jr(){this.Fr=this.Nr-1,this.gt()}Hr(){if(this.gt(),2===this.Wr.W().lastPriceAnimation){const t=performance.now(),i=this.Fr-t;if(i>0)return void(i<650&&(this.Fr+=2600));this.Nr=t,this.Fr=t+2600}}gt(){this.bt=!0}$r(){this.Lr=!0}Tt(){return 0!==this.Wr.W().lastPriceAnimation}Ur(){switch(this.Wr.W().lastPriceAnimation){case 0:return!1;case 1:return!0;case 2:return performance.now()<=this.Fr}}xt(){return this.bt?(this.St(),this.bt=!1,this.Lr=!1):this.Lr&&(this.qr(),this.Lr=!1),this.Ht}St(){this.Ht.it(null);const t=this.Wr.qt().kt(),i=t.Xs(),n=this.Wr.Pt();if(null===i||null===n)return;const s=this.Wr.Yr(!0);if(s.Xr||!i.Kr(s.se))return;const e={x:t.It(s.se),y:this.Wr.At().Ot(s.ct,n.Bt)},r=s.O,h=this.Wr.W().lineWidth,l=ai(this.Zr(),r);this.Ht.it({Cr:r,Tr:h,Pr:l.Pr,Rr:l.Rr,ot:l.ot,Xe:e})}qr(){const t=this.Ht.He();if(null!==t){const i=ai(this.Zr(),t.Cr);t.Pr=i.Pr,t.Rr=i.Rr,t.ot=i.ot}}Zr(){return this.Ur()?performance.now()-this.Nr:2599}}function _i(t,i){return St(Math.min(Math.max(t,12),30)*i)}function ui(t,i){switch(t){case"arrowDown":case"arrowUp":return _i(i,1);case"circle":return _i(i,.8);case"square":return _i(i,.7)}}function ci(t){return function(t){const i=Math.ceil(t);return i%2!=0?i-1:i}(_i(t,1))}function di(t){return Math.max(_i(t,.1),3)}function fi(t,i,n,s,e){const r=ui("square",n),h=(r-1)/2,l=t-h,a=i-h;return s>=l&&s<=l+r&&e>=a&&e<=a+r}function vi(t,i,n,s,e){const r=(ui("arrowUp",e)-1)/2,h=(St(e/2)-1)/2;i.beginPath(),t?(i.moveTo(n-r,s),i.lineTo(n,s-r),i.lineTo(n+r,s),i.lineTo(n+h,s),i.lineTo(n+h,s+r),i.lineTo(n-h,s+r),i.lineTo(n-h,s)):(i.moveTo(n-r,s),i.lineTo(n,s+r),i.lineTo(n+r,s),i.lineTo(n+h,s),i.lineTo(n+h,s-r),i.lineTo(n-h,s-r),i.lineTo(n-h,s)),i.fill()}function pi(t,i,n,s,e,r){return fi(i,n,s,e,r)}class mi extends L{constructor(){super(...arguments),this.Lt=null,this.lr=new Qt,this.j=-1,this.H="",this.Gr=""}it(t){this.Lt=t}ar(t,i){this.j===t&&this.H===i||(this.j=t,this.H=i,this.Gr=z(t,i),this.lr.ir())}br(t,i){if(null===this.Lt||null===this.Lt.nt)return null;for(let n=this.Lt.nt.from;n=t&&e<=t+n&&r>=i-h&&r<=i+h}(t.Jt.et,t.Jt.rt,t.Jt.$i,t.Jt.Et,i,n))||function(t,i,n){if(0===t.Ks)return!1;switch(t.th){case"arrowDown":case"arrowUp":return pi(0,t.et,t.rt,t.Ks,i,n);case"circle":return function(t,i,n,s,e){const r=2+ui("circle",n)/2,h=t-s,l=i-e;return Math.sqrt(h*h+l*l)<=r}(t.et,t.rt,t.Ks,i,n);case"square":return fi(t.et,t.rt,t.Ks,i,n)}}(t,i,n)}function gi(t,i,n,s,e,r,h,l,a){const o=T(n)?n:n.xe,_=T(n)?n:n.ge,u=T(n)?n:n.Me,c=T(i.size)?Math.max(i.size,0):1,d=ci(l.he())*c,f=d/2;switch(t.Ks=d,i.position){case"inBar":return t.rt=h.Ot(o,a),void(void 0!==t.Jt&&(t.Jt.rt=t.rt+f+r+.6*e));case"aboveBar":return t.rt=h.Ot(_,a)-f-s.ih,void 0!==t.Jt&&(t.Jt.rt=t.rt-f-.6*e,s.ih+=1.2*e),void(s.ih+=d+r);case"belowBar":return t.rt=h.Ot(u,a)+f+s.nh,void 0!==t.Jt&&(t.Jt.rt=t.rt+f+r+.6*e,s.nh+=1.2*e),void(s.nh+=d+r)}i.position}class Mi{constructor(t,i){this.bt=!0,this.sh=!0,this.eh=!0,this.rh=null,this.Ht=new mi,this.Wr=t,this.Ui=i,this.Lt={st:[],nt:null}}gt(t){this.bt=!0,this.eh=!0,"data"===t&&(this.sh=!0)}xt(t){if(!this.Wr.Tt())return null;this.bt&&this.hh();const i=this.Ui.W().layout;return this.Ht.ar(i.fontSize,i.fontFamily),this.Ht.it(this.Lt),this.Ht}lh(){if(this.eh){if(this.Wr.ah().length>0){const t=this.Ui.kt().he(),i=di(t),n=1.5*ci(t)+2*i;this.rh={above:n,below:n}}else this.rh=null;this.eh=!1}return this.rh}hh(){const t=this.Wr.At(),i=this.Ui.kt(),n=this.Wr.ah();this.sh&&(this.Lt.st=n.map((t=>({ut:t.time,et:0,rt:0,Ks:0,th:t.shape,O:t.color,Jr:t.Jr,wr:t.id,Jt:void 0}))),this.sh=!1);const s=this.Ui.W().layout;this.Lt.nt=null;const e=i.Xs();if(null===e)return;const r=this.Wr.Pt();if(null===r)return;if(0===this.Lt.st.length)return;let h=NaN;const l=di(i.he()),a={ih:l,nh:l};this.Lt.nt=Vt(this.Lt.st,e,!0);for(let e=this.Lt.nt.from;e0&&(_.Jt={Qr:o.text,et:0,rt:0,$i:0,Et:0});const u=this.Wr.oh(o.time);null!==u&&gi(_,o,u,a,s.fontSize,l,t,i,r.Bt)}this.bt=!1}}class xi extends si{constructor(t){super(t)}yr(){const t=this.Mr;t.Tt=!1;const i=this.Is.W();if(!i.priceLineVisible||!this.Is.Tt())return;const n=this.Is.Yr(0===i.priceLineSource);n.Xr||(t.Tt=!0,t.rt=n.ki,t.O=this.Is._h(n.O),t.ht=i.priceLineWidth,t.Wt=i.priceLineStyle)}}class Si extends Q{constructor(t){super(),this.$t=t}Ii(t,i,n){t.Tt=!1,i.Tt=!1;const s=this.$t;if(!s.Tt())return;const e=s.W(),r=e.lastValueVisible,h=""!==s.uh(),l=0===e.seriesLastValueMode,a=s.Yr(!1);if(a.Xr)return;r&&(t.Jt=this.dh(a,r,l),t.Tt=0!==t.Jt.length),(h||l)&&(i.Jt=this.fh(a,r,h,l),i.Tt=i.Jt.length>0);const o=s._h(a.O),_=y(o);n.t=_.t,n.ki=a.ki,i.Vt=s.qt().zt(a.ki/s.At().Et()),t.Vt=o,t.O=_.i,i.O=_.i}fh(t,i,n,s){let e="";const r=this.$t.uh();return n&&0!==r.length&&(e+=`${r} `),i&&s&&(e+=this.$t.At().ph()?t.mh:t.bh),e.trim()}dh(t,i,n){return i?n?this.$t.At().ph()?t.bh:t.mh:t.Jt:""}}function yi(t,i,n,s){const e=Number.isFinite(i),r=Number.isFinite(n);return e&&r?t(i,n):e||r?e?i:n:s}class ki{constructor(t,i){this.wh=t,this.gh=i}Mh(t){return null!==t&&(this.wh===t.wh&&this.gh===t.gh)}xh(){return new ki(this.wh,this.gh)}Sh(){return this.wh}yh(){return this.gh}kh(){return this.gh-this.wh}Fi(){return this.gh===this.wh||Number.isNaN(this.gh)||Number.isNaN(this.wh)}ts(t){return null===t?this:new ki(yi(Math.min,this.Sh(),t.Sh(),-1/0),yi(Math.max,this.yh(),t.yh(),1/0))}Ch(t){if(!T(t))return;if(0===this.gh-this.wh)return;const i=.5*(this.gh+this.wh);let n=this.gh-i,s=this.wh-i;n*=t,s*=t,this.gh=i+n,this.wh=i+s}Th(t){T(t)&&(this.gh+=t,this.wh+=t)}Ph(){return{minValue:this.wh,maxValue:this.gh}}static Rh(t){return null===t?null:new ki(t.minValue,t.maxValue)}}class Ci{constructor(t,i){this.Dh=t,this.Oh=i||null}Ah(){return this.Dh}Bh(){return this.Oh}Ph(){return null===this.Dh?null:{priceRange:this.Dh.Ph(),margins:this.Oh||void 0}}static Rh(t){return null===t?null:new Ci(ki.Rh(t.priceRange),t.margins)}}class Ti extends si{constructor(t,i){super(t),this.Vh=i}yr(){const t=this.Mr;t.Tt=!1;const i=this.Vh.W();if(!this.Is.Tt()||!i.lineVisible)return;const n=this.Vh.zh();null!==n&&(t.Tt=!0,t.rt=n,t.O=i.color,t.ht=i.lineWidth,t.Wt=i.lineStyle,t.wr=this.Vh.W().id)}}class Pi extends Q{constructor(t,i){super(),this.Wr=t,this.Vh=i}Ii(t,i,n){t.Tt=!1,i.Tt=!1;const s=this.Vh.W(),e=s.axisLabelVisible,r=""!==s.title,h=this.Wr;if(!e||!h.Tt())return;const l=this.Vh.zh();if(null===l)return;r&&(i.Jt=s.title,i.Tt=!0),i.Vt=h.qt().zt(l/h.At().Et()),t.Jt=this.Eh(s.price),t.Tt=!0;const a=y(s.axisLabelColor||s.color);n.t=a.t;const o=s.axisLabelTextColor||a.i;t.O=o,i.O=o,n.ki=l}Eh(t){const i=this.Wr.Pt();return null===i?"":this.Wr.At().Wi(t,i.Bt)}}class Ri{constructor(t,i){this.Wr=t,this.cn=i,this.Ih=new Ti(t,this),this._r=new Pi(t,this),this.Lh=new ii(this._r,t,t.qt())}Nh(t){C(this.cn,t),this.gt(),this.Wr.qt().Fh()}W(){return this.cn}Wh(){return this.Ih}jh(){return this.Lh}Hh(){return this._r}gt(){this.Ih.gt(),this._r.gt()}zh(){const t=this.Wr,i=t.At();if(t.qt().kt().Fi()||i.Fi())return null;const n=t.Pt();return null===n?null:i.Ot(this.cn.price,n.Bt)}}class Di extends et{constructor(t){super(),this.Ui=t}qt(){return this.Ui}}const Oi={Bar:(t,i,n,s)=>{var e;const r=i.upColor,h=i.downColor,l=f(t(n,s)),a=v(l.Bt[0])<=v(l.Bt[3]);return{ue:null!==(e=l.O)&&void 0!==e?e:a?r:h}},Candlestick:(t,i,n,s)=>{var e,r,h;const l=i.upColor,a=i.downColor,o=i.borderUpColor,_=i.borderDownColor,u=i.wickUpColor,c=i.wickDownColor,d=f(t(n,s)),p=v(d.Bt[0])<=v(d.Bt[3]);return{ue:null!==(e=d.O)&&void 0!==e?e:p?l:a,Le:null!==(r=d.Vt)&&void 0!==r?r:p?o:_,Ie:null!==(h=d.$h)&&void 0!==h?h:p?u:c}},Custom:(t,i,n,s)=>{var e;return{ue:null!==(e=f(t(n,s)).O)&&void 0!==e?e:i.color}},Area:(t,i,n,s)=>{var e,r,h,l;const a=f(t(n,s));return{ue:null!==(e=a._t)&&void 0!==e?e:i.lineColor,_t:null!==(r=a._t)&&void 0!==r?r:i.lineColor,Ts:null!==(h=a.Ts)&&void 0!==h?h:i.topColor,Ps:null!==(l=a.Ps)&&void 0!==l?l:i.bottomColor}},Baseline:(t,i,n,s)=>{var e,r,h,l,a,o;const _=f(t(n,s));return{ue:_.Bt[3]>=i.baseValue.price?i.topLineColor:i.bottomLineColor,Pe:null!==(e=_.Pe)&&void 0!==e?e:i.topLineColor,Re:null!==(r=_.Re)&&void 0!==r?r:i.bottomLineColor,Se:null!==(h=_.Se)&&void 0!==h?h:i.topFillColor1,ye:null!==(l=_.ye)&&void 0!==l?l:i.topFillColor2,ke:null!==(a=_.ke)&&void 0!==a?a:i.bottomFillColor1,Ce:null!==(o=_.Ce)&&void 0!==o?o:i.bottomFillColor2}},Line:(t,i,n,s)=>{var e,r;const h=f(t(n,s));return{ue:null!==(e=h.O)&&void 0!==e?e:i.color,_t:null!==(r=h.O)&&void 0!==r?r:i.color}},Histogram:(t,i,n,s)=>{var e;return{ue:null!==(e=f(t(n,s)).O)&&void 0!==e?e:i.color}}};class Ai{constructor(t){this.Uh=(t,i)=>void 0!==i?i.Bt:this.Wr.zn().qh(t),this.Wr=t,this.Yh=Oi[t.Xh()]}Hs(t,i){return this.Yh(this.Uh,this.Wr.W(),t,i)}}var Bi;!function(t){t[t.NearestLeft=-1]="NearestLeft",t[t.None=0]="None",t[t.NearestRight=1]="NearestRight"}(Bi||(Bi={}));const Vi=30;class zi{constructor(){this.Kh=[],this.Zh=new Map,this.Gh=new Map}Jh(){return this.Ks()>0?this.Kh[this.Kh.length-1]:null}Qh(){return this.Ks()>0?this.tl(0):null}Vn(){return this.Ks()>0?this.tl(this.Kh.length-1):null}Ks(){return this.Kh.length}Fi(){return 0===this.Ks()}Kr(t){return null!==this.il(t,0)}qh(t){return this.nl(t)}nl(t,i=0){const n=this.il(t,i);return null===n?null:Object.assign(Object.assign({},this.sl(n)),{se:this.tl(n)})}ie(){return this.Kh}el(t,i,n){if(this.Fi())return null;let s=null;for(const e of n){s=Ei(s,this.rl(t,i,e))}return s}it(t){this.Gh.clear(),this.Zh.clear(),this.Kh=t}tl(t){return this.Kh[t].se}sl(t){return this.Kh[t]}il(t,i){const n=this.hl(t);if(null===n&&0!==i)switch(i){case-1:return this.ll(t);case 1:return this.al(t);default:throw new TypeError("Unknown search mode")}return n}ll(t){let i=this.ol(t);return i>0&&(i-=1),i!==this.Kh.length&&this.tl(i)t.set.se>i))}ul(t,i,n){let s=null;for(let e=t;es.dl&&(s.dl=t)))}return s}rl(t,i,n){if(this.Fi())return null;let s=null;const e=f(this.Qh()),r=f(this.Vn()),h=Math.max(t,e),l=Math.min(i,r),a=Math.ceil(h/Vi)*Vi,o=Math.max(a,Math.floor(l/Vi)*Vi);{const t=this.ol(h),e=this._l(Math.min(l,a,i));s=Ei(s,this.ul(t,e,n))}let _=this.Zh.get(n);void 0===_&&(_=new Map,this.Zh.set(n,_));for(let t=Math.max(a+1,h);tnew Li(t)));return this.gl={vl:e,pl:r},r}tn(){var t,i,n,s;const e=null!==(n=null===(i=(t=this.kl).timeAxisViews)||void 0===i?void 0:i.call(t))&&void 0!==n?n:[];if((null===(s=this.Ml)||void 0===s?void 0:s.vl)===e)return this.Ml.pl;const r=this.Wr.qt().kt(),h=e.map((t=>new Fi(t,r)));return this.Ml={vl:e,pl:h},h}Rn(){var t,i,n,s;const e=null!==(n=null===(i=(t=this.kl).priceAxisViews)||void 0===i?void 0:i.call(t))&&void 0!==n?n:[];if((null===(s=this.xl)||void 0===s?void 0:s.vl)===e)return this.xl.pl;const r=this.Wr.At(),h=e.map((t=>new Wi(t,r)));return this.xl={vl:e,pl:h},h}Tl(){var t,i,n,s;const e=null!==(n=null===(i=(t=this.kl).priceAxisPaneViews)||void 0===i?void 0:i.call(t))&&void 0!==n?n:[];if((null===(s=this.Sl)||void 0===s?void 0:s.vl)===e)return this.Sl.pl;const r=e.map((t=>new Li(t)));return this.Sl={vl:e,pl:r},r}Pl(){var t,i,n,s;const e=null!==(n=null===(i=(t=this.kl).timeAxisPaneViews)||void 0===i?void 0:i.call(t))&&void 0!==n?n:[];if((null===(s=this.yl)||void 0===s?void 0:s.vl)===e)return this.yl.pl;const r=e.map((t=>new Li(t)));return this.yl={vl:e,pl:r},r}Rl(t,i){var n,s,e;return null!==(e=null===(s=(n=this.kl).autoscaleInfo)||void 0===s?void 0:s.call(n,t,i))&&void 0!==e?e:null}br(t,i){var n,s,e;return null!==(e=null===(s=(n=this.kl).hitTest)||void 0===s?void 0:s.call(n,t,i))&&void 0!==e?e:null}}function Hi(t,i,n,s){t.forEach((t=>{i(t).forEach((t=>{t.ml()===n&&s.push(t)}))}))}function $i(t){return t.Pn()}function Ui(t){return t.Tl()}function qi(t){return t.Pl()}class Yi extends Di{constructor(t,i,n,s,e){super(t),this.Lt=new zi,this.Ih=new xi(this),this.Dl=[],this.Ol=new ei(this),this.Al=null,this.Bl=null,this.Vl=[],this.zl=[],this.El=null,this.Il=[],this.cn=i,this.Ll=n;const r=new Si(this);this.hn=[r],this.Lh=new ii(r,this,t),"Area"!==n&&"Line"!==n&&"Baseline"!==n||(this.Al=new oi(this)),this.Nl(),this.Fl(e)}S(){null!==this.El&&clearTimeout(this.El)}_h(t){return this.cn.priceLineColor||t}Yr(t){const i={Xr:!0},n=this.At();if(this.qt().kt().Fi()||n.Fi()||this.Lt.Fi())return i;const s=this.qt().kt().Xs(),e=this.Pt();if(null===s||null===e)return i;let r,h;if(t){const t=this.Lt.Jh();if(null===t)return i;r=t,h=t.se}else{const t=this.Lt.nl(s.di(),-1);if(null===t)return i;if(r=this.Lt.qh(t.se),null===r)return i;h=t.se}const l=r.Bt[3],a=this.$s().Hs(h,{Bt:r}),o=n.Ot(l,e.Bt);return{Xr:!1,ct:l,Jt:n.Wi(l,e.Bt),mh:n.Wl(l),bh:n.jl(l,e.Bt),O:a.ue,ki:o,se:h}}$s(){return null!==this.Bl||(this.Bl=new Ai(this)),this.Bl}W(){return this.cn}Nh(t){const i=t.priceScaleId;void 0!==i&&i!==this.cn.priceScaleId&&this.qt().Hl(this,i),C(this.cn,t),void 0!==t.priceFormat&&(this.Nl(),this.qt().$l()),this.qt().Ul(this),this.qt().ql(),this.wn.gt("options")}it(t,i){this.Lt.it(t),this.Yl(),this.wn.gt("data"),this.dn.gt("data"),null!==this.Al&&(i&&i.Xl?this.Al.Hr():0===t.length&&this.Al.jr());const n=this.qt().cr(this);this.qt().Kl(n),this.qt().Ul(this),this.qt().ql(),this.qt().Fh()}Zl(t){this.Vl=t,this.Yl();const i=this.qt().cr(this);this.dn.gt("data"),this.qt().Kl(i),this.qt().Ul(this),this.qt().ql(),this.qt().Fh()}Gl(){return this.Vl}ah(){return this.zl}Jl(t){const i=new Ri(this,t);return this.Dl.push(i),this.qt().Ul(this),i}Ql(t){const i=this.Dl.indexOf(t);-1!==i&&this.Dl.splice(i,1),this.qt().Ul(this)}Xh(){return this.Ll}Pt(){const t=this.ta();return null===t?null:{Bt:t.Bt[3],ia:t.ut}}ta(){const t=this.qt().kt().Xs();if(null===t)return null;const i=t.Os();return this.Lt.nl(i,1)}zn(){return this.Lt}oh(t){const i=this.Lt.qh(t);return null===i?null:"Bar"===this.Ll||"Candlestick"===this.Ll||"Custom"===this.Ll?{we:i.Bt[0],ge:i.Bt[1],Me:i.Bt[2],xe:i.Bt[3]}:i.Bt[3]}na(t){const i=[];Hi(this.Il,$i,"top",i);const n=this.Al;return null!==n&&n.Tt()?(null===this.El&&n.Ur()&&(this.El=setTimeout((()=>{this.El=null,this.qt().sa()}),0)),n.$r(),i.push(n),i):i}Pn(){const t=[];this.ea()||t.push(this.Ol),t.push(this.wn,this.Ih,this.dn);const i=this.Dl.map((t=>t.Wh()));return t.push(...i),Hi(this.Il,$i,"normal",t),t}ra(){return this.ha($i,"bottom")}la(t){return this.ha(Ui,t)}aa(t){return this.ha(qi,t)}oa(t,i){return this.Il.map((n=>n.br(t,i))).filter((t=>null!==t))}Qi(t){return[this.Lh,...this.Dl.map((t=>t.jh()))]}Rn(t,i){if(i!==this.Xi&&!this.ea())return[];const n=[...this.hn];for(const t of this.Dl)n.push(t.Hh());return this.Il.forEach((t=>{n.push(...t.Rn())})),n}tn(){const t=[];return this.Il.forEach((i=>{t.push(...i.tn())})),t}Rl(t,i){if(void 0!==this.cn.autoscaleInfoProvider){const n=this.cn.autoscaleInfoProvider((()=>{const n=this._a(t,i);return null===n?null:n.Ph()}));return Ci.Rh(n)}return this._a(t,i)}ua(){return this.cn.priceFormat.minMove}ca(){return this.da}On(){var t;this.wn.gt(),this.dn.gt();for(const t of this.hn)t.gt();for(const t of this.Dl)t.gt();this.Ih.gt(),this.Ol.gt(),null===(t=this.Al)||void 0===t||t.gt(),this.Il.forEach((t=>t.On()))}At(){return f(super.At())}Ct(t){if(!(("Line"===this.Ll||"Area"===this.Ll||"Baseline"===this.Ll)&&this.cn.crosshairMarkerVisible))return null;const i=this.Lt.qh(t);if(null===i)return null;return{ct:i.Bt[3],ot:this.fa(),Vt:this.va(),Dt:this.pa(),Rt:this.ma(t)}}uh(){return this.cn.title}Tt(){return this.cn.visible}ba(t){this.Il.push(new ji(t,this))}wa(t){this.Il=this.Il.filter((i=>i.Cl()!==t))}ga(){if(this.wn instanceof Yt!=!1)return t=>this.wn.Fe(t)}Ma(){if(this.wn instanceof Yt!=!1)return t=>this.wn.We(t)}ea(){return!lt(this.At().xa())}_a(t,i){if(!P(t)||!P(i)||this.Lt.Fi())return null;const n="Line"===this.Ll||"Area"===this.Ll||"Baseline"===this.Ll||"Histogram"===this.Ll?[3]:[2,1],s=this.Lt.el(t,i,n);let e=null!==s?new ki(s.cl,s.dl):null;if("Histogram"===this.Xh()){const t=this.cn.base,i=new ki(t,t);e=null!==e?e.ts(i):i}let r=this.dn.lh();return this.Il.forEach((n=>{const s=n.Rl(t,i);if(null==s?void 0:s.priceRange){const t=new ki(s.priceRange.minValue,s.priceRange.maxValue);e=null!==e?e.ts(t):t}var h,l,a,o;(null==s?void 0:s.margins)&&(h=r,l=s.margins,r={above:Math.max(null!==(a=null==h?void 0:h.above)&&void 0!==a?a:0,l.above),below:Math.max(null!==(o=null==h?void 0:h.below)&&void 0!==o?o:0,l.below)})})),new Ci(e,r)}fa(){switch(this.Ll){case"Line":case"Area":case"Baseline":return this.cn.crosshairMarkerRadius}return 0}va(){switch(this.Ll){case"Line":case"Area":case"Baseline":{const t=this.cn.crosshairMarkerBorderColor;if(0!==t.length)return t}}return null}pa(){switch(this.Ll){case"Line":case"Area":case"Baseline":return this.cn.crosshairMarkerBorderWidth}return 0}ma(t){switch(this.Ll){case"Line":case"Area":case"Baseline":{const t=this.cn.crosshairMarkerBackgroundColor;if(0!==t.length)return t}}return this.$s().Hs(t).ue}Nl(){switch(this.cn.priceFormat.type){case"custom":this.da={format:this.cn.priceFormat.formatter};break;case"volume":this.da=new dt(this.cn.priceFormat.precision);break;case"percent":this.da=new ct(this.cn.priceFormat.precision);break;default:{const t=Math.pow(10,this.cn.priceFormat.precision);this.da=new ut(t,this.cn.priceFormat.minMove*t)}}null!==this.Xi&&this.Xi.Sa()}Yl(){const t=this.qt().kt();if(!t.ya()||this.Lt.Fi())return void(this.zl=[]);const i=f(this.Lt.Qh());this.zl=this.Vl.map(((n,s)=>{const e=f(t.ka(n.time,!0)),r=et instanceof Yi)).reduce(((t,s)=>{if(n.dr(s)||!s.Tt())return t;const e=s.At(),r=s.zn();if(e.Fi()||!r.Kr(i))return t;const h=r.qh(i);if(null===h)return t;const l=v(s.Pt());return t.concat([e.Ot(h.Bt[3],l.Bt)])}),[]);if(0===l.length)return s;l.sort(((t,i)=>Math.abs(t-h)-Math.abs(i-h)));const a=l[0];return s=e.pn(a,r),s}}class Ki extends H{constructor(){super(...arguments),this.Lt=null}it(t){this.Lt=t}Z({context:t,bitmapSize:i,horizontalPixelRatio:n,verticalPixelRatio:s}){if(null===this.Lt)return;const e=Math.max(1,Math.floor(n));t.lineWidth=e,function(t,i){t.save(),t.lineWidth%2&&t.translate(.5,.5),i(),t.restore()}(t,(()=>{const r=f(this.Lt);if(r.Pa){t.strokeStyle=r.Ra,_(t,r.Da),t.beginPath();for(const s of r.Oa){const r=Math.round(s.Aa*n);t.moveTo(r,-e),t.lineTo(r,i.height+e)}t.stroke()}if(r.Ba){t.strokeStyle=r.Va,_(t,r.za),t.beginPath();for(const n of r.Ea){const r=Math.round(n.Aa*s);t.moveTo(-e,r),t.lineTo(i.width+e,r)}t.stroke()}}))}}class Zi{constructor(t){this.Ht=new Ki,this.bt=!0,this.nn=t}gt(){this.bt=!0}xt(){if(this.bt){const t=this.nn.qt().W().grid,i={Ba:t.horzLines.visible,Pa:t.vertLines.visible,Va:t.horzLines.color,Ra:t.vertLines.color,za:t.horzLines.style,Da:t.vertLines.style,Ea:this.nn.vn().Ia(),Oa:(this.nn.qt().kt().Ia()||[]).map((t=>({Aa:t.coord})))};this.Ht.it(i),this.bt=!1}return this.Ht}}class Gi{constructor(t){this.wn=new Zi(t)}Wh(){return this.wn}}const Ji={La:4,Na:1e-4};function Qi(t,i){const n=100*(t-i)/i;return i<0?-n:n}function tn(t,i){const n=Qi(t.Sh(),i),s=Qi(t.yh(),i);return new ki(n,s)}function nn(t,i){const n=100*(t-i)/i+100;return i<0?-n:n}function sn(t,i){const n=nn(t.Sh(),i),s=nn(t.yh(),i);return new ki(n,s)}function en(t,i){const n=Math.abs(t);if(n<1e-15)return 0;const s=Math.log10(n+i.Na)+i.La;return t<0?-s:s}function rn(t,i){const n=Math.abs(t);if(n<1e-15)return 0;const s=Math.pow(10,n-i.La)-i.Na;return t<0?-s:s}function hn(t,i){if(null===t)return null;const n=en(t.Sh(),i),s=en(t.yh(),i);return new ki(n,s)}function ln(t,i){if(null===t)return null;const n=rn(t.Sh(),i),s=rn(t.yh(),i);return new ki(n,s)}function an(t){if(null===t)return Ji;const i=Math.abs(t.yh()-t.Sh());if(i>=1||i<1e-15)return Ji;const n=Math.ceil(Math.abs(Math.log10(i))),s=Ji.La+n;return{La:s,Na:1/Math.pow(10,s)}}class on{constructor(t,i){if(this.Fa=t,this.Wa=i,function(t){if(t<0)return!1;for(let i=t;i>1;i/=10)if(i%10!=0)return!1;return!0}(this.Fa))this.ja=[2,2.5,2];else{this.ja=[];for(let t=this.Fa;1!==t;){if(t%2==0)this.ja.push(2),t/=2;else{if(t%5!=0)throw new Error("unexpected base");this.ja.push(2,2.5),t/=5}if(this.ja.length>100)throw new Error("something wrong with base")}}}Ha(t,i,n){const s=0===this.Fa?0:1/this.Fa;let e=Math.pow(10,Math.max(0,Math.ceil(Math.log10(t-i)))),r=0,h=this.Wa[0];for(;;){const t=xt(e,s,1e-14)&&e>s+1e-14,i=xt(e,n*h,1e-14),l=xt(e,1,1e-14);if(!(t&&i&&l))break;e/=h,h=this.Wa[++r%this.Wa.length]}if(e<=s+1e-14&&(e=s),e=Math.max(1,e),this.ja.length>0&&(l=e,a=1,o=1e-14,Math.abs(l-a)s+1e-14;)e/=h,h=this.ja[++r%this.ja.length];var l,a,o;return e}}class _n{constructor(t,i,n,s){this.$a=[],this.Li=t,this.Fa=i,this.Ua=n,this.qa=s}Ha(t,i){if(t=o?1:-1;let d=null,f=0;for(let n=a-u;n>o;n-=_){const s=this.qa(n,i,!0);null!==d&&Math.abs(s-d)l||(ff(t.Zi())-f(i.Zi())))}var cn;!function(t){t[t.Normal=0]="Normal",t[t.Logarithmic=1]="Logarithmic",t[t.Percentage=2]="Percentage",t[t.IndexedTo100=3]="IndexedTo100"}(cn||(cn={}));const dn=new ct,fn=new ut(100,1);class vn{constructor(t,i,n,s){this.Qa=0,this.io=null,this.Dh=null,this.no=null,this.so={eo:!1,ro:null},this.ho=0,this.lo=0,this.ao=new k,this.oo=new k,this._o=[],this.uo=null,this.co=null,this.do=null,this.fo=null,this.da=fn,this.vo=an(null),this.po=t,this.cn=i,this.mo=n,this.bo=s,this.wo=new _n(this,100,this.Mo.bind(this),this.xo.bind(this))}xa(){return this.po}W(){return this.cn}Nh(t){if(C(this.cn,t),this.Sa(),void 0!==t.mode&&this.So({kr:t.mode}),void 0!==t.scaleMargins){const i=d(t.scaleMargins.top),n=d(t.scaleMargins.bottom);if(i<0||i>1)throw new Error(`Invalid top margin - expect value between 0 and 1, given=${i}`);if(n<0||n>1||i+n>1)throw new Error(`Invalid bottom margin - expect value between 0 and 1, given=${n}`);if(i+n>1)throw new Error(`Invalid margins - sum of margins must be less than 1, given=${i+n}`);this.yo(),this.co=null}}ko(){return this.cn.autoScale}Ja(){return 1===this.cn.mode}ph(){return 2===this.cn.mode}Co(){return 3===this.cn.mode}kr(){return{Wn:this.cn.autoScale,To:this.cn.invertScale,kr:this.cn.mode}}So(t){const i=this.kr();let n=null;void 0!==t.Wn&&(this.cn.autoScale=t.Wn),void 0!==t.kr&&(this.cn.mode=t.kr,2!==t.kr&&3!==t.kr||(this.cn.autoScale=!0),this.so.eo=!1),1===i.kr&&t.kr!==i.kr&&(!function(t,i){if(null===t)return!1;const n=rn(t.Sh(),i),s=rn(t.yh(),i);return isFinite(n)&&isFinite(s)}(this.Dh,this.vo)?this.cn.autoScale=!0:(n=ln(this.Dh,this.vo),null!==n&&this.Po(n))),1===t.kr&&t.kr!==i.kr&&(n=hn(this.Dh,this.vo),null!==n&&this.Po(n));const s=i.kr!==this.cn.mode;s&&(2===i.kr||this.ph())&&this.Sa(),s&&(3===i.kr||this.Co())&&this.Sa(),void 0!==t.To&&i.To!==t.To&&(this.cn.invertScale=t.To,this.Ro()),this.oo.m(i,this.kr())}Do(){return this.oo}P(){return this.mo.fontSize}Et(){return this.Qa}Oo(t){this.Qa!==t&&(this.Qa=t,this.yo(),this.co=null)}Ao(){if(this.io)return this.io;const t=this.Et()-this.Bo()-this.Vo();return this.io=t,t}Ah(){return this.zo(),this.Dh}Po(t,i){const n=this.Dh;(i||null===n&&null!==t||null!==n&&!n.Mh(t))&&(this.co=null,this.Dh=t)}Fi(){return this.zo(),0===this.Qa||!this.Dh||this.Dh.Fi()}Eo(t){return this.To()?t:this.Et()-1-t}Ot(t,i){return this.ph()?t=Qi(t,i):this.Co()&&(t=nn(t,i)),this.xo(t,i)}Qs(t,i,n){this.zo();const s=this.Vo(),e=f(this.Ah()),r=e.Sh(),h=e.yh(),l=this.Ao()-1,a=this.To(),o=l/(h-r),_=void 0===n?0:n.from,u=void 0===n?t.length:n.to,c=this.Io();for(let n=_;nt.On()))}Sa(){this.co=null;const t=this.Jo();let i=100;null!==t&&(i=Math.round(1/t.ua())),this.da=fn,this.ph()?(this.da=dn,i=100):this.Co()?(this.da=new ut(100,1),i=100):null!==t&&(this.da=t.ca()),this.wo=new _n(this,i,this.Mo.bind(this),this.xo.bind(this)),this.wo.Xa()}Wo(){this.uo=null}Jo(){return this._o[0]||null}Bo(){return this.To()?this.cn.scaleMargins.bottom*this.Et()+this.lo:this.cn.scaleMargins.top*this.Et()+this.ho}Vo(){return this.To()?this.cn.scaleMargins.top*this.Et()+this.ho:this.cn.scaleMargins.bottom*this.Et()+this.lo}zo(){this.so.eo||(this.so.eo=!0,this.i_())}yo(){this.io=null}xo(t,i){if(this.zo(),this.Fi())return 0;t=this.Ja()&&t?en(t,this.vo):t;const n=f(this.Ah()),s=this.Vo()+(this.Ao()-1)*(t-n.Sh())/n.kh();return this.Eo(s)}Mo(t,i){if(this.zo(),this.Fi())return 0;const n=this.Eo(t),s=f(this.Ah()),e=s.Sh()+s.kh()*((n-this.Vo())/(this.Ao()-1));return this.Ja()?rn(e,this.vo):e}Ro(){this.co=null,this.wo.Xa()}i_(){const t=this.so.ro;if(null===t)return;let i=null;const n=this.Qo();let s=0,e=0;for(const r of n){if(!r.Tt())continue;const n=r.Pt();if(null===n)continue;const h=r.Rl(t.Os(),t.di());let l=h&&h.Ah();if(null!==l){switch(this.cn.mode){case 1:l=hn(l,this.vo);break;case 2:l=tn(l,n.Bt);break;case 3:l=sn(l,n.Bt)}if(i=null===i?l:i.ts(f(l)),null!==h){const t=h.Bh();null!==t&&(s=Math.max(s,t.above),e=Math.max(s,t.below))}}}if(s===this.ho&&e===this.lo||(this.ho=s,this.lo=e,this.co=null,this.yo()),null!==i){if(i.Sh()===i.yh()){const t=this.Jo(),n=5*(null===t||this.ph()||this.Co()?1:t.ua());this.Ja()&&(i=ln(i,this.vo)),i=new ki(i.Sh()-n,i.yh()+n),this.Ja()&&(i=hn(i,this.vo))}if(this.Ja()){const t=ln(i,this.vo),n=an(t);if(r=n,h=this.vo,r.La!==h.La||r.Na!==h.Na){const s=null!==this.no?ln(this.no,this.vo):null;this.vo=n,i=hn(t,n),null!==s&&(this.no=hn(s,n))}}this.Po(i)}else null===this.Dh&&(this.Po(new ki(-.5,.5)),this.vo=an(null));var r,h;this.so.eo=!0}Io(){return this.ph()?Qi:this.Co()?nn:this.Ja()?t=>en(t,this.vo):null}n_(t,i,n){return void 0===i?(void 0===n&&(n=this.ca()),n.format(t)):i(t)}Eh(t,i){return this.n_(t,this.bo.priceFormatter,i)}Go(t,i){return this.n_(t,this.bo.percentageFormatter,i)}}class pn{constructor(t,i){this._o=[],this.s_=new Map,this.Qa=0,this.e_=0,this.r_=1e3,this.uo=null,this.h_=new k,this.wl=t,this.Ui=i,this.l_=new Gi(this);const n=i.W();this.a_=this.o_("left",n.leftPriceScale),this.__=this.o_("right",n.rightPriceScale),this.a_.Do().l(this.u_.bind(this,this.a_),this),this.__.Do().l(this.u_.bind(this,this.__),this),this.c_(n)}c_(t){if(t.leftPriceScale&&this.a_.Nh(t.leftPriceScale),t.rightPriceScale&&this.__.Nh(t.rightPriceScale),t.localization&&(this.a_.Sa(),this.__.Sa()),t.overlayPriceScales){const i=Array.from(this.s_.values());for(const n of i){const i=f(n[0].At());i.Nh(t.overlayPriceScales),t.localization&&i.Sa()}}}d_(t){switch(t){case"left":return this.a_;case"right":return this.__}return this.s_.has(t)?d(this.s_.get(t))[0].At():null}S(){this.qt().f_().p(this),this.a_.Do().p(this),this.__.Do().p(this),this._o.forEach((t=>{t.S&&t.S()})),this.h_.m()}v_(){return this.r_}p_(t){this.r_=t}qt(){return this.Ui}$i(){return this.e_}Et(){return this.Qa}m_(t){this.e_=t,this.b_()}Oo(t){this.Qa=t,this.a_.Oo(t),this.__.Oo(t),this._o.forEach((i=>{if(this.dr(i)){const n=i.At();null!==n&&n.Oo(t)}})),this.b_()}Ta(){return this._o}dr(t){const i=t.At();return null===i||this.a_!==i&&this.__!==i}Fo(t,i,n){const s=void 0!==n?n:this.g_().w_+1;this.M_(t,i,s)}jo(t){const i=this._o.indexOf(t);c(-1!==i,"removeDataSource: invalid data source"),this._o.splice(i,1);const n=f(t.At()).xa();if(this.s_.has(n)){const i=d(this.s_.get(n)),s=i.indexOf(t);-1!==s&&(i.splice(s,1),0===i.length&&this.s_.delete(n))}const s=t.At();s&&s.Ta().indexOf(t)>=0&&s.jo(t),null!==s&&(s.Wo(),this.x_(s)),this.uo=null}pr(t){return t===this.a_?"left":t===this.__?"right":"overlay"}S_(){return this.a_}y_(){return this.__}k_(t,i){t.Uo(i)}C_(t,i){t.qo(i),this.b_()}T_(t){t.Yo()}P_(t,i){t.Xo(i)}R_(t,i){t.Ko(i),this.b_()}D_(t){t.Zo()}b_(){this._o.forEach((t=>{t.On()}))}vn(){let t=null;return this.Ui.W().rightPriceScale.visible&&0!==this.__.Ta().length?t=this.__:this.Ui.W().leftPriceScale.visible&&0!==this.a_.Ta().length?t=this.a_:0!==this._o.length&&(t=this._o[0].At()),null===t&&(t=this.__),t}vr(){let t=null;return this.Ui.W().rightPriceScale.visible?t=this.__:this.Ui.W().leftPriceScale.visible&&(t=this.a_),t}x_(t){null!==t&&t.ko()&&this.O_(t)}A_(t){const i=this.wl.Xs();t.So({Wn:!0}),null!==i&&t.t_(i),this.b_()}B_(){this.O_(this.a_),this.O_(this.__)}V_(){this.x_(this.a_),this.x_(this.__),this._o.forEach((t=>{this.dr(t)&&this.x_(t.At())})),this.b_(),this.Ui.Fh()}No(){return null===this.uo&&(this.uo=un(this._o)),this.uo}z_(){return this.h_}E_(){return this.l_}O_(t){const i=t.Qo();if(i&&i.length>0&&!this.wl.Fi()){const i=this.wl.Xs();null!==i&&t.t_(i)}t.On()}g_(){const t=this.No();if(0===t.length)return{I_:0,w_:0};let i=0,n=0;for(let s=0;sn&&(n=e))}return{I_:i,w_:n}}M_(t,i,n){let s=this.d_(i);if(null===s&&(s=this.o_(i,this.Ui.W().overlayPriceScales)),this._o.push(t),!lt(i)){const n=this.s_.get(i)||[];n.push(t),this.s_.set(i,n)}s.Fo(t),t.Ji(s),t.Gi(n),this.x_(s),this.uo=null}u_(t,i,n){i.kr!==n.kr&&this.O_(t)}o_(t,i){const n=Object.assign({visible:!0,autoScale:!0},O(i)),s=new vn(t,n,this.Ui.W().layout,this.Ui.W().localization);return s.Oo(this.Et()),s}}class mn{constructor(t,i,n=50){this.Ke=0,this.Ze=1,this.Ge=1,this.Qe=new Map,this.Je=new Map,this.L_=t,this.N_=i,this.tr=n}F_(t){const i=t.time,n=this.N_.cacheKey(i),s=this.Qe.get(n);if(void 0!==s)return s.W_;if(this.Ke===this.tr){const t=this.Je.get(this.Ge);this.Je.delete(this.Ge),this.Qe.delete(d(t)),this.Ge++,this.Ke--}const e=this.L_(t);return this.Qe.set(n,{W_:e,er:this.Ze}),this.Je.set(this.Ze,n),this.Ke++,this.Ze++,e}}class bn{constructor(t,i){c(t<=i,"right should be >= left"),this.j_=t,this.H_=i}Os(){return this.j_}di(){return this.H_}U_(){return this.H_-this.j_+1}Kr(t){return this.j_<=t&&t<=this.H_}Mh(t){return this.j_===t.Os()&&this.H_===t.di()}}function wn(t,i){return null===t||null===i?t===i:t.Mh(i)}class gn{constructor(){this.q_=new Map,this.Qe=null,this.Y_=!1}X_(t){this.Y_=t,this.Qe=null}K_(t,i){this.Z_(i),this.Qe=null;for(let n=i;n{t<=n[0].index?i.push(s):n.splice(Dt(n,t,(i=>i.indexi-t))){if(!this.q_.get(n))continue;const s=i;i=[];const e=s.length;let r=0;const h=d(this.q_.get(n)),l=h.length;let a=1/0,o=-1/0;for(let n=0;n=t&&_-o>=t)i.push(l),o=_;else if(this.Y_)return s}for(;ri.weight?t:i}class Sn{constructor(t,i,n,s){this.e_=0,this.eu=null,this.ru=[],this.fo=null,this.do=null,this.hu=new gn,this.lu=new Map,this.au=Mn.su(),this.ou=!0,this._u=new k,this.uu=new k,this.cu=new k,this.du=null,this.fu=null,this.vu=[],this.cn=i,this.bo=n,this.pu=i.rightOffset,this.mu=i.barSpacing,this.Ui=t,this.N_=s,this.bu(),this.hu.X_(i.uniformDistribution)}W(){return this.cn}wu(t){C(this.bo,t),this.gu(),this.bu()}Nh(t,i){var n;C(this.cn,t),this.cn.fixLeftEdge&&this.Mu(),this.cn.fixRightEdge&&this.xu(),void 0!==t.barSpacing&&this.Ui.Gn(t.barSpacing),void 0!==t.rightOffset&&this.Ui.Jn(t.rightOffset),void 0!==t.minBarSpacing&&this.Ui.Gn(null!==(n=t.barSpacing)&&void 0!==n?n:this.mu),this.gu(),this.bu(),this.cu.m()}mn(t){var i,n;return null!==(n=null===(i=this.ru[t])||void 0===i?void 0:i.time)&&void 0!==n?n:null}qi(t){var i;return null!==(i=this.ru[t])&&void 0!==i?i:null}ka(t,i){if(this.ru.length<1)return null;if(this.N_.key(t)>this.N_.key(this.ru[this.ru.length-1].time))return i?this.ru.length-1:null;const n=Dt(this.ru,this.N_.key(t),((t,i)=>this.N_.key(t.time)0}Xs(){return this.Su(),this.au.iu()}yu(){return this.Su(),this.au.nu()}ku(){const t=this.Xs();if(null===t)return null;const i={from:t.Os(),to:t.di()};return this.Cu(i)}Cu(t){const i=Math.round(t.from),n=Math.round(t.to),s=f(this.Tu()),e=f(this.Pu());return{from:f(this.qi(Math.max(s,i))),to:f(this.qi(Math.min(e,n)))}}Ru(t){return{from:f(this.ka(t.from,!0)),to:f(this.ka(t.to,!0))}}$i(){return this.e_}m_(t){if(!isFinite(t)||t<=0)return;if(this.e_===t)return;const i=this.yu(),n=this.e_;if(this.e_=t,this.ou=!0,this.cn.lockVisibleTimeRangeOnResize&&0!==n){const i=this.mu*t/n;this.mu=i}if(this.cn.fixLeftEdge&&null!==i&&i.Os()<=0){const i=n-t;this.pu-=Math.round(i/this.mu)+1,this.ou=!0}this.Du(),this.Ou()}It(t){if(this.Fi()||!P(t))return 0;const i=this.Au()+this.pu-t;return this.e_-(i+.5)*this.mu-1}Js(t,i){const n=this.Au(),s=void 0===i?0:i.from,e=void 0===i?t.length:i.to;for(let i=s;ii/2&&!o?n.needAlignCoordinate=!1:n.needAlignCoordinate=_&&t.index<=l||u&&t.index>=a,c++}return this.vu.length=c,this.fu=this.vu,this.vu}Fu(){this.ou=!0,this.Gn(this.cn.barSpacing),this.Jn(this.cn.rightOffset)}Wu(t){this.ou=!0,this.eu=t,this.Ou(),this.Mu()}ju(t,i){const n=this.Vu(t),s=this.he(),e=s+i*(s/10);this.Gn(e),this.cn.rightBarStaysOnScroll||this.Jn(this.Iu()+(n-this.Vu(t)))}Uo(t){this.fo&&this.Zo(),null===this.do&&null===this.du&&(this.Fi()||(this.do=t,this.Hu()))}qo(t){if(null===this.du)return;const i=Mt(this.e_-t,0,this.e_),n=Mt(this.e_-f(this.do),0,this.e_);0!==i&&0!==n&&this.Gn(this.du.he*i/n)}Yo(){null!==this.do&&(this.do=null,this.$u())}Xo(t){null===this.fo&&null===this.du&&(this.Fi()||(this.fo=t,this.Hu()))}Ko(t){if(null===this.fo)return;const i=(this.fo-t)/this.he();this.pu=f(this.du).Iu+i,this.ou=!0,this.Ou()}Zo(){null!==this.fo&&(this.fo=null,this.$u())}Uu(){this.qu(this.cn.rightOffset)}qu(t,i=400){if(!isFinite(t))throw new RangeError("offset is required and must be finite number");if(!isFinite(i)||i<=0)throw new RangeError("animationDuration (optional) must be finite positive number");const n=this.pu,s=performance.now();this.Ui.Xn({Yu:t=>(t-s)/i>=1,Xu:e=>{const r=(e-s)/i;return r>=1?t:n+(t-n)*r}})}gt(t,i){this.ou=!0,this.ru=t,this.hu.K_(t,i),this.Ou()}Ku(){return this._u}Zu(){return this.uu}Gu(){return this.cu}Au(){return this.eu||0}Ju(t){const i=t.U_();this.Eu(this.e_/i),this.pu=t.di()-this.Au(),this.Ou(),this.ou=!0,this.Ui.zu(),this.Ui.Fh()}Qu(){const t=this.Tu(),i=this.Pu();null!==t&&null!==i&&this.Ju(new bn(t,i+this.cn.rightOffset))}tc(t){const i=new bn(t.from,t.to);this.Ju(i)}Yi(t){return void 0!==this.bo.timeFormatter?this.bo.timeFormatter(t.originalTime):this.N_.formatHorzItem(t.time)}Lu(){const{handleScroll:t,handleScale:i}=this.Ui.W();return!(t.horzTouchDrag||t.mouseWheel||t.pressedMouseMove||t.vertTouchDrag||i.axisDoubleClickReset.time||i.axisPressedMouseMove.time||i.mouseWheel||i.pinch)}Tu(){return 0===this.ru.length?null:0}Pu(){return 0===this.ru.length?null:this.ru.length-1}ic(t){return(this.e_-1-t)/this.mu}Vu(t){const i=this.ic(t),n=this.Au()+this.pu-i;return Math.round(1e6*n)/1e6}Eu(t){const i=this.mu;this.mu=t,this.Du(),i!==this.mu&&(this.ou=!0,this.nc())}Su(){if(!this.ou)return;if(this.ou=!1,this.Fi())return void this.sc(Mn.su());const t=this.Au(),i=this.e_/this.mu,n=this.pu+t,s=new bn(n-i+1,n);this.sc(new Mn(s))}Du(){const t=this.ec();if(this.mut&&(this.mu=t,this.ou=!0)}}ec(){return this.cn.fixLeftEdge&&this.cn.fixRightEdge&&0!==this.ru.length?this.e_/this.ru.length:this.cn.minBarSpacing}Ou(){const t=this.rc();this.pu>t&&(this.pu=t,this.ou=!0);const i=this.hc();null!==i&&this.puthis.lc(t)),this.N_),this.lu.set(t.weight,i)),i.F_(t)}lc(t){return this.N_.formatTickmark(t,this.bo)}sc(t){const i=this.au;this.au=t,wn(i.iu(),this.au.iu())||this._u.m(),wn(i.nu(),this.au.nu())||this.uu.m(),this.nc()}nc(){this.fu=null}gu(){this.nc(),this.lu.clear()}bu(){this.N_.updateFormatter(this.bo)}Mu(){if(!this.cn.fixLeftEdge)return;const t=this.Tu();if(null===t)return;const i=this.Xs();if(null===i)return;const n=i.Os()-t;if(n<0){const t=this.pu-n-1;this.Jn(t)}this.Du()}xu(){this.Ou(),this.Du()}}class yn extends L{constructor(t){super(),this.ac=new Map,this.Lt=t}Z(t){}J(t){if(!this.Lt.Tt)return;const{context:i,mediaSize:n}=t;let s=0;for(const t of this.Lt.oc){if(0===t.Jt.length)continue;i.font=t.R;const e=this._c(i,t.Jt);e>n.width?t.ju=n.width/e:t.ju=1,s+=t.uc*t.ju}let e=0;switch(this.Lt.cc){case"top":e=0;break;case"center":e=Math.max((n.height-s)/2,0);break;case"bottom":e=Math.max(n.height-s,0)}i.fillStyle=this.Lt.O;for(const t of this.Lt.oc){i.save();let s=0;switch(this.Lt.dc){case"left":i.textAlign="left",s=t.uc/2;break;case"center":i.textAlign="center",s=n.width/2;break;case"right":i.textAlign="right",s=n.width-1-t.uc/2}i.translate(s,e),i.textBaseline="top",i.font=t.R,i.scale(t.ju,t.ju),i.fillText(t.Jt,0,t.fc),i.restore(),e+=t.uc*t.ju}}_c(t,i){const n=this.vc(t.font);let s=n.get(i);return void 0===s&&(s=t.measureText(i).width,n.set(i,s)),s}vc(t){let i=this.ac.get(t);return void 0===i&&(i=new Map,this.ac.set(t,i)),i}}class kn{constructor(t){this.bt=!0,this.jt={Tt:!1,O:"",oc:[],cc:"center",dc:"center"},this.Ht=new yn(this.jt),this.$t=t}gt(){this.bt=!0}xt(){return this.bt&&(this.St(),this.bt=!1),this.Ht}St(){const t=this.$t.W(),i=this.jt;i.Tt=t.visible,i.Tt&&(i.O=t.color,i.dc=t.horzAlign,i.cc=t.vertAlign,i.oc=[{Jt:t.text,R:z(t.fontSize,t.fontFamily,t.fontStyle),uc:1.2*t.fontSize,fc:0,ju:0}])}}class Cn extends et{constructor(t,i){super(),this.cn=i,this.wn=new kn(this)}Rn(){return[]}Pn(){return[this.wn]}W(){return this.cn}On(){this.wn.gt()}}var Tn,Pn,Rn,Dn,On;!function(t){t[t.OnTouchEnd=0]="OnTouchEnd",t[t.OnNextTap=1]="OnNextTap"}(Tn||(Tn={}));class An{constructor(t,i,n){this.mc=[],this.bc=[],this.e_=0,this.wc=null,this.gc=new k,this.Mc=new k,this.xc=null,this.Sc=t,this.cn=i,this.N_=n,this.yc=new E(this),this.wl=new Sn(this,i.timeScale,this.cn.localization,n),this.wt=new ht(this,i.crosshair),this.kc=new Xi(i.crosshair),this.Cc=new Cn(this,i.watermark),this.Tc(),this.mc[0].p_(2e3),this.Pc=this.Rc(0),this.Dc=this.Rc(1)}$l(){this.Oc(at.es())}Fh(){this.Oc(at.ss())}sa(){this.Oc(new at(1))}Ul(t){const i=this.Ac(t);this.Oc(i)}Bc(){return this.wc}Vc(t){const i=this.wc;this.wc=t,null!==i&&this.Ul(i.zc),null!==t&&this.Ul(t.zc)}W(){return this.cn}Nh(t){C(this.cn,t),this.mc.forEach((i=>i.c_(t))),void 0!==t.timeScale&&this.wl.Nh(t.timeScale),void 0!==t.localization&&this.wl.wu(t.localization),(t.leftPriceScale||t.rightPriceScale)&&this.gc.m(),this.Pc=this.Rc(0),this.Dc=this.Rc(1),this.$l()}Ec(t,i){if("left"===t)return void this.Nh({leftPriceScale:i});if("right"===t)return void this.Nh({rightPriceScale:i});const n=this.Ic(t);null!==n&&(n.At.Nh(i),this.gc.m())}Ic(t){for(const i of this.mc){const n=i.d_(t);if(null!==n)return{Ut:i,At:n}}return null}kt(){return this.wl}Lc(){return this.mc}Nc(){return this.Cc}Fc(){return this.wt}Wc(){return this.Mc}jc(t,i){t.Oo(i),this.zu()}m_(t){this.e_=t,this.wl.m_(this.e_),this.mc.forEach((i=>i.m_(t))),this.zu()}Tc(t){const i=new pn(this.wl,this);void 0!==t?this.mc.splice(t,0,i):this.mc.push(i);const n=void 0===t?this.mc.length-1:t,s=at.es();return s.Nn(n,{Fn:0,Wn:!0}),this.Oc(s),i}k_(t,i,n){t.k_(i,n)}C_(t,i,n){t.C_(i,n),this.ql(),this.Oc(this.Hc(t,2))}T_(t,i){t.T_(i),this.Oc(this.Hc(t,2))}P_(t,i,n){i.ko()||t.P_(i,n)}R_(t,i,n){i.ko()||(t.R_(i,n),this.ql(),this.Oc(this.Hc(t,2)))}D_(t,i){i.ko()||(t.D_(i),this.Oc(this.Hc(t,2)))}A_(t,i){t.A_(i),this.Oc(this.Hc(t,2))}$c(t){this.wl.Uo(t)}Uc(t,i){const n=this.kt();if(n.Fi()||0===i)return;const s=n.$i();t=Math.max(1,Math.min(t,s)),n.ju(t,i),this.zu()}qc(t){this.Yc(0),this.Xc(t),this.Kc()}Zc(t){this.wl.qo(t),this.zu()}Gc(){this.wl.Yo(),this.Fh()}Yc(t){this.wl.Xo(t)}Xc(t){this.wl.Ko(t),this.zu()}Kc(){this.wl.Zo(),this.Fh()}Mt(){return this.bc}Jc(t,i,n,s,e){this.wt.gn(t,i);let r=NaN,h=this.wl.Bu(t);const l=this.wl.Xs();null!==l&&(h=Math.min(Math.max(l.Os(),h),l.di()));const a=s.vn(),o=a.Pt();null!==o&&(r=a.pn(i,o)),r=this.kc.Ca(r,h,s),this.wt.yn(h,r,s),this.sa(),e||this.Mc.m(this.wt.yt(),{x:t,y:i},n)}Qc(t,i,n){const s=n.vn(),e=s.Pt(),r=s.Ot(t,f(e)),h=this.wl.ka(i,!0),l=this.wl.It(f(h));this.Jc(l,r,null,n,!0)}td(t){this.Fc().Cn(),this.sa(),t||this.Mc.m(null,null,null)}ql(){const t=this.wt.Ut();if(null!==t){const i=this.wt.xn(),n=this.wt.Sn();this.Jc(i,n,null,t)}this.wt.On()}nd(t,i,n){const s=this.wl.mn(0);void 0!==i&&void 0!==n&&this.wl.gt(i,n);const e=this.wl.mn(0),r=this.wl.Au(),h=this.wl.Xs();if(null!==h&&null!==s&&null!==e){const i=h.Kr(r),l=this.N_.key(s)>this.N_.key(e),a=null!==t&&t>r&&!l,o=this.wl.W().allowShiftVisibleRangeOnWhitespaceReplacement,_=i&&(!(void 0===n)||o)&&this.wl.W().shiftVisibleRangeOnNewBar;if(a&&!_){const i=t-r;this.wl.Jn(this.wl.Iu()-i)}}this.wl.Wu(t)}Kl(t){null!==t&&t.V_()}cr(t){const i=this.mc.find((i=>i.No().includes(t)));return void 0===i?null:i}zu(){this.Cc.On(),this.mc.forEach((t=>t.V_())),this.ql()}S(){this.mc.forEach((t=>t.S())),this.mc.length=0,this.cn.localization.priceFormatter=void 0,this.cn.localization.percentageFormatter=void 0,this.cn.localization.timeFormatter=void 0}sd(){return this.yc}mr(){return this.yc.W()}f_(){return this.gc}ed(t,i,n){const s=this.mc[0],e=this.rd(i,t,s,n);return this.bc.push(e),1===this.bc.length?this.$l():this.Fh(),e}hd(t){const i=this.cr(t),n=this.bc.indexOf(t);c(-1!==n,"Series not found"),this.bc.splice(n,1),f(i).jo(t),t.S&&t.S()}Hl(t,i){const n=f(this.cr(t));n.jo(t);const s=this.Ic(i);if(null===s){const s=t.Zi();n.Fo(t,i,s)}else{const e=s.Ut===n?t.Zi():void 0;s.Ut.Fo(t,i,e)}}Qu(){const t=at.ss();t.$n(),this.Oc(t)}ld(t){const i=at.ss();i.Yn(t),this.Oc(i)}Zn(){const t=at.ss();t.Zn(),this.Oc(t)}Gn(t){const i=at.ss();i.Gn(t),this.Oc(i)}Jn(t){const i=at.ss();i.Jn(t),this.Oc(i)}Xn(t){const i=at.ss();i.Xn(t),this.Oc(i)}Un(){const t=at.ss();t.Un(),this.Oc(t)}ad(){return this.cn.rightPriceScale.visible?"right":"left"}od(){return this.Dc}q(){return this.Pc}zt(t){const i=this.Dc,n=this.Pc;if(i===n)return i;if(t=Math.max(0,Math.min(100,Math.round(100*t))),null===this.xc||this.xc.Ts!==n||this.xc.Ps!==i)this.xc={Ts:n,Ps:i,_d:new Map};else{const i=this.xc._d.get(t);if(void 0!==i)return i}const s=function(t,i,n){const[s,e,r,h]=S(t),[l,a,o,_]=S(i),u=[m(s+n*(l-s)),m(e+n*(a-e)),m(r+n*(o-r)),b(h+n*(_-h))];return`rgba(${u[0]}, ${u[1]}, ${u[2]}, ${u[3]})`}(n,i,t/100);return this.xc._d.set(t,s),s}Hc(t,i){const n=new at(i);if(null!==t){const s=this.mc.indexOf(t);n.Nn(s,{Fn:i})}return n}Ac(t,i){return void 0===i&&(i=2),this.Hc(this.cr(t),i)}Oc(t){this.Sc&&this.Sc(t),this.mc.forEach((t=>t.E_().Wh().gt()))}rd(t,i,n,s){const e=new Yi(this,t,i,n,s),r=void 0!==t.priceScaleId?t.priceScaleId:this.ad();return n.Fo(e,r),lt(r)||e.Nh(t),e}Rc(t){const i=this.cn.layout;return"gradient"===i.background.type?0===t?i.background.topColor:i.background.bottomColor:i.background.color}}function Bn(t){return!T(t)&&!R(t)}function Vn(t){return T(t)}!function(t){t[t.Disabled=0]="Disabled",t[t.Continuous=1]="Continuous",t[t.OnDataUpdate=2]="OnDataUpdate"}(Pn||(Pn={})),function(t){t[t.LastBar=0]="LastBar",t[t.LastVisible=1]="LastVisible"}(Rn||(Rn={})),function(t){t.Solid="solid",t.VerticalGradient="gradient"}(Dn||(Dn={})),function(t){t[t.Year=0]="Year",t[t.Month=1]="Month",t[t.DayOfMonth=2]="DayOfMonth",t[t.Time=3]="Time",t[t.TimeWithSeconds=4]="TimeWithSeconds"}(On||(On={}));const zn=t=>t.getUTCFullYear();function En(t,i,n){return i.replace(/yyyy/g,(t=>_t(zn(t),4))(t)).replace(/yy/g,(t=>_t(zn(t)%100,2))(t)).replace(/MMMM/g,((t,i)=>new Date(t.getUTCFullYear(),t.getUTCMonth(),1).toLocaleString(i,{month:"long"}))(t,n)).replace(/MMM/g,((t,i)=>new Date(t.getUTCFullYear(),t.getUTCMonth(),1).toLocaleString(i,{month:"short"}))(t,n)).replace(/MM/g,(t=>_t((t=>t.getUTCMonth()+1)(t),2))(t)).replace(/dd/g,(t=>_t((t=>t.getUTCDate())(t),2))(t))}class In{constructor(t="yyyy-MM-dd",i="default"){this.ud=t,this.dd=i}F_(t){return En(t,this.ud,this.dd)}}class Ln{constructor(t){this.fd=t||"%h:%m:%s"}F_(t){return this.fd.replace("%h",_t(t.getUTCHours(),2)).replace("%m",_t(t.getUTCMinutes(),2)).replace("%s",_t(t.getUTCSeconds(),2))}}const Nn={vd:"yyyy-MM-dd",pd:"%h:%m:%s",md:" ",bd:"default"};class Fn{constructor(t={}){const i=Object.assign(Object.assign({},Nn),t);this.wd=new In(i.vd,i.bd),this.gd=new Ln(i.pd),this.Md=i.md}F_(t){return`${this.wd.F_(t)}${this.Md}${this.gd.F_(t)}`}}function Wn(t){return 60*t*60*1e3}function jn(t){return 60*t*1e3}const Hn=[{xd:($n=1,1e3*$n),Sd:10},{xd:jn(1),Sd:20},{xd:jn(5),Sd:21},{xd:jn(30),Sd:22},{xd:Wn(1),Sd:30},{xd:Wn(3),Sd:31},{xd:Wn(6),Sd:32},{xd:Wn(12),Sd:33}];var $n;function Un(t,i){if(t.getUTCFullYear()!==i.getUTCFullYear())return 70;if(t.getUTCMonth()!==i.getUTCMonth())return 60;if(t.getUTCDate()!==i.getUTCDate())return 50;for(let n=Hn.length-1;n>=0;--n)if(Math.floor(i.getTime()/Hn[n].xd)!==Math.floor(t.getTime()/Hn[n].xd))return Hn[n].Sd;return 0}function qn(t){let i=t;if(R(t)&&(i=Xn(t)),!Bn(i))throw new Error("time must be of type BusinessDay");const n=new Date(Date.UTC(i.year,i.month-1,i.day,0,0,0,0));return{yd:Math.round(n.getTime()/1e3),kd:i}}function Yn(t){if(!Vn(t))throw new Error("time must be of type isUTCTimestamp");return{yd:t}}function Xn(t){const i=new Date(t);if(isNaN(i.getTime()))throw new Error(`Invalid date string=${t}, expected format=yyyy-mm-dd`);return{day:i.getUTCDate(),month:i.getUTCMonth()+1,year:i.getUTCFullYear()}}function Kn(t){R(t.time)&&(t.time=Xn(t.time))}class Zn{options(){return this.cn}setOptions(t){this.cn=t,this.updateFormatter(t.localization)}preprocessData(t){Array.isArray(t)?function(t){t.forEach(Kn)}(t):Kn(t)}createConverterToInternalObj(t){return f(function(t){return 0===t.length?null:Bn(t[0].time)||R(t[0].time)?qn:Yn}(t))}key(t){return"object"==typeof t&&"yd"in t?t.yd:this.key(this.convertHorzItemToInternal(t))}cacheKey(t){const i=t;return void 0===i.kd?new Date(1e3*i.yd).getTime():new Date(Date.UTC(i.kd.year,i.kd.month-1,i.kd.day)).getTime()}convertHorzItemToInternal(t){return Vn(i=t)?Yn(i):Bn(i)?qn(i):qn(Xn(i));var i}updateFormatter(t){if(!this.cn)return;const i=t.dateFormat;this.cn.timeScale.timeVisible?this.Cd=new Fn({vd:i,pd:this.cn.timeScale.secondsVisible?"%h:%m:%s":"%h:%m",md:" ",bd:t.locale}):this.Cd=new In(i,t.locale)}formatHorzItem(t){const i=t;return this.Cd.F_(new Date(1e3*i.yd))}formatTickmark(t,i){const n=function(t,i,n){switch(t){case 0:case 10:return i?n?4:3:2;case 20:case 21:case 22:case 30:case 31:case 32:case 33:return i?3:2;case 50:return 2;case 60:return 1;case 70:return 0}}(t.weight,this.cn.timeScale.timeVisible,this.cn.timeScale.secondsVisible),s=this.cn.timeScale;if(void 0!==s.tickMarkFormatter){const e=s.tickMarkFormatter(t.originalTime,n,i.locale);if(null!==e)return e}return function(t,i,n){const s={};switch(i){case 0:s.year="numeric";break;case 1:s.month="short";break;case 2:s.day="numeric";break;case 3:s.hour12=!1,s.hour="2-digit",s.minute="2-digit";break;case 4:s.hour12=!1,s.hour="2-digit",s.minute="2-digit",s.second="2-digit"}const e=void 0===t.kd?new Date(1e3*t.yd):new Date(Date.UTC(t.kd.year,t.kd.month-1,t.kd.day));return new Date(e.getUTCFullYear(),e.getUTCMonth(),e.getUTCDate(),e.getUTCHours(),e.getUTCMinutes(),e.getUTCSeconds(),e.getUTCMilliseconds()).toLocaleString(n,s)}(t.time,n,i.locale)}maxTickMarkWeight(t){let i=t.reduce(xn,t[0]).weight;return i>30&&i<50&&(i=30),i}fillWeightsForPoints(t,i){!function(t,i=0){if(0===t.length)return;let n=0===i?null:t[i-1].time.yd,s=null!==n?new Date(1e3*n):null,e=0;for(let r=i;r1){const i=Math.ceil(e/(t.length-1)),n=new Date(1e3*(t[0].time.yd-i));t[0].timeWeight=Un(new Date(1e3*t[0].time.yd),n)}}(t,i)}static Td(t){return C({localization:{dateFormat:"dd MMM 'yy"}},null!=t?t:{})}}function Gn(t){var i=t.width,n=t.height;if(i<0)throw new Error("Negative width is not allowed for Size");if(n<0)throw new Error("Negative height is not allowed for Size");return{width:i,height:n}}function Jn(t,i){return t.width===i.width&&t.height===i.height}var Qn=function(){function t(t){var i=this;this._resolutionListener=function(){return i._onResolutionChanged()},this._resolutionMediaQueryList=null,this._observers=[],this._window=t,this._installResolutionListener()}return t.prototype.dispose=function(){this._uninstallResolutionListener(),this._window=null},Object.defineProperty(t.prototype,"value",{get:function(){return this._window.devicePixelRatio},enumerable:!1,configurable:!0}),t.prototype.subscribe=function(t){var i=this,n={next:t};return this._observers.push(n),{unsubscribe:function(){i._observers=i._observers.filter((function(t){return t!==n}))}}},t.prototype._installResolutionListener=function(){if(null!==this._resolutionMediaQueryList)throw new Error("Resolution listener is already installed");var t=this._window.devicePixelRatio;this._resolutionMediaQueryList=this._window.matchMedia("all and (resolution: ".concat(t,"dppx)")),this._resolutionMediaQueryList.addListener(this._resolutionListener)},t.prototype._uninstallResolutionListener=function(){null!==this._resolutionMediaQueryList&&(this._resolutionMediaQueryList.removeListener(this._resolutionListener),this._resolutionMediaQueryList=null)},t.prototype._reinstallResolutionListener=function(){this._uninstallResolutionListener(),this._installResolutionListener()},t.prototype._onResolutionChanged=function(){var t=this;this._observers.forEach((function(i){return i.next(t._window.devicePixelRatio)})),this._reinstallResolutionListener()},t}();var ts=function(){function t(t,i,n){var s;this._canvasElement=null,this._bitmapSizeChangedListeners=[],this._suggestedBitmapSize=null,this._suggestedBitmapSizeChangedListeners=[],this._devicePixelRatioObservable=null,this._canvasElementResizeObserver=null,this._canvasElement=t,this._canvasElementClientSize=Gn({width:this._canvasElement.clientWidth,height:this._canvasElement.clientHeight}),this._transformBitmapSize=null!=i?i:function(t){return t},this._allowResizeObserver=null===(s=null==n?void 0:n.allowResizeObserver)||void 0===s||s,this._chooseAndInitObserver()}return t.prototype.dispose=function(){var t,i;if(null===this._canvasElement)throw new Error("Object is disposed");null===(t=this._canvasElementResizeObserver)||void 0===t||t.disconnect(),this._canvasElementResizeObserver=null,null===(i=this._devicePixelRatioObservable)||void 0===i||i.dispose(),this._devicePixelRatioObservable=null,this._suggestedBitmapSizeChangedListeners.length=0,this._bitmapSizeChangedListeners.length=0,this._canvasElement=null},Object.defineProperty(t.prototype,"canvasElement",{get:function(){if(null===this._canvasElement)throw new Error("Object is disposed");return this._canvasElement},enumerable:!1,configurable:!0}),Object.defineProperty(t.prototype,"canvasElementClientSize",{get:function(){return this._canvasElementClientSize},enumerable:!1,configurable:!0}),Object.defineProperty(t.prototype,"bitmapSize",{get:function(){return Gn({width:this.canvasElement.width,height:this.canvasElement.height})},enumerable:!1,configurable:!0}),t.prototype.resizeCanvasElement=function(t){this._canvasElementClientSize=Gn(t),this.canvasElement.style.width="".concat(this._canvasElementClientSize.width,"px"),this.canvasElement.style.height="".concat(this._canvasElementClientSize.height,"px"),this._invalidateBitmapSize()},t.prototype.subscribeBitmapSizeChanged=function(t){this._bitmapSizeChangedListeners.push(t)},t.prototype.unsubscribeBitmapSizeChanged=function(t){this._bitmapSizeChangedListeners=this._bitmapSizeChangedListeners.filter((function(i){return i!==t}))},Object.defineProperty(t.prototype,"suggestedBitmapSize",{get:function(){return this._suggestedBitmapSize},enumerable:!1,configurable:!0}),t.prototype.subscribeSuggestedBitmapSizeChanged=function(t){this._suggestedBitmapSizeChangedListeners.push(t)},t.prototype.unsubscribeSuggestedBitmapSizeChanged=function(t){this._suggestedBitmapSizeChangedListeners=this._suggestedBitmapSizeChangedListeners.filter((function(i){return i!==t}))},t.prototype.applySuggestedBitmapSize=function(){if(null!==this._suggestedBitmapSize){var t=this._suggestedBitmapSize;this._suggestedBitmapSize=null,this._resizeBitmap(t),this._emitSuggestedBitmapSizeChanged(t,this._suggestedBitmapSize)}},t.prototype._resizeBitmap=function(t){var i=this.bitmapSize;Jn(i,t)||(this.canvasElement.width=t.width,this.canvasElement.height=t.height,this._emitBitmapSizeChanged(i,t))},t.prototype._emitBitmapSizeChanged=function(t,i){var n=this;this._bitmapSizeChangedListeners.forEach((function(s){return s.call(n,t,i)}))},t.prototype._suggestNewBitmapSize=function(t){var i=this._suggestedBitmapSize,n=Gn(this._transformBitmapSize(t,this._canvasElementClientSize)),s=Jn(this.bitmapSize,n)?null:n;null===i&&null===s||null!==i&&null!==s&&Jn(i,s)||(this._suggestedBitmapSize=s,this._emitSuggestedBitmapSizeChanged(i,s))},t.prototype._emitSuggestedBitmapSizeChanged=function(t,i){var n=this;this._suggestedBitmapSizeChangedListeners.forEach((function(s){return s.call(n,t,i)}))},t.prototype._chooseAndInitObserver=function(){var t=this;this._allowResizeObserver?new Promise((function(t){var i=new ResizeObserver((function(n){t(n.every((function(t){return"devicePixelContentBoxSize"in t}))),i.disconnect()}));i.observe(document.body,{box:"device-pixel-content-box"})})).catch((function(){return!1})).then((function(i){return i?t._initResizeObserver():t._initDevicePixelRatioObservable()})):this._initDevicePixelRatioObservable()},t.prototype._initDevicePixelRatioObservable=function(){var t=this;if(null!==this._canvasElement){var i=is(this._canvasElement);if(null===i)throw new Error("No window is associated with the canvas");this._devicePixelRatioObservable=function(t){return new Qn(t)}(i),this._devicePixelRatioObservable.subscribe((function(){return t._invalidateBitmapSize()})),this._invalidateBitmapSize()}},t.prototype._invalidateBitmapSize=function(){var t,i;if(null!==this._canvasElement){var n=is(this._canvasElement);if(null!==n){var s=null!==(i=null===(t=this._devicePixelRatioObservable)||void 0===t?void 0:t.value)&&void 0!==i?i:n.devicePixelRatio,e=this._canvasElement.getClientRects(),r=void 0!==e[0]?function(t,i){return Gn({width:Math.round(t.left*i+t.width*i)-Math.round(t.left*i),height:Math.round(t.top*i+t.height*i)-Math.round(t.top*i)})}(e[0],s):Gn({width:this._canvasElementClientSize.width*s,height:this._canvasElementClientSize.height*s});this._suggestNewBitmapSize(r)}}},t.prototype._initResizeObserver=function(){var t=this;null!==this._canvasElement&&(this._canvasElementResizeObserver=new ResizeObserver((function(i){var n=i.find((function(i){return i.target===t._canvasElement}));if(n&&n.devicePixelContentBoxSize&&n.devicePixelContentBoxSize[0]){var s=n.devicePixelContentBoxSize[0],e=Gn({width:s.inlineSize,height:s.blockSize});t._suggestNewBitmapSize(e)}})),this._canvasElementResizeObserver.observe(this._canvasElement,{box:"device-pixel-content-box"}))},t}();function is(t){return t.ownerDocument.defaultView}var ns=function(){function t(t,i,n){if(0===i.width||0===i.height)throw new TypeError("Rendering target could only be created on a media with positive width and height");if(this._mediaSize=i,0===n.width||0===n.height)throw new TypeError("Rendering target could only be created using a bitmap with positive integer width and height");this._bitmapSize=n,this._context=t}return t.prototype.useMediaCoordinateSpace=function(t){try{return this._context.save(),this._context.setTransform(1,0,0,1,0,0),this._context.scale(this._horizontalPixelRatio,this._verticalPixelRatio),t({context:this._context,mediaSize:this._mediaSize})}finally{this._context.restore()}},t.prototype.useBitmapCoordinateSpace=function(t){try{return this._context.save(),this._context.setTransform(1,0,0,1,0,0),t({context:this._context,mediaSize:this._mediaSize,bitmapSize:this._bitmapSize,horizontalPixelRatio:this._horizontalPixelRatio,verticalPixelRatio:this._verticalPixelRatio})}finally{this._context.restore()}},Object.defineProperty(t.prototype,"_horizontalPixelRatio",{get:function(){return this._bitmapSize.width/this._mediaSize.width},enumerable:!1,configurable:!0}),Object.defineProperty(t.prototype,"_verticalPixelRatio",{get:function(){return this._bitmapSize.height/this._mediaSize.height},enumerable:!1,configurable:!0}),t}();function ss(t,i){var n=t.canvasElementClientSize;if(0===n.width||0===n.height)return null;var s=t.bitmapSize;if(0===s.width||0===s.height)return null;var e=t.canvasElement.getContext("2d",i);return null===e?null:new ns(e,n,s)}const es="undefined"!=typeof window;function rs(){return!!es&&window.navigator.userAgent.toLowerCase().indexOf("firefox")>-1}function hs(){return!!es&&/iPhone|iPad|iPod/.test(window.navigator.platform)}function ls(t){return t+t%2}function as(t,i){return t.Pd-i.Pd}function os(t,i,n){const s=(t.Pd-i.Pd)/(t.ut-i.ut);return Math.sign(s)*Math.min(Math.abs(s),n)}class _s{constructor(t,i,n,s){this.Rd=null,this.Dd=null,this.Od=null,this.Ad=null,this.Bd=null,this.Vd=0,this.zd=0,this.Ed=t,this.Id=i,this.Ld=n,this.rs=s}Nd(t,i){if(null!==this.Rd){if(this.Rd.ut===i)return void(this.Rd.Pd=t);if(Math.abs(this.Rd.Pd-t)50)return;let n=0;const s=os(this.Rd,this.Dd,this.Id),e=as(this.Rd,this.Dd),r=[s],h=[e];if(n+=e,null!==this.Od){const t=os(this.Dd,this.Od,this.Id);if(Math.sign(t)===Math.sign(s)){const i=as(this.Dd,this.Od);if(r.push(t),h.push(i),n+=i,null!==this.Ad){const t=os(this.Od,this.Ad,this.Id);if(Math.sign(t)===Math.sign(s)){const i=as(this.Od,this.Ad);r.push(t),h.push(i),n+=i}}}}let l=0;for(let t=0;t({width:Math.max(t.width,i.width),height:Math.max(t.height,i.height)})});return s.resizeCanvasElement(i),s}function cs(t,i,n,s){t.G&&t.G(i,n,s)}function ds(t,i,n,s){t.K(i,n,s)}function fs(t,i,n,s){const e=t(n,s);for(const t of e){const n=t.xt();null!==n&&i(n)}}function vs(t){es&&void 0!==window.chrome&&t.addEventListener("mousedown",(t=>{if(1===t.button)return t.preventDefault(),!1}))}class ps{constructor(t,i,n){this.Wd=0,this.jd=null,this.Hd={et:Number.NEGATIVE_INFINITY,rt:Number.POSITIVE_INFINITY},this.$d=0,this.Ud=null,this.qd={et:Number.NEGATIVE_INFINITY,rt:Number.POSITIVE_INFINITY},this.Yd=null,this.Xd=!1,this.Kd=null,this.Zd=null,this.Gd=!1,this.Jd=!1,this.Qd=!1,this.tf=null,this.if=null,this.nf=null,this.sf=null,this.ef=null,this.rf=null,this.hf=null,this.lf=0,this.af=!1,this._f=!1,this.uf=!1,this.cf=0,this.df=null,this.ff=!hs(),this.vf=t=>{this.pf(t)},this.mf=t=>{if(this.bf(t)){const i=this.wf(t);if(++this.$d,this.Ud&&this.$d>1){const{gf:n}=this.Mf(ws(t),this.qd);n<30&&!this.Qd&&this.xf(i,this.yf.Sf),this.kf()}}else{const i=this.wf(t);if(++this.Wd,this.jd&&this.Wd>1){const{gf:n}=this.Mf(ws(t),this.Hd);n<5&&!this.Jd&&this.Cf(i,this.yf.Tf),this.Pf()}}},this.Rf=t,this.yf=i,this.cn=n,this.Df()}S(){null!==this.tf&&(this.tf(),this.tf=null),null!==this.if&&(this.if(),this.if=null),null!==this.sf&&(this.sf(),this.sf=null),null!==this.ef&&(this.ef(),this.ef=null),null!==this.rf&&(this.rf(),this.rf=null),null!==this.nf&&(this.nf(),this.nf=null),this.Of(),this.Pf()}Af(t){this.sf&&this.sf();const i=this.Bf.bind(this);if(this.sf=()=>{this.Rf.removeEventListener("mousemove",i)},this.Rf.addEventListener("mousemove",i),this.bf(t))return;const n=this.wf(t);this.Cf(n,this.yf.Vf),this.ff=!0}Pf(){null!==this.jd&&clearTimeout(this.jd),this.Wd=0,this.jd=null,this.Hd={et:Number.NEGATIVE_INFINITY,rt:Number.POSITIVE_INFINITY}}kf(){null!==this.Ud&&clearTimeout(this.Ud),this.$d=0,this.Ud=null,this.qd={et:Number.NEGATIVE_INFINITY,rt:Number.POSITIVE_INFINITY}}Bf(t){if(this.uf||null!==this.Zd)return;if(this.bf(t))return;const i=this.wf(t);this.Cf(i,this.yf.zf),this.ff=!0}Ef(t){const i=Ms(t.changedTouches,f(this.df));if(null===i)return;if(this.cf=gs(t),null!==this.hf)return;if(this._f)return;this.af=!0;const n=this.Mf(ws(i),f(this.Zd)),{If:s,Lf:e,gf:r}=n;if(this.Gd||!(r<5)){if(!this.Gd){const t=.5*s,i=e>=t&&!this.cn.Nf(),n=t>e&&!this.cn.Ff();i||n||(this._f=!0),this.Gd=!0,this.Qd=!0,this.Of(),this.kf()}if(!this._f){const n=this.wf(t,i);this.xf(n,this.yf.Wf),bs(t)}}}jf(t){if(0!==t.button)return;const i=this.Mf(ws(t),f(this.Kd)),{gf:n}=i;if(n>=5&&(this.Jd=!0,this.Pf()),this.Jd){const i=this.wf(t);this.Cf(i,this.yf.Hf)}}Mf(t,i){const n=Math.abs(i.et-t.et),s=Math.abs(i.rt-t.rt);return{If:n,Lf:s,gf:n+s}}$f(t){let i=Ms(t.changedTouches,f(this.df));if(null===i&&0===t.touches.length&&(i=t.changedTouches[0]),null===i)return;this.df=null,this.cf=gs(t),this.Of(),this.Zd=null,this.rf&&(this.rf(),this.rf=null);const n=this.wf(t,i);if(this.xf(n,this.yf.Uf),++this.$d,this.Ud&&this.$d>1){const{gf:t}=this.Mf(ws(i),this.qd);t<30&&!this.Qd&&this.xf(n,this.yf.Sf),this.kf()}else this.Qd||(this.xf(n,this.yf.qf),this.yf.qf&&bs(t));0===this.$d&&bs(t),0===t.touches.length&&this.Xd&&(this.Xd=!1,bs(t))}pf(t){if(0!==t.button)return;const i=this.wf(t);if(this.Kd=null,this.uf=!1,this.ef&&(this.ef(),this.ef=null),rs()){this.Rf.ownerDocument.documentElement.removeEventListener("mouseleave",this.vf)}if(!this.bf(t))if(this.Cf(i,this.yf.Yf),++this.Wd,this.jd&&this.Wd>1){const{gf:n}=this.Mf(ws(t),this.Hd);n<5&&!this.Jd&&this.Cf(i,this.yf.Tf),this.Pf()}else this.Jd||this.Cf(i,this.yf.Xf)}Of(){null!==this.Yd&&(clearTimeout(this.Yd),this.Yd=null)}Kf(t){if(null!==this.df)return;const i=t.changedTouches[0];this.df=i.identifier,this.cf=gs(t);const n=this.Rf.ownerDocument.documentElement;this.Qd=!1,this.Gd=!1,this._f=!1,this.Zd=ws(i),this.rf&&(this.rf(),this.rf=null);{const i=this.Ef.bind(this),s=this.$f.bind(this);this.rf=()=>{n.removeEventListener("touchmove",i),n.removeEventListener("touchend",s)},n.addEventListener("touchmove",i,{passive:!1}),n.addEventListener("touchend",s,{passive:!1}),this.Of(),this.Yd=setTimeout(this.Zf.bind(this,t),240)}const s=this.wf(t,i);this.xf(s,this.yf.Gf),this.Ud||(this.$d=0,this.Ud=setTimeout(this.kf.bind(this),500),this.qd=ws(i))}Jf(t){if(0!==t.button)return;const i=this.Rf.ownerDocument.documentElement;rs()&&i.addEventListener("mouseleave",this.vf),this.Jd=!1,this.Kd=ws(t),this.ef&&(this.ef(),this.ef=null);{const t=this.jf.bind(this),n=this.pf.bind(this);this.ef=()=>{i.removeEventListener("mousemove",t),i.removeEventListener("mouseup",n)},i.addEventListener("mousemove",t),i.addEventListener("mouseup",n)}if(this.uf=!0,this.bf(t))return;const n=this.wf(t);this.Cf(n,this.yf.Qf),this.jd||(this.Wd=0,this.jd=setTimeout(this.Pf.bind(this),500),this.Hd=ws(t))}Df(){this.Rf.addEventListener("mouseenter",this.Af.bind(this)),this.Rf.addEventListener("touchcancel",this.Of.bind(this));{const t=this.Rf.ownerDocument,i=t=>{this.yf.tv&&(t.composed&&this.Rf.contains(t.composedPath()[0])||t.target&&this.Rf.contains(t.target)||this.yf.tv())};this.if=()=>{t.removeEventListener("touchstart",i)},this.tf=()=>{t.removeEventListener("mousedown",i)},t.addEventListener("mousedown",i),t.addEventListener("touchstart",i,{passive:!0})}hs()&&(this.nf=()=>{this.Rf.removeEventListener("dblclick",this.mf)},this.Rf.addEventListener("dblclick",this.mf)),this.Rf.addEventListener("mouseleave",this.iv.bind(this)),this.Rf.addEventListener("touchstart",this.Kf.bind(this),{passive:!0}),vs(this.Rf),this.Rf.addEventListener("mousedown",this.Jf.bind(this)),this.nv(),this.Rf.addEventListener("touchmove",(()=>{}),{passive:!1})}nv(){void 0===this.yf.sv&&void 0===this.yf.ev&&void 0===this.yf.rv||(this.Rf.addEventListener("touchstart",(t=>this.hv(t.touches)),{passive:!0}),this.Rf.addEventListener("touchmove",(t=>{if(2===t.touches.length&&null!==this.hf&&void 0!==this.yf.ev){const i=ms(t.touches[0],t.touches[1])/this.lf;this.yf.ev(this.hf,i),bs(t)}}),{passive:!1}),this.Rf.addEventListener("touchend",(t=>{this.hv(t.touches)})))}hv(t){1===t.length&&(this.af=!1),2!==t.length||this.af||this.Xd?this.lv():this.av(t)}av(t){const i=this.Rf.getBoundingClientRect()||{left:0,top:0};this.hf={et:(t[0].clientX-i.left+(t[1].clientX-i.left))/2,rt:(t[0].clientY-i.top+(t[1].clientY-i.top))/2},this.lf=ms(t[0],t[1]),void 0!==this.yf.sv&&this.yf.sv(),this.Of()}lv(){null!==this.hf&&(this.hf=null,void 0!==this.yf.rv&&this.yf.rv())}iv(t){if(this.sf&&this.sf(),this.bf(t))return;if(!this.ff)return;const i=this.wf(t);this.Cf(i,this.yf.ov),this.ff=!hs()}Zf(t){const i=Ms(t.touches,f(this.df));if(null===i)return;const n=this.wf(t,i);this.xf(n,this.yf._v),this.Qd=!0,this.Xd=!0}bf(t){return t.sourceCapabilities&&void 0!==t.sourceCapabilities.firesTouchEvents?t.sourceCapabilities.firesTouchEvents:gs(t){"touchstart"!==t.type&&bs(t)}}}}function ms(t,i){const n=t.clientX-i.clientX,s=t.clientY-i.clientY;return Math.sqrt(n*n+s*s)}function bs(t){t.cancelable&&t.preventDefault()}function ws(t){return{et:t.pageX,rt:t.pageY}}function gs(t){return t.timeStamp||performance.now()}function Ms(t,i){for(let n=0;n{var s,e,r,h;return(null!==(e=null===(s=n.At())||void 0===s?void 0:s.xa())&&void 0!==e?e:"")!==i?[]:null!==(h=null===(r=n.la)||void 0===r?void 0:r.call(n,t))&&void 0!==h?h:[]}}class ks{constructor(t,i,n,s){this.Li=null,this.wv=null,this.gv=!1,this.Mv=new Qt(200),this.Gr=null,this.xv=0,this.Sv=!1,this.yv=()=>{this.Sv||this.nn.kv().qt().Fh()},this.Cv=()=>{this.Sv||this.nn.kv().qt().Fh()},this.nn=t,this.cn=i,this.mo=i.layout,this.yc=n,this.Tv="left"===s,this.Pv=ys("normal",s),this.Rv=ys("top",s),this.Dv=ys("bottom",s),this.Ov=document.createElement("div"),this.Ov.style.height="100%",this.Ov.style.overflow="hidden",this.Ov.style.width="25px",this.Ov.style.left="0",this.Ov.style.position="relative",this.Av=us(this.Ov,Gn({width:16,height:16})),this.Av.subscribeSuggestedBitmapSizeChanged(this.yv);const e=this.Av.canvasElement;e.style.position="absolute",e.style.zIndex="1",e.style.left="0",e.style.top="0",this.Bv=us(this.Ov,Gn({width:16,height:16})),this.Bv.subscribeSuggestedBitmapSizeChanged(this.Cv);const r=this.Bv.canvasElement;r.style.position="absolute",r.style.zIndex="2",r.style.left="0",r.style.top="0";const h={Qf:this.Vv.bind(this),Gf:this.Vv.bind(this),Hf:this.zv.bind(this),Wf:this.zv.bind(this),tv:this.Ev.bind(this),Yf:this.Iv.bind(this),Uf:this.Iv.bind(this),Tf:this.Lv.bind(this),Sf:this.Lv.bind(this),Vf:this.Nv.bind(this),ov:this.Fv.bind(this)};this.Wv=new ps(this.Bv.canvasElement,h,{Nf:()=>!this.cn.handleScroll.vertTouchDrag,Ff:()=>!0})}S(){this.Wv.S(),this.Bv.unsubscribeSuggestedBitmapSizeChanged(this.Cv),this.Bv.dispose(),this.Av.unsubscribeSuggestedBitmapSizeChanged(this.yv),this.Av.dispose(),null!==this.Li&&this.Li.$o().p(this),this.Li=null}jv(){return this.Ov}P(){return this.mo.fontSize}Hv(){const t=this.yc.W();return this.Gr!==t.R&&(this.Mv.ir(),this.Gr=t.R),t}$v(){if(null===this.Li)return 0;let t=0;const i=this.Hv(),n=f(this.Av.canvasElement.getContext("2d"));n.save();const s=this.Li.Ia();n.font=this.Uv(),s.length>0&&(t=Math.max(this.Mv.Si(n,s[0].Za),this.Mv.Si(n,s[s.length-1].Za)));const e=this.qv();for(let i=e.length;i--;){const s=this.Mv.Si(n,e[i].Jt());s>t&&(t=s)}const r=this.Li.Pt();if(null!==r&&null!==this.wv){const i=this.Li.pn(1,r),s=this.Li.pn(this.wv.height-2,r);t=Math.max(t,this.Mv.Si(n,this.Li.Wi(Math.floor(Math.min(i,s))+.11111111111111,r)),this.Mv.Si(n,this.Li.Wi(Math.ceil(Math.max(i,s))-.11111111111111,r)))}n.restore();const h=t||34;return ls(Math.ceil(i.C+i.T+i.V+i.I+5+h))}Yv(t){null!==this.wv&&Jn(this.wv,t)||(this.wv=t,this.Sv=!0,this.Av.resizeCanvasElement(t),this.Bv.resizeCanvasElement(t),this.Sv=!1,this.Ov.style.width=`${t.width}px`,this.Ov.style.height=`${t.height}px`)}Xv(){return f(this.wv).width}Ji(t){this.Li!==t&&(null!==this.Li&&this.Li.$o().p(this),this.Li=t,t.$o().l(this.ao.bind(this),this))}At(){return this.Li}ir(){const t=this.nn.Kv();this.nn.kv().qt().A_(t,f(this.At()))}Zv(t){if(null===this.wv)return;if(1!==t){this.Gv(),this.Av.applySuggestedBitmapSize();const t=ss(this.Av);null!==t&&(t.useBitmapCoordinateSpace((t=>{this.Jv(t),this.Ve(t)})),this.nn.Qv(t,this.Dv),this.tp(t),this.nn.Qv(t,this.Pv),this.ip(t))}this.Bv.applySuggestedBitmapSize();const i=ss(this.Bv);null!==i&&(i.useBitmapCoordinateSpace((({context:t,bitmapSize:i})=>{t.clearRect(0,0,i.width,i.height)})),this.np(i),this.nn.Qv(i,this.Rv))}sp(){return this.Av.bitmapSize}ep(t,i,n){const s=this.sp();s.width>0&&s.height>0&&t.drawImage(this.Av.canvasElement,i,n)}gt(){var t;null===(t=this.Li)||void 0===t||t.Ia()}Vv(t){if(null===this.Li||this.Li.Fi()||!this.cn.handleScale.axisPressedMouseMove.price)return;const i=this.nn.kv().qt(),n=this.nn.Kv();this.gv=!0,i.k_(n,this.Li,t.localY)}zv(t){if(null===this.Li||!this.cn.handleScale.axisPressedMouseMove.price)return;const i=this.nn.kv().qt(),n=this.nn.Kv(),s=this.Li;i.C_(n,s,t.localY)}Ev(){if(null===this.Li||!this.cn.handleScale.axisPressedMouseMove.price)return;const t=this.nn.kv().qt(),i=this.nn.Kv(),n=this.Li;this.gv&&(this.gv=!1,t.T_(i,n))}Iv(t){if(null===this.Li||!this.cn.handleScale.axisPressedMouseMove.price)return;const i=this.nn.kv().qt(),n=this.nn.Kv();this.gv=!1,i.T_(n,this.Li)}Lv(t){this.cn.handleScale.axisDoubleClickReset.price&&this.ir()}Nv(t){if(null===this.Li)return;!this.nn.kv().qt().W().handleScale.axisPressedMouseMove.price||this.Li.ph()||this.Li.Co()||this.rp(1)}Fv(t){this.rp(0)}qv(){const t=[],i=null===this.Li?void 0:this.Li;return(n=>{for(let s=0;s{t.fillStyle=n.borderColor;const l=Math.max(1,Math.floor(h)),a=Math.floor(.5*h),o=Math.round(s.T*r);t.beginPath();for(const n of i)t.rect(Math.floor(e*r),Math.round(n.Aa*h)-a,o,l);t.fill()})),t.useMediaCoordinateSpace((({context:t})=>{var r;t.font=this.Uv(),t.fillStyle=null!==(r=n.textColor)&&void 0!==r?r:this.mo.textColor,t.textAlign=this.Tv?"right":"left",t.textBaseline="middle";const h=this.Tv?Math.round(e-s.V):Math.round(e+s.T+s.V),l=i.map((i=>this.Mv.xi(t,i.Za)));for(let n=i.length;n--;){const s=i[n];t.fillText(s.Za,h,s.Aa+l[n])}}))}Gv(){if(null===this.wv||null===this.Li)return;let t=this.wv.height/2;const i=[],n=this.Li.No().slice(),s=this.nn.Kv(),e=this.Hv();this.Li===s.vr()&&this.nn.Kv().No().forEach((t=>{s.dr(t)&&n.push(t)}));const r=this.Li.Ta()[0],h=this.Li;n.forEach((n=>{const e=n.Rn(s,h);e.forEach((t=>{t.Bi(null),t.Vi()&&i.push(t)})),r===n&&e.length>0&&(t=e[0].ki())})),i.forEach((t=>t.Bi(t.ki())));this.Li.W().alignLabels&&this.hp(i,e,t)}hp(t,i,n){if(null===this.wv)return;const s=t.filter((t=>t.ki()<=n)),e=t.filter((t=>t.ki()>n));s.sort(((t,i)=>i.ki()-t.ki())),s.length&&e.length&&e.push(s[0]),e.sort(((t,i)=>t.ki()-i.ki()));for(const n of t){const t=Math.floor(n.Et(i)/2),s=n.ki();s>-t&&sthis.wv.height-t&&sl-r&&n.Bi(l-r)}for(let t=1;t{if(i.zi()){i.xt(f(this.Li)).K(t,n,this.Mv,s)}}))}np(t){if(null===this.wv||null===this.Li)return;const i=this.nn.kv().qt(),n=[],s=this.nn.Kv(),e=i.Fc().Rn(s,this.Li);e.length&&n.push(e);const r=this.Hv(),h=this.Tv?"right":"left";n.forEach((i=>{i.forEach((i=>{i.xt(f(this.Li)).K(t,r,this.Mv,h)}))}))}rp(t){this.Ov.style.cursor=1===t?"ns-resize":"default"}ao(){const t=this.$v();this.xv{this.Sv||null===this.wp||this.Ui().Fh()},this.Cv=()=>{this.Sv||null===this.wp||this.Ui().Fh()},this.gp=t,this.wp=i,this.wp.z_().l(this.Mp.bind(this),this,!0),this.xp=document.createElement("td"),this.xp.style.padding="0",this.xp.style.position="relative";const n=document.createElement("div");n.style.width="100%",n.style.height="100%",n.style.position="relative",n.style.overflow="hidden",this.Sp=document.createElement("td"),this.Sp.style.padding="0",this.yp=document.createElement("td"),this.yp.style.padding="0",this.xp.appendChild(n),this.Av=us(n,Gn({width:16,height:16})),this.Av.subscribeSuggestedBitmapSizeChanged(this.yv);const s=this.Av.canvasElement;s.style.position="absolute",s.style.zIndex="1",s.style.left="0",s.style.top="0",this.Bv=us(n,Gn({width:16,height:16})),this.Bv.subscribeSuggestedBitmapSizeChanged(this.Cv);const e=this.Bv.canvasElement;e.style.position="absolute",e.style.zIndex="2",e.style.left="0",e.style.top="0",this.kp=document.createElement("tr"),this.kp.appendChild(this.Sp),this.kp.appendChild(this.xp),this.kp.appendChild(this.yp),this.Cp(),this.Wv=new ps(this.Bv.canvasElement,this,{Nf:()=>null===this.vp&&!this.gp.W().handleScroll.vertTouchDrag,Ff:()=>null===this.vp&&!this.gp.W().handleScroll.horzTouchDrag})}S(){null!==this.lp&&this.lp.S(),null!==this.ap&&this.ap.S(),this.Bv.unsubscribeSuggestedBitmapSizeChanged(this.Cv),this.Bv.dispose(),this.Av.unsubscribeSuggestedBitmapSizeChanged(this.yv),this.Av.dispose(),null!==this.wp&&this.wp.z_().p(this),this.Wv.S()}Kv(){return f(this.wp)}Tp(t){null!==this.wp&&this.wp.z_().p(this),this.wp=t,null!==this.wp&&this.wp.z_().l(Ds.prototype.Mp.bind(this),this,!0),this.Cp()}kv(){return this.gp}jv(){return this.kp}Cp(){if(null!==this.wp&&(this.Pp(),0!==this.Ui().Mt().length)){if(null!==this.lp){const t=this.wp.S_();this.lp.Ji(f(t))}if(null!==this.ap){const t=this.wp.y_();this.ap.Ji(f(t))}}}Rp(){null!==this.lp&&this.lp.gt(),null!==this.ap&&this.ap.gt()}v_(){return null!==this.wp?this.wp.v_():0}p_(t){this.wp&&this.wp.p_(t)}Vf(t){if(!this.wp)return;this.Dp();const i=t.localX,n=t.localY;this.Op(i,n,t)}Qf(t){this.Dp(),this.Ap(),this.Op(t.localX,t.localY,t)}zf(t){var i;if(!this.wp)return;this.Dp();const n=t.localX,s=t.localY;this.Op(n,s,t);const e=this.br(n,s);this.gp.Bp(null!==(i=null==e?void 0:e.bv)&&void 0!==i?i:null),this.Ui().Vc(e&&{zc:e.zc,pv:e.pv})}Xf(t){null!==this.wp&&(this.Dp(),this.Vp(t))}Tf(t){null!==this.wp&&this.zp(this.cp,t)}Sf(t){this.Tf(t)}Hf(t){this.Dp(),this.Ep(t),this.Op(t.localX,t.localY,t)}Yf(t){null!==this.wp&&(this.Dp(),this.fp=!1,this.Ip(t))}qf(t){null!==this.wp&&this.Vp(t)}_v(t){if(this.fp=!0,null===this.vp){const i={x:t.localX,y:t.localY};this.Lp(i,i,t)}}ov(t){null!==this.wp&&(this.Dp(),this.wp.qt().Vc(null),this.Np())}Fp(){return this.up}Wp(){return this.cp}sv(){this.dp=1,this.Ui().Un()}ev(t,i){if(!this.gp.W().handleScale.pinch)return;const n=5*(i-this.dp);this.dp=i,this.Ui().Uc(t.et,n)}Gf(t){this.fp=!1,this.pp=null!==this.vp,this.Ap();const i=this.Ui().Fc();null!==this.vp&&i.Tt()&&(this.mp={x:i.Kt(),y:i.Zt()},this.vp={x:t.localX,y:t.localY})}Wf(t){if(null===this.wp)return;const i=t.localX,n=t.localY;if(null===this.vp)this.Ep(t);else{this.pp=!1;const s=f(this.mp),e=s.x+(i-this.vp.x),r=s.y+(n-this.vp.y);this.Op(e,r,t)}}Uf(t){0===this.kv().W().trackingMode.exitMode&&(this.pp=!0),this.jp(),this.Ip(t)}br(t,i){const n=this.wp;return null===n?null:function(t,i,n){const s=t.No(),e=function(t,i,n){var s,e;let r,h;for(const o of t){const t=null!==(e=null===(s=o.oa)||void 0===s?void 0:s.call(o,i,n))&&void 0!==e?e:[];for(const i of t)l=i.zOrder,(!(a=null==r?void 0:r.zOrder)||"top"===l&&"top"!==a||"normal"===l&&"bottom"===a)&&(r=i,h=o)}var l,a;return r&&h?{mv:r,zc:h}:null}(s,i,n);if("top"===(null==e?void 0:e.mv.zOrder))return xs(e);for(const r of s){if(e&&e.zc===r&&"bottom"!==e.mv.zOrder&&!e.mv.isBackground)return xs(e);const s=Ss(r.Pn(t),i,n);if(null!==s)return{zc:r,fv:s.fv,pv:s.pv};if(e&&e.zc===r&&"bottom"!==e.mv.zOrder&&e.mv.isBackground)return xs(e)}return(null==e?void 0:e.mv)?xs(e):null}(n,t,i)}Hp(t,i){f("left"===i?this.lp:this.ap).Yv(Gn({width:t,height:this.wv.height}))}$p(){return this.wv}Yv(t){Jn(this.wv,t)||(this.wv=t,this.Sv=!0,this.Av.resizeCanvasElement(t),this.Bv.resizeCanvasElement(t),this.Sv=!1,this.xp.style.width=t.width+"px",this.xp.style.height=t.height+"px")}Up(){const t=f(this.wp);t.x_(t.S_()),t.x_(t.y_());for(const i of t.Ta())if(t.dr(i)){const n=i.At();null!==n&&t.x_(n),i.On()}}sp(){return this.Av.bitmapSize}ep(t,i,n){const s=this.sp();s.width>0&&s.height>0&&t.drawImage(this.Av.canvasElement,i,n)}Zv(t){if(0===t)return;if(null===this.wp)return;if(t>1&&this.Up(),null!==this.lp&&this.lp.Zv(t),null!==this.ap&&this.ap.Zv(t),1!==t){this.Av.applySuggestedBitmapSize();const t=ss(this.Av);null!==t&&(t.useBitmapCoordinateSpace((t=>{this.Jv(t)})),this.wp&&(this.qp(t,Cs),this.Yp(t),this.Xp(t),this.qp(t,Ts),this.qp(t,Ps)))}this.Bv.applySuggestedBitmapSize();const i=ss(this.Bv);null!==i&&(i.useBitmapCoordinateSpace((({context:t,bitmapSize:i})=>{t.clearRect(0,0,i.width,i.height)})),this.Kp(i),this.qp(i,Rs))}Zp(){return this.lp}Gp(){return this.ap}Qv(t,i){this.qp(t,i)}Mp(){null!==this.wp&&this.wp.z_().p(this),this.wp=null}Vp(t){this.zp(this.up,t)}zp(t,i){const n=i.localX,s=i.localY;t.M()&&t.m(this.Ui().kt().Bu(n),{x:n,y:s},i)}Jv({context:t,bitmapSize:i}){const{width:n,height:s}=i,e=this.Ui(),r=e.q(),h=e.od();r===h?Y(t,0,0,n,s,h):G(t,0,0,n,s,r,h)}Yp(t){const i=f(this.wp).E_().Wh().xt();null!==i&&i.K(t,!1)}Xp(t){const i=this.Ui().Nc();this.Jp(t,Ts,cs,i),this.Jp(t,Ts,ds,i)}Kp(t){this.Jp(t,Ts,ds,this.Ui().Fc())}qp(t,i){const n=f(this.wp).No();for(const s of n)this.Jp(t,i,cs,s);for(const s of n)this.Jp(t,i,ds,s)}Jp(t,i,n,s){const e=f(this.wp),r=e.qt().Bc(),h=null!==r&&r.zc===s,l=null!==r&&h&&void 0!==r.pv?r.pv.gr:void 0;fs(i,(i=>n(i,t,h,l)),s,e)}Pp(){if(null===this.wp)return;const t=this.gp,i=this.wp.S_().W().visible,n=this.wp.y_().W().visible;i||null===this.lp||(this.Sp.removeChild(this.lp.jv()),this.lp.S(),this.lp=null),n||null===this.ap||(this.yp.removeChild(this.ap.jv()),this.ap.S(),this.ap=null);const s=t.qt().sd();i&&null===this.lp&&(this.lp=new ks(this,t.W(),s,"left"),this.Sp.appendChild(this.lp.jv())),n&&null===this.ap&&(this.ap=new ks(this,t.W(),s,"right"),this.yp.appendChild(this.ap.jv()))}Qp(t){return t.uv&&this.fp||null!==this.vp}tm(t){return Math.max(0,Math.min(t,this.wv.width-1))}im(t){return Math.max(0,Math.min(t,this.wv.height-1))}Op(t,i,n){this.Ui().Jc(this.tm(t),this.im(i),n,f(this.wp))}Np(){this.Ui().td()}jp(){this.pp&&(this.vp=null,this.Np())}Lp(t,i,n){this.vp=t,this.pp=!1,this.Op(i.x,i.y,n);const s=this.Ui().Fc();this.mp={x:s.Kt(),y:s.Zt()}}Ui(){return this.gp.qt()}Ip(t){if(!this._p)return;const i=this.Ui(),n=this.Kv();if(i.D_(n,n.vn()),this.op=null,this._p=!1,i.Kc(),null!==this.bp){const t=performance.now(),n=i.kt();this.bp.Dr(n.Iu(),t),this.bp.Yu(t)||i.Xn(this.bp)}}Dp(){this.vp=null}Ap(){if(!this.wp)return;if(this.Ui().Un(),document.activeElement!==document.body&&document.activeElement!==document.documentElement)f(document.activeElement).blur();else{const t=document.getSelection();null!==t&&t.removeAllRanges()}!this.wp.vn().Fi()&&this.Ui().kt().Fi()}Ep(t){if(null===this.wp)return;const i=this.Ui(),n=i.kt();if(n.Fi())return;const s=this.gp.W(),e=s.handleScroll,r=s.kineticScroll;if((!e.pressedMouseMove||t.uv)&&(!e.horzTouchDrag&&!e.vertTouchDrag||!t.uv))return;const h=this.wp.vn(),l=performance.now();if(null!==this.op||this.Qp(t)||(this.op={x:t.clientX,y:t.clientY,yd:l,nm:t.localX,sm:t.localY}),null!==this.op&&!this._p&&(this.op.x!==t.clientX||this.op.y!==t.clientY)){if(t.uv&&r.touch||!t.uv&&r.mouse){const t=n.he();this.bp=new _s(.2/t,7/t,.997,15/t),this.bp.Nd(n.Iu(),this.op.yd)}else this.bp=null;h.Fi()||i.P_(this.wp,h,t.localY),i.Yc(t.localX),this._p=!0}this._p&&(h.Fi()||i.R_(this.wp,h,t.localY),i.Xc(t.localX),null!==this.bp&&this.bp.Nd(n.Iu(),l))}}class Os{constructor(t,i,n,s,e){this.bt=!0,this.wv=Gn({width:0,height:0}),this.yv=()=>this.Zv(3),this.Tv="left"===t,this.yc=n.sd,this.cn=i,this.rm=s,this.hm=e,this.Ov=document.createElement("div"),this.Ov.style.width="25px",this.Ov.style.height="100%",this.Ov.style.overflow="hidden",this.Av=us(this.Ov,Gn({width:16,height:16})),this.Av.subscribeSuggestedBitmapSizeChanged(this.yv)}S(){this.Av.unsubscribeSuggestedBitmapSizeChanged(this.yv),this.Av.dispose()}jv(){return this.Ov}$p(){return this.wv}Yv(t){Jn(this.wv,t)||(this.wv=t,this.Av.resizeCanvasElement(t),this.Ov.style.width=`${t.width}px`,this.Ov.style.height=`${t.height}px`,this.bt=!0)}Zv(t){if(t<3&&!this.bt)return;if(0===this.wv.width||0===this.wv.height)return;this.bt=!1,this.Av.applySuggestedBitmapSize();const i=ss(this.Av);null!==i&&i.useBitmapCoordinateSpace((t=>{this.Jv(t),this.Ve(t)}))}sp(){return this.Av.bitmapSize}ep(t,i,n){const s=this.sp();s.width>0&&s.height>0&&t.drawImage(this.Av.canvasElement,i,n)}Ve({context:t,bitmapSize:i,horizontalPixelRatio:n,verticalPixelRatio:s}){if(!this.rm())return;t.fillStyle=this.cn.timeScale.borderColor;const e=Math.floor(this.yc.W().C*n),r=Math.floor(this.yc.W().C*s),h=this.Tv?i.width-e:0;t.fillRect(h,0,e,r)}Jv({context:t,bitmapSize:i}){Y(t,0,0,i.width,i.height,this.hm())}}function As(t){return i=>{var n,s;return null!==(s=null===(n=i.aa)||void 0===n?void 0:n.call(i,t))&&void 0!==s?s:[]}}const Bs=As("normal"),Vs=As("top"),zs=As("bottom");class Es{constructor(t,i){this.lm=null,this.am=null,this.k=null,this.om=!1,this.wv=Gn({width:0,height:0}),this._m=new k,this.Mv=new Qt(5),this.Sv=!1,this.yv=()=>{this.Sv||this.gp.qt().Fh()},this.Cv=()=>{this.Sv||this.gp.qt().Fh()},this.gp=t,this.N_=i,this.cn=t.W().layout,this.um=document.createElement("tr"),this.dm=document.createElement("td"),this.dm.style.padding="0",this.fm=document.createElement("td"),this.fm.style.padding="0",this.Ov=document.createElement("td"),this.Ov.style.height="25px",this.Ov.style.padding="0",this.vm=document.createElement("div"),this.vm.style.width="100%",this.vm.style.height="100%",this.vm.style.position="relative",this.vm.style.overflow="hidden",this.Ov.appendChild(this.vm),this.Av=us(this.vm,Gn({width:16,height:16})),this.Av.subscribeSuggestedBitmapSizeChanged(this.yv);const n=this.Av.canvasElement;n.style.position="absolute",n.style.zIndex="1",n.style.left="0",n.style.top="0",this.Bv=us(this.vm,Gn({width:16,height:16})),this.Bv.subscribeSuggestedBitmapSizeChanged(this.Cv);const s=this.Bv.canvasElement;s.style.position="absolute",s.style.zIndex="2",s.style.left="0",s.style.top="0",this.um.appendChild(this.dm),this.um.appendChild(this.Ov),this.um.appendChild(this.fm),this.pm(),this.gp.qt().f_().l(this.pm.bind(this),this),this.Wv=new ps(this.Bv.canvasElement,this,{Nf:()=>!0,Ff:()=>!this.gp.W().handleScroll.horzTouchDrag})}S(){this.Wv.S(),null!==this.lm&&this.lm.S(),null!==this.am&&this.am.S(),this.Bv.unsubscribeSuggestedBitmapSizeChanged(this.Cv),this.Bv.dispose(),this.Av.unsubscribeSuggestedBitmapSizeChanged(this.yv),this.Av.dispose()}jv(){return this.um}bm(){return this.lm}wm(){return this.am}Qf(t){if(this.om)return;this.om=!0;const i=this.gp.qt();!i.kt().Fi()&&this.gp.W().handleScale.axisPressedMouseMove.time&&i.$c(t.localX)}Gf(t){this.Qf(t)}tv(){const t=this.gp.qt();!t.kt().Fi()&&this.om&&(this.om=!1,this.gp.W().handleScale.axisPressedMouseMove.time&&t.Gc())}Hf(t){const i=this.gp.qt();!i.kt().Fi()&&this.gp.W().handleScale.axisPressedMouseMove.time&&i.Zc(t.localX)}Wf(t){this.Hf(t)}Yf(){this.om=!1;const t=this.gp.qt();t.kt().Fi()&&!this.gp.W().handleScale.axisPressedMouseMove.time||t.Gc()}Uf(){this.Yf()}Tf(){this.gp.W().handleScale.axisDoubleClickReset.time&&this.gp.qt().Zn()}Sf(){this.Tf()}Vf(){this.gp.qt().W().handleScale.axisPressedMouseMove.time&&this.rp(1)}ov(){this.rp(0)}$p(){return this.wv}gm(){return this._m}Mm(t,i,n){Jn(this.wv,t)||(this.wv=t,this.Sv=!0,this.Av.resizeCanvasElement(t),this.Bv.resizeCanvasElement(t),this.Sv=!1,this.Ov.style.width=`${t.width}px`,this.Ov.style.height=`${t.height}px`,this._m.m(t)),null!==this.lm&&this.lm.Yv(Gn({width:i,height:t.height})),null!==this.am&&this.am.Yv(Gn({width:n,height:t.height}))}xm(){const t=this.Sm();return Math.ceil(t.C+t.T+t.P+t.L+t.B+t.ym)}gt(){this.gp.qt().kt().Ia()}sp(){return this.Av.bitmapSize}ep(t,i,n){const s=this.sp();s.width>0&&s.height>0&&t.drawImage(this.Av.canvasElement,i,n)}Zv(t){if(0===t)return;if(1!==t){this.Av.applySuggestedBitmapSize();const i=ss(this.Av);null!==i&&(i.useBitmapCoordinateSpace((t=>{this.Jv(t),this.Ve(t),this.km(i,zs)})),this.tp(i),this.km(i,Bs)),null!==this.lm&&this.lm.Zv(t),null!==this.am&&this.am.Zv(t)}this.Bv.applySuggestedBitmapSize();const i=ss(this.Bv);null!==i&&(i.useBitmapCoordinateSpace((({context:t,bitmapSize:i})=>{t.clearRect(0,0,i.width,i.height)})),this.Cm([...this.gp.qt().Mt(),this.gp.qt().Fc()],i),this.km(i,Vs))}km(t,i){const n=this.gp.qt().Mt();for(const s of n)fs(i,(i=>cs(i,t,!1,void 0)),s,void 0);for(const s of n)fs(i,(i=>ds(i,t,!1,void 0)),s,void 0)}Jv({context:t,bitmapSize:i}){Y(t,0,0,i.width,i.height,this.gp.qt().od())}Ve({context:t,bitmapSize:i,verticalPixelRatio:n}){if(this.gp.W().timeScale.borderVisible){t.fillStyle=this.Tm();const s=Math.max(1,Math.floor(this.Sm().C*n));t.fillRect(0,0,i.width,s)}}tp(t){const i=this.gp.qt().kt(),n=i.Ia();if(!n||0===n.length)return;const s=this.N_.maxTickMarkWeight(n),e=this.Sm(),r=i.W();r.borderVisible&&r.ticksVisible&&t.useBitmapCoordinateSpace((({context:t,horizontalPixelRatio:i,verticalPixelRatio:s})=>{t.strokeStyle=this.Tm(),t.fillStyle=this.Tm();const r=Math.max(1,Math.floor(i)),h=Math.floor(.5*i);t.beginPath();const l=Math.round(e.T*s);for(let s=n.length;s--;){const e=Math.round(n[s].coord*i);t.rect(e-h,0,r,l)}t.fill()})),t.useMediaCoordinateSpace((({context:t})=>{const i=e.C+e.T+e.L+e.P/2;t.textAlign="center",t.textBaseline="middle",t.fillStyle=this.$(),t.font=this.Uv();for(const e of n)if(e.weight=s){const n=e.needAlignCoordinate?this.Pm(t,e.coord,e.label):e.coord;t.fillText(e.label,n,i)}}))}Pm(t,i,n){const s=this.Mv.Si(t,n),e=s/2,r=Math.floor(i-e)+.5;return r<0?i+=Math.abs(0-r):r+s>this.wv.width&&(i-=Math.abs(this.wv.width-(r+s))),i}Cm(t,i){const n=this.Sm();for(const s of t)for(const t of s.tn())t.xt().K(i,n)}Tm(){return this.gp.W().timeScale.borderColor}$(){return this.cn.textColor}j(){return this.cn.fontSize}Uv(){return z(this.j(),this.cn.fontFamily)}Rm(){return z(this.j(),this.cn.fontFamily,"bold")}Sm(){null===this.k&&(this.k={C:1,N:NaN,L:NaN,B:NaN,Hi:NaN,T:5,P:NaN,R:"",ji:new Qt,ym:0});const t=this.k,i=this.Uv();if(t.R!==i){const n=this.j();t.P=n,t.R=i,t.L=3*n/12,t.B=3*n/12,t.Hi=9*n/12,t.N=0,t.ym=4*n/12,t.ji.ir()}return this.k}rp(t){this.Ov.style.cursor=1===t?"ew-resize":"default"}pm(){const t=this.gp.qt(),i=t.W();i.leftPriceScale.visible||null===this.lm||(this.dm.removeChild(this.lm.jv()),this.lm.S(),this.lm=null),i.rightPriceScale.visible||null===this.am||(this.fm.removeChild(this.am.jv()),this.am.S(),this.am=null);const n={sd:this.gp.qt().sd()},s=()=>i.leftPriceScale.borderVisible&&t.kt().W().borderVisible,e=()=>t.od();i.leftPriceScale.visible&&null===this.lm&&(this.lm=new Os("left",i,n,s,e),this.dm.appendChild(this.lm.jv())),i.rightPriceScale.visible&&null===this.am&&(this.am=new Os("right",i,n,s,e),this.fm.appendChild(this.am.jv()))}}const Is=!!es&&!!navigator.userAgentData&&navigator.userAgentData.brands.some((t=>t.brand.includes("Chromium")))&&!!es&&((null===(Ls=null===navigator||void 0===navigator?void 0:navigator.userAgentData)||void 0===Ls?void 0:Ls.platform)?"Windows"===navigator.userAgentData.platform:navigator.userAgent.toLowerCase().indexOf("win")>=0);var Ls;class Ns{constructor(t,i,n){var s;this.Dm=[],this.Om=0,this.Qa=0,this.e_=0,this.Am=0,this.Bm=0,this.Vm=null,this.zm=!1,this.up=new k,this.cp=new k,this.Mc=new k,this.Em=null,this.Im=null,this.Lm=t,this.cn=i,this.N_=n,this.um=document.createElement("div"),this.um.classList.add("tv-lightweight-charts"),this.um.style.overflow="hidden",this.um.style.direction="ltr",this.um.style.width="100%",this.um.style.height="100%",(s=this.um).style.userSelect="none",s.style.webkitUserSelect="none",s.style.msUserSelect="none",s.style.MozUserSelect="none",s.style.webkitTapHighlightColor="transparent",this.Nm=document.createElement("table"),this.Nm.setAttribute("cellspacing","0"),this.um.appendChild(this.Nm),this.Fm=this.Wm.bind(this),Fs(this.cn)&&this.jm(!0),this.Ui=new An(this.Sc.bind(this),this.cn,n),this.qt().Wc().l(this.Hm.bind(this),this),this.$m=new Es(this,this.N_),this.Nm.appendChild(this.$m.jv());const e=i.autoSize&&this.Um();let r=this.cn.width,h=this.cn.height;if(e||0===r||0===h){const i=t.getBoundingClientRect();r=r||i.width,h=h||i.height}this.qm(r,h),this.Ym(),t.appendChild(this.um),this.Xm(),this.Ui.kt().Gu().l(this.Ui.$l.bind(this.Ui),this),this.Ui.f_().l(this.Ui.$l.bind(this.Ui),this)}qt(){return this.Ui}W(){return this.cn}Km(){return this.Dm}Zm(){return this.$m}S(){this.jm(!1),0!==this.Om&&window.cancelAnimationFrame(this.Om),this.Ui.Wc().p(this),this.Ui.kt().Gu().p(this),this.Ui.f_().p(this),this.Ui.S();for(const t of this.Dm)this.Nm.removeChild(t.jv()),t.Fp().p(this),t.Wp().p(this),t.S();this.Dm=[],f(this.$m).S(),null!==this.um.parentElement&&this.um.parentElement.removeChild(this.um),this.Mc.S(),this.up.S(),this.cp.S(),this.Gm()}qm(t,i,n=!1){if(this.Qa===i&&this.e_===t)return;const s=function(t){const i=Math.floor(t.width),n=Math.floor(t.height);return Gn({width:i-i%2,height:n-n%2})}(Gn({width:t,height:i}));this.Qa=s.height,this.e_=s.width;const e=this.Qa+"px",r=this.e_+"px";f(this.um).style.height=e,f(this.um).style.width=r,this.Nm.style.height=e,this.Nm.style.width=r,n?this.Jm(at.es(),performance.now()):this.Ui.$l()}Zv(t){void 0===t&&(t=at.es());for(let i=0;i{let s=0;for(let e=0;e{f("left"===i?this.$m.bm():this.$m.wm()).ep(f(t),n,s)};if(this.cn.timeScale.visible){const i=this.$m.sp();if(null!==t){let e=0;this.sb()&&(r("left",e,n),e=f(s.Zp()).sp().width),this.$m.ep(t,e,n),e+=i.width,this.eb()&&r("right",e,n)}n+=i.height}return Gn({width:i,height:n})}ob(){let t=0,i=0,n=0;for(const s of this.Dm)this.sb()&&(i=Math.max(i,f(s.Zp()).$v(),this.cn.leftPriceScale.minimumWidth)),this.eb()&&(n=Math.max(n,f(s.Gp()).$v(),this.cn.rightPriceScale.minimumWidth)),t+=s.v_();i=ls(i),n=ls(n);const s=this.e_,e=this.Qa,r=Math.max(s-i-n,0),h=this.cn.timeScale.visible;let l=h?Math.max(this.$m.xm(),this.cn.timeScale.minimumHeight):0;var a;l=(a=l)+a%2;const o=0+l,_=e{t.Rp()})),3===(null===(n=this.Vm)||void 0===n?void 0:n.jn())&&(this.Vm.ts(t),this.ub(),this.cb(this.Vm),this.fb(this.Vm,i),t=this.Vm,this.Vm=null)),this.Zv(t)}fb(t,i){for(const n of t.Qn())this.ns(n,i)}cb(t){const i=this.Ui.Lc();for(let n=0;n{if(this.zm=!1,this.Om=0,null!==this.Vm){const i=this.Vm;this.Vm=null,this.Jm(i,t);for(const n of i.Qn())if(5===n.qn&&!n.Bt.Yu(t)){this.qt().Xn(n.Bt);break}}})))}ub(){this.Ym()}Ym(){const t=this.Ui.Lc(),i=t.length,n=this.Dm.length;for(let t=i;t{const n=i.zn().nl(t);null!==n&&e.set(i,n)}))}let r;if(null!==t){const i=null===(s=this.Ui.kt().qi(t))||void 0===s?void 0:s.originalTime;void 0!==i&&(r=i)}const h=this.qt().Bc(),l=null!==h&&h.zc instanceof Yi?h.zc:void 0,a=null!==h&&void 0!==h.pv?h.pv.wr:void 0;return{bb:r,se:null!=t?t:void 0,wb:null!=i?i:void 0,gb:l,Mb:e,xb:a,Sb:null!=n?n:void 0}}vb(t,i,n){this.up.m((()=>this.mb(t,i,n)))}pb(t,i,n){this.cp.m((()=>this.mb(t,i,n)))}Hm(t,i,n){this.Mc.m((()=>this.mb(t,i,n)))}Xm(){const t=this.cn.timeScale.visible?"":"none";this.$m.jv().style.display=t}sb(){return this.Dm[0].Kv().S_().W().visible}eb(){return this.Dm[0].Kv().y_().W().visible}Um(){return"ResizeObserver"in window&&(this.Em=new ResizeObserver((t=>{const i=t.find((t=>t.target===this.Lm));i&&this.qm(i.contentRect.width,i.contentRect.height)})),this.Em.observe(this.Lm,{box:"border-box"}),!0)}Gm(){null!==this.Em&&this.Em.disconnect(),this.Em=null}}function Fs(t){return Boolean(t.handleScroll.mouseWheel||t.handleScale.mouseWheel)}function Ws(t,i){var n={};for(var s in t)Object.prototype.hasOwnProperty.call(t,s)&&i.indexOf(s)<0&&(n[s]=t[s]);if(null!=t&&"function"==typeof Object.getOwnPropertySymbols){var e=0;for(s=Object.getOwnPropertySymbols(t);efunction(t,i){return i?i(t):void 0===(n=t).open&&void 0===n.value;var n}(s,h)?Ks({ut:i,se:n,bb:e},s):Ks(t(i,n,s,e,r),s)}function Gs(t){return{Candlestick:Zs(qs),Bar:Zs(Us),Area:Zs(Hs),Baseline:Zs($s),Histogram:Zs(js),Line:Zs(js),Custom:Zs(Ys)}[t]}function Js(t){return{se:0,kb:new Map,ia:t}}function Qs(t,i){if(void 0!==t&&0!==t.length)return{Cb:i.key(t[0].ut),Tb:i.key(t[t.length-1].ut)}}function te(t){let i;return t.forEach((t=>{void 0===i&&(i=t.bb)})),d(i)}class ie{constructor(t){this.Pb=new Map,this.Rb=new Map,this.Db=new Map,this.Ob=[],this.N_=t}S(){this.Pb.clear(),this.Rb.clear(),this.Db.clear(),this.Ob=[]}Ab(t,i){let n=0!==this.Pb.size,s=!1;const e=this.Rb.get(t);if(void 0!==e)if(1===this.Rb.size)n=!1,s=!0,this.Pb.clear();else for(const i of this.Ob)i.pointData.kb.delete(t)&&(s=!0);let r=[];if(0!==i.length){const n=i.map((t=>t.time)),e=this.N_.createConverterToInternalObj(i),h=Gs(t.Xh()),l=t.ga(),a=t.Ma();r=i.map(((i,r)=>{const o=e(i.time),_=this.N_.key(o);let u=this.Pb.get(_);void 0===u&&(u=Js(o),this.Pb.set(_,u),s=!0);const c=h(o,u.se,i,n[r],l,a);return u.kb.set(t,c),c}))}n&&this.Bb(),this.Vb(t,r);let h=-1;if(s){const t=[];this.Pb.forEach((i=>{t.push({timeWeight:0,time:i.ia,pointData:i,originalTime:te(i.kb)})})),t.sort(((t,i)=>this.N_.key(t.time)-this.N_.key(i.time))),h=this.zb(t)}return this.Eb(t,h,function(t,i,n){const s=Qs(t,n),e=Qs(i,n);if(void 0!==s&&void 0!==e)return{Xl:s.Tb>=e.Tb&&s.Cb>=e.Cb}}(this.Rb.get(t),e,this.N_))}hd(t){return this.Ab(t,[])}Ib(t,i){const n=i;!function(t){void 0===t.bb&&(t.bb=t.time)}(n),this.N_.preprocessData(i);const s=this.N_.createConverterToInternalObj([i])(i.time),e=this.Db.get(t);if(void 0!==e&&this.N_.key(s)this.N_.key(t.time)this.N_.key(s.ut)?Xs(i)&&n.push(i):Xs(i)?n[n.length-1]=i:n.splice(-1,1),this.Db.set(t,i.ut)}Vb(t,i){0!==i.length?(this.Rb.set(t,i.filter(Xs)),this.Db.set(t,i[i.length-1].ut)):(this.Rb.delete(t),this.Db.delete(t))}Bb(){for(const t of this.Ob)0===t.pointData.kb.size&&this.Pb.delete(this.N_.key(t.time))}zb(t){let i=-1;for(let n=0;n{0!==i.length&&(t=Math.max(t,i[i.length-1].se))})),t}Eb(t,i,n){const s={Fb:new Map,kt:{Au:this.Nb()}};if(-1!==i)this.Rb.forEach(((i,e)=>{s.Fb.set(e,{He:i,Wb:e===t?n:void 0})})),this.Rb.has(t)||s.Fb.set(t,{He:[],Wb:n}),s.kt.jb=this.Ob,s.kt.Hb=i;else{const i=this.Rb.get(t);s.Fb.set(t,{He:i||[],Wb:n})}return s}}function ne(t,i){t.se=i,t.kb.forEach((t=>{t.se=i}))}function se(t){const i={value:t.Bt[3],time:t.bb};return void 0!==t.yb&&(i.customValues=t.yb),i}function ee(t){const i=se(t);return void 0!==t.O&&(i.color=t.O),i}function re(t){const i=se(t);return void 0!==t._t&&(i.lineColor=t._t),void 0!==t.Ts&&(i.topColor=t.Ts),void 0!==t.Ps&&(i.bottomColor=t.Ps),i}function he(t){const i=se(t);return void 0!==t.Pe&&(i.topLineColor=t.Pe),void 0!==t.Re&&(i.bottomLineColor=t.Re),void 0!==t.Se&&(i.topFillColor1=t.Se),void 0!==t.ye&&(i.topFillColor2=t.ye),void 0!==t.ke&&(i.bottomFillColor1=t.ke),void 0!==t.Ce&&(i.bottomFillColor2=t.Ce),i}function le(t){const i={open:t.Bt[0],high:t.Bt[1],low:t.Bt[2],close:t.Bt[3],time:t.bb};return void 0!==t.yb&&(i.customValues=t.yb),i}function ae(t){const i=le(t);return void 0!==t.O&&(i.color=t.O),i}function oe(t){const i=le(t),{O:n,Vt:s,$h:e}=t;return void 0!==n&&(i.color=n),void 0!==s&&(i.borderColor=s),void 0!==e&&(i.wickColor=e),i}function _e(t){return{Area:re,Line:ee,Baseline:he,Histogram:ee,Bar:ae,Candlestick:oe,Custom:ue}[t]}function ue(t){const i=t.bb;return Object.assign(Object.assign({},t.He),{time:i})}const ce={vertLine:{color:"#9598A1",width:1,style:3,visible:!0,labelVisible:!0,labelBackgroundColor:"#131722"},horzLine:{color:"#9598A1",width:1,style:3,visible:!0,labelVisible:!0,labelBackgroundColor:"#131722"},mode:1},de={vertLines:{color:"#D6DCDE",style:0,visible:!0},horzLines:{color:"#D6DCDE",style:0,visible:!0}},fe={background:{type:"solid",color:"#FFFFFF"},textColor:"#191919",fontSize:12,fontFamily:V},ve={autoScale:!0,mode:0,invertScale:!1,alignLabels:!0,borderVisible:!0,borderColor:"#2B2B43",entireTextOnly:!1,visible:!1,ticksVisible:!1,scaleMargins:{bottom:.1,top:.2},minimumWidth:0},pe={rightOffset:0,barSpacing:6,minBarSpacing:.5,fixLeftEdge:!1,fixRightEdge:!1,lockVisibleTimeRangeOnResize:!1,rightBarStaysOnScroll:!1,borderVisible:!0,borderColor:"#2B2B43",visible:!0,timeVisible:!1,secondsVisible:!0,shiftVisibleRangeOnNewBar:!0,allowShiftVisibleRangeOnWhitespaceReplacement:!1,ticksVisible:!1,uniformDistribution:!1,minimumHeight:0},me={color:"rgba(0, 0, 0, 0)",visible:!1,fontSize:48,fontFamily:V,fontStyle:"",text:"",horzAlign:"center",vertAlign:"center"};function be(){return{width:0,height:0,autoSize:!1,layout:fe,crosshair:ce,grid:de,overlayPriceScales:Object.assign({},ve),leftPriceScale:Object.assign(Object.assign({},ve),{visible:!1}),rightPriceScale:Object.assign(Object.assign({},ve),{visible:!0}),timeScale:pe,watermark:me,localization:{locale:es?navigator.language:"",dateFormat:"dd MMM 'yy"},handleScroll:{mouseWheel:!0,pressedMouseMove:!0,horzTouchDrag:!0,vertTouchDrag:!0},handleScale:{axisPressedMouseMove:{time:!0,price:!0},axisDoubleClickReset:{time:!0,price:!0},mouseWheel:!0,pinch:!0},kineticScroll:{mouse:!1,touch:!0},trackingMode:{exitMode:1}}}class we{constructor(t,i){this.$b=t,this.Ub=i}applyOptions(t){this.$b.qt().Ec(this.Ub,t)}options(){return this.Li().W()}width(){return lt(this.Ub)?this.$b.nb(this.Ub):0}Li(){return f(this.$b.qt().Ic(this.Ub)).At}}function ge(t,i,n){const s=Ws(t,["time","originalTime"]),e=Object.assign({time:i},s);return void 0!==n&&(e.originalTime=n),e}const Me={color:"#FF0000",price:0,lineStyle:2,lineWidth:1,lineVisible:!0,axisLabelVisible:!0,title:"",axisLabelColor:"",axisLabelTextColor:""};class xe{constructor(t){this.Vh=t}applyOptions(t){this.Vh.Nh(t)}options(){return this.Vh.W()}qb(){return this.Vh}}class Se{constructor(t,i,n,s,e){this.Yb=new k,this.Is=t,this.Xb=i,this.Kb=n,this.N_=e,this.Zb=s}S(){this.Yb.S()}priceFormatter(){return this.Is.ca()}priceToCoordinate(t){const i=this.Is.Pt();return null===i?null:this.Is.At().Ot(t,i.Bt)}coordinateToPrice(t){const i=this.Is.Pt();return null===i?null:this.Is.At().pn(t,i.Bt)}barsInLogicalRange(t){if(null===t)return null;const i=new Mn(new bn(t.from,t.to)).iu(),n=this.Is.zn();if(n.Fi())return null;const s=n.nl(i.Os(),1),e=n.nl(i.di(),-1),r=f(n.Qh()),h=f(n.Vn());if(null!==s&&null!==e&&s.se>e.se)return{barsBefore:t.from-r,barsAfter:h-t.to};const l={barsBefore:null===s||s.se===r?t.from-r:s.se-r,barsAfter:null===e||e.se===h?h-t.to:h-e.se};return null!==s&&null!==e&&(l.from=s.bb,l.to=e.bb),l}setData(t){this.N_,this.Is.Xh(),this.Xb.Gb(this.Is,t),this.Jb("full")}update(t){this.Is.Xh(),this.Xb.Qb(this.Is,t),this.Jb("update")}dataByIndex(t,i){const n=this.Is.zn().nl(t,i);if(null===n)return null;return _e(this.seriesType())(n)}data(){const t=_e(this.seriesType());return this.Is.zn().ie().map((i=>t(i)))}subscribeDataChanged(t){this.Yb.l(t)}unsubscribeDataChanged(t){this.Yb.v(t)}setMarkers(t){this.N_;const i=t.map((t=>ge(t,this.N_.convertHorzItemToInternal(t.time),t.time)));this.Is.Zl(i)}markers(){return this.Is.Gl().map((t=>ge(t,t.originalTime,void 0)))}applyOptions(t){this.Is.Nh(t)}options(){return O(this.Is.W())}priceScale(){return this.Kb.priceScale(this.Is.At().xa())}createPriceLine(t){const i=C(O(Me),t),n=this.Is.Jl(i);return new xe(n)}removePriceLine(t){this.Is.Ql(t.qb())}seriesType(){return this.Is.Xh()}attachPrimitive(t){this.Is.ba(t),t.attached&&t.attached({chart:this.Zb,series:this,requestUpdate:()=>this.Is.qt().$l()})}detachPrimitive(t){this.Is.wa(t),t.detached&&t.detached()}Jb(t){this.Yb.M()&&this.Yb.m(t)}}class ye{constructor(t,i,n){this.tw=new k,this.uu=new k,this._m=new k,this.Ui=t,this.wl=t.kt(),this.$m=i,this.wl.Ku().l(this.iw.bind(this)),this.wl.Zu().l(this.nw.bind(this)),this.$m.gm().l(this.sw.bind(this)),this.N_=n}S(){this.wl.Ku().p(this),this.wl.Zu().p(this),this.$m.gm().p(this),this.tw.S(),this.uu.S(),this._m.S()}scrollPosition(){return this.wl.Iu()}scrollToPosition(t,i){i?this.wl.qu(t,1e3):this.Ui.Jn(t)}scrollToRealTime(){this.wl.Uu()}getVisibleRange(){const t=this.wl.ku();return null===t?null:{from:t.from.originalTime,to:t.to.originalTime}}setVisibleRange(t){const i={from:this.N_.convertHorzItemToInternal(t.from),to:this.N_.convertHorzItemToInternal(t.to)},n=this.wl.Ru(i);this.Ui.ld(n)}getVisibleLogicalRange(){const t=this.wl.yu();return null===t?null:{from:t.Os(),to:t.di()}}setVisibleLogicalRange(t){c(t.from<=t.to,"The from index cannot be after the to index."),this.Ui.ld(t)}resetTimeScale(){this.Ui.Zn()}fitContent(){this.Ui.Qu()}logicalToCoordinate(t){const i=this.Ui.kt();return i.Fi()?null:i.It(t)}coordinateToLogical(t){return this.wl.Fi()?null:this.wl.Bu(t)}timeToCoordinate(t){const i=this.N_.convertHorzItemToInternal(t),n=this.wl.ka(i,!1);return null===n?null:this.wl.It(n)}coordinateToTime(t){const i=this.Ui.kt(),n=i.Bu(t),s=i.qi(n);return null===s?null:s.originalTime}width(){return this.$m.$p().width}height(){return this.$m.$p().height}subscribeVisibleTimeRangeChange(t){this.tw.l(t)}unsubscribeVisibleTimeRangeChange(t){this.tw.v(t)}subscribeVisibleLogicalRangeChange(t){this.uu.l(t)}unsubscribeVisibleLogicalRangeChange(t){this.uu.v(t)}subscribeSizeChange(t){this._m.l(t)}unsubscribeSizeChange(t){this._m.v(t)}applyOptions(t){this.wl.Nh(t)}options(){return Object.assign(Object.assign({},O(this.wl.W())),{barSpacing:this.wl.he()})}iw(){this.tw.M()&&this.tw.m(this.getVisibleRange())}nw(){this.uu.M()&&this.uu.m(this.getVisibleLogicalRange())}sw(t){this._m.m(t.width,t.height)}}function ke(t){if(void 0===t||"custom"===t.type)return;const i=t;void 0!==i.minMove&&void 0===i.precision&&(i.precision=function(t){if(t>=1)return 0;let i=0;for(;i<8;i++){const n=Math.round(t);if(Math.abs(n-t)<1e-8)return i;t*=10}return i}(i.minMove))}function Ce(t){return function(t){if(D(t.handleScale)){const i=t.handleScale;t.handleScale={axisDoubleClickReset:{time:i,price:i},axisPressedMouseMove:{time:i,price:i},mouseWheel:i,pinch:i}}else if(void 0!==t.handleScale){const{axisPressedMouseMove:i,axisDoubleClickReset:n}=t.handleScale;D(i)&&(t.handleScale.axisPressedMouseMove={time:i,price:i}),D(n)&&(t.handleScale.axisDoubleClickReset={time:n,price:n})}const i=t.handleScroll;D(i)&&(t.handleScroll={horzTouchDrag:i,vertTouchDrag:i,mouseWheel:i,pressedMouseMove:i})}(t),t}class Te{constructor(t,i,n){this.ew=new Map,this.rw=new Map,this.hw=new k,this.lw=new k,this.aw=new k,this.ow=new ie(i);const s=void 0===n?O(be()):C(O(be()),Ce(n));this.N_=i,this.$b=new Ns(t,s,i),this.$b.Fp().l((t=>{this.hw.M()&&this.hw.m(this._w(t()))}),this),this.$b.Wp().l((t=>{this.lw.M()&&this.lw.m(this._w(t()))}),this),this.$b.Wc().l((t=>{this.aw.M()&&this.aw.m(this._w(t()))}),this);const e=this.$b.qt();this.uw=new ye(e,this.$b.Zm(),this.N_)}remove(){this.$b.Fp().p(this),this.$b.Wp().p(this),this.$b.Wc().p(this),this.uw.S(),this.$b.S(),this.ew.clear(),this.rw.clear(),this.hw.S(),this.lw.S(),this.aw.S(),this.ow.S()}resize(t,i,n){this.autoSizeActive()||this.$b.qm(t,i,n)}addCustomSeries(t,i){const n=v(t),s=Object.assign(Object.assign({},h),n.defaultOptions());return this.cw("Custom",s,i,n)}addAreaSeries(t){return this.cw("Area",s,t)}addBaselineSeries(t){return this.cw("Baseline",e,t)}addBarSeries(t){return this.cw("Bar",i,t)}addCandlestickSeries(i={}){return function(t){void 0!==t.borderColor&&(t.borderUpColor=t.borderColor,t.borderDownColor=t.borderColor),void 0!==t.wickColor&&(t.wickUpColor=t.wickColor,t.wickDownColor=t.wickColor)}(i),this.cw("Candlestick",t,i)}addHistogramSeries(t){return this.cw("Histogram",r,t)}addLineSeries(t){return this.cw("Line",n,t)}removeSeries(t){const i=d(this.ew.get(t)),n=this.ow.hd(i);this.$b.qt().hd(i),this.dw(n),this.ew.delete(t),this.rw.delete(i)}Gb(t,i){this.dw(this.ow.Ab(t,i))}Qb(t,i){this.dw(this.ow.Ib(t,i))}subscribeClick(t){this.hw.l(t)}unsubscribeClick(t){this.hw.v(t)}subscribeCrosshairMove(t){this.aw.l(t)}unsubscribeCrosshairMove(t){this.aw.v(t)}subscribeDblClick(t){this.lw.l(t)}unsubscribeDblClick(t){this.lw.v(t)}priceScale(t){return new we(this.$b,t)}timeScale(){return this.uw}applyOptions(t){this.$b.Nh(Ce(t))}options(){return this.$b.W()}takeScreenshot(){return this.$b.tb()}autoSizeActive(){return this.$b.rb()}chartElement(){return this.$b.hb()}paneSize(){const t=this.$b.ab();return{height:t.height,width:t.width}}setCrosshairPosition(t,i,n){const s=this.ew.get(n);if(void 0===s)return;const e=this.$b.qt().cr(s);null!==e&&this.$b.qt().Qc(t,i,e)}clearCrosshairPosition(){this.$b.qt().td(!0)}cw(t,i,n={},s){ke(n.priceFormat);const e=C(O(l),O(i),n),r=this.$b.qt().ed(t,e,s),h=new Se(r,this,this,this,this.N_);return this.ew.set(h,r),this.rw.set(r,h),h}dw(t){const i=this.$b.qt();i.nd(t.kt.Au,t.kt.jb,t.kt.Hb),t.Fb.forEach(((t,i)=>i.it(t.He,t.Wb))),i.zu()}fw(t){return d(this.rw.get(t))}_w(t){const i=new Map;t.Mb.forEach(((t,n)=>{const s=n.Xh(),e=_e(s)(t);if("Custom"!==s)c(function(t){return void 0!==t.open||void 0!==t.value}(e));else{const t=n.Ma();c(!t||!1===t(e))}i.set(this.fw(n),e)}));const n=void 0===t.gb?void 0:this.fw(t.gb);return{time:t.bb,logical:t.se,point:t.wb,hoveredSeries:n,hoveredObjectId:t.xb,seriesData:i,sourceEvent:t.Sb}}}function Pe(t,i,n){let s;if(R(t)){const i=document.getElementById(t);c(null!==i,`Cannot find element in DOM with id=${t}`),s=i}else s=t;const e=new Te(s,i,n);return i.setOptions(e.options()),e}const Re=Object.assign(Object.assign({},l),h);var De=Object.freeze({__proto__:null,get ColorType(){return Dn},get CrosshairMode(){return rt},get LastPriceAnimationMode(){return Pn},get LineStyle(){return o},get LineType(){return a},get MismatchDirection(){return Bi},get PriceLineSource(){return Rn},get PriceScaleMode(){return cn},get TickMarkType(){return On},get TrackingModeExitMode(){return Tn},createChart:function(t,i){return Pe(t,new Zn,Zn.Td(i))},createChartEx:Pe,customSeriesDefaultOptions:Re,isBusinessDay:Bn,isUTCTimestamp:Vn,version:function(){return"4.2.0-dev+202310302149"}});window.LightweightCharts=De}(); diff --git a/lightweight_charts/js/styles.css b/lightweight_charts/js/styles.css new file mode 100644 index 0000000..991ff2a --- /dev/null +++ b/lightweight_charts/js/styles.css @@ -0,0 +1,234 @@ +:root { + --bg-color:#0c0d0f; + --hover-bg-color: #3c434c; + --click-bg-color: #50565E; + --active-bg-color: rgba(0, 122, 255, 0.7); + --muted-bg-color: rgba(0, 122, 255, 0.3); + --border-color: #3C434C; + --color: #d8d9db; + --active-color: #ececed; +} + +body { + background-color: rgb(0,0,0); + color: rgba(19, 23, 34, 1); + overflow: hidden; + font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, + Cantarell, "Helvetica Neue", sans-serif; +} + +.handler { + display: flex; + flex-direction: column; + position: relative; +} + +.toolbox { + position: absolute; + z-index: 2000; + display: flex; + align-items: center; + top: 25%; + border: 2px solid var(--border-color); + border-left: none; + border-top-right-radius: 4px; + border-bottom-right-radius: 4px; + background-color: rgba(25, 27, 30, 0.5); + flex-direction: column; +} + +.toolbox-button { + margin: 3px; + border-radius: 4px; + display: flex; + background-color: transparent; +} +.toolbox-button:hover { + background-color: rgba(80, 86, 94, 0.7); +} +.toolbox-button:active { + background-color: rgba(90, 106, 104, 0.7); +} + +.active-toolbox-button { + background-color: var(--active-bg-color) !important; +} +.active-toolbox-button g { + fill: var(--active-color); +} + +.context-menu { + position: absolute; + z-index: 1000; + background: rgb(50, 50, 50); + color: var(--active-color); + display: none; + border-radius: 5px; + padding: 3px 3px; + font-size: 13px; + cursor: default; +} +.context-menu-item { + display: flex; + align-items: center; + justify-content: space-between; + padding: 2px 10px; + margin: 1px 0px; + border-radius: 3px; +} +.context-menu-item:hover { + background-color: var(--muted-bg-color); +} + +.color-picker { + max-width: 170px; + background-color: var(--bg-color); + position: absolute; + z-index: 10000; + display: none; + flex-direction: column; + align-items: center; + border: 2px solid var(--border-color); + border-radius: 8px; + cursor: default; +} + + +/* topbar-related */ +.topbar { + background-color: var(--bg-color); + border-bottom: 2px solid var(--border-color); + display: flex; + align-items: center; +} + +.topbar-container { + display: flex; + align-items: center; + flex-grow: 1; +} + +.topbar-button { + border: none; + padding: 2px 5px; + margin: 4px 10px; + font-size: 13px; + border-radius: 4px; + color: var(--color); + background-color: transparent; +} +.topbar-button:hover { + background-color: var(--hover-bg-color) +} + +.topbar-button:active { + background-color: var(--click-bg-color); + color: var(--active-color); + font-weight: 500; +} + +.switcher-button:active { + background-color: var(--click-bg-color); + color: var(--color); + font-weight: normal; +} + +.active-switcher-button { + background-color: var(--active-bg-color) !important; + color: var(--active-color) !important; + font-weight: 500; +} + +.topbar-textbox { + margin: 0px 18px; + font-size: 16px; + color: var(--color); +} + +.topbar-textbox-input { + background-color: var(--bg-color); + color: var(--color); + border: 1px solid var(--color); +} + +.topbar-menu { + position: absolute; + display: none; + z-index: 10000; + background-color: var(--bg-color); + border-radius: 2px; + border: 2px solid var(--border-color); + border-top: none; + align-items: flex-start; + max-height: 80%; + overflow-y: auto; +} + +.topbar-separator { + width: 1px; + height: 20px; + background-color: var(--border-color); +} + +.searchbox { + position: absolute; + top: 0; + bottom: 200px; + left: 0; + right: 0; + margin: auto; + width: 150px; + height: 30px; + padding: 5px; + z-index: 1000; + align-items: center; + background-color: rgba(30 ,30, 30, 0.9); + border: 2px solid var(--border-color); + border-radius: 5px; + display: flex; + +} +.searchbox input { + text-align: center; + width: 100px; + margin-left: 10px; + background-color: var(--muted-bg-color); + color: var(--active-color); + font-size: 20px; + border: none; + outline: none; + border-radius: 2px; +} + +.spinner { + width: 30px; + height: 30px; + border: 4px solid rgba(255, 255, 255, 0.6); + border-top: 4px solid var(--active-bg-color); + border-radius: 50%; + position: absolute; + top: 50%; + left: 50%; + z-index: 1000; + transform: translate(-50%, -50%); + display: none; +} + +.legend { + position: absolute; + z-index: 3000; + pointer-events: none; + top: 10px; + left: 10px; + display: none; + flex-direction: column; +} +.legend-toggle-switch { + border-radius: 4px; + margin-left: 10px; + pointer-events: auto; +} +.legend-toggle-switch:hover { + cursor: pointer; + background-color: rgba(50, 50, 50, 0.5); +} \ No newline at end of file diff --git a/lightweight_charts/js/table.js b/lightweight_charts/js/table.js deleted file mode 100644 index 986f21c..0000000 --- a/lightweight_charts/js/table.js +++ /dev/null @@ -1,166 +0,0 @@ -if (!window.Table) { - class Table { - constructor(width, height, headings, widths, alignments, position, draggable = false, - tableBackgroundColor, borderColor, borderWidth, textColors, backgroundColors) { - this.container = document.createElement('div') - this.callbackName = null - this.borderColor = borderColor - this.borderWidth = borderWidth - - if (draggable) { - this.container.style.position = 'absolute' - this.container.style.cursor = 'move' - } else { - this.container.style.position = 'relative' - this.container.style.float = position - } - this.container.style.zIndex = '2000' - this.reSize(width, height) - this.container.style.display = 'flex' - this.container.style.flexDirection = 'column' - // this.container.style.justifyContent = 'space-between' - - this.container.style.borderRadius = '5px' - this.container.style.color = 'white' - this.container.style.fontSize = '12px' - this.container.style.fontVariantNumeric = 'tabular-nums' - - this.table = document.createElement('table') - this.table.style.width = '100%' - this.table.style.borderCollapse = 'collapse' - this.container.style.overflow = 'hidden' - - this.rows = {} - - this.headings = headings - this.widths = widths.map((width) => `${width * 100}%`) - this.alignments = alignments - - let head = this.table.createTHead() - let row = head.insertRow() - - for (let i = 0; i < this.headings.length; i++) { - let th = document.createElement('th') - th.textContent = this.headings[i] - th.style.width = this.widths[i] - th.style.letterSpacing = '0.03rem' - th.style.padding = '0.2rem 0px' - th.style.fontWeight = '500' - th.style.textAlign = 'center' - if (i !== 0) th.style.borderLeft = borderWidth+'px solid '+borderColor - th.style.position = 'sticky' - th.style.top = '0' - th.style.backgroundColor = backgroundColors.length > 0 ? backgroundColors[i] : tableBackgroundColor - th.style.color = textColors[i] - row.appendChild(th) - } - - let overflowWrapper = document.createElement('div') - overflowWrapper.style.overflowY = 'auto' - overflowWrapper.style.overflowX = 'hidden' - overflowWrapper.style.backgroundColor = tableBackgroundColor - overflowWrapper.appendChild(this.table) - this.container.appendChild(overflowWrapper) - document.getElementById('wrapper').appendChild(this.container) - - if (!draggable) return - - let offsetX, offsetY; - - this.onMouseDown = (event) => { - offsetX = event.clientX - this.container.offsetLeft; - offsetY = event.clientY - this.container.offsetTop; - - document.addEventListener('mousemove', onMouseMove); - document.addEventListener('mouseup', onMouseUp); - } - - let onMouseMove = (event) => { - this.container.style.left = (event.clientX - offsetX) + 'px'; - this.container.style.top = (event.clientY - offsetY) + 'px'; - } - - let onMouseUp = () => { - // Remove the event listeners for dragging - document.removeEventListener('mousemove', onMouseMove); - document.removeEventListener('mouseup', onMouseUp); - } - - this.container.addEventListener('mousedown', this.onMouseDown); - - - } - - divToButton(div, callbackString) { - div.addEventListener('mouseover', () => div.style.backgroundColor = 'rgba(60, 60, 60, 0.6)') - div.addEventListener('mouseout', () => div.style.backgroundColor = 'transparent') - div.addEventListener('mousedown', () => div.style.backgroundColor = 'rgba(60, 60, 60)') - div.addEventListener('click', () => window.callbackFunction(callbackString)) - div.addEventListener('mouseup', () => div.style.backgroundColor = 'rgba(60, 60, 60, 0.6)') - } - - newRow(id, returnClickedCell=false) { - let row = this.table.insertRow() - row.style.cursor = 'default' - - for (let i = 0; i < this.headings.length; i++) { - let cell = row.insertCell() - cell.style.width = this.widths[i]; - cell.style.textAlign = this.alignments[i]; - cell.style.border = this.borderWidth+'px solid '+this.borderColor - if (returnClickedCell) { - this.divToButton(cell, `${this.callbackName}_~_${id};;;${this.headings[i]}`) - } - row[this.headings[i]] = cell - } - if (!returnClickedCell) { - this.divToButton(row, `${this.callbackName}_~_${id}`) - } - this.rows[id] = row - } - - deleteRow(id) { - this.table.deleteRow(this.rows[id].rowIndex) - delete this.rows[id] - } - - clearRows() { - let numRows = Object.keys(this.rows).length - for (let i = 0; i < numRows; i++) - this.table.deleteRow(-1) - this.rows = {} - } - - updateCell(rowId, column, val) { - this.rows[rowId][column].textContent = val - } - - makeSection(id, type, numBoxes, func=false) { - let section = document.createElement('div') - section.style.display = 'flex' - section.style.width = '100%' - section.style.padding = '3px 0px' - section.style.backgroundColor = 'rgb(30, 30, 30)' - type === 'footer' ? this.container.appendChild(section) : this.container.prepend(section) - - this[type] = [] - for (let i = 0; i < numBoxes; i++) { - let textBox = document.createElement('div') - section.appendChild(textBox) - textBox.style.flex = '1' - textBox.style.textAlign = 'center' - if (func) { - this.divToButton(textBox, `${id}_~_${i}`) - textBox.style.borderRadius = '2px' - } - this[type].push(textBox) - } - } - - reSize(width, height) { - this.container.style.width = width <= 1 ? width * 100 + '%' : width + 'px' - this.container.style.height = height <= 1 ? height * 100 + '%' : height + 'px' - } - } - window.Table = Table -} diff --git a/lightweight_charts/js/test.html b/lightweight_charts/js/test.html new file mode 100644 index 0000000..827d7c6 --- /dev/null +++ b/lightweight_charts/js/test.html @@ -0,0 +1,23 @@ + + + + lightweight-charts-python + + + + + + +
+ + + + diff --git a/lightweight_charts/js/toolbox.js b/lightweight_charts/js/toolbox.js deleted file mode 100644 index d899cb8..0000000 --- a/lightweight_charts/js/toolbox.js +++ /dev/null @@ -1,736 +0,0 @@ -if (!window.ToolBox) { - class ToolBox { - constructor(chart) { - this.onTrendSelect = this.onTrendSelect.bind(this) - this.onHorzSelect = this.onHorzSelect.bind(this) - this.onRaySelect = this.onRaySelect.bind(this) - this.saveDrawings = this.saveDrawings.bind(this) - - this.chart = chart - this.drawings = [] - this.chart.cursor = 'default' - this.makingDrawing = false - this.mouseDown = false - - this.hoverBackgroundColor = 'rgba(80, 86, 94, 0.7)' - this.clickBackgroundColor = 'rgba(90, 106, 104, 0.7)' - - this.elem = this.makeToolBox() - this.subscribeHoverMove() - } - - toJSON() { - // Exclude the chart attribute from serialization - const {chart, ...serialized} = this; - return serialized; - } - - makeToolBox() { - let toolBoxElem = document.createElement('div') - toolBoxElem.style.position = 'absolute' - toolBoxElem.style.zIndex = '2000' - toolBoxElem.style.display = 'flex' - toolBoxElem.style.alignItems = 'center' - toolBoxElem.style.top = '25%' - toolBoxElem.style.border = '2px solid '+pane.borderColor - toolBoxElem.style.borderLeft = 'none' - toolBoxElem.style.borderTopRightRadius = '4px' - toolBoxElem.style.borderBottomRightRadius = '4px' - toolBoxElem.style.backgroundColor = 'rgba(25, 27, 30, 0.5)' - toolBoxElem.style.flexDirection = 'column' - - this.chart.activeIcon = null - - let trend = this.makeToolBoxElement(this.onTrendSelect, 'KeyT', ``) - let horz = this.makeToolBoxElement(this.onHorzSelect, 'KeyH', ``) - let ray = this.makeToolBoxElement(this.onRaySelect, 'KeyR', ``) - // let testB = this.makeToolBoxElement(this.onTrendSelect, 'KeyB', ``) - toolBoxElem.appendChild(trend) - toolBoxElem.appendChild(horz) - toolBoxElem.appendChild(ray) - // toolBoxElem.appendChild(testB) - - this.chart.div.append(toolBoxElem) - - let commandZHandler = (toDelete) => { - if (!toDelete) return - if ('price' in toDelete && toDelete.id !== 'toolBox') return commandZHandler(this.drawings[this.drawings.indexOf(toDelete) - 1]) - this.deleteDrawing(toDelete) - } - this.chart.commandFunctions.push((event) => { - if ((event.metaKey || event.ctrlKey) && event.code === 'KeyZ') { - commandZHandler(lastBar(this.drawings)) - return true - } - }); - - return toolBoxElem - } - - makeToolBoxElement(action, keyCmd, paths) { - let elem = document.createElement('div') - elem.style.margin = '3px' - elem.style.borderRadius = '4px' - elem.style.display = 'flex' - - let svg = document.createElementNS("http://www.w3.org/2000/svg", "svg"); - svg.setAttribute("width", "29"); - svg.setAttribute("height", "29"); - - let group = document.createElementNS("http://www.w3.org/2000/svg", "g"); - group.innerHTML = paths - group.setAttribute("fill", pane.color) - - svg.appendChild(group) - elem.appendChild(svg); - - let icon = {elem: elem, action: action} - - elem.addEventListener('mouseenter', () => { - elem.style.backgroundColor = icon === this.chart.activeIcon ? pane.activeBackgroundColor : this.hoverBackgroundColor - }) - elem.addEventListener('mouseleave', () => { - elem.style.backgroundColor = icon === this.chart.activeIcon ? pane.activeBackgroundColor : 'transparent' - }) - elem.addEventListener('mousedown', () => { - elem.style.backgroundColor = icon === this.chart.activeIcon ? pane.activeBackgroundColor : this.clickBackgroundColor - }) - elem.addEventListener('mouseup', () => { - elem.style.backgroundColor = icon === this.chart.activeIcon ? pane.activeBackgroundColor : 'transparent' - }) - elem.addEventListener('click', () => { - if (this.chart.activeIcon) { - this.chart.activeIcon.elem.style.backgroundColor = 'transparent' - group.setAttribute("fill", pane.color) - document.body.style.cursor = 'crosshair' - this.chart.cursor = 'crosshair' - this.chart.activeIcon.action(false) - if (this.chart.activeIcon === icon) { - return this.chart.activeIcon = null - } - } - this.chart.activeIcon = icon - group.setAttribute("fill", pane.activeColor) - elem.style.backgroundColor = pane.activeBackgroundColor - document.body.style.cursor = 'crosshair' - this.chart.cursor = 'crosshair' - this.chart.activeIcon.action(true) - }) - this.chart.commandFunctions.push((event) => { - - if (this.chart !== window.selectedChart) { - return - } - - if (event.altKey && event.code === keyCmd) { - event.preventDefault() - if (this.chart.activeIcon) { - this.chart.activeIcon.elem.style.backgroundColor = 'transparent' - group.setAttribute("fill", pane.color) - document.body.style.cursor = 'crosshair' - this.chart.cursor = 'crosshair' - this.chart.activeIcon.action(false) - } - this.chart.activeIcon = icon - group.setAttribute("fill", pane.activeColor) - elem.style.backgroundColor = pane.activeBackgroundColor - document.body.style.cursor = 'crosshair' - this.chart.cursor = 'crosshair' - this.chart.activeIcon.action(true) - return true - } - }) - return elem - } - - removeActiveAndSave() { - document.body.style.cursor = 'default' - this.chart.cursor = 'default' - this.chart.activeIcon.elem.style.backgroundColor = 'transparent' - this.chart.activeIcon = null - this.saveDrawings() - } - - onTrendSelect(toggle, ray = false) { - let trendLine = null - let firstTime = null - let firstPrice = null - let currentTime = null - - if (!toggle) { - return this.chart.chart.unsubscribeClick(this.clickHandler) - } - let crosshairHandlerTrend = (param) => { - this.chart.chart.unsubscribeCrosshairMove(crosshairHandlerTrend) - - if (!this.makingDrawing) return - - currentTime = this.chart.chart.timeScale().coordinateToTime(param.point.x) - if (!currentTime) { - let barsToMove = param.logical - this.chart.data.length-1 - currentTime = lastBar(this.chart.data).time+(barsToMove*this.chart.interval) - } - let currentPrice = this.chart.series.coordinateToPrice(param.point.y) - - if (!currentTime) return this.chart.chart.subscribeCrosshairMove(crosshairHandlerTrend) - trendLine.calculateAndSet(firstTime, firstPrice, currentTime, currentPrice) - - setTimeout(() => { - this.chart.chart.subscribeCrosshairMove(crosshairHandlerTrend) - }, 10); - } - - this.clickHandler = (param) => { - if (!this.makingDrawing) { - this.makingDrawing = true - trendLine = new TrendLine(this.chart, 'rgb(15, 139, 237)', ray) - firstPrice = this.chart.series.coordinateToPrice(param.point.y) - firstTime = !ray ? this.chart.chart.timeScale().coordinateToTime(param.point.x) : lastBar(this.chart.data).time - this.chart.chart.applyOptions({handleScroll: false}) - this.chart.chart.subscribeCrosshairMove(crosshairHandlerTrend) - } - else { - this.chart.chart.applyOptions({handleScroll: true}) - this.makingDrawing = false - trendLine.line.setMarkers([]) - this.drawings.push(trendLine) - this.chart.chart.unsubscribeCrosshairMove(crosshairHandlerTrend) - this.chart.chart.unsubscribeClick(this.clickHandler) - this.removeActiveAndSave() - } - } - this.chart.chart.subscribeClick(this.clickHandler) - } - - onHorzSelect(toggle) { - let clickHandlerHorz = (param) => { - let price = this.chart.series.coordinateToPrice(param.point.y) - let lineStyle = LightweightCharts.LineStyle.Solid - let line = new HorizontalLine(this.chart, 'toolBox', price,'red', 2, lineStyle, true) - this.drawings.push(line) - this.chart.chart.unsubscribeClick(clickHandlerHorz) - this.removeActiveAndSave() - } - if (toggle) this.chart.chart.subscribeClick(clickHandlerHorz) - else this.chart.chart.unsubscribeClick(clickHandlerHorz) - } - - onRaySelect(toggle) { - this.onTrendSelect(toggle, true) - } - - subscribeHoverMove() { - let hoveringOver = null - let x, y - let colorPicker = new ColorPicker(this.saveDrawings) - let stylePicker = new StylePicker(this.saveDrawings) - - let onClickDelete = () => this.deleteDrawing(contextMenu.drawing) - let onClickColor = (rect) => colorPicker.openMenu(rect, contextMenu.drawing) - let onClickStyle = (rect) => stylePicker.openMenu(rect, contextMenu.drawing) - let contextMenu = new ContextMenu() - contextMenu.menuItem('Color Picker', onClickColor, () =>{ - document.removeEventListener('click', colorPicker.closeMenu) - colorPicker.container.style.display = 'none' - }) - contextMenu.menuItem('Style', onClickStyle, () => { - document.removeEventListener('click', stylePicker.closeMenu) - stylePicker.container.style.display = 'none' - }) - contextMenu.separator() - contextMenu.menuItem('Delete Drawing', onClickDelete) - - let hoverOver = (param) => { - if (!param.point || this.makingDrawing) return - this.chart.chart.unsubscribeCrosshairMove(hoverOver) - x = param.point.x - y = param.point.y - - this.drawings.forEach((drawing) => { - let boundaryConditional - let horizontal = false - - if ('price' in drawing) { - horizontal = true - let priceCoordinate = this.chart.series.priceToCoordinate(drawing.price) - boundaryConditional = Math.abs(priceCoordinate - param.point.y) < 6 - } else { - let trendData = param.seriesData.get(drawing.line); - if (!trendData) return - let priceCoordinate = this.chart.series.priceToCoordinate(trendData.value) - let timeCoordinate = this.chart.chart.timeScale().timeToCoordinate(trendData.time) - boundaryConditional = Math.abs(priceCoordinate - param.point.y) < 6 && Math.abs(timeCoordinate - param.point.x) < 6 - } - - if (boundaryConditional) { - if (hoveringOver === drawing) return - if (!horizontal && !drawing.ray) drawing.line.setMarkers(drawing.markers) - document.body.style.cursor = 'pointer' - document.addEventListener('mousedown', checkForClick) - document.addEventListener('mouseup', checkForRelease) - hoveringOver = drawing - contextMenu.listen(true) - contextMenu.drawing = drawing - } else if (hoveringOver === drawing) { - if (!horizontal && !drawing.ray) drawing.line.setMarkers([]) - document.body.style.cursor = this.chart.cursor - hoveringOver = null - contextMenu.listen(false) - if (!this.mouseDown) { - document.removeEventListener('mousedown', checkForClick) - document.removeEventListener('mouseup', checkForRelease) - } - } - }) - this.chart.chart.subscribeCrosshairMove(hoverOver) - } - let originalIndex - let originalTime - let originalPrice - this.mouseDown = false - let clickedEnd = false - let labelColor - let checkForClick = (event) => { - this.mouseDown = true - document.body.style.cursor = 'grabbing' - this.chart.chart.applyOptions({handleScroll: false}) - this.chart.chart.timeScale().applyOptions({shiftVisibleRangeOnNewBar: false}) - - this.chart.chart.unsubscribeCrosshairMove(hoverOver) - - labelColor = this.chart.chart.options().crosshair.horzLine.labelBackgroundColor - this.chart.chart.applyOptions({crosshair: {horzLine: {labelBackgroundColor: hoveringOver.color}}}) - if ('price' in hoveringOver) { - originalPrice = hoveringOver.price - this.chart.chart.subscribeCrosshairMove(crosshairHandlerHorz) - } else if (Math.abs(this.chart.chart.timeScale().timeToCoordinate(hoveringOver.from[0]) - x) < 4 && !hoveringOver.ray) { - clickedEnd = 'first' - this.chart.chart.subscribeCrosshairMove(crosshairHandlerTrend) - } else if (Math.abs(this.chart.chart.timeScale().timeToCoordinate(hoveringOver.to[0]) - x) < 4 && !hoveringOver.ray) { - clickedEnd = 'last' - this.chart.chart.subscribeCrosshairMove(crosshairHandlerTrend) - } else { - originalPrice = this.chart.series.coordinateToPrice(y) - originalTime = this.chart.chart.timeScale().coordinateToTime(x * this.chart.scale.width) - this.chart.chart.subscribeCrosshairMove(checkForDrag) - } - originalIndex = this.chart.chart.timeScale().coordinateToLogical(x) - document.removeEventListener('mousedown', checkForClick) - } - let checkForRelease = (event) => { - this.mouseDown = false - document.body.style.cursor = this.chart.cursor - - this.chart.chart.applyOptions({handleScroll: true}) - this.chart.chart.timeScale().applyOptions({shiftVisibleRangeOnNewBar: true}) - this.chart.chart.applyOptions({crosshair: {horzLine: {labelBackgroundColor: labelColor}}}) - if (hoveringOver && 'price' in hoveringOver && hoveringOver.id !== 'toolBox') { - window.callbackFunction(`${hoveringOver.id}_~_${hoveringOver.price.toFixed(8)}`); - } - hoveringOver = null - document.removeEventListener('mousedown', checkForClick) - document.removeEventListener('mouseup', checkForRelease) - this.chart.chart.subscribeCrosshairMove(hoverOver) - this.saveDrawings() - } - let checkForDrag = (param) => { - if (!param.point) return - this.chart.chart.unsubscribeCrosshairMove(checkForDrag) - if (!this.mouseDown) return - - let priceAtCursor = this.chart.series.coordinateToPrice(param.point.y) - - let priceDiff = priceAtCursor - originalPrice - let barsToMove = param.logical - originalIndex - - let startBarIndex = this.chart.data.findIndex(item => item.time === hoveringOver.from[0]) - let endBarIndex = this.chart.data.findIndex(item => item.time === hoveringOver.to[0]) - - let startDate - let endBar - if (hoveringOver.ray) { - endBar = this.chart.data[startBarIndex + barsToMove] - startDate = hoveringOver.to[0] - } else { - startDate = this.chart.data[startBarIndex + barsToMove].time - endBar = endBarIndex === -1 ? null : this.chart.data[endBarIndex + barsToMove] - } - - let endDate = endBar ? endBar.time : hoveringOver.to[0] + (barsToMove * this.chart.interval) - let startValue = hoveringOver.from[1] + priceDiff - let endValue = hoveringOver.to[1] + priceDiff - - hoveringOver.calculateAndSet(startDate, startValue, endDate, endValue) - - originalIndex = param.logical - originalPrice = priceAtCursor - this.chart.chart.subscribeCrosshairMove(checkForDrag) - } - let crosshairHandlerTrend = (param) => { - if (!param.point) return - this.chart.chart.unsubscribeCrosshairMove(crosshairHandlerTrend) - if (!this.mouseDown) return - - let currentPrice = this.chart.series.coordinateToPrice(param.point.y) - let currentTime = this.chart.chart.timeScale().coordinateToTime(param.point.x) - - let [firstTime, firstPrice] = [null, null] - if (clickedEnd === 'last') { - firstTime = hoveringOver.from[0] - firstPrice = hoveringOver.from[1] - } else if (clickedEnd === 'first') { - firstTime = hoveringOver.to[0] - firstPrice = hoveringOver.to[1] - } - - if (!currentTime) { - let barsToMove = param.logical - this.chart.data.length-1 - currentTime = lastBar(this.chart.data).time + (barsToMove*this.chart.interval) - } - - hoveringOver.calculateAndSet(firstTime, firstPrice, currentTime, currentPrice) - - setTimeout(() => { - this.chart.chart.subscribeCrosshairMove(crosshairHandlerTrend) - }, 10); - } - let crosshairHandlerHorz = (param) => { - if (!param.point) return - this.chart.chart.unsubscribeCrosshairMove(crosshairHandlerHorz) - if (!this.mouseDown) return - hoveringOver.updatePrice(this.chart.series.coordinateToPrice(param.point.y)) - setTimeout(() => { - this.chart.chart.subscribeCrosshairMove(crosshairHandlerHorz) - }, 10) - } - this.chart.chart.subscribeCrosshairMove(hoverOver) - } - - renderDrawings() { - if (this.mouseDown) return - this.drawings.forEach((item) => { - if ('price' in item) return - let startDate = Math.round(item.from[0]/this.chart.interval)*this.chart.interval - let endDate = Math.round(item.to[0]/this.chart.interval)*this.chart.interval - item.calculateAndSet(startDate, item.from[1], endDate, item.to[1]) - }) - } - - deleteDrawing(drawing) { - if ('price' in drawing) { - this.chart.series.removePriceLine(drawing.line) - } - else { - let range = this.chart.chart.timeScale().getVisibleLogicalRange() - - this.chart.chart.timeScale().applyOptions({shiftVisibleRangeOnNewBar: false}) - this.chart.chart.removeSeries(drawing.line); - this.chart.chart.timeScale().applyOptions({shiftVisibleRangeOnNewBar: true}) - - this.chart.chart.timeScale().setVisibleLogicalRange(range) - } - this.drawings.splice(this.drawings.indexOf(drawing), 1) - this.saveDrawings() - } - - clearDrawings() { - this.drawings.forEach((item) => { - if ('price' in item) this.chart.series.removePriceLine(item.line) - else this.chart.chart.removeSeries(item.line) - }) - this.drawings = [] - } - - saveDrawings() { - let drawingsString = JSON.stringify(this.drawings, (key, value) => { - if (key === '' && Array.isArray(value)) { - return value.filter(item => !(item && typeof item === 'object' && 'priceLine' in item && item.id !== 'toolBox')); - } else if (key === 'line' || (value && typeof value === 'object' && 'priceLine' in value && value.id !== 'toolBox')) { - return undefined; - } - return value; - }); - window.callbackFunction(`save_drawings${this.chart.id}_~_${drawingsString}`) - } - - loadDrawings(drawings) { - this.drawings = [] - drawings.forEach((item) => { - let drawing = null - if ('price' in item) { - drawing = new HorizontalLine(this.chart, 'toolBox', - item.priceLine.price, item.priceLine.color, 2, - item.priceLine.lineStyle, item.priceLine.axisLabelVisible) - } - else { - let startDate = Math.round((item.from[0]/this.chart.interval)*this.chart.interval) - let endDate = Math.round((item.to[0]/this.chart.interval)*this.chart.interval) - - drawing = new TrendLine(this.chart, item.color, item.ray) - drawing.calculateAndSet(startDate, item.from[1], endDate, item.to[1]) - } - this.drawings.push(drawing) - }) - } - } - window.ToolBox = ToolBox - - - class TrendLine { - constructor(chart, color, ray) { - this.calculateAndSet = this.calculateAndSet.bind(this) - - this.line = chart.chart.addLineSeries({ - color: color, - lineWidth: 2, - lastValueVisible: false, - priceLineVisible: false, - crosshairMarkerVisible: false, - autoscaleInfoProvider: () => ({ - priceRange: { - minValue: 1_000_000_000, - maxValue: 0, - }, - }), - }) - this.color = color - this.markers = null - this.data = null - this.from = null - this.to = null - this.ray = ray - this.chart = chart - } - - toJSON() { - // Exclude the chart attribute from serialization - const {chart, ...serialized} = this; - return serialized; - } - - calculateAndSet(firstTime, firstPrice, currentTime, currentPrice) { - let data = calculateTrendLine(firstTime, firstPrice, currentTime, currentPrice, this.chart, this.ray) - this.from = [data[0].time, data[0].value] - this.to = [data[data.length - 1].time, data[data.length-1].value] - - this.chart.chart.timeScale().applyOptions({shiftVisibleRangeOnNewBar: false}) - let logical = this.chart.chart.timeScale().getVisibleLogicalRange() - - this.line.setData(data) - - this.chart.chart.timeScale().applyOptions({shiftVisibleRangeOnNewBar: true}) - this.chart.chart.timeScale().setVisibleLogicalRange(logical) - - if (!this.ray) { - this.markers = [ - {time: this.from[0], position: 'inBar', color: '#1E80F0', shape: 'circle', size: 0.1}, - {time: this.to[0], position: 'inBar', color: '#1E80F0', shape: 'circle', size: 0.1} - ] - this.line.setMarkers(this.markers) - } - } - } - window.TrendLine = TrendLine - - class ColorPicker { - constructor(saveDrawings) { - this.saveDrawings = saveDrawings - - this.container = document.createElement('div') - this.container.style.maxWidth = '170px' - this.container.style.backgroundColor = pane.backgroundColor - this.container.style.position = 'absolute' - this.container.style.zIndex = '10000' - this.container.style.display = 'none' - this.container.style.flexDirection = 'column' - this.container.style.alignItems = 'center' - this.container.style.border = '2px solid '+pane.borderColor - this.container.style.borderRadius = '8px' - this.container.style.cursor = 'default' - - let colorPicker = document.createElement('div') - colorPicker.style.margin = '10px' - colorPicker.style.display = 'flex' - colorPicker.style.flexWrap = 'wrap' - - let colors = [ - '#EBB0B0','#E9CEA1','#E5DF80','#ADEB97','#A3C3EA','#D8BDED', - '#E15F5D','#E1B45F','#E2D947','#4BE940','#639AE1','#D7A0E8', - '#E42C2A','#E49D30','#E7D827','#3CFF0A','#3275E4','#B06CE3', - '#F3000D','#EE9A14','#F1DA13','#2DFC0F','#1562EE','#BB00EF', - '#B50911','#E3860E','#D2BD11','#48DE0E','#1455B4','#6E009F', - '#7C1713','#B76B12','#8D7A13','#479C12','#165579','#51007E', - ] - - colors.forEach((color) => colorPicker.appendChild(this.makeColorBox(color))) - - let separator = document.createElement('div') - separator.style.backgroundColor = pane.borderColor - separator.style.height = '1px' - separator.style.width = '130px' - - let opacity = document.createElement('div') - opacity.style.margin = '10px' - - let opacityText = document.createElement('div') - opacityText.style.color = 'lightgray' - opacityText.style.fontSize = '12px' - opacityText.innerText = 'Opacity' - - let opacityValue = document.createElement('div') - opacityValue.style.color = 'lightgray' - opacityValue.style.fontSize = '12px' - - let opacitySlider = document.createElement('input') - opacitySlider.type = 'range' - opacitySlider.value = this.opacity*100 - opacityValue.innerText = opacitySlider.value+'%' - opacitySlider.oninput = () => { - opacityValue.innerText = opacitySlider.value+'%' - this.opacity = opacitySlider.value/100 - this.updateColor() - } - - opacity.appendChild(opacityText) - opacity.appendChild(opacitySlider) - opacity.appendChild(opacityValue) - - this.container.appendChild(colorPicker) - this.container.appendChild(separator) - this.container.appendChild(opacity) - document.getElementById('wrapper').appendChild(this.container) - - } - makeColorBox(color) { - let box = document.createElement('div') - box.style.width = '18px' - box.style.height = '18px' - box.style.borderRadius = '3px' - box.style.margin = '3px' - box.style.boxSizing = 'border-box' - box.style.backgroundColor = color - - box.addEventListener('mouseover', (event) => box.style.border = '2px solid lightgray') - box.addEventListener('mouseout', (event) => box.style.border = 'none') - - let rgbValues = this.extractRGB(color) - - box.addEventListener('click', (event) => { - this.rgbValues = rgbValues - this.updateColor() - }) - return box - } - extractRGB = (anyColor) => { - let dummyElem = document.createElement('div'); - dummyElem.style.color = anyColor; - document.body.appendChild(dummyElem); - let computedColor = getComputedStyle(dummyElem).color; - document.body.removeChild(dummyElem); - let colorValues = computedColor.match(/\d+/g).map(Number); - let isRgba = computedColor.includes('rgba'); - let opacity = isRgba ? parseFloat(computedColor.split(',')[3]) : 1 - return [colorValues[0], colorValues[1], colorValues[2], opacity] - } - updateColor() { - let oColor = `rgba(${this.rgbValues[0]}, ${this.rgbValues[1]}, ${this.rgbValues[2]}, ${this.opacity})` - if ('price' in this.drawing) this.drawing.updateColor(oColor) - else { - this.drawing.color = oColor - this.drawing.line.applyOptions({color: oColor}) - } - this.saveDrawings() - } - openMenu(rect, drawing) { - this.drawing = drawing - this.rgbValues = this.extractRGB(drawing.color) - this.opacity = parseFloat(this.rgbValues[3]) - this.container.style.top = (rect.top-30)+'px' - this.container.style.left = rect.right+'px' - this.container.style.display = 'flex' - setTimeout(() => document.addEventListener('mousedown', (event) => { - if (!this.container.contains(event.target)) { - this.closeMenu() - } - }), 10) - } - closeMenu(event) { - document.removeEventListener('click', this.closeMenu) - this.container.style.display = 'none' - } - } - window.ColorPicker = ColorPicker - class StylePicker { - constructor(saveDrawings) { - this.saveDrawings = saveDrawings - - this.container = document.createElement('div') - this.container.style.position = 'absolute' - this.container.style.zIndex = '10000' - this.container.style.background = 'rgb(50, 50, 50)' - this.container.style.color = pane.activeColor - this.container.style.display = 'none' - this.container.style.borderRadius = '5px' - this.container.style.padding = '3px 3px' - this.container.style.fontSize = '13px' - this.container.style.cursor = 'default' - - let styles = [ - {name: 'Solid', var: LightweightCharts.LineStyle.Solid}, - {name: 'Dotted', var: LightweightCharts.LineStyle.Dotted}, - {name: 'Dashed', var: LightweightCharts.LineStyle.Dashed}, - {name: 'Large Dashed', var: LightweightCharts.LineStyle.LargeDashed}, - {name: 'Sparse Dotted', var: LightweightCharts.LineStyle.SparseDotted}, - ] - styles.forEach((style) => { - this.container.appendChild(this.makeTextBox(style.name, style.var)) - }) - - document.getElementById('wrapper').appendChild(this.container) - - } - makeTextBox(text, style) { - let item = document.createElement('span') - item.style.display = 'flex' - item.style.alignItems = 'center' - item.style.justifyContent = 'space-between' - item.style.padding = '2px 10px' - item.style.margin = '1px 0px' - item.style.borderRadius = '3px' - item.innerText = text - - item.addEventListener('mouseover', (event) => item.style.backgroundColor = pane.mutedBackgroundColor) - item.addEventListener('mouseout', (event) => item.style.backgroundColor = 'transparent') - - item.addEventListener('click', (event) => { - this.style = style - this.updateStyle() - }) - return item - } - - updateStyle() { - if ('price' in this.drawing) this.drawing.updateStyle(this.style) - else { - this.drawing.line.applyOptions({lineStyle: this.style}) - } - this.saveDrawings() - } - openMenu(rect, drawing) { - this.drawing = drawing - this.container.style.top = (rect.top-30)+'px' - this.container.style.left = rect.right+'px' - this.container.style.display = 'block' - setTimeout(() => document.addEventListener('mousedown', (event) => { - if (!this.container.contains(event.target)) { - this.closeMenu() - } - }), 10) - } - closeMenu(event) { - document.removeEventListener('click', this.closeMenu) - this.container.style.display = 'none' - } - } - window.StylePicker = StylePicker -} diff --git a/lightweight_charts/polygon.py b/lightweight_charts/polygon.py index 623f51e..516bfff 100644 --- a/lightweight_charts/polygon.py +++ b/lightweight_charts/polygon.py @@ -247,7 +247,7 @@ async def async_set(self, sec_type: Literal['stocks', 'options', 'indices', 'for df = await async_get_bar_data(ticker, timeframe, start_date, end_date, limit) - self._chart.set(df, render_drawings=_tickers.get(self._chart) == ticker) + self._chart.set(df, keep_drawings=_tickers.get(self._chart) == ticker) _tickers[self._chart] = ticker if not live: @@ -396,7 +396,7 @@ class PolygonChart(Chart): Tickers, security types and timeframes are to be defined within the chart window. If using the standard `show` method, the `block` parameter must be set to True. - When using `show_async`, either is acceptable. + `show_async` can also be used. """ def __init__( self, api_key: str, live: bool = False, num_bars: int = 200, end_date: str = 'now', limit: int = 5_000, diff --git a/lightweight_charts/table.py b/lightweight_charts/table.py index b360b39..d4212f1 100644 --- a/lightweight_charts/table.py +++ b/lightweight_charts/table.py @@ -1,6 +1,6 @@ import asyncio import random -from typing import Union +from typing import Union, Optional, Callable from .util import jbool, Pane, NUM @@ -11,8 +11,8 @@ def __init__(self, table, section_type): self._table = table self.type = section_type - def __call__(self, number_of_text_boxes: int, func: callable = None): - if func: + def __call__(self, number_of_text_boxes: int, func: Optional[Callable] = None): + if func is not None: self.win.handlers[self.id] = lambda boxId: func(self._table, int(boxId)) self.run_script(f''' {self._table.id}.makeSection("{self.id}", "{self.type}", {number_of_text_boxes}, {"true" if func else ""}) @@ -35,7 +35,8 @@ def __init__(self, table, id, items): def __setitem__(self, column, value): if isinstance(column, tuple): - return [self.__setitem__(col, val) for col, val in zip(column, value)] + [self.__setitem__(col, val) for col, val in zip(column, value)] + return original_value = value if column in self._table._formatters: value = self._table._formatters[column].replace(self._table.VALUE, str(value)) @@ -47,23 +48,33 @@ def background_color(self, column, color): self._style('backgroundColor', column def text_color(self, column, color): self._style('textColor', column, color) def _style(self, style, column, arg): - self.run_script(f"{self._table.id}.rows[{self.id}]['{column}'].style.{style} = '{arg}'") + self.run_script(f"{self._table.id}.styleCell({self.id}, '{column}', '{style}', '{arg}')") def delete(self): self.run_script(f"{self._table.id}.deleteRow('{self.id}')") self._table.pop(self.id) - + class Table(Pane, dict): VALUE = 'CELL__~__VALUE__~__PLACEHOLDER' def __init__( - self, window, width: NUM, height: NUM, headings: tuple, widths: tuple = None, - alignments: tuple = None, position='left', draggable: bool = False, - background_color: str = '#121417', border_color: str = 'rgb(70, 70, 70)', - border_width: int = 1, heading_text_colors: tuple = None, - heading_background_colors: tuple = None, return_clicked_cells: bool = False, - func: callable = None + self, + window, + width: NUM, + height: NUM, + headings: tuple, + widths: Optional[tuple] = None, + alignments: Optional[tuple] = None, + position='left', + draggable: bool = False, + background_color: str = '#121417', + border_color: str = 'rgb(70, 70, 70)', + border_width: int = 1, + heading_text_colors: Optional[tuple] = None, + heading_background_colors: Optional[tuple] = None, + return_clicked_cells: bool = False, + func: Optional[Callable] = None ): dict.__init__(self) Pane.__init__(self, window) @@ -85,17 +96,20 @@ async def async_wrapper(rId, cId=None): self.win.handlers[self.id] = async_wrapper if asyncio.iscoroutinefunction(func) else wrapper self.return_clicked_cells = return_clicked_cells - headings = list(headings) - widths = list(widths) if widths else [] - alignments = list(alignments) if alignments else [] - heading_text_colors = list(heading_text_colors) if heading_text_colors else [] - heading_background_colors = list(heading_background_colors) if heading_background_colors else [] - self.run_script(f''' - {self.id} = new Table( - {width}, {height}, {headings}, {widths}, {alignments}, '{position}', {jbool(draggable)}, - '{background_color}', '{border_color}', {border_width}, {heading_text_colors}, - {heading_background_colors} + {self.id} = new Lib.Table( + {width}, + {height}, + {list(headings)}, + {list(widths) if widths else []}, + {list(alignments) if alignments else []}, + '{position}', + {jbool(draggable)}, + '{background_color}', + '{border_color}', + {border_width}, + {list(heading_text_colors) if heading_text_colors else []}, + {list(heading_background_colors) if heading_background_colors else []} )''') self.run_script(f'{self.id}.callbackName = "{self.id}"') if func else None self.footer = Section(self, 'footer') diff --git a/lightweight_charts/toolbox.py b/lightweight_charts/toolbox.py index 1fe4b27..ac47045 100644 --- a/lightweight_charts/toolbox.py +++ b/lightweight_charts/toolbox.py @@ -3,14 +3,12 @@ class ToolBox: def __init__(self, chart): - from lightweight_charts.abstract import JS self.run_script = chart.run_script self.id = chart.id self._save_under = None self.drawings = {} chart.win.handlers[f'save_drawings{self.id}'] = self._save_drawings - self.run_script(JS['toolbox']) - self.run_script(f'{self.id}.toolBox = new ToolBox({self.id})') + self.run_script(f'{self.id}.createToolBox()') def save_drawings_under(self, widget: 'Widget'): """ @@ -24,7 +22,7 @@ def load_drawings(self, tag: str): """ if not self.drawings.get(tag): return - self.run_script(f'if ("toolBox" in {self.id}) {self.id}.toolBox.loadDrawings({json.dumps(self.drawings[tag])})') + self.run_script(f'if ({self.id}.toolBox) {self.id}.toolBox.loadDrawings({json.dumps(self.drawings[tag])})') def import_drawings(self, file_path): """ diff --git a/lightweight_charts/topbar.py b/lightweight_charts/topbar.py index 4f884dc..bef9978 100644 --- a/lightweight_charts/topbar.py +++ b/lightweight_charts/topbar.py @@ -8,12 +8,15 @@ class Widget(Pane): - def __init__(self, topbar, value, func=None): + def __init__(self, topbar, value, func: callable = None, convert_boolean=False): super().__init__(topbar.win) self.value = value def wrapper(v): - self.value = v + if convert_boolean: + self.value = False if v == 'false' else True + else: + self.value = v func(topbar._chart) async def async_wrapper(v): @@ -24,9 +27,12 @@ async def async_wrapper(v): class TextWidget(Widget): - def __init__(self, topbar, initial_text, align): - super().__init__(topbar, value=initial_text) - self.run_script(f'{self.id} = {topbar.id}.makeTextBoxWidget("{initial_text}", "{align}")') + def __init__(self, topbar, initial_text, align, func): + super().__init__(topbar, value=initial_text, func=func) + + callback_name = f'"{self.id}"' if func else '' + + self.run_script(f'{self.id} = {topbar.id}.makeTextBoxWidget("{initial_text}", "{align}", {callback_name})') def set(self, string): self.value = string @@ -54,6 +60,7 @@ def __init__(self, topbar, options, default, separator, align, func): {self.id} = {topbar.id}.makeMenu({list(options)}, "{default}", {jbool(separator)}, "{self.id}", "{align}") ''') + # TODO this will probably need to be fixed def set(self, option): if option not in self.options: raise ValueError(f"Option {option} not in menu options ({self.options})") @@ -63,15 +70,19 @@ def set(self, option): ''') self.win.handlers[self.id](option) + def update_items(self, *items: str): + self.options = list(items) + self.run_script(f'{self.id}.updateMenuItems({self.options})') + class ButtonWidget(Widget): - def __init__(self, topbar, button, separator, align, func): - super().__init__(topbar, value=button, func=func) + def __init__(self, topbar, button, separator, align, toggle, func): + super().__init__(topbar, value=False, func=func, convert_boolean=toggle) self.run_script( - f'{self.id} = {topbar.id}.makeButton("{button}", "{self.id}", {jbool(separator)}, true, "{align}")') + f'{self.id} = {topbar.id}.makeButton("{button}", "{self.id}", {jbool(separator)}, true, "{align}", {jbool(toggle)})') def set(self, string): - self.value = string + # self.value = string self.run_script(f'{self.id}.elem.innerText = "{string}"') @@ -85,10 +96,8 @@ def __init__(self, chart): def _create(self): if self._created: return - from lightweight_charts.abstract import JS self._created = True - self.run_script(JS['callback']) - self.run_script(f'{self.id} = new TopBar({self._chart.id})') + self.run_script(f'{self.id} = {self._chart.id}.createTopBar()') def __getitem__(self, item): if widget := self._widgets.get(item): @@ -109,11 +118,11 @@ def menu(self, name, options: tuple, default: str = None, separator: bool = True self._widgets[name] = MenuWidget(self, options, default if default else options[0], separator, align, func) def textbox(self, name: str, initial_text: str = '', - align: ALIGN = 'left'): + align: ALIGN = 'left', func: callable = None): self._create() - self._widgets[name] = TextWidget(self, initial_text, align) + self._widgets[name] = TextWidget(self, initial_text, align, func) def button(self, name, button_text: str, separator: bool = True, - align: ALIGN = 'left', func: callable = None): + align: ALIGN = 'left', toggle: bool = False, func: callable = None): self._create() - self._widgets[name] = ButtonWidget(self, button_text, separator, align, func) + self._widgets[name] = ButtonWidget(self, button_text, separator, align, toggle, func) diff --git a/lightweight_charts/util.py b/lightweight_charts/util.py index ef3583c..5f9df42 100644 --- a/lightweight_charts/util.py +++ b/lightweight_charts/util.py @@ -3,6 +3,7 @@ from datetime import datetime from random import choices from typing import Literal, Union +from numpy import isin import pandas as pd @@ -11,6 +12,7 @@ def __init__(self, window): from lightweight_charts import Window self.win: Window = window self.run_script = window.run_script + self.bulk_run = window.bulk_run if hasattr(self, 'id'): return self.id = Window._id_gen.generate() @@ -19,7 +21,7 @@ def __init__(self, window): class IDGen(list): ascii = 'abcdefghijklmnopqrstuvwxyz' - def generate(self): + def generate(self) -> str: var = ''.join(choices(self.ascii, k=8)) if var not in self: self.append(var) @@ -37,13 +39,28 @@ def parse_event_message(window, string): def js_data(data: Union[pd.DataFrame, pd.Series]): if isinstance(data, pd.DataFrame): d = data.to_dict(orient='records') - filtered_records = [{k: v for k, v in record.items() if v is not None} for record in d] + filtered_records = [{k: v for k, v in record.items() if v is not None and not pd.isna(v)} for record in d] else: d = data.to_dict() filtered_records = {k: v for k, v in d.items()} return json.dumps(filtered_records, indent=2) +def snake_to_camel(s: str): + components = s.split('_') + return components[0] + ''.join(x.title() for x in components[1:]) + +def js_json(d: dict): + filtered_dict = {} + for key, val in d.items(): + if key in ('self') or val in (None,): + continue + if '_' in key: + key = snake_to_camel(key) + filtered_dict[key] = val + return f"JSON.parse('{json.dumps(filtered_dict)}')" + + def jbool(b: bool): return 'true' if b is True else 'false' if b is False else None @@ -53,32 +70,27 @@ def jbool(b: bool): return 'true' if b is True else 'false' if b is False else N MARKER_SHAPE = Literal['arrow_up', 'arrow_down', 'circle', 'square'] -CROSSHAIR_MODE = Literal['normal', 'magnet'] +CROSSHAIR_MODE = Literal['normal', 'magnet', 'hidden'] PRICE_SCALE_MODE = Literal['normal', 'logarithmic', 'percentage', 'index100'] -TIME = Union[datetime, pd.Timestamp, str] +TIME = Union[datetime, pd.Timestamp, str, float] NUM = Union[float, int] FLOAT = Literal['left', 'right', 'top', 'bottom'] -def line_style(line: LINE_STYLE): - js = 'LightweightCharts.LineStyle.' - return js+line[:line.index('_')].title() + line[line.index('_') + 1:].title() if '_' in line else js+line.title() - - -def crosshair_mode(mode: CROSSHAIR_MODE): - return f'LightweightCharts.CrosshairMode.{mode.title()}' if mode else None - - -def price_scale_mode(mode: PRICE_SCALE_MODE): - return f"LightweightCharts.PriceScaleMode.{'IndexedTo100' if mode == 'index100' else mode.title() if mode else None}" +def as_enum(value, string_types): + types = string_types.__args__ + return -1 if value not in types else types.index(value) def marker_shape(shape: MARKER_SHAPE): - return shape[:shape.index('_')]+shape[shape.index('_')+1:].title() if '_' in shape else shape + return { + 'arrow_up': 'arrowUp', + 'arrow_down': 'arrowDown', + }.get(shape) or shape def marker_position(p: MARKER_POSITION): @@ -86,8 +98,7 @@ def marker_position(p: MARKER_POSITION): 'above': 'aboveBar', 'below': 'belowBar', 'inside': 'inBar', - None: None, - }[p] + }.get(p) class Emitter: @@ -127,27 +138,54 @@ async def final_async_wrapper(*arg): class Events: def __init__(self, chart): self.new_bar = Emitter() - from lightweight_charts.abstract import JS self.search = JSEmitter(chart, f'search{chart.id}', lambda o: chart.run_script(f''' - {JS['callback']} - makeSpinner({chart.id}) - {chart.id}.search = makeSearchBox({chart.id}) + Lib.Handler.makeSpinner({chart.id}) + {chart.id}.search = Lib.Handler.makeSearchBox({chart.id}) ''') ) - self.range_change = JSEmitter(chart, f'range_change{chart.id}', + salt = chart.id[chart.id.index('.')+1:] + self.range_change = JSEmitter(chart, f'range_change{salt}', lambda o: chart.run_script(f''' - let checkLogicalRange = (logical) => {{ - {chart.id}.chart.timeScale().unsubscribeVisibleLogicalRangeChange(checkLogicalRange) + let checkLogicalRange{salt} = (logical) => {{ + {chart.id}.chart.timeScale().unsubscribeVisibleLogicalRangeChange(checkLogicalRange{salt}) let barsInfo = {chart.id}.series.barsInLogicalRange(logical) - if (barsInfo) window.callbackFunction(`range_change{chart.id}_~_${{barsInfo.barsBefore}};;;${{barsInfo.barsAfter}}`) + if (barsInfo) window.callbackFunction(`range_change{salt}_~_${{barsInfo.barsBefore}};;;${{barsInfo.barsAfter}}`) - setTimeout(() => {chart.id}.chart.timeScale().subscribeVisibleLogicalRangeChange(checkLogicalRange), 50) + setTimeout(() => {chart.id}.chart.timeScale().subscribeVisibleLogicalRangeChange(checkLogicalRange{salt}), 50) }} - {chart.id}.chart.timeScale().subscribeVisibleLogicalRangeChange(checkLogicalRange) + {chart.id}.chart.timeScale().subscribeVisibleLogicalRangeChange(checkLogicalRange{salt}) '''), wrapper=lambda o, c, *arg: o(c, *[float(a) for a in arg]) ) + self.click = JSEmitter(chart, f'subscribe_click{salt}', + lambda o: chart.run_script(f''' + let clickHandler{salt} = (param) => {{ + if (!param.point) return; + const time = {chart.id}.chart.timeScale().coordinateToTime(param.point.x) + const price = {chart.id}.series.coordinateToPrice(param.point.y); + window.callbackFunction(`subscribe_click{salt}_~_${{time}};;;${{price}}`) + }} + {chart.id}.chart.subscribeClick(clickHandler{salt}) + '''), + wrapper=lambda func, c, *args: func(c, *[float(a) for a in args]) + ) + +class BulkRunScript: + def __init__(self, script_func): + self.enabled = False + self.scripts = [] + self.script_func = script_func + + def __enter__(self): + self.enabled = True + + def __exit__(self, *args): + self.enabled = False + self.script_func('\n'.join(self.scripts)) + self.scripts = [] + def add_script(self, script): + self.scripts.append(script) diff --git a/lightweight_charts/widgets.py b/lightweight_charts/widgets.py index ff27678..7b18fd4 100644 --- a/lightweight_charts/widgets.py +++ b/lightweight_charts/widgets.py @@ -10,18 +10,25 @@ wx = None try: - using_py6 = False + using_pyside6 = False from PyQt5.QtWebEngineWidgets import QWebEngineView from PyQt5.QtWebChannel import QWebChannel - from PyQt5.QtCore import QObject, pyqtSlot as Slot + from PyQt5.QtCore import QObject, pyqtSlot as Slot, QUrl, QTimer except ImportError: - using_py6 = True + using_pyside6 = True try: from PySide6.QtWebEngineWidgets import QWebEngineView from PySide6.QtWebChannel import QWebChannel - from PySide6.QtCore import Qt, QObject, Slot + from PySide6.QtCore import Qt, QObject, Slot, QUrl, QTimer except ImportError: - QWebEngineView = None + try: + using_pyside6 = False + from PyQt6.QtWebEngineWidgets import QWebEngineView + from PyQt6.QtWebChannel import QWebChannel + from PyQt6.QtCore import QObject, pyqtSlot as Slot, QUrl, QTimer + except ImportError: + QWebEngineView = None + if QWebEngineView: class Bridge(QObject): @@ -61,12 +68,13 @@ def __init__(self, parent, inner_width: float = 1.0, inner_height: float = 1.0, inner_width, inner_height, scale_candles_only, toolbox) self.webview.Bind(wx.html2.EVT_WEBVIEW_LOADED, lambda e: wx.CallLater(500, self.win.on_js_load)) - self.webview.Bind(wx.html2.EVT_WEBVIEW_SCRIPT_MESSAGE_RECEIVED, lambda e: emit_callback(self, e.GetString())) + self.webview.Bind(wx.html2.EVT_WEBVIEW_SCRIPT_MESSAGE_RECEIVED, lambda e: emit_callback(self.win, e.GetString())) self.webview.AddScriptMessageHandler('wx_msg') - self.webview.SetPage(abstract.TEMPLATE, '') - self.webview.AddUserScript(abstract.JS['toolbox']) if toolbox else None - def get_webview(self): return self.webview + self.webview.LoadURL("file://"+abstract.INDEX) + + def get_webview(self): + return self.webview class QtChart(abstract.AbstractChart): @@ -82,21 +90,25 @@ def __init__(self, widget=None, inner_width: float = 1.0, inner_height: float = self.bridge = Bridge(self) self.web_channel.registerObject('bridge', self.bridge) self.webview.page().setWebChannel(self.web_channel) - self.webview.loadFinished.connect(self.win.on_js_load) - if using_py6: + self.webview.loadFinished.connect(lambda: self.webview.page().runJavaScript(''' + let scriptElement = document.createElement("script") + scriptElement.src = 'qrc:///qtwebchannel/qwebchannel.js' + + scriptElement.onload = function() { + var bridge = new QWebChannel(qt.webChannelTransport, function(channel) { + var pythonObject = channel.objects.bridge + window.pythonObject = pythonObject + }) + } + + document.head.appendChild(scriptElement) + + ''')) + self.webview.loadFinished.connect(lambda: QTimer.singleShot(200, self.win.on_js_load)) + if using_pyside6: self.webview.setContextMenuPolicy(Qt.ContextMenuPolicy.NoContextMenu) - self._html = f''' - {abstract.TEMPLATE[:85]} - - - {abstract.TEMPLATE[85:]} - ''' - self.webview.page().setHtml(self._html) + self.webview.load(QUrl.fromLocalFile(abstract.INDEX)) + def get_webview(self): return self.webview @@ -104,7 +116,21 @@ def get_webview(self): return self.webview class StaticLWC(abstract.AbstractChart): def __init__(self, width=None, height=None, inner_width=1, inner_height=1, scale_candles_only: bool = False, toolbox=False, autosize=True): - self._html = abstract.TEMPLATE.replace('\n\n', '') + + with open(abstract.INDEX.replace("test.html", 'styles.css'), 'r') as f: + css = f.read() + with open(abstract.INDEX.replace("test.html", 'bundle.js'), 'r') as f: + js = f.read() + with open(abstract.INDEX.replace("test.html", 'lightweight-charts.js'), 'r') as f: + lwc = f.read() + + with open(abstract.INDEX, 'r') as f: + self._html = f.read() \ + .replace('', f"") \ + .replace(' src="./lightweight-charts.js">', f'>{lwc}') \ + .replace(' src="./bundle.js">', f'>{js}') \ + .replace('\n', ' + + + diff --git a/src/general/global-params.ts b/src/general/global-params.ts new file mode 100644 index 0000000..6aa5e56 --- /dev/null +++ b/src/general/global-params.ts @@ -0,0 +1,60 @@ +export interface GlobalParams extends Window { + pane: paneStyle; // TODO shouldnt need this cause of css variables + handlerInFocus: string; + callbackFunction: Function; + containerDiv: HTMLElement; + setCursor: Function; + cursor: string; +} + +interface paneStyle { + backgroundColor: string; + hoverBackgroundColor: string; + clickBackgroundColor: string; + activeBackgroundColor: string; + mutedBackgroundColor: string; + borderColor: string; + color: string; + activeColor: string; +} + +export const paneStyleDefault: paneStyle = { + backgroundColor: '#0c0d0f', + hoverBackgroundColor: '#3c434c', + clickBackgroundColor: '#50565E', + activeBackgroundColor: 'rgba(0, 122, 255, 0.7)', + mutedBackgroundColor: 'rgba(0, 122, 255, 0.3)', + borderColor: '#3C434C', + color: '#d8d9db', + activeColor: '#ececed', +} + +declare const window: GlobalParams; + +export function globalParamInit() { + window.pane = { + ...paneStyleDefault, + } + window.containerDiv = document.getElementById("container") || document.createElement('div'); + window.setCursor = (type: string | undefined) => { + if (type) window.cursor = type; + document.body.style.cursor = window.cursor; + } + window.cursor = 'default'; +} + +export const setCursor = (type: string | undefined) => { + if (type) window.cursor = type; + document.body.style.cursor = window.cursor; +} + + +// export interface SeriesHandler { +// type: string; +// series: ISeriesApi; +// markers: SeriesMarker<"">[], +// horizontal_lines: HorizontalLine[], +// name?: string, +// precision: number, +// } + diff --git a/src/general/handler.ts b/src/general/handler.ts new file mode 100644 index 0000000..9321135 --- /dev/null +++ b/src/general/handler.ts @@ -0,0 +1,368 @@ +import { + ColorType, + CrosshairMode, + DeepPartial, + HistogramStyleOptions, + IChartApi, + ISeriesApi, + LineStyleOptions, + LogicalRange, + LogicalRangeChangeEventHandler, + MouseEventHandler, + MouseEventParams, + SeriesOptionsCommon, + SeriesType, + Time, + createChart +} from "lightweight-charts"; + +import { GlobalParams, globalParamInit } from "./global-params"; +import { Legend } from "./legend"; +import { ToolBox } from "./toolbox"; +import { TopBar } from "./topbar"; + + +export interface Scale{ + width: number, + height: number, +} + + +globalParamInit(); +declare const window: GlobalParams; + +export class Handler { + public id: string; + public commandFunctions: Function[] = []; + + public wrapper: HTMLDivElement; + public div: HTMLDivElement; + + public chart: IChartApi; + public scale: Scale; + public precision: number = 2; + + public series: ISeriesApi; + public volumeSeries: ISeriesApi; + + public legend: Legend; + private _topBar: TopBar | undefined; + public toolBox: ToolBox | undefined; + public spinner: HTMLDivElement | undefined; + + public _seriesList: ISeriesApi[] = []; + + // TODO find a better solution rather than the 'position' parameter + constructor( + chartId: string, + innerWidth: number, + innerHeight: number, + position: string, + autoSize: boolean + ) { + this.reSize = this.reSize.bind(this) + + this.id = chartId + this.scale = { + width: innerWidth, + height: innerHeight, + } + + this.wrapper = document.createElement('div') + this.wrapper.classList.add("handler"); + this.wrapper.style.float = position + + this.div = document.createElement('div') + this.div.style.position = 'relative' + + this.wrapper.appendChild(this.div); + window.containerDiv.append(this.wrapper) + + this.chart = this._createChart(); + this.series = this.createCandlestickSeries(); + this.volumeSeries = this.createVolumeSeries(); + + this.legend = new Legend(this) + + document.addEventListener('keydown', (event) => { + for (let i = 0; i < this.commandFunctions.length; i++) { + if (this.commandFunctions[i](event)) break + } + }) + window.handlerInFocus = this.id; + this.wrapper.addEventListener('mouseover', () => window.handlerInFocus = this.id) + + this.reSize() + if (!autoSize) return + window.addEventListener('resize', () => this.reSize()) + } + + + reSize() { + let topBarOffset = this.scale.height !== 0 ? this._topBar?._div.offsetHeight || 0 : 0 + this.chart.resize(window.innerWidth * this.scale.width, (window.innerHeight * this.scale.height) - topBarOffset) + this.wrapper.style.width = `${100 * this.scale.width}%` + this.wrapper.style.height = `${100 * this.scale.height}%` + + // TODO definitely a better way to do this + if (this.scale.height === 0 || this.scale.width === 0) { + // if (this.legend.div.style.display == 'flex') this.legend.div.style.display = 'none' + if (this.toolBox) { + this.toolBox.div.style.display = 'none' + } + } + else { + // this.legend.div.style.display = 'flex' + if (this.toolBox) { + this.toolBox.div.style.display = 'flex' + } + } + } + + private _createChart() { + return createChart(this.div, { + width: window.innerWidth * this.scale.width, + height: window.innerHeight * this.scale.height, + layout:{ + textColor: window.pane.color, + background: { + color: '#000000', + type: ColorType.Solid, + }, + fontSize: 12 + }, + rightPriceScale: { + scaleMargins: {top: 0.3, bottom: 0.25}, + }, + timeScale: {timeVisible: true, secondsVisible: false}, + crosshair: { + mode: CrosshairMode.Normal, + vertLine: { + labelBackgroundColor: 'rgb(46, 46, 46)' + }, + horzLine: { + labelBackgroundColor: 'rgb(55, 55, 55)' + } + }, + grid: { + vertLines: {color: 'rgba(29, 30, 38, 5)'}, + horzLines: {color: 'rgba(29, 30, 58, 5)'}, + }, + handleScroll: {vertTouchDrag: true}, + }) + } + + createCandlestickSeries() { + const up = 'rgba(39, 157, 130, 100)' + const down = 'rgba(200, 97, 100, 100)' + const candleSeries = this.chart.addCandlestickSeries({ + upColor: up, borderUpColor: up, wickUpColor: up, + downColor: down, borderDownColor: down, wickDownColor: down + }); + candleSeries.priceScale().applyOptions({ + scaleMargins: {top: 0.2, bottom: 0.2}, + }); + return candleSeries; + } + + createVolumeSeries() { + const volumeSeries = this.chart.addHistogramSeries({ + color: '#26a69a', + priceFormat: {type: 'volume'}, + priceScaleId: 'volume_scale', + }) + volumeSeries.priceScale().applyOptions({ + scaleMargins: {top: 0.8, bottom: 0}, + }); + return volumeSeries; + } + + createLineSeries(name: string, options: DeepPartial) { + const line = this.chart.addLineSeries({...options}); + this._seriesList.push(line); + this.legend.makeSeriesRow(name, line) + return { + name: name, + series: line, + } + } + + createHistogramSeries(name: string, options: DeepPartial) { + const line = this.chart.addHistogramSeries({...options}); + this._seriesList.push(line); + this.legend.makeSeriesRow(name, line) + return { + name: name, + series: line, + } + } + + createToolBox() { + this.toolBox = new ToolBox(this.id, this.chart, this.series, this.commandFunctions); + this.div.appendChild(this.toolBox.div); + } + + createTopBar() { + this._topBar = new TopBar(this); + this.wrapper.prepend(this._topBar._div) + return this._topBar; + } + + toJSON() { + // Exclude the chart attribute from serialization + const {chart, ...serialized} = this; + return serialized; + } + + public static syncCharts(childChart:Handler, parentChart: Handler, crosshairOnly = false) { + function crosshairHandler(chart: Handler, point: any) {//point: BarData | LineData) { + if (!point) { + chart.chart.clearCrosshairPosition() + return + } + // TODO fix any point ? + chart.chart.setCrosshairPosition(point.value || point!.close, point.time, chart.series); + chart.legend.legendHandler(point, true) + } + + function getPoint(series: ISeriesApi, param: MouseEventParams) { + if (!param.time) return null; + return param.seriesData.get(series) || null; + } + + const childTimeScale = childChart.chart.timeScale(); + const parentTimeScale = parentChart.chart.timeScale(); + + const setChildRange = (timeRange: LogicalRange | null) => { + if(timeRange) childTimeScale.setVisibleLogicalRange(timeRange); + } + const setParentRange = (timeRange: LogicalRange | null) => { + if(timeRange) parentTimeScale.setVisibleLogicalRange(timeRange); + } + + const setParentCrosshair = (param: MouseEventParams) => { + crosshairHandler(parentChart, getPoint(childChart.series, param)) + } + const setChildCrosshair = (param: MouseEventParams) => { + crosshairHandler(childChart, getPoint(parentChart.series, param)) + } + + let selected = parentChart + function addMouseOverListener( + thisChart: Handler, + otherChart: Handler, + thisCrosshair: MouseEventHandler