{"version":3,"file":"8968.89662cc6.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/hooks/use-popover-maxHeight.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/list/hooks.tsx","webpack://@finviz/website/./js/main/components/list/list-item.tsx","webpack://@finviz/website/./js/main/components/list/list.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/popover/hooks.ts","webpack://@finviz/website/./js/main/components/toolbar/popover/popover.tsx","webpack://@finviz/website/./js/main/components/toolbar/popover/popover-trigger.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/hooks/use-window-size.tsx","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/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/tool-button.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/indicator.ts","webpack://@finviz/website/../charts/app/utils/canvas-render.ts","webpack://@finviz/website/../charts/app/indicators/adx.ts","webpack://@finviz/website/../charts/app/indicator-calculation/aroon.ts","webpack://@finviz/website/../charts/app/indicators/aro.ts","webpack://@finviz/website/../charts/app/indicators/aroosc.ts","webpack://@finviz/website/../charts/app/indicators/atr.ts","webpack://@finviz/website/../charts/app/indicators/cci.ts","webpack://@finviz/website/../charts/app/indicators/cot.ts","webpack://@finviz/website/../charts/app/indicator-calculation/fi.ts","webpack://@finviz/website/../charts/app/indicators/fi.ts","webpack://@finviz/website/../charts/app/indicator-calculation/macd.ts","webpack://@finviz/website/../charts/app/indicators/macd.ts","webpack://@finviz/website/../charts/app/indicators/mfi.ts","webpack://@finviz/website/../charts/app/indicators/none.ts","webpack://@finviz/website/../charts/app/indicators/obv.ts","webpack://@finviz/website/../charts/app/indicators/perf.ts","webpack://@finviz/website/../charts/app/indicators/rmi.ts","webpack://@finviz/website/../charts/app/indicators/roc.ts","webpack://@finviz/website/../charts/app/indicator-calculation/rsi.ts","webpack://@finviz/website/../charts/app/indicators/rsi.ts","webpack://@finviz/website/../charts/app/indicators/rvol.ts","webpack://@finviz/website/../charts/app/indicators/rwi.ts","webpack://@finviz/website/../charts/app/indicators/stofu.ts","webpack://@finviz/website/../charts/app/indicators/stofa.ts","webpack://@finviz/website/../charts/app/indicators/stosl.ts","webpack://@finviz/website/../charts/app/indicator-calculation/trix.ts","webpack://@finviz/website/../charts/app/indicators/trix.ts","webpack://@finviz/website/../charts/app/indicators/ult.ts","webpack://@finviz/website/../charts/app/indicators/vol.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/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/dch.ts","webpack://@finviz/website/../charts/app/overlays/ema.ts","webpack://@finviz/website/../charts/app/overlays/ema2.ts","webpack://@finviz/website/../charts/app/overlays/hilo.ts","webpack://@finviz/website/../charts/app/overlays/hline.ts","webpack://@finviz/website/../charts/app/overlays/ic.ts","webpack://@finviz/website/../charts/app/overlays/icf.ts","webpack://@finviz/website/../charts/app/overlays/kch.ts","webpack://@finviz/website/../charts/app/overlays/none.ts","webpack://@finviz/website/../charts/app/overlays/patterns.ts","webpack://@finviz/website/../charts/app/overlays/pp.ts","webpack://@finviz/website/../charts/app/overlays/sar.ts","webpack://@finviz/website/../charts/app/indicator-calculation/sma.ts","webpack://@finviz/website/../charts/app/overlays/sma.ts","webpack://@finviz/website/../charts/app/overlays/sma2.ts","webpack://@finviz/website/../charts/app/overlays/str.ts","webpack://@finviz/website/../charts/app/overlays/vp.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 ElementModel from '../models/element'\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 Pane from './pane'\r\n\r\nconst badgeImages = {} as ObjectHash<{ image: HTMLImageElement; isLoaded?: boolean }, string>\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 // 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.src = `data:image/svg+xml,${encodeURIComponent(svgHTML)}`\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 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 {\r\n Button,\r\n Dropdown,\r\n DropdownItem,\r\n DropdownSeparator,\r\n Icon,\r\n IconNameType,\r\n Paragraph,\r\n useDropdownState,\r\n} 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 const state = useDropdownState({ placement: 'bottom', orientation: 'horizontal' })\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","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\r\n// Re-export Portal so we can use it when we can’t use `modal` components (see chart event popover)\r\nexport { Portal as AriakitPortal } from '@ariakit/react'\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}\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) => {\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) => {\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 React from 'react'\r\n\r\nimport { DropdownStateReturn } from '../components/dropdown'\r\nimport { PopoverStateReturn } from '../components/toolbar/popover/hooks'\r\nimport { useWindowSize } from './use-window-size'\r\n\r\ntype Props = {\r\n maxHeightLimit: number\r\n hasViewportHeightLimit: boolean\r\n offsets: [number, number]\r\n state: DropdownStateReturn | PopoverStateReturn\r\n}\r\n\r\nconst MAX_HEIGHT_PROPERTY = '--popover-max-height'\r\nconst POPOVER_HEIGHT_LIMIT_STYLE = {\r\n maxHeight: `calc(var(${MAX_HEIGHT_PROPERTY}) - env(safe-area-inset-bottom))`,\r\n}\r\n\r\n/**\r\n * Limit popover height to be always in viewport is `hasViewportHeightLimit` is true\r\n */\r\nexport function usePopoverMaxHeight({ maxHeightLimit, hasViewportHeightLimit, offsets, state }: Props) {\r\n const { innerHeight } = useWindowSize({ isWatching: state.visible || state.animating })\r\n const buttonElement = state.unstable_referenceRef.current\r\n\r\n React.useEffect(() => {\r\n if (!buttonElement || !state.visible || !hasViewportHeightLimit) return\r\n\r\n // calculate height\r\n const buttonRect = buttonElement.getBoundingClientRect()\r\n const [, offsetY] = offsets\r\n let elementMaxHeight = 'auto'\r\n if (state.placement.startsWith('bottom')) {\r\n let height = innerHeight - buttonRect.bottom - offsetY * 2\r\n // when used on pages where is scrollable content, buttonRect.bottom is sometimes negative\r\n // in that case we need to subtract window.scrollY\r\n if (buttonRect.bottom < 0) height -= window.scrollY\r\n elementMaxHeight = `${Math.min(height, maxHeightLimit)}px`\r\n } else {\r\n const height = buttonRect.top - offsetY * 2\r\n elementMaxHeight = `${Math.min(height, maxHeightLimit)}px`\r\n }\r\n\r\n // set height\r\n const popoverId = buttonElement.getAttribute('aria-controls')\r\n const popoverWrapper = popoverId ? document.getElementById(popoverId) : null\r\n popoverWrapper?.style.setProperty(MAX_HEIGHT_PROPERTY, elementMaxHeight)\r\n }, [buttonElement, innerHeight, maxHeightLimit, hasViewportHeightLimit, offsets, state.placement, state.visible])\r\n\r\n return hasViewportHeightLimit ? POPOVER_HEIGHT_LIMIT_STYLE : undefined\r\n}\r\n","import * as React from 'react'\r\nimport { usePopper } from 'react-popper'\r\n\r\nimport { usePopoverMaxHeight } from '../../hooks/use-popover-maxHeight'\r\nimport { Button } from '../button'\r\nimport { getExtendedDialogState } from '../dialog'\r\nimport { Dropdown, DropdownItem, DropdownSeparator, useDropdownState } from '../dropdown'\r\nimport { ObjectHash } from '../types'\r\n\r\nconst DEFAULT_OFFSETS: [number, number] = [5, 5]\r\n\r\nfunction getVirtualRef(top: number, left: number) {\r\n return {\r\n getBoundingClientRect(): DOMRect {\r\n const rect = {\r\n top: top - window.scrollY,\r\n x: top - window.scrollY,\r\n left: left - window.scrollX,\r\n y: left - window.scrollX,\r\n bottom: top,\r\n right: left,\r\n width: 0,\r\n height: 0,\r\n }\r\n\r\n return {\r\n ...rect,\r\n toJSON: () => rect,\r\n }\r\n },\r\n }\r\n}\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 ContextMenuProps {\r\n /**\r\n * Top coordinate of the click\r\n */\r\n top: number\r\n\r\n /**\r\n * Left coordinate of the click\r\n */\r\n left: number\r\n\r\n /**\r\n * Can limit the max height of the menu\r\n *\r\n * @default undefined\r\n */\r\n menuMaxHeight?: number\r\n\r\n /**\r\n * Items visible in the menu\r\n */\r\n items: ContextMenuItem[]\r\n\r\n /**\r\n * Callback to hide the menu\r\n */\r\n hide: () => void\r\n}\r\n\r\nexport function ContextMenu({ top, left, menuMaxHeight, hide, items }: ContextMenuProps) {\r\n const [popperElement, setPopperElement] = React.useState(null)\r\n const virtualRef = React.useMemo(() => getVirtualRef(top, left), [left, top])\r\n const dropdownState = useDropdownState({ placement: 'bottom-start' })\r\n const { isFullyClosed } = getExtendedDialogState(dropdownState)\r\n const hasBeenOpen = React.useRef(false)\r\n\r\n const { styles, attributes } = usePopper(virtualRef, popperElement, {\r\n placement: 'auto-end',\r\n modifiers: [\r\n {\r\n name: 'offset',\r\n options: {\r\n offset: DEFAULT_OFFSETS,\r\n },\r\n },\r\n ],\r\n })\r\n\r\n /**\r\n * This effect handles closing the context menu (parent element) itself\r\n */\r\n React.useEffect(() => {\r\n if (isFullyClosed && hasBeenOpen.current) hide()\r\n }, [isFullyClosed, hide])\r\n\r\n /**\r\n * This effect handles opening/closing the inner dropdown\r\n */\r\n React.useEffect(() => {\r\n dropdownState.show()\r\n hasBeenOpen.current = true // This acts as a way to differentiate the first render\r\n\r\n return () => dropdownState.hide()\r\n // This needs to run only on mount/unmount for obvious reasons\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n }, [])\r\n\r\n return (\r\n \r\n }\r\n menuMaxHeight={menuMaxHeight}\r\n state={dropdownState}\r\n items={items}\r\n isStatic\r\n />\r\n \r\n )\r\n}\r\n\r\ninterface ContextMenuInnerProps {\r\n label: JSX.Element\r\n items: ContextMenuItem[]\r\n state: ReturnType\r\n isStatic?: boolean\r\n menuMaxHeight?: number\r\n}\r\n\r\nfunction ContextMenuInner(\r\n { label, items, state, isStatic, menuMaxHeight = Number.MAX_SAFE_INTEGER }: ContextMenuInnerProps,\r\n ref: React.ForwardedRef\r\n) {\r\n const innerState = useDropdownState({ placement: 'right-start' })\r\n const maxHeightStyle = usePopoverMaxHeight({\r\n maxHeightLimit: menuMaxHeight,\r\n hasViewportHeightLimit: true,\r\n offsets: DEFAULT_OFFSETS,\r\n state,\r\n })\r\n\r\n return (\r\n \r\n {items.map((item, index) => {\r\n if (item.type === 'divider') {\r\n return {item.label}\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 items={item.options}\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 className=\"shrink-0\"\r\n >\r\n {item.label}\r\n \r\n )\r\n })}\r\n \r\n )\r\n}\r\n\r\nconst ContextMenuDropdown = 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 * as React from 'react'\r\nimport * as Reakit from 'reakit/Composite'\r\n\r\nimport { SelectItem } from '../select'\r\nimport { PopoverStateReturn } from '../toolbar/popover/hooks'\r\n\r\nexport const ListContext = React.createContext(null)\r\n\r\nexport function useListState(options?: Reakit.CompositeInitialState) {\r\n return Reakit.useCompositeState({ ...options, loop: true, unstable_virtual: true })\r\n}\r\n\r\nfunction getSelectedItemIndex(items: SelectItem[], value: unknown) {\r\n if (!value && value !== 0) return -1\r\n\r\n return items.findIndex((item) => item.value === value)\r\n}\r\n\r\n/**\r\n * Hook which handles select state and returns onChange handler\r\n */\r\nexport function useList>(\r\n state: PopoverStateReturn,\r\n defaultValue: ValueType | undefined,\r\n items: ItemType[],\r\n onChange: (item: ItemType) => void\r\n) {\r\n const [selectedIndex, setSelectedIndex] = React.useState(getSelectedItemIndex(items, defaultValue))\r\n const closePopover = React.useRef(() => state.hide())\r\n\r\n // Update select value on change from outside\r\n React.useEffect(() => {\r\n const newIndex = getSelectedItemIndex(items, defaultValue)\r\n setSelectedIndex(newIndex)\r\n }, [items, selectedIndex, defaultValue])\r\n\r\n const onItemChange = React.useCallback(\r\n (index: number, closeOnSelect = true) => {\r\n const selectedItem = items[index]\r\n setSelectedIndex(index)\r\n\r\n if (closeOnSelect) closePopover.current()\r\n onChange(selectedItem)\r\n },\r\n [items, onChange, setSelectedIndex]\r\n )\r\n\r\n return { selectedIndex, onItemChange }\r\n}\r\n","import classnames from 'classnames'\r\nimport * as React from 'react'\r\nimport * as Reakit from 'reakit/Composite'\r\n\r\nimport { BUTTON_DEFAULT_ELEMENT, Button, ButtonComponentProps, ButtonTheme } from '../button'\r\nimport { ListContext } from './hooks'\r\n\r\nexport interface ListItemProps {\r\n /**\r\n * Theme when the button is selected\r\n */\r\n activeTheme?: keyof typeof ButtonTheme\r\n\r\n /**\r\n * Close parent popover when the item is clicked\r\n */\r\n closeOnSelect?: boolean\r\n\r\n /**\r\n * OnChange callback when item is clicked or navigated to\r\n * @private\r\n */\r\n onSelectItem?: (item: string, closeOnSelect?: boolean) => void\r\n}\r\n\r\nexport function ListItem({\r\n as,\r\n activeTheme = 'blue',\r\n onSelectItem,\r\n onClick,\r\n onKeyPress,\r\n className,\r\n closeOnSelect = true,\r\n children,\r\n ...props\r\n}: React.PropsWithChildren & ButtonComponentProps) {\r\n const state = React.useContext(ListContext)\r\n\r\n return (\r\n {\r\n onClick?.(ev)\r\n onSelectItem?.(ev.currentTarget.id, closeOnSelect)\r\n }}\r\n onKeyPress={(ev) => {\r\n onKeyPress?.(ev)\r\n onSelectItem?.(ev.currentTarget.id, closeOnSelect)\r\n }}\r\n >\r\n {(itemProps: ButtonComponentProps) => {\r\n const active = Boolean(itemProps['aria-selected'])\r\n\r\n return (\r\n \r\n {children}\r\n \r\n )\r\n }}\r\n \r\n )\r\n}\r\n","import classnames from 'classnames'\r\nimport * as React from 'react'\r\nimport * as Reakit from 'reakit/Composite'\r\n\r\nimport { ListContext } from './hooks'\r\nimport { ListItem } from './list-item'\r\n\r\nexport enum ListDirection {\r\n row,\r\n column,\r\n}\r\n\r\nexport interface ListProps extends Omit {\r\n /**\r\n * The returned object from `useListState`\r\n */\r\n state: Reakit.CompositeStateReturn\r\n\r\n /**\r\n * The selected option\r\n */\r\n selectedIndex?: number\r\n\r\n /**\r\n * Callback when selected option index changes\r\n */\r\n onChange?: (selectedIndex: number, closeParent?: boolean) => void\r\n\r\n /**\r\n * Direction to render items\r\n * @default col\r\n */\r\n direction?: keyof typeof ListDirection\r\n\r\n /**\r\n * Whether or not default styles should be included for the list\r\n * @default true\r\n */\r\n includeBaseStyles?: boolean\r\n}\r\n\r\nexport function List({\r\n state,\r\n selectedIndex,\r\n direction = 'column',\r\n includeBaseStyles = true,\r\n onChange,\r\n children,\r\n ...props\r\n}: ListProps) {\r\n const prevSelected = React.useRef(null)\r\n\r\n // Select option when `selectedIndex` changes\r\n React.useEffect(() => {\r\n if (\r\n selectedIndex !== undefined &&\r\n selectedIndex >= 0 &&\r\n prevSelected.current !== selectedIndex &&\r\n state.items.length > selectedIndex\r\n ) {\r\n state.move(state.items[selectedIndex].id)\r\n prevSelected.current = selectedIndex\r\n }\r\n }, [selectedIndex, state, state.items.length])\r\n\r\n const onSelectItem = React.useCallback(\r\n (id: string, closeParent: boolean) => {\r\n onChange?.(\r\n state.items.findIndex((item) => item.id === id),\r\n closeParent\r\n )\r\n },\r\n [onChange, state.items]\r\n )\r\n\r\n return (\r\n \r\n \r\n {React.Children.map(children, (child) => {\r\n if (!React.isValidElement(child)) return child\r\n\r\n if (child.type === ListItem) {\r\n return React.cloneElement(child, { ...child.props, onSelectItem: onSelectItem })\r\n }\r\n\r\n return child\r\n })}\r\n \r\n \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 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 { 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 p-1.5 bg-white dark:bg-gray-800', {\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 'relative z-10 rounded-md border border-gray-100 dark:border-gray-600': isMobile,\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 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 // reason for key is that popover is sealing initial state, description in\r\n // https://github.com/finvizhq/Finviz-Website/pull/402\r\n return (\r\n \r\n {children}\r\n \r\n )\r\n}\r\n","import 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 theme,\r\n isActive,\r\n isStretched,\r\n isInAction,\r\n}: {\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 {\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 '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 item: IToolbarItem\r\n disabledTooltip?: string\r\n isInAction?: boolean\r\n isLoading?: boolean\r\n}\r\n\r\nexport function ToolbarButton({\r\n item,\r\n disabledTooltip,\r\n isInAction: isInActionProp,\r\n isLoading,\r\n ...props\r\n}: PropsWithAs & ToolbarButtonProps) {\r\n const { theme, isStretched } = useToolbarContext()\r\n const isInAction = isInActionProp && item.iconAction !== undefined\r\n const buttonSettings = getButtonThemeSettings({\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 & ToolbarButtonProps)}\r\n appearance={props.appearance ?? 'square'}\r\n title={props.disabled && disabledTooltip ? disabledTooltip : (props.active && item.titleActive) || item.title}\r\n size={\r\n buttonSettings.size ??\r\n (theme === ToolbarTheme.chipTransparent || FinvizSettings.hasRedesignEnabled ? 'medium' : 'large')\r\n }\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","import * as React from 'react'\r\nimport * as Reakit from 'reakit/Popover'\r\n\r\nimport { COMPONENT_ANIMATION_DURATION } from '../../constants'\r\n\r\nexport type PopoverStateReturn = ReturnType\r\n\r\nconst DEFAULT_OFFSET: [number, number] = [0, 5]\r\nconst HOVER_TIMEOUT = 150\r\n\r\nconst preventDefault = (ev: React.MouseEvent) => {\r\n ev.preventDefault()\r\n}\r\n\r\n/**\r\n * Hook which provides state to dialogs\r\n */\r\nexport function usePopoverState(settings?: Reakit.PopoverInitialState) {\r\n const offsets = (settings?.unstable_offset ?? DEFAULT_OFFSET) as [number, number]\r\n const popover = Reakit.usePopoverState({\r\n ...settings,\r\n placement: settings?.placement ?? 'bottom-start',\r\n unstable_offset: offsets,\r\n animated: COMPONENT_ANIMATION_DURATION,\r\n modal: false,\r\n })\r\n\r\n return { ...popover, offsets }\r\n}\r\n\r\nexport function useHoverPopover(settings?: Reakit.PopoverInitialState) {\r\n const popover = usePopoverState(settings)\r\n const showTimeout = React.useRef(null)\r\n const hideTimeout = React.useRef(null)\r\n\r\n const clearTimeouts = React.useRef(() => {\r\n if (showTimeout.current !== null) {\r\n window.clearTimeout(showTimeout.current)\r\n }\r\n if (hideTimeout.current !== null) {\r\n window.clearTimeout(hideTimeout.current)\r\n }\r\n })\r\n\r\n const showPopover = React.useRef(() => {\r\n clearTimeouts.current()\r\n showTimeout.current = window.setTimeout(() => {\r\n popover.show()\r\n }, HOVER_TIMEOUT)\r\n })\r\n\r\n const hidePopover = React.useRef(() => {\r\n clearTimeouts.current()\r\n hideTimeout.current = window.setTimeout(() => {\r\n popover.hide()\r\n }, HOVER_TIMEOUT)\r\n })\r\n\r\n // Unmount cleanup\r\n React.useEffect(() => () => clearTimeouts.current(), [])\r\n\r\n return {\r\n ...popover,\r\n show: showPopover.current,\r\n hide: hidePopover.current,\r\n onMouseOver: showPopover.current,\r\n onMouseOut: hidePopover.current,\r\n onMouseDown: preventDefault,\r\n }\r\n}\r\n","import classnames from 'classnames'\r\nimport * as React from 'react'\r\nimport * as Reakit from 'reakit/Popover'\r\nimport { Portal } from 'reakit/Portal'\r\n\r\nimport { usePopoverMaxHeight } from '../../../hooks/use-popover-maxHeight'\r\nimport { useWindowSize } from '../../../hooks/use-window-size'\r\nimport { Box, BoxProps } from '../../box'\r\nimport { getExtendedDialogState, useZIndex } from '../../dialog'\r\nimport { PopoverStateReturn } from './hooks'\r\n\r\nexport interface PopoverProps extends BoxProps, Pick {\r\n /**\r\n * The returned object from `usePopoverState`\r\n */\r\n state: PopoverStateReturn\r\n\r\n /**\r\n * Focus the popover when it opens\r\n *\r\n * @default true\r\n */\r\n focusOnShow?: Reakit.PopoverProps['unstable_autoFocusOnShow']\r\n\r\n /**\r\n * Focus the anchor element when it closes\r\n *\r\n * @default true\r\n */\r\n focusOnHide?: Reakit.PopoverProps['unstable_autoFocusOnHide']\r\n\r\n /**\r\n * Focus the anchor element when it closes\r\n *\r\n * @default undefined\r\n */\r\n finalFocusRef?: Reakit.PopoverProps['unstable_finalFocusRef']\r\n\r\n /**\r\n * Hides when clicked outside of popover, works with changing focus from the trigger component to another one\r\n *\r\n * @default true\r\n */\r\n hideOnClickOutside?: Reakit.PopoverProps['hideOnClickOutside']\r\n\r\n /**\r\n * Overlay click callback or if false is provided, overlay click calls hide func on popover state object\r\n *\r\n * @default undefined\r\n */\r\n onOverlayClick?: (() => void) | false\r\n\r\n /**\r\n * Popover wrapper css style object\r\n *\r\n * @default undefined\r\n */\r\n popoverWrapperStyle?: React.CSSProperties\r\n\r\n /**\r\n * Show popover arrow\r\n *\r\n * @default false\r\n */\r\n hasArrow?: boolean\r\n\r\n /**\r\n * Enable or disable backdrop click events\r\n *\r\n * @default true\r\n */\r\n hasBackdrop?: boolean\r\n\r\n /**\r\n * Set the popover to height to be limited by the viewport instead of having full height\r\n *\r\n * @default false\r\n */\r\n hasViewportHeightLimit?: boolean\r\n\r\n /**\r\n * Set the popover max-width to be limited by the trigger button\r\n */\r\n hasButtonWidthLimit?: boolean\r\n\r\n /**\r\n * Can be used together with `hasViewportHeightLimit` to limit the height of the popover\r\n *\r\n * @default undefined\r\n */\r\n popoverMaxHeight?: number\r\n}\r\n\r\nexport function Popover({\r\n state,\r\n children,\r\n focusOnShow = true,\r\n focusOnHide = true,\r\n finalFocusRef,\r\n 'aria-label': ariaLabel,\r\n hide,\r\n hideOnClickOutside = true,\r\n hasBackdrop = true,\r\n onOverlayClick,\r\n popoverWrapperStyle,\r\n popoverMaxHeight = Number.MAX_SAFE_INTEGER,\r\n theme = 'light',\r\n hasViewportHeightLimit = false,\r\n hasButtonWidthLimit = false,\r\n ...props\r\n}: PopoverProps) {\r\n const zIndex = useZIndex()\r\n const { isFullyClosed } = getExtendedDialogState(state)\r\n const { innerHeight } = useWindowSize({ isWatching: !isFullyClosed })\r\n\r\n const buttonElement = state.unstable_referenceRef.current\r\n const maxHeightStyle = usePopoverMaxHeight({\r\n maxHeightLimit: popoverMaxHeight,\r\n hasViewportHeightLimit,\r\n offsets: state.offsets,\r\n state,\r\n })\r\n\r\n React.useEffect(() => {\r\n if (!buttonElement || !state.visible || !(hasViewportHeightLimit || hasButtonWidthLimit)) return\r\n\r\n const buttonRect = buttonElement.getBoundingClientRect()\r\n const popoverId = buttonElement.getAttribute('aria-controls')\r\n const popoverWrapper = popoverId ? document.getElementById(popoverId) : null\r\n\r\n // Limit popover max-width to be width of the trigger button\r\n if (hasButtonWidthLimit) {\r\n popoverWrapper?.style.setProperty('max-width', `${buttonRect.width}px`)\r\n }\r\n }, [\r\n state.visible,\r\n state.offsets,\r\n buttonElement,\r\n hasViewportHeightLimit,\r\n hasButtonWidthLimit,\r\n innerHeight,\r\n state.placement,\r\n popoverMaxHeight,\r\n ])\r\n\r\n if (isFullyClosed) return null\r\n\r\n return (\r\n \r\n \r\n {({ onTransitionEnd, onAnimationEnd, ...innerProps }) => (\r\n <>\r\n {\r\n // prevents from page scroll when clicked outside of popover\r\n event.preventDefault()\r\n }}\r\n />\r\n \r\n \r\n {children}\r\n \r\n \r\n \r\n )}\r\n \r\n \r\n )\r\n}\r\n","import classnames from 'classnames'\r\nimport * as React from 'react'\r\nimport * as Reakit from 'reakit/Popover'\r\n\r\nimport { useZIndex } from '../../dialog'\r\n\r\ninterface PopoverButtonProps extends Reakit.PopoverDisclosureHTMLProps {\r\n state: Reakit.PopoverStateReturn\r\n as?: React.ElementType\r\n}\r\n/**\r\n * The trigger button component which handles ref & focus return, etc.\r\n */\r\nexport const PopoverTrigger = React.forwardRef(\r\n ({ state, ...props }: PopoverButtonProps, ref: React.ForwardedRef) => {\r\n const zIndex = useZIndex()\r\n\r\n return (\r\n \r\n {props.children}\r\n \r\n )\r\n }\r\n)\r\n","import classnames from 'classnames'\r\nimport * as React from 'react'\r\n\r\nimport { isMobile } from '../../../app/shared/isMobile'\r\nimport { Icon } from '../icon'\r\nimport { List, ListItem, useListState } from '../list'\r\nimport { useList } from '../list/hooks'\r\nimport { NativeSelect } from '../select/NativeSelect'\r\nimport { useToolbarContext } from './hooks'\r\nimport { IToolbarItem, ToolbarTheme } from './interfaces'\r\nimport { useHoverPopover } from './popover/hooks'\r\nimport { Popover } from './popover/popover'\r\nimport { PopoverTrigger } from './popover/popover-trigger'\r\nimport { ToolbarButton } from './toolbar-button'\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\r\nexport function ToolbarGroup({\r\n defaultItem,\r\n isActive,\r\n isLoading,\r\n groupItems,\r\n groupTitle,\r\n onChange,\r\n useNativeSelect = isMobile(),\r\n disabled,\r\n disabledTooltip,\r\n}: ToolbarGroupProps) {\r\n const listState = useListState({ currentId: null })\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 const popoverState = useHoverPopover({\r\n placement: isAlternativeTheme && isStretched ? 'bottom' : 'right-start',\r\n })\r\n const select = useList(\r\n popoverState,\r\n selectedItem.id,\r\n groupItems?.map((i) => ({ value: i.id, label: i.title })) ?? [],\r\n (option) => {\r\n setSelectedItem(groupItems![groupItems!.findIndex((item) => item.id === option.value)])\r\n onChange(option.value, 'select')\r\n }\r\n )\r\n\r\n return (\r\n \r\n ) => {\r\n ev.preventDefault()\r\n ev.stopPropagation()\r\n onChange(selectedItem.id, 'group')\r\n }}\r\n >\r\n \r\n \r\n \r\n\r\n {useNativeSelect ? (\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 {groupItems.map((item) => (\r\n }\r\n data-testid={`toolbar-group-${groupId}-${item.id}`}\r\n >\r\n {item.title}\r\n \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}: 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, InputHTMLProps, InputProps } from './input'\r\nimport { Tooltip, TooltipColor, TooltipProps, TooltipTrigger, useTooltipState } from './tooltip'\r\n\r\ntype TooltipInputProps = InputProps & InputHTMLProps & { isInteractive?: boolean }\r\n\r\ninterface TooltipSettingsProps extends Pick, Pick {\r\n content?: React.ReactNode\r\n color?: keyof typeof TooltipColor\r\n}\r\n\r\nexport interface TooltipInputWrapperProps extends Pick {\r\n children: React.ReactElement\r\n /**\r\n * Settings for Tooltip component and useTooltipStore\r\n */\r\n tooltipSettings?: TooltipSettingsProps\r\n}\r\n\r\nfunction TooltipInputWrapper({ children, tooltipSettings = {}, name }: TooltipInputWrapperProps) {\r\n const { content, color, gutter, placement = 'bottom' } = tooltipSettings\r\n const tooltip = useTooltipState({ placement })\r\n\r\n return (\r\n <>\r\n \r\n {React.cloneElement(children, {\r\n onFocus: (event: React.FocusEvent) => {\r\n children.props.onFocus?.(event)\r\n tooltip.show()\r\n },\r\n onBlur: (event: React.FocusEvent) => {\r\n children.props.onBlur?.(event)\r\n tooltip.hide()\r\n },\r\n })}\r\n \r\n {content && (\r\n \r\n {content}\r\n \r\n )}\r\n \r\n )\r\n}\r\n\r\nfunction TooltipInputComponent(\r\n { tooltipSettings, isInteractive = true, ...props }: TooltipInputProps & Omit,\r\n ref: React.ForwardedRef\r\n) {\r\n const input = \r\n\r\n if (!isInteractive) {\r\n return input\r\n }\r\n\r\n return (\r\n \r\n {input}\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 throttle from 'lodash.throttle'\r\nimport * as React from 'react'\r\n\r\ninterface Props {\r\n throttleWaitInMs?: number\r\n isWatching?: boolean\r\n}\r\n\r\nexport function useWindowSize({ throttleWaitInMs = 300, isWatching = true }: Props = {}) {\r\n const [size, setSize] = React.useState({\r\n innerWidth: window.innerWidth,\r\n innerHeight: window.innerHeight,\r\n })\r\n\r\n React.useEffect(() => {\r\n if (!isWatching) return\r\n\r\n const handleResize = throttle(() => {\r\n setSize({\r\n innerWidth: window.innerWidth,\r\n innerHeight: window.innerHeight,\r\n })\r\n }, throttleWaitInMs)\r\n\r\n window.addEventListener('resize', handleResize)\r\n\r\n return () => {\r\n handleResize.cancel()\r\n window.removeEventListener('resize', handleResize)\r\n }\r\n }, [throttleWaitInMs, isWatching])\r\n\r\n return size\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(false)\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, 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","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 Thumb from '../canvas/thumb'\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\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\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 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.isEditInProgress = true\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.isEditInProgress = 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 const heightScaled = roundedXY.y2 - roundedXY.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 context.moveTo(roundedXY.x1, Math.round(y2 - p * heightScaled))\r\n context.lineTo(roundedXY.x2, Math.round(y2 - p * heightScaled))\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 if (this.attrs.textBaseline === 'middle') {\r\n y = this.attrs.y! - rawHight / 2 - this.attrs.padding.top - 1\r\n } else if (this.attrs.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 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 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.close.length - 1)\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 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 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\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 * as d3 from 'd3'\r\n\r\nimport { 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\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\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 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 for (let i = 0, end = this.data.close.length, asc = end >= 0; asc ? i < end : i > end; asc ? i++ : i--) {\r\n this.context.lineTo(this.fx(i), Math.round(this.fy(this.perf[ticker][i])))\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.data.getDataByBarIndex('date', 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 hasData = Number.isFinite(tickerData[crossIndex])\r\n const percentageText = hasData ? `${tickerData[crossIndex].toFixed(2)}%` : ''\r\n shouldRenderDate = shouldRenderDate || hasData\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].length - 1\r\n const hasData = Number.isFinite(tickerData[lastCrossIndex])\r\n const percentageText = hasData ? `${tickerData[lastCrossIndex].toFixed(2)}%` : ''\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 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 const filteredQuotes = []\r\n for (const quote of quotes) {\r\n const closes = []\r\n for (let i = 0, end = quote.close.length, asc = end >= 0; asc ? i < end : i > end; asc ? i++ : i--) {\r\n const date = utils.dateFromUnixTimestamp(quote.date[i])\r\n if (fromDate <= date && date <= toDate) {\r\n closes.push(quote.close[i])\r\n }\r\n }\r\n filteredQuotes.push({ ticker: quote.ticker, close: closes })\r\n }\r\n\r\n const daysCount = d3.max(filteredQuotes, (q) => q.close.length) ?? 0\r\n for (const quote of filteredQuotes) {\r\n this.perf[quote.ticker] = []\r\n const first = quote.close[0]\r\n let offset = 0\r\n if (daysCount > quote.close.length) {\r\n offset = daysCount - quote.close.length\r\n for (let i = 0, end1 = offset, asc1 = end1 >= 0; asc1 ? i < end1 : i > end1; asc1 ? i++ : i--) {\r\n this.perf[quote.ticker][i] = NaN\r\n }\r\n }\r\n for (let i = 0, end2 = quote.close.length, asc2 = end2 >= 0; asc2 ? i < end2 : i > end2; asc2 ? i++ : i--) {\r\n this.perf[quote.ticker][offset + i] = (quote.close[i] * 100) / first - 100\r\n }\r\n }\r\n const { min, max } = this.computeVisibleMinMax(...Object.keys(this.perf).map((x) => this.perf[x]))\r\n return { min, max }\r\n }\r\n\r\n // TODO refactor into ?utils\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 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.data.date[0] * 1000)\r\n let lastMonth = date.getMonth() + '-' + date.getFullYear()\r\n\r\n let monthsInData = 0\r\n this.data.date.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.data.date[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.data.date.length; i++) {\r\n date = new Date(this.data.date[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}\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 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","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 usePopoverState,\r\n} from '@finviz/website'\r\nimport classNames from 'classnames'\r\nimport React from 'react'\r\n\r\nimport { CHART_ELEMENT_ID, SpecificChartFunctionality } from '../../constants/common'\r\nimport { chartSettingsAsyncModule } from '../../controllers/chart-settings/async-modules'\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\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 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 setIsLoading(true)\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 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 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\r\n return\r\n }\r\n\r\n removeFromAbortCache(abortControllerKeyRef.current)\r\n\r\n updateChartModelWithNewQuote(quote)\r\n }\r\n\r\n setIsLoading(false)\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) => {\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) => {\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: string\r\n weight: string\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 (key, valueSetter, value) => {\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 (key, valueSetter, value) => {\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 { 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 React.useEffect(() => {\r\n props.element.isEditInProgress = true\r\n return () => {\r\n props.element.isEditInProgress = false\r\n props.element.trigger('change', props.element)\r\n }\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n }, [])\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 }, [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 onFullyClosed={props.onHide}\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 useDropdownState,\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 dropdownState = useDropdownState({ placement: 'bottom-end' })\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 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 {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 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\nclass ContextMenu extends Spine.Model {\r\n static initClass() {\r\n this.configure('ContextMenu', 'shown', 'config', 'top', 'left')\r\n }\r\n\r\n declare shown: boolean\r\n declare config: ContextMenuItem[]\r\n declare top: number\r\n declare left: number\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 } from '@finviz/website'\r\nimport React from 'react'\r\nimport * as ReactDOM from 'react-dom'\r\n\r\nimport { ObjectHash } from '../../types/shared'\r\nimport model from '../models/context_menu'\r\nimport { ready } from '../utils'\r\n\r\nconst selector = '.context-menu'\r\n\r\nclass ContextMenu extends React.Component {\r\n componentDidMount() {\r\n model.bind('update', this.update)\r\n }\r\n\r\n componentWillUnmount() {\r\n model.unbind('update', this.update)\r\n }\r\n\r\n update = () => {\r\n this.forceUpdate()\r\n }\r\n\r\n render() {\r\n if (model.shown) {\r\n document.querySelector(selector)?.classList.remove('hidden')\r\n } else {\r\n document.querySelector(selector)?.classList.add('hidden')\r\n return null\r\n }\r\n\r\n return (\r\n <>\r\n this.hide()}\r\n onContextMenu={(e) => e.preventDefault()}\r\n data-testid=\"charts-context-menu-overlay\"\r\n >\r\n \r\n \r\n )\r\n }\r\n\r\n hide() {\r\n model.updateAttribute('shown', false)\r\n }\r\n}\r\nready(() => {\r\n const el = document.querySelector(selector)\r\n if (el) {\r\n ReactDOM.render(, el)\r\n }\r\n})\r\n\r\nconst contextMenuControl = {\r\n show: (event: MouseEvent | React.MouseEvent, config: ObjectHash) => {\r\n model.updateAttributes({\r\n shown: true,\r\n config: config,\r\n top: event.clientY + window.pageYOffset,\r\n left: event.clientX,\r\n })\r\n },\r\n}\r\n\r\nexport default contextMenuControl\r\n","import {\r\n AriakitPortal,\r\n Delayed,\r\n DialogBody,\r\n Popover,\r\n PopoverAnchor,\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 { chartEventsAsyncModule } from '../../controllers/chart-events/async-modules'\r\nimport { useModelState } from '../../model-hooks/use-model-state'\r\nimport ChartModel from '../../models/chart'\r\nimport { useAsyncModule } from '../../utils/async-modules-utils'\r\nimport { useClickAway } from '../../utils/use-click-away'\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 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 }, !!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 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 \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 )\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(false)\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 this.setSelectedElement(el)\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 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 )\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.RefForwardingComponent\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 { 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(false)\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\r\n const options = {\r\n premarket,\r\n aftermarket,\r\n events: hasChartEvents,\r\n patterns: panesConfig.some(\r\n (pane) =>\r\n pane.elements?.some(\r\n (element) => 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 })\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 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 [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) => {\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) => (\r\n \r\n ))}\r\n {availableDrawingActions.map((item) => (\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 } 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 Notes\r\n {!isFullyClosed && }\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, Icon } from '@finviz/website'\r\nimport React from 'react'\r\n\r\nimport { drawingTools } from '../drawingTools'\r\nimport { DrawingTool } from '../interfaces'\r\n\r\ntype ToolButtonProps = {\r\n onClick: () => void\r\n activeTool: DrawingTool\r\n}\r\n\r\nexport default function ToolButton({ activeTool, onClick }: ToolButtonProps) {\r\n return (\r\n \r\n )\r\n}\r\n","import { Button } from '@finviz/website'\r\nimport classNames from 'classnames'\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 { DrawingActions, DrawingTool, IToolBarProps } from '../interfaces'\r\nimport Toolbar from '../toolbar'\r\nimport ToolButton from './tool-button'\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 [isToolbarVisible, setIsToolbarVisible] = React.useState(false)\r\n const [urlSearchParams, setUrlSearchParams] = useSearchParams()\r\n const [toolbarMobileElement, setToolbarMobileElement] = React.useState(null)\r\n\r\n // get toolbar mobile element on first render\r\n React.useEffect(() => {\r\n setToolbarMobileElement(document.getElementById(MOBILE_TOOLBAR_DIV_ID))\r\n }, [])\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 setIsToolbarVisible(false)\r\n },\r\n [onActiveToolChange]\r\n )\r\n\r\n // Hide toolbar on click outside\r\n const wrapperRef = React.useRef(null)\r\n React.useEffect(() => {\r\n if (!isToolbarVisible) return\r\n\r\n function handleClickOutside(event: TouchEvent | MouseEvent) {\r\n // Get the currently open select\r\n const openSelect = document.querySelector('.finviz-popover[data-enter]')\r\n if (wrapperRef.current?.contains(event.target as Node) || openSelect?.contains(event.target as Node)) return\r\n setIsToolbarVisible(false)\r\n }\r\n\r\n document.addEventListener('mousedown', handleClickOutside)\r\n document.addEventListener('touchstart', handleClickOutside)\r\n\r\n return () => {\r\n document.removeEventListener('mousedown', handleClickOutside)\r\n document.removeEventListener('touchstart', handleClickOutside)\r\n }\r\n }, [isToolbarVisible])\r\n\r\n const handleDrawingActionClick = (actionId: DrawingActions) => {\r\n onDrawingActionClick?.(actionId)\r\n setIsToolbarVisible(false)\r\n }\r\n\r\n if (!toolbarMobileElement) return null\r\n\r\n return ReactDOM.createPortal(\r\n <>\r\n \r\n \r\n \r\n {urlSearchParams.has(SIDEBAR_QUERY_PARAM) || activeTool === DrawingTool.Mouse ? (\r\n {\r\n setIsToolbarVisible(true)\r\n setUrlSearchParams((params) => {\r\n params.delete(SIDEBAR_QUERY_PARAM)\r\n return params\r\n })\r\n }}\r\n >\r\n Draw\r\n \r\n ) : (\r\n {\r\n setIsToolbarVisible(true)\r\n }}\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 } 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 { getIsPreserveDrawingsAndAutosaveAvailable, getIsSidebarEnabled } 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 constructor(props: ChartLayoutComponentProps) {\r\n super(props)\r\n\r\n this.model = props.chartLayoutModel\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) {\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 this.setToolbarPosition()\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 // 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 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?: HTMLElement\r\n isWithNotifications?: boolean\r\n}\r\n\r\nexport function ChartLayout({ config, shouldResize, isWithNotifications = true }: 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?: 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 && 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 if (parentElement) {\r\n parentElement.style.opacity = 'unset'\r\n parentElement.style.minHeight = 'unset'\r\n parentElement.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 omit from 'lodash.omit'\r\nimport 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\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) => omit(q.toJSON(), ['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 useDropdownState,\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 dropdown = useDropdownState()\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 || !dropdown.visible) {\r\n hideTooltip()\r\n }\r\n }, [isAnyQuoteLoading, dropdown.visible, 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 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 {\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 fx = d3\r\n .scaleLinear()\r\n .range([0, width])\r\n .domain([0, Math.max(0, chartModel.quote().close.length - 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 { ChartEventBadgeState } from '../utils/chart-events-utils'\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 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 { OverlayType } from '../constants/common'\r\nimport { MainCalculation, OnValueCalculated } from './main'\r\n\r\ntype Options = {\r\n period: number\r\n}\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 type = OverlayType.Ema\r\n\r\n getDefaultCalculatedValues() {\r\n return { ema: [] }\r\n }\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 { IndicatorType, OverlayType } from '../constants/common'\r\nimport Quote from '../models/quote'\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 static type: IndicatorType | OverlayType = IndicatorType.Indicator\r\n\r\n quote: NonNullable['quote']>\r\n options: MainProps['options']\r\n\r\n protected _calculatedValues: TCalculatedValues\r\n\r\n constructor({ quote, options }: MainProps) {\r\n this.quote = quote ?? new Quote()\r\n this.options = options\r\n this._calculatedValues = this.getDefaultCalculatedValues()\r\n }\r\n\r\n get calculatedValues() {\r\n return this._calculatedValues\r\n }\r\n\r\n getDefaultCalculatedValues(): TCalculatedValues {\r\n throw Error('Implement getDefaultCalculatedValues')\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 { type } = this.constructor as typeof MainCalculation\r\n const typeLabel = type.split('/')[1]\r\n const optionKeys = Object.keys(this.options ?? {}).sort((key1, key2) => key1.localeCompare(key2))\r\n\r\n const optionsStrings = optionKeys.map((key) => `${key.slice(0, 1)}${this.options![key]}`)\r\n return [typeLabel, ...optionsStrings].join('_')\r\n }\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 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 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 {\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\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 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 type = IndicatorType.Indicator\r\n static label = 'Indicator'\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()\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 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).type\r\n }\r\n\r\n get label() {\r\n return (this.constructor as typeof Indicator).label\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) {\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),\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,\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) ? this.data.close.length - 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 renderCrossTextChartsPage(_: CanvasRenderingContext2D, __: number) {}\r\n\r\n renderCrossTextQuotePage(_: CanvasRenderingContext2D, __: number) {}\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 return !areNoBarsVisible && min !== max && min !== MAX_POSITIVE_DEFAULT_VALUE && max !== MAX_NEGATIVE_DEFAULT_VALUE\r\n ? { min, max }\r\n : this.getDomainDefaults(this.type)\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 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 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 { IndicatorType } from '../constants/common'\r\nimport utils from '../utils'\r\nimport { drawInVisibleArea } from '../utils/draw_in_visible_area'\r\nimport Indicator from './indicator'\r\n\r\ninterface Attrs {\r\n period: string\r\n}\r\n\r\nclass ADX extends Indicator {\r\n static type = IndicatorType.Adx\r\n static label = 'ADX'\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 renderIndicator(context: CanvasRenderingContext2D) {\r\n if (this.data.close.length === 0) return\r\n\r\n context.translate(0.5, 0.5)\r\n context.set('strokeStyle', '#2eb12e')\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', '#d43737')\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', this.getChartLayoutSettings().IndicatorSettings.general.Colors.line)\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 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 return {\r\n title: this.label,\r\n inputs: [period],\r\n inputsErrorMessages: {\r\n period: `${period.label} must be a whole number between ${period.min} and ${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 toString() {\r\n return `ADX ${this.period}`\r\n }\r\n}\r\n\r\nexport default ADX\r\n","import { IndicatorType } from '../constants/common'\r\nimport { MainCalculation, OnValueCalculated } from './main'\r\n\r\ntype Options = {\r\n period: number\r\n}\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 type = IndicatorType.Aro\r\n\r\n getDefaultCalculatedValues() {\r\n return {\r\n aroonUp: [],\r\n aroonDown: [],\r\n oscillator: [],\r\n }\r\n }\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 { IndicatorType, 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 Indicator from './indicator'\r\n\r\ninterface Attrs {\r\n period: string\r\n}\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 type = IndicatorType.Aro\r\n static label = 'Aroon'\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 renderIndicator(context: CanvasRenderingContext2D) {\r\n if (this.data.close.length === 0 || !this.aroonCalculation) return\r\n\r\n context.translate(0.5, 0.5)\r\n context.set('strokeStyle', COLORS.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', COLORS.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 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 return {\r\n title: this.label,\r\n inputs: [period],\r\n inputsErrorMessages: {\r\n period: `${period.label} must be a whole number between ${period.min} and ${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 toString() {\r\n return `Aroon ${this.period}`\r\n }\r\n}\r\n\r\nexport default Aroon\r\n","import { IndicatorType } from '../constants/common'\r\nimport { AroonCalculation } from '../indicator-calculation/aroon'\r\nimport Indicator from './indicator'\r\n\r\ninterface Attrs {\r\n period: string\r\n}\r\n\r\nclass AroonOscillator extends Indicator {\r\n static type = IndicatorType.Aroosc\r\n static label = 'Aroon Oscillator'\r\n\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 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 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 return {\r\n title: this.label,\r\n inputs: [period],\r\n inputsErrorMessages: {\r\n period: `${period.label} must be a whole number between ${period.min} and ${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 toString() {\r\n return `Aroon Oscillator ${this.period}`\r\n }\r\n}\r\n\r\nexport default AroonOscillator\r\n","import { IndicatorType } from '../constants/common'\r\nimport AverageTrueRange from '../helpers/atr'\r\nimport { drawInVisibleArea } from '../utils/draw_in_visible_area'\r\nimport Indicator from './indicator'\r\n\r\ninterface Attrs {\r\n period: string\r\n}\r\n\r\nclass ATR extends Indicator {\r\n static type = IndicatorType.Atr\r\n static label = 'Average True Range'\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 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 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 return {\r\n title: this.label,\r\n inputs: [period],\r\n inputsErrorMessages: {\r\n period: `${period.label} must be a whole number between ${period.min} and ${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 toString() {\r\n return `ATR ${this.period}`\r\n }\r\n}\r\n\r\nexport default ATR\r\n","import { IndicatorType } from '../constants/common'\r\nimport Indicator from './indicator'\r\n\r\ninterface Attrs {\r\n period: string\r\n}\r\n\r\nconst constant = 0.015\r\nclass CommodityChannelIndex extends Indicator {\r\n static type = IndicatorType.Cci\r\n static label = 'Commodity Channel Index'\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 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 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 return {\r\n title: this.label,\r\n inputs: [period],\r\n inputsErrorMessages: {\r\n period: `${period.label} must be a whole number between ${period.min} and ${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 toString() {\r\n return `CCI ${this.period}`\r\n }\r\n}\r\n\r\nexport default CommodityChannelIndex\r\n","import * as d3 from 'd3'\r\n\r\nimport { ObjectHash, Theme } from '../../types/shared'\r\nimport Text from '../canvas/text'\r\nimport tailwindColors from '../constants/colors'\r\nimport { INDICATOR_LABEL_HEIGHT, IndicatorType, TextAlign, TextBaseline } from '../constants/common'\r\nimport utils from '../utils'\r\nimport { drawInVisibleArea } from '../utils/draw_in_visible_area'\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\ninterface Attrs {\r\n period: string\r\n code: string\r\n}\r\n\r\ntype ColorsKeys = keyof Pick\r\n\r\nclass COT extends Indicator {\r\n static type = IndicatorType.Cot\r\n static label = 'COT'\r\n\r\n static getNumOfBarsBuffer() {\r\n return 0\r\n }\r\n\r\n declare colors: ObjectHash\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 renderIndicator(context: CanvasRenderingContext2D) {\r\n if (!this.data.COTs) return\r\n context.translate(0.5, 0.5)\r\n for (const key in this.colors) {\r\n context.set('strokeStyle', this.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\r\n new Text(\r\n {\r\n text: this.data.COTs[this.attrs.code].units as string,\r\n x: 38 + name.measure(),\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 ).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 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\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: this.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: this.colors.largeTraders })\r\n text.render(context)\r\n\r\n x += 8 + text.measure()\r\n text.set({ text: 'Small Traders', x, fillStyle: this.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: 'COT',\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) : undefined\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\nCOT.prototype.colors = {\r\n commercialHedgers: '#10cc10',\r\n largeTraders: '#cc1010',\r\n smallTraders: '#1010cc',\r\n}\r\n\r\nexport default COT\r\n","import { IndicatorType } from '../constants/common'\r\nimport { ExponentialMovingAverage } from './ema'\r\nimport { MainCalculation, OnValueCalculated } from './main'\r\n\r\ntype Options = {\r\n period: number\r\n}\r\n\r\ntype DefaultCalculatedValuesType = {\r\n fi: number[]\r\n}\r\n\r\nexport class FICalculation extends MainCalculation {\r\n static type = IndicatorType.Fi\r\n\r\n getDefaultCalculatedValues() {\r\n return { fi: [] }\r\n }\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 { IndicatorType } from '../constants/common'\r\nimport { FICalculation } from '../indicator-calculation/fi'\r\nimport Indicator from './indicator'\r\n\r\ninterface Attrs {\r\n period: string\r\n}\r\n\r\nclass ForceIndex extends Indicator {\r\n static type = IndicatorType.Fi\r\n static label = 'Force Index'\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 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 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 return {\r\n title: this.label,\r\n inputs: [period],\r\n inputsErrorMessages: {\r\n period: `${period.label} must be a whole number between ${period.min} and ${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 toString() {\r\n return `FORCE ${this.period}`\r\n }\r\n}\r\n\r\nexport default ForceIndex\r\n","import { IndicatorType } from '../constants/common'\r\nimport { ExponentialMovingAverage } from './ema'\r\nimport { MainCalculation, OnValueCalculated } from './main'\r\n\r\ntype Options = {\r\n fastPeriod: number\r\n slowPeriod: number\r\n signalPeriod: number\r\n}\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 type = IndicatorType.Macd\r\n\r\n getDefaultCalculatedValues() {\r\n return {\r\n macd: [],\r\n signal: [],\r\n histogram: [],\r\n }\r\n }\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 { IndicatorType } from '../constants/common'\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 Indicator from './indicator'\r\n\r\ninterface Attrs {\r\n period: string\r\n fastPeriod: number\r\n slowPeriod: number\r\n signalPeriod: number\r\n}\r\n\r\nclass MACD extends Indicator {\r\n static type = IndicatorType.Macd\r\n static label = 'MACD'\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 renderIndicator(context: CanvasRenderingContext2D) {\r\n const { IndicatorSettings } = this.getChartLayoutSettings()\r\n if (this.macdCalculation === null || this.data.close.length === 0) return\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', '#79c3e8')\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', IndicatorSettings.general.Colors.line)\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', IndicatorSettings.general.Colors.signalLine)\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 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 const 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 const 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 return {\r\n title: this.label,\r\n inputs: [fastPeriod, slowPeriod, signalPeriod],\r\n inputsErrorMessages: {\r\n fastPeriod: `${fastPeriod.label} must be a whole number between ${fastPeriod.min} and ${fastPeriod.max}`,\r\n slowPeriod: `${slowPeriod.label} must be a whole number between ${slowPeriod.min} and ${slowPeriod.max}`,\r\n signalPeriod: `${signalPeriod.label} must be a whole number between ${signalPeriod.min} and ${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 toString() {\r\n return `MACD ${this.fastPeriod},${this.slowPeriod},${this.signalPeriod}`\r\n }\r\n}\r\n\r\nexport default MACD\r\n","import { IndicatorType } from '../constants/common'\r\nimport Indicator from './indicator'\r\n\r\ninterface Attrs {\r\n period: string\r\n}\r\n\r\nclass MFI extends Indicator {\r\n static type = IndicatorType.Mfi\r\n static label = 'Money Flow Index'\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 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 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 return {\r\n title: this.label,\r\n inputs: [period],\r\n inputsErrorMessages: {\r\n period: `${period.label} must be a whole number between ${period.min} and ${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 toString() {\r\n return `MFI ${this.period}`\r\n }\r\n}\r\n\r\nexport default MFI\r\n","import { IndicatorType } from '../constants/common'\r\nimport Indicator from './indicator'\r\n\r\nclass None extends Indicator {\r\n static type = IndicatorType.None\r\n static label = 'None'\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 math from '../helpers/math'\r\nimport { drawInVisibleArea } from '../utils/draw_in_visible_area'\r\nimport Indicator from './indicator'\r\n\r\nclass OBV extends Indicator {\r\n static type = IndicatorType.Obv\r\n static label = 'On-Balance Volume'\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 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: this.label,\r\n inputs: [],\r\n inputsErrorMessages: {},\r\n }\r\n }\r\n\r\n toString() {\r\n return 'OBV'\r\n }\r\n}\r\n\r\nexport default OBV\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 IndicatorType,\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 Indicator from './indicator'\r\n\r\ninterface Attrs {\r\n period: string\r\n tickers?: string\r\n}\r\n\r\nconst DEFAULT_TICKERS = 'SPY,QQQ'\r\n\r\nclass PricePerformance extends Indicator {\r\n static type = IndicatorType.Perf\r\n static label = 'Price Performance %'\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 firstFetchCalled = false\r\n first: ObjectHash = {}\r\n perf: ObjectHash = {}\r\n quotes: ObjectHash = {}\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 tickers = this.getTickers()\r\n const chartLayoutModel = this.model.chart().chart_layout()\r\n const chartUuid = chartLayoutModel.uuid\r\n const hasCachedData = this.getTickersAndTimeframe().every(\r\n ({ ticker, instrument, timeframe }) =>\r\n Quote.select(\r\n (q: Quote) =>\r\n q.ticker === ticker &&\r\n q.instrument === instrument &&\r\n q.timeframe === timeframe &&\r\n chartLayoutModel.isIdeaId(q.ideaID) &&\r\n chartUuid === q.chartUuid &&\r\n !q.isFetching\r\n ).length > 0\r\n )\r\n\r\n if (this.timeframe !== this.model.chart().quote().timeframe || (!this.ready && !this.firstFetchCalled)) {\r\n this.timeframe = this.model.chart().quote().timeframe\r\n this.firstFetchCalled = true\r\n\r\n if (!hasCachedData) {\r\n const data = await Quote.getAll(this.getTickersAndTimeframe())\r\n if (data) {\r\n this._compute(tickers, data)\r\n this.trigger('change')\r\n }\r\n } else {\r\n this.ready = true\r\n this.compute()\r\n }\r\n } else if (this.ready) {\r\n const data: ObjectHash = {}\r\n for (const ticker of tickers) {\r\n data[ticker] = Quote.select(\r\n (q: Quote) =>\r\n q.ticker === ticker &&\r\n q.timeframe === this.timeframe &&\r\n chartUuid === q.chartUuid &&\r\n chartLayoutModel.isIdeaId(q.ideaID)\r\n )[0]\r\n }\r\n this._compute(tickers, data)\r\n }\r\n }\r\n\r\n _compute(tickers: string[], data: ObjectHash) {\r\n const { leftOffset } = this.model.chart()\r\n let firstBarTime = null\r\n let lastBarTime = null\r\n for (let i = 0; i < this.data.close.length; i++) {\r\n const center = this.fx(i)\r\n if (center + leftOffset < 0 || center + leftOffset > this.contentWidth) {\r\n // margin?\r\n continue\r\n }\r\n\r\n // Rendering one extra bar out of viewport ensures continuity of line, if there are missing data on intraday the indicator may have gaps\r\n if (firstBarTime === null) {\r\n firstBarTime = this.data.date[i]\r\n }\r\n\r\n lastBarTime = this.data.date[i]\r\n }\r\n\r\n data[this.data.ticker] = this.data\r\n this.quotes = data\r\n this.perf = {}\r\n const dateToIndex = this.data.getDateToIndex()\r\n for (const ticker of [this.data.ticker, ...tickers]) {\r\n this.perf[ticker] = []\r\n const d = data[ticker]\r\n if (!d) {\r\n continue\r\n }\r\n let first = null\r\n let index = -1\r\n for (let i = 0; i < d.close.length; i++) {\r\n const date = d.date[i]\r\n if (date < firstBarTime! || date > lastBarTime!) {\r\n continue\r\n }\r\n\r\n index = dateToIndex[date]\r\n if (index === undefined || index === null) {\r\n continue\r\n }\r\n\r\n if (first === null) {\r\n first = d.close[i]\r\n this.first[ticker] = first\r\n if (index > 0) {\r\n this.perf[ticker][index - 1] = (d.close[i] * 100) / first - 100\r\n }\r\n }\r\n\r\n this.perf[ticker][index] = (d.close[i] * 100) / first - 100\r\n }\r\n\r\n if (index < this.data.date.length - 1 && first !== null) {\r\n this.perf[ticker][index + 1] = this.perf[ticker][index]\r\n }\r\n }\r\n\r\n const perfArrays = Object.keys(this.perf).map((x) => this.perf[x])\r\n const { min, max } = perfArrays.some((array) => array.length > 0)\r\n ? this.computeVisibleMinMax(...perfArrays)\r\n : this.getDomainDefaults(this.type)\r\n\r\n this.min = min\r\n this.max = 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 const { ColorsSettings, IndicatorSettings } = this.getChartLayoutSettings()\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 const iterable = this.getTickers()\r\n for (let index = 0; index < iterable.length; index++) {\r\n const ticker = iterable[index]\r\n if (this.perf[ticker].length > 0) {\r\n context.set('strokeStyle', ColorsSettings[index % ColorsSettings.length])\r\n context.beginPath()\r\n for (let i = 0; i < this.perf[ticker].length; i++) {\r\n const y = Math.round(this.fy(this.perf[ticker][i]))\r\n context.lineTo(this.fx(i), y)\r\n }\r\n context.stroke()\r\n }\r\n }\r\n\r\n context.set('strokeStyle', IndicatorSettings.general.Colors.line)\r\n context.beginPath()\r\n for (let i = 0; i < this.perf[this.data.ticker].length; i++) {\r\n const y = Math.round(this.fy(this.perf[this.data.ticker][i]))\r\n if (!isNaN(y)) {\r\n context.lineTo(this.fx(i), y)\r\n }\r\n }\r\n context.stroke()\r\n context.translate(-0.5, -0.5)\r\n }\r\n\r\n renderCrossTextQuotePage(context: CanvasRenderingContext2D, crossIndex: number) {\r\n if (!context || !crossIndex) {\r\n return\r\n }\r\n const { ColorsSettings, 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 crossIndexTickerTimeStamp = this.quotes?.[this.data.ticker]?.getDataByBarIndex('date', crossIndex)\r\n const tickerDateToIndex = crossIndexTickerTimeStamp\r\n ? this.quotes?.[key]?.getDateToIndex()?.[crossIndexTickerTimeStamp]\r\n : null\r\n const tickerPerformance = tickerDateToIndex\r\n ? (this.quotes?.[key]?.close?.[tickerDateToIndex] * 100) / this.first[key] - 100\r\n : null\r\n if (tickerPerformance !== null && !isNaN(tickerPerformance)) {\r\n context.fillStyle = Colors.canvasFill\r\n context.fillRect(\r\n IndicatorSettings.left.indicatorLabel.margin.left! - PADDING.XXXS,\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 PADDING.XXXS,\r\n PADDING.XXXS + this.indicatorLabelWidth[key] + PADDING.XXXS,\r\n PADDING.XXXS + IndicatorSettings.left.indicatorLabel.font.size! + PADDING.XXXS\r\n )\r\n new Text(\r\n {\r\n text: `${key} ${tickerPerformance.toFixed(2)}%`,\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:\r\n index === 0 ? Colors.performanceIndicatorLabel : ColorsSettings[index - (1 % ColorsSettings.length)],\r\n textAlign: TextAlign.left,\r\n textBaseline: TextBaseline.top,\r\n },\r\n this.model\r\n ).render(context)\r\n }\r\n })\r\n }\r\n\r\n renderCrossTextChartsPage(context: CanvasRenderingContext2D, crossIndex: number) {\r\n if (!context || !crossIndex) {\r\n return\r\n }\r\n\r\n const { ColorsSettings, 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 const tickerQuote = this.quotes?.[this.data.ticker]\r\n const maxCrossIndex = Math.min(crossIndex, (tickerQuote?.close.length ?? Infinity) - 1)\r\n tickers.forEach((key, index) => {\r\n const crossIndexTickerTimeStamp = tickerQuote?.getDataByBarIndex('date', maxCrossIndex)\r\n const tickerDateToIndex = crossIndexTickerTimeStamp\r\n ? this.quotes?.[key]?.getDateToIndex()?.[crossIndexTickerTimeStamp]\r\n : null\r\n const tickerPerformance = tickerDateToIndex\r\n ? (this.quotes?.[key]?.close?.[tickerDateToIndex] * 100) / this.first[key] - 100\r\n : null\r\n if (tickerPerformance !== null && !isNaN(tickerPerformance)) {\r\n tickerText.set({\r\n x,\r\n y,\r\n fillStyle:\r\n index === 0 ? Colors.performanceIndicatorLabel : ColorsSettings[index - (1 % ColorsSettings.length)],\r\n text: `${key} ${tickerPerformance.toFixed(2)}%`,\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\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 let ticker\r\n super.renderYAxis(context)\r\n const { IndicatorSettings, ChartSettings, ColorsSettings } = this.getChartLayoutSettings()\r\n const { Colors } = ChartSettings.general\r\n if (!this.ready) {\r\n return\r\n }\r\n if (this.perf[this.data.ticker].length === 0) {\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 iterable = this.getTickers()\r\n const textLabels = []\r\n for (let index = 0; index < iterable.length; index++) {\r\n ticker = iterable[index]\r\n if (this.perf[ticker].length > 0) {\r\n textLabels.push({\r\n text: this.perf[ticker].last().toFixed(2) + '%',\r\n y: Math.round(this.fy(this.perf[ticker].last())),\r\n background: ColorsSettings[index % ColorsSettings.length],\r\n })\r\n }\r\n }\r\n textLabels.push({\r\n text: this.perf[this.data.ticker].last().toFixed(2) + '%',\r\n y: Math.round(this.fy(this.perf[this.data.ticker].last())),\r\n background: Colors.performanceIndicatorLabel,\r\n })\r\n\r\n const minY = 0\r\n const maxY = this.contentHeight\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 renderLabelQuotePage(context: CanvasRenderingContext2D) {\r\n super.renderLabelQuotePage(context)\r\n const { ColorsSettings, ChartSettings, IndicatorSettings } = this.getChartLayoutSettings()\r\n const { Colors } = ChartSettings.general\r\n if (this.ready) {\r\n const tickers = this.getTickers()\r\n const tickerPerformance = [\r\n { [this.data.ticker]: this.perf[this.data.ticker][this.perf[this.data.ticker].length - 1] },\r\n ...tickers.map((ticker) => ({ [ticker]: this.perf[ticker][this.perf[ticker].length - 1] })),\r\n ].reduce((prev, current) => ({ ...prev, ...current }), {})\r\n Object.keys(tickerPerformance).forEach((key, index) => {\r\n if (tickerPerformance[key]) {\r\n const text = new Text(\r\n {\r\n text: `${key} ${tickerPerformance[key].toFixed(2)}%`,\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:\r\n index === 0 ? Colors.performanceIndicatorLabel : ColorsSettings[index - (1 % ColorsSettings.length)],\r\n textAlign: TextAlign.left,\r\n textBaseline: TextBaseline.top,\r\n },\r\n this.model\r\n )\r\n this.indicatorLabelWidth = { ...this.indicatorLabelWidth, [key]: text.measure(context) }\r\n text.render(context)\r\n }\r\n })\r\n }\r\n }\r\n\r\n getTickers() {\r\n return this.tickers\r\n .split(',')\r\n .map((ticker) => ticker)\r\n .filter((x) => x)\r\n }\r\n\r\n getTickersAndTimeframe() {\r\n const { timeframe } = this.model.chart().quote()\r\n return this.getTickers().map((ticker) => ({\r\n ticker,\r\n instrument: getInstrument(ticker),\r\n timeframe,\r\n }))\r\n }\r\n\r\n set(values: Partial) {\r\n this.ready = false\r\n this.firstFetchCalled = false\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 return {\r\n title: this.label,\r\n inputs: [\r\n {\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 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() ? 'PERF %' : `PERF% ${this.tickers}`\r\n }\r\n}\r\n\r\nexport default PricePerformance\r\n","import { IndicatorType } from '../constants/common'\r\nimport { getParsedIntegersFromPeriodString } from '../utils/helpers'\r\nimport Indicator from './indicator'\r\n\r\ninterface Attrs {\r\n period: number | string\r\n momentum: number\r\n}\r\n\r\nclass RMI extends Indicator {\r\n static type = IndicatorType.Rmi\r\n static label = 'Relative Momentum Index'\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 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 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 const 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 return {\r\n title: this.label,\r\n inputs: [period, momentum],\r\n inputsErrorMessages: {\r\n period: `${period.label} must be a whole number between ${period.min} and ${period.max}`,\r\n momentum: `${momentum.label} must be a whole number between ${momentum.min} and ${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 toString() {\r\n return `RMI ${this.period},${this.momentum}`\r\n }\r\n}\r\n\r\nexport default RMI\r\n","import Line from '../canvas/line'\r\nimport { IndicatorType } from '../constants/common'\r\nimport { drawInVisibleArea } from '../utils/draw_in_visible_area'\r\nimport Indicator from './indicator'\r\n\r\ninterface Attrs {\r\n period: string\r\n}\r\n\r\nclass ROC extends Indicator {\r\n static type = IndicatorType.Roc\r\n static label = 'Rate of Change %'\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 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 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 return {\r\n title: this.label,\r\n inputs: [period],\r\n inputsErrorMessages: {\r\n period: `${period.label} must be a whole number between ${period.min} and ${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 toString() {\r\n return `ROC ${this.period}`\r\n }\r\n}\r\n\r\nexport default ROC\r\n","import { IndicatorType } from '../constants/common'\r\nimport { MainCalculation, OnValueCalculated } from './main'\r\n\r\ntype Options = {\r\n period: number\r\n}\r\n\r\ntype DefaultCalculatedValuesType = {\r\n rsi: number[]\r\n}\r\n\r\nexport class RsiCalculation extends MainCalculation {\r\n static type = IndicatorType.Rsi\r\n\r\n getDefaultCalculatedValues() {\r\n return { rsi: [] }\r\n }\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 { IndicatorType } from '../constants/common'\r\nimport { RsiCalculation } from '../indicator-calculation/rsi'\r\nimport Indicator from './indicator'\r\n\r\ninterface Attrs {\r\n period: string\r\n}\r\n\r\nclass RSI extends Indicator {\r\n static type = IndicatorType.Rsi\r\n static label = 'Relative Strength Index'\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 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 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 return {\r\n title: this.label,\r\n inputs: [period],\r\n inputsErrorMessages: {\r\n period: `${period.label} must be a whole number between ${period.min} and ${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 toString() {\r\n return `RSI ${this.period}`\r\n }\r\n}\r\n\r\nexport default RSI\r\n","import Line from '../canvas/line'\r\nimport { IndicatorType } from '../constants/common'\r\nimport { getBarWidthWithMarginByParts } from '../utils/chart'\r\nimport { getHEXWithSpecificAplha } from '../utils/colors'\r\nimport { drawInVisibleArea } from '../utils/draw_in_visible_area'\r\nimport Indicator from './indicator'\r\n\r\ninterface Attrs {\r\n period: number | string\r\n baseLine: number\r\n}\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 type = IndicatorType.Rvol\r\n static label = 'Relative Volume'\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] = this.data.volume[i] / (sum / this.period)\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 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 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\r\n const 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 return {\r\n title: this.label,\r\n inputs: [period, baseLine],\r\n inputsErrorMessages: {\r\n period: `${period.label} must be a whole number between ${period.min} and ${period.max}`,\r\n baseLine: `${baseLine.label} must be a number between ${baseLine.min} and ${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 `RVOL ${this.period}, ${this.baseLine}, SMA`\r\n }\r\n}\r\n\r\nexport default RelativeVolume\r\n","import Text from '../canvas/text'\r\nimport { IndicatorType, 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 Indicator from './indicator'\r\n\r\ninterface Attrs {\r\n period: string\r\n}\r\n\r\nclass RWI extends Indicator {\r\n static type = IndicatorType.Rwi\r\n static label = 'Random Walk Index'\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 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 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 return {\r\n title: this.label,\r\n inputs: [period],\r\n inputsErrorMessages: {\r\n period: `${period.label} must be a whole number between ${period.min} and ${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 toString() {\r\n return `RWI ${this.period}`\r\n }\r\n}\r\n\r\nexport default RWI\r\n","import Line from '../canvas/line'\r\nimport { IndicatorType } from '../constants/common'\r\nimport { drawInVisibleArea } from '../utils/draw_in_visible_area'\r\nimport { getParsedIntegersFromPeriodString } from '../utils/helpers'\r\nimport Indicator from './indicator'\r\n\r\ninterface Attrs {\r\n period: string | number\r\n dPeriod: number\r\n kPeriod: number\r\n}\r\n\r\nclass Stochastics extends Indicator {\r\n static type = IndicatorType.Stofu\r\n static label = 'Stochastics FULL'\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 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 context.set('strokeStyle', this.getChartLayoutSettings().IndicatorSettings.general.Colors.line)\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', '#c80000')\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 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 const 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 const 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 return {\r\n title: this.label,\r\n inputs: [period, kPeriod, dPeriod],\r\n inputsErrorMessages: {\r\n period: `${period.label} must be a whole number between ${period.min} and ${period.max}`,\r\n dPeriod: `${dPeriod.label} must be a whole number between ${dPeriod.min} and ${dPeriod.max}`,\r\n kPeriod: `${kPeriod.label} must be a whole number between ${kPeriod.min} and ${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 toString() {\r\n return `Stochastics FULL ${this.period},${this.kPeriod},${this.dPeriod}`\r\n }\r\n}\r\n\r\nexport default Stochastics\r\n","import { IndicatorType } from '../constants/common'\r\nimport Pane from '../models/pane'\r\nimport { getParsedIntegersFromPeriodString } from '../utils/helpers'\r\nimport Stochastics from './stofu'\r\n\r\ninterface Attrs {\r\n period: string | number\r\n dPeriod: number\r\n kPeriod: number\r\n}\r\n\r\nclass StochasticsFast extends Stochastics {\r\n static type = IndicatorType.Stofa\r\n static label = 'Stochastics FAST'\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 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 const 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 return {\r\n title: this.label,\r\n inputs: [period, dPeriod],\r\n inputsErrorMessages: {\r\n period: `${period.label} must be a whole number between ${period.min} and ${period.max}`,\r\n dPeriod: `${dPeriod.label} must be a whole number between ${dPeriod.min} and ${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 toString() {\r\n return `Stochastics FAST ${this.period},${this.dPeriod}`\r\n }\r\n}\r\n\r\nexport default StochasticsFast\r\n","import { IndicatorType } from '../constants/common'\r\nimport { getParsedIntegersFromPeriodString } from '../utils/helpers'\r\nimport Stochastics from './stofu'\r\n\r\ninterface Attrs {\r\n period: string | number\r\n dPeriod: number\r\n kPeriod: number\r\n}\r\n\r\nclass StochasticsSlow extends Stochastics {\r\n static type = IndicatorType.Stosl\r\n static label = 'Stochastics SLOW'\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 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 const 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 return {\r\n title: this.label,\r\n inputs: [period, dPeriod],\r\n inputsErrorMessages: {\r\n period: `${period.label} must be a whole number between ${period.min} and ${period.max}`,\r\n dPeriod: `${dPeriod.label} must be a whole number between ${dPeriod.min} and ${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 toString() {\r\n return `Stochastics SLOW ${this.period},${this.dPeriod}`\r\n }\r\n}\r\n\r\nexport default StochasticsSlow\r\n","import { IndicatorType } from '../constants/common'\r\nimport { ExponentialMovingAverage } from './ema'\r\nimport { MainCalculation, OnValueCalculated } from './main'\r\n\r\ntype Options = {\r\n period: number\r\n}\r\n\r\ntype DefaultCalculatedValuesType = {\r\n trix: number[]\r\n}\r\n\r\nexport class TrixCalculation extends MainCalculation {\r\n static type = IndicatorType.Trix\r\n\r\n getDefaultCalculatedValues() {\r\n return { trix: [] }\r\n }\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 { IndicatorType } from '../constants/common'\r\nimport { TrixCalculation } from '../indicator-calculation/trix'\r\nimport { drawInVisibleArea } from '../utils/draw_in_visible_area'\r\nimport Indicator from './indicator'\r\n\r\ninterface Attrs {\r\n period: string\r\n}\r\n\r\nclass Trix extends Indicator {\r\n static type = IndicatorType.Trix\r\n static label = 'TRIX'\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 getModalConfig() {\r\n const 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 return {\r\n title: this.label,\r\n inputs: [period],\r\n inputsErrorMessages: {\r\n period: `${period.label} must be a whole number between ${period.min} and ${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 toString() {\r\n return `TRIX ${this.period}`\r\n }\r\n}\r\n\r\nexport default Trix\r\n","import { ChartConfigChartPaneElement, RequireByKey } from '../../types/shared'\r\nimport { IndicatorType } from '../constants/common'\r\nimport { getParsedIntegersFromPeriodString } from '../utils/helpers'\r\nimport Indicator from './indicator'\r\n\r\ninterface Attrs {\r\n period: string\r\n period1: number\r\n period2: number\r\n period3: number\r\n}\r\n\r\nclass UltimateOscillator extends Indicator {\r\n static type = IndicatorType.Ult\r\n static label = 'Ultimate Oscillator'\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 renderIndicator(context: CanvasRenderingContext2D) {\r\n this.renderOversoldOverbought(context, this.ult, 1, 30, 50, 70)\r\n }\r\n\r\n getModalConfig() {\r\n const 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 const 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 const 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 return {\r\n title: this.label,\r\n inputs: [period1, period2, period3],\r\n inputsErrorMessages: {\r\n period1: `${period1.label} must be a whole number between ${period1.min} and ${period1.max}`,\r\n period2: `${period2.label} must be a whole number between ${period2.min} and ${period2.max}`,\r\n period3: `${period3.label} must be a whole number between ${period3.min} and ${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 toString() {\r\n return `ULT ${this.period1},${this.period2},${this.period3}`\r\n }\r\n}\r\n\r\nexport default UltimateOscillator\r\n","import { IndicatorType } from '../constants/common'\r\nimport math from '../helpers/math'\r\nimport { getBarWidthWithMarginByParts } from '../utils/chart'\r\nimport { drawInVisibleArea } from '../utils/draw_in_visible_area'\r\nimport Indicator from './indicator'\r\n\r\nclass Volume extends Indicator {\r\n static type = IndicatorType.Vol\r\n static label = 'Volume'\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 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: this.label,\r\n inputs: [],\r\n inputsErrorMessages: {},\r\n }\r\n }\r\n\r\n toString() {\r\n return `Volume`\r\n }\r\n}\r\n\r\nexport default Volume\r\n","import { IndicatorType } from '../constants/common'\r\nimport Indicator from './indicator'\r\n\r\ninterface Attrs {\r\n period: string\r\n}\r\n\r\nclass WilliamsR extends Indicator {\r\n static type = IndicatorType.Wr\r\n static label = 'Williams %R'\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 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 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 return {\r\n title: this.label,\r\n inputs: [period],\r\n inputsErrorMessages: {\r\n period: `${period.label} must be a whole number between ${period.min} and ${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 toString() {\r\n return `W%R ${this.period}`\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 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})\r\n\r\nexport const indicatorsWithoutPeriod = Object.freeze([IndicatorType.Obv, IndicatorType.Vol])\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 COT from '../indicators/cot'\r\nimport PricePerformance from '../indicators/perf'\r\nimport { getChartLayoutSettings } from '../models/settings'\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\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 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: '#646464',\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: '#646464',\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 } from '../constants/common'\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 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 { getChartLayoutSettings } from '../models/settings'\r\nimport Chart from './chart'\r\nimport ChartEventElement from './chart-event-element'\r\nimport Element from './element'\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 { isSameMonth, isSameWeek } from 'date-fns'\r\nimport queryString from 'query-string'\r\n\r\nimport { Instrument, ObjectHash, TodoObjectHashAnyType } from '../../types/shared'\r\nimport { ChartEventDbType, ChartEventType, IntradayTimeframeInterval, TIMEFRAME } from '../constants/common'\r\nimport type { ICOT } from '../indicators/cot'\r\nimport { 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 { 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}\r\n\r\ninterface QuoteInternalOptions {\r\n cachePredicate?: (quote: Quote) => boolean\r\n fetchNewDataOnCachedQuote?: boolean\r\n}\r\n\r\ninterface UrlOptions extends QuoteFetchOptions {\r\n ticker: string\r\n instrument: string\r\n timeframe: 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}\r\n\r\ninterface COTData {\r\n [code: string]: ICOT\r\n}\r\n\r\nconst emptyQuote = {\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}\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\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\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 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 'hasPatterns',\r\n 'patterns',\r\n 'patternsMinRange',\r\n 'patternsMaxRange',\r\n 'relativeVolume',\r\n 'fetchedAt',\r\n 'isIntraday',\r\n 'interval',\r\n 'drawDays',\r\n 'barIndex',\r\n 'barToDataIndex',\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 )\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 ? 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 )\r\n : []\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 ...emptyQuote,\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 })\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(tickersAndTimeframes: Array<{ ticker: string; instrument: Instrument; timeframe: TIMEFRAME }>) {\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 await Promise.all(\r\n tickersAndTimeframes.map(({ ticker, instrument, timeframe }) =>\r\n this.get({ ticker: ticker, instrument, timeframe })\r\n )\r\n )\r\n const data = tickersAndTimeframes.reduce(\r\n (accumulator, currentValue) => ({\r\n ...accumulator,\r\n [currentValue.ticker]: Quote.select(\r\n (q: Quote) =>\r\n q.ticker === currentValue.ticker &&\r\n q.instrument === currentValue.instrument &&\r\n q.timeframe === currentValue.timeframe\r\n )[0],\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\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 if (getIsAbortError(err as Error)) {\r\n wasFetchAborted = true\r\n } else if (process.env.IS_E2E_TESTING) {\r\n throw new Error('Quote fetch error', { cause: err })\r\n }\r\n is404 = err instanceof NotFoundError\r\n // Ignore network/notfound errors\r\n }\r\n\r\n const shouldUseEmptyQuote = !data && !wasFetchAborted && options.type === QuoteFetchTypeUrlOption.New\r\n\r\n if (process.env.IS_E2E_TESTING && shouldUseEmptyQuote) {\r\n throw new Error('Quote fetch new fail', { cause: { options, is404, wasFetchAborted, data } })\r\n }\r\n\r\n this.updateAttributes({\r\n ...(shouldUseEmptyQuote ? emptyQuote : {}),\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 }\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 const { fetchedAt = 0 } = atts\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 }\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 destroy(options?: ObjectHash) {\r\n super.destroy(options)\r\n deleteCachedQuote({ cid: this.cid })\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 }\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(emptyQuote)\r\n }\r\n}\r\n\r\nQuote.initClass()\r\n\r\nexport default Quote\r\n","export 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}\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 { MainCalculation, OnValueCalculated } from './main'\r\n\r\ntype Options = {\r\n period: number\r\n deviations: number\r\n}\r\n\r\ntype DefaultCalculatedValuesType = {\r\n sma: number[]\r\n stdDev: number[]\r\n upperBand: number[]\r\n lowerBand: number[]\r\n}\r\n\r\nexport class BbCalculation extends MainCalculation {\r\n static type = OverlayType.Bb\r\n\r\n getDefaultCalculatedValues() {\r\n return {\r\n sma: [],\r\n stdDev: [],\r\n upperBand: [],\r\n lowerBand: [],\r\n }\r\n }\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 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 this.calculatedValues.stdDev[i] = Math.sqrt(stdDevSum / period)\r\n\r\n this.calculatedValues.upperBand[i] = this.calculatedValues.sma[i] + this.calculatedValues.stdDev[i] * deviations\r\n this.calculatedValues.lowerBand[i] = this.calculatedValues.sma[i] - this.calculatedValues.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\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 type = OverlayType.Overlay\r\n static label = 'Overlay'\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).type\r\n }\r\n\r\n get label() {\r\n return (this.constructor as typeof Overlay).label\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\r\nexport default Overlay\r\n","import { ChartConfigChartPaneElement, RequireByKey, Theme } from '../../types/shared'\r\nimport { OverlayType } from '../constants/common'\r\nimport { BbCalculation } from '../indicator-calculation/bb'\r\nimport { getParsedIntegersFromPeriodString } from '../utils/helpers'\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\ninterface Attrs {\r\n period: number | string\r\n deviations: number\r\n topColor?: string\r\n bottomColor?: string\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 type = OverlayType.Bb\r\n static label = 'Bollinger Bands'\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 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 const deviations = {\r\n type: 'number',\r\n label: '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 const topColor = {\r\n type: 'color',\r\n label: 'Top Color',\r\n name: 'topColor',\r\n value: this.attrs.topColor ?? this.getFreeColor(),\r\n }\r\n const bottomColor = {\r\n type: 'color',\r\n label: 'Bottom Color',\r\n name: 'bottomColor',\r\n value: this.attrs.bottomColor ?? this.getFreeColor(),\r\n }\r\n\r\n return {\r\n title: this.label,\r\n inputs: [period, deviations, topColor, bottomColor],\r\n inputsErrorMessages: {\r\n period: `${period.label} must be a whole number between ${period.min} and ${period.max}`,\r\n deviations: `${deviations.label} must be a number between ${deviations.min} and ${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 toString() {\r\n return `BB ${this.attrs.period},${this.attrs.deviations}`\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 utils from '../utils'\r\nimport { drawInVisibleArea } from '../utils/draw_in_visible_area'\r\nimport Overlay from './overlay'\r\n\r\ninterface Attrs {\r\n period: number\r\n channelStrokeColor: string\r\n channelFillColor: string\r\n medianBandColor: string\r\n}\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 type = OverlayType.Dch\r\n static label = 'Donchian Channels'\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 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\r\n const strokeColor = {\r\n type: 'color',\r\n label: 'Channels Stroke Color',\r\n name: 'strokeColor',\r\n value: this.attrs.channelStrokeColor ?? this.getFreeColor(),\r\n }\r\n const fillColor = {\r\n type: 'color',\r\n label: 'Channels Fill Color',\r\n name: 'fillColor',\r\n value: this.attrs.channelFillColor ?? this.getFreeColor(),\r\n }\r\n const 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 return {\r\n title: this.label,\r\n inputs: [period, medianBandColor, strokeColor, fillColor],\r\n inputsErrorMessages: {\r\n period: `${period.label} must be a whole number between ${period.min} and ${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 'medianBandColor':\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.medianBandColor\r\n }\r\n\r\n toString() {\r\n return `Donchian ${this.attrs.period}`\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 { OverlayType } from '../constants/common'\r\nimport { EMACalculation } from '../indicator-calculation/ema'\r\nimport Overlay from './overlay'\r\n\r\ninterface Attrs {\r\n period: number\r\n deviations: number\r\n color: string\r\n}\r\n\r\nclass EMA extends Overlay {\r\n static type = OverlayType.Ema\r\n static label = 'Exponential Moving Average'\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 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 const 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 return {\r\n title: this.label,\r\n inputs: [period, color],\r\n inputsErrorMessages: {\r\n period: `${period.label} must be a whole number between ${period.min} and ${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 toString() {\r\n return `EMA ${this.attrs.period}`\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 EMA from './ema'\r\n\r\nclass EMA2 extends EMA {\r\n static type = OverlayType.Ema2\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 PaneModel from '../models/pane'\r\nimport { getBarWidthWithMargin } from '../utils/chart'\r\nimport Overlay from './overlay'\r\n\r\ninterface Attrs {\r\n period: number\r\n lowColor: string\r\n highColor: string\r\n}\r\n\r\nclass HighLow extends Overlay {\r\n static type = OverlayType.Hilo\r\n static label = 'High/Low'\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 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 const 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 const 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 return {\r\n title: this.label,\r\n inputs: [period, highColor, lowColor],\r\n inputsErrorMessages: {\r\n period: `${period.label} must be a whole number between ${period.min} and ${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 toString() {\r\n return `HILO ${this.attrs.period}`\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 { isPositiveFloat } from '../utils/helpers'\r\nimport Overlay from './overlay'\r\n\r\ninterface Attrs {\r\n period: number\r\n price: number\r\n color: string\r\n}\r\n\r\nclass HorizontalLine extends Overlay {\r\n static type = OverlayType.Hline\r\n static label = 'Horizontal Line'\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 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 const 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 return {\r\n title: this.label,\r\n inputs: [price, color],\r\n inputsErrorMessages: {\r\n price: `${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 toString() {\r\n return `HL ${this.attrs.price}`\r\n }\r\n}\r\n\r\nHorizontalLine.prototype.defaults = { color: '#0587cd' }\r\n\r\nexport default HorizontalLine\r\n","import { ChartConfigChartPaneElement, RequireByKey } from '../../types/shared'\r\nimport { OverlayType } from '../constants/common'\r\nimport { drawInVisibleArea } from '../utils/draw_in_visible_area'\r\nimport { getParsedIntegersFromPeriodString } from '../utils/helpers'\r\nimport Overlay from './overlay'\r\n\r\ninterface Attrs {\r\n period?: string\r\n conversion: number\r\n base: number\r\n spanB: number\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\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 type = OverlayType.Ic\r\n static label = 'Ichimoku Cloud'\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 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 const 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 const 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 const 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 const 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 const 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 const 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 const 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 const 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 const 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 return {\r\n title: this.label,\r\n inputs: [\r\n conversion,\r\n base,\r\n spanB,\r\n spanAStrokeColor,\r\n spanAFillColor,\r\n spanBStrokeColor,\r\n spanBFillColor,\r\n conversionLineColor,\r\n baseLineColor,\r\n laggingSpanColor,\r\n ],\r\n inputsErrorMessages: {\r\n conversion: `${conversion.label} must be a whole number between ${conversion.min} and ${conversion.max}`,\r\n base: `${base.label} must be a whole number between ${base.min} and ${base.max}`,\r\n spanB: `${spanB.label} must be a whole number between ${spanB.min} and ${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 toString() {\r\n return `Ichimoku ${this.attrs.conversion},${this.attrs.base},${this.attrs.spanB}`\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 IchimokuCloud from './ic'\r\n\r\nclass IchimokuCloudFull extends IchimokuCloud {\r\n static type = OverlayType.Icf\r\n static label = 'Ichimoku Cloud (Full)'\r\n static renderFull = true\r\n}\r\n\r\nexport default IchimokuCloudFull\r\n","import { ChartConfigChartPaneElement, RequireByKey } from '../../types/shared'\r\nimport { OverlayType } from '../constants/common'\r\nimport AverageTrueRange from '../helpers/atr'\r\nimport { ExponentialMovingAverage } from '../indicator-calculation/ema'\r\nimport Overlay from './overlay'\r\n\r\ninterface Attrs {\r\n period?: string\r\n emaPeriod: number\r\n multiplier: number\r\n atrPeriod: number\r\n strokeColor: string\r\n fillColor: string\r\n}\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 type = OverlayType.Kch\r\n static label = 'Keltner Channel'\r\n\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 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\r\n const 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\r\n const 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\r\n const 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 const 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 return {\r\n title: this.label,\r\n inputs: [emaPeriod, multiplier, atrPeriod, strokeColor, fillColor],\r\n inputsErrorMessages: {\r\n emaPeriod: `${emaPeriod.label} must be a whole number between ${emaPeriod.min} and ${emaPeriod.max}`,\r\n multiplier: `${multiplier.label} must be a number between ${multiplier.min} and ${multiplier.max}`,\r\n atrPeriod: `${atrPeriod.label} must be a whole number between ${atrPeriod.min} and ${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 toString() {\r\n return `Keltner Channel ${this.attrs.emaPeriod},${this.attrs.multiplier},${this.attrs.atrPeriod}`\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 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 type = OverlayType.None\r\n static label = 'None'\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 Text from '../canvas/text'\r\nimport { OverlayType, TextAlign, TextBaseline } from '../constants/common'\r\nimport { getRoundedObject, getXYOffsetFromLine } from '../controllers/renderUtils'\r\nimport Overlay from './overlay'\r\n\r\ntype aboveBelowType = 'above' | 'below'\r\n\r\nclass Patterns extends Overlay {\r\n static type = OverlayType.Patterns\r\n static label = 'Patterns (daily charts)'\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 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 const 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 return {\r\n title: this.label,\r\n inputs: [supportColor, resistColor],\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 toString() {\r\n return ''\r\n }\r\n}\r\n\r\nPatterns.prototype.defaults = { supportColor: '#69c1ea', resistColor: '#d386df' }\r\n\r\nexport default Patterns\r\n","import * as dateFns from 'date-fns'\r\n\r\nimport { Instrument } from '../../types/shared'\r\nimport Text from '../canvas/text'\r\nimport { OverlayType, 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 Overlay from './overlay'\r\n\r\nenum Calculation {\r\n standard = 'Standard',\r\n fibonacci = 'Fibonacci',\r\n}\r\ntype CalculationType = keyof typeof Calculation\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\ninterface Attrs {\r\n period?: string\r\n calculationType: CalculationType\r\n color: string\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 type = OverlayType.Pp\r\n static label = 'Pivot Points'\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 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 const 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 return {\r\n title: this.label,\r\n inputs: [calculationType, color],\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 `Pivot Points (${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 Overlay from './overlay'\r\n\r\ninterface Attrs {\r\n step: number\r\n period: string\r\n maxStep: number\r\n risingColor: string\r\n fallingColor: string\r\n}\r\n\r\nclass SAR extends Overlay {\r\n static type = OverlayType.Sar\r\n static label = 'Parabolic SAR'\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 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 const 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 const 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 const 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 return {\r\n title: this.label,\r\n inputs: [step, maxStep, risingColor, fallingColor],\r\n inputsErrorMessages: {\r\n step: `${step.label} must be a number between ${step.min} and ${step.max}`,\r\n maxStep: `${maxStep.label} must be a number between ${maxStep.min} and ${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 toString() {\r\n return `SAR ${this.attrs.step},${this.attrs.maxStep}`\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 { MainCalculation, OnValueCalculated } from './main'\r\n\r\ntype Options = {\r\n period: number\r\n}\r\n\r\ntype DefaultCalculatedValuesType = {\r\n sma: number[]\r\n}\r\n\r\nexport class SMACalculation extends MainCalculation {\r\n static type = OverlayType.Sma\r\n declare options: Options\r\n\r\n getDefaultCalculatedValues() {\r\n return { sma: [] }\r\n }\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 { OverlayType } from '../constants/common'\r\nimport { SMACalculation } from '../indicator-calculation/sma'\r\nimport Overlay from './overlay'\r\n\r\ninterface Attrs {\r\n step: number\r\n period: string\r\n maxStep: number\r\n risingColor: string\r\n color: string\r\n}\r\n\r\nclass SMA extends Overlay {\r\n static type = OverlayType.Sma\r\n static label = 'Simple Moving Average'\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 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 const 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 return {\r\n title: this.label,\r\n inputs: [period, color],\r\n inputsErrorMessages: {\r\n period: `${period.label} must be a whole number between ${period.min} and ${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 toString() {\r\n return `SMA ${this.attrs.period}`\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 SMA from './sma'\r\n\r\nclass SMA2 extends SMA {\r\n static type = OverlayType.Sma2\r\n}\r\n\r\nSMA2.prototype.defaults = { color: '#ff6400' }\r\n\r\nexport default SMA2\r\n","import { ChartConfigChartPaneElement, RequireByKey } from '../../types/shared'\r\nimport { OverlayType } from '../constants/common'\r\nimport AverageTrueRange from '../helpers/atr'\r\nimport Overlay from './overlay'\r\n\r\ninterface Attrs {\r\n period: number\r\n multiplier: number\r\n uptrendColor: string\r\n downtrendColor: string\r\n}\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 type = OverlayType.Str\r\n static label = 'Supertrend'\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 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 const 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\r\n const 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 const 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 return {\r\n title: this.label,\r\n inputs: [period, multiplier, uptrendColor, downtrendColor],\r\n inputsErrorMessages: {\r\n period: `${period.label} must be a whole number between ${period.min} and ${period.max}`,\r\n multiplier: `${multiplier.label} must be a number between ${multiplier.min} and ${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 toString() {\r\n return `Supertrend ${this.attrs.period},${this.attrs.multiplier}`\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 * as d3 from 'd3'\r\n\r\nimport { ChartConfigChartPaneElement, RequireByKey } from '../../types/shared'\r\nimport { OverlayType } from '../constants/common'\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 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\ninterface Attrs {\r\n period: number | string\r\n opacity: number\r\n upColor?: string\r\n downColor?: string\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 type = OverlayType.Vp\r\n static label = 'Volume Profile'\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 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 const 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 const 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 const 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 return {\r\n title: this.label,\r\n inputs: [period, opacity, upColor, downColor],\r\n inputsErrorMessages: {\r\n period: `${period.label} must be a whole number between ${period.min} and ${period.max}`,\r\n opacity: `${opacity.label} must be a number between ${opacity.min} and ${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 toString() {\r\n return `VP ${this.attrs.period}`\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 { dateFromUnixTimestamp } from '../utils'\r\nimport { MainCalculation, OnValueCalculated } from './main'\r\n\r\ntype Options = {\r\n period: number\r\n}\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 type = OverlayType.Vwap\r\n\r\n getDefaultCalculatedValues() {\r\n return { vwap: [] }\r\n }\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 { OverlayType } from '../constants/common'\r\nimport { VWapCalculation } from '../indicator-calculation/vwap'\r\nimport PaneModel from '../models/pane'\r\nimport Overlay from './overlay'\r\n\r\ninterface Attrs {\r\n period: number\r\n color: string\r\n}\r\n\r\nclass VWAP extends Overlay {\r\n static type = OverlayType.Vwap\r\n static label = 'VWAP (intraday charts)'\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 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 return {\r\n title: this.label,\r\n inputs: [color],\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 `VWAP`\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 } from '../utils/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 hours = parsedDate.getHours()\r\n const formattedDate = formatDateToStringUS(parsedDate, options)\r\n\r\n if (hasEarningsDateSuffix) {\r\n let suffix = ''\r\n\r\n if (hours <= 9) {\r\n suffix = 'BMO'\r\n } else if (hours >= 16) {\r\n suffix = 'AMC'\r\n }\r\n\r\n return `${formattedDate} ${suffix}`\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 { 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 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 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 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\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 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","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","src","encodeURIComponent","onload","onerror","captureException","Error","extra","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","useDropdownState","placement","orientation","Dropdown","label","l","_jsxs","className","layout","DropdownItem","appearance","Icon","DropdownSeparator","Paragraph","size","ChartSyncableParts","_ref4","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","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","MAX_HEIGHT_PROPERTY","POPOVER_HEIGHT_LIMIT_STYLE","maxHeight","usePopoverMaxHeight","maxHeightLimit","hasViewportHeightLimit","offsets","innerHeight","useWindowSize","isWatching","visible","animating","buttonElement","unstable_referenceRef","buttonRect","offsetY","elementMaxHeight","bottom","scrollY","popoverId","getAttribute","popoverWrapper","getElementById","setProperty","DEFAULT_OFFSETS","ContextMenu","menuMaxHeight","items","popperElement","setPopperElement","virtualRef","x","scrollX","y","right","toJSON","getVirtualRef","dropdownState","isFullyClosed","getExtendedDialogState","hasBeenOpen","usePopper","modifiers","offset","popper","ContextMenuDropdown","isStatic","ContextMenuInner","MAX_SAFE_INTEGER","innerState","maxHeightStyle","rightContent","assign","menu_option","ChartGridCell","gridArea","GridLayout","columns","rows","border","gridTemplateColumns","gridTemplateRows","ChartGrid","defaultValueAccessor","InnerState","asComponent","valueKey","changeKey","valueAccessor","setState","handleChange","ListContext","getSelectedItemIndex","ListItem","activeTheme","onSelectItem","onKeyPress","closeOnSelect","Reakit","itemProps","Boolean","role","BUTTON_DEFAULT_ELEMENT","align","List","selectedIndex","direction","includeBaseStyles","prevSelected","move","closeParent","Provider","child","RangeSize","RangeSlider","step","inputClassName","hasTrack","setHasTrack","trackRef","thumbRef","thumbLeft","track","thumb","valuePercent","trackBox","thumbBox","Label","ToolbarTheme","ToolbarDirection","ToolbarContext","vertical","chipTransparent","isWrapped","isStretched","useToolbarContext","getToolbarSettings","hasRedesignEnabled","horizontal","alternative","Toolbar","toolbarRef","contextProviderValue","toolbarSettings","isSafariDesktop","forceReflow","throttle","originalWidth","offsetWidth","ToolbarButton","disabledTooltip","isInAction","isInActionProp","iconAction","buttonSettings","isActive","includeRedesign","grow","getButtonThemeSettings","getMainIcon","iconActive","titleActive","Delayed","delay","delayComponent","Spinner","DEFAULT_OFFSET","HOVER_TIMEOUT","useHoverPopover","unstable_offset","animated","COMPONENT_ANIMATION_DURATION","modal","showTimeout","hideTimeout","clearTimeouts","showPopover","hidePopover","onMouseOver","onMouseOut","focusOnShow","focusOnHide","finalFocusRef","ariaLabel","hideOnClickOutside","hasBackdrop","onOverlayClick","popoverWrapperStyle","popoverMaxHeight","hasButtonWidthLimit","zIndex","useZIndex","Portal","unstable_autoFocusOnShow","unstable_autoFocusOnHide","unstable_finalFocusRef","onTransitionEnd","onAnimationEnd","innerProps","Box","ToolbarGroup","defaultItem","groupItems","groupTitle","useNativeSelect","listState","currentId","loop","unstable_virtual","selectedItem","setSelectedItem","groupId","toLocaleLowerCase","isAlternativeTheme","defaultValue","setSelectedIndex","closePopover","newIndex","onItemChange","useList","i","stopPropagation","NativeSelect","ToolbarItem","isItemActive","ToolbarDivider","StepContent","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","target","on","popperOptions","ReactDOM","modalOverlayOpeningRadius","overlayRadius","modalOverlayOpeningPadding","overlayPadding","addSteps","start","TabSpacing","InternalTab","ariaSelected","spacing","content","classNames","Tab","TabList","TabPanel","Tabs","BadgeSize","BadgePadding","Badge","padding","badgePadding","badgeSize","TooltipInputWrapper","tooltipSettings","gutter","tooltip","useTooltipState","TooltipTrigger","focusable","isHideOnClickOutside","onFocus","onBlur","Tooltip","hideOnHoverOutside","TooltipInputComponent","TooltipInput","useTrackPageView","trackInitial","trackAutomatically","initialRender","handleTrackView","tracking","throttleWaitInMs","setSize","innerWidth","handleResize","cancel","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","Arrow","static","CanvasElementType","arrow","renderContent","resize","_thumbs","Thumb","x1","y1","x2","y2","getBoundingPointKeys","getDefaults","getChartLayoutSettings","ElementSettings","Colors","context","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","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","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","__","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","heightScaled","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","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","open","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","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","maxTickerLength","isLastDate","closeValue","arrays","q","isIdeaId","ideaID","OHLCChart","barWithoutMarginWidth","lineThickness","handleLengthFromWick","lineOffset","barX","PerfChart","overlayLabelWidth","perf","shouldRenderDate","tickerData","MARGIN","hasData","percentageText","lastCrossIndex","fromDate","toDate","filteredQuotes","closes","daysCount","end1","asc1","end2","asc2","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","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","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","chartSettingsModule","chartSettingsAsyncModule","onClose","ScrollableChartSettingsPopover","forceGlobalRerender","getIsConfigChanged","confirmationDialogState","checkChangesAndOpenDiscard","discardChangesAndHide","buttonPosition","popoverContentElement","getState","disclosureElement","chartHeight","chartElement","clientHeight","minHeight","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","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","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","handleValuesChange","shouldSubmit","shouldDismiss","hasOnSubmit","onSubmit","hasOnDismiss","onDismiss","handleValuesChangeDebounceRef","debounce","newFormState","maxWait","checkValidity","handleCloseDialog","Dialog","isDraggable","onFullyClosed","onHide","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","usePrevious","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","selector","componentDidMount","update","componentWillUnmount","forceUpdate","shown","querySelector","onContextMenu","ContextMenuComponent","ready","clientY","clientX","ChartEventPopoverWithState","unwatchedChartLayout","isPopoverMounted","chartEventsModule","isChartEventOfThisChart","setData","clickAwayRef","isListening","refCallback","handler","contains","useClickAway","chartEvent","popoverShow","popoverHide","newData","getChartEvenBadgeType","PopoverAnchor","store","ZIndexContext","AriakitPortal","autoFocusOnShow","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","renderAll","initialStoreDrawings","Hammer","touchAction","threshold","onPress","onTouchMove","passive","scrollable","onScalerReset","onZoomerReset","onDoubleClick","CHART_LAYOUT_CHILD_CHANGE_EVENT","touchEventsDisabled","onPaneClick","paneIndex","getIsHammerAllowScrollActive","isChartPane","getIsChartPane","onPaneMouseMove","onMouseLeave","onPaneMouseLeave","onResizerMouseDown","initialScrollable","onScalerMouseDown","onMouseEnter","onScalerMouseEnter","onScalerTouchStart","onZoomerMouseDown","onZoomerMouseMove","onZoomerTouchStart","DrawingTool","Mouse","onAddToZoomFactor","diff","shouldCalculateRightAlign","onCanvasInteractionStart","onCanvasInteractionMove","onTouchEnd","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","makeClone","bringToFront","sendToBack","bringForward","sendBackward","handleRemoveIndicatorPane","element_type","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","CanvasElement","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","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","drawingCreatorsModule","isDrawingCreatorsModuleLoading","autoSaveState","setIsDrawing","availableDrawingSettings","availableDrawingActions","isDrawingModeContinuous","hasHiddenDrawings","tool","drawingToolsTouchCreatorsByType","drawingToolsCreatorsByType","ToolClass","one","ToolbarComponent","isToolLoading","ChartAutoSaveNote","onNoteChange","ChartAutoSaveNotes","setTickers","unwatchedInternalStore","handleChartChange","tickerNoteMap","AutoSaveNotesDialog","isAnimating","hideOnEsc","onAction","onCancel","isAutosaveDialogContent","dialogContent","getDialogContent","ConfirmationDialogComponent","ToolButton","ToolbarMobile","isToolbarVisible","setIsToolbarVisible","urlSearchParams","setUrlSearchParams","useSearchParams","toolbarMobileElement","setToolbarMobileElement","MOBILE_TOOLBAR_DIV_ID","handleActiveToolChange","drawingTool","wrapperRef","handleClickOutside","openSelect","actionId","has","SIDEBAR_QUERY_PARAM","params","delete","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","modelProperties","isHideDrawingsActive","isToolbarHorizontal","handleInitialPreserveDrawingsState","DELETE","getPaneWithSelection","touchSize","onChartDestroy","setToolbarPosition","onWindowResize","handleOrientationChange","checkTouchEventsDisabled","throttledResize","preserveDrawings","toolsState","handlePreserveDrawingsSettings","setPreserveDrawings","URLSearchParams","tools_state","modelAttrs","newIsToolbarHorizontal","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","Wrapper","NotificationWrapper","ChartLayoutWithGlobalState","parentElement","setChartLayoutModel","getChartLayoutModelConfig","lastGlobalRerender","onRegisterChartLayoutModel","getDefaultZoomFactor","OnInitListener","setIsInit","checkIfInitIsComplete","elementIndex","opacity","newConfig","dark","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","isAnyQuoteLoading","setIsAnyQuoteLoading","dropdown","hideTooltip","dropdownItemProps","checkIfAnyQuoteIsLoading","fetchingQuotes","closeOnClick","activeChartQuote","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","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","Ema","getDefaultCalculatedValues","ema","calculate","onValueCalculated","_calculatedValues","calculatedValues","getAllCalculatedValues","lastNItems","getCalculatedValues","getDbColumnName","key1","key2","localeCompare","MAX_POSITIVE_DEFAULT_VALUE","MAX_NEGATIVE_DEFAULT_VALUE","periodInt","getParsedIntegersFromPeriodString","labelWidth","lastValue","shouldUpdate","compute","renderIndicator","getIsChartPageSpecificFunctionality","renderLabel","isComputeNecessary","tickTextStep","formatAxis","valueY","indicatorCurrentText","indicatorCurrentBackground","renderLabelChartsPage","renderLabelQuotePage","indicatorLabel","roundedRect","isPerfIndicator","Perf","renderCrossTextChartsPage","renderCrossTextQuotePage","renderOversoldOverbought","zero","drawLines","drawInVisibleAreaProps","fromIndexOffset","getCompensatedFirstBarToRenderIndex","clipHeight","renderZeroLine","tickStep","newAttrs","parsePeriodInt","setModel","areNoBarsVisible","getDomainDefaults","inputsErrorMessages","Rvol","Atr","Adx","Aro","Mfi","Rmi","Rsi","Stofu","Ult","Macd","Rwi","Trix","Wr","Aroosc","Roc","Cci","Fi","INDICATOR_DEFAULT_DOMAIN","getIsValid","getIsNumberInputValid","integerOnly","isPositiveInteger","ADX","pdi","mdi","adx","amdm","apdm","atr","deltaHigh","deltaLow","pdm","mdm","di","AroonCalculation","aroonUp","aroonDown","oscillator","highPeriod","highestInPeriod","periodSinceHigh","lastIndexOf","lowPeriod","lowestInPeriod","periodSinceLow","COLORS","Aroon","aroonCalculation","textLabels","labelSetting","AroonOscillator","ATR","AverageTrueRange","CommodityChannelIndex","cci","smaCount","tp","smaSum","devCount","typicalPrice","sma","devSum","dev","COT","cotQuoteCode","cot","commercialHedgers","largeTraders","smallTraders","units","renderAdditionalLabels","secondarylabelX","fontSettings","secondarylabel","FICalculation","fi","ForceIndex","fiCalculation","MACDCalculation","macd","histogram","fastPeriod","slowPeriod","signalPeriod","emaFast","emaSlow","emaSignal","MACD","macdCalculation","signalLine","MFI","mfi","negativeMoneyFlow","mf","prevTypicalPrice","positiveMoneyFlow","moneyFlow","oldMF","OBV","Obv","obv","currentObv","PricePerformance","firstFetchCalled","indicatorLabelWidth","getTickers","chartUuid","hasCachedData","getTickersAndTimeframe","getAll","firstBarTime","lastBarTime","dateToIndex","getDateToIndex","perfArrays","crossIndexTickerTimeStamp","tickerDateToIndex","tickerPerformance","performanceIndicatorLabel","isVertical","labelBottom","canFitItemsVertically","tickerQuote","maxCrossIndex","tickerTextWidth","crossText","getSanitizedTicker","RMI","rmi","momentum","u","ad","au","sumu","sumd","rs","ROC","roc","RsiCalculation","rsi","RSI","rsiCalculation","DEFAULT_PARAMETERS","RelativeVolume","rvol","baseLine","periodStr","parsePeriod","baseLineY","RWI","rwiHi","rwiLo","trSum","atrWeight","maxHi","maxLo","Stochastics","k1","kPeriod","dPeriod","dCount","dSum","kSum","kCount","highestHigh","lowestLow","StochasticsFast","Stofa","StochasticsSlow","Stosl","TrixCalculation","trix","ema1","ema2","ema3","trixCalculation","UltimateOscillator","period1","period2","period3","ult","bp","bpSum2","bpSum3","count2","count3","trSum2","trSum3","avg2","avg3","bpSum1","trSum1","count1","avg1","Volume","WilliamsR","none","aro","aroosc","rwi","stofa","stofu","stosl","vol","wr","getWatchedPropValue","watchedProp","spineObject","getIsSpineObject","hasToObject","getJSONReplacerFunc","getWatchedProps","getAreWatchedPropsEqual","currentValue","previousValue","DEFAULT_SPINE_EVENTS","DefaultSpineEvents","stringifiedOptions","useForceUpdate","watchedPropertiesRef","handleModelChange","spineEvents","hasMany","getChartElement","getChartType","defaultRefreshInterval","Default","customRefreshInterval","Elite","isStockFastRefreshAvailable","EliteStocksReduced","Free","omitKeys","getIsScrollable","perfQuotes","quotePerfTickers","quotePerf","chartOrIndicator","attrsInSync","ChartPartToAttrsSyncMap","modelAttr","hasOwnProperty","chartParts","isInSync","chartPart","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","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","emptyQuote","numberOfRefreshChecks","is404","patternsMinRange","patternsMaxRange","dataId","tickerRaw","shouldUseCache","doesQuoteAndFetchParamsMatch","isSameOrNoChartUuid","isNotEmptyQuote","isCacheAllowed","hasPatterns","doesQuoteAndOptionsMatch","getResolvedFetchingPromise","maxBars","tickersAndTimeframes","accumulator","fetchRequest","QuoteFetchTypeUrlOption","New","fetchingPromise","getUrl","getIsAbortError","NotFoundError","shouldUseEmptyQuote","Newer","noNewData","newQuoteData","lastTime","afterTime","AIndex","BIndex","mergeIndex","ADate","BDate","prevAIndex","prevDate","newDate","isSameWeek","isSameMonth","warn","thisDateLength","dataDateLength","atts","drawDays","getBarIndexes","barToDataIndex","getChartEventsWithId","deleteCachedQuote","cachedHeikinAshiData","HAClose","heikAshiData","cachedDayToOffset","dateStringFromDate","yyyy","mm","dd","dataIndex","cachedDateToIndex","getTimestampFromPositionX","host","env","BE_API_URL","rev","clearData","largeChartFontSize","INTERACTIVE_CHART_SETTINGS","tickerTimeframeChangeHeight","chartSettings","colorsOverride","settingColors","isLight","getNormalizedZIndex","BbCalculation","Bb","stdDev","upperBand","lowerBand","deviations","stdDevSum","getFreeColor","periods","getRGBAValueFromValidColorString","BB_COLORS","TOP","BOTTOM","MIDDLE","BollingerBands","scaledTop","scaledBottom","firstBarToRender","lastBarToRender","bbCalculation","topColor","bottomColor","DonchianChannels","Dch","medianBand","strokeColor","channelStrokeColor","fillColor","channelFillColor","medianBandColor","EMA","EMA2","Ema2","HighLow","Hilo","highColor","prevHigh","lowColor","prevLow","prevBar","Hline","isPositiveFloat","Stroke","Fill","Conversion","Base","SpanB","conversion","spanB","IchimokuCloud","Ic","renderFull","outsideBar","spanAFillColor","spanAStrokeColor","spanBFillColor","spanBStrokeColor","baseLineColor","conversionLineColor","laggingSpanColor","conversionLine","senkouSpanA","senkouSpanB","conversionStartIndex","baseStartIndex","spanBIndex","highestHi","lowestLo","lastSpanAX","lastSpanBX","cloudStartingX","toIndexOffset","fxOverride","IchimokuCloudFull","Icf","KeltnerChannel","Kch","emaPeriod","atrPeriod","middleLine","Patterns","originalScale","barsInDay","aboveBelow","textHS","above","below","supportColor","resistColor","kind","Calculation","PivotPeriod","PivotPoints","Pp","calculationType","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","SAR","Sar","maxStep","isLong","sar","ep","newHigh","newLow","af","sarToDraw","risingColor","fallingColor","customizable","SMACalculation","Sma","SMA","SMA2","Sma2","Supertrend","Str","finalUpperBand","finalLowerBand","supertrend","uptrendColor","avg","downtrendColor","VP_COLORS","applyOpacityToColor","VolumeProfile","Vp","upColor","downColor","minClose","maxClose","segment","segments","up","down","segmentIndex","isInSegment","volumeTrend","volumeFX","segmentHeightRaw","segmentHeight","upSegmentWidth","downSegmentWidth","VWapCalculation","Vwap","vwap","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","parsedDate","formattedDate","formatDateToStringUS","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","dates","upperIndex","isWithinRangeOfQuoteDate","commonVirtualCacheProps","cachedDates","virtualDateSeconds","getCachedVirtualDates","timeframeSeconds","firstDate","numOfDatesBefore","numOfDatesAfter","virtualTradedDays","dateStartSeconds","dateEndSeconds","datesSeconds","isStartBeforeDates","isEndAfterDates","dateTime","getVirtualTradedDays","marketStartSeconds","barTimeframeSeconds","quoteDatesTimestampOffset","dayStartSeconds","barSeconds","virtualTimeframeTradedDates","isLowerBounded","isOneBeforeLowerBoundStarts","lastDateIndex","isLookingBack","averageBarDate","numOfSecondsOutOfBounds","perfIndicatorElement","getPerfIndicatorTickerAndTimeframes","resolve","isXAxisInView","domainRange","priceFy","YAxisLeftMargin","firstBarClose","_ref20","changePercent","changePercentString","_ref21","isForexFuturesCryptoPage","_ref22","isForexFuturesCrypto","isOffscreenChartWithNarrowBars","isQuoteChartWithNarrowBars","_ref23","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","visited","WeakSet","toLocaleDateString","crypto","randomUUID","getRandomValues","Uint8Array","two","local","remote","useChartLayoutGlobalModelModule","useChartLayoutGlobalModel"],"sourceRoot":""}