openalgo-charts 1.0.12 → 1.0.13

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/README.md CHANGED
@@ -62,12 +62,12 @@ Import only what you use. Each tier is a separate bundle that registers into the
62
62
  |---|---|---|
63
63
  | `openalgo-charts` | Engine, 13 chart types, panes & scales, primitives, registries, chart state, trading overlay, OpenAlgo feeds | 34.6 KB |
64
64
  | `openalgo-charts/indicators` | 18 built-in indicators + the Tier-2 (external-data) contract | 4.5 KB |
65
- | `openalgo-charts/draw` | 34 drawing tools + a headless drawing controller | 8.3 KB |
65
+ | `openalgo-charts/draw` | 43 drawing tools + a headless drawing controller | 11.3 KB |
66
66
  | `openalgo-charts/transform` | Heikin Ashi, Renko, Range bars, Line Break, Point & Figure, Kagi | 2.7 KB |
67
67
  | `openalgo-charts/profile` | Volume Profile, Market Profile (TPO), Footprint, order flow | 10.1 KB |
68
68
  | `openalgo-charts/trade` | Order / position / bracket tools + DOM ladder | 6.6 KB |
69
69
 
70
- Everything together is **66.7 KB Brotli**.
70
+ Everything together is **69.8 KB Brotli**.
71
71
 
72
72
  ## What's built
73
73
 
@@ -97,7 +97,7 @@ const draw = new DrawingController(chart, { magnet: true });
97
97
  draw.setTool('trend-line'); // the next two clicks place it
98
98
  ```
99
99
 
100
- 34 tools. Lines: trend line, ray, extended line, arrow, horizontal line/ray, vertical line, cross line. Shapes: rectangle, ellipse, circle, triangle. Paths: polyline, arc, curve. Channels: parallel channel, fib channel. Fibonacci: retracement, extension, time zone, speed fan. Gann: fan, box. Forecasting: long/short position (with R:R and risk-based sizing), forecast. Measurers: price range, date range, measure. Arrows: mark up, mark down. Annotation: text, brush, highlighter.
100
+ 43 tools. Lines: trend line, ray, extended line, arrow, horizontal line/ray, vertical line, cross line. Shapes: rectangle, rotated rectangle, ellipse, circle, triangle. Paths: path, polyline, arc, curve, double curve. Channels: parallel channel, fib channel. Fibonacci: retracement, extension, time zone, speed fan. Gann: fan, box. Cycles: cyclic lines, time cycles, sine line. Forecasting: long/short position (1:1 from one click, with risk/reward and risk-based sizing), forecast. Measurers: price range, date range, measure. Arrows: mark up, mark down. Text and notes: text, price label, callout, flag mark. Brushes: brush, highlighter (freehand).
101
101
 
102
102
  Headless by design — no toolbar, no dialogs. Placement with live preview, selection, whole-shape and per-anchor dragging, magnet snap to O/H/L/C, undo/redo (a drag is one step), and persistence. Anchors are `{ time, price }`, never pixels, so they survive zoom and resolve inside collapsed session gaps and past the last bar.
103
103
 
@@ -313,6 +313,12 @@ interface PrimitiveRenderContext {
313
313
  priceAxisWidth: number;
314
314
  dpr: number;
315
315
  theme: ChartTheme;
316
+ /**
317
+ * The pane's primary price series, for a primitive that needs what price
318
+ * actually did rather than just the scales — a forecast scoring itself, say.
319
+ * Lazy, so nothing pays for it unless asked. Absent on synthetic contexts.
320
+ */
321
+ bars?: () => readonly Bar[];
316
322
  /** externalId of the primitive hit under the pointer (hover state), if any. */
317
323
  hoverId?: string | null;
318
324
  /** externalId of the line being dragged (active state), if any. */
@@ -457,6 +463,16 @@ interface HitContext {
457
463
  drawing: Drawing;
458
464
  rc: PrimitiveRenderContext;
459
465
  }
466
+ /** What {@link DrawingTool.expand} needs to size a default in chart units. */
467
+ interface ExpandContext {
468
+ /** Seconds between adjacent bars, so a default can span a sane bar count. */
469
+ barSeconds: number;
470
+ /**
471
+ * Bars currently on screen. A default sized in fixed bars is a hairline when
472
+ * zoomed out and fills the pane when zoomed in, so size against this instead.
473
+ */
474
+ visibleBars: number;
475
+ }
460
476
  interface DrawingTool {
461
477
  id: string;
462
478
  name: string;
@@ -465,6 +481,23 @@ interface DrawingTool {
465
481
  * drawing finishes on double-click.
466
482
  */
467
483
  points: number;
484
+ /**
485
+ * Sample the cursor continuously while the pointer is held, and finish on
486
+ * release — one press-drag-release gesture is one stroke. Brushes want this;
487
+ * without it a `points: 0` tool collects a vertex per click, which is
488
+ * polyline behaviour and never terminates on its own.
489
+ */
490
+ freehand?: boolean;
491
+ /**
492
+ * Turn the anchors actually clicked into the full anchor set. Lets a tool drop
493
+ * a complete, immediately editable default from fewer clicks — the position
494
+ * tools place a 1:1 box off a single click, which the user then drags, rather
495
+ * than demanding entry/target/stop be clicked in turn.
496
+ *
497
+ * The returned points become the drawing's anchors, so each one stays a
498
+ * draggable handle.
499
+ */
500
+ expand?(clicked: readonly DrawingPoint[], ctx: ExpandContext): DrawingPoint[];
468
501
  /** Merged under the caller's style when a drawing is created. */
469
502
  defaultStyle?: DrawingStyle;
470
503
  draw(c: DrawContext): void;
@@ -505,6 +538,10 @@ declare const MEASURE: DrawingTool;
505
538
  declare const LONG_POSITION: DrawingTool;
506
539
  declare const SHORT_POSITION: DrawingTool;
507
540
  declare const TEXT: DrawingTool;
541
+ /**
542
+ * Path — click each vertex, double-click to finish, arrowhead on the last leg.
543
+ * The arrow is what separates it from `polyline`: a path points somewhere.
544
+ */
508
545
  declare const PATH: DrawingTool;
509
546
  declare const BUILTIN_DRAWING_TOOLS: readonly DrawingTool[];
510
547
  /** Register every built-in tool. Idempotent; called on tier import. */
@@ -2098,6 +2135,31 @@ declare class DrawingController {
2098
2135
  fromJSON(data: unknown): void;
2099
2136
  destroy(): void;
2100
2137
  private _onCrosshair;
2138
+ /**
2139
+ * Let a tool turn the clicked anchors into its full set (the position tools
2140
+ * build a 1:1 box off one click). Identity for tools without the hook.
2141
+ */
2142
+ private _expand;
2143
+ private _isFreehand;
2144
+ /**
2145
+ * Append one sample to the stroke in progress. Points arriving closer than a
2146
+ * bar-eighth apart in time carry no shape and would bloat the saved drawing,
2147
+ * so they collapse into the last one — a pointer can fire far faster than the
2148
+ * stroke actually changes direction.
2149
+ */
2150
+ private _inkPoint;
2151
+ /** Commit `pts` as a drawing of the armed tool and leave placement. */
2152
+ private _commit;
2153
+ /** Commit the stroke a freehand gesture built, if it has any extent. */
2154
+ private _finishFreehand;
2155
+ /**
2156
+ * End a variable-anchor shape (polyline, path) at the anchors placed so far.
2157
+ * Those tools declare `points: 0`, so nothing else can ever complete them —
2158
+ * without this they collected vertices forever. Bound to double-click, and
2159
+ * public so a host can offer Esc / Enter too. No-op when there is nothing
2160
+ * placeable, so a stray double-click costs nothing.
2161
+ */
2162
+ finish(): boolean;
2101
2163
  private _onClick;
2102
2164
  private _placePoint;
2103
2165
  /** Snap to the nearest O/H/L/C of the hovered bar when magnet is on. */
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.12";
2
+ declare const VERSION = "1.0.13";
3
3
  /** Returns the current library version. */
4
4
  declare function version(): string;
5
5
 
@@ -528,6 +528,12 @@ interface PrimitiveRenderContext {
528
528
  priceAxisWidth: number;
529
529
  dpr: number;
530
530
  theme: ChartTheme;
531
+ /**
532
+ * The pane's primary price series, for a primitive that needs what price
533
+ * actually did rather than just the scales — a forecast scoring itself, say.
534
+ * Lazy, so nothing pays for it unless asked. Absent on synthetic contexts.
535
+ */
536
+ bars?: () => readonly Bar[];
531
537
  /** externalId of the primitive hit under the pointer (hover state), if any. */
532
538
  hoverId?: string | null;
533
539
  /** externalId of the line being dragged (active state), if any. */
@@ -1,2 +1,2 @@
1
- function t(t,e,i,s){const n=s.x-i.x,o=s.y-i.y,l=n*n+o*o;if(0===l)return Math.hypot(t-i.x,e-i.y);let r=((t-i.x)*n+(e-i.y)*o)/l;return r=r<0?0:r>1?1:r,Math.hypot(t-(i.x+r*n),e-(i.y+r*o))}function e(t,e,i,s){const n=s.x-i.x,o=s.y-i.y,l=Math.hypot(n,o);return 0===l?Math.hypot(t-i.x,e-i.y):Math.abs(o*(t-i.x)-n*(e-i.y))/l}function i(t,e){return Math.abs(t-e)}function s(t,e){return Math.abs(t-e)}function n(e,i,s){let n=1/0;for(let o=1;o<s.length;o++){const l=t(e,i,s[o-1],s[o]);l<n&&(n=l)}return n}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,s,n,l){const r=o(s,n);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 s=0;s<4;s++){const n=t(e,i,a[s],a[(s+1)%4]);n<c&&(c=n)}return c}function r(t,e,i,s,n){const l=o(i,s),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),d=(t-r)/c,x=(e-a)/h,p=Math.hypot(d,x);return n&&p<=1?0:Math.abs(p-1)*Math.min(c,h)}function a(t,e,i,s,n){const o=e.x-t.x;if(0===o)return[t,e];const l=(e.y-t.y)/o;return[s?{x:0,y:t.y+(0-t.x)*l}:t,n?{x:i,y:t.y+(i-t.x)*l}:e]}const c=new Map;function h(t){c.set(t.id,t)}function d(t){const e=c.get(t);if(void 0===e)throw new Error(`openalgo-charts: unknown drawing tool "${t}"`);return e}function x(t){return c.has(t)}function p(){return Array.from(c.values())}function y(t){const{ctx:e,rc:i,style:s}=t,n=i.dpr;e.strokeStyle=s.color,e.lineWidth=Math.max(1,Math.round(s.lineWidth*n)),e.lineJoin="round",e.lineCap="round",e.setLineDash("dashed"===s.lineStyle?[6*n,4*n]:"dotted"===s.lineStyle?[1*n,3*n]:[])}function u(t){return t.style.fillColor??t.style.color}function f(t,e){if(!0!==t.style.fill)return;const{ctx:i}=t;i.save(),i.globalAlpha=t.style.fillOpacity??.12,i.fillStyle=u(t),e(),i.restore()}function g(t,e,i,s,n){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,s-.75*a,c+4*l.dpr,1.5*a),o.globalAlpha=1,o.fillStyle=n??r.color,o.fillText(e,i,s),o.restore()}const m=[0,.236,.382,.5,.618,.786,1];function b(i,s,n,o){return{id:i,name:s,points:2,defaultStyle:{extendLeft:n,extendRight:o},draw:t=>{const[e,i]=a(t.pts[0],t.pts[1],t.rc.plotWidth*t.rc.dpr,t.style.extendLeft??n,t.style.extendRight??o);y(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,s,l)=>{const r=l.drawing.style.extendLeft??n,c=l.drawing.style.extendRight??o;if(r&&c)return e(i,s,l.pts[0],l.pts[1]);const[h,d]=a(l.pts[0],l.pts[1],l.rc.plotWidth,r,c);return t(i,s,h,d)}}}const _=b("trend-line","Trend Line",!1,!1),w=b("ray","Ray",!1,!0),v=b("extended-line","Extended Line",!0,!0),M={id:"arrow",name:"Arrow",points:2,draw:t=>{const[e,i]=t.pts;y(t),t.ctx.beginPath(),t.ctx.moveTo(e.x,e.y),t.ctx.lineTo(i.x,i.y),t.ctx.stroke();const s=Math.max(8,5*t.style.lineWidth)*t.rc.dpr,n=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-s*Math.cos(n-.4),i.y-s*Math.sin(n-.4)),t.ctx.lineTo(i.x-s*Math.cos(n+.4),i.y-s*Math.sin(n+.4)),t.ctx.closePath(),t.ctx.fillStyle=t.style.color,t.ctx.fill(),t.ctx.setLineDash([])},distance:(e,i,s)=>t(e,i,s.pts[0],s.pts[1])},T={id:"horizontal-line",name:"Horizontal Line",points:1,defaultStyle:{showLabels:!0},draw:t=>{const e=Math.round(t.pts[0].y)+.5;y(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&&g(t,t.formatPrice(t.drawing.points[0].price),4*t.rc.dpr,e-8*t.rc.dpr)},distance:(t,e,s)=>i(e,s.pts[0].y)},S={id:"horizontal-ray",name:"Horizontal Ray",points:1,defaultStyle:{showLabels:!0},draw:t=>{const e=Math.round(t.pts[0].y)+.5;y(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&&g(t,t.formatPrice(t.drawing.points[0].price),t.pts[0].x+4*t.rc.dpr,e-8*t.rc.dpr)},distance:(t,e,s)=>t<s.pts[0].x?null:i(e,s.pts[0].y)},P={id:"vertical-line",name:"Vertical Line",points:1,draw:t=>{const e=Math.round(t.pts[0].x)+.5;y(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)=>s(t,i.pts[0].x)},L={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;y(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,n)=>Math.min(s(t,n.pts[0].x),i(e,n.pts[0].y))},k={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]);f(t,()=>t.ctx.fillRect(e.x0,e.y0,e.x1-e.x0,e.y1-e.y0)),y(t),t.ctx.strokeRect(e.x0,e.y0,e.x1-e.x0,e.y1-e.y0),t.ctx.setLineDash([]),J(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)},O={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,s=(e.y0+e.y1)/2,n=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,s,n,l,0,0,2*Math.PI)};f(t,()=>{r(),t.ctx.fill()}),y(t),r(),t.ctx.stroke(),t.ctx.setLineDash([]),J(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)},D={id:"parallel-channel",name:"Parallel Channel",points:3,defaultStyle:{fill:!0},draw:t=>{const[e,i,s]=t.pts,n=s.y-(e.y+.5*(i.y-e.y)),o={x:e.x,y:e.y+n},l={x:i.x,y:i.y+n};f(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()}),y(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([]),J(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,s)=>{const[n,o,l]=s.pts,r=l.y-(n.y+.5*(o.y-n.y)),a=t(e,i,n,o),c=t(e,i,{x:n.x,y:n.y+r},{x:o.x,y:o.y+r});return Math.min(a,c)}};function $(t,e,i){return{id:t,name:e,points:i,defaultStyle:{showLabels:!0,levels:[...m],fill:!0,fillOpacity:.06},draw:t=>{const e=t.style.levels??m,s=t.drawing.points,n=2===i?s[0].price:s[2].price,o=s[1].price-s[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;y(t);let c=null;for(const i of e){const e=n+o*i,s=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=u(t),t.ctx.fillRect(l,Math.min(c,s),a-l,Math.abs(s-c)),t.ctx.restore()),c=s,t.ctx.beginPath(),t.ctx.moveTo(l,s),t.ctx.lineTo(a,s),t.ctx.stroke(),!1!==t.style.showLabels&&g(t,`${(100*i).toFixed(1)}% ${t.formatPrice(e)}`,l+4*t.rc.dpr,s-8*t.rc.dpr)}t.ctx.setLineDash([])},distance:(t,e,s)=>{const n=s.drawing.style.levels??m,o=s.drawing.points,l=2===i?o[0].price:o[2].price,r=o[1].price-o[0].price,a=Math.min(s.pts[0].x,s.pts[i-1].x),c=!0===s.drawing.style.extendRight?s.rc.plotWidth:Math.max(s.pts[0].x,s.pts[i-1].x);if(t<a-4||t>c+4)return null;let h=1/0;for(const t of n){const i=Math.abs(e-s.rc.priceScale.priceToY(l+r*t));i<h&&(h=i)}return h}}}const A=$("fib-retracement","Fib Retracement",2),W=$("fib-extension","Fib Extension",3),F={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,s=i[1].price-i[0].price,n=0!==i[0].price?s/i[0].price*100:0,l=s>=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(),y(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)),d=l?"+":"";g(t,`${d}${t.formatPrice(s)} (${d}${n.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 R(t,e,i){return{id:t,name:e,points:3,defaultStyle:{showLabels:!0,fillOpacity:.13,accountSize:1e5,risk:1},draw:t=>{const[e,s,n]=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(s.price)*o,h=t.rc.priceScale.priceToY(n.price)*o,d=(e,i,s)=>{t.ctx.save(),t.ctx.globalAlpha=t.style.fillOpacity??.13,t.ctx.fillStyle=s,t.ctx.fillRect(l,Math.min(e,i),r-l,Math.abs(i-e)),t.ctx.restore()};d(a,c,"#26a69a"),d(a,h,"#ef5350"),y(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 x=Math.abs(e.price-n.price),p=Math.abs(s.price-e.price),u=x>0?p/x:0,f=t.style.accountSize??0,m=t.style.risk??0,b=x>0&&f>0?Math.floor(f*m/100/x):0;g(t,`${i?"LONG":"SHORT"} R:R ${u.toFixed(2)}${b>0?` qty ${b}`:""}`,l+4*o,a-10*o)},distance:(t,e,i)=>{const s=Math.min(i.pts[0].x,i.pts[1].x,i.pts[2].x),n=Math.max(i.pts[0].x,i.pts[1].x,i.pts[2].x);if(t<s-4||t>n+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 I=R("long-position","Long Position",!0),C=R("short-position","Short Position",!1),j=1.35,z="ui-sans-serif, system-ui, -apple-system, Segoe UI, Roboto, sans-serif";function N(t,e){const i="bold"===t.fontWeight?"700 ":"";return`${"italic"===t.fontStyle?"italic ":""}${i}${e}px ${t.fontFamily??z}`}function U(t,e,i){const s=(e.text??"").split("\n");if(!0!==e.wrap)return s;const n=[];for(const e of s){const s=e.split(/\s+/).filter(t=>""!==t);if(0===s.length){n.push("");continue}let o=s[0];for(let e=1;e<s.length;e++){const l=`${o} ${s[e]}`;t.measureText(l).width>i?(n.push(o),o=s[e]):o=l}n.push(o)}return n}function H(t,e,i){const s=(e.fontSize??13)*i;t.font=N(e,s);const n=U(t,e,(e.wrapWidth??220)*i);let o=0;for(const e of n)o=Math.max(o,t.measureText(e).width);const l=s*j;return{lines:n,width:o+10*i,height:n.length*l+10*i,lineHeight:l}}function J(t,e,i,s,n){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,d=6*c;o.save(),o.setLineDash([]),o.font=N(r,h),o.fillStyle=r.fontColor??r.color,o.textBaseline="top";const x=!0===r.wrap?U(o,r,Math.max(20*c,s-e-2*d)):a.split("\n"),p=h*j,y=x.length*p,u=r.textAlign??"left";o.textAlign=u;const f="center"===u?(e+s)/2:"right"===u?s-d:e+d;let g;if("outside"===r.textPosition)g=i-y-d;else{const t=r.textVAlign??"top";g="middle"===t?(i+n-y)/2:"bottom"===t?n-y-d:i+d}for(const t of x)o.fillText(t,f,g),g+=p;o.restore()}const E={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:s}=t,n=i.dpr,o=H(e,s,n),l=t.pts[0].x,r=t.pts[0].y;e.save(),e.setLineDash([]),!0===s.background&&(e.globalAlpha=s.backgroundOpacity??1,e.fillStyle=s.backgroundColor??i.theme.background,e.beginPath(),e.roundRect(l,r,o.width,o.height,4*n),e.fill(),e.globalAlpha=1),!0===s.border&&(e.strokeStyle=s.borderColor??s.color,e.lineWidth=Math.max(1,s.lineWidth*n),e.beginPath(),e.roundRect(l,r,o.width,o.height,4*n),e.stroke()),e.font=N(s,(s.fontSize??13)*n),e.fillStyle=s.color,e.textBaseline="top";const a=s.textAlign??"left";e.textAlign=a;const c="center"===a?l+o.width/2:"right"===a?l+o.width-5*n:l+5*n;let h=r+5*n;for(const t of o.lines)e.fillText(t,c,h),h+=o.lineHeight;e.restore()},distance:(t,e,i)=>{const s=i.drawing.style,n=s.fontSize??13,o=i.pts[0],l=function(){if(void 0!==B)return B;try{B="undefined"==typeof document?null:document.createElement("canvas").getContext("2d")}catch{B=null}return B}(),r=null===l?{width:(s.text??"").length*n*.6+10,height:n*j+10}:H(l,s,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 B;const Y={id:"path",name:"Path",points:0,draw:t=>{if(!(t.pts.length<2)){y(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([])}},distance:(t,e,i)=>i.pts.length<2?null:n(t,e,i.pts)},q={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,s=i[1].price-i[0].price,n=0!==i[0].price?s/i[0].price*100:0,o=s>=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(),y(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 d=(r+a)/2;t.ctx.moveTo(d,c),t.ctx.lineTo(d,h);const x=h>c?1:-1;t.ctx.moveTo(d-4*e,h-5*e*x),t.ctx.lineTo(d,h),t.ctx.lineTo(d+4*e,h-5*e*x),t.ctx.moveTo(d-4*e,c+5*e*x),t.ctx.lineTo(d,c),t.ctx.lineTo(d+4*e,c+5*e*x),t.ctx.stroke(),t.ctx.setLineDash([]);const p=o?"+":"";g(t,`${p}${t.formatPrice(s)} (${p}${n.toFixed(2)}%)`,d+6*e,(c+h)/2,l)},distance:(t,e,i)=>l(t,e,i.pts[0],i.pts[1],!0)},V={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,s=t.style.color,n=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=s,t.ctx.fillRect(Math.min(n,o),l,Math.abs(o-n),r-l),t.ctx.restore(),y(t),t.ctx.beginPath();for(const e of[n,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(n,a),t.ctx.lineTo(o,a);const c=o>n?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(n+5*e*c,a-4*e),t.ctx.lineTo(n,a),t.ctx.lineTo(n+5*e*c,a+4*e),t.ctx.stroke(),t.ctx.setLineDash([]);const h=t.rc.dataLayer.timeToIndexFloat(i[0].time),d=t.rc.dataLayer.timeToIndexFloat(i[1].time);g(t,`${Math.abs(Math.round(d-h))} bars`,(n+o)/2,l-10*e,s)},distance:(t,e,i)=>l(t,e,i.pts[0],i.pts[1],!0)},G={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,[s,n]=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(n.y-s.y)+6*e;t.ctx.save(),t.ctx.globalAlpha=t.style.fillOpacity??.12,t.ctx.fillStyle=a,t.ctx.beginPath(),t.ctx.moveTo(s.x,s.y),t.ctx.lineTo(n.x,n.y-c),t.ctx.lineTo(n.x,n.y+c),t.ctx.closePath(),t.ctx.fill(),t.ctx.restore(),y(t),t.ctx.strokeStyle=a,t.ctx.beginPath(),t.ctx.moveTo(s.x,s.y),t.ctx.lineTo(n.x,n.y),t.ctx.stroke(),t.ctx.setLineDash([]),t.ctx.beginPath(),t.ctx.arc(s.x,s.y,3*e,0,2*Math.PI),t.ctx.fillStyle=a,t.ctx.fill();const h=t.rc.dataLayer.timeToIndexFloat(i[0].time),d=t.rc.dataLayer.timeToIndexFloat(i[1].time),x=Math.abs(Math.round(d-h)),p=r?"+":"";g(t,`${p}${t.formatPrice(o)} (${p}${l.toFixed(2)}%) ${x} bars`,n.x+6*e,n.y,a)},distance:(e,i,s)=>t(e,i,s.pts[0],s.pts[1])},X={id:"circle",name:"Circle",points:2,defaultStyle:{fill:!0},draw:t=>{const[e,i]=t.pts,s=Math.hypot(i.x-e.x,i.y-e.y);t.ctx.beginPath(),t.ctx.arc(e.x,e.y,s,0,2*Math.PI),f(t,()=>t.ctx.fill()),y(t),t.ctx.stroke(),t.ctx.setLineDash([])},distance:(t,e,i)=>{const[s,n]=i.pts,o=Math.hypot(n.x-s.x,n.y-s.y),l=Math.hypot(t-s.x,e-s.y);return!0===i.drawing.style.fill&&l<=o?0:Math.abs(l-o)}},Z={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(),f(t,()=>t.ctx.fill()),y(t),t.ctx.stroke(),t.ctx.setLineDash([])},distance:(t,e,i)=>n(t,e,[...i.pts,i.pts[0]])},K={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(),f(t,()=>t.ctx.fill())),y(t),t.ctx.stroke(),t.ctx.setLineDash([])}},distance:(t,e,i)=>n(t,e,i.pts)};const Q={id:"arc",name:"Arc",points:3,draw:t=>{const[e,i,s]=t.pts;y(t),t.ctx.beginPath(),t.ctx.moveTo(e.x,e.y),t.ctx.quadraticCurveTo(2*i.x-(e.x+s.x)/2,2*i.y-(e.y+s.y)/2,s.x,s.y),t.ctx.stroke(),t.ctx.setLineDash([])},distance:(t,e,i)=>n(t,e,function(t,e,i){const s=2*e.x-(t.x+i.x)/2,n=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*s+l*l*i.x,y:r*r*t.y+2*r*l*n+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,s]=t.pts;y(t),t.ctx.beginPath(),t.ctx.moveTo(e.x,e.y),t.ctx.quadraticCurveTo(i.x,i.y,s.x,s.y),t.ctx.stroke(),t.ctx.setLineDash([])},distance:(t,e,i)=>{const[s,o,l]=i.pts,r=[];for(let t=0;t<=16;t++){const e=t/16,i=1-e;r.push({x:i*i*s.x+2*i*e*o.x+e*e*l.x,y:i*i*s.y+2*i*e*o.y+e*e*l.y})}return n(t,e,r)}};function et(t,e,i){return{id:t,name:e,points:1,defaultStyle:{fill:!0,fillOpacity:.9},draw:t=>{const e=t.rc.dpr,{x:s,y:n}=t.pts[0],o=16*e,l=6*e,r=i?1:-1,a=n+2*r*e;t.ctx.beginPath(),t.ctx.moveTo(s,a),t.ctx.lineTo(s-l,a+r*l),t.ctx.lineTo(s-l/2.4,a+r*l),t.ctx.lineTo(s-l/2.4,a+r*o),t.ctx.lineTo(s+l/2.4,a+r*o),t.ctx.lineTo(s+l/2.4,a+r*l),t.ctx.lineTo(s+l,a+r*l),t.ctx.closePath(),t.ctx.save(),t.ctx.globalAlpha=t.style.fillOpacity??.9,t.ctx.fillStyle=u(t),t.ctx.fill(),t.ctx.restore(),y(t),t.ctx.stroke(),t.ctx.setLineDash([])},distance:(t,e,s)=>{const n=s.pts[0],o=i?e-n.y:n.y-e;return Math.abs(t-n.x)<=8&&o>=-4&&o<=20?0:null}}}const it=et("arrow-up","Arrow Up",!0),st=et("arrow-down","Arrow Down",!1),nt={id:"highlighter",name:"Highlighter",points: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 s=n(t,e,i.pts);return s<=Math.max(6,(i.drawing.style.lineWidth??12)/2)?0:s}},ot={id:"fib-channel",name:"Fib Channel",points:3,defaultStyle:{showLabels:!0,levels:[...m]},draw:t=>{const e=t.style.levels??m,[i,s,n]=t.pts,o=n.x-s.x,l=n.y-s.y;y(t);for(const n of e)t.ctx.beginPath(),t.ctx.moveTo(i.x+o*n,i.y+l*n),t.ctx.lineTo(s.x+o*n,s.y+l*n),t.ctx.stroke(),!1!==t.style.showLabels&&g(t,`${(100*n).toFixed(1)}%`,s.x+o*n+4*t.rc.dpr,s.y+l*n);t.ctx.setLineDash([])},distance:(e,i,s)=>{const n=s.drawing.style.levels??m,[o,l,r]=s.pts;let a=1/0;for(const s of n){const n=t(e,i,{x:o.x+(r.x-l.x)*s,y:o.y+(r.y-l.y)*s},{x:l.x+(r.x-l.x)*s,y:l.y+(r.y-l.y)*s});n<a&&(a=n)}return a}},lt=[0,1,2,3,5,8,13,21,34,55],rt={id:"fib-time-zone",name:"Fib Time Zone",points:2,defaultStyle:{showLabels:!0},draw:t=>{const[e,i]=t.pts,s=i.x-e.x;if(Math.abs(s)<.5)return;const n=t.rc.dpr,o=t.rc.plotWidth*n;y(t);for(const i of lt){const l=e.x+s*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*n),t.ctx.stroke(),!1!==t.style.showLabels&&g(t,String(i),l+3*n,12*n))}t.ctx.setLineDash([])},distance:(t,e,i)=>{const[s,n]=i.pts,o=n.x-s.x;if(Math.abs(o)<.5)return null;let l=1/0;for(const e of lt)l=Math.min(l,Math.abs(t-(s.x+o*e)));return l}},at=[.236,.382,.5,.618,.786,1],ct={id:"fib-fan",name:"Fib Speed Fan",points:2,defaultStyle:{showLabels:!0,levels:[...at]},draw:t=>{const e=t.style.levels??at,[i,s]=t.pts,n=t.rc.dpr,o=t.rc.plotWidth*n;y(t);for(const l of e){const e=a(i,{x:s.x,y:i.y+(s.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&&g(t,`${(100*l).toFixed(1)}%`,s.x+4*n,i.y+(s.y-i.y)*l)}t.ctx.setLineDash([])},distance:(e,i,s)=>{const n=s.drawing.style.levels??at,[o,l]=s.pts;let r=1/0;for(const c of n)r=Math.min(r,t(e,i,o,a(o,{x:l.x,y:o.y+(l.y-o.y)*c},s.rc.plotWidth,!1,!0)[1]));return r}},ht=[[1,.125],[1,.25],[1,.5],[1,1],[.5,1],[.25,1],[.125,1]],dt=[_,w,v,M,T,S,P,L,k,O,D,A,W,I,C,G,F,q,V,X,Z,K,Q,tt,it,st,nt,ot,rt,ct,{id:"gann-fan",name:"Gann Fan",points:2,defaultStyle:{showLabels:!0},draw:t=>{const[e,i]=t.pts,s=t.rc.dpr,n=t.rc.plotWidth*s,o=i.x-e.x,l=i.y-e.y;if(!(Math.abs(o)<.5)){y(t);for(const[i,s]of ht){const r=a(e,{x:e.x+o*i,y:e.y+l*s},n,!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&&g(t,"1x1",i.x+4*s,i.y),t.ctx.setLineDash([])}},distance:(e,i,s)=>{const[n,o]=s.pts,l=o.x-n.x,r=o.y-n.y;let c=1/0;for(const[o,h]of ht)c=Math.min(c,t(e,i,n,a(n,{x:n.x+l*o,y:n.y+r*h},s.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]);f(t,()=>t.ctx.fillRect(e.x0,e.y0,e.x1-e.x0,e.y1-e.y0)),y(t);const i=e.x1-e.x0,s=e.y1-e.y0;t.ctx.beginPath();for(let n=0;n<=8;n++){const o=Math.round(e.x0+i*n/8)+.5,l=Math.round(e.y0+s*n/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)},E,Y];let xt=!1;function pt(){if(!xt){xt=!0;for(const t of dt)h(t)}}class yt{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 s of i){if(!1===s.visible||!x(s.tool))continue;const i=d(s.tool);if(s.points.length<Math.max(1,i.points))continue;const n=this._points(e,s);if(!n.some(t=>Number.isFinite(t.x)&&Number.isFinite(t.y)))continue;const o={color:s.style.color??e.theme.lineColor,lineWidth:s.style.lineWidth??1.5,...s.style},l=e.dpr;t.save(),s===this._preview&&(t.globalAlpha=.7),i.draw({ctx:t,rc:e,drawing:s,selected:s.id===this._selected,pts:n.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(),s.id===this._selected&&!0!==s.locked&&this._drawHandles(t,e,n)}}_drawHandles(t,e,i){const s=e.dpr;t.save(),t.setLineDash([]),t.lineWidth=Math.max(1,Math.round(1.5*s));for(const n of i)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 s=this._drawings.find(t=>t.id===this._selected);if(void 0!==s&&!0!==s.locked){const n=this._points(i,s);for(let i=0;i<n.length;i++)if(Math.hypot(t-n[i].x,e-n[i].y)<=7)return{externalId:`draw:${s.id}#${i}`,zOrder:"top",distance:0,cursor:"grabbing",draggable:!0}}}let s=null;for(let n=this._drawings.length-1;n>=0;n--){const o=this._drawings[n];if(!1===o.visible||!0===o.locked||!x(o.tool))continue;const l=d(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===s||r<s.distance)&&(s={id:o.id,distance:r})}return null===s?null:{externalId:`draw:${s.id}`,zOrder:"top",distance:s.distance,cursor:"move",draggable:!0}}}let ut=1;class ft{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()));const i=t.drawingState();Array.isArray(i)&&(this._drawings=i.map(t=>({...t}))),this._sync()}setTool(t){if(null!==t&&!x(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=d(t.tool),i={...t,id:t.id??"d"+ut++,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,s=t.paneIndex??null;this._lastCursor=null===e||null===i||null===s?null:{time:e,price:i,paneIndex:s},this._lastBar=t.bar??null,null!==this._tool&&this._pending.length>0&&this._syncPreview()}_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(!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=d(this._tool);if(i.points>0&&this._pending.length>=i.points){const t=this.add({tool:i.id,points:this._pending,style:{},paneIndex:this._pendingPane});this._pending=[],this._opts.stayInDrawingMode||(this._tool=null,this._setPlacementMode(!1)),this._syncPreview(),this.select(t.id),this._chart.emit("draw:tool",{tool:this._tool})}else this._syncPreview()}_snap(t,e){if(!this._opts.magnet||0!==e)return t;const i=this._lastBar;if(null===i)return t;let s=t,n=1/0;for(const e of[i.open,i.high,i.low,i.close]){const i=Math.abs(e-t);i<n&&(n=i,s=e)}return s}_onDrag(t){if(!t.id.startsWith("draw:"))return;const[e,i]=t.id.slice(5).split("#"),s=this.get(e);if(void 0===s||!0===s.locked)return;const n=void 0===i?null:Number(i);null!==this._dragStart&&this._dragStart.id===e&&this._dragStart.handle===n||(this._pushUndo(),this._dragStart={id:e,handle:n,points:s.points.map(t=>({...t})),from:{time:t.fromTime??t.time,price:t.fromPrice??t.price}});const o=this._dragStart;if(null===n){const e=t.time-o.from.time,i=t.price-o.from.price;s.points=o.points.map(t=>({time:t.time+e,price:t.price+i}))}else n>=0&&n<s.points.length&&(s.points=o.points.map((e,i)=>i===n?{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 yt,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 gt="draw";pt();export{M as ARROW,dt as BUILTIN_DRAWING_TOOLS,L as CROSS_LINE,gt as DRAW_TIER,ft as DrawingController,yt as DrawingLayer,O as ELLIPSE,v as EXTENDED_LINE,W as FIB_EXTENSION,A as FIB_RETRACEMENT,T as HORIZONTAL_LINE,S as HORIZONTAL_RAY,I as LONG_POSITION,F as MEASURE,D as PARALLEL_CHANNEL,Y as PATH,w as RAY,k as RECTANGLE,C as SHORT_POSITION,E as TEXT,_ as TREND_LINE,P as VERTICAL_LINE,r as distToEllipse,e as distToLine,n as distToPolyline,l as distToRect,t as distToSegment,a as extendSegment,d as getDrawingTool,x as hasDrawingTool,o as rectOf,pt as registerBuiltinDrawingTools,h as registerDrawingTool,p 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`}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};
2
2
  //# sourceMappingURL=openalgo-charts.draw.mjs.map