@trdrs/quickcharts 2.4.0 → 4.0.0
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/CHANGELOG.md +121 -0
- package/README.md +326 -25
- package/dist/adapters/rest.d.ts +1 -1
- package/dist/{ar-KSXQ2USS.js → ar-FXZ5QJUR.js} +206 -56
- package/dist/ar-FXZ5QJUR.js.map +1 -0
- package/dist/{assets-M5emOz5c.d.ts → assets-Gg-UquDA.d.ts} +285 -61
- package/dist/{ca_ES-JG4FM55E.js → ca_ES-3WVKFBIF.js} +206 -56
- package/dist/ca_ES-3WVKFBIF.js.map +1 -0
- package/dist/chunk-C4MEVUNK.js +11449 -0
- package/dist/chunk-C4MEVUNK.js.map +1 -0
- package/dist/{de-VSW2LHNF.js → de-V72Q3OI7.js} +206 -56
- package/dist/de-V72Q3OI7.js.map +1 -0
- package/dist/drawings.d.ts +24 -13
- package/dist/drawings.js +5 -1
- package/dist/{es-5ZXIPVOB.js → es-CNQ3OJ6E.js} +206 -56
- package/dist/es-CNQ3OJ6E.js.map +1 -0
- package/dist/feature-manifest.json +94 -11
- package/dist/{fr-4F6DAWGD.js → fr-5WQBCGR4.js} +206 -56
- package/dist/fr-5WQBCGR4.js.map +1 -0
- package/dist/{he_IL-B7PBQUEV.js → he_IL-WXKA77UE.js} +206 -56
- package/dist/he_IL-WXKA77UE.js.map +1 -0
- package/dist/{id_ID-CYJRMXPC.js → id_ID-XPBAYSWK.js} +206 -56
- package/dist/id_ID-XPBAYSWK.js.map +1 -0
- package/dist/index.d.ts +1834 -1671
- package/dist/index.js +5405 -2619
- package/dist/index.js.map +1 -1
- package/dist/{it-KTX4SG5P.js → it-DR2EBNWX.js} +206 -56
- package/dist/it-DR2EBNWX.js.map +1 -0
- package/dist/{ja-V7OURU5D.js → ja-URB2CPXO.js} +206 -56
- package/dist/ja-URB2CPXO.js.map +1 -0
- package/dist/{ko-2RNEBYVE.js → ko-OE47NYVP.js} +206 -56
- package/dist/ko-OE47NYVP.js.map +1 -0
- package/dist/{ms_MY-EY235E7Q.js → ms_MY-BKCFRK2K.js} +206 -56
- package/dist/ms_MY-BKCFRK2K.js.map +1 -0
- package/dist/{pl-ADNVRP55.js → pl-3IKQRG3Y.js} +206 -56
- package/dist/pl-3IKQRG3Y.js.map +1 -0
- package/dist/{pt-OL2DR3DO.js → pt-PZHV5EZE.js} +206 -56
- package/dist/pt-PZHV5EZE.js.map +1 -0
- package/dist/quickcharts.css +2060 -717
- package/dist/{resources-C0cYryO9.d.ts → resources-Le6flcEn.d.ts} +1 -1
- package/dist/{ru-V6YFEPAF.js → ru-BAL6RQUV.js} +206 -56
- package/dist/ru-BAL6RQUV.js.map +1 -0
- package/dist/{sv-TORXQVE7.js → sv-Y6GBGDHM.js} +206 -56
- package/dist/sv-Y6GBGDHM.js.map +1 -0
- package/dist/{symbols-BL1fD4CS.d.ts → symbols-6V22WaRX.d.ts} +1 -1
- package/dist/symbols.d.ts +1 -1
- package/dist/{th-K6SJSYSY.js → th-MAMLMZKU.js} +206 -56
- package/dist/th-MAMLMZKU.js.map +1 -0
- package/dist/theme-manifest.json +204 -16
- package/dist/{tr-4AEM66KW.js → tr-3LQHINUZ.js} +206 -56
- package/dist/tr-3LQHINUZ.js.map +1 -0
- package/dist/{vi-YU5XCEUU.js → vi-GR4PSDKP.js} +206 -56
- package/dist/vi-GR4PSDKP.js.map +1 -0
- package/dist/{zh-QXKRYHU5.js → zh-2RJ5VNAI.js} +206 -56
- package/dist/zh-2RJ5VNAI.js.map +1 -0
- package/dist/{zh_TW-AYPDKG4Q.js → zh_TW-XEBSACHU.js} +206 -56
- package/dist/zh_TW-XEBSACHU.js.map +1 -0
- package/package.json +1 -1
- package/dist/ar-KSXQ2USS.js.map +0 -1
- package/dist/ca_ES-JG4FM55E.js.map +0 -1
- package/dist/chunk-YR7NT5ZW.js +0 -6997
- package/dist/chunk-YR7NT5ZW.js.map +0 -1
- package/dist/de-VSW2LHNF.js.map +0 -1
- package/dist/es-5ZXIPVOB.js.map +0 -1
- package/dist/fr-4F6DAWGD.js.map +0 -1
- package/dist/he_IL-B7PBQUEV.js.map +0 -1
- package/dist/id_ID-CYJRMXPC.js.map +0 -1
- package/dist/it-KTX4SG5P.js.map +0 -1
- package/dist/ja-V7OURU5D.js.map +0 -1
- package/dist/ko-2RNEBYVE.js.map +0 -1
- package/dist/ms_MY-EY235E7Q.js.map +0 -1
- package/dist/pl-ADNVRP55.js.map +0 -1
- package/dist/pt-OL2DR3DO.js.map +0 -1
- package/dist/ru-V6YFEPAF.js.map +0 -1
- package/dist/sv-TORXQVE7.js.map +0 -1
- package/dist/th-K6SJSYSY.js.map +0 -1
- package/dist/tr-4AEM66KW.js.map +0 -1
- package/dist/vi-YU5XCEUU.js.map +0 -1
- package/dist/zh-QXKRYHU5.js.map +0 -1
- package/dist/zh_TW-AYPDKG4Q.js.map +0 -1
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/internal/drawings/core/visibility.ts","../src/internal/drawings/core/types.ts","../src/internal/drawings/render/canvas.ts","../src/internal/drawings/render/pane-view.ts","../src/internal/drawings/core/drawing.ts","../src/internal/drawings/core/manager.ts","../src/internal/drawings/core/magnet.ts","../src/internal/drawings/core/geometry.ts","../src/internal/drawings/render/imageCache.ts","../src/internal/drawings/render/axis-view.ts","../src/internal/drawings/tools/lines.ts","../src/internal/drawings/tools/shapes.ts","../src/internal/drawings/tools/annotations.ts","../src/internal/drawings/core/bars.ts","../src/internal/drawings/tools/measurement.ts","../src/internal/drawings/tools/channels.ts","../src/internal/drawings/tools/pitchforks.ts","../src/internal/drawings/tools/fibonacci.ts","../src/internal/drawings/tools/gann.ts","../src/internal/drawings/core/money.ts","../src/internal/drawings/tools/forecasting.ts","../src/internal/drawings/tools/freehand.ts","../src/internal/drawings/tools/table.ts","../src/internal/drawings/tools/patterns.ts","../src/internal/drawings/tools/elliott.ts","../src/internal/drawings/tools/cycles.ts","../src/internal/drawings/tools/bars.ts","../src/internal/drawings/tools/volume.ts","../src/internal/drawings/tools/content.ts","../src/internal/drawings/registry.ts","../src/internal/drawings/store.ts","../src/drawings/tools.ts","../src/drawings/store.ts","../src/drawings/magnetModel.ts","../src/drawings/drawingToolbarModel.ts","../src/drawings/hideModel.ts","../src/drawings/cursorModel.ts","../src/drawings/lockModel.ts","../src/drawings/favoritesModel.ts","../src/drawings/editModel.ts","../src/theme/color.ts","../src/ui/controls/color/palette.ts","../src/ui/controls/dom.ts","../src/ui/controls/escape.ts","../src/ui/drawings/dom.ts","../src/ui/controls/color/picker.ts","../src/drawings/preferences.ts","../src/drawings/templates.ts","../src/drawings/assets.ts","../src/drawings/capabilities.ts"],"sourcesContent":["/** One timeframe bucket's visibility rule: enabled + the inclusive value range it covers. */\nexport interface VisibilityRange {\n on: boolean\n from: number\n to: number\n}\n\n/**\n * Per-timeframe visibility for one drawing — which chart timeframes it appears on. Buckets and\n * ranges mirror the timeframe vocabulary (seconds/minutes 1–59, hours 1–24, days 1–366,\n * weeks 1–52, months 1–12); ticks is a single switch.\n */\nexport interface TimeframeVisibility {\n ticks: boolean\n seconds: VisibilityRange\n minutes: VisibilityRange\n hours: VisibilityRange\n days: VisibilityRange\n weeks: VisibilityRange\n months: VisibilityRange\n}\n\nexport const DEFAULT_VISIBILITY: TimeframeVisibility = {\n ticks: true,\n seconds: { on: true, from: 1, to: 59 },\n minutes: { on: true, from: 1, to: 59 },\n hours: { on: true, from: 1, to: 24 },\n days: { on: true, from: 1, to: 366 },\n weeks: { on: true, from: 1, to: 52 },\n months: { on: true, from: 1, to: 12 },\n}\n\nexport type TimeframeBucket = 'ticks' | 'seconds' | 'minutes' | 'hours' | 'days' | 'weeks' | 'months'\n\n/** The four quick visibility rules, resolved against the chart's CURRENT timeframe. */\nexport type VisibilityPreset = 'current-and-above' | 'current-and-below' | 'current-only' | 'all'\n\nconst RANGE_BUCKETS = ['seconds', 'minutes', 'hours', 'days', 'weeks', 'months'] as const\nconst BUCKET_MAX: Record<(typeof RANGE_BUCKETS)[number], number> = {\n seconds: 59,\n minutes: 59,\n hours: 24,\n days: 366,\n weeks: 52,\n months: 12,\n}\n\n/** Build the visibility tree for one quick rule. \"Above\" means the current timeframe and every\n * COARSER one (a 1h line kept \"and above\" shows on 4h and 1d, never on 5m); \"below\" mirrors it\n * toward the finer timeframes; \"only\" pins the current bucket's value. A fractional context\n * (90m → hours 1.5) rounds OUTWARD so the current chart always satisfies its own rule. With no\n * context (unparseable timeframe) every rule degrades to all — a drawing must never vanish\n * because the timeframe could not be classified. */\nexport function visibilityPreset(kind: VisibilityPreset, ctx: TimeframeContext): TimeframeVisibility {\n const all: TimeframeVisibility = {\n ticks: true,\n seconds: { on: true, from: 1, to: 59 },\n minutes: { on: true, from: 1, to: 59 },\n hours: { on: true, from: 1, to: 24 },\n days: { on: true, from: 1, to: 366 },\n weeks: { on: true, from: 1, to: 52 },\n months: { on: true, from: 1, to: 12 },\n }\n if (kind === 'all' || !ctx) return all\n const order: TimeframeBucket[] = ['ticks', ...RANGE_BUCKETS]\n const at = order.indexOf(ctx.bucket)\n const lo = Math.max(1, Math.floor(ctx.value))\n const hi = Math.max(lo, Math.ceil(ctx.value))\n const out = all\n // Ticks is a single switch and the FINEST bucket: on when ticks IS the current bucket (every\n // rule keeps the current timeframe visible), else only \"and below\" reaches down to it.\n out.ticks = ctx.bucket === 'ticks' || kind === 'current-and-below'\n for (const bucket of RANGE_BUCKETS) {\n const i = order.indexOf(bucket)\n if (i === at) {\n out[bucket] =\n kind === 'current-and-above'\n ? { on: true, from: lo, to: BUCKET_MAX[bucket] }\n : kind === 'current-and-below'\n ? { on: true, from: 1, to: hi }\n : { on: true, from: lo, to: hi }\n } else if (i > at) {\n out[bucket] = { on: kind === 'current-and-above', from: 1, to: BUCKET_MAX[bucket] }\n } else {\n out[bucket] = { on: kind === 'current-and-below', from: 1, to: BUCKET_MAX[bucket] }\n }\n }\n return out\n}\n\n/** The chart's current timeframe, bucketed; null = unknown (drawings then always show). */\nexport type TimeframeContext = { bucket: TimeframeBucket; value: number } | null\n\n/**\n * Parse a timeframe token ('1t', '30s', '45m', '4h', '1d', '1w', '3mo') into a bucket context.\n * Oversized values roll up so custom timeframes land in the range viewers expect (90m → 1.5h).\n */\nexport function parseTimeframeContext(tf: string): TimeframeContext {\n const match = /^(\\d+)(t|s|m|h|d|w|mo)$/.exec(tf.trim().toLowerCase())\n if (!match) return null\n let value = Number(match[1])\n const unit = match[2]\n if (unit === 't') return { bucket: 'ticks', value }\n if (unit === 's') {\n if (value < 60) return { bucket: 'seconds', value }\n value /= 60\n return value < 60 ? { bucket: 'minutes', value } : { bucket: 'hours', value: value / 60 }\n }\n if (unit === 'm') {\n return value < 60 ? { bucket: 'minutes', value } : { bucket: 'hours', value: value / 60 }\n }\n if (unit === 'h') return { bucket: 'hours', value }\n if (unit === 'd') return { bucket: 'days', value }\n if (unit === 'w') return { bucket: 'weeks', value }\n return { bucket: 'months', value }\n}\n\n/** Deep-copied visibility with defaults filled in — configs never alias the shared default. */\nexport function normalizeVisibility(partial?: Partial<TimeframeVisibility>): TimeframeVisibility {\n return {\n ticks: partial?.ticks ?? DEFAULT_VISIBILITY.ticks,\n seconds: { ...DEFAULT_VISIBILITY.seconds, ...partial?.seconds },\n minutes: { ...DEFAULT_VISIBILITY.minutes, ...partial?.minutes },\n hours: { ...DEFAULT_VISIBILITY.hours, ...partial?.hours },\n days: { ...DEFAULT_VISIBILITY.days, ...partial?.days },\n weeks: { ...DEFAULT_VISIBILITY.weeks, ...partial?.weeks },\n months: { ...DEFAULT_VISIBILITY.months, ...partial?.months },\n }\n}\n\n/** Whether a drawing with this visibility config shows at the given timeframe. */\nexport function visibleAt(visibility: TimeframeVisibility, context: TimeframeContext): boolean {\n if (!context) return true\n if (context.bucket === 'ticks') return visibility.ticks\n const range = visibility[context.bucket]\n return range.on && context.value >= range.from && context.value <= range.to\n}\n","import type { Time } from 'lightweight-charts'\nimport type { TimeframeContext, TimeframeVisibility } from './visibility'\nimport { DEFAULT_VISIBILITY } from './visibility'\n\n/** How the host writes a price: the symbol's own formatter, injected so every drawing label,\n * pill and readout carries the market's declared precision. The drawings package never derives a\n * precision from a price's magnitude. */\nexport type PriceFormatPort = (price: number) => string\n\n/** Where a glyph mark's artwork comes from. Platform emoji fonts cannot be trusted on a canvas\n * (Windows draws no flag glyphs at all), so emoji and sticker marks draw a host-supplied image\n * when this answers with a URL. Null falls back to drawing the glyph as text, which is also what\n * icon marks always do, because their ink is tinted by the stroke colour and artwork cannot\n * carry that. */\nexport type GlyphSourcePort = (glyph: string) => string | null\n\n/** A point the drawing is pinned to, in chart coordinates. */\nexport interface Anchor {\n time: Time\n price: number\n}\n\n/** A point in pane-local CSS pixels. */\nexport interface Point {\n x: number\n y: number\n}\n\nexport type LineStyle = 'solid' | 'dashed' | 'dotted'\n\n/**\n * The shared visual vocabulary every tool paints with. `style` is HOW a drawing is painted\n * (what the floating toolbar edits generically); a tool's `props` are WHAT it is (levels,\n * extension flags, text content, …); `options` are lifecycle flags. All style fields are\n * required — constructors merge defaults so tools never carry `?? fallback` chains.\n */\nexport interface DrawingStyle {\n lineColor: string\n lineWidth: number\n lineStyle: LineStyle\n /** Fill paint for tools with a fillable region; fill shows only while `fillOpacity > 0`. */\n fillColor: string\n fillOpacity: number\n /** Text channel for tools that render text (labels, notes, callouts). */\n textColor: string\n fontSize: number\n bold: boolean\n italic: boolean\n}\n\nexport const DEFAULT_STYLE: DrawingStyle = {\n lineColor: '#4c98fb',\n lineWidth: 2,\n lineStyle: 'solid',\n fillColor: '#4c98fb',\n fillOpacity: 0,\n textColor: '#e5e7eb',\n fontSize: 13,\n bold: false,\n italic: false,\n}\n\n/** Lifecycle flags, uniform across tools. Higher `zIndex` hit-tests (and later paints) on top. */\nexport interface DrawingOptions {\n visible: boolean\n locked: boolean\n zIndex: number\n /** Which chart timeframes the drawing shows on (independent of the manual `visible` switch). */\n visibility: TimeframeVisibility\n}\n\nexport const DEFAULT_OPTIONS: DrawingOptions = {\n visible: true,\n locked: false,\n zIndex: 0,\n visibility: DEFAULT_VISIBILITY,\n}\n\n/**\n * Wire/persistence format. `props` carries the tool-specific payload — every tool round-trips\n * its COMPLETE state through this shape (the schema exists so nothing is ever dropped on save).\n */\nexport interface SerializedDrawing {\n v: 2\n id: string\n type: string\n anchors: Anchor[]\n style: DrawingStyle\n options: DrawingOptions\n props?: Record<string, unknown>\n /** The chart surface this drawing is LOCAL to, when it is local to one. Absent — the case for\n * every drawing made while sync is on, and for every drawing made before scoping existed —\n * means the drawing is shared by every surface showing this symbol. The host owns the shape of\n * the token; the drawing layer only ever compares it for equality. */\n scope?: string\n}\n\nexport type DrawingState = 'normal' | 'hovered' | 'selected' | 'editing'\n\n/**\n * Pane-local coordinate conversions handed to paint/hit-test code. Width/height are the pane's\n * CSS-pixel size (never a container fallback — extension math depends on the real pane box).\n */\nexport interface Viewport {\n width: number\n height: number\n xOf(time: Time): number | null\n yOf(price: number): number | null\n timeAt(x: number): Time | null\n priceAt(y: number): number | null\n /** Bar-index distance between two times (fractional; null when either falls outside data). */\n barsBetween(a: Time, b: Time): number | null\n /** The bar index a time sits at (fractional; null outside the loaded range). */\n logicalOf(time: Time): number | null\n /** The time at a bar index (null in whitespace beyond the loaded range). */\n timeOfLogical(logical: number): Time | null\n}\n\n/** A draggable handle over an anchor, in pane-local CSS pixels. */\nexport interface ControlPoint {\n index: number\n x: number\n y: number\n}\n\nexport interface IDrawing {\n readonly id: string\n readonly type: string\n /** The chart surface this drawing is bound to, when it is bound to one; undefined is shared by\n * every surface showing the symbol. The host assigns and compares it; the model only carries it. */\n scope?: string\n anchors: readonly Anchor[]\n style: Readonly<DrawingStyle>\n options: Readonly<DrawingOptions>\n state: DrawingState\n\n setAnchors(anchors: Anchor[]): void\n updateAnchor(index: number, anchor: Anchor): void\n appendAnchor(anchor: Anchor): void\n removeAnchor(index: number): void\n updateStyle(patch: Partial<DrawingStyle>): void\n updateOptions(patch: Partial<DrawingOptions>): void\n setState(state: DrawingState): void\n\n /** The tool-specific payload (typed per tool; empty object for tools without one). */\n readonly props: Readonly<Record<string, unknown>>\n applyProps(patch: Record<string, unknown>): void\n\n /** True once the drawing has its full anchor set (placement complete, all values finite). */\n isValid(): boolean\n\n /** The chart's current timeframe (the manager broadcasts it on timeframe changes). */\n setTimeframeContext(context: TimeframeContext): void\n /** Chart-wide hide-all switch (transient view state — never serialized). */\n setGlobalHidden(hidden: boolean): void\n /** The symbol's smallest price move (tick-denominated readouts); null omits those readouts. */\n setTickSize(tick: number | null): void\n /** The symbol's price formatter (the manager broadcasts it); null returns to the declared\n * stand-in. */\n setPriceFormatter(format: PriceFormatPort | null): void\n /** Where glyph artwork comes from (the manager broadcasts it); null draws glyphs as text. */\n setGlyphSource(source: GlyphSourcePort | null): void\n /** Manual `visible` switch AND hide-all AND the per-timeframe rule, combined. */\n isVisibleNow(): boolean\n\n testHit(point: Point, viewport: Viewport): boolean\n getControlPoints(viewport: Viewport): ControlPoint[]\n anchorToPixel(anchor: Anchor, viewport: Viewport): Point | null\n /** Scale grips beyond the anchors (emoji/image corners); dragging one calls `resizeTo`. */\n resizeHandles(viewport: Viewport): Point[]\n resizeTo(handleIndex: number, point: Point, viewport: Viewport): void\n /** \"+ Add text\" hint above a selected text-capable drawing that has no text yet. */\n paintTextHint(ctx: CanvasRenderingContext2D, viewport: Viewport): void\n hitTextHint(point: Point): boolean\n /** Where the hint last painted — the inline editor opens exactly there (the hint becomes it). */\n textHintAnchor(): { x: number; y: number; angle: number } | null\n /** An inline text editor is open on this drawing — the hint stays hidden underneath it. */\n textEditing: boolean\n\n getViewport(): Viewport | null\n requestUpdate(): void\n toJSON(): SerializedDrawing\n}\n\nexport type ToolCategory =\n | 'lines'\n | 'channels'\n | 'pitchforks'\n | 'fibonacci'\n | 'gann'\n | 'patterns'\n | 'elliott'\n | 'cycles'\n | 'forecasting'\n | 'volume'\n | 'measurement'\n | 'shapes'\n | 'annotation'\n | 'content'\n\nexport type DrawingEventType =\n | 'drawing:added'\n | 'drawing:removed'\n | 'drawing:selected'\n | 'drawing:deselected'\n | 'drawing:cleared'\n\nexport interface DrawingEvent {\n type: DrawingEventType\n drawingId?: string\n drawing?: IDrawing\n}\n\nexport type DrawingEventCallback = (event: DrawingEvent) => void\n","import type { DrawingStyle, LineStyle, Point } from '../core/types'\n\n/** Dash pattern for a line style, scaled so dashes stay legible at any width. */\nexport function dashPattern(style: LineStyle, width: number): number[] {\n switch (style) {\n case 'dashed':\n return [Math.max(4, width * 3), Math.max(3, width * 2)]\n case 'dotted':\n return [Math.max(1, width), Math.max(2, width * 2)]\n default:\n return []\n }\n}\n\n/** Apply the stroke channel (color, width, dash) of a drawing's style. */\nexport function applyStroke(ctx: CanvasRenderingContext2D, style: DrawingStyle): void {\n ctx.strokeStyle = style.lineColor\n ctx.lineWidth = style.lineWidth\n ctx.setLineDash(dashPattern(style.lineStyle, style.lineWidth))\n ctx.lineCap = 'round'\n ctx.lineJoin = 'round'\n}\n\n/** Stroke the segment a→b with the current stroke settings. */\nexport function strokeSegment(ctx: CanvasRenderingContext2D, a: Point, b: Point): void {\n ctx.beginPath()\n ctx.moveTo(a.x, a.y)\n ctx.lineTo(b.x, b.y)\n ctx.stroke()\n}\n\n/** The CSS font string for a drawing's text channel. */\nexport function fontOf(style: DrawingStyle): string {\n const weight = style.bold ? '600 ' : ''\n const slant = style.italic ? 'italic ' : ''\n return `${slant}${weight}${style.fontSize}px ui-sans-serif, system-ui, sans-serif`\n}\n\nexport interface LabelOptions {\n align?: CanvasTextAlign\n baseline?: CanvasTextBaseline\n /** Padded pill behind the text; omit for bare text. */\n background?: string\n padding?: number\n}\n\n/** Paint a single-line text label; returns its painted bounds (for hit-testing). */\nexport function paintLabel(\n ctx: CanvasRenderingContext2D,\n text: string,\n at: Point,\n style: DrawingStyle,\n opts: LabelOptions = {},\n): { x: number; y: number; width: number; height: number } {\n const { align = 'left', baseline = 'middle', background, padding = 4 } = opts\n ctx.save()\n ctx.font = fontOf(style)\n ctx.textAlign = align\n ctx.textBaseline = baseline\n const metrics = ctx.measureText(text)\n const width = metrics.width\n const height = style.fontSize + 2\n const left = align === 'right' ? at.x - width : align === 'center' ? at.x - width / 2 : at.x\n const top = baseline === 'bottom' ? at.y - height : baseline === 'top' ? at.y : at.y - height / 2\n if (background) {\n ctx.fillStyle = background\n ctx.beginPath()\n ctx.roundRect(left - padding, top - padding, width + padding * 2, height + padding * 2, 4)\n ctx.fill()\n }\n ctx.fillStyle = style.textColor\n ctx.setLineDash([])\n ctx.fillText(text, at.x, at.y)\n ctx.restore()\n return { x: left - padding, y: top - padding, width: width + padding * 2, height: height + padding * 2 }\n}\n\n/** Filled arrow head at `tip`, oriented along `from`→`tip`. Scales with line width. */\nexport function paintArrowHead(\n ctx: CanvasRenderingContext2D,\n from: Point,\n tip: Point,\n style: DrawingStyle,\n): void {\n const angle = Math.atan2(tip.y - from.y, tip.x - from.x)\n const size = 4 + style.lineWidth * 2.5\n ctx.save()\n ctx.fillStyle = style.lineColor\n ctx.setLineDash([])\n ctx.beginPath()\n ctx.moveTo(tip.x, tip.y)\n ctx.lineTo(tip.x - size * Math.cos(angle - Math.PI / 6), tip.y - size * Math.sin(angle - Math.PI / 6))\n ctx.lineTo(tip.x - size * Math.cos(angle + Math.PI / 6), tip.y - size * Math.sin(angle + Math.PI / 6))\n ctx.closePath()\n ctx.fill()\n ctx.restore()\n}\n\nlet measurer: CanvasRenderingContext2D | null = null\n\n/** Measure a text block (newline-aware) without a live rendering context. */\nexport function measureTextBlock(\n text: string,\n style: DrawingStyle,\n): { width: number; height: number; lineHeight: number } {\n const lines = text.split('\\n')\n const lineHeight = Math.round(style.fontSize * 1.35)\n if (!measurer && typeof document !== 'undefined') {\n measurer = document.createElement('canvas').getContext('2d')\n }\n let width = 0\n if (measurer) {\n measurer.font = fontOf(style)\n for (const line of lines) width = Math.max(width, measurer.measureText(line).width)\n } else {\n for (const line of lines) width = Math.max(width, line.length * style.fontSize * 0.6)\n }\n return { width, height: lines.length * lineHeight, lineHeight }\n}\n\nexport interface TextBlockOptions {\n background?: string\n borderColor?: string\n padding?: number\n align?: 'left' | 'center'\n}\n\n/** Paint a (possibly multi-line) text block anchored at its top-left; returns painted bounds. */\nexport function paintTextBlock(\n ctx: CanvasRenderingContext2D,\n text: string,\n topLeft: Point,\n style: DrawingStyle,\n opts: TextBlockOptions = {},\n): { x: number; y: number; width: number; height: number } {\n const { background, borderColor, padding = 6, align = 'left' } = opts\n const { width, height, lineHeight } = measureTextBlock(text, style)\n const box = {\n x: topLeft.x,\n y: topLeft.y,\n width: width + padding * 2,\n height: height + padding * 2,\n }\n ctx.save()\n ctx.setLineDash([])\n if (background || borderColor) {\n ctx.beginPath()\n ctx.roundRect(box.x, box.y, box.width, box.height, 4)\n if (background) {\n ctx.fillStyle = background\n ctx.fill()\n }\n if (borderColor) {\n ctx.strokeStyle = borderColor\n ctx.lineWidth = 1\n ctx.stroke()\n }\n }\n ctx.font = fontOf(style)\n ctx.fillStyle = style.textColor\n ctx.textBaseline = 'top'\n ctx.textAlign = align\n const textX = align === 'center' ? box.x + box.width / 2 : box.x + padding\n const lines = text.split('\\n')\n for (let i = 0; i < lines.length; i++) {\n ctx.fillText(lines[i], textX, box.y + padding + i * lineHeight)\n }\n ctx.restore()\n return box\n}\n\nconst HANDLE_RADIUS = 4.5\n\n/** Paint the anchor handles for a selected/editing drawing. */\nexport function paintHandles(\n ctx: CanvasRenderingContext2D,\n points: readonly Point[],\n accent: string,\n): void {\n ctx.save()\n ctx.setLineDash([])\n ctx.lineWidth = 1.5\n for (const p of points) {\n ctx.beginPath()\n ctx.arc(p.x, p.y, HANDLE_RADIUS, 0, Math.PI * 2)\n ctx.fillStyle = '#ffffff'\n ctx.fill()\n ctx.strokeStyle = accent\n ctx.stroke()\n }\n ctx.restore()\n}\n\n/** Square scale grips (emoji/image corners) for a selected drawing. */\nexport function paintResizeGrips(\n ctx: CanvasRenderingContext2D,\n points: readonly Point[],\n accent: string,\n): void {\n ctx.save()\n ctx.setLineDash([])\n ctx.lineWidth = 1.5\n for (const p of points) {\n ctx.fillStyle = '#ffffff'\n ctx.strokeStyle = accent\n ctx.beginPath()\n ctx.rect(p.x - 3.5, p.y - 3.5, 7, 7)\n ctx.fill()\n ctx.stroke()\n }\n ctx.restore()\n}\n\n/** Fill color string with the style's fill opacity applied. */\nexport function fillPaint(style: DrawingStyle): string | null {\n if (style.fillOpacity <= 0) return null\n return withAlpha(style.fillColor, style.fillOpacity)\n}\n\n/** The alpha carried by a color value (rgba's 4th component); opaque formats report 1. */\nexport function alphaOf(color: string): number {\n const m = color.trim().match(/^rgba\\([^,]+,[^,]+,[^,]+,\\s*([0-9.]+)\\s*\\)$/i)\n if (!m) return 1\n const a = Number(m[1])\n return Number.isFinite(a) ? Math.max(0, Math.min(1, a)) : 1\n}\n\n/** Apply an alpha to a #rgb/#rrggbb/rgb()/rgba() color. Unknown formats pass through. */\nexport function withAlpha(color: string, alpha: number): string {\n const a = Math.max(0, Math.min(1, alpha))\n const hex = color.trim().match(/^#([0-9a-f]{3}|[0-9a-f]{6})$/i)\n if (hex) {\n const h = hex[1]\n const full = h.length === 3 ? h.split('').map((c) => c + c).join('') : h\n const n = parseInt(full, 16)\n return `rgba(${(n >> 16) & 255}, ${(n >> 8) & 255}, ${n & 255}, ${a})`\n }\n const rgb = color.trim().match(/^rgba?\\(([^)]+)\\)$/i)\n if (rgb) {\n const parts = rgb[1].split(',').map((s) => s.trim())\n return `rgba(${parts[0]}, ${parts[1]}, ${parts[2]}, ${a})`\n }\n return color\n}\n","import type { IPrimitivePaneRenderer, IPrimitivePaneView, PrimitivePaneViewZOrder } from 'lightweight-charts'\nimport type { CanvasRenderingTarget2D } from 'fancy-canvas'\n\nimport type { AnyDrawing } from '../core/drawing'\nimport { paintHandles, paintResizeGrips } from './canvas'\n\n/**\n * The one pane view every drawing uses. It owns the canvas plumbing (coordinate space,\n * visibility, selection handles) so tool classes only implement `paint` in CSS pixels.\n */\nexport class DrawingPaneView implements IPrimitivePaneView, IPrimitivePaneRenderer {\n private readonly _drawing: AnyDrawing\n\n constructor(drawing: AnyDrawing) {\n this._drawing = drawing\n }\n\n zOrder(): PrimitivePaneViewZOrder {\n return 'normal'\n }\n\n renderer(): IPrimitivePaneRenderer {\n return this\n }\n\n draw(target: CanvasRenderingTarget2D): void {\n const drawing = this._drawing\n if (!drawing.isVisibleNow()) return\n const viewport = drawing.getViewport()\n if (!viewport) return\n\n target.useMediaCoordinateSpace(({ context: ctx }) => {\n ctx.save()\n try {\n if (drawing.isValid()) {\n drawing.paint(ctx, viewport)\n } else {\n drawing.paintConstruction(ctx, viewport)\n }\n const state = drawing.state\n if (state === 'selected' || state === 'editing') {\n const points = drawing.getControlPoints(viewport)\n if (points.length > 0) paintHandles(ctx, points, drawing.style.lineColor)\n const grips = drawing.resizeHandles(viewport)\n if (grips.length > 0) paintResizeGrips(ctx, grips, drawing.style.lineColor)\n if (drawing.isValid()) drawing.paintTextHint(ctx, viewport)\n }\n } finally {\n ctx.restore()\n }\n })\n }\n}\n","import type {\n IChartApi,\n ISeriesApi,\n IPrimitivePaneView,\n ISeriesPrimitive,\n ISeriesPrimitiveAxisView,\n PrimitiveHoveredItem,\n SeriesAttachedParameter,\n SeriesType,\n Time,\n} from 'lightweight-charts'\n\nimport type {\n Anchor,\n ControlPoint,\n DrawingOptions,\n DrawingState,\n DrawingStyle,\n IDrawing,\n Point,\n GlyphSourcePort,\n PriceFormatPort,\n SerializedDrawing,\n Viewport,\n} from './types'\nimport { DEFAULT_OPTIONS, DEFAULT_STYLE } from './types'\nimport type { TimeframeContext } from './visibility'\nimport { normalizeVisibility, visibleAt } from './visibility'\nimport type { BarSource, SourceBar } from './bars'\nimport { DrawingPaneView } from '../render/pane-view'\n\nfunction normalizeOptions(patch: Partial<DrawingOptions>): DrawingOptions {\n return { ...DEFAULT_OPTIONS, ...patch, visibility: normalizeVisibility(patch.visibility) }\n}\n\n/** Any concrete drawing, prop shape erased — the store/registry currency. */\nexport type AnyDrawing = Drawing<Record<string, unknown>>\n\n\n/** Build a Viewport over a chart + series pair. Null while either is unusable (torn down). */\nexport function viewportOf(chart: IChartApi, series: ISeriesApi<SeriesType>): Viewport | null {\n let width: number\n let height: number\n try {\n width = chart.timeScale().width()\n height = chart.paneSize().height\n } catch {\n return null\n }\n if (width <= 0 || height <= 0) return null\n const ts = chart.timeScale()\n\n // ── time ⇄ logical ⇄ x, grounded in the library's MEASURED contract ──\n // Two live measurements define what the time scale can be trusted with:\n // (1) `timeToCoordinate` resolves only times that exist as bars of the CURRENT grid. An anchor\n // placed on a finer timeframe (17:30 on an hourly chart) answers null.\n // (2) `logicalToCoordinate` is exact for INTEGER indices inside the data — even thousands of\n // pixels off-screen (index 0 answered -11448.34px while scrolled far right, and the slope\n // between any two in-range integers equals the live barSpacing to full precision) — but\n // answers 0, the pane's left edge, for EVERY fractional logical and for any integer outside\n // the data. The visible logical range's endpoints are continuous scroll positions,\n // fractional in every real frame, so calibrating a linear map from them reads two poisoned\n // zeros and disables the map — which made every between-bars anchor (i.e. every drawing\n // after a timeframe switch) paint nothing.\n // So the library is consulted only where it is exact — bar times, integer in-range indices, the\n // live barSpacing — and every fractional mapping is computed from the series data directly.\n const data = series.data()\n const lastIndex = data.length - 1\n const numTime = (i: number): number | null => {\n const t = data[i]?.time\n return typeof t === 'number' ? t : null\n }\n const firstTime = data.length > 0 ? numTime(0) : null\n const lastTime = data.length > 0 ? numTime(lastIndex) : null\n // Leading/trailing bar steps extrapolate beyond the loaded range: past the last bar is a\n // projection into empty future space, before the first is unloaded history.\n const prevTime = numTime(lastIndex - 1)\n const trailStep = lastTime !== null && prevTime !== null && lastTime > prevTime ? lastTime - prevTime : null\n const secondTime = numTime(1)\n const leadStep = firstTime !== null && secondTime !== null && secondTime > firstTime ? secondTime - firstTime : null\n\n const logicalOfTime = (time: Time): number | null => {\n // A time that IS a bar of the current grid takes the library's exact mapping. This also covers\n // non-numeric Time shapes, which the data math below cannot address.\n const x = ts.timeToCoordinate(time)\n if (x !== null) {\n const logical = ts.coordinateToLogical(x)\n if (logical !== null) return logical\n }\n if (typeof time !== 'number' || firstTime === null || lastTime === null) return null\n if (time >= lastTime) return trailStep === null ? lastIndex : lastIndex + (time - lastTime) / trailStep\n if (time <= firstTime) return leadStep === null ? 0 : (time - firstTime) / leadStep\n // Between bars: binary-search the straddling pair and interpolate inside it. Bar steps are\n // NOT uniform (session gaps), so proportional placement within the one straddling pair is the\n // only mapping that keeps a finer-grid anchor in place — counting bars at a fixed step from\n // either end would shift it by every gap in between.\n let lo = 0\n let hi = lastIndex\n while (hi - lo > 1) {\n const mid = (lo + hi) >> 1\n const tm = numTime(mid)\n if (tm === null) return null\n if (tm <= time) lo = mid\n else hi = mid\n }\n const tLo = numTime(lo)\n const tHi = numTime(hi)\n if (tLo === null || tHi === null || tHi <= tLo) return null\n return lo + (time - tLo) / (tHi - tLo)\n }\n\n // The inverse, from the same data: fractional logicals interpolate between their neighbouring\n // bars' times, out-of-range logicals extrapolate on the edge step. Never routed through\n // `logicalToCoordinate` — a fractional input there answers 0, and `coordinateToTime(0)` then\n // returns the LEFT EDGE bar's time: a silently wrong answer rather than a null.\n const timeOfLogicalIndex = (logical: number): Time | null => {\n if (firstTime === null || lastTime === null) return null\n if (logical >= lastIndex) return trailStep === null ? (lastTime as Time) : ((lastTime + (logical - lastIndex) * trailStep) as Time)\n if (logical <= 0) return leadStep === null ? (firstTime as Time) : ((firstTime + logical * leadStep) as Time)\n const i = Math.floor(logical)\n const tLo = numTime(i)\n const tHi = numTime(i + 1)\n if (tLo === null || tHi === null) return null\n return (tLo + (logical - i) * (tHi - tLo)) as Time\n }\n\n // logical → x: ONE trustworthy point (integer index 0, exact at any scroll position) plus the\n // live barSpacing; the x axis is linear by construction. Declines only when the chart is empty.\n let xAtLogical: (logical: number) => number | null = () => null\n if (data.length > 0) {\n const x0 = ts.logicalToCoordinate(0 as Parameters<typeof ts.logicalToCoordinate>[0])\n const barSpacing = ts.options().barSpacing\n if (x0 !== null && barSpacing > 0) xAtLogical = (logical) => x0 + logical * barSpacing\n }\n\n return {\n width,\n height,\n xOf: (time) => {\n const direct = ts.timeToCoordinate(time)\n if (direct !== null) return direct\n const logical = logicalOfTime(time)\n if (logical === null) return null\n return xAtLogical(logical)\n },\n yOf: (price) => series.priceToCoordinate(price),\n timeAt: (x) => {\n const direct = ts.coordinateToTime(x)\n if (direct !== null) return direct\n const logical = ts.coordinateToLogical(x)\n if (logical === null) return null\n return timeOfLogicalIndex(logical)\n },\n priceAt: (y) => series.coordinateToPrice(y),\n barsBetween: (a, b) => {\n const la = logicalOfTime(a)\n const lb = logicalOfTime(b)\n if (la === null || lb === null) return null\n return lb - la\n },\n logicalOf: logicalOfTime,\n timeOfLogical: timeOfLogicalIndex,\n }\n}\n\n/**\n * Base class for every drawing tool: a lightweight-charts series primitive holding anchors\n * (chart coordinates), shared style, lifecycle options, and a typed tool-specific `props` bag.\n *\n * Deliberate non-features:\n * - No `autoscaleInfo`. Drawings are annotations — they must never stretch the price scale,\n * so the primitive simply does not implement it.\n * - No DOM listeners. Input (placement, dragging, selection gestures) belongs to the host app;\n * this class owns state, geometry, and pixels.\n *\n * Subclasses implement `paint` (canvas, CSS-pixel space) and `testHit`, and override\n * `defaultProps` when they carry tool-specific state. `props` round-trips through\n * `toJSON`/`fromJSON` in full — a tool's serialized form IS its complete state.\n */\n/** What a drawing writes when no host formatter has been injected: cents, a DECLARED stand-in\n * for an unhosted drawing. A host always injects the symbol's formatter; this is never a rule\n * that reads precision off the price. */\nconst UNRESOLVED_PRICE_TEXT: PriceFormatPort = (price) => price.toFixed(2)\n\nexport abstract class Drawing<P extends Record<string, unknown> = Record<string, never>>\n implements IDrawing, ISeriesPrimitive<Time>\n{\n readonly id: string\n /** Set when this drawing belongs to ONE surface; undefined when every surface showing the symbol\n * shares it. Opaque here — the host assigns and compares it. */\n scope?: string\n abstract readonly type: string\n\n protected _anchors: Anchor[]\n protected _style: DrawingStyle\n protected _options: DrawingOptions\n protected _props: P\n protected _state: DrawingState = 'normal'\n private _timeframeContext: TimeframeContext = null\n private _globalHidden = false\n private _barSource: BarSource | null = null\n\n private _chart: IChartApi | null = null\n private _series: ISeriesApi<SeriesType> | null = null\n private _requestUpdate: (() => void) | null = null\n private readonly _paneViews: IPrimitivePaneView[]\n\n constructor(\n id: string,\n anchors: Anchor[] = [],\n style: Partial<DrawingStyle> = {},\n options: Partial<DrawingOptions> = {},\n props: Partial<P> = {},\n ) {\n this.id = id\n this._anchors = anchors.map((a) => ({ ...a }))\n this._style = { ...DEFAULT_STYLE, ...style }\n this._options = normalizeOptions(options)\n this._props = { ...this.defaultProps(), ...props }\n this._paneViews = [new DrawingPaneView(this)]\n }\n\n /** Tool-specific defaults. Must not read instance fields (runs during construction). */\n protected defaultProps(): P {\n return {} as P\n }\n\n // ============ ISeriesPrimitive ============\n\n attached(params: SeriesAttachedParameter<Time>): void {\n this._chart = params.chart\n this._series = params.series\n this._requestUpdate = params.requestUpdate\n }\n\n detached(): void {\n this._chart = null\n this._series = null\n this._requestUpdate = null\n }\n\n paneViews(): readonly IPrimitivePaneView[] {\n return this._paneViews\n }\n\n priceAxisViews(): readonly ISeriesPrimitiveAxisView[] {\n return this.axisViews()\n }\n\n timeAxisViews(): readonly ISeriesPrimitiveAxisView[] {\n return this.timeViews()\n }\n\n /** Axis pills this drawing contributes (a horizontal line's price marker); default none. */\n protected axisViews(): readonly ISeriesPrimitiveAxisView[] {\n return []\n }\n\n /** Time-axis pills (a vertical line's timestamp marker); default none. */\n protected timeViews(): readonly ISeriesPrimitiveAxisView[] {\n return []\n }\n\n hitTest(x: number, y: number): PrimitiveHoveredItem | null {\n if (!this.isVisibleNow()) return null\n const viewport = this.getViewport()\n if (!viewport) return null\n if (!this.testHit({ x, y }, viewport)) return null\n return {\n cursorStyle: this._options.locked ? 'default' : (this.cursorAt({ x, y }, viewport) ?? 'pointer'),\n externalId: this.id,\n zOrder: 'normal',\n }\n }\n\n /** Position-specific hover cursor (a table divider's col-resize); null = the default pointer. */\n protected cursorAt(_point: Point, _viewport: Viewport): string | null {\n return null\n }\n\n // ============ State ============\n\n get anchors(): readonly Anchor[] {\n return this._anchors\n }\n\n get style(): Readonly<DrawingStyle> {\n return this._style\n }\n\n get options(): Readonly<DrawingOptions> {\n return this._options\n }\n\n get props(): Readonly<P> {\n return this._props\n }\n\n get state(): DrawingState {\n return this._state\n }\n\n set state(value: DrawingState) {\n this.setState(value)\n }\n\n setAnchors(anchors: Anchor[]): void {\n this._anchors = anchors.map((a) => ({ ...a }))\n this.requestUpdate()\n }\n\n updateAnchor(index: number, anchor: Anchor): void {\n if (index < 0 || index >= this._anchors.length) return\n this._anchors[index] = { ...anchor }\n this.requestUpdate()\n }\n\n /** Grow the anchor set (freehand strokes, multi-point paths). */\n appendAnchor(anchor: Anchor): void {\n this._anchors.push({ ...anchor })\n this.requestUpdate()\n }\n\n removeAnchor(index: number): void {\n if (index < 0 || index >= this._anchors.length) return\n this._anchors.splice(index, 1)\n this.requestUpdate()\n }\n\n updateStyle(patch: Partial<DrawingStyle>): void {\n this._style = { ...this._style, ...patch }\n this.requestUpdate()\n }\n\n updateOptions(patch: Partial<DrawingOptions>): void {\n this._options = {\n ...this._options,\n ...patch,\n visibility: patch.visibility ? normalizeVisibility(patch.visibility) : this._options.visibility,\n }\n this.requestUpdate()\n }\n\n setTimeframeContext(context: TimeframeContext): void {\n this._timeframeContext = context\n this.requestUpdate()\n }\n\n /** Chart-wide hide-all switch (transient view state — never serialized). */\n setGlobalHidden(hidden: boolean): void {\n this._globalHidden = hidden\n this.requestUpdate()\n }\n\n /** Host bar feed for data-driven tools (regression, profiles, VWAP, bar patterns). */\n setBarSource(source: BarSource | null): void {\n this._barSource = source\n this.requestUpdate()\n }\n\n protected bars(): readonly SourceBar[] {\n return this._barSource?.() ?? []\n }\n\n private _tickSize: number | null = null\n\n /** The symbol's smallest price move; a tick-denominated readout is omitted without it rather\n * than inferred from the data. */\n setTickSize(tick: number | null): void {\n this._tickSize = tick && tick > 0 ? tick : null\n this.requestUpdate()\n }\n\n protected tickSize(): number | null {\n return this._tickSize\n }\n\n private _priceFormat: PriceFormatPort | null = null\n\n /** The symbol's price formatter, from the host. */\n setPriceFormatter(format: PriceFormatPort | null): void {\n this._priceFormat = format\n this.requestUpdate()\n }\n\n /** A price as the symbol writes it: every label, pill and readout comes through here. */\n protected formatPrice(price: number): string {\n return (this._priceFormat ?? UNRESOLVED_PRICE_TEXT)(price)\n }\n\n private _glyphSource: GlyphSourcePort | null = null\n\n /** The host's glyph artwork source. Per instance, not per process: two charts on one page may\n * be handed different asset sets, and a module-level hook could only ever hold one. */\n setGlyphSource(source: GlyphSourcePort | null): void {\n this._glyphSource = source\n this.requestUpdate()\n }\n\n /** The artwork URL for a glyph, or null to draw it as text. */\n protected glyphUrl(glyph: string): string | null {\n return this._glyphSource ? this._glyphSource(glyph) : null\n }\n\n isVisibleNow(): boolean {\n return !this._globalHidden && this._options.visible && visibleAt(this._options.visibility, this._timeframeContext)\n }\n\n applyProps(patch: Partial<P>): void {\n this._props = { ...this._props, ...patch }\n this.requestUpdate()\n }\n\n setState(state: DrawingState): void {\n if (this._state === state) return\n this._state = state\n this.requestUpdate()\n }\n\n requestUpdate(): void {\n this._requestUpdate?.()\n }\n\n // ============ Geometry ============\n\n getViewport(): Viewport | null {\n if (!this._chart || !this._series) return null\n return viewportOf(this._chart, this._series)\n }\n\n anchorToPixel(anchor: Anchor, viewport: Viewport): Point | null {\n const x = viewport.xOf(anchor.time)\n const y = viewport.yOf(anchor.price)\n if (x === null || y === null) return null\n return { x, y }\n }\n\n /** Anchor pixels in order; entries are null while an anchor is outside the loaded range. */\n protected anchorPixels(viewport: Viewport): (Point | null)[] {\n return this._anchors.map((a) => this.anchorToPixel(a, viewport))\n }\n\n getControlPoints(viewport: Viewport): ControlPoint[] {\n const points: ControlPoint[] = []\n for (let i = 0; i < this._anchors.length; i++) {\n const p = this.anchorToPixel(this._anchors[i], viewport)\n if (p) points.push({ index: i, x: p.x, y: p.y })\n }\n return points\n }\n\n isValid(): boolean {\n return (\n this._anchors.length >= this.requiredAnchors() &&\n this._anchors.every((a) => Number.isFinite(a.price))\n )\n }\n\n /** Anchor count that completes placement. */\n abstract requiredAnchors(): number\n\n /** Paint the drawing. CSS-pixel coordinate space; the shared pane view sets the transform. */\n abstract paint(ctx: CanvasRenderingContext2D, viewport: Viewport): void\n\n /**\n * Mid-placement preview, painted while the anchor set is still short of `requiredAnchors`.\n * Default: a dashed construction polyline through the anchors placed so far — the finished\n * geometry only appears once every point exists (a fib projection draws its trend leg first).\n */\n paintConstruction(ctx: CanvasRenderingContext2D, viewport: Viewport): void {\n const points = this.anchorPixels(viewport).filter((p): p is Point => !!p)\n if (points.length < 2) return\n ctx.save()\n ctx.strokeStyle = this._style.lineColor\n ctx.lineWidth = Math.max(1, this._style.lineWidth - 0.5)\n ctx.setLineDash([4, 4])\n ctx.beginPath()\n ctx.moveTo(points[0].x, points[0].y)\n for (let i = 1; i < points.length; i++) ctx.lineTo(points[i].x, points[i].y)\n ctx.stroke()\n ctx.restore()\n }\n\n /**\n * Extra grab points beyond the anchors (an emoji's scale corners). Dragging one routes to\n * `resizeTo`. Default: none.\n */\n resizeHandles(_viewport: Viewport): Point[] {\n return []\n }\n\n resizeTo(_handleIndex: number, _point: Point, _viewport: Viewport): void {}\n\n private _textHint: { cx: number; cy: number; angle: number; halfW: number; halfH: number } | null = null\n\n /** An inline text editor is open on this drawing (transient view state — never serialized). */\n textEditing = false\n\n /**\n * \"+ Add text\" hint above a selected text-capable drawing that has no text yet. Pressing the\n * painted region routes to the inline text editor. Two-point drawings ride the segment's angle\n * (the hint sits along a sloped trend line); everything else sits level above the bounds.\n * Painted as UI chrome (fixed muted paint), not with the drawing's own text style.\n */\n /** The hint label's CENTER: level above the drawing's bounds by default. Tools whose text\n * rides their own geometry override — a trend line's hint slopes with the segment, a\n * rectangle's sits dead-center in the box, an arrow marker's at the butt end. Two corner\n * anchors are NOT a segment (a box tool's hint must stay level). */\n protected textHintPlacement(points: Point[]): { x: number; y: number; angle: number } {\n return {\n x: points.reduce((sum, p) => sum + p.x, 0) / points.length,\n y: Math.max(12, Math.min(...points.map((p) => p.y)) - 16),\n angle: 0,\n }\n }\n\n paintTextHint(ctx: CanvasRenderingContext2D, viewport: Viewport): void {\n this._textHint = null\n if (this.textEditing) return\n // The invitation belongs to a tool that DECLARES a label. A stored drawing may carry a text\n // key its tool no longer has, and a stray key is not a channel.\n if (!('text' in (this.defaultProps() as Record<string, unknown>))) return\n const text = (this._props as Record<string, unknown>).text\n if (typeof text !== 'string' || text !== '') return\n const points = this.anchorPixels(viewport).filter((p): p is Point => !!p)\n if (points.length === 0) return\n const { x: mx, y: my, angle } = this.textHintPlacement(points)\n const label = '+ Add text'\n ctx.save()\n ctx.translate(mx, my)\n ctx.rotate(angle)\n ctx.font = '12px ui-sans-serif, system-ui, sans-serif'\n ctx.textAlign = 'center'\n ctx.textBaseline = 'middle'\n ctx.setLineDash([])\n ctx.fillStyle = 'rgba(178, 181, 190, 0.95)'\n ctx.fillText(label, 0, 0)\n const width = ctx.measureText(label).width\n ctx.restore()\n this._textHint = {\n cx: mx,\n cy: my,\n angle,\n halfW: width / 2 + 6,\n halfH: 10,\n }\n }\n\n hitTextHint(point: Point): boolean {\n const r = this._textHint\n if (!r) return false\n const dx = point.x - r.cx\n const dy = point.y - r.cy\n const cos = Math.cos(-r.angle)\n const sin = Math.sin(-r.angle)\n const rx = dx * cos - dy * sin\n const ry = dx * sin + dy * cos\n return Math.abs(rx) <= r.halfW && Math.abs(ry) <= r.halfH\n }\n\n textHintAnchor(): { x: number; y: number; angle: number } | null {\n const r = this._textHint\n return r ? { x: r.cx, y: r.cy, angle: r.angle } : null\n }\n\n abstract testHit(point: Point, viewport: Viewport): boolean\n\n // ============ Serialization ============\n\n toJSON(): SerializedDrawing {\n const props = this._props as Record<string, unknown>\n return {\n v: 2,\n id: this.id,\n type: this.type,\n anchors: this._anchors.map((a) => ({ ...a })),\n style: { ...this._style },\n options: { ...this._options },\n ...(Object.keys(props).length > 0 ? { props: { ...props } } : {}),\n ...(this.scope === undefined ? {} : { scope: this.scope }),\n }\n }\n\n fromJSON(data: SerializedDrawing): void {\n this._anchors = data.anchors.map((a) => ({ ...a }))\n this._style = { ...DEFAULT_STYLE, ...data.style }\n this._options = normalizeOptions(data.options)\n this._props = { ...this.defaultProps(), ...(data.props as Partial<P> | undefined) }\n this.scope = data.scope\n this.requestUpdate()\n }\n}\n","import type { IChartApi, ISeriesApi, SeriesType } from 'lightweight-charts'\n\nimport type {\n DrawingEvent,\n DrawingEventCallback,\n DrawingEventType,\n IDrawing,\n Point,\n GlyphSourcePort,\n PriceFormatPort,\n SerializedDrawing,\n Viewport,\n} from './types'\nimport type { AnyDrawing } from './drawing'\nimport { viewportOf } from './drawing'\nimport type { TimeframeContext } from './visibility'\nimport type { BarSource } from './bars'\n\n/**\n * The drawing model for one chart: an ordered store of drawings attached to a series, with\n * selection, top-most hit-testing, and serialization. Deliberately input-free — pointer and\n * keyboard handling live in the host app, which calls into this model. Attaching is what makes\n * a drawing render (drawings are series primitives).\n */\nexport class DrawingManager {\n private readonly _drawings = new Map<string, AnyDrawing>()\n private _order: string[] = [] // insertion order; later = painted and hit-tested on top\n private _selectedId: string | null = null\n private _chart: IChartApi | null = null\n private _series: ISeriesApi<SeriesType> | null = null\n private _timeframeContext: TimeframeContext = null\n private _allHidden = false\n private _barSource: BarSource | null = null\n private _tickSize: number | null = null\n private _priceFormat: PriceFormatPort | null = null\n private _glyphSource: GlyphSourcePort | null = null\n private readonly _listeners = new Map<DrawingEventType, Set<DrawingEventCallback>>()\n\n /** Host bar feed, broadcast to every drawing (data-driven tools read it at paint time). */\n setBarSource(source: BarSource | null): void {\n this._barSource = source\n for (const drawing of this._drawings.values()) drawing.setBarSource(source)\n }\n\n /** The symbol's smallest price move, broadcast to every drawing (tick-denominated readouts). */\n setTickSize(tick: number | null): void {\n this._tickSize = tick\n for (const drawing of this._drawings.values()) drawing.setTickSize(tick)\n }\n\n /** The symbol's price formatter, broadcast to every drawing: the one port every label, pill\n * and readout writes prices through. The host resolves it from the symbol's declared format. */\n setPriceFormatter(format: PriceFormatPort | null): void {\n this._priceFormat = format\n for (const drawing of this._drawings.values()) drawing.setPriceFormatter(format)\n }\n\n /** The host's glyph artwork source, broadcast to every drawing. Per manager, so two charts in\n * one document can draw different asset sets. */\n setGlyphSource(source: GlyphSourcePort | null): void {\n this._glyphSource = source\n for (const drawing of this._drawings.values()) drawing.setGlyphSource(source)\n }\n\n /** Broadcast the chart's timeframe so per-timeframe visibility rules apply. */\n setTimeframeContext(context: TimeframeContext): void {\n this._timeframeContext = context\n for (const drawing of this._drawings.values()) drawing.setTimeframeContext(context)\n }\n\n /** Chart-wide hide-all: every drawing (and its axis pills) disappears until toggled back. */\n setAllHidden(hidden: boolean): void {\n this._allHidden = hidden\n for (const drawing of this._drawings.values()) drawing.setGlobalHidden(hidden)\n }\n\n allHidden(): boolean {\n return this._allHidden\n }\n\n attach(chart: IChartApi, series: ISeriesApi<SeriesType>): void {\n if (this._chart) this.detach()\n this._chart = chart\n this._series = series\n for (const id of this._order) {\n const drawing = this._drawings.get(id)\n if (drawing) series.attachPrimitive(drawing)\n }\n }\n\n detach(): void {\n if (this._series) {\n for (const drawing of this._drawings.values()) {\n try {\n this._series.detachPrimitive(drawing)\n } catch {\n /* series already disposed */\n }\n }\n }\n this._chart = null\n this._series = null\n }\n\n isAttached(): boolean {\n return this._chart !== null\n }\n\n // ============ Store ============\n\n add(drawing: IDrawing): void {\n if (this._drawings.has(drawing.id)) return\n // Every IDrawing is a Drawing subclass (the registry only makes those); the store needs the\n // class type because attaching requires the series-primitive surface.\n const concrete = drawing as AnyDrawing\n concrete.setTimeframeContext(this._timeframeContext)\n concrete.setGlobalHidden(this._allHidden)\n concrete.setBarSource(this._barSource)\n concrete.setTickSize(this._tickSize)\n concrete.setPriceFormatter(this._priceFormat)\n concrete.setGlyphSource(this._glyphSource)\n this._drawings.set(concrete.id, concrete)\n this._order.push(concrete.id)\n this._series?.attachPrimitive(concrete)\n this.emit('drawing:added', { drawingId: concrete.id, drawing: concrete })\n }\n\n remove(id: string): void {\n const drawing = this._drawings.get(id)\n if (!drawing) return\n if (this._selectedId === id) this.deselect()\n if (this._series) {\n try {\n this._series.detachPrimitive(drawing)\n } catch {\n /* series already disposed */\n }\n }\n this._drawings.delete(id)\n this._order = this._order.filter((d) => d !== id)\n this.emit('drawing:removed', { drawingId: id })\n }\n\n get(id: string): IDrawing | undefined {\n return this._drawings.get(id)\n }\n\n /** All drawings in insertion order (bottom-most first). */\n all(): IDrawing[] {\n return this._order\n .map((id) => this._drawings.get(id))\n .filter((d): d is AnyDrawing => !!d)\n }\n\n clear(): void {\n this.deselect()\n if (this._series) {\n for (const drawing of this._drawings.values()) {\n try {\n this._series.detachPrimitive(drawing)\n } catch {\n /* series already disposed */\n }\n }\n }\n this._drawings.clear()\n this._order = []\n this.emit('drawing:cleared', {})\n }\n\n // ============ Selection ============\n\n select(id: string): void {\n const drawing = this._drawings.get(id)\n if (!drawing || this._selectedId === id) return\n if (this._selectedId) this._drawings.get(this._selectedId)?.setState('normal')\n drawing.setState('selected')\n this._selectedId = id\n this.emit('drawing:selected', { drawingId: id, drawing })\n }\n\n deselect(): void {\n if (!this._selectedId) return\n const id = this._selectedId\n this._drawings.get(id)?.setState('normal')\n this._selectedId = null\n this.emit('drawing:deselected', { drawingId: id })\n }\n\n selected(): IDrawing | null {\n return (this._selectedId && this._drawings.get(this._selectedId)) || null\n }\n\n // ============ Stacking ============\n\n /** Paint above everything else (and hit-test first, since hit order follows zIndex). */\n bringToFront(id: string): void {\n const drawing = this._drawings.get(id)\n if (!drawing) return\n const top = Math.max(0, ...this.all().map((d) => d.options.zIndex))\n drawing.updateOptions({ zIndex: top + 1 })\n this.restack()\n }\n\n sendToBack(id: string): void {\n const drawing = this._drawings.get(id)\n if (!drawing) return\n const bottom = Math.min(0, ...this.all().map((d) => d.options.zIndex))\n drawing.updateOptions({ zIndex: bottom - 1 })\n this.restack()\n }\n\n /** One step up in the paint order — swap with the neighbour directly above (no-op at the\n * front). Every step RENUMBERS the whole stack to a dense 0..n-1 sequence: repeated\n * to-front/to-back extremes otherwise drift zIndexes apart until \"one step\" and \"adjacent\n * number\" stop meaning the same thing. */\n bringForward(id: string): void {\n this.stepStack(id, +1)\n }\n\n /** One step down in the paint order — swap with the neighbour directly below (no-op at the back). */\n sendBackward(id: string): void {\n this.stepStack(id, -1)\n }\n\n private stepStack(id: string, dir: 1 | -1): void {\n const sorted = this.visualOrder()\n const at = sorted.findIndex((d) => d.id === id)\n if (at < 0 || at + dir < 0 || at + dir >= sorted.length) return\n const other = sorted[at + dir]!\n sorted[at + dir] = sorted[at]!\n sorted[at] = other\n sorted.forEach((d, i) => {\n if (d.options.zIndex !== i) d.updateOptions({ zIndex: i })\n })\n this.restack()\n }\n\n /** Where a drawing sits in the paint order — menus disable the moves that cannot apply\n * (a drawing already at the back has nothing below it to step behind). */\n stackPosition(id: string): { atFront: boolean; atBack: boolean } {\n const sorted = this.visualOrder()\n const at = sorted.findIndex((d) => d.id === id)\n return { atFront: at < 0 || at === sorted.length - 1, atBack: at <= 0 }\n }\n\n /** The paint order, bottom first: (zIndex, insertion) — the ONE sort restack keys off too. */\n private visualOrder(): AnyDrawing[] {\n return this._order\n .map((oid) => this._drawings.get(oid))\n .filter((d): d is AnyDrawing => !!d)\n .sort((a, b) => a.options.zIndex - b.options.zIndex)\n }\n\n /** Re-attach primitives so PAINT order follows (zIndex, insertion) — the chart paints\n * primitives in attach order, so stacking changes must re-key that order. */\n private restack(): void {\n if (!this._series) return\n const sorted = this.visualOrder()\n for (const drawing of sorted) {\n try {\n this._series.detachPrimitive(drawing)\n this._series.attachPrimitive(drawing)\n } catch {\n /* series disposed mid-restack */\n }\n }\n }\n\n // ============ Hit testing ============\n\n getViewport(): Viewport | null {\n if (!this._chart || !this._series) return null\n return viewportOf(this._chart, this._series)\n }\n\n /**\n * Top-most visible drawing at a pane point: higher zIndex wins, then later insertion.\n * The selected drawing is tried first so a stacked selection stays grabbable.\n */\n hitTest(point: Point): IDrawing | null {\n const viewport = this.getViewport()\n if (!viewport) return null\n const sel = this.selected()\n if (sel && sel.isVisibleNow() && sel.testHit(point, viewport)) return sel\n const byTopmost = [...this._order].reverse().map((id) => this._drawings.get(id))\n byTopmost.sort((a, b) => (b?.options.zIndex ?? 0) - (a?.options.zIndex ?? 0))\n for (const drawing of byTopmost) {\n if (!drawing || !drawing.isVisibleNow()) continue\n if (drawing.testHit(point, viewport)) return drawing\n }\n return null\n }\n\n // ============ Serialization ============\n\n export(): SerializedDrawing[] {\n return this.all().map((d) => d.toJSON())\n }\n\n // ============ Events ============\n\n on(event: DrawingEventType, callback: DrawingEventCallback): () => void {\n let set = this._listeners.get(event)\n if (!set) {\n set = new Set()\n this._listeners.set(event, set)\n }\n set.add(callback)\n return () => {\n set.delete(callback)\n }\n }\n\n private emit(type: DrawingEventType, data: Omit<DrawingEvent, 'type'>): void {\n const listeners = this._listeners.get(type)\n if (!listeners) return\n const event: DrawingEvent = { type, ...data }\n for (const callback of listeners) callback(event)\n }\n}\n","import { MismatchDirection } from 'lightweight-charts'\nimport type { IChartApi, ISeriesApi, SeriesType, Time } from 'lightweight-charts'\n\nimport type { Anchor, Point } from './types'\n\nexport type MagnetMode = 'off' | 'weak' | 'strong'\n\n/** Weak magnet only pulls when the pointer is already this close (px) to an OHLC value. */\nconst WEAK_RADIUS = 14\n\nexport interface OhlcBar {\n time: Time\n open: number\n high: number\n low: number\n close: number\n}\n\n/**\n * The pure snap: nearest OHLC value of one bar, in pixel space. `weak` returns null when every\n * value is farther than the pull radius; `strong` always takes the nearest.\n */\nexport function snapToBar(\n bar: OhlcBar,\n pointerY: number,\n priceToY: (price: number) => number | null,\n mode: Exclude<MagnetMode, 'off'>,\n): number | null {\n let best: number | null = null\n let bestDistance = Infinity\n for (const price of [bar.open, bar.high, bar.low, bar.close]) {\n const y = priceToY(price)\n if (y === null) continue\n const distance = Math.abs(y - pointerY)\n if (distance < bestDistance) {\n bestDistance = distance\n best = price\n }\n }\n if (best === null) return null\n if (mode === 'weak' && bestDistance > WEAK_RADIUS) return null\n return best\n}\n\n/**\n * Snap a pane point to the nearest bar's nearest OHLC value. Returns the snapped anchor (time\n * pinned to the bar, price to the chosen value), or null when nothing pulls — the caller then\n * uses the raw pointer anchor.\n */\nexport function magnetSnap(\n chart: IChartApi,\n series: ISeriesApi<SeriesType>,\n point: Point,\n mode: MagnetMode,\n): Anchor | null {\n if (mode === 'off') return null\n let bar: OhlcBar | null = null\n try {\n const logical = chart.timeScale().coordinateToLogical(point.x)\n if (logical === null) return null\n const item = series.dataByIndex(Math.round(logical), MismatchDirection.NearestLeft)\n if (!item || !('open' in item)) return null\n bar = item as OhlcBar\n } catch {\n return null\n }\n const price = snapToBar(bar, point.y, (p) => series.priceToCoordinate(p), mode)\n if (price === null) return null\n return { time: bar.time, price }\n}\n","import type { Point } from './types'\n\n/** Distance from a point to the segment [a, b]. */\nexport function distanceToSegment(p: Point, a: Point, b: Point): number {\n const dx = b.x - a.x\n const dy = b.y - a.y\n const lengthSq = dx * dx + dy * dy\n if (lengthSq === 0) return Math.hypot(p.x - a.x, p.y - a.y)\n const t = Math.max(0, Math.min(1, ((p.x - a.x) * dx + (p.y - a.y) * dy) / lengthSq))\n return Math.hypot(p.x - (a.x + t * dx), p.y - (a.y + t * dy))\n}\n\n/** Distance from a point to the infinite line through a and b. */\nexport function distanceToLine(p: Point, a: Point, b: Point): number {\n const dx = b.x - a.x\n const dy = b.y - a.y\n const lengthSq = dx * dx + dy * dy\n if (lengthSq === 0) return Math.hypot(p.x - a.x, p.y - a.y)\n return Math.abs(dy * p.x - dx * p.y + b.x * a.y - b.y * a.x) / Math.sqrt(lengthSq)\n}\n\nexport function midpoint(a: Point, b: Point): Point {\n return { x: (a.x + b.x) / 2, y: (a.y + b.y) / 2 }\n}\n\n/** Angle of a→b in radians, y-down screen space. */\nexport function angleOf(a: Point, b: Point): number {\n return Math.atan2(b.y - a.y, b.x - a.x)\n}\n\n/** Angle of a→b folded into (-90°, 90°] so text painted along the segment always reads upright. */\nexport function segmentTextAngle(a: Point, b: Point): number {\n let angle = angleOf(a, b)\n if (angle > Math.PI / 2) angle -= Math.PI\n if (angle < -Math.PI / 2) angle += Math.PI\n return angle\n}\n\n/**\n * Extend the segment a→b along its own direction to the pane bounds. `left` extends behind `a`\n * (opposite the a→b direction), `right` extends beyond `b`. A zero-length segment is returned\n * unchanged — it has no direction to extend along.\n */\nexport function extendSegment(\n a: Point,\n b: Point,\n width: number,\n height: number,\n left: boolean,\n right: boolean,\n): { a: Point; b: Point } {\n const dx = b.x - a.x\n const dy = b.y - a.y\n if (dx === 0 && dy === 0) return { a, b }\n\n // Parametric p(t) = a + t·d: find the t range where the line crosses the pane box, then clamp\n // the requested sides to it. t=0 is `a`, t=1 is `b`.\n let tMin = -Infinity\n let tMax = Infinity\n if (dx !== 0) {\n const t0 = (0 - a.x) / dx\n const t1 = (width - a.x) / dx\n tMin = Math.min(t0, t1)\n tMax = Math.max(t0, t1)\n } else {\n if (a.x < 0 || a.x > width) return { a, b }\n }\n if (dy !== 0) {\n const t0 = (0 - a.y) / dy\n const t1 = (height - a.y) / dy\n tMin = Math.max(tMin, Math.min(t0, t1))\n tMax = Math.min(tMax, Math.max(t0, t1))\n } else if (a.y < 0 || a.y > height) {\n return { a, b }\n }\n if (tMin > tMax) return { a, b } // the line never crosses the pane\n\n const tA = left ? Math.min(0, tMin) : 0\n const tB = right ? Math.max(1, tMax) : 1\n return {\n a: { x: a.x + tA * dx, y: a.y + tA * dy },\n b: { x: a.x + tB * dx, y: a.y + tB * dy },\n }\n}\n","// Decoded bitmaps, shared between whoever chose the picture and the drawing that paints it.\n//\n// A data URL is not a bitmap: handing one to an <img> costs a base64 parse plus a decode, and that\n// work happens asynchronously, so an unprimed image would appear a beat AFTER the click that placed\n// it, even though the picker already decoded the identical payload a moment earlier to show its\n// preview. Priming the result here means the drawing finds a ready bitmap and paints it on the very\n// first frame.\n//\n// Keyed by the data URL itself, which is exactly the identity that matters: the same payload is the\n// same picture, and two drawings sharing one image share one decode.\n\nconst cache = new Map<string, HTMLImageElement>()\n\n/** Bitmaps are megabytes of decoded pixels, so the map is bounded and evicts oldest-first. Well\n * above any realistic number of images on one chart, low enough that it cannot become a leak. */\nconst MAX_ENTRIES = 24\n\nexport function primeImageBitmap(key: string, image: HTMLImageElement): void {\n if (!key) return\n if (cache.has(key)) cache.delete(key) // re-insert so it counts as most recently used\n cache.set(key, image)\n while (cache.size > MAX_ENTRIES) {\n const oldest = cache.keys().next()\n if (oldest.done) break\n cache.delete(oldest.value)\n }\n}\n\n/** A bitmap already decoded for this payload, or null when it has to be loaded the slow way. */\nexport function cachedImageBitmap(key: string): HTMLImageElement | null {\n if (!key) return null\n const hit = cache.get(key)\n if (!hit) return null\n // A cached element that never finished decoding is no use to a synchronous paint.\n return hit.complete && hit.naturalWidth > 0 ? hit : null\n}\n","import type { ISeriesPrimitiveAxisView } from 'lightweight-charts'\n\nexport interface AxisLabelSource {\n coordinate(): number | null\n text(): string\n color(): string\n visible(): boolean\n}\n\n/** A pill on the price/time axis (a drawing's level marker). */\nexport class AxisLabel implements ISeriesPrimitiveAxisView {\n private readonly _source: AxisLabelSource\n\n constructor(source: AxisLabelSource) {\n this._source = source\n }\n\n coordinate(): number {\n return this._source.coordinate() ?? -1_000_000\n }\n\n text(): string {\n return this._source.text()\n }\n\n textColor(): string {\n return '#ffffff'\n }\n\n backColor(): string {\n return this._source.color()\n }\n\n visible(): boolean {\n return this._source.visible() && this._source.coordinate() !== null\n }\n}\n","import type { ISeriesPrimitiveAxisView } from 'lightweight-charts'\n\nimport type { Point, Viewport } from '../core/types'\nimport { Drawing } from '../core/drawing'\nimport { angleOf, distanceToSegment, extendSegment, midpoint, segmentTextAngle } from '../core/geometry'\nimport {\n applyStroke,\n paintArrowHead,\n paintLabel,\n strokeSegment,\n withAlpha,\n} from '../render/canvas'\nimport { AxisLabel } from '../render/axis-view'\n\nexport type LineEnd = 'normal' | 'arrow'\n\n/** The two-point line family's full option set. Tool identity = these defaults. */\nexport type TrendLineProps = {\n /** Free label rendered along the line (edited in the settings dialog's Text tab). */\n text: string\n extendLeft: boolean\n extendRight: boolean\n leftEnd: LineEnd\n rightEnd: LineEnd\n /** Marker at the segment's midpoint. */\n middlePoint: boolean\n /** Price pill beside each end point. */\n showPriceLabels: boolean\n /** Stats readout items (price delta, percent change, bar count, span, slope angle). */\n showPriceRange: boolean\n showPercentChange: boolean\n showBarsRange: boolean\n showDateTimeRange: boolean\n showAngle: boolean\n statsPosition: 'left' | 'center' | 'right'\n}\n\nconst LINE_PROPS: TrendLineProps = {\n text: '',\n extendLeft: false,\n extendRight: false,\n leftEnd: 'normal',\n rightEnd: 'normal',\n middlePoint: false,\n showPriceLabels: false,\n showPriceRange: false,\n showPercentChange: false,\n showBarsRange: false,\n showDateTimeRange: false,\n showAngle: false,\n statsPosition: 'center',\n}\n\nfunction hitTolerance(lineWidth: number): number {\n return Math.max(6, lineWidth / 2 + 4)\n}\n\n/**\n * Two-anchor straight line. The whole family (trend line, ray, extended line, arrow, info line,\n * trend angle) is this geometry under different prop defaults and decorations.\n */\nexport class TrendLine extends Drawing<TrendLineProps> {\n readonly type: string = 'trend_line'\n\n protected override defaultProps(): TrendLineProps {\n return { ...LINE_PROPS }\n }\n\n requiredAnchors(): number {\n return 2\n }\n\n /** The hint rides the segment's slope, lifted off the line where the text itself paints. */\n protected override textHintPlacement(points: Point[]): { x: number; y: number; angle: number } {\n if (points.length < 2) return super.textHintPlacement(points)\n const angle = segmentTextAngle(points[0], points[1])\n return {\n x: (points[0].x + points[1].x) / 2 + 16 * Math.sin(angle),\n y: (points[0].y + points[1].y) / 2 - 16 * Math.cos(angle),\n angle,\n }\n }\n\n /** The on-screen segment after extension — the shared basis for painting and hit-testing. */\n protected segment(viewport: Viewport): { a: Point; b: Point } | null {\n const [pa, pb] = this.anchorPixels(viewport)\n if (!pa || !pb) return null\n const { extendLeft, extendRight } = this.props\n if (!extendLeft && !extendRight) return { a: pa, b: pb }\n return extendSegment(pa, pb, viewport.width, viewport.height, extendLeft, extendRight)\n }\n\n paint(ctx: CanvasRenderingContext2D, viewport: Viewport): void {\n const seg = this.segment(viewport)\n if (!seg) return\n applyStroke(ctx, this.style)\n strokeSegment(ctx, seg.a, seg.b)\n if (this.props.leftEnd === 'arrow') paintArrowHead(ctx, seg.b, seg.a, this.style)\n if (this.props.rightEnd === 'arrow') paintArrowHead(ctx, seg.a, seg.b, this.style)\n this.paintProps(ctx, viewport)\n this.paintDecorations(ctx, viewport)\n }\n\n /** Prop-driven ink shared by the family: midpoint marker, end price pills, the stats block. */\n private paintProps(ctx: CanvasRenderingContext2D, viewport: Viewport): void {\n const [pa, pb] = this.anchorPixels(viewport)\n if (!pa || !pb) return\n\n if (this.props.middlePoint) {\n const mid = midpoint(pa, pb)\n ctx.save()\n ctx.setLineDash([])\n ctx.fillStyle = this.style.lineColor\n ctx.beginPath()\n ctx.arc(mid.x, mid.y, Math.max(2.5, this.style.lineWidth), 0, Math.PI * 2)\n ctx.fill()\n ctx.restore()\n }\n\n if (this.props.showPriceLabels) {\n const [a, b] = this.anchors\n paintLabel(ctx, this.formatPrice(a.price), { x: pa.x - 8, y: pa.y }, this.style, {\n align: 'right',\n background: withAlpha(this.style.lineColor, 0.2),\n })\n paintLabel(ctx, this.formatPrice(b.price), { x: pb.x + 8, y: pb.y }, this.style, {\n background: withAlpha(this.style.lineColor, 0.2),\n })\n }\n\n // Text and stats ride the segment's angle — a label on a rising line slopes with it.\n const textAngle = segmentTextAngle(pa, pb)\n\n if (this.props.text) {\n const mid = midpoint(pa, pb)\n ctx.save()\n ctx.translate(mid.x, mid.y)\n ctx.rotate(textAngle)\n paintLabel(ctx, this.props.text, { x: 0, y: -14 }, this.style, { align: 'center' })\n ctx.restore()\n }\n\n const stats = this.statsText(viewport)\n if (stats) {\n const t = this.props.statsPosition === 'left' ? 0.12 : this.props.statsPosition === 'right' ? 0.88 : 0.5\n // The stats pill drops below its usual perch when a text label already sits above the line.\n const lift = this.props.text && this.props.statsPosition === 'center' ? -32 : -14\n ctx.save()\n ctx.translate(pa.x + (pb.x - pa.x) * t, pa.y + (pb.y - pa.y) * t)\n ctx.rotate(textAngle)\n paintLabel(ctx, stats, { x: 0, y: lift }, this.style, { align: 'center', background: withAlpha('#1b1f27', 0.92) })\n ctx.restore()\n }\n }\n\n protected statsText(viewport: Viewport): string | null {\n const [a, b] = this.anchors\n if (!a || !b) return null\n const parts: string[] = []\n const dPrice = b.price - a.price\n if (this.props.showPriceRange) {\n parts.push(`${dPrice >= 0 ? '+' : ''}${this.formatPrice(dPrice)}`)\n }\n if (this.props.showPercentChange) {\n const pct = a.price !== 0 ? (dPrice / Math.abs(a.price)) * 100 : 0\n parts.push(`${pct >= 0 ? '+' : ''}${pct.toFixed(2)}%`)\n }\n if (this.props.showBarsRange) {\n const bars = viewport.barsBetween(a.time, b.time)\n if (bars !== null) parts.push(`${Math.round(bars)} bars`)\n }\n if (this.props.showDateTimeRange) {\n const secs = Math.abs(Number(b.time) - Number(a.time))\n if (Number.isFinite(secs) && secs > 0) {\n const d = Math.floor(secs / 86400)\n const h = Math.floor((secs % 86400) / 3600)\n const m = Math.floor((secs % 3600) / 60)\n parts.push(d > 0 ? `${d}d ${h}h` : h > 0 ? `${h}h ${m}m` : `${m}m`)\n }\n }\n if (this.props.showAngle) {\n const [pa, pb] = this.anchorPixels(viewport)\n if (pa && pb) parts.push(`${(-angleOf(pa, pb) * (180 / Math.PI)).toFixed(0)}°`)\n }\n return parts.length ? parts.join(' · ') : null\n }\n\n /** Extra ink beyond the shared prop set — the family variants override. */\n protected paintDecorations(_ctx: CanvasRenderingContext2D, _viewport: Viewport): void {}\n\n testHit(point: Point, viewport: Viewport): boolean {\n const seg = this.segment(viewport)\n if (!seg) return false\n return distanceToSegment(point, seg.a, seg.b) <= hitTolerance(this.style.lineWidth)\n }\n}\n\nexport class Ray extends TrendLine {\n override readonly type = 'ray'\n\n protected override defaultProps(): TrendLineProps {\n return { ...LINE_PROPS, extendRight: true }\n }\n}\n\nexport class ExtendedLine extends TrendLine {\n override readonly type = 'extended'\n\n protected override defaultProps(): TrendLineProps {\n return { ...LINE_PROPS, extendLeft: true, extendRight: true }\n }\n}\n\nexport class Arrow extends TrendLine {\n override readonly type = 'arrow'\n\n protected override defaultProps(): TrendLineProps {\n return { ...LINE_PROPS, rightEnd: 'arrow' }\n }\n}\n\n/** Trend line whose identity is the full measurement readout. */\nexport class InfoLine extends TrendLine {\n override readonly type = 'info_line'\n\n protected override defaultProps(): TrendLineProps {\n return { ...LINE_PROPS, showPriceRange: true, showBarsRange: true, showAngle: true }\n }\n}\n\n/** Trend line that reports its slope, with a horizontal reference arc at the origin. */\nexport class TrendAngle extends TrendLine {\n override readonly type = 'trend_angle'\n\n protected override paintDecorations(ctx: CanvasRenderingContext2D, viewport: Viewport): void {\n const [pa, pb] = this.anchorPixels(viewport)\n if (!pa || !pb) return\n const angle = angleOf(pa, pb)\n const angleDeg = -angle * (180 / Math.PI)\n const radius = Math.min(36, Math.hypot(pb.x - pa.x, pb.y - pa.y) / 2)\n if (radius > 8) {\n ctx.save()\n applyStroke(ctx, this.style)\n ctx.lineWidth = 1\n ctx.setLineDash([2, 3])\n // Reference horizontal from the first anchor, then the sweep up/down to the line's angle.\n ctx.beginPath()\n ctx.moveTo(pa.x, pa.y)\n ctx.lineTo(pa.x + radius + 12, pa.y)\n ctx.stroke()\n ctx.beginPath()\n // Canvas arcs sweep clockwise in y-down space; draw from 0 to the line's angle the short way.\n ctx.arc(pa.x, pa.y, radius, 0, angle, angle < 0)\n ctx.stroke()\n ctx.restore()\n }\n paintLabel(ctx, `${angleDeg.toFixed(0)}°`, { x: pa.x + radius + 18, y: pa.y }, this.style, {\n background: withAlpha('#1b1f27', 0.92),\n })\n }\n}\n\nexport type HorizontalLineProps = {\n /** Free label rendered above the line's left side. */\n text: string\n /** Price pill on the axis at the line's level. */\n showPrice: boolean\n}\n\n/** Full-width horizontal line at one price. */\nexport class HorizontalLine extends Drawing<HorizontalLineProps> {\n readonly type: string = 'horizontal_line'\n\n private readonly _axisViews = [\n new AxisLabel({\n coordinate: () => {\n const anchor = this.anchors[0]\n const viewport = this.getViewport()\n if (!anchor || !viewport) return null\n return viewport.yOf(anchor.price)\n },\n text: () => this.formatPrice(this.anchors[0]?.price ?? 0),\n color: () => this.style.lineColor,\n visible: () => this.props.showPrice && this.isVisibleNow(),\n }),\n ]\n\n protected override defaultProps(): HorizontalLineProps {\n return { text: '', showPrice: true }\n }\n\n protected override axisViews(): readonly ISeriesPrimitiveAxisView[] {\n return this._axisViews\n }\n\n requiredAnchors(): number {\n return 1\n }\n\n paint(ctx: CanvasRenderingContext2D, viewport: Viewport): void {\n const y = viewport.yOf(this.anchors[0]?.price ?? NaN)\n if (y === null || !Number.isFinite(y)) return\n applyStroke(ctx, this.style)\n strokeSegment(ctx, { x: this.leftEdge(viewport), y }, { x: viewport.width, y })\n if (this.props.text) {\n paintLabel(ctx, this.props.text, { x: this.leftEdge(viewport) + 8, y: y - 12 }, this.style)\n }\n }\n\n /** Where the line starts; the ray variant starts at its anchor. */\n protected leftEdge(_viewport: Viewport): number {\n return 0\n }\n\n testHit(point: Point, viewport: Viewport): boolean {\n const y = viewport.yOf(this.anchors[0]?.price ?? NaN)\n if (y === null) return false\n return point.x >= this.leftEdge(viewport) - 4 && Math.abs(point.y - y) <= hitTolerance(this.style.lineWidth)\n }\n}\n\n/** Horizontal line from its anchor rightward. */\nexport class HorizontalRay extends HorizontalLine {\n override readonly type = 'horizontal_ray'\n\n protected override leftEdge(viewport: Viewport): number {\n const anchor = this.anchors[0]\n if (!anchor) return 0\n const p = this.anchorToPixel(anchor, viewport)\n return p ? p.x : 0\n }\n}\n\n/** Time-axis pill text for a numeric (unix-seconds) anchor time. */\nfunction timeText(time: unknown): string {\n const t = Number(time)\n if (!Number.isFinite(t)) return String(time)\n const d = new Date(t * 1000)\n const pad = (n: number) => String(n).padStart(2, '0')\n return `${d.getUTCFullYear()}-${pad(d.getUTCMonth() + 1)}-${pad(d.getUTCDate())} ${pad(d.getUTCHours())}:${pad(d.getUTCMinutes())}`\n}\n\nexport type VerticalLineProps = {\n /** Free label rendered beside the line's top. */\n text: string\n /** Timestamp pill on the time axis. */\n showTime: boolean\n}\n\n/** Full-height vertical line at one time. */\nexport class VerticalLine extends Drawing<VerticalLineProps> {\n readonly type = 'vertical_line'\n\n private readonly _timeViews = [\n new AxisLabel({\n coordinate: () => {\n const anchor = this.anchors[0]\n const viewport = this.getViewport()\n if (!anchor || !viewport) return null\n return viewport.xOf(anchor.time)\n },\n text: () => timeText(this.anchors[0]?.time),\n color: () => this.style.lineColor,\n visible: () => this.props.showTime && this.isVisibleNow(),\n }),\n ]\n\n protected override defaultProps(): VerticalLineProps {\n return { text: '', showTime: true }\n }\n\n protected override timeViews(): readonly ISeriesPrimitiveAxisView[] {\n return this._timeViews\n }\n\n requiredAnchors(): number {\n return 1\n }\n\n paint(ctx: CanvasRenderingContext2D, viewport: Viewport): void {\n const anchor = this.anchors[0]\n if (!anchor) return\n const x = viewport.xOf(anchor.time)\n if (x === null) return\n applyStroke(ctx, this.style)\n strokeSegment(ctx, { x, y: 0 }, { x, y: viewport.height })\n if (this.props.text) {\n paintLabel(ctx, this.props.text, { x: x + 6, y: 14 }, this.style)\n }\n }\n\n testHit(point: Point, viewport: Viewport): boolean {\n const anchor = this.anchors[0]\n if (!anchor) return false\n const x = viewport.xOf(anchor.time)\n if (x === null) return false\n return Math.abs(point.x - x) <= hitTolerance(this.style.lineWidth)\n }\n}\n\nexport type CrossLineProps = {\n /** Price pill on the axis at the cross's level. */\n showPrice: boolean\n /** Timestamp pill on the time axis at the cross's time. */\n showTime: boolean\n}\n\n/** Crosshair pinned to one point: a horizontal and a vertical line through the anchor. */\nexport class CrossLine extends Drawing<CrossLineProps> {\n readonly type = 'cross_line'\n\n private readonly _axisViews = [\n new AxisLabel({\n coordinate: () => {\n const anchor = this.anchors[0]\n const viewport = this.getViewport()\n if (!anchor || !viewport) return null\n return viewport.yOf(anchor.price)\n },\n text: () => this.formatPrice(this.anchors[0]?.price ?? 0),\n color: () => this.style.lineColor,\n visible: () => this.props.showPrice && this.isVisibleNow(),\n }),\n ]\n\n private readonly _timeViews = [\n new AxisLabel({\n coordinate: () => {\n const anchor = this.anchors[0]\n const viewport = this.getViewport()\n if (!anchor || !viewport) return null\n return viewport.xOf(anchor.time)\n },\n text: () => timeText(this.anchors[0]?.time),\n color: () => this.style.lineColor,\n visible: () => this.props.showTime && this.isVisibleNow(),\n }),\n ]\n\n protected override defaultProps(): CrossLineProps {\n return { showPrice: true, showTime: true }\n }\n\n protected override axisViews(): readonly ISeriesPrimitiveAxisView[] {\n return this._axisViews\n }\n\n protected override timeViews(): readonly ISeriesPrimitiveAxisView[] {\n return this._timeViews\n }\n\n requiredAnchors(): number {\n return 1\n }\n\n paint(ctx: CanvasRenderingContext2D, viewport: Viewport): void {\n const anchor = this.anchors[0]\n if (!anchor) return\n const p = this.anchorToPixel(anchor, viewport)\n if (!p) return\n applyStroke(ctx, this.style)\n strokeSegment(ctx, { x: 0, y: p.y }, { x: viewport.width, y: p.y })\n strokeSegment(ctx, { x: p.x, y: 0 }, { x: p.x, y: viewport.height })\n }\n\n testHit(point: Point, viewport: Viewport): boolean {\n const anchor = this.anchors[0]\n if (!anchor) return false\n const p = this.anchorToPixel(anchor, viewport)\n if (!p) return false\n const tolerance = hitTolerance(this.style.lineWidth)\n return Math.abs(point.y - p.y) <= tolerance || Math.abs(point.x - p.x) <= tolerance\n }\n}\n","import type { ControlPoint, Point, Viewport } from '../core/types'\nimport { Drawing, type AnyDrawing } from '../core/drawing'\nimport { distanceToSegment } from '../core/geometry'\nimport { applyStroke, fillPaint, paintLabel } from '../render/canvas'\n\nfunction hitTolerance(lineWidth: number): number {\n return Math.max(6, lineWidth / 2 + 4)\n}\n\nfunction pointInPolygon(p: Point, polygon: readonly Point[]): boolean {\n let inside = false\n for (let i = 0, j = polygon.length - 1; i < polygon.length; j = i++) {\n const a = polygon[i]\n const b = polygon[j]\n if (a.y > p.y !== b.y > p.y && p.x < ((b.x - a.x) * (p.y - a.y)) / (b.y - a.y) + a.x) {\n inside = !inside\n }\n }\n return inside\n}\n\nfunction nearPolygonEdge(p: Point, polygon: readonly Point[], tolerance: number, close: boolean): boolean {\n const last = close ? polygon.length : polygon.length - 1\n for (let i = 0; i < last; i++) {\n if (distanceToSegment(p, polygon[i], polygon[(i + 1) % polygon.length]) <= tolerance) return true\n }\n return false\n}\n\n/** Stroke + optional fill for a closed polygon in one pass. */\nfunction paintPolygon(\n ctx: CanvasRenderingContext2D,\n polygon: readonly Point[],\n drawing: AnyDrawing,\n): void {\n if (polygon.length < 2) return\n applyStroke(ctx, drawing.style)\n ctx.beginPath()\n ctx.moveTo(polygon[0].x, polygon[0].y)\n for (let i = 1; i < polygon.length; i++) ctx.lineTo(polygon[i].x, polygon[i].y)\n ctx.closePath()\n const fill = fillPaint(drawing.style)\n if (fill) {\n ctx.fillStyle = fill\n ctx.fill()\n }\n ctx.stroke()\n}\n\nexport type RectangleProps = {\n /** Free label rendered centered inside the rectangle. */\n text: string\n /** Dashed horizontal midline across the box. */\n middleLine: boolean\n extendLeft: boolean\n extendRight: boolean\n}\n\n/** Axis-aligned rectangle spanned by two corner anchors. */\nexport class Rectangle extends Drawing<RectangleProps> {\n readonly type = 'rectangle'\n\n protected override defaultProps(): RectangleProps {\n return { text: '', middleLine: false, extendLeft: false, extendRight: false }\n }\n\n requiredAnchors(): number {\n return 2\n }\n\n /** The hint sits level at the box center — exactly where the text itself renders. */\n protected override textHintPlacement(points: Point[]): { x: number; y: number; angle: number } {\n return {\n x: points.reduce((sum, p) => sum + p.x, 0) / points.length,\n y: points.reduce((sum, p) => sum + p.y, 0) / points.length,\n angle: 0,\n }\n }\n\n protected corners(viewport: Viewport): Point[] | null {\n const [a, b] = this.anchorPixels(viewport)\n if (!a || !b) return null\n // Extension stretches the box horizontally to the pane edge(s).\n const left = this.props.extendLeft ? 0 : Math.min(a.x, b.x)\n const right = this.props.extendRight ? viewport.width : Math.max(a.x, b.x)\n return [\n { x: left, y: a.y },\n { x: right, y: a.y },\n { x: right, y: b.y },\n { x: left, y: b.y },\n ]\n }\n\n paint(ctx: CanvasRenderingContext2D, viewport: Viewport): void {\n const corners = this.corners(viewport)\n if (!corners) return\n paintPolygon(ctx, corners, this)\n if (this.props.middleLine) {\n const midY = (corners[0].y + corners[2].y) / 2\n ctx.save()\n applyStroke(ctx, this.style)\n ctx.setLineDash([4, 4])\n ctx.beginPath()\n ctx.moveTo(corners[0].x, midY)\n ctx.lineTo(corners[1].x, midY)\n ctx.stroke()\n ctx.restore()\n }\n if (this.props.text) {\n paintLabel(\n ctx,\n this.props.text,\n { x: (corners[0].x + corners[2].x) / 2, y: (corners[0].y + corners[2].y) / 2 },\n this.style,\n { align: 'center' },\n )\n }\n }\n\n testHit(point: Point, viewport: Viewport): boolean {\n const corners = this.corners(viewport)\n if (!corners) return false\n const tolerance = hitTolerance(this.style.lineWidth)\n if (nearPolygonEdge(point, corners, tolerance, true)) return true\n return this.style.fillOpacity > 0 && pointInPolygon(point, corners)\n }\n}\n\n/**\n * Rectangle at an arbitrary angle: anchors 1–2 span one edge, anchor 3 sets the extrusion —\n * the rectangle extends perpendicular from the base edge through the third point.\n */\nexport class RotatedRectangle extends Drawing {\n readonly type = 'rotated_rectangle'\n\n requiredAnchors(): number {\n return 3\n }\n\n protected corners(viewport: Viewport): Point[] | null {\n const [a, b, c] = this.anchorPixels(viewport)\n if (!a || !b || !c) return null\n const dx = b.x - a.x\n const dy = b.y - a.y\n const lengthSq = dx * dx + dy * dy\n if (lengthSq === 0) return null\n // Perpendicular offset of c from the a→b edge, projected onto the unit normal.\n const t = ((c.x - a.x) * -dy + (c.y - a.y) * dx) / lengthSq\n const nx = -dy * t\n const ny = dx * t\n return [a, b, { x: b.x + nx, y: b.y + ny }, { x: a.x + nx, y: a.y + ny }]\n }\n\n paint(ctx: CanvasRenderingContext2D, viewport: Viewport): void {\n const corners = this.corners(viewport)\n if (corners) paintPolygon(ctx, corners, this)\n }\n\n testHit(point: Point, viewport: Viewport): boolean {\n const corners = this.corners(viewport)\n if (!corners) return false\n const tolerance = hitTolerance(this.style.lineWidth)\n if (nearPolygonEdge(point, corners, tolerance, true)) return true\n return this.style.fillOpacity > 0 && pointInPolygon(point, corners)\n }\n}\n\n/** Three-corner polygon. */\nexport class Triangle extends Drawing {\n readonly type = 'triangle'\n\n requiredAnchors(): number {\n return 3\n }\n\n paint(ctx: CanvasRenderingContext2D, viewport: Viewport): void {\n const points = this.anchorPixels(viewport).filter((p): p is Point => !!p)\n if (points.length === 3) paintPolygon(ctx, points, this)\n }\n\n testHit(point: Point, viewport: Viewport): boolean {\n const points = this.anchorPixels(viewport).filter((p): p is Point => !!p)\n if (points.length < 3) return false\n const tolerance = hitTolerance(this.style.lineWidth)\n if (nearPolygonEdge(point, points, tolerance, true)) return true\n return this.style.fillOpacity > 0 && pointInPolygon(point, points)\n }\n}\n\n/** The free label a round shape carries, centered in it. */\nexport type RoundShapeProps = {\n text: string\n}\n\n/** Circle from a center anchor and a radius anchor. */\nexport class Circle extends Drawing<RoundShapeProps> {\n readonly type = 'circle'\n\n protected override defaultProps(): RoundShapeProps {\n return { text: '' }\n }\n\n requiredAnchors(): number {\n return 2\n }\n\n /** The hint sits at the center anchor, which is where the text itself renders. */\n protected override textHintPlacement(points: Point[]): { x: number; y: number; angle: number } {\n const center = points[0]\n return center ? { x: center.x, y: center.y, angle: 0 } : super.textHintPlacement(points)\n }\n\n protected geometry(viewport: Viewport): { center: Point; radius: number } | null {\n const [center, rim] = this.anchorPixels(viewport)\n if (!center || !rim) return null\n return { center, radius: Math.hypot(rim.x - center.x, rim.y - center.y) }\n }\n\n paint(ctx: CanvasRenderingContext2D, viewport: Viewport): void {\n const geo = this.geometry(viewport)\n if (!geo) return\n applyStroke(ctx, this.style)\n ctx.beginPath()\n ctx.arc(geo.center.x, geo.center.y, geo.radius, 0, Math.PI * 2)\n const fill = fillPaint(this.style)\n if (fill) {\n ctx.fillStyle = fill\n ctx.fill()\n }\n ctx.stroke()\n if (this.props.text) paintLabel(ctx, this.props.text, geo.center, this.style, { align: 'center' })\n }\n\n testHit(point: Point, viewport: Viewport): boolean {\n const geo = this.geometry(viewport)\n if (!geo) return false\n const distance = Math.hypot(point.x - geo.center.x, point.y - geo.center.y)\n if (Math.abs(distance - geo.radius) <= hitTolerance(this.style.lineWidth)) return true\n return this.style.fillOpacity > 0 && distance < geo.radius\n }\n}\n\n/**\n * Axis-aligned ellipse: anchors 1–2 span the horizontal diameter, anchor 3 drags the vertical\n * radius from the diameter's midline.\n */\nexport class Ellipse extends Drawing<RoundShapeProps> {\n readonly type = 'ellipse'\n\n protected override defaultProps(): RoundShapeProps {\n return { text: '' }\n }\n\n requiredAnchors(): number {\n return 3\n }\n\n /** The hint sits on the diameter's midpoint, which is where the text itself renders. */\n protected override textHintPlacement(points: Point[]): { x: number; y: number; angle: number } {\n const [a, b] = points\n return a && b ? { x: (a.x + b.x) / 2, y: (a.y + b.y) / 2, angle: 0 } : super.textHintPlacement(points)\n }\n\n protected geometry(viewport: Viewport): { center: Point; rx: number; ry: number } | null {\n const [a, b, c] = this.anchorPixels(viewport)\n if (!a || !b || !c) return null\n const center = { x: (a.x + b.x) / 2, y: (a.y + b.y) / 2 }\n const rx = Math.abs(b.x - a.x) / 2\n const ry = Math.abs(c.y - center.y)\n if (rx === 0 || ry === 0) return null\n return { center, rx, ry }\n }\n\n paint(ctx: CanvasRenderingContext2D, viewport: Viewport): void {\n const geo = this.geometry(viewport)\n if (!geo) return\n applyStroke(ctx, this.style)\n ctx.beginPath()\n ctx.ellipse(geo.center.x, geo.center.y, geo.rx, geo.ry, 0, 0, Math.PI * 2)\n const fill = fillPaint(this.style)\n if (fill) {\n ctx.fillStyle = fill\n ctx.fill()\n }\n ctx.stroke()\n if (this.props.text) paintLabel(ctx, this.props.text, geo.center, this.style, { align: 'center' })\n }\n\n /** The third handle stands on the ellipse at its centre's time, where the vertical radius it\n * drags meets the outline: the anchor's own time paints nothing, so a handle at it would stay\n * behind as the diameter moves. */\n override getControlPoints(viewport: Viewport): ControlPoint[] {\n const points = super.getControlPoints(viewport)\n const geo = this.geometry(viewport)\n return geo ? points.map((point) => (point.index === 2 ? { ...point, x: geo.center.x } : point)) : points\n }\n\n testHit(point: Point, viewport: Viewport): boolean {\n const geo = this.geometry(viewport)\n if (!geo) return false\n // Normalized radial distance: 1 = on the ellipse. Tolerance scales by the smaller radius.\n const nx = (point.x - geo.center.x) / geo.rx\n const ny = (point.y - geo.center.y) / geo.ry\n const radial = Math.sqrt(nx * nx + ny * ny)\n const tolerance = hitTolerance(this.style.lineWidth) / Math.min(geo.rx, geo.ry)\n if (Math.abs(radial - 1) <= tolerance) return true\n return this.style.fillOpacity > 0 && radial < 1\n }\n}\n\n/** Sampled quadratic/cubic Bézier shared by the curved tools. */\nfunction sampleBezier(controls: readonly Point[], samples = 32): Point[] {\n const out: Point[] = []\n for (let i = 0; i <= samples; i++) {\n const t = i / samples\n if (controls.length === 3) {\n const [p0, p1, p2] = controls\n const u = 1 - t\n out.push({\n x: u * u * p0.x + 2 * u * t * p1.x + t * t * p2.x,\n y: u * u * p0.y + 2 * u * t * p1.y + t * t * p2.y,\n })\n } else {\n const [p0, p1, p2, p3] = controls\n const u = 1 - t\n out.push({\n x: u ** 3 * p0.x + 3 * u * u * t * p1.x + 3 * u * t * t * p2.x + t ** 3 * p3.x,\n y: u ** 3 * p0.y + 3 * u * u * t * p1.y + 3 * u * t * t * p2.y + t ** 3 * p3.y,\n })\n }\n }\n return out\n}\n\nfunction paintSampled(ctx: CanvasRenderingContext2D, drawing: AnyDrawing, samples: Point[]): void {\n if (samples.length < 2) return\n // The background channel fills the area the curve closes over (chord back to the start).\n const fill = fillPaint(drawing.style)\n if (fill) {\n ctx.save()\n ctx.fillStyle = fill\n ctx.beginPath()\n ctx.moveTo(samples[0].x, samples[0].y)\n for (let i = 1; i < samples.length; i++) ctx.lineTo(samples[i].x, samples[i].y)\n ctx.closePath()\n ctx.fill()\n ctx.restore()\n }\n applyStroke(ctx, drawing.style)\n ctx.beginPath()\n ctx.moveTo(samples[0].x, samples[0].y)\n for (let i = 1; i < samples.length; i++) ctx.lineTo(samples[i].x, samples[i].y)\n ctx.stroke()\n}\n\nfunction hitSampled(point: Point, samples: Point[], tolerance: number): boolean {\n for (let i = 0; i < samples.length - 1; i++) {\n if (distanceToSegment(point, samples[i], samples[i + 1]) <= tolerance) return true\n }\n return false\n}\n\n/**\n * Bend line: anchors 1–2 are the ends, anchor 3 is the bend — the curve passes THROUGH it\n * (the Bézier control is derived so the midpoint lands on the bend anchor).\n */\nexport class Curve extends Drawing {\n readonly type = 'curve'\n\n requiredAnchors(): number {\n return 3\n }\n\n protected samples(viewport: Viewport): Point[] | null {\n const [a, b, bend] = this.anchorPixels(viewport)\n if (!a || !b || !bend) return null\n const control = { x: 2 * bend.x - (a.x + b.x) / 2, y: 2 * bend.y - (a.y + b.y) / 2 }\n return sampleBezier([a, control, b])\n }\n\n paint(ctx: CanvasRenderingContext2D, viewport: Viewport): void {\n const samples = this.samples(viewport)\n if (samples) paintSampled(ctx, this, samples)\n }\n\n testHit(point: Point, viewport: Viewport): boolean {\n const samples = this.samples(viewport)\n return !!samples && hitSampled(point, samples, hitTolerance(this.style.lineWidth))\n }\n}\n\n/** S-curve: ends at anchors 1–2, shaped through the two bend anchors 3–4. */\nexport class DoubleCurve extends Drawing {\n readonly type = 'double_curve'\n\n requiredAnchors(): number {\n return 4\n }\n\n protected samples(viewport: Viewport): Point[] | null {\n const [a, b, bend1, bend2] = this.anchorPixels(viewport)\n if (!a || !b || !bend1 || !bend2) return null\n // Cubic through both bends at t=1/3 and t=2/3 (standard interpolation → control points).\n const c1 = {\n x: (-5 * a.x + 18 * bend1.x - 9 * bend2.x + 2 * b.x) / 6,\n y: (-5 * a.y + 18 * bend1.y - 9 * bend2.y + 2 * b.y) / 6,\n }\n const c2 = {\n x: (2 * a.x - 9 * bend1.x + 18 * bend2.x - 5 * b.x) / 6,\n y: (2 * a.y - 9 * bend1.y + 18 * bend2.y - 5 * b.y) / 6,\n }\n return sampleBezier([a, c1, c2, b], 48)\n }\n\n paint(ctx: CanvasRenderingContext2D, viewport: Viewport): void {\n const samples = this.samples(viewport)\n if (samples) paintSampled(ctx, this, samples)\n }\n\n testHit(point: Point, viewport: Viewport): boolean {\n const samples = this.samples(viewport)\n return !!samples && hitSampled(point, samples, hitTolerance(this.style.lineWidth))\n }\n}\n\n/** Circular arc through a chord (anchors 1–2) bent to pass through anchor 3. */\nexport class Arc extends Drawing {\n readonly type = 'arc'\n\n requiredAnchors(): number {\n return 3\n }\n\n protected samples(viewport: Viewport): Point[] | null {\n const [a, b, bend] = this.anchorPixels(viewport)\n if (!a || !b || !bend) return null\n const control = { x: 2 * bend.x - (a.x + b.x) / 2, y: 2 * bend.y - (a.y + b.y) / 2 }\n return sampleBezier([a, control, b])\n }\n\n paint(ctx: CanvasRenderingContext2D, viewport: Viewport): void {\n const samples = this.samples(viewport)\n if (samples) paintSampled(ctx, this, samples)\n }\n\n testHit(point: Point, viewport: Viewport): boolean {\n const samples = this.samples(viewport)\n return !!samples && hitSampled(point, samples, hitTolerance(this.style.lineWidth))\n }\n}\n","import type { Point, Viewport } from '../core/types'\nimport { Drawing } from '../core/drawing'\nimport { distanceToSegment } from '../core/geometry'\nimport {\n applyStroke,\n fillPaint,\n measureTextBlock,\n paintTextBlock,\n withAlpha,\n} from '../render/canvas'\n\nexport type TextProps = {\n text: string\n}\n\n/** Free text blocks additionally carry their alignment. */\nexport type TextBlockProps = TextProps & {\n align: 'left' | 'center'\n}\n\nfunction inBox(p: Point, box: { x: number; y: number; width: number; height: number }, pad = 2): boolean {\n return (\n p.x >= box.x - pad && p.x <= box.x + box.width + pad && p.y >= box.y - pad && p.y <= box.y + box.height + pad\n )\n}\n\n/** Free-floating text pinned to a chart point. */\nexport class TextLabel extends Drawing<TextBlockProps> {\n readonly type: string = 'text'\n\n protected override defaultProps(): TextBlockProps {\n return { text: '', align: 'left' }\n }\n\n requiredAnchors(): number {\n return 1\n }\n\n /** The box the text occupies; anchor is its top-left. */\n protected box(viewport: Viewport): { x: number; y: number; width: number; height: number } | null {\n const anchor = this.anchors[0]\n if (!anchor) return null\n const p = this.anchorToPixel(anchor, viewport)\n if (!p) return null\n const { width, height } = measureTextBlock(this.props.text || ' ', this.style)\n return { x: p.x, y: p.y, width: width + 12, height: height + 12 }\n }\n\n paint(ctx: CanvasRenderingContext2D, viewport: Viewport): void {\n const anchor = this.anchors[0]\n if (!anchor) return\n const p = this.anchorToPixel(anchor, viewport)\n if (!p) return\n paintTextBlock(ctx, this.props.text || ' ', p, this.style, {\n background: fillPaint(this.style) ?? undefined,\n align: this.props.align,\n })\n }\n\n testHit(point: Point, viewport: Viewport): boolean {\n const box = this.box(viewport)\n return !!box && inBox(point, box)\n }\n}\n\n/** Text in a filled note card with a border. */\nexport class Note extends TextLabel {\n override readonly type: string = 'note'\n\n override paint(ctx: CanvasRenderingContext2D, viewport: Viewport): void {\n const anchor = this.anchors[0]\n if (!anchor) return\n const p = this.anchorToPixel(anchor, viewport)\n if (!p) return\n paintTextBlock(ctx, this.props.text || ' ', p, this.style, {\n background: fillPaint(this.style) ?? undefined,\n borderColor: this.style.lineColor,\n align: this.props.align,\n })\n }\n}\n\n/** Note variant with a speech-bubble tail pointing at the anchor. */\nexport class Comment extends TextLabel {\n override readonly type = 'comment'\n\n override paint(ctx: CanvasRenderingContext2D, viewport: Viewport): void {\n const anchor = this.anchors[0]\n if (!anchor) return\n const p = this.anchorToPixel(anchor, viewport)\n if (!p) return\n // Bubble sits above-right of the anchor; the tail drops back to the anchor point.\n const top = { x: p.x + 10, y: p.y - 14 - measureTextBlock(this.props.text || ' ', this.style).height - 12 }\n const bubble = fillPaint(this.style) ?? 'transparent'\n const box = paintTextBlock(ctx, this.props.text || ' ', top, this.style, {\n background: bubble,\n borderColor: this.style.lineColor,\n })\n ctx.save()\n ctx.fillStyle = bubble\n ctx.strokeStyle = this.style.lineColor\n ctx.lineWidth = 1\n ctx.setLineDash([])\n ctx.beginPath()\n ctx.moveTo(box.x + 8, box.y + box.height)\n ctx.lineTo(p.x, p.y)\n ctx.lineTo(box.x + 24, box.y + box.height)\n ctx.closePath()\n ctx.fill()\n ctx.stroke()\n ctx.restore()\n }\n\n override testHit(point: Point, viewport: Viewport): boolean {\n const anchor = this.anchors[0]\n if (!anchor) return false\n const p = this.anchorToPixel(anchor, viewport)\n if (!p) return false\n const { height } = measureTextBlock(this.props.text || ' ', this.style)\n const top = { x: p.x + 10, y: p.y - 14 - height - 12 }\n const { width } = measureTextBlock(this.props.text || ' ', this.style)\n return inBox(point, { x: top.x, y: top.y, width: width + 12, height: height + 12 })\n }\n}\n\n/**\n * Text box tethered to a target point: anchor 1 is what the callout points at, anchor 2 is\n * where the box sits — both stay draggable.\n */\nexport class Callout extends Drawing<TextProps> {\n readonly type: string = 'callout'\n\n protected override defaultProps(): TextProps {\n return { text: '' }\n }\n\n requiredAnchors(): number {\n return 2\n }\n\n /** What the box displays; variants prepend computed lines (e.g. the target price). */\n protected bodyText(): string {\n return this.props.text\n }\n\n protected boxAt(viewport: Viewport): { x: number; y: number; width: number; height: number } | null {\n const boxAnchor = this.anchors[1]\n if (!boxAnchor) return null\n const p = this.anchorToPixel(boxAnchor, viewport)\n if (!p) return null\n const { width, height } = measureTextBlock(this.bodyText() || ' ', this.style)\n return { x: p.x, y: p.y, width: width + 12, height: height + 12 }\n }\n\n paint(ctx: CanvasRenderingContext2D, viewport: Viewport): void {\n const target = this.anchors[0] && this.anchorToPixel(this.anchors[0], viewport)\n const box = this.boxAt(viewport)\n if (!target || !box) return\n // Tether from the box edge nearest the target.\n const edge = {\n x: Math.max(box.x, Math.min(target.x, box.x + box.width)),\n y: Math.max(box.y, Math.min(target.y, box.y + box.height)),\n }\n applyStroke(ctx, this.style)\n ctx.beginPath()\n ctx.moveTo(target.x, target.y)\n ctx.lineTo(edge.x, edge.y)\n ctx.stroke()\n paintTextBlock(ctx, this.bodyText() || ' ', { x: box.x, y: box.y }, this.style, {\n background: fillPaint(this.style) ?? undefined,\n borderColor: this.style.lineColor,\n })\n }\n\n testHit(point: Point, viewport: Viewport): boolean {\n const box = this.boxAt(viewport)\n if (box && inBox(point, box)) return true\n const target = this.anchors[0] && this.anchorToPixel(this.anchors[0], viewport)\n if (!target || !box) return false\n const edge = {\n x: Math.max(box.x, Math.min(target.x, box.x + box.width)),\n y: Math.max(box.y, Math.min(target.y, box.y + box.height)),\n }\n return distanceToSegment(point, target, edge) <= 6\n }\n}\n\n/** Pill showing the anchor's price, with a pointer tail at the exact level. */\nexport class PriceLabel extends Drawing {\n readonly type = 'price_label'\n\n requiredAnchors(): number {\n return 1\n }\n\n protected box(viewport: Viewport): { x: number; y: number; width: number; height: number } | null {\n const anchor = this.anchors[0]\n if (!anchor) return null\n const p = this.anchorToPixel(anchor, viewport)\n if (!p) return null\n const { width, height } = measureTextBlock(this.formatPrice(anchor.price), this.style)\n return { x: p.x + 12, y: p.y - (height + 12) / 2, width: width + 12, height: height + 12 }\n }\n\n paint(ctx: CanvasRenderingContext2D, viewport: Viewport): void {\n const anchor = this.anchors[0]\n if (!anchor) return\n const p = this.anchorToPixel(anchor, viewport)\n const box = this.box(viewport)\n if (!p || !box) return\n ctx.save()\n ctx.fillStyle = withAlpha(this.style.lineColor, 0.18)\n ctx.strokeStyle = this.style.lineColor\n ctx.lineWidth = 1\n ctx.setLineDash([])\n ctx.beginPath()\n // Pointer tail to the exact price point, then the pill.\n ctx.moveTo(p.x, p.y)\n ctx.lineTo(box.x, box.y + box.height / 2 - 5)\n ctx.lineTo(box.x, box.y + box.height / 2 + 5)\n ctx.closePath()\n ctx.fill()\n ctx.stroke()\n ctx.beginPath()\n ctx.roundRect(box.x, box.y, box.width, box.height, 4)\n ctx.fill()\n ctx.stroke()\n ctx.restore()\n paintTextBlock(ctx, this.formatPrice(anchor.price), { x: box.x, y: box.y }, this.style)\n }\n\n testHit(point: Point, viewport: Viewport): boolean {\n const box = this.box(viewport)\n return !!box && inBox(point, box)\n }\n}\n\ntype MarkDirection = 'up' | 'down'\n\nabstract class ArrowMark extends Drawing<TextProps> {\n protected abstract direction(): MarkDirection\n\n protected override defaultProps(): TextProps {\n return { text: '' }\n }\n\n requiredAnchors(): number {\n return 1\n }\n\n paint(ctx: CanvasRenderingContext2D, viewport: Viewport): void {\n const anchor = this.anchors[0]\n if (!anchor) return\n const p = this.anchorToPixel(anchor, viewport)\n if (!p) return\n const size = 7 + this.style.lineWidth * 2\n const up = this.direction() === 'up'\n const sign = up ? 1 : -1\n ctx.save()\n ctx.fillStyle = this.style.lineColor\n ctx.setLineDash([])\n ctx.beginPath()\n // Chevron arrow: tip at the anchor, body extending away from the price it marks.\n ctx.moveTo(p.x, p.y)\n ctx.lineTo(p.x - size, p.y + sign * size)\n ctx.lineTo(p.x - size / 2, p.y + sign * size)\n ctx.lineTo(p.x - size / 2, p.y + sign * size * 2)\n ctx.lineTo(p.x + size / 2, p.y + sign * size * 2)\n ctx.lineTo(p.x + size / 2, p.y + sign * size)\n ctx.lineTo(p.x + size, p.y + sign * size)\n ctx.closePath()\n ctx.fill()\n ctx.restore()\n if (this.props.text) {\n const { width } = measureTextBlock(this.props.text, this.style)\n paintTextBlock(\n ctx,\n this.props.text,\n { x: p.x - (width + 12) / 2, y: up ? p.y + size * 2 + 4 : p.y - size * 2 - 4 - measureTextBlock(this.props.text, this.style).height - 12 },\n this.style,\n )\n }\n }\n\n testHit(point: Point, viewport: Viewport): boolean {\n const anchor = this.anchors[0]\n if (!anchor) return false\n const p = this.anchorToPixel(anchor, viewport)\n if (!p) return false\n const size = 7 + this.style.lineWidth * 2\n const up = this.direction() === 'up'\n const box = up\n ? { x: p.x - size, y: p.y, width: size * 2, height: size * 2 }\n : { x: p.x - size, y: p.y - size * 2, width: size * 2, height: size * 2 }\n return inBox(point, box, 4)\n }\n}\n\n/** Upward arrow mark (tip at the anchor price). */\nexport class ArrowMarkUp extends ArrowMark {\n readonly type = 'arrow_up'\n\n protected direction(): MarkDirection {\n return 'up'\n }\n}\n\n/** Downward arrow mark (tip at the anchor price). */\nexport class ArrowMarkDown extends ArrowMark {\n readonly type = 'arrow_down'\n\n protected direction(): MarkDirection {\n return 'down'\n }\n}\n\n/** Callout variant whose body leads with the target's exact price. */\nexport class PriceNote extends Callout {\n override readonly type = 'price_note'\n\n protected override bodyText(): string {\n const target = this.anchors[0]\n const price = target ? this.formatPrice(target.price) : ''\n return this.props.text ? `${price}\\n${this.props.text}` : price\n }\n}\n\n/** Map pin at a chart point, with its note text beneath when present. */\nexport class Pin extends Drawing<TextProps> {\n readonly type = 'pin'\n\n protected override defaultProps(): TextProps {\n return { text: '' }\n }\n\n requiredAnchors(): number {\n return 1\n }\n\n paint(ctx: CanvasRenderingContext2D, viewport: Viewport): void {\n const anchor = this.anchors[0]\n if (!anchor) return\n const p = this.anchorToPixel(anchor, viewport)\n if (!p) return\n const r = 7\n ctx.save()\n ctx.setLineDash([])\n ctx.fillStyle = this.style.lineColor\n // Teardrop: circle head + tapered stem down to the anchor point.\n ctx.beginPath()\n ctx.arc(p.x, p.y - r * 2, r, Math.PI * 0.85, Math.PI * 0.15)\n ctx.lineTo(p.x, p.y)\n ctx.closePath()\n ctx.fill()\n ctx.fillStyle = '#ffffff'\n ctx.beginPath()\n ctx.arc(p.x, p.y - r * 2, r / 2.6, 0, Math.PI * 2)\n ctx.fill()\n ctx.restore()\n if (this.props.text) {\n const { width } = measureTextBlock(this.props.text, this.style)\n paintTextBlock(ctx, this.props.text, { x: p.x - (width + 12) / 2, y: p.y + 6 }, this.style, {\n background: withAlpha('#1b1f27', 0.95),\n })\n }\n }\n\n testHit(point: Point, viewport: Viewport): boolean {\n const anchor = this.anchors[0]\n if (!anchor) return false\n const p = this.anchorToPixel(anchor, viewport)\n if (!p) return false\n return inBox(point, { x: p.x - 9, y: p.y - 24, width: 18, height: 26 }, 3)\n }\n}\n\n/** Signpost: a label on a stem planted at the anchor. */\nexport class Signpost extends Drawing<TextProps> {\n readonly type = 'signpost'\n\n protected override defaultProps(): TextProps {\n return { text: '' }\n }\n\n requiredAnchors(): number {\n return 1\n }\n\n protected box(viewport: Viewport): { x: number; y: number; width: number; height: number } | null {\n const anchor = this.anchors[0]\n if (!anchor) return null\n const p = this.anchorToPixel(anchor, viewport)\n if (!p) return null\n const { width, height } = measureTextBlock(this.props.text || ' ', this.style)\n return { x: p.x - (width + 12) / 2, y: p.y - 34 - height, width: width + 12, height: height + 12 }\n }\n\n paint(ctx: CanvasRenderingContext2D, viewport: Viewport): void {\n const anchor = this.anchors[0]\n if (!anchor) return\n const p = this.anchorToPixel(anchor, viewport)\n const box = this.box(viewport)\n if (!p || !box) return\n ctx.save()\n ctx.setLineDash([])\n ctx.strokeStyle = this.style.lineColor\n ctx.lineWidth = 1.5\n ctx.beginPath()\n ctx.moveTo(p.x, p.y)\n ctx.lineTo(p.x, box.y + box.height)\n ctx.stroke()\n ctx.fillStyle = this.style.lineColor\n ctx.beginPath()\n ctx.arc(p.x, p.y, 3, 0, Math.PI * 2)\n ctx.fill()\n ctx.restore()\n paintTextBlock(ctx, this.props.text || ' ', { x: box.x, y: box.y }, this.style, {\n background: withAlpha('#1b1f27', 0.95),\n borderColor: this.style.lineColor,\n })\n }\n\n testHit(point: Point, viewport: Viewport): boolean {\n const box = this.box(viewport)\n return !!box && inBox(point, box)\n }\n}\n\n/**\n * Fat arrow between two anchors: the tip sits at the first, the tail sizes and aims it — drag\n * the tail to grow the arrow or flip it to point the other way. Text sits at the butt end,\n * clear of the arrow body.\n */\nexport class ArrowMarker extends Drawing<TextProps> {\n readonly type = 'arrow_marker'\n\n protected override defaultProps(): TextProps {\n return { text: '' }\n }\n\n requiredAnchors(): number {\n return 2\n }\n\n private geometry(viewport: Viewport): { tip: Point; tail: Point; len: number; w: number; angle: number } | null {\n const [tip, tail] = this.anchorPixels(viewport)\n if (!tip || !tail) return null\n const len = Math.max(18, Math.hypot(tail.x - tip.x, tail.y - tip.y))\n const w = Math.max(8, Math.min(46, len * 0.34))\n return { tip, tail, len, w, angle: Math.atan2(tail.y - tip.y, tail.x - tip.x) }\n }\n\n paint(ctx: CanvasRenderingContext2D, viewport: Viewport): void {\n const g = this.geometry(viewport)\n if (!g) return\n ctx.save()\n ctx.setLineDash([])\n ctx.translate(g.tip.x, g.tip.y)\n ctx.rotate(g.angle)\n ctx.fillStyle = this.style.lineColor\n ctx.beginPath()\n // Tip at the origin; head then shaft running toward the tail along +x.\n ctx.moveTo(0, 0)\n ctx.lineTo(g.w, -g.w)\n ctx.lineTo(g.w, -g.w / 2)\n ctx.lineTo(g.len, -g.w / 2)\n ctx.lineTo(g.len, g.w / 2)\n ctx.lineTo(g.w, g.w / 2)\n ctx.lineTo(g.w, g.w)\n ctx.closePath()\n ctx.fill()\n ctx.restore()\n if (this.props.text) {\n const { width, height } = measureTextBlock(this.props.text, this.style)\n const boxW = width + 12\n const boxH = height + 12\n const above = g.tail.y <= g.tip.y\n const y = above ? g.tail.y - boxH - 8 : g.tail.y + 8\n paintTextBlock(ctx, this.props.text, { x: g.tail.x - boxW / 2, y }, this.style)\n }\n }\n\n /** The hint sits at the butt end where the text will render — never over the arrow body. */\n protected override textHintPlacement(points: Point[]): { x: number; y: number; angle: number } {\n const tip = points[0]\n const tail = points[1] ?? tip\n const above = tail.y <= tip.y\n return { x: tail.x, y: above ? tail.y - 18 : tail.y + 18, angle: 0 }\n }\n\n testHit(point: Point, viewport: Viewport): boolean {\n const g = this.geometry(viewport)\n if (!g) return false\n const dx = point.x - g.tip.x\n const dy = point.y - g.tip.y\n const cos = Math.cos(-g.angle)\n const sin = Math.sin(-g.angle)\n const rx = dx * cos - dy * sin\n const ry = dx * sin + dy * cos\n return rx >= -4 && rx <= g.len + 4 && Math.abs(ry) <= g.w + 4\n }\n}\n\n/** Flag pin at a chart point. */\nexport class FlagMark extends Drawing {\n readonly type = 'flag'\n\n requiredAnchors(): number {\n return 1\n }\n\n paint(ctx: CanvasRenderingContext2D, viewport: Viewport): void {\n const anchor = this.anchors[0]\n if (!anchor) return\n const p = this.anchorToPixel(anchor, viewport)\n if (!p) return\n const height = 22\n ctx.save()\n ctx.setLineDash([])\n ctx.strokeStyle = this.style.lineColor\n ctx.lineWidth = 2\n ctx.beginPath()\n ctx.moveTo(p.x, p.y)\n ctx.lineTo(p.x, p.y - height)\n ctx.stroke()\n ctx.fillStyle = this.style.lineColor\n ctx.beginPath()\n ctx.moveTo(p.x, p.y - height)\n ctx.lineTo(p.x + 16, p.y - height + 5)\n ctx.lineTo(p.x, p.y - height + 10)\n ctx.closePath()\n ctx.fill()\n ctx.restore()\n }\n\n testHit(point: Point, viewport: Viewport): boolean {\n const anchor = this.anchors[0]\n if (!anchor) return false\n const p = this.anchorToPixel(anchor, viewport)\n if (!p) return false\n return inBox(point, { x: p.x - 4, y: p.y - 24, width: 24, height: 26 })\n }\n}\n","import type { Time } from 'lightweight-charts'\n\n/** One chart bar as the data-driven tools consume it (volume present when the host has it). */\nexport interface SourceBar {\n time: Time\n open: number\n high: number\n low: number\n close: number\n volume?: number\n}\n\n/** Host-injected bar feed. Called at paint time; implementations should be cheap/memoized. */\nexport type BarSource = () => readonly SourceBar[]\n\n/** Bars whose time falls inside [from, to] (inclusive, either anchor order). */\nexport function barsInRange(bars: readonly SourceBar[], a: Time, b: Time): SourceBar[] {\n const from = Math.min(Number(a), Number(b))\n const to = Math.max(Number(a), Number(b))\n if (!Number.isFinite(from) || !Number.isFinite(to)) return []\n return bars.filter((bar) => {\n const t = Number(bar.time)\n return t >= from && t <= to\n })\n}\n\n/** Price sources a data-driven tool can compute over. */\nexport type BarPriceSource = 'close' | 'open' | 'hl2' | 'hlc3'\n\nexport function barPrice(bar: SourceBar, source: BarPriceSource): number {\n switch (source) {\n case 'open':\n return bar.open\n case 'hl2':\n return (bar.high + bar.low) / 2\n case 'hlc3':\n return (bar.high + bar.low + bar.close) / 3\n default:\n return bar.close\n }\n}\n\n/** Least-squares line over the bars' chosen price source, plus the residual σ. */\nexport function linearRegression(\n bars: readonly SourceBar[],\n source: BarPriceSource = 'close',\n): { slope: number; intercept: number; sigma: number } | null {\n const n = bars.length\n if (n < 2) return null\n let sumX = 0\n let sumY = 0\n let sumXY = 0\n let sumXX = 0\n for (let i = 0; i < n; i++) {\n const y = barPrice(bars[i], source)\n sumX += i\n sumY += y\n sumXY += i * y\n sumXX += i * i\n }\n const denominator = n * sumXX - sumX * sumX\n if (denominator === 0) return null\n const slope = (n * sumXY - sumX * sumY) / denominator\n const intercept = (sumY - slope * sumX) / n\n let variance = 0\n for (let i = 0; i < n; i++) {\n const residual = barPrice(bars[i], source) - (intercept + slope * i)\n variance += residual * residual\n }\n return { slope, intercept, sigma: Math.sqrt(variance / n) }\n}\n\nexport interface VolumeBin {\n priceLow: number\n priceHigh: number\n volume: number\n upVolume: number\n downVolume: number\n}\n\n/**\n * Volume-by-price histogram: each bar's volume spreads uniformly over the bins its high–low\n * range covers, attributed up/down by close vs open (close > open counts as up volume).\n * Null when the range has no volume data at all.\n */\nexport function volumeProfile(bars: readonly SourceBar[], rows: number): VolumeBin[] | null {\n const withVolume = bars.filter((b) => typeof b.volume === 'number' && b.volume > 0)\n if (!withVolume.length || rows < 1) return null\n let min = Infinity\n let max = -Infinity\n for (const bar of withVolume) {\n min = Math.min(min, bar.low)\n max = Math.max(max, bar.high)\n }\n if (!(max > min)) return null\n const height = (max - min) / rows\n const bins: VolumeBin[] = Array.from({ length: rows }, (_, i) => ({\n priceLow: min + i * height,\n priceHigh: min + (i + 1) * height,\n volume: 0,\n upVolume: 0,\n downVolume: 0,\n }))\n for (const bar of withVolume) {\n const lowBin = Math.max(0, Math.min(rows - 1, Math.floor((bar.low - min) / height)))\n const highBin = Math.max(0, Math.min(rows - 1, Math.floor((bar.high - min) / height)))\n const span = highBin - lowBin + 1\n const share = (bar.volume as number) / span\n const up = bar.close > bar.open\n for (let i = lowBin; i <= highBin; i++) {\n bins[i].volume += share\n if (up) bins[i].upVolume += share\n else bins[i].downVolume += share\n }\n }\n return bins\n}\n","import type { DrawingStyle, Point, Viewport } from '../core/types'\nimport { Drawing } from '../core/drawing'\nimport { barsInRange } from '../core/bars'\nimport { applyStroke, paintArrowHead, paintLabel, strokeSegment, withAlpha } from '../render/canvas'\n\n/** Compact volume readout (12.4M style). */\nfunction volumeText(volume: number): string {\n if (volume >= 1e9) return `${(volume / 1e9).toFixed(2)}B`\n if (volume >= 1e6) return `${(volume / 1e6).toFixed(2)}M`\n if (volume >= 1e3) return `${(volume / 1e3).toFixed(1)}K`\n return String(Math.round(volume))\n}\n\nfunction box(a: Point, b: Point): { x: number; y: number; width: number; height: number } {\n return {\n x: Math.min(a.x, b.x),\n y: Math.min(a.y, b.y),\n width: Math.abs(b.x - a.x),\n height: Math.abs(b.y - a.y),\n }\n}\n\nfunction inBox(p: Point, r: { x: number; y: number; width: number; height: number }, pad = 4): boolean {\n return p.x >= r.x - pad && p.x <= r.x + r.width + pad && p.y >= r.y - pad && p.y <= r.y + r.height + pad\n}\n\nexport type RangeMeterProps = {\n /** The viewer's own word for the span, inside it. */\n text: string\n /** Stats readout toggles; a meter only surfaces the ones its axes measure. */\n showPriceDelta: boolean\n showPercent: boolean\n showBars: boolean\n showTimeSpan: boolean\n showVolume: boolean\n /** Stretch the shaded span across the axis the meter doesn't measure. */\n extend: boolean\n}\n\n/** Shared skeleton for the range meters: shaded span + measuring arrow + stats pill. */\nabstract class RangeMeter extends Drawing<RangeMeterProps> {\n requiredAnchors(): number {\n return 2\n }\n\n protected pixels(viewport: Viewport): { a: Point; b: Point } | null {\n const [a, b] = this.anchorPixels(viewport)\n if (!a || !b) return null\n return { a, b }\n }\n\n /** The hint sits at the span's center, which is where the text itself renders. */\n protected override textHintPlacement(points: Point[]): { x: number; y: number; angle: number } {\n const [a, b] = points\n return a && b ? { x: (a.x + b.x) / 2, y: (a.y + b.y) / 2, angle: 0 } : super.textHintPlacement(points)\n }\n\n protected paintSpan(ctx: CanvasRenderingContext2D, a: Point, b: Point, viewport: Viewport): void {\n let r = box(a, b)\n if (this.props.extend) {\n // A price meter extends across time; a time meter extends across price.\n r = this.measuresPrice()\n ? { x: 0, y: r.y, width: viewport.width, height: r.height }\n : { x: r.x, y: 0, width: r.width, height: viewport.height }\n }\n ctx.save()\n ctx.fillStyle = withAlpha(this.style.lineColor, Math.max(0.08, this.style.fillOpacity))\n ctx.fillRect(r.x, r.y, r.width, r.height)\n ctx.restore()\n }\n\n protected stats(viewport: Viewport): string[] {\n const [a, b] = this.anchors\n if (!a || !b) return []\n const out: string[] = []\n if (this.measuresPrice()) {\n const dPrice = b.price - a.price\n const pct = a.price !== 0 ? (dPrice / Math.abs(a.price)) * 100 : 0\n const parts: string[] = []\n if (this.props.showPriceDelta) parts.push(`${dPrice >= 0 ? '+' : ''}${this.formatPrice(dPrice)}`)\n if (this.props.showPercent) parts.push(`(${pct >= 0 ? '+' : ''}${pct.toFixed(2)}%)`)\n if (parts.length) out.push(parts.join(' '))\n }\n if (this.measuresTime()) {\n if (this.props.showBars) {\n const bars = viewport.barsBetween(a.time, b.time)\n if (bars !== null) out.push(`${Math.round(bars)} bars`)\n }\n if (this.props.showTimeSpan) {\n const secs = Number(b.time) - Number(a.time)\n if (Number.isFinite(secs) && secs !== 0) out.push(spanText(Math.abs(secs)))\n }\n if (this.props.showVolume) {\n const range = barsInRange(this.bars(), a.time, b.time)\n const total = range.reduce((sum, bar) => sum + (bar.volume ?? 0), 0)\n if (total > 0) out.push(`Vol ${volumeText(total)}`)\n }\n }\n return out\n }\n\n protected abstract measuresPrice(): boolean\n protected abstract measuresTime(): boolean\n\n paint(ctx: CanvasRenderingContext2D, viewport: Viewport): void {\n const px = this.pixels(viewport)\n if (!px) return\n const { a, b } = px\n this.paintSpan(ctx, a, b, viewport)\n applyStroke(ctx, this.style)\n if (this.measuresPrice()) {\n const x = (a.x + b.x) / 2\n strokeSegment(ctx, { x, y: a.y }, { x, y: b.y })\n paintArrowHead(ctx, { x, y: a.y }, { x, y: b.y }, this.style)\n }\n if (this.measuresTime()) {\n const y = this.measuresPrice() ? Math.max(a.y, b.y) : (a.y + b.y) / 2\n strokeSegment(ctx, { x: a.x, y }, { x: b.x, y })\n paintArrowHead(ctx, { x: a.x, y }, { x: b.x, y }, this.style)\n }\n const stats = this.stats(viewport)\n if (stats.length) {\n const r = box(a, b)\n paintLabel(ctx, stats.join(' · '), { x: r.x + r.width / 2, y: r.y + r.height + 16 }, this.style, {\n align: 'center',\n background: withAlpha('#1b1f27', 0.92),\n })\n }\n if (this.props.text) {\n const r = box(a, b)\n paintLabel(ctx, this.props.text, { x: r.x + r.width / 2, y: r.y + r.height / 2 }, this.style, { align: 'center' })\n }\n }\n\n testHit(point: Point, viewport: Viewport): boolean {\n const px = this.pixels(viewport)\n if (!px) return false\n return inBox(point, box(px.a, px.b))\n }\n}\n\n/** Vertical meter: price delta and % between two levels. */\nexport class PriceRange extends RangeMeter {\n readonly type = 'price_range'\n\n protected override defaultProps(): RangeMeterProps {\n return { text: '', showPriceDelta: true, showPercent: true, showBars: false, showTimeSpan: false, showVolume: false, extend: false }\n }\n\n protected measuresPrice(): boolean {\n return true\n }\n\n protected measuresTime(): boolean {\n return false\n }\n}\n\n/** Horizontal meter: bar count and time span between two times. */\nexport class DateRange extends RangeMeter {\n readonly type = 'date_range'\n\n protected override defaultProps(): RangeMeterProps {\n return { text: '', showPriceDelta: false, showPercent: false, showBars: true, showTimeSpan: true, showVolume: true, extend: false }\n }\n\n protected measuresPrice(): boolean {\n return false\n }\n\n protected measuresTime(): boolean {\n return true\n }\n}\n\n/** Combined meter: price and time deltas of the spanned box. */\nexport class DatePriceRange extends RangeMeter {\n readonly type = 'date_and_price_range'\n\n protected override defaultProps(): RangeMeterProps {\n return { text: '', showPriceDelta: true, showPercent: true, showBars: true, showTimeSpan: true, showVolume: true, extend: false }\n }\n\n protected measuresPrice(): boolean {\n return true\n }\n\n protected measuresTime(): boolean {\n return true\n }\n}\n\nconst MEASURE_UP = '#2962ff'\nconst MEASURE_DOWN = '#f23645'\n\n/**\n * The measure action's readout: a direction-colored zone (blue measuring up, red down) with a\n * vertical arrow spanning it, a horizontal arrow at mid-height, and a solid pill above/below\n * carrying `Δprice (Δ%) Δticks` over `bars, duration`.\n */\nexport class Measure extends Drawing {\n readonly type = 'measure'\n\n requiredAnchors(): number {\n return 2\n }\n\n paint(ctx: CanvasRenderingContext2D, viewport: Viewport): void {\n const [pa, pb] = this.anchorPixels(viewport)\n const [a, b] = this.anchors\n if (!pa || !pb || !a || !b) return\n const up = b.price >= a.price\n const color = up ? MEASURE_UP : MEASURE_DOWN\n const r = box(pa, pb)\n if (r.width < 1 && r.height < 1) return\n const arrowStyle: DrawingStyle = { ...this.style, lineColor: color, lineWidth: 1.5 }\n\n ctx.save()\n ctx.setLineDash([])\n ctx.fillStyle = withAlpha(color, 0.18)\n ctx.fillRect(r.x, r.y, r.width, r.height)\n\n // The cross: price arrow spanning the zone toward the move's direction, time arrow at\n // mid-height toward the drag's direction.\n const cx = r.x + r.width / 2\n const cy = r.y + r.height / 2\n ctx.strokeStyle = color\n ctx.lineWidth = 1.5\n if (r.height >= 8) {\n const from = { x: cx, y: up ? r.y + r.height : r.y }\n const to = { x: cx, y: up ? r.y : r.y + r.height }\n strokeSegment(ctx, from, to)\n paintArrowHead(ctx, from, to, arrowStyle)\n }\n if (r.width >= 8) {\n const rightward = pb.x >= pa.x\n const from = { x: rightward ? r.x : r.x + r.width, y: cy }\n const to = { x: rightward ? r.x + r.width : r.x, y: cy }\n strokeSegment(ctx, from, to)\n paintArrowHead(ctx, from, to, arrowStyle)\n }\n\n // The data pill: solid direction color, white text, two centered lines.\n const dPrice = b.price - a.price\n const pct = a.price !== 0 ? (dPrice / Math.abs(a.price)) * 100 : 0\n // The tick count rides only on a host-stated tick; without one the readout omits it.\n const tick = this.tickSize()\n const ticks = tick !== null && tick > 0 ? Math.round(Math.abs(dPrice) / tick) : 0\n const parts = [`${this.formatPrice(dPrice)} (${pct.toFixed(2)}%)`]\n if (ticks > 0 && Number.isFinite(ticks)) parts[0] += ` ${ticks}`\n const bars = viewport.barsBetween(a.time, b.time)\n const secs = Math.abs(Number(b.time) - Number(a.time))\n const line2: string[] = []\n if (bars !== null) line2.push(`${Math.abs(Math.round(bars))} bars`)\n if (Number.isFinite(secs) && secs > 0) line2.push(spanText(secs))\n const lines = line2.length ? [parts[0], line2.join(', ')] : [parts[0]]\n\n ctx.font = `600 ${this.style.fontSize}px ui-sans-serif, system-ui, sans-serif`\n ctx.textAlign = 'center'\n ctx.textBaseline = 'middle'\n const lineH = Math.round(this.style.fontSize * 1.35)\n const textW = Math.max(...lines.map((l) => ctx.measureText(l).width))\n const pillW = textW + 20\n const pillH = lines.length * lineH + 10\n const pillX = Math.max(4, Math.min(cx - pillW / 2, viewport.width - pillW - 4))\n const pillY = up ? Math.max(4, r.y - pillH - 10) : Math.min(viewport.height - pillH - 4, r.y + r.height + 10)\n ctx.fillStyle = color\n ctx.beginPath()\n ctx.roundRect(pillX, pillY, pillW, pillH, 4)\n ctx.fill()\n ctx.fillStyle = '#ffffff'\n for (let i = 0; i < lines.length; i++) {\n ctx.fillText(lines[i], pillX + pillW / 2, pillY + 5 + lineH * i + lineH / 2)\n }\n ctx.restore()\n }\n\n testHit(point: Point, viewport: Viewport): boolean {\n const [pa, pb] = this.anchorPixels(viewport)\n if (!pa || !pb) return false\n return inBox(point, box(pa, pb))\n }\n}\n\n/** Human span like \"2d 4h\" / \"3h 12m\" / \"45s\" from a duration in seconds. */\nfunction spanText(seconds: number): string {\n const d = Math.floor(seconds / 86400)\n const h = Math.floor((seconds % 86400) / 3600)\n const m = Math.floor((seconds % 3600) / 60)\n const s = Math.floor(seconds % 60)\n if (d > 0) return h > 0 ? `${d}d ${h}h` : `${d}d`\n if (h > 0) return m > 0 ? `${h}h ${m}m` : `${h}h`\n if (m > 0) return s > 0 ? `${m}m ${s}s` : `${m}m`\n return `${s}s`\n}\n","import type { ControlPoint, Point, Viewport } from '../core/types'\nimport { Drawing } from '../core/drawing'\nimport { distanceToSegment, extendSegment } from '../core/geometry'\nimport { applyStroke, dashPattern, fillPaint, paintLabel, strokeSegment } from '../render/canvas'\n\nexport type ChannelProps = {\n /** Free label rendered above the baseline's start. */\n text: string\n extendLeft: boolean\n extendRight: boolean\n /** Dashed midline halfway between the channel boundaries. */\n showMiddle: boolean\n}\n\nconst CHANNEL_PROPS: ChannelProps = { text: '', extendLeft: false, extendRight: false, showMiddle: false }\n\nfunction hitTolerance(lineWidth: number): number {\n return Math.max(6, lineWidth / 2 + 4)\n}\n\n/**\n * Parallel channel: anchors 1–2 span the baseline, anchor 3 sets the vertical offset of the\n * second boundary (same slope, same time range).\n */\nexport class ParallelChannel extends Drawing<ChannelProps> {\n readonly type = 'parallel_channel'\n\n protected override defaultProps(): ChannelProps {\n return { ...CHANNEL_PROPS }\n }\n\n requiredAnchors(): number {\n return 3\n }\n\n /** Both boundaries after extension, or null while an anchor is off-range. */\n protected boundaries(viewport: Viewport): { base: { a: Point; b: Point }; offset: { a: Point; b: Point } } | null {\n const [p1, p2, p3] = this.anchorPixels(viewport)\n if (!p1 || !p2 || !p3) return null\n // The second boundary is the baseline translated vertically through p3.\n const dy = p3.y - (p1.y + (p2.y - p1.y) * ((p3.x - p1.x) / ((p2.x - p1.x) || 1)))\n const { extendLeft, extendRight } = this.props\n const base =\n extendLeft || extendRight\n ? extendSegment(p1, p2, viewport.width, viewport.height, extendLeft, extendRight)\n : { a: p1, b: p2 }\n const offset =\n extendLeft || extendRight\n ? extendSegment(\n { x: p1.x, y: p1.y + dy },\n { x: p2.x, y: p2.y + dy },\n viewport.width,\n viewport.height,\n extendLeft,\n extendRight,\n )\n : { a: { x: p1.x, y: p1.y + dy }, b: { x: p2.x, y: p2.y + dy } }\n return { base, offset }\n }\n\n paint(ctx: CanvasRenderingContext2D, viewport: Viewport): void {\n const b = this.boundaries(viewport)\n if (!b) return\n const fill = fillPaint(this.style)\n if (fill) {\n ctx.save()\n ctx.fillStyle = fill\n ctx.beginPath()\n ctx.moveTo(b.base.a.x, b.base.a.y)\n ctx.lineTo(b.base.b.x, b.base.b.y)\n ctx.lineTo(b.offset.b.x, b.offset.b.y)\n ctx.lineTo(b.offset.a.x, b.offset.a.y)\n ctx.closePath()\n ctx.fill()\n ctx.restore()\n }\n applyStroke(ctx, this.style)\n strokeSegment(ctx, b.base.a, b.base.b)\n strokeSegment(ctx, b.offset.a, b.offset.b)\n if (this.props.text) paintLabel(ctx, this.props.text, { x: b.base.a.x + 6, y: b.base.a.y - 12 }, this.style)\n if (this.props.showMiddle) {\n ctx.save()\n ctx.setLineDash(dashPattern('dashed', this.style.lineWidth))\n strokeSegment(\n ctx,\n { x: (b.base.a.x + b.offset.a.x) / 2, y: (b.base.a.y + b.offset.a.y) / 2 },\n { x: (b.base.b.x + b.offset.b.x) / 2, y: (b.base.b.y + b.offset.b.y) / 2 },\n )\n ctx.restore()\n }\n }\n\n testHit(point: Point, viewport: Viewport): boolean {\n const b = this.boundaries(viewport)\n if (!b) return false\n const tolerance = hitTolerance(this.style.lineWidth)\n if (distanceToSegment(point, b.base.a, b.base.b) <= tolerance) return true\n if (distanceToSegment(point, b.offset.a, b.offset.b) <= tolerance) return true\n // Inside the channel body counts as a hit — that is how the whole channel is grabbed.\n const minX = Math.min(b.base.a.x, b.base.b.x)\n const maxX = Math.max(b.base.a.x, b.base.b.x)\n if (point.x < minX || point.x > maxX) return false\n const t = maxX === minX ? 0 : (point.x - b.base.a.x) / (b.base.b.x - b.base.a.x || 1)\n const yBase = b.base.a.y + (b.base.b.y - b.base.a.y) * t\n const yOff = b.offset.a.y + (b.offset.b.y - b.offset.a.y) * t\n return point.y >= Math.min(yBase, yOff) && point.y <= Math.max(yBase, yOff)\n }\n}\n\n/**\n * Flat top/bottom: anchors 1–2 span a trend boundary, anchor 3 sets a horizontal boundary —\n * a channel with one sloped and one flat side.\n */\nexport class FlatTopBottom extends Drawing<ChannelProps> {\n readonly type = 'flat_top_bottom'\n\n protected override defaultProps(): ChannelProps {\n return { ...CHANNEL_PROPS }\n }\n\n requiredAnchors(): number {\n return 3\n }\n\n protected boundaries(viewport: Viewport): { slope: { a: Point; b: Point }; flat: { a: Point; b: Point } } | null {\n const [p1, p2, p3] = this.anchorPixels(viewport)\n if (!p1 || !p2 || !p3) return null\n const { extendLeft, extendRight } = this.props\n const slope =\n extendLeft || extendRight\n ? extendSegment(p1, p2, viewport.width, viewport.height, extendLeft, extendRight)\n : { a: p1, b: p2 }\n const flatA = { x: slope.a.x, y: p3.y }\n const flatB = { x: slope.b.x, y: p3.y }\n return { slope, flat: { a: flatA, b: flatB } }\n }\n\n paint(ctx: CanvasRenderingContext2D, viewport: Viewport): void {\n const b = this.boundaries(viewport)\n if (!b) return\n const fill = fillPaint(this.style)\n if (fill) {\n ctx.save()\n ctx.fillStyle = fill\n ctx.beginPath()\n ctx.moveTo(b.slope.a.x, b.slope.a.y)\n ctx.lineTo(b.slope.b.x, b.slope.b.y)\n ctx.lineTo(b.flat.b.x, b.flat.b.y)\n ctx.lineTo(b.flat.a.x, b.flat.a.y)\n ctx.closePath()\n ctx.fill()\n ctx.restore()\n }\n applyStroke(ctx, this.style)\n strokeSegment(ctx, b.slope.a, b.slope.b)\n strokeSegment(ctx, b.flat.a, b.flat.b)\n if (this.props.text) paintLabel(ctx, this.props.text, { x: b.slope.a.x + 6, y: b.slope.a.y - 12 }, this.style)\n }\n\n /** The flat side's handle stands at the flat side's end under the second anchor: the flat side\n * spans the sloped side's times at the third anchor's price, and that anchor's own time paints\n * nothing, so a handle at it would drift off the side as the sloped side moves. */\n override getControlPoints(viewport: Viewport): ControlPoint[] {\n const points = super.getControlPoints(viewport)\n const end = points.find((point) => point.index === 1)\n return end ? points.map((point) => (point.index === 2 ? { ...point, x: end.x } : point)) : points\n }\n\n testHit(point: Point, viewport: Viewport): boolean {\n const b = this.boundaries(viewport)\n if (!b) return false\n const tolerance = hitTolerance(this.style.lineWidth)\n if (distanceToSegment(point, b.slope.a, b.slope.b) <= tolerance) return true\n if (distanceToSegment(point, b.flat.a, b.flat.b) <= tolerance) return true\n const minX = Math.min(b.slope.a.x, b.slope.b.x)\n const maxX = Math.max(b.slope.a.x, b.slope.b.x)\n if (point.x < minX || point.x > maxX) return false\n const t = (point.x - b.slope.a.x) / (b.slope.b.x - b.slope.a.x || 1)\n const ySlope = b.slope.a.y + (b.slope.b.y - b.slope.a.y) * t\n return point.y >= Math.min(ySlope, b.flat.a.y) && point.y <= Math.max(ySlope, b.flat.a.y)\n }\n}\n\n/** Disjoint channel: two independent boundaries (anchors 1–2 and 3–4) with a filled body. */\nexport class DisjointChannel extends Drawing<ChannelProps> {\n readonly type = 'disjoint_channel'\n\n protected override defaultProps(): ChannelProps {\n return { ...CHANNEL_PROPS }\n }\n\n requiredAnchors(): number {\n return 4\n }\n\n protected boundaries(viewport: Viewport): { top: { a: Point; b: Point }; bottom: { a: Point; b: Point } } | null {\n const [p1, p2, p3, p4] = this.anchorPixels(viewport)\n if (!p1 || !p2 || !p3 || !p4) return null\n const { extendLeft, extendRight } = this.props\n const line = (a: Point, b: Point) =>\n extendLeft || extendRight ? extendSegment(a, b, viewport.width, viewport.height, extendLeft, extendRight) : { a, b }\n return { top: line(p1, p2), bottom: line(p3, p4) }\n }\n\n paint(ctx: CanvasRenderingContext2D, viewport: Viewport): void {\n const b = this.boundaries(viewport)\n if (!b) return\n const fill = fillPaint(this.style)\n if (fill) {\n ctx.save()\n ctx.fillStyle = fill\n ctx.beginPath()\n ctx.moveTo(b.top.a.x, b.top.a.y)\n ctx.lineTo(b.top.b.x, b.top.b.y)\n ctx.lineTo(b.bottom.b.x, b.bottom.b.y)\n ctx.lineTo(b.bottom.a.x, b.bottom.a.y)\n ctx.closePath()\n ctx.fill()\n ctx.restore()\n }\n applyStroke(ctx, this.style)\n strokeSegment(ctx, b.top.a, b.top.b)\n strokeSegment(ctx, b.bottom.a, b.bottom.b)\n if (this.props.text) paintLabel(ctx, this.props.text, { x: b.top.a.x + 6, y: b.top.a.y - 12 }, this.style)\n }\n\n testHit(point: Point, viewport: Viewport): boolean {\n const b = this.boundaries(viewport)\n if (!b) return false\n const tolerance = hitTolerance(this.style.lineWidth)\n return (\n distanceToSegment(point, b.top.a, b.top.b) <= tolerance ||\n distanceToSegment(point, b.bottom.a, b.bottom.b) <= tolerance\n )\n }\n}\n","import type { Point, Viewport } from '../core/types'\nimport { Drawing } from '../core/drawing'\nimport { distanceToSegment, midpoint } from '../core/geometry'\nimport { applyStroke, strokeSegment, withAlpha } from '../render/canvas'\n\n/** One additional line set at ±value of the fork's half-width (1 = the tines through p2/p3). */\nexport type ForkLevel = {\n value: number\n visible: boolean\n /** Per-set line color; the drawing's stroke color when omitted. */\n color?: string\n}\n\nexport type ForkVariant = 'original' | 'schiff' | 'modified_schiff' | 'inside'\n\nexport type PitchforkProps = {\n /** Which fork construction the median uses — switchable in place. */\n variant: ForkVariant\n /** Extend all lines left as well as right. */\n extendLines: boolean\n levels: ForkLevel[]\n /** Background fill between visible line pairs. */\n background: boolean\n}\n\nconst DEFAULT_LEVELS: ForkLevel[] = [\n { value: 0.25, visible: false },\n { value: 0.5, visible: true },\n { value: 0.75, visible: false },\n { value: 1, visible: true },\n { value: 1.5, visible: false },\n { value: 2, visible: false },\n]\n\ninterface ForkGeometry {\n /** Where the median line begins (the fork's handle end). */\n origin: Point\n /** Midpoint of the p2→p3 segment — every level line is anchored relative to it. */\n mid: Point\n /** Direction of all fork lines (origin → mid). */\n dir: Point\n /** Half-width vector (mid → p3); level k passes through mid ± k·halfWidth. */\n halfWidth: Point\n}\n\n/**\n * The pitchfork family. All variants share one parametric fork — a median through `mid(p2,p3)`\n * plus level lines offset by multiples of the half-width — and differ only in where the median\n * originates.\n */\nexport class Pitchfork extends Drawing<PitchforkProps> {\n readonly type: string = 'pitchfork'\n\n /** The construction seeded at creation; the prop switches it in place afterwards. */\n protected defaultVariant(): ForkVariant {\n return 'original'\n }\n\n protected override defaultProps(): PitchforkProps {\n return {\n variant: this.defaultVariant(),\n extendLines: false,\n levels: DEFAULT_LEVELS.map((l) => ({ ...l })),\n background: true,\n }\n }\n\n requiredAnchors(): number {\n return 3\n }\n\n protected fork(viewport: Viewport): ForkGeometry | null {\n const [p1, p2, p3] = this.anchorPixels(viewport)\n if (!p1 || !p2 || !p3) return null\n const mid = midpoint(p2, p3)\n const variant = this.props.variant\n const origin =\n variant === 'schiff'\n ? midpoint(p1, p2)\n : variant === 'modified_schiff'\n ? { x: p1.x, y: (p1.y + p2.y) / 2 }\n : variant === 'inside'\n ? mid\n : p1\n // The inside fork has no handle: it emanates from the tine segment, aimed away from p1.\n const dir = variant === 'inside' ? { x: mid.x - p1.x, y: mid.y - p1.y } : { x: mid.x - origin.x, y: mid.y - origin.y }\n if (dir.x === 0 && dir.y === 0) return null\n return { origin, mid, dir, halfWidth: { x: p3.x - mid.x, y: p3.y - mid.y } }\n }\n\n /** A fork line through `at`, running along the fork direction to the pane edge(s). */\n protected lineThrough(fork: ForkGeometry, at: Point, viewport: Viewport): { a: Point; b: Point } {\n // Scale the direction so the far end always clears the pane regardless of zoom.\n const reach = (viewport.width + viewport.height) / Math.hypot(fork.dir.x, fork.dir.y)\n const b = { x: at.x + fork.dir.x * reach, y: at.y + fork.dir.y * reach }\n const a = this.props.extendLines ? { x: at.x - fork.dir.x * reach, y: at.y - fork.dir.y * reach } : at\n return { a, b }\n }\n\n protected levelPoint(fork: ForkGeometry, value: number): Point {\n return { x: fork.mid.x + fork.halfWidth.x * value, y: fork.mid.y + fork.halfWidth.y * value }\n }\n\n paint(ctx: CanvasRenderingContext2D, viewport: Viewport): void {\n const fork = this.fork(viewport)\n if (!fork) return\n const visible = this.props.levels.filter((l) => l.visible && l.value > 0)\n\n if (this.props.background && visible.length > 0) {\n // Fill between each adjacent pair of visible level lines, mirrored above and below.\n const sorted = [...visible].sort((a, b) => a.value - b.value)\n const bands: [number, number][] = []\n let prev = 0\n for (const l of sorted) {\n bands.push([prev, l.value])\n prev = l.value\n }\n ctx.save()\n for (let i = 0; i < bands.length; i++) {\n const [from, to] = bands[i]\n const alpha = 0.06 + 0.03 * (bands.length - i)\n ctx.fillStyle = withAlpha(this.style.lineColor, alpha)\n for (const sign of [1, -1]) {\n const lineA = this.lineThrough(fork, this.levelPoint(fork, from * sign), viewport)\n const lineB = this.lineThrough(fork, this.levelPoint(fork, to * sign), viewport)\n ctx.beginPath()\n ctx.moveTo(lineA.a.x, lineA.a.y)\n ctx.lineTo(lineA.b.x, lineA.b.y)\n ctx.lineTo(lineB.b.x, lineB.b.y)\n ctx.lineTo(lineB.a.x, lineB.a.y)\n ctx.closePath()\n ctx.fill()\n }\n }\n ctx.restore()\n }\n\n applyStroke(ctx, this.style)\n // Median: handle from the origin to mid, then onward along the fork.\n const median = this.lineThrough(fork, fork.mid, viewport)\n strokeSegment(ctx, this.props.extendLines ? median.a : fork.origin, median.b)\n // Level lines above and below, each set in its own color when one is chosen.\n for (const level of visible) {\n ctx.save()\n applyStroke(ctx, this.style)\n if (level.color) ctx.strokeStyle = level.color\n for (const sign of [1, -1]) {\n const line = this.lineThrough(fork, this.levelPoint(fork, level.value * sign), viewport)\n strokeSegment(ctx, line.a, line.b)\n }\n ctx.restore()\n }\n }\n\n testHit(point: Point, viewport: Viewport): boolean {\n const fork = this.fork(viewport)\n if (!fork) return false\n const tolerance = Math.max(6, this.style.lineWidth / 2 + 4)\n const median = this.lineThrough(fork, fork.mid, viewport)\n if (distanceToSegment(point, this.props.extendLines ? median.a : fork.origin, median.b) <= tolerance) return true\n for (const level of this.props.levels) {\n if (!level.visible || level.value <= 0) continue\n for (const sign of [1, -1]) {\n const line = this.lineThrough(fork, this.levelPoint(fork, level.value * sign), viewport)\n if (distanceToSegment(point, line.a, line.b) <= tolerance) return true\n }\n }\n return false\n }\n}\n\n/** Median origin at the full midpoint (time and price) of p1→p2. */\nexport class SchiffPitchfork extends Pitchfork {\n override readonly type = 'schiff_pitchfork'\n\n protected override defaultVariant(): ForkVariant {\n return 'schiff'\n }\n}\n\n/** Median origin shifted half the p1→p2 price distance, at p1's time. */\nexport class ModifiedSchiffPitchfork extends Pitchfork {\n override readonly type = 'schiff_pitchfork_modified'\n\n protected override defaultVariant(): ForkVariant {\n return 'modified_schiff'\n }\n}\n\n/** No handle: the fork emanates from the p2→p3 segment itself, aimed away from p1. */\nexport class InsidePitchfork extends Pitchfork {\n override readonly type = 'inside_pitchfork'\n\n protected override defaultVariant(): ForkVariant {\n return 'inside'\n }\n}\n","import type { ControlPoint, Point, Viewport } from '../core/types'\nimport { Drawing } from '../core/drawing'\nimport { angleOf, distanceToSegment, extendSegment, midpoint } from '../core/geometry'\nimport { applyStroke, dashPattern, paintLabel, strokeSegment, withAlpha } from '../render/canvas'\n\n/** One retracement/extension level. Color falls back to the shared palette by position. */\nexport type FibLevel = {\n value: number\n visible: boolean\n color?: string\n /** Custom per-level caption, prefixed to the ratio in the level's label. */\n text?: string\n}\n\nexport type FibProps = {\n levels: FibLevel[]\n extendLeft: boolean\n extendRight: boolean\n showPrices: boolean\n showLevels: boolean\n /** Swap which anchor is level 0 / level 1. */\n reverse: boolean\n background: boolean\n}\n\n/** Level palette keyed by common ratios; anything else falls back by index. */\nconst LEVEL_COLORS: Record<string, string> = {\n '0': '#787b86',\n '0.236': '#f23645',\n '0.382': '#ff9800',\n '0.5': '#4caf50',\n '0.618': '#089981',\n '0.786': '#00bcd4',\n '1': '#787b86',\n '1.618': '#2962ff',\n '2.618': '#f23645',\n '3.618': '#9c27b0',\n '4.236': '#e91e63',\n}\n\nconst FALLBACK_COLORS = ['#2962ff', '#f23645', '#ff9800', '#4caf50', '#089981', '#00bcd4', '#9c27b0', '#e91e63']\n\nexport function fibLevelColor(level: FibLevel, index: number): string {\n return level.color ?? LEVEL_COLORS[String(level.value)] ?? FALLBACK_COLORS[index % FALLBACK_COLORS.length]\n}\n\nconst RETRACEMENT_LEVELS: FibLevel[] = [\n { value: 0, visible: true },\n { value: 0.236, visible: true },\n { value: 0.382, visible: true },\n { value: 0.5, visible: true },\n { value: 0.618, visible: true },\n { value: 0.786, visible: true },\n { value: 1, visible: true },\n { value: 1.618, visible: true },\n { value: 2.618, visible: true },\n { value: 3.618, visible: true },\n { value: 4.236, visible: true },\n]\n\nconst EXTENSION_LEVELS: FibLevel[] = [\n { value: 0, visible: true },\n { value: 0.382, visible: true },\n { value: 0.618, visible: true },\n { value: 1, visible: true },\n { value: 1.382, visible: true },\n { value: 1.618, visible: true },\n { value: 2.618, visible: true },\n { value: 3.618, visible: false },\n { value: 4.236, visible: false },\n]\n\nconst CHANNEL_LEVELS: FibLevel[] = [\n { value: 0, visible: true },\n { value: 0.25, visible: true },\n { value: 0.382, visible: true },\n { value: 0.5, visible: true },\n { value: 0.618, visible: true },\n { value: 0.75, visible: true },\n { value: 1, visible: true },\n { value: 1.618, visible: false },\n { value: 2.618, visible: false },\n]\n\nconst RATIO_FRACTIONS: FibLevel[] = [\n { value: 0.25, visible: true },\n { value: 0.382, visible: true },\n { value: 0.5, visible: true },\n { value: 0.618, visible: true },\n { value: 0.75, visible: true },\n { value: 1, visible: true },\n]\n\nconst TIME_SEQUENCE = [0, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]\nconst TIME_RATIOS: FibLevel[] = [\n { value: 0, visible: true },\n { value: 0.382, visible: true },\n { value: 0.618, visible: true },\n { value: 1, visible: true },\n { value: 1.382, visible: true },\n { value: 1.618, visible: true },\n { value: 2, visible: true },\n { value: 2.618, visible: false },\n]\n\nconst GOLDEN_RATIO = 1.618033988749895\n\nfunction fibDefaults(levels: FibLevel[]): FibProps {\n return {\n levels: levels.map((l) => ({ ...l })),\n extendLeft: false,\n extendRight: false,\n showPrices: true,\n showLevels: true,\n reverse: false,\n background: true,\n }\n}\n\nfunction hitTolerance(lineWidth: number): number {\n return Math.max(6, lineWidth / 2 + 4)\n}\n\n/** Horizontal retracement levels between two swing points (level 0 at the second anchor). */\nexport class FibRetracement extends Drawing<FibProps> {\n readonly type: string = 'fib_retracement'\n\n protected override defaultProps(): FibProps {\n return fibDefaults(RETRACEMENT_LEVELS)\n }\n\n requiredAnchors(): number {\n return 2\n }\n\n /** Price at a ratio (0 = second anchor, 1 = first; reverse swaps). */\n protected priceAt(value: number): number {\n const [a, b] = this.anchors\n const [from, to] = this.props.reverse ? [a, b] : [b, a]\n return from.price + (to.price - from.price) * value\n }\n\n protected span(viewport: Viewport): { minX: number; maxX: number } | null {\n const [pa, pb] = this.anchorPixels(viewport)\n if (!pa || !pb) return null\n return {\n minX: this.props.extendLeft ? 0 : Math.min(pa.x, pb.x),\n maxX: this.props.extendRight ? viewport.width : Math.max(pa.x, pb.x),\n }\n }\n\n paint(ctx: CanvasRenderingContext2D, viewport: Viewport): void {\n if (this.anchors.length < 2) return\n const span = this.span(viewport)\n if (!span) return\n const visible = this.props.levels\n .map((level, i) => ({ level, color: fibLevelColor(level, i) }))\n .filter((e) => e.level.visible)\n .map((e) => ({ ...e, y: viewport.yOf(this.priceAt(e.level.value)) }))\n .filter((e): e is typeof e & { y: number } => e.y !== null)\n .sort((a, b) => a.y - b.y)\n\n if (this.props.background) {\n for (let i = 0; i < visible.length - 1; i++) {\n ctx.fillStyle = withAlpha(visible[i + 1].color, 0.07)\n ctx.fillRect(span.minX, visible[i].y, span.maxX - span.minX, visible[i + 1].y - visible[i].y)\n }\n }\n for (const entry of visible) {\n ctx.save()\n applyStroke(ctx, this.style)\n ctx.strokeStyle = entry.color\n strokeSegment(ctx, { x: span.minX, y: entry.y }, { x: span.maxX, y: entry.y })\n ctx.restore()\n const parts: string[] = []\n if (entry.level.text) parts.push(entry.level.text)\n if (this.props.showLevels) parts.push(String(entry.level.value))\n if (this.props.showPrices) parts.push(`(${this.formatPrice(this.priceAt(entry.level.value))})`)\n if (parts.length) {\n paintLabel(ctx, parts.join(' '), { x: span.minX - 6, y: entry.y }, { ...this.style, textColor: entry.color }, { align: 'right' })\n }\n }\n }\n\n testHit(point: Point, viewport: Viewport): boolean {\n if (this.anchors.length < 2) return false\n const span = this.span(viewport)\n if (!span) return false\n const tolerance = hitTolerance(this.style.lineWidth)\n if (point.x < span.minX - tolerance || point.x > span.maxX + tolerance) return false\n for (const [i, level] of this.props.levels.entries()) {\n void i\n if (!level.visible) continue\n const y = viewport.yOf(this.priceAt(level.value))\n if (y !== null && Math.abs(point.y - y) <= tolerance) return true\n }\n return false\n }\n}\n\n/** Extension levels projected from a third point by the first swing's price delta. */\nexport class FibExtension extends FibRetracement {\n override readonly type = 'fib_trend_ext'\n\n protected override defaultProps(): FibProps {\n return fibDefaults(EXTENSION_LEVELS)\n }\n\n override requiredAnchors(): number {\n return 3\n }\n\n protected override priceAt(value: number): number {\n const [a, b, c] = this.anchors\n const delta = (b.price - a.price) * (this.props.reverse ? -1 : 1)\n return c.price + delta * value\n }\n\n protected override span(viewport: Viewport): { minX: number; maxX: number } | null {\n const [pa, pb, pc] = this.anchorPixels(viewport)\n if (!pa || !pb || !pc) return null\n return {\n minX: this.props.extendLeft ? 0 : pc.x,\n maxX: this.props.extendRight ? viewport.width : pc.x + Math.max(40, Math.abs(pb.x - pa.x)),\n }\n }\n\n override paint(ctx: CanvasRenderingContext2D, viewport: Viewport): void {\n if (this.anchors.length < 3) return\n super.paint(ctx, viewport)\n // The defining swing, drawn faintly so the projection's source stays visible.\n const [pa, pb, pc] = this.anchorPixels(viewport)\n if (!pa || !pb || !pc) return\n ctx.save()\n applyStroke(ctx, this.style)\n ctx.globalAlpha = 0.5\n ctx.setLineDash(dashPattern('dashed', this.style.lineWidth))\n strokeSegment(ctx, pa, pb)\n strokeSegment(ctx, pb, pc)\n ctx.restore()\n }\n\n override testHit(point: Point, viewport: Viewport): boolean {\n if (this.anchors.length < 3) return false\n return super.testHit(point, viewport)\n }\n}\n\n/** Parallel channel whose offset repeats at ratio multiples. */\nexport class FibChannel extends Drawing<FibProps> {\n readonly type = 'fib_channel'\n\n protected override defaultProps(): FibProps {\n return fibDefaults(CHANNEL_LEVELS)\n }\n\n requiredAnchors(): number {\n return 3\n }\n\n protected lines(viewport: Viewport): { level: FibLevel; color: string; a: Point; b: Point }[] {\n const [p1, p2, p3] = this.anchorPixels(viewport)\n if (!p1 || !p2 || !p3) return []\n const slopeT = (p3.x - p1.x) / ((p2.x - p1.x) || 1)\n const dy = p3.y - (p1.y + (p2.y - p1.y) * slopeT)\n const { extendLeft, extendRight } = this.props\n return this.props.levels\n .map((level, i) => ({ level, color: fibLevelColor(level, i) }))\n .filter((e) => e.level.visible)\n .map((e) => {\n const a = { x: p1.x, y: p1.y + dy * e.level.value }\n const b = { x: p2.x, y: p2.y + dy * e.level.value }\n const seg = extendLeft || extendRight ? extendSegment(a, b, viewport.width, viewport.height, extendLeft, extendRight) : { a, b }\n return { ...e, ...seg }\n })\n }\n\n paint(ctx: CanvasRenderingContext2D, viewport: Viewport): void {\n const lines = this.lines(viewport)\n if (this.props.background) {\n for (let i = 0; i < lines.length - 1; i++) {\n ctx.fillStyle = withAlpha(lines[i + 1].color, 0.06)\n ctx.beginPath()\n ctx.moveTo(lines[i].a.x, lines[i].a.y)\n ctx.lineTo(lines[i].b.x, lines[i].b.y)\n ctx.lineTo(lines[i + 1].b.x, lines[i + 1].b.y)\n ctx.lineTo(lines[i + 1].a.x, lines[i + 1].a.y)\n ctx.closePath()\n ctx.fill()\n }\n }\n for (const line of lines) {\n ctx.save()\n applyStroke(ctx, this.style)\n ctx.strokeStyle = line.color\n strokeSegment(ctx, line.a, line.b)\n ctx.restore()\n if (this.props.showLevels || this.props.showPrices || line.level.text) {\n const price = viewport.priceAt(line.a.y)\n const parts = [\n line.level.text || null,\n this.props.showLevels ? String(line.level.value) : null,\n this.props.showPrices && price !== null ? `(${this.formatPrice(price)})` : null,\n ].filter((s): s is string => s !== null)\n paintLabel(ctx, parts.join(' '), { x: line.a.x - 6, y: line.a.y }, { ...this.style, textColor: line.color }, { align: 'right' })\n }\n }\n }\n\n testHit(point: Point, viewport: Viewport): boolean {\n const tolerance = hitTolerance(this.style.lineWidth)\n return this.lines(viewport).some((line) => distanceToSegment(point, line.a, line.b) <= tolerance)\n }\n}\n\n/** Vertical lines at Fibonacci-sequence multiples of the base span. */\nexport class FibTimeZone extends Drawing<FibProps> {\n readonly type = 'fib_timezone'\n\n protected override defaultProps(): FibProps {\n return {\n ...fibDefaults(TIME_SEQUENCE.map((n) => ({ value: n, visible: true }))),\n background: false,\n }\n }\n\n requiredAnchors(): number {\n return 2\n }\n\n protected xs(viewport: Viewport): { level: FibLevel; color: string; x: number }[] {\n const [p1, p2] = this.anchorPixels(viewport)\n if (!p1 || !p2) return []\n const unit = p2.x - p1.x\n if (unit === 0) return []\n return this.props.levels\n .map((level, i) => ({ level, color: fibLevelColor(level, i), x: p1.x + unit * level.value }))\n .filter((e) => e.level.visible && e.x >= -viewport.width && e.x <= viewport.width * 2)\n }\n\n paint(ctx: CanvasRenderingContext2D, viewport: Viewport): void {\n for (const entry of this.xs(viewport)) {\n ctx.save()\n applyStroke(ctx, this.style)\n ctx.strokeStyle = entry.color\n strokeSegment(ctx, { x: entry.x, y: 0 }, { x: entry.x, y: viewport.height })\n ctx.restore()\n if (this.props.showLevels) {\n paintLabel(ctx, String(entry.level.value), { x: entry.x + 4, y: viewport.height - 12 }, { ...this.style, textColor: entry.color })\n }\n }\n }\n\n testHit(point: Point, viewport: Viewport): boolean {\n const tolerance = hitTolerance(this.style.lineWidth)\n return this.xs(viewport).some((e) => Math.abs(point.x - e.x) <= tolerance)\n }\n}\n\n/** Fan rays from the first anchor through ratio points of the spanned box's far edge. */\nexport class FibSpeedFan extends Drawing<FibProps> {\n readonly type = 'fib_speed_resist_fan'\n\n protected override defaultProps(): FibProps {\n return fibDefaults(RATIO_FRACTIONS)\n }\n\n requiredAnchors(): number {\n return 2\n }\n\n protected rays(viewport: Viewport): { level: FibLevel; color: string; a: Point; b: Point }[] {\n const [p1, p2] = this.anchorPixels(viewport)\n if (!p1 || !p2 || p1.x === p2.x) return []\n return this.props.levels\n .map((level, i) => ({ level, color: fibLevelColor(level, i) }))\n .filter((e) => e.level.visible)\n .map((e) => {\n const through = { x: p2.x, y: p1.y + (p2.y - p1.y) * e.level.value }\n const seg = extendSegment(p1, through, viewport.width, viewport.height, false, true)\n return { ...e, a: p1, b: seg.b }\n })\n }\n\n paint(ctx: CanvasRenderingContext2D, viewport: Viewport): void {\n const [p1, p2] = this.anchorPixels(viewport)\n if (!p1 || !p2) return\n ctx.save()\n applyStroke(ctx, this.style)\n ctx.globalAlpha = 0.45\n ctx.setLineDash(dashPattern('dashed', this.style.lineWidth))\n ctx.strokeRect(Math.min(p1.x, p2.x), Math.min(p1.y, p2.y), Math.abs(p2.x - p1.x), Math.abs(p2.y - p1.y))\n ctx.restore()\n for (const ray of this.rays(viewport)) {\n ctx.save()\n applyStroke(ctx, this.style)\n ctx.strokeStyle = ray.color\n strokeSegment(ctx, ray.a, ray.b)\n ctx.restore()\n if (this.props.showLevels || this.props.showPrices || ray.level.text) {\n const y = p1.y + (p2.y - p1.y) * ray.level.value\n const price = viewport.priceAt(y)\n const parts = [\n ray.level.text || null,\n this.props.showLevels ? String(ray.level.value) : null,\n this.props.showPrices && price !== null ? `(${this.formatPrice(price)})` : null,\n ].filter((s): s is string => s !== null)\n paintLabel(ctx, parts.join(' '), { x: p2.x + 6, y }, { ...this.style, textColor: ray.color })\n }\n }\n }\n\n testHit(point: Point, viewport: Viewport): boolean {\n const tolerance = hitTolerance(this.style.lineWidth)\n return this.rays(viewport).some((ray) => distanceToSegment(point, ray.a, ray.b) <= tolerance)\n }\n}\n\n/** Vertical time ratios of the first swing projected from the third anchor. */\nexport class FibTimeExtension extends Drawing<FibProps> {\n readonly type = 'fib_trend_time'\n\n protected override defaultProps(): FibProps {\n return { ...fibDefaults(TIME_RATIOS), background: false }\n }\n\n requiredAnchors(): number {\n return 3\n }\n\n protected xs(viewport: Viewport): { level: FibLevel; color: string; x: number }[] {\n const [p1, p2, p3] = this.anchorPixels(viewport)\n if (!p1 || !p2 || !p3) return []\n const unit = p2.x - p1.x\n if (unit === 0) return []\n return this.props.levels\n .map((level, i) => ({ level, color: fibLevelColor(level, i), x: p3.x + unit * level.value }))\n .filter((e) => e.level.visible)\n }\n\n paint(ctx: CanvasRenderingContext2D, viewport: Viewport): void {\n for (const entry of this.xs(viewport)) {\n ctx.save()\n applyStroke(ctx, this.style)\n ctx.strokeStyle = entry.color\n strokeSegment(ctx, { x: entry.x, y: 0 }, { x: entry.x, y: viewport.height })\n ctx.restore()\n if (this.props.showLevels) {\n paintLabel(ctx, String(entry.level.value), { x: entry.x + 4, y: viewport.height - 12 }, { ...this.style, textColor: entry.color })\n }\n }\n }\n\n testHit(point: Point, viewport: Viewport): boolean {\n const tolerance = hitTolerance(this.style.lineWidth)\n return this.xs(viewport).some((e) => Math.abs(point.x - e.x) <= tolerance)\n }\n}\n\n/** Concentric circles at ratio multiples of the anchor distance. */\nexport type FibCirclesProps = FibProps & {\n /** Label the ratios as percentages (0.618 → 62%). */\n coeffsAsPercents: boolean\n}\n\nexport class FibCircles extends Drawing<FibCirclesProps> {\n readonly type = 'fib_circles'\n\n protected override defaultProps(): FibCirclesProps {\n return { ...fibDefaults(RATIO_FRACTIONS.concat([{ value: 1.618, visible: true }])), coeffsAsPercents: false }\n }\n\n requiredAnchors(): number {\n return 2\n }\n\n paint(ctx: CanvasRenderingContext2D, viewport: Viewport): void {\n const [p1, p2] = this.anchorPixels(viewport)\n if (!p1 || !p2) return\n const base = Math.hypot(p2.x - p1.x, p2.y - p1.y)\n if (base === 0) return\n for (const [i, level] of this.props.levels.entries()) {\n if (!level.visible) continue\n const color = fibLevelColor(level, i)\n ctx.save()\n applyStroke(ctx, this.style)\n ctx.strokeStyle = color\n ctx.beginPath()\n ctx.arc(p1.x, p1.y, base * level.value, 0, Math.PI * 2)\n ctx.stroke()\n ctx.restore()\n if (this.props.showLevels) {\n const label = this.props.coeffsAsPercents ? `${Math.round(level.value * 100)}%` : String(level.value)\n paintLabel(ctx, label, { x: p1.x + base * level.value + 4, y: p1.y }, { ...this.style, textColor: color })\n }\n }\n }\n\n testHit(point: Point, viewport: Viewport): boolean {\n const [p1, p2] = this.anchorPixels(viewport)\n if (!p1 || !p2) return false\n const base = Math.hypot(p2.x - p1.x, p2.y - p1.y)\n if (base === 0) return false\n const d = Math.hypot(point.x - p1.x, point.y - p1.y)\n const tolerance = hitTolerance(this.style.lineWidth)\n return this.props.levels.some((l) => l.visible && Math.abs(d - base * l.value) <= tolerance)\n }\n}\n\n/** Half-circle arcs at ratio radii, centered on the trend line's end and facing its origin. */\nexport type FibArcsProps = FibProps & {\n /** Complete each arc into a full circle. */\n fullCircles: boolean\n}\n\nexport class FibArcs extends Drawing<FibArcsProps> {\n readonly type = 'fib_speed_resist_arcs'\n\n protected override defaultProps(): FibArcsProps {\n return {\n ...fibDefaults([\n { value: 0.382, visible: true },\n { value: 0.5, visible: true },\n { value: 0.618, visible: true },\n { value: 1, visible: true },\n ]),\n fullCircles: false,\n }\n }\n\n requiredAnchors(): number {\n return 2\n }\n\n paint(ctx: CanvasRenderingContext2D, viewport: Viewport): void {\n const [p1, p2] = this.anchorPixels(viewport)\n if (!p1 || !p2) return\n const base = Math.hypot(p2.x - p1.x, p2.y - p1.y)\n if (base === 0) return\n // The arcs bow back toward the origin: a half circle perpendicular to the trend segment.\n const back = angleOf(p2, p1)\n ctx.save()\n applyStroke(ctx, this.style)\n ctx.globalAlpha = 0.45\n ctx.setLineDash(dashPattern('dashed', this.style.lineWidth))\n strokeSegment(ctx, p1, p2)\n ctx.restore()\n for (const [i, level] of this.props.levels.entries()) {\n if (!level.visible) continue\n const color = fibLevelColor(level, i)\n ctx.save()\n applyStroke(ctx, this.style)\n ctx.strokeStyle = color\n ctx.beginPath()\n if (this.props.fullCircles) ctx.arc(p2.x, p2.y, base * level.value, 0, Math.PI * 2)\n else ctx.arc(p2.x, p2.y, base * level.value, back - Math.PI / 2, back + Math.PI / 2)\n ctx.stroke()\n ctx.restore()\n if (this.props.showLevels) {\n const lx = p2.x + Math.cos(back) * base * level.value\n const ly = p2.y + Math.sin(back) * base * level.value\n paintLabel(ctx, String(level.value), { x: lx, y: ly - 8 }, { ...this.style, textColor: color }, { align: 'center' })\n }\n }\n }\n\n testHit(point: Point, viewport: Viewport): boolean {\n const [p1, p2] = this.anchorPixels(viewport)\n if (!p1 || !p2) return false\n const base = Math.hypot(p2.x - p1.x, p2.y - p1.y)\n if (base === 0) return false\n const d = Math.hypot(point.x - p2.x, point.y - p2.y)\n const tolerance = hitTolerance(this.style.lineWidth)\n return this.props.levels.some((l) => l.visible && Math.abs(d - base * l.value) <= tolerance)\n }\n}\n\n/** Golden-ratio spiral wound from the first anchor out through the second. */\nexport class FibSpiral extends Drawing {\n readonly type = 'fib_spiral'\n\n requiredAnchors(): number {\n return 2\n }\n\n protected samples(viewport: Viewport): Point[] | null {\n const [p1, p2] = this.anchorPixels(viewport)\n if (!p1 || !p2) return null\n const target = Math.hypot(p2.x - p1.x, p2.y - p1.y)\n if (target === 0) return null\n const growth = Math.log(GOLDEN_RATIO) / (Math.PI / 2)\n const baseAngle = angleOf(p1, p2)\n const points: Point[] = []\n // Wind 2.5 turns inward and 1 turn outward around the anchor pair.\n for (let theta = -Math.PI * 5; theta <= Math.PI * 2; theta += Math.PI / 24) {\n const r = target * Math.exp(growth * theta)\n if (r < 0.5) continue\n points.push({ x: p1.x + Math.cos(baseAngle + theta) * r, y: p1.y + Math.sin(baseAngle + theta) * r })\n }\n return points\n }\n\n paint(ctx: CanvasRenderingContext2D, viewport: Viewport): void {\n const points = this.samples(viewport)\n if (!points || points.length < 2) return\n applyStroke(ctx, this.style)\n ctx.beginPath()\n ctx.moveTo(points[0].x, points[0].y)\n for (let i = 1; i < points.length; i++) ctx.lineTo(points[i].x, points[i].y)\n ctx.stroke()\n }\n\n testHit(point: Point, viewport: Viewport): boolean {\n const points = this.samples(viewport)\n if (!points) return false\n const tolerance = hitTolerance(this.style.lineWidth)\n for (let i = 0; i < points.length - 1; i++) {\n if (distanceToSegment(point, points[i], points[i + 1]) <= tolerance) return true\n }\n return false\n }\n}\n\n/** Fan of rays from the pitchfork origin through the fork's level points. */\nexport class Pitchfan extends Drawing<FibProps> {\n readonly type = 'pitchfan'\n\n protected override defaultProps(): FibProps {\n return fibDefaults([\n { value: 0, visible: true },\n { value: 0.25, visible: true },\n { value: 0.5, visible: true },\n { value: 0.75, visible: true },\n { value: 1, visible: true },\n ])\n }\n\n requiredAnchors(): number {\n return 3\n }\n\n protected rays(viewport: Viewport): { level: FibLevel; color: string; a: Point; b: Point }[] {\n const [p1, p2, p3] = this.anchorPixels(viewport)\n if (!p1 || !p2 || !p3) return []\n const mid = midpoint(p2, p3)\n return this.props.levels\n .map((level, i) => ({ level, color: fibLevelColor(level, i) }))\n .filter((e) => e.level.visible)\n .flatMap((e) => {\n const offsets = e.level.value === 0 ? [0] : [e.level.value, -e.level.value]\n return offsets.map((k) => {\n const through = { x: mid.x + (p3.x - mid.x) * k, y: mid.y + (p3.y - mid.y) * k }\n const seg = extendSegment(p1, through, viewport.width, viewport.height, false, true)\n return { ...e, a: p1, b: seg.b }\n })\n })\n }\n\n paint(ctx: CanvasRenderingContext2D, viewport: Viewport): void {\n for (const ray of this.rays(viewport)) {\n ctx.save()\n applyStroke(ctx, this.style)\n ctx.strokeStyle = ray.color\n strokeSegment(ctx, ray.a, ray.b)\n ctx.restore()\n if (this.props.showLevels) {\n // Label near the ray's far end, pulled slightly back inside the pane.\n const t = 0.92\n paintLabel(\n ctx,\n String(ray.level.value),\n { x: ray.a.x + (ray.b.x - ray.a.x) * t, y: ray.a.y + (ray.b.y - ray.a.y) * t - 8 },\n { ...this.style, textColor: ray.color },\n { align: 'center' },\n )\n }\n }\n }\n\n testHit(point: Point, viewport: Viewport): boolean {\n const tolerance = hitTolerance(this.style.lineWidth)\n return this.rays(viewport).some((ray) => distanceToSegment(point, ray.a, ray.b) <= tolerance)\n }\n}\n\n/** Wedge: two rays from an apex with ratio arcs spanning the angle between them. */\nexport class FibWedge extends Drawing<FibProps> {\n readonly type = 'fib_wedge'\n\n protected override defaultProps(): FibProps {\n return fibDefaults([\n { value: 0.382, visible: true },\n { value: 0.5, visible: true },\n { value: 0.618, visible: true },\n { value: 1, visible: true },\n ])\n }\n\n requiredAnchors(): number {\n return 3\n }\n\n protected geometry(viewport: Viewport): { apex: Point; radius: number; a1: number; a2: number } | null {\n const [apex, p2, p3] = this.anchorPixels(viewport)\n if (!apex || !p2 || !p3) return null\n const radius = Math.hypot(p2.x - apex.x, p2.y - apex.y)\n if (radius === 0) return null\n return { apex, radius, a1: angleOf(apex, p2), a2: angleOf(apex, p3) }\n }\n\n paint(ctx: CanvasRenderingContext2D, viewport: Viewport): void {\n const geo = this.geometry(viewport)\n if (!geo) return\n applyStroke(ctx, this.style)\n strokeSegment(ctx, geo.apex, { x: geo.apex.x + Math.cos(geo.a1) * geo.radius, y: geo.apex.y + Math.sin(geo.a1) * geo.radius })\n strokeSegment(ctx, geo.apex, { x: geo.apex.x + Math.cos(geo.a2) * geo.radius, y: geo.apex.y + Math.sin(geo.a2) * geo.radius })\n // Labels sit along the wedge's bisector, just past each arc.\n const cross = Math.sin(geo.a2 - geo.a1)\n const sweep = cross < 0 ? geo.a1 - geo.a2 : geo.a2 - geo.a1\n const bisector = geo.a1 + (cross < 0 ? -1 : 1) * (Math.abs(sweep) / 2)\n for (const [i, level] of this.props.levels.entries()) {\n if (!level.visible) continue\n const color = fibLevelColor(level, i)\n ctx.save()\n applyStroke(ctx, this.style)\n ctx.strokeStyle = color\n ctx.beginPath()\n // Sweep the short way between the two rays.\n ctx.arc(geo.apex.x, geo.apex.y, geo.radius * level.value, geo.a1, geo.a2, cross < 0)\n ctx.stroke()\n ctx.restore()\n if (this.props.showLevels) {\n const r = geo.radius * level.value + 9\n paintLabel(\n ctx,\n String(level.value),\n { x: geo.apex.x + Math.cos(bisector) * r, y: geo.apex.y + Math.sin(bisector) * r },\n { ...this.style, textColor: color },\n { align: 'center' },\n )\n }\n }\n }\n\n /** The third handle stands at the end of the second ray: that ray runs as long as the first, at\n * the third anchor's angle, so the anchor's own distance from the apex paints nothing and a\n * handle at it would float off the ray's end as the first ray changes length. */\n override getControlPoints(viewport: Viewport): ControlPoint[] {\n const points = super.getControlPoints(viewport)\n const geo = this.geometry(viewport)\n if (!geo) return points\n const end = { x: geo.apex.x + Math.cos(geo.a2) * geo.radius, y: geo.apex.y + Math.sin(geo.a2) * geo.radius }\n return points.map((point) => (point.index === 2 ? { ...point, ...end } : point))\n }\n\n testHit(point: Point, viewport: Viewport): boolean {\n const geo = this.geometry(viewport)\n if (!geo) return false\n const tolerance = hitTolerance(this.style.lineWidth)\n const d = Math.hypot(point.x - geo.apex.x, point.y - geo.apex.y)\n if (this.props.levels.some((l) => l.visible && Math.abs(d - geo.radius * l.value) <= tolerance)) {\n // Constrain arc hits to the wedge's angular span (short way between the rays).\n const angle = Math.atan2(point.y - geo.apex.y, point.x - geo.apex.x)\n const norm = (x: number) => ((x % (Math.PI * 2)) + Math.PI * 2) % (Math.PI * 2)\n const sweep = norm(geo.a2 - geo.a1) <= Math.PI ? norm(geo.a2 - geo.a1) : Math.PI * 2 - norm(geo.a2 - geo.a1)\n const start = norm(geo.a2 - geo.a1) <= Math.PI ? geo.a1 : geo.a2\n const rel = norm(angle - start)\n if (rel <= sweep + 0.05) return true\n }\n const end1 = { x: geo.apex.x + Math.cos(geo.a1) * geo.radius, y: geo.apex.y + Math.sin(geo.a1) * geo.radius }\n const end2 = { x: geo.apex.x + Math.cos(geo.a2) * geo.radius, y: geo.apex.y + Math.sin(geo.a2) * geo.radius }\n return distanceToSegment(point, geo.apex, end1) <= tolerance || distanceToSegment(point, geo.apex, end2) <= tolerance\n }\n}\n","import type { Point, Viewport } from '../core/types'\nimport { Drawing } from '../core/drawing'\nimport { distanceToSegment, extendSegment } from '../core/geometry'\nimport { applyStroke, paintLabel, strokeSegment, withAlpha } from '../render/canvas'\nimport { fibLevelColor, type FibLevel } from './fibonacci'\n\nexport type GannProps = {\n levels: FibLevel[]\n showLabels: boolean\n background: boolean\n}\n\nconst BOX_FRACTIONS: FibLevel[] = [\n { value: 0, visible: true },\n { value: 0.25, visible: true },\n { value: 0.382, visible: true },\n { value: 0.5, visible: true },\n { value: 0.618, visible: true },\n { value: 0.75, visible: true },\n { value: 1, visible: true },\n]\n\n/** The classic fan ratios (price units per time unit). */\nconst FAN_RATIOS = [8, 4, 3, 2, 1, 1 / 2, 1 / 3, 1 / 4, 1 / 8]\n\nfunction hitTolerance(lineWidth: number): number {\n return Math.max(6, lineWidth / 2 + 4)\n}\n\n/** Box spanned by two corners with ratio lines dividing both axes. */\nexport class GannBox extends Drawing<GannProps> {\n readonly type: string = 'gannbox'\n\n protected override defaultProps(): GannProps {\n return { levels: BOX_FRACTIONS.map((l) => ({ ...l })), showLabels: true, background: true }\n }\n\n requiredAnchors(): number {\n return 2\n }\n\n protected frame(viewport: Viewport): { a: Point; b: Point } | null {\n const [a, b] = this.anchorPixels(viewport)\n if (!a || !b) return null\n return { a, b }\n }\n\n paint(ctx: CanvasRenderingContext2D, viewport: Viewport): void {\n const f = this.frame(viewport)\n if (!f) return\n const { a, b } = f\n const visible = this.props.levels.filter((l) => l.visible)\n if (this.props.background) {\n ctx.save()\n ctx.fillStyle = withAlpha(this.style.lineColor, 0.05)\n ctx.fillRect(Math.min(a.x, b.x), Math.min(a.y, b.y), Math.abs(b.x - a.x), Math.abs(b.y - a.y))\n ctx.restore()\n }\n for (const [i, level] of visible.entries()) {\n const color = fibLevelColor(level, i)\n ctx.save()\n applyStroke(ctx, this.style)\n ctx.strokeStyle = color\n // Horizontal division…\n const y = a.y + (b.y - a.y) * level.value\n strokeSegment(ctx, { x: a.x, y }, { x: b.x, y })\n // …and the matching vertical division.\n const x = a.x + (b.x - a.x) * level.value\n strokeSegment(ctx, { x, y: a.y }, { x, y: b.y })\n ctx.restore()\n if (this.props.showLabels) {\n paintLabel(ctx, String(level.value), { x: Math.min(a.x, b.x) - 6, y }, { ...this.style, textColor: color }, { align: 'right' })\n }\n }\n }\n\n testHit(point: Point, viewport: Viewport): boolean {\n const f = this.frame(viewport)\n if (!f) return false\n const { a, b } = f\n const tolerance = hitTolerance(this.style.lineWidth)\n const inX = point.x >= Math.min(a.x, b.x) - tolerance && point.x <= Math.max(a.x, b.x) + tolerance\n const inY = point.y >= Math.min(a.y, b.y) - tolerance && point.y <= Math.max(a.y, b.y) + tolerance\n if (!inX || !inY) return false\n for (const level of this.props.levels) {\n if (!level.visible) continue\n const y = a.y + (b.y - a.y) * level.value\n if (inX && Math.abs(point.y - y) <= tolerance) return true\n const x = a.x + (b.x - a.x) * level.value\n if (inY && Math.abs(point.x - x) <= tolerance) return true\n }\n return false\n }\n}\n\n/** Gann square: the box plus its corner-to-corner diagonals. */\nexport class GannSquare extends GannBox {\n override readonly type = 'gannbox_square'\n\n override paint(ctx: CanvasRenderingContext2D, viewport: Viewport): void {\n super.paint(ctx, viewport)\n const f = this.frame(viewport)\n if (!f) return\n const { a, b } = f\n ctx.save()\n applyStroke(ctx, this.style)\n strokeSegment(ctx, a, b)\n strokeSegment(ctx, { x: a.x, y: b.y }, { x: b.x, y: a.y })\n ctx.restore()\n }\n\n override testHit(point: Point, viewport: Viewport): boolean {\n if (super.testHit(point, viewport)) return true\n const f = this.frame(viewport)\n if (!f) return false\n const tolerance = hitTolerance(this.style.lineWidth)\n return (\n distanceToSegment(point, f.a, f.b) <= tolerance ||\n distanceToSegment(point, { x: f.a.x, y: f.b.y }, { x: f.b.x, y: f.a.y }) <= tolerance\n )\n }\n}\n\n/** Gann square from a single origin: a square grid sized by one price/time unit. */\nexport class GannSquareFixed extends GannBox {\n override readonly type = 'gannbox_fixed'\n\n override requiredAnchors(): number {\n return 2\n }\n\n protected override frame(viewport: Viewport): { a: Point; b: Point } | null {\n const [a, b] = this.anchorPixels(viewport)\n if (!a || !b) return null\n // Fixed variant squares the frame: the larger drag axis sets both dimensions.\n const size = Math.max(Math.abs(b.x - a.x), Math.abs(b.y - a.y))\n return {\n a,\n b: { x: a.x + Math.sign(b.x - a.x || 1) * size, y: a.y + Math.sign(b.y - a.y || 1) * size },\n }\n }\n}\n\n/** The 1x1…8x1 fan rays from an origin, scaled by the drag vector's unit. */\nexport class GannFan extends Drawing<GannProps> {\n readonly type = 'gannbox_fan'\n\n protected override defaultProps(): GannProps {\n return {\n levels: FAN_RATIOS.map((value) => ({ value, visible: true })),\n showLabels: true,\n background: false,\n }\n }\n\n requiredAnchors(): number {\n return 2\n }\n\n protected rays(viewport: Viewport): { ratio: number; color: string; a: Point; b: Point }[] {\n const [p1, p2] = this.anchorPixels(viewport)\n if (!p1 || !p2 || p1.x === p2.x || p1.y === p2.y) return []\n const dx = p2.x - p1.x\n const dy = p2.y - p1.y\n return this.props.levels\n .filter((l) => l.visible)\n .map((l, i) => {\n const through = { x: p1.x + dx, y: p1.y + dy * l.value }\n const seg = extendSegment(p1, through, viewport.width, viewport.height, false, true)\n return { ratio: l.value, color: fibLevelColor(l, i), a: p1, b: seg.b }\n })\n }\n\n paint(ctx: CanvasRenderingContext2D, viewport: Viewport): void {\n for (const ray of this.rays(viewport)) {\n ctx.save()\n applyStroke(ctx, this.style)\n ctx.strokeStyle = ray.color\n strokeSegment(ctx, ray.a, ray.b)\n ctx.restore()\n if (this.props.showLabels) {\n const label = ray.ratio >= 1 ? `${ray.ratio}/1` : `1/${Math.round(1 / ray.ratio)}`\n paintLabel(ctx, label, { x: ray.b.x - 8, y: ray.b.y }, { ...this.style, textColor: ray.color }, { align: 'right' })\n }\n }\n }\n\n testHit(point: Point, viewport: Viewport): boolean {\n const tolerance = hitTolerance(this.style.lineWidth)\n return this.rays(viewport).some((ray) => distanceToSegment(point, ray.a, ray.b) <= tolerance)\n }\n}\n","// The MONEY stand-in. A forecasting tool writes a position's P&L and the amount at its target or\n// stop; those are money in the account's currency, not prices on the symbol's grid, so they do\n// not go through the host's price-format port (a Treasury position would otherwise read its\n// P&L in thirty-seconds). Money is written at two decimals: a DECLARED policy, the same for every\n// magnitude and every symbol, never a rule read off the value.\n\n/** A money amount at the declared two decimals, with its sign. */\nexport function moneyText(value: number): string {\n return value.toFixed(2)\n}\n","import type { ControlPoint, DrawingStyle, Point, Viewport } from '../core/types'\nimport { Drawing } from '../core/drawing'\nimport { moneyText } from '../core/money'\nimport { distanceToSegment } from '../core/geometry'\nimport { applyStroke, fillPaint, fontOf, paintArrowHead, paintLabel, strokeSegment, withAlpha } from '../render/canvas'\n\n/** The hues a position opens its two zones in, until the viewer says otherwise. */\nconst PROFIT = '#089981'\nconst LOSS = '#f23645'\n/** How solid a zone's wash opens. The bars have to stay readable through it. */\nconst ZONE_ALPHA = 0.2\n\nexport type PositionProps = {\n /** Account equity the risk figure is taken from. */\n accountSize: number\n /** Risk per trade, as a percent of the account or a money amount (per `riskDisplay`). */\n risk: number\n riskDisplay: 'percent' | 'money'\n /** Contract/lot granularity — quantity is expressed in lots of this size. */\n lotSize: number\n /** Caps the position at the account's buying power: qty ≤ account × leverage / entry. */\n leverage: number\n /** The reward zone's background: the band between entry and target, painted as given, opacity\n * and all. Its rule and its label take the same hue at full strength. */\n profitColor: string\n /** The risk zone's background, the same three places below the entry. */\n stopColor: string\n showPrices: boolean\n /** Compact stats mode — the tags shrink to their essentials. */\n compact: boolean\n}\n\n/** Everything the three tags read, derived once per paint. */\ntype PositionStats = {\n qty: number\n ratio: number\n tpOffset: number\n tpPercent: number\n slOffset: number\n slPercent: number\n amountAtTp: number\n amountAtSl: number\n /** Money PnL at the box's state (open tracks price, closed locks to the touched level). */\n pnl: number\n closed: boolean\n}\n\n/**\n * Trade plan visual: anchor 1 = entry (its time is the box's left edge), anchor 2 = target\n * (its time sets the right edge), anchor 3 = stop. The profit zone paints green with its\n * target/amount tag, the risk zone red with its stop/amount tag, and the entry line carries\n * PnL · quantity · risk/reward. Quantity is the lesser of the risk budget over the stop\n * distance and the leveraged account's buying power.\n */\nexport class LongPosition extends Drawing<PositionProps> {\n readonly type: string = 'long_position'\n\n protected override defaultProps(): PositionProps {\n return { accountSize: 1000, risk: 25, riskDisplay: 'percent', lotSize: 1, leverage: 1, profitColor: withAlpha(PROFIT, ZONE_ALPHA), stopColor: withAlpha(LOSS, ZONE_ALPHA), showPrices: true, compact: false }\n }\n\n requiredAnchors(): number {\n return 3\n }\n\n protected isShort(): boolean {\n return false\n }\n\n protected zones(viewport: Viewport): {\n left: number\n right: number\n entryY: number\n targetY: number\n stopY: number\n } | null {\n const [entry, target, stop] = this.anchorPixels(viewport)\n if (!entry || !target || !stop) return null\n const left = Math.min(entry.x, target.x)\n const right = Math.max(entry.x, target.x)\n if (right - left < 2) return null\n return { left, right, entryY: entry.y, targetY: target.y, stopY: stop.y }\n }\n\n protected stats(): PositionStats | null {\n const [entry, target, stop] = this.anchors\n if (!entry || !target || !stop) return null\n const { accountSize, risk, riskDisplay, leverage } = this.props\n const lot = this.props.lotSize > 0 ? this.props.lotSize : 1\n const short = this.isShort()\n\n const tpOffset = Math.abs(target.price - entry.price)\n const slOffset = Math.abs(entry.price - stop.price)\n const riskSize = riskDisplay === 'percent' ? (accountSize * risk) / 100 : risk\n // Qty = min(QtyRisk, QtyLvg): the risk budget over the stop distance, capped by what the\n // leveraged account can carry at the entry price. Point value is 1 (prices are per unit).\n const qtyRisk = slOffset > 0 ? riskSize / slOffset / lot : 0\n const qtyLvg = entry.price > 0 ? (accountSize * Math.max(1, leverage)) / entry.price / lot : 0\n const qty = Math.max(0, Math.min(qtyRisk, qtyLvg))\n\n const amountAtTp = accountSize + tpOffset * qty * lot\n const amountAtSl = accountSize - slOffset * qty * lot\n const ratio = slOffset > 0 ? tpOffset / slOffset : 0\n\n // PnL over the box's span: closed at ±offset once the target/stop is touched by a bar inside\n // the box, else open against the latest close at (or after) the right edge.\n const sign = short ? -1 : 1\n const bars = this.bars()\n const from = Math.min(Number(entry.time), Number(target.time))\n const to = Math.max(Number(entry.time), Number(target.time))\n let pnl = 0\n let closed = false\n let lastClose: number | null = null\n for (const bar of bars) {\n const t = Number(bar.time)\n if (t < from) continue\n if (t > to) break\n lastClose = bar.close\n const hitTp = short ? bar.low <= target.price : bar.high >= target.price\n const hitSl = short ? bar.high >= stop.price : bar.low <= stop.price\n if (hitSl) {\n pnl = -slOffset * qty * lot\n closed = true\n break\n }\n if (hitTp) {\n pnl = tpOffset * qty * lot\n closed = true\n break\n }\n }\n if (!closed) {\n // The box may sit in the future (no bars inside): open PnL tracks the last known close.\n const reference = lastClose ?? (bars.length ? bars[bars.length - 1].close : null)\n pnl = reference == null ? 0 : sign * (reference - entry.price) * qty * lot\n }\n\n return {\n qty,\n ratio,\n tpOffset,\n tpPercent: entry.price !== 0 ? (tpOffset / entry.price) * 100 : 0,\n slOffset,\n slPercent: entry.price !== 0 ? (slOffset / entry.price) * 100 : 0,\n amountAtTp,\n amountAtSl,\n pnl,\n closed,\n }\n }\n\n /** \"offset (pct%) ticks\" — the level readout shared by the target and stop tags. */\n private levelText(offset: number, percent: number): string {\n const tick = this.tickSize()\n const ticks = tick && tick > 0 ? `, ${Math.round(offset / tick)}` : ''\n return `${this.formatPrice(offset)} (${percent.toFixed(2)}%)${ticks}`\n }\n\n paint(ctx: CanvasRenderingContext2D, viewport: Viewport): void {\n const z = this.zones(viewport)\n if (!z) return\n const [entry, target, stop] = this.anchors\n ctx.save()\n const profitInk = withAlpha(this.props.profitColor, 1)\n const stopInk = withAlpha(this.props.stopColor, 1)\n ctx.fillStyle = this.props.profitColor\n ctx.fillRect(z.left, Math.min(z.entryY, z.targetY), z.right - z.left, Math.abs(z.targetY - z.entryY))\n ctx.fillStyle = this.props.stopColor\n ctx.fillRect(z.left, Math.min(z.entryY, z.stopY), z.right - z.left, Math.abs(z.stopY - z.entryY))\n ctx.restore()\n\n ctx.save()\n applyStroke(ctx, this.style)\n ctx.strokeStyle = profitInk\n strokeSegment(ctx, { x: z.left, y: z.targetY }, { x: z.right, y: z.targetY })\n ctx.strokeStyle = stopInk\n strokeSegment(ctx, { x: z.left, y: z.stopY }, { x: z.right, y: z.stopY })\n ctx.strokeStyle = this.style.lineColor\n strokeSegment(ctx, { x: z.left, y: z.entryY }, { x: z.right, y: z.entryY })\n ctx.restore()\n\n const s = this.stats()\n if (!s) return\n const mid = (z.left + z.right) / 2\n const qtyText = s.qty >= 100 ? s.qty.toFixed(0) : s.qty.toFixed(2)\n const pnlLabel = s.closed ? 'Closed PnL' : 'Open PnL'\n // The P&L and the amounts at target and stop are MONEY, written by the money stand-in; the\n // level offsets are prices on the symbol's grid and go through the price port (levelText).\n const entryText = this.props.compact\n ? `${moneyText(s.pnl)} · ${qtyText} · ${s.ratio.toFixed(2)}`\n : `${pnlLabel}: ${moneyText(s.pnl)}, Qty: ${qtyText}, Risk/Reward Ratio: ${s.ratio.toFixed(2)}`\n const targetText = this.props.compact\n ? this.levelText(s.tpOffset, s.tpPercent)\n : `Target: ${this.levelText(s.tpOffset, s.tpPercent)}, Amount: ${moneyText(s.amountAtTp)}`\n const stopText = this.props.compact\n ? this.levelText(s.slOffset, s.slPercent)\n : `Stop: ${this.levelText(s.slOffset, s.slPercent)}, Amount: ${moneyText(s.amountAtSl)}`\n\n // The three tags are written in the drawing's text colour, which is what the bar's text\n // control sets: the plan's words are the only text it has.\n paintLabel(ctx, targetText, { x: mid, y: z.targetY }, this.style, { align: 'center', background: profitInk })\n paintLabel(ctx, stopText, { x: mid, y: z.stopY }, this.style, { align: 'center', background: stopInk })\n paintLabel(ctx, entryText, { x: mid, y: z.entryY }, this.style, { align: 'center', background: '#585858' })\n\n if (this.props.showPrices) {\n paintLabel(ctx, this.formatPrice(target.price), { x: z.right + 6, y: z.targetY }, { ...this.style, textColor: profitInk })\n paintLabel(ctx, this.formatPrice(stop.price), { x: z.right + 6, y: z.stopY }, { ...this.style, textColor: stopInk })\n // Each price beside the plan is written in its own level's ink, the entry's in the entry line's:\n // the text colour belongs to the tags alone.\n paintLabel(ctx, this.formatPrice(entry.price), { x: z.right + 6, y: z.entryY }, { ...this.style, textColor: this.style.lineColor })\n }\n }\n\n /** The stop's handle stands on the box's far edge beside the target's, where the stop's level is\n * painted: the box's edges are the entry's time and the target's, and the stop's own time paints\n * nothing, so a handle at it would stay behind as the box's width changes. */\n override getControlPoints(viewport: Viewport): ControlPoint[] {\n const points = super.getControlPoints(viewport)\n const edge = points.find((point) => point.index === 1)\n return edge ? points.map((point) => (point.index === 2 ? { ...point, x: edge.x } : point)) : points\n }\n\n testHit(point: Point, viewport: Viewport): boolean {\n const z = this.zones(viewport)\n if (!z) return false\n const top = Math.min(z.entryY, z.targetY, z.stopY)\n const bottom = Math.max(z.entryY, z.targetY, z.stopY)\n return point.x >= z.left - 4 && point.x <= z.right + 4 && point.y >= top - 4 && point.y <= bottom + 4\n }\n}\n\n/** Identical structure to the long position; the PnL direction flips with the side. */\nexport class ShortPosition extends LongPosition {\n override readonly type = 'short_position'\n\n protected override isShort(): boolean {\n return true\n }\n}\n\n/** Bordered label pill (source/target/verdict boxes); returns its painted bounds. */\nfunction paintPill(\n ctx: CanvasRenderingContext2D,\n text: string,\n at: Point,\n style: DrawingStyle,\n colors: { text: string; back: string; border?: string },\n): { x: number; y: number; width: number; height: number } {\n ctx.save()\n ctx.font = fontOf(style)\n ctx.setLineDash([])\n const width = ctx.measureText(text).width + 12\n const height = style.fontSize + 10\n const box = { x: at.x - width / 2, y: at.y - height / 2, width, height }\n ctx.beginPath()\n ctx.roundRect(box.x, box.y, box.width, box.height, 4)\n ctx.fillStyle = colors.back\n ctx.fill()\n if (colors.border) {\n ctx.strokeStyle = colors.border\n ctx.lineWidth = 1\n ctx.stroke()\n }\n ctx.fillStyle = colors.text\n ctx.textAlign = 'center'\n ctx.textBaseline = 'middle'\n ctx.fillText(text, at.x, at.y)\n ctx.restore()\n return box\n}\n\nexport type ForecastProps = {\n sourceTextColor: string\n sourceBackColor: string\n sourceBorderColor: string\n targetTextColor: string\n targetBackColor: string\n targetBorderColor: string\n successTextColor: string\n successBackColor: string\n failureTextColor: string\n failureBackColor: string\n}\n\n/**\n * Position forecast: entry (source) and exit (target) anchors set a projected move and its\n * duration. As bars arrive the idea resolves itself — Success when price touches the target\n * before the target time, Failure once that time passes untouched.\n */\nexport class Forecast extends Drawing<ForecastProps> {\n readonly type = 'forecast'\n\n protected override defaultProps(): ForecastProps {\n return {\n sourceTextColor: '#ffffff',\n sourceBackColor: '#2962ff',\n sourceBorderColor: '#2962ff',\n targetTextColor: '#ffffff',\n targetBackColor: PROFIT,\n targetBorderColor: PROFIT,\n successTextColor: '#ffffff',\n successBackColor: PROFIT,\n failureTextColor: '#ffffff',\n failureBackColor: LOSS,\n }\n }\n\n requiredAnchors(): number {\n return 2\n }\n\n /** Success once a bar inside the window touches the target; Failure when time runs out. */\n private verdict(): 'Success' | 'Failure' | null {\n const [a, b] = this.anchors\n if (!a || !b) return null\n const start = Math.min(Number(a.time), Number(b.time))\n const end = Math.max(Number(a.time), Number(b.time))\n const up = b.price >= a.price\n let latest = -Infinity\n for (const bar of this.bars()) {\n const t = Number(bar.time)\n latest = Math.max(latest, t)\n if (t <= start || t > end) continue\n if (up ? bar.high >= b.price : bar.low <= b.price) return 'Success'\n }\n return latest > end ? 'Failure' : null\n }\n\n paint(ctx: CanvasRenderingContext2D, viewport: Viewport): void {\n const [p1, p2] = this.anchorPixels(viewport)\n if (!p1 || !p2) return\n const [a, b] = this.anchors\n applyStroke(ctx, this.style)\n strokeSegment(ctx, p1, p2)\n paintArrowHead(ctx, p1, p2, this.style)\n const p = this.props\n const up = b.price >= a.price\n paintPill(ctx, this.formatPrice(a.price), { x: p1.x, y: p1.y + (up ? 16 : -16) }, this.style, {\n text: p.sourceTextColor,\n back: p.sourceBackColor,\n border: p.sourceBorderColor,\n })\n paintPill(ctx, this.formatPrice(b.price), { x: p2.x, y: p2.y + (up ? -16 : 16) }, this.style, {\n text: p.targetTextColor,\n back: p.targetBackColor,\n border: p.targetBorderColor,\n })\n const verdict = this.verdict()\n if (verdict) {\n const win = verdict === 'Success'\n paintPill(ctx, verdict, { x: p2.x, y: p2.y + (up ? -40 : 40) }, this.style, {\n text: win ? p.successTextColor : p.failureTextColor,\n back: win ? p.successBackColor : p.failureBackColor,\n })\n }\n }\n\n testHit(point: Point, viewport: Viewport): boolean {\n const [p1, p2] = this.anchorPixels(viewport)\n if (!p1 || !p2) return false\n return distanceToSegment(point, p1, p2) <= Math.max(6, this.style.lineWidth / 2 + 4)\n }\n}\n\n/**\n * Sector: a wedge projecting price forward — origin, a horizontal point in the future, and a\n * third point at the estimated price. The arc between the two far points closes the slice.\n */\nexport class Sector extends Drawing {\n readonly type = 'sector'\n\n requiredAnchors(): number {\n return 3\n }\n\n /** Arc samples from anchor 2 to anchor 3, radius blending between the two legs. */\n private arc(viewport: Viewport): { origin: Point; p2: Point; p3: Point; samples: Point[] } | null {\n const [origin, p2, p3] = this.anchorPixels(viewport)\n if (!origin || !p2 || !p3) return null\n const r2 = Math.hypot(p2.x - origin.x, p2.y - origin.y)\n const r3 = Math.hypot(p3.x - origin.x, p3.y - origin.y)\n const a2 = Math.atan2(p2.y - origin.y, p2.x - origin.x)\n const a3 = Math.atan2(p3.y - origin.y, p3.x - origin.x)\n let sweep = a3 - a2\n if (sweep > Math.PI) sweep -= Math.PI * 2\n if (sweep < -Math.PI) sweep += Math.PI * 2\n const steps = 32\n const samples: Point[] = []\n for (let i = 0; i <= steps; i++) {\n const t = i / steps\n const angle = a2 + sweep * t\n const radius = r2 + (r3 - r2) * t\n samples.push({ x: origin.x + Math.cos(angle) * radius, y: origin.y + Math.sin(angle) * radius })\n }\n return { origin, p2, p3, samples }\n }\n\n paint(ctx: CanvasRenderingContext2D, viewport: Viewport): void {\n const arc = this.arc(viewport)\n if (!arc) return\n ctx.save()\n ctx.beginPath()\n ctx.moveTo(arc.origin.x, arc.origin.y)\n for (const s of arc.samples) ctx.lineTo(s.x, s.y)\n ctx.closePath()\n const fill = fillPaint(this.style)\n if (fill) {\n ctx.fillStyle = fill\n ctx.fill()\n }\n applyStroke(ctx, this.style)\n ctx.stroke()\n ctx.restore()\n }\n\n testHit(point: Point, viewport: Viewport): boolean {\n const arc = this.arc(viewport)\n if (!arc) return false\n const tolerance = Math.max(6, this.style.lineWidth / 2 + 4)\n if (distanceToSegment(point, arc.origin, arc.samples[0]) <= tolerance) return true\n if (distanceToSegment(point, arc.origin, arc.samples[arc.samples.length - 1]) <= tolerance) return true\n for (let i = 0; i < arc.samples.length - 1; i++) {\n if (distanceToSegment(point, arc.samples[i], arc.samples[i + 1]) <= tolerance) return true\n }\n return false\n }\n}\n","import type { ControlPoint, Point, Viewport } from '../core/types'\nimport { Drawing } from '../core/drawing'\nimport { distanceToSegment } from '../core/geometry'\nimport { applyStroke, paintArrowHead, withAlpha } from '../render/canvas'\n\nfunction hitTolerance(lineWidth: number): number {\n return Math.max(6, lineWidth / 2 + 4)\n}\n\n/** Earlier saved highlighters stored the shared 1–4 line width and rendered it eightfold. New\n * strokes store their actual pixel width, so the style value matches the toolbar label. */\nexport function highlighterStrokeWidth(lineWidth: number): number {\n return lineWidth <= 4 ? Math.max(lineWidth * 8, 12) : lineWidth\n}\n\n/** Polyline through every anchor — the shared body of the freehand/multi-point family. */\nabstract class StrokeDrawing extends Drawing {\n requiredAnchors(): number {\n return 2\n }\n\n protected points(viewport: Viewport): Point[] {\n return this.anchorPixels(viewport).filter((p): p is Point => !!p)\n }\n\n protected tracePath(ctx: CanvasRenderingContext2D, points: Point[], smooth: boolean): void {\n ctx.beginPath()\n ctx.moveTo(points[0].x, points[0].y)\n if (smooth && points.length > 2) {\n // Midpoint quadratic smoothing keeps a hand-drawn stroke from looking segmented.\n for (let i = 1; i < points.length - 1; i++) {\n const midX = (points[i].x + points[i + 1].x) / 2\n const midY = (points[i].y + points[i + 1].y) / 2\n ctx.quadraticCurveTo(points[i].x, points[i].y, midX, midY)\n }\n const last = points[points.length - 1]\n ctx.lineTo(last.x, last.y)\n } else {\n for (let i = 1; i < points.length; i++) ctx.lineTo(points[i].x, points[i].y)\n }\n }\n\n testHit(point: Point, viewport: Viewport): boolean {\n const points = this.points(viewport)\n const tolerance = hitTolerance(this.strokeWidth())\n for (let i = 0; i < points.length - 1; i++) {\n if (distanceToSegment(point, points[i], points[i + 1]) <= tolerance) return true\n }\n return false\n }\n\n protected strokeWidth(): number {\n return this.style.lineWidth\n }\n}\n\n/** Sampled points shape a freehand stroke, but are not individually editable handles. The whole\n * stroke remains selectable and movable by grabbing its ink. */\nabstract class FreehandStroke extends StrokeDrawing {\n override getControlPoints(_viewport: Viewport): ControlPoint[] {\n return []\n }\n}\n\n/** Freehand stroke captured while the pointer drags. */\nexport class Brush extends FreehandStroke {\n readonly type: string = 'brush'\n\n paint(ctx: CanvasRenderingContext2D, viewport: Viewport): void {\n const points = this.points(viewport)\n if (points.length < 2) return\n // The background channel fills the stroke's enclosed area (path closed back to the start).\n if (this.style.fillOpacity > 0) {\n ctx.save()\n ctx.fillStyle = withAlpha(this.style.fillColor, this.style.fillOpacity)\n this.tracePath(ctx, points, true)\n ctx.closePath()\n ctx.fill()\n ctx.restore()\n }\n applyStroke(ctx, this.style)\n this.tracePath(ctx, points, true)\n ctx.stroke()\n }\n}\n\n/**\n * Brush variant: a wide stroke that reads as marker ink. Always solid — the translucency lives\n * in the color value itself (the default seeds ~35% alpha), so the opacity control is the whole\n * style surface.\n */\nexport class Highlighter extends FreehandStroke {\n override readonly type = 'highlighter'\n\n paint(ctx: CanvasRenderingContext2D, viewport: Viewport): void {\n const points = this.points(viewport)\n if (points.length < 2) return\n ctx.save()\n ctx.setLineDash([])\n ctx.lineCap = 'round'\n ctx.lineJoin = 'round'\n ctx.strokeStyle = this.style.lineColor\n ctx.lineWidth = highlighterStrokeWidth(this.style.lineWidth)\n this.tracePath(ctx, points, true)\n ctx.stroke()\n ctx.restore()\n }\n\n protected override strokeWidth(): number {\n return highlighterStrokeWidth(this.style.lineWidth)\n }\n}\n\n/** Click-placed polyline with an arrow at its final point. */\nexport class PathLine extends StrokeDrawing {\n override readonly type = 'path'\n\n paint(ctx: CanvasRenderingContext2D, viewport: Viewport): void {\n const points = this.points(viewport)\n if (points.length < 2) return\n applyStroke(ctx, this.style)\n this.tracePath(ctx, points, false)\n ctx.stroke()\n paintArrowHead(ctx, points[points.length - 2], points[points.length - 1], this.style)\n }\n}\n\n/** Click-placed polygon; closes and fills once it has three points. */\nexport class Polyline extends StrokeDrawing {\n override readonly type = 'polyline'\n\n paint(ctx: CanvasRenderingContext2D, viewport: Viewport): void {\n const points = this.points(viewport)\n if (points.length < 2) return\n applyStroke(ctx, this.style)\n this.tracePath(ctx, points, false)\n if (points.length > 2) {\n ctx.closePath()\n if (this.style.fillOpacity > 0) {\n ctx.fillStyle = withAlpha(this.style.fillColor, this.style.fillOpacity)\n ctx.fill()\n }\n }\n ctx.stroke()\n }\n\n override testHit(point: Point, viewport: Viewport): boolean {\n if (super.testHit(point, viewport)) return true\n const points = this.points(viewport)\n if (points.length < 3) return false\n const tolerance = hitTolerance(this.style.lineWidth)\n return distanceToSegment(point, points[points.length - 1], points[0]) <= tolerance\n }\n}\n","import type { Point, Viewport } from '../core/types'\nimport { Drawing } from '../core/drawing'\nimport { fillPaint, fontOf, withAlpha } from '../render/canvas'\n\nexport type TableProps = {\n /** Row-major cell text. The grid's shape IS this array's shape. */\n cells: string[][]\n headerRow: boolean\n /** Per-column widths / per-row heights in px; entries beyond the arrays use the defaults, so\n * row/column appends never have to touch them. */\n colWidths: number[]\n rowHeights: number[]\n}\n\nconst CELL_WIDTH = 96\nconst CELL_HEIGHT = 26\nconst CELL_PAD = 8\nconst MIN_COL = 28\nconst MAX_COL = 600\nconst MIN_ROW = 16\nconst MAX_ROW = 200\n\n/**\n * Floating table pinned to a chart point (anchor = top-left). Corners scale the whole grid,\n * grips on the internal dividers resize single columns/rows, and the host edits cells inline\n * through `cellAt`.\n */\nexport class TableNote extends Drawing<TableProps> {\n readonly type = 'table'\n\n protected override defaultProps(): TableProps {\n return {\n cells: [\n ['', ''],\n ['', ''],\n ],\n headerRow: true,\n colWidths: [],\n rowHeights: [],\n }\n }\n\n requiredAnchors(): number {\n return 1\n }\n\n private colWidth(i: number): number {\n return Math.max(MIN_COL, this.props.colWidths[i] ?? CELL_WIDTH)\n }\n\n private rowHeight(r: number): number {\n return Math.max(MIN_ROW, this.props.rowHeights[r] ?? CELL_HEIGHT)\n }\n\n /** Left offsets per column boundary (0..cols) and top offsets per row boundary (0..rows). */\n private offsets(): { xs: number[]; ys: number[] } {\n const rows = this.props.cells.length\n const cols = this.props.cells[0]?.length ?? 0\n const xs = [0]\n for (let c = 0; c < cols; c++) xs.push(xs[c] + this.colWidth(c))\n const ys = [0]\n for (let r = 0; r < rows; r++) ys.push(ys[r] + this.rowHeight(r))\n return { xs, ys }\n }\n\n protected frame(viewport: Viewport): { x: number; y: number; width: number; height: number } | null {\n const anchor = this.anchors[0]\n if (!anchor) return null\n const p = this.anchorToPixel(anchor, viewport)\n if (!p) return null\n const { xs, ys } = this.offsets()\n if (xs.length < 2 || ys.length < 2) return null\n return { x: p.x, y: p.y, width: xs[xs.length - 1], height: ys[ys.length - 1] }\n }\n\n /** The cell under a pane point, with its rect — the host's inline editor opens there. */\n cellAt(point: Point, viewport: Viewport): { row: number; col: number; rect: { x: number; y: number; width: number; height: number } } | null {\n const f = this.frame(viewport)\n if (!f) return null\n const { xs, ys } = this.offsets()\n const dx = point.x - f.x\n const dy = point.y - f.y\n if (dx < 0 || dy < 0 || dx > f.width || dy > f.height) return null\n let col = 0\n while (col < xs.length - 2 && dx >= xs[col + 1]) col++\n let row = 0\n while (row < ys.length - 2 && dy >= ys[row + 1]) row++\n return {\n row,\n col,\n rect: { x: f.x + xs[col], y: f.y + ys[row], width: xs[col + 1] - xs[col], height: ys[row + 1] - ys[row] },\n }\n }\n\n paint(ctx: CanvasRenderingContext2D, viewport: Viewport): void {\n const f = this.frame(viewport)\n if (!f) return\n const rows = this.props.cells.length\n const cols = this.props.cells[0]?.length ?? 0\n const { xs, ys } = this.offsets()\n ctx.save()\n ctx.setLineDash([])\n // Card base + optional header band — the base paints from the background channel.\n const base = fillPaint(this.style)\n if (base) {\n ctx.fillStyle = base\n ctx.beginPath()\n ctx.roundRect(f.x, f.y, f.width, f.height, 4)\n ctx.fill()\n }\n if (this.props.headerRow) {\n ctx.fillStyle = withAlpha(this.style.lineColor, 0.16)\n ctx.beginPath()\n ctx.roundRect(f.x, f.y, f.width, ys[1], 4)\n ctx.fill()\n }\n // Grid lines.\n ctx.strokeStyle = withAlpha(this.style.lineColor, 0.45)\n ctx.lineWidth = 1\n ctx.beginPath()\n ctx.roundRect(f.x, f.y, f.width, f.height, 4)\n ctx.stroke()\n ctx.beginPath()\n for (let r = 1; r < rows; r++) {\n ctx.moveTo(f.x, f.y + ys[r])\n ctx.lineTo(f.x + f.width, f.y + ys[r])\n }\n for (let c = 1; c < cols; c++) {\n ctx.moveTo(f.x + xs[c], f.y)\n ctx.lineTo(f.x + xs[c], f.y + f.height)\n }\n ctx.stroke()\n // Cell text, clipped per cell.\n ctx.font = fontOf(this.style)\n ctx.textBaseline = 'middle'\n for (let r = 0; r < rows; r++) {\n for (let c = 0; c < cols; c++) {\n const text = this.props.cells[r][c]\n if (!text) continue\n ctx.save()\n ctx.beginPath()\n ctx.rect(f.x + xs[c] + 1, f.y + ys[r] + 1, xs[c + 1] - xs[c] - 2, ys[r + 1] - ys[r] - 2)\n ctx.clip()\n ctx.fillStyle = this.style.textColor\n ctx.fillText(text, f.x + xs[c] + CELL_PAD, f.y + (ys[r] + ys[r + 1]) / 2)\n ctx.restore()\n }\n }\n ctx.restore()\n }\n\n /** Corner grips only — the internal dividers drag as LINES (see `dividerHandleIndex`), so no\n * stray squares float mid-table. */\n override resizeHandles(viewport: Viewport): Point[] {\n const f = this.frame(viewport)\n if (!f) return []\n return [\n { x: f.x, y: f.y },\n { x: f.x + f.width, y: f.y },\n { x: f.x + f.width, y: f.y + f.height },\n { x: f.x, y: f.y + f.height },\n ]\n }\n\n /** Handle indices: 0-3 corners, then column dividers, row dividers, and the four outer edges\n * (left, right, top, bottom). */\n private edgeBase(): number {\n const rows = this.props.cells.length\n const cols = this.props.cells[0]?.length ?? 0\n return 4 + Math.max(0, cols - 1) + Math.max(0, rows - 1)\n }\n\n /**\n * The divider or outer edge under a point — grabbable ANYWHERE along the line (±4px). Returns\n * the `resizeTo`-compatible handle index; corners win first (the host checks grips before\n * calling this).\n */\n dividerHandleIndex(point: Point, viewport: Viewport): number | null {\n const f = this.frame(viewport)\n if (!f) return null\n const { xs, ys } = this.offsets()\n const inY = point.y >= f.y - 4 && point.y <= f.y + f.height + 4\n const inX = point.x >= f.x - 4 && point.x <= f.x + f.width + 4\n if (inY) {\n for (let c = 1; c < xs.length - 1; c++) {\n if (Math.abs(point.x - (f.x + xs[c])) <= 4) return 4 + (c - 1)\n }\n }\n if (inX) {\n for (let r = 1; r < ys.length - 1; r++) {\n if (Math.abs(point.y - (f.y + ys[r])) <= 4) return 4 + (xs.length - 2) + (r - 1)\n }\n }\n const edge = this.edgeBase()\n if (inY && Math.abs(point.x - f.x) <= 4) return edge\n if (inY && Math.abs(point.x - (f.x + f.width)) <= 4) return edge + 1\n if (inX && Math.abs(point.y - f.y) <= 4) return edge + 2\n if (inX && Math.abs(point.y - (f.y + f.height)) <= 4) return edge + 3\n return null\n }\n\n /** Hover feedback: resize cursors over the corners and divider lines. */\n protected override cursorAt(point: Point, viewport: Viewport): string | null {\n const f = this.frame(viewport)\n if (!f) return null\n const corners = this.resizeHandles(viewport)\n for (let i = 0; i < corners.length; i++) {\n if (Math.hypot(point.x - corners[i].x, point.y - corners[i].y) <= 8) {\n return i % 2 === 0 ? 'nwse-resize' : 'nesw-resize'\n }\n }\n const divider = this.dividerHandleIndex(point, viewport)\n if (divider === null) return null\n const cols = this.props.cells[0]?.length ?? 0\n const edge = this.edgeBase()\n if (divider >= edge) return divider - edge < 2 ? 'col-resize' : 'row-resize'\n return divider - 4 < cols - 1 ? 'col-resize' : 'row-resize'\n }\n\n override resizeTo(handleIndex: number, point: Point, viewport: Viewport): void {\n const f = this.frame(viewport)\n if (!f) return\n const rows = this.props.cells.length\n const cols = this.props.cells[0]?.length ?? 0\n if (!rows || !cols) return\n\n if (handleIndex < 4) {\n // Corner drag: the opposite corner pins, every column/row scales proportionally.\n const pin = [\n { x: f.x + f.width, y: f.y + f.height },\n { x: f.x, y: f.y + f.height },\n { x: f.x, y: f.y },\n { x: f.x + f.width, y: f.y },\n ][handleIndex]\n const newW = Math.max(cols * MIN_COL, Math.abs(point.x - pin.x))\n const newH = Math.max(rows * MIN_ROW, Math.abs(point.y - pin.y))\n const scaleX = newW / f.width\n const scaleY = newH / f.height\n const colWidths = Array.from({ length: cols }, (_, c) => Math.min(MAX_COL, Math.max(MIN_COL, this.colWidth(c) * scaleX)))\n const rowHeights = Array.from({ length: rows }, (_, r) => Math.min(MAX_ROW, Math.max(MIN_ROW, this.rowHeight(r) * scaleY)))\n this.applyProps({ colWidths, rowHeights } as Partial<TableProps>)\n // Keep the pinned corner where it was: the anchor is the box's top-left.\n const left = Math.min(pin.x, point.x)\n const top = Math.min(pin.y, point.y)\n const time = viewport.timeAt(left)\n const price = viewport.priceAt(top)\n if (time !== null && price !== null) this.updateAnchor(0, { time, price })\n return\n }\n\n const { xs, ys } = this.offsets()\n const edge = this.edgeBase()\n if (handleIndex >= edge) {\n const which = handleIndex - edge\n const colWidths = Array.from({ length: cols }, (_, c) => this.colWidth(c))\n const rowHeights = Array.from({ length: rows }, (_, r) => this.rowHeight(r))\n if (which === 0) {\n // Left edge: the first column grows toward the pointer, the right side stays pinned.\n colWidths[0] = Math.min(MAX_COL, Math.max(MIN_COL, f.x + xs[1] - point.x))\n this.applyProps({ colWidths } as Partial<TableProps>)\n const time = viewport.timeAt(f.x + xs[1] - colWidths[0])\n const price = viewport.priceAt(f.y)\n if (time !== null && price !== null) this.updateAnchor(0, { time, price })\n } else if (which === 1) {\n colWidths[cols - 1] = Math.min(MAX_COL, Math.max(MIN_COL, point.x - (f.x + xs[cols - 1])))\n this.applyProps({ colWidths } as Partial<TableProps>)\n } else if (which === 2) {\n // Top edge: the first row grows toward the pointer, the bottom stays pinned.\n rowHeights[0] = Math.min(MAX_ROW, Math.max(MIN_ROW, f.y + ys[1] - point.y))\n this.applyProps({ rowHeights } as Partial<TableProps>)\n const time = viewport.timeAt(f.x)\n const price = viewport.priceAt(f.y + ys[1] - rowHeights[0])\n if (time !== null && price !== null) this.updateAnchor(0, { time, price })\n } else {\n rowHeights[rows - 1] = Math.min(MAX_ROW, Math.max(MIN_ROW, point.y - (f.y + ys[rows - 1])))\n this.applyProps({ rowHeights } as Partial<TableProps>)\n }\n return\n }\n\n const divider = handleIndex - 4\n if (divider < cols - 1) {\n const colWidths = Array.from({ length: cols }, (_, c) => this.colWidth(c))\n colWidths[divider] = Math.min(MAX_COL, Math.max(MIN_COL, point.x - (f.x + xs[divider])))\n this.applyProps({ colWidths } as Partial<TableProps>)\n return\n }\n const rowIndex = divider - (cols - 1)\n if (rowIndex < rows - 1) {\n const rowHeights = Array.from({ length: rows }, (_, r) => this.rowHeight(r))\n rowHeights[rowIndex] = Math.min(MAX_ROW, Math.max(MIN_ROW, point.y - (f.y + ys[rowIndex])))\n this.applyProps({ rowHeights } as Partial<TableProps>)\n }\n }\n\n testHit(point: Point, viewport: Viewport): boolean {\n const f = this.frame(viewport)\n if (!f) return false\n return point.x >= f.x - 2 && point.x <= f.x + f.width + 2 && point.y >= f.y - 2 && point.y <= f.y + f.height + 2\n }\n}\n","import type { Point, Viewport } from '../core/types'\nimport { Drawing } from '../core/drawing'\nimport { distanceToSegment } from '../core/geometry'\nimport { applyStroke, fontOf, paintLabel, withAlpha } from '../render/canvas'\n\nfunction hitTolerance(lineWidth: number): number {\n return Math.max(6, lineWidth / 2 + 4)\n}\n\n/** What a pattern carries beyond its vertices. */\nexport type PatternProps = {\n /** The viewer's own word for the pattern, above the whole of it. */\n text: string\n}\n\n/**\n * Shared body of the pattern/wave tools: a polyline through every anchor with a circled letter\n * (or number) at each vertex. Subclasses supply the label sequence and any extra ink.\n */\nexport abstract class LabeledPolyline extends Drawing<PatternProps> {\n protected abstract labels(): readonly string[]\n\n protected override defaultProps(): PatternProps {\n return { text: '' }\n }\n\n protected points(viewport: Viewport): (Point | null)[] {\n return this.anchorPixels(viewport)\n }\n\n paint(ctx: CanvasRenderingContext2D, viewport: Viewport): void {\n const points = this.points(viewport).filter((p): p is Point => !!p)\n if (points.length < 2) return\n applyStroke(ctx, this.style)\n ctx.beginPath()\n ctx.moveTo(points[0].x, points[0].y)\n for (let i = 1; i < points.length; i++) ctx.lineTo(points[i].x, points[i].y)\n ctx.stroke()\n this.paintExtras(ctx, points, viewport)\n this.paintLabels(ctx, points)\n this.paintText(ctx, points)\n }\n\n /** The free label, standing where the hint stood offering it, so the two never drift apart. */\n protected paintText(ctx: CanvasRenderingContext2D, points: Point[]): void {\n if (!this.props.text) return\n paintLabel(ctx, this.props.text, this.textHintPlacement(points), this.style, { align: 'center' })\n }\n\n /** Placement preview IS the progressive pattern — the zigzag grows labeled leg by leg. */\n override paintConstruction(ctx: CanvasRenderingContext2D, viewport: Viewport): void {\n this.paint(ctx, viewport)\n }\n\n protected paintExtras(_ctx: CanvasRenderingContext2D, _points: Point[], _viewport: Viewport): void {}\n\n protected paintLabels(ctx: CanvasRenderingContext2D, points: Point[]): void {\n const labels = this.labels()\n ctx.save()\n ctx.setLineDash([])\n ctx.font = fontOf(this.style)\n ctx.textAlign = 'center'\n ctx.textBaseline = 'middle'\n for (let i = 0; i < points.length && i < labels.length; i++) {\n if (!labels[i]) continue // an unlabeled vertex (a pattern's starting point)\n const p = points[i]\n // Place the pill away from the line: above when the vertex is a local high, below otherwise.\n const prev = points[i - 1] ?? points[i + 1]\n const dy = prev && prev.y > p.y ? -14 : 14\n const cy = p.y + dy\n ctx.fillStyle = withAlpha('#1b1f27', 0.95)\n ctx.beginPath()\n ctx.arc(p.x, cy, 9, 0, Math.PI * 2)\n ctx.fill()\n ctx.strokeStyle = this.style.lineColor\n ctx.lineWidth = 1\n ctx.stroke()\n // The letters render through the text channel — label color/font edit independently.\n ctx.fillStyle = this.style.textColor\n ctx.fillText(labels[i], p.x, cy + 0.5)\n }\n ctx.restore()\n }\n\n testHit(point: Point, viewport: Viewport): boolean {\n const points = this.points(viewport).filter((p): p is Point => !!p)\n const tolerance = hitTolerance(this.style.lineWidth)\n for (let i = 0; i < points.length - 1; i++) {\n if (distanceToSegment(point, points[i], points[i + 1]) <= tolerance) return true\n }\n return false\n }\n}\n\n/** Fill the triangle spanned by three points with the drawing's background channel. */\nfunction fillTriangle(\n ctx: CanvasRenderingContext2D,\n style: { fillColor: string; fillOpacity: number },\n a: Point,\n b: Point,\n c: Point,\n): void {\n if (style.fillOpacity <= 0) return\n ctx.save()\n ctx.fillStyle = withAlpha(style.fillColor, style.fillOpacity)\n ctx.beginPath()\n ctx.moveTo(a.x, a.y)\n ctx.lineTo(b.x, b.y)\n ctx.lineTo(c.x, c.y)\n ctx.closePath()\n ctx.fill()\n ctx.restore()\n}\n\n/** Five-point harmonic (X A B C D) with the two classic triangles shaded. */\nexport class XabcdPattern extends LabeledPolyline {\n readonly type: string = 'xabcd_pattern'\n\n requiredAnchors(): number {\n return 5\n }\n\n protected labels(): readonly string[] {\n return ['X', 'A', 'B', 'C', 'D']\n }\n\n protected override paintExtras(ctx: CanvasRenderingContext2D, points: Point[]): void {\n if (points.length >= 3) fillTriangle(ctx, this.style, points[0], points[1], points[2])\n if (points.length >= 5) fillTriangle(ctx, this.style, points[2], points[3], points[4])\n }\n}\n\n/** Cypher: same five-point construction, its own identity for defaults/recognition. */\nexport class CypherPattern extends XabcdPattern {\n override readonly type = 'cypher_pattern'\n}\n\n/**\n * Three drives: a start point, then three with-trend drives (1, 2, 3) separated by two\n * retracements (A, C). Symmetry of the drives/retracements is the pattern's whole premise —\n * the tool just labels the six swing points.\n */\nexport class ThreeDrivesPattern extends LabeledPolyline {\n readonly type = 'three_drives'\n\n requiredAnchors(): number {\n return 6\n }\n\n protected labels(): readonly string[] {\n return ['', '1', 'A', '2', 'C', '3']\n }\n}\n\n/** Four-point AB=CD pattern with the two legs shaded. */\nexport class AbcdPattern extends LabeledPolyline {\n readonly type = 'abcd_pattern'\n\n requiredAnchors(): number {\n return 4\n }\n\n protected labels(): readonly string[] {\n return ['A', 'B', 'C', 'D']\n }\n\n protected override paintExtras(ctx: CanvasRenderingContext2D, points: Point[]): void {\n if (points.length >= 4) {\n // The AC / BD guide diagonals, dashed.\n ctx.save()\n applyStroke(ctx, this.style)\n ctx.setLineDash([4, 4])\n ctx.globalAlpha = 0.55\n ctx.beginPath()\n ctx.moveTo(points[0].x, points[0].y)\n ctx.lineTo(points[2].x, points[2].y)\n ctx.moveTo(points[1].x, points[1].y)\n ctx.lineTo(points[3].x, points[3].y)\n ctx.stroke()\n ctx.restore()\n }\n }\n}\n\n/** Four-point triangle pattern: the zigzag plus its two converging boundary lines. */\nexport class TrianglePattern extends LabeledPolyline {\n readonly type = 'triangle_pattern'\n\n requiredAnchors(): number {\n return 4\n }\n\n protected labels(): readonly string[] {\n return ['A', 'B', 'C', 'D']\n }\n\n protected override paintExtras(ctx: CanvasRenderingContext2D, points: Point[]): void {\n if (points.length < 4) return\n // Boundaries connect the alternating swing points (A→C and B→D), extended to D's time.\n ctx.save()\n applyStroke(ctx, this.style)\n ctx.globalAlpha = 0.7\n ctx.beginPath()\n ctx.moveTo(points[0].x, points[0].y)\n ctx.lineTo(points[2].x, points[2].y)\n ctx.moveTo(points[1].x, points[1].y)\n ctx.lineTo(points[3].x, points[3].y)\n ctx.stroke()\n ctx.restore()\n fillTriangle(ctx, this.style, points[0], points[1], points[2])\n }\n}\n\n/** Seven-point head & shoulders with the neckline and shaded shoulders/head. */\nexport class HeadAndShoulders extends LabeledPolyline {\n readonly type = 'head_and_shoulders'\n\n requiredAnchors(): number {\n return 7\n }\n\n protected labels(): readonly string[] {\n // Left shoulder, head, right shoulder over the classic seven pivots.\n return ['', 'LS', '', 'H', '', 'RS', '']\n }\n\n protected override paintExtras(ctx: CanvasRenderingContext2D, points: Point[]): void {\n if (points.length < 7) return\n // Neckline through the two troughs framing the head, extended across the pattern.\n ctx.save()\n applyStroke(ctx, this.style)\n ctx.setLineDash([4, 4])\n ctx.beginPath()\n ctx.moveTo(points[0].x, points[2].y + (points[0].x - points[2].x) * ((points[4].y - points[2].y) / ((points[4].x - points[2].x) || 1)))\n ctx.lineTo(points[6].x, points[2].y + (points[6].x - points[2].x) * ((points[4].y - points[2].y) / ((points[4].x - points[2].x) || 1)))\n ctx.stroke()\n ctx.restore()\n fillTriangle(ctx, this.style, points[0], points[1], points[2])\n fillTriangle(ctx, this.style, points[2], points[3], points[4])\n fillTriangle(ctx, this.style, points[4], points[5], points[6])\n }\n}\n","import { LabeledPolyline } from './patterns'\n\n// The Elliott wave set: labeled zigzags whose vocabulary (numbers vs letters) IS the tool.\n// Wave degree styling (minor/intermediate/…) refines label typography in a later pass; the\n// counts and labels here match the standard notation.\n\n/** Impulse 12345: six pivots (origin 0 + waves 1–5). */\nexport class ElliottImpulse extends LabeledPolyline {\n readonly type: string = 'elliott_impulse_wave'\n\n requiredAnchors(): number {\n return 6\n }\n\n protected labels(): readonly string[] {\n return ['0', '1', '2', '3', '4', '5']\n }\n}\n\n/** Correction ABC: origin + three corrective waves. */\nexport class ElliottCorrection extends LabeledPolyline {\n readonly type = 'elliott_correction'\n\n requiredAnchors(): number {\n return 4\n }\n\n protected labels(): readonly string[] {\n return ['0', 'A', 'B', 'C']\n }\n}\n\n/** Triangle ABCDE: origin + five contracting waves. */\nexport class ElliottTriangle extends LabeledPolyline {\n readonly type = 'elliott_triangle_wave'\n\n requiredAnchors(): number {\n return 6\n }\n\n protected labels(): readonly string[] {\n return ['0', 'A', 'B', 'C', 'D', 'E']\n }\n}\n\n/** Double combo WXY. */\nexport class ElliottDoubleCombo extends LabeledPolyline {\n readonly type = 'elliott_double_combo'\n\n requiredAnchors(): number {\n return 4\n }\n\n protected labels(): readonly string[] {\n return ['0', 'W', 'X', 'Y']\n }\n}\n\n/** Triple combo WXYXZ. */\nexport class ElliottTripleCombo extends LabeledPolyline {\n readonly type = 'elliott_triple_combo'\n\n requiredAnchors(): number {\n return 6\n }\n\n protected labels(): readonly string[] {\n return ['0', 'W', 'X', 'Y', 'X', 'Z']\n }\n}\n","import type { Point, Viewport } from '../core/types'\nimport { Drawing } from '../core/drawing'\nimport { distanceToSegment } from '../core/geometry'\nimport { applyStroke, fillPaint, strokeSegment } from '../render/canvas'\n\nfunction hitTolerance(lineWidth: number): number {\n return Math.max(6, lineWidth / 2 + 4)\n}\n\n/** Vertical lines repeating rightward at the span between the two anchors. */\nexport class CyclicLines extends Drawing {\n readonly type = 'cyclic_lines'\n\n requiredAnchors(): number {\n return 2\n }\n\n protected xs(viewport: Viewport): number[] {\n const [a, b] = this.anchorPixels(viewport)\n if (!a || !b) return []\n const step = b.x - a.x\n if (Math.abs(step) < 2) return []\n const out: number[] = []\n for (let x = a.x; x >= -step && x <= viewport.width + Math.abs(step); x += Math.abs(step)) {\n out.push(x)\n if (out.length > 200) break\n }\n return out.filter((x) => x >= 0 && x <= viewport.width)\n }\n\n paint(ctx: CanvasRenderingContext2D, viewport: Viewport): void {\n applyStroke(ctx, this.style)\n for (const x of this.xs(viewport)) strokeSegment(ctx, { x, y: 0 }, { x, y: viewport.height })\n }\n\n testHit(point: Point, viewport: Viewport): boolean {\n const tolerance = hitTolerance(this.style.lineWidth)\n return this.xs(viewport).some((x) => Math.abs(point.x - x) <= tolerance)\n }\n}\n\n/** Repeating semicircle arcs along the anchors' baseline — one hump per cycle. */\nexport class TimeCycles extends Drawing {\n readonly type = 'time_cycles'\n\n requiredAnchors(): number {\n return 2\n }\n\n protected geometry(viewport: Viewport): { y: number; startX: number; step: number } | null {\n const [a, b] = this.anchorPixels(viewport)\n if (!a || !b) return null\n const step = Math.abs(b.x - a.x)\n if (step < 4) return null\n return { y: a.y, startX: Math.min(a.x, b.x), step }\n }\n\n paint(ctx: CanvasRenderingContext2D, viewport: Viewport): void {\n const geo = this.geometry(viewport)\n if (!geo) return\n const fill = fillPaint(this.style)\n if (fill) {\n ctx.save()\n ctx.fillStyle = fill\n ctx.setLineDash([])\n let filled = 0\n for (let x = geo.startX; x <= viewport.width && filled < 200; x += geo.step, filled++) {\n ctx.beginPath()\n ctx.arc(x + geo.step / 2, geo.y, geo.step / 2, 0, Math.PI, true)\n ctx.closePath()\n ctx.fill()\n }\n ctx.restore()\n }\n applyStroke(ctx, this.style)\n ctx.beginPath()\n let count = 0\n for (let x = geo.startX; x <= viewport.width && count < 200; x += geo.step, count++) {\n ctx.moveTo(x + geo.step, geo.y)\n ctx.arc(x + geo.step / 2, geo.y, geo.step / 2, 0, Math.PI, true)\n }\n ctx.stroke()\n }\n\n testHit(point: Point, viewport: Viewport): boolean {\n const geo = this.geometry(viewport)\n if (!geo) return false\n if (point.x < geo.startX) return false\n const radius = geo.step / 2\n const within = (point.x - geo.startX) % geo.step\n const cx = point.x - within + radius\n const distance = Math.hypot(point.x - cx, point.y - geo.y)\n return point.y <= geo.y + 2 && Math.abs(distance - radius) <= hitTolerance(this.style.lineWidth)\n }\n}\n\n/** Sine wave: the anchors set half a period and the amplitude. */\nexport class SineLine extends Drawing {\n readonly type = 'sine_line'\n\n requiredAnchors(): number {\n return 2\n }\n\n protected samples(viewport: Viewport): Point[] | null {\n const [a, b] = this.anchorPixels(viewport)\n if (!a || !b) return null\n const half = b.x - a.x\n if (Math.abs(half) < 2) return null\n const amplitude = b.y - a.y\n const period = Math.abs(half) * 2\n const out: Point[] = []\n for (let x = 0; x <= viewport.width; x += Math.max(2, period / 48)) {\n const phase = ((x - a.x) / half) * Math.PI * 0.5\n out.push({ x, y: a.y + Math.sin(phase) * amplitude })\n }\n return out\n }\n\n paint(ctx: CanvasRenderingContext2D, viewport: Viewport): void {\n const samples = this.samples(viewport)\n if (!samples || samples.length < 2) return\n applyStroke(ctx, this.style)\n ctx.beginPath()\n ctx.moveTo(samples[0].x, samples[0].y)\n for (let i = 1; i < samples.length; i++) ctx.lineTo(samples[i].x, samples[i].y)\n ctx.stroke()\n }\n\n testHit(point: Point, viewport: Viewport): boolean {\n const samples = this.samples(viewport)\n if (!samples) return false\n const tolerance = hitTolerance(this.style.lineWidth)\n for (let i = 0; i < samples.length - 1; i++) {\n if (distanceToSegment(point, samples[i], samples[i + 1]) <= tolerance) return true\n }\n return false\n }\n}\n","import type { Point, Viewport } from '../core/types'\nimport { Drawing } from '../core/drawing'\nimport { barsInRange, linearRegression } from '../core/bars'\nimport { distanceToSegment } from '../core/geometry'\nimport { alphaOf, applyStroke, paintLabel, strokeSegment, withAlpha } from '../render/canvas'\n\nfunction hitTolerance(lineWidth: number): number {\n return Math.max(6, lineWidth / 2 + 4)\n}\n\nexport type RegressionProps = {\n upperDeviation: number\n lowerDeviation: number\n useUpper: boolean\n useLower: boolean\n source: 'close' | 'open' | 'hl2' | 'hlc3'\n}\n\n/**\n * Regression trend: least-squares line over the closes between the two anchors, with bands a\n * configurable number of standard deviations away. Recomputes live as bars arrive.\n */\nexport class RegressionTrend extends Drawing<RegressionProps> {\n readonly type = 'regression_trend'\n\n protected override defaultProps(): RegressionProps {\n return { upperDeviation: 2, lowerDeviation: 2, useUpper: true, useLower: true, source: 'close' }\n }\n\n requiredAnchors(): number {\n return 2\n }\n\n protected lines(viewport: Viewport): { base: [Point, Point]; upper?: [Point, Point]; lower?: [Point, Point] } | null {\n const [a, b] = this.anchors\n if (!a || !b) return null\n const range = barsInRange(this.bars(), a.time, b.time)\n const fit = linearRegression(range, this.props.source)\n if (!fit) return null\n const first = range[0]\n const last = range[range.length - 1]\n const lineAt = (offset: number): [Point, Point] | null => {\n const y1 = viewport.yOf(fit.intercept + offset)\n const y2 = viewport.yOf(fit.intercept + fit.slope * (range.length - 1) + offset)\n const x1 = viewport.xOf(first.time)\n const x2 = viewport.xOf(last.time)\n if (y1 === null || y2 === null || x1 === null || x2 === null) return null\n return [\n { x: x1, y: y1 },\n { x: x2, y: y2 },\n ]\n }\n const base = lineAt(0)\n if (!base) return null\n return {\n base,\n upper: this.props.useUpper ? (lineAt(fit.sigma * this.props.upperDeviation) ?? undefined) : undefined,\n lower: this.props.useLower ? (lineAt(-fit.sigma * this.props.lowerDeviation) ?? undefined) : undefined,\n }\n }\n\n paint(ctx: CanvasRenderingContext2D, viewport: Viewport): void {\n const lines = this.lines(viewport)\n if (!lines) {\n this.paintUnavailable(ctx, viewport)\n return\n }\n if (lines.upper && lines.lower) {\n ctx.save()\n ctx.fillStyle = withAlpha(this.style.lineColor, 0.08)\n ctx.beginPath()\n ctx.moveTo(lines.upper[0].x, lines.upper[0].y)\n ctx.lineTo(lines.upper[1].x, lines.upper[1].y)\n ctx.lineTo(lines.lower[1].x, lines.lower[1].y)\n ctx.lineTo(lines.lower[0].x, lines.lower[0].y)\n ctx.closePath()\n ctx.fill()\n ctx.restore()\n }\n applyStroke(ctx, this.style)\n strokeSegment(ctx, lines.base[0], lines.base[1])\n for (const band of [lines.upper, lines.lower]) {\n if (!band) continue\n ctx.save()\n applyStroke(ctx, this.style)\n ctx.globalAlpha = 0.7\n strokeSegment(ctx, band[0], band[1])\n ctx.restore()\n }\n }\n\n protected paintUnavailable(ctx: CanvasRenderingContext2D, viewport: Viewport): void {\n const [pa, pb] = this.anchorPixels(viewport)\n if (!pa || !pb) return\n ctx.save()\n applyStroke(ctx, this.style)\n ctx.setLineDash([4, 4])\n ctx.globalAlpha = 0.5\n strokeSegment(ctx, pa, pb)\n ctx.restore()\n paintLabel(ctx, 'no bar data in range', { x: (pa.x + pb.x) / 2, y: (pa.y + pb.y) / 2 - 12 }, this.style, {\n align: 'center',\n background: withAlpha('#1b1f27', 0.92),\n })\n }\n\n testHit(point: Point, viewport: Viewport): boolean {\n const lines = this.lines(viewport)\n const tolerance = hitTolerance(this.style.lineWidth)\n if (!lines) {\n const [pa, pb] = this.anchorPixels(viewport)\n return !!pa && !!pb && distanceToSegment(point, pa, pb) <= tolerance\n }\n for (const line of [lines.base, lines.upper, lines.lower]) {\n if (line && distanceToSegment(point, line[0], line[1]) <= tolerance) return true\n }\n return false\n }\n}\n\n/** A captured bar (relative form) inside a bars-pattern/ghost-feed payload. */\nexport type CapturedBar = {\n o: number\n h: number\n l: number\n c: number\n}\n\nexport type BarsPatternProps = {\n /** OHLC snapshot captured at placement — the pattern stays as drawn while it moves. */\n bars: CapturedBar[]\n /** Reflect the pattern vertically (price axis). */\n mirrored: boolean\n /** Reflect the pattern horizontally (time axis). */\n flipped: boolean\n /** 'bars' paints candle sticks; a price source paints the pattern as a line through it. */\n mode: 'bars' | 'open' | 'high' | 'low' | 'close' | 'hl2'\n}\n\nexport type GhostFeedProps = {\n /** Average candle high-low span in price units; 0 = auto-seed from recent bars at placement. */\n averageHL: number\n /** Wobble amplitude as a percentage of the average span (0..100). */\n variance: number\n upColor: string\n downColor: string\n borderUpColor: string\n borderDownColor: string\n wickColor: string\n drawBorder: boolean\n drawWick: boolean\n /** 0..100; candles paint at (100 − transparency)% opacity. */\n transparency: number\n}\n\n/**\n * Shared base for tools that snapshot the OHLC run between their anchors at placement and\n * repaint it wherever the drawing is dragged (prices shift with the first anchor).\n */\nexport abstract class CapturedBarsDrawing<P extends { bars: CapturedBar[] } & Record<string, unknown>> extends Drawing<P> {\n requiredAnchors(): number {\n return 2\n }\n\n /** Captured at placement by the host: the OHLC run between the anchors. */\n capture(): void {\n const [a, b] = this.anchors\n if (!a || !b) return\n const range = barsInRange(this.bars(), a.time, b.time)\n if (!range.length) return\n this.applyProps({\n bars: range.map((bar) => ({ o: bar.open, h: bar.high, l: bar.low, c: bar.close })),\n } as unknown as Partial<P>)\n }\n\n protected frame(viewport: Viewport): { x1: number; x2: number; baseY: number; scale: number } | null {\n const [pa, pb] = this.anchorPixels(viewport)\n if (!pa || !pb || this.props.bars.length === 0) return null\n // Price-to-pixel scale from the viewport at the first anchor's price.\n const yAtBase = viewport.yOf(this.anchors[0].price)\n const yAtBasePlus = viewport.yOf(this.anchors[0].price + 1)\n if (yAtBase === null || yAtBasePlus === null) return null\n const scale = yAtBasePlus - yAtBase // px per +1 price (negative in screen space)\n return { x1: Math.min(pa.x, pb.x), x2: Math.max(pa.x, pb.x), baseY: pa.y, scale }\n }\n\n protected paintPlaceholder(ctx: CanvasRenderingContext2D, viewport: Viewport): void {\n const [pa, pb] = this.anchorPixels(viewport)\n if (!pa || !pb) return\n ctx.save()\n applyStroke(ctx, this.style)\n ctx.setLineDash([4, 4])\n ctx.globalAlpha = 0.5\n ctx.strokeRect(Math.min(pa.x, pb.x), Math.min(pa.y, pb.y), Math.abs(pb.x - pa.x), Math.max(12, Math.abs(pb.y - pa.y)))\n ctx.restore()\n }\n}\n\n/** Bars pattern: the captured run repainted as sticks (or a source line), in the stroke color. */\nexport class BarsPattern extends CapturedBarsDrawing<BarsPatternProps> {\n readonly type: string = 'bars_pattern'\n\n protected override defaultProps(): BarsPatternProps {\n return { bars: [], mirrored: false, flipped: false, mode: 'bars' }\n }\n\n private priceOf(bar: CapturedBar): number {\n const { mode } = this.props\n if (mode === 'open') return bar.o\n if (mode === 'high') return bar.h\n if (mode === 'low') return bar.l\n if (mode === 'hl2') return (bar.h + bar.l) / 2\n return bar.c\n }\n\n /** Bars in paint order (flip reverses time) with the y mapper (mirror negates price offsets). */\n private sequence(f: { baseY: number; scale: number }): { seq: CapturedBar[]; yAt: (v: number) => number } {\n const seq = this.props.flipped ? [...this.props.bars].reverse() : this.props.bars\n const base = seq[0].c\n const sign = this.props.mirrored ? -1 : 1\n return { seq, yAt: (v: number) => f.baseY + (v - base) * f.scale * sign }\n }\n\n paint(ctx: CanvasRenderingContext2D, viewport: Viewport): void {\n const f = this.frame(viewport)\n if (!f) {\n this.paintPlaceholder(ctx, viewport)\n return\n }\n const { seq, yAt } = this.sequence(f)\n const width = (f.x2 - f.x1) / seq.length\n\n // The whole style surface is the one color (opacity riding in it) — no width/dash channel.\n if (this.props.mode !== 'bars') {\n ctx.save()\n ctx.setLineDash([])\n ctx.strokeStyle = this.style.lineColor\n ctx.lineWidth = 2\n ctx.lineCap = 'round'\n ctx.lineJoin = 'round'\n ctx.beginPath()\n for (let i = 0; i < seq.length; i++) {\n const x = f.x1 + width * (i + 0.5)\n const y = yAt(this.priceOf(seq[i]))\n if (i === 0) ctx.moveTo(x, y)\n else ctx.lineTo(x, y)\n }\n ctx.stroke()\n ctx.restore()\n return\n }\n\n const bodyW = Math.max(1.5, Math.min(9, width * 0.6))\n ctx.save()\n ctx.setLineDash([])\n ctx.strokeStyle = this.style.lineColor\n ctx.fillStyle = this.style.lineColor\n ctx.lineWidth = 1\n for (let i = 0; i < seq.length; i++) {\n const bar = seq[i]\n const cx = f.x1 + width * (i + 0.5)\n const yO = yAt(bar.o)\n const yC = yAt(bar.c)\n ctx.beginPath()\n ctx.moveTo(cx, yAt(bar.h))\n ctx.lineTo(cx, yAt(bar.l))\n ctx.stroke()\n ctx.fillRect(cx - bodyW / 2, Math.min(yO, yC), bodyW, Math.max(1, Math.abs(yC - yO)))\n }\n ctx.restore()\n }\n\n testHit(point: Point, viewport: Viewport): boolean {\n const f = this.frame(viewport)\n if (!f) {\n const [pa, pb] = this.anchorPixels(viewport)\n if (!pa || !pb) return false\n return point.x >= Math.min(pa.x, pb.x) && point.x <= Math.max(pa.x, pb.x) && Math.abs(point.y - pa.y) <= 24\n }\n const { seq, yAt } = this.sequence(f)\n let minY = Infinity\n let maxY = -Infinity\n for (const bar of seq) {\n minY = Math.min(minY, yAt(bar.h), yAt(bar.l))\n maxY = Math.max(maxY, yAt(bar.h), yAt(bar.l))\n }\n return point.x >= f.x1 - 4 && point.x <= f.x2 + 4 && point.y >= minY - 4 && point.y <= maxY + 4\n }\n}\n\n/**\n * Ghost feed: projected candles sketched from the first anchor toward the second — any\n * direction, including empty future space. One candle per bar slot; sizes come from the\n * average-span and variance inputs (auto-seeded from the trailing bars at placement); the\n * wobble is deterministic, so the same drawing always sketches the same candles.\n */\nexport class GhostFeed extends Drawing<GhostFeedProps> {\n readonly type = 'ghost_feed'\n\n protected override defaultProps(): GhostFeedProps {\n return {\n averageHL: 0,\n variance: 50,\n upColor: '#ACE5DC',\n downColor: '#FAA1A4',\n borderUpColor: '#089981',\n borderDownColor: '#F23645',\n wickColor: '#808080',\n drawBorder: true,\n drawWick: true,\n transparency: 50,\n }\n }\n\n requiredAnchors(): number {\n return 2\n }\n\n /** Placement hook: seed the average candle span from the trailing bars (only while auto). */\n capture(): void {\n if (this.props.averageHL > 0) return\n const recent = this.bars().slice(-20)\n if (!recent.length) return\n const avg = recent.reduce((sum, bar) => sum + Math.abs(bar.high - bar.low), 0) / recent.length\n if (avg > 0) this.applyProps({ averageHL: avg } as Partial<GhostFeedProps>)\n }\n\n /** Candle span in price units — the auto fallback keys off the anchor price. */\n private span(): number {\n if (this.props.averageHL > 0) return this.props.averageHL\n const price = Math.abs(this.anchors[0]?.price ?? 0)\n return price > 0 ? price * 0.005 : 1\n }\n\n paint(ctx: CanvasRenderingContext2D, viewport: Viewport): void {\n const [a, b] = this.anchors\n const [pa, pb] = this.anchorPixels(viewport)\n if (!a || !b || !pa || !pb) return\n const rawCount = viewport.barsBetween(a.time, b.time)\n const count = Math.max(1, Math.min(500, Math.round(Math.abs(rawCount ?? (pb.x - pa.x) / 8))))\n const width = (pb.x - pa.x) / count\n if (!Number.isFinite(width) || Math.abs(width) < 0.5) return\n const avg = this.span()\n const wobbleAmp = avg * (Math.max(0, this.props.variance) / 100)\n const alpha = Math.max(0, Math.min(1, 1 - this.props.transparency / 100))\n const drift = (b.price - a.price) / count\n const bodyW = Math.max(1.5, Math.min(9, Math.abs(width) * 0.6))\n let price = a.price\n ctx.save()\n ctx.setLineDash([])\n ctx.lineWidth = 1\n for (let i = 0; i < count; i++) {\n // Deterministic wobble seeded by the index (stable across repaints).\n const w1 = Math.sin(i * 2.399963)\n const w2 = Math.sin(i * 2.399963 + 1.7)\n const open = price\n const close = open + drift + w1 * wobbleAmp * 0.6\n const high = Math.max(open, close) + Math.abs(w2) * avg * 0.35\n const low = Math.min(open, close) - Math.abs(w1) * avg * 0.35\n const cx = pa.x + width * (i + 0.5)\n const ys = { o: viewport.yOf(open), h: viewport.yOf(high), l: viewport.yOf(low), c: viewport.yOf(close) }\n if (ys.o !== null && ys.h !== null && ys.l !== null && ys.c !== null) {\n const up = close >= open\n // The tool-wide opacity multiplies any alpha a color value carries of its own.\n const paint = (c: string) => withAlpha(c, alpha * alphaOf(c))\n if (this.props.drawWick) {\n ctx.strokeStyle = paint(this.props.wickColor)\n ctx.beginPath()\n ctx.moveTo(cx, ys.h)\n ctx.lineTo(cx, ys.l)\n ctx.stroke()\n }\n const top = Math.min(ys.o, ys.c)\n const bodyH = Math.max(1, Math.abs(ys.c - ys.o))\n ctx.fillStyle = paint(up ? this.props.upColor : this.props.downColor)\n ctx.fillRect(cx - bodyW / 2, top, bodyW, bodyH)\n if (this.props.drawBorder) {\n ctx.strokeStyle = paint(up ? this.props.borderUpColor : this.props.borderDownColor)\n ctx.strokeRect(cx - bodyW / 2, top, bodyW, bodyH)\n }\n }\n price = close\n }\n ctx.restore()\n }\n\n testHit(point: Point, viewport: Viewport): boolean {\n const [pa, pb] = this.anchorPixels(viewport)\n if (!pa || !pb) return false\n const minX = Math.min(pa.x, pb.x)\n const maxX = Math.max(pa.x, pb.x)\n const minY = Math.min(pa.y, pb.y) - 20\n const maxY = Math.max(pa.y, pb.y) + 20\n return point.x >= minX && point.x <= maxX && point.y >= minY && point.y <= maxY\n }\n}\n","import type { Time } from 'lightweight-charts'\n\nimport type { Point, Viewport } from '../core/types'\nimport { Drawing } from '../core/drawing'\nimport { barsInRange, volumeProfile } from '../core/bars'\nimport type { SourceBar } from '../core/bars'\nimport { distanceToSegment } from '../core/geometry'\nimport { alphaOf, applyStroke, dashPattern, paintLabel, withAlpha } from '../render/canvas'\n\nfunction hitTolerance(lineWidth: number): number {\n return Math.max(6, lineWidth / 2 + 4)\n}\n\n/** Bars from the anchor's time to the newest bar. */\nfunction barsFrom(all: readonly SourceBar[], from: Time): SourceBar[] {\n const start = Number(from)\n if (!Number.isFinite(start)) return []\n return all.filter((bar) => Number(bar.time) >= start)\n}\n\n/**\n * Anchored VWAP: the volume-weighted average price of every bar since the anchor, drawn as a\n * stepped line that extends live as bars arrive.\n */\nexport class AnchoredVwap extends Drawing {\n readonly type = 'anchored_vwap'\n\n requiredAnchors(): number {\n return 1\n }\n\n protected samples(viewport: Viewport): Point[] | null {\n const anchor = this.anchors[0]\n if (!anchor) return null\n const run = barsFrom(this.bars(), anchor.time)\n if (!run.length) return null\n let cumulativePV = 0\n let cumulativeVolume = 0\n const out: Point[] = []\n for (const bar of run) {\n const volume = bar.volume ?? 0\n const typical = (bar.high + bar.low + bar.close) / 3\n cumulativePV += typical * volume\n cumulativeVolume += volume\n if (cumulativeVolume <= 0) continue\n const x = viewport.xOf(bar.time)\n const y = viewport.yOf(cumulativePV / cumulativeVolume)\n if (x !== null && y !== null) out.push({ x, y })\n }\n return out.length >= 2 ? out : null\n }\n\n paint(ctx: CanvasRenderingContext2D, viewport: Viewport): void {\n const samples = this.samples(viewport)\n const anchor = this.anchors[0]\n const p = anchor ? this.anchorToPixel(anchor, viewport) : null\n if (p) {\n ctx.save()\n ctx.setLineDash([])\n ctx.fillStyle = this.style.lineColor\n ctx.beginPath()\n ctx.arc(p.x, p.y, 3.5, 0, Math.PI * 2)\n ctx.fill()\n ctx.restore()\n }\n if (!samples) {\n if (p) {\n paintLabel(ctx, 'VWAP needs volume data', { x: p.x + 8, y: p.y - 12 }, this.style, {\n background: withAlpha('#1b1f27', 0.92),\n })\n }\n return\n }\n applyStroke(ctx, this.style)\n ctx.beginPath()\n ctx.moveTo(samples[0].x, samples[0].y)\n for (let i = 1; i < samples.length; i++) ctx.lineTo(samples[i].x, samples[i].y)\n ctx.stroke()\n }\n\n testHit(point: Point, viewport: Viewport): boolean {\n const samples = this.samples(viewport)\n if (!samples) {\n const anchor = this.anchors[0]\n const p = anchor ? this.anchorToPixel(anchor, viewport) : null\n return !!p && Math.hypot(point.x - p.x, point.y - p.y) <= 10\n }\n const tolerance = hitTolerance(this.style.lineWidth)\n for (let i = 0; i < samples.length - 1; i++) {\n if (distanceToSegment(point, samples[i], samples[i + 1]) <= tolerance) return true\n }\n return false\n }\n}\n\nexport type ProfileProps = {\n /** 'number' sizes the histogram by total row count; 'ticks' by price ticks per row. */\n rowsLayout: 'number' | 'ticks'\n rowSize: number\n /** 'updown' splits each row by up/down bars, 'total' paints one bar, 'delta' their difference. */\n volume: 'updown' | 'total' | 'delta'\n /** Percentage of total volume the value area highlights (0 hides it). */\n valueAreaVolume: number\n upColor: string\n downColor: string\n valueAreaUpColor: string\n valueAreaDownColor: string\n /** Histogram width as a percentage of the range box. */\n widthPercent: number\n /** Which edge the histogram grows from. */\n placement: 'left' | 'right'\n pocVisible: boolean\n pocColor: string\n pocWidth: number\n pocStyle: 'solid' | 'dashed' | 'dotted'\n vahVisible: boolean\n vahColor: string\n vahWidth: number\n vahStyle: 'solid' | 'dashed' | 'dotted'\n valVisible: boolean\n valColor: string\n valWidth: number\n valStyle: 'solid' | 'dashed' | 'dotted'\n /** Running point-of-control / value-area polylines, computed bar by bar across the range. */\n developingPoc: boolean\n developingVa: boolean\n}\n\nconst PROFILE_PROPS: ProfileProps = {\n rowsLayout: 'number',\n rowSize: 24,\n volume: 'updown',\n valueAreaVolume: 70,\n upColor: '#089981',\n downColor: '#f23645',\n valueAreaUpColor: '#089981',\n valueAreaDownColor: '#f23645',\n widthPercent: 30,\n placement: 'left',\n pocVisible: true,\n pocColor: '#f23645',\n pocWidth: 2,\n pocStyle: 'solid',\n vahVisible: true,\n vahColor: '#787b86',\n vahWidth: 1,\n vahStyle: 'dashed',\n valVisible: true,\n valColor: '#787b86',\n valWidth: 1,\n valStyle: 'dashed',\n developingPoc: false,\n developingVa: false,\n}\n\n/**\n * Running POC/VAH/VAL per bar, computed incrementally over the range's fixed price extent —\n * one pass over the bars, O(rows) work per bar, so a 5k-bar range stays cheap. Sampled points\n * come back in price space; the caller maps them to pixels per paint.\n */\nfunction developingLevels(\n range: readonly SourceBar[],\n rows: number,\n vaShare: number,\n): { poc: { time: SourceBar['time']; price: number }[]; vah: { time: SourceBar['time']; price: number }[]; val: { time: SourceBar['time']; price: number }[] } | null {\n const withVolume = range.filter((b) => typeof b.volume === 'number' && b.volume > 0)\n if (withVolume.length < 2 || rows < 1) return null\n let min = Infinity\n let max = -Infinity\n for (const bar of withVolume) {\n min = Math.min(min, bar.low)\n max = Math.max(max, bar.high)\n }\n if (!(max > min)) return null\n const height = (max - min) / rows\n const bins = new Array<number>(rows).fill(0)\n const out = {\n poc: [] as { time: SourceBar['time']; price: number }[],\n vah: [] as { time: SourceBar['time']; price: number }[],\n val: [] as { time: SourceBar['time']; price: number }[],\n }\n let total = 0\n for (const bar of withVolume) {\n const lowBin = Math.max(0, Math.min(rows - 1, Math.floor((bar.low - min) / height)))\n const highBin = Math.max(0, Math.min(rows - 1, Math.floor((bar.high - min) / height)))\n const share = (bar.volume as number) / (highBin - lowBin + 1)\n for (let i = lowBin; i <= highBin; i++) bins[i] += share\n total += bar.volume as number\n let pocIndex = 0\n for (let i = 1; i < rows; i++) if (bins[i] > bins[pocIndex]) pocIndex = i\n out.poc.push({ time: bar.time, price: min + (pocIndex + 0.5) * height })\n if (vaShare > 0) {\n let low = pocIndex\n let high = pocIndex\n let covered = bins[pocIndex]\n while (covered < total * vaShare && (low > 0 || high < rows - 1)) {\n const below = low > 0 ? bins[low - 1] : -1\n const above = high < rows - 1 ? bins[high + 1] : -1\n if (above >= below) covered += bins[++high]\n else covered += bins[--low]\n }\n out.vah.push({ time: bar.time, price: min + (high + 1) * height })\n out.val.push({ time: bar.time, price: min + low * height })\n }\n }\n return out\n}\n\n/** Shared volume-by-price histogram body; subclasses define the bar range and the x-span. */\nabstract class VolumeProfileBase<P extends ProfileProps & Record<string, unknown>> extends Drawing<P> {\n protected abstract range(): SourceBar[]\n protected abstract span(viewport: Viewport): { x1: number; x2: number } | null\n\n protected rowCount(range: readonly SourceBar[]): number {\n const size = Math.max(1, this.props.rowSize)\n if (this.props.rowsLayout === 'ticks') {\n let min = Infinity\n let max = -Infinity\n for (const bar of range) {\n min = Math.min(min, bar.low)\n max = Math.max(max, bar.high)\n }\n if (!(max > min)) return 24\n // Tick rows need the symbol's tick; without one the profile keeps its default row count.\n const tick = this.tickSize()\n if (tick === null) return 24\n const rows = Math.ceil((max - min) / (tick * size))\n return Math.max(1, Math.min(400, rows))\n }\n return Math.max(1, Math.min(400, Math.round(size)))\n }\n\n paint(ctx: CanvasRenderingContext2D, viewport: Viewport): void {\n const span = this.span(viewport)\n if (!span) return\n const range = this.range()\n const bins = volumeProfile(range, this.rowCount(range))\n // The range frame. The profile has no generic stroke channel — frame, POC, and value-area\n // bounds paint in fixed chrome colors; the histogram colors are the tool's own props.\n ctx.save()\n ctx.strokeStyle = withAlpha('#787b86', 0.5)\n ctx.lineWidth = 1\n ctx.setLineDash([4, 4])\n ctx.strokeRect(span.x1, 0, span.x2 - span.x1, viewport.height)\n ctx.restore()\n if (!bins) {\n paintLabel(ctx, 'profile needs volume data', { x: (span.x1 + span.x2) / 2, y: 16 }, this.style, {\n align: 'center',\n background: withAlpha('#1b1f27', 0.92),\n })\n return\n }\n const maxVolume = Math.max(...bins.map((b) => b.volume))\n if (maxVolume <= 0) return\n const maxWidth = ((span.x2 - span.x1) * Math.max(5, Math.min(100, this.props.widthPercent))) / 100\n const fromRight = this.props.placement === 'right'\n const pocIndex = bins.reduce((best, bin, i) => (bin.volume > bins[best].volume ? i : best), 0)\n const poc = bins[pocIndex]\n\n // Value area: expand from the POC toward the heavier neighbor until it holds the target\n // share of total volume — the trading-profile convention.\n const vaShare = Math.max(0, Math.min(95, this.props.valueAreaVolume)) / 100\n const total = bins.reduce((s, b) => s + b.volume, 0)\n let low = pocIndex\n let high = pocIndex\n let covered = poc.volume\n while (vaShare > 0 && covered < total * vaShare && (low > 0 || high < bins.length - 1)) {\n const below = low > 0 ? bins[low - 1].volume : -1\n const above = high < bins.length - 1 ? bins[high + 1].volume : -1\n if (above >= below) {\n high++\n covered += bins[high].volume\n } else {\n low--\n covered += bins[low].volume\n }\n }\n\n ctx.save()\n ctx.setLineDash([])\n for (const [i, bin] of bins.entries()) {\n const y1 = viewport.yOf(bin.priceHigh)\n const y2 = viewport.yOf(bin.priceLow)\n if (y1 === null || y2 === null) continue\n const top = Math.min(y1, y2)\n const rowH = Math.max(1, Math.abs(y2 - y1) - 1)\n const inValueArea = vaShare > 0 && i >= low && i <= high\n // Structural dim outside the value area, multiplied by any alpha the color itself carries.\n const dim = inValueArea ? 0.8 : 0.3\n const upBase = inValueArea ? this.props.valueAreaUpColor : this.props.upColor\n const downBase = inValueArea ? this.props.valueAreaDownColor : this.props.downColor\n const upPaint = withAlpha(upBase, dim * alphaOf(upBase))\n const downPaint = withAlpha(downBase, dim * alphaOf(downBase))\n // Rows grow from the chosen edge; a right placement mirrors every rect.\n const rect = (offset: number, w: number) => {\n if (fromRight) ctx.fillRect(span.x2 - offset - w, top, w, rowH)\n else ctx.fillRect(span.x1 + offset, top, w, rowH)\n }\n if (this.props.volume === 'updown') {\n const upW = (bin.upVolume / maxVolume) * maxWidth\n const downW = (bin.downVolume / maxVolume) * maxWidth\n ctx.fillStyle = upPaint\n rect(0, upW)\n ctx.fillStyle = downPaint\n rect(upW, downW)\n } else if (this.props.volume === 'delta') {\n const delta = bin.upVolume - bin.downVolume\n ctx.fillStyle = delta >= 0 ? upPaint : downPaint\n rect(0, (Math.abs(delta) / maxVolume) * maxWidth)\n } else {\n ctx.fillStyle = upPaint\n rect(0, (bin.volume / maxVolume) * maxWidth)\n }\n }\n // Point of control across the whole range, plus the value-area bounds — each its own channel.\n const boundary = (y: number | null, visible: boolean, color: string, width: number, dash: 'solid' | 'dashed' | 'dotted') => {\n if (y === null || !visible) return\n ctx.strokeStyle = withAlpha(color, 0.9 * alphaOf(color))\n ctx.lineWidth = width\n ctx.setLineDash(dashPattern(dash, width))\n ctx.beginPath()\n ctx.moveTo(span.x1, y)\n ctx.lineTo(span.x2, y)\n ctx.stroke()\n }\n const p = this.props\n boundary(viewport.yOf((poc.priceLow + poc.priceHigh) / 2), p.pocVisible, p.pocColor, p.pocWidth, p.pocStyle)\n if (vaShare > 0) {\n boundary(viewport.yOf(bins[high].priceHigh), p.vahVisible, p.vahColor, p.vahWidth, p.vahStyle)\n boundary(viewport.yOf(bins[low].priceLow), p.valVisible, p.valColor, p.valWidth, p.valStyle)\n }\n // Developing lines: the running POC/VA walked bar by bar across the range.\n if (p.developingPoc || p.developingVa) {\n const levels = developingLevels(range, this.rowCount(range), vaShare)\n if (levels) {\n const polyline = (points: { time: SourceBar['time']; price: number }[], color: string) => {\n ctx.strokeStyle = withAlpha(color, 0.7 * alphaOf(color))\n ctx.lineWidth = 1\n ctx.setLineDash([2, 2])\n ctx.beginPath()\n let started = false\n for (const point of points) {\n const x = viewport.xOf(point.time)\n const y = viewport.yOf(point.price)\n if (x === null || y === null) continue\n if (started) ctx.lineTo(x, y)\n else ctx.moveTo(x, y)\n started = true\n }\n if (started) ctx.stroke()\n }\n if (p.developingPoc) polyline(levels.poc, p.pocColor)\n if (p.developingVa) {\n polyline(levels.vah, p.vahColor)\n polyline(levels.val, p.valColor)\n }\n }\n }\n ctx.restore()\n }\n\n testHit(point: Point, viewport: Viewport): boolean {\n const span = this.span(viewport)\n if (!span) return false\n return point.x >= span.x1 - 4 && point.x <= span.x2 + 4\n }\n}\n\nexport type FixedProfileProps = ProfileProps & {\n /** Keep building through every bar right of the range — new bars join the profile live. */\n extendRight: boolean\n}\n\n/** Volume-by-price histogram over the two anchors' time range, drawn inside the range box. */\nexport class FixedRangeVolumeProfile extends VolumeProfileBase<FixedProfileProps> {\n readonly type = 'fixed_range_volume_profile'\n\n protected override defaultProps(): FixedProfileProps {\n return { ...PROFILE_PROPS, extendRight: false }\n }\n\n requiredAnchors(): number {\n return 2\n }\n\n protected range(): SourceBar[] {\n const [a, b] = this.anchors\n if (!a || !b) return []\n if (this.props.extendRight) {\n return barsFrom(this.bars(), Number(a.time) <= Number(b.time) ? a.time : b.time)\n }\n return barsInRange(this.bars(), a.time, b.time)\n }\n\n protected span(viewport: Viewport): { x1: number; x2: number } | null {\n const [pa, pb] = this.anchorPixels(viewport)\n if (!pa || !pb) return null\n const x1 = Math.min(pa.x, pb.x)\n return { x1, x2: this.props.extendRight ? viewport.width : Math.max(pa.x, pb.x) }\n }\n}\n\n/** Volume profile from the anchor's time to the newest bar. */\nexport class AnchoredVolumeProfile extends VolumeProfileBase<ProfileProps> {\n readonly type = 'anchored_volume_profile'\n\n protected override defaultProps(): ProfileProps {\n return { ...PROFILE_PROPS }\n }\n\n requiredAnchors(): number {\n return 1\n }\n\n protected range(): SourceBar[] {\n const anchor = this.anchors[0]\n if (!anchor) return []\n return barsFrom(this.bars(), anchor.time)\n }\n\n protected span(viewport: Viewport): { x1: number; x2: number } | null {\n const anchor = this.anchors[0]\n if (!anchor) return null\n const x = viewport.xOf(anchor.time)\n if (x === null) return null\n return { x1: x, x2: viewport.width }\n }\n}\n","import type { Point, Viewport } from '../core/types'\nimport { Drawing } from '../core/drawing'\nimport { measureTextBlock, paintTextBlock, withAlpha } from '../render/canvas'\nimport { cachedImageBitmap, primeImageBitmap } from '../render/imageCache'\n\nfunction inBox(p: Point, box: { x: number; y: number; width: number; height: number }, pad = 3): boolean {\n return (\n p.x >= box.x - pad && p.x <= box.x + box.width + pad && p.y >= box.y - pad && p.y <= box.y + box.height + pad\n )\n}\n\nexport type ImageProps = {\n /** Data-URL payload (kept small by the host's picker); empty = placeholder frame. */\n dataUrl: string\n width: number\n /** 0..1 paint opacity. */\n opacity: number\n}\n\n/** A viewer's image pinned to a chart point (anchor = top-left). */\nexport class ImageNote extends Drawing<ImageProps> {\n readonly type = 'image'\n\n private _bitmap: HTMLImageElement | null = null\n private _loadedFrom = ''\n\n protected override defaultProps(): ImageProps {\n return { dataUrl: '', width: 160, opacity: 1 }\n }\n\n requiredAnchors(): number {\n return 1\n }\n\n protected frame(viewport: Viewport): { x: number; y: number; width: number; height: number } | null {\n const anchor = this.anchors[0]\n if (!anchor) return null\n const p = this.anchorToPixel(anchor, viewport)\n if (!p) return null\n const width = Math.max(24, this.props.width)\n const ratio = this._bitmap && this._bitmap.naturalWidth > 0 ? this._bitmap.naturalHeight / this._bitmap.naturalWidth : 0.66\n return { x: p.x, y: p.y, width, height: width * ratio }\n }\n\n private ensureBitmap(): void {\n const source = this.props.dataUrl\n if (!source || source === this._loadedFrom || typeof Image === 'undefined') return\n // Whoever chose this picture already decoded this exact payload to preview it, so the bitmap is\n // usually sitting in the cache and the first frame can paint it. Decoding it a second time here\n // is what made a placed image arrive a beat after the click that placed it.\n const warm = cachedImageBitmap(source)\n if (warm) {\n this._loadedFrom = source\n this._bitmap = warm\n return\n }\n this._loadedFrom = source\n const image = new Image()\n image.onload = () => {\n primeImageBitmap(source, image) // so a second drawing on the same picture pays nothing\n this._bitmap = image\n this.requestUpdate()\n }\n image.src = source\n }\n\n /** Four corners, so any of them can be grabbed. */\n override resizeHandles(viewport: Viewport): Point[] {\n if (!this.props.dataUrl) return []\n const f = this.frame(viewport)\n if (!f) return []\n return [\n { x: f.x, y: f.y },\n { x: f.x + f.width, y: f.y },\n { x: f.x, y: f.y + f.height },\n { x: f.x + f.width, y: f.y + f.height },\n ]\n }\n\n /** A corner drag scales the picture about its anchor, which is the top-left. Only WIDTH is stored —\n * height follows the bitmap's own ratio, so an image cannot be dragged out of proportion into\n * something that just looks broken. */\n override resizeTo(handleIndex: number, point: Point, viewport: Viewport): void {\n const anchor = this.anchors[0]\n if (!anchor) return\n const origin = this.anchorToPixel(anchor, viewport)\n if (!origin) return\n // Left-side handles are mirrored so dragging outward grows the image whichever corner is held.\n const dx = handleIndex === 0 || handleIndex === 2 ? origin.x - point.x : point.x - origin.x\n this.applyProps({ width: Math.max(24, Math.round(dx)) })\n }\n\n paint(ctx: CanvasRenderingContext2D, viewport: Viewport): void {\n this.ensureBitmap()\n const f = this.frame(viewport)\n if (!f) return\n if (this._bitmap && this.props.dataUrl) {\n ctx.save()\n ctx.globalAlpha = Math.max(0, Math.min(1, this.props.opacity))\n ctx.drawImage(this._bitmap, f.x, f.y, f.width, f.height)\n ctx.restore()\n if (this.state === 'selected' || this.state === 'editing') {\n ctx.save()\n ctx.strokeStyle = this.style.lineColor\n ctx.lineWidth = 1\n ctx.setLineDash([])\n ctx.strokeRect(f.x, f.y, f.width, f.height)\n ctx.restore()\n }\n return\n }\n // Placeholder until an image is chosen in settings.\n ctx.save()\n ctx.setLineDash([4, 4])\n ctx.strokeStyle = this.style.lineColor\n ctx.lineWidth = 1\n ctx.strokeRect(f.x, f.y, f.width, f.height)\n ctx.setLineDash([])\n ctx.font = '11px ui-sans-serif, system-ui, sans-serif'\n ctx.fillStyle = this.style.lineColor\n ctx.textAlign = 'center'\n ctx.textBaseline = 'middle'\n ctx.fillText('image: pick in settings', f.x + f.width / 2, f.y + f.height / 2)\n ctx.restore()\n }\n\n testHit(point: Point, viewport: Viewport): boolean {\n const f = this.frame(viewport)\n return !!f && inBox(point, f)\n }\n}\n\nexport type ContentCardProps = {\n text: string\n url: string\n}\n\n/** Quote/link card: body text with the source URL as its footer. */\nexport class ContentCard extends Drawing<ContentCardProps> {\n readonly type = 'content_card'\n\n protected override defaultProps(): ContentCardProps {\n return { text: '', url: '' }\n }\n\n requiredAnchors(): number {\n return 1\n }\n\n protected body(): string {\n const text = this.props.text || ' '\n return this.props.url ? `${text}\\n${this.props.url}` : text\n }\n\n protected box(viewport: Viewport): { x: number; y: number; width: number; height: number } | null {\n const anchor = this.anchors[0]\n if (!anchor) return null\n const p = this.anchorToPixel(anchor, viewport)\n if (!p) return null\n const { width, height } = measureTextBlock(this.body(), this.style)\n return { x: p.x, y: p.y, width: Math.max(140, width + 16), height: height + 16 }\n }\n\n paint(ctx: CanvasRenderingContext2D, viewport: Viewport): void {\n const anchor = this.anchors[0]\n if (!anchor) return\n const p = this.anchorToPixel(anchor, viewport)\n if (!p) return\n paintTextBlock(ctx, this.body(), p, this.style, {\n background: withAlpha('#1b1f27', 0.95),\n borderColor: this.style.lineColor,\n padding: 8,\n })\n }\n\n testHit(point: Point, viewport: Viewport): boolean {\n const box = this.box(viewport)\n return !!box && inBox(point, box)\n }\n}\n\nexport type GlyphProps = {\n /** The rendered character(s) — an emoji, sticker glyph, or symbol. */\n glyph: string\n size: number\n}\n\n/** Decoded artwork, keyed by URL. The cache is shared across instances on purpose: it is keyed\n * by the URL a source produced, so two charts pointing at the same asset set reuse one decode\n * and two pointing at different ones cannot collide. */\nconst glyphImages = new Map<string, HTMLImageElement | 'loading' | 'failed'>()\n\n/** Shared body of the emoji/sticker/icon tools: one glyph rendered at a point. */\nexport class GlyphMark extends Drawing<GlyphProps> {\n readonly type: string = 'emoji'\n\n protected override defaultProps(): GlyphProps {\n return { glyph: '😀', size: 28 }\n }\n\n requiredAnchors(): number {\n return 1\n }\n\n protected radius(): number {\n return Math.max(10, this.props.size) / 2 + 4\n }\n\n /** Icon marks tint with the stroke color; emoji/sticker marks carry their own artwork. */\n protected tintsWithStroke(): boolean {\n return false\n }\n\n private glyphImage(): HTMLImageElement | null {\n if (this.tintsWithStroke() || typeof Image === 'undefined') return null\n const url = this.glyphUrl(this.props.glyph)\n if (!url) return null\n const cached = glyphImages.get(url)\n if (cached instanceof HTMLImageElement) return cached\n if (cached === undefined) {\n glyphImages.set(url, 'loading')\n const image = new Image()\n image.onload = () => {\n glyphImages.set(url, image)\n this.requestUpdate()\n }\n image.onerror = () => glyphImages.set(url, 'failed')\n image.src = url\n }\n return null\n }\n\n paint(ctx: CanvasRenderingContext2D, viewport: Viewport): void {\n const anchor = this.anchors[0]\n if (!anchor) return\n const p = this.anchorToPixel(anchor, viewport)\n if (!p) return\n const size = Math.max(10, this.props.size)\n const image = this.glyphImage()\n if (image) {\n ctx.drawImage(image, p.x - size / 2, p.y - size / 2, size, size)\n return\n }\n ctx.save()\n ctx.font = `${size}px ui-sans-serif, system-ui, sans-serif`\n ctx.textAlign = 'center'\n ctx.textBaseline = 'middle'\n // Icons render in the drawing hue; emoji/stickers carry their own colors.\n ctx.fillStyle = this.style.lineColor\n ctx.fillText(this.props.glyph || '?', p.x, p.y)\n ctx.restore()\n }\n\n /** Scale grips at the glyph's bounding-box corners. */\n override resizeHandles(viewport: Viewport): Point[] {\n const anchor = this.anchors[0]\n if (!anchor) return []\n const p = this.anchorToPixel(anchor, viewport)\n if (!p) return []\n const r = this.radius()\n return [\n { x: p.x - r, y: p.y - r },\n { x: p.x + r, y: p.y - r },\n { x: p.x + r, y: p.y + r },\n { x: p.x - r, y: p.y + r },\n ]\n }\n\n override resizeTo(_handleIndex: number, point: Point, viewport: Viewport): void {\n const anchor = this.anchors[0]\n if (!anchor) return\n const p = this.anchorToPixel(anchor, viewport)\n if (!p) return\n const r = Math.max(Math.abs(point.x - p.x), Math.abs(point.y - p.y))\n this.applyProps({ size: Math.max(10, Math.min(160, Math.round((r - 4) * 2))) } as Partial<GlyphProps>)\n }\n\n testHit(point: Point, viewport: Viewport): boolean {\n const anchor = this.anchors[0]\n if (!anchor) return false\n const p = this.anchorToPixel(anchor, viewport)\n if (!p) return false\n const r = this.radius()\n return Math.abs(point.x - p.x) <= r && Math.abs(point.y - p.y) <= r\n }\n}\n\nexport class StickerMark extends GlyphMark {\n override readonly type = 'sticker'\n\n protected override defaultProps(): GlyphProps {\n return { glyph: '👍', size: 44 }\n }\n}\n\nexport class IconMark extends GlyphMark {\n override readonly type = 'icon'\n\n protected override defaultProps(): GlyphProps {\n return { glyph: '★', size: 24 }\n }\n\n protected override tintsWithStroke(): boolean {\n return true\n }\n}\n","import type { Anchor, DrawingOptions, DrawingStyle, SerializedDrawing, ToolCategory } from './core/types'\nimport type { AnyDrawing, Drawing } from './core/drawing'\n\nimport {\n Arrow,\n CrossLine,\n ExtendedLine,\n HorizontalLine,\n HorizontalRay,\n InfoLine,\n Ray,\n TrendAngle,\n TrendLine,\n VerticalLine,\n} from './tools/lines'\nimport {\n Arc,\n Circle,\n Curve,\n DoubleCurve,\n Ellipse,\n Rectangle,\n RotatedRectangle,\n Triangle,\n} from './tools/shapes'\nimport {\n ArrowMarkDown,\n ArrowMarkUp,\n Callout,\n Comment,\n FlagMark,\n Note,\n PriceLabel,\n TextLabel,\n} from './tools/annotations'\nimport { DatePriceRange, DateRange, Measure, PriceRange } from './tools/measurement'\nimport { DisjointChannel, FlatTopBottom, ParallelChannel } from './tools/channels'\nimport { InsidePitchfork, ModifiedSchiffPitchfork, Pitchfork, SchiffPitchfork } from './tools/pitchforks'\nimport {\n FibArcs,\n FibChannel,\n FibCircles,\n FibExtension,\n FibRetracement,\n FibSpeedFan,\n FibSpiral,\n FibTimeExtension,\n FibTimeZone,\n FibWedge,\n Pitchfan,\n} from './tools/fibonacci'\nimport { GannBox, GannFan, GannSquare, GannSquareFixed } from './tools/gann'\nimport { Forecast, LongPosition, Sector, ShortPosition } from './tools/forecasting'\nimport { Brush, Highlighter, PathLine, Polyline } from './tools/freehand'\nimport { ArrowMarker, Pin, PriceNote, Signpost } from './tools/annotations'\nimport { TableNote } from './tools/table'\nimport { AbcdPattern, CypherPattern, HeadAndShoulders, ThreeDrivesPattern, TrianglePattern, XabcdPattern } from './tools/patterns'\nimport {\n ElliottCorrection,\n ElliottDoubleCombo,\n ElliottImpulse,\n ElliottTriangle,\n ElliottTripleCombo,\n} from './tools/elliott'\nimport { CyclicLines, SineLine, TimeCycles } from './tools/cycles'\nimport { BarsPattern, GhostFeed, RegressionTrend } from './tools/bars'\nimport { AnchoredVolumeProfile, AnchoredVwap, FixedRangeVolumeProfile } from './tools/volume'\nimport { ContentCard, GlyphMark, IconMark, ImageNote, StickerMark } from './tools/content'\n\nexport interface ToolDefinition {\n type: string\n name: string\n category: ToolCategory\n /** Anchor count that completes placement. */\n anchors: number\n /** Default style overrides for new drawings of this tool (e.g. a highlighter's fill). */\n style?: Partial<DrawingStyle>\n /** Tool renders the viewer's text — the host opens its text editor right after placement. */\n hasText?: boolean\n /** How anchors are gathered: drag-captured stroke, or click-to-add points (double-click ends).\n * Omitted = the fixed `anchors` count. */\n placement?: 'freehand' | 'multipoint' | 'instant'\n /** Tool snapshots the bars between its anchors when placement completes (the host triggers\n * the drawing's `capture()`). */\n capturesBars?: boolean\n create(\n id: string,\n anchors?: Anchor[],\n style?: Partial<DrawingStyle>,\n options?: Partial<DrawingOptions>,\n props?: Record<string, unknown>,\n ): AnyDrawing\n}\n\ninterface ToolMeta {\n type: string\n name: string\n category: ToolCategory\n anchors: number\n style?: Partial<DrawingStyle>\n hasText?: boolean\n placement?: 'freehand' | 'multipoint' | 'instant'\n capturesBars?: boolean\n}\n\n/** Bind a tool class to its metadata (typed props cast happens exactly once, here). */\nfunction tool<P extends Record<string, unknown>>(\n Ctor: new (\n id: string,\n anchors?: Anchor[],\n style?: Partial<DrawingStyle>,\n options?: Partial<DrawingOptions>,\n props?: Partial<P>,\n ) => Drawing<P>,\n meta: ToolMeta,\n): ToolDefinition {\n return {\n ...meta,\n create: (id, anchors, style, options, props) =>\n new Ctor(id, anchors, style, options, props as Partial<P> | undefined) as AnyDrawing,\n }\n}\n\n/** Display order of categories in the drawing toolbar. */\nexport const TOOL_CATEGORIES: readonly ToolCategory[] = [\n 'lines',\n 'channels',\n 'pitchforks',\n 'fibonacci',\n 'gann',\n 'patterns',\n 'elliott',\n 'cycles',\n 'forecasting',\n 'volume',\n 'measurement',\n 'shapes',\n 'annotation',\n 'content',\n]\n\nconst DEFINITIONS: ToolDefinition[] = [\n // Lines\n tool(TrendLine, { type: 'trend_line', name: 'Trend line', category: 'lines', anchors: 2 }),\n tool(Ray, { type: 'ray', name: 'Ray', category: 'lines', anchors: 2 }),\n tool(InfoLine, { type: 'info_line', name: 'Info line', category: 'lines', anchors: 2 }),\n tool(ExtendedLine, { type: 'extended', name: 'Extended line', category: 'lines', anchors: 2 }),\n tool(TrendAngle, { type: 'trend_angle', name: 'Trend angle', category: 'lines', anchors: 2 }),\n tool(HorizontalLine, { type: 'horizontal_line', name: 'Horizontal line', category: 'lines', anchors: 1 }),\n tool(HorizontalRay, { type: 'horizontal_ray', name: 'Horizontal ray', category: 'lines', anchors: 1 }),\n tool(VerticalLine, { type: 'vertical_line', name: 'Vertical line', category: 'lines', anchors: 1 }),\n tool(CrossLine, { type: 'cross_line', name: 'Cross line', category: 'lines', anchors: 1 }),\n tool(Arrow, { type: 'arrow', name: 'Arrow', category: 'lines', anchors: 2 }),\n\n // Shapes\n tool(Rectangle, { type: 'rectangle', name: 'Rectangle', category: 'shapes', anchors: 2 }),\n tool(RotatedRectangle, { type: 'rotated_rectangle', name: 'Rotated rectangle', category: 'shapes', anchors: 3 }),\n tool(Ellipse, { type: 'ellipse', name: 'Ellipse', category: 'shapes', anchors: 3 }),\n tool(Circle, { type: 'circle', name: 'Circle', category: 'shapes', anchors: 2 }),\n tool(Triangle, { type: 'triangle', name: 'Triangle', category: 'shapes', anchors: 3 }),\n tool(Arc, { type: 'arc', name: 'Arc', category: 'shapes', anchors: 3 }),\n tool(Curve, { type: 'curve', name: 'Curve', category: 'shapes', anchors: 3 }),\n tool(DoubleCurve, { type: 'double_curve', name: 'Double curve', category: 'shapes', anchors: 4 }),\n\n // Channels\n tool(RegressionTrend, { type: 'regression_trend', name: 'Regression trend', category: 'channels', anchors: 2 }),\n tool(ParallelChannel, { type: 'parallel_channel', name: 'Parallel channel', category: 'channels', anchors: 3, style: { fillOpacity: 0.08 } }),\n tool(FlatTopBottom, { type: 'flat_top_bottom', name: 'Flat top/bottom', category: 'channels', anchors: 3, style: { fillOpacity: 0.08 } }),\n tool(DisjointChannel, { type: 'disjoint_channel', name: 'Disjoint channel', category: 'channels', anchors: 4, style: { fillOpacity: 0.08 } }),\n\n // Fibonacci\n tool(FibRetracement, { type: 'fib_retracement', name: 'Fib retracement', category: 'fibonacci', anchors: 2 }),\n tool(FibExtension, { type: 'fib_trend_ext', name: 'Trend-based fib extension', category: 'fibonacci', anchors: 3 }),\n tool(FibChannel, { type: 'fib_channel', name: 'Fib channel', category: 'fibonacci', anchors: 3 }),\n tool(FibTimeZone, { type: 'fib_timezone', name: 'Fib time zone', category: 'fibonacci', anchors: 2 }),\n tool(FibSpeedFan, { type: 'fib_speed_resist_fan', name: 'Fib speed resistance fan', category: 'fibonacci', anchors: 2 }),\n tool(FibTimeExtension, { type: 'fib_trend_time', name: 'Trend-based fib time', category: 'fibonacci', anchors: 3 }),\n tool(FibCircles, { type: 'fib_circles', name: 'Fib circles', category: 'fibonacci', anchors: 2 }),\n tool(FibSpiral, { type: 'fib_spiral', name: 'Fib spiral', category: 'fibonacci', anchors: 2 }),\n tool(FibArcs, { type: 'fib_speed_resist_arcs', name: 'Fib speed resistance arcs', category: 'fibonacci', anchors: 2 }),\n tool(FibWedge, { type: 'fib_wedge', name: 'Fib wedge', category: 'fibonacci', anchors: 3 }),\n tool(Pitchfan, { type: 'pitchfan', name: 'Pitchfan', category: 'fibonacci', anchors: 3 }),\n\n // Pitchforks\n tool(Pitchfork, { type: 'pitchfork', name: 'Pitchfork', category: 'pitchforks', anchors: 3 }),\n tool(SchiffPitchfork, { type: 'schiff_pitchfork', name: 'Schiff pitchfork', category: 'pitchforks', anchors: 3 }),\n tool(ModifiedSchiffPitchfork, { type: 'schiff_pitchfork_modified', name: 'Modified Schiff pitchfork', category: 'pitchforks', anchors: 3 }),\n tool(InsidePitchfork, { type: 'inside_pitchfork', name: 'Inside pitchfork', category: 'pitchforks', anchors: 3 }),\n\n // Gann\n tool(GannBox, { type: 'gannbox', name: 'Gann box', category: 'gann', anchors: 2 }),\n tool(GannSquare, { type: 'gannbox_square', name: 'Gann square', category: 'gann', anchors: 2 }),\n tool(GannSquareFixed, { type: 'gannbox_fixed', name: 'Gann square fixed', category: 'gann', anchors: 2 }),\n tool(GannFan, { type: 'gannbox_fan', name: 'Gann fan', category: 'gann', anchors: 2 }),\n\n // Patterns\n tool(XabcdPattern, { type: 'xabcd_pattern', name: 'XABCD pattern', category: 'patterns', anchors: 5, style: { fillOpacity: 0.12 } }),\n tool(CypherPattern, { type: 'cypher_pattern', name: 'Cypher pattern', category: 'patterns', anchors: 5, style: { fillOpacity: 0.12 } }),\n tool(AbcdPattern, { type: 'abcd_pattern', name: 'ABCD pattern', category: 'patterns', anchors: 4 }),\n tool(ThreeDrivesPattern, { type: 'three_drives', name: 'Three drives pattern', category: 'patterns', anchors: 6 }),\n tool(TrianglePattern, { type: 'triangle_pattern', name: 'Triangle pattern', category: 'patterns', anchors: 4, style: { fillOpacity: 0.12 } }),\n tool(HeadAndShoulders, { type: 'head_and_shoulders', name: 'Head and shoulders', category: 'patterns', anchors: 7, style: { fillOpacity: 0.12 } }),\n\n // Elliott waves\n tool(ElliottImpulse, { type: 'elliott_impulse_wave', name: 'Elliott impulse (12345)', category: 'elliott', anchors: 6 }),\n tool(ElliottCorrection, { type: 'elliott_correction', name: 'Elliott correction (ABC)', category: 'elliott', anchors: 4 }),\n tool(ElliottTriangle, { type: 'elliott_triangle_wave', name: 'Elliott triangle (ABCDE)', category: 'elliott', anchors: 6 }),\n tool(ElliottDoubleCombo, { type: 'elliott_double_combo', name: 'Elliott double combo (WXY)', category: 'elliott', anchors: 4 }),\n tool(ElliottTripleCombo, { type: 'elliott_triple_combo', name: 'Elliott triple combo (WXYXZ)', category: 'elliott', anchors: 6 }),\n\n // Cycles\n tool(CyclicLines, { type: 'cyclic_lines', name: 'Cyclic lines', category: 'cycles', anchors: 2 }),\n tool(TimeCycles, { type: 'time_cycles', name: 'Time cycles', category: 'cycles', anchors: 2, style: { fillOpacity: 0.12 } }),\n tool(SineLine, { type: 'sine_line', name: 'Sine line', category: 'cycles', anchors: 2 }),\n\n // Forecasting & positions\n tool(LongPosition, { type: 'long_position', name: 'Long position', category: 'forecasting', anchors: 3, placement: 'instant', style: { textColor: '#ffffff' } }),\n tool(ShortPosition, { type: 'short_position', name: 'Short position', category: 'forecasting', anchors: 3, placement: 'instant', style: { textColor: '#ffffff' } }),\n tool(Forecast, { type: 'forecast', name: 'Position forecast', category: 'forecasting', anchors: 2 }),\n tool(Sector, { type: 'sector', name: 'Sector', category: 'forecasting', anchors: 3, style: { fillOpacity: 0.2 } }),\n tool(BarsPattern, { type: 'bars_pattern', name: 'Bars pattern', category: 'forecasting', anchors: 2, capturesBars: true }),\n tool(GhostFeed, { type: 'ghost_feed', name: 'Ghost feed', category: 'forecasting', anchors: 2, capturesBars: true }),\n\n // Volume\n tool(AnchoredVwap, { type: 'anchored_vwap', name: 'Anchored VWAP', category: 'volume', anchors: 1 }),\n tool(FixedRangeVolumeProfile, { type: 'fixed_range_volume_profile', name: 'Fixed range volume profile', category: 'volume', anchors: 2 }),\n tool(AnchoredVolumeProfile, { type: 'anchored_volume_profile', name: 'Anchored volume profile', category: 'volume', anchors: 1 }),\n\n // Content\n tool(ImageNote, { type: 'image', name: 'Image', category: 'content', anchors: 1 }),\n tool(ContentCard, { type: 'content_card', name: 'Content card', category: 'content', anchors: 1, hasText: true }),\n tool(GlyphMark, { type: 'emoji', name: 'Emoji', category: 'content', anchors: 1 }),\n tool(StickerMark, { type: 'sticker', name: 'Sticker', category: 'content', anchors: 1 }),\n tool(IconMark, { type: 'icon', name: 'Icon', category: 'content', anchors: 1 }),\n\n // Annotation\n tool(TextLabel, { type: 'text', name: 'Text', category: 'annotation', anchors: 1, hasText: true }),\n tool(Note, { type: 'note', name: 'Note', category: 'annotation', anchors: 1, hasText: true, style: { fillColor: '#1b1f27', fillOpacity: 0.95 } }),\n tool(Comment, { type: 'comment', name: 'Comment', category: 'annotation', anchors: 1, hasText: true, style: { fillColor: '#1b1f27', fillOpacity: 0.95 } }),\n tool(Callout, { type: 'callout', name: 'Callout', category: 'annotation', anchors: 2, hasText: true, style: { fillColor: '#1b1f27', fillOpacity: 0.95 } }),\n tool(PriceLabel, { type: 'price_label', name: 'Price label', category: 'annotation', anchors: 1 }),\n tool(ArrowMarkUp, { type: 'arrow_up', name: 'Arrow mark up', category: 'annotation', anchors: 1 }),\n tool(ArrowMarkDown, { type: 'arrow_down', name: 'Arrow mark down', category: 'annotation', anchors: 1 }),\n tool(ArrowMarker, { type: 'arrow_marker', name: 'Arrow marker', category: 'annotation', anchors: 2 }),\n tool(FlagMark, { type: 'flag', name: 'Flag mark', category: 'annotation', anchors: 1 }),\n tool(PriceNote, { type: 'price_note', name: 'Price note', category: 'annotation', anchors: 2, hasText: true }),\n tool(Pin, { type: 'pin', name: 'Pin', category: 'annotation', anchors: 1, hasText: true }),\n tool(Signpost, { type: 'signpost', name: 'Signpost', category: 'annotation', anchors: 1, hasText: true }),\n tool(TableNote, { type: 'table', name: 'Table', category: 'annotation', anchors: 1, style: { fillColor: '#1b1f27', fillOpacity: 0.95 } }),\n\n // Brushes & multi-point shapes\n tool(Brush, { type: 'brush', name: 'Brush', category: 'shapes', anchors: 2, placement: 'freehand' }),\n tool(Highlighter, { type: 'highlighter', name: 'Highlighter', category: 'shapes', anchors: 2, placement: 'freehand', style: { lineColor: 'rgba(245, 166, 35, 0.35)', lineWidth: 20 } }),\n tool(PathLine, { type: 'path', name: 'Path', category: 'shapes', anchors: 2, placement: 'multipoint' }),\n tool(Polyline, { type: 'polyline', name: 'Polyline', category: 'shapes', anchors: 2, placement: 'multipoint', style: { fillOpacity: 0.1 } }),\n\n // Measurement\n tool(PriceRange, { type: 'price_range', name: 'Price range', category: 'measurement', anchors: 2 }),\n tool(DateRange, { type: 'date_range', name: 'Date range', category: 'measurement', anchors: 2 }),\n tool(DatePriceRange, { type: 'date_and_price_range', name: 'Date and price range', category: 'measurement', anchors: 2 }),\n tool(Measure, { type: 'measure', name: 'Measure', category: 'measurement', anchors: 2 }),\n]\n\n/**\n * The tool registry: type → metadata + factory. The toolbar lists it, placement creates through\n * it, and persistence restores through it.\n */\nexport class ToolRegistry {\n private readonly _tools = new Map<string, ToolDefinition>()\n\n constructor(definitions: readonly ToolDefinition[]) {\n for (const definition of definitions) this._tools.set(definition.type, definition)\n }\n\n register(definition: ToolDefinition): void {\n this._tools.set(definition.type, definition)\n }\n\n get(type: string): ToolDefinition | undefined {\n return this._tools.get(type)\n }\n\n has(type: string): boolean {\n return this._tools.has(type)\n }\n\n all(): ToolDefinition[] {\n return Array.from(this._tools.values())\n }\n\n byCategory(category: ToolCategory): ToolDefinition[] {\n return this.all().filter((t) => t.category === category)\n }\n\n /** New drawing with the tool's default style under the given overrides. */\n create(\n type: string,\n id: string,\n anchors: Anchor[],\n styleOverrides?: Partial<DrawingStyle>,\n ): AnyDrawing | null {\n const definition = this._tools.get(type)\n if (!definition) return null\n return definition.create(id, anchors, { ...definition.style, ...styleOverrides })\n }\n\n /** Rebuild a drawing from its serialized form; null for unknown types or malformed data. */\n restore(data: SerializedDrawing): AnyDrawing | null {\n const definition = this._tools.get(data.type)\n if (!definition || !Array.isArray(data.anchors)) return null\n try {\n return definition.create(data.id, data.anchors, data.style, data.options, data.props)\n } catch {\n return null\n }\n }\n}\n\nexport const toolRegistry = new ToolRegistry(DEFINITIONS)\n","// The persisted drawings STORE codec: one JSON document per surface holding every symbol's\n// serialized drawings — `{ [symbol]: SerializedDrawing[] }`. This codec is the cross-surface\n// compatibility contract: every host that persists drawings through it, the widget among them,\n// reads a store any other wrote, so a saved store survives a move between hosts. Keep it boring\n// and total: parsing tolerates anything (malformed JSON, a\n// non-object root, a junk bucket → the empty store / a dropped bucket, never a throw), and\n// serializing drops empty buckets so a store never accumulates dead symbol keys.\nimport { toolRegistry } from './registry'\nimport type { SerializedDrawing } from './core/types'\nimport type { AnyDrawing } from './core/drawing'\n\n/** Parse a persisted store document. Total: malformed input is an EMPTY store, a non-array or\n * empty bucket is dropped — a corrupt corner of the document never takes the healthy rest down. */\nexport function parseDrawingsStore(raw: string | null | undefined): Record<string, SerializedDrawing[]> {\n try {\n const parsed: unknown = JSON.parse(raw ?? 'null')\n if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) return {}\n const out: Record<string, SerializedDrawing[]> = {}\n for (const [sym, bucket] of Object.entries(parsed as Record<string, unknown>)) {\n if (Array.isArray(bucket) && bucket.length > 0) out[sym] = bucket as SerializedDrawing[]\n }\n return out\n } catch {\n return {}\n }\n}\n\n/** Serialize a store document, dropping empty buckets. The inverse of {@link parseDrawingsStore}\n * for every well-formed store: parse(serialize(m)) deep-equals m minus empty buckets. */\nexport function serializeDrawingsStore(map: Record<string, readonly SerializedDrawing[]>): string {\n const out: Record<string, readonly SerializedDrawing[]> = {}\n for (const [sym, bucket] of Object.entries(map)) {\n if (Array.isArray(bucket) && bucket.length > 0) out[sym] = bucket\n }\n return JSON.stringify(out)\n}\n\n/** Rebuild live drawings from one symbol's serialized bucket through the tool registry. A row the\n * registry cannot restore (an unknown type, malformed anchors) is skipped, never a throw — the\n * rest of the bucket still loads. */\nexport function restoreDrawings(list: readonly SerializedDrawing[]): AnyDrawing[] {\n const out: AnyDrawing[] = []\n for (const d of list) {\n const obj = toolRegistry.restore(d)\n if (obj) out.push(obj)\n }\n return out\n}\n","// The public view of the drawing tool catalog.\n//\n// The internal seam registers its 90 tools in one mutable registry whose entries carry a factory\n// that builds a live drawing object. Neither the mutability nor the factory belongs on a public\n// surface: a consumer reads the catalog to build a picker and restores drawings through the codec,\n// and the drawing classes themselves are implementation. So this module publishes a READ-ONLY view\n// over the registry and a `DrawingTool` shape that stops at metadata.\n//\n// There is deliberately no host registration door. A host-authored tool would need the seam's\n// `Drawing` base class, which is not public, and host tool contribution belongs behind the\n// access-policy plane rather than a bare `register`. Publishing a door nobody can walk through is\n// the kind of dead API this sprint deletes.\nimport { toolRegistry, TOOL_CATEGORIES, type ToolCategory, type SerializedDrawing, type IDrawing, type Anchor, type DrawingStyle } from '../internal/drawings/index'\n\nexport { TOOL_CATEGORIES }\n\n/** How a tool gathers the anchors that complete a placement. Absent means the fixed `anchors`\n * count: the host collects exactly that many points. */\nexport type DrawingPlacement = 'freehand' | 'multipoint' | 'instant'\n\n/** One tool in the catalog, as a consumer reads it: identity, grouping, and the facts a picker or\n * a placement loop needs. The factory that builds the drawing stays inside the library. */\nexport interface DrawingTool {\n /** The stable id a serialized drawing carries and a preference is keyed by. */\n readonly type: string\n /** The English fallback name. Localized display goes through `toolName` on the root entrypoint. */\n readonly name: string\n readonly category: ToolCategory\n /** Anchor count that completes placement when `placement` is absent. */\n readonly anchors: number\n /** Style overrides every new drawing of this tool starts with. */\n readonly style?: Partial<DrawingStyle>\n /** The tool renders the viewer's text, so a host opens its text editor once placement completes. */\n readonly hasText?: boolean\n readonly placement?: DrawingPlacement\n /** The tool snapshots the bars between its anchors when placement completes. */\n readonly capturesBars?: boolean\n}\n\nconst readOnly = (definition: {\n type: string\n name: string\n category: ToolCategory\n anchors: number\n style?: Partial<DrawingStyle>\n hasText?: boolean\n placement?: DrawingPlacement\n capturesBars?: boolean\n}): DrawingTool => Object.freeze({ ...definition })\n\n/** The catalog: read access to the registered tools, plus the two constructors persistence needs.\n * Nothing here mutates the catalog. */\nexport interface DrawingToolCatalog {\n /** One tool by type, or undefined when nothing is registered under it. */\n get(type: string): DrawingTool | undefined\n has(type: string): boolean\n /** Every registered tool, in registration order. */\n all(): DrawingTool[]\n /** The tools of one category, in registration order. */\n byCategory(category: ToolCategory): DrawingTool[]\n /** A new drawing of `type` at `anchors`, under the tool's default style and the given overrides.\n * Null when the type is not registered. */\n create(type: string, id: string, anchors: Anchor[], style?: Partial<DrawingStyle>): IDrawing | null\n /** One serialized drawing rebuilt, or null for an unknown type or malformed data. */\n restore(data: SerializedDrawing): IDrawing | null\n}\n\nconst catalog: DrawingToolCatalog = {\n get(type) {\n const definition = toolRegistry.get(type)\n return definition ? readOnly(definition) : undefined\n },\n has(type) {\n return toolRegistry.has(type)\n },\n all() {\n return toolRegistry.all().map(readOnly)\n },\n byCategory(category) {\n return toolRegistry.byCategory(category).map(readOnly)\n },\n create(type, id, anchors, style) {\n return toolRegistry.create(type, id, anchors, style)\n },\n restore(data) {\n return toolRegistry.restore(data)\n },\n}\n\n/** The library's tool catalog. Frozen: the view itself cannot be extended with a registration door\n * at runtime either. */\nexport const drawingTools: DrawingToolCatalog = Object.freeze(catalog)\n","// The drawings STORE codec, as a consumer meets it.\n//\n// One JSON document per surface holding every symbol's serialized drawings. The codec is total in\n// both directions: parsing tolerates anything (malformed JSON, a non-object root, a junk bucket\n// reads as the empty store or a dropped bucket, never a throw) and serializing drops empty buckets\n// so a document never accumulates dead symbol keys. That is what lets a host hand the chart\n// whatever a backend returned without guarding it first.\n//\n// `restoreDrawings` is wrapped rather than re-exported so its result is typed as the public\n// `IDrawing`, not the library's internal drawing class.\nimport {\n parseDrawingsStore as parseStore,\n restoreDrawings as restoreAll,\n serializeDrawingsStore as serializeStore,\n type IDrawing,\n type SerializedDrawing,\n} from '../internal/drawings/index'\n\nexport { parseStore as parseDrawingsStore, serializeStore as serializeDrawingsStore }\n\n/** Rebuild live drawings from one symbol's serialized bucket. A row the catalog cannot restore (an\n * unknown type, malformed anchors) is skipped, never a throw, so the rest of the bucket loads. */\nexport function restoreDrawings(list: readonly SerializedDrawing[]): IDrawing[] {\n return restoreAll(list)\n}\n","// The magnet, as a POLICY over the seam's snap.\n//\n// `magnetSnap` answers one question — which OHLC value does this point pull to — and it is pure\n// geometry. The product decisions around it are separate and belong here: the toolbar's icon toggles\n// between off and weak rather than cycling three states, the menu's two rows are latching (picking\n// the mode that is already on releases the magnet, so there is no Off row to hunt for), and the\n// button's face says strong or plain magnet rather than on or off.\nimport type { MagnetMode } from '../internal/drawings/index'\nimport type { ChartMessageKey } from '../i18n/en'\n\nexport type { MagnetMode }\n\n/** The two modes the menu offers. Off is reached by toggling, never by picking. */\nexport const MAGNET_STRENGTHS: readonly Exclude<MagnetMode, 'off'>[] = ['weak', 'strong']\n\nexport const MAGNET_LABELS: Readonly<Record<Exclude<MagnetMode, 'off'>, ChartMessageKey>> = {\n weak: 'drawing.magnetWeak',\n strong: 'drawing.magnetStrong',\n}\n\n/** The toolbar button. It is a plain on/off switch over the LAST strength the viewer chose, so a\n * viewer who set strong gets strong back when they turn the magnet on again. */\nexport function toggleMagnet(mode: MagnetMode, lastStrength: Exclude<MagnetMode, 'off'> = 'weak'): MagnetMode {\n return mode === 'off' ? lastStrength : 'off'\n}\n\n/** A menu row. Picking the active strength releases the magnet; picking the other switches to it\n * without a trip through off. */\nexport function chooseMagnetStrength(mode: MagnetMode, strength: Exclude<MagnetMode, 'off'>): MagnetMode {\n return mode === strength ? 'off' : strength\n}\n\n/** Whether the magnet is pulling at all. */\nexport const magnetActive = (mode: MagnetMode): boolean => mode !== 'off'\n","// The drawing toolbar's STRUCTURE, with no view attached.\n//\n// The toolbar is one button per tool GROUP; each group opens a flyout whose sections gather the\n// related registry categories under a heading. Categories alone do not give that shape: the arrow\n// marks belong beside the arrow line rather than with the annotations, the brushes lead the shapes,\n// and the image and content cards sit under Content rather than with the glyph marks. Those moves\n// are the product's, so they live here as data rather than as conditions inside a component.\n//\n// Everything is catalog KEYS, never words: the toolbar is built once from the registry while the\n// headings it shows follow the interface language.\nimport type { ToolCategory } from '../internal/drawings/index'\nimport type { ChartMessageKey } from '../i18n/en'\nimport { drawingTools, type DrawingTool } from './tools'\n\n/** One heading inside a group's flyout and the tools under it. */\nexport interface DrawingToolbarSection {\n label: ChartMessageKey\n tools: DrawingTool[]\n}\n\n/** One toolbar button: its stable id, its heading, and the sections its flyout shows. */\nexport interface DrawingToolbarGroup {\n id: string\n label: ChartMessageKey\n sections: DrawingToolbarSection[]\n}\n\n/** The arrow marks ride with the plain arrow line in the shapes group's Arrows section. */\nexport const ARROW_TYPES: readonly string[] = ['arrow_marker', 'arrow', 'arrow_up', 'arrow_down']\n/** The brushes lead the shapes group rather than sitting among the geometric shapes. */\nexport const BRUSH_TYPES: readonly string[] = ['brush', 'highlighter']\n/** The glyph marks get a group of their own. */\nexport const GLYPH_TYPES: readonly string[] = ['emoji', 'sticker', 'icon']\n/** Image and content cards make a Content section under Text and notes. */\nexport const CARD_TYPES: readonly string[] = ['image', 'content_card']\n\n/** A section built from whole categories, minus the types that moved elsewhere. */\ninterface CategorySection {\n label: ChartMessageKey\n category: ToolCategory\n exclude?: readonly string[]\n}\n\n/** A section built from an explicit list, in that order. */\ninterface TypeSection {\n label: ChartMessageKey\n types: readonly string[]\n}\n\ntype SectionPlan = CategorySection | TypeSection\n\ninterface GroupPlan {\n id: string\n label: ChartMessageKey\n sections: readonly SectionPlan[]\n}\n\n/** The toolbar's seven groups and their sections, in display order. This is the product decision the\n * registry cannot express: which categories share a button, and where the moved types land. */\nexport const DRAWING_TOOLBAR_PLAN: readonly GroupPlan[] = [\n {\n id: 'trend',\n label: 'drawing.groupTrend',\n sections: [\n { label: 'drawing.sectionLines', category: 'lines', exclude: ['arrow'] },\n { label: 'drawing.sectionChannels', category: 'channels' },\n { label: 'drawing.sectionPitchforks', category: 'pitchforks' },\n ],\n },\n {\n id: 'fib-gann',\n label: 'drawing.groupFibGann',\n sections: [\n { label: 'drawing.sectionFibonacci', category: 'fibonacci' },\n { label: 'drawing.sectionGann', category: 'gann' },\n ],\n },\n {\n id: 'patterns',\n label: 'drawing.groupPatterns',\n sections: [\n { label: 'drawing.sectionChartPatterns', category: 'patterns' },\n { label: 'drawing.sectionElliott', category: 'elliott' },\n { label: 'drawing.sectionCycles', category: 'cycles' },\n ],\n },\n {\n id: 'forecast',\n label: 'drawing.groupForecast',\n sections: [\n { label: 'drawing.sectionForecasting', category: 'forecasting' },\n { label: 'drawing.sectionVolumeBased', category: 'volume' },\n // Measure is a transient tool on the toolbar's action row, not a placeable drawing in a flyout.\n { label: 'drawing.sectionMeasures', category: 'measurement', exclude: ['measure'] },\n ],\n },\n {\n id: 'shapes',\n label: 'drawing.shapes',\n sections: [\n { label: 'drawing.sectionBrushes', types: BRUSH_TYPES },\n { label: 'drawing.sectionArrows', types: ARROW_TYPES },\n { label: 'drawing.shapes', category: 'shapes', exclude: BRUSH_TYPES },\n ],\n },\n {\n id: 'annotation',\n label: 'drawing.textNotes',\n sections: [\n { label: 'drawing.textNotes', category: 'annotation', exclude: ARROW_TYPES },\n { label: 'drawing.sectionContent', types: CARD_TYPES },\n ],\n },\n {\n id: 'glyphs',\n label: 'drawing.groupGlyphs',\n sections: [{ label: 'drawing.sectionGlyphs', types: GLYPH_TYPES }],\n },\n]\n\nconst isTypeSection = (section: SectionPlan): section is TypeSection => 'types' in section\n\n/** Build the toolbar from the tool catalog. An empty section and a group left with none are dropped,\n * so a catalog trimmed by configuration never shows a button that opens on nothing. */\nexport function buildDrawingToolbarGroups(catalog = drawingTools): DrawingToolbarGroup[] {\n const toolsOf = (section: SectionPlan): DrawingTool[] =>\n isTypeSection(section)\n ? section.types.map((type) => catalog.get(type)).filter((tool): tool is DrawingTool => !!tool)\n : catalog.byCategory(section.category).filter((tool) => !(section.exclude ?? []).includes(tool.type))\n\n return DRAWING_TOOLBAR_PLAN.map((group) => ({\n id: group.id,\n label: group.label,\n sections: group.sections.map((section) => ({ label: section.label, tools: toolsOf(section) })).filter((section) => section.tools.length > 0),\n })).filter((group) => group.sections.length > 0)\n}\n\n/** Which group holds a tool, or null when no group shows it. The toolbar highlights that button while\n * the tool is armed. */\nexport function groupOfTool(groups: readonly DrawingToolbarGroup[], type: string | null): string | null {\n if (!type) return null\n return groups.find((group) => group.sections.some((section) => section.tools.some((tool) => tool.type === type)))?.id ?? null\n}\n\n/** Each toolbar button wears its last-picked tool's glyph, so the toolbar keeps that face across\n * reloads. This resolves the face: the remembered tool when the group still shows it, else the\n * group's first tool, else null for a group whose tools carry no glyph. */\nexport function drawingToolbarFaceOf(group: DrawingToolbarGroup, lastTools: Readonly<Record<string, string>>): string | null {\n const remembered = lastTools[group.id]\n if (remembered && group.sections.some((section) => section.tools.some((tool) => tool.type === remembered))) return remembered\n return group.sections[0]?.tools[0]?.type ?? null\n}\n\n/** Remember the tool a group was last used to arm. Returns a NEW record, so a caller stores the\n * result rather than mutating what it was handed. A tool no group shows changes nothing. */\nexport function rememberDrawingToolbarTool(\n groups: readonly DrawingToolbarGroup[],\n lastTools: Readonly<Record<string, string>>,\n type: string,\n): Record<string, string> {\n const group = groupOfTool(groups, type)\n if (!group) return { ...lastTools }\n return { ...lastTools, [group]: type }\n}\n","// The toolbar's eye: ONE switch with a chosen subject, not a row of toggles.\n//\n// The menu picks which layer the eye blanks, the eye blanks it, and the eye keeps wearing that\n// layer's mark until the subject changes. Exactly one subject is ever blanked, so choosing a new\n// one restores the last, and `all` is a subject like the others rather than an extra switch.\n//\n// The chart's own layers are drawings and indicators. Positions, working orders, executions and\n// any other overlay are not the chart's to know: an extension that draws one CONTRIBUTES it as a\n// layer, and it then lists between the chart's own and `all`, which blanks it with them.\nimport type { ChartMessageKey } from '../i18n/en'\n\n/** The layers the eye itself owns, and `all`. */\nexport type BuiltInHideMode = 'drawings' | 'indicators' | 'all'\n\n/** A subject of the eye: one of its own, or the id of a contributed layer. */\nexport type HideMode = string\n\n/** The chart's own layers, ahead of any contributed one. */\nexport const CHART_HIDE_LAYERS: readonly BuiltInHideMode[] = ['drawings', 'indicators']\n\n/** Menu order: the chart's layers, then the contributed ones in contribution order, then all. */\nexport function hideOrder(contributed: readonly string[] = []): readonly HideMode[] {\n return [...CHART_HIDE_LAYERS, ...contributed, 'all']\n}\n\n/** What the eye is pointed at, and whether it is blanking. */\nexport interface HideState {\n mode: HideMode\n on: boolean\n}\n\n/** The eye's resting state: pointed at drawings, blanking nothing. */\nexport const DEFAULT_HIDE_STATE: HideState = { mode: 'drawings', on: false }\n\n/** Each built-in subject's wording in both states. The eye keeps its subject's mark whether or not\n * the layer is blanked, so the toolbar never stops naming what the button acts on. A contributed\n * layer carries its own wording. */\nexport const HIDE_LABELS: Readonly<Record<BuiltInHideMode, { hide: ChartMessageKey; show: ChartMessageKey }>> = {\n drawings: { hide: 'drawing.hideDrawings', show: 'drawing.showDrawings' },\n indicators: { hide: 'drawing.hideIndicators', show: 'drawing.showIndicators' },\n all: { hide: 'drawing.hideAll', show: 'drawing.showAll' },\n}\n\nexport function isBuiltInHideMode(mode: HideMode): mode is BuiltInHideMode {\n return mode === 'drawings' || mode === 'indicators' || mode === 'all'\n}\n\n/** Whether a state blanks one concrete layer. `all` covers every concrete layer; asking whether\n * `all` itself is blanked is asking about the subject, which is `state.mode`. */\nexport function blanks(state: HideState, layer: HideMode): boolean {\n return state.on && (state.mode === layer || state.mode === 'all')\n}\n\n/** The eye itself: blank or restore the current subject. */\nexport function toggleHide(state: HideState): HideState {\n return { mode: state.mode, on: !state.on }\n}\n\n/** The menu picking a subject. Picking the subject that is currently blanked releases it; picking\n * any other subject points the eye there AND blanks it, which is what makes the pick a single\n * gesture rather than a pick followed by a click on the eye. */\nexport function chooseHideMode(state: HideState, mode: HideMode): HideState {\n const active = state.on && state.mode === mode\n return { mode, on: !active }\n}\n\n/** Whether the menu marks a row: only when it is BOTH the chosen subject and currently blanked, so\n * the menu reads as \"this is what the eye is doing\" rather than three separate states. */\nexport function hideRowActive(state: HideState, mode: HideMode): boolean {\n return state.on && state.mode === mode\n}\n","// What the pointer is doing on the chart: the cursor glyph, the two TRANSIENT tools, and whether\n// arming a tool survives the drawing it just made.\n//\n// Measure and Zoom arm from the toolbar exactly like a drawing tool, but nothing they place is kept:\n// the readout lives until the next gesture and the zoom box disappears into the range it set. They\n// are therefore not drawings with a \"temporary\" flag; they are pointer modes with a shape, which is\n// why they are modelled here and not in the tool catalog.\nimport type { ChartMessageKey } from '../i18n/en'\n\n/** The pointer's own glyph over the chart. */\nexport type CursorMode = 'cross' | 'dot' | 'arrow'\n\nexport const CURSOR_MODES: readonly CursorMode[] = ['cross', 'dot', 'arrow']\n\nexport const CURSOR_LABELS: Readonly<Record<CursorMode, ChartMessageKey>> = {\n cross: 'drawing.cursorCross',\n dot: 'drawing.cursorDot',\n arrow: 'drawing.cursorArrow',\n}\n\n/** The armed pointer tools that place nothing permanent. The eraser removes on click and stays\n * armed; measure and zoom draw a two-anchor shape that is discarded once it has done its work. */\nexport type TransientTool = 'eraser' | 'measure' | 'zoom'\n\nexport const TRANSIENT_TOOLS: readonly TransientTool[] = ['eraser', 'measure', 'zoom']\n\nexport const TRANSIENT_LABELS: Readonly<Record<TransientTool, ChartMessageKey>> = {\n eraser: 'drawing.cursorEraser',\n measure: 'drawing.measure',\n zoom: 'drawing.zoomIn',\n}\n\n/** Whether an armed tool id is a transient rather than a catalog tool. `null` (nothing armed) is\n * not a transient. */\nexport function isTransientTool(tool: string | null): tool is TransientTool {\n return tool !== null && (TRANSIENT_TOOLS as readonly string[]).includes(tool)\n}\n\n/** Whether a lingering measure readout or zoom box survives the gesture starting now. It survives\n * only while the same transient stays armed, which is what lets a second measure replace the\n * first without the readout flickering away in between. */\nexport function transientSurvives(tool: string | null): boolean {\n return tool === 'measure' || tool === 'zoom'\n}\n\n/** What stays armed after a placement completes. Freehand tools keep drawing successive strokes;\n * other permanent tools follow Stay in drawing mode. Transients keep their own pointer mode. */\nexport function toolAfterPlacement(tool: string | null, stayInDrawingMode: boolean): string | null {\n if (isTransientTool(tool) || tool === 'brush' || tool === 'highlighter') return tool\n return stayInDrawingMode ? tool : null\n}\n\n/** Which toolbar buttons look armed. The cursor button is the resting state, and it also owns the\n * eraser, so it reads as armed while the eraser is. */\nexport function cursorButtonArmed(tool: string | null): boolean {\n return tool === null || tool === 'eraser'\n}\n","// What a lock refuses, and what the remove menu takes.\n//\n// Two locks act at once and they are not the same thing. The toolbar's LOCK ALL is a mode that\n// suspends the chart: it refuses every edit, the deliberate Delete and Clone included, without\n// changing any drawing. A DRAWING's own lock is a viewer pinning one object down: it refuses a\n// move, a resize, a text edit, the eraser and a modifier-drag duplicate, and lets Delete and Clone\n// act, because a viewer who names a locked drawing and asks for either has asked for exactly that.\n// One predicate holds that matrix, so no surface has to remember which lock answers which edit.\n//\n// The matrix is the library's own and stays inside it. Nothing on the public subpath names it: a\n// host locks and unlocks through the drawing commands and reads what they answer, so the policy\n// can be sharpened here without a consumer having reproduced it.\n//\n// The remove menu is here for the same reason: its counts are a lock question. A sweep spares\n// locked drawings unless the standing preference says otherwise, so what the menu offers to take\n// and what it says it will take are one calculation.\nimport type { ChartMessageKey } from '../i18n/en'\n\n/** Every edit a lock is asked about. `place` and `paste` bring a new drawing and so have no target\n * of their own; the rest act on one.\n *\n * `delete` and `clone` are the DELIBERATE actions a viewer names from the toolbar, the menu or a\n * key. `erase` and `cloneDrag` are the gestures that would do the same thing by accident: the\n * eraser sweeping over a drawing, and a modifier-drag pulling a copy out of it. They are separate\n * edits because a lock answers them differently. */\ntype DrawingEdit = 'select' | 'move' | 'resize' | 'delete' | 'editText' | 'clone' | 'erase' | 'cloneDrag' | 'place' | 'paste'\n\n/** What a drawing's OWN lock refuses: everything that would change the object where it stands, or\n * take it away under a gesture aimed at the chart rather than at it.\n *\n * Selecting is deliberately absent, because a locked drawing stays reachable so it can be\n * inspected, restyled and unlocked, which is the only way back. So are `delete` and `clone`: a\n * viewer who selects a locked drawing and presses Delete, or picks Clone from its menu, has named\n * that one object and asked for exactly this. Refusing there leaves a button that says it acted\n * and did not. */\nconst LOCKED_REFUSES: readonly DrawingEdit[] = ['move', 'resize', 'editText', 'erase', 'cloneDrag']\n\n/** The one lock question every surface asks.\n *\n * Two locks act at once. `allLocked` is the toolbar's mode and it suspends editing across the whole\n * chart, new drawings included, without changing any drawing's own flag. A drawing's `locked`\n * refuses only the edits that would change it. `target` is null for an edit that has no drawing\n * yet. */\nexport function editRefused(edit: DrawingEdit, target: { locked: boolean } | null, allLocked: boolean): boolean {\n if (allLocked) return true\n return !!target && target.locked && LOCKED_REFUSES.includes(edit)\n}\n\n/** Live tally the remove menu counts from. */\nexport interface DrawingCounts {\n total: number\n locked: number\n}\n\n/** How many drawings a sweep would actually take. A locked drawing survives unless the standing\n * \"always remove locked\" preference is on, and the menu's row shows THIS number rather than the\n * total, so the count and the outcome cannot disagree. */\nexport function removableDrawings(counts: DrawingCounts, includeLocked: boolean): number {\n return includeLocked ? counts.total : counts.total - counts.locked\n}\n\n/** One row the remove menu offers. Rows whose count is zero are never built, so the menu never\n * offers a no-op, and the combined row appears only when both kinds are present. */\nexport interface RemoveRow {\n id: 'drawings' | 'indicators' | 'both'\n /** The carrier message; its slots are filled with counted phrases by the surface that renders it. */\n label: ChartMessageKey\n drawings: number\n indicators: number\n}\n\n/** The remove menu's rows for the current tallies. An empty array means there is nothing to take,\n * and the surface says so rather than showing a menu of dead rows. */\nexport function removeRows(counts: DrawingCounts, indicators: number, includeLocked: boolean): RemoveRow[] {\n const drawings = removableDrawings(counts, includeLocked)\n const rows: RemoveRow[] = []\n if (drawings > 0) rows.push({ id: 'drawings', label: 'drawing.removeItems', drawings, indicators: 0 })\n if (indicators > 0) rows.push({ id: 'indicators', label: 'drawing.removeItems', drawings: 0, indicators })\n if (drawings > 0 && indicators > 0) rows.push({ id: 'both', label: 'drawing.removeBoth', drawings, indicators })\n return rows\n}\n","// Favorite drawing tools: the starred list, and the floating bar it fills.\n//\n// The list is ORDERED and the order is the viewer's: a tool joins at the end and keeps its place,\n// because a bar that re-sorts itself is a bar whose buttons move under the pointer. The bar's own\n// visibility and dragged position travel with the list, since all three are the same preference\n// from a viewer's point of view: where my favorites are.\n//\n// The cap exists so the bar cannot grow past the chart it floats over. Starring past the cap is\n// refused rather than silently dropping the oldest: a star that appears to do nothing is a bug\n// report, and a star that quietly evicts another is worse.\n\n/** The most tools the bar holds. */\nexport const MAX_FAVORITE_TOOLS = 24\n\n/** Where the bar sits inside the chart, in CSS pixels from the chart's top left. Null means the\n * bar has never been dragged and takes its default corner. */\nexport interface FavoritesPosition {\n x: number\n y: number\n}\n\n/** The whole favorites preference: what is starred, whether the bar shows, and where it sits. */\nexport interface FavoritesState {\n tools: readonly string[]\n visible: boolean\n position: FavoritesPosition | null\n}\n\nexport const DEFAULT_FAVORITES: FavoritesState = { tools: [], visible: true, position: null }\n\n/** Where favorites live. The chart holds no storage of its own, so a host implements this over\n * whatever it already uses for viewer state, and every surface that stars a tool goes through it.\n * `subscribe` is what keeps the toolbar's stars and the floating bar showing the same list without\n * either one owning the other. */\nexport interface FavoritesPort {\n read(): FavoritesState\n write(state: FavoritesState): void\n /** Hear every change, including one made by another surface. Returns its own unsubscribe. */\n subscribe(listener: () => void): () => void\n}\n\nexport const isFavorite = (state: FavoritesState, type: string): boolean => state.tools.includes(type)\n\n/** Star or unstar a tool. Returns a NEW state; unstarring always succeeds, and starring past the\n * cap returns the state unchanged so the caller can say why nothing happened. */\nexport function toggleFavorite(state: FavoritesState, type: string): FavoritesState {\n if (isFavorite(state, type)) return { ...state, tools: state.tools.filter((t) => t !== type) }\n if (state.tools.length >= MAX_FAVORITE_TOOLS) return state\n return { ...state, tools: [...state.tools, type] }\n}\n\n/** Whether the bar has anything to show. An empty list hides the bar even when it is switched on,\n * because an empty floating strip over a chart is a smudge, not a control. */\nexport const favoritesBarShown = (state: FavoritesState): boolean => state.visible && state.tools.length > 0\n\n/** Drop starred tools the catalog no longer registers, so a list saved against an older\n * configuration does not leave dead buttons on the bar. */\nexport function pruneFavorites(state: FavoritesState, known: (type: string) => boolean): FavoritesState {\n const tools = state.tools.filter(known)\n return tools.length === state.tools.length ? state : { ...state, tools }\n}\n\n/** Keep a dragged bar inside the chart. A chart that shrinks below the bar's last position would\n * otherwise strand it off the edge with no way to drag it back. */\nexport function clampFavoritesPosition(\n position: FavoritesPosition,\n bar: { width: number; height: number },\n chart: { width: number; height: number },\n): FavoritesPosition {\n return {\n x: Math.min(Math.max(0, position.x), Math.max(0, chart.width - bar.width)),\n y: Math.min(Math.max(0, position.y), Math.max(0, chart.height - bar.height)),\n }\n}\n","// Two edit workflows whose rules are decisions rather than geometry: copying a drawing, and\n// typing into one.\n//\n// CLONE AND PASTE both land a copy BESIDE its source rather than under it, because a copy that\n// lands exactly on the original is invisible and the viewer drags what they think is the copy while\n// the original sits underneath. The offset is stated once here, in pixels, and converted to the\n// chart's own time by the caller that has a viewport.\n//\n// TEXT is the workflow where an empty commit means two different things. On a drawing the viewer\n// just placed, empty means \"I changed my mind\" and the placement is undone: there is no such thing\n// as a blank note nobody asked for. On a drawing that already carries text, empty means \"clear it\",\n// and the drawing stays. Getting that backwards leaves a chart littered with empty labels or eats\n// a note somebody meant to blank.\n\n/** How far right a clone or a paste lands from its source, in CSS pixels. */\nexport const CLONE_OFFSET_PX = 24\n\n/** What a text edit is attached to: one drawing, optionally one cell of a table. */\nexport interface TextEditTarget {\n id: string\n /** Set for a table cell; absent when the edit is the drawing's own text. */\n cell?: { row: number; col: number }\n /** The edit opened as part of placing this drawing, rather than on an existing one. */\n fresh: boolean\n}\n\n/** What committing a text edit does. */\nexport type TextCommit =\n | { kind: 'apply'; text: string }\n | { kind: 'apply-cell'; row: number; col: number; text: string }\n /** A fresh placement committed empty: undo the placement, and write no history entry. */\n | { kind: 'discard' }\n\n/** Resolve a commit. Whitespace is trimmed first, so a note of nothing but spaces is a blank one. */\nexport function commitText(target: TextEditTarget, value: string): TextCommit {\n const text = value.trim()\n if (target.cell) return { kind: 'apply-cell', row: target.cell.row, col: target.cell.col, text }\n if (!text && target.fresh) return { kind: 'discard' }\n return { kind: 'apply', text }\n}\n\n/** What cancelling does. A fresh placement is removed, because cancelling the text of a drawing\n * that only exists to carry text cancels the drawing. An existing one keeps what it had. */\nexport function cancelText(target: TextEditTarget): { kind: 'remove' } | { kind: 'keep' } {\n return target.fresh ? { kind: 'remove' } : { kind: 'keep' }\n}\n\n/** Whether placing this tool opens the text editor straight away. */\nexport const opensTextEditor = (tool: { hasText?: boolean } | undefined): boolean => !!tool?.hasText\n","// The theme system's own color arithmetic. Quick Charts adds no dependency for this: parsing a CSS\n// color, compositing a translucent value over its backdrop, and computing a WCAG contrast ratio are\n// the three operations the schema's validation and contrast gates need, and each is a few lines of\n// arithmetic defined by a public specification.\n//\n// The parser accepts the two notations a palette or a host override is written in: hex (`#rgb`,\n// `#rgba`, `#rrggbb`, `#rrggbbaa`) and the `rgb()`/`rgba()` functions in either the comma or the\n// space-with-slash form. It rejects everything else, including named colors and `currentColor`,\n// because a role's value has to be measurable for the contrast gate to mean anything.\n\n/** A parsed color in sRGB. Channels are 0-255 integers; `a` is 0-1. */\nexport interface Rgba {\n r: number\n g: number\n b: number\n a: number\n}\n\nconst HEX = /^#([0-9a-f]{3,8})$/i\nconst FUNCTIONAL = /^rgba?\\(([^)]*)\\)$/i\n\n/** One `rgb()` argument: a 0-255 number, or a percentage of 255. Alpha percentages are handled by\n * the caller, which divides by 100 rather than by 255. */\nfunction channel(token: string): number | null {\n const pct = token.endsWith('%')\n const n = Number(pct ? token.slice(0, -1) : token)\n if (!Number.isFinite(n)) return null\n return pct ? (n / 100) * 255 : n\n}\n\n/** Parse a CSS color string into sRGB channels, or null when the notation is not one a palette may\n * use. A parse failure is a diagnostic, never a throw: an invalid host override is reported and\n * the built-in value is kept. */\nexport function parseCssColor(input: string): Rgba | null {\n const value = input.trim()\n\n const hex = HEX.exec(value)\n if (hex) {\n const digits = hex[1]!\n const expand = (s: string): number => parseInt(s.length === 1 ? s + s : s, 16)\n if (digits.length === 3 || digits.length === 4) {\n const [r, g, b, a] = [digits[0]!, digits[1]!, digits[2]!, digits[3]]\n return { r: expand(r), g: expand(g), b: expand(b), a: a === undefined ? 1 : expand(a) / 255 }\n }\n if (digits.length === 6 || digits.length === 8) {\n const pair = (i: number): number => parseInt(digits.slice(i, i + 2), 16)\n return { r: pair(0), g: pair(2), b: pair(4), a: digits.length === 8 ? pair(6) / 255 : 1 }\n }\n return null\n }\n\n const fn = FUNCTIONAL.exec(value)\n if (!fn) return null\n const body = fn[1]!.trim()\n const [colorPart, alphaPart] = body.includes('/') ? body.split('/') : [body, undefined]\n const parts = colorPart!.trim().split(/[\\s,]+/).filter(Boolean)\n const explicitAlpha = alphaPart?.trim() ?? (parts.length === 4 ? parts[3] : undefined)\n if (parts.length !== 3 && parts.length !== 4) return null\n const rgb = [parts[0]!, parts[1]!, parts[2]!].map(channel)\n if (rgb.some((c) => c === null)) return null\n let a = 1\n if (explicitAlpha !== undefined) {\n const raw = explicitAlpha.endsWith('%') ? Number(explicitAlpha.slice(0, -1)) / 100 : Number(explicitAlpha)\n if (!Number.isFinite(raw)) return null\n a = raw\n }\n const clamp = (n: number, hi: number): number => Math.min(hi, Math.max(0, n))\n return { r: clamp(Math.round(rgb[0]!), 255), g: clamp(Math.round(rgb[1]!), 255), b: clamp(Math.round(rgb[2]!), 255), a: clamp(a, 1) }\n}\n\n/** Flatten a translucent color onto an opaque backdrop, the way a browser composites it. Contrast\n * is only defined between opaque colors, so every ratio starts here. */\nexport function compositeOver(front: Rgba, back: Rgba): Rgba {\n if (front.a >= 1) return { ...front, a: 1 }\n const mix = (f: number, b: number): number => Math.round(f * front.a + b * (1 - front.a))\n return { r: mix(front.r, back.r), g: mix(front.g, back.g), b: mix(front.b, back.b), a: 1 }\n}\n\n/** WCAG 2.2 relative luminance of an opaque sRGB color (WCAG 2.2, relative luminance definition). */\nexport function relativeLuminance(c: Rgba): number {\n const linear = (v: number): number => {\n const s = v / 255\n return s <= 0.04045 ? s / 12.92 : ((s + 0.055) / 1.055) ** 2.4\n }\n return 0.2126 * linear(c.r) + 0.7152 * linear(c.g) + 0.0722 * linear(c.b)\n}\n\nconst WHITE: Rgba = { r: 255, g: 255, b: 255, a: 1 }\n\n/** The WCAG 2.2 contrast ratio between a foreground and a backdrop, 1 to 21. Contrast is defined on\n * opaque colors, so a translucent backdrop is flattened first, onto `beneath` (the opaque surface\n * it is drawn on) when one is given and onto white otherwise, and the foreground is then composited\n * onto that. */\nexport function contrastRatio(foreground: Rgba, background: Rgba, beneath?: Rgba): number {\n const back = compositeOver(background, beneath ? compositeOver(beneath, WHITE) : WHITE)\n const front = compositeOver(foreground, back)\n const [hi, lo] = [relativeLuminance(front), relativeLuminance(back)].sort((a, b) => b - a) as [number, number]\n return (hi + 0.05) / (lo + 0.05)\n}\n\n/** The contrast ratio between two color strings, or null when any of them is unparseable. `beneath`\n * is the opaque surface a translucent `background` is drawn on. */\nexport function contrastOf(foreground: string, background: string, beneath?: string): number | null {\n const f = parseCssColor(foreground)\n const b = parseCssColor(background)\n const under = beneath === undefined ? undefined : parseCssColor(beneath)\n if (!f || !b || under === null) return null\n return contrastRatio(f, b, under)\n}\n","// The color arithmetic behind every palette and custom editor in the chart: hex and HSV both ways,\n// the opaque base of a value that carries alpha, and the swatch grid. The grid's ten hues and ten\n// greys are stated as values, because a palette is a chosen set of colors rather than a formula:\n// deriving the hues from angles would move eight of the ten off their pinned values. The five\n// shade rows derive, by mixing each hue toward white and black.\n//\n// These are the only literal colors outside `theme/palettes.ts` and the documented series\n// defaults, and they belong here rather than in a theme role: they are the set the chart OFFERS a\n// viewer to choose from, the same in light and dark, and a pick becomes a drawing or indicator\n// property rather than anything a mode re-resolves. `theme/literals.test.ts` names this file as\n// that exemption and pins its count.\nimport { parseCssColor } from '../../../theme/color'\n\nexport interface Hsv {\n /** 0..360 */\n h: number\n /** 0..1 */\n s: number\n /** 0..1 */\n v: number\n}\n\nconst to2 = (n: number): string => Math.round(Math.max(0, Math.min(255, n))).toString(16).padStart(2, '0')\n\n/** `#rrggbb` from channels. */\nexport const rgbToHex = (r: number, g: number, b: number): string => `#${to2(r)}${to2(g)}${to2(b)}`\n\n/** Whether a string is a six-digit hex color, with or without its hash. */\nexport const isHex = (s: string): boolean => /^#?[0-9a-f]{6}$/i.test(s)\n\n/** `#rrggbb` to HSV. */\nexport function hexToHsv(hex: string): Hsv {\n const n = parseInt(hex.replace('#', ''), 16)\n const r = ((n >> 16) & 255) / 255\n const g = ((n >> 8) & 255) / 255\n const b = (n & 255) / 255\n const max = Math.max(r, g, b)\n const min = Math.min(r, g, b)\n const d = max - min\n let h = 0\n if (d !== 0) {\n if (max === r) h = ((g - b) / d) % 6\n else if (max === g) h = (b - r) / d + 2\n else h = (r - g) / d + 4\n h *= 60\n if (h < 0) h += 360\n }\n return { h, s: max === 0 ? 0 : d / max, v: max }\n}\n\n/** HSV to `#rrggbb`. */\nexport function hsvToHex(h: number, s: number, v: number): string {\n const c = v * s\n const x = c * (1 - Math.abs(((h / 60) % 2) - 1))\n const m = v - c\n const [r1, g1, b1] = h < 60 ? [c, x, 0] : h < 120 ? [x, c, 0] : h < 180 ? [0, c, x] : h < 240 ? [0, x, c] : h < 300 ? [x, 0, c] : [c, 0, x]\n return rgbToHex((r1 + m) * 255, (g1 + m) * 255, (b1 + m) * 255)\n}\n\n/** The opaque `#rrggbb` of a hex, rgb or rgba value: what a swatch highlight compares against and\n * what the opacity track fades into. A value in a notation the palette does not read passes\n * through untouched, so an unsupported declaration is never rewritten as opaque black. */\nexport function hexOf(color: string): string {\n const value = color.trim()\n const parsed = parseCssColor(value)\n if (parsed) return rgbToHex(parsed.r, parsed.g, parsed.b)\n return value.toLowerCase()\n}\n\n/** The color and alpha of a value the control can edit, or null when the notation is not one it\n * reads. A null keeps the declaration intact until a valid edit replaces it. */\nexport function readColor(color: string | undefined): { hex: string; alpha: number } | null {\n if (!color) return null\n const parsed = parseCssColor(color.trim())\n if (!parsed) return null\n return { hex: rgbToHex(parsed.r, parsed.g, parsed.b), alpha: parsed.a }\n}\n\n/** The grey ramp of the first row, white to black. */\nexport const GREY_RAMP: readonly string[] = ['#ffffff', '#dbdbdb', '#b8b8b8', '#9c9c9c', '#808080', '#636363', '#4a4a4a', '#2e2e2e', '#0f0f0f', '#000000']\n\n/** The ten base hues, the row every ramp below is a lighter or darker reading of. */\nexport const HUE_BASES: readonly string[] = ['#f23645', '#ff9800', '#ffeb3b', '#4caf50', '#089981', '#00bcd4', '#2962ff', '#673ab7', '#9c27b0', '#e91e63']\n\n/** The six ramps under the bases, light to dark. Each is a CHOSEN row rather than a mix of the\n * base above it: a ramp computed by moving every hue the same distance toward white or black\n * goes muddy in the greens and neons in the yellows, so each step is stated as the value it is. */\nexport const HUE_RAMPS: readonly (readonly string[])[] = [\n ['#fccbcd', '#ffe0b2', '#fff9c4', '#c8e6c9', '#ace5dc', '#b2ebf2', '#bbd9fb', '#d1c4e9', '#e1bee7', '#f8bbd0'],\n ['#faa1a4', '#ffcc80', '#fff59d', '#a5d6a7', '#70ccbd', '#80deea', '#90bff9', '#b39ddb', '#ce93d8', '#f48fb1'],\n ['#f77c80', '#ffb74d', '#fff176', '#81c784', '#42bda8', '#4dd0e1', '#5b9cf6', '#9575cd', '#ba68c8', '#f06292'],\n ['#f7525f', '#ffa726', '#ffee58', '#66bb6a', '#22ab94', '#26c6da', '#3179f5', '#7e57c2', '#ab47bc', '#ec407a'],\n ['#b22833', '#f57c00', '#fbc02d', '#388e3c', '#056656', '#0097a7', '#1848cc', '#512da8', '#7b1fa2', '#c2185b'],\n ['#801922', '#e65100', '#f57f17', '#1b5e20', '#00332a', '#006064', '#0c3299', '#311b92', '#4a148c', '#880e4f'],\n]\n\n/** The default the custom editor opens on when the current value is not a color it can read. */\nexport const CUSTOM_COLOR_FALLBACK = '#4c98fb'\n\n/** The palette as the panel lays it out: the greys and the bases stand together as what a viewer\n * reaches for first, and the ramps stand as their own block under a gap. Ten columns throughout,\n * every cell a `#rrggbb`. */\nexport const SWATCH_BLOCKS: readonly (readonly (readonly string[])[])[] = [[GREY_RAMP, HUE_BASES], HUE_RAMPS]\n","// The two DOM questions every surface asks: what in here can take the keyboard, and which way does\n// this element read. Both the chrome and the drawing surfaces need them, and an answer that differs\n// between the two would put a dialog's focus trap and a menu's out of step.\n\n/** Everything inside `root` a hand or the keyboard can reach: not disabled, not taken out of the\n * tab order, not hidden from sight or from a reader, and not inside a hidden group. */\nexport function focusables(root: HTMLElement): HTMLElement[] {\n const nodes = root.querySelectorAll<HTMLElement>('button, [href], input, select, textarea, [tabindex]')\n return [...nodes].filter((n) => !n.hasAttribute('disabled') && n.tabIndex >= 0 && !hiddenWithin(n, root) && n.getAttribute('aria-hidden') !== 'true')\n}\n\n/** Whether the element, or a group between it and `root`, is hidden. */\nfunction hiddenWithin(node: HTMLElement, root: HTMLElement): boolean {\n for (let el: HTMLElement | null = node; el && el !== root; el = el.parentElement) if (el.hidden) return true\n return false\n}\n\n/** Which way the element reads, by the nearest declared direction and the computed one after it.\n * A document without a layout engine answers left to right rather than throwing. */\nexport function isRtl(node: Element): boolean {\n const dir = node.closest<HTMLElement>('[dir]')?.getAttribute('dir') ?? (typeof getComputedStyle === 'function' ? getComputedStyle(node).direction : 'ltr')\n return dir === 'rtl'\n}\n","// Who owns Escape when overlays nest. A menu, a dialog, a drawing popover and the color panel a\n// row expands each bind Escape on the document in the capture phase, so without an order the\n// outermost surface would win and a nested panel could never be dismissed on its own. Every\n// surface that closes on Escape registers here on open and releases on close; only the surface at\n// the top of the stack, the innermost one open, acts on the press. The stack is module state with\n// no public API: it is the package's own overlay contract, not a host capability.\n\nconst stack: object[] = []\n\n/** Register a surface as an Escape owner. Returns the release, which its close runs. */\nexport function pushEscapeOwner(): { token: object; release(): void } {\n const token = {}\n stack.push(token)\n return {\n token,\n release() {\n const at = stack.indexOf(token)\n if (at >= 0) stack.splice(at, 1)\n },\n }\n}\n\n/** Whether this token is the innermost open surface, and therefore the one Escape belongs to. */\nexport function ownsEscape(token: object): boolean {\n return stack.length === 0 || stack[stack.length - 1] === token\n}\n","// The small DOM vocabulary the drawing surfaces share: building elements, keeping presses out of\n// the gesture layers, roving keyboard focus over a row of controls, a menu's own keyboard, a\n// dialog's focus trap and restoration, and placing a floating panel inside the chart root.\n//\n// Nothing here is a component. Each helper does one thing to real elements, so every surface stays\n// readable as the DOM it builds.\n\nimport { focusables, isRtl } from '../controls/dom'\nimport { ownsEscape, pushEscapeOwner } from '../controls/escape'\n\ntype Child = Node | string | null | undefined | false\n\n/** Build an element with attributes and children in one call. `class` is the class list, `text`\n * is the text content, `on` binds listeners, and any other key is an attribute. */\nexport function el<K extends keyof HTMLElementTagNameMap>(\n tag: K,\n props: Record<string, string | number | boolean | undefined | Record<string, EventListener>> = {},\n ...children: Child[]\n): HTMLElementTagNameMap[K] {\n const node = document.createElement(tag)\n for (const [key, value] of Object.entries(props)) {\n if (value === undefined || value === false) continue\n if (typeof value === 'object') {\n if (key === 'on') for (const [type, listener] of Object.entries(value)) node.addEventListener(type, listener)\n } else if (key === 'class') node.className = String(value)\n else if (key === 'text') node.textContent = String(value)\n else if (key === 'html') node.innerHTML = String(value)\n else node.setAttribute(key, value === true ? '' : String(value))\n }\n for (const child of children) {\n if (child === null || child === undefined || child === false) continue\n node.append(child)\n }\n return node\n}\n\n/** A button of the chart's own chrome: never a form submitter, always named. */\nexport function button(props: { class?: string; label: string; title?: string; icon?: Element | null; text?: string; onClick?: (event: MouseEvent) => void; pressed?: boolean; disabled?: boolean }): HTMLButtonElement {\n const b = el('button', {\n type: 'button',\n class: props.class ?? 'qc-button',\n 'aria-label': props.label,\n title: props.title ?? props.label,\n ...(props.text !== undefined ? { text: props.text } : {}),\n ...(props.pressed !== undefined ? { 'aria-pressed': String(props.pressed) } : {}),\n })\n if (props.icon) b.append(props.icon)\n if (props.disabled) b.disabled = true\n if (props.onClick) b.addEventListener('click', props.onClick)\n return b\n}\n\n/** Keep a surface's presses to itself. The chrome layer is inert and each control opts back in, but\n * the drag layers under it bind capture-phase handlers on the gesture box: a surface that lives in\n * the chrome subtree is safe, and this stops the bubble so a press on a panel never reaches a\n * chart handler either. */\nexport function ownPointer(node: HTMLElement): void {\n for (const type of ['pointerdown', 'pointerup', 'pointermove', 'wheel', 'mousedown', 'dblclick'] as const) {\n node.addEventListener(type, (e) => e.stopPropagation())\n }\n}\n\n/** Follow a pointer until it is released, then stop.\n *\n * The listeners take the CAPTURE phase, and that is the whole point: these floating surfaces call\n * {@link ownPointer} so a press on a control never reaches the chart underneath, which means a\n * release over the surface is stopped on its way out and a bubble listener never hears it. Capture\n * runs before the event reaches the surface at all, so a drag always hears its own end. */\n/** Where a floating bar is PAINTED, given where the viewer left it and the box it floats in now.\n * The remembered position is the viewer's and is never rewritten: a panel that opens beside the\n * chart pushes the bar in, and one that closes lets it back to where it was put. A box with no\n * measured size yet, as before first layout, leaves the position as it was remembered. */\nexport function paintedPosition(position: { x: number; y: number }, bar: HTMLElement, host: HTMLElement): { x: number; y: number } {\n const box = host.getBoundingClientRect()\n if (!(box.width > 0 && box.height > 0)) return position\n return {\n x: Math.min(Math.max(0, position.x), Math.max(0, box.width - bar.offsetWidth)),\n y: Math.min(Math.max(0, position.y), Math.max(0, box.height - bar.offsetHeight)),\n }\n}\n\n/** Re-place a floating bar whenever the box it floats in changes size. Returns the stop. */\nexport function followHostSize(host: HTMLElement, place: () => void): () => void {\n if (typeof ResizeObserver === 'undefined') return () => undefined\n const observer = new ResizeObserver(() => place())\n observer.observe(host)\n return () => observer.disconnect()\n}\n\nexport function dragUntilRelease(onMove: (event: PointerEvent) => void, onRelease: () => void): void {\n const types = ['pointermove', 'pointerup', 'pointercancel'] as const\n const end = (): void => {\n for (const type of types) window.removeEventListener(type, handlers[type], true)\n onRelease()\n }\n const handlers = { pointermove: onMove, pointerup: end, pointercancel: end }\n for (const type of types) window.addEventListener(type, handlers[type], true)\n}\n\n/** The elements inside a root that take focus in tab order. */\n/** Roving focus over a set of controls: one tab stop, arrows move between them, Home and End\n * jump. The set is read at every press, so controls that come and go are always current. */\nexport function rovingFocus(root: HTMLElement, items: () => HTMLElement[], orientation: 'horizontal' | 'vertical' | 'both' = 'both'): () => void {\n const sync = (active: HTMLElement | null): void => {\n const list = items()\n for (const item of list) item.tabIndex = item === active ? 0 : -1\n if (!active && list[0]) list[0].tabIndex = 0\n }\n const onKey = (e: KeyboardEvent): void => {\n const list = items()\n if (list.length === 0) return\n const at = list.indexOf(document.activeElement as HTMLElement)\n const next = orientation !== 'vertical' && (e.key === 'ArrowRight' || (orientation === 'horizontal' && e.key === 'ArrowDown'))\n const prev = orientation !== 'vertical' && (e.key === 'ArrowLeft' || (orientation === 'horizontal' && e.key === 'ArrowUp'))\n const down = orientation !== 'horizontal' && e.key === 'ArrowDown'\n const up = orientation !== 'horizontal' && e.key === 'ArrowUp'\n let target: HTMLElement | undefined\n if (next || down) target = list[(at + 1 + list.length) % list.length]\n else if (prev || up) target = list[(at - 1 + list.length) % list.length]\n else if (e.key === 'Home') target = list[0]\n else if (e.key === 'End') target = list[list.length - 1]\n if (!target) return\n e.preventDefault()\n sync(target)\n target.focus()\n }\n const onFocus = (e: FocusEvent): void => {\n const target = e.target as HTMLElement\n if (items().includes(target)) sync(target)\n }\n root.addEventListener('keydown', onKey)\n root.addEventListener('focusin', onFocus)\n sync(null)\n return () => {\n root.removeEventListener('keydown', onKey)\n root.removeEventListener('focusin', onFocus)\n }\n}\n\n/** Trap Tab inside a dialog and restore focus to the opener when it closes. */\nexport function trapFocus(root: HTMLElement): () => void {\n const opener = document.activeElement as HTMLElement | null\n const onKey = (e: KeyboardEvent): void => {\n if (e.key !== 'Tab') return\n const list = focusables(root)\n if (list.length === 0) {\n e.preventDefault()\n return\n }\n const first = list[0]!\n const last = list[list.length - 1]!\n const active = document.activeElement\n if (e.shiftKey && (active === first || !root.contains(active))) {\n e.preventDefault()\n last.focus()\n } else if (!e.shiftKey && (active === last || !root.contains(active))) {\n e.preventDefault()\n first.focus()\n }\n }\n root.addEventListener('keydown', onKey)\n return () => {\n root.removeEventListener('keydown', onKey)\n if (opener && opener.isConnected) opener.focus({ preventScroll: true })\n }\n}\n\n/** Close a floating panel on a press outside it (and outside the control that opened it), or on\n * Escape. Bound on the document in the capture phase, so a press the chart swallows still counts.\n * Escape belongs to the innermost surface open, so a panel raised over this one dismisses first. */\nexport function dismissOnOutside(panel: HTMLElement, anchor: HTMLElement | null, close: () => void, inside?: (target: Node) => boolean): () => void {\n const escape = pushEscapeOwner()\n const onDown = (e: Event): void => {\n const target = e.target as Node\n if (panel.contains(target) || (anchor && anchor.contains(target)) || inside?.(target)) return\n close()\n }\n const onKey = (e: KeyboardEvent): void => {\n if (e.key === 'Escape' && ownsEscape(escape.token)) {\n e.stopPropagation()\n close()\n }\n }\n document.addEventListener('pointerdown', onDown, true)\n document.addEventListener('keydown', onKey, true)\n return () => {\n escape.release()\n document.removeEventListener('pointerdown', onDown, true)\n document.removeEventListener('keydown', onKey, true)\n }\n}\n\n/** Whether the chart reads right to left, from the root's own direction. */\nexport type PanelPlacement = 'side' | 'sidecar' | 'below' | 'below-end'\n\n/** Place a floating panel inside the chart's chrome box beside its anchor: to the inline end of\n * the anchor for `side`, below it for `below` (its inline-end edges level for `below-end`),\n * clamped so the panel stays within the box and flipping to the other side when there is no\n * room. A `sidecar` is a submenu: level with its row and flush to the row's outer edge, with no\n * offset at all, so a pointer travelling from the row into the panel crosses nothing that would\n * close it. Sizes are measured after the panel is in the DOM; the position is the one inline\n * write, because a position is calculated geometry. */\nexport function placePanel(panel: HTMLElement, anchor: HTMLElement, box: HTMLElement, mode: PanelPlacement, gap = 2): void {\n // The widget's layer on the document body has no box of its own: what stands in it is placed at\n // viewport coordinates and kept within the viewport.\n const b = box.classList.contains('qc-layer')\n ? { left: 0, top: 0, width: document.documentElement.clientWidth, height: document.documentElement.clientHeight }\n : box.getBoundingClientRect()\n const a = anchor.getBoundingClientRect()\n const w = panel.offsetWidth\n const h = panel.offsetHeight\n const rtl = isRtl(box)\n let left: number\n let top: number\n if (mode === 'sidecar') {\n // The list the row belongs to pads its rows, so the row's own edge sits inside the list's. A\n // panel placed on the row's edge would stand that padding over the list it came from.\n const list = (anchor.closest('[role=\"menu\"]') ?? anchor).getBoundingClientRect()\n left = rtl ? list.left - b.left - w : list.right - b.left\n if (rtl ? left < 0 : left + w > b.width) left = rtl ? list.right - b.left : list.left - b.left - w\n top = a.top - b.top\n } else if (mode === 'side') {\n // A side panel opens a pixel clear of its trigger: the gap is the trigger's own edge, not space\n // the pointer has to travel, and the panel's padding carries the rest.\n left = rtl ? a.left - b.left - w - 1 : a.right - b.left + 1\n if (left + w > b.width) left = a.left - b.left - w - 1\n if (left < 0) left = Math.max(0, rtl ? a.right - b.left : 0)\n // Lifted by the panel's OWN top padding, so its first row lands level with the trigger instead\n // of a padding's worth below it.\n const lift = Number.parseFloat(getComputedStyle(panel).paddingTop) || 0\n top = a.top - b.top - lift\n if (top + h > b.height) top = Math.max(0, b.height - h)\n } else {\n const end = (mode === 'below-end') !== rtl\n left = end ? a.right - b.left - w : a.left - b.left\n left = Math.max(0, Math.min(left, b.width - w))\n top = a.bottom - b.top + gap\n if (top + h > b.height) top = Math.max(0, a.top - b.top - h - gap)\n }\n // The anchor may sit just outside an explicitly selected host (an external drawing toolbar beside\n // its widget). Clamp the result to that host without changing which chart owns the action.\n left = Math.max(0, Math.min(left, b.width - w))\n top = Math.max(0, Math.min(top, b.height - h))\n panel.style.left = `${Math.round(left)}px`\n panel.style.top = `${Math.round(top)}px`\n panel.style.maxHeight = `${Math.max(120, b.height - top - 4)}px`\n}\n\n/** A menu's own keyboard: arrows move over its rows, Home and End jump, Escape is the caller's.\n * Rows are read at every press, so a rebuilt menu needs no rebinding. */\nexport function menuKeys(menu: HTMLElement, rows: () => HTMLElement[]): () => void {\n return rovingFocus(menu, rows, 'vertical')\n}\n\n/** The first row of a menu takes focus when it opens, so the keyboard lands on the choices. */\nexport function focusFirst(root: HTMLElement): void {\n focusables(root)[0]?.focus({ preventScroll: true })\n}\n","// The one color control the chart offers, wherever a color is chosen: the drawing toolbar and its\n// settings dialog, the chart settings menu, and the indicator plot, level and fill editors. It\n// replaces the native color input, which opened the operating system's own dialog: a different\n// window on every machine, unstyleable, and jarring over a dark chart.\n//\n// The control owns transient interaction state only. It reports a typed edit and is updated and\n// destroyed explicitly by its consumer, which owns persistence, previews, commits and\n// cancellation: the drawing toolbar commits at once, the indicator dialog collects for Apply. A\n// value update repaints in place, so neither a new value nor a theme change remounts an open\n// panel, and a drag on the square or the strip reports nothing until it is committed, so one drag\n// is one edit rather than one per pointer move.\nimport { button, el, focusFirst } from '../../drawings/dom'\nimport type { ChartTranslate } from '../../../i18n'\nimport { CUSTOM_COLOR_FALLBACK, GREY_RAMP, hexOf, hexToHsv, hsvToHex, isHex, readColor, SWATCH_BLOCKS, type Hsv } from './palette'\n\nconst clamp01 = (n: number): number => Math.min(1, Math.max(0, n))\n\n/** How many mixed colours the panel keeps, newest first: three rows of the grid less the cell the\n * plus stands in. A viewer reaching past thirty is reaching for the mixer, not for a memory. */\nexport const RECENT_COLOR_LIMIT = 29\n\nexport interface ControlHandle<E extends HTMLElement = HTMLElement> {\n element: E\n destroy(): void\n}\n\nexport interface CustomColorHandle extends ControlHandle {\n /** Repaint from a value the consumer now holds, without rebuilding the editor. */\n update(value: string): void\n}\n\nexport interface OpacityHandle extends ControlHandle {\n update(color: string, value: number): void\n}\n\n/** The opacity control: a range over a track that fades into the color, beside the same value as a\n * figure the viewer may type over. Both carry the percent and both report the fraction, so which\n * one a hand reaches for is the only difference between them. */\nexport function createOpacitySlider(t: ChartTranslate, color: string, value: number, onChange: (v: number) => void): OpacityHandle {\n const track = el('input', { type: 'range', min: '0', max: '100', class: 'qc-drawing-opacity', 'aria-label': t('drawing.opacity') }) as HTMLInputElement\n const figure = el('input', { class: 'qc-drawing-opacity-readout', 'aria-label': t('drawing.opacity'), inputmode: 'numeric', spellcheck: 'false' }) as HTMLInputElement\n track.value = String(Math.round(clamp01(value) * 100))\n figure.value = track.value\n track.style.setProperty('--qcd-swatch', hexOf(color))\n track.addEventListener('input', () => {\n figure.value = track.value\n onChange(Number(track.value) / 100)\n })\n // The field takes figures alone and holds the range as it is typed, so a hundred is the most a\n // hand can reach. An emptied field reports nothing until there is a number to report.\n figure.addEventListener('input', () => {\n const digits = figure.value.replace(/[^0-9]/g, '').slice(0, 3)\n if (digits === '') {\n figure.value = ''\n return\n }\n const next = Math.min(100, Number(digits))\n figure.value = String(next)\n track.value = figure.value\n onChange(next / 100)\n })\n figure.addEventListener('blur', () => {\n figure.value = track.value\n })\n const element = el(\n 'div',\n { class: 'qc-drawing-opacity-row' },\n track,\n el('span', { class: 'qc-drawing-opacity-field' }, figure, el('span', { class: 'qc-drawing-opacity-unit', 'aria-hidden': 'true', text: '%' })),\n )\n return {\n element,\n update(nextColor, nextValue) {\n track.style.setProperty('--qcd-swatch', hexOf(nextColor))\n if (document.activeElement !== track) track.value = String(Math.round(clamp01(nextValue) * 100))\n if (document.activeElement !== figure) figure.value = track.value\n },\n destroy() {\n element.remove()\n },\n }\n}\n\n/** The custom color editor behind the palette's plus cell: a live swatch, a hex field and an Add\n * button on one row, then a saturation and value square beside a hue strip. Both tracks take the\n * pointer and the keyboard; the pointer is captured by the track, so a drag that leaves the panel\n * still tracks, a cancelled gesture releases, and no listener outlives the editor. */\nexport function createCustomColorPicker(t: ChartTranslate, initial: string, onAdd: (hex: string) => void): CustomColorHandle {\n const startOf = (value: string): string => readColor(value)?.hex ?? CUSTOM_COLOR_FALLBACK\n let hsv: Hsv = hexToHsv(startOf(initial))\n const hex = (): string => hsvToHex(hsv.h, hsv.s, hsv.v)\n\n const swatch = el('span', { class: 'qc-drawing-custom-swatch' })\n const field = el('input', { class: 'qc-drawing-hex', 'aria-label': t('drawing.hexColor'), spellcheck: 'false' }) as HTMLInputElement\n const commit = (): void => {\n if (isHex(field.value)) onAdd(`#${field.value.toLowerCase()}`)\n }\n const add = button({ class: 'qc-button qc-button--primary qc-drawing-add', label: t('drawing.add'), text: t('drawing.add'), onClick: commit })\n const square = el('div', { class: 'qc-drawing-sv', role: 'slider', tabindex: '0', 'aria-label': t('drawing.saturationValue') })\n const squareDot = el('span', { class: 'qc-drawing-sv-dot' })\n const strip = el('div', { class: 'qc-drawing-hue', role: 'slider', tabindex: '0', 'aria-label': t('drawing.hue'), 'aria-valuemin': '0', 'aria-valuemax': '360' })\n const stripDot = el('span', { class: 'qc-drawing-hue-dot' })\n square.appendChild(squareDot)\n strip.appendChild(stripDot)\n\n /** Repaint from the HSV state. A paint that follows typing leaves the field as typed, so a\n * half-typed hex is never overwritten under the viewer's hands. */\n const paint = (typed = false): void => {\n const h = hex()\n swatch.style.setProperty('--qcd-swatch', h)\n square.style.setProperty('--qcd-hue', hsvToHex(hsv.h, 1, 1))\n squareDot.style.left = `${hsv.s * 100}%`\n squareDot.style.top = `${(1 - hsv.v) * 100}%`\n stripDot.style.top = `${(hsv.h / 360) * 100}%`\n square.setAttribute('aria-valuetext', h)\n strip.setAttribute('aria-valuenow', String(Math.round(hsv.h)))\n if (!typed) field.value = h.slice(1)\n add.disabled = !isHex(field.value)\n }\n field.addEventListener('input', () => {\n field.value = field.value.replace(/[^0-9a-f]/gi, '').slice(0, 6)\n if (isHex(field.value)) hsv = hexToHsv(`#${field.value}`)\n paint(true)\n })\n field.addEventListener('keydown', (e) => {\n if (e.key === 'Enter') commit()\n })\n\n /** A drag on a track. The track captures the pointer for the gesture, so the move and the\n * release arrive at the track itself whether or not the pointer is still over it. */\n const drag = (track: HTMLElement, onPos: (x: number, y: number) => void): void => {\n let pointer: number | null = null\n const at = (event: PointerEvent): void => {\n const r = track.getBoundingClientRect()\n onPos(clamp01((event.clientX - r.left) / (r.width || 1)), clamp01((event.clientY - r.top) / (r.height || 1)))\n paint()\n }\n track.addEventListener('pointerdown', (event) => {\n if (pointer !== null) return\n pointer = event.pointerId\n track.setPointerCapture?.(event.pointerId)\n track.focus({ preventScroll: true })\n at(event)\n event.preventDefault()\n })\n track.addEventListener('pointermove', (event) => {\n if (pointer !== event.pointerId) return\n at(event)\n })\n const release = (event: PointerEvent): void => {\n if (pointer !== event.pointerId) return\n pointer = null\n if (track.hasPointerCapture?.(event.pointerId)) track.releasePointerCapture?.(event.pointerId)\n }\n track.addEventListener('pointerup', release)\n track.addEventListener('pointercancel', release)\n track.addEventListener('lostpointercapture', release)\n }\n drag(square, (x, y) => {\n hsv = { ...hsv, s: x, v: 1 - y }\n })\n drag(strip, (_x, y) => {\n hsv = { ...hsv, h: y * 360 }\n })\n\n // The keyboard on the two tracks: the arrows move the axis a track owns, Shift moves it by the\n // coarse step, Home and End reach its ends, Enter commits as it does from the field.\n square.addEventListener('keydown', (event) => {\n if (event.key === 'Enter') {\n commit()\n return\n }\n const size = event.shiftKey ? 0.1 : 0.02\n if (event.key === 'ArrowRight') hsv = { ...hsv, s: clamp01(hsv.s + size) }\n else if (event.key === 'ArrowLeft') hsv = { ...hsv, s: clamp01(hsv.s - size) }\n else if (event.key === 'ArrowUp') hsv = { ...hsv, v: clamp01(hsv.v + size) }\n else if (event.key === 'ArrowDown') hsv = { ...hsv, v: clamp01(hsv.v - size) }\n else if (event.key === 'Home') hsv = { ...hsv, s: 0, v: 1 }\n else if (event.key === 'End') hsv = { ...hsv, s: 1, v: 0 }\n else return\n event.preventDefault()\n event.stopPropagation()\n paint()\n })\n strip.addEventListener('keydown', (event) => {\n if (event.key === 'Enter') {\n commit()\n return\n }\n const size = event.shiftKey ? 20 : 2\n const move = (h: number): void => {\n hsv = { ...hsv, h: Math.min(360, Math.max(0, h)) }\n }\n if (event.key === 'ArrowRight' || event.key === 'ArrowUp') move(hsv.h + size)\n else if (event.key === 'ArrowLeft' || event.key === 'ArrowDown') move(hsv.h - size)\n else if (event.key === 'Home') move(0)\n else if (event.key === 'End') move(360)\n else return\n event.preventDefault()\n event.stopPropagation()\n paint()\n })\n paint()\n\n const element = el(\n 'div',\n { class: 'qc-drawing-custom' },\n el('div', { class: 'qc-drawing-custom-row' }, swatch, el('span', { class: 'qc-drawing-hex-wrap' }, el('span', { class: 'qc-muted', text: '#' }), field), add),\n el('div', { class: 'qc-drawing-custom-tracks' }, square, strip),\n )\n return {\n element,\n update(value) {\n // A repaint while the field has the keyboard would overwrite what is being typed.\n if (document.activeElement === field) return\n hsv = hexToHsv(startOf(value))\n paint()\n },\n destroy() {\n element.remove()\n },\n }\n}\n\nexport interface PaletteOptions {\n value: string\n onPick(color: string): void\n /** The colours this viewer has mixed, newest first, and how a new one joins them. The control\n * reads and writes through this rather than holding a store: what a chart remembers is the\n * chart's to keep. Absent, the panel shows no remembered row and the mixer still applies. */\n recents?: { list(): readonly string[]; add(hex: string): void }\n /** 0..1 opacity; omit to hide the slider row. A value whose notation carries no alpha the\n * control reads has no opacity row, and its declaration stands until a valid edit. */\n opacity?: number\n onOpacity?(value: number): void\n}\n\nexport interface PaletteHandle extends ControlHandle {\n /** The value, and the opacity where the consumer supplies one, without a rebuild. */\n update(value: string, opacity?: number): void\n}\n\n/** The palette: the offered colours on a ten-wide grid, the ones this viewer mixed under a rule,\n * and the opacity beneath. The plus does not grow the panel: it turns it over to the mixer, so\n * the surface holding it never changes size under the pointer.\n *\n * A block is a group of rows that stand together. The greys and the ten bases are what a viewer\n * reaches for first; the ramps are a second reading of the same ten. */\nexport function createColorPalette(t: ChartTranslate, options: PaletteOptions): PaletteHandle {\n let value = options.value\n const grid = el('div', { class: 'qc-drawing-swatches', role: 'group', 'aria-label': t('drawing.pickColor') })\n const cells: HTMLButtonElement[] = []\n let lastRememberedCount = 0\n const swatch = (c: string): HTMLButtonElement => {\n const b = button({ class: 'qc-drawing-swatch', label: t('drawing.colorSwatch', { hex: c }), onClick: () => options.onPick(c) })\n b.style.setProperty('--qcd-swatch', c)\n b.dataset.qcColor = c\n // The palest cell of all would otherwise have no edge against a light panel.\n if (c === GREY_RAMP[0]) b.dataset.qcPale = 'true'\n cells.push(b)\n return b\n }\n /** One block's cells, ten to a row, appended to whatever holds it. A trailing control is laid\n * out as one more cell, so it takes the next free place in the last row and wraps with the\n * colours rather than standing on a row of its own. */\n const rowsOf = (host: HTMLElement, colors: readonly string[], trailing?: HTMLElement): void => {\n const row: HTMLElement[] = colors.map(swatch)\n if (trailing) row.push(trailing)\n for (let i = 0; i < row.length; i += 10) host.appendChild(el('div', { class: 'qc-drawing-swatch-row' }, ...row.slice(i, i + 10)))\n }\n for (const block of SWATCH_BLOCKS) {\n const box = el('div', { class: 'qc-drawing-swatch-block' })\n rowsOf(box, block.flat())\n grid.appendChild(box)\n }\n const markActive = (): void => {\n const base = hexOf(value)\n for (const b of cells) {\n if (b.dataset.qcColor === base) b.dataset.qcActive = 'true'\n else delete b.dataset.qcActive\n }\n }\n markActive()\n\n // The plus stands in the remembered row, in the next free cell: it is one of the colours a\n // viewer reaches along, not a control parked under them.\n const plus = button({ class: 'qc-drawing-swatch qc-drawing-swatch-plus', label: t('drawing.customColor') })\n plus.setAttribute('aria-haspopup', 'true')\n const remembered = el('div', { class: 'qc-drawing-swatch-block' })\n const paintRemembered = (): void => {\n remembered.replaceChildren()\n const kept = (options.recents?.list() ?? []).slice(0, RECENT_COLOR_LIMIT)\n for (const cell of cells.splice(cells.length - lastRememberedCount)) void cell\n lastRememberedCount = kept.length\n rowsOf(remembered, kept, plus)\n markActive()\n }\n grid.appendChild(el('div', { class: 'qc-drawing-separator', role: 'presentation' }))\n grid.appendChild(remembered)\n\n const element = el('div', { class: 'qc-drawing-palette' }, grid)\n\n // The mixer TURNS THE PANEL OVER rather than growing it: the swatches stand down, the mixer\n // takes their place at the same anchor, and committing a colour brings the swatches back with\n // the new one already remembered. A panel that grew instead would move every row under the\n // pointer that opened it.\n let custom: CustomColorHandle | null = null\n const closeCustom = (): void => {\n if (!custom) return\n custom.destroy()\n custom = null\n grid.hidden = false\n opacityRow?.removeAttribute('hidden')\n plus.focus({ preventScroll: true })\n }\n plus.addEventListener('click', () => {\n if (custom) {\n closeCustom()\n return\n }\n custom = createCustomColorPicker(t, value, (hex) => {\n options.recents?.add(hex)\n closeCustom()\n paintRemembered()\n options.onPick(hex)\n })\n grid.hidden = true\n opacityRow?.setAttribute('hidden', '')\n element.appendChild(custom.element)\n focusFirst(custom.element)\n })\n // Escape leaves the mixer for the swatches it replaced, before the surface holding the palette\n // sees the press and closes everything.\n element.addEventListener('keydown', (event) => {\n if (event.key !== 'Escape' || !custom) return\n event.stopPropagation()\n event.preventDefault()\n closeCustom()\n })\n\n let opacity: OpacityHandle | null = null\n let opacityRow: HTMLElement | null = null\n if (options.opacity !== undefined && options.onOpacity) {\n opacity = createOpacitySlider(t, hexOf(value), options.opacity, options.onOpacity)\n opacityRow = el('div', { class: 'qc-drawing-palette-opacity' }, el('span', { class: 'qc-drawing-section-title', text: t('drawing.opacity') }), opacity.element)\n element.appendChild(opacityRow)\n }\n paintRemembered()\n return {\n element,\n update(next, nextOpacity) {\n value = next\n paintRemembered()\n custom?.update(next)\n if (opacity && nextOpacity !== undefined) opacity.update(hexOf(next), nextOpacity)\n },\n destroy() {\n closeCustom()\n opacity?.destroy()\n element.remove()\n },\n }\n}\n\n/** How a consumer mounts the panel the control opens: it places `content` against `anchor`, calls\n * `onClosed` whenever the panel goes for any reason, and returns its own close. The control never\n * mounts an overlay itself, so overlay lifetime stays with the surface that owns it. */\nexport type OpenColorPanel = (anchor: HTMLElement, content: HTMLElement, onClosed: () => void) => () => void\n\nexport interface ColorControlOptions {\n label: string\n value: string\n onPick(color: string): void\n opacity?: number\n onOpacity?(value: number): void\n disabled?: boolean\n /** Close the panel as soon as a swatch is picked. A panel that also carries stroke rows stays. */\n closeOnPick?: boolean\n /** Extra rows the consumer appends below the palette, such as thickness and line style. */\n extraRows?(panel: HTMLElement): void\n openPanel: OpenColorPanel\n}\n\nexport interface ColorControlHandle extends ControlHandle<HTMLButtonElement> {\n update(value: string, opacity?: number): void\n}\n\n/** The color field: a well showing the value over a checkerboard, which opens the palette. */\nexport function createColorControl(t: ChartTranslate, options: ColorControlOptions): ColorControlHandle {\n let value = options.value\n let opacity = options.opacity\n const fill = el('span', { class: 'qc-drawing-well-fill' })\n const well = el('span', { class: 'qc-drawing-well' }, fill)\n const face = (): void => {\n fill.style.setProperty('--qcd-swatch', value)\n fill.style.opacity = String(opacity ?? 1)\n }\n face()\n const element = button({ class: 'qc-field qc-drawing-swatch-button', label: options.label, disabled: options.disabled })\n element.setAttribute('aria-haspopup', 'dialog')\n element.setAttribute('aria-expanded', 'false')\n element.appendChild(well)\n\n let palette: PaletteHandle | null = null\n let close: (() => void) | null = null\n element.addEventListener('click', () => {\n if (close) {\n close()\n return\n }\n const panel = el('div', { class: 'qc-drawing-swatch-panel' })\n palette = createColorPalette(t, {\n value,\n onPick: (c) => {\n options.onPick(c)\n if (options.closeOnPick) close?.()\n },\n ...(opacity !== undefined && options.onOpacity ? { opacity, onOpacity: options.onOpacity } : {}),\n })\n panel.appendChild(palette.element)\n options.extraRows?.(panel)\n close = options.openPanel(element, panel, () => {\n palette?.destroy()\n palette = null\n close = null\n })\n focusFirst(panel)\n })\n\n return {\n element,\n update(next, nextOpacity) {\n value = next\n if (nextOpacity !== undefined) opacity = nextOpacity\n face()\n palette?.update(next, nextOpacity)\n },\n destroy() {\n close?.()\n element.remove()\n },\n }\n}\n","// Every standing choice the drawing workflow remembers, as ONE record.\n//\n// These were seven separate browser keys, each read and written where it happened to be needed,\n// which is why a host had no way to move them anywhere else. They are one preference record now,\n// persisted through the chart's `ChartStorage` port by the widget, so a host that keeps viewer\n// state on a server keeps these there too and a second device opens the chart set up the same way.\n//\n// This is flat viewer state, not an entity: no identity, no revision, no conflict. That is exactly\n// the line `ChartStorage` draws against the revisioned resource contract next door, where saved\n// charts, layouts, drawings and templates live.\nimport type { CursorMode } from './cursorModel'\nimport { CURSOR_MODES } from './cursorModel'\nimport type { MagnetMode } from './magnetModel'\nimport type { FavoritesPosition, FavoritesState } from './favoritesModel'\nimport { DEFAULT_FAVORITES, MAX_FAVORITE_TOOLS } from './favoritesModel'\nimport { RECENT_COLOR_LIMIT } from '../ui/controls/color'\n\n/** The most recent glyph picks the record keeps. */\nconst RECENT_GLYPHS_MAX = 12\n\nexport interface DrawingPreferences {\n /** The pointer's glyph over the chart. */\n cursor: CursorMode\n /** Off, or the strength the magnet pulls with. */\n magnet: MagnetMode\n /** The last strength chosen, so switching the magnet back on restores it rather than falling\n * back to weak. */\n magnetStrength: Exclude<MagnetMode, 'off'>\n /** A placed tool stays armed for the next drawing. */\n stayInDrawingMode: boolean\n /** A sweep takes locked drawings too. */\n removeLocked: boolean\n /** A NEW drawing is replicated to every pane charting the same symbol. */\n syncAcrossPanes: boolean\n /** Each toolbar group's last-picked tool, so the button keeps that face. Keyed by group id. */\n drawingToolbarTools: Readonly<Record<string, string>>\n favorites: FavoritesState\n /** Where the selected drawing's settings bar was dragged to; null takes its default place. */\n settingsBarPosition: FavoritesPosition | null\n /** The glyph picker's most recent picks, newest first. */\n recentGlyphs: readonly string[]\n /** The colours this viewer mixed in the picker, newest first. */\n recentColors: readonly string[]\n}\n\nexport const DEFAULT_DRAWING_PREFERENCES: DrawingPreferences = {\n cursor: 'cross',\n magnet: 'off',\n magnetStrength: 'weak',\n stayInDrawingMode: false,\n removeLocked: false,\n syncAcrossPanes: true,\n drawingToolbarTools: {},\n favorites: DEFAULT_FAVORITES,\n settingsBarPosition: null,\n recentGlyphs: [],\n recentColors: [],\n}\n\nconst positionOf = (value: unknown): FavoritesPosition | null => {\n const p = value as { x?: unknown; y?: unknown } | null | undefined\n return p && typeof p.x === 'number' && typeof p.y === 'number' ? { x: p.x, y: p.y } : null\n}\n\nconst oneOf = <T extends string>(value: unknown, allowed: readonly T[], fallback: T): T =>\n typeof value === 'string' && (allowed as readonly string[]).includes(value) ? (value as T) : fallback\n\nconst bool = (value: unknown, fallback: boolean): boolean => (typeof value === 'boolean' ? value : fallback)\n\nconst stringRecord = (value: unknown): Record<string, string> => {\n if (!value || typeof value !== 'object' || Array.isArray(value)) return {}\n const out: Record<string, string> = {}\n for (const [key, entry] of Object.entries(value as Record<string, unknown>)) if (typeof entry === 'string') out[key] = entry\n return out\n}\n\nconst favoritesOf = (value: unknown): FavoritesState => {\n if (!value || typeof value !== 'object' || Array.isArray(value)) return DEFAULT_FAVORITES\n const raw = value as { tools?: unknown; visible?: unknown; position?: unknown }\n const tools = Array.isArray(raw.tools) ? raw.tools.filter((t): t is string => typeof t === 'string').slice(0, MAX_FAVORITE_TOOLS) : []\n const p = raw.position as { x?: unknown; y?: unknown } | null | undefined\n const position = p && typeof p.x === 'number' && typeof p.y === 'number' ? { x: p.x, y: p.y } : null\n return { tools, visible: bool(raw.visible, DEFAULT_FAVORITES.visible), position }\n}\n\n/** Read a stored record. TOTAL: anything unreadable, and any field that is missing or not what it\n * claims, falls back to its default rather than throwing. A preference document is the one piece\n * of state a chart must never fail to open on. */\nexport function parseDrawingPreferences(raw: string | null | undefined): DrawingPreferences {\n let parsed: unknown = null\n try {\n parsed = JSON.parse(raw ?? 'null')\n } catch {\n parsed = null\n }\n if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) return DEFAULT_DRAWING_PREFERENCES\n const value = parsed as Record<string, unknown>\n return {\n cursor: oneOf(value.cursor, CURSOR_MODES, DEFAULT_DRAWING_PREFERENCES.cursor),\n magnet: oneOf(value.magnet, ['off', 'weak', 'strong'] as const, DEFAULT_DRAWING_PREFERENCES.magnet),\n magnetStrength: oneOf(value.magnetStrength, ['weak', 'strong'] as const, DEFAULT_DRAWING_PREFERENCES.magnetStrength),\n stayInDrawingMode: bool(value.stayInDrawingMode, DEFAULT_DRAWING_PREFERENCES.stayInDrawingMode),\n removeLocked: bool(value.removeLocked, DEFAULT_DRAWING_PREFERENCES.removeLocked),\n syncAcrossPanes: bool(value.syncAcrossPanes, DEFAULT_DRAWING_PREFERENCES.syncAcrossPanes),\n drawingToolbarTools: stringRecord(value.drawingToolbarTools),\n favorites: favoritesOf(value.favorites),\n settingsBarPosition: positionOf(value.settingsBarPosition),\n recentGlyphs: Array.isArray(value.recentGlyphs) ? value.recentGlyphs.filter((g): g is string => typeof g === 'string').slice(0, RECENT_GLYPHS_MAX) : [],\n recentColors: Array.isArray(value.recentColors) ? value.recentColors.filter((c): c is string => typeof c === 'string' && /^#[0-9a-f]{6}$/i.test(c)).slice(0, RECENT_COLOR_LIMIT) : [],\n }\n}\n\n/** Write a preference document. */\nexport function serializeDrawingPreferences(preferences: DrawingPreferences): string {\n return JSON.stringify(preferences)\n}\n\n/** The `ChartStorage` key the widget persists the record under, in the widget's own namespace\n * beside its symbol, timeframe and scale keys. */\nexport const DRAWING_PREFERENCES_KEY = 'quickcharts.drawingPrefs.v1'\n","// A tool's saved setup, in two kinds that look alike and behave nothing alike.\n//\n// DEFAULTS — the style and props every NEW drawing of a tool starts with. There is no save\n// control: the last edit to any drawing of that type becomes the default, silently,\n// and editing a default never touches drawings already on a chart. One per tool.\n// TEMPLATES — named snapshots a viewer applies on demand. Several per tool, each with a name the\n// viewer typed.\n//\n// Both ride the revisioned resource contract's `templates('drawing')` store rather than a store of\n// their own, so a host that keeps saved charts on a server keeps these there too, and two tabs\n// editing the same template get a typed conflict instead of a silent overwrite. A drawing template\n// carries its `tool`, which is what makes \"the templates for a trend line\" a filter rather than a\n// separate collection: a trend-line template is meaningless on a rectangle.\nimport type { DrawingStyle } from '../internal/drawings/index'\nimport type { ResourceRef, ResourceStore, TemplateBody, TemplateMeta, WriteOutcome } from '../resources'\n\n/** A saved tool setup: style and props partials layered over the tool's factory defaults. */\nexport interface ToolPreset {\n style?: Partial<DrawingStyle>\n props?: Record<string, unknown>\n}\n\n/** A named preset, as the picker lists it. */\nexport interface ToolTemplate extends ToolPreset {\n ref: ResourceRef\n name: string\n tool: string\n}\n\n/** The reserved template name that holds a tool's silent last-used DEFAULT. It is not shown in the\n * template list and cannot be typed: a name a viewer could collide with would let them overwrite\n * their defaults by saving a template. */\nexport const DEFAULT_PRESET_NAME = ''\n\nconst encode = (preset: ToolPreset): string => JSON.stringify(preset)\n\n/** Total: a body that will not parse reads as an empty preset, so one corrupt row never takes the\n * picker down with it. */\nexport function decodePreset(content: string): ToolPreset {\n try {\n const parsed: unknown = JSON.parse(content)\n if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) return {}\n const raw = parsed as { style?: unknown; props?: unknown }\n const preset: ToolPreset = {}\n if (raw.style && typeof raw.style === 'object' && !Array.isArray(raw.style)) preset.style = raw.style as Partial<DrawingStyle>\n if (raw.props && typeof raw.props === 'object' && !Array.isArray(raw.props)) preset.props = raw.props as Record<string, unknown>\n return preset\n } catch {\n return {}\n }\n}\n\n/** Whether a listing row is a tool's silent default rather than a named template. */\nconst isDefaultRow = (row: TemplateMeta): boolean => row.name === DEFAULT_PRESET_NAME\n\n/** How many template bodies `listAll` reads at a time. */\nconst BODY_READS = 6\n\n/** The drawing-template workflow over one `templates('drawing')` store. Every call takes the\n * caller's `AbortSignal`, so a closed dialog or a fast retype abandons in flight and a late answer\n * never lands. */\nexport class DrawingTemplates {\n constructor(private readonly store: ResourceStore<TemplateMeta, TemplateBody>) {}\n\n /** The named templates for one tool, in the store's order. The tool's silent default is not\n * among them. */\n async list(tool: string, signal?: AbortSignal): Promise<TemplateMeta[]> {\n const rows = await this.store.list(signal)\n return rows.filter((row) => row.tool === tool && !isDefaultRow(row))\n }\n\n /** Every row of the family, defaults included, each with its preset. A host that has to answer\n * synchronously (a placement path, a render) reads this once into a cache of its own rather\n * fetched: one read per saved setup, once, against a family a viewer keeps in the dozens. The\n * reads run together, `BODY_READS` at a time, and the answer keeps the store's order. */\n async listAll(signal?: AbortSignal): Promise<ToolTemplate[]> {\n const rows = await this.store.list(signal)\n const found: (Awaited<ReturnType<ResourceStore<TemplateMeta, TemplateBody>['load']>> | undefined)[] = new Array(rows.length)\n let next = 0\n const reader = async (): Promise<void> => {\n while (next < rows.length) {\n const at = next++\n found[at] = await this.store.load(rows[at]!.id, signal)\n }\n }\n await Promise.all(Array.from({ length: Math.min(BODY_READS, rows.length) }, reader))\n const out: ToolTemplate[] = []\n for (const one of found) {\n if (one) out.push({ ...decodePreset(one.body.content), ref: one.ref, name: one.body.name, tool: one.body.tool ?? '' })\n }\n return out\n }\n\n /** One template's preset. Null when the id is gone, which is what a picker shows after another\n * tab deleted it. */\n async load(id: string, signal?: AbortSignal): Promise<{ ref: ResourceRef; template: ToolTemplate } | null> {\n const found = await this.store.load(id, signal)\n if (!found) return null\n const preset = decodePreset(found.body.content)\n return { ref: found.ref, template: { ...preset, ref: found.ref, name: found.body.name, tool: found.body.tool ?? '' } }\n }\n\n /** Save a NAMED template. Saving over a name the tool already has REPLACES that row at the\n * revision the caller read, so two tabs saving the same name conflict rather than one silently\n * winning. A name the tool does not have creates a row. */\n async save(tool: string, name: string, preset: ToolPreset, signal?: AbortSignal): Promise<WriteOutcome<TemplateMeta>> {\n const body: TemplateBody = { name, tool, content: encode(preset) }\n const rows = await this.store.list(signal)\n const existing = rows.find((row) => row.tool === tool && row.name === name)\n if (!existing) return this.store.create(body, signal)\n const found = await this.store.load(existing.id, signal)\n if (!found) return this.store.create(body, signal)\n return this.store.update(found.ref, body, signal)\n }\n\n async remove(ref: ResourceRef, signal?: AbortSignal): Promise<WriteOutcome<void>> {\n return this.store.remove(ref, signal)\n }\n\n /** A tool's silent last-used default, or an empty preset when it has none. */\n async defaultFor(tool: string, signal?: AbortSignal): Promise<ToolPreset> {\n const rows = await this.store.list(signal)\n const row = rows.find((r) => r.tool === tool && isDefaultRow(r))\n if (!row) return {}\n const found = await this.store.load(row.id, signal)\n return found ? decodePreset(found.body.content) : {}\n }\n\n /** Remember a tool's default. This runs after an ordinary style edit, so a CONFLICT here is not\n * worth surfacing: another surface already wrote a newer default and the viewer's next edit\n * writes again. It is returned rather than swallowed so a caller may still look. */\n async rememberDefault(tool: string, preset: ToolPreset, signal?: AbortSignal): Promise<WriteOutcome<TemplateMeta>> {\n return this.save(tool, DEFAULT_PRESET_NAME, preset, signal)\n }\n\n /** Forget a tool's default, so new drawings of it start from the factory style again. */\n async clearDefault(tool: string, signal?: AbortSignal): Promise<WriteOutcome<void> | null> {\n const rows = await this.store.list(signal)\n const row = rows.find((r) => r.tool === tool && isDefaultRow(r))\n if (!row) return null\n const found = await this.store.load(row.id, signal)\n if (!found) return null\n return this.store.remove(found.ref, signal)\n }\n}\n","// Host image intake and an optional replacement for the chart's bundled emoji artwork.\nimport type { ChartMessageKey } from '../i18n/en'\n\n/** What the intake accepts. Stated here because it is a product rule, not a host preference: a\n * drawing is persisted with its picture inline, so an unbounded image is an unbounded saved chart. */\nexport const IMAGE_MAX_BYTES = 2 * 1024 * 1024\n/** Longest edge, in pixels. A larger picture is downscaled rather than refused. */\nexport const IMAGE_MAX_EDGE = 2000\nexport const IMAGE_TYPES: readonly string[] = ['image/jpeg', 'image/png']\n/** The `accept` attribute for a file input, kept beside the types it mirrors. */\nexport const IMAGE_ACCEPT = 'image/jpeg,image/png'\n\n/** Why an intake failed. A CODE, not a sentence: the host renders it through the catalog, so the\n * reason reaches a viewer in their own language and no English lives in the port. */\nexport type ImageIntakeError = 'wrong-type' | 'too-large' | 'unreadable' | 'undecodable'\n\n/** The catalog message each code says. `too-large` carries the picked file's size in its slot. */\nexport const IMAGE_ERROR_MESSAGES: Readonly<Record<ImageIntakeError, ChartMessageKey>> = {\n 'wrong-type': 'drawing.imageErrorType',\n 'too-large': 'drawing.imageErrorSize',\n unreadable: 'drawing.imageErrorRead',\n undecodable: 'drawing.imageErrorDecode',\n}\n\n/** A picture that is ready to store on a drawing. */\nexport interface ImageAsset {\n /** A data URL sized within the caps. */\n dataUrl: string\n width: number\n height: number\n /** The picture was larger than the edge cap and had to be resampled. */\n downscaled: boolean\n}\n\nexport type ImageIntakeResult = { ok: true; asset: ImageAsset } | { ok: false; error: ImageIntakeError; bytes?: number }\n\n/** What the host supplies so the image and glyph tools can draw. */\nexport interface DrawingAssetPort {\n /** Validate a picked file and turn it into a payload within the caps, or say why it cannot be\n * used. The host owns the decode and the resample; `checkImageFile` and `fitScale` below are the\n * library's rules it applies. */\n intakeImage(file: File): Promise<ImageIntakeResult>\n /** Optional replacement for the bundled Twemoji artwork. Artwork for one emoji or sticker glyph, as a URL the canvas can draw, or null to fall back to\n * drawing the glyph as text. Icon marks always stay text: their ink is tinted by the stroke\n * color, which artwork cannot carry. */\n glyphSource?(glyph: string): string | null\n}\n\n/** Type and size gate, pure so it needs no DOM and no real file. */\nexport function checkImageFile(file: { type: string; size: number }): { error: ImageIntakeError; bytes?: number } | null {\n if (!IMAGE_TYPES.includes(file.type)) return { error: 'wrong-type' }\n if (file.size > IMAGE_MAX_BYTES) return { error: 'too-large', bytes: file.size }\n return null\n}\n\n/** The scale that brings a picture inside the edge cap. 1 when it already fits, so a small picture\n * is never resampled and never loses a pixel it did not have to. */\nexport function fitScale(width: number, height: number, maxEdge = IMAGE_MAX_EDGE): number {\n const longest = Math.max(width, height)\n return longest > maxEdge ? maxEdge / longest : 1\n}\n\n/** The pixel size a picture is resampled to. */\nexport function fittedSize(width: number, height: number, maxEdge = IMAGE_MAX_EDGE): { width: number; height: number } {\n const scale = fitScale(width, height, maxEdge)\n return { width: Math.max(1, Math.round(width * scale)), height: Math.max(1, Math.round(height * scale)) }\n}\n","// Per-tool SETTINGS CAPABILITY sets: one place to answer \"does this tool have a fill?\", \"does it\n// have a stroke at all?\", and \"which of its props deserve a control?\".\n//\n// These are facts about what a tool paints, so they belong beside the tools rather than inside the\n// surface that renders their controls. A settings dialog and a floating bar reading the same sets\n// cannot disagree about whether a tool has a background, and a tool that gains a fill gains its\n// control everywhere at once.\n\n/** Tools whose paint has a fillable region — they get the Background color/opacity controls. */\nexport const FILLABLE: ReadonlySet<string> = new Set([\n 'rectangle',\n 'rotated_rectangle',\n 'ellipse',\n 'circle',\n 'triangle',\n 'polyline',\n 'parallel_channel',\n 'flat_top_bottom',\n 'disjoint_channel',\n 'price_range',\n 'date_range',\n 'date_and_price_range',\n 'xabcd_pattern',\n 'cypher_pattern',\n 'triangle_pattern',\n 'head_and_shoulders',\n 'time_cycles',\n 'sector',\n 'comment',\n 'callout',\n 'price_label',\n 'table',\n 'arc',\n 'brush',\n 'curve',\n 'double_curve',\n])\n\n/** No stroke channel at all (glyph/image marks; ghost feed and the volume profiles carry their\n * own color props; the text tool's ink is its text channel) — no color/width/line-style\n * controls. */\nexport const NO_STROKE: ReadonlySet<string> = new Set([\n 'emoji',\n 'sticker',\n 'image',\n 'ghost_feed',\n 'fixed_range_volume_profile',\n 'anchored_volume_profile',\n 'text',\n 'long_position',\n 'short_position',\n 'callout',\n 'comment',\n 'price_label',\n])\n\n/** Stroke color applies but width/line-style don't (sized by their own geometry or fixed ink,\n * or the color paints a border whose thickness is fixed). */\nexport const NO_LINE_DECOR: ReadonlySet<string> = new Set([\n 'arrow_marker',\n 'bars_pattern',\n 'icon',\n 'arrow_up',\n 'arrow_down',\n 'callout',\n 'comment',\n 'note',\n 'table',\n 'signpost',\n])\n\n/** Annotation text tools: no Style tab at all — color/size/weight/background/border live on the\n * Text tab (border applies where the tool draws one). */\nexport const NO_STYLE_TAB: ReadonlySet<string> = new Set(['text', 'note', 'comment', 'callout'])\n\n/** Tools that write words of their own and carry none of the viewer's: a plan's target, P&L and\n * stop tags. Their bar offers the text colour, because those words take it, and nothing that\n * belongs to a free label: no font size, and no invitation on the canvas to add text. */\nexport const OWN_WORDS_TOOLS: ReadonlySet<string> = new Set(['long_position', 'short_position'])\n\n/** Tools whose floating bar carries a font-size control (their ink is type, not lines). */\nexport const FONT_TOOLS: ReadonlySet<string> = new Set(['text', 'note', 'comment', 'callout', 'table', 'price_label', 'signpost'])\n\n/** Pattern/wave tools with circled vertex labels — the Style tab gets a Label styling row. */\nexport const LABELED_PATTERNS: ReadonlySet<string> = new Set([\n 'xabcd_pattern',\n 'cypher_pattern',\n 'abcd_pattern',\n 'triangle_pattern',\n 'head_and_shoulders',\n 'three_drives',\n 'elliott_impulse_wave',\n 'elliott_correction',\n 'elliott_triangle_wave',\n 'elliott_double_combo',\n 'elliott_triple_combo',\n])\n\n/** Prop keys a tool carries (via a shared props type) but whose paint ignores them — their rows\n * stay hidden so the modal never shows a control that does nothing. */\nexport const INERT_PROPS: Record<string, readonly string[]> = {\n fib_timezone: ['showPrices', 'reverse', 'extendLeft', 'background'],\n fib_trend_time: ['showPrices', 'reverse', 'extendLeft', 'background'],\n fib_speed_resist_arcs: ['showPrices', 'reverse', 'extendLeft'],\n fib_circles: ['showPrices', 'reverse', 'extendLeft'],\n}\n\n/** Tools whose anchors are time-only — the Coordinates tab hides the price field. */\nexport const BAR_ONLY_COORDS: ReadonlySet<string> = new Set([\n 'vertical_line',\n 'regression_trend',\n 'fixed_range_volume_profile',\n 'anchored_volume_profile',\n])\n\n/** Width applies but the stroke is always solid — no line-style control (marker ink). */\n/** A colour a tool paints that is none of the three every drawing may have. A plan paints two\n * zones, and a reader tells them apart by what the glyph says as much as by where it sits, so a\n * channel names its own mark. The pick writes the tool's own PROP, not the shared style. */\nexport interface ToolColorChannel {\n /** The prop the pick writes. */\n prop: string\n /** The mark the button wears, from the settings bar's own glyph set. */\n icon: 'pencil16' | 'bucket' | 'textTee'\n /** The catalog key naming it. */\n label: string\n}\n\n/** The extra colours a tool offers, in the order its bar shows them. A tool absent here offers\n * only the stroke, fill and text every drawing may carry. */\nexport const TOOL_COLOR_CHANNELS: Record<string, readonly ToolColorChannel[]> = {\n long_position: [\n { prop: 'profitColor', icon: 'bucket', label: 'drawing.profitColor' },\n { prop: 'stopColor', icon: 'bucket', label: 'drawing.stopColor' },\n ],\n short_position: [\n { prop: 'profitColor', icon: 'bucket', label: 'drawing.profitColor' },\n { prop: 'stopColor', icon: 'bucket', label: 'drawing.stopColor' },\n ],\n}\n\nexport const NO_DASH: ReadonlySet<string> = new Set(['highlighter', 'brush', 'price_range', 'date_range', 'date_and_price_range'])\n\n/** Prop keys that belong on a separate Inputs tab: what a drawing computes with, kept apart from\n * how it looks.\n * A tool listed here gets the Inputs tab; unlisted props stay on Style. */\nexport const INPUT_PROPS: Record<string, readonly string[]> = {\n fixed_range_volume_profile: ['rowsLayout', 'rowSize', 'volume', 'valueAreaVolume', 'extendRight'],\n anchored_volume_profile: ['rowsLayout', 'rowSize', 'volume', 'valueAreaVolume'],\n ghost_feed: ['averageHL', 'variance'],\n long_position: ['accountSize', 'risk', 'riskDisplay', 'lotSize', 'leverage', 'compact'],\n short_position: ['accountSize', 'risk', 'riskDisplay', 'lotSize', 'leverage', 'compact'],\n regression_trend: ['upperDeviation', 'lowerDeviation', 'useUpper', 'useLower', 'source'],\n}\n"],"mappings":"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","names":["box","hitTolerance","box","inBox","hitTolerance","hitTolerance","hitTolerance","box","hitTolerance","hitTolerance","hitTolerance","hitTolerance","hitTolerance","inBox","box","restoreDrawings","catalog","tool","tool","tool","a","el","box","box","box","tool"]}
|