openalgo-charts 1.0.16 → 1.0.18
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +72 -2
- package/dist/openalgo-charts.draw.mjs +1 -1
- package/dist/openalgo-charts.draw.mjs.map +1 -1
- package/dist/openalgo-charts.indicators.mjs +1 -1
- package/dist/openalgo-charts.indicators.mjs.map +1 -1
- package/dist/openalgo-charts.mjs +1 -1
- package/dist/openalgo-charts.mjs.map +1 -1
- package/dist/openalgo-charts.standalone.js +1 -1
- package/dist/openalgo-charts.standalone.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/** Library version string. Matches package.json (published npm release). */
|
|
2
|
-
declare const VERSION = "1.0.
|
|
2
|
+
declare const VERSION = "1.0.18";
|
|
3
3
|
/** Returns the current library version. */
|
|
4
4
|
declare function version(): string;
|
|
5
5
|
|
|
@@ -828,6 +828,7 @@ declare function plotStyleKeys(plot: IndicatorPlot): {
|
|
|
828
828
|
width: string;
|
|
829
829
|
lineStyle: string;
|
|
830
830
|
opacity: string;
|
|
831
|
+
type: string;
|
|
831
832
|
};
|
|
832
833
|
/**
|
|
833
834
|
* Per-plot appearance inputs, generated from the descriptor rather than
|
|
@@ -846,6 +847,20 @@ declare const INDICATOR_SOURCES: readonly {
|
|
|
846
847
|
}[];
|
|
847
848
|
type IndicatorSettings = Record<string, unknown>;
|
|
848
849
|
/** One plotted line/band/histogram. `type` is any registered chart type. */
|
|
850
|
+
/** A shaded band between two of an indicator's plots. */
|
|
851
|
+
interface IndicatorFillSpec {
|
|
852
|
+
/** The two plot keys to fill between. */
|
|
853
|
+
between: readonly [string, string];
|
|
854
|
+
/** Colour where the first plot is above the second. */
|
|
855
|
+
colorUp?: string;
|
|
856
|
+
/** Colour where the second is above the first. */
|
|
857
|
+
colorDown?: string;
|
|
858
|
+
/** Settings keys holding those colours, so the band is restyleable. */
|
|
859
|
+
colorUpKey?: string;
|
|
860
|
+
colorDownKey?: string;
|
|
861
|
+
/** 0..1. Defaults to 0.12. */
|
|
862
|
+
opacity?: number;
|
|
863
|
+
}
|
|
849
864
|
interface IndicatorPlot {
|
|
850
865
|
/** Key into the `calc` result. */
|
|
851
866
|
key: string;
|
|
@@ -896,6 +911,13 @@ interface IndicatorDescriptor {
|
|
|
896
911
|
placement: 'onchart' | 'pane';
|
|
897
912
|
inputs: readonly IndicatorInput[];
|
|
898
913
|
plots: readonly IndicatorPlot[];
|
|
914
|
+
/**
|
|
915
|
+
* Shaded bands between pairs of plots — the Ichimoku cloud, a Bollinger
|
|
916
|
+
* channel. A pair of lines is not the same picture as a filled region: the
|
|
917
|
+
* fill is what makes "price is above the cloud" readable at a glance, and
|
|
918
|
+
* which side leads is itself the signal, hence the two colours.
|
|
919
|
+
*/
|
|
920
|
+
fills?: readonly IndicatorFillSpec[];
|
|
899
921
|
/**
|
|
900
922
|
* Full recompute over every bar. Must return arrays the same length as
|
|
901
923
|
* `bars` (use `null` for warmup gaps — the line renderer breaks across them
|
|
@@ -1105,6 +1127,51 @@ declare class PaneLegend implements IPrimitive {
|
|
|
1105
1127
|
hitTest(x: number, y: number): PrimitiveHit | null;
|
|
1106
1128
|
}
|
|
1107
1129
|
|
|
1130
|
+
/**
|
|
1131
|
+
* Shaded band between two indicator plots — the Ichimoku cloud, a Bollinger
|
|
1132
|
+
* channel, a Keltner envelope.
|
|
1133
|
+
*
|
|
1134
|
+
* A pair of lines is not the same picture as a filled region: the fill is what
|
|
1135
|
+
* makes "price is above the cloud" or "the cloud flipped" readable at a glance,
|
|
1136
|
+
* and which side is on top is itself the signal. So the band is drawn as two
|
|
1137
|
+
* runs — one where A leads, one where B does — and the crossings between them
|
|
1138
|
+
* are split at the exact intersection rather than at the nearest bar, or the
|
|
1139
|
+
* colours would bleed a bar past every flip.
|
|
1140
|
+
*/
|
|
1141
|
+
|
|
1142
|
+
interface IndicatorFillOptions {
|
|
1143
|
+
/** Fill colour where the first series is above the second. */
|
|
1144
|
+
colorUp: string;
|
|
1145
|
+
/** Fill colour where the second is above the first. */
|
|
1146
|
+
colorDown: string;
|
|
1147
|
+
/** 0..1. Defaults to 0.12 — a band must not drown the candles it sits behind. */
|
|
1148
|
+
opacity?: number;
|
|
1149
|
+
}
|
|
1150
|
+
/** One bar's pair of values; `null` where either plot has no value yet. */
|
|
1151
|
+
interface FillPoint {
|
|
1152
|
+
/** Logical index on the shared time axis (fractional is fine). */
|
|
1153
|
+
index: number;
|
|
1154
|
+
a: number | null;
|
|
1155
|
+
b: number | null;
|
|
1156
|
+
}
|
|
1157
|
+
declare class IndicatorFill implements IPrimitive {
|
|
1158
|
+
private _points;
|
|
1159
|
+
private _opts;
|
|
1160
|
+
private _host;
|
|
1161
|
+
private _visible;
|
|
1162
|
+
constructor(options: IndicatorFillOptions);
|
|
1163
|
+
attached(host: PrimitiveHost): void;
|
|
1164
|
+
detached(): void;
|
|
1165
|
+
/** Behind the series, so the lines and candles stay crisp on top of it. */
|
|
1166
|
+
zOrder(): ZOrder;
|
|
1167
|
+
/** The plots it spans already drive the scale; the fill must not widen it. */
|
|
1168
|
+
autoscaleInfo(): null;
|
|
1169
|
+
setPoints(points: readonly FillPoint[]): void;
|
|
1170
|
+
setOptions(patch: Partial<IndicatorFillOptions>): void;
|
|
1171
|
+
setVisible(on: boolean): void;
|
|
1172
|
+
draw(ctx: CanvasRenderingContext2D, rc: PrimitiveRenderContext): void;
|
|
1173
|
+
}
|
|
1174
|
+
|
|
1108
1175
|
/**
|
|
1109
1176
|
* Indicator runtime (ARCHITECTURE.md §8). Turns an `IndicatorDescriptor` into
|
|
1110
1177
|
* live chart objects: one series per plot, optional reference levels, an
|
|
@@ -1132,6 +1199,9 @@ interface IndicatorHost {
|
|
|
1132
1199
|
addIndicatorSeries(type: string, paneIndex: number, style: Record<string, unknown> | undefined, priceScaleId: string | undefined): SeriesApi;
|
|
1133
1200
|
addIndicatorLevel(price: number, color: string, dashed: boolean, label: string, id: string, paneIndex: number): PriceLine;
|
|
1134
1201
|
removeIndicatorLevel(line: PriceLine): void;
|
|
1202
|
+
/** Attach a band drawn behind the plots (an Ichimoku cloud). */
|
|
1203
|
+
addIndicatorFill(fill: IndicatorFill, paneIndex: number): void;
|
|
1204
|
+
removeIndicatorFill(fill: IndicatorFill): void;
|
|
1135
1205
|
/** Bars of the primary price series — the calculation input. */
|
|
1136
1206
|
sourceBars(): readonly Bar[];
|
|
1137
1207
|
/** Index of a fresh pane for an indicator that wants its own. */
|
|
@@ -3115,4 +3185,4 @@ declare function lerp(a: number, b: number, t: number): number;
|
|
|
3115
3185
|
*/
|
|
3116
3186
|
declare function roundToTick(value: number, step: number): number;
|
|
3117
3187
|
|
|
3118
|
-
export { ALT_PRESET, type AddSeriesOptions, type AggTick, BUILTIN_COMMANDS, type Bar, type BarUpdate, type BarsRequest, BuySellButtons, type BuySellButtonsOptions, CHART_STATE_VERSION, CandleBuilder, type CandleBuilderOptions, type CandleStyle, type CandleUpdate, Chart, type ChartEvent, type ChartOptions, type ChartState, type ChartTheme, type CrosshairMoveEvent, type CustomShortcut, DEFAULT_CANDLE_BUILDER_OPTIONS, DEFAULT_CANDLE_STYLE, DEFAULT_HISTOGRAM_STYLE, DEFAULT_KEYMAP, DEFAULT_PRICE_SCALE_OPTIONS, DEFAULT_THEME, DEFAULT_TIME_NAVIGATOR_OPTIONS, DEFAULT_TIME_SCALE_OPTIONS, DEFAULT_TRADING_COLORS, type DataFeed, DataLayer, type DepthLevel, type DrawItem, EventMarkers, FakeDataFeed, type FeedScheduler, type HistogramStyle, INDICATOR_LINE_STYLES, INDICATOR_SOURCES, type IPrimitive, IST_OFFSET_SECONDS, type IndexedBar, type IndicatorApi, type IndicatorAttachContext, type IndicatorDescriptor, type IndicatorHost, type IndicatorInput, type IndicatorLevel, type IndicatorPlot, type IndicatorSettings, type IndicatorSource, type IndicatorState, type IndicatorStore, type IndicatorValues, InvalidationLevel, type KeymapEntry, type LateTickPolicy, type LegendValue, type LinePoint, type LogicalRange, LogoWatermark, type LogoWatermarkOptions, type LtpEvent, type MarkerPosition, type MarkerShape, type MarkerSize, type MarketDepth, type OpenAlgoConfig, OpenAlgoDataFeed, type OpenAlgoLiveConfig, OpenAlgoLiveDataFeed, type OpenAlgoTradeConfig, OpenAlgoTradeFeed, type OpenAlgoWsConfig, OpenAlgoWsFeed, type OrderSide$1 as OrderSide, type OrderType$1 as OrderType, type OriginalTime, Pane, type PaneInvalidation, PaneLegend, type PaneLegendAction, type PaneLegendOptions, type PaneState, type PlaceOrder, type PositionSide, PriceLine, type PriceLineOptions, type PriceRange, PriceScale, type PriceScaleId, type PriceScaleMode, type PriceScaleOptions, type PriceScaleState, type PrimitiveHit, type PrimitiveHost, type PrimitiveRenderContext, type RendererEntry, type RestoreReport, type SeriesApi, type SeriesDataItem, type SeriesId, type SeriesMarker, SeriesMarkers, type SeriesRenderContext, type SeriesState, type SeriesStyle, type SeriesType, type ShortcutListItem, ShortcutManager, type ShortcutManagerOptions, type ShortcutPreset, type ShortcutScope, type ShortcutTriggerEvent, type Size, type SocketFactory, type SocketLike, type SupertrendPoint, type Tick, TickBarAggregator, type TickMarkType, type TickTimeframe, TimeNavigator, type TimeNavigatorAction, type TimeNavigatorOptions, TimeScale, type TimeScaleOp, type TimeScaleOptions, type TradeFeed, type TradeMarkerVariant, TradeMarkersPrimitive, type TradingColors, TradingController, type TradingHost, type TradingLineStyle, type TradingLineVariant, type TradingOrder, type TradingOrderSide, type TradingOrderType, type TradingPosition, type TradingSettings, type TradingSyncPayload, type TradingTrade, type UTCSeconds, type UnsubscribeFn, VERSION, type VolumeMode, type WatermarkPosition, type Whitespace, type WsControlMessage, type WsMode, type WsState, type ZOrder, atr, autoscaleRange, bestHit, bitmapSize, clamp, compactVolume, conflateBars, conflateItems, conflationGroupSize, createChart, darkTheme, drawShape, effectiveMarkerPx, ema, emaSeries, epochMsToUtcSeconds, eventToCombo, formatCombo, formatIstDate, formatIstTime, formatIstTimeSeconds, formatSubscribe, formatUnsubscribe, generateBars, getChartType, getIndicator, hasIndicator, indicatorDefaults, indicatorStyleInputs, intervalToSeconds, isNewIstDay, isReservedCombo, isValidCombo, isWhitespace, istStringToUtcSeconds, lerp, lightTheme, mapHistoryResponse, mapOrder, mapPosition, markerSizePx, mergeBars, niceTicks, normalizeCombo, optimalBarWidth, parseCombo, parseMessage, plotStyleKeys, precisionForStep, registerChartType, registerIndicator, registeredChartTypes, registeredIndicators, roundToTick, rowTimeToUtcSeconds, rsi, rsiSeries, snapToDevicePixel, sourceValue, sourceValues, supertrend, supertrendSeries, toBar, trueRange, utcSecondsToIstDateString, utcSecondsToIstParts, version, verticalGradient, watermarkRect };
|
|
3188
|
+
export { ALT_PRESET, type AddSeriesOptions, type AggTick, BUILTIN_COMMANDS, type Bar, type BarUpdate, type BarsRequest, BuySellButtons, type BuySellButtonsOptions, CHART_STATE_VERSION, CandleBuilder, type CandleBuilderOptions, type CandleStyle, type CandleUpdate, Chart, type ChartEvent, type ChartOptions, type ChartState, type ChartTheme, type CrosshairMoveEvent, type CustomShortcut, DEFAULT_CANDLE_BUILDER_OPTIONS, DEFAULT_CANDLE_STYLE, DEFAULT_HISTOGRAM_STYLE, DEFAULT_KEYMAP, DEFAULT_PRICE_SCALE_OPTIONS, DEFAULT_THEME, DEFAULT_TIME_NAVIGATOR_OPTIONS, DEFAULT_TIME_SCALE_OPTIONS, DEFAULT_TRADING_COLORS, type DataFeed, DataLayer, type DepthLevel, type DrawItem, EventMarkers, FakeDataFeed, type FeedScheduler, type FillPoint, type HistogramStyle, INDICATOR_LINE_STYLES, INDICATOR_SOURCES, type IPrimitive, IST_OFFSET_SECONDS, type IndexedBar, type IndicatorApi, type IndicatorAttachContext, type IndicatorDescriptor, IndicatorFill, type IndicatorFillOptions, type IndicatorFillSpec, type IndicatorHost, type IndicatorInput, type IndicatorLevel, type IndicatorPlot, type IndicatorSettings, type IndicatorSource, type IndicatorState, type IndicatorStore, type IndicatorValues, InvalidationLevel, type KeymapEntry, type LateTickPolicy, type LegendValue, type LinePoint, type LogicalRange, LogoWatermark, type LogoWatermarkOptions, type LtpEvent, type MarkerPosition, type MarkerShape, type MarkerSize, type MarketDepth, type OpenAlgoConfig, OpenAlgoDataFeed, type OpenAlgoLiveConfig, OpenAlgoLiveDataFeed, type OpenAlgoTradeConfig, OpenAlgoTradeFeed, type OpenAlgoWsConfig, OpenAlgoWsFeed, type OrderSide$1 as OrderSide, type OrderType$1 as OrderType, type OriginalTime, Pane, type PaneInvalidation, PaneLegend, type PaneLegendAction, type PaneLegendOptions, type PaneState, type PlaceOrder, type PositionSide, PriceLine, type PriceLineOptions, type PriceRange, PriceScale, type PriceScaleId, type PriceScaleMode, type PriceScaleOptions, type PriceScaleState, type PrimitiveHit, type PrimitiveHost, type PrimitiveRenderContext, type RendererEntry, type RestoreReport, type SeriesApi, type SeriesDataItem, type SeriesId, type SeriesMarker, SeriesMarkers, type SeriesRenderContext, type SeriesState, type SeriesStyle, type SeriesType, type ShortcutListItem, ShortcutManager, type ShortcutManagerOptions, type ShortcutPreset, type ShortcutScope, type ShortcutTriggerEvent, type Size, type SocketFactory, type SocketLike, type SupertrendPoint, type Tick, TickBarAggregator, type TickMarkType, type TickTimeframe, TimeNavigator, type TimeNavigatorAction, type TimeNavigatorOptions, TimeScale, type TimeScaleOp, type TimeScaleOptions, type TradeFeed, type TradeMarkerVariant, TradeMarkersPrimitive, type TradingColors, TradingController, type TradingHost, type TradingLineStyle, type TradingLineVariant, type TradingOrder, type TradingOrderSide, type TradingOrderType, type TradingPosition, type TradingSettings, type TradingSyncPayload, type TradingTrade, type UTCSeconds, type UnsubscribeFn, VERSION, type VolumeMode, type WatermarkPosition, type Whitespace, type WsControlMessage, type WsMode, type WsState, type ZOrder, atr, autoscaleRange, bestHit, bitmapSize, clamp, compactVolume, conflateBars, conflateItems, conflationGroupSize, createChart, darkTheme, drawShape, effectiveMarkerPx, ema, emaSeries, epochMsToUtcSeconds, eventToCombo, formatCombo, formatIstDate, formatIstTime, formatIstTimeSeconds, formatSubscribe, formatUnsubscribe, generateBars, getChartType, getIndicator, hasIndicator, indicatorDefaults, indicatorStyleInputs, intervalToSeconds, isNewIstDay, isReservedCombo, isValidCombo, isWhitespace, istStringToUtcSeconds, lerp, lightTheme, mapHistoryResponse, mapOrder, mapPosition, markerSizePx, mergeBars, niceTicks, normalizeCombo, optimalBarWidth, parseCombo, parseMessage, plotStyleKeys, precisionForStep, registerChartType, registerIndicator, registeredChartTypes, registeredIndicators, roundToTick, rowTimeToUtcSeconds, rsi, rsiSeries, snapToDevicePixel, sourceValue, sourceValues, supertrend, supertrendSeries, toBar, trueRange, utcSecondsToIstDateString, utcSecondsToIstParts, version, verticalGradient, watermarkRect };
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
function t(t,e,i,n){const s=n.x-i.x,o=n.y-i.y,l=s*s+o*o;if(0===l)return Math.hypot(t-i.x,e-i.y);let r=((t-i.x)*s+(e-i.y)*o)/l;return r=r<0?0:r>1?1:r,Math.hypot(t-(i.x+r*s),e-(i.y+r*o))}function e(t,e,i,n){const s=n.x-i.x,o=n.y-i.y,l=Math.hypot(s,o);return 0===l?Math.hypot(t-i.x,e-i.y):Math.abs(o*(t-i.x)-s*(e-i.y))/l}function i(t,e){return Math.abs(t-e)}function n(t,e){return Math.abs(t-e)}function s(e,i,n){let s=1/0;for(let o=1;o<n.length;o++){const l=t(e,i,n[o-1],n[o]);l<s&&(s=l)}return s}function o(t,e){return{x0:Math.min(t.x,e.x),y0:Math.min(t.y,e.y),x1:Math.max(t.x,e.x),y1:Math.max(t.y,e.y)}}function l(e,i,n,s,l){const r=o(n,s);if(e>=r.x0&&e<=r.x1&&i>=r.y0&&i<=r.y1&&l)return 0;const a=[{x:r.x0,y:r.y0},{x:r.x1,y:r.y0},{x:r.x1,y:r.y1},{x:r.x0,y:r.y1}];let c=1/0;for(let n=0;n<4;n++){const s=t(e,i,a[n],a[(n+1)%4]);s<c&&(c=s)}return c}function r(t,e,i,n,s){const l=o(i,n),r=(l.x0+l.x1)/2,a=(l.y0+l.y1)/2,c=Math.max(1e-6,(l.x1-l.x0)/2),h=Math.max(1e-6,(l.y1-l.y0)/2),x=(t-r)/c,d=(e-a)/h,p=Math.hypot(x,d);return s&&p<=1?0:Math.abs(p-1)*Math.min(c,h)}function a(t,e,i,n,s){const o=e.x-t.x;if(0===o)return[t,e];const l=(e.y-t.y)/o;return[n?{x:0,y:t.y+(0-t.x)*l}:t,s?{x:i,y:t.y+(i-t.x)*l}:e]}function c(t){const e=function(t){const e=t.trim();if(e.startsWith("#")){const t=e.slice(1);if(3===t.length||4===t.length){const[e,i,n,s]=[...t].map(t=>parseInt(t+t,16));return[e,i,n].some(Number.isNaN)?null:{r:e,g:i,b:n,a:4===t.length?s/255:1}}if(6===t.length||8===t.length){const e=parseInt(t.slice(0,6),16);if(Number.isNaN(e))return null;const i=8===t.length?parseInt(t.slice(6,8),16)/255:1;return{r:e>>16&255,g:e>>8&255,b:255&e,a:Number.isNaN(i)?1:i}}return null}const i=/^rgba?\(\s*([\d.]+)\s*,\s*([\d.]+)\s*,\s*([\d.]+)\s*(?:,\s*([\d.]+)\s*)?\)$/i.exec(e);return null===i?null:{r:Number(i[1]),g:Number(i[2]),b:Number(i[3]),a:void 0===i[4]?1:Number(i[4])}}(t);if(null===e)return.5;const i=t=>{const e=t/255;return e<=.03928?e/12.92:Math.pow((e+.055)/1.055,2.4)};return.2126*i(e.r)+.7152*i(e.g)+.0722*i(e.b)}function h(t){return c(t)>.45?"#10131a":"#ffffff"}function x(t,e,i,n,s,o){const l=t.roundRect;"function"==typeof l?l.call(t,e,i,n,s,Math.max(0,Math.min(o,n/2,s/2))):t.rect(e,i,n,s)}const d=new Map;function p(t){d.set(t.id,t)}function y(t){const e=d.get(t);if(void 0===e)throw new Error(`openalgo-charts: unknown drawing tool "${t}"`);return e}function u(t){return d.has(t)}function f(){return Array.from(d.values())}function g(t){const{ctx:e,rc:i,style:n}=t,s=i.dpr;e.strokeStyle=n.color,e.lineWidth=Math.max(1,Math.round(n.lineWidth*s)),e.lineJoin="round",e.lineCap="round",e.setLineDash("dashed"===n.lineStyle?[6*s,4*s]:"dotted"===n.lineStyle?[1*s,3*s]:[])}function m(t){return t.style.fillColor??t.style.color}function b(t,e){if(!0!==t.style.fill)return;const{ctx:i}=t;i.save(),i.globalAlpha=t.style.fillOpacity??.12,i.fillStyle=m(t),e(),i.restore()}function _(t,e,i,n,s){const{ctx:o,rc:l,style:r}=t,a=(r.fontSize??11)*l.dpr;o.save(),o.setLineDash([]),o.font=`${a}px ui-sans-serif, system-ui, sans-serif`,o.textBaseline="middle",o.textAlign="left";const c=o.measureText(e).width;o.globalAlpha=.85,o.fillStyle=l.theme.background,o.fillRect(i-2*l.dpr,n-.75*a,c+4*l.dpr,1.5*a),o.globalAlpha=1,o.fillStyle=s??r.color,o.fillText(e,i,n),o.restore()}function w(t,e,i,n,s,o={}){const{ctx:l,rc:r}=t,a=r.dpr,c=(t.style.fontSize??11)*a;l.save(),l.setLineDash([]),l.globalAlpha=1,l.font=`${c}px ui-sans-serif, system-ui, sans-serif`,l.textBaseline="middle",l.textAlign="left";const d=5*a,p=3*a,y=1.35*c;let u=0;for(const t of e)u=Math.max(u,l.measureText(t).width);const f=u+2*d,g=y*e.length+2*p,m=o.align??"left",b="center"===m?i-f/2:"right"===m?i-f:i,_=o.place??"above",w="above"===_?n-g-4*a:"below"===_?n+4*a:n-g/2;l.beginPath(),x(l,b,w,f,g,3*a),l.fillStyle=s,l.fill(),l.fillStyle=h(s);for(let t=0;t<e.length;t++)l.fillText(e[t],b+d,w+p+y*(t+.5));return l.restore(),g}function M(t,e=0){const[i,n]=Math.abs(t).toFixed(e).split(".");return(t<0?"-":"")+i.replace(/\B(?=(\d{3})+(?!\d))/g,",")+(void 0===n?"":"."+n)}function v(t){const e=new Date(1e3*t),i=t=>String(t).padStart(2,"0");return`${e.getUTCFullYear()}-${i(e.getUTCMonth()+1)}-${i(e.getUTCDate())}`}function T(t){const e=Math.max(0,Math.round(Math.abs(t))),i=Math.floor(e/86400),n=Math.floor(e%86400/3600),s=Math.floor(e%3600/60);return i>0?`${i}d ${n}h`:n>0?`${n}h ${s}m`:`${s}m`}const S="#26a69a",P="#ef5350",L=[0,.236,.382,.5,.618,.786,1];function k(i,n,s,o){return{id:i,name:n,points:2,defaultStyle:{extendLeft:s,extendRight:o},draw:t=>{const[e,i]=a(t.pts[0],t.pts[1],t.rc.plotWidth*t.rc.dpr,t.style.extendLeft??s,t.style.extendRight??o);g(t),t.ctx.beginPath(),t.ctx.moveTo(e.x,e.y),t.ctx.lineTo(i.x,i.y),t.ctx.stroke(),t.ctx.setLineDash([])},distance:(i,n,l)=>{const r=l.drawing.style.extendLeft??s,c=l.drawing.style.extendRight??o;if(r&&c)return e(i,n,l.pts[0],l.pts[1]);const[h,x]=a(l.pts[0],l.pts[1],l.rc.plotWidth,r,c);return t(i,n,h,x)}}}const D=k("trend-line","Trend Line",!1,!1),$=k("ray","Ray",!1,!0),O=k("extended-line","Extended Line",!0,!0),F={id:"arrow",name:"Arrow",points:2,draw:t=>{const[e,i]=t.pts;g(t),t.ctx.beginPath(),t.ctx.moveTo(e.x,e.y),t.ctx.lineTo(i.x,i.y),t.ctx.stroke();const n=Math.max(8,5*t.style.lineWidth)*t.rc.dpr,s=Math.atan2(i.y-e.y,i.x-e.x);t.ctx.beginPath(),t.ctx.moveTo(i.x,i.y),t.ctx.lineTo(i.x-n*Math.cos(s-.4),i.y-n*Math.sin(s-.4)),t.ctx.lineTo(i.x-n*Math.cos(s+.4),i.y-n*Math.sin(s+.4)),t.ctx.closePath(),t.ctx.fillStyle=t.style.color,t.ctx.fill(),t.ctx.setLineDash([])},distance:(e,i,n)=>t(e,i,n.pts[0],n.pts[1])},A={id:"horizontal-line",name:"Horizontal Line",points:1,defaultStyle:{showLabels:!0},draw:t=>{const e=Math.round(t.pts[0].y)+.5;g(t),t.ctx.beginPath(),t.ctx.moveTo(0,e),t.ctx.lineTo(t.rc.plotWidth*t.rc.dpr,e),t.ctx.stroke(),t.ctx.setLineDash([]),!1!==t.style.showLabels&&_(t,t.formatPrice(t.drawing.points[0].price),4*t.rc.dpr,e-8*t.rc.dpr)},distance:(t,e,n)=>i(e,n.pts[0].y)},N={id:"horizontal-ray",name:"Horizontal Ray",points:1,defaultStyle:{showLabels:!0},draw:t=>{const e=Math.round(t.pts[0].y)+.5;g(t),t.ctx.beginPath(),t.ctx.moveTo(t.pts[0].x,e),t.ctx.lineTo(t.rc.plotWidth*t.rc.dpr,e),t.ctx.stroke(),t.ctx.setLineDash([]),!1!==t.style.showLabels&&_(t,t.formatPrice(t.drawing.points[0].price),t.pts[0].x+4*t.rc.dpr,e-8*t.rc.dpr)},distance:(t,e,n)=>t<n.pts[0].x?null:i(e,n.pts[0].y)},W={id:"vertical-line",name:"Vertical Line",points:1,draw:t=>{const e=Math.round(t.pts[0].x)+.5;g(t),t.ctx.beginPath(),t.ctx.moveTo(e,0),t.ctx.lineTo(e,t.rc.plotHeight*t.rc.dpr),t.ctx.stroke(),t.ctx.setLineDash([])},distance:(t,e,i)=>n(t,i.pts[0].x)},C={id:"cross-line",name:"Cross Line",points:1,draw:t=>{const e=Math.round(t.pts[0].x)+.5,i=Math.round(t.pts[0].y)+.5;g(t),t.ctx.beginPath(),t.ctx.moveTo(e,0),t.ctx.lineTo(e,t.rc.plotHeight*t.rc.dpr),t.ctx.moveTo(0,i),t.ctx.lineTo(t.rc.plotWidth*t.rc.dpr,i),t.ctx.stroke(),t.ctx.setLineDash([])},distance:(t,e,s)=>Math.min(n(t,s.pts[0].x),i(e,s.pts[0].y))},I={id:"rectangle",name:"Rectangle",points:2,defaultStyle:{fill:!0,fontSize:14,textAlign:"left",textVAlign:"top",textPosition:"inside"},draw:t=>{const e=o(t.pts[0],t.pts[1]);b(t,()=>t.ctx.fillRect(e.x0,e.y0,e.x1-e.x0,e.y1-e.y0)),g(t),t.ctx.strokeRect(e.x0,e.y0,e.x1-e.x0,e.y1-e.y0),t.ctx.setLineDash([]),Z(t,e.x0,e.y0,e.x1,e.y1)},distance:(t,e,i)=>l(t,e,i.pts[0],i.pts[1],!0===i.drawing.style.fill)},R={id:"ellipse",name:"Ellipse",points:2,defaultStyle:{fill:!0,fontSize:14,textAlign:"center",textVAlign:"middle",textPosition:"inside"},draw:t=>{const e=o(t.pts[0],t.pts[1]),i=(e.x0+e.x1)/2,n=(e.y0+e.y1)/2,s=Math.max(1,(e.x1-e.x0)/2),l=Math.max(1,(e.y1-e.y0)/2),r=()=>{t.ctx.beginPath(),t.ctx.ellipse(i,n,s,l,0,0,2*Math.PI)};b(t,()=>{r(),t.ctx.fill()}),g(t),r(),t.ctx.stroke(),t.ctx.setLineDash([]),Z(t,e.x0,e.y0,e.x1,e.y1)},distance:(t,e,i)=>r(t,e,i.pts[0],i.pts[1],!0===i.drawing.style.fill)},z={id:"parallel-channel",name:"Parallel Channel",points:3,defaultStyle:{fill:!0},draw:t=>{const[e,i,n]=t.pts,s=n.y-(e.y+.5*(i.y-e.y)),o={x:e.x,y:e.y+s},l={x:i.x,y:i.y+s};b(t,()=>{t.ctx.beginPath(),t.ctx.moveTo(e.x,e.y),t.ctx.lineTo(i.x,i.y),t.ctx.lineTo(l.x,l.y),t.ctx.lineTo(o.x,o.y),t.ctx.closePath(),t.ctx.fill()}),g(t),t.ctx.beginPath(),t.ctx.moveTo(e.x,e.y),t.ctx.lineTo(i.x,i.y),t.ctx.moveTo(o.x,o.y),t.ctx.lineTo(l.x,l.y),t.ctx.stroke(),t.ctx.setLineDash([]),Z(t,Math.min(e.x,i.x),Math.min(e.y,i.y,o.y,l.y),Math.max(e.x,i.x),Math.max(e.y,i.y,o.y,l.y))},distance:(e,i,n)=>{const[s,o,l]=n.pts,r=l.y-(s.y+.5*(o.y-s.y)),a=t(e,i,s,o),c=t(e,i,{x:s.x,y:s.y+r},{x:o.x,y:o.y+r});return Math.min(a,c)}};function j(t,e,i){return{id:t,name:e,points:i,defaultStyle:{showLabels:!0,levels:[...L],fill:!0,fillOpacity:.06},draw:t=>{const e=t.style.levels??L,n=t.drawing.points,s=2===i?n[0].price:n[2].price,o=n[1].price-n[0].price,l=Math.min(t.pts[0].x,t.pts[i-1].x),r=Math.max(t.pts[0].x,t.pts[i-1].x),a=!0===t.style.extendRight?t.rc.plotWidth*t.rc.dpr:r;g(t);let c=null;for(const i of e){const e=s+o*i,n=Math.round(t.rc.priceScale.priceToY(e)*t.rc.dpr)+.5;!0===t.style.fill&&null!==c&&(t.ctx.save(),t.ctx.globalAlpha=t.style.fillOpacity??.06,t.ctx.fillStyle=m(t),t.ctx.fillRect(l,Math.min(c,n),a-l,Math.abs(n-c)),t.ctx.restore()),c=n,t.ctx.beginPath(),t.ctx.moveTo(l,n),t.ctx.lineTo(a,n),t.ctx.stroke(),!1!==t.style.showLabels&&_(t,`${(100*i).toFixed(1)}% ${t.formatPrice(e)}`,l+4*t.rc.dpr,n-8*t.rc.dpr)}t.ctx.setLineDash([])},distance:(t,e,n)=>{const s=n.drawing.style.levels??L,o=n.drawing.points,l=2===i?o[0].price:o[2].price,r=o[1].price-o[0].price,a=Math.min(n.pts[0].x,n.pts[i-1].x),c=!0===n.drawing.style.extendRight?n.rc.plotWidth:Math.max(n.pts[0].x,n.pts[i-1].x);if(t<a-4||t>c+4)return null;let h=1/0;for(const t of s){const i=Math.abs(e-n.rc.priceScale.priceToY(l+r*t));i<h&&(h=i)}return h}}}const U=j("fib-retracement","Fib Retracement",2),B=j("fib-extension","Fib Extension",3),H={id:"measure",name:"Measure",points:2,defaultStyle:{fill:!0,showLabels:!0,fillOpacity:.1},draw:t=>{const e=o(t.pts[0],t.pts[1]),i=t.drawing.points,n=i[1].price-i[0].price,s=0!==i[0].price?n/i[0].price*100:0,l=n>=0,r=l?"#26a69a":"#ef5350";t.ctx.save(),t.ctx.globalAlpha=t.style.fillOpacity??.1,t.ctx.fillStyle=r,t.ctx.fillRect(e.x0,e.y0,e.x1-e.x0,e.y1-e.y0),t.ctx.restore(),g(t),t.ctx.strokeStyle=r,t.ctx.strokeRect(e.x0,e.y0,e.x1-e.x0,e.y1-e.y0),t.ctx.setLineDash([]);const a=t.rc.dataLayer.timeToIndexFloat(i[0].time),c=t.rc.dataLayer.timeToIndexFloat(i[1].time),h=Math.abs(Math.round(c-a)),x=l?"+":"";_(t,`${x}${t.formatPrice(n)} (${x}${s.toFixed(2)}%) ${h} bars`,e.x0+4*t.rc.dpr,e.y0-10*t.rc.dpr,r)},distance:(t,e,i)=>l(t,e,i.pts[0],i.pts[1],!0)};function J(t,e,i){return{id:t,name:e,points:1,defaultStyle:{showLabels:!0,fillOpacity:.13,accountSize:1e5,risk:1},expand:(t,e)=>{const n=t[0],s=.01*Math.abs(n.price)||1,o=Math.max(5,Math.round(.08*e.visibleBars)),l=n.time+Math.max(1,e.barSeconds)*o;return i?[n,{time:l,price:n.price+s},{time:l,price:n.price-s}]:[n,{time:l,price:n.price-s},{time:l,price:n.price+s}]},draw:t=>{if(t.drawing.points.length<3||t.pts.length<3)return;const[e,n,s]=t.drawing.points,o=t.rc.dpr,l=Math.min(t.pts[0].x,t.pts[1].x,t.pts[2].x),r=Math.max(t.pts[0].x,t.pts[1].x,t.pts[2].x),a=t.rc.priceScale.priceToY(e.price)*o,c=t.rc.priceScale.priceToY(n.price)*o,h=t.rc.priceScale.priceToY(s.price)*o,x=(e,i,n)=>{t.ctx.save(),t.ctx.globalAlpha=t.style.fillOpacity??.13,t.ctx.fillStyle=n,t.ctx.fillRect(l,Math.min(e,i),r-l,Math.abs(i-e)),t.ctx.restore()};x(a,c,S),x(a,h,P),g(t);for(const e of[a,c,h]){const i=Math.round(e)+.5;t.ctx.beginPath(),t.ctx.moveTo(l,i),t.ctx.lineTo(r,i),t.ctx.stroke()}if(t.ctx.setLineDash([]),!1===t.style.showLabels)return;const d=Math.abs(e.price-s.price),p=Math.abs(n.price-e.price),y=d>0?p/d:0,u=t.style.accountSize??0,f=t.style.risk??0,m=d>0&&u>0?Math.floor(u*f/100/d):0,b=t=>(0!==e.price?t/e.price*100:0).toFixed(3),_=t=>m>0?`, Amount: ${M(m*t)}`:"",v=(l+r)/2;w(t,[`Target: ${t.formatPrice(p)} (${b(p)}%)${_(p)}`],v,c,S,{align:"center",place:c<=a?"above":"below"}),w(t,[`Stop: ${t.formatPrice(d)} (${b(d)}%)${_(d)}`],v,h,P,{align:"center",place:h>=a?"below":"above"}),w(t,[`${i?"Long":"Short"} · Qty: ${m>0?M(m):"—"}`,`Risk/reward ratio: ${y.toFixed(2)}`],v,a,t.rc.theme.background,{align:"center",place:"middle"})},distance:(t,e,i)=>{if(i.pts.length<3)return null;const n=Math.min(i.pts[0].x,i.pts[1].x,i.pts[2].x),s=Math.max(i.pts[0].x,i.pts[1].x,i.pts[2].x);if(t<n-4||t>s+4)return null;const o=i.drawing.points.map(t=>i.rc.priceScale.priceToY(t.price)),l=Math.min(...o),r=Math.max(...o);return e>=l&&e<=r?0:Math.min(Math.abs(e-l),Math.abs(e-r))}}}const E=J("long-position","Long Position",!0),Y=J("short-position","Short Position",!1),q=1.35,V="ui-sans-serif, system-ui, -apple-system, Segoe UI, Roboto, sans-serif";function G(t,e){const i="bold"===t.fontWeight?"700 ":"";return`${"italic"===t.fontStyle?"italic ":""}${i}${e}px ${t.fontFamily??V}`}function Q(t,e,i){const n=(e.text??"").split("\n");if(!0!==e.wrap)return n;const s=[];for(const e of n){const n=e.split(/\s+/).filter(t=>""!==t);if(0===n.length){s.push("");continue}let o=n[0];for(let e=1;e<n.length;e++){const l=`${o} ${n[e]}`;t.measureText(l).width>i?(s.push(o),o=n[e]):o=l}s.push(o)}return s}function X(t,e,i){const n=(e.fontSize??13)*i;t.font=G(e,n);const s=Q(t,e,(e.wrapWidth??220)*i);let o=0;for(const e of s)o=Math.max(o,t.measureText(e).width);const l=n*q;return{lines:s,width:o+10*i,height:s.length*l+10*i,lineHeight:l}}function Z(t,e,i,n,s){const{ctx:o,rc:l,style:r}=t,a=r.text;if(void 0===a||""===a)return;const c=l.dpr,h=(r.fontSize??14)*c,x=6*c;o.save(),o.setLineDash([]),o.font=G(r,h),o.fillStyle=r.fontColor??r.color,o.textBaseline="top";const d=!0===r.wrap?Q(o,r,Math.max(20*c,n-e-2*x)):a.split("\n"),p=h*q,y=d.length*p,u=r.textAlign??"left";o.textAlign=u;const f="center"===u?(e+n)/2:"right"===u?n-x:e+x;let g;if("outside"===r.textPosition)g=i-y-x;else{const t=r.textVAlign??"top";g="middle"===t?(i+s-y)/2:"bottom"===t?s-y-x:i+x}for(const t of d)o.fillText(t,f,g),g+=p;o.restore()}const K={id:"text",name:"Text",points:1,defaultStyle:{text:"Text",fontSize:14,fontWeight:"normal",fontStyle:"normal",background:!1,backgroundOpacity:1,border:!1,wrap:!1,wrapWidth:220,textAlign:"left"},draw:t=>{const{ctx:e,rc:i,style:n}=t,s=i.dpr,o=X(e,n,s),l=t.pts[0].x,r=t.pts[0].y;e.save(),e.setLineDash([]),!0===n.background&&(e.globalAlpha=n.backgroundOpacity??1,e.fillStyle=n.backgroundColor??i.theme.background,e.beginPath(),e.roundRect(l,r,o.width,o.height,4*s),e.fill(),e.globalAlpha=1),!0===n.border&&(e.strokeStyle=n.borderColor??n.color,e.lineWidth=Math.max(1,n.lineWidth*s),e.beginPath(),e.roundRect(l,r,o.width,o.height,4*s),e.stroke()),e.font=G(n,(n.fontSize??13)*s),e.fillStyle=n.color,e.textBaseline="top";const a=n.textAlign??"left";e.textAlign=a;const c="center"===a?l+o.width/2:"right"===a?l+o.width-5*s:l+5*s;let h=r+5*s;for(const t of o.lines)e.fillText(t,c,h),h+=o.lineHeight;e.restore()},distance:(t,e,i)=>{const n=i.drawing.style,s=n.fontSize??13,o=i.pts[0],l=function(){if(void 0!==tt)return tt;try{tt="undefined"==typeof document?null:document.createElement("canvas").getContext("2d")}catch{tt=null}return tt}(),r=null===l?{width:(n.text??"").length*s*.6+10,height:s*q+10}:X(l,n,1);return t>=o.x-3&&t<=o.x+r.width+3&&e>=o.y-3&&e<=o.y+r.height+3?0:null}};let tt;const et={id:"path",name:"Path",points:0,draw:t=>{if(!(t.pts.length<2)){g(t),t.ctx.beginPath(),t.ctx.moveTo(t.pts[0].x,t.pts[0].y);for(let e=1;e<t.pts.length;e++)t.ctx.lineTo(t.pts[e].x,t.pts[e].y);t.ctx.stroke(),t.ctx.setLineDash([]),function(t,e,i){const n=Math.max(8,5*t.style.lineWidth)*t.rc.dpr,s=Math.atan2(i.y-e.y,i.x-e.x);t.ctx.beginPath(),t.ctx.moveTo(i.x,i.y),t.ctx.lineTo(i.x-n*Math.cos(s-.4),i.y-n*Math.sin(s-.4)),t.ctx.lineTo(i.x-n*Math.cos(s+.4),i.y-n*Math.sin(s+.4)),t.ctx.closePath(),t.ctx.fillStyle=t.style.color,t.ctx.fill()}(t,t.pts[t.pts.length-2],t.pts[t.pts.length-1])}},distance:(t,e,i)=>i.pts.length<2?null:s(t,e,i.pts)},it={id:"brush",name:"Brush",points:0,freehand:!0,defaultStyle:{lineWidth:2},draw:t=>{if(!(t.pts.length<2)){g(t),t.ctx.lineCap="round",t.ctx.lineJoin="round",t.ctx.beginPath(),t.ctx.moveTo(t.pts[0].x,t.pts[0].y);for(let e=1;e<t.pts.length;e++)t.ctx.lineTo(t.pts[e].x,t.pts[e].y);t.ctx.stroke(),t.ctx.setLineDash([])}},distance:(t,e,i)=>i.pts.length<2?null:s(t,e,i.pts)},nt={id:"rotated-rectangle",name:"Rotated Rectangle",points:3,defaultStyle:{fill:!0,fillOpacity:.12},draw:t=>{if(t.pts.length<3)return;const e=st(t.pts[0],t.pts[1],t.pts[2]);t.ctx.beginPath(),t.ctx.moveTo(e[0].x,e[0].y);for(let i=1;i<4;i++)t.ctx.lineTo(e[i].x,e[i].y);t.ctx.closePath(),!0===t.style.fill&&(t.ctx.save(),t.ctx.globalAlpha=t.style.fillOpacity??.12,t.ctx.fillStyle=m(t),t.ctx.fill(),t.ctx.restore()),g(t),t.ctx.stroke(),t.ctx.setLineDash([])},distance:(e,i,n)=>{if(n.pts.length<3)return null;const s=st(n.pts[0],n.pts[1],n.pts[2]);if(!0===n.drawing.style.fill&&function(t,e,i){let n=!1;for(let s=0,o=i.length-1;s<i.length;o=s++){const l=i[s],r=i[o];l.y>e!=r.y>e&&t<(r.x-l.x)*(e-l.y)/(r.y-l.y)+l.x&&(n=!n)}return n}(e,i,s))return 0;let o=1/0;for(let n=0;n<4;n++)o=Math.min(o,t(e,i,s[n],s[(n+1)%4]));return o}};function st(t,e,i){const n=e.x-t.x,s=e.y-t.y,o=Math.hypot(n,s)||1,l=-s/o,r=n/o,a=(i.x-e.x)*l+(i.y-e.y)*r;return[t,e,{x:e.x+l*a,y:e.y+r*a},{x:t.x+l*a,y:t.y+r*a}]}const ot={id:"double-curve",name:"Double Curve",points:3,draw:t=>{if(t.pts.length<3)return;const[e,i,n]=t.pts;g(t),t.ctx.beginPath(),t.ctx.moveTo(e.x,e.y),t.ctx.bezierCurveTo(i.x,i.y,e.x+n.x-i.x,e.y+n.y-i.y,n.x,n.y),t.ctx.stroke(),t.ctx.setLineDash([])},distance:(t,e,i)=>{if(i.pts.length<3)return null;const[n,o,l]=i.pts;return s(t,e,function(t,e,i,n,s){const o=[];for(let l=0;l<=s;l++){const r=l/s,a=1-r,c=a*a*a,h=3*a*a*r,x=3*a*r*r,d=r*r*r;o.push({x:c*t.x+h*e.x+x*i.x+d*n.x,y:c*t.y+h*e.y+x*i.y+d*n.y})}return o}(n,o,{x:n.x+l.x-o.x,y:n.y+l.y-o.y},l,24))}};const lt={id:"cyclic-lines",name:"Cyclic Lines",points:2,defaultStyle:{lineStyle:"dashed"},draw:t=>{const[e,i]=t.pts,n=i.x-e.x;if(!Number.isFinite(n)||Math.abs(n)<.5)return;const s=t.rc.plotHeight*t.rc.dpr,o=t.rc.plotWidth*t.rc.dpr;g(t),t.ctx.beginPath();for(let i=0;i<=12;i++){const l=Math.round(e.x+n*i)+.5;l<0||l>o||(t.ctx.moveTo(l,0),t.ctx.lineTo(l,s))}t.ctx.stroke(),t.ctx.setLineDash([])},distance:(t,e,i)=>{const n=i.pts[1].x-i.pts[0].x;if(!Number.isFinite(n)||Math.abs(n)<.5)return null;const s=Math.round((t-i.pts[0].x)/n);return s<0||s>12?null:Math.abs(t-(i.pts[0].x+n*s))}},rt={id:"time-cycles",name:"Time Cycles",points:2,draw:t=>{const[e,i]=t.pts,n=i.x-e.x;if(!Number.isFinite(n)||Math.abs(n)<1)return;const s=Math.abs(n)/2;g(t),t.ctx.beginPath();for(let i=0;i<12;i++){const o=e.x+n*i+n/2;o+s<0||o-s>t.rc.plotWidth*t.rc.dpr||(t.ctx.moveTo(o+s,e.y),t.ctx.arc(o,e.y,s,0,Math.PI,!0))}t.ctx.stroke(),t.ctx.setLineDash([])},distance:(t,e,i)=>{const[n,s]=i.pts,o=s.x-n.x;if(!Number.isFinite(o)||Math.abs(o)<1)return null;const l=Math.abs(o)/2;let r=1/0;for(let i=0;i<12;i++){const s=n.x+o*i+o/2;e>n.y+2||(r=Math.min(r,Math.abs(Math.hypot(t-s,e-n.y)-l)))}return Number.isFinite(r)?r:null}},at={id:"sine-line",name:"Sine Line",points:2,draw:t=>{const e=ct(t.pts[0],t.pts[1]);if(null!==e){g(t),t.ctx.beginPath(),t.ctx.moveTo(e[0].x,e[0].y);for(let i=1;i<e.length;i++)t.ctx.lineTo(e[i].x,e[i].y);t.ctx.stroke(),t.ctx.setLineDash([])}},distance:(t,e,i)=>{const n=ct(i.pts[0],i.pts[1]);return null===n?null:s(t,e,n)}};function ct(t,e){const i=e.x-t.x,n=e.y-t.y;if(!Number.isFinite(i)||Math.abs(i)<1)return null;const s=[];for(let e=0;e<=64;e++){const o=e/64;s.push({x:t.x+i*o,y:t.y+n*Math.sin(o*Math.PI*2)})}return s}const ht={id:"price-label",name:"Price Label",points:1,defaultStyle:{fontSize:12},draw:t=>{const e=t.pts[0],i=t.rc.dpr,n=void 0!==t.style.text&&""!==t.style.text?t.style.text:t.formatPrice(t.drawing.points[0].price),s=dt(t,[n],e.x+18*i,e.y-30*i);pt(t,s,e,t.style.color),yt(t,s,[n],t.style.color)},distance:(t,e,i)=>{const n=i.pts[0],s=n.x+18,o=n.y-30-11;return t>=s&&t<=s+64&&e>=o&&e<=o+22||Math.hypot(t-n.x,e-n.y)<=10?0:null}},xt={id:"callout",name:"Callout",points:2,defaultStyle:{fontSize:12,text:"Note"},draw:t=>{if(t.pts.length<2)return;const[e,i]=t.pts,n=(t.style.text??"Note").split("\n"),s=dt(t,n,i.x,i.y);pt(t,s,e,t.style.color),yt(t,s,n,t.style.color)},distance:(e,i,n)=>{if(n.pts.length<2)return null;const[s,o]=n.pts;return Math.abs(e-o.x)<=60&&Math.abs(i-o.y)<=16?0:t(e,i,s,o)}};function dt(t,e,i,n){const s=t.rc.dpr,o=(t.style.fontSize??12)*s;t.ctx.save(),t.ctx.font=`${o}px ui-sans-serif, system-ui, sans-serif`;let l=0;for(const i of e)l=Math.max(l,t.ctx.measureText(i).width);t.ctx.restore();const r=l+14*s,a=1.4*o*e.length+8*s;return{x:i-r/2,y:n-a/2,w:r,h:a}}function pt(t,e,i,n){const s=t.rc.dpr,o=e.x+e.w/2,l=e.y+e.h/2,r=Math.atan2(i.y-l,i.x-o),a=5*s,c=o+Math.cos(r)*(e.w/2-a),h=l+Math.sin(r)*(e.h/2-a);t.ctx.save(),t.ctx.setLineDash([]),t.ctx.fillStyle=n,t.ctx.beginPath(),t.ctx.moveTo(i.x,i.y),t.ctx.lineTo(c-Math.sin(r)*a,h+Math.cos(r)*a),t.ctx.lineTo(c+Math.sin(r)*a,h-Math.cos(r)*a),t.ctx.closePath(),t.ctx.fill(),t.ctx.beginPath(),x(t.ctx,e.x,e.y,e.w,e.h,5*s),t.ctx.fill(),t.ctx.beginPath(),t.ctx.arc(i.x,i.y,2.5*s,0,2*Math.PI),t.ctx.fill(),t.ctx.restore()}function yt(t,e,i,n){const s=t.rc.dpr,o=(t.style.fontSize??12)*s;t.ctx.save(),t.ctx.setLineDash([]),t.ctx.font=`${o}px ui-sans-serif, system-ui, sans-serif`,t.ctx.textAlign="center",t.ctx.textBaseline="middle",t.ctx.fillStyle=t.style.fontColor??h(n);const l=1.4*o,r=e.y+e.h/2-l*(i.length-1)/2;for(let n=0;n<i.length;n++)t.ctx.fillText(i[n],e.x+e.w/2,r+l*n);t.ctx.restore()}const ut={id:"flag-mark",name:"Flag Mark",points:1,defaultStyle:{fill:!0,fillOpacity:.95},draw:t=>{const e=t.pts[0],i=t.rc.dpr,n=22*i,s=15*i,o=11*i;g(t),t.ctx.beginPath(),t.ctx.moveTo(e.x,e.y),t.ctx.lineTo(e.x,e.y-n),t.ctx.stroke(),t.ctx.setLineDash([]),t.ctx.beginPath(),t.ctx.moveTo(e.x,e.y-n),t.ctx.lineTo(e.x+s,e.y-n+.28*o),t.ctx.lineTo(e.x+.72*s,e.y-n+.5*o),t.ctx.lineTo(e.x+s,e.y-n+.72*o),t.ctx.lineTo(e.x,e.y-n+o),t.ctx.closePath(),t.ctx.save(),t.ctx.globalAlpha=t.style.fillOpacity??.95,t.ctx.fillStyle=m(t),t.ctx.fill(),t.ctx.restore()},distance:(t,e,i)=>{const n=i.pts[0];return t>=n.x-4&&t<=n.x+16&&e>=n.y-24&&e<=n.y+2||Math.hypot(t-n.x,e-n.y)<=8?0:null}},ft={id:"price-range",name:"Price Range",points:2,defaultStyle:{fill:!0,showLabels:!0,fillOpacity:.1},draw:t=>{const e=t.rc.dpr,i=t.drawing.points,n=i[1].price-i[0].price,s=0!==i[0].price?n/i[0].price*100:0,o=n>=0,l=o?"#26a69a":"#ef5350",r=Math.min(t.pts[0].x,t.pts[1].x),a=Math.max(t.pts[0].x,t.pts[1].x)+(t.pts[0].x===t.pts[1].x?60*e:0),c=t.pts[0].y,h=t.pts[1].y;t.ctx.save(),t.ctx.globalAlpha=t.style.fillOpacity??.1,t.ctx.fillStyle=l,t.ctx.fillRect(r,Math.min(c,h),a-r,Math.abs(h-c)),t.ctx.restore(),g(t),t.ctx.strokeStyle=l,t.ctx.beginPath();for(const e of[c,h])t.ctx.moveTo(r,Math.round(e)+.5),t.ctx.lineTo(a,Math.round(e)+.5);const x=(r+a)/2;t.ctx.moveTo(x,c),t.ctx.lineTo(x,h);const d=h>c?1:-1;t.ctx.moveTo(x-4*e,h-5*e*d),t.ctx.lineTo(x,h),t.ctx.lineTo(x+4*e,h-5*e*d),t.ctx.moveTo(x-4*e,c+5*e*d),t.ctx.lineTo(x,c),t.ctx.lineTo(x+4*e,c+5*e*d),t.ctx.stroke(),t.ctx.setLineDash([]);const p=o?"+":"";_(t,`${p}${t.formatPrice(n)} (${p}${s.toFixed(2)}%)`,x+6*e,(c+h)/2,l)},distance:(t,e,i)=>l(t,e,i.pts[0],i.pts[1],!0)},gt={id:"date-range",name:"Date Range",points:2,defaultStyle:{fill:!0,showLabels:!0,fillOpacity:.1},draw:t=>{const e=t.rc.dpr,i=t.drawing.points,n=t.style.color,s=t.pts[0].x,o=t.pts[1].x,l=Math.min(t.pts[0].y,t.pts[1].y),r=Math.max(t.pts[0].y,t.pts[1].y)+(t.pts[0].y===t.pts[1].y?40*e:0);t.ctx.save(),t.ctx.globalAlpha=t.style.fillOpacity??.1,t.ctx.fillStyle=n,t.ctx.fillRect(Math.min(s,o),l,Math.abs(o-s),r-l),t.ctx.restore(),g(t),t.ctx.beginPath();for(const e of[s,o])t.ctx.moveTo(Math.round(e)+.5,l),t.ctx.lineTo(Math.round(e)+.5,r);const a=(l+r)/2;t.ctx.moveTo(s,a),t.ctx.lineTo(o,a);const c=o>s?1:-1;t.ctx.moveTo(o-5*e*c,a-4*e),t.ctx.lineTo(o,a),t.ctx.lineTo(o-5*e*c,a+4*e),t.ctx.moveTo(s+5*e*c,a-4*e),t.ctx.lineTo(s,a),t.ctx.lineTo(s+5*e*c,a+4*e),t.ctx.stroke(),t.ctx.setLineDash([]);const h=t.rc.dataLayer.timeToIndexFloat(i[0].time),x=t.rc.dataLayer.timeToIndexFloat(i[1].time);_(t,`${Math.abs(Math.round(x-h))} bars`,(s+o)/2,l-10*e,n)},distance:(t,e,i)=>l(t,e,i.pts[0],i.pts[1],!0)},mt={id:"forecast",name:"Forecast",points:2,defaultStyle:{fill:!0,showLabels:!0,fillOpacity:.12,lineStyle:"dashed"},draw:t=>{const e=t.rc.dpr,i=t.drawing.points,[n,s]=t.pts,o=i[1].price-i[0].price,l=0!==i[0].price?o/i[0].price*100:0,r=o>=0,a=r?"#26a69a":"#ef5350",c=.35*Math.abs(s.y-n.y)+6*e;if(t.ctx.save(),t.ctx.globalAlpha=t.style.fillOpacity??.12,t.ctx.fillStyle=a,t.ctx.beginPath(),t.ctx.moveTo(n.x,n.y),t.ctx.lineTo(s.x,s.y-c),t.ctx.lineTo(s.x,s.y+c),t.ctx.closePath(),t.ctx.fill(),t.ctx.restore(),g(t),t.ctx.strokeStyle=a,t.ctx.beginPath(),t.ctx.moveTo(n.x,n.y),t.ctx.lineTo(s.x,s.y),t.ctx.stroke(),t.ctx.setLineDash([]),t.ctx.beginPath(),t.ctx.arc(n.x,n.y,3*e,0,2*Math.PI),t.ctx.fillStyle=a,t.ctx.fill(),!1===t.style.showLabels)return;const h=r?"+":"";w(t,[t.formatPrice(i[0].price),v(i[0].time)],n.x,n.y,a,{align:"center"}),w(t,[`${h}${t.formatPrice(o)} (${h}${l.toFixed(2)}%) in ${T(i[1].time-i[0].time)}`,`${t.formatPrice(i[1].price)} · ${v(i[1].time)}`],s.x,s.y,a,{align:"center",place:"below"});const x=t.rc.bars?.();if(void 0!==x&&x.length>0&&x[x.length-1].time>=i[1].time){let n=!1;for(const t of x)if(!(t.time<i[0].time)){if(t.time>i[1].time)break;if(r?t.high>=i[1].price:t.low<=i[1].price){n=!0;break}}w(t,[n?"SUCCESS":"MISSED"],s.x,s.y+36*e,n?"#4a934a":"#8a4a4a",{align:"center",place:"below"})}},distance:(e,i,n)=>t(e,i,n.pts[0],n.pts[1])},bt={id:"circle",name:"Circle",points:2,defaultStyle:{fill:!0},draw:t=>{const[e,i]=t.pts,n=Math.hypot(i.x-e.x,i.y-e.y);t.ctx.beginPath(),t.ctx.arc(e.x,e.y,n,0,2*Math.PI),b(t,()=>t.ctx.fill()),g(t),t.ctx.stroke(),t.ctx.setLineDash([])},distance:(t,e,i)=>{const[n,s]=i.pts,o=Math.hypot(s.x-n.x,s.y-n.y),l=Math.hypot(t-n.x,e-n.y);return!0===i.drawing.style.fill&&l<=o?0:Math.abs(l-o)}},_t={id:"triangle",name:"Triangle",points:3,defaultStyle:{fill:!0},draw:t=>{t.ctx.beginPath(),t.ctx.moveTo(t.pts[0].x,t.pts[0].y),t.ctx.lineTo(t.pts[1].x,t.pts[1].y),t.ctx.lineTo(t.pts[2].x,t.pts[2].y),t.ctx.closePath(),b(t,()=>t.ctx.fill()),g(t),t.ctx.stroke(),t.ctx.setLineDash([])},distance:(t,e,i)=>s(t,e,[...i.pts,i.pts[0]])},wt={id:"polyline",name:"Polyline",points:0,defaultStyle:{fill:!1},draw:t=>{if(!(t.pts.length<2)){t.ctx.beginPath(),t.ctx.moveTo(t.pts[0].x,t.pts[0].y);for(let e=1;e<t.pts.length;e++)t.ctx.lineTo(t.pts[e].x,t.pts[e].y);!0===t.style.fill&&(t.ctx.closePath(),b(t,()=>t.ctx.fill())),g(t),t.ctx.stroke(),t.ctx.setLineDash([])}},distance:(t,e,i)=>s(t,e,i.pts)};const Mt={id:"arc",name:"Arc",points:3,draw:t=>{const[e,i,n]=t.pts;g(t),t.ctx.beginPath(),t.ctx.moveTo(e.x,e.y),t.ctx.quadraticCurveTo(2*i.x-(e.x+n.x)/2,2*i.y-(e.y+n.y)/2,n.x,n.y),t.ctx.stroke(),t.ctx.setLineDash([])},distance:(t,e,i)=>s(t,e,function(t,e,i){const n=2*e.x-(t.x+i.x)/2,s=2*e.y-(t.y+i.y)/2,o=[];for(let e=0;e<=16;e++){const l=e/16,r=1-l;o.push({x:r*r*t.x+2*r*l*n+l*l*i.x,y:r*r*t.y+2*r*l*s+l*l*i.y})}return o}(i.pts[0],i.pts[1],i.pts[2]))},vt={id:"curve",name:"Curve",points:3,draw:t=>{const[e,i,n]=t.pts;g(t),t.ctx.beginPath(),t.ctx.moveTo(e.x,e.y),t.ctx.quadraticCurveTo(i.x,i.y,n.x,n.y),t.ctx.stroke(),t.ctx.setLineDash([])},distance:(t,e,i)=>{const[n,o,l]=i.pts,r=[];for(let t=0;t<=16;t++){const e=t/16,i=1-e;r.push({x:i*i*n.x+2*i*e*o.x+e*e*l.x,y:i*i*n.y+2*i*e*o.y+e*e*l.y})}return s(t,e,r)}};function Tt(t,e,i){return{id:t,name:e,points:1,defaultStyle:{fill:!0,fillOpacity:.9},draw:t=>{const e=t.rc.dpr,{x:n,y:s}=t.pts[0],o=16*e,l=6*e,r=i?1:-1,a=s+2*r*e;t.ctx.beginPath(),t.ctx.moveTo(n,a),t.ctx.lineTo(n-l,a+r*l),t.ctx.lineTo(n-l/2.4,a+r*l),t.ctx.lineTo(n-l/2.4,a+r*o),t.ctx.lineTo(n+l/2.4,a+r*o),t.ctx.lineTo(n+l/2.4,a+r*l),t.ctx.lineTo(n+l,a+r*l),t.ctx.closePath(),t.ctx.save(),t.ctx.globalAlpha=t.style.fillOpacity??.9,t.ctx.fillStyle=m(t),t.ctx.fill(),t.ctx.restore(),g(t),t.ctx.stroke(),t.ctx.setLineDash([])},distance:(t,e,n)=>{const s=n.pts[0],o=i?e-s.y:s.y-e;return Math.abs(t-s.x)<=8&&o>=-4&&o<=20?0:null}}}const St=Tt("arrow-up","Arrow Up",!0),Pt=Tt("arrow-down","Arrow Down",!1),Lt={id:"highlighter",name:"Highlighter",points:0,freehand:!0,defaultStyle:{lineWidth:12,fillOpacity:.28},draw:t=>{if(t.pts.length<2)return;const e=t.rc.dpr;t.ctx.save(),t.ctx.globalAlpha=t.style.fillOpacity??.28,t.ctx.strokeStyle=t.style.color,t.ctx.lineWidth=Math.max(2,(t.style.lineWidth||12)*e),t.ctx.lineCap="round",t.ctx.lineJoin="round",t.ctx.beginPath(),t.ctx.moveTo(t.pts[0].x,t.pts[0].y);for(let e=1;e<t.pts.length;e++)t.ctx.lineTo(t.pts[e].x,t.pts[e].y);t.ctx.stroke(),t.ctx.restore()},distance:(t,e,i)=>{const n=s(t,e,i.pts);return n<=Math.max(6,(i.drawing.style.lineWidth??12)/2)?0:n}},kt={id:"fib-channel",name:"Fib Channel",points:3,defaultStyle:{showLabels:!0,levels:[...L]},draw:t=>{const e=t.style.levels??L,[i,n,s]=t.pts,o=s.x-n.x,l=s.y-n.y;g(t);for(const s of e)t.ctx.beginPath(),t.ctx.moveTo(i.x+o*s,i.y+l*s),t.ctx.lineTo(n.x+o*s,n.y+l*s),t.ctx.stroke(),!1!==t.style.showLabels&&_(t,`${(100*s).toFixed(1)}%`,n.x+o*s+4*t.rc.dpr,n.y+l*s);t.ctx.setLineDash([])},distance:(e,i,n)=>{const s=n.drawing.style.levels??L,[o,l,r]=n.pts;let a=1/0;for(const n of s){const s=t(e,i,{x:o.x+(r.x-l.x)*n,y:o.y+(r.y-l.y)*n},{x:l.x+(r.x-l.x)*n,y:l.y+(r.y-l.y)*n});s<a&&(a=s)}return a}},Dt=[0,1,2,3,5,8,13,21,34,55],$t={id:"fib-time-zone",name:"Fib Time Zone",points:2,defaultStyle:{showLabels:!0},draw:t=>{const[e,i]=t.pts,n=i.x-e.x;if(Math.abs(n)<.5)return;const s=t.rc.dpr,o=t.rc.plotWidth*s;g(t);for(const i of Dt){const l=e.x+n*i;l<-10||l>o+10||(t.ctx.beginPath(),t.ctx.moveTo(Math.round(l)+.5,0),t.ctx.lineTo(Math.round(l)+.5,t.rc.plotHeight*s),t.ctx.stroke(),!1!==t.style.showLabels&&_(t,String(i),l+3*s,12*s))}t.ctx.setLineDash([])},distance:(t,e,i)=>{const[n,s]=i.pts,o=s.x-n.x;if(Math.abs(o)<.5)return null;let l=1/0;for(const e of Dt)l=Math.min(l,Math.abs(t-(n.x+o*e)));return l}},Ot=[.236,.382,.5,.618,.786,1],Ft={id:"fib-fan",name:"Fib Speed Fan",points:2,defaultStyle:{showLabels:!0,levels:[...Ot]},draw:t=>{const e=t.style.levels??Ot,[i,n]=t.pts,s=t.rc.dpr,o=t.rc.plotWidth*s;g(t);for(const l of e){const e=a(i,{x:n.x,y:i.y+(n.y-i.y)*l},o,!1,!0)[1];t.ctx.beginPath(),t.ctx.moveTo(i.x,i.y),t.ctx.lineTo(e.x,e.y),t.ctx.stroke(),!1!==t.style.showLabels&&_(t,`${(100*l).toFixed(1)}%`,n.x+4*s,i.y+(n.y-i.y)*l)}t.ctx.setLineDash([])},distance:(e,i,n)=>{const s=n.drawing.style.levels??Ot,[o,l]=n.pts;let r=1/0;for(const c of s)r=Math.min(r,t(e,i,o,a(o,{x:l.x,y:o.y+(l.y-o.y)*c},n.rc.plotWidth,!1,!0)[1]));return r}},At=[[1,.125],[1,.25],[1,.5],[1,1],[.5,1],[.25,1],[.125,1]],Nt=[D,$,O,F,A,N,W,C,I,R,z,U,B,E,Y,mt,H,ft,gt,bt,_t,wt,Mt,vt,nt,ot,St,Pt,Lt,it,kt,$t,Ft,{id:"gann-fan",name:"Gann Fan",points:2,defaultStyle:{showLabels:!0},draw:t=>{const[e,i]=t.pts,n=t.rc.dpr,s=t.rc.plotWidth*n,o=i.x-e.x,l=i.y-e.y;if(!(Math.abs(o)<.5)){g(t);for(const[i,n]of At){const r=a(e,{x:e.x+o*i,y:e.y+l*n},s,!1,!0)[1];t.ctx.beginPath(),t.ctx.moveTo(e.x,e.y),t.ctx.lineTo(r.x,r.y),t.ctx.stroke()}!1!==t.style.showLabels&&_(t,"1x1",i.x+4*n,i.y),t.ctx.setLineDash([])}},distance:(e,i,n)=>{const[s,o]=n.pts,l=o.x-s.x,r=o.y-s.y;let c=1/0;for(const[o,h]of At)c=Math.min(c,t(e,i,s,a(s,{x:s.x+l*o,y:s.y+r*h},n.rc.plotWidth,!1,!0)[1]));return c}},{id:"gann-box",name:"Gann Box",points:2,defaultStyle:{fill:!0,fillOpacity:.05},draw:t=>{const e=o(t.pts[0],t.pts[1]);b(t,()=>t.ctx.fillRect(e.x0,e.y0,e.x1-e.x0,e.y1-e.y0)),g(t);const i=e.x1-e.x0,n=e.y1-e.y0;t.ctx.beginPath();for(let s=0;s<=8;s++){const o=Math.round(e.x0+i*s/8)+.5,l=Math.round(e.y0+n*s/8)+.5;t.ctx.moveTo(o,e.y0),t.ctx.lineTo(o,e.y1),t.ctx.moveTo(e.x0,l),t.ctx.lineTo(e.x1,l)}t.ctx.moveTo(e.x0,e.y1),t.ctx.lineTo(e.x1,e.y0),t.ctx.stroke(),t.ctx.setLineDash([])},distance:(t,e,i)=>l(t,e,i.pts[0],i.pts[1],!0===i.drawing.style.fill)},lt,rt,at,K,et,ht,xt,ut];let Wt=!1;function Ct(){if(!Wt){Wt=!0;for(const t of Nt)p(t)}}function It(t,e){return u(t)&&!0===y(t).freehand&&e>2?[0,e-1]:Array.from({length:e},(t,e)=>e)}class Rt{constructor(){Object.defineProperty(this,"_drawings",{enumerable:!0,configurable:!0,writable:!0,value:[]}),Object.defineProperty(this,"_host",{enumerable:!0,configurable:!0,writable:!0,value:null}),Object.defineProperty(this,"_selected",{enumerable:!0,configurable:!0,writable:!0,value:null}),Object.defineProperty(this,"_preview",{enumerable:!0,configurable:!0,writable:!0,value:null})}attached(t){this._host=t}detached(){this._host=null}zOrder(){return"top"}autoscaleInfo(){return null}setDrawings(t){this._drawings=t.slice(),this._host?.requestUpdate()}setSelected(t){t!==this._selected&&(this._selected=t,this._host?.requestUpdate())}setPreview(t){this._preview=t,this._host?.requestUpdate()}_project(t,e,i){return{x:t.timeScale.indexToX(t.dataLayer.timeToIndexFloat(e)),y:t.priceScale.priceToY(i)}}_points(t,e){return e.points.map(e=>this._project(t,e.time,e.price))}draw(t,e){const i=null===this._preview?this._drawings:[...this._drawings,this._preview];for(const n of i){if(!1===n.visible||!u(n.tool))continue;const i=y(n.tool);if(n.points.length<Math.max(1,i.points))continue;const s=this._points(e,n);if(!s.some(t=>Number.isFinite(t.x)&&Number.isFinite(t.y)))continue;const o={color:n.style.color??e.theme.lineColor,lineWidth:n.style.lineWidth??1.5,...n.style},l=e.dpr;t.save(),n===this._preview&&(t.globalAlpha=.7),i.draw({ctx:t,rc:e,drawing:n,selected:n.id===this._selected,pts:s.map(t=>({x:t.x*l,y:t.y*l})),style:{...o,color:o.color,lineWidth:o.lineWidth},formatPrice:t=>e.priceScale.format(t)}),t.restore(),n.id===this._selected&&!0!==n.locked&&this._drawHandles(t,e,s,n.tool)}}_drawHandles(t,e,i,n){const s=e.dpr;t.save(),t.setLineDash([]),t.lineWidth=Math.max(1,Math.round(1.5*s));for(const o of It(n,i.length)){const n=i[o];t.beginPath(),t.arc(n.x*s,n.y*s,5*s,0,2*Math.PI),t.fillStyle=e.theme.background,t.fill(),t.strokeStyle=e.theme.lineColor,t.stroke()}t.restore()}hitTest(t,e,i){if(null!==this._selected){const n=this._drawings.find(t=>t.id===this._selected);if(void 0!==n&&!0!==n.locked){const s=this._points(i,n);for(const i of It(n.tool,s.length))if(Math.hypot(t-s[i].x,e-s[i].y)<=7)return{externalId:`draw:${n.id}#${i}`,zOrder:"top",distance:0,cursor:"grabbing",draggable:!0}}}let n=null;for(let s=this._drawings.length-1;s>=0;s--){const o=this._drawings[s];if(!1===o.visible||!0===o.locked||!u(o.tool))continue;const l=y(o.tool);if(o.points.length<Math.max(1,l.points))continue;const r=l.distance(t,e,{pts:this._points(i,o),drawing:o,rc:i});null===r||!Number.isFinite(r)||r>6||(null===n||r<n.distance)&&(n={id:o.id,distance:r})}return null===n?null:{externalId:`draw:${n.id}`,zOrder:"top",distance:n.distance,cursor:"move",draggable:!0}}}let zt=1;class jt{constructor(t,e={}){Object.defineProperty(this,"_chart",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"_opts",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"_layers",{enumerable:!0,configurable:!0,writable:!0,value:new Map}),Object.defineProperty(this,"_drawings",{enumerable:!0,configurable:!0,writable:!0,value:[]}),Object.defineProperty(this,"_tool",{enumerable:!0,configurable:!0,writable:!0,value:null}),Object.defineProperty(this,"_pending",{enumerable:!0,configurable:!0,writable:!0,value:[]}),Object.defineProperty(this,"_pendingPane",{enumerable:!0,configurable:!0,writable:!0,value:0}),Object.defineProperty(this,"_selected",{enumerable:!0,configurable:!0,writable:!0,value:null}),Object.defineProperty(this,"_undo",{enumerable:!0,configurable:!0,writable:!0,value:[]}),Object.defineProperty(this,"_redo",{enumerable:!0,configurable:!0,writable:!0,value:[]}),Object.defineProperty(this,"_dragStart",{enumerable:!0,configurable:!0,writable:!0,value:null}),Object.defineProperty(this,"_off",{enumerable:!0,configurable:!0,writable:!0,value:[]}),Object.defineProperty(this,"_lastCursor",{enumerable:!0,configurable:!0,writable:!0,value:null}),Object.defineProperty(this,"_lastBar",{enumerable:!0,configurable:!0,writable:!0,value:null}),this._chart=t,this._opts={magnet:e.magnet??!1,stayInDrawingMode:e.stayInDrawingMode??!1,historyLimit:e.historyLimit??50,defaultStyle:e.defaultStyle??{}},this._off.push(t.on("click",t=>this._onClick(t))),this._off.push(t.on("crosshair:move",t=>this._onCrosshair(t))),this._off.push(t.on("drag",t=>this._onDrag(t))),this._off.push(t.on("drag:end",()=>this._onDragEnd())),this._off.push(t.on("dblclick",()=>{this.finish()}));const i=t.drawingState();Array.isArray(i)&&(this._drawings=i.map(t=>({...t}))),this._sync()}setTool(t){if(null!==t&&!u(t))throw new Error(`openalgo-charts: unknown drawing tool "${t}"`);this._tool=t,this._pending=[],this._setPlacementMode(null!==t),this._syncPreview(),this._chart.emit("draw:tool",{tool:t})}_setPlacementMode(t){const e=this._chart;e.setPlacementMode?.(t)}activeTool(){return this._tool}setOptions(t){this._opts={...this._opts,...t,defaultStyle:t.defaultStyle??this._opts.defaultStyle}}drawings(){return this._drawings}get(t){return this._drawings.find(e=>e.id===t)}add(t){this._pushUndo();const e=y(t.tool),i={...t,id:t.id??"d"+zt++,style:{...this._opts.defaultStyle,...e.defaultStyle,...t.style}};return this._drawings.push(i),this._sync(),this._chart.emit("draw:add",{drawing:i}),i}update(t,e){const i=this.get(t);return void 0!==i&&(this._pushUndo(),void 0!==e.points&&(i.points=e.points.map(t=>({...t}))),void 0!==e.style&&(i.style={...i.style,...e.style}),void 0!==e.locked&&(i.locked=e.locked),void 0!==e.visible&&(i.visible=e.visible),this._sync(),this._chart.emit("draw:update",{drawing:i}),!0)}remove(t){const e=this._drawings.findIndex(e=>e.id===t);if(e<0)return!1;this._pushUndo();const[i]=this._drawings.splice(e,1);return this._selected===t&&(this._selected=null),this._sync(),this._chart.emit("draw:remove",{drawing:i}),!0}clear(){0!==this._drawings.length&&(this._pushUndo(),this._drawings=[],this._selected=null,this._sync())}select(t){this._selected=t;for(const e of this._layers.values())e.setSelected(t);this._chart.emit("draw:select",{id:t})}selected(){return this._selected}undo(){const t=this._undo.pop();return void 0!==t&&(this._redo.push(JSON.stringify(this._drawings)),this._drawings=JSON.parse(t),this._drawings.some(t=>t.id===this._selected)||(this._selected=null),this._sync(),!0)}redo(){const t=this._redo.pop();return void 0!==t&&(this._undo.push(JSON.stringify(this._drawings)),this._drawings=JSON.parse(t),this._sync(),!0)}canUndo(){return this._undo.length>0}canRedo(){return this._redo.length>0}toJSON(){return this._drawings.map(t=>({...t,points:t.points.map(t=>({...t})),style:{...t.style}}))}fromJSON(t){this._drawings=Array.isArray(t)?t.map(t=>({...t})):[],this._selected=null,this._undo=[],this._redo=[],this._sync()}destroy(){this._setPlacementMode(!1);for(const t of this._off)t();this._off.length=0;for(const[t,e]of this._layers)this._chart.removePrimitive(e);this._layers.clear()}_onCrosshair(t){const e=t.time,i=t.price,n=t.paneIndex??null;this._lastCursor=null===e||null===i||null===n?null:{time:e,price:i,paneIndex:n},this._lastBar=t.bar??null,null!==this._tool&&!0===t.pressed&&this._isFreehand()&&null!==e&&null!==i&&null!==n&&Number.isFinite(e)&&Number.isFinite(i)?this._inkPoint({time:e,price:i},n):null!==this._tool&&this._pending.length>0&&this._syncPreview()}_expand(t,e){if(void 0===t.expand)return e;const i=this._chart.dataLayer,n=i.baseIndex,s=n>0?i.indexToTime(n-1):void 0,o=n>=0?i.indexToTime(n):void 0,l=void 0!==s&&void 0!==o&&o>s?o-s:60,r=this._chart.getVisibleLogicalRange(),a=null===r?60:Math.max(1,r.to-r.from);return t.expand(e,{barSeconds:l,visibleBars:a})}_isFreehand(){return null!==this._tool&&!0===y(this._tool).freehand}_inkPoint(t,e){if(0===this._pending.length)this._pendingPane=e;else{if(e!==this._pendingPane)return;{const e=this._pending[this._pending.length-1];if(e.time===t.time&&e.price===t.price)return}}this._pending.push(t),this._syncPreview()}_commit(t){const e=y(this._tool),i=this.add({tool:e.id,points:t,style:{},paneIndex:this._pendingPane});this._pending=[],this._opts.stayInDrawingMode||(this._tool=null,this._setPlacementMode(!1)),this._syncPreview(),this.select(i.id),this._chart.emit("draw:tool",{tool:this._tool})}_finishFreehand(){const t=this._pending;this._pending=[],t.length<2?this._syncPreview():this._commit(t)}finish(){if(null===this._tool||0===this._pending.length)return!1;const t=y(this._tool);if(0!==t.points||!0===t.freehand)return!1;const e=this._pending;return e.length<2?(this._pending=[],this._syncPreview(),!1):(this._commit(e),!0)}_onClick(t){if(null===this._tool)null!==t.id&&t.id.startsWith("draw:")?this.select(t.id.slice(5).split("#")[0]):null===t.id&&this.select(null);else{if(this._isFreehand())return void(!0===t.viaDrag&&this._finishFreehand());if(!0===t.viaDrag&&0===this._pending.length)return;if(null===t.price||!Number.isFinite(t.price)||!Number.isFinite(t.time))return;this._placePoint({time:t.time,price:this._snap(t.price,t.paneIndex)},t.paneIndex)}}_placePoint(t,e){0===this._pending.length&&(this._pendingPane=e),this._pending.push(t);const i=y(this._tool);i.points>0&&this._pending.length>=i.points?this._commit(this._expand(i,this._pending)):this._syncPreview()}_snap(t,e){if(!this._opts.magnet||0!==e)return t;const i=this._lastBar;if(null===i)return t;let n=t,s=1/0;for(const e of[i.open,i.high,i.low,i.close]){const i=Math.abs(e-t);i<s&&(s=i,n=e)}return n}_onDrag(t){if(!t.id.startsWith("draw:"))return;const[e,i]=t.id.slice(5).split("#"),n=this.get(e);if(void 0===n||!0===n.locked)return;const s=void 0===i?null:Number(i);null!==this._dragStart&&this._dragStart.id===e&&this._dragStart.handle===s||(this._pushUndo(),this._dragStart={id:e,handle:s,points:n.points.map(t=>({...t})),from:{time:t.fromTime??t.time,price:t.fromPrice??t.price}});const o=this._dragStart;if(null===s){const e=t.time-o.from.time,i=t.price-o.from.price;n.points=o.points.map(t=>({time:t.time+e,price:t.price+i}))}else s>=0&&s<n.points.length&&(n.points=o.points.map((e,i)=>i===s?{time:t.time,price:t.price}:{...e}));this._sync()}_onDragEnd(){if(null===this._dragStart)return;const t=this.get(this._dragStart.id);this._dragStart=null,void 0!==t&&this._chart.emit("draw:update",{drawing:t})}_layerFor(t){let e=this._layers.get(t);return void 0===e&&(e=new Rt,this._chart.addPrimitive(e,t),this._layers.set(t,e)),e}_sync(){const t=new Map;for(const e of this._drawings){const i=t.get(e.paneIndex)??[];i.push(e),t.set(e.paneIndex,i)}for(const[e,i]of t)this._layerFor(e).setDrawings(i);for(const[e,i]of this._layers)t.has(e)||i.setDrawings([]),i.setSelected(this._selected);this._chart.setDrawingState(this.toJSON())}_syncPreview(){for(const t of this._layers.values())t.setPreview(null);if(null===this._tool||0===this._pending.length)return;const t=this._lastCursor,e=null===t?this._pending:[...this._pending,{time:t.time,price:t.price}];this._layerFor(this._pendingPane).setPreview({id:"__preview",tool:this._tool,points:e,style:this._opts.defaultStyle,paneIndex:this._pendingPane})}_pushUndo(){this._undo.push(JSON.stringify(this._drawings)),this._undo.length>this._opts.historyLimit&&this._undo.shift(),this._redo=[]}}const Ut="draw";Ct();export{F as ARROW,Nt as BUILTIN_DRAWING_TOOLS,C as CROSS_LINE,Ut as DRAW_TIER,jt as DrawingController,Rt as DrawingLayer,R as ELLIPSE,O as EXTENDED_LINE,B as FIB_EXTENSION,U as FIB_RETRACEMENT,A as HORIZONTAL_LINE,N as HORIZONTAL_RAY,E as LONG_POSITION,H as MEASURE,z as PARALLEL_CHANNEL,et as PATH,$ as RAY,I as RECTANGLE,Y as SHORT_POSITION,K as TEXT,D as TREND_LINE,W as VERTICAL_LINE,r as distToEllipse,e as distToLine,s as distToPolyline,l as distToRect,t as distToSegment,a as extendSegment,y as getDrawingTool,u as hasDrawingTool,o as rectOf,Ct as registerBuiltinDrawingTools,p as registerDrawingTool,f as registeredDrawingTools};
|
|
1
|
+
function t(t,e,i,n){const s=n.x-i.x,o=n.y-i.y,l=s*s+o*o;if(0===l)return Math.hypot(t-i.x,e-i.y);let r=((t-i.x)*s+(e-i.y)*o)/l;return r=r<0?0:r>1?1:r,Math.hypot(t-(i.x+r*s),e-(i.y+r*o))}function e(t,e,i,n){const s=n.x-i.x,o=n.y-i.y,l=Math.hypot(s,o);return 0===l?Math.hypot(t-i.x,e-i.y):Math.abs(o*(t-i.x)-s*(e-i.y))/l}function i(t,e){return Math.abs(t-e)}function n(t,e){return Math.abs(t-e)}function s(e,i,n){let s=1/0;for(let o=1;o<n.length;o++){const l=t(e,i,n[o-1],n[o]);l<s&&(s=l)}return s}function o(t,e){return{x0:Math.min(t.x,e.x),y0:Math.min(t.y,e.y),x1:Math.max(t.x,e.x),y1:Math.max(t.y,e.y)}}function l(e,i,n,s,l){const r=o(n,s);if(e>=r.x0&&e<=r.x1&&i>=r.y0&&i<=r.y1&&l)return 0;const a=[{x:r.x0,y:r.y0},{x:r.x1,y:r.y0},{x:r.x1,y:r.y1},{x:r.x0,y:r.y1}];let c=1/0;for(let n=0;n<4;n++){const s=t(e,i,a[n],a[(n+1)%4]);s<c&&(c=s)}return c}function r(t,e,i,n,s){const l=o(i,n),r=(l.x0+l.x1)/2,a=(l.y0+l.y1)/2,c=Math.max(1e-6,(l.x1-l.x0)/2),h=Math.max(1e-6,(l.y1-l.y0)/2),x=(t-r)/c,d=(e-a)/h,p=Math.hypot(x,d);return s&&p<=1?0:Math.abs(p-1)*Math.min(c,h)}function a(t,e,i,n,s){const o=e.x-t.x;if(0===o)return[t,e];const l=(e.y-t.y)/o;return[n?{x:0,y:t.y+(0-t.x)*l}:t,s?{x:i,y:t.y+(i-t.x)*l}:e]}function c(t){const e=function(t){const e=t.trim();if(e.startsWith("#")){const t=e.slice(1);if(3===t.length||4===t.length){const[e,i,n,s]=[...t].map(t=>parseInt(t+t,16));return[e,i,n].some(Number.isNaN)?null:{r:e,g:i,b:n,a:4===t.length?s/255:1}}if(6===t.length||8===t.length){const e=parseInt(t.slice(0,6),16);if(Number.isNaN(e))return null;const i=8===t.length?parseInt(t.slice(6,8),16)/255:1;return{r:e>>16&255,g:e>>8&255,b:255&e,a:Number.isNaN(i)?1:i}}return null}const i=/^rgba?\(\s*([\d.]+)\s*,\s*([\d.]+)\s*,\s*([\d.]+)\s*(?:,\s*([\d.]+)\s*)?\)$/i.exec(e);return null===i?null:{r:Number(i[1]),g:Number(i[2]),b:Number(i[3]),a:void 0===i[4]?1:Number(i[4])}}(t);if(null===e)return.5;const i=t=>{const e=t/255;return e<=.03928?e/12.92:Math.pow((e+.055)/1.055,2.4)};return.2126*i(e.r)+.7152*i(e.g)+.0722*i(e.b)}function h(t){return c(t)>.45?"#10131a":"#ffffff"}function x(t,e,i,n,s,o){const l=t.roundRect;"function"==typeof l?l.call(t,e,i,n,s,Math.max(0,Math.min(o,n/2,s/2))):t.rect(e,i,n,s)}const d=new Map;function p(t){d.set(t.id,t)}function y(t){const e=d.get(t);if(void 0===e)throw new Error(`openalgo-charts: unknown drawing tool "${t}"`);return e}function u(t){return d.has(t)}function f(){return Array.from(d.values())}function g(t){const{ctx:e,rc:i,style:n}=t,s=i.dpr;e.strokeStyle=n.color,e.lineWidth=Math.max(1,Math.round(n.lineWidth*s)),e.lineJoin="round",e.lineCap="round",e.setLineDash("dashed"===n.lineStyle?[6*s,4*s]:"dotted"===n.lineStyle?[1*s,3*s]:[])}function m(t){return t.style.fillColor??t.style.color}function b(t,e){if(!0!==t.style.fill)return;const{ctx:i}=t;i.save(),i.globalAlpha=t.style.fillOpacity??.12,i.fillStyle=m(t),e(),i.restore()}function _(t,e,i,n,s){const{ctx:o,rc:l,style:r}=t,a=(r.fontSize??11)*l.dpr;o.save(),o.setLineDash([]),o.font=`${a}px ui-sans-serif, system-ui, sans-serif`,o.textBaseline="middle",o.textAlign="left";const c=o.measureText(e).width;o.globalAlpha=.85,o.fillStyle=l.theme.background,o.fillRect(i-2*l.dpr,n-.75*a,c+4*l.dpr,1.5*a),o.globalAlpha=1,o.fillStyle=s??r.color,o.fillText(e,i,n),o.restore()}function w(t,e,i,n,s,o={}){const{ctx:l,rc:r}=t,a=r.dpr,c=(t.style.fontSize??11)*a;l.save(),l.setLineDash([]),l.globalAlpha=1,l.font=`${c}px ui-sans-serif, system-ui, sans-serif`,l.textBaseline="middle",l.textAlign="left";const d=5*a,p=3*a,y=1.35*c;let u=0;for(const t of e)u=Math.max(u,l.measureText(t).width);const f=u+2*d,g=y*e.length+2*p,m=o.align??"left",b="center"===m?i-f/2:"right"===m?i-f:i,_=o.place??"above",w="above"===_?n-g-4*a:"below"===_?n+4*a:n-g/2;l.beginPath(),x(l,b,w,f,g,3*a),l.fillStyle=s,l.fill(),l.fillStyle=h(s);for(let t=0;t<e.length;t++)l.fillText(e[t],b+d,w+p+y*(t+.5));return l.restore(),g}function M(t,e=0){const[i,n]=Math.abs(t).toFixed(e).split(".");return(t<0?"-":"")+i.replace(/\B(?=(\d{3})+(?!\d))/g,",")+(void 0===n?"":"."+n)}function v(t){const e=new Date(1e3*t),i=t=>String(t).padStart(2,"0");return`${e.getUTCFullYear()}-${i(e.getUTCMonth()+1)}-${i(e.getUTCDate())}`}function T(t){const e=Math.max(0,Math.round(Math.abs(t))),i=Math.floor(e/86400),n=Math.floor(e%86400/3600),s=Math.floor(e%3600/60);return i>0?`${i}d ${n}h`:n>0?`${n}h ${s}m`:`${s}m`}function S(t,e,i){const n=Math.max(8,5*t.style.lineWidth)*t.rc.dpr,s=Math.atan2(i.y-e.y,i.x-e.x);t.ctx.beginPath(),t.ctx.moveTo(i.x,i.y),t.ctx.lineTo(i.x-n*Math.cos(s-.4),i.y-n*Math.sin(s-.4)),t.ctx.lineTo(i.x-n*Math.cos(s+.4),i.y-n*Math.sin(s+.4)),t.ctx.closePath(),t.ctx.fillStyle=t.style.color,t.ctx.fill()}const P="#26a69a",L="#ef5350",k=[0,.236,.382,.5,.618,.786,1];function D(i,n,s,o){return{id:i,name:n,points:2,defaultStyle:{extendLeft:s,extendRight:o},draw:t=>{const[e,i]=a(t.pts[0],t.pts[1],t.rc.plotWidth*t.rc.dpr,t.style.extendLeft??s,t.style.extendRight??o);g(t),t.ctx.beginPath(),t.ctx.moveTo(e.x,e.y),t.ctx.lineTo(i.x,i.y),t.ctx.stroke(),t.ctx.setLineDash([])},distance:(i,n,l)=>{const r=l.drawing.style.extendLeft??s,c=l.drawing.style.extendRight??o;if(r&&c)return e(i,n,l.pts[0],l.pts[1]);const[h,x]=a(l.pts[0],l.pts[1],l.rc.plotWidth,r,c);return t(i,n,h,x)}}}const $=D("trend-line","Trend Line",!1,!1),O=D("ray","Ray",!1,!0),F=D("extended-line","Extended Line",!0,!0),A={id:"arrow",name:"Arrow",points:2,draw:t=>{const[e,i]=t.pts;g(t),t.ctx.beginPath(),t.ctx.moveTo(e.x,e.y),t.ctx.lineTo(i.x,i.y),t.ctx.stroke();const n=Math.max(8,5*t.style.lineWidth)*t.rc.dpr,s=Math.atan2(i.y-e.y,i.x-e.x);t.ctx.beginPath(),t.ctx.moveTo(i.x,i.y),t.ctx.lineTo(i.x-n*Math.cos(s-.4),i.y-n*Math.sin(s-.4)),t.ctx.lineTo(i.x-n*Math.cos(s+.4),i.y-n*Math.sin(s+.4)),t.ctx.closePath(),t.ctx.fillStyle=t.style.color,t.ctx.fill(),t.ctx.setLineDash([])},distance:(e,i,n)=>t(e,i,n.pts[0],n.pts[1])},N={id:"horizontal-line",name:"Horizontal Line",points:1,defaultStyle:{showLabels:!0},draw:t=>{const e=Math.round(t.pts[0].y)+.5;g(t),t.ctx.beginPath(),t.ctx.moveTo(0,e),t.ctx.lineTo(t.rc.plotWidth*t.rc.dpr,e),t.ctx.stroke(),t.ctx.setLineDash([]),!1!==t.style.showLabels&&_(t,t.formatPrice(t.drawing.points[0].price),4*t.rc.dpr,e-8*t.rc.dpr)},distance:(t,e,n)=>i(e,n.pts[0].y)},W={id:"horizontal-ray",name:"Horizontal Ray",points:1,defaultStyle:{showLabels:!0},draw:t=>{const e=Math.round(t.pts[0].y)+.5;g(t),t.ctx.beginPath(),t.ctx.moveTo(t.pts[0].x,e),t.ctx.lineTo(t.rc.plotWidth*t.rc.dpr,e),t.ctx.stroke(),t.ctx.setLineDash([]),!1!==t.style.showLabels&&_(t,t.formatPrice(t.drawing.points[0].price),t.pts[0].x+4*t.rc.dpr,e-8*t.rc.dpr)},distance:(t,e,n)=>t<n.pts[0].x?null:i(e,n.pts[0].y)},C={id:"vertical-line",name:"Vertical Line",points:1,draw:t=>{const e=Math.round(t.pts[0].x)+.5;g(t),t.ctx.beginPath(),t.ctx.moveTo(e,0),t.ctx.lineTo(e,t.rc.plotHeight*t.rc.dpr),t.ctx.stroke(),t.ctx.setLineDash([])},distance:(t,e,i)=>n(t,i.pts[0].x)},I={id:"cross-line",name:"Cross Line",points:1,draw:t=>{const e=Math.round(t.pts[0].x)+.5,i=Math.round(t.pts[0].y)+.5;g(t),t.ctx.beginPath(),t.ctx.moveTo(e,0),t.ctx.lineTo(e,t.rc.plotHeight*t.rc.dpr),t.ctx.moveTo(0,i),t.ctx.lineTo(t.rc.plotWidth*t.rc.dpr,i),t.ctx.stroke(),t.ctx.setLineDash([])},distance:(t,e,s)=>Math.min(n(t,s.pts[0].x),i(e,s.pts[0].y))},R={id:"rectangle",name:"Rectangle",points:2,defaultStyle:{fill:!0,fontSize:14,textAlign:"left",textVAlign:"top",textPosition:"inside"},draw:t=>{const e=o(t.pts[0],t.pts[1]);b(t,()=>t.ctx.fillRect(e.x0,e.y0,e.x1-e.x0,e.y1-e.y0)),g(t),t.ctx.strokeRect(e.x0,e.y0,e.x1-e.x0,e.y1-e.y0),t.ctx.setLineDash([]),Z(t,e.x0,e.y0,e.x1,e.y1)},distance:(t,e,i)=>l(t,e,i.pts[0],i.pts[1],!0===i.drawing.style.fill)},z={id:"ellipse",name:"Ellipse",points:2,defaultStyle:{fill:!0,fontSize:14,textAlign:"center",textVAlign:"middle",textPosition:"inside"},draw:t=>{const e=o(t.pts[0],t.pts[1]),i=(e.x0+e.x1)/2,n=(e.y0+e.y1)/2,s=Math.max(1,(e.x1-e.x0)/2),l=Math.max(1,(e.y1-e.y0)/2),r=()=>{t.ctx.beginPath(),t.ctx.ellipse(i,n,s,l,0,0,2*Math.PI)};b(t,()=>{r(),t.ctx.fill()}),g(t),r(),t.ctx.stroke(),t.ctx.setLineDash([]),Z(t,e.x0,e.y0,e.x1,e.y1)},distance:(t,e,i)=>r(t,e,i.pts[0],i.pts[1],!0===i.drawing.style.fill)},j={id:"parallel-channel",name:"Parallel Channel",points:3,defaultStyle:{fill:!0},draw:t=>{const[e,i,n]=t.pts,s=n.y-(e.y+.5*(i.y-e.y)),o={x:e.x,y:e.y+s},l={x:i.x,y:i.y+s};b(t,()=>{t.ctx.beginPath(),t.ctx.moveTo(e.x,e.y),t.ctx.lineTo(i.x,i.y),t.ctx.lineTo(l.x,l.y),t.ctx.lineTo(o.x,o.y),t.ctx.closePath(),t.ctx.fill()}),g(t),t.ctx.beginPath(),t.ctx.moveTo(e.x,e.y),t.ctx.lineTo(i.x,i.y),t.ctx.moveTo(o.x,o.y),t.ctx.lineTo(l.x,l.y),t.ctx.stroke(),t.ctx.setLineDash([]),Z(t,Math.min(e.x,i.x),Math.min(e.y,i.y,o.y,l.y),Math.max(e.x,i.x),Math.max(e.y,i.y,o.y,l.y))},distance:(e,i,n)=>{const[s,o,l]=n.pts,r=l.y-(s.y+.5*(o.y-s.y)),a=t(e,i,s,o),c=t(e,i,{x:s.x,y:s.y+r},{x:o.x,y:o.y+r});return Math.min(a,c)}};function U(t,e,i){return{id:t,name:e,points:i,defaultStyle:{showLabels:!0,levels:[...k],fill:!0,fillOpacity:.06},draw:t=>{const e=t.style.levels??k,n=t.drawing.points,s=2===i?n[0].price:n[2].price,o=n[1].price-n[0].price,l=Math.min(t.pts[0].x,t.pts[i-1].x),r=Math.max(t.pts[0].x,t.pts[i-1].x),a=!0===t.style.extendRight?t.rc.plotWidth*t.rc.dpr:r;g(t);let c=null;for(const i of e){const e=s+o*i,n=Math.round(t.rc.priceScale.priceToY(e)*t.rc.dpr)+.5;!0===t.style.fill&&null!==c&&(t.ctx.save(),t.ctx.globalAlpha=t.style.fillOpacity??.06,t.ctx.fillStyle=m(t),t.ctx.fillRect(l,Math.min(c,n),a-l,Math.abs(n-c)),t.ctx.restore()),c=n,t.ctx.beginPath(),t.ctx.moveTo(l,n),t.ctx.lineTo(a,n),t.ctx.stroke(),!1!==t.style.showLabels&&_(t,`${(100*i).toFixed(1)}% ${t.formatPrice(e)}`,l+4*t.rc.dpr,n-8*t.rc.dpr)}t.ctx.setLineDash([])},distance:(t,e,n)=>{const s=n.drawing.style.levels??k,o=n.drawing.points,l=2===i?o[0].price:o[2].price,r=o[1].price-o[0].price,a=Math.min(n.pts[0].x,n.pts[i-1].x),c=!0===n.drawing.style.extendRight?n.rc.plotWidth:Math.max(n.pts[0].x,n.pts[i-1].x);if(t<a-4||t>c+4)return null;let h=1/0;for(const t of s){const i=Math.abs(e-n.rc.priceScale.priceToY(l+r*t));i<h&&(h=i)}return h}}}const B=U("fib-retracement","Fib Retracement",2),H=U("fib-extension","Fib Extension",3),J={id:"measure",name:"Measure",points:2,defaultStyle:{fill:!0,showLabels:!0,fillOpacity:.14},draw:t=>{const e=o(t.pts[0],t.pts[1]),i=t.rc.dpr,n=t.drawing.points,s=n[1].price-n[0].price,l=0!==n[0].price?s/n[0].price*100:0,r=s>=0,a=r?P:L;t.ctx.save(),t.ctx.globalAlpha=t.style.fillOpacity??.14,t.ctx.fillStyle=a,t.ctx.fillRect(e.x0,e.y0,e.x1-e.x0,e.y1-e.y0),t.ctx.restore(),g(t),t.ctx.strokeStyle=a,t.ctx.strokeRect(e.x0,e.y0,e.x1-e.x0,e.y1-e.y0),t.ctx.setLineDash([]);const c=(e.x0+e.x1)/2,h=t.pts[0].y,x=t.pts[1].y;if(t.ctx.strokeStyle=a,t.ctx.beginPath(),t.ctx.moveTo(e.x0,h),t.ctx.lineTo(e.x1,h),t.ctx.stroke(),S(t,{x:e.x0,y:h},{x:e.x1,y:h}),t.ctx.beginPath(),t.ctx.moveTo(c,h),t.ctx.lineTo(c,x),t.ctx.stroke(),S(t,{x:c,y:h},{x:c,y:x}),!1===t.style.showLabels)return;const d=t.rc.dataLayer.timeToIndexFloat(n[0].time),p=t.rc.dataLayer.timeToIndexFloat(n[1].time),y=Math.abs(Math.round(p-d)),u=r?"+":"",f=[`${u}${t.formatPrice(s)} (${u}${l.toFixed(2)}%)`,`${M(y)} bars, ${T(n[1].time-n[0].time)}`],m=t.rc.bars?.();if(void 0!==m&&m.length>0){const t=Math.min(n[0].time,n[1].time),e=Math.max(n[0].time,n[1].time);let i=0,s=!1;for(const n of m)if(!(n.time<t)){if(n.time>e)break;void 0!==n.volume&&(i+=n.volume,s=!0)}s&&f.push(`Vol ${function(t){const e=Math.abs(t);return e>=1e9?`${(t/1e9).toFixed(2)}B`:e>=1e6?`${(t/1e6).toFixed(2)}M`:e>=1e3?`${(t/1e3).toFixed(2)}K`:M(t)}(i)}`)}w(t,f,c,Math.max(h,x)+6*i,a,{align:"center",place:"below"})},distance:(t,e,i)=>l(t,e,i.pts[0],i.pts[1],!0)};function E(t,e,i){return{id:t,name:e,points:1,defaultStyle:{showLabels:!0,fillOpacity:.13,accountSize:1e5,risk:1},expand:(t,e)=>{const n=t[0],s=.01*Math.abs(n.price)||1,o=Math.max(5,Math.round(.08*e.visibleBars)),l=n.time+Math.max(1,e.barSeconds)*o;return i?[n,{time:l,price:n.price+s},{time:l,price:n.price-s}]:[n,{time:l,price:n.price-s},{time:l,price:n.price+s}]},draw:t=>{if(t.drawing.points.length<3||t.pts.length<3)return;const[e,n,s]=t.drawing.points,o=t.rc.dpr,l=Math.min(t.pts[0].x,t.pts[1].x,t.pts[2].x),r=Math.max(t.pts[0].x,t.pts[1].x,t.pts[2].x),a=t.rc.priceScale.priceToY(e.price)*o,c=t.rc.priceScale.priceToY(n.price)*o,h=t.rc.priceScale.priceToY(s.price)*o,x=(e,i,n)=>{t.ctx.save(),t.ctx.globalAlpha=t.style.fillOpacity??.13,t.ctx.fillStyle=n,t.ctx.fillRect(l,Math.min(e,i),r-l,Math.abs(i-e)),t.ctx.restore()};x(a,c,P),x(a,h,L),g(t);for(const e of[a,c,h]){const i=Math.round(e)+.5;t.ctx.beginPath(),t.ctx.moveTo(l,i),t.ctx.lineTo(r,i),t.ctx.stroke()}if(t.ctx.setLineDash([]),!1===t.style.showLabels)return;const d=Math.abs(e.price-s.price),p=Math.abs(n.price-e.price),y=d>0?p/d:0,u=t.style.accountSize??0,f=t.style.risk??0,m=d>0&&u>0?Math.floor(u*f/100/d):0,b=t=>(0!==e.price?t/e.price*100:0).toFixed(3),_=t=>m>0?`, Amount: ${M(m*t)}`:"",v=(l+r)/2;w(t,[`Target: ${t.formatPrice(p)} (${b(p)}%)${_(p)}`],v,c,P,{align:"center",place:c<=a?"above":"below"}),w(t,[`Stop: ${t.formatPrice(d)} (${b(d)}%)${_(d)}`],v,h,L,{align:"center",place:h>=a?"below":"above"}),w(t,[`${i?"Long":"Short"} · Qty: ${m>0?M(m):"—"}`,`Risk/reward ratio: ${y.toFixed(2)}`],v,a,t.rc.theme.background,{align:"center",place:"middle"})},distance:(t,e,i)=>{if(i.pts.length<3)return null;const n=Math.min(i.pts[0].x,i.pts[1].x,i.pts[2].x),s=Math.max(i.pts[0].x,i.pts[1].x,i.pts[2].x);if(t<n-4||t>s+4)return null;const o=i.drawing.points.map(t=>i.rc.priceScale.priceToY(t.price)),l=Math.min(...o),r=Math.max(...o);return e>=l&&e<=r?0:Math.min(Math.abs(e-l),Math.abs(e-r))}}}const Y=E("long-position","Long Position",!0),V=E("short-position","Short Position",!1),q=1.35,G="ui-sans-serif, system-ui, -apple-system, Segoe UI, Roboto, sans-serif";function K(t,e){const i="bold"===t.fontWeight?"700 ":"";return`${"italic"===t.fontStyle?"italic ":""}${i}${e}px ${t.fontFamily??G}`}function Q(t,e,i){const n=(e.text??"").split("\n");if(!0!==e.wrap)return n;const s=[];for(const e of n){const n=e.split(/\s+/).filter(t=>""!==t);if(0===n.length){s.push("");continue}let o=n[0];for(let e=1;e<n.length;e++){const l=`${o} ${n[e]}`;t.measureText(l).width>i?(s.push(o),o=n[e]):o=l}s.push(o)}return s}function X(t,e,i){const n=(e.fontSize??13)*i;t.font=K(e,n);const s=Q(t,e,(e.wrapWidth??220)*i);let o=0;for(const e of s)o=Math.max(o,t.measureText(e).width);const l=n*q;return{lines:s,width:o+10*i,height:s.length*l+10*i,lineHeight:l}}function Z(t,e,i,n,s){const{ctx:o,rc:l,style:r}=t,a=r.text;if(void 0===a||""===a)return;const c=l.dpr,h=(r.fontSize??14)*c,x=6*c;o.save(),o.setLineDash([]),o.font=K(r,h),o.fillStyle=r.fontColor??r.color,o.textBaseline="top";const d=!0===r.wrap?Q(o,r,Math.max(20*c,n-e-2*x)):a.split("\n"),p=h*q,y=d.length*p,u=r.textAlign??"left";o.textAlign=u;const f="center"===u?(e+n)/2:"right"===u?n-x:e+x;let g;if("outside"===r.textPosition)g=i-y-x;else{const t=r.textVAlign??"top";g="middle"===t?(i+s-y)/2:"bottom"===t?s-y-x:i+x}for(const t of d)o.fillText(t,f,g),g+=p;o.restore()}const tt={id:"text",name:"Text",points:1,defaultStyle:{text:"Text",fontSize:14,fontWeight:"normal",fontStyle:"normal",background:!1,backgroundOpacity:1,border:!1,wrap:!1,wrapWidth:220,textAlign:"left"},draw:t=>{const{ctx:e,rc:i,style:n}=t,s=i.dpr,o=X(e,n,s),l=t.pts[0].x,r=t.pts[0].y;e.save(),e.setLineDash([]),!0===n.background&&(e.globalAlpha=n.backgroundOpacity??1,e.fillStyle=n.backgroundColor??i.theme.background,e.beginPath(),e.roundRect(l,r,o.width,o.height,4*s),e.fill(),e.globalAlpha=1),!0===n.border&&(e.strokeStyle=n.borderColor??n.color,e.lineWidth=Math.max(1,n.lineWidth*s),e.beginPath(),e.roundRect(l,r,o.width,o.height,4*s),e.stroke()),e.font=K(n,(n.fontSize??13)*s),e.fillStyle=n.color,e.textBaseline="top";const a=n.textAlign??"left";e.textAlign=a;const c="center"===a?l+o.width/2:"right"===a?l+o.width-5*s:l+5*s;let h=r+5*s;for(const t of o.lines)e.fillText(t,c,h),h+=o.lineHeight;e.restore()},distance:(t,e,i)=>{const n=i.drawing.style,s=n.fontSize??13,o=i.pts[0],l=function(){if(void 0!==et)return et;try{et="undefined"==typeof document?null:document.createElement("canvas").getContext("2d")}catch{et=null}return et}(),r=null===l?{width:(n.text??"").length*s*.6+10,height:s*q+10}:X(l,n,1);return t>=o.x-3&&t<=o.x+r.width+3&&e>=o.y-3&&e<=o.y+r.height+3?0:null}};let et;const it={id:"path",name:"Path",points:0,draw:t=>{if(!(t.pts.length<2)){g(t),t.ctx.beginPath(),t.ctx.moveTo(t.pts[0].x,t.pts[0].y);for(let e=1;e<t.pts.length;e++)t.ctx.lineTo(t.pts[e].x,t.pts[e].y);t.ctx.stroke(),t.ctx.setLineDash([]),S(t,t.pts[t.pts.length-2],t.pts[t.pts.length-1])}},distance:(t,e,i)=>i.pts.length<2?null:s(t,e,i.pts)},nt={id:"brush",name:"Brush",points:0,freehand:!0,defaultStyle:{lineWidth:2},draw:t=>{if(!(t.pts.length<2)){g(t),t.ctx.lineCap="round",t.ctx.lineJoin="round",t.ctx.beginPath(),t.ctx.moveTo(t.pts[0].x,t.pts[0].y);for(let e=1;e<t.pts.length;e++)t.ctx.lineTo(t.pts[e].x,t.pts[e].y);t.ctx.stroke(),t.ctx.setLineDash([])}},distance:(t,e,i)=>i.pts.length<2?null:s(t,e,i.pts)},st={id:"rotated-rectangle",name:"Rotated Rectangle",points:3,defaultStyle:{fill:!0,fillOpacity:.12},draw:t=>{if(t.pts.length<3)return;const e=ot(t.pts[0],t.pts[1],t.pts[2]);t.ctx.beginPath(),t.ctx.moveTo(e[0].x,e[0].y);for(let i=1;i<4;i++)t.ctx.lineTo(e[i].x,e[i].y);t.ctx.closePath(),!0===t.style.fill&&(t.ctx.save(),t.ctx.globalAlpha=t.style.fillOpacity??.12,t.ctx.fillStyle=m(t),t.ctx.fill(),t.ctx.restore()),g(t),t.ctx.stroke(),t.ctx.setLineDash([])},distance:(e,i,n)=>{if(n.pts.length<3)return null;const s=ot(n.pts[0],n.pts[1],n.pts[2]);if(!0===n.drawing.style.fill&&function(t,e,i){let n=!1;for(let s=0,o=i.length-1;s<i.length;o=s++){const l=i[s],r=i[o];l.y>e!=r.y>e&&t<(r.x-l.x)*(e-l.y)/(r.y-l.y)+l.x&&(n=!n)}return n}(e,i,s))return 0;let o=1/0;for(let n=0;n<4;n++)o=Math.min(o,t(e,i,s[n],s[(n+1)%4]));return o}};function ot(t,e,i){const n=e.x-t.x,s=e.y-t.y,o=Math.hypot(n,s)||1,l=-s/o,r=n/o,a=(i.x-e.x)*l+(i.y-e.y)*r;return[t,e,{x:e.x+l*a,y:e.y+r*a},{x:t.x+l*a,y:t.y+r*a}]}const lt={id:"double-curve",name:"Double Curve",points:3,draw:t=>{if(t.pts.length<3)return;const[e,i,n]=t.pts;g(t),t.ctx.beginPath(),t.ctx.moveTo(e.x,e.y),t.ctx.bezierCurveTo(i.x,i.y,e.x+n.x-i.x,e.y+n.y-i.y,n.x,n.y),t.ctx.stroke(),t.ctx.setLineDash([])},distance:(t,e,i)=>{if(i.pts.length<3)return null;const[n,o,l]=i.pts;return s(t,e,function(t,e,i,n,s){const o=[];for(let l=0;l<=s;l++){const r=l/s,a=1-r,c=a*a*a,h=3*a*a*r,x=3*a*r*r,d=r*r*r;o.push({x:c*t.x+h*e.x+x*i.x+d*n.x,y:c*t.y+h*e.y+x*i.y+d*n.y})}return o}(n,o,{x:n.x+l.x-o.x,y:n.y+l.y-o.y},l,24))}};const rt={id:"cyclic-lines",name:"Cyclic Lines",points:2,defaultStyle:{lineStyle:"dashed"},draw:t=>{const[e,i]=t.pts,n=i.x-e.x;if(!Number.isFinite(n)||Math.abs(n)<.5)return;const s=t.rc.plotHeight*t.rc.dpr,o=t.rc.plotWidth*t.rc.dpr;g(t),t.ctx.beginPath();for(let i=0;i<=12;i++){const l=Math.round(e.x+n*i)+.5;l<0||l>o||(t.ctx.moveTo(l,0),t.ctx.lineTo(l,s))}t.ctx.stroke(),t.ctx.setLineDash([])},distance:(t,e,i)=>{const n=i.pts[1].x-i.pts[0].x;if(!Number.isFinite(n)||Math.abs(n)<.5)return null;const s=Math.round((t-i.pts[0].x)/n);return s<0||s>12?null:Math.abs(t-(i.pts[0].x+n*s))}},at={id:"time-cycles",name:"Time Cycles",points:2,draw:t=>{const[e,i]=t.pts,n=i.x-e.x;if(!Number.isFinite(n)||Math.abs(n)<1)return;const s=Math.abs(n)/2;g(t),t.ctx.beginPath();for(let i=0;i<12;i++){const o=e.x+n*i+n/2;o+s<0||o-s>t.rc.plotWidth*t.rc.dpr||(t.ctx.moveTo(o+s,e.y),t.ctx.arc(o,e.y,s,0,Math.PI,!0))}t.ctx.stroke(),t.ctx.setLineDash([])},distance:(t,e,i)=>{const[n,s]=i.pts,o=s.x-n.x;if(!Number.isFinite(o)||Math.abs(o)<1)return null;const l=Math.abs(o)/2;let r=1/0;for(let i=0;i<12;i++){const s=n.x+o*i+o/2;e>n.y+2||(r=Math.min(r,Math.abs(Math.hypot(t-s,e-n.y)-l)))}return Number.isFinite(r)?r:null}},ct={id:"sine-line",name:"Sine Line",points:2,draw:t=>{const e=ht(t.pts[0],t.pts[1]);if(null!==e){g(t),t.ctx.beginPath(),t.ctx.moveTo(e[0].x,e[0].y);for(let i=1;i<e.length;i++)t.ctx.lineTo(e[i].x,e[i].y);t.ctx.stroke(),t.ctx.setLineDash([])}},distance:(t,e,i)=>{const n=ht(i.pts[0],i.pts[1]);return null===n?null:s(t,e,n)}};function ht(t,e){const i=e.x-t.x,n=e.y-t.y;if(!Number.isFinite(i)||Math.abs(i)<1)return null;const s=[];for(let e=0;e<=64;e++){const o=e/64;s.push({x:t.x+i*o,y:t.y+n*Math.sin(o*Math.PI*2)})}return s}const xt={id:"price-label",name:"Price Label",points:1,defaultStyle:{fontSize:12},draw:t=>{const e=t.pts[0],i=t.rc.dpr,n=void 0!==t.style.text&&""!==t.style.text?t.style.text:t.formatPrice(t.drawing.points[0].price),s=pt(t,[n],e.x+18*i,e.y-30*i);yt(t,s,e,t.style.color),ut(t,s,[n],t.style.color)},distance:(t,e,i)=>{const n=i.pts[0],s=n.x+18,o=n.y-30-11;return t>=s&&t<=s+64&&e>=o&&e<=o+22||Math.hypot(t-n.x,e-n.y)<=10?0:null}},dt={id:"callout",name:"Callout",points:2,defaultStyle:{fontSize:12,text:"Note"},draw:t=>{if(t.pts.length<2)return;const[e,i]=t.pts,n=(t.style.text??"Note").split("\n"),s=pt(t,n,i.x,i.y);yt(t,s,e,t.style.color),ut(t,s,n,t.style.color)},distance:(e,i,n)=>{if(n.pts.length<2)return null;const[s,o]=n.pts;return Math.abs(e-o.x)<=60&&Math.abs(i-o.y)<=16?0:t(e,i,s,o)}};function pt(t,e,i,n){const s=t.rc.dpr,o=(t.style.fontSize??12)*s;t.ctx.save(),t.ctx.font=`${o}px ui-sans-serif, system-ui, sans-serif`;let l=0;for(const i of e)l=Math.max(l,t.ctx.measureText(i).width);t.ctx.restore();const r=l+14*s,a=1.4*o*e.length+8*s;return{x:i-r/2,y:n-a/2,w:r,h:a}}function yt(t,e,i,n){const s=t.rc.dpr,o=e.x+e.w/2,l=e.y+e.h/2,r=Math.atan2(i.y-l,i.x-o),a=5*s,c=o+Math.cos(r)*(e.w/2-a),h=l+Math.sin(r)*(e.h/2-a);t.ctx.save(),t.ctx.setLineDash([]),t.ctx.fillStyle=n,t.ctx.beginPath(),t.ctx.moveTo(i.x,i.y),t.ctx.lineTo(c-Math.sin(r)*a,h+Math.cos(r)*a),t.ctx.lineTo(c+Math.sin(r)*a,h-Math.cos(r)*a),t.ctx.closePath(),t.ctx.fill(),t.ctx.beginPath(),x(t.ctx,e.x,e.y,e.w,e.h,5*s),t.ctx.fill(),t.ctx.beginPath(),t.ctx.arc(i.x,i.y,2.5*s,0,2*Math.PI),t.ctx.fill(),t.ctx.restore()}function ut(t,e,i,n){const s=t.rc.dpr,o=(t.style.fontSize??12)*s;t.ctx.save(),t.ctx.setLineDash([]),t.ctx.font=`${o}px ui-sans-serif, system-ui, sans-serif`,t.ctx.textAlign="center",t.ctx.textBaseline="middle",t.ctx.fillStyle=t.style.fontColor??h(n);const l=1.4*o,r=e.y+e.h/2-l*(i.length-1)/2;for(let n=0;n<i.length;n++)t.ctx.fillText(i[n],e.x+e.w/2,r+l*n);t.ctx.restore()}const ft={id:"flag-mark",name:"Flag Mark",points:1,defaultStyle:{fill:!0,fillOpacity:.95},draw:t=>{const e=t.pts[0],i=t.rc.dpr,n=22*i,s=15*i,o=11*i;g(t),t.ctx.beginPath(),t.ctx.moveTo(e.x,e.y),t.ctx.lineTo(e.x,e.y-n),t.ctx.stroke(),t.ctx.setLineDash([]),t.ctx.beginPath(),t.ctx.moveTo(e.x,e.y-n),t.ctx.lineTo(e.x+s,e.y-n+.28*o),t.ctx.lineTo(e.x+.72*s,e.y-n+.5*o),t.ctx.lineTo(e.x+s,e.y-n+.72*o),t.ctx.lineTo(e.x,e.y-n+o),t.ctx.closePath(),t.ctx.save(),t.ctx.globalAlpha=t.style.fillOpacity??.95,t.ctx.fillStyle=m(t),t.ctx.fill(),t.ctx.restore()},distance:(t,e,i)=>{const n=i.pts[0];return t>=n.x-4&&t<=n.x+16&&e>=n.y-24&&e<=n.y+2||Math.hypot(t-n.x,e-n.y)<=8?0:null}},gt={id:"price-range",name:"Price Range",points:2,defaultStyle:{fill:!0,showLabels:!0,fillOpacity:.1},draw:t=>{const e=t.rc.dpr,i=t.drawing.points,n=i[1].price-i[0].price,s=0!==i[0].price?n/i[0].price*100:0,o=n>=0,l=o?"#26a69a":"#ef5350",r=Math.min(t.pts[0].x,t.pts[1].x),a=Math.max(t.pts[0].x,t.pts[1].x)+(t.pts[0].x===t.pts[1].x?60*e:0),c=t.pts[0].y,h=t.pts[1].y;t.ctx.save(),t.ctx.globalAlpha=t.style.fillOpacity??.1,t.ctx.fillStyle=l,t.ctx.fillRect(r,Math.min(c,h),a-r,Math.abs(h-c)),t.ctx.restore(),g(t),t.ctx.strokeStyle=l,t.ctx.beginPath();for(const e of[c,h])t.ctx.moveTo(r,Math.round(e)+.5),t.ctx.lineTo(a,Math.round(e)+.5);const x=(r+a)/2;t.ctx.moveTo(x,c),t.ctx.lineTo(x,h);const d=h>c?1:-1;t.ctx.moveTo(x-4*e,h-5*e*d),t.ctx.lineTo(x,h),t.ctx.lineTo(x+4*e,h-5*e*d),t.ctx.moveTo(x-4*e,c+5*e*d),t.ctx.lineTo(x,c),t.ctx.lineTo(x+4*e,c+5*e*d),t.ctx.stroke(),t.ctx.setLineDash([]);const p=o?"+":"";_(t,`${p}${t.formatPrice(n)} (${p}${s.toFixed(2)}%)`,x+6*e,(c+h)/2,l)},distance:(t,e,i)=>l(t,e,i.pts[0],i.pts[1],!0)},mt={id:"date-range",name:"Date Range",points:2,defaultStyle:{fill:!0,showLabels:!0,fillOpacity:.1},draw:t=>{const e=t.rc.dpr,i=t.drawing.points,n=t.style.color,s=t.pts[0].x,o=t.pts[1].x,l=Math.min(t.pts[0].y,t.pts[1].y),r=Math.max(t.pts[0].y,t.pts[1].y)+(t.pts[0].y===t.pts[1].y?40*e:0);t.ctx.save(),t.ctx.globalAlpha=t.style.fillOpacity??.1,t.ctx.fillStyle=n,t.ctx.fillRect(Math.min(s,o),l,Math.abs(o-s),r-l),t.ctx.restore(),g(t),t.ctx.beginPath();for(const e of[s,o])t.ctx.moveTo(Math.round(e)+.5,l),t.ctx.lineTo(Math.round(e)+.5,r);const a=(l+r)/2;t.ctx.moveTo(s,a),t.ctx.lineTo(o,a);const c=o>s?1:-1;t.ctx.moveTo(o-5*e*c,a-4*e),t.ctx.lineTo(o,a),t.ctx.lineTo(o-5*e*c,a+4*e),t.ctx.moveTo(s+5*e*c,a-4*e),t.ctx.lineTo(s,a),t.ctx.lineTo(s+5*e*c,a+4*e),t.ctx.stroke(),t.ctx.setLineDash([]);const h=t.rc.dataLayer.timeToIndexFloat(i[0].time),x=t.rc.dataLayer.timeToIndexFloat(i[1].time);_(t,`${Math.abs(Math.round(x-h))} bars`,(s+o)/2,l-10*e,n)},distance:(t,e,i)=>l(t,e,i.pts[0],i.pts[1],!0)},bt={id:"forecast",name:"Forecast",points:2,defaultStyle:{fill:!0,showLabels:!0,fillOpacity:.12,lineStyle:"dashed"},draw:t=>{const e=t.rc.dpr,i=t.drawing.points,[n,s]=t.pts,o=i[1].price-i[0].price,l=0!==i[0].price?o/i[0].price*100:0,r=o>=0,a=r?"#26a69a":"#ef5350",c=.35*Math.abs(s.y-n.y)+6*e;if(t.ctx.save(),t.ctx.globalAlpha=t.style.fillOpacity??.12,t.ctx.fillStyle=a,t.ctx.beginPath(),t.ctx.moveTo(n.x,n.y),t.ctx.lineTo(s.x,s.y-c),t.ctx.lineTo(s.x,s.y+c),t.ctx.closePath(),t.ctx.fill(),t.ctx.restore(),g(t),t.ctx.strokeStyle=a,t.ctx.beginPath(),t.ctx.moveTo(n.x,n.y),t.ctx.lineTo(s.x,s.y),t.ctx.stroke(),t.ctx.setLineDash([]),t.ctx.beginPath(),t.ctx.arc(n.x,n.y,3*e,0,2*Math.PI),t.ctx.fillStyle=a,t.ctx.fill(),!1===t.style.showLabels)return;const h=r?"+":"";w(t,[t.formatPrice(i[0].price),v(i[0].time)],n.x,n.y,a,{align:"center"}),w(t,[`${h}${t.formatPrice(o)} (${h}${l.toFixed(2)}%) in ${T(i[1].time-i[0].time)}`,`${t.formatPrice(i[1].price)} · ${v(i[1].time)}`],s.x,s.y,a,{align:"center",place:"below"});const x=t.rc.bars?.();if(void 0!==x&&x.length>0&&x[x.length-1].time>=i[1].time){let n=!1;for(const t of x)if(!(t.time<i[0].time)){if(t.time>i[1].time)break;if(r?t.high>=i[1].price:t.low<=i[1].price){n=!0;break}}w(t,[n?"SUCCESS":"MISSED"],s.x,s.y+36*e,n?"#4a934a":"#8a4a4a",{align:"center",place:"below"})}},distance:(e,i,n)=>t(e,i,n.pts[0],n.pts[1])},_t={id:"circle",name:"Circle",points:2,defaultStyle:{fill:!0},draw:t=>{const[e,i]=t.pts,n=Math.hypot(i.x-e.x,i.y-e.y);t.ctx.beginPath(),t.ctx.arc(e.x,e.y,n,0,2*Math.PI),b(t,()=>t.ctx.fill()),g(t),t.ctx.stroke(),t.ctx.setLineDash([])},distance:(t,e,i)=>{const[n,s]=i.pts,o=Math.hypot(s.x-n.x,s.y-n.y),l=Math.hypot(t-n.x,e-n.y);return!0===i.drawing.style.fill&&l<=o?0:Math.abs(l-o)}},wt={id:"triangle",name:"Triangle",points:3,defaultStyle:{fill:!0},draw:t=>{t.ctx.beginPath(),t.ctx.moveTo(t.pts[0].x,t.pts[0].y),t.ctx.lineTo(t.pts[1].x,t.pts[1].y),t.ctx.lineTo(t.pts[2].x,t.pts[2].y),t.ctx.closePath(),b(t,()=>t.ctx.fill()),g(t),t.ctx.stroke(),t.ctx.setLineDash([])},distance:(t,e,i)=>s(t,e,[...i.pts,i.pts[0]])},Mt={id:"polyline",name:"Polyline",points:0,defaultStyle:{fill:!1},draw:t=>{if(!(t.pts.length<2)){t.ctx.beginPath(),t.ctx.moveTo(t.pts[0].x,t.pts[0].y);for(let e=1;e<t.pts.length;e++)t.ctx.lineTo(t.pts[e].x,t.pts[e].y);!0===t.style.fill&&(t.ctx.closePath(),b(t,()=>t.ctx.fill())),g(t),t.ctx.stroke(),t.ctx.setLineDash([])}},distance:(t,e,i)=>s(t,e,i.pts)};const vt={id:"arc",name:"Arc",points:3,draw:t=>{const[e,i,n]=t.pts;g(t),t.ctx.beginPath(),t.ctx.moveTo(e.x,e.y),t.ctx.quadraticCurveTo(2*i.x-(e.x+n.x)/2,2*i.y-(e.y+n.y)/2,n.x,n.y),t.ctx.stroke(),t.ctx.setLineDash([])},distance:(t,e,i)=>s(t,e,function(t,e,i){const n=2*e.x-(t.x+i.x)/2,s=2*e.y-(t.y+i.y)/2,o=[];for(let e=0;e<=16;e++){const l=e/16,r=1-l;o.push({x:r*r*t.x+2*r*l*n+l*l*i.x,y:r*r*t.y+2*r*l*s+l*l*i.y})}return o}(i.pts[0],i.pts[1],i.pts[2]))},Tt={id:"curve",name:"Curve",points:3,draw:t=>{const[e,i,n]=t.pts;g(t),t.ctx.beginPath(),t.ctx.moveTo(e.x,e.y),t.ctx.quadraticCurveTo(i.x,i.y,n.x,n.y),t.ctx.stroke(),t.ctx.setLineDash([])},distance:(t,e,i)=>{const[n,o,l]=i.pts,r=[];for(let t=0;t<=16;t++){const e=t/16,i=1-e;r.push({x:i*i*n.x+2*i*e*o.x+e*e*l.x,y:i*i*n.y+2*i*e*o.y+e*e*l.y})}return s(t,e,r)}};function St(t,e,i){return{id:t,name:e,points:1,defaultStyle:{fill:!0,fillOpacity:.9},draw:t=>{const e=t.rc.dpr,{x:n,y:s}=t.pts[0],o=16*e,l=6*e,r=i?1:-1,a=s+2*r*e;t.ctx.beginPath(),t.ctx.moveTo(n,a),t.ctx.lineTo(n-l,a+r*l),t.ctx.lineTo(n-l/2.4,a+r*l),t.ctx.lineTo(n-l/2.4,a+r*o),t.ctx.lineTo(n+l/2.4,a+r*o),t.ctx.lineTo(n+l/2.4,a+r*l),t.ctx.lineTo(n+l,a+r*l),t.ctx.closePath(),t.ctx.save(),t.ctx.globalAlpha=t.style.fillOpacity??.9,t.ctx.fillStyle=m(t),t.ctx.fill(),t.ctx.restore(),g(t),t.ctx.stroke(),t.ctx.setLineDash([])},distance:(t,e,n)=>{const s=n.pts[0],o=i?e-s.y:s.y-e;return Math.abs(t-s.x)<=8&&o>=-4&&o<=20?0:null}}}const Pt=St("arrow-up","Arrow Up",!0),Lt=St("arrow-down","Arrow Down",!1),kt={id:"highlighter",name:"Highlighter",points:0,freehand:!0,defaultStyle:{lineWidth:12,fillOpacity:.28},draw:t=>{if(t.pts.length<2)return;const e=t.rc.dpr;t.ctx.save(),t.ctx.globalAlpha=t.style.fillOpacity??.28,t.ctx.strokeStyle=t.style.color,t.ctx.lineWidth=Math.max(2,(t.style.lineWidth||12)*e),t.ctx.lineCap="round",t.ctx.lineJoin="round",t.ctx.beginPath(),t.ctx.moveTo(t.pts[0].x,t.pts[0].y);for(let e=1;e<t.pts.length;e++)t.ctx.lineTo(t.pts[e].x,t.pts[e].y);t.ctx.stroke(),t.ctx.restore()},distance:(t,e,i)=>{const n=s(t,e,i.pts);return n<=Math.max(6,(i.drawing.style.lineWidth??12)/2)?0:n}},Dt={id:"fib-channel",name:"Fib Channel",points:3,defaultStyle:{showLabels:!0,levels:[...k]},draw:t=>{const e=t.style.levels??k,[i,n,s]=t.pts,o=s.x-n.x,l=s.y-n.y;g(t);for(const s of e)t.ctx.beginPath(),t.ctx.moveTo(i.x+o*s,i.y+l*s),t.ctx.lineTo(n.x+o*s,n.y+l*s),t.ctx.stroke(),!1!==t.style.showLabels&&_(t,`${(100*s).toFixed(1)}%`,n.x+o*s+4*t.rc.dpr,n.y+l*s);t.ctx.setLineDash([])},distance:(e,i,n)=>{const s=n.drawing.style.levels??k,[o,l,r]=n.pts;let a=1/0;for(const n of s){const s=t(e,i,{x:o.x+(r.x-l.x)*n,y:o.y+(r.y-l.y)*n},{x:l.x+(r.x-l.x)*n,y:l.y+(r.y-l.y)*n});s<a&&(a=s)}return a}},$t=[0,1,2,3,5,8,13,21,34,55],Ot={id:"fib-time-zone",name:"Fib Time Zone",points:2,defaultStyle:{showLabels:!0},draw:t=>{const[e,i]=t.pts,n=i.x-e.x;if(Math.abs(n)<.5)return;const s=t.rc.dpr,o=t.rc.plotWidth*s;g(t);for(const i of $t){const l=e.x+n*i;l<-10||l>o+10||(t.ctx.beginPath(),t.ctx.moveTo(Math.round(l)+.5,0),t.ctx.lineTo(Math.round(l)+.5,t.rc.plotHeight*s),t.ctx.stroke(),!1!==t.style.showLabels&&_(t,String(i),l+3*s,12*s))}t.ctx.setLineDash([])},distance:(t,e,i)=>{const[n,s]=i.pts,o=s.x-n.x;if(Math.abs(o)<.5)return null;let l=1/0;for(const e of $t)l=Math.min(l,Math.abs(t-(n.x+o*e)));return l}},Ft=[.236,.382,.5,.618,.786,1],At={id:"fib-fan",name:"Fib Speed Fan",points:2,defaultStyle:{showLabels:!0,levels:[...Ft]},draw:t=>{const e=t.style.levels??Ft,[i,n]=t.pts,s=t.rc.dpr,o=t.rc.plotWidth*s;g(t);for(const l of e){const e=a(i,{x:n.x,y:i.y+(n.y-i.y)*l},o,!1,!0)[1];t.ctx.beginPath(),t.ctx.moveTo(i.x,i.y),t.ctx.lineTo(e.x,e.y),t.ctx.stroke(),!1!==t.style.showLabels&&_(t,`${(100*l).toFixed(1)}%`,n.x+4*s,i.y+(n.y-i.y)*l)}t.ctx.setLineDash([])},distance:(e,i,n)=>{const s=n.drawing.style.levels??Ft,[o,l]=n.pts;let r=1/0;for(const c of s)r=Math.min(r,t(e,i,o,a(o,{x:l.x,y:o.y+(l.y-o.y)*c},n.rc.plotWidth,!1,!0)[1]));return r}},Nt=[[1,.125],[1,.25],[1,.5],[1,1],[.5,1],[.25,1],[.125,1]],Wt=[$,O,F,A,N,W,C,I,R,z,j,B,H,Y,V,bt,J,gt,mt,_t,wt,Mt,vt,Tt,st,lt,Pt,Lt,kt,nt,Dt,Ot,At,{id:"gann-fan",name:"Gann Fan",points:2,defaultStyle:{showLabels:!0},draw:t=>{const[e,i]=t.pts,n=t.rc.dpr,s=t.rc.plotWidth*n,o=i.x-e.x,l=i.y-e.y;if(!(Math.abs(o)<.5)){g(t);for(const[i,n]of Nt){const r=a(e,{x:e.x+o*i,y:e.y+l*n},s,!1,!0)[1];t.ctx.beginPath(),t.ctx.moveTo(e.x,e.y),t.ctx.lineTo(r.x,r.y),t.ctx.stroke()}!1!==t.style.showLabels&&_(t,"1x1",i.x+4*n,i.y),t.ctx.setLineDash([])}},distance:(e,i,n)=>{const[s,o]=n.pts,l=o.x-s.x,r=o.y-s.y;let c=1/0;for(const[o,h]of Nt)c=Math.min(c,t(e,i,s,a(s,{x:s.x+l*o,y:s.y+r*h},n.rc.plotWidth,!1,!0)[1]));return c}},{id:"gann-box",name:"Gann Box",points:2,defaultStyle:{fill:!0,fillOpacity:.05},draw:t=>{const e=o(t.pts[0],t.pts[1]);b(t,()=>t.ctx.fillRect(e.x0,e.y0,e.x1-e.x0,e.y1-e.y0)),g(t);const i=e.x1-e.x0,n=e.y1-e.y0;t.ctx.beginPath();for(let s=0;s<=8;s++){const o=Math.round(e.x0+i*s/8)+.5,l=Math.round(e.y0+n*s/8)+.5;t.ctx.moveTo(o,e.y0),t.ctx.lineTo(o,e.y1),t.ctx.moveTo(e.x0,l),t.ctx.lineTo(e.x1,l)}t.ctx.moveTo(e.x0,e.y1),t.ctx.lineTo(e.x1,e.y0),t.ctx.stroke(),t.ctx.setLineDash([])},distance:(t,e,i)=>l(t,e,i.pts[0],i.pts[1],!0===i.drawing.style.fill)},rt,at,ct,tt,it,xt,dt,ft];let Ct=!1;function It(){if(!Ct){Ct=!0;for(const t of Wt)p(t)}}function Rt(t,e){return u(t)&&!0===y(t).freehand&&e>2?[0,e-1]:Array.from({length:e},(t,e)=>e)}class zt{constructor(){Object.defineProperty(this,"_drawings",{enumerable:!0,configurable:!0,writable:!0,value:[]}),Object.defineProperty(this,"_host",{enumerable:!0,configurable:!0,writable:!0,value:null}),Object.defineProperty(this,"_selected",{enumerable:!0,configurable:!0,writable:!0,value:null}),Object.defineProperty(this,"_preview",{enumerable:!0,configurable:!0,writable:!0,value:null})}attached(t){this._host=t}detached(){this._host=null}zOrder(){return"top"}autoscaleInfo(){return null}setDrawings(t){this._drawings=t.slice(),this._host?.requestUpdate()}setSelected(t){t!==this._selected&&(this._selected=t,this._host?.requestUpdate())}setPreview(t){this._preview=t,this._host?.requestUpdate()}_project(t,e,i){return{x:t.timeScale.indexToX(t.dataLayer.timeToIndexFloat(e)),y:t.priceScale.priceToY(i)}}_points(t,e){return e.points.map(e=>this._project(t,e.time,e.price))}draw(t,e){const i=null===this._preview?this._drawings:[...this._drawings,this._preview];for(const n of i){if(!1===n.visible||!u(n.tool))continue;const i=y(n.tool);if(n.points.length<Math.max(1,i.points))continue;const s=this._points(e,n);if(!s.some(t=>Number.isFinite(t.x)&&Number.isFinite(t.y)))continue;const o={color:n.style.color??e.theme.lineColor,lineWidth:n.style.lineWidth??1.5,...n.style},l=e.dpr;t.save(),n===this._preview&&(t.globalAlpha=.7),i.draw({ctx:t,rc:e,drawing:n,selected:n.id===this._selected,pts:s.map(t=>({x:t.x*l,y:t.y*l})),style:{...o,color:o.color,lineWidth:o.lineWidth},formatPrice:t=>e.priceScale.format(t)}),t.restore(),n.id===this._selected&&!0!==n.locked&&this._drawHandles(t,e,s,n.tool)}}_drawHandles(t,e,i,n){const s=e.dpr;t.save(),t.setLineDash([]),t.lineWidth=Math.max(1,Math.round(1.5*s));for(const o of Rt(n,i.length)){const n=i[o];t.beginPath(),t.arc(n.x*s,n.y*s,5*s,0,2*Math.PI),t.fillStyle=e.theme.background,t.fill(),t.strokeStyle=e.theme.lineColor,t.stroke()}t.restore()}hitTest(t,e,i){if(null!==this._selected){const n=this._drawings.find(t=>t.id===this._selected);if(void 0!==n&&!0!==n.locked){const s=this._points(i,n);for(const i of Rt(n.tool,s.length))if(Math.hypot(t-s[i].x,e-s[i].y)<=7)return{externalId:`draw:${n.id}#${i}`,zOrder:"top",distance:0,cursor:"grabbing",draggable:!0}}}let n=null;for(let s=this._drawings.length-1;s>=0;s--){const o=this._drawings[s];if(!1===o.visible||!0===o.locked||!u(o.tool))continue;const l=y(o.tool);if(o.points.length<Math.max(1,l.points))continue;const r=l.distance(t,e,{pts:this._points(i,o),drawing:o,rc:i});null===r||!Number.isFinite(r)||r>6||(null===n||r<n.distance)&&(n={id:o.id,distance:r})}return null===n?null:{externalId:`draw:${n.id}`,zOrder:"top",distance:n.distance,cursor:"move",draggable:!0}}}let jt=1;class Ut{constructor(t,e={}){Object.defineProperty(this,"_chart",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"_opts",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"_layers",{enumerable:!0,configurable:!0,writable:!0,value:new Map}),Object.defineProperty(this,"_drawings",{enumerable:!0,configurable:!0,writable:!0,value:[]}),Object.defineProperty(this,"_tool",{enumerable:!0,configurable:!0,writable:!0,value:null}),Object.defineProperty(this,"_pending",{enumerable:!0,configurable:!0,writable:!0,value:[]}),Object.defineProperty(this,"_pendingPane",{enumerable:!0,configurable:!0,writable:!0,value:0}),Object.defineProperty(this,"_selected",{enumerable:!0,configurable:!0,writable:!0,value:null}),Object.defineProperty(this,"_undo",{enumerable:!0,configurable:!0,writable:!0,value:[]}),Object.defineProperty(this,"_redo",{enumerable:!0,configurable:!0,writable:!0,value:[]}),Object.defineProperty(this,"_dragStart",{enumerable:!0,configurable:!0,writable:!0,value:null}),Object.defineProperty(this,"_off",{enumerable:!0,configurable:!0,writable:!0,value:[]}),Object.defineProperty(this,"_lastCursor",{enumerable:!0,configurable:!0,writable:!0,value:null}),Object.defineProperty(this,"_lastBar",{enumerable:!0,configurable:!0,writable:!0,value:null}),this._chart=t,this._opts={magnet:e.magnet??!1,stayInDrawingMode:e.stayInDrawingMode??!1,historyLimit:e.historyLimit??50,defaultStyle:e.defaultStyle??{}},this._off.push(t.on("click",t=>this._onClick(t))),this._off.push(t.on("crosshair:move",t=>this._onCrosshair(t))),this._off.push(t.on("drag",t=>this._onDrag(t))),this._off.push(t.on("drag:end",()=>this._onDragEnd())),this._off.push(t.on("dblclick",()=>{this.finish()}));const i=t.drawingState();Array.isArray(i)&&(this._drawings=i.map(t=>({...t}))),this._sync()}setTool(t){if(null!==t&&!u(t))throw new Error(`openalgo-charts: unknown drawing tool "${t}"`);this._tool=t,this._pending=[],this._setPlacementMode(null!==t),this._syncPreview(),this._chart.emit("draw:tool",{tool:t})}_setPlacementMode(t){const e=this._chart;e.setPlacementMode?.(t)}activeTool(){return this._tool}setOptions(t){this._opts={...this._opts,...t,defaultStyle:t.defaultStyle??this._opts.defaultStyle}}drawings(){return this._drawings}get(t){return this._drawings.find(e=>e.id===t)}add(t){this._pushUndo();const e=y(t.tool),i={...t,id:t.id??"d"+jt++,style:{...this._opts.defaultStyle,...e.defaultStyle,...t.style}};return this._drawings.push(i),this._sync(),this._chart.emit("draw:add",{drawing:i}),i}update(t,e){const i=this.get(t);return void 0!==i&&(this._pushUndo(),void 0!==e.points&&(i.points=e.points.map(t=>({...t}))),void 0!==e.style&&(i.style={...i.style,...e.style}),void 0!==e.locked&&(i.locked=e.locked),void 0!==e.visible&&(i.visible=e.visible),this._sync(),this._chart.emit("draw:update",{drawing:i}),!0)}remove(t){const e=this._drawings.findIndex(e=>e.id===t);if(e<0)return!1;this._pushUndo();const[i]=this._drawings.splice(e,1);return this._selected===t&&(this._selected=null),this._sync(),this._chart.emit("draw:remove",{drawing:i}),!0}clear(){0!==this._drawings.length&&(this._pushUndo(),this._drawings=[],this._selected=null,this._sync())}select(t){this._selected=t;for(const e of this._layers.values())e.setSelected(t);this._chart.emit("draw:select",{id:t})}selected(){return this._selected}undo(){const t=this._undo.pop();return void 0!==t&&(this._redo.push(JSON.stringify(this._drawings)),this._drawings=JSON.parse(t),this._drawings.some(t=>t.id===this._selected)||(this._selected=null),this._sync(),!0)}redo(){const t=this._redo.pop();return void 0!==t&&(this._undo.push(JSON.stringify(this._drawings)),this._drawings=JSON.parse(t),this._sync(),!0)}canUndo(){return this._undo.length>0}canRedo(){return this._redo.length>0}toJSON(){return this._drawings.map(t=>({...t,points:t.points.map(t=>({...t})),style:{...t.style}}))}fromJSON(t){this._drawings=Array.isArray(t)?t.map(t=>({...t})):[],this._selected=null,this._undo=[],this._redo=[],this._sync()}destroy(){this._setPlacementMode(!1);for(const t of this._off)t();this._off.length=0;for(const[t,e]of this._layers)this._chart.removePrimitive(e);this._layers.clear()}_onCrosshair(t){const e=t.time,i=t.price,n=t.paneIndex??null;this._lastCursor=null===e||null===i||null===n?null:{time:e,price:i,paneIndex:n},this._lastBar=t.bar??null,null!==this._tool&&!0===t.pressed&&this._isFreehand()&&null!==e&&null!==i&&null!==n&&Number.isFinite(e)&&Number.isFinite(i)?this._inkPoint({time:e,price:i},n):null!==this._tool&&this._pending.length>0&&this._syncPreview()}_expand(t,e){if(void 0===t.expand)return e;const i=this._chart.dataLayer,n=i.baseIndex,s=n>0?i.indexToTime(n-1):void 0,o=n>=0?i.indexToTime(n):void 0,l=void 0!==s&&void 0!==o&&o>s?o-s:60,r=this._chart.getVisibleLogicalRange(),a=null===r?60:Math.max(1,r.to-r.from);return t.expand(e,{barSeconds:l,visibleBars:a})}_isFreehand(){return null!==this._tool&&!0===y(this._tool).freehand}_inkPoint(t,e){if(0===this._pending.length)this._pendingPane=e;else{if(e!==this._pendingPane)return;{const e=this._pending[this._pending.length-1];if(e.time===t.time&&e.price===t.price)return}}this._pending.push(t),this._syncPreview()}_commit(t){const e=y(this._tool),i=this.add({tool:e.id,points:t,style:{},paneIndex:this._pendingPane});this._pending=[],this._opts.stayInDrawingMode||(this._tool=null,this._setPlacementMode(!1)),this._syncPreview(),this.select(i.id),this._chart.emit("draw:tool",{tool:this._tool})}_finishFreehand(){const t=this._pending;this._pending=[],t.length<2?this._syncPreview():this._commit(t)}finish(){if(null===this._tool||0===this._pending.length)return!1;const t=y(this._tool);if(0!==t.points||!0===t.freehand)return!1;const e=this._pending;return e.length<2?(this._pending=[],this._syncPreview(),!1):(this._commit(e),!0)}_onClick(t){if(null===this._tool)null!==t.id&&t.id.startsWith("draw:")?this.select(t.id.slice(5).split("#")[0]):null===t.id&&this.select(null);else{if(this._isFreehand())return void(!0===t.viaDrag&&this._finishFreehand());if(!0===t.viaDrag&&0===this._pending.length)return;if(null===t.price||!Number.isFinite(t.price)||!Number.isFinite(t.time))return;this._placePoint({time:t.time,price:this._snap(t.price,t.paneIndex)},t.paneIndex)}}_placePoint(t,e){0===this._pending.length&&(this._pendingPane=e),this._pending.push(t);const i=y(this._tool);i.points>0&&this._pending.length>=i.points?this._commit(this._expand(i,this._pending)):this._syncPreview()}_snap(t,e){if(!this._opts.magnet||0!==e)return t;const i=this._lastBar;if(null===i)return t;let n=t,s=1/0;for(const e of[i.open,i.high,i.low,i.close]){const i=Math.abs(e-t);i<s&&(s=i,n=e)}return n}_onDrag(t){if(!t.id.startsWith("draw:"))return;const[e,i]=t.id.slice(5).split("#"),n=this.get(e);if(void 0===n||!0===n.locked)return;const s=void 0===i?null:Number(i);null!==this._dragStart&&this._dragStart.id===e&&this._dragStart.handle===s||(this._pushUndo(),this._dragStart={id:e,handle:s,points:n.points.map(t=>({...t})),from:{time:t.fromTime??t.time,price:t.fromPrice??t.price}});const o=this._dragStart;if(null===s){const e=t.time-o.from.time,i=t.price-o.from.price;n.points=o.points.map(t=>({time:t.time+e,price:t.price+i}))}else s>=0&&s<n.points.length&&(n.points=o.points.map((e,i)=>i===s?{time:t.time,price:t.price}:{...e}));this._sync()}_onDragEnd(){if(null===this._dragStart)return;const t=this.get(this._dragStart.id);this._dragStart=null,void 0!==t&&this._chart.emit("draw:update",{drawing:t})}_layerFor(t){let e=this._layers.get(t);return void 0===e&&(e=new zt,this._chart.addPrimitive(e,t),this._layers.set(t,e)),e}_sync(){const t=new Map;for(const e of this._drawings){const i=t.get(e.paneIndex)??[];i.push(e),t.set(e.paneIndex,i)}for(const[e,i]of t)this._layerFor(e).setDrawings(i);for(const[e,i]of this._layers)t.has(e)||i.setDrawings([]),i.setSelected(this._selected);this._chart.setDrawingState(this.toJSON())}_syncPreview(){for(const t of this._layers.values())t.setPreview(null);if(null===this._tool||0===this._pending.length)return;const t=this._lastCursor,e=null===t?this._pending:[...this._pending,{time:t.time,price:t.price}];this._layerFor(this._pendingPane).setPreview({id:"__preview",tool:this._tool,points:e,style:this._opts.defaultStyle,paneIndex:this._pendingPane})}_pushUndo(){this._undo.push(JSON.stringify(this._drawings)),this._undo.length>this._opts.historyLimit&&this._undo.shift(),this._redo=[]}}const Bt="draw";It();export{A as ARROW,Wt as BUILTIN_DRAWING_TOOLS,I as CROSS_LINE,Bt as DRAW_TIER,Ut as DrawingController,zt as DrawingLayer,z as ELLIPSE,F as EXTENDED_LINE,H as FIB_EXTENSION,B as FIB_RETRACEMENT,N as HORIZONTAL_LINE,W as HORIZONTAL_RAY,Y as LONG_POSITION,J as MEASURE,j as PARALLEL_CHANNEL,it as PATH,O as RAY,R as RECTANGLE,V as SHORT_POSITION,tt as TEXT,$ as TREND_LINE,C as VERTICAL_LINE,r as distToEllipse,e as distToLine,s as distToPolyline,l as distToRect,t as distToSegment,a as extendSegment,y as getDrawingTool,u as hasDrawingTool,o as rectOf,It as registerBuiltinDrawingTools,p as registerDrawingTool,f as registeredDrawingTools};
|
|
2
2
|
//# sourceMappingURL=openalgo-charts.draw.mjs.map
|