@tradecanvas/chart 1.71.0 → 1.72.1

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.
Files changed (177) hide show
  1. package/dist/LayoutSession-DO4bYkUi.cjs +2 -0
  2. package/dist/LayoutSession-DO4bYkUi.cjs.map +1 -0
  3. package/dist/{LayoutSession-BOQCN6yY.js → LayoutSession-qRYG8GTD.js} +539 -552
  4. package/dist/LayoutSession-qRYG8GTD.js.map +1 -0
  5. package/dist/WidgetCommandPalette-CeCLHPy1.js +177 -0
  6. package/dist/WidgetCommandPalette-CeCLHPy1.js.map +1 -0
  7. package/dist/WidgetCommandPalette-ZZNbWwCZ.cjs +2 -0
  8. package/dist/WidgetCommandPalette-ZZNbWwCZ.cjs.map +1 -0
  9. package/dist/WidgetDrawingSettings-BeW8fX7r.js +474 -0
  10. package/dist/WidgetDrawingSettings-BeW8fX7r.js.map +1 -0
  11. package/dist/WidgetDrawingSettings-Cyl2u_u8.cjs +2 -0
  12. package/dist/WidgetDrawingSettings-Cyl2u_u8.cjs.map +1 -0
  13. package/dist/WidgetGoToDate-BNdngHlg.cjs +2 -0
  14. package/dist/WidgetGoToDate-BNdngHlg.cjs.map +1 -0
  15. package/dist/WidgetGoToDate-hcDtezRm.js +191 -0
  16. package/dist/WidgetGoToDate-hcDtezRm.js.map +1 -0
  17. package/dist/WidgetHotkeySheet-1lRFSdvt.js +416 -0
  18. package/dist/WidgetHotkeySheet-1lRFSdvt.js.map +1 -0
  19. package/dist/WidgetHotkeySheet-y5LWKSG6.cjs +2 -0
  20. package/dist/WidgetHotkeySheet-y5LWKSG6.cjs.map +1 -0
  21. package/dist/WidgetIndicatorPicker-CGvZ5kYd.js +245 -0
  22. package/dist/WidgetIndicatorPicker-CGvZ5kYd.js.map +1 -0
  23. package/dist/WidgetIndicatorPicker-DuKJFPRC.cjs +2 -0
  24. package/dist/WidgetIndicatorPicker-DuKJFPRC.cjs.map +1 -0
  25. package/dist/WidgetIndicatorSettings-C7vpco6e.cjs +2 -0
  26. package/dist/WidgetIndicatorSettings-C7vpco6e.cjs.map +1 -0
  27. package/dist/WidgetIndicatorSettings-dDkqzzYo.js +326 -0
  28. package/dist/WidgetIndicatorSettings-dDkqzzYo.js.map +1 -0
  29. package/dist/WidgetSettings-D7Pq42zW.cjs +2 -0
  30. package/dist/WidgetSettings-D7Pq42zW.cjs.map +1 -0
  31. package/dist/WidgetSettings-eOo93L7Z.js +546 -0
  32. package/dist/WidgetSettings-eOo93L7Z.js.map +1 -0
  33. package/dist/WidgetSymbolSearch-C4OR42nZ.cjs +2 -0
  34. package/dist/WidgetSymbolSearch-C4OR42nZ.cjs.map +1 -0
  35. package/dist/WidgetSymbolSearch-CvPpjIwa.js +580 -0
  36. package/dist/WidgetSymbolSearch-CvPpjIwa.js.map +1 -0
  37. package/dist/focusTrap-Br9Zfje0.js +27 -0
  38. package/dist/focusTrap-Br9Zfje0.js.map +1 -0
  39. package/dist/focusTrap-DrhhmG0V.cjs +2 -0
  40. package/dist/focusTrap-DrhhmG0V.cjs.map +1 -0
  41. package/dist/i18n-C2nQBZTY.cjs +2 -0
  42. package/dist/i18n-C2nQBZTY.cjs.map +1 -0
  43. package/dist/{i18n-DUmd4Z_r.js → i18n-C5v6Tzp1.js} +3 -1
  44. package/dist/i18n-C5v6Tzp1.js.map +1 -0
  45. package/dist/index.cjs +1 -1
  46. package/dist/index.d.ts +1 -1
  47. package/dist/index.d.ts.map +1 -1
  48. package/dist/index.js +1 -1
  49. package/dist/indicatorInputWords-Bd9Pt6qp.js +25 -0
  50. package/dist/indicatorInputWords-Bd9Pt6qp.js.map +1 -0
  51. package/dist/indicatorInputWords-CTA4IcJR.cjs +2 -0
  52. package/dist/indicatorInputWords-CTA4IcJR.cjs.map +1 -0
  53. package/dist/indicatorLabel-BNZvaOcl.cjs +2 -0
  54. package/dist/indicatorLabel-BNZvaOcl.cjs.map +1 -0
  55. package/dist/indicatorLabel-Sbegyhp2.js +17 -0
  56. package/dist/indicatorLabel-Sbegyhp2.js.map +1 -0
  57. package/dist/indicatorSettingsTabs-B0liE3ST.cjs +2 -0
  58. package/dist/indicatorSettingsTabs-B0liE3ST.cjs.map +1 -0
  59. package/dist/indicatorSettingsTabs-XcgMdbLp.js +161 -0
  60. package/dist/indicatorSettingsTabs-XcgMdbLp.js.map +1 -0
  61. package/dist/monthView-B-CieFDJ.cjs +2 -0
  62. package/dist/monthView-B-CieFDJ.cjs.map +1 -0
  63. package/dist/monthView-N8yDaTqZ.js +198 -0
  64. package/dist/monthView-N8yDaTqZ.js.map +1 -0
  65. package/dist/platformKeys-B82-j1Fs.cjs +2 -0
  66. package/dist/platformKeys-B82-j1Fs.cjs.map +1 -0
  67. package/dist/platformKeys-Dd1qOCjF.js +5 -0
  68. package/dist/platformKeys-Dd1qOCjF.js.map +1 -0
  69. package/dist/settingsControls-DIjzCFHI.js +379 -0
  70. package/dist/settingsControls-DIjzCFHI.js.map +1 -0
  71. package/dist/settingsControls-Tn8_vJJv.cjs +2 -0
  72. package/dist/settingsControls-Tn8_vJJv.cjs.map +1 -0
  73. package/dist/symbolCatalog-CA1fpz3s.js +90 -0
  74. package/dist/symbolCatalog-CA1fpz3s.js.map +1 -0
  75. package/dist/symbolCatalog-Dx1YnZgm.cjs +2 -0
  76. package/dist/symbolCatalog-Dx1YnZgm.cjs.map +1 -0
  77. package/dist/widget/ChartWidget.d.ts +102 -582
  78. package/dist/widget/ChartWidget.d.ts.map +1 -1
  79. package/dist/widget/WidgetAlerts.d.ts +35 -0
  80. package/dist/widget/WidgetAlerts.d.ts.map +1 -0
  81. package/dist/widget/WidgetChartSettings.d.ts +194 -0
  82. package/dist/widget/WidgetChartSettings.d.ts.map +1 -0
  83. package/dist/widget/WidgetCommands.d.ts +54 -0
  84. package/dist/widget/WidgetCommands.d.ts.map +1 -0
  85. package/dist/widget/WidgetCompares.d.ts +140 -0
  86. package/dist/widget/WidgetCompares.d.ts.map +1 -0
  87. package/dist/widget/WidgetDockArea.d.ts +89 -0
  88. package/dist/widget/WidgetDockArea.d.ts.map +1 -0
  89. package/dist/widget/WidgetDrawingEdit.d.ts +73 -0
  90. package/dist/widget/WidgetDrawingEdit.d.ts.map +1 -0
  91. package/dist/widget/WidgetGoToDate.d.ts +1 -14
  92. package/dist/widget/WidgetGoToDate.d.ts.map +1 -1
  93. package/dist/widget/WidgetIndicatorSettings.d.ts.map +1 -1
  94. package/dist/widget/WidgetIntervals.d.ts +66 -0
  95. package/dist/widget/WidgetIntervals.d.ts.map +1 -0
  96. package/dist/widget/WidgetLayouts.d.ts +85 -0
  97. package/dist/widget/WidgetLayouts.d.ts.map +1 -0
  98. package/dist/widget/WidgetLegendView.d.ts +54 -0
  99. package/dist/widget/WidgetLegendView.d.ts.map +1 -0
  100. package/dist/widget/WidgetMenus.d.ts +79 -0
  101. package/dist/widget/WidgetMenus.d.ts.map +1 -0
  102. package/dist/widget/WidgetReplay.d.ts +199 -0
  103. package/dist/widget/WidgetReplay.d.ts.map +1 -0
  104. package/dist/widget/WidgetTrading.d.ts +48 -0
  105. package/dist/widget/WidgetTrading.d.ts.map +1 -0
  106. package/dist/widget/WidgetWatchlists.d.ts +77 -0
  107. package/dist/widget/WidgetWatchlists.d.ts.map +1 -0
  108. package/dist/widget/drawingSettingsTabs.d.ts +2 -19
  109. package/dist/widget/drawingSettingsTabs.d.ts.map +1 -1
  110. package/dist/widget/drawingText.d.ts +24 -0
  111. package/dist/widget/drawingText.d.ts.map +1 -0
  112. package/dist/widget/index.cjs +22 -23
  113. package/dist/widget/index.cjs.map +1 -1
  114. package/dist/widget/index.js +6193 -9868
  115. package/dist/widget/index.js.map +1 -1
  116. package/dist/widget/keyTarget.d.ts +4 -0
  117. package/dist/widget/keyTarget.d.ts.map +1 -1
  118. package/dist/widget/lazyPart.d.ts +47 -0
  119. package/dist/widget/lazyPart.d.ts.map +1 -0
  120. package/dist/widget/locales/ar.d.ts.map +1 -1
  121. package/dist/widget/locales/cs.d.ts.map +1 -1
  122. package/dist/widget/locales/da.d.ts.map +1 -1
  123. package/dist/widget/locales/de.d.ts.map +1 -1
  124. package/dist/widget/locales/el.d.ts.map +1 -1
  125. package/dist/widget/locales/en.d.ts +1 -0
  126. package/dist/widget/locales/en.d.ts.map +1 -1
  127. package/dist/widget/locales/es.d.ts.map +1 -1
  128. package/dist/widget/locales/et.d.ts.map +1 -1
  129. package/dist/widget/locales/fa.d.ts.map +1 -1
  130. package/dist/widget/locales/fr.d.ts.map +1 -1
  131. package/dist/widget/locales/he.d.ts.map +1 -1
  132. package/dist/widget/locales/hu.d.ts.map +1 -1
  133. package/dist/widget/locales/id.d.ts.map +1 -1
  134. package/dist/widget/locales/index.cjs +1 -1
  135. package/dist/widget/locales/index.cjs.map +1 -1
  136. package/dist/widget/locales/index.js +29 -1
  137. package/dist/widget/locales/index.js.map +1 -1
  138. package/dist/widget/locales/it.d.ts.map +1 -1
  139. package/dist/widget/locales/ja.d.ts.map +1 -1
  140. package/dist/widget/locales/ko.d.ts.map +1 -1
  141. package/dist/widget/locales/ms.d.ts.map +1 -1
  142. package/dist/widget/locales/nb.d.ts.map +1 -1
  143. package/dist/widget/locales/nl.d.ts.map +1 -1
  144. package/dist/widget/locales/pl.d.ts.map +1 -1
  145. package/dist/widget/locales/pt.d.ts.map +1 -1
  146. package/dist/widget/locales/ro.d.ts.map +1 -1
  147. package/dist/widget/locales/ru.d.ts.map +1 -1
  148. package/dist/widget/locales/sk.d.ts.map +1 -1
  149. package/dist/widget/locales/sv.d.ts.map +1 -1
  150. package/dist/widget/locales/th.d.ts.map +1 -1
  151. package/dist/widget/locales/tr.d.ts.map +1 -1
  152. package/dist/widget/locales/vi.d.ts.map +1 -1
  153. package/dist/widget/locales/zh.d.ts.map +1 -1
  154. package/dist/widget/locales/zhHant.d.ts.map +1 -1
  155. package/dist/widget/pageEnv.d.ts +5 -0
  156. package/dist/widget/pageEnv.d.ts.map +1 -0
  157. package/dist/widget/signals.d.ts +41 -0
  158. package/dist/widget/signals.d.ts.map +1 -0
  159. package/dist/widget/wallTime.d.ts +15 -0
  160. package/dist/widget/wallTime.d.ts.map +1 -0
  161. package/dist/widget/widgetDialogs.d.ts +17 -0
  162. package/dist/widget/widgetDialogs.d.ts.map +1 -0
  163. package/dist/widgetFeatures-BM6u0u74.js +186 -0
  164. package/dist/widgetFeatures-BM6u0u74.js.map +1 -0
  165. package/dist/widgetFeatures-BZ8OVPN2.cjs +3 -0
  166. package/dist/widgetFeatures-BZ8OVPN2.cjs.map +1 -0
  167. package/dist/widgetLocales-BPK5i0Ok.cjs +2 -0
  168. package/dist/widgetLocales-BPK5i0Ok.cjs.map +1 -0
  169. package/dist/widgetLocales-DgTR8JSu.js +838 -0
  170. package/dist/widgetLocales-DgTR8JSu.js.map +1 -0
  171. package/package.json +3 -3
  172. package/dist/LayoutSession-BOQCN6yY.js.map +0 -1
  173. package/dist/LayoutSession-RF8OqOXy.cjs +0 -2
  174. package/dist/LayoutSession-RF8OqOXy.cjs.map +0 -1
  175. package/dist/i18n-BsstZ9md.cjs +0 -2
  176. package/dist/i18n-BsstZ9md.cjs.map +0 -1
  177. package/dist/i18n-DUmd4Z_r.js.map +0 -1
@@ -0,0 +1,580 @@
1
+ import { o as e } from "./widgetFeatures-BM6u0u74.js";
2
+ import { i as t, n } from "./focusTrap-Br9Zfje0.js";
3
+ import { a as r, c as i, i as a, o, r as s, s as c, u as l } from "./symbolCatalog-CA1fpz3s.js";
4
+ import { r as u, t as d } from "./i18n-C5v6Tzp1.js";
5
+ var f = 20, p = 1e3, m = /* @__PURE__ */ new Set(), h = {
6
+ stock: 1,
7
+ stocks: 1,
8
+ equity: 1,
9
+ share: 1,
10
+ shares: 1,
11
+ "cổ phiếu": 1,
12
+ 株式: 1,
13
+ 株: 1,
14
+ 股票: 1,
15
+ 주식: 1,
16
+ futures: 2,
17
+ future: 2,
18
+ derivative: 2,
19
+ derivatives: 2,
20
+ option: 2,
21
+ options: 2,
22
+ "phái sinh": 2,
23
+ 先物: 2,
24
+ 期货: 2,
25
+ 期貨: 2,
26
+ 선물: 2,
27
+ warrant: 2,
28
+ warrants: 2,
29
+ "covered warrant": 2,
30
+ "chứng quyền": 2,
31
+ index: 3,
32
+ indices: 3,
33
+ "chỉ số": 3,
34
+ 指数: 3,
35
+ 指數: 3,
36
+ 지수: 3,
37
+ fund: 3,
38
+ funds: 3,
39
+ etf: 3,
40
+ etfs: 3,
41
+ "chứng chỉ quỹ": 3,
42
+ crypto: 4,
43
+ cryptocurrency: 4,
44
+ perpetual: 4,
45
+ perpetuals: 4,
46
+ perp: 4,
47
+ perps: 4,
48
+ "tiền mã hóa": 4,
49
+ "tiền mã hoá": 4,
50
+ "tiền điện tử": 4,
51
+ 暗号資産: 4,
52
+ 仮想通貨: 4,
53
+ 加密货币: 4,
54
+ 加密貨幣: 4,
55
+ 数字货币: 4,
56
+ 數字貨幣: 4,
57
+ 虚拟货币: 4,
58
+ 虛擬貨幣: 4,
59
+ 암호화폐: 4,
60
+ 가상자산: 4,
61
+ 가상화폐: 4,
62
+ forex: 5,
63
+ fx: 5,
64
+ currency: 5,
65
+ "ngoại hối": 5,
66
+ 為替: 5,
67
+ 外国為替: 5,
68
+ 外汇: 5,
69
+ 外匯: 5,
70
+ 외환: 5,
71
+ bond: 5,
72
+ bonds: 5,
73
+ "trái phiếu": 5
74
+ }, g = 1e3, _ = /* @__PURE__ */ new Map(), v = /i\u0307|\u0131/g;
75
+ function y(e) {
76
+ if (typeof e != "string") return "";
77
+ let t = _.get(e);
78
+ return t === void 0 && (t = e.trim().normalize("NFC").toLowerCase().replace(v, "i"), _.size >= g && _.clear(), _.set(e, t)), t;
79
+ }
80
+ function b(e) {
81
+ let t = y(e);
82
+ return t ? Object.prototype.hasOwnProperty.call(h, t) ? h[t] : 1 + x(t) % 5 : 0;
83
+ }
84
+ function x(e) {
85
+ let t = 2166136261;
86
+ for (let n of e) t ^= n.codePointAt(0), t = Math.imul(t, 16777619) >>> 0;
87
+ return t;
88
+ }
89
+ function S(e) {
90
+ let { ticker: t } = i(e), n = /[\p{L}\p{N}]/u.exec(t);
91
+ return n ? n[0].toUpperCase() : "";
92
+ }
93
+ function C(e, t) {
94
+ let n = a(t?.logo);
95
+ if (!n || m.has(n)) return T(e, t);
96
+ let r = document.createElement("img");
97
+ return r.className = "tcw-ss-badge", r.alt = "", r.width = f, r.height = f, r.draggable = !1, r.setAttribute("aria-hidden", "true"), r.setAttribute("loading", "lazy"), r.setAttribute("decoding", "async"), r.setAttribute("referrerpolicy", "no-referrer"), r.addEventListener("error", () => {
98
+ w(n), r.replaceWith(T(e, t));
99
+ }, { once: !0 }), r.src = n, r;
100
+ }
101
+ function w(e) {
102
+ m.size >= p && m.clear(), m.add(e);
103
+ }
104
+ function T(e, t) {
105
+ let n = document.createElement("span");
106
+ return n.className = "tcw-ss-badge", n.setAttribute("aria-hidden", "true"), n.dataset.kind = String(b(t?.type)), n.textContent = S(e), n;
107
+ }
108
+ //#endregion
109
+ //#region src/widget/symbolMatch.ts
110
+ var E = 180, D = 150, O = 50;
111
+ function k(e) {
112
+ return {
113
+ upper: e.toUpperCase(),
114
+ folded: N(e)
115
+ };
116
+ }
117
+ function A(e, t, n) {
118
+ return Math.max(j(e.toUpperCase(), n.upper), M(t, n.folded));
119
+ }
120
+ function j(e, t) {
121
+ if (e === t) return 1e3;
122
+ if (e.startsWith(t)) return 500 + (50 - Math.min(50, e.length - t.length));
123
+ if (e.includes(t)) return 200 + (50 - Math.min(50, e.length - t.length));
124
+ let n = 0, r = -1, i = 0;
125
+ for (let a = 0; a < e.length && n < t.length; a++) e[a] === t[n] && (r >= 0 && (i += a - r - 1), r = a, n++);
126
+ return n < t.length ? 0 : 100 - Math.min(99, i);
127
+ }
128
+ function M(e, t) {
129
+ if (!e || !t) return 0;
130
+ if (e.startsWith(t)) return E;
131
+ let n = e.indexOf(t);
132
+ return n < 0 ? 0 : D - Math.min(O, n);
133
+ }
134
+ function N(e) {
135
+ return e.normalize("NFD").replace(/\p{M}+/gu, "").replace(/[đĐ]/g, "D").toUpperCase();
136
+ }
137
+ function P(e, t, n = 0, r = e.length) {
138
+ let i = t ? F(e.toUpperCase(), t) : /* @__PURE__ */ new Set(), a = "";
139
+ for (let t = n; t < r; t++) a += i.has(t) ? `<mark>${l(e[t])}</mark>` : l(e[t]);
140
+ return a;
141
+ }
142
+ function F(e, t) {
143
+ let n = /* @__PURE__ */ new Set(), r = e.indexOf(t);
144
+ if (r >= 0) {
145
+ for (let e = r; e < r + t.length; e++) n.add(e);
146
+ return n;
147
+ }
148
+ let i = 0;
149
+ for (let r = 0; r < e.length && i < t.length; r++) e[r] === t[i] && (n.add(r), i++);
150
+ return i < t.length ? /* @__PURE__ */ new Set() : n;
151
+ }
152
+ //#endregion
153
+ //#region src/widget/symbolCell.ts
154
+ function I(e, t) {
155
+ let n = document.createElement("span");
156
+ n.className = "tcw-ss-symbol", n.dir = "ltr";
157
+ let { venue: r } = i(e), a = (n, r, i) => {
158
+ let a = document.createElement("span");
159
+ return a.className = n, a.innerHTML = P(e, t, r, i), a;
160
+ };
161
+ return r && n.appendChild(a("tcw-ss-venue", 0, r.length)), n.appendChild(a("tcw-ss-ticker", r.length, e.length)), n;
162
+ }
163
+ //#endregion
164
+ //#region src/widget/symbolSearchFilters.ts
165
+ var L = y, R = 2, z = 1, B = class {
166
+ el;
167
+ kindsEl;
168
+ exchangeEl;
169
+ kinds = /* @__PURE__ */ new Map();
170
+ exchanges = /* @__PURE__ */ new Map();
171
+ kind = null;
172
+ exchange = null;
173
+ resize;
174
+ constructor(e, t) {
175
+ this.t = e, this.onChange = t, this.el = document.createElement("div"), this.el.className = "tcw-ss-filters", this.el.hidden = !0, this.kindsEl = document.createElement("div"), this.kindsEl.className = "tcw-ss-kinds", this.kindsEl.setAttribute("role", "group"), this.kindsEl.setAttribute("aria-label", e("symbolSearch.kinds")), this.kindsEl.hidden = !0, this.kindsEl.addEventListener("scroll", () => this.markMore(), { passive: !0 }), this.resize = typeof ResizeObserver > "u" ? null : new ResizeObserver(() => this.markMore()), this.resize?.observe(this.kindsEl), this.exchangeEl = document.createElement("select"), this.exchangeEl.className = "tcw-settings-select tcw-ss-exchange-filter", this.exchangeEl.setAttribute("aria-label", e("symbolSearch.exchange")), this.exchangeEl.hidden = !0, this.exchangeEl.addEventListener("change", () => {
176
+ this.exchange = L(this.exchangeEl.value) || null, this.onChange(!1);
177
+ }), this.el.append(this.kindsEl, this.exchangeEl);
178
+ }
179
+ see(e) {
180
+ let t = this.kinds.size, n = this.exchanges.size;
181
+ for (let t of e) V(this.kinds, t?.type), V(this.exchanges, t?.exchange);
182
+ this.kinds.size !== t && this.renderKinds(), this.exchanges.size !== n && this.renderExchanges(), this.kindsEl.hidden = this.kinds.size === 0, this.exchangeEl.hidden = this.exchanges.size < R, this.el.hidden = this.kindsEl.hidden && this.exchangeEl.hidden, this.markMore();
183
+ }
184
+ destroy() {
185
+ this.resize?.disconnect();
186
+ }
187
+ markMore() {
188
+ let e = this.kindsEl, t = Math.abs(e.scrollLeft), n = e.scrollWidth - e.clientWidth, r = [t > z ? "start" : "", t < n - z ? "end" : ""].filter(Boolean);
189
+ r.length > 0 ? e.dataset.more = r.join(" ") : delete e.dataset.more;
190
+ }
191
+ passes(e, t) {
192
+ return H(this.kind, L(e?.type), t) && H(this.exchange, L(e?.exchange), t);
193
+ }
194
+ renderKinds() {
195
+ let e = (e, t) => {
196
+ let n = document.createElement("button");
197
+ return n.type = "button", n.className = "tcw-ss-type", n.textContent = t, e !== null && (n.dir = "auto"), n.setAttribute("aria-pressed", String(this.kind === e)), n.addEventListener("click", () => {
198
+ this.kind = e;
199
+ for (let e of this.kindsEl.children) e.setAttribute("aria-pressed", String(e === n));
200
+ this.onChange(!0);
201
+ }), n;
202
+ }, t = [...this.kinds].map(([t, n]) => e(t, n));
203
+ this.kindsEl.replaceChildren(e(null, this.t("symbolSearch.allKinds")), ...t);
204
+ }
205
+ renderExchanges() {
206
+ let e = (e, t) => {
207
+ let n = document.createElement("option");
208
+ return n.value = e, n.textContent = t, e && (n.dir = "auto"), n;
209
+ }, t = [...this.exchanges.values()].map((t) => e(t, t));
210
+ this.exchangeEl.replaceChildren(e("", this.t("symbolSearch.allExchanges")), ...t), this.exchangeEl.value = this.exchange === null ? "" : this.exchanges.get(this.exchange) ?? "";
211
+ }
212
+ };
213
+ function V(e, t) {
214
+ let n = L(t);
215
+ n && !e.has(n) && e.set(n, t.trim());
216
+ }
217
+ function H(e, t, n) {
218
+ return e === null || t === e || n && t === "";
219
+ }
220
+ //#endregion
221
+ //#region src/widget/WidgetSymbolSearch.ts
222
+ var U = 150, W = 229, G = 200, K = 1, q = class {
223
+ backdrop = null;
224
+ input = null;
225
+ list = null;
226
+ results = null;
227
+ live = null;
228
+ columns = null;
229
+ filters = null;
230
+ mode = null;
231
+ given = [];
232
+ rows = [];
233
+ rowsGiven = !1;
234
+ shown = [];
235
+ compared = [];
236
+ way = "";
237
+ selectedIndex = 0;
238
+ searchFn = null;
239
+ searchTimer = null;
240
+ searchAbort = null;
241
+ status = "idle";
242
+ pickOnResults = !1;
243
+ heard = /* @__PURE__ */ new Map();
244
+ givenInfo = /* @__PURE__ */ new Map();
245
+ foldedNames = /* @__PURE__ */ new Map();
246
+ returnFocus = null;
247
+ uid = K++;
248
+ constructor(e, t = () => document.body, n = d) {
249
+ this.callbacks = e, this.host = t, this.t = n;
250
+ }
251
+ open(e) {
252
+ this.begin({
253
+ kind: "search",
254
+ start: e
255
+ });
256
+ }
257
+ openCompare(e) {
258
+ this.compared = e.compared, this.way = e.ways.some((t) => t.id === e.way) ? e.way : e.ways[0]?.id ?? "", this.begin({
259
+ kind: "compare",
260
+ start: e
261
+ });
262
+ }
263
+ setCompared(e) {
264
+ if (this.compared = e, this.mode?.kind !== "compare" || !this.results) return;
265
+ let t = this.results.contains(document.activeElement);
266
+ this.renderList(), t && !this.results.contains(document.activeElement) && this.input?.focus();
267
+ }
268
+ close() {
269
+ if (!this.backdrop) return;
270
+ this.cancelSearch(), this.pickOnResults = !1, this.searchFn = null, this.backdrop.remove(), this.backdrop = this.input = this.list = this.results = this.live = this.columns = null, this.filters?.destroy(), this.filters = null, this.mode = null, this.callbacks.onClose();
271
+ let e = this.returnFocus;
272
+ this.returnFocus = null, e?.isConnected && e.focus();
273
+ }
274
+ isOpen() {
275
+ return this.backdrop !== null;
276
+ }
277
+ isComparing() {
278
+ return this.mode?.kind === "compare";
279
+ }
280
+ destroy() {
281
+ this.close();
282
+ }
283
+ begin(e) {
284
+ this.backdrop && this.close(), this.returnFocus = document.activeElement instanceof HTMLElement ? document.activeElement : null, this.mode = e, this.searchFn = e.start.search ?? null, this.status = "idle", this.learnGiven(e), this.build(e);
285
+ let t = e.kind === "search" ? e.start.query ?? "" : "";
286
+ this.input && (this.input.value = t), t ? (this.filter(), this.searchFn && this.searchNow()) : this.listGiven(), this.input?.focus();
287
+ }
288
+ learnGiven(e) {
289
+ let t = o(e.start.symbols);
290
+ this.given = t.names, this.givenInfo = t.info, this.foldedNames = /* @__PURE__ */ new Map();
291
+ let n = e.start.current, i = e.kind === "search" ? e.start.currentInfo : null;
292
+ if (i && typeof i == "object" && n) {
293
+ let { description: e, logo: t } = s(i, n);
294
+ this.givenInfo.set(n, r({
295
+ symbol: n,
296
+ description: e,
297
+ logo: t
298
+ }, this.givenInfo.get(n)));
299
+ }
300
+ }
301
+ infoOf(e) {
302
+ return r(this.givenInfo.get(e), this.heard.get(e));
303
+ }
304
+ build(t) {
305
+ let n = document.createElement("div");
306
+ n.className = "tcw-modal-backdrop";
307
+ let r = !1;
308
+ n.addEventListener("pointerdown", (e) => {
309
+ r = e.target === n;
310
+ }), n.addEventListener("click", (e) => {
311
+ e.target === n && r && this.close(), r = !1;
312
+ });
313
+ let i = document.createElement("div");
314
+ i.className = `tcw-modal tcw-ss${t.kind === "compare" ? " tcw-ss--compare" : ""}`, e(i, t.kind === "compare" ? "compare" : "symbolSearch"), i.setAttribute("role", "dialog"), i.setAttribute("aria-modal", "true"), i.setAttribute("aria-labelledby", `tcw-ss-title-${this.uid}`), i.tabIndex = -1, i.addEventListener("keydown", (e) => this.onKeyDown(e, i)), i.append(this.buildHeader(t), this.buildSearch()), t.kind === "compare" && i.appendChild(this.buildWay(t.start));
315
+ let a = new B(this.t, (e) => {
316
+ this.afterResults(!1), e && this.input?.focus();
317
+ }), o = document.createElement("div");
318
+ o.className = "tcw-ss-list", o.id = `tcw-ss-list-${this.uid}`, o.setAttribute("role", "listbox");
319
+ let s = document.createElement("div");
320
+ s.className = "tcw-ss-results";
321
+ let c = this.buildColumns();
322
+ s.append(c, o), s.addEventListener("mousedown", (e) => {
323
+ e.target.closest("button") || e.preventDefault();
324
+ });
325
+ let l = document.createElement("div");
326
+ l.className = "tcw-ss-live tcw-visually-hidden", l.setAttribute("aria-live", "polite"), i.append(a.el, s, l);
327
+ let u = t.kind === "search" ? t.start.hint : void 0;
328
+ if (u) {
329
+ let e = document.createElement("div");
330
+ e.className = "tcw-ss-foot", e.textContent = u, i.appendChild(e);
331
+ }
332
+ n.appendChild(i), this.host().appendChild(n), this.backdrop = n, this.filters = a, this.columns = c, this.list = o, this.results = s, this.live = l;
333
+ }
334
+ buildColumns() {
335
+ let e = document.createElement("div");
336
+ e.className = "tcw-ss-columns", e.setAttribute("aria-hidden", "true");
337
+ let t = [
338
+ "",
339
+ this.t("symbolSearch.symbol"),
340
+ this.t("symbolSearch.description"),
341
+ this.t("symbolSearch.type"),
342
+ this.t("symbolSearch.exchange")
343
+ ];
344
+ return e.append(...t.map((e) => this.tag("tcw-ss-head", e))), e;
345
+ }
346
+ buildHeader(e) {
347
+ let n = document.createElement("div");
348
+ n.className = "tcw-modal-header";
349
+ let r = document.createElement("h3");
350
+ r.id = `tcw-ss-title-${this.uid}`, r.textContent = this.t(e.kind === "compare" ? "compare.title" : "symbolSearch.title");
351
+ let i = document.createElement("button");
352
+ return i.type = "button", i.className = "tcw-modal-close", i.setAttribute("aria-label", this.t("common.close")), i.innerHTML = t("x", 16), i.addEventListener("click", () => this.close()), n.append(r, i), n;
353
+ }
354
+ buildSearch() {
355
+ let e = document.createElement("label");
356
+ e.className = "tcw-ss-search", e.innerHTML = t("search", 16);
357
+ let n = document.createElement("input");
358
+ return n.type = "search", n.className = "tcw-ss-input", n.placeholder = this.t("symbolSearch.placeholder"), n.setAttribute("aria-label", this.t("symbolSearch.placeholder")), n.setAttribute("role", "combobox"), n.setAttribute("aria-expanded", "true"), n.setAttribute("aria-controls", `tcw-ss-list-${this.uid}`), n.setAttribute("aria-autocomplete", "list"), n.autocomplete = "off", n.spellcheck = !1, n.addEventListener("input", () => this.filter()), e.appendChild(n), this.input = n, e;
359
+ }
360
+ buildWay(e) {
361
+ let t = document.createElement("label");
362
+ t.className = "tcw-ss-way";
363
+ let n = document.createElement("span");
364
+ n.textContent = this.t("compare.addAs");
365
+ let r = document.createElement("select");
366
+ r.className = "tcw-settings-select tcw-ss-way-select";
367
+ for (let t of e.ways) {
368
+ let e = document.createElement("option");
369
+ e.value = t.id, e.textContent = t.label, r.appendChild(e);
370
+ }
371
+ return r.value = this.way, r.addEventListener("change", () => {
372
+ this.way = r.value;
373
+ }), t.append(n, r), t;
374
+ }
375
+ listGiven() {
376
+ this.rows = this.given.map((e) => ({
377
+ symbol: e,
378
+ score: 0,
379
+ info: this.infoOf(e)
380
+ })), this.rowsGiven = !0, this.afterResults(!0);
381
+ }
382
+ filter() {
383
+ this.pickOnResults = !1;
384
+ let e = this.input?.value.trim() ?? "";
385
+ if (this.searchFn && e) {
386
+ this.scheduleSearch(e);
387
+ return;
388
+ }
389
+ if (this.cancelSearch(), this.status = "idle", !e) {
390
+ this.listGiven();
391
+ return;
392
+ }
393
+ let t = k(e);
394
+ this.rows = this.given.map((e) => {
395
+ let n = this.infoOf(e);
396
+ return {
397
+ symbol: e,
398
+ score: A(e, this.foldedName(n?.description), t),
399
+ info: n
400
+ };
401
+ }).filter((e) => e.score > 0).sort((e, t) => t.score - e.score), this.rowsGiven = !0, this.afterResults(!1);
402
+ }
403
+ foldedName(e) {
404
+ if (!e) return "";
405
+ let t = this.foldedNames.get(e);
406
+ return t === void 0 && (t = N(e), this.foldedNames.set(e, t)), t;
407
+ }
408
+ scheduleSearch(e) {
409
+ this.searchTimer !== null && clearTimeout(this.searchTimer), this.searchTimer = setTimeout(() => {
410
+ this.searchTimer = null, this.runSearch(e);
411
+ }, 150);
412
+ }
413
+ searchNow() {
414
+ this.searchTimer !== null && clearTimeout(this.searchTimer), this.searchTimer = null, this.runSearch(this.input?.value.trim() ?? "");
415
+ }
416
+ async runSearch(e) {
417
+ let t = this.searchFn;
418
+ if (!t) return;
419
+ this.searchAbort?.abort();
420
+ let n = new AbortController();
421
+ this.searchAbort = n, this.status = "searching", this.shown.length === 0 && this.renderList();
422
+ try {
423
+ let i = await t(e, n.signal);
424
+ if (n.signal.aborted) return;
425
+ let a = c(i);
426
+ for (let e of a) this.heard.set(e.symbol, r(this.heard.get(e.symbol), e));
427
+ this.rows = a.map((e) => ({
428
+ symbol: e.symbol,
429
+ score: 0,
430
+ info: this.infoOf(e.symbol)
431
+ })), this.status = "idle";
432
+ } catch {
433
+ if (n.signal.aborted) return;
434
+ this.rows = [], this.status = "failed";
435
+ }
436
+ this.rowsGiven = !1, this.afterResults(!1), this.pickOnResults && (this.pickOnResults = !1, this.pick(0));
437
+ }
438
+ cancelSearch() {
439
+ this.searchTimer !== null && clearTimeout(this.searchTimer), this.searchTimer = null, this.searchAbort?.abort(), this.searchAbort = null;
440
+ }
441
+ afterResults(e) {
442
+ let t = this.listableRows();
443
+ this.filters?.see(t.map((e) => e.info)), this.shown = this.visibleRows(t);
444
+ let n = e ? this.shown.findIndex((e) => e.symbol === this.mode?.start.current) : -1;
445
+ this.selectedIndex = n >= 0 && n < this.listedCount() ? n : 0, this.renderList();
446
+ }
447
+ listedCount() {
448
+ return Math.min(this.shown.length, 200);
449
+ }
450
+ listableRows() {
451
+ if (this.mode?.kind !== "compare") return this.rows;
452
+ let e = this.mode.start.current;
453
+ return this.rows.filter((t) => t.symbol !== e);
454
+ }
455
+ visibleRows(e) {
456
+ let t = this.filters;
457
+ return t ? e.filter((e) => t.passes(e.info, this.rowsGiven)) : [...e];
458
+ }
459
+ renderList() {
460
+ let e = this.list, t = this.results;
461
+ if (!e || !t) return;
462
+ let n = (this.input?.value ?? "").trim(), r = this.mode?.kind === "compare", i = [];
463
+ if (r && !n && this.compared.length > 0) {
464
+ let t = this.heading(this.t("compare.onChart"), "added"), n = document.createElement("div");
465
+ n.className = "tcw-ss-added", n.setAttribute("role", "group"), n.setAttribute("aria-labelledby", t.id), n.append(...this.compared.map((e) => this.addedRow(e)));
466
+ let r = this.heading(this.t("compare.symbols"), "symbols");
467
+ r.hidden = this.shown.length === 0, i.push(t, n, r), e.setAttribute("aria-labelledby", r.id);
468
+ } else e.setAttribute("aria-labelledby", `tcw-ss-title-${this.uid}`);
469
+ let a = n.toUpperCase(), o = new Set(this.compared.map((e) => e.symbol)), s = this.shown.slice(0, 200);
470
+ e.replaceChildren(...s.map((e, t) => this.row(e, t, a, r && o.has(e.symbol))));
471
+ let c = this.shown.length === 0 ? this.emptyNote(n, r) : this.moreNote(this.shown.length - s.length);
472
+ t.replaceChildren(...this.columns ? [this.columns] : [], ...i, e, ...c ? [c] : []), this.live && (this.live.textContent = this.shown.length === 0 ? c?.textContent ?? "" : ""), this.markSelection();
473
+ }
474
+ emptyNote(e, t) {
475
+ let n;
476
+ if (this.status === "searching") n = this.t("symbolSearch.searching");
477
+ else if (this.status === "failed") n = this.t("symbolSearch.failed");
478
+ else if (t && !e) {
479
+ if (this.compared.length > 0) return null;
480
+ n = this.t("compare.empty");
481
+ } else n = this.t("symbolSearch.empty");
482
+ let r = document.createElement("div");
483
+ return r.className = "tcw-ss-empty", r.textContent = n, r;
484
+ }
485
+ moreNote(e) {
486
+ if (e <= 0) return null;
487
+ let t = document.createElement("div");
488
+ return t.className = "tcw-ss-more", t.textContent = u(this.t("symbolSearch.more"), { count: e }), t;
489
+ }
490
+ heading(e, t) {
491
+ let n = document.createElement("div");
492
+ return n.className = "tcw-ss-heading", n.id = `tcw-ss-${t}-${this.uid}`, n.textContent = e, n;
493
+ }
494
+ row(e, n, r, i) {
495
+ let a = document.createElement("div");
496
+ a.className = "tcw-ss-row", a.id = `tcw-ss-opt-${this.uid}-${n}`, a.dataset.symbol = e.symbol, a.setAttribute("role", "option");
497
+ let o = this.mode?.kind === "search" && e.symbol === this.mode.start.current;
498
+ a.classList.toggle("tcw-current", o), a.classList.toggle("tcw-on-chart", i), o && a.setAttribute("aria-current", "true");
499
+ let s = this.tag("tcw-ss-kind", e.info?.type?.trim() ?? ""), c = this.tag("tcw-ss-exchange", e.info?.exchange?.trim() ?? "");
500
+ if (s.dir = c.dir = "auto", a.append(C(e.symbol, e.info), I(e.symbol, r), this.descriptionCell(e), s, c), o || i) {
501
+ let e = document.createElement("span");
502
+ e.className = "tcw-ss-check", e.innerHTML = t("check", 14), a.appendChild(e);
503
+ }
504
+ return i && a.appendChild(this.tag("tcw-visually-hidden", this.t("compare.onChart"))), a.addEventListener("click", () => this.pick(n)), a.addEventListener("mousemove", () => {
505
+ this.selectedIndex !== n && (this.selectedIndex = n, this.markSelection());
506
+ }), a;
507
+ }
508
+ descriptionCell(e) {
509
+ let t = document.createElement("span");
510
+ t.className = "tcw-ss-desc-cell";
511
+ let n = e.info?.description && e.info.description !== e.symbol ? e.info.description : "";
512
+ if (n) {
513
+ let e = this.tag("tcw-ss-desc", n);
514
+ e.dir = "auto", t.appendChild(e);
515
+ }
516
+ return t;
517
+ }
518
+ addedRow(e) {
519
+ let n = document.createElement("div");
520
+ if (n.className = "tcw-ss-added-row", n.setAttribute("role", "presentation"), e.color) {
521
+ let t = document.createElement("span");
522
+ t.className = "tcw-ss-swatch", t.style.background = e.color, n.appendChild(t);
523
+ }
524
+ let r = document.createElement("span");
525
+ r.className = "tcw-ss-way-cell", r.appendChild(this.tag("tcw-ss-way-label", e.way));
526
+ let i = document.createElement("button");
527
+ i.type = "button", i.className = "tcw-ss-remove";
528
+ let a = u(this.t("compare.remove"), { symbol: e.symbol });
529
+ return i.title = a, i.setAttribute("aria-label", a), i.innerHTML = t("x", 12), i.addEventListener("click", () => {
530
+ this.mode?.kind === "compare" && this.mode.start.onRemove(e.id);
531
+ }), n.append(I(e.symbol, ""), r, i), n;
532
+ }
533
+ tag(e, t) {
534
+ let n = document.createElement("span");
535
+ return n.className = e, n.textContent = t, n;
536
+ }
537
+ markSelection() {
538
+ let e = this.list?.querySelectorAll(".tcw-ss-row") ?? [], t = null;
539
+ e.forEach((e, n) => {
540
+ let r = n === this.selectedIndex;
541
+ e.setAttribute("aria-selected", String(r)), e.classList.toggle("tcw-selected", r), r && (t = e);
542
+ });
543
+ let n = t;
544
+ n ? (this.input?.setAttribute("aria-activedescendant", n.id), n.scrollIntoView?.({ block: "nearest" })) : this.input?.removeAttribute("aria-activedescendant");
545
+ }
546
+ pick(e) {
547
+ let t = this.shown[e], n = this.mode;
548
+ if (!t || !n) return;
549
+ if (n.kind === "compare") {
550
+ this.selectedIndex = e, this.markSelection(), n.start.onAdd(t.symbol, this.way);
551
+ return;
552
+ }
553
+ let r = n.start.onPick ?? this.callbacks.onPick;
554
+ this.close(), r(t.symbol);
555
+ }
556
+ onKeyDown(e, t) {
557
+ if (e.stopPropagation(), e.isComposing || e.keyCode === W) return;
558
+ if (e.key === "Escape") {
559
+ e.preventDefault(), this.close();
560
+ return;
561
+ }
562
+ if (n(e, t), e.target !== this.input) return;
563
+ let r = this.listedCount();
564
+ if (e.key === "ArrowDown" || e.key === "ArrowUp") {
565
+ if (e.preventDefault(), r === 0) return;
566
+ this.selectedIndex = (this.selectedIndex + (e.key === "ArrowDown" ? 1 : -1) + r) % r, this.markSelection();
567
+ } else if (e.key === "Enter") {
568
+ if (e.preventDefault(), e.repeat && this.mode?.kind === "compare") return;
569
+ if (this.searchTimer !== null || this.status === "searching") {
570
+ this.pickOnResults = !0, this.searchTimer !== null && this.searchNow();
571
+ return;
572
+ }
573
+ this.pick(this.selectedIndex);
574
+ }
575
+ }
576
+ };
577
+ //#endregion
578
+ export { G as MAX_LISTED_ROWS, U as SYMBOL_SEARCH_DEBOUNCE_MS, q as WidgetSymbolSearch };
579
+
580
+ //# sourceMappingURL=WidgetSymbolSearch-CvPpjIwa.js.map