Files
crypto_trader/frontend/node_modules/.vite/deps/lightweight-charts.js

12679 lines
500 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import "./chunk-HXA6O6EE.js";
// node_modules/fancy-canvas/size.mjs
function size(_a) {
var width = _a.width, height = _a.height;
if (width < 0) {
throw new Error("Negative width is not allowed for Size");
}
if (height < 0) {
throw new Error("Negative height is not allowed for Size");
}
return {
width,
height
};
}
function equalSizes(first, second) {
return first.width === second.width && first.height === second.height;
}
// node_modules/fancy-canvas/device-pixel-ratio.mjs
var Observable = (
/** @class */
function() {
function Observable2(win) {
var _this = this;
this._resolutionListener = function() {
return _this._onResolutionChanged();
};
this._resolutionMediaQueryList = null;
this._observers = [];
this._window = win;
this._installResolutionListener();
}
Observable2.prototype.dispose = function() {
this._uninstallResolutionListener();
this._window = null;
};
Object.defineProperty(Observable2.prototype, "value", {
get: function() {
return this._window.devicePixelRatio;
},
enumerable: false,
configurable: true
});
Observable2.prototype.subscribe = function(next) {
var _this = this;
var observer = { next };
this._observers.push(observer);
return {
unsubscribe: function() {
_this._observers = _this._observers.filter(function(o) {
return o !== observer;
});
}
};
};
Observable2.prototype._installResolutionListener = function() {
if (this._resolutionMediaQueryList !== null) {
throw new Error("Resolution listener is already installed");
}
var dppx = this._window.devicePixelRatio;
this._resolutionMediaQueryList = this._window.matchMedia("all and (resolution: ".concat(dppx, "dppx)"));
this._resolutionMediaQueryList.addListener(this._resolutionListener);
};
Observable2.prototype._uninstallResolutionListener = function() {
if (this._resolutionMediaQueryList !== null) {
this._resolutionMediaQueryList.removeListener(this._resolutionListener);
this._resolutionMediaQueryList = null;
}
};
Observable2.prototype._reinstallResolutionListener = function() {
this._uninstallResolutionListener();
this._installResolutionListener();
};
Observable2.prototype._onResolutionChanged = function() {
var _this = this;
this._observers.forEach(function(observer) {
return observer.next(_this._window.devicePixelRatio);
});
this._reinstallResolutionListener();
};
return Observable2;
}()
);
function createObservable(win) {
return new Observable(win);
}
// node_modules/fancy-canvas/canvas-element-bitmap-size.mjs
var DevicePixelContentBoxBinding = (
/** @class */
function() {
function DevicePixelContentBoxBinding2(canvasElement, transformBitmapSize, options) {
var _a;
this._canvasElement = null;
this._bitmapSizeChangedListeners = [];
this._suggestedBitmapSize = null;
this._suggestedBitmapSizeChangedListeners = [];
this._devicePixelRatioObservable = null;
this._canvasElementResizeObserver = null;
this._canvasElement = canvasElement;
this._canvasElementClientSize = size({
width: this._canvasElement.clientWidth,
height: this._canvasElement.clientHeight
});
this._transformBitmapSize = transformBitmapSize !== null && transformBitmapSize !== void 0 ? transformBitmapSize : function(size3) {
return size3;
};
this._allowResizeObserver = (_a = options === null || options === void 0 ? void 0 : options.allowResizeObserver) !== null && _a !== void 0 ? _a : true;
this._chooseAndInitObserver();
}
DevicePixelContentBoxBinding2.prototype.dispose = function() {
var _a, _b;
if (this._canvasElement === null) {
throw new Error("Object is disposed");
}
(_a = this._canvasElementResizeObserver) === null || _a === void 0 ? void 0 : _a.disconnect();
this._canvasElementResizeObserver = null;
(_b = this._devicePixelRatioObservable) === null || _b === void 0 ? void 0 : _b.dispose();
this._devicePixelRatioObservable = null;
this._suggestedBitmapSizeChangedListeners.length = 0;
this._bitmapSizeChangedListeners.length = 0;
this._canvasElement = null;
};
Object.defineProperty(DevicePixelContentBoxBinding2.prototype, "canvasElement", {
get: function() {
if (this._canvasElement === null) {
throw new Error("Object is disposed");
}
return this._canvasElement;
},
enumerable: false,
configurable: true
});
Object.defineProperty(DevicePixelContentBoxBinding2.prototype, "canvasElementClientSize", {
get: function() {
return this._canvasElementClientSize;
},
enumerable: false,
configurable: true
});
Object.defineProperty(DevicePixelContentBoxBinding2.prototype, "bitmapSize", {
get: function() {
return size({
width: this.canvasElement.width,
height: this.canvasElement.height
});
},
enumerable: false,
configurable: true
});
DevicePixelContentBoxBinding2.prototype.resizeCanvasElement = function(clientSize) {
this._canvasElementClientSize = size(clientSize);
this.canvasElement.style.width = "".concat(this._canvasElementClientSize.width, "px");
this.canvasElement.style.height = "".concat(this._canvasElementClientSize.height, "px");
this._invalidateBitmapSize();
};
DevicePixelContentBoxBinding2.prototype.subscribeBitmapSizeChanged = function(listener) {
this._bitmapSizeChangedListeners.push(listener);
};
DevicePixelContentBoxBinding2.prototype.unsubscribeBitmapSizeChanged = function(listener) {
this._bitmapSizeChangedListeners = this._bitmapSizeChangedListeners.filter(function(l) {
return l !== listener;
});
};
Object.defineProperty(DevicePixelContentBoxBinding2.prototype, "suggestedBitmapSize", {
get: function() {
return this._suggestedBitmapSize;
},
enumerable: false,
configurable: true
});
DevicePixelContentBoxBinding2.prototype.subscribeSuggestedBitmapSizeChanged = function(listener) {
this._suggestedBitmapSizeChangedListeners.push(listener);
};
DevicePixelContentBoxBinding2.prototype.unsubscribeSuggestedBitmapSizeChanged = function(listener) {
this._suggestedBitmapSizeChangedListeners = this._suggestedBitmapSizeChangedListeners.filter(function(l) {
return l !== listener;
});
};
DevicePixelContentBoxBinding2.prototype.applySuggestedBitmapSize = function() {
if (this._suggestedBitmapSize === null) {
return;
}
var oldSuggestedSize = this._suggestedBitmapSize;
this._suggestedBitmapSize = null;
this._resizeBitmap(oldSuggestedSize);
this._emitSuggestedBitmapSizeChanged(oldSuggestedSize, this._suggestedBitmapSize);
};
DevicePixelContentBoxBinding2.prototype._resizeBitmap = function(newSize) {
var oldSize = this.bitmapSize;
if (equalSizes(oldSize, newSize)) {
return;
}
this.canvasElement.width = newSize.width;
this.canvasElement.height = newSize.height;
this._emitBitmapSizeChanged(oldSize, newSize);
};
DevicePixelContentBoxBinding2.prototype._emitBitmapSizeChanged = function(oldSize, newSize) {
var _this = this;
this._bitmapSizeChangedListeners.forEach(function(listener) {
return listener.call(_this, oldSize, newSize);
});
};
DevicePixelContentBoxBinding2.prototype._suggestNewBitmapSize = function(newSize) {
var oldSuggestedSize = this._suggestedBitmapSize;
var finalNewSize = size(this._transformBitmapSize(newSize, this._canvasElementClientSize));
var newSuggestedSize = equalSizes(this.bitmapSize, finalNewSize) ? null : finalNewSize;
if (oldSuggestedSize === null && newSuggestedSize === null) {
return;
}
if (oldSuggestedSize !== null && newSuggestedSize !== null && equalSizes(oldSuggestedSize, newSuggestedSize)) {
return;
}
this._suggestedBitmapSize = newSuggestedSize;
this._emitSuggestedBitmapSizeChanged(oldSuggestedSize, newSuggestedSize);
};
DevicePixelContentBoxBinding2.prototype._emitSuggestedBitmapSizeChanged = function(oldSize, newSize) {
var _this = this;
this._suggestedBitmapSizeChangedListeners.forEach(function(listener) {
return listener.call(_this, oldSize, newSize);
});
};
DevicePixelContentBoxBinding2.prototype._chooseAndInitObserver = function() {
var _this = this;
if (!this._allowResizeObserver) {
this._initDevicePixelRatioObservable();
return;
}
isDevicePixelContentBoxSupported().then(function(isSupported) {
return isSupported ? _this._initResizeObserver() : _this._initDevicePixelRatioObservable();
});
};
DevicePixelContentBoxBinding2.prototype._initDevicePixelRatioObservable = function() {
var _this = this;
if (this._canvasElement === null) {
return;
}
var win = canvasElementWindow(this._canvasElement);
if (win === null) {
throw new Error("No window is associated with the canvas");
}
this._devicePixelRatioObservable = createObservable(win);
this._devicePixelRatioObservable.subscribe(function() {
return _this._invalidateBitmapSize();
});
this._invalidateBitmapSize();
};
DevicePixelContentBoxBinding2.prototype._invalidateBitmapSize = function() {
var _a, _b;
if (this._canvasElement === null) {
return;
}
var win = canvasElementWindow(this._canvasElement);
if (win === null) {
return;
}
var ratio = (_b = (_a = this._devicePixelRatioObservable) === null || _a === void 0 ? void 0 : _a.value) !== null && _b !== void 0 ? _b : win.devicePixelRatio;
var canvasRects = this._canvasElement.getClientRects();
var newSize = (
// eslint-disable-next-line no-negated-condition
canvasRects[0] !== void 0 ? predictedBitmapSize(canvasRects[0], ratio) : size({
width: this._canvasElementClientSize.width * ratio,
height: this._canvasElementClientSize.height * ratio
})
);
this._suggestNewBitmapSize(newSize);
};
DevicePixelContentBoxBinding2.prototype._initResizeObserver = function() {
var _this = this;
if (this._canvasElement === null) {
return;
}
this._canvasElementResizeObserver = new ResizeObserver(function(entries) {
var entry = entries.find(function(entry2) {
return entry2.target === _this._canvasElement;
});
if (!entry || !entry.devicePixelContentBoxSize || !entry.devicePixelContentBoxSize[0]) {
return;
}
var entrySize = entry.devicePixelContentBoxSize[0];
var newSize = size({
width: entrySize.inlineSize,
height: entrySize.blockSize
});
_this._suggestNewBitmapSize(newSize);
});
this._canvasElementResizeObserver.observe(this._canvasElement, { box: "device-pixel-content-box" });
};
return DevicePixelContentBoxBinding2;
}()
);
function bindTo(canvasElement, target) {
if (target.type === "device-pixel-content-box") {
return new DevicePixelContentBoxBinding(canvasElement, target.transform, target.options);
}
throw new Error("Unsupported binding target");
}
function canvasElementWindow(canvasElement) {
return canvasElement.ownerDocument.defaultView;
}
function isDevicePixelContentBoxSupported() {
return new Promise(function(resolve) {
var ro = new ResizeObserver(function(entries) {
resolve(entries.every(function(entry) {
return "devicePixelContentBoxSize" in entry;
}));
ro.disconnect();
});
ro.observe(document.body, { box: "device-pixel-content-box" });
}).catch(function() {
return false;
});
}
function predictedBitmapSize(canvasRect, ratio) {
return size({
width: Math.round(canvasRect.left * ratio + canvasRect.width * ratio) - Math.round(canvasRect.left * ratio),
height: Math.round(canvasRect.top * ratio + canvasRect.height * ratio) - Math.round(canvasRect.top * ratio)
});
}
// node_modules/fancy-canvas/canvas-rendering-target.mjs
var CanvasRenderingTarget2D = (
/** @class */
function() {
function CanvasRenderingTarget2D2(context, mediaSize, bitmapSize) {
if (mediaSize.width === 0 || mediaSize.height === 0) {
throw new TypeError("Rendering target could only be created on a media with positive width and height");
}
this._mediaSize = mediaSize;
if (bitmapSize.width === 0 || bitmapSize.height === 0) {
throw new TypeError("Rendering target could only be created using a bitmap with positive integer width and height");
}
this._bitmapSize = bitmapSize;
this._context = context;
}
CanvasRenderingTarget2D2.prototype.useMediaCoordinateSpace = function(f) {
try {
this._context.save();
this._context.setTransform(1, 0, 0, 1, 0, 0);
this._context.scale(this._horizontalPixelRatio, this._verticalPixelRatio);
return f({
context: this._context,
mediaSize: this._mediaSize
});
} finally {
this._context.restore();
}
};
CanvasRenderingTarget2D2.prototype.useBitmapCoordinateSpace = function(f) {
try {
this._context.save();
this._context.setTransform(1, 0, 0, 1, 0, 0);
return f({
context: this._context,
mediaSize: this._mediaSize,
bitmapSize: this._bitmapSize,
horizontalPixelRatio: this._horizontalPixelRatio,
verticalPixelRatio: this._verticalPixelRatio
});
} finally {
this._context.restore();
}
};
Object.defineProperty(CanvasRenderingTarget2D2.prototype, "_horizontalPixelRatio", {
get: function() {
return this._bitmapSize.width / this._mediaSize.width;
},
enumerable: false,
configurable: true
});
Object.defineProperty(CanvasRenderingTarget2D2.prototype, "_verticalPixelRatio", {
get: function() {
return this._bitmapSize.height / this._mediaSize.height;
},
enumerable: false,
configurable: true
});
return CanvasRenderingTarget2D2;
}()
);
function tryCreateCanvasRenderingTarget2D(binding, contextOptions) {
var mediaSize = binding.canvasElementClientSize;
if (mediaSize.width === 0 || mediaSize.height === 0) {
return null;
}
var bitmapSize = binding.bitmapSize;
if (bitmapSize.width === 0 || bitmapSize.height === 0) {
return null;
}
var context = binding.canvasElement.getContext("2d", contextOptions);
if (context === null) {
return null;
}
return new CanvasRenderingTarget2D(context, mediaSize, bitmapSize);
}
// node_modules/lightweight-charts/dist/lightweight-charts.development.mjs
var candlestickStyleDefaults = {
upColor: "#26a69a",
downColor: "#ef5350",
wickVisible: true,
borderVisible: true,
borderColor: "#378658",
borderUpColor: "#26a69a",
borderDownColor: "#ef5350",
wickColor: "#737375",
wickUpColor: "#26a69a",
wickDownColor: "#ef5350"
};
var barStyleDefaults = {
upColor: "#26a69a",
downColor: "#ef5350",
openVisible: true,
thinBars: true
};
var lineStyleDefaults = {
color: "#2196f3",
lineStyle: 0,
lineWidth: 3,
lineType: 0,
lineVisible: true,
crosshairMarkerVisible: true,
crosshairMarkerRadius: 4,
crosshairMarkerBorderColor: "",
crosshairMarkerBorderWidth: 2,
crosshairMarkerBackgroundColor: "",
lastPriceAnimation: 0,
pointMarkersVisible: false
};
var areaStyleDefaults = {
topColor: "rgba( 46, 220, 135, 0.4)",
bottomColor: "rgba( 40, 221, 100, 0)",
invertFilledArea: false,
lineColor: "#33D778",
lineStyle: 0,
lineWidth: 3,
lineType: 0,
lineVisible: true,
crosshairMarkerVisible: true,
crosshairMarkerRadius: 4,
crosshairMarkerBorderColor: "",
crosshairMarkerBorderWidth: 2,
crosshairMarkerBackgroundColor: "",
lastPriceAnimation: 0,
pointMarkersVisible: false
};
var baselineStyleDefaults = {
baseValue: {
type: "price",
price: 0
},
topFillColor1: "rgba(38, 166, 154, 0.28)",
topFillColor2: "rgba(38, 166, 154, 0.05)",
topLineColor: "rgba(38, 166, 154, 1)",
bottomFillColor1: "rgba(239, 83, 80, 0.05)",
bottomFillColor2: "rgba(239, 83, 80, 0.28)",
bottomLineColor: "rgba(239, 83, 80, 1)",
lineWidth: 3,
lineStyle: 0,
lineType: 0,
lineVisible: true,
crosshairMarkerVisible: true,
crosshairMarkerRadius: 4,
crosshairMarkerBorderColor: "",
crosshairMarkerBorderWidth: 2,
crosshairMarkerBackgroundColor: "",
lastPriceAnimation: 0,
pointMarkersVisible: false
};
var histogramStyleDefaults = {
color: "#26a69a",
base: 0
};
var customStyleDefaults = {
color: "#2196f3"
};
var seriesOptionsDefaults = {
title: "",
visible: true,
lastValueVisible: true,
priceLineVisible: true,
priceLineSource: 0,
priceLineWidth: 1,
priceLineColor: "",
priceLineStyle: 2,
baseLineVisible: true,
baseLineWidth: 1,
baseLineColor: "#B2B5BE",
baseLineStyle: 0,
priceFormat: {
type: "price",
precision: 2,
minMove: 0.01
}
};
var LineType;
(function(LineType2) {
LineType2[LineType2["Simple"] = 0] = "Simple";
LineType2[LineType2["WithSteps"] = 1] = "WithSteps";
LineType2[LineType2["Curved"] = 2] = "Curved";
})(LineType || (LineType = {}));
var LineStyle;
(function(LineStyle2) {
LineStyle2[LineStyle2["Solid"] = 0] = "Solid";
LineStyle2[LineStyle2["Dotted"] = 1] = "Dotted";
LineStyle2[LineStyle2["Dashed"] = 2] = "Dashed";
LineStyle2[LineStyle2["LargeDashed"] = 3] = "LargeDashed";
LineStyle2[LineStyle2["SparseDotted"] = 4] = "SparseDotted";
})(LineStyle || (LineStyle = {}));
function setLineStyle(ctx, style) {
const dashPatterns = {
[
0
/* LineStyle.Solid */
]: [],
[
1
/* LineStyle.Dotted */
]: [ctx.lineWidth, ctx.lineWidth],
[
2
/* LineStyle.Dashed */
]: [2 * ctx.lineWidth, 2 * ctx.lineWidth],
[
3
/* LineStyle.LargeDashed */
]: [6 * ctx.lineWidth, 6 * ctx.lineWidth],
[
4
/* LineStyle.SparseDotted */
]: [ctx.lineWidth, 4 * ctx.lineWidth]
};
const dashPattern = dashPatterns[style];
ctx.setLineDash(dashPattern);
}
function drawHorizontalLine(ctx, y, left, right) {
ctx.beginPath();
const correction = ctx.lineWidth % 2 ? 0.5 : 0;
ctx.moveTo(left, y + correction);
ctx.lineTo(right, y + correction);
ctx.stroke();
}
function drawVerticalLine(ctx, x, top, bottom) {
ctx.beginPath();
const correction = ctx.lineWidth % 2 ? 0.5 : 0;
ctx.moveTo(x + correction, top);
ctx.lineTo(x + correction, bottom);
ctx.stroke();
}
function strokeInPixel(ctx, drawFunction) {
ctx.save();
if (ctx.lineWidth % 2) {
ctx.translate(0.5, 0.5);
}
drawFunction();
ctx.restore();
}
function assert(condition, message) {
if (!condition) {
throw new Error("Assertion failed" + (message ? ": " + message : ""));
}
}
function ensureDefined(value) {
if (value === void 0) {
throw new Error("Value is undefined");
}
return value;
}
function ensureNotNull(value) {
if (value === null) {
throw new Error("Value is null");
}
return value;
}
function ensure(value) {
return ensureNotNull(ensureDefined(value));
}
function ensureNever(value) {
}
var namedColorRgbHexStrings = {
// The order of properties in this Record is not important for the internal logic.
// It's just GZIPped better when props follows this order.
// Please add new colors to the end of the record.
khaki: "#f0e68c",
azure: "#f0ffff",
aliceblue: "#f0f8ff",
ghostwhite: "#f8f8ff",
gold: "#ffd700",
goldenrod: "#daa520",
gainsboro: "#dcdcdc",
gray: "#808080",
green: "#008000",
honeydew: "#f0fff0",
floralwhite: "#fffaf0",
lightblue: "#add8e6",
lightcoral: "#f08080",
lemonchiffon: "#fffacd",
hotpink: "#ff69b4",
lightyellow: "#ffffe0",
greenyellow: "#adff2f",
lightgoldenrodyellow: "#fafad2",
limegreen: "#32cd32",
linen: "#faf0e6",
lightcyan: "#e0ffff",
magenta: "#f0f",
maroon: "#800000",
olive: "#808000",
orange: "#ffa500",
oldlace: "#fdf5e6",
mediumblue: "#0000cd",
transparent: "#0000",
lime: "#0f0",
lightpink: "#ffb6c1",
mistyrose: "#ffe4e1",
moccasin: "#ffe4b5",
midnightblue: "#191970",
orchid: "#da70d6",
mediumorchid: "#ba55d3",
mediumturquoise: "#48d1cc",
orangered: "#ff4500",
royalblue: "#4169e1",
powderblue: "#b0e0e6",
red: "#f00",
coral: "#ff7f50",
turquoise: "#40e0d0",
white: "#fff",
whitesmoke: "#f5f5f5",
wheat: "#f5deb3",
teal: "#008080",
steelblue: "#4682b4",
bisque: "#ffe4c4",
aquamarine: "#7fffd4",
aqua: "#0ff",
sienna: "#a0522d",
silver: "#c0c0c0",
springgreen: "#00ff7f",
antiquewhite: "#faebd7",
burlywood: "#deb887",
brown: "#a52a2a",
beige: "#f5f5dc",
chocolate: "#d2691e",
chartreuse: "#7fff00",
cornflowerblue: "#6495ed",
cornsilk: "#fff8dc",
crimson: "#dc143c",
cadetblue: "#5f9ea0",
tomato: "#ff6347",
fuchsia: "#f0f",
blue: "#00f",
salmon: "#fa8072",
blanchedalmond: "#ffebcd",
slateblue: "#6a5acd",
slategray: "#708090",
thistle: "#d8bfd8",
tan: "#d2b48c",
cyan: "#0ff",
darkblue: "#00008b",
darkcyan: "#008b8b",
darkgoldenrod: "#b8860b",
darkgray: "#a9a9a9",
blueviolet: "#8a2be2",
black: "#000",
darkmagenta: "#8b008b",
darkslateblue: "#483d8b",
darkkhaki: "#bdb76b",
darkorchid: "#9932cc",
darkorange: "#ff8c00",
darkgreen: "#006400",
darkred: "#8b0000",
dodgerblue: "#1e90ff",
darkslategray: "#2f4f4f",
dimgray: "#696969",
deepskyblue: "#00bfff",
firebrick: "#b22222",
forestgreen: "#228b22",
indigo: "#4b0082",
ivory: "#fffff0",
lavenderblush: "#fff0f5",
feldspar: "#d19275",
indianred: "#cd5c5c",
lightgreen: "#90ee90",
lightgrey: "#d3d3d3",
lightskyblue: "#87cefa",
lightslategray: "#789",
lightslateblue: "#8470ff",
snow: "#fffafa",
lightseagreen: "#20b2aa",
lightsalmon: "#ffa07a",
darksalmon: "#e9967a",
darkviolet: "#9400d3",
mediumpurple: "#9370d8",
mediumaquamarine: "#66cdaa",
skyblue: "#87ceeb",
lavender: "#e6e6fa",
lightsteelblue: "#b0c4de",
mediumvioletred: "#c71585",
mintcream: "#f5fffa",
navajowhite: "#ffdead",
navy: "#000080",
olivedrab: "#6b8e23",
palevioletred: "#d87093",
violetred: "#d02090",
yellow: "#ff0",
yellowgreen: "#9acd32",
lawngreen: "#7cfc00",
pink: "#ffc0cb",
paleturquoise: "#afeeee",
palegoldenrod: "#eee8aa",
darkolivegreen: "#556b2f",
darkseagreen: "#8fbc8f",
darkturquoise: "#00ced1",
peachpuff: "#ffdab9",
deeppink: "#ff1493",
violet: "#ee82ee",
palegreen: "#98fb98",
mediumseagreen: "#3cb371",
peru: "#cd853f",
saddlebrown: "#8b4513",
sandybrown: "#f4a460",
rosybrown: "#bc8f8f",
purple: "#800080",
seagreen: "#2e8b57",
seashell: "#fff5ee",
papayawhip: "#ffefd5",
mediumslateblue: "#7b68ee",
plum: "#dda0dd",
mediumspringgreen: "#00fa9a"
};
function normalizeRgbComponent(component) {
if (component < 0) {
return 0;
}
if (component > 255) {
return 255;
}
return Math.round(component) || 0;
}
function normalizeAlphaComponent(component) {
if (component <= 0 || component > 1) {
return Math.min(Math.max(component, 0), 1);
}
return Math.round(component * 1e4) / 1e4;
}
var shortHexRe = /^#([0-9a-f])([0-9a-f])([0-9a-f])([0-9a-f])?$/i;
var hexRe = /^#([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})?$/i;
var rgbRe = /^rgb\(\s*(-?\d{1,10})\s*,\s*(-?\d{1,10})\s*,\s*(-?\d{1,10})\s*\)$/;
var rgbaRe = /^rgba\(\s*(-?\d{1,10})\s*,\s*(-?\d{1,10})\s*,\s*(-?\d{1,10})\s*,\s*(-?\d*\.?\d+)\s*\)$/;
function colorStringToRgba(colorString) {
colorString = colorString.toLowerCase();
if (colorString in namedColorRgbHexStrings) {
colorString = namedColorRgbHexStrings[colorString];
}
{
const matches = rgbaRe.exec(colorString) || rgbRe.exec(colorString);
if (matches) {
return [
normalizeRgbComponent(parseInt(matches[1], 10)),
normalizeRgbComponent(parseInt(matches[2], 10)),
normalizeRgbComponent(parseInt(matches[3], 10)),
normalizeAlphaComponent(matches.length < 5 ? 1 : parseFloat(matches[4]))
];
}
}
{
const matches = hexRe.exec(colorString);
if (matches) {
return [
normalizeRgbComponent(parseInt(matches[1], 16)),
normalizeRgbComponent(parseInt(matches[2], 16)),
normalizeRgbComponent(parseInt(matches[3], 16)),
1
];
}
}
{
const matches = shortHexRe.exec(colorString);
if (matches) {
return [
normalizeRgbComponent(parseInt(matches[1], 16) * 17),
normalizeRgbComponent(parseInt(matches[2], 16) * 17),
normalizeRgbComponent(parseInt(matches[3], 16) * 17),
1
];
}
}
throw new Error(`Cannot parse color: ${colorString}`);
}
function rgbaToGrayscale(rgbValue) {
const redComponentGrayscaleWeight = 0.199;
const greenComponentGrayscaleWeight = 0.687;
const blueComponentGrayscaleWeight = 0.114;
return redComponentGrayscaleWeight * rgbValue[0] + greenComponentGrayscaleWeight * rgbValue[1] + blueComponentGrayscaleWeight * rgbValue[2];
}
function applyAlpha(color2, alpha) {
if (color2 === "transparent") {
return color2;
}
const originRgba = colorStringToRgba(color2);
const originAlpha = originRgba[3];
return `rgba(${originRgba[0]}, ${originRgba[1]}, ${originRgba[2]}, ${alpha * originAlpha})`;
}
function generateContrastColors(backgroundColor) {
const rgb = colorStringToRgba(backgroundColor);
return {
_internal_background: `rgb(${rgb[0]}, ${rgb[1]}, ${rgb[2]})`,
_internal_foreground: rgbaToGrayscale(rgb) > 160 ? "black" : "white"
};
}
function colorStringToGrayscale(backgroundColor) {
return rgbaToGrayscale(colorStringToRgba(backgroundColor));
}
function gradientColorAtPercent(topColor, bottomColor, percent) {
const [topR, topG, topB, topA] = colorStringToRgba(topColor);
const [bottomR, bottomG, bottomB, bottomA] = colorStringToRgba(bottomColor);
const resultRgba = [
normalizeRgbComponent(topR + percent * (bottomR - topR)),
normalizeRgbComponent(topG + percent * (bottomG - topG)),
normalizeRgbComponent(topB + percent * (bottomB - topB)),
normalizeAlphaComponent(topA + percent * (bottomA - topA))
];
return `rgba(${resultRgba[0]}, ${resultRgba[1]}, ${resultRgba[2]}, ${resultRgba[3]})`;
}
var Delegate = class {
constructor() {
this._private__listeners = [];
}
_internal_subscribe(callback, linkedObject, singleshot) {
const listener = {
_internal_callback: callback,
_internal_linkedObject: linkedObject,
_internal_singleshot: singleshot === true
};
this._private__listeners.push(listener);
}
_internal_unsubscribe(callback) {
const index = this._private__listeners.findIndex((listener) => callback === listener._internal_callback);
if (index > -1) {
this._private__listeners.splice(index, 1);
}
}
_internal_unsubscribeAll(linkedObject) {
this._private__listeners = this._private__listeners.filter((listener) => listener._internal_linkedObject !== linkedObject);
}
_internal_fire(param1, param2, param3) {
const listenersSnapshot = [...this._private__listeners];
this._private__listeners = this._private__listeners.filter((listener) => !listener._internal_singleshot);
listenersSnapshot.forEach((listener) => listener._internal_callback(param1, param2, param3));
}
_internal_hasListeners() {
return this._private__listeners.length > 0;
}
_internal_destroy() {
this._private__listeners = [];
}
};
function merge(dst, ...sources) {
for (const src of sources) {
for (const i in src) {
if (src[i] === void 0 || !Object.prototype.hasOwnProperty.call(src, i) || ["__proto__", "constructor", "prototype"].includes(i)) {
continue;
}
if ("object" !== typeof src[i] || dst[i] === void 0 || Array.isArray(src[i])) {
dst[i] = src[i];
} else {
merge(dst[i], src[i]);
}
}
}
return dst;
}
function isNumber(value) {
return typeof value === "number" && isFinite(value);
}
function isInteger(value) {
return typeof value === "number" && value % 1 === 0;
}
function isString(value) {
return typeof value === "string";
}
function isBoolean(value) {
return typeof value === "boolean";
}
function clone(object) {
const o = object;
if (!o || "object" !== typeof o) {
return o;
}
let c;
if (Array.isArray(o)) {
c = [];
} else {
c = {};
}
let p;
let v;
for (p in o) {
if (o.hasOwnProperty(p)) {
v = o[p];
if (v && "object" === typeof v) {
c[p] = clone(v);
} else {
c[p] = v;
}
}
}
return c;
}
function notNull(t) {
return t !== null;
}
function undefinedIfNull(t) {
return t === null ? void 0 : t;
}
var defaultFontFamily = `-apple-system, BlinkMacSystemFont, 'Trebuchet MS', Roboto, Ubuntu, sans-serif`;
function makeFont(size3, family, style) {
if (style !== void 0) {
style = `${style} `;
} else {
style = "";
}
if (family === void 0) {
family = defaultFontFamily;
}
return `${style}${size3}px ${family}`;
}
var PriceAxisRendererOptionsProvider = class {
constructor(chartModel) {
this._private__rendererOptions = {
_internal_borderSize: 1,
_internal_tickLength: 5,
_internal_fontSize: NaN,
_internal_font: "",
_internal_fontFamily: "",
_internal_color: "",
_internal_paneBackgroundColor: "",
_internal_paddingBottom: 0,
_internal_paddingInner: 0,
_internal_paddingOuter: 0,
_internal_paddingTop: 0,
_internal_baselineOffset: 0
};
this._private__chartModel = chartModel;
}
_internal_options() {
const rendererOptions = this._private__rendererOptions;
const currentFontSize = this._private__fontSize();
const currentFontFamily = this._private__fontFamily();
if (rendererOptions._internal_fontSize !== currentFontSize || rendererOptions._internal_fontFamily !== currentFontFamily) {
rendererOptions._internal_fontSize = currentFontSize;
rendererOptions._internal_fontFamily = currentFontFamily;
rendererOptions._internal_font = makeFont(currentFontSize, currentFontFamily);
rendererOptions._internal_paddingTop = 2.5 / 12 * currentFontSize;
rendererOptions._internal_paddingBottom = rendererOptions._internal_paddingTop;
rendererOptions._internal_paddingInner = currentFontSize / 12 * rendererOptions._internal_tickLength;
rendererOptions._internal_paddingOuter = currentFontSize / 12 * rendererOptions._internal_tickLength;
rendererOptions._internal_baselineOffset = 0;
}
rendererOptions._internal_color = this._private__textColor();
rendererOptions._internal_paneBackgroundColor = this._private__paneBackgroundColor();
return this._private__rendererOptions;
}
_private__textColor() {
return this._private__chartModel._internal_options().layout.textColor;
}
_private__paneBackgroundColor() {
return this._private__chartModel._internal_backgroundTopColor();
}
_private__fontSize() {
return this._private__chartModel._internal_options().layout.fontSize;
}
_private__fontFamily() {
return this._private__chartModel._internal_options().layout.fontFamily;
}
};
var CompositeRenderer = class {
constructor() {
this._private__renderers = [];
}
_internal_setRenderers(renderers) {
this._private__renderers = renderers;
}
_internal_draw(target, isHovered, hitTestData) {
this._private__renderers.forEach((r) => {
r._internal_draw(target, isHovered, hitTestData);
});
}
};
var BitmapCoordinatesPaneRenderer = class {
_internal_draw(target, isHovered, hitTestData) {
target.useBitmapCoordinateSpace((scope) => this._internal__drawImpl(scope, isHovered, hitTestData));
}
};
var PaneRendererMarks = class extends BitmapCoordinatesPaneRenderer {
constructor() {
super(...arguments);
this._internal__data = null;
}
_internal_setData(data) {
this._internal__data = data;
}
_internal__drawImpl({ context: ctx, horizontalPixelRatio, verticalPixelRatio }) {
if (this._internal__data === null || this._internal__data._internal_visibleRange === null) {
return;
}
const visibleRange = this._internal__data._internal_visibleRange;
const data = this._internal__data;
const tickWidth = Math.max(1, Math.floor(horizontalPixelRatio));
const correction = tickWidth % 2 / 2;
const draw = (radiusMedia) => {
ctx.beginPath();
for (let i = visibleRange.to - 1; i >= visibleRange.from; --i) {
const point = data._internal_items[i];
const centerX = Math.round(point._internal_x * horizontalPixelRatio) + correction;
const centerY = point._internal_y * verticalPixelRatio;
const radius2 = radiusMedia * verticalPixelRatio + correction;
ctx.moveTo(centerX, centerY);
ctx.arc(centerX, centerY, radius2, 0, Math.PI * 2);
}
ctx.fill();
};
if (data._internal_lineWidth > 0) {
ctx.fillStyle = data._internal_backColor;
draw(data._internal_radius + data._internal_lineWidth);
}
ctx.fillStyle = data._internal_lineColor;
draw(data._internal_radius);
}
};
function createEmptyMarkerData() {
return {
_internal_items: [{
_internal_x: 0,
_internal_y: 0,
_internal_time: 0,
_internal_price: 0
}],
_internal_lineColor: "",
_internal_backColor: "",
_internal_radius: 0,
_internal_lineWidth: 0,
_internal_visibleRange: null
};
}
var rangeForSinglePoint = { from: 0, to: 1 };
var CrosshairMarksPaneView = class {
constructor(chartModel, crosshair) {
this._private__compositeRenderer = new CompositeRenderer();
this._private__markersRenderers = [];
this._private__markersData = [];
this._private__invalidated = true;
this._private__chartModel = chartModel;
this._private__crosshair = crosshair;
this._private__compositeRenderer._internal_setRenderers(this._private__markersRenderers);
}
_internal_update(updateType) {
const serieses = this._private__chartModel._internal_serieses();
if (serieses.length !== this._private__markersRenderers.length) {
this._private__markersData = serieses.map(createEmptyMarkerData);
this._private__markersRenderers = this._private__markersData.map((data) => {
const res = new PaneRendererMarks();
res._internal_setData(data);
return res;
});
this._private__compositeRenderer._internal_setRenderers(this._private__markersRenderers);
}
this._private__invalidated = true;
}
_internal_renderer() {
if (this._private__invalidated) {
this._private__updateImpl();
this._private__invalidated = false;
}
return this._private__compositeRenderer;
}
_private__updateImpl() {
const forceHidden = this._private__crosshair._internal_options().mode === 2;
const serieses = this._private__chartModel._internal_serieses();
const timePointIndex = this._private__crosshair._internal_appliedIndex();
const timeScale = this._private__chartModel._internal_timeScale();
serieses.forEach((s, index) => {
var _a;
const data = this._private__markersData[index];
const seriesData = s._internal_markerDataAtIndex(timePointIndex);
if (forceHidden || seriesData === null || !s._internal_visible()) {
data._internal_visibleRange = null;
return;
}
const firstValue = ensureNotNull(s._internal_firstValue());
data._internal_lineColor = seriesData._internal_backgroundColor;
data._internal_radius = seriesData._internal_radius;
data._internal_lineWidth = seriesData._internal_borderWidth;
data._internal_items[0]._internal_price = seriesData._internal_price;
data._internal_items[0]._internal_y = s._internal_priceScale()._internal_priceToCoordinate(seriesData._internal_price, firstValue._internal_value);
data._internal_backColor = (_a = seriesData._internal_borderColor) !== null && _a !== void 0 ? _a : this._private__chartModel._internal_backgroundColorAtYPercentFromTop(data._internal_items[0]._internal_y / s._internal_priceScale()._internal_height());
data._internal_items[0]._internal_time = timePointIndex;
data._internal_items[0]._internal_x = timeScale._internal_indexToCoordinate(timePointIndex);
data._internal_visibleRange = rangeForSinglePoint;
});
}
};
var CrosshairRenderer = class extends BitmapCoordinatesPaneRenderer {
constructor(data) {
super();
this._private__data = data;
}
_internal__drawImpl({ context: ctx, bitmapSize, horizontalPixelRatio, verticalPixelRatio }) {
if (this._private__data === null) {
return;
}
const vertLinesVisible = this._private__data._internal_vertLine._internal_visible;
const horzLinesVisible = this._private__data._internal_horzLine._internal_visible;
if (!vertLinesVisible && !horzLinesVisible) {
return;
}
const x = Math.round(this._private__data._internal_x * horizontalPixelRatio);
const y = Math.round(this._private__data._internal_y * verticalPixelRatio);
ctx.lineCap = "butt";
if (vertLinesVisible && x >= 0) {
ctx.lineWidth = Math.floor(this._private__data._internal_vertLine._internal_lineWidth * horizontalPixelRatio);
ctx.strokeStyle = this._private__data._internal_vertLine._internal_color;
ctx.fillStyle = this._private__data._internal_vertLine._internal_color;
setLineStyle(ctx, this._private__data._internal_vertLine._internal_lineStyle);
drawVerticalLine(ctx, x, 0, bitmapSize.height);
}
if (horzLinesVisible && y >= 0) {
ctx.lineWidth = Math.floor(this._private__data._internal_horzLine._internal_lineWidth * verticalPixelRatio);
ctx.strokeStyle = this._private__data._internal_horzLine._internal_color;
ctx.fillStyle = this._private__data._internal_horzLine._internal_color;
setLineStyle(ctx, this._private__data._internal_horzLine._internal_lineStyle);
drawHorizontalLine(ctx, y, 0, bitmapSize.width);
}
}
};
var CrosshairPaneView = class {
constructor(source) {
this._private__invalidated = true;
this._private__rendererData = {
_internal_vertLine: {
_internal_lineWidth: 1,
_internal_lineStyle: 0,
_internal_color: "",
_internal_visible: false
},
_internal_horzLine: {
_internal_lineWidth: 1,
_internal_lineStyle: 0,
_internal_color: "",
_internal_visible: false
},
_internal_x: 0,
_internal_y: 0
};
this._private__renderer = new CrosshairRenderer(this._private__rendererData);
this._private__source = source;
}
_internal_update() {
this._private__invalidated = true;
}
_internal_renderer() {
if (this._private__invalidated) {
this._private__updateImpl();
this._private__invalidated = false;
}
return this._private__renderer;
}
_private__updateImpl() {
const visible = this._private__source._internal_visible();
const pane = ensureNotNull(this._private__source._internal_pane());
const crosshairOptions = pane._internal_model()._internal_options().crosshair;
const data = this._private__rendererData;
if (crosshairOptions.mode === 2) {
data._internal_horzLine._internal_visible = false;
data._internal_vertLine._internal_visible = false;
return;
}
data._internal_horzLine._internal_visible = visible && this._private__source._internal_horzLineVisible(pane);
data._internal_vertLine._internal_visible = visible && this._private__source._internal_vertLineVisible();
data._internal_horzLine._internal_lineWidth = crosshairOptions.horzLine.width;
data._internal_horzLine._internal_lineStyle = crosshairOptions.horzLine.style;
data._internal_horzLine._internal_color = crosshairOptions.horzLine.color;
data._internal_vertLine._internal_lineWidth = crosshairOptions.vertLine.width;
data._internal_vertLine._internal_lineStyle = crosshairOptions.vertLine.style;
data._internal_vertLine._internal_color = crosshairOptions.vertLine.color;
data._internal_x = this._private__source._internal_appliedX();
data._internal_y = this._private__source._internal_appliedY();
}
};
function fillRectInnerBorder(ctx, x, y, width, height, borderWidth) {
ctx.fillRect(x + borderWidth, y, width - borderWidth * 2, borderWidth);
ctx.fillRect(x + borderWidth, y + height - borderWidth, width - borderWidth * 2, borderWidth);
ctx.fillRect(x, y, borderWidth, height);
ctx.fillRect(x + width - borderWidth, y, borderWidth, height);
}
function clearRect(ctx, x, y, w, h, clearColor) {
ctx.save();
ctx.globalCompositeOperation = "copy";
ctx.fillStyle = clearColor;
ctx.fillRect(x, y, w, h);
ctx.restore();
}
function changeBorderRadius(borderRadius, offset) {
return borderRadius.map((x) => x === 0 ? x : x + offset);
}
function drawRoundRect(ctx, x, y, w, h, radii) {
ctx.beginPath();
if (ctx.roundRect) {
ctx.roundRect(x, y, w, h, radii);
return;
}
ctx.lineTo(x + w - radii[1], y);
if (radii[1] !== 0) {
ctx.arcTo(x + w, y, x + w, y + radii[1], radii[1]);
}
ctx.lineTo(x + w, y + h - radii[2]);
if (radii[2] !== 0) {
ctx.arcTo(x + w, y + h, x + w - radii[2], y + h, radii[2]);
}
ctx.lineTo(x + radii[3], y + h);
if (radii[3] !== 0) {
ctx.arcTo(x, y + h, x, y + h - radii[3], radii[3]);
}
ctx.lineTo(x, y + radii[0]);
if (radii[0] !== 0) {
ctx.arcTo(x, y, x + radii[0], y, radii[0]);
}
}
function drawRoundRectWithBorder(ctx, left, top, width, height, backgroundColor, borderWidth = 0, outerBorderRadius = [0, 0, 0, 0], borderColor = "") {
ctx.save();
if (!borderWidth || !borderColor || borderColor === backgroundColor) {
drawRoundRect(ctx, left, top, width, height, outerBorderRadius);
ctx.fillStyle = backgroundColor;
ctx.fill();
ctx.restore();
return;
}
const halfBorderWidth = borderWidth / 2;
const radii = changeBorderRadius(outerBorderRadius, -halfBorderWidth);
drawRoundRect(ctx, left + halfBorderWidth, top + halfBorderWidth, width - borderWidth, height - borderWidth, radii);
if (backgroundColor !== "transparent") {
ctx.fillStyle = backgroundColor;
ctx.fill();
}
if (borderColor !== "transparent") {
ctx.lineWidth = borderWidth;
ctx.strokeStyle = borderColor;
ctx.closePath();
ctx.stroke();
}
ctx.restore();
}
function clearRectWithGradient(ctx, x, y, w, h, topColor, bottomColor) {
ctx.save();
ctx.globalCompositeOperation = "copy";
const gradient = ctx.createLinearGradient(0, 0, 0, h);
gradient.addColorStop(0, topColor);
gradient.addColorStop(1, bottomColor);
ctx.fillStyle = gradient;
ctx.fillRect(x, y, w, h);
ctx.restore();
}
var PriceAxisViewRenderer = class {
constructor(data, commonData) {
this._internal_setData(data, commonData);
}
_internal_setData(data, commonData) {
this._private__data = data;
this._private__commonData = commonData;
}
_internal_height(rendererOptions, useSecondLine) {
if (!this._private__data._internal_visible) {
return 0;
}
return rendererOptions._internal_fontSize + rendererOptions._internal_paddingTop + rendererOptions._internal_paddingBottom;
}
_internal_draw(target, rendererOptions, textWidthCache, align) {
if (!this._private__data._internal_visible || this._private__data._internal_text.length === 0) {
return;
}
const textColor = this._private__data._internal_color;
const backgroundColor = this._private__commonData._internal_background;
const geometry = target.useBitmapCoordinateSpace((scope) => {
const ctx = scope.context;
ctx.font = rendererOptions._internal_font;
const geom = this._private__calculateGeometry(scope, rendererOptions, textWidthCache, align);
const gb = geom._internal_bitmap;
if (geom._internal_alignRight) {
drawRoundRectWithBorder(ctx, gb._internal_xOutside, gb._internal_yTop, gb._internal_totalWidth, gb._internal_totalHeight, backgroundColor, gb._internal_horzBorder, [gb._internal_radius, 0, 0, gb._internal_radius], backgroundColor);
} else {
drawRoundRectWithBorder(ctx, gb._internal_xInside, gb._internal_yTop, gb._internal_totalWidth, gb._internal_totalHeight, backgroundColor, gb._internal_horzBorder, [0, gb._internal_radius, gb._internal_radius, 0], backgroundColor);
}
if (this._private__data._internal_tickVisible) {
ctx.fillStyle = textColor;
ctx.fillRect(gb._internal_xInside, gb._internal_yMid, gb._internal_xTick - gb._internal_xInside, gb._internal_tickHeight);
}
if (this._private__data._internal_borderVisible) {
ctx.fillStyle = rendererOptions._internal_paneBackgroundColor;
ctx.fillRect(geom._internal_alignRight ? gb._internal_right - gb._internal_horzBorder : 0, gb._internal_yTop, gb._internal_horzBorder, gb._internal_yBottom - gb._internal_yTop);
}
return geom;
});
target.useMediaCoordinateSpace(({ context: ctx }) => {
const gm = geometry._internal_media;
ctx.font = rendererOptions._internal_font;
ctx.textAlign = geometry._internal_alignRight ? "right" : "left";
ctx.textBaseline = "middle";
ctx.fillStyle = textColor;
ctx.fillText(this._private__data._internal_text, gm._internal_xText, (gm._internal_yTop + gm._internal_yBottom) / 2 + gm._internal_textMidCorrection);
});
}
_private__calculateGeometry(scope, rendererOptions, textWidthCache, align) {
var _a;
const { context: ctx, bitmapSize, mediaSize, horizontalPixelRatio, verticalPixelRatio } = scope;
const tickSize = this._private__data._internal_tickVisible || !this._private__data._internal_moveTextToInvisibleTick ? rendererOptions._internal_tickLength : 0;
const horzBorder = this._private__data._internal_separatorVisible ? rendererOptions._internal_borderSize : 0;
const paddingTop = rendererOptions._internal_paddingTop + this._private__commonData._internal_additionalPaddingTop;
const paddingBottom = rendererOptions._internal_paddingBottom + this._private__commonData._internal_additionalPaddingBottom;
const paddingInner = rendererOptions._internal_paddingInner;
const paddingOuter = rendererOptions._internal_paddingOuter;
const text = this._private__data._internal_text;
const actualTextHeight = rendererOptions._internal_fontSize;
const textMidCorrection = textWidthCache._internal_yMidCorrection(ctx, text);
const textWidth = Math.ceil(textWidthCache._internal_measureText(ctx, text));
const totalHeight = actualTextHeight + paddingTop + paddingBottom;
const totalWidth = rendererOptions._internal_borderSize + paddingInner + paddingOuter + textWidth + tickSize;
const tickHeightBitmap = Math.max(1, Math.floor(verticalPixelRatio));
let totalHeightBitmap = Math.round(totalHeight * verticalPixelRatio);
if (totalHeightBitmap % 2 !== tickHeightBitmap % 2) {
totalHeightBitmap += 1;
}
const horzBorderBitmap = horzBorder > 0 ? Math.max(1, Math.floor(horzBorder * horizontalPixelRatio)) : 0;
const totalWidthBitmap = Math.round(totalWidth * horizontalPixelRatio);
const tickSizeBitmap = Math.round(tickSize * horizontalPixelRatio);
const yMid = (_a = this._private__commonData._internal_fixedCoordinate) !== null && _a !== void 0 ? _a : this._private__commonData._internal_coordinate;
const yMidBitmap = Math.round(yMid * verticalPixelRatio) - Math.floor(verticalPixelRatio * 0.5);
const yTopBitmap = Math.floor(yMidBitmap + tickHeightBitmap / 2 - totalHeightBitmap / 2);
const yBottomBitmap = yTopBitmap + totalHeightBitmap;
const alignRight = align === "right";
const xInside = alignRight ? mediaSize.width - horzBorder : horzBorder;
const xInsideBitmap = alignRight ? bitmapSize.width - horzBorderBitmap : horzBorderBitmap;
let xOutsideBitmap;
let xTickBitmap;
let xText;
if (alignRight) {
xOutsideBitmap = xInsideBitmap - totalWidthBitmap;
xTickBitmap = xInsideBitmap - tickSizeBitmap;
xText = xInside - tickSize - paddingInner - horzBorder;
} else {
xOutsideBitmap = xInsideBitmap + totalWidthBitmap;
xTickBitmap = xInsideBitmap + tickSizeBitmap;
xText = xInside + tickSize + paddingInner;
}
return {
_internal_alignRight: alignRight,
_internal_bitmap: {
_internal_yTop: yTopBitmap,
_internal_yMid: yMidBitmap,
_internal_yBottom: yBottomBitmap,
_internal_totalWidth: totalWidthBitmap,
_internal_totalHeight: totalHeightBitmap,
// TODO: it is better to have different horizontal and vertical radii
_internal_radius: 2 * horizontalPixelRatio,
_internal_horzBorder: horzBorderBitmap,
_internal_xOutside: xOutsideBitmap,
_internal_xInside: xInsideBitmap,
_internal_xTick: xTickBitmap,
_internal_tickHeight: tickHeightBitmap,
_internal_right: bitmapSize.width
},
_internal_media: {
_internal_yTop: yTopBitmap / verticalPixelRatio,
_internal_yBottom: yBottomBitmap / verticalPixelRatio,
_internal_xText: xText,
_internal_textMidCorrection: textMidCorrection
}
};
}
};
var PriceAxisView = class {
constructor(ctor) {
this._private__commonRendererData = {
_internal_coordinate: 0,
_internal_background: "#000",
_internal_additionalPaddingBottom: 0,
_internal_additionalPaddingTop: 0
};
this._private__axisRendererData = {
_internal_text: "",
_internal_visible: false,
_internal_tickVisible: true,
_internal_moveTextToInvisibleTick: false,
_internal_borderColor: "",
_internal_color: "#FFF",
_internal_borderVisible: false,
_internal_separatorVisible: false
};
this._private__paneRendererData = {
_internal_text: "",
_internal_visible: false,
_internal_tickVisible: false,
_internal_moveTextToInvisibleTick: true,
_internal_borderColor: "",
_internal_color: "#FFF",
_internal_borderVisible: true,
_internal_separatorVisible: true
};
this._private__invalidated = true;
this._private__axisRenderer = new (ctor || PriceAxisViewRenderer)(this._private__axisRendererData, this._private__commonRendererData);
this._private__paneRenderer = new (ctor || PriceAxisViewRenderer)(this._private__paneRendererData, this._private__commonRendererData);
}
_internal_text() {
this._private__updateRendererDataIfNeeded();
return this._private__axisRendererData._internal_text;
}
_internal_coordinate() {
this._private__updateRendererDataIfNeeded();
return this._private__commonRendererData._internal_coordinate;
}
_internal_update() {
this._private__invalidated = true;
}
_internal_height(rendererOptions, useSecondLine = false) {
return Math.max(this._private__axisRenderer._internal_height(rendererOptions, useSecondLine), this._private__paneRenderer._internal_height(rendererOptions, useSecondLine));
}
_internal_getFixedCoordinate() {
return this._private__commonRendererData._internal_fixedCoordinate || 0;
}
_internal_setFixedCoordinate(value) {
this._private__commonRendererData._internal_fixedCoordinate = value;
}
_internal_isVisible() {
this._private__updateRendererDataIfNeeded();
return this._private__axisRendererData._internal_visible || this._private__paneRendererData._internal_visible;
}
_internal_isAxisLabelVisible() {
this._private__updateRendererDataIfNeeded();
return this._private__axisRendererData._internal_visible;
}
_internal_renderer(priceScale) {
this._private__updateRendererDataIfNeeded();
this._private__axisRendererData._internal_tickVisible = this._private__axisRendererData._internal_tickVisible && priceScale._internal_options().ticksVisible;
this._private__paneRendererData._internal_tickVisible = this._private__paneRendererData._internal_tickVisible && priceScale._internal_options().ticksVisible;
this._private__axisRenderer._internal_setData(this._private__axisRendererData, this._private__commonRendererData);
this._private__paneRenderer._internal_setData(this._private__paneRendererData, this._private__commonRendererData);
return this._private__axisRenderer;
}
_internal_paneRenderer() {
this._private__updateRendererDataIfNeeded();
this._private__axisRenderer._internal_setData(this._private__axisRendererData, this._private__commonRendererData);
this._private__paneRenderer._internal_setData(this._private__paneRendererData, this._private__commonRendererData);
return this._private__paneRenderer;
}
_private__updateRendererDataIfNeeded() {
if (this._private__invalidated) {
this._private__axisRendererData._internal_tickVisible = true;
this._private__paneRendererData._internal_tickVisible = false;
this._internal__updateRendererData(this._private__axisRendererData, this._private__paneRendererData, this._private__commonRendererData);
}
}
};
var CrosshairPriceAxisView = class extends PriceAxisView {
constructor(source, priceScale, valueProvider) {
super();
this._private__source = source;
this._private__priceScale = priceScale;
this._private__valueProvider = valueProvider;
}
_internal__updateRendererData(axisRendererData, paneRendererData, commonRendererData) {
axisRendererData._internal_visible = false;
if (this._private__source._internal_options().mode === 2) {
return;
}
const options = this._private__source._internal_options().horzLine;
if (!options.labelVisible) {
return;
}
const firstValue = this._private__priceScale._internal_firstValue();
if (!this._private__source._internal_visible() || this._private__priceScale._internal_isEmpty() || firstValue === null) {
return;
}
const colors = generateContrastColors(options.labelBackgroundColor);
commonRendererData._internal_background = colors._internal_background;
axisRendererData._internal_color = colors._internal_foreground;
const additionalPadding = 2 / 12 * this._private__priceScale._internal_fontSize();
commonRendererData._internal_additionalPaddingTop = additionalPadding;
commonRendererData._internal_additionalPaddingBottom = additionalPadding;
const value = this._private__valueProvider(this._private__priceScale);
commonRendererData._internal_coordinate = value._internal_coordinate;
axisRendererData._internal_text = this._private__priceScale._internal_formatPrice(value._internal_price, firstValue);
axisRendererData._internal_visible = true;
}
};
var optimizationReplacementRe = /[1-9]/g;
var radius$1 = 2;
var TimeAxisViewRenderer = class {
constructor() {
this._private__data = null;
}
_internal_setData(data) {
this._private__data = data;
}
_internal_draw(target, rendererOptions) {
if (this._private__data === null || this._private__data._internal_visible === false || this._private__data._internal_text.length === 0) {
return;
}
const textWidth = target.useMediaCoordinateSpace(({ context: ctx }) => {
ctx.font = rendererOptions._internal_font;
return Math.round(rendererOptions._internal_widthCache._internal_measureText(ctx, ensureNotNull(this._private__data)._internal_text, optimizationReplacementRe));
});
if (textWidth <= 0) {
return;
}
const horzMargin = rendererOptions._internal_paddingHorizontal;
const labelWidth = textWidth + 2 * horzMargin;
const labelWidthHalf = labelWidth / 2;
const timeScaleWidth = this._private__data._internal_width;
let coordinate = this._private__data._internal_coordinate;
let x1 = Math.floor(coordinate - labelWidthHalf) + 0.5;
if (x1 < 0) {
coordinate = coordinate + Math.abs(0 - x1);
x1 = Math.floor(coordinate - labelWidthHalf) + 0.5;
} else if (x1 + labelWidth > timeScaleWidth) {
coordinate = coordinate - Math.abs(timeScaleWidth - (x1 + labelWidth));
x1 = Math.floor(coordinate - labelWidthHalf) + 0.5;
}
const x2 = x1 + labelWidth;
const y1 = 0;
const y2 = Math.ceil(y1 + rendererOptions._internal_borderSize + rendererOptions._internal_tickLength + rendererOptions._internal_paddingTop + rendererOptions._internal_fontSize + rendererOptions._internal_paddingBottom);
target.useBitmapCoordinateSpace(({ context: ctx, horizontalPixelRatio, verticalPixelRatio }) => {
const data = ensureNotNull(this._private__data);
ctx.fillStyle = data._internal_background;
const x1scaled = Math.round(x1 * horizontalPixelRatio);
const y1scaled = Math.round(y1 * verticalPixelRatio);
const x2scaled = Math.round(x2 * horizontalPixelRatio);
const y2scaled = Math.round(y2 * verticalPixelRatio);
const radiusScaled = Math.round(radius$1 * horizontalPixelRatio);
ctx.beginPath();
ctx.moveTo(x1scaled, y1scaled);
ctx.lineTo(x1scaled, y2scaled - radiusScaled);
ctx.arcTo(x1scaled, y2scaled, x1scaled + radiusScaled, y2scaled, radiusScaled);
ctx.lineTo(x2scaled - radiusScaled, y2scaled);
ctx.arcTo(x2scaled, y2scaled, x2scaled, y2scaled - radiusScaled, radiusScaled);
ctx.lineTo(x2scaled, y1scaled);
ctx.fill();
if (data._internal_tickVisible) {
const tickX = Math.round(data._internal_coordinate * horizontalPixelRatio);
const tickTop = y1scaled;
const tickBottom = Math.round((tickTop + rendererOptions._internal_tickLength) * verticalPixelRatio);
ctx.fillStyle = data._internal_color;
const tickWidth = Math.max(1, Math.floor(horizontalPixelRatio));
const tickOffset = Math.floor(horizontalPixelRatio * 0.5);
ctx.fillRect(tickX - tickOffset, tickTop, tickWidth, tickBottom - tickTop);
}
});
target.useMediaCoordinateSpace(({ context: ctx }) => {
const data = ensureNotNull(this._private__data);
const yText = y1 + rendererOptions._internal_borderSize + rendererOptions._internal_tickLength + rendererOptions._internal_paddingTop + rendererOptions._internal_fontSize / 2;
ctx.font = rendererOptions._internal_font;
ctx.textAlign = "left";
ctx.textBaseline = "middle";
ctx.fillStyle = data._internal_color;
const textYCorrection = rendererOptions._internal_widthCache._internal_yMidCorrection(ctx, "Apr0");
ctx.translate(x1 + horzMargin, yText + textYCorrection);
ctx.fillText(data._internal_text, 0, 0);
});
}
};
var CrosshairTimeAxisView = class {
constructor(crosshair, model, valueProvider) {
this._private__invalidated = true;
this._private__renderer = new TimeAxisViewRenderer();
this._private__rendererData = {
_internal_visible: false,
_internal_background: "#4c525e",
_internal_color: "white",
_internal_text: "",
_internal_width: 0,
_internal_coordinate: NaN,
_internal_tickVisible: true
};
this._private__crosshair = crosshair;
this._private__model = model;
this._private__valueProvider = valueProvider;
}
_internal_update() {
this._private__invalidated = true;
}
_internal_renderer() {
if (this._private__invalidated) {
this._private__updateImpl();
this._private__invalidated = false;
}
this._private__renderer._internal_setData(this._private__rendererData);
return this._private__renderer;
}
_private__updateImpl() {
const data = this._private__rendererData;
data._internal_visible = false;
if (this._private__crosshair._internal_options().mode === 2) {
return;
}
const options = this._private__crosshair._internal_options().vertLine;
if (!options.labelVisible) {
return;
}
const timeScale = this._private__model._internal_timeScale();
if (timeScale._internal_isEmpty()) {
return;
}
data._internal_width = timeScale._internal_width();
const value = this._private__valueProvider();
if (value === null) {
return;
}
data._internal_coordinate = value._internal_coordinate;
const currentTime = timeScale._internal_indexToTimeScalePoint(this._private__crosshair._internal_appliedIndex());
data._internal_text = timeScale._internal_formatDateTime(ensureNotNull(currentTime));
data._internal_visible = true;
const colors = generateContrastColors(options.labelBackgroundColor);
data._internal_background = colors._internal_background;
data._internal_color = colors._internal_foreground;
data._internal_tickVisible = timeScale._internal_options().ticksVisible;
}
};
var DataSource = class {
constructor() {
this._internal__priceScale = null;
this._private__zorder = 0;
}
_internal_zorder() {
return this._private__zorder;
}
_internal_setZorder(zorder) {
this._private__zorder = zorder;
}
_internal_priceScale() {
return this._internal__priceScale;
}
_internal_setPriceScale(priceScale) {
this._internal__priceScale = priceScale;
}
_internal_labelPaneViews(pane) {
return [];
}
_internal_timeAxisViews() {
return [];
}
_internal_visible() {
return true;
}
};
var CrosshairMode;
(function(CrosshairMode2) {
CrosshairMode2[CrosshairMode2["Normal"] = 0] = "Normal";
CrosshairMode2[CrosshairMode2["Magnet"] = 1] = "Magnet";
CrosshairMode2[CrosshairMode2["Hidden"] = 2] = "Hidden";
})(CrosshairMode || (CrosshairMode = {}));
var Crosshair = class extends DataSource {
constructor(model, options) {
super();
this._private__pane = null;
this._private__price = NaN;
this._private__index = 0;
this._private__visible = true;
this._private__priceAxisViews = /* @__PURE__ */ new Map();
this._private__subscribed = false;
this._private__x = NaN;
this._private__y = NaN;
this._private__originX = NaN;
this._private__originY = NaN;
this._private__model = model;
this._private__options = options;
this._private__markersPaneView = new CrosshairMarksPaneView(model, this);
const valuePriceProvider = (rawPriceProvider, rawCoordinateProvider) => {
return (priceScale) => {
const coordinate = rawCoordinateProvider();
const rawPrice = rawPriceProvider();
if (priceScale === ensureNotNull(this._private__pane)._internal_defaultPriceScale()) {
return { _internal_price: rawPrice, _internal_coordinate: coordinate };
} else {
const firstValue = ensureNotNull(priceScale._internal_firstValue());
const price = priceScale._internal_coordinateToPrice(coordinate, firstValue);
return { _internal_price: price, _internal_coordinate: coordinate };
}
};
};
const valueTimeProvider = (rawIndexProvider, rawCoordinateProvider) => {
return () => {
const time = this._private__model._internal_timeScale()._internal_indexToTime(rawIndexProvider());
const coordinate = rawCoordinateProvider();
if (!time || !Number.isFinite(coordinate)) {
return null;
}
return {
_internal_time: time,
_internal_coordinate: coordinate
};
};
};
this._private__currentPosPriceProvider = valuePriceProvider(() => this._private__price, () => this._private__y);
const currentPosTimeProvider = valueTimeProvider(() => this._private__index, () => this._internal_appliedX());
this._private__timeAxisView = new CrosshairTimeAxisView(this, model, currentPosTimeProvider);
this._private__paneView = new CrosshairPaneView(this);
}
_internal_options() {
return this._private__options;
}
_internal_saveOriginCoord(x, y) {
this._private__originX = x;
this._private__originY = y;
}
_internal_clearOriginCoord() {
this._private__originX = NaN;
this._private__originY = NaN;
}
_internal_originCoordX() {
return this._private__originX;
}
_internal_originCoordY() {
return this._private__originY;
}
_internal_setPosition(index, price, pane) {
if (!this._private__subscribed) {
this._private__subscribed = true;
}
this._private__visible = true;
this._private__tryToUpdateViews(index, price, pane);
}
_internal_appliedIndex() {
return this._private__index;
}
_internal_appliedX() {
return this._private__x;
}
_internal_appliedY() {
return this._private__y;
}
_internal_visible() {
return this._private__visible;
}
_internal_clearPosition() {
this._private__visible = false;
this._private__setIndexToLastSeriesBarIndex();
this._private__price = NaN;
this._private__x = NaN;
this._private__y = NaN;
this._private__pane = null;
this._internal_clearOriginCoord();
}
_internal_paneViews(pane) {
return this._private__pane !== null ? [this._private__paneView, this._private__markersPaneView] : [];
}
_internal_horzLineVisible(pane) {
return pane === this._private__pane && this._private__options.horzLine.visible;
}
_internal_vertLineVisible() {
return this._private__options.vertLine.visible;
}
_internal_priceAxisViews(pane, priceScale) {
if (!this._private__visible || this._private__pane !== pane) {
this._private__priceAxisViews.clear();
}
const views = [];
if (this._private__pane === pane) {
views.push(this._private__createPriceAxisViewOnDemand(this._private__priceAxisViews, priceScale, this._private__currentPosPriceProvider));
}
return views;
}
_internal_timeAxisViews() {
return this._private__visible ? [this._private__timeAxisView] : [];
}
_internal_pane() {
return this._private__pane;
}
_internal_updateAllViews() {
this._private__paneView._internal_update();
this._private__priceAxisViews.forEach((value) => value._internal_update());
this._private__timeAxisView._internal_update();
this._private__markersPaneView._internal_update();
}
_private__priceScaleByPane(pane) {
if (pane && !pane._internal_defaultPriceScale()._internal_isEmpty()) {
return pane._internal_defaultPriceScale();
}
return null;
}
_private__tryToUpdateViews(index, price, pane) {
if (this._private__tryToUpdateData(index, price, pane)) {
this._internal_updateAllViews();
}
}
_private__tryToUpdateData(newIndex, newPrice, newPane) {
const oldX = this._private__x;
const oldY = this._private__y;
const oldPrice = this._private__price;
const oldIndex = this._private__index;
const oldPane = this._private__pane;
const priceScale = this._private__priceScaleByPane(newPane);
this._private__index = newIndex;
this._private__x = isNaN(newIndex) ? NaN : this._private__model._internal_timeScale()._internal_indexToCoordinate(newIndex);
this._private__pane = newPane;
const firstValue = priceScale !== null ? priceScale._internal_firstValue() : null;
if (priceScale !== null && firstValue !== null) {
this._private__price = newPrice;
this._private__y = priceScale._internal_priceToCoordinate(newPrice, firstValue);
} else {
this._private__price = NaN;
this._private__y = NaN;
}
return oldX !== this._private__x || oldY !== this._private__y || oldIndex !== this._private__index || oldPrice !== this._private__price || oldPane !== this._private__pane;
}
_private__setIndexToLastSeriesBarIndex() {
const lastIndexes = this._private__model._internal_serieses().map((s) => s._internal_bars()._internal_lastIndex()).filter(notNull);
const lastBarIndex = lastIndexes.length === 0 ? null : Math.max(...lastIndexes);
this._private__index = lastBarIndex !== null ? lastBarIndex : NaN;
}
_private__createPriceAxisViewOnDemand(map, priceScale, valueProvider) {
let view = map.get(priceScale);
if (view === void 0) {
view = new CrosshairPriceAxisView(this, priceScale, valueProvider);
map.set(priceScale, view);
}
return view;
}
};
function isDefaultPriceScale(priceScaleId) {
return priceScaleId === "left" || priceScaleId === "right";
}
function mergePaneInvalidation(beforeValue, newValue) {
if (beforeValue === void 0) {
return newValue;
}
const level = Math.max(beforeValue._internal_level, newValue._internal_level);
const autoScale = beforeValue._internal_autoScale || newValue._internal_autoScale;
return { _internal_level: level, _internal_autoScale: autoScale };
}
var InvalidateMask = class _InvalidateMask {
constructor(globalLevel) {
this._private__invalidatedPanes = /* @__PURE__ */ new Map();
this._private__timeScaleInvalidations = [];
this._private__globalLevel = globalLevel;
}
_internal_invalidatePane(paneIndex, invalidation) {
const prevValue = this._private__invalidatedPanes.get(paneIndex);
const newValue = mergePaneInvalidation(prevValue, invalidation);
this._private__invalidatedPanes.set(paneIndex, newValue);
}
_internal_fullInvalidation() {
return this._private__globalLevel;
}
_internal_invalidateForPane(paneIndex) {
const paneInvalidation = this._private__invalidatedPanes.get(paneIndex);
if (paneInvalidation === void 0) {
return {
_internal_level: this._private__globalLevel
};
}
return {
_internal_level: Math.max(this._private__globalLevel, paneInvalidation._internal_level),
_internal_autoScale: paneInvalidation._internal_autoScale
};
}
_internal_setFitContent() {
this._internal_stopTimeScaleAnimation();
this._private__timeScaleInvalidations = [{
_internal_type: 0
/* TimeScaleInvalidationType.FitContent */
}];
}
_internal_applyRange(range) {
this._internal_stopTimeScaleAnimation();
this._private__timeScaleInvalidations = [{ _internal_type: 1, _internal_value: range }];
}
_internal_setTimeScaleAnimation(animation) {
this._private__removeTimeScaleAnimation();
this._private__timeScaleInvalidations.push({ _internal_type: 5, _internal_value: animation });
}
_internal_stopTimeScaleAnimation() {
this._private__removeTimeScaleAnimation();
this._private__timeScaleInvalidations.push({
_internal_type: 6
/* TimeScaleInvalidationType.StopAnimation */
});
}
_internal_resetTimeScale() {
this._internal_stopTimeScaleAnimation();
this._private__timeScaleInvalidations = [{
_internal_type: 4
/* TimeScaleInvalidationType.Reset */
}];
}
_internal_setBarSpacing(barSpacing) {
this._internal_stopTimeScaleAnimation();
this._private__timeScaleInvalidations.push({ _internal_type: 2, _internal_value: barSpacing });
}
_internal_setRightOffset(offset) {
this._internal_stopTimeScaleAnimation();
this._private__timeScaleInvalidations.push({ _internal_type: 3, _internal_value: offset });
}
_internal_timeScaleInvalidations() {
return this._private__timeScaleInvalidations;
}
_internal_merge(other) {
for (const tsInvalidation of other._private__timeScaleInvalidations) {
this._private__applyTimeScaleInvalidation(tsInvalidation);
}
this._private__globalLevel = Math.max(this._private__globalLevel, other._private__globalLevel);
other._private__invalidatedPanes.forEach((invalidation, index) => {
this._internal_invalidatePane(index, invalidation);
});
}
static _internal_light() {
return new _InvalidateMask(
2
/* InvalidationLevel.Light */
);
}
static _internal_full() {
return new _InvalidateMask(
3
/* InvalidationLevel.Full */
);
}
_private__applyTimeScaleInvalidation(invalidation) {
switch (invalidation._internal_type) {
case 0:
this._internal_setFitContent();
break;
case 1:
this._internal_applyRange(invalidation._internal_value);
break;
case 2:
this._internal_setBarSpacing(invalidation._internal_value);
break;
case 3:
this._internal_setRightOffset(invalidation._internal_value);
break;
case 4:
this._internal_resetTimeScale();
break;
case 5:
this._internal_setTimeScaleAnimation(invalidation._internal_value);
break;
case 6:
this._private__removeTimeScaleAnimation();
}
}
_private__removeTimeScaleAnimation() {
const index = this._private__timeScaleInvalidations.findIndex(
(inv) => inv._internal_type === 5
/* TimeScaleInvalidationType.Animation */
);
if (index !== -1) {
this._private__timeScaleInvalidations.splice(index, 1);
}
}
};
var formatterOptions = {
_internal_decimalSign: ".",
_internal_decimalSignFractional: "'"
};
function numberToStringWithLeadingZero(value, length) {
if (!isNumber(value)) {
return "n/a";
}
if (!isInteger(length)) {
throw new TypeError("invalid length");
}
if (length < 0 || length > 16) {
throw new TypeError("invalid length");
}
if (length === 0) {
return value.toString();
}
const dummyString = "0000000000000000";
return (dummyString + value.toString()).slice(-length);
}
var PriceFormatter = class {
constructor(priceScale, minMove) {
if (!minMove) {
minMove = 1;
}
if (!isNumber(priceScale) || !isInteger(priceScale)) {
priceScale = 100;
}
if (priceScale < 0) {
throw new TypeError("invalid base");
}
this._private__priceScale = priceScale;
this._private__minMove = minMove;
this._private__calculateDecimal();
}
format(price) {
const sign = price < 0 ? "" : "";
price = Math.abs(price);
return sign + this._private__formatAsDecimal(price);
}
_private__calculateDecimal() {
this._internal__fractionalLength = 0;
if (this._private__priceScale > 0 && this._private__minMove > 0) {
let base = this._private__priceScale;
while (base > 1) {
base /= 10;
this._internal__fractionalLength++;
}
}
}
_private__formatAsDecimal(price) {
const base = this._private__priceScale / this._private__minMove;
let intPart = Math.floor(price);
let fracString = "";
const fracLength = this._internal__fractionalLength !== void 0 ? this._internal__fractionalLength : NaN;
if (base > 1) {
let fracPart = +(Math.round(price * base) - intPart * base).toFixed(this._internal__fractionalLength);
if (fracPart >= base) {
fracPart -= base;
intPart += 1;
}
fracString = formatterOptions._internal_decimalSign + numberToStringWithLeadingZero(+fracPart.toFixed(this._internal__fractionalLength) * this._private__minMove, fracLength);
} else {
intPart = Math.round(intPart * base) / base;
if (fracLength > 0) {
fracString = formatterOptions._internal_decimalSign + numberToStringWithLeadingZero(0, fracLength);
}
}
return intPart.toFixed(0) + fracString;
}
};
var PercentageFormatter = class extends PriceFormatter {
constructor(priceScale = 100) {
super(priceScale);
}
format(price) {
return `${super.format(price)}%`;
}
};
var VolumeFormatter = class {
constructor(precision) {
this._private__precision = precision;
}
format(vol) {
let sign = "";
if (vol < 0) {
sign = "-";
vol = -vol;
}
if (vol < 995) {
return sign + this._private__formatNumber(vol);
} else if (vol < 999995) {
return sign + this._private__formatNumber(vol / 1e3) + "K";
} else if (vol < 999999995) {
vol = 1e3 * Math.round(vol / 1e3);
return sign + this._private__formatNumber(vol / 1e6) + "M";
} else {
vol = 1e6 * Math.round(vol / 1e6);
return sign + this._private__formatNumber(vol / 1e9) + "B";
}
}
_private__formatNumber(value) {
let res;
const priceScale = Math.pow(10, this._private__precision);
value = Math.round(value * priceScale) / priceScale;
if (value >= 1e-15 && value < 1) {
res = value.toFixed(this._private__precision).replace(/\.?0+$/, "");
} else {
res = String(value);
}
return res.replace(/(\.[1-9]*)0+$/, (e, p1) => p1);
}
};
function walkLine(renderingScope, items, lineType, visibleRange, barWidth, styleGetter, finishStyledArea2) {
if (items.length === 0 || visibleRange.from >= items.length || visibleRange.to <= 0) {
return;
}
const { context: ctx, horizontalPixelRatio, verticalPixelRatio } = renderingScope;
const firstItem = items[visibleRange.from];
let currentStyle = styleGetter(renderingScope, firstItem);
let currentStyleFirstItem = firstItem;
if (visibleRange.to - visibleRange.from < 2) {
const halfBarWidth = barWidth / 2;
ctx.beginPath();
const item1 = { _internal_x: firstItem._internal_x - halfBarWidth, _internal_y: firstItem._internal_y };
const item2 = { _internal_x: firstItem._internal_x + halfBarWidth, _internal_y: firstItem._internal_y };
ctx.moveTo(item1._internal_x * horizontalPixelRatio, item1._internal_y * verticalPixelRatio);
ctx.lineTo(item2._internal_x * horizontalPixelRatio, item2._internal_y * verticalPixelRatio);
finishStyledArea2(renderingScope, currentStyle, item1, item2);
} else {
const changeStyle = (newStyle, currentItem2) => {
finishStyledArea2(renderingScope, currentStyle, currentStyleFirstItem, currentItem2);
ctx.beginPath();
currentStyle = newStyle;
currentStyleFirstItem = currentItem2;
};
let currentItem = currentStyleFirstItem;
ctx.beginPath();
ctx.moveTo(firstItem._internal_x * horizontalPixelRatio, firstItem._internal_y * verticalPixelRatio);
for (let i = visibleRange.from + 1; i < visibleRange.to; ++i) {
currentItem = items[i];
const itemStyle = styleGetter(renderingScope, currentItem);
switch (lineType) {
case 0:
ctx.lineTo(currentItem._internal_x * horizontalPixelRatio, currentItem._internal_y * verticalPixelRatio);
break;
case 1:
ctx.lineTo(currentItem._internal_x * horizontalPixelRatio, items[i - 1]._internal_y * verticalPixelRatio);
if (itemStyle !== currentStyle) {
changeStyle(itemStyle, currentItem);
ctx.lineTo(currentItem._internal_x * horizontalPixelRatio, items[i - 1]._internal_y * verticalPixelRatio);
}
ctx.lineTo(currentItem._internal_x * horizontalPixelRatio, currentItem._internal_y * verticalPixelRatio);
break;
case 2: {
const [cp1, cp2] = getControlPoints(items, i - 1, i);
ctx.bezierCurveTo(cp1._internal_x * horizontalPixelRatio, cp1._internal_y * verticalPixelRatio, cp2._internal_x * horizontalPixelRatio, cp2._internal_y * verticalPixelRatio, currentItem._internal_x * horizontalPixelRatio, currentItem._internal_y * verticalPixelRatio);
break;
}
}
if (lineType !== 1 && itemStyle !== currentStyle) {
changeStyle(itemStyle, currentItem);
ctx.moveTo(currentItem._internal_x * horizontalPixelRatio, currentItem._internal_y * verticalPixelRatio);
}
}
if (currentStyleFirstItem !== currentItem || currentStyleFirstItem === currentItem && lineType === 1) {
finishStyledArea2(renderingScope, currentStyle, currentStyleFirstItem, currentItem);
}
}
}
var curveTension = 6;
function subtract(p1, p2) {
return { _internal_x: p1._internal_x - p2._internal_x, _internal_y: p1._internal_y - p2._internal_y };
}
function add(p1, p2) {
return { _internal_x: p1._internal_x + p2._internal_x, _internal_y: p1._internal_y + p2._internal_y };
}
function divide(p1, n) {
return { _internal_x: p1._internal_x / n, _internal_y: p1._internal_y / n };
}
function getControlPoints(points, fromPointIndex, toPointIndex) {
const beforeFromPointIndex = Math.max(0, fromPointIndex - 1);
const afterToPointIndex = Math.min(points.length - 1, toPointIndex + 1);
const cp1 = add(points[fromPointIndex], divide(subtract(points[toPointIndex], points[beforeFromPointIndex]), curveTension));
const cp2 = subtract(points[toPointIndex], divide(subtract(points[afterToPointIndex], points[fromPointIndex]), curveTension));
return [cp1, cp2];
}
function finishStyledArea$1(baseLevelCoordinate, scope, style, areaFirstItem, newAreaFirstItem) {
const { context, horizontalPixelRatio, verticalPixelRatio } = scope;
context.lineTo(newAreaFirstItem._internal_x * horizontalPixelRatio, baseLevelCoordinate * verticalPixelRatio);
context.lineTo(areaFirstItem._internal_x * horizontalPixelRatio, baseLevelCoordinate * verticalPixelRatio);
context.closePath();
context.fillStyle = style;
context.fill();
}
var PaneRendererAreaBase = class extends BitmapCoordinatesPaneRenderer {
constructor() {
super(...arguments);
this._internal__data = null;
}
_internal_setData(data) {
this._internal__data = data;
}
_internal__drawImpl(renderingScope) {
var _a;
if (this._internal__data === null) {
return;
}
const { _internal_items: items, _internal_visibleRange: visibleRange, _internal_barWidth: barWidth, _internal_lineWidth: lineWidth, _internal_lineStyle: lineStyle, _internal_lineType: lineType } = this._internal__data;
const baseLevelCoordinate = (_a = this._internal__data._internal_baseLevelCoordinate) !== null && _a !== void 0 ? _a : this._internal__data._internal_invertFilledArea ? 0 : renderingScope.mediaSize.height;
if (visibleRange === null) {
return;
}
const ctx = renderingScope.context;
ctx.lineCap = "butt";
ctx.lineJoin = "round";
ctx.lineWidth = lineWidth;
setLineStyle(ctx, lineStyle);
ctx.lineWidth = 1;
walkLine(renderingScope, items, lineType, visibleRange, barWidth, this._internal__fillStyle.bind(this), finishStyledArea$1.bind(null, baseLevelCoordinate));
}
};
function clamp(value, minVal, maxVal) {
return Math.min(Math.max(value, minVal), maxVal);
}
function isBaseDecimal(value) {
if (value < 0) {
return false;
}
for (let current = value; current > 1; current /= 10) {
if (current % 10 !== 0) {
return false;
}
}
return true;
}
function greaterOrEqual(x1, x2, epsilon) {
return x2 - x1 <= epsilon;
}
function equal(x1, x2, epsilon) {
return Math.abs(x1 - x2) < epsilon;
}
function min(arr) {
if (arr.length < 1) {
throw Error("array is empty");
}
let minVal = arr[0];
for (let i = 1; i < arr.length; ++i) {
if (arr[i] < minVal) {
minVal = arr[i];
}
}
return minVal;
}
function ceiledEven(x) {
const ceiled = Math.ceil(x);
return ceiled % 2 !== 0 ? ceiled - 1 : ceiled;
}
function ceiledOdd(x) {
const ceiled = Math.ceil(x);
return ceiled % 2 === 0 ? ceiled - 1 : ceiled;
}
var GradientStyleCache = class {
_internal_get(scope, params) {
const cachedParams = this._private__params;
const { _internal_topColor1: topColor1, _internal_topColor2: topColor2, _internal_bottomColor1: bottomColor1, _internal_bottomColor2: bottomColor2, _internal_bottom: bottom, _internal_baseLevelCoordinate: baseLevelCoordinate } = params;
if (this._private__cachedValue === void 0 || cachedParams === void 0 || cachedParams._internal_topColor1 !== topColor1 || cachedParams._internal_topColor2 !== topColor2 || cachedParams._internal_bottomColor1 !== bottomColor1 || cachedParams._internal_bottomColor2 !== bottomColor2 || cachedParams._internal_baseLevelCoordinate !== baseLevelCoordinate || cachedParams._internal_bottom !== bottom) {
const gradient = scope.context.createLinearGradient(0, 0, 0, bottom);
gradient.addColorStop(0, topColor1);
if (baseLevelCoordinate != null) {
const baselinePercent = clamp(baseLevelCoordinate * scope.verticalPixelRatio / bottom, 0, 1);
gradient.addColorStop(baselinePercent, topColor2);
gradient.addColorStop(baselinePercent, bottomColor1);
}
gradient.addColorStop(1, bottomColor2);
this._private__cachedValue = gradient;
this._private__params = params;
}
return this._private__cachedValue;
}
};
var PaneRendererArea = class extends PaneRendererAreaBase {
constructor() {
super(...arguments);
this._private__fillCache = new GradientStyleCache();
}
_internal__fillStyle(renderingScope, item) {
return this._private__fillCache._internal_get(renderingScope, {
_internal_topColor1: item._internal_topColor,
_internal_topColor2: "",
_internal_bottomColor1: "",
_internal_bottomColor2: item._internal_bottomColor,
_internal_bottom: renderingScope.bitmapSize.height
});
}
};
function drawSeriesPointMarkers(renderingScope, items, pointMarkersRadius, visibleRange, styleGetter) {
const { horizontalPixelRatio, verticalPixelRatio, context } = renderingScope;
let prevStyle = null;
const tickWidth = Math.max(1, Math.floor(horizontalPixelRatio));
const correction = tickWidth % 2 / 2;
const radius2 = pointMarkersRadius * verticalPixelRatio + correction;
for (let i = visibleRange.to - 1; i >= visibleRange.from; --i) {
const point = items[i];
if (point) {
const style = styleGetter(renderingScope, point);
if (style !== prevStyle) {
context.beginPath();
if (prevStyle !== null) {
context.fill();
}
context.fillStyle = style;
prevStyle = style;
}
const centerX = Math.round(point._internal_x * horizontalPixelRatio) + correction;
const centerY = point._internal_y * verticalPixelRatio;
context.moveTo(centerX, centerY);
context.arc(centerX, centerY, radius2, 0, Math.PI * 2);
}
}
context.fill();
}
function finishStyledArea(scope, style) {
const ctx = scope.context;
ctx.strokeStyle = style;
ctx.stroke();
}
var PaneRendererLineBase = class extends BitmapCoordinatesPaneRenderer {
constructor() {
super(...arguments);
this._internal__data = null;
}
_internal_setData(data) {
this._internal__data = data;
}
_internal__drawImpl(renderingScope) {
if (this._internal__data === null) {
return;
}
const { _internal_items: items, _internal_visibleRange: visibleRange, _internal_barWidth: barWidth, _internal_lineType: lineType, _internal_lineWidth: lineWidth, _internal_lineStyle: lineStyle, _internal_pointMarkersRadius: pointMarkersRadius } = this._internal__data;
if (visibleRange === null) {
return;
}
const ctx = renderingScope.context;
ctx.lineCap = "butt";
ctx.lineWidth = lineWidth * renderingScope.verticalPixelRatio;
setLineStyle(ctx, lineStyle);
ctx.lineJoin = "round";
const styleGetter = this._internal__strokeStyle.bind(this);
if (lineType !== void 0) {
walkLine(renderingScope, items, lineType, visibleRange, barWidth, styleGetter, finishStyledArea);
}
if (pointMarkersRadius) {
drawSeriesPointMarkers(renderingScope, items, pointMarkersRadius, visibleRange, styleGetter);
}
}
};
var PaneRendererLine = class extends PaneRendererLineBase {
_internal__strokeStyle(renderingScope, item) {
return item._internal_lineColor;
}
};
function boundCompare(lower, arr, value, compare, start = 0, to = arr.length) {
let count = to - start;
while (0 < count) {
const count2 = count >> 1;
const mid = start + count2;
if (compare(arr[mid], value) === lower) {
start = mid + 1;
count -= count2 + 1;
} else {
count = count2;
}
}
return start;
}
var lowerBound = boundCompare.bind(null, true);
var upperBound = boundCompare.bind(null, false);
function lowerBoundItemsCompare(item, time) {
return item._internal_time < time;
}
function upperBoundItemsCompare(item, time) {
return time < item._internal_time;
}
function visibleTimedValues(items, range, extendedRange) {
const firstBar = range._internal_left();
const lastBar = range._internal_right();
const from = lowerBound(items, firstBar, lowerBoundItemsCompare);
const to = upperBound(items, lastBar, upperBoundItemsCompare);
if (!extendedRange) {
return { from, to };
}
let extendedFrom = from;
let extendedTo = to;
if (from > 0 && from < items.length && items[from]._internal_time >= firstBar) {
extendedFrom = from - 1;
}
if (to > 0 && to < items.length && items[to - 1]._internal_time <= lastBar) {
extendedTo = to + 1;
}
return { from: extendedFrom, to: extendedTo };
}
var SeriesPaneViewBase = class {
constructor(series, model, extendedVisibleRange) {
this._internal__invalidated = true;
this._internal__dataInvalidated = true;
this._internal__optionsInvalidated = true;
this._internal__items = [];
this._internal__itemsVisibleRange = null;
this._internal__series = series;
this._internal__model = model;
this._private__extendedVisibleRange = extendedVisibleRange;
}
_internal_update(updateType) {
this._internal__invalidated = true;
if (updateType === "data") {
this._internal__dataInvalidated = true;
}
if (updateType === "options") {
this._internal__optionsInvalidated = true;
}
}
_internal_renderer() {
if (!this._internal__series._internal_visible()) {
return null;
}
this._private__makeValid();
return this._internal__itemsVisibleRange === null ? null : this._internal__renderer;
}
_internal__updateOptions() {
this._internal__items = this._internal__items.map((item) => Object.assign(Object.assign({}, item), this._internal__series._internal_barColorer()._internal_barStyle(item._internal_time)));
}
_internal__clearVisibleRange() {
this._internal__itemsVisibleRange = null;
}
_private__makeValid() {
if (this._internal__dataInvalidated) {
this._internal__fillRawPoints();
this._internal__dataInvalidated = false;
}
if (this._internal__optionsInvalidated) {
this._internal__updateOptions();
this._internal__optionsInvalidated = false;
}
if (this._internal__invalidated) {
this._private__makeValidImpl();
this._internal__invalidated = false;
}
}
_private__makeValidImpl() {
const priceScale = this._internal__series._internal_priceScale();
const timeScale = this._internal__model._internal_timeScale();
this._internal__clearVisibleRange();
if (timeScale._internal_isEmpty() || priceScale._internal_isEmpty()) {
return;
}
const visibleBars = timeScale._internal_visibleStrictRange();
if (visibleBars === null) {
return;
}
if (this._internal__series._internal_bars()._internal_size() === 0) {
return;
}
const firstValue = this._internal__series._internal_firstValue();
if (firstValue === null) {
return;
}
this._internal__itemsVisibleRange = visibleTimedValues(this._internal__items, visibleBars, this._private__extendedVisibleRange);
this._internal__convertToCoordinates(priceScale, timeScale, firstValue._internal_value);
this._internal__prepareRendererData();
}
};
var LinePaneViewBase = class extends SeriesPaneViewBase {
constructor(series, model) {
super(series, model, true);
}
_internal__convertToCoordinates(priceScale, timeScale, firstValue) {
timeScale._internal_indexesToCoordinates(this._internal__items, undefinedIfNull(this._internal__itemsVisibleRange));
priceScale._internal_pointsArrayToCoordinates(this._internal__items, firstValue, undefinedIfNull(this._internal__itemsVisibleRange));
}
_internal__createRawItemBase(time, price) {
return {
_internal_time: time,
_internal_price: price,
_internal_x: NaN,
_internal_y: NaN
};
}
_internal__fillRawPoints() {
const colorer = this._internal__series._internal_barColorer();
this._internal__items = this._internal__series._internal_bars()._internal_rows().map((row) => {
const value = row._internal_value[
3
/* PlotRowValueIndex.Close */
];
return this._internal__createRawItem(row._internal_index, value, colorer);
});
}
};
var SeriesAreaPaneView = class extends LinePaneViewBase {
constructor(series, model) {
super(series, model);
this._internal__renderer = new CompositeRenderer();
this._private__areaRenderer = new PaneRendererArea();
this._private__lineRenderer = new PaneRendererLine();
this._internal__renderer._internal_setRenderers([this._private__areaRenderer, this._private__lineRenderer]);
}
_internal__createRawItem(time, price, colorer) {
return Object.assign(Object.assign({}, this._internal__createRawItemBase(time, price)), colorer._internal_barStyle(time));
}
_internal__prepareRendererData() {
const options = this._internal__series._internal_options();
this._private__areaRenderer._internal_setData({
_internal_lineType: options.lineType,
_internal_items: this._internal__items,
_internal_lineStyle: options.lineStyle,
_internal_lineWidth: options.lineWidth,
_internal_baseLevelCoordinate: null,
_internal_invertFilledArea: options.invertFilledArea,
_internal_visibleRange: this._internal__itemsVisibleRange,
_internal_barWidth: this._internal__model._internal_timeScale()._internal_barSpacing()
});
this._private__lineRenderer._internal_setData({
_internal_lineType: options.lineVisible ? options.lineType : void 0,
_internal_items: this._internal__items,
_internal_lineStyle: options.lineStyle,
_internal_lineWidth: options.lineWidth,
_internal_visibleRange: this._internal__itemsVisibleRange,
_internal_barWidth: this._internal__model._internal_timeScale()._internal_barSpacing(),
_internal_pointMarkersRadius: options.pointMarkersVisible ? options.pointMarkersRadius || options.lineWidth / 2 + 2 : void 0
});
}
};
function optimalBarWidth(barSpacing, pixelRatio) {
return Math.floor(barSpacing * 0.3 * pixelRatio);
}
function optimalCandlestickWidth(barSpacing, pixelRatio) {
const barSpacingSpecialCaseFrom = 2.5;
const barSpacingSpecialCaseTo = 4;
const barSpacingSpecialCaseCoeff = 3;
if (barSpacing >= barSpacingSpecialCaseFrom && barSpacing <= barSpacingSpecialCaseTo) {
return Math.floor(barSpacingSpecialCaseCoeff * pixelRatio);
}
const barSpacingReducingCoeff = 0.2;
const coeff = 1 - barSpacingReducingCoeff * Math.atan(Math.max(barSpacingSpecialCaseTo, barSpacing) - barSpacingSpecialCaseTo) / (Math.PI * 0.5);
const res = Math.floor(barSpacing * coeff * pixelRatio);
const scaledBarSpacing = Math.floor(barSpacing * pixelRatio);
const optimal = Math.min(res, scaledBarSpacing);
return Math.max(Math.floor(pixelRatio), optimal);
}
var PaneRendererBars = class extends BitmapCoordinatesPaneRenderer {
constructor() {
super(...arguments);
this._private__data = null;
this._private__barWidth = 0;
this._private__barLineWidth = 0;
}
_internal_setData(data) {
this._private__data = data;
}
// eslint-disable-next-line complexity
_internal__drawImpl({ context: ctx, horizontalPixelRatio, verticalPixelRatio }) {
if (this._private__data === null || this._private__data._internal_bars.length === 0 || this._private__data._internal_visibleRange === null) {
return;
}
this._private__barWidth = this._private__calcBarWidth(horizontalPixelRatio);
if (this._private__barWidth >= 2) {
const lineWidth = Math.max(1, Math.floor(horizontalPixelRatio));
if (lineWidth % 2 !== this._private__barWidth % 2) {
this._private__barWidth--;
}
}
this._private__barLineWidth = this._private__data._internal_thinBars ? Math.min(this._private__barWidth, Math.floor(horizontalPixelRatio)) : this._private__barWidth;
let prevColor = null;
const drawOpenClose = this._private__barLineWidth <= this._private__barWidth && this._private__data._internal_barSpacing >= Math.floor(1.5 * horizontalPixelRatio);
for (let i = this._private__data._internal_visibleRange.from; i < this._private__data._internal_visibleRange.to; ++i) {
const bar = this._private__data._internal_bars[i];
if (prevColor !== bar._internal_barColor) {
ctx.fillStyle = bar._internal_barColor;
prevColor = bar._internal_barColor;
}
const bodyWidthHalf = Math.floor(this._private__barLineWidth * 0.5);
const bodyCenter = Math.round(bar._internal_x * horizontalPixelRatio);
const bodyLeft = bodyCenter - bodyWidthHalf;
const bodyWidth = this._private__barLineWidth;
const bodyRight = bodyLeft + bodyWidth - 1;
const high = Math.min(bar._internal_highY, bar._internal_lowY);
const low = Math.max(bar._internal_highY, bar._internal_lowY);
const bodyTop = Math.round(high * verticalPixelRatio) - bodyWidthHalf;
const bodyBottom = Math.round(low * verticalPixelRatio) + bodyWidthHalf;
const bodyHeight = Math.max(bodyBottom - bodyTop, this._private__barLineWidth);
ctx.fillRect(bodyLeft, bodyTop, bodyWidth, bodyHeight);
const sideWidth = Math.ceil(this._private__barWidth * 1.5);
if (drawOpenClose) {
if (this._private__data._internal_openVisible) {
const openLeft = bodyCenter - sideWidth;
let openTop = Math.max(bodyTop, Math.round(bar._internal_openY * verticalPixelRatio) - bodyWidthHalf);
let openBottom = openTop + bodyWidth - 1;
if (openBottom > bodyTop + bodyHeight - 1) {
openBottom = bodyTop + bodyHeight - 1;
openTop = openBottom - bodyWidth + 1;
}
ctx.fillRect(openLeft, openTop, bodyLeft - openLeft, openBottom - openTop + 1);
}
const closeRight = bodyCenter + sideWidth;
let closeTop = Math.max(bodyTop, Math.round(bar._internal_closeY * verticalPixelRatio) - bodyWidthHalf);
let closeBottom = closeTop + bodyWidth - 1;
if (closeBottom > bodyTop + bodyHeight - 1) {
closeBottom = bodyTop + bodyHeight - 1;
closeTop = closeBottom - bodyWidth + 1;
}
ctx.fillRect(bodyRight + 1, closeTop, closeRight - bodyRight, closeBottom - closeTop + 1);
}
}
}
_private__calcBarWidth(pixelRatio) {
const limit = Math.floor(pixelRatio);
return Math.max(limit, Math.floor(optimalBarWidth(ensureNotNull(this._private__data)._internal_barSpacing, pixelRatio)));
}
};
var BarsPaneViewBase = class extends SeriesPaneViewBase {
constructor(series, model) {
super(series, model, false);
}
_internal__convertToCoordinates(priceScale, timeScale, firstValue) {
timeScale._internal_indexesToCoordinates(this._internal__items, undefinedIfNull(this._internal__itemsVisibleRange));
priceScale._internal_barPricesToCoordinates(this._internal__items, firstValue, undefinedIfNull(this._internal__itemsVisibleRange));
}
_internal__createDefaultItem(time, bar, colorer) {
return {
_internal_time: time,
_internal_open: bar._internal_value[
0
/* PlotRowValueIndex.Open */
],
_internal_high: bar._internal_value[
1
/* PlotRowValueIndex.High */
],
_internal_low: bar._internal_value[
2
/* PlotRowValueIndex.Low */
],
_internal_close: bar._internal_value[
3
/* PlotRowValueIndex.Close */
],
_internal_x: NaN,
_internal_openY: NaN,
_internal_highY: NaN,
_internal_lowY: NaN,
_internal_closeY: NaN
};
}
_internal__fillRawPoints() {
const colorer = this._internal__series._internal_barColorer();
this._internal__items = this._internal__series._internal_bars()._internal_rows().map((row) => this._internal__createRawItem(row._internal_index, row, colorer));
}
};
var SeriesBarsPaneView = class extends BarsPaneViewBase {
constructor() {
super(...arguments);
this._internal__renderer = new PaneRendererBars();
}
_internal__createRawItem(time, bar, colorer) {
return Object.assign(Object.assign({}, this._internal__createDefaultItem(time, bar, colorer)), colorer._internal_barStyle(time));
}
_internal__prepareRendererData() {
const barStyleProps = this._internal__series._internal_options();
this._internal__renderer._internal_setData({
_internal_bars: this._internal__items,
_internal_barSpacing: this._internal__model._internal_timeScale()._internal_barSpacing(),
_internal_openVisible: barStyleProps.openVisible,
_internal_thinBars: barStyleProps.thinBars,
_internal_visibleRange: this._internal__itemsVisibleRange
});
}
};
var PaneRendererBaselineArea = class extends PaneRendererAreaBase {
constructor() {
super(...arguments);
this._private__fillCache = new GradientStyleCache();
}
_internal__fillStyle(renderingScope, item) {
const data = this._internal__data;
return this._private__fillCache._internal_get(renderingScope, {
_internal_topColor1: item._internal_topFillColor1,
_internal_topColor2: item._internal_topFillColor2,
_internal_bottomColor1: item._internal_bottomFillColor1,
_internal_bottomColor2: item._internal_bottomFillColor2,
_internal_bottom: renderingScope.bitmapSize.height,
_internal_baseLevelCoordinate: data._internal_baseLevelCoordinate
});
}
};
var PaneRendererBaselineLine = class extends PaneRendererLineBase {
constructor() {
super(...arguments);
this._private__strokeCache = new GradientStyleCache();
}
_internal__strokeStyle(renderingScope, item) {
const data = this._internal__data;
return this._private__strokeCache._internal_get(renderingScope, {
_internal_topColor1: item._internal_topLineColor,
_internal_topColor2: item._internal_topLineColor,
_internal_bottomColor1: item._internal_bottomLineColor,
_internal_bottomColor2: item._internal_bottomLineColor,
_internal_bottom: renderingScope.bitmapSize.height,
_internal_baseLevelCoordinate: data._internal_baseLevelCoordinate
});
}
};
var SeriesBaselinePaneView = class extends LinePaneViewBase {
constructor(series, model) {
super(series, model);
this._internal__renderer = new CompositeRenderer();
this._private__baselineAreaRenderer = new PaneRendererBaselineArea();
this._private__baselineLineRenderer = new PaneRendererBaselineLine();
this._internal__renderer._internal_setRenderers([this._private__baselineAreaRenderer, this._private__baselineLineRenderer]);
}
_internal__createRawItem(time, price, colorer) {
return Object.assign(Object.assign({}, this._internal__createRawItemBase(time, price)), colorer._internal_barStyle(time));
}
_internal__prepareRendererData() {
const firstValue = this._internal__series._internal_firstValue();
if (firstValue === null) {
return;
}
const options = this._internal__series._internal_options();
const baseLevelCoordinate = this._internal__series._internal_priceScale()._internal_priceToCoordinate(options.baseValue.price, firstValue._internal_value);
const barWidth = this._internal__model._internal_timeScale()._internal_barSpacing();
this._private__baselineAreaRenderer._internal_setData({
_internal_items: this._internal__items,
_internal_lineWidth: options.lineWidth,
_internal_lineStyle: options.lineStyle,
_internal_lineType: options.lineType,
_internal_baseLevelCoordinate: baseLevelCoordinate,
_internal_invertFilledArea: false,
_internal_visibleRange: this._internal__itemsVisibleRange,
_internal_barWidth: barWidth
});
this._private__baselineLineRenderer._internal_setData({
_internal_items: this._internal__items,
_internal_lineWidth: options.lineWidth,
_internal_lineStyle: options.lineStyle,
_internal_lineType: options.lineVisible ? options.lineType : void 0,
_internal_pointMarkersRadius: options.pointMarkersVisible ? options.pointMarkersRadius || options.lineWidth / 2 + 2 : void 0,
_internal_baseLevelCoordinate: baseLevelCoordinate,
_internal_visibleRange: this._internal__itemsVisibleRange,
_internal_barWidth: barWidth
});
}
};
var PaneRendererCandlesticks = class extends BitmapCoordinatesPaneRenderer {
constructor() {
super(...arguments);
this._private__data = null;
this._private__barWidth = 0;
}
_internal_setData(data) {
this._private__data = data;
}
_internal__drawImpl(renderingScope) {
if (this._private__data === null || this._private__data._internal_bars.length === 0 || this._private__data._internal_visibleRange === null) {
return;
}
const { horizontalPixelRatio } = renderingScope;
this._private__barWidth = optimalCandlestickWidth(this._private__data._internal_barSpacing, horizontalPixelRatio);
if (this._private__barWidth >= 2) {
const wickWidth = Math.floor(horizontalPixelRatio);
if (wickWidth % 2 !== this._private__barWidth % 2) {
this._private__barWidth--;
}
}
const bars = this._private__data._internal_bars;
if (this._private__data._internal_wickVisible) {
this._private__drawWicks(renderingScope, bars, this._private__data._internal_visibleRange);
}
if (this._private__data._internal_borderVisible) {
this._private__drawBorder(renderingScope, bars, this._private__data._internal_visibleRange);
}
const borderWidth = this._private__calculateBorderWidth(horizontalPixelRatio);
if (!this._private__data._internal_borderVisible || this._private__barWidth > borderWidth * 2) {
this._private__drawCandles(renderingScope, bars, this._private__data._internal_visibleRange);
}
}
_private__drawWicks(renderingScope, bars, visibleRange) {
if (this._private__data === null) {
return;
}
const { context: ctx, horizontalPixelRatio, verticalPixelRatio } = renderingScope;
let prevWickColor = "";
let wickWidth = Math.min(Math.floor(horizontalPixelRatio), Math.floor(this._private__data._internal_barSpacing * horizontalPixelRatio));
wickWidth = Math.max(Math.floor(horizontalPixelRatio), Math.min(wickWidth, this._private__barWidth));
const wickOffset = Math.floor(wickWidth * 0.5);
let prevEdge = null;
for (let i = visibleRange.from; i < visibleRange.to; i++) {
const bar = bars[i];
if (bar._internal_barWickColor !== prevWickColor) {
ctx.fillStyle = bar._internal_barWickColor;
prevWickColor = bar._internal_barWickColor;
}
const top = Math.round(Math.min(bar._internal_openY, bar._internal_closeY) * verticalPixelRatio);
const bottom = Math.round(Math.max(bar._internal_openY, bar._internal_closeY) * verticalPixelRatio);
const high = Math.round(bar._internal_highY * verticalPixelRatio);
const low = Math.round(bar._internal_lowY * verticalPixelRatio);
const scaledX = Math.round(horizontalPixelRatio * bar._internal_x);
let left = scaledX - wickOffset;
const right = left + wickWidth - 1;
if (prevEdge !== null) {
left = Math.max(prevEdge + 1, left);
left = Math.min(left, right);
}
const width = right - left + 1;
ctx.fillRect(left, high, width, top - high);
ctx.fillRect(left, bottom + 1, width, low - bottom);
prevEdge = right;
}
}
_private__calculateBorderWidth(pixelRatio) {
let borderWidth = Math.floor(1 * pixelRatio);
if (this._private__barWidth <= 2 * borderWidth) {
borderWidth = Math.floor((this._private__barWidth - 1) * 0.5);
}
const res = Math.max(Math.floor(pixelRatio), borderWidth);
if (this._private__barWidth <= res * 2) {
return Math.max(Math.floor(pixelRatio), Math.floor(1 * pixelRatio));
}
return res;
}
_private__drawBorder(renderingScope, bars, visibleRange) {
if (this._private__data === null) {
return;
}
const { context: ctx, horizontalPixelRatio, verticalPixelRatio } = renderingScope;
let prevBorderColor = "";
const borderWidth = this._private__calculateBorderWidth(horizontalPixelRatio);
let prevEdge = null;
for (let i = visibleRange.from; i < visibleRange.to; i++) {
const bar = bars[i];
if (bar._internal_barBorderColor !== prevBorderColor) {
ctx.fillStyle = bar._internal_barBorderColor;
prevBorderColor = bar._internal_barBorderColor;
}
let left = Math.round(bar._internal_x * horizontalPixelRatio) - Math.floor(this._private__barWidth * 0.5);
const right = left + this._private__barWidth - 1;
const top = Math.round(Math.min(bar._internal_openY, bar._internal_closeY) * verticalPixelRatio);
const bottom = Math.round(Math.max(bar._internal_openY, bar._internal_closeY) * verticalPixelRatio);
if (prevEdge !== null) {
left = Math.max(prevEdge + 1, left);
left = Math.min(left, right);
}
if (this._private__data._internal_barSpacing * horizontalPixelRatio > 2 * borderWidth) {
fillRectInnerBorder(ctx, left, top, right - left + 1, bottom - top + 1, borderWidth);
} else {
const width = right - left + 1;
ctx.fillRect(left, top, width, bottom - top + 1);
}
prevEdge = right;
}
}
_private__drawCandles(renderingScope, bars, visibleRange) {
if (this._private__data === null) {
return;
}
const { context: ctx, horizontalPixelRatio, verticalPixelRatio } = renderingScope;
let prevBarColor = "";
const borderWidth = this._private__calculateBorderWidth(horizontalPixelRatio);
for (let i = visibleRange.from; i < visibleRange.to; i++) {
const bar = bars[i];
let top = Math.round(Math.min(bar._internal_openY, bar._internal_closeY) * verticalPixelRatio);
let bottom = Math.round(Math.max(bar._internal_openY, bar._internal_closeY) * verticalPixelRatio);
let left = Math.round(bar._internal_x * horizontalPixelRatio) - Math.floor(this._private__barWidth * 0.5);
let right = left + this._private__barWidth - 1;
if (bar._internal_barColor !== prevBarColor) {
const barColor = bar._internal_barColor;
ctx.fillStyle = barColor;
prevBarColor = barColor;
}
if (this._private__data._internal_borderVisible) {
left += borderWidth;
top += borderWidth;
right -= borderWidth;
bottom -= borderWidth;
}
if (top > bottom) {
continue;
}
ctx.fillRect(left, top, right - left + 1, bottom - top + 1);
}
}
};
var SeriesCandlesticksPaneView = class extends BarsPaneViewBase {
constructor() {
super(...arguments);
this._internal__renderer = new PaneRendererCandlesticks();
}
_internal__createRawItem(time, bar, colorer) {
return Object.assign(Object.assign({}, this._internal__createDefaultItem(time, bar, colorer)), colorer._internal_barStyle(time));
}
_internal__prepareRendererData() {
const candlestickStyleProps = this._internal__series._internal_options();
this._internal__renderer._internal_setData({
_internal_bars: this._internal__items,
_internal_barSpacing: this._internal__model._internal_timeScale()._internal_barSpacing(),
_internal_wickVisible: candlestickStyleProps.wickVisible,
_internal_borderVisible: candlestickStyleProps.borderVisible,
_internal_visibleRange: this._internal__itemsVisibleRange
});
}
};
var CustomSeriesPaneRendererWrapper = class {
constructor(sourceRenderer, priceScale) {
this._private__sourceRenderer = sourceRenderer;
this._private__priceScale = priceScale;
}
_internal_draw(target, isHovered, hitTestData) {
this._private__sourceRenderer.draw(target, this._private__priceScale, isHovered, hitTestData);
}
};
var SeriesCustomPaneView = class extends SeriesPaneViewBase {
constructor(series, model, paneView) {
super(series, model, false);
this._private__paneView = paneView;
this._internal__renderer = new CustomSeriesPaneRendererWrapper(this._private__paneView.renderer(), (price) => {
const firstValue = series._internal_firstValue();
if (firstValue === null) {
return null;
}
return series._internal_priceScale()._internal_priceToCoordinate(price, firstValue._internal_value);
});
}
_internal_priceValueBuilder(plotRow) {
return this._private__paneView.priceValueBuilder(plotRow);
}
_internal_isWhitespace(data) {
return this._private__paneView.isWhitespace(data);
}
_internal__fillRawPoints() {
const colorer = this._internal__series._internal_barColorer();
this._internal__items = this._internal__series._internal_bars()._internal_rows().map((row) => {
return Object.assign(Object.assign({ _internal_time: row._internal_index, _internal_x: NaN }, colorer._internal_barStyle(row._internal_index)), { _internal_originalData: row._internal_data });
});
}
_internal__convertToCoordinates(priceScale, timeScale) {
timeScale._internal_indexesToCoordinates(this._internal__items, undefinedIfNull(this._internal__itemsVisibleRange));
}
_internal__prepareRendererData() {
this._private__paneView.update({
bars: this._internal__items.map(unwrapItemData),
barSpacing: this._internal__model._internal_timeScale()._internal_barSpacing(),
visibleRange: this._internal__itemsVisibleRange
}, this._internal__series._internal_options());
}
};
function unwrapItemData(item) {
return {
x: item._internal_x,
time: item._internal_time,
originalData: item._internal_originalData,
barColor: item._internal_barColor
};
}
var showSpacingMinimalBarWidth = 1;
var alignToMinimalWidthLimit = 4;
var PaneRendererHistogram = class extends BitmapCoordinatesPaneRenderer {
constructor() {
super(...arguments);
this._private__data = null;
this._private__precalculatedCache = [];
}
_internal_setData(data) {
this._private__data = data;
this._private__precalculatedCache = [];
}
_internal__drawImpl({ context: ctx, horizontalPixelRatio, verticalPixelRatio }) {
if (this._private__data === null || this._private__data._internal_items.length === 0 || this._private__data._internal_visibleRange === null) {
return;
}
if (!this._private__precalculatedCache.length) {
this._private__fillPrecalculatedCache(horizontalPixelRatio);
}
const tickWidth = Math.max(1, Math.floor(verticalPixelRatio));
const histogramBase = Math.round(this._private__data._internal_histogramBase * verticalPixelRatio);
const topHistogramBase = histogramBase - Math.floor(tickWidth / 2);
const bottomHistogramBase = topHistogramBase + tickWidth;
for (let i = this._private__data._internal_visibleRange.from; i < this._private__data._internal_visibleRange.to; i++) {
const item = this._private__data._internal_items[i];
const current = this._private__precalculatedCache[i - this._private__data._internal_visibleRange.from];
const y = Math.round(item._internal_y * verticalPixelRatio);
ctx.fillStyle = item._internal_barColor;
let top;
let bottom;
if (y <= topHistogramBase) {
top = y;
bottom = bottomHistogramBase;
} else {
top = topHistogramBase;
bottom = y - Math.floor(tickWidth / 2) + tickWidth;
}
ctx.fillRect(current._internal_left, top, current._internal_right - current._internal_left + 1, bottom - top);
}
}
// eslint-disable-next-line complexity
_private__fillPrecalculatedCache(pixelRatio) {
if (this._private__data === null || this._private__data._internal_items.length === 0 || this._private__data._internal_visibleRange === null) {
this._private__precalculatedCache = [];
return;
}
const spacing = Math.ceil(this._private__data._internal_barSpacing * pixelRatio) <= showSpacingMinimalBarWidth ? 0 : Math.max(1, Math.floor(pixelRatio));
const columnWidth = Math.round(this._private__data._internal_barSpacing * pixelRatio) - spacing;
this._private__precalculatedCache = new Array(this._private__data._internal_visibleRange.to - this._private__data._internal_visibleRange.from);
for (let i = this._private__data._internal_visibleRange.from; i < this._private__data._internal_visibleRange.to; i++) {
const item = this._private__data._internal_items[i];
const x = Math.round(item._internal_x * pixelRatio);
let left;
let right;
if (columnWidth % 2) {
const halfWidth = (columnWidth - 1) / 2;
left = x - halfWidth;
right = x + halfWidth;
} else {
const halfWidth = columnWidth / 2;
left = x - halfWidth;
right = x + halfWidth - 1;
}
this._private__precalculatedCache[i - this._private__data._internal_visibleRange.from] = {
_internal_left: left,
_internal_right: right,
_internal_roundedCenter: x,
_internal_center: item._internal_x * pixelRatio,
_internal_time: item._internal_time
};
}
for (let i = this._private__data._internal_visibleRange.from + 1; i < this._private__data._internal_visibleRange.to; i++) {
const current = this._private__precalculatedCache[i - this._private__data._internal_visibleRange.from];
const prev = this._private__precalculatedCache[i - this._private__data._internal_visibleRange.from - 1];
if (current._internal_time !== prev._internal_time + 1) {
continue;
}
if (current._internal_left - prev._internal_right !== spacing + 1) {
if (prev._internal_roundedCenter > prev._internal_center) {
prev._internal_right = current._internal_left - spacing - 1;
} else {
current._internal_left = prev._internal_right + spacing + 1;
}
}
}
let minWidth = Math.ceil(this._private__data._internal_barSpacing * pixelRatio);
for (let i = this._private__data._internal_visibleRange.from; i < this._private__data._internal_visibleRange.to; i++) {
const current = this._private__precalculatedCache[i - this._private__data._internal_visibleRange.from];
if (current._internal_right < current._internal_left) {
current._internal_right = current._internal_left;
}
const width = current._internal_right - current._internal_left + 1;
minWidth = Math.min(width, minWidth);
}
if (spacing > 0 && minWidth < alignToMinimalWidthLimit) {
for (let i = this._private__data._internal_visibleRange.from; i < this._private__data._internal_visibleRange.to; i++) {
const current = this._private__precalculatedCache[i - this._private__data._internal_visibleRange.from];
const width = current._internal_right - current._internal_left + 1;
if (width > minWidth) {
if (current._internal_roundedCenter > current._internal_center) {
current._internal_right -= 1;
} else {
current._internal_left += 1;
}
}
}
}
}
};
var SeriesHistogramPaneView = class extends LinePaneViewBase {
constructor() {
super(...arguments);
this._internal__renderer = new PaneRendererHistogram();
}
_internal__createRawItem(time, price, colorer) {
return Object.assign(Object.assign({}, this._internal__createRawItemBase(time, price)), colorer._internal_barStyle(time));
}
_internal__prepareRendererData() {
const data = {
_internal_items: this._internal__items,
_internal_barSpacing: this._internal__model._internal_timeScale()._internal_barSpacing(),
_internal_visibleRange: this._internal__itemsVisibleRange,
_internal_histogramBase: this._internal__series._internal_priceScale()._internal_priceToCoordinate(this._internal__series._internal_options().base, ensureNotNull(this._internal__series._internal_firstValue())._internal_value)
};
this._internal__renderer._internal_setData(data);
}
};
var SeriesLinePaneView = class extends LinePaneViewBase {
constructor() {
super(...arguments);
this._internal__renderer = new PaneRendererLine();
}
_internal__createRawItem(time, price, colorer) {
return Object.assign(Object.assign({}, this._internal__createRawItemBase(time, price)), colorer._internal_barStyle(time));
}
_internal__prepareRendererData() {
const options = this._internal__series._internal_options();
const data = {
_internal_items: this._internal__items,
_internal_lineStyle: options.lineStyle,
_internal_lineType: options.lineVisible ? options.lineType : void 0,
_internal_lineWidth: options.lineWidth,
_internal_pointMarkersRadius: options.pointMarkersVisible ? options.pointMarkersRadius || options.lineWidth / 2 + 2 : void 0,
_internal_visibleRange: this._internal__itemsVisibleRange,
_internal_barWidth: this._internal__model._internal_timeScale()._internal_barSpacing()
};
this._internal__renderer._internal_setData(data);
}
};
var defaultReplacementRe = /[2-9]/g;
var TextWidthCache = class {
constructor(size3 = 50) {
this._private__actualSize = 0;
this._private__usageTick = 1;
this._private__oldestTick = 1;
this._private__tick2Labels = {};
this._private__cache = /* @__PURE__ */ new Map();
this._private__maxSize = size3;
}
_internal_reset() {
this._private__actualSize = 0;
this._private__cache.clear();
this._private__usageTick = 1;
this._private__oldestTick = 1;
this._private__tick2Labels = {};
}
_internal_measureText(ctx, text, optimizationReplacementRe2) {
return this._private__getMetrics(ctx, text, optimizationReplacementRe2).width;
}
_internal_yMidCorrection(ctx, text, optimizationReplacementRe2) {
const metrics = this._private__getMetrics(ctx, text, optimizationReplacementRe2);
return ((metrics.actualBoundingBoxAscent || 0) - (metrics.actualBoundingBoxDescent || 0)) / 2;
}
_private__getMetrics(ctx, text, optimizationReplacementRe2) {
const re = optimizationReplacementRe2 || defaultReplacementRe;
const cacheString = String(text).replace(re, "0");
if (this._private__cache.has(cacheString)) {
return ensureDefined(this._private__cache.get(cacheString))._internal_metrics;
}
if (this._private__actualSize === this._private__maxSize) {
const oldestValue = this._private__tick2Labels[this._private__oldestTick];
delete this._private__tick2Labels[this._private__oldestTick];
this._private__cache.delete(oldestValue);
this._private__oldestTick++;
this._private__actualSize--;
}
ctx.save();
ctx.textBaseline = "middle";
const metrics = ctx.measureText(cacheString);
ctx.restore();
if (metrics.width === 0 && !!text.length) {
return metrics;
}
this._private__cache.set(cacheString, { _internal_metrics: metrics, _internal_tick: this._private__usageTick });
this._private__tick2Labels[this._private__usageTick] = cacheString;
this._private__actualSize++;
this._private__usageTick++;
return metrics;
}
};
var PanePriceAxisViewRenderer = class {
constructor(textWidthCache) {
this._private__priceAxisViewRenderer = null;
this._private__rendererOptions = null;
this._private__align = "right";
this._private__textWidthCache = textWidthCache;
}
_internal_setParams(priceAxisViewRenderer, rendererOptions, align) {
this._private__priceAxisViewRenderer = priceAxisViewRenderer;
this._private__rendererOptions = rendererOptions;
this._private__align = align;
}
_internal_draw(target) {
if (this._private__rendererOptions === null || this._private__priceAxisViewRenderer === null) {
return;
}
this._private__priceAxisViewRenderer._internal_draw(target, this._private__rendererOptions, this._private__textWidthCache, this._private__align);
}
};
var PanePriceAxisView = class {
constructor(priceAxisView, dataSource, chartModel) {
this._private__priceAxisView = priceAxisView;
this._private__textWidthCache = new TextWidthCache(50);
this._private__dataSource = dataSource;
this._private__chartModel = chartModel;
this._private__fontSize = -1;
this._private__renderer = new PanePriceAxisViewRenderer(this._private__textWidthCache);
}
_internal_renderer() {
const pane = this._private__chartModel._internal_paneForSource(this._private__dataSource);
if (pane === null) {
return null;
}
const priceScale = pane._internal_isOverlay(this._private__dataSource) ? pane._internal_defaultVisiblePriceScale() : this._private__dataSource._internal_priceScale();
if (priceScale === null) {
return null;
}
const position = pane._internal_priceScalePosition(priceScale);
if (position === "overlay") {
return null;
}
const options = this._private__chartModel._internal_priceAxisRendererOptions();
if (options._internal_fontSize !== this._private__fontSize) {
this._private__fontSize = options._internal_fontSize;
this._private__textWidthCache._internal_reset();
}
this._private__renderer._internal_setParams(this._private__priceAxisView._internal_paneRenderer(), options, position);
return this._private__renderer;
}
};
var HorizontalLineRenderer = class extends BitmapCoordinatesPaneRenderer {
constructor() {
super(...arguments);
this._private__data = null;
}
_internal_setData(data) {
this._private__data = data;
}
_internal_hitTest(x, y) {
var _a;
if (!((_a = this._private__data) === null || _a === void 0 ? void 0 : _a._internal_visible)) {
return null;
}
const { _internal_y: itemY, _internal_lineWidth: lineWidth, _internal_externalId: externalId } = this._private__data;
if (y >= itemY - lineWidth - 7 && y <= itemY + lineWidth + 7) {
return {
_internal_hitTestData: this._private__data,
_internal_externalId: externalId
};
}
return null;
}
_internal__drawImpl({ context: ctx, bitmapSize, horizontalPixelRatio, verticalPixelRatio }) {
if (this._private__data === null) {
return;
}
if (this._private__data._internal_visible === false) {
return;
}
const y = Math.round(this._private__data._internal_y * verticalPixelRatio);
if (y < 0 || y > bitmapSize.height) {
return;
}
ctx.lineCap = "butt";
ctx.strokeStyle = this._private__data._internal_color;
ctx.lineWidth = Math.floor(this._private__data._internal_lineWidth * horizontalPixelRatio);
setLineStyle(ctx, this._private__data._internal_lineStyle);
drawHorizontalLine(ctx, y, 0, bitmapSize.width);
}
};
var SeriesHorizontalLinePaneView = class {
constructor(series) {
this._internal__lineRendererData = {
_internal_y: 0,
_internal_color: "rgba(0, 0, 0, 0)",
_internal_lineWidth: 1,
_internal_lineStyle: 0,
_internal_visible: false
};
this._internal__lineRenderer = new HorizontalLineRenderer();
this._private__invalidated = true;
this._internal__series = series;
this._internal__model = series._internal_model();
this._internal__lineRenderer._internal_setData(this._internal__lineRendererData);
}
_internal_update() {
this._private__invalidated = true;
}
_internal_renderer() {
if (!this._internal__series._internal_visible()) {
return null;
}
if (this._private__invalidated) {
this._internal__updateImpl();
this._private__invalidated = false;
}
return this._internal__lineRenderer;
}
};
var SeriesHorizontalBaseLinePaneView = class extends SeriesHorizontalLinePaneView {
// eslint-disable-next-line no-useless-constructor
constructor(series) {
super(series);
}
_internal__updateImpl() {
this._internal__lineRendererData._internal_visible = false;
const priceScale = this._internal__series._internal_priceScale();
const mode = priceScale._internal_mode()._internal_mode;
if (mode !== 2 && mode !== 3) {
return;
}
const seriesOptions = this._internal__series._internal_options();
if (!seriesOptions.baseLineVisible || !this._internal__series._internal_visible()) {
return;
}
const firstValue = this._internal__series._internal_firstValue();
if (firstValue === null) {
return;
}
this._internal__lineRendererData._internal_visible = true;
this._internal__lineRendererData._internal_y = priceScale._internal_priceToCoordinate(firstValue._internal_value, firstValue._internal_value);
this._internal__lineRendererData._internal_color = seriesOptions.baseLineColor;
this._internal__lineRendererData._internal_lineWidth = seriesOptions.baseLineWidth;
this._internal__lineRendererData._internal_lineStyle = seriesOptions.baseLineStyle;
}
};
var SeriesLastPriceAnimationRenderer = class extends BitmapCoordinatesPaneRenderer {
constructor() {
super(...arguments);
this._private__data = null;
}
_internal_setData(data) {
this._private__data = data;
}
_internal_data() {
return this._private__data;
}
_internal__drawImpl({ context: ctx, horizontalPixelRatio, verticalPixelRatio }) {
const data = this._private__data;
if (data === null) {
return;
}
const tickWidth = Math.max(1, Math.floor(horizontalPixelRatio));
const correction = tickWidth % 2 / 2;
const centerX = Math.round(data._internal_center.x * horizontalPixelRatio) + correction;
const centerY = data._internal_center.y * verticalPixelRatio;
ctx.fillStyle = data._internal_seriesLineColor;
ctx.beginPath();
const centerPointRadius = Math.max(2, data._internal_seriesLineWidth * 1.5) * horizontalPixelRatio;
ctx.arc(centerX, centerY, centerPointRadius, 0, 2 * Math.PI, false);
ctx.fill();
ctx.fillStyle = data._internal_fillColor;
ctx.beginPath();
ctx.arc(centerX, centerY, data._internal_radius * horizontalPixelRatio, 0, 2 * Math.PI, false);
ctx.fill();
ctx.lineWidth = tickWidth;
ctx.strokeStyle = data._internal_strokeColor;
ctx.beginPath();
ctx.arc(centerX, centerY, data._internal_radius * horizontalPixelRatio + tickWidth / 2, 0, 2 * Math.PI, false);
ctx.stroke();
}
};
var animationStagesData = [
{
_internal_start: 0,
_internal_end: 0.25,
_internal_startRadius: 4,
_internal_endRadius: 10,
_internal_startFillAlpha: 0.25,
_internal_endFillAlpha: 0,
_internal_startStrokeAlpha: 0.4,
_internal_endStrokeAlpha: 0.8
},
{
_internal_start: 0.25,
_internal_end: 0.25 + 0.275,
_internal_startRadius: 10,
_internal_endRadius: 14,
_internal_startFillAlpha: 0,
_internal_endFillAlpha: 0,
_internal_startStrokeAlpha: 0.8,
_internal_endStrokeAlpha: 0
},
{
_internal_start: 0.25 + 0.275,
_internal_end: 0.25 + 0.275 + 0.475,
_internal_startRadius: 14,
_internal_endRadius: 14,
_internal_startFillAlpha: 0,
_internal_endFillAlpha: 0,
_internal_startStrokeAlpha: 0,
_internal_endStrokeAlpha: 0
}
];
function color(seriesLineColor, stage, startAlpha, endAlpha) {
const alpha = startAlpha + (endAlpha - startAlpha) * stage;
return applyAlpha(seriesLineColor, alpha);
}
function radius(stage, startRadius, endRadius) {
return startRadius + (endRadius - startRadius) * stage;
}
function animationData(durationSinceStart, lineColor) {
const globalStage = durationSinceStart % 2600 / 2600;
let currentStageData;
for (const stageData of animationStagesData) {
if (globalStage >= stageData._internal_start && globalStage <= stageData._internal_end) {
currentStageData = stageData;
break;
}
}
assert(currentStageData !== void 0, "Last price animation internal logic error");
const subStage = (globalStage - currentStageData._internal_start) / (currentStageData._internal_end - currentStageData._internal_start);
return {
_internal_fillColor: color(lineColor, subStage, currentStageData._internal_startFillAlpha, currentStageData._internal_endFillAlpha),
_internal_strokeColor: color(lineColor, subStage, currentStageData._internal_startStrokeAlpha, currentStageData._internal_endStrokeAlpha),
_internal_radius: radius(subStage, currentStageData._internal_startRadius, currentStageData._internal_endRadius)
};
}
var SeriesLastPriceAnimationPaneView = class {
constructor(series) {
this._private__renderer = new SeriesLastPriceAnimationRenderer();
this._private__invalidated = true;
this._private__stageInvalidated = true;
this._private__startTime = performance.now();
this._private__endTime = this._private__startTime - 1;
this._private__series = series;
}
_internal_onDataCleared() {
this._private__endTime = this._private__startTime - 1;
this._internal_update();
}
_internal_onNewRealtimeDataReceived() {
this._internal_update();
if (this._private__series._internal_options().lastPriceAnimation === 2) {
const now = performance.now();
const timeToAnimationEnd = this._private__endTime - now;
if (timeToAnimationEnd > 0) {
if (timeToAnimationEnd < 2600 / 4) {
this._private__endTime += 2600;
}
return;
}
this._private__startTime = now;
this._private__endTime = now + 2600;
}
}
_internal_update() {
this._private__invalidated = true;
}
_internal_invalidateStage() {
this._private__stageInvalidated = true;
}
_internal_visible() {
return this._private__series._internal_options().lastPriceAnimation !== 0;
}
_internal_animationActive() {
switch (this._private__series._internal_options().lastPriceAnimation) {
case 0:
return false;
case 1:
return true;
case 2:
return performance.now() <= this._private__endTime;
}
}
_internal_renderer() {
if (this._private__invalidated) {
this._private__updateImpl();
this._private__invalidated = false;
this._private__stageInvalidated = false;
} else if (this._private__stageInvalidated) {
this._private__updateRendererDataStage();
this._private__stageInvalidated = false;
}
return this._private__renderer;
}
_private__updateImpl() {
this._private__renderer._internal_setData(null);
const timeScale = this._private__series._internal_model()._internal_timeScale();
const visibleRange = timeScale._internal_visibleStrictRange();
const firstValue = this._private__series._internal_firstValue();
if (visibleRange === null || firstValue === null) {
return;
}
const lastValue = this._private__series._internal_lastValueData(true);
if (lastValue._internal_noData || !visibleRange._internal_contains(lastValue._internal_index)) {
return;
}
const lastValuePoint = {
x: timeScale._internal_indexToCoordinate(lastValue._internal_index),
y: this._private__series._internal_priceScale()._internal_priceToCoordinate(lastValue._internal_price, firstValue._internal_value)
};
const seriesLineColor = lastValue._internal_color;
const seriesLineWidth = this._private__series._internal_options().lineWidth;
const data = animationData(this._private__duration(), seriesLineColor);
this._private__renderer._internal_setData({
_internal_seriesLineColor: seriesLineColor,
_internal_seriesLineWidth: seriesLineWidth,
_internal_fillColor: data._internal_fillColor,
_internal_strokeColor: data._internal_strokeColor,
_internal_radius: data._internal_radius,
_internal_center: lastValuePoint
});
}
_private__updateRendererDataStage() {
const rendererData = this._private__renderer._internal_data();
if (rendererData !== null) {
const data = animationData(this._private__duration(), rendererData._internal_seriesLineColor);
rendererData._internal_fillColor = data._internal_fillColor;
rendererData._internal_strokeColor = data._internal_strokeColor;
rendererData._internal_radius = data._internal_radius;
}
}
_private__duration() {
return this._internal_animationActive() ? performance.now() - this._private__startTime : 2600 - 1;
}
};
function size2(barSpacing, coeff) {
const result = Math.min(
Math.max(
barSpacing,
12
/* Constants.MinShapeSize */
),
30
/* Constants.MaxShapeSize */
) * coeff;
return ceiledOdd(result);
}
function shapeSize(shape, originalSize) {
switch (shape) {
case "arrowDown":
case "arrowUp":
return size2(originalSize, 1);
case "circle":
return size2(originalSize, 0.8);
case "square":
return size2(originalSize, 0.7);
}
}
function calculateShapeHeight(barSpacing) {
return ceiledEven(size2(barSpacing, 1));
}
function shapeMargin(barSpacing) {
return Math.max(
size2(barSpacing, 0.1),
3
/* Constants.MinShapeMargin */
);
}
function calculateAdjustedMargin(margin, hasSide, hasInBar) {
if (hasSide) {
return margin;
} else if (hasInBar) {
return Math.ceil(margin / 2);
}
return 0;
}
function drawSquare(ctx, coords, size3) {
const squareSize = shapeSize("square", size3);
const halfSize = (squareSize - 1) * coords._internal_pixelRatio / 2;
const left = coords._internal_x - halfSize;
const top = coords._internal_y - halfSize;
ctx.fillRect(left, top, squareSize * coords._internal_pixelRatio, squareSize * coords._internal_pixelRatio);
}
function hitTestSquare(centerX, centerY, size3, x, y) {
const squareSize = shapeSize("square", size3);
const halfSize = (squareSize - 1) / 2;
const left = centerX - halfSize;
const top = centerY - halfSize;
return x >= left && x <= left + squareSize && y >= top && y <= top + squareSize;
}
function drawArrow(up, ctx, coords, size3) {
const arrowSize = shapeSize("arrowUp", size3);
const halfArrowSize = (arrowSize - 1) / 2 * coords._internal_pixelRatio;
const baseSize = ceiledOdd(size3 / 2);
const halfBaseSize = (baseSize - 1) / 2 * coords._internal_pixelRatio;
ctx.beginPath();
if (up) {
ctx.moveTo(coords._internal_x - halfArrowSize, coords._internal_y);
ctx.lineTo(coords._internal_x, coords._internal_y - halfArrowSize);
ctx.lineTo(coords._internal_x + halfArrowSize, coords._internal_y);
ctx.lineTo(coords._internal_x + halfBaseSize, coords._internal_y);
ctx.lineTo(coords._internal_x + halfBaseSize, coords._internal_y + halfArrowSize);
ctx.lineTo(coords._internal_x - halfBaseSize, coords._internal_y + halfArrowSize);
ctx.lineTo(coords._internal_x - halfBaseSize, coords._internal_y);
} else {
ctx.moveTo(coords._internal_x - halfArrowSize, coords._internal_y);
ctx.lineTo(coords._internal_x, coords._internal_y + halfArrowSize);
ctx.lineTo(coords._internal_x + halfArrowSize, coords._internal_y);
ctx.lineTo(coords._internal_x + halfBaseSize, coords._internal_y);
ctx.lineTo(coords._internal_x + halfBaseSize, coords._internal_y - halfArrowSize);
ctx.lineTo(coords._internal_x - halfBaseSize, coords._internal_y - halfArrowSize);
ctx.lineTo(coords._internal_x - halfBaseSize, coords._internal_y);
}
ctx.fill();
}
function hitTestArrow(up, centerX, centerY, size3, x, y) {
return hitTestSquare(centerX, centerY, size3, x, y);
}
function drawCircle(ctx, coords, size3) {
const circleSize = shapeSize("circle", size3);
const halfSize = (circleSize - 1) / 2;
ctx.beginPath();
ctx.arc(coords._internal_x, coords._internal_y, halfSize * coords._internal_pixelRatio, 0, 2 * Math.PI, false);
ctx.fill();
}
function hitTestCircle(centerX, centerY, size3, x, y) {
const circleSize = shapeSize("circle", size3);
const tolerance = 2 + circleSize / 2;
const xOffset = centerX - x;
const yOffset = centerY - y;
const dist = Math.sqrt(xOffset * xOffset + yOffset * yOffset);
return dist <= tolerance;
}
function drawText(ctx, text, x, y, horizontalPixelRatio, verticalPixelRatio) {
ctx.save();
ctx.scale(horizontalPixelRatio, verticalPixelRatio);
ctx.fillText(text, x, y);
ctx.restore();
}
function hitTestText(textX, textY, textWidth, textHeight, x, y) {
const halfHeight = textHeight / 2;
return x >= textX && x <= textX + textWidth && y >= textY - halfHeight && y <= textY + halfHeight;
}
var SeriesMarkersRenderer = class extends BitmapCoordinatesPaneRenderer {
constructor() {
super(...arguments);
this._private__data = null;
this._private__textWidthCache = new TextWidthCache();
this._private__fontSize = -1;
this._private__fontFamily = "";
this._private__font = "";
}
_internal_setData(data) {
this._private__data = data;
}
_internal_setParams(fontSize, fontFamily) {
if (this._private__fontSize !== fontSize || this._private__fontFamily !== fontFamily) {
this._private__fontSize = fontSize;
this._private__fontFamily = fontFamily;
this._private__font = makeFont(fontSize, fontFamily);
this._private__textWidthCache._internal_reset();
}
}
_internal_hitTest(x, y) {
if (this._private__data === null || this._private__data._internal_visibleRange === null) {
return null;
}
for (let i = this._private__data._internal_visibleRange.from; i < this._private__data._internal_visibleRange.to; i++) {
const item = this._private__data._internal_items[i];
if (hitTestItem(item, x, y)) {
return {
_internal_hitTestData: item._internal_internalId,
_internal_externalId: item._internal_externalId
};
}
}
return null;
}
_internal__drawImpl({ context: ctx, horizontalPixelRatio, verticalPixelRatio }, isHovered, hitTestData) {
if (this._private__data === null || this._private__data._internal_visibleRange === null) {
return;
}
ctx.textBaseline = "middle";
ctx.font = this._private__font;
for (let i = this._private__data._internal_visibleRange.from; i < this._private__data._internal_visibleRange.to; i++) {
const item = this._private__data._internal_items[i];
if (item._internal_text !== void 0) {
item._internal_text._internal_width = this._private__textWidthCache._internal_measureText(ctx, item._internal_text._internal_content);
item._internal_text._internal_height = this._private__fontSize;
item._internal_text._internal_x = item._internal_x - item._internal_text._internal_width / 2;
}
drawItem(item, ctx, horizontalPixelRatio, verticalPixelRatio);
}
}
};
function bitmapShapeItemCoordinates(item, horizontalPixelRatio, verticalPixelRatio) {
const tickWidth = Math.max(1, Math.floor(horizontalPixelRatio));
const correction = tickWidth % 2 / 2;
return {
_internal_x: Math.round(item._internal_x * horizontalPixelRatio) + correction,
_internal_y: item._internal_y * verticalPixelRatio,
_internal_pixelRatio: horizontalPixelRatio
};
}
function drawItem(item, ctx, horizontalPixelRatio, verticalPixelRatio) {
ctx.fillStyle = item._internal_color;
if (item._internal_text !== void 0) {
drawText(ctx, item._internal_text._internal_content, item._internal_text._internal_x, item._internal_text._internal_y, horizontalPixelRatio, verticalPixelRatio);
}
drawShape(item, ctx, bitmapShapeItemCoordinates(item, horizontalPixelRatio, verticalPixelRatio));
}
function drawShape(item, ctx, coordinates) {
if (item._internal_size === 0) {
return;
}
switch (item._internal_shape) {
case "arrowDown":
drawArrow(false, ctx, coordinates, item._internal_size);
return;
case "arrowUp":
drawArrow(true, ctx, coordinates, item._internal_size);
return;
case "circle":
drawCircle(ctx, coordinates, item._internal_size);
return;
case "square":
drawSquare(ctx, coordinates, item._internal_size);
return;
}
ensureNever(item._internal_shape);
}
function hitTestItem(item, x, y) {
if (item._internal_text !== void 0 && hitTestText(item._internal_text._internal_x, item._internal_text._internal_y, item._internal_text._internal_width, item._internal_text._internal_height, x, y)) {
return true;
}
return hitTestShape(item, x, y);
}
function hitTestShape(item, x, y) {
if (item._internal_size === 0) {
return false;
}
switch (item._internal_shape) {
case "arrowDown":
return hitTestArrow(true, item._internal_x, item._internal_y, item._internal_size, x, y);
case "arrowUp":
return hitTestArrow(false, item._internal_x, item._internal_y, item._internal_size, x, y);
case "circle":
return hitTestCircle(item._internal_x, item._internal_y, item._internal_size, x, y);
case "square":
return hitTestSquare(item._internal_x, item._internal_y, item._internal_size, x, y);
}
}
function fillSizeAndY(rendererItem, marker, seriesData, offsets, textHeight, shapeMargin2, priceScale, timeScale, firstValue) {
const inBarPrice = isNumber(seriesData) ? seriesData : seriesData._internal_close;
const highPrice = isNumber(seriesData) ? seriesData : seriesData._internal_high;
const lowPrice = isNumber(seriesData) ? seriesData : seriesData._internal_low;
const sizeMultiplier = isNumber(marker.size) ? Math.max(marker.size, 0) : 1;
const shapeSize2 = calculateShapeHeight(timeScale._internal_barSpacing()) * sizeMultiplier;
const halfSize = shapeSize2 / 2;
rendererItem._internal_size = shapeSize2;
switch (marker.position) {
case "inBar": {
rendererItem._internal_y = priceScale._internal_priceToCoordinate(inBarPrice, firstValue);
if (rendererItem._internal_text !== void 0) {
rendererItem._internal_text._internal_y = rendererItem._internal_y + halfSize + shapeMargin2 + textHeight * (0.5 + 0.1);
}
return;
}
case "aboveBar": {
rendererItem._internal_y = priceScale._internal_priceToCoordinate(highPrice, firstValue) - halfSize - offsets._internal_aboveBar;
if (rendererItem._internal_text !== void 0) {
rendererItem._internal_text._internal_y = rendererItem._internal_y - halfSize - textHeight * (0.5 + 0.1);
offsets._internal_aboveBar += textHeight * (1 + 2 * 0.1);
}
offsets._internal_aboveBar += shapeSize2 + shapeMargin2;
return;
}
case "belowBar": {
rendererItem._internal_y = priceScale._internal_priceToCoordinate(lowPrice, firstValue) + halfSize + offsets._internal_belowBar;
if (rendererItem._internal_text !== void 0) {
rendererItem._internal_text._internal_y = rendererItem._internal_y + halfSize + shapeMargin2 + textHeight * (0.5 + 0.1);
offsets._internal_belowBar += textHeight * (1 + 2 * 0.1);
}
offsets._internal_belowBar += shapeSize2 + shapeMargin2;
return;
}
}
ensureNever(marker.position);
}
var SeriesMarkersPaneView = class {
constructor(series, model) {
this._private__invalidated = true;
this._private__dataInvalidated = true;
this._private__autoScaleMarginsInvalidated = true;
this._private__autoScaleMargins = null;
this._private__markersPositions = null;
this._private__renderer = new SeriesMarkersRenderer();
this._private__series = series;
this._private__model = model;
this._private__data = {
_internal_items: [],
_internal_visibleRange: null
};
}
_internal_update(updateType) {
this._private__invalidated = true;
this._private__autoScaleMarginsInvalidated = true;
if (updateType === "data") {
this._private__dataInvalidated = true;
this._private__markersPositions = null;
}
}
_internal_renderer(addAnchors) {
if (!this._private__series._internal_visible()) {
return null;
}
if (this._private__invalidated) {
this._internal__makeValid();
}
const layout = this._private__model._internal_options().layout;
this._private__renderer._internal_setParams(layout.fontSize, layout.fontFamily);
this._private__renderer._internal_setData(this._private__data);
return this._private__renderer;
}
_internal_autoScaleMargins() {
if (this._private__autoScaleMarginsInvalidated) {
if (this._private__series._internal_indexedMarkers().length > 0) {
const barSpacing = this._private__model._internal_timeScale()._internal_barSpacing();
const shapeMargin$1 = shapeMargin(barSpacing);
const marginValue = calculateShapeHeight(barSpacing) * 1.5 + shapeMargin$1 * 2;
const positions = this._internal__getMarkerPositions();
this._private__autoScaleMargins = {
above: calculateAdjustedMargin(marginValue, positions.aboveBar, positions.inBar),
below: calculateAdjustedMargin(marginValue, positions.belowBar, positions.inBar)
};
} else {
this._private__autoScaleMargins = null;
}
this._private__autoScaleMarginsInvalidated = false;
}
return this._private__autoScaleMargins;
}
_internal__getMarkerPositions() {
if (this._private__markersPositions === null) {
this._private__markersPositions = this._private__series._internal_indexedMarkers().reduce((acc, marker) => {
if (!acc[marker.position]) {
acc[marker.position] = true;
}
return acc;
}, {
inBar: false,
aboveBar: false,
belowBar: false
});
}
return this._private__markersPositions;
}
_internal__makeValid() {
const priceScale = this._private__series._internal_priceScale();
const timeScale = this._private__model._internal_timeScale();
const seriesMarkers = this._private__series._internal_indexedMarkers();
if (this._private__dataInvalidated) {
this._private__data._internal_items = seriesMarkers.map((marker) => ({
_internal_time: marker.time,
_internal_x: 0,
_internal_y: 0,
_internal_size: 0,
_internal_shape: marker.shape,
_internal_color: marker.color,
_internal_internalId: marker._internal_internalId,
_internal_externalId: marker.id,
_internal_text: void 0
}));
this._private__dataInvalidated = false;
}
const layoutOptions = this._private__model._internal_options().layout;
this._private__data._internal_visibleRange = null;
const visibleBars = timeScale._internal_visibleStrictRange();
if (visibleBars === null) {
return;
}
const firstValue = this._private__series._internal_firstValue();
if (firstValue === null) {
return;
}
if (this._private__data._internal_items.length === 0) {
return;
}
let prevTimeIndex = NaN;
const shapeMargin$1 = shapeMargin(timeScale._internal_barSpacing());
const offsets = {
_internal_aboveBar: shapeMargin$1,
_internal_belowBar: shapeMargin$1
};
this._private__data._internal_visibleRange = visibleTimedValues(this._private__data._internal_items, visibleBars, true);
for (let index = this._private__data._internal_visibleRange.from; index < this._private__data._internal_visibleRange.to; index++) {
const marker = seriesMarkers[index];
if (marker.time !== prevTimeIndex) {
offsets._internal_aboveBar = shapeMargin$1;
offsets._internal_belowBar = shapeMargin$1;
prevTimeIndex = marker.time;
}
const rendererItem = this._private__data._internal_items[index];
rendererItem._internal_x = timeScale._internal_indexToCoordinate(marker.time);
if (marker.text !== void 0 && marker.text.length > 0) {
rendererItem._internal_text = {
_internal_content: marker.text,
_internal_x: 0,
_internal_y: 0,
_internal_width: 0,
_internal_height: 0
};
}
const dataAt = this._private__series._internal_dataAt(marker.time);
if (dataAt === null) {
continue;
}
fillSizeAndY(rendererItem, marker, dataAt, offsets, layoutOptions.fontSize, shapeMargin$1, priceScale, timeScale, firstValue._internal_value);
}
this._private__invalidated = false;
}
};
var SeriesPriceLinePaneView = class extends SeriesHorizontalLinePaneView {
// eslint-disable-next-line no-useless-constructor
constructor(series) {
super(series);
}
_internal__updateImpl() {
const data = this._internal__lineRendererData;
data._internal_visible = false;
const seriesOptions = this._internal__series._internal_options();
if (!seriesOptions.priceLineVisible || !this._internal__series._internal_visible()) {
return;
}
const lastValueData = this._internal__series._internal_lastValueData(
seriesOptions.priceLineSource === 0
/* PriceLineSource.LastBar */
);
if (lastValueData._internal_noData) {
return;
}
data._internal_visible = true;
data._internal_y = lastValueData._internal_coordinate;
data._internal_color = this._internal__series._internal_priceLineColor(lastValueData._internal_color);
data._internal_lineWidth = seriesOptions.priceLineWidth;
data._internal_lineStyle = seriesOptions.priceLineStyle;
}
};
var SeriesPriceAxisView = class extends PriceAxisView {
constructor(source) {
super();
this._private__source = source;
}
_internal__updateRendererData(axisRendererData, paneRendererData, commonRendererData) {
axisRendererData._internal_visible = false;
paneRendererData._internal_visible = false;
const source = this._private__source;
if (!source._internal_visible()) {
return;
}
const seriesOptions = source._internal_options();
const showSeriesLastValue = seriesOptions.lastValueVisible;
const showSymbolLabel = source._internal_title() !== "";
const showPriceAndPercentage = seriesOptions.seriesLastValueMode === 0;
const lastValueData = source._internal_lastValueData(false);
if (lastValueData._internal_noData) {
return;
}
if (showSeriesLastValue) {
axisRendererData._internal_text = this._internal__axisText(lastValueData, showSeriesLastValue, showPriceAndPercentage);
axisRendererData._internal_visible = axisRendererData._internal_text.length !== 0;
}
if (showSymbolLabel || showPriceAndPercentage) {
paneRendererData._internal_text = this._internal__paneText(lastValueData, showSeriesLastValue, showSymbolLabel, showPriceAndPercentage);
paneRendererData._internal_visible = paneRendererData._internal_text.length > 0;
}
const lastValueColor = source._internal_priceLineColor(lastValueData._internal_color);
const colors = generateContrastColors(lastValueColor);
commonRendererData._internal_background = colors._internal_background;
commonRendererData._internal_coordinate = lastValueData._internal_coordinate;
paneRendererData._internal_borderColor = source._internal_model()._internal_backgroundColorAtYPercentFromTop(lastValueData._internal_coordinate / source._internal_priceScale()._internal_height());
axisRendererData._internal_borderColor = lastValueColor;
axisRendererData._internal_color = colors._internal_foreground;
paneRendererData._internal_color = colors._internal_foreground;
}
_internal__paneText(lastValue, showSeriesLastValue, showSymbolLabel, showPriceAndPercentage) {
let result = "";
const title = this._private__source._internal_title();
if (showSymbolLabel && title.length !== 0) {
result += `${title} `;
}
if (showSeriesLastValue && showPriceAndPercentage) {
result += this._private__source._internal_priceScale()._internal_isPercentage() ? lastValue._internal_formattedPriceAbsolute : lastValue._internal_formattedPricePercentage;
}
return result.trim();
}
_internal__axisText(lastValueData, showSeriesLastValue, showPriceAndPercentage) {
if (!showSeriesLastValue) {
return "";
}
if (!showPriceAndPercentage) {
return lastValueData._internal_text;
}
return this._private__source._internal_priceScale()._internal_isPercentage() ? lastValueData._internal_formattedPricePercentage : lastValueData._internal_formattedPriceAbsolute;
}
};
function computeFiniteResult(method, valueOne, valueTwo, fallback) {
const firstFinite = Number.isFinite(valueOne);
const secondFinite = Number.isFinite(valueTwo);
if (firstFinite && secondFinite) {
return method(valueOne, valueTwo);
}
return !firstFinite && !secondFinite ? fallback : firstFinite ? valueOne : valueTwo;
}
var PriceRangeImpl = class _PriceRangeImpl {
constructor(minValue, maxValue) {
this._private__minValue = minValue;
this._private__maxValue = maxValue;
}
_internal_equals(pr) {
if (pr === null) {
return false;
}
return this._private__minValue === pr._private__minValue && this._private__maxValue === pr._private__maxValue;
}
_internal_clone() {
return new _PriceRangeImpl(this._private__minValue, this._private__maxValue);
}
_internal_minValue() {
return this._private__minValue;
}
_internal_maxValue() {
return this._private__maxValue;
}
_internal_length() {
return this._private__maxValue - this._private__minValue;
}
_internal_isEmpty() {
return this._private__maxValue === this._private__minValue || Number.isNaN(this._private__maxValue) || Number.isNaN(this._private__minValue);
}
_internal_merge(anotherRange) {
if (anotherRange === null) {
return this;
}
return new _PriceRangeImpl(computeFiniteResult(Math.min, this._internal_minValue(), anotherRange._internal_minValue(), -Infinity), computeFiniteResult(Math.max, this._internal_maxValue(), anotherRange._internal_maxValue(), Infinity));
}
_internal_scaleAroundCenter(coeff) {
if (!isNumber(coeff)) {
return;
}
const delta = this._private__maxValue - this._private__minValue;
if (delta === 0) {
return;
}
const center = (this._private__maxValue + this._private__minValue) * 0.5;
let maxDelta = this._private__maxValue - center;
let minDelta = this._private__minValue - center;
maxDelta *= coeff;
minDelta *= coeff;
this._private__maxValue = center + maxDelta;
this._private__minValue = center + minDelta;
}
_internal_shift(delta) {
if (!isNumber(delta)) {
return;
}
this._private__maxValue += delta;
this._private__minValue += delta;
}
_internal_toRaw() {
return {
minValue: this._private__minValue,
maxValue: this._private__maxValue
};
}
static _internal_fromRaw(raw) {
return raw === null ? null : new _PriceRangeImpl(raw.minValue, raw.maxValue);
}
};
var AutoscaleInfoImpl = class _AutoscaleInfoImpl {
constructor(priceRange, margins) {
this._private__priceRange = priceRange;
this._private__margins = margins || null;
}
_internal_priceRange() {
return this._private__priceRange;
}
_internal_margins() {
return this._private__margins;
}
_internal_toRaw() {
if (this._private__priceRange === null) {
return null;
}
return {
priceRange: this._private__priceRange._internal_toRaw(),
margins: this._private__margins || void 0
};
}
static _internal_fromRaw(raw) {
return raw === null ? null : new _AutoscaleInfoImpl(PriceRangeImpl._internal_fromRaw(raw.priceRange), raw.margins);
}
};
var CustomPriceLinePaneView = class extends SeriesHorizontalLinePaneView {
constructor(series, priceLine) {
super(series);
this._private__priceLine = priceLine;
}
_internal__updateImpl() {
const data = this._internal__lineRendererData;
data._internal_visible = false;
const lineOptions = this._private__priceLine._internal_options();
if (!this._internal__series._internal_visible() || !lineOptions.lineVisible) {
return;
}
const y = this._private__priceLine._internal_yCoord();
if (y === null) {
return;
}
data._internal_visible = true;
data._internal_y = y;
data._internal_color = lineOptions.color;
data._internal_lineWidth = lineOptions.lineWidth;
data._internal_lineStyle = lineOptions.lineStyle;
data._internal_externalId = this._private__priceLine._internal_options().id;
}
};
var CustomPriceLinePriceAxisView = class extends PriceAxisView {
constructor(series, priceLine) {
super();
this._private__series = series;
this._private__priceLine = priceLine;
}
_internal__updateRendererData(axisRendererData, paneRendererData, commonData) {
axisRendererData._internal_visible = false;
paneRendererData._internal_visible = false;
const options = this._private__priceLine._internal_options();
const labelVisible = options.axisLabelVisible;
const showPaneLabel = options.title !== "";
const series = this._private__series;
if (!labelVisible || !series._internal_visible()) {
return;
}
const y = this._private__priceLine._internal_yCoord();
if (y === null) {
return;
}
if (showPaneLabel) {
paneRendererData._internal_text = options.title;
paneRendererData._internal_visible = true;
}
paneRendererData._internal_borderColor = series._internal_model()._internal_backgroundColorAtYPercentFromTop(y / series._internal_priceScale()._internal_height());
axisRendererData._internal_text = this._private__formatPrice(options.price);
axisRendererData._internal_visible = true;
const colors = generateContrastColors(options.axisLabelColor || options.color);
commonData._internal_background = colors._internal_background;
const textColor = options.axisLabelTextColor || colors._internal_foreground;
axisRendererData._internal_color = textColor;
paneRendererData._internal_color = textColor;
commonData._internal_coordinate = y;
}
_private__formatPrice(price) {
const firstValue = this._private__series._internal_firstValue();
if (firstValue === null) {
return "";
}
return this._private__series._internal_priceScale()._internal_formatPrice(price, firstValue._internal_value);
}
};
var CustomPriceLine = class {
constructor(series, options) {
this._private__series = series;
this._private__options = options;
this._private__priceLineView = new CustomPriceLinePaneView(series, this);
this._private__priceAxisView = new CustomPriceLinePriceAxisView(series, this);
this._private__panePriceAxisView = new PanePriceAxisView(this._private__priceAxisView, series, series._internal_model());
}
_internal_applyOptions(options) {
merge(this._private__options, options);
this._internal_update();
this._private__series._internal_model()._internal_lightUpdate();
}
_internal_options() {
return this._private__options;
}
_internal_paneView() {
return this._private__priceLineView;
}
_internal_labelPaneView() {
return this._private__panePriceAxisView;
}
_internal_priceAxisView() {
return this._private__priceAxisView;
}
_internal_update() {
this._private__priceLineView._internal_update();
this._private__priceAxisView._internal_update();
}
_internal_yCoord() {
const series = this._private__series;
const priceScale = series._internal_priceScale();
const timeScale = series._internal_model()._internal_timeScale();
if (timeScale._internal_isEmpty() || priceScale._internal_isEmpty()) {
return null;
}
const firstValue = series._internal_firstValue();
if (firstValue === null) {
return null;
}
return priceScale._internal_priceToCoordinate(this._private__options.price, firstValue._internal_value);
}
};
var PriceDataSource = class extends DataSource {
constructor(model) {
super();
this._private__model = model;
}
_internal_model() {
return this._private__model;
}
};
var barStyleFnMap = {
// eslint-disable-next-line @typescript-eslint/naming-convention
Bar: (findBar, barStyle, barIndex, precomputedBars) => {
var _a;
const upColor = barStyle.upColor;
const downColor = barStyle.downColor;
const currentBar = ensureNotNull(findBar(barIndex, precomputedBars));
const isUp = ensure(currentBar._internal_value[
0
/* PlotRowValueIndex.Open */
]) <= ensure(currentBar._internal_value[
3
/* PlotRowValueIndex.Close */
]);
return {
_internal_barColor: (_a = currentBar._internal_color) !== null && _a !== void 0 ? _a : isUp ? upColor : downColor
};
},
// eslint-disable-next-line @typescript-eslint/naming-convention
Candlestick: (findBar, candlestickStyle, barIndex, precomputedBars) => {
var _a, _b, _c;
const upColor = candlestickStyle.upColor;
const downColor = candlestickStyle.downColor;
const borderUpColor = candlestickStyle.borderUpColor;
const borderDownColor = candlestickStyle.borderDownColor;
const wickUpColor = candlestickStyle.wickUpColor;
const wickDownColor = candlestickStyle.wickDownColor;
const currentBar = ensureNotNull(findBar(barIndex, precomputedBars));
const isUp = ensure(currentBar._internal_value[
0
/* PlotRowValueIndex.Open */
]) <= ensure(currentBar._internal_value[
3
/* PlotRowValueIndex.Close */
]);
return {
_internal_barColor: (_a = currentBar._internal_color) !== null && _a !== void 0 ? _a : isUp ? upColor : downColor,
_internal_barBorderColor: (_b = currentBar._internal_borderColor) !== null && _b !== void 0 ? _b : isUp ? borderUpColor : borderDownColor,
_internal_barWickColor: (_c = currentBar._internal_wickColor) !== null && _c !== void 0 ? _c : isUp ? wickUpColor : wickDownColor
};
},
// eslint-disable-next-line @typescript-eslint/naming-convention
Custom: (findBar, customStyle, barIndex, precomputedBars) => {
var _a;
const currentBar = ensureNotNull(findBar(barIndex, precomputedBars));
return {
_internal_barColor: (_a = currentBar._internal_color) !== null && _a !== void 0 ? _a : customStyle.color
};
},
// eslint-disable-next-line @typescript-eslint/naming-convention
Area: (findBar, areaStyle, barIndex, precomputedBars) => {
var _a, _b, _c, _d;
const currentBar = ensureNotNull(findBar(barIndex, precomputedBars));
return {
_internal_barColor: (_a = currentBar._internal_lineColor) !== null && _a !== void 0 ? _a : areaStyle.lineColor,
_internal_lineColor: (_b = currentBar._internal_lineColor) !== null && _b !== void 0 ? _b : areaStyle.lineColor,
_internal_topColor: (_c = currentBar._internal_topColor) !== null && _c !== void 0 ? _c : areaStyle.topColor,
_internal_bottomColor: (_d = currentBar._internal_bottomColor) !== null && _d !== void 0 ? _d : areaStyle.bottomColor
};
},
// eslint-disable-next-line @typescript-eslint/naming-convention
Baseline: (findBar, baselineStyle, barIndex, precomputedBars) => {
var _a, _b, _c, _d, _e, _f;
const currentBar = ensureNotNull(findBar(barIndex, precomputedBars));
const isAboveBaseline = currentBar._internal_value[
3
/* PlotRowValueIndex.Close */
] >= baselineStyle.baseValue.price;
return {
_internal_barColor: isAboveBaseline ? baselineStyle.topLineColor : baselineStyle.bottomLineColor,
_internal_topLineColor: (_a = currentBar._internal_topLineColor) !== null && _a !== void 0 ? _a : baselineStyle.topLineColor,
_internal_bottomLineColor: (_b = currentBar._internal_bottomLineColor) !== null && _b !== void 0 ? _b : baselineStyle.bottomLineColor,
_internal_topFillColor1: (_c = currentBar._internal_topFillColor1) !== null && _c !== void 0 ? _c : baselineStyle.topFillColor1,
_internal_topFillColor2: (_d = currentBar._internal_topFillColor2) !== null && _d !== void 0 ? _d : baselineStyle.topFillColor2,
_internal_bottomFillColor1: (_e = currentBar._internal_bottomFillColor1) !== null && _e !== void 0 ? _e : baselineStyle.bottomFillColor1,
_internal_bottomFillColor2: (_f = currentBar._internal_bottomFillColor2) !== null && _f !== void 0 ? _f : baselineStyle.bottomFillColor2
};
},
// eslint-disable-next-line @typescript-eslint/naming-convention
Line: (findBar, lineStyle, barIndex, precomputedBars) => {
var _a, _b;
const currentBar = ensureNotNull(findBar(barIndex, precomputedBars));
return {
_internal_barColor: (_a = currentBar._internal_color) !== null && _a !== void 0 ? _a : lineStyle.color,
_internal_lineColor: (_b = currentBar._internal_color) !== null && _b !== void 0 ? _b : lineStyle.color
};
},
// eslint-disable-next-line @typescript-eslint/naming-convention
Histogram: (findBar, histogramStyle, barIndex, precomputedBars) => {
var _a;
const currentBar = ensureNotNull(findBar(barIndex, precomputedBars));
return {
_internal_barColor: (_a = currentBar._internal_color) !== null && _a !== void 0 ? _a : histogramStyle.color
};
}
};
var SeriesBarColorer = class {
constructor(series) {
this._private__findBar = (barIndex, precomputedBars) => {
if (precomputedBars !== void 0) {
return precomputedBars._internal_value;
}
return this._private__series._internal_bars()._internal_valueAt(barIndex);
};
this._private__series = series;
this._private__styleGetter = barStyleFnMap[series._internal_seriesType()];
}
_internal_barStyle(barIndex, precomputedBars) {
return this._private__styleGetter(this._private__findBar, this._private__series._internal_options(), barIndex, precomputedBars);
}
};
var MismatchDirection;
(function(MismatchDirection2) {
MismatchDirection2[MismatchDirection2["NearestLeft"] = -1] = "NearestLeft";
MismatchDirection2[MismatchDirection2["None"] = 0] = "None";
MismatchDirection2[MismatchDirection2["NearestRight"] = 1] = "NearestRight";
})(MismatchDirection || (MismatchDirection = {}));
var CHUNK_SIZE = 30;
var PlotList = class {
constructor() {
this._private__items = [];
this._private__minMaxCache = /* @__PURE__ */ new Map();
this._private__rowSearchCache = /* @__PURE__ */ new Map();
}
// @returns Last row
_internal_last() {
return this._internal_size() > 0 ? this._private__items[this._private__items.length - 1] : null;
}
_internal_firstIndex() {
return this._internal_size() > 0 ? this._private__indexAt(0) : null;
}
_internal_lastIndex() {
return this._internal_size() > 0 ? this._private__indexAt(this._private__items.length - 1) : null;
}
_internal_size() {
return this._private__items.length;
}
_internal_isEmpty() {
return this._internal_size() === 0;
}
_internal_contains(index) {
return this._private__search(
index,
0
/* MismatchDirection.None */
) !== null;
}
_internal_valueAt(index) {
return this._internal_search(index);
}
_internal_search(index, searchMode = 0) {
const pos = this._private__search(index, searchMode);
if (pos === null) {
return null;
}
return Object.assign(Object.assign({}, this._private__valueAt(pos)), { _internal_index: this._private__indexAt(pos) });
}
_internal_rows() {
return this._private__items;
}
_internal_minMaxOnRangeCached(start, end, plots) {
if (this._internal_isEmpty()) {
return null;
}
let result = null;
for (const plot of plots) {
const plotMinMax = this._private__minMaxOnRangeCachedImpl(start, end, plot);
result = mergeMinMax(result, plotMinMax);
}
return result;
}
_internal_setData(plotRows) {
this._private__rowSearchCache.clear();
this._private__minMaxCache.clear();
this._private__items = plotRows;
}
_private__indexAt(offset) {
return this._private__items[offset]._internal_index;
}
_private__valueAt(offset) {
return this._private__items[offset];
}
_private__search(index, searchMode) {
const exactPos = this._private__bsearch(index);
if (exactPos === null && searchMode !== 0) {
switch (searchMode) {
case -1:
return this._private__searchNearestLeft(index);
case 1:
return this._private__searchNearestRight(index);
default:
throw new TypeError("Unknown search mode");
}
}
return exactPos;
}
_private__searchNearestLeft(index) {
let nearestLeftPos = this._private__lowerbound(index);
if (nearestLeftPos > 0) {
nearestLeftPos = nearestLeftPos - 1;
}
return nearestLeftPos !== this._private__items.length && this._private__indexAt(nearestLeftPos) < index ? nearestLeftPos : null;
}
_private__searchNearestRight(index) {
const nearestRightPos = this._private__upperbound(index);
return nearestRightPos !== this._private__items.length && index < this._private__indexAt(nearestRightPos) ? nearestRightPos : null;
}
_private__bsearch(index) {
const start = this._private__lowerbound(index);
if (start !== this._private__items.length && !(index < this._private__items[start]._internal_index)) {
return start;
}
return null;
}
_private__lowerbound(index) {
return lowerBound(this._private__items, index, (a, b) => a._internal_index < b);
}
_private__upperbound(index) {
return upperBound(this._private__items, index, (a, b) => a._internal_index > b);
}
_private__plotMinMax(startIndex, endIndexExclusive, plotIndex) {
let result = null;
for (let i = startIndex; i < endIndexExclusive; i++) {
const values = this._private__items[i]._internal_value;
const v = values[plotIndex];
if (Number.isNaN(v)) {
continue;
}
if (result === null) {
result = { _internal_min: v, _internal_max: v };
} else {
if (v < result._internal_min) {
result._internal_min = v;
}
if (v > result._internal_max) {
result._internal_max = v;
}
}
}
return result;
}
_private__minMaxOnRangeCachedImpl(start, end, plotIndex) {
if (this._internal_isEmpty()) {
return null;
}
let result = null;
const firstIndex = ensureNotNull(this._internal_firstIndex());
const lastIndex = ensureNotNull(this._internal_lastIndex());
const s = Math.max(start, firstIndex);
const e = Math.min(end, lastIndex);
const cachedLow = Math.ceil(s / CHUNK_SIZE) * CHUNK_SIZE;
const cachedHigh = Math.max(cachedLow, Math.floor(e / CHUNK_SIZE) * CHUNK_SIZE);
{
const startIndex = this._private__lowerbound(s);
const endIndex = this._private__upperbound(Math.min(e, cachedLow, end));
const plotMinMax = this._private__plotMinMax(startIndex, endIndex, plotIndex);
result = mergeMinMax(result, plotMinMax);
}
let minMaxCache = this._private__minMaxCache.get(plotIndex);
if (minMaxCache === void 0) {
minMaxCache = /* @__PURE__ */ new Map();
this._private__minMaxCache.set(plotIndex, minMaxCache);
}
for (let c = Math.max(cachedLow + 1, s); c < cachedHigh; c += CHUNK_SIZE) {
const chunkIndex = Math.floor(c / CHUNK_SIZE);
let chunkMinMax = minMaxCache.get(chunkIndex);
if (chunkMinMax === void 0) {
const chunkStart = this._private__lowerbound(chunkIndex * CHUNK_SIZE);
const chunkEnd = this._private__upperbound((chunkIndex + 1) * CHUNK_SIZE - 1);
chunkMinMax = this._private__plotMinMax(chunkStart, chunkEnd, plotIndex);
minMaxCache.set(chunkIndex, chunkMinMax);
}
result = mergeMinMax(result, chunkMinMax);
}
{
const startIndex = this._private__lowerbound(cachedHigh);
const endIndex = this._private__upperbound(e);
const plotMinMax = this._private__plotMinMax(startIndex, endIndex, plotIndex);
result = mergeMinMax(result, plotMinMax);
}
return result;
}
};
function mergeMinMax(first, second) {
if (first === null) {
return second;
} else {
if (second === null) {
return first;
} else {
const min2 = Math.min(first._internal_min, second._internal_min);
const max = Math.max(first._internal_max, second._internal_max);
return { _internal_min: min2, _internal_max: max };
}
}
}
function createSeriesPlotList() {
return new PlotList();
}
var SeriesPrimitiveRendererWrapper = class {
constructor(baseRenderer) {
this._private__baseRenderer = baseRenderer;
}
_internal_draw(target, isHovered, hitTestData) {
this._private__baseRenderer.draw(target);
}
_internal_drawBackground(target, isHovered, hitTestData) {
var _a, _b;
(_b = (_a = this._private__baseRenderer).drawBackground) === null || _b === void 0 ? void 0 : _b.call(_a, target);
}
};
var SeriesPrimitivePaneViewWrapper = class {
constructor(paneView) {
this._private__cache = null;
this._private__paneView = paneView;
}
_internal_renderer() {
var _a;
const baseRenderer = this._private__paneView.renderer();
if (baseRenderer === null) {
return null;
}
if (((_a = this._private__cache) === null || _a === void 0 ? void 0 : _a._internal_base) === baseRenderer) {
return this._private__cache._internal_wrapper;
}
const wrapper = new SeriesPrimitiveRendererWrapper(baseRenderer);
this._private__cache = {
_internal_base: baseRenderer,
_internal_wrapper: wrapper
};
return wrapper;
}
_internal_zOrder() {
var _a, _b, _c;
return (_c = (_b = (_a = this._private__paneView).zOrder) === null || _b === void 0 ? void 0 : _b.call(_a)) !== null && _c !== void 0 ? _c : "normal";
}
};
function getAxisViewData(baseView) {
var _a, _b, _c, _d, _e;
return {
_internal_text: baseView.text(),
_internal_coordinate: baseView.coordinate(),
_internal_fixedCoordinate: (_a = baseView.fixedCoordinate) === null || _a === void 0 ? void 0 : _a.call(baseView),
_internal_color: baseView.textColor(),
_internal_background: baseView.backColor(),
_internal_visible: (_c = (_b = baseView.visible) === null || _b === void 0 ? void 0 : _b.call(baseView)) !== null && _c !== void 0 ? _c : true,
_internal_tickVisible: (_e = (_d = baseView.tickVisible) === null || _d === void 0 ? void 0 : _d.call(baseView)) !== null && _e !== void 0 ? _e : true
};
}
var SeriesPrimitiveTimeAxisViewWrapper = class {
constructor(baseView, timeScale) {
this._private__renderer = new TimeAxisViewRenderer();
this._private__baseView = baseView;
this._private__timeScale = timeScale;
}
_internal_renderer() {
this._private__renderer._internal_setData(Object.assign({ _internal_width: this._private__timeScale._internal_width() }, getAxisViewData(this._private__baseView)));
return this._private__renderer;
}
};
var SeriesPrimitivePriceAxisViewWrapper = class extends PriceAxisView {
constructor(baseView, priceScale) {
super();
this._private__baseView = baseView;
this._private__priceScale = priceScale;
}
_internal__updateRendererData(axisRendererData, paneRendererData, commonRendererData) {
const data = getAxisViewData(this._private__baseView);
commonRendererData._internal_background = data._internal_background;
axisRendererData._internal_color = data._internal_color;
const additionalPadding = 2 / 12 * this._private__priceScale._internal_fontSize();
commonRendererData._internal_additionalPaddingTop = additionalPadding;
commonRendererData._internal_additionalPaddingBottom = additionalPadding;
commonRendererData._internal_coordinate = data._internal_coordinate;
commonRendererData._internal_fixedCoordinate = data._internal_fixedCoordinate;
axisRendererData._internal_text = data._internal_text;
axisRendererData._internal_visible = data._internal_visible;
axisRendererData._internal_tickVisible = data._internal_tickVisible;
}
};
var SeriesPrimitiveWrapper = class {
constructor(primitive, series) {
this._private__paneViewsCache = null;
this._private__timeAxisViewsCache = null;
this._private__priceAxisViewsCache = null;
this._private__priceAxisPaneViewsCache = null;
this._private__timeAxisPaneViewsCache = null;
this._private__primitive = primitive;
this._private__series = series;
}
_internal_primitive() {
return this._private__primitive;
}
_internal_updateAllViews() {
var _a, _b;
(_b = (_a = this._private__primitive).updateAllViews) === null || _b === void 0 ? void 0 : _b.call(_a);
}
_internal_paneViews() {
var _a, _b, _c, _d;
const base = (_c = (_b = (_a = this._private__primitive).paneViews) === null || _b === void 0 ? void 0 : _b.call(_a)) !== null && _c !== void 0 ? _c : [];
if (((_d = this._private__paneViewsCache) === null || _d === void 0 ? void 0 : _d._internal_base) === base) {
return this._private__paneViewsCache._internal_wrapper;
}
const wrapper = base.map((pw) => new SeriesPrimitivePaneViewWrapper(pw));
this._private__paneViewsCache = {
_internal_base: base,
_internal_wrapper: wrapper
};
return wrapper;
}
_internal_timeAxisViews() {
var _a, _b, _c, _d;
const base = (_c = (_b = (_a = this._private__primitive).timeAxisViews) === null || _b === void 0 ? void 0 : _b.call(_a)) !== null && _c !== void 0 ? _c : [];
if (((_d = this._private__timeAxisViewsCache) === null || _d === void 0 ? void 0 : _d._internal_base) === base) {
return this._private__timeAxisViewsCache._internal_wrapper;
}
const timeScale = this._private__series._internal_model()._internal_timeScale();
const wrapper = base.map((aw) => new SeriesPrimitiveTimeAxisViewWrapper(aw, timeScale));
this._private__timeAxisViewsCache = {
_internal_base: base,
_internal_wrapper: wrapper
};
return wrapper;
}
_internal_priceAxisViews() {
var _a, _b, _c, _d;
const base = (_c = (_b = (_a = this._private__primitive).priceAxisViews) === null || _b === void 0 ? void 0 : _b.call(_a)) !== null && _c !== void 0 ? _c : [];
if (((_d = this._private__priceAxisViewsCache) === null || _d === void 0 ? void 0 : _d._internal_base) === base) {
return this._private__priceAxisViewsCache._internal_wrapper;
}
const priceScale = this._private__series._internal_priceScale();
const wrapper = base.map((aw) => new SeriesPrimitivePriceAxisViewWrapper(aw, priceScale));
this._private__priceAxisViewsCache = {
_internal_base: base,
_internal_wrapper: wrapper
};
return wrapper;
}
_internal_priceAxisPaneViews() {
var _a, _b, _c, _d;
const base = (_c = (_b = (_a = this._private__primitive).priceAxisPaneViews) === null || _b === void 0 ? void 0 : _b.call(_a)) !== null && _c !== void 0 ? _c : [];
if (((_d = this._private__priceAxisPaneViewsCache) === null || _d === void 0 ? void 0 : _d._internal_base) === base) {
return this._private__priceAxisPaneViewsCache._internal_wrapper;
}
const wrapper = base.map((pw) => new SeriesPrimitivePaneViewWrapper(pw));
this._private__priceAxisPaneViewsCache = {
_internal_base: base,
_internal_wrapper: wrapper
};
return wrapper;
}
_internal_timeAxisPaneViews() {
var _a, _b, _c, _d;
const base = (_c = (_b = (_a = this._private__primitive).timeAxisPaneViews) === null || _b === void 0 ? void 0 : _b.call(_a)) !== null && _c !== void 0 ? _c : [];
if (((_d = this._private__timeAxisPaneViewsCache) === null || _d === void 0 ? void 0 : _d._internal_base) === base) {
return this._private__timeAxisPaneViewsCache._internal_wrapper;
}
const wrapper = base.map((pw) => new SeriesPrimitivePaneViewWrapper(pw));
this._private__timeAxisPaneViewsCache = {
_internal_base: base,
_internal_wrapper: wrapper
};
return wrapper;
}
_internal_autoscaleInfo(startTimePoint, endTimePoint) {
var _a, _b, _c;
return (_c = (_b = (_a = this._private__primitive).autoscaleInfo) === null || _b === void 0 ? void 0 : _b.call(_a, startTimePoint, endTimePoint)) !== null && _c !== void 0 ? _c : null;
}
_internal_hitTest(x, y) {
var _a, _b, _c;
return (_c = (_b = (_a = this._private__primitive).hitTest) === null || _b === void 0 ? void 0 : _b.call(_a, x, y)) !== null && _c !== void 0 ? _c : null;
}
};
function extractPrimitivePaneViews(primitives, extractor, zOrder, destination) {
primitives.forEach((wrapper) => {
extractor(wrapper).forEach((paneView) => {
if (paneView._internal_zOrder() !== zOrder) {
return;
}
destination.push(paneView);
});
});
}
function primitivePaneViewsExtractor(wrapper) {
return wrapper._internal_paneViews();
}
function primitivePricePaneViewsExtractor(wrapper) {
return wrapper._internal_priceAxisPaneViews();
}
function primitiveTimePaneViewsExtractor(wrapper) {
return wrapper._internal_timeAxisPaneViews();
}
var Series = class extends PriceDataSource {
constructor(model, options, seriesType, pane, customPaneView) {
super(model);
this._private__data = createSeriesPlotList();
this._private__priceLineView = new SeriesPriceLinePaneView(this);
this._private__customPriceLines = [];
this._private__baseHorizontalLineView = new SeriesHorizontalBaseLinePaneView(this);
this._private__lastPriceAnimationPaneView = null;
this._private__barColorerCache = null;
this._private__markers = [];
this._private__indexedMarkers = [];
this._private__animationTimeoutId = null;
this._private__primitives = [];
this._private__options = options;
this._private__seriesType = seriesType;
const priceAxisView = new SeriesPriceAxisView(this);
this._private__priceAxisViews = [priceAxisView];
this._private__panePriceAxisView = new PanePriceAxisView(priceAxisView, this, model);
if (seriesType === "Area" || seriesType === "Line" || seriesType === "Baseline") {
this._private__lastPriceAnimationPaneView = new SeriesLastPriceAnimationPaneView(this);
}
this._private__recreateFormatter();
this._private__recreatePaneViews(customPaneView);
}
_internal_destroy() {
if (this._private__animationTimeoutId !== null) {
clearTimeout(this._private__animationTimeoutId);
}
}
_internal_priceLineColor(lastBarColor) {
return this._private__options.priceLineColor || lastBarColor;
}
_internal_lastValueData(globalLast) {
const noDataRes = { _internal_noData: true };
const priceScale = this._internal_priceScale();
if (this._internal_model()._internal_timeScale()._internal_isEmpty() || priceScale._internal_isEmpty() || this._private__data._internal_isEmpty()) {
return noDataRes;
}
const visibleBars = this._internal_model()._internal_timeScale()._internal_visibleStrictRange();
const firstValue = this._internal_firstValue();
if (visibleBars === null || firstValue === null) {
return noDataRes;
}
let bar;
let lastIndex;
if (globalLast) {
const lastBar = this._private__data._internal_last();
if (lastBar === null) {
return noDataRes;
}
bar = lastBar;
lastIndex = lastBar._internal_index;
} else {
const endBar = this._private__data._internal_search(
visibleBars._internal_right(),
-1
/* MismatchDirection.NearestLeft */
);
if (endBar === null) {
return noDataRes;
}
bar = this._private__data._internal_valueAt(endBar._internal_index);
if (bar === null) {
return noDataRes;
}
lastIndex = endBar._internal_index;
}
const price = bar._internal_value[
3
/* PlotRowValueIndex.Close */
];
const barColorer = this._internal_barColorer();
const style = barColorer._internal_barStyle(lastIndex, { _internal_value: bar });
const coordinate = priceScale._internal_priceToCoordinate(price, firstValue._internal_value);
return {
_internal_noData: false,
_internal_price: price,
_internal_text: priceScale._internal_formatPrice(price, firstValue._internal_value),
_internal_formattedPriceAbsolute: priceScale._internal_formatPriceAbsolute(price),
_internal_formattedPricePercentage: priceScale._internal_formatPricePercentage(price, firstValue._internal_value),
_internal_color: style._internal_barColor,
_internal_coordinate: coordinate,
_internal_index: lastIndex
};
}
_internal_barColorer() {
if (this._private__barColorerCache !== null) {
return this._private__barColorerCache;
}
this._private__barColorerCache = new SeriesBarColorer(this);
return this._private__barColorerCache;
}
_internal_options() {
return this._private__options;
}
_internal_applyOptions(options) {
const targetPriceScaleId = options.priceScaleId;
if (targetPriceScaleId !== void 0 && targetPriceScaleId !== this._private__options.priceScaleId) {
this._internal_model()._internal_moveSeriesToScale(this, targetPriceScaleId);
}
merge(this._private__options, options);
if (options.priceFormat !== void 0) {
this._private__recreateFormatter();
this._internal_model()._internal_fullUpdate();
}
this._internal_model()._internal_updateSource(this);
this._internal_model()._internal_updateCrosshair();
this._private__paneView._internal_update("options");
}
_internal_setData(data, updateInfo) {
this._private__data._internal_setData(data);
this._private__recalculateMarkers();
this._private__paneView._internal_update("data");
this._private__markersPaneView._internal_update("data");
if (this._private__lastPriceAnimationPaneView !== null) {
if (updateInfo && updateInfo._internal_lastBarUpdatedOrNewBarsAddedToTheRight) {
this._private__lastPriceAnimationPaneView._internal_onNewRealtimeDataReceived();
} else if (data.length === 0) {
this._private__lastPriceAnimationPaneView._internal_onDataCleared();
}
}
const sourcePane = this._internal_model()._internal_paneForSource(this);
this._internal_model()._internal_recalculatePane(sourcePane);
this._internal_model()._internal_updateSource(this);
this._internal_model()._internal_updateCrosshair();
this._internal_model()._internal_lightUpdate();
}
_internal_setMarkers(data) {
this._private__markers = data;
this._private__recalculateMarkers();
const sourcePane = this._internal_model()._internal_paneForSource(this);
this._private__markersPaneView._internal_update("data");
this._internal_model()._internal_recalculatePane(sourcePane);
this._internal_model()._internal_updateSource(this);
this._internal_model()._internal_updateCrosshair();
this._internal_model()._internal_lightUpdate();
}
_internal_markers() {
return this._private__markers;
}
_internal_indexedMarkers() {
return this._private__indexedMarkers;
}
_internal_createPriceLine(options) {
const result = new CustomPriceLine(this, options);
this._private__customPriceLines.push(result);
this._internal_model()._internal_updateSource(this);
return result;
}
_internal_removePriceLine(line) {
const index = this._private__customPriceLines.indexOf(line);
if (index !== -1) {
this._private__customPriceLines.splice(index, 1);
}
this._internal_model()._internal_updateSource(this);
}
_internal_seriesType() {
return this._private__seriesType;
}
_internal_firstValue() {
const bar = this._internal_firstBar();
if (bar === null) {
return null;
}
return {
_internal_value: bar._internal_value[
3
/* PlotRowValueIndex.Close */
],
_internal_timePoint: bar._internal_time
};
}
_internal_firstBar() {
const visibleBars = this._internal_model()._internal_timeScale()._internal_visibleStrictRange();
if (visibleBars === null) {
return null;
}
const startTimePoint = visibleBars._internal_left();
return this._private__data._internal_search(
startTimePoint,
1
/* MismatchDirection.NearestRight */
);
}
_internal_bars() {
return this._private__data;
}
_internal_dataAt(time) {
const prices = this._private__data._internal_valueAt(time);
if (prices === null) {
return null;
}
if (this._private__seriesType === "Bar" || this._private__seriesType === "Candlestick" || this._private__seriesType === "Custom") {
return {
_internal_open: prices._internal_value[
0
/* PlotRowValueIndex.Open */
],
_internal_high: prices._internal_value[
1
/* PlotRowValueIndex.High */
],
_internal_low: prices._internal_value[
2
/* PlotRowValueIndex.Low */
],
_internal_close: prices._internal_value[
3
/* PlotRowValueIndex.Close */
]
};
} else {
return prices._internal_value[
3
/* PlotRowValueIndex.Close */
];
}
}
_internal_topPaneViews(pane) {
const res = [];
extractPrimitivePaneViews(this._private__primitives, primitivePaneViewsExtractor, "top", res);
const animationPaneView = this._private__lastPriceAnimationPaneView;
if (animationPaneView === null || !animationPaneView._internal_visible()) {
return res;
}
if (this._private__animationTimeoutId === null && animationPaneView._internal_animationActive()) {
this._private__animationTimeoutId = setTimeout(() => {
this._private__animationTimeoutId = null;
this._internal_model()._internal_cursorUpdate();
}, 0);
}
animationPaneView._internal_invalidateStage();
res.unshift(animationPaneView);
return res;
}
_internal_paneViews() {
const res = [];
if (!this._private__isOverlay()) {
res.push(this._private__baseHorizontalLineView);
}
res.push(this._private__paneView, this._private__priceLineView, this._private__markersPaneView);
const priceLineViews = this._private__customPriceLines.map((line) => line._internal_paneView());
res.push(...priceLineViews);
extractPrimitivePaneViews(this._private__primitives, primitivePaneViewsExtractor, "normal", res);
return res;
}
_internal_bottomPaneViews() {
return this._private__extractPaneViews(primitivePaneViewsExtractor, "bottom");
}
_internal_pricePaneViews(zOrder) {
return this._private__extractPaneViews(primitivePricePaneViewsExtractor, zOrder);
}
_internal_timePaneViews(zOrder) {
return this._private__extractPaneViews(primitiveTimePaneViewsExtractor, zOrder);
}
_internal_primitiveHitTest(x, y) {
return this._private__primitives.map((primitive) => primitive._internal_hitTest(x, y)).filter((result) => result !== null);
}
_internal_labelPaneViews(pane) {
return [
this._private__panePriceAxisView,
...this._private__customPriceLines.map((line) => line._internal_labelPaneView())
];
}
_internal_priceAxisViews(pane, priceScale) {
if (priceScale !== this._internal__priceScale && !this._private__isOverlay()) {
return [];
}
const result = [...this._private__priceAxisViews];
for (const customPriceLine of this._private__customPriceLines) {
result.push(customPriceLine._internal_priceAxisView());
}
this._private__primitives.forEach((wrapper) => {
result.push(...wrapper._internal_priceAxisViews());
});
return result;
}
_internal_timeAxisViews() {
const res = [];
this._private__primitives.forEach((wrapper) => {
res.push(...wrapper._internal_timeAxisViews());
});
return res;
}
_internal_autoscaleInfo(startTimePoint, endTimePoint) {
if (this._private__options.autoscaleInfoProvider !== void 0) {
const autoscaleInfo = this._private__options.autoscaleInfoProvider(() => {
const res = this._private__autoscaleInfoImpl(startTimePoint, endTimePoint);
return res === null ? null : res._internal_toRaw();
});
return AutoscaleInfoImpl._internal_fromRaw(autoscaleInfo);
}
return this._private__autoscaleInfoImpl(startTimePoint, endTimePoint);
}
_internal_minMove() {
return this._private__options.priceFormat.minMove;
}
_internal_formatter() {
return this._private__formatter;
}
_internal_updateAllViews() {
var _a;
this._private__paneView._internal_update();
this._private__markersPaneView._internal_update();
for (const priceAxisView of this._private__priceAxisViews) {
priceAxisView._internal_update();
}
for (const customPriceLine of this._private__customPriceLines) {
customPriceLine._internal_update();
}
this._private__priceLineView._internal_update();
this._private__baseHorizontalLineView._internal_update();
(_a = this._private__lastPriceAnimationPaneView) === null || _a === void 0 ? void 0 : _a._internal_update();
this._private__primitives.forEach((wrapper) => wrapper._internal_updateAllViews());
}
_internal_priceScale() {
return ensureNotNull(super._internal_priceScale());
}
_internal_markerDataAtIndex(index) {
const getValue = (this._private__seriesType === "Line" || this._private__seriesType === "Area" || this._private__seriesType === "Baseline") && this._private__options.crosshairMarkerVisible;
if (!getValue) {
return null;
}
const bar = this._private__data._internal_valueAt(index);
if (bar === null) {
return null;
}
const price = bar._internal_value[
3
/* PlotRowValueIndex.Close */
];
const radius2 = this._private__markerRadius();
const borderColor = this._private__markerBorderColor();
const borderWidth = this._private__markerBorderWidth();
const backgroundColor = this._private__markerBackgroundColor(index);
return { _internal_price: price, _internal_radius: radius2, _internal_borderColor: borderColor, _internal_borderWidth: borderWidth, _internal_backgroundColor: backgroundColor };
}
_internal_title() {
return this._private__options.title;
}
_internal_visible() {
return this._private__options.visible;
}
_internal_attachPrimitive(primitive) {
this._private__primitives.push(new SeriesPrimitiveWrapper(primitive, this));
}
_internal_detachPrimitive(source) {
this._private__primitives = this._private__primitives.filter((wrapper) => wrapper._internal_primitive() !== source);
}
_internal_customSeriesPlotValuesBuilder() {
if (this._private__paneView instanceof SeriesCustomPaneView === false) {
return void 0;
}
return (data) => {
return this._private__paneView._internal_priceValueBuilder(data);
};
}
_internal_customSeriesWhitespaceCheck() {
if (this._private__paneView instanceof SeriesCustomPaneView === false) {
return void 0;
}
return (data) => {
return this._private__paneView._internal_isWhitespace(data);
};
}
_private__isOverlay() {
const priceScale = this._internal_priceScale();
return !isDefaultPriceScale(priceScale._internal_id());
}
_private__autoscaleInfoImpl(startTimePoint, endTimePoint) {
if (!isInteger(startTimePoint) || !isInteger(endTimePoint) || this._private__data._internal_isEmpty()) {
return null;
}
const plots = this._private__seriesType === "Line" || this._private__seriesType === "Area" || this._private__seriesType === "Baseline" || this._private__seriesType === "Histogram" ? [
3
/* PlotRowValueIndex.Close */
] : [
2,
1
/* PlotRowValueIndex.High */
];
const barsMinMax = this._private__data._internal_minMaxOnRangeCached(startTimePoint, endTimePoint, plots);
let range = barsMinMax !== null ? new PriceRangeImpl(barsMinMax._internal_min, barsMinMax._internal_max) : null;
if (this._internal_seriesType() === "Histogram") {
const base = this._private__options.base;
const rangeWithBase = new PriceRangeImpl(base, base);
range = range !== null ? range._internal_merge(rangeWithBase) : rangeWithBase;
}
let margins = this._private__markersPaneView._internal_autoScaleMargins();
this._private__primitives.forEach((primitive) => {
const primitiveAutoscale = primitive._internal_autoscaleInfo(startTimePoint, endTimePoint);
if (primitiveAutoscale === null || primitiveAutoscale === void 0 ? void 0 : primitiveAutoscale.priceRange) {
const primitiveRange = new PriceRangeImpl(primitiveAutoscale.priceRange.minValue, primitiveAutoscale.priceRange.maxValue);
range = range !== null ? range._internal_merge(primitiveRange) : primitiveRange;
}
if (primitiveAutoscale === null || primitiveAutoscale === void 0 ? void 0 : primitiveAutoscale.margins) {
margins = mergeMargins(margins, primitiveAutoscale.margins);
}
});
return new AutoscaleInfoImpl(range, margins);
}
_private__markerRadius() {
switch (this._private__seriesType) {
case "Line":
case "Area":
case "Baseline":
return this._private__options.crosshairMarkerRadius;
}
return 0;
}
_private__markerBorderColor() {
switch (this._private__seriesType) {
case "Line":
case "Area":
case "Baseline": {
const crosshairMarkerBorderColor = this._private__options.crosshairMarkerBorderColor;
if (crosshairMarkerBorderColor.length !== 0) {
return crosshairMarkerBorderColor;
}
}
}
return null;
}
_private__markerBorderWidth() {
switch (this._private__seriesType) {
case "Line":
case "Area":
case "Baseline":
return this._private__options.crosshairMarkerBorderWidth;
}
return 0;
}
_private__markerBackgroundColor(index) {
switch (this._private__seriesType) {
case "Line":
case "Area":
case "Baseline": {
const crosshairMarkerBackgroundColor = this._private__options.crosshairMarkerBackgroundColor;
if (crosshairMarkerBackgroundColor.length !== 0) {
return crosshairMarkerBackgroundColor;
}
}
}
return this._internal_barColorer()._internal_barStyle(index)._internal_barColor;
}
_private__recreateFormatter() {
switch (this._private__options.priceFormat.type) {
case "custom": {
this._private__formatter = { format: this._private__options.priceFormat.formatter };
break;
}
case "volume": {
this._private__formatter = new VolumeFormatter(this._private__options.priceFormat.precision);
break;
}
case "percent": {
this._private__formatter = new PercentageFormatter(this._private__options.priceFormat.precision);
break;
}
default: {
const priceScale = Math.pow(10, this._private__options.priceFormat.precision);
this._private__formatter = new PriceFormatter(priceScale, this._private__options.priceFormat.minMove * priceScale);
}
}
if (this._internal__priceScale !== null) {
this._internal__priceScale._internal_updateFormatter();
}
}
_private__recalculateMarkers() {
const timeScale = this._internal_model()._internal_timeScale();
if (!timeScale._internal_hasPoints() || this._private__data._internal_isEmpty()) {
this._private__indexedMarkers = [];
return;
}
const firstDataIndex = ensureNotNull(this._private__data._internal_firstIndex());
this._private__indexedMarkers = this._private__markers.map((marker, index) => {
const timePointIndex = ensureNotNull(timeScale._internal_timeToIndex(marker.time, true));
const searchMode = timePointIndex < firstDataIndex ? 1 : -1;
const seriesDataIndex = ensureNotNull(this._private__data._internal_search(timePointIndex, searchMode))._internal_index;
return {
time: seriesDataIndex,
position: marker.position,
shape: marker.shape,
color: marker.color,
id: marker.id,
_internal_internalId: index,
text: marker.text,
size: marker.size,
originalTime: marker.originalTime
};
});
}
_private__recreatePaneViews(customPaneView) {
this._private__markersPaneView = new SeriesMarkersPaneView(this, this._internal_model());
switch (this._private__seriesType) {
case "Bar": {
this._private__paneView = new SeriesBarsPaneView(this, this._internal_model());
break;
}
case "Candlestick": {
this._private__paneView = new SeriesCandlesticksPaneView(this, this._internal_model());
break;
}
case "Line": {
this._private__paneView = new SeriesLinePaneView(this, this._internal_model());
break;
}
case "Custom": {
this._private__paneView = new SeriesCustomPaneView(this, this._internal_model(), ensureDefined(customPaneView));
break;
}
case "Area": {
this._private__paneView = new SeriesAreaPaneView(this, this._internal_model());
break;
}
case "Baseline": {
this._private__paneView = new SeriesBaselinePaneView(this, this._internal_model());
break;
}
case "Histogram": {
this._private__paneView = new SeriesHistogramPaneView(this, this._internal_model());
break;
}
default:
throw Error("Unknown chart style assigned: " + this._private__seriesType);
}
}
_private__extractPaneViews(extractor, zOrder) {
const res = [];
extractPrimitivePaneViews(this._private__primitives, extractor, zOrder, res);
return res;
}
};
function mergeMargins(source, additionalMargin) {
var _a, _b;
return {
above: Math.max((_a = source === null || source === void 0 ? void 0 : source.above) !== null && _a !== void 0 ? _a : 0, additionalMargin.above),
below: Math.max((_b = source === null || source === void 0 ? void 0 : source.below) !== null && _b !== void 0 ? _b : 0, additionalMargin.below)
};
}
var Magnet = class {
constructor(options) {
this._private__options = options;
}
_internal_align(price, index, pane) {
let res = price;
if (this._private__options.mode === 0) {
return res;
}
const defaultPriceScale = pane._internal_defaultPriceScale();
const firstValue = defaultPriceScale._internal_firstValue();
if (firstValue === null) {
return res;
}
const y = defaultPriceScale._internal_priceToCoordinate(price, firstValue);
const serieses = pane._internal_dataSources().filter((ds) => ds instanceof Series);
const candidates = serieses.reduce((acc, series) => {
if (pane._internal_isOverlay(series) || !series._internal_visible()) {
return acc;
}
const ps = series._internal_priceScale();
const bars = series._internal_bars();
if (ps._internal_isEmpty() || !bars._internal_contains(index)) {
return acc;
}
const bar = bars._internal_valueAt(index);
if (bar === null) {
return acc;
}
const firstPrice = ensure(series._internal_firstValue());
return acc.concat([ps._internal_priceToCoordinate(bar._internal_value[
3
/* PlotRowValueIndex.Close */
], firstPrice._internal_value)]);
}, []);
if (candidates.length === 0) {
return res;
}
candidates.sort((y1, y2) => Math.abs(y1 - y) - Math.abs(y2 - y));
const nearest = candidates[0];
res = defaultPriceScale._internal_coordinateToPrice(nearest, firstValue);
return res;
}
};
var GridRenderer = class extends BitmapCoordinatesPaneRenderer {
constructor() {
super(...arguments);
this._private__data = null;
}
_internal_setData(data) {
this._private__data = data;
}
_internal__drawImpl({ context: ctx, bitmapSize, horizontalPixelRatio, verticalPixelRatio }) {
if (this._private__data === null) {
return;
}
const lineWidth = Math.max(1, Math.floor(horizontalPixelRatio));
ctx.lineWidth = lineWidth;
strokeInPixel(ctx, () => {
const data = ensureNotNull(this._private__data);
if (data._internal_vertLinesVisible) {
ctx.strokeStyle = data._internal_vertLinesColor;
setLineStyle(ctx, data._internal_vertLineStyle);
ctx.beginPath();
for (const timeMark of data._internal_timeMarks) {
const x = Math.round(timeMark._internal_coord * horizontalPixelRatio);
ctx.moveTo(x, -lineWidth);
ctx.lineTo(x, bitmapSize.height + lineWidth);
}
ctx.stroke();
}
if (data._internal_horzLinesVisible) {
ctx.strokeStyle = data._internal_horzLinesColor;
setLineStyle(ctx, data._internal_horzLineStyle);
ctx.beginPath();
for (const priceMark of data._internal_priceMarks) {
const y = Math.round(priceMark._internal_coord * verticalPixelRatio);
ctx.moveTo(-lineWidth, y);
ctx.lineTo(bitmapSize.width + lineWidth, y);
}
ctx.stroke();
}
});
}
};
var GridPaneView = class {
constructor(pane) {
this._private__renderer = new GridRenderer();
this._private__invalidated = true;
this._private__pane = pane;
}
_internal_update() {
this._private__invalidated = true;
}
_internal_renderer() {
if (this._private__invalidated) {
const gridOptions = this._private__pane._internal_model()._internal_options().grid;
const data = {
_internal_horzLinesVisible: gridOptions.horzLines.visible,
_internal_vertLinesVisible: gridOptions.vertLines.visible,
_internal_horzLinesColor: gridOptions.horzLines.color,
_internal_vertLinesColor: gridOptions.vertLines.color,
_internal_horzLineStyle: gridOptions.horzLines.style,
_internal_vertLineStyle: gridOptions.vertLines.style,
_internal_priceMarks: this._private__pane._internal_defaultPriceScale()._internal_marks(),
// need this conversiom because TimeMark is a part of external interface
// and fields inside TimeMark are not minified
_internal_timeMarks: (this._private__pane._internal_model()._internal_timeScale()._internal_marks() || []).map((tm) => {
return { _internal_coord: tm.coord };
})
};
this._private__renderer._internal_setData(data);
this._private__invalidated = false;
}
return this._private__renderer;
}
};
var Grid = class {
constructor(pane) {
this._private__paneView = new GridPaneView(pane);
}
_internal_paneView() {
return this._private__paneView;
}
};
var defLogFormula = {
_internal_logicalOffset: 4,
_internal_coordOffset: 1e-4
};
function fromPercent(value, baseValue) {
if (baseValue < 0) {
value = -value;
}
return value / 100 * baseValue + baseValue;
}
function toPercent(value, baseValue) {
const result = 100 * (value - baseValue) / baseValue;
return baseValue < 0 ? -result : result;
}
function toPercentRange(priceRange, baseValue) {
const minPercent = toPercent(priceRange._internal_minValue(), baseValue);
const maxPercent = toPercent(priceRange._internal_maxValue(), baseValue);
return new PriceRangeImpl(minPercent, maxPercent);
}
function fromIndexedTo100(value, baseValue) {
value -= 100;
if (baseValue < 0) {
value = -value;
}
return value / 100 * baseValue + baseValue;
}
function toIndexedTo100(value, baseValue) {
const result = 100 * (value - baseValue) / baseValue + 100;
return baseValue < 0 ? -result : result;
}
function toIndexedTo100Range(priceRange, baseValue) {
const minPercent = toIndexedTo100(priceRange._internal_minValue(), baseValue);
const maxPercent = toIndexedTo100(priceRange._internal_maxValue(), baseValue);
return new PriceRangeImpl(minPercent, maxPercent);
}
function toLog(price, logFormula) {
const m = Math.abs(price);
if (m < 1e-15) {
return 0;
}
const res = Math.log10(m + logFormula._internal_coordOffset) + logFormula._internal_logicalOffset;
return price < 0 ? -res : res;
}
function fromLog(logical, logFormula) {
const m = Math.abs(logical);
if (m < 1e-15) {
return 0;
}
const res = Math.pow(10, m - logFormula._internal_logicalOffset) - logFormula._internal_coordOffset;
return logical < 0 ? -res : res;
}
function convertPriceRangeToLog(priceRange, logFormula) {
if (priceRange === null) {
return null;
}
const min2 = toLog(priceRange._internal_minValue(), logFormula);
const max = toLog(priceRange._internal_maxValue(), logFormula);
return new PriceRangeImpl(min2, max);
}
function canConvertPriceRangeFromLog(priceRange, logFormula) {
if (priceRange === null) {
return false;
}
const min2 = fromLog(priceRange._internal_minValue(), logFormula);
const max = fromLog(priceRange._internal_maxValue(), logFormula);
return isFinite(min2) && isFinite(max);
}
function convertPriceRangeFromLog(priceRange, logFormula) {
if (priceRange === null) {
return null;
}
const min2 = fromLog(priceRange._internal_minValue(), logFormula);
const max = fromLog(priceRange._internal_maxValue(), logFormula);
return new PriceRangeImpl(min2, max);
}
function logFormulaForPriceRange(range) {
if (range === null) {
return defLogFormula;
}
const diff = Math.abs(range._internal_maxValue() - range._internal_minValue());
if (diff >= 1 || diff < 1e-15) {
return defLogFormula;
}
const digits = Math.ceil(Math.abs(Math.log10(diff)));
const logicalOffset = defLogFormula._internal_logicalOffset + digits;
const coordOffset = 1 / Math.pow(10, logicalOffset);
return {
_internal_logicalOffset: logicalOffset,
_internal_coordOffset: coordOffset
};
}
function logFormulasAreSame(f1, f2) {
return f1._internal_logicalOffset === f2._internal_logicalOffset && f1._internal_coordOffset === f2._internal_coordOffset;
}
var PriceTickSpanCalculator = class {
constructor(base, integralDividers) {
this._private__base = base;
this._private__integralDividers = integralDividers;
if (isBaseDecimal(this._private__base)) {
this._private__fractionalDividers = [2, 2.5, 2];
} else {
this._private__fractionalDividers = [];
for (let baseRest = this._private__base; baseRest !== 1; ) {
if (baseRest % 2 === 0) {
this._private__fractionalDividers.push(2);
baseRest /= 2;
} else if (baseRest % 5 === 0) {
this._private__fractionalDividers.push(2, 2.5);
baseRest /= 5;
} else {
throw new Error("unexpected base");
}
if (this._private__fractionalDividers.length > 100) {
throw new Error("something wrong with base");
}
}
}
}
_internal_tickSpan(high, low, maxTickSpan) {
const minMovement = this._private__base === 0 ? 0 : 1 / this._private__base;
let resultTickSpan = Math.pow(10, Math.max(0, Math.ceil(Math.log10(high - low))));
let index = 0;
let c = this._private__integralDividers[0];
while (true) {
const resultTickSpanLargerMinMovement = greaterOrEqual(
resultTickSpan,
minMovement,
1e-14
/* Constants.TickSpanEpsilon */
) && resultTickSpan > minMovement + 1e-14;
const resultTickSpanLargerMaxTickSpan = greaterOrEqual(
resultTickSpan,
maxTickSpan * c,
1e-14
/* Constants.TickSpanEpsilon */
);
const resultTickSpanLarger1 = greaterOrEqual(
resultTickSpan,
1,
1e-14
/* Constants.TickSpanEpsilon */
);
const haveToContinue = resultTickSpanLargerMinMovement && resultTickSpanLargerMaxTickSpan && resultTickSpanLarger1;
if (!haveToContinue) {
break;
}
resultTickSpan /= c;
c = this._private__integralDividers[++index % this._private__integralDividers.length];
}
if (resultTickSpan <= minMovement + 1e-14) {
resultTickSpan = minMovement;
}
resultTickSpan = Math.max(1, resultTickSpan);
if (this._private__fractionalDividers.length > 0 && equal(
resultTickSpan,
1,
1e-14
/* Constants.TickSpanEpsilon */
)) {
index = 0;
c = this._private__fractionalDividers[0];
while (greaterOrEqual(
resultTickSpan,
maxTickSpan * c,
1e-14
/* Constants.TickSpanEpsilon */
) && resultTickSpan > minMovement + 1e-14) {
resultTickSpan /= c;
c = this._private__fractionalDividers[++index % this._private__fractionalDividers.length];
}
}
return resultTickSpan;
}
};
var TICK_DENSITY = 2.5;
var PriceTickMarkBuilder = class {
constructor(priceScale, base, coordinateToLogicalFunc, logicalToCoordinateFunc) {
this._private__marks = [];
this._private__priceScale = priceScale;
this._private__base = base;
this._private__coordinateToLogicalFunc = coordinateToLogicalFunc;
this._private__logicalToCoordinateFunc = logicalToCoordinateFunc;
}
_internal_tickSpan(high, low) {
if (high < low) {
throw new Error("high < low");
}
const scaleHeight = this._private__priceScale._internal_height();
const markHeight = this._private__tickMarkHeight();
const maxTickSpan = (high - low) * markHeight / scaleHeight;
const spanCalculator1 = new PriceTickSpanCalculator(this._private__base, [2, 2.5, 2]);
const spanCalculator2 = new PriceTickSpanCalculator(this._private__base, [2, 2, 2.5]);
const spanCalculator3 = new PriceTickSpanCalculator(this._private__base, [2.5, 2, 2]);
const spans = [];
spans.push(spanCalculator1._internal_tickSpan(high, low, maxTickSpan), spanCalculator2._internal_tickSpan(high, low, maxTickSpan), spanCalculator3._internal_tickSpan(high, low, maxTickSpan));
return min(spans);
}
_internal_rebuildTickMarks() {
const priceScale = this._private__priceScale;
const firstValue = priceScale._internal_firstValue();
if (firstValue === null) {
this._private__marks = [];
return;
}
const scaleHeight = priceScale._internal_height();
const bottom = this._private__coordinateToLogicalFunc(scaleHeight - 1, firstValue);
const top = this._private__coordinateToLogicalFunc(0, firstValue);
const extraTopBottomMargin = this._private__priceScale._internal_options().entireTextOnly ? this._private__fontHeight() / 2 : 0;
const minCoord = extraTopBottomMargin;
const maxCoord = scaleHeight - 1 - extraTopBottomMargin;
const high = Math.max(bottom, top);
const low = Math.min(bottom, top);
if (high === low) {
this._private__marks = [];
return;
}
let span = this._internal_tickSpan(high, low);
let mod = high % span;
mod += mod < 0 ? span : 0;
const sign = high >= low ? 1 : -1;
let prevCoord = null;
let targetIndex = 0;
for (let logical = high - mod; logical > low; logical -= span) {
const coord = this._private__logicalToCoordinateFunc(logical, firstValue, true);
if (prevCoord !== null && Math.abs(coord - prevCoord) < this._private__tickMarkHeight()) {
continue;
}
if (coord < minCoord || coord > maxCoord) {
continue;
}
if (targetIndex < this._private__marks.length) {
this._private__marks[targetIndex]._internal_coord = coord;
this._private__marks[targetIndex]._internal_label = priceScale._internal_formatLogical(logical);
} else {
this._private__marks.push({
_internal_coord: coord,
_internal_label: priceScale._internal_formatLogical(logical)
});
}
targetIndex++;
prevCoord = coord;
if (priceScale._internal_isLog()) {
span = this._internal_tickSpan(logical * sign, low);
}
}
this._private__marks.length = targetIndex;
}
_internal_marks() {
return this._private__marks;
}
_private__fontHeight() {
return this._private__priceScale._internal_fontSize();
}
_private__tickMarkHeight() {
return Math.ceil(this._private__fontHeight() * TICK_DENSITY);
}
};
function sortSources(sources) {
return sources.slice().sort((s1, s2) => {
return ensureNotNull(s1._internal_zorder()) - ensureNotNull(s2._internal_zorder());
});
}
var PriceScaleMode;
(function(PriceScaleMode2) {
PriceScaleMode2[PriceScaleMode2["Normal"] = 0] = "Normal";
PriceScaleMode2[PriceScaleMode2["Logarithmic"] = 1] = "Logarithmic";
PriceScaleMode2[PriceScaleMode2["Percentage"] = 2] = "Percentage";
PriceScaleMode2[PriceScaleMode2["IndexedTo100"] = 3] = "IndexedTo100";
})(PriceScaleMode || (PriceScaleMode = {}));
var percentageFormatter = new PercentageFormatter();
var defaultPriceFormatter = new PriceFormatter(100, 1);
var PriceScale = class {
constructor(id, options, layoutOptions, localizationOptions) {
this._private__height = 0;
this._private__internalHeightCache = null;
this._private__priceRange = null;
this._private__priceRangeSnapshot = null;
this._private__invalidatedForRange = { _internal_isValid: false, _internal_visibleBars: null };
this._private__marginAbove = 0;
this._private__marginBelow = 0;
this._private__onMarksChanged = new Delegate();
this._private__modeChanged = new Delegate();
this._private__dataSources = [];
this._private__cachedOrderedSources = null;
this._private__marksCache = null;
this._private__scaleStartPoint = null;
this._private__scrollStartPoint = null;
this._private__formatter = defaultPriceFormatter;
this._private__logFormula = logFormulaForPriceRange(null);
this._private__id = id;
this._private__options = options;
this._private__layoutOptions = layoutOptions;
this._private__localizationOptions = localizationOptions;
this._private__markBuilder = new PriceTickMarkBuilder(this, 100, this._private__coordinateToLogical.bind(this), this._private__logicalToCoordinate.bind(this));
}
_internal_id() {
return this._private__id;
}
_internal_options() {
return this._private__options;
}
_internal_applyOptions(options) {
merge(this._private__options, options);
this._internal_updateFormatter();
if (options.mode !== void 0) {
this._internal_setMode({ _internal_mode: options.mode });
}
if (options.scaleMargins !== void 0) {
const top = ensureDefined(options.scaleMargins.top);
const bottom = ensureDefined(options.scaleMargins.bottom);
if (top < 0 || top > 1) {
throw new Error(`Invalid top margin - expect value between 0 and 1, given=${top}`);
}
if (bottom < 0 || bottom > 1) {
throw new Error(`Invalid bottom margin - expect value between 0 and 1, given=${bottom}`);
}
if (top + bottom > 1) {
throw new Error(`Invalid margins - sum of margins must be less than 1, given=${top + bottom}`);
}
this._private__invalidateInternalHeightCache();
this._private__marksCache = null;
}
}
_internal_isAutoScale() {
return this._private__options.autoScale;
}
_internal_isLog() {
return this._private__options.mode === 1;
}
_internal_isPercentage() {
return this._private__options.mode === 2;
}
_internal_isIndexedTo100() {
return this._private__options.mode === 3;
}
_internal_mode() {
return {
_internal_autoScale: this._private__options.autoScale,
_internal_isInverted: this._private__options.invertScale,
_internal_mode: this._private__options.mode
};
}
// eslint-disable-next-line complexity
_internal_setMode(newMode) {
const oldMode = this._internal_mode();
let priceRange = null;
if (newMode._internal_autoScale !== void 0) {
this._private__options.autoScale = newMode._internal_autoScale;
}
if (newMode._internal_mode !== void 0) {
this._private__options.mode = newMode._internal_mode;
if (newMode._internal_mode === 2 || newMode._internal_mode === 3) {
this._private__options.autoScale = true;
}
this._private__invalidatedForRange._internal_isValid = false;
}
if (oldMode._internal_mode === 1 && newMode._internal_mode !== oldMode._internal_mode) {
if (canConvertPriceRangeFromLog(this._private__priceRange, this._private__logFormula)) {
priceRange = convertPriceRangeFromLog(this._private__priceRange, this._private__logFormula);
if (priceRange !== null) {
this._internal_setPriceRange(priceRange);
}
} else {
this._private__options.autoScale = true;
}
}
if (newMode._internal_mode === 1 && newMode._internal_mode !== oldMode._internal_mode) {
priceRange = convertPriceRangeToLog(this._private__priceRange, this._private__logFormula);
if (priceRange !== null) {
this._internal_setPriceRange(priceRange);
}
}
const modeChanged = oldMode._internal_mode !== this._private__options.mode;
if (modeChanged && (oldMode._internal_mode === 2 || this._internal_isPercentage())) {
this._internal_updateFormatter();
}
if (modeChanged && (oldMode._internal_mode === 3 || this._internal_isIndexedTo100())) {
this._internal_updateFormatter();
}
if (newMode._internal_isInverted !== void 0 && oldMode._internal_isInverted !== newMode._internal_isInverted) {
this._private__options.invertScale = newMode._internal_isInverted;
this._private__onIsInvertedChanged();
}
this._private__modeChanged._internal_fire(oldMode, this._internal_mode());
}
_internal_modeChanged() {
return this._private__modeChanged;
}
_internal_fontSize() {
return this._private__layoutOptions.fontSize;
}
_internal_height() {
return this._private__height;
}
_internal_setHeight(value) {
if (this._private__height === value) {
return;
}
this._private__height = value;
this._private__invalidateInternalHeightCache();
this._private__marksCache = null;
}
_internal_internalHeight() {
if (this._private__internalHeightCache) {
return this._private__internalHeightCache;
}
const res = this._internal_height() - this._private__topMarginPx() - this._private__bottomMarginPx();
this._private__internalHeightCache = res;
return res;
}
_internal_priceRange() {
this._private__makeSureItIsValid();
return this._private__priceRange;
}
_internal_setPriceRange(newPriceRange, isForceSetValue) {
const oldPriceRange = this._private__priceRange;
if (!isForceSetValue && !(oldPriceRange === null && newPriceRange !== null) && (oldPriceRange === null || oldPriceRange._internal_equals(newPriceRange))) {
return;
}
this._private__marksCache = null;
this._private__priceRange = newPriceRange;
}
_internal_isEmpty() {
this._private__makeSureItIsValid();
return this._private__height === 0 || !this._private__priceRange || this._private__priceRange._internal_isEmpty();
}
_internal_invertedCoordinate(coordinate) {
return this._internal_isInverted() ? coordinate : this._internal_height() - 1 - coordinate;
}
_internal_priceToCoordinate(price, baseValue) {
if (this._internal_isPercentage()) {
price = toPercent(price, baseValue);
} else if (this._internal_isIndexedTo100()) {
price = toIndexedTo100(price, baseValue);
}
return this._private__logicalToCoordinate(price, baseValue);
}
_internal_pointsArrayToCoordinates(points, baseValue, visibleRange) {
this._private__makeSureItIsValid();
const bh = this._private__bottomMarginPx();
const range = ensureNotNull(this._internal_priceRange());
const min2 = range._internal_minValue();
const max = range._internal_maxValue();
const ih = this._internal_internalHeight() - 1;
const isInverted = this._internal_isInverted();
const hmm = ih / (max - min2);
const fromIndex = visibleRange === void 0 ? 0 : visibleRange.from;
const toIndex = visibleRange === void 0 ? points.length : visibleRange.to;
const transformFn = this._private__getCoordinateTransformer();
for (let i = fromIndex; i < toIndex; i++) {
const point = points[i];
const price = point._internal_price;
if (isNaN(price)) {
continue;
}
let logical = price;
if (transformFn !== null) {
logical = transformFn(point._internal_price, baseValue);
}
const invCoordinate = bh + hmm * (logical - min2);
const coordinate = isInverted ? invCoordinate : this._private__height - 1 - invCoordinate;
point._internal_y = coordinate;
}
}
_internal_barPricesToCoordinates(pricesList, baseValue, visibleRange) {
this._private__makeSureItIsValid();
const bh = this._private__bottomMarginPx();
const range = ensureNotNull(this._internal_priceRange());
const min2 = range._internal_minValue();
const max = range._internal_maxValue();
const ih = this._internal_internalHeight() - 1;
const isInverted = this._internal_isInverted();
const hmm = ih / (max - min2);
const fromIndex = visibleRange === void 0 ? 0 : visibleRange.from;
const toIndex = visibleRange === void 0 ? pricesList.length : visibleRange.to;
const transformFn = this._private__getCoordinateTransformer();
for (let i = fromIndex; i < toIndex; i++) {
const bar = pricesList[i];
let openLogical = bar._internal_open;
let highLogical = bar._internal_high;
let lowLogical = bar._internal_low;
let closeLogical = bar._internal_close;
if (transformFn !== null) {
openLogical = transformFn(bar._internal_open, baseValue);
highLogical = transformFn(bar._internal_high, baseValue);
lowLogical = transformFn(bar._internal_low, baseValue);
closeLogical = transformFn(bar._internal_close, baseValue);
}
let invCoordinate = bh + hmm * (openLogical - min2);
let coordinate = isInverted ? invCoordinate : this._private__height - 1 - invCoordinate;
bar._internal_openY = coordinate;
invCoordinate = bh + hmm * (highLogical - min2);
coordinate = isInverted ? invCoordinate : this._private__height - 1 - invCoordinate;
bar._internal_highY = coordinate;
invCoordinate = bh + hmm * (lowLogical - min2);
coordinate = isInverted ? invCoordinate : this._private__height - 1 - invCoordinate;
bar._internal_lowY = coordinate;
invCoordinate = bh + hmm * (closeLogical - min2);
coordinate = isInverted ? invCoordinate : this._private__height - 1 - invCoordinate;
bar._internal_closeY = coordinate;
}
}
_internal_coordinateToPrice(coordinate, baseValue) {
const logical = this._private__coordinateToLogical(coordinate, baseValue);
return this._internal_logicalToPrice(logical, baseValue);
}
_internal_logicalToPrice(logical, baseValue) {
let value = logical;
if (this._internal_isPercentage()) {
value = fromPercent(value, baseValue);
} else if (this._internal_isIndexedTo100()) {
value = fromIndexedTo100(value, baseValue);
}
return value;
}
_internal_dataSources() {
return this._private__dataSources;
}
_internal_orderedSources() {
if (this._private__cachedOrderedSources) {
return this._private__cachedOrderedSources;
}
let sources = [];
for (let i = 0; i < this._private__dataSources.length; i++) {
const ds = this._private__dataSources[i];
if (ds._internal_zorder() === null) {
ds._internal_setZorder(i + 1);
}
sources.push(ds);
}
sources = sortSources(sources);
this._private__cachedOrderedSources = sources;
return this._private__cachedOrderedSources;
}
_internal_addDataSource(source) {
if (this._private__dataSources.indexOf(source) !== -1) {
return;
}
this._private__dataSources.push(source);
this._internal_updateFormatter();
this._internal_invalidateSourcesCache();
}
_internal_removeDataSource(source) {
const index = this._private__dataSources.indexOf(source);
if (index === -1) {
throw new Error("source is not attached to scale");
}
this._private__dataSources.splice(index, 1);
if (this._private__dataSources.length === 0) {
this._internal_setMode({
_internal_autoScale: true
});
this._internal_setPriceRange(null);
}
this._internal_updateFormatter();
this._internal_invalidateSourcesCache();
}
_internal_firstValue() {
let result = null;
for (const source of this._private__dataSources) {
const firstValue = source._internal_firstValue();
if (firstValue === null) {
continue;
}
if (result === null || firstValue._internal_timePoint < result._internal_timePoint) {
result = firstValue;
}
}
return result === null ? null : result._internal_value;
}
_internal_isInverted() {
return this._private__options.invertScale;
}
_internal_marks() {
const firstValueIsNull = this._internal_firstValue() === null;
if (this._private__marksCache !== null && (firstValueIsNull || this._private__marksCache._internal_firstValueIsNull === firstValueIsNull)) {
return this._private__marksCache._internal_marks;
}
this._private__markBuilder._internal_rebuildTickMarks();
const marks = this._private__markBuilder._internal_marks();
this._private__marksCache = { _internal_marks: marks, _internal_firstValueIsNull: firstValueIsNull };
this._private__onMarksChanged._internal_fire();
return marks;
}
_internal_onMarksChanged() {
return this._private__onMarksChanged;
}
_internal_startScale(x) {
if (this._internal_isPercentage() || this._internal_isIndexedTo100()) {
return;
}
if (this._private__scaleStartPoint !== null || this._private__priceRangeSnapshot !== null) {
return;
}
if (this._internal_isEmpty()) {
return;
}
this._private__scaleStartPoint = this._private__height - x;
this._private__priceRangeSnapshot = ensureNotNull(this._internal_priceRange())._internal_clone();
}
_internal_scaleTo(x) {
if (this._internal_isPercentage() || this._internal_isIndexedTo100()) {
return;
}
if (this._private__scaleStartPoint === null) {
return;
}
this._internal_setMode({
_internal_autoScale: false
});
x = this._private__height - x;
if (x < 0) {
x = 0;
}
let scaleCoeff = (this._private__scaleStartPoint + (this._private__height - 1) * 0.2) / (x + (this._private__height - 1) * 0.2);
const newPriceRange = ensureNotNull(this._private__priceRangeSnapshot)._internal_clone();
scaleCoeff = Math.max(scaleCoeff, 0.1);
newPriceRange._internal_scaleAroundCenter(scaleCoeff);
this._internal_setPriceRange(newPriceRange);
}
_internal_endScale() {
if (this._internal_isPercentage() || this._internal_isIndexedTo100()) {
return;
}
this._private__scaleStartPoint = null;
this._private__priceRangeSnapshot = null;
}
_internal_startScroll(x) {
if (this._internal_isAutoScale()) {
return;
}
if (this._private__scrollStartPoint !== null || this._private__priceRangeSnapshot !== null) {
return;
}
if (this._internal_isEmpty()) {
return;
}
this._private__scrollStartPoint = x;
this._private__priceRangeSnapshot = ensureNotNull(this._internal_priceRange())._internal_clone();
}
_internal_scrollTo(x) {
if (this._internal_isAutoScale()) {
return;
}
if (this._private__scrollStartPoint === null) {
return;
}
const priceUnitsPerPixel = ensureNotNull(this._internal_priceRange())._internal_length() / (this._internal_internalHeight() - 1);
let pixelDelta = x - this._private__scrollStartPoint;
if (this._internal_isInverted()) {
pixelDelta *= -1;
}
const priceDelta = pixelDelta * priceUnitsPerPixel;
const newPriceRange = ensureNotNull(this._private__priceRangeSnapshot)._internal_clone();
newPriceRange._internal_shift(priceDelta);
this._internal_setPriceRange(newPriceRange, true);
this._private__marksCache = null;
}
_internal_endScroll() {
if (this._internal_isAutoScale()) {
return;
}
if (this._private__scrollStartPoint === null) {
return;
}
this._private__scrollStartPoint = null;
this._private__priceRangeSnapshot = null;
}
_internal_formatter() {
if (!this._private__formatter) {
this._internal_updateFormatter();
}
return this._private__formatter;
}
_internal_formatPrice(price, firstValue) {
switch (this._private__options.mode) {
case 2:
return this._private__formatPercentage(toPercent(price, firstValue));
case 3:
return this._internal_formatter().format(toIndexedTo100(price, firstValue));
default:
return this._private__formatPrice(price);
}
}
_internal_formatLogical(logical) {
switch (this._private__options.mode) {
case 2:
return this._private__formatPercentage(logical);
case 3:
return this._internal_formatter().format(logical);
default:
return this._private__formatPrice(logical);
}
}
_internal_formatPriceAbsolute(price) {
return this._private__formatPrice(price, ensureNotNull(this._private__formatterSource())._internal_formatter());
}
_internal_formatPricePercentage(price, baseValue) {
price = toPercent(price, baseValue);
return this._private__formatPercentage(price, percentageFormatter);
}
_internal_sourcesForAutoScale() {
return this._private__dataSources;
}
_internal_recalculatePriceRange(visibleBars) {
this._private__invalidatedForRange = {
_internal_visibleBars: visibleBars,
_internal_isValid: false
};
}
_internal_updateAllViews() {
this._private__dataSources.forEach((s) => s._internal_updateAllViews());
}
_internal_updateFormatter() {
this._private__marksCache = null;
const formatterSource = this._private__formatterSource();
let base = 100;
if (formatterSource !== null) {
base = Math.round(1 / formatterSource._internal_minMove());
}
this._private__formatter = defaultPriceFormatter;
if (this._internal_isPercentage()) {
this._private__formatter = percentageFormatter;
base = 100;
} else if (this._internal_isIndexedTo100()) {
this._private__formatter = new PriceFormatter(100, 1);
base = 100;
} else {
if (formatterSource !== null) {
this._private__formatter = formatterSource._internal_formatter();
}
}
this._private__markBuilder = new PriceTickMarkBuilder(this, base, this._private__coordinateToLogical.bind(this), this._private__logicalToCoordinate.bind(this));
this._private__markBuilder._internal_rebuildTickMarks();
}
_internal_invalidateSourcesCache() {
this._private__cachedOrderedSources = null;
}
/**
* @returns The {@link IPriceDataSource} that will be used as the "formatter source" (take minMove for formatter).
*/
_private__formatterSource() {
return this._private__dataSources[0] || null;
}
_private__topMarginPx() {
return this._internal_isInverted() ? this._private__options.scaleMargins.bottom * this._internal_height() + this._private__marginBelow : this._private__options.scaleMargins.top * this._internal_height() + this._private__marginAbove;
}
_private__bottomMarginPx() {
return this._internal_isInverted() ? this._private__options.scaleMargins.top * this._internal_height() + this._private__marginAbove : this._private__options.scaleMargins.bottom * this._internal_height() + this._private__marginBelow;
}
_private__makeSureItIsValid() {
if (!this._private__invalidatedForRange._internal_isValid) {
this._private__invalidatedForRange._internal_isValid = true;
this._private__recalculatePriceRangeImpl();
}
}
_private__invalidateInternalHeightCache() {
this._private__internalHeightCache = null;
}
_private__logicalToCoordinate(logical, baseValue) {
this._private__makeSureItIsValid();
if (this._internal_isEmpty()) {
return 0;
}
logical = this._internal_isLog() && logical ? toLog(logical, this._private__logFormula) : logical;
const range = ensureNotNull(this._internal_priceRange());
const invCoordinate = this._private__bottomMarginPx() + (this._internal_internalHeight() - 1) * (logical - range._internal_minValue()) / range._internal_length();
const coordinate = this._internal_invertedCoordinate(invCoordinate);
return coordinate;
}
_private__coordinateToLogical(coordinate, baseValue) {
this._private__makeSureItIsValid();
if (this._internal_isEmpty()) {
return 0;
}
const invCoordinate = this._internal_invertedCoordinate(coordinate);
const range = ensureNotNull(this._internal_priceRange());
const logical = range._internal_minValue() + range._internal_length() * ((invCoordinate - this._private__bottomMarginPx()) / (this._internal_internalHeight() - 1));
return this._internal_isLog() ? fromLog(logical, this._private__logFormula) : logical;
}
_private__onIsInvertedChanged() {
this._private__marksCache = null;
this._private__markBuilder._internal_rebuildTickMarks();
}
// eslint-disable-next-line complexity
_private__recalculatePriceRangeImpl() {
const visibleBars = this._private__invalidatedForRange._internal_visibleBars;
if (visibleBars === null) {
return;
}
let priceRange = null;
const sources = this._internal_sourcesForAutoScale();
let marginAbove = 0;
let marginBelow = 0;
for (const source of sources) {
if (!source._internal_visible()) {
continue;
}
const firstValue = source._internal_firstValue();
if (firstValue === null) {
continue;
}
const autoScaleInfo = source._internal_autoscaleInfo(visibleBars._internal_left(), visibleBars._internal_right());
let sourceRange = autoScaleInfo && autoScaleInfo._internal_priceRange();
if (sourceRange !== null) {
switch (this._private__options.mode) {
case 1:
sourceRange = convertPriceRangeToLog(sourceRange, this._private__logFormula);
break;
case 2:
sourceRange = toPercentRange(sourceRange, firstValue._internal_value);
break;
case 3:
sourceRange = toIndexedTo100Range(sourceRange, firstValue._internal_value);
break;
}
if (priceRange === null) {
priceRange = sourceRange;
} else {
priceRange = priceRange._internal_merge(ensureNotNull(sourceRange));
}
if (autoScaleInfo !== null) {
const margins = autoScaleInfo._internal_margins();
if (margins !== null) {
marginAbove = Math.max(marginAbove, margins.above);
marginBelow = Math.max(marginBelow, margins.below);
}
}
}
}
if (marginAbove !== this._private__marginAbove || marginBelow !== this._private__marginBelow) {
this._private__marginAbove = marginAbove;
this._private__marginBelow = marginBelow;
this._private__marksCache = null;
this._private__invalidateInternalHeightCache();
}
if (priceRange !== null) {
if (priceRange._internal_minValue() === priceRange._internal_maxValue()) {
const formatterSource = this._private__formatterSource();
const minMove = formatterSource === null || this._internal_isPercentage() || this._internal_isIndexedTo100() ? 1 : formatterSource._internal_minMove();
const extendValue = 5 * minMove;
if (this._internal_isLog()) {
priceRange = convertPriceRangeFromLog(priceRange, this._private__logFormula);
}
priceRange = new PriceRangeImpl(priceRange._internal_minValue() - extendValue, priceRange._internal_maxValue() + extendValue);
if (this._internal_isLog()) {
priceRange = convertPriceRangeToLog(priceRange, this._private__logFormula);
}
}
if (this._internal_isLog()) {
const rawRange = convertPriceRangeFromLog(priceRange, this._private__logFormula);
const newLogFormula = logFormulaForPriceRange(rawRange);
if (!logFormulasAreSame(newLogFormula, this._private__logFormula)) {
const rawSnapshot = this._private__priceRangeSnapshot !== null ? convertPriceRangeFromLog(this._private__priceRangeSnapshot, this._private__logFormula) : null;
this._private__logFormula = newLogFormula;
priceRange = convertPriceRangeToLog(rawRange, newLogFormula);
if (rawSnapshot !== null) {
this._private__priceRangeSnapshot = convertPriceRangeToLog(rawSnapshot, newLogFormula);
}
}
}
this._internal_setPriceRange(priceRange);
} else {
if (this._private__priceRange === null) {
this._internal_setPriceRange(new PriceRangeImpl(-0.5, 0.5));
this._private__logFormula = logFormulaForPriceRange(null);
}
}
this._private__invalidatedForRange._internal_isValid = true;
}
_private__getCoordinateTransformer() {
if (this._internal_isPercentage()) {
return toPercent;
} else if (this._internal_isIndexedTo100()) {
return toIndexedTo100;
} else if (this._internal_isLog()) {
return (price) => toLog(price, this._private__logFormula);
}
return null;
}
_private__formatValue(value, formatter, fallbackFormatter) {
if (formatter === void 0) {
if (fallbackFormatter === void 0) {
fallbackFormatter = this._internal_formatter();
}
return fallbackFormatter.format(value);
}
return formatter(value);
}
_private__formatPrice(price, fallbackFormatter) {
return this._private__formatValue(price, this._private__localizationOptions.priceFormatter, fallbackFormatter);
}
_private__formatPercentage(percentage, fallbackFormatter) {
return this._private__formatValue(percentage, this._private__localizationOptions.percentageFormatter, fallbackFormatter);
}
};
var DEFAULT_STRETCH_FACTOR = 1e3;
var Pane = class {
constructor(timeScale, model) {
this._private__dataSources = [];
this._private__overlaySourcesByScaleId = /* @__PURE__ */ new Map();
this._private__height = 0;
this._private__width = 0;
this._private__stretchFactor = DEFAULT_STRETCH_FACTOR;
this._private__cachedOrderedSources = null;
this._private__destroyed = new Delegate();
this._private__timeScale = timeScale;
this._private__model = model;
this._private__grid = new Grid(this);
const options = model._internal_options();
this._private__leftPriceScale = this._private__createPriceScale("left", options.leftPriceScale);
this._private__rightPriceScale = this._private__createPriceScale("right", options.rightPriceScale);
this._private__leftPriceScale._internal_modeChanged()._internal_subscribe(this._private__onPriceScaleModeChanged.bind(this, this._private__leftPriceScale), this);
this._private__rightPriceScale._internal_modeChanged()._internal_subscribe(this._private__onPriceScaleModeChanged.bind(this, this._private__rightPriceScale), this);
this._internal_applyScaleOptions(options);
}
_internal_applyScaleOptions(options) {
if (options.leftPriceScale) {
this._private__leftPriceScale._internal_applyOptions(options.leftPriceScale);
}
if (options.rightPriceScale) {
this._private__rightPriceScale._internal_applyOptions(options.rightPriceScale);
}
if (options.localization) {
this._private__leftPriceScale._internal_updateFormatter();
this._private__rightPriceScale._internal_updateFormatter();
}
if (options.overlayPriceScales) {
const sourceArrays = Array.from(this._private__overlaySourcesByScaleId.values());
for (const arr of sourceArrays) {
const priceScale = ensureNotNull(arr[0]._internal_priceScale());
priceScale._internal_applyOptions(options.overlayPriceScales);
if (options.localization) {
priceScale._internal_updateFormatter();
}
}
}
}
_internal_priceScaleById(id) {
switch (id) {
case "left": {
return this._private__leftPriceScale;
}
case "right": {
return this._private__rightPriceScale;
}
}
if (this._private__overlaySourcesByScaleId.has(id)) {
return ensureDefined(this._private__overlaySourcesByScaleId.get(id))[0]._internal_priceScale();
}
return null;
}
_internal_destroy() {
this._internal_model()._internal_priceScalesOptionsChanged()._internal_unsubscribeAll(this);
this._private__leftPriceScale._internal_modeChanged()._internal_unsubscribeAll(this);
this._private__rightPriceScale._internal_modeChanged()._internal_unsubscribeAll(this);
this._private__dataSources.forEach((source) => {
if (source._internal_destroy) {
source._internal_destroy();
}
});
this._private__destroyed._internal_fire();
}
_internal_stretchFactor() {
return this._private__stretchFactor;
}
_internal_setStretchFactor(factor) {
this._private__stretchFactor = factor;
}
_internal_model() {
return this._private__model;
}
_internal_width() {
return this._private__width;
}
_internal_height() {
return this._private__height;
}
_internal_setWidth(width) {
this._private__width = width;
this._internal_updateAllSources();
}
_internal_setHeight(height) {
this._private__height = height;
this._private__leftPriceScale._internal_setHeight(height);
this._private__rightPriceScale._internal_setHeight(height);
this._private__dataSources.forEach((ds) => {
if (this._internal_isOverlay(ds)) {
const priceScale = ds._internal_priceScale();
if (priceScale !== null) {
priceScale._internal_setHeight(height);
}
}
});
this._internal_updateAllSources();
}
_internal_dataSources() {
return this._private__dataSources;
}
_internal_isOverlay(source) {
const priceScale = source._internal_priceScale();
if (priceScale === null) {
return true;
}
return this._private__leftPriceScale !== priceScale && this._private__rightPriceScale !== priceScale;
}
_internal_addDataSource(source, targetScaleId, zOrder) {
const targetZOrder = zOrder !== void 0 ? zOrder : this._private__getZOrderMinMax()._internal_maxZOrder + 1;
this._private__insertDataSource(source, targetScaleId, targetZOrder);
}
_internal_removeDataSource(source) {
const index = this._private__dataSources.indexOf(source);
assert(index !== -1, "removeDataSource: invalid data source");
this._private__dataSources.splice(index, 1);
const priceScaleId = ensureNotNull(source._internal_priceScale())._internal_id();
if (this._private__overlaySourcesByScaleId.has(priceScaleId)) {
const overlaySources = ensureDefined(this._private__overlaySourcesByScaleId.get(priceScaleId));
const overlayIndex = overlaySources.indexOf(source);
if (overlayIndex !== -1) {
overlaySources.splice(overlayIndex, 1);
if (overlaySources.length === 0) {
this._private__overlaySourcesByScaleId.delete(priceScaleId);
}
}
}
const priceScale = source._internal_priceScale();
if (priceScale && priceScale._internal_dataSources().indexOf(source) >= 0) {
priceScale._internal_removeDataSource(source);
}
if (priceScale !== null) {
priceScale._internal_invalidateSourcesCache();
this._internal_recalculatePriceScale(priceScale);
}
this._private__cachedOrderedSources = null;
}
_internal_priceScalePosition(priceScale) {
if (priceScale === this._private__leftPriceScale) {
return "left";
}
if (priceScale === this._private__rightPriceScale) {
return "right";
}
return "overlay";
}
_internal_leftPriceScale() {
return this._private__leftPriceScale;
}
_internal_rightPriceScale() {
return this._private__rightPriceScale;
}
_internal_startScalePrice(priceScale, x) {
priceScale._internal_startScale(x);
}
_internal_scalePriceTo(priceScale, x) {
priceScale._internal_scaleTo(x);
this._internal_updateAllSources();
}
_internal_endScalePrice(priceScale) {
priceScale._internal_endScale();
}
_internal_startScrollPrice(priceScale, x) {
priceScale._internal_startScroll(x);
}
_internal_scrollPriceTo(priceScale, x) {
priceScale._internal_scrollTo(x);
this._internal_updateAllSources();
}
_internal_endScrollPrice(priceScale) {
priceScale._internal_endScroll();
}
_internal_updateAllSources() {
this._private__dataSources.forEach((source) => {
source._internal_updateAllViews();
});
}
_internal_defaultPriceScale() {
let priceScale = null;
if (this._private__model._internal_options().rightPriceScale.visible && this._private__rightPriceScale._internal_dataSources().length !== 0) {
priceScale = this._private__rightPriceScale;
} else if (this._private__model._internal_options().leftPriceScale.visible && this._private__leftPriceScale._internal_dataSources().length !== 0) {
priceScale = this._private__leftPriceScale;
} else if (this._private__dataSources.length !== 0) {
priceScale = this._private__dataSources[0]._internal_priceScale();
}
if (priceScale === null) {
priceScale = this._private__rightPriceScale;
}
return priceScale;
}
_internal_defaultVisiblePriceScale() {
let priceScale = null;
if (this._private__model._internal_options().rightPriceScale.visible) {
priceScale = this._private__rightPriceScale;
} else if (this._private__model._internal_options().leftPriceScale.visible) {
priceScale = this._private__leftPriceScale;
}
return priceScale;
}
_internal_recalculatePriceScale(priceScale) {
if (priceScale === null || !priceScale._internal_isAutoScale()) {
return;
}
this._private__recalculatePriceScaleImpl(priceScale);
}
_internal_resetPriceScale(priceScale) {
const visibleBars = this._private__timeScale._internal_visibleStrictRange();
priceScale._internal_setMode({ _internal_autoScale: true });
if (visibleBars !== null) {
priceScale._internal_recalculatePriceRange(visibleBars);
}
this._internal_updateAllSources();
}
_internal_momentaryAutoScale() {
this._private__recalculatePriceScaleImpl(this._private__leftPriceScale);
this._private__recalculatePriceScaleImpl(this._private__rightPriceScale);
}
_internal_recalculate() {
this._internal_recalculatePriceScale(this._private__leftPriceScale);
this._internal_recalculatePriceScale(this._private__rightPriceScale);
this._private__dataSources.forEach((ds) => {
if (this._internal_isOverlay(ds)) {
this._internal_recalculatePriceScale(ds._internal_priceScale());
}
});
this._internal_updateAllSources();
this._private__model._internal_lightUpdate();
}
_internal_orderedSources() {
if (this._private__cachedOrderedSources === null) {
this._private__cachedOrderedSources = sortSources(this._private__dataSources);
}
return this._private__cachedOrderedSources;
}
_internal_onDestroyed() {
return this._private__destroyed;
}
_internal_grid() {
return this._private__grid;
}
_private__recalculatePriceScaleImpl(priceScale) {
const sourceForAutoScale = priceScale._internal_sourcesForAutoScale();
if (sourceForAutoScale && sourceForAutoScale.length > 0 && !this._private__timeScale._internal_isEmpty()) {
const visibleBars = this._private__timeScale._internal_visibleStrictRange();
if (visibleBars !== null) {
priceScale._internal_recalculatePriceRange(visibleBars);
}
}
priceScale._internal_updateAllViews();
}
_private__getZOrderMinMax() {
const sources = this._internal_orderedSources();
if (sources.length === 0) {
return { _internal_minZOrder: 0, _internal_maxZOrder: 0 };
}
let minZOrder = 0;
let maxZOrder = 0;
for (let j = 0; j < sources.length; j++) {
const ds = sources[j];
const zOrder = ds._internal_zorder();
if (zOrder !== null) {
if (zOrder < minZOrder) {
minZOrder = zOrder;
}
if (zOrder > maxZOrder) {
maxZOrder = zOrder;
}
}
}
return { _internal_minZOrder: minZOrder, _internal_maxZOrder: maxZOrder };
}
_private__insertDataSource(source, priceScaleId, zOrder) {
let priceScale = this._internal_priceScaleById(priceScaleId);
if (priceScale === null) {
priceScale = this._private__createPriceScale(priceScaleId, this._private__model._internal_options().overlayPriceScales);
}
this._private__dataSources.push(source);
if (!isDefaultPriceScale(priceScaleId)) {
const overlaySources = this._private__overlaySourcesByScaleId.get(priceScaleId) || [];
overlaySources.push(source);
this._private__overlaySourcesByScaleId.set(priceScaleId, overlaySources);
}
priceScale._internal_addDataSource(source);
source._internal_setPriceScale(priceScale);
source._internal_setZorder(zOrder);
this._internal_recalculatePriceScale(priceScale);
this._private__cachedOrderedSources = null;
}
_private__onPriceScaleModeChanged(priceScale, oldMode, newMode) {
if (oldMode._internal_mode === newMode._internal_mode) {
return;
}
this._private__recalculatePriceScaleImpl(priceScale);
}
_private__createPriceScale(id, options) {
const actualOptions = Object.assign({ visible: true, autoScale: true }, clone(options));
const priceScale = new PriceScale(id, actualOptions, this._private__model._internal_options().layout, this._private__model._internal_options().localization);
priceScale._internal_setHeight(this._internal_height());
return priceScale;
}
};
var FormattedLabelsCache = class {
constructor(format, horzScaleBehavior, size3 = 50) {
this._private__actualSize = 0;
this._private__usageTick = 1;
this._private__oldestTick = 1;
this._private__cache = /* @__PURE__ */ new Map();
this._private__tick2Labels = /* @__PURE__ */ new Map();
this._private__format = format;
this._private__horzScaleBehavior = horzScaleBehavior;
this._private__maxSize = size3;
}
_internal_format(tickMark) {
const time = tickMark.time;
const cacheKey = this._private__horzScaleBehavior.cacheKey(time);
const tick = this._private__cache.get(cacheKey);
if (tick !== void 0) {
return tick._internal_string;
}
if (this._private__actualSize === this._private__maxSize) {
const oldestValue = this._private__tick2Labels.get(this._private__oldestTick);
this._private__tick2Labels.delete(this._private__oldestTick);
this._private__cache.delete(ensureDefined(oldestValue));
this._private__oldestTick++;
this._private__actualSize--;
}
const str = this._private__format(tickMark);
this._private__cache.set(cacheKey, { _internal_string: str, _internal_tick: this._private__usageTick });
this._private__tick2Labels.set(this._private__usageTick, cacheKey);
this._private__actualSize++;
this._private__usageTick++;
return str;
}
};
var RangeImpl = class {
constructor(left, right) {
assert(left <= right, "right should be >= left");
this._private__left = left;
this._private__right = right;
}
_internal_left() {
return this._private__left;
}
_internal_right() {
return this._private__right;
}
_internal_count() {
return this._private__right - this._private__left + 1;
}
_internal_contains(index) {
return this._private__left <= index && index <= this._private__right;
}
_internal_equals(other) {
return this._private__left === other._internal_left() && this._private__right === other._internal_right();
}
};
function areRangesEqual(first, second) {
if (first === null || second === null) {
return first === second;
}
return first._internal_equals(second);
}
var TickMarks = class {
constructor() {
this._private__marksByWeight = /* @__PURE__ */ new Map();
this._private__cache = null;
this._private__uniformDistribution = false;
}
_internal_setUniformDistribution(val) {
this._private__uniformDistribution = val;
this._private__cache = null;
}
_internal_setTimeScalePoints(newPoints, firstChangedPointIndex) {
this._private__removeMarksSinceIndex(firstChangedPointIndex);
this._private__cache = null;
for (let index = firstChangedPointIndex; index < newPoints.length; ++index) {
const point = newPoints[index];
let marksForWeight = this._private__marksByWeight.get(point.timeWeight);
if (marksForWeight === void 0) {
marksForWeight = [];
this._private__marksByWeight.set(point.timeWeight, marksForWeight);
}
marksForWeight.push({
index,
time: point.time,
weight: point.timeWeight,
originalTime: point.originalTime
});
}
}
_internal_build(spacing, maxWidth) {
const maxIndexesPerMark = Math.ceil(maxWidth / spacing);
if (this._private__cache === null || this._private__cache._internal_maxIndexesPerMark !== maxIndexesPerMark) {
this._private__cache = {
_internal_marks: this._private__buildMarksImpl(maxIndexesPerMark),
_internal_maxIndexesPerMark: maxIndexesPerMark
};
}
return this._private__cache._internal_marks;
}
_private__removeMarksSinceIndex(sinceIndex) {
if (sinceIndex === 0) {
this._private__marksByWeight.clear();
return;
}
const weightsToClear = [];
this._private__marksByWeight.forEach((marks, timeWeight) => {
if (sinceIndex <= marks[0].index) {
weightsToClear.push(timeWeight);
} else {
marks.splice(lowerBound(marks, sinceIndex, (tm) => tm.index < sinceIndex), Infinity);
}
});
for (const weight of weightsToClear) {
this._private__marksByWeight.delete(weight);
}
}
_private__buildMarksImpl(maxIndexesPerMark) {
let marks = [];
for (const weight of Array.from(this._private__marksByWeight.keys()).sort((a, b) => b - a)) {
if (!this._private__marksByWeight.get(weight)) {
continue;
}
const prevMarks = marks;
marks = [];
const prevMarksLength = prevMarks.length;
let prevMarksPointer = 0;
const currentWeight = ensureDefined(this._private__marksByWeight.get(weight));
const currentWeightLength = currentWeight.length;
let rightIndex = Infinity;
let leftIndex = -Infinity;
for (let i = 0; i < currentWeightLength; i++) {
const mark = currentWeight[i];
const currentIndex = mark.index;
while (prevMarksPointer < prevMarksLength) {
const lastMark = prevMarks[prevMarksPointer];
const lastIndex = lastMark.index;
if (lastIndex < currentIndex) {
prevMarksPointer++;
marks.push(lastMark);
leftIndex = lastIndex;
rightIndex = Infinity;
} else {
rightIndex = lastIndex;
break;
}
}
if (rightIndex - currentIndex >= maxIndexesPerMark && currentIndex - leftIndex >= maxIndexesPerMark) {
marks.push(mark);
leftIndex = currentIndex;
} else {
if (this._private__uniformDistribution) {
return prevMarks;
}
}
}
for (; prevMarksPointer < prevMarksLength; prevMarksPointer++) {
marks.push(prevMarks[prevMarksPointer]);
}
}
return marks;
}
};
var TimeScaleVisibleRange = class _TimeScaleVisibleRange {
constructor(logicalRange) {
this._private__logicalRange = logicalRange;
}
_internal_strictRange() {
if (this._private__logicalRange === null) {
return null;
}
return new RangeImpl(Math.floor(this._private__logicalRange._internal_left()), Math.ceil(this._private__logicalRange._internal_right()));
}
_internal_logicalRange() {
return this._private__logicalRange;
}
static _internal_invalid() {
return new _TimeScaleVisibleRange(null);
}
};
var defaultTickMarkMaxCharacterLength = 8;
function markWithGreaterWeight(a, b) {
return a.weight > b.weight ? a : b;
}
var TimeScale = class {
constructor(model, options, localizationOptions, horzScaleBehavior) {
this._private__width = 0;
this._private__baseIndexOrNull = null;
this._private__points = [];
this._private__scrollStartPoint = null;
this._private__scaleStartPoint = null;
this._private__tickMarks = new TickMarks();
this._private__formattedByWeight = /* @__PURE__ */ new Map();
this._private__visibleRange = TimeScaleVisibleRange._internal_invalid();
this._private__visibleRangeInvalidated = true;
this._private__visibleBarsChanged = new Delegate();
this._private__logicalRangeChanged = new Delegate();
this._private__optionsApplied = new Delegate();
this._private__commonTransitionStartState = null;
this._private__timeMarksCache = null;
this._private__labels = [];
this._private__options = options;
this._private__localizationOptions = localizationOptions;
this._private__rightOffset = options.rightOffset;
this._private__barSpacing = options.barSpacing;
this._private__model = model;
this._private__horzScaleBehavior = horzScaleBehavior;
this._private__updateDateTimeFormatter();
this._private__tickMarks._internal_setUniformDistribution(options.uniformDistribution);
}
_internal_options() {
return this._private__options;
}
_internal_applyLocalizationOptions(localizationOptions) {
merge(this._private__localizationOptions, localizationOptions);
this._private__invalidateTickMarks();
this._private__updateDateTimeFormatter();
}
_internal_applyOptions(options, localizationOptions) {
var _a;
merge(this._private__options, options);
if (this._private__options.fixLeftEdge) {
this._private__doFixLeftEdge();
}
if (this._private__options.fixRightEdge) {
this._private__doFixRightEdge();
}
if (options.barSpacing !== void 0) {
this._private__model._internal_setBarSpacing(options.barSpacing);
}
if (options.rightOffset !== void 0) {
this._private__model._internal_setRightOffset(options.rightOffset);
}
if (options.minBarSpacing !== void 0) {
this._private__model._internal_setBarSpacing((_a = options.barSpacing) !== null && _a !== void 0 ? _a : this._private__barSpacing);
}
this._private__invalidateTickMarks();
this._private__updateDateTimeFormatter();
this._private__optionsApplied._internal_fire();
}
_internal_indexToTime(index) {
var _a, _b;
return (_b = (_a = this._private__points[index]) === null || _a === void 0 ? void 0 : _a.time) !== null && _b !== void 0 ? _b : null;
}
_internal_indexToTimeScalePoint(index) {
var _a;
return (_a = this._private__points[index]) !== null && _a !== void 0 ? _a : null;
}
_internal_timeToIndex(time, findNearest) {
if (this._private__points.length < 1) {
return null;
}
if (this._private__horzScaleBehavior.key(time) > this._private__horzScaleBehavior.key(this._private__points[this._private__points.length - 1].time)) {
return findNearest ? this._private__points.length - 1 : null;
}
const index = lowerBound(this._private__points, this._private__horzScaleBehavior.key(time), (a, b) => this._private__horzScaleBehavior.key(a.time) < b);
if (this._private__horzScaleBehavior.key(time) < this._private__horzScaleBehavior.key(this._private__points[index].time)) {
return findNearest ? index : null;
}
return index;
}
_internal_isEmpty() {
return this._private__width === 0 || this._private__points.length === 0 || this._private__baseIndexOrNull === null;
}
_internal_hasPoints() {
return this._private__points.length > 0;
}
// strict range: integer indices of the bars in the visible range rounded in more wide direction
_internal_visibleStrictRange() {
this._private__updateVisibleRange();
return this._private__visibleRange._internal_strictRange();
}
_internal_visibleLogicalRange() {
this._private__updateVisibleRange();
return this._private__visibleRange._internal_logicalRange();
}
_internal_visibleTimeRange() {
const visibleBars = this._internal_visibleStrictRange();
if (visibleBars === null) {
return null;
}
const range = {
from: visibleBars._internal_left(),
to: visibleBars._internal_right()
};
return this._internal_timeRangeForLogicalRange(range);
}
_internal_timeRangeForLogicalRange(range) {
const from = Math.round(range.from);
const to = Math.round(range.to);
const firstIndex = ensureNotNull(this._private__firstIndex());
const lastIndex = ensureNotNull(this._private__lastIndex());
return {
from: ensureNotNull(this._internal_indexToTimeScalePoint(Math.max(firstIndex, from))),
to: ensureNotNull(this._internal_indexToTimeScalePoint(Math.min(lastIndex, to)))
};
}
_internal_logicalRangeForTimeRange(range) {
return {
from: ensureNotNull(this._internal_timeToIndex(range.from, true)),
to: ensureNotNull(this._internal_timeToIndex(range.to, true))
};
}
_internal_width() {
return this._private__width;
}
_internal_setWidth(newWidth) {
if (!isFinite(newWidth) || newWidth <= 0) {
return;
}
if (this._private__width === newWidth) {
return;
}
const previousVisibleRange = this._internal_visibleLogicalRange();
const oldWidth = this._private__width;
this._private__width = newWidth;
this._private__visibleRangeInvalidated = true;
if (this._private__options.lockVisibleTimeRangeOnResize && oldWidth !== 0) {
const newBarSpacing = this._private__barSpacing * newWidth / oldWidth;
this._private__barSpacing = newBarSpacing;
}
if (this._private__options.fixLeftEdge) {
if (previousVisibleRange !== null && previousVisibleRange._internal_left() <= 0) {
const delta = oldWidth - newWidth;
this._private__rightOffset -= Math.round(delta / this._private__barSpacing) + 1;
this._private__visibleRangeInvalidated = true;
}
}
this._private__correctBarSpacing();
this._private__correctOffset();
}
_internal_indexToCoordinate(index) {
if (this._internal_isEmpty() || !isInteger(index)) {
return 0;
}
const baseIndex = this._internal_baseIndex();
const deltaFromRight = baseIndex + this._private__rightOffset - index;
const coordinate = this._private__width - (deltaFromRight + 0.5) * this._private__barSpacing - 1;
return coordinate;
}
_internal_indexesToCoordinates(points, visibleRange) {
const baseIndex = this._internal_baseIndex();
const indexFrom = visibleRange === void 0 ? 0 : visibleRange.from;
const indexTo = visibleRange === void 0 ? points.length : visibleRange.to;
for (let i = indexFrom; i < indexTo; i++) {
const index = points[i]._internal_time;
const deltaFromRight = baseIndex + this._private__rightOffset - index;
const coordinate = this._private__width - (deltaFromRight + 0.5) * this._private__barSpacing - 1;
points[i]._internal_x = coordinate;
}
}
_internal_coordinateToIndex(x) {
return Math.ceil(this._private__coordinateToFloatIndex(x));
}
_internal_setRightOffset(offset) {
this._private__visibleRangeInvalidated = true;
this._private__rightOffset = offset;
this._private__correctOffset();
this._private__model._internal_recalculateAllPanes();
this._private__model._internal_lightUpdate();
}
_internal_barSpacing() {
return this._private__barSpacing;
}
_internal_setBarSpacing(newBarSpacing) {
this._private__setBarSpacing(newBarSpacing);
this._private__correctOffset();
this._private__model._internal_recalculateAllPanes();
this._private__model._internal_lightUpdate();
}
_internal_rightOffset() {
return this._private__rightOffset;
}
// eslint-disable-next-line complexity
_internal_marks() {
if (this._internal_isEmpty()) {
return null;
}
if (this._private__timeMarksCache !== null) {
return this._private__timeMarksCache;
}
const spacing = this._private__barSpacing;
const fontSize = this._private__model._internal_options().layout.fontSize;
const pixelsPer8Characters = (fontSize + 4) * 5;
const pixelsPerCharacter = pixelsPer8Characters / defaultTickMarkMaxCharacterLength;
const maxLabelWidth = pixelsPerCharacter * (this._private__options.tickMarkMaxCharacterLength || defaultTickMarkMaxCharacterLength);
const indexPerLabel = Math.round(maxLabelWidth / spacing);
const visibleBars = ensureNotNull(this._internal_visibleStrictRange());
const firstBar = Math.max(visibleBars._internal_left(), visibleBars._internal_left() - indexPerLabel);
const lastBar = Math.max(visibleBars._internal_right(), visibleBars._internal_right() - indexPerLabel);
const items = this._private__tickMarks._internal_build(spacing, maxLabelWidth);
const earliestIndexOfSecondLabel = this._private__firstIndex() + indexPerLabel;
const indexOfSecondLastLabel = this._private__lastIndex() - indexPerLabel;
const isAllScalingAndScrollingDisabled = this._private__isAllScalingAndScrollingDisabled();
const isLeftEdgeFixed = this._private__options.fixLeftEdge || isAllScalingAndScrollingDisabled;
const isRightEdgeFixed = this._private__options.fixRightEdge || isAllScalingAndScrollingDisabled;
let targetIndex = 0;
for (const tm of items) {
if (!(firstBar <= tm.index && tm.index <= lastBar)) {
continue;
}
let label;
if (targetIndex < this._private__labels.length) {
label = this._private__labels[targetIndex];
label.coord = this._internal_indexToCoordinate(tm.index);
label.label = this._private__formatLabel(tm);
label.weight = tm.weight;
} else {
label = {
needAlignCoordinate: false,
coord: this._internal_indexToCoordinate(tm.index),
label: this._private__formatLabel(tm),
weight: tm.weight
};
this._private__labels.push(label);
}
if (this._private__barSpacing > maxLabelWidth / 2 && !isAllScalingAndScrollingDisabled) {
label.needAlignCoordinate = false;
} else {
label.needAlignCoordinate = isLeftEdgeFixed && tm.index <= earliestIndexOfSecondLabel || isRightEdgeFixed && tm.index >= indexOfSecondLastLabel;
}
targetIndex++;
}
this._private__labels.length = targetIndex;
this._private__timeMarksCache = this._private__labels;
return this._private__labels;
}
_internal_restoreDefault() {
this._private__visibleRangeInvalidated = true;
this._internal_setBarSpacing(this._private__options.barSpacing);
this._internal_setRightOffset(this._private__options.rightOffset);
}
_internal_setBaseIndex(baseIndex) {
this._private__visibleRangeInvalidated = true;
this._private__baseIndexOrNull = baseIndex;
this._private__correctOffset();
this._private__doFixLeftEdge();
}
/**
* Zoom in/out the scale around a `zoomPoint` on `scale` value.
*
* @param zoomPoint - X coordinate of the point to apply the zoom.
* If `rightBarStaysOnScroll` option is disabled, then will be used to restore right offset.
* @param scale - Zoom value (in 1/10 parts of current bar spacing).
* Negative value means zoom out, positive - zoom in.
*/
_internal_zoom(zoomPoint, scale) {
const floatIndexAtZoomPoint = this._private__coordinateToFloatIndex(zoomPoint);
const barSpacing = this._internal_barSpacing();
const newBarSpacing = barSpacing + scale * (barSpacing / 10);
this._internal_setBarSpacing(newBarSpacing);
if (!this._private__options.rightBarStaysOnScroll) {
this._internal_setRightOffset(this._internal_rightOffset() + (floatIndexAtZoomPoint - this._private__coordinateToFloatIndex(zoomPoint)));
}
}
_internal_startScale(x) {
if (this._private__scrollStartPoint) {
this._internal_endScroll();
}
if (this._private__scaleStartPoint !== null || this._private__commonTransitionStartState !== null) {
return;
}
if (this._internal_isEmpty()) {
return;
}
this._private__scaleStartPoint = x;
this._private__saveCommonTransitionsStartState();
}
_internal_scaleTo(x) {
if (this._private__commonTransitionStartState === null) {
return;
}
const startLengthFromRight = clamp(this._private__width - x, 0, this._private__width);
const currentLengthFromRight = clamp(this._private__width - ensureNotNull(this._private__scaleStartPoint), 0, this._private__width);
if (startLengthFromRight === 0 || currentLengthFromRight === 0) {
return;
}
this._internal_setBarSpacing(this._private__commonTransitionStartState._internal_barSpacing * startLengthFromRight / currentLengthFromRight);
}
_internal_endScale() {
if (this._private__scaleStartPoint === null) {
return;
}
this._private__scaleStartPoint = null;
this._private__clearCommonTransitionsStartState();
}
_internal_startScroll(x) {
if (this._private__scrollStartPoint !== null || this._private__commonTransitionStartState !== null) {
return;
}
if (this._internal_isEmpty()) {
return;
}
this._private__scrollStartPoint = x;
this._private__saveCommonTransitionsStartState();
}
_internal_scrollTo(x) {
if (this._private__scrollStartPoint === null) {
return;
}
const shiftInLogical = (this._private__scrollStartPoint - x) / this._internal_barSpacing();
this._private__rightOffset = ensureNotNull(this._private__commonTransitionStartState)._internal_rightOffset + shiftInLogical;
this._private__visibleRangeInvalidated = true;
this._private__correctOffset();
}
_internal_endScroll() {
if (this._private__scrollStartPoint === null) {
return;
}
this._private__scrollStartPoint = null;
this._private__clearCommonTransitionsStartState();
}
_internal_scrollToRealTime() {
this._internal_scrollToOffsetAnimated(this._private__options.rightOffset);
}
_internal_scrollToOffsetAnimated(offset, animationDuration = 400) {
if (!isFinite(offset)) {
throw new RangeError("offset is required and must be finite number");
}
if (!isFinite(animationDuration) || animationDuration <= 0) {
throw new RangeError("animationDuration (optional) must be finite positive number");
}
const source = this._private__rightOffset;
const animationStart = performance.now();
this._private__model._internal_setTimeScaleAnimation({
_internal_finished: (time) => (time - animationStart) / animationDuration >= 1,
_internal_getPosition: (time) => {
const animationProgress = (time - animationStart) / animationDuration;
const finishAnimation = animationProgress >= 1;
return finishAnimation ? offset : source + (offset - source) * animationProgress;
}
});
}
_internal_update(newPoints, firstChangedPointIndex) {
this._private__visibleRangeInvalidated = true;
this._private__points = newPoints;
this._private__tickMarks._internal_setTimeScalePoints(newPoints, firstChangedPointIndex);
this._private__correctOffset();
}
_internal_visibleBarsChanged() {
return this._private__visibleBarsChanged;
}
_internal_logicalRangeChanged() {
return this._private__logicalRangeChanged;
}
_internal_optionsApplied() {
return this._private__optionsApplied;
}
_internal_baseIndex() {
return this._private__baseIndexOrNull || 0;
}
_internal_setVisibleRange(range) {
const length = range._internal_count();
this._private__setBarSpacing(this._private__width / length);
this._private__rightOffset = range._internal_right() - this._internal_baseIndex();
this._private__correctOffset();
this._private__visibleRangeInvalidated = true;
this._private__model._internal_recalculateAllPanes();
this._private__model._internal_lightUpdate();
}
_internal_fitContent() {
const first = this._private__firstIndex();
const last = this._private__lastIndex();
if (first === null || last === null) {
return;
}
this._internal_setVisibleRange(new RangeImpl(first, last + this._private__options.rightOffset));
}
_internal_setLogicalRange(range) {
const barRange = new RangeImpl(range.from, range.to);
this._internal_setVisibleRange(barRange);
}
_internal_formatDateTime(timeScalePoint) {
if (this._private__localizationOptions.timeFormatter !== void 0) {
return this._private__localizationOptions.timeFormatter(timeScalePoint.originalTime);
}
return this._private__horzScaleBehavior.formatHorzItem(timeScalePoint.time);
}
_private__isAllScalingAndScrollingDisabled() {
const { handleScroll, handleScale } = this._private__model._internal_options();
return !handleScroll.horzTouchDrag && !handleScroll.mouseWheel && !handleScroll.pressedMouseMove && !handleScroll.vertTouchDrag && !handleScale.axisDoubleClickReset.time && !handleScale.axisPressedMouseMove.time && !handleScale.mouseWheel && !handleScale.pinch;
}
_private__firstIndex() {
return this._private__points.length === 0 ? null : 0;
}
_private__lastIndex() {
return this._private__points.length === 0 ? null : this._private__points.length - 1;
}
_private__rightOffsetForCoordinate(x) {
return (this._private__width - 1 - x) / this._private__barSpacing;
}
_private__coordinateToFloatIndex(x) {
const deltaFromRight = this._private__rightOffsetForCoordinate(x);
const baseIndex = this._internal_baseIndex();
const index = baseIndex + this._private__rightOffset - deltaFromRight;
return Math.round(index * 1e6) / 1e6;
}
_private__setBarSpacing(newBarSpacing) {
const oldBarSpacing = this._private__barSpacing;
this._private__barSpacing = newBarSpacing;
this._private__correctBarSpacing();
if (oldBarSpacing !== this._private__barSpacing) {
this._private__visibleRangeInvalidated = true;
this._private__resetTimeMarksCache();
}
}
_private__updateVisibleRange() {
if (!this._private__visibleRangeInvalidated) {
return;
}
this._private__visibleRangeInvalidated = false;
if (this._internal_isEmpty()) {
this._private__setVisibleRange(TimeScaleVisibleRange._internal_invalid());
return;
}
const baseIndex = this._internal_baseIndex();
const newBarsLength = this._private__width / this._private__barSpacing;
const rightBorder = this._private__rightOffset + baseIndex;
const leftBorder = rightBorder - newBarsLength + 1;
const logicalRange = new RangeImpl(leftBorder, rightBorder);
this._private__setVisibleRange(new TimeScaleVisibleRange(logicalRange));
}
_private__correctBarSpacing() {
const minBarSpacing = this._private__minBarSpacing();
if (this._private__barSpacing < minBarSpacing) {
this._private__barSpacing = minBarSpacing;
this._private__visibleRangeInvalidated = true;
}
if (this._private__width !== 0) {
const maxBarSpacing = this._private__width * 0.5;
if (this._private__barSpacing > maxBarSpacing) {
this._private__barSpacing = maxBarSpacing;
this._private__visibleRangeInvalidated = true;
}
}
}
_private__minBarSpacing() {
if (this._private__options.fixLeftEdge && this._private__options.fixRightEdge && this._private__points.length !== 0) {
return this._private__width / this._private__points.length;
}
return this._private__options.minBarSpacing;
}
_private__correctOffset() {
const minRightOffset = this._private__minRightOffset();
if (minRightOffset !== null && this._private__rightOffset < minRightOffset) {
this._private__rightOffset = minRightOffset;
this._private__visibleRangeInvalidated = true;
}
const maxRightOffset = this._private__maxRightOffset();
if (this._private__rightOffset > maxRightOffset) {
this._private__rightOffset = maxRightOffset;
this._private__visibleRangeInvalidated = true;
}
}
_private__minRightOffset() {
const firstIndex = this._private__firstIndex();
const baseIndex = this._private__baseIndexOrNull;
if (firstIndex === null || baseIndex === null) {
return null;
}
const barsEstimation = this._private__options.fixLeftEdge ? this._private__width / this._private__barSpacing : Math.min(2, this._private__points.length);
return firstIndex - baseIndex - 1 + barsEstimation;
}
_private__maxRightOffset() {
return this._private__options.fixRightEdge ? 0 : this._private__width / this._private__barSpacing - Math.min(2, this._private__points.length);
}
_private__saveCommonTransitionsStartState() {
this._private__commonTransitionStartState = {
_internal_barSpacing: this._internal_barSpacing(),
_internal_rightOffset: this._internal_rightOffset()
};
}
_private__clearCommonTransitionsStartState() {
this._private__commonTransitionStartState = null;
}
_private__formatLabel(tickMark) {
let formatter = this._private__formattedByWeight.get(tickMark.weight);
if (formatter === void 0) {
formatter = new FormattedLabelsCache((mark) => {
return this._private__formatLabelImpl(mark);
}, this._private__horzScaleBehavior);
this._private__formattedByWeight.set(tickMark.weight, formatter);
}
return formatter._internal_format(tickMark);
}
_private__formatLabelImpl(tickMark) {
return this._private__horzScaleBehavior.formatTickmark(tickMark, this._private__localizationOptions);
}
_private__setVisibleRange(newVisibleRange) {
const oldVisibleRange = this._private__visibleRange;
this._private__visibleRange = newVisibleRange;
if (!areRangesEqual(oldVisibleRange._internal_strictRange(), this._private__visibleRange._internal_strictRange())) {
this._private__visibleBarsChanged._internal_fire();
}
if (!areRangesEqual(oldVisibleRange._internal_logicalRange(), this._private__visibleRange._internal_logicalRange())) {
this._private__logicalRangeChanged._internal_fire();
}
this._private__resetTimeMarksCache();
}
_private__resetTimeMarksCache() {
this._private__timeMarksCache = null;
}
_private__invalidateTickMarks() {
this._private__resetTimeMarksCache();
this._private__formattedByWeight.clear();
}
_private__updateDateTimeFormatter() {
this._private__horzScaleBehavior.updateFormatter(this._private__localizationOptions);
}
_private__doFixLeftEdge() {
if (!this._private__options.fixLeftEdge) {
return;
}
const firstIndex = this._private__firstIndex();
if (firstIndex === null) {
return;
}
const visibleRange = this._internal_visibleStrictRange();
if (visibleRange === null) {
return;
}
const delta = visibleRange._internal_left() - firstIndex;
if (delta < 0) {
const leftEdgeOffset = this._private__rightOffset - delta - 1;
this._internal_setRightOffset(leftEdgeOffset);
}
this._private__correctBarSpacing();
}
_private__doFixRightEdge() {
this._private__correctOffset();
this._private__correctBarSpacing();
}
};
var MediaCoordinatesPaneRenderer = class {
_internal_draw(target, isHovered, hitTestData) {
target.useMediaCoordinateSpace((scope) => this._internal__drawImpl(scope, isHovered, hitTestData));
}
_internal_drawBackground(target, isHovered, hitTestData) {
target.useMediaCoordinateSpace((scope) => this._internal__drawBackgroundImpl(scope, isHovered, hitTestData));
}
_internal__drawBackgroundImpl(renderingScope, isHovered, hitTestData) {
}
};
var WatermarkRenderer = class extends MediaCoordinatesPaneRenderer {
constructor(data) {
super();
this._private__metricsCache = /* @__PURE__ */ new Map();
this._private__data = data;
}
_internal__drawImpl(renderingScope) {
}
_internal__drawBackgroundImpl(renderingScope) {
if (!this._private__data._internal_visible) {
return;
}
const { context: ctx, mediaSize } = renderingScope;
let textHeight = 0;
for (const line of this._private__data._internal_lines) {
if (line._internal_text.length === 0) {
continue;
}
ctx.font = line._internal_font;
const textWidth = this._private__metrics(ctx, line._internal_text);
if (textWidth > mediaSize.width) {
line._internal_zoom = mediaSize.width / textWidth;
} else {
line._internal_zoom = 1;
}
textHeight += line._internal_lineHeight * line._internal_zoom;
}
let vertOffset = 0;
switch (this._private__data._internal_vertAlign) {
case "top":
vertOffset = 0;
break;
case "center":
vertOffset = Math.max((mediaSize.height - textHeight) / 2, 0);
break;
case "bottom":
vertOffset = Math.max(mediaSize.height - textHeight, 0);
break;
}
ctx.fillStyle = this._private__data._internal_color;
for (const line of this._private__data._internal_lines) {
ctx.save();
let horzOffset = 0;
switch (this._private__data._internal_horzAlign) {
case "left":
ctx.textAlign = "left";
horzOffset = line._internal_lineHeight / 2;
break;
case "center":
ctx.textAlign = "center";
horzOffset = mediaSize.width / 2;
break;
case "right":
ctx.textAlign = "right";
horzOffset = mediaSize.width - 1 - line._internal_lineHeight / 2;
break;
}
ctx.translate(horzOffset, vertOffset);
ctx.textBaseline = "top";
ctx.font = line._internal_font;
ctx.scale(line._internal_zoom, line._internal_zoom);
ctx.fillText(line._internal_text, 0, line._internal_vertOffset);
ctx.restore();
vertOffset += line._internal_lineHeight * line._internal_zoom;
}
}
_private__metrics(ctx, text) {
const fontCache = this._private__fontCache(ctx.font);
let result = fontCache.get(text);
if (result === void 0) {
result = ctx.measureText(text).width;
fontCache.set(text, result);
}
return result;
}
_private__fontCache(font) {
let fontCache = this._private__metricsCache.get(font);
if (fontCache === void 0) {
fontCache = /* @__PURE__ */ new Map();
this._private__metricsCache.set(font, fontCache);
}
return fontCache;
}
};
var WatermarkPaneView = class {
constructor(source) {
this._private__invalidated = true;
this._private__rendererData = {
_internal_visible: false,
_internal_color: "",
_internal_lines: [],
_internal_vertAlign: "center",
_internal_horzAlign: "center"
};
this._private__renderer = new WatermarkRenderer(this._private__rendererData);
this._private__source = source;
}
_internal_update() {
this._private__invalidated = true;
}
_internal_renderer() {
if (this._private__invalidated) {
this._private__updateImpl();
this._private__invalidated = false;
}
return this._private__renderer;
}
_private__updateImpl() {
const options = this._private__source._internal_options();
const data = this._private__rendererData;
data._internal_visible = options.visible;
if (!data._internal_visible) {
return;
}
data._internal_color = options.color;
data._internal_horzAlign = options.horzAlign;
data._internal_vertAlign = options.vertAlign;
data._internal_lines = [
{
_internal_text: options.text,
_internal_font: makeFont(options.fontSize, options.fontFamily, options.fontStyle),
_internal_lineHeight: options.fontSize * 1.2,
_internal_vertOffset: 0,
_internal_zoom: 0
}
];
}
};
var Watermark = class extends DataSource {
constructor(model, options) {
super();
this._private__options = options;
this._private__paneView = new WatermarkPaneView(this);
}
_internal_priceAxisViews() {
return [];
}
_internal_paneViews() {
return [this._private__paneView];
}
_internal_options() {
return this._private__options;
}
_internal_updateAllViews() {
this._private__paneView._internal_update();
}
};
var TrackingModeExitMode;
(function(TrackingModeExitMode2) {
TrackingModeExitMode2[TrackingModeExitMode2["OnTouchEnd"] = 0] = "OnTouchEnd";
TrackingModeExitMode2[TrackingModeExitMode2["OnNextTap"] = 1] = "OnNextTap";
})(TrackingModeExitMode || (TrackingModeExitMode = {}));
var ChartModel = class {
constructor(invalidateHandler, options, horzScaleBehavior) {
this._private__panes = [];
this._private__serieses = [];
this._private__width = 0;
this._private__hoveredSource = null;
this._private__priceScalesOptionsChanged = new Delegate();
this._private__crosshairMoved = new Delegate();
this._private__gradientColorsCache = null;
this._private__invalidateHandler = invalidateHandler;
this._private__options = options;
this._private__horzScaleBehavior = horzScaleBehavior;
this._private__rendererOptionsProvider = new PriceAxisRendererOptionsProvider(this);
this._private__timeScale = new TimeScale(this, options.timeScale, this._private__options.localization, horzScaleBehavior);
this._private__crosshair = new Crosshair(this, options.crosshair);
this._private__magnet = new Magnet(options.crosshair);
this._private__watermark = new Watermark(this, options.watermark);
this._internal_createPane();
this._private__panes[0]._internal_setStretchFactor(DEFAULT_STRETCH_FACTOR * 2);
this._private__backgroundTopColor = this._private__getBackgroundColor(
0
/* BackgroundColorSide.Top */
);
this._private__backgroundBottomColor = this._private__getBackgroundColor(
1
/* BackgroundColorSide.Bottom */
);
}
_internal_fullUpdate() {
this._private__invalidate(InvalidateMask._internal_full());
}
_internal_lightUpdate() {
this._private__invalidate(InvalidateMask._internal_light());
}
_internal_cursorUpdate() {
this._private__invalidate(new InvalidateMask(
1
/* InvalidationLevel.Cursor */
));
}
_internal_updateSource(source) {
const inv = this._private__invalidationMaskForSource(source);
this._private__invalidate(inv);
}
_internal_hoveredSource() {
return this._private__hoveredSource;
}
_internal_setHoveredSource(source) {
const prevSource = this._private__hoveredSource;
this._private__hoveredSource = source;
if (prevSource !== null) {
this._internal_updateSource(prevSource._internal_source);
}
if (source !== null) {
this._internal_updateSource(source._internal_source);
}
}
_internal_options() {
return this._private__options;
}
_internal_applyOptions(options) {
merge(this._private__options, options);
this._private__panes.forEach((p) => p._internal_applyScaleOptions(options));
if (options.timeScale !== void 0) {
this._private__timeScale._internal_applyOptions(options.timeScale);
}
if (options.localization !== void 0) {
this._private__timeScale._internal_applyLocalizationOptions(options.localization);
}
if (options.leftPriceScale || options.rightPriceScale) {
this._private__priceScalesOptionsChanged._internal_fire();
}
this._private__backgroundTopColor = this._private__getBackgroundColor(
0
/* BackgroundColorSide.Top */
);
this._private__backgroundBottomColor = this._private__getBackgroundColor(
1
/* BackgroundColorSide.Bottom */
);
this._internal_fullUpdate();
}
_internal_applyPriceScaleOptions(priceScaleId, options) {
if (priceScaleId === "left") {
this._internal_applyOptions({
leftPriceScale: options
});
return;
} else if (priceScaleId === "right") {
this._internal_applyOptions({
rightPriceScale: options
});
return;
}
const res = this._internal_findPriceScale(priceScaleId);
if (res === null) {
{
throw new Error(`Trying to apply price scale options with incorrect ID: ${priceScaleId}`);
}
}
res._internal_priceScale._internal_applyOptions(options);
this._private__priceScalesOptionsChanged._internal_fire();
}
_internal_findPriceScale(priceScaleId) {
for (const pane of this._private__panes) {
const priceScale = pane._internal_priceScaleById(priceScaleId);
if (priceScale !== null) {
return {
_internal_pane: pane,
_internal_priceScale: priceScale
};
}
}
return null;
}
_internal_timeScale() {
return this._private__timeScale;
}
_internal_panes() {
return this._private__panes;
}
_internal_watermarkSource() {
return this._private__watermark;
}
_internal_crosshairSource() {
return this._private__crosshair;
}
_internal_crosshairMoved() {
return this._private__crosshairMoved;
}
_internal_setPaneHeight(pane, height) {
pane._internal_setHeight(height);
this._internal_recalculateAllPanes();
}
_internal_setWidth(width) {
this._private__width = width;
this._private__timeScale._internal_setWidth(this._private__width);
this._private__panes.forEach((pane) => pane._internal_setWidth(width));
this._internal_recalculateAllPanes();
}
_internal_createPane(index) {
const pane = new Pane(this._private__timeScale, this);
if (index !== void 0) {
this._private__panes.splice(index, 0, pane);
} else {
this._private__panes.push(pane);
}
const actualIndex = index === void 0 ? this._private__panes.length - 1 : index;
const mask = InvalidateMask._internal_full();
mask._internal_invalidatePane(actualIndex, {
_internal_level: 0,
_internal_autoScale: true
});
this._private__invalidate(mask);
return pane;
}
_internal_startScalePrice(pane, priceScale, x) {
pane._internal_startScalePrice(priceScale, x);
}
_internal_scalePriceTo(pane, priceScale, x) {
pane._internal_scalePriceTo(priceScale, x);
this._internal_updateCrosshair();
this._private__invalidate(this._private__paneInvalidationMask(
pane,
2
/* InvalidationLevel.Light */
));
}
_internal_endScalePrice(pane, priceScale) {
pane._internal_endScalePrice(priceScale);
this._private__invalidate(this._private__paneInvalidationMask(
pane,
2
/* InvalidationLevel.Light */
));
}
_internal_startScrollPrice(pane, priceScale, x) {
if (priceScale._internal_isAutoScale()) {
return;
}
pane._internal_startScrollPrice(priceScale, x);
}
_internal_scrollPriceTo(pane, priceScale, x) {
if (priceScale._internal_isAutoScale()) {
return;
}
pane._internal_scrollPriceTo(priceScale, x);
this._internal_updateCrosshair();
this._private__invalidate(this._private__paneInvalidationMask(
pane,
2
/* InvalidationLevel.Light */
));
}
_internal_endScrollPrice(pane, priceScale) {
if (priceScale._internal_isAutoScale()) {
return;
}
pane._internal_endScrollPrice(priceScale);
this._private__invalidate(this._private__paneInvalidationMask(
pane,
2
/* InvalidationLevel.Light */
));
}
_internal_resetPriceScale(pane, priceScale) {
pane._internal_resetPriceScale(priceScale);
this._private__invalidate(this._private__paneInvalidationMask(
pane,
2
/* InvalidationLevel.Light */
));
}
_internal_startScaleTime(position) {
this._private__timeScale._internal_startScale(position);
}
/**
* Zoom in/out the chart (depends on scale value).
*
* @param pointX - X coordinate of the point to apply the zoom (the point which should stay on its place)
* @param scale - Zoom value. Negative value means zoom out, positive - zoom in.
*/
_internal_zoomTime(pointX, scale) {
const timeScale = this._internal_timeScale();
if (timeScale._internal_isEmpty() || scale === 0) {
return;
}
const timeScaleWidth = timeScale._internal_width();
pointX = Math.max(1, Math.min(pointX, timeScaleWidth));
timeScale._internal_zoom(pointX, scale);
this._internal_recalculateAllPanes();
}
_internal_scrollChart(x) {
this._internal_startScrollTime(0);
this._internal_scrollTimeTo(x);
this._internal_endScrollTime();
}
_internal_scaleTimeTo(x) {
this._private__timeScale._internal_scaleTo(x);
this._internal_recalculateAllPanes();
}
_internal_endScaleTime() {
this._private__timeScale._internal_endScale();
this._internal_lightUpdate();
}
_internal_startScrollTime(x) {
this._private__timeScale._internal_startScroll(x);
}
_internal_scrollTimeTo(x) {
this._private__timeScale._internal_scrollTo(x);
this._internal_recalculateAllPanes();
}
_internal_endScrollTime() {
this._private__timeScale._internal_endScroll();
this._internal_lightUpdate();
}
_internal_serieses() {
return this._private__serieses;
}
_internal_setAndSaveCurrentPosition(x, y, event, pane, skipEvent) {
this._private__crosshair._internal_saveOriginCoord(x, y);
let price = NaN;
let index = this._private__timeScale._internal_coordinateToIndex(x);
const visibleBars = this._private__timeScale._internal_visibleStrictRange();
if (visibleBars !== null) {
index = Math.min(Math.max(visibleBars._internal_left(), index), visibleBars._internal_right());
}
const priceScale = pane._internal_defaultPriceScale();
const firstValue = priceScale._internal_firstValue();
if (firstValue !== null) {
price = priceScale._internal_coordinateToPrice(y, firstValue);
}
price = this._private__magnet._internal_align(price, index, pane);
this._private__crosshair._internal_setPosition(index, price, pane);
this._internal_cursorUpdate();
if (!skipEvent) {
this._private__crosshairMoved._internal_fire(this._private__crosshair._internal_appliedIndex(), { x, y }, event);
}
}
// A position provided external (not from an internal event listener)
_internal_setAndSaveSyntheticPosition(price, horizontalPosition, pane) {
const priceScale = pane._internal_defaultPriceScale();
const firstValue = priceScale._internal_firstValue();
const y = priceScale._internal_priceToCoordinate(price, ensureNotNull(firstValue));
const index = this._private__timeScale._internal_timeToIndex(horizontalPosition, true);
const x = this._private__timeScale._internal_indexToCoordinate(ensureNotNull(index));
this._internal_setAndSaveCurrentPosition(x, y, null, pane, true);
}
_internal_clearCurrentPosition(skipEvent) {
const crosshair = this._internal_crosshairSource();
crosshair._internal_clearPosition();
this._internal_cursorUpdate();
if (!skipEvent) {
this._private__crosshairMoved._internal_fire(null, null, null);
}
}
_internal_updateCrosshair() {
const pane = this._private__crosshair._internal_pane();
if (pane !== null) {
const x = this._private__crosshair._internal_originCoordX();
const y = this._private__crosshair._internal_originCoordY();
this._internal_setAndSaveCurrentPosition(x, y, null, pane);
}
this._private__crosshair._internal_updateAllViews();
}
_internal_updateTimeScale(newBaseIndex, newPoints, firstChangedPointIndex) {
const oldFirstTime = this._private__timeScale._internal_indexToTime(0);
if (newPoints !== void 0 && firstChangedPointIndex !== void 0) {
this._private__timeScale._internal_update(newPoints, firstChangedPointIndex);
}
const newFirstTime = this._private__timeScale._internal_indexToTime(0);
const currentBaseIndex = this._private__timeScale._internal_baseIndex();
const visibleBars = this._private__timeScale._internal_visibleStrictRange();
if (visibleBars !== null && oldFirstTime !== null && newFirstTime !== null) {
const isLastSeriesBarVisible = visibleBars._internal_contains(currentBaseIndex);
const isLeftBarShiftToLeft = this._private__horzScaleBehavior.key(oldFirstTime) > this._private__horzScaleBehavior.key(newFirstTime);
const isSeriesPointsAdded = newBaseIndex !== null && newBaseIndex > currentBaseIndex;
const isSeriesPointsAddedToRight = isSeriesPointsAdded && !isLeftBarShiftToLeft;
const allowShiftWhenReplacingWhitespace = this._private__timeScale._internal_options().allowShiftVisibleRangeOnWhitespaceReplacement;
const replacedExistingWhitespace = firstChangedPointIndex === void 0;
const needShiftVisibleRangeOnNewBar = isLastSeriesBarVisible && (!replacedExistingWhitespace || allowShiftWhenReplacingWhitespace) && this._private__timeScale._internal_options().shiftVisibleRangeOnNewBar;
if (isSeriesPointsAddedToRight && !needShiftVisibleRangeOnNewBar) {
const compensationShift = newBaseIndex - currentBaseIndex;
this._private__timeScale._internal_setRightOffset(this._private__timeScale._internal_rightOffset() - compensationShift);
}
}
this._private__timeScale._internal_setBaseIndex(newBaseIndex);
}
_internal_recalculatePane(pane) {
if (pane !== null) {
pane._internal_recalculate();
}
}
_internal_paneForSource(source) {
const pane = this._private__panes.find((p) => p._internal_orderedSources().includes(source));
return pane === void 0 ? null : pane;
}
_internal_recalculateAllPanes() {
this._private__watermark._internal_updateAllViews();
this._private__panes.forEach((p) => p._internal_recalculate());
this._internal_updateCrosshair();
}
_internal_destroy() {
this._private__panes.forEach((p) => p._internal_destroy());
this._private__panes.length = 0;
this._private__options.localization.priceFormatter = void 0;
this._private__options.localization.percentageFormatter = void 0;
this._private__options.localization.timeFormatter = void 0;
}
_internal_rendererOptionsProvider() {
return this._private__rendererOptionsProvider;
}
_internal_priceAxisRendererOptions() {
return this._private__rendererOptionsProvider._internal_options();
}
_internal_priceScalesOptionsChanged() {
return this._private__priceScalesOptionsChanged;
}
_internal_createSeries(seriesType, options, customPaneView) {
const pane = this._private__panes[0];
const series = this._private__createSeries(options, seriesType, pane, customPaneView);
this._private__serieses.push(series);
if (this._private__serieses.length === 1) {
this._internal_fullUpdate();
} else {
this._internal_lightUpdate();
}
return series;
}
_internal_removeSeries(series) {
const pane = this._internal_paneForSource(series);
const seriesIndex = this._private__serieses.indexOf(series);
assert(seriesIndex !== -1, "Series not found");
this._private__serieses.splice(seriesIndex, 1);
ensureNotNull(pane)._internal_removeDataSource(series);
if (series._internal_destroy) {
series._internal_destroy();
}
}
_internal_moveSeriesToScale(series, targetScaleId) {
const pane = ensureNotNull(this._internal_paneForSource(series));
pane._internal_removeDataSource(series);
const target = this._internal_findPriceScale(targetScaleId);
if (target === null) {
const zOrder = series._internal_zorder();
pane._internal_addDataSource(series, targetScaleId, zOrder);
} else {
const zOrder = target._internal_pane === pane ? series._internal_zorder() : void 0;
target._internal_pane._internal_addDataSource(series, targetScaleId, zOrder);
}
}
_internal_fitContent() {
const mask = InvalidateMask._internal_light();
mask._internal_setFitContent();
this._private__invalidate(mask);
}
_internal_setTargetLogicalRange(range) {
const mask = InvalidateMask._internal_light();
mask._internal_applyRange(range);
this._private__invalidate(mask);
}
_internal_resetTimeScale() {
const mask = InvalidateMask._internal_light();
mask._internal_resetTimeScale();
this._private__invalidate(mask);
}
_internal_setBarSpacing(spacing) {
const mask = InvalidateMask._internal_light();
mask._internal_setBarSpacing(spacing);
this._private__invalidate(mask);
}
_internal_setRightOffset(offset) {
const mask = InvalidateMask._internal_light();
mask._internal_setRightOffset(offset);
this._private__invalidate(mask);
}
_internal_setTimeScaleAnimation(animation) {
const mask = InvalidateMask._internal_light();
mask._internal_setTimeScaleAnimation(animation);
this._private__invalidate(mask);
}
_internal_stopTimeScaleAnimation() {
const mask = InvalidateMask._internal_light();
mask._internal_stopTimeScaleAnimation();
this._private__invalidate(mask);
}
_internal_defaultVisiblePriceScaleId() {
return this._private__options.rightPriceScale.visible ? "right" : "left";
}
_internal_backgroundBottomColor() {
return this._private__backgroundBottomColor;
}
_internal_backgroundTopColor() {
return this._private__backgroundTopColor;
}
_internal_backgroundColorAtYPercentFromTop(percent) {
const bottomColor = this._private__backgroundBottomColor;
const topColor = this._private__backgroundTopColor;
if (bottomColor === topColor) {
return bottomColor;
}
percent = Math.max(0, Math.min(100, Math.round(percent * 100)));
if (this._private__gradientColorsCache === null || this._private__gradientColorsCache._internal_topColor !== topColor || this._private__gradientColorsCache._internal_bottomColor !== bottomColor) {
this._private__gradientColorsCache = {
_internal_topColor: topColor,
_internal_bottomColor: bottomColor,
_internal_colors: /* @__PURE__ */ new Map()
};
} else {
const cachedValue = this._private__gradientColorsCache._internal_colors.get(percent);
if (cachedValue !== void 0) {
return cachedValue;
}
}
const result = gradientColorAtPercent(topColor, bottomColor, percent / 100);
this._private__gradientColorsCache._internal_colors.set(percent, result);
return result;
}
_private__paneInvalidationMask(pane, level) {
const inv = new InvalidateMask(level);
if (pane !== null) {
const index = this._private__panes.indexOf(pane);
inv._internal_invalidatePane(index, {
_internal_level: level
});
}
return inv;
}
_private__invalidationMaskForSource(source, invalidateType) {
if (invalidateType === void 0) {
invalidateType = 2;
}
return this._private__paneInvalidationMask(this._internal_paneForSource(source), invalidateType);
}
_private__invalidate(mask) {
if (this._private__invalidateHandler) {
this._private__invalidateHandler(mask);
}
this._private__panes.forEach((pane) => pane._internal_grid()._internal_paneView()._internal_update());
}
_private__createSeries(options, seriesType, pane, customPaneView) {
const series = new Series(this, options, seriesType, pane, customPaneView);
const targetScaleId = options.priceScaleId !== void 0 ? options.priceScaleId : this._internal_defaultVisiblePriceScaleId();
pane._internal_addDataSource(series, targetScaleId);
if (!isDefaultPriceScale(targetScaleId)) {
series._internal_applyOptions(options);
}
return series;
}
_private__getBackgroundColor(side) {
const layoutOptions = this._private__options.layout;
if (layoutOptions.background.type === "gradient") {
return side === 0 ? layoutOptions.background.topColor : layoutOptions.background.bottomColor;
}
return layoutOptions.background.color;
}
};
function fillUpDownCandlesticksColors(options) {
if (options.borderColor !== void 0) {
options.borderUpColor = options.borderColor;
options.borderDownColor = options.borderColor;
}
if (options.wickColor !== void 0) {
options.wickUpColor = options.wickColor;
options.wickDownColor = options.wickColor;
}
}
var LastPriceAnimationMode;
(function(LastPriceAnimationMode2) {
LastPriceAnimationMode2[LastPriceAnimationMode2["Disabled"] = 0] = "Disabled";
LastPriceAnimationMode2[LastPriceAnimationMode2["Continuous"] = 1] = "Continuous";
LastPriceAnimationMode2[LastPriceAnimationMode2["OnDataUpdate"] = 2] = "OnDataUpdate";
})(LastPriceAnimationMode || (LastPriceAnimationMode = {}));
function precisionByMinMove(minMove) {
if (minMove >= 1) {
return 0;
}
let i = 0;
for (; i < 8; i++) {
const intPart = Math.round(minMove);
const fractPart = Math.abs(intPart - minMove);
if (fractPart < 1e-8) {
return i;
}
minMove = minMove * 10;
}
return i;
}
var PriceLineSource;
(function(PriceLineSource2) {
PriceLineSource2[PriceLineSource2["LastBar"] = 0] = "LastBar";
PriceLineSource2[PriceLineSource2["LastVisible"] = 1] = "LastVisible";
})(PriceLineSource || (PriceLineSource = {}));
var ColorType;
(function(ColorType2) {
ColorType2["Solid"] = "solid";
ColorType2["VerticalGradient"] = "gradient";
})(ColorType || (ColorType = {}));
function isBusinessDay(time) {
return !isNumber(time) && !isString(time);
}
function isUTCTimestamp(time) {
return isNumber(time);
}
var TickMarkType;
(function(TickMarkType2) {
TickMarkType2[TickMarkType2["Year"] = 0] = "Year";
TickMarkType2[TickMarkType2["Month"] = 1] = "Month";
TickMarkType2[TickMarkType2["DayOfMonth"] = 2] = "DayOfMonth";
TickMarkType2[TickMarkType2["Time"] = 3] = "Time";
TickMarkType2[TickMarkType2["TimeWithSeconds"] = 4] = "TimeWithSeconds";
})(TickMarkType || (TickMarkType = {}));
var getMonth = (date) => date.getUTCMonth() + 1;
var getDay = (date) => date.getUTCDate();
var getYear = (date) => date.getUTCFullYear();
var dd = (date) => numberToStringWithLeadingZero(getDay(date), 2);
var MMMM = (date, locale) => new Date(date.getUTCFullYear(), date.getUTCMonth(), 1).toLocaleString(locale, { month: "long" });
var MMM = (date, locale) => new Date(date.getUTCFullYear(), date.getUTCMonth(), 1).toLocaleString(locale, { month: "short" });
var MM = (date) => numberToStringWithLeadingZero(getMonth(date), 2);
var yy = (date) => numberToStringWithLeadingZero(getYear(date) % 100, 2);
var yyyy = (date) => numberToStringWithLeadingZero(getYear(date), 4);
function formatDate(date, format, locale) {
return format.replace(/yyyy/g, yyyy(date)).replace(/yy/g, yy(date)).replace(/MMMM/g, MMMM(date, locale)).replace(/MMM/g, MMM(date, locale)).replace(/MM/g, MM(date)).replace(/dd/g, dd(date));
}
var DateFormatter = class {
constructor(dateFormat = "yyyy-MM-dd", locale = "default") {
this._private__dateFormat = dateFormat;
this._private__locale = locale;
}
_internal_format(date) {
return formatDate(date, this._private__dateFormat, this._private__locale);
}
};
var TimeFormatter = class {
constructor(format) {
this._private__formatStr = format || "%h:%m:%s";
}
_internal_format(date) {
return this._private__formatStr.replace("%h", numberToStringWithLeadingZero(date.getUTCHours(), 2)).replace("%m", numberToStringWithLeadingZero(date.getUTCMinutes(), 2)).replace("%s", numberToStringWithLeadingZero(date.getUTCSeconds(), 2));
}
};
var defaultParams = {
_internal_dateFormat: "yyyy-MM-dd",
_internal_timeFormat: "%h:%m:%s",
_internal_dateTimeSeparator: " ",
_internal_locale: "default"
};
var DateTimeFormatter = class {
constructor(params = {}) {
const formatterParams = Object.assign(Object.assign({}, defaultParams), params);
this._private__dateFormatter = new DateFormatter(formatterParams._internal_dateFormat, formatterParams._internal_locale);
this._private__timeFormatter = new TimeFormatter(formatterParams._internal_timeFormat);
this._private__separator = formatterParams._internal_dateTimeSeparator;
}
_internal_format(dateTime) {
return `${this._private__dateFormatter._internal_format(dateTime)}${this._private__separator}${this._private__timeFormatter._internal_format(dateTime)}`;
}
};
function defaultTickMarkFormatter(timePoint, tickMarkType, locale) {
const formatOptions = {};
switch (tickMarkType) {
case 0:
formatOptions.year = "numeric";
break;
case 1:
formatOptions.month = "short";
break;
case 2:
formatOptions.day = "numeric";
break;
case 3:
formatOptions.hour12 = false;
formatOptions.hour = "2-digit";
formatOptions.minute = "2-digit";
break;
case 4:
formatOptions.hour12 = false;
formatOptions.hour = "2-digit";
formatOptions.minute = "2-digit";
formatOptions.second = "2-digit";
break;
}
const date = timePoint._internal_businessDay === void 0 ? new Date(timePoint._internal_timestamp * 1e3) : new Date(Date.UTC(timePoint._internal_businessDay.year, timePoint._internal_businessDay.month - 1, timePoint._internal_businessDay.day));
const localDateFromUtc = new Date(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate(), date.getUTCHours(), date.getUTCMinutes(), date.getUTCSeconds(), date.getUTCMilliseconds());
return localDateFromUtc.toLocaleString(locale, formatOptions);
}
function hours(count) {
return count * 60 * 60 * 1e3;
}
function minutes(count) {
return count * 60 * 1e3;
}
function seconds(count) {
return count * 1e3;
}
var intradayWeightDivisors = [
{
_internal_divisor: seconds(1),
_internal_weight: 10
/* TickMarkWeight.Second */
},
{
_internal_divisor: minutes(1),
_internal_weight: 20
/* TickMarkWeight.Minute1 */
},
{
_internal_divisor: minutes(5),
_internal_weight: 21
/* TickMarkWeight.Minute5 */
},
{
_internal_divisor: minutes(30),
_internal_weight: 22
/* TickMarkWeight.Minute30 */
},
{
_internal_divisor: hours(1),
_internal_weight: 30
/* TickMarkWeight.Hour1 */
},
{
_internal_divisor: hours(3),
_internal_weight: 31
/* TickMarkWeight.Hour3 */
},
{
_internal_divisor: hours(6),
_internal_weight: 32
/* TickMarkWeight.Hour6 */
},
{
_internal_divisor: hours(12),
_internal_weight: 33
/* TickMarkWeight.Hour12 */
}
];
function weightByTime(currentDate, prevDate) {
if (currentDate.getUTCFullYear() !== prevDate.getUTCFullYear()) {
return 70;
} else if (currentDate.getUTCMonth() !== prevDate.getUTCMonth()) {
return 60;
} else if (currentDate.getUTCDate() !== prevDate.getUTCDate()) {
return 50;
}
for (let i = intradayWeightDivisors.length - 1; i >= 0; --i) {
if (Math.floor(prevDate.getTime() / intradayWeightDivisors[i]._internal_divisor) !== Math.floor(currentDate.getTime() / intradayWeightDivisors[i]._internal_divisor)) {
return intradayWeightDivisors[i]._internal_weight;
}
}
return 0;
}
function cast(t) {
return t;
}
function fillWeightsForPoints(sortedTimePoints, startIndex = 0) {
if (sortedTimePoints.length === 0) {
return;
}
let prevTime = startIndex === 0 ? null : cast(sortedTimePoints[startIndex - 1].time)._internal_timestamp;
let prevDate = prevTime !== null ? new Date(prevTime * 1e3) : null;
let totalTimeDiff = 0;
for (let index = startIndex; index < sortedTimePoints.length; ++index) {
const currentPoint = sortedTimePoints[index];
const currentDate = new Date(cast(currentPoint.time)._internal_timestamp * 1e3);
if (prevDate !== null) {
currentPoint.timeWeight = weightByTime(currentDate, prevDate);
}
totalTimeDiff += cast(currentPoint.time)._internal_timestamp - (prevTime || cast(currentPoint.time)._internal_timestamp);
prevTime = cast(currentPoint.time)._internal_timestamp;
prevDate = currentDate;
}
if (startIndex === 0 && sortedTimePoints.length > 1) {
const averageTimeDiff = Math.ceil(totalTimeDiff / (sortedTimePoints.length - 1));
const approxPrevDate = new Date((cast(sortedTimePoints[0].time)._internal_timestamp - averageTimeDiff) * 1e3);
sortedTimePoints[0].timeWeight = weightByTime(new Date(cast(sortedTimePoints[0].time)._internal_timestamp * 1e3), approxPrevDate);
}
}
function businessDayConverter(time) {
let businessDay = time;
if (isString(time)) {
businessDay = stringToBusinessDay(time);
}
if (!isBusinessDay(businessDay)) {
throw new Error("time must be of type BusinessDay");
}
const date = new Date(Date.UTC(businessDay.year, businessDay.month - 1, businessDay.day, 0, 0, 0, 0));
return {
_internal_timestamp: Math.round(date.getTime() / 1e3),
_internal_businessDay: businessDay
};
}
function timestampConverter(time) {
if (!isUTCTimestamp(time)) {
throw new Error("time must be of type isUTCTimestamp");
}
return {
_internal_timestamp: time
};
}
function selectTimeConverter(data) {
if (data.length === 0) {
return null;
}
if (isBusinessDay(data[0].time) || isString(data[0].time)) {
return businessDayConverter;
}
return timestampConverter;
}
var validDateRegex = /^\d\d\d\d-\d\d-\d\d$/;
function convertTime(time) {
if (isUTCTimestamp(time)) {
return timestampConverter(time);
}
if (!isBusinessDay(time)) {
return businessDayConverter(stringToBusinessDay(time));
}
return businessDayConverter(time);
}
function stringToBusinessDay(value) {
{
if (!validDateRegex.test(value)) {
throw new Error(`Invalid date string=${value}, expected format=yyyy-mm-dd`);
}
}
const d = new Date(value);
if (isNaN(d.getTime())) {
throw new Error(`Invalid date string=${value}, expected format=yyyy-mm-dd`);
}
return {
day: d.getUTCDate(),
month: d.getUTCMonth() + 1,
year: d.getUTCFullYear()
};
}
function convertStringToBusinessDay(value) {
if (isString(value.time)) {
value.time = stringToBusinessDay(value.time);
}
}
function convertStringsToBusinessDays(data) {
return data.forEach(convertStringToBusinessDay);
}
function weightToTickMarkType(weight, timeVisible, secondsVisible) {
switch (weight) {
case 0:
case 10:
return timeVisible ? secondsVisible ? 4 : 3 : 2;
case 20:
case 21:
case 22:
case 30:
case 31:
case 32:
case 33:
return timeVisible ? 3 : 2;
case 50:
return 2;
case 60:
return 1;
case 70:
return 0;
}
}
var HorzScaleBehaviorTime = class {
options() {
return this._private__options;
}
setOptions(options) {
this._private__options = options;
this.updateFormatter(options.localization);
}
preprocessData(data) {
if (Array.isArray(data)) {
convertStringsToBusinessDays(data);
} else {
convertStringToBusinessDay(data);
}
}
createConverterToInternalObj(data) {
return ensureNotNull(selectTimeConverter(data));
}
key(item) {
if (typeof item === "object" && "_internal_timestamp" in item) {
return item._internal_timestamp;
} else {
return this.key(this.convertHorzItemToInternal(item));
}
}
cacheKey(item) {
const time = item;
return time._internal_businessDay === void 0 ? new Date(time._internal_timestamp * 1e3).getTime() : new Date(Date.UTC(time._internal_businessDay.year, time._internal_businessDay.month - 1, time._internal_businessDay.day)).getTime();
}
convertHorzItemToInternal(item) {
return convertTime(item);
}
updateFormatter(options) {
if (!this._private__options) {
return;
}
const dateFormat = options.dateFormat;
if (this._private__options.timeScale.timeVisible) {
this._private__dateTimeFormatter = new DateTimeFormatter({
_internal_dateFormat: dateFormat,
_internal_timeFormat: this._private__options.timeScale.secondsVisible ? "%h:%m:%s" : "%h:%m",
_internal_dateTimeSeparator: " ",
_internal_locale: options.locale
});
} else {
this._private__dateTimeFormatter = new DateFormatter(dateFormat, options.locale);
}
}
formatHorzItem(item) {
const tp = item;
return this._private__dateTimeFormatter._internal_format(new Date(tp._internal_timestamp * 1e3));
}
formatTickmark(tickMark, localizationOptions) {
const tickMarkType = weightToTickMarkType(tickMark.weight, this._private__options.timeScale.timeVisible, this._private__options.timeScale.secondsVisible);
const options = this._private__options.timeScale;
if (options.tickMarkFormatter !== void 0) {
const tickMarkString = options.tickMarkFormatter(tickMark.originalTime, tickMarkType, localizationOptions.locale);
if (tickMarkString !== null) {
return tickMarkString;
}
}
return defaultTickMarkFormatter(tickMark.time, tickMarkType, localizationOptions.locale);
}
maxTickMarkWeight(tickMarks) {
let maxWeight = tickMarks.reduce(markWithGreaterWeight, tickMarks[0]).weight;
if (maxWeight > 30 && maxWeight < 50) {
maxWeight = 30;
}
return maxWeight;
}
fillWeightsForPoints(sortedTimePoints, startIndex) {
fillWeightsForPoints(sortedTimePoints, startIndex);
}
static _internal_applyDefaults(options) {
return merge({ localization: { dateFormat: "dd MMM 'yy" } }, options !== null && options !== void 0 ? options : {});
}
};
var isRunningOnClientSide = typeof window !== "undefined";
function isFF() {
if (!isRunningOnClientSide) {
return false;
}
return window.navigator.userAgent.toLowerCase().indexOf("firefox") > -1;
}
function isIOS() {
if (!isRunningOnClientSide) {
return false;
}
return /iPhone|iPad|iPod/.test(window.navigator.platform);
}
function isChrome() {
if (!isRunningOnClientSide) {
return false;
}
return window.chrome !== void 0;
}
function isWindows() {
var _a;
if (!isRunningOnClientSide) {
return false;
}
if ((_a = navigator === null || navigator === void 0 ? void 0 : navigator.userAgentData) === null || _a === void 0 ? void 0 : _a.platform) {
return navigator.userAgentData.platform === "Windows";
}
return navigator.userAgent.toLowerCase().indexOf("win") >= 0;
}
function isChromiumBased() {
if (!isRunningOnClientSide) {
return false;
}
if (!navigator.userAgentData) {
return false;
}
return navigator.userAgentData.brands.some((brand) => {
return brand.brand.includes("Chromium");
});
}
function warn(msg) {
{
console.warn(msg);
}
}
function suggestChartSize(originalSize) {
const integerWidth = Math.floor(originalSize.width);
const integerHeight = Math.floor(originalSize.height);
const width = integerWidth - integerWidth % 2;
const height = integerHeight - integerHeight % 2;
return size({ width, height });
}
function suggestTimeScaleHeight(originalHeight) {
return originalHeight + originalHeight % 2;
}
function suggestPriceScaleWidth(originalWidth) {
return originalWidth + originalWidth % 2;
}
function distanceBetweenPoints(pos1, pos2) {
return pos1._internal_position - pos2._internal_position;
}
function speedPxPerMSec(pos1, pos2, maxSpeed) {
const speed = (pos1._internal_position - pos2._internal_position) / (pos1._internal_time - pos2._internal_time);
return Math.sign(speed) * Math.min(Math.abs(speed), maxSpeed);
}
function durationMSec(speed, dumpingCoeff) {
const lnDumpingCoeff = Math.log(dumpingCoeff);
return Math.log(1 * lnDumpingCoeff / -speed) / lnDumpingCoeff;
}
var KineticAnimation = class {
constructor(minSpeed, maxSpeed, dumpingCoeff, minMove) {
this._private__position1 = null;
this._private__position2 = null;
this._private__position3 = null;
this._private__position4 = null;
this._private__animationStartPosition = null;
this._private__durationMsecs = 0;
this._private__speedPxPerMsec = 0;
this._private__minSpeed = minSpeed;
this._private__maxSpeed = maxSpeed;
this._private__dumpingCoeff = dumpingCoeff;
this._private__minMove = minMove;
}
_internal_addPosition(position, time) {
if (this._private__position1 !== null) {
if (this._private__position1._internal_time === time) {
this._private__position1._internal_position = position;
return;
}
if (Math.abs(this._private__position1._internal_position - position) < this._private__minMove) {
return;
}
}
this._private__position4 = this._private__position3;
this._private__position3 = this._private__position2;
this._private__position2 = this._private__position1;
this._private__position1 = { _internal_time: time, _internal_position: position };
}
_internal_start(position, time) {
if (this._private__position1 === null || this._private__position2 === null) {
return;
}
if (time - this._private__position1._internal_time > 50) {
return;
}
let totalDistance = 0;
const speed1 = speedPxPerMSec(this._private__position1, this._private__position2, this._private__maxSpeed);
const distance1 = distanceBetweenPoints(this._private__position1, this._private__position2);
const speedItems = [speed1];
const distanceItems = [distance1];
totalDistance += distance1;
if (this._private__position3 !== null) {
const speed2 = speedPxPerMSec(this._private__position2, this._private__position3, this._private__maxSpeed);
if (Math.sign(speed2) === Math.sign(speed1)) {
const distance2 = distanceBetweenPoints(this._private__position2, this._private__position3);
speedItems.push(speed2);
distanceItems.push(distance2);
totalDistance += distance2;
if (this._private__position4 !== null) {
const speed3 = speedPxPerMSec(this._private__position3, this._private__position4, this._private__maxSpeed);
if (Math.sign(speed3) === Math.sign(speed1)) {
const distance3 = distanceBetweenPoints(this._private__position3, this._private__position4);
speedItems.push(speed3);
distanceItems.push(distance3);
totalDistance += distance3;
}
}
}
}
let resultSpeed = 0;
for (let i = 0; i < speedItems.length; ++i) {
resultSpeed += distanceItems[i] / totalDistance * speedItems[i];
}
if (Math.abs(resultSpeed) < this._private__minSpeed) {
return;
}
this._private__animationStartPosition = { _internal_position: position, _internal_time: time };
this._private__speedPxPerMsec = resultSpeed;
this._private__durationMsecs = durationMSec(Math.abs(resultSpeed), this._private__dumpingCoeff);
}
_internal_getPosition(time) {
const startPosition = ensureNotNull(this._private__animationStartPosition);
const durationMsecs = time - startPosition._internal_time;
return startPosition._internal_position + this._private__speedPxPerMsec * (Math.pow(this._private__dumpingCoeff, durationMsecs) - 1) / Math.log(this._private__dumpingCoeff);
}
_internal_finished(time) {
return this._private__animationStartPosition === null || this._private__progressDuration(time) === this._private__durationMsecs;
}
_private__progressDuration(time) {
const startPosition = ensureNotNull(this._private__animationStartPosition);
const progress = time - startPosition._internal_time;
return Math.min(progress, this._private__durationMsecs);
}
};
var svg = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 35 19" width="35" height="19" fill="none"><g fill-rule="evenodd" clip-path="url(#a)" clip-rule="evenodd"><path fill="var(--stroke)" d="M2 0H0v10h6v9h21.4l.5-1.3 6-15 1-2.7H23.7l-.5 1.3-.2.6a5 5 0 0 0-7-.9V0H2Zm20 17h4l5.2-13 .8-2h-7l-1 2.5-.2.5-1.5 3.8-.3.7V17Zm-.8-10a3 3 0 0 0 .7-2.7A3 3 0 1 0 16.8 7h4.4ZM14 7V2H2v6h6v9h4V7h2Z"/><path fill="var(--fill)" d="M14 2H2v6h6v9h6V2Zm12 15h-7l6-15h7l-6 15Zm-7-9a3 3 0 1 0 0-6 3 3 0 0 0 0 6Z"/></g><defs><clipPath id="a"><path fill="var(--stroke)" d="M0 0h35v19H0z"/></clipPath></defs></svg>`;
var css = `a#tv-attr-logo{--fill:#131722;--stroke:#fff;position:absolute;left:10px;bottom:10px;height:19px;width:35px;margin:0;padding:0;border:0;z-index:3;}a#tv-attr-logo[data-dark]{--fill:#D1D4DC;--stroke:#131722;}`;
var AttributionLogoWidget = class {
constructor(container, chart) {
this._private__element = void 0;
this._private__cssElement = void 0;
this._private__theme = void 0;
this._private__visible = false;
this._private__container = container;
this._private__chart = chart;
this._private__render();
}
_internal_update() {
this._private__render();
}
_internal_removeElement() {
if (this._private__element) {
this._private__container.removeChild(this._private__element);
}
if (this._private__cssElement) {
this._private__container.removeChild(this._private__cssElement);
}
this._private__element = void 0;
this._private__cssElement = void 0;
}
_private__shouldUpdate() {
return this._private__visible !== this._private__shouldBeVisible() || this._private__theme !== this._private__themeToUse();
}
_private__themeToUse() {
return colorStringToGrayscale(this._private__chart._internal_options().layout.textColor) > 160 ? "dark" : "light";
}
_private__shouldBeVisible() {
return this._private__chart._internal_options().layout.attributionLogo;
}
_private__getUTMSource() {
const url = new URL(location.href);
if (!url.hostname) {
return "";
}
return "&utm_source=" + url.hostname + url.pathname;
}
_private__render() {
if (!this._private__shouldUpdate()) {
return;
}
this._internal_removeElement();
this._private__visible = this._private__shouldBeVisible();
if (this._private__visible) {
this._private__theme = this._private__themeToUse();
this._private__cssElement = document.createElement("style");
this._private__cssElement.innerText = css;
this._private__element = document.createElement("a");
this._private__element.href = `https://www.tradingview.com/?utm_medium=lwc-link&utm_campaign=lwc-chart${this._private__getUTMSource()}`;
this._private__element.title = "Charting by TradingView";
this._private__element.id = "tv-attr-logo";
this._private__element.target = "_blank";
this._private__element.innerHTML = svg;
this._private__element.toggleAttribute("data-dark", this._private__theme === "dark");
this._private__container.appendChild(this._private__cssElement);
this._private__container.appendChild(this._private__element);
}
}
};
function createBoundCanvas(parentElement, size3) {
const doc = ensureNotNull(parentElement.ownerDocument);
const canvas = doc.createElement("canvas");
parentElement.appendChild(canvas);
const binding = bindTo(canvas, {
type: "device-pixel-content-box",
options: {
allowResizeObserver: false
},
transform: (bitmapSize, canvasElementClientSize) => ({
width: Math.max(bitmapSize.width, canvasElementClientSize.width),
height: Math.max(bitmapSize.height, canvasElementClientSize.height)
})
});
binding.resizeCanvasElement(size3);
return binding;
}
function releaseCanvas(canvas) {
var _a;
canvas.width = 1;
canvas.height = 1;
(_a = canvas.getContext("2d")) === null || _a === void 0 ? void 0 : _a.clearRect(0, 0, 1, 1);
}
function drawBackground(renderer, target, isHovered, hitTestData) {
if (renderer._internal_drawBackground) {
renderer._internal_drawBackground(target, isHovered, hitTestData);
}
}
function drawForeground(renderer, target, isHovered, hitTestData) {
renderer._internal_draw(target, isHovered, hitTestData);
}
function drawSourcePaneViews(paneViewsGetter, drawRendererFn, source, pane) {
const paneViews = paneViewsGetter(source, pane);
for (const paneView of paneViews) {
const renderer = paneView._internal_renderer();
if (renderer !== null) {
drawRendererFn(renderer);
}
}
}
function preventScrollByWheelClick(el) {
if (!isChrome()) {
return;
}
el.addEventListener("mousedown", (e) => {
if (e.button === 1) {
e.preventDefault();
return false;
}
return void 0;
});
}
var MouseEventHandler = class {
constructor(target, handler, options) {
this._private__clickCount = 0;
this._private__clickTimeoutId = null;
this._private__clickPosition = { _internal_x: Number.NEGATIVE_INFINITY, _internal_y: Number.POSITIVE_INFINITY };
this._private__tapCount = 0;
this._private__tapTimeoutId = null;
this._private__tapPosition = { _internal_x: Number.NEGATIVE_INFINITY, _internal_y: Number.POSITIVE_INFINITY };
this._private__longTapTimeoutId = null;
this._private__longTapActive = false;
this._private__mouseMoveStartPosition = null;
this._private__touchMoveStartPosition = null;
this._private__touchMoveExceededManhattanDistance = false;
this._private__cancelClick = false;
this._private__cancelTap = false;
this._private__unsubscribeOutsideMouseEvents = null;
this._private__unsubscribeOutsideTouchEvents = null;
this._private__unsubscribeMobileSafariEvents = null;
this._private__unsubscribeMousemove = null;
this._private__unsubscribeRootMouseEvents = null;
this._private__unsubscribeRootTouchEvents = null;
this._private__startPinchMiddlePoint = null;
this._private__startPinchDistance = 0;
this._private__pinchPrevented = false;
this._private__preventTouchDragProcess = false;
this._private__mousePressed = false;
this._private__lastTouchEventTimeStamp = 0;
this._private__activeTouchId = null;
this._private__acceptMouseLeave = !isIOS();
this._private__onFirefoxOutsideMouseUp = (mouseUpEvent) => {
this._private__mouseUpHandler(mouseUpEvent);
};
this._private__onMobileSafariDoubleClick = (dblClickEvent) => {
if (this._private__firesTouchEvents(dblClickEvent)) {
const compatEvent = this._private__makeCompatEvent(dblClickEvent);
++this._private__tapCount;
if (this._private__tapTimeoutId && this._private__tapCount > 1) {
const { _internal_manhattanDistance: manhattanDistance } = this._private__touchMouseMoveWithDownInfo(getPosition(dblClickEvent), this._private__tapPosition);
if (manhattanDistance < 30 && !this._private__cancelTap) {
this._private__processTouchEvent(compatEvent, this._private__handler._internal_doubleTapEvent);
}
this._private__resetTapTimeout();
}
} else {
const compatEvent = this._private__makeCompatEvent(dblClickEvent);
++this._private__clickCount;
if (this._private__clickTimeoutId && this._private__clickCount > 1) {
const { _internal_manhattanDistance: manhattanDistance } = this._private__touchMouseMoveWithDownInfo(getPosition(dblClickEvent), this._private__clickPosition);
if (manhattanDistance < 5 && !this._private__cancelClick) {
this._private__processMouseEvent(compatEvent, this._private__handler._internal_mouseDoubleClickEvent);
}
this._private__resetClickTimeout();
}
}
};
this._private__target = target;
this._private__handler = handler;
this._private__options = options;
this._private__init();
}
_internal_destroy() {
if (this._private__unsubscribeOutsideMouseEvents !== null) {
this._private__unsubscribeOutsideMouseEvents();
this._private__unsubscribeOutsideMouseEvents = null;
}
if (this._private__unsubscribeOutsideTouchEvents !== null) {
this._private__unsubscribeOutsideTouchEvents();
this._private__unsubscribeOutsideTouchEvents = null;
}
if (this._private__unsubscribeMousemove !== null) {
this._private__unsubscribeMousemove();
this._private__unsubscribeMousemove = null;
}
if (this._private__unsubscribeRootMouseEvents !== null) {
this._private__unsubscribeRootMouseEvents();
this._private__unsubscribeRootMouseEvents = null;
}
if (this._private__unsubscribeRootTouchEvents !== null) {
this._private__unsubscribeRootTouchEvents();
this._private__unsubscribeRootTouchEvents = null;
}
if (this._private__unsubscribeMobileSafariEvents !== null) {
this._private__unsubscribeMobileSafariEvents();
this._private__unsubscribeMobileSafariEvents = null;
}
this._private__clearLongTapTimeout();
this._private__resetClickTimeout();
}
_private__mouseEnterHandler(enterEvent) {
if (this._private__unsubscribeMousemove) {
this._private__unsubscribeMousemove();
}
const boundMouseMoveHandler = this._private__mouseMoveHandler.bind(this);
this._private__unsubscribeMousemove = () => {
this._private__target.removeEventListener("mousemove", boundMouseMoveHandler);
};
this._private__target.addEventListener("mousemove", boundMouseMoveHandler);
if (this._private__firesTouchEvents(enterEvent)) {
return;
}
const compatEvent = this._private__makeCompatEvent(enterEvent);
this._private__processMouseEvent(compatEvent, this._private__handler._internal_mouseEnterEvent);
this._private__acceptMouseLeave = true;
}
_private__resetClickTimeout() {
if (this._private__clickTimeoutId !== null) {
clearTimeout(this._private__clickTimeoutId);
}
this._private__clickCount = 0;
this._private__clickTimeoutId = null;
this._private__clickPosition = { _internal_x: Number.NEGATIVE_INFINITY, _internal_y: Number.POSITIVE_INFINITY };
}
_private__resetTapTimeout() {
if (this._private__tapTimeoutId !== null) {
clearTimeout(this._private__tapTimeoutId);
}
this._private__tapCount = 0;
this._private__tapTimeoutId = null;
this._private__tapPosition = { _internal_x: Number.NEGATIVE_INFINITY, _internal_y: Number.POSITIVE_INFINITY };
}
_private__mouseMoveHandler(moveEvent) {
if (this._private__mousePressed || this._private__touchMoveStartPosition !== null) {
return;
}
if (this._private__firesTouchEvents(moveEvent)) {
return;
}
const compatEvent = this._private__makeCompatEvent(moveEvent);
this._private__processMouseEvent(compatEvent, this._private__handler._internal_mouseMoveEvent);
this._private__acceptMouseLeave = true;
}
_private__touchMoveHandler(moveEvent) {
const touch = touchWithId(moveEvent.changedTouches, ensureNotNull(this._private__activeTouchId));
if (touch === null) {
return;
}
this._private__lastTouchEventTimeStamp = eventTimeStamp(moveEvent);
if (this._private__startPinchMiddlePoint !== null) {
return;
}
if (this._private__preventTouchDragProcess) {
return;
}
this._private__pinchPrevented = true;
const moveInfo = this._private__touchMouseMoveWithDownInfo(getPosition(touch), ensureNotNull(this._private__touchMoveStartPosition));
const { _internal_xOffset: xOffset, _internal_yOffset: yOffset, _internal_manhattanDistance: manhattanDistance } = moveInfo;
if (!this._private__touchMoveExceededManhattanDistance && manhattanDistance < 5) {
return;
}
if (!this._private__touchMoveExceededManhattanDistance) {
const correctedXOffset = xOffset * 0.5;
const isVertDrag = yOffset >= correctedXOffset && !this._private__options._internal_treatVertTouchDragAsPageScroll();
const isHorzDrag = correctedXOffset > yOffset && !this._private__options._internal_treatHorzTouchDragAsPageScroll();
if (!isVertDrag && !isHorzDrag) {
this._private__preventTouchDragProcess = true;
}
this._private__touchMoveExceededManhattanDistance = true;
this._private__cancelTap = true;
this._private__clearLongTapTimeout();
this._private__resetTapTimeout();
}
if (!this._private__preventTouchDragProcess) {
const compatEvent = this._private__makeCompatEvent(moveEvent, touch);
this._private__processTouchEvent(compatEvent, this._private__handler._internal_touchMoveEvent);
preventDefault(moveEvent);
}
}
_private__mouseMoveWithDownHandler(moveEvent) {
if (moveEvent.button !== 0) {
return;
}
const moveInfo = this._private__touchMouseMoveWithDownInfo(getPosition(moveEvent), ensureNotNull(this._private__mouseMoveStartPosition));
const { _internal_manhattanDistance: manhattanDistance } = moveInfo;
if (manhattanDistance >= 5) {
this._private__cancelClick = true;
this._private__resetClickTimeout();
}
if (this._private__cancelClick) {
const compatEvent = this._private__makeCompatEvent(moveEvent);
this._private__processMouseEvent(compatEvent, this._private__handler._internal_pressedMouseMoveEvent);
}
}
_private__touchMouseMoveWithDownInfo(currentPosition, startPosition) {
const xOffset = Math.abs(startPosition._internal_x - currentPosition._internal_x);
const yOffset = Math.abs(startPosition._internal_y - currentPosition._internal_y);
const manhattanDistance = xOffset + yOffset;
return {
_internal_xOffset: xOffset,
_internal_yOffset: yOffset,
_internal_manhattanDistance: manhattanDistance
};
}
// eslint-disable-next-line complexity
_private__touchEndHandler(touchEndEvent) {
let touch = touchWithId(touchEndEvent.changedTouches, ensureNotNull(this._private__activeTouchId));
if (touch === null && touchEndEvent.touches.length === 0) {
touch = touchEndEvent.changedTouches[0];
}
if (touch === null) {
return;
}
this._private__activeTouchId = null;
this._private__lastTouchEventTimeStamp = eventTimeStamp(touchEndEvent);
this._private__clearLongTapTimeout();
this._private__touchMoveStartPosition = null;
if (this._private__unsubscribeRootTouchEvents) {
this._private__unsubscribeRootTouchEvents();
this._private__unsubscribeRootTouchEvents = null;
}
const compatEvent = this._private__makeCompatEvent(touchEndEvent, touch);
this._private__processTouchEvent(compatEvent, this._private__handler._internal_touchEndEvent);
++this._private__tapCount;
if (this._private__tapTimeoutId && this._private__tapCount > 1) {
const { _internal_manhattanDistance: manhattanDistance } = this._private__touchMouseMoveWithDownInfo(getPosition(touch), this._private__tapPosition);
if (manhattanDistance < 30 && !this._private__cancelTap) {
this._private__processTouchEvent(compatEvent, this._private__handler._internal_doubleTapEvent);
}
this._private__resetTapTimeout();
} else {
if (!this._private__cancelTap) {
this._private__processTouchEvent(compatEvent, this._private__handler._internal_tapEvent);
if (this._private__handler._internal_tapEvent) {
preventDefault(touchEndEvent);
}
}
}
if (this._private__tapCount === 0) {
preventDefault(touchEndEvent);
}
if (touchEndEvent.touches.length === 0) {
if (this._private__longTapActive) {
this._private__longTapActive = false;
preventDefault(touchEndEvent);
}
}
}
_private__mouseUpHandler(mouseUpEvent) {
if (mouseUpEvent.button !== 0) {
return;
}
const compatEvent = this._private__makeCompatEvent(mouseUpEvent);
this._private__mouseMoveStartPosition = null;
this._private__mousePressed = false;
if (this._private__unsubscribeRootMouseEvents) {
this._private__unsubscribeRootMouseEvents();
this._private__unsubscribeRootMouseEvents = null;
}
if (isFF()) {
const rootElement = this._private__target.ownerDocument.documentElement;
rootElement.removeEventListener("mouseleave", this._private__onFirefoxOutsideMouseUp);
}
if (this._private__firesTouchEvents(mouseUpEvent)) {
return;
}
this._private__processMouseEvent(compatEvent, this._private__handler._internal_mouseUpEvent);
++this._private__clickCount;
if (this._private__clickTimeoutId && this._private__clickCount > 1) {
const { _internal_manhattanDistance: manhattanDistance } = this._private__touchMouseMoveWithDownInfo(getPosition(mouseUpEvent), this._private__clickPosition);
if (manhattanDistance < 5 && !this._private__cancelClick) {
this._private__processMouseEvent(compatEvent, this._private__handler._internal_mouseDoubleClickEvent);
}
this._private__resetClickTimeout();
} else {
if (!this._private__cancelClick) {
this._private__processMouseEvent(compatEvent, this._private__handler._internal_mouseClickEvent);
}
}
}
_private__clearLongTapTimeout() {
if (this._private__longTapTimeoutId === null) {
return;
}
clearTimeout(this._private__longTapTimeoutId);
this._private__longTapTimeoutId = null;
}
_private__touchStartHandler(downEvent) {
if (this._private__activeTouchId !== null) {
return;
}
const touch = downEvent.changedTouches[0];
this._private__activeTouchId = touch.identifier;
this._private__lastTouchEventTimeStamp = eventTimeStamp(downEvent);
const rootElement = this._private__target.ownerDocument.documentElement;
this._private__cancelTap = false;
this._private__touchMoveExceededManhattanDistance = false;
this._private__preventTouchDragProcess = false;
this._private__touchMoveStartPosition = getPosition(touch);
if (this._private__unsubscribeRootTouchEvents) {
this._private__unsubscribeRootTouchEvents();
this._private__unsubscribeRootTouchEvents = null;
}
{
const boundTouchMoveWithDownHandler = this._private__touchMoveHandler.bind(this);
const boundTouchEndHandler = this._private__touchEndHandler.bind(this);
this._private__unsubscribeRootTouchEvents = () => {
rootElement.removeEventListener("touchmove", boundTouchMoveWithDownHandler);
rootElement.removeEventListener("touchend", boundTouchEndHandler);
};
rootElement.addEventListener("touchmove", boundTouchMoveWithDownHandler, { passive: false });
rootElement.addEventListener("touchend", boundTouchEndHandler, { passive: false });
this._private__clearLongTapTimeout();
this._private__longTapTimeoutId = setTimeout(
this._private__longTapHandler.bind(this, downEvent),
240
/* Delay.LongTap */
);
}
const compatEvent = this._private__makeCompatEvent(downEvent, touch);
this._private__processTouchEvent(compatEvent, this._private__handler._internal_touchStartEvent);
if (!this._private__tapTimeoutId) {
this._private__tapCount = 0;
this._private__tapTimeoutId = setTimeout(
this._private__resetTapTimeout.bind(this),
500
/* Delay.ResetClick */
);
this._private__tapPosition = getPosition(touch);
}
}
_private__mouseDownHandler(downEvent) {
if (downEvent.button !== 0) {
return;
}
const rootElement = this._private__target.ownerDocument.documentElement;
if (isFF()) {
rootElement.addEventListener("mouseleave", this._private__onFirefoxOutsideMouseUp);
}
this._private__cancelClick = false;
this._private__mouseMoveStartPosition = getPosition(downEvent);
if (this._private__unsubscribeRootMouseEvents) {
this._private__unsubscribeRootMouseEvents();
this._private__unsubscribeRootMouseEvents = null;
}
{
const boundMouseMoveWithDownHandler = this._private__mouseMoveWithDownHandler.bind(this);
const boundMouseUpHandler = this._private__mouseUpHandler.bind(this);
this._private__unsubscribeRootMouseEvents = () => {
rootElement.removeEventListener("mousemove", boundMouseMoveWithDownHandler);
rootElement.removeEventListener("mouseup", boundMouseUpHandler);
};
rootElement.addEventListener("mousemove", boundMouseMoveWithDownHandler);
rootElement.addEventListener("mouseup", boundMouseUpHandler);
}
this._private__mousePressed = true;
if (this._private__firesTouchEvents(downEvent)) {
return;
}
const compatEvent = this._private__makeCompatEvent(downEvent);
this._private__processMouseEvent(compatEvent, this._private__handler._internal_mouseDownEvent);
if (!this._private__clickTimeoutId) {
this._private__clickCount = 0;
this._private__clickTimeoutId = setTimeout(
this._private__resetClickTimeout.bind(this),
500
/* Delay.ResetClick */
);
this._private__clickPosition = getPosition(downEvent);
}
}
_private__init() {
this._private__target.addEventListener("mouseenter", this._private__mouseEnterHandler.bind(this));
this._private__target.addEventListener("touchcancel", this._private__clearLongTapTimeout.bind(this));
{
const doc = this._private__target.ownerDocument;
const outsideHandler = (event) => {
if (!this._private__handler._internal_mouseDownOutsideEvent) {
return;
}
if (event.composed && this._private__target.contains(event.composedPath()[0])) {
return;
}
if (event.target && this._private__target.contains(event.target)) {
return;
}
this._private__handler._internal_mouseDownOutsideEvent();
};
this._private__unsubscribeOutsideTouchEvents = () => {
doc.removeEventListener("touchstart", outsideHandler);
};
this._private__unsubscribeOutsideMouseEvents = () => {
doc.removeEventListener("mousedown", outsideHandler);
};
doc.addEventListener("mousedown", outsideHandler);
doc.addEventListener("touchstart", outsideHandler, { passive: true });
}
if (isIOS()) {
this._private__unsubscribeMobileSafariEvents = () => {
this._private__target.removeEventListener("dblclick", this._private__onMobileSafariDoubleClick);
};
this._private__target.addEventListener("dblclick", this._private__onMobileSafariDoubleClick);
}
this._private__target.addEventListener("mouseleave", this._private__mouseLeaveHandler.bind(this));
this._private__target.addEventListener("touchstart", this._private__touchStartHandler.bind(this), { passive: true });
preventScrollByWheelClick(this._private__target);
this._private__target.addEventListener("mousedown", this._private__mouseDownHandler.bind(this));
this._private__initPinch();
this._private__target.addEventListener("touchmove", () => {
}, { passive: false });
}
_private__initPinch() {
if (this._private__handler._internal_pinchStartEvent === void 0 && this._private__handler._internal_pinchEvent === void 0 && this._private__handler._internal_pinchEndEvent === void 0) {
return;
}
this._private__target.addEventListener("touchstart", (event) => this._private__checkPinchState(event.touches), { passive: true });
this._private__target.addEventListener("touchmove", (event) => {
if (event.touches.length !== 2 || this._private__startPinchMiddlePoint === null) {
return;
}
if (this._private__handler._internal_pinchEvent !== void 0) {
const currentDistance = getDistance(event.touches[0], event.touches[1]);
const scale = currentDistance / this._private__startPinchDistance;
this._private__handler._internal_pinchEvent(this._private__startPinchMiddlePoint, scale);
preventDefault(event);
}
}, { passive: false });
this._private__target.addEventListener("touchend", (event) => {
this._private__checkPinchState(event.touches);
});
}
_private__checkPinchState(touches) {
if (touches.length === 1) {
this._private__pinchPrevented = false;
}
if (touches.length !== 2 || this._private__pinchPrevented || this._private__longTapActive) {
this._private__stopPinch();
} else {
this._private__startPinch(touches);
}
}
_private__startPinch(touches) {
const box = getBoundingClientRect(this._private__target);
this._private__startPinchMiddlePoint = {
_internal_x: (touches[0].clientX - box.left + (touches[1].clientX - box.left)) / 2,
_internal_y: (touches[0].clientY - box.top + (touches[1].clientY - box.top)) / 2
};
this._private__startPinchDistance = getDistance(touches[0], touches[1]);
if (this._private__handler._internal_pinchStartEvent !== void 0) {
this._private__handler._internal_pinchStartEvent();
}
this._private__clearLongTapTimeout();
}
_private__stopPinch() {
if (this._private__startPinchMiddlePoint === null) {
return;
}
this._private__startPinchMiddlePoint = null;
if (this._private__handler._internal_pinchEndEvent !== void 0) {
this._private__handler._internal_pinchEndEvent();
}
}
_private__mouseLeaveHandler(event) {
if (this._private__unsubscribeMousemove) {
this._private__unsubscribeMousemove();
}
if (this._private__firesTouchEvents(event)) {
return;
}
if (!this._private__acceptMouseLeave) {
return;
}
const compatEvent = this._private__makeCompatEvent(event);
this._private__processMouseEvent(compatEvent, this._private__handler._internal_mouseLeaveEvent);
this._private__acceptMouseLeave = !isIOS();
}
_private__longTapHandler(event) {
const touch = touchWithId(event.touches, ensureNotNull(this._private__activeTouchId));
if (touch === null) {
return;
}
const compatEvent = this._private__makeCompatEvent(event, touch);
this._private__processTouchEvent(compatEvent, this._private__handler._internal_longTapEvent);
this._private__cancelTap = true;
this._private__longTapActive = true;
}
_private__firesTouchEvents(e) {
if (e.sourceCapabilities && e.sourceCapabilities.firesTouchEvents !== void 0) {
return e.sourceCapabilities.firesTouchEvents;
}
return eventTimeStamp(e) < this._private__lastTouchEventTimeStamp + 500;
}
_private__processTouchEvent(event, callback) {
if (callback) {
callback.call(this._private__handler, event);
}
}
_private__processMouseEvent(event, callback) {
if (!callback) {
return;
}
callback.call(this._private__handler, event);
}
_private__makeCompatEvent(event, touch) {
const eventLike = touch || event;
const box = this._private__target.getBoundingClientRect() || { left: 0, top: 0 };
return {
clientX: eventLike.clientX,
clientY: eventLike.clientY,
pageX: eventLike.pageX,
pageY: eventLike.pageY,
screenX: eventLike.screenX,
screenY: eventLike.screenY,
localX: eventLike.clientX - box.left,
localY: eventLike.clientY - box.top,
ctrlKey: event.ctrlKey,
altKey: event.altKey,
shiftKey: event.shiftKey,
metaKey: event.metaKey,
_internal_isTouch: !event.type.startsWith("mouse") && event.type !== "contextmenu" && event.type !== "click",
_internal_srcType: event.type,
_internal_target: eventLike.target,
_internal_view: event.view,
_internal_preventDefault: () => {
if (event.type !== "touchstart") {
preventDefault(event);
}
}
};
}
};
function getBoundingClientRect(element) {
return element.getBoundingClientRect() || { left: 0, top: 0 };
}
function getDistance(p1, p2) {
const xDiff = p1.clientX - p2.clientX;
const yDiff = p1.clientY - p2.clientY;
return Math.sqrt(xDiff * xDiff + yDiff * yDiff);
}
function preventDefault(event) {
if (event.cancelable) {
event.preventDefault();
}
}
function getPosition(eventLike) {
return {
_internal_x: eventLike.pageX,
_internal_y: eventLike.pageY
};
}
function eventTimeStamp(e) {
return e.timeStamp || performance.now();
}
function touchWithId(touches, id) {
for (let i = 0; i < touches.length; ++i) {
if (touches[i].identifier === id) {
return touches[i];
}
}
return null;
}
function comparePrimitiveZOrder(item, reference) {
return !reference || item === "top" && reference !== "top" || item === "normal" && reference === "bottom";
}
function findBestPrimitiveHitTest(sources, x, y) {
var _a, _b;
let bestPrimitiveHit;
let bestHitSource;
for (const source of sources) {
const primitiveHitResults = (_b = (_a = source._internal_primitiveHitTest) === null || _a === void 0 ? void 0 : _a.call(source, x, y)) !== null && _b !== void 0 ? _b : [];
for (const hitResult of primitiveHitResults) {
if (comparePrimitiveZOrder(hitResult.zOrder, bestPrimitiveHit === null || bestPrimitiveHit === void 0 ? void 0 : bestPrimitiveHit.zOrder)) {
bestPrimitiveHit = hitResult;
bestHitSource = source;
}
}
}
if (!bestPrimitiveHit || !bestHitSource) {
return null;
}
return {
_internal_hit: bestPrimitiveHit,
_internal_source: bestHitSource
};
}
function convertPrimitiveHitResult(primitiveHit) {
return {
_internal_source: primitiveHit._internal_source,
_internal_object: {
_internal_externalId: primitiveHit._internal_hit.externalId
},
_internal_cursorStyle: primitiveHit._internal_hit.cursorStyle
};
}
function hitTestPaneView(paneViews, x, y) {
for (const paneView of paneViews) {
const renderer = paneView._internal_renderer();
if (renderer !== null && renderer._internal_hitTest) {
const result = renderer._internal_hitTest(x, y);
if (result !== null) {
return {
_internal_view: paneView,
_internal_object: result
};
}
}
}
return null;
}
function hitTestPane(pane, x, y) {
const sources = pane._internal_orderedSources();
const bestPrimitiveHit = findBestPrimitiveHitTest(sources, x, y);
if ((bestPrimitiveHit === null || bestPrimitiveHit === void 0 ? void 0 : bestPrimitiveHit._internal_hit.zOrder) === "top") {
return convertPrimitiveHitResult(bestPrimitiveHit);
}
for (const source of sources) {
if (bestPrimitiveHit && bestPrimitiveHit._internal_source === source && bestPrimitiveHit._internal_hit.zOrder !== "bottom" && !bestPrimitiveHit._internal_hit.isBackground) {
return convertPrimitiveHitResult(bestPrimitiveHit);
}
const sourceResult = hitTestPaneView(source._internal_paneViews(pane), x, y);
if (sourceResult !== null) {
return {
_internal_source: source,
_internal_view: sourceResult._internal_view,
_internal_object: sourceResult._internal_object
};
}
if (bestPrimitiveHit && bestPrimitiveHit._internal_source === source && bestPrimitiveHit._internal_hit.zOrder !== "bottom" && bestPrimitiveHit._internal_hit.isBackground) {
return convertPrimitiveHitResult(bestPrimitiveHit);
}
}
if (bestPrimitiveHit === null || bestPrimitiveHit === void 0 ? void 0 : bestPrimitiveHit._internal_hit) {
return convertPrimitiveHitResult(bestPrimitiveHit);
}
return null;
}
function buildPriceAxisViewsGetter(zOrder, priceScaleId) {
return (source) => {
var _a, _b, _c, _d;
const psId = (_b = (_a = source._internal_priceScale()) === null || _a === void 0 ? void 0 : _a._internal_id()) !== null && _b !== void 0 ? _b : "";
if (psId !== priceScaleId) {
return [];
}
return (_d = (_c = source._internal_pricePaneViews) === null || _c === void 0 ? void 0 : _c.call(source, zOrder)) !== null && _d !== void 0 ? _d : [];
};
}
function recalculateOverlapping(views, direction, scaleHeight, rendererOptions) {
if (!views.length) {
return;
}
let currentGroupStart = 0;
const center = scaleHeight / 2;
const initLabelHeight = views[0]._internal_height(rendererOptions, true);
let spaceBeforeCurrentGroup = direction === 1 ? center - (views[0]._internal_getFixedCoordinate() - initLabelHeight / 2) : views[0]._internal_getFixedCoordinate() - initLabelHeight / 2 - center;
spaceBeforeCurrentGroup = Math.max(0, spaceBeforeCurrentGroup);
for (let i = 1; i < views.length; i++) {
const view = views[i];
const prev = views[i - 1];
const height = prev._internal_height(rendererOptions, false);
const coordinate = view._internal_getFixedCoordinate();
const prevFixedCoordinate = prev._internal_getFixedCoordinate();
const overlap = direction === 1 ? coordinate > prevFixedCoordinate - height : coordinate < prevFixedCoordinate + height;
if (overlap) {
const fixedCoordinate = prevFixedCoordinate - height * direction;
view._internal_setFixedCoordinate(fixedCoordinate);
const edgePoint = fixedCoordinate - direction * height / 2;
const outOfViewport = direction === 1 ? edgePoint < 0 : edgePoint > scaleHeight;
if (outOfViewport && spaceBeforeCurrentGroup > 0) {
const desiredGroupShift = direction === 1 ? -1 - edgePoint : edgePoint - scaleHeight;
const possibleShift = Math.min(desiredGroupShift, spaceBeforeCurrentGroup);
for (let k = currentGroupStart; k < views.length; k++) {
views[k]._internal_setFixedCoordinate(views[k]._internal_getFixedCoordinate() + direction * possibleShift);
}
spaceBeforeCurrentGroup -= possibleShift;
}
} else {
currentGroupStart = i;
spaceBeforeCurrentGroup = direction === 1 ? prevFixedCoordinate - height - coordinate : coordinate - (prevFixedCoordinate + height);
}
}
}
function priceScaleCrosshairLabelVisible(crosshair) {
return crosshair.mode !== 2 && crosshair.horzLine.visible && crosshair.horzLine.labelVisible;
}
var PriceAxisWidget = class {
constructor(pane, options, rendererOptionsProvider, side) {
this._private__priceScale = null;
this._private__size = null;
this._private__mousedown = false;
this._private__widthCache = new TextWidthCache(200);
this._private__font = null;
this._private__prevOptimalWidth = 0;
this._private__isSettingSize = false;
this._private__canvasSuggestedBitmapSizeChangedHandler = () => {
if (this._private__isSettingSize) {
return;
}
this._private__pane._internal_chart()._internal_model()._internal_lightUpdate();
};
this._private__topCanvasSuggestedBitmapSizeChangedHandler = () => {
if (this._private__isSettingSize) {
return;
}
this._private__pane._internal_chart()._internal_model()._internal_lightUpdate();
};
this._private__pane = pane;
this._private__options = options;
this._private__layoutOptions = options.layout;
this._private__rendererOptionsProvider = rendererOptionsProvider;
this._private__isLeft = side === "left";
this._private__sourcePaneViews = buildPriceAxisViewsGetter("normal", side);
this._private__sourceTopPaneViews = buildPriceAxisViewsGetter("top", side);
this._private__sourceBottomPaneViews = buildPriceAxisViewsGetter("bottom", side);
this._private__cell = document.createElement("div");
this._private__cell.style.height = "100%";
this._private__cell.style.overflow = "hidden";
this._private__cell.style.width = "25px";
this._private__cell.style.left = "0";
this._private__cell.style.position = "relative";
this._private__canvasBinding = createBoundCanvas(this._private__cell, size({ width: 16, height: 16 }));
this._private__canvasBinding.subscribeSuggestedBitmapSizeChanged(this._private__canvasSuggestedBitmapSizeChangedHandler);
const canvas = this._private__canvasBinding.canvasElement;
canvas.style.position = "absolute";
canvas.style.zIndex = "1";
canvas.style.left = "0";
canvas.style.top = "0";
this._private__topCanvasBinding = createBoundCanvas(this._private__cell, size({ width: 16, height: 16 }));
this._private__topCanvasBinding.subscribeSuggestedBitmapSizeChanged(this._private__topCanvasSuggestedBitmapSizeChangedHandler);
const topCanvas = this._private__topCanvasBinding.canvasElement;
topCanvas.style.position = "absolute";
topCanvas.style.zIndex = "2";
topCanvas.style.left = "0";
topCanvas.style.top = "0";
const handler = {
_internal_mouseDownEvent: this._private__mouseDownEvent.bind(this),
_internal_touchStartEvent: this._private__mouseDownEvent.bind(this),
_internal_pressedMouseMoveEvent: this._private__pressedMouseMoveEvent.bind(this),
_internal_touchMoveEvent: this._private__pressedMouseMoveEvent.bind(this),
_internal_mouseDownOutsideEvent: this._private__mouseDownOutsideEvent.bind(this),
_internal_mouseUpEvent: this._private__mouseUpEvent.bind(this),
_internal_touchEndEvent: this._private__mouseUpEvent.bind(this),
_internal_mouseDoubleClickEvent: this._private__mouseDoubleClickEvent.bind(this),
_internal_doubleTapEvent: this._private__mouseDoubleClickEvent.bind(this),
_internal_mouseEnterEvent: this._private__mouseEnterEvent.bind(this),
_internal_mouseLeaveEvent: this._private__mouseLeaveEvent.bind(this)
};
this._private__mouseEventHandler = new MouseEventHandler(this._private__topCanvasBinding.canvasElement, handler, {
_internal_treatVertTouchDragAsPageScroll: () => !this._private__options.handleScroll.vertTouchDrag,
_internal_treatHorzTouchDragAsPageScroll: () => true
});
}
_internal_destroy() {
this._private__mouseEventHandler._internal_destroy();
this._private__topCanvasBinding.unsubscribeSuggestedBitmapSizeChanged(this._private__topCanvasSuggestedBitmapSizeChangedHandler);
releaseCanvas(this._private__topCanvasBinding.canvasElement);
this._private__topCanvasBinding.dispose();
this._private__canvasBinding.unsubscribeSuggestedBitmapSizeChanged(this._private__canvasSuggestedBitmapSizeChangedHandler);
releaseCanvas(this._private__canvasBinding.canvasElement);
this._private__canvasBinding.dispose();
if (this._private__priceScale !== null) {
this._private__priceScale._internal_onMarksChanged()._internal_unsubscribeAll(this);
}
this._private__priceScale = null;
}
_internal_getElement() {
return this._private__cell;
}
_internal_fontSize() {
return this._private__layoutOptions.fontSize;
}
_internal_rendererOptions() {
const options = this._private__rendererOptionsProvider._internal_options();
const isFontChanged = this._private__font !== options._internal_font;
if (isFontChanged) {
this._private__widthCache._internal_reset();
this._private__font = options._internal_font;
}
return options;
}
_internal_optimalWidth() {
if (this._private__priceScale === null) {
return 0;
}
let tickMarkMaxWidth = 0;
const rendererOptions = this._internal_rendererOptions();
const ctx = ensureNotNull(this._private__canvasBinding.canvasElement.getContext("2d"));
ctx.save();
const tickMarks = this._private__priceScale._internal_marks();
ctx.font = this._private__baseFont();
if (tickMarks.length > 0) {
tickMarkMaxWidth = Math.max(this._private__widthCache._internal_measureText(ctx, tickMarks[0]._internal_label), this._private__widthCache._internal_measureText(ctx, tickMarks[tickMarks.length - 1]._internal_label));
}
const views = this._private__backLabels();
for (let j = views.length; j--; ) {
const width = this._private__widthCache._internal_measureText(ctx, views[j]._internal_text());
if (width > tickMarkMaxWidth) {
tickMarkMaxWidth = width;
}
}
const firstValue = this._private__priceScale._internal_firstValue();
if (firstValue !== null && this._private__size !== null && priceScaleCrosshairLabelVisible(this._private__options.crosshair)) {
const topValue = this._private__priceScale._internal_coordinateToPrice(1, firstValue);
const bottomValue = this._private__priceScale._internal_coordinateToPrice(this._private__size.height - 2, firstValue);
tickMarkMaxWidth = Math.max(tickMarkMaxWidth, this._private__widthCache._internal_measureText(ctx, this._private__priceScale._internal_formatPrice(Math.floor(Math.min(topValue, bottomValue)) + 0.11111111111111, firstValue)), this._private__widthCache._internal_measureText(ctx, this._private__priceScale._internal_formatPrice(Math.ceil(Math.max(topValue, bottomValue)) - 0.11111111111111, firstValue)));
}
ctx.restore();
const resultTickMarksMaxWidth = tickMarkMaxWidth || 34;
const res = Math.ceil(rendererOptions._internal_borderSize + rendererOptions._internal_tickLength + rendererOptions._internal_paddingInner + rendererOptions._internal_paddingOuter + 5 + resultTickMarksMaxWidth);
return suggestPriceScaleWidth(res);
}
_internal_setSize(newSize) {
if (this._private__size === null || !equalSizes(this._private__size, newSize)) {
this._private__size = newSize;
this._private__isSettingSize = true;
this._private__canvasBinding.resizeCanvasElement(newSize);
this._private__topCanvasBinding.resizeCanvasElement(newSize);
this._private__isSettingSize = false;
this._private__cell.style.width = `${newSize.width}px`;
this._private__cell.style.height = `${newSize.height}px`;
}
}
_internal_getWidth() {
return ensureNotNull(this._private__size).width;
}
_internal_setPriceScale(priceScale) {
if (this._private__priceScale === priceScale) {
return;
}
if (this._private__priceScale !== null) {
this._private__priceScale._internal_onMarksChanged()._internal_unsubscribeAll(this);
}
this._private__priceScale = priceScale;
priceScale._internal_onMarksChanged()._internal_subscribe(this._private__onMarksChanged.bind(this), this);
}
_internal_priceScale() {
return this._private__priceScale;
}
_internal_reset() {
const pane = this._private__pane._internal_state();
const model = this._private__pane._internal_chart()._internal_model();
model._internal_resetPriceScale(pane, ensureNotNull(this._internal_priceScale()));
}
_internal_paint(type) {
if (this._private__size === null) {
return;
}
if (type !== 1) {
this._private__alignLabels();
this._private__canvasBinding.applySuggestedBitmapSize();
const target = tryCreateCanvasRenderingTarget2D(this._private__canvasBinding);
if (target !== null) {
target.useBitmapCoordinateSpace((scope) => {
this._private__drawBackground(scope);
this._private__drawBorder(scope);
});
this._private__pane._internal_drawAdditionalSources(target, this._private__sourceBottomPaneViews);
this._private__drawTickMarks(target);
this._private__pane._internal_drawAdditionalSources(target, this._private__sourcePaneViews);
this._private__drawBackLabels(target);
}
}
this._private__topCanvasBinding.applySuggestedBitmapSize();
const topTarget = tryCreateCanvasRenderingTarget2D(this._private__topCanvasBinding);
if (topTarget !== null) {
topTarget.useBitmapCoordinateSpace(({ context: ctx, bitmapSize }) => {
ctx.clearRect(0, 0, bitmapSize.width, bitmapSize.height);
});
this._private__drawCrosshairLabel(topTarget);
this._private__pane._internal_drawAdditionalSources(topTarget, this._private__sourceTopPaneViews);
}
}
_internal_getBitmapSize() {
return this._private__canvasBinding.bitmapSize;
}
_internal_drawBitmap(ctx, x, y) {
const bitmapSize = this._internal_getBitmapSize();
if (bitmapSize.width > 0 && bitmapSize.height > 0) {
ctx.drawImage(this._private__canvasBinding.canvasElement, x, y);
}
}
_internal_update() {
var _a;
(_a = this._private__priceScale) === null || _a === void 0 ? void 0 : _a._internal_marks();
}
_private__mouseDownEvent(e) {
if (this._private__priceScale === null || this._private__priceScale._internal_isEmpty() || !this._private__options.handleScale.axisPressedMouseMove.price) {
return;
}
const model = this._private__pane._internal_chart()._internal_model();
const pane = this._private__pane._internal_state();
this._private__mousedown = true;
model._internal_startScalePrice(pane, this._private__priceScale, e.localY);
}
_private__pressedMouseMoveEvent(e) {
if (this._private__priceScale === null || !this._private__options.handleScale.axisPressedMouseMove.price) {
return;
}
const model = this._private__pane._internal_chart()._internal_model();
const pane = this._private__pane._internal_state();
const priceScale = this._private__priceScale;
model._internal_scalePriceTo(pane, priceScale, e.localY);
}
_private__mouseDownOutsideEvent() {
if (this._private__priceScale === null || !this._private__options.handleScale.axisPressedMouseMove.price) {
return;
}
const model = this._private__pane._internal_chart()._internal_model();
const pane = this._private__pane._internal_state();
const priceScale = this._private__priceScale;
if (this._private__mousedown) {
this._private__mousedown = false;
model._internal_endScalePrice(pane, priceScale);
}
}
_private__mouseUpEvent(e) {
if (this._private__priceScale === null || !this._private__options.handleScale.axisPressedMouseMove.price) {
return;
}
const model = this._private__pane._internal_chart()._internal_model();
const pane = this._private__pane._internal_state();
this._private__mousedown = false;
model._internal_endScalePrice(pane, this._private__priceScale);
}
_private__mouseDoubleClickEvent(e) {
if (this._private__options.handleScale.axisDoubleClickReset.price) {
this._internal_reset();
}
}
_private__mouseEnterEvent(e) {
if (this._private__priceScale === null) {
return;
}
const model = this._private__pane._internal_chart()._internal_model();
if (model._internal_options().handleScale.axisPressedMouseMove.price && !this._private__priceScale._internal_isPercentage() && !this._private__priceScale._internal_isIndexedTo100()) {
this._private__setCursor(
1
/* CursorType.NsResize */
);
}
}
_private__mouseLeaveEvent(e) {
this._private__setCursor(
0
/* CursorType.Default */
);
}
_private__backLabels() {
const res = [];
const priceScale = this._private__priceScale === null ? void 0 : this._private__priceScale;
const addViewsForSources = (sources) => {
for (let i = 0; i < sources.length; ++i) {
const source = sources[i];
const views = source._internal_priceAxisViews(this._private__pane._internal_state(), priceScale);
for (let j = 0; j < views.length; j++) {
res.push(views[j]);
}
}
};
addViewsForSources(this._private__pane._internal_state()._internal_orderedSources());
return res;
}
_private__drawBackground({ context: ctx, bitmapSize }) {
const { width, height } = bitmapSize;
const model = this._private__pane._internal_state()._internal_model();
const topColor = model._internal_backgroundTopColor();
const bottomColor = model._internal_backgroundBottomColor();
if (topColor === bottomColor) {
clearRect(ctx, 0, 0, width, height, topColor);
} else {
clearRectWithGradient(ctx, 0, 0, width, height, topColor, bottomColor);
}
}
_private__drawBorder({ context: ctx, bitmapSize, horizontalPixelRatio }) {
if (this._private__size === null || this._private__priceScale === null || !this._private__priceScale._internal_options().borderVisible) {
return;
}
ctx.fillStyle = this._private__priceScale._internal_options().borderColor;
const borderSize = Math.max(1, Math.floor(this._internal_rendererOptions()._internal_borderSize * horizontalPixelRatio));
let left;
if (this._private__isLeft) {
left = bitmapSize.width - borderSize;
} else {
left = 0;
}
ctx.fillRect(left, 0, borderSize, bitmapSize.height);
}
_private__drawTickMarks(target) {
if (this._private__size === null || this._private__priceScale === null) {
return;
}
const tickMarks = this._private__priceScale._internal_marks();
const priceScaleOptions = this._private__priceScale._internal_options();
const rendererOptions = this._internal_rendererOptions();
const tickMarkLeftX = this._private__isLeft ? this._private__size.width - rendererOptions._internal_tickLength : 0;
if (priceScaleOptions.borderVisible && priceScaleOptions.ticksVisible) {
target.useBitmapCoordinateSpace(({ context: ctx, horizontalPixelRatio, verticalPixelRatio }) => {
ctx.fillStyle = priceScaleOptions.borderColor;
const tickHeight = Math.max(1, Math.floor(verticalPixelRatio));
const tickOffset = Math.floor(verticalPixelRatio * 0.5);
const tickLength = Math.round(rendererOptions._internal_tickLength * horizontalPixelRatio);
ctx.beginPath();
for (const tickMark of tickMarks) {
ctx.rect(Math.floor(tickMarkLeftX * horizontalPixelRatio), Math.round(tickMark._internal_coord * verticalPixelRatio) - tickOffset, tickLength, tickHeight);
}
ctx.fill();
});
}
target.useMediaCoordinateSpace(({ context: ctx }) => {
var _a;
ctx.font = this._private__baseFont();
ctx.fillStyle = (_a = priceScaleOptions.textColor) !== null && _a !== void 0 ? _a : this._private__layoutOptions.textColor;
ctx.textAlign = this._private__isLeft ? "right" : "left";
ctx.textBaseline = "middle";
const textLeftX = this._private__isLeft ? Math.round(tickMarkLeftX - rendererOptions._internal_paddingInner) : Math.round(tickMarkLeftX + rendererOptions._internal_tickLength + rendererOptions._internal_paddingInner);
const yMidCorrections = tickMarks.map((mark) => this._private__widthCache._internal_yMidCorrection(ctx, mark._internal_label));
for (let i = tickMarks.length; i--; ) {
const tickMark = tickMarks[i];
ctx.fillText(tickMark._internal_label, textLeftX, tickMark._internal_coord + yMidCorrections[i]);
}
});
}
_private__alignLabels() {
if (this._private__size === null || this._private__priceScale === null) {
return;
}
const views = [];
const orderedSources = this._private__priceScale._internal_orderedSources().slice();
const pane = this._private__pane;
const paneState = pane._internal_state();
const rendererOptions = this._internal_rendererOptions();
const isDefault = this._private__priceScale === paneState._internal_defaultVisiblePriceScale();
if (isDefault) {
this._private__pane._internal_state()._internal_orderedSources().forEach((source) => {
if (paneState._internal_isOverlay(source)) {
orderedSources.push(source);
}
});
}
const priceScale = this._private__priceScale;
const updateForSources = (sources) => {
sources.forEach((source) => {
const sourceViews = source._internal_priceAxisViews(paneState, priceScale);
sourceViews.forEach((view) => {
view._internal_setFixedCoordinate(null);
if (view._internal_isVisible()) {
views.push(view);
}
});
});
};
updateForSources(orderedSources);
views.forEach((view) => view._internal_setFixedCoordinate(view._internal_coordinate()));
const options = this._private__priceScale._internal_options();
if (!options.alignLabels) {
return;
}
this._private__fixLabelOverlap(views, rendererOptions);
}
_private__fixLabelOverlap(views, rendererOptions) {
if (this._private__size === null) {
return;
}
const center = this._private__size.height / 2;
const top = views.filter((view) => view._internal_coordinate() <= center);
const bottom = views.filter((view) => view._internal_coordinate() > center);
top.sort((l, r) => r._internal_coordinate() - l._internal_coordinate());
bottom.sort((l, r) => l._internal_coordinate() - r._internal_coordinate());
for (const view of views) {
const halfHeight = Math.floor(view._internal_height(rendererOptions) / 2);
const coordinate = view._internal_coordinate();
if (coordinate > -halfHeight && coordinate < halfHeight) {
view._internal_setFixedCoordinate(halfHeight);
}
if (coordinate > this._private__size.height - halfHeight && coordinate < this._private__size.height + halfHeight) {
view._internal_setFixedCoordinate(this._private__size.height - halfHeight);
}
}
recalculateOverlapping(top, 1, this._private__size.height, rendererOptions);
recalculateOverlapping(bottom, -1, this._private__size.height, rendererOptions);
}
_private__drawBackLabels(target) {
if (this._private__size === null) {
return;
}
const views = this._private__backLabels();
const rendererOptions = this._internal_rendererOptions();
const align = this._private__isLeft ? "right" : "left";
views.forEach((view) => {
if (view._internal_isAxisLabelVisible()) {
const renderer = view._internal_renderer(ensureNotNull(this._private__priceScale));
renderer._internal_draw(target, rendererOptions, this._private__widthCache, align);
}
});
}
_private__drawCrosshairLabel(target) {
if (this._private__size === null || this._private__priceScale === null) {
return;
}
const model = this._private__pane._internal_chart()._internal_model();
const views = [];
const pane = this._private__pane._internal_state();
const v = model._internal_crosshairSource()._internal_priceAxisViews(pane, this._private__priceScale);
if (v.length) {
views.push(v);
}
const ro = this._internal_rendererOptions();
const align = this._private__isLeft ? "right" : "left";
views.forEach((arr) => {
arr.forEach((view) => {
view._internal_renderer(ensureNotNull(this._private__priceScale))._internal_draw(target, ro, this._private__widthCache, align);
});
});
}
_private__setCursor(type) {
this._private__cell.style.cursor = type === 1 ? "ns-resize" : "default";
}
_private__onMarksChanged() {
const width = this._internal_optimalWidth();
if (this._private__prevOptimalWidth < width) {
this._private__pane._internal_chart()._internal_model()._internal_fullUpdate();
}
this._private__prevOptimalWidth = width;
}
_private__baseFont() {
return makeFont(this._private__layoutOptions.fontSize, this._private__layoutOptions.fontFamily);
}
};
function sourceBottomPaneViews$1(source, pane) {
var _a, _b;
return (_b = (_a = source._internal_bottomPaneViews) === null || _a === void 0 ? void 0 : _a.call(source, pane)) !== null && _b !== void 0 ? _b : [];
}
function sourcePaneViews$1(source, pane) {
var _a, _b;
return (_b = (_a = source._internal_paneViews) === null || _a === void 0 ? void 0 : _a.call(source, pane)) !== null && _b !== void 0 ? _b : [];
}
function sourceLabelPaneViews(source, pane) {
var _a, _b;
return (_b = (_a = source._internal_labelPaneViews) === null || _a === void 0 ? void 0 : _a.call(source, pane)) !== null && _b !== void 0 ? _b : [];
}
function sourceTopPaneViews$1(source, pane) {
var _a, _b;
return (_b = (_a = source._internal_topPaneViews) === null || _a === void 0 ? void 0 : _a.call(source, pane)) !== null && _b !== void 0 ? _b : [];
}
var PaneWidget = class _PaneWidget {
constructor(chart, state) {
this._private__size = size({ width: 0, height: 0 });
this._private__leftPriceAxisWidget = null;
this._private__rightPriceAxisWidget = null;
this._private__attributionLogoWidget = null;
this._private__startScrollingPos = null;
this._private__isScrolling = false;
this._private__clicked = new Delegate();
this._private__dblClicked = new Delegate();
this._private__prevPinchScale = 0;
this._private__longTap = false;
this._private__startTrackPoint = null;
this._private__exitTrackingModeOnNextTry = false;
this._private__initCrosshairPosition = null;
this._private__scrollXAnimation = null;
this._private__isSettingSize = false;
this._private__canvasSuggestedBitmapSizeChangedHandler = () => {
if (this._private__isSettingSize || this._private__state === null) {
return;
}
this._private__model()._internal_lightUpdate();
};
this._private__topCanvasSuggestedBitmapSizeChangedHandler = () => {
if (this._private__isSettingSize || this._private__state === null) {
return;
}
this._private__model()._internal_lightUpdate();
};
this._private__chart = chart;
this._private__state = state;
this._private__state._internal_onDestroyed()._internal_subscribe(this._private__onStateDestroyed.bind(this), this, true);
this._private__paneCell = document.createElement("td");
this._private__paneCell.style.padding = "0";
this._private__paneCell.style.position = "relative";
const paneWrapper = document.createElement("div");
paneWrapper.style.width = "100%";
paneWrapper.style.height = "100%";
paneWrapper.style.position = "relative";
paneWrapper.style.overflow = "hidden";
this._private__leftAxisCell = document.createElement("td");
this._private__leftAxisCell.style.padding = "0";
this._private__rightAxisCell = document.createElement("td");
this._private__rightAxisCell.style.padding = "0";
this._private__paneCell.appendChild(paneWrapper);
this._private__canvasBinding = createBoundCanvas(paneWrapper, size({ width: 16, height: 16 }));
this._private__canvasBinding.subscribeSuggestedBitmapSizeChanged(this._private__canvasSuggestedBitmapSizeChangedHandler);
const canvas = this._private__canvasBinding.canvasElement;
canvas.style.position = "absolute";
canvas.style.zIndex = "1";
canvas.style.left = "0";
canvas.style.top = "0";
this._private__topCanvasBinding = createBoundCanvas(paneWrapper, size({ width: 16, height: 16 }));
this._private__topCanvasBinding.subscribeSuggestedBitmapSizeChanged(this._private__topCanvasSuggestedBitmapSizeChangedHandler);
const topCanvas = this._private__topCanvasBinding.canvasElement;
topCanvas.style.position = "absolute";
topCanvas.style.zIndex = "2";
topCanvas.style.left = "0";
topCanvas.style.top = "0";
this._private__rowElement = document.createElement("tr");
this._private__rowElement.appendChild(this._private__leftAxisCell);
this._private__rowElement.appendChild(this._private__paneCell);
this._private__rowElement.appendChild(this._private__rightAxisCell);
this._internal_updatePriceAxisWidgetsStates();
this._private__mouseEventHandler = new MouseEventHandler(this._private__topCanvasBinding.canvasElement, this, {
_internal_treatVertTouchDragAsPageScroll: () => this._private__startTrackPoint === null && !this._private__chart._internal_options().handleScroll.vertTouchDrag,
_internal_treatHorzTouchDragAsPageScroll: () => this._private__startTrackPoint === null && !this._private__chart._internal_options().handleScroll.horzTouchDrag
});
}
_internal_destroy() {
if (this._private__leftPriceAxisWidget !== null) {
this._private__leftPriceAxisWidget._internal_destroy();
}
if (this._private__rightPriceAxisWidget !== null) {
this._private__rightPriceAxisWidget._internal_destroy();
}
this._private__attributionLogoWidget = null;
this._private__topCanvasBinding.unsubscribeSuggestedBitmapSizeChanged(this._private__topCanvasSuggestedBitmapSizeChangedHandler);
releaseCanvas(this._private__topCanvasBinding.canvasElement);
this._private__topCanvasBinding.dispose();
this._private__canvasBinding.unsubscribeSuggestedBitmapSizeChanged(this._private__canvasSuggestedBitmapSizeChangedHandler);
releaseCanvas(this._private__canvasBinding.canvasElement);
this._private__canvasBinding.dispose();
if (this._private__state !== null) {
this._private__state._internal_onDestroyed()._internal_unsubscribeAll(this);
}
this._private__mouseEventHandler._internal_destroy();
}
_internal_state() {
return ensureNotNull(this._private__state);
}
_internal_setState(pane) {
var _a, _b;
if (this._private__state !== null) {
this._private__state._internal_onDestroyed()._internal_unsubscribeAll(this);
}
this._private__state = pane;
if (this._private__state !== null) {
this._private__state._internal_onDestroyed()._internal_subscribe(_PaneWidget.prototype._private__onStateDestroyed.bind(this), this, true);
}
this._internal_updatePriceAxisWidgetsStates();
if (this._private__chart._internal_paneWidgets().indexOf(this) === this._private__chart._internal_paneWidgets().length - 1) {
this._private__attributionLogoWidget = (_a = this._private__attributionLogoWidget) !== null && _a !== void 0 ? _a : new AttributionLogoWidget(this._private__paneCell, this._private__chart);
this._private__attributionLogoWidget._internal_update();
} else {
(_b = this._private__attributionLogoWidget) === null || _b === void 0 ? void 0 : _b._internal_removeElement();
this._private__attributionLogoWidget = null;
}
}
_internal_chart() {
return this._private__chart;
}
_internal_getElement() {
return this._private__rowElement;
}
_internal_updatePriceAxisWidgetsStates() {
if (this._private__state === null) {
return;
}
this._private__recreatePriceAxisWidgets();
if (this._private__model()._internal_serieses().length === 0) {
return;
}
if (this._private__leftPriceAxisWidget !== null) {
const leftPriceScale = this._private__state._internal_leftPriceScale();
this._private__leftPriceAxisWidget._internal_setPriceScale(ensureNotNull(leftPriceScale));
}
if (this._private__rightPriceAxisWidget !== null) {
const rightPriceScale = this._private__state._internal_rightPriceScale();
this._private__rightPriceAxisWidget._internal_setPriceScale(ensureNotNull(rightPriceScale));
}
}
_internal_updatePriceAxisWidgets() {
if (this._private__leftPriceAxisWidget !== null) {
this._private__leftPriceAxisWidget._internal_update();
}
if (this._private__rightPriceAxisWidget !== null) {
this._private__rightPriceAxisWidget._internal_update();
}
}
_internal_stretchFactor() {
return this._private__state !== null ? this._private__state._internal_stretchFactor() : 0;
}
_internal_setStretchFactor(stretchFactor) {
if (this._private__state) {
this._private__state._internal_setStretchFactor(stretchFactor);
}
}
_internal_mouseEnterEvent(event) {
if (!this._private__state) {
return;
}
this._private__onMouseEvent();
const x = event.localX;
const y = event.localY;
this._private__setCrosshairPosition(x, y, event);
}
_internal_mouseDownEvent(event) {
this._private__onMouseEvent();
this._private__mouseTouchDownEvent();
this._private__setCrosshairPosition(event.localX, event.localY, event);
}
_internal_mouseMoveEvent(event) {
var _a;
if (!this._private__state) {
return;
}
this._private__onMouseEvent();
const x = event.localX;
const y = event.localY;
this._private__setCrosshairPosition(x, y, event);
const hitTest = this._internal_hitTest(x, y);
this._private__chart._internal_setCursorStyle((_a = hitTest === null || hitTest === void 0 ? void 0 : hitTest._internal_cursorStyle) !== null && _a !== void 0 ? _a : null);
this._private__model()._internal_setHoveredSource(hitTest && { _internal_source: hitTest._internal_source, _internal_object: hitTest._internal_object });
}
_internal_mouseClickEvent(event) {
if (this._private__state === null) {
return;
}
this._private__onMouseEvent();
this._private__fireClickedDelegate(event);
}
_internal_mouseDoubleClickEvent(event) {
if (this._private__state === null) {
return;
}
this._private__fireMouseClickDelegate(this._private__dblClicked, event);
}
_internal_doubleTapEvent(event) {
this._internal_mouseDoubleClickEvent(event);
}
_internal_pressedMouseMoveEvent(event) {
this._private__onMouseEvent();
this._private__pressedMouseTouchMoveEvent(event);
this._private__setCrosshairPosition(event.localX, event.localY, event);
}
_internal_mouseUpEvent(event) {
if (this._private__state === null) {
return;
}
this._private__onMouseEvent();
this._private__longTap = false;
this._private__endScroll(event);
}
_internal_tapEvent(event) {
if (this._private__state === null) {
return;
}
this._private__fireClickedDelegate(event);
}
_internal_longTapEvent(event) {
this._private__longTap = true;
if (this._private__startTrackPoint === null) {
const point = { x: event.localX, y: event.localY };
this._private__startTrackingMode(point, point, event);
}
}
_internal_mouseLeaveEvent(event) {
if (this._private__state === null) {
return;
}
this._private__onMouseEvent();
this._private__state._internal_model()._internal_setHoveredSource(null);
this._private__clearCrosshairPosition();
}
_internal_clicked() {
return this._private__clicked;
}
_internal_dblClicked() {
return this._private__dblClicked;
}
_internal_pinchStartEvent() {
this._private__prevPinchScale = 1;
this._private__model()._internal_stopTimeScaleAnimation();
}
_internal_pinchEvent(middlePoint, scale) {
if (!this._private__chart._internal_options().handleScale.pinch) {
return;
}
const zoomScale = (scale - this._private__prevPinchScale) * 5;
this._private__prevPinchScale = scale;
this._private__model()._internal_zoomTime(middlePoint._internal_x, zoomScale);
}
_internal_touchStartEvent(event) {
this._private__longTap = false;
this._private__exitTrackingModeOnNextTry = this._private__startTrackPoint !== null;
this._private__mouseTouchDownEvent();
const crosshair = this._private__model()._internal_crosshairSource();
if (this._private__startTrackPoint !== null && crosshair._internal_visible()) {
this._private__initCrosshairPosition = { x: crosshair._internal_appliedX(), y: crosshair._internal_appliedY() };
this._private__startTrackPoint = { x: event.localX, y: event.localY };
}
}
_internal_touchMoveEvent(event) {
if (this._private__state === null) {
return;
}
const x = event.localX;
const y = event.localY;
if (this._private__startTrackPoint !== null) {
this._private__exitTrackingModeOnNextTry = false;
const origPoint = ensureNotNull(this._private__initCrosshairPosition);
const newX = origPoint.x + (x - this._private__startTrackPoint.x);
const newY = origPoint.y + (y - this._private__startTrackPoint.y);
this._private__setCrosshairPosition(newX, newY, event);
return;
}
this._private__pressedMouseTouchMoveEvent(event);
}
_internal_touchEndEvent(event) {
if (this._internal_chart()._internal_options().trackingMode.exitMode === 0) {
this._private__exitTrackingModeOnNextTry = true;
}
this._private__tryExitTrackingMode();
this._private__endScroll(event);
}
_internal_hitTest(x, y) {
const state = this._private__state;
if (state === null) {
return null;
}
return hitTestPane(state, x, y);
}
_internal_setPriceAxisSize(width, position) {
const priceAxisWidget = position === "left" ? this._private__leftPriceAxisWidget : this._private__rightPriceAxisWidget;
ensureNotNull(priceAxisWidget)._internal_setSize(size({ width, height: this._private__size.height }));
}
_internal_getSize() {
return this._private__size;
}
_internal_setSize(newSize) {
if (equalSizes(this._private__size, newSize)) {
return;
}
this._private__size = newSize;
this._private__isSettingSize = true;
this._private__canvasBinding.resizeCanvasElement(newSize);
this._private__topCanvasBinding.resizeCanvasElement(newSize);
this._private__isSettingSize = false;
this._private__paneCell.style.width = newSize.width + "px";
this._private__paneCell.style.height = newSize.height + "px";
}
_internal_recalculatePriceScales() {
const pane = ensureNotNull(this._private__state);
pane._internal_recalculatePriceScale(pane._internal_leftPriceScale());
pane._internal_recalculatePriceScale(pane._internal_rightPriceScale());
for (const source of pane._internal_dataSources()) {
if (pane._internal_isOverlay(source)) {
const priceScale = source._internal_priceScale();
if (priceScale !== null) {
pane._internal_recalculatePriceScale(priceScale);
}
source._internal_updateAllViews();
}
}
}
_internal_getBitmapSize() {
return this._private__canvasBinding.bitmapSize;
}
_internal_drawBitmap(ctx, x, y) {
const bitmapSize = this._internal_getBitmapSize();
if (bitmapSize.width > 0 && bitmapSize.height > 0) {
ctx.drawImage(this._private__canvasBinding.canvasElement, x, y);
}
}
_internal_paint(type) {
if (type === 0) {
return;
}
if (this._private__state === null) {
return;
}
if (type > 1) {
this._internal_recalculatePriceScales();
}
if (this._private__leftPriceAxisWidget !== null) {
this._private__leftPriceAxisWidget._internal_paint(type);
}
if (this._private__rightPriceAxisWidget !== null) {
this._private__rightPriceAxisWidget._internal_paint(type);
}
if (type !== 1) {
this._private__canvasBinding.applySuggestedBitmapSize();
const target = tryCreateCanvasRenderingTarget2D(this._private__canvasBinding);
if (target !== null) {
target.useBitmapCoordinateSpace((scope) => {
this._private__drawBackground(scope);
});
if (this._private__state) {
this._private__drawSources(target, sourceBottomPaneViews$1);
this._private__drawGrid(target);
this._private__drawWatermark(target);
this._private__drawSources(target, sourcePaneViews$1);
this._private__drawSources(target, sourceLabelPaneViews);
}
}
}
this._private__topCanvasBinding.applySuggestedBitmapSize();
const topTarget = tryCreateCanvasRenderingTarget2D(this._private__topCanvasBinding);
if (topTarget !== null) {
topTarget.useBitmapCoordinateSpace(({ context: ctx, bitmapSize }) => {
ctx.clearRect(0, 0, bitmapSize.width, bitmapSize.height);
});
this._private__drawCrosshair(topTarget);
this._private__drawSources(topTarget, sourceTopPaneViews$1);
}
}
_internal_leftPriceAxisWidget() {
return this._private__leftPriceAxisWidget;
}
_internal_rightPriceAxisWidget() {
return this._private__rightPriceAxisWidget;
}
_internal_drawAdditionalSources(target, paneViewsGetter) {
this._private__drawSources(target, paneViewsGetter);
}
_private__onStateDestroyed() {
if (this._private__state !== null) {
this._private__state._internal_onDestroyed()._internal_unsubscribeAll(this);
}
this._private__state = null;
}
_private__fireClickedDelegate(event) {
this._private__fireMouseClickDelegate(this._private__clicked, event);
}
_private__fireMouseClickDelegate(delegate, event) {
const x = event.localX;
const y = event.localY;
if (delegate._internal_hasListeners()) {
delegate._internal_fire(this._private__model()._internal_timeScale()._internal_coordinateToIndex(x), { x, y }, event);
}
}
_private__drawBackground({ context: ctx, bitmapSize }) {
const { width, height } = bitmapSize;
const model = this._private__model();
const topColor = model._internal_backgroundTopColor();
const bottomColor = model._internal_backgroundBottomColor();
if (topColor === bottomColor) {
clearRect(ctx, 0, 0, width, height, bottomColor);
} else {
clearRectWithGradient(ctx, 0, 0, width, height, topColor, bottomColor);
}
}
_private__drawGrid(target) {
const state = ensureNotNull(this._private__state);
const paneView = state._internal_grid()._internal_paneView();
const renderer = paneView._internal_renderer();
if (renderer !== null) {
renderer._internal_draw(target, false);
}
}
_private__drawWatermark(target) {
const source = this._private__model()._internal_watermarkSource();
this._private__drawSourceImpl(target, sourcePaneViews$1, drawBackground, source);
this._private__drawSourceImpl(target, sourcePaneViews$1, drawForeground, source);
}
_private__drawCrosshair(target) {
this._private__drawSourceImpl(target, sourcePaneViews$1, drawForeground, this._private__model()._internal_crosshairSource());
}
_private__drawSources(target, paneViewsGetter) {
const state = ensureNotNull(this._private__state);
const sources = state._internal_orderedSources();
for (const source of sources) {
this._private__drawSourceImpl(target, paneViewsGetter, drawBackground, source);
}
for (const source of sources) {
this._private__drawSourceImpl(target, paneViewsGetter, drawForeground, source);
}
}
_private__drawSourceImpl(target, paneViewsGetter, drawFn, source) {
const state = ensureNotNull(this._private__state);
const hoveredSource = state._internal_model()._internal_hoveredSource();
const isHovered = hoveredSource !== null && hoveredSource._internal_source === source;
const objecId = hoveredSource !== null && isHovered && hoveredSource._internal_object !== void 0 ? hoveredSource._internal_object._internal_hitTestData : void 0;
const drawRendererFn = (renderer) => drawFn(renderer, target, isHovered, objecId);
drawSourcePaneViews(paneViewsGetter, drawRendererFn, source, state);
}
_private__recreatePriceAxisWidgets() {
if (this._private__state === null) {
return;
}
const chart = this._private__chart;
const leftAxisVisible = this._private__state._internal_leftPriceScale()._internal_options().visible;
const rightAxisVisible = this._private__state._internal_rightPriceScale()._internal_options().visible;
if (!leftAxisVisible && this._private__leftPriceAxisWidget !== null) {
this._private__leftAxisCell.removeChild(this._private__leftPriceAxisWidget._internal_getElement());
this._private__leftPriceAxisWidget._internal_destroy();
this._private__leftPriceAxisWidget = null;
}
if (!rightAxisVisible && this._private__rightPriceAxisWidget !== null) {
this._private__rightAxisCell.removeChild(this._private__rightPriceAxisWidget._internal_getElement());
this._private__rightPriceAxisWidget._internal_destroy();
this._private__rightPriceAxisWidget = null;
}
const rendererOptionsProvider = chart._internal_model()._internal_rendererOptionsProvider();
if (leftAxisVisible && this._private__leftPriceAxisWidget === null) {
this._private__leftPriceAxisWidget = new PriceAxisWidget(this, chart._internal_options(), rendererOptionsProvider, "left");
this._private__leftAxisCell.appendChild(this._private__leftPriceAxisWidget._internal_getElement());
}
if (rightAxisVisible && this._private__rightPriceAxisWidget === null) {
this._private__rightPriceAxisWidget = new PriceAxisWidget(this, chart._internal_options(), rendererOptionsProvider, "right");
this._private__rightAxisCell.appendChild(this._private__rightPriceAxisWidget._internal_getElement());
}
}
_private__preventScroll(event) {
return event._internal_isTouch && this._private__longTap || this._private__startTrackPoint !== null;
}
_private__correctXCoord(x) {
return Math.max(0, Math.min(x, this._private__size.width - 1));
}
_private__correctYCoord(y) {
return Math.max(0, Math.min(y, this._private__size.height - 1));
}
_private__setCrosshairPosition(x, y, event) {
this._private__model()._internal_setAndSaveCurrentPosition(this._private__correctXCoord(x), this._private__correctYCoord(y), event, ensureNotNull(this._private__state));
}
_private__clearCrosshairPosition() {
this._private__model()._internal_clearCurrentPosition();
}
_private__tryExitTrackingMode() {
if (this._private__exitTrackingModeOnNextTry) {
this._private__startTrackPoint = null;
this._private__clearCrosshairPosition();
}
}
_private__startTrackingMode(startTrackPoint, crossHairPosition, event) {
this._private__startTrackPoint = startTrackPoint;
this._private__exitTrackingModeOnNextTry = false;
this._private__setCrosshairPosition(crossHairPosition.x, crossHairPosition.y, event);
const crosshair = this._private__model()._internal_crosshairSource();
this._private__initCrosshairPosition = { x: crosshair._internal_appliedX(), y: crosshair._internal_appliedY() };
}
_private__model() {
return this._private__chart._internal_model();
}
_private__endScroll(event) {
if (!this._private__isScrolling) {
return;
}
const model = this._private__model();
const state = this._internal_state();
model._internal_endScrollPrice(state, state._internal_defaultPriceScale());
this._private__startScrollingPos = null;
this._private__isScrolling = false;
model._internal_endScrollTime();
if (this._private__scrollXAnimation !== null) {
const startAnimationTime = performance.now();
const timeScale = model._internal_timeScale();
this._private__scrollXAnimation._internal_start(timeScale._internal_rightOffset(), startAnimationTime);
if (!this._private__scrollXAnimation._internal_finished(startAnimationTime)) {
model._internal_setTimeScaleAnimation(this._private__scrollXAnimation);
}
}
}
_private__onMouseEvent() {
this._private__startTrackPoint = null;
}
_private__mouseTouchDownEvent() {
if (!this._private__state) {
return;
}
this._private__model()._internal_stopTimeScaleAnimation();
if (document.activeElement !== document.body && document.activeElement !== document.documentElement) {
ensureNotNull(document.activeElement).blur();
} else {
const selection = document.getSelection();
if (selection !== null) {
selection.removeAllRanges();
}
}
const priceScale = this._private__state._internal_defaultPriceScale();
if (priceScale._internal_isEmpty() || this._private__model()._internal_timeScale()._internal_isEmpty()) {
return;
}
}
// eslint-disable-next-line complexity
_private__pressedMouseTouchMoveEvent(event) {
if (this._private__state === null) {
return;
}
const model = this._private__model();
const timeScale = model._internal_timeScale();
if (timeScale._internal_isEmpty()) {
return;
}
const chartOptions = this._private__chart._internal_options();
const scrollOptions = chartOptions.handleScroll;
const kineticScrollOptions = chartOptions.kineticScroll;
if ((!scrollOptions.pressedMouseMove || event._internal_isTouch) && (!scrollOptions.horzTouchDrag && !scrollOptions.vertTouchDrag || !event._internal_isTouch)) {
return;
}
const priceScale = this._private__state._internal_defaultPriceScale();
const now = performance.now();
if (this._private__startScrollingPos === null && !this._private__preventScroll(event)) {
this._private__startScrollingPos = {
x: event.clientX,
y: event.clientY,
_internal_timestamp: now,
_internal_localX: event.localX,
_internal_localY: event.localY
};
}
if (this._private__startScrollingPos !== null && !this._private__isScrolling && (this._private__startScrollingPos.x !== event.clientX || this._private__startScrollingPos.y !== event.clientY)) {
if (event._internal_isTouch && kineticScrollOptions.touch || !event._internal_isTouch && kineticScrollOptions.mouse) {
const barSpacing = timeScale._internal_barSpacing();
this._private__scrollXAnimation = new KineticAnimation(0.2 / barSpacing, 7 / barSpacing, 0.997, 15 / barSpacing);
this._private__scrollXAnimation._internal_addPosition(timeScale._internal_rightOffset(), this._private__startScrollingPos._internal_timestamp);
} else {
this._private__scrollXAnimation = null;
}
if (!priceScale._internal_isEmpty()) {
model._internal_startScrollPrice(this._private__state, priceScale, event.localY);
}
model._internal_startScrollTime(event.localX);
this._private__isScrolling = true;
}
if (this._private__isScrolling) {
if (!priceScale._internal_isEmpty()) {
model._internal_scrollPriceTo(this._private__state, priceScale, event.localY);
}
model._internal_scrollTimeTo(event.localX);
if (this._private__scrollXAnimation !== null) {
this._private__scrollXAnimation._internal_addPosition(timeScale._internal_rightOffset(), now);
}
}
}
};
var PriceAxisStub = class {
constructor(side, options, params, borderVisible, bottomColor) {
this._private__invalidated = true;
this._private__size = size({ width: 0, height: 0 });
this._private__canvasSuggestedBitmapSizeChangedHandler = () => this._internal_paint(
3
/* InvalidationLevel.Full */
);
this._private__isLeft = side === "left";
this._private__rendererOptionsProvider = params._internal_rendererOptionsProvider;
this._private__options = options;
this._private__borderVisible = borderVisible;
this._private__bottomColor = bottomColor;
this._private__cell = document.createElement("div");
this._private__cell.style.width = "25px";
this._private__cell.style.height = "100%";
this._private__cell.style.overflow = "hidden";
this._private__canvasBinding = createBoundCanvas(this._private__cell, size({ width: 16, height: 16 }));
this._private__canvasBinding.subscribeSuggestedBitmapSizeChanged(this._private__canvasSuggestedBitmapSizeChangedHandler);
}
_internal_destroy() {
this._private__canvasBinding.unsubscribeSuggestedBitmapSizeChanged(this._private__canvasSuggestedBitmapSizeChangedHandler);
releaseCanvas(this._private__canvasBinding.canvasElement);
this._private__canvasBinding.dispose();
}
_internal_getElement() {
return this._private__cell;
}
_internal_getSize() {
return this._private__size;
}
_internal_setSize(newSize) {
if (!equalSizes(this._private__size, newSize)) {
this._private__size = newSize;
this._private__canvasBinding.resizeCanvasElement(newSize);
this._private__cell.style.width = `${newSize.width}px`;
this._private__cell.style.height = `${newSize.height}px`;
this._private__invalidated = true;
}
}
_internal_paint(type) {
if (type < 3 && !this._private__invalidated) {
return;
}
if (this._private__size.width === 0 || this._private__size.height === 0) {
return;
}
this._private__invalidated = false;
this._private__canvasBinding.applySuggestedBitmapSize();
const target = tryCreateCanvasRenderingTarget2D(this._private__canvasBinding);
if (target !== null) {
target.useBitmapCoordinateSpace((scope) => {
this._private__drawBackground(scope);
this._private__drawBorder(scope);
});
}
}
_internal_getBitmapSize() {
return this._private__canvasBinding.bitmapSize;
}
_internal_drawBitmap(ctx, x, y) {
const bitmapSize = this._internal_getBitmapSize();
if (bitmapSize.width > 0 && bitmapSize.height > 0) {
ctx.drawImage(this._private__canvasBinding.canvasElement, x, y);
}
}
_private__drawBorder({ context: ctx, bitmapSize, horizontalPixelRatio, verticalPixelRatio }) {
if (!this._private__borderVisible()) {
return;
}
ctx.fillStyle = this._private__options.timeScale.borderColor;
const horzBorderSize = Math.floor(this._private__rendererOptionsProvider._internal_options()._internal_borderSize * horizontalPixelRatio);
const vertBorderSize = Math.floor(this._private__rendererOptionsProvider._internal_options()._internal_borderSize * verticalPixelRatio);
const left = this._private__isLeft ? bitmapSize.width - horzBorderSize : 0;
ctx.fillRect(left, 0, horzBorderSize, vertBorderSize);
}
_private__drawBackground({ context: ctx, bitmapSize }) {
clearRect(ctx, 0, 0, bitmapSize.width, bitmapSize.height, this._private__bottomColor());
}
};
function buildTimeAxisViewsGetter(zOrder) {
return (source) => {
var _a, _b;
return (_b = (_a = source._internal_timePaneViews) === null || _a === void 0 ? void 0 : _a.call(source, zOrder)) !== null && _b !== void 0 ? _b : [];
};
}
var sourcePaneViews = buildTimeAxisViewsGetter("normal");
var sourceTopPaneViews = buildTimeAxisViewsGetter("top");
var sourceBottomPaneViews = buildTimeAxisViewsGetter("bottom");
var TimeAxisWidget = class {
constructor(chartWidget, horzScaleBehavior) {
this._private__leftStub = null;
this._private__rightStub = null;
this._private__rendererOptions = null;
this._private__mouseDown = false;
this._private__size = size({ width: 0, height: 0 });
this._private__sizeChanged = new Delegate();
this._private__widthCache = new TextWidthCache(5);
this._private__isSettingSize = false;
this._private__canvasSuggestedBitmapSizeChangedHandler = () => {
if (!this._private__isSettingSize) {
this._private__chart._internal_model()._internal_lightUpdate();
}
};
this._private__topCanvasSuggestedBitmapSizeChangedHandler = () => {
if (!this._private__isSettingSize) {
this._private__chart._internal_model()._internal_lightUpdate();
}
};
this._private__chart = chartWidget;
this._private__horzScaleBehavior = horzScaleBehavior;
this._private__options = chartWidget._internal_options().layout;
this._private__element = document.createElement("tr");
this._private__leftStubCell = document.createElement("td");
this._private__leftStubCell.style.padding = "0";
this._private__rightStubCell = document.createElement("td");
this._private__rightStubCell.style.padding = "0";
this._private__cell = document.createElement("td");
this._private__cell.style.height = "25px";
this._private__cell.style.padding = "0";
this._private__dv = document.createElement("div");
this._private__dv.style.width = "100%";
this._private__dv.style.height = "100%";
this._private__dv.style.position = "relative";
this._private__dv.style.overflow = "hidden";
this._private__cell.appendChild(this._private__dv);
this._private__canvasBinding = createBoundCanvas(this._private__dv, size({ width: 16, height: 16 }));
this._private__canvasBinding.subscribeSuggestedBitmapSizeChanged(this._private__canvasSuggestedBitmapSizeChangedHandler);
const canvas = this._private__canvasBinding.canvasElement;
canvas.style.position = "absolute";
canvas.style.zIndex = "1";
canvas.style.left = "0";
canvas.style.top = "0";
this._private__topCanvasBinding = createBoundCanvas(this._private__dv, size({ width: 16, height: 16 }));
this._private__topCanvasBinding.subscribeSuggestedBitmapSizeChanged(this._private__topCanvasSuggestedBitmapSizeChangedHandler);
const topCanvas = this._private__topCanvasBinding.canvasElement;
topCanvas.style.position = "absolute";
topCanvas.style.zIndex = "2";
topCanvas.style.left = "0";
topCanvas.style.top = "0";
this._private__element.appendChild(this._private__leftStubCell);
this._private__element.appendChild(this._private__cell);
this._private__element.appendChild(this._private__rightStubCell);
this._private__recreateStubs();
this._private__chart._internal_model()._internal_priceScalesOptionsChanged()._internal_subscribe(this._private__recreateStubs.bind(this), this);
this._private__mouseEventHandler = new MouseEventHandler(this._private__topCanvasBinding.canvasElement, this, {
_internal_treatVertTouchDragAsPageScroll: () => true,
_internal_treatHorzTouchDragAsPageScroll: () => !this._private__chart._internal_options().handleScroll.horzTouchDrag
});
}
_internal_destroy() {
this._private__mouseEventHandler._internal_destroy();
if (this._private__leftStub !== null) {
this._private__leftStub._internal_destroy();
}
if (this._private__rightStub !== null) {
this._private__rightStub._internal_destroy();
}
this._private__topCanvasBinding.unsubscribeSuggestedBitmapSizeChanged(this._private__topCanvasSuggestedBitmapSizeChangedHandler);
releaseCanvas(this._private__topCanvasBinding.canvasElement);
this._private__topCanvasBinding.dispose();
this._private__canvasBinding.unsubscribeSuggestedBitmapSizeChanged(this._private__canvasSuggestedBitmapSizeChangedHandler);
releaseCanvas(this._private__canvasBinding.canvasElement);
this._private__canvasBinding.dispose();
}
_internal_getElement() {
return this._private__element;
}
_internal_leftStub() {
return this._private__leftStub;
}
_internal_rightStub() {
return this._private__rightStub;
}
_internal_mouseDownEvent(event) {
if (this._private__mouseDown) {
return;
}
this._private__mouseDown = true;
const model = this._private__chart._internal_model();
if (model._internal_timeScale()._internal_isEmpty() || !this._private__chart._internal_options().handleScale.axisPressedMouseMove.time) {
return;
}
model._internal_startScaleTime(event.localX);
}
_internal_touchStartEvent(event) {
this._internal_mouseDownEvent(event);
}
_internal_mouseDownOutsideEvent() {
const model = this._private__chart._internal_model();
if (!model._internal_timeScale()._internal_isEmpty() && this._private__mouseDown) {
this._private__mouseDown = false;
if (this._private__chart._internal_options().handleScale.axisPressedMouseMove.time) {
model._internal_endScaleTime();
}
}
}
_internal_pressedMouseMoveEvent(event) {
const model = this._private__chart._internal_model();
if (model._internal_timeScale()._internal_isEmpty() || !this._private__chart._internal_options().handleScale.axisPressedMouseMove.time) {
return;
}
model._internal_scaleTimeTo(event.localX);
}
_internal_touchMoveEvent(event) {
this._internal_pressedMouseMoveEvent(event);
}
_internal_mouseUpEvent() {
this._private__mouseDown = false;
const model = this._private__chart._internal_model();
if (model._internal_timeScale()._internal_isEmpty() && !this._private__chart._internal_options().handleScale.axisPressedMouseMove.time) {
return;
}
model._internal_endScaleTime();
}
_internal_touchEndEvent() {
this._internal_mouseUpEvent();
}
_internal_mouseDoubleClickEvent() {
if (this._private__chart._internal_options().handleScale.axisDoubleClickReset.time) {
this._private__chart._internal_model()._internal_resetTimeScale();
}
}
_internal_doubleTapEvent() {
this._internal_mouseDoubleClickEvent();
}
_internal_mouseEnterEvent() {
if (this._private__chart._internal_model()._internal_options().handleScale.axisPressedMouseMove.time) {
this._private__setCursor(
1
/* CursorType.EwResize */
);
}
}
_internal_mouseLeaveEvent() {
this._private__setCursor(
0
/* CursorType.Default */
);
}
_internal_getSize() {
return this._private__size;
}
_internal_sizeChanged() {
return this._private__sizeChanged;
}
_internal_setSizes(timeAxisSize, leftStubWidth, rightStubWidth) {
if (!equalSizes(this._private__size, timeAxisSize)) {
this._private__size = timeAxisSize;
this._private__isSettingSize = true;
this._private__canvasBinding.resizeCanvasElement(timeAxisSize);
this._private__topCanvasBinding.resizeCanvasElement(timeAxisSize);
this._private__isSettingSize = false;
this._private__cell.style.width = `${timeAxisSize.width}px`;
this._private__cell.style.height = `${timeAxisSize.height}px`;
this._private__sizeChanged._internal_fire(timeAxisSize);
}
if (this._private__leftStub !== null) {
this._private__leftStub._internal_setSize(size({ width: leftStubWidth, height: timeAxisSize.height }));
}
if (this._private__rightStub !== null) {
this._private__rightStub._internal_setSize(size({ width: rightStubWidth, height: timeAxisSize.height }));
}
}
_internal_optimalHeight() {
const rendererOptions = this._private__getRendererOptions();
return Math.ceil(
// rendererOptions.offsetSize +
rendererOptions._internal_borderSize + rendererOptions._internal_tickLength + rendererOptions._internal_fontSize + rendererOptions._internal_paddingTop + rendererOptions._internal_paddingBottom + rendererOptions._internal_labelBottomOffset
);
}
_internal_update() {
this._private__chart._internal_model()._internal_timeScale()._internal_marks();
}
_internal_getBitmapSize() {
return this._private__canvasBinding.bitmapSize;
}
_internal_drawBitmap(ctx, x, y) {
const bitmapSize = this._internal_getBitmapSize();
if (bitmapSize.width > 0 && bitmapSize.height > 0) {
ctx.drawImage(this._private__canvasBinding.canvasElement, x, y);
}
}
_internal_paint(type) {
if (type === 0) {
return;
}
if (type !== 1) {
this._private__canvasBinding.applySuggestedBitmapSize();
const target = tryCreateCanvasRenderingTarget2D(this._private__canvasBinding);
if (target !== null) {
target.useBitmapCoordinateSpace((scope) => {
this._private__drawBackground(scope);
this._private__drawBorder(scope);
this._private__drawAdditionalSources(target, sourceBottomPaneViews);
});
this._private__drawTickMarks(target);
this._private__drawAdditionalSources(target, sourcePaneViews);
}
if (this._private__leftStub !== null) {
this._private__leftStub._internal_paint(type);
}
if (this._private__rightStub !== null) {
this._private__rightStub._internal_paint(type);
}
}
this._private__topCanvasBinding.applySuggestedBitmapSize();
const topTarget = tryCreateCanvasRenderingTarget2D(this._private__topCanvasBinding);
if (topTarget !== null) {
topTarget.useBitmapCoordinateSpace(({ context: ctx, bitmapSize }) => {
ctx.clearRect(0, 0, bitmapSize.width, bitmapSize.height);
});
this._private__drawLabels([...this._private__chart._internal_model()._internal_serieses(), this._private__chart._internal_model()._internal_crosshairSource()], topTarget);
this._private__drawAdditionalSources(topTarget, sourceTopPaneViews);
}
}
_private__drawAdditionalSources(target, axisViewsGetter) {
const sources = this._private__chart._internal_model()._internal_serieses();
for (const source of sources) {
drawSourcePaneViews(axisViewsGetter, (renderer) => drawBackground(renderer, target, false, void 0), source, void 0);
}
for (const source of sources) {
drawSourcePaneViews(axisViewsGetter, (renderer) => drawForeground(renderer, target, false, void 0), source, void 0);
}
}
_private__drawBackground({ context: ctx, bitmapSize }) {
clearRect(ctx, 0, 0, bitmapSize.width, bitmapSize.height, this._private__chart._internal_model()._internal_backgroundBottomColor());
}
_private__drawBorder({ context: ctx, bitmapSize, verticalPixelRatio }) {
if (this._private__chart._internal_options().timeScale.borderVisible) {
ctx.fillStyle = this._private__lineColor();
const borderSize = Math.max(1, Math.floor(this._private__getRendererOptions()._internal_borderSize * verticalPixelRatio));
ctx.fillRect(0, 0, bitmapSize.width, borderSize);
}
}
_private__drawTickMarks(target) {
const timeScale = this._private__chart._internal_model()._internal_timeScale();
const tickMarks = timeScale._internal_marks();
if (!tickMarks || tickMarks.length === 0) {
return;
}
const maxWeight = this._private__horzScaleBehavior.maxTickMarkWeight(tickMarks);
const rendererOptions = this._private__getRendererOptions();
const options = timeScale._internal_options();
if (options.borderVisible && options.ticksVisible) {
target.useBitmapCoordinateSpace(({ context: ctx, horizontalPixelRatio, verticalPixelRatio }) => {
ctx.strokeStyle = this._private__lineColor();
ctx.fillStyle = this._private__lineColor();
const tickWidth = Math.max(1, Math.floor(horizontalPixelRatio));
const tickOffset = Math.floor(horizontalPixelRatio * 0.5);
ctx.beginPath();
const tickLen = Math.round(rendererOptions._internal_tickLength * verticalPixelRatio);
for (let index = tickMarks.length; index--; ) {
const x = Math.round(tickMarks[index].coord * horizontalPixelRatio);
ctx.rect(x - tickOffset, 0, tickWidth, tickLen);
}
ctx.fill();
});
}
target.useMediaCoordinateSpace(({ context: ctx }) => {
const yText = rendererOptions._internal_borderSize + rendererOptions._internal_tickLength + rendererOptions._internal_paddingTop + rendererOptions._internal_fontSize / 2;
ctx.textAlign = "center";
ctx.textBaseline = "middle";
ctx.fillStyle = this._private__textColor();
ctx.font = this._private__baseFont();
for (const tickMark of tickMarks) {
if (tickMark.weight < maxWeight) {
const coordinate = tickMark.needAlignCoordinate ? this._private__alignTickMarkLabelCoordinate(ctx, tickMark.coord, tickMark.label) : tickMark.coord;
ctx.fillText(tickMark.label, coordinate, yText);
}
}
if (this._private__chart._internal_options().timeScale.allowBoldLabels) {
ctx.font = this._private__baseBoldFont();
}
for (const tickMark of tickMarks) {
if (tickMark.weight >= maxWeight) {
const coordinate = tickMark.needAlignCoordinate ? this._private__alignTickMarkLabelCoordinate(ctx, tickMark.coord, tickMark.label) : tickMark.coord;
ctx.fillText(tickMark.label, coordinate, yText);
}
}
});
}
_private__alignTickMarkLabelCoordinate(ctx, coordinate, labelText) {
const labelWidth = this._private__widthCache._internal_measureText(ctx, labelText);
const labelWidthHalf = labelWidth / 2;
const leftTextCoordinate = Math.floor(coordinate - labelWidthHalf) + 0.5;
if (leftTextCoordinate < 0) {
coordinate = coordinate + Math.abs(0 - leftTextCoordinate);
} else if (leftTextCoordinate + labelWidth > this._private__size.width) {
coordinate = coordinate - Math.abs(this._private__size.width - (leftTextCoordinate + labelWidth));
}
return coordinate;
}
_private__drawLabels(sources, target) {
const rendererOptions = this._private__getRendererOptions();
for (const source of sources) {
for (const view of source._internal_timeAxisViews()) {
view._internal_renderer()._internal_draw(target, rendererOptions);
}
}
}
_private__lineColor() {
return this._private__chart._internal_options().timeScale.borderColor;
}
_private__textColor() {
return this._private__options.textColor;
}
_private__fontSize() {
return this._private__options.fontSize;
}
_private__baseFont() {
return makeFont(this._private__fontSize(), this._private__options.fontFamily);
}
_private__baseBoldFont() {
return makeFont(this._private__fontSize(), this._private__options.fontFamily, "bold");
}
_private__getRendererOptions() {
if (this._private__rendererOptions === null) {
this._private__rendererOptions = {
_internal_borderSize: 1,
_internal_baselineOffset: NaN,
_internal_paddingTop: NaN,
_internal_paddingBottom: NaN,
_internal_paddingHorizontal: NaN,
_internal_tickLength: 5,
_internal_fontSize: NaN,
_internal_font: "",
_internal_widthCache: new TextWidthCache(),
_internal_labelBottomOffset: 0
};
}
const rendererOptions = this._private__rendererOptions;
const newFont = this._private__baseFont();
if (rendererOptions._internal_font !== newFont) {
const fontSize = this._private__fontSize();
rendererOptions._internal_fontSize = fontSize;
rendererOptions._internal_font = newFont;
rendererOptions._internal_paddingTop = 3 * fontSize / 12;
rendererOptions._internal_paddingBottom = 3 * fontSize / 12;
rendererOptions._internal_paddingHorizontal = 9 * fontSize / 12;
rendererOptions._internal_baselineOffset = 0;
rendererOptions._internal_labelBottomOffset = 4 * fontSize / 12;
rendererOptions._internal_widthCache._internal_reset();
}
return this._private__rendererOptions;
}
_private__setCursor(type) {
this._private__cell.style.cursor = type === 1 ? "ew-resize" : "default";
}
_private__recreateStubs() {
const model = this._private__chart._internal_model();
const options = model._internal_options();
if (!options.leftPriceScale.visible && this._private__leftStub !== null) {
this._private__leftStubCell.removeChild(this._private__leftStub._internal_getElement());
this._private__leftStub._internal_destroy();
this._private__leftStub = null;
}
if (!options.rightPriceScale.visible && this._private__rightStub !== null) {
this._private__rightStubCell.removeChild(this._private__rightStub._internal_getElement());
this._private__rightStub._internal_destroy();
this._private__rightStub = null;
}
const rendererOptionsProvider = this._private__chart._internal_model()._internal_rendererOptionsProvider();
const params = {
_internal_rendererOptionsProvider: rendererOptionsProvider
};
const borderVisibleGetter = () => {
return options.leftPriceScale.borderVisible && model._internal_timeScale()._internal_options().borderVisible;
};
const bottomColorGetter = () => model._internal_backgroundBottomColor();
if (options.leftPriceScale.visible && this._private__leftStub === null) {
this._private__leftStub = new PriceAxisStub("left", options, params, borderVisibleGetter, bottomColorGetter);
this._private__leftStubCell.appendChild(this._private__leftStub._internal_getElement());
}
if (options.rightPriceScale.visible && this._private__rightStub === null) {
this._private__rightStub = new PriceAxisStub("right", options, params, borderVisibleGetter, bottomColorGetter);
this._private__rightStubCell.appendChild(this._private__rightStub._internal_getElement());
}
}
};
var windowsChrome = isChromiumBased() && isWindows();
var ChartWidget = class {
constructor(container, options, horzScaleBehavior) {
this._private__paneWidgets = [];
this._private__drawRafId = 0;
this._private__height = 0;
this._private__width = 0;
this._private__leftPriceAxisWidth = 0;
this._private__rightPriceAxisWidth = 0;
this._private__invalidateMask = null;
this._private__drawPlanned = false;
this._private__clicked = new Delegate();
this._private__dblClicked = new Delegate();
this._private__crosshairMoved = new Delegate();
this._private__observer = null;
this._private__cursorStyleOverride = null;
this._private__container = container;
this._private__options = options;
this._private__horzScaleBehavior = horzScaleBehavior;
this._private__element = document.createElement("div");
this._private__element.classList.add("tv-lightweight-charts");
this._private__element.style.overflow = "hidden";
this._private__element.style.direction = "ltr";
this._private__element.style.width = "100%";
this._private__element.style.height = "100%";
disableSelection(this._private__element);
this._private__tableElement = document.createElement("table");
this._private__tableElement.setAttribute("cellspacing", "0");
this._private__element.appendChild(this._private__tableElement);
this._private__onWheelBound = this._private__onMousewheel.bind(this);
if (shouldSubscribeMouseWheel(this._private__options)) {
this._private__setMouseWheelEventListener(true);
}
this._private__model = new ChartModel(this._private__invalidateHandler.bind(this), this._private__options, horzScaleBehavior);
this._internal_model()._internal_crosshairMoved()._internal_subscribe(this._private__onPaneWidgetCrosshairMoved.bind(this), this);
this._private__timeAxisWidget = new TimeAxisWidget(this, this._private__horzScaleBehavior);
this._private__tableElement.appendChild(this._private__timeAxisWidget._internal_getElement());
const usedObserver = options.autoSize && this._private__installObserver();
let width = this._private__options.width;
let height = this._private__options.height;
if (usedObserver || width === 0 || height === 0) {
const containerRect = container.getBoundingClientRect();
width = width || containerRect.width;
height = height || containerRect.height;
}
this._internal_resize(width, height);
this._private__syncGuiWithModel();
container.appendChild(this._private__element);
this._private__updateTimeAxisVisibility();
this._private__model._internal_timeScale()._internal_optionsApplied()._internal_subscribe(this._private__model._internal_fullUpdate.bind(this._private__model), this);
this._private__model._internal_priceScalesOptionsChanged()._internal_subscribe(this._private__model._internal_fullUpdate.bind(this._private__model), this);
}
_internal_model() {
return this._private__model;
}
_internal_options() {
return this._private__options;
}
_internal_paneWidgets() {
return this._private__paneWidgets;
}
_internal_timeAxisWidget() {
return this._private__timeAxisWidget;
}
_internal_destroy() {
this._private__setMouseWheelEventListener(false);
if (this._private__drawRafId !== 0) {
window.cancelAnimationFrame(this._private__drawRafId);
}
this._private__model._internal_crosshairMoved()._internal_unsubscribeAll(this);
this._private__model._internal_timeScale()._internal_optionsApplied()._internal_unsubscribeAll(this);
this._private__model._internal_priceScalesOptionsChanged()._internal_unsubscribeAll(this);
this._private__model._internal_destroy();
for (const paneWidget of this._private__paneWidgets) {
this._private__tableElement.removeChild(paneWidget._internal_getElement());
paneWidget._internal_clicked()._internal_unsubscribeAll(this);
paneWidget._internal_dblClicked()._internal_unsubscribeAll(this);
paneWidget._internal_destroy();
}
this._private__paneWidgets = [];
ensureNotNull(this._private__timeAxisWidget)._internal_destroy();
if (this._private__element.parentElement !== null) {
this._private__element.parentElement.removeChild(this._private__element);
}
this._private__crosshairMoved._internal_destroy();
this._private__clicked._internal_destroy();
this._private__dblClicked._internal_destroy();
this._private__uninstallObserver();
}
_internal_resize(width, height, forceRepaint = false) {
if (this._private__height === height && this._private__width === width) {
return;
}
const sizeHint = suggestChartSize(size({ width, height }));
this._private__height = sizeHint.height;
this._private__width = sizeHint.width;
const heightStr = this._private__height + "px";
const widthStr = this._private__width + "px";
ensureNotNull(this._private__element).style.height = heightStr;
ensureNotNull(this._private__element).style.width = widthStr;
this._private__tableElement.style.height = heightStr;
this._private__tableElement.style.width = widthStr;
if (forceRepaint) {
this._private__drawImpl(InvalidateMask._internal_full(), performance.now());
} else {
this._private__model._internal_fullUpdate();
}
}
_internal_paint(invalidateMask) {
if (invalidateMask === void 0) {
invalidateMask = InvalidateMask._internal_full();
}
for (let i = 0; i < this._private__paneWidgets.length; i++) {
this._private__paneWidgets[i]._internal_paint(invalidateMask._internal_invalidateForPane(i)._internal_level);
}
if (this._private__options.timeScale.visible) {
this._private__timeAxisWidget._internal_paint(invalidateMask._internal_fullInvalidation());
}
}
_internal_applyOptions(options) {
const currentlyHasMouseWheelListener = shouldSubscribeMouseWheel(this._private__options);
this._private__model._internal_applyOptions(options);
const shouldHaveMouseWheelListener = shouldSubscribeMouseWheel(this._private__options);
if (shouldHaveMouseWheelListener !== currentlyHasMouseWheelListener) {
this._private__setMouseWheelEventListener(shouldHaveMouseWheelListener);
}
this._private__updateTimeAxisVisibility();
this._private__applyAutoSizeOptions(options);
}
_internal_clicked() {
return this._private__clicked;
}
_internal_dblClicked() {
return this._private__dblClicked;
}
_internal_crosshairMoved() {
return this._private__crosshairMoved;
}
_internal_takeScreenshot() {
if (this._private__invalidateMask !== null) {
this._private__drawImpl(this._private__invalidateMask, performance.now());
this._private__invalidateMask = null;
}
const screeshotBitmapSize = this._private__traverseLayout(null);
const screenshotCanvas = document.createElement("canvas");
screenshotCanvas.width = screeshotBitmapSize.width;
screenshotCanvas.height = screeshotBitmapSize.height;
const ctx = ensureNotNull(screenshotCanvas.getContext("2d"));
this._private__traverseLayout(ctx);
return screenshotCanvas;
}
_internal_getPriceAxisWidth(position) {
if (position === "left" && !this._private__isLeftAxisVisible()) {
return 0;
}
if (position === "right" && !this._private__isRightAxisVisible()) {
return 0;
}
if (this._private__paneWidgets.length === 0) {
return 0;
}
const priceAxisWidget = position === "left" ? this._private__paneWidgets[0]._internal_leftPriceAxisWidget() : this._private__paneWidgets[0]._internal_rightPriceAxisWidget();
return ensureNotNull(priceAxisWidget)._internal_getWidth();
}
_internal_autoSizeActive() {
return this._private__options.autoSize && this._private__observer !== null;
}
_internal_element() {
return this._private__element;
}
_internal_setCursorStyle(style) {
this._private__cursorStyleOverride = style;
if (this._private__cursorStyleOverride) {
this._internal_element().style.setProperty("cursor", style);
} else {
this._internal_element().style.removeProperty("cursor");
}
}
_internal_getCursorOverrideStyle() {
return this._private__cursorStyleOverride;
}
_internal_paneSize() {
return ensureDefined(this._private__paneWidgets[0])._internal_getSize();
}
// eslint-disable-next-line complexity
_private__applyAutoSizeOptions(options) {
if (options.autoSize === void 0 && this._private__observer && (options.width !== void 0 || options.height !== void 0)) {
warn(`You should turn autoSize off explicitly before specifying sizes; try adding options.autoSize: false to new options`);
return;
}
if (options.autoSize && !this._private__observer) {
this._private__installObserver();
}
if (options.autoSize === false && this._private__observer !== null) {
this._private__uninstallObserver();
}
if (!options.autoSize && (options.width !== void 0 || options.height !== void 0)) {
this._internal_resize(options.width || this._private__width, options.height || this._private__height);
}
}
/**
* Traverses the widget's layout (pane and axis child widgets),
* draws the screenshot (if rendering context is passed) and returns the screenshot bitmap size
*
* @param ctx - if passed, used to draw the screenshot of widget
* @returns screenshot bitmap size
*/
_private__traverseLayout(ctx) {
let totalWidth = 0;
let totalHeight = 0;
const firstPane = this._private__paneWidgets[0];
const drawPriceAxises = (position, targetX) => {
let targetY = 0;
for (let paneIndex = 0; paneIndex < this._private__paneWidgets.length; paneIndex++) {
const paneWidget = this._private__paneWidgets[paneIndex];
const priceAxisWidget = ensureNotNull(position === "left" ? paneWidget._internal_leftPriceAxisWidget() : paneWidget._internal_rightPriceAxisWidget());
const bitmapSize = priceAxisWidget._internal_getBitmapSize();
if (ctx !== null) {
priceAxisWidget._internal_drawBitmap(ctx, targetX, targetY);
}
targetY += bitmapSize.height;
}
};
if (this._private__isLeftAxisVisible()) {
drawPriceAxises("left", 0);
const leftAxisBitmapWidth = ensureNotNull(firstPane._internal_leftPriceAxisWidget())._internal_getBitmapSize().width;
totalWidth += leftAxisBitmapWidth;
}
for (let paneIndex = 0; paneIndex < this._private__paneWidgets.length; paneIndex++) {
const paneWidget = this._private__paneWidgets[paneIndex];
const bitmapSize = paneWidget._internal_getBitmapSize();
if (ctx !== null) {
paneWidget._internal_drawBitmap(ctx, totalWidth, totalHeight);
}
totalHeight += bitmapSize.height;
}
const firstPaneBitmapWidth = firstPane._internal_getBitmapSize().width;
totalWidth += firstPaneBitmapWidth;
if (this._private__isRightAxisVisible()) {
drawPriceAxises("right", totalWidth);
const rightAxisBitmapWidth = ensureNotNull(firstPane._internal_rightPriceAxisWidget())._internal_getBitmapSize().width;
totalWidth += rightAxisBitmapWidth;
}
const drawStub = (position, targetX, targetY) => {
const stub = ensureNotNull(position === "left" ? this._private__timeAxisWidget._internal_leftStub() : this._private__timeAxisWidget._internal_rightStub());
stub._internal_drawBitmap(ensureNotNull(ctx), targetX, targetY);
};
if (this._private__options.timeScale.visible) {
const timeAxisBitmapSize = this._private__timeAxisWidget._internal_getBitmapSize();
if (ctx !== null) {
let targetX = 0;
if (this._private__isLeftAxisVisible()) {
drawStub("left", targetX, totalHeight);
targetX = ensureNotNull(firstPane._internal_leftPriceAxisWidget())._internal_getBitmapSize().width;
}
this._private__timeAxisWidget._internal_drawBitmap(ctx, targetX, totalHeight);
targetX += timeAxisBitmapSize.width;
if (this._private__isRightAxisVisible()) {
drawStub("right", targetX, totalHeight);
}
}
totalHeight += timeAxisBitmapSize.height;
}
return size({
width: totalWidth,
height: totalHeight
});
}
// eslint-disable-next-line complexity
_private__adjustSizeImpl() {
let totalStretch = 0;
let leftPriceAxisWidth = 0;
let rightPriceAxisWidth = 0;
for (const paneWidget of this._private__paneWidgets) {
if (this._private__isLeftAxisVisible()) {
leftPriceAxisWidth = Math.max(leftPriceAxisWidth, ensureNotNull(paneWidget._internal_leftPriceAxisWidget())._internal_optimalWidth(), this._private__options.leftPriceScale.minimumWidth);
}
if (this._private__isRightAxisVisible()) {
rightPriceAxisWidth = Math.max(rightPriceAxisWidth, ensureNotNull(paneWidget._internal_rightPriceAxisWidget())._internal_optimalWidth(), this._private__options.rightPriceScale.minimumWidth);
}
totalStretch += paneWidget._internal_stretchFactor();
}
leftPriceAxisWidth = suggestPriceScaleWidth(leftPriceAxisWidth);
rightPriceAxisWidth = suggestPriceScaleWidth(rightPriceAxisWidth);
const width = this._private__width;
const height = this._private__height;
const paneWidth = Math.max(width - leftPriceAxisWidth - rightPriceAxisWidth, 0);
const separatorsHeight = 0;
const timeAxisVisible = this._private__options.timeScale.visible;
let timeAxisHeight = timeAxisVisible ? Math.max(this._private__timeAxisWidget._internal_optimalHeight(), this._private__options.timeScale.minimumHeight) : 0;
timeAxisHeight = suggestTimeScaleHeight(timeAxisHeight);
const otherWidgetHeight = separatorsHeight + timeAxisHeight;
const totalPaneHeight = height < otherWidgetHeight ? 0 : height - otherWidgetHeight;
const stretchPixels = totalPaneHeight / totalStretch;
let accumulatedHeight = 0;
for (let paneIndex = 0; paneIndex < this._private__paneWidgets.length; ++paneIndex) {
const paneWidget = this._private__paneWidgets[paneIndex];
paneWidget._internal_setState(this._private__model._internal_panes()[paneIndex]);
let paneHeight = 0;
let calculatePaneHeight = 0;
if (paneIndex === this._private__paneWidgets.length - 1) {
calculatePaneHeight = totalPaneHeight - accumulatedHeight;
} else {
calculatePaneHeight = Math.round(paneWidget._internal_stretchFactor() * stretchPixels);
}
paneHeight = Math.max(calculatePaneHeight, 2);
accumulatedHeight += paneHeight;
paneWidget._internal_setSize(size({ width: paneWidth, height: paneHeight }));
if (this._private__isLeftAxisVisible()) {
paneWidget._internal_setPriceAxisSize(leftPriceAxisWidth, "left");
}
if (this._private__isRightAxisVisible()) {
paneWidget._internal_setPriceAxisSize(rightPriceAxisWidth, "right");
}
if (paneWidget._internal_state()) {
this._private__model._internal_setPaneHeight(paneWidget._internal_state(), paneHeight);
}
}
this._private__timeAxisWidget._internal_setSizes(size({ width: timeAxisVisible ? paneWidth : 0, height: timeAxisHeight }), timeAxisVisible ? leftPriceAxisWidth : 0, timeAxisVisible ? rightPriceAxisWidth : 0);
this._private__model._internal_setWidth(paneWidth);
if (this._private__leftPriceAxisWidth !== leftPriceAxisWidth) {
this._private__leftPriceAxisWidth = leftPriceAxisWidth;
}
if (this._private__rightPriceAxisWidth !== rightPriceAxisWidth) {
this._private__rightPriceAxisWidth = rightPriceAxisWidth;
}
}
_private__setMouseWheelEventListener(add2) {
if (add2) {
this._private__element.addEventListener("wheel", this._private__onWheelBound, { passive: false });
return;
}
this._private__element.removeEventListener("wheel", this._private__onWheelBound);
}
_private__determineWheelSpeedAdjustment(event) {
switch (event.deltaMode) {
case event.DOM_DELTA_PAGE:
return 120;
case event.DOM_DELTA_LINE:
return 32;
}
if (!windowsChrome) {
return 1;
}
return 1 / window.devicePixelRatio;
}
_private__onMousewheel(event) {
if ((event.deltaX === 0 || !this._private__options.handleScroll.mouseWheel) && (event.deltaY === 0 || !this._private__options.handleScale.mouseWheel)) {
return;
}
const scrollSpeedAdjustment = this._private__determineWheelSpeedAdjustment(event);
const deltaX = scrollSpeedAdjustment * event.deltaX / 100;
const deltaY = -(scrollSpeedAdjustment * event.deltaY / 100);
if (event.cancelable) {
event.preventDefault();
}
if (deltaY !== 0 && this._private__options.handleScale.mouseWheel) {
const zoomScale = Math.sign(deltaY) * Math.min(1, Math.abs(deltaY));
const scrollPosition = event.clientX - this._private__element.getBoundingClientRect().left;
this._internal_model()._internal_zoomTime(scrollPosition, zoomScale);
}
if (deltaX !== 0 && this._private__options.handleScroll.mouseWheel) {
this._internal_model()._internal_scrollChart(deltaX * -80);
}
}
_private__drawImpl(invalidateMask, time) {
var _a;
const invalidationType = invalidateMask._internal_fullInvalidation();
if (invalidationType === 3) {
this._private__updateGui();
}
if (invalidationType === 3 || invalidationType === 2) {
this._private__applyMomentaryAutoScale(invalidateMask);
this._private__applyTimeScaleInvalidations(invalidateMask, time);
this._private__timeAxisWidget._internal_update();
this._private__paneWidgets.forEach((pane) => {
pane._internal_updatePriceAxisWidgets();
});
if (((_a = this._private__invalidateMask) === null || _a === void 0 ? void 0 : _a._internal_fullInvalidation()) === 3) {
this._private__invalidateMask._internal_merge(invalidateMask);
this._private__updateGui();
this._private__applyMomentaryAutoScale(this._private__invalidateMask);
this._private__applyTimeScaleInvalidations(this._private__invalidateMask, time);
invalidateMask = this._private__invalidateMask;
this._private__invalidateMask = null;
}
}
this._internal_paint(invalidateMask);
}
_private__applyTimeScaleInvalidations(invalidateMask, time) {
for (const tsInvalidation of invalidateMask._internal_timeScaleInvalidations()) {
this._private__applyTimeScaleInvalidation(tsInvalidation, time);
}
}
_private__applyMomentaryAutoScale(invalidateMask) {
const panes = this._private__model._internal_panes();
for (let i = 0; i < panes.length; i++) {
if (invalidateMask._internal_invalidateForPane(i)._internal_autoScale) {
panes[i]._internal_momentaryAutoScale();
}
}
}
_private__applyTimeScaleInvalidation(invalidation, time) {
const timeScale = this._private__model._internal_timeScale();
switch (invalidation._internal_type) {
case 0:
timeScale._internal_fitContent();
break;
case 1:
timeScale._internal_setLogicalRange(invalidation._internal_value);
break;
case 2:
timeScale._internal_setBarSpacing(invalidation._internal_value);
break;
case 3:
timeScale._internal_setRightOffset(invalidation._internal_value);
break;
case 4:
timeScale._internal_restoreDefault();
break;
case 5:
if (!invalidation._internal_value._internal_finished(time)) {
timeScale._internal_setRightOffset(invalidation._internal_value._internal_getPosition(time));
}
break;
}
}
_private__invalidateHandler(invalidateMask) {
if (this._private__invalidateMask !== null) {
this._private__invalidateMask._internal_merge(invalidateMask);
} else {
this._private__invalidateMask = invalidateMask;
}
if (!this._private__drawPlanned) {
this._private__drawPlanned = true;
this._private__drawRafId = window.requestAnimationFrame((time) => {
this._private__drawPlanned = false;
this._private__drawRafId = 0;
if (this._private__invalidateMask !== null) {
const mask = this._private__invalidateMask;
this._private__invalidateMask = null;
this._private__drawImpl(mask, time);
for (const tsInvalidation of mask._internal_timeScaleInvalidations()) {
if (tsInvalidation._internal_type === 5 && !tsInvalidation._internal_value._internal_finished(time)) {
this._internal_model()._internal_setTimeScaleAnimation(tsInvalidation._internal_value);
break;
}
}
}
});
}
}
_private__updateGui() {
this._private__syncGuiWithModel();
}
// private _destroySeparator(separator: PaneSeparator): void {
// this._tableElement.removeChild(separator.getElement());
// separator.destroy();
// }
_private__syncGuiWithModel() {
const panes = this._private__model._internal_panes();
const targetPaneWidgetsCount = panes.length;
const actualPaneWidgetsCount = this._private__paneWidgets.length;
for (let i = targetPaneWidgetsCount; i < actualPaneWidgetsCount; i++) {
const paneWidget = ensureDefined(this._private__paneWidgets.pop());
this._private__tableElement.removeChild(paneWidget._internal_getElement());
paneWidget._internal_clicked()._internal_unsubscribeAll(this);
paneWidget._internal_dblClicked()._internal_unsubscribeAll(this);
paneWidget._internal_destroy();
}
for (let i = actualPaneWidgetsCount; i < targetPaneWidgetsCount; i++) {
const paneWidget = new PaneWidget(this, panes[i]);
paneWidget._internal_clicked()._internal_subscribe(this._private__onPaneWidgetClicked.bind(this), this);
paneWidget._internal_dblClicked()._internal_subscribe(this._private__onPaneWidgetDblClicked.bind(this), this);
this._private__paneWidgets.push(paneWidget);
this._private__tableElement.insertBefore(paneWidget._internal_getElement(), this._private__timeAxisWidget._internal_getElement());
}
for (let i = 0; i < targetPaneWidgetsCount; i++) {
const state = panes[i];
const paneWidget = this._private__paneWidgets[i];
if (paneWidget._internal_state() !== state) {
paneWidget._internal_setState(state);
} else {
paneWidget._internal_updatePriceAxisWidgetsStates();
}
}
this._private__updateTimeAxisVisibility();
this._private__adjustSizeImpl();
}
_private__getMouseEventParamsImpl(index, point, event) {
var _a;
const seriesData = /* @__PURE__ */ new Map();
if (index !== null) {
const serieses = this._private__model._internal_serieses();
serieses.forEach((s) => {
const data = s._internal_bars()._internal_search(index);
if (data !== null) {
seriesData.set(s, data);
}
});
}
let clientTime;
if (index !== null) {
const timePoint = (_a = this._private__model._internal_timeScale()._internal_indexToTimeScalePoint(index)) === null || _a === void 0 ? void 0 : _a.originalTime;
if (timePoint !== void 0) {
clientTime = timePoint;
}
}
const hoveredSource = this._internal_model()._internal_hoveredSource();
const hoveredSeries = hoveredSource !== null && hoveredSource._internal_source instanceof Series ? hoveredSource._internal_source : void 0;
const hoveredObject = hoveredSource !== null && hoveredSource._internal_object !== void 0 ? hoveredSource._internal_object._internal_externalId : void 0;
return {
_internal_originalTime: clientTime,
_internal_index: index !== null && index !== void 0 ? index : void 0,
_internal_point: point !== null && point !== void 0 ? point : void 0,
_internal_hoveredSeries: hoveredSeries,
_internal_seriesData: seriesData,
_internal_hoveredObject: hoveredObject,
_internal_touchMouseEventData: event !== null && event !== void 0 ? event : void 0
};
}
_private__onPaneWidgetClicked(time, point, event) {
this._private__clicked._internal_fire(() => this._private__getMouseEventParamsImpl(time, point, event));
}
_private__onPaneWidgetDblClicked(time, point, event) {
this._private__dblClicked._internal_fire(() => this._private__getMouseEventParamsImpl(time, point, event));
}
_private__onPaneWidgetCrosshairMoved(time, point, event) {
this._private__crosshairMoved._internal_fire(() => this._private__getMouseEventParamsImpl(time, point, event));
}
_private__updateTimeAxisVisibility() {
const display = this._private__options.timeScale.visible ? "" : "none";
this._private__timeAxisWidget._internal_getElement().style.display = display;
}
_private__isLeftAxisVisible() {
return this._private__paneWidgets[0]._internal_state()._internal_leftPriceScale()._internal_options().visible;
}
_private__isRightAxisVisible() {
return this._private__paneWidgets[0]._internal_state()._internal_rightPriceScale()._internal_options().visible;
}
_private__installObserver() {
if (!("ResizeObserver" in window)) {
warn('Options contains "autoSize" flag, but the browser does not support ResizeObserver feature. Please provide polyfill.');
return false;
} else {
this._private__observer = new ResizeObserver((entries) => {
const containerEntry = entries.find((entry) => entry.target === this._private__container);
if (!containerEntry) {
return;
}
this._internal_resize(containerEntry.contentRect.width, containerEntry.contentRect.height);
});
this._private__observer.observe(this._private__container, { box: "border-box" });
return true;
}
}
_private__uninstallObserver() {
if (this._private__observer !== null) {
this._private__observer.disconnect();
}
this._private__observer = null;
}
};
function disableSelection(element) {
element.style.userSelect = "none";
element.style.webkitUserSelect = "none";
element.style.msUserSelect = "none";
element.style.MozUserSelect = "none";
element.style.webkitTapHighlightColor = "transparent";
}
function shouldSubscribeMouseWheel(options) {
return Boolean(options.handleScroll.mouseWheel || options.handleScale.mouseWheel);
}
function isWhitespaceData(data) {
return data.open === void 0 && data.value === void 0;
}
function isFulfilledData(data) {
return isFulfilledBarData(data) || isFulfilledLineData(data);
}
function isFulfilledBarData(data) {
return data.open !== void 0;
}
function isFulfilledLineData(data) {
return data.value !== void 0;
}
function __rest(s, e) {
var t = {};
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
t[p] = s[p];
if (s != null && typeof Object.getOwnPropertySymbols === "function")
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
t[p[i]] = s[p[i]];
}
return t;
}
function getColoredLineBasedSeriesPlotRow(time, index, item, originalTime) {
const val = item.value;
const res = { _internal_index: index, _internal_time: time, _internal_value: [val, val, val, val], _internal_originalTime: originalTime };
if (item.color !== void 0) {
res._internal_color = item.color;
}
return res;
}
function getAreaSeriesPlotRow(time, index, item, originalTime) {
const val = item.value;
const res = { _internal_index: index, _internal_time: time, _internal_value: [val, val, val, val], _internal_originalTime: originalTime };
if (item.lineColor !== void 0) {
res._internal_lineColor = item.lineColor;
}
if (item.topColor !== void 0) {
res._internal_topColor = item.topColor;
}
if (item.bottomColor !== void 0) {
res._internal_bottomColor = item.bottomColor;
}
return res;
}
function getBaselineSeriesPlotRow(time, index, item, originalTime) {
const val = item.value;
const res = { _internal_index: index, _internal_time: time, _internal_value: [val, val, val, val], _internal_originalTime: originalTime };
if (item.topLineColor !== void 0) {
res._internal_topLineColor = item.topLineColor;
}
if (item.bottomLineColor !== void 0) {
res._internal_bottomLineColor = item.bottomLineColor;
}
if (item.topFillColor1 !== void 0) {
res._internal_topFillColor1 = item.topFillColor1;
}
if (item.topFillColor2 !== void 0) {
res._internal_topFillColor2 = item.topFillColor2;
}
if (item.bottomFillColor1 !== void 0) {
res._internal_bottomFillColor1 = item.bottomFillColor1;
}
if (item.bottomFillColor2 !== void 0) {
res._internal_bottomFillColor2 = item.bottomFillColor2;
}
return res;
}
function getBarSeriesPlotRow(time, index, item, originalTime) {
const res = { _internal_index: index, _internal_time: time, _internal_value: [item.open, item.high, item.low, item.close], _internal_originalTime: originalTime };
if (item.color !== void 0) {
res._internal_color = item.color;
}
return res;
}
function getCandlestickSeriesPlotRow(time, index, item, originalTime) {
const res = { _internal_index: index, _internal_time: time, _internal_value: [item.open, item.high, item.low, item.close], _internal_originalTime: originalTime };
if (item.color !== void 0) {
res._internal_color = item.color;
}
if (item.borderColor !== void 0) {
res._internal_borderColor = item.borderColor;
}
if (item.wickColor !== void 0) {
res._internal_wickColor = item.wickColor;
}
return res;
}
function getCustomSeriesPlotRow(time, index, item, originalTime, dataToPlotRow) {
const values = ensureDefined(dataToPlotRow)(item);
const max = Math.max(...values);
const min2 = Math.min(...values);
const last = values[values.length - 1];
const value = [last, max, min2, last];
const _a = item, { time: excludedTime, color: color2 } = _a, data = __rest(_a, ["time", "color"]);
return { _internal_index: index, _internal_time: time, _internal_value: value, _internal_originalTime: originalTime, _internal_data: data, _internal_color: color2 };
}
function isSeriesPlotRow(row) {
return row._internal_value !== void 0;
}
function wrapCustomValues(plotRow, bar) {
if (bar.customValues !== void 0) {
plotRow._internal_customValues = bar.customValues;
}
return plotRow;
}
function isWhitespaceDataWithCustomCheck(bar, customIsWhitespace) {
if (customIsWhitespace) {
return customIsWhitespace(bar);
}
return isWhitespaceData(bar);
}
function wrapWhitespaceData(createPlotRowFn) {
return (time, index, bar, originalTime, dataToPlotRow, customIsWhitespace) => {
if (isWhitespaceDataWithCustomCheck(bar, customIsWhitespace)) {
return wrapCustomValues({ _internal_time: time, _internal_index: index, _internal_originalTime: originalTime }, bar);
}
return wrapCustomValues(createPlotRowFn(time, index, bar, originalTime, dataToPlotRow), bar);
};
}
function getSeriesPlotRowCreator(seriesType) {
const seriesPlotRowFnMap = {
Candlestick: wrapWhitespaceData(getCandlestickSeriesPlotRow),
Bar: wrapWhitespaceData(getBarSeriesPlotRow),
Area: wrapWhitespaceData(getAreaSeriesPlotRow),
Baseline: wrapWhitespaceData(getBaselineSeriesPlotRow),
Histogram: wrapWhitespaceData(getColoredLineBasedSeriesPlotRow),
Line: wrapWhitespaceData(getColoredLineBasedSeriesPlotRow),
Custom: wrapWhitespaceData(getCustomSeriesPlotRow)
};
return seriesPlotRowFnMap[seriesType];
}
function createEmptyTimePointData(timePoint) {
return { _internal_index: 0, _internal_mapping: /* @__PURE__ */ new Map(), _internal_timePoint: timePoint };
}
function seriesRowsFirstAndLastTime(seriesRows, bh) {
if (seriesRows === void 0 || seriesRows.length === 0) {
return void 0;
}
return {
_internal_firstTime: bh.key(seriesRows[0]._internal_time),
_internal_lastTime: bh.key(seriesRows[seriesRows.length - 1]._internal_time)
};
}
function seriesUpdateInfo(seriesRows, prevSeriesRows, bh) {
const firstAndLastTime = seriesRowsFirstAndLastTime(seriesRows, bh);
const prevFirstAndLastTime = seriesRowsFirstAndLastTime(prevSeriesRows, bh);
if (firstAndLastTime !== void 0 && prevFirstAndLastTime !== void 0) {
return {
_internal_lastBarUpdatedOrNewBarsAddedToTheRight: firstAndLastTime._internal_lastTime >= prevFirstAndLastTime._internal_lastTime && firstAndLastTime._internal_firstTime >= prevFirstAndLastTime._internal_firstTime
};
}
return void 0;
}
function timeScalePointTime(mergedPointData) {
let result;
mergedPointData.forEach((v) => {
if (result === void 0) {
result = v._internal_originalTime;
}
});
return ensureDefined(result);
}
function saveOriginalTime(data) {
if (data._internal_originalTime === void 0) {
data._internal_originalTime = data.time;
}
}
var DataLayer = class {
constructor(horzScaleBehavior) {
this._private__pointDataByTimePoint = /* @__PURE__ */ new Map();
this._private__seriesRowsBySeries = /* @__PURE__ */ new Map();
this._private__seriesLastTimePoint = /* @__PURE__ */ new Map();
this._private__sortedTimePoints = [];
this._private__horzScaleBehavior = horzScaleBehavior;
}
_internal_destroy() {
this._private__pointDataByTimePoint.clear();
this._private__seriesRowsBySeries.clear();
this._private__seriesLastTimePoint.clear();
this._private__sortedTimePoints = [];
}
_internal_setSeriesData(series, data) {
let needCleanupPoints = this._private__pointDataByTimePoint.size !== 0;
let isTimeScaleAffected = false;
const prevSeriesRows = this._private__seriesRowsBySeries.get(series);
if (prevSeriesRows !== void 0) {
if (this._private__seriesRowsBySeries.size === 1) {
needCleanupPoints = false;
isTimeScaleAffected = true;
this._private__pointDataByTimePoint.clear();
} else {
for (const point of this._private__sortedTimePoints) {
if (point.pointData._internal_mapping.delete(series)) {
isTimeScaleAffected = true;
}
}
}
}
let seriesRows = [];
if (data.length !== 0) {
const originalTimes = data.map((d) => d.time);
const timeConverter = this._private__horzScaleBehavior.createConverterToInternalObj(data);
const createPlotRow = getSeriesPlotRowCreator(series._internal_seriesType());
const dataToPlotRow = series._internal_customSeriesPlotValuesBuilder();
const customWhitespaceChecker = series._internal_customSeriesWhitespaceCheck();
seriesRows = data.map((item, index) => {
const time = timeConverter(item.time);
const horzItemKey = this._private__horzScaleBehavior.key(time);
let timePointData = this._private__pointDataByTimePoint.get(horzItemKey);
if (timePointData === void 0) {
timePointData = createEmptyTimePointData(time);
this._private__pointDataByTimePoint.set(horzItemKey, timePointData);
isTimeScaleAffected = true;
}
const row = createPlotRow(time, timePointData._internal_index, item, originalTimes[index], dataToPlotRow, customWhitespaceChecker);
timePointData._internal_mapping.set(series, row);
return row;
});
}
if (needCleanupPoints) {
this._private__cleanupPointsData();
}
this._private__setRowsToSeries(series, seriesRows);
let firstChangedPointIndex = -1;
if (isTimeScaleAffected) {
const newTimeScalePoints = [];
this._private__pointDataByTimePoint.forEach((pointData) => {
newTimeScalePoints.push({
timeWeight: 0,
time: pointData._internal_timePoint,
pointData,
originalTime: timeScalePointTime(pointData._internal_mapping)
});
});
newTimeScalePoints.sort((t1, t2) => this._private__horzScaleBehavior.key(t1.time) - this._private__horzScaleBehavior.key(t2.time));
firstChangedPointIndex = this._private__replaceTimeScalePoints(newTimeScalePoints);
}
return this._private__getUpdateResponse(series, firstChangedPointIndex, seriesUpdateInfo(this._private__seriesRowsBySeries.get(series), prevSeriesRows, this._private__horzScaleBehavior));
}
_internal_removeSeries(series) {
return this._internal_setSeriesData(series, []);
}
_internal_updateSeriesData(series, data) {
const extendedData = data;
saveOriginalTime(extendedData);
this._private__horzScaleBehavior.preprocessData(data);
const timeConverter = this._private__horzScaleBehavior.createConverterToInternalObj([data]);
const time = timeConverter(data.time);
const lastSeriesTime = this._private__seriesLastTimePoint.get(series);
if (lastSeriesTime !== void 0 && this._private__horzScaleBehavior.key(time) < this._private__horzScaleBehavior.key(lastSeriesTime)) {
throw new Error(`Cannot update oldest data, last time=${lastSeriesTime}, new time=${time}`);
}
let pointDataAtTime = this._private__pointDataByTimePoint.get(this._private__horzScaleBehavior.key(time));
const affectsTimeScale = pointDataAtTime === void 0;
if (pointDataAtTime === void 0) {
pointDataAtTime = createEmptyTimePointData(time);
this._private__pointDataByTimePoint.set(this._private__horzScaleBehavior.key(time), pointDataAtTime);
}
const createPlotRow = getSeriesPlotRowCreator(series._internal_seriesType());
const dataToPlotRow = series._internal_customSeriesPlotValuesBuilder();
const customWhitespaceChecker = series._internal_customSeriesWhitespaceCheck();
const plotRow = createPlotRow(time, pointDataAtTime._internal_index, data, extendedData._internal_originalTime, dataToPlotRow, customWhitespaceChecker);
pointDataAtTime._internal_mapping.set(series, plotRow);
this._private__updateLastSeriesRow(series, plotRow);
const info = { _internal_lastBarUpdatedOrNewBarsAddedToTheRight: isSeriesPlotRow(plotRow) };
if (!affectsTimeScale) {
return this._private__getUpdateResponse(series, -1, info);
}
const newPoint = {
timeWeight: 0,
time: pointDataAtTime._internal_timePoint,
pointData: pointDataAtTime,
originalTime: timeScalePointTime(pointDataAtTime._internal_mapping)
};
const insertIndex = lowerBound(this._private__sortedTimePoints, this._private__horzScaleBehavior.key(newPoint.time), (a, b) => this._private__horzScaleBehavior.key(a.time) < b);
this._private__sortedTimePoints.splice(insertIndex, 0, newPoint);
for (let index = insertIndex; index < this._private__sortedTimePoints.length; ++index) {
assignIndexToPointData(this._private__sortedTimePoints[index].pointData, index);
}
this._private__horzScaleBehavior.fillWeightsForPoints(this._private__sortedTimePoints, insertIndex);
return this._private__getUpdateResponse(series, insertIndex, info);
}
_private__updateLastSeriesRow(series, plotRow) {
let seriesData = this._private__seriesRowsBySeries.get(series);
if (seriesData === void 0) {
seriesData = [];
this._private__seriesRowsBySeries.set(series, seriesData);
}
const lastSeriesRow = seriesData.length !== 0 ? seriesData[seriesData.length - 1] : null;
if (lastSeriesRow === null || this._private__horzScaleBehavior.key(plotRow._internal_time) > this._private__horzScaleBehavior.key(lastSeriesRow._internal_time)) {
if (isSeriesPlotRow(plotRow)) {
seriesData.push(plotRow);
}
} else {
if (isSeriesPlotRow(plotRow)) {
seriesData[seriesData.length - 1] = plotRow;
} else {
seriesData.splice(-1, 1);
}
}
this._private__seriesLastTimePoint.set(series, plotRow._internal_time);
}
_private__setRowsToSeries(series, seriesRows) {
if (seriesRows.length !== 0) {
this._private__seriesRowsBySeries.set(series, seriesRows.filter(isSeriesPlotRow));
this._private__seriesLastTimePoint.set(series, seriesRows[seriesRows.length - 1]._internal_time);
} else {
this._private__seriesRowsBySeries.delete(series);
this._private__seriesLastTimePoint.delete(series);
}
}
_private__cleanupPointsData() {
for (const point of this._private__sortedTimePoints) {
if (point.pointData._internal_mapping.size === 0) {
this._private__pointDataByTimePoint.delete(this._private__horzScaleBehavior.key(point.time));
}
}
}
/**
* Sets new time scale and make indexes valid for all series
*
* @returns The index of the first changed point or `-1` if there is no change.
*/
_private__replaceTimeScalePoints(newTimePoints) {
let firstChangedPointIndex = -1;
for (let index = 0; index < this._private__sortedTimePoints.length && index < newTimePoints.length; ++index) {
const oldPoint = this._private__sortedTimePoints[index];
const newPoint = newTimePoints[index];
if (this._private__horzScaleBehavior.key(oldPoint.time) !== this._private__horzScaleBehavior.key(newPoint.time)) {
firstChangedPointIndex = index;
break;
}
newPoint.timeWeight = oldPoint.timeWeight;
assignIndexToPointData(newPoint.pointData, index);
}
if (firstChangedPointIndex === -1 && this._private__sortedTimePoints.length !== newTimePoints.length) {
firstChangedPointIndex = Math.min(this._private__sortedTimePoints.length, newTimePoints.length);
}
if (firstChangedPointIndex === -1) {
return -1;
}
for (let index = firstChangedPointIndex; index < newTimePoints.length; ++index) {
assignIndexToPointData(newTimePoints[index].pointData, index);
}
this._private__horzScaleBehavior.fillWeightsForPoints(newTimePoints, firstChangedPointIndex);
this._private__sortedTimePoints = newTimePoints;
return firstChangedPointIndex;
}
_private__getBaseIndex() {
if (this._private__seriesRowsBySeries.size === 0) {
return null;
}
let baseIndex = 0;
this._private__seriesRowsBySeries.forEach((data) => {
if (data.length !== 0) {
baseIndex = Math.max(baseIndex, data[data.length - 1]._internal_index);
}
});
return baseIndex;
}
_private__getUpdateResponse(updatedSeries, firstChangedPointIndex, info) {
const dataUpdateResponse = {
_internal_series: /* @__PURE__ */ new Map(),
_internal_timeScale: {
_internal_baseIndex: this._private__getBaseIndex()
}
};
if (firstChangedPointIndex !== -1) {
this._private__seriesRowsBySeries.forEach((data, s) => {
dataUpdateResponse._internal_series.set(s, {
_internal_data: data,
_internal_info: s === updatedSeries ? info : void 0
});
});
if (!this._private__seriesRowsBySeries.has(updatedSeries)) {
dataUpdateResponse._internal_series.set(updatedSeries, { _internal_data: [], _internal_info: info });
}
dataUpdateResponse._internal_timeScale._internal_points = this._private__sortedTimePoints;
dataUpdateResponse._internal_timeScale._internal_firstChangedPointIndex = firstChangedPointIndex;
} else {
const seriesData = this._private__seriesRowsBySeries.get(updatedSeries);
dataUpdateResponse._internal_series.set(updatedSeries, { _internal_data: seriesData || [], _internal_info: info });
}
return dataUpdateResponse;
}
};
function assignIndexToPointData(pointData, index) {
pointData._internal_index = index;
pointData._internal_mapping.forEach((seriesRow) => {
seriesRow._internal_index = index;
});
}
function singleValueData(plotRow) {
const data = {
value: plotRow._internal_value[
3
/* PlotRowValueIndex.Close */
],
time: plotRow._internal_originalTime
};
if (plotRow._internal_customValues !== void 0) {
data.customValues = plotRow._internal_customValues;
}
return data;
}
function lineData(plotRow) {
const result = singleValueData(plotRow);
if (plotRow._internal_color !== void 0) {
result.color = plotRow._internal_color;
}
return result;
}
function areaData(plotRow) {
const result = singleValueData(plotRow);
if (plotRow._internal_lineColor !== void 0) {
result.lineColor = plotRow._internal_lineColor;
}
if (plotRow._internal_topColor !== void 0) {
result.topColor = plotRow._internal_topColor;
}
if (plotRow._internal_bottomColor !== void 0) {
result.bottomColor = plotRow._internal_bottomColor;
}
return result;
}
function baselineData(plotRow) {
const result = singleValueData(plotRow);
if (plotRow._internal_topLineColor !== void 0) {
result.topLineColor = plotRow._internal_topLineColor;
}
if (plotRow._internal_bottomLineColor !== void 0) {
result.bottomLineColor = plotRow._internal_bottomLineColor;
}
if (plotRow._internal_topFillColor1 !== void 0) {
result.topFillColor1 = plotRow._internal_topFillColor1;
}
if (plotRow._internal_topFillColor2 !== void 0) {
result.topFillColor2 = plotRow._internal_topFillColor2;
}
if (plotRow._internal_bottomFillColor1 !== void 0) {
result.bottomFillColor1 = plotRow._internal_bottomFillColor1;
}
if (plotRow._internal_bottomFillColor2 !== void 0) {
result.bottomFillColor2 = plotRow._internal_bottomFillColor2;
}
return result;
}
function ohlcData(plotRow) {
const data = {
open: plotRow._internal_value[
0
/* PlotRowValueIndex.Open */
],
high: plotRow._internal_value[
1
/* PlotRowValueIndex.High */
],
low: plotRow._internal_value[
2
/* PlotRowValueIndex.Low */
],
close: plotRow._internal_value[
3
/* PlotRowValueIndex.Close */
],
time: plotRow._internal_originalTime
};
if (plotRow._internal_customValues !== void 0) {
data.customValues = plotRow._internal_customValues;
}
return data;
}
function barData(plotRow) {
const result = ohlcData(plotRow);
if (plotRow._internal_color !== void 0) {
result.color = plotRow._internal_color;
}
return result;
}
function candlestickData(plotRow) {
const result = ohlcData(plotRow);
const { _internal_color: color2, _internal_borderColor: borderColor, _internal_wickColor: wickColor } = plotRow;
if (color2 !== void 0) {
result.color = color2;
}
if (borderColor !== void 0) {
result.borderColor = borderColor;
}
if (wickColor !== void 0) {
result.wickColor = wickColor;
}
return result;
}
function getSeriesDataCreator(seriesType) {
const seriesPlotRowToDataMap = {
Area: areaData,
Line: lineData,
Baseline: baselineData,
Histogram: lineData,
Bar: barData,
Candlestick: candlestickData,
Custom: customData
};
return seriesPlotRowToDataMap[seriesType];
}
function customData(plotRow) {
const time = plotRow._internal_originalTime;
return Object.assign(Object.assign({}, plotRow._internal_data), { time });
}
var crosshairOptionsDefaults = {
vertLine: {
color: "#9598A1",
width: 1,
style: 3,
visible: true,
labelVisible: true,
labelBackgroundColor: "#131722"
},
horzLine: {
color: "#9598A1",
width: 1,
style: 3,
visible: true,
labelVisible: true,
labelBackgroundColor: "#131722"
},
mode: 1
};
var gridOptionsDefaults = {
vertLines: {
color: "#D6DCDE",
style: 0,
visible: true
},
horzLines: {
color: "#D6DCDE",
style: 0,
visible: true
}
};
var layoutOptionsDefaults = {
background: {
type: "solid",
color: "#FFFFFF"
},
textColor: "#191919",
fontSize: 12,
fontFamily: defaultFontFamily,
attributionLogo: true
};
var priceScaleOptionsDefaults = {
autoScale: true,
mode: 0,
invertScale: false,
alignLabels: true,
borderVisible: true,
borderColor: "#2B2B43",
entireTextOnly: false,
visible: false,
ticksVisible: false,
scaleMargins: {
bottom: 0.1,
top: 0.2
},
minimumWidth: 0
};
var timeScaleOptionsDefaults = {
rightOffset: 0,
barSpacing: 6,
minBarSpacing: 0.5,
fixLeftEdge: false,
fixRightEdge: false,
lockVisibleTimeRangeOnResize: false,
rightBarStaysOnScroll: false,
borderVisible: true,
borderColor: "#2B2B43",
visible: true,
timeVisible: false,
secondsVisible: true,
shiftVisibleRangeOnNewBar: true,
allowShiftVisibleRangeOnWhitespaceReplacement: false,
ticksVisible: false,
uniformDistribution: false,
minimumHeight: 0,
allowBoldLabels: true
};
var watermarkOptionsDefaults = {
color: "rgba(0, 0, 0, 0)",
visible: false,
fontSize: 48,
fontFamily: defaultFontFamily,
fontStyle: "",
text: "",
horzAlign: "center",
vertAlign: "center"
};
function chartOptionsDefaults() {
return {
width: 0,
height: 0,
autoSize: false,
layout: layoutOptionsDefaults,
crosshair: crosshairOptionsDefaults,
grid: gridOptionsDefaults,
overlayPriceScales: Object.assign({}, priceScaleOptionsDefaults),
leftPriceScale: Object.assign(Object.assign({}, priceScaleOptionsDefaults), { visible: false }),
rightPriceScale: Object.assign(Object.assign({}, priceScaleOptionsDefaults), { visible: true }),
timeScale: timeScaleOptionsDefaults,
watermark: watermarkOptionsDefaults,
localization: {
locale: isRunningOnClientSide ? navigator.language : "",
dateFormat: "dd MMM 'yy"
},
handleScroll: {
mouseWheel: true,
pressedMouseMove: true,
horzTouchDrag: true,
vertTouchDrag: true
},
handleScale: {
axisPressedMouseMove: {
time: true,
price: true
},
axisDoubleClickReset: {
time: true,
price: true
},
mouseWheel: true,
pinch: true
},
kineticScroll: {
mouse: false,
touch: true
},
trackingMode: {
exitMode: 1
}
};
}
var PriceScaleApi = class {
constructor(chartWidget, priceScaleId) {
this._private__chartWidget = chartWidget;
this._private__priceScaleId = priceScaleId;
}
applyOptions(options) {
this._private__chartWidget._internal_model()._internal_applyPriceScaleOptions(this._private__priceScaleId, options);
}
options() {
return this._private__priceScale()._internal_options();
}
width() {
if (!isDefaultPriceScale(this._private__priceScaleId)) {
return 0;
}
return this._private__chartWidget._internal_getPriceAxisWidth(this._private__priceScaleId);
}
_private__priceScale() {
return ensureNotNull(this._private__chartWidget._internal_model()._internal_findPriceScale(this._private__priceScaleId))._internal_priceScale;
}
};
function checkPriceLineOptions(options) {
assert(typeof options.price === "number", `the type of 'price' price line's property must be a number, got '${typeof options.price}'`);
}
function checkItemsAreOrdered(data, bh, allowDuplicates = false) {
if (data.length === 0) {
return;
}
let prevTime = bh.key(data[0].time);
for (let i = 1; i < data.length; ++i) {
const currentTime = bh.key(data[i].time);
const checkResult = allowDuplicates ? prevTime <= currentTime : prevTime < currentTime;
assert(checkResult, `data must be asc ordered by time, index=${i}, time=${currentTime}, prev time=${prevTime}`);
prevTime = currentTime;
}
}
function checkSeriesValuesType(type, data) {
data.forEach(getChecker(type));
}
function getChecker(type) {
switch (type) {
case "Bar":
case "Candlestick":
return checkBarItem.bind(null, type);
case "Area":
case "Baseline":
case "Line":
case "Histogram":
return checkLineItem.bind(null, type);
case "Custom":
return checkCustomItem.bind(null, type);
}
}
function checkBarItem(type, barItem) {
if (!isFulfilledBarData(barItem)) {
return;
}
assert(
// eslint-disable-next-line @typescript-eslint/tslint/config
typeof barItem.open === "number",
`${type} series item data value of open must be a number, got=${typeof barItem.open}, value=${barItem.open}`
);
assert(
// eslint-disable-next-line @typescript-eslint/tslint/config
typeof barItem.high === "number",
`${type} series item data value of high must be a number, got=${typeof barItem.high}, value=${barItem.high}`
);
assert(
// eslint-disable-next-line @typescript-eslint/tslint/config
typeof barItem.low === "number",
`${type} series item data value of low must be a number, got=${typeof barItem.low}, value=${barItem.low}`
);
assert(
// eslint-disable-next-line @typescript-eslint/tslint/config
typeof barItem.close === "number",
`${type} series item data value of close must be a number, got=${typeof barItem.close}, value=${barItem.close}`
);
}
function checkLineItem(type, lineItem) {
if (!isFulfilledLineData(lineItem)) {
return;
}
assert(
// eslint-disable-next-line @typescript-eslint/tslint/config
typeof lineItem.value === "number",
`${type} series item data value must be a number, got=${typeof lineItem.value}, value=${lineItem.value}`
);
}
function checkCustomItem() {
return;
}
function convertSeriesMarker(sm, newTime, originalTime) {
const values = __rest(sm, ["time", "originalTime"]);
const res = Object.assign({ time: newTime }, values);
if (originalTime !== void 0) {
res.originalTime = originalTime;
}
return res;
}
var priceLineOptionsDefaults = {
color: "#FF0000",
price: 0,
lineStyle: 2,
lineWidth: 1,
lineVisible: true,
axisLabelVisible: true,
title: "",
axisLabelColor: "",
axisLabelTextColor: ""
};
var PriceLine = class {
constructor(priceLine) {
this._private__priceLine = priceLine;
}
applyOptions(options) {
this._private__priceLine._internal_applyOptions(options);
}
options() {
return this._private__priceLine._internal_options();
}
_internal_priceLine() {
return this._private__priceLine;
}
};
var SeriesApi = class {
constructor(series, dataUpdatesConsumer, priceScaleApiProvider, chartApi, horzScaleBehavior) {
this._private__dataChangedDelegate = new Delegate();
this._internal__series = series;
this._internal__dataUpdatesConsumer = dataUpdatesConsumer;
this._private__priceScaleApiProvider = priceScaleApiProvider;
this._private__horzScaleBehavior = horzScaleBehavior;
this._internal__chartApi = chartApi;
}
_internal_destroy() {
this._private__dataChangedDelegate._internal_destroy();
}
priceFormatter() {
return this._internal__series._internal_formatter();
}
priceToCoordinate(price) {
const firstValue = this._internal__series._internal_firstValue();
if (firstValue === null) {
return null;
}
return this._internal__series._internal_priceScale()._internal_priceToCoordinate(price, firstValue._internal_value);
}
coordinateToPrice(coordinate) {
const firstValue = this._internal__series._internal_firstValue();
if (firstValue === null) {
return null;
}
return this._internal__series._internal_priceScale()._internal_coordinateToPrice(coordinate, firstValue._internal_value);
}
barsInLogicalRange(range) {
if (range === null) {
return null;
}
const correctedRange = new TimeScaleVisibleRange(new RangeImpl(range.from, range.to))._internal_strictRange();
const bars = this._internal__series._internal_bars();
if (bars._internal_isEmpty()) {
return null;
}
const dataFirstBarInRange = bars._internal_search(
correctedRange._internal_left(),
1
/* MismatchDirection.NearestRight */
);
const dataLastBarInRange = bars._internal_search(
correctedRange._internal_right(),
-1
/* MismatchDirection.NearestLeft */
);
const dataFirstIndex = ensureNotNull(bars._internal_firstIndex());
const dataLastIndex = ensureNotNull(bars._internal_lastIndex());
if (dataFirstBarInRange !== null && dataLastBarInRange !== null && dataFirstBarInRange._internal_index > dataLastBarInRange._internal_index) {
return {
barsBefore: range.from - dataFirstIndex,
barsAfter: dataLastIndex - range.to
};
}
const barsBefore = dataFirstBarInRange === null || dataFirstBarInRange._internal_index === dataFirstIndex ? range.from - dataFirstIndex : dataFirstBarInRange._internal_index - dataFirstIndex;
const barsAfter = dataLastBarInRange === null || dataLastBarInRange._internal_index === dataLastIndex ? dataLastIndex - range.to : dataLastIndex - dataLastBarInRange._internal_index;
const result = { barsBefore, barsAfter };
if (dataFirstBarInRange !== null && dataLastBarInRange !== null) {
result.from = dataFirstBarInRange._internal_originalTime;
result.to = dataLastBarInRange._internal_originalTime;
}
return result;
}
setData(data) {
checkItemsAreOrdered(data, this._private__horzScaleBehavior);
checkSeriesValuesType(this._internal__series._internal_seriesType(), data);
this._internal__dataUpdatesConsumer._internal_applyNewData(this._internal__series, data);
this._private__onDataChanged("full");
}
update(bar) {
checkSeriesValuesType(this._internal__series._internal_seriesType(), [bar]);
this._internal__dataUpdatesConsumer._internal_updateData(this._internal__series, bar);
this._private__onDataChanged("update");
}
dataByIndex(logicalIndex, mismatchDirection) {
const data = this._internal__series._internal_bars()._internal_search(logicalIndex, mismatchDirection);
if (data === null) {
return null;
}
const creator = getSeriesDataCreator(this.seriesType());
return creator(data);
}
data() {
const seriesCreator = getSeriesDataCreator(this.seriesType());
const rows = this._internal__series._internal_bars()._internal_rows();
return rows.map((row) => seriesCreator(row));
}
subscribeDataChanged(handler) {
this._private__dataChangedDelegate._internal_subscribe(handler);
}
unsubscribeDataChanged(handler) {
this._private__dataChangedDelegate._internal_unsubscribe(handler);
}
setMarkers(data) {
checkItemsAreOrdered(data, this._private__horzScaleBehavior, true);
const convertedMarkers = data.map((marker) => convertSeriesMarker(marker, this._private__horzScaleBehavior.convertHorzItemToInternal(marker.time), marker.time));
this._internal__series._internal_setMarkers(convertedMarkers);
}
markers() {
return this._internal__series._internal_markers().map((internalItem) => {
return convertSeriesMarker(internalItem, internalItem.originalTime, void 0);
});
}
applyOptions(options) {
this._internal__series._internal_applyOptions(options);
}
options() {
return clone(this._internal__series._internal_options());
}
priceScale() {
return this._private__priceScaleApiProvider.priceScale(this._internal__series._internal_priceScale()._internal_id());
}
createPriceLine(options) {
checkPriceLineOptions(options);
const strictOptions = merge(clone(priceLineOptionsDefaults), options);
const priceLine = this._internal__series._internal_createPriceLine(strictOptions);
return new PriceLine(priceLine);
}
removePriceLine(line) {
this._internal__series._internal_removePriceLine(line._internal_priceLine());
}
seriesType() {
return this._internal__series._internal_seriesType();
}
attachPrimitive(primitive) {
this._internal__series._internal_attachPrimitive(primitive);
if (primitive.attached) {
primitive.attached({
chart: this._internal__chartApi,
series: this,
requestUpdate: () => this._internal__series._internal_model()._internal_fullUpdate()
});
}
}
detachPrimitive(primitive) {
this._internal__series._internal_detachPrimitive(primitive);
if (primitive.detached) {
primitive.detached();
}
}
_private__onDataChanged(scope) {
if (this._private__dataChangedDelegate._internal_hasListeners()) {
this._private__dataChangedDelegate._internal_fire(scope);
}
}
};
var TimeScaleApi = class {
constructor(model, timeAxisWidget, horzScaleBehavior) {
this._private__timeRangeChanged = new Delegate();
this._private__logicalRangeChanged = new Delegate();
this._private__sizeChanged = new Delegate();
this._private__model = model;
this._private__timeScale = model._internal_timeScale();
this._private__timeAxisWidget = timeAxisWidget;
this._private__timeScale._internal_visibleBarsChanged()._internal_subscribe(this._private__onVisibleBarsChanged.bind(this));
this._private__timeScale._internal_logicalRangeChanged()._internal_subscribe(this._private__onVisibleLogicalRangeChanged.bind(this));
this._private__timeAxisWidget._internal_sizeChanged()._internal_subscribe(this._private__onSizeChanged.bind(this));
this._private__horzScaleBehavior = horzScaleBehavior;
}
_internal_destroy() {
this._private__timeScale._internal_visibleBarsChanged()._internal_unsubscribeAll(this);
this._private__timeScale._internal_logicalRangeChanged()._internal_unsubscribeAll(this);
this._private__timeAxisWidget._internal_sizeChanged()._internal_unsubscribeAll(this);
this._private__timeRangeChanged._internal_destroy();
this._private__logicalRangeChanged._internal_destroy();
this._private__sizeChanged._internal_destroy();
}
scrollPosition() {
return this._private__timeScale._internal_rightOffset();
}
scrollToPosition(position, animated) {
if (!animated) {
this._private__model._internal_setRightOffset(position);
return;
}
this._private__timeScale._internal_scrollToOffsetAnimated(
position,
1e3
/* Constants.AnimationDurationMs */
);
}
scrollToRealTime() {
this._private__timeScale._internal_scrollToRealTime();
}
getVisibleRange() {
const timeRange = this._private__timeScale._internal_visibleTimeRange();
if (timeRange === null) {
return null;
}
return {
from: timeRange.from.originalTime,
to: timeRange.to.originalTime
};
}
setVisibleRange(range) {
const convertedRange = {
from: this._private__horzScaleBehavior.convertHorzItemToInternal(range.from),
to: this._private__horzScaleBehavior.convertHorzItemToInternal(range.to)
};
const logicalRange = this._private__timeScale._internal_logicalRangeForTimeRange(convertedRange);
this._private__model._internal_setTargetLogicalRange(logicalRange);
}
getVisibleLogicalRange() {
const logicalRange = this._private__timeScale._internal_visibleLogicalRange();
if (logicalRange === null) {
return null;
}
return {
from: logicalRange._internal_left(),
to: logicalRange._internal_right()
};
}
setVisibleLogicalRange(range) {
assert(range.from <= range.to, "The from index cannot be after the to index.");
this._private__model._internal_setTargetLogicalRange(range);
}
resetTimeScale() {
this._private__model._internal_resetTimeScale();
}
fitContent() {
this._private__model._internal_fitContent();
}
logicalToCoordinate(logical) {
const timeScale = this._private__model._internal_timeScale();
if (timeScale._internal_isEmpty()) {
return null;
} else {
return timeScale._internal_indexToCoordinate(logical);
}
}
coordinateToLogical(x) {
if (this._private__timeScale._internal_isEmpty()) {
return null;
} else {
return this._private__timeScale._internal_coordinateToIndex(x);
}
}
timeToCoordinate(time) {
const timePoint = this._private__horzScaleBehavior.convertHorzItemToInternal(time);
const timePointIndex = this._private__timeScale._internal_timeToIndex(timePoint, false);
if (timePointIndex === null) {
return null;
}
return this._private__timeScale._internal_indexToCoordinate(timePointIndex);
}
coordinateToTime(x) {
const timeScale = this._private__model._internal_timeScale();
const timePointIndex = timeScale._internal_coordinateToIndex(x);
const timePoint = timeScale._internal_indexToTimeScalePoint(timePointIndex);
if (timePoint === null) {
return null;
}
return timePoint.originalTime;
}
width() {
return this._private__timeAxisWidget._internal_getSize().width;
}
height() {
return this._private__timeAxisWidget._internal_getSize().height;
}
subscribeVisibleTimeRangeChange(handler) {
this._private__timeRangeChanged._internal_subscribe(handler);
}
unsubscribeVisibleTimeRangeChange(handler) {
this._private__timeRangeChanged._internal_unsubscribe(handler);
}
subscribeVisibleLogicalRangeChange(handler) {
this._private__logicalRangeChanged._internal_subscribe(handler);
}
unsubscribeVisibleLogicalRangeChange(handler) {
this._private__logicalRangeChanged._internal_unsubscribe(handler);
}
subscribeSizeChange(handler) {
this._private__sizeChanged._internal_subscribe(handler);
}
unsubscribeSizeChange(handler) {
this._private__sizeChanged._internal_unsubscribe(handler);
}
applyOptions(options) {
this._private__timeScale._internal_applyOptions(options);
}
options() {
return Object.assign(Object.assign({}, clone(this._private__timeScale._internal_options())), { barSpacing: this._private__timeScale._internal_barSpacing() });
}
_private__onVisibleBarsChanged() {
if (this._private__timeRangeChanged._internal_hasListeners()) {
this._private__timeRangeChanged._internal_fire(this.getVisibleRange());
}
}
_private__onVisibleLogicalRangeChanged() {
if (this._private__logicalRangeChanged._internal_hasListeners()) {
this._private__logicalRangeChanged._internal_fire(this.getVisibleLogicalRange());
}
}
_private__onSizeChanged(size3) {
this._private__sizeChanged._internal_fire(size3.width, size3.height);
}
};
function patchPriceFormat(priceFormat) {
if (priceFormat === void 0 || priceFormat.type === "custom") {
return;
}
const priceFormatBuiltIn = priceFormat;
if (priceFormatBuiltIn.minMove !== void 0 && priceFormatBuiltIn.precision === void 0) {
priceFormatBuiltIn.precision = precisionByMinMove(priceFormatBuiltIn.minMove);
}
}
function migrateHandleScaleScrollOptions(options) {
if (isBoolean(options.handleScale)) {
const handleScale = options.handleScale;
options.handleScale = {
axisDoubleClickReset: {
time: handleScale,
price: handleScale
},
axisPressedMouseMove: {
time: handleScale,
price: handleScale
},
mouseWheel: handleScale,
pinch: handleScale
};
} else if (options.handleScale !== void 0) {
const { axisPressedMouseMove, axisDoubleClickReset } = options.handleScale;
if (isBoolean(axisPressedMouseMove)) {
options.handleScale.axisPressedMouseMove = {
time: axisPressedMouseMove,
price: axisPressedMouseMove
};
}
if (isBoolean(axisDoubleClickReset)) {
options.handleScale.axisDoubleClickReset = {
time: axisDoubleClickReset,
price: axisDoubleClickReset
};
}
}
const handleScroll = options.handleScroll;
if (isBoolean(handleScroll)) {
options.handleScroll = {
horzTouchDrag: handleScroll,
vertTouchDrag: handleScroll,
mouseWheel: handleScroll,
pressedMouseMove: handleScroll
};
}
}
function toInternalOptions(options) {
migrateHandleScaleScrollOptions(options);
return options;
}
var ChartApi = class {
constructor(container, horzScaleBehavior, options) {
this._private__seriesMap = /* @__PURE__ */ new Map();
this._private__seriesMapReversed = /* @__PURE__ */ new Map();
this._private__clickedDelegate = new Delegate();
this._private__dblClickedDelegate = new Delegate();
this._private__crosshairMovedDelegate = new Delegate();
this._private__dataLayer = new DataLayer(horzScaleBehavior);
const internalOptions = options === void 0 ? clone(chartOptionsDefaults()) : merge(clone(chartOptionsDefaults()), toInternalOptions(options));
this._private__horzScaleBehavior = horzScaleBehavior;
this._private__chartWidget = new ChartWidget(container, internalOptions, horzScaleBehavior);
this._private__chartWidget._internal_clicked()._internal_subscribe((paramSupplier) => {
if (this._private__clickedDelegate._internal_hasListeners()) {
this._private__clickedDelegate._internal_fire(this._private__convertMouseParams(paramSupplier()));
}
}, this);
this._private__chartWidget._internal_dblClicked()._internal_subscribe((paramSupplier) => {
if (this._private__dblClickedDelegate._internal_hasListeners()) {
this._private__dblClickedDelegate._internal_fire(this._private__convertMouseParams(paramSupplier()));
}
}, this);
this._private__chartWidget._internal_crosshairMoved()._internal_subscribe((paramSupplier) => {
if (this._private__crosshairMovedDelegate._internal_hasListeners()) {
this._private__crosshairMovedDelegate._internal_fire(this._private__convertMouseParams(paramSupplier()));
}
}, this);
const model = this._private__chartWidget._internal_model();
this._private__timeScaleApi = new TimeScaleApi(model, this._private__chartWidget._internal_timeAxisWidget(), this._private__horzScaleBehavior);
}
remove() {
this._private__chartWidget._internal_clicked()._internal_unsubscribeAll(this);
this._private__chartWidget._internal_dblClicked()._internal_unsubscribeAll(this);
this._private__chartWidget._internal_crosshairMoved()._internal_unsubscribeAll(this);
this._private__timeScaleApi._internal_destroy();
this._private__chartWidget._internal_destroy();
this._private__seriesMap.clear();
this._private__seriesMapReversed.clear();
this._private__clickedDelegate._internal_destroy();
this._private__dblClickedDelegate._internal_destroy();
this._private__crosshairMovedDelegate._internal_destroy();
this._private__dataLayer._internal_destroy();
}
resize(width, height, forceRepaint) {
if (this.autoSizeActive()) {
warn(`Height and width values ignored because 'autoSize' option is enabled.`);
return;
}
this._private__chartWidget._internal_resize(width, height, forceRepaint);
}
addCustomSeries(customPaneView, options) {
const paneView = ensure(customPaneView);
const defaults = Object.assign(Object.assign({}, customStyleDefaults), paneView.defaultOptions());
return this._private__addSeriesImpl("Custom", defaults, options, paneView);
}
addAreaSeries(options) {
return this._private__addSeriesImpl("Area", areaStyleDefaults, options);
}
addBaselineSeries(options) {
return this._private__addSeriesImpl("Baseline", baselineStyleDefaults, options);
}
addBarSeries(options) {
return this._private__addSeriesImpl("Bar", barStyleDefaults, options);
}
addCandlestickSeries(options = {}) {
fillUpDownCandlesticksColors(options);
return this._private__addSeriesImpl("Candlestick", candlestickStyleDefaults, options);
}
addHistogramSeries(options) {
return this._private__addSeriesImpl("Histogram", histogramStyleDefaults, options);
}
addLineSeries(options) {
return this._private__addSeriesImpl("Line", lineStyleDefaults, options);
}
removeSeries(seriesApi) {
const series = ensureDefined(this._private__seriesMap.get(seriesApi));
const update = this._private__dataLayer._internal_removeSeries(series);
const model = this._private__chartWidget._internal_model();
model._internal_removeSeries(series);
this._private__sendUpdateToChart(update);
this._private__seriesMap.delete(seriesApi);
this._private__seriesMapReversed.delete(series);
}
_internal_applyNewData(series, data) {
this._private__sendUpdateToChart(this._private__dataLayer._internal_setSeriesData(series, data));
}
_internal_updateData(series, data) {
this._private__sendUpdateToChart(this._private__dataLayer._internal_updateSeriesData(series, data));
}
subscribeClick(handler) {
this._private__clickedDelegate._internal_subscribe(handler);
}
unsubscribeClick(handler) {
this._private__clickedDelegate._internal_unsubscribe(handler);
}
subscribeCrosshairMove(handler) {
this._private__crosshairMovedDelegate._internal_subscribe(handler);
}
unsubscribeCrosshairMove(handler) {
this._private__crosshairMovedDelegate._internal_unsubscribe(handler);
}
subscribeDblClick(handler) {
this._private__dblClickedDelegate._internal_subscribe(handler);
}
unsubscribeDblClick(handler) {
this._private__dblClickedDelegate._internal_unsubscribe(handler);
}
priceScale(priceScaleId) {
return new PriceScaleApi(this._private__chartWidget, priceScaleId);
}
timeScale() {
return this._private__timeScaleApi;
}
applyOptions(options) {
this._private__chartWidget._internal_applyOptions(toInternalOptions(options));
}
options() {
return this._private__chartWidget._internal_options();
}
takeScreenshot() {
return this._private__chartWidget._internal_takeScreenshot();
}
autoSizeActive() {
return this._private__chartWidget._internal_autoSizeActive();
}
chartElement() {
return this._private__chartWidget._internal_element();
}
paneSize() {
const size3 = this._private__chartWidget._internal_paneSize();
return {
height: size3.height,
width: size3.width
};
}
setCrosshairPosition(price, horizontalPosition, seriesApi) {
const series = this._private__seriesMap.get(seriesApi);
if (series === void 0) {
return;
}
const pane = this._private__chartWidget._internal_model()._internal_paneForSource(series);
if (pane === null) {
return;
}
this._private__chartWidget._internal_model()._internal_setAndSaveSyntheticPosition(price, horizontalPosition, pane);
}
clearCrosshairPosition() {
this._private__chartWidget._internal_model()._internal_clearCurrentPosition(true);
}
_private__addSeriesImpl(type, styleDefaults, options = {}, customPaneView) {
patchPriceFormat(options.priceFormat);
const strictOptions = merge(clone(seriesOptionsDefaults), clone(styleDefaults), options);
const series = this._private__chartWidget._internal_model()._internal_createSeries(type, strictOptions, customPaneView);
const res = new SeriesApi(series, this, this, this, this._private__horzScaleBehavior);
this._private__seriesMap.set(res, series);
this._private__seriesMapReversed.set(series, res);
return res;
}
_private__sendUpdateToChart(update) {
const model = this._private__chartWidget._internal_model();
model._internal_updateTimeScale(update._internal_timeScale._internal_baseIndex, update._internal_timeScale._internal_points, update._internal_timeScale._internal_firstChangedPointIndex);
update._internal_series.forEach((value, series) => series._internal_setData(value._internal_data, value._internal_info));
model._internal_recalculateAllPanes();
}
_private__mapSeriesToApi(series) {
return ensureDefined(this._private__seriesMapReversed.get(series));
}
_private__convertMouseParams(param) {
const seriesData = /* @__PURE__ */ new Map();
param._internal_seriesData.forEach((plotRow, series) => {
const seriesType = series._internal_seriesType();
const data = getSeriesDataCreator(seriesType)(plotRow);
if (seriesType !== "Custom") {
assert(isFulfilledData(data));
} else {
const customWhitespaceChecker = series._internal_customSeriesWhitespaceCheck();
assert(!customWhitespaceChecker || customWhitespaceChecker(data) === false);
}
seriesData.set(this._private__mapSeriesToApi(series), data);
});
const hoveredSeries = param._internal_hoveredSeries === void 0 || !this._private__seriesMapReversed.has(param._internal_hoveredSeries) ? void 0 : this._private__mapSeriesToApi(param._internal_hoveredSeries);
return {
time: param._internal_originalTime,
logical: param._internal_index,
point: param._internal_point,
hoveredSeries,
hoveredObjectId: param._internal_hoveredObject,
seriesData,
sourceEvent: param._internal_touchMouseEventData
};
}
};
function createChartEx(container, horzScaleBehavior, options) {
let htmlElement;
if (isString(container)) {
const element = document.getElementById(container);
assert(element !== null, `Cannot find element in DOM with id=${container}`);
htmlElement = element;
} else {
htmlElement = container;
}
const res = new ChartApi(htmlElement, horzScaleBehavior, options);
horzScaleBehavior.setOptions(res.options());
return res;
}
function createChart(container, options) {
return createChartEx(container, new HorzScaleBehaviorTime(), HorzScaleBehaviorTime._internal_applyDefaults(options));
}
function defaultHorzScaleBehavior() {
return HorzScaleBehaviorTime;
}
var customSeriesDefaultOptions = Object.assign(Object.assign({}, seriesOptionsDefaults), customStyleDefaults);
function version() {
return "4.2.3";
}
export {
ColorType,
CrosshairMode,
LastPriceAnimationMode,
LineStyle,
LineType,
MismatchDirection,
PriceLineSource,
PriceScaleMode,
TickMarkType,
TrackingModeExitMode,
createChart,
createChartEx,
customSeriesDefaultOptions,
defaultHorzScaleBehavior,
isBusinessDay,
isUTCTimestamp,
version
};
/*! Bundled license information:
lightweight-charts/dist/lightweight-charts.development.mjs:
(*!
* @license
* TradingView Lightweight Charts™ v4.2.3
* Copyright (c) 2025 TradingView, Inc.
* Licensed under Apache License 2.0 https://www.apache.org/licenses/LICENSE-2.0
*)
*/
//# sourceMappingURL=lightweight-charts.js.map