@trdrs/quickcharts 5.1.1 → 5.3.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 +20 -0
- package/README.md +65 -17
- package/dist/{ar-TG26ZCCE.js → ar-BBRV6CC4.js} +5 -1
- package/dist/{ar-TG26ZCCE.js.map → ar-BBRV6CC4.js.map} +1 -1
- package/dist/{assets-DF3nozNV.d.ts → assets-B_JlJaHF.d.ts} +4 -0
- package/dist/{ca_ES-WJWH5BXU.js → ca_ES-OF2NGA3A.js} +5 -1
- package/dist/{ca_ES-WJWH5BXU.js.map → ca_ES-OF2NGA3A.js.map} +1 -1
- package/dist/{chunk-Q3DCXQDW.js → chunk-FRZFOTMO.js} +42 -39
- package/dist/chunk-FRZFOTMO.js.map +1 -0
- package/dist/{chunk-GFQQSY47.js → chunk-U4W26DXU.js} +2 -2
- package/dist/{chunk-GFQQSY47.js.map → chunk-U4W26DXU.js.map} +1 -1
- package/dist/{de-SUDTTPQ3.js → de-D5WWQLT5.js} +5 -1
- package/dist/{de-SUDTTPQ3.js.map → de-D5WWQLT5.js.map} +1 -1
- package/dist/drawings.d.ts +2 -2
- package/dist/drawings.js +1 -1
- package/dist/{es-FOBXUK2X.js → es-6TM3Z6CQ.js} +5 -1
- package/dist/{es-FOBXUK2X.js.map → es-6TM3Z6CQ.js.map} +1 -1
- package/dist/feature-manifest.json +6 -1
- package/dist/{fr-7KQC4IJH.js → fr-L5EPUMNA.js} +5 -1
- package/dist/{fr-7KQC4IJH.js.map → fr-L5EPUMNA.js.map} +1 -1
- package/dist/{he_IL-2T6XBA6D.js → he_IL-PXH4KNDC.js} +5 -1
- package/dist/{he_IL-2T6XBA6D.js.map → he_IL-PXH4KNDC.js.map} +1 -1
- package/dist/{id_ID-SI25N57C.js → id_ID-MMY4EQSL.js} +5 -1
- package/dist/{id_ID-SI25N57C.js.map → id_ID-MMY4EQSL.js.map} +1 -1
- package/dist/index.d.ts +29 -6
- package/dist/index.js +229 -119
- package/dist/index.js.map +1 -1
- package/dist/{it-PMSTWZDL.js → it-TUILRXJ5.js} +5 -1
- package/dist/{it-PMSTWZDL.js.map → it-TUILRXJ5.js.map} +1 -1
- package/dist/{ja-PABDRAXV.js → ja-7QY2FLXF.js} +5 -1
- package/dist/{ja-PABDRAXV.js.map → ja-7QY2FLXF.js.map} +1 -1
- package/dist/{ko-JHRYYFCV.js → ko-RWI5JOO2.js} +5 -1
- package/dist/{ko-JHRYYFCV.js.map → ko-RWI5JOO2.js.map} +1 -1
- package/dist/{ms_MY-U4EE5Q4V.js → ms_MY-ABJSZCPH.js} +5 -1
- package/dist/{ms_MY-U4EE5Q4V.js.map → ms_MY-ABJSZCPH.js.map} +1 -1
- package/dist/{pl-4HCG3T3J.js → pl-XLOQLQVW.js} +5 -1
- package/dist/{pl-4HCG3T3J.js.map → pl-XLOQLQVW.js.map} +1 -1
- package/dist/{pt-6LTNN653.js → pt-TZWQOZ5P.js} +5 -1
- package/dist/{pt-6LTNN653.js.map → pt-TZWQOZ5P.js.map} +1 -1
- package/dist/quickcharts.css +369 -372
- package/dist/{ru-LFHCSDBV.js → ru-2KVG2H7U.js} +5 -1
- package/dist/{ru-LFHCSDBV.js.map → ru-2KVG2H7U.js.map} +1 -1
- package/dist/{sv-4XVUXYK6.js → sv-3JTSBHQN.js} +5 -1
- package/dist/{sv-4XVUXYK6.js.map → sv-3JTSBHQN.js.map} +1 -1
- package/dist/{symbols-CHJGWrf-.d.ts → symbols-CCYUK8MU.d.ts} +5 -1
- package/dist/symbols.d.ts +1 -1
- package/dist/symbols.js +1 -1
- package/dist/{th-WM2PVA24.js → th-O3CHCMEU.js} +5 -1
- package/dist/{th-WM2PVA24.js.map → th-O3CHCMEU.js.map} +1 -1
- package/dist/theme-manifest.json +51 -40
- package/dist/{tr-HMAZXSJM.js → tr-RWKHFLUS.js} +5 -1
- package/dist/{tr-HMAZXSJM.js.map → tr-RWKHFLUS.js.map} +1 -1
- package/dist/{vi-ITFBV5B7.js → vi-D2CXSN5R.js} +5 -1
- package/dist/{vi-ITFBV5B7.js.map → vi-D2CXSN5R.js.map} +1 -1
- package/dist/{zh-ZGU2RI7K.js → zh-KBHIBNWP.js} +5 -1
- package/dist/{zh-ZGU2RI7K.js.map → zh-KBHIBNWP.js.map} +1 -1
- package/dist/{zh_TW-PNINSQ6F.js → zh_TW-474AC5C4.js} +5 -1
- package/dist/{zh_TW-PNINSQ6F.js.map → zh_TW-474AC5C4.js.map} +1 -1
- package/package.json +1 -1
- package/dist/chunk-Q3DCXQDW.js.map +0 -1
package/dist/index.js
CHANGED
|
@@ -25,6 +25,7 @@ import {
|
|
|
25
25
|
IMAGE_ERROR_MESSAGES,
|
|
26
26
|
INERT_PROPS,
|
|
27
27
|
INPUT_PROPS,
|
|
28
|
+
LIGHT_THEME,
|
|
28
29
|
MAGNET_LABELS,
|
|
29
30
|
MAGNET_STRENGTHS,
|
|
30
31
|
MIXED_LEVEL_COLORS,
|
|
@@ -113,7 +114,7 @@ import {
|
|
|
113
114
|
withRow,
|
|
114
115
|
withoutColumn,
|
|
115
116
|
withoutRow
|
|
116
|
-
} from "./chunk-
|
|
117
|
+
} from "./chunk-FRZFOTMO.js";
|
|
117
118
|
import {
|
|
118
119
|
ResourceAbortError,
|
|
119
120
|
memorySaveLoadAdapter
|
|
@@ -143,7 +144,7 @@ import {
|
|
|
143
144
|
} from "./chunk-QYGSDD2Q.js";
|
|
144
145
|
import {
|
|
145
146
|
symbolNames
|
|
146
|
-
} from "./chunk-
|
|
147
|
+
} from "./chunk-U4W26DXU.js";
|
|
147
148
|
|
|
148
149
|
// src/datafeed.ts
|
|
149
150
|
function olderPageVerdict(page, askedTo, alreadyHopped) {
|
|
@@ -1552,8 +1553,16 @@ var picker = {
|
|
|
1552
1553
|
"picker.noMatches": "No matching indicators.",
|
|
1553
1554
|
"picker.collections": "Indicator collections",
|
|
1554
1555
|
"picker.personal": "Personal",
|
|
1556
|
+
/** The rail's heading over the shipped definitions. */
|
|
1555
1557
|
"picker.builtin": "Built-in",
|
|
1558
|
+
/** The rail's collection of shipped technical indicators, under Built-in. */
|
|
1559
|
+
"picker.technicals": "Technicals",
|
|
1556
1560
|
"picker.favorites": "Favorites",
|
|
1561
|
+
/** The kind filters: their group's name, the filter that shows every kind, and the chart's own
|
|
1562
|
+
* kind beside the kinds a host declares. */
|
|
1563
|
+
"picker.kindFilter": "Type",
|
|
1564
|
+
"picker.allKinds": "All",
|
|
1565
|
+
"picker.indicators": "Indicators",
|
|
1557
1566
|
"picker.thousands": " K",
|
|
1558
1567
|
"picker.name": "Name",
|
|
1559
1568
|
"picker.author": "Author",
|
|
@@ -1789,26 +1798,26 @@ function readingDirection(i18n) {
|
|
|
1789
1798
|
return BUILT_IN_LOCALES.find((l) => l.code === i18n.locale())?.dir ?? "ltr";
|
|
1790
1799
|
}
|
|
1791
1800
|
var chartDictionaries = createDictionaryLoader(en, {
|
|
1792
|
-
de: () => import("./de-
|
|
1793
|
-
fr: () => import("./fr-
|
|
1794
|
-
es: () => import("./es-
|
|
1795
|
-
it: () => import("./it-
|
|
1796
|
-
ca_ES: () => import("./ca_ES-
|
|
1797
|
-
pl: () => import("./pl-
|
|
1798
|
-
sv: () => import("./sv-
|
|
1799
|
-
tr: () => import("./tr-
|
|
1800
|
-
ru: () => import("./ru-
|
|
1801
|
-
pt: () => import("./pt-
|
|
1802
|
-
id_ID: () => import("./id_ID-
|
|
1803
|
-
ms_MY: () => import("./ms_MY-
|
|
1804
|
-
th: () => import("./th-
|
|
1805
|
-
vi: () => import("./vi-
|
|
1806
|
-
ja: () => import("./ja-
|
|
1807
|
-
ko: () => import("./ko-
|
|
1808
|
-
zh: () => import("./zh-
|
|
1809
|
-
zh_TW: () => import("./zh_TW-
|
|
1810
|
-
ar: () => import("./ar-
|
|
1811
|
-
he_IL: () => import("./he_IL-
|
|
1801
|
+
de: () => import("./de-D5WWQLT5.js"),
|
|
1802
|
+
fr: () => import("./fr-L5EPUMNA.js"),
|
|
1803
|
+
es: () => import("./es-6TM3Z6CQ.js"),
|
|
1804
|
+
it: () => import("./it-TUILRXJ5.js"),
|
|
1805
|
+
ca_ES: () => import("./ca_ES-OF2NGA3A.js"),
|
|
1806
|
+
pl: () => import("./pl-XLOQLQVW.js"),
|
|
1807
|
+
sv: () => import("./sv-3JTSBHQN.js"),
|
|
1808
|
+
tr: () => import("./tr-RWKHFLUS.js"),
|
|
1809
|
+
ru: () => import("./ru-2KVG2H7U.js"),
|
|
1810
|
+
pt: () => import("./pt-TZWQOZ5P.js"),
|
|
1811
|
+
id_ID: () => import("./id_ID-MMY4EQSL.js"),
|
|
1812
|
+
ms_MY: () => import("./ms_MY-ABJSZCPH.js"),
|
|
1813
|
+
th: () => import("./th-O3CHCMEU.js"),
|
|
1814
|
+
vi: () => import("./vi-D2CXSN5R.js"),
|
|
1815
|
+
ja: () => import("./ja-7QY2FLXF.js"),
|
|
1816
|
+
ko: () => import("./ko-RWI5JOO2.js"),
|
|
1817
|
+
zh: () => import("./zh-KBHIBNWP.js"),
|
|
1818
|
+
zh_TW: () => import("./zh_TW-474AC5C4.js"),
|
|
1819
|
+
ar: () => import("./ar-BBRV6CC4.js"),
|
|
1820
|
+
he_IL: () => import("./he_IL-PXH4KNDC.js")
|
|
1812
1821
|
});
|
|
1813
1822
|
var dynamic = (t) => t;
|
|
1814
1823
|
var source = null;
|
|
@@ -1989,7 +1998,8 @@ var THEME_ROLES = [
|
|
|
1989
1998
|
// rows it runs beside.
|
|
1990
1999
|
{ id: "chrome.scrollThumb", family: "chrome", kind: "color", description: "The thumb of the thin bar beside a list the viewer scrolls, such as the search results or the indicator list." },
|
|
1991
2000
|
{ id: "chrome.radius", family: "chrome", kind: "length", description: "Corner radius of a control." },
|
|
1992
|
-
{ id: "chrome.radiusLarge", family: "chrome", kind: "length", description: "Corner radius of a panel
|
|
2001
|
+
{ id: "chrome.radiusLarge", family: "chrome", kind: "length", description: "Corner radius of a panel or menu." },
|
|
2002
|
+
{ id: "chrome.radiusDialog", family: "chrome", kind: "length", description: "Corner radius of a dialog." },
|
|
1993
2003
|
// ── overlay: menus, dialogs, popovers, and what sits behind them ────────────────────────────
|
|
1994
2004
|
{ id: "overlay.surface", family: "overlay", kind: "color", description: "The fill of a floating menu, dialog, or popover." },
|
|
1995
2005
|
{ id: "overlay.separator", family: "overlay", kind: "color", description: "The rule between groups inside a menu or panel." },
|
|
@@ -5199,6 +5209,27 @@ function mergePartialChartSettings(first, second) {
|
|
|
5199
5209
|
function copyPartialChartSettings(partial) {
|
|
5200
5210
|
return mergePartialChartSettings({}, partial);
|
|
5201
5211
|
}
|
|
5212
|
+
var MODE_LEAVES = (() => {
|
|
5213
|
+
const light = chartSettingsDefaults(LIGHT_THEME);
|
|
5214
|
+
const dark = SHAPE;
|
|
5215
|
+
const paths = /* @__PURE__ */ new Set();
|
|
5216
|
+
for (const [section, leaves] of Object.entries(dark)) {
|
|
5217
|
+
for (const [leaf, value] of Object.entries(leaves)) if (light[section]?.[leaf] !== value) paths.add(`${section}.${leaf}`);
|
|
5218
|
+
}
|
|
5219
|
+
return paths;
|
|
5220
|
+
})();
|
|
5221
|
+
function hasModeLeaves(partial) {
|
|
5222
|
+
return Object.entries(partial).some(([section, leaves]) => Object.keys(leaves ?? {}).some((leaf) => MODE_LEAVES.has(`${section}.${leaf}`)));
|
|
5223
|
+
}
|
|
5224
|
+
function withoutModeLeaves(partial) {
|
|
5225
|
+
const out = {};
|
|
5226
|
+
for (const [section, leaves] of Object.entries(partial)) {
|
|
5227
|
+
for (const [leaf, value] of Object.entries(leaves ?? {})) {
|
|
5228
|
+
if (!MODE_LEAVES.has(`${section}.${leaf}`)) (out[section] ??= {})[leaf] = value;
|
|
5229
|
+
}
|
|
5230
|
+
}
|
|
5231
|
+
return out;
|
|
5232
|
+
}
|
|
5202
5233
|
function settingsFromAppearance(appearance, isColor) {
|
|
5203
5234
|
if (!appearance || typeof appearance !== "object" || Array.isArray(appearance)) return { settings: {}, rejected: [] };
|
|
5204
5235
|
const old = appearance;
|
|
@@ -10285,11 +10316,13 @@ var ICONS = {
|
|
|
10285
10316
|
textItalic: { viewBox: "0 0 28 28", body: '<path fill="none" stroke="currentColor" d="M12 6.5h7M9 21.5h7M15.5 6.5l-3 15"/>' },
|
|
10286
10317
|
close18: { viewBox: "0 0 18 18", body: '<path d="M4.5 4.5l9 9M13.5 4.5l-9 9" stroke="currentColor" stroke-width="1.4" stroke-linecap="round"/>' },
|
|
10287
10318
|
chevronDown18: { viewBox: "0 0 18 18", body: solid(polyline([[4.4, 7.25], [9, 11.3], [13.6, 7.25]], 1.5)) },
|
|
10288
|
-
// The indicator picker's marks
|
|
10289
|
-
|
|
10290
|
-
|
|
10291
|
-
|
|
10292
|
-
|
|
10319
|
+
// The indicator picker's marks. A row's star on the 18 grid, a one-unit outline or the filled
|
|
10320
|
+
// shape; the rail's Favorites, an outlined star on the 28 grid; and the rail's built-in indicators,
|
|
10321
|
+
// a trend line over a run of columns.
|
|
10322
|
+
pickerStar: { viewBox: "0 0 18 18", body: '<path stroke="currentColor" d="M9 2.13l1.903 3.855.116.236.26.038 4.255.618-3.079 3.001-.188.184.044.259.727 4.237-3.805-2L9 12.434l-.233.122-3.805 2.001.727-4.237.044-.26-.188-.183-3.079-3.001 4.255-.618.26-.038.116-.236L9 2.13z"/>' },
|
|
10323
|
+
pickerStarFilled: { viewBox: "0 0 18 18", body: '<path fill="currentColor" d="M9 1l2.35 4.76 5.26.77-3.8 3.7.9 5.24L9 13l-4.7 2.47.9-5.23-3.8-3.71 5.25-.77L9 1z"/>' },
|
|
10324
|
+
pickerFavorites: { viewBox: "0 0 28 28", body: '<path fill="currentColor" fill-rule="evenodd" d="m17.13 9.74 7.37.9-5.44 5.06L20.4 23 14 19.38 7.6 23l1.34-7.3-5.44-5.06 7.37-.9L14 3l3.13 6.74Zm3.99 2-3.68 3.42.9 4.96L14 17.66l-4.34 2.46.9-4.96-3.68-3.42 5-.6L14 6.56l2.12 4.56 5 .61Z"/>' },
|
|
10325
|
+
pickerTechnicals: { viewBox: "0 0 28 28", body: '<path fill="currentColor" d="m22.85 7.85-4.58 4.59a2.5 2.5 0 0 1-3.54 0l-3.17-3.17a1.5 1.5 0 0 0-2.12 0l-4.59 4.58-.7-.7 4.58-4.59a2.5 2.5 0 0 1 3.54 0l3.17 3.17a1.5 1.5 0 0 0 2.12 0l4.59-4.58.7.7ZM11 22h-1v-8h1v8Zm12 0h-1v-8h1v8ZM8 22H7v-6h1v6Zm6 0h-1v-6h1v6Zm6 0h-1v-6h1v6Zm-3 0h-1v-4h1v4ZM5 22H4v-3h1v3Z"/>' },
|
|
10293
10326
|
// The note beside a switch that needs a sentence.
|
|
10294
10327
|
info: { viewBox: "0 0 18 18", body: solid(disc(9, 9, 8) + disc(9, 5, 1, true) + polygon([[7, 8], [10, 8], [10, 14], [8.5, 14], [8.5, 9.5], [7, 9.5]], true)) },
|
|
10295
10328
|
// The short tip beside a setting's label: a disc with a question mark cut through it, its hook
|
|
@@ -10398,7 +10431,6 @@ function openDialog(options2) {
|
|
|
10398
10431
|
scrim.appendChild(box2);
|
|
10399
10432
|
const motion = options2.motion !== false;
|
|
10400
10433
|
if (options2.veil === false) scrim.dataset.qcVeil = "none";
|
|
10401
|
-
if (options2.passThrough) scrim.dataset.qcPass = "true";
|
|
10402
10434
|
if (motion) scrim.dataset.state = "opening";
|
|
10403
10435
|
let isOpen = true;
|
|
10404
10436
|
const previouslyFocused = document.activeElement;
|
|
@@ -11527,7 +11559,6 @@ function openDialog2(options2) {
|
|
|
11527
11559
|
...options2.width === void 0 ? {} : { width: options2.width },
|
|
11528
11560
|
...options2.veil === void 0 ? {} : { veil: options2.veil },
|
|
11529
11561
|
...options2.motion === void 0 ? {} : { motion: options2.motion },
|
|
11530
|
-
...options2.passThrough === void 0 ? {} : { passThrough: options2.passThrough },
|
|
11531
11562
|
build(element, dialog) {
|
|
11532
11563
|
box2 = element;
|
|
11533
11564
|
closeBox = () => dialog.close();
|
|
@@ -15143,6 +15174,7 @@ function serializeChartContent(content) {
|
|
|
15143
15174
|
axis: content.priceAxis,
|
|
15144
15175
|
indicators: content.indicators.map(savedIndicatorFields),
|
|
15145
15176
|
settings: content.settings,
|
|
15177
|
+
...content.settingsMode ? { settingsMode: content.settingsMode } : {},
|
|
15146
15178
|
compares: content.compares,
|
|
15147
15179
|
panes: content.panes,
|
|
15148
15180
|
...content.drawings ? { drawings: content.drawings } : {},
|
|
@@ -15165,6 +15197,7 @@ function parseChartContent(content) {
|
|
|
15165
15197
|
indicators: indicators2,
|
|
15166
15198
|
settings: read?.settings,
|
|
15167
15199
|
settingsRejected: read?.rejected,
|
|
15200
|
+
settingsMode: raw.settingsMode === "light" || raw.settingsMode === "dark" ? raw.settingsMode : void 0,
|
|
15168
15201
|
drawings: Array.isArray(raw.drawings) ? raw.drawings : void 0,
|
|
15169
15202
|
compares: raw.compares,
|
|
15170
15203
|
// An earlier blob carries no order of its own, and its panes stand in the order it stores what
|
|
@@ -18125,7 +18158,7 @@ var byMeaning = (table) => table;
|
|
|
18125
18158
|
var CONTROL_ICONS = byMeaning({
|
|
18126
18159
|
// The top bar and the widget's menus.
|
|
18127
18160
|
compare: [ICONS.comparePlus],
|
|
18128
|
-
indicators: [ICONS.indicators],
|
|
18161
|
+
indicators: [ICONS.indicators, ICONS.pickerTechnicals],
|
|
18129
18162
|
replay: [ICONS.replay],
|
|
18130
18163
|
undo: [ICONS.undo],
|
|
18131
18164
|
redo: [ICONS.redo],
|
|
@@ -18162,15 +18195,15 @@ var CONTROL_ICONS = byMeaning({
|
|
|
18162
18195
|
close: [ICONS.close, ICONS.closeThin, ICONS.dialogClose],
|
|
18163
18196
|
remove: [ICONS.close18, ICONS.removeRow],
|
|
18164
18197
|
delete: [ICONS.trash, ICONS.trash28],
|
|
18165
|
-
add: [ICONS.plus, ICONS.plusThin
|
|
18198
|
+
add: [ICONS.plus, ICONS.plusThin],
|
|
18166
18199
|
bold: [ICONS.textBold],
|
|
18167
18200
|
italic: [ICONS.textItalic],
|
|
18168
|
-
search: [ICONS.search
|
|
18201
|
+
search: [ICONS.search],
|
|
18169
18202
|
clear: [ICONS.clear],
|
|
18170
18203
|
open: [ICONS.folder],
|
|
18171
18204
|
rename: [ICONS.pencil],
|
|
18172
18205
|
duplicate: [ICONS.clone],
|
|
18173
|
-
favorite: [ICONS.star, ICONS.pickerStar],
|
|
18206
|
+
favorite: [ICONS.star, ICONS.pickerStar, ICONS.pickerFavorites],
|
|
18174
18207
|
favorited: [ICONS.starFilled, ICONS.pickerStarFilled],
|
|
18175
18208
|
sortAscending: [ICONS.sortUp, ICONS.sortUpRow],
|
|
18176
18209
|
sortDescending: [ICONS.sortDown, ICONS.sortDownRow],
|
|
@@ -19643,7 +19676,8 @@ var MENU_COMMAND = {
|
|
|
19643
19676
|
"copy-price": "chart.price.copy",
|
|
19644
19677
|
paste: "chart.drawings.paste",
|
|
19645
19678
|
"remove-indicators": "chart.indicators.removeAll",
|
|
19646
|
-
"remove-drawings": "chart.drawings.removeAll"
|
|
19679
|
+
"remove-drawings": "chart.drawings.removeAll",
|
|
19680
|
+
settings: "chart.settings.open"
|
|
19647
19681
|
};
|
|
19648
19682
|
var PLACE_HORIZONTAL_LINE = "chart.drawings.placeHorizontalLine";
|
|
19649
19683
|
function levelAt(series2, y, step) {
|
|
@@ -19689,12 +19723,11 @@ function attachMenuPlane(deps) {
|
|
|
19689
19723
|
{
|
|
19690
19724
|
priceText,
|
|
19691
19725
|
symbol: deps.symbol(),
|
|
19692
|
-
// The
|
|
19693
|
-
//
|
|
19694
|
-
//
|
|
19695
|
-
// and the chart.drawings.* commands drive.
|
|
19726
|
+
// The paste row is live exactly when the paste command would run (a copied drawing on the
|
|
19727
|
+
// clipboard, the verb permitted), and the settings row wherever the chart offers its
|
|
19728
|
+
// settings door and the command would open the dialog.
|
|
19696
19729
|
canPaste: deps.commands.available("chart.drawings.paste"),
|
|
19697
|
-
canSettings:
|
|
19730
|
+
canSettings: (deps.settingsDoor ?? true) && deps.commands.available(MENU_COMMAND.settings),
|
|
19698
19731
|
indicatorCount: deps.indicatorCount(),
|
|
19699
19732
|
drawingCount: deps.drawingCount(),
|
|
19700
19733
|
...table ? { table } : {}
|
|
@@ -20386,9 +20419,9 @@ function mountScaleControls(deps) {
|
|
|
20386
20419
|
stopPointer(modes);
|
|
20387
20420
|
const unit = h("div", { class: "qc-scale-unit", "data-role": "scale-unit" });
|
|
20388
20421
|
deps.chrome.appendChild(unit);
|
|
20389
|
-
const
|
|
20390
|
-
|
|
20391
|
-
deps.chrome.appendChild(
|
|
20422
|
+
const plus = h("button", { type: "button", class: "qc-scale-plus", "data-role": "scale-plus" });
|
|
20423
|
+
plus.hidden = true;
|
|
20424
|
+
deps.chrome.appendChild(plus);
|
|
20392
20425
|
let placed = null;
|
|
20393
20426
|
let pressing = null;
|
|
20394
20427
|
let releasing = false;
|
|
@@ -20403,7 +20436,7 @@ function mountScaleControls(deps) {
|
|
|
20403
20436
|
const at2 = anchor();
|
|
20404
20437
|
return at2 !== null && clientX >= at2.left && clientX < at2.right && clientY >= at2.top && clientY < at2.bottom;
|
|
20405
20438
|
};
|
|
20406
|
-
|
|
20439
|
+
plus.addEventListener("click", (event) => {
|
|
20407
20440
|
const at2 = anchor();
|
|
20408
20441
|
if (at2) deps.openPriceMenu(at2, event.detail === 0);
|
|
20409
20442
|
});
|
|
@@ -20444,19 +20477,19 @@ function mountScaleControls(deps) {
|
|
|
20444
20477
|
const scale = box2 ? deps.box() : null;
|
|
20445
20478
|
if (!box2 || !scale) {
|
|
20446
20479
|
placed = null;
|
|
20447
|
-
|
|
20480
|
+
plus.hidden = true;
|
|
20448
20481
|
return;
|
|
20449
20482
|
}
|
|
20450
20483
|
const plotLeft = scale.side === "right" ? scale.left - box2.paneWidth : scale.left + scale.width;
|
|
20451
20484
|
const left = plotLeft + box2.left;
|
|
20452
20485
|
const was = placed;
|
|
20453
20486
|
placed = { left, top: scale.top + box2.top, width: box2.width, height: box2.height, y: scale.top + box2.y, side: scale.side };
|
|
20454
|
-
if (was && !
|
|
20455
|
-
|
|
20456
|
-
|
|
20457
|
-
|
|
20458
|
-
|
|
20459
|
-
|
|
20487
|
+
if (was && !plus.hidden && was.left === placed.left && was.top === placed.top && was.width === placed.width && was.height === placed.height) return;
|
|
20488
|
+
plus.hidden = false;
|
|
20489
|
+
plus.style.left = `${placed.left}px`;
|
|
20490
|
+
plus.style.top = `${placed.top}px`;
|
|
20491
|
+
plus.style.width = `${placed.width}px`;
|
|
20492
|
+
plus.style.height = `${placed.height}px`;
|
|
20460
20493
|
};
|
|
20461
20494
|
auto.addEventListener("click", () => {
|
|
20462
20495
|
deps.toggleAutoScale();
|
|
@@ -20475,7 +20508,7 @@ function mountScaleControls(deps) {
|
|
|
20475
20508
|
name(auto, t("chrome.autoScale"));
|
|
20476
20509
|
log.textContent = t("chrome.logScaleMark");
|
|
20477
20510
|
name(log, t("chrome.logScale"));
|
|
20478
|
-
name(
|
|
20511
|
+
name(plus, t("chrome.priceLevelMenu"));
|
|
20479
20512
|
};
|
|
20480
20513
|
const sync = () => {
|
|
20481
20514
|
const box2 = deps.box();
|
|
@@ -20561,7 +20594,7 @@ function mountScaleControls(deps) {
|
|
|
20561
20594
|
deps.gestures.removeEventListener("click", onClick, true);
|
|
20562
20595
|
modes.remove();
|
|
20563
20596
|
unit.remove();
|
|
20564
|
-
|
|
20597
|
+
plus.remove();
|
|
20565
20598
|
}
|
|
20566
20599
|
};
|
|
20567
20600
|
}
|
|
@@ -21977,6 +22010,7 @@ function createChartInstance(deps) {
|
|
|
21977
22010
|
let menuLevel = null;
|
|
21978
22011
|
let drawingPrefs = readDrawingPreferences();
|
|
21979
22012
|
let viewerPartial = {};
|
|
22013
|
+
let leavesMode = deps.theme.mode();
|
|
21980
22014
|
const canvas = () => canvasTheme(deps.theme.get());
|
|
21981
22015
|
const hostPartial = (() => {
|
|
21982
22016
|
const named2 = readPartialChartSettings(deps.settings ?? {}, paintableColor).settings;
|
|
@@ -22628,6 +22662,7 @@ function createChartInstance(deps) {
|
|
|
22628
22662
|
drawingCount: () => drawings2.handle?.count() ?? 0,
|
|
22629
22663
|
extensions: () => extensions.host,
|
|
22630
22664
|
shown: (id) => commandShown(deps.access, id),
|
|
22665
|
+
settingsDoor: deps.ui.settingsMenu,
|
|
22631
22666
|
setLevel: (price) => {
|
|
22632
22667
|
menuLevel = price;
|
|
22633
22668
|
},
|
|
@@ -23416,6 +23451,9 @@ function createChartInstance(deps) {
|
|
|
23416
23451
|
// factory colors and the host's brand as though a viewer had chosen every one of them, and a
|
|
23417
23452
|
// reopen under another theme or another brand would then be stuck with the old ones.
|
|
23418
23453
|
settings: copyPartialChartSettings(viewerPartial),
|
|
23454
|
+
// The mode a leaf that follows the mode was chosen in, so a reopen in the other mode lets the
|
|
23455
|
+
// mode in effect paint it.
|
|
23456
|
+
...hasModeLeaves(viewerPartial) ? { settingsMode: leavesMode } : {},
|
|
23419
23457
|
compares: compare?.serialize() ?? [],
|
|
23420
23458
|
// The order the panes stand in, top to bottom, those waiting to be drawn included.
|
|
23421
23459
|
panes: paneOps.order(),
|
|
@@ -23436,16 +23474,19 @@ function createChartInstance(deps) {
|
|
|
23436
23474
|
const { dropped } = indicators2.restore(parsed.indicators);
|
|
23437
23475
|
writeHidden();
|
|
23438
23476
|
if (dropped > 0) deps.doors.notify("info", i18n.t("toast.indicatorsNotCarried", { count: dropped }));
|
|
23439
|
-
if (parsed.settings) handle.applySettings(parsed.settings);
|
|
23477
|
+
if (parsed.settings) handle.applySettings(inMode(parsed.settings, parsed.settingsMode));
|
|
23440
23478
|
compare?.restore(parsed.compares);
|
|
23441
23479
|
paneOps.arrange(parsed.panes);
|
|
23442
23480
|
if (deps.drawings.mode === "combined" && parsed.drawings) drawings2.handle?.restore(parsed.drawings);
|
|
23443
23481
|
const extensionsComplete = extensions.host.restore(parsed.ext);
|
|
23444
23482
|
return dropped === 0 && extensionsComplete;
|
|
23445
23483
|
}
|
|
23484
|
+
function inMode(settings2, mode) {
|
|
23485
|
+
return mode && mode !== leavesMode ? withoutModeLeaves(settings2) : settings2;
|
|
23486
|
+
}
|
|
23446
23487
|
function applyHistoryContent(next) {
|
|
23447
23488
|
if (disposed) return;
|
|
23448
|
-
viewerPartial = copyPartialChartSettings(next.settings);
|
|
23489
|
+
viewerPartial = copyPartialChartSettings(inMode(next.settings, next.settingsMode));
|
|
23449
23490
|
applyLook();
|
|
23450
23491
|
applyContent({
|
|
23451
23492
|
symbol: next.symbol,
|
|
@@ -23772,8 +23813,16 @@ function createChartInstance(deps) {
|
|
|
23772
23813
|
setLegendRows: (rows2) => legend2.setHostRows(rows2),
|
|
23773
23814
|
screenshot: () => extensions.host.capture(() => chart.takeScreenshot(), () => ({ width: chart.chartElement().clientWidth, height: chart.chartElement().clientHeight })),
|
|
23774
23815
|
repaintTheme() {
|
|
23816
|
+
const mode = deps.theme.mode();
|
|
23817
|
+
const switched = mode !== leavesMode && hasModeLeaves(viewerPartial);
|
|
23818
|
+
leavesMode = mode;
|
|
23819
|
+
if (switched) viewerPartial = withoutModeLeaves(viewerPartial);
|
|
23775
23820
|
applyLook();
|
|
23776
23821
|
legend2.setDot(session2.state());
|
|
23822
|
+
if (switched) {
|
|
23823
|
+
deps.contentChanged?.();
|
|
23824
|
+
history2.changed();
|
|
23825
|
+
}
|
|
23777
23826
|
},
|
|
23778
23827
|
relabel() {
|
|
23779
23828
|
applyTimezone();
|
|
@@ -25478,6 +25527,7 @@ function openIndicatorSettings(deps) {
|
|
|
25478
25527
|
}
|
|
25479
25528
|
|
|
25480
25529
|
// src/ui/chrome/indicatorPickerData.ts
|
|
25530
|
+
var INDICATOR_KIND = "indicator";
|
|
25481
25531
|
var record2 = (value) => !!value && typeof value === "object" && !Array.isArray(value);
|
|
25482
25532
|
var text = (value) => typeof value === "string" && value.trim().length > 0;
|
|
25483
25533
|
var builtinIds = new Set(BUILT_IN_INDICATORS2.map((d) => d.id));
|
|
@@ -25506,12 +25556,26 @@ function pickerCollections(value) {
|
|
|
25506
25556
|
return null;
|
|
25507
25557
|
}
|
|
25508
25558
|
}
|
|
25509
|
-
function
|
|
25559
|
+
function pickerKinds(value) {
|
|
25560
|
+
try {
|
|
25561
|
+
if (value === void 0) return [];
|
|
25562
|
+
if (!Array.isArray(value)) return null;
|
|
25563
|
+
const result = [];
|
|
25564
|
+
for (const row2 of value) {
|
|
25565
|
+
if (!record2(row2) || !text(row2.id) || row2.id === INDICATOR_KIND || !text(row2.label)) return null;
|
|
25566
|
+
result.push({ id: row2.id, label: row2.label });
|
|
25567
|
+
}
|
|
25568
|
+
return unique(result.map((row2) => row2.id)) ? result : null;
|
|
25569
|
+
} catch {
|
|
25570
|
+
return null;
|
|
25571
|
+
}
|
|
25572
|
+
}
|
|
25573
|
+
function pickerRows(value, kinds = []) {
|
|
25510
25574
|
try {
|
|
25511
25575
|
if (!record2(value) || value.kind !== "ok" || !Array.isArray(value.items) || value.builtIns !== void 0 && !Array.isArray(value.builtIns)) return null;
|
|
25512
25576
|
const items2 = [];
|
|
25513
25577
|
for (const row2 of value.items) {
|
|
25514
|
-
if (!record2(row2) || !text(row2.id) || builtinIds.has(row2.id) || ["builtin", "favorites", "add", "favorite"].includes(row2.id) || !text(row2.title) || !optionalText(row2.description) || !optionalText(row2.author) || !count(row2.favoriteCount) || row2.favorite !== void 0 && typeof row2.favorite !== "boolean") return null;
|
|
25578
|
+
if (!record2(row2) || !text(row2.id) || builtinIds.has(row2.id) || ["builtin", "favorites", "add", "favorite"].includes(row2.id) || !text(row2.title) || !optionalText(row2.description) || !optionalText(row2.author) || !count(row2.favoriteCount) || row2.favorite !== void 0 && typeof row2.favorite !== "boolean" || row2.kind !== void 0 && (typeof row2.kind !== "string" || row2.kind !== INDICATOR_KIND && !kinds.includes(row2.kind))) return null;
|
|
25515
25579
|
const verbs = actions(row2.actions);
|
|
25516
25580
|
if (!verbs || !text(row2.primaryAction) || !verbs.some((a) => a.id === row2.primaryAction)) return null;
|
|
25517
25581
|
items2.push({
|
|
@@ -25521,6 +25585,7 @@ function pickerRows(value) {
|
|
|
25521
25585
|
actions: verbs,
|
|
25522
25586
|
...row2.description !== void 0 ? { description: row2.description } : {},
|
|
25523
25587
|
...row2.author !== void 0 ? { author: row2.author } : {},
|
|
25588
|
+
...row2.kind !== void 0 ? { kind: row2.kind } : {},
|
|
25524
25589
|
...row2.favorite !== void 0 ? { favorite: row2.favorite } : {},
|
|
25525
25590
|
...row2.favoriteCount !== void 0 ? { favoriteCount: row2.favoriteCount } : {}
|
|
25526
25591
|
});
|
|
@@ -25538,11 +25603,17 @@ function pickerRows(value) {
|
|
|
25538
25603
|
}
|
|
25539
25604
|
}
|
|
25540
25605
|
|
|
25606
|
+
// src/ui/chrome/searchField.ts
|
|
25607
|
+
function searchField(icons, input, ...trailing) {
|
|
25608
|
+
return h("div", { class: "qc-search-field" }, icons.glyph(ICONS.search, { size: 28, className: "qc-search-magnifier" }), input, h("span", { class: "qc-search-actions-field" }, ...trailing));
|
|
25609
|
+
}
|
|
25610
|
+
function searchClear(icons, label3, onClear) {
|
|
25611
|
+
return button2({ label: label3, icon: icons.glyph(ICONS.clear, { size: 18 }), className: "qc-search-op", onClick: onClear });
|
|
25612
|
+
}
|
|
25613
|
+
|
|
25541
25614
|
// src/ui/chrome/indicatorPicker.ts
|
|
25542
25615
|
var FAVORITES_KEY = "quickcharts.indicatorFavorites.v1";
|
|
25543
25616
|
var star = (icons, filled) => icons.glyph(filled ? ICONS.pickerStarFilled : ICONS.pickerStar, { size: 18 });
|
|
25544
|
-
var plus = (icons) => icons.glyph(ICONS.plus24, { size: 18 });
|
|
25545
|
-
var searchGlyph = (icons) => icons.glyph(ICONS.search24, { size: 18 });
|
|
25546
25617
|
function freshInstanceId(definitionId, existing) {
|
|
25547
25618
|
const taken = new Set(existing.map((i) => i.id));
|
|
25548
25619
|
let n = 1;
|
|
@@ -25558,12 +25629,20 @@ function openIndicatorPicker(deps) {
|
|
|
25558
25629
|
const t = (key, ...args) => deps.i18n.t(key, ...args);
|
|
25559
25630
|
const source3 = deps.indicatorPicker;
|
|
25560
25631
|
let collections = null;
|
|
25632
|
+
let kinds = [];
|
|
25561
25633
|
let hostValid = !source3;
|
|
25562
|
-
|
|
25563
|
-
|
|
25564
|
-
|
|
25565
|
-
|
|
25566
|
-
|
|
25634
|
+
const readHost = () => {
|
|
25635
|
+
try {
|
|
25636
|
+
collections = source3 ? pickerCollections(source3.collections) : [];
|
|
25637
|
+
kinds = source3 ? pickerKinds(source3.kinds) : [];
|
|
25638
|
+
hostValid = collections !== null && kinds !== null && (!source3 || typeof source3.list === "function" && typeof source3.act === "function");
|
|
25639
|
+
} catch {
|
|
25640
|
+
collections = null;
|
|
25641
|
+
kinds = null;
|
|
25642
|
+
hostValid = false;
|
|
25643
|
+
}
|
|
25644
|
+
};
|
|
25645
|
+
readHost();
|
|
25567
25646
|
let favorites = [];
|
|
25568
25647
|
try {
|
|
25569
25648
|
const stored = JSON.parse(deps.storage?.get(FAVORITES_KEY) ?? "[]");
|
|
@@ -25572,6 +25651,7 @@ function openIndicatorPicker(deps) {
|
|
|
25572
25651
|
}
|
|
25573
25652
|
let query = "";
|
|
25574
25653
|
let collection = deps.initialCollection === "favorites" || collections?.some((row2) => row2.id === deps.initialCollection) ? deps.initialCollection : "builtin";
|
|
25654
|
+
let kind = null;
|
|
25575
25655
|
let generation = 0;
|
|
25576
25656
|
let controller = null;
|
|
25577
25657
|
let busy = false;
|
|
@@ -25601,14 +25681,20 @@ function openIndicatorPicker(deps) {
|
|
|
25601
25681
|
offLocale();
|
|
25602
25682
|
},
|
|
25603
25683
|
build(box2, dialog) {
|
|
25604
|
-
const input = h("input", { type: "
|
|
25684
|
+
const input = h("input", { type: "text", class: "qc-search-input qc-picker-search", role: "searchbox", "aria-label": t("picker.search"), placeholder: t("picker.search"), autocomplete: "off", spellcheck: "false" });
|
|
25685
|
+
const clear = searchClear(deps.icons, t("search.clear"), () => {
|
|
25686
|
+
input.value = "";
|
|
25687
|
+
setQuery("");
|
|
25688
|
+
input.focus();
|
|
25689
|
+
});
|
|
25690
|
+
clear.hidden = true;
|
|
25691
|
+
const strip = h("div", { class: "qc-search-classes" });
|
|
25605
25692
|
const nav = h("nav", { class: "qc-picker-nav", "aria-label": t("picker.collections") });
|
|
25606
25693
|
const list = h("div", { class: "qc-picker-list", role: "table", "aria-label": t("picker.title") });
|
|
25607
25694
|
const status2 = h("div", { class: "qc-picker-status qc-secondary", role: "status", "aria-live": "polite" });
|
|
25608
|
-
const close = button2({ label: t("search.close"), icon: deps.icons.glyph(ICONS.dialogClose, { size: 18 }), className: "qc-dialog-close", onClick: () => dialog.close() });
|
|
25609
25695
|
let pendingFocus = null;
|
|
25610
|
-
const actionButton = (label3, content, run, disabled = false, focusKey) => {
|
|
25611
|
-
const button3 = h("button", { type: "button", class:
|
|
25696
|
+
const actionButton = (label3, content, run, disabled = false, focusKey, className = "qc-picker-action") => {
|
|
25697
|
+
const button3 = h("button", { type: "button", class: className, "aria-label": label3, title: label3, "data-picker-focus": focusKey }, content ?? h("span", {}, label3));
|
|
25612
25698
|
button3.disabled = disabled;
|
|
25613
25699
|
button3.addEventListener("click", (event) => {
|
|
25614
25700
|
event.stopPropagation();
|
|
@@ -25653,9 +25739,9 @@ function openIndicatorPicker(deps) {
|
|
|
25653
25739
|
render();
|
|
25654
25740
|
}
|
|
25655
25741
|
};
|
|
25656
|
-
const toggle = (
|
|
25742
|
+
const toggle = (kind2, id, favorite, hosted) => {
|
|
25657
25743
|
if (hosted) {
|
|
25658
|
-
void act({ kind, id }, "favorite", !favorite);
|
|
25744
|
+
void act({ kind: kind2, id }, "favorite", !favorite);
|
|
25659
25745
|
return;
|
|
25660
25746
|
}
|
|
25661
25747
|
favorites = favorite ? favorites.filter((value) => value !== id) : [...favorites, id];
|
|
@@ -25668,8 +25754,12 @@ function openIndicatorPicker(deps) {
|
|
|
25668
25754
|
const buildRow = (options2) => {
|
|
25669
25755
|
const row2 = h("div", { class: "qc-picker-row", role: "row" });
|
|
25670
25756
|
const key = (action) => JSON.stringify([options2.kind, options2.id, action]);
|
|
25671
|
-
const favoriteCell = h("div", { role: "cell" });
|
|
25672
|
-
if (options2.favorite !== void 0)
|
|
25757
|
+
const favoriteCell = h("div", { role: "cell", class: "qc-picker-star-cell" });
|
|
25758
|
+
if (options2.favorite !== void 0) {
|
|
25759
|
+
const toggleStar = actionButton(t(options2.favorite ? "picker.unfavorite" : "picker.favorite", { name: options2.title }), star(deps.icons, options2.favorite), () => toggle(options2.kind, options2.id, options2.favorite, options2.hostedFavorite === true), options2.hostedFavorite === true && (busy || loading) || !!source3 && !available, key("favorite"), "qc-picker-star");
|
|
25760
|
+
toggleStar.setAttribute("aria-pressed", String(options2.favorite));
|
|
25761
|
+
favoriteCell.append(toggleStar);
|
|
25762
|
+
}
|
|
25673
25763
|
const label3 = options2.permitted ? options2.title : t("picker.notPermitted", { name: options2.title });
|
|
25674
25764
|
const name2 = h("button", { type: "button", class: "qc-picker-name", "data-qc-item": "", tabindex: "-1", ...options2.builtin ? { "data-indicator": options2.id } : { "data-picker-item": options2.id }, "aria-label": options2.builtin && options2.permitted ? t("picker.add", { name: options2.title }) : label3, title: options2.description ?? label3 }, options2.title);
|
|
25675
25765
|
name2.disabled = !options2.permitted;
|
|
@@ -25684,11 +25774,6 @@ function openIndicatorPicker(deps) {
|
|
|
25684
25774
|
if (personal && rows2.items.find((item) => item.id === options2.id)?.primaryAction === action.id) continue;
|
|
25685
25775
|
actions2.append(actionButton(action.label, hostIcon(action.icon), () => void act({ kind: options2.kind, id: options2.id }, action.id), busy || loading || action.disabled === true, key("action:" + action.id)));
|
|
25686
25776
|
}
|
|
25687
|
-
if (options2.builtin) {
|
|
25688
|
-
const button3 = actionButton(t("picker.add", { name: options2.title }), plus(deps.icons), options2.primary, !options2.permitted, key("add"));
|
|
25689
|
-
button3.dataset.pickerAdd = options2.id;
|
|
25690
|
-
actions2.append(button3);
|
|
25691
|
-
}
|
|
25692
25777
|
const total2 = options2.count;
|
|
25693
25778
|
const compact2 = total2 === void 0 ? 0 : total2 < 1e3 ? total2 : total2 < 1e4 ? Math.round(total2 / 100) / 10 : Math.round(total2 / 1e3);
|
|
25694
25779
|
const count2 = total2 === void 0 ? "" : new Intl.NumberFormat(deps.i18n.tag()).format(compact2) + (total2 >= 1e3 ? t("picker.thousands") : "");
|
|
@@ -25698,27 +25783,31 @@ function openIndicatorPicker(deps) {
|
|
|
25698
25783
|
});
|
|
25699
25784
|
return row2;
|
|
25700
25785
|
};
|
|
25786
|
+
const admitted = (rowKind) => kind === null || kind === rowKind;
|
|
25701
25787
|
const render = () => {
|
|
25702
25788
|
const focused = document.activeElement;
|
|
25703
25789
|
if (focused && list.contains(focused)) pendingFocus = focused.dataset.pickerFocus ?? null;
|
|
25704
25790
|
else if (focused && focused !== document.body) pendingFocus = null;
|
|
25705
25791
|
const selected = (collections ?? []).find((row2) => row2.id === collection);
|
|
25706
25792
|
list.classList.toggle("qc-picker-list--personal", selected?.layout === "list");
|
|
25793
|
+
list.classList.toggle("qc-picker-list--catalog", collection === "builtin");
|
|
25707
25794
|
for (const button3 of nav.querySelectorAll("[data-picker-collection]")) button3.setAttribute("aria-pressed", String(button3.getAttribute("data-picker-collection") === collection));
|
|
25795
|
+
for (const chip of strip.querySelectorAll("[data-picker-kind]")) chip.setAttribute("aria-pressed", String((chip.getAttribute("data-picker-kind") || null) === kind));
|
|
25708
25796
|
const headings = h("div", { role: "row", class: "qc-picker-headings" }, ...["", t("picker.name"), t("picker.author"), t("picker.favorites"), ""].map((label3) => h("span", { role: "columnheader" }, label3)));
|
|
25709
25797
|
const body = h("div", { role: "rowgroup" });
|
|
25710
|
-
if (collection === "builtin" || collection === "favorites") {
|
|
25798
|
+
if ((collection === "builtin" || collection === "favorites") && admitted(INDICATOR_KIND)) {
|
|
25711
25799
|
for (const definition of filterDefinitions(t, query)) {
|
|
25712
25800
|
const metadata = rows2.builtIns.find((row2) => row2.id === definition.id);
|
|
25713
25801
|
const favorite = metadata?.favorite ?? favorites.includes(definition.id);
|
|
25714
25802
|
if (collection === "favorites" && !favorite) continue;
|
|
25715
25803
|
if (!offered(definition)) continue;
|
|
25716
25804
|
if (!indicatorShown(deps.access, definition) || !commandShown(deps.access, "chart.indicators.add")) continue;
|
|
25717
|
-
body.append(buildRow({ id: definition.id, kind: "builtin", title: t(definition.nameKey), description: t(definition.descriptionKey),
|
|
25805
|
+
body.append(buildRow({ id: definition.id, kind: "builtin", title: t(definition.nameKey), description: t(definition.descriptionKey), favorite, count: metadata?.favoriteCount, hostedFavorite: metadata?.favorite !== void 0 || !!source3 && loading, actions: metadata?.actions ?? [], primary: () => add(definition), permitted: indicatorPermitted(deps.access, definition) && deps.commands.available("chart.indicators.add"), builtin: definition }));
|
|
25718
25806
|
}
|
|
25719
25807
|
}
|
|
25720
25808
|
if (collection !== "builtin") for (const item of rows2.items) {
|
|
25721
25809
|
if (collection === "favorites" && item.favorite !== true) continue;
|
|
25810
|
+
if (!admitted(item.kind ?? INDICATOR_KIND)) continue;
|
|
25722
25811
|
const primary = item.actions.find((action) => action.id === item.primaryAction);
|
|
25723
25812
|
body.append(buildRow({ id: item.id, kind: "item", title: item.title, description: item.description, author: item.author, favorite: item.favorite, count: item.favoriteCount, hostedFavorite: true, actions: item.actions, primary: () => void act({ kind: "item", id: item.id }, primary.id), permitted: !busy && !loading && !primary.disabled }));
|
|
25724
25813
|
}
|
|
@@ -25752,7 +25841,7 @@ function openIndicatorPicker(deps) {
|
|
|
25752
25841
|
try {
|
|
25753
25842
|
const result = await source3.list({ collection, query, builtInIds: BUILT_IN_INDICATORS2.filter(offered).map((d) => d.id) }, pending.signal);
|
|
25754
25843
|
if (!dialog.open() || revision !== generation) return;
|
|
25755
|
-
const parsed = pickerRows(result);
|
|
25844
|
+
const parsed = pickerRows(result, (kinds ?? []).map((row2) => row2.id));
|
|
25756
25845
|
if (parsed) {
|
|
25757
25846
|
rows2 = parsed;
|
|
25758
25847
|
available = true;
|
|
@@ -25766,25 +25855,47 @@ function openIndicatorPicker(deps) {
|
|
|
25766
25855
|
}
|
|
25767
25856
|
}
|
|
25768
25857
|
};
|
|
25858
|
+
const setQuery = (next) => {
|
|
25859
|
+
query = next;
|
|
25860
|
+
clear.hidden = next === "";
|
|
25861
|
+
void refresh();
|
|
25862
|
+
};
|
|
25769
25863
|
const renderNavigation = () => {
|
|
25770
25864
|
replace(nav);
|
|
25771
|
-
const
|
|
25865
|
+
const personal = t("picker.personal");
|
|
25866
|
+
const navigation = [{ id: "favorites", label: t("picker.favorites"), group: personal, icon: deps.icons.glyph(ICONS.pickerFavorites, { size: 28 }) }, ...(collections ?? []).map((row2) => ({ ...row2, icon: hostIcon(row2.icon) })), { id: "builtin", label: t("picker.technicals"), group: t("picker.builtin"), icon: deps.icons.glyph(ICONS.pickerTechnicals, { size: 28 }) }];
|
|
25867
|
+
let section = null;
|
|
25772
25868
|
let group;
|
|
25773
25869
|
for (const item of navigation) {
|
|
25774
|
-
if (item.group && item.group !== group)
|
|
25775
|
-
|
|
25776
|
-
|
|
25870
|
+
if (!section || !!item.group && item.group !== group) {
|
|
25871
|
+
section = h("div", { class: "qc-picker-section" }, item.group ? h("div", { class: "qc-picker-group" }, item.group) : null);
|
|
25872
|
+
nav.append(section);
|
|
25873
|
+
group = item.group;
|
|
25874
|
+
}
|
|
25875
|
+
const button3 = h("button", { type: "button", class: "qc-picker-collection", "data-picker-collection": item.id }, h("span", { class: "qc-picker-collection-icon" }, item.icon), h("span", { class: "qc-picker-collection-label" }, item.label));
|
|
25777
25876
|
button3.addEventListener("click", () => {
|
|
25778
25877
|
collection = item.id;
|
|
25779
25878
|
void refresh();
|
|
25780
25879
|
});
|
|
25781
|
-
|
|
25880
|
+
section.append(button3);
|
|
25782
25881
|
}
|
|
25783
25882
|
};
|
|
25784
|
-
|
|
25785
|
-
|
|
25786
|
-
|
|
25787
|
-
|
|
25883
|
+
const renderKinds = () => {
|
|
25884
|
+
const declared = kinds ?? [];
|
|
25885
|
+
if (kind !== null && kind !== INDICATOR_KIND && !declared.some((row2) => row2.id === kind)) kind = null;
|
|
25886
|
+
const group = h("div", { class: "qc-search-class-group", role: "group", "aria-label": t("picker.kindFilter") });
|
|
25887
|
+
for (const entry of [{ id: "", label: t("picker.allKinds") }, { id: INDICATOR_KIND, label: t("picker.indicators") }, ...declared]) {
|
|
25888
|
+
const chip = button2({ label: entry.label, text: entry.label, className: "qc-chip qc-search-class", pressed: (entry.id || null) === kind, onClick: () => {
|
|
25889
|
+
kind = entry.id || null;
|
|
25890
|
+
render();
|
|
25891
|
+
} });
|
|
25892
|
+
chip.dataset.pickerKind = entry.id;
|
|
25893
|
+
group.append(chip);
|
|
25894
|
+
}
|
|
25895
|
+
replace(strip, group);
|
|
25896
|
+
strip.hidden = declared.length === 0;
|
|
25897
|
+
};
|
|
25898
|
+
input.addEventListener("input", () => setQuery(input.value));
|
|
25788
25899
|
input.addEventListener("keydown", (event) => {
|
|
25789
25900
|
if (event.key === "ArrowDown" && roveFocus(list, event)) event.preventDefault();
|
|
25790
25901
|
});
|
|
@@ -25794,27 +25905,21 @@ function openIndicatorPicker(deps) {
|
|
|
25794
25905
|
input.focus();
|
|
25795
25906
|
} else if (roveFocus(list, event)) event.preventDefault();
|
|
25796
25907
|
});
|
|
25797
|
-
box2.append(
|
|
25908
|
+
box2.append(searchField(deps.icons, input, clear), strip, h("div", { class: "qc-picker-body" }, nav, h("div", { class: "qc-picker-content" }, list, status2)));
|
|
25909
|
+
renderKinds();
|
|
25798
25910
|
renderNavigation();
|
|
25799
25911
|
redraw = render;
|
|
25800
25912
|
offLocale = deps.i18n.onChange(() => {
|
|
25801
25913
|
if (!dialog.open()) return;
|
|
25802
25914
|
box2.setAttribute("aria-label", t("picker.title"));
|
|
25803
|
-
box2.querySelector(".qc-title").textContent = t("picker.title");
|
|
25804
|
-
box2.querySelector(".qc-picker-tab").textContent = t("picker.title");
|
|
25805
25915
|
input.placeholder = t("picker.search");
|
|
25806
25916
|
input.setAttribute("aria-label", t("picker.search"));
|
|
25807
|
-
name(
|
|
25917
|
+
name(clear, t("search.clear"));
|
|
25808
25918
|
nav.setAttribute("aria-label", t("picker.collections"));
|
|
25809
25919
|
list.setAttribute("aria-label", t("picker.title"));
|
|
25810
|
-
|
|
25811
|
-
collections = source3 ? pickerCollections(source3.collections) : [];
|
|
25812
|
-
hostValid = collections !== null && (!source3 || typeof source3.list === "function" && typeof source3.act === "function");
|
|
25813
|
-
} catch {
|
|
25814
|
-
collections = null;
|
|
25815
|
-
hostValid = false;
|
|
25816
|
-
}
|
|
25920
|
+
readHost();
|
|
25817
25921
|
if (!["builtin", "favorites", ...(collections ?? []).map((row2) => row2.id)].includes(collection)) collection = "builtin";
|
|
25922
|
+
renderKinds();
|
|
25818
25923
|
renderNavigation();
|
|
25819
25924
|
void refresh();
|
|
25820
25925
|
});
|
|
@@ -25957,8 +26062,9 @@ function dialogRows(input) {
|
|
|
25957
26062
|
}
|
|
25958
26063
|
return base;
|
|
25959
26064
|
}
|
|
25960
|
-
var ROW_MARK_SIZE2 =
|
|
25961
|
-
var SOURCE_MARK_SIZE =
|
|
26065
|
+
var ROW_MARK_SIZE2 = 36;
|
|
26066
|
+
var SOURCE_MARK_SIZE = 24;
|
|
26067
|
+
var SCOPE_MARK_SIZE = 18;
|
|
25962
26068
|
var picks = 0;
|
|
25963
26069
|
var PREFETCH_MARGIN = 8;
|
|
25964
26070
|
function buildSearchSurface(deps, box2, frame2) {
|
|
@@ -25975,7 +26081,6 @@ function buildSearchSurface(deps, box2, frame2) {
|
|
|
25975
26081
|
let scoped = scopeSession !== null && searchScope?.on !== false;
|
|
25976
26082
|
const session2 = () => scoped && scopeSession ? scopeSession : feedSession;
|
|
25977
26083
|
const search2 = () => session2().controller;
|
|
25978
|
-
if (mode === "search" || mode === "pick") box2.classList.add("qc-search-table");
|
|
25979
26084
|
let query = request.changeFrom ?? "";
|
|
25980
26085
|
const display = deps.display ?? {};
|
|
25981
26086
|
const spreads = display.spreads !== false;
|
|
@@ -25993,7 +26098,7 @@ function buildSearchSurface(deps, box2, frame2) {
|
|
|
25993
26098
|
};
|
|
25994
26099
|
let scopeMarkDisposer = null;
|
|
25995
26100
|
const input = h("input", { type: "text", role: "combobox", class: "qc-search-input", "aria-label": t("search.placeholder"), placeholder: t("search.placeholder"), autocomplete: "off", "aria-autocomplete": "list", "aria-expanded": "true", "aria-controls": listId, spellcheck: "false", value: query });
|
|
25996
|
-
const clear =
|
|
26101
|
+
const clear = searchClear(deps.icons, t("search.clear"), () => setQuery(""));
|
|
25997
26102
|
const rule = offerOps ? h("span", { class: "qc-search-rule", "aria-hidden": "true" }) : null;
|
|
25998
26103
|
const showClear = (shown2) => {
|
|
25999
26104
|
clear.hidden = !shown2;
|
|
@@ -26026,8 +26131,7 @@ function buildSearchSurface(deps, box2, frame2) {
|
|
|
26026
26131
|
}
|
|
26027
26132
|
setOps(opsOpen);
|
|
26028
26133
|
}
|
|
26029
|
-
const
|
|
26030
|
-
const field = h("div", { class: "qc-search-field" }, deps.icons.glyph(ICONS.search, { size: 28, className: "qc-search-magnifier" }), input, actions2);
|
|
26134
|
+
const field = searchField(deps.icons, input, clear, rule, offerOps ? ops : null, offerOps ? opsToggle : null);
|
|
26031
26135
|
const classes = compare ? null : deps.classes();
|
|
26032
26136
|
const branches = classes ? classBranches(classes) : [];
|
|
26033
26137
|
const allShown = display.allClasses !== false;
|
|
@@ -26079,7 +26183,7 @@ function buildSearchSurface(deps, box2, frame2) {
|
|
|
26079
26183
|
}
|
|
26080
26184
|
if (searchScope) {
|
|
26081
26185
|
const mark = h("span", { class: "qc-search-scope-mark", "aria-hidden": "true" });
|
|
26082
|
-
const drop = searchScope.mark?.({ host: mark, size:
|
|
26186
|
+
const drop = searchScope.mark?.({ host: mark, size: SCOPE_MARK_SIZE });
|
|
26083
26187
|
if (typeof drop === "function") {
|
|
26084
26188
|
mark.dataset.qcHost = "true";
|
|
26085
26189
|
scopeMarkDisposer = drop;
|
|
@@ -26092,7 +26196,7 @@ function buildSearchSurface(deps, box2, frame2) {
|
|
|
26092
26196
|
const status2 = h("div", { class: "qc-search-status", role: "status", "aria-live": "polite" });
|
|
26093
26197
|
const sentinel = h("div", { class: "qc-search-sentinel qc-muted" }, t("search.loadingMore"));
|
|
26094
26198
|
sentinel.hidden = true;
|
|
26095
|
-
append(box2,
|
|
26199
|
+
append(box2, field, strip, ...narrower.map((n) => n.row), list, status2);
|
|
26096
26200
|
const serverQuery = () => spreads && looksLikeSpread(query) && !isSymbolPair(query) ? spreadSearchQuery(query) : query;
|
|
26097
26201
|
const setQuery = (next) => {
|
|
26098
26202
|
query = next;
|
|
@@ -26159,16 +26263,22 @@ function buildSearchSurface(deps, box2, frame2) {
|
|
|
26159
26263
|
markDisposers.push(dropMark);
|
|
26160
26264
|
} else mark.set(label3.ticker);
|
|
26161
26265
|
option.appendChild(mark.element);
|
|
26162
|
-
option.appendChild(
|
|
26266
|
+
option.appendChild(
|
|
26267
|
+
h(
|
|
26268
|
+
"span",
|
|
26269
|
+
{ class: "qc-search-text" },
|
|
26270
|
+
marked(label3.ticker),
|
|
26271
|
+
h("span", { class: "qc-search-line" }, h("span", { class: "qc-search-name" }, label3.description), r.type ? h("span", { class: "qc-search-kind" }, r.type) : null)
|
|
26272
|
+
)
|
|
26273
|
+
);
|
|
26163
26274
|
if (compare && entry.added) {
|
|
26164
26275
|
const mark2 = h("span", { class: "qc-search-added", title: t("search.addedMark", { symbol: label3.ticker }) });
|
|
26165
26276
|
mark2.appendChild(deps.icons.glyph(ICONS.check, { size: 18 }));
|
|
26166
26277
|
option.appendChild(mark2);
|
|
26167
26278
|
} else {
|
|
26168
26279
|
const source3 = h("span", { class: "qc-search-source" });
|
|
26169
|
-
source3.appendChild(h("span", { class: "qc-search-source-text" }, label3.source ? h("span", { class: "qc-search-source-name" }, label3.source) : null, h("span", { class: "qc-search-kind" }, r.type)));
|
|
26170
26280
|
if (label3.source) {
|
|
26171
|
-
const sourceMark = h("span", { class: "qc-search-mark", "aria-
|
|
26281
|
+
const sourceMark = h("span", { class: "qc-search-mark", role: "img", "aria-label": label3.source, title: label3.source });
|
|
26172
26282
|
const dropSource = r.exchange ? deps.painters.venue?.({ exchange: r.exchange, host: sourceMark, size: SOURCE_MARK_SIZE }) : r.dataSource ? deps.painters.dataSource?.({ dataSource: r.dataSource, host: sourceMark, size: SOURCE_MARK_SIZE }) : void 0;
|
|
26173
26283
|
if (typeof dropSource === "function") {
|
|
26174
26284
|
sourceMark.dataset.qcHost = "true";
|
|
@@ -26178,9 +26288,9 @@ function buildSearchSurface(deps, box2, frame2) {
|
|
|
26178
26288
|
}
|
|
26179
26289
|
option.appendChild(source3);
|
|
26180
26290
|
if (compare) {
|
|
26181
|
-
const
|
|
26291
|
+
const actions2 = h("span", { class: "qc-search-actions" });
|
|
26182
26292
|
for (const p of PLACEMENTS2) {
|
|
26183
|
-
|
|
26293
|
+
actions2.appendChild(
|
|
26184
26294
|
button2({
|
|
26185
26295
|
label: t(p.label),
|
|
26186
26296
|
text: t(p.label),
|
|
@@ -26192,7 +26302,7 @@ function buildSearchSurface(deps, box2, frame2) {
|
|
|
26192
26302
|
})
|
|
26193
26303
|
);
|
|
26194
26304
|
}
|
|
26195
|
-
option.appendChild(
|
|
26305
|
+
option.appendChild(actions2);
|
|
26196
26306
|
}
|
|
26197
26307
|
}
|
|
26198
26308
|
option.addEventListener("click", () => act(entry));
|
|
@@ -26291,7 +26401,7 @@ function openSearchDialog(deps) {
|
|
|
26291
26401
|
deps.onClose?.(dialog);
|
|
26292
26402
|
},
|
|
26293
26403
|
build(box2, handle) {
|
|
26294
|
-
surface = buildSearchSurface(deps, box2, {
|
|
26404
|
+
surface = buildSearchSurface(deps, box2, { done: () => handle.close() });
|
|
26295
26405
|
},
|
|
26296
26406
|
initialFocus: (box2) => box2.querySelector(".qc-search-input")
|
|
26297
26407
|
});
|
|
@@ -29874,8 +29984,8 @@ function createChartSettingsDialog(deps) {
|
|
|
29874
29984
|
role: "chart-settings",
|
|
29875
29985
|
width: 750,
|
|
29876
29986
|
veil: false,
|
|
29877
|
-
|
|
29878
|
-
//
|
|
29987
|
+
// Escape, the close, a press outside the dialog and the host's teardown end the session as
|
|
29988
|
+
// the dialog begins to close.
|
|
29879
29989
|
onClosing: () => {
|
|
29880
29990
|
if (s && !s.settled) cancel(s);
|
|
29881
29991
|
},
|
|
@@ -30925,8 +31035,8 @@ function mountSymbolSearch(options2) {
|
|
|
30925
31035
|
}
|
|
30926
31036
|
},
|
|
30927
31037
|
element,
|
|
30928
|
-
// A card
|
|
30929
|
-
{
|
|
31038
|
+
// A card's done is the page's close.
|
|
31039
|
+
{ done: () => options2.onClose?.() }
|
|
30930
31040
|
);
|
|
30931
31041
|
return {
|
|
30932
31042
|
element,
|