oakscriptjs 0.5.0 → 0.6.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.
- package/README.md +42 -8
- package/dist/array/index.d.ts +7 -7
- package/dist/array/index.d.ts.map +1 -1
- package/dist/box/index.d.ts +11 -3
- package/dist/box/index.d.ts.map +1 -1
- package/dist/color/index.d.ts +15 -15
- package/dist/color/index.d.ts.map +1 -1
- package/dist/compare/index.d.ts +8 -0
- package/dist/compare/index.d.ts.map +1 -0
- package/dist/drawing/registry.d.ts +19 -0
- package/dist/drawing/registry.d.ts.map +1 -0
- package/dist/index.cjs +1740 -608
- package/dist/index.d.ts +9 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.mjs +1740 -608
- package/dist/input.d.ts +7 -1
- package/dist/input.d.ts.map +1 -1
- package/dist/label/index.d.ts +12 -4
- package/dist/label/index.d.ts.map +1 -1
- package/dist/line/index.d.ts +11 -3
- package/dist/line/index.d.ts.map +1 -1
- package/dist/linefill/index.d.ts +3 -1
- package/dist/linefill/index.d.ts.map +1 -1
- package/dist/map/index.d.ts +14 -0
- package/dist/map/index.d.ts.map +1 -0
- package/dist/polyline/index.d.ts +1 -0
- package/dist/polyline/index.d.ts.map +1 -1
- package/dist/runtime/adapters/SimpleInputAdapter.d.ts.map +1 -1
- package/dist/runtime/index.cjs +40 -1
- package/dist/runtime/index.d.ts +1 -1
- package/dist/runtime/index.d.ts.map +1 -1
- package/dist/runtime/index.mjs +40 -1
- package/dist/runtime/inputs.d.ts +3 -0
- package/dist/runtime/inputs.d.ts.map +1 -1
- package/dist/runtime/series.d.ts.map +1 -1
- package/dist/runtime/types.d.ts +1 -1
- package/dist/runtime/types.d.ts.map +1 -1
- package/dist/script/index.cjs +3097 -635
- package/dist/script/index.d.ts +293 -27
- package/dist/script/index.d.ts.map +1 -1
- package/dist/script/index.mjs +3097 -635
- package/dist/security/resample.d.ts +13 -0
- package/dist/security/resample.d.ts.map +1 -0
- package/dist/session/bars.d.ts +34 -0
- package/dist/session/bars.d.ts.map +1 -0
- package/dist/session/calendar.d.ts +31 -0
- package/dist/session/calendar.d.ts.map +1 -0
- package/dist/str/dateformat.d.ts +2 -0
- package/dist/str/dateformat.d.ts.map +1 -0
- package/dist/str/index.d.ts +1 -1
- package/dist/str/index.d.ts.map +1 -1
- package/dist/str/messageformat.d.ts +2 -0
- package/dist/str/messageformat.d.ts.map +1 -0
- package/dist/str/numberformat.d.ts +3 -0
- package/dist/str/numberformat.d.ts.map +1 -0
- package/dist/ta/index.d.ts +14 -5
- package/dist/ta/index.d.ts.map +1 -1
- package/dist/ta-series.d.ts +23 -5
- package/dist/ta-series.d.ts.map +1 -1
- package/dist/text/index.d.ts +4 -0
- package/dist/text/index.d.ts.map +1 -0
- package/dist/time/datestring.d.ts +2 -0
- package/dist/time/datestring.d.ts.map +1 -0
- package/dist/time/index.d.ts +11 -0
- package/dist/time/index.d.ts.map +1 -1
- package/dist/time/session.d.ts +2 -0
- package/dist/time/session.d.ts.map +1 -0
- package/dist/time/timezone.d.ts +13 -0
- package/dist/time/timezone.d.ts.map +1 -0
- package/dist/timeframe/index.d.ts +17 -0
- package/dist/timeframe/index.d.ts.map +1 -0
- package/dist/types/index.d.ts +7 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/metadata.d.ts +1 -1
- package/dist/types/metadata.d.ts.map +1 -1
- package/dist/utils/index.d.ts +1 -0
- package/dist/utils/index.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
var __defProp = Object.defineProperty;
|
|
2
|
-
var __export = (target,
|
|
3
|
-
for (var name in
|
|
4
|
-
__defProp(target, name, { get:
|
|
2
|
+
var __export = (target, all7) => {
|
|
3
|
+
for (var name in all7)
|
|
4
|
+
__defProp(target, name, { get: all7[name], enumerable: true });
|
|
5
5
|
};
|
|
6
6
|
|
|
7
7
|
// src/types/index.ts
|
|
@@ -15,6 +15,7 @@ var xloc = {
|
|
|
15
15
|
// src/ta/index.ts
|
|
16
16
|
var ta_exports = {};
|
|
17
17
|
__export(ta_exports, {
|
|
18
|
+
accdist: () => accdist,
|
|
18
19
|
alma: () => alma,
|
|
19
20
|
atr: () => atr,
|
|
20
21
|
barssince: () => barssince,
|
|
@@ -37,6 +38,7 @@ __export(ta_exports, {
|
|
|
37
38
|
highestbars: () => highestbars,
|
|
38
39
|
hma: () => hma,
|
|
39
40
|
ichimoku: () => ichimoku,
|
|
41
|
+
iii: () => iii,
|
|
40
42
|
kc: () => kc,
|
|
41
43
|
kcw: () => kcw,
|
|
42
44
|
linreg: () => linreg,
|
|
@@ -49,12 +51,16 @@ __export(ta_exports, {
|
|
|
49
51
|
min: () => min,
|
|
50
52
|
mode: () => mode,
|
|
51
53
|
mom: () => mom,
|
|
54
|
+
nvi: () => nvi,
|
|
55
|
+
obv: () => obv,
|
|
52
56
|
percentile_linear_interpolation: () => percentile_linear_interpolation,
|
|
53
57
|
percentile_nearest_rank: () => percentile_nearest_rank,
|
|
54
58
|
percentrank: () => percentrank,
|
|
55
59
|
pivot_point_levels: () => pivot_point_levels,
|
|
56
60
|
pivothigh: () => pivothigh,
|
|
57
61
|
pivotlow: () => pivotlow,
|
|
62
|
+
pvi: () => pvi,
|
|
63
|
+
pvt: () => pvt,
|
|
58
64
|
range: () => range,
|
|
59
65
|
rci: () => rci,
|
|
60
66
|
rising: () => rising,
|
|
@@ -73,8 +79,10 @@ __export(ta_exports, {
|
|
|
73
79
|
variance: () => variance,
|
|
74
80
|
vwap: () => vwap,
|
|
75
81
|
vwma: () => vwma,
|
|
82
|
+
wad: () => wad,
|
|
76
83
|
wma: () => wma,
|
|
77
84
|
wpr: () => wpr,
|
|
85
|
+
wvad: () => wvad,
|
|
78
86
|
zigzag: () => zigzag
|
|
79
87
|
});
|
|
80
88
|
function sma(source, length2) {
|
|
@@ -134,8 +142,8 @@ function rsi(source, length2) {
|
|
|
134
142
|
for (let i = 1; i < source.length; i++) {
|
|
135
143
|
changes.push(source[i] - source[i - 1]);
|
|
136
144
|
}
|
|
137
|
-
const gains = changes.map((c) => c > 0 ? c : 0);
|
|
138
|
-
const losses = changes.map((c) => c < 0 ? -c : 0);
|
|
145
|
+
const gains = changes.map((c) => Number.isNaN(c) ? NaN : c > 0 ? c : 0);
|
|
146
|
+
const losses = changes.map((c) => Number.isNaN(c) ? NaN : c < 0 ? -c : 0);
|
|
139
147
|
const avgGains = rma(gains, length2);
|
|
140
148
|
const avgLosses = rma(losses, length2);
|
|
141
149
|
result.push(NaN);
|
|
@@ -174,23 +182,42 @@ function bb(series, length2, mult2) {
|
|
|
174
182
|
}
|
|
175
183
|
return [basis, upper2, lower2];
|
|
176
184
|
}
|
|
177
|
-
function stdev(source, length2) {
|
|
178
|
-
const result = [];
|
|
185
|
+
function stdev(source, length2, biased = true) {
|
|
179
186
|
const len = Math.floor(length2);
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
if (
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
187
|
+
return source.map((_, i) => {
|
|
188
|
+
const values2 = lastValues(source, i, len);
|
|
189
|
+
if (!values2) return NaN;
|
|
190
|
+
const mean = values2.reduce((a, b2) => a + b2, 0) / len;
|
|
191
|
+
const squares = values2.reduce((a, b2) => a + (b2 - mean) * (b2 - mean), 0);
|
|
192
|
+
return Math.sqrt(squares / (biased ? len : len - 1));
|
|
193
|
+
});
|
|
194
|
+
}
|
|
195
|
+
function lastValues(source, i, length2) {
|
|
196
|
+
const values2 = [];
|
|
197
|
+
for (let j = i; j >= 0 && values2.length < length2; j--) {
|
|
198
|
+
const x = source[j];
|
|
199
|
+
if (!Number.isNaN(x)) values2.push(x);
|
|
200
|
+
}
|
|
201
|
+
return values2.length === length2 ? values2 : null;
|
|
202
|
+
}
|
|
203
|
+
function windowUntilNa(source, i, length2) {
|
|
204
|
+
const values2 = [];
|
|
205
|
+
for (let j = 0; j < length2 && i - j >= 0; j++) {
|
|
206
|
+
const x = source[i - j];
|
|
207
|
+
if (Number.isNaN(x)) break;
|
|
208
|
+
values2.push([x, -j]);
|
|
209
|
+
}
|
|
210
|
+
return values2;
|
|
211
|
+
}
|
|
212
|
+
function extremeOffset(source, length2, isHigher) {
|
|
213
|
+
return source.map((_, i) => {
|
|
214
|
+
if (i < length2 - 1) return NaN;
|
|
215
|
+
const w = windowUntilNa(source, i, length2);
|
|
216
|
+
if (w.length === 0) return 0;
|
|
217
|
+
let best = w[0];
|
|
218
|
+
for (const item of w) if (isHigher(item[0], best[0])) best = item;
|
|
219
|
+
return best[1];
|
|
220
|
+
});
|
|
194
221
|
}
|
|
195
222
|
function crossover(series1, series2) {
|
|
196
223
|
const result = [];
|
|
@@ -343,8 +370,10 @@ function rma(source, length2) {
|
|
|
343
370
|
const val = source[i];
|
|
344
371
|
if (val !== void 0 && !isNaN(val)) {
|
|
345
372
|
rmaValue = alpha * val + (1 - alpha) * rmaValue;
|
|
373
|
+
result.push(rmaValue);
|
|
374
|
+
} else {
|
|
375
|
+
result.push(NaN);
|
|
346
376
|
}
|
|
347
|
-
result.push(rmaValue);
|
|
348
377
|
}
|
|
349
378
|
}
|
|
350
379
|
return result;
|
|
@@ -369,47 +398,26 @@ function wma(source, length2) {
|
|
|
369
398
|
return result;
|
|
370
399
|
}
|
|
371
400
|
function highest(source, length2) {
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
let max6 = -Infinity;
|
|
378
|
-
for (let j = 0; j < length2; j++) {
|
|
379
|
-
if (!isNaN(source[i - j])) {
|
|
380
|
-
max6 = Math.max(max6, source[i - j]);
|
|
381
|
-
}
|
|
382
|
-
}
|
|
383
|
-
result.push(max6 === -Infinity ? NaN : max6);
|
|
384
|
-
}
|
|
385
|
-
}
|
|
386
|
-
return result;
|
|
401
|
+
return source.map((_, i) => {
|
|
402
|
+
if (i < length2 - 1) return NaN;
|
|
403
|
+
const w = windowUntilNa(source, i, length2);
|
|
404
|
+
return w.length ? Math.max(...w.map((x) => x[0])) : NaN;
|
|
405
|
+
});
|
|
387
406
|
}
|
|
388
407
|
function lowest(source, length2) {
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
let min6 = Infinity;
|
|
395
|
-
for (let j = 0; j < length2; j++) {
|
|
396
|
-
if (!isNaN(source[i - j])) {
|
|
397
|
-
min6 = Math.min(min6, source[i - j]);
|
|
398
|
-
}
|
|
399
|
-
}
|
|
400
|
-
result.push(min6 === Infinity ? NaN : min6);
|
|
401
|
-
}
|
|
402
|
-
}
|
|
403
|
-
return result;
|
|
408
|
+
return source.map((_, i) => {
|
|
409
|
+
if (i < length2 - 1) return NaN;
|
|
410
|
+
const w = windowUntilNa(source, i, length2);
|
|
411
|
+
return w.length ? Math.min(...w.map((x) => x[0])) : NaN;
|
|
412
|
+
});
|
|
404
413
|
}
|
|
405
414
|
function cum(source) {
|
|
406
|
-
const result = [];
|
|
407
415
|
let sum4 = 0;
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
416
|
+
return source.map((v) => {
|
|
417
|
+
if (Number.isNaN(v)) return NaN;
|
|
418
|
+
sum4 += v;
|
|
419
|
+
return sum4;
|
|
420
|
+
});
|
|
413
421
|
}
|
|
414
422
|
function cross(source1, source2) {
|
|
415
423
|
const result = [];
|
|
@@ -538,21 +546,21 @@ function median(source, length2) {
|
|
|
538
546
|
if (i < length2 - 1) {
|
|
539
547
|
result.push(NaN);
|
|
540
548
|
} else {
|
|
541
|
-
const
|
|
549
|
+
const values2 = [];
|
|
542
550
|
for (let j = 0; j < length2; j++) {
|
|
543
551
|
if (!isNaN(source[i - j])) {
|
|
544
|
-
|
|
552
|
+
values2.push(source[i - j]);
|
|
545
553
|
}
|
|
546
554
|
}
|
|
547
|
-
if (
|
|
555
|
+
if (values2.length === 0) {
|
|
548
556
|
result.push(NaN);
|
|
549
557
|
} else {
|
|
550
|
-
|
|
551
|
-
const mid = Math.floor(
|
|
552
|
-
if (
|
|
553
|
-
result.push((
|
|
558
|
+
values2.sort((a, b2) => a - b2);
|
|
559
|
+
const mid = Math.floor(values2.length / 2);
|
|
560
|
+
if (values2.length % 2 === 0) {
|
|
561
|
+
result.push((values2[mid - 1] + values2[mid]) / 2);
|
|
554
562
|
} else {
|
|
555
|
-
result.push(
|
|
563
|
+
result.push(values2[mid]);
|
|
556
564
|
}
|
|
557
565
|
}
|
|
558
566
|
}
|
|
@@ -882,89 +890,44 @@ function sar(start, inc, max6, high, low, close) {
|
|
|
882
890
|
}
|
|
883
891
|
return result;
|
|
884
892
|
}
|
|
893
|
+
function pivot(source, leftbars, rightbars, isHigh) {
|
|
894
|
+
const beatsLeft = isHigh ? (x, v) => x > v : (x, v) => x < v;
|
|
895
|
+
const beatsRight = isHigh ? (x, v) => x >= v : (x, v) => x <= v;
|
|
896
|
+
return source.map((_, i) => {
|
|
897
|
+
const center = i - rightbars;
|
|
898
|
+
if (center - leftbars < 0) return NaN;
|
|
899
|
+
const v = source[center];
|
|
900
|
+
if (Number.isNaN(v)) return NaN;
|
|
901
|
+
for (let j = 1; j <= leftbars; j++) {
|
|
902
|
+
const x = source[center - j];
|
|
903
|
+
if (Number.isNaN(x)) break;
|
|
904
|
+
if (beatsLeft(x, v)) return NaN;
|
|
905
|
+
}
|
|
906
|
+
for (let j = 1; j <= rightbars; j++) {
|
|
907
|
+
const x = source[center + j];
|
|
908
|
+
if (Number.isNaN(x)) break;
|
|
909
|
+
if (beatsRight(x, v)) return NaN;
|
|
910
|
+
}
|
|
911
|
+
return v;
|
|
912
|
+
});
|
|
913
|
+
}
|
|
885
914
|
function pivothigh(sourceOrLeftbars, leftbarsOrRightbars, rightbars, high) {
|
|
886
|
-
let source;
|
|
887
|
-
let leftbars;
|
|
888
|
-
let right;
|
|
889
915
|
if (rightbars === void 0) {
|
|
890
916
|
if (!high) {
|
|
891
917
|
throw new Error("ta.pivothigh() requires high series when using two-parameter version.");
|
|
892
918
|
}
|
|
893
|
-
|
|
894
|
-
leftbars = sourceOrLeftbars;
|
|
895
|
-
right = leftbarsOrRightbars;
|
|
896
|
-
} else {
|
|
897
|
-
source = sourceOrLeftbars;
|
|
898
|
-
leftbars = leftbarsOrRightbars;
|
|
899
|
-
right = rightbars;
|
|
919
|
+
return pivot(high, sourceOrLeftbars, leftbarsOrRightbars, true);
|
|
900
920
|
}
|
|
901
|
-
|
|
902
|
-
for (let i = 0; i < source.length; i++) {
|
|
903
|
-
if (i < leftbars || i + right >= source.length) {
|
|
904
|
-
result.push(NaN);
|
|
905
|
-
continue;
|
|
906
|
-
}
|
|
907
|
-
const centerValue = source[i];
|
|
908
|
-
let isPivot = true;
|
|
909
|
-
for (let j = 1; j <= leftbars; j++) {
|
|
910
|
-
if (source[i - j] >= centerValue) {
|
|
911
|
-
isPivot = false;
|
|
912
|
-
break;
|
|
913
|
-
}
|
|
914
|
-
}
|
|
915
|
-
if (isPivot) {
|
|
916
|
-
for (let j = 1; j <= right; j++) {
|
|
917
|
-
if (source[i + j] >= centerValue) {
|
|
918
|
-
isPivot = false;
|
|
919
|
-
break;
|
|
920
|
-
}
|
|
921
|
-
}
|
|
922
|
-
}
|
|
923
|
-
result.push(isPivot ? centerValue : NaN);
|
|
924
|
-
}
|
|
925
|
-
return result;
|
|
921
|
+
return pivot(sourceOrLeftbars, leftbarsOrRightbars, rightbars, true);
|
|
926
922
|
}
|
|
927
923
|
function pivotlow(sourceOrLeftbars, leftbarsOrRightbars, rightbars, low) {
|
|
928
|
-
let source;
|
|
929
|
-
let leftbars;
|
|
930
|
-
let right;
|
|
931
924
|
if (rightbars === void 0) {
|
|
932
925
|
if (!low) {
|
|
933
926
|
throw new Error("ta.pivotlow() requires low series when using two-parameter version.");
|
|
934
927
|
}
|
|
935
|
-
|
|
936
|
-
leftbars = sourceOrLeftbars;
|
|
937
|
-
right = leftbarsOrRightbars;
|
|
938
|
-
} else {
|
|
939
|
-
source = sourceOrLeftbars;
|
|
940
|
-
leftbars = leftbarsOrRightbars;
|
|
941
|
-
right = rightbars;
|
|
928
|
+
return pivot(low, sourceOrLeftbars, leftbarsOrRightbars, false);
|
|
942
929
|
}
|
|
943
|
-
|
|
944
|
-
for (let i = 0; i < source.length; i++) {
|
|
945
|
-
if (i < leftbars || i + right >= source.length) {
|
|
946
|
-
result.push(NaN);
|
|
947
|
-
continue;
|
|
948
|
-
}
|
|
949
|
-
const centerValue = source[i];
|
|
950
|
-
let isPivot = true;
|
|
951
|
-
for (let j = 1; j <= leftbars; j++) {
|
|
952
|
-
if (source[i - j] <= centerValue) {
|
|
953
|
-
isPivot = false;
|
|
954
|
-
break;
|
|
955
|
-
}
|
|
956
|
-
}
|
|
957
|
-
if (isPivot) {
|
|
958
|
-
for (let j = 1; j <= right; j++) {
|
|
959
|
-
if (source[i + j] <= centerValue) {
|
|
960
|
-
isPivot = false;
|
|
961
|
-
break;
|
|
962
|
-
}
|
|
963
|
-
}
|
|
964
|
-
}
|
|
965
|
-
result.push(isPivot ? centerValue : NaN);
|
|
966
|
-
}
|
|
967
|
-
return result;
|
|
930
|
+
return pivot(sourceOrLeftbars, leftbarsOrRightbars, rightbars, false);
|
|
968
931
|
}
|
|
969
932
|
function barssince(condition) {
|
|
970
933
|
const result = [];
|
|
@@ -1158,27 +1121,38 @@ function wpr(high, low, close, length2 = 14) {
|
|
|
1158
1121
|
}
|
|
1159
1122
|
return result;
|
|
1160
1123
|
}
|
|
1161
|
-
function vwap(source, volume) {
|
|
1124
|
+
function vwap(source, volume, anchor, stdev_mult) {
|
|
1162
1125
|
if (source.length !== volume.length) {
|
|
1163
1126
|
throw new Error("ta.vwap: source and volume must have the same length");
|
|
1164
1127
|
}
|
|
1165
|
-
const
|
|
1166
|
-
|
|
1167
|
-
|
|
1128
|
+
const mid = [];
|
|
1129
|
+
const upper2 = [];
|
|
1130
|
+
const lower2 = [];
|
|
1131
|
+
let sumPV = 0;
|
|
1132
|
+
let sumV = 0;
|
|
1133
|
+
let sumPPV = 0;
|
|
1168
1134
|
for (let i = 0; i < source.length; i++) {
|
|
1169
|
-
if (
|
|
1170
|
-
|
|
1171
|
-
|
|
1135
|
+
if (anchor && anchor[i]) {
|
|
1136
|
+
sumPV = 0;
|
|
1137
|
+
sumV = 0;
|
|
1138
|
+
sumPPV = 0;
|
|
1172
1139
|
}
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
if (
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1140
|
+
const s = source[i];
|
|
1141
|
+
const v = volume[i];
|
|
1142
|
+
if (!Number.isNaN(s) && !Number.isNaN(v)) {
|
|
1143
|
+
sumPV += s * v;
|
|
1144
|
+
sumV += v;
|
|
1145
|
+
sumPPV += s * s * v;
|
|
1146
|
+
}
|
|
1147
|
+
const m = sumV === 0 ? NaN : sumPV / sumV;
|
|
1148
|
+
mid.push(m);
|
|
1149
|
+
if (stdev_mult !== void 0) {
|
|
1150
|
+
const sd = Math.sqrt(Math.max(0, sumPPV / sumV - m * m));
|
|
1151
|
+
upper2.push(m + stdev_mult * sd);
|
|
1152
|
+
lower2.push(m - stdev_mult * sd);
|
|
1179
1153
|
}
|
|
1180
1154
|
}
|
|
1181
|
-
return
|
|
1155
|
+
return stdev_mult === void 0 ? mid : [mid, upper2, lower2];
|
|
1182
1156
|
}
|
|
1183
1157
|
function alma(source, length2 = 9, offset = 0.85, sigma = 6, floor2 = false) {
|
|
1184
1158
|
const result = [];
|
|
@@ -1220,85 +1194,31 @@ function kcw(source, length2 = 20, mult2 = 2, useTrueRange = true, high, low, cl
|
|
|
1220
1194
|
}
|
|
1221
1195
|
return result;
|
|
1222
1196
|
}
|
|
1223
|
-
function range(
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
for (let i = 0; i < high.length; i++) {
|
|
1229
|
-
if (isNaN(high[i]) || isNaN(low[i])) {
|
|
1230
|
-
result.push(NaN);
|
|
1231
|
-
} else {
|
|
1232
|
-
result.push(high[i] - low[i]);
|
|
1233
|
-
}
|
|
1234
|
-
}
|
|
1235
|
-
return result;
|
|
1197
|
+
function range(source, length2) {
|
|
1198
|
+
return source.map((_, i) => {
|
|
1199
|
+
const values2 = lastValues(source, i, length2);
|
|
1200
|
+
return values2 ? Math.max(...values2) - Math.min(...values2) : NaN;
|
|
1201
|
+
});
|
|
1236
1202
|
}
|
|
1237
1203
|
function highestbars(source, length2) {
|
|
1238
|
-
|
|
1239
|
-
for (let i = 0; i < source.length; i++) {
|
|
1240
|
-
if (i < length2 - 1) {
|
|
1241
|
-
result.push(NaN);
|
|
1242
|
-
continue;
|
|
1243
|
-
}
|
|
1244
|
-
let highestValue = source[i - length2 + 1];
|
|
1245
|
-
let highestOffset = length2 - 1;
|
|
1246
|
-
for (let j = i - length2 + 2; j <= i; j++) {
|
|
1247
|
-
if (source[j] > highestValue) {
|
|
1248
|
-
highestValue = source[j];
|
|
1249
|
-
highestOffset = i - j;
|
|
1250
|
-
}
|
|
1251
|
-
}
|
|
1252
|
-
result.push(highestOffset);
|
|
1253
|
-
}
|
|
1254
|
-
return result;
|
|
1204
|
+
return extremeOffset(source, length2, (a, b2) => a >= b2);
|
|
1255
1205
|
}
|
|
1256
1206
|
function lowestbars(source, length2) {
|
|
1257
|
-
|
|
1258
|
-
for (let i = 0; i < source.length; i++) {
|
|
1259
|
-
if (i < length2 - 1) {
|
|
1260
|
-
result.push(NaN);
|
|
1261
|
-
continue;
|
|
1262
|
-
}
|
|
1263
|
-
let lowestValue = source[i - length2 + 1];
|
|
1264
|
-
let lowestOffset = length2 - 1;
|
|
1265
|
-
for (let j = i - length2 + 2; j <= i; j++) {
|
|
1266
|
-
if (source[j] < lowestValue) {
|
|
1267
|
-
lowestValue = source[j];
|
|
1268
|
-
lowestOffset = i - j;
|
|
1269
|
-
}
|
|
1270
|
-
}
|
|
1271
|
-
result.push(lowestOffset);
|
|
1272
|
-
}
|
|
1273
|
-
return result;
|
|
1207
|
+
return extremeOffset(source, length2, (a, b2) => a <= b2);
|
|
1274
1208
|
}
|
|
1275
|
-
function max(
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
if (isNaN(source1[i]) || isNaN(source2[i])) {
|
|
1282
|
-
result.push(NaN);
|
|
1283
|
-
} else {
|
|
1284
|
-
result.push(Math.max(source1[i], source2[i]));
|
|
1285
|
-
}
|
|
1286
|
-
}
|
|
1287
|
-
return result;
|
|
1209
|
+
function max(source) {
|
|
1210
|
+
let best = NaN;
|
|
1211
|
+
return source.map((x) => {
|
|
1212
|
+
if (!Number.isNaN(x) && !(x <= best)) best = x;
|
|
1213
|
+
return best;
|
|
1214
|
+
});
|
|
1288
1215
|
}
|
|
1289
|
-
function min(
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
if (isNaN(source1[i]) || isNaN(source2[i])) {
|
|
1296
|
-
result.push(NaN);
|
|
1297
|
-
} else {
|
|
1298
|
-
result.push(Math.min(source1[i], source2[i]));
|
|
1299
|
-
}
|
|
1300
|
-
}
|
|
1301
|
-
return result;
|
|
1216
|
+
function min(source) {
|
|
1217
|
+
let best = NaN;
|
|
1218
|
+
return source.map((x) => {
|
|
1219
|
+
if (!Number.isNaN(x) && !(x >= best)) best = x;
|
|
1220
|
+
return best;
|
|
1221
|
+
});
|
|
1302
1222
|
}
|
|
1303
1223
|
function cog(source, length2 = 10) {
|
|
1304
1224
|
const result = [];
|
|
@@ -1331,19 +1251,19 @@ function mode(source, length2) {
|
|
|
1331
1251
|
result.push(NaN);
|
|
1332
1252
|
continue;
|
|
1333
1253
|
}
|
|
1334
|
-
const
|
|
1254
|
+
const values2 = [];
|
|
1335
1255
|
for (let j = 0; j < length2; j++) {
|
|
1336
1256
|
const value = source[i - j];
|
|
1337
1257
|
if (!isNaN(value)) {
|
|
1338
|
-
|
|
1258
|
+
values2.push(value);
|
|
1339
1259
|
}
|
|
1340
1260
|
}
|
|
1341
|
-
if (
|
|
1261
|
+
if (values2.length === 0) {
|
|
1342
1262
|
result.push(NaN);
|
|
1343
1263
|
continue;
|
|
1344
1264
|
}
|
|
1345
1265
|
const frequencyMap = /* @__PURE__ */ new Map();
|
|
1346
|
-
for (const value of
|
|
1266
|
+
for (const value of values2) {
|
|
1347
1267
|
frequencyMap.set(value, (frequencyMap.get(value) || 0) + 1);
|
|
1348
1268
|
}
|
|
1349
1269
|
let maxFrequency = 0;
|
|
@@ -1369,16 +1289,16 @@ function percentile_linear_interpolation(source, length2, percentage) {
|
|
|
1369
1289
|
result.push(NaN);
|
|
1370
1290
|
continue;
|
|
1371
1291
|
}
|
|
1372
|
-
const
|
|
1292
|
+
const values2 = [];
|
|
1373
1293
|
for (let j = 0; j < length2; j++) {
|
|
1374
1294
|
const value = source[i - j];
|
|
1375
|
-
|
|
1295
|
+
values2.push(value);
|
|
1376
1296
|
}
|
|
1377
|
-
if (
|
|
1297
|
+
if (values2.some((v) => isNaN(v))) {
|
|
1378
1298
|
result.push(NaN);
|
|
1379
1299
|
continue;
|
|
1380
1300
|
}
|
|
1381
|
-
const sorted = [...
|
|
1301
|
+
const sorted = [...values2].sort((a, b2) => a - b2);
|
|
1382
1302
|
const position = percentage / 100 * (sorted.length - 1);
|
|
1383
1303
|
const lowerIndex = Math.floor(position);
|
|
1384
1304
|
const upperIndex = Math.ceil(position);
|
|
@@ -1399,18 +1319,18 @@ function percentile_nearest_rank(source, length2, percentage) {
|
|
|
1399
1319
|
result.push(NaN);
|
|
1400
1320
|
continue;
|
|
1401
1321
|
}
|
|
1402
|
-
const
|
|
1322
|
+
const values2 = [];
|
|
1403
1323
|
for (let j = 0; j < length2; j++) {
|
|
1404
1324
|
const value = source[i - j];
|
|
1405
1325
|
if (!isNaN(value)) {
|
|
1406
|
-
|
|
1326
|
+
values2.push(value);
|
|
1407
1327
|
}
|
|
1408
1328
|
}
|
|
1409
|
-
if (
|
|
1329
|
+
if (values2.length === 0) {
|
|
1410
1330
|
result.push(NaN);
|
|
1411
1331
|
continue;
|
|
1412
1332
|
}
|
|
1413
|
-
const sorted = [...
|
|
1333
|
+
const sorted = [...values2].sort((a, b2) => a - b2);
|
|
1414
1334
|
if (percentage >= 100) {
|
|
1415
1335
|
result.push(sorted[sorted.length - 1]);
|
|
1416
1336
|
continue;
|
|
@@ -1428,15 +1348,15 @@ function rci(source, length2) {
|
|
|
1428
1348
|
result.push(NaN);
|
|
1429
1349
|
continue;
|
|
1430
1350
|
}
|
|
1431
|
-
const
|
|
1351
|
+
const values2 = [];
|
|
1432
1352
|
for (let j = 0; j < length2; j++) {
|
|
1433
|
-
|
|
1353
|
+
values2.push(source[i - length2 + 1 + j]);
|
|
1434
1354
|
}
|
|
1435
|
-
if (
|
|
1355
|
+
if (values2.some((v) => isNaN(v))) {
|
|
1436
1356
|
result.push(NaN);
|
|
1437
1357
|
continue;
|
|
1438
1358
|
}
|
|
1439
|
-
const indexed =
|
|
1359
|
+
const indexed = values2.map((value, index) => ({ value, index }));
|
|
1440
1360
|
const sorted = [...indexed].sort((a, b2) => a.value - b2.value);
|
|
1441
1361
|
const ranks = new Array(length2).fill(0);
|
|
1442
1362
|
let currentRank = 1;
|
|
@@ -1800,23 +1720,86 @@ function zigzag(deviation = 5, depth = 10, backstep = 3, source, high, low) {
|
|
|
1800
1720
|
if (potentialPivot) {
|
|
1801
1721
|
confirmedPivots.push(potentialPivot);
|
|
1802
1722
|
}
|
|
1803
|
-
for (const
|
|
1804
|
-
zigzagValues[
|
|
1805
|
-
isPivot[
|
|
1723
|
+
for (const pivot2 of confirmedPivots) {
|
|
1724
|
+
zigzagValues[pivot2.index] = pivot2.price;
|
|
1725
|
+
isPivot[pivot2.index] = true;
|
|
1806
1726
|
}
|
|
1807
1727
|
let currentDir = 0;
|
|
1808
1728
|
let pivotIdx = 0;
|
|
1809
1729
|
const numConfirmed = lastPotentialWasAdded ? confirmedPivots.length - 1 : confirmedPivots.length;
|
|
1810
1730
|
for (let i = 0; i < length2; i++) {
|
|
1811
1731
|
while (pivotIdx < numConfirmed && confirmedPivots[pivotIdx].index <= i) {
|
|
1812
|
-
const
|
|
1813
|
-
currentDir =
|
|
1732
|
+
const pivot2 = confirmedPivots[pivotIdx];
|
|
1733
|
+
currentDir = pivot2.type === "low" ? 1 : -1;
|
|
1814
1734
|
pivotIdx++;
|
|
1815
1735
|
}
|
|
1816
1736
|
directions[i] = currentDir;
|
|
1817
1737
|
}
|
|
1818
1738
|
return [zigzagValues, directions, isPivot];
|
|
1819
1739
|
}
|
|
1740
|
+
function obv(close, volume) {
|
|
1741
|
+
return cum(close.map((c, i) => i === 0 ? NaN : Math.sign(c - close[i - 1]) * volume[i]));
|
|
1742
|
+
}
|
|
1743
|
+
function pvt(close, volume) {
|
|
1744
|
+
return cum(
|
|
1745
|
+
close.map((c, i) => i === 0 ? NaN : (c - close[i - 1]) / close[i - 1] * volume[i])
|
|
1746
|
+
);
|
|
1747
|
+
}
|
|
1748
|
+
function accdist(high, low, close, volume) {
|
|
1749
|
+
return cum(
|
|
1750
|
+
close.map((c, i) => {
|
|
1751
|
+
const h = high[i];
|
|
1752
|
+
const l = low[i];
|
|
1753
|
+
return h === l ? 0 : (2 * c - l - h) / (h - l) * volume[i];
|
|
1754
|
+
})
|
|
1755
|
+
);
|
|
1756
|
+
}
|
|
1757
|
+
function iii(high, low, close, volume) {
|
|
1758
|
+
return close.map((c, i) => {
|
|
1759
|
+
const range4 = high[i] - low[i];
|
|
1760
|
+
return range4 === 0 ? NaN : (2 * c - high[i] - low[i]) / range4 * volume[i];
|
|
1761
|
+
});
|
|
1762
|
+
}
|
|
1763
|
+
function wvad(open, high, low, close, volume) {
|
|
1764
|
+
return close.map((c, i) => {
|
|
1765
|
+
const range4 = high[i] - low[i];
|
|
1766
|
+
return range4 === 0 ? NaN : (c - open[i]) / range4 * volume[i];
|
|
1767
|
+
});
|
|
1768
|
+
}
|
|
1769
|
+
function wad(high, low, close) {
|
|
1770
|
+
return cum(
|
|
1771
|
+
close.map((c, i) => {
|
|
1772
|
+
const prev = i === 0 ? NaN : close[i - 1];
|
|
1773
|
+
const mom3 = c - prev;
|
|
1774
|
+
if (mom3 > 0) return c - Math.min(low[i], prev);
|
|
1775
|
+
if (mom3 < 0) return c - Math.max(high[i], prev);
|
|
1776
|
+
return 0;
|
|
1777
|
+
})
|
|
1778
|
+
);
|
|
1779
|
+
}
|
|
1780
|
+
function volumeIndex(close, volume, use) {
|
|
1781
|
+
const result = [];
|
|
1782
|
+
let prevIndex = NaN;
|
|
1783
|
+
for (let i = 0; i < close.length; i++) {
|
|
1784
|
+
const prev = !prevIndex ? 1 : prevIndex;
|
|
1785
|
+
const c = close[i];
|
|
1786
|
+
const prevC = i === 0 ? NaN : close[i - 1];
|
|
1787
|
+
let value = prev;
|
|
1788
|
+
if (c && prevC) {
|
|
1789
|
+
const prevV = i === 0 || Number.isNaN(volume[i - 1]) ? 0 : volume[i - 1];
|
|
1790
|
+
if (use(volume[i], prevV)) value = prev + (c - prevC) / prevC * prev;
|
|
1791
|
+
}
|
|
1792
|
+
result.push(value);
|
|
1793
|
+
prevIndex = value;
|
|
1794
|
+
}
|
|
1795
|
+
return result;
|
|
1796
|
+
}
|
|
1797
|
+
function nvi(close, volume) {
|
|
1798
|
+
return volumeIndex(close, volume, (v, prevV) => v < prevV);
|
|
1799
|
+
}
|
|
1800
|
+
function pvi(close, volume) {
|
|
1801
|
+
return volumeIndex(close, volume, (v, prevV) => v > prevV);
|
|
1802
|
+
}
|
|
1820
1803
|
|
|
1821
1804
|
// src/math/index.ts
|
|
1822
1805
|
var math_exports = {};
|
|
@@ -1851,6 +1834,38 @@ __export(math_exports, {
|
|
|
1851
1834
|
toradians: () => toradians
|
|
1852
1835
|
});
|
|
1853
1836
|
|
|
1837
|
+
// src/compare/index.ts
|
|
1838
|
+
var compare_exports = {};
|
|
1839
|
+
__export(compare_exports, {
|
|
1840
|
+
EPSILON: () => EPSILON,
|
|
1841
|
+
eq: () => eq,
|
|
1842
|
+
ge: () => ge,
|
|
1843
|
+
gt: () => gt,
|
|
1844
|
+
le: () => le,
|
|
1845
|
+
lt: () => lt,
|
|
1846
|
+
ne: () => ne
|
|
1847
|
+
});
|
|
1848
|
+
var EPSILON = 1e-10;
|
|
1849
|
+
var valid = (a, b2) => !Number.isNaN(a) && !Number.isNaN(b2);
|
|
1850
|
+
function eq(a, b2) {
|
|
1851
|
+
return valid(a, b2) && Math.abs(a - b2) <= EPSILON;
|
|
1852
|
+
}
|
|
1853
|
+
function ne(a, b2) {
|
|
1854
|
+
return valid(a, b2) && Math.abs(a - b2) > EPSILON;
|
|
1855
|
+
}
|
|
1856
|
+
function lt(a, b2) {
|
|
1857
|
+
return valid(a, b2) && b2 - a > EPSILON;
|
|
1858
|
+
}
|
|
1859
|
+
function le(a, b2) {
|
|
1860
|
+
return valid(a, b2) && a - b2 <= EPSILON;
|
|
1861
|
+
}
|
|
1862
|
+
function gt(a, b2) {
|
|
1863
|
+
return valid(a, b2) && a - b2 > EPSILON;
|
|
1864
|
+
}
|
|
1865
|
+
function ge(a, b2) {
|
|
1866
|
+
return valid(a, b2) && b2 - a <= EPSILON;
|
|
1867
|
+
}
|
|
1868
|
+
|
|
1854
1869
|
// src/runtime/series.ts
|
|
1855
1870
|
var BarData = class _BarData {
|
|
1856
1871
|
_bars;
|
|
@@ -1993,8 +2008,8 @@ var Series = class _Series {
|
|
|
1993
2008
|
* @param field - Field to extract ('open', 'high', 'low', 'close', 'volume')
|
|
1994
2009
|
* @returns Series with extracted field values
|
|
1995
2010
|
*/
|
|
1996
|
-
static fromBars(bars,
|
|
1997
|
-
return new _Series(bars, (bar) => bar[
|
|
2011
|
+
static fromBars(bars, field2) {
|
|
2012
|
+
return new _Series(bars, (bar) => bar[field2] ?? NaN);
|
|
1998
2013
|
}
|
|
1999
2014
|
/**
|
|
2000
2015
|
* Create a constant series (same value for all bars)
|
|
@@ -2011,8 +2026,8 @@ var Series = class _Series {
|
|
|
2011
2026
|
* @param values - Array of values
|
|
2012
2027
|
* @returns Series
|
|
2013
2028
|
*/
|
|
2014
|
-
static fromArray(bars,
|
|
2015
|
-
return new _Series(bars, (_bar, i) =>
|
|
2029
|
+
static fromArray(bars, values2) {
|
|
2030
|
+
return new _Series(bars, (_bar, i) => values2[i] ?? NaN);
|
|
2016
2031
|
}
|
|
2017
2032
|
// ============================================
|
|
2018
2033
|
// Arithmetic Operations
|
|
@@ -2099,7 +2114,7 @@ var Series = class _Series {
|
|
|
2099
2114
|
});
|
|
2100
2115
|
}
|
|
2101
2116
|
// ============================================
|
|
2102
|
-
// Comparison Operations
|
|
2117
|
+
// Comparison Operations (PineScript operators: tolerance 1e-10, false with na; see src/compare)
|
|
2103
2118
|
// ============================================
|
|
2104
2119
|
/**
|
|
2105
2120
|
* Greater than comparison
|
|
@@ -2110,7 +2125,7 @@ var Series = class _Series {
|
|
|
2110
2125
|
return new _Series(this.dataSource, (bar, i, data) => {
|
|
2111
2126
|
const a = this.extractor(bar, i, data);
|
|
2112
2127
|
const b2 = typeof other === "number" ? other : other.extractor(bar, i, data);
|
|
2113
|
-
return a
|
|
2128
|
+
return gt(a, b2) ? 1 : 0;
|
|
2114
2129
|
});
|
|
2115
2130
|
}
|
|
2116
2131
|
/**
|
|
@@ -2122,7 +2137,7 @@ var Series = class _Series {
|
|
|
2122
2137
|
return new _Series(this.dataSource, (bar, i, data) => {
|
|
2123
2138
|
const a = this.extractor(bar, i, data);
|
|
2124
2139
|
const b2 = typeof other === "number" ? other : other.extractor(bar, i, data);
|
|
2125
|
-
return a
|
|
2140
|
+
return ge(a, b2) ? 1 : 0;
|
|
2126
2141
|
});
|
|
2127
2142
|
}
|
|
2128
2143
|
/**
|
|
@@ -2134,7 +2149,7 @@ var Series = class _Series {
|
|
|
2134
2149
|
return new _Series(this.dataSource, (bar, i, data) => {
|
|
2135
2150
|
const a = this.extractor(bar, i, data);
|
|
2136
2151
|
const b2 = typeof other === "number" ? other : other.extractor(bar, i, data);
|
|
2137
|
-
return a
|
|
2152
|
+
return lt(a, b2) ? 1 : 0;
|
|
2138
2153
|
});
|
|
2139
2154
|
}
|
|
2140
2155
|
/**
|
|
@@ -2146,7 +2161,7 @@ var Series = class _Series {
|
|
|
2146
2161
|
return new _Series(this.dataSource, (bar, i, data) => {
|
|
2147
2162
|
const a = this.extractor(bar, i, data);
|
|
2148
2163
|
const b2 = typeof other === "number" ? other : other.extractor(bar, i, data);
|
|
2149
|
-
return a
|
|
2164
|
+
return le(a, b2) ? 1 : 0;
|
|
2150
2165
|
});
|
|
2151
2166
|
}
|
|
2152
2167
|
/**
|
|
@@ -2158,7 +2173,7 @@ var Series = class _Series {
|
|
|
2158
2173
|
return new _Series(this.dataSource, (bar, i, data) => {
|
|
2159
2174
|
const a = this.extractor(bar, i, data);
|
|
2160
2175
|
const b2 = typeof other === "number" ? other : other.extractor(bar, i, data);
|
|
2161
|
-
return a
|
|
2176
|
+
return eq(a, b2) ? 1 : 0;
|
|
2162
2177
|
});
|
|
2163
2178
|
}
|
|
2164
2179
|
/**
|
|
@@ -2170,7 +2185,7 @@ var Series = class _Series {
|
|
|
2170
2185
|
return new _Series(this.dataSource, (bar, i, data) => {
|
|
2171
2186
|
const a = this.extractor(bar, i, data);
|
|
2172
2187
|
const b2 = typeof other === "number" ? other : other.extractor(bar, i, data);
|
|
2173
|
-
return a
|
|
2188
|
+
return ne(a, b2) ? 1 : 0;
|
|
2174
2189
|
});
|
|
2175
2190
|
}
|
|
2176
2191
|
// ============================================
|
|
@@ -2302,8 +2317,8 @@ var Series = class _Series {
|
|
|
2302
2317
|
* @returns New Series with computed values and no closure dependencies
|
|
2303
2318
|
*/
|
|
2304
2319
|
materialize() {
|
|
2305
|
-
const
|
|
2306
|
-
const valuesCopy = [...
|
|
2320
|
+
const values2 = this.toArray();
|
|
2321
|
+
const valuesCopy = [...values2];
|
|
2307
2322
|
return _Series.fromArray(this.dataSource, valuesCopy);
|
|
2308
2323
|
}
|
|
2309
2324
|
/**
|
|
@@ -2333,16 +2348,16 @@ var Series = class _Series {
|
|
|
2333
2348
|
* @returns Value at that index
|
|
2334
2349
|
*/
|
|
2335
2350
|
get(index) {
|
|
2336
|
-
const
|
|
2337
|
-
return
|
|
2351
|
+
const values2 = this.toArray();
|
|
2352
|
+
return values2[index] ?? NaN;
|
|
2338
2353
|
}
|
|
2339
2354
|
/**
|
|
2340
2355
|
* Get the last value (most recent bar)
|
|
2341
2356
|
* @returns Most recent value
|
|
2342
2357
|
*/
|
|
2343
2358
|
last() {
|
|
2344
|
-
const
|
|
2345
|
-
return
|
|
2359
|
+
const values2 = this.toArray();
|
|
2360
|
+
return values2[values2.length - 1] ?? NaN;
|
|
2346
2361
|
}
|
|
2347
2362
|
/**
|
|
2348
2363
|
* Get number of values
|
|
@@ -2356,11 +2371,11 @@ var Series = class _Series {
|
|
|
2356
2371
|
* @returns Array of { time, value } objects
|
|
2357
2372
|
*/
|
|
2358
2373
|
toTimeValuePairs() {
|
|
2359
|
-
const
|
|
2374
|
+
const values2 = this.toArray();
|
|
2360
2375
|
const bars = this.dataSource.bars;
|
|
2361
2376
|
return bars.map((bar, i) => ({
|
|
2362
2377
|
time: bar.time,
|
|
2363
|
-
value:
|
|
2378
|
+
value: values2[i]
|
|
2364
2379
|
})).filter((point) => !Number.isNaN(point.value));
|
|
2365
2380
|
}
|
|
2366
2381
|
};
|
|
@@ -2434,60 +2449,60 @@ function round(value, precision) {
|
|
|
2434
2449
|
const multiplier = Math.pow(10, precision);
|
|
2435
2450
|
return Math.round(value * multiplier) / multiplier;
|
|
2436
2451
|
}
|
|
2437
|
-
function max2(...
|
|
2438
|
-
const hasSeries =
|
|
2452
|
+
function max2(...values2) {
|
|
2453
|
+
const hasSeries = values2.some((v) => v instanceof Series);
|
|
2439
2454
|
if (!hasSeries) {
|
|
2440
|
-
return Math.max(...
|
|
2455
|
+
return Math.max(...values2);
|
|
2441
2456
|
}
|
|
2442
|
-
const firstSeries =
|
|
2457
|
+
const firstSeries = values2.find((v) => v instanceof Series);
|
|
2443
2458
|
const bars = firstSeries.bars;
|
|
2444
2459
|
const length2 = bars.length;
|
|
2445
|
-
const valueArrays =
|
|
2460
|
+
const valueArrays = values2.map(
|
|
2446
2461
|
(v) => v instanceof Series ? v.toArray() : null
|
|
2447
2462
|
);
|
|
2448
2463
|
const result = [];
|
|
2449
2464
|
for (let i = 0; i < length2; i++) {
|
|
2450
|
-
const nums =
|
|
2465
|
+
const nums = values2.map(
|
|
2451
2466
|
(v, idx) => valueArrays[idx] ? valueArrays[idx][i] ?? NaN : v
|
|
2452
2467
|
);
|
|
2453
2468
|
result.push(Math.max(...nums));
|
|
2454
2469
|
}
|
|
2455
2470
|
return Series.fromArray(bars, result);
|
|
2456
2471
|
}
|
|
2457
|
-
function min2(...
|
|
2458
|
-
const hasSeries =
|
|
2472
|
+
function min2(...values2) {
|
|
2473
|
+
const hasSeries = values2.some((v) => v instanceof Series);
|
|
2459
2474
|
if (!hasSeries) {
|
|
2460
|
-
return Math.min(...
|
|
2475
|
+
return Math.min(...values2);
|
|
2461
2476
|
}
|
|
2462
|
-
const firstSeries =
|
|
2477
|
+
const firstSeries = values2.find((v) => v instanceof Series);
|
|
2463
2478
|
const bars = firstSeries.bars;
|
|
2464
2479
|
const length2 = bars.length;
|
|
2465
|
-
const valueArrays =
|
|
2480
|
+
const valueArrays = values2.map(
|
|
2466
2481
|
(v) => v instanceof Series ? v.toArray() : null
|
|
2467
2482
|
);
|
|
2468
2483
|
const result = [];
|
|
2469
2484
|
for (let i = 0; i < length2; i++) {
|
|
2470
|
-
const nums =
|
|
2485
|
+
const nums = values2.map(
|
|
2471
2486
|
(v, idx) => valueArrays[idx] ? valueArrays[idx][i] ?? NaN : v
|
|
2472
2487
|
);
|
|
2473
2488
|
result.push(Math.min(...nums));
|
|
2474
2489
|
}
|
|
2475
2490
|
return Series.fromArray(bars, result);
|
|
2476
2491
|
}
|
|
2477
|
-
function avg(...
|
|
2478
|
-
const hasSeries =
|
|
2492
|
+
function avg(...values2) {
|
|
2493
|
+
const hasSeries = values2.some((v) => v instanceof Series);
|
|
2479
2494
|
if (!hasSeries) {
|
|
2480
|
-
return
|
|
2495
|
+
return values2.reduce((a, b2) => a + b2, 0) / values2.length;
|
|
2481
2496
|
}
|
|
2482
|
-
const firstSeries =
|
|
2497
|
+
const firstSeries = values2.find((v) => v instanceof Series);
|
|
2483
2498
|
const bars = firstSeries.bars;
|
|
2484
2499
|
const length2 = bars.length;
|
|
2485
|
-
const valueArrays =
|
|
2500
|
+
const valueArrays = values2.map(
|
|
2486
2501
|
(v) => v instanceof Series ? v.toArray() : null
|
|
2487
2502
|
);
|
|
2488
2503
|
const result = [];
|
|
2489
2504
|
for (let i = 0; i < length2; i++) {
|
|
2490
|
-
const nums =
|
|
2505
|
+
const nums = values2.map(
|
|
2491
2506
|
(v, idx) => valueArrays[idx] ? valueArrays[idx][i] ?? NaN : v
|
|
2492
2507
|
);
|
|
2493
2508
|
const sum4 = nums.reduce((a, b2) => a + b2, 0);
|
|
@@ -2721,10 +2736,10 @@ function sign(value) {
|
|
|
2721
2736
|
}
|
|
2722
2737
|
return value > 0 ? 1 : value < 0 ? -1 : 0;
|
|
2723
2738
|
}
|
|
2724
|
-
function round_to_mintick(
|
|
2725
|
-
if (
|
|
2726
|
-
const bars =
|
|
2727
|
-
const valueArray =
|
|
2739
|
+
function round_to_mintick(number2, mintick) {
|
|
2740
|
+
if (number2 instanceof Series) {
|
|
2741
|
+
const bars = number2.bars;
|
|
2742
|
+
const valueArray = number2.toArray();
|
|
2728
2743
|
const length2 = bars.length;
|
|
2729
2744
|
if (mintick === void 0) {
|
|
2730
2745
|
throw new Error(
|
|
@@ -2748,7 +2763,7 @@ function round_to_mintick(number, mintick) {
|
|
|
2748
2763
|
}
|
|
2749
2764
|
return Series.fromArray(bars, result);
|
|
2750
2765
|
}
|
|
2751
|
-
if (isNaN(
|
|
2766
|
+
if (isNaN(number2)) {
|
|
2752
2767
|
return NaN;
|
|
2753
2768
|
}
|
|
2754
2769
|
if (mintick === void 0) {
|
|
@@ -2757,9 +2772,9 @@ function round_to_mintick(number, mintick) {
|
|
|
2757
2772
|
);
|
|
2758
2773
|
}
|
|
2759
2774
|
if (mintick === 0) {
|
|
2760
|
-
return
|
|
2775
|
+
return number2;
|
|
2761
2776
|
}
|
|
2762
|
-
return Math.round(
|
|
2777
|
+
return Math.round(number2 / mintick) * mintick;
|
|
2763
2778
|
}
|
|
2764
2779
|
var pi = Math.PI;
|
|
2765
2780
|
var e = Math.E;
|
|
@@ -2825,9 +2840,9 @@ __export(array_exports, {
|
|
|
2825
2840
|
unshift: () => unshift,
|
|
2826
2841
|
variance: () => variance2
|
|
2827
2842
|
});
|
|
2828
|
-
function new_array(
|
|
2843
|
+
function new_array(size3 = 0, initial_value) {
|
|
2829
2844
|
const arr = [];
|
|
2830
|
-
for (let i = 0; i <
|
|
2845
|
+
for (let i = 0; i < size3; i++) {
|
|
2831
2846
|
arr.push(initial_value);
|
|
2832
2847
|
}
|
|
2833
2848
|
return arr;
|
|
@@ -2901,11 +2916,13 @@ function sum2(id) {
|
|
|
2901
2916
|
function avg2(id) {
|
|
2902
2917
|
return sum2(id) / size(id);
|
|
2903
2918
|
}
|
|
2904
|
-
function min3(id) {
|
|
2905
|
-
|
|
2919
|
+
function min3(id, nth = 0) {
|
|
2920
|
+
const values2 = id.filter((v) => !Number.isNaN(v)).sort((a, b2) => a - b2);
|
|
2921
|
+
return values2.length ? values2[Math.min(nth, values2.length - 1)] : NaN;
|
|
2906
2922
|
}
|
|
2907
|
-
function max3(id) {
|
|
2908
|
-
|
|
2923
|
+
function max3(id, nth = 0) {
|
|
2924
|
+
const values2 = id.filter((v) => !Number.isNaN(v)).sort((a, b2) => b2 - a);
|
|
2925
|
+
return values2.length ? values2[Math.min(nth, values2.length - 1)] : NaN;
|
|
2909
2926
|
}
|
|
2910
2927
|
function median2(id) {
|
|
2911
2928
|
const sorted = [...id].sort((a, b2) => a - b2);
|
|
@@ -2926,16 +2943,15 @@ function mode2(id) {
|
|
|
2926
2943
|
}
|
|
2927
2944
|
return mode5;
|
|
2928
2945
|
}
|
|
2929
|
-
function stdev2(id) {
|
|
2930
|
-
|
|
2931
|
-
const squareDiffs = id.map((value) => Math.pow(value - mean, 2));
|
|
2932
|
-
const avgSquareDiff = sum2(squareDiffs) / size(id);
|
|
2933
|
-
return Math.sqrt(avgSquareDiff);
|
|
2946
|
+
function stdev2(id, biased = true) {
|
|
2947
|
+
return Math.sqrt(variance2(id, biased));
|
|
2934
2948
|
}
|
|
2935
|
-
function variance2(id) {
|
|
2936
|
-
const
|
|
2937
|
-
|
|
2938
|
-
|
|
2949
|
+
function variance2(id, biased = true) {
|
|
2950
|
+
const values2 = id.filter((v) => !Number.isNaN(v));
|
|
2951
|
+
if (!values2.length) return NaN;
|
|
2952
|
+
const mean = values2.reduce((a, b2) => a + b2, 0) / values2.length;
|
|
2953
|
+
const squares = values2.reduce((a, b2) => a + (b2 - mean) * (b2 - mean), 0);
|
|
2954
|
+
return squares / (biased ? values2.length : values2.length - 1);
|
|
2939
2955
|
}
|
|
2940
2956
|
function fill(id, value, index_from = 0, index_to) {
|
|
2941
2957
|
const end = index_to ?? id.length;
|
|
@@ -2943,8 +2959,8 @@ function fill(id, value, index_from = 0, index_to) {
|
|
|
2943
2959
|
id[i] = value;
|
|
2944
2960
|
}
|
|
2945
2961
|
}
|
|
2946
|
-
function from(
|
|
2947
|
-
return
|
|
2962
|
+
function from(...values2) {
|
|
2963
|
+
return [...values2];
|
|
2948
2964
|
}
|
|
2949
2965
|
function first(id) {
|
|
2950
2966
|
return id[0];
|
|
@@ -2952,38 +2968,38 @@ function first(id) {
|
|
|
2952
2968
|
function last(id) {
|
|
2953
2969
|
return id[id.length - 1];
|
|
2954
2970
|
}
|
|
2955
|
-
function some(id
|
|
2956
|
-
return id.some(
|
|
2971
|
+
function some(id) {
|
|
2972
|
+
return id.some((v) => v === true);
|
|
2957
2973
|
}
|
|
2958
|
-
function every(id
|
|
2959
|
-
return id.every(
|
|
2974
|
+
function every(id) {
|
|
2975
|
+
return id.length > 0 && id.every((v) => v === true);
|
|
2960
2976
|
}
|
|
2961
|
-
function new_bool(
|
|
2962
|
-
return new_array(
|
|
2977
|
+
function new_bool(size3 = 0, initial_value = false) {
|
|
2978
|
+
return new_array(size3, initial_value);
|
|
2963
2979
|
}
|
|
2964
|
-
function new_float(
|
|
2965
|
-
return new_array(
|
|
2980
|
+
function new_float(size3 = 0, initial_value = NaN) {
|
|
2981
|
+
return new_array(size3, initial_value);
|
|
2966
2982
|
}
|
|
2967
|
-
function new_int(
|
|
2968
|
-
return new_array(
|
|
2983
|
+
function new_int(size3 = 0, initial_value = NaN) {
|
|
2984
|
+
return new_array(size3, initial_value);
|
|
2969
2985
|
}
|
|
2970
|
-
function new_string(
|
|
2971
|
-
return new_array(
|
|
2986
|
+
function new_string(size3 = 0, initial_value) {
|
|
2987
|
+
return new_array(size3, initial_value);
|
|
2972
2988
|
}
|
|
2973
|
-
function new_color(
|
|
2974
|
-
return new_array(
|
|
2989
|
+
function new_color(size3 = 0, initial_value) {
|
|
2990
|
+
return new_array(size3, initial_value);
|
|
2975
2991
|
}
|
|
2976
|
-
function new_line(
|
|
2977
|
-
return new_array(
|
|
2992
|
+
function new_line(size3 = 0, initial_value) {
|
|
2993
|
+
return new_array(size3, initial_value);
|
|
2978
2994
|
}
|
|
2979
|
-
function new_box(
|
|
2980
|
-
return new_array(
|
|
2995
|
+
function new_box(size3 = 0, initial_value) {
|
|
2996
|
+
return new_array(size3, initial_value);
|
|
2981
2997
|
}
|
|
2982
|
-
function new_label(
|
|
2983
|
-
return new_array(
|
|
2998
|
+
function new_label(size3 = 0, initial_value) {
|
|
2999
|
+
return new_array(size3, initial_value);
|
|
2984
3000
|
}
|
|
2985
|
-
function new_linefill(
|
|
2986
|
-
return new_array(
|
|
3001
|
+
function new_linefill(size3 = 0, initial_value) {
|
|
3002
|
+
return new_array(size3, initial_value);
|
|
2987
3003
|
}
|
|
2988
3004
|
function abs2(id) {
|
|
2989
3005
|
return id.map((x) => Math.abs(x));
|
|
@@ -3123,8 +3139,70 @@ function standardize(id) {
|
|
|
3123
3139
|
}
|
|
3124
3140
|
return id.map((value) => (value - mean) / stdDev);
|
|
3125
3141
|
}
|
|
3126
|
-
function newtype(
|
|
3127
|
-
return new_array(
|
|
3142
|
+
function newtype(size3 = 0, initial_value) {
|
|
3143
|
+
return new_array(size3, initial_value);
|
|
3144
|
+
}
|
|
3145
|
+
|
|
3146
|
+
// src/map/index.ts
|
|
3147
|
+
var map_exports = {};
|
|
3148
|
+
__export(map_exports, {
|
|
3149
|
+
MAX_SIZE: () => MAX_SIZE,
|
|
3150
|
+
clear: () => clear2,
|
|
3151
|
+
contains: () => contains,
|
|
3152
|
+
copy: () => copy2,
|
|
3153
|
+
get: () => get2,
|
|
3154
|
+
keys: () => keys,
|
|
3155
|
+
new_map: () => new_map,
|
|
3156
|
+
put: () => put,
|
|
3157
|
+
put_all: () => put_all,
|
|
3158
|
+
remove: () => remove2,
|
|
3159
|
+
size: () => size2,
|
|
3160
|
+
values: () => values
|
|
3161
|
+
});
|
|
3162
|
+
var MAX_SIZE = 5e4;
|
|
3163
|
+
function tooLarge(size3) {
|
|
3164
|
+
return new RangeError(`A map cannot have more than ${MAX_SIZE} key-value pairs. The current size is ${size3}.`);
|
|
3165
|
+
}
|
|
3166
|
+
function new_map() {
|
|
3167
|
+
return /* @__PURE__ */ new Map();
|
|
3168
|
+
}
|
|
3169
|
+
function put(id, key, value) {
|
|
3170
|
+
const previous = id.get(key);
|
|
3171
|
+
if (!id.has(key) && id.size >= MAX_SIZE) throw tooLarge(id.size + 1);
|
|
3172
|
+
id.set(key, value);
|
|
3173
|
+
return previous;
|
|
3174
|
+
}
|
|
3175
|
+
function put_all(id, id2) {
|
|
3176
|
+
let size3 = id.size;
|
|
3177
|
+
for (const key of id2.keys()) if (!id.has(key)) size3++;
|
|
3178
|
+
if (size3 > MAX_SIZE) throw tooLarge(size3);
|
|
3179
|
+
for (const [key, value] of id2) id.set(key, value);
|
|
3180
|
+
}
|
|
3181
|
+
function get2(id, key) {
|
|
3182
|
+
return id.get(key);
|
|
3183
|
+
}
|
|
3184
|
+
function contains(id, key) {
|
|
3185
|
+
return id.has(key);
|
|
3186
|
+
}
|
|
3187
|
+
function remove2(id, key) {
|
|
3188
|
+
const value = id.get(key);
|
|
3189
|
+
id.delete(key);
|
|
3190
|
+
return value;
|
|
3191
|
+
}
|
|
3192
|
+
function size2(id) {
|
|
3193
|
+
return id.size;
|
|
3194
|
+
}
|
|
3195
|
+
function clear2(id) {
|
|
3196
|
+
id.clear();
|
|
3197
|
+
}
|
|
3198
|
+
function keys(id) {
|
|
3199
|
+
return [...id.keys()];
|
|
3200
|
+
}
|
|
3201
|
+
function values(id) {
|
|
3202
|
+
return [...id.values()];
|
|
3203
|
+
}
|
|
3204
|
+
function copy2(id) {
|
|
3205
|
+
return new Map(id);
|
|
3128
3206
|
}
|
|
3129
3207
|
|
|
3130
3208
|
// src/str/index.ts
|
|
@@ -3132,7 +3210,7 @@ var str_exports = {};
|
|
|
3132
3210
|
__export(str_exports, {
|
|
3133
3211
|
charAt: () => charAt,
|
|
3134
3212
|
concat: () => concat2,
|
|
3135
|
-
contains: () =>
|
|
3213
|
+
contains: () => contains2,
|
|
3136
3214
|
endswith: () => endswith,
|
|
3137
3215
|
format: () => format,
|
|
3138
3216
|
format_time: () => format_time,
|
|
@@ -3153,15 +3231,486 @@ __export(str_exports, {
|
|
|
3153
3231
|
trimRight: () => trimRight,
|
|
3154
3232
|
upper: () => upper
|
|
3155
3233
|
});
|
|
3234
|
+
|
|
3235
|
+
// src/str/numberformat.ts
|
|
3236
|
+
var patterns = /* @__PURE__ */ new Map();
|
|
3237
|
+
function parsePattern(pattern) {
|
|
3238
|
+
const cached = patterns.get(pattern);
|
|
3239
|
+
if (cached) return cached;
|
|
3240
|
+
let prefix = "";
|
|
3241
|
+
let suffix = "";
|
|
3242
|
+
let number2 = "";
|
|
3243
|
+
let percent = false;
|
|
3244
|
+
let phase = "prefix";
|
|
3245
|
+
for (let i = 0; i < pattern.length; i++) {
|
|
3246
|
+
const ch = pattern[i];
|
|
3247
|
+
let literal;
|
|
3248
|
+
if (ch === "'") {
|
|
3249
|
+
const end = pattern.indexOf("'", i + 1);
|
|
3250
|
+
if (end === i + 1) {
|
|
3251
|
+
literal = "'";
|
|
3252
|
+
i = end;
|
|
3253
|
+
} else {
|
|
3254
|
+
literal = pattern.slice(i + 1, end === -1 ? void 0 : end);
|
|
3255
|
+
i = end === -1 ? pattern.length : end;
|
|
3256
|
+
}
|
|
3257
|
+
} else if (phase !== "suffix" && ("#0,.".includes(ch) || phase === "number" && ch === "E")) {
|
|
3258
|
+
phase = "number";
|
|
3259
|
+
number2 += ch;
|
|
3260
|
+
continue;
|
|
3261
|
+
} else {
|
|
3262
|
+
if (ch === "%") percent = true;
|
|
3263
|
+
literal = ch;
|
|
3264
|
+
}
|
|
3265
|
+
if (phase === "number") phase = "suffix";
|
|
3266
|
+
if (phase === "prefix") prefix += literal;
|
|
3267
|
+
else suffix += literal;
|
|
3268
|
+
}
|
|
3269
|
+
const [mantissa = "", exp2] = number2.split("E");
|
|
3270
|
+
const [intPart = "", fracPart = ""] = mantissa.split(".");
|
|
3271
|
+
const lastComma = intPart.lastIndexOf(",");
|
|
3272
|
+
const parsed = {
|
|
3273
|
+
prefix,
|
|
3274
|
+
suffix,
|
|
3275
|
+
// as in Java, a pattern with a decimal point and no '0' at all ("#.##") shows one integer digit
|
|
3276
|
+
minInt: !mantissa.includes("0") && mantissa.includes(".") ? 1 : [...intPart].filter((c) => c === "0").length,
|
|
3277
|
+
minFrac: [...fracPart].filter((c) => c === "0").length,
|
|
3278
|
+
maxFrac: [...fracPart].filter((c) => c === "0" || c === "#").length,
|
|
3279
|
+
grouping: lastComma === -1 ? 0 : intPart.length - lastComma - 1,
|
|
3280
|
+
percent,
|
|
3281
|
+
exponent: exp2 === void 0 ? null : exp2.length,
|
|
3282
|
+
hasDigits: /[0#]/.test(mantissa)
|
|
3283
|
+
};
|
|
3284
|
+
patterns.set(pattern, parsed);
|
|
3285
|
+
return parsed;
|
|
3286
|
+
}
|
|
3287
|
+
function shortestDigits(x) {
|
|
3288
|
+
const m = /^(\d+)(?:\.(\d+))?(?:e([+-]\d+))?$/.exec(String(Math.abs(x)));
|
|
3289
|
+
const all7 = m[1] + (m[2] ?? "");
|
|
3290
|
+
let intLen = m[1].length + Number(m[3] ?? 0);
|
|
3291
|
+
const lead = all7.length - all7.replace(/^0+/, "").length;
|
|
3292
|
+
intLen -= lead;
|
|
3293
|
+
const digits = all7.slice(lead).replace(/0+$/, "");
|
|
3294
|
+
return { digits, intLen: digits ? intLen : 0 };
|
|
3295
|
+
}
|
|
3296
|
+
function exactDigits(x) {
|
|
3297
|
+
const abs3 = Math.abs(x);
|
|
3298
|
+
if (abs3 === 0) return { digits: "", intLen: 0 };
|
|
3299
|
+
const view = new DataView(new ArrayBuffer(8));
|
|
3300
|
+
view.setFloat64(0, abs3);
|
|
3301
|
+
const bits = view.getBigUint64(0);
|
|
3302
|
+
const expBits = Number(bits >> 52n & 0x7ffn);
|
|
3303
|
+
let mant = bits & 0xfffffffffffffn;
|
|
3304
|
+
const e2 = expBits === 0 ? -1074 : expBits - 1075;
|
|
3305
|
+
if (expBits !== 0) mant |= 1n << 52n;
|
|
3306
|
+
let str;
|
|
3307
|
+
let fracDigits;
|
|
3308
|
+
if (e2 >= 0) {
|
|
3309
|
+
str = (mant << BigInt(e2)).toString();
|
|
3310
|
+
fracDigits = 0;
|
|
3311
|
+
} else {
|
|
3312
|
+
str = (mant * 5n ** BigInt(-e2)).toString();
|
|
3313
|
+
fracDigits = -e2;
|
|
3314
|
+
}
|
|
3315
|
+
const intLen = str.length - fracDigits;
|
|
3316
|
+
const lead = str.length - str.replace(/^0+/, "").length;
|
|
3317
|
+
const digits = str.slice(lead).replace(/0+$/, "");
|
|
3318
|
+
return { digits, intLen: intLen - lead };
|
|
3319
|
+
}
|
|
3320
|
+
function roundDigits(d, frac, mode5) {
|
|
3321
|
+
const keep = d.intLen + frac;
|
|
3322
|
+
if (keep >= d.digits.length) return d;
|
|
3323
|
+
if (keep < 0) return { digits: "", intLen: 0 };
|
|
3324
|
+
const first2 = d.digits.charCodeAt(keep) - 48;
|
|
3325
|
+
let up;
|
|
3326
|
+
if (mode5 === "halfUpShortest") up = first2 >= 5;
|
|
3327
|
+
else if (first2 !== 5) up = first2 > 5;
|
|
3328
|
+
else if (d.digits.length > keep + 1) up = true;
|
|
3329
|
+
else up = keep > 0 && (d.digits.charCodeAt(keep - 1) - 48) % 2 === 1;
|
|
3330
|
+
let kept = d.digits.slice(0, keep);
|
|
3331
|
+
let intLen = d.intLen;
|
|
3332
|
+
if (up) {
|
|
3333
|
+
const n = (BigInt(kept || "0") + 1n).toString();
|
|
3334
|
+
if (n.length > kept.length) intLen += 1;
|
|
3335
|
+
kept = n;
|
|
3336
|
+
}
|
|
3337
|
+
kept = kept.replace(/0+$/, "");
|
|
3338
|
+
return { digits: kept, intLen: kept ? intLen : 0 };
|
|
3339
|
+
}
|
|
3340
|
+
function group(int, size3) {
|
|
3341
|
+
if (!size3 || int.length <= size3) return int;
|
|
3342
|
+
const parts = [];
|
|
3343
|
+
for (let end = int.length; end > 0; end -= size3) parts.unshift(int.slice(Math.max(0, end - size3), end));
|
|
3344
|
+
return parts.join(",");
|
|
3345
|
+
}
|
|
3346
|
+
function layout(d, p) {
|
|
3347
|
+
let int = d.intLen > 0 ? d.digits.slice(0, d.intLen).padEnd(d.intLen, "0") : "";
|
|
3348
|
+
int = int.replace(/^0+/, "").padStart(p.minInt, "0");
|
|
3349
|
+
let frac = d.intLen < 0 ? "0".repeat(-d.intLen) + d.digits : d.digits.slice(Math.max(0, d.intLen));
|
|
3350
|
+
frac = frac.slice(0, p.maxFrac).replace(/0+$/, "").padEnd(p.minFrac, "0");
|
|
3351
|
+
if (!int && !frac) int = "0";
|
|
3352
|
+
return group(int, p.grouping) + (frac ? "." + frac : "");
|
|
3353
|
+
}
|
|
3354
|
+
function formatNumber(value, pattern, mode5) {
|
|
3355
|
+
if (Number.isNaN(value)) return "NaN";
|
|
3356
|
+
const p = parsePattern(pattern);
|
|
3357
|
+
if (!Number.isFinite(value)) return (value < 0 ? "-" : "") + p.prefix + "\u221E" + p.suffix;
|
|
3358
|
+
const x = p.percent ? value * 100 : value;
|
|
3359
|
+
const toDigits = mode5 === "halfUpShortest" ? shortestDigits : exactDigits;
|
|
3360
|
+
let body;
|
|
3361
|
+
let isZero;
|
|
3362
|
+
if (p.exponent !== null) {
|
|
3363
|
+
const rounded = roundDigits(toDigits(x), p.maxFrac, mode5);
|
|
3364
|
+
const intDigits = Math.max(p.minInt, 1);
|
|
3365
|
+
isZero = rounded.digits === "";
|
|
3366
|
+
let exponent = isZero ? 0 : rounded.intLen - intDigits;
|
|
3367
|
+
let mant = roundDigits({ digits: rounded.digits, intLen: isZero ? 0 : intDigits }, p.maxFrac, mode5);
|
|
3368
|
+
if (mant.intLen > intDigits) {
|
|
3369
|
+
exponent += 1;
|
|
3370
|
+
mant = { digits: mant.digits, intLen: intDigits };
|
|
3371
|
+
}
|
|
3372
|
+
const e2 = String(Math.abs(exponent)).padStart(p.exponent, "0");
|
|
3373
|
+
body = layout(mant, p) + "E" + (exponent < 0 ? "-" : "") + e2;
|
|
3374
|
+
} else {
|
|
3375
|
+
const rounded = roundDigits(toDigits(x), p.hasDigits ? p.maxFrac : 0, mode5);
|
|
3376
|
+
isZero = rounded.digits === "";
|
|
3377
|
+
body = p.hasDigits ? layout(rounded, p) : layout(rounded, { ...p, minInt: 0, maxFrac: 0, minFrac: 0 });
|
|
3378
|
+
}
|
|
3379
|
+
const negative = x < 0 && (!isZero || !p.hasDigits);
|
|
3380
|
+
return (negative ? "-" : "") + p.prefix + body + p.suffix;
|
|
3381
|
+
}
|
|
3382
|
+
|
|
3383
|
+
// src/time/timezone.ts
|
|
3384
|
+
var MS_PER_SECOND = 1e3;
|
|
3385
|
+
var MS_PER_DAY = 864e5;
|
|
3386
|
+
var MAX_OFFSET_SECONDS = 18 * 3600;
|
|
3387
|
+
var OFFSET_NOTATION = /^(?:UTC|GMT)(?:([+-])(\d{1,2})(?::?(\d{2})(?::?(\d{2}))?)?)?$/;
|
|
3388
|
+
var REJECTED_NAMES = /* @__PURE__ */ new Set(["EST", "MST", "HST"]);
|
|
3389
|
+
var canonicalNames;
|
|
3390
|
+
function hasTimeZoneCase(name) {
|
|
3391
|
+
if (name.split("/").some((segment) => !/^[A-Z]/.test(segment))) return false;
|
|
3392
|
+
canonicalNames ??= new Map(Intl.supportedValuesOf("timeZone").map((n) => [n.toLowerCase(), n]));
|
|
3393
|
+
const canonical = canonicalNames.get(name.toLowerCase());
|
|
3394
|
+
return canonical === void 0 || canonical === name;
|
|
3395
|
+
}
|
|
3396
|
+
var zones = /* @__PURE__ */ new Map();
|
|
3397
|
+
function resolveZone(timezone) {
|
|
3398
|
+
let zone = zones.get(timezone);
|
|
3399
|
+
if (zone) return zone;
|
|
3400
|
+
const invalid = () => new RangeError(
|
|
3401
|
+
`Invalid time zone "${timezone}": use UTC/GMT offset notation ("UTC-5", "GMT+0530") or an IANA name ("America/New_York")`
|
|
3402
|
+
);
|
|
3403
|
+
const m = OFFSET_NOTATION.exec(timezone);
|
|
3404
|
+
if (m) {
|
|
3405
|
+
const [, sign2, h = "0", mi = "0", s] = m;
|
|
3406
|
+
const minutes = Number(mi);
|
|
3407
|
+
const seconds = s === void 0 ? 0 : Number(s);
|
|
3408
|
+
if (minutes > 59 || seconds > 59 || s !== void 0 && h.length !== 2) throw invalid();
|
|
3409
|
+
const offsetSeconds = Number(h) * 3600 + minutes * 60 + seconds;
|
|
3410
|
+
if (offsetSeconds > MAX_OFFSET_SECONDS) throw invalid();
|
|
3411
|
+
zone = { kind: "fixed", offsetMs: (sign2 === "-" ? -offsetSeconds : offsetSeconds) * MS_PER_SECOND };
|
|
3412
|
+
} else {
|
|
3413
|
+
if (REJECTED_NAMES.has(timezone) || !hasTimeZoneCase(timezone)) throw invalid();
|
|
3414
|
+
let format2;
|
|
3415
|
+
try {
|
|
3416
|
+
format2 = new Intl.DateTimeFormat("en-US", {
|
|
3417
|
+
timeZone: timezone,
|
|
3418
|
+
hourCycle: "h23",
|
|
3419
|
+
year: "numeric",
|
|
3420
|
+
month: "numeric",
|
|
3421
|
+
day: "numeric",
|
|
3422
|
+
hour: "numeric",
|
|
3423
|
+
minute: "numeric",
|
|
3424
|
+
second: "numeric"
|
|
3425
|
+
});
|
|
3426
|
+
} catch {
|
|
3427
|
+
throw invalid();
|
|
3428
|
+
}
|
|
3429
|
+
zone = { kind: "iana", format: format2 };
|
|
3430
|
+
}
|
|
3431
|
+
zones.set(timezone, zone);
|
|
3432
|
+
return zone;
|
|
3433
|
+
}
|
|
3434
|
+
function offsetAt(zone, time) {
|
|
3435
|
+
if (zone.kind === "fixed") return zone.offsetMs;
|
|
3436
|
+
const wholeSecond = Math.floor(time / 1e3) * 1e3;
|
|
3437
|
+
const f = {};
|
|
3438
|
+
for (const part of zone.format.formatToParts(wholeSecond)) {
|
|
3439
|
+
if (part.type !== "literal") f[part.type] = Number(part.value);
|
|
3440
|
+
}
|
|
3441
|
+
const local = Date.UTC(f.year, f.month - 1, f.day, f.hour, f.minute, f.second);
|
|
3442
|
+
return local - wholeSecond;
|
|
3443
|
+
}
|
|
3444
|
+
function zoneOffset(time, timezone) {
|
|
3445
|
+
return offsetAt(resolveZone(timezone), time);
|
|
3446
|
+
}
|
|
3447
|
+
function zonedFields(time, timezone) {
|
|
3448
|
+
const local = new Date(time + offsetAt(resolveZone(timezone), time));
|
|
3449
|
+
return {
|
|
3450
|
+
year: local.getUTCFullYear(),
|
|
3451
|
+
month: local.getUTCMonth() + 1,
|
|
3452
|
+
day: local.getUTCDate(),
|
|
3453
|
+
hour: local.getUTCHours(),
|
|
3454
|
+
minute: local.getUTCMinutes(),
|
|
3455
|
+
second: local.getUTCSeconds(),
|
|
3456
|
+
dayOfWeek: local.getUTCDay() + 1
|
|
3457
|
+
};
|
|
3458
|
+
}
|
|
3459
|
+
function zonedToUnix(timezone, year2, month2, day, hour2 = 0, minute2 = 0, second2 = 0) {
|
|
3460
|
+
const zone = resolveZone(timezone);
|
|
3461
|
+
const local = Date.UTC(year2, month2 - 1, day, hour2, minute2, second2);
|
|
3462
|
+
if (zone.kind === "fixed") return local - zone.offsetMs;
|
|
3463
|
+
const before = offsetAt(zone, local - MS_PER_DAY);
|
|
3464
|
+
const after = offsetAt(zone, local + MS_PER_DAY);
|
|
3465
|
+
const candidates = [local - before, local - after].filter((t2) => local - offsetAt(zone, t2) === t2);
|
|
3466
|
+
if (candidates.length) return Math.max(...candidates);
|
|
3467
|
+
return local - before;
|
|
3468
|
+
}
|
|
3469
|
+
|
|
3470
|
+
// src/str/dateformat.ts
|
|
3471
|
+
var MONTHS = [
|
|
3472
|
+
"January",
|
|
3473
|
+
"February",
|
|
3474
|
+
"March",
|
|
3475
|
+
"April",
|
|
3476
|
+
"May",
|
|
3477
|
+
"June",
|
|
3478
|
+
"July",
|
|
3479
|
+
"August",
|
|
3480
|
+
"September",
|
|
3481
|
+
"October",
|
|
3482
|
+
"November",
|
|
3483
|
+
"December"
|
|
3484
|
+
];
|
|
3485
|
+
var DAYS = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"];
|
|
3486
|
+
var pad = (n, width) => String(n).padStart(width, "0");
|
|
3487
|
+
function zoneName(time, timezone, offsetMs) {
|
|
3488
|
+
if (timezone === "Etc/UTC") return "UTC";
|
|
3489
|
+
if (/^(UTC|GMT)/.test(timezone)) {
|
|
3490
|
+
if (offsetMs === 0) return "GMT";
|
|
3491
|
+
const minutes = Math.abs(offsetMs) / 6e4;
|
|
3492
|
+
return `GMT${offsetMs < 0 ? "-" : "+"}${pad(Math.floor(minutes / 60), 2)}:${pad(minutes % 60, 2)}`;
|
|
3493
|
+
}
|
|
3494
|
+
const part = new Intl.DateTimeFormat("en-US", { timeZone: timezone, timeZoneName: "short" }).formatToParts(time).find((p) => p.type === "timeZoneName");
|
|
3495
|
+
return part?.value ?? timezone;
|
|
3496
|
+
}
|
|
3497
|
+
function weekOfYear(year2, month2, day) {
|
|
3498
|
+
const date = Date.UTC(year2, month2 - 1, day);
|
|
3499
|
+
const dow = new Date(date).getUTCDay();
|
|
3500
|
+
const weekStart = date - dow * 864e5;
|
|
3501
|
+
if (weekStart + 6 * 864e5 >= Date.UTC(year2 + 1, 0, 1)) return 1;
|
|
3502
|
+
const jan1 = Date.UTC(year2, 0, 1);
|
|
3503
|
+
const jan1Dow = new Date(jan1).getUTCDay();
|
|
3504
|
+
return Math.floor((date - jan1 + jan1Dow * 864e5) / (7 * 864e5)) + 1;
|
|
3505
|
+
}
|
|
3506
|
+
function formatDate(time, pattern, timezone) {
|
|
3507
|
+
if (Number.isNaN(time)) return "NaN";
|
|
3508
|
+
const f = zonedFields(time, timezone);
|
|
3509
|
+
const offset = zoneOffset(time, timezone);
|
|
3510
|
+
const ms = (time % 1e3 + 1e3) % 1e3;
|
|
3511
|
+
const dayOfYear = (Date.UTC(f.year, f.month - 1, f.day) - Date.UTC(f.year, 0, 1)) / 864e5 + 1;
|
|
3512
|
+
let out = "";
|
|
3513
|
+
for (let i = 0; i < pattern.length; ) {
|
|
3514
|
+
const ch = pattern[i];
|
|
3515
|
+
if (ch === "'") {
|
|
3516
|
+
const end = pattern.indexOf("'", i + 1);
|
|
3517
|
+
if (end === i + 1) {
|
|
3518
|
+
out += "'";
|
|
3519
|
+
i += 2;
|
|
3520
|
+
} else {
|
|
3521
|
+
out += pattern.slice(i + 1, end === -1 ? void 0 : end);
|
|
3522
|
+
i = end === -1 ? pattern.length : end + 1;
|
|
3523
|
+
}
|
|
3524
|
+
continue;
|
|
3525
|
+
}
|
|
3526
|
+
if (!/[A-Za-z]/.test(ch)) {
|
|
3527
|
+
out += ch;
|
|
3528
|
+
i++;
|
|
3529
|
+
continue;
|
|
3530
|
+
}
|
|
3531
|
+
let n = 1;
|
|
3532
|
+
while (pattern[i + n] === ch) n++;
|
|
3533
|
+
i += n;
|
|
3534
|
+
const hour12 = f.hour % 12;
|
|
3535
|
+
switch (ch) {
|
|
3536
|
+
case "y":
|
|
3537
|
+
out += n === 2 ? pad(f.year % 100, 2) : pad(f.year, n);
|
|
3538
|
+
break;
|
|
3539
|
+
case "M":
|
|
3540
|
+
out += n >= 4 ? MONTHS[f.month - 1] : n === 3 ? MONTHS[f.month - 1].slice(0, 3) : pad(f.month, n);
|
|
3541
|
+
break;
|
|
3542
|
+
case "d":
|
|
3543
|
+
out += pad(f.day, n);
|
|
3544
|
+
break;
|
|
3545
|
+
case "E":
|
|
3546
|
+
out += n >= 4 ? DAYS[f.dayOfWeek - 1] : DAYS[f.dayOfWeek - 1].slice(0, 3);
|
|
3547
|
+
break;
|
|
3548
|
+
case "u":
|
|
3549
|
+
out += pad(f.dayOfWeek === 1 ? 7 : f.dayOfWeek - 1, n);
|
|
3550
|
+
break;
|
|
3551
|
+
case "D":
|
|
3552
|
+
out += pad(dayOfYear, n);
|
|
3553
|
+
break;
|
|
3554
|
+
case "w":
|
|
3555
|
+
out += pad(weekOfYear(f.year, f.month, f.day), n);
|
|
3556
|
+
break;
|
|
3557
|
+
case "H":
|
|
3558
|
+
out += pad(f.hour, n);
|
|
3559
|
+
break;
|
|
3560
|
+
case "k":
|
|
3561
|
+
out += pad(f.hour === 0 ? 24 : f.hour, n);
|
|
3562
|
+
break;
|
|
3563
|
+
case "K":
|
|
3564
|
+
out += pad(hour12, n);
|
|
3565
|
+
break;
|
|
3566
|
+
case "h":
|
|
3567
|
+
out += pad(hour12 === 0 ? 12 : hour12, n);
|
|
3568
|
+
break;
|
|
3569
|
+
case "a":
|
|
3570
|
+
out += f.hour < 12 ? "AM" : "PM";
|
|
3571
|
+
break;
|
|
3572
|
+
case "m":
|
|
3573
|
+
out += pad(f.minute, n);
|
|
3574
|
+
break;
|
|
3575
|
+
case "s":
|
|
3576
|
+
out += pad(f.second, n);
|
|
3577
|
+
break;
|
|
3578
|
+
case "S":
|
|
3579
|
+
out += pad(ms, n);
|
|
3580
|
+
break;
|
|
3581
|
+
case "Z": {
|
|
3582
|
+
const minutes = Math.abs(offset) / 6e4;
|
|
3583
|
+
out += (offset < 0 ? "-" : "+") + pad(Math.floor(minutes / 60), 2) + pad(minutes % 60, 2);
|
|
3584
|
+
break;
|
|
3585
|
+
}
|
|
3586
|
+
case "z":
|
|
3587
|
+
out += zoneName(time, timezone, offset);
|
|
3588
|
+
break;
|
|
3589
|
+
default:
|
|
3590
|
+
throw new SyntaxError(`Unsupported date pattern letter "${ch}" in "${pattern}"`);
|
|
3591
|
+
}
|
|
3592
|
+
}
|
|
3593
|
+
return out;
|
|
3594
|
+
}
|
|
3595
|
+
|
|
3596
|
+
// src/str/messageformat.ts
|
|
3597
|
+
var DATE_STYLES = {
|
|
3598
|
+
short: "M/d/yy",
|
|
3599
|
+
medium: "MMM d, yyyy",
|
|
3600
|
+
long: "MMMM d, yyyy",
|
|
3601
|
+
full: "EEEE, MMMM d, yyyy"
|
|
3602
|
+
};
|
|
3603
|
+
var TIME_STYLES = {
|
|
3604
|
+
short: "h:mm\u202Fa",
|
|
3605
|
+
medium: "h:mm:ss\u202Fa",
|
|
3606
|
+
long: "h:mm:ss\u202Fa z",
|
|
3607
|
+
full: "h:mm:ss\u202Fa z"
|
|
3608
|
+
};
|
|
3609
|
+
function number(value, pattern) {
|
|
3610
|
+
return typeof value === "number" ? formatNumber(value, pattern, "halfEvenExact") : String(value);
|
|
3611
|
+
}
|
|
3612
|
+
function choice(value, spec) {
|
|
3613
|
+
const options = spec.split("|").map((part) => {
|
|
3614
|
+
const m = /^\s*(-?[\d.]+|-?∞)\s*([#<≤])(.*)$/.exec(part);
|
|
3615
|
+
if (!m) throw new SyntaxError(`Invalid choice format "${spec}"`);
|
|
3616
|
+
const limit = m[1].includes("\u221E") ? m[1].startsWith("-") ? -Infinity : Infinity : Number(m[1]);
|
|
3617
|
+
return { limit: m[2] === "<" ? limit + Number.EPSILON * Math.max(1, Math.abs(limit)) : limit, text: m[3] };
|
|
3618
|
+
});
|
|
3619
|
+
let chosen = options[0];
|
|
3620
|
+
for (const o of options) if (value >= o.limit) chosen = o;
|
|
3621
|
+
return chosen.text;
|
|
3622
|
+
}
|
|
3623
|
+
function formatArgument(value, type, style, timezone) {
|
|
3624
|
+
if (value === void 0) return "";
|
|
3625
|
+
if (!type) return typeof value === "number" ? number(value, "#,##0.###") : String(value);
|
|
3626
|
+
switch (type.trim()) {
|
|
3627
|
+
case "number": {
|
|
3628
|
+
const s = style?.trim();
|
|
3629
|
+
if (!s) return number(value, "#,##0.###");
|
|
3630
|
+
if (s === "integer") return number(value, "#,##0");
|
|
3631
|
+
if (s === "percent") return number(value, "#,##0%");
|
|
3632
|
+
if (s === "currency") return number(value, "'$'#,##0.00");
|
|
3633
|
+
return number(value, style);
|
|
3634
|
+
}
|
|
3635
|
+
case "date":
|
|
3636
|
+
case "time": {
|
|
3637
|
+
const styles = type.trim() === "date" ? DATE_STYLES : TIME_STYLES;
|
|
3638
|
+
const s = style?.trim() ?? "medium";
|
|
3639
|
+
return formatDate(Number(value), styles[s] ?? style, typeof timezone === "function" ? timezone() : timezone);
|
|
3640
|
+
}
|
|
3641
|
+
case "choice":
|
|
3642
|
+
return choice(Number(value), style ?? "");
|
|
3643
|
+
default:
|
|
3644
|
+
throw new SyntaxError(`Unknown format type "${type}"`);
|
|
3645
|
+
}
|
|
3646
|
+
}
|
|
3647
|
+
function formatMessage(pattern, args, timezone) {
|
|
3648
|
+
let out = "";
|
|
3649
|
+
for (let i = 0; i < pattern.length; ) {
|
|
3650
|
+
const ch = pattern[i];
|
|
3651
|
+
if (ch === "'") {
|
|
3652
|
+
if (pattern[i + 1] === "'") {
|
|
3653
|
+
out += "'";
|
|
3654
|
+
i += 2;
|
|
3655
|
+
continue;
|
|
3656
|
+
}
|
|
3657
|
+
const end = pattern.indexOf("'", i + 1);
|
|
3658
|
+
out += pattern.slice(i + 1, end === -1 ? void 0 : end);
|
|
3659
|
+
i = end === -1 ? pattern.length : end + 1;
|
|
3660
|
+
continue;
|
|
3661
|
+
}
|
|
3662
|
+
if (ch !== "{") {
|
|
3663
|
+
out += ch;
|
|
3664
|
+
i++;
|
|
3665
|
+
continue;
|
|
3666
|
+
}
|
|
3667
|
+
let depth = 1;
|
|
3668
|
+
let j = i + 1;
|
|
3669
|
+
let inQuote = false;
|
|
3670
|
+
for (; j < pattern.length && depth > 0; j++) {
|
|
3671
|
+
const c = pattern[j];
|
|
3672
|
+
if (c === "'") inQuote = !inQuote;
|
|
3673
|
+
else if (!inQuote && c === "{") depth++;
|
|
3674
|
+
else if (!inQuote && c === "}") depth--;
|
|
3675
|
+
}
|
|
3676
|
+
const inner = pattern.slice(i + 1, j - 1);
|
|
3677
|
+
const [index = "", type, ...rest] = inner.split(",");
|
|
3678
|
+
const style = rest.length ? rest.join(",") : void 0;
|
|
3679
|
+
const n = Number(index.trim());
|
|
3680
|
+
out += n < args.length ? formatArgument(args[n], type, style, timezone) : `{${inner}}`;
|
|
3681
|
+
i = j;
|
|
3682
|
+
}
|
|
3683
|
+
return out;
|
|
3684
|
+
}
|
|
3685
|
+
|
|
3686
|
+
// src/str/index.ts
|
|
3156
3687
|
function length(str) {
|
|
3157
3688
|
return str.length;
|
|
3158
3689
|
}
|
|
3159
3690
|
function tostring(value, format2) {
|
|
3160
|
-
if (typeof value
|
|
3161
|
-
|
|
3162
|
-
|
|
3691
|
+
if (typeof value !== "number") return String(value);
|
|
3692
|
+
if (!Number.isFinite(value)) return String(value);
|
|
3693
|
+
if (format2 === void 0 || format2 === "") {
|
|
3694
|
+
if (Math.abs(value) >= 1e21 && Number.isFinite(value)) {
|
|
3695
|
+
return String(value).replace("e+", "E").replace(/\.0+E/, "E");
|
|
3696
|
+
}
|
|
3697
|
+
return formatNumber(value, "#.##########", "halfUpShortest");
|
|
3698
|
+
}
|
|
3699
|
+
switch (format2) {
|
|
3700
|
+
case "percent":
|
|
3701
|
+
return formatNumber(value, "0.00", "halfUpShortest") + "%";
|
|
3702
|
+
case "volume": {
|
|
3703
|
+
const abs3 = Math.abs(value);
|
|
3704
|
+
for (const [size3, unit] of [[1e12, "T"], [1e9, "B"], [1e6, "M"], [1e3, "K"]]) {
|
|
3705
|
+
if (abs3 >= size3) return formatNumber(value / size3, "#.###", "halfUpShortest") + unit;
|
|
3706
|
+
}
|
|
3707
|
+
return formatNumber(value, "#", "halfUpShortest");
|
|
3708
|
+
}
|
|
3709
|
+
case "mintick":
|
|
3710
|
+
throw new Error("str.tostring(x, format.mintick) needs the symbol tick size (syminfo.mintick), which is not known here");
|
|
3711
|
+
default:
|
|
3712
|
+
return formatNumber(value, format2, "halfUpShortest");
|
|
3163
3713
|
}
|
|
3164
|
-
return String(value);
|
|
3165
3714
|
}
|
|
3166
3715
|
function tonumber(str) {
|
|
3167
3716
|
const num = parseFloat(str);
|
|
@@ -3176,7 +3725,7 @@ function upper(str) {
|
|
|
3176
3725
|
function lower(str) {
|
|
3177
3726
|
return str.toLowerCase();
|
|
3178
3727
|
}
|
|
3179
|
-
function
|
|
3728
|
+
function contains2(source, str) {
|
|
3180
3729
|
return source.includes(str);
|
|
3181
3730
|
}
|
|
3182
3731
|
function pos(source, str) {
|
|
@@ -3199,11 +3748,7 @@ function concat2(...strings) {
|
|
|
3199
3748
|
return strings.join("");
|
|
3200
3749
|
}
|
|
3201
3750
|
function format(formatStr, ...args) {
|
|
3202
|
-
|
|
3203
|
-
args.forEach((arg, index) => {
|
|
3204
|
-
result = result.replaceAll(`{${index}}`, String(arg));
|
|
3205
|
-
});
|
|
3206
|
-
return result;
|
|
3751
|
+
return formatMessage(formatStr, args, "Etc/UTC");
|
|
3207
3752
|
}
|
|
3208
3753
|
function startswith(source, str) {
|
|
3209
3754
|
return source.startsWith(str);
|
|
@@ -3231,84 +3776,8 @@ function repeat(source, count, separator = "") {
|
|
|
3231
3776
|
if (count <= 0) return "";
|
|
3232
3777
|
return Array(count).fill(source).join(separator);
|
|
3233
3778
|
}
|
|
3234
|
-
function format_time(time, format2) {
|
|
3235
|
-
|
|
3236
|
-
const monthNames = [
|
|
3237
|
-
"January",
|
|
3238
|
-
"February",
|
|
3239
|
-
"March",
|
|
3240
|
-
"April",
|
|
3241
|
-
"May",
|
|
3242
|
-
"June",
|
|
3243
|
-
"July",
|
|
3244
|
-
"August",
|
|
3245
|
-
"September",
|
|
3246
|
-
"October",
|
|
3247
|
-
"November",
|
|
3248
|
-
"December"
|
|
3249
|
-
];
|
|
3250
|
-
const monthNamesShort = [
|
|
3251
|
-
"Jan",
|
|
3252
|
-
"Feb",
|
|
3253
|
-
"Mar",
|
|
3254
|
-
"Apr",
|
|
3255
|
-
"May",
|
|
3256
|
-
"Jun",
|
|
3257
|
-
"Jul",
|
|
3258
|
-
"Aug",
|
|
3259
|
-
"Sep",
|
|
3260
|
-
"Oct",
|
|
3261
|
-
"Nov",
|
|
3262
|
-
"Dec"
|
|
3263
|
-
];
|
|
3264
|
-
const year = date.getUTCFullYear();
|
|
3265
|
-
const month = date.getUTCMonth();
|
|
3266
|
-
const day = date.getUTCDate();
|
|
3267
|
-
const hours = date.getUTCHours();
|
|
3268
|
-
const minutes = date.getUTCMinutes();
|
|
3269
|
-
const seconds = date.getUTCSeconds();
|
|
3270
|
-
const pad = (num, len = 2) => num.toString().padStart(len, "0");
|
|
3271
|
-
const hours12 = hours % 12 || 12;
|
|
3272
|
-
const ampm = hours < 12 ? "AM" : "PM";
|
|
3273
|
-
const replacements = [
|
|
3274
|
-
// Year (process yyyy before yy)
|
|
3275
|
-
[/yyyy/g, year.toString()],
|
|
3276
|
-
[/yy/g, year.toString().slice(-2)],
|
|
3277
|
-
// Month (process MMMM before MMM before MM before M)
|
|
3278
|
-
[/MMMM/g, monthNames[month]],
|
|
3279
|
-
[/MMM/g, monthNamesShort[month]],
|
|
3280
|
-
[/MM/g, pad(month + 1)],
|
|
3281
|
-
[/M/g, (month + 1).toString()],
|
|
3282
|
-
// Day (process dd before d)
|
|
3283
|
-
[/dd/g, pad(day)],
|
|
3284
|
-
[/d/g, day.toString()],
|
|
3285
|
-
// Hours 24-hour (process HH before H)
|
|
3286
|
-
[/HH/g, pad(hours)],
|
|
3287
|
-
[/H/g, hours.toString()],
|
|
3288
|
-
// Hours 12-hour (process hh before h)
|
|
3289
|
-
[/hh/g, pad(hours12)],
|
|
3290
|
-
[/h/g, hours12.toString()],
|
|
3291
|
-
// Minutes (process mm before m)
|
|
3292
|
-
[/mm/g, pad(minutes)],
|
|
3293
|
-
[/m/g, minutes.toString()],
|
|
3294
|
-
// Seconds (process ss before s)
|
|
3295
|
-
[/ss/g, pad(seconds)],
|
|
3296
|
-
[/s/g, seconds.toString()],
|
|
3297
|
-
// AM/PM
|
|
3298
|
-
[/a/g, ampm]
|
|
3299
|
-
];
|
|
3300
|
-
let result = format2;
|
|
3301
|
-
const tokens = [];
|
|
3302
|
-
replacements.forEach(([pattern, value], index) => {
|
|
3303
|
-
const token = `\uFFF0${index}\uFFF1`;
|
|
3304
|
-
result = result.replace(pattern, token);
|
|
3305
|
-
tokens[index] = value;
|
|
3306
|
-
});
|
|
3307
|
-
tokens.forEach((value, index) => {
|
|
3308
|
-
const token = `\uFFF0${index}\uFFF1`;
|
|
3309
|
-
result = result.replaceAll(token, value);
|
|
3310
|
-
});
|
|
3311
|
-
return result;
|
|
3779
|
+
function format_time(time, format2 = "yyyy-MM-dd'T'HH:mm:ssZ", timezone = "Etc/UTC") {
|
|
3780
|
+
return formatDate(time, format2, timezone);
|
|
3312
3781
|
}
|
|
3313
3782
|
|
|
3314
3783
|
// src/color/index.ts
|
|
@@ -3376,6 +3845,13 @@ function t(clr) {
|
|
|
3376
3845
|
}
|
|
3377
3846
|
function parseColor(clr) {
|
|
3378
3847
|
if (typeof clr === "string") {
|
|
3848
|
+
const hex = /^#([0-9a-f]{3,4}|[0-9a-f]{6}|[0-9a-f]{8})$/i.exec(clr.trim());
|
|
3849
|
+
if (hex) {
|
|
3850
|
+
let digits = hex[1];
|
|
3851
|
+
if (digits.length <= 4) digits = [...digits].map((c) => c + c).join("");
|
|
3852
|
+
const byte = (k) => parseInt(digits.slice(k, k + 2), 16);
|
|
3853
|
+
return { r: byte(0), g: byte(2), b: byte(4), t: digits.length === 8 ? (1 - byte(6) / 255) * 100 : 0 };
|
|
3854
|
+
}
|
|
3379
3855
|
const match2 = clr.match(/rgba?\((\d+),\s*(\d+),\s*(\d+)(?:,\s*([\d.]+))?\)/);
|
|
3380
3856
|
if (match2) {
|
|
3381
3857
|
return {
|
|
@@ -3388,34 +3864,34 @@ function parseColor(clr) {
|
|
|
3388
3864
|
}
|
|
3389
3865
|
return { r: 0, g: 0, b: 0, t: 0 };
|
|
3390
3866
|
}
|
|
3391
|
-
var aqua = "#
|
|
3392
|
-
var black = "#
|
|
3393
|
-
var blue = "#
|
|
3394
|
-
var fuchsia = "#
|
|
3395
|
-
var gray = "#
|
|
3396
|
-
var green = "#
|
|
3397
|
-
var lime = "#
|
|
3398
|
-
var maroon = "#
|
|
3399
|
-
var navy = "#
|
|
3867
|
+
var aqua = "#00BCD4";
|
|
3868
|
+
var black = "#363A45";
|
|
3869
|
+
var blue = "#2962FF";
|
|
3870
|
+
var fuchsia = "#E040FB";
|
|
3871
|
+
var gray = "#787B86";
|
|
3872
|
+
var green = "#4CAF50";
|
|
3873
|
+
var lime = "#00E676";
|
|
3874
|
+
var maroon = "#880E4F";
|
|
3875
|
+
var navy = "#311B92";
|
|
3400
3876
|
var olive = "#808000";
|
|
3401
|
-
var orange = "#
|
|
3402
|
-
var purple = "#
|
|
3403
|
-
var red = "#
|
|
3404
|
-
var silver = "#
|
|
3405
|
-
var teal = "#
|
|
3877
|
+
var orange = "#FF9800";
|
|
3878
|
+
var purple = "#9C27B0";
|
|
3879
|
+
var red = "#F23645";
|
|
3880
|
+
var silver = "#B2B5BE";
|
|
3881
|
+
var teal = "#089981";
|
|
3406
3882
|
var white = "#FFFFFF";
|
|
3407
|
-
var yellow = "#
|
|
3883
|
+
var yellow = "#FDD835";
|
|
3408
3884
|
function from_gradient(value, bottom_value, top_value, bottom_color, top_color) {
|
|
3409
|
-
const parseColor2 = (
|
|
3410
|
-
if (typeof
|
|
3411
|
-
if (
|
|
3412
|
-
const hex =
|
|
3885
|
+
const parseColor2 = (col3) => {
|
|
3886
|
+
if (typeof col3 === "string") {
|
|
3887
|
+
if (col3.startsWith("#")) {
|
|
3888
|
+
const hex = col3.slice(1);
|
|
3413
3889
|
const r4 = parseInt(hex.slice(0, 2), 16);
|
|
3414
3890
|
const g4 = parseInt(hex.slice(2, 4), 16);
|
|
3415
3891
|
const b4 = parseInt(hex.slice(4, 6), 16);
|
|
3416
3892
|
return [r4, g4, b4, 1];
|
|
3417
3893
|
}
|
|
3418
|
-
const match2 =
|
|
3894
|
+
const match2 = col3.match(/rgba?\((\d+),\s*(\d+),\s*(\d+)(?:,\s*([\d.]+))?\)/);
|
|
3419
3895
|
if (match2) {
|
|
3420
3896
|
return [
|
|
3421
3897
|
parseInt(match2[1]),
|
|
@@ -3450,21 +3926,260 @@ function from_gradient(value, bottom_value, top_value, bottom_color, top_color)
|
|
|
3450
3926
|
// src/time/index.ts
|
|
3451
3927
|
var time_exports = {};
|
|
3452
3928
|
__export(time_exports, {
|
|
3929
|
+
dayofmonth: () => dayofmonth,
|
|
3930
|
+
dayofweek: () => dayofweek,
|
|
3931
|
+
hour: () => hour,
|
|
3932
|
+
inSession: () => inSession2,
|
|
3933
|
+
minute: () => minute,
|
|
3934
|
+
month: () => month,
|
|
3453
3935
|
now: () => now,
|
|
3454
|
-
|
|
3936
|
+
second: () => second,
|
|
3937
|
+
timestamp: () => timestamp,
|
|
3938
|
+
weekofyear: () => weekofyear,
|
|
3939
|
+
year: () => year
|
|
3455
3940
|
});
|
|
3941
|
+
|
|
3942
|
+
// src/time/datestring.ts
|
|
3943
|
+
var MONTHS2 = ["jan", "feb", "mar", "apr", "may", "jun", "jul", "aug", "sep", "oct", "nov", "dec"];
|
|
3944
|
+
var FULL_MONTHS = [
|
|
3945
|
+
"january",
|
|
3946
|
+
"february",
|
|
3947
|
+
"march",
|
|
3948
|
+
"april",
|
|
3949
|
+
"may",
|
|
3950
|
+
"june",
|
|
3951
|
+
"july",
|
|
3952
|
+
"august",
|
|
3953
|
+
"september",
|
|
3954
|
+
"october",
|
|
3955
|
+
"november",
|
|
3956
|
+
"december"
|
|
3957
|
+
];
|
|
3958
|
+
var ZONE_NAMES = {
|
|
3959
|
+
ut: 0,
|
|
3960
|
+
utc: 0,
|
|
3961
|
+
gmt: 0,
|
|
3962
|
+
est: -5,
|
|
3963
|
+
edt: -4,
|
|
3964
|
+
cst: -6,
|
|
3965
|
+
cdt: -5,
|
|
3966
|
+
mst: -7,
|
|
3967
|
+
mdt: -6,
|
|
3968
|
+
pst: -8,
|
|
3969
|
+
pdt: -7
|
|
3970
|
+
};
|
|
3971
|
+
var TIME = String.raw`(\d{1,2}):(\d{2})(?::(\d{2})(?:\.(\d{1,3})\d*)?)?`;
|
|
3972
|
+
var ZONE = String.raw`(ut|utc|gmt|[ecmp][sd]t|(?:utc|gmt)?\s*[+-]\d{1,2}(?::?\d{2})?)`;
|
|
3973
|
+
var NUMERIC_ZONE = String.raw`([+-]\d{2}(?::?\d{2})?)`;
|
|
3974
|
+
var DATE = String.raw`(\d{4})([-/])(\d{1,2})\2(\d{1,2})`;
|
|
3975
|
+
var WEEKDAY = String.raw`(?:[a-z]{3,9},?\s+)?`;
|
|
3976
|
+
var ISO_T = new RegExp(String.raw`^${DATE}t${TIME}\s*${NUMERIC_ZONE}?$`, "i");
|
|
3977
|
+
var ISO = new RegExp(String.raw`^${DATE}(?:\s+${TIME})?\s*${ZONE}?$`, "i");
|
|
3978
|
+
var DAY_FIRST = new RegExp(String.raw`^${WEEKDAY}(\d{1,2})(?:\s+|-)([a-z]+)\.?,?(?:\s+|-)(\d{4})(?:,?\s+${TIME})?\s*${ZONE}?$`, "i");
|
|
3979
|
+
var MONTH_FIRST = new RegExp(String.raw`^${WEEKDAY}([a-z]+)\.?\s+(\d{1,2}),?\s+(\d{4})(?:,?\s+${TIME})?\s*${ZONE}?$`, "i");
|
|
3980
|
+
function monthNumber(name) {
|
|
3981
|
+
const lower2 = name.toLowerCase();
|
|
3982
|
+
const i = FULL_MONTHS.findIndex((full, k) => lower2.startsWith(MONTHS2[k]) && full.startsWith(lower2));
|
|
3983
|
+
return i + 1;
|
|
3984
|
+
}
|
|
3985
|
+
function zoneMinutes(zone) {
|
|
3986
|
+
if (!zone) return 0;
|
|
3987
|
+
const lower2 = zone.toLowerCase().replace(/\s+/g, "");
|
|
3988
|
+
const named = ZONE_NAMES[lower2];
|
|
3989
|
+
if (named !== void 0) return named * 60;
|
|
3990
|
+
const m = /^(?:utc|gmt)?([+-])(\d{1,2})(?::?(\d{2}))?$/.exec(lower2);
|
|
3991
|
+
if (!m) return NaN;
|
|
3992
|
+
const minutes = Number(m[2]) * 60 + (m[3] ? Number(m[3]) : 0);
|
|
3993
|
+
return m[1] === "-" ? -minutes : minutes;
|
|
3994
|
+
}
|
|
3995
|
+
function parseDateString(dateString) {
|
|
3996
|
+
const text = dateString.trim();
|
|
3997
|
+
let year2, month2, day;
|
|
3998
|
+
let rest;
|
|
3999
|
+
let m;
|
|
4000
|
+
if (m = ISO_T.exec(text) ?? ISO.exec(text)) {
|
|
4001
|
+
[year2, month2, day] = [m[1], Number(m[3]), m[4]];
|
|
4002
|
+
rest = m.slice(5);
|
|
4003
|
+
} else if (m = DAY_FIRST.exec(text)) {
|
|
4004
|
+
[day, month2, year2] = [m[1], monthNumber(m[2]), m[3]];
|
|
4005
|
+
rest = m.slice(4);
|
|
4006
|
+
} else if (m = MONTH_FIRST.exec(text)) {
|
|
4007
|
+
[month2, day, year2] = [monthNumber(m[1]), m[2], m[3]];
|
|
4008
|
+
rest = m.slice(4);
|
|
4009
|
+
} else {
|
|
4010
|
+
throw new SyntaxError(`Invalid date string "${dateString}": use RFC 2822 or ISO 8601 ("20 Feb 2020", "2020-02-20T14:48:00")`);
|
|
4011
|
+
}
|
|
4012
|
+
const [hour2 = "0", minute2 = "0", second2 = "0", millis = "0", zone] = rest;
|
|
4013
|
+
const d = Number(day);
|
|
4014
|
+
const h = Number(hour2);
|
|
4015
|
+
const mi = Number(minute2);
|
|
4016
|
+
const s = Number(second2);
|
|
4017
|
+
const offset = zoneMinutes(zone);
|
|
4018
|
+
const endOfDay = h === 24 && mi === 0 && s === 0 && Number(millis) === 0;
|
|
4019
|
+
if (month2 < 1 || month2 > 12 || d < 1 || d > 31 || h > 23 && !endOfDay || mi > 59 || s > 59 || Number.isNaN(offset)) {
|
|
4020
|
+
throw new SyntaxError(`Invalid date string "${dateString}": a field is out of range`);
|
|
4021
|
+
}
|
|
4022
|
+
const ms = Number(millis.padEnd(3, "0"));
|
|
4023
|
+
return Date.UTC(Number(year2), month2 - 1, d, h, mi, s, ms) - offset * 6e4;
|
|
4024
|
+
}
|
|
4025
|
+
|
|
4026
|
+
// src/time/session.ts
|
|
4027
|
+
var PERIOD = /^(\d{2})(\d{2})-(\d{2})(\d{2})$/;
|
|
4028
|
+
var sessions = /* @__PURE__ */ new Map();
|
|
4029
|
+
function parseSession(session) {
|
|
4030
|
+
let parsed = sessions.get(session);
|
|
4031
|
+
if (parsed) return parsed;
|
|
4032
|
+
const invalid = () => new SyntaxError(`Invalid session "${session}": expected "HHmm-HHmm[,HHmm-HHmm...][:days]"`);
|
|
4033
|
+
const text = session.trim() === "24x7" ? "0000-0000" : session.replace(/\s+/g, "");
|
|
4034
|
+
const [periodText = "", dayText, extra] = text.split(":");
|
|
4035
|
+
if (extra !== void 0 || periodText === "") throw invalid();
|
|
4036
|
+
const periods = periodText.split(",").map((p) => {
|
|
4037
|
+
const m = PERIOD.exec(p);
|
|
4038
|
+
if (!m) throw invalid();
|
|
4039
|
+
const [h1, m1, h2, m2] = [m[1], m[2], m[3], m[4]].map(Number);
|
|
4040
|
+
if (h1 > 23 || h2 > 23 || m1 > 59 || m2 > 59) throw invalid();
|
|
4041
|
+
return { start: h1 * 60 + m1, end: h2 * 60 + m2 };
|
|
4042
|
+
});
|
|
4043
|
+
const dayDigits = dayText ?? (periods.length > 1 ? "23456" : "1234567");
|
|
4044
|
+
if (!/^[1-7]+$/.test(dayDigits)) throw invalid();
|
|
4045
|
+
const days = new Array(8).fill(false);
|
|
4046
|
+
for (const d of dayDigits) days[Number(d)] = true;
|
|
4047
|
+
parsed = { periods, days };
|
|
4048
|
+
sessions.set(session, parsed);
|
|
4049
|
+
return parsed;
|
|
4050
|
+
}
|
|
4051
|
+
function inSession(time, session, timezone) {
|
|
4052
|
+
if (Number.isNaN(time)) return false;
|
|
4053
|
+
const { periods, days } = parseSession(session);
|
|
4054
|
+
const f = zonedFields(time, timezone);
|
|
4055
|
+
const minute2 = f.hour * 60 + f.minute;
|
|
4056
|
+
const nextDay = f.dayOfWeek % 7 + 1;
|
|
4057
|
+
for (const { start, end } of periods) {
|
|
4058
|
+
if (start < end || start === 0 && end === 0) {
|
|
4059
|
+
if (minute2 >= start && (minute2 < end || end === 0) && days[f.dayOfWeek]) return true;
|
|
4060
|
+
} else {
|
|
4061
|
+
if (minute2 >= start && days[nextDay]) return true;
|
|
4062
|
+
if (minute2 < end && days[f.dayOfWeek]) return true;
|
|
4063
|
+
}
|
|
4064
|
+
}
|
|
4065
|
+
return false;
|
|
4066
|
+
}
|
|
4067
|
+
|
|
4068
|
+
// src/time/index.ts
|
|
3456
4069
|
function now() {
|
|
3457
4070
|
return Date.now();
|
|
3458
4071
|
}
|
|
3459
|
-
function timestamp(
|
|
3460
|
-
|
|
3461
|
-
|
|
3462
|
-
|
|
3463
|
-
|
|
3464
|
-
|
|
3465
|
-
|
|
3466
|
-
|
|
3467
|
-
|
|
4072
|
+
function timestamp(first2, ...rest) {
|
|
4073
|
+
if (typeof first2 === "string") {
|
|
4074
|
+
if (rest.length === 0) return parseDateString(first2);
|
|
4075
|
+
const [year2, month3, day2, hour3, minute3, second3] = rest;
|
|
4076
|
+
return zonedToUnix(first2, year2, month3, day2, hour3 ?? 0, minute3 ?? 0, second3 ?? 0);
|
|
4077
|
+
}
|
|
4078
|
+
const [month2, day, hour2, minute2, second2] = rest;
|
|
4079
|
+
return new Date(first2, month2 - 1, day, hour2 || 0, minute2 || 0, second2 || 0).getTime();
|
|
4080
|
+
}
|
|
4081
|
+
function field(time, timezone, pick) {
|
|
4082
|
+
return Number.isNaN(time) ? NaN : pick(zonedFields(time, timezone));
|
|
4083
|
+
}
|
|
4084
|
+
function year(time, timezone) {
|
|
4085
|
+
return field(time, timezone, (f) => f.year);
|
|
4086
|
+
}
|
|
4087
|
+
function month(time, timezone) {
|
|
4088
|
+
return field(time, timezone, (f) => f.month);
|
|
4089
|
+
}
|
|
4090
|
+
function dayofmonth(time, timezone) {
|
|
4091
|
+
return field(time, timezone, (f) => f.day);
|
|
4092
|
+
}
|
|
4093
|
+
function dayofweek(time, timezone) {
|
|
4094
|
+
return field(time, timezone, (f) => f.dayOfWeek);
|
|
4095
|
+
}
|
|
4096
|
+
function weekofyear(time, timezone) {
|
|
4097
|
+
return field(time, timezone, (f) => {
|
|
4098
|
+
const date = Date.UTC(f.year, f.month - 1, f.day);
|
|
4099
|
+
const mondayBased = (f.dayOfWeek + 5) % 7;
|
|
4100
|
+
const thursday = new Date(date + (3 - mondayBased) * 864e5);
|
|
4101
|
+
const yearStart = Date.UTC(thursday.getUTCFullYear(), 0, 1);
|
|
4102
|
+
return 1 + Math.floor((thursday.getTime() - yearStart) / (7 * 864e5));
|
|
4103
|
+
});
|
|
4104
|
+
}
|
|
4105
|
+
function hour(time, timezone) {
|
|
4106
|
+
return field(time, timezone, (f) => f.hour);
|
|
4107
|
+
}
|
|
4108
|
+
function minute(time, timezone) {
|
|
4109
|
+
return field(time, timezone, (f) => f.minute);
|
|
4110
|
+
}
|
|
4111
|
+
function second(time, timezone) {
|
|
4112
|
+
return field(time, timezone, (f) => f.second);
|
|
4113
|
+
}
|
|
4114
|
+
function inSession2(time, session, timezone) {
|
|
4115
|
+
return inSession(time, session, timezone);
|
|
4116
|
+
}
|
|
4117
|
+
|
|
4118
|
+
// src/timeframe/index.ts
|
|
4119
|
+
var timeframe_exports = {};
|
|
4120
|
+
__export(timeframe_exports, {
|
|
4121
|
+
from_seconds: () => from_seconds,
|
|
4122
|
+
in_seconds: () => in_seconds,
|
|
4123
|
+
info: () => info
|
|
4124
|
+
});
|
|
4125
|
+
var SECONDS_PER_MINUTE = 60;
|
|
4126
|
+
var SECONDS_PER_DAY = 86400;
|
|
4127
|
+
var SECONDS_PER_WEEK = 604800;
|
|
4128
|
+
var SECONDS_PER_MONTH = 2628003;
|
|
4129
|
+
var SECONDS_365_DAYS = 365 * SECONDS_PER_DAY;
|
|
4130
|
+
var UNIT_SECONDS = {
|
|
4131
|
+
S: 1,
|
|
4132
|
+
"": SECONDS_PER_MINUTE,
|
|
4133
|
+
D: SECONDS_PER_DAY,
|
|
4134
|
+
W: SECONDS_PER_WEEK,
|
|
4135
|
+
M: SECONDS_PER_MONTH
|
|
4136
|
+
};
|
|
4137
|
+
var SECOND_TIMEFRAMES = [1, 5, 10, 15, 30];
|
|
4138
|
+
function in_seconds(timeframe) {
|
|
4139
|
+
const text = timeframe.trim();
|
|
4140
|
+
if (text === "") {
|
|
4141
|
+
throw new RangeError("timeframe.in_seconds() needs a timeframe: the chart timeframe is not known here");
|
|
4142
|
+
}
|
|
4143
|
+
const before = /^(\d*)([SDWMT]?)$/.exec(text);
|
|
4144
|
+
const after = before ? null : /^([SDWMT])(\d+)$/.exec(text);
|
|
4145
|
+
if (!before && !after) throw new RangeError(`Invalid timeframe "${timeframe}"`);
|
|
4146
|
+
const [digits, unit] = before ? [before[1], before[2]] : [after[2], after[1]];
|
|
4147
|
+
if (unit === "T") return NaN;
|
|
4148
|
+
const multiplier = digits === "" ? 1 : Number(digits);
|
|
4149
|
+
return multiplier * UNIT_SECONDS[unit];
|
|
4150
|
+
}
|
|
4151
|
+
function from_seconds(seconds) {
|
|
4152
|
+
if (Number.isNaN(seconds)) throw new RangeError("timeframe.from_seconds() needs a number of seconds");
|
|
4153
|
+
if (seconds >= SECONDS_365_DAYS) return "12M";
|
|
4154
|
+
if (seconds > 0) {
|
|
4155
|
+
if (seconds % SECONDS_PER_MONTH === 0) return `${seconds / SECONDS_PER_MONTH}M`;
|
|
4156
|
+
if (seconds % SECONDS_PER_WEEK === 0) return `${seconds / SECONDS_PER_WEEK}W`;
|
|
4157
|
+
if (seconds % SECONDS_PER_DAY === 0) return `${seconds / SECONDS_PER_DAY}D`;
|
|
4158
|
+
if (seconds % SECONDS_PER_MINUTE === 0 && seconds < SECONDS_PER_DAY) return `${seconds / SECONDS_PER_MINUTE}`;
|
|
4159
|
+
}
|
|
4160
|
+
const second2 = SECOND_TIMEFRAMES.find((m) => seconds <= m);
|
|
4161
|
+
if (second2 !== void 0) return `${second2}S`;
|
|
4162
|
+
if (seconds < SECONDS_PER_DAY) return `${Math.ceil(seconds / SECONDS_PER_MINUTE)}`;
|
|
4163
|
+
return `${Math.ceil(seconds / SECONDS_PER_DAY)}D`;
|
|
4164
|
+
}
|
|
4165
|
+
function info(timeframe) {
|
|
4166
|
+
const text = timeframe.trim();
|
|
4167
|
+
const m = /^(\d*)([SDWMT]?)$/.exec(text);
|
|
4168
|
+
if (!m || text === "") throw new RangeError(`Invalid timeframe "${timeframe}"`);
|
|
4169
|
+
const unit = m[2];
|
|
4170
|
+
const multiplier = m[1] === "" ? 1 : Number(m[1]);
|
|
4171
|
+
return {
|
|
4172
|
+
period: unit === "" ? String(multiplier) : `${multiplier}${unit}`,
|
|
4173
|
+
multiplier,
|
|
4174
|
+
isintraday: unit === "" || unit === "S" || unit === "T",
|
|
4175
|
+
isdaily: unit === "D",
|
|
4176
|
+
isweekly: unit === "W",
|
|
4177
|
+
ismonthly: unit === "M",
|
|
4178
|
+
isminutes: unit === "",
|
|
4179
|
+
isseconds: unit === "S",
|
|
4180
|
+
isticks: unit === "T",
|
|
4181
|
+
isdwm: unit === "D" || unit === "W" || unit === "M"
|
|
4182
|
+
};
|
|
3468
4183
|
}
|
|
3469
4184
|
|
|
3470
4185
|
// src/matrix/index.ts
|
|
@@ -3476,14 +4191,14 @@ __export(matrix_exports, {
|
|
|
3476
4191
|
col: () => col,
|
|
3477
4192
|
columns: () => columns,
|
|
3478
4193
|
concat: () => concat3,
|
|
3479
|
-
copy: () =>
|
|
4194
|
+
copy: () => copy3,
|
|
3480
4195
|
det: () => det,
|
|
3481
4196
|
diff: () => diff,
|
|
3482
4197
|
eigenvalues: () => eigenvalues,
|
|
3483
4198
|
eigenvectors: () => eigenvectors,
|
|
3484
4199
|
elements_count: () => elements_count,
|
|
3485
4200
|
fill: () => fill2,
|
|
3486
|
-
get: () =>
|
|
4201
|
+
get: () => get3,
|
|
3487
4202
|
inv: () => inv,
|
|
3488
4203
|
is_antidiagonal: () => is_antidiagonal,
|
|
3489
4204
|
is_antisymmetric: () => is_antisymmetric,
|
|
@@ -3532,7 +4247,7 @@ function new_matrix(rows2, columns2, initial_value) {
|
|
|
3532
4247
|
}
|
|
3533
4248
|
return { rows: rows2, columns: columns2, data };
|
|
3534
4249
|
}
|
|
3535
|
-
function
|
|
4250
|
+
function get3(id, row2, column) {
|
|
3536
4251
|
if (row2 < 0 || row2 >= id.rows || column < 0 || column >= id.columns) {
|
|
3537
4252
|
throw new Error(`Matrix index out of bounds: [${row2}, ${column}] for matrix of size [${id.rows}, ${id.columns}]`);
|
|
3538
4253
|
}
|
|
@@ -3565,7 +4280,7 @@ function col(id, column_index) {
|
|
|
3565
4280
|
}
|
|
3566
4281
|
return id.data.map((r2) => r2[column_index]);
|
|
3567
4282
|
}
|
|
3568
|
-
function
|
|
4283
|
+
function copy3(id) {
|
|
3569
4284
|
const newData = id.data.map((r2) => [...r2]);
|
|
3570
4285
|
return {
|
|
3571
4286
|
rows: id.rows,
|
|
@@ -3917,24 +4632,24 @@ function median3(id) {
|
|
|
3917
4632
|
if (id.rows === 0 || id.columns === 0) {
|
|
3918
4633
|
return NaN;
|
|
3919
4634
|
}
|
|
3920
|
-
const
|
|
4635
|
+
const values2 = [];
|
|
3921
4636
|
for (let i = 0; i < id.rows; i++) {
|
|
3922
4637
|
for (let j = 0; j < id.columns; j++) {
|
|
3923
4638
|
const val = id.data[i][j];
|
|
3924
4639
|
if (val !== null && val !== void 0 && !isNaN(val)) {
|
|
3925
|
-
|
|
4640
|
+
values2.push(val);
|
|
3926
4641
|
}
|
|
3927
4642
|
}
|
|
3928
4643
|
}
|
|
3929
|
-
if (
|
|
4644
|
+
if (values2.length === 0) {
|
|
3930
4645
|
return NaN;
|
|
3931
4646
|
}
|
|
3932
|
-
|
|
3933
|
-
const mid = Math.floor(
|
|
3934
|
-
if (
|
|
3935
|
-
return (
|
|
4647
|
+
values2.sort((a, b2) => a - b2);
|
|
4648
|
+
const mid = Math.floor(values2.length / 2);
|
|
4649
|
+
if (values2.length % 2 === 0) {
|
|
4650
|
+
return (values2[mid - 1] + values2[mid]) / 2;
|
|
3936
4651
|
} else {
|
|
3937
|
-
return
|
|
4652
|
+
return values2[mid];
|
|
3938
4653
|
}
|
|
3939
4654
|
}
|
|
3940
4655
|
function mode3(id) {
|
|
@@ -4099,7 +4814,7 @@ function is_stochastic(id) {
|
|
|
4099
4814
|
}
|
|
4100
4815
|
return true;
|
|
4101
4816
|
}
|
|
4102
|
-
var
|
|
4817
|
+
var EPSILON2 = 1e-10;
|
|
4103
4818
|
function createIdentity(n) {
|
|
4104
4819
|
const m = new_matrix(n, n, 0);
|
|
4105
4820
|
for (let i = 0; i < n; i++) {
|
|
@@ -4180,7 +4895,7 @@ function pow2(id, power) {
|
|
|
4180
4895
|
base = inverse;
|
|
4181
4896
|
p = -power;
|
|
4182
4897
|
} else {
|
|
4183
|
-
base =
|
|
4898
|
+
base = copy3(id);
|
|
4184
4899
|
}
|
|
4185
4900
|
let result = createIdentity(n);
|
|
4186
4901
|
while (p > 0) {
|
|
@@ -4209,31 +4924,31 @@ function det(id) {
|
|
|
4209
4924
|
const a = id.data.map((row2) => [...row2]);
|
|
4210
4925
|
let determinant = 1;
|
|
4211
4926
|
let swapCount = 0;
|
|
4212
|
-
for (let
|
|
4213
|
-
let maxRow =
|
|
4214
|
-
let maxVal = Math.abs(a[
|
|
4215
|
-
for (let row2 =
|
|
4216
|
-
const absVal = Math.abs(a[row2][
|
|
4927
|
+
for (let col3 = 0; col3 < n; col3++) {
|
|
4928
|
+
let maxRow = col3;
|
|
4929
|
+
let maxVal = Math.abs(a[col3][col3]);
|
|
4930
|
+
for (let row2 = col3 + 1; row2 < n; row2++) {
|
|
4931
|
+
const absVal = Math.abs(a[row2][col3]);
|
|
4217
4932
|
if (absVal > maxVal) {
|
|
4218
4933
|
maxVal = absVal;
|
|
4219
4934
|
maxRow = row2;
|
|
4220
4935
|
}
|
|
4221
4936
|
}
|
|
4222
|
-
if (maxRow !==
|
|
4223
|
-
const temp = a[
|
|
4224
|
-
a[
|
|
4937
|
+
if (maxRow !== col3) {
|
|
4938
|
+
const temp = a[col3];
|
|
4939
|
+
a[col3] = a[maxRow];
|
|
4225
4940
|
a[maxRow] = temp;
|
|
4226
4941
|
swapCount++;
|
|
4227
4942
|
}
|
|
4228
|
-
const
|
|
4229
|
-
if (Math.abs(
|
|
4943
|
+
const pivot2 = a[col3][col3];
|
|
4944
|
+
if (Math.abs(pivot2) < EPSILON2) {
|
|
4230
4945
|
return 0;
|
|
4231
4946
|
}
|
|
4232
|
-
determinant *=
|
|
4233
|
-
for (let row2 =
|
|
4234
|
-
const factor = a[row2][
|
|
4235
|
-
for (let j =
|
|
4236
|
-
a[row2][j] = a[row2][j] - factor * a[
|
|
4947
|
+
determinant *= pivot2;
|
|
4948
|
+
for (let row2 = col3 + 1; row2 < n; row2++) {
|
|
4949
|
+
const factor = a[row2][col3] / pivot2;
|
|
4950
|
+
for (let j = col3; j < n; j++) {
|
|
4951
|
+
a[row2][j] = a[row2][j] - factor * a[col3][j];
|
|
4237
4952
|
}
|
|
4238
4953
|
}
|
|
4239
4954
|
}
|
|
@@ -4261,33 +4976,33 @@ function inv(id) {
|
|
|
4261
4976
|
}
|
|
4262
4977
|
aug.push(row2);
|
|
4263
4978
|
}
|
|
4264
|
-
for (let
|
|
4265
|
-
let maxRow =
|
|
4266
|
-
let maxVal = Math.abs(aug[
|
|
4267
|
-
for (let row2 =
|
|
4268
|
-
const absVal = Math.abs(aug[row2][
|
|
4979
|
+
for (let col3 = 0; col3 < n; col3++) {
|
|
4980
|
+
let maxRow = col3;
|
|
4981
|
+
let maxVal = Math.abs(aug[col3][col3]);
|
|
4982
|
+
for (let row2 = col3 + 1; row2 < n; row2++) {
|
|
4983
|
+
const absVal = Math.abs(aug[row2][col3]);
|
|
4269
4984
|
if (absVal > maxVal) {
|
|
4270
4985
|
maxVal = absVal;
|
|
4271
4986
|
maxRow = row2;
|
|
4272
4987
|
}
|
|
4273
4988
|
}
|
|
4274
|
-
if (maxRow !==
|
|
4275
|
-
const temp = aug[
|
|
4276
|
-
aug[
|
|
4989
|
+
if (maxRow !== col3) {
|
|
4990
|
+
const temp = aug[col3];
|
|
4991
|
+
aug[col3] = aug[maxRow];
|
|
4277
4992
|
aug[maxRow] = temp;
|
|
4278
4993
|
}
|
|
4279
|
-
const
|
|
4280
|
-
if (Math.abs(
|
|
4994
|
+
const pivot2 = aug[col3][col3];
|
|
4995
|
+
if (Math.abs(pivot2) < EPSILON2) {
|
|
4281
4996
|
return null;
|
|
4282
4997
|
}
|
|
4283
4998
|
for (let j = 0; j < 2 * n; j++) {
|
|
4284
|
-
aug[
|
|
4999
|
+
aug[col3][j] = aug[col3][j] / pivot2;
|
|
4285
5000
|
}
|
|
4286
5001
|
for (let row2 = 0; row2 < n; row2++) {
|
|
4287
|
-
if (row2 !==
|
|
4288
|
-
const factor = aug[row2][
|
|
5002
|
+
if (row2 !== col3) {
|
|
5003
|
+
const factor = aug[row2][col3];
|
|
4289
5004
|
for (let j = 0; j < 2 * n; j++) {
|
|
4290
|
-
aug[row2][j] = aug[row2][j] - factor * aug[
|
|
5005
|
+
aug[row2][j] = aug[row2][j] - factor * aug[col3][j];
|
|
4291
5006
|
}
|
|
4292
5007
|
}
|
|
4293
5008
|
}
|
|
@@ -4350,17 +5065,17 @@ function rank(id) {
|
|
|
4350
5065
|
const m = id.rows;
|
|
4351
5066
|
const n = id.columns;
|
|
4352
5067
|
let r2 = 0;
|
|
4353
|
-
for (let
|
|
5068
|
+
for (let col3 = 0; col3 < n && r2 < m; col3++) {
|
|
4354
5069
|
let maxRow = r2;
|
|
4355
|
-
let maxVal = Math.abs(a[r2][
|
|
5070
|
+
let maxVal = Math.abs(a[r2][col3]);
|
|
4356
5071
|
for (let row2 = r2 + 1; row2 < m; row2++) {
|
|
4357
|
-
const absVal = Math.abs(a[row2][
|
|
5072
|
+
const absVal = Math.abs(a[row2][col3]);
|
|
4358
5073
|
if (absVal > maxVal) {
|
|
4359
5074
|
maxVal = absVal;
|
|
4360
5075
|
maxRow = row2;
|
|
4361
5076
|
}
|
|
4362
5077
|
}
|
|
4363
|
-
if (maxVal <
|
|
5078
|
+
if (maxVal < EPSILON2) {
|
|
4364
5079
|
continue;
|
|
4365
5080
|
}
|
|
4366
5081
|
if (maxRow !== r2) {
|
|
@@ -4368,10 +5083,10 @@ function rank(id) {
|
|
|
4368
5083
|
a[r2] = a[maxRow];
|
|
4369
5084
|
a[maxRow] = temp;
|
|
4370
5085
|
}
|
|
4371
|
-
const
|
|
5086
|
+
const pivot2 = a[r2][col3];
|
|
4372
5087
|
for (let row2 = r2 + 1; row2 < m; row2++) {
|
|
4373
|
-
const factor = a[row2][
|
|
4374
|
-
for (let j =
|
|
5088
|
+
const factor = a[row2][col3] / pivot2;
|
|
5089
|
+
for (let j = col3; j < n; j++) {
|
|
4375
5090
|
a[row2][j] = a[row2][j] - factor * a[r2][j];
|
|
4376
5091
|
}
|
|
4377
5092
|
}
|
|
@@ -4417,7 +5132,7 @@ function toHessenberg(m) {
|
|
|
4417
5132
|
for (let i = k + 1; i < n; i++) {
|
|
4418
5133
|
maxVal = Math.max(maxVal, Math.abs(h[i][k]));
|
|
4419
5134
|
}
|
|
4420
|
-
if (maxVal <
|
|
5135
|
+
if (maxVal < EPSILON2) continue;
|
|
4421
5136
|
let sigma = 0;
|
|
4422
5137
|
for (let i = k + 1; i < n; i++) {
|
|
4423
5138
|
sigma += h[i][k] * h[i][k];
|
|
@@ -4433,7 +5148,7 @@ function toHessenberg(m) {
|
|
|
4433
5148
|
for (let i = k + 1; i < n; i++) {
|
|
4434
5149
|
uTu += u[i] * u[i];
|
|
4435
5150
|
}
|
|
4436
|
-
if (uTu <
|
|
5151
|
+
if (uTu < EPSILON2) continue;
|
|
4437
5152
|
for (let j = k; j < n; j++) {
|
|
4438
5153
|
let dot = 0;
|
|
4439
5154
|
for (let i = k + 1; i < n; i++) {
|
|
@@ -4465,7 +5180,7 @@ function qrAlgorithm(h, maxIter) {
|
|
|
4465
5180
|
for (let iter = 0; iter < maxIter && remaining > 1; iter++) {
|
|
4466
5181
|
let converged = false;
|
|
4467
5182
|
for (let i = remaining - 1; i >= 1; i--) {
|
|
4468
|
-
if (Math.abs(a[i][i - 1]) <
|
|
5183
|
+
if (Math.abs(a[i][i - 1]) < EPSILON2 * (Math.abs(a[i - 1][i - 1]) + Math.abs(a[i][i]))) {
|
|
4469
5184
|
a[i][i - 1] = 0;
|
|
4470
5185
|
if (i === remaining - 1) {
|
|
4471
5186
|
eigenvals.push(a[remaining - 1][remaining - 1]);
|
|
@@ -4484,8 +5199,8 @@ function qrAlgorithm(h, maxIter) {
|
|
|
4484
5199
|
let z = a[1][0];
|
|
4485
5200
|
for (let k = 0; k < remaining - 1; k++) {
|
|
4486
5201
|
let r2 = Math.sqrt(x * x + z * z);
|
|
4487
|
-
if (r2 <
|
|
4488
|
-
r2 =
|
|
5202
|
+
if (r2 < EPSILON2) {
|
|
5203
|
+
r2 = EPSILON2;
|
|
4489
5204
|
}
|
|
4490
5205
|
const c = x / r2;
|
|
4491
5206
|
const s = z / r2;
|
|
@@ -4546,8 +5261,8 @@ function inverseIteration(m, lambda) {
|
|
|
4546
5261
|
(row2, i) => row2.map((val, j) => i === j ? val - lambda : val)
|
|
4547
5262
|
);
|
|
4548
5263
|
for (let i = 0; i < n; i++) {
|
|
4549
|
-
if (Math.abs(shifted[i][i]) <
|
|
4550
|
-
shifted[i][i] =
|
|
5264
|
+
if (Math.abs(shifted[i][i]) < EPSILON2) {
|
|
5265
|
+
shifted[i][i] = EPSILON2;
|
|
4551
5266
|
}
|
|
4552
5267
|
}
|
|
4553
5268
|
let v = new Array(n).fill(1);
|
|
@@ -4558,7 +5273,7 @@ function inverseIteration(m, lambda) {
|
|
|
4558
5273
|
norm += w[i] * w[i];
|
|
4559
5274
|
}
|
|
4560
5275
|
norm = Math.sqrt(norm);
|
|
4561
|
-
if (norm <
|
|
5276
|
+
if (norm < EPSILON2) {
|
|
4562
5277
|
return v;
|
|
4563
5278
|
}
|
|
4564
5279
|
const newV = [];
|
|
@@ -4570,7 +5285,7 @@ function inverseIteration(m, lambda) {
|
|
|
4570
5285
|
diff2 += Math.abs(Math.abs(newV[i]) - Math.abs(v[i]));
|
|
4571
5286
|
}
|
|
4572
5287
|
v = newV;
|
|
4573
|
-
if (diff2 <
|
|
5288
|
+
if (diff2 < EPSILON2) {
|
|
4574
5289
|
break;
|
|
4575
5290
|
}
|
|
4576
5291
|
}
|
|
@@ -4579,29 +5294,29 @@ function inverseIteration(m, lambda) {
|
|
|
4579
5294
|
function solveLinearSystem(a, b2) {
|
|
4580
5295
|
const n = a.length;
|
|
4581
5296
|
const aug = a.map((row2, i) => [...row2, b2[i]]);
|
|
4582
|
-
for (let
|
|
4583
|
-
let maxRow =
|
|
4584
|
-
let maxVal = Math.abs(aug[
|
|
4585
|
-
for (let row2 =
|
|
4586
|
-
const absVal = Math.abs(aug[row2][
|
|
5297
|
+
for (let col3 = 0; col3 < n; col3++) {
|
|
5298
|
+
let maxRow = col3;
|
|
5299
|
+
let maxVal = Math.abs(aug[col3][col3]);
|
|
5300
|
+
for (let row2 = col3 + 1; row2 < n; row2++) {
|
|
5301
|
+
const absVal = Math.abs(aug[row2][col3]);
|
|
4587
5302
|
if (absVal > maxVal) {
|
|
4588
5303
|
maxVal = absVal;
|
|
4589
5304
|
maxRow = row2;
|
|
4590
5305
|
}
|
|
4591
5306
|
}
|
|
4592
|
-
if (maxRow !==
|
|
4593
|
-
const temp = aug[
|
|
4594
|
-
aug[
|
|
5307
|
+
if (maxRow !== col3) {
|
|
5308
|
+
const temp = aug[col3];
|
|
5309
|
+
aug[col3] = aug[maxRow];
|
|
4595
5310
|
aug[maxRow] = temp;
|
|
4596
5311
|
}
|
|
4597
|
-
const
|
|
4598
|
-
if (Math.abs(
|
|
5312
|
+
const pivot2 = aug[col3][col3];
|
|
5313
|
+
if (Math.abs(pivot2) < EPSILON2) {
|
|
4599
5314
|
continue;
|
|
4600
5315
|
}
|
|
4601
|
-
for (let row2 =
|
|
4602
|
-
const factor = aug[row2][
|
|
4603
|
-
for (let j =
|
|
4604
|
-
aug[row2][j] = aug[row2][j] - factor * aug[
|
|
5316
|
+
for (let row2 = col3 + 1; row2 < n; row2++) {
|
|
5317
|
+
const factor = aug[row2][col3] / pivot2;
|
|
5318
|
+
for (let j = col3; j <= n; j++) {
|
|
5319
|
+
aug[row2][j] = aug[row2][j] - factor * aug[col3][j];
|
|
4605
5320
|
}
|
|
4606
5321
|
}
|
|
4607
5322
|
}
|
|
@@ -4612,7 +5327,7 @@ function solveLinearSystem(a, b2) {
|
|
|
4612
5327
|
sum4 -= aug[i][j] * x[j];
|
|
4613
5328
|
}
|
|
4614
5329
|
const diag = aug[i][i];
|
|
4615
|
-
x[i] = Math.abs(diag) <
|
|
5330
|
+
x[i] = Math.abs(diag) < EPSILON2 ? 0 : sum4 / diag;
|
|
4616
5331
|
}
|
|
4617
5332
|
return x;
|
|
4618
5333
|
}
|
|
@@ -4633,8 +5348,8 @@ function kron(id1, id2) {
|
|
|
4633
5348
|
for (let i2 = 0; i2 < m2; i2++) {
|
|
4634
5349
|
for (let j2 = 0; j2 < n2; j2++) {
|
|
4635
5350
|
const row2 = i1 * m2 + i2;
|
|
4636
|
-
const
|
|
4637
|
-
data[row2][
|
|
5351
|
+
const col3 = j1 * n2 + j2;
|
|
5352
|
+
data[row2][col3] = a * id2.data[i2][j2];
|
|
4638
5353
|
}
|
|
4639
5354
|
}
|
|
4640
5355
|
}
|
|
@@ -4652,7 +5367,9 @@ function newtype2(rows2 = 0, columns2 = 0, initial_value) {
|
|
|
4652
5367
|
// src/line/index.ts
|
|
4653
5368
|
var line_exports = {};
|
|
4654
5369
|
__export(line_exports, {
|
|
4655
|
-
|
|
5370
|
+
all: () => all2,
|
|
5371
|
+
copy: () => copy4,
|
|
5372
|
+
delete: () => delete_line,
|
|
4656
5373
|
delete_line: () => delete_line,
|
|
4657
5374
|
get_price: () => get_price,
|
|
4658
5375
|
get_x1: () => get_x1,
|
|
@@ -4663,6 +5380,8 @@ __export(line_exports, {
|
|
|
4663
5380
|
new_line: () => new_line2,
|
|
4664
5381
|
set_color: () => set_color,
|
|
4665
5382
|
set_extend: () => set_extend,
|
|
5383
|
+
set_first_point: () => set_first_point,
|
|
5384
|
+
set_second_point: () => set_second_point,
|
|
4666
5385
|
set_style: () => set_style,
|
|
4667
5386
|
set_width: () => set_width,
|
|
4668
5387
|
set_x1: () => set_x1,
|
|
@@ -4673,18 +5392,78 @@ __export(line_exports, {
|
|
|
4673
5392
|
set_y1: () => set_y1,
|
|
4674
5393
|
set_y2: () => set_y2
|
|
4675
5394
|
});
|
|
4676
|
-
|
|
4677
|
-
|
|
5395
|
+
|
|
5396
|
+
// src/drawing/registry.ts
|
|
5397
|
+
var DEFAULT_MAX_COUNT = 50;
|
|
5398
|
+
var SLACK = 5;
|
|
5399
|
+
var live = { line: [], label: [], box: [], polyline: [], linefill: [] };
|
|
5400
|
+
var limits = {
|
|
5401
|
+
line: DEFAULT_MAX_COUNT,
|
|
5402
|
+
label: DEFAULT_MAX_COUNT,
|
|
5403
|
+
box: DEFAULT_MAX_COUNT,
|
|
5404
|
+
polyline: DEFAULT_MAX_COUNT
|
|
5405
|
+
};
|
|
5406
|
+
var deleted = /* @__PURE__ */ new WeakSet();
|
|
5407
|
+
var COORDINATES = {
|
|
5408
|
+
line: ["x1", "y1", "x2", "y2"],
|
|
5409
|
+
label: ["x", "y"],
|
|
5410
|
+
box: ["left", "top", "right", "bottom"],
|
|
5411
|
+
polyline: [],
|
|
5412
|
+
linefill: []
|
|
5413
|
+
};
|
|
5414
|
+
function markDeleted(kind, obj, explicit) {
|
|
5415
|
+
deleted.add(obj);
|
|
5416
|
+
for (const field2 of COORDINATES[kind]) obj[field2] = NaN;
|
|
5417
|
+
if (kind === "line" && explicit) {
|
|
5418
|
+
for (const fill3 of live.linefill.filter((f) => f.line1 === obj || f.line2 === obj)) remove3("linefill", fill3);
|
|
5419
|
+
}
|
|
5420
|
+
}
|
|
5421
|
+
function register(kind, obj) {
|
|
5422
|
+
const list = live[kind];
|
|
5423
|
+
list.push(obj);
|
|
5424
|
+
const max6 = limits[kind === "linefill" ? "line" : kind];
|
|
5425
|
+
if (list.length > max6 + SLACK) {
|
|
5426
|
+
for (const old of list.splice(0, list.length - max6)) markDeleted(kind, old, false);
|
|
5427
|
+
}
|
|
5428
|
+
return obj;
|
|
5429
|
+
}
|
|
5430
|
+
function remove3(kind, obj) {
|
|
5431
|
+
const list = live[kind];
|
|
5432
|
+
const index = list.indexOf(obj);
|
|
5433
|
+
if (index !== -1) list.splice(index, 1);
|
|
5434
|
+
if (!deleted.has(obj)) markDeleted(kind, obj, true);
|
|
5435
|
+
}
|
|
5436
|
+
function isDeleted(obj) {
|
|
5437
|
+
return typeof obj === "object" && obj !== null && deleted.has(obj);
|
|
5438
|
+
}
|
|
5439
|
+
function all(kind) {
|
|
5440
|
+
return [...live[kind]];
|
|
5441
|
+
}
|
|
5442
|
+
|
|
5443
|
+
// src/line/index.ts
|
|
5444
|
+
function new_line2(...args) {
|
|
5445
|
+
let x1, y1, x2, y2, rest;
|
|
5446
|
+
if (typeof args[0] === "object" && args[0] !== null) {
|
|
5447
|
+
const [p1, p2, ...others] = args;
|
|
5448
|
+
const xloc3 = others[0] ?? "bar_index";
|
|
5449
|
+
[x1, y1, x2, y2, rest] = [pointX(p1, xloc3), p1.price, pointX(p2, xloc3), p2.price, others];
|
|
5450
|
+
} else {
|
|
5451
|
+
[x1, y1, x2, y2] = args;
|
|
5452
|
+
rest = args.slice(4);
|
|
5453
|
+
}
|
|
5454
|
+
const [xloc2, extend, lineColor, style, width, force_overlay] = rest;
|
|
5455
|
+
return register("line", {
|
|
4678
5456
|
x1,
|
|
4679
5457
|
y1,
|
|
4680
5458
|
x2,
|
|
4681
5459
|
y2,
|
|
4682
|
-
xloc: xloc2,
|
|
4683
|
-
extend,
|
|
5460
|
+
xloc: xloc2 ?? "bar_index",
|
|
5461
|
+
extend: extend ?? "none",
|
|
4684
5462
|
color: lineColor,
|
|
4685
5463
|
style: style || "solid",
|
|
4686
|
-
width: width || 1
|
|
4687
|
-
|
|
5464
|
+
width: width || 1,
|
|
5465
|
+
force_overlay: force_overlay ?? false
|
|
5466
|
+
});
|
|
4688
5467
|
}
|
|
4689
5468
|
function get_price(id, x) {
|
|
4690
5469
|
const { x1, y1, x2, y2, extend, xloc: xloc2 } = id;
|
|
@@ -4723,64 +5502,97 @@ function get_y1(id) {
|
|
|
4723
5502
|
function get_y2(id) {
|
|
4724
5503
|
return id.y2;
|
|
4725
5504
|
}
|
|
4726
|
-
function
|
|
4727
|
-
return { ...id };
|
|
5505
|
+
function copy4(id) {
|
|
5506
|
+
return register("line", { ...id });
|
|
4728
5507
|
}
|
|
4729
5508
|
function set_x1(id, x) {
|
|
5509
|
+
if (isDeleted(id)) return id;
|
|
4730
5510
|
id.x1 = x;
|
|
4731
5511
|
return id;
|
|
4732
5512
|
}
|
|
4733
5513
|
function set_x2(id, x) {
|
|
5514
|
+
if (isDeleted(id)) return id;
|
|
4734
5515
|
id.x2 = x;
|
|
4735
5516
|
return id;
|
|
4736
5517
|
}
|
|
4737
5518
|
function set_y1(id, y) {
|
|
5519
|
+
if (isDeleted(id)) return id;
|
|
4738
5520
|
id.y1 = y;
|
|
4739
5521
|
return id;
|
|
4740
5522
|
}
|
|
4741
5523
|
function set_y2(id, y) {
|
|
5524
|
+
if (isDeleted(id)) return id;
|
|
4742
5525
|
id.y2 = y;
|
|
4743
5526
|
return id;
|
|
4744
5527
|
}
|
|
4745
5528
|
function set_xy1(id, x, y) {
|
|
5529
|
+
if (isDeleted(id)) return id;
|
|
4746
5530
|
id.x1 = x;
|
|
4747
5531
|
id.y1 = y;
|
|
4748
5532
|
return id;
|
|
4749
5533
|
}
|
|
4750
5534
|
function set_xy2(id, x, y) {
|
|
5535
|
+
if (isDeleted(id)) return id;
|
|
4751
5536
|
id.x2 = x;
|
|
4752
5537
|
id.y2 = y;
|
|
4753
5538
|
return id;
|
|
4754
5539
|
}
|
|
4755
5540
|
function set_xloc(id, x1, x2, xloc2) {
|
|
5541
|
+
if (isDeleted(id)) return id;
|
|
4756
5542
|
id.x1 = x1;
|
|
4757
5543
|
id.x2 = x2;
|
|
4758
5544
|
id.xloc = xloc2;
|
|
4759
5545
|
return id;
|
|
4760
5546
|
}
|
|
4761
5547
|
function set_extend(id, extend) {
|
|
5548
|
+
if (isDeleted(id)) return id;
|
|
4762
5549
|
id.extend = extend;
|
|
4763
5550
|
return id;
|
|
4764
5551
|
}
|
|
4765
5552
|
function set_color(id, lineColor) {
|
|
5553
|
+
if (isDeleted(id)) return id;
|
|
4766
5554
|
id.color = lineColor;
|
|
4767
5555
|
return id;
|
|
4768
5556
|
}
|
|
4769
5557
|
function set_style(id, style) {
|
|
5558
|
+
if (isDeleted(id)) return id;
|
|
4770
5559
|
id.style = style;
|
|
4771
5560
|
return id;
|
|
4772
5561
|
}
|
|
4773
5562
|
function set_width(id, width) {
|
|
5563
|
+
if (isDeleted(id)) return id;
|
|
4774
5564
|
id.width = width;
|
|
4775
5565
|
return id;
|
|
4776
5566
|
}
|
|
4777
|
-
function delete_line(
|
|
5567
|
+
function delete_line(id) {
|
|
5568
|
+
remove3("line", id);
|
|
5569
|
+
}
|
|
5570
|
+
function pointX(point, xloc2) {
|
|
5571
|
+
const x = xloc2 === "bar_time" ? point.time : point.index;
|
|
5572
|
+
return x ?? NaN;
|
|
5573
|
+
}
|
|
5574
|
+
function all2() {
|
|
5575
|
+
return all("line");
|
|
5576
|
+
}
|
|
5577
|
+
function set_first_point(id, point) {
|
|
5578
|
+
if (isDeleted(id)) return id;
|
|
5579
|
+
id.x1 = pointX(point, id.xloc);
|
|
5580
|
+
id.y1 = point.price;
|
|
5581
|
+
return id;
|
|
5582
|
+
}
|
|
5583
|
+
function set_second_point(id, point) {
|
|
5584
|
+
if (isDeleted(id)) return id;
|
|
5585
|
+
id.x2 = pointX(point, id.xloc);
|
|
5586
|
+
id.y2 = point.price;
|
|
5587
|
+
return id;
|
|
4778
5588
|
}
|
|
4779
5589
|
|
|
4780
5590
|
// src/box/index.ts
|
|
4781
5591
|
var box_exports = {};
|
|
4782
5592
|
__export(box_exports, {
|
|
4783
|
-
|
|
5593
|
+
all: () => all3,
|
|
5594
|
+
copy: () => copy5,
|
|
5595
|
+
delete: () => delete_box,
|
|
4784
5596
|
delete_box: () => delete_box,
|
|
4785
5597
|
get_bottom: () => get_bottom,
|
|
4786
5598
|
get_left: () => get_left,
|
|
@@ -4793,6 +5605,7 @@ __export(box_exports, {
|
|
|
4793
5605
|
set_border_style: () => set_border_style,
|
|
4794
5606
|
set_border_width: () => set_border_width,
|
|
4795
5607
|
set_bottom: () => set_bottom,
|
|
5608
|
+
set_bottom_right_point: () => set_bottom_right_point,
|
|
4796
5609
|
set_extend: () => set_extend2,
|
|
4797
5610
|
set_left: () => set_left,
|
|
4798
5611
|
set_lefttop: () => set_lefttop,
|
|
@@ -4801,21 +5614,49 @@ __export(box_exports, {
|
|
|
4801
5614
|
set_text: () => set_text,
|
|
4802
5615
|
set_text_color: () => set_text_color,
|
|
4803
5616
|
set_text_font_family: () => set_text_font_family,
|
|
5617
|
+
set_text_formatting: () => set_text_formatting,
|
|
4804
5618
|
set_text_halign: () => set_text_halign,
|
|
4805
5619
|
set_text_size: () => set_text_size,
|
|
4806
5620
|
set_text_valign: () => set_text_valign,
|
|
4807
5621
|
set_text_wrap: () => set_text_wrap,
|
|
4808
5622
|
set_top: () => set_top,
|
|
5623
|
+
set_top_left_point: () => set_top_left_point,
|
|
4809
5624
|
set_xloc: () => set_xloc2
|
|
4810
5625
|
});
|
|
4811
|
-
function new_box2(
|
|
4812
|
-
|
|
5626
|
+
function new_box2(...args) {
|
|
5627
|
+
let left, top, right, bottom, rest;
|
|
5628
|
+
if (typeof args[0] === "object" && args[0] !== null) {
|
|
5629
|
+
const [tl, br, ...others] = args;
|
|
5630
|
+
const xloc3 = others[4] ?? "bar_index";
|
|
5631
|
+
[left, top, right, bottom, rest] = [pointX2(tl, xloc3), tl.price, pointX2(br, xloc3), br.price, others];
|
|
5632
|
+
} else {
|
|
5633
|
+
[left, top, right, bottom] = args;
|
|
5634
|
+
rest = args.slice(4);
|
|
5635
|
+
}
|
|
5636
|
+
const [
|
|
5637
|
+
border_color,
|
|
5638
|
+
border_width,
|
|
5639
|
+
border_style,
|
|
5640
|
+
extend,
|
|
5641
|
+
xloc2,
|
|
5642
|
+
bgcolor,
|
|
5643
|
+
text,
|
|
5644
|
+
text_size,
|
|
5645
|
+
text_color,
|
|
5646
|
+
text_halign,
|
|
5647
|
+
text_valign,
|
|
5648
|
+
text_wrap,
|
|
5649
|
+
text_font_family,
|
|
5650
|
+
force_overlay,
|
|
5651
|
+
text_formatting
|
|
5652
|
+
] = rest;
|
|
5653
|
+
return register("box", {
|
|
4813
5654
|
left,
|
|
4814
5655
|
top,
|
|
4815
5656
|
right,
|
|
4816
5657
|
bottom,
|
|
4817
|
-
xloc: xloc2,
|
|
4818
|
-
extend,
|
|
5658
|
+
xloc: xloc2 ?? "bar_index",
|
|
5659
|
+
extend: extend ?? "none",
|
|
4819
5660
|
border_color,
|
|
4820
5661
|
border_width: border_width || 1,
|
|
4821
5662
|
border_style: border_style || "solid",
|
|
@@ -4826,8 +5667,10 @@ function new_box2(left, top, right, bottom, xloc2 = "bar_index", extend = "none"
|
|
|
4826
5667
|
text_halign,
|
|
4827
5668
|
text_valign,
|
|
4828
5669
|
text_wrap,
|
|
4829
|
-
text_font_family
|
|
4830
|
-
|
|
5670
|
+
text_font_family,
|
|
5671
|
+
force_overlay: force_overlay ?? false,
|
|
5672
|
+
text_formatting
|
|
5673
|
+
});
|
|
4831
5674
|
}
|
|
4832
5675
|
function get_left(id) {
|
|
4833
5676
|
return id.left;
|
|
@@ -4841,96 +5684,142 @@ function get_top(id) {
|
|
|
4841
5684
|
function get_bottom(id) {
|
|
4842
5685
|
return id.bottom;
|
|
4843
5686
|
}
|
|
4844
|
-
function
|
|
4845
|
-
return { ...id };
|
|
5687
|
+
function copy5(id) {
|
|
5688
|
+
return register("box", { ...id });
|
|
4846
5689
|
}
|
|
4847
5690
|
function set_left(id, left) {
|
|
5691
|
+
if (isDeleted(id)) return id;
|
|
4848
5692
|
id.left = left;
|
|
4849
5693
|
return id;
|
|
4850
5694
|
}
|
|
4851
5695
|
function set_right(id, right) {
|
|
5696
|
+
if (isDeleted(id)) return id;
|
|
4852
5697
|
id.right = right;
|
|
4853
5698
|
return id;
|
|
4854
5699
|
}
|
|
4855
5700
|
function set_top(id, top) {
|
|
5701
|
+
if (isDeleted(id)) return id;
|
|
4856
5702
|
id.top = top;
|
|
4857
5703
|
return id;
|
|
4858
5704
|
}
|
|
4859
5705
|
function set_bottom(id, bottom) {
|
|
5706
|
+
if (isDeleted(id)) return id;
|
|
4860
5707
|
id.bottom = bottom;
|
|
4861
5708
|
return id;
|
|
4862
5709
|
}
|
|
4863
5710
|
function set_lefttop(id, left, top) {
|
|
5711
|
+
if (isDeleted(id)) return id;
|
|
4864
5712
|
id.left = left;
|
|
4865
5713
|
id.top = top;
|
|
4866
5714
|
return id;
|
|
4867
5715
|
}
|
|
4868
5716
|
function set_rightbottom(id, right, bottom) {
|
|
5717
|
+
if (isDeleted(id)) return id;
|
|
4869
5718
|
id.right = right;
|
|
4870
5719
|
id.bottom = bottom;
|
|
4871
5720
|
return id;
|
|
4872
5721
|
}
|
|
4873
5722
|
function set_xloc2(id, left, right, xloc2) {
|
|
5723
|
+
if (isDeleted(id)) return id;
|
|
4874
5724
|
id.left = left;
|
|
4875
5725
|
id.right = right;
|
|
4876
5726
|
id.xloc = xloc2;
|
|
4877
5727
|
return id;
|
|
4878
5728
|
}
|
|
4879
5729
|
function set_extend2(id, extend) {
|
|
5730
|
+
if (isDeleted(id)) return id;
|
|
4880
5731
|
id.extend = extend;
|
|
4881
5732
|
return id;
|
|
4882
5733
|
}
|
|
4883
5734
|
function set_border_color(id, borderColor) {
|
|
5735
|
+
if (isDeleted(id)) return id;
|
|
4884
5736
|
id.border_color = borderColor;
|
|
4885
5737
|
return id;
|
|
4886
5738
|
}
|
|
4887
5739
|
function set_border_width(id, width) {
|
|
5740
|
+
if (isDeleted(id)) return id;
|
|
4888
5741
|
id.border_width = width;
|
|
4889
5742
|
return id;
|
|
4890
5743
|
}
|
|
4891
5744
|
function set_border_style(id, style) {
|
|
5745
|
+
if (isDeleted(id)) return id;
|
|
4892
5746
|
id.border_style = style;
|
|
4893
5747
|
return id;
|
|
4894
5748
|
}
|
|
4895
5749
|
function set_bgcolor(id, bgColor) {
|
|
5750
|
+
if (isDeleted(id)) return id;
|
|
4896
5751
|
id.bgcolor = bgColor;
|
|
4897
5752
|
return id;
|
|
4898
5753
|
}
|
|
4899
5754
|
function set_text(id, text) {
|
|
5755
|
+
if (isDeleted(id)) return id;
|
|
4900
5756
|
id.text = text;
|
|
4901
5757
|
return id;
|
|
4902
5758
|
}
|
|
4903
5759
|
function set_text_color(id, textColor) {
|
|
5760
|
+
if (isDeleted(id)) return id;
|
|
4904
5761
|
id.text_color = textColor;
|
|
4905
5762
|
return id;
|
|
4906
5763
|
}
|
|
4907
|
-
function set_text_size(id,
|
|
4908
|
-
id
|
|
5764
|
+
function set_text_size(id, size3) {
|
|
5765
|
+
if (isDeleted(id)) return id;
|
|
5766
|
+
id.text_size = size3;
|
|
4909
5767
|
return id;
|
|
4910
5768
|
}
|
|
4911
5769
|
function set_text_halign(id, align) {
|
|
5770
|
+
if (isDeleted(id)) return id;
|
|
4912
5771
|
id.text_halign = align;
|
|
4913
5772
|
return id;
|
|
4914
5773
|
}
|
|
4915
5774
|
function set_text_valign(id, align) {
|
|
5775
|
+
if (isDeleted(id)) return id;
|
|
4916
5776
|
id.text_valign = align;
|
|
4917
5777
|
return id;
|
|
4918
5778
|
}
|
|
4919
5779
|
function set_text_wrap(id, wrap) {
|
|
5780
|
+
if (isDeleted(id)) return id;
|
|
4920
5781
|
id.text_wrap = wrap;
|
|
4921
5782
|
return id;
|
|
4922
5783
|
}
|
|
4923
5784
|
function set_text_font_family(id, font) {
|
|
5785
|
+
if (isDeleted(id)) return id;
|
|
4924
5786
|
id.text_font_family = font;
|
|
4925
5787
|
return id;
|
|
4926
5788
|
}
|
|
4927
|
-
function delete_box(
|
|
5789
|
+
function delete_box(id) {
|
|
5790
|
+
remove3("box", id);
|
|
5791
|
+
}
|
|
5792
|
+
function pointX2(point, xloc2) {
|
|
5793
|
+
const x = xloc2 === "bar_time" ? point.time : point.index;
|
|
5794
|
+
return x ?? NaN;
|
|
5795
|
+
}
|
|
5796
|
+
function all3() {
|
|
5797
|
+
return all("box");
|
|
5798
|
+
}
|
|
5799
|
+
function set_top_left_point(id, point) {
|
|
5800
|
+
if (isDeleted(id)) return id;
|
|
5801
|
+
id.left = pointX2(point, id.xloc);
|
|
5802
|
+
id.top = point.price;
|
|
5803
|
+
return id;
|
|
5804
|
+
}
|
|
5805
|
+
function set_bottom_right_point(id, point) {
|
|
5806
|
+
if (isDeleted(id)) return id;
|
|
5807
|
+
id.right = pointX2(point, id.xloc);
|
|
5808
|
+
id.bottom = point.price;
|
|
5809
|
+
return id;
|
|
5810
|
+
}
|
|
5811
|
+
function set_text_formatting(id, formatting) {
|
|
5812
|
+
if (isDeleted(id)) return id;
|
|
5813
|
+
id.text_formatting = formatting;
|
|
5814
|
+
return id;
|
|
4928
5815
|
}
|
|
4929
5816
|
|
|
4930
5817
|
// src/label/index.ts
|
|
4931
5818
|
var label_exports = {};
|
|
4932
5819
|
__export(label_exports, {
|
|
4933
|
-
|
|
5820
|
+
all: () => all4,
|
|
5821
|
+
copy: () => copy6,
|
|
5822
|
+
delete: () => delete_label,
|
|
4934
5823
|
delete_label: () => delete_label,
|
|
4935
5824
|
get_text: () => get_text,
|
|
4936
5825
|
get_x: () => get_x,
|
|
@@ -4938,10 +5827,12 @@ __export(label_exports, {
|
|
|
4938
5827
|
new: () => new_label2,
|
|
4939
5828
|
new_label: () => new_label2,
|
|
4940
5829
|
set_color: () => set_color2,
|
|
5830
|
+
set_point: () => set_point,
|
|
4941
5831
|
set_size: () => set_size,
|
|
4942
5832
|
set_style: () => set_style2,
|
|
4943
5833
|
set_text: () => set_text2,
|
|
4944
5834
|
set_text_font_family: () => set_text_font_family2,
|
|
5835
|
+
set_text_formatting: () => set_text_formatting2,
|
|
4945
5836
|
set_textalign: () => set_textalign,
|
|
4946
5837
|
set_textcolor: () => set_textcolor,
|
|
4947
5838
|
set_tooltip: () => set_tooltip,
|
|
@@ -4951,21 +5842,47 @@ __export(label_exports, {
|
|
|
4951
5842
|
set_y: () => set_y,
|
|
4952
5843
|
set_yloc: () => set_yloc
|
|
4953
5844
|
});
|
|
4954
|
-
function new_label2(
|
|
4955
|
-
|
|
5845
|
+
function new_label2(...args) {
|
|
5846
|
+
let x, y, rest;
|
|
5847
|
+
if (typeof args[0] === "object" && args[0] !== null) {
|
|
5848
|
+
const point = args[0];
|
|
5849
|
+
rest = args.slice(1);
|
|
5850
|
+
x = pointX3(point, rest[1] ?? "bar_index");
|
|
5851
|
+
y = point.price;
|
|
5852
|
+
} else {
|
|
5853
|
+
[x, y] = args;
|
|
5854
|
+
rest = args.slice(2);
|
|
5855
|
+
}
|
|
5856
|
+
const [
|
|
5857
|
+
text,
|
|
5858
|
+
xloc2,
|
|
5859
|
+
yloc,
|
|
5860
|
+
labelColor,
|
|
5861
|
+
style,
|
|
5862
|
+
textcolor,
|
|
5863
|
+
size3,
|
|
5864
|
+
textalign,
|
|
5865
|
+
tooltip,
|
|
5866
|
+
text_font_family,
|
|
5867
|
+
force_overlay,
|
|
5868
|
+
text_formatting
|
|
5869
|
+
] = rest;
|
|
5870
|
+
return register("label", {
|
|
4956
5871
|
x,
|
|
4957
5872
|
y,
|
|
4958
|
-
xloc: xloc2,
|
|
4959
|
-
yloc,
|
|
5873
|
+
xloc: xloc2 ?? "bar_index",
|
|
5874
|
+
yloc: yloc ?? "price",
|
|
4960
5875
|
text,
|
|
4961
5876
|
tooltip,
|
|
4962
5877
|
color: labelColor,
|
|
4963
5878
|
style,
|
|
4964
5879
|
textcolor,
|
|
4965
|
-
size:
|
|
5880
|
+
size: size3,
|
|
4966
5881
|
textalign,
|
|
4967
|
-
text_font_family
|
|
4968
|
-
|
|
5882
|
+
text_font_family,
|
|
5883
|
+
force_overlay: force_overlay ?? false,
|
|
5884
|
+
text_formatting
|
|
5885
|
+
});
|
|
4969
5886
|
}
|
|
4970
5887
|
function get_x(id) {
|
|
4971
5888
|
return id.x;
|
|
@@ -4976,70 +5893,103 @@ function get_y(id) {
|
|
|
4976
5893
|
function get_text(id) {
|
|
4977
5894
|
return id.text;
|
|
4978
5895
|
}
|
|
4979
|
-
function
|
|
4980
|
-
return { ...id };
|
|
5896
|
+
function copy6(id) {
|
|
5897
|
+
return register("label", { ...id });
|
|
4981
5898
|
}
|
|
4982
5899
|
function set_x(id, x) {
|
|
5900
|
+
if (isDeleted(id)) return id;
|
|
4983
5901
|
id.x = x;
|
|
4984
5902
|
return id;
|
|
4985
5903
|
}
|
|
4986
5904
|
function set_y(id, y) {
|
|
5905
|
+
if (isDeleted(id)) return id;
|
|
4987
5906
|
id.y = y;
|
|
4988
5907
|
return id;
|
|
4989
5908
|
}
|
|
4990
5909
|
function set_xy(id, x, y) {
|
|
5910
|
+
if (isDeleted(id)) return id;
|
|
4991
5911
|
id.x = x;
|
|
4992
5912
|
id.y = y;
|
|
4993
5913
|
return id;
|
|
4994
5914
|
}
|
|
4995
5915
|
function set_xloc3(id, x, xloc2) {
|
|
5916
|
+
if (isDeleted(id)) return id;
|
|
4996
5917
|
id.x = x;
|
|
4997
5918
|
id.xloc = xloc2;
|
|
4998
5919
|
return id;
|
|
4999
5920
|
}
|
|
5000
|
-
function set_yloc(id,
|
|
5001
|
-
id
|
|
5921
|
+
function set_yloc(id, yloc) {
|
|
5922
|
+
if (isDeleted(id)) return id;
|
|
5002
5923
|
id.yloc = yloc;
|
|
5003
5924
|
return id;
|
|
5004
5925
|
}
|
|
5005
5926
|
function set_text2(id, text) {
|
|
5927
|
+
if (isDeleted(id)) return id;
|
|
5006
5928
|
id.text = text;
|
|
5007
5929
|
return id;
|
|
5008
5930
|
}
|
|
5009
5931
|
function set_tooltip(id, tooltip) {
|
|
5932
|
+
if (isDeleted(id)) return id;
|
|
5010
5933
|
id.tooltip = tooltip;
|
|
5011
5934
|
return id;
|
|
5012
5935
|
}
|
|
5013
5936
|
function set_color2(id, labelColor) {
|
|
5937
|
+
if (isDeleted(id)) return id;
|
|
5014
5938
|
id.color = labelColor;
|
|
5015
5939
|
return id;
|
|
5016
5940
|
}
|
|
5017
5941
|
function set_textcolor(id, textColor) {
|
|
5942
|
+
if (isDeleted(id)) return id;
|
|
5018
5943
|
id.textcolor = textColor;
|
|
5019
5944
|
return id;
|
|
5020
5945
|
}
|
|
5021
5946
|
function set_style2(id, style) {
|
|
5947
|
+
if (isDeleted(id)) return id;
|
|
5022
5948
|
id.style = style;
|
|
5023
5949
|
return id;
|
|
5024
5950
|
}
|
|
5025
|
-
function set_size(id,
|
|
5026
|
-
id
|
|
5951
|
+
function set_size(id, size3) {
|
|
5952
|
+
if (isDeleted(id)) return id;
|
|
5953
|
+
id.size = size3;
|
|
5027
5954
|
return id;
|
|
5028
5955
|
}
|
|
5029
5956
|
function set_textalign(id, align) {
|
|
5957
|
+
if (isDeleted(id)) return id;
|
|
5030
5958
|
id.textalign = align;
|
|
5031
5959
|
return id;
|
|
5032
5960
|
}
|
|
5033
5961
|
function set_text_font_family2(id, font) {
|
|
5962
|
+
if (isDeleted(id)) return id;
|
|
5034
5963
|
id.text_font_family = font;
|
|
5035
5964
|
return id;
|
|
5036
5965
|
}
|
|
5037
|
-
function delete_label(
|
|
5966
|
+
function delete_label(id) {
|
|
5967
|
+
remove3("label", id);
|
|
5968
|
+
}
|
|
5969
|
+
function pointX3(point, xloc2) {
|
|
5970
|
+
const x = xloc2 === "bar_time" ? point.time : point.index;
|
|
5971
|
+
return x ?? NaN;
|
|
5972
|
+
}
|
|
5973
|
+
function all4() {
|
|
5974
|
+
return all("label");
|
|
5975
|
+
}
|
|
5976
|
+
function set_point(id, point) {
|
|
5977
|
+
if (isDeleted(id)) return id;
|
|
5978
|
+
id.x = pointX3(point, id.xloc);
|
|
5979
|
+
id.y = point.price;
|
|
5980
|
+
return id;
|
|
5981
|
+
}
|
|
5982
|
+
function set_text_formatting2(id, formatting) {
|
|
5983
|
+
if (isDeleted(id)) return id;
|
|
5984
|
+
id.text_formatting = formatting;
|
|
5985
|
+
return id;
|
|
5038
5986
|
}
|
|
5039
5987
|
|
|
5040
5988
|
// src/linefill/index.ts
|
|
5041
5989
|
var linefill_exports = {};
|
|
5042
5990
|
__export(linefill_exports, {
|
|
5991
|
+
all: () => all5,
|
|
5992
|
+
delete: () => delete_linefill,
|
|
5043
5993
|
delete_linefill: () => delete_linefill,
|
|
5044
5994
|
get_line1: () => get_line1,
|
|
5045
5995
|
get_line2: () => get_line2,
|
|
@@ -5048,11 +5998,11 @@ __export(linefill_exports, {
|
|
|
5048
5998
|
set_color: () => set_color3
|
|
5049
5999
|
});
|
|
5050
6000
|
function new_linefill2(line1, line2, fillColor) {
|
|
5051
|
-
return {
|
|
6001
|
+
return register("linefill", {
|
|
5052
6002
|
line1,
|
|
5053
6003
|
line2,
|
|
5054
6004
|
color: fillColor
|
|
5055
|
-
};
|
|
6005
|
+
});
|
|
5056
6006
|
}
|
|
5057
6007
|
function get_line1(id) {
|
|
5058
6008
|
return id.line1;
|
|
@@ -5061,16 +6011,21 @@ function get_line2(id) {
|
|
|
5061
6011
|
return id.line2;
|
|
5062
6012
|
}
|
|
5063
6013
|
function set_color3(id, fillColor) {
|
|
6014
|
+
if (isDeleted(id)) return id;
|
|
5064
6015
|
id.color = fillColor;
|
|
5065
6016
|
return id;
|
|
5066
6017
|
}
|
|
5067
|
-
function delete_linefill(
|
|
6018
|
+
function delete_linefill(id) {
|
|
6019
|
+
remove3("linefill", id);
|
|
6020
|
+
}
|
|
6021
|
+
function all5() {
|
|
6022
|
+
return all("linefill");
|
|
5068
6023
|
}
|
|
5069
6024
|
|
|
5070
6025
|
// src/chartpoint/index.ts
|
|
5071
6026
|
var chartpoint_exports = {};
|
|
5072
6027
|
__export(chartpoint_exports, {
|
|
5073
|
-
copy: () =>
|
|
6028
|
+
copy: () => copy7,
|
|
5074
6029
|
from_index: () => from_index,
|
|
5075
6030
|
from_time: () => from_time,
|
|
5076
6031
|
new: () => new_point,
|
|
@@ -5097,7 +6052,7 @@ function from_index(index, price) {
|
|
|
5097
6052
|
price
|
|
5098
6053
|
};
|
|
5099
6054
|
}
|
|
5100
|
-
function
|
|
6055
|
+
function copy7(point) {
|
|
5101
6056
|
return {
|
|
5102
6057
|
time: point.time,
|
|
5103
6058
|
index: point.index,
|
|
@@ -5108,6 +6063,7 @@ function copy6(point) {
|
|
|
5108
6063
|
// src/polyline/index.ts
|
|
5109
6064
|
var polyline_exports = {};
|
|
5110
6065
|
__export(polyline_exports, {
|
|
6066
|
+
all: () => all6,
|
|
5111
6067
|
clear_all: () => clear_all,
|
|
5112
6068
|
delete: () => delete_polyline,
|
|
5113
6069
|
delete_polyline: () => delete_polyline,
|
|
@@ -5117,7 +6073,6 @@ __export(polyline_exports, {
|
|
|
5117
6073
|
reset_id_counter: () => reset_id_counter
|
|
5118
6074
|
});
|
|
5119
6075
|
var polylineIdCounter = 0;
|
|
5120
|
-
var allPolylines = [];
|
|
5121
6076
|
function generateId() {
|
|
5122
6077
|
return `polyline_${++polylineIdCounter}`;
|
|
5123
6078
|
}
|
|
@@ -5144,28 +6099,39 @@ function new_polyline(points, curved = false, closed = false, xloc2 = "bar_index
|
|
|
5144
6099
|
line_width,
|
|
5145
6100
|
force_overlay
|
|
5146
6101
|
};
|
|
5147
|
-
|
|
5148
|
-
return polyline;
|
|
6102
|
+
return register("polyline", polyline);
|
|
5149
6103
|
}
|
|
5150
6104
|
function delete_polyline(id) {
|
|
5151
|
-
|
|
5152
|
-
if (index !== -1) {
|
|
5153
|
-
allPolylines.splice(index, 1);
|
|
5154
|
-
}
|
|
6105
|
+
remove3("polyline", id);
|
|
5155
6106
|
}
|
|
5156
6107
|
function get_all() {
|
|
5157
|
-
return
|
|
6108
|
+
return all("polyline");
|
|
6109
|
+
}
|
|
6110
|
+
function all6() {
|
|
6111
|
+
return all("polyline");
|
|
5158
6112
|
}
|
|
5159
6113
|
function clear_all() {
|
|
5160
|
-
|
|
6114
|
+
for (const p of all("polyline")) remove3("polyline", p);
|
|
5161
6115
|
}
|
|
5162
6116
|
function reset_id_counter() {
|
|
5163
6117
|
polylineIdCounter = 0;
|
|
5164
6118
|
}
|
|
5165
6119
|
|
|
6120
|
+
// src/text/index.ts
|
|
6121
|
+
var text_exports = {};
|
|
6122
|
+
__export(text_exports, {
|
|
6123
|
+
format_bold: () => format_bold,
|
|
6124
|
+
format_italic: () => format_italic,
|
|
6125
|
+
format_none: () => format_none
|
|
6126
|
+
});
|
|
6127
|
+
var format_none = 0;
|
|
6128
|
+
var format_bold = 1;
|
|
6129
|
+
var format_italic = 2;
|
|
6130
|
+
|
|
5166
6131
|
// src/ta-series.ts
|
|
5167
6132
|
var ta_series_exports = {};
|
|
5168
6133
|
__export(ta_series_exports, {
|
|
6134
|
+
accdist: () => accdist2,
|
|
5169
6135
|
alma: () => alma2,
|
|
5170
6136
|
atr: () => atr2,
|
|
5171
6137
|
barssince: () => barssince2,
|
|
@@ -5188,6 +6154,7 @@ __export(ta_series_exports, {
|
|
|
5188
6154
|
highestbars: () => highestbars2,
|
|
5189
6155
|
hma: () => hma2,
|
|
5190
6156
|
ichimoku: () => ichimoku2,
|
|
6157
|
+
iii: () => iii2,
|
|
5191
6158
|
kc: () => kc2,
|
|
5192
6159
|
kcw: () => kcw2,
|
|
5193
6160
|
linreg: () => linreg2,
|
|
@@ -5200,11 +6167,15 @@ __export(ta_series_exports, {
|
|
|
5200
6167
|
min: () => min5,
|
|
5201
6168
|
mode: () => mode4,
|
|
5202
6169
|
mom: () => mom2,
|
|
6170
|
+
nvi: () => nvi2,
|
|
6171
|
+
obv: () => obv2,
|
|
5203
6172
|
percentile_linear_interpolation: () => percentile_linear_interpolation3,
|
|
5204
6173
|
percentile_nearest_rank: () => percentile_nearest_rank3,
|
|
5205
6174
|
percentrank: () => percentrank3,
|
|
5206
6175
|
pivothigh: () => pivothigh2,
|
|
5207
6176
|
pivotlow: () => pivotlow2,
|
|
6177
|
+
pvi: () => pvi2,
|
|
6178
|
+
pvt: () => pvt2,
|
|
5208
6179
|
range: () => range3,
|
|
5209
6180
|
rci: () => rci2,
|
|
5210
6181
|
rising: () => rising2,
|
|
@@ -5223,9 +6194,12 @@ __export(ta_series_exports, {
|
|
|
5223
6194
|
valuewhen: () => valuewhen2,
|
|
5224
6195
|
variance: () => variance3,
|
|
5225
6196
|
vwap: () => vwap2,
|
|
6197
|
+
vwapBands: () => vwapBands,
|
|
5226
6198
|
vwma: () => vwma2,
|
|
6199
|
+
wad: () => wad2,
|
|
5227
6200
|
wma: () => wma2,
|
|
5228
6201
|
wpr: () => wpr2,
|
|
6202
|
+
wvad: () => wvad2,
|
|
5229
6203
|
zigzag: () => zigzag2
|
|
5230
6204
|
});
|
|
5231
6205
|
function sma2(source, length2) {
|
|
@@ -5276,11 +6250,9 @@ function bb2(source, length2, mult2) {
|
|
|
5276
6250
|
const lowerSeries = Series.fromArray(bars, lowerVals);
|
|
5277
6251
|
return [upperSeries, basisSeries, lowerSeries];
|
|
5278
6252
|
}
|
|
5279
|
-
function stdev3(source, length2) {
|
|
6253
|
+
function stdev3(source, length2, biased = true) {
|
|
5280
6254
|
const bars = source.bars;
|
|
5281
|
-
|
|
5282
|
-
const result = stdev(sourceValues, length2);
|
|
5283
|
-
return Series.fromArray(bars, result);
|
|
6255
|
+
return Series.fromArray(bars, stdev(source.toArray(), length2, biased));
|
|
5284
6256
|
}
|
|
5285
6257
|
function atr2(bars, length2) {
|
|
5286
6258
|
const high = bars.map((b2) => b2.high);
|
|
@@ -5296,6 +6268,40 @@ function tr2(bars, handle_na = false) {
|
|
|
5296
6268
|
const result = tr(handle_na, high, low, close);
|
|
5297
6269
|
return Series.fromArray(bars, result);
|
|
5298
6270
|
}
|
|
6271
|
+
var col2 = (bars, f) => bars.map((b2) => b2[f] ?? NaN);
|
|
6272
|
+
function obv2(bars) {
|
|
6273
|
+
return Series.fromArray(bars, obv(col2(bars, "close"), col2(bars, "volume")));
|
|
6274
|
+
}
|
|
6275
|
+
function pvt2(bars) {
|
|
6276
|
+
return Series.fromArray(bars, pvt(col2(bars, "close"), col2(bars, "volume")));
|
|
6277
|
+
}
|
|
6278
|
+
function accdist2(bars) {
|
|
6279
|
+
return Series.fromArray(
|
|
6280
|
+
bars,
|
|
6281
|
+
accdist(col2(bars, "high"), col2(bars, "low"), col2(bars, "close"), col2(bars, "volume"))
|
|
6282
|
+
);
|
|
6283
|
+
}
|
|
6284
|
+
function nvi2(bars) {
|
|
6285
|
+
return Series.fromArray(bars, nvi(col2(bars, "close"), col2(bars, "volume")));
|
|
6286
|
+
}
|
|
6287
|
+
function pvi2(bars) {
|
|
6288
|
+
return Series.fromArray(bars, pvi(col2(bars, "close"), col2(bars, "volume")));
|
|
6289
|
+
}
|
|
6290
|
+
function iii2(bars) {
|
|
6291
|
+
return Series.fromArray(
|
|
6292
|
+
bars,
|
|
6293
|
+
iii(col2(bars, "high"), col2(bars, "low"), col2(bars, "close"), col2(bars, "volume"))
|
|
6294
|
+
);
|
|
6295
|
+
}
|
|
6296
|
+
function wad2(bars) {
|
|
6297
|
+
return Series.fromArray(bars, wad(col2(bars, "high"), col2(bars, "low"), col2(bars, "close")));
|
|
6298
|
+
}
|
|
6299
|
+
function wvad2(bars) {
|
|
6300
|
+
return Series.fromArray(
|
|
6301
|
+
bars,
|
|
6302
|
+
wvad(col2(bars, "open"), col2(bars, "high"), col2(bars, "low"), col2(bars, "close"), col2(bars, "volume"))
|
|
6303
|
+
);
|
|
6304
|
+
}
|
|
5299
6305
|
function stoch2(source, high, low, length2) {
|
|
5300
6306
|
const bars = source.bars;
|
|
5301
6307
|
const sourceValues = source.toArray();
|
|
@@ -5387,12 +6393,14 @@ function supertrend2(bars, factor, atrLength) {
|
|
|
5387
6393
|
const dirSeries = Series.fromArray(bars, dirVals);
|
|
5388
6394
|
return [trendSeries, dirSeries];
|
|
5389
6395
|
}
|
|
5390
|
-
function vwap2(source, volume) {
|
|
6396
|
+
function vwap2(source, volume, anchor) {
|
|
5391
6397
|
const bars = source.bars;
|
|
5392
|
-
|
|
5393
|
-
|
|
5394
|
-
|
|
5395
|
-
|
|
6398
|
+
return Series.fromArray(bars, vwap(source.toArray(), volume.toArray(), anchor?.toArray()));
|
|
6399
|
+
}
|
|
6400
|
+
function vwapBands(source, volume, anchor, stdev_mult) {
|
|
6401
|
+
const bars = source.bars;
|
|
6402
|
+
const [m, u, l] = vwap(source.toArray(), volume.toArray(), anchor?.toArray(), stdev_mult);
|
|
6403
|
+
return [Series.fromArray(bars, m), Series.fromArray(bars, u), Series.fromArray(bars, l)];
|
|
5396
6404
|
}
|
|
5397
6405
|
function ichimoku2(bars, conversionPeriods, basePeriods, laggingSpan2Periods, displacement) {
|
|
5398
6406
|
const high = bars.map((b2) => b2.high);
|
|
@@ -5577,10 +6585,9 @@ function kcw2(bars, source, length2 = 20, mult2 = 2, useTrueRange = true) {
|
|
|
5577
6585
|
const result = kcw(source.toArray(), length2, mult2, useTrueRange, high, low, close);
|
|
5578
6586
|
return Series.fromArray(bars, result);
|
|
5579
6587
|
}
|
|
5580
|
-
function range3(
|
|
5581
|
-
const bars =
|
|
5582
|
-
|
|
5583
|
-
return Series.fromArray(bars, result);
|
|
6588
|
+
function range3(source, length2) {
|
|
6589
|
+
const bars = source.bars;
|
|
6590
|
+
return Series.fromArray(bars, range(source.toArray(), length2));
|
|
5584
6591
|
}
|
|
5585
6592
|
function highestbars2(source, length2) {
|
|
5586
6593
|
const bars = source.bars;
|
|
@@ -5592,15 +6599,13 @@ function lowestbars2(source, length2) {
|
|
|
5592
6599
|
const result = lowestbars(source.toArray(), length2);
|
|
5593
6600
|
return Series.fromArray(bars, result);
|
|
5594
6601
|
}
|
|
5595
|
-
function max5(
|
|
5596
|
-
const bars =
|
|
5597
|
-
|
|
5598
|
-
return Series.fromArray(bars, result);
|
|
6602
|
+
function max5(source) {
|
|
6603
|
+
const bars = source.bars;
|
|
6604
|
+
return Series.fromArray(bars, max(source.toArray()));
|
|
5599
6605
|
}
|
|
5600
|
-
function min5(
|
|
5601
|
-
const bars =
|
|
5602
|
-
|
|
5603
|
-
return Series.fromArray(bars, result);
|
|
6606
|
+
function min5(source) {
|
|
6607
|
+
const bars = source.bars;
|
|
6608
|
+
return Series.fromArray(bars, min(source.toArray()));
|
|
5604
6609
|
}
|
|
5605
6610
|
function cog2(source, length2 = 10) {
|
|
5606
6611
|
const bars = source.bars;
|
|
@@ -5683,6 +6688,15 @@ var ta = {
|
|
|
5683
6688
|
lowestbars: lowestbars2,
|
|
5684
6689
|
max: max5,
|
|
5685
6690
|
min: min5,
|
|
6691
|
+
vwapBands,
|
|
6692
|
+
obv: obv2,
|
|
6693
|
+
pvt: pvt2,
|
|
6694
|
+
accdist: accdist2,
|
|
6695
|
+
nvi: nvi2,
|
|
6696
|
+
pvi: pvi2,
|
|
6697
|
+
iii: iii2,
|
|
6698
|
+
wad: wad2,
|
|
6699
|
+
wvad: wvad2,
|
|
5686
6700
|
cog: cog2,
|
|
5687
6701
|
mode: mode4,
|
|
5688
6702
|
percentile_linear_interpolation: percentile_linear_interpolation3,
|
|
@@ -5692,11 +6706,23 @@ var ta = {
|
|
|
5692
6706
|
|
|
5693
6707
|
// src/utils/index.ts
|
|
5694
6708
|
function isNA(value) {
|
|
5695
|
-
return value === null || value === void 0 || Number.isNaN(value);
|
|
6709
|
+
return value === null || value === void 0 || Number.isNaN(value) || isDeleted(value);
|
|
5696
6710
|
}
|
|
5697
6711
|
function nz(value, defaultValue = 0) {
|
|
5698
6712
|
return isNA(value) ? defaultValue : value;
|
|
5699
6713
|
}
|
|
6714
|
+
function fixnan(source) {
|
|
6715
|
+
let last2;
|
|
6716
|
+
let seen = false;
|
|
6717
|
+
return source.map((v) => {
|
|
6718
|
+
if (!isNA(v)) {
|
|
6719
|
+
last2 = v;
|
|
6720
|
+
seen = true;
|
|
6721
|
+
return v;
|
|
6722
|
+
}
|
|
6723
|
+
return seen ? last2 : v;
|
|
6724
|
+
});
|
|
6725
|
+
}
|
|
5700
6726
|
function ohlcFromBars(bars) {
|
|
5701
6727
|
return {
|
|
5702
6728
|
open: bars.map((b2) => b2.open),
|
|
@@ -6088,16 +7114,78 @@ var input = {
|
|
|
6088
7114
|
title: options.title,
|
|
6089
7115
|
options: options.options
|
|
6090
7116
|
};
|
|
7117
|
+
},
|
|
7118
|
+
/**
|
|
7119
|
+
* Create a timeframe input parameter (PineScript `input.timeframe`)
|
|
7120
|
+
* @param defaultValue - Default timeframe string ("60", "1D", "W"); "" means the chart timeframe
|
|
7121
|
+
* @param options - Additional options (title, options for dropdown)
|
|
7122
|
+
* @returns Input value object
|
|
7123
|
+
*
|
|
7124
|
+
* @example
|
|
7125
|
+
* ```typescript
|
|
7126
|
+
* const htf = input.timeframe('1D', { title: 'Higher timeframe' });
|
|
7127
|
+
* console.log(htf.value); // '1D'
|
|
7128
|
+
* ```
|
|
7129
|
+
*/
|
|
7130
|
+
timeframe(defaultValue, options = {}) {
|
|
7131
|
+
return {
|
|
7132
|
+
type: "timeframe",
|
|
7133
|
+
defaultValue,
|
|
7134
|
+
value: defaultValue,
|
|
7135
|
+
title: options.title,
|
|
7136
|
+
options: options.options
|
|
7137
|
+
};
|
|
7138
|
+
},
|
|
7139
|
+
/**
|
|
7140
|
+
* Create a session input parameter (PineScript `input.session`)
|
|
7141
|
+
* @param defaultValue - Default session string ("0930-1600", "0930-1600:23456")
|
|
7142
|
+
* @param options - Additional options (title, options for dropdown)
|
|
7143
|
+
* @returns Input value object
|
|
7144
|
+
*
|
|
7145
|
+
* @example
|
|
7146
|
+
* ```typescript
|
|
7147
|
+
* const rth = input.session('0930-1600', { title: 'Regular hours' });
|
|
7148
|
+
* console.log(rth.value); // '0930-1600'
|
|
7149
|
+
* ```
|
|
7150
|
+
*/
|
|
7151
|
+
session(defaultValue, options = {}) {
|
|
7152
|
+
return {
|
|
7153
|
+
type: "session",
|
|
7154
|
+
defaultValue,
|
|
7155
|
+
value: defaultValue,
|
|
7156
|
+
title: options.title,
|
|
7157
|
+
options: options.options
|
|
7158
|
+
};
|
|
7159
|
+
},
|
|
7160
|
+
/**
|
|
7161
|
+
* Create a date/time input parameter (PineScript `input.time`)
|
|
7162
|
+
* @param defaultValue - Default UNIX time in milliseconds, e.g. `time.timestamp('2024-01-01')`
|
|
7163
|
+
* @param options - Additional options (title)
|
|
7164
|
+
* @returns Input value object
|
|
7165
|
+
*
|
|
7166
|
+
* @example
|
|
7167
|
+
* ```typescript
|
|
7168
|
+
* const start = input.time(time.timestamp('2024-01-01'), { title: 'Start' });
|
|
7169
|
+
* console.log(start.value); // 1704067200000
|
|
7170
|
+
* ```
|
|
7171
|
+
*/
|
|
7172
|
+
time(defaultValue, options = {}) {
|
|
7173
|
+
return {
|
|
7174
|
+
type: "time",
|
|
7175
|
+
defaultValue,
|
|
7176
|
+
value: defaultValue,
|
|
7177
|
+
title: options.title
|
|
7178
|
+
};
|
|
6091
7179
|
}
|
|
6092
7180
|
};
|
|
6093
7181
|
Object.freeze(input);
|
|
6094
7182
|
|
|
6095
7183
|
// src/plot.ts
|
|
6096
|
-
function plot(
|
|
7184
|
+
function plot(values2, times, options = {}) {
|
|
6097
7185
|
const result = [];
|
|
6098
7186
|
const offset = options.offset ?? 0;
|
|
6099
|
-
for (let i = 0; i <
|
|
6100
|
-
const value =
|
|
7187
|
+
for (let i = 0; i < values2.length; i++) {
|
|
7188
|
+
const value = values2[i];
|
|
6101
7189
|
const timeIndex = i + offset;
|
|
6102
7190
|
if (value === null || value === void 0 || Number.isNaN(value)) {
|
|
6103
7191
|
continue;
|
|
@@ -6112,10 +7200,10 @@ function plot(values, times, options = {}) {
|
|
|
6112
7200
|
}
|
|
6113
7201
|
return result;
|
|
6114
7202
|
}
|
|
6115
|
-
function createPlot(id,
|
|
7203
|
+
function createPlot(id, values2, times, options = {}) {
|
|
6116
7204
|
return {
|
|
6117
7205
|
id,
|
|
6118
|
-
data: plot(
|
|
7206
|
+
data: plot(values2, times, options),
|
|
6119
7207
|
options
|
|
6120
7208
|
};
|
|
6121
7209
|
}
|
|
@@ -6356,6 +7444,42 @@ function input_string(defval, title, options) {
|
|
|
6356
7444
|
const value = context2.inputs.getValue(id);
|
|
6357
7445
|
return typeof value === "string" ? value : defval;
|
|
6358
7446
|
}
|
|
7447
|
+
function registerOnce(config) {
|
|
7448
|
+
const context2 = getContext();
|
|
7449
|
+
if (!registeredInputs.has(config.id)) {
|
|
7450
|
+
context2.inputs.registerInput(config);
|
|
7451
|
+
registeredInputs.set(config.id, true);
|
|
7452
|
+
if (autoRecalculateEnabled) {
|
|
7453
|
+
context2.inputs.onInputChange((changedId) => {
|
|
7454
|
+
if (changedId === config.id) {
|
|
7455
|
+
recalculate();
|
|
7456
|
+
}
|
|
7457
|
+
});
|
|
7458
|
+
}
|
|
7459
|
+
}
|
|
7460
|
+
return context2.inputs.getValue(config.id);
|
|
7461
|
+
}
|
|
7462
|
+
function input_timeframe(defval, title, options) {
|
|
7463
|
+
if (!getContext()) {
|
|
7464
|
+
return defval;
|
|
7465
|
+
}
|
|
7466
|
+
const value = registerOnce({ id: generateInputId(title, defval, "timeframe"), type: "timeframe", defval, title, options });
|
|
7467
|
+
return typeof value === "string" ? value : defval;
|
|
7468
|
+
}
|
|
7469
|
+
function input_session(defval, title, options) {
|
|
7470
|
+
if (!getContext()) {
|
|
7471
|
+
return defval;
|
|
7472
|
+
}
|
|
7473
|
+
const value = registerOnce({ id: generateInputId(title, defval, "session"), type: "session", defval, title, options });
|
|
7474
|
+
return typeof value === "string" ? value : defval;
|
|
7475
|
+
}
|
|
7476
|
+
function input_time(defval, title) {
|
|
7477
|
+
if (!getContext()) {
|
|
7478
|
+
return defval;
|
|
7479
|
+
}
|
|
7480
|
+
const value = registerOnce({ id: generateInputId(title, defval, "time"), type: "time", defval, title });
|
|
7481
|
+
return typeof value === "number" ? value : defval;
|
|
7482
|
+
}
|
|
6359
7483
|
function input_source(defval, title) {
|
|
6360
7484
|
const context2 = getContext();
|
|
6361
7485
|
if (!context2) {
|
|
@@ -6578,7 +7702,7 @@ var SimpleInputAdapter = class {
|
|
|
6578
7702
|
validatedValue = Math.floor(validatedValue);
|
|
6579
7703
|
}
|
|
6580
7704
|
}
|
|
6581
|
-
if (config.type === "string" && config.options && typeof value === "string") {
|
|
7705
|
+
if ((config.type === "string" || config.type === "timeframe" || config.type === "session") && config.options && typeof value === "string") {
|
|
6582
7706
|
if (!config.options.includes(value)) {
|
|
6583
7707
|
return;
|
|
6584
7708
|
}
|
|
@@ -6626,8 +7750,8 @@ var SimpleInputAdapter = class {
|
|
|
6626
7750
|
};
|
|
6627
7751
|
|
|
6628
7752
|
// src/index.ts
|
|
6629
|
-
var VERSION = "0.
|
|
6630
|
-
var
|
|
7753
|
+
var VERSION = "0.6.1";
|
|
7754
|
+
var info2 = {
|
|
6631
7755
|
name: "OakScriptJS",
|
|
6632
7756
|
version: VERSION,
|
|
6633
7757
|
description: "Simplified PineScript-like library - Series + TA functions",
|
|
@@ -6640,8 +7764,8 @@ var info = {
|
|
|
6640
7764
|
minimal: "No DSL layer - complexity in transpiler"
|
|
6641
7765
|
},
|
|
6642
7766
|
namespaces: {
|
|
6643
|
-
core: ["ta", "math", "array", "str", "color", "time", "matrix"],
|
|
6644
|
-
drawing: ["line", "box", "label", "linefill", "chartPoint", "polyline"],
|
|
7767
|
+
core: ["ta", "math", "array", "map", "str", "color", "time", "timeframe", "matrix"],
|
|
7768
|
+
drawing: ["line", "box", "label", "linefill", "chartPoint", "polyline", "text"],
|
|
6645
7769
|
runtime: ["setContext", "plot", "hline", "input_*"],
|
|
6646
7770
|
indicator: ["indicator", "input", "plotHelper", "createPlot"]
|
|
6647
7771
|
}
|
|
@@ -6670,6 +7794,7 @@ export {
|
|
|
6670
7794
|
clearPlots,
|
|
6671
7795
|
color_exports as color,
|
|
6672
7796
|
from_hex as color_from_hex,
|
|
7797
|
+
compare_exports as compare,
|
|
6673
7798
|
cos,
|
|
6674
7799
|
createPlot,
|
|
6675
7800
|
crossover2 as crossover,
|
|
@@ -6677,6 +7802,7 @@ export {
|
|
|
6677
7802
|
cum2 as cum,
|
|
6678
7803
|
ema2 as ema,
|
|
6679
7804
|
exp,
|
|
7805
|
+
fixnan,
|
|
6680
7806
|
floor,
|
|
6681
7807
|
getClose,
|
|
6682
7808
|
getContext,
|
|
@@ -6686,18 +7812,22 @@ export {
|
|
|
6686
7812
|
getSourceSeries,
|
|
6687
7813
|
hline,
|
|
6688
7814
|
indicator,
|
|
6689
|
-
info,
|
|
7815
|
+
info2 as info,
|
|
6690
7816
|
input,
|
|
6691
7817
|
input_bool,
|
|
6692
7818
|
input_float,
|
|
6693
7819
|
input_int,
|
|
7820
|
+
input_session,
|
|
6694
7821
|
input_source,
|
|
6695
7822
|
input_string,
|
|
7823
|
+
input_time,
|
|
7824
|
+
input_timeframe,
|
|
6696
7825
|
label_exports as label,
|
|
6697
7826
|
line_exports as line,
|
|
6698
7827
|
linefill_exports as linefill,
|
|
6699
7828
|
log,
|
|
6700
7829
|
macd2 as macd,
|
|
7830
|
+
map_exports as map,
|
|
6701
7831
|
math_exports as math,
|
|
6702
7832
|
matrix_exports as matrix,
|
|
6703
7833
|
max2 as max,
|
|
@@ -6725,7 +7855,9 @@ export {
|
|
|
6725
7855
|
ta_series_exports as ta,
|
|
6726
7856
|
ta_exports as taCore,
|
|
6727
7857
|
tan,
|
|
7858
|
+
text_exports as text,
|
|
6728
7859
|
time_exports as time,
|
|
7860
|
+
timeframe_exports as timeframe,
|
|
6729
7861
|
tr2 as tr,
|
|
6730
7862
|
vwap2 as vwap,
|
|
6731
7863
|
xloc,
|