{"version":3,"file":"255.3bf2315e.js","mappings":"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","sources":["webpack://@finviz/website/../charts/app/lib/shims.ts","webpack://@finviz/website/../charts/app/logger.js","webpack://@finviz/website/../charts/app/models/chart-event-element.ts","webpack://@finviz/website/../charts/app/models/indicator.ts","webpack://@finviz/website/../charts/app/models/overlay.ts","webpack://@finviz/website/../charts/app/models/relationships.ts","webpack://@finviz/website/../charts/app/index.ts","webpack://@finviz/website/../charts/app/controllers/header/fullscreen_button.tsx","webpack://@finviz/website/../charts/app/controllers/header/layout_dropdown.tsx","webpack://@finviz/website/../charts/app/helpers/sorter.ts","webpack://@finviz/website/../charts/app/controllers/header/theme_toggle_button.tsx","webpack://@finviz/website/../charts/app/controllers/header/index.tsx","webpack://@finviz/website/../charts/app/controllers/chart-controls/stock-detail-timeframe-bar.tsx","webpack://@finviz/website/../charts/app/utils/convert_ta.ts","webpack://@finviz/website/./js/app/charts-lib.ts","webpack://@finviz/website/./js/app/quote/create-alert/async-modules.ts","webpack://@finviz/website/./js/app/quote/save-to-portfolio/async-modules.ts","webpack://@finviz/website/./js/app/shared/tracking.ts","webpack://@finviz/website/./js/main/components/portfolio/async-modules.ts","webpack://@finviz/website/./js/charts_lib_entry_do_not_directly_use_in_website.ts","webpack://@finviz/website/./js/main/components/checkbox.tsx","webpack://@finviz/website/./js/main/components/color-picker/draggable.tsx","webpack://@finviz/website/./js/main/components/color-picker/pointer.tsx","webpack://@finviz/website/./js/main/components/color-picker/util.ts","webpack://@finviz/website/./js/main/components/color-picker/alpha.tsx","webpack://@finviz/website/./js/main/components/color-picker/color-palette.tsx","webpack://@finviz/website/./js/main/components/color-picker/hue-saturation.tsx","webpack://@finviz/website/./js/main/components/color-picker/lightness.tsx","webpack://@finviz/website/./js/main/components/color-picker/color-preview.tsx","webpack://@finviz/website/./js/main/components/color-picker/picker-input.tsx","webpack://@finviz/website/./js/main/components/color-picker/picker.tsx","webpack://@finviz/website/./js/main/components/color-picker/picker-button.tsx","webpack://@finviz/website/./js/main/components/copy-to-clipboard/copy-to-clipboard.tsx","webpack://@finviz/website/./js/main/components/dropdown/dropdown.tsx","webpack://@finviz/website/./js/main/components/dropdown/dropdown-item.tsx","webpack://@finviz/website/./js/main/components/dropdown/hooks.ts","webpack://@finviz/website/./js/main/components/context-menu/context-menu.tsx","webpack://@finviz/website/./js/main/components/grid/grid.tsx","webpack://@finviz/website/./js/main/components/inner-state/inner-state.tsx","webpack://@finviz/website/./js/main/components/range.tsx","webpack://@finviz/website/./js/main/components/toolbar/interfaces.ts","webpack://@finviz/website/./js/main/components/toolbar/hooks.ts","webpack://@finviz/website/./js/main/components/toolbar/toolbar.tsx","webpack://@finviz/website/./js/main/components/toolbar/toolbar-button.tsx","webpack://@finviz/website/./js/main/components/toolbar/toolbar-group.tsx","webpack://@finviz/website/./js/main/components/toolbar/toolbar-item.tsx","webpack://@finviz/website/./js/main/components/toolbar/toolbar-divider.tsx","webpack://@finviz/website/./js/main/components/tour/step-content.tsx","webpack://@finviz/website/./js/main/components/tour/utils.ts","webpack://@finviz/website/./js/main/components/tour/hooks.tsx","webpack://@finviz/website/./js/main/components/tabs/tab.tsx","webpack://@finviz/website/./js/main/components/tabs/tab-list.tsx","webpack://@finviz/website/./js/main/components/tabs/tab-panel.tsx","webpack://@finviz/website/./js/main/components/tabs/tabs.tsx","webpack://@finviz/website/./js/main/components/badge.tsx","webpack://@finviz/website/./js/main/components/tooltip-input.tsx","webpack://@finviz/website/./js/main/hooks/use-track-pageview.ts","webpack://@finviz/website/./js/main/services/async-modules-utils.tsx","webpack://@finviz/website/./js/main/services/import-with-retry.ts","webpack://@finviz/website/../charts/app/canvas/ElementBaseConfig.ts","webpack://@finviz/website/../charts/app/canvas/arrow.ts","webpack://@finviz/website/../charts/app/canvas/brush/brush_v1.ts","webpack://@finviz/website/../charts/app/canvas/callout/callout_utils.ts","webpack://@finviz/website/../charts/app/canvas/callout/callout_v1.ts","webpack://@finviz/website/../charts/app/canvas/curve.ts","webpack://@finviz/website/../charts/app/canvas/ellipse.ts","webpack://@finviz/website/../charts/app/canvas/rotated_rectangle.ts","webpack://@finviz/website/../charts/app/canvas/symbol.ts","webpack://@finviz/website/../charts/app/canvas/drawingTools.ts","webpack://@finviz/website/../charts/app/canvas/element.ts","webpack://@finviz/website/../charts/app/canvas/elliott_waves/elliott_waves.ts","webpack://@finviz/website/../charts/app/canvas/ellipse/ellipse_v1.ts","webpack://@finviz/website/../charts/app/canvas/fibonacci_retracements.ts","webpack://@finviz/website/../charts/app/canvas/horizontal_line.ts","webpack://@finviz/website/../charts/app/canvas/line.ts","webpack://@finviz/website/../charts/app/canvas/measure.ts","webpack://@finviz/website/../charts/app/canvas/pitchfork/pitchfork_utils.ts","webpack://@finviz/website/../charts/app/canvas/pitchfork/pitchfork_v1.ts","webpack://@finviz/website/../charts/app/canvas/polygon.ts","webpack://@finviz/website/../charts/app/canvas/position.ts","webpack://@finviz/website/../charts/app/canvas/rectangle.ts","webpack://@finviz/website/../charts/app/canvas/rotated_rectangle/rotated_rectangle_v1.ts","webpack://@finviz/website/../charts/app/canvas/scaled_line.ts","webpack://@finviz/website/../charts/app/canvas/scaled_text.ts","webpack://@finviz/website/../charts/app/canvas/text.ts","webpack://@finviz/website/../charts/app/canvas/thumb.ts","webpack://@finviz/website/../charts/app/canvas/triangle.ts","webpack://@finviz/website/../charts/app/canvas/vertical_line.ts","webpack://@finviz/website/../charts/app/canvas/xabcd.ts","webpack://@finviz/website/../charts/app/canvas/cache.js","webpack://@finviz/website/../charts/app/models/chart_settings/interfaces.ts","webpack://@finviz/website/../charts/app/charts/utils.ts","webpack://@finviz/website/../charts/app/charts/base_chart.ts","webpack://@finviz/website/../charts/app/charts/candle_stick.ts","webpack://@finviz/website/../charts/app/charts/candle_stick_hollow.ts","webpack://@finviz/website/../charts/app/charts/heikin_ashi.ts","webpack://@finviz/website/../charts/app/charts/line_chart.ts","webpack://@finviz/website/../charts/app/charts/market_sentiment.ts","webpack://@finviz/website/../charts/app/charts/multi_line_chart.ts","webpack://@finviz/website/../charts/app/charts/ohlc_chart.ts","webpack://@finviz/website/../charts/app/charts/perf_chart.ts","webpack://@finviz/website/../charts/app/charts/charts.ts","webpack://@finviz/website/../charts/app/constants/common.ts","webpack://@finviz/website/../charts/app/controllers/autosave/utils.ts","webpack://@finviz/website/../charts/app/controllers/chart-controls/settings-button.tsx","webpack://@finviz/website/../charts/app/controllers/chart-controls/use-chart-controls.ts","webpack://@finviz/website/../charts/app/model-hooks/useModelRef.ts","webpack://@finviz/website/../charts/app/controllers/chart-controls/use-chart-model-custom-date-range-values.tsx","webpack://@finviz/website/../charts/app/controllers/chart-controls/use-charts-path-location.ts","webpack://@finviz/website/../charts/app/controllers/chart-controls/utils.ts","webpack://@finviz/website/../charts/app/controllers/chart-events/async-modules.ts","webpack://@finviz/website/../charts/app/controllers/chart-settings/async-modules.ts","webpack://@finviz/website/../charts/app/modals/background.tsx","webpack://@finviz/website/../charts/app/modals/color_range_row.tsx","webpack://@finviz/website/../charts/app/modals/border.tsx","webpack://@finviz/website/../charts/app/modals/checkbox.tsx","webpack://@finviz/website/../charts/app/modals/font.tsx","webpack://@finviz/website/../charts/app/modals/line.tsx","webpack://@finviz/website/../charts/app/modals/multiline_string.tsx","webpack://@finviz/website/../charts/app/modals/number.tsx","webpack://@finviz/website/../charts/app/modals/string.tsx","webpack://@finviz/website/../charts/app/modals/trend.tsx","webpack://@finviz/website/../charts/app/modals/visibility/visibility-input.tsx","webpack://@finviz/website/../charts/app/modals/visibility/index.tsx","webpack://@finviz/website/../charts/app/modals/element_style.tsx","webpack://@finviz/website/../charts/app/controllers/autosave/constants.ts","webpack://@finviz/website/../charts/app/controllers/autosave/use-drawing-autosave-api.tsx","webpack://@finviz/website/../charts/app/utils/string-byte-length.ts","webpack://@finviz/website/../charts/app/controllers/autosave/use-drawing-auto-save-controls.ts","webpack://@finviz/website/../charts/app/controllers/autosave/use-is-auto-save-active.ts","webpack://@finviz/website/../charts/app/controllers/autosave/with-auto-save.tsx","webpack://@finviz/website/../charts/app/utils/use-prev-state.ts","webpack://@finviz/website/../charts/app/controllers/chart-controls/chart-type-select.tsx","webpack://@finviz/website/../charts/app/controllers/chart-controls/use-chart-types.ts","webpack://@finviz/website/../charts/app/controllers/chart-controls/daily-change-display.tsx","webpack://@finviz/website/../charts/app/controllers/chart-controls/draw-button.tsx","webpack://@finviz/website/../charts/app/controllers/chart-controls/fullscreen-button.tsx","webpack://@finviz/website/../charts/app/controllers/chart-controls/search.tsx","webpack://@finviz/website/../charts/app/controllers/chart-controls/chart-controls.tsx","webpack://@finviz/website/../charts/app/models/context_menu.ts","webpack://@finviz/website/../charts/app/controllers/context_menu.tsx","webpack://@finviz/website/../charts/app/controllers/pane/chart-event-popover-with-state.tsx","webpack://@finviz/website/../charts/app/utils/use-click-away.ts","webpack://@finviz/website/../charts/app/controllers/pane/load-latest-data-button.tsx","webpack://@finviz/website/../charts/app/utils/use-is-mounted.ts","webpack://@finviz/website/../charts/app/controllers/pane/zoom_controls.tsx","webpack://@finviz/website/../charts/app/controllers/pane/pane.tsx","webpack://@finviz/website/../charts/app/controllers/pane/with-pane-model.tsx","webpack://@finviz/website/../charts/app/controllers/chart/chart-spinner-overlay.tsx","webpack://@finviz/website/../charts/app/controllers/chart/constants.ts","webpack://@finviz/website/../charts/app/controllers/chart/chart.tsx","webpack://@finviz/website/../charts/app/controllers/chart/with-chart-init.tsx","webpack://@finviz/website/../charts/app/controllers/chart/with-watched-panes-on-chart-model.tsx","webpack://@finviz/website/../charts/app/creators/async-modules.ts","webpack://@finviz/website/../charts/app/controllers/toolbar/drawingActions.tsx","webpack://@finviz/website/../charts/app/controllers/toolbar/drawingSettings.tsx","webpack://@finviz/website/../charts/app/controllers/toolbar/drawingTools.ts","webpack://@finviz/website/../charts/app/controllers/toolbar/toolbar.tsx","webpack://@finviz/website/../charts/app/controllers/toolbar/index.ts","webpack://@finviz/website/../charts/app/controllers/toolbar/auto-save-notes/auto-save-notes.tsx","webpack://@finviz/website/../charts/app/controllers/toolbar/auto-save-notes/auto-save-notes-dialog.tsx","webpack://@finviz/website/../charts/app/controllers/toolbar/confirmation_dialog.tsx","webpack://@finviz/website/../charts/app/controllers/toolbar/mobile/toolbar-mobile.tsx","webpack://@finviz/website/../charts/app/controllers/chart_layout/auto-save-state-indicator.tsx","webpack://@finviz/website/../charts/app/controllers/chart_layout/chart-layout-auto-save-note.tsx","webpack://@finviz/website/../charts/app/controllers/chart_layout/publish_old_button_click_listener.tsx","webpack://@finviz/website/../charts/app/controllers/autosave/idea-leave-dialog.tsx","webpack://@finviz/website/../charts/app/controllers/chart_layout/with-chart-route-change.tsx","webpack://@finviz/website/../charts/app/controllers/chart_layout/chart_layout_component.tsx","webpack://@finviz/website/../charts/app/controllers/chart_layout/with-quote-cache-management.tsx","webpack://@finviz/website/../charts/app/controllers/with_dialog_state_hook.tsx","webpack://@finviz/website/../charts/app/controllers/chart_layout/with-chart-page-title.tsx","webpack://@finviz/website/../charts/app/controllers/chart_layout/with-idea-model-state.tsx","webpack://@finviz/website/../charts/app/controllers/chart_layout/chart_layout.tsx","webpack://@finviz/website/../charts/app/controllers/chart_layout/constants.ts","webpack://@finviz/website/../charts/app/controllers/chart_layout/with-complete-layout-model-init.tsx","webpack://@finviz/website/../charts/app/controllers/chart_layout/with-quote-polling.tsx","webpack://@finviz/website/../charts/app/modals/ideas/utils.ts","webpack://@finviz/website/../charts/app/modals/ideas/IdeaItem.tsx","webpack://@finviz/website/../charts/app/modals/ideas/IdeasTabs.tsx","webpack://@finviz/website/../charts/app/modals/ideas/Ideas.tsx","webpack://@finviz/website/../charts/app/controllers/header/ideas_dropdown.tsx","webpack://@finviz/website/../charts/app/controllers/header/publish.tsx","webpack://@finviz/website/../charts/app/controllers/header/tour_button.tsx","webpack://@finviz/website/../charts/app/utils/chart-date-range-utils.ts","webpack://@finviz/website/../charts/app/controllers/renderUtils.ts","webpack://@finviz/website/../charts/app/controllers/sidebar/constants.ts","webpack://@finviz/website/../charts/app/controllers/sidebar/hooks/sidebar-context.tsx","webpack://@finviz/website/../charts/app/controllers/sidebar/modules/module-load-failed.tsx","webpack://@finviz/website/../charts/app/controllers/sidebar/modules/portfolio-watchlist/async-modules.ts","webpack://@finviz/website/../charts/app/controllers/sidebar/modules/modules.ts","webpack://@finviz/website/../charts/app/controllers/sidebar/modules/with-module-async-load.tsx","webpack://@finviz/website/../charts/app/controllers/sidebar/sidebar-tabs.tsx","webpack://@finviz/website/../charts/app/controllers/sidebar/sidebar-content.tsx","webpack://@finviz/website/../charts/app/controllers/sidebar/sidebar.tsx","webpack://@finviz/website/../charts/app/controllers/toolbar/interfaces.ts","webpack://@finviz/website/../charts/app/controllers/utils.ts","webpack://@finviz/website/../charts/app/helpers/atr.ts","webpack://@finviz/website/../charts/app/chart-events/chart-event.ts","webpack://@finviz/website/../charts/app/chart-events/dividends.ts","webpack://@finviz/website/../charts/app/chart-events/earnings.ts","webpack://@finviz/website/../charts/app/chart-events/split.ts","webpack://@finviz/website/../charts/app/chart-events/index.ts","webpack://@finviz/website/../charts/app/helpers/get-canvas-element-by-type.ts","webpack://@finviz/website/../charts/app/helpers/math.ts","webpack://@finviz/website/../charts/app/indicator-calculation/ema.ts","webpack://@finviz/website/../charts/app/indicator-calculation/main.ts","webpack://@finviz/website/../charts/app/indicators/configs/indicatorBaseConfig.ts","webpack://@finviz/website/../charts/app/indicators/configs/adx.ts","webpack://@finviz/website/../charts/app/indicators/indicator.ts","webpack://@finviz/website/../charts/app/utils/canvas-render.ts","webpack://@finviz/website/../charts/app/indicators/adx.ts","webpack://@finviz/website/../charts/app/indicators/configs/aro.ts","webpack://@finviz/website/../charts/app/indicator-calculation/aroon.ts","webpack://@finviz/website/../charts/app/indicators/aro.ts","webpack://@finviz/website/../charts/app/indicators/configs/aroosc.ts","webpack://@finviz/website/../charts/app/indicators/aroosc.ts","webpack://@finviz/website/../charts/app/indicators/configs/atr.ts","webpack://@finviz/website/../charts/app/indicators/atr.ts","webpack://@finviz/website/../charts/app/indicators/configs/cci.ts","webpack://@finviz/website/../charts/app/indicators/cci.ts","webpack://@finviz/website/../charts/app/indicators/configs/cot.ts","webpack://@finviz/website/../charts/app/indicators/cot.ts","webpack://@finviz/website/../charts/app/indicators/configs/fi.ts","webpack://@finviz/website/../charts/app/indicator-calculation/fi.ts","webpack://@finviz/website/../charts/app/indicators/fi.ts","webpack://@finviz/website/../charts/app/indicators/configs/macd.ts","webpack://@finviz/website/../charts/app/indicator-calculation/macd.ts","webpack://@finviz/website/../charts/app/indicators/macd.ts","webpack://@finviz/website/../charts/app/indicators/configs/mfi.ts","webpack://@finviz/website/../charts/app/indicators/mfi.ts","webpack://@finviz/website/../charts/app/indicators/configs/none.ts","webpack://@finviz/website/../charts/app/indicators/none.ts","webpack://@finviz/website/../charts/app/indicators/configs/obv.ts","webpack://@finviz/website/../charts/app/indicators/obv.ts","webpack://@finviz/website/../charts/app/indicators/configs/perf.ts","webpack://@finviz/website/../charts/app/indicators/perf.ts","webpack://@finviz/website/../charts/app/indicators/configs/rmi.ts","webpack://@finviz/website/../charts/app/indicators/rmi.ts","webpack://@finviz/website/../charts/app/indicators/configs/roc.ts","webpack://@finviz/website/../charts/app/indicators/roc.ts","webpack://@finviz/website/../charts/app/indicators/configs/rsi.ts","webpack://@finviz/website/../charts/app/indicator-calculation/rsi.ts","webpack://@finviz/website/../charts/app/indicators/rsi.ts","webpack://@finviz/website/../charts/app/indicators/configs/rvol.ts","webpack://@finviz/website/../charts/app/indicators/rvol.ts","webpack://@finviz/website/../charts/app/indicators/configs/rwi.ts","webpack://@finviz/website/../charts/app/indicators/rwi.ts","webpack://@finviz/website/../charts/app/indicators/configs/shrtfl.ts","webpack://@finviz/website/../charts/app/indicators/financialIndicator.ts","webpack://@finviz/website/../charts/app/indicators/shrtfl.ts","webpack://@finviz/website/../charts/app/indicators/configs/shrtra.ts","webpack://@finviz/website/../charts/app/indicators/shrtra.ts","webpack://@finviz/website/../charts/app/indicators/configs/stofa.ts","webpack://@finviz/website/../charts/app/indicators/configs/stofu.ts","webpack://@finviz/website/../charts/app/indicators/stofu.ts","webpack://@finviz/website/../charts/app/indicators/stofa.ts","webpack://@finviz/website/../charts/app/indicators/configs/stosl.ts","webpack://@finviz/website/../charts/app/indicators/stosl.ts","webpack://@finviz/website/../charts/app/indicators/configs/trix.ts","webpack://@finviz/website/../charts/app/indicator-calculation/trix.ts","webpack://@finviz/website/../charts/app/indicators/trix.ts","webpack://@finviz/website/../charts/app/indicators/configs/ult.ts","webpack://@finviz/website/../charts/app/indicators/ult.ts","webpack://@finviz/website/../charts/app/indicators/configs/vol.ts","webpack://@finviz/website/../charts/app/indicators/vol.ts","webpack://@finviz/website/../charts/app/indicators/configs/wr.ts","webpack://@finviz/website/../charts/app/indicators/wr.ts","webpack://@finviz/website/../charts/app/indicators/indicators.ts","webpack://@finviz/website/../charts/app/modals/publish/async-modules.ts","webpack://@finviz/website/../charts/app/model-hooks/use-model-state.ts","webpack://@finviz/website/../charts/app/models/chart.ts","webpack://@finviz/website/../charts/app/models/chart/contstants.ts","webpack://@finviz/website/../charts/app/models/chart_layout.ts","webpack://@finviz/website/../charts/app/models/chart_settings/index.ts","webpack://@finviz/website/../charts/app/models/constants.ts","webpack://@finviz/website/../charts/app/models/drawings-internal-store.ts","webpack://@finviz/website/../charts/app/models/element.ts","webpack://@finviz/website/../charts/app/models/mouse/mouse-utils.ts","webpack://@finviz/website/../charts/app/models/mouse/mouse.ts","webpack://@finviz/website/../charts/app/models/pane.ts","webpack://@finviz/website/../charts/app/models/quoteCache.ts","webpack://@finviz/website/../charts/app/models/quote.ts","webpack://@finviz/website/../charts/app/models/quote/constants.ts","webpack://@finviz/website/../charts/app/models/chart_settings/constants.ts","webpack://@finviz/website/../charts/app/models/chart_settings/interactive_chart_settings.ts","webpack://@finviz/website/../charts/app/models/settings.ts","webpack://@finviz/website/../charts/app/models/utils.ts","webpack://@finviz/website/../charts/app/overlays/configs/ema.ts","webpack://@finviz/website/../charts/app/overlays/configs/overlayBaseConfig.ts","webpack://@finviz/website/../charts/app/overlays/configs/bb.ts","webpack://@finviz/website/../charts/app/indicator-calculation/bb.ts","webpack://@finviz/website/../charts/app/overlays/overlay.ts","webpack://@finviz/website/../charts/app/overlays/bb.ts","webpack://@finviz/website/../charts/app/overlays/configs/dch.ts","webpack://@finviz/website/../charts/app/overlays/dch.ts","webpack://@finviz/website/../charts/app/overlays/ema.ts","webpack://@finviz/website/../charts/app/overlays/configs/ema2.ts","webpack://@finviz/website/../charts/app/overlays/ema2.ts","webpack://@finviz/website/../charts/app/overlays/configs/hilo.ts","webpack://@finviz/website/../charts/app/overlays/hilo.ts","webpack://@finviz/website/../charts/app/overlays/configs/hline.ts","webpack://@finviz/website/../charts/app/overlays/hline.ts","webpack://@finviz/website/../charts/app/overlays/configs/ic.ts","webpack://@finviz/website/../charts/app/overlays/ic.ts","webpack://@finviz/website/../charts/app/overlays/configs/icf.ts","webpack://@finviz/website/../charts/app/overlays/icf.ts","webpack://@finviz/website/../charts/app/overlays/configs/kch.ts","webpack://@finviz/website/../charts/app/overlays/kch.ts","webpack://@finviz/website/../charts/app/overlays/configs/none.ts","webpack://@finviz/website/../charts/app/overlays/none.ts","webpack://@finviz/website/../charts/app/overlays/configs/patterns.ts","webpack://@finviz/website/../charts/app/overlays/patterns.ts","webpack://@finviz/website/../charts/app/overlays/configs/pp.ts","webpack://@finviz/website/../charts/app/overlays/pp.ts","webpack://@finviz/website/../charts/app/overlays/configs/sar.ts","webpack://@finviz/website/../charts/app/overlays/sar.ts","webpack://@finviz/website/../charts/app/overlays/configs/sma.ts","webpack://@finviz/website/../charts/app/indicator-calculation/sma.ts","webpack://@finviz/website/../charts/app/overlays/sma.ts","webpack://@finviz/website/../charts/app/overlays/configs/sma2.ts","webpack://@finviz/website/../charts/app/overlays/sma2.ts","webpack://@finviz/website/../charts/app/overlays/configs/str.ts","webpack://@finviz/website/../charts/app/overlays/str.ts","webpack://@finviz/website/../charts/app/overlays/configs/vp.ts","webpack://@finviz/website/../charts/app/overlays/vp.ts","webpack://@finviz/website/../charts/app/overlays/configs/vwap.ts","webpack://@finviz/website/../charts/app/indicator-calculation/vwap.ts","webpack://@finviz/website/../charts/app/overlays/vwap.ts","webpack://@finviz/website/../charts/app/overlays/overlays.ts","webpack://@finviz/website/../charts/app/utils.ts","webpack://@finviz/website/../charts/app/utils/abort_controller.ts","webpack://@finviz/website/../charts/app/utils/async-modules-utils.ts","webpack://@finviz/website/../charts/app/utils/canvas.ts","webpack://@finviz/website/../charts/app/utils/chart-events-utils.ts","webpack://@finviz/website/../charts/app/utils/chart.ts","webpack://@finviz/website/../charts/app/utils/colors.ts","webpack://@finviz/website/../charts/app/utils/cursor.ts","webpack://@finviz/website/../charts/app/utils/draw_in_visible_area.ts","webpack://@finviz/website/../charts/app/utils/fetch_api.ts","webpack://@finviz/website/../charts/app/utils/force-update.ts","webpack://@finviz/website/../charts/app/utils/helpers.ts","webpack://@finviz/website/../charts/app/utils/hlc.ts","webpack://@finviz/website/../charts/app/utils/useChartLayoutGlobalModelAsync.ts","webpack://@finviz/website/../charts/types/shared.ts"],"sourcesContent":["import Spine from '@finviz/spine'\r\n\r\n// eslint-disable-next-line no-extend-native\r\nArray.prototype.last = function () {\r\n return this[this.length - 1]\r\n}\r\n\r\n// eslint-disable-next-line no-extend-native\r\nString.prototype.padLeft = function (paddingValue) {\r\n return String(paddingValue + this).slice(-paddingValue.length)\r\n}\r\n\r\n// eslint-disable-next-line no-extend-native\r\nString.prototype.startsWith = function (str) {\r\n return this.indexOf(str) === 0\r\n}\r\n\r\ninterface CallbackCacheItem {\r\n newCb: (...args: any[]) => any\r\n origCb: (...args: any[]) => any\r\n}\r\n\r\nconst _callbackCache: CallbackCacheItem[] = []\r\nSpine.Collection.prototype.bind = function (ev, callback) {\r\n // eslint-disable-next-line @typescript-eslint/no-this-alias\r\n const that = this\r\n const cb = (record: Spine.Model, ...rest: any[]) => {\r\n if (record[that.fkey as keyof Spine.Model] === that.record.id) {\r\n return callback(record, ...rest)\r\n }\r\n }\r\n _callbackCache.push({ newCb: cb, origCb: callback })\r\n this.model.bind(ev, cb)\r\n return this\r\n}\r\n\r\nSpine.Collection.prototype.unbind = function (ev, callback) {\r\n let cb\r\n for (const item of _callbackCache) {\r\n if (item.origCb === callback) {\r\n cb = item.newCb\r\n break\r\n }\r\n }\r\n return this.model.unbind(ev, cb)\r\n}\r\n\r\nSpine.Model.findIndex = function (element) {\r\n const iterable = this.all()\r\n for (let index = 0; index < iterable.length; index++) {\r\n const el = iterable[index]\r\n if (element.eql(el)) {\r\n return index\r\n }\r\n }\r\n}\r\n","import Spine from '@finviz/spine'\r\n\r\nexport const defaults = {\r\n enabled: false,\r\n collapsed: true,\r\n duration: false,\r\n timestamp: true,\r\n logErrors: true,\r\n withStackTrace: false,\r\n level: 'log',\r\n logger: console,\r\n filterChanges: (model, attrs) => {\r\n const props = Object.keys(attrs)\r\n return (\r\n model.constructor.name === 'Mouse' ||\r\n model.constructor.name === 'Quote' ||\r\n (props.length === 1 && (props[0] === 'scale' || props[0] === 'leftOffset'))\r\n )\r\n },\r\n errorTransformer: (error) => error,\r\n titleFormatter: ({ timestamp, duration }, title, time, took) => {\r\n const parts = ['model']\r\n parts.push(`%c${String(title)}`)\r\n if (timestamp) {\r\n parts.push(`%c@ ${time}`)\r\n }\r\n if (duration) {\r\n parts.push(`%c(in ${took.toFixed(2)} ms)`)\r\n }\r\n return parts.join(' ')\r\n },\r\n colors: {\r\n title: () => 'inherit',\r\n prevState: () => '#9E9E9E',\r\n action: () => '#03A9F4',\r\n nextState: () => '#4CAF50',\r\n error: () => '#F20404',\r\n },\r\n}\r\n\r\nconst repeat = (str, times) => new Array(times + 1).join(str)\r\nconst pad = (num, maxLength = 2) => repeat('0', maxLength - num.toString().length) + num\r\nconst formatTime = (time) =>\r\n `${pad(time.getHours())}:${pad(time.getMinutes())}:${pad(time.getSeconds())}.${pad(time.getMilliseconds(), 3)}`\r\n\r\nexport const printLogEntry = (logEntry, options = {}) => {\r\n const { logger, logErrors, titleFormatter, collapsed, timestamp, duration, withStackTrace, colors, level } = {\r\n ...defaults,\r\n ...options,\r\n }\r\n const { startedTime, title, prevState, data, error, nextState, took } = logEntry\r\n\r\n const formattedTime = formatTime(startedTime)\r\n const titleCSS = colors.title ? `color: ${colors.title(title)};` : ''\r\n const headerCSS = ['color: gray; font-weight: lighter;']\r\n headerCSS.push(titleCSS)\r\n if (timestamp) {\r\n headerCSS.push('color: gray; font-weight: lighter;')\r\n }\r\n if (duration) {\r\n headerCSS.push('color: gray; font-weight: lighter;')\r\n }\r\n const formattedTitle = titleFormatter(defaults, title, formattedTime, took)\r\n\r\n try {\r\n if (collapsed) {\r\n if (colors.title) {\r\n logger.groupCollapsed(`%c ${formattedTitle}`, ...headerCSS)\r\n } else {\r\n logger.groupCollapsed(formattedTitle)\r\n }\r\n } else if (colors.title) {\r\n logger.group(`%c ${formattedTitle}`, ...headerCSS)\r\n } else {\r\n logger.group(formattedTitle)\r\n }\r\n } catch (e) {\r\n logger.log(formattedTitle)\r\n }\r\n\r\n if (colors.prevState) {\r\n const styles = `color: ${colors.prevState(prevState)}; font-weight: bold`\r\n logger[level]('%c prev state', styles, prevState)\r\n } else {\r\n logger[level]('prev state', prevState)\r\n }\r\n\r\n if (colors.action) {\r\n const styles = `color: ${colors.action(data)}; font-weight: bold`\r\n logger[level]('%c arguments ', styles, data)\r\n } else {\r\n logger[level]('arguments ', data)\r\n }\r\n\r\n if (error && logErrors) {\r\n if (colors.error) {\r\n const styles = `color: ${colors.error(error, prevState)}; font-weight: bold;`\r\n logger['error']('%c error ', styles, error)\r\n } else {\r\n logger['error']('error ', error)\r\n }\r\n }\r\n\r\n if (colors.nextState) {\r\n const styles = `color: ${colors.nextState(nextState)}; font-weight: bold`\r\n logger[level]('%c next state', styles, nextState)\r\n } else {\r\n logger[level]('next state', nextState)\r\n }\r\n\r\n if (withStackTrace) {\r\n logger.groupCollapsed('TRACE')\r\n logger.trace()\r\n logger.groupEnd()\r\n }\r\n\r\n try {\r\n logger.groupEnd()\r\n } catch (e) {\r\n logger.log('—— log end ——')\r\n }\r\n}\r\n\r\nexport const initialize = () => {\r\n window['logger'] = defaults\r\n\r\n const protoModelLoad = Spine.Model.prototype.load\r\n Spine.Model.prototype.load = function (attrs) {\r\n if (defaults.enabled && !defaults.filterChanges(this, attrs)) {\r\n const started = Date.now()\r\n const logEntry = {\r\n title: `${this.constructor.name}[#${this.id || this.cid}]`,\r\n started: started,\r\n startedTime: new Date(started),\r\n prevState: this.attributes(),\r\n data: attrs,\r\n }\r\n\r\n let returnedValue\r\n try {\r\n returnedValue = protoModelLoad.apply(this, arguments)\r\n } catch (e) {\r\n logEntry.error = e\r\n }\r\n\r\n logEntry.nextState = this.attributes()\r\n logEntry.took = Date.now() - logEntry.started\r\n\r\n printLogEntry(logEntry)\r\n return returnedValue\r\n } else {\r\n return protoModelLoad.apply(this, arguments)\r\n }\r\n }\r\n}\r\n","import { ObjectHash } from '../../types/shared'\r\nimport { Theme } from '../../types/shared'\r\nimport ChartEvent from '../chart-events/chart-event'\r\nimport { ChartEventBadgeType } from '../constants/common'\r\nimport { chartEventsAsyncModule } from '../controllers/chart-events/async-modules'\r\nimport { ChartEventBadgeState, IChartEventBadgeProps } from '../utils/chart-events-utils'\r\nimport { captureException } from '../utils/helpers'\r\nimport { CHART_EVENT_BADGE_SIZE } from './constants'\r\nimport ElementModel from './element'\r\nimport Pane from './pane'\r\n\r\nlet badgeImages: ObjectHash<{ image: HTMLImageElement; isLoaded?: boolean }, string> | null = null\r\n\r\ntype ChartEventBadgeCommonType = Omit & { badgeType: ChartEventBadgeType }\r\n\r\nfunction getSvgImageCacheKey(props: Pick) {\r\n return `${props.badgeType}-${props.theme}-${props.state}`\r\n}\r\n\r\nasync function fetchAndCacheChartEventBadges({ onBadgeInitLoad }: { onBadgeInitLoad: () => void }) {\r\n // Currently node charts don't render badges and if the code below is executed on server it will crash because of missing file which is not transpiled\r\n if (typeof window === 'undefined') {\r\n return\r\n }\r\n\r\n if (badgeImages === null) {\r\n badgeImages = {}\r\n } else {\r\n // Early return if cache was already initialized\r\n return\r\n }\r\n\r\n // Temp workaround to prevent node charts from crashing\r\n const { importWithRetry } = await import('@finviz/website')\r\n const { chartBadgeSvgByType } = await importWithRetry(chartEventsAsyncModule.importFn)\r\n\r\n const handleImageResolve = () => {\r\n const hasSomeUnresolvedImages = Object.values(badgeImages!).some(({ isLoaded }) => isLoaded === undefined)\r\n if (!hasSomeUnresolvedImages) {\r\n onBadgeInitLoad()\r\n }\r\n }\r\n\r\n Object.values(ChartEventBadgeState).forEach((badgeState) => {\r\n Object.values(ChartEventBadgeType).forEach((badgeType) => {\r\n Object.values(Theme).forEach((theme) => {\r\n const cacheKey = getSvgImageCacheKey({\r\n badgeType,\r\n state: badgeState,\r\n theme,\r\n })\r\n const svgHTML = chartBadgeSvgByType[badgeType]({\r\n state: badgeState,\r\n theme,\r\n width: CHART_EVENT_BADGE_SIZE,\r\n })\r\n const img = new Image()\r\n img.onload = () => {\r\n badgeImages![cacheKey].isLoaded = true\r\n handleImageResolve()\r\n }\r\n img.onerror = () => {\r\n badgeImages![cacheKey].isLoaded = false\r\n handleImageResolve()\r\n captureException(new Error(`Image with cache key ${cacheKey} is invalid`), { extra: { src: img.src } })\r\n }\r\n img.src = `data:image/svg+xml,${encodeURIComponent(svgHTML)}`\r\n badgeImages![cacheKey] = {\r\n image: img,\r\n }\r\n })\r\n })\r\n })\r\n}\r\n\r\nclass ChartEventElement extends ElementModel {\r\n static initClass(paneModel: typeof Pane) {\r\n this.configure('ChartEventElement', 'instance', 'lastChange', 'zIndex', 'yIndex', 'elementId')\r\n this.belongsTo('pane', paneModel)\r\n }\r\n\r\n declare instance: ChartEvent\r\n yIndex = 0\r\n\r\n getChartEventBadgeImage(props: ChartEventBadgeCommonType) {\r\n const cacheKey = getSvgImageCacheKey(props)\r\n const badgeImage = badgeImages?.[cacheKey]\r\n if (badgeImage) {\r\n // Possible fix for https://finvizcom.sentry.io/issues/4737062163\r\n if (badgeImage.isLoaded && badgeImage.image.width > 0 && badgeImage.image.height > 0) {\r\n return badgeImage.image\r\n }\r\n return undefined\r\n }\r\n\r\n void fetchAndCacheChartEventBadges({\r\n onBadgeInitLoad: () => this.trigger('change', this),\r\n })\r\n }\r\n\r\n getChartEventData() {\r\n return this.instance.model\r\n .chart()\r\n .quote()\r\n ?.chartEvents?.find((stockEvent) => stockEvent.elementId === this?.elementId)\r\n }\r\n\r\n toObject() {\r\n return {\r\n ...super.toObject(),\r\n yIndex: this.yIndex,\r\n }\r\n }\r\n\r\n toConfig() {\r\n return {\r\n ...super.toConfig(),\r\n yIndex: this.yIndex,\r\n }\r\n }\r\n}\r\n\r\nexport default ChartEventElement\r\n","import Spine from '@finviz/spine'\r\n\r\nimport Chart from './chart'\r\n\r\nclass Indicator extends Spine.Model {\r\n static initClass(chartModel: typeof Chart) {\r\n this.configure('Indicator', 'instance')\r\n this.belongsTo('chart', chartModel)\r\n }\r\n\r\n declare chart: () => Chart\r\n\r\n // instance - todo - not sure what instance type to put here\r\n}\r\n\r\nexport default Indicator\r\n","import Spine from '@finviz/spine'\r\n\r\nimport Chart from './chart'\r\n\r\nclass Overlay extends Spine.Model {\r\n static initClass(chartModel: typeof Chart) {\r\n this.configure('Overlay', 'overlay')\r\n this.belongsTo('chart', chartModel)\r\n }\r\n\r\n declare overlay: any\r\n declare chart: () => Chart\r\n}\r\n\r\nexport default Overlay\r\n","/**\r\n * This file sets up the relationships between models and solves circular dependencies\r\n * This file needs to be imported in the index file so that the relationships are\r\n * called in time for instantiation.\r\n */\r\nimport Chart from './chart'\r\nimport ChartEventElement from './chart-event-element'\r\nimport ChartLayout from './chart_layout'\r\nimport DrawingsInternalStore from './drawings-internal-store'\r\nimport Element from './element'\r\nimport Indicator from './indicator'\r\nimport Overlay from './overlay'\r\nimport Pane from './pane'\r\nimport Quote from './quote'\r\n\r\nChart.initClass(Pane, Quote, ChartLayout)\r\nChartLayout.initClass(Chart, DrawingsInternalStore)\r\nDrawingsInternalStore.initClass()\r\nElement.initClass(Pane)\r\nChartEventElement.initClass(Pane)\r\nIndicator.initClass(Chart)\r\nOverlay.initClass(Chart)\r\nPane.initClass(Element, ChartEventElement, Chart)\r\n","import './lib/shims'\r\nimport { initialize } from './logger'\r\nimport './models/relationships'\r\n\r\nif (document.location.hostname === 'localhost') {\r\n initialize()\r\n}\r\n","import { Button } from '@finviz/website'\r\nimport * as React from 'react'\r\n\r\nimport Utils, { getExitFullscreen, getFullscreenStatus, getRequestFullscreen } from '../../utils'\r\n\r\nconst isIPad = Utils.isIPad()\r\nconst IPAD_FULLSCREEN_CLASS = 'is-ipad-fullscreen'\r\n\r\nexport function FullscreenButton() {\r\n const [isFullscreen, setIsFullscreen] = React.useState(getFullscreenStatus())\r\n const requestFullscreen = getRequestFullscreen(document.documentElement)\r\n const exitFullscreen = getExitFullscreen()\r\n\r\n const onClick = React.useRef(() => {\r\n if (getFullscreenStatus()) {\r\n exitFullscreen.call(document)\r\n } else {\r\n requestFullscreen.call(document.documentElement)\r\n }\r\n })\r\n\r\n React.useEffect(() => {\r\n const checkFullscreen = () => {\r\n if (isIPad) {\r\n if (getFullscreenStatus()) {\r\n document.body.classList.add(IPAD_FULLSCREEN_CLASS)\r\n } else {\r\n document.body.classList.remove(IPAD_FULLSCREEN_CLASS)\r\n }\r\n }\r\n setIsFullscreen(getFullscreenStatus())\r\n }\r\n\r\n document.addEventListener('webkitfullscreenchange', checkFullscreen)\r\n document.addEventListener('fullscreenchange', checkFullscreen)\r\n return () => {\r\n document.removeEventListener('webkitfullscreenchange', checkFullscreen)\r\n document.removeEventListener('fullscreenchange', checkFullscreen)\r\n }\r\n }, [])\r\n\r\n if (!requestFullscreen) return null\r\n\r\n return (\r\n \r\n {isFullscreen ? 'Exit Full screen' : 'Full screen'}\r\n \r\n )\r\n}\r\n","import { Button, Dropdown, DropdownItem, Icon, IconNameType, MenuGroup, Paragraph } from '@finviz/website'\r\nimport * as React from 'react'\r\nimport { useLocation, useNavigate } from 'react-router-dom'\r\n\r\nimport { LAYOUTS } from '../../constants/common'\r\nimport { sortObjects } from '../../helpers/sorter'\r\nimport { useModelState } from '../../model-hooks/use-model-state'\r\nimport { ChartSyncableParts } from '../../models/chart/contstants'\r\nimport ChartLayout from '../../models/chart_layout'\r\nimport { decodeQueryString } from '../../utils/query_string'\r\nimport { useChartsPathLocation } from '../chart-controls/use-charts-path-location'\r\n\r\nconst SORTED_LAYOUT_KEYS = sortObjects(\r\n Object.entries(LAYOUTS).map(([key, value]) => ({ ...value, key })),\r\n [{ sortBy: 'columns' }, { sortBy: 'count' }]\r\n).map(({ key }) => key)\r\n\r\nexport function ChartLayoutDropdown({ model }: { model: ChartLayout }) {\r\n const location = useLocation()\r\n const navigate = useNavigate()\r\n const parsedQuery = decodeQueryString(location.search)\r\n const chartLayoutModel = useModelState(model, { watchProperties: ['layout', 'syncChartParts'] })\r\n const { getChartsToPath } = useChartsPathLocation({ chartLayoutModel })\r\n\r\n return (\r\n \r\n Layout\r\n \r\n }\r\n >\r\n
\r\n
\r\n {SORTED_LAYOUT_KEYS.map((layout) => (\r\n {\r\n navigate(getChartsToPath({ layout }))\r\n }}\r\n >\r\n \r\n \r\n ))}\r\n
\r\n \r\n
\r\n
\r\n Sync:\r\n
\r\n {ChartSyncableParts.map(({ value, label }) => {\r\n const isChartPartInSync = chartLayoutModel.getIsChartPartInSync(value)\r\n return (\r\n {\r\n chartLayoutModel.setSyncChartParts(value, !isChartPartInSync)\r\n if (!isChartPartInSync) window.gtag?.('event', 'sync', { event_label: value })\r\n }}\r\n >\r\n {label}\r\n \r\n )\r\n })}\r\n
\r\n
\r\n
\r\n \r\n )\r\n}\r\n","import { ObjectHash } from '../../types/shared'\r\nimport { SORT_DIRECTION } from '../constants/common'\r\n\r\nexport function sortObjects(\r\n arr: ObjectHash[],\r\n options: Array<{ sortBy: string; sortDirection?: keyof typeof SORT_DIRECTION }> = []\r\n) {\r\n return arr.sort((a, b) =>\r\n options.reduce((acc, option) => {\r\n const { sortBy, sortDirection = SORT_DIRECTION.ASC } = option\r\n const directionMultiplier = sortDirection === SORT_DIRECTION.ASC ? 1 : -1\r\n return acc === 0 ? (a[sortBy] - b[sortBy]) * directionMultiplier : acc\r\n }, 0)\r\n )\r\n}\r\n","import { Button, setCookieRequest } from '@finviz/website'\r\nimport * as React from 'react'\r\n\r\nimport { useModelState } from '../../model-hooks/use-model-state'\r\nimport ChartLayout from '../../models/chart_layout'\r\nimport { updateSettings } from '../../models/settings'\r\n\r\nexport function ThemeToggleButton({ model }: { model: ChartLayout }) {\r\n const chartLayoutModel = useModelState(model, { watchProperties: ['theme'] })\r\n const isDarkMode = model.theme === 'dark'\r\n\r\n const onClick = () => {\r\n const theme = isDarkMode ? 'light' : 'dark'\r\n chartLayoutModel.updateAttributes({ theme, settings: updateSettings(chartLayoutModel, theme) })\r\n chartLayoutModel.trigger('theme', chartLayoutModel)\r\n setCookieRequest('chartsTheme', theme).catch(() => {})\r\n\r\n if (isDarkMode) {\r\n document.documentElement.classList.remove('dark')\r\n } else {\r\n document.documentElement.classList.add('dark')\r\n }\r\n }\r\n\r\n if (!chartLayoutModel) {\r\n return null\r\n }\r\n\r\n return (\r\n \r\n )\r\n}\r\n","import { Button, Time, TimeBreakpoint } from '@finviz/website'\r\nimport * as React from 'react'\r\n\r\nimport { useModelState } from '../../model-hooks/use-model-state'\r\nimport ChartLayout from '../../models/chart_layout'\r\nimport { FullscreenButton } from './fullscreen_button'\r\nimport { IdeasDropdown } from './ideas_dropdown'\r\nimport { ChartLayoutDropdown } from './layout_dropdown'\r\nimport { Publish } from './publish'\r\nimport { ThemeToggleButton } from './theme_toggle_button'\r\nimport { TourButton } from './tour_button'\r\n\r\nconst BREAKPOINTS: TimeBreakpoint[] = [\r\n { minWidth: -Infinity, marketBadgeText: false, timeFormat: 'timeOnly' },\r\n { minWidth: 550, marketBadgeText: false, timeFormat: 'short' },\r\n { minWidth: 700, marketBadgeText: false, timeFormat: 'long' },\r\n { minWidth: 768, marketBadgeText: true, timeFormat: 'long' },\r\n]\r\n\r\ninterface ChartLayoutHeaderProps {\r\n model: ChartLayout\r\n onSettingsOpen: () => void\r\n hasPublish: boolean\r\n}\r\n\r\nexport function ChartLayoutHeaderComponent({ model, onSettingsOpen = () => {}, hasPublish }: ChartLayoutHeaderProps) {\r\n const chartLayout = useModelState(model, { watchProperties: ['idea'] })!\r\n\r\n return (\r\n <>\r\n
\r\n \r\n Ideas\r\n \r\n
\r\n
\r\n \r\n Chart tour\r\n \r\n \r\n \r\n {hasPublish && (\r\n \r\n Share\r\n \r\n )}\r\n \r\n \r\n \r\n
\r\n \r\n )\r\n}\r\n\r\nexport const ChartLayoutHeader = React.memo(\r\n ChartLayoutHeaderComponent,\r\n (prevProps, nextProps) =>\r\n prevProps.model === nextProps.model &&\r\n prevProps.onSettingsOpen === nextProps.onSettingsOpen &&\r\n prevProps.hasPublish === nextProps.hasPublish\r\n)\r\n","import {\r\n ButtonSizeType,\r\n CustomDateRange,\r\n TimeframeBar,\r\n useCustomDateRangeDialog,\r\n useFavoriteTimeframes,\r\n withSuspense,\r\n} from '@finviz/website'\r\nimport React from 'react'\r\n\r\nimport { Instrument } from '../../../types/shared'\r\nimport { TIMEFRAME } from '../../constants/common'\r\nimport { useModelState } from '../../model-hooks/use-model-state'\r\nimport { isRedesignEnabled } from '../../utils'\r\nimport { useChartLayoutGlobalModelAsync } from '../../utils/useChartLayoutGlobalModelAsync'\r\nimport { useChartControls } from './use-chart-controls'\r\nimport { useChartModelCustomDateRangeValues } from './use-chart-model-custom-date-range-values'\r\n\r\nfunction StockDetailTimeframeBarRaw({\r\n size = 'regular',\r\n className = '!m-0 space-x-2',\r\n isDateRangeAvailable,\r\n isPremium,\r\n isLoadingOverride,\r\n isScrollIntoViewEnabled = false,\r\n onTimeframeSelect = () => {},\r\n onDateRangeSelect = () => {},\r\n}: {\r\n size?: ButtonSizeType\r\n className?: string\r\n isDateRangeAvailable: boolean\r\n isPremium: boolean\r\n isLoadingOverride?: boolean\r\n isScrollIntoViewEnabled?: boolean\r\n onTimeframeSelect?: (timeframe: any) => void\r\n onDateRangeSelect?: (timeframe: any) => void\r\n}) {\r\n const { chartLayoutModel } = useChartLayoutGlobalModelAsync()\r\n const chartModelUnwatched = React.useMemo(() => chartLayoutModel?.getAllCharts()[0] ?? null, [chartLayoutModel])\r\n const { favoriteTimeframes, toggleFavoriteTimeframe } = useFavoriteTimeframes(isPremium)\r\n const chartModel = useModelState(chartModelUnwatched, {\r\n watchProperties: ['timeframe', 'dateRange'],\r\n })\r\n const { instrument = Instrument.Stock } = chartModel?.quote() || {}\r\n const { isLoading } = useChartControls({\r\n chartModel,\r\n isInteractive: isDateRangeAvailable,\r\n })\r\n\r\n const {\r\n anchorDate,\r\n generateChartLayoutRouterPath,\r\n timeframeGroupsWithHref,\r\n dateRangeGroupsWithHref,\r\n isFetching,\r\n handleCustomDateRangeValidation,\r\n } = useChartModelCustomDateRangeValues({ chartModel, isPremium })\r\n const { onDialogSubmit, customDateRangeDialogState, handleDateRangeSelect, getDateRangeTimeframe } =\r\n useCustomDateRangeDialog({\r\n instrument,\r\n anchorDate,\r\n pathGenerator: generateChartLayoutRouterPath,\r\n })\r\n\r\n const dateRangeGroups = dateRangeGroupsWithHref({ isPremium, customRange: chartModel?.dateRange, instrument })\r\n const timeFrameGroups = timeframeGroupsWithHref(isPremium)\r\n\r\n async function handleCustomRangeSubmit(values: { dateRange: string | null }) {\r\n const dateRangeTimeframe = values.dateRange\r\n ? getDateRangeTimeframe(values.dateRange)\r\n : { value: '', timeframe: chartModel!.timeframe }\r\n\r\n if (dateRangeTimeframe === null) {\r\n return\r\n } else if (dateRangeTimeframe.value) {\r\n const isValid = await handleCustomDateRangeValidation(dateRangeTimeframe)\r\n if (!isValid) {\r\n return\r\n }\r\n }\r\n\r\n onDialogSubmit(dateRangeTimeframe, onDateRangeSelect)\r\n }\r\n\r\n return (\r\n <>\r\n {\r\n handleDateRangeSelect(value)\r\n onDateRangeSelect?.(value)\r\n }}\r\n onCustomDateRangeClick={() => {\r\n if (isPremium) customDateRangeDialogState.show()\r\n }}\r\n onTimeframeSelect={onTimeframeSelect}\r\n onFavoriteTimeframeToggle={({ value }: { value: string }) => {\r\n toggleFavoriteTimeframe(value as TIMEFRAME)\r\n }}\r\n isDateRangeAvailable={isDateRangeAvailable}\r\n containerElement={document.body}\r\n className={className}\r\n isFavoritesEnabled={isPremium}\r\n isScrollIntoViewEnabled={isScrollIntoViewEnabled}\r\n />\r\n\r\n {chartModel && (\r\n \r\n )}\r\n \r\n )\r\n}\r\n\r\nexport const StockDetailTimeframeBar = withSuspense(StockDetailTimeframeBarRaw)\r\n","import { ChartConfigChartPane, Position, RootChartConfigObject } from '../../types/shared'\r\nimport { ChartElementType, IndicatorType, OverlayType, PANE_HEIGHT_DEFAULT, ScaleType } from '../constants/common'\r\n\r\nfunction hasPaneWithCOTCode(panes: ChartConfigChartPane[], code: string) {\r\n return panes.some(({ elements }) =>\r\n elements.some((element) => element.type === IndicatorType.Cot && element.code === code)\r\n )\r\n}\r\nfunction pushIndicators(\r\n panes: ChartConfigChartPane[],\r\n indicator: { name: string; parameters: string },\r\n options?: { COTs?: string[] }\r\n) {\r\n if (indicator.name === 'cot') {\r\n const cotKeys = options?.COTs ?? []\r\n if (cotKeys.length === 0) {\r\n cotKeys.push('')\r\n }\r\n cotKeys.forEach(function (code: string) {\r\n if (!hasPaneWithCOTCode(panes, code)) {\r\n panes.push({\r\n height: PANE_HEIGHT_DEFAULT.indicator,\r\n elements: [\r\n {\r\n type: IndicatorType.Cot,\r\n code,\r\n },\r\n ],\r\n })\r\n }\r\n })\r\n } else {\r\n panes.push({\r\n height: PANE_HEIGHT_DEFAULT.indicator,\r\n elements: [\r\n {\r\n type: ('indicators/' + indicator.name) as IndicatorType,\r\n period: indicator.parameters,\r\n },\r\n ],\r\n })\r\n }\r\n}\r\n\r\nfunction getChartTypeByTaConfigStyle(style: string) {\r\n const chartTypeMap = {\r\n candlestick: ChartElementType.CandleStick,\r\n heikinashi: ChartElementType.HeikinAshi,\r\n hollowcandlestick: ChartElementType.HollowCandleStick,\r\n line: ChartElementType.LineChart,\r\n ohlc: ChartElementType.OhlcChart,\r\n }\r\n return chartTypeMap[style as keyof typeof chartTypeMap]\r\n}\r\n\r\nfunction getChartScaleByTaConfigScale(scale: string | undefined) {\r\n const chartScaleMap = {\r\n linear: ScaleType.Linear,\r\n percentage: ScaleType.Percentage,\r\n logarithmic: ScaleType.Logarithmic,\r\n }\r\n return chartScaleMap[scale as keyof typeof chartScaleMap] ?? ScaleType.Linear\r\n}\r\n\r\n/*\r\n * Merges chartConfig (in \"chart\" format) with taConfig (in format that TA is preserved in DB)\r\n */\r\nexport const mergeChartAndTAConfig = function convertTA(\r\n chartConfig: RootChartConfigObject,\r\n taConfig: TaConfigObject,\r\n options?: { COTs: string[] }\r\n) {\r\n const panes = chartConfig.charts[0].panes\r\n const chart = chartConfig.charts[0]\r\n\r\n chart.scale = getChartScaleByTaConfigScale(taConfig.scale)\r\n\r\n taConfig.indicators\r\n .filter((indicator) => indicator.position === Position.Above)\r\n .forEach((indicator) => {\r\n pushIndicators(panes, indicator, options)\r\n })\r\n\r\n const overlays = taConfig.overlays.map(function (overlay) {\r\n return {\r\n type: ('overlays/' + overlay.name) as OverlayType,\r\n period: overlay.parameters ?? '',\r\n color: overlay.color ?? '',\r\n }\r\n })\r\n panes.push({\r\n height: PANE_HEIGHT_DEFAULT.chart,\r\n elements: [\r\n {\r\n type: getChartTypeByTaConfigStyle(taConfig.style),\r\n overlays: overlays,\r\n },\r\n ],\r\n })\r\n\r\n taConfig.indicators\r\n .filter((indicator) => indicator.position === Position.Below)\r\n .forEach((indicator) => {\r\n pushIndicators(panes, indicator, options)\r\n })\r\n\r\n chartConfig.height = chart.height = PANE_HEIGHT_DEFAULT.chart + (panes.length - 1) * PANE_HEIGHT_DEFAULT.indicator\r\n}\r\n\r\nexport const getPanes = function getPanes(taConfig: TaConfigObject) {\r\n const options = {}\r\n const panes: ChartConfigChartPane[] = []\r\n\r\n taConfig.indicators\r\n .filter((indicator) => indicator.position === Position.Above)\r\n .forEach((indicator) => {\r\n pushIndicators(panes, indicator, options)\r\n })\r\n\r\n const overlays = taConfig.overlays.map(function (overlay) {\r\n return {\r\n type: ('overlays/' + overlay.name) as OverlayType,\r\n period: overlay.parameters ?? '',\r\n color: overlay.color ?? '',\r\n }\r\n })\r\n panes.push({\r\n height: PANE_HEIGHT_DEFAULT.chart,\r\n elements: [\r\n {\r\n type: getChartTypeByTaConfigStyle(taConfig.style),\r\n overlays: overlays,\r\n },\r\n ],\r\n })\r\n\r\n taConfig.indicators\r\n .filter((indicator) => indicator.position === Position.Below)\r\n .forEach((indicator) => {\r\n pushIndicators(panes, indicator, options)\r\n })\r\n\r\n return panes\r\n}\r\n","export * from 'finviz-charts/app/lib-export'\r\n\r\nexport enum SettingsTab {\r\n Chart = 'chart',\r\n Colors = 'colors',\r\n}\r\n\r\nexport enum SidebarDirection {\r\n vertical,\r\n horizontal,\r\n}\r\n","export const createAlertAsyncModule = {\r\n importFn: () => import(/* webpackChunkName: \"create-alert\" */ './module-entry'),\r\n cacheKey: 'create-alert',\r\n}\r\n","export const saveToPortfolioAsyncModule = {\r\n importFn: () => import(/* webpackChunkName: \"save-to-portfolio\" */ './module-entry'),\r\n cacheKey: 'save-to-portfolio',\r\n}\r\n","export enum AdsProvider {\r\n None,\r\n InvestingChannel,\r\n Freestar,\r\n}\r\n\r\nexport function getAdsProvider() {\r\n if (FinvizSettings.hasUserPremium) return AdsProvider.None\r\n\r\n if (FinvizSettings.adsProvider === 2) {\r\n return AdsProvider.Freestar\r\n }\r\n\r\n return AdsProvider.InvestingChannel\r\n}\r\n\r\n/**\r\n * Tracks virtual page views to google analytics and freestar\r\n */\r\nexport function trackPageView(props: { pathname?: string; query?: string; freestarPageView?: boolean }) {\r\n const { pathname = window.location.pathname, query = window.location.search, freestarPageView = true } = props\r\n\r\n window.gtag?.('set', 'page_path', `${pathname}${query.length ? '?' : ''}${query.replace(/^\\?/, '')}`)\r\n window.gtag?.('event', 'page_view')\r\n\r\n if (freestarPageView && getAdsProvider() === AdsProvider.Freestar) {\r\n window.freestar?.queue.push(() => freestar.trackPageview())\r\n }\r\n}\r\n","export const portfolioWatchlistTableAsyncModule = {\r\n importFn: () => import(/* webpackChunkName: \"portfolio-watchlist-table\" */ './PortfolioWatchlistTable'),\r\n cacheKey: 'portfolio-watchlist-table',\r\n}\r\n","import logo from './app/shared/assets/logo.png'\r\nimport logo_light from './app/shared/assets/logo_light.png'\r\n\r\nexport * from './main/components'\r\n\r\nexport { getSanitizedTicker } from './app/shared/ticker-sanitizer'\r\nexport * from './app/queryString'\r\nexport * from './main/modules/portfolio/types'\r\n\r\nexport { getFormattedDateString } from './app/header/utils'\r\nexport { decodeQueryString, encodeQueryString } from './app/queryString'\r\nexport { createAlertAsyncModule } from './app/quote/create-alert/async-modules'\r\nexport { saveToPortfolioAsyncModule } from './app/quote/save-to-portfolio/async-modules'\r\nexport { formatDateToStringUS } from './app/shared/utils'\r\nexport { portfolioWatchlistTableAsyncModule } from './main/components/portfolio/async-modules'\r\nexport { useTrackPageView } from './main/hooks/use-track-pageview'\r\nexport {\r\n useAsyncModule,\r\n withSuspense,\r\n type ControlledModuleConfig,\r\n type SuspenseModuleConfig,\r\n} from './main/services/async-modules-utils'\r\nexport { importWithRetry } from './main/services/import-with-retry'\r\nexport * as localStorage from './main/services/local-storage'\r\nexport { waitForPreviousPromise } from './main/services/wait-for-previous-promise'\r\nexport { setCookieRequest } from './main/services/api'\r\n\r\nexport const assets = { logo, logo_light }\r\n","import classnames from 'classnames'\r\nimport { ForwardedRef, HTMLProps, PropsWithChildren, ReactNode, forwardRef } from 'react'\r\n\r\nimport { Icon } from './icon'\r\n\r\nexport enum ColorVariant {\r\n violet = 'violet',\r\n emerald = 'emerald',\r\n orange = 'orange',\r\n teal = 'teal',\r\n pink = 'pink',\r\n lime = 'lime',\r\n purple = 'purple',\r\n green = 'green',\r\n yellow = 'yellow',\r\n blue = 'blue',\r\n red = 'red',\r\n gray = 'gray',\r\n default = 'default',\r\n dark = 'dark',\r\n}\r\n\r\nexport enum CheckboxSize {\r\n none = '', // Do not set fixed size\r\n small = 'min-h-6 text-2xs', // 24px\r\n regular = 'min-h-7 text-sm', // 28px\r\n}\r\nexport type CheckboxSizeType = keyof typeof CheckboxSize\r\n\r\ninterface CheckboxProps extends Omit, 'label' | 'size'> {\r\n /**\r\n * Text that gets displayed on the right side of the checkbox\r\n */\r\n label?: ReactNode\r\n\r\n checked: boolean\r\n\r\n /**\r\n * Size of the checkbox\r\n *\r\n * @default \"regular\"\r\n */\r\n size?: CheckboxSizeType\r\n\r\n /**\r\n * Color of the checkbox\r\n *\r\n * @default \"default\"\r\n */\r\n color?: ColorVariant\r\n}\r\n\r\nfunction CheckboxComponent(\r\n {\r\n className,\r\n label,\r\n size = 'regular',\r\n color = ColorVariant.default,\r\n children,\r\n ...props\r\n }: PropsWithChildren,\r\n ref: ForwardedRef\r\n) {\r\n const checked = props.checked ?? props.defaultChecked\r\n\r\n return (\r\n \r\n
\r\n \r\n {checked && (\r\n \r\n )}\r\n
\r\n {label ?? children}\r\n \r\n )\r\n}\r\n\r\nexport const Checkbox = forwardRef(CheckboxComponent)\r\n","import classnames from 'classnames'\r\nimport { HTMLProps, PropsWithChildren, memo, useCallback, useLayoutEffect, useRef, useState } from 'react'\r\n\r\nexport interface Interaction {\r\n left: number\r\n top: number\r\n}\r\n\r\n/**\r\n * Clamp value between two bounds\r\n */\r\nfunction clamp(num: number, min = 0, max = 1) {\r\n return num > max ? max : num < min ? min : num\r\n}\r\n\r\n/**\r\n * Check if an event was triggered by touch\r\n */\r\nfunction isTouch(event: MouseEvent | TouchEvent): event is TouchEvent {\r\n return 'touches' in event\r\n}\r\n\r\n/**\r\n * Returns a relative position of the pointer inside the node's bounding box\r\n */\r\nfunction getRelativePosition(node: HTMLDivElement, event: MouseEvent | TouchEvent): Interaction {\r\n const rect = node.getBoundingClientRect()\r\n\r\n // Get user's pointer position from `touches` array if it's a `TouchEvent`\r\n const pointer = isTouch(event) ? event.touches[0] : (event as MouseEvent)\r\n\r\n return {\r\n left: clamp((pointer.pageX - (rect.left + window.pageXOffset)) / rect.width),\r\n top: clamp((pointer.pageY - (rect.top + window.pageYOffset)) / rect.height),\r\n }\r\n}\r\n\r\n/**\r\n * Browsers introduced an intervention, making touch events passive by default.\r\n * This workaround removes `preventDefault` call from the touch handlers.\r\n * @see https://github.com/facebook/react/issues/19651\r\n */\r\nfunction preventDefaultMove(event: MouseEvent | TouchEvent) {\r\n !isTouch(event) && event.preventDefault()\r\n}\r\n\r\ninterface Props {\r\n onMove: (interaction: Interaction) => void\r\n onKey: (offset: Interaction) => void\r\n}\r\n\r\nfunction DraggablePickerComponent({\r\n onMove,\r\n onKey,\r\n className,\r\n ...props\r\n}: PropsWithChildren & HTMLProps) {\r\n const container = useRef(null)\r\n const hasTouched = useRef(false)\r\n const [isDragging, setDragging] = useState(false)\r\n\r\n /**\r\n * Prevent mobile browsers from handling mouse events (conflicting with touch ones).\r\n * If we detected a touch interaction before, we prefer reacting to touch events only.\r\n */\r\n const isValid = useRef((event: MouseEvent | TouchEvent): boolean => {\r\n if (hasTouched.current && !isTouch(event)) return false\r\n if (!hasTouched.current) hasTouched.current = isTouch(event)\r\n return true\r\n })\r\n\r\n const handleMove = useCallback(\r\n (event: MouseEvent | TouchEvent) => {\r\n preventDefaultMove(event)\r\n\r\n // If user moves the pointer outside of the window or iframe bounds and release it there,\r\n // `mouseup`/`touchend` won't be fired. In order to stop the picker from following the cursor\r\n // after the user has moved the mouse/finger back to the document, we check `event.buttons`\r\n // and `event.touches`. It allows us to detect that the user is just moving his pointer\r\n // without pressing it down\r\n const isDown = isTouch(event) ? event.touches.length > 0 : event.buttons > 0\r\n\r\n if (isDown && container.current) {\r\n onMove(getRelativePosition(container.current, event))\r\n } else {\r\n setDragging(false)\r\n }\r\n },\r\n [onMove]\r\n )\r\n\r\n const handleMoveStart = useCallback(\r\n ({ nativeEvent }: React.MouseEvent | React.TouchEvent) => {\r\n preventDefaultMove(nativeEvent)\r\n\r\n if (!isValid.current(nativeEvent)) return\r\n\r\n // The node/ref must actually exist when user start an interaction.\r\n // We won't suppress the ESLint warning though, as it should probably be something to be aware of.\r\n onMove(getRelativePosition(container.current!, nativeEvent))\r\n setDragging(true)\r\n },\r\n [onMove]\r\n )\r\n\r\n const handleKeyDown = useCallback(\r\n (event: React.KeyboardEvent) => {\r\n const keyCode = event.which || event.keyCode\r\n\r\n // Ignore all keys except arrow ones\r\n if (keyCode < 37 || keyCode > 40) return\r\n // Do not scroll page by arrow keys when document is focused on the element\r\n event.preventDefault()\r\n // Send relative offset to the parent component.\r\n // We use codes (37←, 38↑, 39→, 40↓) instead of keys ('ArrowRight', 'ArrowDown', etc)\r\n // to reduce the size of the library\r\n onKey({\r\n left: keyCode === 39 ? 0.05 : keyCode === 37 ? -0.05 : 0,\r\n top: keyCode === 40 ? 0.05 : keyCode === 38 ? -0.05 : 0,\r\n })\r\n },\r\n [onKey]\r\n )\r\n\r\n const handleMoveEnd = useCallback(() => setDragging(false), [])\r\n\r\n const toggleDocumentEvents = useCallback(\r\n (state: boolean) => {\r\n // add or remove additional pointer event listeners\r\n const toggleEvent = state ? window.addEventListener : window.removeEventListener\r\n toggleEvent(hasTouched.current ? 'touchmove' : 'mousemove', handleMove)\r\n toggleEvent(hasTouched.current ? 'touchend' : 'mouseup', handleMoveEnd)\r\n },\r\n [handleMove, handleMoveEnd]\r\n )\r\n\r\n useLayoutEffect(() => {\r\n toggleDocumentEvents(isDragging)\r\n return () => {\r\n isDragging && toggleDocumentEvents(false)\r\n }\r\n }, [isDragging, toggleDocumentEvents])\r\n\r\n return (\r\n \r\n )\r\n}\r\n\r\nexport const DraggablePicker = memo(DraggablePickerComponent)\r\n","interface PointerProps {\r\n className?: string\r\n top?: number\r\n left: number\r\n color: string\r\n}\r\n\r\nexport function Pointer({ color, left, top = 0.5 }: PointerProps) {\r\n return (\r\n \r\n
\r\n
\r\n )\r\n}\r\n","/**\r\n * Keep this file in sync with `app/utils/colors.ts` in charts repo\r\n * */\r\n\r\nexport interface RGBA {\r\n r: number\r\n g: number\r\n b: number\r\n a: number\r\n}\r\n\r\nexport interface HSVA {\r\n h: number\r\n s: number\r\n v: number\r\n a: number\r\n}\r\n\r\nexport interface HSLA {\r\n h: number\r\n s: number\r\n l: number\r\n a: number\r\n}\r\n\r\n/**\r\n * Convert Hex string to RGBA object.\r\n * @see https://css-tricks.com/converting-color-spaces-in-javascript/\r\n *\r\n * Input: color in hex3, hex4, hex6 or hex8 format (#fff)\r\n *\r\n * Output: { r: [0,255], g: [0,255], b: [0,255], a: [0,1]}\r\n */\r\nexport function hexStringToRGBA(hexString: string): RGBA {\r\n const hexColor = removeHashSymbol(hexString)\r\n let r: string | number = 0\r\n let g: string | number = 0\r\n let b: string | number = 0\r\n let a: string | number = 255\r\n\r\n // 3 digits\r\n if (hexColor.length === 3 || hexColor.length === 4) {\r\n r = '0x' + hexColor[0] + hexColor[0]\r\n g = '0x' + hexColor[1] + hexColor[1]\r\n b = '0x' + hexColor[2] + hexColor[2]\r\n // Get channel if defined\r\n a = hexColor.length === 4 ? '0x' + hexColor[3] + hexColor[3] : a\r\n\r\n // 6 digits\r\n } else if (hexColor.length === 6 || hexColor.length === 8) {\r\n r = '0x' + hexColor[0] + hexColor[1]\r\n g = '0x' + hexColor[2] + hexColor[3]\r\n b = '0x' + hexColor[4] + hexColor[5]\r\n // Get channel if defined\r\n a = hexColor.length === 8 ? '0x' + hexColor[6] + hexColor[7] : a\r\n }\r\n\r\n return { r: Number(r), g: Number(g), b: Number(b), a: Math.min(Math.round((Number(a) / 255) * 100) / 100, 1) }\r\n}\r\n\r\n/**\r\n * Convert HEX string to HSVA color representation.\r\n *\r\n * Input: color in hex3, hex4, hex6 or hex8 format (#fff)\r\n *\r\n * Output: { h: [0,360], s: [0,1], v: [0,1], a: [0,1]}\r\n */\r\nexport function hexStringToHSVA(hexString: string) {\r\n return rgbaToHSVA(hexStringToRGBA(hexString))\r\n}\r\n\r\n/**\r\n * Convert HEX string to HSLA color representation.\r\n *\r\n * Input: color in hex3, hex4, hex6 or hex8 format (#fff)\r\n *\r\n * Output: { h: [0,360], s: [0,1], l: [0,1], a: [0,1]}\r\n */\r\nexport function hexStringToHSLA(hexString: string) {\r\n return rgbaToHSLA(hexStringToRGBA(hexString))\r\n}\r\n\r\n/**\r\n * Convert alpha value to hex value\r\n *\r\n * Input: [0,1]\r\n *\r\n * Output: alpha in HEX format\r\n */\r\nexport function alphaToHex(alpha: number) {\r\n return Math.max(Math.min(Math.round(alpha * 255), 255), 0)\r\n .toString(16)\r\n .padStart(2, '0')\r\n}\r\n\r\n/**\r\n * Convert RGBA color to HEX string.\r\n *\r\n * Input: { r: [0,255], g: [0,255], b: [0,255], a: [0,1]}\r\n *\r\n * Output: color in hex6 or hex8 depending on whether or not alpha is enabled\r\n */\r\nexport function rgbaToHexString(color: RGBA, alpha = false) {\r\n const r = color.r.toString(16)\r\n const g = color.g.toString(16)\r\n const b = color.b.toString(16)\r\n const hexString = '#' + r.padStart(2, '0') + g.padStart(2, '0') + b.padStart(2, '0')\r\n\r\n if (!alpha || color.a === 1) {\r\n return hexString\r\n }\r\n\r\n return `${hexString}${alphaToHex(color.a)}`\r\n}\r\n\r\n/**\r\n * Convert HSVA object to HEX string\r\n *\r\n * @see https://css-tricks.com/converting-color-spaces-in-javascript/\r\n *\r\n * Input: { h: [0,360], s: [0,1], v: [0,1], a: [0,1]}\r\n *\r\n * Output: { r: [0,255], g: [0,255], b: [0,255], a: [0,1]}\r\n */\r\nexport function hsvaToHEXString(color: HSVA, alpha = false) {\r\n const rgbaColor = hsvaToRGBA(color)\r\n\r\n return rgbaToHexString(rgbaColor, alpha)\r\n}\r\n\r\n/**\r\n * Convert HSLA object to HEX string\r\n *\r\n * @see https://css-tricks.com/converting-color-spaces-in-javascript/\r\n *\r\n * Input: { h: [0,360], s: [0,1], l: [0,1], a: [0,1]}\r\n *\r\n * Output: { r: [0,255], g: [0,255], b: [0,255], a: [0,1]}\r\n */\r\nexport function hslaToHexString(color: HSLA, alpha = false) {\r\n const rgbaColor = hslaToRGBA(color)\r\n\r\n return rgbaToHexString(rgbaColor, alpha)\r\n}\r\n\r\n/**\r\n * Convert RGBA color to HSVA\r\n * @see https://stackoverflow.com/a/54070620/6662683\r\n *\r\n * Input: { r: [0,255], g: [0,255], b: [0,255], a: [0,1]}\r\n *\r\n * Output: { h: [0,360], s: [0,1], v: [0,1], a: [0,1]}\r\n */\r\nexport function rgbaToHSVA(color: RGBA): HSVA {\r\n const r = color.r / 255\r\n const g = color.g / 255\r\n const b = color.b / 255\r\n\r\n const v = Math.max(r, g, b)\r\n const c = v - Math.min(r, g, b)\r\n const h = c && (v === r ? (g - b) / c : v === g ? 2 + (b - r) / c : 4 + (r - g) / c)\r\n\r\n return {\r\n h: 60 * (h < 0 ? h + 6 : h),\r\n s: v ? c / v : 0,\r\n v: v,\r\n a: color.a,\r\n }\r\n}\r\n\r\n/**\r\n * Convert RGBA to HSLA\r\n * @see https://stackoverflow.com/a/54071699/6662683\r\n *\r\n * Input: { r: [0,255], g: [0,255], b: [0,255], a: [0,1]}\r\n *\r\n * Output: { h: [0,360], s: [0,1], l: [0,1], a: [0,1]}\r\n */\r\nexport function rgbaToHSLA(color: RGBA): HSLA {\r\n const r = color.r / 255\r\n const g = color.g / 255\r\n const b = color.b / 255\r\n\r\n const v = Math.max(r, g, b)\r\n const c = v - Math.min(r, g, b)\r\n const f = 1 - Math.abs(v + v - c - 1)\r\n const h = c && (v === r ? (g - b) / c : v === g ? 2 + (b - r) / c : 4 + (r - g) / c)\r\n\r\n return {\r\n h: 60 * (h < 0 ? h + 6 : h),\r\n s: f ? c / f : 0,\r\n l: (v + v - c) / 2,\r\n a: color.a,\r\n }\r\n}\r\n\r\n/**\r\n * Convert HSVA color to RGBA\r\n * @see https://stackoverflow.com/a/54024653/6662683\r\n *\r\n * Input: { h: [0,360], s: [0,1], v: [0,1], a: [0,1]}\r\n *\r\n * Output: { r: [0,255], g: [0,255], b: [0,255], a: [0,1]}\r\n */\r\nexport function hsvaToRGBA(color: HSVA): RGBA {\r\n const f = (n: number, k = (n + color.h / 60) % 6) => color.v - color.v * color.s * Math.max(Math.min(k, 4 - k, 1), 0)\r\n\r\n return {\r\n r: Math.round(f(5) * 255),\r\n g: Math.round(f(3) * 255),\r\n b: Math.round(f(1) * 255),\r\n a: Math.round(color.a * 100) / 100,\r\n }\r\n}\r\n\r\n/**\r\n * Convert HSLA color to RGBA\r\n * @see https://stackoverflow.com/a/54014428/6662683\r\n *\r\n * Input: { h: [0,360], s: [0,1], l: [0,1], a: [0,1]}\r\n *\r\n * Output: { r: [0,255], g: [0,255], b: [0,255], a: [0,1]}\r\n */\r\nexport function hslaToRGBA(color: HSLA): RGBA {\r\n const a = color.s * Math.min(color.l, 1 - color.l)\r\n const f = (n: number, k = (n + color.h / 30) % 12) => color.l - a * Math.max(Math.min(k - 3, 9 - k, 1), -1)\r\n\r\n return {\r\n r: Math.round(f(0) * 255),\r\n g: Math.round(f(8) * 255),\r\n b: Math.round(f(4) * 255),\r\n a: color.a,\r\n }\r\n}\r\n\r\n/**\r\n * Convert RGBA color to rgba() string\r\n *\r\n * Input: { r: [0,255], g: [0,255], b: [0,255], a: [0,1]}\r\n *\r\n * Output: rgba(r, g, b, a)\r\n */\r\nexport function rgbaToRGBAString(color: RGBA) {\r\n return `rgba(${color.r}, ${color.g}, ${color.b}, ${color.a})`\r\n}\r\n\r\n/**\r\n * Convert rgba() string to RGBA color\r\n *\r\n * Input: rgba(r, g, b, a)\r\n *\r\n * Output: { r: [0,255], g: [0,255], b: [0,255], a: [0,1]}\r\n */\r\nexport function rgbaStringToObject(color: string) {\r\n const colorParts = /^rgba?\\(([0-9]{1,3})[ ,]+([0-9]{1,3})[ ,]+([0-9]{1,3})[ ,]*([01].?[0-9]*)?\\)$/.exec(color)\r\n const [red, green, blue, alpha = '1'] = colorParts?.slice(1) || [0, 0, 0, 1].map(String)\r\n return {\r\n r: Number.parseInt(red),\r\n g: Number.parseInt(green),\r\n b: Number.parseInt(blue),\r\n a: Number.parseFloat(alpha),\r\n }\r\n}\r\n\r\n/**\r\n * Convert HSLA color to hsla() string\r\n *\r\n * Input: { h: [0,360], s: [0,1], l: [0,1], a: [0,1]}\r\n *\r\n * Output: hsla(h, s, l, a)\r\n */\r\nexport function hslaToHSLAString(color: HSLA) {\r\n return `hsla(${Math.round(color.h)}, ${Math.round(color.s * 10000) / 100}%, ${Math.round(color.l * 10000) / 100}%, ${\r\n color.a\r\n })`\r\n}\r\n\r\nexport function removeHashSymbol(strColor: string) {\r\n return strColor.replace(/#/g, '')\r\n}\r\n\r\n/**\r\n * Check if the param is a valid color by setting it as style\r\n */\r\nexport function isValidColor(strColor: string) {\r\n const isRgb = strColor.startsWith('rgba')\r\n const s = new Option().style\r\n\r\n s.color = isRgb ? strColor : `#${removeHashSymbol(strColor)}`\r\n\r\n return s.color !== ''\r\n}\r\n\r\n/**\r\n * Normalize color to be a hex value\r\n */\r\nexport function convertColorToHEX(strColor: string) {\r\n const isRgb = getIsRgb(strColor)\r\n\r\n if (isRgb) {\r\n return rgbaToHexString(rgbaStringToObject(strColor), true)\r\n }\r\n\r\n return strColor\r\n}\r\n\r\n/**\r\n * Returns true if color is rgb or rgba\r\n */\r\nexport function getIsRgb(strColor: string, isAlphaAllowed = true) {\r\n const rgbKeys = ['rgb']\r\n if (isAlphaAllowed) {\r\n rgbKeys.push('rgba')\r\n }\r\n return rgbKeys.some((startsWith) => strColor.startsWith(startsWith))\r\n}\r\n\r\n/**\r\n * Convert any color format to HSVA (internal color picker representation)\r\n */\r\nexport function getHSVAFromColor(strColor: string) {\r\n if (getIsRgb(strColor)) {\r\n return rgbaToHSVA(rgbaStringToObject(strColor))\r\n }\r\n\r\n return hexStringToHSVA(strColor)\r\n}\r\n\r\n/**\r\n * Stringify HSVA color representation into a output format\r\n */\r\nexport function stringifyHSVAColor(color: HSVA, output: 'rgba' | 'hex', canSelectAlpha?: boolean) {\r\n switch (output) {\r\n case 'rgba':\r\n return rgbaToRGBAString(hsvaToRGBA(color))\r\n default:\r\n return hsvaToHEXString(color, canSelectAlpha)\r\n }\r\n}\r\n\r\n/**\r\n * Get luma value from RGBA color using the Rec. 709 coefficients\r\n * @see https://en.wikipedia.org/wiki/Luma_%28video%29\r\n *\r\n * If luma is >= 165 the foreground color should be dark\r\n */\r\nexport function getLumaFromRGBA(color: RGBA) {\r\n return 0.2126 * color.r + 0.7152 * color.g + 0.0722 * color.b\r\n}\r\n\r\n/**\r\n * Checks if luma is >= 165 or alpha < 0.3\r\n */\r\nexport function getIsColorTooLightOrTransparent(color: RGBA) {\r\n return getLumaFromRGBA(color) >= 165 || color.a < 0.5\r\n}\r\n\r\n/**\r\n * Set specific alpha for a hex color\r\n */\r\nexport function getHEXWithSpecificAplha(color: string, alpha = 1) {\r\n const rgbaColor = hexStringToRGBA(color)\r\n return rgbaToHexString({ ...rgbaColor, a: alpha }, true)\r\n}\r\n\r\n/**\r\n * Get rgba from valid color string\r\n */\r\nexport function getRGBAValueFromValidColorString(value: string) {\r\n if (getIsRgb(value)) return rgbaToRGBAString(rgbaStringToObject(value))\r\n return rgbaToRGBAString(hexStringToRGBA(value))\r\n}\r\n","import { useCallback, useMemo } from 'react'\r\n\r\nimport { DraggablePicker, Interaction } from './draggable'\r\nimport { Pointer } from './pointer'\r\nimport { HSVA, hsvaToHEXString } from './util'\r\n\r\ninterface LightnessProps {\r\n color: HSVA\r\n onChange: (color: HSVA) => void\r\n}\r\n\r\nexport function Alpha({ color, onChange }: LightnessProps) {\r\n const changeLightness = useCallback((pos: Interaction) => onChange({ ...color, a: 1 - pos.left }), [onChange, color])\r\n\r\n const gradientPreview = useMemo(() => {\r\n const gradientFrom = hsvaToHEXString({ ...color, a: 1 })\r\n const gradientTo = hsvaToHEXString({ ...color, a: 0 }, true)\r\n\r\n return `linear-gradient(90deg, ${gradientFrom}, ${gradientTo})`\r\n // Don’t recalculate when alpha changes\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n }, [color.h, color.s, color.v])\r\n\r\n return (\r\n \r\n
\r\n
\r\n
\r\n \r\n \r\n )\r\n}\r\n","import { Icon } from '../icon'\r\nimport { HSVA, hexStringToHSVA } from './util'\r\n\r\nconst DEFAULT_COLORS = [\r\n { title: 'Rose', value: '#f43f5e' },\r\n { title: 'Pink', value: '#db2777' },\r\n { title: 'Fuchsia', value: '#c026d3' },\r\n { title: 'Purple', value: '#9333ea' },\r\n { title: 'Violet', value: '#7c3aed' },\r\n { title: 'Indigo', value: '#4f46e5' },\r\n { title: 'Blue', value: '#2563eb' },\r\n { title: 'Light Blue', value: '#0284c7' },\r\n { title: 'Cyan', value: '#0891b2' },\r\n { title: 'Teal', value: '#0d9488' },\r\n { title: 'Emerald', value: '#059669' },\r\n { title: 'Green', value: '#16a34a' },\r\n { title: 'Lime', value: '#65a30d' },\r\n { title: 'Yellow', value: '#eab308' },\r\n { title: 'Amber', value: '#d97706' },\r\n { title: 'Red', value: '#dc2626' },\r\n]\r\n\r\ninterface ColorItem {\r\n /**\r\n * Name of the color\r\n */\r\n title: string\r\n\r\n /**\r\n * Hex value\r\n */\r\n value: string\r\n}\r\n\r\ninterface ColorPaletteProps {\r\n /**\r\n * Current selected color in HEX format (supports HEX8 for alpha)\r\n */\r\n color: string\r\n\r\n /**\r\n * List of colors to display in the palette\r\n *\r\n * @default DEFAULT_COLORS\r\n */\r\n colors?: ColorItem[]\r\n\r\n /**\r\n * Callback when user picks a color\r\n */\r\n onChange: (color: string, originalColor: HSVA) => void\r\n}\r\n\r\nexport function ColorPalette({ color, colors = DEFAULT_COLORS, onChange }: ColorPaletteProps) {\r\n const lowerCaseColor = color.toLowerCase()\r\n\r\n return (\r\n
\r\n {colors.map((colorObj) => {\r\n const isSelected = lowerCaseColor.startsWith(colorObj.value)\r\n return (\r\n onChange(colorObj.value, hexStringToHSVA(colorObj.value))}\r\n >\r\n {isSelected && }\r\n
\r\n )\r\n })}\r\n
\r\n )\r\n}\r\n","import { useCallback, useMemo } from 'react'\r\n\r\nimport { DraggablePicker, Interaction } from './draggable'\r\nimport { Pointer } from './pointer'\r\nimport { HSVA, hsvaToHEXString } from './util'\r\n\r\ninterface HueSaturationProps {\r\n color: HSVA\r\n onChange: (color: HSVA) => void\r\n}\r\n\r\nfunction getPositionFromHSLA(color: HSVA) {\r\n return {\r\n left: color.h / 360,\r\n top: 1 - color.s,\r\n }\r\n}\r\n\r\nexport function HueSaturation({ color, onChange }: HueSaturationProps) {\r\n const position = useMemo(() => getPositionFromHSLA(color), [color])\r\n\r\n const colorPreview = useMemo(() => hsvaToHEXString({ h: color.h, s: color.s, v: 1, a: 1 }), [color.h, color.s])\r\n\r\n const changeSaturation = useCallback(\r\n (pos: Interaction) =>\r\n onChange({\r\n h: Math.round(pos.left * 360),\r\n s: 1 - pos.top,\r\n v: 1,\r\n a: color.a,\r\n }),\r\n [color.a, onChange]\r\n )\r\n\r\n return (\r\n \r\n
\r\n
\r\n
\r\n \r\n \r\n )\r\n}\r\n","import { useCallback, useMemo } from 'react'\r\n\r\nimport { DraggablePicker, Interaction } from './draggable'\r\nimport { Pointer } from './pointer'\r\nimport { HSVA, hsvaToHEXString } from './util'\r\n\r\ninterface LightnessProps {\r\n color: HSVA\r\n onChange: (color: HSVA) => void\r\n}\r\n\r\nexport function Lightness({ color, onChange }: LightnessProps) {\r\n const changeLightness = useCallback((pos: Interaction) => onChange({ ...color, v: 1 - pos.left }), [onChange, color])\r\n\r\n const colorPreview = useMemo(\r\n () => hsvaToHEXString({ h: color.h, s: color.s, v: color.v, a: 1 }),\r\n [color.h, color.s, color.v]\r\n )\r\n\r\n const gradientPreview = useMemo(() => {\r\n const gradientFrom = hsvaToHEXString({ h: color.h, s: color.s, v: 1, a: 1 })\r\n const gradientTo = hsvaToHEXString({ h: color.h, s: color.s, v: 0, a: 1 })\r\n\r\n return `linear-gradient(90deg, ${gradientFrom}, ${gradientTo})`\r\n }, [color.h, color.s])\r\n\r\n return (\r\n \r\n
\r\n \r\n \r\n )\r\n}\r\n","import classnames from 'classnames'\r\nimport React from 'react'\r\n\r\nimport { Icon, IconNameType, isValidIconName } from '../icon'\r\nimport { getIsColorTooLightOrTransparent, hexStringToRGBA } from './util'\r\n\r\ninterface ColorPreviewProps {\r\n /**\r\n * Name of an icon or JSX.Element\r\n */\r\n icon?: JSX.Element | IconNameType\r\n\r\n /**\r\n * One or more colors to show in the preview\r\n */\r\n color: string | string[]\r\n\r\n /**\r\n * Wrapper classname\r\n */\r\n className?: string\r\n}\r\n\r\nexport function ColorPreview({ icon, color, className }: ColorPreviewProps) {\r\n const colors = Array.isArray(color) ? color : [color]\r\n const isTooLight = getIsColorTooLightOrTransparent(hexStringToRGBA(colors[0]))\r\n return (\r\n \r\n {icon && (\r\n
\r\n {isValidIconName(icon) ? (\r\n \r\n ) : (\r\n icon\r\n )}\r\n
\r\n )}\r\n {colors.map((color, index) => (\r\n //   has to be there because of a bug on safari which ignores h-full when empty element\r\n
\r\n  \r\n
\r\n ))}\r\n
\r\n )\r\n}\r\n","import classnames from 'classnames'\r\nimport React, { ForwardedRef, useCallback, useEffect, useState } from 'react'\r\n\r\nimport { Input, InputComponentProps } from '../input'\r\nimport { ColorPreview } from './color-preview'\r\nimport { ColorPickerProps } from './picker'\r\nimport * as colorUtil from './util'\r\n\r\ninterface PickerInputProps extends Omit {\r\n color: ColorPickerProps['color']\r\n onChange: ColorPickerProps['onChange']\r\n\r\n /*\r\n * Is color preview square visible\r\n *\r\n * @default true\r\n * */\r\n hasColorPreview?: boolean\r\n}\r\nexport const PickerInput = React.forwardRef(\r\n (\r\n { color, inputClass, hasColorPreview = true, onChange, ...props }: PickerInputProps,\r\n ref: ForwardedRef\r\n ) => {\r\n const [colorInput, setColorInput] = useState(colorUtil.removeHashSymbol(color))\r\n const isRgba = colorUtil.getIsRgb(colorInput)\r\n\r\n useEffect(() => {\r\n setColorInput(colorUtil.removeHashSymbol(color))\r\n }, [color])\r\n\r\n const handleColorInputChange = useCallback(\r\n (event: React.KeyboardEvent) => {\r\n const value = colorUtil.removeHashSymbol(event.currentTarget.value)\r\n const isRgba = value.startsWith('rgba')\r\n const colorValue = isRgba ? value : `#${value}`\r\n\r\n setColorInput(value)\r\n if ((value.length >= 6 || (isRgba && value.length >= 16)) && colorUtil.isValidColor(colorValue)) {\r\n onChange(colorValue, colorUtil.hexStringToHSVA(colorValue))\r\n }\r\n },\r\n [onChange]\r\n )\r\n return (\r\n \r\n {hasColorPreview && (\r\n
\r\n \r\n
\r\n )}\r\n {!isRgba && #}\r\n
\r\n }\r\n onChange={handleColorInputChange}\r\n />\r\n )\r\n }\r\n)\r\n","import * as Ariakit from '@ariakit/react'\r\nimport classnames from 'classnames'\r\nimport React, { ReactNode, useCallback, useEffect, useRef, useState } from 'react'\r\n\r\nimport { isMobile } from '../../../app/shared/isMobile'\r\nimport { Button } from '../button'\r\nimport { Popover, PopoverTrigger, usePopoverState } from '../popover'\r\nimport { Alpha } from './alpha'\r\nimport { ColorPalette } from './color-palette'\r\nimport { HueSaturation } from './hue-saturation'\r\nimport { Lightness } from './lightness'\r\nimport { PickerInput } from './picker-input'\r\nimport * as colorUtil from './util'\r\n\r\nexport interface ColorPickerProps {\r\n /**\r\n * The selected color in HEX format (supports HEX8 for alpha)\r\n */\r\n color: string\r\n\r\n /**\r\n * Whether or not the user is able to select custom color\r\n *\r\n * @default true\r\n */\r\n canSelectCustom?: boolean\r\n\r\n /**\r\n * Whether or not the user is able to change alpha channel. Only applicable\r\n * when `canSelectCustom` is true\r\n *\r\n * @default true\r\n */\r\n canSelectAlpha?: boolean\r\n\r\n /**\r\n * Sets the output format for the color picker\r\n *\r\n * @default 'hex'\r\n */\r\n outputFormat?: 'hex' | 'rgba'\r\n\r\n /**\r\n * Callback when user changes color. Use the second parameter to do color space\r\n * conversions otherwise the color could differ due to rounding\r\n */\r\n onChange: (color: string, originalColor: colorUtil.HSVA) => void\r\n\r\n /**\r\n * Callback when user clicks on a palette item. Used to close popover\r\n */\r\n onPaletteItemClick?: () => void\r\n}\r\n\r\nexport function ColorPicker({\r\n color,\r\n canSelectCustom = true,\r\n canSelectAlpha = true,\r\n outputFormat = 'hex',\r\n onChange,\r\n onPaletteItemClick,\r\n}: ColorPickerProps) {\r\n const cachedColor = useRef(color)\r\n const [hsvaColor, setColor] = useState(colorUtil.getHSVAFromColor(color))\r\n const popover = Ariakit.usePopoverContext()\r\n const input = popover?.useState('disclosureElement')\r\n\r\n /**\r\n * Update state if the color from outside changed\r\n */\r\n useEffect(() => {\r\n const currentColor = colorUtil.removeHashSymbol(cachedColor.current)\r\n const newColor = colorUtil.removeHashSymbol(color)\r\n\r\n if (currentColor === newColor || !colorUtil.isValidColor(newColor)) return\r\n\r\n cachedColor.current = color\r\n setColor(colorUtil.getHSVAFromColor(color))\r\n }, [color])\r\n\r\n /**\r\n * Handle color change\r\n * 1. update cache so we can correctly check when outside color updates\r\n * 2. Update internal color representation\r\n * 3. call onChange with string color\r\n */\r\n const onChangeCallback = useCallback(\r\n (color: colorUtil.HSVA) => {\r\n const stringColor = colorUtil.stringifyHSVAColor(color, outputFormat, canSelectAlpha)\r\n cachedColor.current = stringColor\r\n onChange(stringColor, color)\r\n setColor(color)\r\n },\r\n [onChange, canSelectAlpha, outputFormat]\r\n )\r\n\r\n const onSetCustomCodeClick = useCallback(() => {\r\n const value = prompt('Enter a color code')?.trim()\r\n\r\n if (!value) return\r\n\r\n const isValid = colorUtil.isValidColor(value)\r\n\r\n if (!isValid) {\r\n return alert('The code is not a valid color')\r\n }\r\n\r\n onChangeCallback(colorUtil.getHSVAFromColor(value))\r\n }, [onChangeCallback])\r\n\r\n return (\r\n
\r\n {canSelectCustom && (\r\n <>\r\n {isMobile() && (\r\n \r\n )}\r\n \r\n \r\n\r\n {canSelectAlpha && }\r\n \r\n )}\r\n\r\n \r\n {\r\n input?.focus({ preventScroll: true })\r\n onPaletteItemClick?.()\r\n onChangeCallback({ ...orignalColor, a: hsvaColor.a })\r\n }}\r\n />\r\n
\r\n \r\n )\r\n}\r\n\r\ninterface InputColorPickerProps extends ColorPickerProps {\r\n /**\r\n * Label for the input\r\n */\r\n label?: ReactNode\r\n inputDataTestId?: string\r\n}\r\n\r\nexport function InputColorPicker({ label, inputDataTestId, onChange, ...props }: InputColorPickerProps) {\r\n const popoverState = usePopoverState()\r\n const canSelectCustom = props.canSelectCustom !== false\r\n const isMobileDevice = isMobile()\r\n\r\n return (\r\n <>\r\n \r\n }\r\n />\r\n \r\n \r\n {\r\n if (canSelectCustom) return\r\n popoverState.hide()\r\n }}\r\n />\r\n \r\n \r\n \r\n )\r\n}\r\n","import classnames from 'classnames'\r\nimport React from 'react'\r\n\r\nimport { isMobile } from '../../../app/shared/isMobile'\r\nimport { Button, ButtonComponentProps, ButtonRounding, ButtonSizeType } from '../button'\r\nimport { ButtonGroup } from '../button-group'\r\nimport { IconNameType } from '../icon'\r\nimport { Popover, PopoverTrigger, usePopoverState } from '../popover'\r\nimport { ColorPreview } from './color-preview'\r\nimport { ColorPicker, ColorPickerProps } from './picker'\r\nimport { PickerInput } from './picker-input'\r\nimport * as colorUtil from './util'\r\n\r\ninterface MultiColorPickerProps extends ColorPickerProps {\r\n /**\r\n * Label for color text input\r\n *\r\n * @default undefined\r\n */\r\n colorInputLabel?: string\r\n}\r\n\r\nexport function MultiColorPicker({\r\n colorInputLabel,\r\n onChange,\r\n canSelectCustom = true,\r\n ...props\r\n}: MultiColorPickerProps) {\r\n const isMobileDevice = isMobile()\r\n\r\n return (\r\n <>\r\n {canSelectCustom && !isMobileDevice && (\r\n
\r\n \r\n
\r\n )}\r\n \r\n {}} />\r\n \r\n \r\n )\r\n}\r\n\r\ninterface ColorTabButtonProps extends ButtonComponentProps {\r\n /*\r\n * Preview color\r\n * */\r\n color: string\r\n}\r\n\r\nexport function ColorTabButton({ color, children, ...props }: ColorTabButtonProps) {\r\n return (\r\n }\r\n {...props}\r\n >\r\n {children}\r\n \r\n )\r\n}\r\n\r\ntype ButtonColorProperties = { color: string; label: string }\r\n\r\ninterface ButtonColorPickerProps\r\n extends Omit {\r\n /**\r\n * Temporary prop to enable/disable multi picker funcionality,\r\n * in the future we'll only use secondaryColor prop to decide if the picker is multi picker or not\r\n *\r\n * @default undefined\r\n */\r\n isMultiPicker?: boolean\r\n\r\n /**\r\n * Button classname\r\n */\r\n className?: string\r\n\r\n /**\r\n * Array of objects with color and value\r\n */\r\n colors: ColorType[]\r\n\r\n /**\r\n * Color onchange callback\r\n */\r\n onChange: (colors: ColorType[], originalColor: colorUtil.HSVA) => void\r\n\r\n /**\r\n * Button size\r\n *\r\n * @default undefined\r\n */\r\n size?: ButtonSizeType\r\n /**\r\n * Label for color text input\r\n *\r\n * @default undefined\r\n */\r\n colorInputLabel?: string\r\n\r\n /**\r\n * Name of an icon or JSX.Element\r\n */\r\n icon?: JSX.Element | IconNameType\r\n\r\n /**\r\n * Identifier for e2e testing\r\n *\r\n * @default undefined\r\n */\r\n buttonPickerDataTestId?: string\r\n}\r\n\r\nexport function ButtonColorPicker({\r\n size,\r\n icon,\r\n colors,\r\n className,\r\n onChange,\r\n buttonPickerDataTestId,\r\n ...props\r\n}: ButtonColorPickerProps) {\r\n const popoverState = usePopoverState()\r\n const isOpen = popoverState.useState('open')\r\n const isMultiPicker = !!props.isMultiPicker && colors.length > 1\r\n const [activeColorIndex, setActiveColorIndex] = React.useState(0)\r\n const handleColorChange = React.useCallback(\r\n (color: string, originalColor: colorUtil.HSVA) => {\r\n onChange(\r\n colors.map((colorObject, index) => (index === activeColorIndex ? { ...colorObject, color } : colorObject)),\r\n originalColor\r\n )\r\n },\r\n [activeColorIndex, colors, onChange]\r\n )\r\n return (\r\n <>\r\n \r\n color)}\r\n className={classnames('h-full w-full', ButtonRounding.small)}\r\n />\r\n \r\n \r\n {isMultiPicker && (\r\n
\r\n \r\n {colors.map(({ color, label }, index) => (\r\n setActiveColorIndex(index)}\r\n >\r\n {label}\r\n \r\n ))}\r\n \r\n
\r\n )}\r\n \r\n
\r\n \r\n )\r\n}\r\n","import copy from 'copy-to-clipboard'\r\nimport React from 'react'\r\n\r\nimport { Button } from '../button'\r\nimport { InputProps, Textarea } from '../input'\r\n\r\ninterface Props extends Pick {\r\n className?: string\r\n text: string\r\n bottomLeftContent?: React.ReactNode\r\n}\r\n\r\nexport const CopyToClipboard: React.FC = ({ className, label, text, bottomLeftContent }) => {\r\n const [isCopied, setIsCopied] = React.useState(false)\r\n\r\n const handleCopyToClipboard = React.useCallback(() => {\r\n setIsCopied(true)\r\n copy(text)\r\n }, [text])\r\n\r\n React.useEffect(() => {\r\n let timeout: number\r\n const resetTimer = () => {\r\n if (!timeout) return\r\n clearTimeout(timeout)\r\n }\r\n if (isCopied) {\r\n resetTimer()\r\n timeout = window.setTimeout(() => {\r\n setIsCopied(false)\r\n }, 2000)\r\n }\r\n\r\n return () => {\r\n resetTimer()\r\n }\r\n }, [isCopied])\r\n\r\n return (\r\n
\r\n e.currentTarget.select()}\r\n inputClass=\"h-12\"\r\n data-testid=\"copy-to-clipboard-textarea\"\r\n value={text}\r\n />\r\n
\r\n {bottomLeftContent &&
{bottomLeftContent}
}\r\n \r\n {isCopied ? 'Copied' : 'Copy'}\r\n \r\n
\r\n
\r\n )\r\n}\r\n","import * as Ariakit from '@ariakit/react'\r\nimport classNames from 'classnames'\r\nimport * as React from 'react'\r\n\r\nimport { usePrevious } from '../../hooks/use-previous'\r\nimport { usePopoverPlacement } from '../../hooks/usePopoverPlacement'\r\nimport { blurWithoutScroll, focusWithoutScroll, preventDefault } from '../../util'\r\n\r\nenum DropdownRounding {\r\n none = '',\r\n regular = 'rounded-lg',\r\n}\r\n\r\nenum DropdownTheme {\r\n none = '',\r\n default = 'border border-primary bg-primary',\r\n}\r\n\r\ninterface StatelessDropdownProps\r\n extends Omit, 'ref'>,\r\n Pick {\r\n /**\r\n * Trigger button for the dropdown\r\n */\r\n trigger: JSX.Element | null\r\n\r\n /**\r\n * Disable interaction with other page elements when the dropdown is open\r\n *\r\n * @default true\r\n */\r\n modal?: boolean\r\n\r\n /**\r\n * When true, the dropdown will show when dropdown is hovered. Combine with\r\n * `backdrop={false}` to make the popover hide on mouse out\r\n */\r\n showOnHover?: boolean\r\n\r\n /**\r\n * Placement of the dropdown\r\n *\r\n */\r\n placement?: Ariakit.MenuProviderProps['placement']\r\n\r\n /**\r\n * Orientation in which the items are laid out. Changes which arrows control next/prev item\r\n *\r\n * @default vertical\r\n */\r\n orientation?: 'vertical' | 'horizontal'\r\n\r\n /**\r\n * Set rounding for the dropdown list\r\n *\r\n * @default regular\r\n */\r\n rounding?: keyof typeof DropdownRounding\r\n\r\n /**\r\n * Dropdown theme\r\n *\r\n * @default default\r\n */\r\n theme?: keyof typeof DropdownTheme\r\n\r\n /**\r\n * The amount of space between button and its popover\r\n *\r\n * @default 4\r\n */\r\n gutter?: number\r\n\r\n /**\r\n * Show backdrop on the dialog. Provide your own element if you want to add background or animation\r\n *\r\n */\r\n backdrop?: false | JSX.Element\r\n\r\n /**\r\n * Do not render the items when the popover is not visible\r\n *\r\n * @default true\r\n */\r\n unmountOnHide?: boolean\r\n\r\n /**\r\n * If true, the dropdown will overlay the trigger if necessary instead of going\r\n * out of bounds and overflowing\r\n */\r\n overlap?: boolean\r\n\r\n /**\r\n * Callback before the menu starts hiding. Event can be prevented which keeps the menu open\r\n * This callback isn’t called on backdrop click. Use `backdrop={
}` to react on backdrop clicks\r\n */\r\n onClose?: (ev: Event) => void\r\n\r\n /**\r\n * Used to provide virtual anchor, useful for context menu, etc\r\n */\r\n getAnchorRect?: () => { x: number; y: number }\r\n\r\n /**\r\n * Set which element gets focus when the dialog visibility changes. If `false`, the focus stays on the previous element.\r\n * Defaults to focusing without scrolling the page or keeping the focus on trigger if input-like.\r\n */\r\n autoFocusOnShow?: false | ((element: HTMLElement) => boolean)\r\n\r\n /**\r\n * Set which element gets focus when the dialog visibility changes. If `false`, the focus stays on the previous element.\r\n * Defaults to focusing without scrolling the page or keeping the focus on trigger if input-like.\r\n */\r\n autoFocusOnHide?: false | ((element: HTMLElement) => boolean)\r\n\r\n /**\r\n * Callback which is called when the dialog opens and all animations complete\r\n */\r\n onFullyOpen?: () => void\r\n\r\n /**\r\n * Callback which is called when the dialog closes and all animations complete\r\n */\r\n onFullyClosed?: () => void\r\n}\r\n\r\nexport const StatelessDropdown = React.forwardRef(function DropdownComponent(\r\n {\r\n trigger,\r\n modal = true,\r\n rounding = 'regular',\r\n theme = 'default',\r\n gutter,\r\n unmountOnHide = true,\r\n children,\r\n backdrop,\r\n showOnHover,\r\n hideOnInteractOutside,\r\n autoFocusOnShow,\r\n autoFocusOnHide,\r\n onFullyOpen,\r\n onFullyClosed,\r\n ...props\r\n }: React.PropsWithChildren,\r\n ref: React.ForwardedRef\r\n) {\r\n const store = Ariakit.useMenuContext()\r\n const { placement, zIndex, updatePosition } = usePopoverPlacement(store)\r\n const isOpen = store?.useState('open')\r\n const [isFullyOpen, setIsFullyOpen] = React.useState(false)\r\n const isMounted = store?.useState('mounted')\r\n const wasMounted = usePrevious(isMounted)\r\n const menuGutter = gutter ?? (store?.parent ? 6 : 4)\r\n\r\n React.useEffect(() => {\r\n if (wasMounted && !isMounted) {\r\n onFullyClosed?.()\r\n }\r\n // We want to call it only on isMounted change\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n }, [isMounted])\r\n\r\n return (\r\n <>\r\n {trigger && (\r\n \r\n )}\r\n }\r\n // Update zIndex when popover position changes\r\n updatePosition={updatePosition}\r\n // E2E tests don’t wait for transitions to complete and it could lead to bugs with other popover components (ResizeObserver loop exceeded)\r\n // or visual diffs due a screenshot being captured while the dropdown still in transition\r\n // If you encounter this problem, just do `cy.get('[data-fully-open=true]').should('exist')` before continuing to wait for the dropdown\r\n data-fully-open={isFullyOpen}\r\n className={classNames(\r\n props.className,\r\n zIndex,\r\n DropdownRounding[rounding],\r\n DropdownTheme[theme],\r\n 'custom-scrollbar absolute flex flex-col overflow-hidden shadow-modal outline-none dark:shadow-modal-dark',\r\n // These are set by popper, we just need to make sure we don’t encroach on the safe insets\r\n 'min-w-[--popover-anchor-width] max-w-[--popover-available-width]',\r\n // Animations\r\n 'opacity-0 transition duration-[250ms] data-[enter]:translate-y-0 data-[enter]:opacity-100',\r\n {\r\n // When in combobox mode, the padding is smaller so we can render a gradient under the combobox input.\r\n // Change the custom scrollbar offset so the top of the first item fits the top of our scrollbar\r\n '[--scrollbar-radius:0]': DropdownRounding[rounding] === DropdownRounding.none,\r\n // Direction based styles\r\n 'max-h-[calc(var(--popover-available-height)-env(safe-area-inset-bottom))] motion-safe:-translate-y-1':\r\n placement?.startsWith('bottom'),\r\n 'max-h-[calc(var(--popover-available-height)-env(safe-area-inset-top))] motion-safe:translate-y-1':\r\n placement?.startsWith('top'),\r\n }\r\n )}\r\n onTransitionEnd={(ev) => {\r\n if (ev.target === ev.currentTarget && isOpen) {\r\n setIsFullyOpen(true)\r\n onFullyOpen?.()\r\n }\r\n }}\r\n >\r\n \r\n {children}\r\n
\r\n \r\n \r\n )\r\n})\r\n\r\nexport interface DropdownProps extends StatelessDropdownProps {\r\n state?: Ariakit.MenuStore\r\n}\r\n\r\nexport const Dropdown = React.forwardRef(\r\n (\r\n { state, placement, orientation = 'vertical', ...props }: React.PropsWithChildren,\r\n ref: React.ForwardedRef\r\n ) => (\r\n \r\n \r\n \r\n )\r\n)\r\n","import * as Ariakit from '@ariakit/react'\r\nimport * as React from 'react'\r\n\r\nimport { OptionButton, OptionButtonProps } from '../OptionButton'\r\nimport { BUTTON_DEFAULT_ELEMENT } from '../button'\r\nimport { PropsWithAs } from '../types'\r\n\r\ninterface DropdownItemProps extends OptionButtonProps {\r\n store?: Ariakit.MenuStore\r\n\r\n subtitle?: React.ReactNode\r\n\r\n /**\r\n * Whether clicking the item should also close the dropdown. Only applies to\r\n * items without a submenu\r\n *\r\n * @default true\r\n */\r\n hideOnClick?: boolean\r\n}\r\n\r\nfunction DropdownItemComponent(\r\n { as: asComponent, ...props }: PropsWithAs & DropdownItemProps,\r\n ref: React.ForwardedRef\r\n) {\r\n return } />\r\n}\r\n\r\n/**\r\n * We need to forward ref to the function, but typescript looses the type of the\r\n * props param so we need to typecast to get suggestions to work\r\n */\r\nexport const DropdownItem = React.forwardRef(DropdownItemComponent) as <\r\n TagType extends React.ElementType = typeof BUTTON_DEFAULT_ELEMENT,\r\n>(\r\n props: PropsWithAs & DropdownItemProps & { ref?: React.ForwardedRef }\r\n) => ReturnType\r\n","import * as Ariakit from '@ariakit/react'\r\n\r\nexport const useDropdownState = Ariakit.useMenuStore\r\n","import * as React from 'react'\r\n\r\nimport { PartialBy } from '../../types'\r\nimport { MenuGroup } from '../MenuGroup'\r\nimport { Dropdown, DropdownItem, DropdownProps } from '../dropdown'\r\nimport { ObjectHash } from '../types'\r\n\r\nexport interface IContextMenuOption {\r\n type?: never\r\n id: string\r\n label: React.ReactNode\r\n onClick?: () => void\r\n options?: ContextMenuItem[]\r\n gtag?: ObjectHash\r\n}\r\n\r\ninterface IContextMenuDivider {\r\n type: 'divider'\r\n label?: React.ReactNode\r\n}\r\n\r\nexport type ContextMenuItem = IContextMenuOption | IContextMenuDivider\r\n\r\ninterface ContextMenuInnerProps extends PartialBy {\r\n /**\r\n * Items visible in the menu\r\n */\r\n items: ContextMenuItem[]\r\n}\r\n\r\nexport function ContextMenuInner(\r\n { trigger, items, onClose, ...props }: ContextMenuInnerProps,\r\n ref: React.ForwardedRef\r\n) {\r\n return (\r\n ev.preventDefault()}\r\n >\r\n {items?.map((item, index) => {\r\n if (item.type === 'divider') {\r\n return \r\n }\r\n\r\n if (item?.options !== undefined) {\r\n return (\r\n \r\n {item.label}\r\n \r\n }\r\n />\r\n )\r\n }\r\n\r\n return (\r\n {\r\n item.onClick?.()\r\n window.gtag?.('event', 'context-menu', Object.assign({ menu_option: item.id }, item.gtag))\r\n }}\r\n data-testid={`dropdown-menu-${item.id}`}\r\n >\r\n {item.label}\r\n \r\n )\r\n })}\r\n \r\n )\r\n}\r\n\r\nexport const ContextMenu = React.forwardRef(ContextMenuInner)\r\n","import classnames from 'classnames'\r\nimport React from 'react'\r\n\r\ninterface GridLayoutProps extends React.HTMLProps {\r\n /**\r\n * Number of columns\r\n */\r\n columns?: number\r\n\r\n /**\r\n * Number of rows\r\n */\r\n rows?: number\r\n\r\n /**\r\n * Whether or not a border is rendered between and around items. eg. charts\r\n * on HP won’t have a border\r\n *\r\n * @default false\r\n */\r\n border?: boolean\r\n}\r\n\r\nexport const ChartGridCell = React.forwardRef(\r\n ({ children, gridArea, className, ...props }, ref) => (\r\n \r\n {children}\r\n \r\n )\r\n)\r\n\r\ninterface ChartGridCellProps extends React.HTMLProps {\r\n /**\r\n * Css grid-area value\r\n */\r\n gridArea?: string\r\n}\r\n\r\nexport function GridLayout({ columns = 1, rows = 1, border = false, children, className, ...props }: GridLayoutProps) {\r\n return (\r\n \r\n {children}\r\n \r\n )\r\n}\r\n\r\ninterface ChartGridProps extends GridLayoutProps {\r\n isResizable?: boolean\r\n}\r\n\r\nexport const ChartGrid: React.FC = (props) => \r\n","import * as React from 'react'\r\n\r\nimport { PropsWithAs, RequireByKey } from '../types'\r\n\r\nconst defaultValueAccessor: ValueAccessor = (data) => data\r\n\r\nconst DEFAULT_VALUE_KEY = 'value'\r\nconst DEFAULT_CHANGE_KEY = 'onChange'\r\n\r\ntype ValueAccessor<\r\n TagType extends React.ElementType,\r\n ValueKey extends keyof React.ComponentProps = typeof DEFAULT_VALUE_KEY,\r\n ChangeKey extends keyof React.ComponentProps = typeof DEFAULT_CHANGE_KEY,\r\n> = (...args: Parameters[ChangeKey]>) => React.ComponentProps[ValueKey]\r\n\r\nexport type InnerStateProps<\r\n TagType extends React.ElementType,\r\n ValueKey extends keyof React.ComponentProps,\r\n ChangeKey extends keyof React.ComponentProps,\r\n> = RequireByKey, 'as'> & {\r\n valueKey?: ValueKey\r\n changeKey?: ChangeKey\r\n valueAccessor?: ValueAccessor\r\n}\r\n\r\nexport function InnerState<\r\n TagType extends React.ElementType,\r\n ValueKey extends keyof React.ComponentProps = typeof DEFAULT_VALUE_KEY,\r\n ChangeKey extends keyof React.ComponentProps = typeof DEFAULT_CHANGE_KEY,\r\n>({\r\n as: asComponent,\r\n valueKey = 'value' as ValueKey,\r\n changeKey = 'onChange' as ChangeKey,\r\n valueAccessor = defaultValueAccessor,\r\n ...props\r\n}: InnerStateProps) {\r\n const { [valueKey]: value, [changeKey]: onChange } = props\r\n const [state, setState] = React.useState[ValueKey]>(value)\r\n\r\n const handleChange = React.useCallback>(\r\n (...args) => {\r\n setState(valueAccessor(...args))\r\n onChange(...args)\r\n },\r\n [onChange, valueAccessor]\r\n )\r\n\r\n return React.createElement(asComponent, {\r\n ...props,\r\n [valueKey]: state,\r\n [changeKey]: handleChange,\r\n })\r\n}\r\n","import classnames from 'classnames'\r\nimport { HTMLProps, ReactNode, useEffect, useMemo, useRef, useState } from 'react'\r\n\r\nimport { Label } from './typography'\r\n\r\nexport enum RangeSize {\r\n small = 'sm:h-6', // 24px height\r\n regular = 'sm:h-7', // 28px height\r\n medium = 'sm:h-8', // 32px height\r\n large = 'sm:h-9', // 36px height\r\n}\r\n\r\ntype InputProps = HTMLProps\r\n\r\ninterface RangeSliderProps extends Omit {\r\n /**\r\n * Label which is rendered above the select\r\n */\r\n label?: ReactNode\r\n\r\n /**\r\n * Range size. All inputs have forced height on mobile to avoid zoom\r\n *\r\n * @default regular\r\n */\r\n size?: keyof typeof RangeSize\r\n\r\n /**\r\n * Element which will be rendered on the left side of the slider\r\n */\r\n leftContent?: ReactNode\r\n\r\n /**\r\n * Element which will be rendered on the right side of the slider\r\n */\r\n rightContent?: ReactNode\r\n\r\n /**\r\n * Class name for the wrapper element\r\n */\r\n className?: string\r\n\r\n /**\r\n * Class name for the input element\r\n */\r\n inputClassName?: string\r\n\r\n /**\r\n * Min value for the input\r\n *\r\n * @default 0\r\n */\r\n min?: number\r\n\r\n /**\r\n * Max value for the input\r\n *\r\n * @default 100\r\n */\r\n max?: number\r\n\r\n /**\r\n * Step value for the input\r\n *\r\n * @default 1\r\n */\r\n step?: number\r\n\r\n /**\r\n * Current value\r\n */\r\n value: number\r\n\r\n /**\r\n * Callback when value changes\r\n */\r\n onChange: InputProps['onChange']\r\n}\r\n\r\nexport function RangeSlider({\r\n label,\r\n size = 'regular',\r\n leftContent,\r\n rightContent,\r\n min = 0,\r\n max = 100,\r\n step = 1,\r\n className,\r\n inputClassName,\r\n ...props\r\n}: RangeSliderProps) {\r\n const [hasTrack, setHasTrack] = useState(false)\r\n const trackRef = useRef(null)\r\n const thumbRef = useRef(null)\r\n\r\n useEffect(() => {\r\n setHasTrack(Boolean(trackRef.current && thumbRef.current))\r\n }, [])\r\n\r\n const thumbLeft = useMemo(() => {\r\n const track = trackRef.current\r\n const thumb = thumbRef.current\r\n const valuePercent = (props.value - min) / (max - min)\r\n\r\n if (!hasTrack || !track || !thumb) return\r\n\r\n const trackBox = track.getBoundingClientRect()\r\n const thumbBox = thumb.getBoundingClientRect()\r\n\r\n return ((valuePercent * (trackBox.width - thumbBox.width)) / trackBox.width) * 100\r\n }, [min, max, props.value, hasTrack])\r\n\r\n return (\r\n \r\n )\r\n}\r\n","import { ButtonRoundingType, ButtonThemeType } from '../button'\r\nimport { IconNameType } from '../icon'\r\n\r\nexport enum ToolbarTheme {\r\n chipTransparent, // (default)\r\n alternative,\r\n}\r\n\r\nexport enum ToolbarDirection {\r\n vertical,\r\n horizontal,\r\n}\r\n\r\nexport type ToolbarDirectionType = keyof typeof ToolbarDirection\r\n\r\nexport interface IButtonThemeSettings {\r\n className?: string\r\n theme: ButtonThemeType\r\n rounding: ButtonRoundingType\r\n}\r\n\r\nexport interface IToolbarItem {\r\n id: string\r\n icon: IconNameType\r\n iconActive?: IconNameType\r\n iconAction?: IconNameType\r\n title: string\r\n titleActive?: string\r\n titleAction?: string\r\n}\r\n\r\nexport type ToolbarThemeType = keyof typeof ToolbarTheme\r\n","import * as React from 'react'\r\n\r\nimport { ToolbarDirection, ToolbarTheme } from './interfaces'\r\n\r\nexport interface IToolbarContext {\r\n direction: ToolbarDirection\r\n theme: ToolbarTheme\r\n isWrapped: boolean\r\n isStretched: boolean\r\n isMobile: boolean\r\n}\r\n\r\nexport const ToolbarContext = React.createContext({\r\n direction: ToolbarDirection.vertical,\r\n theme: ToolbarTheme.chipTransparent,\r\n isWrapped: false,\r\n isStretched: false,\r\n isMobile: false,\r\n})\r\n\r\nexport function useToolbarContext() {\r\n return React.useContext(ToolbarContext)\r\n}\r\n","import * as Ariakit from '@ariakit/react'\r\nimport classnames from 'classnames'\r\nimport throttle from 'lodash.throttle'\r\nimport React from 'react'\r\n\r\nimport { isSafariDesktop } from '../../../app/shared/isMobile'\r\nimport { StatelessDropdown } from '../dropdown'\r\nimport { IToolbarContext, ToolbarContext } from './hooks'\r\nimport { ToolbarDirection, ToolbarDirectionType, ToolbarTheme, ToolbarThemeType } from './interfaces'\r\n\r\nconst getToolbarSettings = ({\r\n direction,\r\n isWrapped,\r\n isMobile,\r\n theme,\r\n}: IToolbarContext): React.HTMLProps => {\r\n switch (isWrapped) {\r\n case true:\r\n return {\r\n className: classnames('shrink-0 items-center bg-white dark:bg-gray-800', {\r\n 'flex flex-wrap justify-between': direction === ToolbarDirection.vertical,\r\n 'grid border border-gray-100 dark:border-gray-600 p-1.5 gap-1 border-box rounded-md grid-cols-2':\r\n FinvizSettings.hasRedesignEnabled,\r\n }),\r\n }\r\n\r\n default:\r\n return {\r\n className: classnames('flex shrink-0 items-center bg-white dark:bg-gray-800', {\r\n 'p-1.5': !isMobile,\r\n 'space-x-1.5 px-1.5': direction === ToolbarDirection.horizontal && FinvizSettings.hasRedesignEnabled,\r\n 'flex-col overflow-hidden overflow-y-auto [--inset-l:0.5rem] landscape-primary:pl-inset-left':\r\n direction === ToolbarDirection.vertical,\r\n 'space-y-2': direction === ToolbarDirection.vertical && !isMobile,\r\n 'pb-inset-bottom [--inset-b:0.5rem]': theme !== ToolbarTheme.alternative && !isMobile,\r\n 'w-screen space-x-2 overflow-hidden overflow-x-auto':\r\n direction === ToolbarDirection.horizontal && theme !== ToolbarTheme.alternative,\r\n 'overflow-x-hidden': theme === ToolbarTheme.alternative,\r\n }),\r\n }\r\n }\r\n}\r\n\r\nexport interface ToolbarProps {\r\n /**\r\n * Toolbar direction\r\n *\r\n * @default vertical\r\n */\r\n direction?: ToolbarDirectionType\r\n\r\n /**\r\n * Toolbar buttons theme\r\n *\r\n * @default light\r\n */\r\n theme?: ToolbarThemeType\r\n\r\n /**\r\n * Charts mobile design\r\n *\r\n * @default false\r\n */\r\n isMobile?: boolean\r\n\r\n className?: string\r\n}\r\n\r\nexport function Toolbar({\r\n direction = 'vertical',\r\n theme = 'chipTransparent',\r\n isMobile = false,\r\n children,\r\n className,\r\n}: React.PropsWithChildren) {\r\n const hasFocusRings = React.useRef(false)\r\n const toolbarRef = React.useRef(null)\r\n const contextProviderValue = React.useMemo(\r\n () => ({\r\n direction: ToolbarDirection[direction],\r\n theme: ToolbarTheme[theme],\r\n isWrapped:\r\n ToolbarDirection[direction] === ToolbarDirection.vertical && ToolbarTheme[theme] === ToolbarTheme.alternative,\r\n isStretched:\r\n ToolbarDirection[direction] === ToolbarDirection.horizontal && ToolbarTheme[theme] === ToolbarTheme.alternative,\r\n isMobile,\r\n }),\r\n [direction, theme, isMobile]\r\n )\r\n const toolbarSettings = getToolbarSettings(contextProviderValue)\r\n\r\n React.useLayoutEffect(() => {\r\n // Workaround for Safari scrollbar bug https://github.com/finvizhq/charts/issues/1038\r\n // Safari injects scrollbar after layout render and doesn't trigger reflow\r\n if (ToolbarTheme[theme] !== ToolbarTheme.alternative && isSafariDesktop()) {\r\n const forceReflow = throttle(() => {\r\n if (toolbarRef.current !== null) {\r\n const originalWidth = toolbarRef.current.style.width\r\n toolbarRef.current.style.width = '0'\r\n // eslint-disable-next-line @typescript-eslint/no-unused-expressions\r\n toolbarRef.current.offsetWidth\r\n toolbarRef.current.style.width = originalWidth\r\n }\r\n }, 200)\r\n\r\n forceReflow()\r\n window.addEventListener('resize', forceReflow)\r\n\r\n return () => {\r\n window.removeEventListener('resize', forceReflow)\r\n }\r\n }\r\n }, [theme])\r\n\r\n return (\r\n \r\n \r\n {children}\r\n {\r\n hasFocusRings.current = !!document.querySelector('[data-focus-visible]')\r\n return true\r\n }}\r\n autoFocusOnHide={(el: HTMLElement) => {\r\n // Only call focus when we previously had focus rings to prevent sticky focus rings\r\n if (hasFocusRings.current) el.focus({ preventScroll: true })\r\n hasFocusRings.current = false\r\n return false\r\n }}\r\n />\r\n \r\n \r\n )\r\n}\r\n","import * as Ariakit from '@ariakit/react'\r\nimport classnames from 'classnames'\r\nimport * as React from 'react'\r\n\r\nimport { Button, ButtonHTMLProps, ButtonProps } from '../button'\r\nimport { Delayed } from '../delayed'\r\nimport { Icon } from '../icon'\r\nimport { Spinner } from '../spinner'\r\nimport { PropsWithAs } from '../types'\r\nimport { useToolbarContext } from './hooks'\r\nimport { IToolbarItem, ToolbarTheme } from './interfaces'\r\n\r\nfunction getButtonThemeSettings({\r\n className,\r\n theme,\r\n isActive,\r\n isStretched,\r\n isInAction,\r\n}: {\r\n className: string\r\n theme: ToolbarTheme\r\n isStretched: boolean\r\n isActive?: boolean\r\n isInAction?: boolean\r\n}): Omit & ButtonProps {\r\n const includeRedesign = FinvizSettings.hasRedesignEnabled\r\n switch (theme) {\r\n case ToolbarTheme.alternative:\r\n return {\r\n className: classnames(\r\n className,\r\n {\r\n grow: isStretched,\r\n 'h-10 w-10': !isStretched && !includeRedesign,\r\n 'animate-pulse': isInAction,\r\n },\r\n\r\n !includeRedesign && {\r\n 'active:bg-white disabled:bg-white disabled:text-gray-300 disabled:hover:text-gray-300': true,\r\n 'border border-white text-gray-500 hover:border-gray-100 hover:text-gray-900': !isActive,\r\n 'border border-gray-900 text-gray-900': isActive,\r\n }\r\n ),\r\n theme: includeRedesign ? 'chipTransparent' : 'transparent',\r\n rounding: includeRedesign ? undefined : 'none',\r\n size: isStretched || includeRedesign ? undefined : 'none',\r\n }\r\n default:\r\n return {\r\n className: classnames(\r\n className,\r\n 'border dark:disabled:bg-gray-800 dark:disabled:text-gray-600 disabled:text-gray-300 disabled:bg-white dark:disabled:hover:bg-gray-800 dark:disabled:hover:text-gray-600 disabled:hover:text-gray-300 disabled:hover:bg-white',\r\n {\r\n 'animate-pulse': isInAction,\r\n 'border-transparent text-gray-500 hover:bg-gray-200/30 hover:text-gray-900 dark:text-gray-400 dark:hover:bg-gray-500/30 dark:hover:text-gray-200':\r\n !isActive,\r\n 'border-blue-400 bg-blue-50 text-gray-900 dark:bg-gray-700 dark:text-white': isActive,\r\n }\r\n ),\r\n theme: 'transparent',\r\n rounding: 'small',\r\n }\r\n }\r\n}\r\n\r\nexport interface ToolbarButtonProps extends Omit {\r\n rowId?: number\r\n item: IToolbarItem\r\n disabledTooltip?: string\r\n isInAction?: boolean\r\n isLoading?: boolean\r\n}\r\n\r\nexport const ToolbarButton = React.forwardRef(function ToolbarButton(\r\n { item, disabledTooltip, isInAction: isInActionProp, isLoading, ...props }: PropsWithAs & ToolbarButtonProps,\r\n ref: React.ForwardedRef\r\n) {\r\n const context = Ariakit.useMenuContext()\r\n const { theme, isStretched } = useToolbarContext()\r\n const isInAction = isInActionProp && item.iconAction !== undefined\r\n const buttonSettings = getButtonThemeSettings({\r\n className: props.className,\r\n theme,\r\n isStretched,\r\n isActive: props.active,\r\n isInAction: isInAction,\r\n })\r\n\r\n const getMainIcon = () => (\r\n \r\n )\r\n\r\n return (\r\n }\r\n store={context?.menubar || undefined}\r\n blurOnHoverEnd\r\n render={\r\n \r\n {isLoading ? (\r\n \r\n \r\n \r\n ) : (\r\n <>\r\n {props.children ??\r\n (isInAction ? (\r\n \r\n \r\n \r\n ) : (\r\n getMainIcon()\r\n ))}\r\n \r\n )}\r\n \r\n }\r\n />\r\n )\r\n})\r\n","import * as Ariakit from '@ariakit/react'\r\nimport classnames from 'classnames'\r\nimport * as React from 'react'\r\n\r\nimport { isMobile } from '../../../app/shared/isMobile'\r\nimport { DropdownItem } from '../dropdown'\r\nimport { Icon } from '../icon'\r\nimport { NativeSelect } from '../select/NativeSelect'\r\nimport { useToolbarContext } from './hooks'\r\nimport { IToolbarItem, ToolbarTheme } from './interfaces'\r\nimport { ToolbarButton } from './toolbar-button'\r\n\r\nconst isMobileBrowser = isMobile()\r\n\r\nexport interface ToolbarGroupProps {\r\n /**\r\n * Main button item\r\n */\r\n defaultItem: IToolbarItem\r\n\r\n /**\r\n * Shows spinner instead of icon\r\n */\r\n isLoading?: boolean\r\n\r\n /**\r\n * Current selected item id\r\n */\r\n isActive: boolean\r\n\r\n /**\r\n * Should indicate some action in progress\r\n */\r\n isInAction?: boolean\r\n\r\n /**\r\n * Array of items\r\n */\r\n groupItems: IToolbarItem[]\r\n\r\n /**\r\n * Expand group button label\r\n */\r\n groupTitle?: string\r\n\r\n /**\r\n * On item select callback\r\n */\r\n onChange: (id: string, trigger: 'button' | 'select' | 'group') => void\r\n\r\n /**\r\n * Use native select for mobile devices\r\n *\r\n * @default true\r\n */\r\n useNativeSelect?: boolean\r\n\r\n /**\r\n * Is item disabled\r\n */\r\n disabled?: boolean\r\n\r\n /**\r\n * Tooltip message if item is disabled\r\n */\r\n disabledTooltip?: string\r\n\r\n rowId?: number\r\n}\r\n\r\nexport const ToolbarGroup = React.forwardRef(function ToolbarGroup(\r\n {\r\n defaultItem,\r\n isActive,\r\n isLoading,\r\n groupItems,\r\n groupTitle,\r\n onChange,\r\n useNativeSelect = isMobileBrowser,\r\n disabled,\r\n disabledTooltip,\r\n rowId,\r\n }: ToolbarGroupProps,\r\n ref: React.ForwardedRef\r\n) {\r\n const { theme, isStretched } = useToolbarContext()\r\n const [selectedItem, setSelectedItem] = React.useState(defaultItem)\r\n const groupId = groupTitle?.replace(/\\s/g, '-').toLocaleLowerCase()\r\n const isAlternativeTheme = theme === ToolbarTheme.alternative\r\n\r\n // Setup states, pass Menubar context to this menu so we can control the shared menu\r\n const context = Ariakit.useMenuContext()\r\n const menu = Ariakit.useMenuStore({ store: context })\r\n\r\n // We have multiple menu triggers but just one shared menu so we need a way to know which button has been hovered\r\n const [menuButton, setMenuButton] = React.useState(null)\r\n const open = menu.useState((state) => state.mounted && state.anchorElement === menuButton)\r\n\r\n // Find the element to render the menu into using Portal\r\n const parentMenu = menu.useState('contentElement')\r\n const menuContentElement = React.useMemo(() => parentMenu?.querySelector('div'), [parentMenu])\r\n\r\n /**\r\n * Charts prevent bubling mouseover so we need to hide the menu manually\r\n */\r\n const hideMenu = menu.hide\r\n React.useEffect(() => {\r\n const onMouseLeave = () => hideMenu()\r\n\r\n parentMenu?.addEventListener('mouseleave', onMouseLeave)\r\n return () => parentMenu?.removeEventListener('mouseleave', onMouseLeave)\r\n }, [hideMenu, parentMenu])\r\n\r\n const showMenu = menu.show\r\n const handleMenuOpen = React.useCallback(\r\n (ev: React.SyntheticEvent) => {\r\n menu.setDisclosureElement(ev.currentTarget)\r\n menu.setAnchorElement(ev.currentTarget)\r\n showMenu()\r\n },\r\n [menu, showMenu]\r\n )\r\n\r\n const trigger = (\r\n \r\n \r\n \r\n \r\n )\r\n\r\n if (useNativeSelect) {\r\n return (\r\n \r\n {trigger}\r\n ({ value: item.id, label: item.title }))}\r\n onChange={(option) => {\r\n setSelectedItem(groupItems![groupItems!.findIndex((item) => item.id === option.value)])\r\n onChange(option.value, 'select')\r\n }}\r\n onClick={() => onChange(selectedItem.id, 'select')}\r\n />\r\n \r\n )\r\n }\r\n\r\n return (\r\n \r\n ) => {\r\n // Preventing this means the dropdown will only open on hover not by a click\r\n ev.preventDefault()\r\n }}\r\n onPointerDown={(ev: React.PointerEvent) => {\r\n // Finally, pre-select the current group tool\r\n onChange(selectedItem.id, 'group')\r\n handleMenuOpen(ev)\r\n }}\r\n />\r\n {open && (\r\n // Render this menu's contents into the parent menu.\r\n }>\r\n {groupItems.map((item) => (\r\n }\r\n data-testid={`toolbar-group-${groupId}-${item.id}`}\r\n rounding={theme === ToolbarTheme.alternative && !FinvizSettings.hasRedesignEnabled ? 'none' : undefined}\r\n onPointerDown={() => {\r\n setSelectedItem(item)\r\n onChange(item.id, 'select')\r\n }}\r\n >\r\n {item.title}\r\n \r\n ))}\r\n \r\n )}\r\n \r\n )\r\n})\r\n","import { PartialBy } from '../../types'\r\nimport { ToolbarButton } from './toolbar-button'\r\nimport { ToolbarGroup, ToolbarGroupProps } from './toolbar-group'\r\n\r\nexport function ToolbarItem({\r\n defaultItem,\r\n isLoading,\r\n isActive,\r\n isInAction,\r\n groupItems,\r\n groupTitle,\r\n onChange,\r\n useNativeSelect,\r\n disabled,\r\n disabledTooltip,\r\n rowId,\r\n}: PartialBy) {\r\n const isItemActive = isActive && !disabled\r\n\r\n if (!!groupItems?.length) {\r\n return (\r\n \r\n )\r\n }\r\n\r\n return (\r\n {\r\n onChange(defaultItem.id, 'button')\r\n }}\r\n />\r\n )\r\n}\r\n","import classnames from 'classnames'\r\nimport React from 'react'\r\n\r\nimport { useToolbarContext } from './hooks'\r\nimport { ToolbarDirection, ToolbarTheme } from './interfaces'\r\n\r\ntype ToolbarDividerProps = {\r\n className?: string\r\n}\r\n\r\nexport function ToolbarDivider({ className }: ToolbarDividerProps) {\r\n const { direction, theme } = useToolbarContext()\r\n\r\n return (\r\n \r\n )\r\n}\r\n","import { Box } from '../box'\r\nimport { Heading, Paragraph } from '../typography'\r\nimport { TourStep } from './types'\r\n\r\nexport function StepContent({ step }: { step: TourStep }) {\r\n return (\r\n \r\n {step.title && (\r\n \r\n {step.title}\r\n \r\n )}\r\n {step.body && {step.body}}\r\n \r\n )\r\n}\r\n","import classnames from 'classnames'\r\nimport * as React from 'react'\r\nimport * as ReactDOM from 'react-dom/server'\r\nimport Shepherd from 'shepherd.js'\r\n\r\nimport {\r\n BUTTON_BASE_CLASS,\r\n BUTTON_FOCUS_STYLES,\r\n ButtonPadding,\r\n ButtonRounding,\r\n ButtonSize,\r\n ButtonTheme,\r\n getButtonTheme,\r\n} from '../button'\r\nimport { StepContent } from './step-content'\r\nimport { TourDefinition, TourStep } from './types'\r\n\r\ntype ExcludesFalse = (x: T | false) => x is T\r\n\r\n/**\r\n * Async load Shepherd module when we need it\r\n */\r\nlet shepherdLibrary: typeof Shepherd\r\nexport async function loadShepherdLibrary(setLoading: (state: boolean) => void) {\r\n if (shepherdLibrary) return shepherdLibrary\r\n\r\n try {\r\n setLoading(true)\r\n const shepherdPromise = await import('shepherd.js')\r\n shepherdLibrary = shepherdPromise.default\r\n setLoading(false)\r\n\r\n return shepherdLibrary\r\n } catch {}\r\n}\r\n\r\n/**\r\n * Get buttons based on index in the step array\r\n */\r\nconst buttonClasses = classnames(BUTTON_BASE_CLASS, BUTTON_FOCUS_STYLES, ButtonSize.regular, ButtonRounding.regular)\r\nfunction getStepButtons(tour: Shepherd.Tour, step: TourStep, index: number, arr: TourStep[]) {\r\n return [\r\n {\r\n action: tour.complete,\r\n classes: classnames(buttonClasses, 'mr-auto', getButtonTheme(ButtonTheme.light).button, ButtonPadding.regular),\r\n text: 'Exit',\r\n },\r\n index > 0 && {\r\n action: tour.back,\r\n classes: classnames(buttonClasses, getButtonTheme(ButtonTheme.light).button, ButtonPadding.regular),\r\n text: step.backButton ?? 'Back',\r\n },\r\n {\r\n classes: classnames(buttonClasses, getButtonTheme(ButtonTheme.blue).button, ButtonPadding.regular),\r\n action: tour.next,\r\n text: step.nextButton ?? (index === arr.length - 1 ? 'Finish' : 'Next'),\r\n },\r\n ].filter(Boolean as unknown as ExcludesFalse)\r\n}\r\n\r\n/**\r\n * Convert tour steps to Shepherd steps\r\n */\r\nexport function processSteps(tour: Shepherd.Tour, steps: TourStep[]): Shepherd.Step.StepOptions[] {\r\n return steps.map((step, index) => ({\r\n attachTo: { element: step.target, on: step.placement ?? 'auto' },\r\n classes: 'z-dialog',\r\n // Add offset\r\n popperOptions: {\r\n modifiers: [\r\n {\r\n name: 'offset',\r\n options: {\r\n offset: step.offset ?? [0, 10],\r\n },\r\n },\r\n ],\r\n },\r\n // Render the body\r\n text: ReactDOM.renderToString(React.createElement(StepContent, { step })),\r\n // Add buttons\r\n buttons: getStepButtons(tour, step, index, steps),\r\n modalOverlayOpeningRadius: step.overlayRadius ?? 8,\r\n modalOverlayOpeningPadding: step.overlayPadding ?? 0,\r\n }))\r\n}\r\n\r\nexport function getTourKey() {\r\n return `tour${window.location.pathname.replace(/[/.]/g, '-')}`\r\n}\r\n\r\nexport function getStepsForUser(tours: TourDefinition[]) {\r\n const lastFinishedTour = localStorage?.getItem(getTourKey())\r\n const lastTourIndex = tours.findIndex((tour) => tour.id === lastFinishedTour)\r\n const allToursViewed = lastTourIndex === tours.length - 1 || tours.slice(lastTourIndex + 1).every((item) => item.skip)\r\n const toursToView = allToursViewed ? tours : tours.slice(lastTourIndex + 1)\r\n const userTour = toursToView.reduce(\r\n (acc, current) =>\r\n current.skip\r\n ? acc\r\n : {\r\n ...acc,\r\n id: current.id,\r\n steps: [...acc.steps, ...current.steps],\r\n },\r\n { id: 'tour', steps: [], initialTour: toursToView[0].id }\r\n )\r\n\r\n return { hasNewTours: !allToursViewed, tour: userTour }\r\n}\r\n\r\nexport function completeTour(key: string) {\r\n localStorage?.setItem(getTourKey(), key)\r\n}\r\n","import * as React from 'react'\r\nimport Shepherd from 'shepherd.js'\r\n\r\nimport { TourDefinition } from './types'\r\nimport * as tourUtils from './utils'\r\n\r\nexport const DEFAULT_OPTIONS = {\r\n exitOnEsc: true,\r\n useModalOverlay: true,\r\n}\r\n\r\n/**\r\n * Hook which controls shepherd.js. The library is lazy-loaded when the tour starts\r\n *\r\n * Returns:\r\n * - `isLoading`: state of the library loading\r\n * - `currentTour`: tour object, only defined after library has loaded\r\n * - `startTour`: load the library and start tour. Returns `currentTour`\r\n * - `getStepsForUser`: returns a list of tour steps based on tours the user finished\r\n * - `completeTour`: persists the last finished tour to local storage\r\n */\r\nexport function useTour(options?: Shepherd.Tour.TourOptions) {\r\n const [isLoading, setIsLoading] = React.useState(false)\r\n const [currentTour, setTour] = React.useState(null)\r\n\r\n /**\r\n * We’re loading shepherd asynchronously and want to have loading state so we use\r\n * AbortController to check if the component is still mounted.\r\n */\r\n const controller = React.useRef('AbortController' in window ? new AbortController() : undefined)\r\n const loadingSetter = React.useRef((state: boolean) => {\r\n if (controller.current?.signal.aborted) return\r\n\r\n setIsLoading(state)\r\n })\r\n // Cleanup effect to abort the controller\r\n React.useEffect(() => () => controller.current?.abort(), [])\r\n\r\n const startTour = React.useCallback(\r\n async (definition: TourDefinition, setComplete = true) => {\r\n const shepherdLibrary = await tourUtils.loadShepherdLibrary(loadingSetter.current)\r\n\r\n if (shepherdLibrary && !controller.current?.signal.aborted) {\r\n const tour = currentTour ?? new shepherdLibrary.Tour({ ...DEFAULT_OPTIONS, ...options })\r\n\r\n if (!currentTour) setTour(tour)\r\n\r\n // Reset the tour steps in case they were updated\r\n Array.from(tour.steps).forEach((step) => tour.removeStep(step.id))\r\n\r\n const processedSteps = tourUtils.processSteps(tour, definition.steps)\r\n tour.addSteps(processedSteps)\r\n\r\n if (setComplete) {\r\n tourUtils.completeTour(definition.id)\r\n }\r\n\r\n tour.start()\r\n window.gtag?.('event', 'tour-start', { event_label: definition.initialTour ?? definition.id })\r\n\r\n return tour\r\n }\r\n },\r\n [currentTour, options]\r\n )\r\n\r\n return {\r\n isLoading,\r\n currentTour,\r\n startTour,\r\n getStepsForUser: tourUtils.getStepsForUser,\r\n completeTour: tourUtils.completeTour,\r\n }\r\n}\r\n","/* eslint-disable @typescript-eslint/no-duplicate-enum-values */\r\nimport * as Ariakit from '@ariakit/react'\r\nimport classNames from 'classnames'\r\nimport React from 'react'\r\n\r\nimport { BUTTON_DEFAULT_ELEMENT, Button, ButtonComponentProps } from '../button'\r\nimport { Icon, IconNameType, isValidIconName } from '../icon'\r\n\r\n// Must have the same keys as ButtonSize\r\nexport enum TabSpacing {\r\n xxsmall = 'space-x-0.5', // 2px spacing\r\n xsmall = 'space-x-1', // 4px spacing\r\n none = 'space-x-1.5', // 6px spacing\r\n small = 'space-x-1.5', // 6px spacing\r\n regular = 'space-x-1.5', // 6px spacing\r\n medium = 'space-x-2', // 8px spacing\r\n large = 'space-x-2', // 8px spacing\r\n}\r\n\r\nfunction getRightContent(content: JSX.Element | IconNameType | undefined, isActive: boolean) {\r\n if (isValidIconName(content)) return \r\n else if (React.isValidElement(content))\r\n return React.cloneElement(content as React.ReactElement<{ active: boolean }>, {\r\n active: isActive,\r\n })\r\n else return content\r\n}\r\n\r\nconst InternalTab = React.forwardRef(function InternalTab<\r\n TagType extends React.ElementType = typeof BUTTON_DEFAULT_ELEMENT,\r\n>(\r\n {\r\n rounding = 'none',\r\n theme = 'tab',\r\n size = 'medium',\r\n 'aria-selected': ariaSelected,\r\n children,\r\n ...props\r\n }: Omit, 'theme'>,\r\n ref: React.ForwardedRef\r\n) {\r\n const spacing = TabSpacing[size]\r\n const active = Boolean(ariaSelected)\r\n const rightContent = getRightContent(props.rightContent, active)\r\n\r\n return (\r\n )}\r\n ref={ref}\r\n active={active}\r\n theme={theme}\r\n size={size}\r\n rounding={rounding}\r\n rightContent={undefined}\r\n className={classNames('group/badge', props.className)}\r\n contentClass={classNames(spacing, 'flex', props.contentClass)}\r\n >\r\n {children}\r\n {rightContent}\r\n \r\n )\r\n})\r\n\r\nexport function Tab(\r\n props: React.PropsWithChildren>\r\n) {\r\n return } />\r\n}\r\n","import * as Ariakit from '@ariakit/react'\r\nimport classNames from 'classnames'\r\n\r\nexport function TabList(props: Ariakit.TabListProps) {\r\n return (\r\n \r\n )\r\n}\r\n","import * as Ariakit from '@ariakit/react'\r\nimport React from 'react'\r\n\r\nexport function TabPanel(props: Ariakit.TabPanelProps) {\r\n return \r\n}\r\n","import * as Ariakit from '@ariakit/react'\r\nimport React from 'react'\r\n\r\nexport function Tabs({ children }: React.PropsWithChildren) {\r\n return (\r\n \r\n
{children}
\r\n
\r\n )\r\n}\r\n","import classNames from 'classnames'\r\nimport React from 'react'\r\n\r\nenum BadgeSize {\r\n small = 'h-4 min-w-4', // 16px height\r\n medium = 'h-5 min-w-5', // 20px height\r\n}\r\ntype BadgeSizeType = keyof typeof BadgeSize\r\n\r\nenum BadgePadding {\r\n small = 'px-[5px] py-0', // 16px height\r\n medium = 'px-1.5 py-0.5', // 20px height\r\n}\r\ntype BadgePaddingType = keyof typeof BadgePadding\r\n\r\ntype BadgeProps = {\r\n size?: BadgeSizeType\r\n padding?: BadgePaddingType\r\n active?: boolean\r\n}\r\n\r\nexport function Badge({ size = 'medium', padding = size, active, children }: React.PropsWithChildren) {\r\n const badgePadding = BadgePadding[padding]\r\n const badgeSize = BadgeSize[size]\r\n\r\n return (\r\n \r\n {children}\r\n \r\n )\r\n}\r\n","import * as Ariakit from '@ariakit/react'\r\nimport * as React from 'react'\r\n\r\nimport { Input, InputComponentProps } from './input'\r\nimport { Tooltip, TooltipColor, TooltipProps, TooltipTrigger } from './tooltip'\r\n\r\ninterface TooltipSettingsProps\r\n extends Pick,\r\n Pick {\r\n color?: keyof typeof TooltipColor\r\n}\r\n\r\ninterface TooltipInputProps extends InputComponentProps {\r\n /**\r\n * Optimization to turn off the tooltip functionality if the input isn’t visible on screen\r\n *\r\n * @default true\r\n */\r\n isInteractive?: boolean\r\n\r\n /**\r\n * Settings for Tooltip component and useTooltipStore\r\n */\r\n tooltipSettings?: TooltipSettingsProps\r\n}\r\n\r\nfunction TooltipInputComponent(\r\n { tooltipSettings, isInteractive = true, name, children, ...props }: React.PropsWithChildren,\r\n ref: React.ForwardedRef\r\n) {\r\n const { color, gutter, placement = 'bottom', isPointerEventsEnabled } = tooltipSettings ?? {}\r\n\r\n const input = \r\n\r\n if (!isInteractive || !children) {\r\n return input\r\n }\r\n\r\n return (\r\n \r\n \r\n \r\n {children}\r\n \r\n \r\n )\r\n}\r\n\r\nexport const TooltipInput = React.forwardRef(TooltipInputComponent)\r\n","import * as React from 'react'\r\nimport { useLocation } from 'react-router-dom'\r\n\r\nimport * as tracking from '../../app/shared/tracking'\r\n\r\nexport function useTrackPageView(props?: { trackInitial?: boolean; trackAutomatically?: boolean }) {\r\n const { trackInitial = false, trackAutomatically = true } = props ?? {}\r\n const initialRender = React.useRef(trackInitial)\r\n const location = useLocation()\r\n\r\n const handleTrackView = React.useCallback(() => {\r\n tracking.trackPageView({ pathname: location.pathname, query: location.search })\r\n }, [location.pathname, location.search])\r\n\r\n React.useEffect(() => {\r\n if (!trackAutomatically) return\r\n if (initialRender.current) handleTrackView()\r\n initialRender.current = true\r\n }, [trackAutomatically, handleTrackView, trackInitial])\r\n\r\n return handleTrackView\r\n}\r\n","import * as React from 'react'\r\n\r\nimport { Notification, useNotification } from '../components/notification'\r\nimport { Paragraph } from '../components/typography'\r\nimport { useIsMounted } from '../hooks/use-is-mounted'\r\nimport { importWithRetry } from './import-with-retry'\r\n\r\nconst cache: any = {}\r\nconst errorsCache: any = {}\r\n\r\nenum ErrorSeverity {\r\n medium,\r\n high,\r\n}\r\n\r\nfunction defaultCaptureException(exception: Error, captureContext?: { extra: Record }) {\r\n if (process.env.NODE_ENV === 'development') {\r\n console.error(exception)\r\n } else {\r\n window.Sentry.captureException(exception, captureContext)\r\n }\r\n}\r\n\r\nexport interface ControlledModuleConfig {\r\n /**\r\n * Suspense mode shouldn’t be used together with controlled loading as it could lead to bugs.\r\n * If you know what you’re doing, add an ignore comment explaining the decision\r\n */\r\n isSuspenseMode?: never\r\n shouldLoadModule?: boolean\r\n}\r\nexport interface SuspenseModuleConfig {\r\n /**\r\n * Controlled loading shouldn’t be used together with suspense mode as it could lead to bugs.\r\n * If you know what you’re doing, add an ignore comment explaining the decision\r\n */\r\n shouldLoadModule?: never\r\n isSuspenseMode?: SuspenseMode\r\n}\r\n\r\n/**\r\n * Hook used to asynchronously load a module\r\n *\r\n * Usage: [wiki](https://github.com/finvizhq/Finviz-Website/wiki/Loading-modules-asynchronously#useasyncmodule)\r\n */\r\nexport function useAsyncModule({\r\n importFn,\r\n onError,\r\n errorSeverity,\r\n cacheKey,\r\n captureException = defaultCaptureException,\r\n shouldLoadModule = false,\r\n isSuspenseMode = false as SuspenseMode,\r\n}: {\r\n importFn: () => Promise\r\n onError?: () => void\r\n cacheKey: string\r\n errorSeverity?: keyof typeof ErrorSeverity\r\n captureException?: typeof defaultCaptureException\r\n} & (ControlledModuleConfig | SuspenseModuleConfig)) {\r\n const notificationContext = useNotification()\r\n const [isLoading, setIsLoading] = React.useState(null)\r\n const [isError, setIsError] = React.useState(false)\r\n const getIsMounted = useIsMounted()\r\n\r\n const handleError = () => {\r\n onError?.()\r\n setIsError(true)\r\n\r\n if (errorSeverity === undefined) {\r\n return\r\n }\r\n\r\n if (ErrorSeverity[errorSeverity] === ErrorSeverity.high) {\r\n window.handleScriptNotLoaded()\r\n window.renderScriptNotLoaded()\r\n }\r\n\r\n if (ErrorSeverity[errorSeverity] === ErrorSeverity.medium) {\r\n notificationContext.show(\r\n \r\n \r\n One or more of the required application components couldn’t be loaded.
Please try to repeat the\r\n action or{' '}\r\n window.location.reload()}>\r\n refresh the page\r\n {' '}\r\n if the problem persists.\r\n
\r\n
\r\n )\r\n }\r\n }\r\n\r\n const loadModule = async () => {\r\n if (cache[cacheKey]) {\r\n return cache[cacheKey]\r\n }\r\n\r\n setIsLoading(true)\r\n\r\n try {\r\n cache[cacheKey] = await importWithRetry(importFn)\r\n } catch (error) {\r\n captureException(error as Error)\r\n handleError()\r\n } finally {\r\n if (getIsMounted()) {\r\n setIsLoading(false)\r\n }\r\n }\r\n\r\n return cache[cacheKey]\r\n }\r\n\r\n React.useEffect(() => {\r\n if (shouldLoadModule) {\r\n loadModule()\r\n }\r\n // We want to run it only on shouldLoadModule change\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n }, [shouldLoadModule])\r\n\r\n const cachedModule = cache[cacheKey]\r\n if (isSuspenseMode) {\r\n if (errorsCache[cacheKey]) throw errorsCache[cacheKey]\r\n if (!cachedModule) {\r\n throw importFn()\r\n .then((mod) => (cache[cacheKey] = mod))\r\n .catch((err) => {\r\n handleError()\r\n errorsCache[cacheKey] = err\r\n })\r\n }\r\n }\r\n\r\n return [cachedModule ?? null, { isLoading: !!cachedModule ? false : isLoading, loadModule, isError }] as [\r\n SuspenseMode extends true ? T : T | null,\r\n { isLoading: boolean; loadModule: () => Promise; isError: boolean },\r\n ]\r\n}\r\n\r\n/**\r\n * HOC which wraps component in React.Suspense\r\n *\r\n * Usage: [wiki](https://github.com/finvizhq/Finviz-Website/wiki/Loading-modules-asynchronously#withsuspense)\r\n */\r\nexport function withSuspense

>(\r\n Component: React.ComponentType

,\r\n fallback: React.ReactNode = null\r\n) {\r\n return function WrappedComponent(props: P) {\r\n return (\r\n \r\n \r\n \r\n )\r\n }\r\n}\r\n","const NUM_OF_RETRIES = 3\r\n\r\nexport function importWithRetry(importFn: () => Promise, retries = 0) {\r\n const result = importFn().catch(async (err) => {\r\n if (retries > NUM_OF_RETRIES) {\r\n throw err\r\n }\r\n\r\n await new Promise((r) => setTimeout(r, 1000 * retries))\r\n\r\n return importWithRetry(importFn, retries + 1)\r\n }) as Promise\r\n\r\n return result\r\n}\r\n","export default class ElementBaseConfig {\r\n static type: string\r\n static abbreviation: string\r\n static label: string\r\n static shortLabel: string\r\n static optionsOrder: readonly string[]\r\n static optionsLabels: { [key: string]: string }\r\n static inputsOrder: readonly string[]\r\n static inputsLabels: { [key: string]: string }\r\n static calculatedValuesOrder: readonly string[]\r\n static calculatedValuesLabels: { [key: string]: string }\r\n static defaultCalculatedValueOption?: string\r\n\r\n static getShortLabelWithAttrs: (attrs: ObjectHash) => string\r\n static getDefaultCalculatedValues: () => { [key: string]: number[] }\r\n\r\n get type() {\r\n return (this.constructor as typeof ElementBaseConfig).type\r\n }\r\n\r\n get abbreviation() {\r\n return (this.constructor as typeof ElementBaseConfig).abbreviation\r\n }\r\n\r\n get label() {\r\n return (this.constructor as typeof ElementBaseConfig).label\r\n }\r\n\r\n get shortLabel() {\r\n return (this.constructor as typeof ElementBaseConfig).shortLabel\r\n }\r\n\r\n get optionsOrder() {\r\n return (this.constructor as typeof ElementBaseConfig).optionsOrder\r\n }\r\n\r\n get optionsLabels() {\r\n return (this.constructor as typeof ElementBaseConfig).optionsLabels\r\n }\r\n\r\n get inputsOrder() {\r\n return (this.constructor as typeof ElementBaseConfig).inputsOrder\r\n }\r\n\r\n get inputsLabels() {\r\n return (this.constructor as typeof ElementBaseConfig).inputsLabels\r\n }\r\n\r\n get calculatedValuesOrder() {\r\n return (this.constructor as typeof ElementBaseConfig).calculatedValuesOrder\r\n }\r\n\r\n get calculatedValuesLabels() {\r\n return (this.constructor as typeof ElementBaseConfig).calculatedValuesLabels\r\n }\r\n\r\n get defaultCalculatedValueOption() {\r\n return (this.constructor as typeof ElementBaseConfig).defaultCalculatedValueOption\r\n }\r\n\r\n get getShortLabelWithAttrs() {\r\n return (this.constructor as typeof ElementBaseConfig).getShortLabelWithAttrs\r\n }\r\n\r\n get getDefaultCalculatedValues() {\r\n return (this.constructor as typeof ElementBaseConfig).getDefaultCalculatedValues\r\n }\r\n}\r\n","import { DrawingBorder, PaneArea, ResizeByThumbWithTypeAndDifs } from '../../types/shared'\r\nimport { CanvasElementType } from '../constants/common'\r\nimport { getRoundedObject, getXYOffsetFromLine } from '../controllers/renderUtils'\r\nimport math from '../helpers/math'\r\nimport PaneModel from '../models/pane'\r\nimport Element from './element'\r\nimport Thumb from './thumb'\r\n\r\nexport interface IArrowAttrs {\r\n x1: number\r\n x2: number\r\n y1: number\r\n y2: number\r\n border: DrawingBorder\r\n}\r\n\r\nclass Arrow extends Element {\r\n static type = CanvasElementType.arrow\r\n\r\n declare scaled: Pick\r\n name = 'Arrow'\r\n\r\n constructor(values: Partial, model: PaneModel) {\r\n super(values, model)\r\n this.renderContent = this.renderContent.bind(this)\r\n this.resize = this.resize.bind(this)\r\n this._thumbs = [\r\n new Thumb(\r\n 'l',\r\n () => this.attrs.x1,\r\n () => this.attrs.y1,\r\n this.resize,\r\n this.model\r\n ),\r\n new Thumb(\r\n 'r',\r\n () => this.attrs.x2,\r\n () => this.attrs.y2,\r\n this.resize,\r\n this.model\r\n ),\r\n ]\r\n this.scale(this.getBoundingPointKeys())\r\n }\r\n\r\n getDefaults() {\r\n return {\r\n border: {\r\n width: 3,\r\n color: this.getChartLayoutSettings().ElementSettings.Colors.line,\r\n },\r\n } as Partial\r\n }\r\n\r\n getBoundingPointKeys = () => ({ x: ['x1', 'x2'], y: ['y1', 'y2'] })\r\n\r\n renderContent(context: CanvasRenderingContext2D) {\r\n const { x1, x2, y1, y2 } = this.scaled\r\n const roundedXY = getRoundedObject({ x1, x2, y1, y2 })\r\n const translateXY = getXYOffsetFromLine({ lineWidth: this.attrs.border.width, ...roundedXY })\r\n\r\n context.translate(translateXY.x, translateXY.y)\r\n context.beginPath()\r\n context.set('lineCap', 'round')\r\n context.set('lineWidth', this.attrs.border.width)\r\n context.set('strokeStyle', this.attrs.border.color)\r\n\r\n const angle = Math.PI / 8\r\n const d = 20\r\n\r\n context.beginPath()\r\n context.moveTo(roundedXY.x1, roundedXY.y1)\r\n context.lineTo(roundedXY.x2, roundedXY.y2)\r\n context.stroke()\r\n\r\n const lineAngle = Math.atan2(roundedXY.y2 - roundedXY.y1, roundedXY.x2 - roundedXY.x1)\r\n const h = Math.abs(d / Math.cos(angle))\r\n\r\n const angle1 = lineAngle + angle\r\n const topx = roundedXY.x1 + Math.cos(angle1) * h\r\n const topy = roundedXY.y1 + Math.sin(angle1) * h\r\n const angle2 = lineAngle - angle\r\n const botx = roundedXY.x1 + Math.cos(angle2) * h\r\n const boty = roundedXY.y1 + Math.sin(angle2) * h\r\n\r\n context.beginPath()\r\n context.moveTo(topx, topy)\r\n context.lineTo(roundedXY.x1, roundedXY.y1)\r\n context.lineTo(botx, boty)\r\n context.stroke()\r\n context.translate(translateXY.x * -1, translateXY.y * -1)\r\n\r\n if (this.getShouldRenderThumbs()) {\r\n this.renderThumbs(context)\r\n }\r\n }\r\n\r\n moveBy(x: number, y: number) {\r\n this.attrs.x1 += x\r\n this.attrs.x2 += x\r\n this.attrs.y1 += y\r\n this.attrs.y2 += y\r\n }\r\n\r\n resize({ type, difX, difY }: ResizeByThumbWithTypeAndDifs) {\r\n if (type === 'l') {\r\n this.attrs.x1 += difX\r\n this.attrs.y1 += difY\r\n } else {\r\n this.attrs.x2 += difX\r\n this.attrs.y2 += difY\r\n }\r\n }\r\n\r\n isInArea(area: PaneArea) {\r\n if (super.isDrawingElementLockedOrInvisible()) return false\r\n if (math.distanceToSegment(area.scaled, this.scaled) <= 10) {\r\n return true\r\n }\r\n return super.isInArea(area)\r\n }\r\n}\r\n\r\nArrow.prototype.modalConfig = {\r\n inputs: [{ type: 'line', name: 'border' }],\r\n}\r\n\r\nexport default Arrow\r\n","import { DrawingBorder, PaneArea, RequireByKey, ResizeByThumbFuncProps } from '../../../types/shared'\r\nimport { CanvasElementType } from '../../constants/common'\r\nimport math from '../../helpers/math'\r\nimport PaneModel from '../../models/pane'\r\nimport { getContextWithCache } from '../../utils/canvas'\r\nimport Element, { EdgeValues } from '../element'\r\nimport Thumb from '../thumb'\r\n\r\nexport type BrushPoints = Array<[x: number, y: number]>\r\n\r\nexport interface IBrushAttrs {\r\n points: BrushPoints\r\n fill: string\r\n border: DrawingBorder\r\n isPolyLineClosed: boolean\r\n positionPointsTimestamps: BrushPoints\r\n}\r\n\r\nclass Brush extends Element {\r\n static type = CanvasElementType.brushV1\r\n\r\n untranslatedContext: CanvasRenderingContext2D | null = null\r\n\r\n name = 'Brush'\r\n\r\n brushPath: Path2D | null = null\r\n\r\n cachedFill = {\r\n previousFill: '',\r\n shouldRenderFill: false,\r\n }\r\n\r\n constructor(values: Partial, model: PaneModel) {\r\n super(values, model)\r\n this.untranslatedContext = getContextWithCache(document.createElement('canvas'))\r\n this.setFillCache()\r\n }\r\n\r\n getDefaults() {\r\n const { ElementSettings } = this.getChartLayoutSettings()\r\n return {\r\n fill: ElementSettings.defaultTransparentFill,\r\n border: {\r\n width: 3,\r\n color: ElementSettings.Colors.border,\r\n },\r\n isPolyLineClosed: false,\r\n } as Partial\r\n }\r\n\r\n setFillCache() {\r\n this.cachedFill.previousFill = this.attrs.fill\r\n if (this.attrs.fill.length === 9) {\r\n this.cachedFill.shouldRenderFill = this.attrs.fill.slice(7) !== '00'\r\n } else {\r\n this.cachedFill.shouldRenderFill = true\r\n }\r\n }\r\n\r\n getShouldRenderFill() {\r\n if (this.attrs.fill !== this.cachedFill.previousFill) {\r\n this.setFillCache()\r\n }\r\n return this.cachedFill.shouldRenderFill\r\n }\r\n\r\n renderContent(context: CanvasRenderingContext2D) {\r\n if (this.attrs.border != null) {\r\n context.set('strokeStyle', this.attrs.border.color)\r\n }\r\n context.set('lineCap', 'round')\r\n context.set('lineJoin', 'round')\r\n\r\n const brushPath = new Path2D()\r\n const { points } = this.attrs\r\n context.beginPath()\r\n brushPath.moveTo(this.fx(points[0][0]), this.fy(points[0][1]))\r\n let i\r\n if (points.length > 3) {\r\n for (i = 0; i < points.length - 2; i++) {\r\n const xc = (this.fx(points[i][0]) + this.fx(points[i + 1][0])) / 2\r\n const yc = (this.fy(points[i][1]) + this.fy(points[i + 1][1])) / 2\r\n brushPath.quadraticCurveTo(this.fx(points[i][0]), this.fy(points[i][1]), xc, yc)\r\n }\r\n brushPath.quadraticCurveTo(\r\n this.fx(points[i][0]),\r\n this.fy(points[i][1]),\r\n this.fx(points[i + 1][0]),\r\n this.fy(points[i + 1][1])\r\n )\r\n } else {\r\n for (const point of points) {\r\n brushPath.lineTo(this.fx(point[0]), this.fy(point[1]))\r\n }\r\n }\r\n\r\n if (this.attrs.isPolyLineClosed) {\r\n brushPath.closePath()\r\n }\r\n this.brushPath = brushPath\r\n if (this.attrs.fill && this.getShouldRenderFill()) {\r\n context.set('fillStyle', this.attrs.fill)\r\n context.fill(brushPath)\r\n }\r\n if (this.attrs?.border?.width) {\r\n context.set('lineWidth', this.attrs.border.width)\r\n context.stroke(brushPath)\r\n }\r\n if (this.getShouldRenderThumbs()) {\r\n this.renderThumbs(context)\r\n }\r\n }\r\n\r\n getThumbs() {\r\n const [firstX, firstY] = this.attrs.points[0]\r\n const [lastX, lastY] = this.attrs.points[this.attrs.points.length - 1]\r\n\r\n return [\r\n new Thumb(\r\n 'first',\r\n () => firstX,\r\n () => firstY,\r\n this.moveByThumb,\r\n this.model\r\n ),\r\n new Thumb(\r\n 'last',\r\n () => lastX,\r\n () => lastY,\r\n this.moveByThumb,\r\n this.model\r\n ),\r\n ]\r\n }\r\n\r\n moveByThumb = ({ difX, difY }: RequireByKey) => {\r\n this.moveBy(difX, difY)\r\n }\r\n\r\n moveBy(x: number, y: number) {\r\n if (this.getIsCreator()) return\r\n for (const point of this.attrs.points) {\r\n point[0] += x\r\n point[1] += y\r\n }\r\n }\r\n\r\n onMouseUp() {\r\n const [currentDomainMax, currentDomainMin] = this.model.scale.y.domain()\r\n for (const point of this.attrs.points) {\r\n point[0] = this.roundToFixed(point[0], 2)\r\n point[1] = this.roundY(point[1], currentDomainMax - currentDomainMin)\r\n }\r\n super.onMouseUp()\r\n }\r\n\r\n isInArea(area: PaneArea) {\r\n if (super.isDrawingElementLockedOrInvisible()) return false\r\n const { points } = this.attrs\r\n if (\r\n (this.getShouldRenderFill() || this.attrs.isPolyLineClosed) &&\r\n this.brushPath &&\r\n this.untranslatedContext?.isPointInPath(this.brushPath, area.scaled.x, area.scaled.y)\r\n ) {\r\n return true\r\n } else if (points.length > 1) {\r\n for (let i = 0; i < points.length - 1; i++) {\r\n if (\r\n math.distanceToSegment(area.scaled, {\r\n x1: this.fx(points[i][0]),\r\n y1: this.fy(points[i][1]),\r\n x2: this.fx(points[i + 1][0]),\r\n y2: this.fy(points[i + 1][1]),\r\n }) <= 10\r\n ) {\r\n return true\r\n }\r\n }\r\n }\r\n return super.isInArea(area)\r\n }\r\n\r\n cachePointPositionTimestamp = () => {\r\n const quote = this.model?.chart()?.quote()\r\n if (quote) {\r\n const positionPointsTimestamps = this.attrs.points.map(([x, y]) => [quote.getTimestampFomPositionX(x), y])\r\n this.set({ positionPointsTimestamps } as Partial)\r\n }\r\n }\r\n\r\n updateScales() {\r\n const quote = this.model.chart().quote()\r\n const { positionPointsTimestamps } = this.attrs\r\n if (!quote || !positionPointsTimestamps) {\r\n // positionPointsTimestamps check is temporary to prevent app from crashing\r\n // caused by corrupted drawings - https://github.com/finvizhq/charts/pull/1386/files\r\n return\r\n }\r\n const points = positionPointsTimestamps.map(([x, y]) => [quote.getPositionXFromTimestamp(x), y])\r\n this.set({ points } as Partial)\r\n }\r\n\r\n roundToFixed = (value: number, places: number) => Number.parseFloat(math.round({ value, overridePlaces: places }))\r\n\r\n roundY = (y: number, domainDiff: number) => {\r\n if (domainDiff < 1) {\r\n const numberOfLeadingZeros = Math.abs(Math.floor(Math.log10(Math.abs(domainDiff)) + 1))\r\n if (numberOfLeadingZeros > 0) {\r\n return this.roundToFixed(y, numberOfLeadingZeros + 4)\r\n } else {\r\n return this.roundToFixed(y, numberOfLeadingZeros + 3)\r\n }\r\n } else if (domainDiff < 10) {\r\n return this.roundToFixed(y, 3)\r\n }\r\n return this.roundToFixed(y, 2)\r\n }\r\n\r\n getAutosaveOmittedProperties() {\r\n return ['points']\r\n }\r\n\r\n getEdgeXYValues() {\r\n if (this.edgeXYValues === null) {\r\n const edgeXYValues = {} as EdgeValues\r\n this.attrs.points.forEach(([x, y]) => {\r\n edgeXYValues.minX = Math.min(x, edgeXYValues.minX ?? x)\r\n edgeXYValues.minY = Math.min(y, edgeXYValues.minY ?? y)\r\n edgeXYValues.maxX = Math.max(x, edgeXYValues.maxX ?? x)\r\n edgeXYValues.maxY = Math.max(y, edgeXYValues.maxY ?? y)\r\n })\r\n\r\n this.edgeXYValues = edgeXYValues\r\n }\r\n\r\n return this.edgeXYValues\r\n }\r\n}\r\n\r\nBrush.prototype.modalConfig = {\r\n inputs: [\r\n { type: 'background', name: 'fill' },\r\n { type: 'border', name: 'border', min: 1, max: 20, default: {} },\r\n { type: 'checkbox', name: 'isPolyLineClosed', label: 'Close line' },\r\n ],\r\n}\r\n\r\nexport default Brush\r\n","import math from '../../helpers/math'\r\n\r\ninterface ICoordinates {\r\n x: number\r\n y: number\r\n}\r\nexport interface IRectangleSidesCoordinates {\r\n topLeft: ICoordinates\r\n topRight: ICoordinates\r\n rightTop: ICoordinates\r\n rightBottom: ICoordinates\r\n bottomRight: ICoordinates\r\n bottomLeft: ICoordinates\r\n leftBottom: ICoordinates\r\n leftTop: ICoordinates\r\n}\r\n\r\nexport interface ITailCoordinates {\r\n tailRoot: ICoordinates\r\n tailTip: ICoordinates\r\n}\r\n\r\nexport enum TailDirection {\r\n noTail,\r\n topLeftCorner,\r\n topRightCorner,\r\n bottomLeftCorner,\r\n bottomRightCorner,\r\n topSide,\r\n rightSide,\r\n bottomSide,\r\n leftSide,\r\n}\r\n\r\nexport const getRectangleSidesCoordinates = ({\r\n padding,\r\n radius,\r\n x2,\r\n y2,\r\n textWidth,\r\n measuredHeight,\r\n}: {\r\n padding: number\r\n radius: number\r\n x2: number\r\n y2: number\r\n textWidth: number\r\n measuredHeight: number\r\n}): IRectangleSidesCoordinates => ({\r\n topLeft: {\r\n x: x2 - padding + radius,\r\n y: y2 - padding,\r\n },\r\n topRight: {\r\n x: x2 + textWidth + padding - radius,\r\n y: y2 - padding,\r\n },\r\n rightTop: {\r\n x: x2 + textWidth + padding,\r\n y: y2 - padding + radius,\r\n },\r\n rightBottom: {\r\n x: x2 + textWidth + padding,\r\n y: y2 + padding + measuredHeight - radius,\r\n },\r\n bottomRight: {\r\n x: x2 + textWidth + padding - radius,\r\n y: y2 + padding + measuredHeight,\r\n },\r\n bottomLeft: {\r\n x: x2 - padding + radius,\r\n y: y2 + padding + measuredHeight,\r\n },\r\n leftBottom: {\r\n x: x2 - padding,\r\n y: y2 + padding + measuredHeight - radius,\r\n },\r\n leftTop: {\r\n x: x2 - padding,\r\n y: y2 - padding + radius,\r\n },\r\n})\r\n\r\nexport const getTailCoordinates = ({\r\n rectangleSides,\r\n x1,\r\n y1,\r\n}: {\r\n rectangleSides: IRectangleSidesCoordinates\r\n x1: number\r\n y1: number\r\n}): ITailCoordinates => ({\r\n tailRoot: {\r\n x: rectangleSides.topLeft.x + (rectangleSides.topRight.x - rectangleSides.topLeft.x) / 2,\r\n y: rectangleSides.leftTop.y + (rectangleSides.leftBottom.y - rectangleSides.leftTop.y) / 2,\r\n },\r\n tailTip: {\r\n x: x1,\r\n y: y1,\r\n },\r\n})\r\n\r\nconst getTailHalfWidth = (halfWidth: number, p1: ICoordinates, p2: ICoordinates): number => {\r\n const dist = math.distance(p1, p2)\r\n if (dist < halfWidth * 2) {\r\n return dist / 2\r\n } else {\r\n return halfWidth\r\n }\r\n}\r\n\r\nexport const getTailToSideIntersection = ({\r\n tail,\r\n rectangleSides,\r\n}: {\r\n tail: ITailCoordinates\r\n rectangleSides: IRectangleSidesCoordinates\r\n}): TailDirection => {\r\n const { topLeft, topRight, rightTop, rightBottom, bottomRight, bottomLeft, leftBottom, leftTop } = rectangleSides\r\n const { tailTip, tailRoot } = tail\r\n if (math.twoSegmentLinesIntersection(tailTip, tailRoot, topLeft, leftTop)) {\r\n return TailDirection.topLeftCorner\r\n } else if (math.twoSegmentLinesIntersection(tailTip, tailRoot, topRight, rightTop)) {\r\n return TailDirection.topRightCorner\r\n } else if (math.twoSegmentLinesIntersection(tailTip, tailRoot, bottomLeft, leftBottom)) {\r\n return TailDirection.bottomLeftCorner\r\n } else if (math.twoSegmentLinesIntersection(tailTip, tailRoot, bottomRight, rightBottom)) {\r\n return TailDirection.bottomRightCorner\r\n } else if (math.twoSegmentLinesIntersection(tailTip, tailRoot, topLeft, topRight)) {\r\n return TailDirection.topSide\r\n } else if (math.twoSegmentLinesIntersection(tailTip, tailRoot, rightTop, rightBottom)) {\r\n return TailDirection.rightSide\r\n } else if (math.twoSegmentLinesIntersection(tailTip, tailRoot, bottomLeft, bottomRight)) {\r\n return TailDirection.bottomSide\r\n } else if (math.twoSegmentLinesIntersection(tailTip, tailRoot, leftTop, leftBottom)) {\r\n return TailDirection.leftSide\r\n } else {\r\n return TailDirection.noTail\r\n }\r\n}\r\n\r\ninterface IRenderCallout {\r\n context: any\r\n radius: number\r\n requiredTailHalfWidth: number\r\n tail: ITailCoordinates\r\n rectangleSides: IRectangleSidesCoordinates\r\n tailDirection: TailDirection\r\n}\r\n\r\nexport const renderCallout = ({\r\n context,\r\n radius,\r\n requiredTailHalfWidth,\r\n tail,\r\n rectangleSides,\r\n tailDirection,\r\n}: IRenderCallout): void => {\r\n const { topLeft, topRight, rightTop, rightBottom, bottomRight, bottomLeft, leftBottom, leftTop } = rectangleSides\r\n const { tailTip, tailRoot } = tail\r\n\r\n // draw rounded rectangle from top left corner clockwise\r\n // !!! ORDER OF RENDER MATTERS !!!\r\n\r\n // renderTopLeftCorner\r\n if (tailDirection === TailDirection.topLeftCorner) {\r\n context.moveTo(leftTop.x, leftTop.y)\r\n context.lineTo(tailTip.x, tailTip.y)\r\n context.lineTo(topLeft.x, topLeft.y)\r\n } else {\r\n context.moveTo(leftTop.x, leftTop.y)\r\n context.arcTo(leftTop.x, topLeft.y, topLeft.x, topLeft.y, radius)\r\n }\r\n\r\n // renderTopLine\r\n if (tailDirection === TailDirection.topSide) {\r\n const tailLineToTopLineIntersection = math.twoSegmentLinesIntersection(tailTip, tailRoot, topLeft, topRight)\r\n if (!tailLineToTopLineIntersection) {\r\n context.lineTo(topRight.x, topRight.y)\r\n return\r\n }\r\n const tailHalfWidth = getTailHalfWidth(requiredTailHalfWidth, topLeft, topRight)\r\n if (tailLineToTopLineIntersection.x - tailHalfWidth < topLeft.x) {\r\n context.lineTo(tailTip.x, tailTip.y)\r\n context.lineTo(topLeft.x + tailHalfWidth * 2, tailLineToTopLineIntersection.y)\r\n } else if (tailLineToTopLineIntersection.x + tailHalfWidth > topRight.x) {\r\n context.lineTo(topRight.x - tailHalfWidth * 2, tailLineToTopLineIntersection.y)\r\n context.lineTo(tailTip.x, tailTip.y)\r\n context.lineTo(topRight.x, tailLineToTopLineIntersection.y)\r\n } else {\r\n context.lineTo(tailLineToTopLineIntersection.x - tailHalfWidth, tailLineToTopLineIntersection.y)\r\n context.lineTo(tailTip.x, tailTip.y)\r\n context.lineTo(tailLineToTopLineIntersection.x + tailHalfWidth, tailLineToTopLineIntersection.y)\r\n context.lineTo(topRight.x, topRight.y)\r\n }\r\n } else {\r\n context.lineTo(topRight.x, topRight.y)\r\n }\r\n\r\n // renderTopRightCorner\r\n if (tailDirection === TailDirection.topRightCorner) {\r\n context.lineTo(topRight.x, topRight.y)\r\n context.lineTo(tailTip.x, tailTip.y)\r\n context.lineTo(rightTop.x, rightTop.y)\r\n } else {\r\n context.arcTo(rightTop.x, topRight.y, rightTop.x, rightTop.y, radius)\r\n }\r\n\r\n // renderRightLine\r\n if (tailDirection === TailDirection.rightSide) {\r\n const tailLineToRightLineIntersection = math.twoSegmentLinesIntersection(tailTip, tailRoot, rightTop, rightBottom)\r\n if (!tailLineToRightLineIntersection) {\r\n context.lineTo(rightBottom.x, rightBottom.y)\r\n return\r\n }\r\n const tailHalfWidth = getTailHalfWidth(requiredTailHalfWidth, rightTop, rightBottom)\r\n if (tailLineToRightLineIntersection.y - tailHalfWidth < rightTop.y) {\r\n context.lineTo(tailTip.x, tailTip.y)\r\n context.lineTo(rightTop.x, rightTop.y + tailHalfWidth * 2)\r\n } else if (tailLineToRightLineIntersection.y + tailHalfWidth > rightBottom.y) {\r\n context.lineTo(rightBottom.x, rightBottom.y - tailHalfWidth * 2)\r\n context.lineTo(tailTip.x, tailTip.y)\r\n context.lineTo(rightBottom.x, rightBottom.y)\r\n } else {\r\n context.lineTo(tailLineToRightLineIntersection.x, tailLineToRightLineIntersection.y - tailHalfWidth)\r\n context.lineTo(tailTip.x, tailTip.y)\r\n context.lineTo(tailLineToRightLineIntersection.x, tailLineToRightLineIntersection.y + tailHalfWidth)\r\n context.lineTo(rightBottom.x, rightBottom.y)\r\n }\r\n } else {\r\n context.lineTo(rightBottom.x, rightBottom.y)\r\n }\r\n\r\n // renderBottomRightCorner\r\n if (tailDirection === TailDirection.bottomRightCorner) {\r\n context.lineTo(rightBottom.x, rightBottom.y)\r\n context.lineTo(tailTip.x, tailTip.y)\r\n context.lineTo(bottomRight.x, bottomRight.y)\r\n } else {\r\n context.arcTo(rightBottom.x, bottomRight.y, bottomRight.x, bottomRight.y, radius)\r\n }\r\n\r\n // renderBottomLine\r\n if (tailDirection === TailDirection.bottomSide) {\r\n const tailLineToBottomLineIntersection = math.twoSegmentLinesIntersection(\r\n tailTip,\r\n tailRoot,\r\n bottomLeft,\r\n bottomRight\r\n )\r\n if (!tailLineToBottomLineIntersection) {\r\n context.lineTo(bottomLeft.x, bottomLeft.y)\r\n return\r\n }\r\n const tailHalfWidth = getTailHalfWidth(requiredTailHalfWidth, bottomLeft, bottomRight)\r\n if (tailLineToBottomLineIntersection.x + tailHalfWidth > bottomRight.x) {\r\n context.lineTo(tailTip.x, tailTip.y)\r\n context.lineTo(bottomRight.x - tailHalfWidth * 2, tailLineToBottomLineIntersection.y)\r\n } else if (tailLineToBottomLineIntersection.x - tailHalfWidth < bottomLeft.x) {\r\n context.lineTo(bottomLeft.x + tailHalfWidth * 2, tailLineToBottomLineIntersection.y)\r\n context.lineTo(tailTip.x, tailTip.y)\r\n context.lineTo(bottomLeft.x, tailLineToBottomLineIntersection.y)\r\n } else {\r\n context.lineTo(tailLineToBottomLineIntersection.x + tailHalfWidth, tailLineToBottomLineIntersection.y)\r\n context.lineTo(tailTip.x, tailTip.y)\r\n context.lineTo(tailLineToBottomLineIntersection.x - tailHalfWidth, tailLineToBottomLineIntersection.y)\r\n context.lineTo(bottomLeft.x, bottomLeft.y)\r\n }\r\n } else {\r\n context.lineTo(bottomLeft.x, bottomLeft.y)\r\n }\r\n\r\n // renderBottomLeftCorner\r\n if (tailDirection === TailDirection.bottomLeftCorner) {\r\n context.lineTo(bottomLeft.x, bottomLeft.y)\r\n context.lineTo(tailTip.x, tailTip.y)\r\n context.lineTo(leftBottom.x, leftBottom.y)\r\n } else {\r\n context.arcTo(leftBottom.x, bottomLeft.y, leftBottom.x, leftBottom.y, radius)\r\n }\r\n\r\n // renderLeftLine\r\n if (tailDirection === TailDirection.leftSide) {\r\n const tailLineToLeftLineIntersection = math.twoSegmentLinesIntersection(tailTip, tailRoot, leftTop, leftBottom)\r\n if (!tailLineToLeftLineIntersection) {\r\n context.lineTo(leftTop.x, leftTop.y)\r\n return\r\n }\r\n const tailHalfWidth = getTailHalfWidth(requiredTailHalfWidth, leftTop, leftBottom)\r\n if (tailLineToLeftLineIntersection.y + tailHalfWidth > leftBottom.y) {\r\n context.lineTo(tailTip.x, tailTip.y)\r\n context.lineTo(leftBottom.x, leftBottom.y - tailHalfWidth * 2)\r\n } else if (tailLineToLeftLineIntersection.y - tailHalfWidth < leftTop.y) {\r\n context.lineTo(leftTop.x, leftTop.y + tailHalfWidth * 2)\r\n context.lineTo(tailTip.x, tailTip.y)\r\n context.lineTo(leftTop.x, leftTop.y)\r\n } else {\r\n context.lineTo(tailLineToLeftLineIntersection.x, tailLineToLeftLineIntersection.y + tailHalfWidth)\r\n context.lineTo(tailTip.x, tailTip.y)\r\n context.lineTo(tailLineToLeftLineIntersection.x, tailLineToLeftLineIntersection.y - tailHalfWidth)\r\n context.lineTo(leftTop.x, leftTop.y)\r\n }\r\n } else {\r\n context.lineTo(leftTop.x, leftTop.y)\r\n }\r\n}\r\n","import merge from 'lodash.merge'\r\n\r\nimport { PaneArea, RequireByKey, ResizeByThumbWithTypeAndDifs, TextAttrs } from '../../../types/shared'\r\nimport { PADDING } from '../../constants/common'\r\nimport { CanvasElementType } from '../../constants/common'\r\nimport math from '../../helpers/math'\r\nimport Chart from '../../models/chart'\r\nimport PaneModel from '../../models/pane'\r\nimport Text from '../text'\r\nimport Thumb from '../thumb'\r\nimport {\r\n getRectangleSidesCoordinates,\r\n getTailCoordinates,\r\n getTailToSideIntersection,\r\n renderCallout,\r\n} from './callout_utils'\r\n\r\nexport interface ICalloutAttrs {\r\n x1: number\r\n y1: number\r\n x2: number\r\n y2: number\r\n}\r\n\r\ninterface FontFamilyHeightCoefficient {\r\n Arial: {\r\n firstLine: number\r\n otherLines: number\r\n }\r\n Verdana: {\r\n firstLine: number\r\n otherLines: number\r\n }\r\n}\r\n\r\ntype CalloutTextAttrs = ICalloutAttrs & RequireByKey\r\n\r\nclass Callout extends Text {\r\n static type = CanvasElementType.calloutV1\r\n\r\n name = 'Callout'\r\n\r\n declare fontFamilyHeightCoeficient: FontFamilyHeightCoefficient\r\n declare isActualBoundingBoxAvailable: boolean\r\n declare lastAttrs: Attrs\r\n declare scaled: Pick\r\n declare measuredHeight: number\r\n declare font: string\r\n declare context?: CanvasRenderingContext2D\r\n declare lines: {\r\n text: string\r\n metrics: TextMetrics\r\n }[]\r\n\r\n constructor(values: Partial, model: PaneModel) {\r\n super(values, model)\r\n this.resize = this.resize.bind(this)\r\n this._thumbs = [\r\n new Thumb(\r\n 'tail',\r\n () => this.attrs.x1,\r\n () => this.attrs.y1,\r\n this.resize,\r\n this.model\r\n ),\r\n ]\r\n this.scale(this.getBoundingPointKeys())\r\n }\r\n\r\n getBoundingPointKeys = () => ({ x: ['x1', 'x2'], y: ['y1', 'y2'] })\r\n\r\n getModalConfigBase() {\r\n return {\r\n inputs: [\r\n { type: 'multiline_string', name: 'text', required: true },\r\n { type: 'font', name: 'font' },\r\n {\r\n type: 'background',\r\n name: 'fillStyle',\r\n label: 'Color',\r\n default: this.getChartLayoutSettings().ElementSettings.Colors.textWithoutBackground,\r\n },\r\n {\r\n type: 'background',\r\n name: 'background',\r\n label: 'Background',\r\n default: 'rgba(0,0,0,0)',\r\n },\r\n {\r\n type: 'border',\r\n name: 'border',\r\n min: 0,\r\n },\r\n ],\r\n }\r\n }\r\n\r\n getDefaults() {\r\n const { ElementSettings } = this.getChartLayoutSettings()\r\n return {\r\n text: '',\r\n font: {\r\n size: 15,\r\n family: 'Arial',\r\n style: 'normal',\r\n weight: 'normal',\r\n },\r\n fillStyle: ElementSettings.Colors.textWithoutBackground,\r\n lineHeight: 15,\r\n // left | right | center | start | end\r\n textAlign: 'left',\r\n // top | middle | alphabetic | bottom\r\n textBaseline: 'alphabetic',\r\n padding: {\r\n top: 0,\r\n right: 0,\r\n bottom: 0,\r\n left: 0,\r\n },\r\n background: ElementSettings.defaultFill,\r\n border: { color: ElementSettings.Colors.line, width: 1 },\r\n } as Partial\r\n }\r\n\r\n setupContext(context: CanvasRenderingContext2D) {\r\n this.context = context\r\n context.set('font', this.font)\r\n context.set('fillStyle', this.attrs.fillStyle)\r\n context.set('textAlign', this.attrs.textAlign)\r\n context.set('textBaseline', this.attrs.textBaseline)\r\n this.setupTextMetricsCache()\r\n }\r\n\r\n setupTextMetricsCache() {\r\n const ctx = this.context\r\n\r\n if (\r\n (this.attrs.text !== this.lastAttrs?.text ||\r\n JSON.stringify(this.attrs.font) !== JSON.stringify(this.lastAttrs?.font)) &&\r\n ctx\r\n ) {\r\n this.lastAttrs = merge({}, this.attrs)\r\n this.lines = this.getLines().map((line) => ({\r\n text: line,\r\n metrics: ctx.measureText(line),\r\n }))\r\n this.measuredHeight = this.lines.reduce((acc, current, currentIndex) => {\r\n const lineHeight =\r\n current.metrics.actualBoundingBoxAscent +\r\n current.metrics.actualBoundingBoxDescent +\r\n (currentIndex !== this.lines.length - 1 ? PADDING.S : 0)\r\n return acc + lineHeight\r\n }, 0)\r\n }\r\n }\r\n\r\n renderContent(context: CanvasRenderingContext2D) {\r\n this.render(context)\r\n if (this.getShouldRenderThumbs()) {\r\n this.renderThumbs(context)\r\n }\r\n }\r\n\r\n renderText() {\r\n if (!this.context) return\r\n let y = this.scaled.y2 + this.attrs.padding.top\r\n let previousDescent = 0\r\n for (let i = 0; i < this.lines.length; i++) {\r\n y += i === 0 ? 0 : this.lines[i].metrics.actualBoundingBoxAscent + previousDescent + PADDING.S\r\n this.context.fillText(this.lines[i].text, this.scaled.x2 + this.attrs.padding.left, y)\r\n previousDescent = this.lines[i].metrics.actualBoundingBoxDescent\r\n }\r\n }\r\n\r\n getCalloutProperties() {\r\n const textWidth = this.attrs.text === '' ? this.attrs.font.size * 2 : this.width\r\n const requiredTailHalfWidth = this.attrs.font.size * 0.5\r\n const padding = this.attrs.border.width / 2 + this.attrs.font.size * 0.5\r\n const radius = textWidth < requiredTailHalfWidth ? textWidth / 2 : requiredTailHalfWidth\r\n\r\n const measuredHeight = this.measuredHeight < requiredTailHalfWidth ? radius * 2 : this.measuredHeight\r\n const y2 = this.scaled.y2 - (this.lines?.[0]?.metrics.actualBoundingBoxAscent || measuredHeight)\r\n\r\n // Points diagram\r\n //.......X-----------------X.......\r\n //.................................\r\n //...X.........................X...\r\n //...|.........................|...\r\n //...|.........................|...\r\n //...X.........................X...\r\n //.................................\r\n //.......X-----------------X.......\r\n\r\n const rectangleSides = getRectangleSidesCoordinates({\r\n padding,\r\n radius,\r\n x2: this.scaled.x2,\r\n y2,\r\n textWidth,\r\n measuredHeight,\r\n })\r\n const tail = getTailCoordinates({ rectangleSides, x1: this.scaled.x1, y1: this.scaled.y1 })\r\n const tailDirection = getTailToSideIntersection({ tail, rectangleSides })\r\n\r\n return {\r\n radius,\r\n requiredTailHalfWidth,\r\n rectangleSides,\r\n tail,\r\n tailDirection,\r\n }\r\n }\r\n\r\n renderBackground() {\r\n if (!this.attrs.background || !this.context) {\r\n return\r\n }\r\n\r\n const { radius, requiredTailHalfWidth, tail, tailDirection, rectangleSides } = this.getCalloutProperties()\r\n\r\n this.context.beginPath()\r\n this.context.set('fillStyle', this.attrs.background)\r\n this.context.lineJoin = 'round'\r\n renderCallout({\r\n context: this.context,\r\n radius,\r\n requiredTailHalfWidth,\r\n tail,\r\n rectangleSides,\r\n tailDirection,\r\n })\r\n this.context.closePath()\r\n this.context.fill()\r\n this.context.set('fillStyle', this.attrs.fillStyle)\r\n this.renderBorder()\r\n }\r\n\r\n isInArea(area: PaneArea) {\r\n if (super.isDrawingElementLockedOrInvisible()) return false\r\n // is in rectangle\r\n const { tail, rectangleSides, requiredTailHalfWidth } = this.getCalloutProperties()\r\n if (\r\n this.lines &&\r\n rectangleSides &&\r\n rectangleSides.leftTop.x < area.scaled.x &&\r\n rectangleSides.topLeft.y < area.scaled.y &&\r\n rectangleSides.rightBottom.x > area.scaled.x &&\r\n rectangleSides.bottomRight.y > area.scaled.y\r\n ) {\r\n return true\r\n }\r\n // is in tail\r\n if (tail) {\r\n const tailP1 = math.perpendicularPointToLine({\r\n distance: requiredTailHalfWidth,\r\n line: { x1: tail.tailTip.x, y1: tail.tailTip.y, x2: tail.tailRoot.x, y2: tail.tailRoot.y },\r\n })\r\n const pointOffsetX = tailP1.x - tail.tailRoot.x\r\n const pointOffsetY = tailP1.y - tail.tailRoot.y\r\n const tailP2 = { x: tail.tailRoot.x + -1 * pointOffsetX, y: tail.tailRoot.y + -1 * pointOffsetY }\r\n const polygon = [tail.tailTip, tailP1, tailP2]\r\n if (math.pointInPolygon(area.scaled, polygon)) {\r\n return true\r\n }\r\n }\r\n return super.isInArea(area)\r\n }\r\n\r\n moveBy(x: number, y: number) {\r\n this.attrs.x2 += x\r\n this.attrs.y2 += y\r\n }\r\n\r\n resize({ type, difX, difY }: ResizeByThumbWithTypeAndDifs) {\r\n if (type === 'tail') {\r\n this.attrs.x1 += difX\r\n this.attrs.y1 += difY\r\n }\r\n }\r\n\r\n getIsInChartView(chart: Chart) {\r\n if (this.getIsCreator() || !this.lines) {\r\n return true\r\n }\r\n\r\n const { tail, rectangleSides } = this.getCalloutProperties()\r\n\r\n return [...Object.values(rectangleSides), tail.tailRoot, tail.tailTip].some(\r\n ({ x, y }) => x <= -chart.leftOffset + chart.width && x >= -chart.leftOffset && y >= 0 && y <= this.model.height\r\n )\r\n }\r\n}\r\n\r\nexport default Callout\r\n","import { Bezier } from 'bezier-js'\r\n\r\nimport { DrawingBorder, PaneArea, ResizeByThumbWithTypeAndDifs } from '../../types/shared'\r\nimport { CanvasElementType } from '../constants/common'\r\nimport Chart from '../models/chart'\r\nimport PaneModel from '../models/pane'\r\nimport Element from './element'\r\nimport Thumb from './thumb'\r\n\r\nexport interface ICurveAttrs {\r\n x1: number\r\n x2: number\r\n x3: number\r\n cp1x: number\r\n cp2x: number\r\n y1: number\r\n y2: number\r\n y3: number\r\n cp1y: number\r\n cp2y: number\r\n border: DrawingBorder\r\n}\r\n\r\nclass Curve extends Element {\r\n static type = CanvasElementType.curve\r\n\r\n name = 'Curve'\r\n declare scaled: Pick\r\n declare curve: Bezier\r\n\r\n constructor(values: Partial, model: PaneModel) {\r\n super(values, model)\r\n this.render = this.render.bind(this)\r\n this.resize = this.resize.bind(this)\r\n this._thumbs = [\r\n new Thumb(\r\n 'a',\r\n () => this.attrs.x1,\r\n () => this.attrs.y1,\r\n this.resize,\r\n this.model\r\n ),\r\n new Thumb(\r\n 'b',\r\n () => this.attrs.x2,\r\n () => this.attrs.y2,\r\n this.resize,\r\n this.model\r\n ),\r\n new Thumb(\r\n 'c',\r\n () => this.attrs.x3 || this.attrs.x2,\r\n () => this.attrs.y3 || this.attrs.y2,\r\n this.resize,\r\n this.model\r\n ),\r\n ]\r\n this.scale(this.getBoundingPointKeys())\r\n }\r\n\r\n getDefaults() {\r\n return {\r\n border: {\r\n width: 1,\r\n color: this.getChartLayoutSettings().ElementSettings.Colors.line,\r\n },\r\n } as Partial\r\n }\r\n\r\n getBoundingPointKeys = () => ({ x: ['x1', 'x2', 'x3'], y: ['y1', 'y2', 'y3'] })\r\n\r\n drawQuadraticCurve(context: CanvasRenderingContext2D, curve: Bezier) {\r\n const { points } = curve\r\n context.beginPath()\r\n context.moveTo(points[0].x, points[0].y)\r\n context.quadraticCurveTo(points[1].x, points[1].y, points[2].x, points[2].y)\r\n context.stroke()\r\n }\r\n\r\n renderContent(context: CanvasRenderingContext2D) {\r\n const { x1, x2, x3, y1, y2, y3 } = this.scaled\r\n context.translate(0.5, 0.5)\r\n context.set('lineWidth', this.attrs.border.width)\r\n context.set('strokeStyle', this.attrs.border.color)\r\n if (!x3 || !y3) {\r\n context.beginPath()\r\n context.moveTo(x1, y1)\r\n context.lineTo(x2, y2)\r\n context.lineTo(x3, y3)\r\n context.stroke()\r\n } else {\r\n this.curve = Bezier.quadraticFromPoints({ x: x1, y: y1 }, { x: x2, y: y2 }, { x: x3, y: y3 }, 0.5)\r\n this.drawQuadraticCurve(context, this.curve)\r\n }\r\n\r\n context.translate(-0.5, -0.5)\r\n if (this.getShouldRenderThumbs()) {\r\n this.renderThumbs(context)\r\n }\r\n }\r\n\r\n moveBy(x: number, y: number) {\r\n this.attrs.x1 += x\r\n this.attrs.x2 += x\r\n this.attrs.x3 += x\r\n this.attrs.cp1x += x\r\n this.attrs.cp2x += x\r\n\r\n this.attrs.y1 += y\r\n this.attrs.y2 += y\r\n this.attrs.y3 += y\r\n this.attrs.cp1y += y\r\n this.attrs.cp2y += y\r\n }\r\n\r\n resize({ type, difX, difY }: ResizeByThumbWithTypeAndDifs) {\r\n switch (type) {\r\n case 'a':\r\n this.attrs.x1 += difX\r\n this.attrs.y1 += difY\r\n break\r\n case 'b':\r\n this.attrs.x2 += difX\r\n this.attrs.y2 += difY\r\n break\r\n case 'c':\r\n this.attrs.x3 += difX\r\n this.attrs.y3 += difY\r\n break\r\n default:\r\n break\r\n }\r\n }\r\n\r\n isInArea(area: PaneArea) {\r\n if (super.isDrawingElementLockedOrInvisible()) return false\r\n if (this.curve && this.curve.project(area.scaled).d! <= 10) {\r\n return true\r\n }\r\n return this.thumbsAreInArea(area)\r\n }\r\n\r\n getIsInChartView(chart: Chart) {\r\n if (this.getIsCreator()) {\r\n return true\r\n }\r\n\r\n const { x1, x2, x3, y1, y2, y3 } = this.scaled\r\n if (!x3 || !y3) {\r\n return true\r\n }\r\n const isInView =\r\n Bezier.quadraticFromPoints({ x: x1, y: y1 }, { x: x2, y: y2 }, { x: x3, y: y3 }, 0.5).points.some(\r\n ({ x, y }) => x <= -chart.leftOffset + chart.width && x >= -chart.leftOffset && y >= 0 && y <= this.model.height\r\n ) ?? true\r\n\r\n return isInView\r\n }\r\n}\r\n\r\nCurve.prototype.modalConfig = {\r\n inputs: [{ type: 'line', name: 'border' }],\r\n}\r\n\r\nexport default Curve\r\n","import { DrawingBorder, PaneArea, ResizeByThumbWithTypeAndDifs } from '../../types/shared'\r\nimport { CanvasElementType } from '../constants/common'\r\nimport PaneModel from '../models/pane'\r\nimport Element from './element'\r\nimport Thumb from './thumb'\r\n\r\nexport interface IEllipseAttrs {\r\n x1: number\r\n x2: number\r\n x3: number\r\n cp1x: number\r\n cp2x: number\r\n y1: number\r\n y2: number\r\n y3: number\r\n cp1y: number\r\n cp2y: number\r\n width: number\r\n fill: string\r\n border: DrawingBorder\r\n}\r\n\r\ninterface ICoordinates {\r\n topCenterX: number\r\n topCenterY: number\r\n topRightX: number\r\n topRightY: number\r\n topLeftX: number\r\n topLeftY: number\r\n centerLeftX: number\r\n centerLeftY: number\r\n centerRightX: number\r\n centerRightY: number\r\n bottomCenterX: number\r\n bottomCenterY: number\r\n bottomLeftX: number\r\n bottomLeftY: number\r\n bottomRightX: number\r\n bottomRightY: number\r\n}\r\n\r\n// OLD Ellipse \"v0\" kept for backward-compatibiluty for old saved ideas\r\n// current Ellipse tool located in ellipse folder\r\nclass Ellipse extends Element {\r\n static type = CanvasElementType.ellipse\r\n\r\n name = 'Ellipse'\r\n\r\n declare scaled: Pick\r\n\r\n constructor(values: Partial, model: PaneModel) {\r\n super(values, model)\r\n this.resize = this.resize.bind(this)\r\n this._thumbs = [\r\n new Thumb(\r\n 'x1',\r\n () => this.attrs.x1,\r\n () => this.attrs.y1,\r\n this.resize,\r\n this.model\r\n ),\r\n new Thumb(\r\n 'x2',\r\n () => this.attrs.x2,\r\n () => this.attrs.y2,\r\n this.resize,\r\n this.model\r\n ),\r\n new Thumb(\r\n 'lw',\r\n () => this.model.scale.x.invert(this.getCoordinates().centerLeftX),\r\n () => this.model.scale.y.invert(this.getCoordinates().centerLeftY),\r\n this.resize,\r\n this.model\r\n ),\r\n new Thumb(\r\n 'rw',\r\n () => this.model.scale.x.invert(this.getCoordinates().centerRightX),\r\n () => this.model.scale.y.invert(this.getCoordinates().centerRightY),\r\n this.resize,\r\n this.model\r\n ),\r\n ]\r\n const boundingPointKeys = this.getBoundingPointKeys()\r\n this.scale({ x: [...boundingPointKeys.x, 'width'], y: boundingPointKeys.y })\r\n }\r\n\r\n getDefaults() {\r\n const { ElementSettings } = this.getChartLayoutSettings()\r\n return {\r\n fill: ElementSettings.defaultFill,\r\n border: {\r\n width: 1,\r\n color: ElementSettings.Colors.line,\r\n },\r\n } as Partial\r\n }\r\n\r\n getBoundingPointKeys = () => ({ x: ['x1', 'x2'], y: ['y1', 'y2'] })\r\n\r\n renderContent(context: CanvasRenderingContext2D) {\r\n const c = this.getCoordinates()\r\n\r\n context.set('fillStyle', this.attrs.fill)\r\n\r\n context.beginPath()\r\n context.moveTo(c.bottomCenterX, c.bottomCenterY)\r\n context.bezierCurveTo(c.bottomRightX, c.bottomRightY, c.topRightX, c.topRightY, c.topCenterX, c.topCenterY)\r\n context.bezierCurveTo(c.topLeftX, c.topLeftY, c.bottomLeftX, c.bottomLeftY, c.bottomCenterX, c.bottomCenterY)\r\n context.closePath()\r\n context.fill()\r\n\r\n context.set('lineWidth', this.attrs.border.width)\r\n context.set('strokeStyle', this.attrs.border.color)\r\n if ((this.attrs.border != null ? this.attrs.border.width : undefined) !== 0) {\r\n context.stroke()\r\n }\r\n\r\n if (this.getShouldRenderThumbs()) {\r\n this.renderThumbs(context)\r\n }\r\n }\r\n\r\n moveBy(x: number, y: number) {\r\n this.attrs.x1 += x\r\n this.attrs.y1 += y\r\n this.attrs.x2 += x\r\n this.attrs.y2 += y\r\n }\r\n\r\n resize({ type, difX, difY }: ResizeByThumbWithTypeAndDifs) {\r\n switch (type) {\r\n case 'x1':\r\n this.attrs.x1 += difX\r\n this.attrs.y1 += difY\r\n break\r\n case 'x2':\r\n this.attrs.x2 += difX\r\n this.attrs.y2 += difY\r\n break\r\n case 'lw':\r\n this.attrs.width += difX\r\n break\r\n case 'rw':\r\n this.attrs.width -= difX\r\n break\r\n default:\r\n break\r\n }\r\n }\r\n\r\n getCoordinates(): ICoordinates {\r\n // TODO cache?\r\n // http://stackoverflow.com/questions/14169234/the-relation-of-the-bezier-curve-and-ellipse\r\n const rotationAngle =\r\n Math.PI + Math.atan(-1 / ((this.scaled.y2 - this.scaled.y1) / (this.scaled.x2 - this.scaled.x1)))\r\n\r\n const sign = this.scaled.y1 > this.scaled.y2 ? 1 : -1\r\n const radiusX = this.scaled.width / 2\r\n let radiusY = (sign * Math.abs(this.scaled.y1 - this.scaled.y2)) / Math.cos(rotationAngle) / 2\r\n if (this.scaled.y1 === this.scaled.y2) {\r\n radiusY = Math.abs(this.scaled.x1 - this.scaled.x2) / 2\r\n }\r\n\r\n const width_two_thirds = (radiusX * 4) / 3\r\n\r\n const dx1 = Math.sin(rotationAngle) * radiusY\r\n const dy1 = Math.cos(rotationAngle) * radiusY\r\n const dx2 = Math.cos(rotationAngle) * width_two_thirds\r\n const dy2 = Math.sin(rotationAngle) * width_two_thirds\r\n\r\n const x = this.scaled.x1 + dx1\r\n const y = this.scaled.y1 - dy1\r\n\r\n const topCenterX = x - dx1\r\n const topCenterY = y + dy1\r\n const topRightX = topCenterX + dx2\r\n const topRightY = topCenterY + dy2\r\n const topLeftX = topCenterX - dx2\r\n const topLeftY = topCenterY - dy2\r\n\r\n const bottomCenterX = x + dx1\r\n const bottomCenterY = y - dy1\r\n const bottomRightX = bottomCenterX + dx2\r\n const bottomRightY = bottomCenterY + dy2\r\n const bottomLeftX = bottomCenterX - dx2\r\n const bottomLeftY = bottomCenterY - dy2\r\n\r\n const centerRightX = x + dx2\r\n const centerRightY = y + dy2\r\n const centerLeftX = x - dx2\r\n const centerLeftY = y - dy2\r\n\r\n return {\r\n topCenterX,\r\n topCenterY,\r\n topRightX,\r\n topRightY,\r\n topLeftX,\r\n topLeftY,\r\n centerLeftX,\r\n centerLeftY,\r\n centerRightX,\r\n centerRightY,\r\n bottomCenterX,\r\n bottomCenterY,\r\n bottomLeftX,\r\n bottomLeftY,\r\n bottomRightX,\r\n bottomRightY,\r\n }\r\n }\r\n\r\n isInArea(area: PaneArea) {\r\n if (super.isDrawingElementLockedOrInvisible()) return false\r\n const c = this.getCoordinates()\r\n const left = Math.min(this.scaled.x1, this.scaled.x2, c.centerRightX)\r\n const right = Math.max(this.scaled.x1, this.scaled.x2, c.centerLeftX)\r\n const top = Math.min(this.scaled.y1, this.scaled.y2, c.centerRightY)\r\n const bottom = Math.max(this.scaled.y1, this.scaled.y2, c.centerLeftY)\r\n if (left < area.scaled.x && area.scaled.x < right && top < area.scaled.y && area.scaled.y < bottom) {\r\n return true\r\n }\r\n return super.isInArea(area)\r\n }\r\n\r\n getIsInChartView() {\r\n return true\r\n }\r\n}\r\n\r\nEllipse.prototype.modalConfig = {\r\n inputs: [\r\n { type: 'background', name: 'fill' },\r\n { type: 'border', name: 'border', min: 1, default: {} },\r\n ],\r\n}\r\n\r\nexport default Ellipse\r\n","import { DrawingBorder, PaneArea, ResizeByThumbWithTypeAndDifs } from '../../types/shared'\r\nimport { CanvasElementType } from '../constants/common'\r\nimport math from '../helpers/math'\r\nimport PaneModel from '../models/pane'\r\nimport Element from './element'\r\nimport Thumb from './thumb'\r\n\r\ntype RotatedRectangleCoordiantes = [[number, number], [number, number], [number, number], [number, number]]\r\n\r\nexport interface IRotatedRectangleAttrs {\r\n x1: number\r\n x2: number\r\n y1: number\r\n y2: number\r\n height: number\r\n fill: string\r\n border: DrawingBorder\r\n}\r\n\r\n// OLD RotatedRectangle \"v0\" kept for backward-compatibiluty for old saved ideas\r\n// current RotatedRectangle tool located in rotated_rectangle folder\r\nclass RotatedRectangle extends Element {\r\n static type = CanvasElementType.rotatedRectangle\r\n\r\n name = 'Rotated rectangle'\r\n\r\n declare scaled: Pick\r\n\r\n constructor(values: Partial, model: PaneModel) {\r\n super(values, model)\r\n this.resize = this.resize.bind(this)\r\n const x = this.model.scale.x.invert\r\n const y = this.model.scale.y.invert\r\n this._thumbs = [\r\n new Thumb(\r\n 'ml',\r\n () => this.attrs.x1,\r\n () => this.attrs.y1,\r\n this.resize,\r\n this.model\r\n ),\r\n new Thumb(\r\n 'mr',\r\n () => this.attrs.x2,\r\n () => this.attrs.y2,\r\n this.resize,\r\n this.model\r\n ),\r\n new Thumb(\r\n 'tl',\r\n () => x(this.getRectCoordinates()[0][0]),\r\n () => y(this.getRectCoordinates()[0][1]),\r\n this.resize,\r\n this.model\r\n ),\r\n new Thumb(\r\n 'tr',\r\n () => x(this.getRectCoordinates()[1][0]),\r\n () => y(this.getRectCoordinates()[1][1]),\r\n this.resize,\r\n this.model\r\n ),\r\n new Thumb(\r\n 'bl',\r\n () => x(this.getRectCoordinates()[2][0]),\r\n () => y(this.getRectCoordinates()[2][1]),\r\n this.resize,\r\n this.model\r\n ),\r\n new Thumb(\r\n 'br',\r\n () => x(this.getRectCoordinates()[3][0]),\r\n () => y(this.getRectCoordinates()[3][1]),\r\n this.resize,\r\n this.model\r\n ),\r\n ]\r\n const boundingPointKeys = this.getBoundingPointKeys()\r\n this.scale({ x: [...boundingPointKeys.x, 'height'], y: boundingPointKeys.y })\r\n }\r\n\r\n getDefaults() {\r\n const { ElementSettings } = this.getChartLayoutSettings()\r\n return {\r\n fill: ElementSettings.defaultFill,\r\n border: {\r\n width: 1,\r\n color: ElementSettings.Colors.border,\r\n },\r\n } as Partial\r\n }\r\n\r\n getBoundingPointKeys = () => ({ x: ['x1', 'x2'], y: ['y1', 'y2'] })\r\n\r\n renderContent(context: CanvasRenderingContext2D) {\r\n context.set('fillStyle', this.attrs.fill)\r\n\r\n context.beginPath()\r\n const coords = this.getRectCoordinates()\r\n for (const point of coords) {\r\n context.lineTo(point[0], point[1])\r\n }\r\n context.lineTo(coords[0][0], coords[0][1])\r\n context.fill()\r\n\r\n context.set('lineWidth', this.attrs.border.width)\r\n context.set('strokeStyle', this.attrs.border.color)\r\n if ((this.attrs.border != null ? this.attrs.border.width : undefined) !== 0) {\r\n context.stroke()\r\n }\r\n\r\n if (this.getShouldRenderThumbs()) {\r\n this.renderThumbs(context)\r\n }\r\n }\r\n\r\n getRectCoordinates(): RotatedRectangleCoordiantes {\r\n const mx1 = this.scaled.x1\r\n const mx2 = this.scaled.x2\r\n const my1 = this.scaled.y1\r\n const my2 = this.scaled.y2\r\n const { height } = this.scaled\r\n\r\n const k = (my2 - my1) / (mx2 - mx1)\r\n const nk = -1 / k\r\n\r\n const sign = my1 > my2 ? 1 : -1\r\n const dx = (sign * Math.sqrt((height * height) / (1 + nk * nk))) / 2\r\n const dy = nk * dx\r\n\r\n let x1 = mx1 - dx\r\n let y1 = my1 - dy\r\n let x2 = mx2 - dx\r\n let y2 = my2 - dy\r\n\r\n let x3 = mx2 + dx\r\n let y3 = my2 + dy\r\n let x4 = mx1 + dx\r\n let y4 = my1 + dy\r\n\r\n if (my1 === my2) {\r\n x1 = mx1\r\n y1 = my1 - height / 2\r\n x2 = mx2\r\n y2 = my2 - height / 2\r\n\r\n x3 = mx2\r\n y3 = my2 + height / 2\r\n x4 = mx1\r\n y4 = my1 + height / 2\r\n }\r\n\r\n return [\r\n [x1, y1],\r\n [x2, y2],\r\n [x3, y3],\r\n [x4, y4],\r\n ]\r\n }\r\n\r\n moveBy(x: number, y: number) {\r\n this.attrs.x1 += x\r\n this.attrs.y1 += y\r\n this.attrs.x2 += x\r\n this.attrs.y2 += y\r\n }\r\n\r\n resize({ type, difX, difY }: ResizeByThumbWithTypeAndDifs) {\r\n switch (type) {\r\n case 'ml':\r\n this.attrs.x1 += difX\r\n this.attrs.y1 += difY\r\n break\r\n case 'mr':\r\n this.attrs.x2 += difX\r\n this.attrs.y2 += difY\r\n break\r\n case 'tl':\r\n case 'tr':\r\n this.attrs.height += difY\r\n break\r\n case 'bl':\r\n case 'br':\r\n this.attrs.height -= difY\r\n break\r\n default:\r\n return\r\n }\r\n }\r\n\r\n isInArea(area: PaneArea) {\r\n if (super.isDrawingElementLockedOrInvisible()) return false\r\n const coords = this.getRectCoordinates()\r\n const polygon = coords.map((c) => ({ x: c[0], y: c[1] }))\r\n if (math.pointInPolygon(area.scaled, polygon)) {\r\n return true\r\n }\r\n return super.isInArea(area)\r\n }\r\n\r\n getIsInChartView() {\r\n return true\r\n }\r\n}\r\n\r\nRotatedRectangle.prototype.modalConfig = {\r\n inputs: [\r\n { type: 'background', name: 'fill' },\r\n { type: 'border', name: 'border', min: 1, default: {} },\r\n ],\r\n}\r\n\r\nexport default RotatedRectangle\r\n","// TODO FontAwesome font or similar needs to be loaded before using Symbol\r\nimport { DrawingBorder, PaneArea, ResizeByThumbWithTypeAndDifs } from '../../types/shared'\r\nimport { CanvasElementType } from '../constants/common'\r\nimport PaneModel from '../models/pane'\r\nimport Element from './element'\r\nimport Thumb from './thumb'\r\n\r\nexport interface ISymbolAttrs {\r\n x1: number\r\n scaleX: number\r\n y1: number\r\n scaleY: number\r\n angle: number\r\n fill: string\r\n symbol: string\r\n border: DrawingBorder\r\n}\r\n\r\nclass SymbolElement extends Element {\r\n static type = CanvasElementType.symbol\r\n\r\n name = 'Symbol'\r\n\r\n declare textWidth: number\r\n declare textHeight: number\r\n declare scaled: Pick\r\n\r\n constructor(values: Partial, model: PaneModel) {\r\n super(values, model)\r\n\r\n this.resize = this.resize.bind(this)\r\n\r\n const sx = (sign: number) =>\r\n this.getRotatedCoordinates(this.scaled.x1 + sign * (this.textWidth / 2) * this.attrs.scaleX, this.scaled.y1)\r\n const sy = (sign: number) =>\r\n this.getRotatedCoordinates(this.scaled.x1, this.scaled.y1 + sign * (this.textHeight / 2) * this.attrs.scaleY)\r\n this._thumbs = [\r\n new Thumb(\r\n 'xr',\r\n () => this.model.scale.x.invert(sx(+1).x),\r\n () => this.model.scale.y.invert(sx(+1).y),\r\n this.resize,\r\n this.model\r\n ),\r\n new Thumb(\r\n 'xl',\r\n () => this.model.scale.x.invert(sx(-1).x),\r\n () => this.model.scale.y.invert(sx(-1).y),\r\n this.resize,\r\n this.model\r\n ),\r\n new Thumb(\r\n 'yt',\r\n () => this.model.scale.x.invert(sy(+1).x),\r\n () => this.model.scale.y.invert(sy(+1).y),\r\n this.resize,\r\n this.model\r\n ),\r\n new Thumb(\r\n 'yb',\r\n () => this.model.scale.x.invert(sy(-1).x),\r\n () => this.model.scale.y.invert(sy(-1).y),\r\n this.resize,\r\n this.model\r\n ),\r\n new Thumb(\r\n 'c',\r\n () => this.attrs.x1,\r\n () => this.attrs.y1,\r\n this.resize,\r\n this.model\r\n ),\r\n ]\r\n this.scale(this.getBoundingPointKeys())\r\n this.attrs.angle = this.attrs.angle || 0\r\n }\r\n\r\n getBoundingPointKeys = () => ({ x: ['x1'], y: ['y1'] })\r\n\r\n renderContent(context: CanvasRenderingContext2D) {\r\n context.set('font', '36px FontAwesome')\r\n context.set('fillStyle', this.attrs.fill)\r\n context.set('textAlign', 'left')\r\n context.set('textBaseline', 'top')\r\n\r\n this.textWidth = context.measureText(this.attrs.symbol).width\r\n this.textHeight = 36\r\n const xScale = this.attrs.scaleX\r\n const yScale = this.attrs.scaleY\r\n\r\n const xOffset = this.textWidth / -2\r\n const yOffset = this.textHeight / -2\r\n\r\n context.save()\r\n context.translate(this.scaled.x1, this.scaled.y1)\r\n context.rotate(this.attrs.angle)\r\n context.scale(xScale, yScale)\r\n context.fillText(this.attrs.symbol, xOffset, yOffset)\r\n context.restore()\r\n\r\n if (this.getShouldRenderThumbs()) {\r\n this.renderThumbs(context)\r\n }\r\n }\r\n\r\n getRotatedCoordinates(x: number, y: number) {\r\n const cx = this.scaled.x1\r\n const cy = this.scaled.y1\r\n const dx = x - cx\r\n const dy = y - cy\r\n const rx = dx * Math.cos(this.attrs.angle) - dy * Math.sin(this.attrs.angle)\r\n const ry = dy * Math.cos(this.attrs.angle) + dx * Math.sin(this.attrs.angle)\r\n return { x: cx + rx, y: cy + ry }\r\n }\r\n\r\n moveBy(x: number, y: number) {\r\n this.attrs.x1 += x\r\n return (this.attrs.y1 += y)\r\n }\r\n\r\n resize({ type, difX, difY }: ResizeByThumbWithTypeAndDifs) {\r\n switch (type) {\r\n case 'xl':\r\n this.attrs.scaleX -= difX\r\n break\r\n case 'xr':\r\n this.attrs.scaleX += difX\r\n break\r\n case 'yt':\r\n this.attrs.scaleY -= difY\r\n break\r\n case 'yb':\r\n this.attrs.scaleY += difY\r\n break\r\n case 'c':\r\n this.attrs.angle += difX / 5\r\n break\r\n default:\r\n break\r\n }\r\n }\r\n\r\n isInArea(area: PaneArea) {\r\n if (super.isDrawingElementLockedOrInvisible()) return false\r\n const halfWidth = (this.textWidth / 2) * this.attrs.scaleX\r\n const halfHeight = (this.textHeight / 2) * this.attrs.scaleY\r\n const left = Math.min(this.scaled.x1 - halfWidth, this.scaled.x1 + halfWidth)\r\n const right = Math.max(this.scaled.x1 - halfWidth, this.scaled.x1 + halfWidth)\r\n const top = Math.min(this.scaled.y1 - halfHeight, this.scaled.y1 + halfHeight)\r\n const bottom = Math.max(this.scaled.y1 - halfHeight, this.scaled.y1 + halfHeight)\r\n if (left < area.scaled.x && area.scaled.x < right && top < area.scaled.y && area.scaled.y < bottom) {\r\n return true\r\n }\r\n return super.isInArea(area)\r\n }\r\n}\r\n\r\nSymbolElement.prototype.defaults = { fill: 'rgba(0,0,0,1)' }\r\n\r\nSymbolElement.prototype.modalConfig = {\r\n inputs: [{ type: 'background', name: 'fill', label: 'Fill' }],\r\n}\r\n\r\nexport default SymbolElement\r\n","import { CanvasElementType } from '../constants/common'\r\nimport arrow from './arrow'\r\nimport brush_v1 from './brush/brush_v1'\r\nimport callout_v1 from './callout/callout_v1'\r\nimport curve from './curve'\r\nimport element from './element'\r\nimport elliottWaves from './elliott_waves/elliott_waves'\r\nimport ellipse from './ellipse'\r\nimport ellipse_v1 from './ellipse/ellipse_v1'\r\nimport fibonacci from './fibonacci_retracements'\r\nimport horizontalLine from './horizontal_line'\r\nimport line from './line'\r\nimport measure from './measure'\r\nimport pitchfork_v1 from './pitchfork/pitchfork_v1'\r\nimport polygon from './polygon'\r\nimport position from './position'\r\nimport rectangle from './rectangle'\r\nimport rotatedRectangle from './rotated_rectangle'\r\nimport rotatedRectangle_v1 from './rotated_rectangle/rotated_rectangle_v1'\r\nimport scaledLine from './scaled_line'\r\nimport scaledText from './scaled_text'\r\nimport symbolElement from './symbol'\r\nimport text from './text'\r\nimport triangle from './triangle'\r\nimport verticalLine from './vertical_line'\r\nimport xabcd from './xabcd'\r\n\r\nexport const drawingToolsByType = Object.freeze({\r\n [CanvasElementType.element]: element,\r\n [CanvasElementType.arrow]: arrow,\r\n [CanvasElementType.brushV1]: brush_v1,\r\n [CanvasElementType.calloutV1]: callout_v1,\r\n [CanvasElementType.curve]: curve,\r\n [CanvasElementType.elliottWaves]: elliottWaves,\r\n [CanvasElementType.ellipse]: ellipse,\r\n [CanvasElementType.ellipseV1]: ellipse_v1,\r\n [CanvasElementType.fibonacciRetracements]: fibonacci,\r\n [CanvasElementType.horizontalLine]: horizontalLine,\r\n [CanvasElementType.line]: line,\r\n [CanvasElementType.measure]: measure,\r\n [CanvasElementType.pitchforkV1]: pitchfork_v1,\r\n [CanvasElementType.polygon]: polygon,\r\n [CanvasElementType.position]: position,\r\n [CanvasElementType.rectangle]: rectangle,\r\n [CanvasElementType.rotatedRectangle]: rotatedRectangle,\r\n [CanvasElementType.rotatedRectangleV1]: rotatedRectangle_v1,\r\n [CanvasElementType.scaledLine]: scaledLine,\r\n [CanvasElementType.scaledText]: scaledText,\r\n [CanvasElementType.symbol]: symbolElement,\r\n [CanvasElementType.text]: text,\r\n [CanvasElementType.triangle]: triangle,\r\n [CanvasElementType.verticalLine]: verticalLine,\r\n [CanvasElementType.xabcd]: xabcd,\r\n})\r\n","import Spine from '@finviz/spine'\r\nimport merge from 'lodash.merge'\r\nimport mergewith from 'lodash.mergewith'\r\nimport omit from 'lodash.omit'\r\n\r\nimport {\r\n ChartConfigChartPaneElement,\r\n ObjectHash,\r\n PaneArea,\r\n RequireByKey,\r\n TodoObjectHashAnyType,\r\n} from '../../types/shared'\r\nimport {\r\n CanvasElementType,\r\n ChartElementType,\r\n ChartEventType,\r\n IVisibility,\r\n IndicatorType,\r\n MacroTimeframe,\r\n MicroMacroTimeframe,\r\n OverlayType,\r\n SetVisibilityTo,\r\n TIMEFRAME,\r\n} from '../constants/common'\r\nimport Chart from '../models/chart'\r\nimport PaneModel, { ScaleAxis } from '../models/pane'\r\nimport Quote from '../models/quote'\r\nimport { getChartLayoutSettings } from '../models/settings'\r\nimport { isInRange } from '../utils/helpers'\r\nimport ElementBaseConfig from './ElementBaseConfig'\r\nimport Thumb from './thumb'\r\n\r\nexport type TodoModalConfig = TodoObjectHashAnyType\r\ntype TodoPositionTimestamps = TodoObjectHashAnyType\r\n\r\nexport interface DefaultAttrs extends ObjectHash {\r\n positionTimestamps?: TodoPositionTimestamps\r\n visibility?: IVisibility\r\n}\r\n\r\nexport type EdgeValues = { minX?: number; maxX?: number; minY?: number; maxY?: number }\r\n\r\nclass Element extends Spine.Module {\r\n static type: CanvasElementType | OverlayType | ChartElementType | IndicatorType | ChartEventType =\r\n CanvasElementType.element\r\n\r\n static fromObject(obj: T['attrs'], model: T['model']) {\r\n return new this(obj, model) as T\r\n }\r\n\r\n static getNumOfBarsBuffer(\r\n _?: RequireByKey | RequireByKey\r\n ) {\r\n return 0\r\n }\r\n\r\n isCreator = false\r\n isCreatorDialogOpen = false\r\n attrs: Attrs = {} as Attrs\r\n declare static config: ElementBaseConfig\r\n\r\n model: any\r\n _thumbs: Thumb[]\r\n\r\n getDefaults?(): Partial\r\n renderCross?(ctx: RenderingContext2DType): void\r\n renderCrossText?(\r\n ctx: RenderingContext2DType,\r\n crossIndex: number,\r\n getDataByCrossIndex?: (key: keyof Quote, shouldReturnRoundedString?: boolean) => string | undefined\r\n ): void\r\n\r\n renderContent?(ctx: RenderingContext2DType): void\r\n renderGrid?(ctx: RenderingContext2DType): void\r\n renderLabels?(ctx: RenderingContext2DType): void\r\n declare defaults?: Partial\r\n getModalConfigBase?(): TodoModalConfig\r\n declare modalConfig?: TodoModalConfig\r\n getMinMax?(): { min: number; max: number }\r\n setupAxis?(fx: ScaleAxis): void | { min: number; max: number }\r\n\r\n activeThumb: Thumb | null = null\r\n isMouseDown = false\r\n isSelected = false\r\n isHovered = false\r\n isEditInProgress = false\r\n edgeXYValues: EdgeValues | null = null\r\n declare scaled?: ObjectHash | Partial\r\n\r\n declare toolsCallback: () => void\r\n\r\n constructor(values: Partial, model: Model) {\r\n super(values, model)\r\n this.model = model\r\n if (this.getDefaults) {\r\n this.set(this.getDefaults() || {})\r\n } else {\r\n this.set(this.defaults || {})\r\n }\r\n this.set(values)\r\n this._thumbs = []\r\n\r\n this.onMouseDown = this.onMouseDown.bind(this)\r\n this.onMouseMove = this.onMouseMove.bind(this)\r\n this.onMouseUp = this.onMouseUp.bind(this)\r\n this.bind('mousedown', this.onMouseDown)\r\n this.bind('mousemove', this.onMouseMove)\r\n this.bind('mouseup', this.onMouseUp)\r\n this.bind('change', () => {\r\n // elements is optional because this.model is not Pane in all usecases, e.g. base_chart extends this element and sets Chart as model\r\n const element = this.getIsChartEvent()\r\n ? this.model.chartEvents?.()?.findByAttribute('instance', this)\r\n : this.model.elements?.()?.findByAttribute('instance', this)\r\n\r\n element?.trigger('change', element)\r\n })\r\n }\r\n\r\n get type() {\r\n return (this.constructor as typeof Element).type\r\n }\r\n\r\n getThumbs() {\r\n return this._thumbs\r\n }\r\n\r\n moveBy(_: number, __: number) {}\r\n\r\n setIsEditInProgress(isEditInProgress: boolean, shouldTriggerChange = true) {\r\n this.isEditInProgress = isEditInProgress\r\n if (shouldTriggerChange) {\r\n this.trigger('change', this)\r\n }\r\n }\r\n\r\n setIsSelected(isSelected: boolean) {\r\n this.isSelected = isSelected\r\n this.trigger('change')\r\n }\r\n\r\n setIsHovered(isHovered: boolean) {\r\n this.isHovered = isHovered\r\n this.trigger('change')\r\n }\r\n\r\n getShouldRenderThumbs() {\r\n return this.isSelected || this.isHovered\r\n }\r\n\r\n getIsPaneSelection(): boolean {\r\n const paneModel = this.model.elements().findByAttribute('instance', this)?.pane() as PaneModel | undefined\r\n return paneModel?.selection === this\r\n }\r\n\r\n set(obj: Partial) {\r\n const attrsSubset = Object.keys(obj).reduce(\r\n (acc, key) => ({ ...acc, [key]: this.attrs[key] }),\r\n {} as Partial\r\n )\r\n if (JSON.stringify(obj) !== JSON.stringify(attrsSubset)) {\r\n const customizer = (objValue: Partial, srcValue: Partial, key: keyof Attrs) => {\r\n if (this.getIsDrawing() && key === 'visibility') {\r\n return srcValue ?? {}\r\n }\r\n }\r\n mergewith(this.attrs, obj, customizer)\r\n if (this.getIsPaneSelection() && !this.getIsCreator()) {\r\n this.cachePointPositionTimestamp()\r\n }\r\n this.trigger('change', this)\r\n }\r\n this.edgeXYValues = null\r\n return this\r\n }\r\n\r\n get(key: T) {\r\n return this.attrs[key]\r\n }\r\n\r\n getBoundingPointKeys = (): { x: string[]; y: string[] } | void => {}\r\n\r\n fx = (x: number) => this.model.scale.x(x)\r\n\r\n fy = (y: number) => this.model.scale.y(y)\r\n\r\n scale({ x, y }: { x: string[]; y: string[] }) {\r\n this.scaled = {}\r\n x.forEach((el) => {\r\n Object.defineProperty(this.scaled, el, {\r\n get: () => this.fx(this.attrs[el]),\r\n })\r\n })\r\n\r\n y.forEach((el) => {\r\n Object.defineProperty(this.scaled, el, {\r\n get: () => this.fy(this.attrs[el]),\r\n })\r\n })\r\n }\r\n\r\n render(_: RenderingContext2DType) {}\r\n\r\n renderThumbs(context: CanvasRenderingContext2D) {\r\n const isHoveredThumbStyle = this.isHovered && !this.isSelected\r\n if (isHoveredThumbStyle) {\r\n context.globalAlpha = 0.5\r\n }\r\n this.getThumbs().map((thumb) => thumb.render(context))\r\n context.globalAlpha = 1\r\n }\r\n\r\n onMouseDown(area: PaneArea) {\r\n this.isMouseDown = true\r\n this.setIsEditInProgress(true, false)\r\n for (const thumb of this.getThumbs()) {\r\n if (thumb.isInArea(area)) {\r\n this.activeThumb = thumb\r\n this.activeThumb.startEditing(area)\r\n return\r\n }\r\n }\r\n }\r\n\r\n onMouseMove(area: PaneArea) {\r\n if (!area.mouseDown) {\r\n return\r\n }\r\n if (this.activeThumb != null) {\r\n this.activeThumb.moveTo(area)\r\n this.trigger('change')\r\n }\r\n }\r\n\r\n onMouseUp(_?: PaneArea) {\r\n this.isMouseDown = false\r\n this.setIsEditInProgress(false, false)\r\n this.activeThumb = null\r\n if (!this.getIsCreator() && !this.getIsChartEvent()) {\r\n this.cachePointPositionTimestamp()\r\n }\r\n this.trigger('change', this)\r\n }\r\n\r\n cachePointPositionTimestamp = () => {\r\n const quote = this.model?.chart().quote()\r\n if (quote) {\r\n const { x: xPointKeys } = this.getBoundingPointKeys()!\r\n const positionTimestamps = xPointKeys.reduce((acc, key) => {\r\n const positionX = this.attrs[key]\r\n const timeStamp = positionX && quote.getTimestampFomPositionX(positionX)\r\n return {\r\n ...acc,\r\n [key]: timeStamp,\r\n }\r\n }, {}) as TodoPositionTimestamps\r\n this.set({ positionTimestamps } as Partial)\r\n }\r\n }\r\n\r\n updateScales() {\r\n const quote = this.model.chart().quote()\r\n const { positionTimestamps } = this.attrs\r\n if (!quote || !positionTimestamps) {\r\n // positionTimestamps check is temporary to prevent app from crashing\r\n // caused by corrupted drawings - https://github.com/finvizhq/charts/pull/1386/files\r\n return\r\n }\r\n const pointPoitionsFromTimestamp = Object.entries(positionTimestamps).reduce(\r\n (acc, [key, timestamp]) => ({\r\n ...acc,\r\n [key]: timestamp && quote.getPositionXFromTimestamp(timestamp),\r\n }),\r\n {}\r\n )\r\n this.set(pointPoitionsFromTimestamp)\r\n }\r\n\r\n thumbsAreInArea(area: PaneArea) {\r\n for (const thumb of this.getThumbs()) {\r\n if (thumb.isInArea(area)) {\r\n return true\r\n }\r\n }\r\n return false\r\n }\r\n\r\n isInArea(area: PaneArea) {\r\n return this.thumbsAreInArea(area)\r\n }\r\n\r\n isDrawingElementLockedOrInvisible() {\r\n return this.model.chart().chart_layout().isLockDrawingsActive || !this.getIsVisible()\r\n }\r\n\r\n getModalConfig() {\r\n let config\r\n if (this.getModalConfigBase) {\r\n config = merge({}, this.getModalConfigBase())\r\n } else {\r\n config = merge({}, this.modalConfig)\r\n }\r\n if (this.getIsDrawing()) {\r\n config.inputs.push({ type: 'visibility', name: 'visibility', label: 'Visibility' })\r\n }\r\n if (config.title == null) {\r\n config.title = this.name\r\n }\r\n for (const input of config.inputs) {\r\n if (input.default != null) {\r\n input.value = input.default\r\n }\r\n if (this.attrs[input.name] != null) {\r\n input.value = this.attrs[input.name]\r\n }\r\n }\r\n return config\r\n }\r\n\r\n toObject() {\r\n return merge({}, this.attrs, { type: this.type })\r\n }\r\n\r\n toConfig(): T['attrs'] & { type: T['type'] } {\r\n return this.toObject()\r\n }\r\n\r\n getAutosaveOmittedProperties() {\r\n return this.attrs.positionTimestamps ? Object.keys(this.attrs.positionTimestamps) : []\r\n }\r\n\r\n toAutosaveConfig() {\r\n // We don't want to save attrs which are stored in \"position timestamps\" because they are relative to timeframe for example\r\n // so in order to keep drawings in sync across different timeframes we can't rely on its position but we have to rely on \"position timestamps\" and then call updateScales to calculate correct positions for given timeframe\r\n return omit(this.toConfig(), this.getAutosaveOmittedProperties()) as Partial\r\n }\r\n\r\n replaceMyself(element: Element) {\r\n setTimeout(() => {\r\n element.cachePointPositionTimestamp()\r\n const el = this.model.elements().findByAttribute('instance', this)\r\n if (!el) {\r\n // Temporary code below\r\n // additional info gaining for https://finvizcom.sentry.io/issues/3990343438/events/e87ce8b4108341cf81f15ec78707c65e/?project=33153&query=is%3Aunresolved+Cannot+read+properties+of+undefined&referrer=previous-event&statsPeriod=14d&stream_index=0\r\n window.Sentry?.captureMessage('element.ts replaceMyself', {\r\n extra: {\r\n oldElement: {\r\n type: this?.type,\r\n isCreator: this?.isCreator,\r\n isMouseDown: this?.isMouseDown,\r\n isSelected: this?.isSelected,\r\n isHovered: this?.isHovered,\r\n isEditInProgress: this?.isEditInProgress,\r\n },\r\n newElement: {\r\n type: element?.type,\r\n isCreator: element?.isCreator,\r\n isMouseDown: element?.isMouseDown,\r\n isSelected: element?.isSelected,\r\n isHovered: element?.isHovered,\r\n isEditInProgress: element?.isEditInProgress,\r\n },\r\n },\r\n })\r\n } else {\r\n el.replace(element)\r\n }\r\n })\r\n }\r\n\r\n toString() {\r\n return this.name\r\n }\r\n\r\n getIsCreator() {\r\n return this.isCreator\r\n }\r\n\r\n getIsCreatorDialogOpen() {\r\n return this.isCreatorDialogOpen\r\n }\r\n\r\n release() {\r\n this.cachePointPositionTimestamp()\r\n this.unbind()\r\n }\r\n\r\n getChartLayoutSettings() {\r\n return getChartLayoutSettings(this.model.chart().chart_layout())\r\n }\r\n\r\n getIsDrawing() {\r\n return !!this.type.startsWith('canvas/')\r\n }\r\n\r\n getIsChartEvent() {\r\n return !!this?.type.startsWith('chartEvent/')\r\n }\r\n\r\n getIsVisible() {\r\n const { micro, macro } = MicroMacroTimeframe[this.model.chart().quote().timeframe as TIMEFRAME]\r\n const visibility = this.attrs.visibility?.[macro]\r\n\r\n // this.attrs.visibility.minutes === undefined: drawing visible on any minutes timeframe\r\n if (visibility === undefined) return true\r\n // this.attrs.visibility.minutes === {}: drawing invisible on any minutes timeframe\r\n if (Object.keys(visibility).length === 0) return false\r\n // this.attrs.visibility.minutes === {from: 5, to: 15}: drawing visible on minutes TF between 5 & 15 interval\r\n return isInRange({ value: micro, min: visibility.from, max: visibility.to })\r\n }\r\n\r\n setVisibilityTo(setTo: SetVisibilityTo) {\r\n const { macro, micro } = MicroMacroTimeframe[this.model.chart().quote().timeframe as TIMEFRAME]\r\n const currentIndex = Object.keys(MacroTimeframe).indexOf(macro)\r\n\r\n let timeframesToSet: string[] = []\r\n let attrsToSet: { from?: number; to?: number } = {}\r\n\r\n switch (setTo) {\r\n case SetVisibilityTo.currentAndAbove: {\r\n timeframesToSet = Object.keys(MacroTimeframe).filter((key, index) => index < currentIndex)\r\n attrsToSet = { from: micro }\r\n break\r\n }\r\n case SetVisibilityTo.currentAndBelow: {\r\n timeframesToSet = Object.keys(MacroTimeframe).filter((key, index) => index > currentIndex)\r\n attrsToSet = { to: micro }\r\n break\r\n }\r\n case SetVisibilityTo.currentOnly: {\r\n timeframesToSet = Object.keys(MacroTimeframe).filter((key, index) => index !== currentIndex)\r\n attrsToSet = { from: micro, to: micro }\r\n break\r\n }\r\n case SetVisibilityTo.all:\r\n default: {\r\n this.set({ visibility: {} } as Partial)\r\n return\r\n }\r\n }\r\n\r\n this.set({\r\n visibility: Object.assign({}, ...timeframesToSet.map((item) => ({ [item]: {} })), { [macro]: attrsToSet }),\r\n } as Partial)\r\n }\r\n\r\n getEdgeXYValues() {\r\n const { x: xPoints, y: yPoints } = this.getBoundingPointKeys() ?? {}\r\n if (this.edgeXYValues === null) {\r\n const edgeXYValues = {} as EdgeValues\r\n xPoints?.forEach((key) => {\r\n const positionX = this.attrs[key]\r\n if (positionX !== undefined) {\r\n edgeXYValues.minX = Math.min(positionX, edgeXYValues.minX ?? positionX)\r\n edgeXYValues.maxX = Math.max(positionX, edgeXYValues.maxX ?? positionX)\r\n }\r\n })\r\n yPoints?.forEach((key) => {\r\n const positionY = this.attrs[key]\r\n if (positionY !== undefined) {\r\n edgeXYValues.minY = Math.min(positionY, edgeXYValues.minY ?? positionY)\r\n edgeXYValues.maxY = Math.max(positionY, edgeXYValues.maxY ?? positionY)\r\n }\r\n })\r\n\r\n this.edgeXYValues = edgeXYValues\r\n }\r\n\r\n return this.edgeXYValues\r\n }\r\n\r\n getIsInChartView(chart: Chart, options?: { omitX?: boolean; omitY?: boolean }) {\r\n const { minX, maxX, minY, maxY } = this.getEdgeXYValues()\r\n\r\n if (this.getIsCreator()) {\r\n return true\r\n }\r\n\r\n if (!options?.omitX) {\r\n const isMaxXInvalid = maxX === undefined || isNaN(maxX)\r\n const isMinXInvalid = minX === undefined || isNaN(minX)\r\n if (\r\n !isMaxXInvalid &&\r\n !isMinXInvalid &&\r\n !(this.fx(maxX) >= -chart.leftOffset && this.fx(minX) <= -chart.leftOffset + chart.width)\r\n ) {\r\n return false\r\n }\r\n }\r\n\r\n if (!options?.omitY) {\r\n if (minY === undefined || maxY === undefined) {\r\n return true\r\n }\r\n\r\n const topBound = this.model.scale.y.invert(0)\r\n const bottomBound = this.model.scale.y.invert(this.model.height)\r\n return topBound >= minY && bottomBound <= maxY\r\n }\r\n\r\n // If all checks fall through, render element\r\n return true\r\n }\r\n}\r\n\r\nexport default Element\r\n","import { DrawingBorder, PaneArea, ResizeByThumbWithTypeAndDifs } from '../../../types/shared'\r\nimport { CanvasElementType, TextAlign, TextBaseline } from '../../constants/common'\r\nimport { getOffsetFromLineWidth } from '../../controllers/renderUtils'\r\nimport math from '../../helpers/math'\r\nimport PaneModel from '../../models/pane'\r\nimport Element from '../element'\r\nimport Text from '../text'\r\nimport Thumb from '../thumb'\r\n\r\nexport interface IElliottWavesAttrs {\r\n waves: Array<{ x: number; y: number }>\r\n positionWavesTimestamps?: Array<{ x: number; y: number }>\r\n border: DrawingBorder\r\n}\r\n\r\nclass ElliottWaves extends Element {\r\n static type = CanvasElementType.elliottWaves\r\n\r\n name = 'Elliott Wave'\r\n waves = ['', 'I', 'II', 'III', 'IV', 'V']\r\n\r\n constructor(values: Partial, model: PaneModel) {\r\n super(values, model)\r\n this.resize = this.resize.bind(this)\r\n }\r\n\r\n getDefaults() {\r\n return {\r\n border: {\r\n width: 2,\r\n color: this.getChartLayoutSettings().ElementSettings.Colors.line,\r\n },\r\n } as Partial\r\n }\r\n\r\n renderContent(context: CanvasRenderingContext2D) {\r\n const offset = getOffsetFromLineWidth(this.attrs.border.width)\r\n context.set('lineWidth', this.attrs.border.width)\r\n context.set('strokeStyle', this.attrs.border.color)\r\n\r\n context.translate(offset, offset)\r\n context.beginPath()\r\n context.moveTo(Math.round(this.fx(this.attrs.waves[0].x)), Math.round(this.fy(this.attrs.waves[0].y)))\r\n for (const p of this.attrs.waves.slice(1)) {\r\n context.lineTo(Math.round(this.fx(p.x)), Math.round(this.fy(p.y)))\r\n }\r\n context.stroke()\r\n context.translate(offset * -1, offset * -1)\r\n\r\n const text = new Text(\r\n {\r\n font: { size: 8, style: 'bold' },\r\n textBaseline: TextBaseline.middle,\r\n textAlign: TextAlign.center,\r\n fillStyle: this.getChartLayoutSettings().ElementSettings.Colors.textWithoutBackground,\r\n },\r\n this.model\r\n )\r\n for (let i = 0; i < this.attrs.waves.length; i++) {\r\n let y\r\n const p = this.attrs.waves[i]\r\n if (i > 0 && this.attrs.waves[i - 1].y > p.y) {\r\n y = this.fy(p.y) + 8\r\n } else {\r\n y = this.fy(p.y) - 8\r\n }\r\n text.set({ text: this.waves[i], x: this.fx(p.x), y })\r\n text.render(context)\r\n }\r\n\r\n if (this.getShouldRenderThumbs()) {\r\n this.renderThumbs(context)\r\n }\r\n }\r\n\r\n getThumbs() {\r\n return this.attrs.waves.map(\r\n (wave, index) =>\r\n new Thumb(\r\n `${index}`,\r\n () => wave.x,\r\n () => wave.y,\r\n this.resize,\r\n this.model\r\n )\r\n )\r\n }\r\n\r\n cachePointPositionTimestamp = () => {\r\n const quote = this.model?.chart().quote()\r\n if (quote) {\r\n const positionWavesTimestamps = this.attrs.waves.map((wave) => ({\r\n ...wave,\r\n x: quote.getTimestampFomPositionX(wave.x),\r\n }))\r\n\r\n this.set({ positionWavesTimestamps } as Partial)\r\n }\r\n }\r\n\r\n updateScales() {\r\n const quote = this.model.chart().quote()\r\n const { positionWavesTimestamps } = this.attrs\r\n if (!quote || !positionWavesTimestamps) {\r\n // positionWavesTimestamps check is temporary to prevent app from crashing\r\n // caused by corrupted drawings - https://github.com/finvizhq/charts/pull/1386/files\r\n return\r\n }\r\n const waves = positionWavesTimestamps.map((wave) => ({\r\n ...wave,\r\n x: quote.getPositionXFromTimestamp(wave.x),\r\n }))\r\n this.set({ waves } as Partial)\r\n }\r\n\r\n moveBy(x: number, y: number) {\r\n for (const point of this.attrs.waves) {\r\n point.x += x\r\n point.y += y\r\n }\r\n }\r\n\r\n resize({ type, difX, difY }: ResizeByThumbWithTypeAndDifs) {\r\n this.attrs.waves[+type].x += difX\r\n this.attrs.waves[+type].y += difY\r\n }\r\n\r\n isInArea(area: PaneArea) {\r\n if (super.isDrawingElementLockedOrInvisible()) return false\r\n const waves = this.attrs.waves\r\n for (let i = 0; i < waves.length - 1; i++) {\r\n if (\r\n math.distanceToSegment(area.scaled, {\r\n x1: this.fx(waves[i].x),\r\n y1: this.fy(waves[i].y),\r\n x2: this.fx(waves[i + 1].x),\r\n y2: this.fy(waves[i + 1].y),\r\n }) <= 10\r\n ) {\r\n return true\r\n }\r\n }\r\n return super.isInArea(area)\r\n }\r\n\r\n getAutosaveOmittedProperties() {\r\n return ['waves']\r\n }\r\n}\r\n\r\nElliottWaves.prototype.modalConfig = {\r\n inputs: [{ type: 'line', name: 'border' }],\r\n}\r\n\r\nexport default ElliottWaves\r\n","import { DrawingBorder, PaneArea, Point, ResizeByThumbWithTypeAndDifs } from '../../../types/shared'\r\nimport { CanvasElementType } from '../../constants/common'\r\nimport math from '../../helpers/math'\r\nimport PaneModel from '../../models/pane'\r\nimport { getContextWithCache } from '../../utils/canvas'\r\nimport Element from '../element'\r\nimport Thumb from '../thumb'\r\n\r\nexport interface IEllipseAttrs {\r\n x1: number\r\n x2: number\r\n y1: number\r\n y2: number\r\n cursorTargetX: number\r\n cursorTargetY: number\r\n\r\n fill: string\r\n border: DrawingBorder\r\n}\r\n\r\ninterface Coordinates {\r\n P1: Point\r\n P2: Point\r\n P3: Point\r\n P4: Point\r\n CP1: Point\r\n CP2: Point\r\n CP3: Point\r\n CP4: Point\r\n}\r\n\r\nclass EllipseV1 extends Element {\r\n static type = CanvasElementType.ellipseV1\r\n\r\n name = 'Ellipse'\r\n\r\n untranslatedContext: CanvasRenderingContext2D | null = null\r\n declare ellipsePath: Path2D\r\n declare scaled: Pick\r\n\r\n constructor(values: Partial, model: PaneModel) {\r\n super(values, model)\r\n this.resize = this.resize.bind(this)\r\n this.untranslatedContext = getContextWithCache(document.createElement('canvas'))\r\n this._thumbs = [\r\n new Thumb(\r\n 'left',\r\n () => this.attrs.x1,\r\n () => this.attrs.y1,\r\n this.resize,\r\n this.model\r\n ),\r\n new Thumb(\r\n 'right',\r\n () => this.attrs.x2,\r\n () => this.attrs.y2,\r\n this.resize,\r\n this.model\r\n ),\r\n new Thumb(\r\n 'top',\r\n () => this.getEllipsePoints(true).P2.x || this.attrs.x1,\r\n () => this.getEllipsePoints(true).P2.y || this.attrs.y1,\r\n this.resize,\r\n this.model\r\n ),\r\n new Thumb(\r\n 'bottom',\r\n () => this.getEllipsePoints(true).P4.x || this.attrs.x2,\r\n () => this.getEllipsePoints(true).P4.y || this.attrs.y2,\r\n this.resize,\r\n this.model\r\n ),\r\n ]\r\n this.scale(this.getBoundingPointKeys())\r\n }\r\n\r\n getDefaults() {\r\n const { ElementSettings } = this.getChartLayoutSettings()\r\n return {\r\n fill: ElementSettings.defaultFill,\r\n border: {\r\n width: 1,\r\n color: ElementSettings.Colors.border,\r\n },\r\n } as Partial\r\n }\r\n\r\n getBoundingPointKeys = () => ({ x: ['x1', 'x2', 'cursorTargetX'], y: ['y1', 'y2', 'cursorTargetY'] })\r\n\r\n renderContent(context: CanvasRenderingContext2D) {\r\n const coordinates = this.getEllipsePoints() as Coordinates\r\n const ellipse = new Path2D()\r\n context.set('fillStyle', this.attrs.fill)\r\n context.beginPath()\r\n if (coordinates.P2.x === coordinates.P3.x || coordinates.P2.y === coordinates.P3.y) {\r\n ellipse.lineTo(coordinates.P1.x, coordinates.P1.y)\r\n ellipse.lineTo(coordinates.P2.x, coordinates.P2.y)\r\n } else {\r\n ellipse.moveTo(coordinates.P4.x, coordinates.P4.y)\r\n ellipse.bezierCurveTo(\r\n coordinates.CP4.x,\r\n coordinates.CP4.y,\r\n coordinates.CP1.x,\r\n coordinates.CP1.y,\r\n coordinates.P2.x,\r\n coordinates.P2.y\r\n )\r\n ellipse.bezierCurveTo(\r\n coordinates.CP2.x,\r\n coordinates.CP2.y,\r\n coordinates.CP3.x,\r\n coordinates.CP3.y,\r\n coordinates.P4.x,\r\n coordinates.P4.y\r\n )\r\n ellipse.closePath()\r\n this.ellipsePath = ellipse\r\n context.fill(ellipse)\r\n }\r\n\r\n context.set('lineWidth', this.attrs.border.width)\r\n context.set('strokeStyle', this.attrs.border.color)\r\n context.stroke(ellipse)\r\n\r\n if (this.getShouldRenderThumbs()) {\r\n this.renderThumbs(context)\r\n }\r\n }\r\n\r\n getEllipsePoints(inverted = false) {\r\n const { x1, x2, y1, y2, cursorTargetX, cursorTargetY } = this.scaled\r\n\r\n const P1 = { x: x2, y: y2 }\r\n const P3 = { x: x1, y: y1 }\r\n\r\n let perpendicularPoint\r\n if (!isNaN(cursorTargetX) && !isNaN(cursorTargetY)) {\r\n const cursor = { x: cursorTargetX, y: cursorTargetY }\r\n const line = { x1, y1, x2, y2 }\r\n const distance = math.distanceToLine(cursor, line)\r\n perpendicularPoint = math.perpendicularPointToLine({\r\n distance,\r\n line,\r\n })\r\n } else {\r\n return {\r\n P1: P3,\r\n P2: P1,\r\n P3: P1,\r\n P4: P3,\r\n }\r\n }\r\n\r\n const lineCenterX = (P1.x + P3.x) / 2\r\n const lineCenterY = (P1.y + P3.y) / 2\r\n const pointOffsetX = perpendicularPoint.x - P1.x\r\n const pointOffsetY = perpendicularPoint.y - P1.y\r\n\r\n const P2 = { x: lineCenterX + pointOffsetX, y: lineCenterY + pointOffsetY }\r\n const P4 = { x: lineCenterX + -1 * pointOffsetX, y: lineCenterY + -1 * pointOffsetY }\r\n const invertX = this.model.scale.x.invert\r\n const invertY = this.model.scale.y.invert\r\n if (inverted) {\r\n return {\r\n P2: { x: invertX(P2.x), y: invertY(P2.y) },\r\n P4: { x: invertX(P4.x), y: invertY(P4.y) },\r\n }\r\n }\r\n\r\n const perpendicularPointEllipseOffsetX = (perpendicularPoint.x - P2.x) / 0.75 - (perpendicularPoint.x - P2.x)\r\n const perpendicularPointEllipseOffsetY = (perpendicularPoint.y - P2.y) / 0.75 - (perpendicularPoint.y - P2.y)\r\n\r\n const P1WithOffsetX = P1.x + perpendicularPointEllipseOffsetX\r\n const P1WithOffsetY = P1.y + perpendicularPointEllipseOffsetY\r\n\r\n const P3WithOffsetX = P3.x - perpendicularPointEllipseOffsetX\r\n const P3WithOffsetY = P3.y - perpendicularPointEllipseOffsetY\r\n\r\n const CP1 = {\r\n x: perpendicularPoint.x + perpendicularPointEllipseOffsetX,\r\n y: perpendicularPoint.y + perpendicularPointEllipseOffsetY,\r\n }\r\n const controlPointOffsetX = CP1.x - P1WithOffsetX\r\n const controlPointOffsetY = CP1.y - P1WithOffsetY\r\n\r\n const CP2 = { x: P3WithOffsetX + controlPointOffsetX, y: P3WithOffsetY + controlPointOffsetY }\r\n const CP3 = { x: P3WithOffsetX + -1 * controlPointOffsetX, y: P3WithOffsetY + -1 * controlPointOffsetY }\r\n const CP4 = { x: P1WithOffsetX + -1 * controlPointOffsetX, y: P1WithOffsetY + -1 * controlPointOffsetY }\r\n\r\n return {\r\n P1,\r\n P2,\r\n P3,\r\n P4,\r\n CP1,\r\n CP2,\r\n CP3,\r\n CP4,\r\n }\r\n }\r\n\r\n getRotatedPointCoordinates = ({\r\n rotationAxisPoint,\r\n pointToRotate,\r\n oldLinePoint,\r\n newLinePoint,\r\n }: {\r\n rotationAxisPoint: { x: number; y: number }\r\n pointToRotate: { x: number; y: number }\r\n oldLinePoint: { x: number; y: number }\r\n newLinePoint: { x: number; y: number }\r\n }) => {\r\n const angle = math.sharedPointLinesAngle({\r\n sharedPoint: rotationAxisPoint,\r\n oldLinePoint,\r\n newLinePoint,\r\n })\r\n const rotatedPoinCoordinates = math.rotatedPointCoordinates({\r\n rotationAxisPoint,\r\n angle,\r\n pointToRotate,\r\n })\r\n return {\r\n x: this.model.scale.x.invert(rotatedPoinCoordinates.x),\r\n y: this.model.scale.y.invert(rotatedPoinCoordinates.y),\r\n }\r\n }\r\n\r\n moveBy(x: number, y: number) {\r\n this.attrs.x1 += x\r\n this.attrs.y1 += y\r\n this.attrs.x2 += x\r\n this.attrs.y2 += y\r\n this.attrs.cursorTargetX += x\r\n this.attrs.cursorTargetY += y\r\n }\r\n\r\n resize({ type, difX, difY, area }: ResizeByThumbWithTypeAndDifs) {\r\n switch (type) {\r\n case 'left':\r\n const newLeftPoint = {\r\n x: this.attrs.x1 + difX,\r\n y: this.attrs.y1 + difY,\r\n }\r\n const leftRotatedCursorPoint = this.getRotatedPointCoordinates({\r\n rotationAxisPoint: { x: this.scaled.x2, y: this.scaled.y2 },\r\n pointToRotate: {\r\n x: this.scaled.cursorTargetX,\r\n y: this.scaled.cursorTargetY,\r\n },\r\n oldLinePoint: { x: this.scaled.x1, y: this.scaled.y1 },\r\n newLinePoint: { x: this.model.scale.x(newLeftPoint.x), y: this.model.scale.y(newLeftPoint.y) },\r\n })\r\n this.attrs = {\r\n ...this.attrs,\r\n x1: newLeftPoint.x,\r\n y1: newLeftPoint.y,\r\n cursorTargetX: leftRotatedCursorPoint.x,\r\n cursorTargetY: leftRotatedCursorPoint.y,\r\n }\r\n break\r\n case 'right':\r\n const newRightPoint = {\r\n x: this.attrs.x2 + difX,\r\n y: this.attrs.y2 + difY,\r\n }\r\n const rightRotatedCursorPoint = this.getRotatedPointCoordinates({\r\n rotationAxisPoint: { x: this.scaled.x1, y: this.scaled.y1 },\r\n pointToRotate: {\r\n x: this.scaled.cursorTargetX,\r\n y: this.scaled.cursorTargetY,\r\n },\r\n oldLinePoint: { x: this.scaled.x2, y: this.scaled.y2 },\r\n newLinePoint: { x: this.model.scale.x(newRightPoint.x), y: this.model.scale.y(newRightPoint.y) },\r\n })\r\n this.attrs = {\r\n ...this.attrs,\r\n x2: newRightPoint.x,\r\n y2: newRightPoint.y,\r\n cursorTargetX: rightRotatedCursorPoint.x,\r\n cursorTargetY: rightRotatedCursorPoint.y,\r\n }\r\n break\r\n case 'top':\r\n case 'bottom':\r\n this.attrs = {\r\n ...this.attrs,\r\n cursorTargetX: area.x,\r\n cursorTargetY: area.y,\r\n }\r\n break\r\n default:\r\n break\r\n }\r\n }\r\n\r\n isInArea(area: PaneArea) {\r\n if (super.isDrawingElementLockedOrInvisible()) return false\r\n if (this.ellipsePath && this.untranslatedContext?.isPointInPath(this.ellipsePath, area.scaled.x, area.scaled.y)) {\r\n return true\r\n }\r\n return super.isInArea(area)\r\n }\r\n\r\n getIsInChartView() {\r\n return true\r\n }\r\n}\r\n\r\nEllipseV1.prototype.modalConfig = {\r\n inputs: [\r\n { type: 'background', name: 'fill' },\r\n { type: 'border', name: 'border', min: 1, default: {} },\r\n ],\r\n}\r\n\r\nexport default EllipseV1\r\n","import { DrawingBorder, PaneArea, ResizeByThumbWithTypeAndDifs } from '../../types/shared'\r\nimport { CanvasElementType, TextAlign, TextBaseline } from '../constants/common'\r\nimport { getRoundedObject, getXYOffsetFromLine } from '../controllers/renderUtils'\r\nimport PaneModel from '../models/pane'\r\nimport Element from './element'\r\nimport Text, { ITextAttrs } from './text'\r\nimport Thumb from './thumb'\r\n\r\ntype Coefficients = string\r\n\r\nexport interface IFibonacciRetracementsAttrs {\r\n x1: number\r\n x2: number\r\n y1: number\r\n y2: number\r\n coefficients: Coefficients\r\n border: DrawingBorder\r\n}\r\n\r\nclass FibonacciRetracements<\r\n Attrs extends IFibonacciRetracementsAttrs = IFibonacciRetracementsAttrs,\r\n> extends Element {\r\n static type = CanvasElementType.fibonacciRetracements\r\n\r\n name = 'Fibonacci Retracements'\r\n declare coefficients: { default: string; parsed: number[]; max: number; min: number }\r\n declare scaled: Pick\r\n\r\n constructor(values: Partial, model: PaneModel) {\r\n super(values, model)\r\n this.resize = this.resize.bind(this)\r\n this._thumbs = [\r\n new Thumb(\r\n 'oneCoefficient_1',\r\n () => this.attrs.x1,\r\n () => this.attrs.y1,\r\n this.resize,\r\n this.model\r\n ),\r\n new Thumb(\r\n 'oneCoefficient_2',\r\n () => this.attrs.x2,\r\n () => this.attrs.y1,\r\n this.resize,\r\n this.model\r\n ),\r\n new Thumb(\r\n 'zeroCoefficient_1',\r\n () => this.attrs.x1,\r\n () => this.attrs.y2,\r\n this.resize,\r\n this.model\r\n ),\r\n new Thumb(\r\n 'zeroCoefficient_2',\r\n () => this.attrs.x2,\r\n () => this.attrs.y2,\r\n this.resize,\r\n this.model\r\n ),\r\n ]\r\n this.parseCoefficients(this.attrs.coefficients)\r\n this.scale(this.getBoundingPointKeys())\r\n }\r\n\r\n getDefaults() {\r\n return {\r\n border: {\r\n width: 1,\r\n color: this.getChartLayoutSettings().ElementSettings.Colors.line,\r\n },\r\n coefficients: [0, 0.236, 0.382, 0.5, 0.618, 1].toString(),\r\n } as Partial\r\n }\r\n\r\n getBoundingPointKeys = () => ({ x: ['x1', 'x2'], y: ['y1', 'y2'] })\r\n\r\n parseCoefficients(coefficients: Coefficients) {\r\n if (!this.coefficients || coefficients !== this.coefficients.default) {\r\n const parsed = coefficients.split(',').map((x) => parseFloat(x.trim()))\r\n this.coefficients = { default: coefficients, parsed, max: Math.max(...parsed), min: Math.min(...parsed) }\r\n }\r\n }\r\n\r\n getMaxCoefficientUnscaledY() {\r\n return this.model.scale.y.invert(this.scaled.y2 - this.coefficients.max * (this.scaled.y2 - this.scaled.y1))\r\n }\r\n\r\n getMinCoefficientUnscaledY() {\r\n return this.model.scale.y.invert(this.scaled.y2 - this.coefficients.min * (this.scaled.y2 - this.scaled.y1))\r\n }\r\n\r\n renderContent(context: CanvasRenderingContext2D) {\r\n const { x1, x2, y1, y2 } = this.scaled\r\n const roundedXY = getRoundedObject({ x1, x2, y1, y2 })\r\n const translateXY = getXYOffsetFromLine({ lineWidth: this.attrs.border.width, ...roundedXY, y2: roundedXY.y1 })\r\n\r\n context.set('lineWidth', this.attrs.border.width)\r\n context.set('strokeStyle', this.attrs.border.color)\r\n this.parseCoefficients(this.attrs.coefficients)\r\n\r\n const height = this.attrs.y2 - this.attrs.y1\r\n\r\n context.translate(translateXY.x, translateXY.y)\r\n context.beginPath()\r\n for (const p of this.coefficients.parsed) {\r\n const y = Math.round(this.fy(this.attrs.y2 - p * height))\r\n context.moveTo(roundedXY.x1, y)\r\n context.lineTo(roundedXY.x2, y)\r\n }\r\n context.stroke()\r\n context.translate(translateXY.x * -1, translateXY.y * -1)\r\n\r\n const text = new Text(\r\n {\r\n x: roundedXY.x1,\r\n font: { size: 8, style: 'bold' },\r\n textBaseline: TextBaseline.bottom,\r\n fillStyle: this.attrs.border.color,\r\n textAlign: TextAlign.left,\r\n },\r\n this.model\r\n )\r\n if (roundedXY.x1 > roundedXY.x2) {\r\n text.set({ textAlign: TextAlign.right })\r\n }\r\n\r\n for (const p of this.coefficients.parsed) {\r\n const y = this.attrs.y2 - p * height\r\n text.set({\r\n text: (p * 100).toFixed(1) + '%: ' + y.toFixed(2),\r\n y: Math.round(this.fy(y) - this.attrs.border.width / 2),\r\n } as Partial)\r\n text.render(context)\r\n }\r\n\r\n if (this.getShouldRenderThumbs()) {\r\n this.renderThumbs(context)\r\n }\r\n }\r\n\r\n getThumbs() {\r\n if (this.coefficients.max > 1 && !this._thumbs.some(({ type }) => type.includes('maxCoefficient'))) {\r\n this._thumbs = [\r\n ...this._thumbs,\r\n new Thumb(\r\n 'maxCoefficient_1',\r\n () => this.attrs.x1,\r\n () => this.getMaxCoefficientUnscaledY(),\r\n this.resize,\r\n this.model\r\n ),\r\n new Thumb(\r\n 'maxCoefficient_2',\r\n () => this.attrs.x2,\r\n () => this.getMaxCoefficientUnscaledY(),\r\n this.resize,\r\n this.model\r\n ),\r\n ]\r\n }\r\n if (this.coefficients.max <= 1 && this._thumbs.some(({ type }) => type.includes('maxCoefficient'))) {\r\n this._thumbs = this._thumbs.filter(({ type }) => !type.includes('maxCoefficient'))\r\n }\r\n\r\n if (this.coefficients.min < 0 && !this._thumbs.some(({ type }) => type.includes('minCoefficient'))) {\r\n this._thumbs = [\r\n ...this._thumbs,\r\n new Thumb(\r\n 'minCoefficient_1',\r\n () => this.attrs.x1,\r\n () => this.getMinCoefficientUnscaledY(),\r\n this.resize,\r\n this.model\r\n ),\r\n new Thumb(\r\n 'minCoefficient_2',\r\n () => this.attrs.x2,\r\n () => this.getMinCoefficientUnscaledY(),\r\n this.resize,\r\n this.model\r\n ),\r\n ]\r\n }\r\n if (this.coefficients.min >= 0 && this._thumbs.some(({ type }) => type.includes('minCoefficient'))) {\r\n this._thumbs = this._thumbs.filter(({ type }) => !type.includes('minCoefficient'))\r\n }\r\n\r\n return this._thumbs\r\n }\r\n\r\n moveBy(x: number, y: number) {\r\n this.attrs.x1 += x\r\n this.attrs.x2 += x\r\n this.attrs.y1 += y\r\n this.attrs.y2 += y\r\n }\r\n\r\n resize({ type, difX, difY }: ResizeByThumbWithTypeAndDifs) {\r\n switch (type) {\r\n case 'oneCoefficient_1':\r\n this.attrs.x1 += difX\r\n this.attrs.y1 += difY\r\n break\r\n case 'oneCoefficient_2':\r\n this.attrs.x2 += difX\r\n this.attrs.y1 += difY\r\n break\r\n case 'zeroCoefficient_1':\r\n this.attrs.x1 += difX\r\n this.attrs.y2 += difY\r\n break\r\n case 'zeroCoefficient_2':\r\n this.attrs.x2 += difX\r\n this.attrs.y2 += difY\r\n break\r\n case 'maxCoefficient_1':\r\n this.attrs.x1 += difX\r\n this.attrs.y1 += difY / this.coefficients.max\r\n break\r\n case 'maxCoefficient_2':\r\n this.attrs.x2 += difX\r\n this.attrs.y1 += difY / this.coefficients.max\r\n break\r\n case 'minCoefficient_1':\r\n this.attrs.x1 += difX\r\n this.attrs.y2 += difY / (Math.abs(this.coefficients.min) + 1)\r\n break\r\n case 'minCoefficient_2':\r\n this.attrs.x2 += difX\r\n this.attrs.y2 += difY / (Math.abs(this.coefficients.min) + 1)\r\n break\r\n default:\r\n break\r\n }\r\n }\r\n\r\n isInArea(area: PaneArea) {\r\n if (super.isDrawingElementLockedOrInvisible()) return false\r\n const maxCoefficientY = this.coefficients.max > 1 && this.getMaxCoefficientUnscaledY()\r\n const minCoefficientY = this.coefficients.min < 0 && this.getMinCoefficientUnscaledY()\r\n const left = Math.min(this.attrs.x1, this.attrs.x2)\r\n const right = Math.max(this.attrs.x1, this.attrs.x2)\r\n const allYValues = [this.attrs.y1, this.attrs.y2, maxCoefficientY, minCoefficientY].filter((item) => item !== false)\r\n const top = Math.min(...allYValues)\r\n const bottom = Math.max(...allYValues)\r\n\r\n if (left < area.x && area.x < right && top < area.y && area.y < bottom) {\r\n return true\r\n }\r\n return super.isInArea(area)\r\n }\r\n\r\n getEdgeXYValues() {\r\n this.edgeXYValues = super.getEdgeXYValues()\r\n\r\n // Because minY, maxY can go outside of control points boundaries [0,1] we need to compensate\r\n // for that in getEdgeXYValues(), otherwise getIsInChartView() hide drawings sooner than it should\r\n const min = this.getMinCoefficientUnscaledY()\r\n const max = this.getMaxCoefficientUnscaledY()\r\n\r\n if (!isNaN(min) && !isNaN(max)) {\r\n this.edgeXYValues.minY = Math.min(min, max)\r\n this.edgeXYValues.maxY = Math.max(min, max)\r\n }\r\n\r\n return this.edgeXYValues\r\n }\r\n}\r\n\r\nFibonacciRetracements.prototype.modalConfig = {\r\n inputs: [\r\n { type: 'line', name: 'border' },\r\n { type: 'string', name: 'coefficients', label: 'Coefficients' },\r\n ],\r\n}\r\n\r\nexport default FibonacciRetracements\r\n","import { Maybe, RequireByKey, ResizeByThumbFuncProps } from '../../types/shared'\r\nimport { CanvasElementType, TextBaseline } from '../constants/common'\r\nimport math from '../helpers/math'\r\nimport Chart from '../models/chart'\r\nimport PaneModel from '../models/pane'\r\nimport ScaledLine, { IScaledLineAttrs } from './scaled_line'\r\nimport Text from './text'\r\n\r\nconst DEFAULT_DECIMAL_PLACES = 2\r\n\r\nclass HorizontalLine extends ScaledLine {\r\n static type = CanvasElementType.horizontalLine\r\n\r\n name = 'Horizontal line'\r\n decimalPlaces = DEFAULT_DECIMAL_PLACES\r\n declare scaled: Pick\r\n declare model: PaneModel\r\n\r\n constructor(values: Partial, model: PaneModel) {\r\n super(values, model)\r\n\r\n this.updateDecimalPlaces()\r\n\r\n if (this.attrs.y1) {\r\n this.attrs.y1 = Number(math.round({ value: this.attrs.y1, overridePlaces: this.decimalPlaces }))\r\n }\r\n if (this.modalConfig) {\r\n const step = `0.${'0'.repeat(this.decimalPlaces - 1)}1`\r\n this.modalConfig.inputs[1] = {\r\n ...this.modalConfig.inputs[1],\r\n step,\r\n min: Number(step),\r\n }\r\n }\r\n this.renderContent = this.renderContent.bind(this)\r\n this._thumbs = []\r\n }\r\n\r\n getBoundingPointKeys = () => ({ x: ['x1', 'x2'], y: ['y1', 'y2'] })\r\n\r\n updateDecimalPlaces() {\r\n const quote = this.model.chart().quote()\r\n this.decimalPlaces = quote\r\n ? math.getInstrumentDecimalPlaces({\r\n instrument: quote.instrument,\r\n value: quote.lastClose,\r\n })\r\n : DEFAULT_DECIMAL_PLACES\r\n }\r\n\r\n renderContent(context: CanvasRenderingContext2D) {\r\n const { ChartSettings } = this.getChartLayoutSettings()\r\n this.attrs.y2 = this.attrs.y1\r\n // mixing scaled and unscaled values, do not copy paste as solution\r\n this.attrs.x1 = ChartSettings.left.width * -1\r\n this.attrs.x2 =\r\n this.model\r\n .chart()\r\n .quote()\r\n .getBarIndex(this.model.chart().quote().close.length - 1) + this.model.chart().width\r\n super.renderContent(context)\r\n }\r\n\r\n renderLabels(context: CanvasRenderingContext2D) {\r\n if (this.attrs.y1) {\r\n this.updateDecimalPlaces()\r\n const { ChartSettings, IndicatorSettings } = this.getChartLayoutSettings()\r\n const isIndicatorPane = this.model\r\n .elements()\r\n .all()\r\n .some((element) => element.isIndicator())\r\n const settings = isIndicatorPane ? IndicatorSettings : ChartSettings\r\n context.translate(this.model.chart().width - settings.right.width, settings.top.height)\r\n new Text(\r\n {\r\n x: 6,\r\n y: this.scaled.y1,\r\n font: { size: 8, style: 'bold' },\r\n lineHeight: 8,\r\n padding: {\r\n top: 2,\r\n right: 2,\r\n bottom: 2,\r\n left: 2,\r\n },\r\n fillStyle: '#fff',\r\n background: '#000',\r\n textBaseline: TextBaseline.middle,\r\n text: this.attrs.y1.toFixed(this.decimalPlaces).toString(),\r\n },\r\n this.model\r\n ).render(context)\r\n }\r\n }\r\n\r\n moveBy(x: Maybe, y: number) {\r\n this.attrs.y1 += y\r\n }\r\n\r\n resize({ difY }: RequireByKey) {\r\n this.moveBy(0, difY)\r\n }\r\n\r\n getIsInChartView(chart: Chart) {\r\n return super.getIsInChartView(chart, { omitX: true })\r\n }\r\n}\r\n\r\nHorizontalLine.prototype.modalConfig = {\r\n inputs: [\r\n { type: 'line', name: 'border' },\r\n { type: 'number', name: 'y1', label: 'Price', allowDecimal: true },\r\n ],\r\n}\r\n\r\nexport default HorizontalLine\r\n","import { PaneArea, ResizeByThumbWithTypeAndDifs } from '../../types/shared'\r\nimport { CanvasElementType } from '../constants/common'\r\nimport { getRoundedObject, getXYOffsetFromLine } from '../controllers/renderUtils'\r\nimport math from '../helpers/math'\r\nimport PaneModel from '../models/pane'\r\nimport Element from './element'\r\nimport Thumb from './thumb'\r\n\r\ninterface ILineAttrs {\r\n x1: number\r\n x2: number\r\n y1: number\r\n y2: number\r\n dashLength: number\r\n lineWidth: number\r\n strokeStyle: string\r\n}\r\n\r\nclass Line extends Element {\r\n static type = CanvasElementType.line\r\n\r\n constructor(values: Partial, model: PaneModel) {\r\n super(values, model)\r\n this.render = this.render.bind(this)\r\n this.resize = this.resize.bind(this)\r\n this._thumbs = [\r\n new Thumb(\r\n 'l',\r\n () => this.attrs.x1,\r\n () => this.attrs.y1,\r\n this.resize,\r\n this.model\r\n ),\r\n new Thumb(\r\n 'r',\r\n () => this.attrs.x2,\r\n () => this.attrs.y2,\r\n this.resize,\r\n this.model\r\n ),\r\n ]\r\n }\r\n\r\n getDefaults() {\r\n return {\r\n lineWidth: 1,\r\n strokeStyle: this.getChartLayoutSettings().ElementSettings.Colors.line,\r\n } as Partial\r\n }\r\n\r\n getBoundingPointKeys = () => ({ x: ['x1', 'x2'], y: ['y1', 'y2'] })\r\n\r\n render(context: CanvasRenderingContext2D) {\r\n const { x1, y1, x2, y2, lineWidth } = this.attrs\r\n const roundedXY = getRoundedObject({ x1, y1, x2, y2 })\r\n const translateXY = getXYOffsetFromLine({ lineWidth, ...roundedXY })\r\n\r\n context.translate(translateXY.x, translateXY.y)\r\n context.beginPath()\r\n context.set('lineWidth', this.attrs.lineWidth)\r\n context.set('strokeStyle', this.attrs.strokeStyle)\r\n\r\n context.moveTo(roundedXY.x1, roundedXY.y1)\r\n if (this.attrs.dashLength) {\r\n context.setLineDash([this.attrs.dashLength])\r\n }\r\n context.lineTo(roundedXY.x2, roundedXY.y2)\r\n context.stroke()\r\n if (this.attrs.dashLength) {\r\n context.setLineDash([])\r\n }\r\n context.translate(translateXY.x * -1, translateXY.y * -1)\r\n\r\n if (this.getShouldRenderThumbs()) {\r\n this.renderThumbs(context)\r\n }\r\n }\r\n\r\n moveBy(x: number, y: number) {\r\n this.attrs.x1 += x\r\n this.attrs.x2 += x\r\n this.attrs.y1 += y\r\n this.attrs.y2 += y\r\n }\r\n\r\n resize({ type, difX, difY }: ResizeByThumbWithTypeAndDifs) {\r\n if (type === 'l') {\r\n this.attrs.x1 += difX\r\n this.attrs.y1 += difY\r\n } else {\r\n this.attrs.x2 += difX\r\n this.attrs.y2 += difY\r\n }\r\n }\r\n\r\n isInArea(area: PaneArea) {\r\n if (super.isDrawingElementLockedOrInvisible()) return false\r\n if (math.distanceToSegment(area, this.attrs) <= 10) {\r\n return true\r\n }\r\n return super.isInArea(area)\r\n }\r\n}\r\n\r\nexport default Line\r\n","import { PaneArea, ResizeByThumbWithTypeAndDifs } from '../../types/shared'\r\nimport { CanvasElementType, TextBaseline } from '../constants/common'\r\nimport { getRoundedObject } from '../controllers/renderUtils'\r\nimport PaneModel from '../models/pane'\r\nimport { numberToStringWithUnitsSuffix } from '../utils'\r\nimport { getRoundedString } from '../utils/helpers'\r\nimport Element from './element'\r\nimport Text, { ITextAttrs } from './text'\r\nimport Thumb from './thumb'\r\n\r\ninterface Coordinates {\r\n x1: number\r\n x2: number\r\n y1: number\r\n y2: number\r\n}\r\n\r\nexport interface IMeasureAttrs extends Coordinates {\r\n fill: string\r\n}\r\n\r\nclass Measure extends Element {\r\n static type = CanvasElementType.measure\r\n\r\n name = 'Measure'\r\n declare scaled: Pick\r\n\r\n x1Dif: number\r\n x2Dif: number\r\n startingX1: number\r\n startingX2: number\r\n\r\n constructor(values: Partial, model: PaneModel) {\r\n super(values, model)\r\n this.resize = this.resize.bind(this)\r\n this._thumbs = [\r\n new Thumb(\r\n 'tl',\r\n () => this.attrs.x1,\r\n () => this.attrs.y1,\r\n this.resize,\r\n this.model\r\n ),\r\n new Thumb(\r\n 'br',\r\n () => this.attrs.x2,\r\n () => this.attrs.y2,\r\n this.resize,\r\n this.model\r\n ),\r\n ]\r\n this.scale(this.getBoundingPointKeys())\r\n this.x1Dif = this.x2Dif = 0\r\n\r\n this.startingX1 = this.attrs.x1\r\n this.startingX2 = this.attrs.x2\r\n }\r\n\r\n getBoundingPointKeys = () => ({ x: ['x1', 'x2'], y: ['y1', 'y2'] })\r\n\r\n getVolumeSumString = () => {\r\n const { volume, barIndex }: { volume: number[]; barIndex: number[] } = this.model.chart().quote()\r\n const roundedX1 = Math.round(this.attrs.x1)\r\n const roundedX2 = Math.round(this.attrs.x2)\r\n // min/max values are offset by 1 so there's no value on such index\r\n // and at the same time it won't iterate over unlimited number of nonexisting indexes\r\n const minIndexLimit = barIndex[0] - 1\r\n const maxIndexLimit = barIndex[barIndex.length - 1] + 1\r\n const volMinIndex = Math.min(Math.max(Math.min(roundedX1, roundedX2), minIndexLimit), maxIndexLimit)\r\n const volMaxIndex = Math.min(Math.max(Math.max(roundedX1, roundedX2), minIndexLimit), maxIndexLimit)\r\n\r\n let volumeSum = 0\r\n for (let i = volMinIndex; i <= volMaxIndex; i++) {\r\n const volumeIndex = barIndex.indexOf(i)\r\n if (volumeIndex >= 0) {\r\n volumeSum += volume[volumeIndex]\r\n }\r\n }\r\n\r\n return `Vol ${numberToStringWithUnitsSuffix(volumeSum)}`\r\n }\r\n\r\n renderContent(context: CanvasRenderingContext2D) {\r\n context.set('fillStyle', this.attrs.fill)\r\n const { x1, x2, y1, y2 } = this.scaled\r\n const roundedXY = getRoundedObject({ x1, x2, y1, y2 })\r\n\r\n const width = roundedXY.x2 - roundedXY.x1\r\n const height = roundedXY.y2 - roundedXY.y1\r\n context.fillRect(x1, roundedXY.y1, width, height)\r\n\r\n const priceDif = this.attrs.y2 - this.attrs.y1\r\n const percentage = (100 / this.attrs.y1) * priceDif\r\n const heightStr = `${priceDif.toFixed(2)} (${percentage.toFixed(2)}%)`\r\n\r\n const text = new Text(\r\n {\r\n text: `${getRoundedString({ number: Math.abs(this.attrs.x2 - this.attrs.x1), numOfDecimalPlaces: 2 })} bars`,\r\n fillStyle: '#333',\r\n font: { size: 10, family: 'Arial', weight: 'bold' },\r\n textBaseline: TextBaseline.middle,\r\n },\r\n this.model\r\n )\r\n const baseX = x1 + width / 2\r\n const baseY = roundedXY.y1 + height / 2\r\n let textWidth = text.measure(context)\r\n text.set({\r\n x: baseX - textWidth / 2,\r\n y: baseY - text.getHeight(),\r\n } as Partial)\r\n text.render(context)\r\n\r\n text.set({ text: heightStr })\r\n textWidth = text.measure(context)\r\n text.set({\r\n x: baseX - textWidth / 2,\r\n y: baseY,\r\n } as Partial)\r\n text.render(context)\r\n\r\n text.set({ text: this.getVolumeSumString() })\r\n textWidth = text.measure(context)\r\n text.set({\r\n x: baseX - textWidth / 2,\r\n y: baseY + text.getHeight(),\r\n } as Partial)\r\n text.render(context)\r\n\r\n if (this.getShouldRenderThumbs()) {\r\n this.renderThumbs(context)\r\n }\r\n }\r\n\r\n addToCoordinates(difs: Partial) {\r\n this.attrs.y1 += difs.y1 || 0\r\n this.attrs.y2 += difs.y2 || 0\r\n\r\n this.x1Dif += difs.x1 || 0\r\n this.x2Dif += difs.x2 || 0\r\n\r\n // The reason for adding +1 is to \"ceil\" the number when moving to the left (decreasing bar index)\r\n const newX1 = ~~(this.startingX1 + this.x1Dif) + (this.x1Dif < 0 ? 1 : 0)\r\n if (~~this.attrs.x1 - newX1 !== 0) {\r\n this.attrs.x1 = newX1\r\n }\r\n const newX2 = ~~(this.startingX2 + this.x2Dif) + (this.x2Dif < 0 ? 1 : 0)\r\n if (~~this.attrs.x2 - newX2 !== 0) {\r\n this.attrs.x2 = newX2\r\n }\r\n }\r\n\r\n moveBy(x: number, y: number) {\r\n return this.addToCoordinates({\r\n x1: x,\r\n y1: y,\r\n x2: x,\r\n y2: y,\r\n })\r\n }\r\n\r\n resize({ type, difX, difY }: ResizeByThumbWithTypeAndDifs) {\r\n if (type === 'tl') {\r\n this.addToCoordinates({ x1: difX, y1: difY })\r\n } else {\r\n this.addToCoordinates({ x2: difX, y2: difY })\r\n }\r\n }\r\n\r\n isInArea(area: PaneArea) {\r\n if (super.isDrawingElementLockedOrInvisible()) return false\r\n const x1 = Math.round(this.attrs.x1)\r\n const x2 = Math.round(this.attrs.x2)\r\n\r\n const left = Math.min(x1, x2)\r\n const right = Math.max(x1, x2)\r\n const top = Math.min(this.attrs.y1, this.attrs.y2)\r\n const bottom = Math.max(this.attrs.y1, this.attrs.y2)\r\n if (left < area.x && area.x < right && top < area.y && area.y < bottom) {\r\n return true\r\n }\r\n return super.isInArea(area)\r\n }\r\n\r\n onMouseDown(paneArea: PaneArea) {\r\n super.onMouseDown(paneArea)\r\n this.startingX1 = this.attrs.x1\r\n this.startingX2 = this.attrs.x2\r\n }\r\n\r\n onMouseUp(paneArea?: PaneArea) {\r\n super.onMouseUp(paneArea)\r\n this.x1Dif = this.x2Dif = 0\r\n }\r\n}\r\n\r\nMeasure.prototype.defaults = { fill: 'rgba(180,220,255,0.8)' }\r\n\r\nMeasure.prototype.modalConfig = {\r\n inputs: [{ type: 'background', name: 'fill' }],\r\n}\r\n\r\nexport default Measure\r\n","import { Point } from '../../../types/shared'\r\nimport { getRoundedObject } from '../../controllers/renderUtils'\r\nimport math from '../../helpers/math'\r\nimport PaneModel from '../../models/pane'\r\nimport { isInRange } from '../../utils/helpers'\r\nimport { ITrendAttrs } from './pitchfork_v1'\r\n\r\ninterface IGetEdgeIntersectionPointArguments {\r\n sides: { x: number; y: number }[][]\r\n rayOrigin: Point\r\n rayDirection: Point\r\n}\r\n\r\nexport const getEdgeIntersectionPoint = ({ sides, rayOrigin, rayDirection }: IGetEdgeIntersectionPointArguments) => {\r\n if (rayOrigin.x === rayDirection.x && rayOrigin.y === rayDirection.y) return rayDirection\r\n\r\n let intersection = rayDirection\r\n let intersectionDistance = 0\r\n for (let index = 0; index < sides.length; index++) {\r\n const rayToLineIntersection = math.getRayToLineSegmentIntersection(\r\n rayOrigin,\r\n rayDirection,\r\n sides[index][0],\r\n sides[index][1]\r\n )\r\n if (rayToLineIntersection) {\r\n const distance = math.distance(rayToLineIntersection, rayOrigin)\r\n if (distance > intersectionDistance && isInRange({ value: distance })) {\r\n intersectionDistance = distance\r\n intersection = { x: rayToLineIntersection.x, y: rayToLineIntersection.y }\r\n }\r\n }\r\n }\r\n\r\n return intersection\r\n}\r\n\r\nexport const getChartVisibleAreaBoundaries = (paneModel: PaneModel) => {\r\n const { left, right, top, bottom } = paneModel.getChartLayoutSettings().ChartSettings\r\n const { leftOffset, width } = paneModel.chart()\r\n\r\n const chartVisibleAreaLeftX = Math.abs(leftOffset)\r\n const chartVisibleAreaRightX = chartVisibleAreaLeftX + width - left.width - right.width\r\n const chartVisibleAreaTopY = 0\r\n const chartVisibleAreaBottomY = paneModel.height - top.height - bottom.height\r\n\r\n const chartVisibleAreaTopLeftPoint = {\r\n x: chartVisibleAreaLeftX,\r\n y: chartVisibleAreaTopY,\r\n }\r\n const chartVisibleAreaTopRightPoint = {\r\n x: chartVisibleAreaRightX,\r\n y: chartVisibleAreaTopY,\r\n }\r\n const chartVisibleAreaBottomLeftPoint = {\r\n x: chartVisibleAreaLeftX,\r\n y: chartVisibleAreaBottomY,\r\n }\r\n const chartVisibleAreaBottomRightPoint = {\r\n x: chartVisibleAreaRightX,\r\n y: chartVisibleAreaBottomY,\r\n }\r\n const topSide = [chartVisibleAreaTopLeftPoint, chartVisibleAreaTopRightPoint]\r\n const rightSide = [chartVisibleAreaTopRightPoint, chartVisibleAreaBottomRightPoint]\r\n const bottomSide = [chartVisibleAreaBottomLeftPoint, chartVisibleAreaBottomRightPoint]\r\n const leftSide = [chartVisibleAreaTopLeftPoint, chartVisibleAreaBottomLeftPoint]\r\n\r\n const sides = [topSide, rightSide, bottomSide, leftSide]\r\n\r\n return sides\r\n}\r\n\r\ninterface IGetPitchforkCoordinates {\r\n paneModel: PaneModel\r\n rayOrigin: Point\r\n rayDirectionControlPoint1: Point\r\n rayDirectionControlPoint2?: Point\r\n trend1: ITrendAttrs\r\n trend2: ITrendAttrs\r\n}\r\n\r\ninterface ILineSegment {\r\n P1: Point\r\n P2: Point\r\n}\r\n\r\ninterface ICoordinates {\r\n medianRay: ILineSegment\r\n trend1Ray1: ILineSegment | undefined\r\n trend1Ray2: ILineSegment | undefined\r\n trend2Ray1: ILineSegment | undefined\r\n trend2Ray2: ILineSegment | undefined\r\n}\r\n\r\nexport const getPitchforkCoordinates = ({\r\n paneModel,\r\n rayOrigin,\r\n rayDirectionControlPoint1,\r\n rayDirectionControlPoint2,\r\n trend1,\r\n trend2,\r\n}: IGetPitchforkCoordinates) => {\r\n const sides = getChartVisibleAreaBoundaries(paneModel)\r\n\r\n const coordinates: ICoordinates = {\r\n medianRay: { P1: rayOrigin, P2: rayDirectionControlPoint1 },\r\n trend1Ray1: undefined,\r\n trend2Ray1: undefined,\r\n trend1Ray2: undefined,\r\n trend2Ray2: undefined,\r\n }\r\n\r\n // If rayDirectionControlPoint2 doesn't exist return only medianRay with rayDirectionControlPoint1 as rayDirection\r\n if (!rayDirectionControlPoint2) {\r\n coordinates.medianRay = {\r\n P1: getRoundedObject(rayOrigin),\r\n P2: getRoundedObject(\r\n getEdgeIntersectionPoint({\r\n sides,\r\n rayOrigin,\r\n rayDirection: rayDirectionControlPoint1,\r\n })\r\n ),\r\n }\r\n return coordinates\r\n }\r\n\r\n const medianRayDirectionPoint = math.getMiddlePointOnLineSegment(rayDirectionControlPoint1, rayDirectionControlPoint2)\r\n const rayOriginToRayDirectionVector = {\r\n x: medianRayDirectionPoint.x - rayOrigin.x,\r\n y: medianRayDirectionPoint.y - rayOrigin.y,\r\n }\r\n\r\n const rayDirectionControlPoint1ToPoint2Vector = {\r\n x: rayDirectionControlPoint1.x - rayDirectionControlPoint2.x,\r\n y: rayDirectionControlPoint1.y - rayDirectionControlPoint2.y,\r\n }\r\n\r\n const normalizedRayDirectionControlPoint1ToPoint2Vector = math.normalizeVector(\r\n rayDirectionControlPoint1ToPoint2Vector\r\n )\r\n\r\n const medianRayDirectionPointToRayDirectionControlPoint1Distance = math.distance(\r\n medianRayDirectionPoint,\r\n rayDirectionControlPoint1\r\n )\r\n\r\n coordinates.medianRay = {\r\n P1: getRoundedObject(rayOrigin),\r\n P2: getRoundedObject(\r\n getEdgeIntersectionPoint({\r\n sides,\r\n rayOrigin,\r\n rayDirection: medianRayDirectionPoint,\r\n })\r\n ),\r\n }\r\n if (trend1.active) {\r\n const trend1Ray = getTrendRayCoordinates({\r\n trend: trend1.trend,\r\n medianToControlPointDistance: medianRayDirectionPointToRayDirectionControlPoint1Distance,\r\n normalizedControlToControlPointVector: normalizedRayDirectionControlPoint1ToPoint2Vector,\r\n rayOriginToRayDirectionVector,\r\n medianRayDirectionPoint,\r\n sides,\r\n })\r\n\r\n coordinates.trend1Ray1 = trend1Ray.trendRay1\r\n coordinates.trend1Ray2 = trend1Ray.trendRay2\r\n }\r\n if (trend2.active) {\r\n const trend2Ray = getTrendRayCoordinates({\r\n trend: trend2.trend,\r\n medianToControlPointDistance: medianRayDirectionPointToRayDirectionControlPoint1Distance,\r\n normalizedControlToControlPointVector: normalizedRayDirectionControlPoint1ToPoint2Vector,\r\n rayOriginToRayDirectionVector,\r\n medianRayDirectionPoint,\r\n sides,\r\n })\r\n\r\n coordinates.trend2Ray1 = trend2Ray.trendRay1\r\n coordinates.trend2Ray2 = trend2Ray.trendRay2\r\n }\r\n\r\n return coordinates\r\n}\r\n\r\ninterface IGetTrendRayCoordinates {\r\n trend: number\r\n medianToControlPointDistance: number\r\n normalizedControlToControlPointVector: Point\r\n rayOriginToRayDirectionVector: Point\r\n medianRayDirectionPoint: Point\r\n sides: Point[][]\r\n}\r\n\r\nconst getTrendRayCoordinates = ({\r\n trend,\r\n medianToControlPointDistance,\r\n normalizedControlToControlPointVector,\r\n rayOriginToRayDirectionVector,\r\n medianRayDirectionPoint,\r\n sides,\r\n}: IGetTrendRayCoordinates) => {\r\n const medianToTrendLineDistance = medianToControlPointDistance * trend\r\n\r\n const trendRayPoint1Origin = math.addPoints(\r\n medianRayDirectionPoint,\r\n math.multiplyVectorByScalar(normalizedControlToControlPointVector, medianToTrendLineDistance)\r\n )\r\n const trendPoint2RayOriginPoint2 = math.subtractPoints(\r\n medianRayDirectionPoint,\r\n math.multiplyVectorByScalar(normalizedControlToControlPointVector, medianToTrendLineDistance)\r\n )\r\n\r\n const trendRayPoint1DirectionPoint = {\r\n x: trendRayPoint1Origin.x + rayOriginToRayDirectionVector.x,\r\n y: trendRayPoint1Origin.y + rayOriginToRayDirectionVector.y,\r\n }\r\n const trendPoint2RayDirectionPoint = {\r\n x: trendPoint2RayOriginPoint2.x + rayOriginToRayDirectionVector.x,\r\n y: trendPoint2RayOriginPoint2.y + rayOriginToRayDirectionVector.y,\r\n }\r\n\r\n return {\r\n trendRay1: {\r\n P1: getRoundedObject(trendRayPoint1Origin),\r\n P2: getRoundedObject(\r\n getEdgeIntersectionPoint({\r\n sides,\r\n rayOrigin: trendRayPoint1Origin,\r\n rayDirection: trendRayPoint1DirectionPoint,\r\n })\r\n ),\r\n },\r\n trendRay2: {\r\n P1: getRoundedObject(trendPoint2RayOriginPoint2),\r\n P2: getRoundedObject(\r\n getEdgeIntersectionPoint({\r\n sides,\r\n rayOrigin: trendPoint2RayOriginPoint2,\r\n rayDirection: trendPoint2RayDirectionPoint,\r\n })\r\n ),\r\n },\r\n }\r\n}\r\n","import { PaneArea, ResizeByThumbWithTypeAndDifs } from '../../../types/shared'\r\nimport { CanvasElementType } from '../../constants/common'\r\nimport { getOffsetFromLineWidth } from '../../controllers/renderUtils'\r\nimport math from '../../helpers/math'\r\nimport Chart from '../../models/chart'\r\nimport PaneModel from '../../models/pane'\r\nimport { getHEXWithSpecificAplha } from '../../utils/colors'\r\nimport Element from '../element'\r\nimport Thumb from '../thumb'\r\nimport { getPitchforkCoordinates } from './pitchfork_utils'\r\n\r\nexport interface ITrendAttrs {\r\n active: boolean\r\n trend: number\r\n color: string\r\n}\r\n\r\nexport interface IPitchforkAttrs {\r\n x1: number\r\n y1: number\r\n x2: number\r\n y2: number\r\n x3: number\r\n y3: number\r\n median: { color: string; width: number }\r\n trend1: ITrendAttrs\r\n trend2: ITrendAttrs\r\n}\r\n\r\nclass Pitchfork extends Element {\r\n static type = CanvasElementType.pitchforkV1\r\n\r\n declare scaled: Pick\r\n name = 'Pitchfork'\r\n\r\n constructor(values: Partial, model: PaneModel) {\r\n super(values, model)\r\n\r\n this.resize = this.resize.bind(this)\r\n\r\n this._thumbs = [\r\n new Thumb(\r\n 'medianRayOrigin',\r\n () => this.attrs.x1,\r\n () => this.attrs.y1,\r\n this.resize,\r\n this.model\r\n ),\r\n new Thumb(\r\n 'rayDirectionControlPoint1',\r\n () => this.attrs.x2,\r\n () => this.attrs.y2,\r\n this.resize,\r\n this.model\r\n ),\r\n new Thumb(\r\n 'rayDirectionControlPoint2',\r\n () => this.attrs.x3,\r\n () => this.attrs.y3,\r\n this.resize,\r\n this.model\r\n ),\r\n ]\r\n this.scale(this.getBoundingPointKeys())\r\n }\r\n\r\n getDefaults() {\r\n return {\r\n median: { color: '#e72f2f', width: 1 },\r\n trend1: {\r\n color: '#004ad31c',\r\n active: true,\r\n trend: 1,\r\n },\r\n trend2: {\r\n color: '#00ca4e1f',\r\n active: true,\r\n trend: 0.5,\r\n },\r\n } as Partial\r\n }\r\n\r\n getBoundingPointKeys = () => ({ x: ['x1', 'x2', 'x3'], y: ['y1', 'y2', 'y3'] })\r\n\r\n renderContent(context: CanvasRenderingContext2D) {\r\n const { x1, x2, x3, y1, y2, y3 } = this.scaled\r\n\r\n const offset = getOffsetFromLineWidth(this.attrs.median.width)\r\n context.translate(offset, offset)\r\n\r\n const { medianRay, trend1Ray1, trend1Ray2, trend2Ray1, trend2Ray2 } = getPitchforkCoordinates({\r\n paneModel: this.model,\r\n rayOrigin: { x: x1, y: y1 },\r\n rayDirectionControlPoint1: { x: x2, y: y2 },\r\n rayDirectionControlPoint2: Number.isNaN(x3) || Number.isNaN(y3) ? undefined : { x: x3, y: y3 },\r\n trend1: this.attrs.trend1,\r\n trend2: this.attrs.trend2,\r\n })\r\n\r\n context.set('lineWidth', this.attrs.median.width)\r\n\r\n const trendLines = [\r\n { trend: this.attrs.trend1, line1: trend1Ray1, line2: trend1Ray2 },\r\n { trend: this.attrs.trend2, line1: trend2Ray1, line2: trend2Ray2 },\r\n ].sort((a, b) => {\r\n if (Math.abs(a.trend.trend) > Math.abs(b.trend.trend)) {\r\n return -1\r\n }\r\n if (Math.abs(a.trend.trend) < Math.abs(b.trend.trend)) {\r\n return 1\r\n }\r\n return 0\r\n })\r\n\r\n // Draw trend lines and fill\r\n trendLines.forEach((trendLine, trendLineIndex) => {\r\n if (trendLine.line1 && trendLine.line2) {\r\n const { line1, line2 } = trendLine\r\n const solidTrendColor = getHEXWithSpecificAplha(trendLine.trend.color)\r\n const nextTrendLine = trendLines[trendLineIndex + 1]\r\n\r\n context.beginPath()\r\n context.moveTo(line1.P1.x, line1.P1.y)\r\n context.lineTo(line1.P2.x, line1.P2.y)\r\n if (trendLineIndex !== trendLines.length - 1 && nextTrendLine.line1 && nextTrendLine.line2) {\r\n context.lineTo(nextTrendLine.line1.P2.x, nextTrendLine.line1.P2.y)\r\n context.lineTo(nextTrendLine.line1.P1.x, nextTrendLine.line1.P1.y)\r\n context.moveTo(nextTrendLine.line2.P1.x, nextTrendLine.line2.P1.y)\r\n context.lineTo(nextTrendLine.line2.P2.x, nextTrendLine.line2.P2.y)\r\n }\r\n context.lineTo(line2.P2.x, line2.P2.y)\r\n context.lineTo(line2.P1.x, line2.P1.y)\r\n context.closePath()\r\n context.set('fillStyle', trendLine.trend.color)\r\n context.fill()\r\n\r\n context.beginPath()\r\n context.moveTo(line1.P1.x, line1.P1.y)\r\n context.lineTo(line1.P2.x, line1.P2.y)\r\n context.moveTo(line2.P1.x, line2.P1.y)\r\n context.lineTo(line2.P2.x, line2.P2.y)\r\n context.set('strokeStyle', solidTrendColor)\r\n context.stroke()\r\n }\r\n })\r\n\r\n // Draw median ray line\r\n context.beginPath()\r\n context.moveTo(medianRay.P1.x, medianRay.P1.y)\r\n context.lineTo(medianRay.P2.x, medianRay.P2.y)\r\n\r\n // Draw line between outer trend lines origin points or if smaller than 1 between direction control points\r\n const outerTrendLines =\r\n trendLines.filter(\r\n (item) => item.line1 && item.line2 && item.trend.active && Math.abs(item.trend.trend) >= 1\r\n )[0] ?? {}\r\n\r\n if (outerTrendLines.line1 && outerTrendLines.line2) {\r\n context.moveTo(outerTrendLines.line1.P1.x, outerTrendLines.line1.P1.y)\r\n context.lineTo(outerTrendLines.line2.P1.x, outerTrendLines.line2.P1.y)\r\n } else if (!Number.isNaN(x3) && !Number.isNaN(y3)) {\r\n context.moveTo(x2, y2)\r\n context.lineTo(x3, y3)\r\n }\r\n\r\n context.set('strokeStyle', this.attrs.median.color)\r\n context.stroke()\r\n\r\n context.translate(offset * -1, offset * -1)\r\n\r\n if (this.getShouldRenderThumbs()) {\r\n this.renderThumbs(context)\r\n }\r\n }\r\n\r\n moveBy(x: number, y: number) {\r\n this.attrs.x1 += x\r\n this.attrs.y1 += y\r\n this.attrs.x2 += x\r\n this.attrs.y2 += y\r\n this.attrs.x3 += x\r\n this.attrs.y3 += y\r\n }\r\n\r\n resize({ type, difX, difY }: ResizeByThumbWithTypeAndDifs) {\r\n switch (type) {\r\n case 'medianRayOrigin':\r\n this.attrs.x1 += difX\r\n this.attrs.y1 += difY\r\n break\r\n case 'rayDirectionControlPoint1':\r\n this.attrs.x2 += difX\r\n this.attrs.y2 += difY\r\n break\r\n case 'rayDirectionControlPoint2':\r\n this.attrs.x3 += difX\r\n this.attrs.y3 += difY\r\n break\r\n default:\r\n break\r\n }\r\n }\r\n\r\n isInArea(area: PaneArea) {\r\n if (super.isDrawingElementLockedOrInvisible()) return false\r\n const { x1, x2, x3, y1, y2, y3 } = this.scaled\r\n const { medianRay, trend1Ray1, trend1Ray2, trend2Ray1, trend2Ray2 } = getPitchforkCoordinates({\r\n paneModel: this.model,\r\n rayOrigin: { x: x1, y: y1 },\r\n rayDirectionControlPoint1: { x: x2, y: y2 },\r\n rayDirectionControlPoint2: Number.isNaN(x3) || Number.isNaN(y3) ? undefined : { x: x3, y: y3 },\r\n trend1: this.attrs.trend1,\r\n trend2: this.attrs.trend2,\r\n })\r\n const outerTrendLines =\r\n Math.abs(this.attrs.trend1.trend) > Math.abs(this.attrs.trend2.trend)\r\n ? { line1: trend1Ray1, line2: trend1Ray2 }\r\n : { line1: trend2Ray1, line2: trend2Ray2 }\r\n\r\n if (\r\n math.distanceToSegment(area.scaled, {\r\n x1: medianRay.P1.x,\r\n y1: medianRay.P1.y,\r\n x2: medianRay.P2.x,\r\n y2: medianRay.P2.y,\r\n }) <= 10\r\n ) {\r\n // cursor is near median ray\r\n return true\r\n } else if (\r\n !Number.isNaN(x3) &&\r\n !Number.isNaN(y3) &&\r\n math.distanceToSegment(area.scaled, {\r\n x1: x2,\r\n y1: y2,\r\n x2: x3,\r\n y2: y3,\r\n }) <= 10\r\n ) {\r\n // cursor is near line connecting direction control points\r\n return true\r\n } else if (\r\n outerTrendLines.line1 &&\r\n outerTrendLines.line2 &&\r\n math.pointInPolygon(area.scaled, [\r\n outerTrendLines.line1.P1,\r\n outerTrendLines.line1.P2,\r\n outerTrendLines.line2.P2,\r\n outerTrendLines.line2.P1,\r\n ])\r\n ) {\r\n // cursor is on polygon created by outer trend lines\r\n return true\r\n }\r\n return super.isInArea(area)\r\n }\r\n\r\n getIsInChartView(_: Chart) {\r\n return true\r\n }\r\n}\r\n\r\nPitchfork.prototype.modalConfig = {\r\n inputs: [\r\n { type: 'line', name: 'median' },\r\n { type: 'trend', name: 'trend1' },\r\n { type: 'trend', name: 'trend2' },\r\n ],\r\n}\r\n\r\nexport default Pitchfork\r\n","import { DrawingBorder, PaneArea, ResizeByThumbWithTypeAndDifs } from '../../types/shared'\r\nimport { CanvasElementType } from '../constants/common'\r\nimport { getOffsetFromLineWidth } from '../controllers/renderUtils'\r\nimport math from '../helpers/math'\r\nimport PaneModel from '../models/pane'\r\nimport Element, { EdgeValues } from './element'\r\nimport Thumb from './thumb'\r\n\r\ntype Points = Array<{ x: number; y: number }>\r\n\r\nexport interface IPolygonAttrs {\r\n points: Points\r\n fill: string\r\n border: DrawingBorder\r\n positionPointsTimestamps?: Points\r\n}\r\n\r\nclass Polygon extends Element {\r\n static type = CanvasElementType.polygon\r\n\r\n name = 'Polygon'\r\n\r\n constructor(values: Partial, model: PaneModel) {\r\n super(values, model)\r\n this.resize = this.resize.bind(this)\r\n this.attrs.fill = this.attrs.fill || 'rgba(50, 60, 70, 0.8)'\r\n }\r\n\r\n getDefaults() {\r\n const { ElementSettings } = this.getChartLayoutSettings()\r\n return {\r\n fill: ElementSettings.defaultFill,\r\n border: {\r\n width: 1,\r\n color: ElementSettings.Colors.border,\r\n },\r\n } as Partial\r\n }\r\n\r\n renderContent(context: CanvasRenderingContext2D) {\r\n context.set('fillStyle', this.attrs.fill)\r\n context.set('lineWidth', this.attrs.border.width)\r\n context.set('strokeStyle', this.attrs.border.color)\r\n\r\n const offset = getOffsetFromLineWidth(this.attrs.border.width)\r\n context.translate(offset, offset)\r\n\r\n const { points } = this.attrs\r\n context.beginPath()\r\n context.moveTo(this.fx(points[0].x), this.fy(points[0].y))\r\n for (const p of points.slice(1)) {\r\n context.lineTo(this.fx(p.x), this.fy(p.y))\r\n }\r\n\r\n if (this.isPolygon()) {\r\n context.closePath()\r\n context.fill()\r\n }\r\n context.translate(offset * -1, offset * -1)\r\n if ((this.attrs.border != null ? this.attrs.border.width : undefined) !== 0) {\r\n context.stroke()\r\n }\r\n\r\n if (this.getShouldRenderThumbs()) {\r\n this.renderThumbs(context)\r\n }\r\n }\r\n\r\n getThumbs() {\r\n return this.attrs.points.map(\r\n (point, index) =>\r\n new Thumb(\r\n `${index}`,\r\n () => point.x,\r\n () => point.y,\r\n this.resize,\r\n this.model\r\n )\r\n )\r\n }\r\n\r\n cachePointPositionTimestamp = () => {\r\n const quote = this.model?.chart()?.quote()\r\n if (quote) {\r\n const positionPointsTimestamps = this.attrs.points.map((point) => ({\r\n ...point,\r\n x: quote.getTimestampFomPositionX(point.x),\r\n }))\r\n\r\n this.set({ positionPointsTimestamps } as Partial)\r\n }\r\n }\r\n\r\n updateScales() {\r\n const quote = this.model.chart().quote()\r\n const { positionPointsTimestamps } = this.attrs\r\n if (!quote || !positionPointsTimestamps) {\r\n // positionWavesTimestamps check is temporary to prevent app from crashing\r\n // caused by corrupted drawings - https://github.com/finvizhq/charts/pull/1386/files\r\n return\r\n }\r\n const points = positionPointsTimestamps.map((point) => ({\r\n ...point,\r\n x: quote.getPositionXFromTimestamp(point.x),\r\n }))\r\n this.set({ points } as Partial)\r\n }\r\n\r\n moveBy(x: number, y: number) {\r\n for (const point of this.attrs.points) {\r\n point.x += x\r\n point.y += y\r\n }\r\n }\r\n\r\n resize({ type, difX, difY }: ResizeByThumbWithTypeAndDifs) {\r\n const last = this.attrs.points.length - 1\r\n if (this.isPolygon() && (+type === 0 || +type === last)) {\r\n this.attrs.points[0].x += difX\r\n this.attrs.points[0].y += difY\r\n this.attrs.points[last].x += difX\r\n this.attrs.points[last].y += difY\r\n } else {\r\n this.attrs.points[+type].x += difX\r\n this.attrs.points[+type].y += difY\r\n }\r\n }\r\n\r\n isPolygon() {\r\n return (\r\n this.attrs.points[0].x === this.attrs.points.last()?.x && this.attrs.points[0].y === this.attrs.points.last()?.y\r\n )\r\n }\r\n\r\n isInArea(area: PaneArea) {\r\n if (super.isDrawingElementLockedOrInvisible()) return false\r\n const scaledPoints = this.attrs.points.map((p) => ({\r\n x: this.fx(p.x),\r\n y: this.fy(p.y),\r\n }))\r\n if (this.isPolygon()) {\r\n if (math.pointInPolygon(area.scaled, scaledPoints)) {\r\n return true\r\n }\r\n } else {\r\n for (let i = 0; i < scaledPoints.length - 1; i++) {\r\n if (\r\n math.distanceToSegment(area.scaled, {\r\n x1: scaledPoints[i].x,\r\n y1: scaledPoints[i].y,\r\n x2: scaledPoints[i + 1].x,\r\n y2: scaledPoints[i + 1].y,\r\n }) <= 10\r\n ) {\r\n return true\r\n }\r\n }\r\n }\r\n\r\n return super.isInArea(area)\r\n }\r\n\r\n getAutosaveOmittedProperties() {\r\n return ['points']\r\n }\r\n\r\n getEdgeXYValues() {\r\n if (this.edgeXYValues === null) {\r\n const edgeXYValues = {} as EdgeValues\r\n this.attrs.points.forEach(({ x, y }) => {\r\n const xPoint = x\r\n const yPoint = y\r\n edgeXYValues.minX = Math.min(xPoint, edgeXYValues.minX ?? xPoint)\r\n edgeXYValues.minY = Math.min(yPoint, edgeXYValues.minY ?? yPoint)\r\n edgeXYValues.maxX = Math.max(xPoint, edgeXYValues.maxX ?? xPoint)\r\n edgeXYValues.maxY = Math.max(yPoint, edgeXYValues.maxY ?? yPoint)\r\n })\r\n\r\n this.edgeXYValues = edgeXYValues\r\n }\r\n\r\n return this.edgeXYValues\r\n }\r\n}\r\n\r\nPolygon.prototype.modalConfig = {\r\n inputs: [\r\n { type: 'background', name: 'fill' },\r\n { type: 'border', name: 'border', min: 1, default: {} },\r\n ],\r\n}\r\n\r\nexport default Polygon\r\n","import { PaneArea, ResizeByThumbWithTypeAndDifs } from '../../types/shared'\r\nimport { CanvasElementType, TextBaseline } from '../constants/common'\r\nimport { getRoundedObject } from '../controllers/renderUtils'\r\nimport PaneModel from '../models/pane'\r\nimport Element from './element'\r\nimport Text, { ITextAttrs } from './text'\r\nimport Thumb from './thumb'\r\n\r\ninterface Coordinates {\r\n x1: number\r\n x2: number\r\n y1: number\r\n y2: number\r\n}\r\n\r\nexport interface IPositionAttrs extends Coordinates {\r\n targetColor: string\r\n stopColor: string\r\n targetY: number\r\n centerY: number\r\n stopY: number\r\n}\r\n\r\nclass Position extends Element {\r\n static type = CanvasElementType.position\r\n\r\n name = 'Position'\r\n\r\n declare scaled: Pick\r\n\r\n x1Dif: number\r\n x2Dif: number\r\n\r\n constructor(values: Partial, model: PaneModel) {\r\n super(values, model)\r\n this.resize = this.resize.bind(this)\r\n this._thumbs = [\r\n new Thumb(\r\n 't1',\r\n () => this.attrs.x1,\r\n () => this.attrs.targetY,\r\n this.resize,\r\n this.model\r\n ),\r\n new Thumb(\r\n 't2',\r\n () => this.attrs.x2,\r\n () => this.attrs.targetY,\r\n this.resize,\r\n this.model\r\n ),\r\n new Thumb(\r\n 's1',\r\n () => this.attrs.x1,\r\n () => this.attrs.stopY,\r\n this.resize,\r\n this.model\r\n ),\r\n new Thumb(\r\n 's2',\r\n () => this.attrs.x2,\r\n () => this.attrs.stopY,\r\n this.resize,\r\n this.model\r\n ),\r\n new Thumb(\r\n 'c1',\r\n () => this.attrs.x1,\r\n () => this.attrs.centerY,\r\n this.resize,\r\n this.model\r\n ),\r\n new Thumb(\r\n 'c2',\r\n () => this.attrs.x2,\r\n () => this.attrs.centerY,\r\n this.resize,\r\n this.model\r\n ),\r\n ]\r\n this.scale(this.getBoundingPointKeys())\r\n this.x1Dif = this.x2Dif = 0\r\n }\r\n\r\n getBoundingPointKeys = () => ({ x: ['x1', 'x2'], y: ['targetY', 'centerY', 'stopY'] })\r\n\r\n renderContent(context: CanvasRenderingContext2D) {\r\n const { x1, x2, targetY, centerY, stopY } = this.scaled\r\n const roundedXY = getRoundedObject({ x1, x2, targetY, centerY, stopY })\r\n let sign, stopBaseline, targetBaseline\r\n const width = roundedXY.x2 - roundedXY.x1\r\n\r\n context.set('fillStyle', this.attrs.targetColor)\r\n context.fillRect(roundedXY.x1, roundedXY.targetY, width, roundedXY.centerY - roundedXY.targetY)\r\n\r\n context.set('fillStyle', this.attrs.stopColor)\r\n context.fillRect(roundedXY.x1, roundedXY.centerY, width, roundedXY.stopY - roundedXY.centerY)\r\n\r\n const targetDif = Math.abs(this.attrs.targetY - this.attrs.centerY)\r\n const targetPerc = (100 / this.attrs.centerY) * targetDif\r\n const targetStr = `Target: ${targetDif.toFixed(2)} (${targetPerc.toFixed(2)}%)`\r\n\r\n const stopDif = Math.abs(this.attrs.stopY - this.attrs.centerY)\r\n const stopPerc = (100 / this.attrs.centerY) * stopDif\r\n const stopStr = `Stop: ${stopDif.toFixed(2)} (${stopPerc.toFixed(2)}%)`\r\n\r\n if (this.attrs.targetY > this.attrs.centerY) {\r\n sign = 1\r\n targetBaseline = TextBaseline.bottom\r\n stopBaseline = TextBaseline.top\r\n } else {\r\n sign = -1\r\n targetBaseline = TextBaseline.top\r\n stopBaseline = TextBaseline.bottom\r\n }\r\n\r\n const text = new Text(\r\n {\r\n text: targetStr,\r\n fillStyle: this.getChartLayoutSettings().ElementSettings.Colors.textWithoutBackground,\r\n font: { size: 10, family: 'Arial', weight: 'bold' },\r\n y: roundedXY.targetY - sign * 4,\r\n textBaseline: targetBaseline,\r\n },\r\n this.model\r\n )\r\n let textWidth = text.measure(context)\r\n text.set({ x: roundedXY.x1 + width / 2 - textWidth / 2 } as Partial)\r\n text.render(context)\r\n\r\n text.set({\r\n text: stopStr,\r\n y: roundedXY.stopY + sign * 4,\r\n textBaseline: stopBaseline,\r\n })\r\n textWidth = text.measure(context)\r\n text.set({ x: roundedXY.x1 + width / 2 - textWidth / 2 } as Partial)\r\n text.render(context)\r\n\r\n if (this.getShouldRenderThumbs()) {\r\n this.renderThumbs(context)\r\n }\r\n }\r\n\r\n addToCoordinates(difs: Partial) {\r\n let middle, middle1, result\r\n if (difs.targetY) {\r\n result = this.attrs.targetY + difs.targetY\r\n if (\r\n (this.attrs.targetY > this.attrs.centerY && result < this.attrs.centerY) ||\r\n (this.attrs.targetY < this.attrs.centerY && result > this.attrs.centerY)\r\n ) {\r\n this.attrs.stopY = this.attrs.centerY - (this.attrs.stopY - this.attrs.centerY) // swap target&stop\r\n }\r\n this.attrs.targetY = result\r\n }\r\n\r\n if (difs.stopY) {\r\n result = this.attrs.stopY + difs.stopY\r\n if (\r\n (this.attrs.stopY > this.attrs.centerY && result < this.attrs.centerY) ||\r\n (this.attrs.stopY < this.attrs.centerY && result > this.attrs.centerY)\r\n ) {\r\n this.attrs.targetY = this.attrs.centerY - (this.attrs.targetY - this.attrs.centerY) // swap target&stop\r\n }\r\n this.attrs.stopY = result\r\n }\r\n\r\n if (\r\n difs.centerY &&\r\n ((this.attrs.stopY < (middle = this.attrs.centerY + difs.centerY) && middle < this.attrs.targetY) ||\r\n (this.attrs.stopY > (middle1 = this.attrs.centerY + difs.centerY) && middle1 > this.attrs.targetY))\r\n ) {\r\n this.attrs.centerY += difs.centerY\r\n }\r\n\r\n this.x1Dif += difs.x1 || 0\r\n this.x2Dif += difs.x2 || 0\r\n const roundDif = ~~this.x1Dif || ~~this.x2Dif\r\n if (roundDif !== 0) {\r\n if (difs.x1 != null) {\r\n this.attrs.x1 += roundDif\r\n }\r\n if (difs.x2 != null) {\r\n this.attrs.x2 += roundDif\r\n }\r\n this.x1Dif = this.x2Dif = 0\r\n }\r\n }\r\n\r\n moveBy(x: number, y: number) {\r\n return this.addToCoordinates({\r\n x1: x,\r\n x2: x,\r\n targetY: y,\r\n centerY: y,\r\n stopY: y,\r\n })\r\n }\r\n\r\n resize({ type, difX, difY }: ResizeByThumbWithTypeAndDifs) {\r\n const [coordType, coordIndex] = (type as string).split('')\r\n const yPoints: Record = { t: 'targetY', c: 'centerY', s: 'stopY' }\r\n const obj: Partial = {\r\n [`x${coordIndex}`]: difX,\r\n [yPoints[coordType]]: difY,\r\n }\r\n return this.addToCoordinates(obj)\r\n }\r\n\r\n isInArea(area: PaneArea) {\r\n if (super.isDrawingElementLockedOrInvisible()) return false\r\n const x1 = Math.round(this.attrs.x1)\r\n const x2 = Math.round(this.attrs.x2)\r\n const left = Math.min(x1, x2)\r\n const right = Math.max(x1, x2)\r\n const top = Math.min(this.attrs.targetY, this.attrs.stopY)\r\n const bottom = Math.max(this.attrs.targetY, this.attrs.stopY)\r\n if (left < area.x && area.x < right && top < area.y && area.y < bottom) {\r\n return true\r\n }\r\n return super.isInArea(area)\r\n }\r\n}\r\n\r\nPosition.prototype.defaults = {\r\n targetColor: 'rgba(0,200,0,0.3)',\r\n stopColor: 'rgba(200,0,0,0.3)',\r\n}\r\n\r\nPosition.prototype.modalConfig = {\r\n inputs: [\r\n { type: 'background', name: 'targetColor' },\r\n { type: 'background', name: 'stopColor' },\r\n ],\r\n}\r\n\r\nexport default Position\r\n","import { DrawingBorder, PaneArea, ResizeByThumbWithTypeAndDifs } from '../../types/shared'\r\nimport { CanvasElementType } from '../constants/common'\r\nimport { getOffsetFromLineWidth, getRoundedObject } from '../controllers/renderUtils'\r\nimport PaneModel from '../models/pane'\r\nimport Element from './element'\r\nimport Thumb from './thumb'\r\n\r\nexport interface IRectangleAttrs {\r\n x1: number\r\n x2: number\r\n y1: number\r\n y2: number\r\n fill: string\r\n border: DrawingBorder\r\n}\r\n\r\nclass Rectangle extends Element {\r\n static type = CanvasElementType.rectangle\r\n\r\n name = 'Rectangle'\r\n\r\n declare scaled: Pick\r\n\r\n constructor(values: Partial, model: PaneModel) {\r\n super(values, model)\r\n this.resize = this.resize.bind(this)\r\n this._thumbs = [\r\n new Thumb(\r\n 'br',\r\n () => this.attrs.x2,\r\n () => this.attrs.y2,\r\n this.resize,\r\n this.model\r\n ),\r\n new Thumb(\r\n 'tl',\r\n () => this.attrs.x1,\r\n () => this.attrs.y1,\r\n this.resize,\r\n this.model\r\n ),\r\n ]\r\n this.scale(this.getBoundingPointKeys())\r\n }\r\n\r\n getDefaults() {\r\n const { ElementSettings } = this.getChartLayoutSettings()\r\n return {\r\n fill: ElementSettings.defaultFill,\r\n border: {\r\n width: 1,\r\n color: ElementSettings.Colors.border,\r\n },\r\n } as Partial\r\n }\r\n\r\n getBoundingPointKeys = () => ({ x: ['x1', 'x2'], y: ['y1', 'y2'] })\r\n\r\n renderContent(context: CanvasRenderingContext2D) {\r\n const { x1, x2, y1, y2 } = this.scaled\r\n const roundedXY = getRoundedObject({ x1, x2, y1, y2 })\r\n const width = roundedXY.x2 - roundedXY.x1\r\n const height = roundedXY.y2 - roundedXY.y1\r\n\r\n context.set('fillStyle', this.attrs.fill)\r\n\r\n context.fillRect(roundedXY.x1, roundedXY.y1, width, height)\r\n\r\n if ((this.attrs.border != null ? this.attrs.border.width : undefined) !== 0) {\r\n context.set('lineWidth', this.attrs.border.width)\r\n context.set('strokeStyle', this.attrs.border.color)\r\n const offset = getOffsetFromLineWidth(this.attrs.border.width)\r\n context.strokeRect(roundedXY.x1 + offset, roundedXY.y1 + offset, width, height)\r\n }\r\n\r\n if (this.getShouldRenderThumbs()) {\r\n this.renderThumbs(context)\r\n }\r\n }\r\n\r\n moveBy(x: number, y: number) {\r\n this.attrs.x1 += x\r\n this.attrs.x2 += x\r\n this.attrs.y1 += y\r\n this.attrs.y2 += y\r\n\r\n // @todo - Live sync of elements while they are being moved around\r\n // In order to have live sync across charts we need to trigger change so listeners can update other charts with new values\r\n // this.set(this.attrs)\r\n // this.trigger('change', this)\r\n }\r\n\r\n resize({ type, difX, difY }: ResizeByThumbWithTypeAndDifs) {\r\n if (type === 'tl') {\r\n this.attrs.x1 += difX\r\n return (this.attrs.y1 += difY)\r\n } else {\r\n this.attrs.x2 += difX\r\n this.attrs.y2 += difY\r\n }\r\n }\r\n\r\n isInArea(area: PaneArea) {\r\n if (super.isDrawingElementLockedOrInvisible()) return false\r\n const left = Math.min(this.attrs.x1, this.attrs.x2)\r\n const right = Math.max(this.attrs.x1, this.attrs.x2)\r\n const top = Math.min(this.attrs.y1, this.attrs.y2)\r\n const bottom = Math.max(this.attrs.y1, this.attrs.y2)\r\n if (left < area.x && area.x < right && top < area.y && area.y < bottom) {\r\n return true\r\n }\r\n return super.isInArea(area)\r\n }\r\n}\r\n\r\nRectangle.prototype.modalConfig = {\r\n inputs: [\r\n { type: 'background', name: 'fill' },\r\n { type: 'border', name: 'border', min: 1, default: {} },\r\n ],\r\n}\r\n\r\nexport default Rectangle\r\n","import { DrawingBorder, PaneArea, Point, ResizeByThumbWithTypeAndDifs } from '../../../types/shared'\r\nimport { CanvasElementType } from '../../constants/common'\r\nimport { getOffsetFromLineWidth, getRoundedObject } from '../../controllers/renderUtils'\r\nimport math from '../../helpers/math'\r\nimport PaneModel from '../../models/pane'\r\nimport Element from '../element'\r\nimport Thumb from '../thumb'\r\n\r\nexport interface IRotatedRectangleV1Attrs {\r\n x1: number\r\n x2: number\r\n y1: number\r\n y2: number\r\n cursorTargetX: number\r\n cursorTargetY: number\r\n fill: string\r\n border: DrawingBorder\r\n}\r\n\r\nclass RotatedRectangleV1 extends Element {\r\n static type = CanvasElementType.rotatedRectangleV1\r\n\r\n name = 'New Rotated Rectangle'\r\n\r\n declare scaled: Pick\r\n\r\n constructor(values: Partial, model: PaneModel) {\r\n super(values, model)\r\n this.resize = this.resize.bind(this)\r\n this._thumbs = [\r\n new Thumb(\r\n 'middleLeft',\r\n () => this.attrs.x1,\r\n () => this.attrs.y1,\r\n this.resize,\r\n this.model\r\n ),\r\n new Thumb(\r\n 'middleRight',\r\n () => this.attrs.x2,\r\n () => this.attrs.y2,\r\n this.resize,\r\n this.model\r\n ),\r\n new Thumb(\r\n 'topRight',\r\n () => this.getRectCoordinates(true).P1.x || this.attrs.x2,\r\n () => this.getRectCoordinates(true).P1.y || this.attrs.y2,\r\n this.resize,\r\n this.model\r\n ),\r\n new Thumb(\r\n 'topLeft',\r\n () => this.getRectCoordinates(true).P2.x || this.attrs.x2,\r\n () => this.getRectCoordinates(true).P2.y || this.attrs.y2,\r\n this.resize,\r\n this.model\r\n ),\r\n new Thumb(\r\n 'bottomLeft',\r\n () => this.getRectCoordinates(true).P3.x || this.attrs.x1,\r\n () => this.getRectCoordinates(true).P3.y || this.attrs.y1,\r\n this.resize,\r\n this.model\r\n ),\r\n new Thumb(\r\n 'bottomRight',\r\n () => this.getRectCoordinates(true).P4.x || this.attrs.x1,\r\n () => this.getRectCoordinates(true).P4.y || this.attrs.y1,\r\n this.resize,\r\n this.model\r\n ),\r\n ]\r\n this.scale(this.getBoundingPointKeys())\r\n }\r\n\r\n getDefaults() {\r\n const { ElementSettings } = this.getChartLayoutSettings()\r\n return {\r\n fill: ElementSettings.defaultFill,\r\n border: {\r\n width: 1,\r\n color: ElementSettings.Colors.border,\r\n },\r\n } as Partial\r\n }\r\n\r\n getBoundingPointKeys = () => ({ x: ['x1', 'x2', 'cursorTargetX'], y: ['y1', 'y2', 'cursorTargetY'] })\r\n\r\n renderContent(context: CanvasRenderingContext2D) {\r\n const { P1, P2, P3, P4 } = this.getRectCoordinates()\r\n const roundedXY = {\r\n P1: getRoundedObject(P1),\r\n P2: getRoundedObject(P2),\r\n P3: getRoundedObject(P3),\r\n P4: getRoundedObject(P4),\r\n }\r\n const offset = getOffsetFromLineWidth(this.attrs.border.width)\r\n context.set('fillStyle', this.attrs.fill)\r\n\r\n context.translate(offset, offset)\r\n context.beginPath()\r\n if (roundedXY.P1.x === roundedXY.P4.x && roundedXY.P1.y === roundedXY.P4.y) {\r\n context.lineTo(roundedXY.P1.x, roundedXY.P1.y)\r\n context.lineTo(roundedXY.P2.x, roundedXY.P2.y)\r\n } else {\r\n context.lineTo(roundedXY.P1.x, roundedXY.P1.y)\r\n context.lineTo(roundedXY.P2.x, roundedXY.P2.y)\r\n context.lineTo(roundedXY.P3.x, roundedXY.P3.y)\r\n context.lineTo(roundedXY.P4.x, roundedXY.P4.y)\r\n context.closePath()\r\n context.fill()\r\n }\r\n context.translate(offset * -1, offset * -1)\r\n\r\n context.set('lineWidth', this.attrs.border.width)\r\n context.set('strokeStyle', this.attrs.border.color)\r\n context.stroke()\r\n\r\n if (this.getShouldRenderThumbs()) {\r\n this.renderThumbs(context)\r\n }\r\n }\r\n\r\n getRectCoordinates(inverted = false) {\r\n const { x1, x2, y1, y2, cursorTargetX, cursorTargetY } = this.scaled\r\n let perpendicularPoint\r\n if (!isNaN(cursorTargetX) && !isNaN(cursorTargetY)) {\r\n const cursor = { x: cursorTargetX, y: cursorTargetY }\r\n const line = { x1, y1, x2, y2 }\r\n const distance = math.distanceToLine(cursor, line)\r\n perpendicularPoint = math.perpendicularPointToLine({\r\n distance,\r\n line,\r\n })\r\n } else {\r\n return {\r\n P1: { x: x2, y: y2 },\r\n P2: { x: x1, y: y1 },\r\n P3: { x: x1, y: y1 },\r\n P4: { x: x2, y: y2 },\r\n }\r\n }\r\n\r\n const pointOffsetX = perpendicularPoint.x - x2\r\n const pointOffsetY = perpendicularPoint.y - y2\r\n\r\n const P1 = { x: x2 + pointOffsetX, y: y2 + pointOffsetY }\r\n const P2 = { x: x1 + pointOffsetX, y: y1 + pointOffsetY }\r\n const P3 = { x: x1 + -1 * pointOffsetX, y: y1 + -1 * pointOffsetY }\r\n const P4 = { x: x2 + -1 * pointOffsetX, y: y2 + -1 * pointOffsetY }\r\n\r\n const invertX = this.model.scale.x.invert\r\n const invertY = this.model.scale.y.invert\r\n if (inverted) {\r\n return {\r\n P1: { x: invertX(P1.x), y: invertY(P1.y) },\r\n P2: { x: invertX(P2.x), y: invertY(P2.y) },\r\n P3: { x: invertX(P3.x), y: invertY(P3.y) },\r\n P4: { x: invertX(P4.x), y: invertY(P4.y) },\r\n }\r\n }\r\n return { P1, P2, P3, P4 }\r\n }\r\n\r\n getRotatedPointCoordinates = ({\r\n rotationAxisPoint,\r\n pointToRotate,\r\n oldLinePoint,\r\n newLinePoint,\r\n }: {\r\n rotationAxisPoint: Point\r\n pointToRotate: Point\r\n oldLinePoint: Point\r\n newLinePoint: Point\r\n }) => {\r\n const angle = math.sharedPointLinesAngle({\r\n sharedPoint: rotationAxisPoint,\r\n oldLinePoint,\r\n newLinePoint,\r\n })\r\n const rotatedPoinCoordinates = math.rotatedPointCoordinates({\r\n rotationAxisPoint,\r\n angle,\r\n pointToRotate,\r\n })\r\n return {\r\n x: this.model.scale.x.invert(rotatedPoinCoordinates.x),\r\n y: this.model.scale.y.invert(rotatedPoinCoordinates.y),\r\n }\r\n }\r\n\r\n moveBy(x: number, y: number) {\r\n this.attrs.x1 += x\r\n this.attrs.y1 += y\r\n this.attrs.x2 += x\r\n this.attrs.y2 += y\r\n this.attrs.cursorTargetX += x\r\n this.attrs.cursorTargetY += y\r\n }\r\n\r\n resize({ type, difX, difY, area }: ResizeByThumbWithTypeAndDifs) {\r\n switch (type) {\r\n case 'middleLeft':\r\n const newMiddleLeftPoint = {\r\n x: this.attrs.x1 + difX,\r\n y: this.attrs.y1 + difY,\r\n }\r\n const middleLeftRotatedCursorPoint = this.getRotatedPointCoordinates({\r\n rotationAxisPoint: { x: this.scaled.x2, y: this.scaled.y2 },\r\n pointToRotate: {\r\n x: this.scaled.cursorTargetX,\r\n y: this.scaled.cursorTargetY,\r\n },\r\n oldLinePoint: { x: this.scaled.x1, y: this.scaled.y1 },\r\n newLinePoint: { x: this.model.scale.x(newMiddleLeftPoint.x), y: this.model.scale.y(newMiddleLeftPoint.y) },\r\n })\r\n this.attrs = {\r\n ...this.attrs,\r\n x1: newMiddleLeftPoint.x,\r\n y1: newMiddleLeftPoint.y,\r\n cursorTargetX: middleLeftRotatedCursorPoint.x,\r\n cursorTargetY: middleLeftRotatedCursorPoint.y,\r\n }\r\n break\r\n case 'middleRight':\r\n const newMiddleRightPoint = {\r\n x: this.attrs.x2 + difX,\r\n y: this.attrs.y2 + difY,\r\n }\r\n const middleRightRotatedCursorPoint = this.getRotatedPointCoordinates({\r\n rotationAxisPoint: { x: this.scaled.x1, y: this.scaled.y1 },\r\n pointToRotate: {\r\n x: this.scaled.cursorTargetX,\r\n y: this.scaled.cursorTargetY,\r\n },\r\n oldLinePoint: { x: this.scaled.x2, y: this.scaled.y2 },\r\n newLinePoint: { x: this.model.scale.x(newMiddleRightPoint.x), y: this.model.scale.y(newMiddleRightPoint.y) },\r\n })\r\n this.attrs = {\r\n ...this.attrs,\r\n x2: newMiddleRightPoint.x,\r\n y2: newMiddleRightPoint.y,\r\n cursorTargetX: middleRightRotatedCursorPoint.x,\r\n cursorTargetY: middleRightRotatedCursorPoint.y,\r\n }\r\n break\r\n case 'topRight':\r\n case 'topLeft':\r\n case 'bottomLeft':\r\n case 'bottomRight':\r\n this.attrs = {\r\n ...this.attrs,\r\n cursorTargetX: area.x,\r\n cursorTargetY: area.y,\r\n }\r\n break\r\n default:\r\n break\r\n }\r\n }\r\n\r\n isInArea(area: PaneArea) {\r\n if (super.isDrawingElementLockedOrInvisible()) return false\r\n const coordinates = this.getRectCoordinates()\r\n const polygon = Object.keys(coordinates).map((point) => ({\r\n x: coordinates[point as 'P1' | 'P2' | 'P3' | 'P4'].x,\r\n y: coordinates[point as 'P1' | 'P2' | 'P3' | 'P4'].y,\r\n }))\r\n if (math.pointInPolygon(area.scaled, polygon)) {\r\n return true\r\n }\r\n return super.isInArea(area)\r\n }\r\n\r\n getIsInChartView() {\r\n return true\r\n }\r\n}\r\n\r\nRotatedRectangleV1.prototype.modalConfig = {\r\n inputs: [\r\n { type: 'background', name: 'fill' },\r\n { type: 'border', name: 'border', min: 1, default: {} },\r\n ],\r\n}\r\n\r\nexport default RotatedRectangleV1\r\n","import { DrawingBorder, PaneArea } from '../../types/shared'\r\nimport { CanvasElementType } from '../constants/common'\r\nimport { getRoundedObject, getXYOffsetFromLine } from '../controllers/renderUtils'\r\nimport math from '../helpers/math'\r\nimport PaneModel from '../models/pane'\r\nimport Line from './line'\r\n\r\nexport interface IScaledLineAttrs {\r\n x1: number\r\n x2: number\r\n y1: number\r\n y2: number\r\n dashLength: number\r\n lineWidth: number\r\n strokeStyle: string\r\n border: DrawingBorder\r\n}\r\n\r\nclass ScaledLine extends Line {\r\n static type = CanvasElementType.scaledLine\r\n\r\n name = 'Line'\r\n\r\n declare scaled: Pick\r\n\r\n constructor(values: Partial, model: PaneModel) {\r\n super(values, model)\r\n this.renderContent = this.renderContent.bind(this)\r\n this.scale(this.getBoundingPointKeys())\r\n }\r\n\r\n getDefaults() {\r\n return {\r\n border: {\r\n width: 1,\r\n color: this.getChartLayoutSettings().ElementSettings.Colors.border,\r\n },\r\n } as Partial\r\n }\r\n\r\n getBoundingPointKeys = () => ({ x: ['x1', 'x2'], y: ['y1', 'y2'] })\r\n\r\n renderContent(context: CanvasRenderingContext2D) {\r\n const { x1, x2, y1, y2 } = this.scaled\r\n const roundedXY = getRoundedObject({ x1, x2, y1, y2 })\r\n const translateXY = getXYOffsetFromLine({ lineWidth: this.attrs.border.width, ...roundedXY })\r\n\r\n context.translate(translateXY.x, translateXY.y)\r\n context.beginPath()\r\n context.set('lineWidth', this.attrs.border.width)\r\n context.set('strokeStyle', this.attrs.border.color)\r\n\r\n context.moveTo(roundedXY.x1, roundedXY.y1)\r\n if (this.attrs.dashLength) {\r\n context.setLineDash([this.attrs.dashLength])\r\n }\r\n context.lineTo(roundedXY.x2, roundedXY.y2)\r\n context.stroke()\r\n context.translate(translateXY.x * -1, translateXY.y * -1)\r\n\r\n if (this.getShouldRenderThumbs()) {\r\n this.renderThumbs(context)\r\n }\r\n }\r\n\r\n isInArea(area: PaneArea) {\r\n if (super.isDrawingElementLockedOrInvisible()) return false\r\n if (math.distanceToSegment(area.scaled, this.scaled) <= 10) {\r\n return true\r\n }\r\n return this.thumbsAreInArea(area)\r\n }\r\n}\r\n\r\nScaledLine.prototype.modalConfig = {\r\n inputs: [{ type: 'line', name: 'border' }],\r\n}\r\n\r\nexport default ScaledLine\r\n","import merge from 'lodash.merge'\r\n\r\nimport { PaneArea } from '../../types/shared'\r\nimport { PADDING } from '../constants/common'\r\nimport { CanvasElementType } from '../constants/common'\r\nimport Chart from '../models/chart'\r\nimport PaneModel from '../models/pane'\r\nimport Text, { ITextAttrs } from './text'\r\n\r\ninterface FontFamilyHeightCoefficient {\r\n Arial: {\r\n firstLine: number\r\n otherLines: number\r\n }\r\n Verdana: {\r\n firstLine: number\r\n otherLines: number\r\n }\r\n}\r\n\r\nclass ScaledText extends Text {\r\n static type = CanvasElementType.scaledText\r\n\r\n name = 'Text'\r\n declare fontFamilyHeightCoeficient: FontFamilyHeightCoefficient\r\n declare lastAttrs: Attrs\r\n declare scaled: Partial\r\n declare measuredHeight: number\r\n\r\n declare font: string\r\n declare context?: CanvasRenderingContext2D\r\n declare lines: {\r\n text: string\r\n metrics: TextMetrics\r\n }[]\r\n\r\n constructor(values: Partial, model: PaneModel) {\r\n super(values, model)\r\n this.scale({ x: ['x'], y: ['y'] })\r\n }\r\n\r\n getBoundingPointKeys = () => ({ x: ['x'], y: ['y'] })\r\n\r\n renderContent(context: CanvasRenderingContext2D) {\r\n this.render(context)\r\n }\r\n\r\n setupTextMetricsCache() {\r\n const ctx = this.context\r\n\r\n if (\r\n (this.attrs.text !== this.lastAttrs?.text ||\r\n JSON.stringify(this.attrs.font) !== JSON.stringify(this.lastAttrs?.font)) &&\r\n ctx\r\n ) {\r\n this.lastAttrs = merge({}, this.attrs)\r\n this.lines = this.getLines().map((line) => ({\r\n text: line,\r\n metrics: ctx.measureText(line),\r\n }))\r\n this.measuredHeight = this.lines.reduce((acc, current, currentIndex) => {\r\n const lineHeight =\r\n current.metrics.actualBoundingBoxAscent +\r\n current.metrics.actualBoundingBoxDescent +\r\n (currentIndex !== this.lines.length - 1 ? PADDING.XXXS : 0)\r\n return acc + lineHeight\r\n }, 0)\r\n }\r\n }\r\n\r\n // private\r\n setupContext(context: CanvasRenderingContext2D) {\r\n this.context = context\r\n context.set('font', this.font)\r\n context.set('fillStyle', this.attrs.fillStyle!)\r\n context.set('textAlign', this.attrs.textAlign!)\r\n context.set('textBaseline', this.attrs.textBaseline)\r\n this.setupTextMetricsCache()\r\n }\r\n\r\n // private\r\n renderText() {\r\n if (!this.context) return\r\n let y = this.scaled.y! + this.attrs.padding.top\r\n let previousDescent = 0\r\n for (let i = 0; i < this.lines.length; i++) {\r\n y += i === 0 ? 0 : this.lines[i].metrics.actualBoundingBoxAscent + previousDescent + PADDING.XXXS\r\n this.context.fillText(this.lines[i].text, this.scaled.x! + this.attrs.padding.left, y)\r\n previousDescent = this.lines[i].metrics.actualBoundingBoxDescent\r\n }\r\n }\r\n\r\n // private\r\n renderBackground() {\r\n if (!this.attrs.background || !this.context) {\r\n return\r\n }\r\n const padding = this.attrs.border!.width / 2 + PADDING.XXS\r\n\r\n this.context.beginPath()\r\n this.context.rect(\r\n this.scaled.x! - padding,\r\n this.scaled.y! - this.lines[0].metrics.actualBoundingBoxAscent - padding,\r\n this.width + padding * 2,\r\n this.measuredHeight + padding * 2\r\n )\r\n this.context.set('fillStyle', this.attrs.background)\r\n this.context.fill()\r\n this.context.set('fillStyle', this.attrs.fillStyle!)\r\n this.renderBorder()\r\n this.context.closePath()\r\n }\r\n\r\n isInArea(area: PaneArea) {\r\n if (super.isDrawingElementLockedOrInvisible()) return false\r\n // TODO\r\n // if @attrs.textBaseline == 'middle'\r\n // rect.y = @attrs.y - rect.height/2\r\n if (\r\n this.lines &&\r\n this.scaled.x! < area.scaled.x &&\r\n area.scaled.x < this.scaled.x! + this.width &&\r\n this.scaled.y! - this.lines[0].metrics.actualBoundingBoxAscent < area.scaled.y &&\r\n area.scaled.y < this.scaled.y! - this.lines[0].metrics.actualBoundingBoxAscent + this.measuredHeight\r\n ) {\r\n return true\r\n }\r\n return this.thumbsAreInArea(area)\r\n }\r\n\r\n getIsInChartView(chart: Chart) {\r\n if (this.getIsCreator()) {\r\n return true\r\n }\r\n\r\n if (!this.lines) {\r\n return true\r\n }\r\n\r\n const padding = this.attrs.border!.width / 2 + PADDING.XXS\r\n const textBoxX = this.scaled.x! - padding\r\n const textBoxY = this.scaled.y! - this.lines[0].metrics.actualBoundingBoxAscent - padding\r\n const textBoxWidth = this.width + padding * 2\r\n const textBoxHeight = this.measuredHeight + padding * 2\r\n\r\n if (\r\n textBoxX <= -chart.leftOffset + chart.width &&\r\n textBoxX + textBoxWidth >= -chart.leftOffset &&\r\n textBoxY <= this.model.height &&\r\n textBoxY + textBoxHeight >= 0\r\n ) {\r\n return true\r\n }\r\n\r\n return false\r\n }\r\n\r\n moveBy(x: number, y: number) {\r\n this.attrs.x! += x\r\n this.attrs.y! += y\r\n }\r\n}\r\n\r\nexport default ScaledText\r\n","import { PaneArea, RequireByKey, TextAttrs } from '../../types/shared'\r\nimport { CanvasElementType, TextAlign, TextBaseline } from '../constants/common'\r\nimport Element, { TodoModalConfig } from './element'\r\n\r\nexport interface Area {\r\n x: number\r\n y: number\r\n}\r\n\r\nexport type ITextAttrs = RequireByKey & Partial\r\n\r\nconst DEFAULTS: Partial = {\r\n text: '',\r\n font: {\r\n size: 20,\r\n family: 'Arial',\r\n style: 'normal',\r\n weight: 'normal',\r\n },\r\n lineHeight: 20,\r\n // left | right | center | start | end\r\n textAlign: TextAlign.left,\r\n // top | hanging | middle | alphabetic | ideographic | bottom\r\n textBaseline: TextBaseline.alphabetic,\r\n padding: {\r\n top: 0,\r\n right: 0,\r\n bottom: 0,\r\n left: 0,\r\n },\r\n}\r\n\r\nclass Text extends Element {\r\n static type = CanvasElementType.text\r\n\r\n static getMergedPropsWithDefaults>(\r\n propKey: T,\r\n props: Partial = {}\r\n ) {\r\n return {\r\n ...DEFAULTS[propKey],\r\n ...Object.entries(props).reduce((acc, [key, value]) => (value ? { ...acc, [key]: value } : acc), {}),\r\n }\r\n }\r\n\r\n name = 'Anchored text'\r\n declare context?: CanvasRenderingContext2D\r\n declare width: number\r\n declare height: number\r\n declare font: string\r\n\r\n static initClass() {\r\n Object.defineProperty(this.prototype, 'width', {\r\n get() {\r\n // TODO: revisit this getter, when you call `this.width` you don't expect/want context change\r\n if (this.context) {\r\n this.setupContext(this.context)\r\n }\r\n return this.measure() + this.attrs.padding.left + this.attrs.padding.right\r\n },\r\n })\r\n\r\n Object.defineProperty(this.prototype, 'height', {\r\n get() {\r\n const count = this.getLines().length\r\n return this.attrs.lineHeight * count + this.attrs.padding.top + this.attrs.padding.bottom\r\n },\r\n })\r\n\r\n Object.defineProperty(this.prototype, 'font', {\r\n get() {\r\n const f = this.attrs.font\r\n return `${f.style} ${f.weight} ${f.size}pt ${f.family}`\r\n },\r\n })\r\n }\r\n\r\n getModalConfigBase() {\r\n return {\r\n inputs: [\r\n { type: 'multiline_string', name: 'text', required: true },\r\n { type: 'font', name: 'font' },\r\n {\r\n type: 'background',\r\n name: 'fillStyle',\r\n label: 'Color',\r\n default: this.getChartLayoutSettings().ElementSettings.Colors.textWithoutBackground,\r\n },\r\n {\r\n type: 'background',\r\n name: 'background',\r\n label: 'Background',\r\n default: 'rgba(0,0,0,0)',\r\n },\r\n {\r\n type: 'border',\r\n name: 'border',\r\n min: 0,\r\n default: { color: 'rgba(0,0,0)', width: 0 },\r\n },\r\n ],\r\n } as unknown as TodoModalConfig\r\n }\r\n\r\n getDefaults() {\r\n return {\r\n ...DEFAULTS,\r\n fillStyle: this.getChartLayoutSettings().ElementSettings.Colors.textWithoutBackground,\r\n } as Partial\r\n }\r\n\r\n getBoundingPointKeys = () => ({ x: ['x'], y: ['y'] })\r\n\r\n set(obj: Partial) {\r\n super.set(obj)\r\n if (obj.font?.size && !obj.lineHeight) {\r\n this.attrs.lineHeight = Math.max(obj.font.size, this.attrs.lineHeight)\r\n }\r\n return this\r\n }\r\n\r\n render(context: CanvasRenderingContext2D) {\r\n this.setupContext(context)\r\n if (this.attrs.angle && this.context) {\r\n // TODO background & multiline text\r\n this.context.save()\r\n this.context.translate(this.attrs.x!, this.attrs.y!)\r\n this.context.rotate((this.attrs.angle * Math.PI) / 180)\r\n this.context.fillText(this.attrs.text, 0, 0)\r\n this.context.restore()\r\n } else {\r\n this.renderBackground()\r\n this.renderText()\r\n }\r\n }\r\n\r\n measure(context?: CanvasRenderingContext2D) {\r\n if (context) {\r\n this.setupContext(context)\r\n }\r\n const lines = this.getLines()\r\n let max = 0\r\n for (const line of lines) {\r\n max = Math.max(this.context?.measureText(line).width ?? Number.MIN_SAFE_INTEGER, max)\r\n }\r\n return ~~max\r\n }\r\n\r\n isInArea(testArea: PaneArea) {\r\n const area = this.convertArea(testArea)\r\n // TODO iny align\r\n if (\r\n this.attrs.x! < area.x &&\r\n area.x < this.attrs.x! + this.width &&\r\n this.attrs.y! - this.attrs.font.size < area.y &&\r\n area.y < this.attrs.y! - this.attrs.font.size + this.height\r\n ) {\r\n return true\r\n }\r\n return super.isInArea(testArea)\r\n }\r\n\r\n setupContext(context: CanvasRenderingContext2D) {\r\n this.context = context\r\n context.set('font', this.font)\r\n context.set('fillStyle', this.attrs.fillStyle)\r\n context.set('textAlign', this.attrs.textAlign)\r\n context.set('textBaseline', this.attrs.textBaseline)\r\n }\r\n\r\n getLines() {\r\n return this.attrs.text.toString().split('\\n')\r\n }\r\n\r\n renderText() {\r\n if (!this.context) return\r\n let { y } = this.attrs // + @attrs.padding.top\r\n for (const line of this.getLines()) {\r\n this.context.fillText(line, this.attrs.x! + this.attrs.padding.left, y!)\r\n y! += this.attrs.lineHeight\r\n }\r\n }\r\n\r\n renderBackground() {\r\n if (!this.attrs.background || !this.context) {\r\n return\r\n }\r\n\r\n const { width } = this\r\n const { height } = this\r\n const rawHight = height - this.attrs.padding.top - this.attrs.padding.bottom\r\n const { x } = this.attrs\r\n let y = this.attrs.y! - height\r\n\r\n const getFontHeight = () => {\r\n // @todo - This is needed to be able to verticaly center background behind the text, the better would be to always use TextBaseline.middle and in case of options having different TextBaseline we should move text manually on y axis\r\n const { fontBoundingBoxAscent = 0, fontBoundingBoxDescent = 0 } = this.context?.measureText(this.attrs.text) ?? {}\r\n return fontBoundingBoxAscent + fontBoundingBoxDescent\r\n }\r\n\r\n if (this.attrs.textBaseline === TextBaseline.bottom) {\r\n y = this.attrs.y! - (height - (height - getFontHeight()) / 2)\r\n } else if (this.attrs.textBaseline === TextBaseline.top) {\r\n y = this.attrs.y! - this.attrs.padding.top - 1 - (height - getFontHeight()) / 2\r\n } else if (this.attrs.textBaseline === TextBaseline.middle) {\r\n y = this.attrs.y! - rawHight / 2 - this.attrs.padding.top - 1\r\n } else if (this.attrs.textBaseline === TextBaseline.alphabetic) {\r\n y = this.attrs.y! - this.attrs.lineHeight\r\n }\r\n\r\n this.context.beginPath()\r\n this.context.set('fillStyle', this.attrs.background)\r\n this.context.rect(x!, y, width, height)\r\n this.context.fill()\r\n this.context.set('fillStyle', this.attrs.fillStyle)\r\n this.renderBorder()\r\n this.context.closePath()\r\n }\r\n\r\n renderBorder() {\r\n const { lineWidth = 0, strokeStyle, border } = this.attrs\r\n const borderWidth = border?.width ?? 0\r\n\r\n if ((lineWidth || this.attrs.strokeStyle || borderWidth > 0) && this.context) {\r\n this.context.set('strokeStyle', strokeStyle ?? border?.color ?? '')\r\n this.context.set('lineWidth', Math.max(lineWidth, borderWidth))\r\n this.context.stroke()\r\n }\r\n }\r\n\r\n private convertArea(area: PaneArea) {\r\n const { ChartSettings } = this.getChartLayoutSettings()\r\n return {\r\n x: this.model.scale.x(area.x) + this.model.chart().leftOffset + ChartSettings.left.width,\r\n y: this.model.scale.y(area.y) + ChartSettings.top.height,\r\n }\r\n }\r\n\r\n moveBy(x: number, y: number) {\r\n this.attrs.x! += this.model.scale.x(x) + 1\r\n this.attrs.y! += this.model.scale.y(y) - this.model.scale.y(0)\r\n }\r\n\r\n getHeight() {\r\n return this.height\r\n }\r\n}\r\n\r\nText.initClass()\r\n\r\nexport default Text\r\n","import { PaneArea, ResizeByThumbFuncProps, ThumbType } from '../../types/shared'\r\nimport { getOffsetFromLineWidth } from '../controllers/renderUtils'\r\nimport PaneModel from '../models/pane'\r\n\r\ntype Area = PaneArea\r\ntype ResizeFunc = (props: ResizeByThumbFuncProps) => void\r\ntype ScaleFunc = () => number\r\n\r\nclass Thumb {\r\n type: ThumbType\r\n lastX = 0\r\n lastY = 0\r\n fx: ScaleFunc\r\n fy: ScaleFunc\r\n resize: ResizeFunc\r\n model: PaneModel\r\n\r\n constructor(type: ThumbType, fx: ScaleFunc, fy: ScaleFunc, resize: ResizeFunc, model: PaneModel) {\r\n this.type = type\r\n this.fx = fx\r\n this.fy = fy\r\n this.resize = resize\r\n this.model = model\r\n }\r\n\r\n render(context: CanvasRenderingContext2D) {\r\n const { ThumbSettings } = this.model.getChartLayoutSettings()\r\n context.set('fillStyle', ThumbSettings.color)\r\n context.set('strokeStyle', ThumbSettings.borderColor)\r\n context.set('lineWidth', ThumbSettings.borderWidth)\r\n const x = ~~this.x()\r\n const y = ~~this.y()\r\n const thumbWidth = this.getThumbWidth()\r\n const offset = getOffsetFromLineWidth(ThumbSettings.borderWidth)\r\n context.beginPath()\r\n context.rect(x + offset, y + offset, thumbWidth, thumbWidth)\r\n context.fill()\r\n context.stroke()\r\n }\r\n\r\n startEditing(area: Area) {\r\n this.lastX = area.x\r\n return (this.lastY = area.y)\r\n }\r\n\r\n moveTo(area: Area) {\r\n const difX = area.x - this.lastX\r\n const difY = area.y - this.lastY\r\n this.resize({ type: this.type, difX, difY, area })\r\n this.lastX = area.x\r\n this.lastY = area.y\r\n }\r\n\r\n isInArea(area: Area) {\r\n const width = this.model.scale.x.invert(this.getThumbWidth())\r\n const height = this.model.scale.y.invert(0) - this.model.scale.y.invert(this.getThumbWidth())\r\n // +- width/2 because we have coordinates of a center\r\n if (\r\n this.fx() + width / 2 >= area.x &&\r\n this.fx() - width / 2 <= area.x &&\r\n this.fy() + height / 2 > area.y &&\r\n this.fy() - height / 2 < area.y\r\n ) {\r\n return true\r\n }\r\n return false\r\n }\r\n\r\n getThumbWidth() {\r\n const { ThumbSettings } = this.model.getChartLayoutSettings()\r\n return ThumbSettings.size + ThumbSettings.borderWidth * 2\r\n }\r\n\r\n x() {\r\n const { ThumbSettings } = this.model.getChartLayoutSettings()\r\n return this.model.scale.x(this.fx()) - ThumbSettings.size / 2\r\n }\r\n\r\n y() {\r\n const { ThumbSettings } = this.model.getChartLayoutSettings()\r\n return this.model.scale.y(this.fy()) - ThumbSettings.size / 2\r\n }\r\n}\r\n\r\nexport default Thumb\r\n","import { PaneArea, ResizeByThumbWithTypeAndDifs } from '../../types/shared'\r\nimport { CanvasElementType } from '../constants/common'\r\nimport { getOffsetFromLineWidth, getRoundedObject } from '../controllers/renderUtils'\r\nimport math from '../helpers/math'\r\nimport PaneModel from '../models/pane'\r\nimport Element from './element'\r\nimport Thumb from './thumb'\r\n\r\nexport interface ITriangleAttrs {\r\n x1: number\r\n x2: number\r\n x3: number\r\n y1: number\r\n y2: number\r\n y3: number\r\n fill: string\r\n border: string\r\n}\r\n\r\nclass Triangle extends Element {\r\n static type = CanvasElementType.triangle\r\n\r\n declare scaled: Pick\r\n name = 'Triangle'\r\n\r\n constructor(values: Partial, model: PaneModel) {\r\n super(values, model)\r\n\r\n this.resize = this.resize.bind(this)\r\n\r\n this._thumbs = [\r\n new Thumb(\r\n 'a',\r\n () => this.attrs.x1,\r\n () => this.attrs.y1,\r\n this.resize,\r\n this.model\r\n ),\r\n new Thumb(\r\n 'b',\r\n () => this.attrs.x2,\r\n () => this.attrs.y2,\r\n this.resize,\r\n this.model\r\n ),\r\n new Thumb(\r\n 'c',\r\n () => this.attrs.x3,\r\n () => this.attrs.y3,\r\n this.resize,\r\n this.model\r\n ),\r\n ]\r\n this.scale(this.getBoundingPointKeys())\r\n }\r\n\r\n getDefaults() {\r\n const { ElementSettings } = this.getChartLayoutSettings()\r\n return { fill: ElementSettings.defaultFill, border: ElementSettings.Colors.border } as Partial\r\n }\r\n\r\n getBoundingPointKeys = () => ({ x: ['x1', 'x2', 'x3'], y: ['y1', 'y2', 'y3'] })\r\n\r\n renderContent(context: CanvasRenderingContext2D) {\r\n const { x1, x2, x3, y1, y2, y3 } = this.scaled\r\n const roundedXY = getRoundedObject({ x1, x2, x3, y1, y2, y3 })\r\n\r\n context.set('fillStyle', this.attrs.fill)\r\n\r\n const offset = this.getShouldRenderThumbs() ? getOffsetFromLineWidth(1) : 0\r\n\r\n context.translate(offset, offset)\r\n context.beginPath()\r\n context.moveTo(roundedXY.x1, roundedXY.y1)\r\n context.lineTo(roundedXY.x2, roundedXY.y2)\r\n context.lineTo(roundedXY.x3, roundedXY.y3)\r\n context.lineTo(roundedXY.x1, roundedXY.y1)\r\n context.fill()\r\n context.translate(offset * -1, offset * -1)\r\n\r\n if (this.getShouldRenderThumbs()) {\r\n context.set('strokeStyle', this.attrs.border)\r\n context.stroke()\r\n this.renderThumbs(context)\r\n }\r\n }\r\n\r\n moveBy(x: number, y: number) {\r\n this.attrs.x1 += x\r\n this.attrs.y1 += y\r\n this.attrs.x2 += x\r\n this.attrs.y2 += y\r\n this.attrs.x3 += x\r\n this.attrs.y3 += y\r\n }\r\n\r\n resize({ type, difX, difY }: ResizeByThumbWithTypeAndDifs) {\r\n switch (type) {\r\n case 'a':\r\n this.attrs.x1 += difX\r\n this.attrs.y1 += difY\r\n break\r\n case 'b':\r\n this.attrs.x2 += difX\r\n this.attrs.y2 += difY\r\n break\r\n case 'c':\r\n this.attrs.x3 += difX\r\n this.attrs.y3 += difY\r\n break\r\n default:\r\n break\r\n }\r\n }\r\n\r\n isInArea(area: PaneArea) {\r\n if (super.isDrawingElementLockedOrInvisible()) return false\r\n const polygon = [1, 2, 3].map((i) => ({\r\n x: this.scaled[`x${i}` as 'x1' | 'x2' | 'x3'],\r\n y: this.scaled[`y${i}` as 'y1' | 'y2' | 'y3'],\r\n }))\r\n if (math.pointInPolygon(area.scaled, polygon)) {\r\n return true\r\n }\r\n return super.isInArea(area)\r\n }\r\n}\r\n\r\nTriangle.prototype.modalConfig = {\r\n inputs: [{ type: 'background', name: 'fill' }],\r\n}\r\n\r\nexport default Triangle\r\n","import { RequireByKey, ResizeByThumbFuncProps } from '../../types/shared'\r\nimport { CanvasElementType } from '../constants/common'\r\nimport Chart from '../models/chart'\r\nimport PaneModel from '../models/pane'\r\nimport ScaledLine, { IScaledLineAttrs } from './scaled_line'\r\n\r\nclass VerticalLine extends ScaledLine {\r\n static type = CanvasElementType.verticalLine\r\n\r\n name = 'Vertical line'\r\n\r\n constructor(values: Partial, model: PaneModel) {\r\n super(values, model)\r\n\r\n this.renderContent = this.renderContent.bind(this)\r\n\r\n this.attrs.x2 = this.attrs.x1\r\n this._thumbs = [this._thumbs[0]]\r\n }\r\n\r\n getBoundingPointKeys = () => ({ x: ['x1', 'x2'], y: ['y1', 'y2'] })\r\n\r\n renderContent(context: CanvasRenderingContext2D) {\r\n const domain = this.model.scale.y.domain()\r\n this.attrs.y1 = domain[0]\r\n this.attrs.y2 = domain[1]\r\n this._thumbs[0].fy = () => (this.attrs.y1 + this.attrs.y2) / 2\r\n super.renderContent(context)\r\n }\r\n\r\n moveBy(x: number) {\r\n return (this.attrs.x1 = this.attrs.x2 += x)\r\n }\r\n\r\n resize({ difX }: RequireByKey) {\r\n return this.moveBy(difX)\r\n }\r\n\r\n getIsInChartView(chart: Chart) {\r\n return super.getIsInChartView(chart, { omitY: true })\r\n }\r\n}\r\n\r\nexport default VerticalLine\r\n","import { DrawingBorder, PaneArea, ResizeByThumbWithTypeAndDifs } from '../../types/shared'\r\nimport { CanvasElementType, TextAlign, TextBaseline } from '../constants/common'\r\nimport { getOffsetFromLineWidth, getRoundedObject } from '../controllers/renderUtils'\r\nimport math from '../helpers/math'\r\nimport PaneModel from '../models/pane'\r\nimport Element from './element'\r\nimport Text, { ITextAttrs } from './text'\r\nimport Thumb from './thumb'\r\n\r\nexport interface IXABCDPositionAttrs {\r\n xx: number\r\n xy: number\r\n ax: number\r\n ay: number\r\n bx: number\r\n by: number\r\n cx: number\r\n cy: number\r\n dx: number\r\n dy: number\r\n}\r\n\r\ntype xPoints = 'xx' | 'ax' | 'bx' | 'cx' | 'dx'\r\ntype yPoints = 'xy' | 'ay' | 'by' | 'cy' | 'dy'\r\n\r\nexport interface IXABCDAttrs extends IXABCDPositionAttrs {\r\n fill: string\r\n border: DrawingBorder\r\n lineWidth: number\r\n}\r\n\r\nclass XABCD extends Element {\r\n static type = CanvasElementType.xabcd\r\n\r\n name = 'XABCD pattern'\r\n\r\n declare scaled: Pick\r\n\r\n constructor(values: Partial, model: PaneModel) {\r\n super(values, model)\r\n\r\n this.resize = this.resize.bind(this)\r\n\r\n this._thumbs = [\r\n new Thumb(\r\n 'x',\r\n () => this.attrs.xx,\r\n () => this.attrs.xy,\r\n this.resize,\r\n this.model\r\n ),\r\n new Thumb(\r\n 'a',\r\n () => this.attrs.ax,\r\n () => this.attrs.ay,\r\n this.resize,\r\n this.model\r\n ),\r\n new Thumb(\r\n 'b',\r\n () => this.attrs.bx,\r\n () => this.attrs.by,\r\n this.resize,\r\n this.model\r\n ),\r\n new Thumb(\r\n 'c',\r\n () => this.attrs.cx,\r\n () => this.attrs.cy,\r\n this.resize,\r\n this.model\r\n ),\r\n new Thumb(\r\n 'd',\r\n () => this.attrs.dx,\r\n () => this.attrs.dy,\r\n this.resize,\r\n this.model\r\n ),\r\n ]\r\n if (this.attrs.lineWidth == null) {\r\n this.attrs.lineWidth = 1\r\n }\r\n this.scale(this.getBoundingPointKeys())\r\n }\r\n\r\n getDefaults() {\r\n const { ElementSettings } = this.getChartLayoutSettings()\r\n return {\r\n fill: ElementSettings.defaultFill,\r\n border: {\r\n width: 1,\r\n color: ElementSettings.Colors.border,\r\n },\r\n } as Partial\r\n }\r\n\r\n getBoundingPointKeys = () => ({\r\n x: ['xx', 'ax', 'bx', 'cx', 'dx'],\r\n y: ['xy', 'ay', 'by', 'cy', 'dy'],\r\n })\r\n\r\n renderContent(context: CanvasRenderingContext2D) {\r\n const { xx, xy, ax, ay, bx, by, cx, cy, dx, dy } = this.scaled\r\n const roundedXY = getRoundedObject({ xx, xy, ax, ay, bx, by, cx, cy, dx, dy })\r\n\r\n context.set('fillStyle', this.attrs.fill)\r\n context.set('lineWidth', this.attrs.border.width)\r\n context.set('strokeStyle', this.attrs.border.color)\r\n\r\n const offset = getOffsetFromLineWidth(this.attrs.border.width)\r\n context.translate(offset, offset)\r\n\r\n context.beginPath()\r\n context.moveTo(roundedXY.xx, roundedXY.xy)\r\n context.lineTo(roundedXY.ax, roundedXY.ay)\r\n context.lineTo(roundedXY.bx, roundedXY.by)\r\n context.lineTo(roundedXY.xx, roundedXY.xy)\r\n context.fill()\r\n if ((this.attrs.border != null ? this.attrs.border.width : undefined) !== 0) {\r\n context.stroke()\r\n }\r\n\r\n context.beginPath()\r\n context.moveTo(roundedXY.bx, roundedXY.by)\r\n context.lineTo(roundedXY.cx, roundedXY.cy)\r\n context.lineTo(roundedXY.dx, roundedXY.dy)\r\n context.lineTo(roundedXY.bx, roundedXY.by)\r\n context.fill()\r\n if ((this.attrs.border != null ? this.attrs.border.width : undefined) !== 0) {\r\n context.stroke()\r\n }\r\n\r\n context.beginPath()\r\n context.moveTo(roundedXY.ax, roundedXY.ay)\r\n context.lineTo(roundedXY.cx, roundedXY.cy)\r\n context.moveTo(roundedXY.xx, roundedXY.xy)\r\n context.lineTo(roundedXY.dx, roundedXY.dy)\r\n context.stroke()\r\n\r\n const text = new Text(\r\n {\r\n font: { size: 8, style: 'bold' },\r\n lineHeight: 8,\r\n padding: {\r\n top: 2,\r\n right: 2,\r\n bottom: 2,\r\n left: 2,\r\n },\r\n textBaseline: TextBaseline.middle,\r\n textAlign: TextAlign.start,\r\n fillStyle: '#ffffff',\r\n background: this.attrs.fill || '#000000',\r\n },\r\n this.model\r\n )\r\n\r\n for (const t of Array.from('xabcd')) {\r\n text\r\n .set({\r\n text: t.toUpperCase(),\r\n x: roundedXY[(t + 'x') as xPoints] - 6,\r\n y: roundedXY[(t + 'y') as yPoints] + 12,\r\n } as Partial)\r\n .render(context)\r\n }\r\n\r\n const retLabel = (y1: string, y2: string, y3: string) => {\r\n const len = Math.abs(this.attrs[(y1 + 'y') as yPoints] - this.attrs[(y2 + 'y') as yPoints])\r\n const ret = Math.abs(this.attrs[(y3 + 'y') as yPoints] - this.attrs[(y2 + 'y') as yPoints]) / len\r\n const x = (roundedXY[(y1 + 'x') as xPoints] + roundedXY[(y3 + 'x') as xPoints]) / 2\r\n const y = (roundedXY[(y1 + 'y') as yPoints] + roundedXY[(y3 + 'y') as yPoints]) / 2\r\n return text\r\n .set({\r\n text: ret.toFixed(3),\r\n x,\r\n y,\r\n })\r\n .render(context)\r\n }\r\n\r\n retLabel('x', 'a', 'b')\r\n retLabel('a', 'b', 'c')\r\n retLabel('b', 'c', 'd')\r\n retLabel('x', 'a', 'd')\r\n\r\n if (this.getShouldRenderThumbs()) {\r\n this.renderThumbs(context)\r\n }\r\n context.translate(offset * -1, offset * -1)\r\n }\r\n\r\n moveBy(x: number, y: number) {\r\n for (const t of Array.from('xabcd')) {\r\n this.attrs[(t + 'x') as xPoints] += x\r\n this.attrs[(t + 'y') as yPoints] += y\r\n }\r\n }\r\n\r\n resize({ type, difX, difY }: ResizeByThumbWithTypeAndDifs) {\r\n this.attrs[(type + 'x') as xPoints] += difX\r\n return (this.attrs[(type + 'y') as yPoints] += difY)\r\n }\r\n\r\n isInArea(area: PaneArea) {\r\n if (super.isDrawingElementLockedOrInvisible()) return false\r\n let t\r\n const xab = (() => {\r\n const result = []\r\n for (t of Array.from('xab')) {\r\n result.push({ x: this.scaled[(t + 'x') as xPoints], y: this.scaled[(t + 'y') as yPoints] })\r\n }\r\n return result\r\n })()\r\n const bcd = (() => {\r\n const result1 = []\r\n for (t of Array.from('bcd')) {\r\n result1.push({ x: this.scaled[(t + 'x') as xPoints], y: this.scaled[(t + 'y') as yPoints] })\r\n }\r\n return result1\r\n })()\r\n if (math.pointInPolygon(area.scaled, xab) || math.pointInPolygon(area.scaled, bcd)) {\r\n return true\r\n }\r\n return super.isInArea(area)\r\n }\r\n}\r\n\r\nXABCD.prototype.modalConfig = {\r\n inputs: [\r\n { type: 'background', name: 'fill' },\r\n { type: 'border', name: 'border', min: 1 },\r\n ],\r\n}\r\n\r\nexport default XABCD\r\n","import Utils from '../utils'\r\nimport { getContextWithCache } from '../utils/canvas'\r\nimport { captureException, getIsSSr } from '../utils/helpers'\r\n\r\nclass Cache {\r\n constructor() {\r\n this.canvas = getIsSSr() ? null : document.createElement('canvas')\r\n }\r\n\r\n set(callback, width, height) {\r\n this.callback = callback\r\n this.width = width\r\n this.height = height\r\n this.rendered = false\r\n }\r\n\r\n render(context, x, y) {\r\n if (x == null) {\r\n x = 0\r\n }\r\n if (y == null) {\r\n y = 0\r\n }\r\n if (!this.rendered) {\r\n this.refresh()\r\n }\r\n if (this.width < 1 || this.height < 1) {\r\n return\r\n }\r\n\r\n try {\r\n if (this.ratio >= 1 && this.canvas) {\r\n context.drawImage(\r\n this.canvas,\r\n 0,\r\n 0,\r\n ~~(this.width * this.ratio),\r\n ~~(this.height * this.ratio),\r\n x,\r\n y,\r\n this.width,\r\n this.height\r\n )\r\n } else {\r\n context.save()\r\n context.translate(x, y)\r\n this.callback(context)\r\n context.restore()\r\n }\r\n } catch (e) {\r\n captureException(\r\n e,\r\n this.canvas\r\n ? {\r\n extra: {\r\n width: this.width,\r\n height: this.height,\r\n ratio: this.ratio,\r\n cWidth: this.canvas.width,\r\n cHeight: this.canvas.height,\r\n sWidth: window.screen.width,\r\n sHeight: window.screen.height,\r\n },\r\n }\r\n : {}\r\n )\r\n }\r\n }\r\n\r\n refresh() {\r\n if (getIsSSr()) {\r\n return\r\n }\r\n this.canvas.width = this.width\r\n this.canvas.height = this.height\r\n this.context = getContextWithCache(this.canvas)\r\n this.ratio = Utils.getScaleRatio()\r\n Utils.setSizeOnCanvasElement({ canvasElement: this.canvas, width: this.width, height: this.height })\r\n this.context.scale(this.ratio, this.ratio)\r\n\r\n this.callback(this.context)\r\n this.rendered = true\r\n }\r\n}\r\n\r\nexport default Cache\r\n","import { ObjectHash, Theme } from '../../../types/shared'\r\nimport { TextAlign, TextBaseline } from '../../constants/common'\r\nimport { IChartThemeColors, IElementThemeColors, IIndicatorThemeColors } from '../constants'\r\n\r\nexport enum OHLCType {\r\n singleLine = 'singleLine',\r\n dateOnly = 'dateOnly',\r\n timeOnly = 'timeOnly',\r\n}\r\n\r\nexport interface IMargin {\r\n top?: number\r\n right?: number\r\n bottom?: number\r\n left?: number\r\n}\r\n\r\ninterface IPadding {\r\n top?: number\r\n right?: number\r\n bottom?: number\r\n left?: number\r\n}\r\n\r\ninterface IGenericText {\r\n margin: IMargin\r\n font: IFont\r\n}\r\n\r\ninterface IFont {\r\n size?: number\r\n style?: string\r\n weight?: string\r\n family?: string\r\n lineHeight?: number\r\n padding?: IPadding\r\n baseline?: TextBaseline\r\n textAlign?: TextAlign\r\n}\r\n\r\ninterface ISettingsGeneralBase {\r\n Colors: IChartThemeColors\r\n}\r\n\r\nexport interface ISettingsCenterBase {\r\n barWidth: number\r\n barMargin: number\r\n border: number\r\n volumeHeight?: number\r\n}\r\n\r\ninterface ISettingsTopBase {\r\n height: number\r\n}\r\n\r\ninterface ISettingsBottomBase {\r\n height: number\r\n}\r\n\r\ninterface ISettingsLeftBase {\r\n width: number\r\n}\r\n\r\ninterface ISettingsRightBase {\r\n width: number\r\n}\r\n\r\nexport interface ISettings {\r\n ChartSettings: IChartSettings\r\n IndicatorSettings: IIndicatorSettings\r\n MarketSentimentSettings: IMarketSentimentChartSettings\r\n ColorsSettings: Array\r\n ThumbSettings: IThumbSettings\r\n ElementSettings: IElementSettings\r\n isOurSiteRequest?: boolean\r\n}\r\n\r\nexport interface IChartSettings {\r\n general: IChartGeneral\r\n center: ISettingsCenterBase\r\n top: IChartTop\r\n bottom: IChartBottom\r\n left: IChartLeft\r\n right: IChartRight\r\n}\r\n\r\ninterface IChartGeneral {\r\n settingsHeight: number\r\n tickerTimeframeChangeHeight: number\r\n Colors: IChartThemeColors & ObjectHash\r\n}\r\n\r\ninterface IChartTop extends ISettingsTopBase {\r\n baseline: TextBaseline\r\n ticker: IGenericText\r\n ohlc: IOHLC\r\n change: IGenericText\r\n}\r\n\r\ninterface IOHLC extends IGenericText {\r\n type?: OHLCType\r\n}\r\n\r\ninterface IChartBottom extends ISettingsBottomBase {\r\n baseline: TextBaseline\r\n axis: IGenericText\r\n}\r\n\r\ninterface IChartLeft extends ISettingsLeftBase {\r\n overlayLabel: IOverlayLabel\r\n timeframe: IGenericText\r\n volumeAxis: IGenericText\r\n}\r\n\r\ninterface IOverlayLabel extends IGenericText {\r\n labelSpacing: number\r\n}\r\n\r\ninterface IChartRight extends ISettingsRightBase {\r\n axis: IGenericText\r\n}\r\n\r\nexport interface IIndicatorSettings {\r\n general: IIndicatorGeneral\r\n center: ISettingsCenterBase\r\n top: ISettingsTopBase\r\n bottom: ISettingsBottomBase\r\n left: IIndicatorLeft\r\n right: IIndicatorRight\r\n}\r\n\r\ninterface IIndicatorRight extends ISettingsRightBase {\r\n axis: IGenericText\r\n}\r\n\r\ninterface IIndicatorLeft extends ISettingsLeftBase {\r\n indicatorLabel: IIndicatorLabel\r\n}\r\n\r\ninterface IIndicatorLabel extends IGenericText {\r\n labelSpacing: number\r\n}\r\n\r\ninterface IIndicatorGeneral {\r\n Colors: IIndicatorThemeColors\r\n height: number\r\n}\r\n\r\ninterface IMarketSentimentChartSettings {\r\n general: ISettingsGeneralBase\r\n center: ISettingsCenterBase\r\n top: ISettingsTopBase\r\n bottom: ISettingsBottomBase\r\n left: ISettingsLeftBase\r\n right: ISettingsRightBase\r\n}\r\n\r\ninterface IThumbSettings {\r\n size: number\r\n touchSize: number\r\n color: string\r\n borderWidth: number\r\n borderColor: string\r\n}\r\n\r\ninterface IElementSettings {\r\n Colors: IElementThemeColors\r\n defaultFill: string\r\n defaultTransparentFill: string\r\n}\r\n","export enum ChartMinWidthBreakpoints {\r\n xs = 0,\r\n s = 480,\r\n m = 768,\r\n l = 1024,\r\n}\r\n\r\nexport function getChartBreakpoints(chartWidthInPx: number) {\r\n return {\r\n isXs: chartWidthInPx >= ChartMinWidthBreakpoints.xs,\r\n isS: chartWidthInPx >= ChartMinWidthBreakpoints.s,\r\n isM: chartWidthInPx >= ChartMinWidthBreakpoints.m,\r\n isL: chartWidthInPx >= ChartMinWidthBreakpoints.l,\r\n }\r\n}\r\n","import * as d3 from 'd3'\r\nimport merge from 'lodash.merge'\r\n\r\nimport {\r\n ChartConfigChartPaneElement,\r\n CustomSpineEvents,\r\n Instrument,\r\n Maybe,\r\n RequireByKey,\r\n Theme,\r\n} from '../../types/shared'\r\nimport Cache from '../canvas/cache'\r\nimport Element from '../canvas/element'\r\nimport Line from '../canvas/line'\r\nimport Text from '../canvas/text'\r\nimport tailwindColors from '../constants/colors'\r\nimport {\r\n CHART_MARGIN,\r\n ChartElementType,\r\n FONT_SIZE,\r\n IndicatorType,\r\n IntradayTimeframeInterval,\r\n LINE_HEIGHT,\r\n MONTHS,\r\n OFFSET,\r\n PADDING,\r\n ScaleType,\r\n SpecificChartFunctionality,\r\n TIMEFRAME,\r\n TIMEFRAMES_WITH_PRE_MARKET,\r\n TextAlign,\r\n TextBaseline,\r\n getTimeframeLabel,\r\n} from '../constants/common'\r\nimport {\r\n getIsSmallIndexChart,\r\n getPercentageFromValue,\r\n getTranslate,\r\n getValueFromPercentage,\r\n} from '../controllers/renderUtils'\r\nimport Chart from '../models/chart'\r\nimport { getColorOverwrites } from '../models/chart_settings'\r\nimport { ISettings, OHLCType } from '../models/chart_settings/interfaces'\r\nimport { darkerWickColors, thinBarColorsOverride } from '../models/constants'\r\nimport mouseModel from '../models/mouse'\r\nimport PaneModel, { ScaleAxis } from '../models/pane'\r\nimport Quote from '../models/quote'\r\nimport { getChartLayoutSettings } from '../models/settings'\r\nimport Overlay from '../overlays/overlay'\r\nimport { overlaysByType } from '../overlays/overlays'\r\nimport utils, { dateFromDateString, isRedesignedPage, numberToStringWithUnitsSuffix } from '../utils'\r\nimport {\r\n ITickerChange,\r\n getBarWidthWithMargin,\r\n getBarWithoutMarginWidth,\r\n getChangeColor,\r\n getHalfBarWidth,\r\n getShouldUseDarkerWickColors,\r\n getTickerChange,\r\n getTickerChangeFromCloseValues,\r\n getVirtualTimeframeTradedDates,\r\n renderCross,\r\n round,\r\n unmountCanvas,\r\n} from '../utils/chart'\r\nimport { convertColorToHEX, getHEXWithSpecificAplha, getHSVAFromColor, stringifyHSVAColor } from '../utils/colors'\r\nimport { setElementCursor } from '../utils/cursor'\r\nimport { drawInVisibleArea, getAreNoBarsVisible, getVisibleBarToRenderIndex } from '../utils/draw_in_visible_area'\r\nimport { getChartBreakpoints } from './utils'\r\n\r\nexport interface BaseChartAttrs {\r\n overlays: Required['overlays']\r\n}\r\n\r\ntype OhlcLineElements = Array<{ text: string; color: string } | 'space'>\r\n\r\ninterface LastOHLCAttrs {\r\n text: string\r\n x: number\r\n y: number\r\n width: number\r\n textBaseline: TextBaseline\r\n textAlign: TextAlign\r\n}\r\n\r\ninterface IRenderOHLCParameters {\r\n context: CanvasRenderingContext2D\r\n date: Maybe\r\n open?: Maybe\r\n high?: Maybe\r\n low?: Maybe\r\n close?: Maybe\r\n volume?: Maybe\r\n afterHour?: string\r\n isSmallIndexChart?: boolean\r\n isNewestOHLC?: boolean\r\n directRender?: boolean\r\n time?: string\r\n changePercentage?: Maybe\r\n}\r\n\r\ninterface XAxisLabel {\r\n x: number\r\n text: string\r\n textWidth: number\r\n hasPriority?: boolean\r\n allowedOverflow?: number\r\n}\r\n\r\ninterface IRenderXAxisProps {\r\n textRenderer: Text\r\n startBarIndex: number\r\n endBarIndex: number\r\n}\r\n\r\nconst getDateString = ({ date, timeframe }: { date: Date; timeframe: TIMEFRAME }) => {\r\n let dateString = ''\r\n const month = date.getMonth() // 20141126\r\n const year = date.getFullYear()\r\n const day = date.getDate()\r\n switch (timeframe) {\r\n case TIMEFRAME.i1:\r\n case TIMEFRAME.i2:\r\n case TIMEFRAME.i3:\r\n case TIMEFRAME.i5:\r\n case TIMEFRAME.i10:\r\n case TIMEFRAME.i15:\r\n case TIMEFRAME.i30:\r\n case TIMEFRAME.h:\r\n case TIMEFRAME.h2:\r\n case TIMEFRAME.h4:\r\n const t =\r\n (((date.getHours() + 11) % 12) + 1).toString().padLeft('00') +\r\n ':' +\r\n date.getMinutes().toString().padLeft('00') +\r\n (date.getHours() < 12 ? 'AM' : 'PM')\r\n dateString = `${MONTHS[month]} ${day} ${t}`\r\n break\r\n case TIMEFRAME.d:\r\n case TIMEFRAME.w:\r\n dateString = `${MONTHS[month]} ${day}`\r\n break\r\n case TIMEFRAME.m:\r\n dateString = `${MONTHS[month]} ${year}`\r\n break\r\n default:\r\n break\r\n }\r\n\r\n return dateString\r\n}\r\n\r\nconst getIsOverlapping = ({\r\n x,\r\n textWidth,\r\n renderedLabelRanges,\r\n}: {\r\n x: number\r\n textWidth: number\r\n renderedLabelRanges: Array<{ from: number; to: number }>\r\n}) =>\r\n renderedLabelRanges.some(({ from, to }) => {\r\n const minX = x - textWidth / 2\r\n const maxX = x + textWidth / 2\r\n return (from < maxX && maxX < to) || (from < minX && minX < to)\r\n })\r\n\r\nfunction getClosestDifferentMinMaxValueIndices(\r\n currentMinIndex: number,\r\n currentMaxIndex: number,\r\n high: number[],\r\n low: number[]\r\n): { minIndex: number; maxIndex: number } {\r\n const hasPreviousIndex = currentMinIndex > 0\r\n const hasNextIndex = currentMaxIndex < high.length - 1\r\n let minIndex = currentMinIndex\r\n let maxIndex = currentMaxIndex\r\n if (hasPreviousIndex) {\r\n minIndex -= 1\r\n }\r\n if (hasNextIndex) {\r\n maxIndex += 1\r\n }\r\n\r\n if (low[minIndex] === high[maxIndex] && (hasPreviousIndex || hasNextIndex)) {\r\n return getClosestDifferentMinMaxValueIndices(minIndex, maxIndex, high, low)\r\n }\r\n\r\n return low[minIndex] < high[maxIndex] ? { minIndex, maxIndex } : { minIndex: maxIndex, maxIndex: minIndex }\r\n}\r\n\r\nconst SMALL_INDEX_CHART_LABEL_BUFFER = 15\r\n\r\nconst gray300 = tailwindColors.gray[300]\r\n\r\nclass BaseChart extends Element {\r\n static initClass() {\r\n Object.defineProperty(this.prototype, 'width', {\r\n get() {\r\n const { ChartSettings } = this.getChartLayoutSettings() as ISettings\r\n if (!this.model.width) return 0\r\n return this.model.width - ChartSettings.left.width - ChartSettings.right.width\r\n },\r\n })\r\n\r\n Object.defineProperty(this.prototype, 'height', {\r\n get() {\r\n const { ChartSettings } = this.getChartLayoutSettings() as ISettings\r\n if (!this.paneModel.height) return 0\r\n return this.paneModel.height - ChartSettings.top.height - ChartSettings.bottom.height\r\n },\r\n })\r\n }\r\n\r\n static getNumOfBarsBuffer({ overlays }: RequireByKey) {\r\n return Math.max(0, ...overlays.map((overlay) => overlaysByType[overlay.type].getNumOfBarsBuffer(overlay)))\r\n }\r\n\r\n static label = 'Chart'\r\n static iconName = ''\r\n\r\n paneModel: PaneModel\r\n model: Chart\r\n data: Quote\r\n specificChartFunctionality: SpecificChartFunctionality\r\n tickerWidth = 0\r\n changeWidth = 0\r\n lastOhlc: Array> = []\r\n overlays: Overlay[] = []\r\n isLargeChart?: boolean\r\n shouldRenderVolume = true\r\n afterChange: {\r\n x: number\r\n y: number\r\n width: number\r\n } | null = null\r\n\r\n declare setupAxisTimeFrame: string\r\n declare volumeFY: d3.ScaleLinear\r\n declare tickerText: Text\r\n declare baseCache: Cache\r\n declare leftOffset: number\r\n declare context: CanvasRenderingContext2D\r\n declare width: number\r\n declare height: number\r\n declare isMobile: boolean\r\n\r\n constructor(values: Partial, paneModel: PaneModel) {\r\n super(values, paneModel)\r\n\r\n this.paneModel = paneModel\r\n this.model = this.paneModel.chart()\r\n this.data = this.model.quote()\r\n const chartLayoutModel = this.model.chart_layout()\r\n this.specificChartFunctionality = chartLayoutModel.specificChartFunctionality\r\n this.isLargeChart = chartLayoutModel.isLargeChart\r\n this.isMobile = utils.isMobile(true)\r\n\r\n this.overlays = []\r\n if (values.overlays) {\r\n for (const overlayDefinition of values.overlays) {\r\n // overlayDefinition.color coming from DB is always string however overlays\r\n // internaly didn't use format as in db (type, color, period) but rather\r\n // more overlay specific parameters eg. (BB: topColor, bottomColor, etc.)\r\n // thus overlayDefinition.color might be undefined\r\n // approach could be reworked in https://github.com/finvizhq/charts/issues/770\r\n // but for now (!overlayDefinition.color) check solve issue as well\r\n const overlay = overlaysByType[overlayDefinition.type].fromObject(\r\n {\r\n ...overlayDefinition,\r\n color:\r\n !overlayDefinition.color || overlayDefinition.color.includes('|')\r\n ? ''\r\n : convertColorToHEX(overlayDefinition.color),\r\n },\r\n this.paneModel\r\n )\r\n this.addOverlay(overlay)\r\n }\r\n delete values.overlays\r\n }\r\n\r\n this.renderYAxis = this.renderYAxis.bind(this)\r\n this.renderText = this.renderText.bind(this)\r\n this.renderCrossText = this.renderCrossText.bind(this)\r\n this.setupCache = this.setupCache.bind(this)\r\n this.renderOverlaysLabels = this.renderOverlaysLabels.bind(this)\r\n\r\n // this.paneModel.bind('update', this.setupAxis.bind(this))\r\n this.paneModel.bind('update', this.setupCache)\r\n this.paneModel.bind('change', this.trigger.bind(this, 'change'))\r\n this.model = this.paneModel.chart()\r\n // this.model.bind('change', this.setupAxis.bind(this))\r\n this.model.bind('change', this.setupCache)\r\n this.model.bind('change', this.trigger.bind(this, 'change'))\r\n this.model.bind(CustomSpineEvents.IndicatorsChange, this.handleIndicatorsChange.bind(this))\r\n const mouseModelChangeHandler = this.trigger.bind(this, 'change', 'cross')\r\n this.model.bind('destroy', () => {\r\n this.model.unbind('change', this.setupCache)\r\n this.model.unbind(CustomSpineEvents.IndicatorsChange, this.handleIndicatorsChange.bind(this))\r\n mouseModel.unbind('change', mouseModelChangeHandler)\r\n unmountCanvas(this.baseCache.canvas)\r\n })\r\n mouseModel.bind('change', mouseModelChangeHandler)\r\n\r\n this.model.chart_layout().bind('theme', this.setupCache)\r\n this.model.chart_layout().bind('update', this.updateShouldRenderVolume.bind(this))\r\n\r\n this.setupCache()\r\n }\r\n\r\n renderChart() {\r\n throw Error('Implement renderChart')\r\n }\r\n\r\n render(context: CanvasRenderingContext2D) {\r\n this.data = this.model.quote()\r\n this.leftOffset = this.model.leftOffset\r\n this.context = context\r\n\r\n if (this.data.close.length === 0) {\r\n this.renderChartNotAvailable()\r\n if (!this.getIsRedesignedChart()) this.renderTicker(context)\r\n return\r\n }\r\n\r\n this.context.save()\r\n this.clip()\r\n this.renderVolume()\r\n this.renderChart()\r\n this.renderOverlays()\r\n this.renderPrevClose()\r\n this.renderFadeExtendedHours()\r\n this.context.restore()\r\n if (!this.getIsRedesignedChart()) this.renderTicker(context)\r\n }\r\n\r\n renderGrid(context: CanvasRenderingContext2D) {\r\n this.data = this.model.quote()\r\n this.leftOffset = this.model.leftOffset\r\n this.context = context\r\n // text, xAxis, volumeAxis\r\n this.renderXAxis()\r\n this.baseCache.render(context)\r\n }\r\n\r\n renderTicker(context: CanvasRenderingContext2D) {\r\n if (this.tickerText) {\r\n const { ChartSettings } = this.getChartLayoutSettings()\r\n context.translate(ChartSettings.left.width, 0)\r\n this.tickerText.render(context)\r\n\r\n if (getIsSmallIndexChart(this.specificChartFunctionality) && this.data.ticker === 'RUSSELL 2000') {\r\n const { Colors } = ChartSettings.general\r\n new Text(\r\n {\r\n text: 'ETF',\r\n x: ChartSettings.top.ticker.margin.left,\r\n y: ChartSettings.top.ticker.margin.top! + FONT_SIZE.XXS + OFFSET.XXS,\r\n font: { size: FONT_SIZE.XXS },\r\n fillStyle: Colors.text,\r\n textBaseline: ChartSettings.top.baseline,\r\n },\r\n this.paneModel\r\n ).render(context)\r\n }\r\n\r\n context.translate(-ChartSettings.left.width, 0)\r\n }\r\n }\r\n\r\n renderTimeframe(context: CanvasRenderingContext2D) {\r\n const { ChartSettings } = this.getChartLayoutSettings()\r\n const { Colors } = ChartSettings.general\r\n const quote = this.model.quote()\r\n const y = (this.height - this.volumeFY.range()[1] - 4) / 2\r\n\r\n return new Text(\r\n {\r\n text: quote.instrument === Instrument.Group ? 'YEAR PERFORMANCE %' : getTimeframeLabel(quote.timeframe),\r\n x: ChartSettings.left.timeframe.margin.left,\r\n y: ChartSettings.top.height + y + (ChartSettings.left.timeframe.margin.top ?? 0),\r\n angle: -90,\r\n font: Text.getMergedPropsWithDefaults('font', ChartSettings.left.timeframe.font),\r\n fillStyle: Colors.textSecondary,\r\n textAlign: TextAlign.center,\r\n textBaseline: TextBaseline.alphabetic,\r\n },\r\n this.paneModel\r\n ).render(context)\r\n }\r\n\r\n renderText(context: CanvasRenderingContext2D) {\r\n const { ChartSettings, isOurSiteRequest } = this.getChartLayoutSettings()\r\n const { Colors } = ChartSettings.general\r\n context.save()\r\n context.translate(ChartSettings.left.width, 0)\r\n\r\n if (!getIsSmallIndexChart(this.specificChartFunctionality)) {\r\n this.tickerText = new Text(\r\n {\r\n text: this.data.name || this.data.ticker,\r\n x: ChartSettings.top.ticker.margin.left,\r\n y: ChartSettings.top.ticker.margin.top,\r\n font: Text.getMergedPropsWithDefaults('font', ChartSettings.top.ticker.font),\r\n textBaseline: ChartSettings.top.baseline,\r\n fillStyle: Colors.text,\r\n },\r\n this.paneModel\r\n )\r\n } else {\r\n this.tickerText = new Text(\r\n {\r\n text: this.data.name || this.data.ticker,\r\n x: ChartSettings.top.ticker.margin.left,\r\n y: ChartSettings.top.ticker.margin.top,\r\n font: { size: FONT_SIZE.L, style: 'bold' },\r\n fillStyle: Colors.text,\r\n },\r\n this.paneModel\r\n )\r\n }\r\n this.tickerWidth = this.tickerText.measure(context)\r\n\r\n // render watermark on backend chart\r\n if (this.specificChartFunctionality === SpecificChartFunctionality.offScreen) {\r\n let yOffset = 0\r\n if (!isOurSiteRequest) {\r\n yOffset = this.isLargeChart ? -2 : -3\r\n }\r\n new Text(\r\n {\r\n text: '© finviz.com',\r\n x: this.width + ChartSettings.right.width - 2,\r\n y: 1 + yOffset,\r\n font: { size: isOurSiteRequest ? FONT_SIZE.XS : FONT_SIZE.M },\r\n textAlign: TextAlign.right,\r\n textBaseline: TextBaseline.top,\r\n fillStyle: isOurSiteRequest ? 'rgb(136, 193, 233)' : tailwindColors.finviz.blue,\r\n },\r\n this.paneModel\r\n ).render(context)\r\n }\r\n\r\n if (!this.getIsRedesignedChart()) {\r\n this.renderChange({ context })\r\n if (!this.lastOhlc[0]) {\r\n this.getOHLC({ context, directRender: false })\r\n }\r\n this.getOHLC({ context })\r\n }\r\n\r\n context.restore()\r\n if (!this.getIsRedesignedChart() && !getIsSmallIndexChart(this.specificChartFunctionality)) {\r\n this.renderTimeframe(context)\r\n }\r\n }\r\n\r\n getOHLC({\r\n context,\r\n directRender = true,\r\n data,\r\n date,\r\n dateString = null,\r\n changePercentage = null,\r\n }: {\r\n context: CanvasRenderingContext2D\r\n directRender?: boolean\r\n data?: {\r\n open?: string\r\n high?: string\r\n low?: string\r\n close?: string\r\n volume?: string\r\n }\r\n date?: Date\r\n dateString?: string | null\r\n changePercentage?: ITickerChange | null\r\n }) {\r\n if (!this.data.lastDate) return\r\n\r\n // modulo \"parsing\" is 100% faster than with str.slice()\r\n const lastDate = `${MONTHS[(~~(this.data.lastDate / 100) % 100) - 1]} ${this.data.lastDate % 100}` // YYYYMMDD / 20211118 => Nov 18\r\n if (getIsSmallIndexChart(this.specificChartFunctionality)) {\r\n this.renderOHLC({\r\n context,\r\n date: lastDate,\r\n isSmallIndexChart: true,\r\n isNewestOHLC: true,\r\n directRender,\r\n })\r\n } else if (data && date) {\r\n this.renderOHLC({\r\n context,\r\n date: getDateString({ date, timeframe: this.data.timeframe }),\r\n open: data.open,\r\n high: data.high,\r\n low: data.low,\r\n close: data.close,\r\n volume: numberToStringWithUnitsSuffix(Number(data.volume)),\r\n directRender,\r\n changePercentage,\r\n })\r\n } else if (dateString !== null) {\r\n this.renderOHLC({\r\n context,\r\n date: dateString,\r\n open: null,\r\n high: null,\r\n low: null,\r\n close: null,\r\n volume: null,\r\n directRender,\r\n })\r\n } else {\r\n this.renderOHLC({\r\n context,\r\n date: lastDate,\r\n afterHour:\r\n Number.isFinite(this.data.afterClose) && this.data.afterClose !== this.data.lastClose\r\n ? this.roundOhlc(this.data.afterClose)\r\n : undefined,\r\n volume: numberToStringWithUnitsSuffix(this.data.lastVolume),\r\n isNewestOHLC: true,\r\n time: utils.dateFromUnixTimestamp(this.data.date.last()!).toLocaleTimeString('en-US', {\r\n hour: '2-digit',\r\n minute: '2-digit',\r\n }),\r\n directRender,\r\n ...this.getRoundedLastData(),\r\n })\r\n }\r\n }\r\n\r\n getRoundedLastData() {\r\n return {\r\n open: this.roundOhlc(this.data.lastOpen),\r\n high: this.roundOhlc(this.data.lastHigh),\r\n low: this.roundOhlc(this.data.lastLow),\r\n close: this.roundOhlc(this.data.lastClose),\r\n }\r\n }\r\n\r\n renderOverlaysLabels(context: CanvasRenderingContext2D) {\r\n if (!this.getIsRedesignedChart()) {\r\n this.renderOverlaysLabelsQuotePage(context)\r\n } else if (this.data.close.length !== 0) {\r\n this.renderOverlaysLabelsChartsPage(context)\r\n }\r\n }\r\n\r\n renderOverlaysLabelsQuotePage(context: CanvasRenderingContext2D) {\r\n const { ChartSettings } = this.getChartLayoutSettings()\r\n const text = new Text(\r\n {\r\n x: ChartSettings.left.overlayLabel.margin.left,\r\n y: ChartSettings.top.height + ChartSettings.left.overlayLabel.margin.top!,\r\n font: Text.getMergedPropsWithDefaults('font', ChartSettings.left.overlayLabel.font),\r\n textBaseline: TextBaseline.top,\r\n },\r\n this.paneModel\r\n )\r\n for (const overlay of this.overlays) {\r\n if (!overlay.isRenderedOverlaysLabel()) {\r\n continue\r\n }\r\n text\r\n .set({\r\n text: overlay.toString(),\r\n y: text.get('y')! + ChartSettings.left.overlayLabel.labelSpacing,\r\n fillStyle: overlay.getLabelColor(),\r\n })\r\n .render(context)\r\n }\r\n }\r\n\r\n getYAxisLeftMargin() {\r\n if (this.data.instrument === Instrument.Crypto && this.data.lastClose <= 0.001) {\r\n return 3\r\n }\r\n return 8\r\n }\r\n\r\n getYAxisLastCloseLabel({ lastClose, firstVisibleClose }: { lastClose: number; firstVisibleClose?: number | null }) {\r\n if (typeof firstVisibleClose === 'number' && this.model.scale === ScaleType.Percentage) {\r\n return `${this.round(getPercentageFromValue({ number: lastClose, base: firstVisibleClose }), 2)}%`\r\n }\r\n return this.round(lastClose)\r\n }\r\n\r\n renderYAxis(\r\n context: CanvasRenderingContext2D,\r\n { lastClose }: RequireByKey, 'lastClose'> = this.data,\r\n renderLabels = true\r\n ) {\r\n const { ChartSettings } = this.getChartLayoutSettings()\r\n const { Colors } = ChartSettings.general\r\n let y, lineTicks, textTicks, lastCloseLabel\r\n const translate = getTranslate({ context, xOffset: ChartSettings.left.width, yOffset: ChartSettings.top.height })\r\n translate.do()\r\n const tickCount = Math.floor(this.paneModel.height / 35)\r\n const minMax = this.getMinMax()\r\n const { firstVisibleClose } = minMax\r\n const height = this.height\r\n let stepPrice = 0\r\n let placesAxis\r\n\r\n switch (this.model.scale) {\r\n case ScaleType.Percentage: {\r\n if (!firstVisibleClose) return\r\n\r\n const scaleRange = this.paneModel.scaleRange\r\n const { min, max } = scaleRange || minMax\r\n\r\n this.model.updateAttribute('firstBarClose', firstVisibleClose)\r\n\r\n const minPerc = getPercentageFromValue({ number: min, base: firstVisibleClose })\r\n const maxPerc = getPercentageFromValue({ number: max, base: firstVisibleClose })\r\n\r\n const percScale = d3.scaleLinear().range([0, this.height]).domain([maxPerc, minPerc]).nice(10)\r\n textTicks = percScale.ticks(Math.min(tickCount, 9))\r\n lineTicks = textTicks.map((tick) => getValueFromPercentage({ number: tick, base: firstVisibleClose }))\r\n lastCloseLabel = this.getYAxisLastCloseLabel({ lastClose, firstVisibleClose })\r\n break\r\n }\r\n case ScaleType.Logarithmic: {\r\n if (!firstVisibleClose) return\r\n\r\n const scaleRange = this.paneModel.scaleRange\r\n const { min, max } = scaleRange || minMax\r\n lineTicks = [Math.floor(min)]\r\n const pixelGap = 30\r\n\r\n const negativeScale = []\r\n if (min < 0) {\r\n let previousNegativeTick = Math.min(0, max)\r\n while (this.paneModel.scale.y(previousNegativeTick) + pixelGap < this.paneModel.scale.y(min)) {\r\n const tick = this.paneModel.scale.y.invert(this.paneModel.scale.y(previousNegativeTick) + pixelGap)\r\n if (previousNegativeTick === tick) {\r\n break\r\n }\r\n const range = d3.nice(-previousNegativeTick, -tick, 2)\r\n previousNegativeTick = -range[range.length - 1]\r\n negativeScale.unshift(previousNegativeTick)\r\n }\r\n }\r\n\r\n const positiveScale = []\r\n if (max > 0) {\r\n positiveScale.push(Math.max(this.paneModel.scale.y.invert(this.paneModel.scale.y(min) + pixelGap), 0))\r\n }\r\n while (this.paneModel.scale.y(positiveScale[positiveScale.length - 1]) - pixelGap > 0) {\r\n const previousTick = positiveScale[positiveScale.length - 1]\r\n const positiveScaleY = this.paneModel.scale.y(positiveScale[positiveScale.length - 1])\r\n const tick = this.paneModel.scale.y.invert(positiveScaleY - pixelGap)\r\n if (previousTick === tick) {\r\n break\r\n }\r\n\r\n const range = d3.nice(previousTick, tick, 2)\r\n positiveScale.push(range[range.length - 1])\r\n }\r\n lineTicks = [...negativeScale, ...positiveScale]\r\n textTicks = lineTicks\r\n lastCloseLabel = this.getYAxisLastCloseLabel({ lastClose })\r\n break\r\n }\r\n default:\r\n // default to linear scale type\r\n lineTicks = this.paneModel.scale.y.ticks(Math.min(tickCount, 9))\r\n textTicks = lineTicks\r\n lastCloseLabel = this.getYAxisLastCloseLabel({ lastClose })\r\n }\r\n\r\n if (textTicks.length >= 2) {\r\n stepPrice = Math.abs(textTicks[1] - textTicks[0])\r\n }\r\n if (\r\n stepPrice > 10 ||\r\n (getIsSmallIndexChart(this.specificChartFunctionality) && Math.round(textTicks[0]).toString().length > 3) // if small index chart max tick is less than 999 (3 digits) allow for decimals in axis labels\r\n ) {\r\n placesAxis = 0\r\n }\r\n\r\n const getYLineText = (val: number, places?: number) => {\r\n switch (this.model.scale) {\r\n case ScaleType.Percentage:\r\n return `${val}%`\r\n default:\r\n return this.round(val, places)\r\n }\r\n }\r\n\r\n const yTickText = new Text(\r\n {\r\n x: this.width + this.getYAxisLeftMargin() + ChartSettings.right.axis.margin.left!,\r\n font: Text.getMergedPropsWithDefaults('font', ChartSettings.right.axis.font),\r\n fillStyle: Colors.text,\r\n textBaseline: TextBaseline.middle,\r\n },\r\n this.paneModel\r\n )\r\n\r\n let yTickLine = this.getYLine()\r\n const resetYTicksStyles = () => {\r\n yTickText.set({\r\n font: Text.getMergedPropsWithDefaults('font', ChartSettings.right.axis.font),\r\n fillStyle: Colors.text,\r\n textBaseline: TextBaseline.middle,\r\n })\r\n yTickLine = this.getYLine()\r\n }\r\n for (let i = 0; i < lineTicks.length; i++) {\r\n y = Math.round(this.fy(lineTicks[i]))\r\n if (y < 0 || y > height) continue\r\n yTickLine.set({ y1: y, y2: y })\r\n yTickText.set({\r\n text: getYLineText(textTicks[i], placesAxis),\r\n y,\r\n })\r\n if (this.model.scale === ScaleType.Percentage && textTicks[i] === 0) {\r\n yTickLine.set({ strokeStyle: Colors.text })\r\n yTickText.set({\r\n font: { weight: 'bold', size: yTickText.attrs.font.size },\r\n fillStyle: Colors.percentageZeroLineText,\r\n })\r\n yTickLine.render(context)\r\n yTickText.render(context)\r\n resetYTicksStyles()\r\n } else {\r\n yTickLine.render(context)\r\n yTickText.render(context)\r\n }\r\n }\r\n translate.undo()\r\n\r\n if (renderLabels) {\r\n this.renderYAxisLabel({ context, yCoordinate: Math.round(this.fy(lastClose)), label: lastCloseLabel })\r\n // if (typeof this.data.afterClose === 'number') {\r\n // this.renderYAxisLabel({\r\n // context,\r\n // yCoordinate: this.getYAxisSecondaryLabelYCoordinate({\r\n // mainLabelValue: lastClose,\r\n // secondaryLabelValue: this.data.afterClose,\r\n // }),\r\n // label: this.getYAxisLastCloseLabel({ lastClose: this.data.afterClose, firstVisibleClose }),\r\n // background: this.getSecondaryLabelBackgroundColor(),\r\n // })\r\n // }\r\n }\r\n }\r\n\r\n getSecondaryLabelBackgroundColor() {\r\n return stringifyHSVAColor(\r\n {\r\n ...getHSVAFromColor(this.getChartLayoutSettings().ChartSettings.general.Colors.currentBackground),\r\n s: 0.3,\r\n },\r\n 'hex'\r\n )\r\n }\r\n\r\n getYAxisSecondaryLabelYCoordinate({\r\n mainLabelValue,\r\n secondaryLabelValue,\r\n }: {\r\n mainLabelValue: number\r\n secondaryLabelValue: number\r\n }) {\r\n const { ChartSettings } = this.getChartLayoutSettings()\r\n const { lineHeight } = ChartSettings.right.axis.font\r\n const padding = Text.getMergedPropsWithDefaults('padding', ChartSettings.right.axis.font.padding)\r\n\r\n const direction = Math.sign(mainLabelValue - secondaryLabelValue) || 1\r\n const offset = (lineHeight ?? LINE_HEIGHT.S) + (padding.top ?? PADDING.XXS) + (padding.bottom ?? PADDING.XXS)\r\n const mainLabelValuePosition = Math.round(this.fy(mainLabelValue))\r\n const secondaryLabelValuePosition = Math.round(this.fy(secondaryLabelValue))\r\n const offsetedY = mainLabelValuePosition + offset * direction\r\n\r\n return Math.abs(secondaryLabelValuePosition - mainLabelValuePosition) > offset\r\n ? secondaryLabelValuePosition\r\n : offsetedY\r\n }\r\n\r\n renderYAxisLabel({\r\n context,\r\n yCoordinate,\r\n label,\r\n background,\r\n }: {\r\n context: CanvasRenderingContext2D\r\n yCoordinate: number\r\n label: string\r\n background?: string\r\n }) {\r\n const { ChartSettings } = this.getChartLayoutSettings()\r\n const translate = getTranslate({ context, xOffset: ChartSettings.left.width, yOffset: ChartSettings.top.height })\r\n const { Colors } = ChartSettings.general\r\n const { size, lineHeight } = ChartSettings.right.axis.font\r\n const padding = Text.getMergedPropsWithDefaults('padding', ChartSettings.right.axis.font.padding)\r\n\r\n translate.do()\r\n new Text(\r\n {\r\n text: label,\r\n x: this.width + this.getYAxisLeftMargin() - padding.left + ChartSettings.right.axis.margin.left!,\r\n y: yCoordinate,\r\n font: Text.getMergedPropsWithDefaults('font', { size, style: 'bold' }),\r\n lineHeight,\r\n padding,\r\n textBaseline: TextBaseline.middle,\r\n fillStyle:\r\n this.specificChartFunctionality === SpecificChartFunctionality.offScreen ? 'black' : Colors.currentText,\r\n background: background || Colors.currentBackground,\r\n },\r\n this.paneModel\r\n ).render(context)\r\n translate.undo()\r\n }\r\n\r\n renderXAxis() {\r\n const { leftOffset, width } = this\r\n const { ChartSettings } = this.getChartLayoutSettings()\r\n const { Colors } = ChartSettings.general\r\n\r\n this.context.save()\r\n if (\r\n this.data.getDrawDays() !== 1 &&\r\n !getIsSmallIndexChart(this.specificChartFunctionality) &&\r\n this.data.instrument !== Instrument.MarketSentiment\r\n ) {\r\n this.clip(true)\r\n }\r\n this.context.translate(ChartSettings.left.width, ChartSettings.top.height)\r\n const textRenderer = new Text(\r\n {\r\n y: this.height + ChartSettings.bottom.axis.margin.top!,\r\n font: Text.getMergedPropsWithDefaults('font', { size: ChartSettings.bottom.axis.font.size }),\r\n fillStyle: Colors.text,\r\n textBaseline: TextBaseline.top,\r\n textAlign: TextAlign.center,\r\n },\r\n this.paneModel\r\n )\r\n\r\n // Ticks are placed at the start of each timeframe period (hour/day/month/year).\r\n // The \"-1\" in the code ensures we start searching from one bar outside the visible area,\r\n // avoiding a tick on the first visible index unless it marks the start of a new timeframe period.\r\n // For example, if the start of December is on December 3rd and the first visible bar is on December 14th,\r\n // we won't display a tick.\r\n const startBarIndex = Math.max(\r\n getVisibleBarToRenderIndex({\r\n quote: this.data,\r\n paneModel: this.paneModel,\r\n leftOffset,\r\n }).index - 1,\r\n 0\r\n )\r\n\r\n const endBarIndex = Math.min(\r\n getVisibleBarToRenderIndex({\r\n quote: this.data,\r\n paneModel: this.paneModel,\r\n leftOffset,\r\n chartWidth: width,\r\n }).index + 1,\r\n this.data.close.length - 1\r\n )\r\n\r\n switch (this.data.timeframe) {\r\n case TIMEFRAME.i1:\r\n case TIMEFRAME.i2:\r\n case TIMEFRAME.i3:\r\n case TIMEFRAME.i5:\r\n if (this.data.instrument === Instrument.Stock) {\r\n if (\r\n this.type === ChartElementType.LineChart &&\r\n this.specificChartFunctionality === SpecificChartFunctionality.offScreen &&\r\n this.data.timeframe === 'i5'\r\n ) {\r\n this.render15MinXAxis({ textRenderer, startBarIndex, endBarIndex })\r\n } else {\r\n this.renderIntradayXAxis(textRenderer)\r\n }\r\n } else {\r\n this.renderIntradayXAxisFutures({ textRenderer, startBarIndex, endBarIndex })\r\n }\r\n break\r\n case TIMEFRAME.i10:\r\n if (getIsSmallIndexChart(this.specificChartFunctionality)) {\r\n this.renderIntradayXAxis(textRenderer)\r\n } else {\r\n this.render15MinXAxis({ textRenderer, startBarIndex, endBarIndex })\r\n }\r\n break\r\n case TIMEFRAME.i15:\r\n case TIMEFRAME.i30:\r\n case TIMEFRAME.h:\r\n case TIMEFRAME.h2:\r\n case TIMEFRAME.h4:\r\n this.render15MinXAxis({ textRenderer, startBarIndex, endBarIndex })\r\n break\r\n case TIMEFRAME.d:\r\n this.renderDailyXAxis({ textRenderer, startBarIndex, endBarIndex })\r\n break\r\n case TIMEFRAME.w:\r\n this.renderWeeklyXAxis({ textRenderer, startBarIndex, endBarIndex })\r\n break\r\n case TIMEFRAME.m:\r\n this.renderMonthlyXAxis({ textRenderer, startBarIndex, endBarIndex })\r\n break\r\n default:\r\n break\r\n }\r\n this.context.restore()\r\n }\r\n\r\n isXPointVisible(x: number, buffer = 0) {\r\n return x >= 0 - buffer && x <= this.width + buffer\r\n }\r\n\r\n renderXAxisLabels({\r\n labels,\r\n textRenderer,\r\n allowedOverflow = 0,\r\n }: {\r\n labels: Omit[]\r\n textRenderer: Text\r\n allowedOverflow?: number\r\n }) {\r\n const sortedLabels: XAxisLabel[] = []\r\n const renderedLabelRanges: Array<{ from: number; to: number }> = []\r\n labels.reverse().forEach((label) => {\r\n textRenderer.set({ text: label.text })\r\n const textWidth = Math.floor(textRenderer.measure(this.context))\r\n const newLabel = { ...label, textWidth }\r\n if (label.hasPriority) {\r\n sortedLabels.unshift(newLabel)\r\n } else {\r\n sortedLabels.push(newLabel)\r\n }\r\n })\r\n\r\n sortedLabels.forEach(({ x, text, textWidth }) => {\r\n if (!this.isXPointVisible(x, allowedOverflow)) {\r\n return\r\n }\r\n const halfOfTextWidth = textWidth / 2\r\n const overflowLeft = x - halfOfTextWidth + allowedOverflow\r\n const overflowRight = this.width - (x + halfOfTextWidth) + allowedOverflow\r\n let labelX = x\r\n if (overflowLeft < 0) {\r\n labelX = Math.round(x - overflowLeft)\r\n } else if (overflowRight < 0) {\r\n labelX = Math.round(x + overflowRight)\r\n }\r\n if (getIsOverlapping({ x: labelX, textWidth, renderedLabelRanges })) {\r\n return\r\n }\r\n renderedLabelRanges.push({\r\n from: labelX - halfOfTextWidth - OFFSET.M,\r\n to: labelX + halfOfTextWidth + OFFSET.M,\r\n })\r\n textRenderer.set({ text, x: labelX })\r\n textRenderer.render(this.context)\r\n })\r\n }\r\n\r\n renderIntradayXAxis(textRenderer: Text) {\r\n const interval = IntradayTimeframeInterval[this.data.timeframe as keyof typeof IntradayTimeframeInterval]\r\n const marketStartHour = ~~(this.data.marketStartMinutes / 60)\r\n let marketEndHour = 15 + Math.ceil(this.data.aftermarketLengthMinutes / 60)\r\n const labels = []\r\n if (getIsSmallIndexChart(this.specificChartFunctionality)) {\r\n marketEndHour = 16\r\n }\r\n\r\n const xLine = this.getXLine()\r\n const barWidth = getBarWidthWithMargin({\r\n zoomFactor: this.model.zoomFactor,\r\n chartLayout: this.model.chart_layout(),\r\n })\r\n\r\n const dayToOffset = this.data.getDayToOffset()\r\n const isSmallIndexChart = getIsSmallIndexChart(this.specificChartFunctionality)\r\n const allowedOverflow = isSmallIndexChart ? SMALL_INDEX_CHART_LABEL_BUFFER : 0\r\n for (const day in dayToOffset) {\r\n const dayIndex = dayToOffset[day]\r\n const date = dateFromDateString(day)\r\n\r\n for (let i = marketStartHour; i <= marketEndHour; i++) {\r\n let x =\r\n ((i * 60 - this.data.marketStartMinutes) / interval) * barWidth +\r\n dayIndex * (this.data.drawMinutesPerDay / interval) * barWidth +\r\n this.leftOffset\r\n if (!this.isXPointVisible(x, allowedOverflow)) {\r\n continue\r\n }\r\n let roundedX = Math.round(x)\r\n\r\n if (i === marketStartHour) {\r\n if (isSmallIndexChart) {\r\n roundedX = Math.round(x - 3 + (30 / interval) * barWidth)\r\n // ~9:30AM\r\n xLine\r\n .set({\r\n x1: roundedX,\r\n x2: roundedX,\r\n })\r\n .render(this.context)\r\n continue\r\n }\r\n if (this.data.premarketLengthMinutes === 0) {\r\n // If there is no premarket, day starts at 9:30 AM\r\n x += (30 / interval) * barWidth\r\n }\r\n roundedX = Math.round(x)\r\n xLine.set({ x1: roundedX, x2: roundedX }).render(this.context)\r\n labels.push({\r\n hasPriority: true,\r\n text: MONTHS[date.getMonth()] + ' ' + date.getDate().toString().padLeft('00'),\r\n x: roundedX,\r\n })\r\n } else {\r\n xLine.set({ x1: roundedX, x2: roundedX }).render(this.context)\r\n labels.push({\r\n text: ((i + 11) % 12) + 1 + (i < 12 ? 'AM' : 'PM'),\r\n x: roundedX,\r\n })\r\n }\r\n }\r\n }\r\n this.renderXAxisLabels({ labels, textRenderer, allowedOverflow })\r\n }\r\n\r\n renderIntradayXAxisFutures({ textRenderer, startBarIndex, endBarIndex }: IRenderXAxisProps) {\r\n let lastDay = ''\r\n let lastHours = NaN\r\n\r\n const labels = []\r\n const xLine = this.getXLine()\r\n for (let i = startBarIndex; i <= endBarIndex; i++) {\r\n const date = utils.dateFromUnixTimestamp(this.data.date[i])\r\n const day = date.getDate() + '-' + date.getMonth()\r\n const hours = date.getHours()\r\n const x = Math.round(this.fx(i) + this.leftOffset)\r\n\r\n if (day !== lastDay) {\r\n lastDay = day\r\n lastHours = hours\r\n if (!this.isXPointVisible(x)) {\r\n continue\r\n }\r\n xLine.set({ x1: x, x2: x }).render(this.context)\r\n labels.push({\r\n x,\r\n text: MONTHS[date.getMonth()] + ' ' + date.getDate().toString().padLeft('00'),\r\n })\r\n } else if (hours % 2 === 0 && hours !== lastHours) {\r\n lastHours = hours\r\n if (!this.isXPointVisible(x)) {\r\n continue\r\n }\r\n xLine.set({ x1: x, x2: x }).render(this.context)\r\n labels.push({ x, text: ((hours + 11) % 12) + 1 + (hours < 12 ? 'AM' : 'PM') })\r\n }\r\n }\r\n this.renderXAxisLabels({ labels, textRenderer })\r\n }\r\n\r\n render15MinXAxis({ textRenderer, startBarIndex, endBarIndex }: IRenderXAxisProps) {\r\n let lastDay = ''\r\n let x = 0\r\n\r\n const labels = []\r\n const xLine = this.getXLine()\r\n for (let i = startBarIndex; i <= endBarIndex; i++) {\r\n const date = utils.dateFromUnixTimestamp(this.data.date[i])\r\n const day = date.getDate() + '-' + date.getMonth()\r\n if (day !== lastDay) {\r\n lastDay = day\r\n if (this.data.instrument === Instrument.Stock) {\r\n const barAtMinute = date.getMinutes() + date.getHours() * 60\r\n const indexOffset = (barAtMinute - this.data.marketStartMinutes) / this.data.interval\r\n x = Math.round(this.paneModel.scale.x(this.data.barIndex[i] - indexOffset) + this.leftOffset)\r\n } else {\r\n x = Math.round(this.fx(i) + this.leftOffset)\r\n }\r\n if (!this.isXPointVisible(x)) {\r\n continue\r\n }\r\n xLine.set({ x1: x, x2: x }).render(this.context)\r\n labels.push({\r\n text: MONTHS[date.getMonth()] + ' ' + date.getDate().toString().padLeft('00'),\r\n x,\r\n })\r\n }\r\n }\r\n\r\n // Offscreen only - if lastDate !== lastBarDate add tick\r\n if (this.specificChartFunctionality === SpecificChartFunctionality.offScreen) {\r\n const lastDate = `${MONTHS[(~~(this.data.lastDate / 100) % 100) - 1]} ${(this.data.lastDate % 100)\r\n .toString()\r\n .padLeft('00')}` // YYYYMMDD / 20211118 => Nov 18\r\n\r\n if (labels.length > 0 && labels[labels.length - 1].text !== lastDate) {\r\n const barsInDay = this.data.getBarsInDay()!\r\n const barWidth = getBarWidthWithMargin({\r\n zoomFactor: this.model.zoomFactor,\r\n chartLayout: this.model.chart_layout(),\r\n })\r\n const dayWidth = barsInDay * barWidth\r\n x += dayWidth\r\n labels.push({\r\n text: lastDate,\r\n x,\r\n })\r\n xLine.set({ x1: x, x2: x }).render(this.context)\r\n }\r\n }\r\n\r\n this.renderXAxisLabels({ labels, textRenderer })\r\n }\r\n\r\n renderDailyXAxis({ textRenderer, startBarIndex, endBarIndex }: IRenderXAxisProps) {\r\n let lastMonth = ''\r\n\r\n const labels = []\r\n const xLine = this.getXLine()\r\n for (let i = startBarIndex; i <= endBarIndex; i++) {\r\n const date = utils.dateFromUnixTimestamp(this.data.date[i])\r\n const month = date.getMonth() + '-' + date.getFullYear()\r\n if (month !== lastMonth) {\r\n lastMonth = month\r\n const x = Math.round(this.fx(i) + this.leftOffset)\r\n if (!this.isXPointVisible(x)) {\r\n continue\r\n }\r\n xLine.set({ x1: x, x2: x }).render(this.context)\r\n labels.push({\r\n hasPriority: date.getMonth() === 0,\r\n text: date.getMonth() === 0 ? date.getFullYear().toString() : MONTHS[date.getMonth()],\r\n x,\r\n })\r\n }\r\n }\r\n this.renderXAxisLabels({ labels, textRenderer })\r\n }\r\n\r\n renderWeeklyXAxis({ textRenderer, startBarIndex, endBarIndex }: IRenderXAxisProps) {\r\n let lastMonth = ''\r\n\r\n const labels = []\r\n const xLine = this.getXLine()\r\n const { Colors } = this.getChartLayoutSettings().ChartSettings.general\r\n for (let i = startBarIndex; i <= endBarIndex; i++) {\r\n const date = utils.dateFromUnixTimestamp(this.data.date[i])\r\n const month = date.getMonth() + '-' + date.getFullYear()\r\n if (month !== lastMonth) {\r\n lastMonth = month\r\n const x = Math.round(this.fx(i) + this.leftOffset)\r\n if (!this.isXPointVisible(x)) {\r\n continue\r\n }\r\n if (date.getMonth() % 3 === 0) {\r\n xLine.set({ x1: x, x2: x }).render(this.context)\r\n } else {\r\n new Line(\r\n {\r\n x1: x,\r\n x2: x,\r\n y1: 0,\r\n y2: this.height,\r\n strokeStyle: Colors.gridSecondary,\r\n dashLength: 3,\r\n },\r\n this.paneModel\r\n ).render(this.context)\r\n }\r\n const isYearLabel = date.getMonth() === 0\r\n labels.push({\r\n text: isYearLabel ? date.getFullYear().toString().substring(2) : MONTHS[date.getMonth()][0],\r\n hasPriority: isYearLabel,\r\n x,\r\n })\r\n }\r\n }\r\n this.renderXAxisLabels({ labels, textRenderer })\r\n }\r\n\r\n renderMonthlyXAxis({ textRenderer, startBarIndex, endBarIndex }: IRenderXAxisProps) {\r\n let lastYear = null\r\n\r\n const labels = []\r\n const xLine = this.getXLine()\r\n for (let i = startBarIndex; i <= endBarIndex; i++) {\r\n const date = utils.dateFromUnixTimestamp(this.data.date[i])\r\n const year = date.getFullYear()\r\n const isJanuary = date.getMonth() === 0\r\n if (year !== lastYear && (labels.length !== 0 || isJanuary)) {\r\n lastYear = year\r\n const x = Math.round(this.fx(i) + this.leftOffset)\r\n if (!this.isXPointVisible(x)) {\r\n continue\r\n }\r\n xLine.set({ x1: x, x2: x }).render(this.context)\r\n labels.push({\r\n text: date.getFullYear().toString(),\r\n x,\r\n })\r\n }\r\n }\r\n this.renderXAxisLabels({ labels, textRenderer })\r\n }\r\n\r\n handleIndicatorsChange() {\r\n this.updateShouldRenderVolume()\r\n this.setupCache()\r\n this.trigger('change')\r\n }\r\n\r\n updateShouldRenderVolume() {\r\n this.shouldRenderVolume = !this.model.chart_layout().getIsIndicatorPresent(IndicatorType.Vol)\r\n }\r\n\r\n getVolumeTicks(count: number, maxHeight: number, fontHeight: number): number[] {\r\n const maxCount = 5\r\n const minCount = 1\r\n if (count > maxCount) {\r\n count = maxCount\r\n }\r\n const ticks = this.volumeFY.ticks(count).filter((tick) => tick !== 0)\r\n if (count <= minCount) {\r\n return [ticks[ticks.length - 1]]\r\n }\r\n // ticks are rendered on middle line so we have +- 1/2 of font size above and below range[min,max]\r\n // so we already have +-1 fontsize space, but in some cases that wouldn't be enough so we need to scale\r\n // dynamically, we add 3px of space per tick gap\r\n if (ticks.length * fontHeight + (ticks.length - 1) * 3 > maxHeight) {\r\n return this.getVolumeTicks(count - 1, maxHeight, fontHeight)\r\n }\r\n return ticks\r\n }\r\n\r\n renderVolumeAxis(context: CanvasRenderingContext2D) {\r\n const { ChartSettings } = this.getChartLayoutSettings()\r\n const { Colors } = ChartSettings.general\r\n if (getIsSmallIndexChart(this.specificChartFunctionality)) {\r\n context.save()\r\n const relativeVolume = Math.max(0, Math.min(2, this.data.relativeVolume))\r\n\r\n const x = 20\r\n const fy = (y: number) => ChartSettings.top.height + this.height - this.height * (0.5 * y)\r\n const height = this.height * (0.5 * relativeVolume)\r\n\r\n const label = new Text(\r\n {\r\n x: 15,\r\n font: { size: 8 },\r\n fillStyle: Colors.text,\r\n textBaseline: TextBaseline.middle,\r\n textAlign: TextAlign.right,\r\n },\r\n this.paneModel\r\n )\r\n for (let i = 0.5; i <= 2; i += 0.5) {\r\n const y = Math.round(fy(i))\r\n label\r\n .set({\r\n text: i.toFixed(1),\r\n y: y,\r\n })\r\n .render(context)\r\n\r\n context.set('strokeStyle', 'rgb(130, 130, 130)')\r\n context.beginPath()\r\n context.setLineDash([2, 3])\r\n context.translate(0, 0.5)\r\n context.moveTo(x, y)\r\n context.lineTo(x + 7, y)\r\n context.translate(0, -0.5)\r\n context.stroke()\r\n }\r\n\r\n context.set('fillStyle', 'rgba(0, 135, 255, 0.58)')\r\n context.set('lineWidth', 1)\r\n context.set('strokeStyle', Colors.grid)\r\n context.setLineDash([])\r\n\r\n context.fillRect(x, Math.round(ChartSettings.top.height + this.height - height), 7, Math.round(height))\r\n context.translate(0.5, 0.5)\r\n context.strokeRect(x, ChartSettings.top.height, 7, this.height)\r\n context.translate(-0.5, -0.5)\r\n\r\n new Text(\r\n {\r\n text: 'RELATIVE\\nVOLUME',\r\n x: 33,\r\n y: ChartSettings.top.height + this.height + 6,\r\n font: { size: FONT_SIZE.XXS },\r\n lineHeight: LINE_HEIGHT.XS,\r\n fillStyle: Colors.text,\r\n textBaseline: TextBaseline.top,\r\n textAlign: TextAlign.right,\r\n },\r\n this.paneModel\r\n ).render(context)\r\n context.restore()\r\n return\r\n }\r\n const rangeMax = this.volumeFY.range()[1]\r\n const volumeAxisFontSize = ChartSettings.left.volumeAxis.font.size!\r\n const tickCount = Math.floor(rangeMax / volumeAxisFontSize)\r\n const ticks = this.getVolumeTicks(tickCount, rangeMax, volumeAxisFontSize)\r\n const format = this.volumeFY.tickFormat(4, 's')\r\n const text = new Text(\r\n {\r\n x: ChartSettings.left.volumeAxis.margin.left,\r\n font: Text.getMergedPropsWithDefaults('font', { size: ChartSettings.left.volumeAxis.font.size }),\r\n fillStyle: Colors.text,\r\n textBaseline: TextBaseline.middle,\r\n textAlign: TextAlign.right,\r\n },\r\n this.paneModel\r\n )\r\n ticks.forEach((tick) =>\r\n text\r\n .set({\r\n text: format(tick).replace(/G/, 'B'), // https://github.com/d3/d3-format/blob/master/README.md#locale_formatPrefix\r\n y: ChartSettings.top.height + this.height - this.volumeFY(tick),\r\n })\r\n .render(context)\r\n )\r\n }\r\n\r\n renderVolume() {\r\n if (!this.shouldRenderVolume) return\r\n\r\n const { ChartSettings } = this.getChartLayoutSettings()\r\n const { Colors } = ChartSettings.general\r\n // Return if the domain bounds are equal, this would put any value in the middle\r\n const [domainFrom, domainTo] = this.volumeFY.domain()\r\n if (this.setupAxisTimeFrame !== this.data.timeframe || domainFrom === domainTo) {\r\n return\r\n }\r\n const translate = getTranslate({\r\n context: this.context,\r\n xOffset: this.leftOffset + ChartSettings.left.width,\r\n yOffset: ChartSettings.top.height + this.height - 59,\r\n })\r\n translate.do()\r\n const halfBarWidth = getHalfBarWidth(this.model)\r\n const barWidthWithoutMargin = getBarWithoutMarginWidth(this.model)\r\n drawInVisibleArea({\r\n quote: this.data,\r\n paneModel: this.paneModel,\r\n leftOffset: this.leftOffset,\r\n width: this.width,\r\n drawBarCallback: (i, x) => {\r\n // Skip render if the value is <= 0\r\n if (this.data.volume[i] <= 0) {\r\n return\r\n }\r\n\r\n this.context.fillStyle = this.data.close[i] < this.data.open[i] ? Colors.volumeTrendDown : Colors.volumeTrendUp\r\n const y = Math.round(this.volumeFY(this.data.volume[i]))\r\n this.context.fillRect(x - halfBarWidth, 60, barWidthWithoutMargin, -y)\r\n },\r\n })\r\n translate.undo()\r\n }\r\n\r\n renderOverlays() {\r\n const { ChartSettings } = this.getChartLayoutSettings()\r\n const translate = getTranslate({\r\n context: this.context,\r\n xOffset: this.leftOffset + ChartSettings.left.width,\r\n yOffset: ChartSettings.top.height,\r\n })\r\n translate.do()\r\n for (const overlay of this.overlays) {\r\n overlay.renderContent(this.context)\r\n }\r\n translate.undo()\r\n }\r\n\r\n renderCross(context: CanvasRenderingContext2D) {\r\n const isRendered = renderCross({\r\n context,\r\n mouseModel,\r\n paneModel: this.paneModel,\r\n contentWidth: this.width,\r\n contentHeight: this.height,\r\n quote: this.data,\r\n getRoundDecimalPlaces: (price) => this.getPlacesLastClose(price),\r\n onRenderCrossText: !this.getIsRedesignedChart() ? this.renderCrossText : undefined,\r\n })\r\n if (this.getIsRedesignedChart()) {\r\n this.renderCrossText(context, mouseModel.getCrossIndexForPane(this.paneModel))\r\n }\r\n\r\n if (isRendered !== undefined) {\r\n setElementCursor({\r\n elementId: this.model.chart_layout().getHTMLElementId(),\r\n cursor: isRendered ? 'crosshair' : 'default',\r\n conditionalCursor: 'grabbing',\r\n })\r\n }\r\n }\r\n\r\n getDataByCrossIndex(crossIndex: number, key: keyof Quote, shouldReturnRoundedString = true) {\r\n const n = this.data.getDataByBarIndex(key, crossIndex)\r\n if (n !== null) {\r\n return shouldReturnRoundedString ? this.roundOhlc(n) : `${n}`\r\n }\r\n }\r\n\r\n getCrossIndexChange(crossIndex: number) {\r\n const crossDataIndex = this.data.getDataIndexByBarIndex(crossIndex)\r\n const crossClose = this.data.close[crossDataIndex] ?? null\r\n const previousClose = this.data.close[crossDataIndex - 1] ?? null\r\n if (crossClose !== null && previousClose !== null) {\r\n return getTickerChangeFromCloseValues({ data: this.data, anchorClose: crossClose, prevClose: previousClose })\r\n }\r\n\r\n return null\r\n }\r\n\r\n renderCrossText(context: CanvasRenderingContext2D, crossIndex: number) {\r\n const { ChartSettings } = this.getChartLayoutSettings()\r\n context.save()\r\n context.translate(ChartSettings.left.width, 0)\r\n\r\n if (this.getIsRedesignedChart()) {\r\n this.renderOverlaysLabels(context)\r\n if (Number.isNaN(crossIndex)) {\r\n this.getOHLC({ context })\r\n context.restore()\r\n return\r\n }\r\n }\r\n\r\n const dateByBarIndex = this.data.getDataByBarIndex('date', crossIndex)\r\n const date = dateByBarIndex ? utils.dateFromUnixTimestamp(dateByBarIndex) : null\r\n\r\n if (date === null) {\r\n const virtualTradedDates =\r\n this.data.date.length > 0\r\n ? getVirtualTimeframeTradedDates({\r\n dateStart: this.data.date[0],\r\n dateEnd: this.data.date[this.data.date.length - 1],\r\n quote: this.data,\r\n })\r\n : []\r\n this.getOHLC({\r\n context,\r\n dateString: virtualTradedDates[crossIndex]\r\n ? getDateString({\r\n date: utils.dateFromUnixTimestamp(virtualTradedDates[crossIndex]),\r\n timeframe: this.data.timeframe,\r\n })\r\n : null,\r\n })\r\n context.restore()\r\n return\r\n }\r\n\r\n this.getOHLC({\r\n context,\r\n date,\r\n data: {\r\n open: this.getDataByCrossIndex(crossIndex, 'open'),\r\n high: this.getDataByCrossIndex(crossIndex, 'high'),\r\n low: this.getDataByCrossIndex(crossIndex, 'low'),\r\n close: this.getDataByCrossIndex(crossIndex, 'close'),\r\n volume: this.getDataByCrossIndex(crossIndex, 'volume', false),\r\n },\r\n changePercentage: this.getCrossIndexChange(crossIndex),\r\n })\r\n\r\n context.restore()\r\n }\r\n\r\n renderChange({ context }: { context: CanvasRenderingContext2D }) {\r\n const CHANGE_SPACER = 10\r\n const { ChartSettings, isOurSiteRequest } = this.getChartLayoutSettings()\r\n const { ticker, change, ohlc } = ChartSettings.top\r\n const { tickerChange, tickerAfterChange } = getTickerChange({ data: this.data })\r\n\r\n if (!tickerChange) {\r\n return\r\n }\r\n\r\n const isOffscreen = this.specificChartFunctionality === SpecificChartFunctionality.offScreen\r\n const isGroupInstrument = this.data.instrument === Instrument.Group\r\n const finvizWatermarkOffset = !isOffscreen || isOurSiteRequest || this.isLargeChart ? 0 : 15\r\n const changeText = new Text(\r\n {\r\n text: isOffscreen && isGroupInstrument ? tickerChange.percentString : tickerChange.string,\r\n x: !getIsSmallIndexChart(this.specificChartFunctionality)\r\n ? this.width - ChartSettings.top.change.margin.right! - finvizWatermarkOffset\r\n : this.width,\r\n y: ChartSettings.top.change.margin.top,\r\n font: Text.getMergedPropsWithDefaults('font', ChartSettings.top.change.font),\r\n textAlign: TextAlign.right,\r\n textBaseline: ChartSettings.top.baseline,\r\n fillStyle: getChangeColor({ change: tickerChange.points, ChartSettings }),\r\n },\r\n this.paneModel\r\n )\r\n this.changeWidth = changeText.measure(context)\r\n changeText.render(context)\r\n\r\n if (isOffscreen && (!this.isLargeChart || isGroupInstrument)) {\r\n return\r\n }\r\n if (tickerAfterChange) {\r\n const afterChangeText = new Text(\r\n {\r\n text: tickerAfterChange?.string,\r\n font: Text.getMergedPropsWithDefaults('font', ChartSettings.top.change.font),\r\n textAlign: TextAlign.right,\r\n textBaseline: ChartSettings.top.baseline,\r\n fillStyle: getChangeColor({ change: tickerAfterChange.points, ChartSettings }),\r\n },\r\n this.paneModel\r\n )\r\n const afterChangeTextWidth = afterChangeText.measure(context)\r\n const oneLineAHChangeWidth = this.changeWidth + CHANGE_SPACER + afterChangeTextWidth\r\n\r\n if (\r\n ChartSettings.left.width + this.tickerWidth + ticker.margin.left! + OFFSET.S <\r\n ChartSettings.left.width + this.width - oneLineAHChangeWidth - change.margin.right!\r\n ) {\r\n afterChangeText\r\n .set({\r\n x: this.width - ChartSettings.top.change.margin.right! - this.changeWidth - CHANGE_SPACER,\r\n y: ChartSettings.top.change.margin.top,\r\n })\r\n .render(context)\r\n this.afterChange = null\r\n this.changeWidth = oneLineAHChangeWidth\r\n } else if (\r\n this.lastOhlc[0] &&\r\n ChartSettings.left.width +\r\n this.tickerWidth +\r\n ticker.margin.left! +\r\n this.lastOhlc[0].width! +\r\n ohlc.margin.left! +\r\n ohlc.margin.right! <\r\n ChartSettings.left.width + this.width - afterChangeTextWidth - change.margin.right!\r\n ) {\r\n afterChangeText\r\n .set({\r\n x: this.width - ChartSettings.top.change.margin.right!,\r\n y: ChartSettings.top.change.margin.top! - ChartSettings.top.change.font.size! - OFFSET.S,\r\n })\r\n .render(context)\r\n this.changeWidth = Math.max(this.changeWidth, afterChangeTextWidth)\r\n this.afterChange = {\r\n x: this.width - ChartSettings.top.change.margin.right!,\r\n y: ChartSettings.top.change.margin.top! - ChartSettings.top.change.font.size! - OFFSET.S,\r\n width: afterChangeTextWidth,\r\n }\r\n }\r\n }\r\n }\r\n\r\n renderOHLC(parameters: IRenderOHLCParameters) {\r\n if (!this.getIsRedesignedChart()) {\r\n this.renderOHLCQuotePage(parameters)\r\n } else {\r\n this.renderOHLCChartsPage(parameters)\r\n }\r\n }\r\n\r\n renderOHLCChartsPage({ context, date, open, high, low, close, volume, changePercentage }: IRenderOHLCParameters) {\r\n const chartBreakpoints = getChartBreakpoints(this.width)\r\n const { ChartSettings } = this.getChartLayoutSettings()\r\n const { Colors } = ChartSettings.general\r\n\r\n const OhlcText = new Text(\r\n {\r\n font: { size: FONT_SIZE.S },\r\n lineHeight: 18,\r\n fillStyle: Colors.text,\r\n textAlign: TextAlign.left,\r\n textBaseline: TextBaseline.middle,\r\n background: getHEXWithSpecificAplha(Colors.canvasFill, 0.8),\r\n },\r\n this.paneModel\r\n )\r\n\r\n const dateElements = date ? [{ text: date, color: gray300 }] : []\r\n const trendColor = (open ?? 0) > (close ?? 0) ? tailwindColors.red[400] : tailwindColors.green[400]\r\n const oElements = open\r\n ? [\r\n { text: 'O', color: gray300 },\r\n { text: open, color: trendColor },\r\n ]\r\n : []\r\n const hElements = high\r\n ? [\r\n { text: 'H', color: gray300 },\r\n { text: high, color: trendColor },\r\n ]\r\n : []\r\n const lElements = low\r\n ? [\r\n { text: 'L', color: gray300 },\r\n { text: low, color: trendColor },\r\n ]\r\n : []\r\n const cElements = close\r\n ? [\r\n { text: 'C', color: gray300 },\r\n { text: close, color: trendColor },\r\n ]\r\n : []\r\n const volElements = volume\r\n ? [\r\n { text: 'Vol', color: gray300 },\r\n { text: volume, color: trendColor },\r\n ]\r\n : []\r\n const changeElements = changePercentage != null ? [{ text: changePercentage.string, color: trendColor }] : []\r\n\r\n const lines: OhlcLineElements[] = []\r\n\r\n const getFlatLineArrayWithSpaces = (lineElements: OhlcLineElements[]) =>\r\n lineElements.flatMap((elements, index) =>\r\n index > 0 ? ([...(elements.length > 0 ? ['space'] : []), ...elements] as OhlcLineElements) : elements\r\n )\r\n if (chartBreakpoints.isM) {\r\n lines.push(\r\n getFlatLineArrayWithSpaces([\r\n dateElements,\r\n oElements,\r\n hElements,\r\n lElements,\r\n cElements,\r\n volElements,\r\n changeElements,\r\n ])\r\n )\r\n } else if (chartBreakpoints.isS) {\r\n lines.push(getFlatLineArrayWithSpaces([dateElements, changeElements]))\r\n lines.push(getFlatLineArrayWithSpaces([oElements, hElements, lElements, cElements, volElements]))\r\n } else {\r\n lines.push(getFlatLineArrayWithSpaces([dateElements, volElements, changeElements]))\r\n lines.push(getFlatLineArrayWithSpaces([oElements, hElements, lElements, cElements]))\r\n }\r\n\r\n const startX = OFFSET.M - ChartSettings.left.width\r\n let x = startX\r\n let y = OFFSET.M + OhlcText.attrs.lineHeight / 2\r\n\r\n lines.forEach((line) => {\r\n x = startX\r\n line.forEach((lineElement, index, lineElements) => {\r\n const padding = { left: 1, right: 1, top: 0, bottom: 0 }\r\n const { text = '', color = undefined } = lineElement === 'space' ? {} : lineElement\r\n if (index === 0) {\r\n padding.left = 5\r\n } else if (index === lineElements.length - 1) {\r\n padding.right = 5\r\n } else if (lineElement === 'space') {\r\n padding.left = 7\r\n padding.right = 7\r\n if (!chartBreakpoints.isS) {\r\n padding.left = 5\r\n padding.right = 5\r\n }\r\n }\r\n OhlcText.set({ text, fillStyle: color, x, y, padding })\r\n OhlcText.render(context)\r\n x += OhlcText.width\r\n })\r\n y += OhlcText.attrs.lineHeight\r\n })\r\n }\r\n\r\n renderOverlaysLabelsChartsPage(context: CanvasRenderingContext2D) {\r\n const { ChartSettings } = this.getChartLayoutSettings()\r\n const chartBreakpoints = getChartBreakpoints(this.width)\r\n const LabelsText = new Text(\r\n {\r\n font: { size: FONT_SIZE.S },\r\n lineHeight: 18,\r\n textAlign: TextAlign.left,\r\n textBaseline: TextBaseline.middle,\r\n background: getHEXWithSpecificAplha(ChartSettings.general.Colors.canvasFill, 0.8),\r\n // this function gets (indirectly) called from renderCrossText which is already \"translateX\" by ChartSettings.left.width\r\n x: OFFSET.M - ChartSettings.left.width,\r\n padding: { left: PADDING.S, right: PADDING.S, top: 0, bottom: 0 },\r\n },\r\n this.paneModel\r\n )\r\n\r\n let numberOfNewOhlcLines = 2\r\n if (chartBreakpoints.isM) {\r\n numberOfNewOhlcLines = 1\r\n } else if (chartBreakpoints.isS) {\r\n numberOfNewOhlcLines = 2\r\n }\r\n\r\n // We assume lineheight is the same as OHLC text\r\n const { lineHeight } = LabelsText.attrs\r\n let y = lineHeight * numberOfNewOhlcLines + lineHeight / 2 + OFFSET.M\r\n\r\n for (const overlay of this.overlays) {\r\n if (!overlay.isRenderedOverlaysLabel()) {\r\n continue\r\n }\r\n LabelsText.set({\r\n text: overlay.toString(),\r\n y,\r\n fillStyle: overlay.getLabelColor(),\r\n }).render(context)\r\n y += lineHeight\r\n }\r\n }\r\n\r\n renderOHLCQuotePage({\r\n context,\r\n date,\r\n open,\r\n high,\r\n low,\r\n close,\r\n volume,\r\n afterHour,\r\n isSmallIndexChart = false,\r\n isNewestOHLC = false,\r\n time,\r\n directRender = false,\r\n changePercentage,\r\n }: IRenderOHLCParameters) {\r\n const { ChartSettings } = this.getChartLayoutSettings()\r\n const { Colors } = ChartSettings.general\r\n const { ohlc } = ChartSettings.top\r\n const isOffscreen = this.specificChartFunctionality === SpecificChartFunctionality.offScreen\r\n const isGroupInstrument = this.data.instrument === Instrument.Group\r\n if (isOffscreen && isGroupInstrument) {\r\n ohlc.type = OHLCType.dateOnly\r\n } else if (isOffscreen && this.data.instrument !== Instrument.Stock && time) {\r\n ohlc.type = OHLCType.timeOnly\r\n }\r\n\r\n const lineTopY = ohlc.type ? ohlc.margin.top : ohlc.margin.top! - ChartSettings.top.ticker.font.size!\r\n const OHLCFontSize = ohlc.font.size!\r\n const centerXOffset =\r\n this.tickerWidth +\r\n ChartSettings.top.ticker.margin.left! +\r\n (this.width -\r\n (this.tickerWidth +\r\n ChartSettings.top.ticker.margin.left! +\r\n this.changeWidth +\r\n (isSmallIndexChart ? 0 : ChartSettings.top.change.margin.right!))) / // smallIndexChart don't have change.margin.right\r\n 2\r\n const leftXOffset = this.tickerWidth + ChartSettings.top.ticker.margin.left! + ohlc.margin.left!\r\n const hasOhlc = ![open, high, low, close, volume].some((ohlcString) => !ohlcString)\r\n const OHLC = hasOhlc\r\n ? {\r\n date: [date ?? ''],\r\n singleLine: [\r\n `${date} O:${open} H:${high} L:${low} C:${close}${\r\n afterHour ? ` AH:${afterHour}` : ''\r\n } Vol:${volume} `,\r\n /*\r\n * this is needed because of the way we render ohlc text down below in renderOHLCToCanvas\r\n * undefined is used instead of null because TS had some issues with `null` even if it is filtered out\r\n * */\r\n changePercentage ? changePercentage.string : undefined,\r\n ].filter((value) => value !== undefined),\r\n }\r\n : {\r\n date: [date ?? ''],\r\n singleLine: [`${date ?? ''}`],\r\n }\r\n\r\n const OHLC_TEXT = new Text(\r\n {\r\n font: { size: OHLCFontSize },\r\n },\r\n this.paneModel\r\n )\r\n\r\n const getOHLCType = () => {\r\n if (!isSmallIndexChart) {\r\n return OHLCType.singleLine\r\n }\r\n return OHLCType.dateOnly\r\n }\r\n\r\n const getOHLCSettings = () => {\r\n switch (ohlc.type || getOHLCType()) {\r\n case OHLCType.singleLine:\r\n return {\r\n text: OHLC.singleLine,\r\n x: [leftXOffset, leftXOffset],\r\n y: [ohlc.margin.top],\r\n textAlign: TextAlign.left,\r\n textBaseline: [TextBaseline.alphabetic],\r\n }\r\n case OHLCType.dateOnly:\r\n if (isOffscreen && isGroupInstrument) {\r\n const text = `${OHLC.date} Volume: ${volume}`\r\n const textWidth = OHLC_TEXT.set({ text }).measure(context)\r\n return {\r\n text: [text],\r\n x: [\r\n this.width - ChartSettings.top.change.margin.right! - this.changeWidth - textWidth - CHART_MARGIN.XXL,\r\n ],\r\n y: [ohlc.margin.top],\r\n textAlign: TextAlign.center,\r\n textBaseline: [TextBaseline.alphabetic],\r\n }\r\n } else if (isSmallIndexChart) {\r\n return {\r\n text: OHLC.date,\r\n x: [centerXOffset],\r\n y: [ohlc.margin.top],\r\n textAlign: TextAlign.center,\r\n textBaseline: [TextBaseline.alphabetic],\r\n }\r\n } else {\r\n const isEnoughSpace =\r\n this.width -\r\n (this.tickerWidth +\r\n ChartSettings.top.ticker.margin.left! +\r\n ohlc.margin.left! +\r\n ohlc.margin.right! +\r\n this.changeWidth +\r\n ChartSettings.top.change.margin.right!) >\r\n OHLC_TEXT.set({ text: OHLC.date[0] }).measure(context)\r\n const alignTop = !isEnoughSpace || ohlc.font.baseline === TextBaseline.top\r\n return {\r\n text: OHLC.date,\r\n x: [leftXOffset],\r\n y: alignTop ? [lineTopY] : [ohlc.margin.top],\r\n textAlign: TextAlign.left,\r\n textBaseline: alignTop ? [TextBaseline.top] : [TextBaseline.alphabetic],\r\n }\r\n }\r\n case OHLCType.timeOnly:\r\n return {\r\n text: [time],\r\n x: [centerXOffset - OHLC_TEXT.set({ text: time }).measure(context) / 2],\r\n y: [lineTopY],\r\n textAlign: TextAlign.center,\r\n textBaseline: [ohlc.font.baseline],\r\n }\r\n default:\r\n return\r\n }\r\n }\r\n\r\n if (!isNewestOHLC) {\r\n context.fillStyle = Colors.canvasFill\r\n this.lastOhlc.forEach((line) => {\r\n const x = (line.textAlign === TextAlign.left ? line.x : line.x! - line.width! / 2)!\r\n const y = (line.textBaseline === TextBaseline.top ? line.y : line.y! - OHLCFontSize)!\r\n context.fillRect(\r\n x - PADDING.XXS,\r\n y - PADDING.XXS,\r\n PADDING.XXS + line.width! + PADDING.XXS,\r\n PADDING.XXS + OHLCFontSize + PADDING.XXS\r\n )\r\n })\r\n\r\n if (this.afterChange) {\r\n context.fillRect(\r\n this.afterChange.x - this.afterChange.width - PADDING.XXS,\r\n this.afterChange.y - ChartSettings.top.change.font.size! - PADDING.XXS,\r\n PADDING.XXS + this.afterChange.width + PADDING.XXS,\r\n PADDING.XXS + ChartSettings.top.change.font.size! + PADDING.XS\r\n )\r\n }\r\n } else {\r\n this.lastOhlc = []\r\n }\r\n\r\n const ohlcSettings = getOHLCSettings()\r\n\r\n const renderOHLCToCanvas = ({\r\n ohlcSet,\r\n render = true,\r\n }: {\r\n ohlcSet?: {\r\n text: (string | undefined)[]\r\n x: number[]\r\n y: (number | undefined)[]\r\n textAlign: TextAlign\r\n textBaseline: (TextBaseline | undefined)[]\r\n }\r\n render?: boolean\r\n }) => {\r\n const isSingleLineWithChange = (ohlc.type || getOHLCType()) === OHLCType.singleLine && changePercentage\r\n ohlcSet?.text.forEach((line: string | undefined, index: number) => {\r\n let i = index\r\n let leftOffset = 0\r\n let fillStyle = Colors.text\r\n let text = line\r\n if (index > 0 && isSingleLineWithChange) {\r\n i -= 1\r\n leftOffset = OHLC_TEXT.measure(context)\r\n text = line\r\n\r\n fillStyle = getChangeColor({ change: changePercentage.points, ChartSettings })\r\n }\r\n const options = {\r\n text,\r\n x: ohlcSet.x[i] + leftOffset,\r\n y: ohlcSet.y[i],\r\n textBaseline: ohlc.font.baseline ? ohlc.font.baseline : ohlcSet.textBaseline[i],\r\n textAlign: ohlc.font.textAlign ? ohlc.font.textAlign : ohlcSet.textAlign,\r\n fillStyle,\r\n }\r\n OHLC_TEXT.set(options)\r\n if (isNewestOHLC) {\r\n this.lastOhlc[i] = { width: OHLC_TEXT.measure(context), ...options }\r\n }\r\n if (render) {\r\n OHLC_TEXT.render(context)\r\n }\r\n })\r\n }\r\n renderOHLCToCanvas({ ohlcSet: ohlcSettings, render: directRender })\r\n\r\n return {\r\n ohlcSettings,\r\n renderOHLCToCanvas,\r\n }\r\n }\r\n\r\n // only for stocks on i1/i3/i5 and one day view\r\n renderFadeExtendedHours() {\r\n const { ChartSettings } = this.getChartLayoutSettings()\r\n const { Colors } = ChartSettings.general\r\n const period = this.model.quote().timeframe\r\n if (this.data.instrument !== Instrument.Stock) {\r\n return\r\n }\r\n if (![TIMEFRAME.i1, TIMEFRAME.i2, TIMEFRAME.i3, TIMEFRAME.i5].includes(period)) {\r\n return\r\n }\r\n\r\n const interval = parseInt(period.substring(1), 10)\r\n const dayToOffset = this.data.getDayToOffset()\r\n const translate = getTranslate({\r\n context: this.context,\r\n xOffset: this.leftOffset + ChartSettings.left.width,\r\n yOffset: ChartSettings.top.height,\r\n })\r\n translate.do()\r\n const halfBarWidth = getHalfBarWidth(this.model)\r\n for (const day in dayToOffset) {\r\n // todo aftermarket\r\n const dayIndex = dayToOffset[day]\r\n let n0 = (this.data.drawMinutesPerDay / interval) * dayIndex\r\n let n1 = this.data.premarketLengthMinutes / interval + n0 // bars in 90mins from 8am to 9:30am\r\n let x0 = this.paneModel.scale.x(n0) - halfBarWidth\r\n let width = this.paneModel.scale.x(n1) - this.paneModel.scale.x(n0)\r\n this.context.set('fillStyle', Colors.premarketFade)\r\n this.context.fillRect(x0, 0, width, this.height + 1)\r\n\r\n if (this.data.aftermarketLengthMinutes > 0) {\r\n n0 =\r\n (this.data.drawMinutesPerDay / interval) * dayIndex +\r\n (this.data.drawMinutesPerDay - this.data.aftermarketLengthMinutes) / interval\r\n n1 = this.data.aftermarketLengthMinutes / interval + n0 // bars in 90mins from 4pm to 5:30pm\r\n x0 = this.paneModel.scale.x(n0) - halfBarWidth\r\n width = this.paneModel.scale.x(n1) - this.paneModel.scale.x(n0)\r\n\r\n this.context.set('fillStyle', Colors.aftermarketFade)\r\n this.context.fillRect(x0, 0, width, this.height + 1)\r\n }\r\n }\r\n translate.undo()\r\n }\r\n\r\n shouldShowPrevClose() {\r\n const quote = this.model.quote()\r\n const isStock = quote.instrument === Instrument.Stock\r\n const isIntradayWithPreMarket = TIMEFRAMES_WITH_PRE_MARKET.includes(quote.timeframe)\r\n const isIndexChart = this.specificChartFunctionality === SpecificChartFunctionality.smallIndex\r\n\r\n return isStock && (isIntradayWithPreMarket || isIndexChart)\r\n }\r\n\r\n renderPrevClose() {\r\n const { ChartSettings } = this.getChartLayoutSettings()\r\n const { Colors } = ChartSettings.general\r\n if (!this.shouldShowPrevClose()) {\r\n return\r\n }\r\n const translate = getTranslate({\r\n context: this.context,\r\n xOffset: ChartSettings.left.width,\r\n yOffset: ChartSettings.top.height,\r\n })\r\n translate.do()\r\n\r\n let y = Math.round(this.fy(this.model.quote().prevClose))\r\n if (y === this.height) y -= 1 // due pixel perfect rendering of lines, line on bottom edge is moved outside of \"chart area\" because of 0.5px translate, to compensate for this we subtract 1px\r\n\r\n new Line(\r\n {\r\n x1: 0,\r\n x2: this.width,\r\n y1: y,\r\n y2: y,\r\n strokeStyle: Colors.prevClose,\r\n dashLength: 3,\r\n },\r\n this.paneModel\r\n ).render(this.context)\r\n translate.undo()\r\n }\r\n\r\n renderChartNotAvailable() {\r\n const { ChartSettings } = this.getChartLayoutSettings()\r\n const { Colors } = ChartSettings.general\r\n const x = ~~((ChartSettings.left.width + ChartSettings.right.width + this.width) / 2)\r\n const y = ~~((ChartSettings.top.height + ChartSettings.bottom.height + this.height) / 2)\r\n new Text(\r\n {\r\n text: 'Chart not available',\r\n x,\r\n y,\r\n font: { size: FONT_SIZE.M, style: 'bold' },\r\n fillStyle: Colors.text,\r\n textAlign: TextAlign.center,\r\n textBaseline: TextBaseline.middle,\r\n },\r\n this.paneModel\r\n ).render(this.context)\r\n }\r\n\r\n // private\r\n setupCache() {\r\n const { ChartSettings } = this.getChartLayoutSettings()\r\n /*\r\n * Don't create new Cache instances, because Safari takes too long to free up memory\r\n * leading to canvas.getContext returning null. https://stackoverflow.com/questions/52532614/total-canvas-memory-use-exceeds-the-maximum-limit-safari-12\r\n *\r\n * To further improve performance, cache.set shouldn't be called when unnecessary,\r\n * because setupCache is called for many model updates. The same applies for indicators/indicator.js.\r\n */\r\n this.baseCache = this.baseCache || new Cache()\r\n\r\n this.baseCache.set(\r\n (context: CanvasRenderingContext2D) => {\r\n if (this.data.close.length === 0) {\r\n this.renderText(context)\r\n return\r\n }\r\n this.renderYAxis(context)\r\n this.renderText(context)\r\n if (!this.getIsMobileChartPage() && this.shouldRenderVolume) {\r\n this.renderVolumeAxis(context)\r\n }\r\n if (!this.getIsRedesignedChart()) {\r\n this.renderOverlaysLabels(context)\r\n }\r\n },\r\n this.width + ChartSettings.left.width + ChartSettings.right.width,\r\n this.height + ChartSettings.top.height + ChartSettings.bottom.height\r\n )\r\n }\r\n\r\n // called by controllers/pane on recountScale\r\n setupAxis(fx: ScaleAxis) {\r\n this.data = this.model.quote()\r\n const { volumeHeight } = this.getChartLayoutSettings().ChartSettings.center\r\n\r\n if (typeof fx !== 'function') {\r\n return\r\n }\r\n\r\n const firstBarToRenderIndex = getVisibleBarToRenderIndex({\r\n leftOffset: this.model.leftOffset,\r\n paneModel: this.paneModel,\r\n quote: this.data,\r\n })\r\n\r\n const lastBarToRenderIndex = getVisibleBarToRenderIndex({\r\n leftOffset: this.model.leftOffset,\r\n paneModel: this.paneModel,\r\n quote: this.data,\r\n chartWidth: this.width,\r\n })\r\n\r\n const areNoBarsVisible = getAreNoBarsVisible(firstBarToRenderIndex, lastBarToRenderIndex)\r\n\r\n const volumes = []\r\n if (areNoBarsVisible) {\r\n volumes.push(\r\n this.data.volume[firstBarToRenderIndex.index],\r\n Math.min(lastBarToRenderIndex.index, this.data.barIndex.length - 1)\r\n )\r\n } else {\r\n for (let i = firstBarToRenderIndex.index; i <= lastBarToRenderIndex.index; i++) {\r\n volumes.push(this.data.volume[i])\r\n }\r\n }\r\n\r\n const max = utils.max(volumes) ?? 0\r\n const rangeMax = volumeHeight || 60\r\n this.volumeFY = d3.scaleLinear().range([0, rangeMax]).domain([0, max]).nice(4)\r\n this.setupAxisTimeFrame = this.data.timeframe\r\n }\r\n\r\n // private\r\n clip(addMarginBottom?: boolean) {\r\n const { ChartSettings } = this.getChartLayoutSettings()\r\n if (addMarginBottom == null) {\r\n addMarginBottom = false\r\n }\r\n this.context.beginPath()\r\n let marginBottom = 0\r\n if (addMarginBottom) {\r\n marginBottom = ChartSettings.bottom.height\r\n }\r\n // due pixel perfect rendering of lines, line on bottom edge is moved outside of \"chart area\" because of 0.5px translate,\r\n // to compensate for this we clip canvas 1px taller than chart height\r\n this.context.rect(ChartSettings.left.width, ChartSettings.top.height, this.width, this.height + marginBottom + 1)\r\n this.context.clip()\r\n }\r\n\r\n addOverlay(overlay: Overlay) {\r\n overlay.chart = this\r\n this.overlays.push(overlay)\r\n return this.trigger('change')\r\n }\r\n\r\n setOverlays(overlays: Overlay[]) {\r\n this.overlays = overlays\r\n return this.trigger('change')\r\n }\r\n\r\n removeOverlay(overlay: Overlay) {\r\n for (let index = 0; index < this.overlays.length; index++) {\r\n const el = this.overlays[index]\r\n if (el === overlay) {\r\n this.attrs.overlays.splice(index, 1)\r\n this.overlays.splice(index, 1)\r\n this.trigger('change')\r\n break\r\n }\r\n }\r\n }\r\n\r\n getMinMax(): { min: number; max: number; firstVisibleClose?: number | null } {\r\n this.data = this.model.quote()\r\n let min = Number.MAX_VALUE\r\n let max = Number.MIN_VALUE\r\n let minIndex = -1\r\n let maxIndex = -1\r\n let firstVisibleClose = null\r\n\r\n const firstBarToRenderIndex = getVisibleBarToRenderIndex({\r\n leftOffset: this.model.leftOffset,\r\n paneModel: this.paneModel,\r\n quote: this.data,\r\n })\r\n const lastBarToRenderIndex = getVisibleBarToRenderIndex({\r\n leftOffset: this.model.leftOffset,\r\n paneModel: this.paneModel,\r\n quote: this.data,\r\n chartWidth: this.width,\r\n })\r\n\r\n const areNoBarsVisible = getAreNoBarsVisible(firstBarToRenderIndex, lastBarToRenderIndex)\r\n\r\n // If no bars are visible min/max are first available bar before visible and first after\r\n if (areNoBarsVisible) {\r\n min = this.data.low[firstBarToRenderIndex.index]\r\n max = this.data.high[Math.min(lastBarToRenderIndex.index, this.data.barIndex.length - 1)]\r\n if (min > max) {\r\n const prevMin = min\r\n min = max\r\n max = prevMin\r\n }\r\n firstVisibleClose = this.data.close[firstBarToRenderIndex.index]\r\n } else {\r\n for (let i = firstBarToRenderIndex.index; i <= lastBarToRenderIndex.index; i++) {\r\n if (minIndex === -1 || this.data.low[minIndex] > this.data.low[i]) {\r\n minIndex = i\r\n }\r\n if (maxIndex === -1 || this.data.high[maxIndex] < this.data.high[i]) {\r\n maxIndex = i\r\n }\r\n }\r\n\r\n // If only a single bar is visible get min/max index range from closes values outside of visible area\r\n if (this.data.low[minIndex] === this.data.high[maxIndex]) {\r\n const closestMinMaxIndices = getClosestDifferentMinMaxValueIndices(\r\n minIndex,\r\n maxIndex,\r\n this.data.high,\r\n this.data.low\r\n )\r\n minIndex = closestMinMaxIndices.minIndex\r\n maxIndex = closestMinMaxIndices.maxIndex\r\n }\r\n\r\n min = this.data.low[minIndex]\r\n max = this.data.high[maxIndex]\r\n\r\n firstVisibleClose = this.data.close[firstBarToRenderIndex.index]\r\n }\r\n\r\n // Apply scale min & max buffer if min/max is the same\r\n if (min === max) {\r\n min *= 0.99\r\n max *= 1.01\r\n }\r\n\r\n // Update min/max so prevClose is in range and can be rendered if it should\r\n if (this.shouldShowPrevClose() && this.data.prevClose !== null) {\r\n min = Math.min(min, this.data.prevClose)\r\n max = Math.max(max, this.data.prevClose)\r\n }\r\n\r\n // Update min/max so lastClose is in range and can be rendered if it should\r\n if (this.specificChartFunctionality === SpecificChartFunctionality.offScreen && !this.model.dateRange) {\r\n min = Math.min(min, this.data.lastClose)\r\n max = Math.max(max, this.data.lastClose)\r\n }\r\n\r\n return { min, max, firstVisibleClose }\r\n }\r\n\r\n moveBy() {}\r\n\r\n isInArea() {\r\n return false\r\n }\r\n\r\n fx = (x: number) => this.paneModel.scale.x(this.data.barIndex[x])\r\n\r\n fy = (y: number) => this.paneModel.scale.y(y)\r\n\r\n round(n: number, overridePlaces?: number) {\r\n return round({ data: this.data, num: n, overridePlaces: overridePlaces ?? this.getPlacesLastClose() })\r\n }\r\n\r\n roundOhlc(n: number) {\r\n const placesLastClose = this.getPlacesLastClose()\r\n return round({\r\n data: this.data,\r\n num: n,\r\n overridePlaces: placesLastClose ? Math.max(placesLastClose, 2) : undefined,\r\n })\r\n }\r\n\r\n toObject() {\r\n const overlays = this.overlays.map((overlay) => overlay.toObject())\r\n return merge({}, this.attrs, { type: this.type, overlays })\r\n }\r\n\r\n toConfig() {\r\n const overlays = this.overlays.map((overlay) => overlay.toConfig())\r\n return merge({}, this.attrs, { type: this.type, overlays })\r\n }\r\n\r\n getPlacesLastClose(price?: number) {\r\n const { lastClose, instrument } = this.data\r\n const priceAbs = price && Math.abs(price)\r\n if (lastClose >= 100000) {\r\n return 0\r\n } else if (lastClose >= 10000) {\r\n return 1\r\n } else if (instrument === Instrument.Stock && (priceAbs ?? lastClose) < 1) {\r\n return 4\r\n } else if (lastClose === undefined) {\r\n // if lastClose is not defined we'll always display 2 decimpal places, e.g. backtests, screener stats\r\n return 2\r\n }\r\n\r\n return undefined\r\n }\r\n\r\n hasOverlay(type: string) {\r\n return this.overlays.some((x) => x.type === 'overlays/' + type)\r\n }\r\n\r\n getXLine(): Line {\r\n return new Line(\r\n {\r\n y1: 0,\r\n y2: this.height,\r\n strokeStyle: this.getChartLayoutSettings().ChartSettings.general.Colors.grid,\r\n dashLength: 3,\r\n },\r\n this.paneModel\r\n )\r\n }\r\n\r\n getYLine(): Line {\r\n return new Line(\r\n {\r\n x1: 0,\r\n x2: this.width,\r\n strokeStyle: this.getChartLayoutSettings().ChartSettings.general.Colors.grid,\r\n dashLength: 3,\r\n },\r\n this.paneModel\r\n )\r\n }\r\n\r\n getChartLayoutSettings() {\r\n return getChartLayoutSettings(this.model.chart_layout())\r\n }\r\n\r\n getIsMobileChartPage() {\r\n return (\r\n this.isMobile && this.model.chart_layout().specificChartFunctionality === SpecificChartFunctionality.chartPage\r\n )\r\n }\r\n\r\n getCandleLikeChartsRenderingColors() {\r\n const { ChartSettings } = this.getChartLayoutSettings()\r\n const { Colors } = ChartSettings.general\r\n const { theme, specificChartFunctionality } = this.model.chart_layout()\r\n let colors = Colors\r\n const overwrittenColors = getColorOverwrites({\r\n colors,\r\n theme,\r\n })\r\n const overwrittenColorKeys = Object.keys(overwrittenColors)\r\n const hasOverwrittenCandleColor = ['borderUp', 'wickUp', 'borderDown', 'wickDown', 'trendUp', 'trendDown'].some(\r\n (colorKey) => overwrittenColorKeys.includes(colorKey)\r\n )\r\n\r\n const shouldUseDarkerColors =\r\n theme === Theme.light &&\r\n getShouldUseDarkerWickColors({\r\n specificChartFunctionality: specificChartFunctionality,\r\n totalBarWidth: ChartSettings.center.barWidth + ChartSettings.center.border * 2,\r\n })\r\n\r\n if (shouldUseDarkerColors && !hasOverwrittenCandleColor) {\r\n colors = { ...colors, ...darkerWickColors }\r\n }\r\n const isNodeChartWithThinBars =\r\n specificChartFunctionality === SpecificChartFunctionality.offScreen && ChartSettings.center.border === 0\r\n if (isNodeChartWithThinBars && !hasOverwrittenCandleColor) {\r\n colors = { ...colors, ...thinBarColorsOverride, ...overwrittenColors }\r\n }\r\n\r\n return colors\r\n }\r\n\r\n getIsRedesignedChart() {\r\n return this.specificChartFunctionality === SpecificChartFunctionality.chartPage || isRedesignedPage(this)\r\n }\r\n}\r\n\r\nBaseChart.initClass()\r\n\r\nexport default BaseChart\r\n","import { RendererChartBarProps } from '../../types/shared'\r\nimport { ChartElementType } from '../constants/common'\r\nimport { getTranslate } from '../controllers/renderUtils'\r\nimport utils from '../utils'\r\nimport { getBarWidthWithMarginByParts } from '../utils/chart'\r\nimport { drawInVisibleArea } from '../utils/draw_in_visible_area'\r\nimport { getIsSSr } from '../utils/helpers'\r\nimport Chart from './base_chart'\r\n\r\nconst WICK_WIDTH = 1\r\n\r\nclass CandleStick extends Chart {\r\n static type = ChartElementType.CandleStick\r\n static label = 'Candle'\r\n static iconName = 'candleBarBasic'\r\n\r\n getRenderChartBarProps({ index, chartSettingsColors, hasFillAndBorder }: RendererChartBarProps) {\r\n const { trendDown, trendUp, borderDown, borderUp, wickDown, wickUp } = chartSettingsColors\r\n const open = this.data.open[index]\r\n const close = this.data.close[index]\r\n const trendColor = close < open ? trendDown : trendUp\r\n const wickColor = close < open ? wickDown : wickUp\r\n return {\r\n open,\r\n close,\r\n high: this.data.high[index],\r\n low: this.data.low[index],\r\n barFillColor: trendColor,\r\n borderColor: close < open ? borderDown : borderUp,\r\n wickColor: hasFillAndBorder ? wickColor : trendColor,\r\n }\r\n }\r\n\r\n renderChart() {\r\n if (this.setupAxisTimeFrame !== this.data.timeframe) {\r\n return\r\n }\r\n const { ChartSettings } = this.getChartLayoutSettings()\r\n const Colors = this.getCandleLikeChartsRenderingColors()\r\n const { barFillWidth, barBorderWidth } = getBarWidthWithMarginByParts({\r\n chartLayout: this.model.chart_layout(),\r\n zoomFactor: this.model.zoomFactor,\r\n })\r\n const shouldRenderFillAndBorder =\r\n barFillWidth + barBorderWidth * 2 >= 2 &&\r\n !(this.type === ChartElementType.HollowCandleStick && barBorderWidth === 0)\r\n const translate = getTranslate({\r\n context: this.context,\r\n xOffset: this.leftOffset + ChartSettings.left.width,\r\n yOffset: ChartSettings.top.height,\r\n })\r\n const translateForWick = getTranslate({\r\n context: this.context,\r\n xOffset: WICK_WIDTH / 2,\r\n yOffset: 0,\r\n })\r\n\r\n translate.do()\r\n drawInVisibleArea({\r\n quote: this.data,\r\n paneModel: this.paneModel,\r\n leftOffset: this.leftOffset,\r\n width: this.width,\r\n drawBarCallback: (i: number, center: number) => {\r\n const { open, close, high, low, wickColor, borderColor, barFillColor } = this.getRenderChartBarProps({\r\n index: i,\r\n chartSettingsColors: Colors,\r\n hasFillAndBorder: shouldRenderFillAndBorder,\r\n })\r\n\r\n const candleBodyHigh = Math.round(this.fy(utils.max(open, close)))\r\n const candleBodyLow = Math.round(this.fy(utils.min(open, close)))\r\n const candleWickHigh = Math.round(this.fy(high))\r\n const candleWickLow = Math.round(this.fy(low))\r\n\r\n const candleBodyHeight = candleBodyLow - candleBodyHigh\r\n const candleBodyLeftX = center - Math.floor(barBorderWidth + barFillWidth / 2)\r\n const halfBorderWidth = barBorderWidth / 2\r\n\r\n // TODO: revisit for better approach, this solve issue with candlesticks\r\n // with even width are shifted 1px to the left and thus first candle is vertically sliced\r\n if (getIsSSr() && candleBodyLeftX + this.leftOffset < 0) {\r\n return\r\n }\r\n\r\n const isBodyHeightGreaterOrEqualBorders = candleBodyHeight >= barBorderWidth * 2\r\n const isWickLineCandleLessThanOnePixel = !shouldRenderFillAndBorder && candleWickLow - candleWickHigh < 1\r\n\r\n translateForWick.do()\r\n this.context.set('strokeStyle', wickColor)\r\n this.context.beginPath()\r\n this.context.moveTo(center, candleWickHigh)\r\n if (shouldRenderFillAndBorder) {\r\n this.context.lineTo(center, candleBodyHigh)\r\n this.context.moveTo(\r\n center,\r\n candleBodyHigh + (isBodyHeightGreaterOrEqualBorders ? candleBodyHeight : WICK_WIDTH)\r\n )\r\n }\r\n this.context.lineTo(center, isWickLineCandleLessThanOnePixel ? candleWickHigh + 1 : candleWickLow)\r\n this.context.stroke()\r\n translateForWick.undo()\r\n\r\n if (shouldRenderFillAndBorder) {\r\n const hasBorder = barBorderWidth > 0\r\n if (hasBorder) {\r\n this.context.set('strokeStyle', borderColor)\r\n if (isBodyHeightGreaterOrEqualBorders) {\r\n this.context.set('lineWidth', barBorderWidth)\r\n this.context.strokeRect(\r\n candleBodyLeftX + halfBorderWidth,\r\n candleBodyHigh + halfBorderWidth,\r\n barFillWidth + 2 * halfBorderWidth,\r\n candleBodyHeight - 2 * halfBorderWidth\r\n )\r\n this.context.set('lineWidth', WICK_WIDTH)\r\n } else {\r\n this.context.beginPath()\r\n this.context.moveTo(candleBodyLeftX, candleBodyHigh + WICK_WIDTH / 2)\r\n this.context.lineTo(candleBodyLeftX + barFillWidth + 2 * barBorderWidth, candleBodyHigh + WICK_WIDTH / 2)\r\n this.context.stroke()\r\n }\r\n }\r\n\r\n const fillHeight = candleBodyHeight - 2 * barBorderWidth\r\n const hasFill = fillHeight > 0\r\n if (hasFill || !hasBorder) {\r\n this.context.set('fillStyle', hasFill ? barFillColor : borderColor)\r\n this.context.fillRect(\r\n candleBodyLeftX + barBorderWidth,\r\n candleBodyHigh + barBorderWidth,\r\n barFillWidth,\r\n hasFill ? fillHeight : WICK_WIDTH\r\n )\r\n }\r\n }\r\n },\r\n })\r\n translate.undo()\r\n }\r\n\r\n toString() {\r\n return `Candle stick ${this.data.ticker}`\r\n }\r\n}\r\n\r\nexport default CandleStick\r\n","import { ChartConfigChartPaneElement, RendererChartBarProps, RequireByKey } from '../../types/shared'\r\nimport { ChartElementType } from '../constants/common'\r\nimport CandleStick from './candle_stick'\r\n\r\nclass HollowCandleStick extends CandleStick {\r\n static type = ChartElementType.HollowCandleStick\r\n static label = 'Hollow Candle'\r\n static iconName = 'candleBarHollow'\r\n\r\n static getNumOfBarsBuffer(element: RequireByKey) {\r\n return Math.max(1, super.getNumOfBarsBuffer(element))\r\n }\r\n\r\n getRenderChartBarProps({ index, chartSettingsColors }: RendererChartBarProps) {\r\n const open = this.data.open[index]\r\n const close = this.data.close[index]\r\n const isHollow = close > open\r\n const generalTrendColor =\r\n close > this.data.close[index - 1] ? chartSettingsColors.ohlcTrendUp : chartSettingsColors.ohlcTrendDown\r\n const trendColor = index === 0 ? chartSettingsColors.zeroChange : generalTrendColor\r\n return {\r\n open,\r\n close,\r\n high: this.data.high[index],\r\n low: this.data.low[index],\r\n // hollow candles have transparend bodies that's why rgba is here\r\n barFillColor: isHollow ? 'rgba(0, 0, 0, 0)' : trendColor,\r\n borderColor: trendColor,\r\n wickColor: trendColor,\r\n }\r\n }\r\n\r\n toString() {\r\n return `Hollow Candle stick ${this.data.ticker}`\r\n }\r\n}\r\n\r\nexport default HollowCandleStick\r\n","import { ChartConfigChartPaneElement, RendererChartBarProps, RequireByKey } from '../../types/shared'\r\nimport { ChartElementType, ScaleType } from '../constants/common'\r\nimport Quote from '../models/quote'\r\nimport { getTickerChangeFromCloseValues } from '../utils/chart'\r\nimport CandleStick from './candle_stick'\r\n\r\ntype OhlcKeys = 'high' | 'low' | 'open' | 'close'\r\n\r\nclass HeikinAshi extends CandleStick {\r\n static type = ChartElementType.HeikinAshi\r\n static label = 'Heikin Ashi'\r\n static iconName = 'candleBarHeikinAshi'\r\n\r\n static getNumOfBarsBuffer(element: RequireByKey) {\r\n return Math.max(1, super.getNumOfBarsBuffer(element))\r\n }\r\n\r\n getRenderChartBarProps = ({ index, chartSettingsColors, hasFillAndBorder }: RendererChartBarProps) => {\r\n const haData = this.data.getHeikinAshiData()\r\n\r\n const open = haData.open[index]\r\n const close = haData.close[index]\r\n const trendColor = close < open ? chartSettingsColors.trendDown : chartSettingsColors.trendUp\r\n const wickColor = close < open ? chartSettingsColors.wickDown : chartSettingsColors.wickUp\r\n return {\r\n open,\r\n close,\r\n high: Math.max(this.data.high[index], open, close),\r\n low: Math.min(open, close, this.data.low[index]),\r\n barFillColor: trendColor,\r\n borderColor: close < open ? chartSettingsColors.borderDown : chartSettingsColors.borderUp,\r\n wickColor: hasFillAndBorder ? wickColor : trendColor,\r\n }\r\n }\r\n\r\n getLastValues = () => {\r\n const Colors = this.getCandleLikeChartsRenderingColors()\r\n const {\r\n open: lastOpen,\r\n close: lastClose,\r\n high: lastHigh,\r\n low: lastLow,\r\n } = this.getRenderChartBarProps({\r\n index: this.data.date.length - 1,\r\n chartSettingsColors: Colors,\r\n })\r\n\r\n return { lastOpen, lastClose, lastHigh, lastLow }\r\n }\r\n\r\n getRoundedLastData() {\r\n const lastOhlc = this.getLastValues()\r\n return {\r\n open: this.roundOhlc(lastOhlc.lastOpen),\r\n high: this.roundOhlc(lastOhlc.lastHigh),\r\n low: this.roundOhlc(lastOhlc.lastLow),\r\n close: this.roundOhlc(lastOhlc.lastClose),\r\n }\r\n }\r\n\r\n renderYAxis = (context: CanvasRenderingContext2D) => {\r\n const { lastClose } = this.getLastValues()\r\n super.renderYAxis(context, { lastClose }, false)\r\n\r\n const { firstVisibleClose } = this.getMinMax()\r\n if (this.model.scale === ScaleType.Percentage && !firstVisibleClose) return\r\n\r\n const originalLatestClose = this.data.close[this.data.close.length - 1]\r\n const heikinLatestCloseLabel = this.getYAxisLastCloseLabel({ lastClose, firstVisibleClose })\r\n const originalLatestCloseLabel = this.getYAxisLastCloseLabel({ lastClose: originalLatestClose, firstVisibleClose })\r\n\r\n this.renderYAxisLabel({ context, yCoordinate: Math.round(this.fy(lastClose)), label: heikinLatestCloseLabel })\r\n\r\n if (heikinLatestCloseLabel === originalLatestCloseLabel) return\r\n\r\n this.renderYAxisLabel({\r\n context,\r\n yCoordinate: this.getYAxisSecondaryLabelYCoordinate({\r\n mainLabelValue: lastClose,\r\n secondaryLabelValue: originalLatestClose,\r\n }),\r\n label: originalLatestCloseLabel,\r\n background: this.getSecondaryLabelBackgroundColor(),\r\n })\r\n }\r\n\r\n getDataByCrossIndex(crossIndex: number, key: keyof Quote, shouldReturnRoundedString = true) {\r\n const Colors = this.getCandleLikeChartsRenderingColors()\r\n const barIndex = this.data.getDataIndexByBarIndex(crossIndex)\r\n if (barIndex > -1) {\r\n let value = null\r\n if (['high', 'low', 'open', 'close'].includes(key)) {\r\n const data = this.getRenderChartBarProps({ index: barIndex, chartSettingsColors: Colors })\r\n value = data[key as OhlcKeys]\r\n }\r\n value = value === null ? this.data.getDataByBarIndex(key, crossIndex) : value\r\n if (value !== null) {\r\n return shouldReturnRoundedString ? this.roundOhlc(value) : `${value}`\r\n }\r\n }\r\n }\r\n\r\n getCrossIndexChange(crossIndex: number) {\r\n const barIndex = this.data.getDataIndexByBarIndex(crossIndex)\r\n const haData = this.data.getHeikinAshiData()\r\n const crossClose = haData.close[barIndex] ?? null\r\n const previousClose = haData.close[barIndex - 1] ?? null\r\n if (crossClose !== null && previousClose !== null) {\r\n return getTickerChangeFromCloseValues({ data: this.data, anchorClose: crossClose, prevClose: previousClose })\r\n }\r\n\r\n return null\r\n }\r\n\r\n toString() {\r\n return `HA Candle stick ${this.data.ticker}`\r\n }\r\n}\r\n\r\nexport default HeikinAshi\r\n","import { ChartElementType } from '../constants/common'\r\nimport { getTranslate } from '../controllers/renderUtils'\r\nimport { drawInVisibleArea } from '../utils/draw_in_visible_area'\r\nimport Chart from './base_chart'\r\n\r\nclass LineChart extends Chart {\r\n static type = ChartElementType.LineChart\r\n static label = 'Line'\r\n static iconName = 'lineChartType'\r\n\r\n renderChart() {\r\n const { ChartSettings } = this.getChartLayoutSettings()\r\n const { Colors } = ChartSettings.general\r\n let first: number | undefined, last: number | undefined\r\n const translate = getTranslate({\r\n context: this.context,\r\n xOffset: this.leftOffset + ChartSettings.left.width + 0.5,\r\n yOffset: ChartSettings.top.height + 0.5,\r\n })\r\n translate.do()\r\n this.context.beginPath()\r\n this.context.set('lineWidth', 1)\r\n this.context.set('strokeStyle', Colors.line)\r\n drawInVisibleArea({\r\n quote: this.data,\r\n paneModel: this.paneModel,\r\n leftOffset: this.leftOffset,\r\n width: this.width,\r\n drawBarCallback: (i: number, x: number) => {\r\n const y = Math.round(this.fy(this.data.close[i]))\r\n this.context.lineTo(x, y)\r\n last = x\r\n if (first === undefined) {\r\n first = x\r\n }\r\n },\r\n })\r\n if (first !== undefined && last !== undefined) {\r\n this.context.stroke()\r\n this.context.set('fillStyle', Colors.background)\r\n this.context.lineTo(last!, this.height)\r\n this.context.lineTo(first!, this.height)\r\n this.context.fill()\r\n }\r\n\r\n translate.undo()\r\n }\r\n\r\n toString() {\r\n return `Line chart ${this.data.ticker}`\r\n }\r\n}\r\n\r\nexport default LineChart\r\n","import Text from '../canvas/text'\r\nimport { ChartElementType, TextAlign, TextBaseline } from '../constants/common'\r\nimport { getTranslate } from '../controllers/renderUtils'\r\nimport Pane from '../models/pane'\r\nimport { isRedesignEnabled } from '../utils'\r\nimport Chart, { BaseChartAttrs } from './base_chart'\r\n\r\nconst interval = 3\r\nconst domainMin = -1\r\nconst domainMax = 1\r\nconst red = 'rgba(200, 0, 0, 0.392)'\r\nconst redLine = 'rgb(120, 0, 0)'\r\nconst green = 'rgba(0, 180, 0, 0.392)'\r\nconst greenLine = 'rgb(0, 100, 0)'\r\n\r\nclass MarketSentiment extends Chart {\r\n static type = ChartElementType.MarketSentiment\r\n\r\n static initClass() {\r\n Object.defineProperty(this.prototype, 'width', {\r\n get() {\r\n const { MarketSentimentSettings } = this.getChartLayoutSettings()\r\n return this.model.width - MarketSentimentSettings.left.width - MarketSentimentSettings.right.width\r\n },\r\n })\r\n\r\n Object.defineProperty(this.prototype, 'height', {\r\n get() {\r\n const { MarketSentimentSettings } = this.getChartLayoutSettings()\r\n return this.paneModel.height - MarketSentimentSettings.top.height - MarketSentimentSettings.bottom.height\r\n },\r\n })\r\n }\r\n\r\n declare _data: number[]\r\n declare _dataLastIndex: number | null\r\n\r\n constructor(values: Partial, model: Pane) {\r\n super(values, model)\r\n this.renderText = this.renderText.bind(this)\r\n this.renderOverlaysLabels = this.renderOverlaysLabels.bind(this)\r\n this.renderYAxis = this.renderYAxis.bind(this)\r\n this.setupCache = this.setupCache.bind(this)\r\n }\r\n\r\n setupCache() {\r\n super.setupCache()\r\n if (!this.data) {\r\n return\r\n }\r\n const arr: number[] = []\r\n this.data.close.forEach((sum, i) => {\r\n arr[i] = sum / this.data.volume[i]\r\n })\r\n this._data = arr\r\n\r\n let lastIndex = null\r\n for (let i = this.data.volume.length - 1; i >= 0; i--) {\r\n if (this.data.volume[i] !== 0) {\r\n lastIndex = i\r\n break\r\n }\r\n }\r\n this._dataLastIndex =\r\n lastIndex === null\r\n ? null\r\n : Math.min(lastIndex, Math.round((this.data.drawMinutesPerDay - this.data.marketStartMinutes) / interval))\r\n }\r\n\r\n renderChart() {\r\n const { MarketSentimentSettings } = this.getChartLayoutSettings()\r\n const translate = getTranslate({\r\n context: this.context,\r\n xOffset: this.leftOffset + MarketSentimentSettings.left.width + 0.5,\r\n yOffset: MarketSentimentSettings.top.height + 0.5,\r\n })\r\n translate.do()\r\n this.renderLineBullBear(this.context, this._data, 0, 0, 0)\r\n translate.undo()\r\n }\r\n\r\n renderLineBullBear(\r\n context: CanvasRenderingContext2D,\r\n array: number[],\r\n from: number,\r\n oversold: number,\r\n overbought: number\r\n ) {\r\n if (this._dataLastIndex === null) {\r\n return\r\n }\r\n const isRedesign = isRedesignEnabled()\r\n const { ChartSettings } = this.getChartLayoutSettings()\r\n const { Colors } = ChartSettings.general\r\n\r\n const domain = [domainMax, domainMin]\r\n\r\n context.save()\r\n context.beginPath()\r\n context.rect(\r\n -this.leftOffset,\r\n this.fy(domain[1]),\r\n this.fx(this._dataLastIndex),\r\n Math.round(this.fy(oversold) - this.fy(domain[1])) - 0.5\r\n )\r\n context.clip()\r\n context.set('fillStyle', red)\r\n context.set('strokeStyle', isRedesign ? Colors.marketDown : redLine)\r\n context.beginPath()\r\n context.moveTo(this.fx(0), Math.round(this.fy(domain[0])))\r\n for (let i = from; i < this.data.close.length; i++) {\r\n context.lineTo(this.fx(i), Math.round(this.fy(array[i])))\r\n }\r\n context.lineTo(this.fx(this.data.close.length - 1), Math.round(this.fy(domain[0])))\r\n context.fill()\r\n context.stroke()\r\n context.restore()\r\n\r\n context.save()\r\n context.beginPath()\r\n context.rect(\r\n -this.leftOffset,\r\n this.fy(domain[0]),\r\n this.fx(this._dataLastIndex),\r\n Math.round(this.fy(overbought)) - 0.5\r\n )\r\n context.clip()\r\n context.set('fillStyle', green)\r\n context.set('strokeStyle', isRedesign ? Colors.marketUp : greenLine)\r\n context.beginPath()\r\n context.moveTo(this.fx(0), Math.round(this.fy(domain[1])))\r\n for (let i = from; i < this.data.close.length; i++) {\r\n context.lineTo(this.fx(i), Math.round(this.fy(array[i])))\r\n }\r\n context.lineTo(this.fx(this.data.close.length - 1), Math.round(this.fy(domain[1])))\r\n context.fill()\r\n context.stroke()\r\n context.restore()\r\n }\r\n\r\n renderXAxis() {\r\n const { MarketSentimentSettings } = this.getChartLayoutSettings()\r\n const { Colors } = MarketSentimentSettings.general\r\n const translate = getTranslate({\r\n context: this.context,\r\n xOffset: this.leftOffset + MarketSentimentSettings.left.width,\r\n yOffset: MarketSentimentSettings.top.height,\r\n })\r\n translate.do()\r\n\r\n const xLine = this.getXLine()\r\n const text = new Text(\r\n {\r\n y: this.height + 12,\r\n font: { size: 7 },\r\n fillStyle: Colors.text,\r\n textBaseline: TextBaseline.bottom,\r\n textAlign: TextAlign.center,\r\n },\r\n this.paneModel\r\n )\r\n let x\r\n\r\n x = this.fx(0)\r\n xLine.set({ x1: x, x2: x }).render(this.context)\r\n\r\n x = this.fx(10) + 2 /* remove overflow */\r\n text.set({ text: '10AM', x }).render(this.context)\r\n xLine.set({ x1: x, x2: x }).render(this.context)\r\n\r\n x = this.fx(10 + 20)\r\n xLine.set({ x1: x, x2: x }).render(this.context)\r\n\r\n x = this.fx(10 + 40)\r\n text.set({ text: '12PM', x }).render(this.context)\r\n xLine.set({ x1: x, x2: x }).render(this.context)\r\n\r\n x = this.fx(10 + 60)\r\n xLine.set({ x1: x, x2: x }).render(this.context)\r\n\r\n x = this.fx(10 + 80)\r\n text.set({ text: '2PM', x }).render(this.context)\r\n xLine.set({ x1: x, x2: x }).render(this.context)\r\n\r\n x = this.fx(10 + 100)\r\n xLine.set({ x1: x, x2: x }).render(this.context)\r\n\r\n x = this.fx(10 + 120 - 1)\r\n text.set({ text: '4PM', x }).render(this.context)\r\n xLine.set({ x1: x, x2: x }).render(this.context)\r\n\r\n translate.undo()\r\n }\r\n\r\n renderText() {}\r\n\r\n renderCrossText() {}\r\n\r\n renderOverlaysLabels() {}\r\n\r\n _compute() {\r\n return { min: domainMin, max: domainMax }\r\n }\r\n\r\n computeVisibleMinMax() {\r\n return this._compute()\r\n }\r\n\r\n renderYAxis(context: CanvasRenderingContext2D) {\r\n const { MarketSentimentSettings, ChartSettings } = this.getChartLayoutSettings()\r\n const { Colors } = ChartSettings.general\r\n const isRedesign = isRedesignEnabled()\r\n const translate = getTranslate({\r\n context: this.context,\r\n xOffset: MarketSentimentSettings.left.width,\r\n yOffset: MarketSentimentSettings.top.height,\r\n })\r\n translate.do()\r\n\r\n const yLine = this.getYLine()\r\n for (const tick of [domainMin, 0, domainMax]) {\r\n const y = Math.round(this.fy(tick))\r\n yLine.set({ y1: y, y2: y }).render(context)\r\n }\r\n\r\n const text = new Text(\r\n {\r\n x: this.width + 27,\r\n font: { size: 8 },\r\n textBaseline: TextBaseline.middle,\r\n textAlign: TextAlign.right,\r\n },\r\n this.paneModel\r\n )\r\n\r\n const fillUp = isRedesign ? Colors.marketUp : greenLine\r\n const fillDown = isRedesign ? Colors.marketDown : redLine\r\n const last = this._data[this._dataLastIndex!]\r\n const percent = this._dataLastIndex !== null ? Math.floor(last * 50 + 50) : 50\r\n text.set({ y: this.fy(0) - 5, fillStyle: fillUp, text: `${percent}%` }).render(context)\r\n text.set({ y: this.fy(0) + 7, fillStyle: fillDown, text: `${100 - percent}%` }).render(context)\r\n\r\n translate.undo()\r\n }\r\n\r\n clip() {\r\n const { MarketSentimentSettings } = this.getChartLayoutSettings()\r\n this.context.beginPath()\r\n this.context.rect(MarketSentimentSettings.left.width, MarketSentimentSettings.top.height, this.width, this.height)\r\n this.context.clip()\r\n }\r\n\r\n getMinMax() {\r\n return this._compute()\r\n }\r\n\r\n renderVolumeAxis() {}\r\n\r\n renderVolume() {}\r\n\r\n toString() {\r\n return `Market sentiment chart`\r\n }\r\n}\r\nMarketSentiment.initClass()\r\n\r\nexport default MarketSentiment\r\n","import { ObjectHash } from '../../types/shared'\r\nimport Text from '../canvas/text'\r\nimport { ChartElementType, FONT_SIZE, LINE_HEIGHT, PADDING, TextAlign, TextBaseline } from '../constants/common'\r\nimport { getTranslate } from '../controllers/renderUtils'\r\nimport Pane from '../models/pane'\r\nimport Quote from '../models/quote'\r\nimport utils from '../utils'\r\nimport Chart, { BaseChartAttrs } from './base_chart'\r\n\r\ninterface MultiLineChartAttrs extends BaseChartAttrs {\r\n tickers: string[]\r\n label?: string\r\n min?: number\r\n max?: number\r\n}\r\n\r\nconst months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']\r\n\r\nclass MultiLineChart extends Chart {\r\n static type = ChartElementType.MultiLineChart\r\n tickersDimensions: number[] = []\r\n\r\n constructor(values: Partial, model: Pane) {\r\n super(values, model)\r\n this.renderText = this.renderText.bind(this)\r\n }\r\n\r\n renderChart() {\r\n const { ChartSettings, ColorsSettings } = this.getChartLayoutSettings()\r\n const translate = getTranslate({\r\n context: this.context,\r\n xOffset: this.leftOffset + ChartSettings.left.width + 0.5,\r\n yOffset: ChartSettings.top.height + 0.5,\r\n })\r\n translate.do()\r\n\r\n this.context.set('lineWidth', 1)\r\n\r\n const quotes: ObjectHash = {}\r\n for (const quote of this.getQuotes()) {\r\n quotes[quote.ticker] = quote\r\n }\r\n\r\n for (let index = this.attrs.tickers.length - 1; index >= 0; index--) {\r\n const ticker = this.attrs.tickers[index]\r\n const quote = quotes[ticker]\r\n this.context.set('strokeStyle', ColorsSettings[index % ColorsSettings.length])\r\n this.context.beginPath()\r\n for (let i = 0, end = quote.close.length, asc = end >= 0; asc ? i < end : i > end; asc ? i++ : i--) {\r\n const x = this.fx(i)\r\n if (x + this.leftOffset < -10 || x + this.leftOffset > this.model.width + 10) {\r\n // margin?\r\n continue\r\n }\r\n const y = Math.round(this.fy(quote.close[i]))\r\n this.context.lineTo(x, y)\r\n }\r\n this.context.stroke()\r\n }\r\n\r\n translate.undo()\r\n }\r\n\r\n renderText(context: CanvasRenderingContext2D) {\r\n const { ChartSettings } = this.getChartLayoutSettings()\r\n const { Colors } = ChartSettings.general\r\n const text = this.attrs.label || ''\r\n const y = (this.height - 4) / 2\r\n new Text(\r\n {\r\n text,\r\n x: 28,\r\n y: ChartSettings.top.height + y,\r\n angle: -90,\r\n font: { size: 10, weight: '900', family: 'Lato, sans-serif' },\r\n fillStyle: Colors.textSecondary,\r\n textAlign: TextAlign.center,\r\n textBaseline: TextBaseline.alphabetic,\r\n },\r\n this.paneModel\r\n ).render(context)\r\n return this.renderCrossText(context, this.data.barToDataIndex.length - 1)\r\n }\r\n\r\n renderCrossText(context: CanvasRenderingContext2D, crossIndex: number) {\r\n let hasTickerDimensions = false\r\n const { ChartSettings, ColorsSettings } = this.getChartLayoutSettings()\r\n const { Colors } = ChartSettings.general\r\n const maxTickerLength = utils.max(this.attrs.tickers.map((t) => t.length))\r\n\r\n const date = utils.dateFromUnixTimestamp(this.data.getDataByBarIndex('date', crossIndex) ?? 0)\r\n const month = date.getMonth() // 20141126\r\n const year = date.getFullYear()\r\n const day = date.getDate()\r\n const isLastDate = crossIndex === this.data.close.length - 1\r\n\r\n new Text(\r\n {\r\n text: `${months[month]} ${day} ${year} `,\r\n x: ChartSettings.left.width + (maxTickerLength > 15 ? 200 : 132),\r\n y: 30,\r\n font: { size: 8 },\r\n fillStyle: Colors.text,\r\n background: Colors.canvasFill,\r\n },\r\n this.paneModel\r\n ).render(context)\r\n\r\n const quotes: ObjectHash = {}\r\n for (const quote of this.getQuotes()) {\r\n quotes[quote.ticker] = quote\r\n }\r\n for (let index = 0; index < this.attrs.tickers.length; index++) {\r\n const y = PADDING.S + (PADDING.S + LINE_HEIGHT.M) * index\r\n if (this.tickersDimensions[index]) {\r\n hasTickerDimensions = true\r\n context.fillStyle = Colors.canvasFill\r\n context.fillRect(\r\n ChartSettings.left.width - PADDING.XXXS,\r\n y - PADDING.XXXS,\r\n PADDING.XXXS + this.tickersDimensions[index] + PADDING.XXXS,\r\n PADDING.XXXS + FONT_SIZE.M + PADDING.XXXS\r\n )\r\n }\r\n const ticker = this.attrs.tickers[index]\r\n const closeValue = quotes[ticker].close[crossIndex]\r\n const text = new Text(\r\n {\r\n text: `${ticker} ${typeof closeValue === 'number' ? closeValue.toFixed(2) : NaN} `,\r\n x: ChartSettings.left.width,\r\n y,\r\n font: { size: FONT_SIZE.M, style: 'bold' },\r\n lineHeight: LINE_HEIGHT.M,\r\n fillStyle: ColorsSettings[index % ColorsSettings.length],\r\n textAlign: TextAlign.left,\r\n textBaseline: TextBaseline.top,\r\n },\r\n this.paneModel\r\n )\r\n if (isLastDate) {\r\n this.tickersDimensions[index] = text.measure(context)\r\n }\r\n text.render(context)\r\n }\r\n\r\n if (!hasTickerDimensions) this.renderCrossText(context, crossIndex)\r\n }\r\n\r\n computeVisibleMinMax(...arrays: Array) {\r\n let min = Number.MAX_VALUE\r\n let max = Number.MIN_VALUE\r\n\r\n const { leftOffset } = this.model\r\n for (const arr of arrays) {\r\n for (let i = 0, end = arr.length, asc = end >= 0; asc ? i < end : i > end; asc ? i++ : i--) {\r\n const center = this.fx(i)\r\n if (center + leftOffset < 0 || center + leftOffset > this.width) {\r\n // margin?\r\n continue\r\n }\r\n\r\n if (min > arr[i]) {\r\n min = arr[i]\r\n }\r\n if (max < arr[i]) {\r\n max = arr[i]\r\n }\r\n }\r\n }\r\n\r\n return { min, max }\r\n }\r\n\r\n getMinMax() {\r\n const quotes = this.getQuotes()\r\n let { min, max } = this.computeVisibleMinMax(...quotes.map((q) => q.close))\r\n if (typeof this.attrs.min !== 'undefined') {\r\n min = this.attrs.min\r\n }\r\n if (typeof this.attrs.max !== 'undefined') {\r\n max = this.attrs.max\r\n }\r\n return { min, max }\r\n }\r\n\r\n renderVolumeAxis() {}\r\n\r\n renderVolume() {}\r\n\r\n getQuotes() {\r\n return Quote.select(\r\n (q: Quote) =>\r\n this.attrs.tickers.includes(q.ticker) &&\r\n q.timeframe === this.data?.timeframe &&\r\n this.model.chart_layout().isIdeaId(q.ideaID)\r\n )\r\n }\r\n\r\n toString() {\r\n return `Line chart ${this.data.ticker}`\r\n }\r\n}\r\n\r\nexport default MultiLineChart\r\n","import { ChartElementType } from '../constants/common'\r\nimport { getTranslate } from '../controllers/renderUtils'\r\nimport { getBarWithoutMarginWidth } from '../utils/chart'\r\nimport { drawInVisibleArea } from '../utils/draw_in_visible_area'\r\nimport Chart from './base_chart'\r\n\r\nclass OHLCChart extends Chart {\r\n static type = ChartElementType.OhlcChart\r\n static label = 'OHLC'\r\n static iconName = 'ohlcChartType'\r\n\r\n renderChart() {\r\n const { ChartSettings } = this.getChartLayoutSettings()\r\n const { Colors } = ChartSettings.general\r\n const translate = getTranslate({\r\n context: this.context,\r\n xOffset: this.leftOffset + ChartSettings.left.width,\r\n yOffset: ChartSettings.top.height,\r\n })\r\n translate.do()\r\n\r\n const barWithoutMarginWidth = getBarWithoutMarginWidth(this.model)\r\n\r\n let lineWidth = 1\r\n if (barWithoutMarginWidth >= 40) {\r\n lineWidth = 4\r\n } else if (barWithoutMarginWidth >= 30) {\r\n lineWidth = 3\r\n } else if (barWithoutMarginWidth >= 15) {\r\n lineWidth = 2\r\n }\r\n const lineThickness = lineWidth / 2\r\n const handleLengthFromWick = Math.round(barWithoutMarginWidth / 2 - lineThickness)\r\n const lineOffset = lineWidth % 2 === 0 ? 0 : 0.5\r\n this.context.set('lineWidth', lineWidth)\r\n\r\n drawInVisibleArea({\r\n quote: this.data,\r\n paneModel: this.paneModel,\r\n leftOffset: this.leftOffset,\r\n width: this.width,\r\n drawBarCallback: (i: number, x: number) => {\r\n const barX = ~~(x - 1) + lineOffset // move 1px to left so cursor don't cover bar of ohlc-chart & round for pixel perfect render on zoom\r\n\r\n this.context.beginPath()\r\n this.context.set(\r\n 'strokeStyle',\r\n this.data.close[i] < this.data.open[i] ? Colors.ohlcTrendDown : Colors.ohlcTrendUp\r\n )\r\n\r\n this.context.moveTo(barX, Math.round(this.fy(this.data.high[i])))\r\n this.context.lineTo(barX, Math.round(this.fy(this.data.low[i])))\r\n\r\n if (handleLengthFromWick >= 1) {\r\n const open = Math.round(this.fy(this.data.open[i]))\r\n this.context.moveTo(barX + lineThickness, open + lineOffset) // move to right edge of wick\r\n this.context.lineTo(barX - lineThickness - handleLengthFromWick, open + lineOffset) // draw line to the left\r\n\r\n const close = Math.round(this.fy(this.data.close[i]))\r\n this.context.moveTo(barX - lineThickness, close + lineOffset) // move to left edge of wick\r\n this.context.lineTo(barX + lineThickness + handleLengthFromWick, close + lineOffset) // draw line to the right\r\n }\r\n\r\n this.context.stroke()\r\n },\r\n })\r\n\r\n translate.undo()\r\n }\r\n\r\n toString() {\r\n return `OHLC ${this.data.ticker}`\r\n }\r\n}\r\n\r\nexport default OHLCChart\r\n","import { ObjectHash } from '../../types/shared'\r\nimport Text from '../canvas/text'\r\nimport { ChartElementType, FONT_SIZE, MARGIN, OFFSET, PADDING, TextAlign, TextBaseline } from '../constants/common'\r\nimport { getTranslate } from '../controllers/renderUtils'\r\nimport Pane from '../models/pane'\r\nimport Quote from '../models/quote'\r\nimport utils from '../utils'\r\nimport Chart, { BaseChartAttrs } from './base_chart'\r\n\r\nconst months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']\r\nconst NO_VALUE = ' - '\r\n\r\ninterface PerfChartAttrs extends BaseChartAttrs {\r\n tickers: string[]\r\n label?: string\r\n fromDate: string\r\n toDate: string\r\n min?: number\r\n max?: number\r\n}\r\n\r\nclass PerfChart extends Chart {\r\n static type = ChartElementType.PerfChart\r\n\r\n overlayLabelWidth: ObjectHash\r\n perf: ObjectHash> = {}\r\n dates: number[] = []\r\n\r\n constructor(values: Partial, model: Pane) {\r\n super(values, model)\r\n this.renderText = this.renderText.bind(this)\r\n this.renderOverlaysLabels = this.renderOverlaysLabels.bind(this)\r\n this.renderYAxis = this.renderYAxis.bind(this)\r\n this.overlayLabelWidth = {}\r\n }\r\n\r\n fx = (i: number) => this.paneModel.scale.x(i)\r\n\r\n getCompleteChartNumOfBars() {\r\n return this.dates.length\r\n }\r\n\r\n renderChart() {\r\n const { ChartSettings, ColorsSettings } = this.getChartLayoutSettings()\r\n const translate = getTranslate({\r\n context: this.context,\r\n xOffset: this.leftOffset + ChartSettings.left.width + 0.5,\r\n yOffset: ChartSettings.top.height + 0.5,\r\n })\r\n translate.do()\r\n\r\n this.context.beginPath()\r\n this.context.set('lineWidth', 1)\r\n for (let index = 0; index < this.attrs.tickers.length; index++) {\r\n const ticker = this.attrs.tickers[index]\r\n if ((this.perf[ticker] != null ? this.perf[ticker].length : 0) > 0) {\r\n this.context.set('strokeStyle', ColorsSettings[index % ColorsSettings.length])\r\n this.context.beginPath()\r\n // We don't need to calculate first/last visible bars because the data is already cropped\r\n for (let i = 0; i < this.perf[ticker].length; i++) {\r\n const value = this.perf[ticker][i]\r\n if (value !== null && Number.isFinite(value)) {\r\n this.context.lineTo(this.fx(i), Math.round(this.fy(value)))\r\n }\r\n }\r\n this.context.stroke()\r\n }\r\n }\r\n\r\n translate.undo()\r\n }\r\n\r\n renderText(context: CanvasRenderingContext2D) {\r\n const { ChartSettings } = this.getChartLayoutSettings()\r\n const { Colors } = ChartSettings.general\r\n const period = (() => {\r\n switch (this.model.quote().timeframe) {\r\n case 'd':\r\n return 'DAILY'\r\n case 'w':\r\n return 'WEEKLY'\r\n case 'm':\r\n return 'MONTHLY'\r\n default:\r\n return\r\n }\r\n })()\r\n const y = (this.height - 4) / 2\r\n new Text(\r\n {\r\n text: period,\r\n x: 28,\r\n y: ChartSettings.top.height + y,\r\n angle: -90,\r\n font: { size: 10, weight: '900', family: 'Lato, sans-serif' },\r\n fillStyle: Colors.textSecondary,\r\n textAlign: TextAlign.center,\r\n textBaseline: TextBaseline.alphabetic,\r\n },\r\n this.paneModel\r\n ).render(context)\r\n }\r\n\r\n renderCrossText(context: CanvasRenderingContext2D, crossIndex: number) {\r\n const { ChartSettings, ColorsSettings } = this.getChartLayoutSettings()\r\n const { Colors } = ChartSettings.general\r\n const date = utils.dateFromUnixTimestamp(this.dates[crossIndex] ?? 0)\r\n let dateString = ''\r\n const month = date.getMonth() // 20141126\r\n const year = date.getFullYear()\r\n const day = date.getDate()\r\n switch (this.data.timeframe) {\r\n case 'd':\r\n case 'w':\r\n dateString = `${months[month]} ${day}`\r\n break\r\n case 'm':\r\n dateString = `${months[month]} ${year}`\r\n break\r\n default:\r\n return\r\n }\r\n\r\n let shouldRenderDate = false\r\n for (let index = 0; index < this.attrs.tickers.length; index++) {\r\n const ticker = this.attrs.tickers[index]\r\n const tickerData = this.perf[ticker]\r\n if (tickerData?.length) {\r\n context.fillStyle = Colors.canvasFill\r\n context.fillRect(\r\n ChartSettings.left.width - PADDING.XXXS,\r\n OFFSET.M + (FONT_SIZE.M + MARGIN.XS) * index - PADDING.XXXS,\r\n PADDING.XXXS + this.overlayLabelWidth[ticker] + PADDING.XXXS,\r\n PADDING.XXXS + FONT_SIZE.M + PADDING.XXXS\r\n )\r\n const value = tickerData[crossIndex] ?? null\r\n const percentageText = value !== null ? `${value.toFixed(2)}%` : NO_VALUE\r\n shouldRenderDate = shouldRenderDate || value !== null\r\n new Text(\r\n {\r\n text: `${ticker} ${percentageText}`,\r\n x: ChartSettings.left.width,\r\n y: OFFSET.M + (FONT_SIZE.M + MARGIN.XS) * index,\r\n font: { size: FONT_SIZE.M, style: 'bold' },\r\n fillStyle: ColorsSettings[index % ColorsSettings.length],\r\n textAlign: TextAlign.left,\r\n textBaseline: TextBaseline.top,\r\n },\r\n this.paneModel\r\n ).render(context)\r\n }\r\n }\r\n\r\n if (shouldRenderDate) {\r\n new Text(\r\n {\r\n text: `${dateString} `,\r\n x: ChartSettings.left.width + 132,\r\n y: 30,\r\n font: { size: 8 },\r\n fillStyle: Colors.text,\r\n background: Colors.canvasFill,\r\n },\r\n this.paneModel\r\n ).render(context)\r\n }\r\n }\r\n\r\n renderOverlaysLabels(context: CanvasRenderingContext2D) {\r\n super.renderOverlaysLabels(context)\r\n const { ChartSettings, ColorsSettings } = this.getChartLayoutSettings()\r\n\r\n for (let index = 0; index < this.attrs.tickers.length; index++) {\r\n const ticker = this.attrs.tickers[index]\r\n const tickerData = this.perf[ticker]\r\n if (tickerData?.length) {\r\n const lastCrossIndex = this.perf[ticker].findLastIndex((value) => value !== null)\r\n const value = tickerData[lastCrossIndex] ?? null\r\n const percentageText = value !== null ? `${value.toFixed(2)}%` : NO_VALUE\r\n\r\n const text = new Text(\r\n {\r\n text: `${ticker} ${percentageText}`,\r\n x: ChartSettings.left.width,\r\n y: OFFSET.M + (FONT_SIZE.M + MARGIN.XS) * index,\r\n font: { size: FONT_SIZE.M, style: 'bold' },\r\n fillStyle: ColorsSettings[index % ColorsSettings.length],\r\n textAlign: TextAlign.left,\r\n textBaseline: TextBaseline.top,\r\n },\r\n this.paneModel\r\n )\r\n this.overlayLabelWidth = { ...this.overlayLabelWidth, [ticker]: text.measure(context) }\r\n text.render(context)\r\n }\r\n }\r\n }\r\n\r\n _compute() {\r\n let min = Number.MAX_VALUE\r\n let max = Number.MIN_VALUE\r\n this.perf = {}\r\n const quotes = this.getQuotes()\r\n\r\n const fromDate = new Date(this.attrs.fromDate + ' 00:00')\r\n const toDate = new Date(this.attrs.toDate + ' 23:59')\r\n this.dates = []\r\n for (const quote of quotes) {\r\n for (let i = 0; i < quote.date.length; i++) {\r\n const timestampe = quote.date[i]\r\n const date = utils.dateFromUnixTimestamp(timestampe)\r\n if (fromDate <= date && date <= toDate && this.dates.indexOf(timestampe) === -1) {\r\n this.dates.push(timestampe)\r\n }\r\n }\r\n }\r\n\r\n this.dates.sort((a, b) => a - b)\r\n\r\n for (const quote of quotes) {\r\n const ticker = quote.ticker\r\n this.perf[ticker] = []\r\n\r\n const dateToIndex = quote.getDateToIndex()\r\n let first = null\r\n let lastValue = null\r\n let dataIndex = -1\r\n for (let i = 0; i < this.dates.length; i++) {\r\n const timestamp = this.dates[i]\r\n dataIndex = dateToIndex[timestamp]\r\n\r\n if (typeof dataIndex === 'number') {\r\n first = first === null ? quote.close[dataIndex] : first\r\n const value = (quote.close[dataIndex] * 100) / (first ?? 0) - 100\r\n lastValue = Number.isFinite(value) ? value : null\r\n }\r\n\r\n this.perf[ticker][i] = lastValue\r\n\r\n if (lastValue !== null && min > lastValue) {\r\n min = lastValue\r\n }\r\n if (lastValue !== null && max < lastValue) {\r\n max = lastValue\r\n }\r\n }\r\n }\r\n\r\n return { min, max }\r\n }\r\n\r\n renderYAxis(context: CanvasRenderingContext2D) {\r\n const { ChartSettings } = this.getChartLayoutSettings()\r\n const { Colors } = ChartSettings.general\r\n const translate = getTranslate({\r\n context,\r\n xOffset: ChartSettings.left.width,\r\n yOffset: ChartSettings.top.height,\r\n })\r\n translate.do()\r\n const ticks = this.paneModel.scale.y.ticks(10)\r\n const yLine = this.getYLine()\r\n const text = new Text(\r\n {\r\n x: this.width + 8,\r\n font: { size: 8 },\r\n fillStyle: Colors.text,\r\n textBaseline: TextBaseline.middle,\r\n },\r\n this.paneModel\r\n )\r\n for (const tick of ticks) {\r\n const y = Math.round(this.fy(tick))\r\n yLine.set({ y1: y, y2: y }).render(context)\r\n text.set({ text: tick.toFixed(2), y }).render(context)\r\n }\r\n translate.undo()\r\n }\r\n\r\n renderXAxis() {\r\n const { ChartSettings } = this.getChartLayoutSettings()\r\n const { Colors } = ChartSettings.general\r\n const translate = getTranslate({\r\n context: this.context,\r\n xOffset: this.leftOffset + ChartSettings.left.width,\r\n yOffset: ChartSettings.top.height,\r\n })\r\n translate.do()\r\n const text = new Text(\r\n {\r\n y: this.height + 18,\r\n font: { size: 8 },\r\n fillStyle: Colors.text,\r\n textBaseline: TextBaseline.bottom,\r\n textAlign: TextAlign.center,\r\n },\r\n this.paneModel\r\n )\r\n const textWidth = text.set({ text: '2020' }).measure(this.context)\r\n\r\n let date = new Date(this.dates[0] * 1000)\r\n let lastMonth = date.getMonth() + '-' + date.getFullYear()\r\n\r\n let monthsInData = 0\r\n this.dates.forEach((d, index) => {\r\n if (index < 1) {\r\n return\r\n }\r\n\r\n const date = new Date(d * 1000)\r\n const month = date.getMonth() + '-' + date.getFullYear()\r\n if (month !== lastMonth) {\r\n monthsInData++\r\n }\r\n lastMonth = month\r\n })\r\n\r\n const availableTickSpots = ~~(this.width / textWidth)\r\n const monthsToAvail = monthsInData / availableTickSpots\r\n let renderMonth\r\n if (monthsToAvail <= 1) {\r\n renderMonth = () => true\r\n } else if (monthsToAvail <= 2) {\r\n renderMonth = (x: number) => x % 2 === 0\r\n } else if (monthsToAvail <= 3) {\r\n renderMonth = (x: number) => x % 3 === 0\r\n } else if (monthsToAvail <= 4) {\r\n renderMonth = (x: number) => x % 4 === 0\r\n } else if (monthsToAvail <= 6) {\r\n renderMonth = (x: number) => x % 6 === 0\r\n } else {\r\n renderMonth = (x: number) => x === 0\r\n }\r\n\r\n date = new Date(this.dates[0] * 1000)\r\n lastMonth = date.getMonth() + '-' + date.getFullYear()\r\n\r\n const xLine = this.getXLine()\r\n\r\n for (let i = 0; i < this.dates.length; i++) {\r\n date = new Date(this.dates[i] * 1000)\r\n const month = date.getMonth() + '-' + date.getFullYear()\r\n if (month !== lastMonth) {\r\n lastMonth = month\r\n const x = this.fx(i)\r\n if (x + this.leftOffset < -15 || x + this.leftOffset > this.width + 15) {\r\n // margin?\r\n continue\r\n }\r\n xLine.set({ x1: x, x2: x }).render(this.context)\r\n\r\n if (!renderMonth(date.getMonth())) {\r\n continue\r\n }\r\n\r\n text\r\n .set({\r\n text: date.getMonth() === 0 ? date.getFullYear().toString() : months[date.getMonth()],\r\n x: x,\r\n })\r\n .render(this.context)\r\n }\r\n }\r\n\r\n translate.undo()\r\n }\r\n\r\n getMinMax() {\r\n return this._compute()\r\n }\r\n\r\n renderVolumeAxis() {}\r\n\r\n renderVolume() {}\r\n\r\n getQuotes() {\r\n return Quote.select(\r\n (q: Quote) =>\r\n this.attrs.tickers.includes(q.ticker) &&\r\n q.timeframe === this.data?.timeframe &&\r\n this.model.chart_layout().isIdeaId(q.ideaID)\r\n )\r\n }\r\n\r\n toString() {\r\n return `Perf chart ${this.data.ticker}`\r\n }\r\n}\r\n\r\nexport default PerfChart\r\n","import { ChartElementType } from '../constants/common'\r\nimport candleStick from './candle_stick'\r\nimport hollowCandleStick from './candle_stick_hollow'\r\nimport heikinAshi from './heikin_ashi'\r\nimport lineChart from './line_chart'\r\nimport marketSentiment from './market_sentiment'\r\nimport multiLineCharts from './multi_line_chart'\r\nimport ohlcChart from './ohlc_chart'\r\nimport perfChart from './perf_chart'\r\n\r\nexport const chartsByType = Object.freeze({\r\n [ChartElementType.CandleStick]: candleStick,\r\n [ChartElementType.HeikinAshi]: heikinAshi,\r\n [ChartElementType.HollowCandleStick]: hollowCandleStick,\r\n [ChartElementType.LineChart]: lineChart,\r\n [ChartElementType.MarketSentiment]: marketSentiment,\r\n [ChartElementType.MultiLineChart]: multiLineCharts,\r\n [ChartElementType.OhlcChart]: ohlcChart,\r\n [ChartElementType.PerfChart]: perfChart,\r\n})\r\n","export const FONT_SIZE = {\r\n XXS: 5,\r\n XS: 7,\r\n S: 8,\r\n M: 10,\r\n L: 11,\r\n XXL: 18,\r\n XXXL: 23,\r\n}\r\nexport const LINE_HEIGHT = {\r\n XS: 7,\r\n S: 8,\r\n M: 10,\r\n}\r\nexport const PADDING = {\r\n XXXS: 1,\r\n XXS: 2,\r\n XS: 3,\r\n S: 5,\r\n}\r\nexport const MARGIN = {\r\n XS: 4,\r\n}\r\nexport const CHART_MARGIN = {\r\n S: 15,\r\n M: 30,\r\n L: 35,\r\n XL: 38,\r\n XXL: 48,\r\n}\r\nexport const SETTINGS_HEIGHT = 44\r\nexport const TICKER_TIMEFRAME_CHANGE_HEIGHT = 20\r\nexport const OFFSET = {\r\n XXS: 2,\r\n XS: 4,\r\n S: 6,\r\n M: 8,\r\n XXL: 20,\r\n}\r\nexport const MONTHS = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']\r\n\r\nexport enum ChartEditorEnum {\r\n publish = 'publish',\r\n tools = 'tools',\r\n ideas = 'ideas',\r\n settings = 'settings',\r\n timeframe = 'timeframe',\r\n}\r\n\r\nexport enum LayoutType {\r\n '1h1v' = '1h1v',\r\n '1h2v' = '1h2v',\r\n '1h3v' = '1h3v',\r\n '2h1v' = '2h1v',\r\n '2h2v' = '2h2v',\r\n '3h1v' = '3h1v',\r\n '3h2v' = '3h2v',\r\n '1l2r' = '1l2r',\r\n '1t2b' = '1t2b',\r\n}\r\n\r\nexport enum CanvasElementType {\r\n element = 'canvas/element',\r\n arrow = 'canvas/arrow',\r\n brushV1 = 'canvas/brush/brush_v1',\r\n curve = 'canvas/curve',\r\n ellipse = 'canvas/ellipse',\r\n fibonacciRetracements = 'canvas/fibonacci_retracements',\r\n horizontalLine = 'canvas/horizontal_line',\r\n line = 'canvas/line',\r\n measure = 'canvas/measure',\r\n pitchforkV1 = 'canvas/pitchfork/pitchfork_v1',\r\n polygon = 'canvas/polygon',\r\n position = 'canvas/position',\r\n rectangle = 'canvas/rectangle',\r\n rotatedRectangle = 'canvas/rotated_rectangle',\r\n scaledLine = 'canvas/scaled_line',\r\n scaledText = 'canvas/scaled_text',\r\n symbol = 'canvas/symbol',\r\n text = 'canvas/text',\r\n triangle = 'canvas/triangle',\r\n verticalLine = 'canvas/vertical_line',\r\n xabcd = 'canvas/xabcd',\r\n calloutV1 = 'canvas/callout/callout_v1',\r\n elliottWaves = 'canvas/elliott_waves/elliott_waves',\r\n ellipseV1 = 'canvas/ellipse/ellipse_v1',\r\n rotatedRectangleV1 = 'canvas/rotated_rectangle/rotated_rectangle_v1',\r\n}\r\n\r\nexport enum ChartElementType {\r\n CandleStick = 'charts/candle_stick',\r\n HeikinAshi = 'charts/heikin_ashi',\r\n HollowCandleStick = 'charts/candle_stick_hollow',\r\n LineChart = 'charts/line_chart',\r\n OhlcChart = 'charts/ohlc_chart',\r\n MarketSentiment = 'charts/market_sentiment',\r\n MultiLineChart = 'charts/multi_line_chart',\r\n PerfChart = 'charts/perf_chart',\r\n}\r\n\r\nexport enum IndicatorType {\r\n Indicator = 'indicators/indicator',\r\n None = 'indicators/none',\r\n Adx = 'indicators/adx',\r\n Aro = 'indicators/aro',\r\n Aroosc = 'indicators/aroosc',\r\n Atr = 'indicators/atr',\r\n Cci = 'indicators/cci',\r\n Cot = 'indicators/cot',\r\n Fi = 'indicators/fi',\r\n Macd = 'indicators/macd',\r\n Mfi = 'indicators/mfi',\r\n Obv = 'indicators/obv',\r\n Perf = 'indicators/perf',\r\n Rmi = 'indicators/rmi',\r\n Roc = 'indicators/roc',\r\n Rsi = 'indicators/rsi',\r\n Rvol = 'indicators/rvol',\r\n Rwi = 'indicators/rwi',\r\n Stofa = 'indicators/stofa',\r\n Stofu = 'indicators/stofu',\r\n Stosl = 'indicators/stosl',\r\n Trix = 'indicators/trix',\r\n Ult = 'indicators/ult',\r\n Vol = 'indicators/vol',\r\n Wr = 'indicators/wr',\r\n Shrtfl = 'indicators/shrtfl',\r\n Shrtra = 'indicators/shrtra',\r\n}\r\n\r\nexport enum OverlayType {\r\n Overlay = 'overlays/overlay',\r\n None = 'overlays/none',\r\n Bb = 'overlays/bb',\r\n Dch = 'overlays/dch',\r\n Ema = 'overlays/ema',\r\n Ema2 = 'overlays/ema2',\r\n Hilo = 'overlays/hilo',\r\n Hline = 'overlays/hline',\r\n Ic = 'overlays/ic',\r\n Icf = 'overlays/icf',\r\n Kch = 'overlays/kch',\r\n Patterns = 'overlays/patterns',\r\n Pp = 'overlays/pp',\r\n Sar = 'overlays/sar',\r\n Sma = 'overlays/sma',\r\n Sma2 = 'overlays/sma2',\r\n Str = 'overlays/str',\r\n Vp = 'overlays/vp',\r\n Vwap = 'overlays/vwap',\r\n}\r\n\r\nexport enum ChartEventDbType {\r\n Dividends = 'chartEvent/dividends',\r\n Split = 'chartEvent/split',\r\n Earnings = 'chartEvent/earnings',\r\n}\r\n\r\nexport enum ChartEventType {\r\n ChartEvent = 'chartEvent/chartEvent',\r\n Dividends = 'chartEvent/dividends',\r\n Split = 'chartEvent/split',\r\n Earnings = 'chartEvent/earnings',\r\n}\r\n\r\nexport enum ChartEventBadgeType {\r\n Dividends = 'chartEvent/dividends',\r\n Split = 'chartEvent/split',\r\n EarningsPositive = 'chartEvent/earnings',\r\n EarningsNegative = 'chartEvent/earningsNegative',\r\n EarningsNeutral = 'chartEvent/earningsNeutral',\r\n EarningsFuture = 'chartEvent/earningsFuture',\r\n}\r\n\r\nexport const ChartEventLabels: Record = {\r\n [ChartEventBadgeType.Dividends]: 'Dividends',\r\n [ChartEventBadgeType.Split]: 'Split',\r\n [ChartEventBadgeType.EarningsPositive]: 'Earnings & Revenue',\r\n [ChartEventBadgeType.EarningsNegative]: 'Earnings & Revenue',\r\n [ChartEventBadgeType.EarningsNeutral]: 'Earnings & Revenue',\r\n [ChartEventBadgeType.EarningsFuture]: 'Earnings & Revenue',\r\n}\r\n\r\ninterface LayoutRule {\r\n columns: number\r\n rows: number\r\n count: number\r\n gridAreas?: string[]\r\n}\r\n\r\nexport const LAYOUTS: Record = {\r\n '1h1v': { columns: 1, rows: 1, count: 1 },\r\n '1h2v': { columns: 1, rows: 2, count: 2 },\r\n '1h3v': { columns: 1, rows: 3, count: 3 },\r\n '2h1v': { columns: 2, rows: 1, count: 2 },\r\n '2h2v': { columns: 2, rows: 2, count: 4 },\r\n '3h1v': { columns: 3, rows: 1, count: 3 },\r\n '3h2v': { columns: 3, rows: 2, count: 6 },\r\n '1l2r': {\r\n columns: 2,\r\n rows: 2,\r\n count: 3,\r\n gridAreas: ['1 / 1 / 3 / 2', '1 / 2 / 2 / 3', '2 / 2 / 3 / 3'],\r\n },\r\n '1t2b': {\r\n columns: 2,\r\n rows: 2,\r\n count: 3,\r\n gridAreas: ['1 / 1 / 2 / 3', '2 / 1 / 3 / 2', '2 / 2 / 3 / 3'],\r\n },\r\n}\r\n\r\nexport const SORT_DIRECTION = {\r\n ASC: 'ASC',\r\n DESC: 'DESC',\r\n}\r\n\r\nexport const ICON_SIZE = {\r\n L: 32,\r\n}\r\n\r\n// Keep in sync with the copy in Website repo - Website/js/main/constants.ts\r\nexport enum TIMEFRAME {\r\n i1 = 'i1',\r\n i2 = 'i2',\r\n i3 = 'i3',\r\n i5 = 'i5',\r\n i10 = 'i10',\r\n i15 = 'i15',\r\n i30 = 'i30',\r\n h = 'h',\r\n h2 = 'h2',\r\n h4 = 'h4',\r\n d = 'd',\r\n w = 'w',\r\n m = 'm',\r\n}\r\n\r\nexport type TimeframeAndIntradayType = TIMEFRAME | 'intraday'\r\n\r\nexport const TIMEFRAMES_WITH_PRE_MARKET = [TIMEFRAME.i1, TIMEFRAME.i2, TIMEFRAME.i3, TIMEFRAME.i5]\r\n\r\nexport const IntradayTimeframeInterval = {\r\n [TIMEFRAME.i1]: 1,\r\n [TIMEFRAME.i2]: 2,\r\n [TIMEFRAME.i3]: 3,\r\n [TIMEFRAME.i5]: 5,\r\n [TIMEFRAME.i10]: 10,\r\n [TIMEFRAME.i15]: 15,\r\n [TIMEFRAME.i30]: 30,\r\n [TIMEFRAME.h]: 60,\r\n [TIMEFRAME.h2]: 120,\r\n [TIMEFRAME.h4]: 240,\r\n}\r\n\r\nexport const TimeframeLabelShort = {\r\n [TIMEFRAME.i1]: '1M',\r\n [TIMEFRAME.i2]: '2M',\r\n [TIMEFRAME.i3]: '3M',\r\n [TIMEFRAME.i5]: '5M',\r\n [TIMEFRAME.i10]: '10M',\r\n [TIMEFRAME.i15]: '15M',\r\n [TIMEFRAME.i30]: '30M',\r\n [TIMEFRAME.h]: '1H',\r\n [TIMEFRAME.h2]: '2H',\r\n [TIMEFRAME.h4]: '4H',\r\n [TIMEFRAME.d]: 'D',\r\n [TIMEFRAME.w]: 'W',\r\n [TIMEFRAME.m]: 'M',\r\n}\r\n\r\nexport enum DateRangeType {\r\n d1 = 'd1',\r\n d5 = 'd5',\r\n m1 = 'm1',\r\n m3 = 'm3',\r\n m6 = 'm6',\r\n ytd = 'ytd',\r\n y1 = 'y1',\r\n y2 = 'y2',\r\n y5 = 'y5',\r\n max = 'max',\r\n}\r\n\r\nexport enum QuoteFinancialAttachment {\r\n shortInterest = 'shortInterest',\r\n}\r\n\r\nexport const TIMEFRAME_SECONDS = {\r\n [TIMEFRAME.i1]: 60,\r\n [TIMEFRAME.i2]: 120,\r\n [TIMEFRAME.i3]: 180,\r\n [TIMEFRAME.i5]: 300,\r\n [TIMEFRAME.i10]: 600,\r\n [TIMEFRAME.i15]: 900,\r\n [TIMEFRAME.i30]: 1800,\r\n [TIMEFRAME.h]: 3600,\r\n [TIMEFRAME.h2]: 7200,\r\n [TIMEFRAME.h4]: 14400,\r\n [TIMEFRAME.d]: 86400,\r\n [TIMEFRAME.w]: 604800,\r\n [TIMEFRAME.m]: 2592000,\r\n}\r\n\r\nexport const CRYPTOS = {\r\n BTCUSD: 'BTCUSD',\r\n LTCUSD: 'LTCUSD',\r\n ETHUSD: 'ETHUSD',\r\n XRPUSD: 'XRPUSD',\r\n BCHUSD: 'BCHUSD',\r\n BTCEUR: 'BTCEUR',\r\n LTCEUR: 'LTCEUR',\r\n ETHEUR: 'ETHEUR',\r\n XRPEUR: 'XRPEUR',\r\n BCHEUR: 'BCHEUR',\r\n LTCBTC: 'LTCBTC',\r\n ETHBTC: 'ETHBTC',\r\n XRPBTC: 'XRPBTC',\r\n BCHBTC: 'BCHBTC',\r\n}\r\n\r\nexport enum SpecificChartFunctionality {\r\n default = 'default',\r\n quotePage = 'quotePage',\r\n quotePerf = 'quotePerf',\r\n chartPage = 'chartPage',\r\n smallIndex = 'smallIndex',\r\n offScreen = 'offScreen',\r\n forexPage = 'forexPage',\r\n futuresPage = 'futuresPage',\r\n cryptoPage = 'cryptoPage',\r\n}\r\n\r\nexport enum TextAlign {\r\n left = 'left',\r\n right = 'right',\r\n center = 'center',\r\n start = 'start',\r\n end = 'end',\r\n}\r\n\r\nexport enum TextBaseline {\r\n top = 'top',\r\n hanging_dont_use = 'hanging', // not supported - https://github.com/Automattic/node-canvas/wiki/Compatibility-Status#text-styles\r\n middle = 'middle',\r\n alphabetic = 'alphabetic',\r\n ideographic_dont_use = 'ideographic', // not supported - https://github.com/Automattic/node-canvas/wiki/Compatibility-Status#text-styles\r\n bottom = 'bottom',\r\n}\r\n\r\nexport enum ScaleType {\r\n Linear = 'linear',\r\n Percentage = 'percentage',\r\n Logarithmic = 'logarithmic',\r\n}\r\n\r\nexport enum QuotePollingIntervalInMs {\r\n Default = 2000,\r\n Free = 180000,\r\n Elite = Default,\r\n EliteStocksReduced = 60000,\r\n}\r\n\r\nexport const EXTRA_MARKET_BUFFER_MINUTES = 30\r\n\r\nexport const ScaleLabel = {\r\n [ScaleType.Linear]: 'Linear',\r\n [ScaleType.Percentage]: 'Percentage',\r\n [ScaleType.Logarithmic]: 'Logarithmic',\r\n}\r\n\r\nexport const PANE_HEIGHT_DEFAULT = {\r\n chart: 400,\r\n indicator: 120,\r\n}\r\n\r\nexport const INDICATOR_LABEL_HEIGHT = 24\r\n\r\nexport const MOBILE_BARS_TO_VIEW = 150 // 5 months of daily bars\r\n\r\nexport const MOBILE_VIEW_BREAKPOINT_WIDTH = 768\r\n\r\nexport const FREE_DATE_RANGES = ['m1', 'm3', 'm6', 'ytd', 'y1', 'y2', 'y5', 'max']\r\n\r\nexport const getTimeframeLabel = (timeframe: string) => {\r\n switch (timeframe) {\r\n case TIMEFRAME.i1:\r\n return '1 MIN'\r\n case TIMEFRAME.i2:\r\n return '2 MIN'\r\n case TIMEFRAME.i3:\r\n return '3 MIN'\r\n case TIMEFRAME.i5:\r\n return '5 MIN'\r\n case TIMEFRAME.i10:\r\n return '10 MIN'\r\n case TIMEFRAME.i15:\r\n return '15 MIN'\r\n case TIMEFRAME.i30:\r\n return '30 MIN'\r\n case TIMEFRAME.h:\r\n return '1 HR'\r\n case TIMEFRAME.h2:\r\n return '2 HR'\r\n case TIMEFRAME.h4:\r\n return '4 HR'\r\n case TIMEFRAME.d:\r\n return 'DAILY'\r\n case TIMEFRAME.w:\r\n return 'WEEKLY'\r\n case TIMEFRAME.m:\r\n return 'MONTHLY'\r\n default:\r\n return ''\r\n }\r\n}\r\n\r\nexport type ChartsPageQueryParams = {\r\n p: string\r\n t: string\r\n l: string\r\n r?: string\r\n i?: string\r\n sidebar?: string\r\n}\r\n\r\nexport type QuotePageQueryParams = {\r\n p?: string\r\n t: string\r\n r?: string\r\n i?: string\r\n ty?: QuotePageQueryChartTypes\r\n}\r\n\r\nexport enum QuotePageQueryChartTypes {\r\n l = 'l',\r\n c = 'c',\r\n cs = 'cs',\r\n hc = 'hc',\r\n ha = 'ha',\r\n o = 'o',\r\n p = 'p',\r\n}\r\n\r\nexport type ChartsOrQuotePageQueryParams = ChartsPageQueryParams | QuotePageQueryParams\r\n\r\nexport enum MacroTimeframe {\r\n // seconds = 'seconds',\r\n minutes = 'minutes',\r\n hours = 'hours',\r\n days = 'days',\r\n weeks = 'weeks',\r\n months = 'months',\r\n}\r\n\r\nexport const MicroMacroTimeframe = {\r\n [TIMEFRAME.i1]: {\r\n micro: 1,\r\n macro: MacroTimeframe.minutes,\r\n },\r\n [TIMEFRAME.i2]: {\r\n micro: 2,\r\n macro: MacroTimeframe.minutes,\r\n },\r\n [TIMEFRAME.i3]: {\r\n micro: 3,\r\n macro: MacroTimeframe.minutes,\r\n },\r\n [TIMEFRAME.i5]: {\r\n micro: 5,\r\n macro: MacroTimeframe.minutes,\r\n },\r\n [TIMEFRAME.i10]: {\r\n micro: 10,\r\n macro: MacroTimeframe.minutes,\r\n },\r\n [TIMEFRAME.i15]: {\r\n micro: 15,\r\n macro: MacroTimeframe.minutes,\r\n },\r\n [TIMEFRAME.i30]: {\r\n micro: 30,\r\n macro: MacroTimeframe.minutes,\r\n },\r\n [TIMEFRAME.h]: {\r\n micro: 1,\r\n macro: MacroTimeframe.hours,\r\n },\r\n [TIMEFRAME.h2]: {\r\n micro: 2,\r\n macro: MacroTimeframe.hours,\r\n },\r\n [TIMEFRAME.h4]: {\r\n micro: 4,\r\n macro: MacroTimeframe.hours,\r\n },\r\n [TIMEFRAME.d]: {\r\n micro: 1,\r\n macro: MacroTimeframe.days,\r\n },\r\n [TIMEFRAME.w]: {\r\n micro: 1,\r\n macro: MacroTimeframe.weeks,\r\n },\r\n [TIMEFRAME.m]: {\r\n micro: 1,\r\n macro: MacroTimeframe.months,\r\n },\r\n}\r\n\r\nexport const MicroTimeframeRange = (Object.keys(MicroMacroTimeframe) as TIMEFRAME[]).reduce(\r\n (prev, curr) => ({\r\n ...prev,\r\n [MicroMacroTimeframe[curr].macro]: prev[MicroMacroTimeframe[curr].macro]\r\n ? [...prev[MicroMacroTimeframe[curr].macro], MicroMacroTimeframe[curr].micro]\r\n : [MicroMacroTimeframe[curr].micro],\r\n }),\r\n {} as { [key in MacroTimeframe]: number[] }\r\n)\r\n\r\ntype IRange = {\r\n from?: number\r\n to?: number\r\n}\r\n\r\nexport type IVisibility = {\r\n [key in MacroTimeframe]?: IRange\r\n}\r\n\r\nexport enum SetVisibilityTo {\r\n currentAndAbove,\r\n currentAndBelow,\r\n currentOnly,\r\n all,\r\n}\r\n\r\nexport const QUOTE_FETCH_EVENT = 'quoteFetchEvent'\r\n\r\n// Keep in sync with the clone in Website repo in shared/is-stock-fast-refresh-available.ts\r\nexport const PREMARKET_AFTERMARKET_HOURS = 2.5\r\n\r\nexport const CHART_ELEMENT_ID = 'chart'\r\n\r\nexport const CHART_SETTINGS_DIALOG_TEST_ID = 'chart-settings-dialog'\r\n","import { ChartConfigChartPane } from '../../../types/shared'\r\nimport { IndicatorType } from '../../constants/common'\r\nimport ChartLayout from '../../models/chart_layout'\r\nimport Element from '../../models/element'\r\nimport PaneModel from '../../models/pane'\r\nimport { HLC, compareHlc, incrementHlc, receiveHlc } from '../../utils/hlc'\r\nimport {\r\n AutoSaveChangeType,\r\n AutoSaveElement,\r\n AutoSaveElementDBRecord,\r\n DrawingChangeTimestamp,\r\n DrawingContainerType,\r\n} from './constants'\r\n\r\nexport function getContainerTypeFromPaneConfig(pane: ChartConfigChartPane) {\r\n const indicatorElement = pane.elements.find((el) => el.type.startsWith('indicators/'))\r\n if (indicatorElement) {\r\n return indicatorElement.type as DrawingContainerType\r\n }\r\n const chartElement = pane.elements.find((el) => el.type.startsWith('charts/'))\r\n if (chartElement) {\r\n return 'chart'\r\n }\r\n return null\r\n}\r\n\r\nexport function getContainerType(model: PaneModel) {\r\n const mainElement = model.mainElement()\r\n const indicatorType = mainElement?.instance?.type ?? null\r\n if (mainElement?.isIndicator() && indicatorType !== IndicatorType.None) {\r\n return indicatorType as DrawingContainerType\r\n }\r\n if (mainElement?.isChart()) {\r\n return 'chart'\r\n }\r\n return null\r\n}\r\n\r\nexport function updateInternalStoreWithChangedElement({\r\n element,\r\n changeType,\r\n currentInternalStore,\r\n lastUpdateTimestamp,\r\n}: {\r\n element: Element\r\n changeType: AutoSaveChangeType\r\n currentInternalStore: AutoSaveElement[]\r\n lastUpdateTimestamp: HLC\r\n}) {\r\n const paneModel = element.pane()\r\n const ticker = paneModel.getQuoteRawTicker()\r\n const containerType = getContainerType(paneModel)\r\n if (ticker && paneModel && containerType && (!element.destroyed || changeType === 'destroy')) {\r\n const instanceJson = element.instance.toAutosaveConfig()\r\n const newDrawing: AutoSaveElement = {\r\n elementId: element.elementId!,\r\n zIndex: element.zIndex,\r\n ticker,\r\n lastChange: lastUpdateTimestamp,\r\n changeType,\r\n containerType,\r\n elementAttrs: JSON.stringify(instanceJson),\r\n }\r\n\r\n const newInternalStore = [...currentInternalStore]\r\n const updateDrawingIndex = newInternalStore.findIndex(\r\n (drawingElement) => drawingElement.elementId === newDrawing.elementId\r\n )\r\n\r\n let shouldSyncAndSave = false\r\n if (updateDrawingIndex > -1) {\r\n const updatedRecord = newInternalStore[updateDrawingIndex]\r\n const hasChangedZIndex = updatedRecord.zIndex !== newDrawing.zIndex\r\n const hasChangedType = updatedRecord.changeType !== newDrawing.changeType\r\n const hasChangedAttrs = updatedRecord.elementAttrs !== newDrawing.elementAttrs\r\n const hasChange = hasChangedType || hasChangedAttrs || hasChangedZIndex\r\n if (\r\n !element.instance.isEditInProgress &&\r\n updatedRecord.ticker === ticker &&\r\n hasChange &&\r\n updatedRecord.changeType !== 'destroy'\r\n ) {\r\n newInternalStore[updateDrawingIndex] = newDrawing\r\n shouldSyncAndSave = true\r\n }\r\n } else {\r\n newInternalStore.push(newDrawing)\r\n shouldSyncAndSave = true\r\n }\r\n\r\n return {\r\n newInternalStore,\r\n shouldSyncAndSave,\r\n newDrawing,\r\n }\r\n }\r\n}\r\n\r\nexport function getTickersAndContainerTypesInLayoutModel(chartLayout: ChartLayout) {\r\n const tickers: string[] = []\r\n const containerTypes: Array = ['note']\r\n\r\n chartLayout.getAllPanes().forEach((paneModel) => {\r\n const ticker = paneModel.getQuoteRawTicker()\r\n const containerType = getContainerType(paneModel)\r\n if (ticker && !tickers.includes(ticker)) {\r\n tickers.push(ticker)\r\n }\r\n if (containerType && !containerTypes.includes(containerType)) {\r\n containerTypes.push(containerType)\r\n }\r\n })\r\n return { tickers, containerTypes }\r\n}\r\n\r\nexport function mergeUpdatedDrawingsToInternalStore({\r\n updatedDrawings,\r\n currentInternalStore,\r\n lastUpdateTimestamp,\r\n isRefetchAll,\r\n}: {\r\n updatedDrawings: AutoSaveElement[]\r\n currentInternalStore: AutoSaveElement[]\r\n lastUpdateTimestamp: DrawingChangeTimestamp\r\n isRefetchAll: boolean\r\n}) {\r\n let newLastUpdateTimestamp = lastUpdateTimestamp\r\n const newInternalStore = [...currentInternalStore]\r\n const updatedElementIds: string[] = []\r\n\r\n updatedDrawings.forEach((drawing) => {\r\n newLastUpdateTimestamp = receiveHlc(newLastUpdateTimestamp, drawing.lastChange)\r\n const drawingIndex = newInternalStore.findIndex(({ elementId }) => drawing.elementId === elementId)\r\n const currentDrawing = drawingIndex > -1 ? newInternalStore[drawingIndex] : null\r\n if (currentDrawing === null) {\r\n newInternalStore.push(drawing)\r\n updatedElementIds.push(drawing.elementId)\r\n } else if (currentDrawing.containerType === 'note' && isRefetchAll) {\r\n const currentNote = getElementNoteText(currentDrawing)\r\n const autoSavedNote = getElementNoteText(drawing)\r\n if (currentNote !== autoSavedNote) {\r\n newInternalStore[drawingIndex] = {\r\n ...drawing,\r\n lastChange: incrementHlc(receiveHlc(currentDrawing.lastChange, drawing.lastChange), Date.now()),\r\n elementAttrs: JSON.stringify({\r\n ...JSON.parse(drawing.elementAttrs),\r\n text: `${currentNote}\\r\\n${autoSavedNote}`,\r\n }),\r\n }\r\n }\r\n updatedElementIds.push(drawing.elementId)\r\n } else if (compareHlc(newInternalStore[drawingIndex].lastChange, drawing.lastChange) < 0) {\r\n newInternalStore[drawingIndex] = drawing\r\n updatedElementIds.push(drawing.elementId)\r\n }\r\n })\r\n return { newLastUpdateTimestamp, newInternalStore, updatedElementIds }\r\n}\r\n\r\nexport function getInitialStoreDrawings(): null | AutoSaveElement[] {\r\n const initialDrawings = (\r\n window.FinvizSettings?.initialDrawingsStore ?? window.FinvizChartsSettings?.initialDrawingsStore\r\n )?.drawings as null | AutoSaveElementDBRecord[]\r\n\r\n return initialDrawings?.map((item) => getAutosaveElementFromDBRecord(item)) ?? null\r\n}\r\n\r\nexport function handleCallMethodOnAllDrawings({\r\n chartLayoutModel,\r\n elementMethod,\r\n}: {\r\n chartLayoutModel: ChartLayout\r\n elementMethod: keyof Pick\r\n}) {\r\n chartLayoutModel.getAllElements().forEach((element) => {\r\n if (element.isDrawing()) {\r\n element[elementMethod]()\r\n }\r\n })\r\n}\r\n\r\nexport function getNoteElementId(ticker: string) {\r\n return `note-${ticker}`\r\n}\r\n\r\nexport function getElementNoteText(noteElement?: AutoSaveElement) {\r\n return (noteElement ? JSON.parse(noteElement.elementAttrs)?.text : '') ?? ''\r\n}\r\n\r\nexport function getTickerNoteText({ ticker, elements }: { ticker: string; elements: AutoSaveElement[] }) {\r\n const noteElement = elements.find(({ elementId }) => elementId === getNoteElementId(ticker))\r\n return getElementNoteText(noteElement)\r\n}\r\n\r\nexport function getAutosaveElementFromDBRecord(item: AutoSaveElementDBRecord): AutoSaveElement {\r\n return {\r\n elementId: item.elementId,\r\n ticker: item.ticker,\r\n zIndex: item.zIndex,\r\n changeType: item.changeType,\r\n containerType: item.containerType,\r\n elementAttrs: item.elementAttrs,\r\n lastChange: {\r\n ts: item.lastChangeTimestamp,\r\n count: item.lastChangeCounter,\r\n uuid: item.lastChangeNodeUUID,\r\n },\r\n }\r\n}\r\n\r\nexport function getDBRecordFromAutosaveElement(item: AutoSaveElement): Omit {\r\n return {\r\n elementId: item.elementId,\r\n ticker: item.ticker,\r\n zIndex: item.zIndex,\r\n changeType: item.changeType,\r\n containerType: item.containerType,\r\n elementAttrs: JSON.stringify(item.elementAttrs),\r\n lastChangeTimestamp: item.lastChange.ts,\r\n lastChangeCounter: item.lastChange.count,\r\n lastChangeNodeUUID: item.lastChange.uuid,\r\n }\r\n}\r\n","import {\r\n Button,\r\n ButtonComponentProps,\r\n ConfirmationDialog,\r\n Delayed,\r\n DialogDismiss,\r\n Popover,\r\n PopoverPlacement,\r\n PopoverRounding,\r\n PopoverStateReturn,\r\n PopoverTheme,\r\n PopoverTrigger,\r\n Spinner,\r\n ZIndexContext,\r\n usePopoverState,\r\n} from '@finviz/website'\r\nimport classNames from 'classnames'\r\nimport React from 'react'\r\n\r\nimport { CHART_ELEMENT_ID, CHART_SETTINGS_DIALOG_TEST_ID, SpecificChartFunctionality } from '../../constants/common'\r\nimport ChartLayout from '../../models/chart_layout'\r\nimport { useAsyncModule } from '../../utils/async-modules-utils'\r\nimport { encodeQueryString } from '../../utils/query_string'\r\nimport { useChartLayoutGlobalModelAsync } from '../../utils/useChartLayoutGlobalModelAsync'\r\nimport { chartSettingsAsyncModule } from '../chart-settings/async-modules'\r\n\r\nconst utmCampaign: Partial> = {\r\n [SpecificChartFunctionality.quotePage]: 'quote-settings-button',\r\n [SpecificChartFunctionality.futuresPage]: 'futures-settings-button',\r\n [SpecificChartFunctionality.forexPage]: 'forex-settings-button',\r\n [SpecificChartFunctionality.cryptoPage]: 'crypto-settings-button',\r\n}\r\n\r\ninterface ScrollableChartSettingsPopoverProps {\r\n isOpen: boolean\r\n state: PopoverStateReturn\r\n}\r\n\r\nexport function PopoverInner({ hidePopover }: { hidePopover: () => void }) {\r\n const [chartSettingsModule] = useAsyncModule({\r\n ...chartSettingsAsyncModule,\r\n isSuspenseMode: true,\r\n errorSeverity: 'medium',\r\n onError: () => hidePopover(),\r\n })\r\n\r\n const { ChartSettings } = chartSettingsModule ?? {}\r\n\r\n return \r\n}\r\n\r\nexport const ScrollableChartSettingsPopover = React.memo(function ScrollableChartSettingsPopover({\r\n state,\r\n isOpen,\r\n}: ScrollableChartSettingsPopoverProps) {\r\n const { forceGlobalRerender, getIsConfigChanged, chartLayoutModel } = useChartLayoutGlobalModelAsync()\r\n const confirmationDialogState = usePopoverState()\r\n const hidePopover = state.hide\r\n\r\n const checkChangesAndOpenDiscard = React.useCallback(\r\n (ev: Event | React.MouseEvent) => {\r\n if (getIsConfigChanged()) {\r\n ev.preventDefault()\r\n confirmationDialogState.show()\r\n return\r\n }\r\n hidePopover()\r\n },\r\n [confirmationDialogState, getIsConfigChanged, hidePopover]\r\n )\r\n\r\n const discardChangesAndHide = React.useCallback(() => {\r\n forceGlobalRerender()\r\n // We need to defer the hide so that the rerender finishes first\r\n setTimeout(hidePopover)\r\n }, [forceGlobalRerender, hidePopover])\r\n\r\n const buttonPosition = React.useMemo(() => {\r\n const popoverContentElement = state.getState().disclosureElement\r\n const { top = 0, height = 32 } = popoverContentElement?.getBoundingClientRect() ?? {}\r\n return top + height + window.scrollY\r\n // Only recount on open\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n }, [isOpen])\r\n\r\n const chartHeight = React.useMemo(() => {\r\n const chartElement = document.getElementById(CHART_ELEMENT_ID)\r\n return chartElement?.clientHeight ?? 0\r\n // Only recount on open\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n }, [isOpen])\r\n\r\n return (\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n }\r\n >\r\n \r\n \r\n \r\n \r\n \r\n\r\n \r\n \r\n \r\n Discard changes\r\n \r\n \r\n }\r\n >\r\n Are you sure you want to discard changes?\r\n \r\n \r\n )\r\n})\r\n\r\ninterface ChartSettingsButtonProps extends ButtonComponentProps {\r\n isPremium: boolean\r\n placement?: PopoverPlacement\r\n model: ChartLayout\r\n}\r\n\r\nexport function ChartSettingsButton({\r\n isPremium,\r\n model,\r\n placement,\r\n ...props\r\n}: React.PropsWithChildren) {\r\n const settingsPopoverState = usePopoverState({ placement: placement ?? 'bottom' })\r\n const isOpen = settingsPopoverState.useState('open')\r\n\r\n const buttonProps = React.useMemo(() => {\r\n if (model.specificChartFunctionality !== SpecificChartFunctionality.quotePage && !isPremium) {\r\n return {\r\n as: 'a',\r\n href: `/elite.ashx?${encodeQueryString({\r\n utm_source: 'finviz',\r\n utm_medium: 'banner',\r\n utm_campaign: utmCampaign[model.specificChartFunctionality],\r\n })}`,\r\n } as ButtonComponentProps<'a'>\r\n }\r\n\r\n return {\r\n as: PopoverTrigger,\r\n state: settingsPopoverState,\r\n active: isOpen,\r\n } as ButtonComponentProps\r\n }, [model.specificChartFunctionality, isPremium, settingsPopoverState, isOpen])\r\n\r\n return (\r\n <>\r\n \r\n \r\n \r\n )\r\n}\r\n","import * as React from 'react'\r\nimport { useLocation, useNavigate } from 'react-router-dom'\r\n\r\nimport { ChartsOrQuotePageQueryParams, SpecificChartFunctionality } from '../../constants/common'\r\nimport { useModelState } from '../../model-hooks/use-model-state'\r\nimport { useModelRef } from '../../model-hooks/useModelRef'\r\nimport Chart from '../../models/chart'\r\nimport Quote from '../../models/quote'\r\nimport { QuoteFetchType } from '../../models/quote/constants'\r\nimport { createRequestAbortController, removeFromAbortCache } from '../../utils/abort_controller'\r\nimport { decodeQueryString, encodeQueryString } from '../../utils/query_string'\r\nimport { getLeftOffset } from '../renderUtils'\r\n\r\nconst getQuoteRequestKey = (chartModel: Chart) =>\r\n `quoteReq-${chartModel.ticker}-${chartModel.instrument}-${chartModel.id}`\r\n\r\nexport function useChartControls({\r\n chartModel: unwatchedChartModel,\r\n isInteractive,\r\n}: {\r\n chartModel: Chart | null\r\n isInteractive: boolean\r\n}) {\r\n const location = useLocation()\r\n const navigate = useNavigate()\r\n const chartModel = useModelState(unwatchedChartModel, {\r\n watchProperties: ['ticker', 'timeframe', 'dateRange'],\r\n })\r\n const chartLayoutModel = useModelState(chartModel?.chart_layout() ?? null, {\r\n watchProperties: ['idea', 'settings'],\r\n })\r\n const chartModelRef = useModelRef(chartModel)\r\n const [isLoading, setIsLoading] = React.useState(false)\r\n const abortControllerKeyRef = React.useRef('')\r\n const isIdeaChart = !!chartLayoutModel?.idea?.id\r\n\r\n const updateChartModelWithNewQuote = React.useCallback((quote: Quote) => {\r\n const chart = chartModelRef.current\r\n if (!chart) {\r\n return\r\n }\r\n\r\n const chartLayoutModel = chart.chart_layout()\r\n const isSameTicker = chart.getQuoteRawTicker() === quote.getRawTicker()\r\n\r\n chart.getAllPanes().forEach((pane) => {\r\n if (!!pane.getChartOrIndicatorElement()) {\r\n pane.updateAttribute('scaleRange', null)\r\n }\r\n })\r\n\r\n chart.updateAttributes({ leftOffset: getLeftOffset({ quote, chartModel: chart }), quote, isScrolled: true })\r\n\r\n // Refetch all other chart quotes as the main one is already refetched so we can filter it out but other quotes (from perf for example) should be refetched as well\r\n chart\r\n .getAllQuotes()\r\n .filter((chartQuote) => !chartQuote.eql(quote))\r\n .forEach((quote) => {\r\n quote.fetchData({ fetchType: QuoteFetchType.NewerData })\r\n })\r\n\r\n const chartPane = chart.getChartPane()\r\n chartLayoutModel.activeChartEvent?.instance.toggleIsOpen(false)\r\n\r\n const elements = [...chart.getAllElements(), ...(chartPane?.getAllChartEvents(false) ?? [])]\r\n for (const element of elements) {\r\n const isDrawing = element.isDrawing()\r\n const isChartEvent = element.isChartEvent()\r\n if (isDrawing || isChartEvent) {\r\n // We want to remove all drawings on ticker change but if autosave is enabled we let the autosave hook take care of that\r\n if (isSameTicker && (isChartEvent || chartLayoutModel.isPreserveDrawingsActive)) {\r\n element.instance.updateScales()\r\n } else {\r\n element.destroyCascade()\r\n }\r\n }\r\n }\r\n\r\n chart.setChartEvents(quote.chartEvents, true)\r\n\r\n chartPane?.updateChartEventsZIndexes()\r\n\r\n // The only dependency here is a ref , so no need to add it to dependencies\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n }, [])\r\n\r\n const fetchQuote = React.useCallback(async () => {\r\n if (!isInteractive || !chartModel || isIdeaChart) {\r\n return\r\n }\r\n\r\n const { ticker, instrument, timeframe, hasChartEvents } = chartModel\r\n const { premarket, aftermarket } = Quote.first()\r\n const patterns = chartModel.getHasPatterns()\r\n const currentQuote = chartModel.quote()\r\n if (currentQuote.getRawTicker() !== ticker || currentQuote.timeframe !== timeframe) {\r\n setIsLoading(true)\r\n abortControllerKeyRef.current = getQuoteRequestKey(chartModel)\r\n const abortController = createRequestAbortController({\r\n key: abortControllerKeyRef.current,\r\n shouldAbortRunningRequest: !Quote.select(\r\n (quote) =>\r\n quote.ticker === ticker &&\r\n quote.timeframe === timeframe &&\r\n quote.isFetching &&\r\n chartModel.chart_layout().isIdeaId(quote.ideaID)\r\n ),\r\n })\r\n\r\n const quote = await Quote.get({\r\n ticker,\r\n instrument,\r\n timeframe,\r\n options: {\r\n premarket,\r\n aftermarket,\r\n events: hasChartEvents,\r\n financialAttachments: chartModel.getQuoteFinancialAttachments(),\r\n patterns,\r\n cachePredicate: (quote) => quote.ideaID === undefined,\r\n fetchNewDataOnCachedQuote: true,\r\n },\r\n abortController,\r\n })\r\n\r\n if (quote.wasFetchAborted) {\r\n // Check if the quote is also used in other chars, as the quote may be reused if we already have a quote with the same options\r\n const isQuoteUsedInOtherCharts = chartModel\r\n .chart_layout()\r\n .getAllCharts()\r\n .filter((chart) => !chartModel.eql(chart))\r\n .some((chart) => quote.eql(chart.quote()))\r\n\r\n // If the quote hasn't been fetched yet and is not anywhere else we can destroy the model\r\n if (quote.fetchedAt === -1 && !isQuoteUsedInOtherCharts) {\r\n quote.destroy()\r\n }\r\n } else if (quote.timeframe === chartModel.timeframe && quote.getRawTicker() === chartModel.ticker) {\r\n removeFromAbortCache(abortControllerKeyRef.current)\r\n updateChartModelWithNewQuote(quote)\r\n setIsLoading(false)\r\n }\r\n }\r\n\r\n // We don't want to create new function on any chartModel change as it may be the same chart with different object instance\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n }, [\r\n chartModel?.id,\r\n chartModel?.ticker,\r\n chartModel?.timeframe,\r\n chartModel?.instrument,\r\n isIdeaChart,\r\n updateChartModelWithNewQuote,\r\n isInteractive,\r\n ])\r\n\r\n React.useEffect(() => {\r\n fetchQuote()\r\n }, [fetchQuote])\r\n\r\n // There are several ways how to turn off dateRange, e.g. moving the charts\r\n // This effect listens to dateRange changes on chartmodel and updates the url if there's a change\r\n // Consider refactoring this part so we only update chart models on route changes not the other way around\r\n React.useEffect(() => {\r\n if (chartModel) {\r\n const decodedQueryString = decodeQueryString(location.search)\r\n const rangesArray = chartModel\r\n .chart_layout()\r\n .getAllCharts()\r\n .map((chart) => chart.dateRange)\r\n const ranges = rangesArray.every((i) => !i) ? undefined : rangesArray.join(',')\r\n\r\n if (decodedQueryString.r !== ranges) {\r\n navigate({\r\n search: `?${encodeQueryString({\r\n ...decodedQueryString,\r\n r: ranges,\r\n })}`,\r\n })\r\n }\r\n }\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n }, [chartModel?.dateRange])\r\n\r\n // https://github.com/finvizhq/charts/pull/1253/files#r1052266805\r\n // React.useEffect(\r\n // () => () => {\r\n // if (isInteractive && abortControllerKeyRef.current !== '') {\r\n // abortRequest(abortControllerKeyRef.current)\r\n // }\r\n // },\r\n // [isInteractive]\r\n // )\r\n\r\n React.useEffect(() => {\r\n const chart = chartModelRef.current\r\n const quote = chart?.quote()\r\n\r\n let shouldRecalculateOnCharts = false\r\n if (chartLayoutModel?.specificChartFunctionality === SpecificChartFunctionality.chartPage && !isIdeaChart) {\r\n const settings = chartLayoutModel?.settings\r\n const barWidth = 3\r\n const barMargin = 1\r\n if (settings) {\r\n const hasSameBarWidth = [\r\n settings.ChartSettings.center.barWidth,\r\n settings.IndicatorSettings.center.barWidth,\r\n ].every((value) => value === barWidth)\r\n const hasSameBarMargin = [\r\n settings.ChartSettings.center.barMargin,\r\n settings.IndicatorSettings.center.barMargin,\r\n ].every((value) => value === barMargin)\r\n\r\n shouldRecalculateOnCharts = !hasSameBarWidth || !hasSameBarMargin\r\n if (shouldRecalculateOnCharts) {\r\n settings.ChartSettings.center.barWidth = barWidth\r\n settings.IndicatorSettings.center.barWidth = barWidth\r\n settings.ChartSettings.center.barMargin = barMargin\r\n settings.IndicatorSettings.center.barMargin = barMargin\r\n\r\n chartLayoutModel.updateAttributes({ settings })\r\n }\r\n }\r\n }\r\n\r\n if (\r\n chart &&\r\n quote &&\r\n (chartLayoutModel?.specificChartFunctionality === SpecificChartFunctionality.quotePage ||\r\n shouldRecalculateOnCharts) &&\r\n !isIdeaChart\r\n ) {\r\n const leftOffset = getLeftOffset({ quote, chartModel: chart })\r\n chart.updateAttributes({ leftOffset })\r\n }\r\n // This effect should run only on timeframe change & idea change\r\n // The reason we need to recalculate the left offset is that quote timeframe change changes chart and chart bars sizes\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n }, [chartModel?.quote()?.timeframe, chartLayoutModel?.settings, isIdeaChart])\r\n\r\n return { isLoading }\r\n}\r\n","import Spine from '@finviz/spine'\r\nimport * as React from 'react'\r\n\r\nexport function useModelRef(model: Model | null) {\r\n const modelRef = React.useRef(model)\r\n\r\n React.useEffect(() => {\r\n modelRef.current = model\r\n }, [model])\r\n\r\n return modelRef\r\n}\r\n","import {\r\n Notification,\r\n Paragraph,\r\n generatePathForTimeframeDateRange,\r\n getDateRangeGroupsWithHref,\r\n timeframeUtm,\r\n useNotification,\r\n} from '@finviz/website'\r\nimport React from 'react'\r\nimport { useLocation } from 'react-router-dom'\r\n\r\nimport { Instrument } from '../../../types/shared'\r\nimport { SpecificChartFunctionality, TIMEFRAME, TimeframeAndIntradayType } from '../../constants/common'\r\nimport Chart from '../../models/chart'\r\nimport Quote from '../../models/quote'\r\nimport { dateFromUnixTimestamp } from '../../utils'\r\nimport { getChartStartEndDates, getVisibleBarsNumber } from '../renderUtils'\r\nimport { useChartsPathLocation } from './use-charts-path-location'\r\nimport { getTimeframeGroupsWithHref } from './utils'\r\n\r\ninterface IPathForTimeframeDateRangeProps {\r\n timeframe: TimeframeAndIntradayType\r\n dateRange?: string | null\r\n ticker?: string\r\n}\r\n\r\nexport interface IDateRange {\r\n value: string\r\n timeframe: TIMEFRAME\r\n}\r\n\r\nexport function useChartModelCustomDateRangeValues({\r\n chartModel,\r\n isPremium,\r\n}: {\r\n chartModel: Chart | null\r\n isPremium: boolean\r\n}) {\r\n const notificationContext = useNotification()\r\n const location = useLocation()\r\n const [isFetching, setIsFetching] = React.useState(false)\r\n const chartLayoutModel = chartModel?.chart_layout() || null\r\n const chartIndex = chartLayoutModel?.getAllCharts().findIndex((chart) => chartModel!.eql(chart)) ?? -1\r\n const { getChartsToPath } = useChartsPathLocation({ chartLayoutModel, chartIndex })\r\n const specificChartFunctionality = chartLayoutModel?.specificChartFunctionality ?? SpecificChartFunctionality.default\r\n\r\n const anchorDate = React.useMemo(() => {\r\n if (!chartModel) return new Date()\r\n const quote = chartModel.quote()\r\n return dateFromUnixTimestamp(quote.date[quote.date.length - 1])\r\n }, [chartModel])\r\n\r\n const generateChartLayoutRouterPath = React.useCallback(\r\n ({ ticker, timeframe, dateRange }: IPathForTimeframeDateRangeProps) => {\r\n if (specificChartFunctionality === SpecificChartFunctionality.chartPage) {\r\n return getChartsToPath({\r\n ticker: ticker,\r\n timeframe: timeframe as TIMEFRAME,\r\n dateRange: dateRange,\r\n })\r\n }\r\n\r\n return generatePathForTimeframeDateRange({\r\n isPremium,\r\n pathname: location.pathname,\r\n timeframe: timeframe,\r\n dateRange: dateRange,\r\n utmCampaign: timeframeUtm[specificChartFunctionality],\r\n })\r\n },\r\n [getChartsToPath, isPremium, specificChartFunctionality, location.pathname]\r\n )\r\n\r\n const timeframeGroupsWithHref = (isPremium: boolean) =>\r\n getTimeframeGroupsWithHref({\r\n isPremium,\r\n generatePath: (timeFrame) => generateChartLayoutRouterPath({ timeframe: timeFrame.value, dateRange: null }),\r\n })\r\n\r\n const dateRangeGroupsWithHref = ({\r\n isPremium,\r\n customRange,\r\n instrument,\r\n }: {\r\n isPremium: boolean\r\n customRange?: string\r\n instrument: Instrument\r\n }) =>\r\n getDateRangeGroupsWithHref({\r\n isPremium,\r\n customRange,\r\n instrument,\r\n generatePath: (dateRange: { timeframe?: TIMEFRAME; value: string }) =>\r\n generateChartLayoutRouterPath({ timeframe: dateRange.timeframe!, dateRange: dateRange.value }),\r\n })\r\n\r\n const handleCustomDateRangeValidation = async (dateRangeState: { value: string | null; timeframe: TIMEFRAME }) => {\r\n if (dateRangeState.value !== null) {\r\n const { timeframe, ticker, instrument, premarket, aftermarket } = chartModel?.quote() || {}\r\n const patterns = !!chartModel?.getHasPatterns()\r\n if (!anchorDate || !instrument || !ticker || !timeframe || !dateRangeState.value) return false\r\n setIsFetching(true)\r\n const quote = await Quote.get({\r\n ticker,\r\n instrument,\r\n timeframe: dateRangeState.timeframe,\r\n options: {\r\n premarket,\r\n aftermarket,\r\n patterns,\r\n cachePredicate: (quote) => quote.ideaID === undefined,\r\n fetchNewDataOnCachedQuote: true,\r\n },\r\n })\r\n setIsFetching(false)\r\n\r\n const { numOfVisibleBars } = getVisibleBarsNumber({\r\n ...getChartStartEndDates({ dateRange: dateRangeState.value, quote }),\r\n quote,\r\n dateRange: dateRangeState.value,\r\n })\r\n if (numOfVisibleBars === 0) {\r\n notificationContext.show(\r\n } timeoutInMs={6000}>\r\n \r\n There are no data for the selected date range. Try selecting different dates.\r\n \r\n \r\n )\r\n\r\n return false\r\n }\r\n }\r\n return true\r\n }\r\n\r\n return {\r\n anchorDate,\r\n generateChartLayoutRouterPath,\r\n timeframeGroupsWithHref,\r\n dateRangeGroupsWithHref,\r\n isFetching,\r\n handleCustomDateRangeValidation,\r\n }\r\n}\r\n","import * as React from 'react'\r\nimport { useLocation } from 'react-router-dom'\r\n\r\nimport { ChartsPageQueryParams, LAYOUTS, LayoutType, TIMEFRAME } from '../../constants/common'\r\nimport { useModelState } from '../../model-hooks/use-model-state'\r\nimport { ChartSyncablePart } from '../../models/chart/contstants'\r\nimport ChartLayout from '../../models/chart_layout'\r\nimport { getIsMobilePortrait } from '../../utils'\r\nimport { decodeQueryString, encodeQueryString } from '../../utils/query_string'\r\n\r\nexport function useChartsPathLocation({\r\n chartLayoutModel: unwatchedChartLayoutModel,\r\n chartIndex = -1,\r\n}: {\r\n chartLayoutModel: ChartLayout | null\r\n chartIndex?: number\r\n}) {\r\n const location = useLocation()\r\n const chartLayoutModel = useModelState(unwatchedChartLayoutModel, {\r\n watchProperties: ['syncChartParts'],\r\n })\r\n const hasSyncedTimeframe = React.useMemo(\r\n () => !!chartLayoutModel?.getIsChartPartInSync(ChartSyncablePart.Timeframe),\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n [chartLayoutModel?.syncChartParts]\r\n )\r\n const hasSyncedTicker = React.useMemo(\r\n () => !!chartLayoutModel?.getIsChartPartInSync(ChartSyncablePart.Ticker),\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n [chartLayoutModel?.syncChartParts]\r\n )\r\n\r\n const getChartsToPath = React.useCallback(\r\n ({\r\n ticker,\r\n timeframe,\r\n dateRange,\r\n layout,\r\n }: {\r\n timeframe?: TIMEFRAME\r\n dateRange?: string | null\r\n ticker?: string\r\n layout?: LayoutType\r\n }) => {\r\n if (!chartLayoutModel) {\r\n return {\r\n pathname: location.pathname,\r\n search: '',\r\n }\r\n }\r\n\r\n const decodedSearch = decodeQueryString(location.search)\r\n const { count } = LAYOUTS[(layout ?? chartLayoutModel.layout) as LayoutType]\r\n const urlTickers = decodedSearch.t?.split(',') ?? []\r\n const urlTimeframes = decodedSearch.p?.split(',') ?? []\r\n const urlDateRanges = decodedSearch.r?.split(',')\r\n\r\n const chartsArrayPlaceholder = Array.from({ length: count })\r\n const tickers = chartsArrayPlaceholder\r\n .map((_, index) => {\r\n const currentTicker = urlTickers[index] ?? urlTickers[urlTickers.length - 1]\r\n return (chartIndex === index || hasSyncedTicker) && ticker ? ticker : currentTicker\r\n })\r\n .join(',')\r\n const timeframes = chartsArrayPlaceholder\r\n .map((_, index) => {\r\n const currentTimeframe = urlTimeframes[index] ?? urlTimeframes[urlTimeframes.length - 1]\r\n return (chartIndex === index || hasSyncedTimeframe) && timeframe ? timeframe : currentTimeframe\r\n })\r\n .join(',')\r\n const ranges = chartsArrayPlaceholder\r\n .map((_, index) => {\r\n const currentDaterange = urlDateRanges\r\n ? (urlDateRanges[index] ?? urlDateRanges[urlDateRanges.length - 1])\r\n : undefined\r\n return (chartIndex === index || hasSyncedTimeframe) && dateRange !== undefined ? dateRange : currentDaterange\r\n })\r\n .join(',')\r\n\r\n return {\r\n pathname: location.pathname,\r\n search: `?${encodeQueryString({\r\n t: tickers,\r\n p: timeframes,\r\n r: ranges.split(',').some(Boolean) ? ranges : undefined,\r\n l: layout ?? chartLayoutModel.layout,\r\n sidebar: getIsMobilePortrait() ? undefined : decodedSearch.sidebar,\r\n })}`,\r\n }\r\n },\r\n [chartLayoutModel, chartIndex, location, hasSyncedTicker, hasSyncedTimeframe]\r\n )\r\n\r\n return { getChartsToPath }\r\n}\r\n","import { IconNameType, getTimeframeGroups } from '@finviz/website'\r\nimport { type To } from 'react-router-dom'\r\n\r\nimport { TimeframeAndIntradayType } from '../../constants/common'\r\n\r\ninterface ITimeFrame {\r\n value: TimeframeAndIntradayType\r\n label: string\r\n labelShort: string\r\n labelPageTitle?: string\r\n}\r\n\r\ninterface ITimeframeGroup {\r\n label: string\r\n timeframes: ITimeFrame[]\r\n}\r\n\r\nexport function getTimeframeGroupsWithHref({\r\n isPremium,\r\n generatePath,\r\n}: {\r\n isPremium: boolean\r\n generatePath: (timeframe: ITimeFrame) => To\r\n}) {\r\n return getTimeframeGroups(isPremium).map((timeFrameGroup: ITimeframeGroup) => ({\r\n label: timeFrameGroup.label,\r\n timeframes: timeFrameGroup.timeframes.map((timeFrame) => ({\r\n ...timeFrame,\r\n href: generatePath(timeFrame),\r\n })),\r\n }))\r\n}\r\n\r\nexport enum QuoteNodeChartTypes {\r\n candlesticksimple = 'candlesticksimple',\r\n candlestick = 'candlestick',\r\n line = 'line',\r\n ohlc = 'ohlc',\r\n heikinashi = 'heikinashi',\r\n hollowcandlestick = 'hollowcandlestick',\r\n}\r\n\r\nexport enum QuoteUrlChartTypes {\r\n cs = 'cs',\r\n c = 'c',\r\n l = 'l',\r\n o = 'o',\r\n ha = 'ha',\r\n hc = 'hc',\r\n}\r\n\r\nexport const QuoteShortToLongType = {\r\n [QuoteUrlChartTypes.cs]: QuoteNodeChartTypes.candlesticksimple,\r\n [QuoteUrlChartTypes.c]: QuoteNodeChartTypes.candlestick,\r\n [QuoteUrlChartTypes.l]: QuoteNodeChartTypes.line,\r\n [QuoteUrlChartTypes.o]: QuoteNodeChartTypes.ohlc,\r\n [QuoteUrlChartTypes.ha]: QuoteNodeChartTypes.heikinashi,\r\n [QuoteUrlChartTypes.hc]: QuoteNodeChartTypes.hollowcandlestick,\r\n} as const\r\n\r\nexport const QuoteLongToShortType = {\r\n [QuoteNodeChartTypes.candlesticksimple]: QuoteUrlChartTypes.cs,\r\n [QuoteNodeChartTypes.candlestick]: QuoteUrlChartTypes.c,\r\n [QuoteNodeChartTypes.line]: QuoteUrlChartTypes.l,\r\n [QuoteNodeChartTypes.ohlc]: QuoteUrlChartTypes.o,\r\n [QuoteNodeChartTypes.heikinashi]: QuoteUrlChartTypes.ha,\r\n [QuoteNodeChartTypes.hollowcandlestick]: QuoteUrlChartTypes.hc,\r\n} as const\r\n\r\nexport type TypeBaseOption = {\r\n label: string\r\n value: QuoteNodeChartTypes\r\n icon: IconNameType\r\n href?: string\r\n}\r\nexport const DEFAULT_TYPES: TypeBaseOption[] = [\r\n { icon: 'candleBarBasic', value: QuoteNodeChartTypes.candlestick, label: 'Candle' },\r\n { icon: 'lineChartType', value: QuoteNodeChartTypes.line, label: 'Line' },\r\n { icon: 'ohlcChartType', value: QuoteNodeChartTypes.ohlc, label: 'OHLC' },\r\n { icon: 'candleBarHollow', value: QuoteNodeChartTypes.hollowcandlestick, label: 'Hollow Candle' },\r\n { icon: 'candleBarHeikinAshi', value: QuoteNodeChartTypes.heikinashi, label: 'Heikin Ashi' },\r\n]\r\n\r\nexport const FREE_TYPES_QUOTE: TypeBaseOption[] = [\r\n { icon: 'candleBarBasic', value: QuoteNodeChartTypes.candlesticksimple, label: 'Candle - simple' },\r\n { icon: 'candleBarBasic', value: QuoteNodeChartTypes.candlestick, label: 'Candle - advanced' },\r\n // Filter out the candle from DEFAULT_TYPES, we’re naming it differently\r\n ...DEFAULT_TYPES.filter((type) => type.value !== QuoteNodeChartTypes.candlestick),\r\n]\r\n\r\nexport const FREE_TYPES_QUOTE_VALUES = ['candlesticksimple', 'candlestick', 'line']\r\n","export const chartEventsAsyncModule = {\r\n importFn: () => import(/* webpackChunkName: \"chart-events\" */ './module-entry'),\r\n cacheKey: 'chart-events',\r\n}\r\n","export const chartSettingsAsyncModule = {\r\n importFn: () => import(/* webpackChunkName: \"chart-settings\" */ './module-entry'),\r\n cacheKey: 'chart-settings',\r\n}\r\n\r\nexport const useChartLayoutGlobalModelAsyncModule = {\r\n importFn: () =>\r\n import(/* webpackChunkName: \"use-chart-layout-global-model\" */ './useChartLayoutGlobalModel/module-entry'),\r\n cacheKey: 'use-chart-layout-global-model',\r\n}\r\n\r\nexport const preventClosingUnsavedChangesAsyncModule = {\r\n importFn: () =>\r\n import(/* webpackChunkName: \"prevent-closing-unsaved-changes\" */ './PreventClosingUnsavedChanges/module-entry'),\r\n cacheKey: 'prevent-closing-unsaved-changes',\r\n}\r\n","import { InputColorPicker, convertColorToHEX } from '@finviz/website'\r\nimport * as React from 'react'\r\n\r\ninterface BackgroundInputProps {\r\n label: string\r\n value: string\r\n onChange: (color: string) => void\r\n}\r\n\r\nexport function BackgroundInput({ label = 'Background', value, onChange }: BackgroundInputProps) {\r\n return (\r\n \r\n )\r\n}\r\n","import { InputColorPicker, Paragraph, RangeSlider } from '@finviz/website'\r\nimport React, { useCallback } from 'react'\r\n\r\nimport { ObjectHash } from '../../types/shared'\r\n\r\ninterface ColorRangeRowInputProps {\r\n label: string\r\n colorValue: string\r\n colorTestId: string\r\n rangeValue: string\r\n rangeTestId: string\r\n rangeLabel: string\r\n rangeProps: ObjectHash\r\n onChange: (colorValue: string, value: string) => void\r\n}\r\n\r\nexport function ColorRangeRowInput({\r\n label,\r\n colorValue,\r\n colorTestId,\r\n rangeValue,\r\n rangeTestId,\r\n rangeLabel,\r\n rangeProps,\r\n onChange,\r\n}: ColorRangeRowInputProps) {\r\n const handleRangeChange = useCallback(\r\n (ev: React.ChangeEvent) => {\r\n const value = ev.currentTarget.value\r\n onChange(colorValue, value)\r\n },\r\n [onChange, colorValue]\r\n )\r\n const handleColorChange = useCallback(\r\n (color: string) => {\r\n onChange(color, rangeValue)\r\n },\r\n [onChange, rangeValue]\r\n )\r\n return (\r\n

\r\n
\r\n \r\n
\r\n
\r\n \r\n {rangeValue}\r\n \r\n }\r\n onChange={handleRangeChange}\r\n value={Number(rangeValue)}\r\n data-testid={rangeTestId}\r\n />\r\n
\r\n
\r\n )\r\n}\r\n","import { convertColorToHEX } from '@finviz/website'\r\nimport * as React from 'react'\r\n\r\nimport { ColorRangeRowInput } from './color_range_row'\r\n\r\ninterface Value {\r\n color: string\r\n width: string\r\n}\r\n\r\ninterface BorderInputProps {\r\n label: string\r\n value: Value\r\n min: number\r\n max: number\r\n onChange: (value: Value) => void\r\n}\r\n\r\nexport function BorderInput({ label = 'Border', value, onChange, min, max }: BorderInputProps) {\r\n return (\r\n onChange({ color, width })}\r\n />\r\n )\r\n}\r\n","import { Checkbox } from '@finviz/website'\r\nimport React from 'react'\r\n\r\ninterface CheckBoxProps {\r\n label: string\r\n value: boolean\r\n onChange: (isChecked: boolean) => void\r\n}\r\n\r\nexport function CheckBox({ label, value, onChange }: CheckBoxProps) {\r\n return (\r\n ) => onChange(ev.currentTarget.checked)}\r\n data-testid=\"chart-modal-checkbox\"\r\n >\r\n {label}\r\n \r\n )\r\n}\r\n","import { Checkbox, Input, Label, Select } from '@finviz/website'\r\nimport React, { useCallback, useState } from 'react'\r\n\r\nconst FONT_VALUES = [\r\n { value: 'Arial', label: 'Arial' },\r\n { value: 'Verdana', label: 'Verdana' },\r\n]\r\n\r\ninterface InputProps {\r\n family: string\r\n size: string\r\n style: 'italic' | 'normal'\r\n weight: 'bold' | 'normal'\r\n}\r\n\r\ninterface FontInputProps {\r\n value: InputProps\r\n onChange: (values: InputProps) => void\r\n}\r\n\r\nexport function FontInput({ value, onChange }: FontInputProps) {\r\n const [family, setFamily] = useState(value.family)\r\n const [size, setSize] = useState(value.size)\r\n const [style, setStyle] = useState(value.style)\r\n const [weight, setWeight] = useState(value.weight)\r\n\r\n const setValue = useCallback(\r\n function setValue(\r\n key: string,\r\n valueSetter: React.Dispatch>,\r\n value: ValueType\r\n ) {\r\n valueSetter(value)\r\n onChange({ family, size, style, weight, [key]: value })\r\n },\r\n [family, size, style, weight, onChange]\r\n )\r\n\r\n return (\r\n
\r\n
\r\n \r\n ) => setValue('size', setSize, ev.currentTarget.value)}\r\n value={size}\r\n data-testid=\"chart-modal-font-size\"\r\n />\r\n\r\n ) =>\r\n setValue('weight', setWeight, ev.currentTarget.checked ? 'bold' : 'normal')\r\n }\r\n data-testid=\"chart-modal-font-weight\"\r\n >\r\n Bold\r\n \r\n ) =>\r\n setValue('style', setStyle, ev.currentTarget.checked ? 'italic' : 'normal')\r\n }\r\n data-testid=\"chart-modal-font-style\"\r\n >\r\n Italic\r\n \r\n
\r\n
\r\n )\r\n}\r\n","import { convertColorToHEX } from '@finviz/website'\r\nimport * as React from 'react'\r\n\r\nimport { ColorRangeRowInput } from './color_range_row'\r\n\r\ninterface LineInputValue {\r\n color: string\r\n width: string\r\n}\r\n\r\ninterface LineInputProps {\r\n label: string\r\n value: LineInputValue\r\n onChange: (value: LineInputValue) => void\r\n}\r\n\r\nexport function LineInput({ label = 'Line', value, onChange }: LineInputProps) {\r\n return (\r\n onChange({ color, width })}\r\n />\r\n )\r\n}\r\n","import { Textarea } from '@finviz/website'\r\nimport React from 'react'\r\n\r\ninterface MultilineStringInputProps {\r\n label: string\r\n value: string\r\n required: boolean\r\n onChange: (value: string) => void\r\n}\r\n\r\nexport function MultilineStringInput({ label, value, required, onChange }: MultilineStringInputProps) {\r\n return (\r\n ) => onChange(e.target.value)}\r\n value={value}\r\n autoFocus\r\n data-testid=\"chart-modal-multiline-string-textarea\"\r\n />\r\n )\r\n}\r\n","import { Input } from '@finviz/website'\r\nimport React from 'react'\r\n\r\ninterface NumberInputProps {\r\n label: string\r\n name: string\r\n value: number\r\n required: boolean\r\n min?: number\r\n max?: number\r\n allowDecimal?: boolean\r\n step?: number\r\n onChange: (value: number) => void\r\n}\r\n\r\nexport function NumberInput(props: NumberInputProps) {\r\n const { label, name, value, required, min, max, step, allowDecimal = false } = props\r\n\r\n return (\r\n ) =>\r\n props.onChange(allowDecimal ? parseFloat(e.target.value) : parseInt(e.target.value, 10))\r\n }\r\n data-testid=\"chart-modal-number-input\"\r\n />\r\n )\r\n}\r\n","import { Input } from '@finviz/website'\r\nimport React from 'react'\r\n\r\ninterface StringInputProps {\r\n label: string\r\n name: string\r\n value: string\r\n required: boolean\r\n onChange: (value: string) => void\r\n}\r\n\r\nexport function StringInput(props: StringInputProps) {\r\n const { label, name, value, required } = props\r\n\r\n return (\r\n ) => props.onChange(e.target.value)}\r\n data-testid=\"chart-modal-string-textinput\"\r\n />\r\n )\r\n}\r\n","import { Checkbox, Input, InputColorPicker, convertColorToHEX } from '@finviz/website'\r\nimport React from 'react'\r\n\r\ninterface InputProps {\r\n active: boolean\r\n trend: number\r\n color: string\r\n}\r\n\r\ninterface trendInputProps {\r\n value: InputProps\r\n onChange: (values: InputProps) => void\r\n}\r\n\r\nexport function Trend({ value, onChange }: trendInputProps) {\r\n return (\r\n
\r\n ) => onChange({ ...value, active: ev.currentTarget.checked })}\r\n data-testid=\"chart-modal-trend-active\"\r\n />\r\n ) =>\r\n onChange({ ...value, trend: ev.currentTarget.valueAsNumber })\r\n }\r\n value={value.trend}\r\n data-testid=\"chart-modal-trend-value\"\r\n />\r\n onChange({ ...value, color: color })}\r\n inputDataTestId=\"chart-modal-trend-color\"\r\n />\r\n
\r\n )\r\n}\r\n","import { Checkbox, Input, Paragraph } from '@finviz/website'\r\nimport React from 'react'\r\n\r\nimport { MacroTimeframe } from '../../constants/common'\r\nimport { DEFAULTS } from './index'\r\n\r\nexport interface InputProps {\r\n macroKey: MacroTimeframe\r\n isOff: boolean\r\n from: number\r\n to: number\r\n}\r\n\r\ninterface VisibilityInputProps {\r\n value: InputProps\r\n onChange: (value: InputProps) => void\r\n isCheckboxOnly: boolean\r\n}\r\n\r\nexport function VisibilityInput({ value, onChange, isCheckboxOnly }: VisibilityInputProps) {\r\n const [isOff, setIsOff] = React.useState(value.isOff)\r\n const [from, setFrom] = React.useState(value.from)\r\n const [to, setTo] = React.useState(value.to)\r\n const { macroKey } = value\r\n const macroLabel = macroKey.charAt(0).toUpperCase() + macroKey.slice(1)\r\n\r\n const setValue = React.useCallback(\r\n function (key: string, valueSetter: React.Dispatch>, value: ValueType) {\r\n valueSetter(value)\r\n onChange({ macroKey, isOff, from, to, [key]: value })\r\n },\r\n [macroKey, isOff, from, to, onChange]\r\n )\r\n return (\r\n
\r\n
\r\n ) => setValue('isOff', setIsOff, !e.target.checked)}\r\n >\r\n {isCheckboxOnly && macroLabel}\r\n \r\n {!isCheckboxOnly && (\r\n <>\r\n ) =>\r\n setValue('from', setFrom, Number(ev.currentTarget.value))\r\n }\r\n data-testid={`visibility-input-${macroKey}-from`}\r\n />\r\n -\r\n ) =>\r\n setValue('to', setTo, Number(ev.currentTarget.value))\r\n }\r\n data-testid={`visibility-input-${macroKey}-to`}\r\n />\r\n {macroLabel}\r\n \r\n )}\r\n
\r\n
\r\n )\r\n}\r\n","import merge from 'lodash.merge'\r\nimport React from 'react'\r\n\r\nimport { IVisibility, MacroTimeframe, MicroTimeframeRange } from '../../constants/common'\r\nimport { isInRange } from '../../utils/helpers'\r\nimport { InputProps, VisibilityInput } from './visibility-input'\r\n\r\ninterface VisibilityProps {\r\n label: string\r\n name: string\r\n value: IVisibility\r\n onChange: (value: IVisibility) => void\r\n handleDisableSubmit: (value: string | false) => void\r\n}\r\n\r\ntype Micro = { isOff: boolean; from: number; to: number }\r\nexport type DEFAULTS_TYPE = { [key in MacroTimeframe]: Micro }\r\n\r\nexport const DEFAULTS: DEFAULTS_TYPE = {\r\n // [MacroTimeframe.seconds]: { isOff: false, from: 1, to: 59 },\r\n [MacroTimeframe.minutes]: { isOff: false, from: 1, to: 59 },\r\n [MacroTimeframe.hours]: { isOff: false, from: 1, to: 24 },\r\n [MacroTimeframe.days]: { isOff: false, from: 1, to: 366 },\r\n [MacroTimeframe.weeks]: { isOff: false, from: 1, to: 52 },\r\n [MacroTimeframe.months]: { isOff: false, from: 1, to: 12 },\r\n}\r\n\r\nconst INPUTS_AVAILABLE = [MacroTimeframe.minutes, MacroTimeframe.hours]\r\n\r\nconst getInitialState = (value: IVisibility) => {\r\n const visibilities = merge({}, DEFAULTS)\r\n for (const visibility in visibilities) {\r\n const macroTimeframe = visibility as MacroTimeframe\r\n const valueMacroTimeframe = value?.[macroTimeframe]\r\n if (!valueMacroTimeframe) continue\r\n if (Object.keys(valueMacroTimeframe).length === 0) {\r\n visibilities[macroTimeframe] = { ...visibilities[macroTimeframe], isOff: true }\r\n } else {\r\n visibilities[macroTimeframe] = { ...visibilities[macroTimeframe], ...valueMacroTimeframe }\r\n }\r\n }\r\n return visibilities\r\n}\r\n\r\nconst getIsVisibilityOutsideAvailableTimeframes = (value: IVisibility) => {\r\n const result = Object.keys(MacroTimeframe).every((macrotimeframe) => {\r\n const macroRange = value[macrotimeframe as MacroTimeframe]\r\n\r\n return (\r\n macroRange &&\r\n (Object.keys(macroRange).length === 0 ||\r\n !MicroTimeframeRange[macrotimeframe as MacroTimeframe].some((item) =>\r\n isInRange({\r\n value: item,\r\n min: macroRange?.from ?? DEFAULTS[macrotimeframe as MacroTimeframe].from,\r\n max: macroRange?.to ?? DEFAULTS[macrotimeframe as MacroTimeframe].to,\r\n })\r\n ))\r\n )\r\n })\r\n return result\r\n}\r\n\r\nexport function Visibility(props: VisibilityProps) {\r\n const initialVisibilityRef = React.useRef(getInitialState(props.value))\r\n\r\n const handleChange = (value: InputProps) => {\r\n const result: IVisibility = props.value ? merge({}, props.value) : {}\r\n result[value.macroKey] = {}\r\n\r\n if (value.isOff) {\r\n props.onChange(result)\r\n } else if (value.from === DEFAULTS[value.macroKey].from && value.to === DEFAULTS[value.macroKey].to) {\r\n delete result[value.macroKey]\r\n props.onChange(result)\r\n } else {\r\n if (value.from !== DEFAULTS[value.macroKey].from) {\r\n result[value.macroKey]!.from = value.from\r\n }\r\n if (value.to !== DEFAULTS[value.macroKey].to) {\r\n result[value.macroKey]!.to = value.to\r\n }\r\n props.onChange(result)\r\n }\r\n\r\n props.handleDisableSubmit(\r\n getIsVisibilityOutsideAvailableTimeframes(result)\r\n ? 'The chosen timeframes would make the drawing invisible on all supported timeframes.'\r\n : false\r\n )\r\n }\r\n\r\n return Object.keys(initialVisibilityRef.current).map((macroKey) => (\r\n \r\n ))\r\n}\r\n","import {\r\n Button,\r\n ButtonGroup,\r\n Dialog,\r\n DialogBody,\r\n DialogFooter,\r\n DialogHeader,\r\n DialogStateReturn,\r\n useDialogState,\r\n} from '@finviz/website'\r\nimport debounce from 'lodash.debounce'\r\nimport * as React from 'react'\r\n\r\nimport { ObjectHash } from '../../types/shared'\r\nimport CanvasElement from '../canvas/element'\r\nimport Pane from '../models/pane'\r\nimport { BackgroundInput } from './background'\r\nimport { BorderInput } from './border'\r\nimport { CheckBox } from './checkbox'\r\nimport { FontInput } from './font'\r\nimport { LineInput } from './line'\r\nimport { MultilineStringInput } from './multiline_string'\r\nimport { NumberInput } from './number'\r\nimport { StringInput } from './string'\r\nimport { Trend } from './trend'\r\nimport { Visibility } from './visibility'\r\n\r\nfunction getInputForType(type: string) {\r\n switch (type) {\r\n case 'number':\r\n return NumberInput\r\n case 'string':\r\n return StringInput\r\n case 'text':\r\n return StringInput\r\n case 'background':\r\n return BackgroundInput\r\n case 'border':\r\n return BorderInput\r\n case 'line':\r\n return LineInput\r\n case 'multiline_string':\r\n return MultilineStringInput\r\n case 'font':\r\n return FontInput\r\n case 'checkbox':\r\n return CheckBox\r\n case 'trend':\r\n return Trend\r\n case 'visibility':\r\n return Visibility\r\n default:\r\n return () =>
ERROR: Unknown input type
\r\n }\r\n}\r\n\r\nconst TAB_BUTTON_COMMON_PROPS = { type: 'button' as const, className: 'flex-1', contentClass: 'text-center' }\r\n\r\ntype OnSubmitType = ((value: ObjectHash) => void) | null\r\ntype OnDismissType = (() => void) | null\r\n\r\nexport interface ElementStyleDialogProps {\r\n state: DialogStateReturn\r\n element: ElementType\r\n onSubmit: ((values: ElementType['attrs']) => void) | null\r\n onDismiss: (() => void) | null\r\n onHide: () => void\r\n}\r\n\r\nexport type StyleDialogOpener = (\r\n element: ElementType,\r\n onSubmit: ElementStyleDialogProps['onSubmit'],\r\n onDismiss: ElementStyleDialogProps['onDismiss']\r\n) => void\r\n\r\nfunction getValuesFromFormState(formState: ObjectHash) {\r\n return formState.reduce((acc: ObjectHash, cur: ObjectHash) => {\r\n acc[cur.name] = cur.value\r\n return acc\r\n }, {} as ObjectHash)\r\n}\r\n\r\nenum DialogTabs {\r\n Style,\r\n Visibility,\r\n}\r\n\r\nexport function ElementStyleDialog(props: ElementStyleDialogProps) {\r\n const config = props.element.getModalConfig()\r\n const initialFormStateRef = React.useRef[]>(JSON.parse(JSON.stringify(config.inputs)))\r\n const [formState, setFormState] = React.useState[]>(config.inputs)\r\n const [selectedTab, setSelectedTab] = React.useState(DialogTabs.Style)\r\n const [isSubmitDisabled, setIsSubmitDisabled] = React.useState(false) // If string, the value is used as title for disabled button.\r\n\r\n const isDrawingElement = props.element.getIsDrawing()\r\n\r\n const handleFullyOpen = React.useCallback(() => {\r\n if (props.element instanceof CanvasElement && props.element.model instanceof Pane) {\r\n props.element.setIsSelected(true)\r\n props.element.model.updateAttribute('selection', props.element)\r\n props.element.setIsEditInProgress(true)\r\n }\r\n }, [props.element])\r\n\r\n const handleFullyClosed = React.useCallback(() => {\r\n if (props.element instanceof CanvasElement) {\r\n props.element.setIsEditInProgress(false)\r\n }\r\n props.onHide()\r\n }, [props])\r\n\r\n const handleValuesChange = React.useCallback(\r\n ({\r\n values,\r\n shouldSubmit = false,\r\n shouldDismiss = false,\r\n }: {\r\n values: ObjectHash\r\n shouldSubmit?: boolean\r\n shouldDismiss?: boolean\r\n }) => {\r\n const hasOnSubmit = typeof props.onSubmit === 'function'\r\n const hasOnDismiss = typeof props.onDismiss === 'function'\r\n\r\n props.element.set(values)\r\n if (shouldSubmit && hasOnSubmit) {\r\n props.onSubmit!(values)\r\n } else if (shouldDismiss && hasOnDismiss) {\r\n props.onDismiss!()\r\n }\r\n\r\n if (shouldSubmit || shouldDismiss) {\r\n props.state.hide()\r\n }\r\n },\r\n [props]\r\n )\r\n\r\n const handleValuesChangeDebounceRef = React.useRef(\r\n debounce(\r\n (newFormState) => {\r\n const values = getValuesFromFormState(newFormState)\r\n handleValuesChange({ values })\r\n },\r\n 50,\r\n { maxWait: 100 }\r\n )\r\n )\r\n\r\n React.useEffect(\r\n () => () => {\r\n handleValuesChangeDebounceRef.current.cancel()\r\n },\r\n []\r\n )\r\n\r\n const onSubmit: React.FormEventHandler = React.useCallback(\r\n (ev: React.FormEvent) => {\r\n ev.preventDefault()\r\n if (ev.currentTarget.checkValidity()) {\r\n const values = getValuesFromFormState(formState)\r\n handleValuesChange({ values, shouldSubmit: true })\r\n }\r\n },\r\n [formState, handleValuesChange]\r\n )\r\n\r\n const handleCloseDialog = React.useCallback(() => {\r\n const values = getValuesFromFormState(initialFormStateRef.current)\r\n handleValuesChange({ values, shouldDismiss: true })\r\n\r\n // Ariakit hideOnEscape expects a bool as return value\r\n return true\r\n }, [handleValuesChange])\r\n\r\n const getShouldRenderInputForTab = (inputType: string) => {\r\n if (selectedTab === DialogTabs.Visibility && inputType === 'visibility') return true\r\n if (selectedTab !== DialogTabs.Visibility && inputType !== 'visibility') return true\r\n return false\r\n }\r\n\r\n return (\r\n }\r\n onFullyOpen={handleFullyOpen}\r\n onFullyClosed={handleFullyClosed}\r\n hideOnEsc={handleCloseDialog}\r\n >\r\n {config.title}\r\n
\r\n \r\n {isDrawingElement && (\r\n \r\n setSelectedTab(DialogTabs.Style)}\r\n data-testid=\"dialog-tab-button-style\"\r\n >\r\n Style\r\n \r\n setSelectedTab(DialogTabs.Visibility)}\r\n data-testid=\"dialog-tab-button-visibility\"\r\n >\r\n Visibility\r\n \r\n \r\n )}\r\n\r\n {formState.map((input) => {\r\n const InputComponent = getInputForType(input.type) as React.FC<{\r\n onChange: (value: string) => void\r\n handleDisableSubmit?: typeof setIsSubmitDisabled\r\n }>\r\n return (\r\n getShouldRenderInputForTab(input.type) && (\r\n {\r\n setFormState((prevState) => {\r\n const newFormState = prevState.map((stateInput) => {\r\n if (stateInput.name === input.name) {\r\n return { ...stateInput, value }\r\n }\r\n return stateInput\r\n })\r\n handleValuesChangeDebounceRef.current(newFormState)\r\n return newFormState\r\n })\r\n }}\r\n handleDisableSubmit={setIsSubmitDisabled}\r\n />\r\n )\r\n )\r\n })}\r\n \r\n \r\n \r\n \r\n Save\r\n \r\n \r\n
\r\n \r\n )\r\n}\r\n\r\nexport const ElementStyleDialogContext = React.createContext>(() => {})\r\n\r\nexport function withElementStyleDialogState

(Component: React.ComponentType

) {\r\n return function WrappedComponent(props: P) {\r\n const context = React.useContext(ElementStyleDialogContext)\r\n\r\n return \r\n }\r\n}\r\n\r\nexport function ElementStyleDialogWrapper(props: { children: React.ReactNode }) {\r\n const [element, setElement] = React.useState(null)\r\n const [onSubmit, setOnSubmit] = React.useState(null)\r\n const [onDismiss, setOnDismiss] = React.useState(null)\r\n const dialog = useDialogState()\r\n\r\n const openDialog = (element: CanvasElement, onSubmit?: OnSubmitType, onDismiss?: OnDismissType) => {\r\n if (onSubmit) {\r\n setOnSubmit(() => onSubmit)\r\n }\r\n if (onDismiss) {\r\n setOnDismiss(() => onDismiss)\r\n }\r\n\r\n setElement(element)\r\n dialog.show()\r\n }\r\n\r\n const onHide = () => {\r\n setElement(null)\r\n setOnSubmit(null)\r\n setOnDismiss(null)\r\n }\r\n\r\n return (\r\n \r\n {props.children}\r\n {element && (\r\n \r\n )}\r\n \r\n )\r\n}\r\n","import { IndicatorType } from '../../constants/common'\r\nimport { HLC } from '../../utils/hlc'\r\n\r\nexport type DrawingChangeTimestamp = HLC\r\nexport type DrawingContainerType = IndicatorType | 'chart' | 'note' | null\r\nexport type AutoSaveChangeType = 'update' | 'destroy'\r\n\r\nexport interface AutoSaveElement {\r\n elementId: string\r\n ticker: string\r\n zIndex: number\r\n lastChange: DrawingChangeTimestamp\r\n changeType: AutoSaveChangeType\r\n containerType: DrawingContainerType\r\n elementAttrs: string\r\n}\r\n\r\nexport type AutoSaveElementDBRecord = Omit & { lastChange: string } & {\r\n lastChangeTimestamp: number\r\n lastChangeCounter: number\r\n lastChangeNodeUUID: string\r\n}\r\n\r\nexport const DRAWINGS_UPDATE_INTERVAL_MS = process.env.IS_E2E_TESTING ? 3000 : 15000\r\nexport const DRAWINGS_SAVE_INTERVAL_MS = 250\r\n","import { Notification, Paragraph, useNotification } from '@finviz/website'\r\nimport React from 'react'\r\n\r\nimport fetchApi, {\r\n ContentType,\r\n ForbiddenError,\r\n GenericStatusCodeError,\r\n GoneError,\r\n InternalServerError,\r\n} from '../../utils/fetch_api'\r\nimport { HLC, compareHlc, incrementHlc } from '../../utils/hlc'\r\nimport { getByteLengthOfString } from '../../utils/string-byte-length'\r\nimport { AutoSaveElement, AutoSaveElementDBRecord, DrawingContainerType } from './constants'\r\nimport { getAutosaveElementFromDBRecord, getDBRecordFromAutosaveElement } from './utils'\r\n\r\nconst RETRY_LIMIT = 5\r\n\r\nexport function useDrawingAutoSaveApi() {\r\n const postRetryCountRef = React.useRef(0)\r\n const deleteRetryCountRef = React.useRef(0)\r\n const notificationContext = useNotification()\r\n\r\n const fetchDrawings = React.useCallback(\r\n async ({\r\n tickers,\r\n containerTypes,\r\n lastChange,\r\n }: {\r\n tickers: string[]\r\n containerTypes: DrawingContainerType[]\r\n lastChange: HLC\r\n }) => {\r\n try {\r\n const data = await fetchApi<{\r\n drawings: AutoSaveElementDBRecord[]\r\n }>({\r\n location: '/api/auto_save.ashx',\r\n queryParameters: {\r\n ticker: tickers.join(','),\r\n containerTypes: containerTypes.join(',') || undefined,\r\n lastChangeTimestamp: lastChange.ts,\r\n lastChangeCounter: lastChange.count,\r\n lastChangeNodeUUID: lastChange.uuid,\r\n },\r\n throwOnStatusCodes: [403, 404],\r\n })\r\n return data.drawings.map((drawing) => getAutosaveElementFromDBRecord(drawing))\r\n } catch {\r\n // ignore error\r\n }\r\n\r\n return []\r\n },\r\n []\r\n )\r\n\r\n const saveDrawings = React.useCallback(\r\n async (drawings: AutoSaveElement[]): Promise => {\r\n if (drawings.length === 0) {\r\n return undefined\r\n }\r\n\r\n try {\r\n const bodyJsonString = JSON.stringify(drawings.map((item) => getDBRecordFromAutosaveElement(item)))\r\n let keepalive = false\r\n try {\r\n keepalive = getByteLengthOfString(bodyJsonString) < 64000\r\n } catch (error: any) {\r\n window.Sentry?.captureException(error)\r\n }\r\n await fetchApi({\r\n location: '/api/auto_save.ashx',\r\n method: 'POST',\r\n throwOnStatusCodes: [400, 403, 404, 410, 500],\r\n contentType: ContentType.ApplicationJson,\r\n body: bodyJsonString,\r\n keepalive,\r\n })\r\n const [latestChangeHlc] = [...drawings].sort((a, b) => compareHlc(b.lastChange, a.lastChange))\r\n postRetryCountRef.current = 0\r\n return latestChangeHlc.lastChange\r\n } catch (error) {\r\n if (error instanceof InternalServerError) {\r\n // try again\r\n if (postRetryCountRef.current < RETRY_LIMIT) {\r\n postRetryCountRef.current = postRetryCountRef.current + 1\r\n await new Promise((r) => setTimeout(r, 1000))\r\n return saveDrawings(drawings)\r\n } else {\r\n // continue to report to Sentry\r\n postRetryCountRef.current = 0\r\n }\r\n } else if (error instanceof ForbiddenError) {\r\n // ignore error\r\n return undefined\r\n } else if (error instanceof GoneError) {\r\n const newTicker = (error.response as ObjectHash).newTicker\r\n const message = newTicker\r\n ? `Ticker \"${drawings[0].ticker}\" was renamed to \"${newTicker}\"`\r\n : `Ticker \"${drawings[0].ticker}\" no longer exists.`\r\n notificationContext.show(\r\n } timeoutInMs={6000}>\r\n {message}\r\n \r\n )\r\n return undefined\r\n }\r\n\r\n // report error to Sentry\r\n window.Sentry?.captureException(error, {\r\n extra: (error instanceof GenericStatusCodeError\r\n ? (error.response as ObjectHash).invalidItems\r\n : drawings\r\n ).reduce(\r\n (acc: ObjectHash, cur: ObjectHash, index: number) => ({ ...acc, [`item-${index}`]: JSON.stringify(cur) }),\r\n {} as ObjectHash\r\n ),\r\n })\r\n\r\n return undefined\r\n }\r\n },\r\n [notificationContext]\r\n )\r\n\r\n const deleteAllDrawings = React.useCallback(\r\n async ({ tickers, lastLocalChange }: { tickers: string[]; lastLocalChange: HLC }): Promise => {\r\n try {\r\n const newHlc = incrementHlc(lastLocalChange, Date.now())\r\n await fetchApi({\r\n location: `/api/auto_save.ashx?ticker=${tickers.join(',')}&lastChangeTimestamp=${\r\n newHlc.ts\r\n }&lastChangeCounter=${newHlc.count}&lastChangeNodeUUID=${newHlc.uuid}`,\r\n method: 'DELETE',\r\n throwOnStatusCodes: [403, 404, 500],\r\n keepalive: true,\r\n })\r\n deleteRetryCountRef.current = 0\r\n } catch (error) {\r\n if (error instanceof InternalServerError) {\r\n // try again\r\n if (deleteRetryCountRef.current < RETRY_LIMIT) {\r\n deleteRetryCountRef.current = deleteRetryCountRef.current + 1\r\n await new Promise((r) => setTimeout(r, 1000))\r\n return deleteAllDrawings({ tickers, lastLocalChange })\r\n } else {\r\n // continue to report to Sentry\r\n deleteRetryCountRef.current = 0\r\n }\r\n } else if (error instanceof ForbiddenError) {\r\n // ignore error\r\n return\r\n }\r\n\r\n // report error to Sentry\r\n window.Sentry?.captureException(error)\r\n }\r\n },\r\n []\r\n )\r\n\r\n return { fetchDrawings, saveDrawings, deleteAllDrawings }\r\n}\r\n","// byteLengthCharCode2 from https://stackoverflow.com/a/63893237\r\n\r\nexport function getByteLengthOfString(s: string) {\r\n //assuming the String is UCS-2(aka UTF-16) encoded\r\n let n = 0\r\n for (let i = 0, l = s.length; i < l; i++) {\r\n const hi = s.charCodeAt(i)\r\n if (hi < 0x0080) {\r\n n += 1\r\n } else if (hi < 0x0800) {\r\n n += 2\r\n } else if (hi < 0xd800) {\r\n n += 3\r\n } else if (hi < 0xdc00) {\r\n const lo = s.charCodeAt(++i)\r\n if (i < l && lo >= 0xdc00 && lo <= 0xdfff) {\r\n n += 4\r\n } else {\r\n throw new Error('UCS-2 String malformed')\r\n }\r\n } else if (hi < 0xe000) {\r\n throw new Error('UCS-2 String malformed')\r\n } else {\r\n n += 3\r\n }\r\n }\r\n return n\r\n}\r\n","import React from 'react'\r\n\r\nimport { DrawingSpineOptions, DrawingSpineOptionsEvent } from '../../../types/shared'\r\nimport ElementCanvas from '../../canvas/element'\r\nimport { SpecificChartFunctionality } from '../../constants/common'\r\nimport { getCanvasElementByType } from '../../helpers/get-canvas-element-by-type'\r\nimport ChartLayout from '../../models/chart_layout'\r\nimport { AutoSaveState } from '../../models/constants'\r\nimport Element from '../../models/element'\r\nimport { compareHlc, incrementHlc, initHlc, receiveHlc } from '../../utils/hlc'\r\nimport { AutoSaveChangeType, AutoSaveElement, DRAWINGS_SAVE_INTERVAL_MS } from './constants'\r\nimport { useDrawingAutoSaveApi } from './use-drawing-autosave-api'\r\nimport { useIsAutoSaveActive } from './use-is-auto-save-active'\r\nimport {\r\n getContainerType,\r\n getNoteElementId,\r\n getTickerNoteText,\r\n getTickersAndContainerTypesInLayoutModel,\r\n mergeUpdatedDrawingsToInternalStore,\r\n updateInternalStoreWithChangedElement,\r\n} from './utils'\r\n\r\nexport function useDrawingAutoSaveControls(chartLayout: ChartLayout) {\r\n const { fetchDrawings, saveDrawings, deleteAllDrawings } = useDrawingAutoSaveApi()\r\n const isAutoSaveActive = useIsAutoSaveActive(chartLayout)\r\n const drawingsInternalStore = React.useMemo(() => chartLayout.drawingsInternalStore(), [chartLayout])\r\n const saveTimeoutRef = React.useRef()\r\n\r\n React.useEffect(\r\n () => () => {\r\n if (saveTimeoutRef.current) {\r\n clearTimeout(saveTimeoutRef.current)\r\n }\r\n },\r\n []\r\n )\r\n\r\n const saveLatestChanges = React.useCallback(\r\n (\r\n withDelayInMs = DRAWINGS_SAVE_INTERVAL_MS,\r\n saveQueueExtraFilterCallback: ((item: AutoSaveElement) => boolean) | null = null\r\n ) => {\r\n if (saveTimeoutRef.current) {\r\n clearTimeout(saveTimeoutRef.current)\r\n }\r\n const saveQueue = drawingsInternalStore.elements.filter(\r\n (item) =>\r\n compareHlc(item.lastChange, drawingsInternalStore.latestLocalUpdateTimestamp) > 0 &&\r\n item.lastChange.uuid === drawingsInternalStore.instanceUUID &&\r\n (saveQueueExtraFilterCallback === null || saveQueueExtraFilterCallback(item))\r\n )\r\n if (saveQueue.length === 0) {\r\n return\r\n }\r\n\r\n drawingsInternalStore.setAutoSaveState(AutoSaveState.Unsaved)\r\n\r\n const save = async () => {\r\n drawingsInternalStore.setAutoSaveState(AutoSaveState.Saving)\r\n const result = await saveDrawings(saveQueue)\r\n if (result) {\r\n drawingsInternalStore.updateAttributes({\r\n latestLocalUpdateTimestamp: receiveHlc(drawingsInternalStore.latestLocalUpdateTimestamp, result),\r\n })\r\n }\r\n drawingsInternalStore.setAutoSaveState(AutoSaveState.Saved)\r\n\r\n return result\r\n }\r\n\r\n if (withDelayInMs === 0) {\r\n return save()\r\n }\r\n\r\n saveTimeoutRef.current = window.setTimeout(save, withDelayInMs)\r\n },\r\n [saveDrawings, drawingsInternalStore]\r\n )\r\n\r\n const syncChartLayoutDrawings = React.useCallback(\r\n (drawing: AutoSaveElement) => {\r\n if (drawing.containerType === 'note') {\r\n return\r\n }\r\n const isRemove = drawing.changeType === 'destroy'\r\n\r\n chartLayout.getAllPanes().forEach((paneModel) => {\r\n const ticker = paneModel.getQuoteRawTicker()\r\n const paneContainerType = getContainerType(paneModel)\r\n if (!paneContainerType || drawing.ticker !== ticker) {\r\n return\r\n }\r\n const paneInternalStoreElements = drawingsInternalStore.elements.filter(\r\n (autoSaveElement) => autoSaveElement.ticker === ticker && autoSaveElement.containerType === paneContainerType\r\n )\r\n const paneElements = paneModel.getAllElements()\r\n let element: Element | undefined\r\n paneElements.forEach((paneElement) => {\r\n if (paneElement.isDrawing() && !paneElement.instance.isCreator) {\r\n const paneDrawing = paneInternalStoreElements.find(({ elementId }) => elementId === paneElement.elementId)\r\n if (!paneDrawing || paneDrawing.changeType === 'destroy') {\r\n paneElement.destroyCascade()\r\n } else if (paneElement.elementId && paneElement.elementId === drawing.elementId) {\r\n element = paneElement\r\n }\r\n }\r\n })\r\n\r\n const parsedElementAttrs = JSON.parse(drawing.elementAttrs)\r\n if (element) {\r\n if (drawing.elementAttrs !== JSON.stringify(element.instance.toAutosaveConfig())) {\r\n if (element.pane().selection !== element.instance && !element.hasOngoingInteraction()) {\r\n element.instance.set(parsedElementAttrs)\r\n element.instance.updateScales()\r\n }\r\n }\r\n if (drawing.zIndex !== element.zIndex) {\r\n element.updateAttributes({ zIndex: drawing.zIndex })\r\n }\r\n if (isRemove || paneContainerType !== drawing.containerType) {\r\n element.destroyCascade()\r\n }\r\n } else if (!isRemove && paneContainerType === drawing.containerType) {\r\n const instance = getCanvasElementByType(parsedElementAttrs.type).fromObject(\r\n parsedElementAttrs,\r\n paneModel\r\n ) as ElementCanvas\r\n paneModel.elements().create({ elementId: drawing.elementId, instance, zIndex: drawing.zIndex })\r\n instance.updateScales()\r\n }\r\n })\r\n },\r\n [chartLayout, drawingsInternalStore]\r\n )\r\n\r\n const handleAutoSaveNoteChange = React.useCallback(\r\n (note: string, ticker?: string) => {\r\n if (ticker) {\r\n const newNoteElement: AutoSaveElement = {\r\n elementId: getNoteElementId(ticker),\r\n zIndex: 0,\r\n ticker: ticker,\r\n lastChange: incrementHlc(drawingsInternalStore.latestLocalUpdateTimestamp, Date.now()),\r\n changeType: 'update',\r\n containerType: 'note',\r\n elementAttrs: JSON.stringify({ text: note }),\r\n }\r\n\r\n drawingsInternalStore.updateAttributes({\r\n elements: [\r\n ...drawingsInternalStore.elements.filter(({ elementId }) => elementId !== newNoteElement.elementId),\r\n newNoteElement,\r\n ],\r\n })\r\n }\r\n },\r\n [drawingsInternalStore]\r\n )\r\n\r\n const handleIdeaNoteChange = React.useCallback(\r\n (note: string) => {\r\n if (chartLayout.idea?.note !== note && (chartLayout.idea || note)) {\r\n chartLayout.updateAttribute('idea', { ...chartLayout.idea, note })\r\n handleAutoSaveNoteChange(note, chartLayout.activeChart?.getQuoteRawTicker() ?? undefined)\r\n }\r\n },\r\n [chartLayout, handleAutoSaveNoteChange]\r\n )\r\n\r\n const checkDrawingUpdate = React.useCallback(\r\n async (isRefetchAll = false) => {\r\n const { tickers, containerTypes } = getTickersAndContainerTypesInLayoutModel(chartLayout)\r\n if (isRefetchAll) {\r\n drawingsInternalStore.updateAttributes({\r\n latestRemoteUpdateTimestamp: initHlc(drawingsInternalStore.instanceUUID, 0),\r\n })\r\n }\r\n\r\n const updatedDrawings = await fetchDrawings({\r\n tickers,\r\n containerTypes,\r\n lastChange: drawingsInternalStore.latestRemoteUpdateTimestamp,\r\n })\r\n const { newLastUpdateTimestamp, updatedElementIds, newInternalStore } = mergeUpdatedDrawingsToInternalStore({\r\n updatedDrawings,\r\n currentInternalStore: drawingsInternalStore.elements,\r\n lastUpdateTimestamp: drawingsInternalStore.latestRemoteUpdateTimestamp,\r\n isRefetchAll,\r\n })\r\n\r\n drawingsInternalStore.updateAttributes({\r\n // Even if there are no changes in elements, newInternalStore is new array with the same content which may cause unnecessary rerenders\r\n ...(updatedElementIds.length > 0 ? { elements: newInternalStore } : {}),\r\n latestRemoteUpdateTimestamp: newLastUpdateTimestamp,\r\n latestLocalUpdateTimestamp:\r\n isRefetchAll && newInternalStore.length > 0\r\n ? receiveHlc(drawingsInternalStore.latestLocalUpdateTimestamp, newLastUpdateTimestamp)\r\n : drawingsInternalStore.latestLocalUpdateTimestamp,\r\n })\r\n\r\n if (updatedElementIds.length > 0 || isRefetchAll) {\r\n saveLatestChanges(0)\r\n const allElements = chartLayout.getAllElements()\r\n updatedElementIds.forEach((elementId) => {\r\n const element = allElements.find((element) => element.elementId === elementId)\r\n\r\n if (element && element.isDrawing() && !element.hasOngoingInteraction()) {\r\n element.destroyCascade()\r\n }\r\n })\r\n\r\n drawingsInternalStore.elements.forEach(syncChartLayoutDrawings)\r\n chartLayout.getAllPanes().forEach((paneModel) => {\r\n paneModel.normalizeZIndexes()\r\n })\r\n\r\n if (chartLayout.specificChartFunctionality === SpecificChartFunctionality.quotePage) {\r\n const activeTicker = chartLayout.activeChart?.getQuoteRawTicker() ?? ''\r\n handleIdeaNoteChange(getTickerNoteText({ ticker: activeTicker, elements: newInternalStore }))\r\n }\r\n }\r\n },\r\n [\r\n chartLayout,\r\n drawingsInternalStore,\r\n syncChartLayoutDrawings,\r\n fetchDrawings,\r\n handleIdeaNoteChange,\r\n saveLatestChanges,\r\n ]\r\n )\r\n\r\n const updateInternalStoreWithElement = React.useCallback(\r\n (element: Element, changeType: AutoSaveChangeType) => {\r\n const updateResult = updateInternalStoreWithChangedElement({\r\n element,\r\n changeType,\r\n currentInternalStore: drawingsInternalStore.elements,\r\n lastUpdateTimestamp: incrementHlc(\r\n receiveHlc(\r\n drawingsInternalStore.latestLocalUpdateTimestamp,\r\n drawingsInternalStore.latestRemoteUpdateTimestamp\r\n ),\r\n Date.now()\r\n ),\r\n })\r\n\r\n if (updateResult) {\r\n const { shouldSyncAndSave, newInternalStore, newDrawing } = updateResult\r\n if (shouldSyncAndSave) {\r\n drawingsInternalStore.updateAttributes({ elements: newInternalStore })\r\n syncChartLayoutDrawings(newDrawing)\r\n }\r\n }\r\n },\r\n [syncChartLayoutDrawings, drawingsInternalStore]\r\n )\r\n\r\n const deleteAllAutoSavedElements = React.useCallback(async () => {\r\n const { tickers } = getTickersAndContainerTypesInLayoutModel(chartLayout)\r\n\r\n await deleteAllDrawings({ tickers, lastLocalChange: drawingsInternalStore.latestLocalUpdateTimestamp })\r\n await checkDrawingUpdate()\r\n }, [chartLayout, deleteAllDrawings, drawingsInternalStore, checkDrawingUpdate])\r\n\r\n const onElementChange = React.useCallback(\r\n (element: Element, _?: any, options?: DrawingSpineOptions) => {\r\n const elementPane = element.pane()\r\n // This may happen if pane had been removed already, in most cases \"element.destroyed\" should be true,\r\n // but we would need to check if it was destroyed by delete drawing action or not, and checking if pane exists covers all cases\r\n if (!element.isDrawing() || element.instance.isCreator || !elementPane) {\r\n return\r\n }\r\n const elementContainerType = getContainerType(elementPane)\r\n const elementPaneTicker = elementPane.getQuoteRawTicker()\r\n const isElementInCurrentChartLayout = chartLayout\r\n .getAllPanes()\r\n .some(\r\n (model) => getContainerType(model) === elementContainerType && model.getQuoteRawTicker() === elementPaneTicker\r\n )\r\n if (isElementInCurrentChartLayout) {\r\n const isRemove = options?.eventType === DrawingSpineOptionsEvent.Remove\r\n updateInternalStoreWithElement(element, isRemove ? 'destroy' : 'update')\r\n }\r\n },\r\n [updateInternalStoreWithElement, chartLayout]\r\n )\r\n\r\n return {\r\n drawingsInternalStore,\r\n onElementChange,\r\n handleIdeaNoteChange,\r\n deleteAllAutoSavedElements,\r\n isAutoSaveActive,\r\n handleAutoSaveNoteChange,\r\n syncChartLayoutDrawings,\r\n saveLatestChanges,\r\n checkDrawingUpdate,\r\n }\r\n}\r\n","import React from 'react'\r\n\r\nimport { useModelState } from '../../model-hooks/use-model-state'\r\nimport ChartLayout from '../../models/chart_layout'\r\nimport { getIsPreserveDrawingsAndAutosaveAvailable } from '../../utils/chart'\r\n\r\nexport function useIsAutoSaveActive(chartLayout: ChartLayout) {\r\n const chartLayoutModel = useModelState(chartLayout, {\r\n watchProperties: ['isInit', 'isPreserveDrawingsActive', 'idea'],\r\n })\r\n const { idea, isInit, isPreserveDrawingsActive } = chartLayoutModel\r\n return React.useMemo(\r\n () =>\r\n getIsPreserveDrawingsAndAutosaveAvailable(chartLayoutModel) && isPreserveDrawingsActive && !!isInit && !idea?.id,\r\n [isPreserveDrawingsActive, isInit, idea?.id, chartLayoutModel]\r\n )\r\n}\r\n","import React from 'react'\r\n\r\nimport { CustomSpineEvents } from '../../../types/shared'\r\nimport { useModelState } from '../../model-hooks/use-model-state'\r\nimport ChartModel from '../../models/chart'\r\nimport ChartLayout from '../../models/chart_layout'\r\nimport { AutoSaveState } from '../../models/constants'\r\nimport Element from '../../models/element'\r\nimport { usePrevious } from '../../utils/use-prev-state'\r\nimport { DRAWINGS_UPDATE_INTERVAL_MS } from './constants'\r\nimport { useDrawingAutoSaveControls } from './use-drawing-auto-save-controls'\r\nimport { getTickersAndContainerTypesInLayoutModel } from './utils'\r\n\r\nfunction useDrawingAutoSave(chartLayout: ChartLayout) {\r\n const {\r\n onElementChange,\r\n deleteAllAutoSavedElements,\r\n checkDrawingUpdate,\r\n syncChartLayoutDrawings,\r\n saveLatestChanges,\r\n isAutoSaveActive,\r\n } = useDrawingAutoSaveControls(chartLayout)\r\n\r\n const drawingsInternalStoreUnwatched = React.useMemo(() => chartLayout.drawingsInternalStore(), [chartLayout])\r\n const drawingsInternalStore = useModelState(drawingsInternalStoreUnwatched, { watchProperties: ['elements'] })\r\n const prevIsAutoSaveActive = usePrevious(isAutoSaveActive)\r\n\r\n const runInitialSaveAndRefetchUpdate = React.useCallback(async () => {\r\n chartLayout.getAllElements().forEach((element) => {\r\n // Adds drawings to internal store if isAutoSaveActive and they are not in the store yet\r\n if (!drawingsInternalStore.elements.some((drawing) => drawing.elementId === element.elementId)) {\r\n onElementChange(element)\r\n }\r\n })\r\n\r\n // We want to save everything except notes because saving notes can overwrite those already saved in db. Each drawing has different id but there is only one note per ticker\r\n // Notes are merged in checkDrawingUpdate fn\r\n await saveLatestChanges(0, (item) => item.containerType !== 'note')\r\n\r\n checkDrawingUpdate(true)\r\n }, [checkDrawingUpdate, chartLayout, onElementChange, drawingsInternalStore.elements, saveLatestChanges])\r\n\r\n React.useEffect(() => {\r\n if (isAutoSaveActive) {\r\n saveLatestChanges()\r\n }\r\n }, [saveLatestChanges, drawingsInternalStore.elements, isAutoSaveActive])\r\n\r\n React.useEffect(() => {\r\n if (!isAutoSaveActive) {\r\n chartLayout.drawingsInternalStore().setAutoSaveState(AutoSaveState.Off)\r\n return\r\n }\r\n chartLayout.drawingsInternalStore().setAutoSaveState(AutoSaveState.Saved)\r\n if (!prevIsAutoSaveActive && isAutoSaveActive) {\r\n runInitialSaveAndRefetchUpdate()\r\n }\r\n\r\n let { tickers, containerTypes } = getTickersAndContainerTypesInLayoutModel(chartLayout)\r\n\r\n const onChartOrIndicatorChange = () => {\r\n const { tickers: newTickers, containerTypes: newContainerTypes } =\r\n getTickersAndContainerTypesInLayoutModel(chartLayout)\r\n if (\r\n JSON.stringify(tickers) !== JSON.stringify(newTickers) ||\r\n JSON.stringify(containerTypes) !== JSON.stringify(newContainerTypes)\r\n ) {\r\n tickers = newTickers\r\n containerTypes = newContainerTypes\r\n checkDrawingUpdate(true)\r\n }\r\n }\r\n\r\n ChartModel.bind(`${CustomSpineEvents.IndicatorsChange} change`, onChartOrIndicatorChange)\r\n Element.bind('change', onElementChange)\r\n\r\n drawingsInternalStore.elements.forEach(syncChartLayoutDrawings)\r\n const checkDrawingUpdateInterval = setInterval(checkDrawingUpdate, DRAWINGS_UPDATE_INTERVAL_MS)\r\n\r\n const unregisterListeners = () => {\r\n clearInterval(checkDrawingUpdateInterval)\r\n ChartModel.unbind(`${CustomSpineEvents.IndicatorsChange} change`, onChartOrIndicatorChange)\r\n Element.unbind('change', onElementChange)\r\n }\r\n\r\n ChartLayout.bind('change', (model: ChartLayout) => {\r\n if (model.willDestroy) {\r\n unregisterListeners()\r\n }\r\n })\r\n\r\n return unregisterListeners\r\n }, [\r\n chartLayout,\r\n drawingsInternalStore,\r\n checkDrawingUpdate,\r\n onElementChange,\r\n syncChartLayoutDrawings,\r\n isAutoSaveActive,\r\n prevIsAutoSaveActive,\r\n runInitialSaveAndRefetchUpdate,\r\n ])\r\n\r\n return { deleteAllAutoSavedElements, isAutoSaveActive }\r\n}\r\n\r\ninterface Props {\r\n chartLayoutModel: ChartLayout\r\n}\r\n\r\nexport const withDrawingsAutoSave = (Component: any) => (props: Props) => {\r\n const { deleteAllAutoSavedElements, isAutoSaveActive } = useDrawingAutoSave(props.chartLayoutModel)\r\n\r\n return (\r\n \r\n )\r\n}\r\n","import React from 'react'\r\n\r\nexport function usePrevious(value: any) {\r\n const ref = React.useRef()\r\n React.useEffect(() => {\r\n ref.current = value\r\n }, [value])\r\n return ref.current\r\n}\r\n","import { ButtonComponentProps, Icon, Select, SelectListProps } from '@finviz/website'\r\nimport * as React from 'react'\r\n\r\nimport ChartLayout from '../../models/chart_layout'\r\nimport { useChartTypes } from './use-chart-types'\r\n\r\ninterface Props extends Pick {\r\n isPremium: boolean\r\n model: ChartLayout\r\n rounding: SelectListProps['rounding']\r\n}\r\n\r\nexport function ChartTypesSelect({ isPremium, model, ...props }: Props) {\r\n const { chartTypes, getCurrentType } = useChartTypes({ isPremium, model })\r\n const currentType = getCurrentType()\r\n const [selectedType, setSelectedType] = React.useState(currentType)\r\n const icon = chartTypes.find((item) => item.value === selectedType)?.icon\r\n\r\n React.useEffect(() => {\r\n setSelectedType(currentType)\r\n }, [currentType])\r\n\r\n return (\r\n item.value === selectedType)?.icon} className=\"text-gray-300\" />\r\n )\r\n }\r\n nativeSelect=\"mobile\"\r\n onChange={(item) => setSelectedType(item.value)}\r\n />\r\n )\r\n}\r\n","import * as React from 'react'\r\nimport { useLocation } from 'react-router-dom'\r\n\r\nimport { SpecificChartFunctionality } from '../../constants/common'\r\nimport ChartLayout from '../../models/chart_layout'\r\nimport { decodeQueryString, encodeQueryString } from '../../utils/query_string'\r\nimport {\r\n DEFAULT_TYPES,\r\n FREE_TYPES_QUOTE,\r\n FREE_TYPES_QUOTE_VALUES,\r\n QuoteLongToShortType,\r\n QuoteNodeChartTypes,\r\n QuoteShortToLongType,\r\n QuoteUrlChartTypes,\r\n TypeBaseOption,\r\n} from './utils'\r\n\r\nexport function useChartTypes({ isPremium, model }: { isPremium: boolean; model: ChartLayout }) {\r\n const location = useLocation()\r\n const { b, t, ta, ty, p = 'd', r } = decodeQueryString(location.search)\r\n const taInt = ta ? Number.parseInt(ta) : 1\r\n const isQuotePage = model.specificChartFunctionality === SpecificChartFunctionality.quotePage\r\n\r\n const getCurrentType = React.useCallback(() => {\r\n const defaultType =\r\n ((ty as QuoteUrlChartTypes | undefined) && QuoteShortToLongType[ty as QuoteUrlChartTypes]) ??\r\n (window.FinvizQuoteTypeCurrent as QuoteNodeChartTypes)\r\n\r\n return !isPremium && defaultType === QuoteNodeChartTypes.candlestick && taInt === 0\r\n ? QuoteNodeChartTypes.candlesticksimple\r\n : defaultType\r\n }, [isPremium, taInt, ty])\r\n\r\n const generateRouterPath = React.useCallback(\r\n (type: QuoteNodeChartTypes) => {\r\n if (isPremium || FREE_TYPES_QUOTE_VALUES.includes(type)) {\r\n return `${location.pathname}?${encodeQueryString({\r\n b,\r\n t,\r\n r,\r\n ty:\r\n type === QuoteNodeChartTypes.candlesticksimple\r\n ? QuoteLongToShortType.candlestick\r\n : QuoteLongToShortType[type],\r\n ta: type === QuoteNodeChartTypes.candlestick ? '1' : '0',\r\n p,\r\n })}`\r\n }\r\n return `/elite.ashx?${encodeQueryString({\r\n utm_source: 'finviz',\r\n utm_medium: 'banner',\r\n utm_campaign: 'quote-chart-type-select',\r\n })}`\r\n },\r\n [isPremium, location.pathname, b, t, r, p]\r\n )\r\n\r\n const chartTypes = React.useMemo(() => {\r\n const options = isPremium || !isQuotePage ? DEFAULT_TYPES : FREE_TYPES_QUOTE\r\n\r\n return options.map((item) => ({\r\n ...item,\r\n href: generateRouterPath(item.value as QuoteNodeChartTypes),\r\n reloadDocument: !isPremium,\r\n })) as TypeBaseOption[]\r\n }, [generateRouterPath, isPremium, isQuotePage])\r\n\r\n return { getCurrentType, chartTypes }\r\n}\r\n","import { Paragraph, withSuspense } from '@finviz/website'\r\nimport classnames from 'classnames'\r\nimport * as React from 'react'\r\n\r\nimport math from '../../helpers/math'\r\nimport { useModelState } from '../../model-hooks/use-model-state'\r\nimport { QuoteFetchType } from '../../models/quote/constants'\r\nimport { getTickerChange } from '../../utils/chart'\r\nimport { useChartLayoutGlobalModelAsync } from '../../utils/useChartLayoutGlobalModelAsync'\r\n\r\ninterface Props {\r\n chartIndex: number\r\n}\r\n\r\ninterface ChangeLabelProps {\r\n children: React.ReactNode\r\n changePoints: number\r\n isTiny: boolean\r\n}\r\n\r\nconst CHANGE_UPATE_EVENTS = ['change', 'update']\r\nconst QUOTE_MODEL_CHANGE_EVENTS = [...CHANGE_UPATE_EVENTS, ...Object.values(QuoteFetchType)]\r\n\r\nfunction ChangeLabel({ children, changePoints, isTiny }: ChangeLabelProps) {\r\n return (\r\n 0,\r\n 'text-red-400': changePoints < 0,\r\n })}\r\n >\r\n {children}\r\n \r\n )\r\n}\r\n\r\nexport function DailyChangeDisplayComponent({ chartIndex }: Props) {\r\n const { chartLayoutModel } = useChartLayoutGlobalModelAsync()\r\n const chartModel = useModelState(chartLayoutModel?.getAllCharts()[chartIndex] ?? null, {\r\n watchProperties: ['quote'],\r\n listenOnEvents: CHANGE_UPATE_EVENTS,\r\n })\r\n const quoteModel = useModelState(chartModel?.quote() ?? null, {\r\n watchProperties: ['lastClose', 'prevClose', 'afterClose'],\r\n listenOnEvents: QUOTE_MODEL_CHANGE_EVENTS,\r\n })\r\n\r\n const tickerChange = quoteModel && getTickerChange({ data: quoteModel })\r\n const isTiny =\r\n !!tickerChange?.tickerChange &&\r\n math.getInstrumentDecimalPlaces({\r\n instrument: quoteModel!.instrument,\r\n value: quoteModel!.lastClose,\r\n }) >= 6\r\n\r\n return (\r\n \r\n {tickerChange?.tickerChange && (\r\n <>\r\n {tickerChange.tickerAfterChange && (\r\n \r\n {tickerChange.tickerAfterChange.string}\r\n \r\n )}\r\n \r\n {tickerChange.tickerChange.string}\r\n \r\n \r\n )}\r\n \r\n )\r\n}\r\n\r\nexport const DailyChangeDisplay = React.memo(\r\n withSuspense(DailyChangeDisplayComponent),\r\n (prevProps, nextProps) => prevProps.chartIndex === nextProps.chartIndex\r\n)\r\n","import { Button, ButtonComponentProps, setCookieRequest } from '@finviz/website'\r\nimport * as React from 'react'\r\n\r\nimport { SpecificChartFunctionality } from '../../constants/common'\r\nimport utils from '../../utils'\r\nimport { DRAWING_COOKIE_NAME, getIsDrawingEnabled } from '../../utils/chart'\r\nimport { decodeQueryString, encodeQueryString } from '../../utils/query_string'\r\n\r\nconst utmCampaign: Partial> = {\r\n [SpecificChartFunctionality.quotePage]: 'quote-draw-button',\r\n [SpecificChartFunctionality.futuresPage]: 'futures-interactive-chart',\r\n [SpecificChartFunctionality.forexPage]: 'forex-interactive-chart',\r\n [SpecificChartFunctionality.cryptoPage]: 'crypto-interactive-chart',\r\n}\r\n\r\nconst testId: Partial> = {\r\n [SpecificChartFunctionality.quotePage]: 'quote-toggle-draw-btn',\r\n [SpecificChartFunctionality.futuresPage]: 'futures-interactive',\r\n [SpecificChartFunctionality.forexPage]: 'forex-interactive',\r\n [SpecificChartFunctionality.cryptoPage]: 'crypto-interactive',\r\n}\r\n\r\ninterface DrawButtonProps extends Pick {\r\n isPremium: boolean\r\n specificChartFunctionality: SpecificChartFunctionality\r\n active?: boolean\r\n}\r\n\r\nexport function DrawButton({\r\n isPremium,\r\n specificChartFunctionality,\r\n ...props\r\n}: React.PropsWithChildren) {\r\n const buttonProps = React.useMemo(() => {\r\n if (!isPremium) {\r\n return {\r\n as: 'a' as const,\r\n href: `/elite.ashx?${encodeQueryString({\r\n utm_source: 'finviz',\r\n utm_medium: 'banner',\r\n utm_campaign: utmCampaign[specificChartFunctionality],\r\n })}`,\r\n }\r\n }\r\n\r\n return {\r\n onClick: (ev: React.MouseEvent) => {\r\n ev.preventDefault()\r\n const newValue = getIsDrawingEnabled() ? 'off' : 'on'\r\n\r\n setCookieRequest(DRAWING_COOKIE_NAME, newValue)\r\n .catch(() => {\r\n // fallback to JS otherwise draw toggle won't work if API don't work\r\n const expires = new Date()\r\n expires.setMonth(expires.getMonth() + 1)\r\n utils.setCookie(DRAWING_COOKIE_NAME, newValue, expires)\r\n })\r\n .finally(() => {\r\n const { i: idea, ...rest } = decodeQueryString()\r\n if (idea) {\r\n document.location = `quote.ashx?${encodeQueryString(rest)}`\r\n } else {\r\n document.location.reload()\r\n }\r\n })\r\n },\r\n }\r\n }, [isPremium, specificChartFunctionality])\r\n\r\n return (\r\n \r\n )\r\n}\r\n","import { Button, ButtonComponentProps } from '@finviz/website'\r\nimport * as React from 'react'\r\nimport { useLocation } from 'react-router-dom'\r\n\r\nimport { SpecificChartFunctionality } from '../../constants/common'\r\nimport ChartLayout from '../../models/chart_layout'\r\nimport { decodeQueryString, encodeQueryString } from '../../utils/query_string'\r\n\r\nfunction getTickersString(tickers: string[], tickersCount: number) {\r\n return Array.from({ length: Math.min(tickersCount, 6) })\r\n .map((_, index) => tickers[index] ?? tickers[tickers.length - 1])\r\n .join(',')\r\n}\r\n\r\nfunction getLayoutType(tickersCount: number) {\r\n switch (tickersCount) {\r\n case 0: // shouldn't happen\r\n case 1:\r\n return '1h1v'\r\n case 2:\r\n return '2h1v'\r\n case 3:\r\n return '3h1v'\r\n case 4:\r\n return '2h2v'\r\n case 5:\r\n default:\r\n // 6 and more\r\n return '3h2v'\r\n }\r\n}\r\n\r\nconst utmCampaign: Partial> = {\r\n [SpecificChartFunctionality.quotePage]: 'quote-fullscreen-button',\r\n [SpecificChartFunctionality.futuresPage]: 'futures-fullscreen-button',\r\n [SpecificChartFunctionality.forexPage]: 'forex-fullscreen-button',\r\n [SpecificChartFunctionality.cryptoPage]: 'crypto-fullscreen-button',\r\n}\r\n\r\ninterface FullscreenButtonProps extends Pick {\r\n model: ChartLayout\r\n isPremium: boolean\r\n title?: string\r\n}\r\n\r\nexport function FullscreenButton({ model, isPremium, ...props }: React.PropsWithChildren) {\r\n const location = useLocation()\r\n const { i, p = 'd', r } = decodeQueryString(location.search)\r\n const urlTickers = model\r\n .charts()\r\n .all()\r\n .map((chart) => chart.quote().getRawTicker())\r\n\r\n return (\r\n p).join(','),\r\n l: getLayoutType(urlTickers.length),\r\n r,\r\n })}`\r\n : `/elite.ashx?${encodeQueryString({\r\n utm_source: 'finviz',\r\n utm_medium: 'banner',\r\n utm_campaign: utmCampaign[model.specificChartFunctionality],\r\n })}`\r\n }\r\n />\r\n )\r\n}\r\n","import {\r\n Button,\r\n Dialog,\r\n Dropdown,\r\n DropdownItem,\r\n Icon,\r\n Spinner,\r\n Search as WebsiteSearchComponent,\r\n createAlertAsyncModule,\r\n saveToPortfolioAsyncModule,\r\n useDialogState,\r\n} from '@finviz/website'\r\nimport * as React from 'react'\r\n\r\nimport { Instrument } from '../../../types/shared'\r\nimport { useAsyncModule } from '../../utils/async-modules-utils'\r\n\r\ninterface SearchProps {\r\n ticker: string\r\n instrument: Instrument\r\n onTickerSelected: (ticker: string) => void\r\n chartIndex: number\r\n}\r\n\r\nexport default function Search({ ticker, instrument, onTickerSelected, chartIndex }: SearchProps) {\r\n const saveToPortfolioDialogState = useDialogState()\r\n const isSaveToPortfolioVisible = saveToPortfolioDialogState.useState('open')\r\n const createAlertDialogState = useDialogState()\r\n const isCreateAlertVisible = createAlertDialogState.useState('open')\r\n const [saveToPortfolioModule, { isLoading: isLoadingSaveToPortfolio }] = useAsyncModule({\r\n ...saveToPortfolioAsyncModule,\r\n shouldLoadModule: isSaveToPortfolioVisible,\r\n onError: () => saveToPortfolioDialogState.hide(),\r\n })\r\n const [createAlertModule, { isLoading: isLoadingCreateAlert }] = useAsyncModule({\r\n ...createAlertAsyncModule,\r\n shouldLoadModule: isCreateAlertVisible,\r\n onError: () => createAlertDialogState.hide(),\r\n })\r\n const SaveToPortfolio = saveToPortfolioModule?.SaveToPortfolio\r\n const CreateAlert = createAlertModule?.CreateAlert\r\n\r\n const detailLink = React.useMemo(() => {\r\n const formattedTicker = ticker.replace('@', '')\r\n\r\n switch (instrument) {\r\n case Instrument.Stock:\r\n return `/quote.ashx?t=${formattedTicker}`\r\n case Instrument.Futures:\r\n return `/futures_charts.ashx?t=${formattedTicker}`\r\n case Instrument.Forex:\r\n return `/forex_charts.ashx?t=${formattedTicker}`\r\n case Instrument.Crypto:\r\n return `/crypto_charts.ashx?t=${formattedTicker}`\r\n }\r\n }, [ticker, instrument])\r\n\r\n return (\r\n

\r\n }\r\n />\r\n }\r\n >\r\n {\r\n window.gtag?.('event', 'click', { event_category: 'open-stock-detail' })\r\n }}\r\n >\r\n {instrument === Instrument.Stock ? 'Open Stock Detail' : 'Open Detail'}\r\n \r\n {instrument === Instrument.Stock && (\r\n {\r\n saveToPortfolioDialogState.show()\r\n window.gtag?.('event', 'click', { event_category: 'save-to-portfolio' })\r\n }}\r\n >\r\n Save to Portfolio\r\n \r\n )}\r\n {instrument === Instrument.Stock && (\r\n {\r\n createAlertDialogState.show()\r\n window.gtag?.('event', 'click', { event_category: 'create-alert' })\r\n }}\r\n >\r\n Create Alert\r\n \r\n )}\r\n \r\n }\r\n />\r\n \r\n {isLoadingSaveToPortfolio && (\r\n
\r\n \r\n
\r\n )}\r\n {SaveToPortfolio && }\r\n
\r\n \r\n {isLoadingCreateAlert && (\r\n
\r\n \r\n
\r\n )}\r\n {CreateAlert && }\r\n
\r\n
\r\n )\r\n}\r\n","import {\r\n ButtonRoundingType,\r\n ButtonSizeType,\r\n CustomDateRange,\r\n Heading,\r\n TimeframeBar,\r\n ZIndexContext,\r\n useCustomDateRangeDialog,\r\n useFavoriteTimeframes,\r\n} from '@finviz/website'\r\nimport classnames from 'classnames'\r\nimport React from 'react'\r\nimport { useNavigate } from 'react-router-dom'\r\n\r\nimport { ChartEditorEnum, SpecificChartFunctionality, TIMEFRAME } from '../../constants/common'\r\nimport { useModelState } from '../../model-hooks/use-model-state'\r\nimport Chart from '../../models/chart'\r\nimport { IdeasDropdown } from '../header/ideas_dropdown'\r\nimport { Publish } from '../header/publish'\r\nimport { TourButton } from '../header/tour_button'\r\nimport { ChartTypesSelect } from './chart-type-select'\r\nimport { DailyChangeDisplay } from './daily-change-display'\r\nimport { DrawButton } from './draw-button'\r\nimport { FullscreenButton } from './fullscreen-button'\r\nimport Search from './search'\r\nimport { ChartSettingsButton } from './settings-button'\r\nimport { useChartControls } from './use-chart-controls'\r\nimport { useChartModelCustomDateRangeValues } from './use-chart-model-custom-date-range-values'\r\n\r\ninterface SettingsComponentProps {\r\n chartModel: Chart\r\n chartIndex: number\r\n}\r\n\r\nconst isPremium = window.FinvizSettings.hasUserPremium\r\nconst hasRedesignEnabled = window.FinvizSettings.hasRedesignEnabled\r\n\r\nexport function ChartControls({ chartIndex, chartModel: unwatchedChartModel }: SettingsComponentProps) {\r\n const rounding: ButtonRoundingType | undefined = hasRedesignEnabled ? undefined : 'none'\r\n // This memo is required for publish, otherwise it ends up in a loop\r\n const chartLayout = React.useMemo(() => unwatchedChartModel.chart_layout(), [unwatchedChartModel])\r\n const chartModel = useModelState(unwatchedChartModel, {\r\n watchProperties: ['ticker', 'quote', 'dateRange'],\r\n })\r\n const { instrument } = chartModel?.quote() || {}\r\n const isQuotePage = chartLayout.specificChartFunctionality === SpecificChartFunctionality.quotePage\r\n\r\n const navigate = useNavigate()\r\n const { favoriteTimeframes, toggleFavoriteTimeframe } = useFavoriteTimeframes()\r\n const { isLoading } = useChartControls({\r\n chartModel,\r\n isInteractive: true,\r\n })\r\n const {\r\n anchorDate,\r\n generateChartLayoutRouterPath,\r\n timeframeGroupsWithHref,\r\n dateRangeGroupsWithHref,\r\n isFetching,\r\n handleCustomDateRangeValidation,\r\n } = useChartModelCustomDateRangeValues({ chartModel, isPremium })\r\n const { onDialogSubmit, customDateRangeDialogState, handleDateRangeSelect, getDateRangeTimeframe } =\r\n useCustomDateRangeDialog({\r\n instrument,\r\n anchorDate,\r\n pathGenerator: generateChartLayoutRouterPath,\r\n })\r\n\r\n const handleTickerSelect = React.useCallback(\r\n (ticker: string) => {\r\n const upperCaseTicker = ticker.toUpperCase()\r\n\r\n navigate(\r\n generateChartLayoutRouterPath({\r\n ticker: upperCaseTicker,\r\n timeframe: chartModel.timeframe,\r\n dateRange: chartModel.dateRange,\r\n })\r\n )\r\n },\r\n [chartModel, generateChartLayoutRouterPath, navigate]\r\n )\r\n\r\n async function handleCustomRangeSubmit(values: { dateRange: string | null }) {\r\n const dateRangeTimeframe = values.dateRange\r\n ? getDateRangeTimeframe(values.dateRange)\r\n : { value: '', timeframe: chartModel.timeframe }\r\n\r\n if (dateRangeTimeframe === null) {\r\n return\r\n } else if (dateRangeTimeframe.value) {\r\n const isValid = await handleCustomDateRangeValidation(dateRangeTimeframe)\r\n if (!isValid) {\r\n return\r\n }\r\n }\r\n\r\n onDialogSubmit(dateRangeTimeframe)\r\n }\r\n\r\n const timeframeBarProps = React.useMemo(\r\n () => ({\r\n size: 'medium' as ButtonSizeType,\r\n chartIndex: chartIndex,\r\n timeFrameGroups: timeframeGroupsWithHref(isPremium),\r\n dateRangeGroups: dateRangeGroupsWithHref({ isPremium, customRange: chartModel.dateRange, instrument }),\r\n selectedTimeframe: chartModel.timeframe,\r\n onTimeframeSelect: () => {},\r\n selectedDateRange: chartModel.dateRange,\r\n favoriteTimeframes: favoriteTimeframes,\r\n loadingTimeframe: isLoading ? chartModel.timeframe : undefined,\r\n onDateRangeSelect: handleDateRangeSelect,\r\n onCustomDateRangeClick: () => {\r\n if (isPremium) customDateRangeDialogState.show()\r\n },\r\n isFavoritesEnabled: isPremium,\r\n onFavoriteTimeframeToggle: ({ value }: { value: TIMEFRAME | 'intraday' }) => {\r\n toggleFavoriteTimeframe(value)\r\n },\r\n }),\r\n [\r\n chartIndex,\r\n chartModel.dateRange,\r\n chartModel.timeframe,\r\n customDateRangeDialogState,\r\n dateRangeGroupsWithHref,\r\n favoriteTimeframes,\r\n handleDateRangeSelect,\r\n instrument,\r\n isLoading,\r\n timeframeGroupsWithHref,\r\n toggleFavoriteTimeframe,\r\n ]\r\n )\r\n\r\n if (chartLayout.specificChartFunctionality === SpecificChartFunctionality.chartPage) {\r\n return (\r\n \r\n
\r\n {chartModel.chart_layout().canChangeTicker && (\r\n \r\n )}\r\n\r\n \r\n\r\n \r\n\r\n \r\n
\r\n
\r\n )\r\n }\r\n\r\n const hasTimeframe = chartLayout.editors.includes(ChartEditorEnum.timeframe)\r\n\r\n return (\r\n \r\n
\r\n {!isQuotePage && (\r\n \r\n {chartModel.quote().name ?? chartModel.ticker}\r\n \r\n )}\r\n {chartLayout.editors.includes(ChartEditorEnum.tools) && (\r\n \r\n Draw\r\n \r\n )}\r\n {chartLayout.editors.includes(ChartEditorEnum.ideas) && (\r\n \r\n Ideas\r\n \r\n )}\r\n {!hasTimeframe && (\r\n
\r\n \r\n
\r\n )}\r\n
\r\n\r\n {hasTimeframe && (\r\n
\r\n
\r\n
\r\n \r\n
\r\n
\r\n \r\n \r\n
\r\n
\r\n
\r\n )}\r\n\r\n
\r\n {chartLayout.editors.includes(ChartEditorEnum.publish) && (\r\n \r\n Share\r\n \r\n )}\r\n {isQuotePage && (\r\n \r\n )}\r\n \r\n {!isQuotePage && 'Fullscreen'}\r\n \r\n {chartLayout.editors.includes(ChartEditorEnum.settings) && (\r\n \r\n {!isQuotePage && 'Settings'}\r\n \r\n )}\r\n {!isQuotePage && (\r\n
\r\n \r\n
\r\n )}\r\n
\r\n \r\n )\r\n}\r\n","import Spine from '@finviz/spine'\r\nimport { ContextMenuItem } from '@finviz/website'\r\n\r\nexport type CallbacksType = {\r\n onFullyOpen: () => void\r\n onFullyClosed: () => void\r\n onBeforeItemClick: () => void\r\n}\r\n\r\nclass ContextMenu extends Spine.Model {\r\n static initClass() {\r\n this.configure('ContextMenu', 'shown', 'config', 'anchorRect', 'callbacks')\r\n }\r\n\r\n declare shown: boolean\r\n declare config: ContextMenuItem[]\r\n declare anchorRect: { x: number; y: number }\r\n declare callbacks: CallbacksType | undefined\r\n}\r\n\r\nContextMenu.initClass()\r\n\r\nconst contextMenu = ContextMenu.create() as ContextMenu\r\ncontextMenu.save()\r\n\r\nexport default contextMenu\r\n","import { ContextMenu as ContextMenuComponent, useDropdownState } from '@finviz/website'\r\nimport React from 'react'\r\nimport * as ReactDOM from 'react-dom/client'\r\n\r\nimport { ObjectHash } from '../../types/shared'\r\nimport { useModelState } from '../model-hooks/use-model-state'\r\nimport model, { CallbacksType } from '../models/context_menu'\r\nimport { ready } from '../utils'\r\n\r\nfunction ContextMenu() {\r\n const watchedModel = useModelState(model, {\r\n watchProperties: ['shown', 'anchorRect', 'config', 'callbacks'],\r\n })\r\n const state = useDropdownState({ open: watchedModel.shown })\r\n\r\n return (\r\n ev.type !== 'contextmenu'}\r\n state={state}\r\n items={watchedModel.config?.map((item) => ({\r\n ...item,\r\n onClick: () => {\r\n watchedModel.callbacks?.onBeforeItemClick()\r\n if ('onClick' in item) {\r\n item.onClick?.()\r\n }\r\n },\r\n }))}\r\n getAnchorRect={() => watchedModel.anchorRect}\r\n onClose={() => model.updateAttribute('shown', false)}\r\n onFullyOpen={watchedModel.callbacks?.onFullyOpen}\r\n onFullyClosed={watchedModel.callbacks?.onFullyClosed}\r\n data-testid=\"charts-context-menu-body\"\r\n backdrop={\r\n {\r\n ev.preventDefault()\r\n ev.stopPropagation()\r\n }}\r\n />\r\n }\r\n />\r\n )\r\n}\r\n\r\nready(() => {\r\n const rootEl = document.querySelector('.context-menu')\r\n if (rootEl) {\r\n const root = ReactDOM.createRoot(rootEl!)\r\n root.render()\r\n }\r\n})\r\n\r\nconst contextMenuControl = {\r\n show: (event: MouseEvent | React.MouseEvent, config: ObjectHash, callbacks: CallbacksType) => {\r\n model.updateAttributes({\r\n shown: true,\r\n config: config,\r\n callbacks,\r\n anchorRect: {\r\n x: event.clientX,\r\n y: event.clientY,\r\n },\r\n })\r\n },\r\n}\r\n\r\nexport default contextMenuControl\r\n","import { Delayed, DialogBody, Popover, PopoverAnchor, Spinner, usePopoverState } from '@finviz/website'\r\nimport classNames from 'classnames'\r\nimport React from 'react'\r\n\r\nimport { useModelState } from '../../model-hooks/use-model-state'\r\nimport ChartModel from '../../models/chart'\r\nimport Utils from '../../utils'\r\nimport { useAsyncModule } from '../../utils/async-modules-utils'\r\nimport { useClickAway } from '../../utils/use-click-away'\r\nimport { chartEventsAsyncModule } from '../chart-events/async-modules'\r\n\r\nconst isMobile = Utils.isMobile()\r\n\r\ninterface ChartEventPopoverWithStateProps {\r\n chartModel: ChartModel\r\n}\r\n\r\nexport function ChartEventPopoverWithState({ chartModel }: ChartEventPopoverWithStateProps) {\r\n const unwatchedChartLayout = React.useMemo(() => chartModel.chart_layout() ?? null, [chartModel])\r\n const { activeChartEvent, theme } = useModelState(unwatchedChartLayout, { watchProperties: ['activeChartEvent'] })\r\n const lastEventId = React.useRef(activeChartEvent?.id)\r\n const popoverState = usePopoverState({ placement: 'top' })\r\n const isPopoverMounted = popoverState.useState('mounted')\r\n const [style, setStyle] = React.useState({ top: 0, left: 0 })\r\n const [chartEventsModule] = useAsyncModule({\r\n ...chartEventsAsyncModule,\r\n shouldLoadModule: isPopoverMounted,\r\n errorSeverity: 'medium',\r\n onError: () => popoverState.hide(),\r\n })\r\n const isChartEventOfThisChart = activeChartEvent?.pane().chart().eql(chartModel)\r\n const [data, setData] = React.useState(null)\r\n const clickAwayRef = useClickAway(() => {\r\n const isAnyBadgeHovered = !!chartModel\r\n .getChartPane()\r\n ?.getAllChartEvents()\r\n .some((chartEvent) => chartEvent.instance.isHovered)\r\n\r\n if (!isAnyBadgeHovered && activeChartEvent && isChartEventOfThisChart) {\r\n activeChartEvent.instance.toggleIsOpen(false)\r\n }\r\n // Due to the fact that chart events logic depends heavily on hover state which isn't really present on touch devices\r\n // we need to mimic that state for touch devices, this enables chart event closed on click outside and counterpart in\r\n // chart-events.ts allow chart event to be open\r\n if (activeChartEvent && isMobile) {\r\n activeChartEvent.instance.setIsHovered(false)\r\n }\r\n }, !!activeChartEvent && isChartEventOfThisChart)\r\n // This is intentional, it doesn't need to be in useEffect, it would just call effect function which is redundant\r\n clickAwayRef.current = popoverState.useState('popoverElement')\r\n const popoverShow = popoverState.show\r\n const popoverHide = popoverState.hide\r\n\r\n React.useEffect(() => {\r\n lastEventId.current = activeChartEvent?.id\r\n if (!activeChartEvent?.instance.isOpen || !isChartEventOfThisChart) {\r\n if (!isPopoverMounted) {\r\n return setData(null)\r\n }\r\n return popoverHide()\r\n }\r\n if (!isChartEventOfThisChart) return\r\n const { top, left } = activeChartEvent.instance\r\n const newData = activeChartEvent.getChartEventData()\r\n if (newData?.elementId !== data?.elementId) {\r\n setData({\r\n ...newData,\r\n badgeType: activeChartEvent.instance.getChartEvenBadgeType(),\r\n })\r\n }\r\n\r\n if (style.top !== top || style.left !== left) {\r\n setStyle({ top, left })\r\n }\r\n if (!isPopoverMounted) {\r\n popoverShow()\r\n }\r\n }, [\r\n activeChartEvent,\r\n data?.elementId,\r\n isChartEventOfThisChart,\r\n isPopoverMounted,\r\n popoverHide,\r\n popoverShow,\r\n popoverState,\r\n style.left,\r\n style.top,\r\n ])\r\n\r\n return (\r\n <>\r\n \r\n {data && (\r\n \r\n \r\n {chartEventsModule ? (\r\n \r\n ) : (\r\n
\r\n \r\n \r\n \r\n
\r\n )}\r\n \r\n \r\n )}\r\n \r\n )\r\n}\r\n","import React from 'react'\r\n\r\nimport Utils from '../utils'\r\n\r\nexport function useClickAway(callback: (event: MouseEvent | TouchEvent) => void, isListening = true) {\r\n const ref = React.useRef(null)\r\n const refCallback = React.useRef(callback)\r\n\r\n React.useLayoutEffect(() => {\r\n refCallback.current = callback\r\n })\r\n\r\n React.useEffect(() => {\r\n if (!isListening) {\r\n return\r\n }\r\n const isMobile = Utils.isMobile()\r\n const handler = (e: MouseEvent | TouchEvent) => {\r\n const element = ref.current\r\n if (element && e.target && !element.contains(e.target as HTMLElement)) {\r\n refCallback.current(e)\r\n }\r\n }\r\n\r\n document.addEventListener(isMobile ? 'touchstart' : 'mousedown', handler)\r\n\r\n return () => {\r\n document.removeEventListener(isMobile ? 'touchstart' : 'mousedown', handler)\r\n }\r\n }, [callback, isListening])\r\n\r\n return ref\r\n}\r\n","import { Button, ButtonGroup, Delayed, Icon, Spinner } from '@finviz/website'\r\nimport React from 'react'\r\n\r\nimport { useModelState } from '../../model-hooks/use-model-state'\r\nimport Chart from '../../models/chart'\r\nimport { QuoteFetchType } from '../../models/quote/constants'\r\nimport { useIsMounted } from '../../utils/use-is-mounted'\r\n\r\ninterface LoadLatestDataButtonProps {\r\n chartModel: Chart\r\n}\r\n\r\nexport function LoadLatestDataButton({ chartModel: chartModelUnwatched }: LoadLatestDataButtonProps) {\r\n const getIsMounted = useIsMounted()\r\n const chartModel = useModelState(chartModelUnwatched, { watchProperties: ['quote'] })\r\n const quoteModel = useModelState(chartModel.quote(), { watchProperties: ['isFetching'] })\r\n const [hasNewDataAvailable, setHasNewDataAvailable] = React.useState(false)\r\n\r\n React.useEffect(() => {\r\n if (!chartModel.getRefreshInterval()) {\r\n // We will do a check here if we have correct new data\r\n chartModel\r\n .quote()\r\n .isPossibleToFetchSequentialData()\r\n .then((hasNewData) => {\r\n if (getIsMounted()) {\r\n setHasNewDataAvailable(hasNewData)\r\n }\r\n })\r\n }\r\n // We need to run it only on mount\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n }, [])\r\n\r\n const handleLoadLatestData = async () => {\r\n const promises = chartModel\r\n .getAllQuotes()\r\n .map(async (quote) => quote.fetchData({ fetchType: QuoteFetchType.NewerData }))\r\n chartModel.updateAttributes({ refreshData: true })\r\n await Promise.all(promises)\r\n if (getIsMounted()) {\r\n setHasNewDataAvailable(false)\r\n window.gtag?.('event', 'load-latest-data', { event_category: 'ideas' })\r\n }\r\n }\r\n\r\n if (!hasNewDataAvailable) {\r\n return null\r\n }\r\n\r\n return (\r\n \r\n }>\r\n \r\n \r\n ) : (\r\n 'refresh'\r\n )\r\n }\r\n disabled={quoteModel?.isFetching}\r\n title=\"Load latest data\"\r\n onClick={handleLoadLatestData}\r\n data-testid=\"load-latest-data-button\"\r\n >\r\n Load latest data\r\n \r\n \r\n )\r\n}\r\n","// Copy if this file is in Website repo in Website/js/main/hooks/ folder\r\nimport * as React from 'react'\r\n\r\nexport function useIsMounted() {\r\n const isMountedRef = React.useRef(false)\r\n const getIsMounted = React.useCallback(() => isMountedRef.current, [])\r\n\r\n React.useEffect(() => {\r\n isMountedRef.current = true\r\n return () => {\r\n isMountedRef.current = false\r\n }\r\n }, [])\r\n\r\n return getIsMounted\r\n}\r\n","import { Button, ButtonGroup, ButtonSizeType, Icon } from '@finviz/website'\r\nimport classnames from 'classnames'\r\nimport debounce from 'lodash.debounce'\r\nimport React from 'react'\r\n\r\nimport { useModelState } from '../../model-hooks/use-model-state'\r\nimport Chart from '../../models/chart'\r\nimport Utils from '../../utils'\r\nimport { getLeftOffset } from '../renderUtils'\r\nimport { LoadLatestDataButton } from './load-latest-data-button'\r\n\r\nexport const ZOOM_CONTROLS_ACTIVE_CLASS = 'is-active'\r\nexport const ZOOM_CONTROLS_IS_IN_AREA_CLASS = 'is-in-area'\r\n\r\nconst buttonCommonProps: { size: ButtonSizeType; className: string; contentClass: string } = {\r\n size: 'none',\r\n className: 'w-7 h-6',\r\n contentClass: 'flex justify-center',\r\n}\r\n\r\nconst isMobile = Utils.isMobile()\r\n\r\ninterface ZoomControlsProps {\r\n zoomControlsRef: React.RefObject\r\n isVisible: boolean\r\n chartModel: Chart\r\n onZoomIn: () => void\r\n onZoomOut: () => void\r\n onZoomReset: () => void\r\n}\r\n\r\nconst getDefaultLeftOffset = (chartModel: Chart) =>\r\n getLeftOffset({\r\n quote: chartModel.quote(),\r\n chartModel,\r\n config: {},\r\n })\r\n\r\nexport function ZoomControls({\r\n zoomControlsRef,\r\n chartModel,\r\n isVisible,\r\n onZoomIn,\r\n onZoomOut,\r\n onZoomReset,\r\n}: ZoomControlsProps) {\r\n const chartLayoutModel = useModelState(chartModel.chart_layout(), { watchProperties: ['idea'] })\r\n const [isGoToRecentVisible, setIsGoToRecentVisible] = React.useState(\r\n () => chartModel.leftOffset !== getDefaultLeftOffset(chartModel)\r\n )\r\n const { defaultZoomFactor } = chartLayoutModel\r\n const [isZoomResetVisible, setIsZoomResetVisible] = React.useState(chartModel.zoomFactor !== defaultZoomFactor)\r\n const handleGoToMostRecent = React.useCallback(() => {\r\n chartModel.updateAttributes({ leftOffset: getDefaultLeftOffset(chartModel), dateRange: null })\r\n }, [chartModel])\r\n\r\n React.useEffect(() => {\r\n const handleChartModelChangeDebounced = debounce(\r\n () => {\r\n setIsZoomResetVisible(chartModel.zoomFactor !== defaultZoomFactor)\r\n setIsGoToRecentVisible(chartModel.leftOffset !== getDefaultLeftOffset(chartModel))\r\n },\r\n 100,\r\n { maxWait: 333 }\r\n )\r\n chartModel.bind('change', handleChartModelChangeDebounced)\r\n return () => {\r\n handleChartModelChangeDebounced.cancel()\r\n chartModel.unbind('change', handleChartModelChangeDebounced)\r\n }\r\n }, [defaultZoomFactor, chartModel])\r\n\r\n return (\r\n \r\n {!isMobile && (\r\n
\r\n {isZoomResetVisible && (\r\n
\r\n \r\n \r\n \r\n \r\n \r\n
\r\n )}\r\n \r\n \r\n \r\n \r\n\r\n \r\n \r\n
\r\n )}\r\n\r\n
\r\n {!!chartLayoutModel.idea?.id && }\r\n\r\n {isGoToRecentVisible && (\r\n \r\n \r\n \r\n \r\n \r\n )}\r\n
\r\n \r\n )\r\n}\r\n","import Spine from '@finviz/spine'\r\nimport { Button, Notification, NotificationContextType, Paragraph, withNotificationContext } from '@finviz/website'\r\nimport classnames from 'classnames'\r\nimport Hammer from 'hammerjs'\r\nimport debounce from 'lodash.debounce'\r\nimport React from 'react'\r\n\r\nimport { CustomSpineEvents, DrawingSpineOptionsEvent, EmptyObject, ObjectHash, PaneArea } from '../../../types/shared'\r\nimport CanvasElement from '../../canvas/element'\r\nimport ChartEvent from '../../chart-events/chart-event'\r\nimport { IndicatorType, ScaleType, SetVisibilityTo, SpecificChartFunctionality } from '../../constants/common'\r\nimport IndicatorElement from '../../indicators/indicator'\r\nimport { withElementStyleDialogState } from '../../modals/element_style'\r\nimport ChartModel from '../../models/chart'\r\nimport ChartEventElement from '../../models/chart-event-element'\r\nimport ElementModel from '../../models/element'\r\nimport MouseModel from '../../models/mouse'\r\nimport PaneModel from '../../models/pane'\r\nimport Quote from '../../models/quote'\r\nimport { handleRemoveIndicatorPane } from '../../models/utils'\r\nimport Utils, { isRedesignedPage } from '../../utils'\r\nimport { getContextWithCache } from '../../utils/canvas'\r\nimport { getBarWidthWithMargin, unmountCanvas } from '../../utils/chart'\r\nimport { setElementCursor } from '../../utils/cursor'\r\nimport { getValueInRange, isPrimaryClick } from '../../utils/helpers'\r\nimport { getInitialStoreDrawings } from '../autosave/utils'\r\nimport { CHART_LAYOUT_CHILD_CHANGE_EVENT } from '../chart_layout/constants'\r\nimport ContextMenu from '../context_menu'\r\nimport { getMinMaxLeftOffset, getSettings, recountScale, renderPane } from '../renderUtils'\r\nimport { DrawingTool } from '../toolbar/interfaces'\r\nimport { getChartAlt } from '../utils'\r\nimport { ChartEventPopoverWithState } from './chart-event-popover-with-state'\r\nimport { withPaneModel } from './with-pane-model'\r\nimport { ZOOM_CONTROLS_ACTIVE_CLASS, ZOOM_CONTROLS_IS_IN_AREA_CLASS, ZoomControls } from './zoom_controls'\r\n\r\n// Indicates how many time lower/higher can new scale be compared to original one\r\nconst ALLOWED_MIN_MAX_ZOOM = 10000\r\n\r\ninterface PaneProps {\r\n model: PaneModel\r\n chartModel: ChartModel\r\n activeTool: DrawingTool\r\n activeChartInteraction: string | null\r\n chartIndex: number\r\n paneIndex: number\r\n touchEventsDisabled: boolean\r\n onPaneClick?: (model: PaneModel) => void\r\n onZoomerReset: () => void\r\n onZoomerMouseDown: React.MouseEventHandler\r\n onZoomerTouchStart: React.TouchEventHandler\r\n onAddToZoomFactor: (data: { diff: number; shouldCalculateRightAlign: boolean }) => void\r\n onResizerMouseDown: (e: React.MouseEvent, model: PaneModel) => void\r\n onPaneDestroy: (paneId: string) => void\r\n setActiveChartInteraction: (value: string | null) => void\r\n openElementStyleDialog?: (element: CanvasElement | IndicatorElement) => void\r\n notificationContext: NotificationContextType\r\n}\r\n\r\ninterface PaneState {\r\n hasSeenCrossNotification: boolean\r\n}\r\n\r\nfunction toggleE2eRenderInProgress({ id, isInProgress }: { id: number; isInProgress: boolean }) {\r\n if (process.env.IS_E2E_TESTING) {\r\n window.rendersInProgress = window.rendersInProgress ?? []\r\n\r\n if (isInProgress) {\r\n window.isRenderInProgress = true\r\n window.rendersInProgress.push(id)\r\n } else {\r\n window.rendersInProgress = window.rendersInProgress.filter((progressId) => id !== progressId)\r\n\r\n if (window.rendersInProgress.length === 0) {\r\n window.isRenderInProgress = Date.now()\r\n }\r\n }\r\n }\r\n}\r\n\r\nclass Pane extends React.Component {\r\n rafId?: number | null = null\r\n crossRafId?: number | null = null\r\n quoteModel: Quote\r\n paneRef = React.createRef()\r\n scalerRef = React.createRef()\r\n zoomerRef = React.createRef()\r\n zoomControlsRef = React.createRef()\r\n canvasWrapperRef = React.createRef()\r\n canvasRef = React.createRef()\r\n crossCanvasRef = React.createRef()\r\n chartLayoutModel = this.props.chartModel.chart_layout()\r\n paneHammer!: HammerManager\r\n scalerHammer!: HammerManager\r\n zoomerHammer!: HammerManager\r\n canvasWrapperHammer!: HammerManager\r\n mouseDown = false\r\n lastClientX?: number\r\n lastClientY?: number\r\n currentViewRange: { min: number; max: number } | null = null\r\n lastX!: number\r\n lastY!: number\r\n lastActiveTool: DrawingTool\r\n scalerLastY: number | null = null\r\n isElementHovered = false\r\n hoveredElement: CanvasElement | null = null\r\n isMobile: boolean\r\n isDisableTouchCrossAvailable = true\r\n\r\n canvas: HTMLCanvasElement | null = null\r\n canvasCtx: CanvasRenderingContext2D | null = null\r\n crossCanvas: HTMLCanvasElement | null = null\r\n crossCanvasCtx: CanvasRenderingContext2D | null = null\r\n isIndicatorPane = false\r\n\r\n state: PaneState = {\r\n hasSeenCrossNotification: !!window.localStorage?.getItem('hasSeenCrossNotification'),\r\n }\r\n\r\n // expects chartModel, model, onResizerMouseDown, onPaneDestroy\r\n constructor(props: PaneProps) {\r\n super(props)\r\n\r\n this.quoteModel = this.props.chartModel.quote()\r\n props.model.updateAttribute('instance', this)\r\n props.model.bind('update', this.onModelUpdate)\r\n props.model\r\n .elements()\r\n .bind('create', this.onElementCreate)\r\n .bind('destroy', this.onElementDestroy)\r\n .bind('replace', this.onElementReplace)\r\n .bind('select', this.onElementSelect)\r\n .bind('makeClone', this.onElementClone)\r\n .bind('change', this.immediateRecountScaleOnChartIndicatorChange)\r\n .bind('change', debounce(this.recountScale, 50))\r\n props.model.bind(CustomSpineEvents.ManualChange, this.recountScale)\r\n\r\n props.model.chartEvents().bind('create', this.onElementCreate).bind('change', debounce(this.recountScale, 50))\r\n\r\n this.props.chartModel.bind('update', this.onChartUpdate)\r\n this.props.chartModel.bind(`change ${CustomSpineEvents.IndicatorsChange}`, this.recountScale)\r\n this.quoteModel.bind('change', this.recountScale)\r\n this.isMobile = !!Utils.isMobile()\r\n this.lastActiveTool = props.activeTool\r\n if (!MouseModel.pane()) {\r\n MouseModel.updateAttribute('pane', props.model)\r\n }\r\n this.isIndicatorPane = props.model.getIsIndicatorPane()\r\n this.recountScale()\r\n }\r\n\r\n componentDidMount() {\r\n const { model } = this.props\r\n this.chartLayoutModel.bind('theme', this.renderAll)\r\n this.chartLayoutModel.bind('theme', this.renderCross)\r\n\r\n const initialStoreDrawings = getInitialStoreDrawings() ?? []\r\n const elements = [...model.getAllElements(), ...model.getAllChartEvents(false)]\r\n elements.forEach((element) => {\r\n this.onElementCreate(element)\r\n if (element.isDrawing()) {\r\n const hasDrawingInInitialCache = initialStoreDrawings.some(({ elementId }) => element.elementId === elementId)\r\n if (hasDrawingInInitialCache) {\r\n element.instance?.updateScales()\r\n }\r\n element.instance.cachePointPositionTimestamp()\r\n } else if (element.isChartEvent()) {\r\n element.instance?.updateScales()\r\n }\r\n })\r\n\r\n model?.updateChartEventsZIndexes()\r\n\r\n this.canvas = this.canvasRef.current\r\n this.canvasCtx = getContextWithCache(this.canvasRef.current)\r\n this.crossCanvas = this.crossCanvasRef.current\r\n this.crossCanvasCtx = getContextWithCache(this.crossCanvasRef.current)\r\n\r\n this.paneHammer = new Hammer.Manager(this.paneRef.current!, { touchAction: 'none' })\r\n this.paneHammer.add(new Hammer.Press({ threshold: 5, time: 500 })) // chrome simulator \"long touch\" -> \"oncontextmenu\" is 680ms +- 2ms\r\n this.paneHammer.on('press', this.onPress)\r\n this.canvasWrapperHammer = new Hammer(this.canvasWrapperRef.current!, { touchAction: 'none' })\r\n this.canvasWrapperHammer.on('tap', this.onClick)\r\n this.canvasWrapperRef.current?.addEventListener('touchmove', this.onTouchMove, { passive: false })\r\n\r\n if (this.chartLayoutModel.scrollable || !this.isMobile) {\r\n if (this.scalerRef.current) {\r\n this.scalerHammer = new Hammer(this.scalerRef.current, { touchAction: 'none' })\r\n this.scalerHammer.on('doubletap', this.onScalerReset)\r\n }\r\n if (this.zoomerRef.current) {\r\n this.zoomerHammer = new Hammer(this.zoomerRef.current, { touchAction: 'none' })\r\n this.zoomerHammer.on('doubletap', this.props.onZoomerReset)\r\n }\r\n this.canvasWrapperHammer.on('doubletap', this.onDoubleClick)\r\n }\r\n\r\n this.onChartUpdate({ width: this.props.chartModel.width })\r\n this.onModelUpdate({ height: model.height })\r\n this.forceUpdate()\r\n this.chartLayoutModel.trigger(CHART_LAYOUT_CHILD_CHANGE_EVENT)\r\n }\r\n\r\n componentWillUnmount() {\r\n this.canvasWrapperRef.current?.removeEventListener('touchmove', this.onTouchMove)\r\n unmountCanvas(this.canvas)\r\n unmountCanvas(this.crossCanvas)\r\n this.props.chartModel.unbind('update', this.onChartUpdate)\r\n this.props.chartModel.unbind('change', this.recountScale)\r\n this.quoteModel.unbind('change', this.recountScale)\r\n }\r\n\r\n render() {\r\n const { activeTool, touchEventsDisabled, onPaneClick, paneIndex, chartIndex, model, chartModel } = this.props\r\n if (touchEventsDisabled) {\r\n this.paneHammer?.set({ touchAction: 'auto' })\r\n this.scalerHammer?.set({ touchAction: 'auto' })\r\n this.zoomerHammer?.set({ touchAction: 'auto' })\r\n this.canvasWrapperHammer?.set({ touchAction: 'auto' })\r\n } else {\r\n const touchAction = this.getIsHammerAllowScrollActive() ? 'auto' : 'none'\r\n this.scalerHammer?.set({ touchAction: 'none' })\r\n this.zoomerHammer?.set({ touchAction: 'none' })\r\n this.paneHammer?.set({ touchAction })\r\n this.canvasWrapperHammer?.set({ touchAction })\r\n }\r\n\r\n const isChartPane = model.getIsChartPane()\r\n\r\n return (\r\n onPaneClick?.(model)}\r\n onTouchStart={() => onPaneClick?.(model)}\r\n onContextMenu={this.onContextMenu}\r\n data-testid={`chart-${chartIndex}-pane-${paneIndex}`}\r\n >\r\n {isChartPane && }\r\n {paneIndex !== 0 && (\r\n this.props.onResizerMouseDown(e, model)}\r\n data-testid={`chart-${chartIndex}-pane-${paneIndex}-resizer`}\r\n />\r\n )}\r\n {this.chartLayoutModel.initialScrollable && (\r\n \r\n )}\r\n\r\n {this.chartLayoutModel.initialScrollable && isChartPane && (\r\n <>\r\n \r\n {\r\n this.props.onAddToZoomFactor({ diff: 0.1, shouldCalculateRightAlign: true })\r\n }}\r\n onZoomOut={() => {\r\n this.props.onAddToZoomFactor({ diff: -0.1, shouldCalculateRightAlign: true })\r\n }}\r\n onZoomReset={this.props.onZoomerReset}\r\n />\r\n \r\n )}\r\n \r\n {getChartAlt(this.quoteModel)}\r\n {this.chartLayoutModel.cross && }\r\n \r\n \r\n )\r\n }\r\n\r\n getIsHammerAllowScrollActive = () =>\r\n this.chartLayoutModel.specificChartFunctionality !== SpecificChartFunctionality.chartPage &&\r\n !this.chartLayoutModel.isTouchCrossActive &&\r\n !this.chartLayoutModel.scrollable\r\n\r\n onElementCreate = (el: ElementModel | ChartEventElement) => {\r\n el.instance.bind('change', this.renderAll)\r\n this.renderAll()\r\n }\r\n\r\n onElementReplace = (el: ElementModel, oldElementInstance: CanvasElement) => {\r\n oldElementInstance.unbind('change', this.renderAll)\r\n el.instance.bind('change', this.renderAll)\r\n if (oldElementInstance === this.props.model.selection && !this.chartLayoutModel.isDrawingModeContinuousActive) {\r\n this.setSelection(el.instance)\r\n } else {\r\n this.setSelection(null)\r\n }\r\n this.renderAll()\r\n }\r\n\r\n onElementDestroy = (el: ElementModel) => {\r\n const { type } = el.instance\r\n el.instance.unbind('change', this.renderAll)\r\n if (el.instance === this.props.model.selection) {\r\n this.setSelection(null)\r\n }\r\n if (type.startsWith('charts/') || type.startsWith('indicators/')) {\r\n this.props.onPaneDestroy(el['pane_id'])\r\n }\r\n this.renderAll()\r\n }\r\n\r\n onElementSelect = (el: ElementModel) => {\r\n this.setSelectedElement(el.instance)\r\n }\r\n\r\n onElementClone = (_: unknown, clonedElementInstance: CanvasElement) => {\r\n this.setSelectedElement(clonedElementInstance)\r\n }\r\n\r\n onModelUpdate = ({ height }: { height: number }) => {\r\n this.setCanvasSize({\r\n width: this.props.chartModel.width,\r\n height,\r\n })\r\n }\r\n\r\n onChartUpdate = ({ width }: { width: number }) => {\r\n const { model, chartModel } = this.props\r\n this.setCanvasSize({\r\n width,\r\n height: model.height,\r\n })\r\n const quote = chartModel.quote()\r\n if (!this.quoteModel.eql(quote)) {\r\n this.quoteModel.unbind('change', this.recountScale)\r\n if (quote) {\r\n this.quoteModel = quote\r\n this.quoteModel.bind('change', this.recountScale)\r\n }\r\n }\r\n }\r\n\r\n onZoomerMouseMove: React.MouseEventHandler = (e) => {\r\n if (!this.chartLayoutModel.scrollable || (this.isMobile && !this.chartLayoutModel.isTouchCrossActive)) return\r\n const area = this.getArea(e)\r\n MouseModel.updateAttributes({\r\n position: { x: area.x, y: null },\r\n pane: this.props.model,\r\n })\r\n }\r\n\r\n onMouseMoveOnScrolling = (event: TouchEvent | MouseEvent) => {\r\n if (this.props.activeChartInteraction) {\r\n return\r\n }\r\n\r\n let { clientX, clientY } = event as MouseEvent\r\n const { model } = this.props\r\n\r\n const isTouch = typeof TouchEvent !== 'undefined' && event instanceof TouchEvent\r\n if (isTouch && event.targetTouches?.length > 0) {\r\n clientX = event.targetTouches[0].clientX\r\n clientY = event.targetTouches[0].clientY\r\n }\r\n if (!model.selection && !this.chartLayoutModel.activeChartEvent) {\r\n if (this.lastClientX != null) {\r\n const dif = this.lastClientX - clientX\r\n this.addToLeftOffset(-dif)\r\n }\r\n if (model.scaleRange && this.lastClientY != null) {\r\n let { min, max } = model.scaleRange\r\n let difY\r\n switch (this.props.chartModel.scale) {\r\n case ScaleType.Logarithmic: {\r\n difY = this.lastClientY - clientY\r\n min = model.scale.y.invert(model.scale.y(min) + difY)\r\n max = model.scale.y.invert(model.scale.y(max) + difY)\r\n break\r\n }\r\n default: {\r\n difY = (this.lastClientY - clientY) * (model.scale.y.invert(0) - model.scale.y.invert(1))\r\n min -= difY\r\n max -= difY\r\n break\r\n }\r\n }\r\n\r\n model.updateAttribute('scaleRange', { min, max })\r\n this.recountScale()\r\n this.currentViewRange = this.props.model.getChartOrIndicatorElement()?.instance?.getMinMax?.() ?? null\r\n }\r\n }\r\n this.lastClientX = clientX\r\n this.lastClientY = clientY\r\n }\r\n\r\n onScalerTouchStart: React.TouchEventHandler = (e) => {\r\n if (!this.chartLayoutModel.scrollable || this.props.touchEventsDisabled) return\r\n if (this.chartLayoutModel.scrollable && e.targetTouches.length === 1) {\r\n this.onScalerMouseDown(e.targetTouches[0])\r\n }\r\n }\r\n\r\n onScalerTouchMove = (e: TouchEvent) => {\r\n if (this.chartLayoutModel.scrollable && e.targetTouches.length === 1) {\r\n this.onScalerMouseMove(e.targetTouches[0])\r\n }\r\n }\r\n\r\n onScalerTouchEnd = () => {\r\n if (this.chartLayoutModel.scrollable) {\r\n this.onScalerMouseUp()\r\n }\r\n }\r\n\r\n onScalerMouseEnter = () => {\r\n MouseModel.updateAttributes({\r\n position: null,\r\n pane: null,\r\n })\r\n }\r\n\r\n onScalerMouseDown = (event: React.MouseEvent | React.Touch) => {\r\n const { activeChartInteraction, setActiveChartInteraction, model } = this.props\r\n if ((event instanceof MouseEvent && event.button) || activeChartInteraction || !this.chartLayoutModel.scrollable) {\r\n return\r\n }\r\n setActiveChartInteraction('scaler')\r\n\r\n this.scalerLastY = event.clientY\r\n // here we need current domain scale or former \"nice\" value\r\n const [currentDomainMax, currentDomainMin] = model.scale.y.domain()\r\n this.currentViewRange = { min: currentDomainMin, max: currentDomainMax }\r\n document.addEventListener<'mousemove'>('mousemove', this.onScalerMouseMove)\r\n document.addEventListener('mouseup', this.onScalerMouseUp)\r\n document.addEventListener('touchmove', this.onScalerTouchMove)\r\n document.addEventListener('touchend', this.onScalerTouchEnd)\r\n }\r\n\r\n onScalerMouseMove = (event: MouseEvent | Touch) => {\r\n const { model, chartModel } = this.props\r\n if (model.scaleRange === null && this.currentViewRange === null) {\r\n return\r\n }\r\n let { min, max } = model.scaleRange || this.currentViewRange!\r\n let difY\r\n switch (this.props.chartModel.scale) {\r\n case ScaleType.Logarithmic: {\r\n difY = this.scalerLastY! - event.clientY\r\n min = model.scale.y.invert(model.scale.y(min) - difY)\r\n max = model.scale.y.invert(model.scale.y(max) + difY)\r\n break\r\n }\r\n default: {\r\n difY = -(this.scalerLastY! - event.clientY) * (model.scale.y.invert(0) - model.scale.y.invert(1))\r\n min -= difY\r\n max += difY\r\n break\r\n }\r\n }\r\n this.scalerLastY = event.clientY\r\n\r\n const originalMinMax = model.getChartOrIndicatorElement()?.instance?.getMinMax?.()\r\n if (originalMinMax) {\r\n const currentDiff = Math.abs(max - min)\r\n const originalDiff = Math.abs(originalMinMax.max - originalMinMax.min)\r\n\r\n if (currentDiff > originalDiff * ALLOWED_MIN_MAX_ZOOM || currentDiff < originalDiff / ALLOWED_MIN_MAX_ZOOM) {\r\n return\r\n }\r\n }\r\n\r\n model.updateAttribute('scaleRange', { min, max })\r\n chartModel.updateAttribute('dateRange', null)\r\n this.recountScale()\r\n }\r\n\r\n onScalerMouseUp = () => {\r\n this.scalerLastY = null\r\n\r\n document.removeEventListener('mousemove', this.onScalerMouseMove)\r\n document.removeEventListener('mouseup', this.onScalerMouseUp)\r\n document.removeEventListener('touchmove', this.onScalerTouchMove)\r\n document.removeEventListener('touchend', this.onScalerTouchEnd)\r\n this.props.setActiveChartInteraction(null)\r\n }\r\n\r\n onScalerReset = () => {\r\n const { model, chartModel } = this.props\r\n if (!this.chartLayoutModel.scrollable) return\r\n chartModel.updateAttribute('dateRange', null)\r\n model.updateAttribute('scaleRange', null)\r\n this.recountScale()\r\n }\r\n\r\n addToLeftOffset = (n: number) => {\r\n const quote = this.props.chartModel.quote()\r\n const barWidth = getBarWidthWithMargin({\r\n chartLayout: this.chartLayoutModel,\r\n zoomFactor: this.props.chartModel.zoomFactor,\r\n })\r\n const leftOffset = getMinMaxLeftOffset({\r\n newLeftOffset: this.props.chartModel.leftOffset + n,\r\n chartModel: this.props.chartModel,\r\n barWidth,\r\n barIndex: quote.barIndex[quote.open.length - 1],\r\n })\r\n\r\n if (leftOffset > barWidth) {\r\n quote.fetchOlderData()\r\n }\r\n this.props.chartModel.updateAttributes({\r\n leftOffset,\r\n dateRange: null,\r\n })\r\n }\r\n\r\n onDoubleClick = (event: HammerInput) => {\r\n event.preventDefault()\r\n const area = this.getArea(event)\r\n const element = this.props.model.selection || this.getElement(area)\r\n if (element && element.type !== IndicatorType.Cot && !element.isCreator) {\r\n setTimeout(() => {\r\n this.props.openElementStyleDialog!(element)\r\n }, 0)\r\n element.trigger('dblclick', event)\r\n }\r\n }\r\n\r\n onPress = (e: ObjectHash) => {\r\n if (e.pointerType !== 'touch') return\r\n\r\n e.clientX = e.center.x\r\n e.clientY = e.center.y\r\n\r\n const el = this.props.model.selection || this.getElement(this.getArea(e))\r\n if (!this.chartLayoutModel.isTouchCrossActive) {\r\n if (!el) {\r\n this.onCanvasPress(e as React.MouseEvent)\r\n } else {\r\n this.onContextMenu(e as React.MouseEvent, el)\r\n }\r\n }\r\n }\r\n\r\n onContextMenu = (e: React.MouseEvent, element?: IndicatorElement | CanvasElement) => {\r\n e.preventDefault()\r\n const area = this.getArea(e)\r\n const elementInArea = this.getElement(area)\r\n const el = element ?? elementInArea\r\n if (!el || el.thumbsAreInArea(area)) {\r\n return\r\n }\r\n const elementModel = ElementModel.findByAttribute('instance', el)\r\n if (!elementModel) return\r\n const hasProperties =\r\n ['indicator', 'canvas'].some((type) => el.type.startsWith(type)) && el.type !== IndicatorType.Cot\r\n const isElementDrawing = elementModel.isDrawing()\r\n\r\n const onContextMenuFullyOpen = () => {\r\n this.setSelectedElement(el)\r\n if (el instanceof CanvasElement) {\r\n el.setIsEditInProgress(true)\r\n }\r\n }\r\n\r\n const onContextMenuClose = () => {\r\n if (el instanceof CanvasElement) {\r\n el.setIsEditInProgress(false)\r\n }\r\n }\r\n\r\n return ContextMenu.show(\r\n e,\r\n [\r\n hasProperties && {\r\n id: 'edit',\r\n label: 'Edit style',\r\n onClick: () => this.props.openElementStyleDialog!(el),\r\n },\r\n\r\n !(elementModel.isChart() || elementModel?.isIndicator()) && {\r\n id: 'clone',\r\n label: 'Clone',\r\n onClick: () => elementModel.makeClone(),\r\n },\r\n\r\n ...(isElementDrawing\r\n ? [\r\n { type: 'divider', label: 'Visibility' },\r\n\r\n {\r\n id: 'visibility-current-and-above',\r\n label: 'Current interval and above',\r\n onClick: () => elementModel.instance.setVisibilityTo(SetVisibilityTo.currentAndAbove),\r\n },\r\n\r\n {\r\n id: 'visibility-current-and-below',\r\n label: 'Current interval and below',\r\n onClick: () => elementModel.instance.setVisibilityTo(SetVisibilityTo.currentAndBelow),\r\n },\r\n\r\n {\r\n id: 'visibility-current-only',\r\n label: 'Current interval only',\r\n onClick: () => elementModel.instance.setVisibilityTo(SetVisibilityTo.currentOnly),\r\n },\r\n\r\n {\r\n id: 'visibility-all-intervals',\r\n label: 'All intervals',\r\n onClick: () => elementModel.instance.setVisibilityTo(SetVisibilityTo.all),\r\n },\r\n ]\r\n : []),\r\n\r\n (isElementDrawing || hasProperties) && { type: 'divider' },\r\n\r\n {\r\n id: 'bring-to-front',\r\n label: 'Bring to Front',\r\n onClick: () => elementModel.bringToFront(),\r\n },\r\n {\r\n id: 'send-to-back',\r\n label: 'Send to Back',\r\n onClick: () => elementModel.sendToBack(),\r\n },\r\n {\r\n id: 'bring-forward',\r\n label: 'Bring Forward',\r\n onClick: () => elementModel.bringForward(),\r\n },\r\n {\r\n id: 'send-backward',\r\n label: 'Send Backward',\r\n onClick: () => elementModel.sendBackward(),\r\n },\r\n\r\n { type: 'divider' },\r\n\r\n {\r\n id: 'remove',\r\n label: 'Remove',\r\n onClick: () => {\r\n if (elementModel.isIndicator()) {\r\n handleRemoveIndicatorPane({ paneIndex: this.props.paneIndex, chartLayoutModel: this.chartLayoutModel })\r\n } else {\r\n elementModel.destroyCascade({ eventType: DrawingSpineOptionsEvent.Remove })\r\n this.props.model.normalizeZIndexes()\r\n }\r\n },\r\n },\r\n ]\r\n .filter(Boolean)\r\n .map((item) => ({ ...item, gtag: { element_type: el.type } })),\r\n { onFullyOpen: onContextMenuFullyOpen, onBeforeItemClick: onContextMenuClose, onFullyClosed: onContextMenuClose }\r\n )\r\n }\r\n\r\n immediateRecountScaleOnChartIndicatorChange = (element?: ElementModel) => {\r\n if (element?.isChart() || element?.isIndicator()) {\r\n this.recountScale()\r\n }\r\n }\r\n\r\n recountScale = (_?: unknown, updateType?: Spine.Event) => {\r\n const { model } = this.props\r\n const chartModel = model.chart()\r\n if (updateType === 'destroy' || !chartModel || !chartModel.quote()) {\r\n return\r\n }\r\n\r\n recountScale({ chartModel, paneModel: model })\r\n\r\n if (this.canvasCtx) {\r\n this.renderAll()\r\n }\r\n }\r\n\r\n onBlur = () => {\r\n if (this.props.model.selection?.getIsCreator?.()) {\r\n this.setSelection(null)\r\n } else {\r\n this.setSelectedElement(null)\r\n }\r\n if (this.hoveredElement) {\r\n this.hoveredElement.setIsHovered(false)\r\n this.hoveredElement = null\r\n }\r\n this.props.model.getAllElements().forEach((element) => {\r\n if (element.instance.getIsCreator?.() && !element.instance.getIsCreatorDialogOpen?.()) {\r\n element.destroyCascade()\r\n }\r\n })\r\n }\r\n\r\n renderAll = (type?: string) => {\r\n if (process.env.IS_E2E_TESTING) window.isRenderInProgress = true\r\n\r\n if (type === 'cross' && this.chartLayoutModel.cross) {\r\n if (this.crossRafId === null) {\r\n const crossRafId = window.requestAnimationFrame(() => {\r\n this.renderCross()\r\n if (process.env.IS_E2E_TESTING) {\r\n toggleE2eRenderInProgress({ id: crossRafId, isInProgress: false })\r\n }\r\n })\r\n if (process.env.IS_E2E_TESTING) {\r\n toggleE2eRenderInProgress({ id: crossRafId, isInProgress: true })\r\n }\r\n this.crossRafId = crossRafId\r\n }\r\n } else if (this.rafId == null && this.canvasCtx) {\r\n const rafId = window.requestAnimationFrame(() => {\r\n this._renderAll()\r\n if (process.env.IS_E2E_TESTING) {\r\n toggleE2eRenderInProgress({ id: rafId, isInProgress: false })\r\n }\r\n })\r\n if (process.env.IS_E2E_TESTING) {\r\n toggleE2eRenderInProgress({ id: rafId, isInProgress: true })\r\n }\r\n this.rafId = rafId\r\n }\r\n }\r\n\r\n _renderAll = () => {\r\n const { model } = this.props\r\n // _renderAll may be called after Chart was deleted because of requestAnimationFrame\r\n if (model.chart() === null || this.canvasRef.current === null || !this.canvasCtx) {\r\n return\r\n }\r\n if (this.getIsUpdatedDesign()) {\r\n if (this.crossRafId === null) {\r\n this.crossRafId = window.requestAnimationFrame(this.renderCross)\r\n }\r\n }\r\n this.rafId = undefined\r\n\r\n renderPane({\r\n chartLayoutModel: this.chartLayoutModel,\r\n chartModel: this.props.chartModel,\r\n paneModel: model,\r\n canvasCtx: this.canvasCtx,\r\n })\r\n }\r\n\r\n getIsUpdatedDesign() {\r\n const { specificChartFunctionality } = this.chartLayoutModel\r\n const isCharts = specificChartFunctionality === SpecificChartFunctionality.chartPage\r\n const isRedesignedFuturesForexCrypto = isRedesignedPage({ specificChartFunctionality })\r\n\r\n return isCharts || isRedesignedFuturesForexCrypto\r\n }\r\n\r\n renderCross = () => {\r\n const { model } = this.props\r\n const isMouseInPane = MouseModel.getShouldRenderCrossInPane(model)\r\n this.crossRafId = null\r\n if (!this.crossCanvasCtx) {\r\n return\r\n }\r\n this.crossCanvasCtx.clearRect(0, 0, this.props.chartModel.width, model.height)\r\n const isCrossDisabled =\r\n PaneModel.select((p) => !!p.selection && !p.selection.type.startsWith('indicators/')).length !== 0 ||\r\n this.props.chartModel.getIsDisabled() ||\r\n !isMouseInPane\r\n\r\n for (const { instance: elementInstance } of model.getAllElements()) {\r\n if (\r\n (!isCrossDisabled && elementInstance.renderCross != null) ||\r\n (isCrossDisabled && elementInstance.renderCrossText != null)\r\n ) {\r\n this.crossCanvasCtx.save()\r\n if (isCrossDisabled) {\r\n elementInstance.renderCrossText!(this.crossCanvasCtx, Number.NaN)\r\n } else {\r\n elementInstance.renderCross!(this.crossCanvasCtx)\r\n }\r\n this.crossCanvasCtx.restore()\r\n }\r\n }\r\n }\r\n\r\n getArea = (e: ObjectHash, additionalData?: T): PaneArea => {\r\n const { model } = this.props\r\n const clientX = e.clientX || additionalData?.clientX\r\n const clientY = e.clientY || additionalData?.clientY\r\n const Settings = getSettings(model)\r\n const areaRectangle = this.canvas!.getBoundingClientRect()\r\n const areaRectangleCursorX = clientX - areaRectangle.left\r\n const areaRectangleCursorY = clientY - areaRectangle.top\r\n const x = areaRectangleCursorX - model.chart().leftOffset - Settings.left.width\r\n const y = areaRectangleCursorY - Settings.top.height\r\n const scale = model.scale\r\n const chartLeftX = areaRectangle.left + Settings.left.width\r\n const chartRightX = areaRectangle.right - Settings.right.width\r\n return {\r\n ...(additionalData as T),\r\n // TODO: rewrite if canvas uses padding/border\r\n x: scale.x.invert(x),\r\n y: scale.y.invert(y),\r\n scaled: {\r\n x,\r\n y,\r\n },\r\n width: 1,\r\n height: 1,\r\n cursorX: areaRectangleCursorX,\r\n cursorY: areaRectangleCursorY,\r\n isCursorInChartWidthBoundaries: clientX > chartLeftX && clientX < chartRightX,\r\n }\r\n }\r\n\r\n setCanvasSize = ({ width, height }: { width: number; height: number }) => {\r\n const ratio = Utils.getScaleRatio()\r\n const canvasElement = this.canvasRef.current\r\n\r\n /**\r\n * It seems that value passed into element attr (e.g. height) is ceiled down,\r\n * so if you provide canvas element with height 100.5 we'll get integer 100 from canvasElement.height\r\n * If the difference in values between \"new height\" and canvasElement.height is less than 1, I treat it as the same value\r\n */\r\n if (\r\n this.canvasCtx &&\r\n canvasElement &&\r\n (Math.abs(height * ratio - canvasElement.height) >= 1 || Math.abs(width * ratio - canvasElement.width) >= 1)\r\n ) {\r\n Utils.setSizeOnCanvasElement({ canvasElement, width, height })\r\n this.canvasCtx.scale(ratio, ratio)\r\n if (this.chartLayoutModel.cross && this.crossCanvasCtx) {\r\n Utils.setSizeOnCanvasElement({\r\n canvasElement: this.crossCanvasRef.current,\r\n width,\r\n height,\r\n })\r\n this.crossCanvasCtx.scale(ratio, ratio)\r\n }\r\n setTimeout(() => {\r\n this.recountScale()\r\n })\r\n }\r\n }\r\n\r\n onClick = (event: HammerInput) => {\r\n const area = this.getArea(event, {\r\n clientX: event.center.x,\r\n clientY: event.center.y,\r\n })\r\n const element = this.props.model.selection || this.getElement(area)\r\n element?.trigger('click', area)\r\n\r\n if (!this.isDisableTouchCrossAvailable) {\r\n this.isDisableTouchCrossAvailable = true\r\n return\r\n }\r\n\r\n if (this.chartLayoutModel.isTouchCrossActive) {\r\n MouseModel.updateAttributes({\r\n position: null,\r\n pane: null,\r\n })\r\n this.chartLayoutModel.updateAttributes({\r\n scrollable: this.chartLayoutModel.initialScrollable,\r\n isTouchCrossActive: false,\r\n })\r\n } else if (\r\n this.isMobile &&\r\n !this.state.hasSeenCrossNotification &&\r\n this.lastActiveTool === DrawingTool.Mouse &&\r\n this.chartLayoutModel.specificChartFunctionality !== SpecificChartFunctionality.smallIndex\r\n ) {\r\n const isChartsPage = this.chartLayoutModel.specificChartFunctionality === SpecificChartFunctionality.chartPage\r\n\r\n this.setState({ hasSeenCrossNotification: true })\r\n this.props.notificationContext.show(\r\n {\r\n this.props.notificationContext.hide()\r\n window.localStorage.setItem('hasSeenCrossNotification', 'true')\r\n }}\r\n theme=\"dark\"\r\n >\r\n Got it\r\n \r\n }\r\n >\r\n Long press the chart to show the crosshair.\r\n ,\r\n { inline: !isChartsPage }\r\n )\r\n }\r\n\r\n this.lastActiveTool = this.props.activeTool\r\n }\r\n\r\n onPaneMouseLeave = () => {\r\n // timout in onPaneMouseMove may cause racecondition where active class is added right after it's been removed\r\n setTimeout(() => {\r\n this.zoomControlsRef.current?.classList.remove(ZOOM_CONTROLS_ACTIVE_CLASS, ZOOM_CONTROLS_IS_IN_AREA_CLASS)\r\n })\r\n if (this.chartLayoutModel.specificChartFunctionality === SpecificChartFunctionality.chartPage) {\r\n this.renderCross()\r\n }\r\n }\r\n\r\n onPaneMouseMove = (e: React.MouseEvent | React.Touch, isMouseDownIgnored = false) => {\r\n const { model, chartModel } = this.props\r\n const zoomControls = this.zoomControlsRef.current\r\n const paneHeight = model.height\r\n if (zoomControls) {\r\n const area = this.getArea<{ mouseDown: boolean; clientX: number; clientY: number }>(e, {\r\n mouseDown: !isMouseDownIgnored && this.mouseDown,\r\n clientX: e.clientX,\r\n clientY: e.clientY,\r\n })\r\n\r\n // timeout is needed here as adding a classname on parent element of a button where we are listening on a click is not working properly if done synchrnousely\r\n setTimeout(() => {\r\n // 103 is the destance between pane bottom and zoom-controls top\r\n // zoomer bottom (8 px) + zoomer height (20px) - 13px + zoom controls height (75px) = 90px\r\n const isInArea = model.height - 90 <= area.cursorY && paneHeight > 210\r\n\r\n if (\r\n isInArea &&\r\n !zoomControls.classList.contains(ZOOM_CONTROLS_IS_IN_AREA_CLASS) &&\r\n !chartModel.getIsDisabled()\r\n ) {\r\n zoomControls.classList.add(ZOOM_CONTROLS_IS_IN_AREA_CLASS)\r\n } else if (!isInArea && zoomControls.classList.contains(ZOOM_CONTROLS_IS_IN_AREA_CLASS)) {\r\n zoomControls.classList.remove(ZOOM_CONTROLS_IS_IN_AREA_CLASS)\r\n }\r\n\r\n if (!area.mouseDown && !model.selection && isInArea && !chartModel.getIsDisabled()) {\r\n if (!zoomControls.classList.contains(ZOOM_CONTROLS_ACTIVE_CLASS)) {\r\n zoomControls.classList.add(ZOOM_CONTROLS_ACTIVE_CLASS)\r\n }\r\n } else if (zoomControls.classList.contains(ZOOM_CONTROLS_ACTIVE_CLASS)) {\r\n zoomControls.classList.remove(ZOOM_CONTROLS_ACTIVE_CLASS)\r\n }\r\n })\r\n }\r\n }\r\n\r\n onMouseLeave = () => {\r\n this.mouseDown = false\r\n }\r\n\r\n onTouchStart = (e: React.TouchEvent) => {\r\n if (!this.props.touchEventsDisabled && e.targetTouches.length === 1) {\r\n const touchEvent = e.targetTouches[0]\r\n if (this.chartLayoutModel.scrollable) {\r\n this.onCanvasInteractionStart(touchEvent)\r\n } else if (this.chartLayoutModel.isTouchCrossActive) {\r\n this.lastClientX = touchEvent.clientX\r\n this.lastClientY = touchEvent.clientY\r\n if (!MouseModel.pane()?.eql(this.props.model)) {\r\n const area = this.getArea(touchEvent, {\r\n mouseDown: this.mouseDown,\r\n clientX: touchEvent.clientX,\r\n clientY: touchEvent.clientY,\r\n })\r\n this.setMousePosition(this.getMousePositionInBoundaries(area))\r\n this.isDisableTouchCrossAvailable = false\r\n }\r\n } else {\r\n const area = this.getArea(touchEvent, { isTouch: true }) // passing isTouch is pretty confusing, it's used in Tools.jsx -> onMouseDown method\r\n const element = this.getElement(area)\r\n if (element?.getIsChartEvent?.() && this.props.activeTool === DrawingTool.Mouse) {\r\n const chartEventElement = element as ChartEvent\r\n chartEventElement.toggleIsOpen()\r\n }\r\n }\r\n this.onPaneMouseMove(touchEvent, true)\r\n }\r\n }\r\n\r\n onTouchMove = (e: TouchEvent) => {\r\n if (!this.props.touchEventsDisabled) {\r\n if (!this.getIsHammerAllowScrollActive()) {\r\n e.preventDefault()\r\n }\r\n if (!this.props.touchEventsDisabled && e.targetTouches.length === 1) {\r\n this.onCanvasInteractionMove(e.targetTouches[0])\r\n }\r\n }\r\n }\r\n\r\n onTouchEnd = (e: React.TouchEvent) => {\r\n if (!this.props.touchEventsDisabled && this.chartLayoutModel.scrollable) {\r\n this.onCanvasInteractionEnd(e)\r\n }\r\n }\r\n\r\n onCanvasPress = (e: React.MouseEvent) => {\r\n if (this.chartLayoutModel.scrollable) {\r\n this.chartLayoutModel.updateAttribute('scrollable', false)\r\n document.removeEventListener('touchmove', this.onMouseMoveOnScrolling)\r\n }\r\n if (!this.chartLayoutModel.isTouchCrossActive) {\r\n this.chartLayoutModel.updateAttribute('isTouchCrossActive', true)\r\n this.onCanvasInteractionMove(e)\r\n }\r\n }\r\n\r\n onCanvasInteractionStart = (e: React.Touch | React.MouseEvent) => {\r\n const { activeTool, activeChartInteraction, chartModel, model } = this.props\r\n const isTouch = typeof Touch !== 'undefined' && e instanceof Touch\r\n this.lastActiveTool = activeTool\r\n\r\n if (isPrimaryClick(e) && !activeChartInteraction && !chartModel.getIsDisabled()) {\r\n const area = this.getArea(e, { isTouch }) // passing isTouch is pretty confusing, it's used in Tools.jsx -> onMouseDown method\r\n const element = this.getElement(area)\r\n\r\n // if user click outside of drawable area but still inside canvas creator would hang unfinised,\r\n // it that case we want to cancel element creation, same as we do on click outside of canvas / onBlur\r\n if (model.selection?.isCreator && !area.isCursorInChartWidthBoundaries && element !== model.selection) {\r\n model.getAllElements().forEach((element) => {\r\n if (element.instance.getIsCreator?.() && !element.instance.getIsCreatorDialogOpen?.()) {\r\n element.destroyCascade()\r\n }\r\n })\r\n }\r\n if (this.chartLayoutModel.scrollable) {\r\n setElementCursor({ elementId: this.chartLayoutModel.getHTMLElementId(), cursor: 'grabbing' })\r\n if (model.scaleRange) {\r\n this.currentViewRange = model.getChartOrIndicatorElement()?.instance?.getMinMax?.() ?? null\r\n }\r\n document.addEventListener(isTouch ? 'touchmove' : 'mousemove', this.onMouseMoveOnScrolling)\r\n document.addEventListener(isTouch ? 'touchend' : 'mouseup', this.onCanvasInteractionEnd)\r\n }\r\n if (element?.getIsChartEvent?.() && activeTool === DrawingTool.Mouse) {\r\n this.setSelectedElement(null)\r\n const chartEventElement = element as ChartEvent\r\n chartEventElement.toggleIsOpen()\r\n } else if (\r\n activeTool === DrawingTool.Mouse ||\r\n model.getAllElements().some(({ instance }) => instance.isCreator)\r\n ) {\r\n element?.trigger('mousedown', area)\r\n this.setSelectedElement(element)\r\n }\r\n model.trigger('mousedown', model, area, element)\r\n this.mouseDown = true\r\n this.lastX = area.x\r\n this.lastY = area.y\r\n }\r\n\r\n this.lastClientX = e.clientX\r\n this.lastClientY = e.clientY\r\n }\r\n\r\n onCanvasInteractionMove = (e: React.MouseEvent | React.Touch) => {\r\n const area = this.getArea(e, {\r\n mouseDown: this.mouseDown,\r\n clientX: e.clientX,\r\n clientY: e.clientY,\r\n })\r\n if (!area.isCursorInChartWidthBoundaries) {\r\n MouseModel.updateAttributes({\r\n position: null,\r\n pane: null,\r\n })\r\n return\r\n }\r\n\r\n const { model } = this.props\r\n const hoveredElement = this.getElement(area)\r\n const element = model.selection || hoveredElement\r\n\r\n if (!(this.isMobile && !this.chartLayoutModel.isTouchCrossActive)) {\r\n this.isDisableTouchCrossAvailable = true\r\n this.setMousePosition(\r\n this.lastClientX && this.lastClientY && this.chartLayoutModel.isTouchCrossActive && MouseModel.position\r\n ? this.getMousePositionInBoundaries({\r\n x: MouseModel.position.x + (model.scale.x.invert(area.clientX) - model.scale.x.invert(this.lastClientX)),\r\n y: MouseModel.position.y + (model.scale.y.invert(area.clientY) - model.scale.y.invert(this.lastClientY)),\r\n })\r\n : { x: area.x, y: area.y }\r\n )\r\n }\r\n\r\n if (!this.chartLayoutModel.scrollable) {\r\n this.lastClientX = area.clientX\r\n this.lastClientY = area.clientY\r\n }\r\n\r\n element?.trigger('mousemove', area)\r\n if (\r\n this.mouseDown &&\r\n model.selection instanceof CanvasElement &&\r\n !model.selection.activeThumb &&\r\n !this.chartLayoutModel.activeChartEvent\r\n ) {\r\n if (!model.selection.getIsCreator?.()) {\r\n model.selection.moveBy(area.x - this.lastX, area.y - this.lastY)\r\n }\r\n this.lastX = area.x\r\n this.lastY = area.y\r\n this.renderAll()\r\n }\r\n const isElementHovered =\r\n this.props.activeTool === DrawingTool.Mouse &&\r\n ((element && element === hoveredElement) || hoveredElement instanceof CanvasElement)\r\n\r\n if (hoveredElement !== this.hoveredElement && this.hoveredElement instanceof CanvasElement) {\r\n this.hoveredElement.setIsHovered(false)\r\n this.hoveredElement = null\r\n }\r\n\r\n if (isElementHovered && hoveredElement instanceof CanvasElement) {\r\n if (!hoveredElement.isHovered && !hoveredElement.isSelected) {\r\n hoveredElement.setIsHovered(true)\r\n this.hoveredElement = hoveredElement\r\n }\r\n }\r\n\r\n if (isElementHovered !== this.isElementHovered && this.canvas && hoveredElement?.type !== IndicatorType.Cot) {\r\n this.canvas.className = isElementHovered ? 'hover' : ''\r\n if (this.chartLayoutModel.cross && this.crossCanvas) {\r\n this.crossCanvas.className = `second${isElementHovered ? ' hover' : ''}`\r\n }\r\n this.isElementHovered = isElementHovered\r\n }\r\n }\r\n\r\n onCanvasInteractionEnd = (event: TouchEvent | MouseEvent | React.TouchEvent) => {\r\n if (MouseModel.position) {\r\n setElementCursor({ elementId: this.chartLayoutModel.getHTMLElementId(), cursor: 'crosshair' })\r\n } else {\r\n setElementCursor({ elementId: this.chartLayoutModel.getHTMLElementId(), cursor: 'default' })\r\n }\r\n const isTouch = typeof TouchEvent !== 'undefined' && event instanceof TouchEvent\r\n this.mouseDown = false\r\n const area = this.getArea(event)\r\n const element = this.props.model.selection || this.getElement(area)\r\n element?.trigger('mouseup', area)\r\n document.removeEventListener(isTouch ? 'touchmove' : 'mousemove', this.onMouseMoveOnScrolling)\r\n document.removeEventListener(isTouch ? 'touchend' : 'mouseup', this.onCanvasInteractionEnd)\r\n }\r\n\r\n getMousePositionInBoundaries = ({ x, y }: { x: number; y: number }) => {\r\n const { model } = this.props\r\n const Settings = getSettings(model)\r\n const canvasAreaRectangle = this.canvas!.getBoundingClientRect()\r\n const chartLeft = model.scale.x.invert(-model.chart().leftOffset + 1)\r\n const chartRight = model.scale.x.invert(\r\n canvasAreaRectangle.width - Settings.right.width - Settings.left.width - model.chart().leftOffset - 1\r\n )\r\n const chartTop = model.scale.y.invert(0)\r\n const chartBottom = model.scale.y.invert(canvasAreaRectangle.height - Settings.bottom.height - Settings.top.height)\r\n\r\n return {\r\n x: getValueInRange({\r\n value: x,\r\n min: chartLeft,\r\n max: chartRight,\r\n }),\r\n y: getValueInRange({\r\n value: y,\r\n min: chartBottom,\r\n max: chartTop,\r\n }),\r\n }\r\n }\r\n\r\n setMousePosition = ({ x, y }: { x: number; y: number }) => {\r\n const isSameMouseModel = !!MouseModel.pane()?.eql(this.props.model)\r\n MouseModel.updateAttributes({\r\n position: { x, y },\r\n ...(isSameMouseModel ? {} : { pane: this.props.model }),\r\n })\r\n }\r\n\r\n setSelection = (selection: IndicatorElement | CanvasElement | null) => {\r\n if (selection instanceof CanvasElement) {\r\n selection?.setIsSelected(true)\r\n }\r\n\r\n this.props.model.updateAttribute('selection', selection)\r\n }\r\n\r\n setSelectedElement = (element: IndicatorElement | CanvasElement | null) => {\r\n const { selection } = this.props.model\r\n const isSelectionCanvas = selection instanceof CanvasElement\r\n if (element !== selection || (isSelectionCanvas && element && !selection?.isSelected)) {\r\n if (isSelectionCanvas) {\r\n selection?.setIsSelected(false)\r\n }\r\n if (isSelectionCanvas && selection?.isCreator) {\r\n this.setSelection(null)\r\n } else {\r\n this.setSelection(element)\r\n }\r\n }\r\n }\r\n\r\n getElement = (area: PaneArea) => {\r\n const chartEvents = this.props.model.getAllChartEvents(false)\r\n\r\n for (let i = chartEvents.length - 1; i >= 0; i--) {\r\n const el = chartEvents[i].instance\r\n if (el.getIsInChartView(this.props.chartModel) && el.isInArea(area)) {\r\n return el\r\n }\r\n }\r\n\r\n const elements = this.props.model.getAllElements()\r\n\r\n for (let i = elements.length - 1; i >= 0; i--) {\r\n const el = elements[i].instance\r\n if (el.getIsInChartView(this.props.chartModel) && el.isInArea(area)) {\r\n return el\r\n }\r\n }\r\n return null\r\n }\r\n\r\n getCanvasDOMNode = () =>\r\n // This is used in app/modals/publish/publish.jsx\r\n this.canvasRef.current\r\n}\r\n\r\nexport default withNotificationContext(withElementStyleDialogState(withPaneModel(Pane)))\r\n","import React from 'react'\r\n\r\nimport { useModelState } from '../../model-hooks/use-model-state'\r\nimport PaneModel from '../../models/pane'\r\n\r\nexport function withPaneModel

(Component: React.ComponentType

) {\r\n return function WrappedComponent(props: P) {\r\n const model = useModelState(props.model, { watchProperties: ['selection'] })\r\n\r\n return \r\n }\r\n}\r\n","import { Spinner } from '@finviz/website'\r\nimport classnames from 'classnames'\r\nimport React from 'react'\r\n\r\nexport function ChartSpinnerOverlay({ shouldDisplay, className }: { shouldDisplay: boolean; className: string }) {\r\n const [isVisible, setIsVisible] = React.useState(shouldDisplay)\r\n React.useEffect(() => {\r\n let timeout: number\r\n if (!shouldDisplay) {\r\n timeout = window.setTimeout(() => {\r\n setIsVisible(false)\r\n }, 400)\r\n }\r\n return () => {\r\n clearTimeout(timeout)\r\n }\r\n }, [shouldDisplay])\r\n\r\n return (\r\n <>\r\n {isVisible && (\r\n \r\n \r\n \r\n )}\r\n \r\n )\r\n}\r\n","import React from 'react'\r\n\r\nimport { RootChartConfigObjectChart } from '../../../types/shared'\r\nimport ChartModel from '../../models/chart'\r\nimport ChartLayout from '../../models/chart_layout'\r\nimport { DrawingTool } from '../toolbar/interfaces'\r\n\r\nexport const CHART_CLASS_NAMES = 'chart flex-1 relative'\r\nexport const DEFAULT_WRAPPER_COMPONENT = 'div'\r\n\r\nexport interface ChartProps {\r\n chartIndex: number\r\n gridArea?: string\r\n WrapperComp?: React.ForwardRefRenderFunction\r\n config: RootChartConfigObjectChart\r\n chartModel: ChartModel\r\n layoutModel: ChartLayout\r\n setActiveChartInteraction: (interaction: string | null) => void\r\n activeChartInteraction: string | null\r\n activeTool: DrawingTool\r\n touchEventsDisabled: boolean\r\n hasOutline?: boolean\r\n shouldResize?: boolean\r\n renderChartToolbar?: () => React.ReactNode\r\n}\r\n","import classnames from 'classnames'\r\nimport React from 'react'\r\n\r\nimport { Instrument } from '../../../types/shared'\r\nimport { ChartEditorEnum, SpecificChartFunctionality } from '../../constants/common'\r\nimport math from '../../helpers/math'\r\nimport ChartModel from '../../models/chart'\r\nimport ChartLayout from '../../models/chart_layout'\r\nimport MouseModel from '../../models/mouse'\r\nimport PaneModel from '../../models/pane'\r\nimport Quote from '../../models/quote'\r\nimport { QuoteFetchType } from '../../models/quote/constants'\r\nimport utils, { isRedesignEnabled } from '../../utils'\r\nimport { getBarWidthWithMargin, getZoomFactorForBarsToDisplay } from '../../utils/chart'\r\nimport { ChartControls } from '../chart-controls'\r\nimport Pane from '../pane'\r\nimport {\r\n getBarIndex,\r\n getIsSmallIndexChart,\r\n getLeftOffset,\r\n getMinMaxLeftOffset,\r\n updateZoomAndLeftOffsetByDateRange,\r\n} from '../renderUtils'\r\nimport { ChartProps } from './constants'\r\nimport { withChartInit } from './with-chart-init'\r\nimport { withWatchedPanesOnChartModel } from './with-watched-panes-on-chart-model'\r\n\r\nfunction preventDefaultFunc(event: Event) {\r\n event.preventDefault()\r\n}\r\n\r\nfunction getZoomFactor({\r\n chartLayout,\r\n currentZoomFactor,\r\n diff,\r\n minBarWidthInPx = 1,\r\n maxBarWidthInPx = 66,\r\n}: {\r\n chartLayout: ChartLayout\r\n currentZoomFactor: number\r\n diff: number\r\n minBarWidthInPx?: number\r\n maxBarWidthInPx?: number\r\n}) {\r\n const minZoomFactor = getZoomFactorForBarsToDisplay({\r\n chartLayout,\r\n chartVisibleWidth: minBarWidthInPx,\r\n numOfVisibleBars: 1,\r\n })\r\n const maxZoomFactor = getZoomFactorForBarsToDisplay({\r\n chartLayout,\r\n chartVisibleWidth: maxBarWidthInPx,\r\n numOfVisibleBars: 1,\r\n })\r\n const isNegativeDirection = diff < 0\r\n const newZoomFactor = currentZoomFactor + diff\r\n const newZoomFactorInRange = Math.min(Math.max(minZoomFactor, newZoomFactor), maxZoomFactor)\r\n\r\n if (newZoomFactor > newZoomFactorInRange && currentZoomFactor > newZoomFactorInRange) {\r\n return isNegativeDirection ? newZoomFactor : currentZoomFactor\r\n }\r\n\r\n if (newZoomFactor < newZoomFactorInRange && currentZoomFactor < newZoomFactorInRange) {\r\n return !isNegativeDirection ? newZoomFactor : currentZoomFactor\r\n }\r\n\r\n return newZoomFactorInRange\r\n}\r\n\r\ninterface ChartState {\r\n panesWrapperElement: HTMLDivElement | null\r\n}\r\n\r\nclass Chart extends React.Component {\r\n lastWidth: number\r\n mouseWheelTimeout?: number\r\n setStateWithPanesTimeout?: number\r\n lastHeight = 0\r\n lastY: number | null = null\r\n lastX: number | null = null\r\n resizerPaneIndex = -1\r\n minimalPaneHeight = 0\r\n zoomerRightAlign: {\r\n barIndex?: number\r\n index: number\r\n offsetDiff: number\r\n } | null = null\r\n\r\n // expects model, config, layoutModel\r\n constructor(props: ChartProps) {\r\n super(props)\r\n\r\n this.lastWidth = props.chartModel.width\r\n this.props.layoutModel.bind('change', this.onLayoutModelChange)\r\n this.state = { panesWrapperElement: null }\r\n }\r\n\r\n componentDidMount() {\r\n const { chartModel } = this.props\r\n this.lastWidth = this.props.layoutModel.width\r\n\r\n chartModel.trigger('change', chartModel)\r\n chartModel.bind('createPane', this.onPaneCreate)\r\n\r\n this.calculateMinimalPaneHeight()\r\n this.handleQuoteChange(chartModel.quote()!)\r\n this.onModelChange()\r\n\r\n chartModel.bind('update', this.onModelChange)\r\n chartModel.bind('destroy', () => {\r\n Quote.unbind('olderData', this.onOlderDataLoaded)\r\n Quote.unbind(`${QuoteFetchType.Refetch} ${QuoteFetchType.NewerData}`, this.onDataLoaded)\r\n })\r\n\r\n Quote.bind('olderData', this.onOlderDataLoaded)\r\n Quote.bind(`${QuoteFetchType.Refetch} ${QuoteFetchType.NewerData}`, this.onDataLoaded)\r\n }\r\n\r\n componentDidUpdate(prevProps: Readonly, prevState: Readonly) {\r\n if (\r\n prevState.panesWrapperElement !== this.state.panesWrapperElement ||\r\n prevProps.layoutModel.isWheelZoomEnabled !== this.props.layoutModel.isWheelZoomEnabled\r\n ) {\r\n prevState.panesWrapperElement?.removeEventListener('wheel', preventDefaultFunc)\r\n\r\n if (this.props.layoutModel.isWheelZoomEnabled) {\r\n // can't use onWheel as it has passive: true\r\n this.state.panesWrapperElement?.addEventListener('wheel', preventDefaultFunc, { passive: false })\r\n }\r\n }\r\n }\r\n\r\n componentWillUnmount() {\r\n const { chartModel, layoutModel } = this.props\r\n if (this.setStateWithPanesTimeout) {\r\n clearTimeout(this.setStateWithPanesTimeout)\r\n }\r\n layoutModel.unbind('change', this.onLayoutModelChange)\r\n chartModel.unbind('update', this.onModelChange)\r\n\r\n this.state.panesWrapperElement?.removeEventListener('wheel', preventDefaultFunc)\r\n }\r\n\r\n handleSetPanesWrapperRef = (panesWrapperElement: HTMLDivElement | null) => {\r\n this.setState({ panesWrapperElement })\r\n }\r\n\r\n render() {\r\n const { activeTool, chartIndex, layoutModel, chartModel, renderChartToolbar } = this.props\r\n const isChartPage = layoutModel.specificChartFunctionality === SpecificChartFunctionality.chartPage\r\n const panes =\r\n layoutModel.specificChartFunctionality === SpecificChartFunctionality.futuresPage\r\n ? chartModel.getAllValidPanes()\r\n : chartModel.getAllPanes()\r\n const showSettings = layoutModel.editors.includes(ChartEditorEnum.settings)\r\n\r\n return (\r\n <>\r\n this.onClick(undefined) : undefined}\r\n data-testid={`chart-${chartIndex}-settings`}\r\n onMouseEnter={this.resetMouseModel}\r\n >\r\n {showSettings && }\r\n \r\n {layoutModel.editable && showSettings && renderChartToolbar && (\r\n \r\n {renderChartToolbar()}\r\n \r\n )}\r\n \r\n {panes.map((pane, index) => (\r\n \r\n ))}\r\n \r\n \r\n )\r\n }\r\n\r\n onMouseWheel = (e: React.WheelEvent) => {\r\n const { chartModel, layoutModel } = this.props\r\n const isLoading = chartModel.panes().count() < 1\r\n if (!layoutModel.isWheelZoomEnabled || isLoading) {\r\n return\r\n }\r\n if (!this.zoomerRightAlign) {\r\n this.calcZoomerRightAlign()\r\n }\r\n clearTimeout(this.mouseWheelTimeout)\r\n this.mouseWheelTimeout = window.setTimeout(() => {\r\n this.zoomerRightAlign = null\r\n }, 250)\r\n this.onZoomerMouseMove(e, undefined, true)\r\n }\r\n\r\n onClick = (activePane: PaneModel | undefined) => {\r\n if (\r\n !this.props.layoutModel.activeChart.eql(this.props.chartModel) ||\r\n !(this.props.layoutModel.activePane?.eql(activePane) || this.props.layoutModel.activePane === activePane)\r\n ) {\r\n this.props.layoutModel.updateAttributes({ activeChart: this.props.chartModel, activePane })\r\n }\r\n }\r\n\r\n onPaneCreate = () => {\r\n const { chartModel } = this.props\r\n this.onModelChange()\r\n this.calculateMinimalPaneHeight()\r\n chartModel.trigger('change', chartModel)\r\n }\r\n\r\n onPaneDestroy = (paneId: string) => {\r\n const { chartModel } = this.props\r\n const pane = chartModel.panes().find(paneId)\r\n\r\n if (pane) {\r\n pane.destroyCascade()\r\n this.onModelChange()\r\n chartModel.trigger('change', chartModel)\r\n }\r\n }\r\n\r\n onModelChange = (chartModelParam?: ChartModel) => {\r\n const { chartModel, config } = this.props\r\n const panes = chartModel.getAllPanes()\r\n const quote = chartModel.quote()\r\n\r\n if (panes.length === 0 || !quote || chartModel.leftOffset === undefined) {\r\n return\r\n }\r\n\r\n const { width, height } = chartModel\r\n let panesHeight = panes.reduce((sum, pane) => sum + (pane.height ?? 0), 0)\r\n if (panesHeight !== height) {\r\n panesHeight = panes.reduce((sum, pane) => {\r\n const newPaneHeight = Math.round((pane.height / panesHeight) * height)\r\n if (!Number.isNaN(newPaneHeight)) {\r\n pane.updateAttribute('height', newPaneHeight)\r\n }\r\n return sum + newPaneHeight\r\n }, 0)\r\n const chartPane = chartModel.getChartPane()\r\n if (chartPane && panesHeight !== height) {\r\n const newChartPaneHeight = chartPane.height + height - panesHeight\r\n if (!Number.isNaN(newChartPaneHeight)) {\r\n chartPane.updateAttribute('height', newChartPaneHeight)\r\n }\r\n }\r\n }\r\n\r\n const newLeftOffset = getLeftOffset({\r\n quote,\r\n chartModel,\r\n config: config,\r\n })\r\n const newIsScrolled = chartModel.leftOffset !== newLeftOffset\r\n const isScrolled = chartModel.isScrolled\r\n if (!isScrolled && this.lastWidth !== width) {\r\n this.lastWidth = width\r\n chartModel.updateAttribute('leftOffset', newLeftOffset)\r\n } else if (isScrolled !== newIsScrolled) {\r\n chartModel.updateAttributes({ isScrolled: newIsScrolled })\r\n }\r\n\r\n if (this.lastHeight !== height) {\r\n this.lastHeight = height\r\n this.calculateMinimalPaneHeight()\r\n }\r\n\r\n if (chartModelParam) {\r\n this.handleQuoteChange(chartModelParam.quote())\r\n }\r\n }\r\n\r\n onLayoutModelChange = ({ activeChart, activePane }: { activeChart: ChartModel; activePane: PaneModel }) => {\r\n const { chartModel } = this.props\r\n if (!activeChart) {\r\n return\r\n }\r\n for (const pane of chartModel.getAllPanes()) {\r\n if (activePane?.id !== pane.id && pane.selection?.isSelected === true) {\r\n pane.selection.setIsSelected(false)\r\n pane.updateAttribute('selection', undefined)\r\n }\r\n }\r\n }\r\n\r\n onResizerMouseDown = (e: React.MouseEvent | MouseEvent, model: PaneModel) => {\r\n if (e.button !== 0) {\r\n return\r\n }\r\n this.lastY = e.clientY\r\n this.resizerPaneIndex = this.props.chartModel\r\n .panes()\r\n .all()\r\n .findIndex((pane) => pane.eql(model))\r\n document.addEventListener('mousemove', this.onResizerMouseMove)\r\n document.addEventListener('mouseup', this.onResizerMouseUp)\r\n }\r\n\r\n onResizerMouseMove = (e: MouseEvent) => {\r\n if (this.resizerPaneIndex > 0 && this.lastY !== null && this.resizePanesAccordingly(this.lastY! - e.clientY)) {\r\n this.lastY = e.clientY\r\n }\r\n }\r\n\r\n onResizerMouseUp = (e: MouseEvent) => {\r\n const { chartModel } = this.props\r\n if (this.resizerPaneIndex > 0 && this.lastY !== null) {\r\n this.resizePanesAccordingly(this.lastY - e.clientY)\r\n this.lastY = null\r\n\r\n chartModel.trigger('change', chartModel)\r\n }\r\n\r\n document.removeEventListener('mousemove', this.onResizerMouseMove)\r\n document.removeEventListener('mouseup', this.onResizerMouseUp)\r\n }\r\n\r\n calculateMinimalPaneHeight() {\r\n const { chartModel } = this.props\r\n const { minHeight, total } = chartModel\r\n .panes()\r\n .all()\r\n .reduce(\r\n ({ minHeight, total }, pane) => {\r\n if (minHeight > pane.height) {\r\n minHeight = pane.height\r\n }\r\n total += pane.getIsChartPane() ? 3 : 1\r\n return { minHeight, total }\r\n },\r\n { minHeight: chartModel.height, total: 0 }\r\n )\r\n const optiMinHeight = Math.floor(chartModel.height / total)\r\n this.minimalPaneHeight = Math.min(minHeight, optiMinHeight)\r\n }\r\n\r\n resizePanesAccordingly(difY: number) {\r\n const { chartModel } = this.props\r\n const panes = chartModel.panes().all()\r\n let basePane = this.resizerPaneIndex\r\n if (!difY) {\r\n return true\r\n } else if (difY > 0) {\r\n let i = basePane\r\n let pane = panes[i]\r\n if (pane.height + difY >= this.minimalPaneHeight) {\r\n pane.updateAttribute('height', pane.height + difY)\r\n } else {\r\n pane.updateAttribute('height', this.minimalPaneHeight)\r\n }\r\n for (--i; i >= 0; i--) {\r\n pane = panes[i]\r\n if (pane.height - difY >= this.minimalPaneHeight) {\r\n pane.updateAttribute('height', pane.height - difY)\r\n break\r\n } else {\r\n pane.updateAttribute('height', this.minimalPaneHeight)\r\n }\r\n }\r\n } else if (difY < 0) {\r\n basePane = Math.max(0, basePane - 1)\r\n let i = basePane\r\n let pane = panes[i]\r\n if (pane.height - difY >= this.minimalPaneHeight) {\r\n pane.updateAttribute('height', pane.height - difY)\r\n } else {\r\n pane.updateAttribute('height', this.minimalPaneHeight)\r\n }\r\n for (++i; i < panes.length; i++) {\r\n pane = panes[i]\r\n if (pane.height + difY >= this.minimalPaneHeight) {\r\n pane.updateAttribute('height', pane.height + difY)\r\n break\r\n } else {\r\n pane.updateAttribute('height', this.minimalPaneHeight)\r\n }\r\n }\r\n }\r\n\r\n const panesHeight = panes.reduce((sum, pane) => sum + pane.height, 0)\r\n if (panesHeight !== chartModel.height) {\r\n difY = chartModel.height - panesHeight\r\n\r\n const pane = panes[basePane]\r\n pane.updateAttribute('height', pane.height + difY)\r\n\r\n // if we exceeded total height we need to stop updating lastY - return false\r\n return false\r\n }\r\n\r\n return true\r\n }\r\n\r\n onZoomerTouchStart = (e: React.TouchEvent | TouchEvent) => {\r\n if (!this.props.layoutModel.scrollable || e.touches.length !== 1 || this.props.touchEventsDisabled) {\r\n return\r\n }\r\n this.onZoomerMouseDown(e.targetTouches[0])\r\n }\r\n\r\n onZoomerTouchMove = (e: TouchEvent) => {\r\n if (!this.props.layoutModel.scrollable || e.touches.length !== 1) {\r\n return\r\n }\r\n this.onZoomerMouseMove(e.targetTouches[0])\r\n }\r\n\r\n onZoomerTouchEnd = () => {\r\n if (!this.props.layoutModel.scrollable) {\r\n return\r\n }\r\n this.onZoomerMouseUp()\r\n }\r\n\r\n getRawDistance = (e: Pick) => {\r\n const p1 = { x: e.touches[0].clientX, y: e.touches[0].clientY }\r\n const p2 = { x: e.touches[1].clientX, y: e.touches[1].clientY }\r\n return math.distance(p1, p2)\r\n }\r\n\r\n onPinchStart = (e: React.TouchEvent) => {\r\n const { chartModel } = this.props\r\n const { activeChartInteraction, setActiveChartInteraction, touchEventsDisabled } = this.props\r\n const isLoading = chartModel.panes().count() < 1\r\n\r\n if (\r\n this.props.layoutModel.scrollable &&\r\n e.touches.length === 2 &&\r\n !activeChartInteraction &&\r\n !isLoading &&\r\n !touchEventsDisabled\r\n ) {\r\n setActiveChartInteraction('pinch')\r\n this.onZoomerMouseDown({ clientX: this.getRawDistance(e as unknown as TouchEvent) })\r\n\r\n document.addEventListener('touchmove', this.onPinchMove)\r\n document.addEventListener('touchend', this.onPinchEnd)\r\n }\r\n }\r\n\r\n onPinchMove = (e: TouchEvent) => {\r\n if (e.touches.length === 2) {\r\n this.onZoomerMouseMove({ clientX: this.getRawDistance(e) })\r\n }\r\n }\r\n\r\n onPinchEnd = (e: TouchEvent) => {\r\n if (e.touches.length === 1) {\r\n this.onZoomerMouseUp()\r\n document.removeEventListener('touchmove', this.onPinchMove)\r\n document.removeEventListener('touchend', this.onPinchEnd)\r\n }\r\n }\r\n\r\n calcZoomerRightAlign = () => {\r\n const { chartModel } = this.props\r\n const { ChartSettings } = chartModel.getChartLayoutSettings()\r\n const quote = chartModel.quote()\r\n const fx = chartModel.panes().first().scale.x\r\n const barWidth = getBarWidthWithMargin({ zoomFactor: chartModel.zoomFactor, chartLayout: this.props.layoutModel })\r\n const currentLeftOffset = getLeftOffset({ quote, chartModel, config: this.props.config, barWidth })\r\n this.zoomerRightAlign = null\r\n\r\n if (quote.isIntraday && quote.instrument === Instrument.Stock) {\r\n const barIndex = quote.getBarIndex(quote.close.length - 1)\r\n let offsetDiff =\r\n chartModel.leftOffset -\r\n getLeftOffset({\r\n quote,\r\n chartModel: chartModel,\r\n config: this.props.config,\r\n barWidth,\r\n barIndex,\r\n shouldAlignDaysToLeftApplied: false,\r\n })\r\n const offsetBars = ~~(offsetDiff / barWidth)\r\n offsetDiff -= offsetBars * barWidth\r\n this.zoomerRightAlign = {\r\n barIndex,\r\n index: barIndex - offsetBars,\r\n offsetDiff,\r\n }\r\n } else if (chartModel.leftOffset <= currentLeftOffset) {\r\n this.zoomerRightAlign = {\r\n index: quote.getBarIndex(quote.open.length - 1),\r\n offsetDiff: chartModel.leftOffset - currentLeftOffset,\r\n }\r\n } else {\r\n const offset = chartModel.leftOffset\r\n for (let i = 0; i < quote.open.length; i += 1) {\r\n const x = fx(i)\r\n if (x + offset < 0) {\r\n continue\r\n }\r\n if (x + offset > chartModel.width - ChartSettings.left.width - ChartSettings.right.width) {\r\n const barIndex = quote.getBarIndex(i - 1)\r\n let offsetDiff =\r\n offset -\r\n getLeftOffset({\r\n quote,\r\n chartModel,\r\n config: this.props.config,\r\n barWidth,\r\n barIndex,\r\n })\r\n const offsetBars = ~~(offsetDiff / barWidth)\r\n offsetDiff -= offsetBars * barWidth\r\n this.zoomerRightAlign = {\r\n barIndex,\r\n index: barIndex - offsetBars,\r\n offsetDiff,\r\n }\r\n break\r\n }\r\n }\r\n }\r\n }\r\n\r\n onZoomerMouseDown = (e: Partial) => {\r\n if ((e.button !== 0 && 'button' in e) || !this.props.layoutModel.scrollable) {\r\n return\r\n }\r\n switch (this.props.activeChartInteraction) {\r\n case 'pinch':\r\n break\r\n case null:\r\n this.props.setActiveChartInteraction('zoomer')\r\n break\r\n default:\r\n return\r\n }\r\n\r\n this.lastX = e.clientX ?? null\r\n this.calcZoomerRightAlign()\r\n\r\n document.addEventListener('mousemove', this.onZoomerMouseMove)\r\n document.addEventListener('mouseup', this.onZoomerMouseUp)\r\n document.addEventListener('touchmove', this.onZoomerTouchMove)\r\n document.addEventListener('touchend', this.onZoomerTouchEnd)\r\n }\r\n\r\n normalizeWheelDeltaY = (e: WheelEvent) => {\r\n // because wheel deltaY on mouse and touchpad is quite different we need to normalize it\r\n const abs = Math.abs(e.deltaY)\r\n if (abs === 0) return 0\r\n return Math.log(abs) * Math.sign(e.deltaY) * 10\r\n }\r\n\r\n onZoomerMouseMove = (\r\n e: React.WheelEvent | MouseEvent | Touch | { clientX: number },\r\n _?: unknown,\r\n isMouseWheel = false\r\n ) => {\r\n const { chartModel, layoutModel } = this.props\r\n let difX\r\n if (!layoutModel.scrollable) return\r\n if (!isMouseWheel && this.lastX !== null) {\r\n difX = (this.lastX - e.clientX) / chartModel.width\r\n this.lastX = e.clientX\r\n } else {\r\n // standard difX calculation result is around 0.00x, wheel deltaY is whole px\r\n // because of that we divide px with 1000\r\n difX = this.normalizeWheelDeltaY(e as WheelEvent) / 1000\r\n }\r\n\r\n this.addToZoomFactor({ diff: -difX })\r\n }\r\n\r\n addToZoomFactor = ({\r\n diff,\r\n shouldCalculateRightAlign = false,\r\n }: {\r\n diff: number\r\n shouldCalculateRightAlign?: boolean\r\n }) => {\r\n const { chartModel, layoutModel } = this.props\r\n if (shouldCalculateRightAlign) {\r\n this.calcZoomerRightAlign()\r\n }\r\n // 6 is default bar width with margin on charts page, so to get the similar feeling when zooming we're multiplying the zoom factor by the coefficient\r\n const diffCoefficient = chartModel.zoomFactor * (6 / getBarWidthWithMargin({ chartLayout: this.props.layoutModel }))\r\n const zoomFactor = getZoomFactor({\r\n chartLayout: layoutModel,\r\n currentZoomFactor: chartModel.zoomFactor,\r\n diff: diff * diffCoefficient,\r\n })\r\n const barWidth = getBarWidthWithMargin({\r\n zoomFactor,\r\n chartLayout: this.props.layoutModel,\r\n })\r\n\r\n let leftOffset\r\n if (this.props.config.stretch) {\r\n leftOffset = 0\r\n } else if (getIsSmallIndexChart(this.props.layoutModel.specificChartFunctionality)) {\r\n leftOffset = barWidth\r\n } else if (this.zoomerRightAlign) {\r\n leftOffset = getMinMaxLeftOffset({\r\n newLeftOffset:\r\n getLeftOffset({\r\n quote: chartModel.quote(),\r\n chartModel: chartModel,\r\n config: this.props.config,\r\n barWidth,\r\n barIndex: this.zoomerRightAlign.index,\r\n shouldAlignDaysToLeftApplied: false,\r\n }) + this.zoomerRightAlign.offsetDiff,\r\n chartModel: chartModel,\r\n barWidth,\r\n barIndex: getBarIndex(chartModel.quote()),\r\n })\r\n } else {\r\n return\r\n }\r\n chartModel.updateAttributes({\r\n zoomFactor,\r\n leftOffset,\r\n dateRange: null,\r\n })\r\n if (shouldCalculateRightAlign) {\r\n this.zoomerRightAlign = null\r\n }\r\n }\r\n\r\n onZoomerMouseUp = () => {\r\n this.zoomerRightAlign = null\r\n document.removeEventListener('mousemove', this.onZoomerMouseMove)\r\n document.removeEventListener('mouseup', this.onZoomerMouseUp)\r\n document.removeEventListener('touchmove', this.onZoomerTouchMove)\r\n document.removeEventListener('touchend', this.onZoomerTouchEnd)\r\n this.props.setActiveChartInteraction(null)\r\n }\r\n\r\n onZoomerReset = () => {\r\n const { chartModel, layoutModel } = this.props\r\n const zoomFactor = chartModel.chart_layout().defaultZoomFactor\r\n const barWidth = getBarWidthWithMargin({ zoomFactor, chartLayout: layoutModel })\r\n const leftOffset = getLeftOffset({\r\n quote: chartModel.quote(),\r\n chartModel,\r\n config: this.props.config,\r\n barWidth,\r\n })\r\n\r\n chartModel.updateAttributes({\r\n zoomFactor,\r\n leftOffset,\r\n dateRange: null,\r\n })\r\n }\r\n\r\n onOlderDataLoaded = () => {\r\n throw new Error('onOlderDataLoaded not implemented')\r\n // TODO implement similarly to onDataLoaded\r\n }\r\n\r\n resetMouseModel = () => {\r\n const isLoading = this.props.chartModel.panes().count() < 1\r\n if (!isLoading) {\r\n MouseModel.updateAttributes({\r\n position: null,\r\n pane: null,\r\n })\r\n }\r\n }\r\n\r\n handleQuoteChange = (quote: Quote) => {\r\n const { chartModel } = this.props\r\n\r\n // Update only date range chart\r\n if (chartModel.dateRange) {\r\n if (!quote.eql(chartModel.quote()) || chartModel.timeframe !== quote.timeframe || quote.date.length === 0) {\r\n return\r\n }\r\n updateZoomAndLeftOffsetByDateRange({ chartModel, quote })\r\n }\r\n }\r\n\r\n onDataLoaded = (newQuote: Quote, fetchType: QuoteFetchType) => {\r\n const { chartModel } = this.props\r\n const quote = chartModel.quote()\r\n if (!quote?.eql(newQuote)) {\r\n return\r\n }\r\n\r\n const shouldForceLeftOffsetUpdate = fetchType === QuoteFetchType.Refetch\r\n let newLeftOffset = chartModel.leftOffset // TODO find proper fix. If this line is removed (if we don't trigger leftOffset update), the chart stops being updated for the user until they move chart around.\r\n if (\r\n (this.props.layoutModel.scrollable === false && !this.props.layoutModel.isTouchCrossActive) ||\r\n !chartModel.isScrolled ||\r\n shouldForceLeftOffsetUpdate\r\n ) {\r\n newLeftOffset = getLeftOffset({\r\n quote,\r\n chartModel: chartModel,\r\n config: this.props.config,\r\n })\r\n }\r\n\r\n chartModel.setChartEvents(quote.chartEvents, !quote.events)\r\n\r\n if (newLeftOffset !== chartModel.leftOffset) {\r\n chartModel.getAllElements().forEach((element) => {\r\n if (element.isDrawing() && !element.isMouseDown()) {\r\n element.instance.updateScales()\r\n }\r\n })\r\n }\r\n\r\n chartModel.updateAttribute('leftOffset', newLeftOffset)\r\n\r\n this.handleQuoteChange(quote)\r\n }\r\n}\r\n\r\nexport default withChartInit(withWatchedPanesOnChartModel(Chart))\r\n","import classNames from 'classnames'\r\nimport merge from 'lodash.merge'\r\nimport React from 'react'\r\n\r\nimport { ObjectHash } from '../../../types/shared'\r\nimport { SpecificChartFunctionality } from '../../constants/common'\r\nimport { useModelState } from '../../model-hooks/use-model-state'\r\nimport Quote from '../../models/quote'\r\nimport { getChartsDimensions, isRedesignEnabled } from '../../utils'\r\nimport { getQuoteFinancialAttachmentsFromChartConfig, prefetchPerfIndicatorAllQuotes } from '../../utils/chart'\r\nimport { getLeftOffset } from '../renderUtils'\r\nimport { ChartSpinnerOverlay } from './chart-spinner-overlay'\r\nimport { CHART_CLASS_NAMES, ChartProps, DEFAULT_WRAPPER_COMPONENT } from './constants'\r\n\r\nexport function withChartInit(Component: React.ComponentType) {\r\n return function WrappedComponent(props: ChartProps) {\r\n const { WrapperComp = DEFAULT_WRAPPER_COMPONENT, gridArea } = props\r\n const isModelDestroyedRef = React.useRef(null)\r\n const model = useModelState(props.chartModel, { watchProperties: ['panes', 'quote'] })\r\n const layoutModel = useModelState(props.layoutModel, { watchProperties: ['activeChart'] })\r\n const quote = model.quote()\r\n\r\n const initChartRef = React.useRef(async () => {\r\n const { chartModel, config } = props\r\n const { premarket, hasChartEvents, aftermarket, ticker, instrument, timeframe, panes: panesConfig } = config\r\n const options = {\r\n premarket,\r\n aftermarket,\r\n events: hasChartEvents,\r\n patterns: panesConfig.some((pane) =>\r\n pane.elements?.some((element) =>\r\n element.overlays?.some((overlay: ObjectHash) => overlay.type === 'overlays/patterns')\r\n )\r\n ),\r\n }\r\n\r\n const quote = await Quote.get({\r\n ticker,\r\n instrument,\r\n timeframe,\r\n options: {\r\n ...options,\r\n financialAttachments: getQuoteFinancialAttachmentsFromChartConfig(config),\r\n },\r\n })\r\n const panesWithPerfIndicator = panesConfig.filter(({ elements }) =>\r\n elements.some(({ type }) => type === 'indicators/perf')\r\n )\r\n\r\n if (panesWithPerfIndicator) {\r\n await Promise.allSettled(\r\n panesWithPerfIndicator.map((paneWithPerfIndicator) =>\r\n prefetchPerfIndicatorAllQuotes({ paneWithPerfIndicator, timeframe, options })\r\n )\r\n )\r\n }\r\n\r\n if (isModelDestroyedRef.current) {\r\n return\r\n }\r\n\r\n config.panes.forEach((pane) => {\r\n const paneProperties = merge({}, pane)\r\n paneProperties.chart = chartModel\r\n chartModel.createPaneCascade(paneProperties)\r\n })\r\n\r\n chartModel.updateAttributes({\r\n quote,\r\n premarket: options.premarket,\r\n aftermarket: options.aftermarket,\r\n })\r\n\r\n chartModel.setChartEvents(quote.chartEvents, true)\r\n\r\n if (props.shouldResize) {\r\n const chartsDimensions = getChartsDimensions(props.layoutModel.getHTMLElementId())\r\n props.layoutModel.updateAttributes(chartsDimensions)\r\n }\r\n\r\n if (chartModel.leftOffset == null) {\r\n const leftOffset = getLeftOffset({ quote, chartModel: chartModel, config: props.config })\r\n chartModel.updateAttribute('leftOffset', leftOffset)\r\n }\r\n })\r\n\r\n React.useEffect(() => {\r\n // This prevents the being re-called on hotreload\r\n if (isModelDestroyedRef.current !== null) {\r\n return\r\n }\r\n\r\n isModelDestroyedRef.current = false\r\n\r\n const handleModelBeforeDestroy = () => {\r\n isModelDestroyedRef.current = true\r\n }\r\n\r\n model.bind('beforeDestroy', handleModelBeforeDestroy)\r\n initChartRef.current()\r\n return () => {\r\n model.unbind('beforeDestroy', handleModelBeforeDestroy)\r\n }\r\n // We want to run it only on mount\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n }, [])\r\n\r\n const isQuotePage = props.layoutModel.specificChartFunctionality === SpecificChartFunctionality.quotePage\r\n const isChartPage = props.layoutModel.specificChartFunctionality === SpecificChartFunctionality.chartPage\r\n const isFuturesForexCryptoPage = [\r\n SpecificChartFunctionality.futuresPage,\r\n SpecificChartFunctionality.forexPage,\r\n SpecificChartFunctionality.cryptoPage,\r\n ].includes(props.layoutModel.specificChartFunctionality)\r\n const isModelReady =\r\n quote && ((quote.fetchedAt === undefined && quote.close.length > 0) || quote.fetchedAt > 0 || quote)\r\n const loadingStyle =\r\n !isModelReady && isQuotePage\r\n ? // 2px is border\r\n { width: model.width ? model.width + 2 : '100%', height: model.height + 2 }\r\n : undefined\r\n\r\n return (\r\n \r\n {isChartPage && (\r\n \r\n )}\r\n {isModelReady && }\r\n \r\n )\r\n }\r\n}\r\n","import React from 'react'\r\n\r\nimport { useModelState } from '../../model-hooks/use-model-state'\r\nimport ChartModel from '../../models/chart'\r\n\r\nexport function withWatchedPanesOnChartModel

(Component: React.ComponentType

) {\r\n return function WrappedComponent(props: P) {\r\n const model = useModelState(props.chartModel, { watchProperties: ['panes'] })\r\n\r\n return \r\n }\r\n}\r\n","export const drawingCreatorsAsyncModule = {\r\n importFn: () => import(/* webpackChunkName: \"drawing-creators\" */ './module-entry'),\r\n cacheKey: 'drawing-creators',\r\n}\r\n","import { DrawingActions, IToolbarDrawingAction, IToolbarDrawingActionItem } from './interfaces'\r\n\r\nexport const drawingActions: Record = {\r\n [DrawingActions.AddNote]: {\r\n id: DrawingActions.AddNote,\r\n title: 'Add note',\r\n icon: 'note',\r\n },\r\n [DrawingActions.DeleteDrawings]: {\r\n id: DrawingActions.DeleteDrawings,\r\n title: 'Remove all drawings',\r\n icon: 'drawingActionDelete',\r\n },\r\n [DrawingActions.DeleteAutoSavedDrawings]: {\r\n id: DrawingActions.DeleteAutoSavedDrawings,\r\n title: 'Remove all autosaved drawings',\r\n icon: 'drawingActionDelete',\r\n },\r\n}\r\n\r\nexport const getToolbarDrawingActions = ({\r\n isAutoSaveActive,\r\n isAddNoteAvailable = false,\r\n isIdea,\r\n}: {\r\n isAutoSaveActive: boolean\r\n isAddNoteAvailable?: boolean\r\n isIdea?: boolean\r\n}): Array => [\r\n ...(isAddNoteAvailable\r\n ? [\r\n {\r\n defaultItem: drawingActions[DrawingActions.AddNote],\r\n isDisabled: isIdea,\r\n disabledTooltip: 'Add note is not available in ideas',\r\n },\r\n ]\r\n : []),\r\n {\r\n defaultItem:\r\n drawingActions[isAutoSaveActive ? DrawingActions.DeleteAutoSavedDrawings : DrawingActions.DeleteDrawings],\r\n },\r\n]\r\n","import { DrawingSetting, IToolbarDrawingSetting, IToolbarDrawingsSettingItem } from './interfaces'\r\n\r\nconst drawingSettings: Record = {\r\n [DrawingSetting.PreserveDrawings]: {\r\n id: DrawingSetting.PreserveDrawings,\r\n icon: 'drawingSettingPreserveDrawings',\r\n iconActive: 'drawingSettingPreserveDrawingsActive',\r\n title: 'Preserve drawings: Off',\r\n titleActive: 'Preserve drawings: On',\r\n },\r\n [DrawingSetting.DrawingModeContinuous]: {\r\n id: DrawingSetting.DrawingModeContinuous,\r\n icon: 'drawingSettingDrawingMode',\r\n iconActive: 'drawingSettingDrawingModeActive',\r\n title: 'Drawing mode: Single',\r\n titleActive: 'Drawing mode: Continuous',\r\n },\r\n [DrawingSetting.HideDrawings]: {\r\n id: DrawingSetting.HideDrawings,\r\n icon: 'drawingSettingHide',\r\n iconActive: 'drawingSettingShow',\r\n title: 'Hide drawings',\r\n titleActive: 'Show drawings',\r\n },\r\n [DrawingSetting.LockDrawings]: {\r\n id: DrawingSetting.LockDrawings,\r\n icon: 'drawingSettingLock',\r\n iconActive: 'drawingSettingUnlock',\r\n title: 'Lock drawings',\r\n titleActive: 'Unlock drawings',\r\n },\r\n}\r\n\r\nconst preserveDrawingsAutosaveOverride: IToolbarDrawingSetting = {\r\n id: DrawingSetting.PreserveDrawings, // DrawingSetting.PreserveDrawings so it works with current settings sync to DB\r\n icon: 'drawingSettingAutosaveOff',\r\n iconActive: 'drawingSettingAutosaveOn',\r\n iconAction: 'drawingSettingAutosaveSaving',\r\n title: 'Drawings autosave: Off',\r\n titleActive: 'Drawings Autosave: On',\r\n titleAction: 'Drawings Autosave: Saving',\r\n}\r\n\r\nexport const getToolbarDrawingSettings = ({\r\n isPreserveDrawingsAndAutosaveAvailable,\r\n isIdea,\r\n isAutoSaveInProgress,\r\n}: {\r\n isPreserveDrawingsAndAutosaveAvailable?: boolean\r\n isIdea?: boolean\r\n isAutoSaveInProgress?: boolean\r\n}): Array => {\r\n const toolbarSettings = [\r\n {\r\n defaultItem: drawingSettings[DrawingSetting.DrawingModeContinuous],\r\n },\r\n ...(isPreserveDrawingsAndAutosaveAvailable\r\n ? [\r\n {\r\n defaultItem: preserveDrawingsAutosaveOverride,\r\n isDisabled: isIdea,\r\n isInAction: isAutoSaveInProgress,\r\n disabledTooltip: 'Autosave is not available in ideas',\r\n },\r\n ]\r\n : []),\r\n {\r\n defaultItem: drawingSettings[DrawingSetting.HideDrawings],\r\n },\r\n {\r\n defaultItem: drawingSettings[DrawingSetting.LockDrawings],\r\n },\r\n ]\r\n\r\n return toolbarSettings\r\n}\r\n","import { DrawingTool, IToolbarDrawingTool, IToolbarDrawingToolItem } from './interfaces'\r\n\r\nexport const drawingTools: Record = {\r\n [DrawingTool.Mouse]: {\r\n id: DrawingTool.Mouse,\r\n title: 'Mouse',\r\n icon: 'toolMouse',\r\n },\r\n [DrawingTool.Measure]: {\r\n id: DrawingTool.Measure,\r\n title: 'Measure',\r\n icon: 'toolMeasure',\r\n },\r\n [DrawingTool.ScaledLine]: {\r\n id: DrawingTool.ScaledLine,\r\n title: 'Line',\r\n icon: 'toolLine',\r\n },\r\n [DrawingTool.Arrow]: {\r\n id: DrawingTool.Arrow,\r\n title: 'Arrow',\r\n icon: 'toolArrow',\r\n },\r\n [DrawingTool.VerticalLine]: {\r\n id: DrawingTool.VerticalLine,\r\n title: 'Vertical line',\r\n icon: 'toolMidLineV',\r\n },\r\n [DrawingTool.HorizontalLine]: {\r\n id: DrawingTool.HorizontalLine,\r\n title: 'Horizontal line',\r\n icon: 'toolMidLineH',\r\n },\r\n [DrawingTool.Rectangle]: {\r\n id: DrawingTool.Rectangle,\r\n title: 'Rectangle',\r\n icon: 'toolRect',\r\n },\r\n [DrawingTool.RotatedRectangle]: {\r\n id: DrawingTool.RotatedRectangle,\r\n title: 'Rotated rectangle',\r\n icon: 'toolRectRotated',\r\n },\r\n [DrawingTool.Triangle]: {\r\n id: DrawingTool.Triangle,\r\n title: 'Triangle',\r\n icon: 'toolTriangle',\r\n },\r\n [DrawingTool.Ellipse]: {\r\n id: DrawingTool.Ellipse,\r\n title: 'Ellipse',\r\n icon: 'toolEllipse',\r\n },\r\n [DrawingTool.Curve]: {\r\n id: DrawingTool.Curve,\r\n title: 'Curve',\r\n icon: 'toolCurve',\r\n },\r\n [DrawingTool.Pitchfork]: {\r\n id: DrawingTool.Pitchfork,\r\n title: 'Pitchfork',\r\n icon: 'toolPitchfork',\r\n },\r\n [DrawingTool.Polygon]: {\r\n id: DrawingTool.Polygon,\r\n title: 'Polygon',\r\n icon: 'toolPolygon',\r\n },\r\n [DrawingTool.Xabcd]: {\r\n id: DrawingTool.Xabcd,\r\n title: 'XABCD',\r\n icon: 'toolXABCD',\r\n },\r\n [DrawingTool.ScaledText]: {\r\n id: DrawingTool.ScaledText,\r\n title: 'Text',\r\n icon: 'toolText',\r\n },\r\n [DrawingTool.Brush]: {\r\n id: DrawingTool.Brush,\r\n title: 'Brush',\r\n icon: 'toolBrush',\r\n },\r\n [DrawingTool.ElliottWaves]: {\r\n id: DrawingTool.ElliottWaves,\r\n title: 'Elliott waves',\r\n icon: 'toolElliottWave',\r\n },\r\n [DrawingTool.FibonacciRetracements]: {\r\n id: DrawingTool.FibonacciRetracements,\r\n title: 'Fibonacci retracements',\r\n icon: 'toolFibonacci',\r\n },\r\n [DrawingTool.Position]: {\r\n id: DrawingTool.Position,\r\n title: 'Position',\r\n icon: 'toolPosition',\r\n },\r\n [DrawingTool.Callout]: {\r\n id: DrawingTool.Callout,\r\n title: 'Callout',\r\n icon: 'toolCallout',\r\n },\r\n}\r\n\r\nexport const toolbarDrawingTools: Array = [\r\n {\r\n defaultItem: drawingTools[DrawingTool.Mouse],\r\n },\r\n {\r\n defaultItem: drawingTools[DrawingTool.Measure],\r\n },\r\n {\r\n defaultItem: drawingTools[DrawingTool.ScaledLine],\r\n toolGroup: [\r\n drawingTools[DrawingTool.ScaledLine],\r\n drawingTools[DrawingTool.VerticalLine],\r\n drawingTools[DrawingTool.HorizontalLine],\r\n drawingTools[DrawingTool.Curve],\r\n ],\r\n toolGroupTitle: 'Line tools',\r\n },\r\n {\r\n defaultItem: drawingTools[DrawingTool.Arrow],\r\n },\r\n {\r\n defaultItem: drawingTools[DrawingTool.Rectangle],\r\n },\r\n {\r\n defaultItem: drawingTools[DrawingTool.RotatedRectangle],\r\n },\r\n {\r\n defaultItem: drawingTools[DrawingTool.Triangle],\r\n },\r\n {\r\n defaultItem: drawingTools[DrawingTool.Ellipse],\r\n },\r\n {\r\n defaultItem: drawingTools[DrawingTool.Polygon],\r\n },\r\n {\r\n defaultItem: drawingTools[DrawingTool.Xabcd],\r\n toolGroup: [drawingTools[DrawingTool.Xabcd], drawingTools[DrawingTool.Pitchfork]],\r\n toolGroupTitle: 'XABCD tools',\r\n },\r\n {\r\n defaultItem: drawingTools[DrawingTool.ScaledText],\r\n toolGroup: [drawingTools[DrawingTool.ScaledText], drawingTools[DrawingTool.Callout]],\r\n toolGroupTitle: 'Text tools',\r\n },\r\n {\r\n defaultItem: drawingTools[DrawingTool.Brush],\r\n },\r\n {\r\n defaultItem: drawingTools[DrawingTool.ElliottWaves],\r\n },\r\n {\r\n defaultItem: drawingTools[DrawingTool.FibonacciRetracements],\r\n },\r\n {\r\n defaultItem: drawingTools[DrawingTool.Position],\r\n },\r\n]\r\n","import { Toolbar as ToolbarComponent, ToolbarDivider, ToolbarGroupProps, ToolbarItem } from '@finviz/website'\r\nimport classnames from 'classnames'\r\nimport React from 'react'\r\n\r\nimport { PaneArea } from '../../../types/shared'\r\nimport { SpecificChartFunctionality } from '../../constants/common'\r\nimport { drawingCreatorsAsyncModule } from '../../creators/async-modules'\r\nimport { ElementStyleDialogContext } from '../../modals/element_style'\r\nimport { useModelState } from '../../model-hooks/use-model-state'\r\nimport { AutoSaveState } from '../../models/constants'\r\nimport PaneModel from '../../models/pane'\r\nimport { useAsyncModule } from '../../utils/async-modules-utils'\r\nimport { getIsPreserveDrawingsAndAutosaveAvailable } from '../../utils/chart'\r\nimport { getToolbarDrawingActions } from './drawingActions'\r\nimport { getToolbarDrawingSettings } from './drawingSettings'\r\nimport { drawingTools, toolbarDrawingTools } from './drawingTools'\r\nimport { DrawingSetting, DrawingTool, IToolBarProps } from './interfaces'\r\n\r\nexport const DISABLED_ITEM_TOOLTIP_LABEL = \"Disabled due 'lock/hide' drawings active\"\r\n\r\nexport default function Toolbar({\r\n isSidebar,\r\n isHorizontal,\r\n isMobileOverlay,\r\n activeTool,\r\n chartLayoutModel,\r\n onActiveToolChange,\r\n onDrawingActionClick,\r\n onDrawingSettingClick,\r\n onDrawingEnd,\r\n drawingSettings,\r\n isAlternativeTheme,\r\n areToolsDisabled,\r\n}: IToolBarProps) {\r\n const ignoreRowId =\r\n isHorizontal || chartLayoutModel.specificChartFunctionality === SpecificChartFunctionality.chartPage\r\n const [drawingCreatorsModule, { isLoading: isDrawingCreatorsModuleLoading }] = useAsyncModule({\r\n ...drawingCreatorsAsyncModule,\r\n shouldLoadModule: true,\r\n })\r\n const { autoSaveState } = useModelState(\r\n React.useMemo(() => chartLayoutModel.drawingsInternalStore(), [chartLayoutModel]),\r\n { watchProperties: ['autoSaveState'] }\r\n )\r\n const [isDrawing, setIsDrawing] = React.useState(false)\r\n const openElementStyleDialog = React.useContext(ElementStyleDialogContext)\r\n\r\n const availableDrawingSettings = getToolbarDrawingSettings({\r\n isPreserveDrawingsAndAutosaveAvailable: getIsPreserveDrawingsAndAutosaveAvailable(chartLayoutModel),\r\n isAutoSaveInProgress: autoSaveState === AutoSaveState.Saving,\r\n isIdea: !!chartLayoutModel.idea?.id,\r\n })\r\n\r\n const availableDrawingActions = getToolbarDrawingActions({\r\n isAutoSaveActive: autoSaveState !== AutoSaveState.Off,\r\n isAddNoteAvailable: chartLayoutModel.specificChartFunctionality === SpecificChartFunctionality.chartPage,\r\n isIdea: !!chartLayoutModel.idea?.id,\r\n })\r\n\r\n React.useEffect(() => {\r\n if (!drawingCreatorsModule) {\r\n return\r\n }\r\n\r\n const onMouseDown = (model: PaneModel, area: PaneArea & { isTouch: boolean }) => {\r\n const isDrawingModeContinuous = drawingSettings[DrawingSetting.DrawingModeContinuous]\r\n const hasData = model.chart().quote().close.length > 0\r\n const hasHiddenDrawings = drawingSettings[DrawingSetting.HideDrawings]\r\n const tool = drawingTools[activeTool].id\r\n\r\n if (tool === DrawingTool.Mouse || isDrawing || hasHiddenDrawings || !hasData) {\r\n return\r\n }\r\n\r\n setIsDrawing(true)\r\n const { drawingToolsTouchCreatorsByType, drawingToolsCreatorsByType } = drawingCreatorsModule\r\n const ToolClass = area.isTouch ? drawingToolsTouchCreatorsByType[tool] : drawingToolsCreatorsByType[tool]\r\n const element = model.elements().create({\r\n instance: new ToolClass(area, {}, model, openElementStyleDialog, () => {\r\n if (!isDrawingModeContinuous) {\r\n onActiveToolChange(DrawingTool.Mouse)\r\n }\r\n setIsDrawing(false)\r\n onDrawingEnd?.()\r\n }),\r\n })\r\n element.one('destroy', ({ instance }) => {\r\n if (instance.getIsCreator()) {\r\n setIsDrawing(false)\r\n onDrawingEnd?.()\r\n }\r\n })\r\n\r\n element.trigger('select', element)\r\n }\r\n PaneModel.bind('mousedown', onMouseDown)\r\n return () => {\r\n PaneModel.unbind('mousedown', onMouseDown)\r\n }\r\n }, [\r\n activeTool,\r\n onActiveToolChange,\r\n openElementStyleDialog,\r\n onDrawingEnd,\r\n drawingCreatorsModule,\r\n drawingSettings,\r\n isDrawing,\r\n ])\r\n\r\n return (\r\n \r\n {toolbarDrawingTools.map((item, index) => {\r\n const isActive = activeTool === item.defaultItem.id || item.toolGroup?.some((tool) => tool.id === activeTool)\r\n const isToolLoading = isDrawingCreatorsModuleLoading && isActive\r\n\r\n return (\r\n \r\n )\r\n })}\r\n \r\n {availableDrawingSettings.map((item, index) => (\r\n \r\n ))}\r\n {availableDrawingActions.map((item, index) => (\r\n \r\n ))}\r\n \r\n )\r\n}\r\n","import Toolbar from './toolbar'\r\n\r\nexport default Toolbar\r\n","import { Textarea } from '@finviz/website'\r\nimport React from 'react'\r\n\r\nimport { ObjectHash } from '../../../../types/shared'\r\nimport { useModelState } from '../../../model-hooks/use-model-state'\r\nimport Chart from '../../../models/chart'\r\nimport ChartLayout from '../../../models/chart_layout'\r\nimport { useDrawingAutoSaveControls } from '../../autosave/use-drawing-auto-save-controls'\r\nimport { getElementNoteText, getTickersAndContainerTypesInLayoutModel } from '../../autosave/utils'\r\n\r\ninterface ChartAutoSaveNoteProps {\r\n ticker: string\r\n note: string\r\n onNoteChange: (note: string, ticker: string) => void\r\n}\r\n\r\nfunction ChartAutoSaveNote({ ticker, note, onNoteChange }: ChartAutoSaveNoteProps) {\r\n return (\r\n ) => {\r\n onNoteChange(e.target.value, ticker)\r\n }}\r\n />\r\n )\r\n}\r\n\r\ninterface Props {\r\n chartLayoutModel: ChartLayout\r\n}\r\n\r\nexport function ChartAutoSaveNotes({ chartLayoutModel }: Props) {\r\n const { handleAutoSaveNoteChange } = useDrawingAutoSaveControls(chartLayoutModel)\r\n const [tickers, setTickers] = React.useState([])\r\n const unwatchedInternalStore = React.useMemo(() => chartLayoutModel.drawingsInternalStore(), [chartLayoutModel])\r\n const drawingsInternalStore = useModelState(unwatchedInternalStore, { watchProperties: ['elements'] })\r\n\r\n React.useEffect(() => {\r\n // There was no better way how to listen on ticker changes which is necessary for displaying correct text areas\r\n const handleChartChange = () => {\r\n const { tickers } = getTickersAndContainerTypesInLayoutModel(chartLayoutModel)\r\n setTickers(tickers)\r\n }\r\n\r\n Chart.bind('change', handleChartChange)\r\n handleChartChange()\r\n return () => {\r\n Chart.unbind('change', handleChartChange)\r\n }\r\n }, [chartLayoutModel])\r\n\r\n const tickerNoteMap = React.useMemo(() => {\r\n const map: ObjectHash = {}\r\n drawingsInternalStore.elements.forEach((element) => {\r\n if (element.containerType === 'note' && tickers.includes(element.ticker)) {\r\n map[element.ticker] = getElementNoteText(element)\r\n }\r\n })\r\n\r\n return map\r\n }, [drawingsInternalStore.elements, tickers])\r\n\r\n return (\r\n

\r\n {tickers.map((ticker) => (\r\n \r\n ))}\r\n
\r\n )\r\n}\r\n","import { Dialog, DialogBody, DialogHeader, DialogStateReturn, ZIndexContext } from '@finviz/website'\r\nimport React from 'react'\r\n\r\nimport ChartLayout from '../../../models/chart_layout'\r\nimport { ChartAutoSaveNotes } from './auto-save-notes'\r\n\r\ninterface INoteDialog {\r\n state: DialogStateReturn\r\n chartLayoutModel: ChartLayout\r\n}\r\n\r\nexport function AutoSaveNotesDialog({ state, chartLayoutModel }: INoteDialog) {\r\n const isOpen = state.useState('open')\r\n const isAnimating = state.useState('animating')\r\n const isFullyClosed = !isOpen && !isAnimating\r\n\r\n return (\r\n \r\n \r\n Notes\r\n {!isFullyClosed && }\r\n \r\n \r\n )\r\n}\r\n","import {\r\n Button,\r\n ConfirmationDialog as ConfirmationDialogComponent,\r\n DialogDismiss,\r\n DialogStateReturn,\r\n} from '@finviz/website'\r\nimport React from 'react'\r\n\r\nconst getDialogContent = ({\r\n isAutosaveDialogContent,\r\n tickers,\r\n}: {\r\n isAutosaveDialogContent: boolean\r\n tickers: string[]\r\n}) => {\r\n if (isAutosaveDialogContent) {\r\n return {\r\n title: 'Remove all autosaved drawings?',\r\n message: (\r\n <>\r\n Do you really want to remove all autosaved drawings? This action is irreversible and will remove all\r\n non-idea drawings for {tickers.join(', ')}.\r\n \r\n ),\r\n }\r\n }\r\n return {\r\n title: 'Remove all drawings?',\r\n message: `Do you really want to remove all drawings? This action only affects the current page and visible tickers. This action doesn't remove autosaved drawings or ideas.`,\r\n }\r\n}\r\n\r\nexport interface IConfirmationDialog {\r\n state: DialogStateReturn\r\n onAction: () => void\r\n onCancel?: () => void\r\n isAutosaveDialogContent: boolean\r\n tickers: string[]\r\n}\r\n\r\nexport function ConfirmationDialog({\r\n state,\r\n onAction,\r\n onCancel,\r\n isAutosaveDialogContent = false,\r\n tickers,\r\n}: IConfirmationDialog) {\r\n const dialogContent = getDialogContent({ isAutosaveDialogContent, tickers })\r\n\r\n return (\r\n \r\n \r\n \r\n \r\n }\r\n >\r\n {dialogContent.message}\r\n \r\n )\r\n}\r\n","import { Button, ButtonProps, Dropdown, Icon, useDropdownState } from '@finviz/website'\r\nimport React from 'react'\r\nimport ReactDOM from 'react-dom'\r\nimport { useSearchParams } from 'react-router-dom'\r\n\r\nimport { SIDEBAR_QUERY_PARAM } from '../../sidebar/sidebar'\r\nimport { MOBILE_TOOLBAR_DIV_ID } from '../../sidebar/sidebar-tabs'\r\nimport { drawingTools } from '../drawingTools'\r\nimport { DrawingActions, DrawingTool, IToolBarProps } from '../interfaces'\r\nimport Toolbar from '../toolbar'\r\n\r\ntype ToolbarMobileProps = Omit\r\n\r\nexport default function ToolbarMobile({\r\n activeTool,\r\n onActiveToolChange,\r\n onDrawingActionClick,\r\n ...rest\r\n}: ToolbarMobileProps) {\r\n const toolbarState = useDropdownState()\r\n const hideToolbar = toolbarState.hideAll\r\n const [urlSearchParams, setUrlSearchParams] = useSearchParams()\r\n\r\n // get toolbar mobile element on first render\r\n const [toolbarMobileElement, setToolbarMobileElement] = React.useState(null)\r\n React.useEffect(() => {\r\n setToolbarMobileElement(document.getElementById(MOBILE_TOOLBAR_DIV_ID))\r\n }, [])\r\n\r\n const drawButtonProps = React.useMemo(() => {\r\n if (urlSearchParams.has(SIDEBAR_QUERY_PARAM) || activeTool === DrawingTool.Mouse) {\r\n return {\r\n children: 'Draw',\r\n leftContent: 'draw',\r\n size: 'medium',\r\n onClick: () => {\r\n setUrlSearchParams((params) => {\r\n params.delete(SIDEBAR_QUERY_PARAM)\r\n return params\r\n })\r\n },\r\n }\r\n }\r\n\r\n return {\r\n appearance: 'square',\r\n active: true,\r\n size: 'medium',\r\n theme: 'chipTransparent',\r\n leftContent: ,\r\n }\r\n }, [activeTool, setUrlSearchParams, urlSearchParams])\r\n\r\n const handleActiveToolChange = React.useCallback(\r\n (drawingTool: DrawingTool, trigger?: 'button' | 'select' | 'group') => {\r\n onActiveToolChange(drawingTool, trigger)\r\n\r\n if (trigger !== 'group') return hideToolbar()\r\n },\r\n [hideToolbar, onActiveToolChange]\r\n )\r\n\r\n const handleDrawingActionClick = React.useCallback(\r\n (actionId: DrawingActions) => {\r\n onDrawingActionClick?.(actionId)\r\n hideToolbar()\r\n },\r\n [hideToolbar, onDrawingActionClick]\r\n )\r\n\r\n if (!toolbarMobileElement) return null\r\n\r\n return ReactDOM.createPortal(\r\n }\r\n // Move the dropdown to cover the button\r\n gutter={-32}\r\n modal={activeTool === DrawingTool.Mouse}\r\n backdrop={false}\r\n unmountOnHide={false}\r\n placement=\"top-end\"\r\n className=\"-translate-x-1\"\r\n >\r\n \r\n ,\r\n toolbarMobileElement\r\n )\r\n}\r\n","import React from 'react'\r\n\r\nimport { useModelState } from '../../model-hooks/use-model-state'\r\nimport ChartLayout from '../../models/chart_layout'\r\nimport { AutoSaveState } from '../../models/constants'\r\n\r\ninterface LoadLatestDataButtonProps {\r\n chartLayoutModel: ChartLayout\r\n}\r\n\r\nexport function AutoSaveStateIndicator({ chartLayoutModel }: LoadLatestDataButtonProps) {\r\n const drawingsInternalStoreUnwatched = React.useMemo(\r\n () => chartLayoutModel.drawingsInternalStore(),\r\n [chartLayoutModel]\r\n )\r\n const { autoSaveState } = useModelState(drawingsInternalStoreUnwatched, { watchProperties: ['autoSaveState'] })!\r\n const [isVisible, setIsVisible] = React.useState(false)\r\n\r\n React.useEffect(() => {\r\n if (autoSaveState === AutoSaveState.Off) {\r\n return\r\n }\r\n\r\n let setVisibilityTimeout: number | null = null\r\n const newIsVisible = autoSaveState !== AutoSaveState.Saved\r\n\r\n setVisibilityTimeout = window.setTimeout(\r\n () => {\r\n setIsVisible(newIsVisible)\r\n },\r\n newIsVisible ? 0 : 3000\r\n )\r\n\r\n const checkIfNeededPreventLeaving = (event: BeforeUnloadEvent) => {\r\n if (autoSaveState === AutoSaveState.Saved) {\r\n return undefined\r\n }\r\n\r\n const message = `Your latest changes haven't been saved yet. If you leave now, your changes might be lost.`\r\n event.returnValue = message\r\n return message\r\n }\r\n\r\n window.addEventListener('beforeunload', checkIfNeededPreventLeaving)\r\n\r\n return () => {\r\n window.removeEventListener('beforeunload', checkIfNeededPreventLeaving)\r\n if (setVisibilityTimeout) {\r\n clearTimeout(setVisibilityTimeout)\r\n }\r\n }\r\n }, [autoSaveState])\r\n\r\n if (!isVisible) {\r\n return null\r\n }\r\n\r\n // @todo - add proper indicator component here\r\n return null\r\n}\r\n","import { Textarea } from '@finviz/website'\r\nimport React from 'react'\r\n\r\nimport { useModelState } from '../../model-hooks/use-model-state'\r\nimport ChartLayout from '../../models/chart_layout'\r\nimport { isRedesignEnabled } from '../../utils'\r\nimport { useDrawingAutoSaveControls } from '../autosave/use-drawing-auto-save-controls'\r\n\r\ninterface Props {\r\n chartLayoutModel: ChartLayout\r\n ideaNoteRef?: React.RefObject\r\n}\r\n\r\nconst hasRedesign = isRedesignEnabled()\r\n\r\nexport function ChartLayoutAutoSaveNote({ chartLayoutModel: chartLayoutModelUnwatched, ideaNoteRef }: Props) {\r\n const chartLayoutModel = useModelState(chartLayoutModelUnwatched, {\r\n watchProperties: ['idea'],\r\n })!\r\n const { handleIdeaNoteChange } = useDrawingAutoSaveControls(chartLayoutModel)\r\n\r\n if (!chartLayoutModel.editable) {\r\n return null\r\n }\r\n\r\n return (\r\n
\r\n {!hasRedesign &&
Note:
}\r\n
\r\n ) => {\r\n handleIdeaNoteChange(e.target.value)\r\n }}\r\n />\r\n
\r\n
\r\n )\r\n}\r\n","import { useDialogState } from '@finviz/website'\r\nimport React from 'react'\r\n\r\nimport { publishModalAsyncModule } from '../../modals/publish/async-modules'\r\nimport ChartLayout from '../../models/chart_layout'\r\nimport { useAsyncModule } from '../../utils/async-modules-utils'\r\n\r\ninterface PublishOldButtonClickListenerProps {\r\n isListening: boolean\r\n layoutModel: ChartLayout\r\n}\r\n\r\nexport function getPublishChartHtmlElements() {\r\n const publishChartElements = document.getElementsByClassName('js-publish-chart')\r\n const publishChartHtmlElements = Array.from(publishChartElements) as HTMLElement[]\r\n\r\n return publishChartHtmlElements\r\n}\r\n\r\nfunction getChartImgUrl(index: number) {\r\n const imgElement = document.getElementById(`chart${index}`) as HTMLImageElement | null\r\n return imgElement?.src ?? null\r\n}\r\n\r\nexport function PublishOldButtonClickListener({ isListening, layoutModel }: PublishOldButtonClickListenerProps) {\r\n const dialog = useDialogState()\r\n const isOpen = dialog.useState('open')\r\n const [dialogConfig, setDialogConfig] = React.useState({\r\n isCanvas: true,\r\n chartImgUrl: null as null | string,\r\n timeframe: '',\r\n ticker: '',\r\n })\r\n const [publishModalModule] = useAsyncModule({\r\n ...publishModalAsyncModule,\r\n shouldLoadModule: isOpen,\r\n })\r\n const PublishDialog = publishModalModule?.default\r\n\r\n React.useEffect(() => {\r\n const publishChartHtmlElements = getPublishChartHtmlElements()\r\n const clickHandler = (event: MouseEvent) => {\r\n const { index, ticker, timeframe } = (event.currentTarget as HTMLElement).dataset\r\n if (index && ticker && timeframe) {\r\n const indexInt = Number.parseInt(index)\r\n setDialogConfig({\r\n ticker,\r\n timeframe,\r\n isCanvas: indexInt === 0,\r\n chartImgUrl: indexInt > 0 ? getChartImgUrl(indexInt) : null,\r\n })\r\n dialog.show()\r\n }\r\n }\r\n\r\n if (isListening) {\r\n publishChartHtmlElements.forEach((el) => {\r\n el.addEventListener('click', clickHandler)\r\n })\r\n }\r\n\r\n return () => {\r\n publishChartHtmlElements.forEach((el) => {\r\n el.removeEventListener('click', clickHandler)\r\n })\r\n }\r\n }, [dialog, isListening])\r\n\r\n return PublishDialog ? : null\r\n}\r\n","import {\r\n Button,\r\n Dialog,\r\n DialogBody,\r\n DialogDismiss,\r\n DialogFooter,\r\n DialogHeader,\r\n DialogStateReturn,\r\n Paragraph,\r\n} from '@finviz/website'\r\nimport React from 'react'\r\n\r\nexport enum IdeaDrawingsConfirmationOptions {\r\n Merge,\r\n Override,\r\n Nothing,\r\n Cancel,\r\n}\r\n\r\ninterface IIdeaLeaveDialog {\r\n state: DialogStateReturn\r\n actionCallback: (action: IdeaDrawingsConfirmationOptions) => void\r\n}\r\n\r\nexport function IdeaLeaveDialog({ state, actionCallback }: IIdeaLeaveDialog) {\r\n return (\r\n actionCallback(IdeaDrawingsConfirmationOptions.Cancel)} />}\r\n >\r\n actionCallback(IdeaDrawingsConfirmationOptions.Cancel)}>\r\n You’re About to Leave your Idea\r\n \r\n \r\n
\r\n What would you like to do with the drawings from your current Idea?\r\n \r\n Replace Drawings\r\n
\r\n Your Autosaved Drawings for this ticker will be deleted, and the Idea Drawings will be copied to the live\r\n chart.\r\n
\r\n \r\n Combine Drawings\r\n
\r\n The Idea Drawings will be copied to the live chart without changing the positions or settings of any\r\n Autosaved Drawings. This may cause duplicates if some drawings were also autosaved.\r\n
\r\n \r\n Do Nothing\r\n
\r\n Close the idea without changing any Autosaved Drawings.\r\n
\r\n
\r\n
\r\n \r\n actionCallback(IdeaDrawingsConfirmationOptions.Override)}\r\n >\r\n Replace\r\n \r\n actionCallback(IdeaDrawingsConfirmationOptions.Merge)}\r\n >\r\n Combine\r\n \r\n actionCallback(IdeaDrawingsConfirmationOptions.Nothing)}\r\n >\r\n Do Nothing\r\n \r\n \r\n \r\n )\r\n}\r\n","import { useDialogState, useTrackPageView } from '@finviz/website'\r\nimport * as dateFns from 'date-fns'\r\nimport React from 'react'\r\nimport { useLocation, useNavigate } from 'react-router-dom'\r\n\r\nimport {\r\n ChartElementType,\r\n ChartsOrQuotePageQueryParams,\r\n ChartsPageQueryParams,\r\n QuotePageQueryChartTypes,\r\n QuotePageQueryParams,\r\n SpecificChartFunctionality,\r\n TIMEFRAME,\r\n} from '../../constants/common'\r\nimport Chart from '../../models/chart'\r\nimport ChartLayoutModel from '../../models/chart_layout'\r\nimport { getRawTickerForInstrument } from '../../models/utils'\r\nimport utils from '../../utils'\r\nimport { getInstrument, handleTypeChange } from '../../utils/chart'\r\nimport { getUuid } from '../../utils/helpers'\r\nimport { initHlc } from '../../utils/hlc'\r\nimport { decodeQueryString, encodeQueryString } from '../../utils/query_string'\r\nimport { IdeaLeaveDialog } from '../autosave/idea-leave-dialog'\r\nimport { IdeaDrawingsConfirmationOptions } from '../autosave/idea-leave-dialog'\r\nimport { useDrawingAutoSaveApi } from '../autosave/use-drawing-autosave-api'\r\nimport { getTickersAndContainerTypesInLayoutModel, handleCallMethodOnAllDrawings } from '../autosave/utils'\r\nimport { getChartElementTypeFromResponseType } from '../utils'\r\n\r\nconst getChartElementTypeFromQueryType = (queryType: QuotePageQueryChartTypes | null) => {\r\n switch (queryType) {\r\n case QuotePageQueryChartTypes.l:\r\n return ChartElementType.LineChart\r\n case QuotePageQueryChartTypes.hc:\r\n return ChartElementType.HollowCandleStick\r\n case QuotePageQueryChartTypes.ha:\r\n return ChartElementType.HeikinAshi\r\n case QuotePageQueryChartTypes.o:\r\n return ChartElementType.OhlcChart\r\n case QuotePageQueryChartTypes.p:\r\n return ChartElementType.PerfChart\r\n case QuotePageQueryChartTypes.c:\r\n case QuotePageQueryChartTypes.cs:\r\n return ChartElementType.CandleStick\r\n default:\r\n return (\r\n getChartElementTypeFromResponseType(window.FinvizSettings?.TA?.style ?? null) ?? ChartElementType.CandleStick\r\n )\r\n }\r\n}\r\n\r\nconst useChartRouteChange = (chartLayoutModel: ChartLayoutModel | null) => {\r\n useTrackPageView({ trackInitial: false })\r\n const location = useLocation()\r\n const navigate = useNavigate()\r\n const { deleteAllDrawings } = useDrawingAutoSaveApi()\r\n const dialog = useDialogState()\r\n const isIdeasDialogOpen = dialog.useState('open')\r\n\r\n const isQuotePage = chartLayoutModel?.specificChartFunctionality === SpecificChartFunctionality.quotePage\r\n const isChartPage = chartLayoutModel?.specificChartFunctionality === SpecificChartFunctionality.chartPage\r\n const isFuturesForexCryptoPage = [\r\n SpecificChartFunctionality.futuresPage,\r\n SpecificChartFunctionality.forexPage,\r\n SpecificChartFunctionality.cryptoPage,\r\n ].includes(chartLayoutModel?.specificChartFunctionality as SpecificChartFunctionality)\r\n\r\n React.useEffect(() => {\r\n if (isChartPage) {\r\n utils.setCookie(\r\n 'chartsUrl',\r\n `?${encodeQueryString({ ...decodeQueryString(location.search), i: undefined, settings: undefined })}`,\r\n dateFns.add(new Date(), { months: 1 })\r\n )\r\n }\r\n }, [isChartPage, location.search])\r\n\r\n React.useEffect(() => {\r\n const decodedQueryString = decodeQueryString(location.search)\r\n // We can navigate to idea chart without a refresh e.g. using browser back button\r\n // It breaks charts because we don't have idea data & idea quote anymore\r\n // So if we end up on a page with idea in the url and we don't have any idea data in chartLayout model we'll refresh the page\r\n if (chartLayoutModel && decodedQueryString.i && !chartLayoutModel.idea?.id) {\r\n window.location.reload()\r\n }\r\n // No need to have chartLayoutModel as dependecny here , I'm only interested in idea on the model\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n }, [location.search, chartLayoutModel?.idea?.id])\r\n\r\n const updateChartConfig = React.useCallback(() => {\r\n if (!chartLayoutModel) return\r\n\r\n const decodedSearch = decodeQueryString(location.search)\r\n\r\n const urlType = (decodedSearch as QuotePageQueryParams).ty ?? null\r\n handleTypeChange({\r\n type: getChartElementTypeFromQueryType(urlType),\r\n chartLayoutModel,\r\n })\r\n\r\n if (isChartPage && chartLayoutModel.layout !== (decodedSearch as ChartsPageQueryParams).l) {\r\n chartLayoutModel.updateAttributes({ layout: (decodedSearch as ChartsPageQueryParams).l })\r\n }\r\n\r\n chartLayoutModel.getAllCharts().forEach((chartModel, chartIndex) => {\r\n const urlTicker = decodedSearch.t.split(',')[chartIndex] ?? null\r\n const urlTimeframe = decodedSearch.p?.split(',')[chartIndex] ?? null\r\n const urlDateRange = decodedSearch.r?.split(',')[chartIndex] ?? null\r\n const upperCaseTicker = urlTicker?.toUpperCase()\r\n\r\n /**\r\n * Only Charts page charts can change instruments. Other pages need forced\r\n * instrument because we might not be able to guess it from urlTicker\r\n */\r\n let instrument = getInstrument(upperCaseTicker)\r\n if (chartLayoutModel.specificChartFunctionality !== SpecificChartFunctionality.chartPage) {\r\n instrument = chartModel.instrument\r\n }\r\n\r\n const newChartConfig = {\r\n instrument,\r\n ticker: getRawTickerForInstrument(instrument, upperCaseTicker),\r\n timeframe: urlTimeframe,\r\n dateRange: urlDateRange,\r\n }\r\n\r\n if (Object.entries(newChartConfig).some(([key, value]) => chartModel[key as keyof Chart] !== value)) {\r\n chartModel.updateAttributesAndSync(newChartConfig)\r\n }\r\n })\r\n }, [chartLayoutModel, location.search, isChartPage])\r\n\r\n React.useEffect(() => {\r\n const decodedSearch = decodeQueryString(location.search)\r\n\r\n if (\r\n !chartLayoutModel ||\r\n !decodedSearch.p ||\r\n !decodedSearch.t ||\r\n !(isQuotePage || isChartPage || isFuturesForexCryptoPage)\r\n ) {\r\n if (!decodedSearch.p && isQuotePage) {\r\n navigate(\r\n {\r\n search: `?${encodeQueryString({\r\n ...decodedSearch,\r\n p: window.FinvizSettings.defaultPeriod ?? TIMEFRAME.d,\r\n r: window.FinvizSettings.defaultDateRange,\r\n })}`,\r\n },\r\n {\r\n replace: true,\r\n }\r\n )\r\n }\r\n return\r\n }\r\n if (chartLayoutModel.idea?.id && isIdeasDialogOpen) {\r\n dialog.hide()\r\n }\r\n\r\n if (!decodedSearch.i && chartLayoutModel.idea?.id) {\r\n const urlTicker = decodedSearch.t.split(',')\r\n const isSameTicker = chartLayoutModel\r\n .getAllCharts()\r\n .every((chart, i) => chart.getQuoteRawTicker() === urlTicker[i])\r\n\r\n if (isSameTicker && window.FinvizSettings.hasUserPremium && chartLayoutModel.isPreserveDrawingsActive) {\r\n dialog.show()\r\n return\r\n }\r\n if (!chartLayoutModel.isPreserveDrawingsActive || !isSameTicker) {\r\n handleCallMethodOnAllDrawings({ chartLayoutModel, elementMethod: 'destroyCascade' })\r\n }\r\n chartLayoutModel.exitIdea()\r\n }\r\n updateChartConfig()\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n }, [\r\n location.search,\r\n navigate,\r\n chartLayoutModel,\r\n isQuotePage,\r\n isChartPage,\r\n isFuturesForexCryptoPage,\r\n updateChartConfig,\r\n ])\r\n\r\n const handleIdeaLeave = React.useCallback(\r\n async (action: IdeaDrawingsConfirmationOptions) => {\r\n if (!chartLayoutModel) return\r\n if (action === IdeaDrawingsConfirmationOptions.Cancel) {\r\n navigate(-1)\r\n return\r\n }\r\n switch (action) {\r\n case IdeaDrawingsConfirmationOptions.Merge: {\r\n handleCallMethodOnAllDrawings({\r\n chartLayoutModel,\r\n elementMethod: 'refreshElementId',\r\n })\r\n break\r\n }\r\n case IdeaDrawingsConfirmationOptions.Override: {\r\n const { tickers } = getTickersAndContainerTypesInLayoutModel(chartLayoutModel)\r\n await deleteAllDrawings({ tickers, lastLocalChange: initHlc(getUuid(), Date.now()) })\r\n break\r\n }\r\n case IdeaDrawingsConfirmationOptions.Nothing: {\r\n handleCallMethodOnAllDrawings({\r\n chartLayoutModel,\r\n elementMethod: 'destroyCascade',\r\n })\r\n break\r\n }\r\n default:\r\n break\r\n }\r\n chartLayoutModel.exitIdea()\r\n updateChartConfig()\r\n },\r\n [chartLayoutModel, updateChartConfig, deleteAllDrawings, navigate]\r\n )\r\n\r\n return {\r\n dialog,\r\n handleIdeaLeave,\r\n }\r\n}\r\n\r\nfunction getChartLayoutWithChartRouteChange

(\r\n Component: React.ComponentType

\r\n) {\r\n return function WrappedComponent(props: P) {\r\n const { dialog, handleIdeaLeave } = useChartRouteChange(props.chartLayoutModel)\r\n return (\r\n <>\r\n \r\n \r\n \r\n )\r\n }\r\n}\r\n\r\nexport function withChartRouteChange

(\r\n Component: React.ComponentType

\r\n) {\r\n // Chart layout is used in ReactRouter context and also outside of RR context\r\n // if we use RR hooks outside the context it will crash so this function will return different component for quote & chart pages than for other usecases\r\n const ChartLayoutComponent = getChartLayoutWithChartRouteChange(Component)\r\n return function WrappedComponent(props: P) {\r\n const { ty } = decodeQueryString()\r\n const isChartPage = props.chartLayoutModel.specificChartFunctionality === SpecificChartFunctionality.chartPage\r\n const isQuotePage = props.chartLayoutModel.specificChartFunctionality === SpecificChartFunctionality.quotePage\r\n const isFuturesForexCryptoPage = [\r\n SpecificChartFunctionality.futuresPage,\r\n SpecificChartFunctionality.forexPage,\r\n SpecificChartFunctionality.cryptoPage,\r\n ].includes(props.chartLayoutModel.specificChartFunctionality)\r\n if (isChartPage || (isQuotePage && ty !== 'p') || isFuturesForexCryptoPage) {\r\n return \r\n }\r\n\r\n return \r\n }\r\n}\r\n","import Spine from '@finviz/spine'\r\nimport { ChartGrid, ChartGridCell, DialogStateReturn } from '@finviz/website'\r\nimport classnames from 'classnames'\r\nimport flowRight from 'lodash.flowright'\r\nimport merge from 'lodash.merge'\r\nimport throttle from 'lodash.throttle'\r\nimport React from 'react'\r\nimport * as ReactDOM from 'react-dom'\r\n\r\nimport {\r\n ChartConfigObject,\r\n DrawingSpineOptionsEvent,\r\n IIdea,\r\n RootChartConfigObject,\r\n RootChartConfigObjectChart,\r\n} from '../../../types/shared'\r\nimport { ChartEditorEnum, LAYOUTS, LayoutType, SpecificChartFunctionality, TIMEFRAME } from '../../constants/common'\r\nimport ChartModel from '../../models/chart'\r\nimport ChartLayoutModel from '../../models/chart_layout'\r\nimport ChartLayout from '../../models/chart_layout'\r\nimport { AutoSaveState } from '../../models/constants'\r\nimport ElementModel from '../../models/element'\r\nimport utils, {\r\n getChartsDimensions,\r\n getFullscreenStatus,\r\n getIsMobilePortrait,\r\n isRedesignEnabled,\r\n isRedesignedPage,\r\n} from '../../utils'\r\nimport {\r\n getIsPreserveDrawingsAndAutosaveAvailable,\r\n getIsSidebarEnabled,\r\n isQuoteForexFuturesCryptoPage,\r\n} from '../../utils/chart'\r\nimport fetchApi from '../../utils/fetch_api'\r\nimport { getTickersAndContainerTypesInLayoutModel } from '../autosave/utils'\r\nimport { withDrawingsAutoSave } from '../autosave/with-auto-save'\r\nimport Chart from '../chart'\r\nimport { SidebarDirection } from '../sidebar/constants'\r\nimport { Sidebar } from '../sidebar/sidebar'\r\nimport Toolbar from '../toolbar'\r\nimport { AutoSaveNotesDialog } from '../toolbar/auto-save-notes'\r\nimport { ConfirmationDialog } from '../toolbar/confirmation_dialog'\r\nimport { DrawingActions, DrawingSetting, DrawingTool } from '../toolbar/interfaces'\r\nimport ToolbarMobile from '../toolbar/mobile/toolbar-mobile'\r\nimport { withDialogState } from '../with_dialog_state_hook'\r\nimport { AutoSaveStateIndicator } from './auto-save-state-indicator'\r\nimport { ChartLayoutAutoSaveNote } from './chart-layout-auto-save-note'\r\nimport { PublishOldButtonClickListener, getPublishChartHtmlElements } from './publish_old_button_click_listener'\r\nimport { withChartPageTitle } from './with-chart-page-title'\r\nimport { withChartRouteChange } from './with-chart-route-change'\r\nimport { withCompleteLayoutModelInit } from './with-complete-layout-model-init'\r\nimport { withIdeaModelState } from './with-idea-model-state'\r\nimport { withQuoteCacheManagement } from './with-quote-cache-management'\r\nimport { withQuotePolling } from './with-quote-polling'\r\n\r\ninterface ChartLayoutComponentProps {\r\n config: RootChartConfigObject\r\n confirmationDialogState: DialogStateReturn\r\n noteDialogState: DialogStateReturn\r\n shouldResize?: boolean\r\n chartLayoutModel: ChartLayoutModel\r\n idea?: IIdea\r\n deleteAllAutoSavedElements: () => void\r\n isAutoSaveActive: boolean\r\n}\r\n\r\ninterface ChartLayoutComponentState {\r\n editable: boolean\r\n editors: ChartEditorEnum[]\r\n layout: LayoutType\r\n activeChartInteraction: string | null\r\n touchEventsDisabled: boolean\r\n isToolbarHorizontal: boolean\r\n activeTool: DrawingTool\r\n drawingSettings: Record\r\n}\r\n\r\nclass ChartLayoutComponentBase extends React.Component {\r\n // expects config, bindPublic\r\n model: ChartLayoutModel\r\n isMobile = Boolean(utils.isMobile(true))\r\n charts: Array<{ model: ChartModel; config: RootChartConfigObjectChart }>\r\n orientationChangeTimeout: number | undefined\r\n preserveDrawingAbortController = new AbortController()\r\n\r\n // These two are used on quote to check whether or not we should recompute toolbar position\r\n prevModelWidth?: number\r\n prevTimeframeActiveChart?: TIMEFRAME\r\n\r\n constructor(props: ChartLayoutComponentProps) {\r\n super(props)\r\n\r\n this.model = props.chartLayoutModel\r\n this.prevModelWidth = this.model.width\r\n this.prevTimeframeActiveChart = this.model.activeChart?.timeframe\r\n const config = props.config\r\n\r\n this.charts = []\r\n for (const chartConfig of config.charts) {\r\n const modelProperties: Partial = merge({}, chartConfig)\r\n\r\n modelProperties.chart_layout = this.model\r\n delete modelProperties.panes\r\n if (modelProperties.zoomFactor == null) {\r\n modelProperties.zoomFactor = this.model.defaultZoomFactor\r\n }\r\n if (modelProperties.refreshData == null) {\r\n modelProperties.refreshData = true\r\n }\r\n if (!modelProperties.dateRange) {\r\n modelProperties.dateRange = null\r\n }\r\n modelProperties.isHideDrawingsActive = this.model.isHideDrawingsActive\r\n modelProperties.isScrolled = false\r\n const model = this.model.charts().create(modelProperties)\r\n this.charts.push({ model, config: chartConfig })\r\n }\r\n this.model.updateAttribute('activeChart', this.model.charts().first())\r\n\r\n this.state = {\r\n editable: this.model.editable,\r\n editors: this.model.editors,\r\n layout: this.model.layout,\r\n activeChartInteraction: null,\r\n activeTool: DrawingTool.Mouse,\r\n touchEventsDisabled: false,\r\n isToolbarHorizontal: true,\r\n drawingSettings: {\r\n [DrawingSetting.DrawingModeContinuous]: false,\r\n [DrawingSetting.PreserveDrawings]: this.handleInitialPreserveDrawingsState(),\r\n [DrawingSetting.HideDrawings]: false,\r\n [DrawingSetting.LockDrawings]: false,\r\n },\r\n }\r\n }\r\n\r\n componentDidMount() {\r\n if (this.state.editable) {\r\n const DELETE = 46\r\n window.addEventListener('keyup', (e) => {\r\n const selected = this.model.getPaneWithSelection()\r\n if (e.keyCode === DELETE && selected) {\r\n const element = ElementModel.findByAttribute('instance', selected.selection)\r\n if (element && !element.instance.isEditInProgress) {\r\n const elementPane = element.pane()\r\n element.destroyCascade({ eventType: DrawingSpineOptionsEvent.Remove })\r\n elementPane.normalizeZIndexes()\r\n }\r\n }\r\n })\r\n }\r\n\r\n if (this.isMobile) {\r\n this.model.settings.ThumbSettings.size = this.model.settings.ThumbSettings.touchSize\r\n }\r\n\r\n this.onModelChange()\r\n\r\n this.model.bind('change', this.onModelChange)\r\n this.model.charts().bind('destroy', this.onChartDestroy)\r\n\r\n this.setToolbarPosition()\r\n window.addEventListener('resize', this.onWindowResize)\r\n window.addEventListener('orientationchange', this.handleOrientationChange)\r\n\r\n if (this.isMobile) {\r\n this.checkTouchEventsDisabled()\r\n window.addEventListener('touchend', this.checkTouchEventsDisabled)\r\n }\r\n }\r\n\r\n componentDidUpdate(prevProps: Readonly): void {\r\n if (prevProps.idea && !this.props.idea) {\r\n if (this.model.specificChartFunctionality === SpecificChartFunctionality.chartPage) {\r\n this.onWindowResize()\r\n }\r\n document.querySelector('#idea-title-container')?.remove()\r\n }\r\n\r\n /**\r\n * `setToolbarPosition` calls `flushSync` so we want to use it as sparingly as we can\r\n * It is only needed when chart resizes (or quote timeframe changes)\r\n */\r\n const quoteTimeframe = this.model.activeChart.quote()?.timeframe\r\n if (\r\n (quoteTimeframe && this.prevTimeframeActiveChart !== quoteTimeframe) ||\r\n this.prevModelWidth !== this.model.width\r\n ) {\r\n this.setToolbarPosition()\r\n }\r\n this.prevTimeframeActiveChart = quoteTimeframe\r\n this.prevModelWidth = this.model.width\r\n }\r\n\r\n componentWillUnmount() {\r\n this.preserveDrawingAbortController.abort()\r\n this.model.unbind('change', this.onModelChange)\r\n\r\n window.removeEventListener('resize', this.onWindowResize)\r\n window.removeEventListener('orientationchange', this.handleOrientationChange)\r\n\r\n if (this.isMobile) {\r\n window.removeEventListener('touchend', this.checkTouchEventsDisabled)\r\n }\r\n\r\n clearTimeout(this.orientationChangeTimeout)\r\n this.throttledResize.cancel()\r\n this.model.destroyCascade()\r\n }\r\n\r\n handleInitialPreserveDrawingsState = () => {\r\n let preserveDrawings = false\r\n if (getIsPreserveDrawingsAndAutosaveAvailable(this.model)) {\r\n if (window.FinvizSettings.toolsState?.[DrawingSetting.PreserveDrawings] !== undefined) {\r\n preserveDrawings = window.FinvizSettings.toolsState[DrawingSetting.PreserveDrawings]\r\n } else {\r\n this.handlePreserveDrawingsSettings()\r\n }\r\n }\r\n this.model.updateAttribute('isPreserveDrawingsActive', preserveDrawings)\r\n return preserveDrawings\r\n }\r\n\r\n handlePreserveDrawingsSettings = async (value?: boolean) => {\r\n const setPreserveDrawings = (val: boolean) => {\r\n this.model.updateAttribute('isPreserveDrawingsActive', val)\r\n this.setState((prevState) => ({\r\n drawingSettings: {\r\n ...prevState.drawingSettings,\r\n [DrawingSetting.PreserveDrawings]: val,\r\n },\r\n }))\r\n }\r\n\r\n try {\r\n this.preserveDrawingAbortController.abort()\r\n this.preserveDrawingAbortController = new AbortController()\r\n const response = await fetchApi({\r\n location: '/api/tools_state.ashx',\r\n method: value !== undefined ? 'POST' : 'GET',\r\n body:\r\n value !== undefined\r\n ? new URLSearchParams({ tools_state: JSON.stringify({ [DrawingSetting.PreserveDrawings]: value }) })\r\n : undefined,\r\n throwOnStatusCodes: [404],\r\n abortController: this.preserveDrawingAbortController,\r\n })\r\n\r\n if (value === undefined && response?.[DrawingSetting.PreserveDrawings] !== undefined) {\r\n setPreserveDrawings(response[DrawingSetting.PreserveDrawings])\r\n }\r\n } catch {\r\n if (value !== undefined) {\r\n setPreserveDrawings(!value)\r\n }\r\n }\r\n }\r\n\r\n handleOrientationChange = () => {\r\n this.orientationChangeTimeout = window.setTimeout(() => {\r\n this.setToolbarPosition()\r\n if (this.props.shouldResize) {\r\n this.handleResize()\r\n }\r\n })\r\n }\r\n\r\n onWindowResize = () => {\r\n this.setToolbarPosition()\r\n\r\n if (this.props.shouldResize) {\r\n this.throttledResize()\r\n }\r\n }\r\n\r\n handleResize = () => {\r\n const modelAttrs: Partial = getChartsDimensions(this.model.getHTMLElementId())\r\n this.model.updateAttributes(modelAttrs)\r\n }\r\n\r\n throttledResize = throttle(this.handleResize, 200)\r\n\r\n setToolbarPosition() {\r\n // Toolbar doesn’t change position on other pages\r\n if (!isQuoteForexFuturesCryptoPage(this.model.specificChartFunctionality)) return\r\n\r\n requestAnimationFrame(() =>\r\n /**\r\n * Fixes a problem where React (probably) pushes updates for to\r\n * the next render, which results in multiple re-renders of which\r\n * causes a flicker when changes between vertical and horizontal placement\r\n */\r\n ReactDOM.flushSync(() => {\r\n // quote page toolbar\r\n // 210px represents: (20px (toolbar left margin) + 80px (toolbar width) + 5px (toolbar rigth margin)) * 2 (both sides of chart)\r\n const newIsToolbarHorizontal = this.model.width + 210 > window.innerWidth || window.innerWidth < 1000\r\n if (newIsToolbarHorizontal !== this.state.isToolbarHorizontal) {\r\n this.setState({\r\n isToolbarHorizontal: newIsToolbarHorizontal,\r\n })\r\n }\r\n })\r\n )\r\n }\r\n\r\n checkTouchEventsDisabled = () => {\r\n if (!/\\bcharts\\b/.test(window.location.pathname) || getFullscreenStatus() || this.getVisualViewportScale() === 1) {\r\n this.state?.touchEventsDisabled && this.setState({ touchEventsDisabled: false })\r\n } else {\r\n !this.state?.touchEventsDisabled && this.setState({ touchEventsDisabled: true })\r\n }\r\n }\r\n\r\n getVisualViewportScale = () => {\r\n if (process.env.IS_E2E_TESTING) {\r\n return 1\r\n }\r\n if (window.visualViewport && this.isMobile) {\r\n return window.visualViewport.scale\r\n } else {\r\n return 1\r\n }\r\n }\r\n\r\n handleActiveToolChange = (activeTool: DrawingTool) => {\r\n if (!this.model.isLockDrawingsActive) {\r\n this.setState({ activeTool })\r\n }\r\n }\r\n\r\n handleDrawingAction = (actionId: DrawingActions) => {\r\n switch (actionId) {\r\n case DrawingActions.AddNote:\r\n this.props.noteDialogState.toggle()\r\n break\r\n case DrawingActions.DeleteDrawings:\r\n case DrawingActions.DeleteAutoSavedDrawings:\r\n this.props.confirmationDialogState.show()\r\n break\r\n default:\r\n return\r\n }\r\n }\r\n\r\n handleConfirmationDialogDeleteBtn = () => {\r\n if (this.model.drawingsInternalStore().autoSaveState !== AutoSaveState.Off) {\r\n this.props.deleteAllAutoSavedElements()\r\n }\r\n this.model.getAllElements().forEach((element) => {\r\n if (element.isDrawing()) {\r\n element.destroyCascade({ eventType: DrawingSpineOptionsEvent.Remove })\r\n const drawingToRemove = this.model\r\n .drawingsInternalStore()\r\n .elements.find(({ elementId }) => elementId === element.id)\r\n if (drawingToRemove) {\r\n drawingToRemove.changeType = 'destroy'\r\n }\r\n }\r\n })\r\n this.props.confirmationDialogState.hide()\r\n }\r\n\r\n handleDrawingsSetting = (settingId: DrawingSetting) => {\r\n const newObj = { ...this.state.drawingSettings, [settingId]: !this.state.drawingSettings[settingId] }\r\n\r\n switch (settingId) {\r\n case DrawingSetting.HideDrawings:\r\n this.handleActiveToolChange(DrawingTool.Mouse)\r\n this.toggleHideDrawings(newObj[DrawingSetting.HideDrawings])\r\n this.handleLockDrawings(newObj)\r\n break\r\n case DrawingSetting.PreserveDrawings:\r\n this.handlePreserveDrawingsSettings(newObj[DrawingSetting.PreserveDrawings])\r\n this.model.updateAttribute('isPreserveDrawingsActive', newObj[DrawingSetting.PreserveDrawings])\r\n break\r\n case DrawingSetting.LockDrawings:\r\n this.handleActiveToolChange(DrawingTool.Mouse)\r\n this.handleLockDrawings(newObj)\r\n break\r\n case DrawingSetting.DrawingModeContinuous:\r\n this.model.updateAttribute('isDrawingModeContinuousActive', newObj[DrawingSetting.DrawingModeContinuous])\r\n newObj[DrawingSetting.DrawingModeContinuous] === false && this.handleActiveToolChange(DrawingTool.Mouse)\r\n break\r\n default:\r\n break\r\n }\r\n\r\n this.setState({ drawingSettings: newObj })\r\n window.gtag?.('event', 'drawings_settings_toggle', {\r\n event_category: newObj[settingId] ? 'enable' : 'disable',\r\n event_label: settingId,\r\n })\r\n }\r\n\r\n handleLockDrawings = (drawingSettings: Record) => {\r\n this.model.updateAttribute(\r\n 'isLockDrawingsActive',\r\n !(!drawingSettings[DrawingSetting.HideDrawings] && !drawingSettings[DrawingSetting.LockDrawings])\r\n )\r\n }\r\n\r\n toggleHideDrawings(value: boolean) {\r\n this.model.updateAttribute('isHideDrawingsActive', value)\r\n this.model.getAllCharts().forEach((chart) => chart.updateAttribute('isHideDrawingsActive', value))\r\n }\r\n\r\n renderToolbar(args: any) {\r\n const { activeTool, drawingSettings } = this.state\r\n return args.isOverlayToolbar ? (\r\n \r\n ) : (\r\n \r\n )\r\n }\r\n\r\n render() {\r\n const { newCharts, useGrid } = this.props.config\r\n const { activeTool, editable, editors, isToolbarHorizontal } = this.state\r\n const publish = editors.includes(ChartEditorEnum.publish) && getPublishChartHtmlElements().length > 0\r\n const chartLayout = LAYOUTS[this.model.layout]\r\n const isMobilePortrait = getIsMobilePortrait(this.isMobile)\r\n const { tickers } = getTickersAndContainerTypesInLayoutModel(this.model)\r\n\r\n if (newCharts) {\r\n const isSidebarEnabled = getIsSidebarEnabled(SpecificChartFunctionality.chartPage)\r\n return (\r\n <>\r\n

\r\n {!isMobilePortrait &&\r\n // Due safari iOS flex-column bug not resizing height properly we need to render toolbar\r\n // outside of flex for portrait and inside for landscape\r\n // https://github.com/finvizhq/charts/pull/784\r\n this.renderToolbar({\r\n isSidebar: true,\r\n isHorizontal: false,\r\n })}\r\n \r\n \r\n \r\n {this.charts.map(({ model, config }, index) => (\r\n }\r\n gridArea={chartLayout.gridAreas?.[index]}\r\n setActiveChartInteraction={this.setActiveChartInteraction}\r\n activeTool={activeTool}\r\n activeChartInteraction={this.state.activeChartInteraction}\r\n touchEventsDisabled={this.state.touchEventsDisabled}\r\n shouldResize={this.props.shouldResize}\r\n />\r\n ))}\r\n \r\n \r\n
\r\n {isMobilePortrait && isSidebarEnabled && (\r\n \r\n )}\r\n {isMobilePortrait &&\r\n this.renderToolbar({\r\n isSidebar: false,\r\n isHorizontal: true,\r\n isOverlayToolbar: isSidebarEnabled,\r\n })}\r\n {this.props.idea?.note && (\r\n
\r\n
\r\n {this.props.idea.note}\r\n
\r\n
\r\n )}\r\n \r\n )\r\n }\r\n\r\n const hasRedesign = isRedesignEnabled()\r\n const hasChartTools = editable && editors.includes(ChartEditorEnum.tools)\r\n const renderTools = isRedesignedPage(this.model) ? hasChartTools && !isToolbarHorizontal : hasChartTools\r\n\r\n const ideaTitleContainer = document.querySelector('#idea-title-container')\r\n const ideaTitle = this.props.idea?.date &&\r\n this.model.specificChartFunctionality === SpecificChartFunctionality.quotePage && (\r\n

{`Your idea from ${this.props.idea.date}`}

\r\n )\r\n\r\n return (\r\n <>\r\n {ideaTitleContainer ? ReactDOM.createPortal(ideaTitle, ideaTitleContainer) : ideaTitle}\r\n \r\n {renderTools && (\r\n \r\n {this.renderToolbar({\r\n isHorizontal: isToolbarHorizontal,\r\n isAlternativeTheme: true,\r\n })}\r\n \r\n )}\r\n \r\n \r\n {this.charts.map(({ model, config }, index) => (\r\n \r\n this.renderToolbar({\r\n isHorizontal: true,\r\n isAlternativeTheme: true,\r\n })\r\n : undefined\r\n }\r\n />\r\n ))}\r\n \r\n
\r\n
\r\n
\r\n {this.model.specificChartFunctionality === SpecificChartFunctionality.quotePage && (\r\n \r\n )}\r\n \r\n \r\n )\r\n }\r\n\r\n setActiveChartInteraction = (value: string | null) => {\r\n this.setState({ activeChartInteraction: value })\r\n }\r\n\r\n updateLayout() {\r\n const layout = LAYOUTS[this.model.layout]\r\n const charts = this.model.charts().all()\r\n if (charts.length === 0) {\r\n return\r\n }\r\n\r\n if (charts.length > layout.count) {\r\n this.removeCharts(layout.count)\r\n } else if (charts.length < layout.count) {\r\n this.addCharts(layout.count - charts.length)\r\n }\r\n\r\n this.model\r\n .charts()\r\n .all()\r\n .forEach((chart, index) => {\r\n const [rowStart, columnStart, rowEnd, columnEnd] =\r\n layout.gridAreas?.[index]\r\n .replace(/ /g, '')\r\n .split('/')\r\n .map((num) => Number.parseInt(num)) || []\r\n const numOfRowsCovered = [rowEnd, rowStart].every((value) => value !== undefined) ? rowEnd - rowStart : 1\r\n const numOfColumnsCovered = [columnStart, columnEnd].every((value) => value !== undefined)\r\n ? columnEnd - columnStart\r\n : 1\r\n const percentageOfRowsCovered = numOfRowsCovered / layout.rows\r\n const percentageOfColumnsCovered = numOfColumnsCovered / layout.columns\r\n const newWidth = ~~(this.model.width * percentageOfColumnsCovered)\r\n const isChartPage = this.model.specificChartFunctionality === SpecificChartFunctionality.chartPage\r\n const chartLayoutHeight = isChartPage\r\n ? this.model.height\r\n : this.model.charts().first().height || this.model.height\r\n let newHeight = ~~(chartLayoutHeight * percentageOfRowsCovered)\r\n\r\n if (this.model.editors.includes(ChartEditorEnum.settings) && isChartPage) {\r\n newHeight -= this.model.settings.ChartSettings.general.settingsHeight\r\n }\r\n if ((chart.width !== newWidth || chart.height !== newHeight) && newWidth > 0 && newHeight > 0) {\r\n chart.updateAttributes({ width: newWidth, height: newHeight })\r\n }\r\n })\r\n }\r\n\r\n addCharts(count: number) {\r\n const quote = this.model.charts().last().quote()\r\n if (!quote) return\r\n const config = {\r\n ...this.model.charts().last().toObject(),\r\n leftOffset: null,\r\n chart_layout: this.model,\r\n aftermarket: quote.aftermarket,\r\n premarket: quote.premarket,\r\n }\r\n for (let i = 0; i < count; i++) {\r\n const model = this.model.charts().create(config)\r\n this.charts.push({ model, config })\r\n }\r\n }\r\n\r\n removeCharts(wantedCount: number) {\r\n while (this.model.charts().count() > wantedCount) {\r\n const chart = this.model.charts().last()\r\n chart.destroyCascade()\r\n this.charts.pop()\r\n }\r\n }\r\n\r\n onChartDestroy = (chartModel: ChartModel) => {\r\n this.updateLayout()\r\n if (this.model.activeChart?.eql(chartModel)) {\r\n this.model.updateAttribute('activeChart', this.model.charts().last())\r\n }\r\n }\r\n\r\n onModelChange = (layoutModel?: ChartLayout, event?: Spine.Event) => {\r\n if (event === 'refresh') {\r\n return\r\n }\r\n this.updateLayout()\r\n\r\n if (layoutModel && event === 'update') {\r\n this.setState({\r\n editable: layoutModel.editable,\r\n editors: layoutModel.editors,\r\n layout: layoutModel.layout,\r\n })\r\n }\r\n }\r\n}\r\n\r\nexport const ChartLayoutComponent = flowRight(\r\n withQuoteCacheManagement,\r\n withDialogState,\r\n withCompleteLayoutModelInit,\r\n withChartPageTitle,\r\n withChartRouteChange,\r\n withIdeaModelState,\r\n withQuotePolling,\r\n withDrawingsAutoSave\r\n)(ChartLayoutComponentBase)\r\n","import debounce from 'lodash.debounce'\r\nimport React from 'react'\r\n\r\nimport Chart from '../../models/chart'\r\nimport Quote from '../../models/quote'\r\n\r\nconst MAX_QUOTE_CACHE_TIME_IN_MS = 300000 // 5 min\r\n\r\nexport const withQuoteCacheManagement = (Component: any) => (props: any) => {\r\n React.useEffect(() => {\r\n const cleanupQuoteCache = () => {\r\n const allQuotes = Quote.all()\r\n const allCharts = Chart.all()\r\n const allChartQuotes = allCharts.flatMap((chart) => chart.getAllQuotes())\r\n\r\n allQuotes.forEach((quote) => {\r\n if (\r\n !allChartQuotes.some((usedQuote) => usedQuote.eql(quote)) &&\r\n !quote.isFetching &&\r\n quote.fetchedAt > -1 &&\r\n quote.fetchedAt < Date.now() - MAX_QUOTE_CACHE_TIME_IN_MS\r\n ) {\r\n quote.destroy()\r\n }\r\n })\r\n }\r\n\r\n const checkQuoteCacheDebounce = debounce(cleanupQuoteCache, 500)\r\n\r\n Quote.bind('change', checkQuoteCacheDebounce)\r\n return () => {\r\n checkQuoteCacheDebounce.cancel()\r\n Quote.unbind('change', checkQuoteCacheDebounce)\r\n }\r\n }, [])\r\n\r\n return \r\n}\r\n","import { useDialogState } from '@finviz/website'\r\nimport React from 'react'\r\n\r\nexport const withDialogState = (Component: any) => (props: any) => {\r\n const confirmationDialogState = useDialogState()\r\n const noteDialogState = useDialogState()\r\n\r\n return \r\n}\r\n","import * as React from 'react'\r\n\r\nimport { SpecificChartFunctionality, TIMEFRAME } from '../../constants/common'\r\nimport math from '../../helpers/math'\r\nimport ChartLayoutModel from '../../models/chart_layout'\r\nimport Quote from '../../models/quote'\r\n\r\nfunction useChartPageTitle() {\r\n const defaultDocumentTitleRef = React.useRef(document.title)\r\n\r\n const { current: updateChartsTitle } = React.useRef((chartLayoutModel: ChartLayoutModel) => {\r\n const charts = chartLayoutModel\r\n .getAllCharts()\r\n .reduce(\r\n (acc, current) => {\r\n if (acc.some(({ ticker }) => ticker === current.ticker)) {\r\n return acc\r\n }\r\n return [...acc, { ticker: current.ticker, timeframe: current.timeframe, instrument: current.instrument }]\r\n },\r\n [] as Array<{ ticker: string; timeframe: TIMEFRAME; instrument: string }>\r\n )\r\n .map((chart) => {\r\n const { ticker, timeframe, instrument } = chart\r\n const quotes = Quote.select(\r\n (quote: Quote) =>\r\n quote.ticker === ticker.replace('@', '') &&\r\n quote.timeframe === timeframe &&\r\n quote.instrument === instrument &&\r\n chartLayoutModel.isIdeaId(quote.ideaID)\r\n )\r\n if (quotes.length > 0) {\r\n const { lastClose, instrument, afterClose, prevClose, name } = quotes[0]\r\n let percentageChange: number\r\n if (!lastClose) {\r\n return null\r\n }\r\n if (prevClose !== null) {\r\n percentageChange = (lastClose / prevClose - 1) * 100\r\n }\r\n if (afterClose !== null && afterClose !== lastClose) {\r\n percentageChange = (afterClose / lastClose - 1) * 100\r\n }\r\n return `${name || ticker} ${math.round({\r\n value: lastClose,\r\n lastClose,\r\n instrument,\r\n overridePlaces: undefined,\r\n })} ${percentageChange! > 0 ? '+' : '-'}${math.round({\r\n value: Math.abs(percentageChange!),\r\n overridePlaces: 2,\r\n })}%`\r\n }\r\n return null\r\n })\r\n .filter((chart) => chart !== null)\r\n\r\n if (charts && charts.length > 0) {\r\n const title = charts.join(' | ')\r\n if (document.title !== title) {\r\n document.title = title\r\n }\r\n } else if (document.title !== defaultDocumentTitleRef.current) {\r\n document.title = defaultDocumentTitleRef.current\r\n }\r\n })\r\n\r\n return { updateChartsTitle }\r\n}\r\n\r\nexport function withChartPageTitle

(\r\n Component: React.ComponentType

\r\n) {\r\n return function WrappedComponent(props: P) {\r\n const { updateChartsTitle } = useChartPageTitle()\r\n\r\n const handleChartsUpdate = React.useCallback(() => {\r\n updateChartsTitle(props.chartLayoutModel)\r\n }, [props.chartLayoutModel, updateChartsTitle])\r\n\r\n React.useEffect(() => {\r\n if (props.chartLayoutModel.specificChartFunctionality === SpecificChartFunctionality.chartPage) {\r\n props.chartLayoutModel.charts().bind('change', handleChartsUpdate)\r\n\r\n handleChartsUpdate()\r\n\r\n return () => {\r\n props.chartLayoutModel.charts().unbind('change', handleChartsUpdate)\r\n }\r\n }\r\n }, [props.chartLayoutModel, handleChartsUpdate])\r\n\r\n return \r\n }\r\n}\r\n","import React from 'react'\r\n\r\nimport { useModelState } from '../../model-hooks/use-model-state'\r\nimport ChartLayoutModel from '../../models/chart_layout'\r\n\r\nexport function withIdeaModelState

(\r\n Component: React.ComponentType

\r\n) {\r\n return function WrappedComponent(props: P) {\r\n const chartLayoutModel = useModelState(props.chartLayoutModel, { watchProperties: ['idea'] })\r\n return \r\n }\r\n}\r\n","import { NotificationWrapper, withSuspense } from '@finviz/website'\r\nimport React from 'react'\r\n\r\nimport { RootChartConfigObject } from '../../../types/shared'\r\nimport { ElementStyleDialogWrapper } from '../../modals/element_style'\r\nimport { useChartLayoutGlobalModelAsync } from '../../utils/useChartLayoutGlobalModelAsync'\r\nimport { ChartLayoutComponent } from './chart_layout_component'\r\n\r\ninterface ChartLayoutProps {\r\n config: RootChartConfigObject\r\n shouldResize?: boolean\r\n parentElement?: React.RefObject | HTMLElement\r\n isWithNotifications?: boolean\r\n}\r\n\r\nexport function ChartLayout({ config, shouldResize, isWithNotifications = true, parentElement }: ChartLayoutProps) {\r\n const Wrapper = isWithNotifications ? NotificationWrapper : React.Fragment\r\n return (\r\n \r\n \r\n \r\n \r\n \r\n )\r\n}\r\n\r\nexport function ChartLayoutWithGlobalStateRaw({\r\n config,\r\n shouldResize,\r\n parentElement,\r\n}: Omit) {\r\n const { setChartLayoutModel, getChartLayoutModelConfig, lastGlobalRerender } = useChartLayoutGlobalModelAsync()\r\n\r\n return (\r\n \r\n {config && (\r\n \r\n )}\r\n \r\n )\r\n}\r\n\r\nexport const ChartLayoutWithGlobalState = withSuspense(ChartLayoutWithGlobalStateRaw)\r\n","export const CHART_LAYOUT_CHILD_CHANGE_EVENT = 'chartLayoutChildChange'\r\n","import merge from 'lodash.merge'\r\nimport React from 'react'\r\n\r\nimport { RootChartConfigObject, Theme } from '../../../types/shared'\r\nimport {\r\n ChartEditorEnum,\r\n MOBILE_BARS_TO_VIEW,\r\n MOBILE_VIEW_BREAKPOINT_WIDTH,\r\n SpecificChartFunctionality,\r\n} from '../../constants/common'\r\nimport ChartLayoutModel from '../../models/chart_layout'\r\nimport DrawingsInternalStore from '../../models/drawings-internal-store'\r\nimport { getSettings } from '../../models/settings'\r\nimport utils, { isRedesignedPage } from '../../utils'\r\nimport { getIsPreserveDrawingsAndAutosaveAvailable, getZoomFactorForBarsToDisplay } from '../../utils/chart'\r\nimport { getContainerTypeFromPaneConfig, getInitialStoreDrawings } from '../autosave/utils'\r\nimport { DrawingSetting } from '../toolbar/interfaces'\r\nimport { CHART_LAYOUT_CHILD_CHANGE_EVENT } from './constants'\r\n\r\ninterface Props {\r\n config: RootChartConfigObject\r\n onRegisterChartLayoutModel?: (chartLayoutModel: ChartLayoutModel) => void\r\n parentElement?: HTMLElement\r\n}\r\n\r\nfunction getDefaultZoomFactor(chartLayout: ChartLayoutModel) {\r\n const innerWidth = window.innerWidth\r\n if (\r\n innerWidth >= MOBILE_VIEW_BREAKPOINT_WIDTH ||\r\n chartLayout.specificChartFunctionality !== SpecificChartFunctionality.chartPage\r\n ) {\r\n return 1\r\n }\r\n\r\n return getZoomFactorForBarsToDisplay({\r\n chartLayout,\r\n numOfVisibleBars: MOBILE_BARS_TO_VIEW,\r\n chartVisibleWidth: innerWidth,\r\n })\r\n}\r\n\r\nfunction OnInitListener({\r\n chartLayoutModel,\r\n config,\r\n onRegisterChartLayoutModel,\r\n parentElement,\r\n}: Props & { chartLayoutModel: ChartLayoutModel; parentElement?: React.RefObject | HTMLElement }) {\r\n const [isInit, setIsInit] = React.useState(false)\r\n\r\n /*\r\n * This entire effect is used to check for updates in entire chart layout obj tree.\r\n * Once config object matches object generated from chart layout, the layout model is completely initialised.\r\n *\r\n * We couldn't just add a callback to `componentDidMount` (or equivalent) because its children are rendered asynchronously.\r\n *\r\n * */\r\n React.useEffect(() => {\r\n if ((onRegisterChartLayoutModel || parentElement) && chartLayoutModel && !isInit) {\r\n const checkIfInitIsComplete = () => {\r\n const { charts } = chartLayoutModel.toConfig()\r\n const isReady =\r\n charts.length === config.charts.length &&\r\n charts.every(\r\n (chart, chartIndex) =>\r\n chart.panes.length === config.charts[chartIndex].panes.length &&\r\n chart.panes.every(\r\n (pane, paneIndex) =>\r\n pane.elements.length === config.charts[chartIndex].panes[paneIndex].elements.length &&\r\n pane.elements.every(\r\n (element, elementIndex) =>\r\n element.overlays?.length ===\r\n config.charts[chartIndex].panes[paneIndex].elements[elementIndex].overlays?.length\r\n )\r\n )\r\n )\r\n\r\n if (isReady) {\r\n setIsInit(true)\r\n chartLayoutModel.updateAttributes({ isInit: true })\r\n onRegisterChartLayoutModel?.(chartLayoutModel)\r\n\r\n const containerElement = parentElement?.hasOwnProperty('current')\r\n ? (parentElement as React.RefObject).current\r\n : parentElement\r\n\r\n if (containerElement) {\r\n containerElement.style.opacity = 'unset'\r\n containerElement.style.minHeight = 'unset'\r\n containerElement.style.minWidth = 'unset'\r\n }\r\n }\r\n }\r\n\r\n chartLayoutModel.bind(CHART_LAYOUT_CHILD_CHANGE_EVENT, checkIfInitIsComplete)\r\n\r\n checkIfInitIsComplete()\r\n\r\n return () => {\r\n chartLayoutModel.unbind(CHART_LAYOUT_CHILD_CHANGE_EVENT, checkIfInitIsComplete)\r\n }\r\n }\r\n }, [chartLayoutModel, config, isInit, onRegisterChartLayoutModel, parentElement])\r\n\r\n return null\r\n}\r\n\r\nexport const withCompleteLayoutModelInit = (Component: any) => (props: Props) => {\r\n const config = React.useMemo(() => {\r\n const newConfig = merge({}, props.config, {\r\n editable: props.config.editable ?? true,\r\n canChangeTicker: props.config.canChangeTicker ?? true,\r\n scrollable: props.config.scrollable ?? true,\r\n cross: props.config.cross ?? true,\r\n theme:\r\n props.config.theme && [Theme.light, Theme.dark].includes(props.config.theme) ? props.config.theme : Theme.light,\r\n editors: props.config.editors ?? [ChartEditorEnum.publish, ChartEditorEnum.tools, ChartEditorEnum.ideas],\r\n ideas: props.config.ideas ?? true,\r\n specificChartFunctionality: props.config.specificChartFunctionality ?? SpecificChartFunctionality.default,\r\n initialStoreDrawings: [],\r\n })\r\n\r\n if (!newConfig.ideas) {\r\n newConfig.editors = newConfig.editors.filter((x) => x !== 'ideas')\r\n }\r\n\r\n // We need to add these because ideas might not have them and chart controls wouldn’t render properly\r\n if (isRedesignedPage(newConfig, [SpecificChartFunctionality.quotePage])) {\r\n newConfig.editors = newConfig.editors.concat([ChartEditorEnum.settings, ChartEditorEnum.timeframe])\r\n }\r\n\r\n const initialStoreDrawings = getInitialStoreDrawings()?.filter(({ changeType }) => changeType !== 'destroy') ?? []\r\n const isQuotePage = newConfig.specificChartFunctionality === SpecificChartFunctionality.quotePage\r\n const isQuotePageWithDrawingsOff = isQuotePage && utils.getCookie('charts-draw') !== 'on'\r\n\r\n if (initialStoreDrawings.length === 0 || isQuotePageWithDrawingsOff) {\r\n return newConfig\r\n }\r\n\r\n const noteDrawing = initialStoreDrawings.find(\r\n ({ containerType, ticker }) =>\r\n containerType === 'note' && props.config.charts.some((chart) => chart.ticker === ticker)\r\n )\r\n\r\n const note = noteDrawing && JSON.parse(noteDrawing.elementAttrs)?.text\r\n const ideaObject = isQuotePage && note ? { note } : undefined\r\n\r\n return {\r\n ...newConfig,\r\n initialStoreDrawings,\r\n idea: newConfig.idea ?? ideaObject,\r\n charts: newConfig.charts.map((chart) => {\r\n const { ticker, panes } = chart\r\n return {\r\n ...chart,\r\n panes: panes.map((pane) => {\r\n const containerType = getContainerTypeFromPaneConfig(pane)\r\n const newElements = initialStoreDrawings\r\n .filter(\r\n (drawing) =>\r\n drawing.containerType === containerType &&\r\n drawing.ticker === ticker &&\r\n !pane.elements.some((paneElement) => paneElement.elementId === drawing.elementId)\r\n )\r\n .map(({ elementId, zIndex, elementAttrs }) => ({\r\n elementId,\r\n zIndex,\r\n ...JSON.parse(elementAttrs),\r\n }))\r\n return {\r\n ...pane,\r\n elements: [...pane.elements, ...newElements],\r\n }\r\n }),\r\n }\r\n }),\r\n }\r\n // We need to disable the eslint check because the hook is supposed to run only once on mount\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n }, [])\r\n\r\n const chartLayoutModel = React.useMemo(() => {\r\n const settings = getSettings({ ...config, theme: config.theme! })\r\n const chartLayout = ChartLayoutModel.create({\r\n layout: config.layout,\r\n width: config.width,\r\n height: config.height,\r\n editable: config.editable,\r\n canChangeTicker: config.canChangeTicker,\r\n scrollable: config.scrollable,\r\n initialScrollable: config.scrollable,\r\n cross: config.cross,\r\n editors: config.editors,\r\n theme: config.theme,\r\n idea: config.idea,\r\n settings,\r\n isWheelZoomEnabled: config.specificChartFunctionality === SpecificChartFunctionality.chartPage,\r\n specificChartFunctionality: config.specificChartFunctionality,\r\n isHideDrawingsActive: false,\r\n isPreserveDrawingsActive: !!(\r\n getIsPreserveDrawingsAndAutosaveAvailable(config) &&\r\n window.FinvizSettings.toolsState?.[DrawingSetting.PreserveDrawings]\r\n ),\r\n isLockDrawingsActive: false,\r\n uuid: config.uuid,\r\n drawingsInternalStore: DrawingsInternalStore.create({\r\n elements: config.initialStoreDrawings,\r\n }),\r\n })\r\n\r\n chartLayout.updateAttributes({ defaultZoomFactor: getDefaultZoomFactor(chartLayout) })\r\n\r\n return chartLayout\r\n\r\n // We need to disable the eslint check because the hook is supposed to run only once on mount\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n }, [])\r\n\r\n return chartLayoutModel ? (\r\n <>\r\n \r\n \r\n \r\n ) : null\r\n}\r\n","import debounce from 'lodash.debounce'\r\nimport React from 'react'\r\n\r\nimport { ObjectHash } from '../../../types/shared'\r\nimport { EXTRA_MARKET_BUFFER_MINUTES, QUOTE_FETCH_EVENT } from '../../constants/common'\r\nimport Chart from '../../models/chart'\r\nimport ChartLayoutModel from '../../models/chart_layout'\r\nimport Pane from '../../models/pane'\r\nimport { QuoteFetchType } from '../../models/quote/constants'\r\n\r\ninterface Props {\r\n chartLayoutModel: ChartLayoutModel\r\n}\r\n\r\ntype PollingIntervalToChartsType = ObjectHash\r\n\r\n/*\r\n * This HOC loops through all charts and checks if they are supposed to be refetch in some interval\r\n * It creates groups of charts to be refreshed grouped by the refresh interval\r\n * */\r\nexport const withQuotePolling = (Component: any) => (props: Props) => {\r\n const [pollingIntervalToCharts, setPollingIntervalToCharts] = React.useState({})\r\n const checkForChartsWithPolling = React.useCallback(() => {\r\n // check for charts which have some refresh interval and group chart ids by the interval value e.g. { interval_in_ms: [id1, id2] }\r\n const newPollingIntervalToCharts: PollingIntervalToChartsType = {} // example { 60000: ['c-0', 'c-1'], 9000: ['c-4'] }\r\n props.chartLayoutModel.getAllCharts().forEach((chart) => {\r\n const chartRefreshInterval = chart.getRefreshInterval()\r\n\r\n if (chartRefreshInterval) {\r\n newPollingIntervalToCharts[chartRefreshInterval] = newPollingIntervalToCharts[chartRefreshInterval] ?? []\r\n newPollingIntervalToCharts[chartRefreshInterval].push(chart.id)\r\n }\r\n })\r\n\r\n if (JSON.stringify(newPollingIntervalToCharts) !== JSON.stringify(pollingIntervalToCharts)) {\r\n setPollingIntervalToCharts(newPollingIntervalToCharts)\r\n }\r\n }, [props.chartLayoutModel, pollingIntervalToCharts])\r\n const intervalIdsRef = React.useRef([])\r\n\r\n React.useEffect(() => {\r\n const checkForChartsWithPollingDebounced = debounce(checkForChartsWithPolling)\r\n const chartsCheckerIntervalId = window.setInterval(\r\n checkForChartsWithPollingDebounced,\r\n EXTRA_MARKET_BUFFER_MINUTES * 1000\r\n )\r\n\r\n // listen on any changes in all charts & panes and call debounced check for charts/indicators with quotes that needs to be refetched periodically\r\n Chart.bind('change', checkForChartsWithPollingDebounced)\r\n Pane.bind('change', checkForChartsWithPollingDebounced)\r\n\r\n return () => {\r\n checkForChartsWithPollingDebounced.cancel()\r\n Chart.unbind('change', checkForChartsWithPollingDebounced)\r\n Pane.unbind('change', checkForChartsWithPollingDebounced)\r\n window.clearInterval(chartsCheckerIntervalId)\r\n }\r\n }, [checkForChartsWithPolling])\r\n\r\n React.useEffect(() => {\r\n const timeoutDurations = Object.keys(pollingIntervalToCharts).map(Number)\r\n const allCharts = props.chartLayoutModel.getAllCharts()\r\n const timeoutDurationsMin = Math.min(...timeoutDurations)\r\n\r\n timeoutDurations.forEach((duration) => {\r\n const timeoutId = window.setInterval(() => {\r\n const chartIds = pollingIntervalToCharts[duration]\r\n // get all UNIQUE quotes used in charts and refetch them\r\n allCharts\r\n .filter((chart) => chartIds.includes(chart.id))\r\n .flatMap((chart) => chart.getAllQuotes())\r\n .filter(\r\n (quote, index, quotesToUpdate) =>\r\n !quote.isFetching && index === quotesToUpdate.findIndex((quoteToUpdate) => quote.eql(quoteToUpdate))\r\n )\r\n .forEach((quote) => {\r\n quote.fetchData({ fetchType: QuoteFetchType.NewerData })\r\n })\r\n if (duration === timeoutDurationsMin) {\r\n document.dispatchEvent(new Event(QUOTE_FETCH_EVENT))\r\n }\r\n }, duration)\r\n intervalIdsRef.current.push(timeoutId)\r\n })\r\n\r\n return () => {\r\n if (intervalIdsRef.current.length > 0) {\r\n intervalIdsRef.current.forEach((timeoutId) => {\r\n window.clearInterval(timeoutId)\r\n })\r\n intervalIdsRef.current = []\r\n }\r\n }\r\n }, [props.chartLayoutModel, pollingIntervalToCharts])\r\n\r\n return \r\n}\r\n","import queryString from 'query-string'\r\n\r\nimport { Instrument, ObjectHash } from '../../../types/shared'\r\nimport { LayoutType } from '../../constants/common'\r\nimport { getTickerNoteText } from '../../controllers/autosave/utils'\r\nimport ChartLayout from '../../models/chart_layout'\r\nimport Quote from '../../models/quote'\r\nimport fetchApi, { getFormDataFromObject } from '../../utils/fetch_api'\r\nimport { captureException } from '../../utils/helpers'\r\n\r\nexport interface IIdea {\r\n ticker: string\r\n instrument: string\r\n period: string\r\n company?: string\r\n date: string\r\n time: string\r\n note: string\r\n id: string\r\n}\r\n\r\nexport interface IIdeaCategory {\r\n ticker: string\r\n ideas: IIdea[]\r\n}\r\n\r\nexport function getIdeaUrl({ ticker, instrument, period, id }: Pick) {\r\n const searchObject = { t: ticker, p: period, i: id }\r\n const isStock = instrument === Instrument.Stock\r\n const isQuotePage = /\\/quote\\b/.test(window.location.pathname)\r\n const isStockOnQute = isQuotePage && isStock\r\n const path = !isQuotePage || isStock ? window.location.pathname : '/charts.ashx'\r\n\r\n return `${path}?${queryString.stringify({ ...searchObject, ...(isStockOnQute ? { ta: '2' } : { l: '1h1v' }) })}`\r\n}\r\n\r\nexport async function saveIdea(layoutModel: ChartLayout) {\r\n const activeChart = layoutModel.activeChart\r\n const activeChartQuote = activeChart.quote().toJSON()\r\n const { ticker, instrument, cid } = activeChart\r\n const period = activeChartQuote.timeframe\r\n const { ChartSettings } = layoutModel.settings\r\n const layout: ObjectHash = layoutModel.toObject()\r\n layout.layout = LayoutType['1h1v']\r\n layout.barWidth = ChartSettings.center.barWidth\r\n layout.barMargin = ChartSettings.center.barMargin\r\n layout.charts = layout.charts\r\n .filter((c: ObjectHash) => c.chartId === cid)\r\n .map((c: ObjectHash) => ({ ...c, dateRange: null, refreshData: false }))\r\n\r\n delete layout.charts[0].chartId\r\n if (!activeChart.isScrolled) delete layout.charts[0].leftOffset\r\n\r\n // TODO: replace with better solution after indicators overhaul\r\n const getChartTickers = (layoutModelObjectPanes: { elements: { type: string; tickers: string }[] }[]) => {\r\n let tickers = []\r\n let tickersString = ''\r\n for (const pane of layoutModelObjectPanes) {\r\n for (const element of pane.elements) {\r\n if (element.type === 'indicators/perf') {\r\n tickersString = element.tickers\r\n }\r\n }\r\n }\r\n tickers = tickersString.split(',').filter((item) => item)\r\n if (!tickers.includes(ticker)) {\r\n tickers.push(ticker.replace('@', ''))\r\n }\r\n return tickers\r\n }\r\n const tickers = getChartTickers(layout.charts[0].panes)\r\n const quotes = Quote.select(\r\n (quote: Quote) =>\r\n tickers.includes(quote.ticker) && quote.timeframe === activeChart.timeframe && layoutModel.isIdeaId(quote.ideaID)\r\n ).filter((element, index, array) => array.findIndex((t) => t.ticker === element.ticker) === index)\r\n const quotesJsonString = JSON.stringify(quotes.map((q) => q.toConfig(['ideaID', 'chartUuid'])))\r\n\r\n const chart = JSON.stringify(layout)\r\n const note =\r\n layoutModel.idea?.note ||\r\n getTickerNoteText({ ticker, elements: layoutModel.drawingsInternalStore().elements }) ||\r\n ''\r\n window.gtag?.('event', 'save', { event_category: 'ideas' })\r\n\r\n if (tickers.length !== quotes.length) {\r\n captureException(new Error('Idea saved with inconsistent quotes data'), {\r\n extra: {\r\n tickers,\r\n quoteTickersTimeframes: quotes.map((quote) => ({ ticker: quote.ticker, timeframe: quote.timeframe })),\r\n chartLayout: layoutModel.toConfig(['colors', 'panes']),\r\n },\r\n })\r\n }\r\n\r\n const data = await fetchApi<{ id: string }>({\r\n location: '/api/idea_save.ashx',\r\n method: 'POST',\r\n body: getFormDataFromObject({ ticker, period, chart, quotes: quotesJsonString, note }),\r\n })\r\n\r\n const ideaUrl = getIdeaUrl({\r\n ticker,\r\n period,\r\n instrument,\r\n id: data.id,\r\n })\r\n\r\n if (process.env.IS_E2E_TESTING) {\r\n window.location.href = ideaUrl\r\n } else {\r\n // need to be in setTimeout because Safari block any call to window.open made in async,\r\n // this is hack to force run window.open in main thread\r\n setTimeout(() => {\r\n window.open(ideaUrl, 'FinvizSavedIdea')\r\n })\r\n }\r\n}\r\n\r\nexport function categorizeIdeas(ideas: IIdea[], tickers: string[]) {\r\n if (ideas.length <= 0) return []\r\n\r\n const categorizedIdeas = ideas.reduce((processed, idea) => {\r\n const tickerIdeas = processed.find((i) => i.ticker === idea.ticker)\r\n\r\n if (tickerIdeas) {\r\n tickerIdeas.ideas.push(idea)\r\n } else if (tickers.includes(idea.ticker)) {\r\n processed.push({\r\n ticker: idea.ticker,\r\n ideas: [idea],\r\n })\r\n }\r\n\r\n return processed\r\n }, [] as IIdeaCategory[])\r\n categorizedIdeas.unshift({\r\n ticker: 'All Ideas',\r\n ideas: ideas,\r\n })\r\n\r\n return categorizedIdeas\r\n}\r\n","import { Button, Icon, decodeQueryString } from '@finviz/website'\r\nimport classNames from 'classnames'\r\nimport React from 'react'\r\n\r\nimport { ChartsOrQuotePageQueryParams, TIMEFRAME, TimeframeLabelShort } from '../../constants/common'\r\nimport { IIdea, getIdeaUrl } from './utils'\r\n\r\ntype IdeasListProps = {\r\n idea: IIdea\r\n onIdeaDeleted: (idea: IIdea) => void\r\n}\r\n\r\nexport default function IdeaItem({ idea, onIdeaDeleted }: IdeasListProps) {\r\n const [isDeleting, setIsDeleting] = React.useState(false)\r\n const [isConfirmDelete, setIsConfirmDelete] = React.useState(false)\r\n const { i: currentIdea } = decodeQueryString()\r\n\r\n const onDeleteIdeaClick = React.useRef(async (idea: IIdea) => {\r\n setIsDeleting(true)\r\n\r\n let wasDeleted\r\n try {\r\n const response = await fetch(`/api/idea_delete.ashx?id=${idea.id}`, {\r\n method: 'DELETE',\r\n })\r\n\r\n wasDeleted = response.status === 200\r\n } catch {}\r\n\r\n if (!wasDeleted) {\r\n return\r\n }\r\n\r\n if (currentIdea === idea.id.toString()) {\r\n const newUrl = new URL(window.location.href)\r\n newUrl.searchParams.delete('i')\r\n window.location.href = newUrl.href\r\n return\r\n }\r\n\r\n onIdeaDeleted(idea)\r\n })\r\n\r\n return (\r\n (document.location = getIdeaUrl(idea))}\r\n data-testid=\"charts-notice-idea-item\"\r\n >\r\n <>\r\n

\r\n

\r\n {idea.ticker}\r\n {idea.company && {idea.company}}\r\n

\r\n \r\n {idea.date}\r\n {idea.time}\r\n \r\n \r\n {TimeframeLabelShort[idea.period as TIMEFRAME]}\r\n \r\n \r\n {idea.note !== '' ? (\r\n

{idea.note}

\r\n ) : null}\r\n
\r\n\r\n ) => {\r\n ev.stopPropagation()\r\n setIsConfirmDelete(true)\r\n }}\r\n />\r\n \r\n\r\n {isConfirmDelete && (\r\n
\r\n
\r\n

\r\n Delete {idea.ticker} Idea from {idea.date}?\r\n

\r\n
\r\n\r\n
\r\n {\r\n setIsConfirmDelete(false)\r\n }}\r\n >\r\n Cancel\r\n \r\n {\r\n onDeleteIdeaClick.current(idea)\r\n }}\r\n >\r\n Delete\r\n \r\n
\r\n
\r\n )}\r\n \r\n )\r\n}\r\n","import { Badge, Tab, TabList, TabPanel, Tabs } from '@finviz/website'\r\nimport React from 'react'\r\nimport { useSearchParams } from 'react-router-dom'\r\n\r\nimport { getInstrument } from '../../utils/chart'\r\nimport fetchApi from '../../utils/fetch_api'\r\nimport IdeaItem from './IdeaItem'\r\nimport { IIdea, IIdeaCategory, categorizeIdeas } from './utils'\r\n\r\nexport default function IdeasTabs() {\r\n const [hasError, setHasError] = React.useState(false)\r\n const [hasFetched, setHasFetched] = React.useState(false)\r\n const [categorizedIdeas, setCategorizedIdeas] = React.useState([])\r\n const [params] = useSearchParams()\r\n const queryTickers = params.get('t')!.split(',') // there always be some t param defined\r\n\r\n React.useEffect(() => {\r\n async function fetchIdeas() {\r\n window.gtag?.('event', 'load', { event_category: 'ideas' })\r\n try {\r\n const data = await fetchApi({ location: '/api/ideas_load.ashx', throwOnStatusCodes: [404] })\r\n const ideas = data.ideas.map((idea: IIdea) => {\r\n const dateParts = idea.date.split(' ')\r\n return {\r\n ...idea,\r\n instrument: getInstrument(idea.ticker),\r\n date: dateParts[0].replace('-', ' ').replace('-', ', '),\r\n time: dateParts[1],\r\n }\r\n })\r\n\r\n setCategorizedIdeas(categorizeIdeas(ideas, queryTickers))\r\n setHasFetched(true)\r\n } catch {\r\n setHasError(true)\r\n }\r\n }\r\n\r\n fetchIdeas()\r\n\r\n // run only on mount\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n }, [])\r\n\r\n const handleIdeaDeleted = (idea: IIdea) => {\r\n setCategorizedIdeas((prev) => {\r\n const modifiedCategories = [...prev]\r\n\r\n // remove from specific ticker category\r\n const categoryIndex = modifiedCategories.findIndex((c) => c.ticker === idea.ticker)\r\n if (categoryIndex >= 0) {\r\n const updatedCategory = {\r\n ...modifiedCategories[categoryIndex],\r\n ideas: modifiedCategories[categoryIndex].ideas.filter((i) => i.id !== idea.id),\r\n }\r\n modifiedCategories[categoryIndex] = updatedCategory\r\n }\r\n\r\n // remove from all\r\n const updatedAll = {\r\n ...modifiedCategories[0],\r\n ideas: modifiedCategories[0].ideas.filter((i) => i.id !== idea.id),\r\n }\r\n modifiedCategories[0] = updatedAll\r\n\r\n // remove empty categories\r\n return modifiedCategories.filter((c) => c.ideas.length !== 0)\r\n })\r\n }\r\n\r\n if (!hasFetched || hasError) {\r\n return (\r\n
\r\n {hasError ? 'Unexpected error occurred, please refresh the page.' : 'Loading…'}\r\n
\r\n )\r\n }\r\n\r\n if (categorizedIdeas.length === 0) {\r\n return (\r\n \r\n No saved ideas.\r\n \r\n )\r\n }\r\n\r\n return (\r\n \r\n \r\n {categorizedIdeas.map((category) => (\r\n {category.ideas.length}}>\r\n {category.ticker}\r\n \r\n ))}\r\n \r\n {categorizedIdeas.map((category) => (\r\n \r\n
\r\n {category.ideas.map((idea) => (\r\n \r\n ))}\r\n
\r\n \r\n ))}\r\n
\r\n )\r\n}\r\n","import { Dialog, DialogBody, DialogHeader, DialogStateReturn } from '@finviz/website'\r\n\r\nimport IdeasTabs from './IdeasTabs'\r\n\r\ntype IdeasDialogProps = {\r\n state: DialogStateReturn\r\n}\r\n\r\nexport default function IdeasDialog({ state }: IdeasDialogProps) {\r\n return (\r\n \r\n Your Ideas\r\n \r\n \r\n \r\n \r\n )\r\n}\r\n","import {\r\n Button,\r\n ButtonComponentProps,\r\n ButtonProps,\r\n Dropdown,\r\n DropdownItem,\r\n Spinner,\r\n Tooltip,\r\n TooltipTrigger,\r\n useDialogState,\r\n useTooltipState,\r\n} from '@finviz/website'\r\nimport classnames from 'classnames'\r\nimport * as React from 'react'\r\n\r\nimport IdeasDialog from '../../modals/ideas/Ideas'\r\nimport { saveIdea } from '../../modals/ideas/utils'\r\nimport ChartLayout from '../../models/chart_layout'\r\nimport Quote from '../../models/quote'\r\nimport { getIsMobileScreenSize } from '../../utils'\r\nimport { encodeQueryString } from '../../utils/query_string'\r\n\r\ninterface IdeaDropdownProps {\r\n model: ChartLayout\r\n rounding?: 'none' | 'regular'\r\n theme?: ButtonProps['theme']\r\n size?: ButtonProps['size']\r\n dropdownButtonClassName?: string\r\n}\r\n\r\nexport function IdeasDropdown({\r\n model,\r\n rounding,\r\n dropdownButtonClassName,\r\n ...props\r\n}: React.PropsWithChildren) {\r\n const tooltipState = useTooltipState({ placement: 'right-start' })\r\n const [isAnyQuoteLoading, setIsAnyQuoteLoading] = React.useState(false)\r\n const ref = React.useRef(null)\r\n const dialog = useDialogState()\r\n const hideTooltip = tooltipState.hide\r\n\r\n const dropdownItemProps = isAnyQuoteLoading\r\n ? ({\r\n as: TooltipTrigger,\r\n state: tooltipState,\r\n } as ButtonComponentProps)\r\n : ({} as ButtonComponentProps)\r\n\r\n React.useEffect(() => {\r\n const checkIfAnyQuoteIsLoading = () => {\r\n const fetchingQuotes = Quote.select((quote) => quote.isFetching && quote.fetchedAt === -1)\r\n setIsAnyQuoteLoading(fetchingQuotes.length > 0)\r\n }\r\n\r\n Quote.bind('change', checkIfAnyQuoteIsLoading)\r\n return () => {\r\n Quote.unbind('change', checkIfAnyQuoteIsLoading)\r\n }\r\n }, [])\r\n\r\n React.useEffect(() => {\r\n if (!isAnyQuoteLoading) hideTooltip()\r\n }, [isAnyQuoteLoading, hideTooltip])\r\n\r\n if (!window.FinvizSettings.hasUserPremium) {\r\n return (\r\n \r\n )\r\n }\r\n\r\n return (\r\n <>\r\n \r\n }\r\n >\r\n {\r\n if (isAnyQuoteLoading) {\r\n tooltipState.show()\r\n return\r\n }\r\n saveIdea(model)\r\n }}\r\n >\r\n Save idea\r\n \r\n dialog.show()}\r\n >\r\n Load idea\r\n \r\n \r\n \r\n {isAnyQuoteLoading && (\r\n \r\n
\r\n \r\n
\r\n \r\n Some data is still loading. Please wait.\r\n \r\n
\r\n )}\r\n \r\n )\r\n}\r\n","import { Button, ButtonComponentProps, Delayed, Icon, Spinner, useDialogState } from '@finviz/website'\r\nimport classnames from 'classnames'\r\nimport * as React from 'react'\r\n\r\nimport { publishModalAsyncModule } from '../../modals/publish/async-modules'\r\nimport ChartLayout from '../../models/chart_layout'\r\nimport { useAsyncModule } from '../../utils/async-modules-utils'\r\n\r\ninterface PublishProps extends Pick {\r\n model: ChartLayout\r\n}\r\n\r\nexport function Publish({ model, ...props }: React.PropsWithChildren) {\r\n const dialog = useDialogState()\r\n const isDialogOpen = dialog.useState('open')\r\n const [publishModalModule, { isLoading }] = useAsyncModule({\r\n ...publishModalAsyncModule,\r\n shouldLoadModule: isDialogOpen,\r\n errorSeverity: 'medium',\r\n onError: () => dialog.hide(),\r\n })\r\n const PublishDialog = publishModalModule?.default\r\n\r\n return (\r\n <>\r\n dialog.show()}\r\n leftContent={\r\n isLoading ? (\r\n \r\n }\r\n >\r\n \r\n \r\n ) : (\r\n 'share'\r\n )\r\n }\r\n />\r\n {PublishDialog && }\r\n \r\n )\r\n}\r\n","import {\r\n Button,\r\n ButtonSizeType,\r\n ButtonThemeType,\r\n Delayed,\r\n Icon,\r\n Spinner,\r\n TourDefinition,\r\n useTour,\r\n} from '@finviz/website'\r\nimport classnames from 'classnames'\r\nimport * as React from 'react'\r\n\r\nimport { SpecificChartFunctionality } from '../../constants/common'\r\nimport { getRequestFullscreen, isRedesignEnabled } from '../../utils'\r\nimport { encodeQueryString } from '../../utils/query_string'\r\n\r\nconst isPremium = window.FinvizSettings.hasUserPremium\r\n\r\n// If we need to update / discontinue some tour we can use skip flag on legacy version to ensure that it won't reset users tour but won't include it in new tours\r\nfunction getTour(page: SpecificChartFunctionality): TourDefinition[] {\r\n return [\r\n {\r\n id: 'chart-tour',\r\n steps: [\r\n {\r\n title: 'Chart Tour',\r\n body: 'Discover powerful Chart features in the 2-min tour to master your analysis of trading opportunities.',\r\n },\r\n ...(isPremium\r\n ? [\r\n {\r\n title: 'Scale the Timeline',\r\n body: 'Grab the timeline to zoom it in and out. Double-click the timeline to reset the scaling.',\r\n target: '[data-testid=\"chart-0-pane-0-zoomer\"]',\r\n },\r\n {\r\n title: 'Scale the Price Axis',\r\n body: 'Grab the Price Axis to zoom it in and out. Move the chart around freely in any direction when Price Axis has custom scale. Double-click the Price Axis to reset the scaling.',\r\n target: '[data-testid=\"chart-0-pane-0-scaler\"]',\r\n },\r\n {\r\n title: 'Drawing tools & settings',\r\n body: 'Pick any Drawing Tool to analyze the market. Tailor your drawing experience with additional settings.',\r\n target: '#toolbar',\r\n },\r\n {\r\n title: 'Fine-tune Drawings',\r\n body: 'Double-click on a chart drawing to tweak its color and style. Right-click on a drawing to access other options, such as changing its visibility, order, and more.',\r\n target: '[data-testid=\"chart-0-pane-0\"]',\r\n },\r\n ]\r\n : [\r\n {\r\n title: 'Enable Drawing mode',\r\n body: (\r\n <>\r\n \r\n Finviz*Elite\r\n {' '}\r\n subscribers get access a whole suite of drawing tools which allow them to draw on and annotate the\r\n chart.
\r\n While in drawing mode, you can also pan the chart, scale the timeline and price axis and much more.\r\n \r\n ),\r\n target: '[data-testid=\"quote-toggle-draw-btn\"]',\r\n placement: 'bottom-start',\r\n },\r\n ]),\r\n {\r\n title: 'Save your best Ideas',\r\n body: isPremium\r\n ? 'Besides your drawings being autosaved, you can manually save ideas that you wish to revisit later.'\r\n : 'Your drawings will be saved automatically, but you can also manually save ideas that you wish to revisit later.',\r\n target: '[data-testid=\"chart-toolbar-ideas\"]',\r\n placement: 'bottom-start',\r\n },\r\n ...(page === SpecificChartFunctionality.quotePage\r\n ? []\r\n : [\r\n {\r\n title: 'Chart Layouts & Charts Sync',\r\n body: 'Switch between Chart Layouts to view multiple charts on your screen. Synchronize Ticker, Timeframe or Crosshair position across your charts.',\r\n target: '[data-testid=\"chart-layout-layout\"]',\r\n },\r\n ]),\r\n ...(!getRequestFullscreen(document.documentElement) && page === SpecificChartFunctionality.chartPage\r\n ? []\r\n : [\r\n {\r\n title: 'Fullscreen mode',\r\n body:\r\n page === SpecificChartFunctionality.quotePage\r\n ? 'Open the chart in an expanded view for full-page display and split-screen charts.'\r\n : 'Toggle the window to fill your entire screen.',\r\n target: '[data-testid=\"chart-layout-fullscreen\"]',\r\n placement: page === SpecificChartFunctionality.chartPage ? 'bottom' : 'bottom-end',\r\n },\r\n ]),\r\n {\r\n title: 'Share chart',\r\n body: 'Share a chart together with your analysis and ideas.',\r\n target: '[data-testid=\"chart-toolbar-publish\"]',\r\n overlayPadding: page === SpecificChartFunctionality.quotePage ? 3 : undefined,\r\n placement: 'bottom',\r\n },\r\n ...(isRedesignEnabled() || page === SpecificChartFunctionality.chartPage\r\n ? [\r\n {\r\n title: 'Theme',\r\n body: 'Switch between the Light and Dark theme.',\r\n target: '[data-testid=\"chart-layout-theme\"]',\r\n },\r\n ]\r\n : []),\r\n {\r\n title: 'Study Settings',\r\n body: 'Customize the Chart Type and appearance. Add Overlays, Indicators and toggle Extended Hours.',\r\n target: '[data-testid=\"chart-settings-open-btn\"]',\r\n placement: page === SpecificChartFunctionality.chartPage ? 'bottom' : 'bottom-end',\r\n },\r\n ],\r\n },\r\n page === SpecificChartFunctionality.chartPage && {\r\n id: 'sidebar-watchlist',\r\n steps: [\r\n {\r\n title: 'Explore Your Portfolios',\r\n body: 'Effortlessly navigate through your portfolio holdings. With just a click, visualize individual stock charts, gain insights, and stay updated on your investments.',\r\n target: '[data-testid=\"sidebar-portfolio-btn\"]',\r\n placement: 'left-start',\r\n },\r\n ],\r\n },\r\n ].filter(Boolean) as TourDefinition[]\r\n}\r\n\r\ninterface TourButtonProps {\r\n page: SpecificChartFunctionality\r\n rounding?: 'none' | 'regular'\r\n size?: ButtonSizeType\r\n theme?: ButtonThemeType\r\n className?: string\r\n}\r\n\r\nexport function TourButton({ page, className, theme, ...props }: React.PropsWithChildren) {\r\n const tour = useTour()\r\n const pageTours = getTour(page)\r\n const [userTour, setCurrentTour] = React.useState(tour.getStepsForUser(pageTours))\r\n const buttonTheme: ButtonThemeType = userTour.hasNewTours ? 'blue' : (theme ?? 'headerItem')\r\n\r\n return (\r\n \r\n }\r\n >\r\n \r\n \r\n ) : (\r\n \r\n )\r\n }\r\n className={className}\r\n contentClass={page !== SpecificChartFunctionality.quotePage ? 'hidden lg:flex' : ''}\r\n title=\"Explore new features\"\r\n onClick={async () => {\r\n if (userTour) {\r\n const activeTour = await tour.startTour(userTour.tour)\r\n activeTour?.once('inactive', () => {\r\n setCurrentTour(tour.getStepsForUser(pageTours))\r\n })\r\n }\r\n }}\r\n />\r\n )\r\n}\r\n","import * as dateFns from 'date-fns'\r\n\r\nimport { getChartStartEndDates } from '../controllers/renderUtils'\r\nimport Quote from '../models/quote'\r\n\r\n// **************START**************\r\n// Functions from here until END have to be in sync with\r\n// Finviz-Website: components/timeframe-bar/custom-date-range-utils.ts\r\n// *********************************\r\n\r\nexport enum CustomDateRangePrefixEnum {\r\n Range = 'range',\r\n Prev = 'prev',\r\n}\r\n\r\nexport const CUSTOM_DATE_RANGE = 'custom'\r\nexport const DATE_RANGE_PREFIX_DELMITER = '_'\r\nconst CUSTOM_DATE_RANGE_DELIMITER = 'x'\r\nconst CUSTOM_PREV_RANGE_DELIMITER = '-'\r\n\r\nexport function getParsedDateRange(dateRange: string) {\r\n return dateRange.split(DATE_RANGE_PREFIX_DELMITER)\r\n}\r\n\r\nexport function parseCustomDateRangeUrlParam({ dateRange, anchorDate }: { dateRange: string; anchorDate: Date }) {\r\n const [dateRangePrefix, dateRangeValue] = getParsedDateRange(dateRange)\r\n\r\n if (dateRangePrefix === CustomDateRangePrefixEnum.Range) {\r\n const [dateFromString, dateToString] = dateRangeValue.replace(/-/g, '/').split(CUSTOM_DATE_RANGE_DELIMITER)\r\n const dateFrom = dateFromString ? new Date(dateFromString) : null\r\n const dateTo = dateToString ? new Date(dateToString) : null\r\n return {\r\n start: dateFrom && !Number.isNaN(dateFrom.getTime()) ? dateFrom : null,\r\n end: dateTo && !Number.isNaN(dateTo.getTime()) ? dateFns.endOfDay(dateTo) : null,\r\n }\r\n }\r\n\r\n if (dateRangePrefix === CustomDateRangePrefixEnum.Prev) {\r\n const [years, months, days] = dateRangeValue.split(CUSTOM_PREV_RANGE_DELIMITER).map(Number)\r\n\r\n if ([years, months, days].some(Number.isNaN)) {\r\n return { start: null, end: null }\r\n }\r\n\r\n return {\r\n start: dateFns.startOfDay(dateFns.sub(anchorDate, { years, months, days: days - 1 })),\r\n end: anchorDate,\r\n }\r\n }\r\n\r\n return { start: null, end: anchorDate }\r\n}\r\n\r\n// **************END**************\r\n// Functions below don't need to be\r\n// in sync with Website repository\r\n// *******************************\r\n\r\nexport function getParsedDateRangeMetaData({ dateRange, quote }: { dateRange: string; quote: Quote }) {\r\n const parsedRange = getChartStartEndDates({ dateRange, quote })\r\n const [dateRangePrefix] = getParsedDateRange(dateRange)\r\n\r\n let startQuoteDate: Date | null = null\r\n let endQuoteDate: Date | null = null\r\n let numOfDaysToRender: number | null = null\r\n\r\n if (parsedRange.start && dateRangePrefix === CustomDateRangePrefixEnum.Prev) {\r\n const daysInQuote = quote.getDaysInQuote()\r\n const reversedDaysInQuote = [...daysInQuote].reverse()\r\n const startQuoteDayIndex = reversedDaysInQuote.findIndex((date) => date.getTime() <= parsedRange.start!.getTime())\r\n const endQuoteDayIndex = reversedDaysInQuote.findIndex((date) => date.getTime() <= parsedRange.end!.getTime())\r\n startQuoteDate = reversedDaysInQuote[startQuoteDayIndex] ?? null\r\n endQuoteDate = reversedDaysInQuote[endQuoteDayIndex] ?? null\r\n numOfDaysToRender = quote.interval <= 5 ? startQuoteDayIndex - endQuoteDayIndex + 1 : null\r\n }\r\n\r\n return {\r\n start: parsedRange.start,\r\n end: parsedRange.end,\r\n startQuoteDate,\r\n endQuoteDate,\r\n numOfDaysToRender,\r\n numOfBarsToRender: (numOfDaysToRender ?? 0) * (quote.getBarsInDay() ?? 0) || undefined,\r\n renderDateStart: parsedRange.start && dateFns.startOfDay(parsedRange.start),\r\n renderDateEnd: parsedRange.end && dateFns.endOfDay(parsedRange.end),\r\n }\r\n}\r\n","import * as d3 from 'd3'\r\nimport * as dateFns from 'date-fns'\r\n\r\nimport { Instrument, ObjectHash } from '../../types/shared'\r\nimport type PerfChart from '../charts/perf_chart'\r\nimport {\r\n CHART_MARGIN,\r\n DateRangeType,\r\n PREMARKET_AFTERMARKET_HOURS,\r\n ScaleType,\r\n SpecificChartFunctionality,\r\n TIMEFRAME,\r\n} from '../constants/common'\r\nimport Chart from '../models/chart'\r\nimport ChartEventElement from '../models/chart-event-element'\r\nimport ChartLayout from '../models/chart_layout'\r\nimport { IChartSettings, IIndicatorSettings, ISettings } from '../models/chart_settings/interfaces'\r\nimport { CHART_EVENT_BADGE_SIZE } from '../models/constants'\r\nimport Element from '../models/element'\r\nimport Pane, { ScaleAxis } from '../models/pane'\r\nimport Quote from '../models/quote'\r\nimport Utils from '../utils'\r\nimport utils, { convertLocalToNyTime, dateFromUnixTimestamp, isRedesignedPage } from '../utils'\r\nimport { getBarWidthWithMargin, getZoomFactorForBarsToDisplay } from '../utils/chart'\r\nimport {\r\n DATE_RANGE_PREFIX_DELMITER,\r\n getParsedDateRangeMetaData,\r\n parseCustomDateRangeUrlParam,\r\n} from '../utils/chart-date-range-utils'\r\n\r\ninterface VisibleBarNumberProps {\r\n start: Date | null\r\n end: Date\r\n quote: Quote\r\n dateRange: string\r\n}\r\n\r\ninterface ChartZoomAndLeftOffsetProps extends Omit {\r\n chartVisibleWidth: number\r\n numOfBarsToRender?: number\r\n chartModel: Chart\r\n}\r\n\r\ninterface ChartStartEndDatesProps {\r\n dateRange: string\r\n quote: Quote\r\n}\r\n\r\nexport const getVisibleBarsNumber = ({ start, end, quote, dateRange }: VisibleBarNumberProps) => {\r\n const startInSec = start ? start.getTime() / 1000 : 0\r\n const endInSec = end.getTime() / 1000\r\n const isQuoteDateInRange = (quoteDate: number) => quoteDate >= startInSec && quoteDate <= endInSec\r\n const lastQuoteDateIndex = quote.barIndex[quote.barIndex.length - 1]\r\n let lastVisibleBarIndex = lastQuoteDateIndex\r\n let numOfVisibleBars = 0\r\n if (\r\n [DateRangeType.d1, DateRangeType.d5].includes(dateRange as DateRangeType) &&\r\n quote.instrument === Instrument.Stock\r\n ) {\r\n numOfVisibleBars = quote.drawMinutesPerDay\r\n } else {\r\n let firstVisibleBarIndex = -1\r\n lastVisibleBarIndex = -1\r\n quote.date.forEach((quoteDate, index) => {\r\n if (isQuoteDateInRange(quoteDate)) {\r\n if (firstVisibleBarIndex === -1) {\r\n firstVisibleBarIndex = quote.barIndex[index]\r\n }\r\n lastVisibleBarIndex = quote.barIndex[index]\r\n }\r\n })\r\n numOfVisibleBars = lastVisibleBarIndex - firstVisibleBarIndex + 1\r\n\r\n if (firstVisibleBarIndex === -1 && lastVisibleBarIndex === -1) {\r\n return { numOfVisibleBars: 0, numOfBarsOffset: 0 }\r\n }\r\n }\r\n\r\n return { numOfVisibleBars, numOfBarsOffset: lastQuoteDateIndex - lastVisibleBarIndex }\r\n}\r\n\r\nexport const getChartZoomAndLeftOffset = ({\r\n chartVisibleWidth,\r\n start,\r\n end,\r\n quote,\r\n chartModel,\r\n numOfBarsToRender,\r\n}: ChartZoomAndLeftOffsetProps) => {\r\n const { numOfVisibleBars, numOfBarsOffset } = getVisibleBarsNumber({\r\n start,\r\n end,\r\n quote,\r\n dateRange: chartModel.dateRange,\r\n })\r\n if (numOfVisibleBars === 0) {\r\n return { zoomFactor: chartModel.zoomFactor, leftOffset: chartModel.leftOffset }\r\n }\r\n\r\n const chartLayout = chartModel.chart_layout()\r\n const zoomFactor = getZoomFactorForBarsToDisplay({\r\n chartLayout,\r\n chartVisibleWidth,\r\n numOfVisibleBars: numOfBarsToRender ?? numOfVisibleBars,\r\n })\r\n const barWidth = getBarWidthWithMargin({ chartLayout, zoomFactor })\r\n const leftOffset =\r\n getLeftOffset({\r\n quote,\r\n chartModel,\r\n config: {},\r\n barWidth,\r\n numberOfBarsToDraw: numOfBarsToRender,\r\n }) +\r\n numOfBarsOffset * barWidth\r\n return { zoomFactor, leftOffset }\r\n}\r\n\r\nexport const getChartStartEndDates = ({ dateRange, quote }: ChartStartEndDatesProps) => {\r\n const daysInQuote = quote.getDaysInQuote()\r\n const lastDate = dateFromUnixTimestamp(quote.date[quote.date.length - 1])\r\n\r\n if (dateRange.includes(DATE_RANGE_PREFIX_DELMITER)) {\r\n const range = parseCustomDateRangeUrlParam({ dateRange, anchorDate: lastDate })\r\n const end = convertLocalToNyTime(\r\n range.end && range.end.getTime() <= lastDate.getTime() ? range.end : lastDate,\r\n false\r\n )\r\n return {\r\n start: range.start && convertLocalToNyTime(range.start, false),\r\n end,\r\n }\r\n }\r\n\r\n let start\r\n // No condition is needed here, but this would be dateRangePrefix === DateRangePrefixEnum.Enum\r\n switch (dateRange) {\r\n case DateRangeType.d1:\r\n lastDate.setHours(23, 59, 59, 999)\r\n start = daysInQuote.length === 0 ? lastDate : daysInQuote[daysInQuote.length - 1]\r\n break\r\n case DateRangeType.d5:\r\n lastDate.setHours(23, 59, 59, 999)\r\n const startDateIndex = daysInQuote.length === 0 ? -1 : Math.max(daysInQuote.length - 5, 0)\r\n start = startDateIndex === -1 ? lastDate : daysInQuote[startDateIndex]\r\n break\r\n case DateRangeType.m1:\r\n start = dateFns.subMonths(lastDate, 1)\r\n break\r\n case DateRangeType.m3:\r\n start = dateFns.subMonths(lastDate, 3)\r\n break\r\n case DateRangeType.m6:\r\n start = dateFns.subMonths(lastDate, 6)\r\n break\r\n case DateRangeType.ytd:\r\n start = dateFns.startOfYear(lastDate)\r\n break\r\n case DateRangeType.y1:\r\n start = dateFns.subYears(lastDate, 1)\r\n break\r\n case DateRangeType.y2:\r\n start = dateFns.subYears(lastDate, 2)\r\n break\r\n case DateRangeType.y5:\r\n start = dateFns.subYears(lastDate, 5)\r\n break\r\n case DateRangeType.max:\r\n default:\r\n start = null\r\n break\r\n }\r\n\r\n return { start: start && convertLocalToNyTime(start, false), end: convertLocalToNyTime(lastDate, false) }\r\n}\r\n\r\ninterface GetLeftOffsetProps {\r\n quote: Quote\r\n chartModel: Chart\r\n config?: { stretch?: boolean }\r\n barWidth?: number\r\n barIndex?: number\r\n numberOfBarsToDraw?: number\r\n shouldAlignDaysToLeftApplied?: boolean\r\n}\r\n\r\nexport const getMinMaxLeftOffset = ({\r\n newLeftOffset,\r\n chartModel,\r\n barWidth = getBarWidthWithMargin({ zoomFactor: chartModel.zoomFactor, chartLayout: chartModel.chart_layout() }),\r\n barIndex,\r\n}: {\r\n newLeftOffset: number\r\n chartModel: Chart\r\n barWidth?: number\r\n barIndex: number\r\n}) => {\r\n const { ChartSettings } = chartModel.getChartLayoutSettings()\r\n const width = chartModel.width - ChartSettings.left.width - ChartSettings.right.width\r\n const numOfBarsInView = Math.floor(width / barWidth)\r\n const fx = (index: number) => index * barWidth\r\n return ~~Utils.min(barWidth / 2, Utils.max(newLeftOffset, width - fx(barIndex + numOfBarsInView)))\r\n}\r\n\r\nexport function getFullChartWidth({\r\n hasAftermarket,\r\n hasPremarket,\r\n timeframeMinutes,\r\n barWidthWithMargin,\r\n}: {\r\n hasPremarket: boolean\r\n hasAftermarket: boolean\r\n timeframeMinutes: number\r\n barWidthWithMargin: number\r\n}) {\r\n const premarketHoursLength = hasPremarket ? PREMARKET_AFTERMARKET_HOURS : 0\r\n const aftermarketHoursLength = hasAftermarket ? PREMARKET_AFTERMARKET_HOURS : 0\r\n const marketMinutesLength = (6.5 + premarketHoursLength + aftermarketHoursLength) * 60\r\n // CHART_MARGIN.L as left offset + CHART_MARGIN.XXL as right offset\r\n return CHART_MARGIN.L + CHART_MARGIN.XXL + (marketMinutesLength / timeframeMinutes) * barWidthWithMargin\r\n}\r\n\r\nexport function getIntradayChartConfig({\r\n timeframeMinutes,\r\n barWidthWithMargin,\r\n hasPremarket,\r\n hasAftermarket,\r\n maxWidth,\r\n canCropChart,\r\n}: {\r\n hasPremarket: boolean\r\n hasAftermarket: boolean\r\n timeframeMinutes: number\r\n barWidthWithMargin: number\r\n maxWidth: number\r\n canCropChart: boolean\r\n}) {\r\n const fullChartWidth = getFullChartWidth({ hasPremarket, hasAftermarket, barWidthWithMargin, timeframeMinutes })\r\n const offsetChartAfter = 16 // Int from 0-23 , if last quote date is >= this constant `offsetInPx` is applied (chart is moved to the left)\r\n const cropChartMinutesLength = PREMARKET_AFTERMARKET_HOURS * 60\r\n const offsetInPx = (cropChartMinutesLength / timeframeMinutes) * barWidthWithMargin\r\n const chartWidthWithOffset = fullChartWidth - offsetInPx\r\n const shouldCropChart =\r\n canCropChart && hasAftermarket && hasPremarket && maxWidth >= chartWidthWithOffset && maxWidth < fullChartWidth\r\n\r\n return {\r\n fullChartWidth,\r\n offsetInPx: shouldCropChart ? offsetInPx : 0,\r\n chartWidthWithOffset: shouldCropChart ? fullChartWidth - offsetInPx : fullChartWidth,\r\n offsetChartAfter,\r\n }\r\n}\r\n\r\nexport const getLeftOffset = ({\r\n quote,\r\n chartModel,\r\n config,\r\n barWidth = getBarWidthWithMargin({ zoomFactor: chartModel.zoomFactor, chartLayout: chartModel.chart_layout() }),\r\n barIndex = getBarIndex(quote),\r\n numberOfBarsToDraw,\r\n shouldAlignDaysToLeftApplied = true,\r\n}: GetLeftOffsetProps) => {\r\n const { ChartSettings } = chartModel.getChartLayoutSettings()\r\n const width = chartModel.width - ChartSettings.left.width - ChartSettings.right.width\r\n const specificChartFunctionality = chartModel.chart_layout().specificChartFunctionality\r\n if (config?.stretch) {\r\n return 0\r\n }\r\n if (getIsSmallIndexChart(specificChartFunctionality)) {\r\n return barWidth\r\n }\r\n const fx = (index: number) => index * barWidth\r\n let leftOffset = width - fx(barIndex) - Math.round(barWidth / 2)\r\n leftOffset = Math.round(Utils.min(barWidth / 2, Utils.max(leftOffset, width - fx(barIndex + 45))))\r\n if (\r\n shouldAlignDaysToLeftApplied &&\r\n shouldAlignDaysToLeft({\r\n quote,\r\n numberOfBarsToDraw,\r\n specificChartFunctionality,\r\n dateRange: chartModel.dateRange,\r\n })\r\n ) {\r\n let drawDaysInOneChart = 1\r\n if (numberOfBarsToDraw) {\r\n drawDaysInOneChart = Math.ceil(numberOfBarsToDraw / quote.getBarsInDay()!)\r\n } else if (quote.interval === 10 || chartModel.dateRange === DateRangeType.d5) {\r\n drawDaysInOneChart = 5\r\n } else if (quote.interval === 15) {\r\n drawDaysInOneChart = 6\r\n } else if (quote.interval === 30) {\r\n drawDaysInOneChart = 12\r\n } else if (quote.interval === 60) {\r\n drawDaysInOneChart = 22\r\n } else if (quote.interval === 120) {\r\n drawDaysInOneChart = 39\r\n } else if (quote.interval === 240) {\r\n drawDaysInOneChart = 78\r\n } else if (quote.interval > 240) {\r\n drawDaysInOneChart = (quote.interval / 30) * 10\r\n }\r\n const { offsetInPx, offsetChartAfter } = getIntradayChartConfig({\r\n hasPremarket: quote.premarket,\r\n hasAftermarket: quote.aftermarket,\r\n barWidthWithMargin: barWidth,\r\n timeframeMinutes: quote.interval,\r\n maxWidth: chartModel.width,\r\n canCropChart: !chartModel.dateRange,\r\n })\r\n const drawDaysWidth = drawDaysInOneChart * quote.getBarsInDay()! * barWidth - offsetInPx\r\n\r\n // +1 is a buffer as it often happens drawDaysWidth is wider than width by tiny amount (< 1/10000 of px)\r\n if (drawDaysWidth <= width + 1) {\r\n const lastQuoteDate = quote.date.last() ? utils.dateFromUnixTimestamp(quote.date.last()!) : null\r\n // Align start of day to left if we have enough space to show all bars in day\r\n const barsToOffset = (Object.keys(quote.getDayToOffset()).length - drawDaysInOneChart) * quote.getBarsInDay()!\r\n const offsetChartInPx = (lastQuoteDate?.getHours() ?? 0) >= offsetChartAfter ? offsetInPx : 0\r\n // Math.max(1, ~~num) is to mimic imlementation from getHalfBarWidth(),\r\n // we never render bar with width < 1 but at the same time when we have and odd\r\n // width like 5, wa want to floor because of pixel perfect rendering\r\n leftOffset = Math.round(-fx(barsToOffset) + Math.max(1, ~~(barWidth / 2))) - offsetChartInPx\r\n }\r\n }\r\n // getMinMaxLeftOffset move left offset to keep at least one bar in view what isn't desired for offscreen charts\r\n if (specificChartFunctionality === SpecificChartFunctionality.offScreen) {\r\n return leftOffset\r\n }\r\n return getMinMaxLeftOffset({\r\n newLeftOffset: leftOffset,\r\n chartModel,\r\n barWidth,\r\n barIndex,\r\n })\r\n}\r\n\r\nexport const getBarIndex = (quote: Quote) => quote?.getBarIndex(quote.open?.length ? quote.open.length - 1 : 0) || 0\r\n\r\nexport const getIsSmallIndexChart = (specificChartFunctionality: SpecificChartFunctionality) =>\r\n specificChartFunctionality === SpecificChartFunctionality.smallIndex\r\n\r\ninterface ShouldAlignDaysToLeftProps {\r\n quote: Quote\r\n numberOfBarsToDraw?: number\r\n specificChartFunctionality: SpecificChartFunctionality\r\n dateRange: DateRangeType | null\r\n}\r\n\r\n/**\r\n * Evaluate if days should be aligned to the left\r\n * @param {object} object.quote - Quote model\r\n * @param {string} object.specificChartFunctionality - SpecificChartFunctionality enum\r\n * @returns {boolean} boolean\r\n * */\r\nexport const shouldAlignDaysToLeft = ({\r\n quote,\r\n dateRange,\r\n numberOfBarsToDraw,\r\n specificChartFunctionality,\r\n}: ShouldAlignDaysToLeftProps) => {\r\n const isStockIntraday = quote.isIntraday && quote.instrument === Instrument.Stock\r\n const isIntradayDateRange = !!dateRange && [DateRangeType.d1, DateRangeType.d5].includes(dateRange)\r\n const isOffScreen = specificChartFunctionality === SpecificChartFunctionality.offScreen\r\n const isOffScreenWithNoDateRange = isOffScreen && !dateRange\r\n const isOffScreenIntradayDateRange = isOffScreen && isIntradayDateRange\r\n const isOffScreenWithFixedBars = isOffScreen && numberOfBarsToDraw\r\n\r\n const isQuotePage = specificChartFunctionality === SpecificChartFunctionality.quotePage\r\n const isQuotePageWithNoDateRange = isQuotePage && !dateRange\r\n const isQuotePageIntradayDateRange = isQuotePage && isIntradayDateRange\r\n const isQuotePageWithFixedBars = isQuotePage && numberOfBarsToDraw\r\n\r\n const isChartPage = specificChartFunctionality === SpecificChartFunctionality.chartPage\r\n const isChartsInradayDateRange = isChartPage && isIntradayDateRange\r\n const isChartPageWithFixedBars = isChartPage && numberOfBarsToDraw\r\n return (\r\n isStockIntraday &&\r\n (isOffScreenWithNoDateRange ||\r\n isOffScreenIntradayDateRange ||\r\n isOffScreenWithFixedBars ||\r\n isQuotePageWithNoDateRange ||\r\n isQuotePageIntradayDateRange ||\r\n isQuotePageWithFixedBars ||\r\n isChartsInradayDateRange ||\r\n isChartPageWithFixedBars)\r\n )\r\n}\r\n\r\ninterface ClipProps {\r\n canvasCtx: RenderingContext2DType\r\n width: number\r\n height: number\r\n Settings: ISettings['ChartSettings'] | ISettings['IndicatorSettings']\r\n}\r\n// pane canvasCtx clip\r\nexport const clip = ({ canvasCtx, width, height, Settings }: ClipProps) => {\r\n const contentWidth = width - Settings.left.width - Settings.right.width\r\n const contentHeight = height - Settings.top.height - Settings.bottom.height\r\n canvasCtx.beginPath()\r\n canvasCtx.rect(Settings.left.width, Settings.top.height, contentWidth, contentHeight)\r\n canvasCtx.clip()\r\n}\r\n\r\nexport const getSettings = (paneModel: Pane): IIndicatorSettings | IChartSettings => {\r\n const { ChartSettings, IndicatorSettings } = paneModel.chart().getChartLayoutSettings()\r\n for (const element of paneModel.elements().all()) {\r\n if (element.isIndicator()) {\r\n return IndicatorSettings\r\n }\r\n }\r\n return ChartSettings\r\n}\r\n\r\ninterface RecountScaleProps {\r\n chartModel: Chart\r\n paneModel: Pane\r\n}\r\n\r\ntype ScaledFn = Partial & (d3.ScaleLinear | d3.ScaleSymLog)\r\n\r\nconst getShouldOffsetChartDomain = (elementModel: Element | ChartEventElement) => {\r\n const quote = elementModel.pane().chart().quote()\r\n\r\n return quote.chartEvents.length > 0 && ![TIMEFRAME.w, TIMEFRAME.m].includes(quote.timeframe)\r\n}\r\n\r\nexport const recountScale = ({ chartModel, paneModel }: RecountScaleProps) => {\r\n const { ChartSettings, IndicatorSettings, MarketSentimentSettings } = chartModel.getChartLayoutSettings()\r\n const chartLayout = chartModel.chart_layout()\r\n const barWidthWithMargin = getBarWidthWithMargin({ chartLayout, zoomFactor: chartModel.zoomFactor })\r\n for (const elementModel of [...paneModel.getAllElements(), ...paneModel.getAllChartEvents(false)]) {\r\n const el = elementModel.instance\r\n const isChart = elementModel.isChart()\r\n if (isChart || elementModel.isIndicator()) {\r\n let fx: ScaledFn, Settings: ISettings['MarketSentimentSettings' | 'ChartSettings' | 'IndicatorSettings'], width\r\n const scaleType = isChart ? chartModel.scale : ScaleType.Linear\r\n if (isChart) {\r\n Settings = chartModel.instrument === Instrument.MarketSentiment ? MarketSentimentSettings : ChartSettings\r\n } else {\r\n Settings = IndicatorSettings as ISettings['IndicatorSettings']\r\n }\r\n const contentHeight = paneModel.height - Settings.top.height - Settings.bottom.height\r\n\r\n if (chartModel.stretch) {\r\n width = chartModel.width - Settings.left.width - Settings.right.width\r\n const chartElement = chartModel.getChartElement()\r\n // PerfChart can be only imported as type because of circular dependency, that's why it's not possible to do instanceof check\r\n const isPerfChart = !!chartElement?.instance && 'getCompleteChartNumOfBars' in chartElement?.instance\r\n const perfChartInstance = isPerfChart ? (chartElement.instance as PerfChart) : null\r\n const numOfBars = perfChartInstance?.getCompleteChartNumOfBars() ?? chartModel.quote().close.length\r\n fx = d3\r\n .scaleLinear()\r\n .range([0, width])\r\n .domain([0, Math.max(0, numOfBars - 1)]) as ScaledFn\r\n } else {\r\n fx = ((index: number) => index * barWidthWithMargin) as ScaledFn\r\n fx.invert = (x: number) => x / barWidthWithMargin\r\n fx.width = function (w) {\r\n return this.invert(w) - this.invert(0)\r\n }\r\n }\r\n paneModel.updateAttribute('scale', { x: fx }) // some elements need fx to count getMinMax\r\n\r\n const { min, max } = paneModel.scaleRange || el.getMinMax!()\r\n let fy\r\n\r\n const handleDomainOffset = (currentScale: ScaledFn, scaleCreator: any) => {\r\n if (isChart && getShouldOffsetChartDomain(elementModel)) {\r\n const protectedHeightPx = contentHeight - CHART_EVENT_BADGE_SIZE\r\n const minPx = currentScale(min)\r\n const domain = currentScale.domain()\r\n if (minPx > protectedHeightPx) {\r\n const tempScale = scaleCreator().range([0, protectedHeightPx]).domain([max, min])\r\n const extendedMin = tempScale.invert(contentHeight)\r\n currentScale.domain([domain[0], extendedMin])\r\n }\r\n }\r\n }\r\n\r\n switch (scaleType) {\r\n case ScaleType.Logarithmic:\r\n fy = d3.scaleSymlog().range([0, contentHeight]).domain([max, min]) as ScaledFn\r\n handleDomainOffset(fy, d3.scaleSymlog)\r\n break\r\n default:\r\n fy = d3.scaleLinear().range([0, contentHeight]).domain([max, min]) as ScaledFn\r\n if (!paneModel.scaleRange) {\r\n fy = fy.nice(10)\r\n handleDomainOffset(fy, d3.scaleLinear)\r\n }\r\n break\r\n }\r\n fy.height = function (h: number) {\r\n return this.invert(h) - this.invert(0)\r\n }\r\n paneModel.updateAttribute('scale', {\r\n x: fx,\r\n y: fy,\r\n })\r\n\r\n if (isChart) {\r\n el.setupAxis!(fx as ScaleAxis)\r\n }\r\n break\r\n }\r\n }\r\n}\r\n\r\n// general, only when blurry ends won't be visible or didn't matter\r\nexport const getOffsetFromLineWidth = (lineWidth: number) => (lineWidth % 2 === 0 ? 0 : 0.5)\r\n\r\ninterface IXYOffsetFromLine {\r\n lineWidth: number\r\n x1: number\r\n y1: number\r\n x2: number\r\n y2: number\r\n}\r\n\r\n// return x,y offsets for pixel perfect line rendering\r\nexport const getXYOffsetFromLine = ({ lineWidth, x1, y1, x2, y2 }: IXYOffsetFromLine) => {\r\n // don't add offset is lineWidth is even\r\n if (lineWidth % 2 === 0) {\r\n return { x: 0, y: 0 }\r\n }\r\n if (y1 === y2) {\r\n return { x: 0, y: 0.5 } // horizontal line\r\n } else if (x1 === x2) {\r\n return { x: 0.5, y: 0 } // vertical line\r\n } else {\r\n return { x: 0.5, y: 0.5 } // diagonal line\r\n }\r\n}\r\n\r\nexport const getRoundedObject = (obj: T): T => {\r\n const rounded = Object.entries(obj)\r\n for (let i = 0; i < rounded.length; i++) {\r\n rounded[i][1] = Math.round(rounded[i][1])\r\n }\r\n return Object.fromEntries(rounded) as T\r\n}\r\n\r\ninterface ITranslate {\r\n context: CanvasRenderingContext2D\r\n xOffset: number\r\n yOffset: number\r\n}\r\n\r\ninterface ITranslateObj {\r\n do: () => void\r\n undo: () => void\r\n}\r\n\r\nexport const getTranslate = ({ context, xOffset, yOffset }: ITranslate): ITranslateObj => ({\r\n do: () => context.translate(xOffset, yOffset),\r\n undo: () => context.translate(xOffset * -1, yOffset * -1),\r\n})\r\n\r\ninterface IPercentageScaleValue {\r\n number: number\r\n base: number\r\n}\r\n\r\nexport const getPercentageFromValue = ({ number, base }: IPercentageScaleValue) => ((number - base) / base) * 100\r\n\r\nexport const getValueFromPercentage = ({ number, base }: IPercentageScaleValue) => (number / 100) * base + base\r\n\r\ninterface UpdateZoomAndLeftOffsetByDateRangeProps {\r\n chartModel: Chart\r\n quote: Quote\r\n}\r\n\r\nexport function updateZoomAndLeftOffsetByDateRange({ chartModel, quote }: UpdateZoomAndLeftOffsetByDateRangeProps) {\r\n const { ChartSettings } = chartModel.getChartLayoutSettings()\r\n const chartVisibleWidth = chartModel.width - (ChartSettings.left.width + ChartSettings.right.width)\r\n\r\n const { start, end, numOfBarsToRender } = getParsedDateRangeMetaData({\r\n dateRange: chartModel.dateRange,\r\n quote,\r\n })\r\n\r\n const { zoomFactor, leftOffset } = getChartZoomAndLeftOffset({\r\n chartVisibleWidth,\r\n start,\r\n end,\r\n quote,\r\n numOfBarsToRender,\r\n chartModel: chartModel,\r\n })\r\n\r\n if (chartModel.zoomFactor !== zoomFactor || chartModel.leftOffset !== leftOffset) {\r\n chartModel.updateAttributes({ zoomFactor, leftOffset })\r\n }\r\n}\r\n\r\nexport function renderPane({\r\n chartLayoutModel,\r\n chartModel,\r\n paneModel,\r\n canvasCtx,\r\n shouldRenderCross = false,\r\n}: {\r\n chartLayoutModel: ChartLayout\r\n chartModel: Chart\r\n paneModel: Pane\r\n canvasCtx: CanvasRenderingContext2D\r\n shouldRenderCross?: boolean\r\n}) {\r\n if (paneModel.chart().instrument === Instrument.MarketSentiment) {\r\n canvasCtx.clearRect(0, 0, chartModel.width, paneModel.height)\r\n } else {\r\n canvasCtx.set('fillStyle', chartModel.getChartLayoutSettings().ChartSettings.general.Colors.canvasFill)\r\n canvasCtx.fillRect(0, 0, chartModel.width, paneModel.height)\r\n }\r\n const elements = paneModel.getAllElements()\r\n for (const { instance: elementInstance } of elements) {\r\n if (typeof elementInstance.renderGrid === 'function') {\r\n canvasCtx.save()\r\n elementInstance.renderGrid(canvasCtx)\r\n canvasCtx.restore()\r\n }\r\n }\r\n\r\n const chartEvents = paneModel.getAllChartEvents()\r\n const Settings = getSettings(paneModel)\r\n for (const { instance: elementInstance } of [...elements, ...chartEvents]) {\r\n const isDrawing = elementInstance.getIsDrawing()\r\n const isChartEvent = elementInstance.getIsChartEvent()\r\n\r\n if (isDrawing && (chartLayoutModel.isHideDrawingsActive || !elementInstance.getIsVisible())) {\r\n continue\r\n } else if ((isDrawing || isChartEvent) && !elementInstance.getIsInChartView(chartModel)) {\r\n continue\r\n }\r\n\r\n canvasCtx.save()\r\n if (elementInstance.renderContent != null) {\r\n canvasCtx.save()\r\n clip({\r\n canvasCtx,\r\n width: chartModel.width,\r\n height: paneModel.height,\r\n Settings,\r\n })\r\n canvasCtx.translate(paneModel.chart().leftOffset + Settings.left.width, Settings.top.height)\r\n elementInstance.renderContent(canvasCtx)\r\n canvasCtx.restore()\r\n if (typeof elementInstance.renderLabels === 'function') {\r\n elementInstance.renderLabels(canvasCtx)\r\n }\r\n } else {\r\n elementInstance.render(canvasCtx)\r\n }\r\n if (\r\n shouldRenderCross &&\r\n (chartLayoutModel.specificChartFunctionality === SpecificChartFunctionality.chartPage ||\r\n isRedesignedPage(chartLayoutModel)) &&\r\n elementInstance.renderCross != null\r\n ) {\r\n elementInstance.renderCross(canvasCtx)\r\n }\r\n canvasCtx.restore()\r\n }\r\n}\r\n","export const DEFAULT_WIDTHS = {\r\n min: 200,\r\n max: 400,\r\n}\r\n\r\nexport enum SidebarDirection {\r\n vertical,\r\n horizontal,\r\n}\r\n","import React from 'react'\r\n\r\nimport { DEFAULT_WIDTHS, SidebarDirection } from '../constants'\r\nimport { SidebarModule, SidebarModuleType } from '../modules/modules'\r\n\r\nexport type SidebarContextType = {\r\n isOpen: boolean\r\n isCloseVisible: boolean\r\n direction: SidebarDirection\r\n width?: {\r\n min?: number | string\r\n max?: number | string\r\n default?: { desktop?: number; mobile?: number }\r\n }\r\n activeModule: SidebarModuleType | null\r\n close: () => void\r\n onResize: () => void\r\n selectModule: (module?: SidebarModule) => void\r\n}\r\n\r\nconst DEFAULT_CONTEXT: SidebarContextType = {\r\n activeModule: null,\r\n isOpen: false,\r\n isCloseVisible: false,\r\n direction: SidebarDirection.horizontal,\r\n width: DEFAULT_WIDTHS,\r\n close: () => {},\r\n onResize: () => {},\r\n selectModule: () => {},\r\n}\r\n\r\nexport const SidebarContext = React.createContext(DEFAULT_CONTEXT)\r\nexport const useSidebarContext = () => React.useContext(SidebarContext)\r\n","import { DefaultErrorBoundary } from '@finviz/website'\r\nimport * as React from 'react'\r\nimport { FallbackProps } from 'react-error-boundary'\r\n\r\nexport function ModuleLoadFailed(props: Partial) {\r\n return (\r\n \r\n )\r\n}\r\n","export const portfolioWatchlistAsyncModule = {\r\n importFn: () => import(/* webpackChunkName: \"portfolio-watchlist\" */ './portfolio-watchlist'),\r\n cacheKey: 'portfolio-watchlist',\r\n}\r\n","import { IconNameType } from '@finviz/website'\r\nimport React from 'react'\r\n\r\nimport { portfolioWatchlistAsyncModule } from './portfolio-watchlist/async-modules'\r\nimport { withModuleAsyncLoad } from './with-module-async-load'\r\n\r\nexport enum SidebarModule {\r\n portfolio = 'portfolio',\r\n}\r\n\r\nexport type SidebarModuleType = {\r\n key: SidebarModule\r\n icon: IconNameType\r\n description: string\r\n content: React.ComponentType\r\n width?: {\r\n min?: number | string\r\n max?: number | string\r\n default?: { desktop?: number; mobile?: number }\r\n }\r\n}\r\n\r\nexport const sidebarModules: Record = Object.freeze({\r\n [SidebarModule.portfolio]: {\r\n key: SidebarModule.portfolio,\r\n icon: 'briefcase',\r\n description: 'Portfolio watchlist',\r\n content: withModuleAsyncLoad(portfolioWatchlistAsyncModule, true),\r\n width: { min: 200, default: { mobile: 275 } },\r\n },\r\n})\r\n","import { Delayed, Spinner } from '@finviz/website'\r\nimport React from 'react'\r\n\r\nimport { useAsyncModule } from '../../../utils/async-modules-utils'\r\nimport { ModuleLoadFailed } from './module-load-failed'\r\n\r\nexport function withModuleAsyncLoad<\r\n T extends { default: React.ComponentType<{ setIsComponentReady: React.Dispatch> }> },\r\n>(asyncModule: { importFn: () => Promise; cacheKey: string }, withInitialLoading = false) {\r\n return function InnerFunction() {\r\n const [isComponentReady, setIsComponentReady] = React.useState(false)\r\n const [sidebarModule, { isError }] = useAsyncModule({\r\n ...asyncModule,\r\n isSuspenseMode: true,\r\n })\r\n\r\n const SidebarModule = sidebarModule?.default\r\n\r\n if (isError) {\r\n return \r\n }\r\n\r\n return (\r\n <>\r\n {!isComponentReady && withInitialLoading && (\r\n \r\n
\r\n \r\n
\r\n
\r\n )}\r\n {!!SidebarModule && }\r\n \r\n )\r\n }\r\n}\r\n","import { Button, Icon, Paragraph, Tooltip, TooltipTrigger, useTooltipState } from '@finviz/website'\r\nimport classnames from 'classnames'\r\nimport React from 'react'\r\n\r\nimport { SidebarDirection } from './constants'\r\nimport { useSidebarContext } from './hooks/sidebar-context'\r\nimport { sidebarModules } from './modules/modules'\r\n\r\nexport const MOBILE_TOOLBAR_DIV_ID = 'toolbar-mobile'\r\n\r\ntype SidebarTabsProps = {\r\n className?: string\r\n}\r\n\r\nexport default function SidebarTabs({ className }: SidebarTabsProps) {\r\n const { isOpen, direction, activeModule, selectModule } = useSidebarContext()\r\n const tooltipState = useTooltipState({ placement: 'left', showTimeout: 300 })\r\n\r\n return (\r\n \r\n {/* reserved space for drawing button on mobile devices */}\r\n {direction === SidebarDirection.horizontal && (\r\n \r\n )}\r\n\r\n {Object.entries(sidebarModules).map(([key, value]) => {\r\n const isActive = activeModule?.key === key\r\n return (\r\n \r\n {\r\n selectModule(isActive ? undefined : value.key)\r\n }}\r\n className={classnames({ 'ml-2': direction === SidebarDirection.horizontal })}\r\n data-testid={`sidebar-${key}-btn`}\r\n >\r\n \r\n \r\n }\r\n state={tooltipState}\r\n aria-label={value.description}\r\n isHideOnClick\r\n />\r\n\r\n \r\n {value.description}\r\n \r\n \r\n )\r\n })}\r\n \r\n )\r\n}\r\n","import { Resizable } from 're-resizable'\r\nimport React from 'react'\r\n\r\nimport Utils from '../../utils'\r\nimport { DEFAULT_WIDTHS, SidebarDirection } from './constants'\r\nimport { useSidebarContext } from './hooks/sidebar-context'\r\n\r\ntype SidebarContentProps = {\r\n children: React.ReactNode\r\n}\r\n\r\nexport default function SidebarContent({ children }: SidebarContentProps) {\r\n const { direction, onResize, close, width } = useSidebarContext()\r\n const minWidth = width?.min ?? DEFAULT_WIDTHS.min\r\n const maxWidth = width?.max ?? DEFAULT_WIDTHS.max\r\n const defaultMobile = width?.default?.mobile ?? minWidth\r\n const defaultDesktop = width?.default?.desktop ?? maxWidth\r\n\r\n return (\r\n <>\r\n {direction === SidebarDirection.vertical && (\r\n \r\n {children}\r\n \r\n )}\r\n {direction === SidebarDirection.horizontal && (\r\n <>\r\n
\r\n
\r\n {children}\r\n
\r\n \r\n )}\r\n \r\n )\r\n}\r\n","import { Delayed, Spinner, localStorage } from '@finviz/website'\r\nimport * as React from 'react'\r\nimport { ErrorBoundary } from 'react-error-boundary'\r\nimport { useNavigate, useSearchParams } from 'react-router-dom'\r\n\r\nimport { getIsMobilePortrait } from '../../utils'\r\nimport { SidebarDirection } from './constants'\r\nimport { SidebarContext, SidebarContextType } from './hooks/sidebar-context'\r\nimport { ModuleLoadFailed } from './modules/module-load-failed'\r\nimport { SidebarModule, SidebarModuleType, sidebarModules } from './modules/modules'\r\nimport SidebarContent from './sidebar-content'\r\nimport SidebarTabs from './sidebar-tabs'\r\n\r\nexport const SIDEBAR_QUERY_PARAM = 'sidebar'\r\n\r\n// This is a temp function, to remove unused property from localstorage\r\nfunction removeSidebarFromLocalstorage() {\r\n const SIDEBAR_LOCAL_STORAGE_KEY = 'sidebarModule'\r\n localStorage.removeValue(SIDEBAR_LOCAL_STORAGE_KEY)\r\n}\r\nremoveSidebarFromLocalstorage()\r\n\r\ntype SidebarProps = {\r\n onShouldResize: () => void\r\n direction: SidebarDirection\r\n tabsClassName?: string\r\n}\r\n\r\n// Todo - this is not correct approach but this component can unmount/mount on mobile orientation change so we can't keep it inside the component\r\nlet isInit = false\r\n\r\nexport function Sidebar({ onShouldResize, direction, tabsClassName }: SidebarProps) {\r\n const navigate = useNavigate()\r\n const [urlSearchParams] = useSearchParams()\r\n const sidebarModuleKey = (urlSearchParams.get(SIDEBAR_QUERY_PARAM) as keyof typeof sidebarModules | null) || null\r\n const [activeModule, setActiveModule] = React.useState(null)\r\n\r\n const isOpen = !!activeModule\r\n const handleSelectModule = React.useCallback(\r\n (key?: SidebarModule) => {\r\n const newUrlSearchParams = new URLSearchParams(urlSearchParams)\r\n if (key) {\r\n newUrlSearchParams.set(SIDEBAR_QUERY_PARAM, key)\r\n } else {\r\n newUrlSearchParams.delete(SIDEBAR_QUERY_PARAM)\r\n }\r\n navigate({ search: newUrlSearchParams.toString() }, { replace: true })\r\n },\r\n [urlSearchParams, navigate]\r\n )\r\n\r\n const handleCloseSidebar = React.useCallback(() => {\r\n handleSelectModule(undefined)\r\n }, [handleSelectModule])\r\n\r\n // Resize charts every time the sidebar is opened/closed or active module is changed\r\n React.useEffect(() => {\r\n onShouldResize()\r\n }, [activeModule, onShouldResize])\r\n\r\n // Set active module based on sidebarModuleKey\r\n React.useEffect(() => {\r\n let sidebarModule = sidebarModuleKey && sidebarModules[sidebarModuleKey]\r\n\r\n if (!isInit && getIsMobilePortrait()) {\r\n sidebarModule = null\r\n handleCloseSidebar()\r\n }\r\n\r\n setActiveModule(sidebarModule)\r\n isInit = true\r\n }, [sidebarModuleKey, handleCloseSidebar])\r\n\r\n const contextValue: SidebarContextType = React.useMemo(\r\n () => ({\r\n direction,\r\n isOpen,\r\n isCloseVisible: direction === SidebarDirection.horizontal,\r\n width: activeModule?.width,\r\n activeModule,\r\n onResize: onShouldResize,\r\n close: handleCloseSidebar,\r\n selectModule: handleSelectModule,\r\n }),\r\n [direction, isOpen, onShouldResize, activeModule, handleCloseSidebar, handleSelectModule]\r\n )\r\n\r\n return (\r\n \r\n {activeModule && (\r\n \r\n \r\n \r\n
\r\n \r\n
\r\n \r\n }\r\n >\r\n \r\n \r\n
\r\n
\r\n )}\r\n \r\n
\r\n )\r\n}\r\n","import { IconNameType } from '@finviz/website'\r\n\r\nimport ChartLayout from '../../models/chart_layout'\r\n\r\nexport enum DrawingTool {\r\n Arrow = 'arrow',\r\n Brush = 'brush',\r\n Callout = 'callout',\r\n Curve = 'curve',\r\n ElliottWaves = 'elliott-wave',\r\n Ellipse = 'ellipse',\r\n FibonacciRetracements = 'fibonacci-retracements',\r\n HorizontalLine = 'horizontal-line',\r\n Measure = 'measure',\r\n Mouse = 'mouse',\r\n Pitchfork = 'pitchfork',\r\n Polygon = 'polygon',\r\n Position = 'position',\r\n Rectangle = 'rectangle',\r\n RotatedRectangle = 'rotated-rectangle',\r\n ScaledLine = 'scaled-line',\r\n ScaledText = 'scaled-text',\r\n Triangle = 'triangle',\r\n VerticalLine = 'vertical-line',\r\n Xabcd = 'xabcd',\r\n}\r\n\r\nexport enum DrawingActions {\r\n AddNote = 'add-note',\r\n DeleteDrawings = 'delete-drawings',\r\n DeleteAutoSavedDrawings = 'delete-autosaved-drawings',\r\n}\r\n\r\nexport enum DrawingSetting {\r\n PreserveDrawings = 'preserve-drawings',\r\n DrawingModeContinuous = 'drawing-mode-continuous',\r\n HideDrawings = 'hide-drawings',\r\n LockDrawings = 'lock-drawings',\r\n}\r\n\r\nexport interface IToolBarProps {\r\n chartLayoutModel: ChartLayout\r\n isSidebar?: boolean\r\n isHorizontal?: boolean\r\n isMobileOverlay?: boolean\r\n /**\r\n * Current selected tool id\r\n */\r\n activeTool: DrawingTool\r\n /**\r\n * On tool item select callback\r\n */\r\n onActiveToolChange: (activeTool: DrawingTool, trigger?: 'button' | 'select' | 'group') => void\r\n /**\r\n * On drawing actions item select callback\r\n */\r\n onDrawingActionClick?: (actionId: DrawingActions) => void\r\n /**\r\n * On drawing settings item select callback\r\n */\r\n onDrawingSettingClick?: (settingId: DrawingSetting) => void\r\n /**\r\n * On drawing end callback\r\n */\r\n onDrawingEnd?: () => void\r\n /**\r\n * Current state of drawing settings\r\n */\r\n drawingSettings: Record\r\n isAlternativeTheme?: boolean\r\n /**\r\n * Are tools disabled\r\n */\r\n areToolsDisabled?: boolean\r\n}\r\n\r\nexport interface IToolbarItemProperties {\r\n icon: IconNameType\r\n iconActive?: IconNameType\r\n iconAction?: IconNameType\r\n title: string\r\n titleActive?: string\r\n titleAction?: string\r\n}\r\n\r\nexport interface IToolbarDrawingTool extends IToolbarItemProperties {\r\n id: DrawingTool\r\n}\r\n\r\nexport interface IToolbarDrawingAction extends IToolbarItemProperties {\r\n id: DrawingActions\r\n}\r\n\r\nexport interface IToolbarDrawingSetting extends IToolbarItemProperties {\r\n id: DrawingSetting\r\n}\r\n\r\nexport interface IToolbarDrawingToolItem {\r\n defaultItem: IToolbarDrawingTool\r\n toolGroup?: Array\r\n toolGroupTitle?: string\r\n}\r\n\r\nexport interface IToolbarDrawingActionItem {\r\n defaultItem: IToolbarDrawingAction\r\n isDisabled?: boolean\r\n disabledTooltip?: string\r\n}\r\n\r\nexport interface IToolbarDrawingsSettingItem {\r\n defaultItem: IToolbarDrawingSetting\r\n isDisabled?: boolean\r\n isInAction?: boolean\r\n disabledTooltip?: string\r\n}\r\n","import { Instrument } from '../../types/shared'\r\nimport { ChartElementType } from '../constants/common'\r\nimport QuoteModel from '../models/quote'\r\n\r\nexport function getInstrumentLabel(instrument: Instrument) {\r\n switch (instrument) {\r\n case Instrument.Stock:\r\n return 'Stock'\r\n case Instrument.Futures:\r\n return 'Futures'\r\n case Instrument.Forex:\r\n return 'Forex'\r\n case Instrument.Crypto:\r\n return 'Crypto'\r\n case Instrument.MarketSentiment:\r\n return 'Market Sentiment'\r\n }\r\n}\r\n\r\nexport function getChartAlt(quoteModel: QuoteModel) {\r\n return `${quoteModel.name || quoteModel.ticker} - ${getInstrumentLabel(quoteModel.instrument)} Price Chart`\r\n}\r\n\r\nexport const getResponseChartType = (chartType: ChartElementType) => {\r\n switch (chartType) {\r\n case ChartElementType.HeikinAshi:\r\n return 'heikinashi'\r\n case ChartElementType.HollowCandleStick:\r\n return 'hollowcandlestick'\r\n case ChartElementType.LineChart:\r\n return 'line'\r\n case ChartElementType.OhlcChart:\r\n return 'ohlc'\r\n case ChartElementType.CandleStick:\r\n default:\r\n return 'candlestick'\r\n }\r\n}\r\n\r\nexport const getChartElementTypeFromResponseType = (chartResponseType: string | null) =>\r\n chartResponseType === null\r\n ? null\r\n : Object.values(ChartElementType).find(\r\n (chartType: ChartElementType) => chartResponseType === getResponseChartType(chartType)\r\n )\r\n","import utils from '../utils'\r\n\r\nclass AverageTrueRange {\r\n period: number\r\n sum: number\r\n count: number\r\n value: number\r\n\r\n constructor(period: number) {\r\n this.period = period\r\n this.sum = 0\r\n this.count = 0\r\n this.value = 0\r\n }\r\n\r\n add(high: number, low: number, prevClose: number) {\r\n const tr = utils.max([high - low, Math.abs(high - prevClose), Math.abs(low - prevClose)])\r\n\r\n if (this.count < this.period) {\r\n this.sum += tr\r\n this.value = this.sum / (this.count + 1)\r\n if (this.count === this.period - 1) {\r\n this.sum /= this.period\r\n }\r\n } else {\r\n this.value = (this.value * (this.period - 1) + tr) / this.period\r\n }\r\n this.count++\r\n }\r\n}\r\n\r\nexport default AverageTrueRange\r\n","import { PaneArea } from '../../types/shared'\r\nimport Element, { DefaultAttrs } from '../canvas/element'\r\nimport BaseChart from '../charts/base_chart'\r\nimport { ChartEventBadgeType, ChartEventType, TIMEFRAME } from '../constants/common'\r\nimport { getRoundedObject } from '../controllers/renderUtils'\r\nimport Chart from '../models/chart'\r\nimport ChartEventElement from '../models/chart-event-element'\r\nimport { CHART_EVENT_BADGE_SIZE } from '../models/constants'\r\nimport type PaneModel from '../models/pane'\r\nimport Utils from '../utils'\r\nimport { ChartEventBadgeState } from '../utils/chart-events-utils'\r\n\r\nconst isMobile = Utils.isMobile()\r\n\r\ninterface ChartEventAttrs extends DefaultAttrs {\r\n x: number\r\n}\r\n\r\nfunction getChartEventState(chartEvent: ChartEvent): ChartEventBadgeState {\r\n if (chartEvent.isOpen) {\r\n return ChartEventBadgeState.selected\r\n }\r\n if (chartEvent.isHovered) {\r\n return ChartEventBadgeState.hover\r\n }\r\n return ChartEventBadgeState.default\r\n}\r\n\r\nclass ChartEvent extends Element {\r\n static type = ChartEventType.ChartEvent\r\n static label = 'ChartEvent'\r\n\r\n declare scaled: Pick\r\n\r\n declare chart: BaseChart\r\n\r\n declare model: PaneModel\r\n\r\n declare chartEventModel: ChartEventElement | undefined\r\n\r\n isOpen = false\r\n\r\n left = 0\r\n top = 0\r\n\r\n constructor(values: Partial, model: PaneModel) {\r\n super(values, model)\r\n this.scale(this.getBoundingPointKeys())\r\n }\r\n\r\n getBoundingPointKeys = () => ({ x: ['x'], y: [] })\r\n\r\n get type() {\r\n return (this.constructor as typeof ChartEvent).type\r\n }\r\n\r\n get label() {\r\n return (this.constructor as typeof ChartEvent).label\r\n }\r\n\r\n getChartEvenBadgeType(): ChartEventBadgeType {\r\n switch (this.type) {\r\n case ChartEventType.Dividends:\r\n return ChartEventBadgeType.Dividends\r\n case ChartEventType.Split:\r\n return ChartEventBadgeType.Split\r\n }\r\n\r\n return ChartEventBadgeType.EarningsNeutral\r\n }\r\n\r\n getChartEventModel(): ChartEventElement | undefined {\r\n if (!this.chartEventModel) {\r\n this.chartEventModel = this.model.chartEvents()?.findByAttribute('instance', this)\r\n }\r\n\r\n return this.chartEventModel\r\n }\r\n\r\n getXYPosition() {\r\n const { top, bottom } = this.getChartLayoutSettings().ChartSettings\r\n const chartEventModel = this.getChartEventModel()\r\n const { x } = this.scaled\r\n const roundedXY = getRoundedObject({ x })\r\n const y =\r\n (this.model as PaneModel).height -\r\n top.height -\r\n bottom.height -\r\n CHART_EVENT_BADGE_SIZE -\r\n (chartEventModel?.yIndex ?? 0) * CHART_EVENT_BADGE_SIZE\r\n\r\n return { x: roundedXY.x - CHART_EVENT_BADGE_SIZE / 2, y }\r\n }\r\n\r\n getIsVisible() {\r\n return ![TIMEFRAME.w, TIMEFRAME.m].includes(this.model.chart().quote()?.timeframe)\r\n }\r\n\r\n renderContent(context: CanvasRenderingContext2D) {\r\n if (!this.getIsVisible() || !this.chartEventModel) return\r\n\r\n this.attrs.x = Math.round(this.attrs.x)\r\n const chart = this.model.chart()\r\n const chartLayout = chart.chart_layout()\r\n const { x, y } = this.getXYPosition()\r\n const buffer = 10 + CHART_EVENT_BADGE_SIZE\r\n if (x + chart.leftOffset < -buffer || x + chart.leftOffset > chart.width + buffer) {\r\n return\r\n }\r\n const item = this.chartEventModel.getChartEventBadgeImage({\r\n theme: chartLayout.theme,\r\n state: getChartEventState(this),\r\n badgeType: this.getChartEvenBadgeType(),\r\n })\r\n\r\n if (!item) return\r\n\r\n const { left, top } = this.getChartLayoutSettings().ChartSettings\r\n this.left = x + chart.leftOffset + left.width + CHART_EVENT_BADGE_SIZE / 2\r\n this.top = y + top.height\r\n context.drawImage(item, x, y, CHART_EVENT_BADGE_SIZE, CHART_EVENT_BADGE_SIZE)\r\n }\r\n\r\n setIsHovered(isHovered: boolean) {\r\n if (!this.getIsVisible()) return\r\n\r\n this.isHovered = isHovered\r\n this.model.updateChartEventsZIndexes()\r\n this.trigger('change')\r\n }\r\n\r\n // If isOpenOverride is undefined, the function works as toggle\r\n toggleIsOpen(isOpenOverride?: boolean) {\r\n const chartLayout = this.model.chart().chart_layout()\r\n const chartEventModel = this.getChartEventModel()\r\n\r\n const isCurrentEventActive = chartLayout.activeChartEvent?.elementId === chartEventModel?.elementId\r\n const isOpen = isOpenOverride ?? (isCurrentEventActive ? !chartEventModel?.instance.isOpen : true)\r\n this.isOpen = isOpen\r\n // Due to the fact that chart events logic depends heavily on hover state which isn't really present on touch devices\r\n // we need to mimic that state for touch devices, this enables chart event to be open, and counterpart in\r\n // chart-event-popover-with-state.tsx allow chart event to be closed on click outside\r\n if (isMobile) {\r\n this.isHovered = isOpen\r\n }\r\n if (chartLayout.activeChartEvent?.instance.isOpen && !isCurrentEventActive) {\r\n chartLayout.activeChartEvent?.instance.toggleIsOpen(false)\r\n }\r\n if (isOpen || isCurrentEventActive) {\r\n chartLayout.updateAttribute('activeChartEvent', !isOpen && isCurrentEventActive ? undefined : chartEventModel)\r\n }\r\n\r\n this.model.updateChartEventsZIndexes()\r\n this.trigger('change')\r\n }\r\n\r\n isInArea(area: PaneArea) {\r\n if (!this.getIsVisible()) return false\r\n\r\n const scaledArea = area.scaled\r\n const { x, y } = this.getXYPosition()\r\n const isInArea =\r\n x <= scaledArea.x &&\r\n x + CHART_EVENT_BADGE_SIZE >= scaledArea.x &&\r\n y <= scaledArea.y &&\r\n y + CHART_EVENT_BADGE_SIZE >= scaledArea.y\r\n return isInArea\r\n }\r\n\r\n getIsInChartView(chart: Chart) {\r\n if (!this.getIsVisible()) return false\r\n\r\n const { x } = this.getXYPosition()\r\n const isInView = x + CHART_EVENT_BADGE_SIZE >= -chart.leftOffset && x <= -chart.leftOffset + chart.width\r\n return isInView\r\n }\r\n}\r\n\r\nexport default ChartEvent\r\n","import { ChartEventLabels, ChartEventType } from '../constants/common'\r\nimport ChartEvent from './chart-event'\r\n\r\nclass Dividends extends ChartEvent {\r\n static type = ChartEventType.Dividends\r\n static label = ChartEventLabels[ChartEventType.Dividends]\r\n}\r\n\r\nexport default Dividends\r\n","import { ChartEventBadgeType, ChartEventLabels, ChartEventType } from '../constants/common'\r\nimport { IEarnings } from '../utils/chart-events-utils'\r\nimport ChartEvent from './chart-event'\r\n\r\nclass Earnings extends ChartEvent {\r\n static type = ChartEventType.Earnings\r\n static label = ChartEventLabels[ChartEventType.Earnings]\r\n\r\n getChartEvenBadgeType(): ChartEventBadgeType {\r\n const eventItem = this.getChartEventModel()?.getChartEventData() as IEarnings | undefined\r\n\r\n if (!eventItem) {\r\n return ChartEventBadgeType.EarningsNeutral\r\n }\r\n\r\n if (eventItem.epsActual === undefined || eventItem.epsEstimate === undefined) {\r\n const now = Date.now() / 1000\r\n return eventItem.dateTimestamp > now ? ChartEventBadgeType.EarningsFuture : ChartEventBadgeType.EarningsNeutral\r\n }\r\n return eventItem.epsActual - eventItem.epsEstimate < 0\r\n ? ChartEventBadgeType.EarningsNegative\r\n : ChartEventBadgeType.EarningsPositive\r\n }\r\n}\r\n\r\nexport default Earnings\r\n","import { ChartEventLabels, ChartEventType } from '../constants/common'\r\nimport ChartEvent from './chart-event'\r\n\r\nclass Split extends ChartEvent {\r\n static type = ChartEventType.Split\r\n static label = ChartEventLabels[ChartEventType.Split]\r\n}\r\n\r\nexport default Split\r\n","import { ChartEventType } from '../constants/common'\r\nimport chartEvent from './chart-event'\r\nimport dividends from './dividends'\r\nimport earnings from './earnings'\r\nimport split from './split'\r\n\r\nexport const chartEventsByType = Object.freeze({\r\n [ChartEventType.ChartEvent]: chartEvent,\r\n [ChartEventType.Dividends]: dividends,\r\n [ChartEventType.Split]: split,\r\n [ChartEventType.Earnings]: earnings,\r\n})\r\n","import { ChartConfigChartPaneElement } from '../../types/shared'\r\nimport { drawingToolsByType } from '../canvas/drawingTools'\r\nimport { chartEventsByType } from '../chart-events'\r\nimport { chartsByType } from '../charts/charts'\r\nimport { indicatorsByType } from '../indicators/indicators'\r\nimport { overlaysByType } from '../overlays/overlays'\r\n\r\nconst canvasElements = {\r\n ...overlaysByType,\r\n ...indicatorsByType,\r\n ...drawingToolsByType,\r\n ...chartsByType,\r\n ...chartEventsByType,\r\n}\r\n\r\nexport function getCanvasElementByType(elementType: ChartConfigChartPaneElement['type']) {\r\n return canvasElements[elementType]\r\n}\r\n","import { Instrument, Point } from '../../types/shared'\r\n\r\ninterface LinePoints {\r\n x1: number\r\n x2: number\r\n y1: number\r\n y2: number\r\n}\r\n\r\nexport enum BigNumber {\r\n Thousand,\r\n Million,\r\n Billion,\r\n Trillion,\r\n}\r\n\r\nexport const BIG_NUMBER_VALUES = {\r\n [BigNumber.Thousand]: 1e3,\r\n [BigNumber.Million]: 1e6,\r\n [BigNumber.Billion]: 1e9,\r\n [BigNumber.Trillion]: 1e12,\r\n}\r\n\r\nconst BIG_NUMBER_ZEROES = {\r\n [BigNumber.Thousand]: 3,\r\n [BigNumber.Million]: 6,\r\n [BigNumber.Billion]: 9,\r\n [BigNumber.Trillion]: 12,\r\n}\r\n\r\nconst BIG_NUMBER_SUFFIX = {\r\n [BigNumber.Thousand]: 'K',\r\n [BigNumber.Million]: 'M',\r\n [BigNumber.Billion]: 'B',\r\n [BigNumber.Trillion]: 'T',\r\n}\r\n\r\nconst math = {\r\n dotProduct(p1: Point, p2: Point) {\r\n return p1.x * p2.x + p1.y * p2.y\r\n },\r\n\r\n crossProduct(p1: Point, p2: Point) {\r\n return p1.x * p2.y - p1.y * p2.x\r\n },\r\n\r\n distance(p1: Point, p2: Point) {\r\n return Math.sqrt(Math.pow(p1.x - p2.x, 2) + Math.pow(p1.y - p2.y, 2))\r\n },\r\n\r\n lineEquation(line: LinePoints) {\r\n // ax + by + c = 0\r\n if (line.x1 === line.x2) {\r\n return {\r\n a: 1,\r\n b: 0,\r\n c: -line.x1,\r\n }\r\n }\r\n const k = (line.y2 - line.y1) / (line.x2 - line.x1)\r\n return {\r\n a: -k,\r\n b: 1,\r\n c: k * line.x1 - line.y1,\r\n k,\r\n }\r\n },\r\n\r\n pointInPolygon(point: Point, polygon: Point[]) {\r\n // http://alienryderflex.com/polygon/\r\n let j = polygon.length - 1\r\n let oddNodes = false\r\n for (let i = 0; i < polygon.length; i++) {\r\n const p = polygon[i]\r\n if (\r\n ((p.y < point.y && polygon[j].y >= point.y) || (polygon[j].y < point.y && p.y >= point.y)) &&\r\n (p.x <= point.x || polygon[j].x <= point.x)\r\n ) {\r\n if (p.x + ((point.y - p.y) / (polygon[j].y - p.y)) * (polygon[j].x - p.x) < point.x) {\r\n oddNodes = !oddNodes\r\n }\r\n }\r\n j = i\r\n }\r\n return oddNodes\r\n },\r\n\r\n distanceToLine(point: Point, line: LinePoints) {\r\n const { a, b, c } = this.lineEquation(line)\r\n const dist = Math.abs(a * point.x + b * point.y + c) / Math.sqrt(a * a + b * b)\r\n return dist\r\n },\r\n\r\n distanceToSegment(point: Point, line: LinePoints) {\r\n const l2 = Math.pow(line.x1 - line.x2, 2) + Math.pow(line.y1 - line.y2, 2)\r\n if (l2 === 0) {\r\n return Math.sqrt(Math.pow(point.x - line.x1, 2) + Math.pow(point.y - line.y1, 2))\r\n }\r\n const t = ((point.x - line.x1) * (line.x2 - line.x1) + (point.y - line.y1) * (line.y2 - line.y1)) / l2\r\n if (t < 0) {\r\n return Math.sqrt(Math.pow(point.x - line.x1, 2) + Math.pow(point.y - line.y1, 2))\r\n }\r\n if (t > 1) {\r\n return Math.sqrt(Math.pow(point.x - line.x2, 2) + Math.pow(point.y - line.y2, 2))\r\n }\r\n const x = line.x1 + t * (line.x2 - line.x1)\r\n const y = line.y1 + t * (line.y2 - line.y1)\r\n return Math.sqrt(Math.pow(point.x - x, 2) + Math.pow(point.y - y, 2))\r\n },\r\n\r\n getInstrumentDecimalPlaces({ value, instrument }: { value: number; instrument?: Instrument }) {\r\n if (instrument === Instrument.Crypto && value <= 0.001) {\r\n return 8\r\n }\r\n\r\n if ((instrument !== Instrument.Stock && value <= 6) || (instrument === Instrument.Stock && value < 1)) {\r\n return 4\r\n }\r\n\r\n return 2\r\n },\r\n\r\n formatBigNumber(number: number, toFixed?: number, minNumber?: BigNumber) {\r\n const absNum = Math.abs(number)\r\n const getString = ({ num, suffix, zeroes }: { num: number; suffix: string; zeroes: number }) => {\r\n const str = num.toString()\r\n if (str.includes('e')) {\r\n const splitString = str.split('e')\r\n const addZeroes = Number(splitString[1]) - zeroes\r\n return Math.round(Number(splitString[0])).toString().padEnd(Math.max(0, addZeroes), '0') + suffix\r\n }\r\n const sign = Math.sign(num)\r\n const numberByZeroesCount = Math.pow(10, zeroes)\r\n const result = (absNum / numberByZeroesCount) * sign\r\n return (Number.isInteger(result) ? result : result.toFixed(toFixed !== undefined ? toFixed : 1)) + suffix\r\n }\r\n\r\n if (absNum >= BIG_NUMBER_VALUES[BigNumber.Trillion] || minNumber === BigNumber.Trillion) {\r\n return getString({\r\n num: number,\r\n suffix: BIG_NUMBER_SUFFIX[BigNumber.Trillion],\r\n zeroes: BIG_NUMBER_ZEROES[BigNumber.Trillion],\r\n })\r\n } else if (absNum >= BIG_NUMBER_VALUES[BigNumber.Billion] || minNumber === BigNumber.Billion) {\r\n return getString({\r\n num: number,\r\n suffix: BIG_NUMBER_SUFFIX[BigNumber.Billion],\r\n zeroes: BIG_NUMBER_ZEROES[BigNumber.Billion],\r\n })\r\n } else if (absNum >= BIG_NUMBER_VALUES[BigNumber.Million] || minNumber === BigNumber.Million) {\r\n return getString({\r\n num: number,\r\n suffix: BIG_NUMBER_SUFFIX[BigNumber.Million],\r\n zeroes: BIG_NUMBER_ZEROES[BigNumber.Million],\r\n })\r\n } else if (absNum >= BIG_NUMBER_VALUES[BigNumber.Thousand] || minNumber === BigNumber.Thousand) {\r\n return getString({\r\n num: number,\r\n suffix: BIG_NUMBER_SUFFIX[BigNumber.Thousand],\r\n zeroes: BIG_NUMBER_ZEROES[BigNumber.Thousand],\r\n })\r\n } else {\r\n return toFixed !== undefined ? number.toFixed(toFixed) : number.toString()\r\n }\r\n },\r\n\r\n round({\r\n value,\r\n lastClose = 0,\r\n instrument,\r\n overridePlaces,\r\n }: {\r\n value: number\r\n lastClose?: number\r\n instrument?: Instrument\r\n overridePlaces?: number\r\n }) {\r\n if (Math.abs(value) >= BIG_NUMBER_VALUES[BigNumber.Million]) {\r\n return this.formatBigNumber(value, overridePlaces)\r\n }\r\n\r\n const places =\r\n typeof overridePlaces === 'number'\r\n ? overridePlaces\r\n : this.getInstrumentDecimalPlaces({ value: lastClose, instrument })\r\n\r\n if (value < 0.000001) {\r\n // There was an issue with getting NaN when rounding small numbers with latter method\r\n return value.toFixed(places)\r\n }\r\n return Number(`${Math.round(Number(`${value}e+${places}`))}e-${places}`).toFixed(places)\r\n },\r\n\r\n perpendicularPointToLine({ line, distance }: { line: LinePoints; distance: number }) {\r\n if (distance === 0) {\r\n return { x: line.x2, y: line.y2 }\r\n }\r\n\r\n let yAxisCoeficient\r\n let xAxisCoeficient\r\n\r\n if (line.x1 <= line.x2 && line.y1 >= line.y2) {\r\n xAxisCoeficient = -1\r\n yAxisCoeficient = -1\r\n } else if (line.x1 <= line.x2 && line.y1 <= line.y2) {\r\n xAxisCoeficient = 1\r\n yAxisCoeficient = -1\r\n } else if (line.x1 >= line.x2 && line.y1 >= line.y2) {\r\n xAxisCoeficient = -1\r\n yAxisCoeficient = 1\r\n } else {\r\n // conditions falling to else: (line.x1 >= line.x2 && line.y1 <= line.y2)\r\n xAxisCoeficient = 1\r\n yAxisCoeficient = 1\r\n }\r\n\r\n const radAngle = Math.atan2(Math.abs(line.x2 - line.x1), Math.abs(line.y2 - line.y1))\r\n const x = line.x2 + xAxisCoeficient * (distance * Math.cos(radAngle))\r\n const y = line.y2 + yAxisCoeficient * (distance * Math.sin(radAngle))\r\n return { x, y }\r\n },\r\n\r\n rotatedPointCoordinates({\r\n rotationAxisPoint,\r\n angle,\r\n pointToRotate,\r\n }: {\r\n rotationAxisPoint: Point\r\n angle: number\r\n pointToRotate: Point\r\n }) {\r\n // return newCoordinates for pointToRotate after rotation defined by\r\n // angle around rotationAxisPoint\r\n const sin = Math.sin(angle)\r\n const cos = Math.cos(angle)\r\n const rotatedX =\r\n cos * (pointToRotate.x - rotationAxisPoint.x) +\r\n sin * (pointToRotate.y - rotationAxisPoint.y) +\r\n rotationAxisPoint.x\r\n const rotatedY =\r\n cos * (pointToRotate.y - rotationAxisPoint.y) -\r\n sin * (pointToRotate.x - rotationAxisPoint.x) +\r\n rotationAxisPoint.y\r\n return { x: rotatedX, y: rotatedY }\r\n },\r\n sharedPointLinesAngle({\r\n sharedPoint,\r\n oldLinePoint,\r\n newLinePoint,\r\n }: {\r\n sharedPoint: Point\r\n oldLinePoint: Point\r\n newLinePoint: Point\r\n }) {\r\n // return angle between line from sharedPoint to oldLinePoint and\r\n // line from sharedPoint to newLinePoint\r\n const numerator =\r\n oldLinePoint.y * (sharedPoint.x - newLinePoint.x) +\r\n sharedPoint.y * (newLinePoint.x - oldLinePoint.x) +\r\n newLinePoint.y * (oldLinePoint.x - sharedPoint.x)\r\n const denominator =\r\n (oldLinePoint.x - sharedPoint.x) * (sharedPoint.x - newLinePoint.x) +\r\n (oldLinePoint.y - sharedPoint.y) * (sharedPoint.y - newLinePoint.y)\r\n const ratio = numerator / denominator\r\n\r\n return Math.atan(ratio)\r\n },\r\n\r\n twoSegmentLinesIntersection(p1: Point, p2: Point, p3: Point, p4: Point) {\r\n // line intercept math by Paul Bourke http://paulbourke.net/geometry/pointlineplane/\r\n // Determine the intersection point of two line segments\r\n // Return FALSE if the lines don't intersect\r\n\r\n // Check if none of the lines are of length 0\r\n if ((p1.x === p2.x && p1.y === p2.y) || (p3.x === p4.x && p3.y === p4.y)) {\r\n return false\r\n }\r\n\r\n const denominator = (p4.y - p3.y) * (p2.x - p1.x) - (p4.x - p3.x) * (p2.y - p1.y)\r\n\r\n // Lines are parallel\r\n if (denominator === 0) {\r\n return false\r\n }\r\n\r\n const ua = ((p4.x - p3.x) * (p1.y - p3.y) - (p4.y - p3.y) * (p1.x - p3.x)) / denominator\r\n const ub = ((p2.x - p1.x) * (p1.y - p3.y) - (p2.y - p1.y) * (p1.x - p3.x)) / denominator\r\n\r\n // is the intersection along the segments\r\n if (ua < 0 || ua > 1 || ub < 0 || ub > 1) {\r\n return false\r\n }\r\n\r\n // Return a object with the x and y coordinates of the intersection\r\n const x = p1.x + ua * (p2.x - p1.x)\r\n const y = p1.y + ua * (p2.y - p1.y)\r\n\r\n return { x, y }\r\n },\r\n\r\n // https://stackoverflow.com/a/60368757\r\n checkLineIntersection(line1_p1: Point, line1_p2: Point, line2_p1: Point, line2_p2: Point) {\r\n // if the lines intersect, the result contains the x and y of the intersection (treating the lines as infinite) and booleans for whether line segment 1 or line segment 2 contain the point\r\n let a, b\r\n const result: { x: number; y: number; onLine1: boolean; onLine2: boolean } = {\r\n x: 0,\r\n y: 0,\r\n onLine1: false,\r\n onLine2: false,\r\n }\r\n const denominator =\r\n (line2_p2.y - line2_p1.y) * (line1_p2.x - line1_p1.x) - (line2_p2.x - line2_p1.x) * (line1_p2.y - line1_p1.y)\r\n if (denominator === 0) {\r\n return false\r\n }\r\n\r\n a = line1_p1.y - line2_p1.y\r\n b = line1_p1.x - line2_p1.x\r\n const numerator1 = (line2_p2.x - line2_p1.x) * a - (line2_p2.y - line2_p1.y) * b\r\n const numerator2 = (line1_p2.x - line1_p1.x) * a - (line1_p2.y - line1_p1.y) * b\r\n a = numerator1 / denominator\r\n b = numerator2 / denominator\r\n\r\n // if we cast these lines infinitely in both directions, they intersect here:\r\n result.x = line1_p1.x + a * (line1_p2.x - line1_p1.x)\r\n result.y = line1_p1.y + a * (line1_p2.y - line1_p1.y)\r\n\r\n // if line1 is a segment and line2 is infinite, they intersect if:\r\n if (a > 0 && a < 1) {\r\n result.onLine1 = true\r\n }\r\n // if line2 is a segment and line1 is infinite, they intersect if:\r\n if (b > 0 && b < 1) {\r\n result.onLine2 = true\r\n }\r\n // if line1 and line2 are segments, they intersect if both of the above are true\r\n return result\r\n },\r\n\r\n // ray is considered line1, segment is considered line2\r\n getRayToLineSegmentIntersection(rayOrigin: Point, rayEnd: Point, segmentStart: Point, segmentEnd: Point) {\r\n const lineIntersection = this.checkLineIntersection(rayOrigin, rayEnd, segmentStart, segmentEnd)\r\n\r\n if (\r\n !lineIntersection ||\r\n lineIntersection.onLine1 ||\r\n this.dotProduct(\r\n this.subtractPoints(rayOrigin, lineIntersection as Point),\r\n this.subtractPoints(rayOrigin, rayEnd)\r\n ) <= 0\r\n )\r\n return false\r\n return { ...lineIntersection, x: Math.round(lineIntersection.x), y: Math.round(lineIntersection.y) } // sometimes edge value can have crazy precision instead of `0` something like `5.684341886080802e-14` which is basically 0.00000000000005684341886080802 we should round it\r\n },\r\n\r\n getMiddlePointOnLineSegment(P1: Point, P2: Point) {\r\n const x = (P1.x - P2.x) / 2 + P2.x\r\n const y = (P1.y - P2.y) / 2 + P2.y\r\n return { x, y }\r\n },\r\n\r\n normalizeVector(v: Point) {\r\n const length = Math.sqrt(v.x * v.x + v.y * v.y)\r\n return { x: v.x / length, y: v.y / length }\r\n },\r\n\r\n multiplyVectorByScalar(v: Point, scalar: number) {\r\n return { x: v.x * scalar, y: v.y * scalar }\r\n },\r\n\r\n addPoints(P1: Point, P2: Point) {\r\n return { x: P1.x + P2.x, y: P1.y + P2.y }\r\n },\r\n\r\n subtractPoints(P1: Point, P2: Point): Point {\r\n return { x: P1.x - P2.x, y: P1.y - P2.y }\r\n },\r\n\r\n isSamePoint(P1: Point, P2: Point, margin = { x: 0, y: 0 }) {\r\n return P1.x - margin.x <= P2.x && P2.x <= P1.x + margin.x && P1.y - margin.y <= P2.y && P2.y <= P1.y + margin.y\r\n },\r\n}\r\n\r\nexport default math\r\n","import { EMAConfig, Options } from '../overlays/configs/ema'\r\nimport { MainCalculation, OnValueCalculated } from './main'\r\n\r\nexport class ExponentialMovingAverage {\r\n period: number\r\n multiplier: number\r\n sum: number\r\n count: number\r\n value: number\r\n\r\n constructor(period: number) {\r\n this.period = period\r\n this.multiplier = 2 / (this.period + 1)\r\n this.sum = 0\r\n this.count = 0\r\n this.value = 0\r\n }\r\n\r\n add(d: number) {\r\n if (this.count < this.period) {\r\n this.sum += d\r\n this.count++\r\n this.value = this.sum / this.count\r\n } else {\r\n this.value = d * this.multiplier + this.value * (1 - this.multiplier)\r\n }\r\n }\r\n}\r\n\r\ntype DefaultCalculatedValuesType = {\r\n ema: number[]\r\n}\r\n\r\nexport class EMACalculation extends MainCalculation {\r\n static config = EMAConfig\r\n\r\n calculate(onValueCalculated?: OnValueCalculated) {\r\n const { period } = this.options\r\n const { close } = this.quote\r\n const lastIndex = close.length - 1\r\n const ema = new ExponentialMovingAverage(period)\r\n this._calculatedValues = this.getDefaultCalculatedValues()\r\n\r\n for (let index = 0; index <= lastIndex; index++) {\r\n ema.add(close[index])\r\n this.calculatedValues.ema[index] = ema.value\r\n\r\n if (onValueCalculated?.(this.calculatedValues, index) === false) {\r\n break\r\n }\r\n }\r\n }\r\n}\r\n","import { ObjectHash } from '../../types/shared'\r\nimport IndicatorBaseConfig from '../indicators/configs/indicatorBaseConfig'\r\nimport Quote from '../models/quote'\r\nimport OverlayBaseConfig from '../overlays/configs/overlayBaseConfig'\r\n\r\ntype OptionValuesType = ObjectHash\r\ntype CalculatedValuesType = ObjectHash\r\ninterface MainProps {\r\n quote?: Quote\r\n options: T\r\n}\r\n\r\nexport type OnValueCalculatedReturnValue = boolean | undefined\r\nexport type OnValueCalculated = ((value: T, dataIndex: number) => OnValueCalculatedReturnValue) | undefined\r\n\r\nexport class MainCalculation<\r\n TOptionValues extends OptionValuesType | undefined = undefined,\r\n TCalculatedValues extends CalculatedValuesType = CalculatedValuesType,\r\n> {\r\n declare static config: OverlayBaseConfig | IndicatorBaseConfig\r\n\r\n quote: NonNullable['quote']>\r\n options: MainProps['options']\r\n\r\n protected declare _calculatedValues: TCalculatedValues\r\n\r\n constructor({ quote, options }: MainProps) {\r\n this.quote = quote ?? new Quote()\r\n this.options = options\r\n }\r\n\r\n get calculatedValues() {\r\n return this._calculatedValues ?? this.getDefaultCalculatedValues()\r\n }\r\n\r\n get config() {\r\n return (this.constructor as typeof MainCalculation).config\r\n }\r\n\r\n getDefaultCalculatedValues(): TCalculatedValues {\r\n const defaultCalculatedValues = this.config.getDefaultCalculatedValues() as TCalculatedValues\r\n if (Object.keys(defaultCalculatedValues).length === 0) {\r\n throw Error('Add calculatedValues to indicator config')\r\n }\r\n return defaultCalculatedValues\r\n }\r\n\r\n calculate(_: OnValueCalculated) {\r\n throw Error('Implement calculate')\r\n }\r\n\r\n getAllCalculatedValues(lastNItems: number) {\r\n const calculatedValues = {} as TCalculatedValues\r\n Object.keys(this.calculatedValues).forEach((key) => {\r\n calculatedValues[key as keyof TCalculatedValues] = this.getCalculatedValues(key, lastNItems)\r\n })\r\n return calculatedValues\r\n }\r\n\r\n getCalculatedValues(key: keyof TCalculatedValues, lastNItems: number) {\r\n return (this.calculatedValues[key] as number[]).slice(-lastNItems) as TCalculatedValues[keyof TCalculatedValues]\r\n }\r\n\r\n /**\r\n * This function is used to construct sql script for db table creation\r\n * and also to build precalculated data object used on node server.\r\n *\r\n * Precalculated data object uses database column names as property keys to simplify data mapping on BE\r\n */\r\n getDbColumnName() {\r\n const colName = this.config.abbreviation\r\n const optionKeys = this.config.optionsOrder\r\n\r\n const optionsStrings = optionKeys.map((key) => `${key.slice(0, 1)}${this.options![key]}`)\r\n return [colName, ...optionsStrings].join('_')\r\n }\r\n}\r\n","import { ObjectHash } from '../../../types/shared'\r\nimport ElementBaseConfig from '../../canvas/ElementBaseConfig'\r\nimport { IndicatorType, QuoteFinancialAttachment } from '../../constants/common'\r\n\r\nexport default class IndicatorBaseConfig extends ElementBaseConfig {\r\n static type = IndicatorType.Indicator\r\n static abbreviation = 'ind'\r\n static label = 'Indicator'\r\n static shortLabel = 'Indicator'\r\n static optionsOrder = [] as readonly string[]\r\n static optionsLabels = {}\r\n static inputsOrder = [] as readonly string[]\r\n static inputsLabels = {}\r\n static calculatedValuesOrder = [] as readonly string[]\r\n static calculatedValuesLabels = {}\r\n static defaultCalculatedValueOption = undefined as undefined | string\r\n static quoteFinancialAttachments: QuoteFinancialAttachment[] = []\r\n\r\n static getShortLabelWithAttrs(attrs: ObjectHash) {\r\n return [this.shortLabel, this.optionsOrder.map((item) => attrs[item]).join(',')].filter((item) => !!item).join(' ')\r\n }\r\n\r\n get getShortLabelWithAttrs() {\r\n return (this.constructor as typeof IndicatorBaseConfig).getShortLabelWithAttrs\r\n }\r\n\r\n static getDefaultCalculatedValues() {\r\n return this.calculatedValuesOrder.reduce((prev, curr) => ({ ...prev, [curr]: [] }), {})\r\n }\r\n\r\n get getDefaultCalculatedValues() {\r\n return (this.constructor as typeof IndicatorBaseConfig).getDefaultCalculatedValues\r\n }\r\n}\r\n","import { IndicatorType } from '../../constants/common'\r\nimport IndicatorBaseConfig from './indicatorBaseConfig'\r\n\r\nexport type Options = {\r\n period: number\r\n}\r\n\r\nexport type Attrs = Options\r\n\r\nexport class ADXConfig extends IndicatorBaseConfig {\r\n static type = IndicatorType.Adx\r\n static abbreviation = 'adx'\r\n static label = 'ADX'\r\n static shortLabel = 'ADX'\r\n static optionsOrder = ['period'] as const\r\n static optionsLabels = { period: 'Period' }\r\n static inputsOrder = this.optionsOrder\r\n static inputsLabels = this.optionsLabels\r\n}\r\n","import Spine from '@finviz/spine'\r\nimport merge from 'lodash.merge'\r\n\r\nimport {\r\n ChartConfigChartPaneElement,\r\n CustomSpineEvents,\r\n IModalConfig,\r\n IModalConfigInput,\r\n ObjectHash,\r\n PaneArea,\r\n RequireByKey,\r\n Theme,\r\n} from '../../types/shared'\r\nimport Line from '../canvas/line'\r\nimport Text, { ITextAttrs } from '../canvas/text'\r\nimport tailwindColors from '../constants/colors'\r\nimport {\r\n FONT_SIZE,\r\n INDICATOR_LABEL_HEIGHT,\r\n IndicatorType,\r\n OFFSET,\r\n PADDING,\r\n SpecificChartFunctionality,\r\n TextAlign,\r\n TextBaseline,\r\n} from '../constants/common'\r\nimport { getTranslate } from '../controllers/renderUtils'\r\nimport math from '../helpers/math'\r\nimport Chart from '../models/chart'\r\nimport { ISettings } from '../models/chart_settings/interfaces'\r\nimport mouseModel from '../models/mouse'\r\nimport Pane from '../models/pane'\r\nimport Quote from '../models/quote'\r\nimport { getChartLayoutSettings } from '../models/settings'\r\nimport { isRedesignEnabled } from '../utils'\r\nimport { roundedRect } from '../utils/canvas-render'\r\nimport { renderCross } from '../utils/chart'\r\nimport { getHEXWithSpecificAplha } from '../utils/colors'\r\nimport {\r\n drawInVisibleArea,\r\n getAreNoBarsVisible,\r\n getCompensatedFirstBarToRenderIndex,\r\n getVisibleBarToRenderIndex,\r\n} from '../utils/draw_in_visible_area'\r\nimport { getIsSSr, getParsedIntegersFromPeriodString, isInRange, isPositiveInteger } from '../utils/helpers'\r\nimport IndicatorBaseConfig from './configs/indicatorBaseConfig'\r\n\r\nconst MAX_POSITIVE_DEFAULT_VALUE = Number.MAX_VALUE\r\nconst MAX_NEGATIVE_DEFAULT_VALUE = -Number.MAX_VALUE\r\n\r\nconst INDICATOR_DEFAULT_DOMAIN = (indicator: IndicatorType) => {\r\n switch (indicator) {\r\n case IndicatorType.Rvol:\r\n return { min: 0, max: 2 }\r\n case IndicatorType.Atr:\r\n return { min: 0, max: 10 }\r\n case IndicatorType.Adx:\r\n case IndicatorType.Aro:\r\n case IndicatorType.Mfi:\r\n case IndicatorType.Perf:\r\n case IndicatorType.Rmi:\r\n case IndicatorType.Rsi:\r\n case IndicatorType.Stofu:\r\n case IndicatorType.Ult:\r\n return { min: 0, max: 100 }\r\n case IndicatorType.Macd:\r\n case IndicatorType.Rwi:\r\n case IndicatorType.Trix:\r\n return { min: -1, max: 1 }\r\n case IndicatorType.Wr:\r\n return { min: -100, max: 0 }\r\n case IndicatorType.Aroosc:\r\n case IndicatorType.Roc:\r\n return { min: -100, max: 100 }\r\n case IndicatorType.Cci:\r\n case IndicatorType.Fi:\r\n return { min: -200, max: 200 }\r\n case IndicatorType.Shrtfl:\r\n case IndicatorType.Shrtra:\r\n return { min: 0, max: 1 }\r\n default:\r\n return { min: 0, max: 100 }\r\n }\r\n}\r\n\r\nexport interface IIndicatorIsValid {\r\n getIsValid(key: string): boolean | void\r\n}\r\n\r\nclass Indicator extends Spine.Module implements IIndicatorIsValid {\r\n static config = IndicatorBaseConfig\r\n\r\n static initClass() {\r\n Object.defineProperty(this.prototype, 'height', {\r\n get() {\r\n return this.model.height\r\n },\r\n })\r\n Object.defineProperty(this.prototype, 'contentHeight', {\r\n get() {\r\n const { IndicatorSettings } = this.getChartLayoutSettings() as ISettings\r\n return this.height - IndicatorSettings.top.height - IndicatorSettings.bottom.height\r\n },\r\n })\r\n }\r\n\r\n static fromObject(values: ObjectHash, model: Pane) {\r\n const indicator = new this(values, model)\r\n indicator.set(values)\r\n return indicator\r\n }\r\n\r\n static getNumOfBarsBuffer({ period }: RequireByKey) {\r\n const [periodInt = 0] = getParsedIntegersFromPeriodString(period)\r\n return periodInt\r\n }\r\n\r\n declare data: Quote\r\n declare min: number\r\n declare max: number\r\n declare contentHeight: number\r\n declare height: number\r\n\r\n attrs: Attrs\r\n model: Pane\r\n labelWidth = 0\r\n fetchedAt = -1\r\n leftOffset = 0\r\n width = 0\r\n contentWidth = 0\r\n lastValue: number | null = null\r\n shouldUpdate = true\r\n tickers: string | null = null\r\n period?: string | number\r\n\r\n // Used to calculate yAxis min/max values if min === max, and we don't want to use domain defaults\r\n applyMinMaxPadding = false\r\n\r\n constructor(attrs: Attrs, model: Pane) {\r\n super(attrs, model)\r\n this.attrs = attrs\r\n this.model = model\r\n this.data = this.model.chart().quote()\r\n\r\n this.renderYAxis = this.renderYAxis.bind(this)\r\n this.renderCrossText = this.renderCrossText.bind(this)\r\n\r\n this.model.chart().bind('update', this.trigger.bind(this, 'change'))\r\n this.model.bind('update change', this.trigger.bind(this, 'change'))\r\n const mouseModelChangeHandler = this.trigger.bind(this, 'change', 'cross')\r\n this.model.bind('destroy', () => {\r\n mouseModel.unbind('change', mouseModelChangeHandler)\r\n })\r\n mouseModel.bind('change', mouseModelChangeHandler)\r\n\r\n this.model.chart().chart_layout().bind('theme', this.setupCache.bind(this))\r\n }\r\n\r\n get type() {\r\n return (this.constructor as typeof Indicator).config.type\r\n }\r\n\r\n get label() {\r\n return (this.constructor as typeof Indicator).config.label\r\n }\r\n\r\n get config() {\r\n return (this.constructor as typeof Indicator).config\r\n }\r\n\r\n render(context: CanvasRenderingContext2D) {\r\n const { IndicatorSettings } = this.getChartLayoutSettings()\r\n this.data = this.model.chart().quote()\r\n this.leftOffset = this.model.chart().leftOffset\r\n this.width = this.model.chart().width\r\n this.contentWidth = this.width - IndicatorSettings.left.width - IndicatorSettings.right.width\r\n\r\n this.compute()\r\n\r\n this.setupCache()\r\n\r\n this.renderYAxis(context)\r\n\r\n context.save()\r\n this.clip(context)\r\n this.renderXAxis(context)\r\n const translate = getTranslate({\r\n context,\r\n xOffset: this.leftOffset + IndicatorSettings.left.width,\r\n yOffset: IndicatorSettings.top.height,\r\n })\r\n translate.do()\r\n this.renderIndicator(context)\r\n translate.undo()\r\n context.restore()\r\n\r\n if (!this.getIsChartPageSpecificFunctionality()) {\r\n this.renderLabel(context)\r\n }\r\n }\r\n\r\n isComputeNecessary() {\r\n // if quote was updated (this.fetchedAt !== this.data.fetchedAt)\r\n // or indicator setting was changed via modal (this.shouldUpdate)\r\n // allow compute and update variables to prevent another unless\r\n // those variables change again\r\n if (this.fetchedAt !== this.data.fetchedAt || this.shouldUpdate) {\r\n this.fetchedAt = this.data.fetchedAt\r\n this.shouldUpdate = false\r\n return true\r\n }\r\n return false\r\n }\r\n\r\n renderYAxis(context: CanvasRenderingContext2D, options?: { lastValueSuffix?: string }) {\r\n const { IndicatorSettings, ChartSettings } = this.getChartLayoutSettings()\r\n const { Colors } = ChartSettings.general\r\n let y\r\n const translate = getTranslate({\r\n context,\r\n xOffset: IndicatorSettings.left.width,\r\n yOffset: IndicatorSettings.top.height,\r\n })\r\n translate.do()\r\n const ticks = this.model.scale.y.ticks(10)\r\n const tickTextStep = Math.abs(ticks[2] - ticks[0])\r\n const yLine = new Line(\r\n {\r\n x1: 0,\r\n x2: this.contentWidth,\r\n strokeStyle: Colors.grid,\r\n dashLength: 3,\r\n },\r\n this.model\r\n )\r\n const text = new Text(\r\n {\r\n x: this.contentWidth + OFFSET.M + IndicatorSettings.right.axis.margin.left!,\r\n font: Text.getMergedPropsWithDefaults('font', IndicatorSettings.right.axis.font),\r\n fillStyle: Colors.text,\r\n textBaseline: TextBaseline.middle,\r\n },\r\n this.model\r\n )\r\n for (let index = 0; index < ticks.length; index++) {\r\n const tick = ticks[index]\r\n y = Math.round(this.fy(tick))\r\n yLine.set({ y1: y, y2: y }).render(context)\r\n if (index % 2 === 0) {\r\n text.set({ text: this.formatAxis(tick, tickTextStep), y }).render(context)\r\n }\r\n }\r\n\r\n const minY = 0\r\n const maxY = this.contentHeight\r\n const valueY = this.lastValue === null ? 0 : Math.round(this.fy(this.lastValue))\r\n if (this.lastValue != null && valueY >= minY && valueY <= maxY) {\r\n new Text(\r\n {\r\n text: `${math.formatBigNumber(this.lastValue, 2)}${options?.lastValueSuffix ?? ''}`,\r\n x: this.contentWidth + OFFSET.M - PADDING.XXS + IndicatorSettings.right.axis.margin.left!,\r\n y: valueY,\r\n font: Text.getMergedPropsWithDefaults('font', IndicatorSettings.right.axis.font),\r\n lineHeight: IndicatorSettings.right.axis.font.lineHeight,\r\n padding: {\r\n top: IndicatorSettings.right.axis.font?.padding?.top ?? PADDING.XXS,\r\n right: IndicatorSettings.right.axis.font?.padding?.right ?? PADDING.XXS,\r\n bottom: IndicatorSettings.right.axis.font?.padding?.bottom ?? PADDING.XXS,\r\n left: IndicatorSettings.right.axis.font?.padding?.left ?? PADDING.XXS,\r\n },\r\n textBaseline: TextBaseline.middle,\r\n fillStyle: Colors.indicatorCurrentText,\r\n background: Colors.indicatorCurrentBackground,\r\n },\r\n this.model\r\n ).render(context)\r\n }\r\n\r\n translate.undo()\r\n }\r\n\r\n renderXAxis(context: CanvasRenderingContext2D) {\r\n const { IndicatorSettings, ChartSettings } = this.getChartLayoutSettings()\r\n const { Colors } = ChartSettings.general\r\n const xLine = new Line(\r\n {\r\n x1: 0,\r\n x2: 0,\r\n y1: 0,\r\n y2: this.contentHeight,\r\n strokeStyle: Colors.grid,\r\n dashLength: 3,\r\n },\r\n this.model\r\n )\r\n const translate = getTranslate({\r\n context,\r\n xOffset: IndicatorSettings.left.width,\r\n yOffset: IndicatorSettings.top.height,\r\n })\r\n translate.do()\r\n for (let tick = 0, end = this.data.date.length; tick < end; tick += 10) {\r\n const x = Math.round(this.fx(tick) + this.leftOffset)\r\n if (x < -15 || x > this.width + 15) {\r\n // margin?\r\n continue\r\n }\r\n xLine.set({ x1: x, x2: x }).render(context)\r\n }\r\n translate.undo()\r\n }\r\n\r\n renderLabel(context: CanvasRenderingContext2D) {\r\n if (this.getIsChartPageSpecificFunctionality()) {\r\n this.renderLabelChartsPage(context)\r\n } else {\r\n this.renderLabelQuotePage(context)\r\n }\r\n }\r\n\r\n renderLabelQuotePage(context: CanvasRenderingContext2D) {\r\n const { IndicatorSettings, ChartSettings } = this.getChartLayoutSettings()\r\n const { Colors } = ChartSettings.general\r\n const label = new Text(\r\n {\r\n text: this.toString(),\r\n x: IndicatorSettings.left.indicatorLabel.margin.left,\r\n y: IndicatorSettings.left.indicatorLabel.margin.top,\r\n font: Text.getMergedPropsWithDefaults('font', IndicatorSettings.left.indicatorLabel.font),\r\n fillStyle: Colors.text,\r\n textAlign: TextAlign.left,\r\n textBaseline: TextBaseline.top,\r\n },\r\n this.model\r\n )\r\n this.labelWidth = label.measure(context)\r\n return label.render(context)\r\n }\r\n\r\n renderLabelChartsPage(context: CanvasRenderingContext2D): { x: number; y: number; labelWidth: number } | void {\r\n const { IndicatorSettings } = this.getChartLayoutSettings()\r\n const { theme, specificChartFunctionality } = this.model.chart().chart_layout()\r\n const isDarkMode = theme === Theme.dark\r\n const x =\r\n specificChartFunctionality === SpecificChartFunctionality.quotePage\r\n ? OFFSET.S\r\n : IndicatorSettings.left.indicatorLabel.margin.left!\r\n const y = IndicatorSettings.left.indicatorLabel.margin.top!\r\n const label = new Text(\r\n {\r\n text: this.toString(),\r\n x: x * 2,\r\n font: Text.getMergedPropsWithDefaults('font', IndicatorSettings.left.indicatorLabel.font),\r\n fillStyle: tailwindColors.gray[isDarkMode ? 50 : 900],\r\n textAlign: TextAlign.left,\r\n textBaseline: TextBaseline.middle,\r\n },\r\n this.model\r\n )\r\n this.labelWidth = label.measure(context) + IndicatorSettings.left.indicatorLabel.margin.left! * 2\r\n label.set({ y: y + (INDICATOR_LABEL_HEIGHT - label.attrs.lineHeight / 2) })\r\n roundedRect({\r\n ctx: context,\r\n x,\r\n y,\r\n height: INDICATOR_LABEL_HEIGHT,\r\n width: this.labelWidth,\r\n radius: 6,\r\n color: `${tailwindColors.gray[isDarkMode ? 700 : 50]}cc`,\r\n })\r\n label.render(context)\r\n\r\n return { x, y, labelWidth: this.labelWidth }\r\n }\r\n\r\n renderCross(context: CanvasRenderingContext2D) {\r\n renderCross({\r\n context,\r\n mouseModel,\r\n paneModel: this.model,\r\n quote: this.data,\r\n contentWidth: this.contentWidth,\r\n contentHeight: this.contentHeight,\r\n isIndicator: true,\r\n isPerfIndicator: this.type === IndicatorType.Perf || this.type === IndicatorType.Shrtfl,\r\n onRenderCrossText: !this.getIsChartPageSpecificFunctionality() ? this.renderCrossText : undefined,\r\n })\r\n\r\n if (this.getIsChartPageSpecificFunctionality()) {\r\n this.renderCrossText(context, mouseModel.getCrossIndexForPane(this.model))\r\n }\r\n }\r\n\r\n renderCrossText(context: CanvasRenderingContext2D, crossIndex: number) {\r\n this.data = this.model.chart().quote()\r\n const index = Number.isNaN(crossIndex) ? -1 : crossIndex\r\n if (this.getIsChartPageSpecificFunctionality()) {\r\n this.renderLabelChartsPage(context)\r\n\r\n this.renderCrossTextChartsPage(context, index)\r\n } else {\r\n this.renderCrossTextQuotePage(context, index)\r\n }\r\n }\r\n\r\n getValueLabelsAtIndex(_: number): Array<{ color: string; text: string | null }> {\r\n return []\r\n }\r\n\r\n renderCrossTextValueLabels(\r\n context: CanvasRenderingContext2D,\r\n crossIndex: number,\r\n { textBaseline, y }: Pick\r\n ) {\r\n if (!context || isNaN(crossIndex) || crossIndex === -1) {\r\n return\r\n }\r\n\r\n const { ChartSettings, IndicatorSettings } = this.getChartLayoutSettings()\r\n const { Colors } = ChartSettings.general\r\n const crossValueText = new Text(\r\n {\r\n font: Text.getMergedPropsWithDefaults('font', {\r\n ...IndicatorSettings.left.indicatorLabel.font,\r\n style: 'normal',\r\n }),\r\n textAlign: TextAlign.left,\r\n textBaseline,\r\n background: getHEXWithSpecificAplha(Colors.canvasFill, 0.8),\r\n padding: { top: 0, bottom: 0, left: 5, right: 5 },\r\n },\r\n this.model\r\n )\r\n\r\n let x = this.labelWidth + IndicatorSettings.left.indicatorLabel.margin.left! * 2\r\n\r\n const renderLabel = ({ color, text }: { color: string; text: string | null }) => {\r\n crossValueText.set({\r\n x,\r\n y,\r\n fillStyle: color,\r\n text: text ?? ' - ',\r\n })\r\n\r\n x += crossValueText.measure(context) + crossValueText.attrs.padding.left + crossValueText.attrs.padding.right\r\n\r\n crossValueText.render(context)\r\n }\r\n\r\n let lastRenderedIndex = -1\r\n this.getValueLabelsAtIndex(crossIndex).forEach(({ color, text }, index) => {\r\n if (text !== null) {\r\n if (lastRenderedIndex > -1) {\r\n renderLabel({ color: Colors.zeroChange, text: '·' })\r\n }\r\n renderLabel({ color, text })\r\n\r\n lastRenderedIndex = index\r\n }\r\n })\r\n }\r\n\r\n renderCrossTextChartsPage(context: CanvasRenderingContext2D, crossIndex: number) {\r\n const { indicatorLabel } = this.getChartLayoutSettings().IndicatorSettings.left\r\n // @todo - Default text lineheight is 20 , and is not overwritten by indicatorLabel.font (which is probably a bug) , in this case it's easier to hardcode this value than access is on Text instance\r\n const lineHeight = 20\r\n this.renderCrossTextValueLabels(context, crossIndex, {\r\n textBaseline: TextBaseline.middle,\r\n y: indicatorLabel.margin.top! + (2 * INDICATOR_LABEL_HEIGHT - lineHeight) / 2,\r\n })\r\n }\r\n\r\n renderCrossTextQuotePage(context: CanvasRenderingContext2D, crossIndex: number) {\r\n this.renderCrossTextValueLabels(context, crossIndex, {\r\n textBaseline: TextBaseline.top,\r\n y: this.getChartLayoutSettings().IndicatorSettings.left.indicatorLabel.margin.top,\r\n })\r\n }\r\n\r\n getValueLabel(value: number | undefined | null, unit = '') {\r\n if (value === undefined || value === null || !Number.isFinite(value)) return null\r\n\r\n return `${math.formatBigNumber(value, 2)}${unit}`\r\n }\r\n\r\n getOversoldOverboughtValueLabelsAtIndex(index: number, array: number[]) {\r\n const { IndicatorSettings } = this.getChartLayoutSettings()\r\n const dataIndex = this.data.barToDataIndex[index]\r\n return [{ color: IndicatorSettings.general.Colors.line, text: this.getValueLabel(array[dataIndex]) }]\r\n }\r\n\r\n renderOversoldOverbought(\r\n context: CanvasRenderingContext2D,\r\n array: number[],\r\n from: number,\r\n oversold: number,\r\n zero: number,\r\n overbought: number,\r\n drawLines?: boolean\r\n ) {\r\n const { IndicatorSettings } = this.getChartLayoutSettings()\r\n if (this.data.close.length === 0) return\r\n const drawInVisibleAreaProps = {\r\n fromIndexOffset: from,\r\n leftOffset: this.leftOffset,\r\n paneModel: this.model,\r\n quote: this.data,\r\n width: this.width,\r\n }\r\n\r\n const firstBarToRenderIndex = getCompensatedFirstBarToRenderIndex(drawInVisibleAreaProps)\r\n\r\n if (drawLines == null) {\r\n drawLines = true\r\n }\r\n\r\n context.save()\r\n\r\n let clipHeight = Math.round(this.fy(oversold) - this.fy(this.model.scale.y.domain()[1]))\r\n if (clipHeight <= 0 || getIsSSr()) {\r\n context.beginPath()\r\n context.rect(\r\n -this.leftOffset,\r\n this.fy(this.model.scale.y.domain()[1]) + 1, // compensation to addition of 1 in clip function\r\n this.contentWidth,\r\n clipHeight < 0 ? clipHeight - 1 : -1 // clipHeight - 1 is a compensation to addition of 1 in clip function ; fix bug in skia-canvas when clip is incorrect if height is 0 or clip is outside of previous clip https://github.com/samizdatco/skia-canvas/issues/87\r\n )\r\n }\r\n context.clip()\r\n context.set('fillStyle', '#87ceef')\r\n\r\n context.beginPath()\r\n context.moveTo(this.fx(firstBarToRenderIndex), Math.round(this.fy(this.model.scale.y.domain()[0])))\r\n drawInVisibleArea({\r\n ...drawInVisibleAreaProps,\r\n drawBarCallback: (i, x) => {\r\n context.lineTo(x, Math.round(this.fy(array[i])))\r\n },\r\n })\r\n context.lineTo(this.fx(this.data.close.length - 1), Math.round(this.fy(this.model.scale.y.domain()[0])))\r\n context.fill()\r\n context.restore()\r\n if (drawLines) {\r\n new Line(\r\n {\r\n x1: -this.leftOffset,\r\n x2: -this.leftOffset + this.contentWidth,\r\n y1: Math.round(this.fy(oversold)),\r\n y2: Math.round(this.fy(oversold)),\r\n strokeStyle: '#69c1ea',\r\n },\r\n this.model\r\n ).render(context)\r\n }\r\n\r\n if (drawLines) {\r\n this.renderZeroLine(context, zero)\r\n }\r\n\r\n context.save()\r\n clipHeight = Math.round(this.fy(overbought))\r\n if (clipHeight >= 0 || getIsSSr()) {\r\n context.beginPath()\r\n context.rect(\r\n -this.leftOffset,\r\n this.fy(this.model.scale.y.domain()[0]),\r\n this.contentWidth,\r\n clipHeight > 0 ? clipHeight : 1 // // fix bug in skia-canvas when clip is incorrect if height is 0 or clip is outside of previous clip https://github.com/samizdatco/skia-canvas/issues/87\r\n )\r\n }\r\n\r\n context.clip()\r\n context.set('fillStyle', '#dc9fe5')\r\n context.beginPath()\r\n context.moveTo(this.fx(firstBarToRenderIndex), Math.round(this.fy(this.model.scale.y.domain()[1])))\r\n drawInVisibleArea({\r\n ...drawInVisibleAreaProps,\r\n drawBarCallback: (i, x) => {\r\n context.lineTo(x, Math.round(this.fy(array[i])))\r\n },\r\n })\r\n context.lineTo(this.fx(this.data.close.length - 1), Math.round(this.fy(this.model.scale.y.domain()[1]) + 1))\r\n context.fill()\r\n context.restore()\r\n if (drawLines) {\r\n new Line(\r\n {\r\n x1: -this.leftOffset,\r\n x2: -this.leftOffset + this.contentWidth,\r\n y1: Math.round(this.fy(overbought)),\r\n y2: Math.round(this.fy(overbought)),\r\n strokeStyle: '#d386df',\r\n },\r\n this.model\r\n ).render(context)\r\n }\r\n\r\n context.set('strokeStyle', IndicatorSettings.general.Colors.line)\r\n context.set('fillStyle', '#dc9fe5')\r\n\r\n context.translate(0.5, 0.5)\r\n context.beginPath()\r\n drawInVisibleArea({\r\n ...drawInVisibleAreaProps,\r\n drawBarCallback: (i, x) => {\r\n context.lineTo(Math.round(x), Math.round(this.fy(array[i])))\r\n },\r\n })\r\n context.stroke()\r\n context.translate(-0.5, -0.5)\r\n }\r\n\r\n renderZeroLine(context: CanvasRenderingContext2D, zero: number) {\r\n new Line(\r\n {\r\n x1: -this.leftOffset,\r\n x2: -this.leftOffset + this.contentWidth,\r\n y1: Math.round(this.fy(zero)),\r\n y2: Math.round(this.fy(zero)),\r\n strokeStyle: '#ff8787',\r\n dashLength: 3,\r\n },\r\n this.model\r\n ).render(context)\r\n }\r\n\r\n setupCache() {}\r\n\r\n clip(context: CanvasRenderingContext2D) {\r\n const { IndicatorSettings } = this.getChartLayoutSettings()\r\n context.beginPath()\r\n context.rect(IndicatorSettings.left.width, IndicatorSettings.top.height, this.contentWidth, this.contentHeight + 1) // +1 shows one more pixel which is needed to be able to see a line at very bottom of an indicaor\r\n return context.clip()\r\n }\r\n\r\n formatAxis(value: number, tickStep?: number) {\r\n if (tickStep !== undefined && 10 > tickStep) {\r\n return value.toFixed(2)\r\n }\r\n return value.toString()\r\n }\r\n\r\n fx = (x: number) => this.model.scale.x(this.data.barIndex[x])\r\n\r\n fy = (y: number) => this.model.scale.y(y)\r\n\r\n set(values: Partial) {\r\n const { IndicatorSettings } = this.getChartLayoutSettings()\r\n this.shouldUpdate = true\r\n for (const key in values) {\r\n if (key !== 'type') {\r\n // @ts-expect-error - values keys don't have to always match variables on the instance\r\n this[key] = values[key]\r\n }\r\n }\r\n this.width = this.model.chart().width\r\n this.contentWidth = this.width - IndicatorSettings.left.width - IndicatorSettings.right.width\r\n\r\n const newAttrs = this.getModalConfig()\r\n .inputs.map(({ value }) => value.toString())\r\n .join(',')\r\n if (newAttrs) this.attrs = { ...this.attrs, period: newAttrs }\r\n\r\n this.model.trigger(CustomSpineEvents.ManualChange)\r\n }\r\n\r\n parsePeriodInt(values: Partial) {\r\n if (typeof values.period === 'string') {\r\n this.period = Number.parseInt(values.period, 10)\r\n this.model.trigger(CustomSpineEvents.ManualChange)\r\n }\r\n }\r\n\r\n setModel(model: Pane) {\r\n return (this.model = model)\r\n }\r\n\r\n isInArea(area: PaneArea) {\r\n const { IndicatorSettings } = this.getChartLayoutSettings()\r\n const x = IndicatorSettings.left.indicatorLabel.margin.left!\r\n const y = IndicatorSettings.left.indicatorLabel.margin.top!\r\n let width = OFFSET.M * 2 + this.labelWidth\r\n let height = OFFSET.S * 2 + FONT_SIZE.M\r\n\r\n if (this.getIsChartPageSpecificFunctionality()) {\r\n width = this.labelWidth\r\n height = INDICATOR_LABEL_HEIGHT\r\n }\r\n\r\n if (x < area.cursorX && area.cursorX < width + x && y < area.cursorY && area.cursorY < height + y) {\r\n return true\r\n }\r\n return false\r\n }\r\n\r\n getIsInChartView(_: Chart) {\r\n return true\r\n }\r\n\r\n moveBy() {}\r\n\r\n thumbsAreInArea() {\r\n return false\r\n }\r\n\r\n computeVisibleMinMax(...arrays: number[][]) {\r\n let min = MAX_POSITIVE_DEFAULT_VALUE\r\n let max = MAX_NEGATIVE_DEFAULT_VALUE\r\n\r\n const { leftOffset } = this.model.chart()\r\n\r\n const firstBarToRenderIndex = getVisibleBarToRenderIndex({\r\n quote: this.data,\r\n paneModel: this.model,\r\n leftOffset,\r\n })\r\n const lastBarToRenderIndex = getVisibleBarToRenderIndex({\r\n quote: this.data,\r\n paneModel: this.model,\r\n leftOffset,\r\n chartWidth: this.contentWidth,\r\n })\r\n const areNoBarsVisible = getAreNoBarsVisible(firstBarToRenderIndex, lastBarToRenderIndex)\r\n\r\n for (const arr of arrays) {\r\n for (let i = firstBarToRenderIndex.index; i <= lastBarToRenderIndex.index; i++) {\r\n if (!isNaN(arr[i])) {\r\n min = Math.min(min, arr[i])\r\n max = Math.max(max, arr[i])\r\n }\r\n }\r\n }\r\n\r\n if (!areNoBarsVisible && min !== MAX_POSITIVE_DEFAULT_VALUE && max !== MAX_NEGATIVE_DEFAULT_VALUE) {\r\n if (min === max && this.applyMinMaxPadding) {\r\n min = min - min * Math.sign(min)\r\n max = max + max * Math.sign(max)\r\n }\r\n if (min !== max) {\r\n return { min, max }\r\n }\r\n }\r\n return this.getDomainDefaults(this.type)\r\n }\r\n\r\n getModalConfig(): IModalConfig {\r\n return {\r\n title: this.label,\r\n inputs: [],\r\n inputsErrorMessages: {},\r\n }\r\n }\r\n\r\n getDomainDefaults = (indicatorType: IndicatorType) => INDICATOR_DEFAULT_DOMAIN(indicatorType)\r\n\r\n getMinMax() {\r\n this.data = this.model.chart().quote()\r\n this.compute()\r\n return { min: this.min, max: this.max }\r\n }\r\n\r\n toObject() {\r\n return merge({}, this.attrs, { type: this.type, tickers: this.tickers })\r\n }\r\n\r\n toConfig(): T['attrs'] & { type: T['type'] } {\r\n return {\r\n type: this.type,\r\n period: this.getModalConfig()\r\n .inputs.map((input: IModalConfigInput) => input.value.toString())\r\n .join(','),\r\n }\r\n }\r\n\r\n toString() {\r\n return this.config.getShortLabelWithAttrs(this)\r\n }\r\n\r\n getChartLayoutSettings() {\r\n return getChartLayoutSettings(this.model.chart().chart_layout())\r\n }\r\n\r\n renderIndicator(_: CanvasRenderingContext2D) {\r\n throw Error('Implement renderIndicator method')\r\n }\r\n\r\n getIsValid(_: string): boolean | undefined {\r\n throw Error('Implement')\r\n }\r\n\r\n getIsNumberInputValid({ key, integerOnly = true }: { key: string; integerOnly?: boolean }): boolean {\r\n const input = this.getModalConfig().inputs.find(({ name }: { name: string }) => key === name)\r\n return !!input && isInRange(input) && (!integerOnly || isPositiveInteger(input.value))\r\n }\r\n\r\n getIsChartPageSpecificFunctionality() {\r\n const { specificChartFunctionality } = this.model.chart().chart_layout()\r\n const isCharts = specificChartFunctionality === SpecificChartFunctionality.chartPage\r\n const isRedesignedFuturesForexCrypto =\r\n isRedesignEnabled() &&\r\n [\r\n SpecificChartFunctionality.futuresPage,\r\n SpecificChartFunctionality.forexPage,\r\n SpecificChartFunctionality.cryptoPage,\r\n SpecificChartFunctionality.quotePage,\r\n ].includes(specificChartFunctionality)\r\n\r\n return isCharts || isRedesignedFuturesForexCrypto\r\n }\r\n\r\n getIsDrawing() {\r\n return false\r\n }\r\n\r\n getIsChartEvent() {\r\n return false\r\n }\r\n\r\n compute() {\r\n throw Error('Implement compute method')\r\n }\r\n}\r\n\r\nIndicator.initClass()\r\n\r\nexport default Indicator\r\n","export function roundedRect({\r\n ctx,\r\n x,\r\n y,\r\n width,\r\n height,\r\n radius,\r\n color,\r\n}: {\r\n ctx: CanvasRenderingContext2D\r\n x: number\r\n y: number\r\n width: number\r\n height: number\r\n radius: number\r\n color: string\r\n}) {\r\n ctx.translate(0.5, 0.5)\r\n ctx.set('strokeStyle', color)\r\n ctx.set('fillStyle', color)\r\n ctx.beginPath()\r\n ctx.moveTo(x, y + radius)\r\n ctx.lineTo(x, y + height - radius)\r\n ctx.arcTo(x, y + height, x + radius, y + height, radius)\r\n ctx.lineTo(x + width - radius, y + height)\r\n ctx.arcTo(x + width, y + height, x + width, y + height - radius, radius)\r\n ctx.lineTo(x + width, y + radius)\r\n ctx.arcTo(x + width, y, x + width - radius, y, radius)\r\n ctx.lineTo(x + radius, y)\r\n ctx.arcTo(x, y, x, y + radius, radius)\r\n ctx.stroke()\r\n ctx.fill()\r\n ctx.translate(-0.5, -0.5)\r\n}\r\n","import utils from '../utils'\r\nimport { drawInVisibleArea } from '../utils/draw_in_visible_area'\r\nimport { ADXConfig, Attrs } from './configs/adx'\r\nimport Indicator from './indicator'\r\n\r\nclass ADX extends Indicator {\r\n static config = ADXConfig\r\n\r\n declare period: number\r\n pdi: number[] = []\r\n mdi: number[] = []\r\n adx: number[] = []\r\n\r\n set(values: Partial) {\r\n super.set(values)\r\n this.parsePeriodInt(values)\r\n }\r\n\r\n compute() {\r\n if (this.isComputeNecessary()) {\r\n let adx, amdm, apdm, mdi, pdi\r\n this.pdi = []\r\n this.mdi = []\r\n this.adx = []\r\n let atr = (apdm = amdm = adx = 0)\r\n for (let i = this.period; i < this.data.close.length; i++) {\r\n const deltaHigh = this.data.high[i] - this.data.high[i - 1]\r\n const deltaLow = this.data.low[i - 1] - this.data.low[i]\r\n\r\n let pdm = 0\r\n if (deltaHigh > 0 && deltaHigh > deltaLow) {\r\n pdm = deltaHigh\r\n }\r\n\r\n let mdm = 0\r\n if (deltaLow > 0 && deltaLow > deltaHigh) {\r\n mdm = deltaLow\r\n }\r\n\r\n const tr = utils.max([\r\n this.data.high[i] - this.data.low[i],\r\n Math.abs(this.data.high[i] - this.data.close[i - 1]),\r\n Math.abs(this.data.low[i] - this.data.close[i - 1]),\r\n ])\r\n\r\n atr = (atr * (this.period - 1) + tr) / this.period\r\n apdm = (apdm * (this.period - 1) + pdm) / this.period\r\n amdm = (amdm * (this.period - 1) + mdm) / this.period\r\n\r\n pdi = atr > 0 ? (apdm * 100) / atr : 0\r\n mdi = atr > 0 ? (amdm * 100) / atr : 0\r\n const di = Math.abs(pdi - mdi)\r\n const dx = pdi + mdi > 0 ? (di * 100) / (pdi + mdi) : 0\r\n adx = (adx * (this.period - 1) + dx) / this.period\r\n\r\n this.pdi[i] = pdi\r\n this.mdi[i] = mdi\r\n this.adx[i] = adx\r\n }\r\n this.lastValue = this.adx.last() ?? null\r\n }\r\n const { min, max } =\r\n this.pdi.length > 0 || this.mdi.length > 0 || this.adx.length > 0\r\n ? this.computeVisibleMinMax(this.pdi, this.mdi, this.adx)\r\n : this.getDomainDefaults(this.type)\r\n this.min = min\r\n this.max = max\r\n }\r\n\r\n getLineColors() {\r\n return {\r\n pdi: '#2eb12e',\r\n mdi: '#d43737',\r\n adx: this.getChartLayoutSettings().IndicatorSettings.general.Colors.line,\r\n }\r\n }\r\n\r\n getValueLabelsAtIndex(index: number) {\r\n const lineColors = this.getLineColors()\r\n const dataIndex = this.data.barToDataIndex[index]\r\n return [\r\n { color: lineColors.pdi, text: this.getValueLabel(this.pdi[dataIndex]) },\r\n { color: lineColors.mdi, text: this.getValueLabel(this.mdi[dataIndex]) },\r\n { color: lineColors.adx, text: this.getValueLabel(this.adx[dataIndex]) },\r\n ]\r\n }\r\n\r\n renderIndicator(context: CanvasRenderingContext2D) {\r\n if (this.data.close.length === 0) return\r\n\r\n const lineColors = this.getLineColors()\r\n\r\n context.translate(0.5, 0.5)\r\n context.set('strokeStyle', lineColors.pdi)\r\n context.beginPath()\r\n\r\n const drawInVisibleAreaProps = {\r\n quote: this.data,\r\n paneModel: this.model,\r\n leftOffset: this.leftOffset,\r\n width: this.width,\r\n fromIndexOffset: this.period,\r\n }\r\n drawInVisibleArea({\r\n ...drawInVisibleAreaProps,\r\n drawBarCallback: (i, x) => {\r\n context.lineTo(x, Math.round(this.fy(this.pdi[i])))\r\n },\r\n })\r\n\r\n context.stroke()\r\n\r\n context.set('strokeStyle', lineColors.mdi)\r\n context.beginPath()\r\n drawInVisibleArea({\r\n ...drawInVisibleAreaProps,\r\n drawBarCallback: (i, x) => {\r\n context.lineTo(x, Math.round(this.fy(this.mdi[i])))\r\n },\r\n })\r\n context.stroke()\r\n context.set('strokeStyle', lineColors.adx)\r\n context.beginPath()\r\n\r\n drawInVisibleArea({\r\n ...drawInVisibleAreaProps,\r\n drawBarCallback: (i, x) => {\r\n context.lineTo(x, Math.round(this.fy(this.adx[i])))\r\n },\r\n })\r\n context.stroke()\r\n context.translate(-0.5, -0.5)\r\n }\r\n\r\n getModalConfig() {\r\n const options = {\r\n period: {\r\n type: 'number',\r\n label: 'Period',\r\n name: 'period',\r\n value: this.period ?? 14,\r\n required: true,\r\n min: 1,\r\n max: 999999,\r\n },\r\n }\r\n\r\n return {\r\n title: ADXConfig.label,\r\n inputs: ADXConfig.inputsOrder.map((item) => options[item]),\r\n inputsErrorMessages: {\r\n period: `${options.period.label} must be a whole number between ${options.period.min} and ${options.period.max}`,\r\n },\r\n }\r\n }\r\n\r\n getIsValid(key: string): boolean {\r\n switch (key) {\r\n case 'period':\r\n return this.getIsNumberInputValid({ key })\r\n default:\r\n return false\r\n }\r\n }\r\n}\r\n\r\nexport default ADX\r\n","import { IndicatorType } from '../../constants/common'\r\nimport IndicatorBaseConfig from './indicatorBaseConfig'\r\n\r\nexport type Options = {\r\n period: number\r\n}\r\n\r\nexport type Attrs = Options\r\n\r\nexport class AroConfig extends IndicatorBaseConfig {\r\n static type = IndicatorType.Aro\r\n static abbreviation = 'aro'\r\n static label = 'Aroon'\r\n static shortLabel = 'Aroon'\r\n static optionsOrder = ['period'] as const\r\n static optionsLabels = { period: 'Period' }\r\n static inputsOrder = this.optionsOrder\r\n static inputsLabels = this.optionsLabels\r\n static calculatedValuesOrder = ['aroonUp', 'aroonDown', 'oscillator'] as const\r\n static calculatedValuesLabels = {\r\n aroonUp: 'Aroon Up',\r\n aroonDown: 'Aroon Down',\r\n oscillator: 'Oscillator',\r\n }\r\n\r\n static defaultCalculatedValueOption = this.calculatedValuesOrder[0]\r\n}\r\n","import { AroConfig, Attrs } from '../indicators/configs/aro'\r\nimport { MainCalculation, OnValueCalculated } from './main'\r\n\r\ntype DefaultCalculatedValuesType = {\r\n aroonUp: number[]\r\n aroonDown: number[]\r\n oscillator: number[]\r\n}\r\n\r\nexport class AroonCalculation extends MainCalculation {\r\n static config = AroConfig\r\n\r\n calculate(onValueCalculated?: OnValueCalculated) {\r\n const { period } = this.options\r\n const { low, high } = this.quote\r\n this._calculatedValues = this.getDefaultCalculatedValues()\r\n\r\n for (let i = period; i < high.length; i++) {\r\n const highPeriod = high.slice(i - period, i + 1)\r\n const highestInPeriod = Math.max(...highPeriod)\r\n const periodSinceHigh = period - highPeriod.lastIndexOf(highestInPeriod)\r\n this._calculatedValues.aroonUp[i] = 100 * ((period - periodSinceHigh) / period)\r\n\r\n const lowPeriod = low.slice(i - period, i + 1)\r\n const lowestInPeriod = Math.min(...lowPeriod)\r\n const periodSinceLow = period - lowPeriod.lastIndexOf(lowestInPeriod)\r\n this._calculatedValues.aroonDown[i] = 100 * ((period - periodSinceLow) / period)\r\n\r\n this._calculatedValues.oscillator[i] = this._calculatedValues.aroonUp[i] - this._calculatedValues.aroonDown[i]\r\n\r\n if (onValueCalculated?.(this.calculatedValues, i) === false) {\r\n break\r\n }\r\n }\r\n }\r\n}\r\n","import Text from '../canvas/text'\r\nimport { OFFSET, PADDING, TextBaseline } from '../constants/common'\r\nimport { getTranslate } from '../controllers/renderUtils'\r\nimport { AroonCalculation } from '../indicator-calculation/aroon'\r\nimport Pane from '../models/pane'\r\nimport { drawInVisibleArea } from '../utils/draw_in_visible_area'\r\nimport { AroConfig, Attrs } from './configs/aro'\r\nimport Indicator from './indicator'\r\n\r\nconst COLORS = {\r\n aroonUp: '#00a000',\r\n aroonDown: '#c80000',\r\n}\r\n\r\nclass Aroon extends Indicator {\r\n static config = AroConfig\r\n\r\n aroonCalculation: AroonCalculation | null = null\r\n declare period: number\r\n\r\n constructor(attrs: Attrs, model: Pane) {\r\n super(attrs, model)\r\n this.renderYAxis = this.renderYAxis.bind(this)\r\n }\r\n\r\n set(values: Partial) {\r\n super.set(values)\r\n this.parsePeriodInt(values)\r\n }\r\n\r\n compute() {\r\n if (!this.isComputeNecessary() && this.aroonCalculation !== null) return\r\n\r\n this.aroonCalculation = new AroonCalculation({\r\n quote: this.data,\r\n options: { period: this.period },\r\n })\r\n\r\n this.aroonCalculation.calculate()\r\n\r\n const { min, max } = this.getDomainDefaults(this.type)\r\n this.min = min\r\n this.max = max\r\n }\r\n\r\n getLineColors() {\r\n return {\r\n aroonUp: COLORS.aroonUp,\r\n aroonDown: COLORS.aroonDown,\r\n }\r\n }\r\n\r\n getValueLabelsAtIndex(index: number) {\r\n if (this.data.close.length === 0 || !this.aroonCalculation) return []\r\n\r\n const lineColors = this.getLineColors()\r\n const { aroonUp, aroonDown } = this.aroonCalculation.calculatedValues\r\n const dataIndex = this.data.barToDataIndex[index]\r\n return [\r\n { color: lineColors.aroonDown, text: this.getValueLabel(aroonDown[dataIndex]) },\r\n { color: lineColors.aroonUp, text: this.getValueLabel(aroonUp[dataIndex]) },\r\n ]\r\n }\r\n\r\n renderIndicator(context: CanvasRenderingContext2D) {\r\n if (this.data.close.length === 0 || !this.aroonCalculation) return\r\n\r\n const lineColors = this.getLineColors()\r\n\r\n context.translate(0.5, 0.5)\r\n context.set('strokeStyle', lineColors.aroonUp)\r\n context.beginPath()\r\n const drawInVisibleAreaProps = {\r\n quote: this.data,\r\n paneModel: this.model,\r\n leftOffset: this.leftOffset,\r\n width: this.width,\r\n fromIndexOffset: this.period,\r\n }\r\n const { aroonUp, aroonDown } = this.aroonCalculation.calculatedValues\r\n drawInVisibleArea({\r\n ...drawInVisibleAreaProps,\r\n drawBarCallback: (i, x) => {\r\n context.lineTo(x, Math.round(this.fy(aroonUp[i])))\r\n },\r\n })\r\n context.stroke()\r\n\r\n context.set('strokeStyle', lineColors.aroonDown)\r\n context.beginPath()\r\n drawInVisibleArea({\r\n ...drawInVisibleAreaProps,\r\n drawBarCallback: (i, x) => {\r\n context.lineTo(x, Math.round(this.fy(aroonDown[i])))\r\n },\r\n })\r\n context.stroke()\r\n context.translate(-0.5, -0.5)\r\n }\r\n\r\n renderYAxis(context: CanvasRenderingContext2D) {\r\n super.renderYAxis(context)\r\n if (!this.aroonCalculation) return\r\n const { IndicatorSettings, ChartSettings } = this.getChartLayoutSettings()\r\n const { Colors } = ChartSettings.general\r\n const { aroonUp, aroonDown } = this.aroonCalculation.calculatedValues\r\n\r\n const translate = getTranslate({\r\n context,\r\n xOffset: IndicatorSettings.left.width,\r\n yOffset: IndicatorSettings.top.height,\r\n })\r\n translate.do()\r\n const text = new Text(\r\n {\r\n x: this.contentWidth + OFFSET.M - PADDING.XXS + IndicatorSettings.right.axis.margin.left!,\r\n font: Text.getMergedPropsWithDefaults('font', IndicatorSettings.right.axis.font),\r\n lineHeight: IndicatorSettings.right.axis.font.lineHeight,\r\n padding: {\r\n top: IndicatorSettings.right.axis.font?.padding?.top ?? PADDING.XXS,\r\n right: IndicatorSettings.right.axis.font?.padding?.right ?? PADDING.XXS,\r\n bottom: IndicatorSettings.right.axis.font?.padding?.bottom ?? PADDING.XXS,\r\n left: IndicatorSettings.right.axis.font?.padding?.left ?? PADDING.XXS,\r\n },\r\n textBaseline: TextBaseline.middle,\r\n fillStyle: Colors.indicatorCurrentText,\r\n },\r\n this.model\r\n )\r\n const textLabels = []\r\n if (aroonDown.length > 0) {\r\n textLabels.push({\r\n text: aroonDown.last()!.toFixed(2),\r\n y: Math.round(this.fy(aroonDown.last()!)),\r\n background: COLORS.aroonDown,\r\n })\r\n }\r\n if (aroonUp.length > 0) {\r\n textLabels.push({\r\n text: aroonUp.last()!.toFixed(2),\r\n y: Math.round(this.fy(aroonUp.last()!)),\r\n background: COLORS.aroonUp,\r\n })\r\n }\r\n\r\n const minY = 0\r\n const maxY = this.height - IndicatorSettings.bottom.height - IndicatorSettings.top.height\r\n textLabels.forEach((labelSetting) => {\r\n if (labelSetting.y >= minY && labelSetting.y <= maxY) {\r\n text.set(labelSetting).render(context)\r\n }\r\n })\r\n\r\n translate.undo()\r\n }\r\n\r\n getModalConfig() {\r\n const options = {\r\n period: {\r\n type: 'number',\r\n label: 'Period',\r\n name: 'period',\r\n value: this.period ?? 25,\r\n required: true,\r\n min: 1,\r\n max: 999999,\r\n },\r\n }\r\n\r\n return {\r\n title: AroConfig.label,\r\n inputs: AroConfig.inputsOrder.map((item) => options[item]),\r\n inputsErrorMessages: {\r\n period: `${options.period.label} must be a whole number between ${options.period.min} and ${options.period.max}`,\r\n },\r\n }\r\n }\r\n\r\n getIsValid(key: string): boolean {\r\n switch (key) {\r\n case 'period':\r\n return this.getIsNumberInputValid({ key })\r\n default:\r\n return false\r\n }\r\n }\r\n}\r\n\r\nexport default Aroon\r\n","import { IndicatorType } from '../../constants/common'\r\nimport { AroConfig } from './aro'\r\n\r\nexport type Options = {\r\n period: number\r\n}\r\n\r\nexport type Attrs = Options\r\n\r\nexport class ArooscConfig extends AroConfig {\r\n static type = IndicatorType.Aroosc\r\n static abbreviation = 'aroosc'\r\n static label = 'Aroon Oscillator'\r\n static shortLabel = 'Aroon Oscillator'\r\n}\r\n","import { AroonCalculation } from '../indicator-calculation/aroon'\r\nimport { ArooscConfig, Attrs } from './configs/aroosc'\r\nimport Indicator from './indicator'\r\n\r\nclass AroonOscillator extends Indicator {\r\n static config = ArooscConfig\r\n aroonCalculation: AroonCalculation | null = null\r\n declare period: number\r\n\r\n set(values: Partial) {\r\n super.set(values)\r\n this.parsePeriodInt(values)\r\n }\r\n\r\n compute() {\r\n if (!this.isComputeNecessary() && this.aroonCalculation !== null) return\r\n\r\n this.aroonCalculation = new AroonCalculation({\r\n quote: this.data,\r\n options: { period: this.period },\r\n })\r\n\r\n this.aroonCalculation.calculate()\r\n\r\n this.lastValue = this.aroonCalculation.calculatedValues.oscillator.last() ?? null\r\n const { min, max } = this.getDomainDefaults(this.type)\r\n this.min = min\r\n this.max = max\r\n }\r\n\r\n getValueLabelsAtIndex(index: number) {\r\n return this.getOversoldOverboughtValueLabelsAtIndex(index, this.aroonCalculation?.calculatedValues.oscillator ?? [])\r\n }\r\n\r\n renderIndicator(context: CanvasRenderingContext2D) {\r\n this.renderOversoldOverbought(\r\n context,\r\n this.aroonCalculation?.calculatedValues.oscillator ?? [],\r\n this.period,\r\n 0,\r\n 0,\r\n 0,\r\n false\r\n )\r\n }\r\n\r\n getModalConfig() {\r\n const options = {\r\n period: {\r\n type: 'number',\r\n label: 'Period',\r\n name: 'period',\r\n value: this.period ?? 25,\r\n required: true,\r\n min: 1,\r\n max: 999999,\r\n },\r\n }\r\n\r\n return {\r\n title: ArooscConfig.label,\r\n inputs: ArooscConfig.inputsOrder.map((item) => options[item]),\r\n inputsErrorMessages: {\r\n period: `${options.period.label} must be a whole number between ${options.period.min} and ${options.period.max}`,\r\n },\r\n }\r\n }\r\n\r\n getIsValid(key: string): boolean {\r\n switch (key) {\r\n case 'period':\r\n return this.getIsNumberInputValid({ key })\r\n default:\r\n return false\r\n }\r\n }\r\n}\r\n\r\nexport default AroonOscillator\r\n","import { IndicatorType } from '../../constants/common'\r\nimport IndicatorBaseConfig from './indicatorBaseConfig'\r\n\r\nexport type Options = {\r\n period: number\r\n}\r\n\r\nexport type Attrs = Options\r\n\r\nexport class ATRConfig extends IndicatorBaseConfig {\r\n static type = IndicatorType.Atr\r\n static abbreviation = 'atr'\r\n static label = 'Average True Range'\r\n static shortLabel = 'ATR'\r\n static optionsOrder = ['period'] as const\r\n static optionsLabels = { period: 'Period' }\r\n static inputsOrder = this.optionsOrder\r\n static inputsLabels = this.optionsLabels\r\n}\r\n","import AverageTrueRange from '../helpers/atr'\r\nimport { drawInVisibleArea } from '../utils/draw_in_visible_area'\r\nimport { ATRConfig, Attrs } from './configs/atr'\r\nimport Indicator from './indicator'\r\n\r\nclass ATR extends Indicator {\r\n static config = ATRConfig\r\n\r\n atr: number[] = []\r\n declare period: number\r\n\r\n set(values: Partial) {\r\n super.set(values)\r\n this.parsePeriodInt(values)\r\n }\r\n\r\n compute() {\r\n if (this.isComputeNecessary()) {\r\n this.atr = []\r\n const atr = new AverageTrueRange(this.period)\r\n for (let i = 0; i < this.data.close.length; i++) {\r\n atr.add(this.data.high[i], this.data.low[i], this.data.close[i - 1])\r\n this.atr[i] = atr.value\r\n }\r\n\r\n this.lastValue = this.atr.last() ?? null\r\n }\r\n const { min, max } = this.atr.length > 0 ? this.computeVisibleMinMax(this.atr) : this.getDomainDefaults(this.type)\r\n this.min = min\r\n this.max = max\r\n }\r\n\r\n getValueLabelsAtIndex(index: number) {\r\n const dataIndex = this.data.barToDataIndex[index]\r\n return [\r\n {\r\n color: this.getChartLayoutSettings().IndicatorSettings.general.Colors.line!,\r\n text: this.getValueLabel(this.atr[dataIndex]),\r\n },\r\n ]\r\n }\r\n\r\n renderIndicator(context: CanvasRenderingContext2D) {\r\n context.set('strokeStyle', this.getChartLayoutSettings().IndicatorSettings.general.Colors.line)\r\n context.translate(0.5, 0.5)\r\n context.beginPath()\r\n drawInVisibleArea({\r\n quote: this.data,\r\n paneModel: this.model,\r\n leftOffset: this.leftOffset,\r\n width: this.width,\r\n drawBarCallback: (i: number, x: number) => {\r\n context.lineTo(x, Math.round(this.fy(this.atr[i])))\r\n },\r\n })\r\n context.stroke()\r\n context.translate(-0.5, -0.5)\r\n }\r\n\r\n getModalConfig() {\r\n const options = {\r\n period: {\r\n type: 'number',\r\n label: 'Period',\r\n name: 'period',\r\n value: this.period ?? 14,\r\n required: true,\r\n min: 1,\r\n max: 999999,\r\n },\r\n }\r\n\r\n return {\r\n title: ATRConfig.label,\r\n inputs: ATRConfig.inputsOrder.map((item) => options[item]),\r\n inputsErrorMessages: {\r\n period: `${options.period.label} must be a whole number between ${options.period.min} and ${options.period.max}`,\r\n },\r\n }\r\n }\r\n\r\n getIsValid(key: string): boolean {\r\n switch (key) {\r\n case 'period':\r\n return this.getIsNumberInputValid({ key })\r\n default:\r\n return false\r\n }\r\n }\r\n}\r\n\r\nexport default ATR\r\n","import { IndicatorType } from '../../constants/common'\r\nimport IndicatorBaseConfig from './indicatorBaseConfig'\r\n\r\nexport type Options = {\r\n period: number\r\n}\r\n\r\nexport type Attrs = Options\r\n\r\nexport class CCIConfig extends IndicatorBaseConfig {\r\n static type = IndicatorType.Cci\r\n static abbreviation = 'cci'\r\n static label = 'Commodity Channel Index'\r\n static shortLabel = 'CCI'\r\n static optionsOrder = ['period'] as const\r\n static optionsLabels = { period: 'Period' }\r\n static inputsOrder = this.optionsOrder\r\n static inputsLabels = this.optionsLabels\r\n}\r\n","import { Attrs, CCIConfig } from './configs/cci'\r\nimport Indicator from './indicator'\r\n\r\nconst constant = 0.015\r\nclass CommodityChannelIndex extends Indicator {\r\n static config = CCIConfig\r\n\r\n cci: number[] = []\r\n declare period: number\r\n\r\n set(values: Partial) {\r\n super.set(values)\r\n this.parsePeriodInt(values)\r\n }\r\n\r\n compute() {\r\n if (this.isComputeNecessary()) {\r\n let smaCount\r\n const tp = []\r\n this.cci = []\r\n let smaSum = (smaCount = 0)\r\n for (let i = 0; i < this.data.close.length; i++) {\r\n let devCount\r\n const typicalPrice = (this.data.close[i] + this.data.low[i] + this.data.high[i]) / 3\r\n tp[i] = typicalPrice\r\n\r\n smaSum += typicalPrice\r\n smaCount++\r\n if (smaCount > this.period) {\r\n smaSum -= tp[i - this.period]\r\n smaCount--\r\n }\r\n const sma = smaSum / smaCount\r\n\r\n if (i < this.period - 1) {\r\n continue\r\n }\r\n\r\n let devSum = (devCount = 0)\r\n for (let j = i - this.period + 1; j <= i; j++) {\r\n devSum += Math.abs(tp[j] - sma)\r\n devCount++\r\n }\r\n\r\n const dev = devSum / devCount\r\n this.cci[i] = 0\r\n if (dev > 0) {\r\n this.cci[i] = (typicalPrice - sma) / (constant * dev)\r\n }\r\n }\r\n\r\n this.lastValue = this.cci.last() ?? null\r\n }\r\n\r\n const { min, max } = this.cci.length > 0 ? this.computeVisibleMinMax(this.cci) : this.getDomainDefaults(this.type)\r\n this.min = min\r\n this.max = max\r\n }\r\n\r\n getValueLabelsAtIndex(index: number) {\r\n return this.getOversoldOverboughtValueLabelsAtIndex(index, this.cci)\r\n }\r\n\r\n renderIndicator(context: CanvasRenderingContext2D) {\r\n this.renderOversoldOverbought(context, this.cci, this.period, -100, 0, 100)\r\n }\r\n\r\n getModalConfig() {\r\n const options = {\r\n period: {\r\n type: 'number',\r\n label: 'Period',\r\n name: 'period',\r\n value: this.period ?? 20,\r\n required: true,\r\n min: 1,\r\n max: 999999,\r\n },\r\n }\r\n\r\n return {\r\n title: CCIConfig.label,\r\n inputs: CCIConfig.inputsOrder.map((item) => options[item]),\r\n inputsErrorMessages: {\r\n period: `${options.period.label} must be a whole number between ${options.period.min} and ${options.period.max}`,\r\n },\r\n }\r\n }\r\n\r\n getIsValid(key: string): boolean {\r\n switch (key) {\r\n case 'period':\r\n return this.getIsNumberInputValid({ key })\r\n default:\r\n return false\r\n }\r\n }\r\n}\r\n\r\nexport default CommodityChannelIndex\r\n","import { IndicatorType } from '../../constants/common'\r\nimport IndicatorBaseConfig from './indicatorBaseConfig'\r\n\r\nexport type Attrs = {\r\n period: string\r\n code: string\r\n}\r\n\r\nexport class COTConfig extends IndicatorBaseConfig {\r\n static type = IndicatorType.Cot\r\n static abbreviation = 'cot'\r\n static label = 'COT'\r\n static shortLabel = 'CCI'\r\n}\r\n","import * as d3 from 'd3'\r\n\r\nimport { Theme } from '../../types/shared'\r\nimport Text from '../canvas/text'\r\nimport tailwindColors from '../constants/colors'\r\nimport { INDICATOR_LABEL_HEIGHT, TextAlign, TextBaseline } from '../constants/common'\r\nimport utils from '../utils'\r\nimport { drawInVisibleArea } from '../utils/draw_in_visible_area'\r\nimport { Attrs, COTConfig } from './configs/cot'\r\nimport Indicator from './indicator'\r\n\r\nexport interface ICOT {\r\n code: string\r\n name: string\r\n units: string\r\n commercialHedgers: number[]\r\n largeTraders: number[]\r\n smallTraders: number[]\r\n}\r\n\r\ntype ColorsKeys = keyof Pick\r\n\r\nclass COT extends Indicator {\r\n static config = COTConfig\r\n\r\n static getNumOfBarsBuffer() {\r\n return 0\r\n }\r\n\r\n compute() {\r\n if (!this.isComputeNecessary() || !this.data.COTs) return\r\n const cotQuoteCode = Object.keys(this.data.COTs)[0]\r\n if (!this.attrs.code && cotQuoteCode) {\r\n this.attrs.code = cotQuoteCode\r\n }\r\n const cot = this.data.COTs[this.attrs.code]\r\n const [min, max] = utils.minMax(cot.commercialHedgers, cot.largeTraders, cot.smallTraders)\r\n this.max = Math.max(Math.abs(max), Math.abs(min))\r\n this.min = -this.max\r\n }\r\n\r\n getLineColors() {\r\n const isDarkMode = this.model.chart().chart_layout().theme === Theme.dark\r\n return {\r\n commercialHedgers: tailwindColors.green[400],\r\n largeTraders: tailwindColors.red[400],\r\n smallTraders: tailwindColors.blue[isDarkMode ? 300 : 500],\r\n }\r\n }\r\n\r\n getValueLabelsAtIndex(index: number) {\r\n if (!this.data.COTs) return []\r\n const colors = this.getLineColors()\r\n\r\n return Object.keys(colors).map((key) => {\r\n const data = this.data.COTs[this.attrs.code][key as ColorsKeys]\r\n return {\r\n color: colors[key as ColorsKeys],\r\n text: this.getValueLabel(data[index]),\r\n }\r\n })\r\n }\r\n\r\n renderIndicator(context: CanvasRenderingContext2D) {\r\n if (!this.data.COTs) return\r\n context.translate(0.5, 0.5)\r\n const colors = this.getLineColors()\r\n for (const key in colors) {\r\n context.set('strokeStyle', colors[key as ColorsKeys])\r\n context.beginPath()\r\n const data = this.data.COTs[this.attrs.code][key as ColorsKeys]\r\n drawInVisibleArea({\r\n quote: this.data,\r\n paneModel: this.model,\r\n leftOffset: this.leftOffset,\r\n width: this.width,\r\n drawBarCallback: (i: number, x: number) => {\r\n context.lineTo(x, Math.round(this.fy(data[i])))\r\n },\r\n })\r\n context.stroke()\r\n }\r\n context.translate(-0.5, -0.5)\r\n }\r\n\r\n renderLabel(context: CanvasRenderingContext2D) {\r\n if (!this.data.COTs) return\r\n const { ChartSettings } = this.getChartLayoutSettings()\r\n const { Colors } = ChartSettings.general\r\n const name = new Text(\r\n {\r\n text: this.toString(),\r\n x: 8,\r\n y: 16,\r\n font: { size: 10, style: 'bold' },\r\n fillStyle: Colors.text,\r\n textAlign: TextAlign.left,\r\n textBaseline: TextBaseline.bottom,\r\n },\r\n this.model\r\n )\r\n name.render(context)\r\n const secondarylabelX = 38 + name.measure()\r\n const secondarylabel = new Text(\r\n {\r\n text: this.data.COTs[this.attrs.code].units as string,\r\n x: secondarylabelX,\r\n y: 16,\r\n font: { size: 8 },\r\n fillStyle: Colors.text,\r\n textAlign: TextAlign.left,\r\n textBaseline: TextBaseline.bottom,\r\n },\r\n this.model\r\n )\r\n\r\n this.labelWidth = secondarylabelX + 8 + secondarylabel.measure(context)\r\n secondarylabel.render(context)\r\n\r\n this.renderAdditionalLabels(context)\r\n }\r\n\r\n renderLabelChartsPage(context: CanvasRenderingContext2D) {\r\n const { x, y, labelWidth } = super.renderLabelChartsPage(context) as { x: number; y: number; labelWidth: number }\r\n\r\n const { IndicatorSettings } = this.getChartLayoutSettings()\r\n const isDarkMode = this.model.chart().chart_layout().theme === Theme.dark\r\n const secondarylabelX = labelWidth + x * 2\r\n const fontSettings = IndicatorSettings.left.indicatorLabel.font\r\n const scaleCoefficient = 0.7\r\n\r\n const secondarylabel = new Text(\r\n {\r\n text: this.data.COTs[this.attrs.code].units as string,\r\n x: secondarylabelX + x,\r\n font: Text.getMergedPropsWithDefaults('font', {\r\n ...fontSettings,\r\n size: fontSettings.size ? fontSettings.size * scaleCoefficient : undefined,\r\n style: 'normal',\r\n }),\r\n fillStyle: tailwindColors.gray[isDarkMode ? 50 : 900],\r\n textAlign: TextAlign.left,\r\n textBaseline: TextBaseline.middle,\r\n },\r\n this.model\r\n )\r\n secondarylabel.set({\r\n y: y + (INDICATOR_LABEL_HEIGHT * scaleCoefficient - (secondarylabel.attrs.lineHeight * scaleCoefficient) / 2),\r\n })\r\n this.labelWidth = secondarylabelX + x + secondarylabel.measure(context)\r\n secondarylabel.render(context)\r\n\r\n this.renderAdditionalLabels(context)\r\n }\r\n\r\n renderAdditionalLabels(context: CanvasRenderingContext2D) {\r\n const { ChartSettings, IndicatorSettings } = this.getChartLayoutSettings()\r\n const { Colors } = ChartSettings.general\r\n const colors = this.getLineColors()\r\n\r\n new Text(\r\n {\r\n text: 'COT',\r\n x: 23,\r\n y: IndicatorSettings.top.height + (IndicatorSettings.bottom.height + this.contentHeight) / 2,\r\n angle: -90,\r\n font: { size: 10, weight: '900', family: 'Lato, sans-serif' },\r\n fillStyle: Colors.textSecondary,\r\n textAlign: TextAlign.center,\r\n textBaseline: TextBaseline.alphabetic,\r\n },\r\n this.model\r\n ).render(context)\r\n\r\n const text = new Text(\r\n {\r\n text: 'Commercial Hedgers',\r\n x: IndicatorSettings.left.width,\r\n y: IndicatorSettings.top.height + this.contentHeight + IndicatorSettings.bottom.height - 1, // allign to very bottom of indicator with 1 pixel bottom padding\r\n font: { size: 8, style: 'bold' },\r\n fillStyle: colors.commercialHedgers,\r\n textAlign: TextAlign.left,\r\n textBaseline: TextBaseline.bottom,\r\n },\r\n this.model\r\n )\r\n text.render(context)\r\n\r\n let x = text.get('x')! + 8 + text.measure()\r\n text.set({ text: 'Large Traders', x, fillStyle: colors.largeTraders })\r\n text.render(context)\r\n\r\n x += 8 + text.measure()\r\n text.set({ text: 'Small Traders', x, fillStyle: colors.smallTraders })\r\n text.render(context)\r\n }\r\n\r\n formatAxis(value: number) {\r\n // https://github.com/d3/d3-format/blob/master/README.md#locale_formatPrefix\r\n const scaleY = this.model.scale.y as unknown as d3.ScaleLinear\r\n return scaleY.tickFormat(4, 's')(value).replace(/G/, 'B')\r\n }\r\n\r\n getModalConfig() {\r\n return {\r\n title: COTConfig.label,\r\n inputs: [],\r\n inputsErrorMessages: {},\r\n }\r\n }\r\n\r\n toString() {\r\n return this.data?.COTs ? (this.data.COTs[this.attrs.code].name as string) : ''\r\n }\r\n\r\n toConfig(): T['attrs'] & { type: T['type'] } {\r\n return {\r\n type: this.type,\r\n code: this.attrs.code,\r\n }\r\n }\r\n}\r\n\r\nexport default COT\r\n","import { IndicatorType } from '../../constants/common'\r\nimport IndicatorBaseConfig from './indicatorBaseConfig'\r\n\r\nexport type Options = {\r\n period: number\r\n}\r\n\r\nexport type Attrs = Options\r\n\r\nexport class FIConfig extends IndicatorBaseConfig {\r\n static type = IndicatorType.Fi\r\n static abbreviation = 'fi'\r\n static label = 'Force Index'\r\n static shortLabel = 'FORCE'\r\n static optionsOrder = ['period'] as const\r\n static optionsLabels = { period: 'Period' }\r\n static inputsOrder = this.optionsOrder\r\n static inputsLabels = this.optionsLabels\r\n static calculatedValuesOrder = ['fi'] as const\r\n static calculatedValuesLabels = { fi: 'Force Index' }\r\n static defaultCalculatedValueOption = this.calculatedValuesOrder[0]\r\n}\r\n","import { Attrs, FIConfig } from '../indicators/configs/fi'\r\nimport { ExponentialMovingAverage } from './ema'\r\nimport { MainCalculation, OnValueCalculated } from './main'\r\n\r\ntype DefaultCalculatedValuesType = {\r\n fi: number[]\r\n}\r\n\r\nexport class FICalculation extends MainCalculation {\r\n static config = FIConfig\r\n\r\n calculate(onValueCalculated?: OnValueCalculated) {\r\n const { period } = this.options\r\n const { close, volume } = this.quote\r\n const ema = new ExponentialMovingAverage(period)\r\n this._calculatedValues = this.getDefaultCalculatedValues()\r\n\r\n for (let index = 1; index < close.length; index++) {\r\n const value = ((close[index] - close[index - 1]) * volume[index]) / 1000000\r\n ema.add(value)\r\n this.calculatedValues.fi[index] = ema.value\r\n\r\n if (onValueCalculated?.(this.calculatedValues, index) === false) {\r\n break\r\n }\r\n }\r\n }\r\n}\r\n","import { FICalculation } from '../indicator-calculation/fi'\r\nimport { Attrs, FIConfig } from './configs/fi'\r\nimport Indicator from './indicator'\r\n\r\nclass ForceIndex extends Indicator {\r\n static config = FIConfig\r\n\r\n fiCalculation: FICalculation | null = null\r\n declare period: number\r\n\r\n set(values: Partial) {\r\n super.set(values)\r\n this.parsePeriodInt(values)\r\n }\r\n\r\n compute() {\r\n if (this.isComputeNecessary()) {\r\n this.fiCalculation = new FICalculation({\r\n quote: this.data,\r\n options: {\r\n period: this.period,\r\n },\r\n })\r\n this.fiCalculation.calculate()\r\n this.lastValue = this.fiCalculation.calculatedValues.fi.last() ?? null\r\n }\r\n const fi = this.fiCalculation?.calculatedValues.fi ?? []\r\n const { min, max } = fi.length > 0 ? this.computeVisibleMinMax(fi) : this.getDomainDefaults(this.type)\r\n this.min = min\r\n this.max = max\r\n }\r\n\r\n getValueLabelsAtIndex(index: number) {\r\n return this.getOversoldOverboughtValueLabelsAtIndex(index, this.fiCalculation?.calculatedValues.fi ?? [])\r\n }\r\n\r\n renderIndicator(context: CanvasRenderingContext2D) {\r\n this.renderOversoldOverbought(context, this.fiCalculation?.calculatedValues.fi ?? [], 1, 0, 0, 0, false)\r\n }\r\n\r\n getModalConfig() {\r\n const options = {\r\n period: {\r\n type: 'number',\r\n label: 'Period',\r\n name: 'period',\r\n value: this.period ?? 13,\r\n required: true,\r\n min: 1,\r\n max: 999999,\r\n },\r\n }\r\n\r\n return {\r\n title: FIConfig.label,\r\n inputs: FIConfig.inputsOrder.map((item) => options[item]),\r\n inputsErrorMessages: {\r\n period: `${options.period.label} must be a whole number between ${options.period.min} and ${options.period.max}`,\r\n },\r\n }\r\n }\r\n\r\n getIsValid(key: string): boolean {\r\n switch (key) {\r\n case 'period':\r\n return this.getIsNumberInputValid({ key })\r\n default:\r\n return false\r\n }\r\n }\r\n}\r\n\r\nexport default ForceIndex\r\n","import { IndicatorType } from '../../constants/common'\r\nimport IndicatorBaseConfig from './indicatorBaseConfig'\r\n\r\nexport type Options = {\r\n fastPeriod: number\r\n slowPeriod: number\r\n signalPeriod: number\r\n}\r\n\r\nexport interface Attrs extends Options {\r\n period: string\r\n}\r\n\r\nexport class MACDConfig extends IndicatorBaseConfig {\r\n static type = IndicatorType.Macd\r\n static abbreviation = 'macd'\r\n static label = 'MACD'\r\n static shortLabel = 'MACD'\r\n static optionsOrder = ['fastPeriod', 'slowPeriod', 'signalPeriod'] as const\r\n static optionsLabels = { fastPeriod: 'Period', slowPeriod: 'Slow', signalPeriod: 'Signal' }\r\n static inputsOrder = this.optionsOrder\r\n static inputsLabels = this.optionsLabels\r\n static calculatedValuesOrder = ['macd', 'signal', 'histogram'] as const\r\n static calculatedValuesLabels = { macd: 'MACD Line', signal: 'Signal', histogram: 'Histogram' }\r\n static defaultCalculatedValueOption = this.calculatedValuesOrder[0]\r\n}\r\n","import { MACDConfig, Options } from '../indicators/configs/macd'\r\nimport { ExponentialMovingAverage } from './ema'\r\nimport { MainCalculation, OnValueCalculated } from './main'\r\n\r\ntype DefaultCalculatedValuesType = {\r\n macd: number[]\r\n signal: number[]\r\n histogram: number[]\r\n}\r\n\r\nexport class MACDCalculation extends MainCalculation {\r\n static config = MACDConfig\r\n\r\n calculate(onValueCalculated?: OnValueCalculated) {\r\n const { close } = this.quote\r\n const { fastPeriod, slowPeriod, signalPeriod } = this.options\r\n const emaFast = new ExponentialMovingAverage(fastPeriod)\r\n const emaSlow = new ExponentialMovingAverage(slowPeriod)\r\n const emaSignal = new ExponentialMovingAverage(signalPeriod)\r\n this._calculatedValues = this.getDefaultCalculatedValues()\r\n\r\n for (let i = 0; i < close.length; i++) {\r\n const d = close[i]\r\n\r\n emaFast.add(d)\r\n emaSlow.add(d)\r\n const macd = emaFast.value - emaSlow.value\r\n emaSignal.add(macd)\r\n\r\n this.calculatedValues.macd[i] = macd\r\n this.calculatedValues.signal[i] = emaSignal.value\r\n this.calculatedValues.histogram[i] = macd - emaSignal.value\r\n\r\n if (onValueCalculated?.(this.calculatedValues, i) === false) {\r\n break\r\n }\r\n }\r\n }\r\n}\r\n","import { ChartConfigChartPaneElement, RequireByKey } from '../../types/shared'\r\nimport { MACDCalculation } from '../indicator-calculation/macd'\r\nimport { getBarWidthWithMarginByParts } from '../utils/chart'\r\nimport { drawInVisibleArea } from '../utils/draw_in_visible_area'\r\nimport { getParsedIntegersFromPeriodString } from '../utils/helpers'\r\nimport { Attrs, MACDConfig } from './configs/macd'\r\nimport Indicator from './indicator'\r\n\r\nclass MACD extends Indicator {\r\n static config = MACDConfig\r\n\r\n static getNumOfBarsBuffer({ period }: RequireByKey) {\r\n const [fastPeriod = 0, slowPeriod = 0, signalPeriod = 0] = getParsedIntegersFromPeriodString(period)\r\n return Math.max(fastPeriod, slowPeriod, signalPeriod)\r\n }\r\n\r\n macdCalculation: MACDCalculation | null = null\r\n\r\n declare fastPeriod: number\r\n declare slowPeriod: number\r\n declare signalPeriod: number\r\n\r\n set(values: Partial) {\r\n if (typeof values.period === 'string') {\r\n const [fastPeriod = 0, slowPeriod = 0, signalPeriod = 0] = getParsedIntegersFromPeriodString(this.attrs.period)\r\n super.set({ ...values, fastPeriod, slowPeriod, signalPeriod })\r\n } else {\r\n super.set(values)\r\n }\r\n }\r\n\r\n compute() {\r\n if (this.isComputeNecessary() || this.macdCalculation === null) {\r\n this.macdCalculation = new MACDCalculation({\r\n quote: this.data,\r\n options: {\r\n signalPeriod: this.signalPeriod,\r\n fastPeriod: this.fastPeriod,\r\n slowPeriod: this.slowPeriod,\r\n },\r\n })\r\n this.macdCalculation.calculate()\r\n\r\n this.lastValue = this.macdCalculation.calculatedValues.macd.last() ?? null\r\n }\r\n\r\n const { macd, histogram, signal } = this.macdCalculation.calculatedValues\r\n\r\n const { min, max } =\r\n macd.length > 0 || signal.length > 0 || histogram.length > 0\r\n ? this.computeVisibleMinMax(macd, signal, histogram)\r\n : this.getDomainDefaults(this.type)\r\n this.min = min\r\n this.max = max\r\n }\r\n\r\n getLineColors() {\r\n const { IndicatorSettings } = this.getChartLayoutSettings()\r\n return {\r\n histogram: '#79c3e8',\r\n macd: IndicatorSettings.general.Colors.line,\r\n signal: IndicatorSettings.general.Colors.signalLine,\r\n }\r\n }\r\n\r\n getValueLabelsAtIndex(index: number) {\r\n if (this.macdCalculation === null || this.data.close.length === 0) return []\r\n\r\n const lineColors = this.getLineColors()\r\n const { macd, histogram, signal } = this.macdCalculation.calculatedValues\r\n const dataIndex = this.data.barToDataIndex[index]\r\n return [\r\n { color: lineColors.histogram, text: this.getValueLabel(histogram[dataIndex]) },\r\n { color: lineColors.macd, text: this.getValueLabel(macd[dataIndex]) },\r\n { color: lineColors.signal, text: this.getValueLabel(signal[dataIndex]) },\r\n ]\r\n }\r\n\r\n renderIndicator(context: CanvasRenderingContext2D) {\r\n if (this.macdCalculation === null || this.data.close.length === 0) return\r\n const lineColors = this.getLineColors()\r\n const y = Math.round(this.fy(0))\r\n const chartModel = this.model.chart()\r\n const { zoomFactor } = chartModel\r\n const { barFillWidth, barBorderWidth } = getBarWidthWithMarginByParts({\r\n zoomFactor,\r\n chartLayout: chartModel.chart_layout(),\r\n })\r\n const barWidthWithoutMargin = barFillWidth + barBorderWidth * 2\r\n const halfBarWidth = ~~Math.max(1, barWidthWithoutMargin / 2)\r\n const { macd, histogram, signal } = this.macdCalculation.calculatedValues\r\n const drawInVisibleAreaProps = {\r\n quote: this.data,\r\n paneModel: this.model,\r\n leftOffset: this.leftOffset,\r\n width: this.width,\r\n }\r\n\r\n context.set('fillStyle', lineColors.histogram)\r\n context.beginPath()\r\n drawInVisibleArea({\r\n ...drawInVisibleAreaProps,\r\n drawBarCallback: (i, x) => {\r\n context.rect(x - halfBarWidth, y, barWidthWithoutMargin, Math.round(this.fy(histogram[i]) - y))\r\n },\r\n })\r\n context.fill()\r\n\r\n context.translate(0.5, 0.5)\r\n context.set('strokeStyle', lineColors.macd)\r\n context.beginPath()\r\n\r\n drawInVisibleArea({\r\n ...drawInVisibleAreaProps,\r\n drawBarCallback: (i, x) => {\r\n context.lineTo(x, Math.round(this.fy(macd[i])))\r\n },\r\n })\r\n context.stroke()\r\n\r\n context.set('strokeStyle', lineColors.signal)\r\n context.beginPath()\r\n drawInVisibleArea({\r\n ...drawInVisibleAreaProps,\r\n drawBarCallback: (i, x) => {\r\n context.lineTo(x, Math.round(this.fy(signal[i])))\r\n },\r\n })\r\n context.stroke()\r\n context.translate(-0.5, -0.5)\r\n }\r\n\r\n getModalConfig() {\r\n const options = {\r\n fastPeriod: {\r\n type: 'number',\r\n label: 'Period',\r\n name: 'fastPeriod',\r\n value: this.fastPeriod ?? 12,\r\n required: true,\r\n min: 1,\r\n max: 999999,\r\n },\r\n slowPeriod: {\r\n type: 'number',\r\n label: 'Slow',\r\n name: 'slowPeriod',\r\n value: this.slowPeriod ?? 26,\r\n required: true,\r\n min: 1,\r\n max: 999999,\r\n },\r\n signalPeriod: {\r\n type: 'number',\r\n label: 'Signal',\r\n name: 'signalPeriod',\r\n value: this.signalPeriod ?? 9,\r\n required: true,\r\n min: 1,\r\n max: 999999,\r\n },\r\n }\r\n\r\n return {\r\n title: MACDConfig.label,\r\n inputs: MACDConfig.inputsOrder.map((item) => options[item]),\r\n inputsErrorMessages: {\r\n fastPeriod: `${options.fastPeriod.label} must be a whole number between ${options.fastPeriod.min} and ${options.fastPeriod.max}`,\r\n slowPeriod: `${options.slowPeriod.label} must be a whole number between ${options.slowPeriod.min} and ${options.slowPeriod.max}`,\r\n signalPeriod: `${options.signalPeriod.label} must be a whole number between ${options.signalPeriod.min} and ${options.signalPeriod.max}`,\r\n },\r\n }\r\n }\r\n\r\n getIsValid(key: string): boolean {\r\n switch (key) {\r\n case 'fastPeriod':\r\n case 'slowPeriod':\r\n case 'signalPeriod':\r\n return this.getIsNumberInputValid({ key })\r\n default:\r\n return false\r\n }\r\n }\r\n}\r\n\r\nexport default MACD\r\n","import { IndicatorType } from '../../constants/common'\r\nimport IndicatorBaseConfig from './indicatorBaseConfig'\r\n\r\nexport type Options = {\r\n period: number\r\n}\r\n\r\nexport type Attrs = Options\r\n\r\nexport class MFIConfig extends IndicatorBaseConfig {\r\n static type = IndicatorType.Mfi\r\n static abbreviation = 'mfi'\r\n static label = 'Money Flow Index'\r\n static shortLabel = 'MFI'\r\n static optionsOrder = ['period'] as const\r\n static optionsLabels = { period: 'Period' }\r\n static inputsOrder = this.optionsOrder\r\n static inputsLabels = this.optionsLabels\r\n}\r\n","import { Attrs, MFIConfig } from './configs/mfi'\r\nimport Indicator from './indicator'\r\n\r\nclass MFI extends Indicator {\r\n static config = MFIConfig\r\n\r\n mfi: number[] = []\r\n declare period: number\r\n\r\n set(values: Partial) {\r\n super.set(values)\r\n this.parsePeriodInt(values)\r\n }\r\n\r\n compute() {\r\n if (!this.isComputeNecessary()) return\r\n\r\n let negativeMoneyFlow\r\n const mf = []\r\n this.mfi = []\r\n let prevTypicalPrice = (this.data.close[0] + this.data.low[0] + this.data.high[0]) / 3\r\n let positiveMoneyFlow = (negativeMoneyFlow = 0)\r\n for (let i = 1; i < this.data.close.length; i++) {\r\n const typicalPrice = (this.data.close[i] + this.data.low[i] + this.data.high[i]) / 3\r\n const moneyFlow = typicalPrice * this.data.volume[i]\r\n\r\n if (typicalPrice > prevTypicalPrice) {\r\n positiveMoneyFlow += moneyFlow\r\n mf[i] = moneyFlow\r\n } else if (typicalPrice < prevTypicalPrice) {\r\n negativeMoneyFlow += moneyFlow\r\n mf[i] = -moneyFlow\r\n }\r\n\r\n if (i > this.period) {\r\n const oldMF = mf[i - this.period]\r\n if (oldMF > 0) {\r\n positiveMoneyFlow -= oldMF\r\n } else if (oldMF < 0) {\r\n negativeMoneyFlow += oldMF\r\n }\r\n\r\n if (positiveMoneyFlow + negativeMoneyFlow > 0) {\r\n this.mfi[i] = (positiveMoneyFlow * 100) / (positiveMoneyFlow + negativeMoneyFlow)\r\n } else {\r\n this.mfi[i] = 50\r\n }\r\n }\r\n\r\n prevTypicalPrice = typicalPrice\r\n }\r\n\r\n this.lastValue = this.mfi.last() ?? null\r\n const { min, max } = this.getDomainDefaults(this.type)\r\n this.min = min\r\n this.max = max\r\n }\r\n\r\n getValueLabelsAtIndex(index: number) {\r\n return this.getOversoldOverboughtValueLabelsAtIndex(index, this.mfi)\r\n }\r\n\r\n renderIndicator(context: CanvasRenderingContext2D) {\r\n this.renderOversoldOverbought(context, this.mfi, this.period, 20, 50, 80)\r\n }\r\n\r\n getModalConfig() {\r\n const options = {\r\n period: {\r\n type: 'number',\r\n label: 'Period',\r\n name: 'period',\r\n value: this.period ?? 14,\r\n required: true,\r\n min: 1,\r\n max: 999999,\r\n },\r\n }\r\n\r\n return {\r\n title: MFIConfig.label,\r\n inputs: MFIConfig.inputsOrder.map((item) => options[item]),\r\n inputsErrorMessages: {\r\n period: `${options.period.label} must be a whole number between ${options.period.min} and ${options.period.max}`,\r\n },\r\n }\r\n }\r\n\r\n getIsValid(key: string): boolean {\r\n switch (key) {\r\n case 'period':\r\n return this.getIsNumberInputValid({ key })\r\n default:\r\n return false\r\n }\r\n }\r\n}\r\n\r\nexport default MFI\r\n","import { IndicatorType } from '../../constants/common'\r\nimport IndicatorBaseConfig from './indicatorBaseConfig'\r\n\r\nexport class NoneConfig extends IndicatorBaseConfig {\r\n static type = IndicatorType.None\r\n static abbreviation = 'none'\r\n static label = 'None'\r\n static shortLabel = 'None'\r\n}\r\n","import { NoneConfig } from './configs/none'\r\nimport Indicator from './indicator'\r\n\r\nclass None extends Indicator {\r\n static config = NoneConfig\r\n\r\n compute() {}\r\n\r\n renderIndicator() {}\r\n\r\n toString() {\r\n return ''\r\n }\r\n}\r\n\r\nexport default None\r\n","import { IndicatorType } from '../../constants/common'\r\nimport IndicatorBaseConfig from './indicatorBaseConfig'\r\n\r\nexport class OBVConfig extends IndicatorBaseConfig {\r\n static type = IndicatorType.Obv\r\n static abbreviation = 'obv'\r\n static label = 'On-Balance Volume'\r\n static shortLabel = 'OBV'\r\n}\r\n","import math from '../helpers/math'\r\nimport { drawInVisibleArea } from '../utils/draw_in_visible_area'\r\nimport { OBVConfig } from './configs/obv'\r\nimport Indicator from './indicator'\r\n\r\nclass OBV extends Indicator {\r\n static config = OBVConfig\r\n\r\n obv: number[] = []\r\n\r\n compute() {\r\n if (this.isComputeNecessary()) {\r\n this.obv = [0]\r\n\r\n for (let i = 1; i < this.data.volume.length; i++) {\r\n let currentObv = this.obv[i - 1]\r\n if (this.data.close[i] > this.data.close[i - 1]) {\r\n currentObv += this.data.volume[i]\r\n } else if (this.data.close[i] < this.data.close[i - 1]) {\r\n currentObv -= this.data.volume[i]\r\n }\r\n\r\n this.obv[i] = currentObv\r\n }\r\n\r\n this.lastValue = this.obv.last() ?? null\r\n }\r\n const { min, max } = this.obv.length > 0 ? this.computeVisibleMinMax(this.obv) : this.getDomainDefaults(this.type)\r\n this.min = min\r\n this.max = max\r\n }\r\n\r\n getValueLabelsAtIndex(index: number) {\r\n const dataIndex = this.data.barToDataIndex[index]\r\n return [\r\n {\r\n color: this.getChartLayoutSettings().IndicatorSettings.general.Colors.line!,\r\n text: this.getValueLabel(this.obv[dataIndex]),\r\n },\r\n ]\r\n }\r\n\r\n renderIndicator(context: CanvasRenderingContext2D) {\r\n context.set('strokeStyle', this.getChartLayoutSettings().IndicatorSettings.general.Colors.line)\r\n context.translate(0.5, 0.5)\r\n context.beginPath()\r\n drawInVisibleArea({\r\n quote: this.data,\r\n paneModel: this.model,\r\n leftOffset: this.leftOffset,\r\n width: this.width,\r\n drawBarCallback: (i: number, x: number) => {\r\n context.lineTo(x, Math.round(this.fy(this.obv[i])))\r\n },\r\n })\r\n context.stroke()\r\n context.translate(-0.5, -0.5)\r\n }\r\n\r\n formatAxis(value: number) {\r\n return math.formatBigNumber(value, 2)\r\n }\r\n\r\n getModalConfig() {\r\n return {\r\n title: OBVConfig.label,\r\n inputs: [],\r\n inputsErrorMessages: {},\r\n }\r\n }\r\n}\r\n\r\nexport default OBV\r\n","import { IndicatorType } from '../../constants/common'\r\nimport IndicatorBaseConfig from './indicatorBaseConfig'\r\n\r\nexport type Options = {\r\n period: string\r\n}\r\n\r\nexport interface Attrs extends Options {\r\n tickers?: string\r\n}\r\n\r\nexport class PerfConfig extends IndicatorBaseConfig {\r\n static type = IndicatorType.Perf\r\n static abbreviation = 'perf'\r\n static label = 'Price Performance %'\r\n static shortLabel = 'PERF %'\r\n static optionsOrder = ['tickers'] as const\r\n static optionsLabels = { tickers: 'Tickers' }\r\n static inputsOrder = this.optionsOrder\r\n static inputsLabels = this.optionsLabels\r\n}\r\n","import * as d3 from 'd3'\r\n\r\nimport { ObjectHash } from '../../types/shared'\r\nimport Line from '../canvas/line'\r\nimport Text from '../canvas/text'\r\nimport {\r\n INDICATOR_LABEL_HEIGHT,\r\n MOBILE_VIEW_BREAKPOINT_WIDTH,\r\n OFFSET,\r\n PADDING,\r\n TextAlign,\r\n TextBaseline,\r\n} from '../constants/common'\r\nimport { getTranslate } from '../controllers/renderUtils'\r\nimport Pane from '../models/pane'\r\nimport Quote from '../models/quote'\r\nimport { getSanitizedTicker } from '../utils'\r\nimport { getInstrument } from '../utils/chart'\r\nimport { getHEXWithSpecificAplha } from '../utils/colors'\r\nimport { getVisibleBarToRenderIndex } from '../utils/draw_in_visible_area'\r\nimport { Attrs, PerfConfig } from './configs/perf'\r\nimport Indicator from './indicator'\r\n\r\nconst DEFAULT_TICKERS = 'SPY,QQQ'\r\nconst NO_VALUE = ' - '\r\n\r\ntype PerfData = { lastValueIndex: number; values: Array }\r\nfunction getDefaultPerfData(): PerfData {\r\n return {\r\n lastValueIndex: 0,\r\n values: [],\r\n }\r\n}\r\n\r\nclass PricePerformance extends Indicator {\r\n static config = PerfConfig\r\n\r\n static getNumOfBarsBuffer() {\r\n return 0\r\n }\r\n\r\n timeframe: string\r\n tickers = ''\r\n ready = false\r\n perf: ObjectHash = {}\r\n quotes: ObjectHash = {} // this is used in getAllQuotes() in charts/app/models/chart.ts\r\n indicatorLabelWidth: ObjectHash = {}\r\n\r\n constructor(attrs: Attrs, model: Pane) {\r\n super(attrs, model)\r\n this.renderYAxis = this.renderYAxis.bind(this)\r\n\r\n this.timeframe = this.model.chart().timeframe\r\n this.fy = d3.scaleLinear().range([0, this.contentHeight])\r\n if (this.attrs.period && !this.tickers) {\r\n this.tickers = this.attrs.period\r\n }\r\n }\r\n\r\n async compute() {\r\n const data: ObjectHash = {}\r\n let hasCachedData = true\r\n this.getTickersAndTimeframe().forEach((quoteSettings) => {\r\n const quote = Quote.getFromCacheSync(quoteSettings)\r\n hasCachedData = hasCachedData && !!quote\r\n if (quote) {\r\n data[quoteSettings.ticker] = quote\r\n }\r\n })\r\n\r\n if (hasCachedData) {\r\n return this._compute(Object.keys(data), data)\r\n }\r\n\r\n const fetchedData = await Quote.getAll(this.getTickersAndTimeframe())\r\n if (fetchedData) {\r\n this._compute(Object.keys(fetchedData), fetchedData)\r\n this.trigger('change')\r\n }\r\n }\r\n\r\n _compute(tickers: string[], data: ObjectHash) {\r\n const { leftOffset } = this.model.chart()\r\n data[this.data.ticker] = this.data\r\n this.quotes = data\r\n this.perf = {}\r\n\r\n const firstVisibleBar = getVisibleBarToRenderIndex({\r\n quote: this.data,\r\n leftOffset,\r\n paneModel: this.model,\r\n })\r\n const lastVisibleBar = getVisibleBarToRenderIndex({\r\n quote: this.data,\r\n leftOffset,\r\n paneModel: this.model,\r\n chartWidth: this.contentWidth,\r\n })\r\n\r\n let min: number | null = null\r\n let max: number | null = null\r\n\r\n for (const ticker of [this.data.ticker, ...tickers]) {\r\n this.perf[ticker] = getDefaultPerfData()\r\n const d = data[ticker]\r\n const lastTickerTimestamp = d.date[d.date.length - 1]\r\n if (!d) {\r\n continue\r\n }\r\n const dateToIndex = d.getDateToIndex()\r\n let first = null\r\n let lastValue = null\r\n let dataIndex = -1\r\n for (let i = firstVisibleBar.barIndex; i <= lastVisibleBar.barIndex; i++) {\r\n const timestamp = this.data.getTimestampFomPositionX(i)\r\n dataIndex = dateToIndex[timestamp]\r\n\r\n if (typeof dataIndex === 'number') {\r\n first = first === null ? d.close[dataIndex] : first\r\n lastValue = (d.close[dataIndex] * 100) / (first ?? 0) - 100\r\n }\r\n\r\n this.perf[ticker].values[i] = null\r\n if (lastTickerTimestamp >= timestamp && lastValue !== null && !isNaN(lastValue)) {\r\n this.perf[ticker].values[i] = lastValue\r\n this.perf[ticker].lastValueIndex = i\r\n if (min === null || (lastValue !== null && min > lastValue)) min = lastValue\r\n if (max === null || (lastValue !== null && max < lastValue)) max = lastValue\r\n }\r\n }\r\n\r\n if (firstVisibleBar.barIndex > 0) {\r\n this.perf[ticker].values[firstVisibleBar.barIndex - 1] = this.perf[ticker].values[firstVisibleBar.barIndex]\r\n }\r\n if (lastVisibleBar.barIndex < this.data.barToDataIndex.length) {\r\n this.perf[ticker].values[lastVisibleBar.barIndex + 1] = this.perf[ticker].values[lastVisibleBar.barIndex]\r\n }\r\n }\r\n\r\n // > 2 because we need at least 2 bars to be able to calculate price perf and also we copy first visible bar value\r\n // to its index - 1 to ensure line is drawn from the very left edge of the chart\r\n // so first 2 values are the same and we need one more\r\n const canUseCustomMinMax = Object.values(this.perf).some(\r\n ({ values }) => values.filter((val) => typeof val === 'number').length > 2\r\n )\r\n const domainDefaults = this.getDomainDefaults(this.type)\r\n this.min = canUseCustomMinMax && min !== null ? min : domainDefaults.min\r\n this.max = canUseCustomMinMax && max !== null ? max : domainDefaults.max\r\n\r\n const fy = d3\r\n .scaleLinear()\r\n .range([0, this.contentHeight])\r\n .domain([this.model.scaleRange?.max ?? this.max, this.model.scaleRange?.min ?? this.min])\r\n if (!this.model.scaleRange) {\r\n fy.nice(10)\r\n }\r\n // @ts-expect-error - TODO scale.y types dont match\r\n this.model.scale.y = this.fy = fy\r\n this.ready = true\r\n }\r\n\r\n renderIndicator(context: CanvasRenderingContext2D) {\r\n if (!this.ready) {\r\n return\r\n }\r\n new Line(\r\n {\r\n x1: -this.leftOffset,\r\n x2: -this.leftOffset + this.contentWidth,\r\n y1: Math.round(this.fy(0)),\r\n y2: Math.round(this.fy(0)),\r\n strokeStyle: '#ff8787',\r\n dashLength: 3,\r\n },\r\n this.model\r\n ).render(context)\r\n\r\n context.translate(0.5, 0.5)\r\n\r\n const allTickers = [...this.getTickers(), this.data.ticker]\r\n\r\n allTickers.forEach((ticker) => {\r\n context.set('strokeStyle', this.getTickerColor(ticker))\r\n context.beginPath()\r\n this.perf[ticker].values.forEach((value, index) => {\r\n const y = value !== null ? Math.round(this.fy(value)) : null\r\n if (y !== null && !isNaN(y)) {\r\n context.lineTo(this.model.scale.x(index), y)\r\n }\r\n })\r\n context.stroke()\r\n })\r\n\r\n context.translate(-0.5, -0.5)\r\n }\r\n\r\n renderCrossTextQuotePage(context: CanvasRenderingContext2D, crossIndex: number, hasBackground = true) {\r\n if (!context || isNaN(crossIndex) || !this.ready) {\r\n return\r\n }\r\n const { ChartSettings, IndicatorSettings } = this.getChartLayoutSettings()\r\n const { Colors } = ChartSettings.general\r\n const tickers = [this.data.ticker, ...this.getTickers()]\r\n tickers.forEach((key, index) => {\r\n const tickerValue = this.perf[key]?.values[crossIndex] ?? null\r\n context.fillStyle = hasBackground ? Colors.canvasFill : getHEXWithSpecificAplha(Colors.canvasFill, 0.8)\r\n context.fillRect(\r\n IndicatorSettings.left.indicatorLabel.margin.left! - PADDING.XXXS,\r\n (IndicatorSettings.left.indicatorLabel.font.lineHeight! + IndicatorSettings.left.indicatorLabel.labelSpacing) *\r\n (index + 1) +\r\n IndicatorSettings.left.indicatorLabel.margin.top! -\r\n PADDING.XXXS,\r\n PADDING.XXXS + (this.indicatorLabelWidth[key] ?? 0) + PADDING.XXXS,\r\n PADDING.XXXS + IndicatorSettings.left.indicatorLabel.font.size! + PADDING.XXXS\r\n )\r\n const text = new Text(\r\n {\r\n text: `${key} ${tickerValue !== null ? `${tickerValue.toFixed(2)}%` : NO_VALUE}`,\r\n x: IndicatorSettings.left.indicatorLabel.margin.left,\r\n y:\r\n (IndicatorSettings.left.indicatorLabel.font.lineHeight! +\r\n IndicatorSettings.left.indicatorLabel.labelSpacing) *\r\n (index + 1) +\r\n IndicatorSettings.left.indicatorLabel.margin.top!,\r\n font: Text.getMergedPropsWithDefaults('font', IndicatorSettings.left.indicatorLabel.font),\r\n fillStyle: this.getTickerColor(key),\r\n textAlign: TextAlign.left,\r\n textBaseline: TextBaseline.top,\r\n },\r\n this.model\r\n )\r\n\r\n if (!hasBackground) {\r\n this.indicatorLabelWidth = { ...this.indicatorLabelWidth, [key]: text.measure(context) }\r\n }\r\n text.render(context)\r\n })\r\n }\r\n\r\n renderCrossTextChartsPage(context: CanvasRenderingContext2D, crossIndex: number) {\r\n if (!context || isNaN(crossIndex)) {\r\n return\r\n }\r\n\r\n const { ChartSettings, IndicatorSettings } = this.getChartLayoutSettings()\r\n const { Colors } = ChartSettings.general\r\n let isVertical = true\r\n const labelBottom = IndicatorSettings.left.indicatorLabel.margin.top! + INDICATOR_LABEL_HEIGHT\r\n const tickers = [this.data.ticker, ...this.getTickers()]\r\n const tickerText = new Text(\r\n {\r\n font: Text.getMergedPropsWithDefaults('font', {\r\n ...IndicatorSettings.left.indicatorLabel.font,\r\n style: 'normal',\r\n }),\r\n textAlign: TextAlign.left,\r\n textBaseline: TextBaseline.middle,\r\n background: getHEXWithSpecificAplha(Colors.canvasFill, 0.8),\r\n padding: { top: 0, bottom: 0, left: 5, right: 5 },\r\n },\r\n this.model\r\n )\r\n let x = IndicatorSettings.left.indicatorLabel.margin.left!\r\n let y =\r\n IndicatorSettings.left.indicatorLabel.margin.top! + (2 * INDICATOR_LABEL_HEIGHT - tickerText.attrs.lineHeight) / 2\r\n\r\n const maxHeight = tickerText.attrs.lineHeight * tickers.length\r\n\r\n const canFitItemsVertically = maxHeight + labelBottom <= this.height\r\n if (this.width <= MOBILE_VIEW_BREAKPOINT_WIDTH || !canFitItemsVertically) {\r\n isVertical = false\r\n x += x + this.labelWidth\r\n } else {\r\n y += IndicatorSettings.left.indicatorLabel.margin.top! + INDICATOR_LABEL_HEIGHT\r\n }\r\n\r\n tickers.forEach((key) => {\r\n const tickerValue = this.perf[key]?.values[crossIndex > -1 ? crossIndex : this.perf[key].lastValueIndex] ?? null\r\n tickerText.set({\r\n x,\r\n y,\r\n fillStyle: this.getTickerColor(key),\r\n text: `${key} ${tickerValue !== null ? `${tickerValue.toFixed(2)}%` : NO_VALUE}`,\r\n })\r\n const tickerTextWidth =\r\n tickerText.measure(context) + tickerText.attrs.padding.left + tickerText.attrs.padding.right\r\n if (\r\n !isVertical &&\r\n this.width - IndicatorSettings.left.indicatorLabel.margin.left! - IndicatorSettings.right.width! <=\r\n x + tickerTextWidth\r\n ) {\r\n x = 2 * IndicatorSettings.left.indicatorLabel.margin.left! + this.labelWidth\r\n y += tickerText.attrs.lineHeight\r\n tickerText.set({ x, y })\r\n }\r\n tickerText.render(context)\r\n\r\n if (isVertical) {\r\n y += tickerText.attrs.lineHeight\r\n } else {\r\n x += tickerTextWidth\r\n }\r\n })\r\n }\r\n\r\n getTickerColor(ticker: string) {\r\n const { ChartSettings, ColorsSettings } = this.getChartLayoutSettings()\r\n const { Colors } = ChartSettings.general\r\n\r\n if (ticker === this.data.ticker) {\r\n return Colors.performanceIndicatorLabel\r\n }\r\n\r\n return ColorsSettings[this.getTickers().indexOf(ticker) % ColorsSettings.length]\r\n }\r\n\r\n renderXAxis(context: CanvasRenderingContext2D) {\r\n if (!this.ready) {\r\n return\r\n }\r\n return super.renderXAxis(context)\r\n }\r\n\r\n renderYAxis(context: CanvasRenderingContext2D) {\r\n super.renderYAxis(context)\r\n const { IndicatorSettings, ChartSettings } = this.getChartLayoutSettings()\r\n const { Colors } = ChartSettings.general\r\n if (!this.ready) {\r\n return\r\n }\r\n const translate = getTranslate({\r\n context,\r\n xOffset: IndicatorSettings.left.width,\r\n yOffset: IndicatorSettings.top.height,\r\n })\r\n translate.do()\r\n const { lineHeight, padding, size } = IndicatorSettings.right.axis.font\r\n const text = new Text(\r\n {\r\n x: this.contentWidth + OFFSET.M - padding!.left! + IndicatorSettings.right.axis.margin.left!,\r\n font: Text.getMergedPropsWithDefaults('font', { size }),\r\n lineHeight,\r\n padding: {\r\n left: padding!.left!,\r\n right: padding!.right!,\r\n top: padding!.top!,\r\n bottom: padding!.bottom!,\r\n },\r\n textBaseline: TextBaseline.middle,\r\n fillStyle: Colors.crossText,\r\n },\r\n this.model\r\n )\r\n const allTickers = [...this.getTickers(), this.data.ticker]\r\n\r\n const minY = 0\r\n const maxY = this.contentHeight\r\n allTickers.forEach((ticker) => {\r\n const lastValue = this.perf[ticker]?.values[this.perf[ticker]?.lastValueIndex] ?? null\r\n if (lastValue !== null) {\r\n const labelSetting = {\r\n text: `${lastValue.toFixed(2)}%`,\r\n y: Math.round(this.fy(lastValue)),\r\n background: this.getTickerColor(ticker),\r\n }\r\n if (labelSetting.y >= minY && labelSetting.y <= maxY) {\r\n text.set(labelSetting).render(context)\r\n }\r\n }\r\n })\r\n\r\n translate.undo()\r\n }\r\n\r\n renderLabelQuotePage(context: CanvasRenderingContext2D) {\r\n super.renderLabelQuotePage(context)\r\n this.renderCrossTextQuotePage(context, this.perf[this.data.ticker].lastValueIndex, false)\r\n }\r\n\r\n getTickers() {\r\n return this.tickers\r\n .split(',')\r\n .filter((ticker, i, arr) => ticker && ticker !== this.data.ticker && arr.indexOf(ticker) === i)\r\n }\r\n\r\n getTickersAndTimeframe() {\r\n const chartModel = this.model.chart()\r\n const { timeframe, premarket, aftermarket, hasPatterns } = chartModel.quote()\r\n return this.getTickers().map((ticker) => ({\r\n ticker,\r\n instrument: getInstrument(ticker),\r\n timeframe,\r\n chartUuid: chartModel.chart_layout().uuid,\r\n options: {\r\n premarket,\r\n aftermarket,\r\n patterns: hasPatterns,\r\n },\r\n }))\r\n }\r\n\r\n set(values: Partial) {\r\n super.set({ ...values, tickers: values.period || (values.tickers ? getSanitizedTicker(values.tickers, true) : '') })\r\n this.tickers = (this.tickers || '').toUpperCase()\r\n }\r\n\r\n getModalConfig() {\r\n const options = {\r\n tickers: {\r\n type: 'text',\r\n label: 'Tickers',\r\n name: 'tickers',\r\n value: !!this.tickers ? this.tickers : DEFAULT_TICKERS,\r\n required: true,\r\n },\r\n }\r\n\r\n return {\r\n title: PerfConfig.label,\r\n inputs: PerfConfig.inputsOrder.map((item) => options[item]),\r\n inputsErrorMessages: {\r\n tickers: 'At least one ticker has to be provided',\r\n },\r\n }\r\n }\r\n\r\n getIsValid(key: string): boolean {\r\n switch (key) {\r\n case 'tickers':\r\n return this[key].length > 0\r\n default:\r\n return false\r\n }\r\n }\r\n\r\n toString() {\r\n return this.getIsChartPageSpecificFunctionality() ? PerfConfig.shortLabel : super.toString()\r\n }\r\n}\r\n\r\nexport default PricePerformance\r\n","import { IndicatorType } from '../../constants/common'\r\nimport IndicatorBaseConfig from './indicatorBaseConfig'\r\n\r\nexport type Options = {\r\n period: number | string\r\n momentum: number\r\n}\r\n\r\nexport type Attrs = Options\r\n\r\nexport class RMIConfig extends IndicatorBaseConfig {\r\n static type = IndicatorType.Rmi\r\n static abbreviation = 'rmi'\r\n static label = 'Relative Momentum Index'\r\n static shortLabel = 'RMI'\r\n static optionsOrder = ['period', 'momentum'] as const\r\n static optionsLabels = { period: 'Period', momentum: 'Momentum' }\r\n static inputsOrder = this.optionsOrder\r\n static inputsLabels = this.optionsLabels\r\n}\r\n","import { getParsedIntegersFromPeriodString } from '../utils/helpers'\r\nimport { Attrs, RMIConfig } from './configs/rmi'\r\nimport Indicator from './indicator'\r\n\r\nclass RMI extends Indicator {\r\n static config = RMIConfig\r\n\r\n rmi: number[] = []\r\n declare momentum: number\r\n declare period: number\r\n\r\n set(values: Partial) {\r\n if (typeof values.period === 'string') {\r\n const [period = 0, momentum = 0] = getParsedIntegersFromPeriodString(values.period)\r\n super.set({ ...values, period, momentum })\r\n } else {\r\n super.set(values)\r\n }\r\n }\r\n\r\n compute() {\r\n if (!this.isComputeNecessary()) return\r\n\r\n this.rmi = []\r\n let count = 0\r\n let sumu = 0\r\n let sumd = 0\r\n let u: number, d: number, ad: number, au: number\r\n for (let i = this.momentum; i < this.data.close.length; i++) {\r\n u = d = 0\r\n if (this.data.close[i] > this.data.close[i - this.momentum]) {\r\n u = this.data.close[i] - this.data.close[i - this.momentum]\r\n }\r\n if (this.data.close[i] < this.data.close[i - this.momentum]) {\r\n d = this.data.close[i - this.momentum] - this.data.close[i]\r\n }\r\n\r\n if (count < this.period) {\r\n sumu += u\r\n sumd += d\r\n count++\r\n au = sumu / count\r\n ad = sumd / count\r\n } else {\r\n au = (au! * (this.period - 1) + u) / this.period\r\n ad = (ad! * (this.period - 1) + d) / this.period\r\n }\r\n\r\n const rs = ad > 0 ? au / ad : 1\r\n this.rmi[i] = 100 - 100 * (1 / (1 + rs))\r\n }\r\n\r\n this.lastValue = this.rmi.last() ?? null\r\n const { min, max } = this.getDomainDefaults(this.type)\r\n this.min = min\r\n this.max = max\r\n }\r\n\r\n getValueLabelsAtIndex(index: number) {\r\n return this.getOversoldOverboughtValueLabelsAtIndex(index, this.rmi)\r\n }\r\n\r\n renderIndicator(context: CanvasRenderingContext2D) {\r\n this.renderOversoldOverbought(context, this.rmi, this.momentum, 30, 50, 70)\r\n }\r\n\r\n getModalConfig() {\r\n const options = {\r\n period: {\r\n type: 'number',\r\n label: 'Period',\r\n name: 'period',\r\n value: this.period ?? 20,\r\n required: true,\r\n min: 1,\r\n max: 999999,\r\n },\r\n momentum: {\r\n type: 'number',\r\n label: 'Momentum',\r\n name: 'momentum',\r\n value: this.momentum ?? 5,\r\n required: true,\r\n min: 1,\r\n max: 999999,\r\n },\r\n }\r\n\r\n return {\r\n title: RMIConfig.label,\r\n inputs: RMIConfig.inputsOrder.map((item) => options[item]),\r\n inputsErrorMessages: {\r\n period: `${options.period.label} must be a whole number between ${options.period.min} and ${options.period.max}`,\r\n momentum: `${options.momentum.label} must be a whole number between ${options.momentum.min} and ${options.momentum.max}`,\r\n },\r\n }\r\n }\r\n\r\n getIsValid(key: string): boolean {\r\n switch (key) {\r\n case 'period':\r\n case 'momentum':\r\n return this.getIsNumberInputValid({ key })\r\n default:\r\n return false\r\n }\r\n }\r\n}\r\n\r\nexport default RMI\r\n","import { IndicatorType } from '../../constants/common'\r\nimport IndicatorBaseConfig from './indicatorBaseConfig'\r\n\r\nexport type Options = {\r\n period: number\r\n}\r\n\r\nexport type Attrs = Options\r\n\r\nexport class ROCConfig extends IndicatorBaseConfig {\r\n static type = IndicatorType.Roc\r\n static abbreviation = 'roc'\r\n static label = 'Rate of Change %'\r\n static shortLabel = 'ROC'\r\n static optionsOrder = ['period'] as const\r\n static optionsLabels = { period: 'Period' }\r\n static inputsOrder = this.optionsOrder\r\n static inputsLabels = this.optionsLabels\r\n}\r\n","import Line from '../canvas/line'\r\nimport { drawInVisibleArea } from '../utils/draw_in_visible_area'\r\nimport { Attrs, ROCConfig } from './configs/roc'\r\nimport Indicator from './indicator'\r\n\r\nclass ROC extends Indicator {\r\n static config = ROCConfig\r\n\r\n roc: number[] = []\r\n declare period: number\r\n\r\n set(values: Partial) {\r\n super.set(values)\r\n this.parsePeriodInt(values)\r\n }\r\n\r\n compute() {\r\n if (this.isComputeNecessary()) {\r\n this.roc = []\r\n for (let i = this.period; i < this.data.close.length; i++) {\r\n this.roc[i] = ((this.data.close[i] - this.data.close[i - this.period]) / this.data.close[i - this.period]) * 100\r\n }\r\n\r\n this.lastValue = this.roc.last() ?? null\r\n }\r\n const { min, max } = this.roc.length > 0 ? this.computeVisibleMinMax(this.roc) : this.getDomainDefaults(this.type)\r\n this.min = min\r\n this.max = max\r\n }\r\n\r\n getValueLabelsAtIndex(index: number) {\r\n const dataIndex = this.data.barToDataIndex[index]\r\n return [\r\n {\r\n color: this.getChartLayoutSettings().IndicatorSettings.general.Colors.line!,\r\n text: this.getValueLabel(this.roc[dataIndex]),\r\n },\r\n ]\r\n }\r\n\r\n renderIndicator(context: CanvasRenderingContext2D) {\r\n new Line(\r\n {\r\n x1: -this.leftOffset,\r\n x2: -this.leftOffset + this.contentWidth,\r\n y1: Math.round(this.fy(0)),\r\n y2: Math.round(this.fy(0)),\r\n strokeStyle: '#ff8787',\r\n dashLength: 3,\r\n },\r\n this.model\r\n ).render(context)\r\n context.set('strokeStyle', this.getChartLayoutSettings().IndicatorSettings.general.Colors.line)\r\n context.translate(0.5, 0.5)\r\n context.beginPath()\r\n drawInVisibleArea({\r\n quote: this.data,\r\n paneModel: this.model,\r\n leftOffset: this.leftOffset,\r\n width: this.width,\r\n drawBarCallback: (i: number, x: number) => {\r\n context.lineTo(x, Math.round(this.fy(this.roc[i])))\r\n },\r\n })\r\n context.stroke()\r\n context.translate(-0.5, -0.5)\r\n }\r\n\r\n getModalConfig() {\r\n const options = {\r\n period: {\r\n type: 'number',\r\n label: 'Period',\r\n name: 'period',\r\n value: this.period ?? 12,\r\n required: true,\r\n min: 1,\r\n max: 999999,\r\n },\r\n }\r\n\r\n return {\r\n title: ROCConfig.label,\r\n inputs: ROCConfig.inputsOrder.map((item) => options[item]),\r\n inputsErrorMessages: {\r\n period: `${options.period.label} must be a whole number between ${options.period.min} and ${options.period.max}`,\r\n },\r\n }\r\n }\r\n\r\n getIsValid(key: string): boolean {\r\n switch (key) {\r\n case 'period':\r\n return this.getIsNumberInputValid({ key })\r\n default:\r\n return false\r\n }\r\n }\r\n}\r\n\r\nexport default ROC\r\n","import { IndicatorType } from '../../constants/common'\r\nimport IndicatorBaseConfig from './indicatorBaseConfig'\r\n\r\nexport type Options = {\r\n period: number\r\n}\r\n\r\nexport type Attrs = Options\r\n\r\nexport class RSIConfig extends IndicatorBaseConfig {\r\n static type = IndicatorType.Rsi\r\n static abbreviation = 'rsi'\r\n static label = 'Relative Strength Index'\r\n static shortLabel = 'RSI'\r\n static optionsOrder = ['period'] as const\r\n static optionsLabels = { period: 'Period' }\r\n static inputsOrder = this.optionsOrder\r\n static inputsLabels = this.optionsLabels\r\n static calculatedValuesOrder = ['rsi'] as const\r\n static calculatedValuesLabels = { rsi: 'RSI' }\r\n static defaultCalculatedValueOption = this.calculatedValuesOrder[0]\r\n}\r\n","import { Attrs, RSIConfig } from '../indicators/configs/rsi'\r\nimport { MainCalculation, OnValueCalculated } from './main'\r\n\r\ntype DefaultCalculatedValuesType = {\r\n rsi: number[]\r\n}\r\n\r\nexport class RsiCalculation extends MainCalculation {\r\n static config = RSIConfig\r\n\r\n calculate(onValueCalculated?: OnValueCalculated) {\r\n const { period } = this.options\r\n const { close } = this.quote\r\n this._calculatedValues = this.getDefaultCalculatedValues()\r\n\r\n let sumu = 0\r\n let sumd = 0\r\n let u: number, d: number, ad: number, au: number\r\n for (let i = 1; i < close.length; i++) {\r\n u = d = 0\r\n if (close[i] > close[i - 1]) {\r\n u = close[i] - close[i - 1]\r\n }\r\n if (close[i] < close[i - 1]) {\r\n d = close[i - 1] - close[i]\r\n }\r\n\r\n if (i <= period) {\r\n sumu += u\r\n sumd += d\r\n au = sumu / i\r\n ad = sumd / i\r\n } else {\r\n au = (au! * (period - 1) + u) / period\r\n ad = (ad! * (period - 1) + d) / period\r\n }\r\n\r\n const rs = ad > 0 ? au / ad : 1\r\n this.calculatedValues.rsi[i] = 100 - 100 * (1 / (1 + rs))\r\n\r\n if (onValueCalculated?.(this.calculatedValues, i) === false) {\r\n break\r\n }\r\n }\r\n }\r\n}\r\n","import { RsiCalculation } from '../indicator-calculation/rsi'\r\nimport { Attrs, RSIConfig } from './configs/rsi'\r\nimport Indicator from './indicator'\r\n\r\nclass RSI extends Indicator {\r\n static config = RSIConfig\r\n\r\n rsiCalculation: RsiCalculation | null = null\r\n declare period: number\r\n\r\n set(values: Partial) {\r\n super.set(values)\r\n this.parsePeriodInt(values)\r\n }\r\n\r\n compute() {\r\n if (!this.isComputeNecessary() && this.rsiCalculation !== null) return\r\n\r\n this.rsiCalculation = new RsiCalculation({\r\n quote: this.data,\r\n options: { period: this.period },\r\n })\r\n\r\n this.rsiCalculation.calculate()\r\n\r\n this.lastValue = this.rsiCalculation.calculatedValues.rsi.last() ?? null\r\n const { min, max } = this.getDomainDefaults(this.type)\r\n this.min = min\r\n this.max = max\r\n }\r\n\r\n getValueLabelsAtIndex(index: number) {\r\n return this.getOversoldOverboughtValueLabelsAtIndex(index, this.rsiCalculation?.calculatedValues.rsi ?? [])\r\n }\r\n\r\n renderIndicator(context: CanvasRenderingContext2D) {\r\n this.renderOversoldOverbought(context, this.rsiCalculation?.calculatedValues.rsi ?? [], this.period, 30, 50, 70)\r\n }\r\n\r\n getModalConfig() {\r\n const options = {\r\n period: {\r\n type: 'number',\r\n label: 'Period',\r\n name: 'period',\r\n value: this.period ?? 14,\r\n required: true,\r\n min: 1,\r\n max: 999999,\r\n },\r\n }\r\n\r\n return {\r\n title: RSIConfig.label,\r\n inputs: RSIConfig.inputsOrder.map((item) => options[item]),\r\n inputsErrorMessages: {\r\n period: `${options.period.label} must be a whole number between ${options.period.min} and ${options.period.max}`,\r\n },\r\n }\r\n }\r\n\r\n getIsValid(key: string): boolean {\r\n switch (key) {\r\n case 'period':\r\n return this.getIsNumberInputValid({ key })\r\n default:\r\n return false\r\n }\r\n }\r\n}\r\n\r\nexport default RSI\r\n","import { IndicatorType } from '../../constants/common'\r\nimport IndicatorBaseConfig from './indicatorBaseConfig'\r\n\r\nexport type Options = {\r\n period: number | string\r\n baseLine: number\r\n}\r\n\r\nexport type Attrs = Options\r\n\r\nexport class RVOLConfig extends IndicatorBaseConfig {\r\n static type = IndicatorType.Rvol\r\n static abbreviation = 'rvol'\r\n static label = 'Relative Volume'\r\n static shortLabel = 'RVOL'\r\n static optionsOrder = ['period', 'baseLine'] as const\r\n static optionsLabels = { period: 'Period', baseLine: 'BaseLine' }\r\n static inputsOrder = this.optionsOrder\r\n static inputsLabels = this.optionsLabels\r\n}\r\n","import Line from '../canvas/line'\r\nimport { getBarWidthWithMarginByParts } from '../utils/chart'\r\nimport { getHEXWithSpecificAplha } from '../utils/colors'\r\nimport { drawInVisibleArea } from '../utils/draw_in_visible_area'\r\nimport { Attrs, RVOLConfig } from './configs/rvol'\r\nimport Indicator from './indicator'\r\n\r\nconst DEFAULT_PARAMETERS = {\r\n Period: 50,\r\n BaseLine: 1.0,\r\n}\r\n\r\nfunction parsePeriod(periodStr: string) {\r\n const values = periodStr.split(',')\r\n const period = parseInt(values[0]) || DEFAULT_PARAMETERS.Period\r\n const baseLine = parseFloat(values[1]) || DEFAULT_PARAMETERS.BaseLine\r\n\r\n return [period, baseLine]\r\n}\r\n\r\nclass RelativeVolume extends Indicator {\r\n static config = RVOLConfig\r\n\r\n rvol: number[] = []\r\n declare period: number\r\n declare baseLine: number\r\n\r\n set(values: Partial) {\r\n if (typeof values.period === 'string') {\r\n const [period = 0, baseLine = 0] = parsePeriod(values.period)\r\n super.set({ ...values, period, baseLine })\r\n } else {\r\n super.set(values)\r\n }\r\n }\r\n\r\n compute() {\r\n if (this.isComputeNecessary()) {\r\n this.rvol = []\r\n\r\n let sum = 0\r\n for (let i = 0; i < this.period; i++) {\r\n sum += this.data.volume[i]\r\n }\r\n for (let i = this.period; i < this.data.volume.length; i++) {\r\n sum = sum - this.data.volume[i - this.period] + this.data.volume[i]\r\n this.rvol[i] = sum > 0 ? this.data.volume[i] / (sum / this.period) : 0\r\n }\r\n\r\n this.lastValue = this.rvol.last() ?? null\r\n }\r\n\r\n const { min, max } =\r\n this.rvol.length > 0\r\n ? this.computeVisibleMinMax([...this.rvol, this.baseLine])\r\n : this.getDomainDefaults(this.type)\r\n this.min = min\r\n this.max = max\r\n }\r\n\r\n getValueLabelsAtIndex(index: number) {\r\n const { Colors } = this.getChartLayoutSettings().ChartSettings.general\r\n const dataIndex = this.data.barToDataIndex[index]\r\n const value = this.rvol[dataIndex]\r\n return [\r\n { color: value < this.baseLine ? Colors.volumeTrendDown : Colors.volumeTrendUp, text: this.getValueLabel(value) },\r\n ]\r\n }\r\n\r\n renderIndicator(context: CanvasRenderingContext2D) {\r\n const { ChartSettings } = this.getChartLayoutSettings()\r\n const { Colors } = ChartSettings.general\r\n const chartModel = this.model.chart()\r\n const { zoomFactor } = chartModel\r\n const { barFillWidth, barBorderWidth } = getBarWidthWithMarginByParts({\r\n zoomFactor,\r\n chartLayout: chartModel.chart_layout(),\r\n })\r\n const barWidthWithoutMargin = barFillWidth + barBorderWidth * 2\r\n const halfBarWidth = ~~Math.max(1, barWidthWithoutMargin / 2)\r\n\r\n drawInVisibleArea({\r\n quote: this.data,\r\n paneModel: this.model,\r\n leftOffset: this.leftOffset,\r\n width: this.width,\r\n fromIndexOffset: this.period + 1,\r\n drawBarCallback: (i, x) => {\r\n if (this.rvol[i] === undefined) return\r\n\r\n const baseLine = Math.round(this.fy(this.baseLine))\r\n const y = Math.round(this.fy(this.rvol[i]))\r\n\r\n context.fillStyle = this.rvol[i] < this.baseLine ? Colors.volumeTrendDown : Colors.volumeTrendUp\r\n context.fillRect(x - halfBarWidth, baseLine, barWidthWithoutMargin, y - baseLine)\r\n },\r\n })\r\n\r\n const baseLineY = this.fy(this.baseLine)\r\n new Line(\r\n {\r\n x1: -this.leftOffset,\r\n x2: -this.leftOffset + this.contentWidth,\r\n y1: Math.round(baseLineY),\r\n y2: Math.round(baseLineY),\r\n strokeStyle: getHEXWithSpecificAplha(Colors.zeroChange, 0.5),\r\n },\r\n this.model\r\n ).render(context)\r\n }\r\n\r\n getModalConfig() {\r\n const options = {\r\n period: {\r\n type: 'number',\r\n label: 'Period',\r\n name: 'period',\r\n value: this.period ?? DEFAULT_PARAMETERS.Period,\r\n required: true,\r\n min: 1,\r\n max: 999999,\r\n },\r\n baseLine: {\r\n type: 'number',\r\n label: 'Baseline',\r\n name: 'baseLine',\r\n value: this.baseLine ?? DEFAULT_PARAMETERS.BaseLine,\r\n required: true,\r\n step: 0.1,\r\n allowDecimal: true,\r\n min: 0,\r\n max: 999999,\r\n },\r\n }\r\n\r\n return {\r\n title: RVOLConfig.label,\r\n inputs: RVOLConfig.inputsOrder.map((item) => options[item]),\r\n inputsErrorMessages: {\r\n period: `${options.period.label} must be a whole number between ${options.period.min} and ${options.period.max}`,\r\n baseLine: `${options.baseLine.label} must be a number between ${options.baseLine.min} and ${options.baseLine.max}`,\r\n },\r\n }\r\n }\r\n\r\n getIsValid(key: string): boolean {\r\n switch (key) {\r\n case 'period':\r\n return this.getIsNumberInputValid({ key })\r\n case 'baseLine':\r\n return this.getIsNumberInputValid({ key, integerOnly: false })\r\n default:\r\n return false\r\n }\r\n }\r\n\r\n toString() {\r\n return `${super.toString()}, SMA`\r\n }\r\n}\r\n\r\nexport default RelativeVolume\r\n","import { IndicatorType } from '../../constants/common'\r\nimport IndicatorBaseConfig from './indicatorBaseConfig'\r\n\r\nexport type Options = {\r\n period: number\r\n}\r\n\r\nexport type Attrs = Options\r\n\r\nexport class RWIConfig extends IndicatorBaseConfig {\r\n static type = IndicatorType.Rwi\r\n static abbreviation = 'rwi'\r\n static label = 'Random Walk Index'\r\n static shortLabel = 'RWI'\r\n static optionsOrder = ['period'] as const\r\n static optionsLabels = { period: 'Period' }\r\n static inputsOrder = this.optionsOrder\r\n static inputsLabels = this.optionsLabels\r\n}\r\n","import Text from '../canvas/text'\r\nimport { OFFSET, PADDING, TextBaseline } from '../constants/common'\r\nimport { getTranslate } from '../controllers/renderUtils'\r\nimport Pane from '../models/pane'\r\nimport utils from '../utils'\r\nimport { drawInVisibleArea } from '../utils/draw_in_visible_area'\r\nimport { Attrs, RWIConfig } from './configs/rwi'\r\nimport Indicator from './indicator'\r\n\r\nclass RWI extends Indicator {\r\n static config = RWIConfig\r\n\r\n tr: number[] = []\r\n atr: number[] = []\r\n rwiHi: number[] = []\r\n rwiLo: number[] = []\r\n declare period: number\r\n\r\n constructor(attrs: Attrs, model: Pane) {\r\n super(attrs, model)\r\n this.renderYAxis = this.renderYAxis.bind(this)\r\n }\r\n\r\n set(values: Partial) {\r\n super.set(values)\r\n this.parsePeriodInt(values)\r\n }\r\n\r\n compute() {\r\n if (this.isComputeNecessary()) {\r\n this.tr = []\r\n this.atr = []\r\n this.rwiHi = []\r\n this.rwiLo = []\r\n let atr = 0\r\n\r\n for (let i = 0; i < this.data.close.length; i++) {\r\n const tr = utils.max([\r\n this.data.high[i] - this.data.low[i],\r\n Math.abs(this.data.high[i] - this.data.close[i - 1]),\r\n Math.abs(this.data.low[i] - this.data.close[i - 1]),\r\n ])\r\n this.tr[i] = tr\r\n\r\n if (i < this.period) {\r\n atr += tr\r\n this.atr[i] = atr / (i + 1)\r\n if (i === this.period - 1) {\r\n atr /= this.period\r\n }\r\n } else {\r\n this.atr[i] = (this.atr[i - 1] * (this.period - 1) + tr) / this.period\r\n }\r\n }\r\n\r\n for (let i = this.period + 2; i < this.data.close.length; i++) {\r\n const h = this.data.high[i]\r\n const l = this.data.low[i]\r\n let trSum = this.tr[i - 1] + this.tr[i - 2]\r\n let count = 2\r\n let atrWeight = (trSum / count) * Math.sqrt(count)\r\n let maxHi = atrWeight > 0 ? (h - this.data.low[i - 1]) / atrWeight : -1\r\n let maxLo = atrWeight > 0 ? (this.data.high[i - 1] - l) / atrWeight : -1\r\n for (let j = i - 1; j > i - this.period + 1; j--) {\r\n trSum += this.tr[j - 2]\r\n count++\r\n atrWeight = (trSum / count) * Math.sqrt(count)\r\n if (atrWeight === 0) {\r\n continue\r\n }\r\n\r\n const hi = (h - this.data.low[j - 1]) / atrWeight\r\n if (hi > maxHi) {\r\n maxHi = hi\r\n }\r\n\r\n const lo = (this.data.high[j - 1] - l) / atrWeight\r\n if (lo > maxLo) {\r\n maxLo = lo\r\n }\r\n }\r\n this.rwiHi[i] = maxHi\r\n this.rwiLo[i] = maxLo\r\n }\r\n }\r\n const { min, max } =\r\n this.rwiHi.length > 0 || this.rwiLo.length > 0\r\n ? this.computeVisibleMinMax(this.rwiHi, this.rwiLo)\r\n : this.getDomainDefaults(this.type)\r\n this.min = min\r\n this.max = max\r\n }\r\n\r\n getLineColors() {\r\n return {\r\n rwiLo: '#c80000',\r\n rwiHi: '#00a000',\r\n }\r\n }\r\n\r\n getValueLabelsAtIndex(index: number) {\r\n if (this.data.close.length === 0) return []\r\n\r\n const lineColors = this.getLineColors()\r\n const dataIndex = this.data?.barToDataIndex[index]\r\n return [\r\n { color: lineColors.rwiLo, text: this.getValueLabel(this.rwiLo[dataIndex]) },\r\n { color: lineColors.rwiHi, text: this.getValueLabel(this.rwiHi[dataIndex]) },\r\n ]\r\n }\r\n\r\n renderIndicator(context: CanvasRenderingContext2D) {\r\n if (this.data.close.length === 0) return\r\n\r\n const drawInVisibleAreaProps = {\r\n quote: this.data,\r\n paneModel: this.model,\r\n leftOffset: this.leftOffset,\r\n width: this.width,\r\n fromIndexOffset: this.period,\r\n }\r\n\r\n context.translate(0.5, 0.5)\r\n context.set('strokeStyle', '#c80000')\r\n context.beginPath()\r\n drawInVisibleArea({\r\n ...drawInVisibleAreaProps,\r\n drawBarCallback: (i: number, x: number) => {\r\n context.lineTo(x, Math.round(this.fy(this.rwiLo[i])))\r\n },\r\n })\r\n context.stroke()\r\n\r\n context.set('strokeStyle', '#00a000')\r\n context.beginPath()\r\n drawInVisibleArea({\r\n ...drawInVisibleAreaProps,\r\n drawBarCallback: (i: number, x: number) => {\r\n context.lineTo(x, Math.round(this.fy(this.rwiHi[i])))\r\n },\r\n })\r\n context.stroke()\r\n context.translate(-0.5, -0.5)\r\n }\r\n\r\n renderYAxis(context: CanvasRenderingContext2D) {\r\n super.renderYAxis(context)\r\n const { IndicatorSettings, ChartSettings } = this.getChartLayoutSettings()\r\n const { Colors } = ChartSettings.general\r\n const translate = getTranslate({\r\n context,\r\n xOffset: IndicatorSettings.left.width,\r\n yOffset: IndicatorSettings.top.height,\r\n })\r\n translate.do()\r\n const text = new Text(\r\n {\r\n x: this.contentWidth + OFFSET.M - PADDING.XXS + IndicatorSettings.right.axis.margin.left!,\r\n font: Text.getMergedPropsWithDefaults('font', IndicatorSettings.right.axis.font),\r\n lineHeight: IndicatorSettings.right.axis.font.lineHeight,\r\n padding: {\r\n top: IndicatorSettings.right.axis.font?.padding?.top ?? PADDING.XXS,\r\n right: IndicatorSettings.right.axis.font?.padding?.right ?? PADDING.XXS,\r\n bottom: IndicatorSettings.right.axis.font?.padding?.bottom ?? PADDING.XXS,\r\n left: IndicatorSettings.right.axis.font?.padding?.left ?? PADDING.XXS,\r\n },\r\n textBaseline: TextBaseline.middle,\r\n fillStyle: Colors.indicatorCurrentText,\r\n },\r\n this.model\r\n )\r\n const textLabels = []\r\n if (this.rwiLo.length > 0) {\r\n textLabels.push({\r\n text: this.rwiLo.last()!.toFixed(2),\r\n y: Math.round(this.fy(this.rwiLo.last()!)),\r\n background: '#c80000',\r\n })\r\n }\r\n if (this.rwiHi.length > 0) {\r\n textLabels.push({\r\n text: this.rwiHi.last()!.toFixed(2),\r\n y: Math.round(this.fy(this.rwiHi.last()!)),\r\n background: '#00a000',\r\n })\r\n }\r\n\r\n const minY = 0\r\n const maxY = this.height - IndicatorSettings.bottom.height - IndicatorSettings.top.height\r\n textLabels.forEach((labelSetting) => {\r\n if (labelSetting.y >= minY && labelSetting.y <= maxY) {\r\n text.set(labelSetting).render(context)\r\n }\r\n })\r\n\r\n translate.undo()\r\n }\r\n\r\n getModalConfig() {\r\n const options = {\r\n period: {\r\n type: 'number',\r\n label: 'Period',\r\n name: 'period',\r\n value: this.period ?? 9,\r\n required: true,\r\n min: 1,\r\n max: 999999,\r\n },\r\n }\r\n\r\n return {\r\n title: RWIConfig.label,\r\n inputs: RWIConfig.inputsOrder.map((item) => options[item]),\r\n inputsErrorMessages: {\r\n period: `${options.period.label} must be a whole number between ${options.period.min} and ${options.period.max}`,\r\n },\r\n }\r\n }\r\n\r\n getIsValid(key: string): boolean {\r\n switch (key) {\r\n case 'period':\r\n return this.getIsNumberInputValid({ key })\r\n default:\r\n return false\r\n }\r\n }\r\n}\r\n\r\nexport default RWI\r\n","import { IndicatorType, QuoteFinancialAttachment } from '../../constants/common'\r\nimport IndicatorBaseConfig from './indicatorBaseConfig'\r\n\r\nexport class ShrtflConfig extends IndicatorBaseConfig {\r\n static quoteFinancialAttachments: QuoteFinancialAttachment[] = [QuoteFinancialAttachment.shortInterest]\r\n static type = IndicatorType.Shrtfl\r\n static label = 'Short Float%'\r\n static shortLabel = 'Short Float%'\r\n static abbreviation = 'shrtfl'\r\n}\r\n","import { format } from 'date-fns'\r\n\r\nimport { ObjectHash } from '../../types/shared'\r\nimport { TIMEFRAME } from '../constants/common'\r\nimport { getTranslate } from '../controllers/renderUtils'\r\nimport { dateFromUnixTimestamp } from '../utils'\r\nimport { drawInVisibleArea } from '../utils/draw_in_visible_area'\r\nimport Indicator from './indicator'\r\n\r\ntype ValuesType = Array<{\r\n isBeforeData: boolean\r\n timestamp: number\r\n value: number | null\r\n sourceIndex: number\r\n}>\r\n\r\nclass FinancialIndicator extends Indicator {\r\n values: ValuesType[] = []\r\n applyMinMaxPadding = true\r\n\r\n getComputedValuesAtDateIndex(_: number): ValuesType {\r\n throw Error('Implement getComputedValuesAtDateIndex method')\r\n }\r\n\r\n compute() {\r\n if (!isNaN(this.contentWidth) && this.isComputeNecessary()) {\r\n this.values = []\r\n\r\n if (this.data.financialAttachmentsData) {\r\n for (let i = 0; i < this.data.date.length; i++) {\r\n const computedValues = this.getComputedValuesAtDateIndex(i)\r\n this.values[i] = computedValues.length > 0 ? computedValues : (this.values[i - 1] ?? [])\r\n }\r\n }\r\n }\r\n\r\n this.lastValue = this.getLastValue()\r\n const { min, max } = this.computeVisibleMinMax()\r\n this.min = min\r\n this.max = max\r\n }\r\n\r\n getLastValue() {\r\n return this.getValueAtDataIndex(this.values.length - 1)\r\n }\r\n\r\n computeVisibleMinMax() {\r\n return super.computeVisibleMinMax(this.values.map((values) => values[values.length - 1]?.value ?? Number.NaN))\r\n }\r\n\r\n getValueAtDataIndex(dataIndex: number) {\r\n const vals = this.values[dataIndex]\r\n const val = vals?.[(vals?.length ?? 0) - 1] ?? null\r\n return val?.value\r\n }\r\n\r\n getValueLabelsAtIndex(index: number) {\r\n const shouldShowDate = [TIMEFRAME.i1, TIMEFRAME.i2, TIMEFRAME.i3].includes(this.data.timeframe)\r\n const dataIndex = this.data.barToDataIndex[index]\r\n const values = this.values[dataIndex]\r\n if (!values) {\r\n return []\r\n }\r\n\r\n return values.map(({ timestamp, value, isBeforeData }) => {\r\n const valueLabel = this.getValueLabel(value)\r\n\r\n return {\r\n color: this.getChartLayoutSettings().IndicatorSettings.general.Colors.line!,\r\n text:\r\n valueLabel !== null\r\n ? `${valueLabel} ${\r\n values.length >= 2 || isBeforeData || shouldShowDate\r\n ? `(${format(dateFromUnixTimestamp(timestamp), 'MMM dd')})`\r\n : ''\r\n }`\r\n : null,\r\n }\r\n })\r\n }\r\n\r\n renderIndicator(context: CanvasRenderingContext2D) {\r\n const translate = getTranslate({ context, xOffset: 0.5, yOffset: 0.5 })\r\n translate.do()\r\n context.set('strokeStyle', this.getChartLayoutSettings().IndicatorSettings.general.Colors.line)\r\n context.beginPath()\r\n drawInVisibleArea({\r\n quote: this.data,\r\n paneModel: this.model,\r\n leftOffset: this.leftOffset,\r\n width: this.width,\r\n drawBarCallback: (i: number, x: number) => {\r\n const val = this.getValueAtDataIndex(i)\r\n context.lineTo(x, Math.round(this.fy(val!)))\r\n },\r\n })\r\n context.stroke()\r\n translate.undo()\r\n }\r\n\r\n formatAxis(value: number) {\r\n return this.getValueLabel(value) ?? value.toString()\r\n }\r\n}\r\n\r\nexport default FinancialIndicator\r\n","import { QuoteFinancialAttachment } from '../constants/common'\r\nimport { ShrtflConfig } from './configs/shrtfl'\r\nimport FinancialIndicator from './financialIndicator'\r\n\r\nclass Shrtfl extends FinancialIndicator {\r\n static config = ShrtflConfig\r\n\r\n getComputedValuesAtDateIndex(dateIndex: number) {\r\n const { timestampToFinancialsIndexesMap, alignedFinancialAttachmentsData } = this.data\r\n const timestampKey = this.data.date[dateIndex]?.toString() ?? ''\r\n const sourceIndexes = timestampToFinancialsIndexesMap[QuoteFinancialAttachment.shortInterest]?.[timestampKey] ?? []\r\n const alignedData = alignedFinancialAttachmentsData[QuoteFinancialAttachment.shortInterest] ?? []\r\n let isBeforeData = false\r\n\r\n if (sourceIndexes.length === 0 && dateIndex === 0) {\r\n const lastBeforeDateFinancialsDataIndex = alignedData.findLastIndex(\r\n ({ timestamp }) => timestamp < this.data.date[dateIndex]\r\n )\r\n if (lastBeforeDateFinancialsDataIndex >= 0) {\r\n sourceIndexes.push(lastBeforeDateFinancialsDataIndex)\r\n isBeforeData = true\r\n }\r\n }\r\n\r\n return sourceIndexes.map((si) => {\r\n const { timestamp, shortInterest, sharesFloat } = alignedData[si]\r\n let value: number | null = null\r\n if (shortInterest !== null && sharesFloat !== null) {\r\n value = (shortInterest / sharesFloat) * 100\r\n }\r\n\r\n return {\r\n isBeforeData,\r\n timestamp,\r\n value,\r\n sourceIndex: si,\r\n }\r\n })\r\n }\r\n\r\n renderYAxis(context: CanvasRenderingContext2D, options: { lastValueSuffix?: string } = {}) {\r\n return super.renderYAxis(context, { ...options, lastValueSuffix: '%' })\r\n }\r\n\r\n getValueLabel(value: number | null | undefined) {\r\n return super.getValueLabel(value, '%')\r\n }\r\n\r\n getIsValid(): boolean {\r\n return true\r\n }\r\n}\r\n\r\nexport default Shrtfl\r\n","import { IndicatorType, QuoteFinancialAttachment } from '../../constants/common'\r\nimport IndicatorBaseConfig from './indicatorBaseConfig'\r\n\r\nexport class ShrtraConfig extends IndicatorBaseConfig {\r\n static quoteFinancialAttachments: QuoteFinancialAttachment[] = [QuoteFinancialAttachment.shortInterest]\r\n static type = IndicatorType.Shrtra\r\n static label = 'Short Ratio'\r\n static shortLabel = 'Short Ratio'\r\n static abbreviation = 'shrtra'\r\n}\r\n","import { QuoteFinancialAttachment } from '../constants/common'\r\nimport { ShrtraConfig } from './configs/shrtra'\r\nimport FinancialIndicator from './financialIndicator'\r\n\r\nclass Shrtra extends FinancialIndicator {\r\n static config = ShrtraConfig\r\n\r\n getComputedValuesAtDateIndex(dateIndex: number) {\r\n const { timestampToFinancialsIndexesMap, alignedFinancialAttachmentsData } = this.data\r\n const timestampKey = this.data.date[dateIndex]?.toString() ?? ''\r\n const sourceIndexes = timestampToFinancialsIndexesMap[QuoteFinancialAttachment.shortInterest]?.[timestampKey] ?? []\r\n const alignedData = alignedFinancialAttachmentsData[QuoteFinancialAttachment.shortInterest] ?? []\r\n let isBeforeData = false\r\n\r\n if (sourceIndexes.length === 0 && dateIndex === 0) {\r\n const lastBeforeDateFinancialsDataIndex = alignedData.findLastIndex(\r\n ({ timestamp }) => timestamp < this.data.date[dateIndex]\r\n )\r\n if (lastBeforeDateFinancialsDataIndex >= 0) {\r\n sourceIndexes.push(lastBeforeDateFinancialsDataIndex)\r\n isBeforeData = true\r\n }\r\n }\r\n\r\n return sourceIndexes.map((si) => {\r\n const { timestamp, shortInterest, averageVolume } = alignedData[si]\r\n let value: number | null = null\r\n if (shortInterest !== null && averageVolume !== null) {\r\n value = (shortInterest / averageVolume) * 1_000_000\r\n }\r\n\r\n return {\r\n isBeforeData,\r\n timestamp,\r\n value,\r\n sourceIndex: si,\r\n }\r\n })\r\n }\r\n\r\n getIsValid(): boolean {\r\n return true\r\n }\r\n}\r\n\r\nexport default Shrtra\r\n","import { IndicatorType } from '../../constants/common'\r\nimport IndicatorBaseConfig from './indicatorBaseConfig'\r\n\r\nexport type Options = {\r\n period: string | number\r\n dPeriod: number\r\n}\r\n\r\nexport interface Attrs extends Options {\r\n kPeriod: number\r\n}\r\n\r\nexport class StofaConfig extends IndicatorBaseConfig {\r\n static type = IndicatorType.Stofa\r\n static abbreviation = 'stofa'\r\n static label = 'Stochastics FAST'\r\n static shortLabel = 'Stochastics FAST'\r\n static optionsOrder = ['period', 'dPeriod']\r\n\r\n static optionsLabels = { period: 'Period', dPeriod: 'D Period' }\r\n\r\n static inputsOrder = this.optionsOrder\r\n static inputsLabels = this.optionsLabels\r\n}\r\n","import { IndicatorType } from '../../constants/common'\r\nimport IndicatorBaseConfig from './indicatorBaseConfig'\r\n\r\nexport type Options = {\r\n period: string | number\r\n dPeriod: number\r\n kPeriod: number\r\n}\r\n\r\nexport type Attrs = Options\r\n\r\nexport class StofuConfig extends IndicatorBaseConfig {\r\n static type = IndicatorType.Stofu\r\n static abbreviation = 'stofu'\r\n static label = 'Stochastics FULL'\r\n static shortLabel = 'Stochastics FULL'\r\n static optionsOrder = ['period', 'dPeriod', 'kPeriod']\r\n\r\n static optionsLabels = { period: 'Period', kPeriod: 'K Period', dPeriod: 'D Period' } as { [key: string]: string }\r\n\r\n static inputsOrder = this.optionsOrder\r\n static inputsLabels = this.optionsLabels\r\n}\r\n","import Line from '../canvas/line'\r\nimport { drawInVisibleArea } from '../utils/draw_in_visible_area'\r\nimport { getParsedIntegersFromPeriodString } from '../utils/helpers'\r\nimport { Attrs, StofuConfig } from './configs/stofu'\r\nimport Indicator from './indicator'\r\n\r\nclass Stochastics extends Indicator {\r\n static config = StofuConfig\r\n\r\n k: number[] = []\r\n k1: number[] = []\r\n d: number[] = []\r\n declare kPeriod: number\r\n declare period: number\r\n declare dPeriod: number\r\n\r\n set(values: Partial) {\r\n if (typeof values.period === 'string') {\r\n const [period = 0, kPeriod = 0, dPeriod = 0] = getParsedIntegersFromPeriodString(values.period)\r\n super.set({ ...values, period, dPeriod, kPeriod })\r\n } else {\r\n super.set(values)\r\n }\r\n }\r\n\r\n compute() {\r\n if (!this.isComputeNecessary()) return\r\n\r\n const period = Math.min(this.period, this.data.close.length - 1)\r\n let dCount, dSum, k\r\n this.k1 = []\r\n this.k = []\r\n this.d = []\r\n let kSum = (dSum = 0)\r\n let kCount = (dCount = 0)\r\n for (let i = 0; i < this.data.close.length; i++) {\r\n let highestHigh = this.data.high[i]\r\n let lowestLow = this.data.low[i]\r\n\r\n for (let j = i - period + 1; j <= i; j++) {\r\n if (this.data.high[j] > highestHigh) {\r\n highestHigh = this.data.high[j]\r\n }\r\n if (this.data.low[j] < lowestLow) {\r\n lowestLow = this.data.low[j]\r\n }\r\n }\r\n\r\n k = ((this.data.close[i] - lowestLow) / (highestHigh - lowestLow)) * 100\r\n if (highestHigh === lowestLow) {\r\n k = 100\r\n }\r\n this.k1[i] = k\r\n if (this.kPeriod > 1) {\r\n kSum += k\r\n kCount++\r\n if (kCount > this.kPeriod) {\r\n kSum -= this.k1[i - this.kPeriod]\r\n kCount--\r\n }\r\n k = kSum / kCount\r\n }\r\n\r\n dSum += k\r\n dCount++\r\n if (dCount > this.dPeriod) {\r\n dSum -= this.k[i - this.dPeriod]\r\n dCount--\r\n }\r\n\r\n const d = dSum / dCount\r\n this.k[i] = k\r\n this.d[i] = d\r\n }\r\n\r\n this.lastValue = this.k.last() ?? null\r\n const { min, max } = this.getDomainDefaults(this.type)\r\n this.min = min\r\n this.max = max\r\n }\r\n\r\n getLineColors() {\r\n return {\r\n k: this.getChartLayoutSettings().IndicatorSettings.general.Colors.line,\r\n d: '#c80000',\r\n }\r\n }\r\n\r\n getValueLabelsAtIndex(index: number) {\r\n const lineColors = this.getLineColors()\r\n const dataIndex = this.data.barToDataIndex[index]\r\n return [\r\n { color: lineColors.k, text: this.getValueLabel(this.k[dataIndex]) },\r\n { color: lineColors.d, text: this.getValueLabel(this.d[dataIndex]) },\r\n ]\r\n }\r\n\r\n renderIndicator(context: CanvasRenderingContext2D) {\r\n if (this.data.close.length === 0) return\r\n\r\n new Line(\r\n {\r\n x1: -this.leftOffset,\r\n x2: -this.leftOffset + this.contentWidth,\r\n y1: Math.round(this.fy(50)),\r\n y2: Math.round(this.fy(50)),\r\n strokeStyle: '#ff8787',\r\n dashLength: 3,\r\n },\r\n this.model\r\n ).render(context)\r\n new Line(\r\n {\r\n x1: -this.leftOffset,\r\n x2: -this.leftOffset + this.contentWidth,\r\n y1: Math.round(this.fy(20)),\r\n y2: Math.round(this.fy(20)),\r\n strokeStyle: '#69c1ea',\r\n },\r\n this.model\r\n ).render(context)\r\n new Line(\r\n {\r\n x1: -this.leftOffset,\r\n x2: -this.leftOffset + this.contentWidth,\r\n y1: Math.round(this.fy(80)),\r\n y2: Math.round(this.fy(80)),\r\n strokeStyle: '#d386df',\r\n },\r\n this.model\r\n ).render(context)\r\n\r\n const lineColors = this.getLineColors()\r\n context.set('strokeStyle', lineColors.k)\r\n context.translate(0.5, 0.5)\r\n context.beginPath()\r\n const drawInVisibleAreaProps = {\r\n quote: this.data,\r\n paneModel: this.model,\r\n leftOffset: this.leftOffset,\r\n width: this.width,\r\n fromIndexOffset: this.period,\r\n }\r\n drawInVisibleArea({\r\n ...drawInVisibleAreaProps,\r\n drawBarCallback: (i, x) => {\r\n context.lineTo(x, Math.round(this.fy(this.k[i])))\r\n },\r\n })\r\n context.stroke()\r\n\r\n context.set('strokeStyle', lineColors.d)\r\n context.beginPath()\r\n drawInVisibleArea({\r\n ...drawInVisibleAreaProps,\r\n drawBarCallback: (i, x) => {\r\n context.lineTo(x, Math.round(this.fy(this.d[i])))\r\n },\r\n })\r\n context.stroke()\r\n context.translate(-0.5, -0.5)\r\n }\r\n\r\n getModalConfig() {\r\n const options = {\r\n period: {\r\n type: 'number',\r\n label: 'Period',\r\n name: 'period',\r\n value: this.period ?? 14,\r\n required: true,\r\n min: 1,\r\n max: 999999,\r\n },\r\n kPeriod: {\r\n type: 'number',\r\n label: 'K Period',\r\n name: 'kPeriod',\r\n value: this.kPeriod ?? 3,\r\n required: true,\r\n min: 1,\r\n max: 999999,\r\n },\r\n dPeriod: {\r\n type: 'number',\r\n label: 'D Period',\r\n name: 'dPeriod',\r\n value: this.dPeriod ?? 3,\r\n required: true,\r\n min: 1,\r\n max: 999999,\r\n },\r\n }\r\n\r\n return {\r\n title: StofuConfig.label,\r\n inputs: StofuConfig.inputsOrder.map((item) => options[item as keyof Attrs]),\r\n inputsErrorMessages: {\r\n period: `${options.period.label} must be a whole number between ${options.period.min} and ${options.period.max}`,\r\n dPeriod: `${options.dPeriod.label} must be a whole number between ${options.dPeriod.min} and ${options.dPeriod.max}`,\r\n kPeriod: `${options.kPeriod.label} must be a whole number between ${options.kPeriod.min} and ${options.kPeriod.max}`,\r\n } as {\r\n period: string\r\n dPeriod: string\r\n kPeriod?: string\r\n },\r\n }\r\n }\r\n\r\n getIsValid(key: string): boolean {\r\n switch (key) {\r\n case 'period':\r\n case 'dPeriod':\r\n case 'kPeriod':\r\n return this.getIsNumberInputValid({ key })\r\n default:\r\n return false\r\n }\r\n }\r\n}\r\n\r\nexport default Stochastics\r\n","import Pane from '../models/pane'\r\nimport { getParsedIntegersFromPeriodString } from '../utils/helpers'\r\nimport { Attrs, Options, StofaConfig } from './configs/stofa'\r\nimport Stochastics from './stofu'\r\n\r\nclass StochasticsFast extends Stochastics {\r\n static config = StofaConfig\r\n\r\n declare kPeriod: number\r\n declare period: number\r\n declare dPeriod: number\r\n\r\n constructor(attrs: Attrs, model: Pane) {\r\n super(attrs, model)\r\n this.kPeriod = 1\r\n }\r\n\r\n set(values: Partial) {\r\n if (typeof values.period === 'string') {\r\n const [period = 0, dPeriod = 0] = getParsedIntegersFromPeriodString(values.period)\r\n super.set({ ...values, period, dPeriod, kPeriod: 1 })\r\n } else {\r\n super.set(values)\r\n }\r\n }\r\n\r\n getModalConfig() {\r\n const options = {\r\n period: {\r\n type: 'number',\r\n label: 'Period',\r\n name: 'period',\r\n value: this.period ?? 14,\r\n required: true,\r\n min: 1,\r\n max: 999999,\r\n },\r\n dPeriod: {\r\n type: 'number',\r\n label: 'D Period',\r\n name: 'dPeriod',\r\n value: this.dPeriod ?? 3,\r\n required: true,\r\n min: 1,\r\n max: 999999,\r\n },\r\n }\r\n\r\n return {\r\n title: StofaConfig.label,\r\n inputs: StofaConfig.inputsOrder.map((item) => options[item as keyof Options]),\r\n inputsErrorMessages: {\r\n period: `${options.period.label} must be a whole number between ${options.period.min} and ${options.period.max}`,\r\n dPeriod: `${options.dPeriod.label} must be a whole number between ${options.dPeriod.min} and ${options.dPeriod.max}`,\r\n },\r\n }\r\n }\r\n\r\n getIsValid(key: string): boolean {\r\n switch (key) {\r\n case 'period':\r\n case 'dPeriod':\r\n return this.getIsNumberInputValid({ key })\r\n default:\r\n return false\r\n }\r\n }\r\n}\r\n\r\nexport default StochasticsFast\r\n","import { IndicatorType } from '../../constants/common'\r\nimport { StofaConfig } from './stofa'\r\n\r\nexport type Options = {\r\n period: string | number\r\n dPeriod: number\r\n}\r\n\r\nexport interface Attrs extends Options {\r\n kPeriod: number\r\n}\r\n\r\nexport class StoslConfig extends StofaConfig {\r\n static type = IndicatorType.Stosl\r\n static abbreviation = 'stosl'\r\n static label = 'Stochastics SLOW'\r\n static shortLabel = 'Stochastics SLOW'\r\n}\r\n","import { getParsedIntegersFromPeriodString } from '../utils/helpers'\r\nimport { Attrs, Options, StoslConfig } from './configs/stosl'\r\nimport Stochastics from './stofu'\r\n\r\nclass StochasticsSlow extends Stochastics {\r\n static config = StoslConfig\r\n\r\n kPeriod = 3\r\n\r\n set(values: Partial) {\r\n if (typeof values.period === 'string') {\r\n const [period = 0, dPeriod = 0] = getParsedIntegersFromPeriodString(values.period)\r\n super.set({ ...values, period, dPeriod, kPeriod: 3 })\r\n } else {\r\n super.set(values)\r\n }\r\n }\r\n\r\n getModalConfig() {\r\n const options = {\r\n period: {\r\n type: 'number',\r\n label: 'Period',\r\n name: 'period',\r\n value: this.period ?? 14,\r\n required: true,\r\n min: 1,\r\n max: 999999,\r\n },\r\n dPeriod: {\r\n type: 'number',\r\n label: 'D Period',\r\n name: 'dPeriod',\r\n value: this.dPeriod ?? 3,\r\n required: true,\r\n min: 1,\r\n max: 999999,\r\n },\r\n }\r\n\r\n return {\r\n title: StoslConfig.label,\r\n inputs: StoslConfig.inputsOrder.map((item) => options[item as keyof Options]),\r\n inputsErrorMessages: {\r\n period: `${options.period.label} must be a whole number between ${options.period.min} and ${options.period.max}`,\r\n dPeriod: `${options.dPeriod.label} must be a whole number between ${options.dPeriod.min} and ${options.dPeriod.max}`,\r\n },\r\n }\r\n }\r\n\r\n getIsValid(key: string): boolean {\r\n switch (key) {\r\n case 'period':\r\n case 'dPeriod':\r\n return this.getIsNumberInputValid({ key })\r\n default:\r\n return false\r\n }\r\n }\r\n}\r\n\r\nexport default StochasticsSlow\r\n","import { IndicatorType } from '../../constants/common'\r\nimport IndicatorBaseConfig from './indicatorBaseConfig'\r\n\r\nexport type Options = {\r\n period: number\r\n}\r\n\r\nexport type Attrs = Options\r\n\r\nexport class TRIXConfig extends IndicatorBaseConfig {\r\n static type = IndicatorType.Trix\r\n static abbreviation = 'trix'\r\n static label = 'TRIX'\r\n static shortLabel = 'TRIX'\r\n static optionsOrder = ['period'] as const\r\n static optionsLabels = { period: 'Period' }\r\n static inputsOrder = this.optionsOrder\r\n static inputsLabels = this.optionsLabels\r\n static calculatedValuesOrder = ['trix'] as const\r\n static calculatedValuesLabels = { trix: 'TRIX' }\r\n static defaultCalculatedValueOption = this.calculatedValuesOrder[0]\r\n}\r\n","import { Attrs, TRIXConfig } from '../indicators/configs/trix'\r\nimport { ExponentialMovingAverage } from './ema'\r\nimport { MainCalculation, OnValueCalculated } from './main'\r\n\r\ntype DefaultCalculatedValuesType = {\r\n trix: number[]\r\n}\r\n\r\nexport class TrixCalculation extends MainCalculation {\r\n static config = TRIXConfig\r\n\r\n calculate(onValueCalculated?: OnValueCalculated) {\r\n const { period } = this.options\r\n const { close } = this.quote\r\n const lastIndex = close.length - 1\r\n const ema1 = new ExponentialMovingAverage(period)\r\n const ema2 = new ExponentialMovingAverage(period)\r\n const ema3 = new ExponentialMovingAverage(period)\r\n this._calculatedValues = this.getDefaultCalculatedValues()\r\n\r\n let prev = 0\r\n for (let index = 0; index <= lastIndex; index++) {\r\n ema1.add(close[index])\r\n ema2.add(ema1.value)\r\n ema3.add(ema2.value)\r\n if (prev > 0) {\r\n this.calculatedValues.trix[index] = (ema3.value * 100) / prev - 100\r\n }\r\n prev = ema3.value\r\n\r\n if (onValueCalculated?.(this.calculatedValues, index) === false) {\r\n break\r\n }\r\n }\r\n }\r\n}\r\n","import Line from '../canvas/line'\r\nimport { TrixCalculation } from '../indicator-calculation/trix'\r\nimport { drawInVisibleArea } from '../utils/draw_in_visible_area'\r\nimport { Attrs, TRIXConfig } from './configs/trix'\r\nimport Indicator from './indicator'\r\n\r\nclass Trix extends Indicator {\r\n static config = TRIXConfig\r\n\r\n trixCalculation: TrixCalculation | null = null\r\n declare period: number\r\n\r\n set(values: Partial) {\r\n super.set(values)\r\n this.parsePeriodInt(values)\r\n }\r\n\r\n compute() {\r\n if (this.isComputeNecessary()) {\r\n this.trixCalculation = new TrixCalculation({\r\n quote: this.data,\r\n options: {\r\n period: this.period,\r\n },\r\n })\r\n this.trixCalculation.calculate()\r\n this.lastValue = this.trixCalculation.calculatedValues.trix.last() ?? null\r\n }\r\n const trix = this.trixCalculation?.calculatedValues.trix ?? []\r\n const { min, max } = trix.length > 0 ? this.computeVisibleMinMax(trix) : this.getDomainDefaults(this.type)\r\n this.min = min\r\n this.max = max\r\n }\r\n\r\n renderIndicator(context: CanvasRenderingContext2D) {\r\n new Line(\r\n {\r\n x1: -this.leftOffset,\r\n x2: -this.leftOffset + this.contentWidth,\r\n y1: Math.round(this.fy(0)),\r\n y2: Math.round(this.fy(0)),\r\n strokeStyle: '#ff8787',\r\n dashLength: 3,\r\n },\r\n this.model\r\n ).render(context)\r\n context.set('strokeStyle', this.getChartLayoutSettings().IndicatorSettings.general.Colors.line)\r\n context.translate(0.5, 0.5)\r\n context.beginPath()\r\n drawInVisibleArea({\r\n quote: this.data,\r\n paneModel: this.model,\r\n leftOffset: this.leftOffset,\r\n width: this.width,\r\n drawBarCallback: (i: number, x: number) => {\r\n const value = this.trixCalculation?.calculatedValues.trix[i]\r\n if (value) context.lineTo(x, ~~this.fy(value))\r\n },\r\n })\r\n context.stroke()\r\n context.translate(-0.5, -0.5)\r\n }\r\n\r\n getValueLabelsAtIndex(index: number) {\r\n const dataIndex = this.data.barToDataIndex[index]\r\n return [\r\n {\r\n color: this.getChartLayoutSettings().IndicatorSettings.general.Colors.line!,\r\n text: this.getValueLabel(this.trixCalculation?.calculatedValues.trix[dataIndex]),\r\n },\r\n ]\r\n }\r\n\r\n getModalConfig() {\r\n const options = {\r\n period: {\r\n type: 'number',\r\n label: 'Period',\r\n name: 'period',\r\n value: this.period ?? 9,\r\n required: true,\r\n min: 1,\r\n max: 999999,\r\n },\r\n }\r\n\r\n return {\r\n title: TRIXConfig.label,\r\n inputs: TRIXConfig.inputsOrder.map((item) => options[item]),\r\n inputsErrorMessages: {\r\n period: `${options.period.label} must be a whole number between ${options.period.min} and ${options.period.max}`,\r\n },\r\n }\r\n }\r\n\r\n getIsValid(key: string): boolean {\r\n switch (key) {\r\n case 'period':\r\n return this.getIsNumberInputValid({ key })\r\n default:\r\n return false\r\n }\r\n }\r\n}\r\n\r\nexport default Trix\r\n","import { IndicatorType } from '../../constants/common'\r\nimport IndicatorBaseConfig from './indicatorBaseConfig'\r\n\r\nexport type Options = {\r\n period1: number\r\n period2: number\r\n period3: number\r\n}\r\n\r\nexport interface Attrs extends Options {\r\n period: string\r\n}\r\n\r\nexport class UltConfig extends IndicatorBaseConfig {\r\n static type = IndicatorType.Ult\r\n static abbreviation = 'ult'\r\n static label = 'Ultimate Oscillator'\r\n static shortLabel = 'ULT'\r\n static optionsOrder = ['period1', 'period2', 'period3'] as const\r\n static optionsLabels = {\r\n period1: 'Period 1',\r\n period2: 'Period 2',\r\n period3: 'Period 3',\r\n }\r\n\r\n static inputsOrder = this.optionsOrder\r\n static inputsLabels = this.optionsLabels\r\n}\r\n","import { ChartConfigChartPaneElement, RequireByKey } from '../../types/shared'\r\nimport { getParsedIntegersFromPeriodString } from '../utils/helpers'\r\nimport { Attrs, UltConfig } from './configs/ult'\r\nimport Indicator from './indicator'\r\n\r\nclass UltimateOscillator extends Indicator {\r\n static config = UltConfig\r\n\r\n static getNumOfBarsBuffer({ period }: RequireByKey) {\r\n const [period1 = 0, period2 = 0, period3 = 0] = getParsedIntegersFromPeriodString(period)\r\n return Math.max(period1, period2, period3)\r\n }\r\n\r\n declare period1: number\r\n declare period2: number\r\n declare period3: number\r\n ult: number[] = []\r\n tr: number[] = []\r\n bp: number[] = []\r\n\r\n set(values: Partial) {\r\n if (typeof values.period === 'string') {\r\n const [period1 = 0, period2 = 0, period3 = 0] = getParsedIntegersFromPeriodString(values.period)\r\n super.set({ ...values, period1, period2, period3 })\r\n } else {\r\n super.set(values)\r\n }\r\n }\r\n\r\n compute() {\r\n if (!this.isComputeNecessary()) return\r\n\r\n this.ult = []\r\n let bpSum2, bpSum3, count2, count3, trSum2, trSum3\r\n const tr = []\r\n const bp = []\r\n let bpSum1 = (bpSum2 = bpSum3 = 0)\r\n let trSum1 = (trSum2 = trSum3 = 0)\r\n let count1 = (count2 = count3 = 0)\r\n let avg2, avg3\r\n for (let i = 1; i < this.data.close.length; i++) {\r\n bp[i] = this.data.close[i] - Math.min(this.data.low[i], this.data.close[i - 1])\r\n tr[i] = Math.max(this.data.high[i], this.data.close[i - 1]) - Math.min(this.data.low[i], this.data.close[i - 1])\r\n\r\n bpSum1 += bp[i]\r\n trSum1 += tr[i]\r\n count1++\r\n if (count1 > this.period1) {\r\n bpSum1 -= bp[i - this.period1]\r\n trSum1 -= tr[i - this.period1]\r\n }\r\n\r\n bpSum2 += bp[i]\r\n trSum2 += tr[i]\r\n count2++\r\n if (count2 > this.period2) {\r\n bpSum2 -= bp[i - this.period2]\r\n trSum2 -= tr[i - this.period2]\r\n }\r\n\r\n bpSum3 += bp[i]\r\n trSum3 += tr[i]\r\n count3++\r\n if (count3 > this.period3) {\r\n bpSum3 -= bp[i - this.period3]\r\n trSum3 -= tr[i - this.period3]\r\n }\r\n\r\n let avg1 = (avg2 = avg3 = 0)\r\n if (trSum1 > 0) {\r\n avg1 = bpSum1 / trSum1\r\n }\r\n if (trSum2 > 0) {\r\n avg2 = bpSum2 / trSum2\r\n }\r\n if (trSum3 > 0) {\r\n avg3 = bpSum3 / trSum3\r\n }\r\n\r\n this.ult[i] = (100 * (4 * avg1 + 2 * avg2 + avg3)) / 7\r\n }\r\n\r\n this.lastValue = this.ult.last() ?? null\r\n const { min, max } = this.getDomainDefaults(this.type)\r\n this.min = min\r\n this.max = max\r\n }\r\n\r\n getValueLabelsAtIndex(index: number) {\r\n return this.getOversoldOverboughtValueLabelsAtIndex(index, this.ult)\r\n }\r\n\r\n renderIndicator(context: CanvasRenderingContext2D) {\r\n this.renderOversoldOverbought(context, this.ult, 1, 30, 50, 70)\r\n }\r\n\r\n getModalConfig() {\r\n const options = {\r\n period1: {\r\n type: 'number',\r\n label: 'Period 1',\r\n name: 'period1',\r\n value: this.period1 ?? 7,\r\n required: true,\r\n min: 1,\r\n max: 999999,\r\n },\r\n period2: {\r\n type: 'number',\r\n label: 'Period 2',\r\n name: 'period2',\r\n value: this.period2 ?? 14,\r\n required: true,\r\n min: 1,\r\n max: 999999,\r\n },\r\n period3: {\r\n type: 'number',\r\n label: 'Period 3',\r\n name: 'period3',\r\n value: this.period3 ?? 28,\r\n required: true,\r\n min: 1,\r\n max: 999999,\r\n },\r\n }\r\n\r\n return {\r\n title: UltConfig.label,\r\n inputs: UltConfig.inputsOrder.map((item) => options[item]),\r\n inputsErrorMessages: {\r\n period1: `${options.period1.label} must be a whole number between ${options.period1.min} and ${options.period1.max}`,\r\n period2: `${options.period2.label} must be a whole number between ${options.period2.min} and ${options.period2.max}`,\r\n period3: `${options.period3.label} must be a whole number between ${options.period3.min} and ${options.period3.max}`,\r\n },\r\n }\r\n }\r\n\r\n getIsValid(key: string): boolean {\r\n switch (key) {\r\n case 'period1':\r\n case 'period2':\r\n case 'period3':\r\n return this.getIsNumberInputValid({ key })\r\n default:\r\n return false\r\n }\r\n }\r\n}\r\n\r\nexport default UltimateOscillator\r\n","import { IndicatorType } from '../../constants/common'\r\nimport IndicatorBaseConfig from './indicatorBaseConfig'\r\n\r\nexport class VolConfig extends IndicatorBaseConfig {\r\n static type = IndicatorType.Vol\r\n static abbreviation = 'vol'\r\n static label = 'Volume'\r\n static shortLabel = 'Volume'\r\n}\r\n","import math from '../helpers/math'\r\nimport { getBarWidthWithMarginByParts } from '../utils/chart'\r\nimport { drawInVisibleArea } from '../utils/draw_in_visible_area'\r\nimport { VolConfig } from './configs/vol'\r\nimport Indicator from './indicator'\r\n\r\nclass Volume extends Indicator {\r\n static config = VolConfig\r\n\r\n compute() {\r\n const { min, max } =\r\n this.data.volume.length > 0 ? this.computeVisibleMinMax(this.data.volume) : this.getDomainDefaults(this.type)\r\n this.min = min\r\n this.max = max\r\n this.lastValue = this.data.volume.last() ?? null\r\n }\r\n\r\n getValueLabelsAtIndex(index: number) {\r\n const { Colors } = this.getChartLayoutSettings().ChartSettings.general\r\n const dataIndex = this.data.barToDataIndex[index]\r\n return [\r\n {\r\n color: this.data.close[dataIndex] < this.data.open[dataIndex] ? Colors.volumeTrendDown : Colors.volumeTrendUp,\r\n text: this.getValueLabel(this.data.volume[dataIndex]),\r\n },\r\n ]\r\n }\r\n\r\n renderIndicator(context: CanvasRenderingContext2D) {\r\n const { ChartSettings } = this.getChartLayoutSettings()\r\n const { Colors } = ChartSettings.general\r\n const chartModel = this.model.chart()\r\n const { zoomFactor } = chartModel\r\n const { barFillWidth, barBorderWidth } = getBarWidthWithMarginByParts({\r\n zoomFactor,\r\n chartLayout: chartModel.chart_layout(),\r\n })\r\n const barWidthWithoutMargin = barFillWidth + barBorderWidth * 2\r\n const halfBarWidth = ~~Math.max(1, barWidthWithoutMargin / 2)\r\n\r\n drawInVisibleArea({\r\n quote: this.data,\r\n paneModel: this.model,\r\n leftOffset: this.leftOffset,\r\n width: this.width,\r\n drawBarCallback: (i, x) => {\r\n context.fillStyle = this.data.close[i] < this.data.open[i] ? Colors.volumeTrendDown : Colors.volumeTrendUp\r\n const y = Math.round(this.fy(this.data.volume[i]))\r\n context.fillRect(x - halfBarWidth, y, barWidthWithoutMargin, context.canvas.height - y)\r\n },\r\n })\r\n }\r\n\r\n formatAxis(value: number) {\r\n return math.formatBigNumber(value, 2)\r\n }\r\n\r\n getModalConfig() {\r\n return {\r\n title: VolConfig.label,\r\n inputs: [],\r\n inputsErrorMessages: {},\r\n }\r\n }\r\n}\r\n\r\nexport default Volume\r\n","import { IndicatorType } from '../../constants/common'\r\nimport IndicatorBaseConfig from './indicatorBaseConfig'\r\n\r\nexport type Options = {\r\n period: number\r\n}\r\n\r\nexport type Attrs = Options\r\n\r\nexport class WRConfig extends IndicatorBaseConfig {\r\n static type = IndicatorType.Wr\r\n static abbreviation = 'wr'\r\n static label = 'Williams %R'\r\n static shortLabel = 'W%R'\r\n static optionsOrder = ['period'] as const\r\n static optionsLabels = { period: 'Period' }\r\n static inputsOrder = this.optionsOrder\r\n static inputsLabels = this.optionsLabels\r\n}\r\n","import { Attrs, WRConfig } from './configs/wr'\r\nimport Indicator from './indicator'\r\n\r\nclass WilliamsR extends Indicator {\r\n static config = WRConfig\r\n\r\n declare period: number\r\n r: number[] = []\r\n\r\n set(values: Partial) {\r\n super.set(values)\r\n this.parsePeriodInt(values)\r\n }\r\n\r\n compute() {\r\n if (this.isComputeNecessary()) {\r\n this.r = []\r\n for (let i = this.period; i < this.data.close.length; i++) {\r\n let highestHigh = this.data.high[i]\r\n let lowestLow = this.data.low[i]\r\n for (let j = i - this.period + 1; j <= i; j++) {\r\n if (this.data.high[j] > highestHigh) {\r\n highestHigh = this.data.high[j]\r\n }\r\n if (this.data.low[j] < lowestLow) {\r\n lowestLow = this.data.low[j]\r\n }\r\n }\r\n\r\n this.r[i] = 0\r\n if (highestHigh - lowestLow > 0) {\r\n this.r[i] = ((highestHigh - this.data.close[i]) / (highestHigh - lowestLow)) * -100\r\n }\r\n }\r\n\r\n this.lastValue = this.r.last() ?? null\r\n }\r\n const { min, max } = this.r.length > 0 ? this.computeVisibleMinMax(this.r) : this.getDomainDefaults(this.type)\r\n this.min = min\r\n this.max = max\r\n }\r\n\r\n getValueLabelsAtIndex(index: number) {\r\n return this.getOversoldOverboughtValueLabelsAtIndex(index, this.r)\r\n }\r\n\r\n renderIndicator(context: CanvasRenderingContext2D) {\r\n this.renderOversoldOverbought(context, this.r, this.period, -80, -50, -20)\r\n }\r\n\r\n getModalConfig() {\r\n const options = {\r\n period: {\r\n type: 'number',\r\n label: 'Period',\r\n name: 'period',\r\n value: this.period ?? 14,\r\n required: true,\r\n min: 1,\r\n max: 999999,\r\n },\r\n }\r\n\r\n return {\r\n title: WRConfig.label,\r\n inputs: WRConfig.inputsOrder.map((item) => options[item]),\r\n inputsErrorMessages: {\r\n period: `${options.period.label} must be a whole number between ${options.period.min} and ${options.period.max}`,\r\n },\r\n }\r\n }\r\n\r\n getIsValid(key: string): boolean {\r\n switch (key) {\r\n case 'period':\r\n return this.getIsNumberInputValid({ key })\r\n default:\r\n return false\r\n }\r\n }\r\n}\r\n\r\nexport default WilliamsR\r\n","import { IndicatorType } from '../constants/common'\r\nimport adx from './adx'\r\nimport aro from './aro'\r\nimport aroosc from './aroosc'\r\nimport atr from './atr'\r\nimport cci from './cci'\r\nimport cot from './cot'\r\nimport fi from './fi'\r\nimport indicator from './indicator'\r\nimport macd from './macd'\r\nimport mfi from './mfi'\r\nimport none from './none'\r\nimport obv from './obv'\r\nimport perf from './perf'\r\nimport rmi from './rmi'\r\nimport roc from './roc'\r\nimport rsi from './rsi'\r\nimport rvol from './rvol'\r\nimport rwi from './rwi'\r\nimport shrtfl from './shrtfl'\r\nimport shrtra from './shrtra'\r\nimport stofa from './stofa'\r\nimport stofu from './stofu'\r\nimport stosl from './stosl'\r\nimport trix from './trix'\r\nimport ult from './ult'\r\nimport vol from './vol'\r\nimport wr from './wr'\r\n\r\n// TODO check if this doesn't break saved charts\r\nexport const indicatorsByType = Object.freeze({\r\n [IndicatorType.Indicator]: indicator,\r\n [IndicatorType.None]: none,\r\n [IndicatorType.Adx]: adx,\r\n [IndicatorType.Aro]: aro,\r\n [IndicatorType.Aroosc]: aroosc,\r\n [IndicatorType.Atr]: atr,\r\n [IndicatorType.Cci]: cci,\r\n [IndicatorType.Cot]: cot,\r\n [IndicatorType.Fi]: fi,\r\n [IndicatorType.Macd]: macd,\r\n [IndicatorType.Mfi]: mfi,\r\n [IndicatorType.Obv]: obv,\r\n [IndicatorType.Perf]: perf,\r\n [IndicatorType.Rmi]: rmi,\r\n [IndicatorType.Roc]: roc,\r\n [IndicatorType.Rsi]: rsi,\r\n [IndicatorType.Rvol]: rvol,\r\n [IndicatorType.Rwi]: rwi,\r\n [IndicatorType.Stofa]: stofa,\r\n [IndicatorType.Stofu]: stofu,\r\n [IndicatorType.Stosl]: stosl,\r\n [IndicatorType.Trix]: trix,\r\n [IndicatorType.Ult]: ult,\r\n [IndicatorType.Vol]: vol,\r\n [IndicatorType.Wr]: wr,\r\n [IndicatorType.Shrtfl]: shrtfl,\r\n [IndicatorType.Shrtra]: shrtra,\r\n})\r\n\r\nexport const financialIndicators = Object.freeze([IndicatorType.Shrtfl, IndicatorType.Shrtra])\r\nexport const indicatorsWithoutPeriod = Object.freeze([IndicatorType.Obv, IndicatorType.Vol, ...financialIndicators])\r\n","export const publishModalAsyncModule = {\r\n importFn: () => import(/* webpackChunkName: \"modals-publish\" */ './module-entry'),\r\n cacheKey: 'modals-publish',\r\n}\r\n","import Spine from '@finviz/spine'\r\nimport * as React from 'react'\r\n\r\nimport { DefaultSpineEvents } from '../../types/shared'\r\nimport ElementModule from '../canvas/element'\r\nimport IndicatorModule from '../indicators/indicator'\r\nimport { useForceUpdate } from '../utils/force-update'\r\nimport { getJSONReplacerFunc } from '../utils/helpers'\r\n\r\ninterface UseModelStateOptions {\r\n watchProperties?: T extends null ? never[] : Array\r\n listenOnEvents?: string[]\r\n}\r\n\r\nconst getIsSpineObject = (value: any) =>\r\n [Spine.Model, Spine.Module, Spine.Collection].some((spineObject) => value instanceof spineObject)\r\n\r\nconst getWatchedPropValue = (\r\n watchedProp: Model[keyof Model] | ElementModule | IndicatorModule | undefined,\r\n model: Model | null\r\n) => {\r\n if (typeof watchedProp === 'function') {\r\n const value = watchedProp.call(model)\r\n\r\n if (value && !getIsSpineObject(value)) {\r\n throw Error('Watched prop should have a primitive value or a spine object')\r\n }\r\n\r\n if (typeof value?.all === 'function') {\r\n return value.all()\r\n }\r\n\r\n return value\r\n }\r\n\r\n if (typeof watchedProp === 'object') {\r\n const hasToObject = !!watchedProp && 'toObject' in watchedProp\r\n return JSON.stringify(hasToObject ? watchedProp.toObject() : watchedProp, getJSONReplacerFunc())\r\n }\r\n\r\n return watchedProp\r\n}\r\n\r\nconst getWatchedProps = (model: Model | null, props?: Array) =>\r\n props?.reduce(\r\n (acc, propKey) => ({\r\n ...acc,\r\n [propKey]: getWatchedPropValue(model?.[propKey], model),\r\n }),\r\n {} as Partial\r\n )\r\n\r\nconst getAreWatchedPropsEqual = (\r\n currentValue: Value,\r\n previousValue: Value\r\n) => {\r\n if (currentValue instanceof Spine.Model) {\r\n return currentValue.eql(previousValue)\r\n }\r\n\r\n return currentValue === previousValue\r\n}\r\n\r\nconst DEFAULT_SPINE_EVENTS = Object.values(DefaultSpineEvents)\r\n\r\nexport function useModelState(\r\n model: Model,\r\n options: UseModelStateOptions = {}\r\n) {\r\n const { watchProperties = [], listenOnEvents = DEFAULT_SPINE_EVENTS } = options\r\n const stringifiedOptions = JSON.stringify(options)\r\n const { forceUpdate } = useForceUpdate()\r\n const watchedPropertiesRef = React.useRef(getWatchedProps(model, watchProperties))\r\n\r\n React.useEffect(() => {\r\n const handleModelChange = () => {\r\n const hasChange = watchProperties.some((propKey) => {\r\n const currentValue = getWatchedPropValue(model?.[propKey], model)\r\n const previousValue = watchedPropertiesRef.current?.[propKey]\r\n\r\n if (Array.isArray(currentValue)) {\r\n return (\r\n !Array.isArray(previousValue) ||\r\n currentValue.length !== previousValue.length ||\r\n currentValue.some((record, index) => !getAreWatchedPropsEqual(record, previousValue[index]))\r\n )\r\n }\r\n\r\n return !getAreWatchedPropsEqual(currentValue, previousValue)\r\n })\r\n\r\n if (hasChange) {\r\n watchedPropertiesRef.current = getWatchedProps(model, watchProperties)\r\n forceUpdate()\r\n }\r\n }\r\n\r\n const spineEvents = listenOnEvents.join(' ')\r\n\r\n model?.bind(spineEvents, handleModelChange)\r\n\r\n forceUpdate()\r\n\r\n return () => {\r\n model?.unbind(spineEvents, handleModelChange)\r\n }\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n }, [model?.cid, stringifiedOptions, forceUpdate])\r\n\r\n return model\r\n}\r\n","import Spine, { Collection } from '@finviz/spine'\r\nimport omit from 'lodash.omit'\r\n\r\nimport {\r\n ChartConfigChartPane,\r\n CustomSpineEvents,\r\n Instrument,\r\n ObjectHash,\r\n TodoObjectHashAnyType,\r\n} from '../../types/shared'\r\nimport BaseChart from '../charts/base_chart'\r\nimport PerfChart from '../charts/perf_chart'\r\nimport {\r\n DateRangeType,\r\n IndicatorType,\r\n QuotePollingIntervalInMs,\r\n ScaleType,\r\n SpecificChartFunctionality,\r\n TIMEFRAME,\r\n} from '../constants/common'\r\nimport { getCanvasElementByType } from '../helpers/get-canvas-element-by-type'\r\nimport IndicatorBaseConfig from '../indicators/configs/indicatorBaseConfig'\r\nimport COT from '../indicators/cot'\r\nimport PricePerformance from '../indicators/perf'\r\nimport Utils from '../utils'\r\nimport { IDividends, IEarnings, ISplit } from '../utils/chart-events-utils'\r\nimport ChartEventElement from './chart-event-element'\r\nimport { ChartPartToAttrsSyncMap, ChartSyncablePart } from './chart/contstants'\r\nimport ChartLayout from './chart_layout'\r\nimport Pane from './pane'\r\nimport Quote from './quote'\r\nimport { getChartLayoutSettings } from './settings'\r\n\r\nclass Chart extends Spine.Model {\r\n static initClass(paneModel: typeof Pane, quoteModel: typeof Quote, chartLayoutModel: typeof ChartLayout) {\r\n this.configure(\r\n 'Chart',\r\n 'width',\r\n 'height',\r\n 'timeframe',\r\n 'dateRange',\r\n 'scale',\r\n 'leftOffset',\r\n 'ticker',\r\n 'instrument',\r\n 'fx',\r\n 'fy',\r\n 'zoomFactor',\r\n 'refreshData',\r\n 'stretch',\r\n 'isHideDrawingsActive',\r\n 'isScrolled',\r\n 'firstBarClose',\r\n 'premarket',\r\n 'aftermarket',\r\n 'hasChartEvents'\r\n )\r\n this.hasMany('panes', paneModel)\r\n this.belongsTo('quote', quoteModel)\r\n this.belongsTo('chart_layout', chartLayoutModel)\r\n }\r\n\r\n declare stretch: boolean\r\n declare chart_layout_id: string\r\n declare chart_layout: () => ChartLayout\r\n declare quote_id: string\r\n declare quote: () => Quote\r\n declare panes: () => Collection\r\n declare refreshData: boolean | number\r\n declare dateRange: DateRangeType\r\n declare width: number\r\n declare height: number\r\n declare timeframe: TIMEFRAME\r\n declare leftOffset: number\r\n declare ticker: string\r\n declare instrument: Instrument\r\n declare fx: (x: number) => number\r\n declare fy: (x: number) => number\r\n declare zoomFactor: number\r\n declare isHideDrawingsActive: boolean\r\n declare isScrolled: boolean\r\n declare scale: ScaleType\r\n declare firstBarClose: number\r\n declare premarket: boolean\r\n declare aftermarket: boolean\r\n declare hasChartEvents: boolean\r\n\r\n getChartPane() {\r\n return this.panes()\r\n .all()\r\n .find((pane: Pane) =>\r\n pane\r\n .elements()\r\n .all()\r\n .some((el) => el.isChart())\r\n )\r\n }\r\n\r\n getChartElement() {\r\n for (const pane of this.panes().all()) {\r\n for (const el of pane.elements().all()) {\r\n if (el.isChart()) {\r\n return el\r\n }\r\n }\r\n }\r\n }\r\n\r\n getChartType() {\r\n return this.getChartElement()?.instance.type\r\n }\r\n\r\n getRefreshInterval() {\r\n let defaultRefreshInterval: number | null = null\r\n if (typeof this.refreshData === 'number') {\r\n defaultRefreshInterval = this.refreshData\r\n } else if (this.refreshData === true) {\r\n defaultRefreshInterval = QuotePollingIntervalInMs.Default\r\n }\r\n\r\n const isStock = this.instrument === Instrument.Stock\r\n const isPremium = window.FinvizSettings.hasUserPremium\r\n let customRefreshInterval = QuotePollingIntervalInMs.Elite\r\n if (!isPremium) {\r\n customRefreshInterval = QuotePollingIntervalInMs.Free\r\n } else if (isStock && !Utils.isStockFastRefreshAvailable()) {\r\n customRefreshInterval = QuotePollingIntervalInMs.EliteStocksReduced\r\n }\r\n\r\n return defaultRefreshInterval && Math.max(defaultRefreshInterval, customRefreshInterval)\r\n }\r\n\r\n toObject() {\r\n const panes = this.panes()\r\n .all()\r\n .map((pane) => pane.toObject())\r\n return {\r\n width: this.width,\r\n dateRange: this.dateRange,\r\n height: this.height,\r\n timeframe: this.timeframe,\r\n scale: this.scale,\r\n leftOffset: this.leftOffset,\r\n ticker: this.ticker,\r\n instrument: this.instrument,\r\n zoomFactor: this.zoomFactor,\r\n refreshData: this.refreshData,\r\n stretch: this.stretch,\r\n chartId: this.cid,\r\n panes,\r\n isHideDrawingsActive: this.isHideDrawingsActive,\r\n isScrolled: this.isScrolled,\r\n premarket: this.premarket,\r\n aftermarket: this.aftermarket,\r\n hasChartEvents: this.hasChartEvents,\r\n }\r\n }\r\n\r\n toConfig(omitKeys = [] as string[]) {\r\n const panes = this.panes()\r\n .all()\r\n .map((pane) => pane.toConfig(omitKeys))\r\n return omit(\r\n {\r\n width: this.width,\r\n height: this.height,\r\n timeframe: this.timeframe,\r\n scale: this.scale,\r\n leftOffset: this.leftOffset,\r\n ticker: this.ticker,\r\n instrument: this.instrument,\r\n zoomFactor: this.zoomFactor,\r\n refreshData: this.refreshData,\r\n stretch: this.stretch,\r\n chartId: this.cid,\r\n panes,\r\n isHideDrawingsActive: this.isHideDrawingsActive,\r\n isScrolled: this.isScrolled,\r\n premarket: this.premarket,\r\n aftermarket: this.aftermarket,\r\n hasChartEvents: this.hasChartEvents,\r\n },\r\n omitKeys\r\n )\r\n }\r\n\r\n destroyCascade(options?: TodoObjectHashAnyType) {\r\n this.panes()\r\n .all()\r\n .forEach((pane) => {\r\n pane.destroyCascade()\r\n })\r\n return this.destroy(options)\r\n }\r\n\r\n getChartLayoutSettings() {\r\n return getChartLayoutSettings(this.chart_layout())\r\n }\r\n\r\n getIsDisabled() {\r\n return this.quote()?.close.length === 0\r\n }\r\n\r\n getIsScrollable() {\r\n return this.chart_layout().scrollable\r\n }\r\n\r\n getAllPanes() {\r\n return this.panes().all()\r\n }\r\n\r\n getAllValidPanes() {\r\n const cotKeys = Object.keys(this.quote().COTs ?? {})\r\n return this.getAllPanes().filter((pane) => {\r\n const mainElement = pane.mainElement()\r\n if (mainElement?.instance.type === IndicatorType.Cot) {\r\n // Type of mainElement is `Element` but it can be an indicator too\r\n return cotKeys.includes((mainElement.instance as unknown as COT).attrs.code)\r\n }\r\n return true\r\n })\r\n }\r\n\r\n getAllElements() {\r\n return this.getAllPanes().flatMap((pane) => pane.getAllElements())\r\n }\r\n\r\n getAllQuotes(): Quote[] {\r\n const perfQuotes = this.getAllElements()\r\n .filter(({ instance }) => instance.type === IndicatorType.Perf)\r\n .flatMap(({ instance }) => Object.values((instance as unknown as PricePerformance).quotes))\r\n\r\n let quotePerfTickers: Quote[] = []\r\n if (this.chart_layout().specificChartFunctionality === SpecificChartFunctionality.quotePerf) {\r\n const perfChart = this.getChartElement()?.instance as PerfChart | undefined\r\n if (perfChart) {\r\n quotePerfTickers = Quote.select(\r\n (q: Quote) => perfChart.attrs.tickers.includes(q.ticker) && [TIMEFRAME.d, TIMEFRAME.m].includes(q.timeframe)\r\n )\r\n }\r\n }\r\n\r\n return [...perfQuotes, ...quotePerfTickers, this.quote()].filter(\r\n (quote, index, quotes) => quote && quotes.findIndex((q) => q?.id === quote.id) === index\r\n )\r\n }\r\n\r\n createPaneCascade(paneProperties: ChartConfigChartPane) {\r\n const paneModel = this.panes().create(paneProperties)\r\n\r\n paneProperties.elements?.forEach(({ zIndex, elementId, ...element }) => {\r\n const instance = getCanvasElementByType(element.type).fromObject(element, paneModel)\r\n paneModel.elements().create({ instance, zIndex, elementId })\r\n paneModel.chart().trigger(CustomSpineEvents.IndicatorsChange)\r\n })\r\n\r\n const chartOrIndicator = paneModel.getChartOrIndicatorElement()\r\n if (paneModel.mainElement()?.elementId !== chartOrIndicator?.elementId) {\r\n paneModel.updateAttributes({ mainElement: chartOrIndicator })\r\n }\r\n\r\n return paneModel\r\n }\r\n\r\n updateAttributesAndSync(value: T) {\r\n const attrsInSync = Object.entries(ChartPartToAttrsSyncMap)\r\n .filter(([key]) => this.getIsChartPartInSync(key as unknown as ChartSyncablePart))\r\n .flatMap(([_, modelAttr]) => modelAttr)\r\n this.updateAttributes(value)\r\n\r\n if (attrsInSync.length > 0) {\r\n this.chart_layout()\r\n .getAllCharts()\r\n .forEach((chartModel) => {\r\n if (this.eql(chartModel)) {\r\n return\r\n }\r\n const newAttrs: ObjectHash = {}\r\n attrsInSync.forEach((modelAttr) => {\r\n if (value.hasOwnProperty(modelAttr)) {\r\n newAttrs[modelAttr] = value[modelAttr]\r\n }\r\n })\r\n chartModel.updateAttributes(newAttrs)\r\n })\r\n }\r\n }\r\n\r\n setSyncChartParts(chartParts: ChartSyncablePart | ChartSyncablePart[], isInSync: boolean) {\r\n this.chart_layout().setSyncChartParts(chartParts, isInSync)\r\n }\r\n\r\n getIsChartPartInSync(chartPart: ChartSyncablePart) {\r\n return this.chart_layout().getIsChartPartInSync(chartPart)\r\n }\r\n\r\n getHasPatterns() {\r\n return this.getAllElements().some((element) => {\r\n if ('hasOverlay' in element.instance) {\r\n return (element.instance as BaseChart).hasOverlay?.('patterns')\r\n }\r\n\r\n return false\r\n })\r\n }\r\n\r\n getQuoteFinancialAttachments() {\r\n return this.getAllElements()\r\n .filter((el) => el.isFinancialIndicator())\r\n .flatMap(\r\n (indicatorElement) =>\r\n ((indicatorElement.instance as unknown as any).config as typeof IndicatorBaseConfig).quoteFinancialAttachments\r\n )\r\n .filter((quoteFinancialAttachment, index, arr) => arr.indexOf(quoteFinancialAttachment) === index)\r\n }\r\n\r\n getQuoteRawTicker(): string | null {\r\n return this.quote()?.getRawTicker() ?? null\r\n }\r\n\r\n setChartEvents(chartEvents?: Array, shouldClear = false) {\r\n const chartPane = this.getChartPane()\r\n if (!chartPane) {\r\n return\r\n }\r\n const allChartEvents = chartPane.chartEvents().all()\r\n if (shouldClear) {\r\n allChartEvents.forEach((chartEvent) => chartEvent.destroyCascade())\r\n }\r\n\r\n const events = shouldClear\r\n ? chartEvents\r\n : chartEvents?.filter((chartEvent) => !allChartEvents.some(({ elementId }) => chartEvent.elementId === elementId))\r\n\r\n events?.forEach(({ elementId, eventType, dateTimestamp }) => {\r\n const newChartEvent = chartPane.chartEvents().create({\r\n instance: getCanvasElementByType(eventType).fromObject({ positionTimestamps: { x: dateTimestamp } }, chartPane),\r\n elementId,\r\n })\r\n newChartEvent.instance.updateScales()\r\n })\r\n\r\n chartPane.updateChartEventsZIndexes()\r\n }\r\n}\r\n\r\nexport default Chart\r\n","/*\r\n * it converts it to numbered index and it causes problems later on\r\n * the reason it's not just numbered enum is that it when used in const below\r\n * */\r\nexport enum ChartSyncablePart {\r\n Crosshair = 'crosshair',\r\n Ticker = 'ticker',\r\n Timeframe = 'timeframe',\r\n}\r\n\r\nexport const ChartPartToAttrsSyncMap = {\r\n [ChartSyncablePart.Ticker]: ['ticker'],\r\n [ChartSyncablePart.Timeframe]: ['timeframe', 'dateRange'],\r\n}\r\n\r\nexport const ChartSyncableParts = [\r\n { value: ChartSyncablePart.Ticker, label: 'Ticker' },\r\n { value: ChartSyncablePart.Timeframe, label: 'Timeframe' },\r\n { value: ChartSyncablePart.Crosshair, label: 'Crosshair' },\r\n]\r\n","import Spine, { Collection } from '@finviz/spine'\r\nimport omit from 'lodash.omit'\r\n\r\nimport { IIdea, RootChartConfigObject, Theme, TodoObjectHashAnyType } from '../../types/shared'\r\nimport { ChartEditorEnum, IndicatorType, LayoutType, SpecificChartFunctionality } from '../constants/common'\r\nimport { DrawingSetting } from '../controllers/toolbar/interfaces'\r\nimport Indicator from '../indicators/indicator'\r\nimport { getIsSSr } from '../utils/helpers'\r\nimport Chart from './chart'\r\nimport ChartEventElement from './chart-event-element'\r\nimport { ChartSyncablePart } from './chart/contstants'\r\nimport { ISettings } from './chart_settings/interfaces'\r\nimport DrawingsInternalStore from './drawings-internal-store'\r\nimport Pane from './pane'\r\nimport { QuoteFetchType } from './quote/constants'\r\n\r\nclass ChartLayout extends Spine.Model {\r\n static initClass(chartModel: typeof Chart, drawingsInternalStoreModel: typeof DrawingsInternalStore) {\r\n this.configure(\r\n 'ChartLayout',\r\n 'layout',\r\n 'activeChart',\r\n 'activePane',\r\n 'activeChartEvent',\r\n 'width',\r\n 'height',\r\n 'editable',\r\n 'canChangeTicker',\r\n 'scrollable',\r\n 'initialScrollable',\r\n 'cross',\r\n 'editors',\r\n 'theme',\r\n 'settings',\r\n 'isWheelZoomEnabled',\r\n 'specificChartFunctionality',\r\n 'isLargeChart',\r\n 'isHideDrawingsActive',\r\n 'isPreserveDrawingsActive',\r\n 'isLockDrawingsActive',\r\n 'isDrawingModeContinuousActive',\r\n 'uuid',\r\n 'isTouchCrossActive',\r\n 'defaultZoomFactor',\r\n 'syncChartParts',\r\n 'isInit',\r\n 'willDestroy',\r\n 'idea'\r\n )\r\n this.hasMany('charts', chartModel)\r\n this.belongsTo('drawingsInternalStore', drawingsInternalStoreModel)\r\n }\r\n\r\n declare layout: LayoutType\r\n declare activeChart: Chart\r\n declare activePane?: Pane\r\n declare activeChartEvent?: ChartEventElement\r\n declare width: number\r\n declare height: number\r\n declare editable: boolean\r\n declare canChangeTicker: boolean\r\n declare scrollable: boolean\r\n declare readonly initialScrollable: boolean\r\n declare cross: boolean\r\n declare editors: ChartEditorEnum[]\r\n declare theme: Theme\r\n declare settings: ISettings\r\n declare isWheelZoomEnabled: boolean\r\n declare specificChartFunctionality: SpecificChartFunctionality\r\n declare isLargeChart?: boolean\r\n declare charts: () => Collection\r\n declare isHideDrawingsActive: boolean\r\n declare isPreserveDrawingsActive: boolean\r\n declare isLockDrawingsActive: boolean\r\n declare isDrawingModeContinuousActive: boolean\r\n declare uuid: string\r\n declare isTouchCrossActive?: boolean\r\n declare defaultZoomFactor: number\r\n declare syncChartParts: ChartSyncablePart[]\r\n declare idea?: IIdea\r\n declare isInit?: boolean\r\n declare willDestroy?: boolean\r\n declare drawingsInternalStore: () => DrawingsInternalStore\r\n\r\n constructor(...args: any[]) {\r\n super(...args)\r\n\r\n if (!getIsSSr()) {\r\n this.bind('update', (model: ChartLayout) => {\r\n if (!window.FinvizSettings.toolsState) {\r\n window.FinvizSettings.toolsState = {}\r\n }\r\n window.FinvizSettings.toolsState[DrawingSetting.PreserveDrawings] = model.isPreserveDrawingsActive\r\n })\r\n }\r\n }\r\n\r\n getPaneWithSelection() {\r\n for (const pane of this.getAllPanes()) {\r\n if (pane.selection) {\r\n return pane\r\n }\r\n }\r\n }\r\n\r\n toObject() {\r\n const charts = this.getAllCharts().map((chart) => chart.toObject())\r\n return {\r\n layout: this.layout,\r\n width: this.width,\r\n height: this.height,\r\n charts,\r\n isHideDrawingsActive: this.isHideDrawingsActive,\r\n isPreserveDrawingsActive: this.isPreserveDrawingsActive,\r\n }\r\n }\r\n\r\n toConfig = RootChartConfigObject>(omitKeys = [] as string[]): T {\r\n const charts = this.getAllCharts().map((chart) => chart.toConfig(omitKeys))\r\n return JSON.parse(\r\n JSON.stringify(\r\n omit(\r\n {\r\n ...this.settings.ChartSettings.center,\r\n layout: this.layout,\r\n width: this.width,\r\n height: this.height,\r\n charts,\r\n isHideDrawingsActive: this.isHideDrawingsActive,\r\n isPreserveDrawingsActive: this.isPreserveDrawingsActive,\r\n colors: this.settings.ChartSettings.general.Colors,\r\n specificChartFunctionality: this.specificChartFunctionality,\r\n editors: this.editors,\r\n editable: this.editable,\r\n scrollable: this.scrollable,\r\n theme: this.theme,\r\n newCharts: /\\bcharts\\b/.test(window.location.pathname),\r\n },\r\n omitKeys\r\n )\r\n )\r\n )\r\n }\r\n\r\n destroy(options?: TodoObjectHashAnyType) {\r\n this.updateAttribute('willDestroy', true)\r\n return super.destroy(options)\r\n }\r\n\r\n destroyCascade(options?: TodoObjectHashAnyType) {\r\n this.updateAttribute('willDestroy', true)\r\n this.getAllCharts().forEach((chart) => {\r\n chart.destroyCascade()\r\n })\r\n return this.destroy(options)\r\n }\r\n\r\n getAllCharts() {\r\n return this.charts().all()\r\n }\r\n\r\n getAllPanes() {\r\n return this.getAllCharts().flatMap((chart) => chart.getAllPanes())\r\n }\r\n\r\n getAllElements() {\r\n return this.getAllCharts().flatMap((chart) => chart.getAllElements())\r\n }\r\n\r\n setSyncChartParts(chartParts: ChartSyncablePart | ChartSyncablePart[], isInSync: boolean) {\r\n const chartPartsToSync = Array.isArray(chartParts) ? chartParts : [chartParts]\r\n\r\n const newSyncedChartParts = this.syncChartParts?.filter((chartPart) => !chartPartsToSync.includes(chartPart)) ?? []\r\n\r\n if (isInSync) {\r\n newSyncedChartParts.push(...chartPartsToSync)\r\n }\r\n\r\n this.updateAttributes({ syncChartParts: newSyncedChartParts })\r\n }\r\n\r\n getIsChartPartInSync(chartPart: ChartSyncablePart) {\r\n return !!this.syncChartParts?.includes(chartPart)\r\n }\r\n\r\n getIsIndicatorPresent(type: IndicatorType) {\r\n return !!this.charts()\r\n .first()\r\n ?.getAllElements()\r\n .some((element) => element.isIndicator() && (element.instance as unknown as Indicator).type === type)\r\n }\r\n\r\n getHTMLElementId() {\r\n return `chart-layout-${this.id}`\r\n }\r\n\r\n exitIdea() {\r\n this.updateAttribute('idea', undefined)\r\n this.getAllCharts().forEach((chart) => {\r\n // Change all idea quotes to non idea quotes and refetch because we don't need them anymore, but they may cause inconsistencies if they are in cache\r\n chart.getAllQuotes().forEach((quote) => {\r\n if (quote.ideaID) {\r\n quote.updateAttributes({ ideaID: undefined })\r\n quote.fetchData({ fetchType: QuoteFetchType.Refetch })\r\n }\r\n })\r\n\r\n chart.updateAttributes({ refreshData: true })\r\n })\r\n }\r\n\r\n isIdeaId(id: number | null = null) {\r\n return (this.idea?.id ?? null) === id\r\n }\r\n}\r\n\r\nexport default ChartLayout\r\n","import { ObjectHash, Theme } from '../../../types/shared'\r\nimport { IChartThemeColors, chartDarkTheme, chartLightTheme } from '../constants'\r\n\r\nfunction normalizeHexAlpha(hexString = '') {\r\n const hexValue = hexString.replace('#', '')\r\n if (hexValue.length === 6) {\r\n return `${hexString}FF`\r\n }\r\n return hexString\r\n}\r\n\r\nexport const getColorOverwrites = ({\r\n theme,\r\n colors,\r\n}: {\r\n theme: Theme\r\n colors: ObjectHash, Theme>\r\n}) => {\r\n const customColors = colors[theme]\r\n const customColorKeys = Object.keys(customColors) as Array>\r\n const defaultColors = theme === Theme.light ? chartLightTheme : chartDarkTheme\r\n\r\n return customColorKeys.reduce((acc, colorKey) => {\r\n const isDefaultOverWritten =\r\n normalizeHexAlpha(customColors[colorKey]).toLowerCase() !==\r\n normalizeHexAlpha(defaultColors[colorKey]).toLowerCase()\r\n\r\n return isDefaultOverWritten\r\n ? {\r\n ...acc,\r\n [colorKey]: customColors[colorKey],\r\n }\r\n : acc\r\n }, {})\r\n}\r\n","import tailwindColors from '../constants/colors'\r\nimport { getHEXWithSpecificAplha } from '../utils/colors'\r\n\r\nexport interface IChartThemeColors {\r\n aftermarketFade: string\r\n background: string\r\n borderDown: string\r\n borderUp: string\r\n canvasFill: string\r\n cross: string\r\n crossText: string\r\n crossTextBackground: string\r\n currentBackground: string\r\n currentText: string\r\n grid: string\r\n gridSecondary: string\r\n indicatorCurrentBackground: string\r\n indicatorCurrentText: string\r\n line: string\r\n marketDown: string\r\n marketUp: string\r\n negativeChange: string\r\n ohlcTrendDown: string\r\n ohlcTrendUp: string\r\n overlayTransparentBackground: string\r\n percentageZeroLineText: string\r\n performanceIndicatorLabel: string\r\n positiveChange: string\r\n premarketFade: string\r\n prevClose: string\r\n text: string\r\n textSecondary: string\r\n trendDown: string\r\n trendUp: string\r\n volumeTrendDown: string\r\n volumeTrendUp: string\r\n wickDown: string\r\n wickUp: string\r\n zeroChange: string\r\n}\r\n\r\nexport interface IIndicatorThemeColors {\r\n line: string\r\n signalLine: string\r\n}\r\n\r\nexport interface IElementThemeColors {\r\n line: string\r\n border: string\r\n textWithoutBackground: string\r\n}\r\n\r\ninterface IDarkerWickColors {\r\n borderUp: string\r\n wickUp: string\r\n borderDown: string\r\n wickDown: string\r\n}\r\n\r\nexport const chartLightTheme: IChartThemeColors = {\r\n aftermarketFade: '#FFFFFF99',\r\n background: '#008CFF0E',\r\n borderDown: '#000000FF',\r\n borderUp: '#000000FF',\r\n canvasFill: '#FFFFFFFF',\r\n cross: '#0000004C',\r\n crossText: '#fff',\r\n crossTextBackground: '#111',\r\n currentBackground: tailwindColors.brightYellow[100],\r\n currentText: tailwindColors.gray[800],\r\n grid: '#D2D2D2FF',\r\n gridSecondary: '#ECECEC',\r\n indicatorCurrentBackground: tailwindColors.gray[600],\r\n indicatorCurrentText: '#fff',\r\n line: '#1E6DC0FF',\r\n marketDown: tailwindColors.red[500],\r\n marketUp: tailwindColors.green[500],\r\n negativeChange: '#C80000FF',\r\n ohlcTrendDown: '#E54040FF',\r\n ohlcTrendUp: '#40A140FF',\r\n overlayTransparentBackground: getHEXWithSpecificAplha('#C9CCD6', 0.25),\r\n percentageZeroLineText: '#111',\r\n performanceIndicatorLabel: tailwindColors.gray[600],\r\n positiveChange: '#009600FF',\r\n premarketFade: '#FFFFFF99',\r\n prevClose: '#C80000FF',\r\n text: '#828282',\r\n textSecondary: '#dedede',\r\n trendDown: '#FF0000FF',\r\n trendUp: '#00FF00FF',\r\n volumeTrendDown: '#ffc0c0',\r\n volumeTrendUp: '#a8e0a8',\r\n wickDown: '#000000FF',\r\n wickUp: '#000000FF',\r\n zeroChange: '#000',\r\n}\r\n\r\nexport const chartDarkTheme: IChartThemeColors = {\r\n aftermarketFade: '#4C526133',\r\n background: '#1E6DC019',\r\n borderDown: '#F63538FF',\r\n borderUp: '#30CC5AFF',\r\n canvasFill: tailwindColors.gray[800],\r\n cross: '#404553',\r\n crossText: '#fff',\r\n crossTextBackground: '#111',\r\n currentBackground: tailwindColors.yellow[200],\r\n currentText: tailwindColors.gray[700],\r\n grid: '#363A46FF',\r\n gridSecondary: '#2C303A',\r\n indicatorCurrentBackground: tailwindColors.gray[500],\r\n indicatorCurrentText: '#fff',\r\n line: '#1E6DC0FF',\r\n marketDown: tailwindColors.red[300],\r\n marketUp: tailwindColors.green[300],\r\n negativeChange: tailwindColors.red[400],\r\n ohlcTrendDown: '#E54040FF',\r\n ohlcTrendUp: '#40A140FF',\r\n overlayTransparentBackground: getHEXWithSpecificAplha('#0C0E13', 0.35),\r\n percentageZeroLineText: '#fff',\r\n performanceIndicatorLabel: tailwindColors.gray[300],\r\n positiveChange: tailwindColors.green[400],\r\n premarketFade: '#4C526133',\r\n prevClose: '#C80000FF',\r\n text: '#929cb3',\r\n textSecondary: '#929CB399',\r\n trendDown: '#F63538FF',\r\n trendUp: '#30CC5AFF',\r\n volumeTrendDown: '#F635387F',\r\n volumeTrendUp: '#30CC5A7F',\r\n wickDown: '#F63538FF',\r\n wickUp: '#30CC5AFF',\r\n zeroChange: '#929cb3',\r\n}\r\n\r\nexport const darkerWickColors: IDarkerWickColors = {\r\n borderUp: '#006400FF',\r\n wickUp: '#006400',\r\n borderDown: '#6E0000FF',\r\n wickDown: '#6E0000FF',\r\n}\r\n\r\nexport const indicatorLightTheme: IIndicatorThemeColors = {\r\n line: '#000000',\r\n signalLine: tailwindColors.red[400],\r\n}\r\n\r\nexport const indicatorDarkTheme: IIndicatorThemeColors = {\r\n line: '#D07933',\r\n signalLine: tailwindColors.red[400],\r\n}\r\n\r\nexport const elementLightTheme: IElementThemeColors = {\r\n line: '#000000',\r\n border: '#000000',\r\n textWithoutBackground: '#000000',\r\n}\r\n\r\nexport const elementDarkTheme: IElementThemeColors = {\r\n line: '#5faaf4',\r\n border: '#5192D1',\r\n textWithoutBackground: '#929cb3',\r\n}\r\nexport const generalColors: Array = [\r\n '#1f77b4',\r\n '#ff7f0e',\r\n '#2ca02c',\r\n '#d62728',\r\n '#9467bd',\r\n '#8c564b',\r\n '#e377c2',\r\n '#7f7f7f',\r\n '#bcbd22',\r\n '#17becf',\r\n]\r\n\r\n// node chart with thin bars color override\r\nexport const thinBarColorsOverride = {\r\n trendUp: '#00b400',\r\n trendDown: '#b40000',\r\n}\r\n\r\nexport enum AutoSaveState {\r\n Off,\r\n Saved,\r\n Unsaved,\r\n Saving,\r\n}\r\n\r\nexport const CHART_EVENT_BADGE_SIZE = 24\r\n","import Spine from '@finviz/spine'\r\n\r\nimport { AutoSaveElement } from '../controllers/autosave/constants'\r\nimport { getUuid } from '../utils/helpers'\r\nimport { HLC, initHlc } from '../utils/hlc'\r\nimport { AutoSaveState } from './constants'\r\n\r\ninterface DrawingsInternalStateAttrs {\r\n elements: AutoSaveElement[]\r\n latestRemoteUpdateTimestamp: HLC\r\n latestLocalUpdateTimestamp: HLC\r\n instanceUUID: string\r\n autoSaveState: AutoSaveState\r\n}\r\n\r\nclass DrawingsInternalStore extends Spine.Model {\r\n static initClass() {\r\n this.configure(\r\n 'DrawingsInternalState',\r\n 'elements',\r\n 'latestRemoteUpdateTimestamp',\r\n 'latestLocalUpdateTimestamp',\r\n 'autoSaveState',\r\n 'instanceUUID'\r\n )\r\n }\r\n\r\n elements: AutoSaveElement[]\r\n latestRemoteUpdateTimestamp: HLC\r\n latestLocalUpdateTimestamp: HLC\r\n instanceUUID: string\r\n autoSaveState: AutoSaveState\r\n\r\n constructor(attrs: Partial = {}) {\r\n super(attrs)\r\n\r\n this.elements = attrs.elements ?? []\r\n this.instanceUUID = attrs.instanceUUID ?? getUuid()\r\n this.latestLocalUpdateTimestamp = attrs.latestLocalUpdateTimestamp ?? initHlc(this.instanceUUID, 0)\r\n this.latestRemoteUpdateTimestamp = attrs.latestRemoteUpdateTimestamp ?? initHlc(this.instanceUUID, 0)\r\n this.autoSaveState = attrs.autoSaveState ?? AutoSaveState.Off\r\n }\r\n\r\n setAutoSaveState = (newAutoSaveState: AutoSaveState) => {\r\n if (this.autoSaveState !== newAutoSaveState) {\r\n this.updateAttributes({ autoSaveState: newAutoSaveState })\r\n }\r\n }\r\n}\r\n\r\nexport default DrawingsInternalStore\r\n","import Spine from '@finviz/spine'\r\nimport merge from 'lodash.merge'\r\n\r\nimport { TodoObjectHashAnyType } from '../../types/shared'\r\nimport { drawingToolsByType } from '../canvas/drawingTools'\r\nimport CanvasElement from '../canvas/element'\r\nimport { CanvasElementType, IndicatorType } from '../constants/common'\r\nimport { financialIndicators } from '../indicators/indicators'\r\nimport { getIsSSr, getUuid } from '../utils/helpers'\r\nimport Pane from './pane'\r\nimport { changeElementZIndexes } from './utils'\r\n\r\nclass Element extends Spine.Model {\r\n static initClass(paneModel: typeof Pane) {\r\n this.configure('Element', 'instance', 'lastChange', 'zIndex', 'elementId')\r\n this.belongsTo('pane', paneModel)\r\n }\r\n\r\n declare instance: CanvasElement\r\n declare pane_id: string\r\n declare destroyed: true | undefined\r\n declare pane: () => Pane\r\n lastChange: number | null = null\r\n elementId: string | null = null\r\n zIndex = -1\r\n\r\n generateUuid = getIsSSr() ? undefined : getUuid\r\n\r\n constructor(...args: any[]) {\r\n super(...args)\r\n const elementAttrs = args[0]\r\n this.elementId = elementAttrs?.elementId ?? this.generateUuid?.()\r\n this.one('create', () => {\r\n this.updateAttributes({\r\n zIndex: elementAttrs?.zIndex ?? this.pane().getElementZIndexRange().max + 1,\r\n })\r\n })\r\n }\r\n\r\n replace(instance: CanvasElement) {\r\n const oldInstance = this.instance\r\n this.updateAttribute('instance', instance)\r\n this.trigger('replace', this, oldInstance)\r\n }\r\n\r\n makeClone() {\r\n const { instance, pane_id } = this\r\n const { attrs } = instance\r\n const { scale } = instance.model\r\n const clonedObj = merge({ pane_id }, attrs)\r\n const cloned = drawingToolsByType[instance.type as CanvasElementType].fromObject(clonedObj, instance.model)\r\n const { ThumbSettings } = this.pane().getChartLayoutSettings()\r\n const offset = ThumbSettings.size + ThumbSettings.borderWidth * 2\r\n cloned.moveBy(scale.x.invert(offset), scale.y.invert(offset) - scale.y.invert(0))\r\n cloned.cachePointPositionTimestamp()\r\n Element.create({ instance: cloned, pane_id })\r\n this.trigger('makeClone', this, cloned)\r\n }\r\n\r\n moveToZIndex(zIndex: number) {\r\n const currentZIndex = this.zIndex\r\n const directionCoef = zIndex > currentZIndex ? 1 : -1\r\n\r\n if (this.isChart() || this.isIndicator()) {\r\n if (this.zIndex !== 0) {\r\n this.updateAttributes({ zIndex: 0 })\r\n }\r\n this.pane()\r\n .getAllElements()\r\n .filter((element) => {\r\n const shouldMove = directionCoef === 1 ? element.zIndex <= zIndex : element.zIndex >= zIndex\r\n return shouldMove && element.isDrawing()\r\n })\r\n .forEach((element) => element.moveToZIndex(directionCoef * -1))\r\n\r\n return\r\n }\r\n\r\n const newZIndex = zIndex === 0 ? directionCoef : zIndex // 0 is protected value for chart/indicator element\r\n const { min, max } = this.pane().getElementZIndexRange()\r\n if (\r\n currentZIndex === newZIndex ||\r\n (currentZIndex === min && directionCoef === -1) ||\r\n (currentZIndex === max && directionCoef === 1)\r\n ) {\r\n return\r\n }\r\n const { elementsBelowZero, elementsAboveZero } = this.pane().getBelowAboveZeroElements()\r\n\r\n changeElementZIndexes({\r\n elementsArray: elementsBelowZero,\r\n addElement: newZIndex < 0 ? this : undefined,\r\n oldZIndex: currentZIndex,\r\n newZIndex,\r\n isBelowZero: true,\r\n })\r\n\r\n changeElementZIndexes({\r\n elementsArray: elementsAboveZero,\r\n addElement: newZIndex > 0 ? this : undefined,\r\n oldZIndex: currentZIndex,\r\n newZIndex,\r\n })\r\n }\r\n\r\n bringToFront() {\r\n this.moveToZIndex(this.pane().getElementZIndexRange().max + 1)\r\n }\r\n\r\n sendToBack() {\r\n this.moveToZIndex(this.pane().getElementZIndexRange().min - 1)\r\n }\r\n\r\n bringForward() {\r\n this.moveToZIndex(this.zIndex + 1)\r\n }\r\n\r\n sendBackward() {\r\n this.moveToZIndex(this.zIndex - 1)\r\n }\r\n\r\n isChart() {\r\n return !!this.instance?.type.startsWith('charts/')\r\n }\r\n\r\n isFinancialIndicator() {\r\n return this.isIndicator() && financialIndicators.includes(this.instance!.type as IndicatorType)\r\n }\r\n\r\n isIndicator() {\r\n return !!this.instance?.type.startsWith('indicators/')\r\n }\r\n\r\n isOverlay() {\r\n return !!this.instance?.type.startsWith('overlays/')\r\n }\r\n\r\n isDrawing() {\r\n return !!this.instance?.type.startsWith('canvas/')\r\n }\r\n\r\n isChartEvent() {\r\n return !!this.instance?.type.startsWith('chartEvent/')\r\n }\r\n\r\n isMouseDown() {\r\n return !!this.instance?.isMouseDown\r\n }\r\n\r\n hasOngoingInteraction() {\r\n return this.isMouseDown() || this.instance.isEditInProgress\r\n }\r\n\r\n toObject() {\r\n return {\r\n ...this.instance.toObject(),\r\n elementId: this.elementId,\r\n zIndex: this.zIndex,\r\n }\r\n }\r\n\r\n toConfig() {\r\n return {\r\n ...this.instance.toConfig(),\r\n elementId: this.elementId,\r\n zIndex: this.zIndex,\r\n }\r\n }\r\n\r\n destroyCascade(options?: TodoObjectHashAnyType) {\r\n return this.destroy(options)\r\n }\r\n\r\n refreshElementId() {\r\n this.updateAttribute('elementId', this.generateUuid?.())\r\n }\r\n}\r\n\r\nexport default Element\r\n","import endOfDay from 'date-fns/endOfDay'\r\nimport lastDayOfMonth from 'date-fns/lastDayOfMonth'\r\nimport lastDayOfWeek from 'date-fns/lastDayOfWeek'\r\nimport setDate from 'date-fns/set'\r\n\r\nimport { TIMEFRAME, TIMEFRAMES_WITH_PRE_MARKET } from '../../constants/common'\r\nimport { convertLocalToNyTime, dateFromUnixTimestamp } from '../../utils'\r\nimport Chart from '../chart'\r\n\r\nconst MARKET_START = { hours: 9, minutes: 30 }\r\nconst END_OF_DAY = { hours: 23, minutes: 59 }\r\n\r\nfunction getIsDateBeforeMarketStart(date: Date) {\r\n const hours = date.getHours()\r\n const minutes = date.getMinutes()\r\n return hours < MARKET_START.hours || (hours === MARKET_START.hours && minutes < MARKET_START.minutes)\r\n}\r\n\r\nexport function roundTimeForSyncedPane({\r\n sourceChart,\r\n targetChart,\r\n timestamp,\r\n}: {\r\n sourceChart: Chart\r\n targetChart: Chart\r\n timestamp: number\r\n}) {\r\n let dateToReturn = dateFromUnixTimestamp(timestamp)\r\n const sourceChartHasPremarket =\r\n sourceChart.quote().premarket && TIMEFRAMES_WITH_PRE_MARKET.includes(sourceChart.timeframe)\r\n const targetChartHasPremarket =\r\n targetChart.quote().premarket && TIMEFRAMES_WITH_PRE_MARKET.includes(targetChart.timeframe)\r\n\r\n if ([TIMEFRAME.d, TIMEFRAME.w, TIMEFRAME.m].includes(sourceChart.timeframe)) {\r\n dateToReturn = setDate(dateToReturn, MARKET_START)\r\n }\r\n\r\n if (targetChart.timeframe === TIMEFRAME.m) {\r\n dateToReturn = setDate(lastDayOfMonth(dateToReturn), END_OF_DAY)\r\n } else if (targetChart.timeframe === TIMEFRAME.w) {\r\n dateToReturn = setDate(lastDayOfWeek(dateToReturn, { weekStartsOn: 1 }), END_OF_DAY)\r\n } else if (targetChart.timeframe === TIMEFRAME.d && targetChart.quote().instrument !== 'stock') {\r\n dateToReturn = endOfDay(dateToReturn)\r\n }\r\n\r\n if (sourceChartHasPremarket && !targetChartHasPremarket && targetChart.quote().instrument === 'stock') {\r\n dateToReturn = getIsDateBeforeMarketStart(dateToReturn) ? setDate(dateToReturn, MARKET_START) : dateToReturn\r\n }\r\n\r\n return ~~(convertLocalToNyTime(dateToReturn, false).getTime() / 1000)\r\n}\r\n","import Spine from '@finviz/spine'\r\n\r\nimport { ChartSyncablePart } from '../chart/contstants'\r\nimport Pane from '../pane'\r\nimport { roundTimeForSyncedPane } from './mouse-utils'\r\n\r\nexport class Mouse extends Spine.Model {\r\n static initClass() {\r\n this.configure('Mouse', 'position')\r\n this.belongsTo('pane', Pane)\r\n }\r\n\r\n declare position: { x: number; y: number } | undefined\r\n declare pane: () => Pane | null\r\n\r\n getIsCrossSyncOn = () => !!this.pane()?.chart().getIsChartPartInSync(ChartSyncablePart.Crosshair)\r\n\r\n getIsMouseInChartOfPane = (pane: Pane) => !!this.pane()?.chart().eql(pane.chart())\r\n\r\n getShouldRenderCrossInPane = (pane: Pane) => this.getIsCrossSyncOn() || this.getIsMouseInChartOfPane(pane)\r\n\r\n getCrossIndexForPane = (pane: Pane) => {\r\n if (this.position) {\r\n if (this.getIsMouseInChartOfPane(pane)) {\r\n return Math.round(this.position.x)\r\n }\r\n const paneOfMouse = this.pane()\r\n if (this.getIsCrossSyncOn() && paneOfMouse) {\r\n const mouseInChart = paneOfMouse.chart()\r\n const currentPaneChart = pane.chart()\r\n const mousePositionTimestamp = mouseInChart.quote().getTimestampFomPositionX(Math.round(this.position.x))\r\n const currentPanePositionX = currentPaneChart.quote().getPositionXFromTimestamp(\r\n roundTimeForSyncedPane({\r\n sourceChart: mouseInChart,\r\n targetChart: currentPaneChart,\r\n timestamp: mousePositionTimestamp,\r\n })\r\n )\r\n return Math.floor(currentPanePositionX)\r\n }\r\n }\r\n\r\n return Number.NaN\r\n }\r\n\r\n getPriceForPane = (pane: Pane) => {\r\n const positionY = this.position?.y ?? null\r\n\r\n if (this.pane()?.eql(pane)) {\r\n return positionY\r\n }\r\n\r\n if (this.getIsCrossSyncOn() && this.pane()) {\r\n const mousePaneIndex = this.pane()?.getIndexInChart()\r\n const currentPaneIndex = pane.getIndexInChart()\r\n return mousePaneIndex === currentPaneIndex ? positionY : null\r\n }\r\n\r\n return null\r\n }\r\n}\r\n\r\n/**\r\n * Mouse is a singleton, so `initClass` must be called before we create the instance\r\n * otherwise it wouldn’t work\r\n */\r\nMouse.initClass()\r\n\r\nconst mouse = Mouse.create()\r\nmouse.save()\r\n\r\nexport default mouse as Mouse\r\n","import Spine, { Collection } from '@finviz/spine'\r\nimport omit from 'lodash.omit'\r\n\r\nimport { Position, TodoObjectHashAnyType } from '../../types/shared'\r\nimport CanvasElement from '../canvas/element'\r\nimport { ChartEventBadgeType, PANE_HEIGHT_DEFAULT } from '../constants/common'\r\nimport Chart from './chart'\r\nimport ChartEventElement from './chart-event-element'\r\nimport Element from './element'\r\nimport { getChartLayoutSettings } from './settings'\r\nimport { rebuildElementZIndexes } from './utils'\r\n\r\nexport interface ScaleAxis {\r\n (index: number): number\r\n invert: (x: number) => number\r\n domain: () => [currentDomainMax: number, currentDomainMin: number]\r\n width: (x: number) => number\r\n height: (y: number) => number\r\n ticks: (y: number) => number[]\r\n}\r\n\r\nconst CHART_EVENT_BADGE_TYPE_ORDER = [\r\n ChartEventBadgeType.Split,\r\n ChartEventBadgeType.Dividends,\r\n ChartEventBadgeType.EarningsPositive,\r\n ChartEventBadgeType.EarningsNegative,\r\n ChartEventBadgeType.EarningsNeutral,\r\n ChartEventBadgeType.EarningsFuture,\r\n]\r\n\r\nclass Pane extends Spine.Model {\r\n static initClass(\r\n elementModel: typeof Element,\r\n chartEventElementModel: typeof ChartEventElement,\r\n chartModel: typeof Chart\r\n ) {\r\n this.configure('Pane', 'height', 'scale', 'scaleRange', 'instance', 'selection')\r\n this.hasMany('elements', elementModel)\r\n this.hasMany('chartEvents', chartEventElementModel)\r\n this.belongsTo('mainElement', elementModel)\r\n this.belongsTo('chart', chartModel)\r\n }\r\n\r\n declare id: string\r\n declare chart_id: string\r\n declare height: number\r\n declare scale: {\r\n x: ScaleAxis\r\n y: ScaleAxis\r\n }\r\n\r\n declare instance: any\r\n declare chart: () => Chart\r\n declare mainElement: () => T | null\r\n declare elements: () => Collection\r\n declare chartEvents: () => Collection\r\n selection: CanvasElement | null = null\r\n scaleRange: { min: number; max: number } | null = null\r\n\r\n destroyCascade(options?: TodoObjectHashAnyType) {\r\n this.elements()\r\n .all()\r\n .forEach((element) => {\r\n element.destroyCascade()\r\n })\r\n return this.destroy(options)\r\n }\r\n\r\n toObject() {\r\n const elements = this.elements()\r\n .all()\r\n .map((el) => el.toObject())\r\n return {\r\n height: this.height,\r\n scale: this.scale,\r\n scaleRange: this.scaleRange,\r\n elements,\r\n }\r\n }\r\n\r\n toConfig(omitKeys = [] as string[]) {\r\n const elements = this.elements()\r\n .all()\r\n .map((el) => el.toConfig())\r\n return omit(\r\n {\r\n height: this.height,\r\n scaleRange: this.scaleRange,\r\n elements,\r\n },\r\n omitKeys\r\n )\r\n }\r\n\r\n move(direction: Position) {\r\n const chartPanes = this.chart().getAllPanes()\r\n const chartPane = chartPanes.find((pane) => !pane.getIsIndicatorPane())\r\n const targetPane = chartPanes.find((pane) => this.eql(pane))\r\n\r\n if (!chartPane || !targetPane) return\r\n\r\n const currentChartPaneRecords = Pane.records.filter((pane) => pane.chart_id === targetPane.chart_id)\r\n const ohterChartPaneRecords = Pane.records.filter((pane) => pane.chart_id !== targetPane.chart_id)\r\n\r\n const targetRecordIndex = currentChartPaneRecords.findIndex((record) => record.id === targetPane.id)\r\n const arrayWithoutTargetRecord = currentChartPaneRecords.filter((_, index) => index !== targetRecordIndex)\r\n const chartRecordIndex = arrayWithoutTargetRecord.findIndex((record) => record.id === chartPane.id)\r\n\r\n const panesAbove = arrayWithoutTargetRecord.slice(0, chartRecordIndex)\r\n const panesBelow = arrayWithoutTargetRecord.slice(chartRecordIndex + 1)\r\n if (direction === Position.Above) {\r\n panesAbove.push(currentChartPaneRecords[targetRecordIndex])\r\n panesAbove.sort((a, b) => a.getNumericId() - b.getNumericId())\r\n }\r\n if (direction === Position.Below) {\r\n panesBelow.push(currentChartPaneRecords[targetRecordIndex])\r\n panesBelow.sort((a, b) => a.getNumericId() - b.getNumericId())\r\n }\r\n\r\n Pane.records = ohterChartPaneRecords.concat([\r\n ...panesAbove,\r\n arrayWithoutTargetRecord[chartRecordIndex],\r\n ...panesBelow,\r\n ])\r\n this.chart().trigger('change', this.chart())\r\n }\r\n\r\n getChartLayoutSettings() {\r\n return getChartLayoutSettings(this.chart().chart_layout())\r\n }\r\n\r\n getAllElements() {\r\n return this.elements()\r\n .all()\r\n .sort((a, b) => a.zIndex - b.zIndex)\r\n }\r\n\r\n getAllChartEvents(isSorted = true) {\r\n const chartEvents = [...this.chartEvents().all()]\r\n return isSorted ? chartEvents.sort((a, b) => a.zIndex - b.zIndex) : chartEvents\r\n }\r\n\r\n getChartOrIndicatorElement() {\r\n return this.getAllElements().find((el) => el.isChart() || el.isIndicator()) ?? null\r\n }\r\n\r\n getIsIndicatorPane() {\r\n return !!this.mainElement()?.isIndicator()\r\n }\r\n\r\n getIsChartPane() {\r\n return !!this.mainElement()?.isChart()\r\n }\r\n\r\n resetHeight() {\r\n if (this.getIsIndicatorPane()) {\r\n this.updateAttribute('height', PANE_HEIGHT_DEFAULT.indicator)\r\n }\r\n if (this.getIsChartPane()) {\r\n this.updateAttribute('height', PANE_HEIGHT_DEFAULT.chart)\r\n }\r\n }\r\n\r\n getIndexInChart() {\r\n return this.chart()\r\n .getAllPanes()\r\n .findIndex((chartPane) => chartPane.eql(this))\r\n }\r\n\r\n getElementZIndexRange() {\r\n let max = -1\r\n let min = 1\r\n this.getAllElements().forEach((el) => {\r\n if (el.zIndex > max) {\r\n max = el.zIndex\r\n }\r\n if (el.zIndex < min) {\r\n min = el.zIndex\r\n }\r\n })\r\n return { min, max }\r\n }\r\n\r\n getBelowAboveZeroElements() {\r\n const allPaneElements = this.getAllElements()\r\n const elementsBelowZero: Element[] = []\r\n const elementsAboveZero: Element[] = []\r\n allPaneElements.forEach((el) => {\r\n if (el.zIndex < 0) {\r\n elementsBelowZero.push(el)\r\n }\r\n if (el.zIndex > 0) {\r\n elementsAboveZero.push(el)\r\n }\r\n })\r\n\r\n return { elementsBelowZero, elementsAboveZero }\r\n }\r\n\r\n normalizeZIndexes() {\r\n const { elementsBelowZero, elementsAboveZero } = this.getBelowAboveZeroElements()\r\n rebuildElementZIndexes({ elementsArray: elementsBelowZero, isBelowZero: true })\r\n rebuildElementZIndexes({ elementsArray: elementsAboveZero, isBelowZero: false })\r\n }\r\n\r\n getQuoteRawTicker() {\r\n return this.chart().getQuoteRawTicker()\r\n }\r\n\r\n getNumericId() {\r\n return Number(this.id.replace('c-', ''))\r\n }\r\n\r\n updateChartEventsZIndexes() {\r\n if (!this.scale || !this.scale.hasOwnProperty('x')) {\r\n return\r\n }\r\n\r\n const chartEvents = this.getAllChartEvents(false).sort(\r\n (a, b) => a.instance.attrs.positionTimestamps!.x - b.instance.attrs.positionTimestamps!.x\r\n )\r\n const hoveredChartEvent = chartEvents.find((chartEvent) => chartEvent.instance.isHovered)\r\n const openedChartEvent = chartEvents.find((chartEvent) => chartEvent.instance.isOpen)\r\n\r\n const hoveredTypeChartEventElements: ChartEventElement[] = []\r\n const openedTypeChartEventElements: ChartEventElement[] = []\r\n const nonActiveChartEventElements: ChartEventElement[] = []\r\n\r\n chartEvents.forEach((chartEvent, index) => {\r\n const chartEventsOnSameXPoint = chartEvents.filter(\r\n (chartEvent_B, i) =>\r\n i < index && Math.round(chartEvent.instance.attrs.x) === Math.round(chartEvent_B!.instance.attrs.x)\r\n )\r\n chartEvent.updateAttributes({ yIndex: chartEventsOnSameXPoint.length })\r\n const isHovered = chartEvent.instance === hoveredChartEvent?.instance\r\n const isOpened = chartEvent.instance === openedChartEvent?.instance\r\n const isHoveredType = chartEvent.instance.type === hoveredChartEvent?.instance.type\r\n const isOpenType = chartEvent.instance.type === openedChartEvent?.instance.type\r\n if (!isHovered || !isOpened) {\r\n if (isHoveredType) {\r\n hoveredTypeChartEventElements.push(chartEvent)\r\n } else if (isOpenType) {\r\n openedTypeChartEventElements.push(chartEvent)\r\n } else {\r\n nonActiveChartEventElements.push(chartEvent)\r\n }\r\n }\r\n })\r\n\r\n nonActiveChartEventElements.sort(\r\n (a, b) =>\r\n CHART_EVENT_BADGE_TYPE_ORDER.indexOf(a.instance.getChartEvenBadgeType()) -\r\n CHART_EVENT_BADGE_TYPE_ORDER.indexOf(b.instance.getChartEvenBadgeType())\r\n )\r\n\r\n const chartEventElements = [\r\n ...nonActiveChartEventElements,\r\n ...openedTypeChartEventElements,\r\n openedChartEvent,\r\n ...hoveredTypeChartEventElements,\r\n hoveredChartEvent,\r\n ].filter(Boolean)\r\n chartEventElements.forEach((chartEvent, index) => {\r\n chartEvent!.updateAttributes({ zIndex: index })\r\n })\r\n }\r\n}\r\n\r\nexport default Pane\r\n","import { ObjectHash, RequireByKey } from '../../types/shared'\r\n\r\ninterface HeikinAshiData {\r\n HAOpen: number[]\r\n HAClose: number[]\r\n}\r\n\r\ninterface QuoteValues {\r\n cachedAt: null | number\r\n dayToOffset: ObjectHash[]\r\n dateToIndex: ObjectHash[]\r\n heikinAshiData?: HeikinAshiData\r\n daysInQuote: Date[]\r\n}\r\n\r\ninterface QuoteCacheFunctionProps {\r\n cid: string\r\n key: keyof QuoteValues\r\n fetchedAt: number\r\n value: any\r\n}\r\n\r\nconst quoteCache = {} as ObjectHash\r\n\r\nexport function getCachedQuote({\r\n cid,\r\n key,\r\n fetchedAt,\r\n}: RequireByKey>, 'cid'>) {\r\n const quote = quoteCache[cid]\r\n if (quote?.cachedAt === fetchedAt && key) {\r\n return quote[key]\r\n } else if (!key) {\r\n return quote\r\n }\r\n return null\r\n}\r\n\r\nexport function setCachedQuote({\r\n cid,\r\n key,\r\n value,\r\n fetchedAt,\r\n}: Pick) {\r\n quoteCache[cid] = {\r\n ...(quoteCache[cid]?.cachedAt === fetchedAt ? quoteCache[cid] : {}),\r\n [key]: value,\r\n cachedAt: fetchedAt,\r\n } as QuoteValues\r\n}\r\n\r\nexport function deleteCachedQuote({ cid }: Pick) {\r\n delete quoteCache[cid]\r\n}\r\n","import Spine from '@finviz/spine'\r\nimport { isSameDay, isSameMonth, isSameWeek } from 'date-fns'\r\nimport omit from 'lodash.omit'\r\nimport queryString from 'query-string'\r\n\r\nimport { Instrument, ObjectHash, RootChartConfigObject, TodoObjectHashAnyType } from '../../types/shared'\r\nimport {\r\n ChartEventDbType,\r\n ChartEventType,\r\n IntradayTimeframeInterval,\r\n QuoteFinancialAttachment,\r\n TIMEFRAME,\r\n} from '../constants/common'\r\nimport type { ICOT } from '../indicators/cot'\r\nimport { convertLocalToNyTime, dateFromUnixTimestamp, dateStringFromDate } from '../utils'\r\nimport { getIsAbortError } from '../utils/abort_controller'\r\nimport { getPositionXFromTimestamp, getTimestampFromPositionX } from '../utils/chart'\r\nimport { IDividends, IEarnings, ISplit } from '../utils/chart-events-utils'\r\nimport fetchApi, { NotFoundError } from '../utils/fetch_api'\r\nimport { getIsSSr } from '../utils/helpers'\r\nimport { QuoteFetchType, QuoteFetchTypeUrlOption, QuoteUrlOptions } from './quote/constants'\r\nimport { FinancialAttachmentsData, ShortInterestData } from './quote/financialAttachmentsData'\r\nimport { deleteCachedQuote, getCachedQuote, setCachedQuote } from './quoteCache'\r\nimport { getRawTickerForInstrument } from './utils'\r\n\r\nconst quoteRefreshChecksBeforeFullRefresh = 15\r\n\r\ntype TodoPattern = TodoObjectHashAnyType\r\n\r\nexport interface TickerTimeframesProps {\r\n ticker: string\r\n instrument: string\r\n timeframe: string\r\n}\r\n\r\ninterface QuoteFetchOptions {\r\n aftermarket?: boolean\r\n premarket?: boolean\r\n patterns?: boolean\r\n events?: boolean\r\n maxBars?: number\r\n financialAttachments?: string[]\r\n}\r\n\r\ninterface QuoteInternalOptions {\r\n cachePredicate?: (quote: Quote) => boolean\r\n fetchNewDataOnCachedQuote?: boolean\r\n}\r\n\r\ninterface UrlOptions extends Omit {\r\n ticker: string\r\n instrument: string\r\n timeframe: string\r\n financialAttachments?: string\r\n}\r\n\r\ntype ChartEventDataRaw = Omit & { eventType: ChartEventDbType }\r\n\r\nexport interface DataResponse {\r\n COTs: COTData\r\n name: string\r\n ticker: string\r\n instrument: string\r\n interval: number\r\n timeframe: string\r\n open: number[]\r\n high: number[]\r\n low: number[]\r\n close: number[]\r\n date: number[]\r\n volume: number[]\r\n lastOpen: number\r\n lastHigh: number\r\n lastLow: number\r\n lastClose: number\r\n lastDate: number\r\n lastTime: string | null\r\n lastVolume: number\r\n dataId: string\r\n prevClose: number\r\n afterClose: number\r\n afterChange: number\r\n afterTime: string | null\r\n drawMinutesPerDay: number\r\n marketStartMinutes: number\r\n premarketLengthMinutes: number\r\n aftermarketLengthMinutes: number\r\n aftermarket: boolean\r\n premarket: boolean\r\n hasPatterns: boolean\r\n patterns: Array\r\n patternsMinRange: number\r\n patternsMaxRange: number\r\n relativeVolume: number\r\n isIntraday: boolean\r\n noNewData?: boolean\r\n chartEvents?: ChartEventDataRaw[]\r\n financialAttachmentsData?: FinancialAttachmentsData\r\n}\r\n\r\ninterface COTData {\r\n [code: string]: ICOT\r\n}\r\n\r\nconst getEmptyQuote = () => ({\r\n open: [],\r\n high: [],\r\n low: [],\r\n close: [],\r\n volume: [],\r\n date: [],\r\n fetchedAt: -1,\r\n numberOfRefreshChecks: 0,\r\n isFetching: false,\r\n is404: false,\r\n COTs: undefined,\r\n name: undefined,\r\n drawMinutesPerDay: undefined,\r\n marketStartMinutes: undefined,\r\n premarketLengthMinutes: undefined,\r\n aftermarketLengthMinutes: undefined,\r\n patterns: [],\r\n patternsMinRange: undefined,\r\n patternsMaxRange: undefined,\r\n relativeVolume: undefined,\r\n lastOpen: undefined,\r\n lastHigh: undefined,\r\n lastLow: undefined,\r\n lastClose: undefined,\r\n lastVolume: undefined,\r\n dataId: undefined,\r\n lastDate: undefined,\r\n prevClose: undefined,\r\n afterClose: undefined,\r\n afterChange: undefined,\r\n chartEvents: [],\r\n financialAttachments: [],\r\n financialAttachmentsData: null,\r\n})\r\n\r\ninterface ICacheAvailabilityCheckFunctionsArguments {\r\n quote: Quote\r\n options?: QuoteFetchOptions & QuoteInternalOptions\r\n}\r\n\r\nconst doesQuoteAndOptionsMatch = ({ quote, options }: ICacheAvailabilityCheckFunctionsArguments) =>\r\n !quote.premarket === !options?.premarket &&\r\n !quote.aftermarket === !options?.aftermarket &&\r\n !quote.hasPatterns === !options?.patterns &&\r\n // if options.events is false we can reuse quote with events\r\n (!options?.events || !!quote.events) &&\r\n // Either has no financialAttachments or require all of them to match\r\n ((options?.financialAttachments?.length ?? 0) === 0 ||\r\n options!.financialAttachments!.every((financialAttachment) =>\r\n quote.financialAttachments?.includes(financialAttachment as QuoteFinancialAttachment)\r\n ))\r\n\r\nconst doesQuoteAndFetchParamsMatch = ({\r\n quote,\r\n ticker,\r\n instrument,\r\n timeframe,\r\n}: {\r\n quote: Quote\r\n ticker: string\r\n instrument: Instrument\r\n timeframe: TIMEFRAME\r\n}) => quote.ticker === ticker && quote.instrument === instrument && quote.timeframe === timeframe\r\n\r\n// either we don't care about matching uuid at all, or they have to match\r\nconst isSameOrNoChartUuid = ({ quote, uuid }: { quote: Quote; uuid?: string }) => !uuid || quote.chartUuid === uuid\r\n\r\nconst isCacheAllowed = ({ quote, options }: ICacheAvailabilityCheckFunctionsArguments) =>\r\n !options?.cachePredicate || options.cachePredicate(quote)\r\n\r\nconst isNotEmptyQuote = (quote: Quote) => quote.fetchedAt !== -1 || quote.isFetching || !!quote.is404\r\n\r\nexport type QuoteGetParams = {\r\n ticker: string\r\n instrument: Instrument\r\n timeframe: TIMEFRAME\r\n options?: QuoteFetchOptions & QuoteInternalOptions\r\n abortController?: null | AbortController\r\n shouldUseCache?: boolean\r\n chartUuid?: string\r\n}\r\n\r\nfunction getChartEventsWithId({ ticker, chartEvents }: { ticker: string; chartEvents?: ChartEventDataRaw[] }) {\r\n return (\r\n chartEvents?.map((item) => {\r\n let eventType: ChartEventType\r\n switch (item.eventType) {\r\n case ChartEventDbType.Dividends:\r\n eventType = ChartEventType.Dividends\r\n break\r\n case ChartEventDbType.Split:\r\n eventType = ChartEventType.Split\r\n break\r\n case ChartEventDbType.Earnings:\r\n eventType = ChartEventType.Earnings\r\n break\r\n }\r\n return {\r\n ...item,\r\n elementId: `${ticker.toLowerCase()}-${item.eventType}-${item.dateTimestamp}`,\r\n eventType,\r\n }\r\n }) ?? []\r\n )\r\n}\r\n\r\nclass Quote extends Spine.Model {\r\n static computableKeys = [\r\n 'isIntraday',\r\n 'interval',\r\n 'drawDays',\r\n 'barIndex',\r\n 'barToDataIndex',\r\n 'alignedFinancialAttachmentsData',\r\n 'timestampToFinancialsIndexesMap',\r\n ]\r\n\r\n static initClass() {\r\n this.configure(\r\n 'Quote',\r\n 'ticker',\r\n 'name',\r\n 'instrument',\r\n 'timeframe',\r\n 'open',\r\n 'high',\r\n 'low',\r\n 'close',\r\n 'date',\r\n 'volume',\r\n 'lastOpen',\r\n 'lastHigh',\r\n 'lastLow',\r\n 'lastClose',\r\n 'lastDate',\r\n 'lastVolume',\r\n 'lastTime',\r\n 'dataId',\r\n 'prevClose',\r\n 'COTs',\r\n 'chartEvents',\r\n 'afterClose',\r\n 'afterChange',\r\n 'afterTime',\r\n 'drawMinutesPerDay',\r\n 'marketStartMinutes',\r\n 'premarketLengthMinutes',\r\n 'aftermarketLengthMinutes',\r\n 'aftermarket',\r\n 'premarket',\r\n 'events',\r\n 'financialAttachments',\r\n 'financialAttachmentsData',\r\n 'hasPatterns',\r\n 'patterns',\r\n 'patternsMinRange',\r\n 'patternsMaxRange',\r\n 'relativeVolume',\r\n 'fetchedAt',\r\n 'fetchingPromise',\r\n 'isFetching',\r\n 'wasFetchAborted',\r\n 'chartUuid',\r\n 'numberOfRefreshChecks',\r\n 'maxBars',\r\n 'ideaID',\r\n 'is404',\r\n ...Quote.computableKeys\r\n )\r\n }\r\n\r\n static getFromCacheSync({\r\n ticker: tickerRaw,\r\n instrument,\r\n timeframe,\r\n options,\r\n chartUuid,\r\n }: Omit): Quote | null {\r\n const ticker = tickerRaw.replace('@', '')\r\n return (\r\n Quote.select(\r\n (q) =>\r\n doesQuoteAndFetchParamsMatch({ quote: q, ticker, instrument, timeframe }) &&\r\n isSameOrNoChartUuid({ quote: q, uuid: chartUuid }) &&\r\n isNotEmptyQuote(q) &&\r\n isCacheAllowed({ quote: q, options }) &&\r\n (q.instrument !== Instrument.Stock ||\r\n Number.isInteger(q.ideaID) ||\r\n doesQuoteAndOptionsMatch({ quote: q, options }))\r\n )[0] ?? null\r\n )\r\n }\r\n\r\n static async get({\r\n ticker: tickerRaw,\r\n instrument,\r\n timeframe,\r\n options,\r\n abortController,\r\n shouldUseCache = true,\r\n chartUuid,\r\n }: QuoteGetParams): Promise {\r\n const ticker = tickerRaw.replace('@', '')\r\n const quote = shouldUseCache\r\n ? this.getFromCacheSync({ ticker: tickerRaw, instrument, timeframe, options, chartUuid })\r\n : null\r\n\r\n if (quote) {\r\n if (quote.isFetching) {\r\n await quote.getResolvedFetchingPromise()\r\n } else if (options?.fetchNewDataOnCachedQuote) {\r\n await quote.fetchData({ fetchType: QuoteFetchType.NewerData, abortController })\r\n }\r\n return quote\r\n }\r\n\r\n const newQuote = Quote.create({\r\n ...getEmptyQuote(),\r\n ticker,\r\n timeframe,\r\n instrument,\r\n chartUuid,\r\n maxBars: options?.maxBars,\r\n premarket: !!options?.premarket,\r\n aftermarket: !!options?.aftermarket,\r\n hasPatterns: !!options?.patterns,\r\n events: !!options?.events,\r\n financialAttachments: options?.financialAttachments ?? [],\r\n })\r\n\r\n await newQuote.fetchData({ fetchType: QuoteFetchType.Refetch, abortController })\r\n\r\n return newQuote\r\n }\r\n\r\n static async getAll(\r\n tickersAndTimeframes: Array>\r\n ) {\r\n // TODO: fetch in 1 request\r\n if (tickersAndTimeframes.length === 0) {\r\n return {}\r\n }\r\n\r\n try {\r\n const quotes = await Promise.all(tickersAndTimeframes.map((props) => this.get(props)))\r\n const data = quotes.reduce(\r\n (accumulator, quote) => ({\r\n ...accumulator,\r\n [quote.ticker]: quote,\r\n }),\r\n {}\r\n )\r\n return data\r\n } catch (err) {\r\n // TODO: handle somehow\r\n }\r\n }\r\n\r\n declare ticker: string\r\n declare name: string\r\n declare instrument: Instrument\r\n declare interval: number\r\n declare timeframe: TIMEFRAME\r\n declare open: number[]\r\n declare high: number[]\r\n declare low: number[]\r\n declare close: number[]\r\n declare date: number[]\r\n declare volume: number[]\r\n declare lastOpen: number\r\n declare lastHigh: number\r\n declare lastLow: number\r\n declare lastClose: number\r\n declare lastDate: number\r\n declare lastVolume: number\r\n declare dataId: string\r\n declare prevClose: number\r\n declare COTs: COTData\r\n declare afterClose: number\r\n declare afterChange: number\r\n declare drawMinutesPerDay: number\r\n declare marketStartMinutes: number\r\n declare premarketLengthMinutes: number\r\n declare aftermarketLengthMinutes: number\r\n declare hasPatterns: boolean\r\n declare patterns: Array\r\n declare patternsMinRange: number\r\n declare patternsMaxRange: number\r\n declare relativeVolume: number\r\n declare isIntraday: boolean\r\n declare drawDays?: number\r\n declare barIndex: number[]\r\n /**\r\n * Array of length the same as number of bars\r\n *\r\n * If there's a gap and a bar index has no corresponding data index,\r\n * the last data index is used (or 0 if there's no last data index)\r\n *\r\n * @type {number[]}\r\n */\r\n declare barToDataIndex: number[]\r\n declare chartUuid?: string\r\n declare aftermarket: boolean\r\n declare premarket: boolean\r\n declare fetchedAt: number\r\n declare numberOfRefreshChecks: number\r\n declare isFetching: boolean\r\n declare fetchingPromise?: Promise\r\n declare wasFetchAborted: boolean\r\n declare maxBars?: number\r\n declare ideaID?: number\r\n declare is404?: boolean\r\n declare chartEvents: Array\r\n declare events?: boolean\r\n declare financialAttachments?: QuoteFinancialAttachment[]\r\n declare financialAttachmentsData?: FinancialAttachmentsData\r\n declare alignedFinancialAttachmentsData: {\r\n [QuoteFinancialAttachment.shortInterest]?: Array\r\n }\r\n\r\n declare timestampToFinancialsIndexesMap: {\r\n [QuoteFinancialAttachment.shortInterest]?: ObjectHash\r\n }\r\n\r\n async fetchRequest({\r\n abortController,\r\n options = { type: QuoteFetchTypeUrlOption.New },\r\n }: {\r\n abortController?: null | AbortController\r\n options?: QuoteUrlOptions\r\n }) {\r\n let data: DataResponse | null = null\r\n let is404 = false\r\n let wasFetchAborted = false\r\n\r\n const fetchingPromise = fetchApi({\r\n location: this.getUrl(options),\r\n throwOnStatusCodes: [404],\r\n abortController,\r\n })\r\n\r\n this.updateAttributes({\r\n isFetching: true,\r\n fetchingPromise,\r\n })\r\n\r\n try {\r\n data = await fetchingPromise\r\n } catch (err) {\r\n is404 = err instanceof NotFoundError\r\n if (getIsAbortError(err as Error)) {\r\n wasFetchAborted = true\r\n } else if (!is404 && process.env.IS_E2E_TESTING) {\r\n throw new Error('Quote fetch error', { cause: err })\r\n }\r\n // Ignore network/notfound errors\r\n }\r\n\r\n const shouldUseEmptyQuote = !data && !wasFetchAborted && options.type === QuoteFetchTypeUrlOption.New\r\n\r\n this.updateAttributes({\r\n ...(shouldUseEmptyQuote ? getEmptyQuote() : {}),\r\n is404,\r\n wasFetchAborted,\r\n isFetching: false,\r\n })\r\n\r\n return data\r\n }\r\n\r\n async isPossibleToFetchSequentialData({\r\n abortController,\r\n }: {\r\n abortController?: null | AbortController\r\n } = {}) {\r\n const data = await this.fetchRequest({ abortController })\r\n if (data && data.date.length > 0 && this.date.length > 0) {\r\n return this.date[this.date.length - 1] >= data.date[0]\r\n }\r\n return false\r\n }\r\n\r\n async fetchData({\r\n fetchType,\r\n abortController,\r\n }: {\r\n fetchType: QuoteFetchType\r\n abortController?: null | AbortController\r\n }) {\r\n let options: QuoteUrlOptions\r\n if (fetchType === QuoteFetchType.Refetch) {\r\n options = { type: QuoteFetchTypeUrlOption.New }\r\n } else if (fetchType === QuoteFetchType.NewerData) {\r\n options = { type: QuoteFetchTypeUrlOption.Newer }\r\n if ((this.numberOfRefreshChecks ?? 0) < quoteRefreshChecksBeforeFullRefresh) {\r\n options.dataId = this.dataId\r\n }\r\n } else {\r\n return\r\n }\r\n if (this.instrument === Instrument.Stock) {\r\n options.events = this.events == null ? true : this.events\r\n }\r\n\r\n const data = await this.fetchRequest({ abortController, options })\r\n\r\n if (!data || data.noNewData === true) {\r\n this.updateAttributes({\r\n numberOfRefreshChecks: (this.numberOfRefreshChecks ?? 0) + 1,\r\n })\r\n return\r\n }\r\n if (this.timeframe !== data.timeframe || this.ticker.toLowerCase() !== data.ticker?.toLowerCase()) {\r\n return\r\n }\r\n\r\n const newQuoteData = {\r\n COTs: data.COTs,\r\n name: data.name,\r\n open: data.open,\r\n high: data.high,\r\n low: data.low,\r\n close: data.close,\r\n volume: data.volume,\r\n date: data.date,\r\n drawMinutesPerDay: data.drawMinutesPerDay,\r\n marketStartMinutes: data.marketStartMinutes,\r\n premarketLengthMinutes: data.premarketLengthMinutes,\r\n aftermarketLengthMinutes: data.aftermarketLengthMinutes,\r\n patterns: data.patterns ?? [],\r\n patternsMinRange: data.patternsMinRange,\r\n patternsMaxRange: data.patternsMaxRange,\r\n relativeVolume: data.relativeVolume,\r\n lastOpen: data.lastOpen,\r\n lastHigh: data.lastHigh,\r\n lastLow: data.lastLow,\r\n lastClose: data.lastClose,\r\n lastVolume: data.lastVolume,\r\n dataId: data.dataId,\r\n lastDate: data.lastDate,\r\n lastTime: data.lastTime,\r\n prevClose: data.prevClose,\r\n afterClose: data.afterClose,\r\n afterChange: data.afterChange,\r\n afterTime: data.afterTime,\r\n numberOfRefreshChecks: 0,\r\n chartEvents: data.chartEvents ?? [],\r\n fetchedAt: Date.now(),\r\n financialAttachmentsData: data.financialAttachmentsData,\r\n }\r\n\r\n if (\r\n !(\r\n fetchType === QuoteFetchType.Refetch ||\r\n [Instrument.Futures, Instrument.Forex, Instrument.Crypto].includes(this.instrument)\r\n )\r\n ) {\r\n /*\r\n * Merges current and new data taking date as index\r\n */\r\n let AIndex = 0\r\n let BIndex = 0\r\n let mergeIndex = -1\r\n while (AIndex < this.date.length || BIndex < data.date.length) {\r\n const ADate = this.date[AIndex]\r\n const BDate = data.date[BIndex]\r\n if (BDate === undefined) {\r\n break\r\n } else if (ADate === BDate) {\r\n // Same date, update OHLCV\r\n this.open[AIndex] = data.open[BIndex]\r\n this.high[AIndex] = data.high[BIndex]\r\n this.low[AIndex] = data.low[BIndex]\r\n this.close[AIndex] = data.close[BIndex]\r\n this.volume[AIndex] = data.volume[BIndex]\r\n AIndex++\r\n BIndex++\r\n } else if (ADate > BDate || ADate === undefined) {\r\n // New bar for a date not yet in our dataset\r\n // If weekly or monthly timeframe & wasn't merged on AIndex\r\n if (mergeIndex === -1 && [TIMEFRAME.w, TIMEFRAME.m].includes(this.timeframe)) {\r\n const prevAIndex = AIndex - 1\r\n const prevDate = dateFromUnixTimestamp(this.date[prevAIndex])\r\n const newDate = dateFromUnixTimestamp(data.date[BIndex])\r\n // If merge bar for weekly is sameWeek or for monthly is sameMonth perform merge on AIndex\r\n if (\r\n (TIMEFRAME.w === this.timeframe && isSameWeek(prevDate, newDate, { weekStartsOn: 1 })) ||\r\n (TIMEFRAME.m === this.timeframe && isSameMonth(prevDate, newDate))\r\n ) {\r\n this.date[prevAIndex] = data.date[BIndex]\r\n this.open[prevAIndex] = data.open[BIndex]\r\n this.high[prevAIndex] = data.high[BIndex]\r\n this.low[prevAIndex] = data.low[BIndex]\r\n this.close[prevAIndex] = data.close[BIndex]\r\n this.volume[prevAIndex] = data.volume[BIndex]\r\n mergeIndex = prevAIndex\r\n // Incrementing BIndex only because we're mergin arrays on AIndex\r\n BIndex++\r\n continue\r\n }\r\n }\r\n this.date.splice(AIndex, 0, data.date[BIndex])\r\n this.open.splice(AIndex, 0, data.open[BIndex])\r\n this.high.splice(AIndex, 0, data.high[BIndex])\r\n this.low.splice(AIndex, 0, data.low[BIndex])\r\n this.close.splice(AIndex, 0, data.close[BIndex])\r\n this.volume.splice(AIndex, 0, data.volume[BIndex])\r\n // Incrementing AIndex because we're changing the array in-place\r\n AIndex++\r\n BIndex++\r\n } else if (ADate < BDate) {\r\n AIndex++\r\n } else {\r\n console.warn('fetchNewerData merge warning')\r\n window.Sentry?.captureMessage('quote.ts fetchNewerData merge warning', {\r\n extra: {\r\n thisDateLength: this.date.length,\r\n dataDateLength: data.date.length,\r\n AIndex,\r\n BIndex,\r\n ADate,\r\n BDate,\r\n },\r\n })\r\n }\r\n }\r\n\r\n newQuoteData.date = this.date\r\n newQuoteData.open = this.open\r\n newQuoteData.high = this.high\r\n newQuoteData.low = this.low\r\n newQuoteData.close = this.close\r\n newQuoteData.volume = this.volume\r\n }\r\n\r\n const hasUpdatedSuccessfully = this.updateAttributes(newQuoteData)\r\n // https://github.com/finvizhq/charts/issues/510\r\n if (!hasUpdatedSuccessfully) {\r\n // attempt to find if this.model.quote() => null is comming from this.save() validation fail\r\n window.Sentry?.captureMessage('quote.ts fetchNewerData save() validation failed', { extra: this })\r\n }\r\n if (!this) {\r\n // or this somehow became null / falsy\r\n window.Sentry?.captureMessage('quote.ts fetchNewerData this is falsy', { extra: this })\r\n }\r\n this.trigger(fetchType, this, fetchType)\r\n }\r\n\r\n async getResolvedFetchingPromise() {\r\n try {\r\n return await this.fetchingPromise\r\n } catch {\r\n // do nothing\r\n }\r\n }\r\n\r\n fetchOlderData() {\r\n return // not yet implemented\r\n // TODO cancel previous request\r\n }\r\n\r\n load(atts: ObjectHash) {\r\n super.load(atts)\r\n // This has to be here to prevent recalculations if atts.fetchedAt is not provided\r\n const fetchedAt = atts.fetchedAt ?? this.fetchedAt ?? 0\r\n const { cachedAt } = (getCachedQuote({ cid: this.cid }) as { cachedAt: number } | null) || {}\r\n if (this.timeframe && cachedAt !== fetchedAt) {\r\n setCachedQuote({ cid: this.cid, key: 'cachedAt', value: fetchedAt, fetchedAt })\r\n this.isIntraday = [\r\n TIMEFRAME.i1,\r\n TIMEFRAME.i2,\r\n TIMEFRAME.i3,\r\n TIMEFRAME.i5,\r\n TIMEFRAME.i10,\r\n TIMEFRAME.i15,\r\n TIMEFRAME.i30,\r\n TIMEFRAME.h,\r\n TIMEFRAME.h2,\r\n TIMEFRAME.h4,\r\n ].includes(this.timeframe)\r\n this.interval = this.isIntraday\r\n ? IntradayTimeframeInterval[this.timeframe as keyof typeof IntradayTimeframeInterval]\r\n : 0\r\n this.drawDays = this.getDrawDays()\r\n this.barIndex = this.getBarIndexes()\r\n this.patterns = this.patterns ?? []\r\n this.barToDataIndex = this.barIndex.flatMap((barIndex, index) => {\r\n const lastIndex = this.barIndex[index - 1] ?? -1\r\n return [...Array.from({ length: barIndex - lastIndex - 1 }).fill(Math.max(0, index - 1)), index] as number[]\r\n })\r\n this.alignAllFinancialAttachmentsDataWithQuoteDates()\r\n }\r\n if (this.timeframe && this.ticker) {\r\n this.chartEvents = getChartEventsWithId({\r\n ticker: this.ticker,\r\n chartEvents: this.chartEvents as unknown as ChartEventDataRaw[],\r\n })\r\n }\r\n return this\r\n }\r\n\r\n alignAllFinancialAttachmentsDataWithQuoteDates() {\r\n this.alignedFinancialAttachmentsData = {}\r\n this.timestampToFinancialsIndexesMap = {}\r\n this.financialAttachments?.forEach((quoteFinancialAttachment) => {\r\n this.alignFinancialAttachmentsDataWithQuoteDates(quoteFinancialAttachment)\r\n })\r\n }\r\n\r\n alignFinancialAttachmentsDataWithQuoteDates(quoteFinancialAttachment: QuoteFinancialAttachment) {\r\n const timestampToFinancialsIndexesMap: ObjectHash = {}\r\n const financialAttachmentsData = this.financialAttachmentsData?.[quoteFinancialAttachment]\r\n\r\n if (financialAttachmentsData) {\r\n let lastDateIndex = 0\r\n const firstDate = this.date[0]\r\n this.alignedFinancialAttachmentsData[quoteFinancialAttachment] = financialAttachmentsData.map((data, index) => {\r\n let matchingQuoteTimestamp: number | null = null\r\n\r\n const parsedDate = dateFromUnixTimestamp(data.timestamp)\r\n const convertedDateToNyTimestamp = convertLocalToNyTime(parsedDate, false).getTime() / 1000\r\n\r\n if (firstDate < convertedDateToNyTimestamp) {\r\n for (let dateIndex = lastDateIndex; dateIndex < this.date.length; dateIndex += 1) {\r\n const timestamp = this.date[dateIndex]\r\n const dateDate = dateFromUnixTimestamp(timestamp)\r\n if (this.isIntraday || this.timeframe === TIMEFRAME.d) {\r\n if (isSameDay(parsedDate, dateDate)) {\r\n lastDateIndex = dateIndex\r\n matchingQuoteTimestamp = timestamp\r\n break\r\n }\r\n } else if (this.timeframe === TIMEFRAME.w) {\r\n if (isSameWeek(parsedDate, dateDate, { weekStartsOn: 1 })) {\r\n lastDateIndex = dateIndex\r\n matchingQuoteTimestamp = timestamp\r\n break\r\n }\r\n } else if (this.timeframe === TIMEFRAME.m) {\r\n if (isSameMonth(parsedDate, dateDate)) {\r\n lastDateIndex = dateIndex\r\n matchingQuoteTimestamp = timestamp\r\n break\r\n }\r\n }\r\n }\r\n }\r\n\r\n if (matchingQuoteTimestamp !== null) {\r\n const key = matchingQuoteTimestamp.toString()\r\n timestampToFinancialsIndexesMap[key] ??= []\r\n timestampToFinancialsIndexesMap[key].push(index)\r\n }\r\n\r\n return { ...data, matchingQuoteTimestamp }\r\n })\r\n\r\n this.timestampToFinancialsIndexesMap = {\r\n [quoteFinancialAttachment]: timestampToFinancialsIndexesMap,\r\n }\r\n }\r\n }\r\n\r\n clearCachedData() {\r\n deleteCachedQuote({ cid: this.cid })\r\n }\r\n\r\n destroy(options?: ObjectHash) {\r\n super.destroy(options)\r\n this.clearCachedData()\r\n return this\r\n }\r\n\r\n getDrawDays() {\r\n if (this.instrument !== Instrument.Stock) {\r\n return Infinity\r\n }\r\n switch (this.timeframe) {\r\n case TIMEFRAME.i1:\r\n case TIMEFRAME.i2:\r\n case TIMEFRAME.i3:\r\n case TIMEFRAME.i5:\r\n case TIMEFRAME.i10:\r\n return 10\r\n case TIMEFRAME.i15:\r\n case TIMEFRAME.i30:\r\n case TIMEFRAME.h:\r\n case TIMEFRAME.h2:\r\n case TIMEFRAME.h4:\r\n return 15\r\n default:\r\n break\r\n }\r\n }\r\n\r\n getHeikinAshiData() {\r\n const cachedHeikinAshiData = getCachedQuote({ cid: this.cid, key: 'heikinAshiData', fetchedAt: this.fetchedAt })\r\n if (cachedHeikinAshiData) {\r\n return cachedHeikinAshiData as unknown as { open: number[]; close: number[] }\r\n }\r\n\r\n const HAClose = this.open.map((_, i) => (this.open[i] + this.high[i] + this.close[i] + this.low[i]) / 4)\r\n const HAOpen = this.open.reduce(\r\n (acc, open, i) => [...acc, (i === 0 ? open + HAClose[0] : acc[i - 1] + HAClose[i - 1]) / 2],\r\n [] as number[]\r\n )\r\n\r\n const heikAshiData = { open: HAOpen, close: HAClose }\r\n\r\n setCachedQuote({ cid: this.cid, key: 'heikinAshiData', value: heikAshiData, fetchedAt: this.fetchedAt })\r\n\r\n return heikAshiData\r\n }\r\n\r\n getDayToOffset(): ObjectHash {\r\n const cachedDayToOffset = getCachedQuote({ cid: this.cid, key: 'dayToOffset', fetchedAt: this.fetchedAt })\r\n if (cachedDayToOffset) {\r\n return cachedDayToOffset as unknown as ObjectHash\r\n }\r\n const dayToOffset: ObjectHash = {}\r\n let day = 0\r\n let lastDay\r\n for (let i = 0, end = this.date.length, asc = end >= 0; asc ? i < end : i > end; asc ? i++ : i--) {\r\n const date = dateFromUnixTimestamp(this.date[i])\r\n const dateString = dateStringFromDate(date)\r\n if (dateString !== lastDay) {\r\n dayToOffset[dateString] = day\r\n day++\r\n lastDay = dateString\r\n }\r\n }\r\n // for ofscreen renderer we need to add lastDate to have correct dayToOffset because if\r\n // premarket=false in fetch query there isn't other way to distinguish that\r\n if (getIsSSr() && this.lastDate) {\r\n // YYYYMMDD / 20211118 => YYYY-MM-DD\r\n const [yyyy, mm, dd] = [~~(this.lastDate / 10000), ~~(this.lastDate / 100) % 100, this.lastDate % 100]\r\n const lastDate = `${yyyy}-${String(mm).padStart(2, '0')}-${String(dd).padStart(2, '0')}`\r\n\r\n if (lastDay !== lastDate) {\r\n dayToOffset[lastDate] = day\r\n }\r\n }\r\n\r\n setCachedQuote({ cid: this.cid, key: 'dayToOffset', value: dayToOffset, fetchedAt: this.fetchedAt })\r\n return dayToOffset\r\n }\r\n\r\n getDaysInQuote() {\r\n const cachedDayToOffset = getCachedQuote({ cid: this.cid, key: 'daysInQuote', fetchedAt: this.fetchedAt })\r\n if (cachedDayToOffset) {\r\n return cachedDayToOffset as unknown as Date[]\r\n }\r\n const dayToOffset = this.getDayToOffset()\r\n const daysInQuote = Object.keys(dayToOffset)\r\n .map((dateString) => {\r\n const [year, month, day] = dateString.split('-')\r\n return new Date(Number.parseInt(year), Number.parseInt(month) - 1, Number.parseInt(day))\r\n })\r\n .sort((a, b) => a.getTime() - b.getTime())\r\n\r\n setCachedQuote({ cid: this.cid, key: 'daysInQuote', value: daysInQuote, fetchedAt: this.fetchedAt })\r\n return daysInQuote\r\n }\r\n\r\n getBarIndexes() {\r\n if (!this.isIntraday || this.instrument !== Instrument.Stock) {\r\n return Array.from({ length: this.date.length }).map((_, index) => index)\r\n }\r\n\r\n const barIndex = []\r\n const dayToOffset = this.getDayToOffset()\r\n\r\n for (let i = 0; i < this.date.length; i += 1) {\r\n const date = dateFromUnixTimestamp(this.date[i])\r\n let x = Math.ceil((date.getHours() * 60 + date.getMinutes() - this.marketStartMinutes) / this.interval)\r\n x += dayToOffset[dateStringFromDate(date)] * this.getBarsInDay()! // add days\r\n barIndex[i] = x\r\n }\r\n\r\n return barIndex\r\n }\r\n\r\n getBarIndex(i: number) {\r\n if (!this.isIntraday || this.instrument !== Instrument.Stock) {\r\n return i\r\n }\r\n return this.barIndex[i]\r\n }\r\n\r\n getBarsInDay() {\r\n if (!this.isIntraday || this.instrument !== Instrument.Stock) {\r\n return\r\n }\r\n return Math.ceil(this.drawMinutesPerDay / this.interval)\r\n }\r\n\r\n getDataIndexByBarIndex(index: number) {\r\n if (this.barIndex) {\r\n for (let i = 0; i < this.barIndex.length; i++) {\r\n if (this.barIndex[i] === index) {\r\n return i\r\n }\r\n }\r\n }\r\n return -1\r\n }\r\n\r\n getDataByBarIndex(key: keyof Quote, index: number) {\r\n const dataIndex = this.getDataIndexByBarIndex(index)\r\n if (dataIndex > -1) {\r\n const quoteData = this[key as keyof Quote]! as number[]\r\n return quoteData[dataIndex] ?? null\r\n }\r\n return null\r\n }\r\n\r\n getDateToIndex() {\r\n const cachedDateToIndex = getCachedQuote({ cid: this.cid, key: 'dateToIndex', fetchedAt: this.fetchedAt })\r\n if (cachedDateToIndex) {\r\n return cachedDateToIndex as unknown as ObjectHash\r\n }\r\n const dateToIndex: ObjectHash = {}\r\n for (let i = 0; i < this.date.length; i++) {\r\n dateToIndex[this.date[i]] = i\r\n }\r\n setCachedQuote({ cid: this.cid, key: 'dateToIndex', value: dateToIndex, fetchedAt: this.fetchedAt })\r\n return dateToIndex\r\n }\r\n\r\n getTimestampFomPositionX(positionX: number) {\r\n if (this.date.length === 0) {\r\n return 0\r\n }\r\n return getTimestampFromPositionX({\r\n positionX,\r\n quote: this,\r\n })\r\n }\r\n\r\n getPositionXFromTimestamp(timestamp: number) {\r\n if (this.date.length === 0) {\r\n return 0\r\n }\r\n return getPositionXFromTimestamp({\r\n timestamp,\r\n quote: this,\r\n })\r\n }\r\n\r\n getUrl(options: QuoteUrlOptions) {\r\n const config: UrlOptions = {\r\n ticker: this.ticker,\r\n instrument: this.instrument,\r\n timeframe: this.timeframe || 'd1',\r\n aftermarket: this.aftermarket,\r\n premarket: this.premarket,\r\n patterns: this.hasPatterns,\r\n maxBars: this.maxBars,\r\n ...options,\r\n financialAttachments: this.financialAttachments?.join(','),\r\n }\r\n\r\n const isStock = config.instrument === Instrument.Stock\r\n const isBrowserElite = !getIsSSr() && document.location.host === 'elite.finviz.com'\r\n let domain = isBrowserElite && isStock ? 'https://api.finviz.com' : ''\r\n\r\n if (getIsSSr()) {\r\n domain = process.env.BE_API_URL!\r\n }\r\n\r\n return `${domain}/api/quote.ashx?${queryString.stringify({ rev: Date.now(), ...config })}`\r\n }\r\n\r\n getRawTicker() {\r\n return getRawTickerForInstrument(this.instrument, this.ticker)\r\n }\r\n\r\n clearData() {\r\n this.updateAttributes(getEmptyQuote())\r\n }\r\n\r\n toConfig = RootChartConfigObject>(omitKeys = [] as string[]): T {\r\n return JSON.parse(JSON.stringify(omit(this.toJSON(), [...Quote.computableKeys, ...omitKeys])))\r\n }\r\n}\r\n\r\nQuote.initClass()\r\n\r\nexport default Quote\r\n","import { QuoteFinancialAttachment } from '../../constants/common'\r\n\r\nexport enum QuoteFetchType {\r\n Refetch = 'refetch',\r\n NewerData = 'newerData',\r\n}\r\n\r\nexport enum QuoteFetchTypeUrlOption {\r\n New = 'new',\r\n Newer = 'newer',\r\n}\r\n\r\nexport interface QuoteUrlOptions {\r\n type: QuoteFetchTypeUrlOption\r\n dataId?: string\r\n events?: boolean\r\n financialAttachments?: QuoteFinancialAttachment[]\r\n}\r\n","export const largeChartFontSize = {\r\n S: 8,\r\n M: 10,\r\n XXL: 16,\r\n XXXL: 24,\r\n}\r\n","import { Theme } from '../../../types/shared'\r\nimport {\r\n CHART_MARGIN,\r\n FONT_SIZE,\r\n LINE_HEIGHT,\r\n OFFSET,\r\n PADDING,\r\n SETTINGS_HEIGHT,\r\n TICKER_TIMEFRAME_CHANGE_HEIGHT,\r\n TextBaseline,\r\n} from '../../constants/common'\r\nimport {\r\n chartDarkTheme,\r\n chartLightTheme,\r\n elementDarkTheme,\r\n elementLightTheme,\r\n generalColors,\r\n indicatorDarkTheme,\r\n indicatorLightTheme,\r\n} from '../constants'\r\nimport { ISettings } from './interfaces'\r\n\r\nexport const INTERACTIVE_CHART_SETTINGS = (theme: Theme): ISettings => ({\r\n ChartSettings: {\r\n general: {\r\n Colors: {\r\n ...(theme === Theme.light ? chartLightTheme : chartDarkTheme),\r\n [Theme.light]: chartLightTheme,\r\n [Theme.dark]: chartDarkTheme,\r\n },\r\n settingsHeight: SETTINGS_HEIGHT,\r\n tickerTimeframeChangeHeight: TICKER_TIMEFRAME_CHANGE_HEIGHT,\r\n },\r\n center: {\r\n barWidth: 3,\r\n barMargin: 1,\r\n border: 1,\r\n },\r\n top: {\r\n height: CHART_MARGIN.XL,\r\n baseline: TextBaseline.alphabetic,\r\n ticker: {\r\n margin: {\r\n top: 30,\r\n left: 0,\r\n },\r\n font: {\r\n size: FONT_SIZE.XXXL,\r\n style: 'bold',\r\n },\r\n },\r\n ohlc: {\r\n margin: {\r\n top: 30,\r\n left: 30,\r\n right: 30,\r\n },\r\n font: {\r\n size: FONT_SIZE.S,\r\n },\r\n },\r\n change: {\r\n margin: {\r\n top: 30,\r\n right: 0,\r\n },\r\n font: {\r\n size: FONT_SIZE.M,\r\n style: 'bold',\r\n },\r\n },\r\n },\r\n right: {\r\n width: CHART_MARGIN.XXL,\r\n axis: {\r\n margin: {\r\n left: 0,\r\n },\r\n font: {\r\n size: FONT_SIZE.S,\r\n lineHeight: LINE_HEIGHT.S,\r\n padding: {\r\n top: PADDING.XXS,\r\n bottom: PADDING.XXS,\r\n left: PADDING.XXS,\r\n right: PADDING.XXS,\r\n },\r\n },\r\n },\r\n },\r\n bottom: {\r\n height: CHART_MARGIN.M,\r\n baseline: TextBaseline.top,\r\n axis: {\r\n margin: {\r\n top: 8,\r\n },\r\n font: {\r\n size: FONT_SIZE.S,\r\n },\r\n },\r\n },\r\n left: {\r\n width: CHART_MARGIN.L,\r\n overlayLabel: {\r\n labelSpacing: 12,\r\n margin: {\r\n top: -8,\r\n left: 6,\r\n },\r\n font: {\r\n size: FONT_SIZE.S,\r\n weight: 'bold',\r\n },\r\n },\r\n timeframe: {\r\n margin: {\r\n top: 0,\r\n left: 28,\r\n },\r\n font: {\r\n size: FONT_SIZE.M,\r\n weight: '900',\r\n family: 'Lato, sans-serif',\r\n },\r\n },\r\n volumeAxis: {\r\n margin: {\r\n left: 33,\r\n },\r\n font: {\r\n size: FONT_SIZE.S,\r\n },\r\n },\r\n },\r\n },\r\n IndicatorSettings: {\r\n general: {\r\n height: 140,\r\n Colors: theme === Theme.light ? indicatorLightTheme : indicatorDarkTheme,\r\n },\r\n center: {\r\n barWidth: 3,\r\n barMargin: 2,\r\n border: 1,\r\n },\r\n top: {\r\n height: CHART_MARGIN.S,\r\n },\r\n right: {\r\n width: CHART_MARGIN.XXL,\r\n axis: {\r\n margin: {\r\n left: 0,\r\n },\r\n font: {\r\n size: FONT_SIZE.S,\r\n lineHeight: LINE_HEIGHT.S,\r\n padding: {\r\n top: PADDING.XXS,\r\n bottom: PADDING.XXS,\r\n left: PADDING.XXS,\r\n right: PADDING.XXS,\r\n },\r\n },\r\n },\r\n },\r\n bottom: {\r\n height: CHART_MARGIN.S,\r\n },\r\n left: {\r\n width: CHART_MARGIN.L,\r\n indicatorLabel: {\r\n labelSpacing: 4,\r\n margin: {\r\n top: OFFSET.S,\r\n left: OFFSET.M,\r\n },\r\n font: {\r\n size: FONT_SIZE.M,\r\n style: 'bold',\r\n lineHeight: LINE_HEIGHT.M,\r\n },\r\n },\r\n },\r\n },\r\n MarketSentimentSettings: {\r\n general: {\r\n Colors: theme === Theme.light ? chartLightTheme : chartDarkTheme,\r\n },\r\n center: {\r\n barWidth: 3,\r\n barMargin: 1,\r\n border: 1,\r\n },\r\n top: {\r\n height: 0,\r\n },\r\n bottom: {\r\n height: 12,\r\n },\r\n left: {\r\n width: 0,\r\n },\r\n right: {\r\n width: 30,\r\n },\r\n },\r\n ColorsSettings: generalColors,\r\n ThumbSettings: {\r\n size: 8,\r\n touchSize: 16,\r\n color: '#ddd',\r\n borderWidth: 1,\r\n borderColor: '#999',\r\n },\r\n ElementSettings: {\r\n Colors: theme === Theme.light ? elementLightTheme : elementDarkTheme,\r\n defaultFill: '#1e6dc066',\r\n defaultTransparentFill: '#1e6dc000',\r\n },\r\n})\r\n","import merge from 'lodash.merge'\r\n\r\nimport { ChartConfigChart } from '../../server/chartConfig'\r\nimport { Instrument, ObjectHash, Theme } from '../../types/shared'\r\nimport { SpecificChartFunctionality } from '../constants/common'\r\nimport Utils, { isRedesignedPage } from '../utils'\r\nimport LayoutModel from './chart_layout'\r\nimport { getColorOverwrites } from './chart_settings'\r\nimport { largeChartFontSize } from './chart_settings/constants'\r\nimport { INTERACTIVE_CHART_SETTINGS } from './chart_settings/interactive_chart_settings'\r\nimport { ISettings } from './chart_settings/interfaces'\r\nimport {\r\n IChartThemeColors,\r\n chartDarkTheme,\r\n chartLightTheme,\r\n elementDarkTheme,\r\n elementLightTheme,\r\n indicatorDarkTheme,\r\n indicatorLightTheme,\r\n} from './constants'\r\n\r\ninterface Config {\r\n theme: Theme\r\n barMargin?: number\r\n barWidth?: number\r\n border?: number\r\n charts?: ChartConfigChart[]\r\n colorsOverride?: Array\r\n volumeHeight?: number\r\n colors?: ObjectHash, Theme>\r\n specificChartFunctionality?: SpecificChartFunctionality\r\n isOurSiteRequest?: boolean\r\n}\r\n\r\nexport function getSettings(config: Config, chartSettings?: ISettings): ISettings {\r\n const settings = merge({}, chartSettings ?? INTERACTIVE_CHART_SETTINGS(config.theme))\r\n\r\n if (config.barWidth != null) {\r\n settings.ChartSettings.center.barWidth = config.barWidth\r\n settings.IndicatorSettings.center.barWidth = config.barWidth\r\n }\r\n if (config.barMargin != null) {\r\n settings.ChartSettings.center.barMargin = config.barMargin\r\n settings.IndicatorSettings.center.barMargin = config.barMargin\r\n }\r\n if (config.border != null) {\r\n settings.ChartSettings.center.border = config.border\r\n settings.IndicatorSettings.center.border = config.border\r\n }\r\n if (config.colorsOverride) {\r\n settings.ColorsSettings = config.colorsOverride\r\n }\r\n if (config.volumeHeight) {\r\n settings.ChartSettings.center.volumeHeight = config.volumeHeight\r\n }\r\n if (config.colors) {\r\n const settingColors = settings.ChartSettings.general.Colors\r\n settings.ChartSettings.general.Colors = {\r\n ...settingColors,\r\n [Theme.light]: {\r\n ...settingColors[Theme.light],\r\n ...getColorOverwrites({ theme: Theme.light, colors: config.colors }),\r\n },\r\n [Theme.dark]: {\r\n ...settingColors[Theme.dark],\r\n ...getColorOverwrites({ theme: Theme.dark, colors: config.colors }),\r\n },\r\n }\r\n }\r\n if (config.specificChartFunctionality === SpecificChartFunctionality.chartPage && Utils.isMobile()) {\r\n settings.ChartSettings.left.width = 0\r\n settings.ChartSettings.top.ticker.margin.left = settings.ChartSettings.left.overlayLabel.margin.left\r\n settings.IndicatorSettings.left.width = 0\r\n }\r\n if (SpecificChartFunctionality.chartPage === config.specificChartFunctionality || isRedesignedPage(config)) {\r\n settings.ChartSettings.top.height = 10\r\n }\r\n\r\n if (config.specificChartFunctionality === SpecificChartFunctionality.offScreen) {\r\n const isGroupInstrument = config.charts?.some(({ instrument }) => instrument === Instrument.Group)\r\n if (isGroupInstrument) {\r\n settings.ChartSettings.top.ohlc.margin.top = 4\r\n settings.ChartSettings.top.ticker.margin.top = 0\r\n settings.ChartSettings.top.ticker.font = {\r\n size: largeChartFontSize.XXL,\r\n style: 'bold',\r\n }\r\n settings.ChartSettings.left.timeframe.margin.top = 12\r\n settings.ChartSettings.left.timeframe.font = {\r\n size: largeChartFontSize.S,\r\n style: 'bold',\r\n }\r\n }\r\n }\r\n\r\n if (config.isOurSiteRequest !== undefined) {\r\n settings.isOurSiteRequest = config.isOurSiteRequest\r\n }\r\n\r\n return settings\r\n}\r\n\r\nexport function updateSettings(chart_layout: LayoutModel, theme: string): ISettings {\r\n const settings = merge({}, chart_layout.settings)\r\n const isLight = theme === Theme.light\r\n settings.MarketSentimentSettings.general.Colors = isLight ? { ...chartLightTheme } : { ...chartDarkTheme }\r\n settings.IndicatorSettings.general.Colors = isLight ? { ...indicatorLightTheme } : { ...indicatorDarkTheme }\r\n settings.ElementSettings.Colors = isLight ? { ...elementLightTheme } : { ...elementDarkTheme }\r\n\r\n return settings\r\n}\r\n\r\nexport function getChartLayoutSettings(chart_layout: LayoutModel): ISettings {\r\n const settings = chart_layout.settings\r\n\r\n return {\r\n ...settings,\r\n ChartSettings: {\r\n ...settings.ChartSettings,\r\n general: {\r\n ...settings.ChartSettings.general,\r\n Colors: {\r\n ...settings.ChartSettings.general.Colors,\r\n ...settings.ChartSettings.general.Colors[chart_layout.theme],\r\n },\r\n },\r\n },\r\n }\r\n}\r\n","import { Instrument } from '../../types/shared'\r\nimport ChartLayoutModel from './chart_layout'\r\nimport Element from './element'\r\n\r\nexport const handleRemoveIndicatorPane = ({\r\n paneIndex,\r\n chartLayoutModel,\r\n}: {\r\n paneIndex: number\r\n chartLayoutModel: ChartLayoutModel\r\n}) => {\r\n const charts = chartLayoutModel.getAllCharts()\r\n charts.forEach((chart) => chart.getAllPanes()[paneIndex].destroyCascade())\r\n}\r\n\r\nexport function getNormalizedZIndex({ index, isBelowZero }: { index: number; isBelowZero: boolean }) {\r\n return (index + 1) * (isBelowZero ? -1 : 1)\r\n}\r\n\r\nexport function rebuildElementZIndexes({\r\n elementsArray,\r\n isBelowZero,\r\n}: {\r\n elementsArray: Element[]\r\n isBelowZero: boolean\r\n}) {\r\n const elements = isBelowZero ? [...elementsArray].reverse() : elementsArray\r\n elements.forEach((element, index) => {\r\n const newZIndex = getNormalizedZIndex({ index, isBelowZero })\r\n if (newZIndex !== element.zIndex) {\r\n element.updateAttributes({ zIndex: newZIndex })\r\n }\r\n })\r\n}\r\n\r\nexport function changeElementZIndexes({\r\n elementsArray,\r\n addElement,\r\n oldZIndex,\r\n newZIndex,\r\n isBelowZero = false,\r\n}: {\r\n elementsArray: Element[]\r\n addElement: Element | undefined\r\n oldZIndex: number\r\n newZIndex: number\r\n isBelowZero?: boolean\r\n}) {\r\n const array = isBelowZero ? [...elementsArray].reverse() : elementsArray\r\n const elements =\r\n elementsArray.length === 0 && addElement\r\n ? [...array, addElement]\r\n : array\r\n .filter((_, index) => getNormalizedZIndex({ index, isBelowZero }) !== oldZIndex)\r\n .flatMap((el, index) =>\r\n getNormalizedZIndex({ index, isBelowZero }) === newZIndex && addElement ? [addElement, el] : el\r\n )\r\n\r\n // If there are only 2 drawings and we move a drawing from index 1 to index 2 to have to push it to the array because it's the last element and it didn't get into the array in the flatMap above\r\n if (elements.length < Math.abs(newZIndex) && addElement) {\r\n elements.push(addElement)\r\n }\r\n\r\n rebuildElementZIndexes({ elementsArray: isBelowZero ? [...elements].reverse() : elements, isBelowZero })\r\n}\r\n\r\nexport function getRawTickerForInstrument(instrument: Instrument, ticker: string) {\r\n return `${\r\n [Instrument.Crypto, Instrument.Forex, Instrument.Futures].includes(instrument) && !ticker.includes('@') ? '@' : ''\r\n }${ticker}`\r\n}\r\n","import { OverlayType } from '../../constants/common'\r\nimport BaseConfig from './overlayBaseConfig'\r\n\r\nexport type Options = {\r\n period: number\r\n}\r\n\r\nexport interface Attrs extends Options {\r\n color: string\r\n}\r\n\r\nexport class EMAConfig extends BaseConfig {\r\n static type = OverlayType.Ema\r\n static abbreviation = 'ema'\r\n static label = 'Exponential Moving Average'\r\n static shortLabel = 'EMA'\r\n static optionsOrder = ['period'] as const\r\n static optionsLabels = { period: 'Period' }\r\n static inputsOrder = ['period', 'color'] as Array\r\n static inputsLabels = { period: 'Period', color: 'Color' }\r\n static calculatedValuesOrder = ['ema'] as const\r\n static calculatedValuesLabels = { ema: 'EMA' }\r\n static defaultCalculatedValueOption = this.calculatedValuesOrder[0]\r\n}\r\n","import { ObjectHash } from '../../../types/shared'\r\nimport ElementBaseConfig from '../../canvas/ElementBaseConfig'\r\nimport { OverlayType } from '../../constants/common'\r\n\r\nexport default class OverlayBaseConfig extends ElementBaseConfig {\r\n static type = OverlayType.Overlay\r\n static abbreviation = 'ovl'\r\n static label = 'Overlay'\r\n static shortLabel = 'Overlay'\r\n static optionsOrder = [] as readonly string[]\r\n static optionsLabels = {}\r\n static inputsOrder = [] as readonly string[]\r\n static inputsLabels = {}\r\n static calculatedValuesOrder = [] as readonly string[]\r\n static calculatedValuesLabels = {}\r\n static defaultCalculatedValueOption = undefined as undefined | string\r\n\r\n get defaultCalculatedValueOption() {\r\n return (this.constructor as typeof OverlayBaseConfig).defaultCalculatedValueOption\r\n }\r\n\r\n static getShortLabelWithAttrs(attrs: ObjectHash) {\r\n return `${this.shortLabel} ${this.optionsOrder.map((item) => attrs[item]).join(',')}`\r\n }\r\n\r\n get getShortLabelWithAttrs() {\r\n return (this.constructor as typeof OverlayBaseConfig).getShortLabelWithAttrs\r\n }\r\n\r\n static getDefaultCalculatedValues() {\r\n return this.calculatedValuesOrder.reduce((prev, curr) => ({ ...prev, [curr]: [] }), {})\r\n }\r\n\r\n get getDefaultCalculatedValues() {\r\n return (this.constructor as typeof OverlayBaseConfig).getDefaultCalculatedValues\r\n }\r\n}\r\n","import { OverlayType } from '../../constants/common'\r\nimport BaseConfig from './overlayBaseConfig'\r\n\r\nexport type Options = {\r\n period: number\r\n deviations: number\r\n}\r\n\r\nexport interface Attrs extends Options {\r\n topColor?: string\r\n bottomColor?: string\r\n}\r\n\r\nexport class BBConfig extends BaseConfig {\r\n static type = OverlayType.Bb\r\n static abbreviation = 'bb'\r\n static label = 'Bollinger Bands'\r\n static shortLabel = 'BB'\r\n static optionsOrder = ['period', 'deviations'] as const\r\n static optionsLabels = { period: 'Period', deviations: 'Deviations' }\r\n static inputsOrder = ['period', 'deviations', 'topColor', 'bottomColor'] as Array\r\n static inputsLabels = {\r\n period: 'Period',\r\n deviations: 'Deviations',\r\n topColor: 'Top Color',\r\n bottomColor: 'Bottom Color',\r\n }\r\n\r\n static calculatedValuesOrder = ['upperBand', 'sma', 'lowerBand'] as const\r\n static calculatedValuesLabels = {\r\n sma: 'SMA',\r\n upperBand: 'Upper Band',\r\n lowerBand: 'Lower Band',\r\n }\r\n\r\n static defaultCalculatedValueOption = this.calculatedValuesOrder[1]\r\n}\r\n","import { BBConfig, Options } from '../overlays/configs/bb'\r\nimport { MainCalculation, OnValueCalculated } from './main'\r\n\r\ntype DefaultCalculatedValuesType = {\r\n sma: number[]\r\n upperBand: number[]\r\n lowerBand: number[]\r\n}\r\n\r\nexport class BbCalculation extends MainCalculation {\r\n static config = BBConfig\r\n\r\n calculate(onValueCalculated?: OnValueCalculated) {\r\n const { period, deviations } = this.options\r\n const { close } = this.quote\r\n this._calculatedValues = this.getDefaultCalculatedValues()\r\n\r\n let sum = 0\r\n const stdDev = []\r\n\r\n for (let i = 0; i < period; i++) {\r\n sum += close[i]\r\n }\r\n for (let i = period; i < close.length; i++) {\r\n sum = sum - close[i - period] + close[i]\r\n this.calculatedValues.sma[i] = sum / period\r\n\r\n let stdDevSum = 0\r\n for (let j = i - period + 1; j <= i; j++) {\r\n stdDevSum += Math.pow(close[j] - this.calculatedValues.sma[i], 2)\r\n }\r\n stdDev[i] = Math.sqrt(stdDevSum / period)\r\n\r\n this.calculatedValues.upperBand[i] = this.calculatedValues.sma[i] + stdDev[i] * deviations\r\n this.calculatedValues.lowerBand[i] = this.calculatedValues.sma[i] - stdDev[i] * deviations\r\n\r\n if (onValueCalculated?.(this.calculatedValues, i) === false) {\r\n break\r\n }\r\n }\r\n }\r\n}\r\n","import {\r\n ChartConfigChartPaneElement,\r\n IModalConfig,\r\n IModalConfigInput,\r\n ObjectHash,\r\n RequireByKey,\r\n} from '../../types/shared'\r\nimport Element from '../canvas/element'\r\nimport BaseChart from '../charts/base_chart'\r\nimport { OverlayType } from '../constants/common'\r\nimport Quote from '../models/quote'\r\nimport { convertColorToHEX, getRGBAValueFromValidColorString } from '../utils/colors'\r\nimport { getParsedIntegersFromPeriodString, isInRange, isPositiveInteger } from '../utils/helpers'\r\nimport OverlayConfig from './configs/overlayBaseConfig'\r\n\r\nexport interface IOverlayIsValid {\r\n getIsValid(key: string): boolean | void\r\n}\r\n\r\nconst DEFAULT_LABEL_COLOR = '#0587cd'\r\n\r\nclass Overlay extends Element implements IOverlayIsValid {\r\n static config = OverlayConfig\r\n\r\n static getNumOfBarsBuffer({ period }: RequireByKey) {\r\n const [periodInt] = getParsedIntegersFromPeriodString(period)\r\n return periodInt\r\n }\r\n\r\n declare data: Quote\r\n declare chart: BaseChart\r\n\r\n get type() {\r\n return (this.constructor as typeof Overlay).config.type as OverlayType\r\n }\r\n\r\n get label() {\r\n return (this.constructor as typeof Overlay).config.label\r\n }\r\n\r\n get config() {\r\n return (this.constructor as typeof Overlay).config\r\n }\r\n\r\n getLabelColor() {\r\n return this.attrs.color ? convertColorToHEX(this.attrs.color) : DEFAULT_LABEL_COLOR\r\n }\r\n\r\n getFreeColor() {\r\n return this.getChartLayoutSettings().ColorsSettings[0]\r\n // TODO proper implementation - example how this could be done:\r\n // let colorsUsed = []\r\n // for (let overlay of this.chart.overlays) {\r\n // let object = overlay.getModalConfig().inputs\r\n // for (let _ in object) {\r\n // let input = object[_]\r\n // if (input.type === 'color') {\r\n // colorsUsed.push(input.value)\r\n // }\r\n // }\r\n // }\r\n // for (let color of colors) {\r\n // if (!colorsUsed.includes(color)) {\r\n // return color\r\n // }\r\n // }\r\n // return colors[0]\r\n }\r\n\r\n renderContent(_?: RenderingContext2DType) {\r\n this.data = this.model.chart().quote()\r\n }\r\n\r\n fx = (x: number) => this.model.scale.x(this.data.barIndex[x])\r\n\r\n getIsValid(_: string): boolean | undefined {\r\n throw Error('Implement')\r\n }\r\n\r\n getIsNumberInputValid({ key, integerOnly = true }: { key: string; integerOnly?: boolean }): boolean {\r\n const input = this.getModalConfig().inputs.find(({ name }: { name: string }) => key === name)\r\n return !!input && isInRange(input) && (!integerOnly || isPositiveInteger(input.value))\r\n }\r\n\r\n isRendered() {\r\n return true\r\n }\r\n\r\n isRenderedOverlaysLabel() {\r\n return this.isRendered()\r\n }\r\n\r\n getModalConfig(): IModalConfig {\r\n return {\r\n title: '',\r\n inputs: [],\r\n inputsErrorMessages: {},\r\n }\r\n }\r\n\r\n toConfig() {\r\n const colors: string[] = []\r\n const periods: string[] = []\r\n\r\n this.getModalConfig().inputs.forEach((input: IModalConfigInput) => {\r\n if (input.type === 'color') {\r\n colors.push(getRGBAValueFromValidColorString(input.value.toString()))\r\n } else {\r\n periods.push(input.value.toString())\r\n }\r\n })\r\n\r\n return { type: this.type, period: periods.join(','), color: colors.join('|') }\r\n }\r\n\r\n toString() {\r\n return this.config.getShortLabelWithAttrs(this.attrs)\r\n }\r\n}\r\n\r\nexport default Overlay\r\n","import { ChartConfigChartPaneElement, RequireByKey, Theme } from '../../types/shared'\r\nimport { BbCalculation } from '../indicator-calculation/bb'\r\nimport { getParsedIntegersFromPeriodString } from '../utils/helpers'\r\nimport { Attrs, BBConfig } from './configs/bb'\r\nimport Overlay from './overlay'\r\n\r\nconst BB_COLORS = {\r\n [Theme.light]: {\r\n TOP: '#D386DF',\r\n BOTTOM: '#69C1EA',\r\n MIDDLE: '#CFD2F2',\r\n },\r\n [Theme.dark]: {\r\n TOP: '#D38BFB',\r\n BOTTOM: '#57AEFB',\r\n MIDDLE: '#E1B6FC',\r\n },\r\n}\r\n\r\nconst DEFAULT_PARAMETERS = {\r\n Period: 20,\r\n Deviations: 2.0,\r\n}\r\n\r\nfunction parsePeriod(periodStr: string) {\r\n const values = periodStr.split(',')\r\n const period = parseInt(values[0]) || DEFAULT_PARAMETERS.Period\r\n const deviations = parseFloat(values[1]) || DEFAULT_PARAMETERS.Deviations\r\n\r\n return [period, deviations]\r\n}\r\n\r\nclass BollingerBands extends Overlay {\r\n static config = BBConfig\r\n\r\n static getNumOfBarsBuffer({ period }: RequireByKey) {\r\n const [periodInt = 0] = getParsedIntegersFromPeriodString(period)\r\n return periodInt + 1 // +1 offsets rendering so it doesn't start on first bar which doesn't look OK in SSR rendered charts\r\n }\r\n\r\n set(obj: Partial) {\r\n super.set(obj)\r\n const { period } = obj\r\n if (typeof period === 'string') {\r\n const [periodInt, deviations] = parsePeriod(period)\r\n this.attrs.period = periodInt\r\n this.attrs.deviations = deviations\r\n this.trigger('change')\r\n }\r\n return this\r\n }\r\n\r\n renderContent(context: CanvasRenderingContext2D) {\r\n if (typeof this.attrs.period !== 'number') {\r\n return\r\n }\r\n super.renderContent()\r\n const { Colors } = this.getChartLayoutSettings().ChartSettings.general\r\n const theme = this.model.chart().chart_layout().theme as Theme\r\n const { leftOffset, width } = this.model.chart()\r\n const [top, bottom] = this.model.scale.y.domain()\r\n const scaledTop = this.fy(top)\r\n const scaledBottom = this.fy(bottom)\r\n const { close } = this.data\r\n const period = Math.min(this.attrs.period, close.length - 1)\r\n\r\n let firstBarToRender: number | undefined\r\n let lastBarToRender = 0\r\n\r\n // middle line && find first & last bar to render\r\n context.translate(0.5, 0.5)\r\n context.beginPath()\r\n context.set('lineWidth', 1)\r\n context.set('strokeStyle', BB_COLORS[theme].MIDDLE)\r\n\r\n const bbCalculation = new BbCalculation({\r\n quote: this.data,\r\n options: {\r\n period,\r\n deviations: this.attrs.deviations,\r\n },\r\n })\r\n\r\n bbCalculation.calculate(({ sma }, dataIndex) => {\r\n if (this.fx(dataIndex + 1) + leftOffset < 0) {\r\n return\r\n }\r\n if (firstBarToRender === undefined) firstBarToRender = dataIndex\r\n\r\n context.lineTo(this.fx(dataIndex), Math.round(this.fy(sma[dataIndex])))\r\n\r\n if (this.fx(dataIndex - 1) + leftOffset > width) {\r\n return false\r\n }\r\n lastBarToRender = dataIndex\r\n })\r\n\r\n if (firstBarToRender === undefined) return\r\n context.stroke()\r\n context.set('fillStyle', Colors.overlayTransparentBackground)\r\n\r\n // top line\r\n context.beginPath()\r\n context.moveTo(this.fx(firstBarToRender), scaledTop)\r\n context.set('strokeStyle', BB_COLORS[theme].TOP)\r\n for (let i = firstBarToRender; i <= lastBarToRender; i++) {\r\n context.lineTo(this.fx(i), Math.round(this.fy(bbCalculation.calculatedValues.upperBand[i])))\r\n }\r\n context.stroke()\r\n context.lineTo(this.fx(lastBarToRender), scaledTop)\r\n context.fill()\r\n\r\n // bottom line\r\n context.beginPath()\r\n context.moveTo(this.fx(firstBarToRender), scaledBottom)\r\n context.set('strokeStyle', BB_COLORS[theme].BOTTOM)\r\n for (let i = firstBarToRender; i <= lastBarToRender; i++) {\r\n context.lineTo(this.fx(i), Math.round(this.fy(bbCalculation.calculatedValues.lowerBand[i])))\r\n }\r\n context.stroke()\r\n context.lineTo(this.fx(lastBarToRender), scaledBottom)\r\n context.fill()\r\n context.translate(-0.5, -0.5)\r\n }\r\n\r\n getModalConfig() {\r\n const options = {\r\n period: {\r\n type: 'number',\r\n label: BBConfig.inputsLabels.period,\r\n name: 'period',\r\n value: this.attrs.period ?? DEFAULT_PARAMETERS.Period,\r\n required: true,\r\n min: 1,\r\n max: 999999,\r\n },\r\n deviations: {\r\n type: 'number',\r\n label: BBConfig.inputsLabels.deviations,\r\n name: 'deviations',\r\n value: this.attrs.deviations ?? DEFAULT_PARAMETERS.Deviations,\r\n required: true,\r\n min: 0.1,\r\n max: 999,\r\n step: 0.1,\r\n },\r\n topColor: {\r\n type: 'color',\r\n label: BBConfig.inputsLabels.topColor,\r\n name: 'topColor',\r\n value: this.attrs.topColor ?? this.getFreeColor(),\r\n },\r\n bottomColor: {\r\n type: 'color',\r\n label: BBConfig.inputsLabels.bottomColor,\r\n name: 'bottomColor',\r\n value: this.attrs.bottomColor ?? this.getFreeColor(),\r\n },\r\n }\r\n\r\n return {\r\n title: BBConfig.label,\r\n inputs: BBConfig.inputsOrder.map((item) => options[item]),\r\n inputsErrorMessages: {\r\n period: `${options.period.label} must be a whole number between ${options.period.min} and ${options.period.max}`,\r\n deviations: `${options.deviations.label} must be a number between ${options.deviations.min} and ${options.deviations.max}`,\r\n },\r\n }\r\n }\r\n\r\n getIsValid(key: string): boolean {\r\n switch (key) {\r\n case 'period':\r\n return this.getIsNumberInputValid({ key })\r\n case 'deviations':\r\n return this.getIsNumberInputValid({ key, integerOnly: false })\r\n case 'topColor':\r\n case 'bottomColor':\r\n // Some users have wrong colors which break the form validation\r\n return true\r\n default:\r\n return false\r\n }\r\n }\r\n\r\n getLabelColor() {\r\n const theme = this.model.chart().chart_layout().theme as Theme\r\n return this.attrs.topColor || BB_COLORS[theme].TOP\r\n }\r\n}\r\n\r\nBollingerBands.prototype.defaults = { topColor: '#69c1ea', bottomColor: '#d386df' }\r\n\r\nexport default BollingerBands\r\n","import { OverlayType } from '../../constants/common'\r\nimport BaseConfig from './overlayBaseConfig'\r\n\r\nexport type Options = {\r\n period: number\r\n}\r\n\r\nexport interface Attrs extends Options {\r\n channelStrokeColor: string\r\n channelFillColor: string\r\n medianBandColor: string\r\n}\r\n\r\nexport class DchConfig extends BaseConfig {\r\n static type = OverlayType.Dch\r\n static abbreviation = 'dch'\r\n static label = 'Donchian Channels'\r\n static shortLabel = 'Donchian'\r\n static optionsOrder = ['period'] as const\r\n static optionsLabels = { period: 'Period' }\r\n static inputsOrder = ['period', 'channelStrokeColor', 'channelFillColor', 'medianBandColor'] as Array\r\n static inputsLabels = {\r\n period: 'Period',\r\n channelStrokeColor: 'Channels Stroke Color',\r\n channelFillColor: 'Channels Fill Color',\r\n medianBandColor: 'Median Band Color',\r\n }\r\n}\r\n","import utils from '../utils'\r\nimport { drawInVisibleArea } from '../utils/draw_in_visible_area'\r\nimport { Attrs, DchConfig } from './configs/dch'\r\nimport Overlay from './overlay'\r\n\r\nconst DEFAULT_PERIOD = 20\r\n\r\nconst COLORS = {\r\n ChannelStroke: '#69c1ea',\r\n ChannelFill: '#69C1EA12',\r\n MedianBandStroke: '#ffa75f',\r\n}\r\n\r\nclass DonchianChannels extends Overlay {\r\n static config = DchConfig\r\n\r\n set(obj: Partial) {\r\n super.set(obj)\r\n const { period } = obj\r\n if (typeof period === 'string') {\r\n this.attrs.period = parseInt(period, 10)\r\n this.trigger('change')\r\n }\r\n return this\r\n }\r\n\r\n renderContent(context: CanvasRenderingContext2D) {\r\n super.renderContent()\r\n const { leftOffset, width } = this.model.chart()\r\n const { period } = this.attrs\r\n const upperBand: number[] = []\r\n const lowerBand: number[] = []\r\n const medianBand: number[] = []\r\n let firstBarToRender = -1\r\n let lastBarToRender = 0\r\n if (this.data.close.length === undefined) {\r\n return\r\n }\r\n\r\n context.save()\r\n context.translate(0.5, 0.5)\r\n context.set('lineWidth', 1)\r\n context.set('strokeStyle', COLORS.ChannelStroke)\r\n context.set('fillStyle', COLORS.ChannelFill)\r\n\r\n //upper band + clip\r\n context.beginPath()\r\n drawInVisibleArea({\r\n quote: this.data,\r\n paneModel: this.model,\r\n leftOffset,\r\n width,\r\n drawBarCallback: (i, x) => {\r\n firstBarToRender = firstBarToRender === -1 ? i : firstBarToRender\r\n upperBand[i] = utils.max(this.data.high.slice(Math.max(0, i - period), i + 1))\r\n lowerBand[i] = utils.min(this.data.low.slice(Math.max(0, i - period), i + 1))\r\n medianBand[i] = (upperBand[i] + lowerBand[i]) / 2\r\n\r\n context.lineTo(x, Math.round(this.fy(upperBand[i])))\r\n lastBarToRender = i\r\n },\r\n })\r\n context.stroke()\r\n context.lineTo(this.fx(lastBarToRender), context.canvas.height)\r\n context.lineTo(this.fx(firstBarToRender), context.canvas.height)\r\n context.clip()\r\n\r\n // lower band + fill\r\n context.beginPath()\r\n for (let i = firstBarToRender; i <= lastBarToRender; i++) {\r\n const x = this.fx(i)\r\n context.lineTo(x, Math.round(this.fy(lowerBand[i])))\r\n }\r\n context.stroke()\r\n context.lineTo(this.fx(lastBarToRender), 0)\r\n context.lineTo(0, 0)\r\n context.fill()\r\n\r\n // median band\r\n context.set('strokeStyle', COLORS.MedianBandStroke)\r\n context.beginPath()\r\n for (let i = firstBarToRender; i <= lastBarToRender; i++) {\r\n const x = this.fx(i)\r\n context.lineTo(x, Math.round(this.fy(medianBand[i])))\r\n }\r\n context.stroke()\r\n context.restore()\r\n }\r\n\r\n getModalConfig() {\r\n const options = {\r\n period: {\r\n type: 'number',\r\n label: 'Period',\r\n name: 'period',\r\n value: this.attrs.period ?? DEFAULT_PERIOD,\r\n required: true,\r\n min: 1,\r\n max: 999999,\r\n },\r\n channelStrokeColor: {\r\n type: 'color',\r\n label: 'Channels Stroke Color',\r\n name: 'channelStrokeColor',\r\n value: this.attrs.channelStrokeColor ?? this.getFreeColor(),\r\n },\r\n channelFillColor: {\r\n type: 'color',\r\n label: 'Channels Fill Color',\r\n name: 'channelFillColor',\r\n value: this.attrs.channelFillColor ?? this.getFreeColor(),\r\n },\r\n medianBandColor: {\r\n type: 'color',\r\n label: 'Median Band Color',\r\n name: 'medianBandColor',\r\n value: this.attrs.medianBandColor ?? this.getFreeColor(),\r\n },\r\n }\r\n\r\n return {\r\n title: DchConfig.label,\r\n inputs: DchConfig.inputsOrder.map((item) => options[item]),\r\n inputsErrorMessages: {\r\n period: `${options.period.label} must be a whole number between ${options.period.min} and ${options.period.max}`,\r\n },\r\n }\r\n }\r\n\r\n getIsValid(key: string) {\r\n switch (key) {\r\n case 'period':\r\n return this.getIsNumberInputValid({ key })\r\n case 'channelStrokeColor':\r\n case 'channelFillColor':\r\n case 'medianBandColor':\r\n return true\r\n default:\r\n return false\r\n }\r\n }\r\n\r\n getLabelColor() {\r\n return this.attrs.medianBandColor\r\n }\r\n}\r\n\r\nDonchianChannels.prototype.defaults = {\r\n medianBandColor: COLORS.MedianBandStroke,\r\n channelStrokeColor: COLORS.ChannelStroke,\r\n channelFillColor: COLORS.ChannelFill,\r\n}\r\n\r\nexport default DonchianChannels\r\n","import { EMACalculation } from '../indicator-calculation/ema'\r\nimport { Attrs, EMAConfig } from './configs/ema'\r\nimport Overlay from './overlay'\r\n\r\nclass EMA extends Overlay {\r\n static config = EMAConfig\r\n\r\n set(obj: Partial) {\r\n super.set(obj)\r\n const { period } = obj\r\n if (typeof period === 'string') {\r\n this.attrs.period = parseInt(period, 10)\r\n this.trigger('change')\r\n }\r\n return this\r\n }\r\n\r\n renderContent(context: CanvasRenderingContext2D) {\r\n super.renderContent()\r\n const { leftOffset, width } = this.model.chart()\r\n\r\n context.translate(0.5, 0.5)\r\n context.beginPath()\r\n context.set('lineWidth', 1)\r\n context.set('strokeStyle', this.attrs.color)\r\n const emaCalculation = new EMACalculation({\r\n quote: this.data,\r\n options: {\r\n period: this.attrs.period,\r\n },\r\n })\r\n emaCalculation.calculate(({ ema }, dataIndex) => {\r\n const x = this.fx(dataIndex)\r\n if (this.fx(dataIndex + 1) + leftOffset < 0) {\r\n return\r\n }\r\n if (this.fx(dataIndex - 1) + leftOffset > width) {\r\n return false\r\n }\r\n context.lineTo(x, Math.round(this.fy(ema[dataIndex])))\r\n })\r\n context.stroke()\r\n context.translate(-0.5, -0.5)\r\n }\r\n\r\n getModalConfig() {\r\n const options = {\r\n period: {\r\n type: 'number',\r\n label: 'Period',\r\n name: 'period',\r\n value: this.attrs.period ?? 5,\r\n required: true,\r\n min: 1,\r\n max: 999999,\r\n },\r\n color: {\r\n type: 'color',\r\n label: 'Color',\r\n name: 'color',\r\n value: this.attrs.color ?? this.getFreeColor(),\r\n },\r\n }\r\n\r\n return {\r\n title: this.config.label,\r\n inputs: this.config.inputsOrder.map((item) => options[item as keyof Attrs]),\r\n inputsErrorMessages: {\r\n period: `${options.period.label} must be a whole number between ${options.period.min} and ${options.period.max}`,\r\n },\r\n }\r\n }\r\n\r\n getIsValid(key: string) {\r\n switch (key) {\r\n case 'period':\r\n return this.getIsNumberInputValid({ key })\r\n case 'color':\r\n return !!this.attrs[key] // use real color validation, we got isValidHexColor but it might be also RGBA\r\n default:\r\n return false\r\n }\r\n }\r\n}\r\n\r\nEMA.prototype.defaults = { color: '#ffa75f' }\r\n\r\nexport default EMA\r\n","import { OverlayType } from '../../constants/common'\r\nimport { EMAConfig } from './ema'\r\n\r\nexport class EMA2Config extends EMAConfig {\r\n static type = OverlayType.Ema2\r\n}\r\n","import { EMA2Config } from './configs/ema2'\r\nimport EMA from './ema'\r\n\r\nclass EMA2 extends EMA {\r\n static config = EMA2Config\r\n}\r\n\r\nEMA2.prototype.defaults = { color: '#ff6400' }\r\n\r\nexport default EMA2\r\n","import { OverlayType } from '../../constants/common'\r\nimport BaseConfig from './overlayBaseConfig'\r\n\r\nexport type Options = {\r\n period: number\r\n}\r\n\r\nexport interface Attrs extends Options {\r\n lowColor: string\r\n highColor: string\r\n}\r\n\r\nexport class HILOConfig extends BaseConfig {\r\n static type = OverlayType.Hilo\r\n static abbreviation = 'hilo'\r\n static label = 'High/Low'\r\n static shortLabel = 'HILO'\r\n static optionsOrder = ['period'] as const\r\n static optionsLabels = { period: 'Period' }\r\n static inputsOrder = ['period', 'highColor', 'lowColor'] as Array\r\n static inputsLabels = {\r\n period: 'Period',\r\n highColor: 'High Color',\r\n lowColor: 'Low Color',\r\n }\r\n}\r\n","import PaneModel from '../models/pane'\r\nimport { getBarWidthWithMargin } from '../utils/chart'\r\nimport { Attrs, HILOConfig } from './configs/hilo'\r\nimport Overlay from './overlay'\r\n\r\nclass HighLow extends Overlay {\r\n static config = HILOConfig\r\n\r\n constructor(values: Partial, model: PaneModel) {\r\n super(values, model)\r\n this.renderContent = this.renderContent.bind(this)\r\n }\r\n\r\n set(obj: Partial) {\r\n super.set(obj)\r\n const { period } = obj\r\n if (typeof period === 'string') {\r\n this.attrs.period = parseInt(period, 10)\r\n this.trigger('change')\r\n }\r\n return this\r\n }\r\n\r\n renderContent(context: CanvasRenderingContext2D) {\r\n super.renderContent()\r\n const chartModel = this.model.chart()\r\n const { ChartSettings } = this.getChartLayoutSettings()\r\n const { Colors } = ChartSettings.general\r\n const { leftOffset, width, zoomFactor } = chartModel\r\n const barWidth = getBarWidthWithMargin({\r\n zoomFactor,\r\n chartLayout: chartModel.chart_layout(),\r\n })\r\n const halfWidth = barWidth / 2\r\n const period = Math.min(this.attrs.period, this.data.close.length - 1)\r\n let firstBarToRender\r\n let lastBarToRender = 0\r\n context.translate(0.5, 0.5)\r\n context.set('fillStyle', Colors.overlayTransparentBackground)\r\n context.beginPath()\r\n context.set('strokeStyle', this.attrs.highColor)\r\n let prevHigh = -1\r\n for (let i = 0; i < this.data.close.length; i++) {\r\n let highestHigh = this.data.high[i]\r\n for (let j = i - period + 1; j <= i; j++) {\r\n if (this.data.high[j] > highestHigh) {\r\n highestHigh = this.data.high[j]\r\n }\r\n }\r\n\r\n const x = this.fx(i)\r\n if (this.fx(i + 1) + leftOffset < -10) {\r\n prevHigh = highestHigh\r\n continue\r\n }\r\n if (firstBarToRender === undefined) firstBarToRender = i\r\n if (this.fx(i - 1) + leftOffset > width) {\r\n break\r\n }\r\n\r\n const diff = this.data.barIndex[i] - this.data.barIndex[lastBarToRender]\r\n if (diff > 1 && prevHigh !== highestHigh && prevHigh > 0) {\r\n context.lineTo(Math.round(x - halfWidth), Math.round(this.fy(prevHigh)))\r\n }\r\n context.lineTo(Math.round(x - halfWidth), Math.round(this.fy(highestHigh)))\r\n context.lineTo(Math.round(x + halfWidth), Math.round(this.fy(highestHigh)))\r\n\r\n prevHigh = highestHigh\r\n lastBarToRender = i\r\n }\r\n context.stroke()\r\n if (firstBarToRender === undefined) return\r\n\r\n // return to start and fill with background color\r\n context.lineTo(this.fx(lastBarToRender) + halfWidth, 0)\r\n context.lineTo(this.fx(firstBarToRender) - halfWidth, 0)\r\n context.fill()\r\n\r\n context.beginPath()\r\n context.set('strokeStyle', this.attrs.lowColor)\r\n let prevLow = -1\r\n let prevBar = firstBarToRender\r\n for (let i = firstBarToRender; i <= lastBarToRender; i++) {\r\n let lowestLow = this.data.low[i]\r\n for (let j = i - period + 1; j <= i; j++) {\r\n if (this.data.low[j] < lowestLow) {\r\n lowestLow = this.data.low[j]\r\n }\r\n }\r\n\r\n const x = this.fx(i)\r\n const diff = this.data.barIndex[i] - this.data.barIndex[prevBar]\r\n if (diff > 1 && prevLow !== lowestLow && prevLow > 0) {\r\n context.lineTo(Math.round(x - halfWidth), Math.round(this.fy(prevLow)))\r\n }\r\n context.lineTo(Math.round(x - halfWidth), Math.round(this.fy(lowestLow)))\r\n context.lineTo(Math.round(x + halfWidth), Math.round(this.fy(lowestLow)))\r\n\r\n prevLow = lowestLow\r\n prevBar = i\r\n }\r\n context.stroke()\r\n context.translate(-0.5, -0.5)\r\n\r\n // return to start and fill with background color\r\n context.lineTo(this.fx(lastBarToRender), context.canvas.height)\r\n context.lineTo(this.fx(firstBarToRender) - halfWidth, context.canvas.height)\r\n context.fill()\r\n }\r\n\r\n getModalConfig() {\r\n const options = {\r\n period: {\r\n type: 'number',\r\n label: 'Period',\r\n name: 'period',\r\n value: this.attrs.period ?? 50,\r\n required: true,\r\n min: 1,\r\n max: 999999,\r\n },\r\n highColor: {\r\n type: 'color',\r\n label: 'High Color',\r\n name: 'highColor',\r\n value: this.attrs.highColor ?? this.getFreeColor(),\r\n },\r\n lowColor: {\r\n type: 'color',\r\n label: 'Low Color',\r\n name: 'lowColor',\r\n value: this.attrs.lowColor ?? this.getFreeColor(),\r\n },\r\n }\r\n\r\n return {\r\n title: HILOConfig.label,\r\n inputs: HILOConfig.inputsOrder.map((item) => options[item]),\r\n inputsErrorMessages: {\r\n period: `${options.period.label} must be a whole number between ${options.period.min} and ${options.period.max}`,\r\n },\r\n }\r\n }\r\n\r\n getIsValid(key: string) {\r\n switch (key) {\r\n case 'period':\r\n return this.getIsNumberInputValid({ key })\r\n case 'highColor':\r\n case 'lowColor':\r\n // Some users have wrong colors which break the form validation\r\n return true\r\n default:\r\n return false\r\n }\r\n }\r\n\r\n getLabelColor() {\r\n return this.attrs.highColor\r\n }\r\n}\r\n\r\nHighLow.prototype.defaults = {\r\n lowColor: '#69c1ea',\r\n highColor: '#d386df',\r\n}\r\n\r\nexport default HighLow\r\n","import { OverlayType } from '../../constants/common'\r\nimport BaseConfig from './overlayBaseConfig'\r\n\r\nexport type Options = {\r\n price: number\r\n}\r\n\r\nexport interface Attrs extends Options {\r\n period: number\r\n color: string\r\n}\r\n\r\nexport class HLineConfig extends BaseConfig {\r\n static type = OverlayType.Hline\r\n static abbreviation = 'hline'\r\n static label = 'Horizontal Line'\r\n static shortLabel = 'HL'\r\n static optionsOrder = ['price'] as const\r\n static optionsLabels = { price: 'Price' }\r\n static inputsOrder = ['price', 'color'] as Array>\r\n static inputsLabels = {\r\n price: 'Price',\r\n color: 'Color',\r\n }\r\n}\r\n","import { isPositiveFloat } from '../utils/helpers'\r\nimport { Attrs, HLineConfig } from './configs/hline'\r\nimport Overlay from './overlay'\r\n\r\nclass HorizontalLine extends Overlay {\r\n static config = HLineConfig\r\n\r\n static getNumOfBarsBuffer() {\r\n return 0\r\n }\r\n\r\n set(obj: Partial) {\r\n super.set(obj)\r\n if (typeof this.attrs.period === 'string' && this.attrs.price === undefined) {\r\n this.attrs.price = parseFloat(this.attrs.period)\r\n this.trigger('change')\r\n }\r\n return this\r\n }\r\n\r\n renderContent(context: CanvasRenderingContext2D) {\r\n super.renderContent()\r\n const y = Math.round(this.fy(this.attrs.price))\r\n context.set('strokeStyle', this.attrs.color)\r\n context.translate(0, 0.5)\r\n context.beginPath()\r\n context.moveTo(-this.model.chart().leftOffset, y)\r\n context.lineTo(-this.model.chart().leftOffset + this.model.chart().width, y)\r\n context.stroke()\r\n context.translate(0, -0.5)\r\n }\r\n\r\n getModalConfig() {\r\n const options = {\r\n price: {\r\n type: 'number',\r\n label: 'Price',\r\n name: 'price',\r\n value: this.attrs.price || this.model?.scale?.y?.domain().reduce((a: number, b: number) => a + b, 0) / 2,\r\n required: true,\r\n step: 0.1,\r\n },\r\n color: {\r\n type: 'color',\r\n label: 'Color',\r\n name: 'color',\r\n value: this.attrs.color ?? this.getFreeColor(),\r\n },\r\n }\r\n\r\n return {\r\n title: HLineConfig.label,\r\n inputs: HLineConfig.inputsOrder.map((item) => options[item]),\r\n inputsErrorMessages: {\r\n price: `${options.price.label} must be number`,\r\n },\r\n }\r\n }\r\n\r\n getIsValid(key: string) {\r\n switch (key) {\r\n case 'price':\r\n return isPositiveFloat(this.attrs[key])\r\n case 'color':\r\n return !!this.attrs[key] // use real color validation, we got isValidHexColor but it might be also RGBA\r\n default:\r\n return false\r\n }\r\n }\r\n}\r\n\r\nHorizontalLine.prototype.defaults = { color: '#0587cd' }\r\n\r\nexport default HorizontalLine\r\n","import { OverlayType } from '../../constants/common'\r\nimport BaseConfig from './overlayBaseConfig'\r\n\r\nexport type Options = {\r\n conversion: number\r\n base: number\r\n spanB: number\r\n}\r\n\r\nexport interface Attrs extends Options {\r\n period?: string\r\n spanAStrokeColor: string\r\n spanAFillColor: string\r\n spanBStrokeColor: string\r\n spanBFillColor: string\r\n conversionLineColor: string\r\n baseLineColor: string\r\n laggingSpanColor: string\r\n}\r\n\r\nexport class ICConfig extends BaseConfig {\r\n static type = OverlayType.Ic\r\n static abbreviation = 'ic'\r\n static label = 'Ichimoku Cloud'\r\n static shortLabel = 'Ichimoku'\r\n static optionsOrder = ['conversion', 'base', 'spanB'] as const\r\n\r\n static optionsLabels = {\r\n conversion: 'Conversion Line',\r\n base: 'Base Line Length',\r\n spanB: 'Leading Span B Length',\r\n }\r\n\r\n static inputsOrder = [\r\n ...this.optionsOrder,\r\n 'spanAStrokeColor',\r\n 'spanAFillColor',\r\n 'spanBStrokeColor',\r\n 'spanBFillColor',\r\n 'conversionLineColor',\r\n 'baseLineColor',\r\n 'laggingSpanColor',\r\n ] as Array>\r\n\r\n static inputsLabels = {\r\n ...this.optionsLabels,\r\n spanAStrokeColor: 'Span A Stroke Color',\r\n spanAFillColor: 'Span A Fill Color',\r\n spanBStrokeColor: 'Span B Stroke Color',\r\n spanBFillColor: 'Span B Fill Color',\r\n conversionLineColor: 'Conversion Line Color',\r\n baseLineColor: 'Base Line Color',\r\n laggingSpanColor: 'Lagging Span Color',\r\n }\r\n}\r\n","import { ChartConfigChartPaneElement, RequireByKey } from '../../types/shared'\r\nimport { drawInVisibleArea } from '../utils/draw_in_visible_area'\r\nimport { getParsedIntegersFromPeriodString } from '../utils/helpers'\r\nimport { Attrs, ICConfig } from './configs/ic'\r\nimport Overlay from './overlay'\r\n\r\nconst COLORS = {\r\n SpanA: {\r\n Stroke: '#009600',\r\n Fill: '#00960022',\r\n },\r\n SpanB: {\r\n Stroke: '#C80000',\r\n Fill: '#C8000022',\r\n },\r\n ConversionLine: '#69C1EA',\r\n BaseLine: '#E54040',\r\n LaggingSpan: '#FFA75F',\r\n}\r\n\r\nconst DEFAULT_PARAMETERS = {\r\n Conversion: 9,\r\n Base: 26,\r\n SpanB: 52,\r\n}\r\n\r\nfunction parsePeriod(period: string) {\r\n const [conversion = DEFAULT_PARAMETERS.Conversion, base = DEFAULT_PARAMETERS.Base, spanB = DEFAULT_PARAMETERS.SpanB] =\r\n getParsedIntegersFromPeriodString(period)\r\n return [conversion, base, spanB]\r\n}\r\n\r\nclass IchimokuCloud extends Overlay {\r\n static config = ICConfig\r\n static renderFull = false\r\n\r\n static getNumOfBarsBuffer({ period }: RequireByKey) {\r\n return Math.max(...parsePeriod(period))\r\n }\r\n\r\n get renderFull() {\r\n return (this.constructor as typeof IchimokuCloud).renderFull\r\n }\r\n\r\n set(obj: Partial) {\r\n super.set(obj)\r\n if (\r\n typeof this.attrs.period === 'string' &&\r\n (this.attrs.conversion === undefined || this.attrs.base === undefined || this.attrs.spanB === undefined)\r\n ) {\r\n const [conversion, base, spanB] = parsePeriod(this.attrs.period)\r\n this.attrs.conversion = conversion\r\n this.attrs.base = base\r\n this.attrs.spanB = spanB\r\n }\r\n this.trigger('change')\r\n return this\r\n }\r\n\r\n fx = (x: number) => {\r\n const lastIndex = this.data.close.length - 1\r\n const outsideBar = this.data.barIndex[lastIndex] + x - lastIndex\r\n\r\n return this.model.scale.x(this.data.barIndex[x] ?? outsideBar)\r\n }\r\n\r\n renderContent(context: CanvasRenderingContext2D) {\r\n super.renderContent()\r\n const { leftOffset, width } = this.model.chart()\r\n const { high, low, close } = this.data\r\n\r\n const {\r\n conversion,\r\n base,\r\n spanB,\r\n spanAFillColor,\r\n spanAStrokeColor,\r\n spanBFillColor,\r\n spanBStrokeColor,\r\n baseLineColor,\r\n conversionLineColor,\r\n laggingSpanColor,\r\n } = this.attrs\r\n\r\n const conversionLine: number[] = []\r\n const baseLine: number[] = []\r\n const senkouSpanA: number[] = []\r\n const senkouSpanB: number[] = []\r\n const conversionStartIndex = conversion - 1\r\n const baseStartIndex = base - 1\r\n const spanBIndex = spanB - 1\r\n const start = Math.min(baseStartIndex, conversionStartIndex)\r\n const end = close.length + baseStartIndex\r\n\r\n if (this.data.close.length === 0) return\r\n\r\n // Calculation\r\n for (let i = start; i < end; i++) {\r\n if (i >= conversionStartIndex && i < close.length) {\r\n const highestHi = Math.max(...high.slice(i - conversionStartIndex, i + 1))\r\n const lowestLo = Math.min(...low.slice(i - conversionStartIndex, i + 1))\r\n conversionLine[i] = (highestHi + lowestLo) / 2\r\n }\r\n\r\n if (i >= baseStartIndex && i < close.length) {\r\n const highestHi = Math.max(...high.slice(i - baseStartIndex, i + 1))\r\n const lowestLo = Math.min(...low.slice(i - baseStartIndex, i + 1))\r\n baseLine[i] = (highestHi + lowestLo) / 2\r\n\r\n senkouSpanA[i + baseStartIndex] = (baseLine[i] + conversionLine[i]) / 2 // + baseStart because it needs to be shifted to the future\r\n }\r\n\r\n if (i >= spanBIndex) {\r\n const highestHi = Math.max(...high.slice(i - spanBIndex, i + 1))\r\n const lowestLo = Math.min(...low.slice(i - spanBIndex, i + 1))\r\n senkouSpanB[i + baseStartIndex] = (highestHi + lowestLo) / 2 // + baseStart because it needs to be shifted to the future\r\n }\r\n }\r\n\r\n let lastSpanAX = 0\r\n let lastSpanBX = 0\r\n const cloudStartingX = this.fx(spanBIndex + baseStartIndex)\r\n\r\n const drawInVisibleAreaProps = {\r\n toIndexOffset: baseStartIndex,\r\n leftOffset,\r\n paneModel: this.model,\r\n quote: this.data,\r\n width,\r\n fxOverride: this.fx,\r\n }\r\n\r\n context.set('lineWidth', 1)\r\n context.translate(0.5, 0.5)\r\n context.save()\r\n // 1. Senkou Span A\r\n // 1.1 Stroke\r\n context.set('strokeStyle', spanAStrokeColor)\r\n context.set('fillStyle', spanAFillColor)\r\n context.beginPath()\r\n drawInVisibleArea({\r\n ...drawInVisibleAreaProps,\r\n drawBarCallback: (i, x) => {\r\n context.lineTo(x, Math.round(this.fy(senkouSpanA[i])))\r\n lastSpanAX = x\r\n },\r\n })\r\n context.stroke()\r\n // 1.2 Clipping area\r\n context.lineTo(lastSpanAX, context.canvas.height)\r\n context.lineTo(cloudStartingX, context.canvas.height)\r\n context.clip()\r\n // 1.3 Fill\r\n context.beginPath()\r\n drawInVisibleArea({\r\n ...drawInVisibleAreaProps,\r\n drawBarCallback: (i, x) => {\r\n if (i >= senkouSpanA.length) return\r\n context.lineTo(x, Math.round(this.fy(senkouSpanB[i])))\r\n lastSpanBX = x\r\n },\r\n })\r\n context.lineTo(lastSpanBX, 0)\r\n context.lineTo(cloudStartingX, 0)\r\n context.fill()\r\n context.restore()\r\n\r\n // 2. Senkou Span B\r\n // 2.1 Stroke\r\n context.save()\r\n context.set('strokeStyle', spanBStrokeColor)\r\n context.set('fillStyle', spanBFillColor)\r\n context.beginPath()\r\n drawInVisibleArea({\r\n ...drawInVisibleAreaProps,\r\n drawBarCallback: (i, x) => {\r\n if (i >= senkouSpanA.length) return\r\n context.lineTo(x, Math.round(this.fy(senkouSpanB[i])))\r\n },\r\n })\r\n context.stroke()\r\n // 2.2 Clipping area\r\n context.lineTo(lastSpanBX, context.canvas.height)\r\n context.lineTo(cloudStartingX, context.canvas.height)\r\n context.clip()\r\n // 2.3 Fill\r\n context.beginPath()\r\n drawInVisibleArea({\r\n ...drawInVisibleAreaProps,\r\n drawBarCallback: (i, x) => {\r\n context.lineTo(x, Math.round(this.fy(senkouSpanA[i])))\r\n },\r\n })\r\n context.lineTo(lastSpanBX, 0)\r\n context.lineTo(cloudStartingX, 0)\r\n context.fill()\r\n context.restore()\r\n context.translate(-0.5, -0.5)\r\n\r\n if (this.renderFull) {\r\n // conversion line\r\n context.set('strokeStyle', conversionLineColor)\r\n context.translate(0.5, 0.5)\r\n context.beginPath()\r\n drawInVisibleArea({\r\n ...drawInVisibleAreaProps,\r\n drawBarCallback: (i, x) => {\r\n context.lineTo(x, Math.round(this.fy(conversionLine[i])))\r\n },\r\n })\r\n context.stroke()\r\n\r\n // base line\r\n context.set('strokeStyle', baseLineColor)\r\n context.beginPath()\r\n drawInVisibleArea({\r\n ...drawInVisibleAreaProps,\r\n drawBarCallback: (i, x) => {\r\n context.lineTo(x, Math.round(this.fy(baseLine[i])))\r\n },\r\n })\r\n context.stroke()\r\n\r\n // lagging span\r\n context.set('strokeStyle', laggingSpanColor)\r\n context.beginPath()\r\n drawInVisibleArea({\r\n ...drawInVisibleAreaProps,\r\n fxOverride: (x: number) => this.fx(x - base),\r\n drawBarCallback: (i, x) => {\r\n context.lineTo(x, Math.round(this.fy(this.data.close[i])))\r\n },\r\n })\r\n context.stroke()\r\n context.translate(-0.5, -0.5)\r\n }\r\n }\r\n\r\n getModalConfig() {\r\n const options = {\r\n conversion: {\r\n type: 'number',\r\n label: 'Conversion Line',\r\n name: 'conversion',\r\n value: this.attrs.conversion ?? DEFAULT_PARAMETERS.Conversion,\r\n required: true,\r\n min: 1,\r\n max: 999999,\r\n },\r\n base: {\r\n type: 'number',\r\n label: 'Base Line Length',\r\n name: 'base',\r\n value: this.attrs.base ?? DEFAULT_PARAMETERS.Base,\r\n required: true,\r\n min: 1,\r\n max: 999999,\r\n },\r\n spanB: {\r\n type: 'number',\r\n label: 'Leading Span B Length',\r\n name: 'spanB',\r\n value: this.attrs.spanB ?? DEFAULT_PARAMETERS.SpanB,\r\n required: true,\r\n min: 1,\r\n max: 999999,\r\n },\r\n\r\n spanAStrokeColor: {\r\n type: 'color',\r\n label: 'Span A Stroke Color',\r\n name: 'spanAStrokeColor',\r\n value: this.attrs.spanAStrokeColor ?? this.getFreeColor(),\r\n },\r\n spanAFillColor: {\r\n type: 'color',\r\n label: 'Span A Fill Color',\r\n name: 'spanAFillColor',\r\n value: this.attrs.spanAFillColor ?? this.getFreeColor(),\r\n },\r\n spanBStrokeColor: {\r\n type: 'color',\r\n label: 'Span B Stroke Color',\r\n name: 'spanBStrokeColor',\r\n value: this.attrs.spanBStrokeColor ?? this.getFreeColor(),\r\n },\r\n spanBFillColor: {\r\n type: 'color',\r\n label: 'Span B Fill Color',\r\n name: 'spanBFillColor',\r\n value: this.attrs.spanBFillColor ?? this.getFreeColor(),\r\n },\r\n conversionLineColor: {\r\n type: 'color',\r\n label: 'Conversion Line Color',\r\n name: 'conversionLineColor',\r\n value: this.attrs.conversionLineColor ?? this.getFreeColor(),\r\n },\r\n baseLineColor: {\r\n type: 'color',\r\n label: 'Base Line Color',\r\n name: 'baseLineColor',\r\n value: this.attrs.baseLineColor ?? this.getFreeColor(),\r\n },\r\n laggingSpanColor: {\r\n type: 'color',\r\n label: 'Lagging Span Color',\r\n name: 'laggingSpanColor',\r\n value: this.attrs.laggingSpanColor ?? this.getFreeColor(),\r\n },\r\n }\r\n\r\n return {\r\n title: this.config.label,\r\n inputs: this.config.inputsOrder.map((item) => options[item as keyof Omit]),\r\n inputsErrorMessages: {\r\n conversion: `${options.conversion.label} must be a whole number between ${options.conversion.min} and ${options.conversion.max}`,\r\n base: `${options.base.label} must be a whole number between ${options.base.min} and ${options.base.max}`,\r\n spanB: `${options.spanB.label} must be a whole number between ${options.spanB.min} and ${options.spanB.max}`,\r\n },\r\n }\r\n }\r\n\r\n getIsValid(key: string) {\r\n switch (key) {\r\n case 'conversion':\r\n case 'base':\r\n case 'spanB':\r\n case 'lagging':\r\n return this.getIsNumberInputValid({ key })\r\n case 'spanAStrokeColor':\r\n case 'spanAFillColor':\r\n case 'spanBStrokeColor':\r\n case 'spanBFillColor':\r\n case 'conversionLineColor':\r\n case 'baseLineColor':\r\n case 'laggingSpanColor':\r\n return true\r\n default:\r\n return false\r\n }\r\n }\r\n\r\n getLabelColor() {\r\n return this.attrs.spanAStrokeColor\r\n }\r\n}\r\n\r\nIchimokuCloud.prototype.defaults = {\r\n spanAStrokeColor: COLORS.SpanA.Stroke,\r\n spanAFillColor: COLORS.SpanA.Fill,\r\n spanBStrokeColor: COLORS.SpanB.Stroke,\r\n spanBFillColor: COLORS.SpanB.Fill,\r\n conversionLineColor: COLORS.ConversionLine,\r\n baseLineColor: COLORS.BaseLine,\r\n laggingSpanColor: COLORS.LaggingSpan,\r\n}\r\n\r\nexport default IchimokuCloud\r\n","import { OverlayType } from '../../constants/common'\r\nimport { ICConfig } from './ic'\r\n\r\nexport class ICFConfig extends ICConfig {\r\n static type = OverlayType.Icf\r\n static abbreviation = 'icf'\r\n static label = 'Ichimoku Cloud (Full)'\r\n static shortLabel = 'Ichimoku Full'\r\n}\r\n","import { ICFConfig } from './configs/icf'\r\nimport IchimokuCloud from './ic'\r\n\r\nclass IchimokuCloudFull extends IchimokuCloud {\r\n static config = ICFConfig\r\n static renderFull = true\r\n}\r\n\r\nexport default IchimokuCloudFull\r\n","import { OverlayType } from '../../constants/common'\r\nimport BaseConfig from './overlayBaseConfig'\r\n\r\nexport type Options = {\r\n emaPeriod: number\r\n multiplier: number\r\n atrPeriod: number\r\n}\r\n\r\nexport interface Attrs extends Options {\r\n period?: string\r\n strokeColor: string\r\n fillColor: string\r\n}\r\n\r\nexport class KCHConfig extends BaseConfig {\r\n static type = OverlayType.Kch\r\n static abbreviation = 'kch'\r\n static label = 'Keltner Channel'\r\n static shortLabel = 'Keltner Channel'\r\n static optionsOrder = ['emaPeriod', 'multiplier', 'atrPeriod'] as const\r\n\r\n static optionsLabels = {\r\n emaPeriod: 'EMA Period',\r\n multiplier: 'Multiplier',\r\n atrPeriod: 'ATR Period',\r\n }\r\n\r\n static inputsOrder = [...this.optionsOrder, 'strokeColor', 'fillColor'] as Array>\r\n\r\n static inputsLabels = {\r\n ...this.optionsLabels,\r\n strokeColor: 'Stroke Color',\r\n fillColor: 'Fill Color',\r\n }\r\n}\r\n","import { ChartConfigChartPaneElement, RequireByKey } from '../../types/shared'\r\nimport AverageTrueRange from '../helpers/atr'\r\nimport { ExponentialMovingAverage } from '../indicator-calculation/ema'\r\nimport { Attrs, KCHConfig } from './configs/kch'\r\nimport Overlay from './overlay'\r\n\r\nconst DEFAULT_PARAMETERS = {\r\n emaPeriod: 20,\r\n multiplier: 2.0,\r\n atrPeriod: 10,\r\n}\r\n\r\nconst COLORS = {\r\n Stroke: '#69C1EA',\r\n Fill: '#69C1EA33',\r\n}\r\n\r\nfunction parsePeriod(period: string) {\r\n const values = period.split(',')\r\n const emaPeriod = parseInt(values[0])\r\n const multiplier = parseFloat(values[1])\r\n const atrPeriod = parseInt(values[2])\r\n\r\n return [emaPeriod, multiplier, atrPeriod]\r\n}\r\n\r\nclass KeltnerChannel extends Overlay {\r\n static config = KCHConfig\r\n static getNumOfBarsBuffer({ period }: RequireByKey) {\r\n return Math.max(...parsePeriod(period)) * 2\r\n }\r\n\r\n set(obj: Partial) {\r\n super.set(obj)\r\n if (\r\n typeof this.attrs.period === 'string' &&\r\n (this.attrs.emaPeriod === undefined || this.attrs.multiplier === undefined || this.attrs.atrPeriod === undefined)\r\n ) {\r\n const [emaPeriod, multiplier, atrPeriod] = parsePeriod(this.attrs.period)\r\n this.attrs.emaPeriod = emaPeriod\r\n this.attrs.multiplier = multiplier\r\n this.attrs.atrPeriod = atrPeriod\r\n this.trigger('change')\r\n }\r\n return this\r\n }\r\n\r\n renderContent(context: CanvasRenderingContext2D) {\r\n super.renderContent()\r\n const { leftOffset, width } = this.model.chart()\r\n const { emaPeriod, multiplier, atrPeriod, strokeColor, fillColor } = this.attrs\r\n const ema = new ExponentialMovingAverage(emaPeriod)\r\n const atr = new AverageTrueRange(atrPeriod)\r\n const middleLine: number[] = []\r\n const upperBand: number[] = []\r\n const lowerBand: number[] = []\r\n const start = Math.max(emaPeriod, atrPeriod)\r\n let firstBarToRender\r\n let lastBarToRender = 0\r\n\r\n context.save()\r\n context.translate(0.5, 0.5)\r\n context.set('lineWidth', 1)\r\n context.set('strokeStyle', strokeColor)\r\n context.set('fillStyle', fillColor)\r\n\r\n //top line + clip\r\n context.beginPath()\r\n for (let i = 1; i < this.data.close.length; i++) {\r\n ema.add(this.data.close[i])\r\n atr.add(this.data.high[i], this.data.low[i], this.data.close[i - 1])\r\n if (i < start) {\r\n continue\r\n }\r\n\r\n const x = this.fx(i)\r\n if (this.fx(i + 1) + leftOffset < 0) {\r\n continue\r\n }\r\n if (this.fx(i - 1) + leftOffset > width) {\r\n break\r\n }\r\n if (firstBarToRender === undefined) firstBarToRender = i\r\n\r\n middleLine[i] = ema.value\r\n upperBand[i] = ema.value + multiplier * atr.value\r\n lowerBand[i] = ema.value - multiplier * atr.value\r\n\r\n context.lineTo(x, Math.round(this.fy(upperBand[i])))\r\n lastBarToRender = i\r\n }\r\n if (firstBarToRender === undefined) {\r\n context.restore()\r\n return\r\n }\r\n context.stroke()\r\n context.lineTo(this.fx(lastBarToRender), context.canvas.height)\r\n context.lineTo(this.fx(firstBarToRender), context.canvas.height)\r\n context.clip()\r\n\r\n // bottom line + fill\r\n context.beginPath()\r\n for (let i = firstBarToRender; i <= lastBarToRender; i++) {\r\n const x = this.fx(i)\r\n context.lineTo(x, Math.round(this.fy(lowerBand[i])))\r\n }\r\n context.stroke()\r\n context.lineTo(this.fx(lastBarToRender), 0)\r\n context.lineTo(0, 0)\r\n context.fill()\r\n\r\n // middle line\r\n context.beginPath()\r\n for (let i = firstBarToRender; i <= lastBarToRender; i++) {\r\n const x = this.fx(i)\r\n context.lineTo(x, Math.round(this.fy(middleLine[i])))\r\n }\r\n context.stroke()\r\n context.restore()\r\n }\r\n\r\n getModalConfig() {\r\n const options = {\r\n emaPeriod: {\r\n type: 'number',\r\n label: 'EMA Period',\r\n name: 'emaPeriod',\r\n value: this.attrs.emaPeriod ?? DEFAULT_PARAMETERS.emaPeriod,\r\n required: true,\r\n min: 1,\r\n max: 999999,\r\n },\r\n multiplier: {\r\n type: 'number',\r\n label: 'Multiplier',\r\n name: 'multiplier',\r\n value: this.attrs.multiplier ?? DEFAULT_PARAMETERS.multiplier,\r\n required: true,\r\n step: 0.1,\r\n min: 0.0,\r\n max: 999,\r\n },\r\n atrPeriod: {\r\n type: 'number',\r\n label: 'ATR Period',\r\n name: 'atrPeriod',\r\n value: this.attrs.atrPeriod ?? DEFAULT_PARAMETERS.atrPeriod,\r\n required: true,\r\n min: 1,\r\n max: 999999,\r\n },\r\n strokeColor: {\r\n type: 'color',\r\n label: 'Stroke Color',\r\n name: 'strokeColor',\r\n value: this.attrs.strokeColor ?? this.getFreeColor(),\r\n },\r\n fillColor: {\r\n type: 'color',\r\n label: 'Fill Color',\r\n name: 'fillColor',\r\n value: this.attrs.fillColor ?? this.getFreeColor(),\r\n },\r\n }\r\n\r\n return {\r\n title: KCHConfig.label,\r\n inputs: KCHConfig.inputsOrder.map((item) => options[item]),\r\n inputsErrorMessages: {\r\n emaPeriod: `${options.emaPeriod.label} must be a whole number between ${options.emaPeriod.min} and ${options.emaPeriod.max}`,\r\n multiplier: `${options.multiplier.label} must be a number between ${options.multiplier.min} and ${options.multiplier.max}`,\r\n atrPeriod: `${options.atrPeriod.label} must be a whole number between ${options.atrPeriod.min} and ${options.atrPeriod.max}`,\r\n },\r\n }\r\n }\r\n\r\n getIsValid(key: string) {\r\n switch (key) {\r\n case 'emaPeriod':\r\n return this.getIsNumberInputValid({ key })\r\n case 'multiplier':\r\n return this.getIsNumberInputValid({ key, integerOnly: false })\r\n case 'atrPeriod':\r\n return this.getIsNumberInputValid({ key })\r\n case 'strokeColor':\r\n case 'fillColor':\r\n return true\r\n default:\r\n return false\r\n }\r\n }\r\n\r\n getLabelColor() {\r\n return this.attrs.strokeColor\r\n }\r\n}\r\n\r\nKeltnerChannel.prototype.defaults = { strokeColor: COLORS.Stroke, fillColor: COLORS.Fill }\r\n\r\nexport default KeltnerChannel\r\n","import { OverlayType } from '../../constants/common'\r\nimport BaseConfig from './overlayBaseConfig'\r\n\r\nexport class NoneConfig extends BaseConfig {\r\n static type = OverlayType.None\r\n static abbreviation = 'none'\r\n static label = 'None'\r\n static shortLabel = 'None'\r\n}\r\n","import { NoneConfig } from './configs/none'\r\nimport Overlay from './overlay'\r\n\r\n// This indicator is used as a placeholder when we need to render TA like chart but don't need any overlay or indicator in the chart\r\nclass None extends Overlay {\r\n static config = NoneConfig\r\n\r\n static getNumOfBarsBuffer() {\r\n return 0\r\n }\r\n\r\n isRendered() {\r\n return false\r\n }\r\n\r\n getIsValid() {\r\n return true\r\n }\r\n}\r\n\r\nexport default None\r\n","import { OverlayType } from '../../constants/common'\r\nimport BaseConfig from './overlayBaseConfig'\r\n\r\ninterface Attrs {\r\n supportColor: string\r\n resistColor: string\r\n}\r\n\r\nexport class PatternsConfig extends BaseConfig {\r\n static type = OverlayType.Patterns\r\n static abbreviation = 'patterns'\r\n static label = 'Patterns (daily charts)'\r\n static shortLabel = ''\r\n static inputsOrder = ['supportColor', 'resistColor'] as Array\r\n static inputsLabels = { supportColor: 'Support Color', resistColor: 'Resist Color' }\r\n}\r\n","import Text from '../canvas/text'\r\nimport { TextAlign, TextBaseline } from '../constants/common'\r\nimport { getRoundedObject, getXYOffsetFromLine } from '../controllers/renderUtils'\r\nimport { PatternsConfig } from './configs/patterns'\r\nimport Overlay from './overlay'\r\n\r\ntype aboveBelowType = 'above' | 'below'\r\n\r\nclass Patterns extends Overlay {\r\n static config = PatternsConfig\r\n\r\n static getNumOfBarsBuffer() {\r\n return 0\r\n }\r\n\r\n renderContent(context: CanvasRenderingContext2D) {\r\n super.renderContent()\r\n const { ChartSettings } = this.getChartLayoutSettings()\r\n const data = this.data\r\n if (data.patterns.length === 0) {\r\n return\r\n }\r\n\r\n const originalScale = {\r\n width: 600,\r\n height: 300,\r\n barsInDay: Math.min(data.close.length, 200),\r\n high: data.patternsMaxRange,\r\n low: data.patternsMinRange,\r\n barWidth: 0,\r\n }\r\n originalScale.barWidth = originalScale.width / 200\r\n\r\n const scaleY = (originalScale.high - originalScale.low) / originalScale.height\r\n const fx = (x: number) => {\r\n if (x === 0) {\r\n return this.fx(0)\r\n }\r\n return this.fx(data.close.length - 1 - ~~(originalScale.barsInDay - x / originalScale.barWidth))\r\n }\r\n const fy = (y: number) => this.fy(originalScale.high - y * scaleY)\r\n const line = (color: string, x1: number, y1: number, x2: number, y2: number) => {\r\n const roundedXY = getRoundedObject({\r\n x1: fx(x1),\r\n y1: fy(y1),\r\n x2: fx(x2),\r\n y2: fy(y2),\r\n })\r\n const translateXY = getXYOffsetFromLine({ lineWidth: 1, ...roundedXY })\r\n context.translate(translateXY.x, translateXY.y)\r\n\r\n context.beginPath()\r\n context.set('lineWidth', 1)\r\n context.set('strokeStyle', color)\r\n context.lineTo(roundedXY.x1, roundedXY.y1)\r\n context.lineTo(roundedXY.x2, roundedXY.y2)\r\n context.stroke()\r\n\r\n context.translate(translateXY.x * -1, translateXY.y * -1)\r\n }\r\n const text = (text: string, aboveBelow: aboveBelowType, color: string, x1: number, x2: number, y1: number) => {\r\n new Text(\r\n {\r\n x: fx((x1 + x2) / 2),\r\n y: fy(y1) + (aboveBelow === 'above' ? -1 : 2),\r\n font: { size: 8, style: 'bold' },\r\n textBaseline: aboveBelow === 'above' ? TextBaseline.bottom : TextBaseline.top,\r\n fillStyle: color,\r\n textAlign: TextAlign.center,\r\n text,\r\n },\r\n this.model\r\n ).render(context)\r\n }\r\n const textHS = (text: string, aboveBelow: aboveBelowType, color: string, x1: number, y1: number) => {\r\n new Text(\r\n {\r\n x: fx(x1) + 5,\r\n y: fy(y1) + (aboveBelow === 'above' ? -1 : 2),\r\n font: { size: 9, style: 'bold' },\r\n textBaseline: aboveBelow === 'above' ? TextBaseline.bottom : TextBaseline.top,\r\n fillStyle: color,\r\n textAlign: TextAlign.center,\r\n text,\r\n },\r\n this.model\r\n ).render(context)\r\n }\r\n const above = (y: number) =>\r\n fy(y) + 10 >= this.model.height - ChartSettings.top.height - ChartSettings.bottom.height ? 'above' : 'below'\r\n const below = (y: number) => (fy(y) <= 15 ? 'below' : 'above')\r\n\r\n const supportColor = 'rgb(0, 150, 220)'\r\n const resistColor = 'rgb(180, 50, 200)'\r\n\r\n for (const pattern of data.patterns) {\r\n const { x1, x2, x3, y3 } = pattern\r\n let { y1, y2 } = pattern\r\n switch (pattern.kind) {\r\n case 1: // Horiz S/R\r\n line('rgba(50, 50, 180, 0.588)', x1, y1, x2, y2)\r\n break\r\n\r\n case 2: // tl resist\r\n line(resistColor, x1, y1, x2, y2)\r\n break\r\n\r\n case 3: // tl support\r\n if (y1 === originalScale.height && y2 === originalScale.height) {\r\n y1 = y2 = originalScale.height - 1\r\n // Maybe just need to check on the new scale?\r\n } // support \"pod grafom\"\r\n line(supportColor, x1, y1, x2, y2)\r\n break\r\n\r\n case 12: // double top\r\n text('Double Top', below(y1), resistColor, x1, x2, y1)\r\n break\r\n\r\n case 13: // double bottom\r\n text('Double Bottom', above(y1), supportColor, x1, x2, y1)\r\n break\r\n\r\n case 14: // multi top\r\n text('Multiple Top', below(y1), resistColor, x1, x2, y1)\r\n break\r\n\r\n case 15: // multi bottom\r\n text('Multiple Bottom', above(y1), supportColor, x1, x2, y1)\r\n break\r\n\r\n case 16: // h&s top\r\n textHS('L', below(y1), resistColor, x1, y1)\r\n textHS('H', below(y2), resistColor, x2, y2)\r\n textHS('R', below(y3), resistColor, x3, y3)\r\n break\r\n\r\n case 17: // h&s bot\r\n textHS('L', above(y1), supportColor, x1, y1)\r\n textHS('H', above(y2), supportColor, x2, y2)\r\n textHS('R', above(y3), supportColor, x3, y3)\r\n break\r\n default:\r\n break\r\n }\r\n }\r\n }\r\n\r\n getModalConfig() {\r\n const options = {\r\n supportColor: {\r\n type: 'color',\r\n label: 'Support Color',\r\n name: 'supportColor',\r\n value: this.attrs.supportColor ?? this.getFreeColor(),\r\n },\r\n resistColor: {\r\n type: 'color',\r\n label: 'Resist Color',\r\n name: 'resistColor',\r\n value: this.attrs.resistColor ?? this.getFreeColor(),\r\n },\r\n }\r\n\r\n return {\r\n title: PatternsConfig.label,\r\n inputs: PatternsConfig.inputsOrder.map((item) => options[item]),\r\n inputsErrorMessages: {},\r\n }\r\n }\r\n\r\n getIsValid() {\r\n return true\r\n }\r\n\r\n isRenderedOverlaysLabel() {\r\n return false\r\n }\r\n}\r\n\r\nPatterns.prototype.defaults = { supportColor: '#69c1ea', resistColor: '#d386df' }\r\n\r\nexport default Patterns\r\n","import { OverlayType } from '../../constants/common'\r\nimport BaseConfig from './overlayBaseConfig'\r\n\r\nexport enum Calculation {\r\n standard = 'Standard',\r\n fibonacci = 'Fibonacci',\r\n}\r\nexport type CalculationType = keyof typeof Calculation\r\n\r\nexport type Options = {\r\n calculationType: CalculationType\r\n}\r\nexport interface Attrs extends Options {\r\n period?: string\r\n color: string\r\n}\r\n\r\nexport class PPConfig extends BaseConfig {\r\n static type = OverlayType.Pp\r\n static abbreviation = 'pp'\r\n static label = 'Pivot Points'\r\n static shortLabel = 'Pivot Points'\r\n static optionsOrder = ['calculationType'] as const\r\n static optionsLabels = { calculationType: 'Calculation Type' }\r\n static inputsOrder = ['calculationType', 'color'] as Array>\r\n static inputsLabels = { calculationType: 'Calculation Type', color: 'Color' }\r\n}\r\n","import * as dateFns from 'date-fns'\r\n\r\nimport { Instrument } from '../../types/shared'\r\nimport Text from '../canvas/text'\r\nimport { TIMEFRAME, TextBaseline } from '../constants/common'\r\nimport Chart from '../models/chart'\r\nimport Utils from '../utils'\r\nimport { getBarWidthWithMargin, round } from '../utils/chart'\r\nimport { getAreNoBarsVisible, getVisibleBarToRenderIndex } from '../utils/draw_in_visible_area'\r\nimport { Attrs, Calculation, CalculationType, PPConfig } from './configs/pp'\r\nimport Overlay from './overlay'\r\n\r\nenum PivotPeriod {\r\n day,\r\n week,\r\n month,\r\n year,\r\n}\r\n\r\ntype PivotPointType = {\r\n pivot: number\r\n res1: number\r\n res2: number\r\n res3: number\r\n sup1: number\r\n sup2: number\r\n sup3: number\r\n}\r\n\r\nconst DEFAULT_PARAMETERS = {\r\n CalculationType: 'standard' as CalculationType,\r\n Color: '#FFA75F',\r\n}\r\nconst FIB_LVL_1 = 0.382\r\nconst FIB_LVL_2 = 0.618\r\nconst DAY_SECONDS = 86400\r\nconst MINUTES_PER_DAY = 1440\r\n\r\nclass PivotPoints extends Overlay {\r\n static config = PPConfig\r\n\r\n set(obj: Partial) {\r\n super.set(obj)\r\n const { period } = obj\r\n if (period) {\r\n this.attrs.calculationType = period as CalculationType\r\n this.trigger('change')\r\n }\r\n return this\r\n }\r\n\r\n getPeriodType() {\r\n switch (this.data.timeframe) {\r\n case TIMEFRAME.i30:\r\n case TIMEFRAME.h:\r\n case TIMEFRAME.h2:\r\n return PivotPeriod.week\r\n case TIMEFRAME.h4:\r\n case TIMEFRAME.d:\r\n return PivotPeriod.month\r\n case TIMEFRAME.w:\r\n case TIMEFRAME.m:\r\n return PivotPeriod.year\r\n default:\r\n return PivotPeriod.day\r\n }\r\n }\r\n\r\n getIsEnoughData(startIndex: number, endIndex: number, periodType: PivotPeriod) {\r\n let dayGap = 7 // one week for week period\r\n if (periodType === PivotPeriod.month) dayGap = 28 // shortest month\r\n if (periodType === PivotPeriod.year) dayGap = 365\r\n\r\n if (startIndex !== endIndex) {\r\n if (startIndex === 0) {\r\n const daysDiff = (this.data.date[endIndex] - this.data.date[startIndex]) / DAY_SECONDS\r\n // we need to somehow determine if we have data if it starts from index 0\r\n // and we can't easily check if day before is different (different month/week/year)\r\n // so we are at least checking if it is [dayGap] days between start and end date\r\n return daysDiff >= dayGap\r\n } else {\r\n const startDay = Utils.dateFromUnixTimestamp(this.data.date[startIndex])\r\n const beforeDay = Utils.dateFromUnixTimestamp(this.data.date[startIndex - 1])\r\n if (periodType === PivotPeriod.week) {\r\n return beforeDay.getDate() !== startDay.getDate()\r\n } else {\r\n return beforeDay.getMonth() !== startDay.getMonth()\r\n }\r\n }\r\n }\r\n return false\r\n }\r\n\r\n fx = (x: number) => {\r\n const lastIndex = this.data.close.length - 1\r\n const outsideBar = this.data.barIndex[lastIndex] + x - lastIndex\r\n\r\n return this.model.scale.x(this.data.barIndex[x] ?? outsideBar)\r\n }\r\n\r\n renderContent(context: CanvasRenderingContext2D) {\r\n super.renderContent()\r\n if (this.data.close.length === 0) return\r\n\r\n const chartModel = this.model.chart() as Chart\r\n const { leftOffset, width, zoomFactor } = chartModel\r\n const { left, right } = chartModel.getChartLayoutSettings().ChartSettings\r\n const chartWidth = width - left.width - right.width\r\n const barWidth = getBarWidthWithMargin({\r\n zoomFactor,\r\n chartLayout: chartModel.chart_layout(),\r\n })\r\n\r\n const firstBarToRender = getVisibleBarToRenderIndex({\r\n quote: this.data,\r\n paneModel: this.model,\r\n leftOffset,\r\n })\r\n const lastBarToRender = getVisibleBarToRenderIndex({\r\n quote: this.data,\r\n paneModel: this.model,\r\n leftOffset,\r\n chartWidth,\r\n })\r\n\r\n const areNoBarsVisible = getAreNoBarsVisible(firstBarToRender, lastBarToRender)\r\n if (areNoBarsVisible) return\r\n\r\n const text = (label: string, price: number, calculatedX: number) => {\r\n new Text(\r\n {\r\n x: calculatedX,\r\n y: this.fy(price) - 13,\r\n font: { size: 8, weight: '900' },\r\n textBaseline: TextBaseline.top,\r\n fillStyle: this.attrs.color,\r\n text: `${label} (${round({ data: this.data, num: price })})`,\r\n },\r\n this.model\r\n ).render(context)\r\n }\r\n\r\n const line = (fromX: number, toX: number, y: number) => {\r\n context.moveTo(fromX, this.fy(y))\r\n context.lineTo(toX, this.fy(y))\r\n }\r\n\r\n let startIndex = -1\r\n let endIndex = -1\r\n const isStock = this.data.instrument === Instrument.Stock\r\n const periodType = this.getPeriodType()\r\n let currentDate = new Date()\r\n let lastDate: Date | undefined\r\n\r\n context.translate(0.5, 0.5)\r\n context.set('strokeStyle', this.attrs.color)\r\n\r\n for (let index = firstBarToRender.index; index <= lastBarToRender.index; index++) {\r\n currentDate = Utils.dateFromUnixTimestamp(this.data.date[index])\r\n\r\n // check if new calculation/render is necessary\r\n switch (periodType) {\r\n case PivotPeriod.day: // only if it is a new day\r\n if (currentDate.getDate() === lastDate?.getDate()) {\r\n continue\r\n }\r\n break\r\n case PivotPeriod.week: // only if it is a new week\r\n if (lastDate && dateFns.isSameWeek(lastDate, currentDate, { weekStartsOn: 1 })) {\r\n continue\r\n }\r\n break\r\n case PivotPeriod.month: // only if it is a new month\r\n if (currentDate.getMonth() === lastDate?.getMonth()) {\r\n continue\r\n }\r\n break\r\n case PivotPeriod.year: // only if it is a new year\r\n if (currentDate.getFullYear() === lastDate?.getFullYear()) {\r\n continue\r\n }\r\n break\r\n }\r\n lastDate = currentDate\r\n\r\n // Find start/end indexes for the entire previous period\r\n switch (periodType) {\r\n case PivotPeriod.day:\r\n if (index > 0) {\r\n let previousTradingDay = new Date()\r\n for (let i = index - 1; i >= 0; i--) {\r\n previousTradingDay = Utils.dateFromUnixTimestamp(this.data.date[i])\r\n if (previousTradingDay.getDate() !== currentDate.getDate()) break\r\n }\r\n previousTradingDay.setHours(0, 0, 0, 0)\r\n const previousNYMidnightTimestamp = Utils.convertLocalToNyTime(previousTradingDay, false).getTime() / 1000\r\n const currentMidnight = new Date(currentDate)\r\n currentMidnight.setHours(0, 0, 0, 0)\r\n const currentNYMidnightTimestamp = Utils.convertLocalToNyTime(currentMidnight, false).getTime() / 1000\r\n\r\n startIndex = this.data.date.findIndex((ts) => ts >= previousNYMidnightTimestamp)\r\n endIndex = this.data.date.findIndex((ts) => ts > currentNYMidnightTimestamp)\r\n\r\n // check if we have data for entire day\r\n if (startIndex !== endIndex) {\r\n const diff = this.data.date[endIndex] - this.data.date[startIndex]\r\n const isNonStockFullDay = !isStock && diff >= DAY_SECONDS\r\n const isStockFullDay = isStock && previousTradingDay.getDate() !== currentDate.getDate()\r\n if (!isNonStockFullDay && !isStockFullDay) {\r\n startIndex = endIndex = Number.MIN_SAFE_INTEGER\r\n }\r\n }\r\n }\r\n break\r\n case PivotPeriod.week:\r\n const firstDayCurrentWeek = dateFns.startOfWeek(currentDate, { weekStartsOn: 1 })\r\n const firstDayCurrentWeekTimestamp = Utils.convertLocalToNyTime(firstDayCurrentWeek, false).getTime() / 1000\r\n const firstDayPreviousWeek = dateFns.sub(firstDayCurrentWeek, { weeks: 1 })\r\n const firstDayPreviousWeekTimestamp = Utils.convertLocalToNyTime(firstDayPreviousWeek, false).getTime() / 1000\r\n\r\n startIndex = this.data.date.findIndex((ts) => ts >= firstDayPreviousWeekTimestamp)\r\n endIndex = this.data.date.findIndex((ts) => ts > firstDayCurrentWeekTimestamp)\r\n\r\n if (!this.getIsEnoughData(startIndex, endIndex, periodType)) {\r\n startIndex = endIndex = Number.MIN_SAFE_INTEGER\r\n }\r\n break\r\n case PivotPeriod.month:\r\n const firstDayCurrentMonth = dateFns.startOfMonth(currentDate)\r\n const firstDayCurrentMonthTimestamp = Utils.convertLocalToNyTime(firstDayCurrentMonth, false).getTime() / 1000\r\n const firstDayPreviousMonth = dateFns.sub(firstDayCurrentMonth, { months: 1 })\r\n const firstDayPreviousMonthTimestamp =\r\n Utils.convertLocalToNyTime(firstDayPreviousMonth, false).getTime() / 1000\r\n\r\n startIndex = this.data.date.findIndex((ts) => ts >= firstDayPreviousMonthTimestamp)\r\n endIndex = this.data.date.findIndex((ts) => ts > firstDayCurrentMonthTimestamp)\r\n\r\n if (!this.getIsEnoughData(startIndex, endIndex, periodType)) {\r\n startIndex = endIndex = Number.MIN_SAFE_INTEGER\r\n }\r\n break\r\n case PivotPeriod.year:\r\n const firstDayCurrentYear = dateFns.startOfYear(currentDate)\r\n const firstDayCurrentYearTimestamp = Utils.convertLocalToNyTime(firstDayCurrentYear, false).getTime() / 1000\r\n const firstDayPreviousYear = dateFns.sub(firstDayCurrentYear, { years: 1 })\r\n const firstDayPreviousYearTimestamp = Utils.convertLocalToNyTime(firstDayPreviousYear, false).getTime() / 1000\r\n\r\n startIndex = this.data.date.findIndex((ts) => ts >= firstDayPreviousYearTimestamp)\r\n endIndex = this.data.date.findIndex((ts) => ts > firstDayCurrentYearTimestamp)\r\n\r\n if (!this.getIsEnoughData(startIndex, endIndex, periodType)) {\r\n startIndex = endIndex = Number.MIN_SAFE_INTEGER\r\n }\r\n break\r\n }\r\n\r\n // calculate pivot point if it was found\r\n if (!(startIndex !== -1 && endIndex !== -1 && startIndex < endIndex)) continue\r\n\r\n let pivot, sup1, sup2, sup3, res1, res2, res3\r\n const previousHigh = Math.max(...this.data.high.slice(startIndex, endIndex))\r\n const previousLow = Math.min(...this.data.low.slice(startIndex, endIndex))\r\n const previousClose = this.data.close[endIndex - 1] // endIndex is the beginning of the next period\r\n\r\n if (this.attrs.calculationType === 'standard') {\r\n pivot = (previousHigh + previousLow + previousClose) / 3\r\n sup1 = 2 * pivot - previousHigh\r\n sup2 = pivot - (previousHigh - previousLow)\r\n sup3 = previousLow - 2 * (previousHigh - pivot)\r\n res1 = 2 * pivot - previousLow\r\n res2 = pivot + (previousHigh - previousLow)\r\n res3 = previousHigh + 2 * (pivot - previousLow)\r\n } else {\r\n pivot = (previousHigh + previousLow + previousClose) / 3\r\n sup1 = pivot - (previousHigh - previousLow) * FIB_LVL_1\r\n sup2 = pivot - (previousHigh - previousLow) * FIB_LVL_2\r\n sup3 = pivot - (previousHigh - previousLow)\r\n res1 = pivot + (previousHigh - previousLow) * FIB_LVL_1\r\n res2 = pivot + (previousHigh - previousLow) * FIB_LVL_2\r\n res3 = pivot + (previousHigh - previousLow)\r\n }\r\n\r\n const pivotPoint: PivotPointType = { pivot, sup1, sup2, sup3, res1, res2, res3 }\r\n\r\n // prepare x coordinates for lines rendering\r\n let fromX = this.fx(index)\r\n let toX = this.fx(index)\r\n switch (periodType) {\r\n case PivotPeriod.day:\r\n const interval = this.data.interval\r\n const currentX = fromX\r\n\r\n const toDate = new Date(currentDate)\r\n toDate.setHours(16, 0, 0, 0)\r\n if (this.data.aftermarket && interval <= 5) toDate.setHours(18, 30, 0, 0)\r\n if (interval <= 15 && !isStock) toDate.setHours(23, 59, 59, 99)\r\n const toTimestamp = toDate.getTime() / 1000\r\n const toDiffMinutes = (toTimestamp - currentDate.getTime() / 1000) / 60\r\n const toBars = toDiffMinutes / interval\r\n toX = Math.min(currentX + toBars * barWidth, -leftOffset + width)\r\n\r\n const fromDate = new Date(currentDate)\r\n fromDate.setHours(9, 30, 0, 0)\r\n if (this.data.premarket && interval <= 5) fromDate.setHours(7, 0, 0, 0)\r\n if (interval <= 15 && !isStock) fromDate.setHours(0, 0, 0, 0)\r\n const fromTimestamp = fromDate.getTime() / 1000\r\n const fromDiffMinutes = (fromTimestamp - currentDate.getTime() / 1000) / 60\r\n const fromBars = fromDiffMinutes / interval\r\n fromX = currentX + fromBars * barWidth\r\n break\r\n\r\n case PivotPeriod.week:\r\n for (let i = index + 1; i <= lastBarToRender.index; i++) {\r\n const nextDate = Utils.dateFromUnixTimestamp(this.data.date[i])\r\n if (!dateFns.isSameWeek(currentDate, nextDate, { weekStartsOn: 1 })) {\r\n toX = this.fx(i)\r\n break\r\n }\r\n }\r\n for (let i = index - 1; i >= firstBarToRender.index; i--) {\r\n const nextDate = Utils.dateFromUnixTimestamp(this.data.date[i])\r\n if (!dateFns.isSameWeek(currentDate, nextDate, { weekStartsOn: 1 })) {\r\n fromX = this.fx(i + 1) // because we need start from current week\r\n break\r\n }\r\n }\r\n\r\n if (fromX === toX) {\r\n // we need line to imaginary end of the week\r\n const barsPerDay = Math.ceil((this.data.drawMinutesPerDay ?? MINUTES_PER_DAY) / this.data.interval)\r\n toX += (isStock ? 5 : 7) * barsPerDay * barWidth\r\n }\r\n break\r\n\r\n case PivotPeriod.month:\r\n for (let i = index + 1; i <= lastBarToRender.index; i++) {\r\n const nextDate = Utils.dateFromUnixTimestamp(this.data.date[i])\r\n if (nextDate.getMonth() !== currentDate.getMonth()) {\r\n toX = this.fx(i)\r\n break\r\n }\r\n }\r\n for (let i = index - 1; i >= firstBarToRender.index; i--) {\r\n const nextDate = Utils.dateFromUnixTimestamp(this.data.date[i])\r\n if (nextDate.getMonth() !== currentDate.getMonth()) {\r\n fromX = this.fx(i + 1) // because we need start from current month\r\n break\r\n }\r\n }\r\n\r\n if (fromX === toX) {\r\n // we need line to imaginary end of the month\r\n const barsPerDay = this.data.isIntraday\r\n ? Math.ceil((this.data.drawMinutesPerDay ?? MINUTES_PER_DAY) / this.data.interval)\r\n : 1\r\n toX += (isStock ? 20 : 30) * barsPerDay * barWidth\r\n }\r\n break\r\n default:\r\n for (let i = index + 1; i <= lastBarToRender.index; i++) {\r\n const nextDate = Utils.dateFromUnixTimestamp(this.data.date[i])\r\n if (nextDate.getFullYear() !== currentDate.getFullYear()) {\r\n toX = this.fx(i)\r\n break\r\n }\r\n }\r\n for (let i = index - 1; i >= firstBarToRender.index; i--) {\r\n const nextDate = Utils.dateFromUnixTimestamp(this.data.date[i])\r\n if (nextDate.getFullYear() !== currentDate.getFullYear()) {\r\n fromX = this.fx(i + 1) // because we need start from current year\r\n break\r\n }\r\n }\r\n\r\n if (fromX === toX) {\r\n // we need line to imaginary end of the year\r\n toX += (this.data.timeframe === TIMEFRAME.w ? 49 : 12) * barWidth\r\n }\r\n break\r\n }\r\n fromX = Math.max(fromX, -leftOffset)\r\n\r\n // render pivot line\r\n context.beginPath()\r\n line(fromX, toX, pivotPoint.pivot)\r\n context.stroke()\r\n\r\n // render resistance and support lines\r\n context.save()\r\n context.setLineDash([3, 3])\r\n context.beginPath()\r\n line(fromX, toX, pivotPoint.res1)\r\n line(fromX, toX, pivotPoint.res2)\r\n line(fromX, toX, pivotPoint.res3)\r\n line(fromX, toX, pivotPoint.sup1)\r\n line(fromX, toX, pivotPoint.sup2)\r\n line(fromX, toX, pivotPoint.sup3)\r\n context.stroke()\r\n context.restore()\r\n\r\n // render labels if there is enough space\r\n if (toX - fromX >= 48) {\r\n text('P', pivotPoint.pivot, fromX)\r\n text('R1', pivotPoint.res1, fromX)\r\n text('R2', pivotPoint.res2, fromX)\r\n text('R3', pivotPoint.res3, fromX)\r\n text('S1', pivotPoint.sup1, fromX)\r\n text('S2', pivotPoint.sup2, fromX)\r\n text('S3', pivotPoint.sup3, fromX)\r\n }\r\n }\r\n\r\n context.translate(-0.5, -0.5)\r\n }\r\n\r\n getModalConfig() {\r\n const options = {\r\n calculationType: {\r\n type: 'select',\r\n label: 'Calculation Type',\r\n name: 'calculationType',\r\n value: this.attrs.calculationType ?? DEFAULT_PARAMETERS.CalculationType,\r\n required: true,\r\n items: [\r\n {\r\n value: 'standard',\r\n label: 'Standard',\r\n },\r\n {\r\n value: 'fibonacci',\r\n label: 'Fibonacci',\r\n },\r\n ],\r\n },\r\n color: {\r\n type: 'color',\r\n label: 'Color',\r\n name: 'color',\r\n value: this.attrs.color ?? this.getFreeColor(),\r\n },\r\n }\r\n\r\n return {\r\n title: PPConfig.label,\r\n inputs: PPConfig.inputsOrder.map((item) => options[item]),\r\n inputsErrorMessages: {},\r\n }\r\n }\r\n\r\n getIsValid(key: string) {\r\n switch (key) {\r\n case 'calculationType':\r\n case 'color':\r\n return !!this.attrs[key]\r\n default:\r\n return false\r\n }\r\n }\r\n\r\n toString() {\r\n return `${PPConfig.shortLabel} (${Calculation[this.attrs.calculationType]})`\r\n }\r\n}\r\n\r\nPivotPoints.prototype.defaults = {\r\n calculationType: DEFAULT_PARAMETERS.CalculationType,\r\n color: DEFAULT_PARAMETERS.Color,\r\n}\r\n\r\nexport default PivotPoints\r\n","import { OverlayType } from '../../constants/common'\r\nimport BaseConfig from './overlayBaseConfig'\r\n\r\nexport type Options = {\r\n step: number\r\n maxStep: number\r\n}\r\n\r\nexport interface Attrs extends Options {\r\n period: string\r\n risingColor: string\r\n fallingColor: string\r\n}\r\n\r\nexport class SARConfig extends BaseConfig {\r\n static type = OverlayType.Sar\r\n static abbreviation = 'sar'\r\n static label = 'Parabolic SAR'\r\n static shortLabel = 'SAR'\r\n static optionsOrder = ['step', 'maxStep'] as const\r\n static optionsLabels = {\r\n step: 'Step',\r\n maxStep: 'Maximum Step',\r\n }\r\n\r\n static inputsOrder = [...this.optionsOrder, 'risingColor', 'fallingColor'] as Array>\r\n static inputsLabels = { ...this.optionsLabels, risingColor: 'Rising Color', fallingColor: 'Falling Color' }\r\n}\r\n","import { Attrs, SARConfig } from './configs/sar'\r\nimport Overlay from './overlay'\r\n\r\nclass SAR extends Overlay {\r\n static config = SARConfig\r\n\r\n static getNumOfBarsBuffer() {\r\n return 0\r\n }\r\n\r\n set(obj: Partial) {\r\n super.set(obj)\r\n if (typeof this.attrs.period === 'string' && (this.attrs.step === undefined || this.attrs.maxStep === undefined)) {\r\n const [step = 0, maxStep = 0] = this.attrs.period.split(',').map((x) => parseFloat(x))\r\n this.attrs.step = step\r\n this.attrs.maxStep = maxStep\r\n }\r\n this.trigger('change')\r\n return this\r\n }\r\n\r\n renderContent(context: CanvasRenderingContext2D) {\r\n super.renderContent()\r\n const data = this.data\r\n const deltaHigh = data.high[1] - data.high[0]\r\n const deltaLow = data.low[0] - data.low[1]\r\n const pdm = deltaHigh > 0 && deltaHigh > deltaLow ? deltaHigh : 0\r\n const mdm = deltaLow > 0 && deltaLow > deltaHigh ? deltaLow : 0\r\n let isLong = pdm >= mdm\r\n\r\n let sar = isLong ? data.low[0] : data.high[0]\r\n let ep = isLong ? data.high[1] : data.low[1]\r\n let newHigh = data.high[0]\r\n let newLow = data.low[0]\r\n let af = this.attrs.step\r\n\r\n for (let i = 1, end = data.close.length, asc = end >= 1; asc ? i < end : i > end; asc ? i++ : i--) {\r\n let sarToDraw\r\n const prevHigh = newHigh\r\n const prevLow = newLow\r\n newHigh = data.high[i]\r\n newLow = data.low[i]\r\n\r\n if (isLong) {\r\n if (newLow <= sar) {\r\n isLong = false\r\n sar = ep\r\n\r\n if (sar < prevHigh) {\r\n sar = prevHigh\r\n }\r\n if (sar < newHigh) {\r\n sar = newHigh\r\n }\r\n\r\n sarToDraw = sar\r\n\r\n af = this.attrs.step\r\n ep = newLow\r\n\r\n sar = sar + af * (ep - sar)\r\n\r\n if (sar < prevHigh) {\r\n sar = prevHigh\r\n }\r\n if (sar < newHigh) {\r\n sar = newHigh\r\n }\r\n } else {\r\n sarToDraw = sar\r\n\r\n if (newHigh > ep) {\r\n ep = newHigh\r\n af += this.attrs.step\r\n if (af > this.attrs.maxStep) {\r\n af = this.attrs.maxStep\r\n }\r\n }\r\n\r\n sar = sar + af * (ep - sar)\r\n\r\n if (sar > prevLow) {\r\n sar = prevLow\r\n }\r\n if (sar > newLow) {\r\n sar = newLow\r\n }\r\n }\r\n } else {\r\n if (newHigh >= sar) {\r\n isLong = true\r\n sar = ep\r\n\r\n if (sar > prevLow) {\r\n sar = prevLow\r\n }\r\n if (sar > newLow) {\r\n sar = newLow\r\n }\r\n\r\n sarToDraw = sar\r\n\r\n af = this.attrs.step\r\n ep = newHigh\r\n\r\n sar = sar + af * (ep - sar)\r\n\r\n if (sar > prevLow) {\r\n sar = prevLow\r\n }\r\n if (sar > newLow) {\r\n sar = newLow\r\n }\r\n } else {\r\n sarToDraw = sar\r\n\r\n if (newLow < ep) {\r\n ep = newLow\r\n af += this.attrs.step\r\n if (af > this.attrs.maxStep) {\r\n af = this.attrs.maxStep\r\n }\r\n }\r\n\r\n sar = sar + af * (ep - sar)\r\n\r\n if (sar < prevHigh) {\r\n sar = prevHigh\r\n }\r\n if (sar < newHigh) {\r\n sar = newHigh\r\n }\r\n }\r\n }\r\n\r\n const x = Math.round(this.fx(i) - 1.5)\r\n const y = Math.round(this.fy(sarToDraw) - 1.5)\r\n context.set('fillStyle', isLong ? this.attrs.risingColor : this.attrs.fallingColor)\r\n context.fillRect(x, y, 3, 3)\r\n }\r\n }\r\n\r\n getModalConfig() {\r\n const options = {\r\n step: {\r\n type: 'number',\r\n step: 0.01,\r\n min: 0.01,\r\n max: 999,\r\n label: 'Step',\r\n name: 'step',\r\n value: this.attrs.step ?? 0.02,\r\n required: true,\r\n },\r\n maxStep: {\r\n type: 'number',\r\n step: 0.01,\r\n min: 0.01,\r\n max: 999,\r\n label: 'Maximum Step',\r\n name: 'maxStep',\r\n value: this.attrs.maxStep ?? 0.2,\r\n required: true,\r\n },\r\n risingColor: {\r\n type: 'color',\r\n label: 'Rising Color',\r\n name: 'risingColor',\r\n value: this.attrs.risingColor ?? this.getFreeColor(),\r\n customizable: false,\r\n },\r\n fallingColor: {\r\n type: 'color',\r\n label: 'Falling Color',\r\n name: 'fallingColor',\r\n value: this.attrs.fallingColor ?? this.getFreeColor(),\r\n customizable: false,\r\n },\r\n }\r\n\r\n return {\r\n title: SARConfig.label,\r\n inputs: SARConfig.inputsOrder.map((item) => options[item]),\r\n inputsErrorMessages: {\r\n step: `${options.step.label} must be a number between ${options.step.min} and ${options.step.max}`,\r\n maxStep: `${options.maxStep.label} must be a number between ${options.maxStep.min} and ${options.maxStep.max}`,\r\n },\r\n }\r\n }\r\n\r\n getIsValid(key: string) {\r\n switch (key) {\r\n case 'step':\r\n case 'maxStep': {\r\n return this.getIsNumberInputValid({ key, integerOnly: false })\r\n }\r\n case 'risingColor':\r\n case 'fallingColor':\r\n // Some users have wrong colors which break the form validation\r\n return true\r\n default:\r\n return false\r\n }\r\n }\r\n\r\n getLabelColor() {\r\n return this.attrs.risingColor\r\n }\r\n}\r\n\r\nSAR.prototype.defaults = {\r\n risingColor: '#69c1ea',\r\n fallingColor: '#d386df',\r\n}\r\n\r\nexport default SAR\r\n","import { OverlayType } from '../../constants/common'\r\nimport BaseConfig from './overlayBaseConfig'\r\n\r\nexport type Options = { period: number }\r\n\r\nexport interface Attrs extends Options {\r\n color: string\r\n}\r\n\r\nexport class SMAConfig extends BaseConfig {\r\n static type = OverlayType.Sma\r\n static abbreviation = 'sma'\r\n static label = 'Simple Moving Average'\r\n static shortLabel = 'SMA'\r\n static optionsOrder = ['period'] as const\r\n static optionsLabels = { period: 'Period' }\r\n static inputsOrder = ['period', 'color'] as Array\r\n static inputsLabels = { period: 'Period', color: 'Color' }\r\n static calculatedValuesOrder = ['sma'] as const\r\n static calculatedValuesLabels = { sma: 'SMA' }\r\n static defaultCalculatedValueOption = this.calculatedValuesOrder[0]\r\n}\r\n","import { Options, SMAConfig } from '../overlays/configs/sma'\r\nimport { MainCalculation, OnValueCalculated } from './main'\r\n\r\ntype DefaultCalculatedValuesType = {\r\n sma: number[]\r\n}\r\n\r\nexport class SMACalculation extends MainCalculation {\r\n static config = SMAConfig\r\n declare options: Options\r\n\r\n calculate(onValueCalculated?: OnValueCalculated) {\r\n const { close } = this.quote\r\n const lastIndex = close.length - 1\r\n this._calculatedValues = this.getDefaultCalculatedValues()\r\n\r\n let sum = 0\r\n for (let i = 0; i < this.options.period; i++) {\r\n sum += close[i]\r\n }\r\n for (let i = this.options.period; i <= lastIndex; i++) {\r\n sum = sum - close[i - this.options.period] + close[i]\r\n this.calculatedValues.sma[i] = sum / this.options.period\r\n\r\n if (onValueCalculated?.(this.calculatedValues, i) === false) {\r\n break\r\n }\r\n }\r\n }\r\n}\r\n","import { ChartConfigChartPaneElement, RequireByKey } from '../../types/shared'\r\nimport { SMACalculation } from '../indicator-calculation/sma'\r\nimport { Attrs, SMAConfig } from './configs/sma'\r\nimport Overlay from './overlay'\r\n\r\nclass SMA extends Overlay {\r\n static config = SMAConfig\r\n\r\n static getNumOfBarsBuffer(chartConfig: RequireByKey) {\r\n const numOfBarsBuffer = Overlay.getNumOfBarsBuffer(chartConfig)\r\n return numOfBarsBuffer + 1 // +1 offsets rendering so it doesn't start on first bar which doesn't look OK in SSR rendered charts\r\n }\r\n\r\n set(obj: Partial) {\r\n super.set(obj)\r\n const { period } = obj\r\n if (typeof period === 'string') {\r\n this.attrs.period = parseInt(period, 10)\r\n this.trigger('change')\r\n }\r\n return this\r\n }\r\n\r\n renderContent(context: CanvasRenderingContext2D) {\r\n super.renderContent()\r\n const { leftOffset, width } = this.model.chart()\r\n const period = Math.min(this.attrs.period, this.data.close.length - 1)\r\n context.beginPath()\r\n context.translate(0.5, 0.5)\r\n context.set('lineWidth', 1)\r\n context.set('strokeStyle', this.attrs.color)\r\n\r\n const smaCalculation = new SMACalculation({\r\n quote: this.data,\r\n options: { period },\r\n })\r\n\r\n smaCalculation.calculate(({ sma }, dataIndex) => {\r\n const x = this.fx(dataIndex)\r\n if (this.fx(dataIndex + 1) + leftOffset < 0) {\r\n return\r\n }\r\n if (this.fx(dataIndex - 1) + leftOffset > width) {\r\n return false\r\n }\r\n context.lineTo(x, Math.round(this.fy(sma[dataIndex])))\r\n })\r\n\r\n context.translate(-0.5, -0.5)\r\n context.stroke()\r\n }\r\n\r\n getModalConfig() {\r\n const options = {\r\n period: {\r\n type: 'number',\r\n label: 'Period',\r\n name: 'period',\r\n value: this.attrs.period ?? 5,\r\n required: true,\r\n min: 1,\r\n max: 999999,\r\n },\r\n color: {\r\n type: 'color',\r\n label: 'Color',\r\n name: 'color',\r\n value: this.attrs.color ?? this.getFreeColor(),\r\n },\r\n }\r\n\r\n return {\r\n title: this.config.label,\r\n inputs: this.config.inputsOrder.map((item) => options[item as keyof Attrs]),\r\n inputsErrorMessages: {\r\n period: `${options.period.label} must be a whole number between ${options.period.min} and ${options.period.max}`,\r\n },\r\n }\r\n }\r\n\r\n getIsValid(key: string) {\r\n switch (key) {\r\n case 'period':\r\n return this.getIsNumberInputValid({ key })\r\n case 'color':\r\n return !!this.attrs[key] // use real color validation, we got isValidHexColor but it might be also RGBA\r\n default:\r\n return false\r\n }\r\n }\r\n}\r\n\r\nSMA.prototype.defaults = { color: '#ffa75f' }\r\n\r\nexport default SMA\r\n","import { OverlayType } from '../../constants/common'\r\nimport { SMAConfig } from './sma'\r\n\r\nexport class SMA2Config extends SMAConfig {\r\n static type = OverlayType.Sma2\r\n}\r\n","import { SMA2Config } from './configs/sma2'\r\nimport SMA from './sma'\r\n\r\nclass SMA2 extends SMA {\r\n static config = SMA2Config\r\n}\r\n\r\nSMA2.prototype.defaults = { color: '#ff6400' }\r\n\r\nexport default SMA2\r\n","import { OverlayType } from '../../constants/common'\r\nimport BaseConfig from './overlayBaseConfig'\r\n\r\nexport type Options = {\r\n period: number\r\n multiplier: number\r\n}\r\n\r\nexport interface Attrs extends Options {\r\n uptrendColor: string\r\n downtrendColor: string\r\n}\r\n\r\nexport class StrConfig extends BaseConfig {\r\n static type = OverlayType.Str\r\n static abbreviation = 'str'\r\n static label = 'Supertrend'\r\n static shortLabel = 'Supertrend'\r\n static optionsOrder = ['period', 'multiplier'] as const\r\n static optionsLabels = { period: 'Period', multiplier: 'Period' }\r\n static inputsOrder = [...this.optionsOrder, 'uptrendColor', 'downtrendColor'] as Array\r\n static inputsLabels = {\r\n ...this.optionsLabels,\r\n uptrendColor: 'Uptrend Color',\r\n downtrendColor: 'Downtrend Color',\r\n }\r\n}\r\n","import { ChartConfigChartPaneElement, RequireByKey } from '../../types/shared'\r\nimport AverageTrueRange from '../helpers/atr'\r\nimport { Attrs, StrConfig } from './configs/str'\r\nimport Overlay from './overlay'\r\n\r\nconst DEFAULT_PARAMETERS = {\r\n Period: 7,\r\n Multiplier: 3.0,\r\n}\r\n\r\nconst COLORS = {\r\n Uptrend: '#00a000',\r\n Downtrend: '#c80000',\r\n}\r\n\r\nfunction parsePeriod(periodStr: string) {\r\n const values = periodStr.split(',')\r\n const period = parseInt(values[0]) || DEFAULT_PARAMETERS.Period\r\n const multiplier = parseFloat(values[1]) || DEFAULT_PARAMETERS.Multiplier\r\n\r\n return [period, multiplier]\r\n}\r\n\r\nclass Supertrend extends Overlay {\r\n static config = StrConfig\r\n\r\n static getNumOfBarsBuffer({ period }: RequireByKey) {\r\n const [periodInt] = parsePeriod(period)\r\n return periodInt + 1\r\n }\r\n\r\n set(obj: Partial) {\r\n super.set(obj)\r\n const { period } = obj\r\n if (typeof period === 'string') {\r\n const [periodInt, multiplier] = parsePeriod(period)\r\n this.attrs.period = periodInt\r\n this.attrs.multiplier = multiplier\r\n this.trigger('change')\r\n }\r\n return this\r\n }\r\n\r\n renderContent(context: CanvasRenderingContext2D) {\r\n super.renderContent()\r\n const { leftOffset, width } = this.model.chart()\r\n const { period, multiplier } = this.attrs\r\n const { high, low, close } = this.data\r\n const atr = new AverageTrueRange(period)\r\n const finalUpperBand: number[] = []\r\n const finalLowerBand: number[] = []\r\n const supertrend: boolean[] = []\r\n let firstBarToRender\r\n let lastBarToRender = 0\r\n\r\n context.translate(0.5, 0.5)\r\n context.beginPath()\r\n context.set('lineWidth', 1)\r\n context.set('strokeStyle', this.attrs.uptrendColor)\r\n for (let i = 1; i < close.length; i++) {\r\n atr.add(high[i], low[i], close[i - 1])\r\n\r\n // compute bands\r\n const avg = (high[i] + low[i]) / 2\r\n const upperBand = avg + multiplier * atr.value\r\n const lowerBand = avg - multiplier * atr.value\r\n\r\n finalUpperBand[i] = upperBand\r\n finalLowerBand[i] = lowerBand\r\n\r\n // identify supertrend\r\n if (close[i] > finalUpperBand[i - 1]) {\r\n supertrend[i] = true\r\n } else if (close[i] < finalLowerBand[i - 1]) {\r\n supertrend[i] = false\r\n } else {\r\n supertrend[i] = supertrend[i - 1]\r\n }\r\n\r\n // adjust bands\r\n if (supertrend[i] && finalLowerBand[i] < finalLowerBand[i - 1]) {\r\n finalLowerBand[i] = finalLowerBand[i - 1]\r\n }\r\n if (!supertrend[i] && finalUpperBand[i] > finalUpperBand[i - 1]) {\r\n finalUpperBand[i] = finalUpperBand[i - 1]\r\n }\r\n\r\n const x = this.fx(i)\r\n if (i < period || x + leftOffset < 0) {\r\n continue\r\n }\r\n if (this.fx(i - 1) + leftOffset > width) {\r\n break\r\n }\r\n if (firstBarToRender === undefined) firstBarToRender = i\r\n\r\n if (supertrend[i] && !supertrend[i - 1]) {\r\n // buy\r\n context.moveTo(this.fx(i - 1), Math.round(this.fy(finalUpperBand[i - 1])))\r\n context.lineTo(x, Math.round(this.fy(finalLowerBand[i])))\r\n } else if (supertrend[i]) {\r\n // keep buying\r\n context.lineTo(x, Math.round(this.fy(finalLowerBand[i])))\r\n } else {\r\n // keep selling\r\n context.moveTo(x, Math.round(this.fy(finalLowerBand[i])))\r\n }\r\n lastBarToRender = i\r\n }\r\n context.stroke()\r\n\r\n if (firstBarToRender === undefined) {\r\n context.translate(-0.5, -0.5)\r\n return\r\n }\r\n\r\n context.beginPath()\r\n context.set('strokeStyle', this.attrs.downtrendColor)\r\n for (let i = firstBarToRender; i <= lastBarToRender; i++) {\r\n const x = this.fx(i)\r\n if (!supertrend[i] && supertrend[i - 1]) {\r\n // sell\r\n context.moveTo(this.fx(i - 1), Math.round(this.fy(finalLowerBand[i - 1])))\r\n context.lineTo(x, Math.round(this.fy(finalUpperBand[i])))\r\n } else if (!supertrend[i]) {\r\n // keep selling\r\n context.lineTo(x, Math.round(this.fy(finalUpperBand[i])))\r\n } else {\r\n // keep buying\r\n context.moveTo(x, Math.round(this.fy(finalUpperBand[i])))\r\n }\r\n }\r\n context.stroke()\r\n\r\n context.translate(-0.5, -0.5)\r\n }\r\n\r\n getModalConfig() {\r\n const options = {\r\n period: {\r\n type: 'number',\r\n label: 'Period',\r\n name: 'period',\r\n value: this.attrs.period ?? DEFAULT_PARAMETERS.Period,\r\n required: true,\r\n min: 1,\r\n max: 999999,\r\n },\r\n multiplier: {\r\n type: 'number',\r\n label: 'Period',\r\n name: 'multiplier',\r\n value: this.attrs.multiplier ?? DEFAULT_PARAMETERS.Multiplier,\r\n required: true,\r\n step: 0.1,\r\n min: 0.0,\r\n max: 999,\r\n },\r\n uptrendColor: {\r\n type: 'color',\r\n label: 'Uptrend Color',\r\n name: 'uptrendColor',\r\n value: this.attrs.uptrendColor ?? this.getFreeColor(),\r\n },\r\n downtrendColor: {\r\n type: 'color',\r\n label: 'Downtrend Color',\r\n name: 'downtrendColor',\r\n value: this.attrs.downtrendColor ?? this.getFreeColor(),\r\n },\r\n }\r\n\r\n return {\r\n title: StrConfig.label,\r\n inputs: StrConfig.inputsOrder.map((item) => options[item]),\r\n inputsErrorMessages: {\r\n period: `${options.period.label} must be a whole number between ${options.period.min} and ${options.period.max}`,\r\n multiplier: `${options.multiplier.label} must be a number between ${options.multiplier.min} and ${options.multiplier.max}`,\r\n },\r\n }\r\n }\r\n\r\n getIsValid(key: string) {\r\n switch (key) {\r\n case 'period':\r\n return this.getIsNumberInputValid({ key })\r\n case 'multiplier':\r\n return this.getIsNumberInputValid({ key, integerOnly: false })\r\n case 'uptrendColor':\r\n case 'downtrendColor':\r\n return true\r\n default:\r\n return false\r\n }\r\n }\r\n\r\n getLabelColor(): string {\r\n return this.attrs.uptrendColor\r\n }\r\n}\r\n\r\nSupertrend.prototype.defaults = {\r\n uptrendColor: COLORS.Uptrend,\r\n downtrendColor: COLORS.Downtrend,\r\n}\r\n\r\nexport default Supertrend\r\n","import { OverlayType } from '../../constants/common'\r\nimport BaseConfig from './overlayBaseConfig'\r\n\r\nexport type Options = {\r\n period: number | string\r\n}\r\n\r\nexport interface Attrs extends Options {\r\n opacity: number\r\n upColor?: string\r\n downColor?: string\r\n}\r\n\r\nexport class VPConfig extends BaseConfig {\r\n static type = OverlayType.Vp\r\n static abbreviation = 'vp'\r\n static label = 'Volume Profile'\r\n static shortLabel = 'VP'\r\n static optionsOrder = ['period'] as const\r\n static optionsLabels = { period: 'Period' }\r\n static inputsOrder = ['period', 'opacity', 'upColor', 'downColor'] as Array\r\n\r\n static inputsLabels = {\r\n period: 'Zones',\r\n opacity: 'Opacity',\r\n upColor: 'Up Color',\r\n downColor: 'Down Color',\r\n }\r\n}\r\n","import * as d3 from 'd3'\r\n\r\nimport { ChartConfigChartPaneElement, RequireByKey } from '../../types/shared'\r\nimport Chart from '../models/chart'\r\nimport utils from '../utils'\r\nimport { convertColorToHEX, getHEXWithSpecificAplha } from '../utils/colors'\r\nimport { getAreNoBarsVisible, getVisibleBarToRenderIndex } from '../utils/draw_in_visible_area'\r\nimport { getParsedIntegersFromPeriodString } from '../utils/helpers'\r\nimport { Attrs, VPConfig } from './configs/vp'\r\nimport Overlay from './overlay'\r\n\r\nconst VP_COLORS = {\r\n UP: '#00FF00',\r\n DOWN: '#FF0000',\r\n}\r\n\r\nconst DEFAULT_PARAMETERS = {\r\n Period: 20,\r\n Opacity: 0.3,\r\n}\r\n\r\nfunction applyOpacityToColor(color: string, opacity: number) {\r\n return getHEXWithSpecificAplha(convertColorToHEX(color), opacity)\r\n}\r\n\r\nfunction getColorsWithAppliedOpacity(attrs: Attrs) {\r\n return [\r\n applyOpacityToColor(attrs.upColor ?? VP_COLORS.UP, attrs.opacity),\r\n applyOpacityToColor(attrs.downColor ?? VP_COLORS.DOWN, attrs.opacity),\r\n ]\r\n}\r\n\r\n// Only time when we want value to be able to equal start of segment is first segment,\r\n// because start of next segment is equal to end of previous and value would match two segments\r\nfunction isInSegment(val: number, start: number, end: number, notEqualStart: boolean) {\r\n return (notEqualStart ? val > start : val >= start) && val <= end\r\n}\r\n\r\nfunction parsePeriod(periodStr: string) {\r\n const values = periodStr.split(',')\r\n const period = parseInt(values[0]) || DEFAULT_PARAMETERS.Period\r\n const opacity = parseFloat(values[1]) || DEFAULT_PARAMETERS.Opacity\r\n\r\n return [period, opacity]\r\n}\r\n\r\nclass VolumeProfile extends Overlay {\r\n static config = VPConfig\r\n\r\n static getNumOfBarsBuffer({ period }: RequireByKey) {\r\n const [periodInt = 0] = getParsedIntegersFromPeriodString(period)\r\n return periodInt + 1 // +1 offsets rendering so it doesn't start on first bar which doesn't look OK in SSR rendered charts\r\n }\r\n\r\n set(obj: Partial) {\r\n super.set(obj)\r\n const { period } = obj\r\n if (typeof period === 'string') {\r\n const [periodInt, opacity] = parsePeriod(period)\r\n this.attrs.period = periodInt\r\n this.attrs.opacity = opacity\r\n this.trigger('change')\r\n }\r\n return this\r\n }\r\n\r\n renderContent(context: CanvasRenderingContext2D) {\r\n if (typeof this.attrs.period !== 'number') {\r\n return\r\n }\r\n super.renderContent()\r\n\r\n const chartModel = this.model.chart() as Chart\r\n const { leftOffset, width } = chartModel\r\n const { left, right } = chartModel.getChartLayoutSettings().ChartSettings\r\n const chartWidth = width - left.width - right.width\r\n\r\n if (this.data.close.length === 0) return\r\n\r\n const firstBarToRender = getVisibleBarToRenderIndex({\r\n quote: this.data,\r\n paneModel: this.model,\r\n leftOffset,\r\n })\r\n\r\n const lastBarToRender = getVisibleBarToRenderIndex({\r\n quote: this.data,\r\n paneModel: this.model,\r\n leftOffset,\r\n chartWidth,\r\n })\r\n\r\n const areNoBarsVisible = getAreNoBarsVisible(firstBarToRender, lastBarToRender)\r\n if (areNoBarsVisible) return\r\n\r\n const [upColor, downColor] = getColorsWithAppliedOpacity(this.attrs)\r\n const [minClose, maxClose] = utils.minMax(this.data.close.slice(firstBarToRender.index, lastBarToRender.index + 1))\r\n\r\n const segment = Math.abs(maxClose - minClose) / this.attrs.period\r\n const segments = [] // create an empty array to hold the segments\r\n\r\n for (let i = 0; i < this.attrs.period; i++) {\r\n const segmentStart = minClose + segment * i // calculate start of current segment\r\n const segmentEnd = segmentStart + segment // calculate end of current segment\r\n segments.push({ start: segmentStart, end: segmentEnd, up: 0, down: 0 }) // add segment to array\r\n }\r\n\r\n // loop through visible bars and assign volumes to segments\r\n for (let i = firstBarToRender.index; i <= lastBarToRender.index; i++) {\r\n const segmentIndex: number = segments.findIndex((item, segmentIndex) =>\r\n isInSegment(this.data.close[i], item.start, item.end, !!segmentIndex)\r\n )\r\n if (segmentIndex === -1) continue\r\n const volumeTrend = this.data.close[i] < this.data.open[i] ? 'down' : 'up'\r\n segments[segmentIndex][volumeTrend] += this.data.volume[i]\r\n }\r\n\r\n const max = utils.max(segments.map((item) => item.up + item.down))\r\n const rangeMax = chartWidth * 0.4 // maximum range in pixels where longest bar would reach (now it's 40% of chart width)\r\n const volumeFX = d3.scaleLinear().range([0, rangeMax]).domain([0, max])\r\n\r\n segments.forEach((item) => {\r\n const y = Math.round(this.fy(item.start))\r\n const segmentHeightRaw = Math.round(this.fy(item.end)) - y // raw segment height without gap between segments\r\n const segmentHeight = segmentHeightRaw + (Math.abs(segmentHeightRaw) > 5 ? 2 : 1) // apply gap to segment based on how high segment is\r\n const x = Math.abs(leftOffset) // segments are alligned to left side of chart which equal to absoulute value of leftOffset\r\n const upSegmentWidth = Math.round(volumeFX(item.up))\r\n const downSegmentWidth = Math.round(volumeFX(item.down))\r\n\r\n context.fillStyle = upColor\r\n context.fillRect(x, y, upSegmentWidth, segmentHeight)\r\n context.fillStyle = downColor\r\n context.fillRect(x + upSegmentWidth, y, downSegmentWidth, segmentHeight)\r\n })\r\n }\r\n\r\n getModalConfig() {\r\n const options = {\r\n period: {\r\n type: 'number',\r\n label: 'Zones',\r\n name: 'period',\r\n value: this.attrs.period ?? DEFAULT_PARAMETERS.Period,\r\n required: true,\r\n min: 1,\r\n max: 999999,\r\n },\r\n opacity: {\r\n type: 'number',\r\n label: 'Opacity',\r\n name: 'opacity',\r\n value: this.attrs.opacity ?? DEFAULT_PARAMETERS.Opacity,\r\n required: true,\r\n min: 0,\r\n max: 1,\r\n step: 0.1,\r\n },\r\n upColor: {\r\n type: 'color',\r\n label: 'Up Color',\r\n name: 'upColor',\r\n value: this.attrs.upColor ?? VP_COLORS.UP,\r\n },\r\n downColor: {\r\n type: 'color',\r\n label: 'Down Color',\r\n name: 'downColor',\r\n value: this.attrs.downColor ?? VP_COLORS.DOWN,\r\n },\r\n }\r\n\r\n return {\r\n title: VPConfig.label,\r\n inputs: VPConfig.inputsOrder.map((item) => options[item]),\r\n inputsErrorMessages: {\r\n period: `${options.period.label} must be a whole number between ${options.period.min} and ${options.period.max}`,\r\n opacity: `${options.opacity.label} must be a number between ${options.opacity.min} and ${options.opacity.max}`,\r\n },\r\n }\r\n }\r\n\r\n getIsValid(key: string): boolean {\r\n switch (key) {\r\n case 'period':\r\n return this.getIsNumberInputValid({ key })\r\n case 'opacity':\r\n return this.getIsNumberInputValid({ key, integerOnly: false })\r\n case 'upColor':\r\n case 'downColor':\r\n // Some users have wrong colors which break the form validation\r\n return true\r\n default:\r\n return false\r\n }\r\n }\r\n\r\n getLabelColor() {\r\n return this.attrs.upColor || VP_COLORS.UP\r\n }\r\n}\r\n\r\nVolumeProfile.prototype.defaults = { upColor: VP_COLORS.UP, downColor: VP_COLORS.DOWN }\r\n\r\nexport default VolumeProfile\r\n","import { OverlayType } from '../../constants/common'\r\nimport BaseConfig from './overlayBaseConfig'\r\n\r\nexport type Options = { period: number }\r\n\r\nexport interface Attrs extends Options {\r\n color: string\r\n}\r\n\r\nexport class VWAPConfig extends BaseConfig {\r\n static type = OverlayType.Vwap\r\n static abbreviation = 'vwap'\r\n static label = 'VWAP (intraday charts)'\r\n static shortLabel = 'VWAP'\r\n static inputsOrder = ['color'] as Array>\r\n static inputsLabels = { color: 'Color' }\r\n static calculatedValuesOrder = ['vwap'] as const\r\n static calculatedValuesLabels = { vwap: 'VWAP' }\r\n static defaultCalculatedValueOption = this.calculatedValuesOrder[0]\r\n}\r\n","import { Options, VWAPConfig } from '../overlays/configs/vwap'\r\nimport { dateFromUnixTimestamp } from '../utils'\r\nimport { MainCalculation, OnValueCalculated } from './main'\r\n\r\nconst datesAreOnSameDay = (first: Date, second: Date) =>\r\n first.getFullYear() === second.getFullYear() &&\r\n first.getMonth() === second.getMonth() &&\r\n first.getDate() === second.getDate()\r\n\r\ntype DefaultCalculatedValuesType = {\r\n vwap: number[]\r\n}\r\n\r\nexport class VWapCalculation extends MainCalculation {\r\n static config = VWAPConfig\r\n\r\n calculate(onValueCalculated?: OnValueCalculated) {\r\n const { date, close, low, high, volume } = this.quote\r\n const lastIndex = date.length - 1\r\n this._calculatedValues = this.getDefaultCalculatedValues()\r\n\r\n let cumulativePV = 0\r\n let cumulativeVolume = 0\r\n\r\n for (let i = 0; i <= lastIndex; i++) {\r\n if (i > 0) {\r\n const prevDate = dateFromUnixTimestamp(date[i - 1])\r\n if (!datesAreOnSameDay(prevDate, dateFromUnixTimestamp(date[i]))) {\r\n cumulativePV = 0\r\n cumulativeVolume = 0\r\n }\r\n }\r\n\r\n const typicalPrice = (close[i] + low[i] + high[i]) / 3\r\n const pv = typicalPrice * volume[i]\r\n\r\n cumulativePV += pv\r\n cumulativeVolume += volume[i]\r\n\r\n this.calculatedValues.vwap[i] = cumulativePV / cumulativeVolume\r\n\r\n if (onValueCalculated?.(this.calculatedValues, i) === false) {\r\n break\r\n }\r\n }\r\n }\r\n}\r\n","import { VWapCalculation } from '../indicator-calculation/vwap'\r\nimport PaneModel from '../models/pane'\r\nimport { Attrs, VWAPConfig } from './configs/vwap'\r\nimport Overlay from './overlay'\r\n\r\nclass VWAP extends Overlay {\r\n static config = VWAPConfig\r\n\r\n static getNumOfBarsBuffer() {\r\n return 1\r\n }\r\n\r\n constructor(values: Partial, model: PaneModel) {\r\n super(values, model)\r\n this.attrs.period = 5\r\n }\r\n\r\n renderContent(context: CanvasRenderingContext2D) {\r\n super.renderContent()\r\n if (!this.isRendered()) {\r\n return\r\n }\r\n\r\n const { leftOffset, width } = this.model.chart()\r\n context.translate(0.5, 0.5)\r\n context.beginPath()\r\n context.set('lineWidth', 1)\r\n context.set('strokeStyle', this.attrs.color)\r\n\r\n const vwapCalculation = new VWapCalculation({\r\n quote: this.data,\r\n options: { period: this.attrs.period },\r\n })\r\n\r\n vwapCalculation.calculate(({ vwap }, dataIndex) => {\r\n const x = this.fx(dataIndex)\r\n if (this.fx(dataIndex + 1) + leftOffset < 0) {\r\n return // continue\r\n }\r\n if (this.fx(dataIndex - 1) + leftOffset > width) {\r\n return false // break\r\n }\r\n const y = Math.round(this.fy(vwap[dataIndex]))\r\n context.lineTo(x, y)\r\n })\r\n\r\n context.stroke()\r\n context.translate(-0.5, -0.5)\r\n }\r\n\r\n getModalConfig() {\r\n const options = {\r\n color: {\r\n type: 'color',\r\n label: 'Color',\r\n name: 'color',\r\n value: this.attrs.color ?? this.getFreeColor(),\r\n },\r\n }\r\n\r\n return {\r\n title: VWAPConfig.label,\r\n inputs: VWAPConfig.inputsOrder.map((item) => options[item]),\r\n inputsErrorMessages: {},\r\n }\r\n }\r\n\r\n getIsValid(key: string) {\r\n switch (key) {\r\n case 'color':\r\n // Some users have wrong colors which break the form validation\r\n return true\r\n default:\r\n return false\r\n }\r\n }\r\n\r\n isRendered() {\r\n return this.model.chart().quote().isIntraday\r\n }\r\n\r\n isRenderedOverlaysLabel() {\r\n return this.isRendered()\r\n }\r\n\r\n toString() {\r\n return VWAPConfig.shortLabel\r\n }\r\n}\r\n\r\nVWAP.prototype.defaults = { color: '#9467bd' }\r\n\r\nexport default VWAP\r\n","import { OverlayType } from '../constants/common'\r\nimport bb from './bb'\r\nimport dch from './dch'\r\nimport ema from './ema'\r\nimport ema2 from './ema2'\r\nimport hilo from './hilo'\r\nimport hline from './hline'\r\nimport ic from './ic'\r\nimport icf from './icf'\r\nimport kch from './kch'\r\nimport none from './none'\r\nimport overlay from './overlay'\r\nimport patterns from './patterns'\r\nimport pp from './pp'\r\nimport sar from './sar'\r\nimport sma from './sma'\r\nimport sma2 from './sma2'\r\nimport str from './str'\r\nimport vp from './vp'\r\nimport vwap from './vwap'\r\n\r\nexport const overlaysByType = Object.freeze({\r\n [OverlayType.Overlay]: overlay,\r\n [OverlayType.None]: none,\r\n [OverlayType.Bb]: bb,\r\n [OverlayType.Dch]: dch,\r\n [OverlayType.Ema]: ema,\r\n [OverlayType.Ema2]: ema2,\r\n [OverlayType.Hilo]: hilo,\r\n [OverlayType.Hline]: hline,\r\n [OverlayType.Ic]: ic,\r\n [OverlayType.Icf]: icf,\r\n [OverlayType.Kch]: kch,\r\n [OverlayType.Patterns]: patterns,\r\n [OverlayType.Pp]: pp,\r\n [OverlayType.Sar]: sar,\r\n [OverlayType.Sma]: sma,\r\n [OverlayType.Sma2]: sma2,\r\n [OverlayType.Str]: str,\r\n [OverlayType.Vp]: vp,\r\n [OverlayType.Vwap]: vwap,\r\n})\r\n","import {\r\n MOBILE_VIEW_BREAKPOINT_WIDTH,\r\n PREMARKET_AFTERMARKET_HOURS,\r\n SpecificChartFunctionality,\r\n} from './constants/common'\r\nimport { captureException, getIsSSr } from './utils/helpers'\r\n\r\nexport { getSanitizedTicker } from './utils/ticker-sanitizer'\r\n\r\nfunction getIsDstInNy(date: Date) {\r\n const dayNumber = date.getDate()\r\n const monthIndex = date.getMonth()\r\n const dayOfWeek = date.getDay()\r\n const previousSunday = dayNumber - dayOfWeek\r\n if (monthIndex < 2 || monthIndex > 10) {\r\n return false\r\n }\r\n if (monthIndex > 2 && monthIndex < 10) {\r\n return true\r\n }\r\n return monthIndex === 2 ? previousSunday >= 8 : previousSunday <= 0\r\n}\r\n\r\nclass Utils {\r\n static min(...args: T[]): number {\r\n if (typeof args[0] === 'number') {\r\n return args[0] < +args[1] ? args[0] : (args[1] as number)\r\n }\r\n let min = args[0][0]\r\n for (const arg of args) {\r\n for (const el of arg as number[]) {\r\n if (el < min) {\r\n min = el\r\n }\r\n }\r\n }\r\n return min\r\n }\r\n\r\n static max(...args: T[]): number {\r\n if (typeof args[0] === 'number') {\r\n return args[0] > +args[1] ? args[0] : (args[1] as number)\r\n }\r\n let max = args[0][0]\r\n for (const arg of args) {\r\n for (const el of arg as number[]) {\r\n if (el > max) {\r\n max = el\r\n }\r\n }\r\n }\r\n return max\r\n }\r\n\r\n static minMax(...args: number[][]) {\r\n let max\r\n let min = (max = args[0][0] as number)\r\n for (const arg of args) {\r\n for (const el of arg) {\r\n if (el < min) {\r\n min = el\r\n }\r\n if (el > max) {\r\n max = el\r\n }\r\n }\r\n }\r\n return [min, max]\r\n }\r\n\r\n static getScaleRatio() {\r\n return (typeof window !== 'undefined' && window.devicePixelRatio) || 1\r\n }\r\n\r\n static setSizeOnCanvasElement({\r\n canvasElement,\r\n width,\r\n height,\r\n ratio = Utils.getScaleRatio(),\r\n }: {\r\n canvasElement: HTMLCanvasElement | null\r\n width: number\r\n height: number\r\n ratio?: number\r\n }) {\r\n if (canvasElement) {\r\n canvasElement.width = width * ratio\r\n canvasElement.height = height * ratio\r\n canvasElement.style.width = width + 'px'\r\n canvasElement.style.height = height + 'px'\r\n }\r\n }\r\n\r\n static getQuoteDateTimestampOffsetInSeconds(referenceDate?: Date) {\r\n const date = referenceDate || new Date()\r\n const dateAsNY = new Date(\r\n date.getUTCFullYear(),\r\n date.getUTCMonth(),\r\n date.getUTCDate(),\r\n date.getUTCHours() - 5,\r\n date.getUTCMinutes(),\r\n date.getUTCSeconds()\r\n )\r\n const isDst = getIsDstInNy(dateAsNY)\r\n return (isDst ? 4 : 5) * 60 * 60\r\n }\r\n\r\n static convertLocalToNyTime(referenceDate: Date, addOffset: boolean) {\r\n const date = new Date(referenceDate)\r\n const quoteDateTimeOffsetInMs = Utils.getQuoteDateTimestampOffsetInSeconds(date) * 1000\r\n const localTimeOffsetInMs = date.getTimezoneOffset() * 60 * 1000\r\n const offsetDirectionCoefficient = addOffset ? 1 : -1\r\n date.setTime(date.getTime() + (localTimeOffsetInMs - quoteDateTimeOffsetInMs) * offsetDirectionCoefficient)\r\n return date\r\n }\r\n\r\n // Keep in sync with the clone in Website repo in shared/isStockFastRefreshAvailable.ts\r\n static isStockFastRefreshAvailable(hasPremarket = true, hasAftermarket = true, bufferMinutes = 30) {\r\n const MARKET_START = { hours: 9, minutes: 30 }\r\n const MARKET_END = { hours: 16, minutes: 0 }\r\n const getMinutes = ({ hours, minutes }: { hours: number; minutes: number }) => hours * 60 + minutes\r\n\r\n const date = convertLocalToNyTime(new Date(), true)\r\n const dayOfWeek = date.getDay()\r\n const currentDayMinutes = date.getHours() * 60 + date.getMinutes()\r\n\r\n const premarketMinutes = hasPremarket ? PREMARKET_AFTERMARKET_HOURS * 60 : 0\r\n const aftermarketMinutes = hasAftermarket ? PREMARKET_AFTERMARKET_HOURS * 60 : 0\r\n\r\n const isWeekend = dayOfWeek === 0 || dayOfWeek === 6\r\n const isOpen = getMinutes(MARKET_START) - premarketMinutes - bufferMinutes <= currentDayMinutes\r\n const isClosed = getMinutes(MARKET_END) + aftermarketMinutes + bufferMinutes <= currentDayMinutes\r\n return !isWeekend && isOpen && !isClosed\r\n }\r\n\r\n static dateFromUnixTimestamp(timestamp: number) {\r\n /*\r\n * Passing 0 as a param is needed in order to setUTCSeconds work properly.\r\n * The function adds seconds to the date instance if it exceeds 60.\r\n * For more info see the docs https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/setUTCSeconds\r\n * */\r\n const date = new Date(0)\r\n date.setUTCSeconds(timestamp)\r\n return Utils.convertLocalToNyTime(date, true)\r\n }\r\n\r\n static dateStringFromDate(date: Date) {\r\n return `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, '0')}-${String(date.getDate()).padStart(\r\n 2,\r\n '0'\r\n )}`\r\n }\r\n\r\n static dateFromDateString(dateString: string) {\r\n const [yyyy, mm, dd] = dateString.split('-')\r\n\r\n const date = new Date(Number.parseInt(yyyy), Number.parseInt(mm) - 1, Number.parseInt(dd))\r\n if (Number.isNaN(date.getTime())) {\r\n captureException(new Error('Invalid Date'), { extra: { date, dateString } })\r\n }\r\n\r\n return date\r\n }\r\n\r\n static isMobile(testTouchPoints?: boolean) {\r\n if (getIsSSr()) return false\r\n let isMobileOs = false\r\n\r\n // New iOS versions no longer report iPad in user agent\r\n if (navigator.userAgent.indexOf('Macintosh') > -1) {\r\n try {\r\n document.createEvent('TouchEvent')\r\n isMobileOs = true\r\n } catch (e) {}\r\n } else {\r\n isMobileOs = !!navigator.userAgent.match(\r\n /\\b(Android|webOS|i(?:Phone|Pad|Pod)|BlackBerry|Windows (?:Phone|Mobile))\\b/i\r\n )\r\n }\r\n\r\n if (testTouchPoints) {\r\n try {\r\n return (\r\n isMobileOs &&\r\n (window.navigator.msMaxTouchPoints ||\r\n window.navigator.maxTouchPoints ||\r\n 'ontouchstart' in document.createElement('div'))\r\n )\r\n } catch (e) {}\r\n }\r\n\r\n return isMobileOs\r\n }\r\n\r\n static isIPad() {\r\n const matchesIPad = navigator.userAgent.match(/iPad/i)\r\n const matchesIPhone = navigator.userAgent.match(/iPhone/i)\r\n const matchesIPod = navigator.userAgent.match(/iPod/i)\r\n const matchesIOSLike = navigator.userAgent.match(/Mac/) && navigator.maxTouchPoints > 0\r\n\r\n return (matchesIOSLike && !matchesIPhone && !matchesIPod) || matchesIPad\r\n }\r\n\r\n static getCookie(name: string) {\r\n const re = new RegExp('(?:(?:^|.*;\\\\s*)' + name + '\\\\s*\\\\=\\\\s*([^;]*).*$)|^.*$')\r\n return document.cookie.replace(re, '$1')\r\n }\r\n\r\n static setCookie(name: string, value: string, expires: Date) {\r\n let cookie = name + '=' + value + '; expires=' + expires.toUTCString()\r\n if (document.location.hostname !== 'localhost') {\r\n cookie += '; domain=.finviz.com'\r\n }\r\n document.cookie = cookie\r\n }\r\n}\r\n\r\nexport default Utils\r\nexport const convertLocalToNyTime = Utils.convertLocalToNyTime\r\nexport const dateFromUnixTimestamp = Utils.dateFromUnixTimestamp\r\nexport const dateStringFromDate = Utils.dateStringFromDate\r\nexport const dateFromDateString = Utils.dateFromDateString\r\n\r\nexport function getFullscreenStatus(): boolean {\r\n return (\r\n document.fullscreenElement ??\r\n document.webkitFullscreenElement ??\r\n document.mozFullScreenElement ??\r\n document.msFullscreenElement ??\r\n false\r\n )\r\n}\r\n\r\nexport function getRequestFullscreen(element: HTMLElement) {\r\n return (\r\n element.requestFullscreen ??\r\n element.webkitRequestFullScreen ??\r\n element.mozRequestFullScreen ??\r\n element.msRequestFullscreen\r\n )\r\n}\r\n\r\nexport function getExitFullscreen() {\r\n return (\r\n document.exitFullscreen ?? document.webkitExitFullscreen ?? document.mozExitFullScreen ?? document.msExitFullscreen\r\n )\r\n}\r\n\r\nexport function ready(fn: () => void) {\r\n if (document.readyState !== 'loading') {\r\n fn()\r\n return\r\n }\r\n\r\n document.addEventListener('DOMContentLoaded', fn)\r\n}\r\n\r\nexport function getChartsDimensions(chartElementId: string) {\r\n const PADDING = 2 // Border widths\r\n const containerElement = document.getElementById(chartElementId)\r\n\r\n const box = containerElement?.getBoundingClientRect()\r\n\r\n return {\r\n width: Math.max((box?.width ?? 0) - PADDING, 0),\r\n height: Math.max((box?.height ?? 0) - PADDING, 0),\r\n }\r\n}\r\n\r\nexport function getIsMobileScreenSize() {\r\n return window.innerWidth < MOBILE_VIEW_BREAKPOINT_WIDTH\r\n}\r\n\r\nexport function getIsMobilePortrait(isMobile?: boolean) {\r\n if (isMobile ?? Utils.isMobile()) {\r\n return window.orientation % 180 === 0\r\n }\r\n return false\r\n}\r\n\r\nexport function numberToStringWithUnitsSuffix(value: number) {\r\n let suffix = ''\r\n if (value >= 1000000000) {\r\n value /= 1000000000\r\n suffix = 'B'\r\n } else if (value >= 1000000) {\r\n value /= 1000000\r\n suffix = 'M'\r\n } else if (value >= 1000) {\r\n value /= 1000\r\n suffix = 'K'\r\n }\r\n\r\n return value.toFixed(2) + suffix\r\n}\r\n\r\nexport function isRedesignEnabled() {\r\n return typeof window !== 'undefined' && window.FinvizSettings?.hasRedesignEnabled\r\n}\r\n\r\nexport function isRedesignedPage(\r\n obj: { specificChartFunctionality?: SpecificChartFunctionality | null },\r\n matchingPages = [\r\n SpecificChartFunctionality.forexPage,\r\n SpecificChartFunctionality.futuresPage,\r\n SpecificChartFunctionality.cryptoPage,\r\n ]\r\n) {\r\n return (\r\n (isRedesignEnabled() && matchingPages.includes(obj.specificChartFunctionality!)) ||\r\n // Legacy design on quote uses redesigned elements (page header + chart controls)\r\n obj.specificChartFunctionality === SpecificChartFunctionality.quotePage\r\n )\r\n}\r\n","import { ObjectHash } from '../../types/shared'\r\n\r\nconst requestsAbortControllersCache: ObjectHash = {}\r\n\r\nexport function removeFromAbortCache(key: string) {\r\n delete requestsAbortControllersCache[key]\r\n}\r\n\r\nexport function abortRequest(key: string) {\r\n requestsAbortControllersCache[key]?.abort()\r\n removeFromAbortCache(key)\r\n}\r\n\r\nexport function getIsAbortError(error: Error) {\r\n return error.name === 'AbortError'\r\n}\r\n\r\nexport function createRequestAbortController({\r\n key,\r\n shouldAbortRunningRequest = false,\r\n}: {\r\n key: string\r\n shouldAbortRunningRequest?: boolean\r\n}) {\r\n if (shouldAbortRunningRequest) {\r\n abortRequest(key)\r\n }\r\n const controller = 'AbortController' in window ? new AbortController() : undefined\r\n if (controller) {\r\n requestsAbortControllersCache[key] = controller\r\n }\r\n return controller\r\n}\r\n","import * as websiteShared from '@finviz/website'\r\n\r\nimport { captureException } from './helpers'\r\n\r\n/**\r\n * Hook used to asynchronously load a module\r\n *\r\n * Usage: [wiki](https://github.com/finvizhq/Finviz-Website/wiki/Loading-modules-asynchronously#useasyncmodule)\r\n */\r\nexport const useAsyncModule = (\r\n props: {\r\n importFn: () => Promise\r\n onError?: () => void\r\n cacheKey: string\r\n captureException?: (exception: Error, captureContext?: { extra: Record }) => void\r\n errorSeverity?: 'medium' | 'high'\r\n } & (websiteShared.ControlledModuleConfig | websiteShared.SuspenseModuleConfig)\r\n) =>\r\n websiteShared.useAsyncModule({ captureException, ...props }) as [\r\n SuspenseMode extends true ? T : T | null,\r\n { isLoading: boolean; loadModule: () => Promise; isError: boolean },\r\n ]\r\n","import { getIsSSr } from './helpers'\r\n\r\n// Extracted from isMobile, and modified to fit usage\r\nfunction isFirefoxDesktop() {\r\n const matchesAndroid = navigator.userAgent.match(/Android/i)\r\n const matchesWebOS = navigator.userAgent.match(/webOS/i)\r\n const matchesIPhone = navigator.userAgent.match(/iPhone/i)\r\n const matchesiPad = navigator.userAgent.match(/iPad/i)\r\n const matchesIPod = navigator.userAgent.match(/iPod/i)\r\n const matchesBlackBerry = navigator.userAgent.match(/BlackBerry/i)\r\n const matchesWindowsPhone = navigator.userAgent.match(/Windows Phone/i)\r\n const matchesIOSLike = navigator.userAgent.match(/Mac/) && navigator.maxTouchPoints > 0\r\n\r\n const isMobileDevice =\r\n matchesAndroid ||\r\n matchesWebOS ||\r\n matchesIPhone ||\r\n matchesiPad ||\r\n matchesIPod ||\r\n matchesBlackBerry ||\r\n matchesWindowsPhone ||\r\n matchesIOSLike\r\n\r\n const matchesFirefox = !!navigator.userAgent.match(/firefox/i)\r\n\r\n return matchesFirefox && !isMobileDevice\r\n}\r\n\r\n// Due bug in FireFox, when if HW acceleration is used canvas is blurry\r\n// we need to set canvas as CPU only\r\nconst shouldUseCPUOnly = getIsSSr() ? false : isFirefoxDesktop()\r\n\r\nexport function getContextWithCache(canvas: HTMLCanvasElement | null): CanvasRenderingContext2D | null {\r\n if (!canvas) {\r\n return null\r\n }\r\n\r\n const context = canvas.getContext('2d', shouldUseCPUOnly ? { willReadFrequently: true } : undefined)\r\n if (!context) {\r\n window.Sentry?.captureMessage('Context unavailable')\r\n return null\r\n }\r\n\r\n context._cache = {}\r\n\r\n const _restore = CanvasRenderingContext2D.prototype.restore\r\n context.restore = function () {\r\n this._cache = {}\r\n return _restore.apply(this)\r\n }\r\n\r\n context.set = function (key, value) {\r\n if (this._cache[key] !== value) {\r\n this[key] = value\r\n this._cache[key] = value\r\n }\r\n }\r\n\r\n return context\r\n}\r\n","import { Theme } from '../../types/shared'\r\nimport twColors from '../constants/colors'\r\nimport { ChartEventType } from '../constants/common'\r\nimport math, { BIG_NUMBER_VALUES, BigNumber } from '../helpers/math'\r\nimport utils from '../utils'\r\nimport { formatDateToStringUS, getEarningsDateSuffix } from './helpers'\r\n\r\ninterface IChartEventBase {\r\n elementId: string\r\n eventType: ChartEventType\r\n dateTimestamp: number // represent 'earningsDate' column of earnings and 'exdate' column for dividends & split\r\n}\r\n\r\nexport interface IEarnings extends IChartEventBase {\r\n epsActual?: number\r\n epsEstimate?: number\r\n epsReportedActual?: number\r\n epsReportedEstimate?: number\r\n fiscalEndDate: number\r\n fiscalPeriod: string\r\n salesActual?: number\r\n salesEstimate?: number\r\n}\r\n\r\nexport interface IDividends extends IChartEventBase {\r\n ordinary: number\r\n special: number\r\n}\r\n\r\nexport interface ISplit extends IChartEventBase {\r\n factorFrom: number\r\n factorTo: number\r\n}\r\n\r\nexport enum ChartEventBadgeState {\r\n default = 'default',\r\n hover = 'hover',\r\n selected = 'selected',\r\n}\r\n\r\nexport interface IChartEventBadgeProps {\r\n theme: Theme\r\n state: ChartEventBadgeState\r\n width: number\r\n}\r\n\r\ninterface IGetChartEventBadgeColors {\r\n theme: Theme\r\n state: ChartEventBadgeState\r\n colors: IBadgeColors\r\n}\r\n\r\ninterface IBadgeStateColors {\r\n default: string\r\n hover: string\r\n selected: string\r\n}\r\n\r\ninterface IBadgeThemeColors {\r\n outerStroke: string\r\n innerStroke: string\r\n innerFill: IBadgeStateColors\r\n textFill: IBadgeStateColors\r\n}\r\n\r\ninterface IBadgeColors {\r\n light: IBadgeThemeColors\r\n dark: IBadgeThemeColors\r\n}\r\n\r\nexport function getChartEventBadgeColors({ theme, state, colors }: IGetChartEventBadgeColors) {\r\n return {\r\n outerStroke: colors[theme].outerStroke,\r\n innerStroke: colors[theme].innerStroke,\r\n innerFill: colors[theme].innerFill[state],\r\n textFill: colors[theme].textFill[state],\r\n }\r\n}\r\n\r\nexport function getFormattedEventDate(\r\n exdate: number,\r\n hasEarningsDateSuffix = false,\r\n options: ObjectHash = {\r\n month: 'short',\r\n }\r\n) {\r\n const parsedDate = utils.dateFromUnixTimestamp(exdate)\r\n\r\n const formattedDate = formatDateToStringUS(parsedDate, options)\r\n\r\n if (hasEarningsDateSuffix) {\r\n return `${formattedDate} ${getEarningsDateSuffix(parsedDate)}`\r\n }\r\n\r\n return formattedDate\r\n}\r\n\r\nexport function getFormattedValue({\r\n value,\r\n bigNumberUnit,\r\n maxDecimalPlaces = 3,\r\n}: {\r\n value: number\r\n bigNumberUnit?: BigNumber\r\n maxDecimalPlaces?: number\r\n}) {\r\n let numberString = ''\r\n let suffix = ''\r\n\r\n if (bigNumberUnit === undefined) {\r\n numberString = math.round({ value, overridePlaces: 3 })\r\n } else {\r\n const bigNumber = math.formatBigNumber(value * BIG_NUMBER_VALUES[bigNumberUnit], 3, BigNumber.Million)\r\n numberString = parseFloat(bigNumber.substring(0, bigNumber.length - 1)).toString() // parseFloat with toString are removing trailing zeroes\r\n suffix = bigNumber.substring(bigNumber.length - 1)\r\n }\r\n\r\n const [wholeNumber, decimalNumber] = numberString.split('.')\r\n\r\n if (decimalNumber === undefined) return `${wholeNumber}${suffix}`\r\n\r\n let formattedDecimalNumber = decimalNumber\r\n if (maxDecimalPlaces === 2 || decimalNumber[decimalNumber.length - 1] === '0') {\r\n formattedDecimalNumber = decimalNumber.slice(0, -1)\r\n }\r\n\r\n return `${[wholeNumber, formattedDecimalNumber].join('.')}${suffix}`\r\n}\r\n\r\nexport function getChartEventBageColors(colorKey: 'violet' | 'blue' | 'red' | 'gray' | 'purple' | 'green') {\r\n return {\r\n light: {\r\n outerStroke: twColors.white,\r\n innerStroke: twColors[colorKey][400],\r\n innerFill: {\r\n default: twColors[colorKey][50],\r\n hover: twColors[colorKey][100],\r\n selected: twColors[colorKey][400],\r\n },\r\n textFill: {\r\n default: twColors[colorKey][500],\r\n hover: twColors[colorKey][600],\r\n selected: twColors.white,\r\n },\r\n },\r\n dark: {\r\n outerStroke: twColors.gray[900],\r\n innerStroke: twColors[colorKey][400],\r\n innerFill: {\r\n default: twColors[colorKey][800],\r\n hover: twColors[colorKey][600],\r\n selected: twColors[colorKey][400],\r\n },\r\n textFill: {\r\n default: twColors.white,\r\n hover: twColors.white,\r\n selected: twColors.white,\r\n },\r\n },\r\n } as IBadgeColors\r\n}\r\n","import * as dateFns from 'date-fns'\r\n\r\nimport { ChartConfigChart } from '../../server/chartConfig'\r\nimport { ChartConfigChartPane, Instrument, ObjectHash } from '../../types/shared'\r\nimport Line from '../canvas/line'\r\nimport Text from '../canvas/text'\r\nimport { chartsByType } from '../charts/charts'\r\nimport {\r\n CRYPTOS,\r\n ChartEditorEnum,\r\n ChartElementType,\r\n IndicatorType,\r\n OFFSET,\r\n PADDING,\r\n ScaleType,\r\n SpecificChartFunctionality,\r\n TIMEFRAME,\r\n TIMEFRAME_SECONDS,\r\n TextBaseline,\r\n} from '../constants/common'\r\nimport { getPercentageFromValue } from '../controllers/renderUtils'\r\nimport math from '../helpers/math'\r\nimport { indicatorsByType } from '../indicators/indicators'\r\nimport Chart from '../models/chart'\r\nimport ChartLayoutModel from '../models/chart_layout'\r\nimport { IChartSettings } from '../models/chart_settings/interfaces'\r\nimport { Mouse } from '../models/mouse'\r\nimport Pane from '../models/pane'\r\nimport Quote, { QuoteGetParams } from '../models/quote'\r\nimport { getChartLayoutSettings } from '../models/settings'\r\nimport Utils, { dateFromUnixTimestamp } from '../utils'\r\nimport { captureException } from './helpers'\r\n\r\nconst DAY_IN_SECONDS = 86400\r\nconst TWO_MIN_IN_MS = 2 * 60 * 1000\r\nconst virtualDatesCache: ObjectHash<{\r\n fromSeconds: number\r\n toSeconds: number\r\n lastUsed: number\r\n virtualDates: number[]\r\n}> = {}\r\n\r\n// The reason to use this func instead of dateFns.isSameDay is performance as this is way faster\r\nfunction areTimestampsFromSameDay({ ts1, ts2 }: { ts1: number; ts2: number }) {\r\n const ts1Utc = ts1\r\n const ts2Utc = ts2\r\n return Math.floor(ts1Utc / DAY_IN_SECONDS) === Math.floor(ts2Utc / DAY_IN_SECONDS)\r\n}\r\n\r\nfunction getVirtualDatesCacheId({\r\n idRevision,\r\n ticker,\r\n timeframe,\r\n}: {\r\n idRevision: number\r\n ticker: string\r\n timeframe: string\r\n}) {\r\n return `${ticker}-${timeframe}-${idRevision}`\r\n}\r\n\r\nfunction getCachedVirtualDates({\r\n idRevision,\r\n ticker,\r\n timeframe,\r\n fromSeconds,\r\n toSeconds,\r\n}: {\r\n idRevision: number\r\n ticker: string\r\n timeframe: string\r\n fromSeconds: number\r\n toSeconds: number\r\n}) {\r\n const id = getVirtualDatesCacheId({ idRevision, ticker, timeframe })\r\n const cache = virtualDatesCache[id]\r\n if (cache?.fromSeconds <= fromSeconds && cache?.toSeconds >= toSeconds) {\r\n cache.lastUsed = Date.now()\r\n if (cache.fromSeconds === fromSeconds && cache.toSeconds === toSeconds) {\r\n return cache.virtualDates\r\n }\r\n return cache.virtualDates.filter(\r\n (virtualDateSeconds) => virtualDateSeconds >= fromSeconds && virtualDateSeconds <= toSeconds\r\n )\r\n }\r\n return null\r\n}\r\n\r\nfunction checkVirtualCacheSize() {\r\n const now = Date.now()\r\n Object.keys(virtualDatesCache).forEach((virtualDatesCacheId) => {\r\n if (virtualDatesCache[virtualDatesCacheId].lastUsed < now - TWO_MIN_IN_MS) {\r\n delete virtualDatesCache[virtualDatesCacheId]\r\n }\r\n })\r\n}\r\n\r\nfunction setCachedVirtualDates({\r\n idRevision,\r\n ticker,\r\n timeframe,\r\n fromSeconds,\r\n toSeconds,\r\n virtualDates,\r\n}: {\r\n idRevision: number\r\n ticker: string\r\n timeframe: string\r\n fromSeconds: number\r\n toSeconds: number\r\n virtualDates: number[]\r\n}) {\r\n const id = getVirtualDatesCacheId({ idRevision, ticker, timeframe })\r\n checkVirtualCacheSize()\r\n virtualDatesCache[id] = {\r\n fromSeconds,\r\n toSeconds,\r\n virtualDates,\r\n lastUsed: Date.now(),\r\n }\r\n}\r\n\r\nconst MAX_BAR_BORDER_WIDTH = 1\r\nconst MIN_BAR_MARGIN_WIDTH = 0\r\nconst MAX_BAR_MARGIN_WIDTH = 16\r\n\r\nexport function getBarWidthWithMarginByParts({\r\n zoomFactor = 1,\r\n chartLayout,\r\n}: {\r\n zoomFactor?: number\r\n chartLayout: ChartLayoutModel\r\n}) {\r\n const { ChartSettings } = chartLayout.settings\r\n const settingsCenter = ChartSettings.center\r\n const barMargin =\r\n zoomFactor > 1 && settingsCenter.barMargin === 0\r\n ? Math.min(settingsCenter.barWidth, 1 - 1 / zoomFactor)\r\n : settingsCenter.barMargin\r\n\r\n const barFillWidth = settingsCenter.barWidth * zoomFactor\r\n const barBorderWidth = Math.min(settingsCenter.border * zoomFactor, MAX_BAR_BORDER_WIDTH)\r\n const barMarginWidth = Math.max(MIN_BAR_MARGIN_WIDTH, Math.min(barMargin * zoomFactor, MAX_BAR_MARGIN_WIDTH))\r\n\r\n return {\r\n barFillWidth,\r\n barBorderWidth,\r\n barMarginWidth,\r\n }\r\n}\r\n\r\nexport function getBarWidthWithMargin({\r\n zoomFactor = 1,\r\n chartLayout,\r\n shouldRound = true,\r\n}: {\r\n zoomFactor?: number\r\n chartLayout: ChartLayoutModel\r\n shouldRound?: boolean\r\n}) {\r\n const { barFillWidth, barBorderWidth, barMarginWidth } = getBarWidthWithMarginByParts({ zoomFactor, chartLayout })\r\n\r\n const barWidth = barFillWidth + barBorderWidth * 2 + barMarginWidth\r\n if (!shouldRound) {\r\n return barWidth\r\n }\r\n const roundDecimalPlaces = barWidth > 100 ? 10 : 10000\r\n return Math.round(barWidth * roundDecimalPlaces) / roundDecimalPlaces\r\n}\r\n\r\nexport function getBarWithoutMarginWidth(chartModel: Chart) {\r\n const { barFillWidth, barBorderWidth } = getBarWidthWithMarginByParts({\r\n chartLayout: chartModel.chart_layout(),\r\n zoomFactor: chartModel.zoomFactor,\r\n })\r\n return barFillWidth + barBorderWidth * 2\r\n}\r\n\r\nexport function getHalfBarWidth(chartModel: Chart, floor = true) {\r\n // Math.max(1, num) is kept from previous implementation, it is highly likely\r\n // that some function which use getHalfBarWidth expect return to be >= 1,\r\n // because we never render bar with width < 1 but at the same time when we have and odd\r\n // width like 5, wa want to floor because of pixel perfect rendering\r\n // but some function require raw not floored number to be able to do it's calculations\r\n // TODO: it would be good to possibly revisit this and check usage if we do need\r\n // to perform floor as well as limit result to be >= 1 but it is most likely necessary\r\n const halfBarWidthRaw = Math.max(1, getBarWithoutMarginWidth(chartModel) / 2)\r\n return floor ? ~~halfBarWidthRaw : halfBarWidthRaw\r\n}\r\n\r\nconst DEFAULT_ZOOM_GUESS_INCREMENT = 0.001\r\n\r\nconst zoomFactorForBarsToDisplayCache: ObjectHash = {}\r\nconst zoomFactorForBarsToDisplayCacheKeys: string[] = []\r\nconst NUMBER_OF_CACHED_ZOOM_FACTORS = 10\r\nconst getZoomFactorFromCache = (key: string) => zoomFactorForBarsToDisplayCache[key] ?? null\r\nconst setZoomFactorToCache = (key: string, value: number) => {\r\n if (!zoomFactorForBarsToDisplayCacheKeys.includes(key)) {\r\n zoomFactorForBarsToDisplayCacheKeys.unshift(key)\r\n if (zoomFactorForBarsToDisplayCacheKeys.length > NUMBER_OF_CACHED_ZOOM_FACTORS) {\r\n const poppedKey = zoomFactorForBarsToDisplayCacheKeys.pop()\r\n if (poppedKey) {\r\n delete zoomFactorForBarsToDisplayCache[poppedKey]\r\n }\r\n }\r\n }\r\n\r\n zoomFactorForBarsToDisplayCache[key] = value\r\n}\r\n\r\nexport function getZoomFactorForBarsToDisplay({\r\n chartVisibleWidth,\r\n numOfVisibleBars,\r\n chartLayout,\r\n}: {\r\n chartVisibleWidth: number\r\n numOfVisibleBars: number\r\n chartLayout: ChartLayoutModel\r\n}) {\r\n const defaultBarWidthWithMargin = getBarWidthWithMargin({ chartLayout })\r\n const barWidthWithMargin = chartVisibleWidth / numOfVisibleBars\r\n const cacheKey = `${defaultBarWidthWithMargin}-${barWidthWithMargin}`\r\n let zoomIncrement = 0\r\n let currentZoomFactor = 1\r\n let finalZoomFactor = getZoomFactorFromCache(cacheKey)\r\n let iteration = 0\r\n if (barWidthWithMargin <= defaultBarWidthWithMargin) {\r\n finalZoomFactor = barWidthWithMargin / defaultBarWidthWithMargin\r\n }\r\n while (finalZoomFactor === null) {\r\n iteration += 1\r\n const threshold = 0.01\r\n currentZoomFactor += zoomIncrement\r\n const barWidth = getBarWidthWithMargin({ zoomFactor: currentZoomFactor, chartLayout, shouldRound: false })\r\n const barWidthDiff = barWidthWithMargin - barWidth\r\n if (barWidthDiff > threshold) {\r\n zoomIncrement = zoomIncrement > 0 ? zoomIncrement * 2 : DEFAULT_ZOOM_GUESS_INCREMENT\r\n } else if (barWidthDiff < -threshold) {\r\n zoomIncrement = zoomIncrement < 0 ? zoomIncrement * 2 : -DEFAULT_ZOOM_GUESS_INCREMENT\r\n } else {\r\n finalZoomFactor = currentZoomFactor\r\n }\r\n\r\n if (iteration === 1000) {\r\n captureException(new Error('Invalid zoom factor from getZoomFactorForBarsToDisplay'), {\r\n extra: {\r\n iteration,\r\n zoomIncrement,\r\n barWidthWithMargin,\r\n barWidth,\r\n barWidthDiff,\r\n currentZoomFactor,\r\n chartLayout: chartLayout.toConfig(['colors', 'panes']),\r\n },\r\n })\r\n return currentZoomFactor\r\n }\r\n }\r\n\r\n setZoomFactorToCache(cacheKey, finalZoomFactor)\r\n\r\n return finalZoomFactor\r\n}\r\n\r\nexport function getTimeframeSeconds({\r\n lowerIndex,\r\n dates,\r\n timeframe,\r\n}: {\r\n lowerIndex: number\r\n dates: number[]\r\n timeframe: TIMEFRAME\r\n}) {\r\n const upperIndex = lowerIndex + 1\r\n const areBoundsDefined = ![dates[upperIndex], dates[lowerIndex]].some((index) => index === undefined)\r\n return areBoundsDefined ? dates[upperIndex] - dates[lowerIndex] : TIMEFRAME_SECONDS[timeframe]\r\n}\r\n\r\nfunction getVirtualTradedDays({\r\n dateStartSeconds,\r\n dateEndSeconds,\r\n datesSeconds,\r\n marketStartMinutes,\r\n}: {\r\n dateStartSeconds: number\r\n dateEndSeconds: number\r\n datesSeconds: number[]\r\n marketStartMinutes: number\r\n}) {\r\n const dateStart = dateFromUnixTimestamp(dateStartSeconds)\r\n const dateEnd = dateFromUnixTimestamp(dateEndSeconds)\r\n const isStartBeforeDates = dateStartSeconds < datesSeconds[0]\r\n const isEndAfterDates = datesSeconds.length > 0 && datesSeconds[datesSeconds.length - 1] < dateEndSeconds\r\n const firstDate = dateFromUnixTimestamp(datesSeconds[0])\r\n const lastDate = dateFromUnixTimestamp(datesSeconds[datesSeconds.length - 1])\r\n return dateFns\r\n .eachDayOfInterval({\r\n start:\r\n isStartBeforeDates && (dateFns.isWeekend(dateStart) || dateStart.getMinutes() < marketStartMinutes)\r\n ? dateFns.addBusinessDays(dateStart, -1)\r\n : dateStart,\r\n end: isEndAfterDates ? dateFns.addBusinessDays(dateEnd, 1) : dateEnd,\r\n })\r\n .filter((date) => {\r\n const ts2 = date.getTime() / 1000 - date.getTimezoneOffset() * 60\r\n return (\r\n !dateFns.isWithinInterval(date, { start: dateFns.startOfDay(firstDate), end: dateFns.endOfDay(lastDate) }) ||\r\n datesSeconds.some((dateTime) =>\r\n areTimestampsFromSameDay({\r\n ts1: dateTime - Utils.getQuoteDateTimestampOffsetInSeconds(new Date(dateTime * 1000)),\r\n ts2,\r\n })\r\n )\r\n )\r\n })\r\n}\r\n\r\nexport function getVirtualTimeframeTradedDates({\r\n dateStart,\r\n dateEnd,\r\n quote,\r\n}: {\r\n dateStart: number\r\n dateEnd: number\r\n quote: Quote\r\n}) {\r\n const { date: dates, ticker, timeframe, instrument, isIntraday, marketStartMinutes } = quote\r\n const barsInDay = quote.getBarsInDay() ?? 0\r\n\r\n // Currently we're passing first and last quote dates to dateStart / dateEnd so this is always true\r\n // but this function can be used on other places in the future where it will work with dates out of quote dates range\r\n const isWithinRangeOfQuoteDate = dateStart === dates[0] && dateEnd === dates[dates.length - 1]\r\n\r\n const commonVirtualCacheProps = {\r\n idRevision: dates.length,\r\n ticker,\r\n timeframe,\r\n fromSeconds: dateStart,\r\n toSeconds: dateEnd,\r\n }\r\n const cachedDates = getCachedVirtualDates(commonVirtualCacheProps)\r\n if (cachedDates) {\r\n return cachedDates\r\n }\r\n if (!isIntraday || instrument !== Instrument.Stock) {\r\n if (isWithinRangeOfQuoteDate) {\r\n return dates\r\n }\r\n const timeframeSeconds = TIMEFRAME_SECONDS[timeframe]\r\n const firstDate = dates[0]\r\n const lastDate = dates[dates.length - 1]\r\n const numOfDatesBefore = Math.ceil((firstDate - dateStart) / timeframeSeconds)\r\n const numOfDatesAfter = Math.ceil((dateEnd - lastDate) / timeframeSeconds)\r\n return [\r\n ...Array.from({ length: numOfDatesBefore })\r\n .map((_, index) => firstDate - (index + 1) * timeframeSeconds)\r\n .reverse(),\r\n ...dates,\r\n ...Array.from({ length: numOfDatesAfter }).map((_, index) => lastDate + (index + 1) * timeframeSeconds),\r\n ]\r\n }\r\n\r\n const virtualTradedDays = isWithinRangeOfQuoteDate\r\n ? quote.getDaysInQuote()\r\n : getVirtualTradedDays({\r\n dateStartSeconds: dateStart,\r\n dateEndSeconds: dateEnd,\r\n datesSeconds: dates,\r\n marketStartMinutes,\r\n })\r\n\r\n const marketStartSeconds = marketStartMinutes * 60\r\n const barTimeframeSeconds = Array.from({ length: barsInDay }).map((_, i) => i * TIMEFRAME_SECONDS[timeframe])\r\n const quoteDatesTimestampOffset = Utils.getQuoteDateTimestampOffsetInSeconds(new Date(dateStart * 1000))\r\n const virtualDates = virtualTradedDays.flatMap((date) => {\r\n const daySeconds =\r\n date.getTime() / 1000 + Utils.getQuoteDateTimestampOffsetInSeconds(date) - date.getTimezoneOffset() * 60\r\n const dayStartSeconds = daySeconds + marketStartSeconds\r\n return barTimeframeSeconds.map(\r\n // Hourly market starts at 9:30 but all other time ticks should be rounded down to :00 of the current hour\r\n (barSeconds, index) =>\r\n ([TIMEFRAME.h, TIMEFRAME.h2, TIMEFRAME.h4].includes(timeframe) && index > 0 ? -1800 : 0) +\r\n dayStartSeconds +\r\n barSeconds\r\n )\r\n })\r\n\r\n if (!isWithinRangeOfQuoteDate) {\r\n virtualDates.filter((date, index, virtualTimeframeTradedDates) => {\r\n const isLowerBounded =\r\n date >= dateStart ||\r\n areTimestampsFromSameDay({\r\n ts1: date - Utils.getQuoteDateTimestampOffsetInSeconds(new Date(date * 1000)),\r\n ts2: dateStart - quoteDatesTimestampOffset,\r\n })\r\n const isOneBeforeLowerBoundStarts = dateStart > date && dateStart < virtualTimeframeTradedDates[index + 1]\r\n return isLowerBounded || isOneBeforeLowerBoundStarts\r\n })\r\n }\r\n\r\n setCachedVirtualDates({\r\n ...commonVirtualCacheProps,\r\n virtualDates,\r\n })\r\n\r\n return virtualDates\r\n}\r\n\r\ninterface TimestampPositionGettersProps {\r\n quote: Quote\r\n}\r\n\r\nexport function getTimestampFromPositionX({ positionX, quote }: TimestampPositionGettersProps & { positionX: number }) {\r\n const { date, timeframe } = quote\r\n const dates = getVirtualTimeframeTradedDates({\r\n dateStart: date[0],\r\n dateEnd: date[date.length - 1],\r\n quote,\r\n })\r\n const dateStart = dates[0]\r\n const dateEnd = dates[dates.length - 1]\r\n const lastDateIndex = dates.length - 1\r\n if (positionX >= 0 && positionX <= lastDateIndex) {\r\n const lowerIndex = Math.floor(positionX)\r\n const timeframeSeconds = getTimeframeSeconds({ lowerIndex, dates, timeframe })\r\n return dates[lowerIndex] + (positionX - lowerIndex) * timeframeSeconds\r\n }\r\n const isLookingBack = positionX < 0\r\n const averageBarDate = (dateEnd - dateStart) / dates.length\r\n const numOfSecondsOutOfBounds = isLookingBack\r\n ? Math.abs(positionX) * averageBarDate\r\n : (positionX - lastDateIndex) * averageBarDate\r\n return Math.round(isLookingBack ? dateStart - numOfSecondsOutOfBounds : dateEnd + numOfSecondsOutOfBounds)\r\n}\r\n\r\nexport function getPositionXFromTimestamp({ timestamp, quote }: TimestampPositionGettersProps & { timestamp: number }) {\r\n const { date, timeframe } = quote\r\n const dates = getVirtualTimeframeTradedDates({\r\n dateStart: date[0],\r\n dateEnd: date[date.length - 1],\r\n quote,\r\n })\r\n const dateStart = dates[0]\r\n const dateEnd = dates[dates.length - 1]\r\n const lastDateIndex = dates.length - 1\r\n if (timestamp >= dates[0] && timestamp <= dates[dates.length - 1]) {\r\n const upperIndex = timestamp === dateEnd ? lastDateIndex : dates.findIndex((date) => date > timestamp)\r\n const timeframeSeconds = getTimeframeSeconds({ lowerIndex: upperIndex - 1, dates, timeframe })\r\n const positionDiffUpperTimestamp = (dates[upperIndex] - timestamp) / timeframeSeconds\r\n return upperIndex - positionDiffUpperTimestamp\r\n }\r\n const isLookingBack = timestamp < dateStart\r\n const averageBarDate = (dateEnd - dateStart) / dates.length\r\n return isLookingBack\r\n ? -((dateStart - timestamp) / averageBarDate)\r\n : lastDateIndex + (timestamp - dateEnd) / averageBarDate\r\n}\r\n\r\n// counterpart in Finviz-Website 'Finviz-Website/js/main/util.ts'\r\nexport function getInstrument(tickerRaw: string) {\r\n if (tickerRaw.indexOf('@') === 0) {\r\n const ticker = tickerRaw.substring(1) as keyof typeof CRYPTOS\r\n\r\n if (CRYPTOS[ticker]) {\r\n return Instrument.Crypto\r\n } else if (ticker.length === 6) {\r\n return Instrument.Forex\r\n } else {\r\n return Instrument.Futures\r\n }\r\n }\r\n return Instrument.Stock\r\n}\r\n\r\nexport function getPerfIndicatorTickerAndTimeframes({\r\n paneWithPerfIndicator,\r\n timeframe,\r\n}: {\r\n paneWithPerfIndicator: ChartConfigChartPane\r\n timeframe: TIMEFRAME\r\n}) {\r\n const { elements } = paneWithPerfIndicator\r\n const perfIndicatorElement = elements.find(({ type }) => type === 'indicators/perf')\r\n const tickers = perfIndicatorElement?.period?.split(',') ?? []\r\n return tickers.map((ticker) => ({\r\n ticker,\r\n instrument: getInstrument(ticker),\r\n timeframe,\r\n }))\r\n}\r\n\r\ninterface PrefetchPerfIndicatorAllQuotesProps extends Pick {\r\n paneWithPerfIndicator: ChartConfigChartPane\r\n chartUuid?: string\r\n}\r\n\r\nexport async function prefetchPerfIndicatorAllQuotes({\r\n paneWithPerfIndicator,\r\n timeframe,\r\n options,\r\n chartUuid,\r\n}: PrefetchPerfIndicatorAllQuotesProps) {\r\n const tickersAndTimeframes = getPerfIndicatorTickerAndTimeframes({ paneWithPerfIndicator, timeframe })\r\n\r\n if (tickersAndTimeframes.length > 0) {\r\n const promises = tickersAndTimeframes.map(({ ticker, instrument, timeframe }) =>\r\n Quote.get({\r\n ticker,\r\n instrument,\r\n timeframe,\r\n options,\r\n chartUuid,\r\n })\r\n )\r\n return Promise.all(promises)\r\n }\r\n return Promise.resolve([])\r\n}\r\n\r\ninterface RenderCrossProps {\r\n context: CanvasRenderingContext2D\r\n mouseModel: Mouse\r\n paneModel: Pane\r\n quote: Quote\r\n contentWidth: number\r\n contentHeight: number\r\n onRenderCrossText?: (context: CanvasRenderingContext2D, crossIndex: number) => void\r\n getRoundDecimalPlaces?: (price?: number) => number | undefined\r\n isIndicator?: boolean\r\n isPerfIndicator?: boolean\r\n}\r\n\r\nexport function renderCross({\r\n context,\r\n mouseModel,\r\n paneModel,\r\n quote,\r\n contentWidth,\r\n contentHeight,\r\n onRenderCrossText,\r\n getRoundDecimalPlaces,\r\n isIndicator = false,\r\n isPerfIndicator = false,\r\n}: RenderCrossProps) {\r\n const crossIndex = mouseModel.getCrossIndexForPane(paneModel)\r\n const chartModel = paneModel.chart()\r\n const { ChartSettings, IndicatorSettings } = getChartLayoutSettings(chartModel.chart_layout())\r\n const settings = isIndicator ? IndicatorSettings : ChartSettings\r\n const { Colors } = ChartSettings.general\r\n\r\n if (!mouseModel.getShouldRenderCrossInPane(paneModel)) {\r\n return false\r\n }\r\n\r\n const price = mouseModel.getPriceForPane(paneModel)\r\n const middle = paneModel.scale.x(crossIndex) + chartModel.leftOffset\r\n const isXAxisInView = middle > 0 && middle <= contentWidth\r\n if (isXAxisInView) {\r\n const x = middle + settings.left.width\r\n new Line(\r\n {\r\n x1: x,\r\n x2: x,\r\n y1: settings.top.height,\r\n y2: settings.top.height + contentHeight,\r\n strokeStyle: Colors.cross,\r\n },\r\n paneModel\r\n ).render(context)\r\n\r\n onRenderCrossText?.(context, crossIndex)\r\n }\r\n\r\n const domainRange = paneModel.scale.y\r\n .domain()\r\n .slice()\r\n .sort((a, b) => a - b)\r\n\r\n if (price === null || !(domainRange[0] <= price && price <= domainRange[1])) {\r\n return isXAxisInView\r\n }\r\n\r\n const priceFy = paneModel.scale.y(price)\r\n const y = Math.round(priceFy + settings.top.height)\r\n new Line(\r\n {\r\n x1: settings.left.width,\r\n x2: settings.left.width + contentWidth,\r\n y1: y,\r\n y2: y,\r\n strokeStyle: Colors.cross,\r\n },\r\n paneModel\r\n ).render(context)\r\n const YAxisLeftMargin = quote.instrument === Instrument.Crypto && quote.lastClose <= 0.001 ? 3 : 8\r\n\r\n const getCrossText = () => {\r\n if (chartModel.scale === ScaleType.Percentage && !isIndicator) {\r\n return `${math.round({\r\n value: getPercentageFromValue({ number: price, base: chartModel.firstBarClose }),\r\n lastClose: quote.lastClose,\r\n instrument: quote.instrument,\r\n overridePlaces: 2,\r\n })}%`\r\n }\r\n return `${math.round({\r\n value: price,\r\n lastClose: quote.lastClose,\r\n instrument: quote.instrument,\r\n overridePlaces: getRoundDecimalPlaces?.(price) ?? (paneModel.getIsChartPane() ? undefined : 2),\r\n })}${isPerfIndicator ? '%' : ''}`\r\n }\r\n\r\n new Text(\r\n {\r\n text: getCrossText(),\r\n x:\r\n settings.left.width +\r\n settings.right.axis.margin.left! +\r\n contentWidth +\r\n (isIndicator ? OFFSET.S : YAxisLeftMargin - PADDING.XXS),\r\n padding: isIndicator\r\n ? Text.getMergedPropsWithDefaults('padding', IndicatorSettings.right.axis.font.padding)\r\n : {\r\n top: PADDING.XXS,\r\n right: PADDING.XXS,\r\n bottom: PADDING.XXS,\r\n left: PADDING.XXS,\r\n },\r\n ...{\r\n y,\r\n textBaseline: TextBaseline.middle,\r\n fillStyle: Colors.crossText,\r\n background: Colors.crossTextBackground,\r\n font: Text.getMergedPropsWithDefaults('font', { ...settings.right.axis.font, style: 'bold' }),\r\n lineHeight: settings.right.axis.font.lineHeight,\r\n },\r\n },\r\n paneModel\r\n ).render(context)\r\n\r\n return true\r\n}\r\n\r\n/**\r\n * Set canvas width and height to 0 which fixes Safari memory problems\r\n *\r\n * @see https://stackoverflow.com/questions/52532614/total-canvas-memory-use-exceeds-the-maximum-limit-safari-12\r\n */\r\nexport function unmountCanvas(canvas?: HTMLCanvasElement | null) {\r\n if (!canvas) return\r\n\r\n canvas.width = 0\r\n canvas.height = 0\r\n canvas.style.width = '0px'\r\n canvas.style.height = '0px'\r\n}\r\n\r\nexport function getChangeColor({ change, ChartSettings }: { change: number; ChartSettings: IChartSettings }) {\r\n const { Colors } = ChartSettings.general\r\n if (change === 0) {\r\n return Colors.zeroChange\r\n }\r\n return change > 0 ? Colors.positiveChange : Colors.negativeChange\r\n}\r\n\r\nexport function round({ data, num, overridePlaces }: { data: Quote; num: number; overridePlaces?: number }) {\r\n return math.round({\r\n value: num,\r\n lastClose: data.lastClose,\r\n instrument: data.instrument,\r\n overridePlaces: overridePlaces,\r\n })\r\n}\r\n\r\nexport interface ITickerChange {\r\n points: number\r\n string: string\r\n percentString: string\r\n}\r\ninterface ITickerChangeResult {\r\n tickerChange: ITickerChange | null\r\n tickerAfterChange: ITickerChange | null\r\n}\r\n\r\nexport function getTickerChangeFromCloseValues({\r\n anchorClose,\r\n prevClose,\r\n data,\r\n}: {\r\n anchorClose: number\r\n prevClose: number\r\n data: Quote\r\n}): ITickerChange {\r\n const changePoints = anchorClose - prevClose\r\n const changePercent = (anchorClose / prevClose - 1) * 100\r\n const sign = changePoints < 0 ? '-' : changePoints > 0 ? '+' : ''\r\n const changePercentString = `${round({\r\n data,\r\n num: Math.abs(changePercent),\r\n overridePlaces: 2,\r\n })}%`\r\n const changePointsString = `${sign}${round({\r\n data,\r\n num: Math.abs(changePoints),\r\n })} (${changePercentString})`\r\n\r\n return {\r\n points: changePoints,\r\n string: changePointsString,\r\n percentString: `${sign}${changePercentString}`,\r\n }\r\n}\r\nexport function getTickerChange({ data }: { data: Quote }) {\r\n const result: ITickerChangeResult = { tickerChange: null, tickerAfterChange: null }\r\n const isChange = Number.isFinite(data.prevClose) // if not new stock always present\r\n if (isChange) {\r\n result.tickerChange = getTickerChangeFromCloseValues({\r\n data,\r\n anchorClose: data.lastClose,\r\n prevClose: data.prevClose,\r\n })\r\n }\r\n\r\n const isAfterChange = Number.isFinite(data.afterClose) && data.afterClose !== data.lastClose\r\n if (isAfterChange) {\r\n const tickerAfterChange = getTickerChangeFromCloseValues({\r\n data,\r\n anchorClose: data.afterClose,\r\n prevClose: data.lastClose,\r\n })\r\n result.tickerAfterChange = {\r\n ...tickerAfterChange,\r\n string: `AH: ${tickerAfterChange.string}`,\r\n }\r\n }\r\n\r\n return result\r\n}\r\n\r\nexport function isForexFuturesCryptoPage(specificChartFunctionality: SpecificChartFunctionality) {\r\n return [\r\n SpecificChartFunctionality.forexPage,\r\n SpecificChartFunctionality.cryptoPage,\r\n SpecificChartFunctionality.futuresPage,\r\n ].includes(specificChartFunctionality)\r\n}\r\n\r\nexport function isQuoteForexFuturesCryptoPage(specificChartFunctionality: SpecificChartFunctionality) {\r\n return (\r\n isForexFuturesCryptoPage(specificChartFunctionality) ||\r\n specificChartFunctionality === SpecificChartFunctionality.quotePage\r\n )\r\n}\r\n\r\nexport function getShouldUseDarkerWickColors({\r\n specificChartFunctionality,\r\n totalBarWidth,\r\n}: {\r\n specificChartFunctionality: SpecificChartFunctionality\r\n timeFrame?: TIMEFRAME\r\n totalBarWidth: number\r\n}) {\r\n const isForexFuturesCrypto = isForexFuturesCryptoPage(specificChartFunctionality)\r\n const isOffscreenChartWithNarrowBars =\r\n specificChartFunctionality === SpecificChartFunctionality.offScreen && totalBarWidth < 5\r\n const isQuoteChartWithNarrowBars =\r\n specificChartFunctionality === SpecificChartFunctionality.quotePage && totalBarWidth < 5\r\n\r\n return isForexFuturesCrypto || isOffscreenChartWithNarrowBars || isQuoteChartWithNarrowBars\r\n}\r\n\r\nexport const DRAWING_COOKIE_NAME = 'charts-draw'\r\nexport function getIsDrawingEnabled() {\r\n return Utils.getCookie(DRAWING_COOKIE_NAME) === 'on'\r\n}\r\n\r\nexport function setIsDrawingEnabled(value: boolean) {\r\n const expires = new Date()\r\n expires.setMonth(expires.getMonth() + 1)\r\n Utils.setCookie(DRAWING_COOKIE_NAME, value ? 'on' : 'off', expires)\r\n}\r\n\r\nexport function getIsSidebarEnabled(specificChartFunctionality?: SpecificChartFunctionality) {\r\n return specificChartFunctionality === SpecificChartFunctionality.chartPage\r\n}\r\n\r\nexport const handleTypeChange = ({\r\n type,\r\n chartLayoutModel,\r\n}: {\r\n type: ChartElementType\r\n chartLayoutModel: ChartLayoutModel\r\n}) => {\r\n const elements = chartLayoutModel.getAllElements()\r\n elements.forEach((element) => {\r\n if (element.isChart() && element.instance.attrs.type !== type) {\r\n const pane = element.pane()\r\n const instance = chartsByType[type].fromObject(\r\n {\r\n ...element.instance.attrs,\r\n type,\r\n },\r\n pane\r\n )\r\n element.replace(instance)\r\n }\r\n })\r\n}\r\n\r\nexport const getIsPreserveDrawingsAndAutosaveAvailable = (args: {\r\n specificChartFunctionality: SpecificChartFunctionality\r\n editable: boolean\r\n editors: ChartEditorEnum[]\r\n}) => {\r\n const { specificChartFunctionality, editable, editors } = args\r\n\r\n return (\r\n editable &&\r\n editors?.includes(ChartEditorEnum.tools) &&\r\n specificChartFunctionality &&\r\n [\r\n SpecificChartFunctionality.chartPage,\r\n SpecificChartFunctionality.quotePage,\r\n SpecificChartFunctionality.forexPage,\r\n SpecificChartFunctionality.futuresPage,\r\n SpecificChartFunctionality.cryptoPage,\r\n ].includes(specificChartFunctionality)\r\n )\r\n}\r\n\r\nexport function getQuoteFinancialAttachmentsFromChartConfig({ panes }: Pick) {\r\n return panes.flatMap((pane) =>\r\n pane.elements?.flatMap(\r\n (element) => indicatorsByType[element.type as IndicatorType]?.config.quoteFinancialAttachments ?? []\r\n )\r\n )\r\n}\r\n","/**\r\n * Keep this file in sync with `Website/js/main/components/color-picker/util.ts` in website repo\r\n * */\r\n\r\nexport interface RGBA {\r\n r: number\r\n g: number\r\n b: number\r\n a: number\r\n}\r\n\r\nexport interface HSVA {\r\n h: number\r\n s: number\r\n v: number\r\n a: number\r\n}\r\n\r\nexport interface HSLA {\r\n h: number\r\n s: number\r\n l: number\r\n a: number\r\n}\r\n\r\n/**\r\n * Convert Hex string to RGBA object.\r\n * @see https://css-tricks.com/converting-color-spaces-in-javascript/\r\n *\r\n * Input: color in hex3, hex4, hex6 or hex8 format (#fff)\r\n *\r\n * Output: { r: [0,255], g: [0,255], b: [0,255], a: [0,1]}\r\n */\r\nexport function hexStringToRGBA(hexString: string): RGBA {\r\n const hexColor = removeHashSymbol(hexString)\r\n let r: string | number = 0\r\n let g: string | number = 0\r\n let b: string | number = 0\r\n let a: string | number = 255\r\n\r\n // 3 digits\r\n if (hexColor.length === 3 || hexColor.length === 4) {\r\n r = '0x' + hexColor[0] + hexColor[0]\r\n g = '0x' + hexColor[1] + hexColor[1]\r\n b = '0x' + hexColor[2] + hexColor[2]\r\n // Get channel if defined\r\n a = hexColor.length === 4 ? '0x' + hexColor[3] + hexColor[3] : a\r\n\r\n // 6 digits\r\n } else if (hexColor.length === 6 || hexColor.length === 8) {\r\n r = '0x' + hexColor[0] + hexColor[1]\r\n g = '0x' + hexColor[2] + hexColor[3]\r\n b = '0x' + hexColor[4] + hexColor[5]\r\n // Get channel if defined\r\n a = hexColor.length === 8 ? '0x' + hexColor[6] + hexColor[7] : a\r\n }\r\n\r\n return { r: Number(r), g: Number(g), b: Number(b), a: Math.min(Math.round((Number(a) / 255) * 100) / 100, 1) }\r\n}\r\n\r\n/**\r\n * Convert HEX string to HSVA color representation.\r\n *\r\n * Input: color in hex3, hex4, hex6 or hex8 format (#fff)\r\n *\r\n * Output: { h: [0,360], s: [0,1], v: [0,1], a: [0,1]}\r\n */\r\nexport function hexStringToHSVA(hexString: string) {\r\n return rgbaToHSVA(hexStringToRGBA(hexString))\r\n}\r\n\r\n/**\r\n * Convert HEX string to HSLA color representation.\r\n *\r\n * Input: color in hex3, hex4, hex6 or hex8 format (#fff)\r\n *\r\n * Output: { h: [0,360], s: [0,1], l: [0,1], a: [0,1]}\r\n */\r\nexport function hexStringToHSLA(hexString: string) {\r\n return rgbaToHSLA(hexStringToRGBA(hexString))\r\n}\r\n\r\n/**\r\n * Convert alpha value to hex value\r\n *\r\n * Input: [0,1]\r\n *\r\n * Output: alpha in HEX format\r\n */\r\nexport function alphaToHex(alpha: number) {\r\n return Math.max(Math.min(Math.round(alpha * 255), 255), 0)\r\n .toString(16)\r\n .padStart(2, '0')\r\n}\r\n\r\n/**\r\n * Convert RGBA color to HEX string.\r\n *\r\n * Input: { r: [0,255], g: [0,255], b: [0,255], a: [0,1]}\r\n *\r\n * Output: color in hex6 or hex8 depending on whether or not alpha is enabled\r\n */\r\nexport function rgbaToHexString(color: RGBA, alpha = false) {\r\n const r = color.r.toString(16)\r\n const g = color.g.toString(16)\r\n const b = color.b.toString(16)\r\n const hexString = '#' + r.padStart(2, '0') + g.padStart(2, '0') + b.padStart(2, '0')\r\n\r\n if (!alpha || color.a === 1) {\r\n return hexString\r\n }\r\n\r\n return `${hexString}${alphaToHex(color.a)}`\r\n}\r\n\r\n/**\r\n * Convert HSVA object to HEX string\r\n *\r\n * @see https://css-tricks.com/converting-color-spaces-in-javascript/\r\n *\r\n * Input: { h: [0,360], s: [0,1], v: [0,1], a: [0,1]}\r\n *\r\n * Output: { r: [0,255], g: [0,255], b: [0,255], a: [0,1]}\r\n */\r\nexport function hsvaToHEXString(color: HSVA, alpha = false) {\r\n const rgbaColor = hsvaToRGBA(color)\r\n\r\n return rgbaToHexString(rgbaColor, alpha)\r\n}\r\n\r\n/**\r\n * Convert HSLA object to HEX string\r\n *\r\n * @see https://css-tricks.com/converting-color-spaces-in-javascript/\r\n *\r\n * Input: { h: [0,360], s: [0,1], l: [0,1], a: [0,1]}\r\n *\r\n * Output: { r: [0,255], g: [0,255], b: [0,255], a: [0,1]}\r\n */\r\nexport function hslaToHexString(color: HSLA, alpha = false) {\r\n const rgbaColor = hslaToRGBA(color)\r\n\r\n return rgbaToHexString(rgbaColor, alpha)\r\n}\r\n\r\n/**\r\n * Convert RGBA color to HSVA\r\n * @see https://stackoverflow.com/a/54070620/6662683\r\n *\r\n * Input: { r: [0,255], g: [0,255], b: [0,255], a: [0,1]}\r\n *\r\n * Output: { h: [0,360], s: [0,1], v: [0,1], a: [0,1]}\r\n */\r\nexport function rgbaToHSVA(color: RGBA): HSVA {\r\n const r = color.r / 255\r\n const g = color.g / 255\r\n const b = color.b / 255\r\n\r\n const v = Math.max(r, g, b)\r\n const c = v - Math.min(r, g, b)\r\n const h = c && (v === r ? (g - b) / c : v === g ? 2 + (b - r) / c : 4 + (r - g) / c)\r\n\r\n return {\r\n h: 60 * (h < 0 ? h + 6 : h),\r\n s: v ? c / v : 0,\r\n v: v,\r\n a: color.a,\r\n }\r\n}\r\n\r\n/**\r\n * Convert RGBA to HSLA\r\n * @see https://stackoverflow.com/a/54071699/6662683\r\n *\r\n * Input: { r: [0,255], g: [0,255], b: [0,255], a: [0,1]}\r\n *\r\n * Output: { h: [0,360], s: [0,1], l: [0,1], a: [0,1]}\r\n */\r\nexport function rgbaToHSLA(color: RGBA): HSLA {\r\n const r = color.r / 255\r\n const g = color.g / 255\r\n const b = color.b / 255\r\n\r\n const v = Math.max(r, g, b)\r\n const c = v - Math.min(r, g, b)\r\n const f = 1 - Math.abs(v + v - c - 1)\r\n const h = c && (v === r ? (g - b) / c : v === g ? 2 + (b - r) / c : 4 + (r - g) / c)\r\n\r\n return {\r\n h: 60 * (h < 0 ? h + 6 : h),\r\n s: f ? c / f : 0,\r\n l: (v + v - c) / 2,\r\n a: color.a,\r\n }\r\n}\r\n\r\n/**\r\n * Convert HSVA color to RGBA\r\n * @see https://stackoverflow.com/a/54024653/6662683\r\n *\r\n * Input: { h: [0,360], s: [0,1], v: [0,1], a: [0,1]}\r\n *\r\n * Output: { r: [0,255], g: [0,255], b: [0,255], a: [0,1]}\r\n */\r\nexport function hsvaToRGBA(color: HSVA): RGBA {\r\n const f = (n: number, k = (n + color.h / 60) % 6) => color.v - color.v * color.s * Math.max(Math.min(k, 4 - k, 1), 0)\r\n\r\n return {\r\n r: Math.round(f(5) * 255),\r\n g: Math.round(f(3) * 255),\r\n b: Math.round(f(1) * 255),\r\n a: Math.round(color.a * 100) / 100,\r\n }\r\n}\r\n\r\n/**\r\n * Convert HSLA color to RGBA\r\n * @see https://stackoverflow.com/a/54014428/6662683\r\n *\r\n * Input: { h: [0,360], s: [0,1], l: [0,1], a: [0,1]}\r\n *\r\n * Output: { r: [0,255], g: [0,255], b: [0,255], a: [0,1]}\r\n */\r\nexport function hslaToRGBA(color: HSLA): RGBA {\r\n const a = color.s * Math.min(color.l, 1 - color.l)\r\n const f = (n: number, k = (n + color.h / 30) % 12) => color.l - a * Math.max(Math.min(k - 3, 9 - k, 1), -1)\r\n\r\n return {\r\n r: Math.round(f(0) * 255),\r\n g: Math.round(f(8) * 255),\r\n b: Math.round(f(4) * 255),\r\n a: color.a,\r\n }\r\n}\r\n\r\n/**\r\n * Convert RGBA color to rgba() string\r\n *\r\n * Input: { r: [0,255], g: [0,255], b: [0,255], a: [0,1]}\r\n *\r\n * Output: rgba(r, g, b, a)\r\n */\r\nexport function rgbaToRGBAString(color: RGBA) {\r\n return `rgba(${color.r}, ${color.g}, ${color.b}, ${color.a})`\r\n}\r\n\r\n/**\r\n * Convert rgba() string to RGBA color\r\n *\r\n * Input: rgba(r, g, b, a)\r\n *\r\n * Output: { r: [0,255], g: [0,255], b: [0,255], a: [0,1]}\r\n */\r\nexport function rgbaStringToObject(color: string) {\r\n const colorParts = /^rgba?\\(([0-9]{1,3})[ ,]+([0-9]{1,3})[ ,]+([0-9]{1,3})[ ,]*([01].?[0-9]*)?\\)$/.exec(color)\r\n const [red, green, blue, alpha = '1'] = colorParts?.slice(1) || [0, 0, 0, 1].map(String)\r\n return {\r\n r: Number.parseInt(red),\r\n g: Number.parseInt(green),\r\n b: Number.parseInt(blue),\r\n a: Number.parseFloat(alpha),\r\n }\r\n}\r\n\r\n/**\r\n * Convert HSLA color to hsla() string\r\n *\r\n * Input: { h: [0,360], s: [0,1], l: [0,1], a: [0,1]}\r\n *\r\n * Output: hsla(h, s, l, a)\r\n */\r\nexport function hslaToHSLAString(color: HSLA) {\r\n return `hsla(${Math.round(color.h)}, ${Math.round(color.s * 10000) / 100}%, ${Math.round(color.l * 10000) / 100}%, ${\r\n color.a\r\n })`\r\n}\r\n\r\nexport function removeHashSymbol(strColor: string) {\r\n return strColor.replace(/#/g, '')\r\n}\r\n\r\n/**\r\n * Check if the param is a valid color by setting it as style\r\n */\r\nexport function isValidColor(strColor: string) {\r\n const isRgb = strColor.startsWith('rgba')\r\n const s = new Option().style\r\n\r\n s.color = isRgb ? strColor : `#${removeHashSymbol(strColor)}`\r\n\r\n return s.color !== ''\r\n}\r\n\r\n/**\r\n * Normalize color to be a hex value\r\n */\r\nexport function convertColorToHEX(strColor: string, allowAlpha = true) {\r\n const isRgb = getIsRgb(strColor)\r\n const hexColor = isRgb ? rgbaToHexString(rgbaStringToObject(strColor), allowAlpha) : strColor\r\n\r\n if (allowAlpha) {\r\n return hexColor\r\n }\r\n return hexColor.slice(0, 7)\r\n}\r\n\r\n/**\r\n * Returns true if color is rgb or rgba\r\n */\r\nexport function getIsRgb(strColor: string, isAlphaAllowed = true) {\r\n const rgbKeys = ['rgb']\r\n if (isAlphaAllowed) {\r\n rgbKeys.push('rgba')\r\n }\r\n return rgbKeys.some((startsWith) => strColor.startsWith(startsWith))\r\n}\r\n\r\n/**\r\n * Convert any color format to HSVA (internal color picker representation)\r\n */\r\nexport function getHSVAFromColor(strColor: string) {\r\n if (getIsRgb(strColor)) {\r\n return rgbaToHSVA(rgbaStringToObject(strColor))\r\n }\r\n\r\n return hexStringToHSVA(strColor)\r\n}\r\n\r\n/**\r\n * Stringify HSVA color representation into a output format\r\n */\r\nexport function stringifyHSVAColor(color: HSVA, output: 'rgba' | 'hex', canSelectAlpha?: boolean) {\r\n switch (output) {\r\n case 'rgba':\r\n return rgbaToRGBAString(hsvaToRGBA(color))\r\n default:\r\n return hsvaToHEXString(color, canSelectAlpha)\r\n }\r\n}\r\n\r\n/**\r\n * Get luma value from RGBA color using the Rec. 709 coefficients\r\n * @see https://en.wikipedia.org/wiki/Luma_%28video%29\r\n *\r\n * If luma is >= 165 the foreground color should be dark\r\n */\r\nexport function getLumaFromRGBA(color: RGBA) {\r\n return 0.2126 * color.r + 0.7152 * color.g + 0.0722 * color.b\r\n}\r\n\r\n/**\r\n * Checks if luma is >= 165 or alpha < 0.3\r\n */\r\nexport function getIsColorTooLightOrTransparent(color: RGBA) {\r\n return getLumaFromRGBA(color) >= 165 || color.a < 0.5\r\n}\r\n\r\n/**\r\n * Set specific alpha for a hex color\r\n */\r\nexport function getHEXWithSpecificAplha(color: string, alpha = 1) {\r\n const rgbaColor = hexStringToRGBA(color)\r\n return rgbaToHexString({ ...rgbaColor, a: alpha }, true)\r\n}\r\n\r\n/**\r\n * Get rgba from valid color string\r\n */\r\nexport function getRGBAValueFromValidColorString(value: string) {\r\n if (getIsRgb(value)) return rgbaToRGBAString(rgbaStringToObject(value))\r\n return rgbaToRGBAString(hexStringToRGBA(value))\r\n}\r\n","// if conditionalCursor provided, cursor is set only if current cursor !== conditionalCursor\r\n// otherwise cursor is set if element exists\r\nexport const setElementCursor = ({\r\n elementId,\r\n cursor,\r\n conditionalCursor,\r\n}: {\r\n elementId: string\r\n cursor: string\r\n conditionalCursor?: string\r\n}) => {\r\n const element = document.getElementById(elementId)\r\n if (element && (conditionalCursor ? element.style.cursor !== conditionalCursor : true)) {\r\n element.style.cursor = cursor\r\n }\r\n}\r\n","/*\r\n * We want to be able to render only bars/parts of line that are visible to users,\r\n * but without introducing visual artifacts like bars missing in front of users while scrolling\r\n * or lines that start in middle of chart for sparse intraday stock data.\r\n *\r\n * In general we want to start rendering lines one bar sooner than what is visible to user and stop rendering\r\n * one bar outside of visible area to create a continuous line.\r\n */\r\nimport type Pane from '../models/pane'\r\nimport type Quote from '../models/quote'\r\nimport { getHalfBarWidth } from './chart'\r\n\r\ninterface IBarToRender {\r\n index: number\r\n isBarVisible: boolean\r\n}\r\n\r\nexport const drawInVisibleArea = ({\r\n drawBarCallback,\r\n fromIndexOffset = 0,\r\n fxOverride,\r\n leftOffset,\r\n paneModel,\r\n quote,\r\n toIndexOffset = 0,\r\n width,\r\n}: {\r\n drawBarCallback: (i: number, x: number) => void\r\n fromIndexOffset?: number\r\n fxOverride?: (index: number) => number\r\n leftOffset: number\r\n paneModel: Pane\r\n quote: Quote\r\n toIndexOffset?: number\r\n width: number\r\n}) => {\r\n const fx = fxOverride ?? ((index: number) => paneModel.scale.x(quote.barIndex[index]))\r\n\r\n // We want to start rendering one bar outside of the visible area for two reasons:\r\n // 1. To create a seamless transition for bars entering/leaving the view, avoiding them from\r\n // abruptly dis/appearing when half the bar is outside.\r\n // 2. To prevent disconnected lines in case there's a bar gap.\r\n // However, if a `fromIndex` is provided and it's higher than the first visible bar,\r\n // we need to start rendering from that specific index. This ensures correct starting\r\n // points for elements like indicators that rely on this value.\r\n const firstBarToRenderIndex = getCompensatedFirstBarToRenderIndex({ quote, paneModel, leftOffset, fromIndexOffset })\r\n\r\n let lastBarToRender = -1\r\n for (let i = firstBarToRenderIndex; i < quote.close.length + toIndexOffset; i++) {\r\n const x = fx(i)\r\n if (x + leftOffset > width) {\r\n lastBarToRender = i\r\n break\r\n }\r\n drawBarCallback(i, x)\r\n }\r\n\r\n if (lastBarToRender > -1) {\r\n const x = fx(lastBarToRender)\r\n drawBarCallback(lastBarToRender, x)\r\n }\r\n}\r\n\r\n/**\r\n * Get first or last visible bar index.\r\n * IMPORTANT: If chartWidth provided return is lastVisibleBarIndex\r\n */\r\nexport function getVisibleBarToRenderIndex({\r\n chartWidth,\r\n leftOffset,\r\n paneModel,\r\n quote,\r\n}: {\r\n chartWidth?: number\r\n leftOffset: number\r\n paneModel: Pane\r\n quote: Quote\r\n}) {\r\n const chartModel = paneModel.chart()\r\n\r\n // not all the time there is bar present on barIndex calculated via inverted leftOffset\r\n // there might be a gap between bars, if there is, barToDataIndex on that gap spot will have value of\r\n // previous bar which isn't visible\r\n\r\n const barIndex = Math.round(paneModel.scale.x.invert(-leftOffset + (chartWidth !== undefined ? chartWidth : 0)))\r\n const dataBarIndex = quote.barToDataIndex[Math.min(Math.max(barIndex, 0), quote.barToDataIndex.length - 1)]\r\n const halfBarWidth = getHalfBarWidth(chartModel, false)\r\n\r\n const isBarVisible = Math.round(paneModel.scale.x(quote.barIndex[dataBarIndex]) + halfBarWidth) + leftOffset > 0\r\n\r\n return {\r\n barIndex,\r\n index:\r\n chartWidth === undefined\r\n ? isBarVisible\r\n ? dataBarIndex\r\n : Math.max(Math.min(dataBarIndex + 1, quote.barIndex.length - 1), 0)\r\n : dataBarIndex,\r\n isBarVisible,\r\n }\r\n}\r\n\r\n// Get first bar to render compensated for fromIndexOffset\r\nexport function getCompensatedFirstBarToRenderIndex({\r\n fromIndexOffset = 0,\r\n leftOffset,\r\n paneModel,\r\n quote,\r\n}: {\r\n fromIndexOffset?: number\r\n leftOffset: number\r\n paneModel: Pane\r\n quote: Quote\r\n}) {\r\n return Math.max(0, getVisibleBarToRenderIndex({ quote, leftOffset, paneModel }).index - 1, fromIndexOffset)\r\n}\r\n\r\n/**\r\n * Checks if there are no visible bars between the specified first and last bars to render.\r\n * IMPORTANT: Provided indexes should be without bar gap compensation.\r\n *\r\n * @param {IBarToRender} firstBarToRenderIndex The index of the first bar to render.\r\n * @param {IBarToRender} lastBarToRenderIndex The index of the last bar to render.\r\n * @returns {boolean} True if there are no visible bars between the first and last bars, false otherwise.\r\n */\r\nexport function getAreNoBarsVisible(firstBarToRenderIndex: IBarToRender, lastBarToRenderIndex: IBarToRender): boolean {\r\n return !firstBarToRenderIndex.isBarVisible && !lastBarToRenderIndex.isBarVisible\r\n}\r\n","import queryString from 'query-string'\r\n\r\nimport { ObjectHash } from '../../types/shared'\r\n\r\ninterface FetchApiProps {\r\n location: string\r\n queryParameters?: ObjectHash\r\n method?: string\r\n body?: RequestInit['body']\r\n contentType?: ContentType\r\n abortController?: null | AbortController\r\n throwOnStatusCodes?: number[]\r\n throwOnPredicate?: (response: Response) => boolean\r\n keepalive?: boolean\r\n}\r\n\r\nexport const getFormDataFromObject = (object: ObjectHash) =>\r\n Object.keys(object).reduce((formData, key) => {\r\n formData.append(key, object[key])\r\n return formData\r\n }, new FormData())\r\n\r\n// Keep in sync with ContentType in https://github.com/finvizhq/Finviz-Website/blob/master/Website/js/main/services/api.ts\r\n// START\r\nexport enum ContentType {\r\n ApplicationJson = 'application/json',\r\n ApplicationJsonUTF = 'application/json; charset=utf-8', // WriteAsJsonAsync\r\n FormUrlEncoded = 'application/x-www-form-urlencoded',\r\n Html = 'text/html; charset=utf-8',\r\n}\r\n\r\nfunction parseResponseForContentType(response: string, contentType: ContentType) {\r\n switch (contentType) {\r\n case ContentType.ApplicationJson:\r\n case ContentType.ApplicationJsonUTF:\r\n case ContentType.FormUrlEncoded:\r\n return JSON.parse(response)\r\n default:\r\n return response\r\n }\r\n}\r\n// END\r\n\r\nconst fetchApi = async ({\r\n location,\r\n queryParameters,\r\n method,\r\n body,\r\n contentType,\r\n abortController,\r\n throwOnStatusCodes,\r\n throwOnPredicate,\r\n keepalive = false,\r\n}: FetchApiProps) => {\r\n const url = `${location}${queryParameters ? `?${queryString.stringify(queryParameters)}` : ''}`\r\n const parameters: RequestInit = {\r\n method: method || 'GET',\r\n credentials: 'include',\r\n headers: contentType && {\r\n 'Content-Type': contentType,\r\n },\r\n signal: abortController?.signal,\r\n body: body,\r\n keepalive,\r\n }\r\n try {\r\n const response = await fetch(url, parameters)\r\n const responseContentType: ContentType = (response.headers.get('Content-Type') as any) ?? ContentType.Html\r\n const responseData = parseResponseForContentType(await response.text(), responseContentType)\r\n if (throwOnStatusCodes?.includes(response.status) || throwOnPredicate?.(response)) {\r\n const StatusCodeError = getStatusCodeError(response.status)\r\n throw new StatusCodeError(`${url} returned ${response.status}`, responseData as T, response.status)\r\n }\r\n return responseData as T\r\n } catch (err) {\r\n throw err\r\n }\r\n}\r\n\r\nfunction getStatusCodeError(statusCode: number): typeof GenericStatusCodeError {\r\n switch (statusCode) {\r\n case 403:\r\n return ForbiddenError\r\n case 404:\r\n return NotFoundError\r\n case 410:\r\n return GoneError\r\n case 500:\r\n return InternalServerError\r\n default:\r\n return GenericStatusCodeError\r\n }\r\n}\r\n\r\nexport class GenericStatusCodeError extends Error {\r\n response: ObjectHash | string\r\n statusCode: number\r\n\r\n constructor(message: string, response: ObjectHash | string, statusCode: number) {\r\n super(message)\r\n this.response = response\r\n this.statusCode = statusCode\r\n }\r\n}\r\nexport class ForbiddenError extends GenericStatusCodeError {}\r\nexport class NotFoundError extends GenericStatusCodeError {}\r\nexport class InternalServerError extends GenericStatusCodeError {}\r\nexport class GoneError extends GenericStatusCodeError {}\r\n\r\nexport default fetchApi\r\n","import React from 'react'\r\n\r\nexport function useForceUpdate() {\r\n const [forceUpdateKey, increment] = React.useState(0)\r\n const forceUpdate = React.useCallback(() => {\r\n increment((prev) => prev + 1)\r\n }, [])\r\n return { forceUpdate, forceUpdateKey }\r\n}\r\n","import { EmptyObject, ObjectHash } from '../../types/shared'\r\n\r\nexport function getRoundedString({ number, numOfDecimalPlaces }: { number: number; numOfDecimalPlaces: number }) {\r\n const precision = Math.pow(10, numOfDecimalPlaces)\r\n return String(Math.round(number * precision) / precision)\r\n}\r\n\r\nexport function getIsSSr() {\r\n return typeof process !== 'undefined' && !!process?.env.IS_OFFSCREEN_RENDERER\r\n}\r\n\r\nexport function isValidHexColor(color: string) {\r\n const regex = /^#([\\da-f]{3}){1,2}$|^#([\\da-f]{4}){1,2}$/i\r\n return !!color && regex.test(color)\r\n}\r\n\r\nexport function getParsedIntegersFromPeriodString(periodString: string) {\r\n const periodParts = periodString.split(',')\r\n return periodParts.map((part) => Number.parseInt(part, 10))\r\n}\r\n\r\nexport function captureException(exception: Error, captureContext?: { extra: ObjectHash }) {\r\n if (process.env.NODE_ENV === 'development' || process.env.IS_E2E_TESTING) {\r\n console.error(exception)\r\n } else if (process.env.IS_OFFSCREEN_RENDERER) {\r\n import('@sentry/node').then((client) => {\r\n client.captureException(exception, captureContext)\r\n })\r\n } else {\r\n window.Sentry.captureException(exception, captureContext)\r\n }\r\n}\r\n\r\nexport function isPositiveFloat(value: string | number) {\r\n const parsedNumber = Number.parseFloat(`${value}`)\r\n return !Number.isNaN(parsedNumber) && isFinite(parsedNumber) && parsedNumber > 0\r\n}\r\n\r\nexport function isPositiveInteger(value: string | number) {\r\n const string = `${value}`\r\n return isPositiveFloat(value) && Number.parseInt(string, 10) === Number.parseFloat(string)\r\n}\r\n\r\nexport function isInRange({\r\n value,\r\n min = Number.MIN_SAFE_INTEGER,\r\n max = Number.MAX_SAFE_INTEGER,\r\n}: {\r\n value: string | number\r\n min?: number\r\n max?: number\r\n}) {\r\n const parsedNumber = Number.parseFloat(`${value}`)\r\n return !Number.isNaN(parsedNumber) && parsedNumber >= min && parsedNumber <= max\r\n}\r\n\r\nexport function tryJsonParse(json: string | null = '') {\r\n try {\r\n return JSON.parse(json ?? '') as Result\r\n } catch {\r\n return null\r\n }\r\n}\r\n\r\nexport function getValueInRange({ value, min, max }: { value: number; min: number; max: number }) {\r\n return Math.min(Math.max(value, min), max)\r\n}\r\n\r\nexport function isPrimaryClick(e: React.Touch | React.TouchEvent | React.MouseEvent) {\r\n // cypress trigger mouseevent has button: undefined if button option isn't explicitly specified\r\n // as cy.get('.target').trigger('mousedown', { button: 0 })\r\n if (e.hasOwnProperty('button') && (e as unknown as MouseEvent).button !== undefined) {\r\n return (e as unknown as MouseEvent).button === 0\r\n } else {\r\n return true\r\n }\r\n}\r\n\r\n// this function is used to fix the issue with circular reference when stringifying an object using JSON.stringify\r\nexport function getJSONReplacerFunc() {\r\n const visited = new WeakSet()\r\n return (key: string, value: any) => {\r\n if (typeof value === 'object' && value !== null) {\r\n if (visited.has(value)) {\r\n return\r\n }\r\n visited.add(value)\r\n }\r\n return value\r\n }\r\n}\r\n\r\n// This is a duplicate from Website repo which is accessible on window.FLibs but this doesn't work on SSR charts\r\nexport const formatDateToStringUS = (date: Date, options?: Intl.DateTimeFormatOptions | undefined) =>\r\n date.toLocaleDateString('en-US', {\r\n day: '2-digit',\r\n month: '2-digit',\r\n year: 'numeric',\r\n ...options,\r\n })\r\n\r\n// randomUUID source: https://stackoverflow.com/questions/105034/how-do-i-create-a-guid-uuid/2117523#2117523\r\nexport function randomUUID() {\r\n return `${1e7}-${1e3}-${4e3}-${8e3}-${1e11}`.replace(/[018]/g, (substring) => {\r\n const c = Number(substring)\r\n return (c ^ (crypto.getRandomValues(new Uint8Array(1))[0] & (15 >> (c / 4)))).toString(16)\r\n })\r\n}\r\n\r\nexport function getUuid() {\r\n return window.crypto?.randomUUID?.() ?? randomUUID()\r\n}\r\n\r\n// duplicate from Website/js/app/header/utils.ts , will be refactored in next PR\r\nexport function getEarningsDateSuffix(date: Date) {\r\n const hours = date.getHours()\r\n\r\n if (hours <= 9) {\r\n return 'BMO'\r\n } else if (hours >= 16) {\r\n return 'AMC'\r\n }\r\n\r\n return ''\r\n}\r\n","export type HLC = {\r\n ts: number\r\n count: number\r\n uuid: string\r\n}\r\n\r\nexport const serializeHlc = ({ ts, count, uuid }: HLC) =>\r\n ts.toString().padStart(15, '0') + ':' + count.toString(36).padStart(5, '0') + ':' + uuid\r\n\r\nexport const parseHlc = (serialized: string) => {\r\n const [ts, count, uuid] = serialized.split(':')\r\n return {\r\n ts: Number.parseInt(ts),\r\n count: Number.parseInt(count, 36),\r\n uuid,\r\n }\r\n}\r\n\r\nexport const initHlc = (uuid: string, now: number): HLC => ({\r\n ts: now,\r\n count: 0,\r\n uuid,\r\n})\r\n\r\nexport const compareHlc = (one: HLC, two: HLC) => {\r\n if (one.ts === two.ts) {\r\n if (one.count === two.count) {\r\n if (one.uuid === two.uuid) {\r\n return 0\r\n }\r\n return one.uuid < two.uuid ? -1 : 1\r\n }\r\n return one.count - two.count\r\n }\r\n return one.ts - two.ts\r\n}\r\n\r\nexport const incrementHlc = (local: HLC, now: number): HLC => {\r\n if (now > local.ts) {\r\n return { ts: now, count: 0, uuid: local.uuid }\r\n }\r\n\r\n return { ...local, count: local.count + 1 }\r\n}\r\n\r\nexport const receiveHlc = (local: HLC, remote: HLC): HLC => {\r\n if (compareHlc(local, remote) >= 0) {\r\n return local\r\n }\r\n return { ...local, ts: remote.ts, count: remote.count }\r\n}\r\n","import { useChartLayoutGlobalModelAsyncModule } from '../controllers/chart-settings/async-modules'\r\nimport { useAsyncModule } from './async-modules-utils'\r\n\r\nexport function useChartLayoutGlobalModelAsync() {\r\n const [useChartLayoutGlobalModelModule] = useAsyncModule({\r\n ...useChartLayoutGlobalModelAsyncModule,\r\n isSuspenseMode: true,\r\n })\r\n return useChartLayoutGlobalModelModule.useChartLayoutGlobalModel()\r\n}\r\n","import { CanvasRenderingContext2D as NodeCanvasRenderingContext2D } from 'skia-canvas'\r\n\r\nimport {\r\n CanvasElementType,\r\n ChartEditorEnum,\r\n ChartElementType,\r\n ChartEventType,\r\n IndicatorType,\r\n LayoutType,\r\n OverlayType,\r\n ScaleType,\r\n SpecificChartFunctionality,\r\n TIMEFRAME,\r\n TextAlign,\r\n TextBaseline,\r\n} from '../app/constants/common'\r\nimport ChartModel from '../app/models/chart'\r\nimport ChartLayout from '../app/models/chart_layout'\r\nimport { IChartThemeColors } from '../app/models/constants'\r\n\r\ninterface ISentry {\r\n captureException: (exception: any, captureContext?: { extra: ObjectHash }) => any\r\n captureMessage: (message: string, captureContext?: { extra: ObjectHash }) => any\r\n}\r\n\r\ndeclare global {\r\n interface Window {\r\n Sentry: ISentry\r\n FinvizSettings: ObjectHash\r\n FinvizChartsSettings: ObjectHash\r\n globalChartConfig: RootChartConfigObject\r\n isRenderInProgress: boolean | number\r\n rendersInProgress: number[]\r\n FinvizQuoteTypeCurrent: string\r\n handleScriptNotLoaded: () => void\r\n renderScriptNotLoaded: () => void\r\n gtag?: any\r\n }\r\n\r\n interface Document {\r\n fullscreenElement: any\r\n webkitFullscreenElement?: () => void\r\n mozFullScreenElement?: () => void\r\n msFullscreenElement?: () => void\r\n\r\n webkitExitFullscreen?: () => void\r\n mozExitFullScreen?: () => void\r\n msExitFullscreen?: () => void\r\n }\r\n\r\n interface HTMLElement {\r\n webkitRequestFullScreen?: () => void\r\n mozRequestFullScreen?: () => void\r\n msRequestFullscreen?: () => void\r\n }\r\n\r\n interface Navigator {\r\n msMaxTouchPoints: any\r\n }\r\n\r\n interface Array {\r\n last(): T | undefined\r\n }\r\n\r\n interface String {\r\n padLeft(paddingValue: string): string\r\n startsWith(str: string): boolean\r\n }\r\n\r\n type CanvasCache = Partial>\r\n\r\n interface CanvasRenderingContext2D {\r\n _cache: CanvasCache\r\n // We need to omit `canvas` because it is read only\r\n set>(\r\n key: Key,\r\n value: CanvasRenderingContext2D[Key]\r\n ): void\r\n }\r\n\r\n interface HTMLCanvasElement {\r\n _cache: CanvasCache\r\n }\r\n\r\n interface ImageBitmapRenderingContext {\r\n _cache: CanvasCache\r\n }\r\n\r\n type RenderingContext2DType = CanvasRenderingContext2D | NodeCanvasRenderingContext2D\r\n}\r\n\r\ndeclare module 'skia-canvas' {\r\n interface CanvasRenderingContext2D {\r\n _cache: CanvasCache\r\n\r\n set>(\r\n key: Key,\r\n value: CanvasRenderingContext2D[Key]\r\n ): void\r\n }\r\n}\r\n\r\nexport type TodoObjectHashAnyType = Record\r\nexport type TodoAreaObject = Record\r\nexport type ObjectHash = Record\r\nexport type EmptyObject = Record\r\n\r\nexport type TodoAnyType = any\r\n\r\nexport type ThumbType = string\r\n\r\nexport type PaneArea = {\r\n mouseDown?: boolean\r\n x: number\r\n y: number\r\n scaled: {\r\n x: number\r\n y: number\r\n }\r\n width: number\r\n height: number\r\n cursorX: number\r\n cursorY: number\r\n isCursorInChartWidthBoundaries: boolean\r\n} & T\r\n\r\nexport type Maybe = T | null | undefined\r\n\r\nexport interface DrawingBorder {\r\n color: string\r\n width: number\r\n}\r\n\r\nexport interface TextAttrs {\r\n text?: string\r\n background: string\r\n border?: { width: number; color: string }\r\n lineWidth?: number\r\n font: {\r\n size: number\r\n family?: string\r\n style?: string\r\n weight?: string\r\n }\r\n fillStyle?: string\r\n strokeStyle?: string\r\n angle?: number\r\n lineHeight: number\r\n textAlign?: TextAlign\r\n textBaseline: TextBaseline\r\n padding: {\r\n top: number\r\n right: number\r\n bottom: number\r\n left: number\r\n }\r\n}\r\n\r\nexport interface Point {\r\n x: number\r\n y: number\r\n}\r\n\r\nexport type RequireByKey = Omit & Required>\r\n\r\nexport interface ResizeByThumbFuncProps {\r\n type: ThumbType\r\n difX: number\r\n difY: number\r\n area: PaneArea\r\n}\r\n\r\nexport type ResizeByThumbWithTypeAndDifs = RequireByKey\r\n\r\nexport interface ChartConfigChartPaneElement {\r\n type: ChartElementType | CanvasElementType | IndicatorType | OverlayType | ChartEventType\r\n overlays?: OverlayConfigObject[]\r\n period?: string\r\n code?: string\r\n elementId?: string | null\r\n zIndex?: number\r\n}\r\n\r\nexport interface RendererChartBarProps {\r\n index: number\r\n chartSettingsColors: IChartThemeColors\r\n hasFillAndBorder?: boolean\r\n}\r\n\r\nexport interface ChartConfigChartPane {\r\n elements: ChartConfigChartPaneElement[]\r\n height: number\r\n chart?: ChartConfigObject | ChartModel\r\n}\r\n\r\nexport interface IIdea {\r\n id?: number\r\n date?: string\r\n note: string\r\n}\r\n\r\nexport interface ChartConfigObjectExtended {\r\n editable: boolean\r\n canChangeTicker: boolean\r\n scrollable: boolean\r\n cross: boolean\r\n ideas: boolean\r\n editors: ChartEditorEnum[]\r\n specificChartFunctionality: SpecificChartFunctionality\r\n theme: Theme\r\n layout: LayoutType\r\n uuid?: string\r\n idea?: IIdea\r\n}\r\n\r\nexport interface ChartConfigObject {\r\n width: number\r\n height: number\r\n panes: ChartConfigChartPane[]\r\n premarket: boolean\r\n aftermarket: boolean\r\n dateRange: string | null\r\n hasChartEvents?: boolean\r\n stretch?: boolean\r\n ticker: string\r\n instrument: Instrument\r\n timeframe: TIMEFRAME\r\n chart_layout: ChartLayout\r\n zoomFactor: number\r\n leftOffset: number | null\r\n refreshData: boolean | number\r\n isHideDrawingsActive: boolean\r\n isScrolled?: boolean\r\n scale: ScaleType\r\n}\r\n\r\nexport type RootChartConfigObjectChart = Omit<\r\n ChartConfigObject,\r\n 'chart_layout' | 'leftOffset' | 'zoomFactor' | 'isHideDrawingsActive'\r\n>\r\nexport interface RootChartConfigObject extends Partial {\r\n charts: Array\r\n width: number\r\n height: number\r\n newCharts?: boolean\r\n useGrid?: boolean\r\n}\r\n\r\nexport interface OverlayConfigObject {\r\n color: string\r\n period: string\r\n type: OverlayType\r\n}\r\n\r\nexport enum Instrument {\r\n Stock = 'stock',\r\n Crypto = 'crypto',\r\n MarketSentiment = 'market_sentiment',\r\n Futures = 'futures',\r\n Forex = 'forex',\r\n Group = 'group',\r\n}\r\n\r\nexport enum Theme {\r\n light = 'light',\r\n dark = 'dark',\r\n}\r\n\r\nexport interface IModalConfig {\r\n title: string\r\n inputs: IModalConfigInput[]\r\n inputsErrorMessages: ObjectHash\r\n}\r\nexport interface IOptionType {\r\n value: string | number\r\n label: string\r\n}\r\nexport interface IModalConfigInput {\r\n type: React.HTMLInputTypeAttribute\r\n label: string\r\n name: string\r\n value: number | string\r\n required?: boolean\r\n min?: number\r\n color?: string\r\n step?: number\r\n items?: IOptionType[]\r\n}\r\n\r\n// Keep in sync with config/types/globals.d.ts\r\nexport enum Position {\r\n Above = 'above',\r\n Below = 'below',\r\n}\r\n\r\nexport enum DefaultSpineEvents {\r\n Change = 'change',\r\n Destroy = 'destroy',\r\n Refresh = 'refresh',\r\n Update = 'update',\r\n}\r\n\r\nexport enum CustomSpineEvents {\r\n IndicatorsChange = 'indicatorsChange',\r\n ManualChange = 'manualChange',\r\n}\r\n\r\nexport enum DrawingSpineOptionsEvent {\r\n Remove = 'remove',\r\n}\r\n\r\nexport interface DrawingSpineOptions {\r\n eventType: DrawingSpineOptionsEvent\r\n}\r\n\r\nexport type TodoButtonProps = ObjectHash\r\nexport type TodoButtonTheme = string\r\n"],"names":["Array","prototype","last","this","length","String","padLeft","paddingValue","slice","startsWith","str","indexOf","_callbackCache","Spine","bind","ev","callback","that","cb","record","fkey","id","_len","arguments","rest","_key","push","newCb","origCb","model","unbind","item","findIndex","element","iterable","all","index","el","eql","defaults","enabled","collapsed","duration","timestamp","logErrors","withStackTrace","level","logger","console","filterChanges","attrs","props","Object","keys","constructor","name","errorTransformer","error","titleFormatter","title","time","took","parts","toFixed","join","colors","prevState","action","nextState","pad","num","maxLength","repeat","times","toString","printLogEntry","logEntry","options","startedTime","data","formattedTime","getHours","getMinutes","getSeconds","getMilliseconds","titleCSS","headerCSS","formattedTitle","groupCollapsed","group","e","log","styles","trace","groupEnd","initialize","window","protoModelLoad","load","started","Date","now","cid","attributes","returnedValue","apply","badgeImages","getSvgImageCacheKey","badgeType","theme","state","ChartEventElement","ElementModel","initClass","paneModel","configure","belongsTo","yIndex","getChartEventBadgeImage","cacheKey","badgeImage","isLoaded","image","width","height","async","_ref","onBadgeInitLoad","importWithRetry","chartBadgeSvgByType","chartEventsAsyncModule","importFn","handleImageResolve","values","some","_ref2","undefined","ChartEventBadgeState","forEach","badgeState","ChartEventBadgeType","Theme","svgHTML","CHART_EVENT_BADGE_SIZE","img","Image","onload","onerror","captureException","Error","extra","src","encodeURIComponent","fetchAndCacheChartEventBadges","trigger","getChartEventData","instance","chart","quote","chartEvents","find","stockEvent","elementId","toObject","super","toConfig","Indicator","chartModel","Overlay","Chart","Pane","Quote","ChartLayout","DrawingsInternalStore","Element","document","location","hostname","isIPad","Utils","IPAD_FULLSCREEN_CLASS","FullscreenButton","isFullscreen","setIsFullscreen","React","getFullscreenStatus","requestFullscreen","getRequestFullscreen","documentElement","exitFullscreen","getExitFullscreen","onClick","call","checkFullscreen","body","classList","add","remove","addEventListener","removeEventListener","_jsx","Button","leftContent","contentClass","current","children","SORTED_LAYOUT_KEYS","arr","sort","a","b","reduce","acc","option","sortBy","sortDirection","SORT_DIRECTION","ASC","directionMultiplier","sortObjects","entries","LAYOUTS","map","key","value","ChartLayoutDropdown","_ref3","useLocation","navigate","useNavigate","parsedQuery","decodeQueryString","search","chartLayoutModel","useModelState","watchProperties","getChartsToPath","useChartsPathLocation","Dropdown","placement","orientation","l","_jsxs","className","layout","DropdownItem","appearance","Icon","MenuGroup","Paragraph","size","ChartSyncableParts","_ref4","label","isChartPartInSync","getIsChartPartInSync","active","setSyncChartParts","gtag","event_label","ThemeToggleButton","isDarkMode","updateAttributes","settings","updateSettings","setCookieRequest","catch","BREAKPOINTS","minWidth","Infinity","marketBadgeText","timeFormat","ChartLayoutHeaderComponent","onSettingsOpen","hasPublish","chartLayout","_Fragment","IdeasDropdown","TourButton","page","specificChartFunctionality","Publish","disabled","idea","Time","breakpointMode","breakpoints","ChartLayoutHeader","prevProps","nextProps","StockDetailTimeframeBar","withSuspense","isDateRangeAvailable","isPremium","isLoadingOverride","isScrollIntoViewEnabled","onTimeframeSelect","onDateRangeSelect","useChartLayoutGlobalModelAsync","chartModelUnwatched","getAllCharts","favoriteTimeframes","toggleFavoriteTimeframe","useFavoriteTimeframes","instrument","Instrument","Stock","isLoading","useChartControls","isInteractive","anchorDate","generateChartLayoutRouterPath","timeframeGroupsWithHref","dateRangeGroupsWithHref","isFetching","handleCustomDateRangeValidation","useChartModelCustomDateRangeValues","onDialogSubmit","customDateRangeDialogState","handleDateRangeSelect","getDateRangeTimeframe","useCustomDateRangeDialog","pathGenerator","dateRangeGroups","customRange","dateRange","timeFrameGroups","TimeframeBar","chartIndex","rounding","isRedesignEnabled","selectedTimeframe","timeframe","selectedDateRange","loadingTimeframe","onCustomDateRangeClick","show","onFavoriteTimeframeToggle","containerElement","isFavoritesEnabled","CustomDateRange","dialogState","dateRangeTimeframe","pushIndicators","panes","indicator","cotKeys","COTs","code","elements","type","IndicatorType","Cot","hasPaneWithCOTCode","PANE_HEIGHT_DEFAULT","period","parameters","getChartTypeByTaConfigStyle","style","candlestick","ChartElementType","CandleStick","heikinashi","HeikinAshi","hollowcandlestick","HollowCandleStick","line","LineChart","ohlc","OhlcChart","mergeChartAndTAConfig","chartConfig","taConfig","charts","scale","linear","ScaleType","Linear","percentage","Percentage","logarithmic","Logarithmic","indicators","filter","position","Position","Above","overlays","overlay","color","Below","getPanes","SettingsTab","SidebarDirection","createAlertAsyncModule","saveToPortfolioAsyncModule","AdsProvider","getAdsProvider","FinvizSettings","hasUserPremium","None","adsProvider","Freestar","InvestingChannel","trackPageView","pathname","query","freestarPageView","replace","freestar","queue","trackPageview","portfolioWatchlistTableAsyncModule","assets","logo","logo_light","ColorVariant","CheckboxSize","CheckboxComponent","ref","default","checked","defaultChecked","classnames","violet","emerald","orange","teal","pink","lime","purple","green","yellow","blue","red","gray","dark","Checkbox","forwardRef","clamp","min","max","isTouch","event","getRelativePosition","node","rect","getBoundingClientRect","pointer","touches","left","pageX","pageXOffset","top","pageY","pageYOffset","preventDefaultMove","preventDefault","DraggablePickerComponent","onMove","onKey","container","useRef","hasTouched","isDragging","setDragging","useState","isValid","handleMove","useCallback","buttons","handleMoveStart","nativeEvent","handleKeyDown","keyCode","which","handleMoveEnd","toggleDocumentEvents","toggleEvent","useLayoutEffect","onTouchStart","onMouseDown","onKeyDown","tabIndex","DraggablePicker","memo","Pointer","backgroundColor","hexStringToRGBA","hexString","hexColor","removeHashSymbol","r","g","Number","Math","round","hexStringToHSVA","rgbaToHSVA","alphaToHex","alpha","padStart","rgbaToHexString","hsvaToHEXString","hsvaToRGBA","v","c","h","s","f","n","k","rgbaToRGBAString","rgbaStringToObject","colorParts","exec","parseInt","parseFloat","strColor","isValidColor","isRgb","Option","convertColorToHEX","getIsRgb","rgbKeys","getHSVAFromColor","Alpha","onChange","changeLightness","pos","gradientPreview","useMemo","backgroundImage","DEFAULT_COLORS","ColorPalette","lowerCaseColor","toLowerCase","colorObj","isSelected","HueSaturation","getPositionFromHSLA","colorPreview","changeSaturation","Lightness","ColorPreview","icon","isArray","isTooLight","getLumaFromRGBA","getIsColorTooLightOrTransparent","isValidIconName","PickerInput","inputClass","hasColorPreview","colorInput","setColorInput","colorUtil","isRgba","useEffect","handleColorInputChange","currentTarget","colorValue","Input","ColorPicker","canSelectCustom","canSelectAlpha","outputFormat","onPaletteItemClick","cachedColor","hsvaColor","setColor","popover","Ariakit","input","currentColor","newColor","onChangeCallback","stringColor","output","onSetCustomCodeClick","prompt","trim","alert","isMobile","_hex","orignalColor","focus","preventScroll","InputColorPicker","inputDataTestId","popoverState","usePopoverState","isMobileDevice","PopoverTrigger","render","Popover","hideOnInteractOutside","backdrop","hide","MultiColorPicker","colorInputLabel","ColorTabButton","ButtonRounding","small","ButtonColorPicker","buttonPickerDataTestId","isOpen","isMultiPicker","activeColorIndex","setActiveColorIndex","handleColorChange","originalColor","colorObject","as","ButtonGroup","childComponent","hasDivider","_ref5","CopyToClipboard","text","bottomLeftContent","isCopied","setIsCopied","handleCopyToClipboard","copy","timeout","resetTimer","clearTimeout","setTimeout","Textarea","readOnly","select","DropdownRounding","DropdownTheme","StatelessDropdown","modal","gutter","unmountOnHide","showOnHover","autoFocusOnShow","autoFocusOnHide","onFullyOpen","onFullyClosed","store","zIndex","updatePosition","usePopoverPlacement","isFullyOpen","setIsFullyOpen","isMounted","wasMounted","usePrevious","menuGutter","parent","focusable","portal","hideOnHoverOutside","preventBodyScroll","focusWithoutScroll","blurWithoutScroll","classNames","none","onTransitionEnd","target","focusLoop","virtualFocus","DropdownItemComponent","asComponent","OptionButton","useDropdownState","ContextMenuInner","items","onClose","onContextMenu","rightContent","assign","menu_option","ContextMenu","ChartGridCell","gridArea","GridLayout","columns","rows","border","gridTemplateColumns","gridTemplateRows","ChartGrid","defaultValueAccessor","InnerState","valueKey","changeKey","valueAccessor","setState","handleChange","RangeSize","RangeSlider","step","inputClassName","hasTrack","setHasTrack","trackRef","thumbRef","Boolean","thumbLeft","track","thumb","valuePercent","trackBox","thumbBox","Label","ToolbarTheme","ToolbarDirection","ToolbarContext","direction","vertical","chipTransparent","isWrapped","isStretched","useToolbarContext","getToolbarSettings","hasRedesignEnabled","horizontal","alternative","Toolbar","hasFocusRings","toolbarRef","contextProviderValue","toolbarSettings","isSafariDesktop","forceReflow","throttle","originalWidth","offsetWidth","showTimeout","hideTimeout","Provider","querySelector","ToolbarButton","disabledTooltip","isInAction","isInActionProp","context","iconAction","buttonSettings","isActive","includeRedesign","grow","getButtonThemeSettings","getMainIcon","iconActive","menubar","blurOnHoverEnd","titleActive","Delayed","delay","delayComponent","Spinner","isMobileBrowser","ToolbarGroup","defaultItem","groupItems","groupTitle","useNativeSelect","rowId","selectedItem","setSelectedItem","groupId","toLocaleLowerCase","isAlternativeTheme","menu","menuButton","setMenuButton","open","mounted","anchorElement","parentMenu","menuContentElement","hideMenu","onMouseLeave","showMenu","handleMenuOpen","setDisclosureElement","setAnchorElement","NativeSelect","onFocusVisible","onPointerDown","portalElement","ToolbarItem","isItemActive","ToolbarDivider","StepContent","Box","Heading","shepherdLibrary","loadShepherdLibrary","setLoading","shepherdPromise","buttonClasses","BUTTON_BASE_CLASS","BUTTON_FOCUS_STYLES","ButtonSize","regular","getStepButtons","tour","complete","classes","getButtonTheme","ButtonTheme","light","button","ButtonPadding","back","backButton","next","nextButton","getTourKey","getStepsForUser","tours","lastFinishedTour","localStorage","getItem","lastTourIndex","allToursViewed","every","skip","toursToView","hasNewTours","steps","initialTour","completeTour","setItem","DEFAULT_OPTIONS","exitOnEsc","useModalOverlay","useTour","setIsLoading","currentTour","setTour","controller","AbortController","loadingSetter","signal","aborted","abort","startTour","definition","setComplete","tourUtils","Tour","from","removeStep","processedSteps","attachTo","on","popperOptions","modifiers","offset","ReactDOM","modalOverlayOpeningRadius","overlayRadius","modalOverlayOpeningPadding","overlayPadding","addSteps","start","TabSpacing","InternalTab","ariaSelected","spacing","content","Tab","TabList","TabPanel","Tabs","BadgeSize","BadgePadding","Badge","padding","badgePadding","badgeSize","TooltipInputComponent","tooltipSettings","isPointerEventsEnabled","TooltipTrigger","hideOnBlur","Tooltip","TooltipInput","useTrackPageView","trackInitial","trackAutomatically","initialRender","handleTrackView","tracking","cache","errorsCache","ErrorSeverity","defaultCaptureException","exception","captureContext","Sentry","useAsyncModule","onError","errorSeverity","shouldLoadModule","isSuspenseMode","notificationContext","useNotification","isError","setIsError","getIsMounted","useIsMounted","handleError","high","handleScriptNotLoaded","renderScriptNotLoaded","medium","Notification","timeoutInMs","reload","loadModule","cachedModule","then","mod","err","Component","fallback","NUM_OF_RETRIES","retries","Promise","ElementBaseConfig","static","abbreviation","shortLabel","optionsOrder","optionsLabels","inputsOrder","inputsLabels","calculatedValuesOrder","calculatedValuesLabels","defaultCalculatedValueOption","getShortLabelWithAttrs","getDefaultCalculatedValues","Arrow","CanvasElementType","arrow","renderContent","resize","_thumbs","Thumb","x1","y1","x2","y2","getBoundingPointKeys","getDefaults","getChartLayoutSettings","ElementSettings","Colors","x","y","scaled","roundedXY","getRoundedObject","translateXY","getXYOffsetFromLine","lineWidth","translate","beginPath","set","angle","PI","moveTo","lineTo","stroke","lineAngle","atan2","abs","cos","angle1","topx","topy","sin","angle2","botx","boty","getShouldRenderThumbs","renderThumbs","moveBy","difX","difY","isInArea","area","isDrawingElementLockedOrInvisible","math","distanceToSegment","modalConfig","inputs","Brush","brushV1","untranslatedContext","brushPath","cachedFill","previousFill","shouldRenderFill","getContextWithCache","createElement","setFillCache","fill","defaultTransparentFill","isPolyLineClosed","getShouldRenderFill","Path2D","points","i","fx","fy","xc","yc","quadraticCurveTo","point","closePath","getThumbs","firstX","firstY","lastX","lastY","moveByThumb","getIsCreator","onMouseUp","currentDomainMax","currentDomainMin","domain","roundToFixed","roundY","isPointInPath","cachePointPositionTimestamp","positionPointsTimestamps","getTimestampFomPositionX","updateScales","getPositionXFromTimestamp","places","overridePlaces","domainDiff","numberOfLeadingZeros","floor","log10","getAutosaveOmittedProperties","getEdgeXYValues","edgeXYValues","minX","minY","maxX","maxY","TailDirection","getTailHalfWidth","halfWidth","p1","p2","dist","distance","Callout","Text","calloutV1","getModalConfigBase","required","textWithoutBackground","font","family","weight","fillStyle","lineHeight","textAlign","textBaseline","right","bottom","background","defaultFill","setupContext","setupTextMetricsCache","ctx","lastAttrs","JSON","stringify","merge","lines","getLines","metrics","measureText","measuredHeight","currentIndex","actualBoundingBoxAscent","actualBoundingBoxDescent","PADDING","S","renderText","previousDescent","fillText","getCalloutProperties","textWidth","requiredTailHalfWidth","radius","rectangleSides","topLeft","topRight","rightTop","rightBottom","bottomRight","bottomLeft","leftBottom","leftTop","getRectangleSidesCoordinates","tail","tailRoot","tailTip","getTailCoordinates","tailDirection","twoSegmentLinesIntersection","topLeftCorner","topRightCorner","bottomLeftCorner","bottomRightCorner","topSide","rightSide","bottomSide","leftSide","noTail","getTailToSideIntersection","renderBackground","lineJoin","arcTo","tailLineToTopLineIntersection","tailHalfWidth","tailLineToRightLineIntersection","tailLineToBottomLineIntersection","tailLineToLeftLineIntersection","renderCallout","renderBorder","tailP1","perpendicularPointToLine","pointOffsetX","pointOffsetY","tailP2","polygon","pointInPolygon","getIsInChartView","leftOffset","Curve","curve","x3","y3","drawQuadraticCurve","Bezier","quadraticFromPoints","cp1x","cp2x","cp1y","cp2y","project","d","thumbsAreInArea","Ellipse","ellipse","invert","getCoordinates","centerLeftX","centerLeftY","centerRightX","centerRightY","boundingPointKeys","bottomCenterX","bottomCenterY","bezierCurveTo","bottomRightX","bottomRightY","topRightX","topRightY","topCenterX","topCenterY","topLeftX","topLeftY","bottomLeftX","bottomLeftY","rotationAngle","atan","sign","radiusX","radiusY","width_two_thirds","dx1","dy1","dx2","dy2","RotatedRectangle","rotatedRectangle","getRectCoordinates","coords","mx1","mx2","my1","my2","nk","dx","sqrt","dy","x4","y4","SymbolElement","symbol","sx","getRotatedCoordinates","scaleX","sy","textHeight","scaleY","xScale","yScale","xOffset","yOffset","save","rotate","restore","cx","cy","halfHeight","drawingToolsByType","freeze","brush_v1","callout_v1","elliottWaves","ellipseV1","ellipse_v1","fibonacciRetracements","fibonacci","horizontalLine","measure","pitchforkV1","pitchfork_v1","rectangle","rotatedRectangleV1","rotatedRectangle_v1","scaledLine","scaledText","symbolElement","triangle","verticalLine","xabcd","fromObject","obj","getNumOfBarsBuffer","_","isCreator","isCreatorDialogOpen","activeThumb","isMouseDown","isHovered","isEditInProgress","onMouseMove","getIsChartEvent","findByAttribute","__","setIsEditInProgress","shouldTriggerChange","setIsSelected","setIsHovered","getIsPaneSelection","pane","selection","attrsSubset","customizer","objValue","srcValue","getIsDrawing","mergewith","get","defineProperty","globalAlpha","startEditing","mouseDown","xPointKeys","positionTimestamps","positionX","pointPoitionsFromTimestamp","chart_layout","isLockDrawingsActive","getIsVisible","getModalConfig","config","toAutosaveConfig","omit","replaceMyself","captureMessage","oldElement","newElement","getIsCreatorDialogOpen","release","micro","macro","MicroMacroTimeframe","visibility","isInRange","to","setVisibilityTo","setTo","MacroTimeframe","timeframesToSet","attrsToSet","SetVisibilityTo","currentAndAbove","currentAndBelow","currentOnly","xPoints","yPoints","positionY","omitX","isMaxXInvalid","isNaN","isMinXInvalid","omitY","topBound","bottomBound","ElliottWaves","waves","getOffsetFromLineWidth","p","TextBaseline","middle","TextAlign","center","wave","positionWavesTimestamps","EllipseV1","getEllipsePoints","P2","P4","coordinates","P3","P1","CP4","CP1","CP2","CP3","ellipsePath","inverted","cursorTargetX","cursorTargetY","perpendicularPoint","cursor","distanceToLine","lineCenterX","lineCenterY","invertX","invertY","perpendicularPointEllipseOffsetX","perpendicularPointEllipseOffsetY","P1WithOffsetX","P1WithOffsetY","P3WithOffsetX","P3WithOffsetY","controlPointOffsetX","controlPointOffsetY","getRotatedPointCoordinates","rotationAxisPoint","pointToRotate","oldLinePoint","newLinePoint","sharedPointLinesAngle","sharedPoint","rotatedPoinCoordinates","rotatedPointCoordinates","newLeftPoint","leftRotatedCursorPoint","newRightPoint","rightRotatedCursorPoint","FibonacciRetracements","parseCoefficients","coefficients","parsed","split","getMaxCoefficientUnscaledY","getMinCoefficientUnscaledY","includes","_ref6","_ref7","maxCoefficientY","minCoefficientY","allYValues","HorizontalLine","ScaledLine","decimalPlaces","updateDecimalPlaces","getInstrumentDecimalPlaces","lastClose","ChartSettings","getBarIndex","close","renderLabels","IndicatorSettings","isIndicator","allowDecimal","Line","strokeStyle","dashLength","setLineDash","Measure","x1Dif","x2Dif","startingX1","startingX2","getVolumeSumString","volume","barIndex","roundedX1","roundedX2","minIndexLimit","maxIndexLimit","volMinIndex","volMaxIndex","volumeSum","volumeIndex","numberToStringWithUnitsSuffix","fillRect","priceDif","heightStr","getRoundedString","number","numOfDecimalPlaces","baseX","baseY","getHeight","addToCoordinates","difs","newX1","newX2","paneArea","getEdgeIntersectionPoint","sides","rayOrigin","rayDirection","intersection","intersectionDistance","rayToLineIntersection","getRayToLineSegmentIntersection","getPitchforkCoordinates","rayDirectionControlPoint1","rayDirectionControlPoint2","trend1","trend2","chartVisibleAreaLeftX","chartVisibleAreaRightX","chartVisibleAreaBottomY","chartVisibleAreaTopLeftPoint","chartVisibleAreaTopRightPoint","chartVisibleAreaBottomLeftPoint","chartVisibleAreaBottomRightPoint","getChartVisibleAreaBoundaries","medianRay","trend1Ray1","trend2Ray1","trend1Ray2","trend2Ray2","medianRayDirectionPoint","getMiddlePointOnLineSegment","rayOriginToRayDirectionVector","rayDirectionControlPoint1ToPoint2Vector","normalizedRayDirectionControlPoint1ToPoint2Vector","normalizeVector","medianRayDirectionPointToRayDirectionControlPoint1Distance","trend1Ray","getTrendRayCoordinates","trend","medianToControlPointDistance","normalizedControlToControlPointVector","trendRay1","trendRay2","trend2Ray","medianToTrendLineDistance","trendRayPoint1Origin","addPoints","multiplyVectorByScalar","trendPoint2RayOriginPoint2","subtractPoints","trendRayPoint1DirectionPoint","trendPoint2RayDirectionPoint","Pitchfork","median","trendLines","line1","line2","trendLine","trendLineIndex","solidTrendColor","getHEXWithSpecificAplha","nextTrendLine","outerTrendLines","Polygon","isPolygon","scaledPoints","xPoint","yPoint","targetY","stopY","centerY","stopBaseline","targetBaseline","targetColor","stopColor","targetDif","targetPerc","targetStr","stopDif","stopPerc","stopStr","middle1","result","roundDif","coordType","coordIndex","t","Rectangle","strokeRect","RotatedRectangleV1","newMiddleLeftPoint","middleLeftRotatedCursorPoint","newMiddleRightPoint","middleRightRotatedCursorPoint","ScaledText","XXXS","XXS","textBoxX","textBoxY","textBoxWidth","textBoxHeight","DEFAULTS","alphabetic","getMergedPropsWithDefaults","propKey","count","MIN_SAFE_INTEGER","testArea","convertArea","rawHight","getFontHeight","fontBoundingBoxAscent","fontBoundingBoxDescent","borderWidth","ThumbSettings","borderColor","thumbWidth","getThumbWidth","Triangle","VerticalLine","XABCD","xx","xy","ax","ay","bx","by","toUpperCase","retLabel","len","ret","xab","bcd","result1","canvas","rendered","refresh","ratio","drawImage","cWidth","cHeight","sWidth","screen","sHeight","getScaleRatio","setSizeOnCanvasElement","canvasElement","OHLCType","ChartMinWidthBreakpoints","getChartBreakpoints","chartWidthInPx","isXs","xs","isS","isM","m","isL","getDateString","date","dateString","month","getMonth","year","getFullYear","day","getDate","TIMEFRAME","i1","i2","i3","i5","i10","i15","i30","h2","h4","MONTHS","w","getClosestDifferentMinMaxValueIndices","currentMinIndex","currentMaxIndex","low","hasPreviousIndex","hasNextIndex","minIndex","maxIndex","gray300","tailwindColors","BaseChart","overlaysByType","tickerWidth","changeWidth","lastOhlc","isLargeChart","shouldRenderVolume","afterChange","utils","overlayDefinition","addOverlay","renderYAxis","renderCrossText","setupCache","renderOverlaysLabels","CustomSpineEvents","IndicatorsChange","handleIndicatorsChange","mouseModelChangeHandler","mouseModel","unmountCanvas","baseCache","updateShouldRenderVolume","renderChart","renderChartNotAvailable","getIsRedesignedChart","renderTicker","clip","renderVolume","renderOverlays","renderPrevClose","renderFadeExtendedHours","renderGrid","renderXAxis","tickerText","getIsSmallIndexChart","ticker","general","margin","FONT_SIZE","OFFSET","baseline","renderTimeframe","volumeFY","range","Group","getTimeframeLabel","textSecondary","isOurSiteRequest","L","SpecificChartFunctionality","offScreen","XS","M","renderChange","getOHLC","directRender","changePercentage","lastDate","renderOHLC","isSmallIndexChart","isNewestOHLC","afterHour","isFinite","afterClose","roundOhlc","lastVolume","toLocaleTimeString","hour","minute","getRoundedLastData","lastOpen","lastHigh","lastLow","renderOverlaysLabelsChartsPage","renderOverlaysLabelsQuotePage","overlayLabel","isRenderedOverlaysLabel","labelSpacing","getLabelColor","getYAxisLeftMargin","Crypto","getYAxisLastCloseLabel","firstVisibleClose","getPercentageFromValue","base","lineTicks","textTicks","lastCloseLabel","getTranslate","do","tickCount","minMax","getMinMax","placesAxis","stepPrice","scaleRange","updateAttribute","minPerc","maxPerc","d3","nice","ticks","tick","getValueFromPercentage","pixelGap","negativeScale","previousNegativeTick","unshift","positiveScale","previousTick","positiveScaleY","getYLineText","val","yTickText","axis","yTickLine","getYLine","resetYTicksStyles","percentageZeroLineText","undo","renderYAxisLabel","yCoordinate","getSecondaryLabelBackgroundColor","stringifyHSVAColor","currentBackground","getYAxisSecondaryLabelYCoordinate","mainLabelValue","secondaryLabelValue","LINE_HEIGHT","mainLabelValuePosition","secondaryLabelValuePosition","offsetedY","_ref8","currentText","getDrawDays","MarketSentiment","textRenderer","startBarIndex","getVisibleBarToRenderIndex","endBarIndex","chartWidth","render15MinXAxis","renderIntradayXAxis","renderIntradayXAxisFutures","renderDailyXAxis","renderWeeklyXAxis","renderMonthlyXAxis","isXPointVisible","buffer","renderXAxisLabels","_ref9","labels","allowedOverflow","sortedLabels","renderedLabelRanges","reverse","newLabel","hasPriority","_ref10","halfOfTextWidth","overflowLeft","overflowRight","labelX","getIsOverlapping","interval","IntradayTimeframeInterval","marketStartHour","marketStartMinutes","marketEndHour","ceil","aftermarketLengthMinutes","xLine","getXLine","barWidth","getBarWidthWithMargin","zoomFactor","dayToOffset","getDayToOffset","dayIndex","dateFromDateString","drawMinutesPerDay","roundedX","premarketLengthMinutes","_ref11","lastDay","lastHours","NaN","hours","_ref12","indexOffset","getBarsInDay","_ref13","lastMonth","_ref14","gridSecondary","isYearLabel","substring","_ref15","lastYear","isJanuary","getIsIndicatorPresent","Vol","getVolumeTicks","maxHeight","fontHeight","renderVolumeAxis","relativeVolume","grid","rangeMax","volumeAxisFontSize","volumeAxis","format","tickFormat","domainFrom","domainTo","setupAxisTimeFrame","halfBarWidth","getHalfBarWidth","barWidthWithoutMargin","getBarWithoutMarginWidth","drawInVisibleArea","drawBarCallback","volumeTrendDown","volumeTrendUp","renderCross","isRendered","contentWidth","contentHeight","getRoundDecimalPlaces","price","getPlacesLastClose","onRenderCrossText","getCrossIndexForPane","setElementCursor","getHTMLElementId","conditionalCursor","getDataByCrossIndex","crossIndex","shouldReturnRoundedString","getDataByBarIndex","getCrossIndexChange","crossDataIndex","getDataIndexByBarIndex","crossClose","previousClose","getTickerChangeFromCloseValues","anchorClose","prevClose","dateByBarIndex","virtualTradedDates","getVirtualTimeframeTradedDates","dateStart","dateEnd","_ref16","change","tickerChange","tickerAfterChange","getTickerChange","isOffscreen","isGroupInstrument","finvizWatermarkOffset","changeText","percentString","string","getChangeColor","afterChangeText","afterChangeTextWidth","oneLineAHChangeWidth","renderOHLCChartsPage","renderOHLCQuotePage","_ref17","chartBreakpoints","OhlcText","canvasFill","dateElements","trendColor","oElements","hElements","lElements","cElements","volElements","changeElements","getFlatLineArrayWithSpaces","lineElements","flatMap","startX","lineElement","LabelsText","numberOfNewOhlcLines","_ref18","dateOnly","timeOnly","lineTopY","OHLCFontSize","centerXOffset","leftXOffset","OHLC","ohlcString","singleLine","OHLC_TEXT","getOHLCType","ohlcSettings","getOHLCSettings","CHART_MARGIN","XXL","alignTop","renderOHLCToCanvas","_ref19","ohlcSet","isSingleLineWithChange","n0","n1","x0","premarketFade","aftermarketFade","shouldShowPrevClose","isStock","isIntradayWithPreMarket","TIMEFRAMES_WITH_PRE_MARKET","isIndexChart","smallIndex","Cache","getIsMobileChartPage","setupAxis","volumeHeight","firstBarToRenderIndex","lastBarToRenderIndex","volumes","getAreNoBarsVisible","addMarginBottom","marginBottom","setOverlays","removeOverlay","splice","MAX_VALUE","MIN_VALUE","prevMin","closestMinMaxIndices","placesLastClose","priceAbs","hasOverlay","chartPage","getCandleLikeChartsRenderingColors","overwrittenColors","getColorOverwrites","overwrittenColorKeys","hasOverwrittenCandleColor","colorKey","getShouldUseDarkerWickColors","totalBarWidth","darkerWickColors","thinBarColorsOverride","isRedesignedPage","getRenderChartBarProps","chartSettingsColors","hasFillAndBorder","trendDown","trendUp","borderDown","borderUp","wickDown","wickUp","wickColor","barFillColor","barFillWidth","barBorderWidth","getBarWidthWithMarginByParts","shouldRenderFillAndBorder","translateForWick","WICK_WIDTH","candleBodyHigh","candleBodyLow","candleWickHigh","candleWickLow","candleBodyHeight","candleBodyLeftX","halfBorderWidth","getIsSSr","isBodyHeightGreaterOrEqualBorders","isWickLineCandleLessThanOnePixel","hasBorder","fillHeight","hasFill","isHollow","generalTrendColor","ohlcTrendUp","ohlcTrendDown","zeroChange","haData","getHeikinAshiData","getLastValues","originalLatestClose","heikinLatestCloseLabel","originalLatestCloseLabel","first","redLine","greenLine","MarketSentimentSettings","sum","_data","lastIndex","_dataLastIndex","renderLineBullBear","array","oversold","overbought","isRedesign","marketDown","marketUp","_compute","computeVisibleMinMax","yLine","fillUp","fillDown","percent","months","MultiLineChart","tickersDimensions","ColorsSettings","quotes","getQuotes","tickers","end","asc","barToDataIndex","hasTickerDimensions","maxTickerLength","isLastDate","closeValue","arrays","q","isIdeaId","ideaID","OHLCChart","barWithoutMarginWidth","lineThickness","handleLengthFromWick","lineOffset","barX","PerfChart","overlayLabelWidth","perf","dates","getCompleteChartNumOfBars","shouldRenderDate","tickerData","MARGIN","percentageText","lastCrossIndex","findLastIndex","fromDate","toDate","timestampe","dateToIndex","getDateToIndex","lastValue","dataIndex","monthsInData","availableTickSpots","monthsToAvail","renderMonth","chartsByType","candleStick","heikinAshi","hollowCandleStick","lineChart","marketSentiment","multiLineCharts","ohlcChart","perfChart","XXXL","XL","SETTINGS_HEIGHT","TICKER_TIMEFRAME_CHANGE_HEIGHT","ChartEditorEnum","LayoutType","OverlayType","ChartEventDbType","ChartEventType","ChartEventLabels","Dividends","Split","EarningsPositive","EarningsNegative","EarningsNeutral","EarningsFuture","gridAreas","DESC","TimeframeLabelShort","DateRangeType","QuoteFinancialAttachment","TIMEFRAME_SECONDS","CRYPTOS","BTCUSD","LTCUSD","ETHUSD","XRPUSD","BCHUSD","BTCEUR","LTCEUR","ETHEUR","XRPEUR","BCHEUR","LTCBTC","ETHBTC","XRPBTC","BCHBTC","QuotePollingIntervalInMs","EXTRA_MARKET_BUFFER_MINUTES","ScaleLabel","INDICATOR_LABEL_HEIGHT","MOBILE_BARS_TO_VIEW","MOBILE_VIEW_BREAKPOINT_WIDTH","FREE_DATE_RANGES","QuotePageQueryChartTypes","minutes","days","weeks","MicroTimeframeRange","prev","curr","QUOTE_FETCH_EVENT","PREMARKET_AFTERMARKET_HOURS","CHART_ELEMENT_ID","CHART_SETTINGS_DIALOG_TEST_ID","getContainerTypeFromPaneConfig","indicatorElement","getContainerType","mainElement","indicatorType","isChart","updateInternalStoreWithChangedElement","changeType","currentInternalStore","lastUpdateTimestamp","getQuoteRawTicker","containerType","destroyed","instanceJson","newDrawing","lastChange","elementAttrs","newInternalStore","updateDrawingIndex","drawingElement","shouldSyncAndSave","updatedRecord","hasChangedZIndex","hasChangedType","hasChangedAttrs","hasChange","getTickersAndContainerTypesInLayoutModel","containerTypes","getAllPanes","mergeUpdatedDrawingsToInternalStore","updatedDrawings","isRefetchAll","newLastUpdateTimestamp","updatedElementIds","drawing","receiveHlc","drawingIndex","currentDrawing","currentNote","getElementNoteText","autoSavedNote","incrementHlc","parse","compareHlc","getInitialStoreDrawings","initialDrawings","initialDrawingsStore","FinvizChartsSettings","drawings","getAutosaveElementFromDBRecord","handleCallMethodOnAllDrawings","elementMethod","getAllElements","isDrawing","getNoteElementId","noteElement","getTickerNoteText","ts","lastChangeTimestamp","lastChangeCounter","uuid","lastChangeNodeUUID","getDBRecordFromAutosaveElement","utmCampaign","quotePage","futuresPage","forexPage","cryptoPage","PopoverInner","hidePopover","chartSettingsModule","chartSettingsAsyncModule","ScrollableChartSettingsPopover","forceGlobalRerender","getIsConfigChanged","confirmationDialogState","checkChangesAndOpenDiscard","discardChangesAndHide","buttonPosition","popoverContentElement","getState","disclosureElement","scrollY","chartHeight","chartElement","getElementById","clientHeight","minHeight","ZIndexContext","PopoverRounding","PopoverTheme","ConfirmationDialog","actions","DialogDismiss","ChartSettingsButton","settingsPopoverState","buttonProps","href","encodeQueryString","utm_source","utm_medium","utm_campaign","focusRing","getQuoteRequestKey","unwatchedChartModel","chartModelRef","modelRef","useModelRef","abortControllerKeyRef","isIdeaChart","updateChartModelWithNewQuote","isSameTicker","getRawTicker","getChartOrIndicatorElement","getLeftOffset","isScrolled","getAllQuotes","chartQuote","fetchData","fetchType","QuoteFetchType","NewerData","chartPane","getChartPane","activeChartEvent","toggleIsOpen","getAllChartEvents","isChartEvent","isPreserveDrawingsActive","destroyCascade","setChartEvents","updateChartEventsZIndexes","fetchQuote","hasChartEvents","premarket","aftermarket","patterns","getHasPatterns","currentQuote","abortController","createRequestAbortController","shouldAbortRunningRequest","events","financialAttachments","getQuoteFinancialAttachments","cachePredicate","fetchNewDataOnCachedQuote","wasFetchAborted","isQuoteUsedInOtherCharts","fetchedAt","destroy","removeFromAbortCache","decodedQueryString","rangesArray","ranges","shouldRecalculateOnCharts","barMargin","hasSameBarWidth","hasSameBarMargin","setIsFetching","dateFromUnixTimestamp","generatePathForTimeframeDateRange","timeframeUtm","getTimeframeGroupsWithHref","generatePath","timeFrame","getDateRangeGroupsWithHref","dateRangeState","numOfVisibleBars","getVisibleBarsNumber","getChartStartEndDates","unwatchedChartLayoutModel","hasSyncedTimeframe","ChartSyncablePart","Timeframe","syncChartParts","hasSyncedTicker","Ticker","decodedSearch","urlTickers","urlTimeframes","urlDateRanges","chartsArrayPlaceholder","currentTicker","timeframes","currentTimeframe","currentDaterange","sidebar","getIsMobilePortrait","getTimeframeGroups","timeFrameGroup","QuoteNodeChartTypes","QuoteUrlChartTypes","QuoteShortToLongType","cs","candlesticksimple","o","ha","hc","QuoteLongToShortType","DEFAULT_TYPES","FREE_TYPES_QUOTE","FREE_TYPES_QUOTE_VALUES","useChartLayoutGlobalModelAsyncModule","preventClosingUnsavedChangesAsyncModule","BackgroundInput","ColorRangeRowInput","colorTestId","rangeValue","rangeTestId","rangeLabel","rangeProps","handleRangeChange","BorderInput","CheckBox","FONT_VALUES","FontInput","setFamily","setSize","setStyle","setWeight","setValue","valueSetter","Select","selected","LineInput","MultilineStringInput","placeholder","autoFocus","NumberInput","pattern","StringInput","Trend","valueAsNumber","VisibilityInput","isCheckboxOnly","isOff","setIsOff","setFrom","macroKey","macroLabel","charAt","INPUTS_AVAILABLE","getInitialState","visibilities","macroTimeframe","valueMacroTimeframe","getIsVisibilityOutsideAvailableTimeframes","macrotimeframe","macroRange","Visibility","initialVisibilityRef","handleDisableSubmit","TAB_BUTTON_COMMON_PROPS","getValuesFromFormState","formState","cur","DialogTabs","ElementStyleDialog","initialFormStateRef","setFormState","selectedTab","setSelectedTab","Style","isSubmitDisabled","setIsSubmitDisabled","isDrawingElement","handleFullyOpen","CanvasElement","handleFullyClosed","onHide","handleValuesChange","shouldSubmit","shouldDismiss","hasOnSubmit","onSubmit","hasOnDismiss","onDismiss","handleValuesChangeDebounceRef","debounce","newFormState","maxWait","cancel","checkValidity","handleCloseDialog","Dialog","isDraggable","hideOnEsc","DialogHeader","onCloseClick","DialogBody","InputComponent","getInputForType","inputType","stateInput","DialogFooter","ElementStyleDialogContext","ElementStyleDialogWrapper","setElement","setOnSubmit","setOnDismiss","dialog","useDialogState","openDialog","DRAWINGS_SAVE_INTERVAL_MS","RETRY_LIMIT","useDrawingAutoSaveApi","postRetryCountRef","deleteRetryCountRef","fetchDrawings","fetchApi","queryParameters","throwOnStatusCodes","saveDrawings","bodyJsonString","keepalive","hi","charCodeAt","lo","getByteLengthOfString","method","contentType","ContentType","ApplicationJson","latestChangeHlc","InternalServerError","ForbiddenError","GoneError","newTicker","response","message","GenericStatusCodeError","invalidItems","deleteAllDrawings","lastLocalChange","newHlc","useDrawingAutoSaveControls","isAutoSaveActive","isInit","getIsPreserveDrawingsAndAutosaveAvailable","useIsAutoSaveActive","drawingsInternalStore","saveTimeoutRef","saveLatestChanges","withDelayInMs","saveQueueExtraFilterCallback","saveQueue","latestLocalUpdateTimestamp","instanceUUID","setAutoSaveState","AutoSaveState","Unsaved","Saving","Saved","syncChartLayoutDrawings","isRemove","paneContainerType","paneInternalStoreElements","autoSaveElement","paneElement","paneDrawing","parsedElementAttrs","hasOngoingInteraction","getCanvasElementByType","create","handleAutoSaveNoteChange","note","newNoteElement","handleIdeaNoteChange","activeChart","checkDrawingUpdate","latestRemoteUpdateTimestamp","initHlc","allElements","normalizeZIndexes","activeTicker","updateInternalStoreWithElement","updateResult","deleteAllAutoSavedElements","onElementChange","elementPane","elementContainerType","elementPaneTicker","eventType","DrawingSpineOptionsEvent","Remove","useDrawingAutoSave","drawingsInternalStoreUnwatched","prevIsAutoSaveActive","runInitialSaveAndRefetchUpdate","Off","onChartOrIndicatorChange","newTickers","newContainerTypes","ChartModel","checkDrawingUpdateInterval","setInterval","unregisterListeners","clearInterval","willDestroy","ChartTypesSelect","chartTypes","getCurrentType","ta","ty","taInt","isQuotePage","defaultType","FinvizQuoteTypeCurrent","generateRouterPath","reloadDocument","useChartTypes","currentType","selectedType","setSelectedType","nativeSelect","CHANGE_UPATE_EVENTS","QUOTE_MODEL_CHANGE_EVENTS","ChangeLabel","changePoints","isTiny","DailyChangeDisplay","listenOnEvents","quoteModel","testId","DrawButton","newValue","getIsDrawingEnabled","DRAWING_COOKIE_NAME","expires","setMonth","setCookie","finally","getLayoutType","tickersCount","Search","onTickerSelected","saveToPortfolioDialogState","isSaveToPortfolioVisible","createAlertDialogState","isCreateAlertVisible","saveToPortfolioModule","isLoadingSaveToPortfolio","createAlertModule","isLoadingCreateAlert","SaveToPortfolio","CreateAlert","detailLink","formattedTicker","Futures","Forex","WebsiteSearchComponent","isSearchIcon","isSearchItemLink","isShowAllVisible","event_category","ChartControls","handleTickerSelect","upperCaseTicker","handleCustomRangeSubmit","timeframeBarProps","canChangeTicker","hasTimeframe","editors","tools","editable","ideas","compactViewMaxBreakpointPx","publish","contextMenu","watchedModel","shown","ContextMenuComponent","overlap","callbacks","onBeforeItemClick","getAnchorRect","anchorRect","stopPropagation","ready","rootEl","clientX","clientY","ChartEventPopoverWithState","unwatchedChartLayout","lastEventId","isPopoverMounted","chartEventsModule","isChartEventOfThisChart","setData","clickAwayRef","isListening","refCallback","handler","contains","useClickAway","chartEvent","popoverShow","popoverHide","newData","getChartEvenBadgeType","PopoverAnchor","ChartEventPopoverContent","LoadLatestDataButton","isMountedRef","hasNewDataAvailable","setHasNewDataAvailable","getRefreshInterval","isPossibleToFetchSequentialData","hasNewData","promises","refreshData","ZOOM_CONTROLS_ACTIVE_CLASS","ZOOM_CONTROLS_IS_IN_AREA_CLASS","buttonCommonProps","getDefaultLeftOffset","ZoomControls","zoomControlsRef","isVisible","onZoomIn","onZoomOut","onZoomReset","isGoToRecentVisible","setIsGoToRecentVisible","defaultZoomFactor","isZoomResetVisible","setIsZoomResetVisible","handleGoToMostRecent","handleChartModelChangeDebounced","hidden","rafId","crossRafId","paneRef","scalerRef","zoomerRef","canvasWrapperRef","canvasRef","crossCanvasRef","paneHammer","scalerHammer","zoomerHammer","canvasWrapperHammer","lastClientX","lastClientY","currentViewRange","lastActiveTool","scalerLastY","isElementHovered","hoveredElement","isDisableTouchCrossAvailable","canvasCtx","crossCanvas","crossCanvasCtx","isIndicatorPane","hasSeenCrossNotification","onModelUpdate","onElementCreate","onElementDestroy","onElementReplace","onElementSelect","onElementClone","immediateRecountScaleOnChartIndicatorChange","recountScale","ManualChange","onChartUpdate","activeTool","MouseModel","getIsIndicatorPane","componentDidMount","renderAll","initialStoreDrawings","Hammer","touchAction","threshold","onPress","onTouchMove","passive","scrollable","onScalerReset","onZoomerReset","onDoubleClick","forceUpdate","CHART_LAYOUT_CHILD_CHANGE_EVENT","componentWillUnmount","touchEventsDisabled","onPaneClick","paneIndex","getIsHammerAllowScrollActive","isChartPane","getIsChartPane","onPaneMouseMove","onPaneMouseLeave","onResizerMouseDown","initialScrollable","onScalerMouseDown","onMouseEnter","onScalerMouseEnter","onScalerTouchStart","onZoomerMouseDown","onZoomerMouseMove","onZoomerTouchStart","DrawingTool","Mouse","onAddToZoomFactor","diff","shouldCalculateRightAlign","onCanvasInteractionStart","onCanvasInteractionMove","onTouchEnd","onBlur","getChartAlt","cross","isTouchCrossActive","oldElementInstance","isDrawingModeContinuousActive","setSelection","onPaneDestroy","setSelectedElement","clonedElementInstance","setCanvasSize","getArea","onMouseMoveOnScrolling","activeChartInteraction","TouchEvent","targetTouches","dif","addToLeftOffset","onScalerTouchMove","onScalerMouseMove","onScalerTouchEnd","onScalerMouseUp","setActiveChartInteraction","MouseEvent","originalMinMax","currentDiff","originalDiff","getMinMaxLeftOffset","newLeftOffset","fetchOlderData","getElement","openElementStyleDialog","pointerType","onCanvasPress","elementInArea","elementModel","hasProperties","isElementDrawing","onContextMenuClose","makeClone","bringToFront","sendToBack","bringForward","sendBackward","handleRemoveIndicatorPane","element_type","onContextMenuFullyOpen","updateType","requestAnimationFrame","process","_renderAll","getIsUpdatedDesign","renderPane","isCharts","isRedesignedFuturesForexCrypto","isMouseInPane","getShouldRenderCrossInPane","clearRect","isCrossDisabled","PaneModel","getIsDisabled","elementInstance","additionalData","Settings","getSettings","areaRectangle","areaRectangleCursorX","areaRectangleCursorY","chartLeftX","chartRightX","cursorX","cursorY","isCursorInChartWidthBoundaries","isChartsPage","inline","_this","isMouseDownIgnored","zoomControls","paneHeight","touchEvent","setMousePosition","getMousePositionInBoundaries","onCanvasInteractionEnd","Touch","isPrimaryClick","canvasAreaRectangle","chartLeft","chartRight","chartTop","chartBottom","getValueInRange","isSameMouseModel","isSelectionCanvas","getCanvasDOMNode","withNotificationContext","withElementStyleDialogState","ChartSpinnerOverlay","shouldDisplay","setIsVisible","DEFAULT_WRAPPER_COMPONENT","preventDefaultFunc","lastWidth","mouseWheelTimeout","setStateWithPanesTimeout","lastHeight","resizerPaneIndex","minimalPaneHeight","zoomerRightAlign","layoutModel","onLayoutModelChange","panesWrapperElement","onPaneCreate","calculateMinimalPaneHeight","handleQuoteChange","onModelChange","onOlderDataLoaded","Refetch","onDataLoaded","componentDidUpdate","isWheelZoomEnabled","handleSetPanesWrapperRef","renderChartToolbar","isChartPage","getAllValidPanes","showSettings","resetMouseModel","onPinchStart","onWheel","onMouseWheel","addToZoomFactor","calcZoomerRightAlign","activePane","paneId","chartModelParam","panesHeight","newPaneHeight","newChartPaneHeight","newIsScrolled","onResizerMouseMove","onResizerMouseUp","resizePanesAccordingly","total","optiMinHeight","basePane","onZoomerTouchMove","onZoomerTouchEnd","onZoomerMouseUp","getRawDistance","onPinchMove","onPinchEnd","currentLeftOffset","isIntraday","offsetDiff","shouldAlignDaysToLeftApplied","offsetBars","normalizeWheelDeltaY","deltaY","isMouseWheel","diffCoefficient","currentZoomFactor","minBarWidthInPx","maxBarWidthInPx","minZoomFactor","getZoomFactorForBarsToDisplay","chartVisibleWidth","maxZoomFactor","isNegativeDirection","newZoomFactor","newZoomFactorInRange","getZoomFactor","stretch","updateZoomAndLeftOffsetByDateRange","newQuote","shouldForceLeftOffsetUpdate","WrapperComp","isModelDestroyedRef","initChartRef","panesConfig","getQuoteFinancialAttachmentsFromChartConfig","panesWithPerfIndicator","allSettled","paneWithPerfIndicator","prefetchPerfIndicatorAllQuotes","paneProperties","createPaneCascade","shouldResize","chartsDimensions","getChartsDimensions","handleModelBeforeDestroy","isFuturesForexCryptoPage","isModelReady","loadingStyle","hasOutline","withWatchedPanesOnChartModel","drawingCreatorsAsyncModule","drawingActions","DrawingActions","AddNote","DeleteDrawings","DeleteAutoSavedDrawings","getToolbarDrawingActions","isAddNoteAvailable","isIdea","isDisabled","drawingSettings","DrawingSetting","PreserveDrawings","DrawingModeContinuous","HideDrawings","LockDrawings","preserveDrawingsAutosaveOverride","titleAction","getToolbarDrawingSettings","isPreserveDrawingsAndAutosaveAvailable","isAutoSaveInProgress","drawingTools","Xabcd","toolbarDrawingTools","toolGroup","toolGroupTitle","DISABLED_ITEM_TOOLTIP_LABEL","isSidebar","isHorizontal","isMobileOverlay","onActiveToolChange","onDrawingActionClick","onDrawingSettingClick","onDrawingEnd","areToolsDisabled","ignoreRowId","drawingCreatorsModule","isDrawingCreatorsModuleLoading","autoSaveState","setIsDrawing","availableDrawingSettings","availableDrawingActions","isDrawingModeContinuous","hasData","hasHiddenDrawings","tool","drawingToolsTouchCreatorsByType","drawingToolsCreatorsByType","ToolClass","one","ToolbarComponent","isToolLoading","ChartAutoSaveNote","onNoteChange","ChartAutoSaveNotes","setTickers","unwatchedInternalStore","handleChartChange","tickerNoteMap","AutoSaveNotesDialog","isAnimating","isFullyClosed","onAction","onCancel","isAutosaveDialogContent","dialogContent","getDialogContent","ConfirmationDialogComponent","ToolbarMobile","toolbarState","hideToolbar","hideAll","urlSearchParams","setUrlSearchParams","useSearchParams","toolbarMobileElement","setToolbarMobileElement","MOBILE_TOOLBAR_DIV_ID","drawButtonProps","has","SIDEBAR_QUERY_PARAM","params","delete","handleActiveToolChange","drawingTool","handleDrawingActionClick","actionId","AutoSaveStateIndicator","setVisibilityTimeout","newIsVisible","checkIfNeededPreventLeaving","returnValue","hasRedesign","ChartLayoutAutoSaveNote","chartLayoutModelUnwatched","ideaNoteRef","getPublishChartHtmlElements","publishChartElements","getElementsByClassName","getChartImgUrl","imgElement","PublishOldButtonClickListener","dialogConfig","setDialogConfig","isCanvas","chartImgUrl","publishModalModule","publishModalAsyncModule","PublishDialog","publishChartHtmlElements","clickHandler","dataset","indexInt","IdeaDrawingsConfirmationOptions","IdeaLeaveDialog","actionCallback","Cancel","Override","Merge","Nothing","getChartElementTypeFromQueryType","queryType","getChartElementTypeFromResponseType","TA","useChartRouteChange","isIdeasDialogOpen","dateFns","updateChartConfig","urlType","handleTypeChange","urlTicker","urlTimeframe","urlDateRange","getInstrument","newChartConfig","getRawTickerForInstrument","updateAttributesAndSync","exitIdea","defaultPeriod","defaultDateRange","handleIdeaLeave","getUuid","ChartLayoutComponentBase","orientationChangeTimeout","preserveDrawingAbortController","prevModelWidth","prevTimeframeActiveChart","modelProperties","isHideDrawingsActive","isToolbarHorizontal","handleInitialPreserveDrawingsState","DELETE","getPaneWithSelection","touchSize","onChartDestroy","setToolbarPosition","onWindowResize","handleOrientationChange","checkTouchEventsDisabled","quoteTimeframe","throttledResize","preserveDrawings","toolsState","handlePreserveDrawingsSettings","setPreserveDrawings","URLSearchParams","tools_state","handleResize","modelAttrs","isQuoteForexFuturesCryptoPage","newIsToolbarHorizontal","innerWidth","test","getVisualViewportScale","visualViewport","handleDrawingAction","noteDialogState","toggle","handleConfirmationDialogDeleteBtn","drawingToRemove","handleDrawingsSetting","settingId","newObj","toggleHideDrawings","handleLockDrawings","renderToolbar","args","isOverlayToolbar","newCharts","useGrid","isMobilePortrait","isSidebarEnabled","getIsSidebarEnabled","Sidebar","onShouldResize","hasChartTools","renderTools","ideaTitleContainer","ideaTitle","clear","updateLayout","removeCharts","addCharts","rowStart","columnStart","rowEnd","columnEnd","numOfRowsCovered","numOfColumnsCovered","percentageOfRowsCovered","percentageOfColumnsCovered","newWidth","newHeight","settingsHeight","wantedCount","pop","ChartLayoutComponent","flowRight","checkQuoteCacheDebounce","cleanupQuoteCache","allQuotes","allChartQuotes","usedQuote","withCompleteLayoutModelInit","updateChartsTitle","defaultDocumentTitleRef","percentageChange","useChartPageTitle","handleChartsUpdate","getChartLayoutWithChartRouteChange","withQuotePolling","isWithNotifications","parentElement","Wrapper","NotificationWrapper","ChartLayoutWithGlobalState","setChartLayoutModel","getChartLayoutModelConfig","lastGlobalRerender","onRegisterChartLayoutModel","getDefaultZoomFactor","OnInitListener","setIsInit","checkIfInitIsComplete","elementIndex","hasOwnProperty","opacity","newConfig","concat","isQuotePageWithDrawingsOff","getCookie","noteDrawing","ideaObject","newElements","ChartLayoutModel","pollingIntervalToCharts","setPollingIntervalToCharts","checkForChartsWithPolling","newPollingIntervalToCharts","chartRefreshInterval","intervalIdsRef","checkForChartsWithPollingDebounced","chartsCheckerIntervalId","timeoutDurations","allCharts","timeoutDurationsMin","timeoutId","chartIds","quotesToUpdate","quoteToUpdate","dispatchEvent","Event","getIdeaUrl","searchObject","isStockOnQute","queryString","IdeaItem","onIdeaDeleted","isDeleting","setIsDeleting","isConfirmDelete","setIsConfirmDelete","currentIdea","onDeleteIdeaClick","wasDeleted","fetch","status","newUrl","URL","searchParams","company","IdeasTabs","hasError","setHasError","hasFetched","setHasFetched","categorizedIdeas","setCategorizedIdeas","queryTickers","dateParts","processed","tickerIdeas","categorizeIdeas","fetchIdeas","handleIdeaDeleted","modifiedCategories","categoryIndex","updatedCategory","updatedAll","category","IdeasDialog","hasPadding","dropdownButtonClassName","tooltipState","useTooltipState","isAnyQuoteLoading","setIsAnyQuoteLoading","hideTooltip","dropdownItemProps","checkIfAnyQuoteIsLoading","fetchingQuotes","hideOnClick","activeChartQuote","toJSON","chartId","layoutModelObjectPanes","tickersString","getChartTickers","quotesJsonString","quoteTickersTimeframes","getFormDataFromObject","ideaUrl","saveIdea","getIsMobileScreenSize","isDialogOpen","pageTours","getTour","userTour","setCurrentTour","buttonTheme","activeTour","once","CustomDateRangePrefixEnum","DATE_RANGE_PREFIX_DELMITER","getParsedDateRange","startInSec","getTime","endInSec","lastQuoteDateIndex","lastVisibleBarIndex","d1","d5","firstVisibleBarIndex","quoteDate","isQuoteDateInRange","numOfBarsOffset","getChartZoomAndLeftOffset","numOfBarsToRender","numberOfBarsToDraw","daysInQuote","getDaysInQuote","dateRangePrefix","dateRangeValue","Range","dateFromString","dateToString","dateFrom","dateTo","Prev","years","parseCustomDateRangeUrlParam","convertLocalToNyTime","setHours","startDateIndex","m1","m3","m6","ytd","y5","numOfBarsInView","getIntradayChartConfig","timeframeMinutes","barWidthWithMargin","hasPremarket","hasAftermarket","maxWidth","canCropChart","fullChartWidth","marketMinutesLength","getFullChartWidth","offsetInPx","shouldCropChart","chartWidthWithOffset","offsetChartAfter","shouldAlignDaysToLeft","drawDaysInOneChart","lastQuoteDate","barsToOffset","offsetChartInPx","isStockIntraday","isIntradayDateRange","isOffScreen","isOffScreenWithNoDateRange","isOffScreenIntradayDateRange","isOffScreenWithFixedBars","isQuotePageWithNoDateRange","isQuotePageIntradayDateRange","isQuotePageWithFixedBars","getShouldOffsetChartDomain","scaleType","getChartElement","perfChartInstance","numOfBars","handleDomainOffset","currentScale","scaleCreator","protectedHeightPx","minPx","extendedMin","rounded","fromEntries","parsedRange","startQuoteDate","endQuoteDate","numOfDaysToRender","reversedDaysInQuote","startQuoteDayIndex","endQuoteDayIndex","renderDateStart","renderDateEnd","getParsedDateRangeMetaData","shouldRenderCross","DEFAULT_WIDTHS","DEFAULT_CONTEXT","activeModule","isCloseVisible","onResize","selectModule","SidebarContext","useSidebarContext","ModuleLoadFailed","DefaultErrorBoundary","portfolioWatchlistAsyncModule","SidebarModule","sidebarModules","portfolio","description","asyncModule","withInitialLoading","isComponentReady","setIsComponentReady","sidebarModule","withModuleAsyncLoad","mobile","SidebarTabs","isHideOnClick","SidebarContent","defaultMobile","defaultDesktop","desktop","Resizable","enable","handleClasses","defaultSize","tabsClassName","sidebarModuleKey","setActiveModule","handleSelectModule","newUrlSearchParams","handleCloseSidebar","contextValue","ErrorBoundary","FallbackComponent","getInstrumentLabel","getResponseChartType","chartType","chartResponseType","tr","ChartEvent","getChartEventModel","chartEventModel","getXYPosition","hover","isOpenOverride","isCurrentEventActive","scaledArea","Earnings","eventItem","epsActual","epsEstimate","dateTimestamp","chartEventsByType","dividends","earnings","canvasElements","indicatorsByType","elementType","BigNumber","BIG_NUMBER_VALUES","Thousand","Million","Billion","Trillion","BIG_NUMBER_ZEROES","BIG_NUMBER_SUFFIX","dotProduct","crossProduct","pow","lineEquation","j","oddNodes","l2","formatBigNumber","minNumber","absNum","getString","suffix","zeroes","splitString","addZeroes","padEnd","numberByZeroesCount","isInteger","yAxisCoeficient","xAxisCoeficient","radAngle","p3","p4","denominator","ua","ub","checkLineIntersection","line1_p1","line1_p2","line2_p1","line2_p2","onLine1","onLine2","numerator1","numerator2","rayEnd","segmentStart","segmentEnd","lineIntersection","scalar","isSamePoint","ExponentialMovingAverage","multiplier","EMACalculation","MainCalculation","EMAConfig","calculate","onValueCalculated","ema","_calculatedValues","calculatedValues","defaultCalculatedValues","getAllCalculatedValues","lastNItems","getCalculatedValues","getDbColumnName","IndicatorBaseConfig","ADXConfig","Adx","MAX_POSITIVE_DEFAULT_VALUE","MAX_NEGATIVE_DEFAULT_VALUE","periodInt","getParsedIntegersFromPeriodString","labelWidth","shouldUpdate","applyMinMaxPadding","compute","renderIndicator","getIsChartPageSpecificFunctionality","renderLabel","isComputeNecessary","tickTextStep","formatAxis","valueY","lastValueSuffix","indicatorCurrentText","indicatorCurrentBackground","renderLabelChartsPage","renderLabelQuotePage","indicatorLabel","roundedRect","isPerfIndicator","Perf","Shrtfl","renderCrossTextChartsPage","renderCrossTextQuotePage","getValueLabelsAtIndex","renderCrossTextValueLabels","crossValueText","lastRenderedIndex","getValueLabel","unit","getOversoldOverboughtValueLabelsAtIndex","renderOversoldOverbought","zero","drawLines","drawInVisibleAreaProps","fromIndexOffset","getCompensatedFirstBarToRenderIndex","clipHeight","renderZeroLine","tickStep","newAttrs","parsePeriodInt","setModel","areNoBarsVisible","getDomainDefaults","inputsErrorMessages","Rvol","Atr","Aro","Mfi","Rmi","Rsi","Stofu","Ult","Macd","Rwi","Trix","Wr","Aroosc","Roc","Cci","Fi","Shrtra","INDICATOR_DEFAULT_DOMAIN","getIsValid","getIsNumberInputValid","integerOnly","isPositiveInteger","pdi","mdi","adx","amdm","apdm","atr","deltaHigh","deltaLow","pdm","mdm","di","getLineColors","lineColors","AroConfig","aroonUp","aroonDown","oscillator","AroonCalculation","highPeriod","highestInPeriod","periodSinceHigh","lastIndexOf","lowPeriod","lowestInPeriod","periodSinceLow","COLORS","aroonCalculation","textLabels","labelSetting","ArooscConfig","ATRConfig","AverageTrueRange","CCIConfig","cci","smaCount","tp","smaSum","devCount","typicalPrice","sma","devSum","dev","COTConfig","cotQuoteCode","cot","commercialHedgers","largeTraders","smallTraders","secondarylabelX","secondarylabel","units","renderAdditionalLabels","fontSettings","FIConfig","fi","FICalculation","fiCalculation","MACDConfig","fastPeriod","slowPeriod","signalPeriod","macd","histogram","MACDCalculation","emaFast","emaSlow","emaSignal","macdCalculation","signalLine","MFIConfig","mfi","negativeMoneyFlow","mf","prevTypicalPrice","positiveMoneyFlow","moneyFlow","oldMF","NoneConfig","OBVConfig","Obv","obv","currentObv","PerfConfig","indicatorLabelWidth","hasCachedData","getTickersAndTimeframe","quoteSettings","getFromCacheSync","fetchedData","getAll","firstVisibleBar","lastVisibleBar","lastValueIndex","lastTickerTimestamp","canUseCustomMinMax","domainDefaults","getTickers","getTickerColor","hasBackground","tickerValue","isVertical","labelBottom","canFitItemsVertically","tickerTextWidth","performanceIndicatorLabel","crossText","allTickers","hasPatterns","chartUuid","getSanitizedTicker","RMIConfig","momentum","rmi","u","ad","au","sumu","sumd","rs","ROCConfig","roc","RSIConfig","rsi","RsiCalculation","rsiCalculation","RVOLConfig","baseLine","DEFAULT_PARAMETERS","rvol","periodStr","parsePeriod","baseLineY","RWIConfig","rwiHi","rwiLo","trSum","atrWeight","maxHi","maxLo","ShrtflConfig","shortInterest","getComputedValuesAtDateIndex","financialAttachmentsData","computedValues","getLastValue","getValueAtDataIndex","vals","shouldShowDate","isBeforeData","valueLabel","FinancialIndicator","dateIndex","timestampToFinancialsIndexesMap","alignedFinancialAttachmentsData","timestampKey","sourceIndexes","alignedData","lastBeforeDateFinancialsDataIndex","si","sharesFloat","sourceIndex","ShrtraConfig","averageVolume","StofaConfig","Stofa","dPeriod","StofuConfig","kPeriod","k1","dCount","dSum","kSum","kCount","highestHigh","lowestLow","Stochastics","StoslConfig","Stosl","TRIXConfig","trix","TrixCalculation","ema1","ema2","ema3","trixCalculation","UltConfig","period1","period2","period3","ult","bp","bpSum2","bpSum3","count2","count3","trSum2","trSum3","avg2","avg3","bpSum1","trSum1","count1","avg1","VolConfig","WRConfig","aro","aroosc","rwi","stofa","stofu","stosl","vol","wr","shrtfl","shrtra","financialIndicators","getWatchedPropValue","watchedProp","spineObject","getIsSpineObject","hasToObject","getJSONReplacerFunc","getWatchedProps","getAreWatchedPropsEqual","currentValue","previousValue","DEFAULT_SPINE_EVENTS","DefaultSpineEvents","stringifiedOptions","useForceUpdate","watchedPropertiesRef","handleModelChange","spineEvents","hasMany","getChartType","defaultRefreshInterval","Default","customRefreshInterval","Elite","isStockFastRefreshAvailable","EliteStocksReduced","Free","omitKeys","getIsScrollable","perfQuotes","quotePerfTickers","quotePerf","chartOrIndicator","attrsInSync","ChartPartToAttrsSyncMap","modelAttr","chartParts","isInSync","chartPart","isFinancialIndicator","quoteFinancialAttachments","quoteFinancialAttachment","shouldClear","allChartEvents","Crosshair","drawingsInternalStoreModel","chartPartsToSync","newSyncedChartParts","normalizeHexAlpha","customColors","customColorKeys","defaultColors","chartLightTheme","chartDarkTheme","crossTextBackground","negativeChange","overlayTransparentBackground","positiveChange","indicatorLightTheme","indicatorDarkTheme","elementLightTheme","elementDarkTheme","generalColors","newAutoSaveState","generateUuid","getElementZIndexRange","oldInstance","pane_id","clonedObj","cloned","moveToZIndex","currentZIndex","directionCoef","newZIndex","elementsBelowZero","elementsAboveZero","getBelowAboveZeroElements","changeElementZIndexes","elementsArray","addElement","oldZIndex","isBelowZero","isOverlay","refreshElementId","MARKET_START","END_OF_DAY","roundTimeForSyncedPane","sourceChart","targetChart","dateToReturn","sourceChartHasPremarket","targetChartHasPremarket","setDate","lastDayOfMonth","lastDayOfWeek","weekStartsOn","endOfDay","getIsDateBeforeMarketStart","getIsCrossSyncOn","getIsMouseInChartOfPane","paneOfMouse","mouseInChart","currentPaneChart","mousePositionTimestamp","currentPanePositionX","getPriceForPane","mousePaneIndex","getIndexInChart","mouse","CHART_EVENT_BADGE_TYPE_ORDER","chartEventElementModel","move","chartPanes","targetPane","currentChartPaneRecords","records","chart_id","ohterChartPaneRecords","targetRecordIndex","arrayWithoutTargetRecord","chartRecordIndex","panesAbove","panesBelow","getNumericId","isSorted","resetHeight","allPaneElements","rebuildElementZIndexes","hoveredChartEvent","openedChartEvent","hoveredTypeChartEventElements","openedTypeChartEventElements","nonActiveChartEventElements","chartEventsOnSameXPoint","chartEvent_B","isOpened","isHoveredType","isOpenType","quoteCache","getCachedQuote","cachedAt","setCachedQuote","computableKeys","tickerRaw","doesQuoteAndFetchParamsMatch","isSameOrNoChartUuid","is404","isNotEmptyQuote","isCacheAllowed","financialAttachment","doesQuoteAndOptionsMatch","shouldUseCache","getResolvedFetchingPromise","numberOfRefreshChecks","patternsMinRange","patternsMaxRange","dataId","maxBars","tickersAndTimeframes","accumulator","fetchRequest","QuoteFetchTypeUrlOption","New","fetchingPromise","getUrl","NotFoundError","getIsAbortError","shouldUseEmptyQuote","Newer","noNewData","newQuoteData","lastTime","afterTime","AIndex","BIndex","mergeIndex","ADate","BDate","prevAIndex","prevDate","newDate","isSameWeek","isSameMonth","warn","thisDateLength","dataDateLength","atts","drawDays","getBarIndexes","alignAllFinancialAttachmentsDataWithQuoteDates","getChartEventsWithId","alignFinancialAttachmentsDataWithQuoteDates","lastDateIndex","firstDate","matchingQuoteTimestamp","parsedDate","convertedDateToNyTimestamp","dateDate","isSameDay","clearCachedData","deleteCachedQuote","cachedHeikinAshiData","HAClose","heikAshiData","cachedDayToOffset","dateStringFromDate","yyyy","mm","dd","cachedDateToIndex","getTimestampFromPositionX","host","env","BE_API_URL","rev","clearData","largeChartFontSize","INTERACTIVE_CHART_SETTINGS","tickerTimeframeChangeHeight","chartSettings","colorsOverride","settingColors","isLight","getNormalizedZIndex","BaseConfig","Ema","OverlayBaseConfig","BBConfig","Bb","deviations","topColor","bottomColor","upperBand","lowerBand","BbCalculation","stdDev","stdDevSum","OverlayConfig","getFreeColor","periods","getRGBAValueFromValidColorString","BB_COLORS","TOP","BOTTOM","MIDDLE","BollingerBands","scaledTop","scaledBottom","firstBarToRender","lastBarToRender","bbCalculation","DchConfig","Dch","channelStrokeColor","channelFillColor","medianBandColor","DonchianChannels","medianBand","EMA","EMA2Config","Ema2","EMA2","HILOConfig","Hilo","highColor","lowColor","HighLow","prevHigh","prevLow","prevBar","HLineConfig","Hline","isPositiveFloat","ICConfig","Ic","conversion","spanB","spanAStrokeColor","spanAFillColor","spanBStrokeColor","spanBFillColor","conversionLineColor","baseLineColor","laggingSpanColor","Stroke","Fill","Conversion","Base","SpanB","IchimokuCloud","renderFull","outsideBar","conversionLine","senkouSpanA","senkouSpanB","conversionStartIndex","baseStartIndex","spanBIndex","highestHi","lowestLo","lastSpanAX","lastSpanBX","cloudStartingX","toIndexOffset","fxOverride","ICFConfig","Icf","KCHConfig","Kch","emaPeriod","atrPeriod","strokeColor","fillColor","KeltnerChannel","middleLine","PatternsConfig","Patterns","supportColor","resistColor","originalScale","barsInDay","aboveBelow","textHS","above","below","kind","Calculation","PPConfig","Pp","calculationType","PivotPeriod","PivotPoints","getPeriodType","week","getIsEnoughData","startIndex","endIndex","periodType","dayGap","startDay","beforeDay","calculatedX","fromX","toX","currentDate","previousTradingDay","previousNYMidnightTimestamp","currentMidnight","currentNYMidnightTimestamp","isNonStockFullDay","isStockFullDay","firstDayCurrentWeek","firstDayCurrentWeekTimestamp","firstDayPreviousWeek","firstDayPreviousWeekTimestamp","firstDayCurrentMonth","firstDayCurrentMonthTimestamp","firstDayPreviousMonth","firstDayPreviousMonthTimestamp","firstDayCurrentYear","firstDayCurrentYearTimestamp","firstDayPreviousYear","firstDayPreviousYearTimestamp","pivot","sup1","sup2","sup3","res1","res2","res3","previousHigh","previousLow","pivotPoint","currentX","toBars","nextDate","SARConfig","Sar","maxStep","risingColor","fallingColor","SAR","isLong","sar","ep","newHigh","newLow","af","sarToDraw","customizable","SMAConfig","Sma","SMACalculation","SMA","SMA2Config","Sma2","SMA2","StrConfig","Str","uptrendColor","downtrendColor","Supertrend","finalUpperBand","finalLowerBand","supertrend","avg","VPConfig","Vp","upColor","downColor","VP_COLORS","applyOpacityToColor","VolumeProfile","minClose","maxClose","segment","segments","up","down","segmentIndex","isInSegment","volumeTrend","volumeFX","segmentHeightRaw","segmentHeight","upSegmentWidth","downSegmentWidth","VWAPConfig","Vwap","vwap","VWapCalculation","cumulativePV","cumulativeVolume","second","datesAreOnSameDay","VWAP","bb","dch","hilo","hline","ic","icf","kch","pp","sma2","vp","arg","_len2","_key2","_len3","_key3","devicePixelRatio","getQuoteDateTimestampOffsetInSeconds","referenceDate","dayNumber","monthIndex","previousSunday","getDay","getIsDstInNy","getUTCFullYear","getUTCMonth","getUTCDate","getUTCHours","getUTCMinutes","getUTCSeconds","addOffset","quoteDateTimeOffsetInMs","localTimeOffsetInMs","getTimezoneOffset","offsetDirectionCoefficient","setTime","bufferMinutes","dayOfWeek","currentDayMinutes","premarketMinutes","aftermarketMinutes","isWeekend","isClosed","setUTCSeconds","testTouchPoints","isMobileOs","navigator","userAgent","createEvent","match","msMaxTouchPoints","maxTouchPoints","matchesIPad","matchesIPhone","matchesIPod","re","RegExp","cookie","toUTCString","fullscreenElement","webkitFullscreenElement","mozFullScreenElement","msFullscreenElement","webkitRequestFullScreen","mozRequestFullScreen","msRequestFullscreen","webkitExitFullscreen","mozExitFullScreen","msExitFullscreen","fn","readyState","chartElementId","box","matchingPages","requestsAbortControllersCache","abortRequest","websiteShared","shouldUseCPUOnly","matchesAndroid","matchesWebOS","matchesiPad","matchesBlackBerry","matchesWindowsPhone","matchesIOSLike","isFirefoxDesktop","getContext","willReadFrequently","_cache","_restore","CanvasRenderingContext2D","getChartEventBadgeColors","outerStroke","innerStroke","innerFill","textFill","getFormattedEventDate","exdate","hasEarningsDateSuffix","formattedDate","formatDateToStringUS","getEarningsDateSuffix","getFormattedValue","bigNumberUnit","maxDecimalPlaces","numberString","bigNumber","wholeNumber","decimalNumber","formattedDecimalNumber","getChartEventBageColors","twColors","DAY_IN_SECONDS","TWO_MIN_IN_MS","virtualDatesCache","areTimestampsFromSameDay","ts1","ts2","ts1Utc","ts2Utc","getVirtualDatesCacheId","idRevision","setCachedVirtualDates","fromSeconds","toSeconds","virtualDates","virtualDatesCacheId","lastUsed","checkVirtualCacheSize","MAX_BAR_BORDER_WIDTH","MIN_BAR_MARGIN_WIDTH","MAX_BAR_MARGIN_WIDTH","settingsCenter","barMarginWidth","shouldRound","roundDecimalPlaces","halfBarWidthRaw","DEFAULT_ZOOM_GUESS_INCREMENT","zoomFactorForBarsToDisplayCache","zoomFactorForBarsToDisplayCacheKeys","getZoomFactorFromCache","setZoomFactorToCache","poppedKey","defaultBarWidthWithMargin","zoomIncrement","finalZoomFactor","iteration","barWidthDiff","getTimeframeSeconds","lowerIndex","upperIndex","isWithinRangeOfQuoteDate","commonVirtualCacheProps","cachedDates","virtualDateSeconds","getCachedVirtualDates","timeframeSeconds","numOfDatesBefore","numOfDatesAfter","virtualTradedDays","dateStartSeconds","dateEndSeconds","datesSeconds","isStartBeforeDates","isEndAfterDates","dateTime","getVirtualTradedDays","marketStartSeconds","barTimeframeSeconds","quoteDatesTimestampOffset","dayStartSeconds","barSeconds","virtualTimeframeTradedDates","isLowerBounded","isOneBeforeLowerBoundStarts","isLookingBack","averageBarDate","numOfSecondsOutOfBounds","perfIndicatorElement","getPerfIndicatorTickerAndTimeframes","resolve","isXAxisInView","domainRange","priceFy","YAxisLeftMargin","firstBarClose","_ref20","changePercent","changePercentString","_ref21","isForexFuturesCryptoPage","_ref22","isForexFuturesCrypto","isOffscreenChartWithNarrowBars","isQuoteChartWithNarrowBars","_ref23","_ref24","allowAlpha","dataBarIndex","isBarVisible","object","formData","append","FormData","statusCode","throwOnPredicate","url","credentials","headers","responseContentType","Html","responseData","ApplicationJsonUTF","FormUrlEncoded","parseResponseForContentType","getStatusCodeError","forceUpdateKey","increment","precision","periodString","part","parsedNumber","MAX_SAFE_INTEGER","visited","WeakSet","toLocaleDateString","crypto","randomUUID","getRandomValues","Uint8Array","two","local","remote","useChartLayoutGlobalModelModule","useChartLayoutGlobalModel"],"sourceRoot":""}