@trdrs/quickcharts 1.2.0 → 2.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 +120 -0
- package/README.md +742 -180
- package/dist/adapters/rest.d.ts +3 -3
- package/dist/adapters/rest.js +2 -2
- package/dist/adapters/rest.js.map +1 -1
- package/dist/{ar-G7MVXRE4.js → ar-KSXQ2USS.js} +20 -20
- package/dist/ar-KSXQ2USS.js.map +1 -0
- package/dist/{assets-ySndlUS3.d.ts → assets-DOuBBsOp.d.ts} +50 -50
- package/dist/{ca_ES-EUSRU4VG.js → ca_ES-JG4FM55E.js} +20 -20
- package/dist/ca_ES-JG4FM55E.js.map +1 -0
- package/dist/{chunk-RDAK5MUM.js → chunk-6S6TO2N6.js} +41 -37
- package/dist/chunk-6S6TO2N6.js.map +1 -0
- package/dist/{chunk-KFBQSPNA.js → chunk-D3S26ARP.js} +2 -2
- package/dist/chunk-D3S26ARP.js.map +1 -0
- package/dist/{chunk-AKXIFHQN.js → chunk-KLPTCWA2.js} +1 -1
- package/dist/{chunk-AKXIFHQN.js.map → chunk-KLPTCWA2.js.map} +1 -1
- package/dist/{de-2SVTG25S.js → de-VSW2LHNF.js} +20 -20
- package/dist/de-VSW2LHNF.js.map +1 -0
- package/dist/drawings.d.ts +16 -16
- package/dist/drawings.js +12 -12
- package/dist/{es-UDHZM4W7.js → es-5ZXIPVOB.js} +20 -20
- package/dist/es-5ZXIPVOB.js.map +1 -0
- package/dist/feature-manifest.json +51 -3
- package/dist/{fr-35VN4G4S.js → fr-4F6DAWGD.js} +20 -20
- package/dist/fr-4F6DAWGD.js.map +1 -0
- package/dist/{he_IL-JPZMCURP.js → he_IL-B7PBQUEV.js} +20 -20
- package/dist/he_IL-B7PBQUEV.js.map +1 -0
- package/dist/{id_ID-XSTFHHJQ.js → id_ID-CYJRMXPC.js} +20 -20
- package/dist/id_ID-CYJRMXPC.js.map +1 -0
- package/dist/index.d.ts +599 -225
- package/dist/index.js +10110 -9106
- package/dist/index.js.map +1 -1
- package/dist/{it-EIY6JESQ.js → it-KTX4SG5P.js} +20 -20
- package/dist/it-KTX4SG5P.js.map +1 -0
- package/dist/{ja-42N4XRCW.js → ja-V7OURU5D.js} +20 -20
- package/dist/ja-V7OURU5D.js.map +1 -0
- package/dist/{ko-3VRPTIP3.js → ko-2RNEBYVE.js} +20 -20
- package/dist/ko-2RNEBYVE.js.map +1 -0
- package/dist/{ms_MY-SKN7O6M5.js → ms_MY-EY235E7Q.js} +20 -20
- package/dist/ms_MY-EY235E7Q.js.map +1 -0
- package/dist/{pl-TYARHCLT.js → pl-ADNVRP55.js} +20 -20
- package/dist/pl-ADNVRP55.js.map +1 -0
- package/dist/{pt-72IIFLL4.js → pt-OL2DR3DO.js} +20 -20
- package/dist/pt-OL2DR3DO.js.map +1 -0
- package/dist/quickcharts.css +218 -205
- package/dist/{resources-Ch8eA1Mw.d.ts → resources-Le6flcEn.d.ts} +3 -3
- package/dist/rest-openapi.json +11 -11
- package/dist/{ru-TPH4F7IB.js → ru-V6YFEPAF.js} +20 -20
- package/dist/ru-V6YFEPAF.js.map +1 -0
- package/dist/{sv-DC5RS67Z.js → sv-TORXQVE7.js} +20 -20
- package/dist/sv-TORXQVE7.js.map +1 -0
- package/dist/{th-I6H6AOZ3.js → th-K6SJSYSY.js} +20 -20
- package/dist/th-K6SJSYSY.js.map +1 -0
- package/dist/theme-manifest.json +99 -11
- package/dist/{tr-7FSUVCNW.js → tr-4AEM66KW.js} +20 -20
- package/dist/tr-4AEM66KW.js.map +1 -0
- package/dist/{vi-DLRPHLLH.js → vi-YU5XCEUU.js} +20 -20
- package/dist/vi-YU5XCEUU.js.map +1 -0
- package/dist/{zh-ZXIQBBEP.js → zh-QXKRYHU5.js} +20 -20
- package/dist/zh-QXKRYHU5.js.map +1 -0
- package/dist/{zh_TW-TYNUJU7U.js → zh_TW-AYPDKG4Q.js} +20 -20
- package/dist/zh_TW-AYPDKG4Q.js.map +1 -0
- package/package.json +1 -1
- package/dist/ar-G7MVXRE4.js.map +0 -1
- package/dist/ca_ES-EUSRU4VG.js.map +0 -1
- package/dist/chunk-KFBQSPNA.js.map +0 -1
- package/dist/chunk-RDAK5MUM.js.map +0 -1
- package/dist/de-2SVTG25S.js.map +0 -1
- package/dist/es-UDHZM4W7.js.map +0 -1
- package/dist/fr-35VN4G4S.js.map +0 -1
- package/dist/he_IL-JPZMCURP.js.map +0 -1
- package/dist/id_ID-XSTFHHJQ.js.map +0 -1
- package/dist/it-EIY6JESQ.js.map +0 -1
- package/dist/ja-42N4XRCW.js.map +0 -1
- package/dist/ko-3VRPTIP3.js.map +0 -1
- package/dist/ms_MY-SKN7O6M5.js.map +0 -1
- package/dist/pl-TYARHCLT.js.map +0 -1
- package/dist/pt-72IIFLL4.js.map +0 -1
- package/dist/ru-TPH4F7IB.js.map +0 -1
- package/dist/sv-DC5RS67Z.js.map +0 -1
- package/dist/th-I6H6AOZ3.js.map +0 -1
- package/dist/tr-7FSUVCNW.js.map +0 -1
- package/dist/vi-DLRPHLLH.js.map +0 -1
- package/dist/zh-ZXIQBBEP.js.map +0 -1
- package/dist/zh_TW-TYNUJU7U.js.map +0 -1
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { al as en, C as ChartMessageKey, G as GlyphSourcePort, M as MagnetMode, d as CursorMode, L as LineStyle, I as IDrawing, m as DrawingCounts, D as DrawingStyle, Y as VisibilityPreset, U as ToolPreset, V as ToolTemplate, S as SerializedDrawing, o as DrawingPreferences, l as DrawingAssetPort } from './assets-
|
|
2
|
-
import { R as ResourceRef, C as ChartSaveLoadAdapter, q as ChartMeta, t as ChartBody, f as DrawingResourceContext, i as ResourceStore, u as DrawingsMeta, h as DrawingsBody, j as TemplateMeta, T as TemplateBody, v as LayoutMeta, w as LayoutBody, c as DrawingContextKind } from './resources-
|
|
3
|
-
export { a as ChartLocalDrawingContext, D as DRAWING_CONTEXT_VERSION, b as DRAWING_DOCUMENT_VERSION, d as DrawingEntry, e as DrawingGroup, g as DrawingTombstone, L as LayoutSharedDrawingContext, M as MemoryResourcesOptions, x as ResourceAbortError, S as SymbolGlobalDrawingContext, y as TemplateKind, W as WriteOutcome, k as drawingContextKey, l as emptyDrawingDocument, m as liveDrawingEntries, n as liveDrawingGroups, z as memorySaveLoadAdapter, o as mergeDrawingDocuments, p as parseDrawingDocument, r as reviseDrawingDocument, s as sameDrawingContext } from './resources-
|
|
1
|
+
import { al as en, C as ChartMessageKey, G as GlyphSourcePort, M as MagnetMode, d as CursorMode, L as LineStyle, I as IDrawing, m as DrawingCounts, D as DrawingStyle, Y as VisibilityPreset, U as ToolPreset, V as ToolTemplate, S as SerializedDrawing, o as DrawingPreferences, l as DrawingAssetPort } from './assets-DOuBBsOp.js';
|
|
2
|
+
import { R as ResourceRef, C as ChartSaveLoadAdapter, q as ChartMeta, t as ChartBody, f as DrawingResourceContext, i as ResourceStore, u as DrawingsMeta, h as DrawingsBody, j as TemplateMeta, T as TemplateBody, v as LayoutMeta, w as LayoutBody, c as DrawingContextKind } from './resources-Le6flcEn.js';
|
|
3
|
+
export { a as ChartLocalDrawingContext, D as DRAWING_CONTEXT_VERSION, b as DRAWING_DOCUMENT_VERSION, d as DrawingEntry, e as DrawingGroup, g as DrawingTombstone, L as LayoutSharedDrawingContext, M as MemoryResourcesOptions, x as ResourceAbortError, S as SymbolGlobalDrawingContext, y as TemplateKind, W as WriteOutcome, k as drawingContextKey, l as emptyDrawingDocument, m as liveDrawingEntries, n as liveDrawingGroups, z as memorySaveLoadAdapter, o as mergeDrawingDocuments, p as parseDrawingDocument, r as reviseDrawingDocument, s as sameDrawingContext } from './resources-Le6flcEn.js';
|
|
4
4
|
import { LineData, UTCTimestamp, HistogramData, WhitespaceData, IChartApi, ISeriesApi, CreatePriceLineOptions, PriceLineOptions, ISeriesPrimitive, Time, PriceScaleMode, SeriesType, SeriesAttachedParameter, TickMarkType } from 'lightweight-charts';
|
|
5
5
|
|
|
6
6
|
/** How one symbol's prices are WRITTEN, in five facts. Together they express
|
|
@@ -147,15 +147,15 @@ interface FeedBar {
|
|
|
147
147
|
c: number;
|
|
148
148
|
v: number;
|
|
149
149
|
}
|
|
150
|
-
/** A symbol-search result row. `
|
|
151
|
-
* a row names
|
|
150
|
+
/** A symbol-search result row. `exchange` names the venue the market lists on. `dataSource` names
|
|
151
|
+
* where the market's data comes from, and a row names one only when that source publishes the
|
|
152
|
+
* symbol's data. The row's source cell shows the venue, or the data source for a row with none. */
|
|
152
153
|
interface SymbolRow {
|
|
153
154
|
symbol: string;
|
|
154
155
|
name: string;
|
|
155
156
|
exchange: string;
|
|
156
157
|
type: string;
|
|
157
|
-
|
|
158
|
-
via?: string | null;
|
|
158
|
+
dataSource?: string | null;
|
|
159
159
|
/** What the market is priced in, when the feed knows it here. A PAIR market writes itself as
|
|
160
160
|
* `BASE / QUOTE` wherever it is named, and a ticker alone cannot say what the quote is; a row
|
|
161
161
|
* without it keeps the name the feed sent instead. `resolve()` states the same fact for the
|
|
@@ -217,24 +217,47 @@ interface SubscribeHandlers {
|
|
|
217
217
|
* (the chart shows "market data unavailable" and closes the live subscription), unlike a transient
|
|
218
218
|
* fetch failure which is retried. */
|
|
219
219
|
declare class FeedUnavailableError extends Error {
|
|
220
|
-
/** The server's typed refusal (e.g.
|
|
220
|
+
/** The server's typed refusal (e.g. not_entitled / feed_down),
|
|
221
221
|
* when it sent one — lets the host name the actual cause instead of a generic "unavailable". */
|
|
222
222
|
readonly code: string | null;
|
|
223
223
|
constructor(message?: string,
|
|
224
|
-
/** The server's typed refusal (e.g.
|
|
224
|
+
/** The server's typed refusal (e.g. not_entitled / feed_down),
|
|
225
225
|
* when it sent one — lets the host name the actual cause instead of a generic "unavailable". */
|
|
226
226
|
code?: string | null);
|
|
227
227
|
}
|
|
228
|
+
/** One class in a feed's catalog that holds narrower classes: a `spot` class over its `usdc` and
|
|
229
|
+
* `usdt` quotes, say. `id` is the token the feed is searched with, as a plain string entry is, and
|
|
230
|
+
* `children` are the narrower classes, as tokens or nodes of their own. The search renders two
|
|
231
|
+
* levels, a top-level class and its children: a child's own `children` are not offered, and the
|
|
232
|
+
* child narrows by its `id` alone. */
|
|
233
|
+
interface SearchClassNode {
|
|
234
|
+
readonly id: string;
|
|
235
|
+
readonly children?: readonly (string | SearchClassNode)[];
|
|
236
|
+
}
|
|
237
|
+
/** What a feed's `search` is asked with. `cls` and `classes` say which classes to narrow to; both
|
|
238
|
+
* absent is every class. */
|
|
239
|
+
interface DatafeedSearchOptions {
|
|
240
|
+
/** One class to narrow to. When the viewer may select several classes it is set only while
|
|
241
|
+
* exactly one is selected, so a feed that reads `cls` alone still narrows a single chip. */
|
|
242
|
+
cls?: string;
|
|
243
|
+
/** Every class to narrow to, sent only when the search lets the viewer select several classes at
|
|
244
|
+
* once: a row matches when it is in any of them. A feed may ignore it and read `cls` alone. */
|
|
245
|
+
classes?: readonly string[];
|
|
246
|
+
limit?: number;
|
|
247
|
+
offset?: number;
|
|
248
|
+
}
|
|
228
249
|
/** A feed's coarse, feed-LEVEL capability declaration. Everything optional and the method itself
|
|
229
|
-
* optional: an ABSENT declaration means unconstrained
|
|
230
|
-
* declare what is true — a finite `resolutions` list from a feed that serves any
|
|
250
|
+
* optional: an ABSENT declaration means unconstrained, and a feed must only
|
|
251
|
+
* declare what is true — a finite `resolutions` list from a feed that serves any timeframe would
|
|
231
252
|
* be a lie the chart then enforces. Symbol-level truth (price format, resolutions, session) stays
|
|
232
253
|
* on {@link SymbolInfo}. */
|
|
233
254
|
interface DatafeedConfig {
|
|
234
255
|
/** The wire timeframe tokens this feed can serve ('1m', '4h', '1d', …). Absent = any. */
|
|
235
256
|
resolutions?: readonly string[];
|
|
236
|
-
/** Asset-class tokens the catalog carries
|
|
237
|
-
|
|
257
|
+
/** Asset-class tokens the catalog carries, in the order the search offers them. An entry is a
|
|
258
|
+
* token, or a {@link SearchClassNode} whose children the search offers beneath it once it is
|
|
259
|
+
* selected. Absent = unspecified. */
|
|
260
|
+
classes?: readonly (string | SearchClassNode)[];
|
|
238
261
|
}
|
|
239
262
|
/** The datafeed a chart consumes. Implementations must follow the bar rules on {@link FeedBar} and
|
|
240
263
|
* {@link BarsEvent}; everything else (transport, caching, auth) is the implementation's business. */
|
|
@@ -243,12 +266,9 @@ interface ChartDatafeed {
|
|
|
243
266
|
* feed declares (e.g. its initial timeframe must be servable). Omit it entirely when the feed
|
|
244
267
|
* has no fixed capability set. */
|
|
245
268
|
config?(): Promise<DatafeedConfig>;
|
|
246
|
-
/** Server-side symbol search, paged. `cls` narrows to one asset class ('' / absent = all)
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
limit?: number;
|
|
250
|
-
offset?: number;
|
|
251
|
-
}): Promise<SearchPage>;
|
|
269
|
+
/** Server-side symbol search, paged. `cls` narrows to one asset class ('' / absent = all), and
|
|
270
|
+
* `classes`, when present, to any of several (see {@link DatafeedSearchOptions}). */
|
|
271
|
+
search(q: string, opts?: DatafeedSearchOptions): Promise<SearchPage>;
|
|
252
272
|
/** Resolve one symbol's metadata; null when the symbol is unknown to the feed's catalogs. */
|
|
253
273
|
resolve(symbol: string): Promise<SymbolInfo | null>;
|
|
254
274
|
/** Historical sealed bars: a [from,to] window (epoch seconds, INCLUSIVE of both ends — the chart
|
|
@@ -274,7 +294,7 @@ interface ChartDatafeed {
|
|
|
274
294
|
earliestBar?(symbol: string): Promise<number | null>;
|
|
275
295
|
/** OPTIONAL neutral bar marks over a window (epoch seconds, inclusive of both ends). A mark is a
|
|
276
296
|
* note about a moment: its color is a theme role, its words are the host's, and the chart
|
|
277
|
-
*
|
|
297
|
+
* draws it as given. Omit it entirely when the feed serves none. */
|
|
278
298
|
marks?(symbol: string, from: number, to: number, resolution: string): Promise<readonly BarMark[]>;
|
|
279
299
|
/** OPTIONAL neutral time-scale marks over the same window. */
|
|
280
300
|
timescaleMarks?(symbol: string, from: number, to: number, resolution: string): Promise<readonly TimescaleMark[]>;
|
|
@@ -360,8 +380,7 @@ interface LocaleDefinition<Code extends string = string> {
|
|
|
360
380
|
type ChartLocaleCode = 'en' | 'de' | 'fr' | 'es' | 'it' | 'ca_ES' | 'pl' | 'sv' | 'tr' | 'ru' | 'pt' | 'id_ID' | 'ms_MY' | 'th' | 'vi' | 'ja' | 'ko' | 'zh' | 'zh_TW' | 'ar' | 'he_IL';
|
|
361
381
|
type ChartLocale = LocaleDefinition<ChartLocaleCode>;
|
|
362
382
|
/** English first, then the Latin-script languages, then the others. Endonyms let every reader find
|
|
363
|
-
* their own language in a picker. `scripts/i18n.mjs` reads this table by its line shape
|
|
364
|
-
* `scripts/test/i18n-inventory.test.ts` pins it equal to the app runtime's inventory. */
|
|
383
|
+
* their own language in a picker. `scripts/i18n.mjs` reads this table by its line shape. */
|
|
365
384
|
declare const BUILT_IN_LOCALES: readonly ChartLocale[];
|
|
366
385
|
|
|
367
386
|
type PluralCategory = 'zero' | 'one' | 'two' | 'few' | 'many' | 'other';
|
|
@@ -579,7 +598,7 @@ declare const chartDictionaries: DictionaryLoader<{
|
|
|
579
598
|
readonly 'command.drawingBringForward': "Bring drawing forward";
|
|
580
599
|
readonly 'command.drawingSendBackward': "Send drawing backward";
|
|
581
600
|
readonly 'command.drawingHideSelected': "Hide drawing";
|
|
582
|
-
readonly 'command.drawingVisibility': "Drawing visibility on
|
|
601
|
+
readonly 'command.drawingVisibility': "Drawing visibility on timeframes";
|
|
583
602
|
readonly 'command.drawingSettings': "Drawing settings";
|
|
584
603
|
readonly 'command.drawingCommitEdit': "Apply drawing settings";
|
|
585
604
|
readonly 'command.drawingPlaceImage': "Place image";
|
|
@@ -603,7 +622,7 @@ declare const chartDictionaries: DictionaryLoader<{
|
|
|
603
622
|
readonly 'command.replayStepBack': "Step back";
|
|
604
623
|
readonly 'command.replayGoLive': "Replay to the live edge";
|
|
605
624
|
readonly 'command.replaySpeed': "Replay speed";
|
|
606
|
-
readonly 'command.
|
|
625
|
+
readonly 'command.replayTimeframe': "Replay update timeframe";
|
|
607
626
|
readonly 'command.timeframeSet': "Timeframe";
|
|
608
627
|
readonly 'command.subsessionRegular': "Regular hours";
|
|
609
628
|
readonly 'command.subsessionExtended': "Extended hours";
|
|
@@ -732,7 +751,7 @@ declare const chartDictionaries: DictionaryLoader<{
|
|
|
732
751
|
readonly 'drawing.more': "More";
|
|
733
752
|
readonly 'drawing.moreActions': "More drawing actions";
|
|
734
753
|
readonly 'drawing.visualOrder': "Visual order";
|
|
735
|
-
readonly 'drawing.
|
|
754
|
+
readonly 'drawing.visibilityOnTimeframes': "Visibility on timeframes";
|
|
736
755
|
readonly 'drawing.clone': "Clone";
|
|
737
756
|
readonly 'drawing.copy': "Copy";
|
|
738
757
|
readonly 'drawing.modifierControl': "Ctrl";
|
|
@@ -754,10 +773,10 @@ declare const chartDictionaries: DictionaryLoader<{
|
|
|
754
773
|
readonly 'drawing.sendToBack': "Send to back";
|
|
755
774
|
readonly 'drawing.bringForward': "Bring forward";
|
|
756
775
|
readonly 'drawing.sendBackward': "Send backward";
|
|
757
|
-
readonly 'drawing.visCurrentAndAbove': "Current
|
|
758
|
-
readonly 'drawing.visCurrentAndBelow': "Current
|
|
759
|
-
readonly 'drawing.visCurrentOnly': "Current
|
|
760
|
-
readonly 'drawing.visAll': "All
|
|
776
|
+
readonly 'drawing.visCurrentAndAbove': "Current timeframe and above";
|
|
777
|
+
readonly 'drawing.visCurrentAndBelow': "Current timeframe and below";
|
|
778
|
+
readonly 'drawing.visCurrentOnly': "Current timeframe only";
|
|
779
|
+
readonly 'drawing.visAll': "All timeframes";
|
|
761
780
|
readonly 'drawing.saveTemplate': "Save drawing template";
|
|
762
781
|
readonly 'drawing.templateName': "Template name";
|
|
763
782
|
readonly 'drawing.save': "Save";
|
|
@@ -916,7 +935,7 @@ declare const chartDictionaries: DictionaryLoader<{
|
|
|
916
935
|
readonly 'drawing.unitDays': "Days";
|
|
917
936
|
readonly 'drawing.unitWeeks': "Weeks";
|
|
918
937
|
readonly 'drawing.unitMonths': "Months";
|
|
919
|
-
readonly 'drawing.
|
|
938
|
+
readonly 'drawing.timeframePinnedNote': "A drawing stays on at least one timeframe, so it can always be reached again.";
|
|
920
939
|
readonly 'drawing.colorSwatch': "Color {hex}";
|
|
921
940
|
readonly 'drawing.customColor': "Custom color";
|
|
922
941
|
readonly 'drawing.saturationValue': "Saturation and brightness";
|
|
@@ -1025,7 +1044,7 @@ declare const chartDictionaries: DictionaryLoader<{
|
|
|
1025
1044
|
readonly 'range.oneYear': "1 Year";
|
|
1026
1045
|
readonly 'range.fiveYears': "5 Years";
|
|
1027
1046
|
readonly 'range.all': "All data";
|
|
1028
|
-
readonly 'range.tip': "{range} · {
|
|
1047
|
+
readonly 'range.tip': "{range} · {timeframe} bars";
|
|
1029
1048
|
readonly 'range.zoomIn': "Zoom in";
|
|
1030
1049
|
readonly 'range.zoomOut': "Zoom out";
|
|
1031
1050
|
readonly 'range.scrollLeft': "Scroll left";
|
|
@@ -1193,17 +1212,17 @@ declare const chartDictionaries: DictionaryLoader<{
|
|
|
1193
1212
|
readonly 'layouts.arrangement': "Chart arrangement";
|
|
1194
1213
|
readonly 'layouts.syncInLayout': "Sync in layout";
|
|
1195
1214
|
readonly 'layouts.syncSymbol': "Symbol";
|
|
1196
|
-
readonly 'layouts.
|
|
1215
|
+
readonly 'layouts.syncTimeframe': "Timeframe";
|
|
1197
1216
|
readonly 'layouts.syncCrosshair': "Crosshair";
|
|
1198
1217
|
readonly 'layouts.syncTime': "Time";
|
|
1199
1218
|
readonly 'layouts.syncDateRange': "Date range";
|
|
1200
1219
|
readonly 'layouts.syncSymbolTip': "Symbol changes on all charts within the layout";
|
|
1201
|
-
readonly 'layouts.
|
|
1220
|
+
readonly 'layouts.syncTimeframeTip': "Timeframe changes on all charts within the layout";
|
|
1202
1221
|
readonly 'layouts.syncCrosshairTip': "Crosshair is synced across all charts within the layout";
|
|
1203
1222
|
readonly 'layouts.syncTimeTip': "When a chart is clicked, all charts within the layout display the same point of time";
|
|
1204
1223
|
readonly 'layouts.syncDateRangeTip': "Date range changes on all charts within the layout";
|
|
1205
1224
|
readonly 'layouts.syncSymbolToggle': "Sync symbol";
|
|
1206
|
-
readonly 'layouts.
|
|
1225
|
+
readonly 'layouts.syncTimeframeToggle': "Sync timeframe";
|
|
1207
1226
|
readonly 'layouts.syncCrosshairToggle': "Sync crosshair";
|
|
1208
1227
|
readonly 'layouts.syncTimeToggle': "Sync time";
|
|
1209
1228
|
readonly 'layouts.syncDateRangeToggle': "Sync date range";
|
|
@@ -1235,7 +1254,7 @@ declare const chartDictionaries: DictionaryLoader<{
|
|
|
1235
1254
|
readonly 'layouts.loading': "Loading";
|
|
1236
1255
|
readonly 'layouts.emptyNone': "No saved layouts yet.";
|
|
1237
1256
|
readonly 'layouts.openLayoutRow': "Open layout…";
|
|
1238
|
-
readonly 'layouts.listingFacts': "{symbol}, {
|
|
1257
|
+
readonly 'layouts.listingFacts': "{symbol}, {timeframe}";
|
|
1239
1258
|
readonly 'layouts.listingDated': "{facts} ({date})";
|
|
1240
1259
|
readonly 'layouts.dialogTitle': "Layouts";
|
|
1241
1260
|
readonly 'layouts.search': "Search";
|
|
@@ -1300,11 +1319,11 @@ declare const chartDictionaries: DictionaryLoader<{
|
|
|
1300
1319
|
readonly one: "1 update per {count} second";
|
|
1301
1320
|
readonly other: "1 update per {count} seconds";
|
|
1302
1321
|
};
|
|
1303
|
-
readonly 'replay.
|
|
1304
|
-
readonly 'replay.
|
|
1305
|
-
readonly 'replay.
|
|
1322
|
+
readonly 'replay.timeframe': "Update timeframe";
|
|
1323
|
+
readonly 'replay.timeframeHelp': "How much time each replay update advances. Finer than the chart timeframe, each bar forms from real finer bars.";
|
|
1324
|
+
readonly 'replay.timeframeNone': "No finer timeframe for this chart timeframe";
|
|
1306
1325
|
readonly 'replay.auto': "Auto";
|
|
1307
|
-
readonly 'replay.
|
|
1326
|
+
readonly 'replay.autoSelectTimeframe': "Auto select timeframe";
|
|
1308
1327
|
readonly 'menu.resetView': "Reset chart view";
|
|
1309
1328
|
readonly 'menu.copyPrice': "Copy price {price}";
|
|
1310
1329
|
readonly 'menu.paste': "Paste";
|
|
@@ -1413,8 +1432,8 @@ declare const chartDictionaries: DictionaryLoader<{
|
|
|
1413
1432
|
readonly 'legend.close': "C";
|
|
1414
1433
|
readonly 'legend.change': "{change} ({percent}%)";
|
|
1415
1434
|
readonly 'legend.indicatorSettings': "Indicator settings";
|
|
1416
|
-
readonly 'legend.showRows': "Show
|
|
1417
|
-
readonly 'legend.hideRows': "Hide
|
|
1435
|
+
readonly 'legend.showRows': "Show indicator rows";
|
|
1436
|
+
readonly 'legend.hideRows': "Hide indicator rows";
|
|
1418
1437
|
readonly 'legend.restorePane': "Restore pane";
|
|
1419
1438
|
readonly 'legend.collapsePane': "Collapse pane";
|
|
1420
1439
|
readonly 'legend.maximizePane': "Maximize pane";
|
|
@@ -1425,7 +1444,7 @@ declare const chartDictionaries: DictionaryLoader<{
|
|
|
1425
1444
|
readonly 'legend.scalePercent': "%";
|
|
1426
1445
|
readonly 'legend.scaleIndexed': "100";
|
|
1427
1446
|
readonly 'legend.changeSymbol': "Change symbol";
|
|
1428
|
-
readonly 'legend.removeCompare': "Remove
|
|
1447
|
+
readonly 'legend.removeCompare': "Remove comparison";
|
|
1429
1448
|
readonly 'legend.removeIndicator': "Remove indicator";
|
|
1430
1449
|
}, ChartLocaleCode>;
|
|
1431
1450
|
/** A drawing tool's display name for a registry `type`: the catalog's when it knows the type, else
|
|
@@ -1461,7 +1480,7 @@ interface PriceFormatterOptions {
|
|
|
1461
1480
|
interface PriceFormatter {
|
|
1462
1481
|
/** The price as the symbol writes it. */
|
|
1463
1482
|
format(price: number): string;
|
|
1464
|
-
/** The number a
|
|
1483
|
+
/** The number a viewer typed, or null when the text is not a price in this symbol's format. */
|
|
1465
1484
|
parse(text: string): number | null;
|
|
1466
1485
|
/** How many digits `format` writes after the decimal sign. 0 for a fractional format, which
|
|
1467
1486
|
* writes none; the widest band's width for a variable-tick format, so a column sized from it
|
|
@@ -1538,8 +1557,8 @@ declare const DEFAULT_SUBSESSION: ActiveSubsession;
|
|
|
1538
1557
|
declare function hasExtendedHours(model: SessionModel): boolean;
|
|
1539
1558
|
/** The bar filter for the active subsession: under `regular`, on a symbol with extended hours,
|
|
1540
1559
|
* keep the bars whose open falls in regular hours; otherwise nothing is filtered (null). For
|
|
1541
|
-
* intraday
|
|
1542
|
-
* intraday
|
|
1560
|
+
* intraday timeframes only: a daily bar spans whole sessions, so a caller applies the filter on
|
|
1561
|
+
* intraday timeframes and shows every daily bar. */
|
|
1543
1562
|
declare function subsessionBarFilter(model: SessionModel, active: ActiveSubsession): ((epochSecs: number) => boolean) | null;
|
|
1544
1563
|
/** The session state at an instant (epoch seconds), under the symbol's exchange clock. */
|
|
1545
1564
|
declare function sessionStateAt(model: SessionModel, epochSecs: number): SessionState;
|
|
@@ -1613,9 +1632,9 @@ type VenueMarkPainter = (request: {
|
|
|
1613
1632
|
host: HTMLElement;
|
|
1614
1633
|
size: number;
|
|
1615
1634
|
}) => (() => void) | void;
|
|
1616
|
-
/** Paints the mark of a data
|
|
1617
|
-
type
|
|
1618
|
-
|
|
1635
|
+
/** Paints the mark of a data source, where a row names a data source rather than a venue. */
|
|
1636
|
+
type DataSourceMarkPainter = (request: {
|
|
1637
|
+
dataSource: string;
|
|
1619
1638
|
host: HTMLElement;
|
|
1620
1639
|
size: number;
|
|
1621
1640
|
}) => (() => void) | void;
|
|
@@ -1623,7 +1642,7 @@ type ProviderMarkPainter = (request: {
|
|
|
1623
1642
|
interface MarkPainters {
|
|
1624
1643
|
readonly symbol: SymbolMarkPainter | null;
|
|
1625
1644
|
readonly venue: VenueMarkPainter | null;
|
|
1626
|
-
readonly
|
|
1645
|
+
readonly dataSource: DataSourceMarkPainter | null;
|
|
1627
1646
|
}
|
|
1628
1647
|
/** The host's hooks, as an entry point takes them. Each is the host's to lend or withhold, and
|
|
1629
1648
|
* every entry point that paints marks takes exactly these, so a host writes them once and hands
|
|
@@ -1631,7 +1650,7 @@ interface MarkPainters {
|
|
|
1631
1650
|
interface MarkPainterHooks {
|
|
1632
1651
|
/** The host's mark for a market, called WHEREVER the chart names one: each chart's legend, the
|
|
1633
1652
|
* compare rows under it, every row of the symbol search and compare dialogs, and the market tag
|
|
1634
|
-
*
|
|
1653
|
+
* an extension's notice wears. It receives the element to paint into and the symbol it stands for,
|
|
1635
1654
|
* and returns a disposer that takes the mark down again.
|
|
1636
1655
|
*
|
|
1637
1656
|
* One hook rather than one per surface, so a market wears the same mark everywhere it appears and
|
|
@@ -1643,9 +1662,9 @@ interface MarkPainterHooks {
|
|
|
1643
1662
|
* into and the size of the box, and returns a disposer; absent, a venue wears its initial on the
|
|
1644
1663
|
* neutral disc the package draws itself. */
|
|
1645
1664
|
venueMark?: VenueMarkPainter;
|
|
1646
|
-
/** The host's mark for the data
|
|
1647
|
-
* row's source cell the same way. Absent,
|
|
1648
|
-
|
|
1665
|
+
/** The host's mark for the data source a row names where it names no venue, painted in that
|
|
1666
|
+
* row's source cell the same way. Absent, a data source wears its initial on a neutral disc. */
|
|
1667
|
+
dataSourceMark?: DataSourceMarkPainter;
|
|
1649
1668
|
}
|
|
1650
1669
|
|
|
1651
1670
|
/** One glyph: its own grid and the inner markup drawn on it. */
|
|
@@ -1677,9 +1696,9 @@ interface ChartOverrides {
|
|
|
1677
1696
|
countdown: boolean;
|
|
1678
1697
|
};
|
|
1679
1698
|
}
|
|
1680
|
-
/** The brand palette, single-sourced:
|
|
1681
|
-
* extension's
|
|
1682
|
-
*
|
|
1699
|
+
/** The brand palette, single-sourced: a host's own surfaces on the chart read these (an
|
|
1700
|
+
* extension's lines among them), and a rebrand edits two strings. The candle bodies keep their
|
|
1701
|
+
* own pair; see the note on DEFAULT_OVERRIDES for why. */
|
|
1683
1702
|
declare const BRAND_UP = "#4c98fb";
|
|
1684
1703
|
declare const BRAND_DOWN = "#f23645";
|
|
1685
1704
|
declare const DEFAULT_OVERRIDES: ChartOverrides;
|
|
@@ -1708,9 +1727,11 @@ interface ThemeDeclaration {
|
|
|
1708
1727
|
* add a third. A host that keeps named brand presets resolves each preset to a custom light or
|
|
1709
1728
|
* dark palette before passing it in. */
|
|
1710
1729
|
type ThemeMode = 'light' | 'dark';
|
|
1711
|
-
/** What a role's value is written as. Every value is a CSS token string, so `length` is `'4px'
|
|
1712
|
-
* `duration` is `'150ms'
|
|
1713
|
-
|
|
1730
|
+
/** What a role's value is written as. Every value is a CSS token string, so `length` is `'4px'`,
|
|
1731
|
+
* `duration` is `'150ms'`, `easing` is a timing function such as `'ease-out'`, and `scale` is a
|
|
1732
|
+
* unitless factor such as `'0.97'`; the kind says which tokens are valid, and validation enforces
|
|
1733
|
+
* it. */
|
|
1734
|
+
type ThemeRoleKind = 'color' | 'length' | 'font' | 'duration' | 'easing' | 'scale' | 'shadow';
|
|
1714
1735
|
/** The grouping a role belongs to. Families organize the manual and the manifest; they are not part
|
|
1715
1736
|
* of a role's identity. */
|
|
1716
1737
|
type ThemeRoleFamily = 'canvas' | 'series' | 'scale' | 'text' | 'chrome' | 'overlay' | 'state' | 'control' | 'status' | 'illustration' | 'drawing' | 'motion';
|
|
@@ -1752,17 +1773,17 @@ declare const THEME_ROLES: readonly [{
|
|
|
1752
1773
|
readonly id: "series.up";
|
|
1753
1774
|
readonly family: "series";
|
|
1754
1775
|
readonly kind: "color";
|
|
1755
|
-
readonly description: "A rising value: up volume, a rising
|
|
1776
|
+
readonly description: "A rising value: up volume, a rising indicator tint, a positive series default.";
|
|
1756
1777
|
}, {
|
|
1757
1778
|
readonly id: "series.down";
|
|
1758
1779
|
readonly family: "series";
|
|
1759
1780
|
readonly kind: "color";
|
|
1760
|
-
readonly description: "A falling value: down volume, a falling
|
|
1781
|
+
readonly description: "A falling value: down volume, a falling indicator tint, a negative series default.";
|
|
1761
1782
|
}, {
|
|
1762
1783
|
readonly id: "series.neutral";
|
|
1763
1784
|
readonly family: "series";
|
|
1764
1785
|
readonly kind: "color";
|
|
1765
|
-
readonly description: "A series or level with no direction, such as
|
|
1786
|
+
readonly description: "A series or level with no direction, such as an indicator level line.";
|
|
1766
1787
|
}, {
|
|
1767
1788
|
readonly id: "scale.grid";
|
|
1768
1789
|
readonly family: "scale";
|
|
@@ -1957,7 +1978,7 @@ declare const THEME_ROLES: readonly [{
|
|
|
1957
1978
|
readonly id: "chrome.surface";
|
|
1958
1979
|
readonly family: "chrome";
|
|
1959
1980
|
readonly kind: "color";
|
|
1960
|
-
readonly description: "The fill of toolbars,
|
|
1981
|
+
readonly description: "The fill of toolbars, bars, and panels.";
|
|
1961
1982
|
}, {
|
|
1962
1983
|
readonly id: "chrome.surfaceRaised";
|
|
1963
1984
|
readonly family: "chrome";
|
|
@@ -2275,7 +2296,47 @@ declare const THEME_ROLES: readonly [{
|
|
|
2275
2296
|
readonly id: "motion.durationBase";
|
|
2276
2297
|
readonly family: "motion";
|
|
2277
2298
|
readonly kind: "duration";
|
|
2278
|
-
readonly description: "An ordinary transition,
|
|
2299
|
+
readonly description: "An ordinary transition: a modal dialog and its backdrop opening and closing, and the replay row entering and leaving.";
|
|
2300
|
+
}, {
|
|
2301
|
+
readonly id: "motion.durationModerate";
|
|
2302
|
+
readonly family: "motion";
|
|
2303
|
+
readonly kind: "duration";
|
|
2304
|
+
readonly description: "A control moving to its new state, such as a switch knob sliding.";
|
|
2305
|
+
}, {
|
|
2306
|
+
readonly id: "motion.durationSlow";
|
|
2307
|
+
readonly family: "motion";
|
|
2308
|
+
readonly kind: "duration";
|
|
2309
|
+
readonly description: "A small mark settling, such as a disclosure caret turning or a checkbox filling.";
|
|
2310
|
+
}, {
|
|
2311
|
+
readonly id: "motion.durationSlower";
|
|
2312
|
+
readonly family: "motion";
|
|
2313
|
+
readonly kind: "duration";
|
|
2314
|
+
readonly description: "A larger mark turning, such as the drawing toolbar's chevron.";
|
|
2315
|
+
}, {
|
|
2316
|
+
readonly id: "motion.easingStandard";
|
|
2317
|
+
readonly family: "motion";
|
|
2318
|
+
readonly kind: "easing";
|
|
2319
|
+
readonly description: "The timing of an ordinary transition: a modal dialog box, the replay row, a caret dip, a checkbox fill.";
|
|
2320
|
+
}, {
|
|
2321
|
+
readonly id: "motion.easingOut";
|
|
2322
|
+
readonly family: "motion";
|
|
2323
|
+
readonly kind: "easing";
|
|
2324
|
+
readonly description: "The timing of a motion that settles as it ends: a modal backdrop fading, a switch knob sliding.";
|
|
2325
|
+
}, {
|
|
2326
|
+
readonly id: "motion.easingLinear";
|
|
2327
|
+
readonly family: "motion";
|
|
2328
|
+
readonly kind: "easing";
|
|
2329
|
+
readonly description: "The timing of a color or opacity change under the pointer.";
|
|
2330
|
+
}, {
|
|
2331
|
+
readonly id: "motion.easingSpring";
|
|
2332
|
+
readonly family: "motion";
|
|
2333
|
+
readonly kind: "easing";
|
|
2334
|
+
readonly description: "The timing of a mark that turns with a slight overshoot, such as a caret or chevron.";
|
|
2335
|
+
}, {
|
|
2336
|
+
readonly id: "motion.scaleEnter";
|
|
2337
|
+
readonly family: "motion";
|
|
2338
|
+
readonly kind: "scale";
|
|
2339
|
+
readonly description: "The scale a modal dialog box grows from as it opens and returns to as it closes.";
|
|
2279
2340
|
}];
|
|
2280
2341
|
/** Every role id in the inventory. */
|
|
2281
2342
|
type ThemeRoleId = (typeof THEME_ROLES)[number]['id'];
|
|
@@ -2694,7 +2755,7 @@ interface ChartIconDiagnostic {
|
|
|
2694
2755
|
}
|
|
2695
2756
|
|
|
2696
2757
|
/** The glyphs of the chart's own controls, by meaning, each with every drawing that carries it. */
|
|
2697
|
-
declare const CONTROL_ICONS: Readonly<Record<"info" | "search" | "indicators" | "visible" | "textColor" | "lineColor" | "open" | "close" | "template" | "fillColor" | "locked" | "sync" | "measure" | "image" | "eraser" | "delete" | "remove" | "copy" | "pause" | "play" | "reset" | "scroll" | "
|
|
2758
|
+
declare const CONTROL_ICONS: Readonly<Record<"info" | "search" | "indicators" | "visible" | "textColor" | "lineColor" | "open" | "close" | "template" | "fillColor" | "locked" | "sync" | "measure" | "image" | "eraser" | "delete" | "remove" | "hidden" | "copy" | "pause" | "play" | "reset" | "scroll" | "add" | "magnet" | "compare" | "replay" | "settings" | "fullscreen" | "marketStatus" | "paneCollapse" | "paneRestore" | "paneMaximize" | "replayStatus" | "replayMark" | "replayCut" | "undo" | "redo" | "tileMaximize" | "tileRestore" | "download" | "chevronDown" | "chevronUp" | "chevronLeft" | "chevronRight" | "check" | "clear" | "goLive" | "stepForward" | "stepBack" | "selectBar" | "firstAvailable" | "randomBar" | "cursorCross" | "cursorDot" | "cursorArrow" | "magnetStrong" | "drawingsShown" | "drawingsHidden" | "indicatorsShown" | "indicatorsHidden" | "allShown" | "allHidden" | "zoomIn" | "grip" | "favoritesBar" | "lineSolid" | "lineDashed" | "lineDotted" | "lineThickness1" | "lineThickness2" | "lineThickness3" | "lineThickness4" | "lineEndNormal" | "lineEndArrow" | "fullscreenExit" | "caret" | "collapse" | "zoomOut" | "rename" | "duplicate" | "favorite" | "favorited" | "sortAscending" | "sortDescending" | "flyout" | "submenu" | "more" | "emptySearch" | "emptyCompare" | "operatorsShow" | "operatorsHide" | "operatorAdd" | "operatorSubtract" | "operatorMultiply" | "operatorDivide" | "operatorPower" | "operatorReciprocal" | "selectDate" | "zoomTool" | "stayInMode" | "stayInModeOn" | "unlocked" | "hide" | "glyphTools" | "visualOrder", readonly Glyph[]>>;
|
|
2698
2759
|
/** An icon of one of the chart's own controls. */
|
|
2699
2760
|
type ControlIconId = keyof typeof CONTROL_ICONS;
|
|
2700
2761
|
/** Every icon a host may draw: a control's glyph by its meaning, a chart style by its id, a drawing
|
|
@@ -2878,7 +2939,7 @@ declare function indicatorHidden(ov: IndicatorOverrides | undefined): boolean;
|
|
|
2878
2939
|
/** The manifest's default input values ({ period: 20, source: 0, … }). */
|
|
2879
2940
|
declare function manifestInputDefaults(m: IndicatorManifest): Record<string, number>;
|
|
2880
2941
|
/** The effective color of a plot spec under an instance: override → declared → the instance's
|
|
2881
|
-
* rotated color. A legend dot and a save-as-default snapshot both read THIS, so what the
|
|
2942
|
+
* rotated color. A legend dot and a save-as-default snapshot both read THIS, so what the viewer
|
|
2882
2943
|
* sees is what persists. */
|
|
2883
2944
|
declare function effectivePlotColor(m: IndicatorManifest, key: string, ov: IndicatorOverrides | undefined, instanceColor: string): string;
|
|
2884
2945
|
/** A manifest with an instance's STYLE overrides folded into its declared specs — colors, widths,
|
|
@@ -2898,8 +2959,8 @@ interface ManifestRun {
|
|
|
2898
2959
|
shadeColors?: readonly (string | null)[];
|
|
2899
2960
|
barColors?: readonly (string | null)[];
|
|
2900
2961
|
}
|
|
2901
|
-
/** The ONE walker from a computed run to the render-agnostic spec
|
|
2902
|
-
*
|
|
2962
|
+
/** The ONE walker from a computed run to the render-agnostic spec: built-ins and host
|
|
2963
|
+
* definitions all render through this, so plot semantics can never drift between them.
|
|
2903
2964
|
* `fallbackColor` is the instance's rotated color, used by any plot channel that doesn't declare
|
|
2904
2965
|
* its own. */
|
|
2905
2966
|
declare function buildManifestPlots(run: ManifestRun, times: readonly UTCTimestamp[], title: string, fallbackColor: string): IndicatorPlots;
|
|
@@ -2908,7 +2969,7 @@ declare function buildManifestPlots(run: ManifestRun, times: readonly UTCTimesta
|
|
|
2908
2969
|
* defensively. */
|
|
2909
2970
|
declare function latestPlotValue(data: readonly unknown[] | undefined): number | null;
|
|
2910
2971
|
|
|
2911
|
-
/** The symbol's price format, as
|
|
2972
|
+
/** The symbol's price format, as an indicator scale falls back to it when the manifest declares no
|
|
2912
2973
|
* precision: the formatter writes the scale labels, `minMove` is the symbol's smallest move, and
|
|
2913
2974
|
* `key` changes whenever either does so the scale re-applies. */
|
|
2914
2975
|
interface SymbolPriceFormat {
|
|
@@ -2935,8 +2996,8 @@ interface IndicatorsRenderer {
|
|
|
2935
2996
|
}
|
|
2936
2997
|
declare function attachIndicators(chart: IChartApi, options?: {
|
|
2937
2998
|
candles?: () => ISeriesApi<'Candlestick'> | null;
|
|
2938
|
-
/** The symbol's price format for
|
|
2939
|
-
* leaves those scales on the library's own default formatting. */
|
|
2999
|
+
/** The symbol's price format for indicators that declare no precision. A host that supplies
|
|
3000
|
+
* none leaves those scales on the library's own default formatting. */
|
|
2940
3001
|
symbolPriceFormat?: () => SymbolPriceFormat;
|
|
2941
3002
|
/** The undirected ink a level line takes when the manifest declares no color of its own. Read
|
|
2942
3003
|
* live, so a theme switch repaints the levels with everything else; the built-in dark palette's
|
|
@@ -2989,8 +3050,8 @@ interface ChartExtensionReplayState {
|
|
|
2989
3050
|
cursor: number;
|
|
2990
3051
|
total: number;
|
|
2991
3052
|
}
|
|
2992
|
-
/** The chart an extension is attached to, read-only. It answers what is on screen
|
|
2993
|
-
*
|
|
3053
|
+
/** The chart an extension is attached to, read-only. It answers what is on screen, and a host
|
|
3054
|
+
* steers the chart through the widget it already holds. */
|
|
2994
3055
|
interface ChartExtensionChart {
|
|
2995
3056
|
/** Same value as `pane().id` — the chart and its pane are one thing to an extension. */
|
|
2996
3057
|
id: string;
|
|
@@ -3046,7 +3107,7 @@ interface ChartExtensionIcon {
|
|
|
3046
3107
|
* the row reads exactly as a row that contributed no glyph at all. */
|
|
3047
3108
|
paths: readonly ChartExtensionIconPath[];
|
|
3048
3109
|
}
|
|
3049
|
-
/** A row an extension adds to the chart's
|
|
3110
|
+
/** A row an extension adds to the chart's context menu. It carries its own action: the chart routes
|
|
3050
3111
|
* nothing, so a contributed row cannot collide with a built-in id. */
|
|
3051
3112
|
interface ChartExtensionMenuItem {
|
|
3052
3113
|
id: string;
|
|
@@ -3061,9 +3122,9 @@ interface ChartExtensionMenuItem {
|
|
|
3061
3122
|
group?: 'level' | 'view';
|
|
3062
3123
|
run(): void;
|
|
3063
3124
|
}
|
|
3064
|
-
/** A layer an extension draws that the
|
|
3065
|
-
* chart's own layers and before "Hide all", which blanks it too, and it wears the
|
|
3066
|
-
* marks on the eye while it is the chosen subject. */
|
|
3125
|
+
/** A layer an extension draws that the drawing toolbar's eye can blank. It joins the eye's menu
|
|
3126
|
+
* after the chart's own layers and before "Hide all", which blanks it too, and it wears the
|
|
3127
|
+
* layer's own two marks on the eye while it is the chosen subject. */
|
|
3067
3128
|
interface ChartExtensionHideLayer {
|
|
3068
3129
|
/** Unique within one chart; the mode the hide command names for this layer. */
|
|
3069
3130
|
id: string;
|
|
@@ -3082,16 +3143,18 @@ interface ChartExtensionHideLayer {
|
|
|
3082
3143
|
apply(hidden: boolean): void;
|
|
3083
3144
|
}
|
|
3084
3145
|
/** The chart's side of a contributed layer: read whether it is blanked and flip it, through the
|
|
3085
|
-
* same eye the
|
|
3146
|
+
* same eye the drawing toolbar drives, so a switch on the extension's own surface and the eye
|
|
3147
|
+
* agree. */
|
|
3086
3148
|
interface ChartExtensionHideLayerHandle {
|
|
3087
3149
|
hidden(): boolean;
|
|
3088
3150
|
setHidden(hidden: boolean): void;
|
|
3089
3151
|
/** Withdraw the layer from the eye. Detach withdraws it either way. */
|
|
3090
3152
|
remove(): void;
|
|
3091
3153
|
}
|
|
3092
|
-
/**
|
|
3093
|
-
*
|
|
3094
|
-
|
|
3154
|
+
/** Builds an extension's context menu rows. The chart calls it on every raise with that moment's
|
|
3155
|
+
* context, so the rows can depend on the level that was pressed. An empty list contributes nothing
|
|
3156
|
+
* and costs nothing. */
|
|
3157
|
+
type ChartExtensionMenuBuilder = (context: ChartExtensionMenuContext) => readonly ChartExtensionMenuItem[];
|
|
3095
3158
|
/** A named action an extension offers the host. The minimal shape: an id, a label, whether it can
|
|
3096
3159
|
* run now, and how to run it. */
|
|
3097
3160
|
interface ChartExtensionCommand {
|
|
@@ -3114,7 +3177,7 @@ interface ChartExtensionContext {
|
|
|
3114
3177
|
overlay: HTMLElement;
|
|
3115
3178
|
/** The widget's layer on the document body, themed as the root is. A popover that must stand
|
|
3116
3179
|
* over every pane and over whatever the page stacks around the widget mounts HERE, at viewport
|
|
3117
|
-
* coordinates; the
|
|
3180
|
+
* coordinates; the context menu does the same. */
|
|
3118
3181
|
layer: HTMLElement;
|
|
3119
3182
|
/** The chart's effective canvas palette: the mode's resolved theme with any applied appearance
|
|
3120
3183
|
* overrides on top, projected onto the values a canvas draws with. */
|
|
@@ -3146,7 +3209,7 @@ interface ChartExtensionContext {
|
|
|
3146
3209
|
onActiveChange(callback: (active: boolean) => void): () => void;
|
|
3147
3210
|
/** The chart is going away. Fires before the handle's own `detach()`. */
|
|
3148
3211
|
onDispose(callback: () => void): () => void;
|
|
3149
|
-
contributeContextMenu(
|
|
3212
|
+
contributeContextMenu(build: ChartExtensionMenuBuilder): () => void;
|
|
3150
3213
|
contributeCommands(commands: readonly ChartExtensionCommand[]): () => void;
|
|
3151
3214
|
contributeHideLayer(layer: ChartExtensionHideLayer): ChartExtensionHideLayerHandle;
|
|
3152
3215
|
}
|
|
@@ -3174,7 +3237,7 @@ interface ChartExtension {
|
|
|
3174
3237
|
attach(context: ChartExtensionContext): ChartExtensionHandle;
|
|
3175
3238
|
}
|
|
3176
3239
|
|
|
3177
|
-
/** Localized metadata for one optional collection in the chart-owned indicator
|
|
3240
|
+
/** Localized metadata for one optional collection in the chart-owned indicator picker. */
|
|
3178
3241
|
interface IndicatorPickerCollection {
|
|
3179
3242
|
/** Stable opaque id. `builtin` and `favorites` belong to the chart. */
|
|
3180
3243
|
id: string;
|
|
@@ -3184,7 +3247,7 @@ interface IndicatorPickerCollection {
|
|
|
3184
3247
|
/** Catalog columns by default; a personal list can omit author and favorite columns. */
|
|
3185
3248
|
layout?: 'table' | 'list';
|
|
3186
3249
|
}
|
|
3187
|
-
/** A host action is an opaque verb
|
|
3250
|
+
/** A host action is an opaque verb: the source's `act` runs it, and the chart only names it. */
|
|
3188
3251
|
interface IndicatorPickerAction {
|
|
3189
3252
|
/** Unique within its row. `add` and `favorite` belong to the chart. */
|
|
3190
3253
|
id: string;
|
|
@@ -3215,7 +3278,9 @@ interface IndicatorPickerBuiltInState {
|
|
|
3215
3278
|
}
|
|
3216
3279
|
interface IndicatorPickerSource {
|
|
3217
3280
|
collections: readonly IndicatorPickerCollection[];
|
|
3218
|
-
/** The host supplies localized text. A new query or collection aborts the previous read.
|
|
3281
|
+
/** The host supplies localized text. A new query or collection aborts the previous read.
|
|
3282
|
+
* `builtInIds` are the built-ins the picker lists: every one, or those `builtInIndicators`
|
|
3283
|
+
* offers. */
|
|
3219
3284
|
list(request: {
|
|
3220
3285
|
collection: string;
|
|
3221
3286
|
query: string;
|
|
@@ -3252,21 +3317,21 @@ interface CompareSymbol {
|
|
|
3252
3317
|
symbol: string;
|
|
3253
3318
|
title: string;
|
|
3254
3319
|
}
|
|
3255
|
-
/** One active
|
|
3320
|
+
/** One active comparison, as hosts read it (legend rows, dialogs, serialization). */
|
|
3256
3321
|
interface CompareEntry {
|
|
3257
3322
|
symbol: string;
|
|
3258
3323
|
placement: ComparePlacement;
|
|
3259
3324
|
color: string;
|
|
3260
3325
|
visible: boolean;
|
|
3261
3326
|
/** Style beyond the palette color, absent until a settings edit sets it (2 / solid are the
|
|
3262
|
-
* series defaults). Carried here so a styled
|
|
3327
|
+
* series defaults). Carried here so a styled comparison round-trips through the snapshot. */
|
|
3263
3328
|
lineWidth?: number;
|
|
3264
3329
|
lineStyle?: 'solid' | 'dashed' | 'dotted';
|
|
3265
3330
|
}
|
|
3266
3331
|
/** The serialized form carried inside the chart content blob — and the shape host STATE holds.
|
|
3267
|
-
* Only the identity is required: color and visibility are the
|
|
3332
|
+
* Only the identity is required: color and visibility are the MODULE's to deal (the palette pick,
|
|
3268
3333
|
* the eye's default), so a host can state membership — "compare MSFT on a new scale" — before
|
|
3269
|
-
* the
|
|
3334
|
+
* the module has dealt them, and the module's report back fills them in. `serialize` always emits
|
|
3270
3335
|
* the dealt fields; `restore`/`apply` accept either form. */
|
|
3271
3336
|
interface CompareSnapshot {
|
|
3272
3337
|
symbol: string;
|
|
@@ -3277,13 +3342,13 @@ interface CompareSnapshot {
|
|
|
3277
3342
|
lineStyle?: 'solid' | 'dashed' | 'dotted';
|
|
3278
3343
|
}
|
|
3279
3344
|
/** The compare line palette, in assignment order. Assigned by first
|
|
3280
|
-
* unused slot, so removing a
|
|
3345
|
+
* unused slot, so removing a comparison frees its color for the next one. */
|
|
3281
3346
|
declare const COMPARE_COLORS: readonly string[];
|
|
3282
3347
|
/** First palette color not already worn; wraps past the palette by reuse (better a repeat than an
|
|
3283
3348
|
* invented hue the theme never approved). */
|
|
3284
3349
|
declare function pickCompareColor(used: readonly string[], palette?: readonly string[]): string;
|
|
3285
3350
|
/** Clip bars to the main series' window (inclusive). Null window ⇒ nothing renders yet — the main
|
|
3286
|
-
* series has no bars, and a
|
|
3351
|
+
* series has no bars, and a comparison must never be the thing that gives the axis its range. */
|
|
3287
3352
|
declare function clipToWindow(bars: readonly FeedBar[], window: {
|
|
3288
3353
|
from: number;
|
|
3289
3354
|
to: number;
|
|
@@ -3299,14 +3364,14 @@ interface CompareDeps {
|
|
|
3299
3364
|
/** The chart's CURRENT timeframe — read per fetch, never captured. */
|
|
3300
3365
|
tf(): string;
|
|
3301
3366
|
/** The MAIN series' loaded bar window (epoch seconds, inclusive), or null before first paint.
|
|
3302
|
-
* The
|
|
3367
|
+
* The module clips every comparison to it; the host calls `sync()` whenever it changes shape. */
|
|
3303
3368
|
mainWindow(): {
|
|
3304
3369
|
from: number;
|
|
3305
3370
|
to: number;
|
|
3306
3371
|
} | null;
|
|
3307
3372
|
/** How many bars a fresh compare asks for when the main window is not yet known. */
|
|
3308
3373
|
seedCountBack?: number;
|
|
3309
|
-
/** Entries changed (add/remove/visibility/color) or a
|
|
3374
|
+
/** Entries changed (add/remove/visibility/color) or a comparison's latest value moved — hosts
|
|
3310
3375
|
* re-render their legend from `list()` / `latest()`. */
|
|
3311
3376
|
onChange?(): void;
|
|
3312
3377
|
}
|
|
@@ -3320,11 +3385,11 @@ interface CompareHandle {
|
|
|
3320
3385
|
}): void;
|
|
3321
3386
|
remove(symbol: string): void;
|
|
3322
3387
|
setVisible(symbol: string, visible: boolean): void;
|
|
3323
|
-
/** A host-side hide ANDed with the eye (
|
|
3388
|
+
/** A host-side hide ANDed with the eye (timeframe visibility, a plot-visibility override) —
|
|
3324
3389
|
* never serialized and never touching `visible`, so a timeframe switch that suppresses a
|
|
3325
|
-
* compare cannot flip the
|
|
3390
|
+
* compare cannot flip the viewer's eye state. */
|
|
3326
3391
|
suppress(symbol: string, on: boolean): void;
|
|
3327
|
-
/** Restyle one
|
|
3392
|
+
/** Restyle one comparison's line (a settings edit). Omitted fields keep their current value;
|
|
3328
3393
|
* `priceLabel` is the price-scale label+line pair. Identical values are a no-op (no notify). */
|
|
3329
3394
|
restyle(symbol: string, style: {
|
|
3330
3395
|
color?: string;
|
|
@@ -3333,11 +3398,11 @@ interface CompareHandle {
|
|
|
3333
3398
|
priceLabel?: boolean;
|
|
3334
3399
|
}): void;
|
|
3335
3400
|
list(): CompareEntry[];
|
|
3336
|
-
/** The latest clipped close for one
|
|
3401
|
+
/** The latest clipped close for one comparison, or null (no bars in window / unknown symbol). */
|
|
3337
3402
|
latest(symbol: string): number | null;
|
|
3338
|
-
/** The pane the
|
|
3339
|
-
* symbol — how a host places the
|
|
3340
|
-
* the series, because 'new-pane' indices shift as other panes come and go. */
|
|
3403
|
+
/** The pane the comparison's series currently lives on (0 = the main pane), or null for an
|
|
3404
|
+
* unknown symbol — how a host places the comparison's legend row in the right pane's group. Read
|
|
3405
|
+
* live from the series, because 'new-pane' indices shift as other panes come and go. */
|
|
3341
3406
|
paneIndexOf(symbol: string): number | null;
|
|
3342
3407
|
/** Percent change across the clipped window (last close vs the window's FIRST in-window close —
|
|
3343
3408
|
* the loaded-window approximation of the percent scale's first-visible-bar base), or null with
|
|
@@ -3349,7 +3414,7 @@ interface CompareHandle {
|
|
|
3349
3414
|
* reshaped nothing): re-clip, and fetch older compare history only where the window now starts
|
|
3350
3415
|
* earlier than anything already asked for. */
|
|
3351
3416
|
sync(): void;
|
|
3352
|
-
/** The chart's timeframe changed: every
|
|
3417
|
+
/** The chart's timeframe changed: every comparison refetches at the new bucket size. */
|
|
3353
3418
|
setTimeframe(): void;
|
|
3354
3419
|
serialize(): CompareSnapshot[];
|
|
3355
3420
|
/** Replace the whole set from a snapshot (restore path). Unknown placements are dropped. */
|
|
@@ -3361,7 +3426,7 @@ declare function attachCompare(chart: IChartApi, deps: CompareDeps): CompareHand
|
|
|
3361
3426
|
type ScaleMode = 'normal' | 'log' | 'percent' | 'indexed';
|
|
3362
3427
|
declare const SCALE_MODES: readonly ScaleMode[];
|
|
3363
3428
|
/** Settings-control chips, in render order. Each names its own catalog key, so a control that
|
|
3364
|
-
* renders them reads the
|
|
3429
|
+
* renders them reads the viewer's language rather than an English word compiled into a public
|
|
3365
3430
|
* export. */
|
|
3366
3431
|
declare const SCALE_MODE_OPTIONS: readonly {
|
|
3367
3432
|
id: ScaleMode;
|
|
@@ -3379,24 +3444,24 @@ type ReplaySpeed = (typeof REPLAY_SPEEDS)[number];
|
|
|
3379
3444
|
* nominal seconds; 0 for ticks and for a token the grammar cannot read. A tick bar has no fixed
|
|
3380
3445
|
* duration, so it can neither be subdivided nor stand as a subdivision of a time bar. */
|
|
3381
3446
|
declare function tfSeconds(tf: string): number;
|
|
3382
|
-
/** The update
|
|
3447
|
+
/** The update timeframes a chart timeframe offers.
|
|
3383
3448
|
*
|
|
3384
|
-
* A rung qualifies when it divides the chart's
|
|
3449
|
+
* A rung qualifies when it divides the chart's timeframe evenly and is no coarser than it, drawn
|
|
3385
3450
|
* from the chart's OWN unit group and the group below it. That bound is what keeps the list
|
|
3386
3451
|
* readable: every minute rung divides a day evenly, but a day played a minute at a time is 1,440
|
|
3387
3452
|
* updates per bar, so a daily chart offers hours. Seconds join any intraday chart, which is how a
|
|
3388
3453
|
* minute chart gets a grain at all. A week or a month plays in whole days and nothing else.
|
|
3389
3454
|
*
|
|
3390
|
-
* The chart's own
|
|
3455
|
+
* The chart's own timeframe is ON the list when it is a rung, and choosing it is how a viewer asks
|
|
3391
3456
|
* for whole-bar updates. A timeframe that is not a rung (17m, say) simply has no rung of its own,
|
|
3392
3457
|
* and the list is whatever divides it. */
|
|
3393
|
-
declare function
|
|
3458
|
+
declare function subTimeframesFor(chartTf: string): {
|
|
3394
3459
|
tf: string;
|
|
3395
3460
|
sec: number;
|
|
3396
3461
|
}[];
|
|
3397
|
-
/** Auto = the COARSEST
|
|
3462
|
+
/** Auto = the COARSEST timeframe on offer, which is the chart's own whenever that is a rung. Replay
|
|
3398
3463
|
* then advances a whole bar per update until a viewer asks for a finer grain. */
|
|
3399
|
-
declare function
|
|
3464
|
+
declare function autoTimeframeFor(chartTf: string): {
|
|
3400
3465
|
tf: string;
|
|
3401
3466
|
sec: number;
|
|
3402
3467
|
} | null;
|
|
@@ -3424,8 +3489,11 @@ interface SearchControllerOptions {
|
|
|
3424
3489
|
}
|
|
3425
3490
|
interface SearchState {
|
|
3426
3491
|
readonly query: string;
|
|
3427
|
-
/** The asset-class filter the feed narrowed to; '' is every class.
|
|
3492
|
+
/** The asset-class filter the feed narrowed to; '' is every class. With a list filter it is the
|
|
3493
|
+
* one class the list holds, or '' when it holds several. */
|
|
3428
3494
|
readonly cls: string;
|
|
3495
|
+
/** The list filter the feed narrowed to, when the search was asked with one. */
|
|
3496
|
+
readonly classes?: readonly string[];
|
|
3429
3497
|
/** Every row loaded so far for the query, in the feed's order. */
|
|
3430
3498
|
readonly hits: readonly SymbolRow[];
|
|
3431
3499
|
/** A page for THIS query is in flight and nothing cached answers it yet. Rows of the previous
|
|
@@ -3442,17 +3510,21 @@ interface SearchController {
|
|
|
3442
3510
|
subscribe(listener: (state: SearchState) => void): () => void;
|
|
3443
3511
|
/** Ask for a query. A cached answer shows at once and a single-page entry revalidates in the
|
|
3444
3512
|
* background; a miss keeps the previous rows, marks loading, and fetches after the debounce.
|
|
3445
|
-
* A newer query cancels an older one's result.
|
|
3446
|
-
|
|
3513
|
+
* A newer query cancels an older one's result. `cls` is one class ('' is every class), or a
|
|
3514
|
+
* list of classes: the feed hears a list as `classes`, and as `cls` too when it holds exactly
|
|
3515
|
+
* one. An empty list is every class. */
|
|
3516
|
+
search(query: string, cls?: SearchClassFilter): void;
|
|
3447
3517
|
/** Append the next page of the current query while `hasMore` holds. One page in flight at a
|
|
3448
3518
|
* time; rows already shown are never repeated even when a revalidation shifted a page edge. */
|
|
3449
3519
|
loadMore(): void;
|
|
3450
3520
|
/** Warm the cache for a query without changing the current one, so its first open is instant.
|
|
3451
3521
|
* A failure is dropped; the query fetches on open as it would have. */
|
|
3452
|
-
prefetch(query?: string, cls?:
|
|
3522
|
+
prefetch(query?: string, cls?: SearchClassFilter): void;
|
|
3453
3523
|
/** Stop timers; later results are ignored. */
|
|
3454
3524
|
dispose(): void;
|
|
3455
3525
|
}
|
|
3526
|
+
/** Which classes a search narrows to: one class token ('' is every class), or a list of them. */
|
|
3527
|
+
type SearchClassFilter = string | readonly string[];
|
|
3456
3528
|
declare function createSearchController(datafeed: Pick<ChartDatafeed, 'search'>, options?: SearchControllerOptions): SearchController;
|
|
3457
3529
|
/** How many recent picks a search surface lists. */
|
|
3458
3530
|
declare const RECENT_SYMBOLS_CAP = 10;
|
|
@@ -3478,8 +3550,10 @@ interface MatchSegment {
|
|
|
3478
3550
|
declare function matchSegments(text: string, query: string): MatchSegment[];
|
|
3479
3551
|
/** One spread operator a search input offers. It TYPES into the query; the feed parses and
|
|
3480
3552
|
* evaluates the expression, because the whole expression is the instrument. */
|
|
3553
|
+
/** The name of one spread operator, as a host lists the operators a search offers. */
|
|
3554
|
+
type SpreadOperatorId = 'division' | 'subtraction' | 'addition' | 'multiplication' | 'exponentiation' | 'reciprocal';
|
|
3481
3555
|
interface SpreadOperator {
|
|
3482
|
-
readonly id:
|
|
3556
|
+
readonly id: SpreadOperatorId;
|
|
3483
3557
|
/** What it inserts. */
|
|
3484
3558
|
readonly insert: string;
|
|
3485
3559
|
/** Inserted before the query rather than after it (the reciprocal form). */
|
|
@@ -3681,7 +3755,7 @@ type ThemeChangeListener = (theme: SemanticTheme, mode: ThemeMode) => void;
|
|
|
3681
3755
|
interface ThemeController {
|
|
3682
3756
|
/** The mode in effect. */
|
|
3683
3757
|
mode(): ThemeMode;
|
|
3684
|
-
/** Switch modes. The chart keeps its symbol, timeframe, range, drawings, and
|
|
3758
|
+
/** Switch modes. The chart keeps its symbol, timeframe, range, drawings, and indicators. */
|
|
3685
3759
|
setMode(mode: ThemeMode): void;
|
|
3686
3760
|
/** The complete resolved theme in effect. */
|
|
3687
3761
|
get(): SemanticTheme;
|
|
@@ -3726,7 +3800,8 @@ interface CommandSpec {
|
|
|
3726
3800
|
execute(arg?: unknown): void | Promise<void>;
|
|
3727
3801
|
}
|
|
3728
3802
|
/** What running a command answers. A refusal is a value, never a throw: a menu row, a shortcut and
|
|
3729
|
-
* an
|
|
3803
|
+
* an automation adapter all need to tell "nothing by that name" from "not allowed" without a try
|
|
3804
|
+
* block. */
|
|
3730
3805
|
type CommandResult = {
|
|
3731
3806
|
kind: 'ok';
|
|
3732
3807
|
} | {
|
|
@@ -3752,7 +3827,9 @@ interface CommandRegistry {
|
|
|
3752
3827
|
execute(id: string, arg?: unknown): CommandResult;
|
|
3753
3828
|
/** Remap a shortcut, or clear it with null. */
|
|
3754
3829
|
setShortcut(id: string, shortcut: string | null): void;
|
|
3755
|
-
/** Fires when the registered set or a shortcut changes
|
|
3830
|
+
/** Fires when the registered set or a shortcut changes, and when the host says its access policy
|
|
3831
|
+
* may answer differently (`widget.refreshAccess()`), since what `available` answers may have
|
|
3832
|
+
* moved with it. Returns the unsubscribe. */
|
|
3756
3833
|
onChange(cb: () => void): () => void;
|
|
3757
3834
|
}
|
|
3758
3835
|
|
|
@@ -3858,7 +3935,7 @@ interface DrawingPresets {
|
|
|
3858
3935
|
subscribe(listener: () => void): () => void;
|
|
3859
3936
|
}
|
|
3860
3937
|
/** Why a low-level document operation refused. Machine-readable on purpose: these answer a host's
|
|
3861
|
-
* code, not a
|
|
3938
|
+
* code, not a viewer, so nothing here is a sentence to render. */
|
|
3862
3939
|
type DrawingDocumentRefusal =
|
|
3863
3940
|
/** The widget runs in combined mode: its drawings ride whatever saves the chart, and there is no
|
|
3864
3941
|
* separate document to get, apply or reload. */
|
|
@@ -3870,7 +3947,7 @@ type DrawingDocumentRefusal =
|
|
|
3870
3947
|
* layout, chart or symbol that has moved on. Nothing was changed. */
|
|
3871
3948
|
| 'stale';
|
|
3872
3949
|
/** Why one drawing in a document was not applied. The rest of the document still applies: one
|
|
3873
|
-
* unusable row is not a reason to leave the
|
|
3950
|
+
* unusable row is not a reason to leave the viewer with an empty chart. */
|
|
3874
3951
|
type DrawingRejectionReason =
|
|
3875
3952
|
/** Its owning source is not on this chart (an indicator that is gone, a series never added). */
|
|
3876
3953
|
'missing-source'
|
|
@@ -3932,7 +4009,7 @@ interface DrawingsEvents {
|
|
|
3932
4009
|
onSelectionChange?: (id: string | null) => void;
|
|
3933
4010
|
/** A write of a symbol's document was refused: the stored document moved on (`current` is the
|
|
3934
4011
|
* ref that stands now) or vanished (null). The layer merges the stored document over its own
|
|
3935
|
-
* work and writes again at the adopted ref; the host decides what to tell the
|
|
4012
|
+
* work and writes again at the adopted ref; the host decides what to tell the viewer. */
|
|
3936
4013
|
onSaveConflict?: (info: {
|
|
3937
4014
|
symbol: string;
|
|
3938
4015
|
current: ResourceRef | null;
|
|
@@ -3952,7 +4029,7 @@ interface AttachDrawingsOptions {
|
|
|
3952
4029
|
* the keyboard verbs stay scoped to this widget instead of the whole page. */
|
|
3953
4030
|
container: HTMLElement;
|
|
3954
4031
|
symbol: string;
|
|
3955
|
-
/** Timeframe token ('5m', '1d', ...), which drives per-
|
|
4032
|
+
/** Timeframe token ('5m', '1d', ...), which drives per-timeframe drawing visibility. */
|
|
3956
4033
|
timeframe?: string;
|
|
3957
4034
|
/** SEPARATE-drawing persistence: which drawing-resource context a symbol's document is keyed by,
|
|
3958
4035
|
* and the store for that context. Absent is the COMBINED mode: the layer keeps its documents in
|
|
@@ -3996,6 +4073,12 @@ interface AttachDrawingsOptions {
|
|
|
3996
4073
|
* a cursor beside it would be a second claim about the same point. This layer writes the plot's
|
|
3997
4074
|
* cursor as an inline style, so it is the only place that can stand it down. */
|
|
3998
4075
|
pointerSuppressed?: () => boolean;
|
|
4076
|
+
/** Whether a new drawing may be made as a copy of a drawing of this type. Clone, paste and a
|
|
4077
|
+
* modifier-drag duplicate each make a new drawing, so a host that does not offer a tool refuses
|
|
4078
|
+
* them for its drawings: clone and paste make nothing, `canPaste` answers false, and the drag
|
|
4079
|
+
* moves the drawing itself. Copying to the clipboard is never refused. Absent, every copy is
|
|
4080
|
+
* made. */
|
|
4081
|
+
copies?: (type: string) => boolean;
|
|
3999
4082
|
events?: DrawingsEvents;
|
|
4000
4083
|
}
|
|
4001
4084
|
/** The running drawing layer a host holds. */
|
|
@@ -4052,7 +4135,7 @@ interface DrawingsHandle {
|
|
|
4052
4135
|
};
|
|
4053
4136
|
/** Hide the selection (its own `visible` switch) and deselect it. */
|
|
4054
4137
|
hideSelected(): void;
|
|
4055
|
-
/** Apply one of the quick per-
|
|
4138
|
+
/** Apply one of the quick per-timeframe visibility rules to the selection, against the current
|
|
4056
4139
|
* timeframe. */
|
|
4057
4140
|
setVisibilityPreset(preset: VisibilityPreset): void;
|
|
4058
4141
|
/** Drop a ready picture onto the chart, centred in view, selected. */
|
|
@@ -4107,16 +4190,16 @@ interface ChartReplayApi {
|
|
|
4107
4190
|
setSpeed(speed: ReplaySpeed): void;
|
|
4108
4191
|
/** Jump the cursor to the live edge. Playback pauses; replay stays on. */
|
|
4109
4192
|
goLive(): void;
|
|
4110
|
-
/** The update grain: `auto`, or one of the finer timeframe tokens `
|
|
4111
|
-
|
|
4193
|
+
/** The update grain: `auto`, or one of the finer timeframe tokens `subTimeframes()` lists. */
|
|
4194
|
+
timeframe(): string;
|
|
4112
4195
|
/** Set the grain. A token the chart timeframe cannot form from is refused. */
|
|
4113
|
-
|
|
4196
|
+
setTimeframe(token: string): void;
|
|
4114
4197
|
/** The grain updates actually use, with `auto` resolved to the token it chose. Empty when the
|
|
4115
4198
|
* chart's timeframe has nothing finer to form from, so updates advance whole bars. */
|
|
4116
|
-
|
|
4199
|
+
resolvedTimeframe(): string;
|
|
4117
4200
|
/** The finer timeframe tokens the chart timeframe can form bars from; empty means whole-bar
|
|
4118
4201
|
* updates only. */
|
|
4119
|
-
|
|
4202
|
+
subTimeframes(): readonly string[];
|
|
4120
4203
|
state(): {
|
|
4121
4204
|
on: boolean;
|
|
4122
4205
|
playing: boolean;
|
|
@@ -4144,6 +4227,58 @@ type ReplayPhase = 'off' | 'arming' | 'on';
|
|
|
4144
4227
|
* presets). The public surface grows on demand, not by exposure. */
|
|
4145
4228
|
type ChartDrawingsApi = Omit<DrawingsHandle, 'setSymbol' | 'setTimeframe' | 'setTick' | 'setPriceFormatter' | 'destroy' | 'selectedDrawing' | 'commitEdit' | 'beginPreview' | 'endPreview' | 'textEdit' | 'commitText' | 'cancelText' | 'presets'>;
|
|
4146
4229
|
|
|
4230
|
+
/** What a preset frames: seconds of history, the year to date, or everything loaded. */
|
|
4231
|
+
type RangeSpan = number | 'ytd' | 'all';
|
|
4232
|
+
interface RangePreset {
|
|
4233
|
+
/** The preset's identity and the text its chip wears ('1D', 'YTD', 'All'). It stays as written
|
|
4234
|
+
* in every language; a host names the preset by it. */
|
|
4235
|
+
readonly key: string;
|
|
4236
|
+
readonly span: RangeSpan;
|
|
4237
|
+
/** The timeframe token the preset switches the chart to. */
|
|
4238
|
+
readonly tf: string;
|
|
4239
|
+
/** The catalog key of the preset's full name, for its tooltip. */
|
|
4240
|
+
readonly label: ChartMessageKey;
|
|
4241
|
+
}
|
|
4242
|
+
/** The nine presets, in bar order. */
|
|
4243
|
+
declare const RANGE_PRESETS: readonly RangePreset[];
|
|
4244
|
+
/** The seconds a span covers back from `nowSecs`; null for 'all', which has no span. */
|
|
4245
|
+
declare function rangeSpanSeconds(span: RangeSpan, nowSecs: number): number | null;
|
|
4246
|
+
/** Whether a preset is offered for a symbol whose earliest bar is at `earliestBarSecs`: a preset
|
|
4247
|
+
* deeper than the history that exists is withheld (a listing from last year has no 5Y), 'All'
|
|
4248
|
+
* always stays, and an unknown depth (null) withholds nothing. The depth itself is the host's to
|
|
4249
|
+
* learn from its feed; the chart does not probe. */
|
|
4250
|
+
declare function rangeAvailable(preset: RangePreset, earliestBarSecs: number | null | undefined, nowSecs?: number): boolean;
|
|
4251
|
+
/** A preset's tooltip: what it frames, and the bars it frames it in. */
|
|
4252
|
+
declare function rangePresetTip(t: ChartTranslate, preset: RangePreset): string;
|
|
4253
|
+
/** The part of a chart the framing needs: a time scale that takes a logical range. */
|
|
4254
|
+
interface RangeFrameTarget {
|
|
4255
|
+
timeScale(): {
|
|
4256
|
+
setVisibleLogicalRange(range: {
|
|
4257
|
+
from: number;
|
|
4258
|
+
to: number;
|
|
4259
|
+
}): void;
|
|
4260
|
+
};
|
|
4261
|
+
}
|
|
4262
|
+
/** Frame a pane on a span, anchored on its LAST REAL bar: a series also carries a future
|
|
4263
|
+
* whitespace horizon for right-margin drawing, so fitting to content would frame a screen of
|
|
4264
|
+
* empty space. The bar count comes from the pane's own timeframe, because the same span is a
|
|
4265
|
+
* different number of bars on a one-minute pane than on a daily one. An empty series, or a token
|
|
4266
|
+
* the grammar cannot read, frames nothing rather than a bogus window. */
|
|
4267
|
+
declare function frameRange(chart: RangeFrameTarget, series: {
|
|
4268
|
+
data(): readonly unknown[];
|
|
4269
|
+
}, span: RangeSpan, tf: string, nowSecs?: number): void;
|
|
4270
|
+
/** One zoom step multiplies or divides the bar spacing by this. */
|
|
4271
|
+
declare const ZOOM_FACTOR = 1.25;
|
|
4272
|
+
/** The bar spacing a zoom-out never goes below. */
|
|
4273
|
+
declare const MIN_BAR_SPACING = 0.5;
|
|
4274
|
+
/** How far one scroll step moves, in bars. */
|
|
4275
|
+
declare const SCROLL_STEP_BARS = 10;
|
|
4276
|
+
/** The bar spacing after one zoom step from `spacing`. */
|
|
4277
|
+
declare function zoomedBarSpacing(spacing: number, direction: 'in' | 'out'): number;
|
|
4278
|
+
/** The time-scale scroll position after one scroll step from `position` (positive is right, as
|
|
4279
|
+
* lightweight-charts counts it). */
|
|
4280
|
+
declare function scrolledPosition(position: number, direction: 'left' | 'right'): number;
|
|
4281
|
+
|
|
4147
4282
|
/** The compare surface a host drives. */
|
|
4148
4283
|
interface ChartCompareApi {
|
|
4149
4284
|
add(symbol: string, opts: {
|
|
@@ -4152,7 +4287,7 @@ interface ChartCompareApi {
|
|
|
4152
4287
|
remove(symbol: string): void;
|
|
4153
4288
|
setVisible(symbol: string, visible: boolean): void;
|
|
4154
4289
|
list(): CompareEntry[];
|
|
4155
|
-
/** Latest in-window close for one
|
|
4290
|
+
/** Latest in-window close for one comparison, or null. */
|
|
4156
4291
|
latest(symbol: string): number | null;
|
|
4157
4292
|
/** The host-supplied curated quick-add list, for the compare dialog. */
|
|
4158
4293
|
symbols(): CompareSymbol[];
|
|
@@ -4169,7 +4304,7 @@ declare function applyBar(bars: FeedBar[], bar: FeedBar): FeedBar[] | null;
|
|
|
4169
4304
|
* viewer's, so a later feed that serves the preferred timeframe gets it back. Exported for tests. */
|
|
4170
4305
|
declare function resolveInitialTf(sticky: string, declared: readonly string[] | undefined): string;
|
|
4171
4306
|
/** Pane-composition primitives: the raw mirrors a layout syncs charts with. Subscriptions report
|
|
4172
|
-
*
|
|
4307
|
+
* VIEWER-driven changes only, so a chart being driven through the setters never re-reports the
|
|
4173
4308
|
* change and two mirrored charts cannot echo each other into a loop. Times are the feed's unix
|
|
4174
4309
|
* seconds. */
|
|
4175
4310
|
interface ChartPaneSyncApi {
|
|
@@ -4203,10 +4338,12 @@ interface ChartHandle {
|
|
|
4203
4338
|
* that guessed from the string would be inventing a quote the feed never stated. */
|
|
4204
4339
|
symbolInfo(): SymbolInfo | null;
|
|
4205
4340
|
timeframe(): string;
|
|
4341
|
+
/** Switch the timeframe. A timeframe the widget does not offer is ignored. */
|
|
4206
4342
|
setTimeframe(timeframe: string): void;
|
|
4207
4343
|
style(): ChartStyleId;
|
|
4208
4344
|
/** Switch the main-series style. Presentation only: nothing refetches, and the indicators,
|
|
4209
|
-
* drawings, comparisons and visible range all survive.
|
|
4345
|
+
* drawings, comparisons and visible range all survive. A style the widget does not offer is
|
|
4346
|
+
* ignored. */
|
|
4210
4347
|
setStyle(id: ChartStyleId): void;
|
|
4211
4348
|
visibleRange(): TimeRange | null;
|
|
4212
4349
|
/** The range preset currently framing this chart, or null after other navigation. */
|
|
@@ -4228,7 +4365,7 @@ interface ChartHandle {
|
|
|
4228
4365
|
* follow whatever venue the symbol resolves to. */
|
|
4229
4366
|
timezone(): string;
|
|
4230
4367
|
/** Set the choice. A value the chart's registry does not carry is refused, because the axis
|
|
4231
|
-
* formatters could not label a tick with it. */
|
|
4368
|
+
* formatters could not label a tick with it, and so is one the widget does not offer. */
|
|
4232
4369
|
setTimezone(choice: string): void;
|
|
4233
4370
|
/** The zone the choice resolves to for the symbol on screen: the chosen IANA id, or the exchange
|
|
4234
4371
|
* zone the resolved symbol declared. Null while `exchange` is chosen and no symbol has resolved. */
|
|
@@ -4373,7 +4510,7 @@ interface ChartEvents {
|
|
|
4373
4510
|
/** Which changes replay across the layout. All off by default. */
|
|
4374
4511
|
interface LayoutSyncFlags {
|
|
4375
4512
|
symbol: boolean;
|
|
4376
|
-
|
|
4513
|
+
timeframe: boolean;
|
|
4377
4514
|
crosshair: boolean;
|
|
4378
4515
|
time: boolean;
|
|
4379
4516
|
dateRange: boolean;
|
|
@@ -4406,12 +4543,13 @@ interface LayoutSaveLoadApi {
|
|
|
4406
4543
|
interface LayoutApi {
|
|
4407
4544
|
arrangement(): string;
|
|
4408
4545
|
/** Re-tile. Surviving charts keep their state; new charts clone pane 0's safe presentation;
|
|
4409
|
-
* excess charts are torn down. */
|
|
4546
|
+
* excess charts are torn down. An arrangement the widget does not offer is ignored. */
|
|
4410
4547
|
setArrangement(code: string): void;
|
|
4411
4548
|
/** The index of the active chart. */
|
|
4412
4549
|
active(): number;
|
|
4413
4550
|
setActive(index: number): void;
|
|
4414
4551
|
sync(): LayoutSyncFlags;
|
|
4552
|
+
/** Set sync switches. A switch the widget does not offer keeps its value. */
|
|
4415
4553
|
setSync(partial: Partial<LayoutSyncFlags>): void;
|
|
4416
4554
|
/** The chart standing alone, or null while every chart is tiled. Presentation, not content: a
|
|
4417
4555
|
* maximize is a way of LOOKING at a layout, so it rides no blob and a re-tile clears it. */
|
|
@@ -4470,7 +4608,7 @@ interface UiConfig {
|
|
|
4470
4608
|
topBar?: boolean | TopBarUi;
|
|
4471
4609
|
/** The bottom bar: range presets, the clock, the timezone picker and the session view. */
|
|
4472
4610
|
bottomBar?: boolean;
|
|
4473
|
-
/** The drawing
|
|
4611
|
+
/** The drawing toolbar: the tool groups, cursor, measure and zoom, magnet, lock, the eye, sync,
|
|
4474
4612
|
* remove and the favorites star. */
|
|
4475
4613
|
drawingToolbar?: boolean;
|
|
4476
4614
|
/** The floating favorite-tools bar. */
|
|
@@ -4479,7 +4617,7 @@ interface UiConfig {
|
|
|
4479
4617
|
legend?: boolean | LegendUi;
|
|
4480
4618
|
/** The on-chart navigation cluster: zoom, scroll and reset. */
|
|
4481
4619
|
navigation?: boolean;
|
|
4482
|
-
/** The chart's own right-click
|
|
4620
|
+
/** The chart's own right-click context menu. */
|
|
4483
4621
|
contextMenu?: boolean;
|
|
4484
4622
|
/** The replay transport row: play, pause, step, speed and exit. */
|
|
4485
4623
|
replayTransport?: boolean;
|
|
@@ -4489,7 +4627,7 @@ interface UiConfig {
|
|
|
4489
4627
|
* and `chart.symbol.search`. Off, the symbol still changes through `chart.symbol.set`. The
|
|
4490
4628
|
* compare dialog belongs to `features.compare`. */
|
|
4491
4629
|
symbolSearch?: boolean;
|
|
4492
|
-
/** The indicator
|
|
4630
|
+
/** The indicator picker, and its doors: the Indicators button and `chart.indicators.open`. Off,
|
|
4493
4631
|
* indicators are still added through `chart.indicators.add`. */
|
|
4494
4632
|
indicatorPicker?: boolean;
|
|
4495
4633
|
/** The full indicator settings dialog. Off, the legend's gear opens the inputs-only editor, and
|
|
@@ -4512,8 +4650,16 @@ interface TopBarUi {
|
|
|
4512
4650
|
replay?: boolean;
|
|
4513
4651
|
/** Undo and redo. */
|
|
4514
4652
|
history?: boolean;
|
|
4515
|
-
/** The layout setup menu and the saved-layouts menu.
|
|
4653
|
+
/** The layout setup menu and the saved-layouts menu. `false` hides both, whatever `layoutSetup`
|
|
4654
|
+
* and `savedLayouts` say. */
|
|
4516
4655
|
layouts?: boolean;
|
|
4656
|
+
/** The layout setup menu: the arrangement grid and the sync switches. Not shown when the widget
|
|
4657
|
+
* offers nothing to choose there (see `ChartWidgetOptions.layouts`). */
|
|
4658
|
+
layoutSetup?: boolean;
|
|
4659
|
+
/** The saved-layouts menu: the layout's name with Save, and the menu that saves, copies, renames,
|
|
4660
|
+
* creates and opens layouts. Not shown without a layouts store (`saveLoad.layouts`), since every
|
|
4661
|
+
* row saves or reads one; Download chart data then sits in the image menu. */
|
|
4662
|
+
savedLayouts?: boolean;
|
|
4517
4663
|
/** The chart settings menu. `false` removes it; an object hides part of it. */
|
|
4518
4664
|
settings?: boolean | SettingsMenuUi;
|
|
4519
4665
|
/** The fullscreen button. */
|
|
@@ -4543,13 +4689,37 @@ interface LegendUi {
|
|
|
4543
4689
|
interface AccessPolicy {
|
|
4544
4690
|
/** Whether a command id may run. A refused command answers `denied` from every surface. */
|
|
4545
4691
|
command?(id: string): boolean;
|
|
4546
|
-
/** Whether a drawing tool id may be armed.
|
|
4692
|
+
/** Whether a drawing tool id may be armed. Placing an image (`placeImage`, the picker, a paste)
|
|
4693
|
+
* asks it for `image`. A copy is a new drawing, so a drawing of a refused tool is not cloned,
|
|
4694
|
+
* pasted or duplicated by a modifier-drag. A restore (a saved chart, a layout load, an undo, a
|
|
4695
|
+
* drawings document) puts drawings of a refused tool back like any other, and on the chart they
|
|
4696
|
+
* stay whole: they select, restyle, lock, hide and delete as any drawing does. */
|
|
4547
4697
|
drawingTool?(id: string): boolean;
|
|
4548
4698
|
/** Whether an indicator definition may be added, asked by its DEFINITION id (`manifest.id`; a
|
|
4549
4699
|
* built-in's is the catalog id the picker lists, such as `sma`), never by an instance id. Every
|
|
4550
|
-
* door asks the same id: the picker row, `indicators.add`, and
|
|
4551
|
-
*
|
|
4700
|
+
* door that adds asks the same id: the picker row, `indicators.add`, and `indicators.set` for an
|
|
4701
|
+
* instance the chart does not hold. The policy refuses adding, never restoring: a saved chart, a
|
|
4702
|
+
* layout load, an undo or a redo puts an instance of a refused definition back like any other.
|
|
4703
|
+
* An instance of a refused definition the chart holds stays whole: `indicators.set` and
|
|
4704
|
+
* `chart.indicators.update` edit it, an edit that would move it onto a refused definition leaves
|
|
4705
|
+
* it as it stands, and every remove door removes it. A definition that declares no id is not
|
|
4706
|
+
* gated. */
|
|
4552
4707
|
indicator?(id: string): boolean;
|
|
4708
|
+
/** How the chart's own controls present what the predicates refuse. `'disable'` (the default)
|
|
4709
|
+
* draws a refused control disabled, which suits an offer the viewer can unlock. `'hide'` leaves
|
|
4710
|
+
* it out: a refused drawing tool is not in the drawing toolbar's flyouts, on the favorites bar
|
|
4711
|
+
* or in the glyph picker, and a section or group it empties goes with it; a refused indicator is
|
|
4712
|
+
* not in the indicator picker; and a control or menu row whose command is refused is not drawn.
|
|
4713
|
+
*
|
|
4714
|
+
* Only a refusal hides. A permitted command that cannot run now (nothing to undo, no bars
|
|
4715
|
+
* loaded, nothing selected) is still drawn disabled. Like the predicates it is read whenever a
|
|
4716
|
+
* control is drawn or synced, and again on `widget.refreshAccess()`, so the controls follow a
|
|
4717
|
+
* policy that changes. Nothing stored is
|
|
4718
|
+
* rewritten: a viewer's favorite keeps its star and returns when the policy permits it again,
|
|
4719
|
+
* and drawings and indicators already on the chart render as they do under either value. Every
|
|
4720
|
+
* other door (the keyboard, `widget.commands`, the chart handles) refuses exactly as it does
|
|
4721
|
+
* under `'disable'`. Any other value is a setup error thrown from `createChart`. */
|
|
4722
|
+
refused?: 'disable' | 'hide';
|
|
4553
4723
|
}
|
|
4554
4724
|
/** ── PREFERENCES ─────────────────────────────────────────────────────────────────────────────
|
|
4555
4725
|
* The viewer's own values: what the storage port persists and restores. A host supplies initial
|
|
@@ -4561,7 +4731,7 @@ interface ChartPreferences {
|
|
|
4561
4731
|
style: ChartStyleId;
|
|
4562
4732
|
scaleMode: ScaleMode;
|
|
4563
4733
|
/** The display timezone: an IANA id from the chart's registry, or `exchange` to follow whatever
|
|
4564
|
-
* venue the symbol resolves to. */
|
|
4734
|
+
* venue the symbol resolves to. One that `timezones` leaves out opens on the first listed. */
|
|
4565
4735
|
timezone: string;
|
|
4566
4736
|
/** Which subsession intraday bars are shown for. A symbol with no extended hours has one, so a
|
|
4567
4737
|
* stored `extended` on such a symbol falls back rather than filtering to nothing. */
|
|
@@ -4570,9 +4740,9 @@ interface ChartPreferences {
|
|
|
4570
4740
|
hiddenIndicators: readonly string[];
|
|
4571
4741
|
replaySpeed: ReplaySpeed;
|
|
4572
4742
|
/** The replay update grain: `auto` or a finer timeframe token. */
|
|
4573
|
-
|
|
4574
|
-
/** The standing drawing choices: cursor, magnet, stay-in-mode, favorites, per-group
|
|
4575
|
-
* The drawing models own what each one means; the chart only persists the record. */
|
|
4743
|
+
replayTimeframe: string;
|
|
4744
|
+
/** The standing drawing choices: cursor, magnet, stay-in-mode, favorites, per-group toolbar
|
|
4745
|
+
* tools. The drawing models own what each one means; the chart only persists the record. */
|
|
4576
4746
|
drawings: DrawingPreferences;
|
|
4577
4747
|
/** The timeframe tokens the top bar shows as quick-select chips. */
|
|
4578
4748
|
savedTimeframes: readonly string[];
|
|
@@ -4636,7 +4806,7 @@ interface ImageOptions {
|
|
|
4636
4806
|
header?: boolean;
|
|
4637
4807
|
}
|
|
4638
4808
|
/** ── DRAWING PERSISTENCE ─────────────────────────────────────────────────────────────────────
|
|
4639
|
-
* Where the
|
|
4809
|
+
* Where the viewer's drawings are stored. Two modes, and the host picks one HERE, at construction:
|
|
4640
4810
|
*
|
|
4641
4811
|
* combined (the default) the drawings ride the chart's own saved content, so saving a chart or
|
|
4642
4812
|
* a layout saves the drawings that are on it.
|
|
@@ -4658,9 +4828,12 @@ interface DrawingPersistenceOptions {
|
|
|
4658
4828
|
}
|
|
4659
4829
|
/** The multi-chart arrangement the widget opens with. */
|
|
4660
4830
|
interface LayoutOptions {
|
|
4661
|
-
/** An arrangement code from the catalog (default `s`, one chart
|
|
4831
|
+
/** An arrangement code from the catalog (default `s`, one chart, or the first of
|
|
4832
|
+
* `ChartWidgetOptions.layouts` when the host lists them). Unknown codes throw, and with `layouts`
|
|
4833
|
+
* the code must be one of them. */
|
|
4662
4834
|
arrangement?: string;
|
|
4663
|
-
/** Per-chart starting symbol and timeframe, index-aligned to the arrangement's panes.
|
|
4835
|
+
/** Per-chart starting symbol and timeframe, index-aligned to the arrangement's panes. A timeframe
|
|
4836
|
+
* must be one the widget offers. */
|
|
4664
4837
|
charts?: {
|
|
4665
4838
|
symbol?: string;
|
|
4666
4839
|
timeframe?: string;
|
|
@@ -4690,8 +4863,8 @@ interface IndicatorInstance {
|
|
|
4690
4863
|
title?: string;
|
|
4691
4864
|
overrides?: IndicatorOverrides;
|
|
4692
4865
|
}
|
|
4693
|
-
/** The set of symbols a search answers from, as the host names it: a portfolio, a
|
|
4694
|
-
*
|
|
4866
|
+
/** The set of symbols a search answers from, as the host names it: a portfolio, a watchlist or
|
|
4867
|
+
* any other scope its datafeed applies. `mark` paints the scope's own mark into the
|
|
4695
4868
|
* box the chart owns and returns what takes it down; absent, the scope wears its initial. */
|
|
4696
4869
|
interface SearchScope {
|
|
4697
4870
|
readonly label: string;
|
|
@@ -4700,6 +4873,31 @@ interface SearchScope {
|
|
|
4700
4873
|
size: number;
|
|
4701
4874
|
}) => (() => void) | void;
|
|
4702
4875
|
}
|
|
4876
|
+
/** How the symbol search offers its class filter and its spread operators. Every field is optional,
|
|
4877
|
+
* and a host that sets none gets the default search: all six operators, an All chip, and one class
|
|
4878
|
+
* selected at a time. */
|
|
4879
|
+
interface SearchDisplayOptions {
|
|
4880
|
+
/** The spread operators and the expression rows. `true` (the default) offers every operator.
|
|
4881
|
+
* `false` offers no operator toggle, no operator and no expression row, and searches your feed
|
|
4882
|
+
* with the query exactly as typed. `{ operators }` keeps spreads on and offers only the listed
|
|
4883
|
+
* operators, in the listed order; an empty list offers no operator toggle while a typed
|
|
4884
|
+
* expression still reads as one. The compare dialog offers no operator buttons either way. */
|
|
4885
|
+
spreads?: boolean | {
|
|
4886
|
+
readonly operators: readonly SpreadOperatorId[];
|
|
4887
|
+
};
|
|
4888
|
+
/** The class strip's All chip. `false` offers none: with one class selected at a time the first
|
|
4889
|
+
* declared class starts selected, and with several, no selection means every class. `{ label }`
|
|
4890
|
+
* writes the chip with your label. Absent, the chip wears the catalog's own label. A class's own
|
|
4891
|
+
* row of narrower classes always opens with its all chip, written the same way. */
|
|
4892
|
+
allClasses?: false | {
|
|
4893
|
+
readonly label: string;
|
|
4894
|
+
};
|
|
4895
|
+
/** How many classes the viewer selects at once. `single` (the default) makes the chips a choice
|
|
4896
|
+
* of one, and your feed hears it as `cls`. `multiple` makes each chip a toggle, the All chip
|
|
4897
|
+
* clears the selection, and your feed hears `classes` with every selected class, and `cls` too
|
|
4898
|
+
* while exactly one is selected. */
|
|
4899
|
+
classSelection?: 'single' | 'multiple';
|
|
4900
|
+
}
|
|
4703
4901
|
/** Everything needed to construct a widget. `container` and `datafeed` are the two hard
|
|
4704
4902
|
* requirements; every other field has a working default. */
|
|
4705
4903
|
interface ChartWidgetOptions extends MarkPainterHooks {
|
|
@@ -4723,12 +4921,148 @@ interface ChartWidgetOptions extends MarkPainterHooks {
|
|
|
4723
4921
|
storage?: ChartStorage;
|
|
4724
4922
|
/** The symbol to open on. */
|
|
4725
4923
|
symbol?: string;
|
|
4726
|
-
/** The timeframe token to open on.
|
|
4924
|
+
/** The timeframe token to open on. With `timeframes` or `customTimeframes: false` it must be one
|
|
4925
|
+
* the chart offers. */
|
|
4727
4926
|
timeframe?: string;
|
|
4728
|
-
/** The main-series style to open on. */
|
|
4927
|
+
/** The main-series style to open on. It must be one of `styles`. */
|
|
4729
4928
|
style?: ChartStyleId;
|
|
4929
|
+
/** The main-series styles the chart offers, in this order. Absent, every style in `CHART_STYLES`
|
|
4930
|
+
* is offered and the picker groups them by family.
|
|
4931
|
+
*
|
|
4932
|
+
* A style left out stays off this chart: it has no `chart.style.<id>` command, so no
|
|
4933
|
+
* menu, shortcut or host control reaches it, and `setStyle` ignores it. The picker lists the
|
|
4934
|
+
* offered styles in the order given, and is not shown when one style is offered, since there is
|
|
4935
|
+
* nothing to choose. `ui.topBar.styles: false` hides the picker on its own terms.
|
|
4936
|
+
*
|
|
4937
|
+
* A saved layout, saved chart or stored preference that names a style outside the list opens on
|
|
4938
|
+
* the FIRST offered style, and the rest of it restores. An empty list, an id outside
|
|
4939
|
+
* `CHART_STYLES`, a repeated id, and a `style` outside the list are setup errors thrown from
|
|
4940
|
+
* `createChart`. */
|
|
4941
|
+
styles?: readonly ChartStyleId[];
|
|
4942
|
+
/** The timeframe tokens the chart offers. Absent, every preset in `TIMEFRAME_PRESETS` is offered
|
|
4943
|
+
* and the viewer may compose custom timeframes. Any token the grammar reads may be listed,
|
|
4944
|
+
* preset or not (`2m`). The order given does not matter: the picker lists each unit's group
|
|
4945
|
+
* smallest first.
|
|
4946
|
+
*
|
|
4947
|
+
* A token left out stays off this chart. A preset left out has no
|
|
4948
|
+
* `chart.timeframe.<token>` command, `chart.timeframe.set` and `setTimeframe` ignore a token
|
|
4949
|
+
* left out, and the picker shows no chip and no row for it. A group with no listed token is not
|
|
4950
|
+
* shown, a listed token beyond the presets sits in its unit's group, and there is no
|
|
4951
|
+
* custom-timeframe composer. The viewer's saved chips show where they are listed. When the list
|
|
4952
|
+
* leaves none of them, the chips are the first five listed tokens, and the viewer's stored chips
|
|
4953
|
+
* are kept unchanged for a chart that offers them. The picker is not shown when one timeframe is
|
|
4954
|
+
* offered, since there is nothing to choose. `ui.topBar.timeframes: false` hides the picker on
|
|
4955
|
+
* its own terms. A range preset whose timeframe is left out reads its span at the smallest
|
|
4956
|
+
* listed timeframe at or above that timeframe, else at the largest listed.
|
|
4957
|
+
*
|
|
4958
|
+
* A saved layout, saved chart or stored preference that names a token outside the list opens on
|
|
4959
|
+
* the SMALLEST listed timeframe, and the rest of it restores. An empty list, a token the grammar
|
|
4960
|
+
* cannot read, a repeated token, a `timeframe` or `layout.charts[].timeframe` outside the list,
|
|
4961
|
+
* and `customTimeframes: true` beside a list are setup errors thrown from `createChart`. */
|
|
4962
|
+
timeframes?: readonly string[];
|
|
4963
|
+
/** Whether the viewer may compose custom timeframes beyond the presets (default true). `false`
|
|
4964
|
+
* offers the 26 presets alone: the picker has no composer and lists none of the viewer's custom
|
|
4965
|
+
* timeframes, and `chart.timeframe.set` and `setTimeframe` ignore a token that is not a preset.
|
|
4966
|
+
* A stored token beyond the presets opens on `1m`, and a `timeframe` beyond them is a setup
|
|
4967
|
+
* error. A `timeframes` list offers nothing beyond itself, so `false` beside one changes nothing
|
|
4968
|
+
* and `true` beside one is a setup error.
|
|
4969
|
+
*
|
|
4970
|
+
* This switch is not `preferences.customTimeframes`, which is the list of custom tokens a
|
|
4971
|
+
* first-run viewer starts with. */
|
|
4972
|
+
customTimeframes?: boolean;
|
|
4973
|
+
/** The range presets the chart's bottom bar offers, by the key `RANGE_PRESETS` gives each
|
|
4974
|
+
* (`1D`, `5D`, `1M`, `3M`, `6M`, `YTD`, `1Y`, `5Y`, `All`), in this order. Absent, all nine
|
|
4975
|
+
* are offered in their own order.
|
|
4976
|
+
*
|
|
4977
|
+
* A preset left out stays off this chart: it has no `chart.range.<key>` command, so no
|
|
4978
|
+
* menu, shortcut or host control reaches it, `chart.range.set` ignores its key, and the bottom
|
|
4979
|
+
* bar draws no button for it. An empty list offers no preset: the bottom bar keeps its clock,
|
|
4980
|
+
* timezone picker and session view, and `chart.range.set` still takes an explicit window.
|
|
4981
|
+
* `ui.bottomBar: false` removes the whole bar. A preset whose timeframe `timeframes` leaves out
|
|
4982
|
+
* reads its span at the nearest coarser timeframe the chart offers. A non-list, a key that names
|
|
4983
|
+
* no preset and a repeated key are setup errors thrown from `createChart`. */
|
|
4984
|
+
ranges?: readonly string[];
|
|
4985
|
+
/** The display timezones the chart offers: zone ids `TIMEZONES` lists, and `exchange` for the
|
|
4986
|
+
* charted symbol's own zone. Absent, every zone and the exchange choice are offered. The
|
|
4987
|
+
* timezone picker keeps its own order (UTC, the exchange choice, then every zone by its current
|
|
4988
|
+
* offset); the order given decides only which choice is first.
|
|
4989
|
+
*
|
|
4990
|
+
* A choice left out stays off this chart: it has no `chart.timezone.<id>` command (or
|
|
4991
|
+
* `chart.timezone.exchange`), `chart.timezone.set` and `setTimezone` ignore it, and the picker
|
|
4992
|
+
* lists no row for it. With one choice offered the picker is not shown, since there is nothing to
|
|
4993
|
+
* choose, and the bottom bar's clock still reads the time in that zone.
|
|
4994
|
+
*
|
|
4995
|
+
* A chart opens on the viewer's stored choice, else `preferences.timezone`, when the list offers
|
|
4996
|
+
* it, and otherwise on the FIRST choice listed. A stored choice outside the list is not
|
|
4997
|
+
* rewritten until the viewer chooses, so a chart that offers it again opens on it. The exported
|
|
4998
|
+
* registry (`TIMEZONES`, `isTimezoneChoice`, `timezoneListing`) is never filtered. A non-list,
|
|
4999
|
+
* an empty list, an id that names no zone and a repeated id are setup errors thrown from
|
|
5000
|
+
* `createChart`. */
|
|
5001
|
+
timezones?: readonly string[];
|
|
4730
5002
|
/** The multi-chart arrangement. One chart when omitted. */
|
|
4731
5003
|
layout?: LayoutOptions;
|
|
5004
|
+
/** The arrangement codes the chart offers (`ARRANGEMENTS`). Absent, all 55 are offered. The
|
|
5005
|
+
* layout opens on `layout.arrangement`, else on the first code listed. The layout setup menu
|
|
5006
|
+
* keeps its own rows by chart count and shows only the listed arrangements, and the order given
|
|
5007
|
+
* breaks ties when a saved layout falls back (below).
|
|
5008
|
+
*
|
|
5009
|
+
* An arrangement left out stays off this chart: no tile shows it, and
|
|
5010
|
+
* `widget.layout.setArrangement` and the `widget.layout.setArrangement` command ignore it. With
|
|
5011
|
+
* one arrangement offered the layout setup menu is not shown, since there is nothing to choose,
|
|
5012
|
+
* unless that arrangement holds several charts and a sync switch is offered (`layoutSync`): the
|
|
5013
|
+
* menu then holds the switches alone. `['s']` is a single chart with no layout setup menu.
|
|
5014
|
+
* `ui.topBar.layoutSetup: false` hides the menu on its own terms.
|
|
5015
|
+
*
|
|
5016
|
+
* A saved layout whose arrangement is left out opens on the offered arrangement with the most
|
|
5017
|
+
* charts not above the saved layout's count, the first listed winning a tie. When every offered
|
|
5018
|
+
* arrangement holds more charts, it opens on the one with the fewest, and the panes past the
|
|
5019
|
+
* saved charts are filled as a re-tile fills new panes, from the first chart. Saved charts past
|
|
5020
|
+
* the ones shown are not dropped: the layout carries them, with the saved arrangement and its
|
|
5021
|
+
* divider positions, and a save of it writes them back unchanged beside the shown charts as they
|
|
5022
|
+
* are now, so a chart that offers the saved arrangement again opens all of them. A re-tile the
|
|
5023
|
+
* viewer or the host makes is a new arrangement, and what was carried goes with the charts it
|
|
5024
|
+
* tears down. A saved active chart among the hidden ones leaves the first chart active. Sync
|
|
5025
|
+
* switches restore as saved, apart from those `layoutSync` leaves out.
|
|
5026
|
+
*
|
|
5027
|
+
* An empty list, an unknown code, a repeated code and a `layout.arrangement` outside the list
|
|
5028
|
+
* are setup errors thrown from `createChart`. */
|
|
5029
|
+
layouts?: readonly string[];
|
|
5030
|
+
/** The sync switches the viewer may change (`symbol`, `timeframe`, `crosshair`, `time`,
|
|
5031
|
+
* `dateRange`). Absent, every one. A switch left out holds the value `layout.sync` gives it, or
|
|
5032
|
+
* off: the layout setup menu does not show it, `widget.layout.setSync` and its command leave it
|
|
5033
|
+
* as it is, and a saved layout cannot change it. An empty list fixes every switch and leaves the
|
|
5034
|
+
* layout setup menu the arrangements alone. An unknown or repeated switch is a setup error thrown
|
|
5035
|
+
* from `createChart`. */
|
|
5036
|
+
layoutSync?: readonly (keyof LayoutSyncFlags)[];
|
|
5037
|
+
/** The drawing tools the chart offers, by the type `access.drawingTool` and the `tool.<type>`
|
|
5038
|
+
* icon ids use: any type `drawingTools.all()` lists, `zoom` or `eraser`. Absent, every tool is
|
|
5039
|
+
* offered. The order given does not matter: the drawing toolbar keeps its own groups and
|
|
5040
|
+
* sections.
|
|
5041
|
+
*
|
|
5042
|
+
* A tool left out stays off this chart for creating drawings, and every place a tool is chosen
|
|
5043
|
+
* leaves it out: its group's flyout, a group's face (which wears the first tool the group
|
|
5044
|
+
* offers), the favorites bar and the drawing toolbar (`measure`, `zoom`). A section
|
|
5045
|
+
* or group it empties goes with it. The glyph picker's kinds are the `emoji`, `sticker` and
|
|
5046
|
+
* `icon` tools, and a kind left out has no tab. `chart.drawings.arm`, `armTool`, `placeImage` and
|
|
5047
|
+
* an image pasted over the chart refuse it. A copy of a drawing of it is refused too, since a
|
|
5048
|
+
* copy is a new drawing: `chart.drawings.clone` and `chart.drawings.paste` are unavailable for
|
|
5049
|
+
* one, `clone` and `paste` make nothing, and a modifier-drag moves the drawing instead of
|
|
5050
|
+
* duplicating it. Copying one to the clipboard, to paste on a chart that offers it, is not
|
|
5051
|
+
* refused.
|
|
5052
|
+
*
|
|
5053
|
+
* Drawings of a tool left out that are already on the chart (from a saved chart or layout, a
|
|
5054
|
+
* drawings document or another host) render and stay fully editable: they select, restyle
|
|
5055
|
+
* through the selection's bar and the settings dialog, lock, hide and delete as any drawing
|
|
5056
|
+
* does. The eraser is always offered, listed or not, because it removes rather than creates, so
|
|
5057
|
+
* `['eraser']` is a chart whose viewers keep and remove what is on it and make nothing new.
|
|
5058
|
+
*
|
|
5059
|
+
* It composes with `access`: a tool is offered when it is listed AND the policy permits it, and a
|
|
5060
|
+
* listed tool the policy refuses is drawn as `access.refused` says. Nothing stored is rewritten:
|
|
5061
|
+
* a starred tool left out keeps its star, and a group's remembered face is kept, for a chart that
|
|
5062
|
+
* offers them. `features.drawings: false` removes drawing altogether whatever the list says. An
|
|
5063
|
+
* empty list, a type that names no tool and a repeated type are setup errors thrown from
|
|
5064
|
+
* `createChart`. */
|
|
5065
|
+
drawingTools?: readonly string[];
|
|
4732
5066
|
/** Where the drawings are stored: with the chart's own saved content (the default) or in their
|
|
4733
5067
|
* own documents through the adapter's drawings family. */
|
|
4734
5068
|
drawingPersistence?: DrawingPersistenceOptions;
|
|
@@ -4749,10 +5083,35 @@ interface ChartWidgetOptions extends MarkPainterHooks {
|
|
|
4749
5083
|
access?: AccessPolicy;
|
|
4750
5084
|
/** Initial viewer preferences, for a first-run chart. A stored value wins once there is one. */
|
|
4751
5085
|
preferences?: Partial<ChartPreferences>;
|
|
4752
|
-
/** Optional localized content and actions in the chart-owned indicator
|
|
5086
|
+
/** Optional localized content and actions in the chart-owned indicator picker. */
|
|
4753
5087
|
indicatorPicker?: IndicatorPickerSource;
|
|
4754
5088
|
/** Indicator instances on the chart at mount. */
|
|
4755
5089
|
indicators?: IndicatorInstance[];
|
|
5090
|
+
/** The built-in indicators the chart offers, by the definition id `access.indicator` receives:
|
|
5091
|
+
* any id `BUILT_IN_INDICATORS` lists, such as `sma`. Absent, every built-in is offered. The order
|
|
5092
|
+
* given does not matter: the indicator picker keeps its own.
|
|
5093
|
+
*
|
|
5094
|
+
* A built-in left out stays off this chart. The indicator picker leaves it out of the built-ins,
|
|
5095
|
+
* the favorites (a starred one keeps its star in storage) and the search results, and the host's
|
|
5096
|
+
* `indicatorPicker` listing is handed only the offered ids. Every
|
|
5097
|
+
* door that would add one refuses: `chart.indicators.add` answers `denied`, `indicators.add`
|
|
5098
|
+
* adds nothing, `indicators.set` leaves out an instance of it the chart does not already hold,
|
|
5099
|
+
* and a new pane a re-tile adds copies the first chart's indicators without it. There is no
|
|
5100
|
+
* duplicate verb for an indicator; adding a second instance is adding.
|
|
5101
|
+
*
|
|
5102
|
+
* Instances of a built-in left out that are already on the chart (from a saved chart or layout,
|
|
5103
|
+
* an undo step or another host sharing the store) render and stay fully editable and removable:
|
|
5104
|
+
* the settings dialog, `chart.indicators.update`, the legend's eye and remove, remove all and
|
|
5105
|
+
* `indicators.remove` all work on them, and an edit that would move one onto another left-out
|
|
5106
|
+
* built-in keeps it as it stands. Nothing saved is rewritten because of the list.
|
|
5107
|
+
*
|
|
5108
|
+
* A definition whose `manifest.id` names no built-in is the host's own and is never filtered, nor
|
|
5109
|
+
* is what an `indicatorPicker` source lists. It composes with `access`: a built-in is offered
|
|
5110
|
+
* when it is listed AND the policy permits it, and a listed one the policy refuses is drawn as
|
|
5111
|
+
* `access.refused` says. A non-list, an empty list, an id that names no built-in, a repeated id
|
|
5112
|
+
* and an `indicators` instance whose built-in is not listed are setup errors thrown from
|
|
5113
|
+
* `createChart`. */
|
|
5114
|
+
builtInIndicators?: readonly string[];
|
|
4756
5115
|
/** A built-in interface language for the chart's chrome and its date formatting. */
|
|
4757
5116
|
locale?: ChartLocaleCode;
|
|
4758
5117
|
/** A host-owned localization adapter. When supplied it replaces `locale`, and the host owns its
|
|
@@ -4766,9 +5125,10 @@ interface ChartWidgetOptions extends MarkPainterHooks {
|
|
|
4766
5125
|
image?: ImageOptions;
|
|
4767
5126
|
/** The symbol picker's host inputs. The chart owns the search controller (its debounce, cache and
|
|
4768
5127
|
* cancellation); a host supplies only what it alone knows: where the viewer's recent symbols
|
|
4769
|
-
* live,
|
|
4770
|
-
* class's filter chip wears the class token as
|
|
4771
|
-
|
|
5128
|
+
* live, what its feed's asset classes are called, and how the classes and the spread operators
|
|
5129
|
+
* are offered. Absent, recents last the page, a class's filter chip wears the class token as
|
|
5130
|
+
* written, and the search offers its default class strip and operators. */
|
|
5131
|
+
search?: SearchDisplayOptions & {
|
|
4772
5132
|
recents?: RecentsPort;
|
|
4773
5133
|
/** Display names for the asset-class tokens the feed's `config()` declares in `classes`. */
|
|
4774
5134
|
classNames?: Readonly<Record<string, string>>;
|
|
@@ -4785,7 +5145,7 @@ interface ChartWidgetOptions extends MarkPainterHooks {
|
|
|
4785
5145
|
marks?: boolean;
|
|
4786
5146
|
}
|
|
4787
5147
|
|
|
4788
|
-
/** Host-owned activity, displayed with
|
|
5148
|
+
/** Host-owned activity, displayed with indicators but never saved as an indicator or plotted. */
|
|
4789
5149
|
interface ChartLegendRow {
|
|
4790
5150
|
id: string;
|
|
4791
5151
|
title: string;
|
|
@@ -4924,7 +5284,8 @@ type TopBarSlot = (typeof TOP_BAR_SLOTS)[number];
|
|
|
4924
5284
|
* A slot is live for as long as the widget is. A host appends its own node and takes that node back
|
|
4925
5285
|
* out again; the slot itself belongs to the chart and is never removed or replaced. */
|
|
4926
5286
|
interface ChartChrome {
|
|
4927
|
-
/** Transient host activity in this chart's native
|
|
5287
|
+
/** Transient host activity in this chart's native indicator list. Does not affect chart
|
|
5288
|
+
* content. */
|
|
4928
5289
|
legendRows(chartId: string, rows: readonly ChartLegendRow[]): void;
|
|
4929
5290
|
/** One named place in the top bar. Null when the top bar is hidden, which is the answer a host
|
|
4930
5291
|
* checks before composing a door it would have nowhere to put. */
|
|
@@ -4960,6 +5321,15 @@ interface ChartWidget {
|
|
|
4960
5321
|
/** The chrome's host slots. A host that composes its own doors puts them here rather than beside
|
|
4961
5322
|
* the chart, so a service the chart does not own still reads as part of the same toolbar. */
|
|
4962
5323
|
chrome: ChartChrome;
|
|
5324
|
+
/** Ask the access policy again, now. The chart's own controls read `access` whenever they sync
|
|
5325
|
+
* and whenever a menu opens; call this when the policy's answers changed with nothing on the
|
|
5326
|
+
* chart changing (a viewer's plan changed mid-session). Every control, menu row, drawing toolbar
|
|
5327
|
+
* tool and group, the favorites bar, the glyph picker, the legend's row controls and every menu,
|
|
5328
|
+
* flyout and dialog that is open (the indicator picker among them) read the policy again: shown
|
|
5329
|
+
* or left out under `access.refused`, enabled or disabled. Listeners of `commands.onChange` hear
|
|
5330
|
+
* it too, so a host's own controls can read `commands.available` again. Nothing stored and
|
|
5331
|
+
* nothing on the chart changes. Inert after `dispose`. */
|
|
5332
|
+
refreshAccess(): void;
|
|
4963
5333
|
on<K extends keyof WidgetEvents>(name: K, callback: WidgetEvents[K]): () => void;
|
|
4964
5334
|
/** Tear down every chart, subscription, timer and DOM resource. Idempotent, and every handle and
|
|
4965
5335
|
* subscription is inert afterwards. */
|
|
@@ -4995,7 +5365,7 @@ declare class FillBetweenPrimitive implements ISeriesPrimitive<Time> {
|
|
|
4995
5365
|
private lower;
|
|
4996
5366
|
private colors;
|
|
4997
5367
|
/** Nothing until the first `setData`, which every render path makes before a draw. A tint chosen
|
|
4998
|
-
* here would be a second
|
|
5368
|
+
* here would be a second indicator default with no owner. */
|
|
4999
5369
|
private color;
|
|
5000
5370
|
attached(param: SeriesAttachedParameter<Time>): void;
|
|
5001
5371
|
detached(): void;
|
|
@@ -5024,7 +5394,7 @@ declare class ShadePrimitive implements ISeriesPrimitive<Time> {
|
|
|
5024
5394
|
* isCollapsed would deny the restore affordance forever. */
|
|
5025
5395
|
declare const COLLAPSED_H = 30;
|
|
5026
5396
|
/** The main pane never shrinks below this, whatever a maximize asks for: an unreadable price pane
|
|
5027
|
-
* is worse than an unmaximized
|
|
5397
|
+
* is worse than an unmaximized indicator. */
|
|
5028
5398
|
declare const MAIN_MIN_H = 80;
|
|
5029
5399
|
type PaneOp = {
|
|
5030
5400
|
kind: 'collapse';
|
|
@@ -5139,7 +5509,7 @@ declare const SESSION_DOT: Readonly<Record<SessionState, ThemeRoleId>>;
|
|
|
5139
5509
|
* model, merged into runs, and drawn as full-height rects UNDER the main series (zOrder bottom).
|
|
5140
5510
|
* Re-renders with every chart paint, so it tracks pan/zoom for free. An UNKNOWN model (null)
|
|
5141
5511
|
* never bands: drawing nothing is the only honest render before the symbol resolves. A continuous
|
|
5142
|
-
* market never bands (it is always open), and bands render on INTRADAY
|
|
5512
|
+
* market never bands (it is always open), and bands render on INTRADAY timeframes only: a daily or
|
|
5143
5513
|
* larger bar spans whole sessions, so classifying its single timestamp would shade entire days by
|
|
5144
5514
|
* whichever session that instant fell in. */
|
|
5145
5515
|
interface SessionBandsPrimitive {
|
|
@@ -5256,9 +5626,9 @@ interface Timeframe {
|
|
|
5256
5626
|
readonly count: number;
|
|
5257
5627
|
readonly unit: TimeframeUnit;
|
|
5258
5628
|
}
|
|
5259
|
-
/** Every unit, smallest first: the custom-
|
|
5629
|
+
/** Every unit, smallest first: the custom-timeframe picker's unit rows and the sort order. */
|
|
5260
5630
|
declare const TIMEFRAME_UNITS: readonly TimeframeUnit[];
|
|
5261
|
-
/** The inclusive per-unit count ceiling. A token past it parses as null, so a custom-
|
|
5631
|
+
/** The inclusive per-unit count ceiling. A token past it parses as null, so a custom-timeframe
|
|
5262
5632
|
* input disables Add and a feed is never asked for it. */
|
|
5263
5633
|
declare const TIMEFRAME_MAX: Readonly<Record<TimeframeUnit, number>>;
|
|
5264
5634
|
/** Nominal seconds per unit: exact for the fixed-duration units (s/m/h/d/w), a coarse nominal for
|
|
@@ -5274,7 +5644,7 @@ declare function formatTimeframe(tf: Timeframe): string | null;
|
|
|
5274
5644
|
* count). */
|
|
5275
5645
|
declare function timeframeSeconds(tf: Timeframe): number;
|
|
5276
5646
|
/** True for a sub-daily token (ticks, seconds, minutes, hours). Session bands and the
|
|
5277
|
-
* regular-hours filter engage on intraday
|
|
5647
|
+
* regular-hours filter engage on intraday timeframes only, because a daily or larger bar spans
|
|
5278
5648
|
* whole sessions. A token the grammar cannot read is NOT intraday: mis-shading a chart is worse
|
|
5279
5649
|
* than not shading it. */
|
|
5280
5650
|
declare function isIntradayTimeframe(token: string): boolean;
|
|
@@ -5298,18 +5668,18 @@ interface TimeframeGroup {
|
|
|
5298
5668
|
/** The 26 preset timeframes, grouped as the picker shows them. Weeks and months share the Days
|
|
5299
5669
|
* group. The count is a release inventory: it moves only by decision. */
|
|
5300
5670
|
declare const TIMEFRAME_PRESETS: readonly TimeframeGroup[];
|
|
5301
|
-
/** Every preset token across the groups. A custom
|
|
5671
|
+
/** Every preset token across the groups. A custom timeframe that already exists as a preset is
|
|
5302
5672
|
* refused rather than listed twice. */
|
|
5303
5673
|
declare const TIMEFRAME_PRESET_TOKENS: ReadonlySet<string>;
|
|
5304
|
-
/** The unit's own name in the chart catalog: a picker group's heading and the custom-
|
|
5674
|
+
/** The unit's own name in the chart catalog: a picker group's heading and the custom-timeframe
|
|
5305
5675
|
* unit rows. */
|
|
5306
5676
|
declare const TIMEFRAME_UNIT_NAME: Readonly<Record<TimeframeUnit, ChartMessageKey>>;
|
|
5307
5677
|
/** A readable label for a token in the chart's language: '5t' reads "5 Ticks", '1h' reads
|
|
5308
5678
|
* "1 Hour". A token the grammar cannot read is returned as written, which is what the feed calls
|
|
5309
5679
|
* it, never a blank. */
|
|
5310
5680
|
declare function timeframeLabel(t: ChartTranslate, token: string): string;
|
|
5311
|
-
/** What a symbol and its feed declare about the
|
|
5312
|
-
* an EMPTY list is no restriction: a feed or symbol that serves any
|
|
5681
|
+
/** What a symbol and its feed declare about the timeframes they serve. Both lists are optional and
|
|
5682
|
+
* an EMPTY list is no restriction: a feed or symbol that serves any timeframe says nothing rather
|
|
5313
5683
|
* than listing everything. `supportedResolutions` is the symbol's own list (`SymbolInfo`);
|
|
5314
5684
|
* `resolutions` is the feed-level list (`DatafeedConfig`). A token must pass every list given. */
|
|
5315
5685
|
interface TimeframeRestrictions {
|
|
@@ -5329,10 +5699,10 @@ interface ChartTimezone {
|
|
|
5329
5699
|
/** The display city, as the timezone picker writes it. */
|
|
5330
5700
|
readonly city: string;
|
|
5331
5701
|
}
|
|
5332
|
-
/** The selectable zones: one city per offset region a
|
|
5702
|
+
/** The selectable zones: one city per offset region a viewer picks. The count is a release
|
|
5333
5703
|
* inventory: it moves only by decision. */
|
|
5334
5704
|
declare const TIMEZONES: readonly ChartTimezone[];
|
|
5335
|
-
/** The zone a chart displays in before a host or a
|
|
5705
|
+
/** The zone a chart displays in before a host or a viewer chooses one. */
|
|
5336
5706
|
declare const DEFAULT_TIMEZONE = "Etc/UTC";
|
|
5337
5707
|
/** The timezone choice that follows the charted symbol's exchange: a display preference resolves
|
|
5338
5708
|
* it per symbol through {@link resolveDisplayTimezone}. */
|
|
@@ -5393,58 +5763,6 @@ declare function timezoneListing(t: ChartTranslate, options?: {
|
|
|
5393
5763
|
at?: Date;
|
|
5394
5764
|
}): TimezoneRow[];
|
|
5395
5765
|
|
|
5396
|
-
/** What a preset frames: seconds of history, the year to date, or everything loaded. */
|
|
5397
|
-
type RangeSpan = number | 'ytd' | 'all';
|
|
5398
|
-
interface RangePreset {
|
|
5399
|
-
/** The preset's identity and the text its chip wears ('1D', 'YTD', 'All'). It stays as written
|
|
5400
|
-
* in every language; a host names the preset by it. */
|
|
5401
|
-
readonly key: string;
|
|
5402
|
-
readonly span: RangeSpan;
|
|
5403
|
-
/** The timeframe token the preset switches the chart to. */
|
|
5404
|
-
readonly tf: string;
|
|
5405
|
-
/** The catalog key of the preset's full name, for its tooltip. */
|
|
5406
|
-
readonly label: ChartMessageKey;
|
|
5407
|
-
}
|
|
5408
|
-
/** The nine presets, in bar order. */
|
|
5409
|
-
declare const RANGE_PRESETS: readonly RangePreset[];
|
|
5410
|
-
/** The seconds a span covers back from `nowSecs`; null for 'all', which has no span. */
|
|
5411
|
-
declare function rangeSpanSeconds(span: RangeSpan, nowSecs: number): number | null;
|
|
5412
|
-
/** Whether a preset is offered for a symbol whose earliest bar is at `earliestBarSecs`: a preset
|
|
5413
|
-
* deeper than the history that exists is withheld (a listing from last year has no 5Y), 'All'
|
|
5414
|
-
* always stays, and an unknown depth (null) withholds nothing. The depth itself is the host's to
|
|
5415
|
-
* learn from its feed; the chart does not probe. */
|
|
5416
|
-
declare function rangeAvailable(preset: RangePreset, earliestBarSecs: number | null | undefined, nowSecs?: number): boolean;
|
|
5417
|
-
/** A preset's tooltip: what it frames, and the bars it frames it in. */
|
|
5418
|
-
declare function rangePresetTip(t: ChartTranslate, preset: RangePreset): string;
|
|
5419
|
-
/** The part of a chart the framing needs: a time scale that takes a logical range. */
|
|
5420
|
-
interface RangeFrameTarget {
|
|
5421
|
-
timeScale(): {
|
|
5422
|
-
setVisibleLogicalRange(range: {
|
|
5423
|
-
from: number;
|
|
5424
|
-
to: number;
|
|
5425
|
-
}): void;
|
|
5426
|
-
};
|
|
5427
|
-
}
|
|
5428
|
-
/** Frame a pane on a span, anchored on its LAST REAL bar: a series also carries a future
|
|
5429
|
-
* whitespace horizon for right-margin drawing, so fitting to content would frame a screen of
|
|
5430
|
-
* empty space. The bar count comes from the pane's own interval, because the same span is a
|
|
5431
|
-
* different number of bars on a one-minute pane than on a daily one. An empty series, or a token
|
|
5432
|
-
* the grammar cannot read, frames nothing rather than a bogus window. */
|
|
5433
|
-
declare function frameRange(chart: RangeFrameTarget, series: {
|
|
5434
|
-
data(): readonly unknown[];
|
|
5435
|
-
}, span: RangeSpan, tf: string, nowSecs?: number): void;
|
|
5436
|
-
/** One zoom step multiplies or divides the bar spacing by this. */
|
|
5437
|
-
declare const ZOOM_FACTOR = 1.25;
|
|
5438
|
-
/** The bar spacing a zoom-out never goes below. */
|
|
5439
|
-
declare const MIN_BAR_SPACING = 0.5;
|
|
5440
|
-
/** How far one scroll step moves, in bars. */
|
|
5441
|
-
declare const SCROLL_STEP_BARS = 10;
|
|
5442
|
-
/** The bar spacing after one zoom step from `spacing`. */
|
|
5443
|
-
declare function zoomedBarSpacing(spacing: number, direction: 'in' | 'out'): number;
|
|
5444
|
-
/** The time-scale scroll position after one scroll step from `position` (positive is right, as
|
|
5445
|
-
* lightweight-charts counts it). */
|
|
5446
|
-
declare function scrolledPosition(position: number, direction: 'left' | 'right'): number;
|
|
5447
|
-
|
|
5448
5766
|
/** A catalog kept warm between opens, from `createSymbolSearchCache`. Completed pages outlive a
|
|
5449
5767
|
* dialog, so the second open of a picker, and the first one on a page that warmed it, stands on
|
|
5450
5768
|
* what the viewer already saw instead of a loading line. Query state and in-flight work never pass
|
|
@@ -5460,7 +5778,7 @@ declare function createSymbolSearchCache(options: {
|
|
|
5460
5778
|
datafeed: Pick<ChartDatafeed, 'search'>;
|
|
5461
5779
|
pageSize?: number;
|
|
5462
5780
|
}): SymbolSearchCache;
|
|
5463
|
-
interface SymbolSearchOptions extends MarkPainterHooks {
|
|
5781
|
+
interface SymbolSearchOptions extends MarkPainterHooks, SearchDisplayOptions {
|
|
5464
5782
|
/** The feed the search runs against: the one a chart takes, or anything that answers `search`. */
|
|
5465
5783
|
datafeed: Pick<ChartDatafeed, 'search'>;
|
|
5466
5784
|
/** A catalog warmed over that same feed. Absent, this picker searches from cold and its pages go
|
|
@@ -5481,8 +5799,9 @@ interface SymbolSearchOptions extends MarkPainterHooks {
|
|
|
5481
5799
|
icons?: ChartIcons;
|
|
5482
5800
|
/** Where recent picks are read and written. Default: a list that lives as long as the dialog. */
|
|
5483
5801
|
recents?: RecentsPort;
|
|
5484
|
-
/** The asset classes the feed declares, for the filter strip
|
|
5485
|
-
|
|
5802
|
+
/** The asset classes the feed declares, for the filter strip, as a feed's `config()` declares
|
|
5803
|
+
* them. Absent, there is no strip. */
|
|
5804
|
+
classes?: readonly (string | SearchClassNode)[] | null;
|
|
5486
5805
|
/** Display names for those classes. A class without one wears its token. */
|
|
5487
5806
|
classNames?: Readonly<Record<string, string>>;
|
|
5488
5807
|
/** The query the field opens holding, selected so that typing replaces it. */
|
|
@@ -5511,4 +5830,59 @@ declare function mountSymbolSearch(options: SymbolSearchOptions & {
|
|
|
5511
5830
|
container: HTMLElement;
|
|
5512
5831
|
}): MountedSymbolSearch;
|
|
5513
5832
|
|
|
5514
|
-
|
|
5833
|
+
interface TimeframePickerOptions {
|
|
5834
|
+
/** Where the picked timeframe goes. The drop-down closes on the pick. */
|
|
5835
|
+
onPick(timeframe: string): void;
|
|
5836
|
+
/** The timeframe the list opens on, checked: the page's current value. Absent, no row is checked.
|
|
5837
|
+
* It must be one the list offers. */
|
|
5838
|
+
timeframe?: string;
|
|
5839
|
+
/** The timeframes the list offers, as a chart's `timeframes` names them: any tokens the grammar
|
|
5840
|
+
* reads, in any order, drawn smallest first in their units' groups, with no composer. */
|
|
5841
|
+
timeframes?: readonly string[];
|
|
5842
|
+
/** Whether the list offers composing a custom timeframe, as a chart's `customTimeframes` says.
|
|
5843
|
+
* Default true; `false` offers the presets alone. */
|
|
5844
|
+
customTimeframes?: boolean;
|
|
5845
|
+
/** The resolutions the feed serves, as a feed's `config()` declares them. A timeframe outside
|
|
5846
|
+
* them is left out of the list, as the chart's list leaves it out, and is never composed. */
|
|
5847
|
+
resolutions?: readonly string[] | null;
|
|
5848
|
+
/** The resolutions the symbol serves, as its `supportedResolutions` declares them, with the same
|
|
5849
|
+
* effect. */
|
|
5850
|
+
supportedResolutions?: readonly string[] | null;
|
|
5851
|
+
/** The element the drop-down's layer mounts in. Default: the document body, where the list stands
|
|
5852
|
+
* over the page rather than inside whatever box opened it. */
|
|
5853
|
+
container?: HTMLElement;
|
|
5854
|
+
/** Mode and palettes, as a chart takes them. Default: dark. */
|
|
5855
|
+
theme?: ThemeControllerOptions;
|
|
5856
|
+
/** The language, as a chart takes it. */
|
|
5857
|
+
locale?: string;
|
|
5858
|
+
/** A prepared runtime, when the page already has the chart's. It wins over `locale`. */
|
|
5859
|
+
i18n?: ChartI18n;
|
|
5860
|
+
/** The host's drawings for the list's glyphs, as a chart takes them. */
|
|
5861
|
+
icons?: ChartIcons;
|
|
5862
|
+
/** Called once the list is gone, however it went. */
|
|
5863
|
+
onClose?(): void;
|
|
5864
|
+
}
|
|
5865
|
+
interface TimeframePickerHandle {
|
|
5866
|
+
/** Close it from the outside. Closing twice is safe, and the list's own close is the same door. */
|
|
5867
|
+
close(): void;
|
|
5868
|
+
}
|
|
5869
|
+
/** Drop the chart's timeframe list from a control the page owns, with no chart behind it. */
|
|
5870
|
+
declare function openTimeframePicker(options: TimeframePickerOptions & {
|
|
5871
|
+
anchor: HTMLElement;
|
|
5872
|
+
}): TimeframePickerHandle;
|
|
5873
|
+
interface MountedTimeframePicker {
|
|
5874
|
+
/** The element the list was built into, for a page that measures or animates its own box. */
|
|
5875
|
+
element: HTMLElement;
|
|
5876
|
+
/** Put focus on the checked row, or the first, for a page whose box has just opened. */
|
|
5877
|
+
focus(): void;
|
|
5878
|
+
/** Take it down: the element goes. */
|
|
5879
|
+
dispose(): void;
|
|
5880
|
+
}
|
|
5881
|
+
/** The same list with no drop-down around it, built into a box the page owns and positions: a
|
|
5882
|
+
* phone's card, a panel in a page's own chrome. The page decides where it stands and when it goes;
|
|
5883
|
+
* picking hands the timeframe back, then calls `onClose`, which is the page's cue to close its box. */
|
|
5884
|
+
declare function mountTimeframePicker(options: TimeframePickerOptions & {
|
|
5885
|
+
container: HTMLElement;
|
|
5886
|
+
}): MountedTimeframePicker;
|
|
5887
|
+
|
|
5888
|
+
export { ARRANGEMENTS, type AccessPolicy, type ActiveSubsession, type Arrangement, type AttachDrawingsOptions, BRAND_DOWN, BRAND_UP, BUILT_IN_INDICATORS, BUILT_IN_LOCALES, type BarMark, type BarsEvent, type BuiltInIndicator, CHART_ICON_IDS, CHART_STYLES, COLLAPSED_H, COMPARE_COLORS, type CanvasTheme, type Capabilities, ChartBody, type ChartChrome, type ChartCompareApi, type ChartCustomLocale, type ChartDatafeed, type ChartDictionary, type ChartDrawingsApi, type ChartEvents, type ChartExtension, type ChartExtensionChart, type ChartExtensionCommand, type ChartExtensionContext, type ChartExtensionHandle, type ChartExtensionIcon, type ChartExtensionIconPath, type ChartExtensionMenuBuilder, type ChartExtensionMenuContext, type ChartExtensionMenuItem, type ChartExtensionPane, type ChartExtensionPriceLine, type ChartExtensionReplayState, type ChartExtensionScope, type ChartExtensionSeries, type ChartHandle, type ChartHistoryApi, type ChartI18n, type ChartI18nOptions, type ChartIconContext, type ChartIconDiagnostic, type ChartIconFactory, type ChartIconFailure, type ChartIconId, type ChartIcons, type ChartLegendRow, type ChartLocale, type ChartLocaleCode, type ChartMenuAction, type ChartMenuContext, type ChartMenuIcon, type ChartMenuRow, ChartMessageKey, ChartMeta, type ChartOverrides, type ChartPaneSyncApi, type ChartPreferences, type ChartPriceFormatter, type ChartReplayApi, ChartSaveLoadAdapter, type ChartSaveLoadApi, type ChartStorage, type ChartStyleId, type ChartTimezone, type ChartTranslate, type ChartWidget, type ChartWidgetOptions, type CommandRegistry, type CommandResult, type CommandScope, type CommandSpec, type CompareDeps, type CompareEntry, type CompareHandle, type ComparePlacement, type CompareSnapshot, type CompareSymbol, type ContextMenuHandle, type CustomThemes, DEFAULT_OVERRIDES, DEFAULT_SUBSESSION, DEFAULT_TIMEZONE, type DataSourceMarkPainter, type DataStatus, type DatafeedConfig, type DatafeedSearchOptions, type DrawingApplyOutcome, DrawingAssetPort, DrawingContextKind, type DrawingDocumentApi, type DrawingDocumentPort, type DrawingDocumentRefusal, type DrawingEvent, type DrawingOwner, DrawingPreferences, type DrawingPresets, type DrawingReadOutcome, type DrawingRejection, type DrawingRejectionReason, DrawingResourceContext, DrawingsBody, type DrawingsEvents, type DrawingsHandle, DrawingsMeta, type DrawingsWorkflow, EXCHANGE_TIMEZONE, type FeatureConfig, type FeedBar, FeedUnavailableError, type FetchLike, FillBetweenPrimitive, type FullscreenApi, type FullscreenOptions, type HistoryChange, type HistoryEventState, type HistoryPage, IMAGE_HEADER_H, type ImageApi, type ImageEvent, type ImageHeader, type ImageOptions, type ImageTextRun, type ImageTile, type IndicatorCategory, type IndicatorDefinition, type IndicatorEvent, type IndicatorFill, type IndicatorInstance, type IndicatorLevel, type IndicatorManifest, type IndicatorOverrides, type IndicatorPickerAction, type IndicatorPickerBuiltInState, type IndicatorPickerCollection, type IndicatorPickerItem, type IndicatorPickerSource, type IndicatorPlot, type IndicatorPlots, type IndicatorsApi, type IndicatorsRenderer, LAYOUT_MENU_ROWS, type LayoutApi, LayoutBody, type LayoutEvent, LayoutMeta, type LayoutOptions, type LayoutSaveLoadApi, type LayoutSyncFlags, type LegendUi, type LogicalRange, MAIN_MIN_H, MIN_BAR_SPACING, MIRRORED_ICONS, type ManifestFill, type ManifestInput, type ManifestLevel, type ManifestPlot, type ManifestRun, type MarkColorRole, type MarkPainters, type MarkPlacement, type MarkShape, type MarketStatus, type MatchSegment, type MountedSymbolSearch, type MountedTimeframePicker, type NumericPunctuation, type OlderPageVerdict, type OpenResource, PRICE_SCALE_MODE, type PaneOp, type PanePlan, type PaneRect, type PaneState, type PartialOverrides, type PlacedImage, type PlotPoint, type PriceFormat, type PriceFormatter, type PriceFormatterOptions, RANGE_PRESETS, RECENT_SYMBOLS_CAP, REPLAY_SPEEDS, type RangeFrameTarget, type RangePreset, type RangeSpan, type RecentsPort, type ReplayEventState, type ReplaySpeed, type ResourceLoadOutcome, ResourceRef, type ResourceRemoveOutcome, type ResourceSaveOutcome, ResourceStore, SCALE_MODES, SCALE_MODE_OPTIONS, SCROLL_STEP_BARS, SESSION_DOT, SESSION_LABEL, SESSION_STATE_TITLE, SPREAD_OPERATORS, type SaveConflictInfo, type ScaleMode, type SearchClassFilter, type SearchClassNode, type SearchController, type SearchControllerOptions, type SearchDisplayOptions, type SearchPage, type SearchScope, type SearchState, type SelectedDrawing, type SemanticTheme, type SessionBandsPrimitive, type SessionModel, type SessionSchedule, type SessionSegment, type SessionSource, type SessionState, type SessionTimeline, type SettingsMenuUi, ShadePrimitive, type SpreadOperator, type SpreadOperatorId, type SubscribeHandlers, type Subsession, type SubsessionId, type SubsessionSource, type SymbolInfo, type SymbolMarkPainter, type SymbolNames, type SymbolPriceFormat, type SymbolRow, type SymbolSearchCache, type SymbolSearchHandle, type SymbolSearchOptions, THEME_ROLES, TIMEFRAME_MAX, TIMEFRAME_PRESETS, TIMEFRAME_PRESET_TOKENS, TIMEFRAME_UNITS, TIMEFRAME_UNIT_NAME, TIMEFRAME_UNIT_SECONDS, TIMEZONES, TOP_BAR_SLOTS, TemplateBody, TemplateMeta, type TextEditSession, type ThemeChangeListener, type ThemeController, type ThemeControllerOptions, type ThemeDeclaration, type ThemeDiagnostic, type ThemeDiagnosticCode, type ThemeMode, type ThemeOptions, type ThemeRole, type ThemeRoleFamily, type ThemeRoleId, type ThemeRoleKind, type ThemeRootStyle, type TickBand, type TimeRange, type Timeframe, type TimeframeGroup, type TimeframePickerHandle, type TimeframePickerOptions, type TimeframeRestrictions, type TimeframeUnit, type TimescaleMark, type TimezoneRow, type ToolbarButton, type ToolbarButtonOptions, type ToolbarButtonState, type TopBarSlot, type TopBarUi, type UdfDatafeedOptions, type UdfSymbolResponse, type UiConfig, type VenueMarkPainter, type WidgetEvents, ZOOM_FACTOR, type ZoneClock, allowedTimeframes, applyBar, applyPlotOverrides, arrangementName, arrangementOf, attachCompare, attachDrawings, attachIndicators, autoTimeframeFor, buildManifestPlots, canvasTheme, canvasToBlob, chartContextMenu, chartDictionaries, clipToWindow, coerceChartStyle, coerceScaleMode, compareTimeframes, composeFormingBar, composeImage, createChart, createChartI18n, createPriceFormatter, createSearchController, createSessionBands, createSymbolSearchCache, createThemeController, createUdfDatafeed, effectivePlotColor, exchangeTimezoneText, formatClock, formatDuration, formatTimeframe, frameRange, hasExtendedHours, imageFileName, imageHeaderRuns, imageLayoutHeaderRuns, imageTileRuns, indicatorHidden, isChartStyle, isCollapsed, isIntradayTimeframe, isSymbolPair, isTimezoneChoice, latestPlotValue, layerOverrides, looksLikeSpread, makeCrosshairTimeFormatter, makeTickMarkFormatter, manifestInputDefaults, marketStatus, marketStatusFor, marketStatusText, marketStatusTitle, matchSegments, memoryChartStorage, memoryRecents, mergeOverrides, mountContextMenu, mountSymbolSearch, mountTimeframePicker, nextSessionChange, olderPageVerdict, openInputsEditor, openSymbolSearch, openTimeframePicker, overriddenManifest, parseSessionModel, parseTickBands, parseTimeframe, pickCompareColor, placeableByWidget, planPaneOp, promoteRecent, rangeAvailable, rangePresetTip, rangeSpanSeconds, resolveDisplayTimezone, resolveInitialTf, scrolledPosition, seriesTargetOf, sessionStateAt, sessionTimeline, spreadExpression, spreadSearchQuery, subTimeframesFor, subsessionBarFilter, symbolNames, tfSeconds, tfToUdfResolution, tickBandFor, timeframeAllowed, timeframeGroupUnit, timeframeLabel, timeframeOrder, timeframeSeconds, timezoneCity, timezoneLabel, timezoneListing, toolName, tzOffsetLabel, tzOffsetMinutes, udfPriceFormat, udfResolutionToTf, udfSymbolInfo, valueShaped, withFoldedHistory, zoneClock, zoomedBarSpacing };
|